0519Java面试题总结
Java面试题总结
1. JVM调优的场景和调优的内容
调优场景:
- 应用出现OutOfMemoryError内存溢出
- GC频繁导致应用卡顿
- 应用吞吐量不达标
- 应用响应时间过长
- 堆内存持续增长不释放
调优内容:
- 堆内存调整:-Xms(初始堆大小)、-Xmx(最大堆大小)
- 新生代老年代比例:-XX:NewRatio
- Survivor区比例:-XX:SurvivorRatio
- 选择合适的GC算法:
- 串行收集器:-XX:+UseSerialGC
- 并行收集器:-XX:+UseParallelGC
- CMS收集器:-XX:+UseConcMarkSweepGC
- G1收集器:-XX:+UseG1GC
- 元空间大小:-XX:MetaspaceSize
- GC日志分析:-XX:+PrintGCDetails
- 内存泄漏分析:堆转储分析
2. ThreadLocal原理及常用应用场景
原理:
- ThreadLocal在每个线程内部维护一个ThreadLocalMap
- 以ThreadLocal实例为key,存储线程私有数据
- 通过get()/set()方法存取数据
- 每个线程独立拥有自己的副本,互不干扰
内存泄漏风险:
- ThreadLocalMap的key是弱引用,但value是强引用
- 如果ThreadLocal实例被回收,key变为null,但value仍然存在
- 最佳实践:使用后调用remove()方法清理
应用场景:
- 线程上下文信息传递(如用户会话信息)
- 数据库连接管理(每个线程独立连接)
- SimpleDateFormat等非线程安全对象的线程安全使用
- 跨方法参数传递(避免方法参数层层传递)
3. 多线程中join方法的使用
作用:
- 让当前线程等待调用join()方法的线程执行完毕
使用方式:
Thread t = new Thread(() -> {// 线程执行逻辑
});
t.start();
t.join(); // 当前线程等待t执行完毕
特点:
- join()方法可以设置超时时间:join(long millis)
- 调用join()方法会释放当前线程持有的锁
- 底层基于wait/notify机制实现
- 常用于主线程等待子线程完成后再继续执行
4. 线程池的使用
核心参数:
- corePoolSize:核心线程数
- maximumPoolSize:最大线程数
- keepAliveTime:非核心线程空闲存活时间
- workQueue:任务队列
- threadFactory:线程工厂
- handler:拒绝策略
常用线程池:
- newFixedThreadPool:固定大小线程池
- newCachedThreadPool:可缓存线程池
- newSingleThreadExecutor:单线程线程池
- newScheduledThreadPool:定时任务线程池
最佳实践:
- 使用ThreadPoolExecutor自定义线程池
- 合理设置线程池大小(CPU密集型/IO密集型)
- 选择合适的拒绝策略
- 使用有界队列避免OOM
- 监控线程池状态
5. 高并发的场景和相关技术实现
高并发场景:
- 电商秒杀
- 抢红包
- 实时竞价
- 社交热点
技术实现:
-
前端优化:
- CDN加速
- 静态资源缓存
- 页面静态化
-
服务端优化:
- 分布式架构
- 微服务拆分
- 负载均衡
-
缓存技术:
- 多级缓存(本地缓存+分布式缓存)
- Redis集群
- 缓存预热/降级策略
-
消息队列:
- 异步处理(削峰填谷)
- Kafka/RocketMQ
- 顺序消息/延迟消息
-
数据库优化:
- 读写分离
- 分库分表
- 数据库连接池
- 索引优化
-
限流熔断:
- 令牌桶/漏桶算法
- Sentinel/Hystrix
- 服务降级
-
分布式技术:
- 分布式锁(Redis/Zookeeper)
- 分布式ID生成
- 分布式事务
-
其他优化:
- 无状态设计
- 异步非阻塞IO(Netty)
- 协程/虚拟线程(Java19+)