- 博客(71)
- 收藏
- 关注
原创 (六) Spring AI 1.0版本 + 千问大模型+RAG
上篇文章我们大概讲了一下向量模型的知识,本篇文章,我们将会通过RAG实战的形式,来感受一下RAG。
2025-07-26 15:59:22
301
原创 (五) Spring AI 1.0版本 + 千问大模型+向量模型
Embedding将数据表示为语义空间中的点 ,就像欧氏几何中点的坐标决定其远近,语义空间中点的距离反映含义的相似性:话题相近的句子在多维空间中的位置更接近,如同图表上相邻的数据点。在检索增强生成(RAG)中特别重要。是一种将离散的符号(如单词、字符、语音、视频等)映射到连续向量空间的技术。这些向量能够捕获符号之间的语义和语法关系。以上就是本次分享的内容了。喜欢的读者可以关注我的公众号。application.yaml文件。ChatConfig配置类。这里只只引入了需要的包。控制台会输出一段向量值。
2025-07-26 10:02:24
311
原创 (四)Spring AI 1.0版本 + 千问大模型 实现函数工具调用 FunctionToolCallback
上篇文章主要讲解了Spring AI的@Tool注解的形式来实现工具调用的。
2025-07-20 22:24:19
833
原创 (三)Spring AI 1.0版本 + 千问大模型 实现 Tool Calling
1、name: 工具名称。若不指定,默认使用方法名称。AI 模型通过此名称识别调用工具,因此不允许在同一类中存在同名工具。模型处理单个聊天请求时,所有可用工具的名称必须保持全局唯一。2、description: 工具描述,用于指导模型判断何时及如何调用该工具。若未指定,默认使用方法名称作为工具描述。但强烈建议提供详细描述,因为这对模型理解工具用途和使用方式至关重要。
2025-07-20 18:06:36
791
1
原创 (二)Spring AI 1.0版本 + 千问大模型之 文本记忆对话
Spring AI 除此之外还提供了其他的消息存储方式,详细内容可以参考 https://docs.spring.io/spring-ai/reference/api/chat-memory.html。上篇文章,主要是简单讲解了一下文本对话的功能。参数中的chatId,可以根据自己的实际场景去设定,一般是一个会话页面。项目构建就不详细说了,大家可以参考上篇 文本对话 文章。3、ChatController类。以上功能就可以实现会话记忆功能了。2、修改ChatConfig类。
2025-07-19 20:04:26
339
原创 (一)Spring AI 1.0版本 + 千问大模型之文本对话
最近学习了一下最近比较火的Spring AI 项目,作为一个Java coder,Spring生态是最熟悉不过的内容。下面我将通过项目的形式来感受一下Spring AI,这里只是简单的使用实例,不涉及代码深层次的探究。
2025-07-19 19:21:17
334
原创 IDEA 中 Undo Commit,Revert Commit,Drop Commit区别
是否删除对代码的修改是否删除Commit记录是否会新增Commit记录不会未Push会,已Push不会不会会不会会会未Push会,已Push不会不会。
2025-06-06 21:39:08
1216
1
原创 @TableLogic的实现原理
注解定义了两个属性:value()和delval(),分别表示"未删除值"和"已删除值"/*** 默认逻辑未删除值(该值可无、会自动获取全局配置)*//*** 默认逻辑删除值(该值可无、会自动获取全局配置)*/MyBatis-Plus的通过注解标记哪些字段是逻辑删除字段在初始化时收集逻辑删除信息并存储在表元数据中拦截删除操作,将DELETE语句转换为UPDATE语句生成适当的SET子句将字段更新为"已删除"值在查询条件中自动添加"未删除"的条件。
2025-05-13 15:31:50
629
原创 Docker安装MySql 8.0
使用上面的命令检查一下本机的docker的运行环境。执行完成之后,会输出docker的版本号。是因为连不上默认的镜像地址。需要将镜像源地址,改成国内。拉取mysql8.0版本对的镜像。我们可以看到mysql 8.0已经启动成功。详细操作参考我的另外一篇文章。拉取镜像之后,执行下面的命令。
2025-03-28 22:44:38
971
原创 Docker 设置国内镜像源
1、一般使用Docker Desktop软件,在 Docker Desktop 的图形界面中完成镜像源的更换操作。具体步骤如下: 打开 Docker Desktop 后,在菜单栏依次点击。此时会弹出一个 JSON 编辑框,可以在此处添加国内镜像地址。找到daemon.json修改成上面的json文件内容。对于 Linux 用户,则需手动编辑。
2025-03-28 22:42:58
4218
原创 深入理解ReentrantLock源码
1、可重入是指同一个线程可以多次获取同一把锁。例如,在一个方法中获取了锁,然后在这个方法内部调用了另一个也需要获取该锁的方法,此时线程可以成功获取锁,而不会被阻塞。这就好比一个人有一把自己房间的钥匙,他可以多次进入自己的房间,每次进入相当于线程对锁的一次获取。2、是独占锁,在同一时刻,只有一个线程可以获取该锁。当一个线程获取了锁之后,其他线程如果也想获取这把锁,就会被阻塞,直到锁被释放。这就像是一个只有一个入口的房间,一次只能有一个人进入。3、 它通过一个内部的同步器(
2025-03-26 21:47:19
915
原创 CDN概念和基础知识
CDN (Content Delivery Network) 是一种网络架构。主要是为了提高用户对互联网上内容的访问速度和性能。CDN 是通过在全球各地部署大量的服务器节点。将内容缓存到离用户更近的服务器上,从而减少内容传输的距离,提供访问速度和响应时间、
2025-03-15 21:27:58
469
原创 深入理解Spring事件监听机制
对于开发者来说,使用 Spring 监听机制非常简单。只需要实现事件和监听器接口,并在代码中注册监听器即可。Spring 会自动管理事件和监听器的生命周期,确保它们的正确运行。同时,由于 Spring 监听器使用了异步执行机制,因此不会影响主线程的运行效率,保证了应用程序的高并发和高效性。
2025-02-08 21:41:08
876
原创 LeetCode 128: 最长连续序列
3: 如果第一个元素-1 的值 不在 HahSet 中,则记录当前的值,循环查询当前值+1 的值是否在 HashSet中。如果存在,则连续序列的长度+1。2: 遍历整个HashSet,首先判断当前元素-1 的值是否在 HashSet中,如果不存在,才有可能是一个连续的序列。1: 首先将数组中的所有元素放入到 HashSet 中,去除掉重复元素。通过哈希集合存储整数,以快速判断是否存在相邻数字,从而高效地找出数组中的最长连续序列。,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。
2025-02-08 20:48:59
419
原创 Java 中的各种锁
Java 中我们经常听到各种锁,例如悲观锁,乐观锁,自旋锁等等。今天我们将 Java 中的所有锁放到一起比较一下,并分析各自锁的特点,让大家能够快捷的理解相关知识。
2024-12-29 17:45:59
903
原创 ThreadLocal 详解
ThreadLocal是一个将在多线程中为每个线程创建单独的变量副本的类。当使用 ThreadLocal来维护变量时,ThreadLocal 会为每个线程创建单独的变量副本,避免因多线程操作共享变量而导致的数据不一致情况。
2024-12-26 10:05:14
456
原创 线程可见性问题?还是编译优化问题?
我们思考一下,count的值是类成员变量,一个线程修改count值之后,肯定会刷入到内存中的。那也就是说,在不加volatile的前提下,如果我把代码中 Thread.sleep()的方法参数中的时间调大一些,应该能够将count的最新值刷入到内存中,setCount()方法可见。变量count的值被修改了,子线程执行setCount()方法的时候,count的值一直不可见的。我们知道,JVM会对我们的代码进行编译优化,我们来验证一下,是不是编译器优化的问题。执行完成之后,你会发现,问题确实解决了。
2024-09-08 18:46:26
525
原创 深入理解并发之AtomicReference类
通过AtomicReference的源码可知,最终保证原子操作的是unsafe.getAndSetObject(this, valueOffset, newValue)。由于getAndSetObject是native方法,我需要看下JVM中该方法的实现原理。 上篇文章主要分享了基本封装类型的原子类,例如 AtomicInteger,AtomicBoolean,AtomicLong等。那么对象的原子操作如何实现?假设,我们现在要对用户进行银行卡转账操作并保证转账的安全性。
2024-06-04 16:16:44
660
原创 深入理解并发之LongAdder、DoubleAdder的实现原理
答案是否定的。那么 @sun.misc.Contended 注解就是将该变量数据强制刷到不同的缓存行中。通过阅读DoubleAdder的代码之后,你会发现DoubleAdder和LongAdder的代码几乎一样,所以两者的原理都是一样的,这里就不对DoubleAdder 的代码一行行注释了,大家自行阅读。那么我们是不是可以思考一下,将int数据进行打散,分成若干个值,分别计算,最好将值进行汇总。 根据缓存行的长度,变量不足长度的数据,进行强制填充。
2024-06-04 16:15:51
508
原创 深入理解并发原理之原子类
上文说到,CPU层次,OS层次,都已经解决了并发问题。都是采用了原子操作指令。下面我们通过Java语言的Atomic原子类,看下Java语言是如果做到原子操作的。
2024-05-30 08:51:33
568
原创 深入理解并发问题的产生原因和解决方案
这个时候,进入等待队列,也需要进行竞争(多个线程没有获取成功),所有,需要对队列的tail指针进行加锁,加锁成功,进入阻塞队列,加锁失败,进行自旋,一直能够加锁成功,进入队列。之前加锁成功,执行完代码之后,会唤醒阻塞队列中的线程,让阻塞队列中的线程重新进行标志位加锁,循环往复,直到执行完代码,线程销毁。这些并发问题就能完美解决。上面对控制总线加锁的方案,确实能够解决并发问题,但是又引入另外一个问题,性能问题: 控制总线是整个系统的资源,同一时间只能有一个CPU使用该资源,多核CPU就变得无意义了。
2024-05-30 08:50:52
856
原创 为什么是MC(Memcached)而不是Redis?
本文主要分享一下MC和redis作为缓存的一些比较,希望读者能够通过对比,了解二者的区别,能够在适合的场景中使用。以上就是本次分享的所有内容,主要讲述一下Redis和MC的一些对比和相关的实践。如有不足,请多多指正。
2024-02-21 14:24:50
689
原创 响应式编程
响应式编程(Reactive Programming)是一种面向数据流和变化传播的编程范式,其目标是实现高效、可伸缩和响应式的系统。它强调通过触发数据流的变化来实现响应式的系统。在响应式编程中,数据流被视为异步事件序列,通过使用基于事件的操作符来处理和响应这些事件。由事件模型,我们可以想到观察者模式,其实观察者模式也是响应式的一种。有兴趣的读者可以看下响应式宣言响应式宣言: https://www.reactivemanifesto.org/zh-CN。
2024-02-19 11:15:06
595
原创 网络IO模型
本篇博客主要讲解一下网络IO模型。我们常见的网络模型分为 阻塞IO模型,非阻塞IO模型,IO复用模型,信号驱动IO模型,异步IO模型。下面我详细的介绍一下这五个IO模型。前4种IO模型都是同步阻塞IO模型,因为其第二阶段数据报从内核拷贝到用户空间都是同步阻塞的,只是第一阶段等待数据报的处理不同;最后一种IO模型(异步IO模型)才是真正的异步非阻塞IO模型,内核将一切事情都干完。
2024-02-19 10:12:33
993
原创 Redis key命名规范
Redis key命名规范一、实现目标简洁,高效,可维护二、键值设计规约1 Redis key 命名风格**【推荐】**Redis key 命名需具有可读性以及可管理性,不该使用含义不清的 key 以及特别长的 key 名;【强制】以英文字母开头,命名中只能出现小写字母、数字、英文点号 (.) 和英文半角冒号(????;【强制】不要包含特殊字符,如下划线、空格、换行、单双引号以及其他转义字符;2 命名规范【强制】命名规范:业务模块名: 业务逻辑含义: 其他: value 类型1
2024-02-01 20:43:31
1362
原创 EasyExcel实现三级联动
项目中需要在导出的模板中新增三级联动的功能,类似省市区的联动。在网上找了一些方法,都不能直接使用,需要进行修改。本文主要分享一下,改后的代码,可以直接使用。以上就是excel实现三级联动的功能实现。当然如果你觉得这么写非常麻烦,也可以将设置好的excel,上传到指定目录下,通过直接下载excel的形式实现该功能。以上就是本次分享的内容,如有不足请多多指正。
2024-02-01 16:10:30
2364
6
原创 深入理解MySQL之分区表原理和注意事项
最为糟糕的形式是逐行插入。当然,限制分区的数量也是有效的。答案是你每次查询的数据都是某一个批次的时候就可以用分区,比如说字典,业务的字典和用户类型的字典一般都是存放在同一张表里面的,且你每次查询的时候不是差一个业务或者一个用户类型,而是查询整个业务或者用户类型,这就是一个批次,此时也可以用分区来实现;当更新一条记录时,分区层先打开并锁住所有的底层表,mysql先确定需要更新的记录再哪个分区,然后取出数据并更新,再判断更新后的数据应该再哪个分区,最后对底层表进行写入操作,并对源数据所在的底层表进行删除操作。
2024-01-19 11:27:48
1530
2
原创 深入理解MySQL之分区表
当我们单表数据量比较大的时候,单表查询的IO较大。这个时候,我们是不是可以将表的数据分成多个文件,按照某个条件进行单文件的查询,这样避免了大量的IO操作。通过分而治之的思想,减少IO操作,提升查询效率。本文主要是讲述MySQL中分区表,看MySQL是如何实现分区表的。
2024-01-19 11:26:13
1108
原创 敏捷开发之开发流程
敏捷如果用好了,真的可以提高产研效率,拥抱变化、快速迭代,但是敏捷也不是万金油,需要满足天时地利人和,条件有些苛刻老板大力支持:这个是一切的前提,比如我们之前是老板大力推广敏捷,全部门就能搞起来,后来老板方向变了,敏捷就不搞了;项目能支持小步迭代:敏捷比较适合探索类的项目、或者是 APP 之类的迭代快的项目,因为需求非常容易变更、任务好拆分;如果是传统项目,需求一开始就定好了,任务也不好拆,你就还是老实用瀑布模型吧;团队成员闭环。
2024-01-18 20:10:14
2700
1
原创 敏捷开发之团队组成
上篇文章分享了敏捷开发中的Scrum的流程,简单介绍了Scrum的流程和相关概念,其中Scrum的角色有三种分别是 产品负责人,团队负责人,项目执行人员。本文主要对团队中的角色以及其负责的内容,进行详细讲解。
2024-01-17 20:59:30
1304
原创 敏捷开发之Scrum
敏捷开发的实现主要包括 SCRUM、XP(极限编程)、Crystal Methods、FDD(特性驱动开发)等等。同样是敏捷开发,XP 极限编程更侧重于实践,并力求把实践做到极限。敏捷开发并不是简单地追求速度,而是在保证质量的前提下,尽可能地提高开发效率和满足客户需求。,将软件生命周期划分为固定的六个基本活动,并且规定了它们自上而下、相互衔接的次序,如同瀑布流水,逐级下落。以上就是对Scrum流程的简单介绍,后面将会通过团队角色和开发流程进一步讲解敏捷开发。 敏捷开发的核心理念是。
2024-01-17 20:40:10
1499
原创 Docker环境安装
CentOS Docker 安装脚本自动安装1: 命令如下curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun也可以通过国内 daocloud 一键安装命令curl -sSL https://get.daocloud.io/docker | sh手动安装1: 首先删除Centos 系统中旧版本的dockersudo yum remove docker \ docker-cl
2024-01-15 20:21:24
505
原创 TCP怎么保证传输过程的可靠性?
校验和发送方在发送数据之前计算校验和,接收方收到数据后同样计算,如果不一致,那么传输有误确认应答,序列号TCP进行传输时数据都进行了编号,每次接收方返回ACK都有确认序列号。超时重试这里是引用连接管理流量控制阻塞控制...
2024-01-15 20:20:41
465
原创 谈⼀谈你对TCPIP四层模型,OSI七层模型的理解
TCP/IP四层模型 对比 OSI七层模型OSI七层模型为了增强通⽤性和兼容性,计算机⽹络都被设计成层次机构,每⼀层都遵守⼀定的规则。因此有了OSI这样⼀个抽象的⽹络通信参考模型,按照这个标准使计算机⽹络系统可以互相连接物理层通过⽹线、光缆等这种物理⽅式将电脑连接起来。传递的数据是⽐特流,0101010100。数据链路层⾸先,把⽐特流封装成数据帧的格式,对0、1进⾏分组。电脑连接起来之后,数据都经过⽹卡来传输,⽽⽹卡上定义了全世界唯⼀的MAC地址。然后再通过⼴播的形式向局域⽹内所有电脑
2024-01-14 16:20:41
552
原创 说说TCP 3次握⼿和4次握手
三次握手过程client端建⽴连接,发送⼀个SYN同步包,发送之后状态变成SYN_SENTserver端收到SYN之后,同意建⽴连接,返回⼀个ACK响应,同时也会给client发送⼀个SYN包,发送完成之后状态变为SYN_RCVDclient端收到server的ACK之后,状态变为ESTABLISHED,返回ACK给server端。server收到之后状态也变为ESTABLISHED,连接建⽴完成。思考: 为什么要3次?2次,4次不⾏吗? 因为TCP是双⼯传输模式,不区分客户端和服务端,连
2024-01-14 16:19:46
555
5
原创 New一个对象的过程
new一个对象的整体过程过程解析当虚拟机遇见new关键字时候,实现判断当前类是否已经加载过,如果没有加载过,首先执行类的加载机制,加载完成后再为对象分配空间、初始化等。首先校验当前类是否被加载过,如果没有加载,执行类加载机制加载: 从字节码加载成二进制流的过程验证: 当然加载完成之后,需要校验Class文件是否符合虚拟机规范。准备: 为静态变量 常量赋默认值把常量池中符号引用(以符号描述引用的目标)替换为直接引用的过程静态代码块是绝对线程安全的。只能隐式被java虚拟机在类加载过程中
2024-01-14 16:18:30
434
原创 Lombok简介和常用注解
Lombok简介1:作用简化Pojo(不包含业务逻辑,能够控制自己内部n个属性访问的java对象)类的书写(getter, setter ,toString ,equals, hashcode…)2: 各种POJOdto:data transfer object (前台传输过来的参数)do :data object(表字段一一对应)bo : service处理对象vo : view/value object值对象 对应视图对象3: Lombok注解使用构造函数注解@NoArgsConst
2024-01-11 11:34:34
730
原创 Lombok @Data使用的坑
Lombok 是一个很优秀的Java库,简单的几个注解,可以干掉一大片的模版代码。当我们使用的时候,要知其然,也要知其所以然,这样才能避免不必要的坑。
2024-01-11 11:32:49
1338
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人