常玩qq的人应该知道qq群里可以引入一个“聊天机器人”qq小冰,而后可以在群里通过@qq小冰来达到调戏的目的

然而尿性的腾讯除了qq之外还有微信这样一款聊天的软件

本文目的就是注册一个微信号(来作为我们的机器人),将其拉到微信群里然后通过艾特的功能来实现个人聊天或者客服的目的

做为一个不合格的软开,怎么能不用别人的轮子呢(手动斜眼笑)

ok,给出轮子链接https://github.com/cncoder/WeChatBotJava(用Java语言来实现的)

通过这个轮子可以登陆你的微信,获取联系人、监听消息并自动回复

我们的功能是基于此轮子进行的修改

闲话少说

找到类me.biezhi.wechat.service.WechatServiceImpl,其getContact(WechatMeta)方法是用来获取联系人的

此方法中循环处理memberlist过滤其中公告号、群聊等账号,拿到所有用户contactList

因为我们的目的是实现群聊机器人,因此定义群聊联系人groupList并在群聊的判断语句里将当前contact加入到list中

循环结束后将该list注入wechatContact中去

getContact()方法最后调用了私有的getGroup()方法,起初不懂这是要干嘛,后来见名知意发现这个就是用来获取群联系人的(group嘛)

重写该方法,调用微信的webwxbatchgetcontact api,关于该api的具体使用可以自行百度

下面是该方法的代码

/*** 获取群成员* @param wechatMeta* @param wechatContact*/private void getGroup(WechatMeta wechatMeta, WechatContact wechatContact) {String url = wechatMeta.getBase_uri() + "/webwxbatchgetcontact?"+"type=ex"+"&r=" +DateKit.getCurrentUnixTime()+"&lang=zh_CN"+"&pass_ticket="+wechatMeta.getPass_ticket();JSONObject body = new JSONObject();JSONArray groupList = wechatContact.getGroupList();List<Map<String, String>> list = new ArrayList<Map<String, String>>();body.put("BaseRequest", wechatMeta.getBaseRequest());body.put("Count", groupList.size());for (int i = 0; i < groupList.size(); i++) {HashMap<String, String> map = new HashMap<String, String>();map.put("UserName", groupList.get(i).asJSONObject().getString("UserName"));map.put("EncryChatRoomId", "");list.add(map);}body.put("List", list);HttpRequest request = HttpRequest.post(url).contentType("application/json;charset=utf-8").header("Cookie", wechatMeta.getCookie()).send(body.toString());LOGGER.debug(request.toString());String res = request.body();request.disconnect();if (StringKit.isBlank(res)) {throw new WechatException("获取群信息失败");}LOGGER.debug(res);try {JSONObject jsonObject = JSONKit.parseObject(res);JSONObject BaseResponse = jsonObject.get("BaseResponse").asJSONObject();if (null != BaseResponse) {int ret = BaseResponse.getInt("Ret", -1);if (ret == 0) {JSONArray contactList = jsonObject.get("ContactList").asArray();if (null != contactList) {groupList = new JSONArray();for (int i = 0, len = contactList.size(); i < len; i++) {JSONObject contact = contactList.get(i).asJSONObject();if (contact.getString("UserName").indexOf("@@") != -1) {JSONArray memberList =contact.get("MemberList").asArray();for(JSONValue value:memberList) {groupList.add(value);}}}wechatContact.setGroupList(groupList);}}}} catch (Exception e) {throw new WechatException(e);}}

(注意1:groupLIst在这段代码中出现两次,第一次是JSONArray groupList = wechatContact.getGroupList();这里的groupList是群的相关信息,比如群名字,群成员列表等,第二次出现时在groupList.add(value);这里的groupLIst得到的就是群聊中所有成员的信息,包括昵称、用户名、群昵称等

注意2:在实际使用中可能发现这个wechatContact.getGroupList();得到的groupList为空,或者value里没有你想要的群的消息,这是因为这里得到的是被保存在通讯录里的群的列表,打开微信的某个群,在“聊天信息”里有一个“保存到通讯录”功能,这里开关要打开,然后才能获取到里面的值)

