当前位置: 首页 > news >正文

《Java面试85题图解版(二)》进阶深化上篇:并发编程 + JVM

📘 《Java面试85题图解版(二)》进阶深化上篇:并发编程 + JVM


📂Java面试85题图解版 · 全系列7篇

基础核心篇 | 并发+JVM← 你在看 | Spring+数据库 | Redis缓存 | 高阶架构 | 高阶特性(即将发布)

📌 全系列总目录 | 💡 每道题 = 结构图 → 场景比喻 → 对比表 → 一句话总结


阅读提示:这是“图解+比喻+一句话总结”面试题库第二篇的进阶深化上篇,覆盖并发编程(7题)与JVM(7题)共14道面试高频题。每道题仍然是四层结构——结构图 → 场景比喻 → 关键对比表 → 一句话总结


一、并发编程(第30-36题)

📌 第30题:四种创建线程的方式

一图看清

1. 继承Thread → 重写run() 2. 实现Runnable → 实现run() 3. 实现Callable → 实现call(),可返回结果,抛异常 4. 线程池(推荐) → 复用线程,控制资源 JDK21新增:虚拟线程 → 百万级并发,无需池化

比喻记忆请人干活

  • 继承Thread:指定某人是干活的料,直接让他干。
  • Runnable:写一张任务单,给谁都能执行。
  • Callable:任务单+回执,干完还给你结果。
  • 线程池:雇几个专职人员,来活了分配,干完回来待命。
  • 虚拟线程:临时工零成本,需要时直接雇,用完就走。

💡 一句话总结简单用Runnable,需返回值用Callable,生产必须线程池,JDK21可上虚拟线程。


📌 第31题:synchronized 锁升级过程

一图看清

无锁 ─→ 偏向锁 ─→ 轻量级锁(自旋CAS) ─→ 重量级锁(OS Mutex) 同一线程多次进 少量线程交替执行 激烈竞争,挂起唤醒

比喻记忆会议室使用规则

  • 无锁:会议室空着,谁都能用。
  • 偏向锁:小王经常用,门上贴“小王专用”,直接进。
  • 轻量级锁:变成先到先得,小李偶尔来,门口徘徊等(自旋),抢到就进。
  • 重量级锁:人太多了,保安介入——“都别在门口转了,下来排队,叫号再进”。挂起唤醒慢。

💡 一句话总结无锁→偏向→轻量级→重量级,竞争越激烈锁越重,只升不降。


📌 第32题:volatile 的可见性与有序性

一图看清

可见性 ✅:写后立即刷新主存,读前强制从主存取 有序性 ✅:禁止指令重排序(内存屏障) 原子性 ❌:i++ 复合操作仍不安全

比喻记忆大堂公告屏 vs 部门小黑板

  • 普通变量:各部门自己的小黑板。老板在财务部写了“销售额1亿”,销售部看不见。
  • volatile:大堂LED公告屏,老板一写所有人都看见。但不能做“把总数+1”这种需要读+改+写三步的操作,三步中间别人也可能动。

💡 一句话总结volatile一写全公司可见,顺序不乱,但复合操作仍需加锁。


📌 第33题:synchronized vs ReentrantLock

一图看清

synchronized:JVM内置,自动加解锁,非公平,单条件队列 ReentrantLock:API级,手动加解锁(try/finally),可公平,多Condition,可尝试加锁(tryLock)

比喻记忆电子门禁 vs 机械钥匙

  • synchronized:进门自动锁门,出门自动解锁。简单但功能少。
  • ReentrantLock:手动钥匙,可以公平排队,可以有多个等待区(Condition),可以试试“现在能不能开”(tryLock)。

💡 一句话总结简单场景synchronized够用;需要Condition/可中断/尝试加锁时用ReentrantLock。


📌 第34题:线程池核心参数与工作流程

一图看清

