美团暑期实习AI后端一面分享
面试题目
1. 实习与项目拷打
- 分库分表怎么设计的?分表键是什么?
- 项目里用布隆过滤器了吗?
- 自制RPC框架的服务注册和发现怎么实现的?
2. 八股文
- Java基础:==和equals区别;String常量池位置;泛型类型擦除;反射机制;Stream流特点;volatile底层原理及能否保证原子性。
- JVM:new对象完整过程;双亲委派模型。
- Redis:缓存穿透/击穿/雪崩解决方案;Redis与数据库一致性保证。
- Spring:循环依赖解决方案。
- 多线程:线程状态;sleep与wait区别;如何避免死锁。
- 计算机网络:浏览器输入URL到展示的完整链路。
3. 算法
- 项目代码走读:挑一个复杂接口讲解。
- 手撕:反转链表、字符串解码。
参考解析
- 分库分表:通常基于Hash取模或Range范围分片,需关注数据倾斜和跨分片查询性能。分表键(Shard Key)选择要覆盖高频查询场景,避免全表扫描。
- volatile:底层依赖内存屏障(Memory Barrier)实现可见性与禁止指令重排。它不能保证原子性,因为原子性需要互斥锁(如CAS或synchronized)保证复合操作的完整性。
- Spring循环依赖:通过“三级缓存”解决。一级缓存存放初始化完成的Bean,二级存放半成品Bean,三级存放ObjectFactory用于提前曝光代理对象。
- Redis一致性:常用策略为“先更新数据库,再删除缓存”。若需强一致,需引入分布式锁或订阅数据库Binlog(如Canal)进行异步更新。
- 双亲委派:类加载器加载类时,先委托父类加载器查找,父类找不到才由子类加载。这保证了JDK核心API的安全性,避免用户自定义类覆盖系统类。