← 2026-05-18 📂 All Days 2026-05-21 →

🏗️ 系统设计 / System Design — Day 39

主题 / Topic: 分布式共识 — Raft 与 Paxos / Distributed Consensus (Raft/Paxos)

难度 / Difficulty: Expert | 阶段 / Phase: Mastery


想象你在设计...

你在构建一个分布式数据库集群(想想 etcd、CockroachDB 或 Kafka)。你需要让 5 台机器就"谁是 leader"、"写操作按什么顺序执行"达成一致意见。

如果没有共识算法,任何一台机器宕机都可能导致脑裂(split-brain)——两个节点都认为自己是 leader,各自接受写入,数据永久分叉。

Imagine you're designing a distributed database cluster (like etcd, CockroachDB, or Kafka's KRaft). You need 5 machines to agree on "who is the leader" and "in what order writes happen." Without consensus, any machine failure risks split-brain — two nodes both think they're leader, data forks forever.


ASCII 架构 / Architecture

Client │ Write Request ▼ ┌─────────┐ │ Leader │ ← elected by majority vote │ Node 1 │ └────┬────┘ │ AppendEntries RPC (log replication) ┌────┼─────────┐ ▼ ▼ ▼ Node2 Node3 Node4 Node5 (F) (F) (F) (F) F = Follower Quorum = ⌊N/2⌋ + 1 = 3 out of 5 must acknowledge before leader commits an entry. Leader Election: Follower timeout → Candidate → RequestVote RPC Gets majority → becomes Leader → heartbeat starts

核心概念 / Core Concepts

Raft — 为可读性而设计 / Designed for Understandability

Raft 把共识问题分解成三个相对独立的子问题:

  1. Leader 选举 — 随机超时,先超时先投票
  2. 日志复制 — Leader 把日志条目发给所有 Follower,得到多数 ACK 后提交
  3. 安全性 — 已提交的日志条目永不丢失(只有拥有最新日志的节点才能成为 Leader)

Raft splits consensus into three relatively independent sub-problems:

  1. Leader Election — randomized timeouts, first to time out requests votes
  2. Log Replication — leader appends, waits for majority ACK, then commits
  3. Safety — committed entries are never lost (only node with most up-to-date log can win election)

Raft 核心保证 / Core Guarantee:

Term N 中已提交的日志条目,在 Term N+1 的新 Leader 中一定存在。
An entry committed in Term N is guaranteed to exist in any leader elected in Term N+1.

Paxos — 更通用但更难理解 / More General but Harder

Phase 1a: Proposer sends Prepare(n) to majority
Phase 1b: Acceptors respond with Promise (if n > any seen)
Phase 2a: Proposer sends Accept(n, value) with highest seen value
Phase 2b: Acceptors accept if n >= promised; Learners learn when majority accepts

Multi-Paxos 优化:选出稳定 Leader 后跳过 Phase 1,性能接近 Raft。

Multi-Paxos optimization: skip Phase 1 after stable leader elected — performance close to Raft.


关键权衡 / Key Tradeoffs

维度RaftPaxos (Multi)
可理解性✅ 高❌ 低
工程实现✅ 直观❌ 复杂
灵活性🔶 固定模型✅ 更通用
性能相当相当
实际使用etcd, Consul, TiKVChubby (Google), Zookeeper (ZAB ≈ Paxos)

CAP 下的位置: 共识算法实现 CP — 有网络分区时宁可拒绝请求,也不接受可能不一致的写入。


为什么这样设计?

为什么需要 Quorum(多数派)?

  • 5 节点集群可容忍 2 个节点宕机
  • 任何两个多数派集合至少有 1 个共同节点 → 保证信息传递
  • N=2f+1 节点可容忍 f 个故障

Why Quorum? Any two majority sets share at least 1 node, guaranteeing information propagation. N=2f+1 nodes tolerate f failures.

为什么随机化选举超时?

防止所有 Follower 同时成为 Candidate 造成票数分裂(split vote)。

**Why randomized election timeouts?** Prevents all followers from simultaneously becoming candidates (split vote → no winner → livelock).

别踩这个坑 / Common Mistakes

❌ 认为 Raft/Paxos 解决了一切 — 它们只解决单值或日志顺序共识,不解决拜占庭故障(节点可能发恶意消息)。拜占庭容错需要 PBFT 或 BFT 变种。

❌ 忘记 Leader 选举期间的不可用性 — 典型 Raft 实现选举超时 150-300ms,选出新 Leader 需要 1-2 轮 RTT。在此期间请求被拒绝。

