Spring AI 开发本地deepseek对话快速上手笔记
Spring AI
Spring AI是一个旨在推进生成式人工智能应用程序发展的项目,Spring AI的核心目标是提供高度抽象化的组件,作为开发AI应用程序的基础,使得开发者能够以最少的代码改动便捷地交换和优化功能模块
在开发之前先得引入大模型,这里选择deepseek
至于导入deepseek,咱这里选用ollama 大模型工具来进行本地化部署和管理
ollama下载与启动
进入ollama官网:Ollama
下载对应版本
直接install
deepseek模型下载
下载deepseek模型,这里选择的是r1:8b版本的,各位可以根据自己的电脑配置进行选择
执行ollama run deepseek-r1:8b
看到显示了success即运行成功
spring依赖引入
<!-- WebFlux 响应式支持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></dependency><!--ollama spring ai依赖--><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-ollama-spring-boot-starter</artifactId><version>1.0.0-M6</version></dependency><!-- Swagger3-knife4j依赖 --><dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId><version>4.5.0</version></dependency>
ChatbotController
简单对话直接返回
@Slf4j
@RestController
public class ChatBotController {//注入模型,配置文件中的模型,或者可以在方法中指定模型@Resourceprivate OllamaChatModel model;
@GetMapping("/chat")public String chat(@RequestParam("message") String message){String call = model.call(message);System.out.println(call);return call;}}
启动
postman请求
返回
流式对话响应
@Slf4j
@RestController
public class ChatBotController {
//注入模型,配置文件中的模型,或者可以在方法中指定模型@Resourceprivate OllamaChatModel model;
@Resourceprivate StringRedisTemplate stringRedisTemplate;//引入存储消息服务@Resourceprivate ChatService chatService;@GetMapping(value = "/streamChat", produces = "text/event-stream;charset=UTF-8")public Flux<String> streamChat(@RequestParam("message")String message,@RequestParam String sessionId){Long userId = UserHolder.getUser().getId();return Flux.concat(processAnswering(message, sessionId, userId));}/*** 处理回答阶段*/private Flux<String> processAnswering(String message, String sessionId, Long userId) {return buildPromptWithContext(sessionId, message).flatMapMany(prompt ->model.stream(prompt).index().map(tuple -> {// 第一个消息添加标识if (tuple.getT1() == 0L) {return "[ANSWER] " + tuple.getT2();}return tuple.getT2();})).doOnNext(content -> saveMessage(sessionId, userId, message, content)).delayElements(Duration.ofMillis(30));}/*** 保存消息到Redis和数据库(带事务)*/@Transactionalprotected void saveMessage(String sessionId, Long userId, String question, String answer) {
// // 保存用户问题
// ChatContent userMsg = new ChatContent();
// userMsg.setSessionId(sessionId);
// userMsg.setMessage(question);
// chatService.save(userMsg);// 保存AI回答ChatContent aiMsg = new ChatContent();
// aiMsg.setSessionId(sessionId);aiMsg.setReceiveUserId(userId);aiMsg.setSendUserId(Long.valueOf(sessionId));aiMsg.setMessage(answer);
// aiMsg.setType("ASSISTANT");chatService.save(aiMsg);// 更新Redis上下文stringRedisTemplate.executePipelined((RedisCallback<Object>) connection -> {connection.lPush((CONTEXT_PREFIX + sessionId).getBytes(),question.getBytes(),answer.getBytes());connection.lTrim((CONTEXT_PREFIX + sessionId).getBytes(), 0, MAX_CONTEXT_LENGTH * 2 - 1);return null;});}
}
请求postman
返回
可以看到返回的数据为流式的
前端引入
UI
<div class="bot-chat-container"><!-- 聊天消息区域 --><div class="bot-chat-messages" ref="messagesContainer"><div v-for="message in bot_messages" :key="message.id":class="['message', message.sender]"><div class="avatar"><img :src="message.sender === 'user' ? userAvatar : botAvatar" alt="avatar"></div><div class="bubble"><div class="content" v-html="renderMarkdown(message.content)"></div><!--<div class="content" v-else>{{ message.content }}</div>--><div class="status"><span class="time">{{ message.timestamp }}</span><span v-if="message.loading" class="typing-indicator"><span class="dot"></span><span class="dot"></span><span class="dot"></span></span></div></div></div></div><!-- 输入区域 --><div class="bot-input-area"><textarea v-model="inputMessage"@keydown.enter.exact.prevent="sendMessage"placeholder="输入你的消息..."></textarea><button @click="sendMessage" :disabled="isSending"><span v-if="!isSending">发送</span><span v-else class="sending-indicator"></span></button></div></div>
函数typescript
const sendMessage = async () => {if (!inputMessage.value.trim() || isSending.value) return// 用户消息const userMsg: ChatMessage = {id: Date.now().toString(),content: inputMessage.value.trim(),sender: 'user',timestamp: new Date().toLocaleTimeString()}bot_messages.push(userMsg)// 机器人响应占位const botMsg: ChatMessage = {id: `bot-${Date.now()}`,content: '',sender: 'bot',timestamp: new Date().toLocaleTimeString(),loading: true}bot_messages.push(botMsg)inputMessage.value = ''isSending.value = true// scrollToBottom()try {const sessionId = crypto.randomUUID()// const eventSource = new EventSource(`api/bot/streamChat?message=${encodeURIComponent(userMsg.content)}`)// 发起带有 Authorization 头的流式请求await fetchEventSource(`api/streamChat?message=${encodeURIComponent(userMsg.content)}&sessionId=333`, {method: 'GET', // 或 POST(需服务端支持)headers: {'Authorization': sessionStorage.getItem("token"), // 注入认证头 :ml-citation{ref="8" data="citationList"}},onopen(response) {if (response.ok) return; // 连接成功throw new Error('连接失败');},onmessage(event) {// 处理流式数据(与原 EventSource 逻辑相同)const index = bot_messages.findIndex(m => m.id === botMsg.id)if (index !== -1) {bot_messages[index].content += event.databot_messages[index].loading = falsebot_messages[index].parsedContent = renderMarkdown(bot_messages[index].content)// scrollToBottom()}},onerror(err) {console.error('流式请求异常:', err);}});eventSource.onmessage = (event) => {const index = bot_messages.findIndex(m => m.id === botMsg.id)if (index !== -1) {bot_messages[index].content += event.databot_messages[index].loading = falsebot_messages[index].parsedContent = renderMarkdown(bot_messages[index].content)// scrollToBottom()}}eventSource.onerror = () => {eventSource.close()isSending.value = false}} catch (error) {console.error('Error:', error)isSending.value = false}
}
css
.bot-chat-container {display: flex;flex-direction: column;height: 100vh;background: #f5f5f5;
}.bot-chat-messages {flex: 1;overflow-y: auto;padding: 20px;background: linear-gradient(180deg, #f0f2f5 0%, #ffffff 100%);
}.message {display: flex;margin-bottom: 20px;gap: 12px;
}.message.user {flex-direction: row-reverse;
}.avatar img {width: 40px;height: 40px;border-radius: 50%;box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}.bubble {max-width: 70%;position: relative;
}.bubble .content {padding: 12px 16px;border-radius: 12px;line-height: 1.5;font-size: 14px;
}.message.bot .content {background: white;border: 1px solid #e5e7eb;border-radius: 12px 12px 12px 4px;
}.message.user .content {background: #3875f6;color: white;border-radius: 12px 12px 4px 12px;
}.status {display: flex;align-items: center;gap: 8px;margin-top: 4px;font-size: 12px;color: #666;
}.message.user .status {justify-content: flex-end;
}.typing-indicator {display: inline-flex;gap: 4px;
}.dot {width: 6px;height: 6px;background: #999;border-radius: 50%;animation: bounce 1.4s infinite ease-in-out;
}.dot:nth-child(2) {animation-delay: 0.2s;
}.dot:nth-child(3) {animation-delay: 0.4s;
}@keyframes bounce {0%, 80%, 100% { transform: translateY(0); }40% { transform: translateY(-4px); }
}.bot-input-area {display: flex;gap: 12px;padding: 20px;border-top: 1px solid #e5e7eb;background: white;
}textarea {flex: 1;padding: 12px;border: 1px solid #e5e7eb;border-radius: 8px;resize: none;min-height: 44px;max-height: 120px;font-family: inherit;
}button {padding: 0 20px;background: #3875f6;color: white;border: none;border-radius: 8px;cursor: pointer;transition: opacity 0.2s;
}button:disabled {background: #a0aec0;cursor: not-allowed;
}.sending-indicator {display: inline-block;width: 20px;height: 20px;border: 2px solid #fff;border-top-color: transparent;border-radius: 50%;animation: spin 0.8s linear infinite;
}@keyframes spin {to { transform: rotate(360deg); }
}
.bubble :deep() pre {background: #f8f8f8;padding: 12px;border-radius: 6px;overflow-x: auto;
}.bubble :deep() code {font-family: 'JetBrains Mono', monospace;font-size: 14px;
}.bubble :deep() ul,
.bubble :deep() ol {padding-left: 20px;margin: 8px 0;
}.bubble :deep() blockquote {border-left: 4px solid #ddd;margin: 8px 0;padding-left: 12px;color: #666;
}
发送消息
至此简单的AI对话完成了
源码地址
后端:https://github.com/enjoykanyu/chat_serve
前端:https://github.com/enjoykanyu/kChat_web
觉得不错得话,可以帮点个star呀,感谢
若在执行部署过程中有任何问题,欢迎githup提issue
相关文章:
Spring AI 开发本地deepseek对话快速上手笔记
Spring AI Spring AI是一个旨在推进生成式人工智能应用程序发展的项目,Spring AI的核心目标是提供高度抽象化的组件,作为开发AI应用程序的基础,使得开发者能够以最少的代码改动便捷地交换和优化功能模块 在开发之前先得引入大模型…...
Python训练打卡Day23
机器学习管道 pipeline 基础概念 pipeline在机器学习领域可以翻译为“管道”,也可以翻译为“流水线”,是机器学习中一个重要的概念。 在机器学习中,通常会按照一定的顺序对数据进行预处理、特征提取、模型训练和模型评估等步骤,以…...
【每天一个知识点】Dip 检验(Dip test)
Dip 检验(Dip test)是一种用于检验一维数据分布是否为单峰(unimodal)的非参数统计方法。该检验由 Hartigan 和 Hartigan 于 1985 年提出,通常用于探索性数据分析中,以判断数据是否仅具有一个峰值结构&#…...
AbstractQueuedSynchronizer之AQS
一、前置知识 公平锁和非公平锁: 公平锁:锁被释放以后,先申请的线程先得到锁。性能较差一些,因为公平锁为了保证时间上的绝对顺序,上下文切换更频繁 非公平锁:锁被释放以后,后申…...
【Qt】pro工程文件转CMakeLists文件
1、简述 Qt6以后默认使用cmake来管理工程,之前已经一直习惯使用pro,pro的语法确实很简单、方便。 很多项目都是cmake来管理,将它们加入到Qt项目中,cmake确实是大势所趋。比如,最近将要开发的ROS项目,也是使用的cmake语法。 以前总结的一些Qt代码,已经编写成pro、pri等…...
docker-compose部署thingsboard/tb-cassandra
1、配置 阿里云服务器2H8G 最低 系统:Ubuntu20.0.4 安装 docker 和 docker-compose 环境 ====================安装docker====================== # 更新包 sudo apt update# 安装docker sudo apt install docker.io# 查看是否安装成功 docker --version==================…...
MySQL 日期计算方法 date_sub()、date_add()、datediff() 详解-文中有示例帮助理解
1、date_sub()、date_add() date_sub() 和date_add() 语法相同,只不过一个加一个减。 从日期中减去指定时间间隔 语法: DATE_SUB(start_date, INTERVAL expr unit) start_date: 起始日期(如 now() , 字段名)。 INTERVAL expr…...
GPT-4.1和GPT-4.1-mini系列模型支持微调功能,助力企业级智能应用深度契合业务需求
微软继不久前发布GPT-4.1系列模型后,Azure OpenAI服务(国际版)现已正式开放对GPT-4.1和GPT-4.1-mini的微调功能,并通过Azure AI Foundry(国际版)提供完整的部署和管理解决方案。这一重大升级标志着企业级AI…...
如何将两台虚拟机进行搭桥
虚拟机网络搭桥配置指南 要实现两台虚拟机之间的网络互通("搭桥"),需要根据您的虚拟化平台选择合适的网络模式。以下是主流虚拟化软件的配置方法: 一、VMware 虚拟机互通配置 方案 1:使用桥接模式&#x…...
无缝对接主流电商平台接口,解决货源难题
行业调查显示,大多数代购商每天要花费数小时在淘宝、1688等平台寻找合适商品。手动复制商品链接、整理信息不仅耗时耗力,还容易出错——价格标错、库存不准等问题时有发生,直接影响客户体验。更麻烦的是,不同平台的商品信息格式不…...
GZip+Base64压缩字符串在ios上解压报错问题解决(安卓、PC模拟器正常)
java这边的压缩代码 引入的是java8 jdk自带的gzip压缩( java.util.zip.GZIPOutputStream)、BASE64Encoder( sun.misc.BASE64Encoder) public static String compress(String str) {if (str ! null && str.length() ! 0) {ByteArrayOutputStream…...
Cookie、 Local Storage、 Session Storage三种客户端存储方式
存储特性对比表 特性CookieLocal StorageSession Storage生命周期可设置过期时间永久保存会话结束自动清除存储容量4KB左右5-10MB5-10MB自动发送到服务器每次HTTP请求头携带不发送不发送访问方式服务端/客户端均可读写仅客户端仅客户端 使用场景及示例 1. Cookie - 用户身份…...
进程等待简单讲解
1. 基本概念 1.1 进程终止与退出状态 当一个进程终止时,它会向其父进程发送一个信号(通常是SIGCHLD),并保存退出状态(exit status)。退出状态可以是一个正常终止的返回值,也可以是一个信号导致…...
基于大模型预测胸椎管狭窄诊疗全流程的研究报告
目录 一、引言 1.1 研究背景与意义 1.2 研究目的与创新点 1.3 研究方法与数据来源 二、胸椎管狭窄症概述 2.1 疾病定义与分类 2.2 病因与发病机制 2.3 流行病学特征 三、大模型技术原理与应用现状 3.1 大模型基本原理 3.2 在医疗领域的应用案例 3.3 用于胸椎管狭窄…...
Oracle OCP认证考试考点详解083系列15
题记: 本系列主要讲解Oracle OCP认证考试考点(题目),适用于19C/21C,跟着学OCP考试必过。 71. 第71题: 题目 解析及答案: 关于在 Oracle 18c 及更高版本中基于 Oracle 黄金镜像的安装,以下哪…...
【老飞飞源码】新版高清飞飞源码+数据库+客户端+服务器端完整文件打包
【老飞飞源码】新版高清飞飞源码数据库客户端服务器端完整文件打包下载 编译环境 vs2022 搭建环境 sql2022 测试运行环境 windows 11 本地测试生成搭建都成功 功能包含: pvp排行榜 宠物特效 箱子预览系统 vip系统 宝箱系统 内挂系统 离线摆摊系统 特效帽子系…...
Maven 动态插件配置:Profile的灵活集成实践
🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,精通Java编…...
Python爬虫如何应对网站的反爬加密策略?
在当今的互联网环境中,网络爬虫已经成为数据采集的重要工具之一。然而,随着网站安全意识的不断提高,反爬虫技术也越来越复杂,尤其是数据加密策略的广泛应用,给爬虫开发者带来了巨大的挑战。本文将详细介绍Python爬虫如…...
STM32H743输出50%的占空比波形
使用cubeMX进行配置如下: 时钟配置如下: 具体代码如下: /* USER CODE BEGIN Header */ /********************************************************************************* file : main.c* brief : Main program b…...
ios remote debut proxy 怎么开启手机端调试和inspect
手机开启远程调试教程(适用于 Chrome / Safari) 前端移动端调试指南|适用 iPhone 和 Android|WebDebugX 出品 本教程将详细介绍如何在 iPhone 和 Android 手机上开启网页检查器,配合 WebDebugX 实现远程调试。教程包含…...
GraspVLA:基于Billion-级合成动作数据预训练的抓取基础模型
25年5月来自银河通用(Galbot)、北大、港大和 BAAI 的论文“GraspVLA: a Grasping Foundation Model Pre-trained on Billion-scale Synthetic Action Data”。 具身基础模型因其零样本泛化能力、可扩展性以及通过少量后训练即可适应新任务的优势&#x…...
BGP联邦实验
一.需求 1.AS1存在两个环回,一个地址为192.168.1.0/24,该地址不能再任何协议中宣告 AS3存在两个环回,一个地址为192.168.2.0/24,该地址不能再任何协议中宣告 AS1还有一个环回地址为10.1.1.0/24,AS3另一个环回地址是…...
自动化测试基础知识详解
🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 自动化测试是指利用自动化工具和脚本,模拟人工操作进行软件测试的过程。它在软件开发中扮演着非常重要的角色,可以提高测试效率、降低成本…...
Java后端快速生成验证码
Hutool是一个小而全的Java工具类库,它提供了很多实用的工具类,包括但不限于日期处理、加密解密、文件操作、反射操作、HTTP客户端等。 核心工具类:CaptchaUtil,CaptchaUtil 是 Hutool 提供的一个工具类,用于创建各种类…...
【愚公系列】《Manus极简入门》036-物联网系统架构师:“万物互联师”
🌟【技术大咖愚公搬代码:全栈专家的成长之路,你关注的宝藏博主在这里!】🌟 📣开发者圈持续输出高质量干货的"愚公精神"践行者——全网百万开发者都在追更的顶级技术博主! …...
主流高防服务器技术对比与AI防御方案实战
1. 高防服务器核心能力对比 当前市场主流高防服务商(如阿里云、腾讯云、华为云)的核心防御能力集中在流量清洗与静态规则防护,但面临以下挑战: 静态防御瓶颈:传统方案依赖预定义规则,对新型攻击ÿ…...
带格式的可配置文案展示
方案一(格式包含颜色换行等) 服务端:配置后接口输出带标签的字符串,但是尖括号不能被转义前端:v-html接受字符串(vue项目),原生用innerHTML赋值 方案二(格式针对只存在…...
湖南大学3D场景问答最新综述!3D-SQA:3D场景问答助力具身智能场景理解
作者: Zechuan Li, Hongshan Yu, Yihao Ding, Yan Li, Yong He, Naveed Akhtar 单位:湖南大学,墨尔本大学,悉尼大学,安徽大学 论文标题:Embodied Intelligence for 3D Understanding: A Survey on 3D Sce…...
【PyTorch】深度学习实践——第二章:线性模型
参考:刘二老师的《PyTorch深度学习实践》完结合集 本章实现了一个简单的线性回归模型,用于学习输入x和输出y之间的线性关系(yw*x)。 一、代码细节 1.数据准备 x_data [1.0, 2.0, 3.0] y_data [2.0, 4.0, 6.0]定义了训练数据,x和y之间显然…...
【Python 中文编码】
在 Python 中处理中文编码问题时,需重点关注文件编码声明、字符串编码转换及环境配置。以下是分步指南和最佳实践: 一、Python 3 的默认编码行为 Python 3.x:默认使用 UTF-8 编码(与 Python 2.x 的 ASCII 默认编码不同࿰…...
Excel宏和VBA
Excel宏和VBA(Visual Basic for Applications)是自动化Excel操作的强大工具,可帮助用户批量处理数据、自定义功能、提升效率。以下是详细使用方法及示例: --- ### **一、基础操作** #### 1. **录制宏** - **步骤**࿱…...
1688 API 接口使用限制
在使用 1688 API 接口时,需要注意以下几方面的限制和注意事项,以确保合规使用并避免不必要的问题。 一、调用频率限制 1688 平台对 API 接口的调用频率通常有限制,以防止滥用和对服务器造成过大压力。具体限制如下: 免费版&…...
5. 动画/过渡模块 - 交互式仪表盘
5. 动画/过渡模块 - 交互式仪表盘 案例:数据分析仪表盘 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title></head><style type"text/css">.dashboard {font-family: Arial…...
数据擦除标准:1-Pass vs. 3-Pass vs. 7-Pass有什么区别,哪个更好?
虽然像美国国防部(DoD)5220.22-M这样的旧标准提倡多次覆盖,但像NIST 800-88和新兴的IEEE 2883标准这样的新指南已经改变了对数据擦除效果的看法。在这篇博客中,我们解释了不同的擦除方法,并分析了旧标准在新时代是否仍然相关。 理解数据擦除方法 数据擦除包括用0、1或随…...
MySQL推荐书单:从入门到精通
给大家介绍一些 MySQL 从入门到精通的经典书单,可以基于不同学习阶段的需求进行选择。 入门 MySQL必知必会 这本书继承了《SQL必知必会》的优点,专门针对 MySQL 用户,没有过多阐述数据库基础理论,而是紧贴实战,直接从…...
Rodrigues旋转公式-绕任意轴旋转
Rodrigues旋转公式 给定旋转轴单位向量 k ( k x , k y , k z ) \mathbf{k}(k_x,k_y,k_z) k(kx,ky,kz)和旋转角度 θ \theta θ,旋转矩阵 R R R可以表示为: R I sin θ K ( 1 − cos θ ) K 2 RI\sin \theta K(1-\cos \theta)K^2 RIsin…...
【大模型面试每日一题】Day 17:解释MoE(Mixture of Experts)架构如何实现模型稀疏性,并分析其训练难点
【大模型面试每日一题】Day 17:解释MoE(Mixture of Experts)架构如何实现模型稀疏性,并分析其训练难点 📌 题目重现 🌟🌟 面试官:解释MoE(Mixture of Experts)架构如何…...
Datawhale 5月coze-ai-assistant 笔记1
课程地址: coze-ai-assistant-课程摘要 | Datawhalehttps://www.datawhale.cn/learn/summary/105 动手实践 链接:https://www.coze.cn/home 作业:智能体链接地址扣子扣子是新一代 AI 大模型智能体开发平台。整合了插件、长短期记忆、工作…...
2025.5.13总结
想要成为自己想要成为的那个人,并不是一件容易的事情。在我报口才课的时候,老师一针见血的指出了我的不足。因为不敢,所以不做,因为不去做,所以不会,而正因为不会,也导致了你不敢。当我听到这个…...
spring中的@Async注解详解
一、核心功能与作用 Async 是Spring框架提供的异步方法执行注解,用于将方法标记为异步任务,使其在独立线程中执行,从而提升应用的响应速度和吞吐量。其主要作用包括: 非阻塞调用:主线程调用被标记方法后立即返回&…...
计算机视觉----时域频域在图像中的意义、傅里叶变换在图像中的应用、卷积核的频域解释
1、时域(时间域)——自变量是时间,即横轴是时间,纵轴是信号的变化。其动态信号x(t)是描述信号在不同时刻取值的函数。 2、频域(频率域)——自变量是频率,即横轴是频率,纵轴是该频率信号的幅度,也就是通常说…...
分布式链路跟踪
目录 链路追踪简介 基本概念 基于代理(Agent)的链路跟踪 基于 SDK 的链路跟踪 基于日志的链路跟踪 SkyWalking Sleuth ZipKin 链路追踪简介 分布式链路追踪是一种监控和分析分布式系统中请求流动的方法。它能够记录和分析一个请求在系统中经历的每…...
从数据中台到数据飞轮:实现数据驱动的升级之路
从数据中台到数据飞轮:实现数据驱动的升级之路 随着数字化转型的推进,数据已经成为企业最重要的资产之一,企业普遍搭建了数据中台,用于整合、管理和共享数据;然而,近年来,数据中台的风潮逐渐减退…...
深入解析Java序列化:从使用到原理
在此之前,对于 Java 中的序列化,我一直停留在使用层面 —— 把需要序列化在网络上传输的类实现Serializable接口就可以了 但对于这块知识点,随着工作年限的提升,我觉得必须要好好研究下它了,不能似懂非懂的只知道使用。…...
Python面向对象编程(OOP)深度解析:从封装到继承的多维度实践
引言 面向对象编程(Object-Oriented Programming, OOP)是Python开发中的核心范式,其三大特性——封装、继承、多态——为构建模块化、可维护的代码提供了坚实基础。本文将通过代码实例与理论结合的方式,系统解析Python OOP的实现机制与高级特性…...
传输层:UDP协议
1.UDP协议特点 2.UDP报文格式 如下: 校验和的计算: 3.例子 UDP(User Datagram Protocol,用户数据报协议)是一种无连接的传输层协议,其报文格式简单高效,适用于对实时性要求高但允许少量丢包的…...
使用WebStorm打断点调试Vue项目
1:打开WebStorm,先配置vue启动的服务,如下 2:如果上面的选择第4步空白,,就先启动过vue项目,或者在packege.json启动过,就可以直接添加npm服务 3:使用Debug启动项目 4&…...
AI助力:零基础开启编程之旅
一、代码调试 三步解决BUG 1. 错误信息翻译 指令模板: 错误诊断模式我遇到【编程语言】报错“粘贴报错信息“ 请: 用小白能懂的话解释问题本质标注可能引发该错误的三个场景给出最可能的修复方案和其他备选方案 2. 上下文分析 进阶指令 结合上下文代…...
信息学奥赛一本通 1535:【例 1】数列操作
【题目链接】 ybt 1535:【例 1】数列操作 【题目考点】 1. 树状数组 【解题思路】 本题为树状数组模板题,维护区间和,进行单点修改,区间查询。 详细讲解见:洛谷 P3374 【模板】树状数组 1(树状数组解法…...
MQTT协议详解:物联网通信的轻量级解决方案
MQTT协议详解:物联网通信的轻量级解决方案 引言 在物联网(IoT)快速发展的今天,设备间高效可靠的通信变得至关重要。MQTT(Message Queuing Telemetry Transport)作为一种轻量级的发布/订阅协议,已成为物联网通信的首选解决方案。本文将深入探…...