Java常见场景面试题及深度解析
引言
Java作为企业级开发的主流语言,其面试问题往往涵盖基础语法、并发编程、JVM原理、框架设计等多个维度。本文整理高频Java场景面试题,并提供详细解析,帮助求职者系统准备技术面试。
一、Java基础篇
1. String、StringBuilder与StringBuffer的区别?
问题示例:
String s1 = "hello";
String s2 = new String("hello");
StringBuilder sb = new StringBuilder();
StringBuffer sbf = new StringBuffer();
考点分析:
-
String:不可变类,每次修改生成新对象(适合少量字符串操作)
-
StringBuilder:可变,线程不安全,性能高(单线程场景推荐)
-
StringBuffer:可变,线程安全(方法加
synchronized
,多线程场景使用)
延伸问题:
-
JVM字符串常量池如何工作?
-
String s = new String("abc")
创建了几个对象?
2. HashMap底层实现原理?
问题示例:
Map<String, Integer> map = new HashMap<>();
map.put("key", 1);
考点分析:
-
数据结构:JDK1.8后为数组+链表/红黑树
-
哈希冲突:通过
hash(key)
计算索引,冲突时链表存储(>8转红黑树) -
扩容机制:默认负载因子0.75,扩容时重新哈希
高频追问:
-
为什么重写
equals()
必须重写hashCode()
? -
ConcurrentHashMap如何保证线程安全?
二、并发编程篇
3. synchronized和ReentrantLock的区别?
问题示例:
// synchronized
public synchronized void method() {}
// ReentrantLock
Lock lock = new ReentrantLock();
lock.lock();
try { /* 代码块 */ } finally { lock.unlock(); }
考点分析:
特性 | synchronized | ReentrantLock |
---|---|---|
实现方式 | JVM层面(monitor) | API层面(AQS实现) |
锁公平性 | 非公平锁 | 可选公平/非公平 |
中断响应 | 不支持 | 支持lockInterruptibly() |
条件变量 | 仅wait()/notify() |
支持多个Condition |
场景选择:
-
简单同步用
synchronized
-
需要超时、公平锁等高级功能用
ReentrantLock
4. ThreadLocal的实现原理?内存泄漏风险?
问题示例:
ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
threadLocal.set(1);
核心机制:
-
每个Thread内部维护
ThreadLocalMap
,Key为弱引用的ThreadLocal对象 -
内存泄漏原因:Key被回收后Value仍存在(需调用
remove()
清理)
解决方案:
try {
threadLocal.set(value);
// 业务逻辑
} finally {
threadLocal.remove(); // 强制清理
}
三、JVM篇
5. JVM内存模型与GC机制
问题示例:
List<Object> list = new ArrayList<>();
while (true) {
list.add(new Object()); // OOM模拟
}
核心知识点:
-
内存区域:
-
堆(对象实例)
-
方法区(类信息)
-
虚拟机栈(方法调用)
-
-
GC算法:
-
新生代(复制算法)
-
老年代(标记-整理/清除)
-
实战问题:
-
如何定位OOM?
-XX:+HeapDumpOnOutOfMemoryError
生成Dump文件 -
G1与CMS垃圾收集器的区别?
四、框架设计篇
6. Spring Bean的生命周期
问题示例:
@Component
public class MyBean implements InitializingBean {
@PostConstruct
public void init() { /* 初始化逻辑 */ }
}
生命周期流程:
-
实例化 → 2. 属性填充 → 3. BeanPostProcessor前置处理
-
初始化(
@PostConstruct
、InitializingBean
)→ 5. BeanPostProcessor后置处理 → 6. 销毁
高频追问:
-
循环依赖如何解决?(三级缓存机制)
-
@Autowired
和@Resource
的区别?
五、场景设计题
7. 如何设计一个秒杀系统?
考察维度:
-
架构设计:
-
分层:网关 → 服务 → 缓存 → DB
-
限流:令牌桶/漏桶算法
-
-
关键技术:
-
缓存预热(Redis提前加载库存)
-
分布式锁(Redisson实现)
-
-
容灾方案:
-
降级策略(排队页面静态化)
-
参考答案:
// 伪代码:Redis扣减库存
String key = "seckill:stock:" + itemId;
Long remain = redisTemplate.opsForValue().decrement(key);
if (remain < 0) {
redisTemplate.opsForValue().increment(key); // 回滚
throw new RuntimeException("库存不足");
}
结语
Java面试不仅考察知识点的记忆,更注重对技术原理的理解和实际场景的应用。建议结合项目经验,对每个问题深入思考其设计背后的权衡(如HashMap的负载因子选择)。
(附)刷题资源推荐:
-
书籍:《Java编程思想》《深入理解Java虚拟机》
-
网站:LeetCode(算法)、牛客网(场景题)
掌握这些核心问题,你的Java面试通过率将大幅提升!