携程AI后端暑期实习一面面经
《面试题目》
- CountDownLatch为什么配合线程池使用,为什么不过来一个任务new一个thread?
- 线程池如何设置?
- 虚拟线程十万量级为什么还要用线程池?
- MCP怎么设计的?
- 对于微服务场景怎么根据下游去动态修改线程池?
- 怎么监控线程池,从哪些维度去做切入监控,有用过对应工具吗?
- Java的锁讲一下。
- 分布式锁怎么做,除了NX锁?
- 热Key问题。
- Java哪个版本用到的虚拟线程,Spring哪个版本支持的SSE?
- ThreadLocal会遇到哪些问题?
- ThreadLocal里的信息是怎么传递下去的?
- 线上Full GC怎么去排查?
- 新生代向老年代哪几种情况下会传送数据?
《参考解析》
- 线程池与虚拟线程:频繁创建线程消耗系统资源(上下文切换、堆栈内存),线程池实现复用。即便使用虚拟线程,也需通过线程池(如任务调度器)控制并发度,防止系统过载。
- 分布式锁:除了Redis SETNX,还可使用Redlock算法(多节点)、Zookeeper顺序临时节点(强一致性)或基于数据库唯一索引实现。
- Full GC排查:通过jstat/jmap定位内存占用,利用MAT分析堆转储文件(Heap Dump),查看是否存在内存泄漏或大对象,检查元空间及老年代占用情况。
- ThreadLocal问题:主要问题是内存泄漏(未及时remove导致引用无法回收)和父子线程信息传递困难。解决传递需使用InheritableThreadLocal或自定义修饰器(如TransmittableThreadLocal)。
- 热Key问题:使用本地缓存(Guava/Caffeine)降低Redis压力,或对Key进行多级缓存,或使用逻辑过期和加锁降级处理。