爱学习集团Java开发实习一面面经
《面试题目》
- 了解 Java 的线程吗?面对线程并发安全问题会如何解决?
- ThreadLocal 有什么问题?
- 讲一下 Java 的线程池
- 如果一个接口变慢了,怎么判断是不是线程池导致的?
- 有没有用过 Java 的排查工具?
- 线程池的线程数怎么规划?
- SpringBoot 的自动装配原理是什么?
- 让你设计一个防止重复提交的接口,你会怎么设计?
- MySQL 索引失效的场景有哪些?
- 项目里遇到的最难的问题是什么?怎么解决的?
- 智能体项目的用处是什么?知识库的召回率有多少?
- 短期记忆的实现流程是什么?
- 历史对话文档不会超出上下文窗口吗?
- 后面改造智能体短期记忆的方案是什么?
- 现在在用哪些 AI 工具?
《参考解析》
- 防止接口重复提交的设计:常见方案是给每次请求生成一个唯一 Token(提交表单前后端约定),提交时携带 Token,服务端用 Redis 的
SETNX原子操作校验并删除该 Token——校验通过说明是第一次提交,删除后即使重复点击也无法再次通过校验;对幂等性要求更高的写操作,还可以结合业务唯一键(如订单号)在数据库层加唯一索引兜底。 - 判断接口变慢是否因线程池导致:可以通过监控线程池的活跃线程数、队列积压长度、拒绝次数等指标,如果活跃线程数长期打满且队列大量积压,说明是线程池资源不足;也可以用
jstack抓取线程栈,观察是否有大量线程处于等待获取线程池资源的状态,排除是下游依赖(如数据库、外部接口)本身变慢导致的连锁反应。 - ThreadLocal 常见问题:线程池场景下线程会被复用,如果没有在使用完后调用
remove()清理,会导致上一次请求的数据被下一个任务错误读取(脏数据),且长期不清理还会造成内存泄漏(尤其在 JDK 8 之前 ThreadLocalMap 的 key 是弱引用、value 是强引用的情况下,key 被回收后 value 依然存在);最佳实践是在 finally 块中显式调用remove()。