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

Spring AI 快速入门教程:基于VUE3与Spring AI技术实现的“流式聊天““打字机效果“功能

目录前言一、Spring AI 核心认知1.1 技术定位与核心价值1.2 版本支持与生态兼容性1.3 与其他 AI 集成框架对比二、效果展示三、快速入门3.1 环境准备JDK 配置AI 服务密钥准备3.2 后端项目创建主要技术栈pom.xml 配置application.yml 配置Java 主要代码类3.3 常见问题排查依赖下载失败3.4 前端项目创建3.4.1 创建空项目3.4.2 进入项目3.4.3 依次下载依赖package.json 配置vite.config.js 配置main.jsApp.vue四、课后作业4.1 基础认知题4.2 环境准备题4.3 配置文件题4.4 代码实操题4.5 问题排查题五、总结前言在AI技术快速发展的浪潮中Java生态系统迫切需要一套简洁高效的AI集成解决方案。Spring AI应运而生不仅完美填补了这一技术空白更凭借与Spring生态系统的深度整合让开发者无需切换技术栈就能轻松构建企业级AI应用。一、Spring AI 核心认知1.1 技术定位与核心价值Spring AI 并非 AI 模型本身而是 “Spring 生态与 AI 模型的中间件”核心价值体现在三方面解耦模型依赖屏蔽不同 AI 服务OpenAI/Anthropic/ 本地模型的底层差异提供统一 API降低开发门槛复用 Spring 注解驱动、自动配置、依赖注入等特性无需从零学习 AI 模型调用企业级适配支持权限控制、可观测性、分布式部署满足生产环境要求1.2 版本支持与生态兼容性1.3 与其他 AI 集成框架对比二、效果展示三、快速入门3.1 环境准备JDK 配置下载 JDK 17选择 Oracle JDK 17 或 OpenJDK 17版本验证执行java -version命令确认输出包含 17.0.x 版本号环境变量设置配置JAVA_HOME变量指向 JDK 安装目录AI 服务密钥准备deepseek 密钥登录 deepseek 平台→ 进入个人中心 → API Keys→ 创建新密钥通义千问密钥登录通义千问平台→ 进入个人中心 → 密钥管理→ 创建 API 密钥本地模型无需密钥→ 需提前下载模型文件如通过 Ollama 部署 LLaMA 33.2 后端项目创建主要技术栈springboot 3.5.8 jdk17 spring-ai 1.1.0 redis 6.0pom.xml 配置?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd modelVersion4.0.0/modelVersion parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version3.5.8/version relativePath/ /parent groupIdcom.thoms/groupId artifactIdspring-ai/artifactId version0.0.1-SNAPSHOT/version properties java.version17/java.version spring-ai.version1.1.0/spring-ai.version /properties dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-security/artifactId /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency !-- Actuator for monitoring -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-actuator/artifactId /dependency !-- Micrometer for metrics -- dependency groupIdio.micrometer/groupId artifactIdmicrometer-core/artifactId /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-redis-store/artifactId /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-advisors-vector-store/artifactId /dependency !-- Redis Dependencies -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-redis/artifactId /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-model-openai/artifactId /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-vector-store-weaviate/artifactId /dependency dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-test/artifactId scopetest/scope /dependency /dependencies dependencyManagement dependencies dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-bom/artifactId version${spring-ai.version}/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement build plugins plugin groupIdorg.springframework.boot/groupId artifactIdspring-boot-maven-plugin/artifactId /plugin /plugins /build /projectapplication.yml 配置spring: application: name: spring-ai ###### Deepseek 配置 ####### ai: openai: api-key: sk-**************6cce8218b # 配置自己的key base-url: https://api.deepseek.com # 通义千问则配置 https://dashscope.aliyuncs.com/compatible-mode chat: options: model: deepseek-chat # 通义千问则配置 qwen-plus temperature: 1.3 max-tokens: 4096 ######## weaviate 向量数据库配置 ##### vectorstore: weaviate: scheme: http host: localhost:8080 #### 本地 Ollama 模型配置 #### # ollama: # base-url: http://localhost:11434 # chat: # model: llama3 # temperature: 0.6 #### Redis 配置 #### data: redis: # Redis服务器地址 host: 127.0.0.1 # Redis服务器端口 port: 6379 # Redis数据库索引默认为0 database: 0 # Redis服务器连接密码默认为空 password: 123456 # 连接超时时间 timeout: 10s lettuce: pool: # 连接池最大连接数 max-active: 20 # 连接池最大阻塞等待时间使用负值表示没有限制 max-wait: -1ms # 连接池最大空闲连接 max-idle: 10 # 连接池最小空闲连接 min-idle: 2 server: port: 9999Java 主要代码类ChatEntity.javaimport java.io.Serializable; /** * author Thomas * version v1.0 * createDate 2026/3/2 6:28 PM */ Data public class ChatEntity implements Serializable { /** * 用户ID-前端生成UUID */ private String userId; /** * 查询内容-前端传过来 */ private String prompt; }AiConfig.javaimport org.springframework.ai.chat.client.ChatClient; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; Configuration public class AiConfig { Bean public ChatClient chatClient(ChatClient.Builder builder) { return builder.build(); } }SSEMsgType.java/** * SSE消息类型枚举 */ public enum SSEMsgType { MESSAGE(message, 单次发送的普通信息), ADD(add, 消息追加适用于流式stream推送), FINISH(finish, 消息发送完成), CUSTOM_EVENT(custom_event, 自定义消息类型), DONE(done, 消息发送完成); public final String type; public final String value; SSEMsgType(String type, String value) { this.type type; this.value value; } }SSEServer.javapackage com.thomas.springai.sse; import lombok.extern.slf4j.Slf4j; import org.springframework.util.CollectionUtils; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; import java.io.IOException; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Consumer; /** * 构造 SSE 服务 * author thomas * createDate 2026.3.3 */ Slf4j public class SSEServer { /** * 存放所有用户的SseEmitter连接 */ private static final MapString, SseEmitter sseClients new ConcurrentHashMap(); /** * 根据用户ID建立连接 * param userId 用户ID * return SseEmitter */ public static SseEmitter connect(String userId) { // 设置超时时间为0即不超时 SseEmitter sseEmitter new SseEmitter(0L); // 注册回调函数 sseEmitter.onTimeout(timeoutCallback(userId)); sseEmitter.onCompletion(completionCallback(userId)); sseEmitter.onError(errorCallback(userId)); sseClients.put(userId, sseEmitter); log.info(SSE connect, userId: {}, userId); return sseEmitter; } /** * 发送消息到指定用户 * param userId 用户ID * param message 消息 * param msgType SSEMsgType */ public static void sendMsg(String userId, String message, SSEMsgType msgType) { if (CollectionUtils.isEmpty(sseClients)) return; if (sseClients.containsKey(userId)) { SseEmitter sseEmitter sseClients.get(userId); sendEmitterMessage(sseEmitter, userId, message, msgType); } } /** * 发送消息到所有用户 * param message 消息 */ public static void sendMsgToAllUsers(String message) { if (CollectionUtils.isEmpty(sseClients)) return; sseClients.forEach((userId, sseEmitter) - { sendEmitterMessage(sseEmitter, userId, message, SSEMsgType.MESSAGE); }); } /** * 前端监听消息方法 * param sseEmitter SseEmitter * param userId 用户ID * param message 消息 * param msgType SSEMsgType */ private static void sendEmitterMessage(SseEmitter sseEmitter, String userId, String message, SSEMsgType msgType) { // 指定事件名称前端根据这个名称监听 SseEmitter.SseEventBuilder msgEvent SseEmitter.event() .id(userId) .data(message) .name(msgType.type); try { sseEmitter.send(msgEvent); } catch (IOException e) { log.error(SSE send message error, userId: {}, error: {}, userId, e.getMessage()); // 发送异常时移除该连接 close(userId); } } /** * 关闭连接 * param userId 用户ID */ public static void close(String userId) { SseEmitter emitter sseClients.get(userId); if (emitter ! null) { emitter.complete(); sseClients.remove(userId); } } /** * 回调函数实现 * param userId 用户ID * return Runnable */ private static Runnable timeoutCallback(String userId) { return () - { log.warn(SSE timeout, userId: {}, userId); sseClients.remove(userId); }; } private static Runnable completionCallback(String userId) { return () - { log.info(SSE completion, userId: {}, userId); sseClients.remove(userId); }; } private static ConsumerThrowable errorCallback(String userId) { return throwable - { log.error(SSE error, userId: {}, error: {}, userId, throwable.getMessage()); sseClients.remove(userId); }; } }SSEController.javaimport org.springframework.http.MediaType; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; /** * 前端需要连接SSE服务器 * author thomas * createDate 2026.3.3 */ RestController RequestMapping(/sse) public class SSEController { GetMapping(path /connect, produces {MediaType.TEXT_EVENT_STREAM_VALUE}) public SseEmitter connect(RequestParam String userId) { return SSEServer.connect(userId); } }ChatService.java/** * 聊天服务 * author thomas * createDate 2026.3.3 */ public interface ChatService { void doChat(ChatEntity chatEntity); }ChatServiceImpl.javaimport lombok.extern.slf4j.Slf4j; import org.springframework.ai.chat.client.ChatClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import reactor.core.publisher.Flux; /** * 聊天服务实现类 * author thomas * createDate 2026.3.3 */ Service Slf4j public class ChatServiceImpl implements ChatService { private final ChatClient chatClient; Autowired public ChatServiceImpl(ChatClient chatClient) { this.chatClient chatClient; } Override public void doChat(ChatEntity chatEntity) { String userId chatEntity.getUserId(); String prompt chatEntity.getPrompt(); // 获取 ChatClient 的流式响应 FluxString stringFlux chatClient.prompt(prompt).stream().content(); // 订阅流并实时推送 stringFlux.doOnError(throwable - { log.error(AI Stream error: throwable.getMessage()); SSEServer.sendMsg(userId, AI service error, SSEMsgType.FINISH); SSEServer.close(userId); }).subscribe( content - SSEServer.sendMsg(userId, content, SSEMsgType.ADD), error - log.error(Error processing stream: error.getMessage()), () - { SSEServer.sendMsg(userId, done, SSEMsgType.FINISH); SSEServer.close(userId); } ); } }SSEChatController.javapackage com.thomas.springai.sse; import jakarta.annotation.Resource; import org.springframework.ai.chat.client.ChatClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * 聊天控制器 * author thomas * createDate 2026.3.3 */ RestController RequestMapping(/ai) public class SSEChatController { private final ChatClient chatClient; Autowired public SSEChatController(ChatClient chatClient) { this.chatClient chatClient; } Resource private ChatService chatService; /** * 流式响应接口 * MediaType.TEXT_EVENT_STREAM 用于 SSEServer-Sent Events * produces MediaType.TEXT_EVENT_STREAM_VALUE */ PostMapping(value /stream) public void streamChat(RequestBody ChatEntity chatEntity) { chatService.doChat(chatEntity); } }以上代码复制到自己项目中即可运行3.3 常见问题排查依赖下载失败问题现象Maven/Gradle 无法拉取 Spring AI 快照版本依赖解决方案检查仓库配置是否包含 Spring 快照仓库排除镜像对快照仓库的拦截修改 settings.xml)mirroridaliyunmaven/idname阿里云中央仓库/nameurlhttps://maven.aliyun.com/repository/public/urlmirrorOf*,!spring-snapshots,!central-portal-snapshots/mirrorOf/mirror3.清理本地仓库缓存Mavenmvn clean install -UGradlegradle clean build --refresh-dependencies3.4 前端项目创建3.4.1 创建空项目npm create vue3.2根据提示创建项目名称为 spring-ai-vue 的项目建议创建空项目3.4.2 进入项目cd spring-ai-vue3.4.3 依次下载依赖npm installnpm install element-plusnpm install vue3-markdown-itpackage.json 配置{ name: spring-ai-vue, version: 0.0.0, private: true, scripts: { dev: vite, build: vite build, preview: vite preview }, dependencies: { microsoft/fetch-event-source: ^2.0.1, element-plus: ^2.13.3, vue: ^3.2.45, vue-router: ^4.1.6, vue3-markdown-it: ^1.0.10 }, devDependencies: { vitejs/plugin-vue: ^3.2.0, vite: ^3.2.4 } }vite.config.js 配置import { fileURLToPath, URL } from node:url import { defineConfig } from vite import vue from vitejs/plugin-vue // https://vitejs.dev/config/ export default defineConfig({ plugins: [vue()], resolve: { alias: { : fileURLToPath(new URL(./src, import.meta.url)) } }, server: { port: 5151, open: true, // 项目运行时打开外置浏览器 cors: true, // 允许跨域 fs: { strict: true }, // 代理后端接口 proxy: { /ai/: { target: http://localhost:9999, changeOrigin: true }, /sse/: { target: http://localhost:9999, changeOrigin: true } } } })main.jsimport { createApp } from vue import ElementPlus from element-plus import element-plus/dist/index.css import App from ./App.vue // import router from ./router import ./assets/main.css const app createApp(App) // app.use(router) app.use(ElementPlus) app.mount(#app)App.vuetemplate div classai-chat-container div classchat-display refchatDisplay div v-ifanswerText classmarkdown-body MarkdownIt :sourceanswerText/ /div div v-ifisStreaming classstreaming-indicator el-icon :size16 classis-loadingLoading //el-icon span stylemargin-left: 8px;AI 正在思考.../span /div /div div classinput-area el-input v-modelform.prompt typetextarea :rows2 placeholder请输入您的问题... keyup.enterhandleSubmit / /div div classaction-bar el-button typeprimary clickhandleSubmit :loadingisStreaming :disabled!form.prompt.trim() 问AI /el-button el-button v-ifisStreaming clickstopGenerate 停止生成 /el-button el-button clickclearHistory 清空 /el-button /div /div /template script setup import { ref, reactive, onUnmounted, nextTick } from vue; import MarkdownIt from vue3-markdown-it; import element-plus/dist/index.css; import { ElMessage } from element-plus; import { Loading } from element-plus/icons-vue; // 响应式数据 const uuid crypto.randomUUID(); const answerText ref(); const isStreaming ref(false); const chatDisplay ref(null); const form reactive({ prompt: , userId: uuid }); const url /sse/connect?userId uuid; // 建立SSE连接 function connectSSE() { const eventSource new EventSource(url); // 监听add事件接收流式内容 eventSource.addEventListener(add, (event) { let result event.data; if (result result.toLowerCase() ! null) { // 收到文本片段过滤特殊字符并实时追加 result result.replace(/^|$/g, ); result result.replace(data:, ); result result.replace(data:, ); result result.replace(###, ); result result.replace(/\n/g, ); answerText.value result; // 自动滚动到底部 scrollToBottom(); } }); // 监听finish事件 eventSource.addEventListener(finish, (event) { // 收到结束信号 console.log(流式响应结束); isStreaming.value false; // 保存对话历史 saveConversation(); }); eventSource.onerror (error) { isStreaming.value false; //ElMessage.error(请求发生错误 JSON.stringify(error)); }; } // 提交问题 const handleSubmit async () { if (!form.prompt.trim()) { ElMessage.warning(请输入问题内容); return; } if (isStreaming.value) { ElMessage.info(正在生成中请稍候...); return; } // 清空上一次的回答 answerText.value ; isStreaming.value true; // 建立SSE连接 connectSSE(); // 发送HTTP请求触发AI聊天 try { await fetch(/ai/stream, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify(form) }); } catch (error) { isStreaming.value false; console.error(对话请求失败:, err); } }; // 停止生成 const stopGenerate () { sseClient.abort(); isStreaming.value false; ElMessage.info(已停止生成); }; // 清空对话 const clearHistory () { answerText.value ; form.prompt ; }; // 保存对话记录 const saveConversation async () { // 调用后端接口保存对话历史 console.log(对话已保存); }; // 自动滚动到底部 const scrollToBottom () { nextTick(() { if (chatDisplay.value) { chatDisplay.value.scrollTop chatDisplay.value.scrollHeight; } }); }; // 组件卸载时中断连接 onUnmounted(() { if (isStreaming.value) { sseClient.abort(); } }); /script style scoped .ai-chat-container { padding: 20px; width: 800px; text-align: center; border-radius: 1.3125rem; position: fixed; top: 10px; left: 28%; } .chat-display { min-height: 60px; /* max-height: 500px; */ overflow-y: auto; border: 1px solid #f9f9f9; border-radius: 8px; padding: 20px; margin-bottom: 20px; background-color: #f9f9f9; } .markdown-body { text-align: left; line-height: 1.6; } .streaming-indicator { display: flex; align-items: center; color: #909399; margin-top: 16px; font-size: 14px; } .input-area { margin-top: 20px; width: 47.5rem; background-color: #f3f3f3; } .el-textarea { border-radius: 5px; background-color: #f3f3f3; } .action-bar { display: flex; justify-content: flex-end; margin-top: 16px; gap: 12px; } /style四、课后作业说明本作业题围绕Spring AI 快速入门项目展开覆盖核心认知、环境准备、配置文件、代码实现及常见问题排查旨在巩固项目相关知识点贴合实操场景。4.1 基础认知题请简述Spring AI 的技术定位明确其核心价值至少回答2点并说明它与AI模型本身的区别。参考答案1. 技术定位Spring AI 并非AI模型本身而是“Spring生态与AI模型的中间件”。2. 核心价值① 填补Java生态AI集成解决方案的空白② 与Spring生态深度整合让开发者无需切换技术栈即可构建企业级AI应用。3. 与AI模型的区别Spring AI 不提供AI模型能力仅负责衔接Spring生态与各类AI模型如Deepseek、通义千问、LLaMA 3简化AI模型的集成与调用流程。4.2 环境准备题结合项目文档完成以下2个问题本项目要求的JDK版本是什么如何验证自己的JDK版本是否符合要求若使用通义千问AI服务需如何获取API密钥并写出通义千问在application.yml中对应的base-url和model配置值。参考答案1. JDK版本要求JDK 17Oracle JDK 17或OpenJDK 17验证方法执行java -version命令确认输出包含17.0.x版本号。2. 密钥获取登录通义千问平台→进入个人中心→密钥管理→创建API密钥配置值base-url为https://dashscope.aliyuncs.com/compatible-modemodel为qwen-plus。4.3 配置文件题观察项目中pom.xml和application.yml配置回答以下问题pom.xml中引入的Spring AI 版本号是多少核心的Spring AI 依赖有哪些至少写出2个application.yml中配置的Redis服务器地址、端口和密码分别是什么后端项目的端口号是多少参考答案1. Spring AI版本号1.1.0核心依赖spring-ai-redis-store、spring-ai-starter-model-openai或spring-ai-advisors-vector-store、spring-ai-starter-vector-store-weaviate任选2个即可。2. Redis配置地址127.0.0.1端口6379密码123456后端项目端口号9999。4.4 代码实操题根据项目中提供的代码完成以下操作写出ChatEntity类的核心属性含属性说明并说明该类的作用。简述SSEServer类中connect方法的作用以及该方法中设置SseEmitter超时时间为0的含义。ChatServiceImpl类中doChat方法的核心逻辑是什么流式响应是如何通过SSE推送到前端的参考答案1. 核心属性① userId用户ID前端生成的UUID② prompt查询内容前端传入作用封装前端传入的聊天请求数据作为前后端及后端服务间的数据传输载体。2. connect方法作用根据用户ID建立SSE连接注册超时、完成、异常回调函数并将连接存入集合管理超时时间为0的含义SSE连接不超时持续保持连接状态用于接收流式响应。3. 核心逻辑获取前端传入的用户ID和查询内容通过ChatClient获取AI模型的流式响应推送方式订阅流式响应每收到一段内容通过SSEServer的sendMsg方法以SSEMsgType.ADD类型推送到对应用户响应结束后发送FINISH类型消息并关闭连接。4.5 问题排查题项目开发过程中若出现Maven依赖下载失败的问题请结合文档说明至少2种排查和解决方法。参考答案方法1检查仓库配置是否包含Spring快照仓库排除镜像对快照仓库的拦截修改Maven的settings.xml文件方法2清理本地仓库缓存Maven项目执行mvn clean install -U命令Gradle项目执行gradle clean build --refresh-dependencies命令。五、总结本项目围绕Spring AI 快速入门展开核心是帮助AI开发小白快速掌握Spring AI的集成与应用。项目清晰梳理了Spring AI的技术定位与核心价值完成了从环境准备到前后端开发的全流程实操涵盖JDK配置、AI服务密钥获取、Maven与YML配置以及后端SSE流式通信、前端交互的完整实现。通过作业题可巩固核心知识点重点掌握Spring AI依赖配置、SSE服务搭建、前后端数据交互及常见问题排查。项目兼顾理论与实操适配新手学习节奏同时提供了Redis等数据存储方案为后续企业级AI应用开发奠定了坚实基础助力开发者无需切换技术栈即可快速构建AI相关项目。 感谢您耐心阅读到这里 技术成长没有捷径但每一次的阅读、思考和实践都在默默缩短您与成功的距离。 如果本文对您有所启发欢迎点赞、收藏、分享给更多需要的伙伴️ 期待在评论区看到您的想法、疑问或建议我会认真回复让我们共同探讨、一起进步 关注我持续获取更多干货内容 我们下篇文章见

