返回 Web3 笔记
Day 105

Day 105:系统设计实战 — 45分钟设计100x杠杆Perp DEX

完整45分钟面试模拟(需求分析→架构选型→核心组件→风控→扩展)、决策树、完整ASCII架构图

2026-04-22
交易系统设计面试Perp DEX架构实战Day105

核心概念

系统设计面试的本质

一句话定义:系统设计面试不是考你背架构图,而是考你在有限时间内如何做取舍(Trade-off)、如何沟通设计思路、如何应对模糊需求。

关键认知:面试官评估的不是你设计的"完美系统",而是你的"设计过程"——你如何拆解问题、做出有理有据的决策、考虑边界情况。

系统设计面试评分维度(通常5维):
═══════════════════════════════════════

维度1:需求分析(15%)
├── 能否提出正确的澄清问题?
├── 能否区分核心需求和nice-to-have?
└── 对业务有多深的理解?

维度2:架构设计(25%)
├── 架构是否合理?
├── 组件划分是否清晰?
└── 是否考虑了关键的非功能需求?

维度3:深度设计(25%)
├── 核心组件的细节设计是否到位?
├── 数据模型是否合理?
└── 关键算法是否正确?

维度4:取舍分析(20%)
├── 能否清楚说明每个选择的pros/cons?
├── 为什么选A不选B?
└── 在约束条件下是否做了最优选择?

维度5:扩展与演进(15%)
├── 系统如何scale?
├── 如何处理边界情况?
└── 如何演进为更完善的系统?

45分钟面试模拟

时间分配策略

45分钟最优时间分配:
═══════════════════════════════════════

[0-5分钟]  需求分析 & 澄清问题
[5-10分钟] 高层架构 & 技术选型
[10-30分钟] 核心组件深度设计
[30-40分钟] 风控 & 边界情况
[40-45分钟] 扩展性 & Q&A

黄金法则:
├── 前5分钟决定你的设计方向
├── 中间20分钟展示你的技术深度
├── 后10分钟展示你的全面思考
└── 全程:边画图边讲,保持沟通

Phase 1:需求分析(0-5分钟)

面试官:"请设计一个支持100x杠杆的永续合约DEX"

你的澄清问题(必须问!):
═══════════════════════════════════════

Q1:目标用户和规模?
  "这个DEX面向哪类用户?预期的日交易量和并发用户数?"
  → 假设:中大型,日交易量 $10B,10万并发用户

Q2:去中心化程度?
  "对去中心化有什么要求?纯链上还是可以接受混合架构?"
  → 假设:混合架构可接受,但资产必须自托管

Q3:支持的交易对数量?
  "初期支持多少个交易对?"
  → 假设:初期50对,长期200+

Q4:性能要求?
  "延迟和吞吐的目标?"
  → 假设:撮合延迟 <10ms,吞吐 >10万单/秒

Q5:合规要求?
  "需要KYC吗?面向哪些地区?"
  → 假设:可选KYC,全球用户

核心需求总结:
═══════════════════════════════════════

功能需求:
├── FR1:永续合约交易(多空双向)
├── FR2:100x最大杠杆
├── FR3:逐仓/全仓保证金
├── FR4:限价/市价/止损订单
├── FR5:实时清算系统
└── FR6:资金费率结算

非功能需求:
├── NFR1:撮合延迟 <10ms
├── NFR2:吞吐 >100K 单/秒
├── NFR3:可用性 99.99%
├── NFR4:资产自托管(链上合约)
└── NFR5:抗审查(L1逃生舱)

Phase 2:高层架构(5-10分钟)

架构选型决策树:
═══════════════════════════════════════

Q:需要CeFi级性能? ─── YES
  │
  Q:需要数学级公平性? ─── NO(可以后续加)
  │
  Q:需要生态可组合? ─── 不是第一优先级
  │
  → 选择:链下撮合 + 链上结算(模式一)
  → 类似:Hyperliquid模式
  → 原因:最快落地 + 最好性能 + 资产自托管

