面经-自用
🎯 高频问题 + 深挖追问
一、专业技能
JVM 与 GC
- Q: 线上服务频繁 Full GC,你怎么排查?
- 追问1: 你说用
jmap
dump,那 dump 文件往往好几个 G,你怎么快速定位泄漏对象?
👉 思路:用 MAT/arthas heap dump → 按对象数量/retained size 排序,看大对象(比如HashMap
、ThreadLocalMap
),再看 GC Roots 引用链。 - 追问2: 你说调整
NewRatio
,那如果是 G1 收集器,还会这样调吗?
👉 回答:不会,G1 用 Region,调优点在于-XX:InitiatingHeapOccupancyPercent
,关注的是触发 Mixed GC 的阈值。
Redis
-
Q: 你在项目里解决缓存穿透时没用布隆过滤器,而是缓存空值,为什么?
-
追问: 缓存空值可能被攻击(恶意请求不同 Key),会导致 Redis 被塞满,你怎么避免?
👉 思路:- 给空值设置较短 TTL;
- 对 Key 做限流/黑名单;
- 高并发场景下布隆过滤器更合适。
MQ
- Q: 你说 RocketMQ 有事务消息,那事务半消息没提交之前,消费者会看到吗?
- 追问: 如果生产者在本地事务执行完后挂掉了,Broker 该怎么办?
👉 回答:Broker 会不断回查生产者,直到确认事务状态 → 如果查不到要设计补偿机制。
二、实习经历
用友 - 电商对账单导入
- Q: 线程池 + 批处理,你具体怎么设计线程池参数的?
- 追问1: 如果 10 万条数据,分批写入时一批失败了,你是整体回滚还是部分回滚?为什么?
👉 思路:小批事务保证部分成功;失败批次重试,不能全回滚,否则耗时过高。 - 追问2: 你说用 Redis 推送进度,如果服务挂了,进度会丢吗?怎么保证恢复?
👉 回答:进度写 Redis 有持久化,重启后从 Redis 读最新进度;必要时用数据库存储进度。
明果科技 - 小雀幸 APP
- Q: 你说 Session 缓存比 Redis 高效,那如果服务多节点部署,Session 不共享怎么办?
👉 回答:Session 内缓存只存短生命周期数据,不依赖全局一致性;需要全局共享时再落 Redis。 - 追问: 如果面试官问“那你不就是放弃了水平扩展吗?”
👉 回答:不是,Session 缓存只是局部优化,不影响系统整体可扩展性,属于“冷热数据分层”思路。
三、项目经历
国考刷题网 - ES
-
Q: 你说用 Canal 同步数据到 ES,那如果 Canal 宕机了怎么办?
👉 回答:ES 数据和 MySQL 可能不一致,所以要做定时全量校准,保证最终一致性。 -
追问: 如果用户搜到的数据和 DB 数据不一致,你会怎么做?
👉 思路:- 允许弱一致,写时优先保证 MySQL 正确,搜索端 eventual consistency;
- 或者把关键数据直接从 DB 查,再和 ES 数据聚合。
Redis BitMap
- Q: 你说 BitMap 节省空间,那如果要统计某用户连续刷题天数,怎么做?
👉 思路:用bitfield
或按位运算,滑动窗口扫描;极端情况下写 Lua 脚本优化。 - 追问: 如果要统计所有用户连续打卡 7 天的人数,BitMap 怎么做?
👉 回答:用多个 BitMap,做AND
运算。
JDHotKey + Caffeine
- Q: 本地缓存和 Redis 不一致怎么办?
- 追问: 你说“定时刷新”,那刷新过程中用户可能还是读到旧值,这能接受吗?
👉 回答:能接受,这是典型的 最终一致性 trade-off。要是不能接受,就要用消息通知(Redis Key 过期事件,推送更新本地缓存)。
四、系统设计与挑战
高频流量(美团支付接口)
- Q: 支付接口流量突增,你说用 MQ 削峰,那支付不是实时的吗?怎么能排队?
👉 回答:削峰的是支付后的异步处理,不是实时扣款(例如积分发放、账单统计)。扣款必须实时,后台异步。 - 追问: 如果 MQ 挤满了,消费延迟严重,怎么办?
👉 思路:区分队列优先级,关键任务单独队列,非核心任务可丢弃/降级。
SaaS 架构
- Q: 你说要分库分表,那刷题平台按什么维度分?
👉 回答:按用户 ID 或题库 ID 水平拆分,保证热点均匀。 - 追问: 如果某个大客户占了 50% 流量,分库分表就不均匀了怎么办?
👉 回答:对超级大客户单独建库,避免倾斜。
⚡ 面试官的套路:
- 先问通用问题,看你熟不熟;
- 再追问边界情况(高可用、异常、极端场景);
- 最后看你能不能说出取舍和思考。
要不要我帮你直接生成一份 模拟面试剧本(我扮演美团面试官,一问一答,你先给“第一层答案”,我就追问下去),这样你能感受到被“深挖”的真实压力?