当前位置: 首页 > news >正文

Java企业微信服务商代开发获取AccessToken示例

这里主要针对的是企业微信服务商代开发模式 文档地址

在这里插入图片描述

可以看到里面大致有三种token,一个是服务商的token,一个是企业授权token,还有一个是应用的token
这里面主要有下面几个参数
首先是服务商的 corpid 和 provider_secret ,这个可以在 应用管理-通用开发参数 里面查看

在这里插入图片描述

然后是企业的 corpid 和企业的永久授权码 permanent_code ,这两个是需要在企业授权的的时候通过回调获取的,具体请参考官方文档 获取永久授权码

最后就是应用的 suite_id 和 suite_secret 还需要一个 suite_ticket ,前面两个在应用信息里面就可以看到,suite_ticket 这个也是需要通过回调获取 ,具体参考官方文档 推送suite_ticket

在这里插入图片描述

拿到这些参数后就好说了,剩下的都是调接口
直接上代码

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.qyzj.common.base.exception.BusinessException;
import com.qyzj.common.base.util.HttpsRequestUtil;
import com.qyzj.common.redis.constant.CacheKey;
import com.qyzj.common.redis.util.RedisUtil;
import com.qyzj.service.task.constant.WeiXinProviderConst;
import com.qyzj.service.task.constant.WeixinCorpKeyConst;
import com.qyzj.service.task.constant.WeixinCorpUrlConst;
import lombok.extern.java.Log;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;/*** @author Sakura* @date 2024/7/2 11:48*/
@Component
@Log
public class WxTokenUtil {@Autowiredprivate RedisUtil redisUtil;// 获取服务商token// 这里有一个问题,企业微信本身可能会使token提前失效,所以有时需要强制重新获取token,详情见官方文档// https://developer.work.weixin.qq.com/document/path/91200// 所以此处加了一个cache用来判断是否需要走缓存拿token,正常情况默认走缓存即可public String getProviderAccessToken(Boolean cache) {try {// 如果Redis里面有则直接取Redis里面的if (cache &&redisUtil.hasKey(CacheKey.KEY_CORP_PROVIDER_ACCESS_TOKEN)) {return redisUtil.get(CacheKey.KEY_CORP_PROVIDER_ACCESS_TOKEN).toString();}// 封装请求参数JSONObject json = new JSONObject();json.put("corpid", WeiXinProviderConst.corpId);json.put("provider_secret", WeiXinProviderConst.providerSecret);// 请求微信接口String accessTokenStr = HttpsRequestUtil.sendPostRequest(WeixinCorpUrlConst.PROVIDER_ACCESS_TOKEN, json.toJSONString());log.info("get provider access token return :" + accessTokenStr);JSONObject accessTokenJson = JSON.parseObject(accessTokenStr);// 获取 access_tokenString accessToken = accessTokenJson.getString(WeixinCorpKeyConst.providerAccessToken);//官方 expires_in 为 2个小时, 这里设置100分钟redisUtil.set(CacheKey.KEY_CORP_PROVIDER_ACCESS_TOKEN, accessToken, CacheKey.expireTime100);return accessToken;} catch (Exception e) {log.info("get provider access token error");e.printStackTrace();throw new BusinessException("get provider access token error");}}// 获取企业授权tokenpublic String getCorpAccessToken(String corpId, String permanentCode) {try {// 如果Redis里面有则直接取Redis里面的if (redisUtil.hasKey(CacheKey.KEY_CORP_ACCESS_TOKEN + "_" + corpId)) {return redisUtil.get(CacheKey.KEY_CORP_ACCESS_TOKEN + "_" + corpId).toString();}String accessTokenUrl = WeixinCorpUrlConst.CORP_ACCESS_TOKEN.replace("#{CORP_ID}", corpId).replace("#{CORP_SECRET}", permanentCode);String accessTokenStr = HttpsRequestUtil.sendGetRequest(accessTokenUrl);log.info("get corp access token return :" + accessTokenStr);JSONObject accessTokenJson = JSON.parseObject(accessTokenStr);// 获取 access_tokenString accessToken = accessTokenJson.getString(WeixinCorpKeyConst.accessToken);//官方 expires_in 为 2个小时, 这里设置 100 分钟redisUtil.set(CacheKey.KEY_CORP_ACCESS_TOKEN + "_" + corpId, accessToken, CacheKey.expireTime100);return accessToken;} catch (Exception e) {log.info("get corp access token error");e.printStackTrace();throw new BusinessException("get corp access token error");}}// SuiteTicket是通过回调获取的,企微每10分钟会推送一次// 如果没有可手动在服务商企业微信后台刷新public String getSuiteTicket() {// 如果Redis里面有则直接取Redis里面的if (redisUtil.hasKey(CacheKey.KEY_CORP_SUITE_TICKET)) {return redisUtil.get(CacheKey.KEY_CORP_SUITE_TICKET).toString();} else {log.info("get suite ticket error");throw new BusinessException("get suite ticket error");}}// 获取应用token// 注意suiteTicket是从回调接口获取的// 注意该token需要配置ip白名单public String getSuiteAccessToken() {try {// 如果Redis里面有则直接取Redis里面的if (redisUtil.hasKey(CacheKey.KEY_SUITE_ACCESS_TOKEN)) {return redisUtil.get(CacheKey.KEY_SUITE_ACCESS_TOKEN).toString();}// 封装请求参数JSONObject json = new JSONObject();json.put(WeixinCorpKeyConst.suiteId, WeiXinProviderConst.suiteId);json.put(WeixinCorpKeyConst.suiteSecret, WeiXinProviderConst.suiteSecret);json.put(WeixinCorpKeyConst.suiteTicket, getSuiteTicket());String accessTokenStr = HttpsRequestUtil.sendPostRequest(WeixinCorpUrlConst.SUITE_ACCESS_TOKEN, json.toJSONString());log.info("get suite access token return :" + accessTokenStr);JSONObject accessTokenJson = JSON.parseObject(accessTokenStr);//获取 accessTokenString accessToken = accessTokenJson.getString(WeixinCorpKeyConst.suiteAccessToken);//官方 expires_in 为 2个小时, 这里设置 100分钟redisUtil.set(CacheKey.KEY_SUITE_ACCESS_TOKEN, accessToken, CacheKey.expireTime100);return accessToken;} catch (Exception e) {log.info("get suite access token error");e.printStackTrace();throw new BusinessException("get suite access token error");}}
}

