java实现coze平台鉴权+工作流调用(踩坑记录)

问题偏多建议大家看完文章后再开始实现

OAuth鉴权

https://www.coze.cn/open/docs/developer_guides/preparation
在这里插入图片描述
https://www.coze.cn/open/docs/developer_guides/oauth_apps

OAuth 授权码鉴权

在这里插入图片描述
https://www.coze.cn/open/docs/developer_guides/oauth_code
在这里插入图片描述

创建OAuth应用

https://www.coze.cn/open/oauth/apps
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

获取访问令牌

在这里插入图片描述

https://www.coze.cn/api/permission/oauth2/authorize?response_type=code&client_id=22***替换为自己的.app.coze&redirect_uri=http://localhost:48080/admin-api/ai/coze/oauth&state=

最后的state= 无论使用与否都需要携带
在这里插入图片描述
这里如果本地的接口写好的话,他会直接请求接口做后续逻辑,我这里测试就一切从简
存好url中的code= 后面的授权码
在这里插入图片描述

获取 OAuth Access Token

在这里插入图片描述
在这里插入图片描述

postman访问

https://api.coze.cn/api/permission/oauth2/token
Authorization  Bearer  
{
"grant_type":"authorization_code",
"code":"code_",
"redirect_uri":"http://localhost:48080/admin-api/ai/coze/oauth"
,"client_id":""}

在这里插入图片描述

在这里插入图片描述
以上报错是code有问题,重新授权拿新的授权码再试就成功了
在这里插入图片描述

coze配置文件


import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;/*** @author YXY* @date 2025-03-24* @description coze配置文件*/
@Data
@RefreshScope
public class CozeProperties {@Value("${coze.clientSecret}")private String clientSecret;@Value("${coze.grantType}")private String grantType;@Value("${coze.code}")private String code;@Value("${coze.clientId}")private String clientId;@Value("${coze.redirectUri}")private String redirectUri;@Value("${coze.oAuthAccessTokenUri}")private String oAuthAccessTokenUri;}

配置文件

coze:clientSecret: 创建 OAuth 应用时获取的客户端密钥grantType: authorization_codecode: 授权码clientId: 创建 OAuth 应用时获取的客户端 ID。 redirectUri: 创建 OAuth 应用时指定的重定向 URL。 oAuthAccessTokenUri: https://api.coze.cn/api/permission/oauth2/token
import com.alibaba.fastjson.JSONObject;
import com.goodsoft.shrk.module.ai.controller.admin.coze.vo.CozeAuthRespVo;
import com.goodsoft.shrk.module.ai.enums.coze.CozeEnum;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.stereotype.Component;import java.io.IOException;
import java.util.concurrent.TimeUnit;
/*** @author YXY* @date 2025-03-24* @description coze API* */
@Component
@Slf4j
public class CozeApiClient {private static final String MEDIA_TYPE_JSON = "application/json; charset=utf-8";private final static OkHttpClient client = new OkHttpClient().newBuilder().connectionPool(new ConnectionPool(100, 5, TimeUnit.MINUTES)).readTimeout(60 * 10, TimeUnit.SECONDS).build();private static final String ERROR_MESSAGE = "Unexpected code: ";@Resourceprivate CozeProperties cozeProperties;/***  获取token* @return*/public CozeAuthRespVo getAccessToken() {try {JSONObject jsonObject = new JSONObject();jsonObject.put(CozeEnum.GRANT_TYPE.getName(), cozeProperties.getGrantType());jsonObject.put(CozeEnum.CODE.getName(), cozeProperties.getCode());jsonObject.put(CozeEnum.CLIENT_ID.getName(), cozeProperties.getClientId());jsonObject.put(CozeEnum.REDIRECT_URI.getName(), cozeProperties.getRedirectUri());RequestBody body = RequestBody.create(jsonObject.toString(), MediaType.get(MEDIA_TYPE_JSON));Request request = buildAuthRequest(cozeProperties.getOAuthAccessTokenUri(), body);String res = executeRequest(request);CozeAuthRespVo cozeAuthRespVo = JSONObject.parseObject(res, CozeAuthRespVo.class);return cozeAuthRespVo;} catch (IOException e) {e.printStackTrace();throw new RuntimeException(e);}}/***  构建获取鉴权请求* @param url* @param body* @return*/private Request buildAuthRequest(String url, RequestBody body) {return new Request.Builder().url(url).addHeader(CozeEnum.AUTHORIZATION.getName(), CozeEnum.BEARER+ cozeProperties.getClientSecret()).post(body).build();}/*** 发送请求* @param request* @return* @throws IOException*/private String executeRequest(Request request) throws IOException {try (Response response = client.newCall(request).execute()) {if (!response.isSuccessful()) {System.out.println(response.body().string());throw new IOException(ERROR_MESSAGE + response);}String res = response.body().string();return res;}}
}

