前言
一、为什么场景题在 Java 面试中越来越重要?
现在的 Java 面试早已不是'背概念、写算法'就能通关——面试官更看重'你能不能解决实际工作中的问题'。比如'系统频繁 Full GC 怎么排查?''秒杀场景怎么防止超卖?''分布式系统怎么保证接口幂等性?',这些场景题直接对应工作中的核心痛点,能看出候选人的'实战能力'和'技术思维'。
很多人面对场景题时,要么'答不到重点'(比如只说'用 Redis',不说具体方案),要么'逻辑混乱'(东说一句缓存,西说一句锁,没条理)。本文就针对多个 Java 面试高频场景题,拆解'问题分析→技术选型→实现方案→注意事项'的完整答题框架,帮你形成'有逻辑、有细节、有深度'的回答。
Java 面试高频场景题解析
1. 场景题 1:系统频繁发生 Full GC,该怎么排查和解决?
这是中高级开发岗必考题,考察'JVM 实战调优能力',不能只说'加内存',要体现'排查流程'。
答题框架(先排查,后解决):
-
第一步:确认是否真的是 Full GC 频繁
- 启动参数加
-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:gc.log,生成 GC 日志; - 用
jstat -gc 进程 ID 1000 10实时查看 GC 统计(1 秒一次,共 10 次),重点看 FGC(Full GC 次数)和 FGCT(Full GC 总时间)——比如 1 分钟内 FGC 超过 5 次,且每次耗时超过 1 秒,就是'频繁 Full GC'。
- 启动参数加
-
第二步:分析 Full GC 频繁的原因(常见 3 类)
-
**① 老年代内存不足:**通常由内存泄漏或堆内存配置过小导致。
-
**② 大对象直接进入老年代:**JVM 默认'超过新生代剩余空间的大对象'会直接进老年代(比如 100MB 的 byte 数组),要是频繁创建大对象(比如每次接口请求都生成大的 Excel 临时文件),老年代很快满。
-
**③ 永久代 / 元空间溢出:**JDK 8 前是永久代,后是元空间。JDK 8 前永久代存类信息、常量池,要是频繁动态生成类(比如用 CGLIB 代理,没控制代理类数量),会导致永久代满触发 Full GC;JDK 8 后元空间用本地内存,默认无大小限制,但要是配置了
-XX:MaxMetaspaceSize且太小,也会溢出。 -
用
jmap -histo:live 进程 ID > heap.txt查看老年代存活对象,看是否有大对象(比如几 MB 的 List、大量未释放的线程池); -
用
jhat堆 dump 文件或 JVisualVM 分析对象引用链,看是否有'内存泄漏'(比如静态集合持有大量对象,一直不释放)。 -
**举例:**项目中用
static List<User> userList存用户数据,每次查询都 add 进去,没清理,导致 userList 越来越大,老年代满了频繁 Full GC。
-
-
第三步:针对性解决
-
**修复代码:**比如静态集合用完后调用 clear(),或用弱引用集合(WeakHashMap);之前项目用 static Map 存缓存,没设置过期时间,改成 Guava Cache 并设置 maximumSize 和 expireAfterWrite,自动清理过期数据。
-
调整 JVM 参数:
-XX:PretenureSizeThreshold=10485760(10MB),让小于 10MB 的对象先进新生代,避免直接进老年代;优化代码,比如大 Excel 文件分批次生成,避免一次性创建大对象。 -
**JDK 8 前:**调大永久代
-XX:PermSize=256m -XX:MaxPermSize=512m; -
**JDK 8 后:**调大元空间
-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m,并检查动态生成类的逻辑,避免重复生成。 -
**加分补充:**结合实际案例说'我之前项目中,发现 FGC 每 5 分钟一次,用 jmap 查看堆快照,发现有个线程池的核心线程数设成了 1000,且每个线程都持有数据库连接,导致大量线程对象在老年代,改成核心线程数 20,FGC 频率降到 1 小时一次'——有案例更显真实。
-