拿到了群成员列表之后,岂不就可以为所欲为了吗^_^

上文说到获得的groupList中的每个元素都对应着群中的一个成员,本项目中需要使用的属性为DisplayName和NickName,其中DisplayName为群昵称,就是设置的在这个群的昵称,NickName是个人昵称也就是微信昵称,对于设置了群昵称的群成员就艾特DisplayName,否则艾特NickName。

而群成员在聊天的时候获得的content为Username+内容的组合形式,也就是通过content的username部分获得是哪个用户艾特的机器人,然后根据这个username找到对应grouplist中的某个元素,再得到其displayname或nickname

结尾就是针对该类WechatServiceImpl的完整代码

package me.biezhi.wechat.service;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import com.blade.kit.DateKit;
import com.blade.kit.FileKit;
import com.blade.kit.StringKit;
import com.blade.kit.http.HttpRequest;
import com.blade.kit.json.JSONArray;
import com.blade.kit.json.JSONKit;
import com.blade.kit.json.JSONObject;
import com.blade.kit.json.JSONValue;import me.biezhi.wechat.Constant;
import me.biezhi.wechat.exception.WechatException;
import me.biezhi.wechat.model.WechatContact;
import me.biezhi.wechat.model.WechatMeta;
import me.biezhi.wechat.robot.MoLiRobot;
import me.biezhi.wechat.robot.Robot;
import me.biezhi.wechat.util.Matchers;
import me.cncoder.record.RecordCon;public class WechatServiceImpl implements WechatService {private static final Logger LOGGER = LoggerFactory.getLogger(WechatService.class);// 茉莉机器人private Robot robot = new MoLiRobot();/*** Step7:获取联系人* @url   https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact* @method POST* @data JSON* @header ContentType: application/json; charset=UTF-8* @params BaseRequest* @return JSON*/@Overridepublic WechatContact getContact(WechatMeta wechatMeta) {String url = wechatMeta.getBase_uri() + "/webwxgetcontact?pass_ticket=" + wechatMeta.getPass_ticket() + "&skey="+ wechatMeta.getSkey() + "&r=" + DateKit.getCurrentUnixTime();JSONObject body = new JSONObject();body.put("BaseRequest", wechatMeta.getBaseRequest());HttpRequest request = HttpRequest.post(url).contentType("application/json;charset=utf-8").header("Cookie", wechatMeta.getCookie()).send(body.toString());LOGGER.debug(request.toString());String res = request.body();request.disconnect();if (StringKit.isBlank(res)) {throw new WechatException("获取联系人失败");}LOGGER.debug(res);WechatContact wechatContact = new WechatContact();try {JSONObject jsonObject = JSONKit.parseObject(res);JSONObject BaseResponse = jsonObject.get("BaseResponse").asJSONObject();if (null != BaseResponse) {int ret = BaseResponse.getInt("Ret", -1);if (ret == 0) {//成员列表JSONArray memberList = jsonObject.get("MemberList").asArray();//联系人列表JSONArray contactList = new JSONArray();//群成员列表JSONArray groupList = new JSONArray();if (null != memberList) {for (int i = 0, len = memberList.size(); i < len; i++) {JSONObject contact = memberList.get(i).asJSONObject();// 公众号/服务号if (contact.getInt("VerifyFlag", 0) == 8) {continue;}// 特殊联系人if (Constant.FILTER_USERS.contains(contact.getString("UserName"))) {continue;}// 群聊if (contact.getString("UserName").indexOf("@@") != -1) {groupList.add(contact);}// 自己if (contact.getString("UserName").equals(wechatMeta.getUser().getString("UserName"))) {continue;}contactList.add(contact);}wechatContact.setContactList(contactList);wechatContact.setMemberList(memberList);wechatContact.setGroupList(groupList);this.getGroup(wechatMeta, wechatContact);System.out.println(wechatContact.toString());return wechatContact;}}}} catch (Exception e) {throw new WechatException(e);}return null;}/*** 获取群成员* @param wechatMeta* @param wechatContact*/private void getGroup(WechatMeta wechatMeta, WechatContact wechatContact) {String url = wechatMeta.getBase_uri() + "/webwxbatchgetcontact?"+"type=ex"+"&r=" +DateKit.getCurrentUnixTime()+"&lang=zh_CN"+"&pass_ticket="+wechatMeta.getPass_ticket();JSONObject body = new JSONObject();JSONArray groupList = wechatContact.getGroupList();List<Map<String, String>> list = new ArrayList<Map<String, String>>();body.put("BaseRequest", wechatMeta.getBaseRequest());body.put("Count", groupList.size());for (int i = 0; i < groupList.size(); i++) {HashMap<String, String> map = new HashMap<String, String>();map.put("UserName", groupList.get(i).asJSONObject().getString("UserName"));map.put("EncryChatRoomId", "");list.add(map);}body.put("List", list);HttpRequest request = HttpRequest.post(url).contentType("application/json;charset=utf-8").header("Cookie", wechatMeta.getCookie()).send(body.toString());LOGGER.debug(request.toString());String res = request.body();request.disconnect();if (StringKit.isBlank(res)) {throw new WechatException("获取群信息失败");}LOGGER.debug(res);try {JSONObject jsonObject = JSONKit.parseObject(res);JSONObject BaseResponse = jsonObject.get("BaseResponse").asJSONObject();if (null != BaseResponse) {int ret = BaseResponse.getInt("Ret", -1);if (ret == 0) {JSONArray contactList = jsonObject.get("ContactList").asArray();if (null != contactList) {groupList = new JSONArray();for (int i = 0, len = contactList.size(); i < len; i++) {JSONObject contact = contactList.get(i).asJSONObject();if (contact.getString("UserName").indexOf("@@") != -1) {JSONArray memberList =contact.get("MemberList").asArray();for(JSONValue value:memberList) {groupList.add(value);}}}wechatContact.setGroupList(groupList);}}}} catch (Exception e) {throw new WechatException(e);}}/*** Step1:获取UUID uuid是服务端用来标识一次登陆的通信* @url https://login.weixin.qq.com/jslogin* @method Get* @data URL Encode* @params <b>appid</b> : wx782c26e4c19acffb  这个值不变,表示来自微信网页版<b>fun</b> : new <b>lang</b>: zh_CN <b>_</b> : 时间戳 * @return window.QRLogin.code = 200; window.QRLogin.uuid = "xxx"*/@Overridepublic String getUUID() throws WechatException {HttpRequest request = HttpRequest.get(Constant.JS_LOGIN_URL, true, "appid", "wx782c26e4c19acffb", "fun", "new","lang", "zh_CN", "_", DateKit.getCurrentUnixTime());LOGGER.debug(request.toString());String res = request.body();request.disconnect();if (StringKit.isNotBlank(res)) {String code = Matchers.match("window.QRLogin.code = (\\d+);", res);if (null != code) {if (code.equals("200")) {return Matchers.match("window.QRLogin.uuid = \"(.*)\";", res);} else {throw new WechatException("错误的状态码: " + code);}}}throw new WechatException("获取UUID失败");}/***Step6: 打开状态提醒*@url https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxstatusnotify*@method POST*@data JSON*@header Content-Type: application/json; charset=UTF-8*@params {*          BaseRequest: { Uin: xxx, Sid: xxx, Skey: xxx, DeviceID: xxx }, *            Code: 3, *          FromUserName: 自己的ID, *          ToUserName: 自己的ID, *            ClientMsgId: 时间戳 *        }* @return JSON*/@Overridepublic void openStatusNotify(WechatMeta wechatMeta) throws WechatException {String url = wechatMeta.getBase_uri() + "/webwxstatusnotify?lang=zh_CN&pass_ticket=" + wechatMeta.getPass_ticket();JSONObject body = new JSONObject();body.put("BaseRequest", wechatMeta.getBaseRequest());body.put("Code", 3);body.put("FromUserName", wechatMeta.getUser().getString("UserName"));body.put("ToUserName", wechatMeta.getUser().getString("UserName"));body.put("ClientMsgId", DateKit.getCurrentUnixTime());HttpRequest request = HttpRequest.post(url).contentType("application/json;charset=utf-8").header("Cookie", wechatMeta.getCookie()).send(body.toString());LOGGER.debug("" + request);String res = request.body();request.disconnect();if (StringKit.isBlank(res)) {throw new WechatException("状态通知开启失败");}try {JSONObject jsonObject = JSONKit.parseObject(res);JSONObject BaseResponse = jsonObject.get("BaseResponse").asJSONObject();if (null != BaseResponse) {int ret = BaseResponse.getInt("Ret", -1);if (ret != 0) {throw new WechatException("状态通知开启失败,ret:" + ret);}}} catch (Exception e) {throw new WechatException(e);}}/*** Step5:微信初始化* @url https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxinit* @method POST* @data JSON* @header Content-Type: application/json; charset=UTF-8* @params 上一步登陆获得的BaseRequest* @return JSON 这一步中获取 SyncKey, User 后面的消息监听用。*/@Overridepublic void wxInit(WechatMeta wechatMeta) throws WechatException {String url = wechatMeta.getBase_uri() + "/webwxinit?r=" + DateKit.getCurrentUnixTime() + "&pass_ticket="+ wechatMeta.getPass_ticket() + "&skey=" + wechatMeta.getSkey();JSONObject body = new JSONObject();body.put("BaseRequest", wechatMeta.getBaseRequest());HttpRequest request = HttpRequest.post(url).contentType("application/json;charset=utf-8").header("Cookie", wechatMeta.getCookie()).send(body.toString());LOGGER.debug("" + request);String res = request.body();request.disconnect();if (StringKit.isBlank(res)) {throw new WechatException("微信初始化失败");}try {JSONObject jsonObject = JSONKit.parseObject(res);if (null != jsonObject) {JSONObject BaseResponse = jsonObject.get("BaseResponse").asJSONObject();if (null != BaseResponse) {int ret = BaseResponse.getInt("Ret", -1);if (ret == 0) {wechatMeta.setSyncKey(jsonObject.get("SyncKey").asJSONObject());wechatMeta.setUser(jsonObject.get("User").asJSONObject());StringBuffer synckey = new StringBuffer();JSONArray list = wechatMeta.getSyncKey().get("List").asArray();for (int i = 0, len = list.size(); i < len; i++) {JSONObject item = list.get(i).asJSONObject();synckey.append("|" + item.getInt("Key", 0) + "_" + item.getInt("Val", 0));}wechatMeta.setSynckey(synckey.substring(1));}}}} catch (Exception e) {}}/*** 选择同步线路*/@Overridepublic void choiceSyncLine(WechatMeta wechatMeta) throws WechatException {boolean enabled = false;for(String syncUrl : Constant.SYNC_HOST){int[] res = this.syncCheck(syncUrl, wechatMeta);if(res[0] == 0){String url = "https://" + syncUrl + "/cgi-bin/mmwebwx-bin";wechatMeta.setWebpush_url(url);LOGGER.info("选择线路:[{}]", syncUrl);enabled = true;break;}}if(!enabled){throw new WechatException("同步线路不通畅");}}/*** Step8:消息检测/检测心跳* @url https://webpush2.weixin.qq.com/cgi-bin/mmwebwx-bin/synccheck* @method GET* @data JSON* @header ContentType: application/json; charset=UTF-8* @params BaseRequest* @return window.synccheck={retcode:"xxx",selector:"xxx"}*           其中retcode:0 正常1100 失败/登出微信selector:0 正常2 新的消息7 进入/离开聊天界面*/@Overridepublic int[] syncCheck(WechatMeta wechatMeta) throws WechatException{return this.syncCheck(null, wechatMeta);}/*** 检测心跳*/private int[] syncCheck(String url, WechatMeta meta) throws WechatException{if(null == url){url = meta.getWebpush_url() + "/synccheck";} else{url = "https://" + url + "/cgi-bin/mmwebwx-bin/synccheck";}JSONObject body = new JSONObject();body.put("BaseRequest", meta.getBaseRequest());HttpRequest request = HttpRequest.get(url, true, "r", DateKit.getCurrentUnixTime() + StringKit.getRandomNumber(5), "skey",meta.getSkey(), "uin", meta.getWxuin(), "sid", meta.getWxsid(), "deviceid",meta.getDeviceId(), "synckey", meta.getSynckey(), "_", System.currentTimeMillis()).header("Cookie", meta.getCookie());LOGGER.debug(request.toString());String res = request.body();request.disconnect();int[] arr = new int[]{-1, -1};if (StringKit.isBlank(res)) {return arr;}String retcode = Matchers.match("retcode:\"(\\d+)\",", res);String selector = Matchers.match("selector:\"(\\d+)\"}", res);if (null != retcode && null != selector) {arr[0] = Integer.parseInt(retcode);arr[1] = Integer.parseInt(selector);return arr;}return arr;}/*** 处理消息*/@Overridepublic void handleMsg(WechatMeta wechatMeta, JSONObject data) {if (null == data) {return;}JSONArray AddMsgList = data.get("AddMsgList").asArray();for (int i = 0, len = AddMsgList.size(); i < len; i++) {// LOGGER.info("你有新的消息,请注意查收");JSONObject msg = AddMsgList.get(i).asJSONObject();int msgType = msg.getInt("MsgType", 0);String content = msg.getString("Content");String name = getUserRemarkName(content.split(":")[0]);if (msgType == 1 ) {if (msg.getString("FromUserName").indexOf("@@") != -1) {LOGGER.info(name + ": " + content);String ans = "@";// webwxsendmsg(wechatMeta, ans+name+" 抓包成功", msg.getString("FromUserName"));LOGGER.info("自动回复 " + name + ":" + name);}} else if (msgType == 3) {String imgDir = Constant.config.get("app.img_path");String msgId = msg.getString("MsgId");FileKit.createDir(imgDir, false);String imgUrl = wechatMeta.getBase_uri() + "/webwxgetmsgimg?MsgID=" + msgId + "&skey="+ wechatMeta.getSkey() + "&type=slave";HttpRequest.get(imgUrl).header("Cookie", wechatMeta.getCookie()).receive(new File(imgDir + "/" + msgId + ".jpg"));// webwxsendmsg(wechatMeta, "无法查看图片", msg.getString("FromUserName"));} else if (msgType == 34) {// webwxsendmsg(wechatMeta, "语音也听不懂", msg.getString("FromUserName"));} }}/*** 发送消息*/private void webwxsendmsg(WechatMeta meta, String content, String to) {String url = meta.getBase_uri() + "/webwxsendmsg?lang=zh_CN&pass_ticket=" + meta.getPass_ticket();JSONObject body = new JSONObject();//写入当前回复对象UserNameRecordCon.cache.add(to);String clientMsgId = DateKit.getCurrentUnixTime() + StringKit.getRandomNumber(5);JSONObject Msg = new JSONObject();Msg.put("Type", 1);Msg.put("Content", content);Msg.put("FromUserName", meta.getUser().getString("UserName"));Msg.put("ToUserName", to);Msg.put("LocalID", clientMsgId);Msg.put("ClientMsgId", clientMsgId);body.put("BaseRequest", meta.getBaseRequest());body.put("Msg", Msg);HttpRequest request = HttpRequest.post(url).contentType("application/json;charset=utf-8").header("Cookie", meta.getCookie()).send(body.toString());//LOGGER.info("发送消息...");//LOGGER.debug("" + request);request.body();request.disconnect();}private String getUserRemarkName(String id) {String name = "这个人物名字未知";for (int i = 0, len = Constant.CONTACT.getGroupList().size(); i < len; i++) {JSONObject member = Constant.CONTACT.getGroupList().get(i).asJSONObject();if (member.getString("UserName").equals(id)) {if (StringKit.isNotBlank(member.getString("RemarkName"))) {name = member.getString("RemarkName");}else if(StringKit.isNotBlank(member.getString("DisplayName"))){name = member.getString("DisplayName");}else {name = member.getString("NickName");}return name;}}return name;}@Overridepublic JSONObject webwxsync(WechatMeta meta) throws WechatException{String url = meta.getBase_uri() + "/webwxsync?skey=" + meta.getSkey() + "&sid=" + meta.getWxsid();JSONObject body = new JSONObject();body.put("BaseRequest", meta.getBaseRequest());body.put("SyncKey", meta.getSyncKey());body.put("rr", DateKit.getCurrentUnixTime());HttpRequest request = HttpRequest.post(url).contentType("application/json;charset=utf-8").header("Cookie", meta.getCookie()).send(body.toString());LOGGER.debug(request.toString());String res = request.body();request.disconnect();if (StringKit.isBlank(res)) {throw new WechatException("同步syncKey失败");}JSONObject jsonObject = JSONKit.parseObject(res);JSONObject BaseResponse = jsonObject.get("BaseResponse").asJSONObject();if (null != BaseResponse) {int ret = BaseResponse.getInt("Ret", -1);if (ret == 0) {meta.setSyncKey(jsonObject.get("SyncKey").asJSONObject());StringBuffer synckey = new StringBuffer();JSONArray list = meta.getSyncKey().get("List").asArray();for (int i = 0, len = list.size(); i < len; i++) {JSONObject item = list.get(i).asJSONObject();synckey.append("|" + item.getInt("Key", 0) + "_" + item.getInt("Val", 0));}meta.setSynckey(synckey.substring(1));return jsonObject;}}return null;}}

其实针对这个轮子还修改了RecordCon类,该类是用来将联系人列表写入本地文件的,不过因为这个不是核心处理类,而且逻辑比较简单,这里就不摘了,最后只需要修改返回值ans比如调用图灵机器人api,就可以实现你自己不可告人的需求了

微信实现qq群的qq小冰功能相关推荐

  1. python控制qq群_Python3 selenium 实现QQ群接龙自动化功能

    一.环境 环境配置为安装了 selenium 模块的 Python3 ,以及浏览器对应的driver 如果没有安装 selenium ,可以在控制台执行下面的代码 pip3 install selen ...

  2. qq好友列表获取导出,利用QQ协议实现好友数据备份,包含:qq好友、QQ分组、QQ群、qq群成员【附code源码】

    qq好友列表获取导出,利用QQ协议实现qq好友数据备份,包含:qq好友.QQ分组.QQ群.qq群成员. 我们是在浏览器中的操作,接下来看看数据到底怎么获取的,我们通过Fiddler的查找功能,就可以查 ...

  3. 在QQ群和QQ空间中挂马

    有无数人每天都在使用 QQ ,大家往往注重于QQ尾巴病毒.QQ传 木马 之类的攻击方式,却很少有人注意到我们经常访问的QQ群.QQ空间里面隐藏着更大的安全危险,远比QQ尾巴病毒.QQ传木马之类的隐蔽得 ...

  4. html 点击加入qq群,怎么样加入QQ群?加入QQ群两种方式介绍

    怎么样加入QQ群?加入QQ群通常用于2种方式,一种是已知QQ群号,我们只需要查找添加,另外一种是自行搜索找群,下面我们分别介绍下. 最近有网友问小编:怎样加入脚本之家QQ群啊?随后小编给其发了一个QQ ...

  5. html链接加入qq群,获取QQ群加群链接

    # 获取QQ群加群链接 > 获取QQ群三种一键加群链接:电脑端无弹窗直接加群. ## 请求地址 > https://api88.net/api/qun/ ## 请求方式 > GET ...

  6. php获取QQ群成员QQ号,获取QQ群成员头像

    写一个程序,输入qq群号码,把每个群成员的头像下载下来,保存到本地,图片名字取群昵称,如果没有群昵称,取qq名字 import requests,os url = 'https://qun.qq.co ...

  7. python 下载qq群文件,QQ群文件下载失败怎么办?解决QQ群文件下载失败的解决方法...

    QQ群分享文件无法下载的问题很烦人,具体原因涉及到系统控件加载,防火墙,IE设置,internet选项等等,如果慢慢去排除花时间,麻烦,也不能解决.重装软件也不能解决问题,重装系统更是扯淡,那么这里给 ...

  8. 通过转让群的方法可以让16级以下的QQ号也能拥有QQ群(菜鸟QQ号不需开通QQ会员也能有群)

    群转让有何要求? 1.接受者能接收群,且目前有创建新群的能力,否则不能接受转让. 2.转让两者是好友关系,并且好友关系在7天以上. ---------------------------------- ...

  9. python qq群_python qq群机器人怎么弄

    展开全部 首先第一步就是打开网页版的qq,打开浏览器的开发者模式 这里可32313133353236313431303231363533e58685e5aeb931333361326362以监控所有的 ...

最新文章

  1. vendor自动恢复_解决 vendor 中存在大小写变更问题
  2. python的jupyter的使用教程-强大的jupyter,python开发者的福音
  3. 用python处理excel表格_python用win32com处理excel表格
  4. python国内书籍推荐_这些都是Python官方推荐的最好的书籍
  5. mysql 加字段_MySQL8.0大表秒加字段,是真的吗?
  6. JVM 的 Finalization Delay 引起的 OOM(java.lang.OutOfMemoryError:null at sun.misc.Unsafe.allocateMemory.)
  7. GWT(Google Web Tookit) Eclipse Plugin的zip下载地址(同时提供GWT Designer下载地址)
  8. 解决win2003默认不能使用移动硬盘的问题
  9. 36.MySQY 常用工具
  10. warning: #61-D: integer operation result is out of range
  11. 服务器误删除虚拟机数据恢复成功
  12. 工业App能否成为继Android和iOS后下一个App开发者的春天?
  13. outlook你的邮件服务器证书无效,Outlook添加网易邮箱账号提示服务器的加密连接不可用的解决方法...
  14. [论文笔记]Age of Information Aware Radio Resource Management in Veh Net: A Proactive DRL Perspective
  15. Postgresql on conflict do update 设置当前值,原始值,当前值与原始值相加值
  16. 使用NextDenovo组装Nanopore数据
  17. 厦门吾智美:ESS.OIL.CO潜力无限
  18. ubuntu服务器配置ruby环境(国内傻瓜版)
  19. 超好用的Git工作流
  20. execl(知道每个商品单价,且知道总价,计算每个商品的数量)

热门文章

  1. 【成神之路】Mysql相关面试题
  2. Linux系统 logrotate 详解
  3. 电源完整性之DC-DC
  4. 美国ipv6云服务器配置,Vultr服务器添加ipv6地址的方法
  5. Scikit入门指南
  6. 疫情当前,产品求职者更需苦练内功
  7. matlab读取txt数据文件
  8. 利用AUI实现多种多样的timeline时间轴样式
  9. 概率笔记2——古典概型
  10. 我的世界服务器ess配置信息,我的世界有哪些ess指令_ess指令大全_3DM网游