以上获取 Access Token 成功了,但是根据官网调用 刷新OAuth Access Token 一直失败
所以打算换种方式实现

采用官网提供的SDK进行实现
在这里插入图片描述
官方github的demo地址:https://github.com/coze-dev/coze-java/tree/main/example/src/main/java/example

pom中引入
因为我的项目中有使用 okhttp3 版本冲突了,所以这里处理了下

        <dependency><groupId>com.coze</groupId><artifactId>coze-api</artifactId><version>LATEST</version><exclusions><exclusion><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId></exclusion></exclusions></dependency>

CozeProperties 配置文件

package com.goodsoft.shrk.module.ai.config.coze;import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;/*** @author YXY* @date 2025-03-24* @description coze鉴权配置文件*/
@Data
@RefreshScope
public class CozeProperties {@Value("${coze.clientSecret}")private String clientSecret;@Value("${coze.code}")private String code;@Value("${coze.clientId}")private String clientId;@Value("${coze.redirectUri}")private String redirectUri;
}
import com.coze.openapi.client.auth.OAuthToken;
import com.coze.openapi.service.auth.WebOAuthClient;
import com.coze.openapi.service.config.Consts;
import com.goodsoft.shrk.framework.redis.config.CommonCache;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.util.concurrent.TimeUnit;/*** @author YXY* @date 2025-03-24* @description coze API*/
@Component
@Slf4j
public class CozeApiClient {@Resourceprivate CozeProperties cozeProperties;@Resourceprivate CommonCache commonCache;@Autowiredprivate RedissonClient redissonClient;private static final String LOCK_KEY = "COZE_ACCESS_TOKEN_LOCK";private static final String COZE_ACCESS_TOKEN= "coze_access_token:";/***  获取token* @return*/public OAuthToken getAccessToken() {if (commonCache.hasKey(COZE_ACCESS_TOKEN)){return commonCache.getVal(COZE_ACCESS_TOKEN);}boolean lockAcquired = false;int maxRetries = 5; // 最大重试次数int retries = 0; // 当前重试次数RLock lock = redissonClient.getLock(LOCK_KEY);if (!commonCache.hasKey(COZE_ACCESS_TOKEN)){while (!lockAcquired && retries < maxRetries) {try {// 尝试获取锁,最多等待 5 秒钟lockAcquired = lock.tryLock(5, TimeUnit.SECONDS);if (lockAcquired) {try {WebOAuthClient oauth =new WebOAuthClient.WebOAuthBuilder().clientID(cozeProperties.getClientId()).clientSecret(cozeProperties.getClientSecret()).baseURL(Consts.COZE_CN_BASE_URL).build();OAuthToken resp = oauth.getAccessToken(cozeProperties.getCode(), cozeProperties.getRedirectUri());log.info( "获取CozeApi-token成功:{}", resp);resp = oauth.refreshToken(resp.getRefreshToken());log.info( "刷新CozeApi-token成功:{}", resp);commonCache.set(COZE_ACCESS_TOKEN,resp,resp.getExpiresIn()-60,TimeUnit.SECONDS);} finally {lock.unlock(); // 释放锁}} else {// 未能获取锁,重试retries++;Thread.sleep(100); // 重试间隔}} catch (InterruptedException e) {// 处理中断异常e.printStackTrace();// 尝试重新标记中断状态,并继续重试Thread.currentThread().interrupt();}}}return commonCache.getVal(COZE_ACCESS_TOKEN);}
}

测试鉴权成功,进行下一步

执行工作流

找到工作流的 workflow_id
在这里插入图片描述

在这里插入图片描述
demo

