SWE / SRE / Frontend · System Design / 基础

TikTok 并发设计:从共享状态到原子边界

解释竞态、锁与乐观版本,围绕项目证明不变量而非列工具。

题目重点:解释竞态、锁与乐观版本,围绕项目证明不变量而非列工具。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 项目并发问句未给固定语言;以共享计数、状态迁移与数据库版本为训练案例。

解题路线

  1. 列共享状态和不变量,再定位读写及需要原子的多步操作。race不仅是同时写,同步缺失还会造成可见性和顺序问题。
  2. 锁把需要一起变化的状态包住,统一加锁顺序避免死锁,锁内不做无预算网络I/O。细锁提高并行但增加协调和复杂度。
  3. 乐观版本读v、计算、条件写whereversion=v,失败重试;外部副作用不能在每次重试都执行,需幂等或事务/outbox。
  4. 容器线程安全只保证其合同,跨两个容器/键的业务不变量仍需协调。取消、超时与异常路径必须释放资源。
  5. 验证用可控调度、线性化历史和不变量,不只压测吞吐。性能观察锁等待、热点和P99,不能以CPU不高判定无瓶颈。

手动走一遍

余额10两个并发扣7,若都读10再写3可双花;条件扣减必须保证余额检查与扣款同原子域。读版本后HTTP发券、再CAS失败重试会重复发券,即使最终数据库正确。

规模与取舍

共享热点限制并行扩展;无锁不保证低延迟,重试成本随冲突率增长。报告正确性与吞吐/尾延迟分别验证。

易错点与追问

容易失分的边界

  • volatile解决所有复合竞态。
  • 乐观重试没有上限和幂等。
  • 为了缩锁范围打破原子不变量。

继续深挖

  • 如何定义线性化点?
  • 跨服务状态迁移怎样建幂等合同?
✓已复制微信号!