百度C++后端二面面经
- 轮次
- 二面
- 时间
- 2026-09
- 来源
- 牛客网
《面试题目》
- 你的即时通讯项目和微信相比做了哪些能力,没做什么?
- 服务端可以如何拆分模块,各模块分别负责什么?
- 关系型数据库里一般持久化哪些聊天相关数据?
- 缓存里放什么?缓存和数据库是否需要一一对应?
- 近期聊天记录为什么更适合放 Redis,而不是每次查询 MySQL?
- 压测时同时在线大概到什么量级,瓶颈先出现在哪里?
- 缓存里的新消息如何可靠同步进 MySQL?
- 每分钟大批量刷库导致瞬时写入打满,如何削峰?
- 什么情况下需要把 MySQL 数据重新加载回 Redis?
- 用户发出一条新消息后,写库和写缓存的完整顺序如何设计?
- 拉取历史消息时,如何判断缓存不够用并回源数据库?
- 你最熟悉的语言是什么,其他语言能用到什么程度?
《参考解析》
- 模块拆分:接入层维护长连接并负责鉴权、心跳和编解码;业务层处理好友、会话与消息;状态服务维护用户到节点的路由;存储层保存权威数据;异步层负责推送、刷库和告警。
- 缓存定位:MySQL 是权威数据,Redis 保存在线状态、路由、未读数和近期消息等高频视图,不必与数据库逐字段镜像。缓存应设置长度和过期策略,并保留版本或更新时间。
- 可靠刷库:消息先进入可恢复的队列或日志,再由消费者批量写入 MySQL;以 message_id 做唯一约束保证幂等,失败进入重试或死信,并监控积压与最老消息延迟。
- 削峰与扩展:将整分钟集中刷库改为分片平滑提交,限制批量大小和 worker 并发,必要时合并同会话写入;同时关注文件描述符、线程模型、广播扇出、Redis 和数据库写入瓶颈。
- 缓存回源:请求超出缓存时间窗口、key 过期或长度不足时按会话和游标分页查询 MySQL,再回填 Redis;回填使用 singleflight 或分布式锁避免击穿,空结果不能掩盖临时故障。
- 消息写入顺序:鉴权并生成唯一 message_id 后写入近期消息缓存和未读视图,向在线用户推送,再异步落库;失败通过重试和对账补偿,读取时允许从数据库恢复缺口。