微信商家红包发放接入

微信红包

准备工作

微信商家开通支付功能、微信公众号、开通红包功能

相关网站

  • 微信支付: http://pay.weixin.qq.com/
  • 签名生成算法:http://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=4_3
  • 发放红包接口:http://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_4&index=3

需要资料

  • API证书(apiclient_cert.p12):微信商户平台(pay.weixin.qq.com)-->账户中心-->账户设置-->API安全
  • API支付秘钥:商户平台设置的密钥key 32 位
  • openId:用户微信公众授权获取到得 openId

注意事项

  1. 现金红包接口目前微信还没升级,使用的v2版本,所以提交数据和返回数据采用的是xml格式
  2. 付款金额,单位分
  3. 红包发放成功,会发放到公众号中,需要用户主动点击领取
  4. 测试过程中保证商户运营账号有余额
  5. 微信红包-产品设置-添加测试地址ip白名单,不知道自己外网ip地址 百度搜索 ip 即可

代码示例

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.ssl.SSLContexts;
import org.jeecg.common.util.Md5Util;
import org.jeecg.modules.video.utitls.Constants;
import org.springframework.core.io.ClassPathResource;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.net.ssl.SSLContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.InputStream;
import java.security.*;
import java.util.*;

/**
 * @description:
 * @author: Mr.Fang
 * @create: 2023-05-26 
 **/