 public void reqWorkflows(){OAuthToken accessToken = getAccessToken();TokenAuth authCli = new TokenAuth(accessToken.getAccessToken());CozeAPI coze =new CozeAPI.Builder().baseURL(Consts.COZE_CN_BASE_URL).auth(authCli).readTimeout(10000).build();HashMap<String, Object> map = new HashMap<>();map.put("input", "生成一个设计方案");map.put("fileUrl", "https://***.pdf");map.put("title", "标题");RunWorkflowResp workflowResp = coze.workflows().runs().create(RunWorkflowReq.builder().workflowID("******工作流ID").parameters(map).build());System.out.println(workflowResp);}

做到这里我发现这个授权码code用一次就失效了,每次都得点击页面授权,这个需要前端打开授权页,然后用户点击授权成功回调接口执行后续逻辑,而我们需要的业务没有页面授权这一操作,
应该采用OAuth JWT 授权

OAuth JWT 授权

https://www.coze.cn/open/docs/developer_guides/oauth_jwt
在这里插入图片描述
重新创建JWT应用
在这里插入图片描述
点击创建Key 自动下载私钥 复制公钥备用
在这里插入图片描述
在这里插入图片描述

将私钥 private_key.pem 文件放到项目的resources
在这里插入图片描述

CozeProperties配置文件


import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;/*** @author YXY* @date 2025-03-24* @description coze鉴权配置文件*/
@Data
@RefreshScope
public class CozeProperties {@Value("${coze.clientId}")private String clientId;@Value("${coze.jwt.publicKey}")private String publicKey;public String getPrivateKey() {try (InputStream inputStream = CozeApiClient.class.getClassLoader().getResourceAsStream("private_key.pem")) {if (inputStream == null) {throw new RuntimeException("私钥文件未找到");}return new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);} catch (IOException e) {throw new RuntimeException("读取私钥文件失败", e);}}
}

在这里插入图片描述

根据官网提供方式进行测试:

public static void main(String[] args) {String jwtOauthClientID = "应用ID";String jwtOauthPrivateKey = getPrivateKey();String jwtOauthPublicKeyID = "公钥";JWTOAuthClient oauth = null;try {oauth =new JWTOAuthClient.JWTOAuthBuilder().clientID(jwtOauthClientID).privateKey(jwtOauthPrivateKey).publicKey(jwtOauthPublicKeyID).baseURL(Consts.COZE_CN_BASE_URL).build();} catch (Exception e) {e.printStackTrace();return;}try {OAuthToken resp = oauth.getAccessToken();System.out.println(resp);} catch (Exception e) {e.printStackTrace();}}public static String getPrivateKey() {try (InputStream inputStream = CozeApiClient.class.getClassLoader().getResourceAsStream("private_key.pem")) {if (inputStream == null) {throw new RuntimeException("私钥文件未找到");}return new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);} catch (IOException e) {throw new RuntimeException("读取私钥文件失败", e);}}

运行报错
在这里插入图片描述
找到原因:https://github.com/coze-dev/coze-java?tab=readme-ov-file#jwt-oauth-app
需要自己实现com.coze.openapi.service.auth.JWTBuilder这个接口
https://github.com/coze-dev/coze-java/blob/main/example/src/main/java/example/auth/ExampleJWTBuilder.java

在这里插入图片描述
需要实现自己的 JWTBuilder


