Java 面试高频题——集合、JVM、并发场景题一次说清

发布时间:2026/6/27 7:00:41

Java 面试高频题——集合、JVM、并发场景题一次说清 金三银四跳槽季Java 后端面试其实有规律可循。这篇把最高频的考点梳理一遍每道题说清楚「怎么答」和「为什么」。一、集合框架1. HashMap 底层原理面试官想问你知道 HashMap 怎么存数据的吗线程安全吗JDK 7数组 链表头插法 JDK 8数组 链表/红黑树尾插法 put 流程 计算 key 的 hash → 定位数组下标 → 如果没冲突直接放 → 有冲突挂链表超过8个转红黑树 → 容量超过负载因子75%就扩容 get 流程 计算 hash → 定位下标 → 比较 key 的 equals → 链表/红黑树中查找关键要说的点为什么转红黑树链表太长查询慢O(n)→O(logn)为什么负载因子是0.75空间和时间的平衡HashMap 线程不安全 → 多线程 put 可能死循环JDK7头插法导致线程安全用ConcurrentHashMap分段锁/CASsynchronized2. ArrayList vs LinkedListArrayListLinkedList底层数组连续内存双向链表随机查✅ O(1)❌ O(n)尾部增删✅ O(1)✅ O(1)中间插入❌ O(n) 要移动元素✅ O(1) 改指针内存连续省内存每个节点多存前后指针一句话查多用 ArrayList改多用 LinkedList。3. ConcurrentHashMap 怎么保证线程安全JDK 7分段锁 Segment继承 ReentrantLock 默认16段理论上16个线程同时写 JDK 8CAS synchronized锁链表头节点或红黑树根节点 并发度更高粒度更细要说的重点JDK8 比 JDK7 并发更好而且 synchronized 在 JDK8 已经优化过不像以前那么重了。二、JVM1. 内存区域划分线程私有 程序计数器 → 当前线程执行到哪一行 虚拟机栈 → 局部变量、方法调用StackOverflowError 本地方法栈 → native 方法 线程共享 堆 → 对象实例OOM 重灾区 方法区 → 类信息、常量、静态变量2. GC 垃圾回收哪些对象是垃圾从 GC Root 出发不可达的对象。GC Root 有哪些 - 栈帧中的局部变量引用的对象 - 静态变量引用的对象 - 常量引用的对象 - native 方法引用的对象垃圾回收算法算法原理适用标记-清除标记垃圾→直接清有碎片问题标记-复制分两块活的对象复制到另一块新生代朝生夕死标记-整理标记→存活对象往一边挪老年代分代回收新生代Eden Survivor8:1 → Minor GC复制算法 老年代存活多次的对象 → Major GC标记-整理3. 频繁 Full GC 怎么排查jstat -gcutil pid看各个代的使用率jmap -histo pid看哪些对象占的内存大jstack pid看是否有死锁或线程阻塞结合代码分析是不是 new 了大量对象没释放是不是一次性查了太多数据三、并发编程1. synchronized 原理synchronized 在 JVM 层面是通过 Monitor监视器锁实现的 JDK 1.6 以后做了锁升级 无锁 → 偏向锁只有一个线程竞争 → 轻量级锁CAS 自旋少量线程 → 重量级锁操作系统互斥量锁升级是为了优化大部分场景下锁竞争不激烈没必要一上来就用重量级锁。2. ThreadLocal 内存泄漏问题ThreadLocal 适合每个线程需要自己的一份数据副本比如数据库连接、用户登录信息。内存泄漏原因ThreadLocalMap 的 key 是弱引用WeakReference 如果 key 被 GC 回收了value 还在 → value 永远访问不到 → 内存泄漏解决用完一定要调用remove()清理。3. 线程池参数怎么设置// CPU 密集型corePoolSize CPU核心数 1// IO 密集型corePoolSize CPU核心数 × 2或更多// 混合型拆分任务或按压测结果定拒绝策略怎么选重要的任务支付、下单→ CallerRunsPolicy不重要的日志 → DiscardPolicy默认 AbortPolicy 直接抛异常适合大多数场景四、Spring 全家桶1. Spring Bean 生命周期实例化 → 属性赋值 → Aware 接口 → BeanPostProcessor前置 → PostConstructinit-method → BeanPostProcessor后置 → 就绪 → 销毁PreDestroy2. SpringBoot 自动配置原理SpringBootApplication├──EnableAutoConfiguration→ 加载META-INF/spring.factories ├──ComponentScan→ 扫描当前包及子包 └──Configuration→ 标识为配置类// 条件注解ConditionalOnClass// classpath 有某个类才生效ConditionalOnMissingBean// 容器中没有该 Bean 才创建ConditionalOnProperty// 配置文件中指定值才生效所以为什么 SpringBoot 比 Spring 省事自动配置 条件注解不用手写 XML。3. Spring AOP 两种代理JDK 动态代理目标类必须有接口 CGLIB 代理目标类可以没有接口通过继承实现 SpringBoot 2.x 默认目标类有接口用 JDK没有用 CGLIB 可以通过 spring.aop.proxy-target-classtrue 强制用 CGLIB五、MySQL1. 索引失效的场景-- ❌ 对索引列使用了函数WHEREDATE(create_time)2025-01-01-- ✅ 改写成范围查询WHEREcreate_time2025-01-01ANDcreate_time2025-01-02-- ❌ 隐式类型转换WHEREphone1234567890-- phone 是 varchar-- ✅ 加引号WHEREphone1234567890-- ❌ LIKE 以 % 开头WHEREnameLIKE%张三%-- ✅ 或者用全文索引-- ❌ 联合索引跳过了最左列-- 索引 (a,b,c) 但只查 b 和 c2. 最左前缀原则-- 联合索引 (name, age, phone)-- 以下查询走索引WHEREname张三-- ✅WHEREname张三ANDage25-- ✅WHEREname张三ANDphone138-- ✅ 只用到 name 列phone 走不到-- 以下不走索引WHEREage25-- ❌ 跳过了 name六、面试沟通技巧不会的题先说自己了解的部分然后说这个我目前掌握得不够深回去补一下源码题不一定非要背过每一行代码说清楚原理和流程就够了项目题重点说难点、怎么解决的、带来了什么效果不要只罗列功能最常被问的一个问题“你项目中遇到的最大难点是什么怎么解决的”→ 提前准备好这个回答比背100道面试题都管用。 觉得有用的话点赞 关注【张老师技术栈】吧每周更新 Java/Python/爬虫 实战干货不让你白来。

相关新闻