接上回--综合AIDemo测试
一,前言
上回外挂了知识库之后,我们需要使用知识库中的信息,让AI为我们实际处理业务上的需求。
这里我们让AI扮演公司的人事助手,帮我们处理员工请假的业务。
具体流程如下
- 感知用户需要请假
- 提取用户请假信息
- 获取用户数据库中的信息
- 根据用户角色判断请假时长是否符合公司要求(或者是否需要推送给上级审批)
- 不符合返回理由,符合返回确认信息
- 用户确认后往数据库中写入请假信息
在获取请假信息这块上,如果我们手动去提取用户的msg,那么会有很大的可能会提取失败,所以这块尽可能让ai从我们的对话上下文去提取所需要的信息。
二,需要注意的问题
另外有个很关键的点,就是在使用fuctions处理问题的时候,需要注意,fuctions返回的应该是严格的数据格式,而不能是一段对话。因为这段代码
if (!isProxyToolCalls(prompt, this.defaultOptions)&& isToolCall(response, Set.of(OpenAiApi.ChatCompletionFinishReason.TOOL_CALLS.name(),OpenAiApi.ChatCompletionFinishReason.STOP.name()))) {var toolCallConversation = handleToolCalls(prompt, response);// Recursively call the call method with the tool call message// conversation that contains the call responses.return this.internalCall(new Prompt(toolCallConversation, prompt.getOptions()), response);}
这段代码中调用完fuction方法后会再次调用aiCall进行对话请求,这个时候你可能就会陷入无尽的loop中了。
方法的完整代码如下
public ChatResponse internalCall(Prompt prompt, ChatResponse previousChatResponse) {ChatCompletionRequest request = createRequest(prompt, false);ChatModelObservationContext observationContext = ChatModelObservationContext.builder().prompt(prompt).provider(OpenAiApiConstants.PROVIDER_NAME).requestOptions(buildRequestOptions(request)).build();ChatResponse response = ChatModelObservationDocumentation.CHAT_MODEL_OPERATION.observation(this.observationConvention, DEFAULT_OBSERVATION_CONVENTION, () -> observationContext,this.observationRegistry).observe(() -> {ResponseEntity<ChatCompletion> completionEntity = this.retryTemplate.execute(ctx -> this.openAiApi.chatCompletionEntity(request, getAdditionalHttpHeaders(prompt)));var chatCompletion = completionEntity.getBody();if (chatCompletion == null) {logger.warn("No chat completion returned for prompt: {}", prompt);return new ChatResponse(List.of());}List<Choice> choices = chatCompletion.choices();if (choices == null) {logger.warn("No choices returned for prompt: {}", prompt);return new ChatResponse(List.of());}List<Generation> generations = choices.stream().map(choice -> {// @formatter:offMap<String, Object> metadata = Map.of("id", chatCompletion.id() != null ? chatCompletion.id() : "","role", choice.message().role() != null ? choice.message().role().name() : "","index", choice.index(),"finishReason", choice.finishReason() != null ? choice.finishReason().name() : "","refusal", StringUtils.hasText(choice.message().refusal()) ? choice.message().refusal() : "");// @formatter:onreturn buildGeneration(choice, metadata, request);}).toList();// Non function calling.RateLimit rateLimit = OpenAiResponseHeaderExtractor.extractAiResponseHeaders(completionEntity);// Current usageOpenAiApi.Usage usage = completionEntity.getBody().usage();Usage currentChatResponseUsage = usage != null ? OpenAiUsage.from(usage) : new EmptyUsage();Usage accumulatedUsage = UsageUtils.getCumulativeUsage(currentChatResponseUsage, previousChatResponse);ChatResponse chatResponse = new ChatResponse(generations,from(completionEntity.getBody(), rateLimit, accumulatedUsage));observationContext.setResponse(chatResponse);return chatResponse;});if (!isProxyToolCalls(prompt, this.defaultOptions)&& isToolCall(response, Set.of(OpenAiApi.ChatCompletionFinishReason.TOOL_CALLS.name(),OpenAiApi.ChatCompletionFinishReason.STOP.name()))) {var toolCallConversation = handleToolCalls(prompt, response);// Recursively call the call method with the tool call message// conversation that contains the call responses.return this.internalCall(new Prompt(toolCallConversation, prompt.getOptions()), response);}return response;}
我们来完善一下这块逻辑代码。
三,主要代码
首先我们需要建立拦截,去拦截用户信息,为了简便我就不进行加密token的处理了。有需要可以看我springboot下对这块的处理。
package org.example.springaidemo.filter;import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.example.springaidemo.context.UserContext;
import org.example.springaidemo.moudle.UserModel;
import org.example.springaidemo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;import java.io.IOException;@Component
public class UserAuthFilter implements Filter {@Autowiredprivate UserService userService;@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {HttpServletRequest httpRequest = (HttpServletRequest) request;HttpServletResponse httpResponse = (HttpServletResponse) response;try {// 获取tokenString token = httpRequest.getHeader("token");if (!StringUtils.hasText(token)) {httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);httpResponse.getWriter().write("Missing token");return;}// 获取用户信息UserModel user = userService.getUserByToken(token);if (user == null) {httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);httpResponse.getWriter().write("Invalid token");return;}// 设置用户上下文UserContext.setCurrentUser(user);// 继续处理请求chain.doFilter(request, response);} finally {// 清理用户上下文UserContext.clear();}}
}
这样我们可以从内存中快速提取用户信息。
核心业务逻辑
package org.example.springaidemo.impl;import lombok.extern.slf4j.Slf4j;
import org.example.springaidemo.config.AiMyFunction;
import org.example.springaidemo.config.knowledge.TextKnowledgeBase;
import org.example.springaidemo.context.UserContext;
import org.example.springaidemo.dao.mapper.Mapper1;
import org.example.springaidemo.moudle.UserModel;
import org.example.springaidemo.moudle.UserRestModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.concurrent.CompletableFuture;@Service
@Slf4j
public class SimpleControllerImpl {@Autowiredprivate AiMyFunction aiMyFunction;@Autowiredprivate TextKnowledgeBase textKnowledgeBase;@Autowiredprivate Mapper1 mapper1;public String chat(String message, String token) {// 如果是休假相关的请求,使用特殊处理if (message.contains("休假") || message.contains("请假")) {return handleRestRequest(message, token);}// 普通对话处理List<String> knowledgeResults = textKnowledgeBase.searchKnowledgeAll();StringBuilder promptBuilder = new StringBuilder();if (!knowledgeResults.isEmpty()) {promptBuilder.append("根据以下参考知识回答问题:\n\n");for (String knowledge : knowledgeResults) {promptBuilder.append("- ").append(knowledge).append("\n");}promptBuilder.append("\n问题是:").append(message);} else {promptBuilder.append(message);}return aiMyFunction.generateNormal(promptBuilder.toString(), token);}@Asyncpublic CompletableFuture<Void> processRestAsync(String userId, LocalDateTime startTime, LocalDateTime endTime, String restType, String status, String reason) {return CompletableFuture.runAsync(() -> {try {UserRestModel restModel = new UserRestModel();restModel.setUserid(userId);restModel.setStartTime(startTime);restModel.setEndTime(endTime);restModel.setRestType(restType);restModel.setStatus(status);if ("REJECTED".equals(status)) {restModel.setRejectReason(reason);}mapper1.addUserRest(restModel);log.info("Successfully processed rest request for user: {}", userId);} catch (Exception e) {log.error("Error processing rest request for user: {}", userId, e);}});}private String handleRestRequest(String message, String token) {UserModel user = UserContext.getCurrentUser();if (user == null) {return "未找到用户信息";}// 构建提示词,包含用户角色和规则信息StringBuilder promptBuilder = new StringBuilder();promptBuilder.append("当前用户角色:").append(user.getRoles()).append("\n");promptBuilder.append("请根据以下规则分析休假申请:\n");List<String> rules = textKnowledgeBase.searchKnowledgeAll();for (String rule : rules) {promptBuilder.append("- ").append(rule).append("\n");}promptBuilder.append("\n请分析以下休假申请,并从中提取开始时间、结束时间和休假类型:\n");promptBuilder.append(message).append("\n");promptBuilder.append("\n如果信息不完整或格式不正确,请直接回复提示用户正确的格式。");promptBuilder.append("\n如果信息完整,请按以下格式回复:");promptBuilder.append("\n批准:[分析理由]|[开始时间]|[结束时间]|[休假类型]");promptBuilder.append("\n或");promptBuilder.append("\n拒绝:[拒绝原因]|[开始时间]|[结束时间]|[休假类型]");// 调用AI处理休假请求String aiResponse = aiMyFunction.generateNormal(promptBuilder.toString(), token);log.info("AI Response for rest request: {}", aiResponse);// 解析AI响应并异步处理数据库操作if (aiResponse.startsWith("批准:")) {String[] parts = aiResponse.substring(3).split("\\|");if (parts.length != 4) {return "AI响应格式错误,请重试";}String reason = parts[0];LocalDateTime startTime = LocalDateTime.parse(parts[1].trim() + " 00:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));LocalDateTime endTime = LocalDateTime.parse(parts[2].trim() + " 23:59:59", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));String restType = parts[3].trim();processRestAsync(user.getUserid(), startTime, endTime, restType, "PENDING", null);return String.format("批准:%s\n请确认以下休假信息:\n开始时间:%s\n结束时间:%s\n休假类型:%s", reason, startTime.toLocalDate(), endTime.toLocalDate(), restType);} else if (aiResponse.startsWith("拒绝:")) {String[] parts = aiResponse.substring(3).split("\\|");if (parts.length != 4) {return "AI响应格式错误,请重试";}String reason = parts[0];LocalDateTime startTime = LocalDateTime.parse(parts[1].trim() + " 00:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));LocalDateTime endTime = LocalDateTime.parse(parts[2].trim() + " 23:59:59", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));String restType = parts[3].trim();processRestAsync(user.getUserid(), startTime, endTime, restType, "REJECTED", reason);return String.format("拒绝:%s", reason);}return aiResponse;}public Double priceAll(int count) {double price = 3.25;return price * count;}
}
- 这里首先从对话中catch到用户的请假需求。
- 由ai自动提取所需信息,结合我们外挂的知识库进行分析用户的请假需求是否合理。
- 在ai给出回答后,异步提取回答内容,写入我们业务数据库
注意异步任务的开启需要使用注解
@EnableAsync
你可以新建一个类
package org.example.springaidemo.config;import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;@Configuration
@EnableAsync
public class AsyncConfig {
}
或者直接加到启动类注解上
package org.example.springaidemo;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableAsync;@SpringBootApplication
@ComponentScan({"org.springframework.ai.chat", "org.example.springaidemo"})
@EnableAsync
public class SpringAiDemoApplication {public static void main(String[] args) {SpringApplication.run(SpringAiDemoApplication.class, args);}
}
其它边缘性的代码,就不截图了。相信能看到这块的都是老程序员,这点小case轻轻松松。
另外之前 我都是使用英特
现在使用的是
DeepSeek | 深度求索
DeepSeek
切换也很平滑。改几个配置项即可。
spring.application.name=springAiDemo
spring.ai.openai.api-key=密钥 //改一下密钥
spring.ai.openai.base-url=https://api.deepseek.com // 改一下urlspring.ai.openai.chat.options.model=deepseek-chat // 改一下使用模型
我们来看看测试如何
四,测试
开启对话
按ai给的提示再次对话
查看数据库写入情况
相关文章:
接上回--综合AIDemo测试
一,前言 上回外挂了知识库之后,我们需要使用知识库中的信息,让AI为我们实际处理业务上的需求。 这里我们让AI扮演公司的人事助手,帮我们处理员工请假的业务。 具体流程如下 感知用户需要请假提取用户请假信息获取用户数据库中…...
几何数据结构之四叉树与八叉树
几何数据结构之四叉树与八叉树 四叉树的定义四叉树深度的计算公式推导假设:计算过程:1. 划分空间:2. 节点容纳的最小距离:3. 解出深度:4. 考虑常数项: 总结: 八叉树 四叉树的定义 四叉树&#…...
postman请求参数化
postman界面介绍 一、使用环境变量(Environment Variables)进行参数化 1、在请求中使用环境变量 在请求的url、请求头(Headers)、请求体(Body)等部分都可以使用环境变量。 URL 部分示例 点击 Postman 界面右上角的 “眼睛” 图标(Environment Quick Look)打开环境管理…...
java实现word转html(支持docx及doc文件)
private final static String tempPath "C:\\Users\\xxx\\Desktop\\Word2Html\\src\\test\\";//图片及相关文件保存的路径public static void main(String argv[]) {try {JFileChooser fileChooser new JFileChooser();fileChooser.setDialogTitle("Select a …...
<电子幽灵>开发笔记:BAT基础笔记(一)
BAT脚本基础笔记(一) 介绍 费曼学习法最重要的部分,即把知识教给一个完全不懂的孩子——或者小白。 为了更好的自我学习,也为了让第一次接触某个知识范畴的同学快速入门,我会把我的学习笔记整理成电子幽灵系列。 提示:作为低代码…...
Leetcode::3427.变长子数组求和
给你一个长度为 n 的整数数组 nums 。对于 每个 下标 i(0 < i < n),定义对应的子数组 nums[start ... i](start max(0, i - nums[i]))。 返回为数组中每个下标定义的子数组中所有元素的总和。 子数组 是数组中…...
通过以太网加载linux内核、设备树、根文件系统方法(以stm32MP135为例)
0 硬件平台 正点原子stm32MP135开发板 1 通过以太网加载linux内核、设备树、根文件系统方法(以stm32MP135为例) 在产品正式发布前,为了调试方便,我们可以使用以太网加载linux内核、设备树、根文件系统以加快调试速度。本文以stm3…...
mac配置stable diffusion以及模型出图优化
1. 基础stable diffusion webui安装 使用的工程是stable-diffusion-webui,直接clone下来即可。 然后创建一个conda环境,python为3.9 激活conda环境后,执行./webui.sh即可。脚本会自动安装必要的包,然后启动网页。 默认有一个sd…...
LeetCode热题100(子串篇)
LeetCode热题100 说是子串,其实是子区间~ 560. 和为 K 的子数组 给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续非空序列。 思路 思路: 和为k的子数组,看到…...
从密码学原理与应用新方向到移动身份认证与实践
相关学习资料放下面啦! 记得关注❤️~后续分享更多资料 通过百度网盘分享的文件:从密码学原理与应... 链接https://pan.baidu.com/s/1mHpHkvPuf8DUwReQkoYQlw?pwdGza7 提取码:Gza7 复制这段内容打开「百度网盘APP 即可获取」 记…...
【Flink系列】9. Flink容错机制
9. 容错机制 在Flink中,有一套完整的容错机制来保证故障后的恢复,其中最重要的就是检查点。 9.1 检查点(Checkpoint) 9.1.1 检查点的保存 1)周期性的触发保存 “随时存档”确实恢复起来方便,可是需要我…...
【物联网】ARM核介绍
文章目录 一、芯片产业链1. CPU核(1)ARM(2)MIPS(3)PowerPc(4)Intel(5)RISC-V 2. SOC芯片(1)主流厂家(2)产品解决方案 3. 产品 二、ARM核发展1. 不同架构的特点分析(1)VFP(2)Jazelle(3)Thumb(4)TrustZone(5)SIMD(6)NEON 三、ARM核(ARMv7)工作模式1. 权限级别(privilege level)2.…...
spring的事物管理的认知
事物 它是一个原子操作要么全部不执行,要么全部执行成功,如果有一个失败也会撤销,它保证用户每一次的操作都是可靠的,即使时出现了错误也不至于破坏数据的完整性 它包含了四种特性: 原子性:保证事物要么…...
QT跨平台应用程序开发框架(3)—— 信号和槽
目录 一,基本概念 二,connect函数使用 2.1 connect 2.2 Qt内置信号和槽 2.3 一些细节 三,自定义信号和槽 3.1 自定义槽函数 3.2 自定义信号 3.3 带参数的信号槽 四,信号和槽的意义 五,信号和槽断开连接 六&…...
技术面试中的软素质技巧性答复集锦
1、请你自我介绍一下你自己? 回答提示:一般人回答这个问题过于平常,只说姓名、年龄、爱好、工作经验,这些在简历上都有。其实,企业最希望知道的是求职者能否胜任工作,包括:最强的技能、最深入研…...
JavaWeb项目——如何处理管理员登录和退出——笔记
一、知识点 1、WebServlet注解的使用 WebServlet注解是Servlet 3.0引入的一个特性,它允许开发者在Servlet类上使用注解来声明Servlet的一些属性,从而避免在web.xml文件中进行配置。这种方式简化了Servlet的配置过程,使得代码更加简洁&#…...
函数递归的介绍
1.递归的定义 在C语言中,递归就是函数自己调用自己 上面的代码就是 main 函数在函数主体内 自己调用自己 但是,上面的代码存在问题:main 函数反复地 自己调用自己 ,不受限制,停不下来。 最终形成死递归,…...
昇腾环境ppstreuct部署问题记录
测试代码 我是在华为昇腾910B3上测试的PPStructure。 import os import cv2 from PIL import Image #from paddleocr import PPStructure,draw_structure_result,save_structure_res from paddleocr_asyncio import PPStructuretable_engine PPStructure(show_logTrue, imag…...
《知识图谱:鸿蒙NEXT中人工智能的智慧基石》
在鸿蒙NEXT系统的人工智能应用中,知识图谱技术犹如一座智慧基石,为系统的智能化提供了强大的知识支撑,开启了更智能、更高效、更个性化的交互新时代。 提升语义理解能力 知识图谱以其结构化的知识表示方式,将各种实体和它们之间…...
Springboot项目Jackson支持多种接收多种时间格式
前言 在springboot项目中经常会使用Jackson框架,当前端给后端传输时间类型时,我们一般需要先配置好时间格式,否则后端无法接收。以下是一些配置方法 统一配置 spring:jackson:time-zone: GMT+8date-format: yyyy-MM-dd HH:mm:ss这种配置就是要求前端统一传输的格式是yyyy-…...
go语言zero框架通过chromedp实现网页在线截图的设计与功能实现
在 GoZero 框架中实现网页在线截图的功能,可以通过集成 chromedp 库来控制 Chrome 浏览器进行截图。chromedp 是一个基于 Chrome DevTools 协议的 Go 包,可以用来在 Go 程序中模拟浏览器操作,如页面截图、DOM 操作、表单提交等。 下面是一个…...
基于深度学习的视觉检测小项目(十四) 用SQLite数据库进行用户管理
在开始做用户管理之前,先要了解一下SQLite数据库的基础知识:https://blog.csdn.net/xulibo5828/category_12785993.html?fromshareblogcolumn&sharetypeblogcolumn&sharerId12785993&sharereferPC&sharesourcexulibo5828&sharefrom…...
【2024年华为OD机试】 (B卷,100分)- 敏感字段加密(Java JS PythonC/C++)
一、问题描述 题目描述 给定一个由多个命令字组成的命令字符串: 字符串长度小于等于 127 字节,只包含大小写字母、数字、下划线和偶数个双引号;命令字之间以一个或多个下划线 _ 进行分割;可以通过两个双引号 "" 来标识包含下划线 _ 的命令字或空命令字(仅包含…...
图像去雾数据集的下载和预处理操作
前言 目前,因为要做对比实验,收集了一下去雾数据集,并且建立了一个数据集的预处理工程。 这是以前我写的一个小仓库,我决定还是把它用起来,下面将展示下载的路径和数据处理的方法。 下面的代码均可以在此找到。Auo…...
Vue3数据响应式原理
什么是数据响应式 当数据变化时,引用数据的函数(副作用函数)自动重新执行。 即数据触发了函数的响应,如:视图渲染中使用了某数据,数据改变后,视图跟着自动更新。 触发者:数据 响应者…...
5.最长回文子串--力扣
给你一个字符串 s,找到 s 中最长的 回文子串。 示例 1: 输入:s “babad” 输出:“bab” 解释:“aba” 同样是符合题意的答案。 示例 2: 输入:s “cbbd” 输出:“bb” 原题如上&…...
ChatGPT大模型极简应用开发-CH1-初识 GPT-4 和 ChatGPT
文章目录 1.1 LLM 概述1.1.1 语言模型和NLP基础1.1.2 Transformer及在LLM中的作用1.1.3 解密 GPT 模型的标记化和预测步骤 1.2 GPT 模型简史:从 GPT-1 到 GPT-41.2.1 GPT11.2.2 GPT21.2.3 GPT-31.2.4 从 GPT-3 到 InstructGPT1.2.5 GPT-3.5、Codex 和 ChatGPT1.2.6 …...
python学opencv|读取图像(三十九 )阈值处理Otsu方法
【1】引言 前序学习了5种阈值处理方法,包括(反)阈值处理、(反)零值处理和截断处理,还学习了一种自适应处理方法,相关文章链接为: python学opencv|读取图像(三十三)阈值处理-灰度图像-CSDN博客 python学o…...
统信V20 1070e X86系统编译安装mysql-5.7.44版本以及主从构建
设备信息 操作系统版本架构CPU内存备注统信UOS V20 1070eX864C8G此配置仅做编译安装验证,持续运行或数据量增长大请自行评估资源配置。统信UOS V20 1070eX864C8G 资源包 该包包含mysql-5.7.44源码包、boost资源包、统信编译mysql-5.7.44安装包 通过网盘分享的文件…...
麒麟LINUX V10SP3 2401安装ORACLE 12.2.1 runInstaller直接报UNZIP格式不对
好久没有安装ORACLE了,一般都是RHEL上安装得比较多,这不,现在大家都是选择国产操作系统来安装数据库了,以前在龙蜥,欧拉,麒麟上也安装过,都没有问题,想来在麒麟LINUX v10sp3 2401上面…...
10 为什么系统需要引入分布式、微服务架构
java技术的发展 在java开始流行起来之后,主要服务于企业家应用,例如ERP,CRM等等,这些项目是为企业内部员工使用,我们的思维是怎么用设计模式,如何封装代码。让开发人员关注到业务上去,系统也就那么几十几百…...
【Web】2025西湖论剑·中国杭州网络安全安全技能大赛题解(全)
目录 Rank-l Rank-U sqli or not Rank-l username存在报错回显,发现可以打SSTI 本地起一个服务,折半查找fuzz黑名单,不断扔给fenjing去迭代改payload from flask import Flask, request, render_template_stringapp Flask(__name__)app…...
openharmony应用开发快速入门
开发准备 本文档适用于OpenHarmony应用开发的初学者。通过构建一个简单的具有页面跳转/返回功能的应用(如下图所示),快速了解工程目录的主要文件,熟悉OpenHarmony应用开发流程。 在开始之前,您需要了解有关OpenHarmon…...
解决npm install安装出现packages are looking for funding run `npm fund` for details问题
当我们运行npm install时,可能会收到类似以下的提示信息:“x packages are looking for funding.” 这并不是错误提示,也不会影响项目的正常运行。其实实在提醒有一些软件包正在寻求资金支持。 根据提示输入npm fund可以查看详细的信息&#…...
python助力WRF自动化运行
对大部分人而言,特别是新用户,WRF模式的安装繁琐且不必要,可以作为后续进阶掌握的技能,本学习跳过繁琐的安装步骤,直接聚焦模式的运行部分,通过短平快的教学,快速掌握模式运行。进一步将python语…...
Go-知识 版本演进
Go-知识 版本演进 Go release notesr56(2011/03/16)r57(2011/05/03)Gofix 工具语言包工具小修订 r58(2011/06/29)语言包工具小修订 r59(2011/08/01)语言包工具 r60(2011/09/07)语言包工具 [go1 2012-03-28](https://golang.google.cn/doc/devel/release#go1)[go1.1 2013-05-13]…...
企业级NoSQL数据库Redis
1.浏览器缓存过期机制 1.1 最后修改时间 last-modified 浏览器缓存机制是优化网页加载速度和减少服务器负载的重要手段。以下是关于浏览器缓存过期机制、Last-Modified 和 ETag 的详细讲解: 一、Last-Modified 头部 定义:Last-Modified 表示服务器上资源…...
Android渲染Latex公式的开源框架比较
对比主流框架,介绍如下几款 1、AndroidMath 官网:https://github.com/gregcockroft/AndroidMath/tree/master 基于android原生view方式渲染 优点:速度快,开源协议 MIT license 缺点:不支持文字公式混合渲染 2、Ma…...
ARM学习(42)CortexM3/M4 MPU配置
笔者之前学习过CortexR5的MPU配置,现在学习一下CortexM3/M4 MPU配置 1、背景介绍 笔者在工作中遇到NXP MPU在访问异常地址时,就会出现总线挂死,所以需要MPU抓住异常,就需要配置MPU。具体背景情况可以参考ARM学习(41)NXP MCU总线挂死,CPU could not be halted以及无法连…...
Sam Altman亲自确认:o3-mini即将上线!GPT和o系列模型合并!
大家好,我是木易,一个持续关注AI领域的互联网技术产品经理,国内Top2本科,美国Top10 CS研究生,MBA。我坚信AI是普通人变强的“外挂”,专注于分享AI全维度知识,包括但不限于AI科普,AI工…...
数据结构-队列
目录 前言一、队列及其抽象数据类型1.1 队列的基本概念1.2 队列的抽象数据类型 二、队列的实现2.1 顺序表示2.1.1 结构定义2.1.2 基本操作的实现 2.2 链式表示2.2.1 结构定义2.2.2 基本操作的实现 总结 前言 本篇文章介绍队列的基础知识,包括队列的抽象数据类型以及…...
Go Map 源码分析(一)
Go语言中的map是通过哈希表实现的,其底层结构和实现机制如下: 一、hash 结构 hmap结构体:是map的头部结构,主要字段及含义如下: count:表示当前哈希表中的元素数量,与len()函数相对应。flags…...
天机学堂5-XxlJobRedis
文章目录 梳理前面的实现:Feign点赞改进 day07-积分系统bitmap相关命令签到增加签到记录计算本月已连续签到的天数查询签到记录 积分表设计签到-->发送RabbitMQ消息,保存积分对应的消费者:**消费消息 用于保存积分**增加积分查询个人今日积…...
SpringBoot整合junit
SpringBoot 整合 junit 特别简单,分为以下三步完成: 1在测试类上添加 SpringBootTest 注解2使用 Autowired 注入要测试的资源3定义测试方法进行测试 1.实验准备: 创建一个名为 springboot_junit_test 的 SpringBoot 工程,工程目录结构如下…...
Jenkins-pipeline Jenkinsfile说明
一. 简介: Jenkinsfile 是一个文本文件,通常保存在项目的源代码仓库中,用于定义 Jenkins Pipeline 的行为。使用 Jenkinsfile 可以使 CI/CD 流程版本化,并且易于共享和审核。 二. 关于jenkinsfile: jenkins的pipeline…...
SpringMVC 实战指南:打造高效 Web 应用的秘籍
第一章:三层架构和MVC 三层架构: 开发服务器端,一般基于两种形式,一种 C/S 架构程序,一种 B/S 架构程序使用 Java 语言基本上都是开发 B/S 架构的程序,B/S 架构又分成了三层架构三层架构: 表现…...
结合帧级边界检测和深度伪造检测,定位部分伪造音频攻击中的篡改区域
Integrating frame-level boundary detection and deepfake detection for locating manipulated regions in partially spoofed audio forgery 摘要: 部分伪造音频是一种深度伪造的变体,它通过引入伪造或外部来源的善意音频片段来操纵音频语句…...
人工智能之深度学习_[2]-PyTorch入门
文章目录 PyTorch1.PyTorch简介1.1 什么是PyTorch1.2 PyTorch特点1.3 PyTorch发展历史 2 张量创建2.1 什么是张量2.2 基本创建方式2.3 线性和随机张量2.4 0、1、指定值张量2.5 指定元素类型张量 3 张量类型转换3.1 张量转换为NumPy数组3.2 NumPy数组转换为张量3.3 提取标量张量…...
vue2与vue3的区别
目录 1. 性能 2. 组合式 API 3. 生命周期钩子 4. 片段(Fragments) 5. 递归组件 6. 自定义渲染器 7. 全局 API 8. 组件内部的 this 9. 模板语法 10. 兼容性 总结 Vue 2 和 Vue 3 是 Vue.js 框架的两个主要版本,它们在多个方面有所不…...
八股学习 Mysql
八股学习 Mysql 常见面试问题优化其他 定位慢查询方案一:开源工具方案二:MySQL自带慢日志 SQL执行计划示例场景名词解释 索引概念底层数据结构聚簇索引、二级索引(非聚簇索引)覆盖索引覆盖索引应用场景创建原则索引失效 SQL优化表…...