面灵AI→

字节中国交易与广告后端一面:GMP、Go GC与Redis集群

轮次
一面
时间
2026-10
来源
牛客网

《面试题目》

  1. 请做一下自我介绍。
  2. 介绍一下你的实习,具体负责了什么?
  3. 讲一下 Go 的 GMP 调度原理。
  4. 讲一下 Go 的垃圾回收机制,以及内存泄漏是怎么回事?你实习中遇到过类似问题吗?
  5. Redis 是单线程还是多线程?为什么这么设计?
  6. 讲一下 Redis 集群。
  7. 你在实习中是怎么用 Redis 的?
  8. MySQL 的事务隔离级别有哪些?
  9. 举例讲一下脏读、幻读、不可重复读分别是什么?
  10. 介绍一下你的 AI 项目。
  11. 这个项目里你觉得最核心的机制是哪些?
  12. 为什么要做这个记忆系统?这个方案是怎么得出来的?
  13. 讲一下 RAG。
  14. 手撕一道 Hot 100 里的算法题。
  15. 你怎么看未来 AI native 的组织形态?

《参考解析》

Go 运行时:GMP 与 GC

GMP 是三层结构:G 是 goroutine,M 是操作系统线程,P 是逻辑处理器、持有本地运行队列。P 的数量由 GOMAXPROCS 决定,M 必须绑定一个 P 才能执行 G,这样每个 P 各有本地队列,避免了所有 goroutine 抢一把全局锁。调度上要能说清三件事:本地队列空了会从别的 P 偷或从全局队列取(work stealing);G 进入阻塞系统调用时 M 与 P 解绑、P 交给别的 M 继续跑(hand off);长循环里的 goroutine 靠抢占点被切走,Go 1.14 之后是基于信号的异步抢占,不再只依赖函数调用处的协作式检查。追问往往会落到「为什么要有 P」和「阻塞系统调用时 P 怎么办」,答出这两点基本就稳了。

Go 的 GC 是并发的三色标记清除,靠写屏障保证标记期间对象不被漏标,Go 1.8 之后是混合写屏障,STW 只剩微秒级的两次暂停。触发时机主要由 GOGC 控制(默认堆比上次存活量翻倍就触发),Go 1.19 起还可以用 GOMEMLIMIT 设软内存上限来兜住峰值。所谓「内存泄漏」在 Go 里几乎都不是对象没人管,而是有人一直引用着:goroutine 卡在 channel 上永不退出、循环里 time.After 攒下一堆定时器、全局 map 只增不删、切片截取后仍持有整个底层数组。排查手段是 pprof 的 heap 与 goroutine profile,先看对象从哪分配、再看 goroutine 栈卡在哪一行。

Redis 的单线程设计与集群

Redis 的「单线程」指的是命令执行在主线程上串行完成,网络 IO 走多路复用;4.0 起把大 key 删除这类操作放到异步线程,6.0 起网络读写与协议解析也可以多线程,但命令本身依旧单线程。这样设计的好处是省掉锁竞争和线程上下文切换,每条命令天然原子、也不用担心并发改数据结构,而 Redis 的瓶颈通常在内存与网络而不是 CPU。代价是单个慢命令(keys、大范围 zrange、大 key 删除)会阻塞所有请求,所以线上要禁用危险命令、控制 value 体积。

Redis 集群的核心是分片:16384 个槽按 CRC16(key) % 16384 分配,客户端拿到 MOVED/ASK 后重定向到正确节点;跨槽的多 key 命令(mget、事务、Lua)必须用 hash tag 把 key 固定到同一个槽。集群模式解决了单机内存上限和写吞吐,但没有解决强一致——主从复制是异步的,故障切换期间可能丢最后几条写。要多副本高可用、数据量又不大时,主从 + 哨兵往往比集群更省事。

MySQL 事务隔离级别与三种读问题

四个级别从弱到强是读未提交、读已提交、可重复读、串行化,MySQL 默认可重复读。脏读是读到了别的事务还没提交、之后可能回滚的数据,只有读未提交会中招;不可重复读是同一事务内两次读同一行拿到不同值,读已提交挡不住(每次查询都取最新快照);幻读是同一事务内两次范围查询的行数变了,因为期间有别的事务插入了新行。可重复读靠 MVCC 的一致性视图让快照读稳定,范围上的当前读再用临键锁(记录锁 + 间隙锁)挡住插入;要能顺手说清「快照读」和「当前读」的区别,这是这一题最容易被追问的点。

实习、AI 项目与记忆系统怎么讲

实习部分不要按时间流水账讲,直接给「业务背景 → 我负责的模块 → 我做的技术决定 → 结果数字」四句话,然后主动留一两个钩子等面试官追问,后面用 Redis、并发问题这些真实细节接住。AI 项目被问「最核心的机制」时,考的是你有没有自己的判断,答记忆的写入与检索策略、上下文怎么拼接比罗列框架更有说服力,尤其是「为什么这么设计」——要说清试过什么、否决了什么。RAG 的标准链路是切分、向量化、检索、(可选)重排、拼进上下文生成,真正的取舍在 chunk 粒度、召回数量、要不要 rerank,以及召回率与延迟、成本之间怎么平衡;能讲出你踩过的失败案例(召回不准、上下文被噪声撑爆)比背链路更加分。