- 博客(172)
- 资源 (2)
- 收藏
- 关注
原创 Spring Boot 3 为何移除spring.factories?
SpringBoot3移除spring.factories文件引发开发者关注。这一重大变革主要源于五大原因:1)与GraalVM原生镜像支持冲突;2)启动性能瓶颈;3)Java模块化系统支持不足;4)配置灵活性缺陷;5)维护成本高。新机制采用AutoConfiguration.imports文件替代,具有类型安全、模块化友好、性能提升等优势。开发者需将配置迁移至META-INF/spring目录下的.imports文件,并注意类路径正确性和条件注解使用。这一变革是技术演进的必然选择,为SpringBoot拥
2025-11-27 16:58:58
420
原创 Spring 启动缓存预热:5 种方案深度对比与落地指南
摘要:本文深入解析Spring生态中5种主流缓存预热方案,包括生命周期监听器、CommandLineRunner、定时任务、缓存加载器和分布式预热。通过对比各方案的实现原理、代码示例及优缺点,帮助开发者根据数据量、分布式架构等场景选择最优解。文章强调异步执行、分批加载和分布式锁等优化手段,并给出缓存防护机制建议,最终提出"不影响启动与一致性的高效加载"的预热核心原则,为系统性能优化提供实践指导。
2025-11-27 16:58:18
254
原创 Spring 三级缓存深度解析:循环依赖与 AOP 代理的完美平衡
摘要:Spring框架通过三级缓存机制巧妙解决循环依赖与AOP代理创建的矛盾。在传统场景下,AOP代理在Bean完全初始化后创建;但循环依赖要求提前暴露对象。三级缓存(singletonObjects、earlySingletonObjects、singletonFactories)通过延迟代理创建时机实现平衡:当检测到循环依赖时,通过ObjectFactory动态决定返回原始对象或代理对象,确保注入正确的代理实例。这种设计既满足循环依赖需求,又保持AOP代理的创建原则,体现了Spring框架的精妙架构。
2025-11-27 16:57:36
508
原创 BeanFactory和FactroyBean的关系?
本文摘要: Spring框架中的BeanFactory和FactoryBean都是org.springframework.beans.factory包下的接口,但功能不同。BeanFactory是IoC容器核心接口,负责管理Bean生命周期和依赖注入,采用延迟初始化策略。FactoryBean是特殊Bean,通过实现getObject()方法封装复杂对象的创建逻辑。关键区别在于:BeanFactory是容器管理者,FactoryBean是Bean创建工具。BeanFactory管理所有Bean(包括Fact
2025-11-27 16:56:18
242
原创 AQS-AbstractQueuedSynchronizer
AQS(AbstractQueuedSynchronizer)是Java并发编程中的核心同步框架,为ReentrantLock、CountDownLatch等同步器提供基础实现。其核心包含一个volatile的state变量(通过CAS修改)和一个FIFO双向队列(Node节点构成),分别用于控制同步状态和管理线程排队。AQS支持排他锁(如ReentrantLock)和共享锁(如Semaphore)两种模式。同步辅助类CountDownLatch、CyclicBarrier和Semaphore虽然都基于AQ
2025-11-24 11:14:45
875
原创 TCP 为什么要三次握手和四次挥手?
TCP连接的建立需要"三次握手",通过SYN和ACK数据包的交换,确保双方收发功能正常;断开连接则需"四次挥手",采用FIN和ACK数据包完成双向关闭。三次握手确认通信可靠性,四次挥手则保证全双工连接的安全终止,其中客户端等待2MSL时间防止ACK丢失。这种机制有效维护了TCP连接的稳定性和可靠性。
2025-11-23 00:30:00
899
原创 什么是 JWT? 如何基于 JWT 进行身份验证?
JWT(JSON Web Token)是一种基于Token的无状态跨域认证方案,由Header、Payload和Signature三部分组成。Header定义算法和类型,Payload包含用户数据,Signature用于防篡改。JWT通过签名验证确保数据完整性,无需服务端存储Session,适合RESTful API。使用时建议将Token存于localStorage而非Cookie,避免CSRF风险,并设置合理过期时间。密钥安全是核心,需严格保护。JWT提升了系统扩展性,但需注意敏感数据不应存于Paylo
2025-11-23 00:15:00
662
原创 JVM故障处理工具
本文介绍了Java虚拟机(JVM)监控与诊断工具集,包括jps、jcmd、jstat、jmap、jhat和jstack等常用命令。这些工具可用于查看JVM进程状态、收集运行数据、生成堆转储快照和分析线程堆栈等。主要内容包括: jps命令:列出正在运行的JVM进程信息,支持-q、-l、-m、-v等参数选项,用于查看进程ID、主类全名、启动参数等。 jcmd命令:提供详细的JVM诊断功能,可查看启动参数、运行时长、线程堆栈、系统属性等,并支持导出堆转储文件。 jstat命令:监视类加载、内存使用、垃圾回收等运行
2025-11-22 00:30:00
1930
原创 四种线程池使用介绍
摘要:Executors提供了四种典型线程池:newFixedThreadPool(固定大小)、newSingleThreadExecutor(单线程)、newCachedThreadPool(缓存线程)和newScheduledThreadPool(定时线程)。这些线程池各有特点,适用于不同业务场景,但也存在共同风险——均使用无界队列或极大线程数上限,可能导致任务无限堆积引发OOM。其中newScheduledThreadPool支持定时/延迟任务执行,提供scheduleAtFixedRate等方法,但
2025-11-22 00:15:00
200
原创 五种类代理的方式
摘要:本文介绍了五种Java代理实现方式:1)JDK代理(基于接口,简单常用);2)CGLIB代理(基于ASM字节码,性能高1.5-2倍);3)ASM代理(直接操作字节码指令,性能最优);4)Byte-Buddy代理(API简单,获Oracle大奖);5)Javassist代理(平衡安全与功能)。这些代理技术广泛用于中间件开发、AOP、监控等领域,选择时需权衡实现复杂度与性能需求。深入理解代理机制有助于突破技术瓶颈,提升开发能力。
2025-11-21 00:30:00
630
原创 HashMap源码分析
摘要:HashMap通过扰动函数优化哈希分布,将key的哈希值高16位与低16位异或,增加随机性以减少碰撞。扩容时采用2的幂次方容量,通过位运算计算新容量。当链表长度超过8且桶容量大于64时转为红黑树,提升查询效率。插入、查找和删除操作均通过哈希定位到桶,再根据节点类型(链表/红黑树)进行相应处理。扩容时元素重新散列,通过哈希值与旧容量按位与运算判断新位置,优化迁移效率。
2025-11-21 00:15:00
834
原创 算术移位 、逻辑移位
本文介绍了Java中的位运算操作,分为算术移位和逻辑移位两类。算术移位包括带符号的左右移位(>>和<<),会保持符号位不变;逻辑移位(>>>)则不考虑符号位,右移时高位补零。文章详细解析了移位运算规则及其等效数学运算,并提供了代码示例。同时介绍了四种基本位运算(与、或、非、异或)的原理和应用场景,包括使用异或交换变量值的技巧。此外,文章还讲解了补码表示法、数字正负转换、奇偶和幂值判断等实用案例,最后给出若干优化建议,如用移位替代乘除运算可提高效率。
2025-11-20 00:30:00
862
原创 图 Graph
摘要:本文介绍了图论的发展历程及图数据结构的基本概念与实现方式。从欧拉开创性论文到拓扑学发展,阐述了图论的历史背景。重点讲解了图的分类(无向/有向、有权/无权)和三种实现方法:邻接矩阵(数组)、邻接表(链表)和红黑树实现。详细说明了不同图结构下的元素插入方式,并比较了广度优先遍历(BFS)和深度优先遍历(DFS)算法的特点和实现代码。文章通过具体代码示例展示了图的存储结构及遍历方法在不同类型图中的运用。
2025-11-20 00:15:00
933
原创 平衡二叉树 AVL Tree
AVL树是一种自平衡二叉搜索树,由Adelson-Velsky和Landis在1962年提出,解决了普通BST在顺序插入时退化为链表的问题。其核心是通过旋转操作(左旋、右旋及组合旋转)来维持树的平衡,确保左右子树高度差不超过1。旋转操作类似于调整方向盘,当树高差过大时自动进行修正。AVL树节点包含高度或平衡因子属性,通过四种旋转情形(左旋、右旋、左旋+右旋、右旋+左旋)实现动态平衡。详细代码实现展示了如何通过调整节点关系来完成旋转,最终保持O(log n)的查询效率。这种数据结构在需要高效查找的场景中具有重
2025-11-19 00:30:00
1769
原创 二分搜索树 Binary Search Tree
本文介绍了二叉搜索树(BST)的基本原理及其实现。BST是一种二叉树数据结构,左子树节点值小于根节点,右子树节点值大于根节点。文章回顾了BST的发展历史,并详细阐述了BST的插入、查找和删除操作的具体实现方法。其中,删除操作根据节点子节点数量分三种情况处理:无子节点、单子节点和双子节点。对于双子节点情况,需先找到右子树中的最小节点进行替换。本文还指出BST存在退化为链表的风险,时间复杂度可能从O(logn)恶化到O(n)。BST是构建更复杂平衡树(如AVL树、红黑树)的基础数据结构。
2025-11-19 00:15:00
976
原创 字典树 Trie
摘要:字典树(Trie)是一种高效存储和检索字符串的数据结构,核心通过前缀共享节省空间。本文介绍了字典树的历史背景及数据结构原理,详细阐述了其Java实现方法,包括节点设计、插入元素和前缀检索功能。通过测试案例验证了字典树能快速检索所有指定前缀的单词,适用于海量词汇的存储和查询。字典树的时间复杂度为O(n),在索引长度限制下具有较高查询效率。
2025-11-18 00:30:00
607
原创 堆栈(栈)Stack
本文介绍了堆栈数据结构的特点和实现方式,重点分析了Java中ArrayDeque的源码实现。堆栈是一种LIFO(后进先出)的数据结构,其核心操作包括push(压栈)和pop(弹出)。文章指出应使用ArrayDeque而非Java原生的Stack类来实现堆栈功能。详细解析了ArrayDeque的内部机制:使用循环数组存储元素,通过位运算高效计算索引位置;当数组空间不足时,进行2倍扩容并分两次复制元素;压栈和弹出操作都遵循LIFO原则,通过head指针管理栈顶位置。源码分析包括addFirst(压栈)、doub
2025-11-18 00:15:00
1100
原创 Spring Boot 多数据源切换实战:基于 dynamic-datasource 的优雅实现
本文介绍了基于dynamic-datasource-spring-boot-starter实现多数据源动态切换的完整方案。通过注解驱动的数据源配置,可以轻松应对订单库与用户库分离等业务场景。文章详细讲解了环境准备、核心配置、代码实现等关键环节,重点解决了事务内数据源切换、自调用AOP失效等常见问题,为开发者提供了开箱即用的多数据源管理方案。该方案在保持开发效率的同时,兼具良好的灵活性和扩展性。
2025-11-17 17:45:30
1554
原创 单元测试-模拟框架Mockito
Mockito是一个Java测试框架,用于单元测试中模拟对象行为。它具有三大核心功能:1)创建mock对象隔离外部依赖;2)通过stubbing预设方法返回值;3)验证方法调用情况。Mockito支持部分模拟(Partial Mocks)、参数匹配(ArgumentMatchers)和回调机制(thenAnswer/doAnswer),能灵活处理各种测试场景。集成时只需添加Spring Boot Test依赖即可,提供times()、any()等多种测试验证方法,帮助开发者编写高效、隔离的单元测试。
2025-11-17 17:37:32
516
原创 SocketTimeoutException问题延伸
Java应用出现连接超时问题的原因分析及解决方案建议。系统频繁创建TCP连接会导致资源耗尽、TIME_WAIT状态堆积等问题,引发SocketTimeoutException。分析表明,连接未复用、系统资源限制、TCP协议特性是主要原因。推荐使用OkHttpClient或ApacheHttpClient等支持连接池的HTTP客户端库,避免直接使用HttpURLConnection。OkHttpClient因其高性能、连接池支持和简洁API成为首选方案,而RestTemplate已逐渐过时。合理选择HTTP客
2025-11-17 17:36:35
1075
原创 如何基于Redis实现分布式锁?
摘要:Redis实现简易分布式锁的核心是互斥机制,可通过SETNX命令实现。基本步骤包括:1)使用SETNX获取锁;2)通过唯一值避免误删;3)用Lua脚本保证原子性释放。改进方案包括:设置锁过期时间防止死锁,使用Redisson实现自动续期(看门狗机制)。对于集群环境,Redlock算法可提高可靠性,但实现复杂。实际应用中,单机Redis锁通常已能满足需求,若需更高可靠性可考虑ZooKeeper。
2025-07-16 15:27:53
745
原创 Spring boot中利用WebAsyncTask实现异步任务编程
本文介绍了Servlet 3.0引入的异步请求处理特性及其在SpringBoot中的实现方式。重点阐述了WebAsyncTask的使用方法,包括超时回调、错误处理和完成回调等功能,并提供了线程池配置示例。与@Async注解相比,WebAsyncTask提供了更细粒度的超时控制和回调机制,适合需要精确控制异步任务生命周期的场景。文章通过代码示例展示了如何创建WebAsyncTask异步任务并配置独立的线程池来处理不同优先级的任务。
2025-07-16 15:27:13
215
原创 分布式事务方案
分布式事务的实现方式主要包括XA协议的二阶提交(2PC)、三阶提交(3PC)和TCC补偿性事务。XA协议由X/Open组织提出,规范了事务管理器(TM)与资源管理器(RM)之间的通信,确保事务的ACID特性。2PC通过准备和提交两个阶段实现事务,但存在阻塞和数据不一致的问题。3PC在2PC基础上增加预处理阶段和超时机制,以减少阻塞,但仍无法完全解决网络故障导致的数据不一致。TCC通过Try、Confirm、Cancel三个阶段实现最终一致性,适用于微服务架构,但对业务侵入性大。Seata是阿里开源的分布式事
2025-05-20 16:47:08
584
原创 深入了解Synchronized同步锁的优化
在并发编程中,Java通过Synchronized关键字和Lock接口实现线程同步,确保共享资源的原子性。Synchronized是JVM内置锁,而Lock需要显式管理锁的获取和释放。JDK1.5之前,Synchronized因依赖操作系统MutexLock导致性能开销大,尤其在锁竞争激烈时表现不佳。JDK1.6对Synchronized进行了优化,引入了偏向锁、轻量级锁和重量级锁等概念,通过锁升级机制减少上下文切换,提升性能。此外,JIT编译器通过逃逸分析和锁粗化技术进一步优化锁的使用。减小锁粒度,如Co
2025-05-20 16:46:21
992
原创 事务消息实现分布式事务
在电商系统中,用户下单后,订单系统需要通知购物车系统删除已购商品,这一过程通常通过消息队列实现,以确保数据一致性。分布式事务在此场景中至关重要,它确保订单创建和购物车清理要么都成功,要么都失败,避免数据不一致。分布式事务的实现通常遵循ACID原则,包括原子性、一致性、隔离性和持久性。常见的分布式事务实现方法有2PC、TCC和事务消息。事务消息适用于异步更新数据且对实时性要求不高的场景。消息队列如Kafka和RocketMQ提供了事务相关功能,通过事务消息机制实现分布式事务。例如,订单系统在创建订单后发送“半
2025-05-20 16:45:27
1210
原创 队列消息模型
消息队列产品通常采用两种主要模型:队列模型和发布-订阅模型。队列模型遵循先进先出原则,适用于单一消费者场景,而发布-订阅模型允许多个消费者接收同一消息,适用于需要消息广播的场景。RabbitMQ主要使用队列模型,通过Exchange实现消息分发。RocketMQ和Kafka则采用发布-订阅模型,其中RocketMQ通过队列实现消息的有序性和并行消费,Kafka则使用分区(Partition)实现类似功能。两种模型各有优势,选择哪种模型取决于具体应用场景和需求。
2025-05-20 16:44:25
824
原创 消息队列概述
消息队列适合解决异步处理、流量控制和服务解耦等问题。异步处理能提升系统性能,流量控制可调节系统负载,服务解耦则增强系统灵活性。选择消息队列时,应考虑开源、社区活跃度、消息可靠传递、集群支持和性能等因素。常见的消息队列产品包括RabbitMQ、RocketMQ和Kafka。RabbitMQ以轻量级和灵活路由著称,但处理大量消息时性能下降;RocketMQ由阿里巴巴开发,性能高,易于扩展;Kafka最初用于日志处理,现已发展为功能全面的消息队列,兼容性极佳。每种产品各有特点,应根据具体需求选择。
2025-05-20 16:43:33
446
原创 经典排序算法
它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。它的工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。1959年Shell发明,第一个突破O(n2)的排序算法,是简单插入排序的改进版。
2025-05-07 15:11:37
1145
原创 爬楼梯-递归版
原始递归解法:O(2^n) 时间,O(n) 空间(调用栈)记忆化递归:O(n) 时间,O(n) 空间迭代解法:O(n) 时间,O(n) 空间空间优化迭代:O(n) 时间,O(1) 空间最优选择是空间优化迭代解法,它同时具有最佳的时间和空间复杂度。
2025-04-30 16:01:28
264
原创 搭建基于Kafka的企业级实时日志流处理平台
它是一行 Nginx 日志,只不过 Connect 组件在读取它后,会把它包装成 JSON 格式发送到 Kafka,因此,我们需要借助 Gson 来帮助我们把 JSON 串还原为 Java 对象,这就是我在代码中创建 LogLine 类的原因。从图中我们可以看到,日志先从 Web 服务器被不断地生产出来,随后被实时送入到 Kafka Connect 组件,Kafka Connect 组件对日志进行处理后,将其灌入 Kafka 的某个主题上,接着发送到 Kafka Streams 组件,进行实时分析。
2025-04-30 01:00:00
1448
原创 Kafka副本机制详解
根据 Kafka 副本机制的定义,同一个分区下的所有副本保存有相同的消息序列,这些副本分散保存在不同的 Broker 上,从而能够对抗部分 Broker 宕机带来的数据不可用。在实际生产环境中,每台 Broker 都可能保存有各个主题下不同分区的不同副本,因此,单个 Broker 上存有成百上千个副本的现象是非常正常的。
2025-04-30 00:45:00
706
原创 16个SpringBoot 扩展接口
一般情况下,Spring通过反射机制利用bean的class属性指定支线类去实例化bean,在某些情况下,实例化Bean过程比较复杂,如果按照传统的方式,则需要在bean中提供大量的配置信息。使用场景:用户可以扩展这个类,来为要实例化的bean作一个代理,比如为该对象的所有的方法作一个拦截,在调用前后输出一行log,模仿。可以看到,该类用于执行各种驱动接口,在bean实例化之后,属性填充之后,通过执行以上红框标出的扩展接口,来获取对应容器的变量。这里重点是要关注下这个标准的触发点,这个触发点是在。
2025-04-30 00:15:00
1697
原创 消费者组消费进度监控
对于 Kafka 消费者来说,最重要的事情就是监控它们的消费进度了,或者说是监控它们消费的滞后程度。这个滞后程度有个专门的名称:消费者 Lag 或 Consumer Lag。。比方说,Kafka 生产者向某主题成功生产了 100 万条消息,你的消费者当前消费了 80 万条消息,那么我们就说你的消费者滞后了 20 万条消息,即 Lag 等于 20 万。通常来说,Lag 的单位是消息数,而且我们一般是在主题这个级别上讨论 Lag 的,但实际上,Kafka 监控 Lag 的层级是在分区上的。
2025-04-29 00:30:00
1217
原创 位移提交Committing Offsets
现在,我们假设提交位移之后的 3 秒发生了 Rebalance 操作。对于常规性、阶段性的手动提交,我们调用 commitAsync() 避免程序阻塞,而在 Consumer 要关闭前,我们调用 commitSync() 方法执行同步阻塞式的位移提交,以确保 Consumer 关闭前能够保存正确的位移数据。提交位移主要是为了表征 Consumer 的消费进度,这样当 Consumer 发生故障重启之后,就能够从 Kafka 中读取之前提交的位移值,然后从相应的位移处继续消费,从而避免整个消费过程重来一遍。
2025-04-29 00:15:00
1045
原创 位移主题consumer_offsets
自动提交位移有一个显著的优点,就是省事,你不用操心位移提交的事情,就能保证消息消费不会丢失。,用户不能修改,也就是说你不能随意地向这个主题写消息,因为一旦你写入的消息不满足 Kafka 规定的格式,那么 Kafka 内部无法成功解析,就会造成 Broker 的崩溃。但是,ZooKeeper 其实并不适用于这种高频的写操作,因此,Kafka 社区自 0.8.2.x 版本开始,就在酝酿修改这种设计,并最终在新版本 Consumer 中正式推出了全新的位移管理机制,自然也包括这个新的位移主题。
2025-04-28 10:49:54
1114
原创 消费者详解
发布 / 订阅模型倒是允许消息被多个 Consumer 消费,但它的问题也是伸缩性不高,因为每个订阅者都必须要订阅主题的所有分区。举个简单的例子,假设一个 Consumer Group 订阅了 3 个主题,分别是 A、B、C,它们的分区数依次是 1、2、3,那么通常情况下,为该 Group 设置 6 个 Consumer 实例是比较理想的情形,因为它能最大限度地实现高伸缩性。Consumer Group 订阅了多个主题后,组内的每个实例不要求一定要订阅主题的所有分区,它只会消费部分分区中的消息。
2025-04-28 10:49:18
319
原创 幂等生产者和事务生产者
在 0.11 之后,指定 Producer 幂等性的方法很简单,仅需要设置一个参数即可,即 props.put(“enable.idempotence”, ture),或props.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, true)。其次,它只能实现单会话上的幂等性,不能实现跨会话的幂等性。看上去,幂等性 Producer 的功能很酷,使用起来也很简单,仅仅设置一个参数就能保证消息不重复了,但实际上,我们必须要了解幂等性 Producer 的作用范围。
2025-04-28 10:48:42
623
原创 透视HTTP
看上去好像很多,但互联网的快速发展让地址的分配管理很快就“捉襟见肘”。因为IP协议定义了“IP地址”的概念,所以就可以在“链接层”的基础上,用IP地址取代MAC地址,把许许多多的局域网、广域网连接成一个虚拟的巨大网络,在这个网络里找设备时只要把IP地址再“翻译”成MAC地址就可以了。URI另一个更常用的表现形式是URL(Uniform Resource Locator),统一资源定位符,也就是我们俗称的“网址”,它实际上是URI的一个子集,不过因为这两者几乎是相同的,差异不大,所以通常不会做严格的区分。
2025-04-28 10:46:02
833
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