📅 2026年8月11日 · ⏱️ 阅读约18分钟 · 💻 Java面试专题
🔥 核心亮点速览
✅ 精选JVM和并发编程20道高频面试真题,覆盖90%面试考点
✅ 每道题都有详细的标准答案和深入解析
✅ 附带考点延伸和面试技巧,助你举一反三
✅ 按难度分级(基础/进阶/高级),循序渐进提升
🎯 JVM和并发编程是Java面试中最难也最重要的两个模块。据统计,超过80%的Java后端面试都会涉及JVM和并发相关的问题。本文精选了20道高频面试真题,涵盖JVM内存模型、垃圾回收、类加载、线程安全、锁机制、线程池等核心知识点。
💡 每道题都经过精心筛选,配有标准答案和深入解析。建议先自己思考答案,再看解析,这样才能真正提升面试能力。准备好了吗?让我们开始吧!
━━━━━━━━━━━━━━━━━━━━
🧠 第一部分:JVM高频真题(10道)
📌 Q1:JVM内存模型中,堆和栈的区别是什么?
【标准答案】
✅ 存储内容:堆存储对象实例和数组,栈存储基本数据类型、对象引用和方法调用的局部变量。
✅ 生命周期:堆中的对象生命周期不确定,由垃圾回收器管理;栈中的数据随方法调用结束而销毁。
✅ 线程共享:堆是线程共享的,栈是线程私有的。
✅ 异常:堆溢出抛出OutOfMemoryError,栈溢出抛出StackOverflowError。
🔍 面试技巧:建议结合JVM内存模型图来讲解,展示堆、栈、方法区等区域的位置关系。
📌 Q2:什么是GC Roots?垃圾回收算法有哪些?
【标准答案】
GC Roots是一组活跃的对象引用,垃圾回收器通过它们来判断对象是否可达。可以作为GC Roots的对象包括:虚拟机栈中的本地变量、方法区中的静态变量、方法区中的常量、本地方法栈中的JNI引用等。
垃圾回收算法主要有以下几种:
🟢 标记-清除:先标记存活对象,再清除未标记对象。缺点是会产生内存碎片。
🟢 标记-复制:将存活对象复制到另一半空间。优点是实现简单、无碎片,缺点是内存利用率只有50%。
🟢 标记-整理:先标记存活对象,然后将存活对象移动到一端,最后清理边界外的空间。
🟢 分代收集:根据对象存活周期将堆分为新生代和老年代,分别采用不同的回收算法。
📌 Q3:CMS和G1垃圾回收器有什么区别?
【标准答案】
CMS(Concurrent Mark Sweep)是一种以获取最短回收停顿时间为目标的垃圾回收器。它采用标记-清除算法,分为初始标记、并发标记、重新标记和并发清除四个阶段。优点是停顿时间短,缺点是会产生内存碎片。
G1(Garbage First)是一种面向服务端应用的垃圾回收器。它将堆划分为多个大小相等的Region,根据回收价值优先回收。优点是预测停顿时间、避免内存碎片,适合大内存场景。
📌 Q4:类加载过程分为哪几个阶段?双亲委派模型是什么?
类加载过程分为:加载 -> 验证 -> 准备 -> 解析 -> 初始化。双亲委派模型是指类加载器在加载类时,首先将请求委托给父类加载器处理,如果父类加载器无法处理,再由自己处理。这样可以保证类的唯一性和安全性。
📌 Q5:OOM常见原因有哪些?如何排查?
常见OOM原因:堆内存溢出(对象创建过多)、栈溢出(递归过深)、方法区溢出(动态生成类过多)、直接内存溢出(NIO使用不当)。排查方法:① 查看GC日志 ② 使用jmap生成堆快照 ③ 使用MAT分析内存泄漏 ④ 使用jstack查看线程栈。
📌 Q6:Java内存模型(JMM)中的happens-before规则有哪些?
happens-before规则包括:程序次序规则、锁规则、volatile变量规则、线程启动规则、线程终止规则、线程中断规则、对象终结规则、传递性规则。这些规则保证了多线程环境下的可见性和有序性。
📌 Q7:volatile关键字的作用是什么?如何保证可见性?
volatile关键字有两个作用:① 保证变量的可见性(一个线程修改后,其他线程立即可见)② 禁止指令重排序。volatile通过内存屏障实现,读写操作会插入内存屏障指令,确保内存可见性。但volatile不保证原子性,不能替代synchronized。
📌 Q8:什么是内存泄漏?Java中常见的内存泄漏有哪些?
内存泄漏是指程序中已分配的内存不再使用,但无法被垃圾回收器回收。Java中常见的内存泄漏:① 长生命周期对象持有短生命周期对象引用 ② 集合中的对象无法释放 ③ 静态集合类引起的泄漏 ④ 未关闭的资源(文件、连接等)⑤ 监听器未移除 ⑥ ThreadLocal使用不当。
📌 Q9:JVM调优常用的参数有哪些?
常用JVM参数:-Xms/-Xmx设置堆大小,-Xmn设置新生代大小,-XX:MetaspaceSize设置元空间大小,-XX:+UseG1GC使用G1垃圾回收器,-XX:MaxGCPauseMillis设置最大停顿时间,-XX:+PrintGCDetails打印GC详情,-XX:+HeapDumpOnOutOfMemoryError在OOM时生成堆快照。
📌 Q10:什么情况下会导致Full GC?如何优化?
导致Full GC的情况:① 老年代空间不足 ② 方法区空间不足 ③ System.gc()调用 ④ CMS GC时出现promotion failure。优化方法:① 增大堆内存 ② 调整新生代和老年代比例 ③ 减少大对象创建 ④ 优化代码,减少对象生命周期 ⑤ 选择合适的垃圾回收器。
━━━━━━━━━━━━━━━━━━━━
⚡ 第二部分:并发高频真题(10道)
📌 Q11:synchronized和ReentrantLock的区别?
【标准答案】
🟢 实现方式:synchronized是JVM层面的关键字,通过monitor实现;ReentrantLock是API层面的类,通过AQS实现。
🟢 灵活性:synchronized自动释放锁;ReentrantLock需要手动释放,支持tryLock、超时获取等。
🟢 公平性:synchronized是非公平锁;ReentrantLock默认非公平,但可配置为公平锁。
🟢 条件变量:ReentrantLock支持多个Condition,synchronized只能有一个等待队列。
📌 Q12:什么是CAS?ABA问题怎么解决?
CAS(Compare And Swap)是一种无锁算法,通过比较内存值和预期值来决定是否更新。ABA问题是指一个值从A变为B再变回A,CAS无法检测到中间变化。解决方案:使用AtomicStampedReference,在CAS时同时检查版本号。
📌 Q13:线程池的核心参数有哪些?如何合理设置?
七大核心参数:corePoolSize(核心线程数)、maximumPoolSize(最大线程数)、keepAliveTime(存活时间)、workQueue(任务队列)、threadFactory(线程工厂)、handler(拒绝策略)。设置原则:CPU密集型任务线程数=CPU核心数+1,IO密集型任务线程数=CPU核心数*2。
📌 Q14:ConcurrentHashMap如何保证线程安全?
JDK 7中使用分段锁(Segment)实现,将整个Map分成多个Segment,每个Segment独立加锁。JDK 8中取消了Segment,使用CAS + synchronized实现。当链表长度超过8时,转为红黑树,提高查询效率。
📌 Q15:什么是死锁?如何避免死锁?
死锁是指两个或多个线程互相等待对方释放资源,导致所有线程都无法继续执行。产生死锁的四个条件:互斥、占有且等待、不可抢占、循环等待。避免方法:① 避免嵌套锁 ② 按固定顺序获取锁 ③ 使用tryLock超时获取 ④ 使用死锁检测工具。
📌 Q16:ThreadLocal的原理和使用场景?
ThreadLocal为每个线程提供独立的变量副本,线程之间互不影响。原理:Thread类中有一个ThreadLocalMap,以ThreadLocal对象为key,存储线程本地变量。使用场景:用户上下文传递、数据库连接管理、SimpleDateFormat线程安全。注意:使用完要及时remove(),避免内存泄漏。
📌 Q17:AQS是什么?ReentrantLock如何利用AQS实现?
AQS(AbstractQueuedSynchronizer)是Java并发包的核心框架,提供了一套实现锁和同步器的模板。ReentrantLock通过继承AQS,实现了可重入的独占锁。AQS内部使用CLH队列管理等待线程,通过CAS操作维护state状态。
📌 Q18:synchronized锁升级的过程?
synchronized锁升级过程:无锁 -> 偏向锁 -> 轻量级锁 -> 重量级锁。偏向锁:只有一个线程访问时,记录线程ID,无需CAS。轻量级锁:有竞争时,通过CAS获取锁。重量级锁:竞争严重时,线程阻塞,使用操作系统互斥量。
📌 Q19:什么是线程安全?如何保证线程安全?
线程安全是指多线程环境下,程序能够正确执行,不会出现数据不一致或异常情况。保证线程安全的方法:① 使用synchronized或Lock加锁 ② 使用原子类(AtomicInteger等)③ 使用并发容器(ConcurrentHashMap等)④ 使用ThreadLocal ⑤ 使用不可变对象。
📌 Q20:volatile和synchronized的区别?
volatile保证可见性和有序性,但不保证原子性。synchronized保证可见性、有序性和原子性。volatile适用于单个变量的读写,synchronized适用于需要原子操作的场景。volatile性能优于synchronized,但功能较弱。
━━━━━━━━━━━━━━━━━━━━
🎯 总结与展望
这20道面试真题涵盖了JVM和并发编程的核心知识点。在面试中,不仅要能够准确回答这些问题,还要能够结合自己的项目经验进行深入阐述。建议在回答问题时,先给出简洁的答案,再逐步展开细节,展示你的深度思考能力。
🚀 面试不仅仅是考察知识点,更是考察候选人的思维能力和解决问题的能力。在准备面试的过程中,要注重理解原理而不是死记硬背。只有真正理解了底层原理,才能在面对变体问题时游刃有余。
🎉 觉得有用?别忘了「三连」支持!
👍 点赞 — 让更多Java开发者看到这篇干货
⭐ 收藏 — 面试前翻出来复习
🔄 转发 — 转发给正在准备面试的朋友 😄
━━━━━━━━━━━━━━━━━━━━
📌 关注我,获取更多Java后端、面试技巧、架构设计干货
💻 专注Java后端技术 · 🎓 深耕面试技巧 · 🏗️ 分享架构实战经验
📅 每周更新 · 🔔 点击关注不迷路
🔮 下期预告
📖 《MySQL锁机制全解析:行锁/间隙锁/临键锁》
深入剖析MySQL各种锁的实现原理和使用场景,彻底搞懂InnoDB锁机制。