❌ 混淆"已提交"与"已应用" — 日志条目被多数派确认叫"committed",被状态机执行叫"applied"。读从 Leader 读是强一致,从 Follower 读可能读到"committed but not applied"。

❌ Assuming Raft/Paxos handles everything — they handle ordering/consensus, NOT Byzantine faults (malicious nodes). Byzantine fault tolerance needs PBFT.


真实系统 / Real Systems

  • etcd — Kubernetes 的 backing store,使用 Raft,是学习 Raft 的最佳代码库
  • CockroachDB / TiKV — Raft group per range/region
  • Apache Kafka KRaft — 2.8+ 用 Raft 替代 ZooKeeper
  • Google Spanner — Paxos groups,结合 TrueTime 实现外部一致性

📚 参考资料 / References

  1. The Raft Consensus Algorithm (raft.github.io) — 原论文 + 可视化动画
  2. In Search of an Understandable Consensus Algorithm (Ongaro & Ousterhout, 2014) — Raft 原论文
  3. Paxos Made Simple — Leslie Lamport (2001)
  4. etcd Raft implementation — 生产级实现

🧒 ELI5

想象一个 5 人委员会做决定。Raft 的规则是:一个人举手说"我来主持会议",只要有 3 人(多数)说"好",他就成为主持人。主持人提议每件事,只要 3 人点头,这件事就正式通过。如果主持人突然消失,大家等一段随机时间,第一个说"我来"并获得 3 票的人成为新主持人。

Imagine a 5-person committee making decisions. The rule: one person raises their hand "I'll chair the meeting" — if 3+ people say "OK," they're the chair. Chair proposes everything, and items only pass with 3+ nods. If the chair disappears, everyone waits a random time, and the first person who asks and gets 3 votes becomes the new chair.

💻 算法 / Algorithms — Day 40

题目 / Problem: #138 Copy List with Random Pointer

难度 / Difficulty: 🟡 Medium | 模式 / Pattern: Linked List (6/11)

阶段 / Phase: Mastery


🧩 链表技巧模式 (6/11) — 在第 41 天的模版基础上继续 / Building on the Template from Day 41

前 5 题回顾:Reverse → Merge → Cycle Detection → Reorder → Remove Nth

今天:深拷贝带随机指针的链表 — 需要 Hash Map,不能用快慢指针

Previous 5: Reverse → Merge → Cycle Detection → Reorder → Remove Nth

Today: Deep copy a linked list with random pointers — requires Hash Map, fast-slow pointer won't help here

与模版的关系: 快慢指针解决"遍历类"问题,这题是"复制类"问题 — 关键挑战是 random 指针可以指向链表中任意节点,包括还没遍历到的节点。

Relationship to template: Fast-slow handles traversal/detection problems; this is a copy problem. The challenge: random pointer can point to any node, including ones you haven't visited yet.


🔗 链接 / Links


现实类比 / Real-World Analogy

你有一本通讯录,每条联系人有:

  • next:下一条联系人
  • random:"最佳朋友",指向通讯录中的任意一人

你要完整复制这本通讯录,包括所有的"最佳朋友"关系。

难点:复制第 1 个人时,他的"最佳朋友"可能是第 5 个人,但第 5 个人还没复制出来。

You have an address book. Each contact has next (next person) and random (their "best friend" — anyone in the book). Challenge: when copying person #1, their best friend might be person #5, who doesn't exist in the new book yet.


问题描述 / Problem

# Node definition
class Node:
    def __init__(self, x, next=None, random=None):
        self.val = x
        self.next = next
        self.random = random

# Input: head of linked list, random can point to any node or null
# Output: deep copy — completely new nodes, same structure

解法:两次遍历 + Hash Map / Two-Pass with Hash Map

核心思路 / Key Insight:

第一遍:遍历原链表,为每个节点创建对应的新节点,存入 {old_node: new_node} 映射。

第二遍:再次遍历,用 hash map 设置每个新节点的 next 和 random。

Pass 1: Create new node for each original node, store in {old: new} map.

Pass 2: Wire up next and random using the map.

def copyRandomList(head):
    # Edge case
    if not head:
        return None
    
    # Pass 1: Create all new nodes
    old_to_new = {}
    curr = head
    while curr:
        old_to_new[curr] = Node(curr.val)  # create copy, no links yet
        curr = curr.next
    
    # Pass 2: Wire up next and random
    curr = head
    while curr:
        if curr.next:
            old_to_new[curr].next = old_to_new[curr.next]
        if curr.random:
            old_to_new[curr].random = old_to_new[curr.random]
        curr = curr.next
    
    return old_to_new[head]

