← 每日面试题 学习看板

Java 后端模拟面试题

面试题/高阶题目/2026-10-17-性能优化.md

Java 后端模拟面试题

日期:2026-10-17

总题数:1 题(默认单题)

方向:性能优化


R1 性能优化 | 难度:高阶

题目

场景:某电商订单查询服务(8C16G,JDK17 + Spring Boot),大促期间 QPS 从 2000 涨到 6000。监控发现:

3 个问题:

  1. (定位) sys 高 + load 28 + 大量线程 BLOCKED —— 你判断瓶颈是什么?给出完整定位路径(要落到具体命令与指标)。
  2. (分析/优化) 针对该瓶颈给出至少 3 个优化手段并说明预期效果(锁粒度、无锁化、线程模型三层至少各一)。
  3. (保障) 上线后如何建立监控与回归防护,让同类问题提前暴露?

原始回答

1首先根据已知的信息大量blocked以及sys高,应该是锁导致的线程阻塞;排查可以查看skywalking和接口rt监控监控确认具体的接口和出现缓慢的节点位置; 通过jstack导出当前线程栈,查看blocked的线程情况; 2 基于热点更新是一个计数器和一个synchronized保护的缓存更新,检查下为什么会有那么多内容进行缓存刷新,怀疑是缓存击穿,使用非常规数据去攻击缓存导致的;可以对访问的账号 ,ip,区域进行检查,看是否是某些账户的恶意攻击;对其进行封禁,或者策略处理,另外后续可以增加布隆过滤器对不存在的key进行过滤,前置进行拦截; 如果是正常缓存,那么应该就是设计问题,要么缓存个活期时间太短,要么大量不同数据逐个刷新导致,可以做缓存预热,缓存保护,防止问题; 上线后增加关于缓存的管理,以及做横向扩容qps太高了要降低单机负载

点评

得分:2.5 / 5

优点:

  1. 第一反应锁定"锁竞争 → 线程 BLOCKED"方向正确,sys 高与阻塞的关联判断到位
  2. 有排查路径意识(接口 RT 监控 → jstack 线程栈),jstack 查 BLOCKED 是对路的

不足:

  1. 定位链太浅:没答"为什么是 sys 高"——锁竞争 → 线程 park/unpark → futex 系统调用 → 内核态开销 → sys 飙高,这条因果链是本题核心;量化手段也缺(pidstat -w 看 cswch、vmstat 看 cs/r、top -Hp 定位热点线程、perf top、arthas thread -n)
  2. 忽略题面强信号 AtomicLong:高并发 CAS 自旋 + 伪共享(false sharing)是 sys/user 双高的另一半原因,回答完全没提
  3. 方向跑偏:把假设带到"缓存击穿/恶意攻击",缺乏前置证据支撑(题面没给缓存命中率异常)
  4. 优化手段没答到点:题目明确要求"锁粒度 / 无锁化 / 线程模型"三层各一,回答全落在缓存侧

补充:详见下方「完整讲解」。

完整讲解

一、根因定位:为什么会 sys 高 + load 高 + BLOCKED

先建立因果链,再谈工具:

高并发争抢同一个 monitor
        │
        ▼
synchronized 膨胀为重量级锁 → 未获锁线程 ObjectMonitor::enter
        │
        ▼
线程 park/unpark → JVM 调用 futex 系统调用(内核态)
        │
        ▼
大量上下文切换(cs 暴增)+ 可运行队列变长
        │
        ▼
CPU sys 占比飙升 + load average 飙升

关键认知:

定位路径(落到命令与指标):

步骤命令看什么
1. 确认 CPU/负载构成top → 1(分核)、uptime%sy 高、load 与核数比
2. 上下文切换速率vmstat 1 / pidstat -w 1 -p <pid>cs(context switch/s)、cswch/s(自愿切换)暴增
3. 定位热点线程top -Hp <pid> → 转十六进制 printf '%x' <tid>找到吃 CPU 的线程
4. 线程栈深挖jstack <pid> > stack.txt、arthas thread -b大量 BLOCKED (on object monitor) 指向同一地址;thread -b 直接给"阻塞其他线程的元凶"
5. 锁竞争量化arthas monitor -c 5 com.xxx.Class method、JFR(-XX:StartFlightRecording)锁事件阻塞次数/平均阻塞耗时
6. 内核态采样perf top -p <pid>、perf record -gfutex、__lll_lock_wait、sys_futex 占比
7. 应用层链路SkyWalking / 接口 RT 监控确认慢在哪个接口、哪个节点(题中回答已覆盖)
题中回答的 skywalking + jstack 只是第 4、7 步;缺了第 2、3、5、6 步,所以无法量化"锁竞争 → 系统调用"的因果。