import com.coze.openapi.service.auth.JWTBuilder;
import com.coze.openapi.service.auth.JWTPayload;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.NoArgsConstructor;import java.security.PrivateKey;
import java.util.Map;/*** @author YXY* @date 2025-03-24* @description*/
@NoArgsConstructor
public class ExampleJWTBuilder implements JWTBuilder {@Overridepublic String generateJWT(PrivateKey privateKey, Map<String, Object> header, JWTPayload payload) {try {JwtBuilder jwtBuilder =Jwts.builder().setHeader(header).setIssuer(payload.getIss()).setAudience(payload.getAud()).setIssuedAt(payload.getIat()).setExpiration(payload.getExp()).setId(payload.getJti()).signWith(privateKey, SignatureAlgorithm.RS256);if (payload.getSessionName() != null) {jwtBuilder.claim("session_name", payload.getSessionName());}return jwtBuilder.compact();} catch (Exception e) {throw new RuntimeException("Failed to generate JWT", e);}}
}

实现后进行使用在这里插入图片描述

成功
在这里插入图片描述

package com.goodsoft.shrk.module.ai.config.coze;import com.coze.openapi.client.auth.OAuthToken;
import com.coze.openapi.service.auth.JWTOAuthClient;
import com.coze.openapi.service.config.Consts;
import com.goodsoft.shrk.framework.redis.config.CommonCache;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.util.concurrent.TimeUnit;import static com.goodsoft.shrk.module.system.dal.redis.RedisKeyConstants.COZE_ACCESS_TOKEN;/*** @author YXY* @date 2025-03-24* @description coze鉴权配置文件*/
@Component
@Slf4j
public class CozeApiClient {@Resourceprivate CozeProperties cozeProperties;@Resourceprivate CommonCache commonCache;@Autowiredprivate RedissonClient redissonClient;private static final String LOCK_KEY = "COZE_ACCESS_TOKEN_LOCK";/***  获取token* @return*/public OAuthToken getAccessToken() {if (commonCache.hasKey(COZE_ACCESS_TOKEN)){return commonCache.getVal(COZE_ACCESS_TOKEN);}boolean lockAcquired = false;int maxRetries = 5; // 最大重试次数int retries = 0; // 当前重试次数RLock lock = redissonClient.getLock(LOCK_KEY);if (!commonCache.hasKey(COZE_ACCESS_TOKEN)){while (!lockAcquired && retries < maxRetries) {try {// 尝试获取锁,最多等待 5 秒钟lockAcquired = lock.tryLock(5, TimeUnit.SECONDS);if (lockAcquired) {try {OAuthToken oAuthToken = getOAuthToken();commonCache.set(COZE_ACCESS_TOKEN,oAuthToken,oAuthToken.getExpiresIn()-60,TimeUnit.SECONDS);} finally {lock.unlock(); // 释放锁}} else {// 未能获取锁,重试retries++;Thread.sleep(100); // 重试间隔}} catch (InterruptedException e) {// 处理中断异常e.printStackTrace();// 尝试重新标记中断状态,并继续重试Thread.currentThread().interrupt();}}}return commonCache.getVal(COZE_ACCESS_TOKEN);}public OAuthToken getOAuthToken() {String jwtOauthClientID = cozeProperties.getClientId();String jwtOauthPrivateKey = cozeProperties.getPrivateKey();String jwtOauthPublicKeyID = cozeProperties.getPublicKey();OAuthToken resp = null;try {JWTOAuthClient oauth =new JWTOAuthClient.JWTOAuthBuilder().clientID(jwtOauthClientID).privateKey(jwtOauthPrivateKey).publicKey(jwtOauthPublicKeyID).baseURL(Consts.COZE_CN_BASE_URL).jwtBuilder(new ExampleJWTBuilder()).build();resp = oauth.getAccessToken();System.out.println(resp);} catch (Exception e) {e.printStackTrace();}return resp;}}

鉴权搞定之后进行调用工作流

工作流入参实体,工作流id 和 工作流入参数据

package com.goodsoft.shrk.module.ai.controller.admin.coze.vo;import lombok.Data;import java.util.HashMap;/*** @author YXY* @date 2025-03-24* @description*/
@Data
public class WorkflowsReqVo {private String workflowID;private HashMap<String, Object> parameters;
}

CozeApiClient
这里的 COZE_ACCESS_TOKEN = "coze_access_token:"; 提取到redis常量池中了

import com.coze.openapi.client.auth.OAuthToken;
import com.coze.openapi.client.workflows.run.RunWorkflowReq;
import com.coze.openapi.client.workflows.run.RunWorkflowResp;
import com.coze.openapi.service.auth.JWTOAuthClient;
import com.coze.openapi.service.auth.TokenAuth;
import com.coze.openapi.service.config.Consts;
import com.coze.openapi.service.service.CozeAPI;
import com.goodsoft.shrk.framework.redis.config.CommonCache;
import com.goodsoft.shrk.module.ai.controller.admin.coze.vo.WorkflowsReqVo;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.util.concurrent.TimeUnit;import static com.goodsoft.shrk.module.system.dal.redis.RedisKeyConstants.COZE_ACCESS_TOKEN;/*** @author YXY* @date 2025-03-24* @description coze鉴权配置文件*/
@Component
@Slf4j
public class CozeApiClient {@Resourceprivate CozeProperties cozeProperties;@Resourceprivate CommonCache commonCache;@Autowiredprivate RedissonClient redissonClient;private static final String LOCK_KEY = "COZE_ACCESS_TOKEN_LOCK";/***  获取token* @return*/public OAuthToken getAccessToken() {if (commonCache.hasKey(COZE_ACCESS_TOKEN)){return commonCache.getVal(COZE_ACCESS_TOKEN);}boolean lockAcquired = false;int maxRetries = 5; // 最大重试次数int retries = 0; // 当前重试次数RLock lock = redissonClient.getLock(LOCK_KEY);if (!commonCache.hasKey(COZE_ACCESS_TOKEN)){while (!lockAcquired && retries < maxRetries) {try {// 尝试获取锁,最多等待 5 秒钟lockAcquired = lock.tryLock(5, TimeUnit.SECONDS);if (lockAcquired) {try {OAuthToken oAuthToken = getOAuthToken();commonCache.set(COZE_ACCESS_TOKEN,oAuthToken,oAuthToken.getExpiresIn()-60,TimeUnit.SECONDS);} finally {lock.unlock(); // 释放锁}} else {// 未能获取锁,重试retries++;Thread.sleep(100); // 重试间隔}} catch (InterruptedException e) {// 处理中断异常e.printStackTrace();// 尝试重新标记中断状态,并继续重试Thread.currentThread().interrupt();}}}return commonCache.getVal(COZE_ACCESS_TOKEN);}public OAuthToken getOAuthToken() {String jwtOauthClientID = cozeProperties.getClientId();String jwtOauthPrivateKey = cozeProperties.getPrivateKey();String jwtOauthPublicKeyID = cozeProperties.getPublicKey();OAuthToken resp = null;try {JWTOAuthClient oauth =new JWTOAuthClient.JWTOAuthBuilder().clientID(jwtOauthClientID).privateKey(jwtOauthPrivateKey).publicKey(jwtOauthPublicKeyID).baseURL(Consts.COZE_CN_BASE_URL).jwtBuilder(new ExampleJWTBuilder()).build();resp = oauth.getAccessToken();System.out.println(resp);} catch (Exception e) {e.printStackTrace();}return resp;}/*** 调用工作流*/public void reqWorkflows(WorkflowsReqVo req){OAuthToken accessToken = getAccessToken();TokenAuth authCli = new TokenAuth(accessToken.getAccessToken());CozeAPI coze =new CozeAPI.Builder().baseURL(Consts.COZE_CN_BASE_URL).auth(authCli).readTimeout(10000).build();RunWorkflowResp workflowResp = coze.workflows().runs().create(RunWorkflowReq.builder().workflowID(req.getWorkflowID()).parameters(req.getParameters()).isAsync(true).build());System.out.println(workflowResp);}}

因为工作流执行时间较长,我的工作流配置了执行完成后 http请求我的接口进行后续逻辑处理,所以这里开启了异步执行
isAsync(true) 代表异步调用工作流

coze工作流发送http请求:https://blog.csdn.net/YXWik/article/details/146398637
在这里插入图片描述
成功

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/39424.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025年优化算法:龙卷风优化算法(Tornado optimizer with Coriolis force,TOC)

龙卷风优化算法&#xff08;Tornado optimizer with Coriolis force&#xff09;是发表在中科院二区期刊“ARTIFICIAL INTELLIGENCE REVIEW”&#xff08;IF&#xff1a;11.7&#xff09;的2025年智能优化算法 01.引言 当自然界的狂暴之力&#xff0c;化身数字世界的智慧引擎&…

面试题分享-多线程顺序打印奇偶数

目录 1.题目详情 2.解题思路 2.1.分析题目 2.2.解析思路 3.代码实现 4.运行结果 1.题目详情 昨天刷抖音&#xff0c;遇到一个面试题&#xff0c;描述如下&#xff1a; 请使用两个线程&#xff0c;分别顺序交替打印奇数和偶数&#xff0c;直到10为止。例如有两个线程&#…

QuecPython 网络协议之TCP/UDP协议最祥解析

概述 IP 地址与域名 IP 地址是网络中的主机地址&#xff0c;用于两台网络主机能够互相找到彼此&#xff0c;这也是网络通信能够成功进行的基础。IP 地址一般以点分十进制的字符串来表示&#xff0c;如192.168.1.1。 ​ 我们日常访问的网站&#xff0c;其所在的服务器主机都有…

React - LineChart组件编写(用于查看每日流水图表)

一、简单版本 LineChart.tsx // src/component/LineChart/LineChart.tsx import React, {useEffect,useRef,useImperativeHandle,forwardRef,useMemo,useCallback, } from react; import * as echarts from echarts/core; import type { ComposeOption } from echarts/core; …

医学图像分割数据集肺分割数据labelme格式6299张2类别

数据集格式&#xff1a;labelme格式(不包含mask文件&#xff0c;仅仅包含jpg图片和对应的json文件) 图像分辨率&#xff1a;1024x1024 图片数量(jpg文件个数)&#xff1a;6299 标注数量(json文件个数)&#xff1a;6299 标注类别数&#xff1a;2 标注类别名称:["leftl…

帕金森病致生活艰难,如何缓解心理负担?

你是否留意到身边有人手部不由自主地颤抖&#xff0c;且肢体变得僵硬&#xff0c;行动也愈发迟缓&#xff1f;这很可能是帕金森病的症状。帕金森病是一种常见的神经系统退行性疾病&#xff0c;多发生于中老年人。​ 静止性震颤往往是帕金森病的首发症状&#xff0c;患者在安静状…

从零构建大语言模型全栈开发指南:第二部分:模型架构设计与实现-2.1.1自注意力机制(Scaled Dot-Product Attention)的逐行代码实现

👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 2.1.1 自注意力机制(Scaled Dot-Product Attention)的逐行代码实现1. 自注意力机制的核心原理与数学表达1.1 注意力计算的三元组:`Q, K, V`2. 逐行代码实现与解析2.1 输入嵌入与权重矩阵初始化2.2 完…

机械臂【逆运动学】

回顾正运动学fk&#xff1a; IK&#xff1a; 几何法 代数法 六轴 456轴交再同一点 有解析解 下列公式为正运动学部分结论 a和d是长度 &#xff0c;theta和alfa是角度 **疑问&#xff1a;alfa00&#xff1f; Z轴互相平行 ** 已知末端要在空间XYZ处如下 绿色项&#x…

IDEA批量替换项目下所有文件中的特定内容

文章目录 1. 问题引入2. 批量替换项目下所有文件中的特定内容2.1 右键项目的根目录&#xff0c;点击在文件中替换2.2 输入要替换的内容 3. 解决替换一整行文本后出现空行的问题4. 增加筛选条件提高匹配的精确度 更多 IDEA 的使用技巧可以查看 IDEA 专栏&#xff1a; IDEA 1. 问…

Ubuntu22.04美化MacOS主题

安装Tweaks 参考Ubuntu 22.04 桌面美化成Mac风格这篇更好点 sudo apt install gnome-tweaks gnome-shell-extensions -y安装macos主题 git clone https://github.com/vinceliuice/WhiteSur-gtk-theme.git # 进到文件目录 ./install.sh -t all -N glassy sudo ./tweaks.sh -g…

基于Python的机器学习入门指南

在当今数字化时代&#xff0c;机器学习&#xff08;Machine Learning&#xff09;已经成为科技领域中最热门的话题之一。它不仅改变了我们对数据的理解和处理方式&#xff0c;还在许多行业中得到了广泛应用&#xff0c;如金融、医疗、交通等。Python作为一门强大的编程语言&…

Python前缀和(例题:异或和,求和)

前缀和 前缀和&#xff1a;对于一个长度为n的列表a&#xff0c;前缀和为&#xff1a; sum[i]a[0]a[1]...a[i] 前缀和的性质&#xff1a; 第一条性质用于处理出前缀和&#xff1a; Sum[i]Sum[i-1]a[i] 第二条性质可以在O(l)的时间内求出区间和&#xff1a; a[l]....a[r] S…

统计矩的高阶推广:经验还是理论推导?

矩的发展既是经验总结的结果&#xff0c;也是数学理论推导的产物。研究者们在分析数据、描述物理现象的过程中&#xff0c;发现了低阶矩与日常物理概念&#xff08;如质心、惯性&#xff09;之间的紧密联系&#xff0c;而高阶矩的应用往往出现在更复杂的数学体系中&#xff0c;…

安宝特分享|AR智能装备赋能企业效率跃升

AR装备开启智能培训新时代 在智能制造与数字化转型浪潮下&#xff0c;传统培训体系正面临深度重构。安宝特基于工业级AR智能终端打造的培训系统&#xff0c;可助力企业构建智慧培训新生态。 AR技术在不同领域的助力 01远程指导方面 相较于传统视频教学的单向输出模式&#x…

《软件安装与使用教程》— NVIDIA CUDA在Windows的安装教程

《软件安装与使用教程》— NVIDIA CUDA在Windows的安装教程 Installed: - Nsight Monitor Not Installed: - Nsight for Visual Studio 2019 Reason: VS2019 was not found - Nsight for Visual Studio 2017 Reason: VS2017 was not found - Integrated Graphics Frame Debugge…

领域驱动设计(DDD)实践入门

文章目录 1.认识领域驱动设计1.1 简介1.2 发展历史1.3 DDD 的兴起 2.从一个简单案例2.1 转账需求2.2 设计的问题2.3 违反的设计原则 3.使用 DDD 进行重构抽象数据存储层抽象第三方服务抽象中间件封装业务逻辑重构后的架构 4.小结参考文献 1.认识领域驱动设计 1.1 简介 领域驱…

OrangePi 5B 内核开启 CONFIG_CIFS 通过 Samba 挂载 NAS 路径

文章目录 OrangePi 5B 内核开启 CONFIG_CIFS 通过 Samba 挂载 NAS 路径获取 Linux SDK 的源码从 github 下载 orangepi-build编译 linux 内核更新开发板内核上传编译好的 deb 包到开发板登录开发板&#xff0c;卸载旧内核安装新内核重启开发板 Ubuntu & Debian 系统下挂载 …

8662 234的和

8662 234的和 ⭐️难度&#xff1a;中等 &#x1f31f;考点&#xff1a;模拟、二维前缀和 &#x1f4d6; &#x1f4da; import java.util.Arrays; import java.util.LinkedList; import java.util.Queue; import java.util.Scanner;public class Main {static int[] a ne…

softmax回归的实现

softmax回归是logistic回归在多分类问题上的推广 原理 网络架构&#xff1a; 常用的方式是独热编码&#xff1a; 如果下面这样&#xff0c;会使得分类器更倾向于把奶牛和耗牛预测到一起&#xff0c;因为预测为海公牛惩罚更大&#xff0c;这样是不合理的。 损失函数&…

架构师面试(十九):IM 架构

问题 IM 系统从架构模式上包括 【介绍人模式】和 【代理人模式】。介绍人模式也叫直连模式&#xff0c;消息收发不需要服务端的参与&#xff0c;即客户端之间直连的方式&#xff1b;代理人模式也叫中转模式&#xff0c;消息收发需要服务端进行中转。 下面关于这两类模式描述的…