常见系统设计题

总结摘要
常见系统设计题

一、设计短链系统

核心问题

https://www.example.com/article/123456789 变成 https://t.cn/Ab3dEf

答题框架

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
① 需求澄清
   - 日活多少?假设 1000万 DAU
   - 短链有效期?假设永久有效
   - 读写比例?读远大于写(100:1)

② 容量估算
   - 每天生成短链:100万条
   - 1年:3.65亿条 → 需要 62位(2^62 > 10^18)
   - 存储:每条短链 500字节 → 3.65亿 × 500B ≈ 180GB/年

③ 核心设计:短链怎么生成?
   
   方案A:哈希(MD5/SHA256)→ 冲突问题
   方案B:自增ID转62进制 → 规律暴露,不安全
   方案C:发号器(雪花算法)→ ✅ 推荐

   雪花算法:1位符号 + 41位时间戳 + 10位机器ID + 12位序列号
   → 你简历里做过分布式系统,这个能讲

④ 存储设计
   - 短链 → 长链 映射:Redis(热数据)+ MySQL(持久化)
   - 表结构:(short_code PK, long_url, create_time, expire_time)
   - 索引:short_code 唯一索引

⑤ 跳转优化
   - 301 永久重定向(浏览器缓存,减轻服务器压力)
   - 布隆过滤器:防止无效短链查库(缓存穿透)

⑥ 高可用
   - 发号器多机部署,机器ID区分
   - Redis 主从 + 哨兵

一句话总结

“短链系统核心是解决发号映射两个问题。发号用雪花算法保证唯一,映射用 Redis + MySQL 分层,跳转用 301 缓存优化。”


二、设计消息队列(结合你 RAG 项目的 RabbitMQ 经验)

核心问题

实现一个类似 Kafka/RabbitMQ 的消息中间件

你的答题框架

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
① 核心功能
   - 生产者 → Broker → 消费者
   - 支持 Topic/Queue 模型
   - 消息持久化、ACK确认、重试机制

② 存储设计(最关键)
   
   Kafka 做法:顺序写磁盘 + 零拷贝
   - 每个 Topic 分 Partition
   - 每个 Partition 是追加写的日志文件
   - 索引文件(.index)加速定位

   为什么磁盘比内存慢但 Kafka 很快?
   → 顺序写磁盘 ≈ 内存随机写,且 OS 会预读缓存

③ 你的经验可以套
   
   你在 RAG 项目里用过 RabbitMQ:
   - "我用 RabbitMQ 做了解耦,生产者解析文档入队,
      消费者异步处理向量化"
   - "我实现了手动 ACK + 消息不重复入队,异常时标记失败状态"
   
   把这些迁移到设计题:
   - "Broker 需要维护消费偏移量(offset),
      消费者宕机后能从上次位置继续消费"
   - "为了防止消息丢失,生产者需要收到 Broker 的 ACK 才认为发送成功"

④ 高可用
   - 多副本机制(Leader-Follower)
   - ISR(In-Sync Replicas)列表,只有同步完成的副本才算

一句话总结

“消息队列核心是顺序写磁盘保证吞吐,分区保证扩展,多副本保证可靠。我在 RAG 项目里用 RabbitMQ 实现了异步文档处理,理解了 ACK 和持久化的重要性。”


三、设计秒杀系统(结合你限流熔断的经验)

核心问题

100万人抢100个商品,怎么保证不超卖、不崩

你的答题框架

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
① 核心挑战
   - 瞬时高并发(QPS 100万+)
   - 不能超卖(库存扣减一致性)
   - 用户体验(不能卡顿/报错)

② 流量分层过滤(层层削峰)
   
   浏览器 → CDN → Nginx → 网关 → 服务 → DB
   
   - CDN:静态资源缓存,减少回源
   - Nginx:限流(漏桶/令牌桶),你简历写过!
   - 网关:鉴权 + 限流,无效请求直接拒
   - 服务:库存预扣,异步下单

