Java基础核心能力面试:高频问题、回答框架、公司侧重点
本章聚焦 Java 基础核心能力的高频面试题,覆盖 HashMap、JVM 内存模型、线程池、并发容器、反射 等核心知识点。针对每个问题提供结构化回答框架,帮助你在 60–100 字内精准表达,同时标注大厂考察侧重点与常见追问陷阱。
高频问题速览
| 问题 | 核心考察点 | 难度 |
| HashMap 的底层原理与扩容机制 | 数据结构、哈希冲突、负载因子、红黑树 | ⭐⭐⭐ |
| JVM 内存区域与溢出场景 | 堆、栈、方法区、直接内存、OOM 诊断 | ⭐⭐⭐⭐ |
| 线程池核心参数与拒绝策略 | corePoolSize、workQueue、饱和策略、动态调整 | ⭐⭐⭐⭐ |
问答卡片 1:HashMap 底层原理与扩容机制
| 面试问题 | 请详细说说 HashMap 的底层数据结构、put 流程以及扩容机制。 |
| 考察点 | 数据结构理解(数组+链表/红黑树)、哈希冲突解决、负载因子作用、扩容条件与rehash过程、树化阈值 |
| 回答框架 | ① 底层:数组 + 链表/红黑树,计算 hash 确定桶位;② put:hash → 定位 → 插入/替换 → 判断是否树化;③ 扩容:size>threshold 时扩容2倍,rehash 重新分布,1.8 优化为高低位迁移。 |
| 示例回答 | “HashMap 底层是数组+链表/红黑树。put 时先通过 key 的 hash 确定桶位,若冲突则用尾插法加入链表,链表长度≥8 且数组≥64 时转红黑树。扩容发生在 size>threshold 时,容量翻倍,元素rehash 后均匀分布,1.8 通过高位运算减少移动次数。” |
| 可能追问 | 为什么负载因子默认0.75?红黑树退化为链表的条件?1.7 与 1.8 扩容区别? |
| 避坑提醒 | 不要只说“数组+链表”,要主动提到“红黑树”和“树化阈值”;避免说“rehash 重新计算 hash”,实际是高位索引重新分配。 |
问答卡片 2:JVM 内存区域与溢出场景
| 面试问题 | 请说明 JVM 运行时数据区的划分,哪些区域可能发生 OOM?请结合实际场景分析。 |
| 考察点 | 内存区域概念(堆、栈、方法区、程序计数器、本地方法栈)、OOM 产生原因、参数配置、对象分配策略 |
| 回答框架 | ① 堆:存放对象实例,OOM 常见于大对象/内存泄漏;② 栈:存放局部变量,OOM 常见于递归过深(StackOverflow);③ 方法区:类元数据溢出(永久代/元空间);④ 直接内存(NIO 相关)。 |
| 示例回答 | “堆区 OOM 常因对象无法 GC 导致,例如缓存未清理;栈 OOM 因递归深度过大或线程数过多;方法区 OOM 多见于动态生成大量类(如 CGLIB 代理)。实际调优时用 jmap、jstat 分析,结合 -Xms、-Xmx 和 -XX:MaxMetaspaceSize 控制。” |
| 可能追问 | 如何定位堆外内存泄漏?字符串常量池在哪个区域(1.7/1.8)? |
| 避坑提醒 | 不要混淆 StackOverflowError 和 OutOfMemoryError;方法区在 1.8 改为元空间后使用本地内存,需注意参数差异。 |
问答卡片 3:线程池核心参数与拒绝策略
| 面试问题 | 线程池的核心参数有哪些?拒绝策略分别适用于什么场景?如何动态调整线程池大小? |
| 考察点 | corePoolSize、maximumPoolSize、keepAliveTime、workQueue、饱和策略、线程工厂、动态调整原理(ThreadPoolExecutor 提供的 set 方法) |
| 回答框架 | ① 核心参数:core、max、keepAlive、队列类型(如 LinkedBlockingQueue)、拒绝策略;② 四种策略:Abort(抛异常)、CallerRuns(调用者执行)、Discard(丢弃)、DiscardOldest(丢弃等待最久);③ 动态调整:通过 setCorePoolSize/setMaximumPoolSize 实现,注意结合监控。 |
| 示例回答 | “CPU 密集型设置 core=CPU+1,IO 密集型设置 core=CPU*2。队列建议使用有界队列,防止 OOM。拒绝策略优先使用 CallerRuns 降低提交速度。动态调整时通过 JMX 或 Spring 配置中心动态修改参数,需配合监控统计活跃线程数。” |
| 可能追问 | 如何优雅关闭线程池?shutdown 和 shutdownNow 区别?submit 和 execute 的区别? |
| 避坑提醒 | 不要使用无界队列(如 Executors.newFixedThreadPool 默认 LinkedBlockingQueue 无界,可能撑爆内存);拒绝策略抛出异常要全局处理。 |
💡 面试加分提醒: 回答时主动结合“生产环境调优案例”,例如“我曾在支付系统里将线程池队列从无界改为有界,并设置 CallerRuns 策略,避免雪崩”。大厂面试官尤其看重理论与实践的结合。
⚠️ 常见失分点: 只背概念不举实际场景;对 1.8 之后的 HashMap 变化不熟悉;线程池参数含义混淆(如 core 和 max 颠倒)。务必用具体数字和代码辅助说明。