二、优化手段(三层各一)

层手段预期效果
锁粒度① 缩小临界区,把非共享操作移出 synchronized;② 读写分离:缓存刷新用 volatile + 不可变快照替换(读无锁,写整体替换引用)临界区变短 → 锁持有时间下降 → 阻塞线程数骤减 → cs 下降
无锁化① AtomicLong → LongAdder(Striped64 分段 CAS,把竞争分散到多个 cell);② 缓存行填充 @Contended(需 -XX:-RestrictContended)解决伪共享;③ 单写者模式CAS 失败自旋大幅减少;消除 cache line bouncing → user/sys 双降,吞吐提升
线程模型① 同步刷新 → 异步批量刷新(定时任务 / single-flight 合并重复刷新请求);② 缓存刷新交给独立单线程(single-writer),业务线程只读;③ 若计数无需强一致,改为本地聚合 + 定时刷库从"每请求争锁"变"批量/单写者",争抢源消失

LongAdder 原理:AtomicLong 的 value 是单点 volatile,所有线程 CAS 同一地址;LongAdder 维护 base + Cell[],线程按 threadLocalRandomProbe 散列到不同 cell,冲突时扩容,求和时才汇总。8 核下写吞吐可提升数倍。

三、监控与回归防护

  1. 常驻指标:sys%、cs/s、cswch/s、load1/5/15、锁阻塞时间(ThreadMXBean.getThreadInfo 的 blockedCount/blockedTime、JFR 锁事件)、LongAdder 所在监控项
  2. 告警阈值:cs/s 突增、sys% > 40%、jstack BLOCKED 线程数 > X 时触发
  3. 压测回归:上线前用压测(JMeter/Gatling)复现 6000 QPS,观测 cs/sys 曲线与 P99;设性能基线卡点
  4. 可观测:arthas monitor/watch 常驻排查;JFR 采样回放;SkyWalking 慢接口拓扑
  5. 架构兜底:无状态化 + 横向扩容降低单机 QPS;热点计数下沉到 Redis/本地分片;必要时限流保护

面试总结

表现汇总

轮次方向难度表现得分
R1性能优化高阶锁竞争方向判断正确;但根因链、量化定位、三层优化均缺位,方向跑偏到缓存2.5 / 5

强项

  1. 锁竞争/线程阻塞的直觉判断准确
  2. 有基本的排查工具链意识(监控 + jstack)

待提升点

  1. 根因链表达:能从现象(sys 高/load 高/BLOCKED)倒推到内核机制(futex/上下文切换)
  2. 量化定位:掌握 pidstat -w / vmstat / perf / arthas thread -b 等工具链
  3. 无锁化与伪共享:LongAdder、@Contended、cache line bouncing
  4. 审题:抓住题面给的强信号(AtomicLong),不要被无关假设带偏

建议


会话全文记录

面试官:出题 R1(性能优化 · 高阶),3 个子问题,命中上述场景。

候选人回答(原文保留):

1首先根据已知的信息大量blocked以及sys高,应该是锁导致的线程阻塞;排查可以查看skywalking和接口rt监控监控确认具体的接口和出现缓慢的节点位置; 通过jstack导出当前线程栈,查看blocked的线程情况; 2 基于热点更新是一个计数器和一个synchronized保护的缓存更新,检查下为什么会有那么多内容进行缓存刷新,怀疑是缓存击穿,使用非常规数据去攻击缓存导致的;可以对访问的账号 ,ip,区域进行检查,看是否是某些账户的恶意攻击;对其进行封禁,或者策略处理,另外后续可以增加布隆过滤器对不存在的key进行过滤,前置进行拦截; 如果是正常缓存,那么应该就是设计问题,要么缓存个活期时间太短,要么大量不同数据逐个刷新导致,可以做缓存预热,缓存保护,防止问题; 上线后增加关于缓存的管理,以及做横向扩容qps太高了要降低单机负载

面试官点评:得分 2.5/5。方向正确但深度不足,遗漏 AtomicLong 强信号,三层优化未答(详见上方点评与完整讲解)。

说明:本次会话按daily-interview-question新默认(单题)只抽取 1 题。


生成时间:2026-10-17 · 由 daily-interview-question 维护