执行追踪 / Trace:

Input: 1 → 2 → 3, random: 1→3, 2→1, 3→2 Pass 1 (create nodes): old_to_new = {1: Node(1), 2: Node(2), 3: Node(3)} Pass 2 (wire links): Node(1).next = Node(2), Node(1).random = Node(3) Node(2).next = Node(3), Node(2).random = Node(1) Node(3).next = None, Node(3).random = Node(2) Result: New Node(1) → Node(2) → Node(3) ✓

进阶:O(1) 空间的交织法 / Bonus: O(1) Space Interweaving

def copyRandomList_O1(head):
    if not head:
        return None
    
    # Step 1: Interweave — insert copy after each original
    # 1 → 1' → 2 → 2' → 3 → 3'
    curr = head
    while curr:
        copy = Node(curr.val)
        copy.next = curr.next
        curr.next = copy
        curr = copy.next
    
    # Step 2: Set random pointers for copies
    curr = head
    while curr:
        if curr.random:
            curr.next.random = curr.random.next  # copy's random = original's random's copy
        curr = curr.next.next  # skip the copy
    
    # Step 3: Separate the two lists
    dummy = Node(0)
    copy_curr = dummy
    curr = head
    while curr:
        copy_curr.next = curr.next  # take the copy
        curr.next = curr.next.next  # restore original
        copy_curr = copy_curr.next
        curr = curr.next
    
    return dummy.next

复杂度 / Complexity:

  • Hash Map 法:Time O(n), Space O(n) ✅ 面试首选
  • 交织法:Time O(n), Space O(1) ⚡ 进阶

举一反三 / Pattern Connections (Linked List Block)

题目核心技巧与今天的联系
#206 Reverse三指针翻转最基础的链表操作
#141 Cycle快慢指针检测环
#19 Remove Nth快指针超前 N 步找相对位置
#138 今天Hash Map / 交织复制结构
#146 LRU CacheHashMap + 双向链表链表 + 哈希组合

规律: 链表题要么用指针技巧(快慢、多指针),要么用 Hash Map(复制、随机访问)。


📚 参考资料 / References

  1. LeetCode #138 官方题解
  2. NeetCode 视频讲解
  3. Python Hash Map in Linked List Problems — Real Python

🧒 ELI5

你要抄一张人物关系图。每个人有个"下一位"和一个"随机朋友"。直接抄,抄到第 1 个人时,他的朋友是第 5 个人,第 5 个人还没画出来怎么办?

方法:先把所有人的"空壳"画出来(第一遍),再把所有的连线画上去(第二遍)。这就是两次遍历的核心思想!

Copy a relationship chart: each person has a "next person" and a "random friend." Problem: when copying person #1, their friend is person #5 who doesn't exist yet. Solution: first create all "empty shells" (pass 1), then draw all the connections (pass 2).

🗣️ 软技能 / Soft Skills — Day 39

问题 / Question: 描述一次你扭转了一个表现不佳项目的经历 / Describe a time you turned around an underperforming project

类别 / Category: Leadership | 级别 / Level: Senior/Staff

阶段 / Phase: Mastery


为什么这个问题很重要 / Why This Question Matters

这是一个高度分化的面试题。Junior 候选人会描述技术修复;Senior 候选人会展示:识别根本原因、获得对齐、执行路径、文化影响。

面试官真正想听的是:

  • 你如何诊断真正的问题(不只是症状)
  • 你如何影响你没有直接控制权的人
  • 你如何在压力下决策

This question is highly differentiating. Junior candidates describe technical fixes; Senior candidates show root cause diagnosis, stakeholder alignment, execution, and cultural impact. Interviewers want to see how you think about organizational dynamics, not just coding skills.


STAR 拆解 / STAR Breakdown

Situation — 设定背景

描述具体的"表现不佳":

  • 具体数字:"Sprint 完成率从 85% 跌到 40%,连续三个 Sprint"
  • 外部影响:"关键合作方开始质疑我们能否按期交付"
  • 时间压力:"距离产品发布还有 8 周"

❌ 避免:"项目进展不顺利"(太模糊)

✅ 好:"Q3 的核心功能进度延误了 6 周,工程团队和 PM 之间出现了明显的不信任,每周同步会变成了互相指责的场所。"