高层架构图(边画边讲):
═══════════════════════════════════════

  ┌─────────────────────────────────────────────┐
  │                    用户层                     │
  │  [Web App] [Mobile App] [Trading API]        │
  │     │          │            │                │
  │     └──────────┴────────────┘                │
  │                │                             │
  │         [API Gateway]                        │
  │         ├── 认证(签名验证)                    │
  │         ├── 限流                              │
  │         └── WebSocket管理                     │
  └─────────────────┬───────────────────────────┘
                    │
  ┌─────────────────┴───────────────────────────┐
  │              链下执行层                       │
  │                                              │
  │  ┌──────────┐  ┌──────────┐  ┌──────────┐  │
  │  │ 订单管理  │→│ 风控引擎  │→│ 撮合引擎  │  │
  │  │  (OMS)   │  │  (RMS)   │  │ (Match)  │  │
  │  └──────────┘  └──────────┘  └────┬─────┘  │
  │                                    │        │
  │  ┌──────────┐  ┌──────────┐       │        │
  │  │ 清算引擎  │  │ 资金费率  │←──────┘        │
  │  │(Liquidn) │  │(Funding) │                 │
  │  └──────────┘  └──────────┘                 │
  │       │              │                      │
  │  ┌────┴──────────────┴──────┐               │
  │  │      市场数据引擎          │               │
  │  │  ├── L1/L2行情            │               │
  │  │  ├── K线计算              │               │
  │  │  └── WebSocket推送        │               │
  │  └──────────────────────────┘               │
  └─────────────────┬───────────────────────────┘
                    │ 批量提交
  ┌─────────────────┴───────────────────────────┐
  │              链上结算层                       │
  │                                              │
  │  ┌──────────┐  ┌──────────┐  ┌──────────┐  │
  │  │ 结算合约  │  │ 保险基金  │  │ 逃生舱   │  │
  │  │(Settlement)│ │(Insurance)│ │(Escape)  │  │
  │  └──────────┘  └──────────┘  └──────────┘  │
  │                                              │
  │  ┌──────────────────────────┐               │
  │  │     资产托管合约           │               │
  │  │  ├── 用户余额管理          │               │
  │  │  ├── 充值/提现             │               │
  │  │  └── 多签管理              │               │
  │  └──────────────────────────┘               │
  └──────────────────────────────────────────────┘

为什么选这个架构?
  ├── 性能:链下撮合 → <10ms延迟,>100K TPS
  ├── 安全:链上结算 → 资产自托管
  ├── 体验:免Gas下单 → 接近CEX体验
  ├── 成本:批量提交 → 低Gas成本
  └── 可行性:团队执行最快的方案

Phase 3:核心组件深度设计(10-30分钟)

组件1:撮合引擎(选择深入讲)
═══════════════════════════════════════

设计选择:LMAX模式单线程撮合

  ┌─────────────────────────────────┐
  │       Input Ring Buffer          │
  │  [订单事件: New/Cancel/Modify]   │
  └──────────────┬──────────────────┘
                 ↓
  ┌─────────────────────────────────┐
  │    Single-Thread Processor       │
  │                                 │
  │  Per Symbol:                    │
  │  ┌────────────────────────┐     │
  │  │  Bid Book (RedBlack)  │     │
  │  │  Ask Book (RedBlack)  │     │
  │  │  Order Map (HashMap)  │     │
  │  └────────────────────────┘     │
  │                                 │
  │  撮合算法:Price-Time Priority   │
  │  状态:全部在内存中(~5GB)       │
  └──────────────┬──────────────────┘
                 ↓
  ┌─────────────────────────────────┐
  │       Output Ring Buffer         │
  │  [成交/订单状态/行情事件]         │
  └─────────────────────────────────┘

为什么单线程?
  ├── 消除锁竞争 → 零等待
  ├── CPU缓存友好 → 热路径常驻L1/L2
  ├── 可预测延迟 → P99 <100μs
  └── 简单可靠 → 更少bug

分片策略:
  每个交易对一个独立的撮合引擎实例
  BTC-USDT: Engine #1 (CPU Core #0)
  ETH-USDT: Engine #2 (CPU Core #1)
  ...
  → 50个交易对 = 50个实例 = 50个CPU核心

组件2:清算引擎
═══════════════════════════════════════

清算流程设计:

  [标记价格服务] ─→ 每秒更新
         │
         ↓
  [保证金扫描器] ─→ 每秒扫描所有仓位
         │
         ├─→ 健康仓位:跳过
         ├─→ 预警仓位:发送通知
         └─→ 待清算仓位:
              │
              ↓
         [分级清算执行器]
              │
              ├─→ Step1: 清算25%仓位
              │   └─→ 重新评估
              ├─→ Step2: 必要时继续
              └─→ Step3: 直到安全