新任务 → ├─ 核心线程未满 → 创建核心线程 ├─ 核心线程满 → 入队列排队 │ ├─ 队列未满 → 等待执行 │ └─ 队列满 → 线程数<最大?→ 创建非核心线程 │ └─ 已达最大 → 拒绝策略 └─ 空闲超时(keepAliveTime) → 非核心线程销毁 不推荐Executors:无界队列可能OOM,最大线程数可能Integer.MAX_VALUE

比喻记忆银行柜台

  • corePoolSize:5个常驻柜台,客户来了直接办。
  • workQueue:10个等候座位,坐满了经理才着急。
  • maximumPoolSize:临时开3个流动柜台,总共最多8个。
  • 拒绝策略:大厅站不下了,保安拦人“明天再来”。
  • keepAliveTime:高峰期过后,空闲临时柜台5分钟撤掉。

💡 一句话总结5常驻柜→10座等候→8临时极限→满了就拒,闲了撤临柜,绝不用Executors偷懒。


📌 第35题:ThreadLocal 原理与内存泄漏

一图看清

Thread → ThreadLocalMap → Entry(key弱引用ThreadLocal → value强引用) 当外部强引用ThreadLocal置null → key被GC → Entry的value仍强引用 → 泄漏 线程池中线程长期复用 → ThreadLocalMap一直存在 → value无法回收

比喻记忆公司衣柜

  • Thread= 员工,ThreadLocalMap= 员工专属衣柜。
  • key弱引用= 抽屉标签,撕掉后没人知道里面装啥。
  • value强引用= 抽屉里的羽绒服,只要员工(线程)不走,羽绒服就占着柜子。
  • 线程池员工是长期工,衣柜越塞越满,必须每次用完清空——remove()

💡 一句话总结ThreadLocal的弱引用key被GC后value赖着不走,线程池必须手动remove。


📌 第36题:CompletableFuture 异步任务编排

一图看清

supplyAsync → 启动异步任务,返回结果 thenApply → 转换结果 thenAccept → 消费结果,无返回 thenCombine → 合并两个独立任务的结果 thenCompose → 依赖上一步结果启动新任务(扁平化) allOf / anyOf → 等所有完成 / 任一完成 exceptionally / handle → 异常兜底

比喻记忆餐厅取餐牌

  • supplyAsync:下单“宫保鸡丁”,拿到取餐牌。
  • thenApply:菜好了自动加一份米饭(转换结果)。
  • thenCombine:鸡丁和鱼香肉丝同时做,好了放同一个托盘。
  • thenCompose:先看今日特价菜单,再决定点哪个(依赖第一步结果)。
  • allOf:宴请,所有菜齐了才开吃。
  • exceptionally:哪道菜做砸了,赔个水果盘。

💡 一句话总结CompletableFuture像取餐牌,能串行、并行、合并、兜底,告别Future.get()阻塞。


二、JVM(第37-43题)

📌 第37题:JVM 运行时数据区

一图看清

线程共享: 堆(对象实例、数组) | 方法区/元空间(类元信息、运行时常量池) 线程私有: 程序计数器 | 虚拟机栈(栈帧:局部变量表、操作数栈) | 本地方法栈

比喻记忆公司办公大楼

  • :公共办公区,所有员工共用。保洁阿姨(GC)清理没人用的工位。
  • 方法区/元空间:公司档案室,保存组织架构、规章制度。JDK8后档案室搬到地下室(本地内存),不占主楼面积。
  • 虚拟机栈:员工个人工作记录本,任务完成翻回上页(方法返回)。
  • 程序计数器:手指指着当前正在执行哪一行代码。

💡 一句话总结堆和方法区大家共享,栈、PC寄存器、本地栈各线程独有。


📌 第38题:Java 堆的分代模型

一图看清

新生代(Eden + S0 + S1,默认8:1:1) ↓ Minor GC存活后年龄+1 → 进入Survivor区 ↓ 年龄达到阈值(默认15)→ 晋升老年代 老年代 ↓ 大对象可直接进入 JDK8+:永久代→元空间(本地内存) JDK9+:G1默认收集器,逻辑分代 JDK21:分代ZGC

