字节跳动 TikTok 后端开发实习生二面面经
- 轮次
- 二面
- 结果
- 凉经
- 时间
- 2026-10
- 来源
- 牛客网
《面试题目》
- 请介绍一下你做过的最复杂的后端项目,以及其中最难的技术问题。
- 你的项目为什么要采用微服务架构?如果重新设计,你还会这么拆吗?
- 一个请求经过 Nginx、Gateway、服务、Redis、MySQL,整个链路中任何一个环节出现故障,你怎么保证系统可用?
- 如果某个核心服务 QPS 突然从 1 万涨到 10 万,你会怎么限流和降级?
- Sentinel 的限流算法有哪些?你在项目中为什么选择这种方式?
- 如果一个服务调用另一个服务超时,重试机制应该怎么设计?为什么不能无限重试?
- 什么情况下使用同步调用,什么情况下使用 MQ 异步处理?
- RabbitMQ 如何保证消息不丢失?生产者、Broker、消费者分别需要做什么?
- RabbitMQ 消费者处理成功、但 ACK 之前服务宕机了,会发生什么?怎么保证业务幂等?
- Redis 分布式锁怎么实现?为什么需要 Lua?锁过期时间怎么设置?
- 如果持有者执行时间超过锁的 TTL,会出现什么问题?怎么解决?
- MySQL 事务的 ACID 分别是什么?InnoDB 是如何保证这些特性的?
- MySQL 的 MVCC 是怎么实现的?ReadView 是什么?
- RR 下快照读不会幻读,那当前读的幻读怎么解决?
- 如果数据库出现大量慢查询,你会从哪些方面排查和优化?
- JVM 内存区域有哪些?一个 Java 对象从创建到回收大概经历什么过程?
- 如果线上服务频繁 Full GC,你会怎么排查?
- 如果让你设计一个高并发直播间评论系统,你会怎么设计?
- 手撕:设计并实现一个满足 LRU 缓存约束的数据结构。
- 你认为自己目前最大的技术短板是什么?
《参考解析》
链路容错要按“每一跳都可能挂”来答:入口层做限流和黑白名单,网关层做鉴权、路由与超时,服务间调用设置连接超时、读超时和重试预算,Redis 与 MySQL 都要有降级路径。核心是区分“强依赖”和“弱依赖”:下单、扣库存这类强一致链路失败要快速失败并给出明确错误;评论数、推荐位这类弱依赖失败可以返回兜底数据。再做舱壁隔离,避免一个下游把线程池打满拖垮整个服务。
超时与重试的关键是预算和幂等:每次调用设置小于上游剩余时间的超时,重试只针对幂等操作或可去重的写操作,采用指数退避加抖动,并限制总重试次数和总耗时;不能无限重试,否则会放大流量并在下游故障时形成雪崩。跨服务写操作要带业务唯一键,消费端用唯一索引或状态机做幂等。MQ 不丢消息要三段都做:生产端确认与本地消息表/事务消息,Broker 持久化与副本,消费端手动 ACK 且业务成功后再确认;ACK 前宕机会导致重复消费,所以幂等是必需项而不是可选项。
锁与数据库部分要讲出边界:Redis 锁用 SET key value NX PX 加唯一 value,释放和续期用 Lua 保证原子;TTL 要大于业务最长执行时间,并用看门狗续期,同时接受“极端情况下锁失效”的事实,关键资源再加数据库乐观锁或唯一约束兜底。MVCC 由隐藏事务 ID、undo log 和 ReadView 实现,RR 下快照读复用第一次读的 ReadView;当前读的幻读靠 next-key lock(记录锁 + 间隙锁)解决。慢查询按“是否走索引、索引是否失效、扫描行数、回表次数、锁等待”逐层看执行计划和慢日志。
系统设计与手撕:直播间评论读多写少,按直播间分片,写侧先落 MQ 削峰再异步批量入库,读侧用 Redis List/ZSet 保存最近 N 条并做本地缓存,热点直播间单独扩容;同时要有敏感词过滤、限流和降级。LRU 用哈希表加双向链表,get 命中后移到表头,put 超容量淘汰表尾,Java 里可以用 LinkedHashMap 的 accessOrder 快速实现,但面试最好手写双链表展示对指针操作的理解。