自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(27)
  • 收藏
  • 关注

原创 AOP 核心知识整理

三、切入点表达式:execution vs @annotation方式匹配规则适用场景基于方法名匹配,支持通配符批量拦截某个包或某类方法基于注解匹配精确控制哪些方法需要拦截execution 表达式语法示例:通配符规则:项目中很多类可能没有实现接口,JDK 代理会直接失败。统一用 CGLIB 可以避免开发者因忘记写接口而导致 AOP 失效。如需切回 JDK 代理:五、Spring AOP vs AspectJ维度S

2026-06-27 20:56:26 397

原创 Spring 事务传播行为

事务传播行为定义了一个事务方法被另一个事务方法调用时,事务如何传播,即被调用方法是在调用方的事务中执行,还是新开事务,还是不用事务。Spring 共定义了 7 种传播行为,定义在 枚举中。REQUIRED(默认)SUPPORTSMANDATORYREQUIRES_NEWNOT_SUPPORTEDNEVERNESTED订单创建 → 库存扣减,两个操作必须在同一事务中,要么一起成功,要么一起回滚。2. REQUIRES_NEW(必须独立提交)不管主流程成败,日志必须写入。3. NESTED(部分失败可接

2026-06-27 20:18:57 254

原创 对Spring MVC 的理解

Spring MVC 是基于 Servlet 的 Web 框架,核心是前端控制器框架内部遵循 Model-View-Controller 三分,职责限定在 Web 层Service、DAO 属于 Spring 整体应用分层,不应直接归为“Spring MVC 的分层”事务控制在 Service 层是推荐实践前后端分离场景下,View 概念前移,Spring MVC 更侧重 API 化数据返回。

2026-06-27 19:50:39 929

原创 深入理解缓存一致性:为什么推荐「更新数据库 → 删除缓存」而不是延迟双删?

方案推荐指数一致性更新 DB → 更新缓存⭐容易覆盖删除缓存 → 更新 DB⭐⭐存在脏数据删除缓存 → 更新 DB → 延迟双删⭐⭐⭐⭐最终一致更新 DB → 删除缓存⭐⭐⭐⭐⭐主流方案更新 DB → 删除缓存 → 延迟双删⭐⭐⭐⭐⭐高一致性Canal + MQ 同步缓存⭐⭐⭐⭐⭐最佳实践。

2026-06-24 23:17:51 243

原创 深入理解分布式锁:ZooKeeper vs Redis vs etcd

维度一:生命周期持久节点(Persistent)— 客户端断开后,节点依然存在临时节点(Ephemeral) — 客户端断开后,节点自动删除 ← 锁用这个维度二:是否有序普通节点 — 名字就是你指定的,重复创建会报错顺序节点(Sequential)— ZK 自动在名字后面追加递增编号 ← 锁用这个两者结合就是临时顺序节点,比如你创建断开连接后自动删除,且编号全局递增,天然有序。Watch 就是一次性监听客户端 B 对 order0000000001 注册 Watch↓。

2026-04-30 14:31:54 1028

原创 Java 21 虚拟线程深度解析:它是协程吗?又为何需要载体线程?

Java 21 虚拟线程是披着线程外衣的有栈协程。它既不像传统线程那样昂贵,也不像异步框架那样需要改变编程范式。它通过M:N 调度让百万协程共享少量载体线程,在保持同步代码简洁性的同时,获得了异步化的高吞吐能力。下次再有人问“虚拟线程是协程吗?”,你可以回答:“是的,它是一个由 JVM 调度的、有栈的、协作式轻量级并发单元。而那些所谓的载体线程,正是它用来欺骗操作系统、高效利用 CPU 的秘密武器。这就是虚拟线程的优雅之处:让你用最自然的姿势,写出最高并发的代码。

2026-04-30 12:00:48 445

原创 JVM内存模型

理解JVM内存结构是进阶Java开发的必经之路。线程共享:堆、方法区(元空间)。线程私有:虚拟机栈、本地方法栈、程序计数器。调优重点:关注堆内存的分配和GC策略,避免内存溢出。

2026-03-31 22:18:47 302

原创 深入理解 HotSpot 虚拟机的垃圾回收器:从原理到选型

垃圾回收器的选择不是“越新越好”,而是“合适最重要理解每种 GC 的设计哲学(吞吐优先 vs 延迟优先)、内部机制和限制条件,才能在真实业务场景中做出最优决策。随着 ZGC 和 Shenandoah 的成熟,Java 正在迈向“无感 GC”的新时代——但在此之前,请先掌握 G1。📌记住:没有免费的午餐。低延迟往往以 CPU 开销为代价,高吞吐可能牺牲响应速度。权衡,是性能工程师的核心能力。

2026-03-31 00:17:17 407

原创 Spring 中的 BeanFactory:IoC 容器的基石

是 Spring 框架中IoC 容器的最基础接口根据名称或类型获取(getBean)已注册的 Bean 实例。它是整个 Spring 容器体系的起点,所有高级容器(如)都基于它构建。📌 日常开发中调用,其底层最终委托给的实现类执行。

2026-03-11 22:26:19 260

原创 什么是Spring IOC?

所谓控制反转,反转的是这个创建对象的控制权。依赖注入DI是IOC的实现方式,通过构造器注入、Setter注入或字段注入,把依赖对象传递进来。反转,其实就是关于创建对象且注入依赖对象的这个动作,反转之后,这个动作由IOC容器触发,IOC容器在创建对象A的时候,发现依赖对象B,根据配置文件,它会创建B,并将对象B注入A中。控制的是对象的创建,IOC容器根据配置文件创建对象,在对象的生命周期内,不同时期根据不同配置经行对象的创建和改造。BeanFactory:,基础IOC能力,启动快,资源受限环境。

2026-03-10 20:52:45 384

原创 HashMap 原理解析(JDK 8+)

如果数组太小,长链表很可能是由于容量不足导致的“伪冲突”,此时应优先扩容。只有在容量足够(≥64)仍出现长链表,才说明哈希分布确实不均,值得用红黑树优化。留出缓冲区间(6~8),避免在临界点因增删操作反复在链表与红黑树之间切换,造成不必要的开销。在极端情况下(如大量 key 哈希值相同或分布不均),链表可能变得很长,导致。为保障最坏情况下的性能,JDK 8 引入红黑树。是 Java 中最常用的 Map 实现之一,其底层基于。的插入、删除和查找性能,是非线程安全的键值对容器。:使用 IDE 自动生成。

2026-03-10 19:47:59 492

原创 Spring 如何解决循环依赖?

虽然 Bean 还未完成属性填充和初始化,但其内存地址已确定,可以先拿去被其他 Bean 引用,后续再完善自身。回到 A 的创建流程,拿到已初始化的 B,完成自身初始化,也放入一级缓存。B 拿到 A 的引用,完成属性注入和初始化,最终放入。,将“创建时依赖”转为“使用时依赖”。来消除循环依赖,而非依赖框架兜底。,得到原始实例(属性尚未注入)。如果直接把原始实例放入二级缓存,,并将其工厂放入三级缓存。Spring 开始创建。将一个能生成 A 的。,而非真实 Bean。📌 最佳实践:优先通过。

2026-03-09 15:25:46 413

原创 什么是循环依赖

同一个类里A方法调用B方法,B方法上的@Transaction不会生效,因为没有走代理。注入self后通过self.methodB()调用,就能走代理让事务生效。不过更优雅的做法是把B方法拆到另一个Service里。原型(Prototype)作用域的 Bean 无法解决循环依赖。循环依赖其实是两个或多个bean互相引用,形成一个闭环。,由 A、B 分别依赖它,打破 A ↔ B 的闭环。若存在循环依赖,应用启动将直接失败。官方观点:循环依赖通常是。,不应依赖框架“兜底”。💡 更优雅的做法:将。

2026-03-09 14:37:29 395

原创 MySQL 索引调优全攻略:从原理到实战

MySQL 调优不是一蹴而就的,而是一个**“监控 -> 分析 -> 实验 -> 验证”**的循环过程。工具对慢日志进行聚合分析,找出出现频率最高、耗时最长的 Top 10 SQL。MySQL 是基于**成本(Cost)**模型来选择执行计划的。不要盲目优化,先让数据说话。开启 MySQL 的。本文将深入拆解这三个步骤,并提供避坑指南。MySQL 优化器预估需要扫描的行数。,可以看到更真实的执行成本和实际行数。或 MySQL 8.0+ 的。:MySQL 5.7+ 支持。很大,说明索引区分度不高。

2026-03-08 18:04:58 399

原创 Redis 数据类型全景指南:从基础到高级

Redis 不仅仅是一个简单的 Key-Value 存储系统,其丰富的数据结构是支撑高性能业务场景的核心。本文将深入解析 Redis 的。,并结合生产环境中的最佳实践,探讨如何避免“大 Key”陷阱。虽然理论上限很高,但在生产环境中,注:旧版文档常误述为纯双向链表。是 Redis 性能杀手。

2026-03-05 23:36:29 351

原创 MySQL 并发控制详解:乐观锁 vs 悲观锁

时,InnoDB 不仅会锁住存在的记录,还会锁住记录之间的“间隙”,防止幻读。这在某些场景下可能导致意想不到的锁等待,需谨慎使用。在数据库高并发场景下,如何保证数据的一致性是一个核心问题。直接利用数据库的条件判断来实现原子操作,无需额外的 version 字段,适用于特定数值场景。它们的本质区别在于对“冲突发生概率”的预期不同。在 MySQL (InnoDB 引擎) 中,悲观锁主要通过。如果返回受影响行数为 0,说明库存已变,操作失败。这是一个极其重要的性能考点。FOR UPDATE。

2026-03-05 22:50:08 487

原创 MySQL 深入解析:二级索引与 MVCC 的交互机制

为了保证 MVCC 的正确性,当二级索引列发生变更时,InnoDB 选择保留旧记录(标记删除)并插入新记录,从而在逻辑上保留了“历史状态”,直到事务提交且无其他事务需要该版本时,再由后台线程清理。(Covering Index)查询,只要当前事务需要判断版本可见性(即存在未提交的并发事务影响了相关数据),优化器也可能放弃使用覆盖索引,强制回表以获取正确的版本信息。当查询通过二级索引定位到记录后,若涉及版本可见性判断(即非一致性读,或当前事务启动后有并发写),InnoDB。虽然二级索引的记录行上没有。

2026-03-04 23:58:54 450

原创 MySQL 事务隔离级别详解:从原理到实战

隔离级别脏读不可重复读幻读 (当前读)并发性能推荐指数读未提交✅✅✅⭐⭐⭐⭐⭐❌ 不推荐读已提交 (RC)❌✅✅⭐⭐⭐⭐⭐⭐⭐ (适合高并发插入)可重复读 (RR)❌❌❌ (InnoDB 优化)⭐⭐⭐⭐⭐⭐⭐⭐ (MySQL 默认)串行化❌❌❌⭐❌ 特殊场景。

2026-03-03 22:11:40 484

原创 深入理解 MySQL 事务:从 ACID 到四大核心组件

虽然 MVCC 解决了大部分读写冲突,但在写 - 写冲突或特定隔离级别下,仍需锁机制介入。Redo Log:目的是崩溃恢复。只要数据页刷盘了,对应的日志就没用了。固定大小循环写可以避免磁盘无限增长,且保证顺序写性能。Binlog:目的是主从复制和时间点恢复(PITR)。历史记录不能丢,必须完整保留所有操作序列,因此只能追加写。

2026-03-03 00:05:48 979

原创 MySQL 索引全景指南:从原理到实战

三个维度,深度解析 MySQL(以 InnoDB 引擎为主)的索引体系,并揭示那些容易被忽视的底层细节。索引是数据库性能的“加速器”,但用不好也会变成“绊脚石”。这是 InnoDB 引擎特有的概念,决定了“回表”的发生。很多开发者在建表时忘记设主键,InnoDB 会生成隐藏的。的条件需要 Server 层判断。MySQL 索引是一把双刃剑。主键必建有顺序,联合索引看最左。模糊查询忌百分,覆盖索引少回表。区分太低别建指,隐式转换是大坑。原则则是进阶优化的关键。这是决定查询效率的核心。的条件,减少回表次数。

2026-03-02 01:16:10 604

原创 MySQL中一条SQL语句的执行流程详解

理解SQL在MySQL中的执行流程是掌握数据库管理和优化的基础。通过对连接、分析、优化、执行各环节的理解,以及对相关技术细节的认识,可以更有效地解决实际工作中的问题,提升数据库应用的整体性能。了解一条SQL语句在MySQL中的执行过程有助于优化查询性能、诊断问题以及更好地利用数据库资源。若系统在任意阶段崩溃,恢复时可通过比对 Redo Log 和 Binlog 的状态,决定是提交还是回滚该事务,从而保证数据一致性。等更新语句在执行流程的前半部分(连接、解析、优化)与查询语句基本一致,主要区别体现在。

2026-02-24 16:42:40 761

原创 Java 内部类详解:定义、分类、原理与最佳实践

Java 内部类(Inner Class)是指定义在另一个类内部的类。它最大的特点是能够直接访问外部类的所有成员(包括私有成员),从而在封装性和代码组织上提供更强的表达能力。内部类常用于实现回调、构建复杂对象(如 Builder 模式)、隐藏辅助类等场景。

2026-02-24 15:26:53 759

原创 面向对象 vs 面向过程:Java 编程范式深度解析

Java 是一门典型的面向对象编程(Object-Oriented Programming, OOP)语言,其设计哲学与传统的面向过程编程(Procedural Programming)有本质区别。理解这两种编程范式的差异,有助于开发者在不同场景下选择合适的抽象方式,提升代码的可读性、可维护性和可扩展性。→ 如果只是把函数塞进类里,没有封装、继承、多态的设计,仍是“面向过程披着类的外衣”。(如静态工具方法),关键在于是否合理运用 OOP 原则。复杂系统用面向对象更可控。,不直接暴露余额字段。

2026-02-12 17:23:19 690 1

原创 Java 基本类型 vs 包装类型:深入理解与最佳实践

Java 中的基本类型与其对应的包装类型)在语义、内存布局和使用场景上存在显著差异。理解这些区别对于编写高效、安全的 Java 代码至关重要。✅ 优化:尽量使用基本类型集合(如 Eclipse Collections、FastUtil)或避免不必要的装箱。✅ 结论:在“值不可变”的前提下,两者在方法调用中的行为效果一致。Java 泛型基于类型擦除实现,运行时类型参数被替换为。默认为 0),而包装类型可设为。的,无法通过 JVM 参数调整。类型,基本类型无法直接传入。的子类,无法用于泛型(如。

2026-02-12 16:43:06 1097

原创 String、StringBuffer 和 StringBuilder的区别是什么

⚠️ 注意:这种粗粒度锁虽然保证了线程安全,但也带来了性能损耗,因此在单线程场景下应优先使用。理解三者的区别,有助于我们在不同场景下做出合理选择,避免性能陷阱或并发问题。可能导致常量池膨胀(尤其在 JDK 6 及以前,常量池位于永久代),需谨慎评估。不可变对象天生是线程安全的——多个线程同时读取不会引发数据竞争,无需额外同步。JVM 在堆中维护了一个字符串常量池,相同内容的字符串只存一份。可变,修改一个引用的内容会导致其他引用“意外”改变,破坏池的语义。,所有操作都在原数组上完成,因此效率远高于。

2026-02-11 17:48:50 930

原创 Java 中 Exception 与 Error 的区别:深入理解异常体系

Java 中 Exception 与 Error 的区别:深入理解异常体系

2026-02-10 15:10:59 931

原创 Java 中的序列化与反序列化

Java 中的序列化与反序列化:从入门到实践

2026-02-10 13:50:26 641

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除