相关文章:

Spring AI 快速入门教程:基于VUE3与Spring AI技术实现的“流式聊天““打字机效果“功能

目录 前言 一、Spring AI 核心认知 1.1 技术定位与核心价值 1.2 版本支持与生态兼容性 1.3 与其他 AI 集成框架对比 二、效果展示 三、快速入门 3.1 环境准备 JDK 配置 AI 服务密钥准备 3.2 后端项目创建 主要技术栈 pom.xml 配置 application.yml 配置 Java 主…...

2025零碳园区建设方案【附全文阅读】

2025零碳园区建设方案聚焦能源转型、产业优化、技术创新,通过政策支持、试点示范、多元融资推进,需因地制宜制定具体方案[17]。 关联阅读索引: 收藏不迷路——零碳智慧园区数字化学习索引【持续更新】-CSDN博客https://blog.csdn.net/cdfunlove/article/details/159959732?…...

# 低代码开发新范式:用 Python 快速构建可视化数据报表系统在现代软件工程中,**低代码开发**正从边缘走向主流。它不仅显著

低代码开发新范式:用 Python 快速构建可视化数据报表系统 在现代软件工程中,低代码开发正从边缘走向主流。它不仅显著缩短了开发周期,还降低了非专业开发者的技术门槛。本文将围绕 Python Streamlit Pandas 的组合,演示如何快速…...

