【C++】面试:系统设计与性能优化

C++ 高级面试、公司技术栈深度考察模块,系统设计综合能力评估,性能优化考察工程落地能力。结合项目讲出彩。


1. 系统设计基础

1.1 设计原则

  • 高可用:冗余 + 故障转移
  • 高扩展:水平扩展、模块化
  • 高性能:缓存、异步、并发
  • 高可靠:一致性、容错

1.2 扩展方式

  • 水平扩展:加机器(无状态服务)
  • 垂直扩展:升级单机配置
  • 分片:按维度拆分数据

2. 短链系统设计

2.1 核心功能

  • 长链接 -> 短链接
  • 短链接 -> 重定向长链接
  • 访问统计

2.2 存储设计

复制代码
表 structure:
id, 短码, 长URL, 创建时间, 访问次数

2.3 Hash 算法

  • MD5/SHA1(摘要)
  • 自增 ID + 62进制转换
  • 雪花算法分片

2.4 高并发优化

  • 本地缓存(LRU)
  • Redis 缓存
  • 布隆过滤
  • 限流

2.5 面试问题

  • 冲突怎么办? 查表冲突改用备选码
  • 如何反查? BASE62 逆向 / DB 查询
  • 如何防攻击? IP 限速 + 验证码

3. 抢票/秒杀系统

3.1 核心挑战

  • 高并发雪崩
  • 超卖
  • 机器人刷票

3.2 架构设计

复制代码
┌──────────────┐
│  CDN/Nginx  │  ← 静态资源、限流
└──────────────┘
     ↓
┌──────────────┐
│  Gateway    │  ← 鉴权、限流
└──────────────┘
     ↓
┌──────────────┐
│  消息队列   │  ← 削峰填谷
└──────────────┘
     ↓
┌──────────────┐
│  库存服务    │  ← 原子扣减
└──────────────┘
     ↓
┌──────────────┐
│  DB         │  ← 数据库
└──────────────┘

3.3 关键技术

  • Redis 原子扣减:DECR
  • 乐观锁:version
  • 分布式锁:Redisson
  • 消息队列:Kafka/RabbitMQ
  • 限流:令牌桶 / 滑动窗口

3.4 防超卖

cpp 复制代码
// 错误
stock = stock - 1;    // 多个线程读到相同库存

// 正确
if (redis.decr(goods_stock) >= 0) {
    // 扣减成功,写入 MQ
} else {
    // 库存不足
}

4. 消息队列

4.1 作用

  • 异步:削峰填谷
  • 解耦:生产/消费分离
  • 可靠:消息持久化

4.2 常见 MQ

MQ 特点 场景
Kafka 高吞吐、日志 大数据
RabbitMQ 多协议、灵活 通用
RocketMQ 金融、事务 电商
Redis 轻量 临时

4.3 消息顺序

  • 同一个 Partition 有序
  • 全局有序:单分区
  • 业务有序:消息体带序号

4.4 消息持久化

  • 磁盘顺序写
  • RAID 阵列
  • 多副本 replicas

5. 缓存系统

5.1 缓存策略

  • Cache-Aside

    • 读:先缓存,后 DB
    • 写:先 DB,后删除缓存
  • Write-Through

    • 同步双写
  • Write-Behind

    • 异步写 DB

5.2 淘汰策略

策略 特点 场景
LRU 最近最少使用 通用
LFU 最少使用频率 热点数据
FIFO 先进先出 无差别
Random 随机 无差别

5.3 缓存问题

  • 缓存穿透:布隆过滤 / 空值缓存
  • 缓存击穿:互斥锁 / 永不过期
  • 缓存雪崩:TTL 随机 + 多级缓存

5.4 一致性

  • 删除 vs 更新的选择
  • 延迟双删
  • 最终一致性

6. 分库分表

6.1 何时分

  • 单表 > 1000万
  • 单库 > 100GB
  • QPS > 5000

6.2 分片策略

  • Range :按时间|ID范围
    • 优点:范围查询简单
    • 缺点:热点不均
  • Hash :取模
    • 优点:数据均匀
    • 缺点:扩展难

6.3 迁移步骤

  1. 双写(同步 + 异步)
  2. 灰度切读
  3. 切写
  4. 下线

7. 性能优化

7.1 CPU 优化

  • 代码优化:减少计算
  • 向量化:SIMD
  • 并行:OpenMP

7.2 内存优化

  • 内存池:减少分配
  • 对象池:复用对象
  • 预分配:减少扩容
  • 减小对象:short/int

7.3 IO 优化

  • 零拷贝:sendfile
  • 缓冲 IO:减少系统调用
  • 顺序写:日志优化
  • 熔断:快速失败

7.4 网络优化

  • 连接池:复用连接
  • HTTP/2:多路复用
  • GZIP:压缩
  • CDN:就近访问

8. 性能指标

8.1 核心指标

  • QPS(Queries Per Second)
  • TPS(Transactions Per Second)
  • RT(Response Time)
  • PV(Page Views)
  • UV(Unique Visitors)

8.2 计算公式

复制代码
QPS = PV / 时间
TPS = 成功事务数 / 时间
RT = 完成时间 - 开始时间
并发 = TPS * RT

8.3 性能目标

量级 QPS 说明
小型 < 100 个人项目
中型 100-1000 小团队
大型 1000-10000 公司级
巨型 > 10000 BAT 级别

9. 分布式系统

9.1 CAP 定理

Consistency(一致)+ Availability(可用)+ Partition tolerance(分区容错)

  • 最多同时满足两个
  • CP:Zookeeper
  • AP:Eureka

9.2 BASE 理论

  • Basically Available:基本可用
  • Soft state:软状态
  • Eventually consistent:最终一致

9.3 分布式事务

  • 2PC :两阶段提交
    • Prepare + Commit
    • 协调者单点
  • 3PC :三阶段提交
    • CanCommit + Prepare + Commit
  • TCC :Try + Confirm + Cancel
    • 业务侧实现
  • Saga :链式补偿
    • 正向逆向

10. 监控与诊断

10.1 监控体系

  • 基础设施:CPU/内存/磁盘/网络
  • 应用:QPS/RT/错误率
  • 业务:订单/转化率
  • 链路:TraceId

10.2 工具

类型 工具 场景
性能 perf/VTune CPU 分析
内存 valgrind/ASAN 内存问题
并发 helgrind 线程竞争
IO iostat/sar IO 瓶颈
网络 netstat/tcpdump 网络问题

10.3 常见问题

  • CPU 100%:死循环/计算密集
  • 内存泄漏:对象未释放
  • 响应慢:SQL 慢/GC/锁竞争
  • OOM:内存溢出/GC 频繁

🔥 本章综合高频追问

  1. :如何设计一个抢票系统?

    :MD2 详细展开,先解决高并发扣减。

  2. :Redis 缓存挂了怎么办?

    :多级缓存 + 熔断降级 + 本地缓存。

  3. :分库分表如何查询?

    :路由 + 聚合 / 异构索引 / 使用搜索引擎。

  4. :如何保证 CK ?

    :BASE 理论,最终一致性。


📝 模块总结

本模块覆盖系统设计核心 短链、秒杀、缓存、分库 ,以及 CAP、性能优化,结合项目深入讲解。可应对高级技术面,展示工程能力与架构思维。