标记价格计算:
  indexPrice = weightedAvg([
    { source: "Binance", weight: 0.30 },
    { source: "OKX",     weight: 0.25 },
    { source: "Coinbase", weight: 0.25 },
    { source: "Bybit",   weight: 0.20 },
  ])
  // 异常值过滤 + TWAP平滑
  markPrice = indexPrice + EMA(basis, 5min)

分级保证金表:
  ┌──────────────┬────────────┬──────────┐
  │ 仓位范围      │ 最大杠杆    │ 维持保证金 │
  ├──────────────┼────────────┼──────────┤
  │ $0-$50K      │ 100x       │ 0.5%     │
  │ $50K-$250K   │ 50x        │ 1.0%     │
  │ $250K-$1M    │ 20x        │ 2.5%     │
  │ $1M+         │ 10x        │ 5.0%     │
  └──────────────┴────────────┴──────────┘

组件3:链上结算合约
═══════════════════════════════════════

核心合约设计:

  PerpExchange.sol
  ├── deposit(amount)      // 充值
  ├── withdraw(amount, sig) // 提现(需要链下签名)
  ├── settleBatch(trades[]) // 批量结算
  ├── liquidate(account)    // 清算
  ├── forceWithdraw()       // 逃生舱
  └── updateInsuranceFund() // 保险基金

结算批次设计:
  每 N 秒(如10秒)提交一个批次到链上
  批次内容:
  ├── 新成交列表
  ├── 清算列表
  ├── 资金费率结算
  ├── 新的状态根(Merkle Root)
  └── Sequencer签名

Phase 4:风控与边界情况(30-40分钟)

必须提到的风控设计:
═══════════════════════════════════════

1. 预交易风控(< 100μs)
   ├── 资金检查
   ├── 仓位限额
   ├── 价格合理性
   └── 频率限制

2. 保险基金
   ├── 初始规模:$10M(团队注资)
   ├── 收入:清算手续费 + 强平利润
   ├── 目标:> OI的1%
   └── 链上可验证

3. ADL(自动减仓)
   ├── 触发:保险基金不足
   ├── 排序:盈利比例 × 杠杆
   └── UI:ADL指示灯

4. 熔断机制
   ├── 5分钟内价格变动 > 10%:暂停1分钟
   ├── 保险基金消耗 > 30%/天:降低最大杠杆
   └── 系统级风控可由DAO调整

边界情况必须讨论:
═══════════════════════════════════════

Case 1:Sequencer宕机
  → 逃生舱:用户可在L1直接提现
  → 恢复:从WAL重放恢复状态
  → SLA:< 5分钟恢复

Case 2:预言机故障
  → 多源冗余(4个以上价格源)
  → 故障检测:偏离中位数>5%自动剔除
  → 最坏情况:切换到链上TWAP

Case 3:巨鲸操纵(JELLY事件)
  → 单地址仓位上限(OI的5%)
  → 大额清算人工审核
  → 保险基金不主动接盘(选择ADL)

Case 4:DDoS攻击
  → API限流 + 负载均衡
  → 核心服务与公共服务隔离
  → 自动降级(关闭新用户注册)

Phase 5:扩展性与Q&A(40-45分钟)

未来扩展方向:
═══════════════════════════════════════

短期(1-3个月):
├── 支持更多交易对(50 → 200)
├── 组合保证金(Portfolio Margin)
├── 移动端APP
└── API v2(更低延迟)

中期(3-6个月):
├── 期权交易
├── 跨链入金(支持多链充值)
├── Sequencer去中心化(多节点轮换)
└── ZK证明(可选的公平性验证)

长期(6-12个月):
├── 完全去中心化的Sequencer网络
├── App-chain迁移(自主权)
├── 合规层(KYC Hooks)
└── AI风控引擎

演进路径:
  Phase 1(现在):中心化Sequencer → 快速上线
  Phase 2(3月后):多Sequencer轮换 → 减少单点
  Phase 3(6月后):去中心化网络 → 抗审查
  Phase 4(12月后):ZK验证 → 信任最小化

面试评分维度与常见追问

评分标准(面试官视角):
═══════════════════════════════════════

