字节跳动 AI后端暑期实习一面面经
《面试题目》
- MySQL事务隔离级别有哪些?
- 请讲一下脏读、幻读、不可重复读的区别。
- MySQL索引的工作原理是什么?
- 为什么索引使用B+树而不是B树?
- 联合索引是如何实现的?
- 线程和进程有什么区别?
- Java线程之间如何传递参数?
- Spring是如何解决循环依赖的?
- 算法题:打家劫舍变种。
《参考解析》
- MySQL隔离级别:读未提交、读已提交(RC)、可重复读(RR,默认)、串行化。RR级别通过MVCC和间隙锁解决幻读。
- 读问题:脏读是读到未提交数据;不可重复读是前后读取结果不一致(侧重修改);幻读是范围查询时记录数增减(侧重插入/删除)。
- 索引原理:索引是一种排好序的数据结构,辅助快速查询。B+树将所有数据存放于叶子节点,非叶子节点只存索引,且叶子节点通过双向链表连接,适合范围查找。
- B+树优势:B+树的非叶子节点不存数据,能容纳更多索引,树更矮胖,磁盘I/O次数更少;且叶子链表设计非常契合数据库的范围扫描场景。
- 联合索引:采用“最左前缀原则”。在B+树中将多个字段值拼接作为键值进行排序存储,查找时需从索引的最左侧字段开始匹配,否则索引失效。
- 线程与进程:进程是资源分配的最小单位,线程是CPU调度的最小单位。进程间内存独立,通信代价高;线程共享进程内存,切换开销小,但需处理同步问题。
- Java线程传参:可通过构造函数传参、通过ThreadLocal在线程内部共享变量、或使用Runnable/Callable实现类的成员变量传参。
- Spring循环依赖:主要通过“三级缓存”解决。Bean在实例化后放入一级缓存前,将提前暴露的对象放入三级缓存(ObjectFactory),通过AOP代理处理,从而在注入依赖时获取到提前暴露的引用。