③ 库存扣减方案(防超卖)
   
   ❌ 直接查库:SELECT stock → UPDATE stock
      并发下会超卖
   
   ✅ Redis 预扣 + Lua 脚本(原子操作)
      EVAL "if redis.call('get', KEYS[1]) > 0 then 
            return redis.call('decr', KEYS[1]) 
            else return -1 end" 1 stock:1001
   
   ✅ 数据库乐观锁
      UPDATE stock SET count = count - 1 
      WHERE product_id = 1001 AND count > 0

④ 异步下单(削峰)
   - 秒杀成功 → 发消息到 MQ → 异步创建订单
   - 前端轮询或 WebSocket 推送结果

⑤ 你的经验可以套
   
   你简历写了"令牌桶限流 + 状态机熔断":
   - "我在 RPC 框架里实现了令牌桶限流,秒杀场景可以用
      漏桶/令牌桶在网关层限流,保护后端"
   - "熔断机制防止雪崩,如果库存服务挂了,快速失败"

一句话总结

“秒杀核心是层层限流削峰Redis 原子扣库存防超卖,异步下单保证体验。我在 RPC 框架里实现的限流熔断策略可以直接复用。”


四、设计评论系统(结合你 MySQL 索引优化经验)

核心问题

微博/抖音的评论功能,支持分页、点赞、回复

你的答题框架

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
① 数据模型
   
   评论表 comments:
   - id, content, user_id, post_id, parent_id(回复用), create_time
   
   点赞表 likes:
   - id, comment_id, user_id, create_time

② 分页查询优化(你简历写过慢 SQL 优化!)
   
   ❌ 深度分页:SELECT * FROM comments 
               WHERE post_id = 100 ORDER BY create_time 
               LIMIT 100000, 10
      → 扫描10万行,慢!
   
   ✅ 游标分页:SELECT * FROM comments 
               WHERE post_id = 100 AND create_time < '2024-01-01'
               ORDER BY create_time DESC LIMIT 10
      → 走索引,快!
   
   ✅ 或者:SELECT * FROM comments WHERE id > 100000 LIMIT 10

③ 点赞计数
   
   - 高频操作,不能每次查 COUNT(*)
   - 方案:Redis 计数 + 定时回写 MySQL
   - 或者:评论表冗余 like_count 字段,异步更新

④ 冷热数据分离
   
   - 热评(最近7天):Redis 缓存
   - 历史评论:MySQL 归档表

五、设计分布式 ID 生成器(最简单,先掌握)

核心问题

单机自增 ID 有瓶颈,分布式环境下怎么生成唯一 ID

你的答题框架

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
① 方案对比

   | 方案 | 优点 | 缺点 |
   |------|------|------|
   | UUID | 简单 | 无序、太长、不适合做索引 |
   | 数据库自增 | 简单 | 单点、性能差 |
   | 雪花算法 | 趋势递增、高性能 | 依赖时钟 |
   | 号段模式(Leaf) | 数据库压力小 | 需要维护 |

② 雪花算法详解(重点讲这个)
   
   64位 Long 型:
   - 1位:符号位(0)
   - 41位:时间戳(毫秒级,可用69年)
   - 10位:机器ID(支持1024台机器)
   - 12位:序列号(每毫秒4096个ID)

   时钟回拨问题:
   - 发生时等待或抛异常
   - 或者记录上次时间戳,回拨时拒绝生成

③ 你的经验
   
   你在 RPC 框架里做过服务注册发现:
   - "机器ID可以通过 Nacos 动态分配,
      或者启动时从配置中心获取"

总结

系统核心知识点你能套用的经验
短链雪花算法、Redis 缓存分布式系统经验
消息队列顺序写磁盘、分区、副本RabbitMQ 使用经验
秒杀限流削峰、Redis 原子操作令牌桶限流、熔断
评论分页优化、冷热分离慢 SQL 优化经验
分布式 ID雪花算法服务注册发现