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

springBoot整合讯飞星火认知大模型

1.概述

讯飞星火大模型是科大讯飞最近开放的拥有跨领域的知识和语言理解能力的大模型,能够完成问答对话和文学创作等。由于讯飞星火大模型最近可以免费试用,开发者都可以免费申请一个QPS不超过2的账号,用来实现对平台能力的验证。本文将利用Springboot框架对星火大模型进行整合,使其能够提供简单的问答能力。

2.Springboot整合大模型

2.1 申请开发者账号

讯飞星火认知大模型需要在讯飞星火官网进行申请(如下图所示),点击免费试用按钮,填写相关信息即可。
在这里插入图片描述
申请成功后可以在控制台查看对应的账号信息(如下图所示),APPID、APPKey、APPSecret都是唯一的,不要轻易泄漏。
在这里插入图片描述
至此,账号申请工作完成。由于本文主要展示的是利用JAVA语言来实现对大模型的调用,因此可以在API文档中下载JAVA带上下文的调用示例(如下图所示),通过该文档中的代码可以快速进行一个简单的小测试。
在这里插入图片描述

2.2 接口文档参数分析

在讯飞星火认知大模型的对接文档中,由于结果是流式返回的(不是一次性返回),因此案例中代码通过WebSocket长连接方式与服务器建立连接并发送请求,实时接收返回结果。接口请求参数具体如下:

