🎯 网站简介与内容结构说明
本页面为 Java面试题总结 的权威整合版,内容基于2026年主流互联网企业(含阿里、腾讯、字节、美团、拼多多等)的招聘JD、技术栈演进路径与高频面试反馈构建,力求为求职者提供“信息增益型”内容——即不仅罗列问题,更注重:
① 问题背后的原理性追问;
② 多维度对比分析(如ArrayList vs LinkedList vs CopyOnWriteArrayList);
③ 场景化延伸(如“如何在高并发下实现线程安全的缓存?”);
④ 避坑指南与最佳实践。
📌 本页面覆盖的“高频核心模块”
- 〈Java基础〉:集合、异常、反射、泛型、IO/NIO、新特性(Java 8~21)
- 〈并发编程〉:线程模型、JUC、线程池、锁机制、AQS、CAS原理
- 〈JVM调优〉:内存模型、GC机制、诊断工具、性能调优实战
- 〈Spring全家桶〉:IoC/AOP、事务传播、循环依赖、Spring Boot自动装配
- 〈分布式架构〉:RPC、服务治理、CAP理论、分布式事务、限流降级
- 〈数据库与中间件〉:MySQL索引优化、Redis缓存击穿/雪崩、Kafka消息重复
- 〈工程实践〉:代码规范、Git协作、CI/CD、可观测性(日志/链路/指标)
- 〈软技能〉:项目复盘、STAR法则、反问技巧、谈薪策略
〔使用建议〕
建议采用“三遍阅读法”:
- 第一遍通读标题与加粗关键词,建立知识框架;
- 第二遍精读示例与对比表,强化理解差异点;
- 第三遍结合自身项目复现关键代码,实现从“知道”到“会用”。
🧱 Java核心技术模块|高频考点与深度解析
〔集合框架〕高频考点:ArrayList vs LinkedList vs Vector vs CopyOnWriteArrayList
面试官常追问:**“在高并发读多写少场景下,你会优先选择哪个集合?为什么?”**
| 集合类 | 底层结构 | 线程安全 | 扩容机制 | 适用场景 |
|---|---|---|---|---|
| ArrayList | 动态数组 | ❌ 非线程安全 | 默认1.5倍扩容(JDK 8+),需System.arraycopy | 频繁随机访问、尾部插入;单线程环境 |
| LinkedList | 双向链表 | ❌ 非线程安全 | 无固定容量,动态增删节点 | 频繁头尾插入/删除;作为队列/栈使用 |
| Vector | 动态数组 | ✅ synchronized方法级同步 | 2倍扩容(旧版),已不推荐 | 仅兼容旧系统;新项目请用CopyOnWriteArrayList |
| CopyOnWriteArrayList | 数组+写时复制 | ✅ ReentrantLock保证线程安全 | 每次写操作复制新数组,内存开销大 | 读多写少场景(如配置列表、事件监听器) |
【经典陷阱】
在迭代ArrayList时若进行结构性修改(如remove),会抛出ConcurrentModificationException。正确做法:使用Iterator.remove()或转为CopyOnWriteArrayList。
〔异常处理〕自定义异常 vs 标准异常?try-with-resources本质是什么?
自定义异常需遵循:
① 继承RuntimeException(非受检)或Exception(受检);
② 提供完整构造器(含cause);
③ 命名规范:业务异常以Exception结尾(如OrderNotFoundException)。
try-with-resources 是Java 7引入的语法糖,其底层通过AutoCloseable接口实现资源自动关闭。编译后会生成try-finally块,并在finally中调用close()方法,同时处理close()抛出的异常(抑制异常)。
等价于:
〔反射与泛型〕泛型擦除导致的类型安全问题?如何绕过?
Java泛型是**伪泛型**,仅在编译期存在,运行时会被类型擦除为Object。例如:
这会导致一个经典问题:可通过反射向String集合中添加非String对象:
【应对策略】
- 避免使用反射操作泛型集合;
- 在API文档中明确泛型约束;
- 使用不可变集合(Collections.unmodifiableList)。
⚙️ Spring生态|高频考点与企业级陷阱
〔Spring事务传播机制〕7种传播行为详解与实战选择
| 传播行为 | 描述 | 适用场景 | 风险点 |
|---|---|---|---|
| REQUIRED | 有事务则加入,否则新建事务 | 默认选择;90%业务场景 | 外层事务回滚会导致内层也回滚 |
| REQUIRES_NEW | 挂起当前事务,新建独立事务 | 日志记录、独立审计模块 | 可能导致数据不一致(外层回滚但子事务提交) |
| NESTED | 在当前事务内创建保存点 | 需要部分回滚的复杂流程 | 仅支持JDBC 3.0+;需DataSource支持savepoint |
| NOT_SUPPORTED | 挂起当前事务,以非事务方式执行 | 查询操作;避免事务锁定资源 | 若方法内抛异常,数据可能未持久化 |
【真实案例】
某订单系统中,createOrder()调用sendNotification()。若sendNotification失败应不影响主流程,但若用REQUIRED则会导致订单回滚。正确做法:将sendNotification设为NOT_SUPPORTED或REQUIRES_NEW(异步发送更佳)。
💻 JVM调优|内存模型与性能实战
〔JVM内存区域〕JDK 8+与JDK 7的核心差异
JDK 8移除了永久代(PermGen),引入元空间(Metaspace),存储类元数据于本地内存。关键变化:
- ● -XX:PermSize/-XX:MaxPermSize 参数失效;
- ● -XX:MetaspaceSize/-XX:MaxMetaspaceSize 控制元空间大小;
- ● 元空间OOM错误从java.lang.OutOfMemoryError: PermGen space变为java.lang.OutOfMemoryError: Metaspace。
同时,字符串常量池从永久代移至堆中(JDK 7起),避免常量池溢出。
2020年前:G1成为默认垃圾收集器
适用于大内存(≥4GB)、低延迟场景;可预测停顿时间(-XX:MaxGCPauseMillis)。
2021年:ZGC(实验性)→ 2022年:Shenandoah
目标:10ms以内停顿;适用于超大堆(TB级);但需JDK 11+且仅Linux支持ZGC。
2024年:Epsilon GC(无GC)
适用于内存分析、性能测试等无需GC的场景。
⚡ 并发编程|线程模型与JUC深度解析
〔线程池〕ThreadPoolExecutor核心参数详解
构造函数7个参数:
| 参数 | 作用 | 推荐值 |
|---|---|---|
| corePoolSize | 核心线程数 | CPU核心数+1(CPU密集型) 或2×CPU核心数(IO密集型) |
| maximumPoolSize | 最大线程数 | 避免过大(内存消耗);需结合队列容量评估 |
| keepAliveTime | 非核心线程空闲存活时间 | 30秒~5分钟 |
| workQueue | 任务队列 | SynchronousQueue(直接提交) LinkedBlockingQueue(默认,无界,需防OOM) |
【血泪教训】
某项目使用Executors.newFixedThreadPool()创建线程池,导致任务队列无限堆积,最终OOM。正确做法:**显式声明ThreadPoolExecutor参数**,根据业务预估设置队列上限。
〔AQS原理〕CountDownLatch vs CyclicBarrier vs Semaphore
| 工具类 | 核心用途 | 可重用性 | 典型场景 |
|---|---|---|---|
| CountDownLatch | 等待N个线程完成 | ❌ 一次性 | 主线程等待子线程初始化 |
| CyclicBarrier | 多个线程互相等待到达屏障 | ✅ 可重用(支持reset) | 多线程计算后汇总结果 |
| Semaphore | 控制并发线程数 | ✅ 可重用 | 数据库连接池限流 |
🌐 分布式系统|CAP、事务与高可用
〔分布式事务〕Seata AT模式 vs TCC vs Saga
| 模式 | 侵入性 | 性能 | 适用场景 |
|---|---|---|---|
| AT(自动事务) | 低(基于SQL解析) | 中 | 本地数据库支持2PC(如MySQL) |
| TCC(Try-Confirm-Cancel) | 高(需手动实现三阶段) | 高 | 金融核心系统;强一致性要求 |
| Saga | 中 | 高 | 长事务;允许最终一致性(如电商订单) |
【经验之谈】
在电商场景中,订单创建后需扣减库存、生成物流单、发送优惠券。若用AT模式,库存服务需支持回滚(UPDATE ... WHERE version=oldVersion),但高并发下锁竞争严重。更优方案:用Saga模式,订单服务记录补偿日志,失败时异步重试。
📊 数据库与中间件|高频性能优化点
〔MySQL索引〕最左前缀原则与覆盖索引实战
假设有复合索引:idx_name_age (name, age):
- ✓ WHERE name='Tom' → 走索引
- ✓ WHERE name='Tom' AND age=25 → 走索引
- ✗ WHERE age=25 → 不走索引(违反最左前缀)
- ✓ SELECT id, name, age FROM table WHERE name='Tom' → 覆盖索引(无需回表)
但注意:若查询字段超出索引范围(如SELECT *),则无法使用覆盖索引。
〔Redis缓存〕缓存击穿/雪崩/穿透解决方案
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 击穿 | 热点Key过期,大量请求穿透 | ① 互斥锁重建缓存 ② 永不过期+后台异步刷新 |
| 雪崩 | 大量Key同时过期 | ① 设置随机过期时间 ② 熔断降级(Hystrix) |
| 穿透 | 查询不存在的数据(如ID<0) | ① 缓存空值(短TTL) ② 布隆过滤器预校验 |
📐 设计模式|Java高频考题与落地场景
〔工厂模式 vs 抽象工厂 vs 建造者模式〕
- 工厂模式:创建单一产品(如DB连接工厂);
- 抽象工厂:创建产品族(如MySQL + Redis + Kafka组合);
- 建造者模式:分步骤构建复杂对象(如StringBuilder、Lombok @Builder)。
【反例警示】
某项目为每个Service手动new DAO,导致测试困难。正确做法:用工厂模式+依赖注入,实现解耦。
🛠️ 开发工具|效率提升技巧
〔IDEA技巧〕你可能不知道的8个高效快捷键
- Ctrl+Alt+L:格式化代码(强制遵循阿里规范);
- Ctrl+Shift+U:大小写切换;
- Alt+Insert:生成代码(getter/setter/constructor);
- Ctrl+Alt+V:提取变量(重构必备);
- Ctrl+Shift+R:全项目替换;
- Alt+F7:查找所有引用(比Ctrl+Shift+F更精准);
- Ctrl+G:跳转到行号;
- Ctrl+Shift+F12:隐藏其他窗口,专注编辑区。
📝 简历优化|HR筛选逻辑与技术亮点呈现
〔简历避坑指南〕
- ❌ 错误写法:"熟悉Spring Boot" →
✅ 正确写法:"基于Spring Boot 2.7实现订单中心,QPS 5000+,通过Redis缓存+本地缓存Caffeine双层架构降低DB压力80%"; - ❌ 错误写法:"参与分布式事务开发" →
✅ 正确写法:"主导订单-库存服务的Seata AT模式集成,解决超卖问题,事务成功率99.99%"。
【核心原则】
用技术栈 + 业务场景 + 量化指标 + 解决方案四要素构建项目描述。
💬 面试技巧|反问环节与谈薪策略
〔反问环节黄金问题〕
- ① 团队当前技术栈演进方向?未来6个月重点技术投入?
- ② 岗位最看重的3项能力?团队最大的技术挑战?
- ③ 晋升机制?技术专家路径?
- ④ 绩效考核标准?OKR如何制定?
【禁忌】
避免问薪资、加班、年假等(留到HR面)。技术岗反问体现技术深度与成长诉求。
网站地图
📧 联系我们
本内容由 www.kaoacca.cn 团队持续更新,欢迎反馈问题或建议。
- 📧 邮箱:contact@kaoacca.cn
- 🌐 微信公众号:KaoACCA(搜索ID)
- 💡 版权所有 © 2026 蜀ICP备2026017620号-5