- 博客(127)
- 资源 (3)
- 收藏
- 关注
原创 volatile 的顺序性和可见性原理详解
特性实现原理可见性基于 CPU 缓存一致性协议(MESI)和 JVM 写屏障,强制变量写回主内存并失效其他线程的副本顺序性基于内存屏障(StoreStore、LoadLoad 等),禁止特定类型的指令重排序原子性仅保证单个变量的读写原子性,不保证复合操作的原子性。
2025-12-14 22:00:07
645
原创 JVM G1 和 CMS 详解与对比
CMS 是第一代并发低延迟收集器,通过标记 - 清除算法实现了短 STW 时间,但存在内存碎片、CPU 敏感、并发模式失败等问题,适合小内存、低延迟的传统应用;G1 是新一代垃圾收集器,通过区域化管理、垃圾优先回收和可预测停顿,解决了 CMS 的核心痛点,更适合大内存、高并发的现代应用。随着 JDK 版本的迭代,G1 已成为主流选择,而 CMS 逐渐被废弃。在实际项目中,应根据内存大小、CPU 核心数、延迟要求等因素选择合适的收集器,并通过压测和监控持续优化 GC 参数。
2025-12-14 21:26:47
921
原创 JVM 垃圾收集器中的记忆集与读写屏障
记忆集是一种辅助数据结构,本质是 **“从非收集区到收集区的引用的集合”**(如老年代→新生代、Old Region→Eden Region)。它为每个收集区(如新生代的 Eden/Survivor)维护一个索引,记录哪些非收集区的内存块中存在指向该收集区的引用。组件核心作用实现方式典型使用场景记忆集(卡表)记录跨代 / 跨 Region 引用,避免全堆扫描卡表(主流)、段表、精确表CMS、G1、ParNew 等几乎所有现代收集器写屏障触发记忆集更新、维护并发标记一致性预写屏障、后写屏障;
2025-12-14 21:16:35
679
原创 工厂模式详解
核心特点属于 GoF 23 种经典设计模式,是工厂方法模式的升级版本。抽象工厂不仅创建一种产品,而是创建一族相关的产品(产品族),且产品之间通常存在关联或依赖关系。定义一个抽象工
2025-12-14 20:40:04
339
原创 Java 线程池ThreadPoolExecutor的工作原理
通过核心参数定义线程池的行为,通过任务队列缓冲任务,通过 Worker 线程实现线程复用,通过状态管理控制生命周期。其核心价值是高效管理线程资源,平衡系统的并发性能和资源消耗。在实际开发中,理解线程池的参数设计和执行流程是调优的关键,需根据业务的任务特性(执行时间、并发量、优先级)定制线程池,而非依赖Executors的默认实现。
2025-12-14 13:04:04
11
原创 JVM类加载详解
JVM 类加载过程是一个分层、有序、安全加载:把字节码读入内存,创建 Class 对象;链接:验证合法性、准备静态变量、解析符号引用;初始化:执行静态代码,完成静态变量的赋值。这个过程保证了类在 JVM 中被正确加载和使用,同时通过双亲委派模型、验证阶段等机制保障了 JVM 的安全性和稳定性。
2025-12-11 18:48:35
699
原创 MySQL 临键锁
本质:覆盖「索引记录本身 + 该记录与下一条记录之间的间隙」的锁;作用范围:针对范围查询(如)生效,精准等值查询(命中唯一索引)会降级为行锁;生效级别:仅在 RR / 串行化级别生效(RC 级别下自动禁用间隙锁,仅保留行锁);核心目标:阻止其他事务在锁定的间隙中插入新数据,从根源上解决幻读问题。锁定范围:左闭右开(当前记录闭区间 + 下一条记录前的间隙开区间);降级规则:唯一索引的等值查询(命中)→ 行锁;未命中 → 间隙锁;生效级别:仅 RR / 串行化级别,RC 级别禁用间隙锁;核心目标。
2025-12-11 17:57:47
617
原创 线上服务响应慢,如何排查
常见问题典型现象解决方案Full GC 频繁服务偶尔卡顿,FGC 次数多优化内存配置,更换 GC 收集器(如 G1/ZGC),修复内存泄漏数据库慢查询接口耗时集中在 SQL 执行阶段加索引,优化 SQL,分库分表,读写分离线程阻塞 / 死锁CPU 使用率低,但请求响应慢修复死锁,优化锁粒度(如用 ReentrantLock 代替 synchronized)第三方服务调用超时接口耗时集中在第三方调用阶段设置合理超时时间,增加熔断降级(如 Sentinel/Hystrix)
2025-12-11 10:47:50
656
原创 jvm 方法区和永久代
方法区是 JVM 运行时数据区的一部分,属于线程共享类的元数据(类的结构信息:类名、访问修饰符、字段 / 方法信息、父类 / 接口、常量池等);运行时常量池(从 Class 文件的常量池加载而来,存储字面量、符号引用等);静态变量(static 变量);即时编译器(JIT)编译后的代码缓存等。永久代是 Sun/Oracle 的 HotSpot 虚拟机在 JDK 1.7 及之前,对「方法区」的具体落地实现—— 它把方法区直接划分在 JVM 堆的永久代区域,因此永久代的内存受 JVM 堆内存(
2025-12-09 16:53:14
446
原创 DDD落地
实体(有唯一标识、状态可变):订单(Order):唯一标识 orderId,状态随流程变更。订单项(OrderItem):依赖订单存在,无独立标识。物流单(LogisticsOrder):唯一标识 logisticsId,关联订单。值对象(无唯一标识、不可变):收货地址(ReceivingAddress):包含省、市、区、详细地址、手机号(属性不可单独修改,需整体替换)。支付信息(PaymentInfo):包含支付方式、支付金额、支付时间(不可变)。
2025-11-04 16:39:27
549
原创 DDD—贫血模式和充血模式
定义:领域对象仅包含属性和 getter/setter 方法,无任何业务逻辑,所有核心规则(如状态变更、数据校验)都放在外部服务(如 Service 层)中。本质:领域对象沦为 “数据容器”,业务逻辑与数据分离,是典型的 “面向过程” 设计思路。
2025-11-03 15:58:49
324
原创 DDD—核心概念
DDD 的核心是通过建模抽象业务本质划分边界隔离复杂度统一语言消除沟通障碍,最终构建出既能反映业务逻辑、又具备灵活性和可维护性的系统。其原则并非教条,需结合业务复杂度灵活应用(简单系统可简化实践,复杂系统需深入落地)。
2025-10-30 11:18:40
481
原创 CompletableFuture线程池使用
CompletableFuture 是 Java 8 引入的异步编程工具,其线程管理依赖线程池。使用默认线程池(ForkJoinPool.commonPool())和自定义 ThreadPoolExecutor 存在显著差异
2025-10-24 18:12:04
774
原创 软件设计原则
软件设计原则是指导开发者构建软件系统的核心思想,贯穿需求分析、架构设计、编码实现全流程。这些原则并非强制规范,而是经过行业实践沉淀的 “最佳实践”,能帮助团队规避设计缺陷(如紧耦合、僵化代码),提升系统长期演进能力。
2025-10-23 10:30:00
1691
原创 什么是Native Memory
话承上回,上篇文章解析了java 直接内存,提到过本地内存,本篇文章来解读下什么是本地内存。在计算机领域,通常指操作系统直接管理的内存区域,也称为 “系统内存” 或 “原生内存”,它不属于 Java 等虚拟机(JVM)的内存管理范畴,而是由操作系统内核直接分配和回收。
2025-10-22 14:23:21
651
原创 Java直接内存解读
在 Java 中,直接内存(Direct Memory)是一种不受 JVM 堆内存管理的内存区域,它直接分配在操作系统的本地内存中,而非 JVM 堆中。
2025-10-22 11:26:43
507
原创 两阶段提交(2PC)和三阶段提交(3PC)的超时机制
协调者发送 “CanCommit 询问” 后,若超时未收到全部参与者的 “Yes” 响应,直接判定事务失败,向所有参与者发送 “中断指令”(Abort),触发回滚。协调者向所有参与者发送 “准备请求” 后,若在规定时间内未收到全部参与者的响应(可能因网络故障或参与者崩溃),协调者会判定事务失败,触发。协调者发送 “预提交指令” 后,若超时未收到部分参与者的确认,判定事务失败,发送 “中断指令”,要求参与者回滚预提交的操作。协调者发送 “提交 / 回滚指令” 后,若超时未收到确认,会。如果觉得还不错的话,
2025-10-22 11:20:14
816
原创 分布式系统多节点间的数据一致性解决方案
常见的解决方案包括两阶段提交(2PC)、三阶段提交(3PC)、TCC(Try-Confirm-Cancel)和本地消息表
2025-10-21 14:14:26
57
原创 Statement和PreparedStatement区别
Java中PreparedStatement与普通Statement的核心区别在于:PreparedStatement采用预编译机制,SQL语句创建时即被数据库编译存储,执行时仅传递参数值,避免了重复编译,提升性能;
2025-10-17 17:00:31
591
原创 RocketMQ的DefaultMQPushConsumerImpl 源码解读
通过精巧的组件协作(拉取服务、消费服务、负载均衡服务)实现了 “推” 模式的封装,核心是将复杂的拉取逻辑隐藏在底层,暴露简单的监听器接口给开发者。其源码设计体现了高内聚、低耦合的原则,通过分层和异步机制保证了高并发场景下的稳定性和效率。是 RocketMQ 推送消费者的核心实现类,封装了消息消费的底层逻辑。是单线程,通过队列缓存拉取任务(, 原创不易,且看且珍惜~拉取消息的入口方法,由。如果觉得还不错的话,
2025-10-16 17:05:52
51
原创 @Import和@ComponentScan区别
Import侧重于手动、精确地控制 Bean 的注册,适用于定制化配置和复杂的注册逻辑。侧重于自动扫描和注册组件,适用于简化项目中大量组件的注册过程。如果觉得还不错的话,关注、分享、在看, 原创不易,且看且珍惜~
2025-09-23 11:52:15
335
原创 InheritableThreadLocal 在线程池复用场景下的副作用
设计用于临时创建的子线程,而非池化复用的线程。在线程池环境中使用时,必须额外注意清理机制,否则会导致隐蔽的线程安全问题。对于需要在线程池间传递上下文的场景,推荐使用等专门为解决此问题设计的工具类。如果觉得还不错的话,关注、分享、在看, 原创不易,且看且珍惜~
2025-09-22 10:59:22
335
原创 ThreadLocal 原理讲解
ThreadLocal 是 Java 提供的线程局部变量工具类,它能让每个线程拥有自己独立的变量副本,避免线程间共享导致的并发问题。
2025-09-22 10:35:39
360
原创 Mybatis OGNL表达式对0误判问题
核心问题在于对数字类型误用了字符串的空值判断逻辑。test="str!= null"通过区分字段类型调整判断条件,可避免 OGNL 类型转换导致的误判。如果觉得还不错的话,关注、分享、在看, 原创不易,且看且珍惜~
2025-08-26 17:58:08
372
原创 MDC在微服务中落地思考
摘要: MDC(映射诊断上下文)是微服务架构中实现日志串联的关键机制,通过传递traceId等标识符关联跨服务、跨线程的日志。
2025-07-09 15:07:03
1273
原创 SpringSecurity源码解读AbstractAuthenticationProcessingFilter
是 Spring Security 框架里的一个抽象过滤器,它在处理基于表单的认证等认证流程时起着关键作用。它继承自,并实现了接口。此过滤器的主要功能是拦截客户端发送的认证请求,对请求中的认证信息(如用户名和密码)进行提取,然后将这些信息封装成对象,再把该对象传递给进行认证。// 其他属性和构造方法1. 主要属性解释@Override@Override// 认证成功处理逻辑@Override// 认证失败处理逻辑。
2025-04-24 14:32:29
361
原创 Postman 发送批量请求
postman 作为api 模拟工具,在日常开发中用来调试接口。在线上数据批处理中,也能发挥重大作用,今天就来看一下 批量发送数据。修改参数类型为字符串,参数正确读取,点击运行即可。参数类型默认是“自动检测”,会导致数据精度丢失!
2025-03-27 13:39:28
1853
原创 @ComponentScan和@SpringBootApplication的scanBasePackages 同时使用
但是,如果同时使用,会出现覆盖情况,@ComponentScan优先级更高,@SpringBootApplication中scanBasePackages指定的包会失效。从注释里可以看出,@SpringBootApplication的scanBasePackages 和@ComponentScan 等同。两者作用相同,如果不指定包名,默认扫描使用该注解的类所在包下所有类。
2025-03-10 16:44:24
572
原创 SourceTree 意外退出后无法使用
Windows 经常蓝屏,导致运行着的 SourceTree 意外退出,开机后,双击 SourceTree.exe 闪退,无法使用!此时,可以打开软件了,但是pull 代码一致无法成功,接下来进行第二步操作。重新 pull 代码,成功。工具->选项->一般。
2024-10-11 10:02:31
1381
原创 网页打开慢,这锅该谁背?
工作中扯皮说不可避免且非常常见的事情. 开发与产品、开发和测试、前端和后端都会产生扯皮现象. 今天要聊的一个问题就是前后端之间的扯皮问题.网页打开太慢这个锅谁背?做开发不能无凭据地胡乱甩锅, 我们要用数据说话, 具体看哪个参数呢,就是我们今天介绍的 TTFB.TTFBTime To First Byte 就是后台响应的第一个字节到达浏览器的时间, 说白了这个值比较大的话就说明是后端接口的问题,比如达到了几秒甚至十几秒; 如果比较正常的话通常不会超过一秒,一般都是 ms 级别,当然数据较大
2024-03-06 16:30:00
260
原创 J.U.C——CyclicBarrier 实现原理
1. 通过 generation 来实现循环使用,每一轮结束后,都会重置 generation;2. CyclicBarrier 底层和 CountDownLatch 一样是基于 AQS 实现的;3. CyclicBarrier 不需要代码手动移除(trip)屏障,线程数量达到(count==parties)自动触发。
2024-02-20 14:42:00
236
原创 J.U.C——CountDownLatch 的实现原理
1. 调用await 方法的线程处于 WATING 状态,虽然源码中说是 "block";2. 等待线程和任务线程通过核心方法 wait 和 countDown 来协调工作,完成特定场景需求。
2024-02-20 11:12:20
163
原创 Servlet 预览pdf
上篇文章介绍了图片的预览,这篇我们介绍下 pdf 文件的预览,pdf 预览在实际开发中用的还是比较多的,比如很多文件协议、合同都是用pdf 格式,协议预览就需要我们做 pdf 预览了。大家注意看右上角,下载按钮也有了,这个是浏览器的功劳,所以一旦我们做了文件预览功能,下载功能就自动生成了,是不是特别棒~
2024-01-17 15:21:56
994
原创 RocketMQ 限流参数
1. pullBatchSize 在PushConsumer 模式中默认值是32,注意是每一次从队列拉取的最大数据,针对的是单个队列,所以必须考虑到RocketMQ一个 topic 会创建多个 queue 的特性。2. 根据经验,我们会认为pullBatchSize 调大点会更好,减少拉取次数处理效率更高,但是有时我们得根据实际情况来做取舍。
2024-01-17 11:21:31
1337
原创 HashMap 死循环
1. 死循环的问题根本原因是多个线程操作(准确地说是修改)同一条链表,导致链表循环,其他线程读取的时候就会发生死循环。2. 虽然 1.8 扩容时链表改成了尾插法,但是仍然无法保证多线程数据安全,毕竟 HashMap 本身就不是线程安全的。
2023-12-25 15:59:59
516
原创 Tomcat 源码之StandardWrapperValve
invoke 中,调用 filterChain#filter,所有的filter 走完,调用servlet#service 方法,整个调用过程的任何exception 都会被捕捉,最后由StandardHostValve重定向到 ApplicationDispatcher(implements RequestDispatcher)我们知道一个请求过来 tomcat 处理的核心的代码在。
2023-12-07 17:32:28
1010
原创 从Springboot 看 Tomcat 启动
所以这里可以看出来,启动 server 就是启动 service ,启动 service 里又启动了 engine ,启动 engine 就是启动每个子容器,子容器再递归启动子容器的子容器。就这样engine 启动了 host , host 启动 context ,context 启动 wrapper,这些容器都有一个 startInternal 方法,用来做容器自身的准备以及启动子容器。搞懂每个 startInternal 方法里面做的事情,才能真正理解 tomcat 启动原理!
2023-12-07 17:28:58
1221
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