Task — 你的角色

明确说明你的责任范围,以及为什么是你来解决:

  • "我是 Tech Lead,但这不完全是技术问题"
  • "我主动请缨,因为我和两边都有信任关系"

Action — 你做了什么(最重要)

第一步:诊断真正的问题 / Diagnose the Real Problem

表面症状 → 根本原因 代码质量差 → 没有明确的 Definition of Done 截止日期总 miss → 需求在 Sprint 中途变更,没有变更管理流程 工程师士气低 → 他们的技术债务请求被忽视了 6 个月

第二步:创造心理安全 / Create Psychological Safety

单独 1-on-1 与关键人员:先听,不评判,不立刻提方案。

找出每个人的真实痛点,而不是他们公开表达的立场。

第三步:给所有人一个"共同的敌人" / Give Everyone a Common Enemy

不是"工程 vs PM",而是"流程问题导致我们都在受苦"。

数据化问题:"我们在返工上花了 30% 的 Sprint 时间" — 具体数字打破防御性姿态。

第四步:小步快跑修复 / Small, Quick Wins First

在尝试改变整个文化之前,先解决 1-2 个具体痛点,建立信任和动力。

Result — 结果

量化:

  • "接下来两个 Sprint 完成率回升到 75%,最终按时交付"
  • "团队 NPS 从 -20 上升到 +15"
  • "建立了变更管理流程,被整个 org 采用"

❌ Bad Answer vs ✅ Good Answer

❌ 弱答案:

"项目延误了,我加班加点写代码,最终追上了进度。"

→ 问题:只展示了个人执行,没有展示领导力、系统思维、影响力。

✅ 强答案(结构):

"项目延误的表面原因是代码质量,但深层原因是工程和 PM 之间的信息不对称。我花了一周做诊断,分别和 5 个关键人做 1-on-1,发现真正的痛点是需求在 Sprint 中途频繁变更但没有成本核算。我提议引入'变更影响评估'流程,并亲自推动与 PM 负责人对齐。接下来两个迭代,Sprint 完成率从 38% 回到 78%,并在发布前两周完成了核心功能。"


Senior/Staff 加分点 / Senior/Staff Tips

  1. 展示你改变了系统,不只是救了火 — "我们建立了 X 流程,后来被其他团队也采用了"
  2. 展示你管理了向上的期望 — "我主动更新了 VP,提供了现实的路径,而不是等他们来问"
  3. 展示你考虑到了人的因素 — "PM 当时感到被指责,我需要先修复关系,才能修复流程"
  4. 承认你的局限 — "有一件我没做好的是...但这是我学到的教训"

关键要点 / Key Takeaways

  • 🔍 诊断 > 执行:花时间找根本原因,而不是立刻开始修复症状
  • 🤝 关系 > 流程:在修复流程之前先修复信任
  • 📊 数据化你的故事:具体数字比"显著改善"有说服力 10 倍
  • 🔄 系统性修复:好的答案改变了系统,而不只是救了一次火

📚 参考资料 / References

  1. STAR Method for Behavioral Interviews — Indeed
  2. Diagnosing Organizational Problems — HBR
  3. Turning Around a Failing Project — PMI

🧒 ELI5

想象你的学校项目组快失败了。聪明的做法不是自己把所有作业都做了,而是:先搞清楚为什么大家不配合(也许有人觉得自己的意见没被听),然后找到让所有人都愿意合作的方法,最后建立一个让下次不再出问题的规则。这就是 Senior 工程师和 Junior 工程师的区别。

Imagine your school group project is failing. The smart move isn't to do everyone's work yourself — it's to figure out why people aren't cooperating, fix the relationships, and then fix the process. That's the difference between a Senior and Junior engineer.

🤖 AI 资讯 / AI News — Day 47

模式 / Mode: NEWS | 日期 / Date: 2026-05-20

阶段 / Phase: Mastery

来源 / Sources: The Verge AI, Figma Blog, Google Blog (fetched 2026-05-20)


本周 AI 要闻 / This Week in AI


1. 🎨 Figma 推出 AI 设计 Agent / Figma Launches AI Design Agent

Figma 发布了一款产品设计 AI Agent,可以直接在 Figma Design 中帮助生成、编辑设计项目,以及"自动化繁琐工作"。这是继 Canva 和 Adobe 之后,又一家创意工具公司推出 AI 助手。

Figma has launched a product design AI agent, initially available in Figma Design, that can assist with generating or editing design projects and "automate busywork." It follows similar moves by Canva and Adobe.

