腾讯QQ后端Go开发KPI面经
面试题目
八股:Golang 基础
- GMP 模型:请介绍 Go 的 GMP 调度模型。
- 垃圾回收机制:请介绍 Go 的 GC 机制。
- 追问:你既然这么了解 Go 的 GC,了解 Java 的 GC 吗?了解 C++ 的内存管理吗?(想让候选人做横向对比)
Redis + Lua 脚本
- Redis + Lua 脚本的使用场景与原理(持续深挖)
- 为什么 Redis 执行一条命令是原子性的?(候选人未答上)
项目经历
- 介绍简历中的实习经历第一条(未讲完即被打断)
AI/大模型相关
- 你了解 Agent 开发吗?
- 你了解 MCP 吗?
- 你知道什么是 RAG 吗?
- 你知道什么是 Skill(技能插件)吗?
算法题
- 二叉搜索树中父子节点的最小差值(候选人顺利通过)
参考解析
GMP 模型
- G(Goroutine):Go 协程,轻量级执行单元。
- M(Machine):操作系统线程,真正执行代码。
- P(Processor):逻辑处理器,持有本地 Goroutine 队列,将 G 调度到 M 上运行。
- 核心思路:P 的数量默认等于 CPU 核数(GOMAXPROCS),M 阻塞时 P 会与其解绑并找新 M,实现高并发低开销。
Go GC 机制
- Go 使用三色标记法(白/灰/黑)+ 混合写屏障实现并发 GC。
- 标记阶段:从根对象出发,将可达对象标为黑色,不可达(白色)对象回收。
- Go 1.14+ 通过写屏障保证并发标记的正确性,STW 时间极短(通常 < 1ms)。
- 横向对比:Java 有分代 GC(Young/Old/Metaspace),C++ 无 GC,依赖 RAII/手动管理/智能指针。
Redis 执行单条命令为何是原子性的
- Redis 是单线程处理命令(网络 IO 多线程,命令执行单线程),命令逐条串行执行,不存在并发竞争,天然原子。
- Lua 脚本的原子性原理相同:整个脚本在单线程中一次性执行完毕,执行期间不会插入其他命令。
- 注意区分:单条命令原子 ≠ 多条命令原子,多操作原子性需借助 Lua 脚本或 MULTI/EXEC 事务。
Redis + Lua 脚本
- 使用
EVAL script numkeys key [key ...] arg [arg ...]执行。 - 典型场景:限流(判断+计数原子化)、库存扣减(查询+修改原子化)、分布式锁释放(判断 owner + DEL 原子化)。
- 脚本在 Redis 服务端执行,减少网络往返,保证多步操作原子性。
二叉搜索树父子节点最小差值
- BST 中序遍历结果为升序序列,父子节点差值最小一定出现在中序相邻节点之间。
- 解法:中序遍历,记录前驱节点,依次计算差值取最小值,时间复杂度 O(n),空间 O(h)(h 为树高)。
- 对应 LeetCode 783 / 530,属于简单题,务必熟练掌握 BST 中序遍历模板。