大厂4年经验Java面试题深入解析(10道,排版优化版) 大厂 4 年经验 Java 面试题深入解析10 道这篇文章不是面向校招也不是面向只会背八股的初级候选人而是针对已经有 4 年左右实际项目经验、准备冲击大厂的 Java 工程师。大厂面试更看重你是否能把基础原理、线上问题、设计取舍和工程落地讲透。所以这 10 道题我会按题目、关键点、标准答案、可能追问四个模块展开。页面上只展示正常标题特殊标记保留在 HTML 源码注释中方便后续程序继续识别。第 1 题说一下 synchronized、ReentrantLock、CAS 三者分别适合解决什么问题题目说一下 synchronized、ReentrantLock、CAS 三者分别适合解决什么问题如果线上高并发场景下锁竞争严重你会怎么分析和优化关键点悲观锁和乐观锁的适用边界。synchronized 在 JDK 1.6 之后的锁升级机制。ReentrantLock 的可中断、可超时、公平锁、条件队列等能力。CAS 的 ABA 问题、自旋开销和适用前提。如何从线程状态、锁持有时间、热点代码路径分析竞争瓶颈。标准答案synchronized适合临界区清晰、代码块级同步、对功能要求不复杂的场景。它是 JVM 原生语义使用简单可读性高在低到中等竞争下性能已经足够。ReentrantLock适合需要更强控制能力的场景例如可中断获取锁、定时尝试加锁、多个条件队列、排查死锁或实现公平策略。它本质上基于 AQS扩展性更强。CAS适合无锁化、短时间原子更新的场景例如计数器、状态位切换、队列头尾指针更新。前提是冲突不能过高否则自旋失败成本会放大。线上锁竞争严重时先确认问题是锁粒度过大、持锁时间过长、热点对象竞争还是不合理的串行化逻辑。可以通过 Arthas、jstack、JFR、async-profiler 观察 BLOCKED 线程、热点方法和锁等待时间。优化时优先考虑缩小临界区、拆分锁、把串行逻辑改成分段并行、把粗粒度对象锁改成更细粒度结构或者直接使用并发容器、LongAdder、无锁队列等替代方案。可能追问偏向锁、轻量级锁、重量级锁分别解决什么问题LongAdder 为什么比 AtomicLong 在高并发下性能更好AQS 的核心数据结构是什么第 2 题你如何理解线程池参数线上线程池应该怎么设题目你如何理解 corePoolSize、maximumPoolSize、workQueue、keepAliveTime 等线程池参数如果一个接口 RT 飙高并伴随线程堆积你会如何调整关键点线程池创建线程和入队的执行顺序。CPU 密集型和 IO 密集型任务的配置差异。无界队列导致的问题。拒绝策略与系统降级的关系。动态监控池活跃度、队列长度、任务耗时的重要性。标准答案线程池不是参数背诵题核心是理解任务模型。提交任务时通常先补齐核心线程再尝试入队队列满了才扩到最大线程数最后触发拒绝策略。CPU 密集型任务一般线程数接近 CPU 核数IO 密集型任务可以适当放大但不能脱离下游资源能力否则只是把堵塞转移到数据库、Redis 或 RPC 下游。线上不建议默认使用无界队列。无界队列会掩盖流量突刺最终把问题拖成内存膨胀、请求超时和 Full GC而不是第一时间暴露容量边界。如果 RT 飙高并伴随线程堆积先看是任务变慢还是流量激增。任务变慢要继续分析慢 SQL、远程调用、锁等待、下游超时流量激增则要限流、隔离、快速失败而不是一味加线程。线程池需要业务命名、指标监控和分场景隔离不能所有任务共用一个池。否则某个慢任务类型会把整个应用的异步能力拖垮。可能追问为什么阿里规范不建议直接使用 Executors 创建线程池CallerRunsPolicy 在什么场景下反而是比较好的策略线程池队列积压时如何判断是扩容还是降级第 3 题说一下 JVM 内存结构、垃圾回收器选型以及 Full GC 排查思路。题目说一下 JVM 内存结构、垃圾回收器选型以及 Full GC 排查思路。如果线上频繁 Full GC但堆看起来并不大你会怎么判断根因关键点程序计数器、虚拟机栈、本地方法栈、堆、方法区的职责。新生代、老年代、对象晋升、分配担保。CMS、G1、ZGC 的适用场景。内存泄漏、对象存活过长、晋升过快、元空间膨胀等不同问题类型。jstat、jmap、MAT、GC 日志分析方法。标准答案JVM 内存结构是基础但面试更关注你有没有线上经验。堆主要放对象实例栈主要放栈帧和局部变量方法区承载类元数据和常量等内容。GC 选型不能只说“G1 适合大堆”。要结合停顿目标、堆大小、对象生命周期和业务 RT 要求。4 年经验候选人至少要能讲清为什么项目从 CMS 切到 G1或者为什么没有切。频繁 Full GC 时不能只看堆总量要看 Old 区增长速度、晋升失败、Humongous 对象、元空间、直接内存和引用链持有关系。很多问题并不是“堆不够”而是对象回不掉。排查时通常先看 GC 日志确认 Full GC 触发原因再通过 jmap 导堆、MAT 看 dominator tree 和大对象路径如果是短时流量问题再结合应用日志和监控看是否有缓存击穿、批量加载、消息堆积。如果是元空间导致 Full GC要重点看动态代理、Groovy/Janino、频繁类加载和自定义类加载器泄漏不要只盯着 Java 堆。可能追问对象什么时候会进入老年代G1 的 Region、Remembered Set、Mixed GC 是怎么工作的MAT 里看到一个大 Map 持有大量对象你接下来怎么判断是不是泄漏第 4 题Spring 事务为什么会失效你在线上遇到过哪些坑题目Spring 事务为什么会失效你在线上遇到过哪些常见事务坑分别是怎么定位和修复的关键点AOP 代理机制是事务生效的前提。同类内部调用、private 方法、final 方法的代理问题。默认回滚规则只覆盖 RuntimeException。事务边界与 RPC、MQ、异步线程的关系。长事务、批量事务、锁范围扩大的风险。标准答案Spring 声明式事务本质上依赖代理拦截所以最常见的失效场景是同类内部方法调用绕过代理导致Transactional根本没有被织入。第二类坑是异常处理。默认情况下只有RuntimeException和Error才会触发回滚如果你捕获异常后吃掉了或者抛出的是受检异常却没显式配置回滚规则事务也可能提交。第三类坑是边界错位。例如在事务里调用远程接口、发 MQ、做长时间计算会导致数据库连接长时间占用放大锁持有范围严重时引发雪崩。线上定位通常会结合 SQL 执行时间、事务日志、慢查询、死锁日志和业务代码调用路径一起看。很多所谓“事务不生效”其实是事务开得太大或者异常处理方式有问题。修复时要么调整服务拆分和代理调用路径要么把事务边界缩到真正需要原子性的数据库操作上并通过本地消息表、最终一致性方案替代跨系统强事务。可能追问事务传播行为里 REQUIRED、REQUIRES_NEW、NESTED 的区别是什么为什么不建议把事务包住整个 for 循环批处理分布式事务你做过哪些方案第 5 题MySQL 索引为什么会失效你如何判断 SQL 需要怎么改题目MySQL 索引为什么会失效如果一个查询明明建了联合索引但执行计划仍然很差你会怎么分析关键点BTree 索引结构与回表原理。最左前缀原则和范围查询对后续列的影响。函数操作、隐式类型转换、模糊查询、低区分度列导致的失效。执行计划里 type、rows、filtered、extra 的含义。索引设计要结合查询模式而不是只看字段频率。标准答案索引失效不是单一原因常见场景包括条件没命中最左前缀、对索引列做函数运算、类型不匹配引发隐式转换、like %xx无法利用前缀有序性以及优化器判断全表扫描成本更低。联合索引设计必须围绕高频查询路径。字段顺序通常要综合考虑过滤性、排序、分组和覆盖查询而不是简单把“区分度最高的字段放最前面”。如果执行计划差先看explain再结合show warnings、实际 SQL 参数、表统计信息、数据分布确认是不是优化器误判。很多线上问题是测试数据太少看不出真实代价。SQL 优化不是只会加索引。必要时要改写 SQL、分离冷热数据、避免大分页、引入冗余字段或预聚合表把复杂实时查询改成离线或异步计算。面试里如果你能讲到“索引命中不代表一定快扫描行数和回表成本才关键”说明你的 SQL 调优视角是成熟的。可能追问覆盖索引为什么能提升性能什么情况下 order by 能利用联合索引深分页除了延迟关联还有哪些优化方式第 6 题Redis 在缓存设计里最容易出什么问题题目Redis 在缓存设计里最容易出什么问题如果线上同时出现缓存穿透、击穿、雪崩你会怎么分层处理关键点缓存穿透、击穿、雪崩的定义与区别。布隆过滤器、空值缓存、互斥锁、逻辑过期等方案。热点 key 识别和多级缓存思路。缓存一致性设计优先级和可接受的不一致窗口。大 key、热 key、慢查询、持久化对 Redis 稳定性的影响。标准答案缓存穿透是请求根本不存在的数据击穿是热点 key 恰好失效导致大量请求打到数据库雪崩则是大量 key 同时失效或 Redis 集群异常导致请求整体回源。穿透一般用布隆过滤器、参数校验、空值短 TTL 缓存解决击穿一般用互斥重建、逻辑过期、后台刷新解决雪崩则要做 TTL 打散、多级缓存、限流降级、集群高可用和业务兜底。缓存一致性不能只说“先删缓存再写数据库”。你要明确是读多写少、是否允许短暂不一致、是否需要消息补偿以及删缓存失败后的重试机制。Redis 本身也会出问题比如 big key 导致网络阻塞热 key 导致单分片打满AOF 重写或 RDB 持久化带来抖动。这些都需要监控命中率、慢日志、网络吞吐和实例 CPU。更成熟的回答是把 Redis 放回系统设计里讨论而不是当成“背概念工具”。可能追问延时双删为什么不能保证强一致布隆过滤器为什么会有误判热点 key 很集中时除了加本地缓存还能怎么做第 7 题分库分表之后哪些问题最难处理题目分库分表之后哪些问题最难处理除了路由规则你觉得真正影响系统复杂度的点有哪些关键点分片键选择与数据倾斜。跨库分页、跨库排序、聚合统计的代价。全局唯一 ID、扩容迁移、一致性和事务问题。业务侧是否接受查询能力下降。中间件方案和业务侵入式方案的取舍。标准答案分库分表最难的不是“写个路由器”而是承受由它带来的查询能力下降、运维复杂度上升和数据迁移成本。尤其是二次扩容往往比第一次拆分更痛。分片键选择决定了系统上限。如果按用户 ID 分但业务高频查询是按订单状态和时间范围扫单那后续很多查询都要跨分片聚合性能和开发成本都很差。跨库事务、全局 ID、分布式唯一约束、数据修复和历史数据回迁都需要提前设计。很多团队只解决“写进去”没解决“怎么查、怎么改、怎么扩”。当数据量还没逼到必须拆分时优先通过索引优化、冷热分离、归档、读写分离、表结构优化提升容量别过早上分库分表。真正成熟的回答应该体现你知道分库分表是业务和架构共同承担复杂度而不是数据库层的魔法开关。可能追问你们为什么选择这个分片键有没有踩过数据倾斜的坑扩容时怎么做双写或数据迁移校验跨库分页查询你会怎么设计第 8 题一次线上接口 RT 突然升高你的完整排查路径是什么题目一次线上接口 RT 突然升高但错误率不高。你会如何在最短时间内完成定位请给出一个完整排查路径。关键点先看范围是单机、单接口、单机房还是全链路问题。区分 CPU 打满、线程阻塞、GC 抖动、数据库慢、Redis 慢、下游超时。监控、日志、线程栈、火焰图、链路追踪联动使用。先止血再定位避免一边排查一边扩大故障。输出可复盘的方法论而不是零散工具名。标准答案我会先判断故障范围是某个接口、某个实例、某个可用区还是全站问题。这个步骤决定了是代码问题、机器问题还是下游依赖问题。然后看四类核心指标应用层 RT/QPS/错误率JVM 的 GC/堆/线程系统层 CPU/内存/负载/网络依赖层的 DB、Redis、MQ、RPC 耗时。先建立时间线再缩小嫌疑范围。如果线程堆积就抓线程栈看是否卡在锁、SQL、网络 IO 或某段业务代码如果 CPU 飙高就看火焰图如果 RT 高但 CPU 不高往往是等待型问题重点查下游超时或连接池耗尽。真正好的排查不是“什么都查”而是先做止血动作例如摘流量、限流、降级、回滚再继续做根因定位避免故障窗口扩大。最后要能沉淀成预案如何提前监控、如何自动扩容、如何加熔断隔离、如何优化慢依赖而不是只会事后救火。可能追问如果 CPU 不高但线程很多都在 WAITING你会优先怀疑什么Arthas 里你最常用哪几个命令一次故障复盘文档你通常会怎么写第 9 题设计一个高并发秒杀系统你重点解决哪些问题题目设计一个高并发秒杀系统你重点解决哪些问题请不要只回答“用 Redis 扣库存”。关键点流量削峰、限流、验证码、预约、静态化。库存一致性、超卖控制、幂等处理。异步削峰、MQ、最终一致性。热点数据、本地缓存、分片和隔离。风控、防刷、监控和降级策略。标准答案秒杀的关键不是“扣库存”这一个动作而是从入口到下游全链路都要控流。入口要做静态化、CDN、验证码、预约、前置限流尽量把无效请求挡在最外层。库存处理要兼顾性能和一致性。常见做法是 Redis 预扣减加 MQ 异步下单但要明确失败补偿、重复消费、订单超时回补、消息堆积时的处理策略。数据库层不能承受所有瞬时流量因此需要异步化和削峰。真正的大厂实现里库存、资格、幂等、风控、订单通常不是一个点状方案而是多层防线。系统设计时要考虑热点隔离、服务降级、活动开关、黑白名单、防刷策略以及如何快速熔断某些失败链路避免把核心交易系统拖垮。如果你能把“高并发”回答成“容量规划 一致性设计 稳定性治理”的组合而不是 Redis 八股就更像有真实经验的人。可能追问Redis 预扣成功但下单失败库存怎么补如何防止用户重复下单如果 MQ 积压严重你优先保障什么功能第 10 题如果让你做一次老系统性能优化你会怎么分阶段推进题目如果让你接手一个老系统做性能优化你会怎么分阶段推进如何避免“优化了很多点但整体收益很小”的情况关键点先建立基线和瓶颈分布再决定优化优先级。区分单点优化和系统性优化。从慢 SQL、缓存、线程模型、序列化、网络调用、对象创建、GC 等层面找收益点。性能优化需要压测验证和回归保障。优化目标应绑定业务指标而不是只看单机 TPS。标准答案我会先拿到现状基线包括核心接口 RT、TP99、QPS、错误率、机器资源占用、GC 情况和依赖耗时分布。没有基线的优化基本都不专业。然后做瓶颈拆解区分是数据库瓶颈、缓存命中率问题、线程模型问题、代码热点、序列化开销还是远程调用链路过长。优先做收益大、风险可控、回滚简单的项。优化不能只盯代码。很多时候真正的收益来自索引改造、缓存分层、批量化、异步化、连接池参数、对象复用和网络协议优化。每一轮优化都要通过压测或灰度验证收益并观察副作用例如内存上涨、缓存不一致、下游压力转移、长尾延迟恶化。只看平均 RT 是不够的。最终目标是把优化结果映射回业务指标比如峰值承载提升、资源成本下降、超时率下降而不是停留在“某段代码快了 20%”这种局部结论。可能追问你做过最有价值的一次性能优化是什么为什么很多系统平均 RT 下降了但用户体验没有明显改善性能优化和稳定性治理之间你会怎么排优先级总结如果你准备的是大厂 4 年经验 Java 岗位这类题目已经不会满足于“概念背诵”而是会继续追问你是否经历过真实流量、线上故障、容量瓶颈和架构取舍。建议你复习时不要只背答案而是把每道题都补充成“原理 项目场景 故障案例 优化动作 最终结果”五段式。能讲到这个层次面试官会明显感受到你不是只会看面经而是真的做过事。