Strong Hire(4/5)需要:
├── 清晰的需求分析(提了5+个好问题)
├── 合理的架构选型(能说明为什么选A不选B)
├── 至少2个组件的深度设计
├── 主动提到风控和边界情况
└── 良好的沟通(边画边讲,节奏好)

Hire(3/5)需要:
├── 基本的需求理解
├── 可工作的架构设计
├── 至少1个组件的深度设计
└── 提到了一些风控考虑

No Hire(1-2/5)的表现:
├── 没有澄清需求就开始设计
├── 架构不合理或无法解释选择
├── 没有深度(只有高层框图)
├── 忽略风控和边界情况
└── 无法回答追问

常见追问(准备好!):
═══════════════════════════════════════

追问1:"如果Sequencer作恶怎么办?"
  → 逃生舱 + 经济惩罚 + 渐进去中心化
  → 短期靠声誉,长期靠ZK证明

追问2:"如何处理资金费率结算的一致性?"
  → 链下计算,链上结算批次中包含
  → 使用快照时间点,所有仓位同时结算
  → 资金费率 = f(Mark-Index) × Position × Time

追问3:"这个系统最大的风险是什么?"
  → Sequencer中心化是最大风险
  → 缓解:逃生舱 + 多Sequencer + ZK路线图
  → 保险基金不足是第二大风险

追问4:"如何与Hyperliquid竞争?"
  → 差异化:ZK证明公平性 / 更好的合规层 / 更多资产
  → 不要在性能上硬拼(Hyperliquid已经很强)
  → 找到被忽视的用户需求

追问5:"如果要你只设计一个组件,你设计什么?"
  → 选清算引擎(最核心、最复杂、最关乎安全)
  → 然后深入讲解清算瀑布的每一层

面试实战技巧

10个实战技巧:
═══════════════════════════════════════

1. 永远先问问题
   "在开始设计之前,我想澄清几个需求..."
   → 展示你的产品思维

2. 大声说出你的思考过程
   "我在考虑两个方案:A和B。A的优势是...B的优势是...
    考虑到我们的需求,我选择A,因为..."
   → 展示你的决策能力

3. 画图!画图!画图!
   → 白板/共享屏幕上始终有图
   → 高层图 → 逐步细化

4. 数字说话
   "10万并发用户,每人每秒1个请求,
    10万QPS,每个请求处理100μs,
    需要10个处理线程..."
   → 展示你会做容量估算

5. 主动提风控
   不要等面试官问
   → "在继续之前,我想讨论一下风控设计..."

6. 承认不知道
   "这个具体实现我不太确定,但我的思路是..."
   → 比胡说八道好100倍

7. 时间管理
   → 如果发现某个话题花太多时间
   → "为了时间效率,这部分我先标记,
      后面有时间再详细讨论"

8. 关注取舍,不是完美
   → 没有完美的设计
   → 重要的是你能说明为什么这样取舍

9. 提到演进路径
   → "V1我们先做A,V2再加B"
   → 展示你理解产品是迭代的

10. 结尾总结
    "让我总结一下今天的设计:
     我们选择了X架构,核心是Y和Z,
     最大的风险是W,缓解方案是..."
    → 给面试官一个清晰的印象

产品经理视角

PM在系统设计面试中的独特优势:
═══════════════════════════════════════

1. 需求分析更深入
   ├── 不只问技术参数
   ├── 问用户是谁、痛点是什么、如何衡量成功
   └── 这是纯工程师容易忽略的

2. 取舍能力更强
   ├── PM天天做取舍
   ├── 能清楚说明为什么牺牲X换取Y
   └── 不会陷入"追求完美"的陷阱

3. 产品直觉
   ├── 知道用户真正在意什么
   ├── 知道哪些功能是MVP,哪些是V2
   └── 设计更贴近实际需求

4. 沟通能力
   ├── PM的核心技能
   ├── 能把复杂设计讲得清楚易懂
   └── 面试官印象更好

10年金融经验的加分项:
├── 知道真实交易系统长什么样
├── 知道清算/风控的实际运作
├── 知道监管合规的要求
├── 知道用户(交易者)的真实需求
└── 这些是书本上学不到的

明日预告

Day 106:做市策略与流动性管理 — 从价差报价到库存管理

  • 做市商的核心商业模式
  • Avellaneda-Stoikov 做市模型
  • 库存风险管理
  • DeFi自动做市(AMM)vs 传统做市
  • 做市商产品设计要点