{"header": {"app_id": "12345","uid": "12345"},"parameter": {"chat": {"domain": "general","temperature": 0.5,"max_tokens": 1024, }},"payload": {"message": {# 如果想获取结合上下文的回答,需要开发者每次将历史问答信息一起传给服务端,如下示例# 注意:text里面的所有content内容加一起的tokens需要控制在8192以内,开发者如有较长对话需求,需要适当裁剪历史信息"text": [{"role": "user", "content": "你是谁"} # 用户的历史问题{"role": "assistant", "content": "....."}  # AI的历史回答结果# ....... 省略的历史对话{"role": "user", "content": "你会做什么"}  # 最新的一条问题,如无需上下文,可只传最新一条问题]}}
}

上述请求中对应的参数解释如下:
在这里插入图片描述
在这里需要注意的是:app_id就是我们申请的APPID,uid可以区分不同用户。如果想要大模型能够根据结合上下文去进行问题解答,就要把历史问题和历史回答结果全部传回服务端。
针对上述请求,大模型的接口响应结果如下:

# 接口为流式返回,此示例为最后一次返回结果,开发者需要将接口多次返回的结果进行拼接展示
{"header":{"code":0,"message":"Success","sid":"cht000cb087@dx18793cd421fb894542","status":2},"payload":{"choices":{"status":2,"seq":0,"text":[{"content":"我可以帮助你的吗?","role":"assistant","index":0}]},"usage":{"text":{"question_tokens":4,"prompt_tokens":5,"completion_tokens":9,"total_tokens":14}}}
}

返回字段的解释如下:
在这里插入图片描述
需要注意的是:由于请求结果流式返回,因此需要根据header中的状态值status来进行判断(0代表首次返回结果,1代表中间结果,2代表最后一个结果),一次请求过程中可能会出现多个status为1的结果。

2.3 设计思路

本文设计思路如下图所示:
在这里插入图片描述
客户端通过webSocket的方式与整合大模型的Springboot进行连接建立,整合大模型的Springboot在接收到客户端请求时,会去创建与讯飞大模型服务端的webSocket长连接(每次请求会创建一个长连接,当获取到所有请求内容后,会断开长连接)。由于本文使用的账号为开发者账号(非付费模式),因此并发能力有限,本文采用加锁方式来控制请求访问。
Springboot服务与客户端的交互逻辑如下图所示:
在这里插入图片描述
Springboot服务与讯飞认知大模型的交互逻辑如下图所示:
在这里插入图片描述

2.3 项目结构

在这里插入图片描述

2.4 核心代码

2.4.1 pom依赖

 <properties><netty.verson>4.1.45.Final</netty.verson></properties><dependencies><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.8.2</version></dependency><dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId><version>4.9.0</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId></dependency><dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>${netty.verson}</version></dependency></dependencies>

2.4.2 application.properties配置文件

server.port=9903
xf.config.hostUrl=https://spark-api.xf-yun.com/v2.1/chat
xf.config.appId=efc8c037
xf.config.apiSecret=NDdkNWFiZjdlODM0YzEzNzhkZWRjYTU1
xf.config.apiKey=2733d38dd4717855c7de2f2450c028c2
#最大响应时间,单位:秒
xf.config.maxResponseTime=30

2.4.3 config配置文件

@Data
@Component
@ConfigurationProperties("xf.config")
public class XFConfig {private String appId;private String apiSecret;private String apiKey;private String hostUrl;private Integer maxResponseTime;}

2.4.4 listener文件

XFWebClient类主要用于发送请求至大模型服务端,内部有鉴权方法。

/*** @Author: ChengLiang* @CreateTime: 2023-10-19  11:04* @Description: TODO* @Version: 1.0*/
@Slf4j
@Component
public class XFWebClient {@Autowiredprivate XFConfig xfConfig;/*** @description: 发送请求至大模型方法* @author: ChengLiang* @date: 2023/10/19 16:27* @param: [用户id, 请求内容, 返回结果监听器listener]* @return: okhttp3.WebSocket**/public WebSocket sendMsg(String uid, List<RoleContent> questions, WebSocketListener listener) {// 获取鉴权urlString authUrl = null;try {authUrl = getAuthUrl(xfConfig.getHostUrl(), xfConfig.getApiKey(), xfConfig.getApiSecret());} catch (Exception e) {log.error("鉴权失败:{}", e);return null;}// 鉴权方法生成失败,直接返回 nullOkHttpClient okHttpClient = new OkHttpClient.Builder().build();// 将 https/http 连接替换为 ws/wss 连接String url = authUrl.replace("http://", "ws://").replace("https://", "wss://");Request request = new Request.Builder().url(url).build();// 建立 wss 连接WebSocket webSocket = okHttpClient.newWebSocket(request, listener);// 组装请求参数JSONObject requestDTO = createRequestParams(uid, questions);// 发送请求webSocket.send(JSONObject.toJSONString(requestDTO));return webSocket;}/*** @description: 鉴权方法* @author: ChengLiang* @date: 2023/10/19 16:25* @param: [讯飞大模型请求地址, apiKey, apiSecret]* @return: java.lang.String**/public static String getAuthUrl(String hostUrl, String apiKey, String apiSecret) throws Exception {URL url = new URL(hostUrl);// 时间SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);format.setTimeZone(TimeZone.getTimeZone("GMT"));String date = format.format(new Date());// 拼接String preStr = "host: " + url.getHost() + "\n" +"date: " + date + "\n" +"GET " + url.getPath() + " HTTP/1.1";// SHA256加密Mac mac = Mac.getInstance("hmacsha256");SecretKeySpec spec = new SecretKeySpec(apiSecret.getBytes(StandardCharsets.UTF_8), "hmacsha256");mac.init(spec);byte[] hexDigits = mac.doFinal(preStr.getBytes(StandardCharsets.UTF_8));// Base64加密String sha = Base64.getEncoder().encodeToString(hexDigits);// 拼接String authorization = String.format("api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"", apiKey, "hmac-sha256", "host date request-line", sha);// 拼接地址HttpUrl httpUrl = Objects.requireNonNull(HttpUrl.parse("https://" + url.getHost() + url.getPath())).newBuilder().//addQueryParameter("authorization", Base64.getEncoder().encodeToString(authorization.getBytes(StandardCharsets.UTF_8))).//addQueryParameter("date", date).//addQueryParameter("host", url.getHost()).//build();return httpUrl.toString();}/*** @description: 请求参数组装方法* @author: ChengLiang* @date: 2023/10/19 16:26* @param: [用户id, 请求内容]* @return: com.alibaba.fastjson.JSONObject**/public JSONObject createRequestParams(String uid, List<RoleContent> questions) {JSONObject requestJson = new JSONObject();// header参数JSONObject header = new JSONObject();header.put("app_id", xfConfig.getAppId());header.put("uid", uid);// parameter参数JSONObject parameter = new JSONObject();JSONObject chat = new JSONObject();chat.put("domain", "generalv2");chat.put("temperature", 0.5);chat.put("max_tokens", 4096);parameter.put("chat", chat);// payload参数JSONObject payload = new JSONObject();JSONObject message = new JSONObject();JSONArray jsonArray = new JSONArray();jsonArray.addAll(questions);message.put("text", jsonArray);payload.put("message", message);requestJson.put("header", header);requestJson.put("parameter", parameter);requestJson.put("payload", payload);return requestJson;}
}

XFWebSocketListener 类主要功能是与星火认知大模型建立webSocket连接,核心代码如下:

/*** @Author: ChengLiang* @CreateTime: 2023-10-18  10:17* @Description: TODO* @Version: 1.0*/
@Slf4j
public class XFWebSocketListener extends WebSocketListener {//断开websocket标志位private boolean wsCloseFlag = false;//语句组装buffer,将大模型返回结果全部接收,在组装成一句话返回private StringBuilder answer = new StringBuilder();public String getAnswer() {return answer.toString();}public boolean isWsCloseFlag() {return wsCloseFlag;}@Overridepublic void onOpen(WebSocket webSocket, Response response) {super.onOpen(webSocket, response);log.info("大模型服务器连接成功!");}@Overridepublic void onMessage(WebSocket webSocket, String text) {super.onMessage(webSocket, text);JsonParse myJsonParse = JSON.parseObject(text, JsonParse.class);log.info("myJsonParse:{}", JSON.toJSONString(myJsonParse));if (myJsonParse.getHeader().getCode() != 0) {log.error("发生错误,错误信息为:{}", JSON.toJSONString(myJsonParse.getHeader()));this.answer.append("大模型响应异常,请联系管理员");// 关闭连接标识wsCloseFlag = true;return;}List<Text> textList = myJsonParse.getPayload().getChoices().getText();for (Text temp : textList) {log.info("返回结果信息为:【{}】", JSON.toJSONString(temp));this.answer.append(temp.getContent());}log.info("result:{}", this.answer.toString());if (myJsonParse.getHeader().getStatus() == 2) {wsCloseFlag = true;//todo 将问答信息入库进行记录,可自行实现}}@Overridepublic void onFailure(WebSocket webSocket, Throwable t, Response response) {super.onFailure(webSocket, t, response);try {if (null != response) {int code = response.code();log.error("onFailure body:{}", response.body().string());if (101 != code) {log.error("讯飞星火大模型连接异常");}}} catch (IOException e) {log.error("IO异常:{}", e);}}
}

2.4.5 netty文件

NettyServer主要是用来监听指定端口,接收客户端的webSocket请求。

@Slf4j
@Component
public class NettyServer {/*** webSocket协议名*/private static final String WEBSOCKET_PROTOCOL = "WebSocket";/*** 端口号*/@Value("${webSocket.netty.port:62632}")private int port;/*** webSocket路径*/@Value("${webSocket.netty.path:/webSocket}")private String webSocketPath;@Autowiredprivate WebSocketHandler webSocketHandler;private EventLoopGroup bossGroup;private EventLoopGroup workGroup;/*** 启动** @throws InterruptedException*/private void start() throws InterruptedException {bossGroup = new NioEventLoopGroup();workGroup = new NioEventLoopGroup();ServerBootstrap bootstrap = new ServerBootstrap();// bossGroup辅助客户端的tcp连接请求, workGroup负责与客户端之前的读写操作bootstrap.group(bossGroup, workGroup);// 设置NIO类型的channelbootstrap.channel(NioServerSocketChannel.class);// 设置监听端口bootstrap.localAddress(new InetSocketAddress(port));// 连接到达时会创建一个通道bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {// 流水线管理通道中的处理程序(Handler),用来处理业务// webSocket协议本身是基于http协议的,所以这边也要使用http编解码器ch.pipeline().addLast(new HttpServerCodec());ch.pipeline().addLast(new ObjectEncoder());// 以块的方式来写的处理器ch.pipeline().addLast(new ChunkedWriteHandler());/*说明:1、http数据在传输过程中是分段的,HttpObjectAggregator可以将多个段聚合2、这就是为什么,当浏览器发送大量数据时,就会发送多次http请求*/ch.pipeline().addLast(new HttpObjectAggregator(8192));/*说明:1、对应webSocket,它的数据是以帧(frame)的形式传递2、浏览器请求时 ws://localhost:58080/xxx 表示请求的uri3、核心功能是将http协议升级为ws协议,保持长连接*/ch.pipeline().addLast(new WebSocketServerProtocolHandler(webSocketPath, WEBSOCKET_PROTOCOL, true, 65536 * 10));// 自定义的handler,处理业务逻辑ch.pipeline().addLast(webSocketHandler);}});// 配置完成,开始绑定server,通过调用sync同步方法阻塞直到绑定成功ChannelFuture channelFuture = bootstrap.bind().sync();log.info("Server started and listen on:{}", channelFuture.channel().localAddress());// 对关闭通道进行监听channelFuture.channel().closeFuture().sync();}/*** 释放资源** @throws InterruptedException*/@PreDestroypublic void destroy() throws InterruptedException {if (bossGroup != null) {bossGroup.shutdownGracefully().sync();}if (workGroup != null) {workGroup.shutdownGracefully().sync();}}@PostConstruct()public void init() {//需要开启一个新的线程来执行netty server 服务器new Thread(() -> {try {start();log.info("消息推送线程开启!");} catch (InterruptedException e) {e.printStackTrace();}}).start();}}

WebSocketHandler主要用于接收客户端发送的消息,并返回消息。

/*** @Author: ChengLiang* @CreateTime: 2023-10-17  15:14* @Description: TODO* @Version: 1.0*/
@Slf4j
@Component
@ChannelHandler.Sharable
public class WebSocketHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {@Autowiredprivate PushService pushService;@Overridepublic void handlerAdded(ChannelHandlerContext ctx) throws Exception {log.info("handlerAdded被调用,{}", JSON.toJSONString(ctx));//todo 添加校验功能,校验合法后添加到group中// 添加到channelGroup 通道组NettyGroup.getChannelGroup().add(ctx.channel());}@Overrideprotected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {log.info("服务器收到消息:{}", msg.text());// 获取用户ID,关联channelJSONObject jsonObject = JSON.parseObject(msg.text());String channelId = jsonObject.getString("uid");// 将用户ID作为自定义属性加入到channel中,方便随时channel中获取用户IDAttributeKey<String> key = AttributeKey.valueOf("userId");//String channelId = CharUtil.generateStr(uid);NettyGroup.getUserChannelMap().put(channelId, ctx.channel());boolean containsKey = NettyGroup.getUserChannelMap().containsKey(channelId);//通道已存在,请求信息返回if (containsKey) {//接收消息格式{"uid":"123456","text":"中华人民共和国成立时间"}String text = jsonObject.getString("text");//请求大模型服务器,获取结果ResultBean resultBean = pushService.pushMessageToXFServer(channelId, text);String data = (String) resultBean.getData();//推送pushService.pushToOne(channelId, JSON.toJSONString(data));} else {ctx.channel().attr(key).setIfAbsent(channelId);log.info("连接通道id:{}", channelId);// 回复消息ctx.channel().writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(ResultBean.success(channelId))));}}@Overridepublic void handlerRemoved(ChannelHandlerContext ctx) throws Exception {log.info("handlerRemoved被调用,{}", JSON.toJSONString(ctx));// 删除通道NettyGroup.getChannelGroup().remove(ctx.channel());removeUserId(ctx);}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {log.info("通道异常:{}", cause.getMessage());// 删除通道NettyGroup.getChannelGroup().remove(ctx.channel());removeUserId(ctx);ctx.close();}private void removeUserId(ChannelHandlerContext ctx) {AttributeKey<String> key = AttributeKey.valueOf("userId");String userId = ctx.channel().attr(key).get();NettyGroup.getUserChannelMap().remove(userId);}
}

2.4.6 service文件

PushServiceImpl 主要用于发送请求至讯飞大模型后台获取返回结果,以及根据指定通道发送信息至用户。

/*** @Author: ChengLiang* @CreateTime: 2023-10-17  15:58* @Description: TODO* @Version: 1.0*/
@Slf4j
@Service
public class PushServiceImpl implements PushService {@Autowiredprivate XFConfig xfConfig;@Autowiredprivate XFWebClient xfWebClient;@Overridepublic void pushToOne(String uid, String text) {if (StringUtils.isEmpty(uid) || StringUtils.isEmpty(text)) {log.error("uid或text均不能为空");throw new RuntimeException("uid或text均不能为空");}ConcurrentHashMap<String, Channel> userChannelMap = NettyGroup.getUserChannelMap();for (String channelId : userChannelMap.keySet()) {if (channelId.equals(uid)) {Channel channel = userChannelMap.get(channelId);if (channel != null) {ResultBean success = ResultBean.success(text);channel.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(success)));log.info("信息发送成功:{}", JSON.toJSONString(success));} else {log.error("该id对于channelId不存在!");}return;}}log.error("该用户不存在!");}@Overridepublic void pushToAll(String text) {String trim = text.trim();ResultBean success = ResultBean.success(trim);NettyGroup.getChannelGroup().writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(success)));log.info("信息推送成功:{}", JSON.toJSONString(success));}//测试账号只有2个并发,此处只使用一个,若是生产环境允许多个并发,可以采用分布式锁@Overridepublic synchronized ResultBean pushMessageToXFServer(String uid, String text) {RoleContent userRoleContent = RoleContent.createUserRoleContent(text);ArrayList<RoleContent> questions = new ArrayList<>();questions.add(userRoleContent);XFWebSocketListener xfWebSocketListener = new XFWebSocketListener();WebSocket webSocket = xfWebClient.sendMsg(uid, questions, xfWebSocketListener);if (webSocket == null) {log.error("webSocket连接异常");ResultBean.fail("请求异常,请联系管理员");}try {int count = 0;//参考代码中休眠200ms,若配置了maxResponseTime,若指定时间内未返回,则返回请求失败至前端int maxCount = xfConfig.getMaxResponseTime() * 5;while (count <= maxCount) {Thread.sleep(200);if (xfWebSocketListener.isWsCloseFlag()) {break;}count++;}if (count > maxCount) {return ResultBean.fail("响应超时,请联系相关人员");}return ResultBean.success(xfWebSocketListener.getAnswer());} catch (Exception e) {log.error("请求异常:{}", e);} finally {webSocket.close(1000, "");}return ResultBean.success("");}
}

所有代码可参考附录进行获取。

2.5 测试结果

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

3.小结

1.本文代码主要用于测试,若考虑并发及性能,需要在上述代码上进行优化;
2.讯飞星火认知大模型对于日常简单问题的问答效率较高,对诗词表达欠佳;
3.在本文代码中,部分代码仍可以优化,后续可以将此模块单独抽象成一个springboot-starter,引入即可使用。

4.参考文献

1.https://www.xfyun.cn/doc/spark/Web.html
2.https://console.xfyun.cn/services/bm2

5.附录

https://gitee.com/Marinc/nacos/tree/master/xunfei-bigModel

相关文章:

springBoot整合讯飞星火认知大模型

1.概述 讯飞星火大模型是科大讯飞最近开放的拥有跨领域的知识和语言理解能力的大模型&#xff0c;能够完成问答对话和文学创作等。由于讯飞星火大模型最近可以免费试用&#xff0c;开发者都可以免费申请一个QPS不超过2的账号&#xff0c;用来实现对平台能力的验证。本文将利用…...

JMM对数据竞争的定义

JMM对数据竞争的定义 Java内存模型规范对数据竞争的定义如下在一个线程中写一个变量&#xff0c;在另一个线程读同一个变量&#xff0c;而且写和读没有通过同步来排序。如果一个多线程程序能正确同步&#xff0c;这个程序将是一个没有数据竞争的程序。当程序未正确同步时&…...

民安智库(湖北知名满意度测评公司)食品安全满意度调查如何开展

食品安全问题一直以来都是社会各界广泛关注的焦点之一。近年来&#xff0c;食品安全事件频发&#xff0c;引起了公众的高度关注和担忧。因此&#xff0c;开展食品安全满意度调查&#xff0c;了解公众对食品安全状况的认知和满意程度&#xff0c;对于促进食品安全共建共治共享具…...

Rust 语法笔记

变量绑定&#xff08;声明变量&#xff09; let 变量名: 类型 变量值; let 变量名 变量值[类型]; // 整型 默认 i32&#xff1b;浮点 默认 f64所有的 let 绑定都必须尾接;&#xff0c;代码块也不例外。 mut 可以通过重新声明的方式来改变变量类型 可以下划线改善数字的可读…...

AI智慧安防智能监控平台如何做到健身房智能视频监控?

随着大家对健身的重视&#xff0c;健身房也开始遍地开花&#xff0c;健身房的兴起是必然的&#xff0c;但是健身房的管理不容疏忽&#xff0c;通过EasyCVR智能视频监控系统&#xff0c;则可以解决监管不足的问题。 1、安全摄像头布局 根据健身房的大小和布局&#xff0c;合理规…...

ps插件Coolorus for Mac中文激活版

Coolorus是一款非常实用的Photoshop插件&#xff0c;它为Photoshop增加了色环配色面板&#xff0c;让设计师可以更直观地选择颜色。同时&#xff0c;Coolorus还提供了多种专业配色方案&#xff0c;如鲜艳色、复古色、日常色等&#xff0c;设计师可以直接套用这些方案&#xff0…...

MySQL的索引——索引的介绍及其数据结构B+树 索引的类型 索引的使用及其失效场景 相关名词解释

前言 索引是存储引擎用于快速查找数据纪录的一种数据结构&#xff0c;索引是数据库中经常提及的一个词&#xff0c;究竟什么是索引&#xff0c;索引的数据结构是什么&#xff0c;索引有什么类型&#xff1f; 本篇博客尝试阐述数据库索引的相关内容&#xff0c;涉及什么是索引…...

第十六届中国智慧城市大会 | 国产化三维重建技术服务智慧城市建设

2023年10月13日&#xff0c;由武汉大势智慧科技有限公司、飞燕航空遥感技术有限公司主办的第十六届智慧城市大会-实景三维技术创新与应用论坛在广州成功举办。 来自实景三维、自然资源、数字孪生、AI大数据、航空遥感等多个领域的专家&#xff0c;深度分享各自的智慧城市建设经…...

通过数组的指针获得数组个数

这几天学习智能指针时,自己在练习写个管理数组指针的类时碰到了通过数组指针获取数组个数的问题 1.在网上查询了通过数组指针获取数组个数的方法,对于自定义数据在前四个节点保存了数组个数 Student* pAry new Student[3];size_t num *((size_t*)pAry - 1);//3测试是成功的…...

GeoServer改造Springboot启动四(解决post接口方法无法用@requestbody为入参的请求)

1、修改源码4 解决问题:解决Controller接口post方法(如图 19)无法用@requestbody为入参的 json数据进行请求,用swagger请求示例如图 20,具体错误呈现如图 21。 图 19Controller接口示例 图 20post接口请求示例 图 21post接...

C#,数值计算——分类与推理Phylagglomnode的计算方法与源程序

1 文本格式 using System; using System.Collections.Generic; namespace Legalsoft.Truffer { public class Phylagglomnode { public int mo { get; set; } public int ldau { get; set; } public int rdau { get; set; } public …...

mysql、oracle 构建数据

mysql 构建数据 --创建表 set sql_modeONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE TABLE vote_records_memory ( id int(10) unsigned NOT NULL AUTO_INCRE…...

二叉树;二叉树的前序、中序、后序遍历及查找;顺序存储二叉树;线索化二叉树

数组、链表和树存储方式分析 对于树结构&#xff0c;不论是查找修改还是增加删除&#xff0c;效率都比较高&#xff0c;结合了链表和数组的优点&#xff0c;如以下的二叉树&#xff1a; 1、数组的第一个元素作为第一个节点 2、数组的第二个元素3比7小&#xff0c;放在7的左边…...

有手就会做!保姆级Jmeter分布式压测操作流程(图文并茂)

分布式压测原理 分布式压测操作 保证本机和执行机的JDK和Jmeter版本一致配置Jmeter环境变量配置Jmeter配置文件 上传每个执行机服务jmeter chmod -R 755 apache-jmeter-5.1.1/ 执行机配置写自己的ip 控制机配置所有执行机ip,把server.rmi.ssl.disable改成true 将本机也作为压…...

澳洲谷揽GRANAR谷物分析仪维修GR-1800蛋白检测仪

澳洲GRANAR谷揽GR-1800谷物分析仪应用领域&#xff1a;大豆、油菜籽、亚麻籽 常用分析指标&#xff1a;蛋白质、芥酸、水分、灰分 、油脂等 分析时间&#xff1a;&#xff1c;3min 使用场景&#xff1a;谷物收购、生产加工、实验室 GR-1800i型号特点 1.检测时间由3分钟缩短…...

python基础语法(1)

基础语法 前言一、常量和表达式二、变量和类型变量是什么变量的语法(1)定义变量(2) 使用变量 变量的类型(1) 整数(2) 浮点数&#xff08;小数&#xff09;(3)字符串&#xff08;string&#xff09;可以使用单引号或双引号创建字符串(4) 布尔(5) 其他(1)类型决定了数据在内存中占…...

Web前端开发——新年倒计实时刷新

Web前端开发——年倒计实时刷新 H5(HTML5)前端开发是指使用HTML5、CSS3和JavaScript等技术进行网页和移动应用的开发。HTML5是最新的HTML标准,提供了丰富的语义化标签和功能,使得网页可以更加优雅和多样化。CSS3是用于样式表的升级版本,提供了更多的样式效果和布局控制能…...

ubuntu20.4 执行sudo apt-get update出现错误 libnettle.so.6 动态链接库错误

一、错误描述 sudo apt-get update 报错提示 libnettle.so.6 动态链接库错误 $ sudo apt update /usr/lib/apt/methods/https: error while loading shared libraries: libnettle.so.6: cannot open shared object file: No such file or directory /usr/lib/apt/methods/ht…...

机器人控制算法——TEB算法—Obstacle Avoidance and Robot Footprint Model(避障与机器人足迹模型)

1.How Obstacle Avoidance works 1.1处罚条款 避障是作为整体轨迹优化的一部分来实现的。显然&#xff0c;优化涉及到找到指定成本函数&#xff08;目标函数&#xff09;的最小成本解&#xff08;轨迹&#xff09;。简单地说&#xff1a;如果一个计划的&#xff08;未来&…...

谷歌浏览器报错:VM108:5 crbug/1173575, non-JS module files deprecated.

报错 解决 控制台调整为fast 3G...

基于算法竞赛的c++编程(28)结构体的进阶应用

结构体的嵌套与复杂数据组织 在C中&#xff0c;结构体可以嵌套使用&#xff0c;形成更复杂的数据结构。例如&#xff0c;可以通过嵌套结构体描述多层级数据关系&#xff1a; struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

3.3.1_1 检错编码(奇偶校验码)

从这节课开始&#xff0c;我们会探讨数据链路层的差错控制功能&#xff0c;差错控制功能的主要目标是要发现并且解决一个帧内部的位错误&#xff0c;我们需要使用特殊的编码技术去发现帧内部的位错误&#xff0c;当我们发现位错误之后&#xff0c;通常来说有两种解决方案。第一…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

跨链模式:多链互操作架构与性能扩展方案

跨链模式&#xff1a;多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈&#xff1a;模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展&#xff08;H2Cross架构&#xff09;&#xff1a; 适配层&#xf…...

Mac软件卸载指南,简单易懂!

刚和Adobe分手&#xff0c;它却总在Library里给你写"回忆录"&#xff1f;卸载的Final Cut Pro像电子幽灵般阴魂不散&#xff1f;总是会有残留文件&#xff0c;别慌&#xff01;这份Mac软件卸载指南&#xff0c;将用最硬核的方式教你"数字分手术"&#xff0…...

反射获取方法和属性

Java反射获取方法 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时访问和操作类的内部属性和方法。通过反射&#xff0c;可以动态地创建对象、调用方法、改变属性值&#xff0c;这在很多Java框架中如Spring和Hiberna…...

Spring AI 入门:Java 开发者的生成式 AI 实践之路

一、Spring AI 简介 在人工智能技术快速迭代的今天&#xff0c;Spring AI 作为 Spring 生态系统的新生力量&#xff0c;正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务&#xff08;如 OpenAI、Anthropic&#xff09;的无缝对接&…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...