@Slf4j
public class WxTest {
    public static void main(String[] args) throws Exception {
        // 1、参数封装
        TreeMap<String, Object> map = new TreeMap<>();
        map.put("nonce_str", UUID.randomUUID().toString().replaceAll("-", "")); // 随机字符串
        map.put("mch_billno", "202302260000001");// "商家订单编号"
        map.put("mch_id", Constants.WX_MERCHANT_ID); // 商户号
        map.put("wxappid", Constants.WX_APP_ID); // 公众号 APPID
        map.put("send_name", "我发的");
        map.put("re_openid", "123456"); // openid
        map.put("total_amount", "100"); // 金额
        map.put("total_num", 1); // 数量
        map.put("wishing", "恭喜发财");
        map.put("client_ip", "127.0.0.1");
        map.put("act_name", "任务分佣");
        map.put("remark", "无");

        // 2、参数拼接 k=v 格式
        List<String> list = new ArrayList<>();
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            list.add(String.format("%s=%s", key, value.toString()));
        }
        String join = String.join("&", list);
        log.debug("拼接参数结果:{}", join);
        // 3、参数+&key=API支付秘钥 md5 签名
        String sign = Md5Util.md5Encode(join + "&key=" + Constants.WX_MERCHANT_API_SECRET, "UTF-8");
        log.debug("拼接参数md5:{}", sign.toUpperCase(Locale.ROOT));
        map.put("sign", sign.toUpperCase(Locale.ROOT));
        log.debug("请求参数Map:{}", map);
        // 4、获取 API 证书,当前证书是放在 resource 下的
        ClassPathResource resource = new ClassPathResource("apiclient_cert.p12");
        InputStream inputStream = null;
        try {
            inputStream = resource.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // FIXME: 2023/5/26 也可以这样
//        inputStream = new FileInputStream("证书路径");
        // 5、加载 SSL 证书
        String pass =Constants.WX_MERCHANT_ID; // 密码商户号
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        keyStore.load(inputStream, pass.toCharArray()); // 证书默认密码是商户号码
        SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial((chain, authType) -> true).loadKeyMaterial(keyStore, pass.toCharArray()).build();
        SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}, null, SSLConnectionSocketFactory.getDefaultHostnameVerifier());
        // 6、创建 httpClient 客户端 并设置 ssl 对象
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        httpClientBuilder.setSSLSocketFactory(sslConnectionSocketFactory);
        CloseableHttpClient build = httpClientBuilder.build();

        // 7、创建 post 请求
        HttpPost httpPost = new HttpPost("http://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack");
        String xml = parseMapToXml(map);
        log.debug("请求体xml:{}", xml);
        StringEntity stringEntity = new StringEntity(xml, "UTF-8");
        stringEntity.setContentEncoding("UTF-8");
        httpPost.setEntity(stringEntity);

        // 8、发起请求
        CloseableHttpResponse response = build.execute(httpPost);
        Map<String, Object> toMap = parseXMLToMap(response.getEntity().getContent());
        log.info("mchRedEnvelope:{}", toMap);
    }

    /**
     * 解析 xml
     *
     * @param map
     * @return
     */
    public static String parseMapToXml(Map<String, ? extends Object> map) {
        StringBuilder sb = new StringBuilder("<xml>");
        if (null != map && map.size() > 0) {
            Set<? extends Map.Entry<String, ?>> entries = map.entrySet();

            String key;
            for (Iterator iterator = entries.iterator(); iterator.hasNext(); sb.append("</" + key + ">")) {
                Map.Entry next = (Map.Entry) iterator.next();
                key = (String) next.getKey();
                Object value = next.getValue();
                sb.append("<" + key + ">");
                if (Objects.nonNull(value)) {
                    sb.append("<![CDATA[" + value + "]]>");
                }
            }
        }

        sb.append("</xml>");
        return sb.toString();
    }

    /**
     * xml 转 map
     * @param inputStream
     * @return
     */
    public static Map<String, Object> parseXMLToMap(InputStream inputStream) {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

        try {
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document = builder.parse(inputStream);
            Element documentElement = document.getDocumentElement();
            Map<String, Object> map = recursiveFindXmlElement(documentElement);
            return map;
        } catch (ParserConfigurationException | SAXException | IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    private static Map<String, Object> recursiveFindXmlElement(Element element) {
        if (Objects.nonNull(element)) {
            HashMap<String, Object> map = new HashMap();
            NodeList childNodes = element.getChildNodes();

            for(int i = 0; i < childNodes.getLength(); ++i) {
                Node item = childNodes.item(i);
                short nodeType = item.getNodeType();
                if (Objects.equals(nodeType, (short) 1)) {
                    String nodeName = item.getNodeName();
                    Element childElement = (Element)item;
                    Map<String, Object> childMap = recursiveFindXmlElement(childElement);
                    if (null != childMap && childMap.size() > 0) {
                        map.put(nodeName, childMap);
                    } else {
                        String nodeValue = StringUtils.isBlank(item.getTextContent()) ? null : item.getTextContent().trim();
                        map.put(nodeName, nodeValue);
                    }
                }
            }
            if (map.size() > 0) {
                return map;
            }
        }

        return null;
    }
}

响应结果

展示参数进行处理,不代表真实发送数据内容

拼接参数结果:

act_name=任务分佣&client_ip=127.0.0.1&mch_billno=202302260000001&mch_id=1299535101&nonce_str=c3dad56d4bc74f9d910a6210edaddd0a&re_openid=1111111&remark=无&send_name=我发的&total_amount=100&total_num=1&wishing=恭喜发财&wxappid=1111111

拼接参数md5:

426a84083ea5adc67398a7918490adeb

请求参数Map:

{act_name=任务分佣, client_ip=127.0.0.1, mch_billno=202302260000001, mch_id=1111111, nonce_str=c3dad56d4bc74f9d910a6210edaddd0a, re_openid=1111111, remark=无, send_name=恭喜发财, sign=426a84083eadadc67398a7918490adeb, total_amount=100, total_num=1, wishing=恭喜发财, wxappid=1111111}

请求体xml

<xml>
    <act_name><![CDATA[任务分佣]]></act_name>
    <client_ip><![CDATA[127.0.0.1]]></client_ip>
    <mch_billno><![CDATA[202302260000001]]></mch_billno>
    <mch_id><![CDATA[1111111]]></mch_id>
    <nonce_str><![CDATA[c3dad56d4bc74f9d910a6210edaddd0a]]></nonce_str>
    <re_openid><![CDATA[1111111]]></re_openid>
    <remark><![CDATA[无]]></remark>
    <send_name><![CDATA[33333]]></send_name>
    <sign><![CDATA[426a84083eadadc67398a7918490adeb]]></sign>
    <total_amount><![CDATA[100]]></total_amount>
    <total_num><![CDATA[1]]></total_num>
    <wishing><![CDATA[恭喜发财]]></wishing>
    <wxappid><![CDATA[1111111]]></wxappid>
</xml>

本文来自博客园,作者:天葬,转载请注明原文链接:http://www.cnblogs.com/bxmm/p/17433929.html

本文转载于网络 如有侵权请联系删除

相关文章

  • 字节跳动面经(一、二、三+大boss+hr面)

    大家好,又见面了,我是你们的朋友全栈君。先介绍一下,本科和研究生都不是计算机专业,现在是学通信,然后做图像处理,可能面试官看我不是科班出身没有问太多计算机相关的问题,因为第一次找工作,字节的游戏专场又是最早开始的,就投递了,投递的是游戏测试开发岗(非测试岗),字节是自己投的第一家公司,也是第一家笔试面试的公司,面试官应该都是上海部门的,三轮面试都是视频面,面试时间是从下午5:30到9:30,一共是四个小时多一点吧(含每轮之间的等待时间,每一轮等的时间都不长,估计半小时左右吧,实际面试时间应该是有两个半小时),接下来是面经,因为准备时间不是很充分(周五晚上接到的通知,周六下午面试),回头想了下其实很多问题回答的还可以更好,这里放上自己的回答也供大家参考(目前hr已经打电话说面试通过,一周内给意向书,正式offer等正式批一起下发):笔试一共两个小时,15道不定项选择题(多选不得分,少选得一半分数,大部分和测试的一些概念有关),5道编程题,2道问答题 回答情况: 选择题凭印象答,毕竟从来没学过测试相关的,就本着不确定的就选最少的原则去做 编程题AC了三道半 问答题时间不够,只做了一题(另外

  • 详解PHP中curl_multi并发的实现

    PHP中的curl_multi系列函数可以实现同时请求多个URL来实现并发,而不是像普通curl函数那样请求后会阻塞,直到结果返回才进行下一个请求。因此在批量请求URL时可通过curl_multi系列函数提升程序的运行效率。curl普通请求$startTime=microtime(true); $chArr=[]; $optArr=[ CURLOPT_URL='http://www.httpbin.org/ip', CURLOPT_HEADER=0, CURLOPT_RETURNTRANSFER=1, ]; $result=[]; //创建多个curl资源并执行 for($i=0;$i<10;$i++){ $chArr[$i]=curl_init(); curl_setopt_array($chArr[$i],$optArr); $result[$i]=curl_exec($chArr[$i]); curl_close($chArr[$i]); } $endTime=microtime(true); echosprintf("usetime:%.

  • PHP实现微信对账单处理

    最近要做支付对账,即检查第三方支付与数据库中账单是否一一对应,涉及到微信对账单的处理,成功时,微信账单接口返回数据以文本表格的方式返回,第一行为表头,后面各行为对应的字段内容,字段内容跟查询订单或退款结果一致,具体字段说明可查阅相应接口。Ps:至于怎么调用微信接口下载对账单,在微信的官方SDK包中就有现成的办法,直接调用即可。注意对账单接口一次只能查询一天的数据。代码大致如下://引入微信sdk文件 require_onceAPP_DIR.'/ome/lib/wxpay/lib/WxPay.Api.php'; require_onceAPP_DIR.'/ome/lib/wxpay/log.php'; //实列化下载对账单对象 $input=newWxPayDownloadBill(); //对账单日期 $input-SetBill_date(date("Ymd",strtotime("-1day"))); //对账单类型 $input-SetBill_type('ALL'); //获取

  • MYSQL 索引优化

    优化和索引提升SELECT的最好方式是使用索引。索引条目作为表数据行的指针,使得查询能够很快的定位到所要查找的数据。所有的MySQL数据类型都可以创建索引。不必要的索引会浪费存储空间,同时也会增加数据更新成本(数据更新时,索引也相应的需要被更新)。MySQL使用索引索引用于快速定位特定值的表数据行。如果不使用索引,MySQL则需要从第一个数据行开始查找整个数据表,直到找到要查找的数据行,表越大,查找成本越高。如果查找条件的列存在索引,那么MySQL就可以快速定位需要查找的数据位置。大部分MySQL索引(PRIMARYKEY,UNIQUE,INDEX,andFULLTEXT)都是以B-trees形式存储。例外情况:基于R-trees的空间数据索引;MEMORY引擎的HASH索引;InnoDB的基于倒序列表的全文索引。MySQL使用索引的操作情景:Where条件查找。快速排序干扰数据。使用最具选择行的索引。最左前缀索引查找,如:在(col1,col2,col3)存在索引,则可以使用包括(col1),(col1,col2)及(col1,col2,col3)索引来进行查询。联合查询,从联合表查

  • 他非让我分表

    分库分表初见曾经为了面试,熟读并背诵了那么多骚操作,对于数据库这方面,常会背到的就是sql优化,分库分表了。当分表来临时昨天一个戴眼镜的老哥告诉我有一个表未来数据量会比较大,我准备给他切了,可能会影响你那边。我去?飞来横祸?我这CRUD过的很开心,分什么表啊。为此赶紧调动我面试时背诵的各种知识点,跟老哥进行一场battle,渴望不分表,继续单表开开心心。可惜败下阵来,还是太年轻了。没办法,开始coding吧!最开始想是直接引入sharding-jdbc,第一次操作,不得不说sharding-jdbc的文档真不怎么样,搞了半天总是报错,各种错,反正是没跑起来。于是乎,一个骚操作涌上心头。我这边对这个表的操作很简单,就是select,实在不行,直接改sql吧。我要是直接把select*fromtable复制改成select*fromtable0 union select*fromtable1 union....复制那未来承接这个项目的同学可能会把我骂死,不过让他骂不到也很容易,三下五除二,把代码上的createdby署名删除了,嗯!完美!hahahahahha.....冷静三秒之后,觉得还

  • 识别领域事件 | 洞见

    随着微服务架构的兴起,微服务设计与拆分的的最佳实践DDD已然成为大家讨论与实践的热点,整个行业都在探索如何用DDD建模来实现微服务设计。事件风暴作为最接地气的实践,在不同的项目中野蛮生长,不断演进,今天已经渐渐成熟。作为事件风暴的灵魂——领域事件,值得我们投入更多的精力去设计与打磨。领域事件是用特定方式(已发生的时态)表达发生在问题域中的重要事情,是领域通用语言(UL)的一部分。为了方便理解这个概念,这里举一个宠物的例子:如果做为宠物主人,你的问题域是如何养好一只猫,那么是不是已经打了疫苗,给宠物饲喂食物等将成为你关注的事情,领域事件会有:疫苗已注射,猫粮已饲喂等。如果你是宠物医生,问题域是如何治好宠物的病,关注的事情是宠物的身体构成,准确的诊断宠物病情,对症下药,领域事件会有:病情已确诊,药方已开治。虽说二者关注的都是宠物,在不同的问题域下领域事件是不同的。DDD的提出者和圈内的大师先后提到领域事件在领域建模中的价值,前沿实践者们已经开始应用领域事件来表达业务全景。在DDD建模过程中,以领域事件为线索逐步得到领域模型已经成为了主流的实践,即:事件风暴。事件风暴是以更专注的方式发现与提

  • MySQL高可用方案MHA的一些总结和思考

    MySQL高可用方案中MHA绝地是一个相当成熟的实现。对于数据的切换,其实MGR也能很好的完成,也就是说,数据层面的角色切换已经刻意很平滑的做好了,但是对于访问IP的处理,还是有很大的空间,MHA提供了很多可选的空间来支持。常见的组合方式有:MHA+VIPMHA+keepaliveMHA+Zookeeper当然MHA+VIP是一种很成熟和经典的方案了。一般来说都有以下类似的架构方式,假设架构模式为一主两从。对于应用访问来说,提供的IP信息就依据绑定的VIP地址为准。VIP可以根据节点的数据状态在不同节点间漂移,达到无缝切换的高可用。MHAManager是一个核心的调度器,有了它可以调度多套环境,当然MHAManager自身也有单点,所以会考虑两套MHAManager节点来做冗余,实际上是做交叉互备,比如有100套环境,两个MHAManager节点,那就每个分50个节点,如果Manager节点出现故障,可以很顺利的交接给Manager2来接管。 对于应用来说,就是统一通过VIP的方式来访问。如果是在这个基础上考虑中间件的方案,则数据访问的策略会更加复杂一些。对于这样的一个基本方案,如果从

  • 前端学习-jQuery

    老师博客:https://www.cnblogs.com/yuanchenqi/articles/6070667.html day43,day44 jquery中文文档:http://jquery.cuishifeng.cn/ 首先我们得下载一个jquery文件jquery-3.1.1.js,然后工程引入   <scriptsrc="jquery-3.1.1.js"></script>jquery的基础语法:$(selector).action()selector是选择器复制   jQuery是什么 <1>jQuery由JohnResig创建,至今已吸引了来自世界各地的众多javascript高手加入其team。 <2>jQuery是继prototype之后又一个优秀的Javascript框架。其宗旨是——WRITELESS,DOMORE! <3>它是轻量级的js库(压缩后只有21k),这是其它的js库所不及的,它兼容CSS3,还兼容各种浏览器 <4>jQuery是一个快速的,简洁的javaSc

  • 题型总结之Two Pointers(指针i扫旧, 指针start上新)

    TwoPointers(指针i扫旧,指针start上新)模板: *用指针start帮助生成新数组。指针start指向下一个即将生成的,符合条件的元素的位置。//saveapositionfornextvaliditem *用指针i扫给定数组A *若扫到的A[i]符合新数组对元素的要求,令A[start]=A[i] 复制 TwoPointers(指针i扫旧,指针start上新)高频题: [leetcode]26.RemoveDuplicatesfromSortedArray有序数组去重(单个元素只出现一次) classSolution{ publicintremoveDuplicates(int[]nums){ if(nums.length==0)return0; intstart=1; for(inti=1;i<nums.length;i++){ if(nums[i]!=nums[start-1]){ nums[start]=nums[i]; start++; } } returnstart; } }复制 [leetcode]80.RemoveDuplicatesfrom

  • 后台获取select的值,给页面添加默认值 【js】待续...

    默认选中状态:<selectplaceholder="请选择"id="serverLevel"name="serverLevel"class="selectserverLevel"> <optionvalue="1">满意</option> <optionvalue="2">基本满意</option> <optionvalue="3">不满意</option> <optionvalue="4">其他</option> </select> varsel2=document.getElementById("serverLevel").options; sel2[0].selected=true; 选中状态!复制   获取当前用户选中的值; <selectplaceholder="请选择"id="serverLevel"name="serverLevel"class="selectserverLevel"> <optionvalue=

  • 3-11

      越活越累是一个不可逆的趋势,如果玩游戏就会懂,玩游戏越来越厉害不是越来越轻松,而是越来越累,刚开始你只看得懂手里的技能,后来看得懂局势了,后来看得懂对手的反应和心思了,学会采取针对性策略,整个过程是越来越累的,接受和要处理的信息比初学的时候大十倍,再也没有劲头一玩玩一天了,玩两盘就累的不行。打牌也是如此,开始只知道看手牌,算自己牌大不大,后来学会了观察对手,计算筹码,考虑位置,计算潜在倍率,反正我现在是玩一小会牌就累的不行(尤其是现在网络扑克根本不允许你慢慢思考只有30秒响应时间,必须全神贯注不然就来不及思考)   我现在也差不多,年岁越长,考虑的事越多,活的越心累,说的每一句话做的每一件事都开始小心翼翼。而这个越来越累的过程要一直持续到你放弃人生追求为止。    当然,也可以一直保持啥都不想啥都不学的状态,  只在最低阶的鱼塘混,这样其实也挺幸福的,只是有人会看不起。

  • Python paramiko模块学习记录、封装类的使用及交换机配置批量备份程序的实现

    利用Python3paramiko实现了基于交换机配置自动批量备份的实现,代码已托管GitHub,仓库地址:switchboardbackup,有疑问可在Github提问。 前言 paramiko是基于Python实现SSH连接的第三方库,底层采用了cryptography安装该第三方库,直接使用命令pipinstallparamiko 官方文档:http://docs.paramiko.org/en/stable/index.html 借鉴博文:https://www.cnblogs.com/xiao-apple36/p/9144092.html Paramiko介绍 paramiko包含两个核心组件:SSHClient和SFTPClient。 SSHClient的作用类似于Linux的ssh命令,是对SSH会话的封装,该类封装了传输(Transport),通道(Channel)及SFTPClient建立的方法(open_sftp),通常用于执行远程命令。SFTPClient的作用类似与Linux的sftp命令,是对SFTP客户端的封装,用以实现远程文件操作,如文件上

  • LRU Cache的实现

      代码如下:     来自为知笔记(Wiz)

  • libcurl 基本使用

    libcurl,在HLS流媒体播放终端上提供HTTP下载的相关接口。具体的使用方式可以参见http://curl.haxx.se/libcurl/c/libcurl-tutorial.html,或博客http://www.cppblog.com/tx7do/archive/2012/02/19/166011.html。     代码: [cpp] viewplaincopy   m_pCurl = curl_easy_init();   if (m_pCurl == NULL)       break;   curl_easy_reset(m_pCurl);     curl_easy_setopt(m_pCurl, CURLOPT_URL, url.c_str());    cu

  • 数据导出总结

    1.首先引用ExcelLib.cs这个文件。 2.插入如下代码: DataTabledt=GetTable(resu); ExcelLibexcHelper=newExcelLib(); //writecontent excHelper.WriteCells(dt,0,0,true); //setstyle,optional excHelper.SetHeaderRowStyle(0,0,dt.Columns.Count); excHelper.SetAltRowStyle(0,0,dt,true); excHelper.SetColumnsWidth(0,dt.Columns.Count,30); stringfileName=string.Format("{0}-{1}.xls",Lincoln3R.Resources.Resource.lbl_Report,Lincoln3R.Resources.Resource.Submenu_Report2); byte[]buffer=excHelper.GetMemoryStream(); TransmitFile(fileName

  • 在Mac上搭建带ssl协议和域名指向的Apache服务器

    顾名思义,就是要在苹果电脑上搭建 Apache服务器,并且支持https协议,能用指定域名访问(有些开发调试需要注册域名,比如调试微信JS-SDK),当然最好能在手机端进行调试。首先,Mac系统自带Apache服务器,只需在终端输入sudoapachectlstart 回车即可开启Apache,那么我们现在先给服务器绑定域名,然后再设置ssl协议,最后用Charles实现手机访问。   绑定域名 1、打开访达编辑 /private/etc/hosts 文件,在该文件中添加如下代码,如果要绑定多个域名就添加多行,前面的IP不变: 127.0.0.1www.example.com复制   2、打开文件 /private/etc/apache2/httpd.conf ,找到 Include/private/etc/apache2/extra/httpd-vhosts.conf 将其前面的井号“#”删除,因为后面要用到 /private/etc/apache2/extra/http

  • 用github来展示你的前端静态页面

    经常看到大神们用github展示demo案例,一直很困惑他们是怎么做到的。今天看博客时,发现了一篇《用github来展示你的前端页面吧》这篇文章,详细的介绍了怎么使用github展示你的前端页面。这篇文章的作者博客园里好多关于前端的文章,很不错的,值得关注。 知道github的人不在少数,但是大部分人可能仅知道它可以用于管理我们的项目代码,而不知道其还可以用于展示我们前端的静态页面。比如: https://github.com/Songyj-225/jq-demo 了解github的人都知道上方的地址指向的是一个github项目目录,同时你可能还会发现这样的一个地址: https://songyj-225.github.io/jq-demo 上方的地址就是对应demo项目的展示页面了。 步骤 其实利用github来展示前端静态页面的例子很多,比如各种插件、框架的demo演示地址都会这样做,那么下面我们就来实际操作一下,体验一把展示自己前端项目成果的乐趣。 1.安装git 如果你是mac用户,那么恭喜你mac自带git命令功能,你无须安装git。如果你是windows用户,你可以前往wi

  • C-二维数组,多维数组

    -----二维数组    ->在数组定义当中,行数和列数需要用常量定义    ->在定义的时候如果没有数值进行填充,则补零    ->第一个数是行,第二个数是列    ->行可以不写,但必须定义列 intarray[4][3]={1,2,3,4,5,6,7,8,9,0,1,2}; intarray1[4][3]={{11,12,13},{14,15,16},{17,18,19},{20}}; printf("%d",array[0][0]); printf("\t%d",array1[3][0]); inta=0; intb=0; array[a][b]=0; printf("\t%d",array[0][0]); intarray[][4]={1,2,3,4,5,6,7,8,9}; intarray[][4]={1,2,3,4,5,6,7,8,9}; printf("%lu",sizeof(array)); intarra

  • JVM学习笔记三:垃圾收集器与内存分配策略

    内存回收与分配重点关注的是堆内存和方法区内存(程序计数器占用小,虚拟机栈和本地方法栈随线程有相同的生命周期)。 一、判断对象是否存活? 1.引用计数算法 优势:实现简单,效率高。 致命缺陷:无法解决对象相互引用的问题——会导致对象的引用虽然存在,但是已经不可能再被使用,却无法被回收。 2.可达性分析算法 对象到GCRoots没有引用链,则回收。 GCRoots包括: (1)Java虚拟机栈中引用的对象。 (2)方法区中类静态属性引用的对象。 (3)方法去中常量引用的对象。 (4)本地方法栈中Native方法(JNI)引用的对象。 3.关于引用 JDK1.2之后,Java对引用进行了扩充。 (1)强引用:Objectobj=newObject(),不会被jvm回收 (2)软引用:在内存溢出异常发生之前才被强制回收。 (3)弱引用:延迟到下次垃圾回收之前再被回收。 (4)虚引用:仅为了在被回收时收到一个系统通知。 4.finalize方法: 在对象被JVM回收之前,有一个低优先级的线程去执行。只有覆盖了finalize方法,才会执行,且只会执行一次。 5.回收方法区: 永久代的垃圾

  • 如何判断端口与端口是否通信

      1、curlwww.baidu.com可以正常访问的 上图前两条语句是错误的,后条语句,说明8880的那个网页是返回的。 2、本机是192.168.72.1拼另外一台ip,看主机与主机是否通信,是否可以建立TCP连接。   3、端口检测。看主机与主机之间的端口是否开放,传输层是否通。   最后在硬件防火墙那里开放端口。  

  • [Nowcoder] 六一儿童节(拼多多)

    六一儿童节,老师带了很多好吃的巧克力到幼儿园。每块巧克力j的重量为w[j],对于每个小朋友i,当他分到的巧克力大小达到h[i](即w[j]>=h[i]),他才会上去表演节目。老师的目标是将巧克力分发给孩子们,使得最多的小孩上台表演。可以保证每个w[i]>0且不能将多块巧克力分给一个孩子或将一块分给多个孩子。  输入描述: 第一行:n,表示h数组元素个数第二行:n个h数组元素第三行:m,表示w数组元素个数第四行:m个w数组元素复制 输出描述: 上台表演学生人数复制 输入例子1: 3223231复制 输出例子1: 1复制 六一儿童节,老师手里有x块巧克力,总共有y名小朋友,当小朋友手中得到的巧克力大于等于给定值时,他才可以上台表演。求一共有几个小朋友可以上台表演 将给定的巧克力重量数组以及小朋友上次所需要的巧克力数组排序(升序)。 然后用一个数count来统计能上台表演的小朋友个数,用一个idx表示用掉的巧克力数。 如果最小重量的巧克力满足当前小朋友的需要,那么count+1,idx+1表示用掉了巧克力。如果不满足当前小朋友的需要,那么开始计算第二块巧克力是否满足。

相关推荐

推荐阅读