← 返回面试专题

📱 信息流/朋友圈如何设计?

核心目标:高性能读写、关注关系、推荐算法、缓存策略

🧩 典型题干

设计一个信息流系统: - 高性能读写 - 关注关系 - 推荐算法 - 缓存策略

📚 学习正文:信息流系统如何做到既快又准?

交互图:信息流关键链路闭环(点步骤看推拉/缓存/一致性)

核心面试话术:写路径决定成本(扇出/队列/去重),读路径决定体验(缓存/分页/回源),大V 用读扩散防扇出爆炸,普通用户用写扩散保证读快。

1) 发帖写入:先把内容变成“可复用的事实”

  • 内容存储:content 表(或内容服务)写入一次,生成 contentId/时间戳。
  • 事件驱动:发帖后发 MQ 事件(作者、contentId、发布时间),进入扇出流水线。
  • 幂等:防重复发布/重试导致多条记录(clientPostId)。

1) 需求澄清与量级

2) 核心挑战

写扩散:用户发布时写入所有粉丝时间线(适合大V) 读扩散:用户读取时聚合所有关注者内容(适合普通用户) 混合模式:根据粉丝数动态选择扩散策略 缓存策略:热点内容缓存、冷数据淘汰

3) 数据模型设计

4) 推拉结合策略

1) 大V发布:写扩散,直接推送到粉丝时间线 2) 普通用户发布:读扩散,用户拉取时聚合 3) 动态阈值:根据粉丝数实时选择策略 4) 异步化:所有写操作异步处理,提升响应速度

系统架构图(面试时用它讲全链路)

客户端(App/Web) | v 网关/API(鉴权/限流) | v 内容服务(写 content 表/存储) - 生成 contentId/time - 发出 FeedEvent(MQ) | +--> 关注关系服务(follow graph) | +--> 扇出服务 Fanout(异步 worker) | - 普通用户:写扩散 -> user_inbox(收件箱/时间线) | - 大V:读扩散 -> author_outbox(作者发布列表) | +--> 缓存层 - user_inbox 缓存(活跃用户) - author_outbox 缓存(热点作者) - 内容详情缓存(contentId -> content) 读路径(Feed API): - 写扩散:读 user_inbox(游标分页) -> 批量拉 content - 读扩散:合并关注作者 outbox(topK merge) -> 批量拉 content 过滤与一致性: - 删除/屏蔽/违规:读时过滤 + 必要回源校验 - 回收任务:清理无效指针/补偿遗漏扇出 观测:扇出延迟、inbox 大小、热点作者 QPS、缓存命中率、P95/P99

5) 缓存架构设计

6) 推荐与排序

时间排序:简单高效,适合朋友圈 兴趣排序:基于用户行为和内容标签 混合排序:时间 + 权重 + 推荐分数 实时更新:用户行为实时影响排序结果

🎯 面试题(建议学完上面正文再做)

1. 需求澄清:你会问哪些关键问题?简单
  • 产品形态:纯时间线还是带推荐排序?
  • 量级:DAU、关注数、发帖频率、读 QPS。
  • 一致性:是否允许短暂延迟?是否必须按时间严格排序?
  • 删除/屏蔽:拉黑、删除、违规内容如何影响时间线。
2. 写扩散 vs 读扩散怎么选?中等
  • 写扩散:作者发帖时把动态推入粉丝收件箱(读快写重)。适合读多写少。
  • 读扩散:只存作者发布列表,读时聚合关注作者(写轻读重)。适合关注数小、读量不爆。
  • 混合策略:普通用户写扩散,大 V/热点用户读扩散(避免扇出爆炸)。
3. 热点作者(千万粉丝)如何处理?困难
  • 对热点作者采用读扩散:粉丝拉取时再合并热点作者的发布列表。
  • 异步化与分片:写扩散时分片扇出,落到多队列/多 worker,避免瞬时打爆。
  • 分层缓存:热点作者发布列表缓存,粉丝收件箱只存指针或 seq。
4. 时间线分页怎么做,避免重复/漏数据?困难
  • 避免 offset:用 游标分页(timestamp + id)或 seq。
  • 写扩散收件箱:按 seq 倒序,游标就是 lastSeq。
  • 读扩散聚合:合并多个有序列表,返回 nextCursor(最小 timestamp/id)。
5. 面试 2 分钟总结怎么讲?中等
  1. 先澄清量级与一致性要求。
  2. 普通用户写扩散(读快),热点作者读扩散(防扇出爆炸)。
  3. 时间线用游标分页保证不重不漏,缓存与异步扇出保证稳定性。
  4. 屏蔽/删除/违规通过过滤层与回收任务收敛。