字节中国交易与广告后端一面:GMP、Go GC与Redis集群
- 轮次
- 一面
- 时间
- 2026-10
- 来源
- 牛客网
《面试题目》
- 请做一下自我介绍。
- 介绍一下你的实习,具体负责了什么?
- 讲一下 Go 的 GMP 调度原理。
- 讲一下 Go 的垃圾回收机制,以及内存泄漏是怎么回事?你实习中遇到过类似问题吗?
- Redis 是单线程还是多线程?为什么这么设计?
- 讲一下 Redis 集群。
- 你在实习中是怎么用 Redis 的?
- MySQL 的事务隔离级别有哪些?
- 举例讲一下脏读、幻读、不可重复读分别是什么?
- 介绍一下你的 AI 项目。
- 这个项目里你觉得最核心的机制是哪些?
- 为什么要做这个记忆系统?这个方案是怎么得出来的?
- 讲一下 RAG。
- 手撕一道 Hot 100 里的算法题。
- 你怎么看未来 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,以及召回率与延迟、成本之间怎么平衡;能讲出你踩过的失败案例(召回不准、上下文被噪声撑爆)比背链路更加分。