- 博客(179)
- 收藏
- 关注
原创 spring boot 启动过程
一:new SpringApplication(primarySources): 即将我们传进来的class进行创建为springApplication。9.调用SpringApplicationRunListener的started()方法,发布ApplicationStartedEvent事件。10.调用SpringApplicationRunListener的ready()方法,发布ApplicationReadyEvent事件。在外面启动spring boot项目的时候,入口在如下方法中。
2025-11-02 11:40:52
395
1
原创 Kafka基础
首先:index和timeindex都是以相对偏移量的方式建立log消息日志的数据索引。比如说 0000.index和0550.index中记录的索引数字,都是从0开始的。kafka的基础工作机制是消息发送者可以将消息发送到kafka上指定的topic,而消息消费者,可以从指定的topic上消费消息。kafka都会以追加的方式写入到log日志文件中,kafka中的消息日志,只允许追加,不可以删除或者修改。是一个分布式的发布-订阅消息系统,可以快速的处理高吞吐量的数据流,并将数据实时的分发到多个消费者中。
2025-10-19 11:16:13
252
原创 并发特性理解
CPU高速缓存可以分为一级缓存,二级缓存,部分高端CPU还具有三级缓存,每一级缓存中所储存的全部数据都是下一级缓存的一部分,这三种缓存的技术难度和制造成本是相对递减的,所以其容量也是相对递增的。Java线程之间的通信由Java内存模型(Java Memory Model, 简称JMM)控制,JMM决定一个线程对共享变量的写入何时对另一个线程可见。在Java中,通过synchronized关键字保证原子性,也可以通过Lock锁或者CAS进行保证。程序执行的顺序是按照代码的先后顺序。1.多线程之间如何通信?
2025-10-12 11:48:50
156
原创 Fork/Join框架入门
ForkJoinPool 内部有多个任务队列,当我们通过 ForkJoinPool 的 invoke() 或者 submit() 方法提交任务时,ForkJoinPool 根据一定的路由规则把任务提交到一个任务队列中,如果任务在执行过程中会创建出子任务,那么子任务会提交到工作线程对应的任务队列中。当递归深度较大时,会产生大量的子任务,这些子任务可能被调度到不同的线程中执行,而线程的创建和销毁以及任务调度的开销都会占用大量的资源,从而导致性能下降。是一个并行计算的框架,主要就是用来支持分治任务模型的。
2025-10-12 11:26:29
282
原创 JUC包下的并发容器
LinkedBlockingQueue采用两把锁的锁分离技术实现入队出队互不阻塞,添加元素和获取元素都有独立的锁,也就是说LinkedBlockingQueue是读写分离的,读写操作可以并行执行。原理:利用高并发往往是读多写少的特性,对读操作不加锁,对写操作,先复制一份新的集合,在新的集合上面修改,然后将新集合赋值给旧的引用。主要场景是读多写少的。是有界阻塞队列,其内部是用数组存储元素的,初始化时需要制定容量大小,利用ReentrantLocak实现线程安全。并发容器是解决多线程情况下,可以处理的集合。
2025-10-02 19:53:52
325
原创 JUC并发同步工具类详解
Semaphore维护了一个计数器,线程可以通过调用acquire()方法来获取Semaphore中的许可证,当计数器为0时,调用acquire()的线程将被阻塞,直到有其他线程释放许可证;线程可以通过调用release()方法来释放Semaphore中的许可证,这会使Semaphore中的计数器增加,从而允许更多的线程访问共享资源。是一种用于多线程编程的同步工具,主要用于在一个时刻允许多个线程对共享资源进行操作的场景。
2025-09-27 15:31:43
244
原创 CAS理解
摘要: CAS(Compare And Swap)是一种基于硬件指令的非阻塞同步机制,通过比较内存值(V)、预期值(E)和新值(N)实现原子更新。其应用广泛,如JUC中的Atomic类、AQS及ConcurrentHashMap,用于解决高并发下的线程安全问题(如i++)。Atomic类提供基本类型、引用类型及数组的原子操作,而LongAdder通过分散热点(Cell数组)优化高并发场景。 缺陷: 自旋CAS可能导致CPU开销过大; 仅支持单一共享变量原子操作; 存在ABA问题(通过AtomicStampe
2025-09-14 22:27:37
317
原创 ThreadLocal理解
Spring会从数据库连接池中获得一个connection,然后会把connection放进ThreadLocal中,也就和线程绑定了,事务需要体检或回滚,只要从ThreadLocal中拿到connection进行操作。每个Thrad维护一个ThreadLocalMap,这个Map的key是ThreadLocal实例本身,value才是真正要存储的值Object。ThreadLocal类用来提供线程内部的局部变量,这种变量在多线程环境下访问时能保证哥哥线程的变量相对独立于其他线程内的变量。
2025-09-07 14:22:14
322
原创 MapStruct详解
MapStruct是编译期动态生成getter/setter,在运行期直接调用框架编译好的class类实现实体映射。其次速度快,运行期间直接调用实现类,不会在运行期间使用发射进行转换。先简单的回忆下BeanUtils,处理Java Bean之间的属性拷贝;source:指定源对象中的字段名,该字段的值将被映射到目标对象的字段中。当然,如果Dto和实体之间的名称不一样,可以通过指向固定的字段映射即可。target:指定目标对象中的字段名,该字段将接收源对象字段的值。MapStruct的使用。
2025-09-06 17:16:40
214
原创 Claude Code入门使用
Claude Code Router 是社区开源工具,允许你在无需 Anthropic 帐号的情况下,通过配置将 Claude Code 请求转发到其他 AI 模型/服务。以上一个简单的Claude Code的入门介绍到此,可以自己写代码,看到效果后,非常的感慨是AI是写的非常的不错。以上我们就安装完成了,可以进行让他用来做我们想做的事情了。由于本人是win系统,故介绍的是win系统下的安装过程。可以向我们平常使用的豆包,千亿通问等一样,很快有答案。上述配置肯定是无法直接使用的,需要使用自己的key。
2025-08-10 00:50:15
908
原创 Java代码,调用ES,搜索日志分析
在实际开发中,我们可能遇到各种场景。列如,日志中打印了某些信息,但是这些信息没有入库。而我们需要回退某些功能的时候,需要依赖这些日志。那么,如何将这些日志导出成excel,然后再处理我们想要处理的。第四步:解析我们请求的结果为JSON即可,里面就是我们想要的json格式代码,然后进行导出。第三步:那么就是设置我们模拟请求的cookie。第一步:我们需要远程调用es的接口模拟请求。第六步,将解析的json通过导出写出即可完成了。第二步:封装模拟一个请求,请求我们的Es服务。第五步:引入导出依赖。
2025-08-09 14:09:38
266
原创 MySQL架构全面理解
这篇摘要介绍了MySQL查询和更新语句的执行过程。查询过程包括连接器建立连接、查询缓存、分析器解析SQL、优化器选择执行方案和执行器执行语句。更新语句则涉及重做日志(redo log)和归档日志(binlog)两个关键模块,redo log用于即时记录更新操作,而binlog用于数据恢复。文章通过图示和代码示例,展示了从SQL语句输入到结果返回的完整流程,重点解析了MySQL内部各组件的工作原理和协作方式。
2025-08-03 19:10:29
280
原创 MySQL锁机制与MVCC原理剖析
摘要:本文介绍了MySQL中的锁机制和MVCC实现原理。MySQL包含表锁、行锁等粒度锁,以及读/写锁、乐观/悲观锁等类型。重点讲解了间隙锁在解决不可重复读和幻读问题中的作用。MVCC通过undo日志版本链和read-view机制实现事务隔离,详细分析了可重复读和读已提交隔离级别下read-view的生成规则及数据可见性判断流程,并通过示例说明了不同隔离级别下的查询结果差异。MVCC机制避免了频繁加锁,提高了并发性能。
2025-07-27 17:47:30
443
原创 MySQL事务原理
摘要:MySQL事务的ACID特性通过undo log、锁机制和redo log实现。并发事务可能引发脏写、脏读、不可重复读和幻读问题,默认隔离级别为可重复读。大事务会导致连接池耗尽、锁冲突、主从延迟等问题。优化建议包括:事务外处理查询、拆分大数据操作、延迟加锁操作以及采用异步处理。关键措施是减少事务范围和持续时间,提升系统并发性能。
2025-07-26 18:38:22
224
原创 RabbitMQ详解
基于Raft一致性协议实现的一种新型的分布式消息队列,他实现了持久化,多备份的FIFO队列。Durability有两个选项,Durable和Transient,前者表示队列会将消息保存到硬盘,这样消息的安全性更高。务处理后自动进行应答,而如果消费者的业务逻辑抛出异常,RabbitMQ会将消息进行重试,这样是不会丢。会尽可能早的将消息内容保持到硬盘中,并且只有在用户请求的时候,才临时从硬盘加载到RAM内存中。这时,可以尽量多的申请机器,部署消费端应用,争取在最短的时间内消费掉积压的消息。
2025-05-19 00:33:32
832
原创 RabbitMQ概念详解
消息发送到RabbitMQ中后,会首先进入一个交换机,然后由交换机负责将数据转发到不同的队列中。RabbitMQ中有多种不同类型的交换机来支持不同的路由策略。也可以理解为是客户端与RabbitMQ实际进行数据交互的通道,我们后续的大多数的数据操作都是在信道 Channel 这个层面展开的。Exchange与Queue之间会建立一种绑定的关系,通过绑定关系,Exchange交换机里发送的消息就可以分发到不同的Queue上。从官网的封面就能看到,现在RabbitMQ主推的是Quorum队列。
2025-05-11 14:46:23
660
原创 JVM对象创建内存分配
大量的对象被分配在eden区,满了后触发minor gc;垃圾回收后,剩余少量存活的被挪到survivor区,下一次eden区满了后,再次触发minor gc, 把eden区和survivor区垃圾对象回收,把剩余存活的对象一次性挪到另一块空的survivor区。运行8秒,即可占满eden区,即每8秒有100M到老年代,触发Full Gc;修改:将年轻代调大翻倍,此时运行第16秒后,移动到survivor区,下次minor gc,少量的移动到老年代;假设分配为3G的,年轻代和老年代为1G和2G;
2025-05-10 16:55:57
407
原创 spring Ai---向量知识库(二)
可按页进行分割,使用嵌入模型将文本转为向量表示;存储到数据库中(redis、es);用户提出问题,生成问题对应的向量;调用api的向量检索,找到相关文档;RAG:检索增强,结合了检索和生成两种技术;用于提升生成模型的效果。在此类问题中,需要先处理的是进行文档PDF的存入向量中;通过垂直场景,通过实时更新知识库,无需重新训练模型;即可实现通过文档,输入垂直问题获得向量对应的答案。后续直接调用spring ai的接口。第一步:配置RAG Advisor。保存到本地磁盘中demo。
2025-04-21 00:23:08
292
原创 spring Ai---向量知识库(一)
在一些垂直领域以及公司内部信息相关或者实时性相关的大模型应用,就无法直接使用chatGPT。向量模型定义:将文档向量化,保证内容越相似的文本,在向量空间中距离越近;以上就实现了一个简单的自带存储PDF,然后进行向量接口搜索的demo。我们需要先将文档转为Document,存入向量库。通过坐标向量最接近的即为匹配相关答案。存储文档的可以用redis, es等;测试输入一段文本,被存储在里面的坐标。对于API调用层,都是如下的调用方法。这个时候,向量知识库就进入了。最后通过调用接口搜索。
2025-04-19 22:53:51
1126
原创 springAi---智能客服
在需求分析阶段,把功能属于传统Java处理的和ai的功能进行分离。spring Ai 大模型应用相关开发demo,智能客服系统;首先被取代的是客服类,智能客服机器人都能够高效地完成任务。在ChatClient中,配置defaultTools。函数定义好后,交给spring ai由他们处理即可。业务代码等逻辑,通过CourseTool 实现即可。在大模型中,通过Function定义来实现。第二步:定义Tool,即Function。以上就完成了简单的智能客服。第三步,配置Tool。
2025-04-19 15:11:22
439
原创 SpringAi 会话记忆功能
即会话id,每次会话的时候,通过前端区分这个会话id。属于比较粗暴的方式,把之前的内容与新的提示词一起再次发给大模型。让我们看到他们有记忆功能。在使用chatGPT,豆包等产品后,就会发现他们的会话有“记忆”功能。下面介绍deepseek通过spring ai接入的时候实现记忆功能。以上是springAi中通过内存的实现方式实现如下接口。那么我们用API接口的话,这个是怎么实现的呢?二:配置会话记忆Advisor。上述方式即实现了会话记忆方案。一:定义会话存储方式。
2025-04-13 23:54:41
834
原创 springAi接入本地部署deepseek
上一篇本地简单的部署了deepseek后,通过spring推出的spring ai进行代码实现一个快速入门。2.2注入ollamaChatModel。2.3简单的通过rest接口进行输出文本。勾选一下web spring AI。构建一个新的spring ai项目。2.4通过流试方式输出文本。
2025-04-13 10:13:54
415
1
原创 本地部署大模型(ollama模式)
下载完成ollama后,进行运行deepseek模型。案例以deepseek-r1 为模型。在ollama会给出运行模型的命令。分享记录一下本地部署大模型步骤。至此,就可以本地模型进行聊天了。进入官网,下载ollama。
2025-04-12 23:15:15
468
原创 微服务API网关---APISIX
为客户端与服务系统之间的交互提供统一的接口,也是管理请求和响应的中心点,选择一个合适的API网关,可以有效地简化开发并提高系统的运维与管理效率。API网关作为一个系统访问的切面,对外提供统一的入口访问,隐藏系统架构实现的细节,让微服务使用更为友好;并集成了通用特性,鉴权,限流,熔断,避免每个微服务单独开发,提升效率,使系统更加标准化,单独注重业务。随着业务发展,API的数量也在剧增,使用网关对API统一管理也将面临挑战,选择一个更强大的API网关,可以有效的增强系统的监控、容灾、鉴权和限流等能力。
2024-02-28 15:19:46
1169
1
原创 ConcurrentHashMap源码解析(二)之------put()方法。
当sizeCtl < 0 ,大概率为-1,其他线程正在进行创建table的过程,当前线程没有竞争到初始化table的锁。p是红黑树,如果与你插入节点的key有冲突点的话,则putTreeVal()方法会返回冲突节点的引用。再次判断table为null,防止其他线程已经初始化完毕,然后当前线程再次初始化,导致数据丢失。强制设置binCount为2,因为binCount
2023-01-15 11:55:31
1106
原创 ConcurrentHashMap源码解析(一)之------基础属性
HashMap在单线程中非常好用,也不会出现什么问题。但是在多线程中,HashTable的效率太低。后面提供了ConcurrentHashMap解决多线程的问题,后续都以1.8的为对象进行研究。在1.8中,ConcurrentHashMap的设计与HashMap保持一致,使用了链表和红黑树的组合,当一个链表上的节点数超过8,且总个数超过64,就会触发转为红黑树。
2023-01-08 14:06:00
522
原创 线程池的设计与原理解析(五)之---getTask()方法
1.rs >= SHUTDOWN 成立: 当前的状态最低也是STOP状态,一定要返回 null了。4.线程池中的线程数超过 corePoolSize 时,会有一部分线程可能返回null。getTask()是工作线程在while死循环中获取任务队列中的任务对象的方法;2.前置条件 状态是 SHUTDOWN, workQueue.isEmpty()3.线程池中的线程数量,超过最大限制时,会有一部分线程返回null。1.表示当前线程获取任务是否超时;什么情况下getTask()返回null?
2022-12-17 14:40:47
1070
1
原创 线程池的设计与原理解析(四)之---runWorker()方法
2.如果task为空,则通过getTask()再去取任务,并赋值给task,如果取到的Runnable不为空,则执行该任务;在调用start()方法,调用的就是worker的run方法,实际上调用的是runWorker()方法。4.如果getTask()取到的任务依然是空,那么整个runWorker()方法执行完毕;3.执行完毕后,通过while循环继续getTask()取任务。1.如果task不为空,则开始执行task方法。1.将初始执行task赋值给task。简单的梳理runWorker的流程。
2022-12-17 14:09:47
1074
1
原创 spring bean生命周期四---Initialization阶段
使用场景:实现SmartInitializingSingleton的接口后,当所有单例 bean 都初始化完成以后, Spring的IOC容器会回调该接口的 afterSingletonsInstantiated()方法。主要是回调:SmartInitializingSingleton#afterSingletonsInstantiated。Spring Bean 初始化完成阶段。Spring Bean 初始化后阶段。属性填充后,就是初始化值。
2022-11-20 22:38:31
235
原创 spring bean生命周期三---PopulateBean阶段
postProcessAfterInstantiation()方法,可以决定是否进行属性填充,只要有一个返回了false,都会终止属性填充的过程。自动装配:autowiring自动装配,根据ByName或者ByType。提取依赖的bean,并统一存入到 propertyValues 中。filterPropertyDescriptorsForDependencyCheck()方法。@Autowired 和 @Resource 的注入工作主要是通过。实例化Bean之后,就是对Bean的属性进行注入的过程。
2022-11-20 22:00:10
278
原创 Spring之Bean生命周期之二--- Instantiation阶段
Spring Bean 实例化前阶段、Spring Bean 实例化阶段、Spring Bean 实例化后阶段等阶段。第二次调用后置处理器determineCandidateConstructors获取最优构造方法实例化对象。有参创建 :推断处理的 构造器方法不为null或者开启自动装配或者 使用指定入参的构造方法。第四次调用后置处理器getEarlyBeanReference解决循环依赖的问题。在BeanFactory中,主要的流程就是创建Bean的过程,实例化Bean在源码中。
2022-11-20 21:40:50
600
1
原创 FutureTask详解
FutureTask 表示一个异步运算的任务。FutureTask 里面可以传入一个 Callable 的具体实现类,可以对这个异步运算的任务的结果进行等待获取、判断是否已经完成、取消任务等操作。在学习多线程的时候,了解了FutureTask。FutureTask的构造函数。
2022-11-19 15:26:30
423
原创 Spring之Bean生命周期之一----BeanDefinition生成阶段
三个条件表达的意思是: mbd 中如果nonPublicAccessAllowed字段的值为true,表示class是非公开类型的,也可以创建实列。在Spring源码中,从AbstractAutowireCapableBeanFactory类的 createBean()方法开始。在doCreateBean()方法中,有一个createBeanInstantce方法,该方法即为将bean实例化;在该方法中,具体创建Bean的是doCreateBean()方法。条件3: 说明配置了 构造参数信息。
2022-11-13 21:41:49
571
原创 Order By 多条件排序【MySQL】
mysql 多字段排序,原来是需要逗号隔开,进行描写条件。之前都以为是作为一个,直接逗号一起就行;根据两个条件进行排序查询,开始以为很简单的写了SQL。以为结束了,仔细才发现,后续的没有根据id 进行排序。碰到一个SQL的排序问题,先排序后分页。最终将SQL修改为如下: 完成了该功能。开始就很简单的写了根据多条件的排序。记录一下这个小知识点。
2022-10-29 12:53:36
2212
原创 使用RabbitMQ常见问题
基于MQ的事件驱动机制,给庞大的互联网应用带来了不一样的方向。MQ的异步、解耦、削峰三大功能特点在很多业务场景下都能带来极大的性能提升,在日常工作过程中,应该尝试总结这些设计的思想。
2022-10-23 23:51:02
1232
原创 RabbitMQ入门
MQ:MessageQueue,消息队列;MQ的作用主要有以下三个方面:异步: 能提供系统的响应速度,吞吐量。解耦:服务之间进行解耦,才可以减少服务之间的影响。削峰:以稳定的系统资源应对突发的流量冲击。常用的MQ有:RabbitMQ,RocketMQ,Kafka等;接下来主要学习RabbitMQ;
2022-10-23 14:20:52
796
原创 Nacos源码学习(一)
onPut(key, value):其中的value就算Instances,要更新的服务信息。基于线程池的方式,异步的将service信息写入注册表中。key:是nameSpace的id,起到隔离环境的作用。Nacos提供了服务注册的API接口,客户端只需要向该接口发送请求,即可实现服务注册。2)然后将更新后的数据封装到Instances对象中,后面更新到注册表使用。3)调用put方法完成Nacos集群的数据同步,保证集群一致性。该方法对修改服务列表的动作加了sync,确保线程安全。
2022-09-04 22:00:37
886
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