友塔游戏服务器开发一面二面面经:Linux、MySQL、Redis 与 C++
- 轮次
- 一面、二面、HR面
- 结果
- 已 OC
- 时间
- 2026-10
- 来源
- 牛客网
《面试题目》
一面
- 进程和线程有什么区别?
- 进程间通信有哪些方式?管道、共享内存、消息队列各自的特点是什么?
- 共享内存有什么问题?
- TCP 如何保证可靠性?
- MySQL 的四个隔离级别分别解决了什么问题?
- 讲讲 MySQL 的索引。
- 等值条件和范围条件同时存在时,联合索引的字段顺序应该怎么定?
- Redis 常见的数据类型有哪些?
- 缓存的三类问题是什么?
- C++ 的深拷贝和浅拷贝有什么区别?
- 讲讲 C++ 的虚函数。
- 介绍一下你的实习经历。
- 介绍一下你的项目。
二面
- 介绍一下你的实习和项目。
- Nginx 有什么用途?
- 有状态服务和无状态服务有什么区别?
- 客户端卡顿如何排查?
- 无状态服务如何保证数据一致性?
- 分布式锁怎么实现?
- 如何设计一个数据结构,使其能在动态集合中查找到第 k 小的值?
《参考解析》
Linux 与网络:IPC 的取舍、TCP 靠什么可靠
进程是资源分配的单位,线程是调度的单位,同一进程内的线程共享地址空间与文件描述符,所以线程通信靠共享变量、进程通信必须走内核。管道是最简单的字节流,只支持亲缘或已建立连接的进程、半双工且有容量上限;消息队列以消息为单位、有类型和边界,适合异步解耦但多一次内核拷贝;共享内存是几者里最快的,因为数据不经过内核复制,代价是内核不提供任何同步机制,必须自己配信号量或互斥锁,还要处理越界写和进程异常退出后共享段残留未释放的问题。TCP 的可靠性由一整套机制叠加而成:序号与确认应答、超时重传与快速重传解决丢包,滑动窗口做流量控制、拥塞窗口做拥塞控制,再加校验和与去重排序;面试里只答「三次握手」通常不够,要点到重传与窗口这两层。
MySQL 与 Redis:隔离级别、联合索引顺序与缓存三大问题
四个隔离级别是逐级加锁换一致性:读未提交会脏读,读已提交解决脏读但同一事务内两次读可能不一致,可重复读解决不可重复读,InnoDB 还靠间隙锁(next-key lock)在大部分场景下压住幻读,串行化最严但并发最差。联合索引的排序规则是「先按第一列排,第一列相同再按第二列排」,所以等值条件列放前面、范围条件列放后面,范围列之后的字段无法再用于索引定位与排序——这是最左前缀原则的直接推论。Redis 缓存三类问题要能分清病因:穿透是查了根本不存在的 key(布隆过滤器或缓存空值兜住),击穿是单个热点 key 过期瞬间打穿(互斥锁重建或逻辑过期续期),雪崩是大量 key 同时失效或节点整体不可用(过期时间加随机、多级缓存、限流降级)。数据类型除了 String、List、Hash、Set、ZSet 这五种基础类型,Bitmap、HyperLogLog、GEO、Stream 在游戏场景里也常被问到。
C++ 与项目:深浅拷贝、虚函数,实习怎么讲
浅拷贝只复制指针本身,两个对象指向同一块内存,析构时就会双重释放;深拷贝重新分配并复制内容,代价是多一次内存申请,遵循「管理资源的类要自己写拷贝构造、赋值和析构」(三法则,C++11 之后加上移动语义就是五法则)。虚函数通过对象里的虚表指针找到虚函数表,在运行期完成动态绑定,基类指针才能调到派生类的实现;由此推出基类析构函数必须是虚的,否则 delete 基类指针只会析构基类部分。实习和项目这两问占了面试里相当长的时间(一面约 9 分钟、二面约 12 分钟),准备时按「业务背景 — 我的模块 — 技术难点 — 量化结果」讲,重点留给自己真正改过的那部分,容易被追问到具体实现和取舍。
系统设计与场景题:有状态无状态、分布式锁、第 k 小
有状态服务把会话或连接数据放在实例本地,扩容和故障转移都要考虑数据搬迁;无状态服务把状态外移到 Redis、数据库等共享存储,实例可以随意增删,所以无状态服务的一致性问题本质是「共享存储的读写如何保证原子与顺序」——常见做法是集中式 session、按业务 key 路由到同一实例,加上幂等设计避免重试写坏数据。分布式锁的两种主流实现是 Redis(SETNX 加过期时间,释放时用 Lua 比对唯一标识原子删除,注意业务超时导致锁提前释放)和 ZooKeeper/etcd(临时顺序节点,靠会话失效自动释放);分布式锁无法回避的取舍是「锁过期与业务执行时间」的矛盾。第 k 小那道设计题,思路是让容器同时支持插入、删除和按秩查询:平衡树(Treap、Splay、红黑树)在每个节点维护子树大小,插入删除与查第 k 小都是 O(log n),最通用但实现量大;如果值域可以离散化,树状数组或线段树上二分更简单;对顶堆只适合固定的中位数,不支持任意 k 和删除。回答时先问清「k 是否固定、是否要支持删除、并发量级」,再给方案,比直接写平衡树更能体现设计意识。整场下来一面没有手撕,二面用这道设计题替代了算法题,流程推进很快(9.4 一面、9.8 二面、9.9 HR 面、随后 OC)。