面灵AI→

百度手百服务端一面:Go、Redis 与 MySQL 二十二问

轮次
一面
结果
已挂
时间
2026-04
来源
牛客网

《面试题目》

  1. 自我介绍。
  2. 进程、线程、协程的区别?
  3. Go 如何保证并发安全?
  4. 了解 Channel 吗?channel 的底层?
  5. Go 的 GC 是如何实现的?
  6. Map 是无序的吗?如何实现 map 顺序输出?
  7. Redis 有什么用途?为什么使用 Redis?
  8. 缓存穿透、缓存失效、缓存击穿。
  9. 超卖。
  10. 怎么去做限流?
  11. 如果用户抢购成功但创建订单失败了怎么办?
  12. 活动预热怎么做?怎么在 5 分钟内给 1000w 用户推广活动消息?
  13. ZSET 怎么用?ZSET 底层?
  14. Redis 过期策略和内存淘汰、Redis 持久化机制。
  15. MySQL 索引、索引优缺点,索引底层为什么用 B+ 树?
  16. 事务的 ACID 特性?隔离级别?分别解决什么问题?
  17. 索引失效情况?
  18. 慢查询调优。
  19. 分库分表具体怎么做?分库分表怎么迁移保证服务可用?
  20. 代码题:全排列。
  21. 接口可用性报警,怎么排查问题?单机 / 集群模式下怎么排查?
  22. 接口响应慢,怎么优化?

《参考解析》

  1. 进程、线程、协程与 Go 并发安全:进程有独立地址空间,线程共享地址空间但由内核调度、切换要陷入内核,协程是用户态调度、由 runtime 把大量 goroutine 多路复用到少量线程上(GMP 模型),切换成本更低但阻塞点要自己留意。Go 保证并发安全的两条路是 channel(用通信共享内存)和 sync 包(Mutex/RWMutex/atomic),map 并发写会直接 panic,必须加锁或换 sync.Map。回答时补一句「能用 channel 就用 channel,但共享读多写少时 RWMutex 更省」,比只背口号实在。
  2. channel 底层与 Go GC:channel 是一个带锁的环形缓冲队列加 sendq、recvq 两个等待队列,元素存在环形数组里,阻塞的 goroutine 以 sudog 挂在链表上,收发配对时直接内存拷贝或把接收方指针传过去。Go 的 GC 是并发的三色标记清除,靠混合写屏障保证标记正确,STW 只发生在很短的阶段(如开启标记与标记终止)。要降低 GC 压力就控制对象分配、复用缓冲区(sync.Pool)、避免无意义的小对象和长生命周期的大切片。
  3. 缓存三兄弟、超卖与限流:缓存穿透是查根本不存在的数据,用空值缓存加布隆过滤器挡;缓存击穿是热点 key 过期瞬间大量请求打到库,用互斥重建或逻辑过期;缓存雪崩是大量 key 同时过期,加随机 TTL、多级缓存并配限流兜底。超卖的本质是「判断库存」和「扣减库存」不原子,解决办法是让它们变成一个原子操作——Redis 用 Lua 脚本或 DECR,数据库用带条件的 update stock = stock - 1 where stock >= 1,再配预扣与异步下单。限流按粒度选:单机用令牌桶或漏桶,分布式用 Redis + Lua 做计数或滑动窗口,网关层直接交给限流组件。
  4. 抢购资格与活动预热:用户抢购成功但建单失败,不能只靠一次同步事务,要先把「抢到资格」落成一条幂等记录(资格单或流水),再异步建单并重试,失败可按规则回滚资格,这样既不超卖也不丢单。预热是把商品、库存、活动规则提前推到离用户最近的地方(本地缓存、Redis),把读流量从数据库上卸掉。1000 万用户的触达靠人群包分片加消息队列削峰,分批推送并让下游能限流,绝对不能做成一次全量广播;同时准备好降级策略,推送洪峰时先保下单链路。
  5. ZSET 与 MySQL 索引、分库分表:ZSET 底层是跳表加哈希表——哈希表存元素到分值的映射,跳表支撑范围查询和排名,所以插入、查分值都是 O(log n) 级别。Redis 过期是惰性删除加定期抽样删除,内存打满时按 maxmemory-policy 淘汰,持久化有 RDB 快照、AOF 日志和混合模式。MySQL 用 B+ 树做索引是因为它矮胖、非叶子节点只存键、叶子节点串成链表适合范围扫描,磁盘 IO 次数少;代价是占用空间并拖慢写入。索引失效常见于对列做函数或隐式类型转换、前导通配 like、以及违反最左前缀;慢查询先看执行计划,再决定改 SQL、加索引还是拆表。分库分表按业务和数据量选分片键,迁移走双写加增量补数、灰度切读、最后对账,确保切换期间服务可用。
  6. 接口报警与响应慢的排查:先定位范围——是全站还是单接口、单机还是集群、什么时候开始的,再对照黄金指标(流量、错误率、延迟分位、饱和度)看是哪一类异常,并把时间点和最近的发布、配置、数据变更对齐。单机模式看进程本身:CPU、内存、GC、连接数、线程栈和慢日志;集群模式看是不是某台机器异常、是不是下游依赖或数据库成了瓶颈、是不是热点分片。响应慢的优化顺序是先量后改——定位慢在 SQL、RPC、序列化还是锁竞争,再上缓存、批量化、异步化、加索引或限流降级;没有定位就调参数等于赌。