这里面用到的 HttpsRequestUtil 工具类

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;/*** @author Sakura* @date 2024/6/24 17:07*/
public class HttpsRequestUtil {public static String sendPostRequest(String urlString, String jsonInputString) throws IOException {URL url = new URL(urlString);HttpURLConnection connection = (HttpURLConnection) url.openConnection();// 设置请求方法为POSTconnection.setRequestMethod("POST");// 设置请求头connection.setRequestProperty("Content-Type", "application/json");connection.setRequestProperty("Accept", "application/json");// 启用输出流,用于发送请求数据connection.setDoOutput(true);try (OutputStream os = connection.getOutputStream()) {byte[] input = jsonInputString.getBytes("utf-8");os.write(input, 0, input.length);}// 获取响应try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"))) {StringBuilder response = new StringBuilder();String responseLine;while ((responseLine = br.readLine()) != null) {response.append(responseLine.trim());}return response.toString();} finally {// 关闭连接connection.disconnect();}}public static String sendGetRequest(String urlString) throws IOException {URL url = new URL(urlString);HttpURLConnection connection = (HttpURLConnection) url.openConnection();// 设置请求方法为GETconnection.setRequestMethod("GET");// 设置请求头connection.setRequestProperty("Accept", "application/json");// 获取响应try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"))) {StringBuilder response = new StringBuilder();String responseLine;while ((responseLine = br.readLine()) != null) {response.append(responseLine.trim());}return response.toString();} finally {// 关闭连接connection.disconnect();}}}

还有企业微信的两个基本配置类

public class WeixinCorpUrlConst {/*** 获取 provider_access_token 的 url*/public static final String PROVIDER_ACCESS_TOKEN = "https://qyapi.weixin.qq.com/cgi-bin/service/get_provider_token";/*** 获取 suite_access_token 的 url*/public static final String SUITE_ACCESS_TOKEN = "https://qyapi.weixin.qq.com/cgi-bin/service/get_suite_token";/*** 获取 pre_auth_code 的 url*/public static final String PRE_AUTH_CODE = "https://qyapi.weixin.qq.com/cgi-bin/service/get_pre_auth_code?suite_access_token=";/*** 前端授权页面 的 url*/public static final String URL_AUTH_PAGE = "https://open.work.weixin.qq.com/3rdapp/install";/*** 前端登录页面 的 url*/public static final String URL_LOGIN_PAGE = "https://open.work.weixin.qq.com/wwopen/sso/3rd_qrConnect";/*** 获取 permanent_code 的 url*/public static final String PERMANENT_CODE = "https://qyapi.weixin.qq.com/cgi-bin/service/get_permanent_code?suite_access_token=";/*** 获取 企业授权 access_token 的 url*/public static final String CORP_ACCESS_TOKEN = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=#{CORP_ID}&corpsecret=#{CORP_SECRET}";/*** 获取 企业应用 access_token 的 url*/public static final String ACCESS_TOKEN = "https://qyapi.weixin.qq.com/cgi-bin/gettoken";/*** 获取 应用信息 的 url*/public static final String AGENT_INFO = "https://qyapi.weixin.qq.com/cgi-bin/agent/get?access_token=#{ACCESS_TOKEN}&agentid=#{AGENT_ID}";/*** 获取 部门列表 的 url*/public static final String DEPARTMENT_LIST = "https://qyapi.weixin.qq.com/cgi-bin/department/list?access_token=#{ACCESS_TOKEN}";/*** 获取 部门成员列表 的 url*/public static final String USER_LIST = "https://qyapi.weixin.qq.com/cgi-bin/user/list?access_token=#{ACCESS_TOKEN}&department_id=#{DEPARTMENT_ID}&fetch_child=1";/*** 获取 成员信息 的 url*/public static final String USER_INFO = "https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token=#{ACCESS_TOKEN}&userid=#{USER_ID}";/*** 获取 企业管理员 的 url*/public static final String ADMIN_USER_LIST = "https://qyapi.weixin.qq.com/cgi-bin/service/get_admin_list?suite_access_token=";/*** 第三方应用:获取 企业成员登录信息 的 url*/public static final String PROVIDER_LOGIN_INFO = "https://qyapi.weixin.qq.com/cgi-bin/service/get_login_info?access_token=";/*** 自建应用:获取 企业成员登录信息 的 url*/public static final String LOCAL_LOGIN_INFO = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=#{ACCESS_TOKEN}&code=#{CODE}";public static final String LOGIN_DETAIL_INFO = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserdetail?access_token=#{ACCESS_TOKEN}";/*** 批量获取 客户列表 的 url*/public static final String BATCH_CUSTOMER_LIST = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/batch/get_by_user?access_token=#{ACCESS_TOKEN}";/*** 获取 客户详情 的 url*/public static final String CUSTOMER_INFO = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get?access_token=#{ACCESS_TOKEN}&external_userid=#{EXTERNAL_USERID}";/*** 修改 客户备注信息 的url*/public static final String UPDATE_CUSTOMER_REMARK = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/remark?access_token=#{ACCESS_TOKEN}";/*** 编辑 客户标签 的url*/public static final String MARK_CUSTOMER_TAG = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/mark_tag?access_token=#{ACCESS_TOKEN}";/*** 获取 企业标签 的 url*/public static final String TAG_GROUP_LIST = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_corp_tag_list?access_token=";/*** 添加 企业标签 的 url*/public static final String ADD_TAG_GROUP = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_corp_tag?access_token=";/*** 修改 企业标签 的 url*/public static final String UPDATE_TAG_GROUP = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/edit_corp_tag?access_token=";/*** 删除 企业标签 的 url*/public static final String DELETE_TAG_GROUP = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/del_corp_tag?access_token=";/*** 获取 客户群列表 的 url*/public static final String GROUP_CHAT_LIST = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/list?access_token=#{ACCESS_TOKEN}";/*** 获取 客户群详情 的 url*/public static final String GROUP_CHAT_INFO = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/get?access_token=#{ACCESS_TOKEN}";/*** 查询 联系我 的 url*/public static final String GET_CONTACT_WAY = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_contact_way?access_token=#{ACCESS_TOKEN}";/*** 添加 联系我 的 url*/public static final String ADD_CONTACT_WAY = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_contact_way?access_token=#{ACCESS_TOKEN}";/*** 更新 联系我 的 url*/public static final String UPDATE_CONTACT_WAY = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/update_contact_way?access_token=#{ACCESS_TOKEN}";/*** 删除 联系我 的 url*/public static final String DEL_CONTACT_WAY = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/del_contact_way?access_token=#{ACCESS_TOKEN}";/*** 发送 欢迎语  的 url*/public static final String SEND_WELCOME_MSG = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/send_welcome_msg?access_token=#{ACCESS_TOKEN}";/*** 上传 临时素材 的 url*/public static final String UPLOAD_MEDIA = "https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token=";/*** 添加 入群欢迎语素材  的 url*/public static final String ADD_GROUP_WELCOME_TEMPLATE = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/group_welcome_template/add?access_token=#{ACCESS_TOKEN}";/*** 更新 入群欢迎语素材  的 url*/public static final String UPDATE_GROUP_WELCOME_TEMPLATE = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/group_welcome_template/edit?access_token=#{ACCESS_TOKEN}";/*** 删除 入群欢迎语素材  的 url*/public static final String DEL_GROUP_WELCOME_TEMPLATE = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/group_welcome_template/del?access_token=#{ACCESS_TOKEN}";/*** 发送 应用消息  的 url*/public static final String SEND_APPLICATION_MESSAGE = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=#{ACCESS_TOKEN}";/*** 获取待分配的离职成员列表 的url*/public static final String DIMISSION_WAIT_ALLOT_CLIENT = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_unassigned_list?access_token=#{ACCESS_TOKEN}";/*** 分配离职成员的客户*/public static final String DIMISSION_ALLOT_Client = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/resigned/transfer_customer?access_token=#{ACCESS_TOKEN}";/***  分配离职成员的客户群*/public static final String DIMISSION_ALLOT_GROUP = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/transfer?access_token=#{ACCESS_TOKEN}";/*** 创建企业群发*/public static final String ADD_CORP_MASS_URL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_msg_template?access_token=#{ACCESS_TOKEN}";/*** 编辑客户企业标签*/public static final String EDIT_CUSTOMER_CORP_TAG = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/mark_tag?access_token=#{ACCESS_TOKEN}";/*** 获取企业的jsapi_ticket*/public static final String CORP_JS_API_TICKET = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=";/*** 获取应用的jsapi_ticket*/public static final String AGENT_JS_API_TICKET = "https://qyapi.weixin.qq.com/cgi-bin/ticket/get?type=agent_config&access_token=";/*** 获取 开通了会话存档的员工*/public static final String MSG_AUDIT_EMPLOYEE = "https://qyapi.weixin.qq.com/cgi-bin/msgaudit/get_permit_user_list?access_token=#{ACCESS_TOKEN}";/*** corpid转换 的 url*/public static final String CORPID_TO_OPENCORPID = "https://qyapi.weixin.qq.com/cgi-bin/service/corpid_to_opencorpid?provider_access_token=";/*** userid转换 的 url*/public static final String USERID_TO_OPENUSERID = "https://qyapi.weixin.qq.com/cgi-bin/batch/userid_to_openuserid?access_token=";public static final String GET_NEW_EXTERNAL_USERID = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_new_external_userid?access_token=";public static final String UNIONID_TO_EXTERNAL_USERID = "https://qyapi.weixin.qq.com/cgi-bin/idconvert/unionid_to_external_userid?access_token=";public static final String EXTERNAL_USERID_TO_PENDING_ID = "https://qyapi.weixin.qq.com/cgi-bin/idconvert/batch/external_userid_to_pending_id?access_token=";public static final String FINISH_OPENID_MIGRATION = "https://qyapi.weixin.qq.com/cgi-bin/service/finish_openid_migration?provider_access_token=";
}
public class WeixinCorpKeyConst {public static String errcode = "errcode";public static String errmsg = "errmsg";// 服务商相关public static String corpId = "corpid";public static String authCorpId = "auth_corpid";public static String corpName = "corp_name";public static String suiteId = "suite_id";public static String suiteSecret = "suite_secret";public static String providerSecret = "provider_secret";public static String corpSecret = "corpsecret";public static String suiteTicket = "suite_ticket";public static String suiteAccessToken = "suite_access_token";public static String providerAccessToken = "provider_access_token";public static String preAuthCode = "pre_auth_code";public static String authCode = "auth_code";public static String permanentCode = "permanent_code";public static String authCorpInfo = "auth_corp_info";public static String authInfo = "auth_info";public static String agent = "agent";public static String agentId = "agentid";public static String accessToken = "access_token";}

WeiXinProviderConst 就不贴了,里面就是记录上面那几个参数的

到这里可以发现,其实对接企业微信并不难,麻烦的地方就在于各种配置各种参数,然后就是回调,回调这个后面有空我也会整理出来

相关文章:

Java企业微信服务商代开发获取AccessToken示例

这里主要针对的是企业微信服务商代开发模式 文档地址 可以看到里面大致有三种token,一个是服务商的token,一个是企业授权token,还有一个是应用的token 这里面主要有下面几个参数 首先是服务商的 corpid 和 provider_secret ,这个可…...

How does age change how you learn?(2)年龄如何影响学习能力?(二)

Do different people experience decline differently? 不同人经历的认知衰退会有不同吗? Do all people experience cognitive decline uniformly?Or do some people’s minds slip while others stay sharp much longer? 所有人经历的认知衰退都是一样的吗?还是有些人…...

可验证随机函数 vrf 概述

一、什么是VRF 背景: 在传统的区块链中,常用的随机算法是基于伪随机数生成器(Pseudorandom Number Generator,PRNG)的。PRNG是一种确定性算法,它根据一个初始种子生成一个看似随机的序列。在区块链中,通常使用的是伪随机数序列来选择区块的创建者、确定验证节点的轮换…...

鸿蒙双向绑定组件:TextArea、TextInput、Search、Checkbox,文本输入组件,图案解锁组件PatternLock

对象暂不支持双向绑定, 效果: 代码: Entry Component struct MvvmCase {StateisSelect: boolean falseStatesearchText: String ""StateinputText: string ""StateareaText: string ""build() {Grid() {G…...

JS 算法 - 计数器

theme: smartblue 题目描述 给定一个整型参数 n,请你编写并返回一个 counter 函数。这个 counter 函数最初返回 n,每次调用它时会返回前一个值加 1 的值 ( n , n 1 , n 2 ,等等)。 示例 1: 输入: n 10 ["cal…...

JavaScript基础——JavaScript运算符

赋值运算符 算术运算符 一元运算符 三元/三目运算符 比较运算符 逻辑运算符 运算符优先级 在JavaScript中,常见的运算符可以包括赋值运算符、一元运算符、算术运算符(二元运算符)、三元/三目运算符、比较运算符、逻辑运算符等&#xff0…...

E23.【C语言】练习:不创建第三个变量实现两个整数的交换

目录 题目条件 思路1( -) 思路2 (^)(XOR) 往期推荐 1.题目条件 禁止使用以上代码 2.思路1: -运算 aab; ba-b; aa-b; 但这样有潜在的问题 :a,b存储的数字过大,ab可能超过范围 因此改用思路2…...

如何搭建一个web系统?

需求 搭建一个web系统。 框架 设计:墨刀 前端:Vue.js 后端:Java 算法:Python 数据库:时序数据库,介绍 部署:Jekins https://www.jenkins.io/ 文档管理:Teambition 项目管理:禅道 代码管理:Gitlab 开发流程 设计文档和原型文档,功能接口设计&#xff0…...

三十种未授权访问漏洞复现 合集( 二 )

未授权访问漏洞介绍 未授权访问可以理解为需要安全配置或权限认证的地址、授权页面存在缺陷,导致其他用户可以直接访问,从而引发重要权限可被操作、数据库、网站目录等敏感信息泄露。---->目录遍历 目前主要存在未授权访问漏洞的有:NFS服务&a…...

C语言学习笔记[29]:函数①

函数 在C语言中,函数是一段可以完成特定功能的代码,它们可以被重复调用。 函数的分类: 库函数自定义函数 库函数 在C语言中,库函数是由系统提供的,用于完成特定功能的函数,这些函数被集合在一起&#…...

使用Springboot + netty 打造聊天服务之Nacos集群问题记录

目录 1、前言1.1、方法一1.2、方法二 2、方案二实战2.1、在netty服务里加上ws连接、中断事件2.2、在netty服务里加上消息服务 4、总结 使用Springboot netty 打造聊天服务系列文章 第一章 初始搭建工程 第二章 Nacos集群问题记录 1、前言 在使用Springboot Nacos Netty(Web…...

全网唯一!R语言顶刊配色包TheBestColors

与Matlab相比,R语言在绘图方面有着天然的优势。 比如在配色方面,R语言有各式各样现成的包,按理说配色这种事应该很方便才对。 但实际体验下来,发现似乎不是那么回事。 首先,你很难记住每个包的调用方法以及每种配色…...

链表题型思路错误总结

常见题目 206. 反转链表 关键点:定义前置指针。 在给cur.next复制前,需要定义好next节点防止断链。 public ListNode reverseList(ListNode head) {if (head null || head.next null) {return head;}ListNode pre null;ListNode cur head;while(cur…...

算法学习day28

一、寻找右区间(二分法) 题意:题目很容易理解 但是转换为二分法有点晦涩 给你一个区间数组 intervals ,其中 intervals[i] [starti, endi] ,且每个 starti 都 不同 。区间 i 的 右侧区间 可以记作区间 j ,并满足 startj > e…...

C语言基础题:迷宫寻路(C语言版)

1.题目描述 机器猫被困在一个矩形迷宫里。 迷宫可以视为一个n x m 矩阵,每个位置要么是空地,要么是墙。机器猫只能从一个空地走到其上、下、左、右的空地。 机器猫初始时位于(1,1)的位置,问能否走到(n,m)位置。 2.输入格式 第一行&#xff0…...

力扣-1两数之和2两数相加-2024/8/3

1、两数之和 解法一 暴力法(2个for循环) class Solution:def twoSum(self, nums: List[int], target: int) -> List[int]:for ii in range(len(nums)):for jj in range(ii1, len(nums)):if nums[ii]nums[jj] target:return [ii,jj]解法二 哈希表法…...

简站WordPress主题 专业的WordPress建站服务商

简站WordPress主题是一款备受推崇的WordPress主题,以其简洁、实用、无插件和更安全的特性脱颖而出。以下是关于简站WordPress主题的一些详细分析: 简站WordPress主题采用了扁平化设计风格,界面简洁明了,这使得网站看起来更加专业…...

Final Shell for Mac 虚拟机连接工具【简单易操作,轻松上手】【开发所需连接工具】

Mac分享吧 文章目录 效果一、下载软件二、安装软件三、运行测试安装完成!!! 效果 一、下载软件 下载软件 链接:http://www.macfxb.cn 二、安装软件 三、运行测试 安装完成!!!...

Oracle JDK:版本、支持与许可

文章目录 版本支持许可BCLOTNNFTCFAQ其他OpenJDK和其他的JDK实现JDK、JRE、JVMJava SE、Java EE、Java ME版本 Oracle JDK的最新版本和历史版本的官方下载地址(可查询版本发行说明等信息):https://www.oracle.com/cn/java/technologies/downloads/ 常规版本(非LTS):每隔…...

大模型学习笔记 - LLM 之RLHF人类对齐的简单总结

LLM - RLHF人类对齐的简单总结 LLM-人类对齐 1. RLHF(Reinforcement Learning from Human Feedback, RLHF),基于人类反馈的强化学习2 奖励模型训练3 强化学习训练 3.1 PPO介绍3.2 进阶的RLHF的介绍 3.2.1. 过程监督奖励模型3.2.2. 基于AI反馈的强化学习3.2.3. 非强化学习的对齐…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)&#xff0…...

剑指offer20_链表中环的入口节点

链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

Mysql8 忘记密码重置,以及问题解决

1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...

push [特殊字符] present

push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

Golang——7、包与接口详解

包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...

提升移动端网页调试效率:WebDebugX 与常见工具组合实践

在日常移动端开发中,网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时,开发者迫切需要一套高效、可靠且跨平台的调试方案。过去,我们或多或少使用过 Chrome DevTools、Remote Debug…...