work hard work smart

专注于AI+Java后端开发。 不断总结,举一反三。
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Java 常见面试问题

Posted on 2026-09-14 13:34  work hard work smart  阅读(6)  评论(0)    收藏  举报

1、线程池的核心参数与工作原理

线程池的核心是 ThreadPoolExecutor,有 7 个参数:核心线程数、最大线程数、空闲存活时间、时间单位、阻塞队列、线程工厂、拒绝策略。

执行流程是:任务提交后,如果核心线程未满,创建核心线程执行;如果核心线程满了,放入阻塞队列;如果队列满了,创建非核心线程;如果达到最大线程数,触发拒绝策略。

 

2、synchronized 和 ReentrantLock 的区别

synchronized 是 JVM 层面的关键字,自动加锁释放锁;ReentrantLock 是 JDK 层面的 API,需要手动 lock() / unlock()(必须放在 finally)。
ReentrantLock 更灵活:支持公平锁、可中断(lockInterruptibly)、超时获取(tryLock)、多条件变量(Condition)

 

3、Jvm垃圾回收的流程

JVM 的 GC 过程分三步:

第一步,找垃圾:用可达性分析,从 GC Roots 出发,找不到引用链的对象就是垃圾。

第二步,分代:堆分新生代和老年代。新生代用复制算法,因为存活对象少;老年代用标记-整理,因为存活率高。

第三步,回收:新生代 Eden 满了触发 Minor GC,存活对象复制到 Survivor,年龄够了晋升老年代。老年代满了触发 Full GC,会 STW。

回收器从 Serial 演进到 CMS,再到 G1 和 ZGC,核心目标是降低 STW 时间。现在生产环境主流是 G1,通过分 Region 和可预测停顿模型,把停顿控制在几百毫秒内。”

 

CMS 的四个阶段(只针对老年代)

 
阶段是否 STW做什么
初始标记 STW 标记 GC Roots 直接可达的老年代对象
并发标记 并发 从初始标记对象出发,遍历老年代对象图
重新标记 STW 修正并发标记期间因用户线程修改引用导致的变动(用增量更新 Incremental Update)
并发清除 并发 清除未被标记的对象,不移动存活对象

G1 的四个阶段(针对全堆)    

阶段是否 STW做什么
初始标记 STW 标记 GC Roots 直接可达的对象(伴随一次 Young GC)
并发标记 并发 遍历全堆对象图,用 SATB 记录引用变化
最终标记 STW 处理 SATB 队列,完成标记
筛选回收 STW 统计 Region 回收价值,复制存活对象到新 Region,清空旧 Region

  

4、什么是三色标记

在并发标记过程中,JVM 把对象抽象地分为三种颜色:

 
颜色含义状态
白色 尚未被访问的对象 默认状态,如果标记结束还是白色,就是垃圾
灰色 自己被访问了,但它的子引用还没扫描完 中间状态,正在处理
黑色 自己和它的所有子引用都扫描完了 确认存活

标记过程

  1. 初始时,所有对象都是白色。

  2. GC Roots 直接可达的对象变为灰色,放入“待处理队列”。

  3. 从队列取出灰色对象,扫描它的子引用:

    • 子引用是白色 → 变灰色,加入队列。

    • 子引用是灰色或黑色 → 不动。

  4. 扫描完所有子引用后,该对象从灰色变为黑色。

  5. 队列为空时,标记结束。仍然为白色的对象就是垃圾。

 

“三色标记是并发标记的算法,把对象分为白、灰、黑三种颜色。白色是未访问,灰色是自己访问了但子引用没扫完,黑色是自己和子引用都扫完了。标记结束后,白色对象就是垃圾。

并发标记期间,用户线程可能修改引用,导致漏标。漏标需要同时满足两个条件:黑色对象新增了对白色对象的引用,且灰色对象到该白色对象的引用消失了。

CMS 用增量更新,破坏第一个条件:只要黑色对象新增了对白色对象的引用,就把黑色对象变回灰色,重新标记阶段再扫描一遍。

G1 用 SATB,破坏第二个条件:在并发标记开始时做逻辑快照,如果引用被删除,就把旧引用记录下来,认为它在快照时刻还活着。代价是产生浮动垃圾。

两者都用三色标记,只是解决漏标的策略不同。”