转转实习-后端AI开发一面面试经验分享
面试题目
Java集合与并发
- Java 的 HashMap 数据结构能简单描述一下吗?
- JDK1.8 的 HashMap 为什么要引入红黑树?
- 为什么不直接用红黑树,还要保留链表?
- HashMap 树化阈值为什么是 8 和 64 这两个数字?
- HashMap 是线程不安全的,体现在哪里?为什么说它线程不安全?
- 有哪些线程安全的 Map 实现?
- ConcurrentHashMap 是怎么实现线程安全的?
- JDK1.8 的 ConcurrentHashMap 中,synchronized 锁应用在什么地方?
- Java 线程池有哪些常用参数?有哪些应用场景?
- 线程池在提交任务的过程中,创建线程、处理任务队列的完整流程是什么?
- 并发编程里的 volatile 关键字是做什么用的?使用场景是什么?
- volatile 是怎么实现可见性的?底层原理有了解吗?
- synchronized 和 ReentrantLock 有什么区别?分别在什么场景下使用?
- synchronized 和 ReentrantLock 都是可重入的吗?
- Java 常见的垃圾回收器有哪些?分别有什么特点?
数据库与中间件
- Mysql 的索引结构是什么?简单描述一下。
- 线上碰见过 SQL 慢查询的情况吗?怎么处理?
- 有哪些场景会导致索引失效?
- Mysql 的事务隔离级别有几种?
- Mysql 的事务隔离级别是通过什么手段实现的?
- 可重复读隔离级别是怎么实现的?
- 聊一下 Redis 缓存穿透、缓存雪崩、缓存击穿三个概念的区别,以及对应的预防方案。
- 怎么保证 Redis 里的缓存数据和 Mysql 的数据一致性?
- RabbitMQ 是怎么实现顺序消费的?
- Spring 是怎么解决循环依赖的?
手撕代码 实现无序数组排序,要求奇数在前,偶数在后。
参考解析
- HashMap树化阈值:8是基于泊松分布计算的,在链表长度为8时,红黑树的查找效率(O(log n))明显优于链表(O(n))。64是防止刚开始存储元素较少时频繁树化与退化带来的性能波动。
- ConcurrentHashMap实现:JDK1.8采用CAS + synchronized锁粒度控制在桶头部,实现了高效的并发操作,相比JDK1.7的Segment锁更细化,减少了锁竞争。
- 线程池执行流程:核心线程 -> 阻塞队列 -> 最大线程 -> 拒绝策略。任务进入时先看核心线程是否满,不满则创建;满则尝试入队;队列满则开启临时线程直到最大线程数。
- Redis一致性:最简单方案是“先更新DB,后删除缓存”。为防止极端情况下的不一致,可配合延迟双删、订阅MySQL Binlog同步更新或过期时间兜底。
- Spring循环依赖:通过“三级缓存”机制解决,利用缓存提前暴露尚未完全初始化的Bean实例(半成品),允许在注入依赖时引用尚未完成属性填充的对象。