📌 对工程师的意义: 设计稿生成速度将大幅提升,前端工程师与设计师的协作方式可能发生变化——未来的 PRD 可能直接附带 AI 生成的交互原型。

Why it matters for engineers: Design iteration will speed up dramatically. The frontend dev↔designer handoff may shift — future specs might ship with AI-generated interactive prototypes.

🔗 Figma Blog: The Figma Agent is Here


2. 🤖 Andrej Karpathy 加入 Anthropic / Andrej Karpathy Joins Anthropic

前特斯拉 AI 负责人、OpenAI 联合创始人 Andrej Karpathy 宣布加入 Anthropic,专注 R&D 工作。他此前一直在研究"AI-native 新型学校"的教育项目,称自己"对教育仍深度热情",日后会回归教育方向。

Former Tesla AI head and OpenAI co-founder Andrej Karpathy announced he's joining Anthropic to work on R&D. He had been building an "AI-native school" and says he remains "deeply passionate about education" and plans to return to it "in time."

📌 背景: Karpathy 是深度学习领域最有影响力的工程师之一(3Blue1Brown 风格的教学视频、nanoGPT 作者)。他的加入意味着 Anthropic 在基础研究上的雄心。

Context: Karpathy is one of the most influential engineers in deep learning (nanoGPT, famous teaching videos). His joining signals Anthropic's serious research ambition.

🔗 The Verge: Andrej Karpathy joins Anthropic


3. 🎵 Google Flow Music 获移动 App + 粒度编辑 / Google Flow Music Gets Mobile App & Granular Editing

Google 的 AI 音乐生成工具 Flow Music 已在 iOS 上线,Android 即将推出。新功能包括:

  • 对 AI 生成歌曲的局部编辑(修改某段的节奏、改写某句歌词)
  • 生成"翻唱版"和音乐视频

Google's AI music generation tool Flow Music is now available on iOS (Android coming soon). New features include granular editing tools for changing portions of an AI-generated song — beat drops, lyrics rewrites — plus the ability to generate "covers" and music videos.

📌 趋势: AI 媒体创作工具正从"生成一次"向"可迭代编辑"演进,这与代码 IDE 的发展路径高度类似。

Trend: AI creative tools are evolving from "one-shot generation" to "iterative editing" — the same trajectory as code IDEs.

🔗 Google Blog: Flow Music Updates


4. 💰 Google AI Ultra 降价 / Google AI Ultra Gets Price Cut

Google 的顶级 AI 订阅套餐 AI Ultra(此前 $249.99/月)现在起步价调整为 $100/月,另有 $200/月 选项(含 Project Genie 世界模型访问权限)。这与 OpenAI Pro 的 $100/$200 两档定价结构一致。

Google's top AI subscription AI Ultra (previously $249.99/month) now reportedly starts at $100/month, with a $200/month option including Project Genie world model access. This mirrors OpenAI Pro's $100/$200 tier structure.

📌 竞争格局: 两大 AI 巨头的高端套餐定价趋同,消费者对 AI 订阅价格的接受上限正在被 $100-$200/月 这个锚点固化。

Competition: The two biggest AI players converging on the same pricing signals a market anchor forming around the $100-200/month range for premium AI.

🔗 The Verge: Google AI Ultra pricing


本周洞察 / Weekly Insight

这周的 AI 新闻有一个共同主线:AI 工具正在向各垂直行业深度渗透(设计、音乐),同时基础研究层面的人才流动(Karpathy → Anthropic)预示着下一轮模型能力跃升已在酝酿中。

This week's theme: AI tools deepening into vertical industries (design, music), while talent movement at the research level (Karpathy → Anthropic) signals the next capability leap is already being built.


📚 参考资料 / References

  1. The Verge AI News (2026-05-20)
  2. Figma Agent Blog Post
  3. Google Flow Music Updates

🧒 ELI5

这周 AI 界发生了什么?设计软件 Figma 有了会帮你画图的 AI 助手;Google 的 AI 音乐软件出了手机版还能改歌词;有个特别厉害的 AI 工程师跳槽去了另一家 AI 公司;Google 的 AI 会员降价了。总之,AI 越来越便宜,越来越聪明,越来越多地方可以用到。

What happened in AI this week? Figma now has an AI that helps you design; Google's AI music app went mobile and lets you edit songs; a famous AI engineer switched companies; and Google's AI subscription got cheaper. Bottom line: AI keeps getting cheaper, smarter, and available in more places.