比喻记忆公司员工分级

  • 新生代(Eden):试用期员工,大部分待不久就被优化。
  • S0/S1:转正考核区,每熬过一次考核年龄+1。
  • 老年代:老员工,熬过15次考核(或大对象直接空降高管)。
  • 元空间:公司规章制度,不占工位。

💡 一句话总结新生代复制回收,熬过去进老年代,元空间存类信息不占堆。


📌 第39题:垃圾回收算法

一图看清

标记-清除:标记存活 → 清除未标记 → 产生内存碎片 复制算法:内存分两块 → 存活复制到另一块 → 清空当前块 → 浪费一半内存 标记-整理:标记存活 → 向一端移动 → 清边界外 → 无碎片但STW时间长 分代收集:新生代用复制,老年代用标记-清除/整理

比喻记忆三种搬家方式

  • 标记-清除:贴“要/不要”标签,不要的扔出窗外。房间空了但家具乱七八糟,大沙发放不下(内存碎片)。
  • 复制算法:你有A、B两间房,把A里还要的搬到B,一把火烧掉A。整齐但永远只用一半房间。
  • 标记-整理:把还要的推到房间一端,尾部全清空。最整齐但搬家最累(移动对象开销大)。

💡 一句话总结新生代复制(快),老年代整理(无碎片),分代组合是主流。


📌 第40-41题:常见垃圾回收器及CMS vs G1

一图看清

Serial / Serial Old → 单线程,小内存Client模式 ParNew + CMS → 低延迟,并发标记清除,碎片+浮动垃圾,JDK8常用 Parallel Scavenge + Parallel Old → 关注吞吐量,后台计算 G1 → Region分区+可预测停顿,JDK9+默认 ZGC / Shenandoah → 超低延迟(<1ms),JDK21分代ZGC

比喻记忆清洁工团队

  • Serial:一个人干全部,小房间够用。
  • CMS:几个人边干活边让人用房间,低延迟但房间不整齐(碎片),偶尔要大扫除(退化为Serial Old全STW)。
  • G1:把大楼划分成多个区域,哪块最脏先清哪块,在规定时间内完成。JDK9后默认清洁团队。
  • ZGC:几乎看不见的清洁工,你感觉不到他们在工作。

💡 一句话总结低延迟CMS(老)→G1(JDK9+默认)→ZGC(JDK21分代,极低延迟)。


📌 第42题:类加载过程与双亲委派模型

一图看清

类加载过程:加载 → 验证 → 准备 → 解析 → 初始化 读取 格式 分配 符号 static 字节码 检查 赋零值 引用→ 赋值 直接引用 双亲委派:请求向上委派(子→父→爷),加载向下查找(爷→父→子) Bootstrap ClassLoader → Extension ClassLoader → Application ClassLoader → 自定义

比喻记忆新员工入职 + 小孩要零花钱

  • 加载:HR拿到简历,录入系统。
  • 验证:背调,检查学历证真伪、有无犯罪记录。
  • 准备:分配工位、电脑,但桌上还是空的(static变量赋零值)。
  • 解析:把“隔壁部门张三”这种称呼转成工号(符号引用→直接引用)。
  • 初始化:新员工到岗,摆个人物品,装软件(执行static赋值和static代码块)。

双亲委派:小孩要零花钱,先问爸,爸问爷。爷有就给,都没有爸爸才自己掏。防止小孩用假钞(自定义String)冒充真钱。

💡 一句话总结加载五步走,双亲委派向上请求向下加载,护住核心库不被篡改。


📌 第43题:OOM 排查与定位

一图看清

常见OOM类型: Java heap space → 堆溢出,对象太多 Metaspace → 元空间不够,类加载过多 unable to create new native thread → 线程数超系统限制 排查工具链: jstat → 监控GC和内存 jmap -dump → 导出堆快照 jstack → 看线程状态 MAT / JProfiler → 分析dump文件 GC日志 → -XX:+PrintGCDetails