数据库的undo和redo日志

本文介绍undo和redo日志的一般概念,不涉及具体某个数据库的实现细节,参考资料来自《数据库系统实现》的第六章《系统故障对策》。一个假设和四个操作原语一个假设假设数据库由元素组成。为了简化讨论,这里假设元素是磁盘块,并且元…...

杰理之BLE名字修改【篇】

搜索程序上 HCI_EIR_DATATYPE_COMPLETE_LOCAL_NAME字样,找到数据部分的传参就是实际的蓝牙名。...

AI快速生成可编辑的流程图的方法

AI快速生成可编辑的流程图的方法 方法1:使用deepseek直接生成drawio流程图 生成后下载,使用drawio(访问地址:https://app.diagrams.net/) 打开 在drawio对流程图进行修改和美化。 方法2:使用deepseek生成…...

【iOS设备激活锁突破与合规应用指南:从技术原理到教育医疗场景落地】

【iOS设备激活锁突破与合规应用指南:从技术原理到教育医疗场景落地】 【免费下载链接】applera1n icloud bypass for ios 15-16 项目地址: https://gitcode.com/gh_mirrors/ap/applera1n 【问题象限:激活锁困局与合法需求】 核心概念&#xff1a…...

d2s-editor:暗黑破坏神2存档高效编辑工具全攻略

d2s-editor:暗黑破坏神2存档高效编辑工具全攻略 【免费下载链接】d2s-editor 项目地址: https://gitcode.com/gh_mirrors/d2/d2s-editor 在《暗黑破坏神2》的冒险旅程中,你是否曾因错误的属性分配而懊悔不已?是否希望拥有更强大的装备…...

基于图像识别的鸣潮自动化框架深度解析与架构设计

基于图像识别的鸣潮自动化框架深度解析与架构设计 【免费下载链接】ok-wuthering-waves 鸣潮 后台自动战斗 自动刷声骸 一键日常 Automation for Wuthering Waves 项目地址: https://gitcode.com/GitHub_Trending/ok/ok-wuthering-waves ok-ww是一个基于图像识别技术构建…...

MySQL8.0大小写敏感坑爹实录:lower_case_table_names从报错到解决的完整过程

MySQL 8.0大小写敏感参数避坑指南:从报错到根治的深度实践 最近在迁移开发环境到Docker时,遇到了一个令人头疼的问题——MySQL 8.0服务无法启动,报错提示Different lower_case_table_names settings for server (2) and data dictionary (0)。…...

iOS 15-16 iCloud激活锁绕过终极指南:applera1n工具深度解析与实战

iOS 15-16 iCloud激活锁绕过终极指南:applera1n工具深度解析与实战 【免费下载链接】applera1n icloud bypass for ios 15-16 项目地址: https://gitcode.com/gh_mirrors/ap/applera1n 你是否面临二手iPhone无法激活的困境?或者忘记了Apple ID密码…...

【VirtualBox】Vbox 7.2.6 不让安装在其他盘?这篇保姆级权限修复指南让你 D 盘起飞

在编程的艺术世界里,代码和灵感需要寻找到最佳的交融点,才能打造出令人为之惊叹的作品。 而在这座秋知叶i博客的殿堂里,我们将共同追寻这种完美结合,为未来的世界留下属于我们的独特印记。 【VirtualBox】Vbox 7.2.6 不让安装在其他盘?这篇保姆级权限修复指南让你 D 盘起飞…...

CustomThreads:3D打印螺纹创新3大突破,告别配合难题

CustomThreads:3D打印螺纹创新3大突破,告别配合难题 【免费下载链接】CustomThreads Fusion 360 Thread Profiles for 3D-Printed Threads 项目地址: https://gitcode.com/gh_mirrors/cu/CustomThreads 副标题:为何传统螺纹设计在FDM打…...

Python爬虫入门零门槛!30分钟爬取软科中国大学排名,生成交互式可视化排名表

做Python入门学习的同学,是不是都想找一个反爬弱、代码清晰、爬下来有用、能快速看到成果的实战项目? 很多入门教程要么爬一些过时的、没用的静态页面,要么代码写得晦涩难懂,要么爬下来的数据只是打印在控制台,完全没有…...

EcomGPT-7B电商大模型API接口安全设计

EcomGPT-7B电商大模型API接口安全设计 1. 引言 电商平台每天处理着海量的用户查询、商品信息和交易数据,这些数据不仅包含商业机密,还涉及大量用户隐私信息。想象一下,一个未经保护的API接口就像是一家没有门锁的金店,任何人都可…...

macOS资源下载完全指南:从入门到精通的网络资源嗅探解决方案

macOS资源下载完全指南:从入门到精通的网络资源嗅探解决方案 【免费下载链接】res-downloader 视频号、小程序、抖音、快手、小红书、直播流、m3u8、酷狗、QQ音乐等常见网络资源下载! 项目地址: https://gitcode.com/GitHub_Trending/re/res-downloader 网络…...

Cadence Sigrity 模块深度解析:从电源完整性到信号优化的全流程应用

1. Cadence Sigrity工具套件概览 在高速PCB设计领域,电源完整性和信号完整性分析已经成为确保电子设备可靠性的关键环节。Cadence Sigrity作为业界领先的EDA工具套件,提供了从直流分析到高频仿真的完整解决方案。我第一次接触这套工具是在2013年设计一块…...

【实战】Ubuntu 22.04LTS下Nvidia驱动安装与GCC版本冲突解决指南

1. 为什么你的Nvidia驱动安装总失败? 每次在Ubuntu上装Nvidia驱动就像在玩俄罗斯轮盘赌——有时候一次成功,有时候要反复折腾好几遍。特别是Ubuntu 22.04LTS这个长期支持版本,表面看着稳定,实际暗藏杀机。最常见的问题就是那个让人…...

⾃动化测试 概念

⾃动化⾃动化概念⾃动的代替⼈的⾏为完成操作。 ⾃动化在⽣活中处处可⻅⾃动化的主要⽬的就是⽤来进⾏回归测试。回归测试软件有多个版本需要进⾏功能的整体回归。为了避免新增功能影响到历史的功能需要进⾏功能的回归。常⻅⾯试题 1.⾃动化测试能够取代⼈⼯测试吗?…...

如何实现跨平台VSDX文件无缝协作?drawio-desktop全攻略

如何实现跨平台VSDX文件无缝协作?drawio-desktop全攻略 【免费下载链接】drawio-desktop Official electron build of draw.io 项目地址: https://gitcode.com/GitHub_Trending/dr/drawio-desktop 在数字化协作日益频繁的今天,跨平台文件兼容性问…...

超声AI 2026年市场格局:头部公司怎么选、谁在领跑

超声AI哪家做得好?”这个问题,2026年再用“列公司名单”的方式回答,其实已经不太够用了。因为医疗AI的竞争早就不只拼演示效果,更像一场硬仗:能不能上临床、敢不敢用、用得起、用得开。你最终要的不是“看起来很强”&a…...

终极魔兽争霸III优化指南:WarcraftHelper 完整使用教程

终极魔兽争霸III优化指南:WarcraftHelper 完整使用教程 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 想让经典魔兽争霸III在现代电脑上流…...

算法基础应用精讲【深度学习】-基于深度学习的多Agent入侵检测系统(理论篇)

目录 第一章 引言 1.1 研究背景与意义 1.2 研究现状 1.3 研究目标与主要贡献 1.4 论文(文档)结构 第二章 核心理论基础 2.1 多Agent系统(MAS)理论 2.1.1 多Agent系统的定义与核心特征 2.1.2 多Agent系统在入侵检测中的应用优势 2.2 深度学习核心算法理论 2.2.1 自…...

Testsigma自动化测试平台深度解析:AI协同测试架构设计与实践指南

Testsigma自动化测试平台深度解析:AI协同测试架构设计与实践指南 【免费下载链接】testsigma Testsigma is an agentic test automation platform powered by AI-coworkers that work alongside QA teams to simplify testing, accelerate releases and improve qua…...

3个关键技巧:让AirPods在Windows和Linux上也能享受完整苹果体验

3个关键技巧:让AirPods在Windows和Linux上也能享受完整苹果体验 【免费下载链接】AirPodsDesktop ☄️ AirPods desktop user experience enhancement program, for Windows and Linux (WIP) 项目地址: https://gitcode.com/gh_mirrors/ai/AirPodsDesktop 你…...

3步搭建你的演唱会抢票自动化助手:告别手速焦虑

3步搭建你的演唱会抢票自动化助手:告别手速焦虑 【免费下载链接】DamaiHelper 大麦网演唱会演出抢票脚本。 项目地址: https://gitcode.com/gh_mirrors/dama/DamaiHelper DamaiHelper是一个基于Python开发的智能抢票工具,专门针对大麦网演唱会门票…...

Windows系统苹果USB驱动安装全攻略:告别iTunes臃肿安装

Windows系统苹果USB驱动安装全攻略:告别iTunes臃肿安装 【免费下载链接】Apple-Mobile-Drivers-Installer Powershell script to easily install Apple USB and Mobile Device Ethernet (USB Tethering) drivers on Windows! 项目地址: https://gitcode.com/gh_mi…...

Awoo Installer:Switch游戏安装全场景解决方案的技术突破与实践指南

Awoo Installer:Switch游戏安装全场景解决方案的技术突破与实践指南 【免费下载链接】Awoo-Installer A No-Bullshit NSP, NSZ, XCI, and XCZ Installer for Nintendo Switch 项目地址: https://gitcode.com/gh_mirrors/aw/Awoo-Installer Awoo Installer作为…...

构建个人数字图书馆:用fanqienovel-downloader实现小说永久保存与跨设备阅读

构建个人数字图书馆:用fanqienovel-downloader实现小说永久保存与跨设备阅读 【免费下载链接】fanqienovel-downloader 下载番茄小说 项目地址: https://gitcode.com/gh_mirrors/fa/fanqienovel-downloader 在数字阅读日益普及的今天,如何突破网络…...

labview实现CPU温度的实时检测

上面的系统实现其实很简单,使用Windows 管理规范(WMI) 配合 LabVIEW 的 .NET 接口 实现的,属于系统级硬件监控。1. 核心实现方式:WMI(Windows Management Instrumentation)读取 CPU 温度&#x…...