比喻记忆查漏水

  • jstat + 监控:水管压力表,发现水位在涨。
  • jmap dump:拆开天花板,看哪段管子出问题。
  • MAT分析:工程师分析是哪个厂家的管道老化了。
  • 解决:换管(修代码)、调水压(调JVM参数)、加装蓄水池(扩容内存)。

💡 一句话总结监控+堆dump+MAT定位根源,修代码或调参,ThreadLocal和集合未清理是最常见泄漏点。

本篇(上篇)我们覆盖了并发编程从锁升级到CompletableFutureJVM从运行时数据区到OOM排查的全部核心知识。这些正是面试官在中后段最爱追问的深水区。


上一篇:基础核心篇

下一篇:进阶深化(中):Spring核心 + 数据库进阶 —— Spring循环依赖三级缓存(情侣杯比喻)、自动装配、@Transactional失效坑、MySQL三日志、索引失效八大场景、PG高级索引……

👉 点击关注我 📂 返回全系列导航


http://www.jsqmd.com/news/816915/

相关文章:

  • C++ AVL树的学习
  • 【CanMV K210】显示交互 触摸屏画图与 LCD 轨迹绘制
  • Python MongoDB客户端实战:PyMongo深度解析
  • 米立特国产移液器全系解析:覆盖科研与工业领域的精准移液工具 - 品牌推荐大师
  • WechatDecrypt终极指南:安全高效解密微信聊天记录的完整方案
  • 避坑指南:STM32的OSCIN/OSCOUT引脚配置为GPIO后,如何保证系统时钟稳定运行?
  • 桥接模式和NAT模式
  • 2026北京婚姻纠纷找律师事务所:专业靠谱怎么选?这份参考请收好 - 产业观察网
  • 【逻辑设计】卡诺图化简实战 | 从真值表到最简电路 | 利用无关项优化设计
  • 北京翡翠变现攻略:翡翠手镯、挂件回收,专业鉴定无隐形扣费 - 奢侈品回收测评
  • AGV机器人48V锂电池选型指南:特种定制能力决定供应商质量 - 新闻快传
  • 从模拟信号到云端可视化:光敏电阻物联网项目全链路实践
  • 量子通信与6G融合:探索未来通信新维度
  • 新闻发布行业核心服务商技术盘点 多维度拆解适配逻辑 - 奔跑123
  • AntiDupl.NET:智能图片去重工具,轻松释放硬盘空间
  • 谷歌发布AI语音听写功能Rambler,集成Gboard支持语码切换,今夏率先登陆部分安卓机
  • 《Java面试85题图解版(三)》上篇:高阶架构设计篇
  • 【亲测门店】兴化市别墅品牌对比,哪家更靠谱? - 花开富贵112
  • 运维人会被 AI 淘汰吗?未来的机房,可能连值班都不需要了
  • 探索Taotoken模型广场如何帮助我根据任务选择合适的大模型
  • 2026年餐饮品牌扩张发展背景下的适配性餐饮SaaS服务商专业分析与推荐 - 产业观察网
  • 仓储物流机器人48V电池定制周期多久?哪家厂家值得合作?——以浩博电池为例 - 新闻快传
  • 视频硬字幕提取:本地化AI如何破解87种语言的视频转录难题
  • 别只盯着张雪峰的公关团队了,2026年品牌公关的胜负手其实是它
  • ESP32-S3物联网开发实战:从Bootloader到云端数据交互全流程指南
  • Photoshop图层批量导出终极指南:10倍速免费脚本让你的设计工作流飞起来
  • 鸣潮自动化工具终极指南:3步解放双手的智能助手
  • 如何让dnSpyEx完美支持.NET 8调试?完整兼容性解决方案指南
  • 为小型创业团队搭建统一的大模型开发与测试环境
  • 2026年5月辣椒酱生产厂家最新推荐:复合调味酱、食用油产品优选指南 - 海棠依旧大