← 返回博客列表
DoorDash

DoorDash VO:負載均衡 Debug + 一致性雜湊

2025-11-29

oavoservice 原創復盤:DoorDash 很愛用「先 debug 一個壞實作,再讓你講可擴展設計」的組合題。

Part 1:Round Robin 負載均衡器 Debug(改寫版)

你拿到一個負載均衡器的虛擬碼(或不完整實作),單元測試要求:

常見 bug 畫像

一個正確的最小實作(Python)

class Backend:
    def __init__(self, name, state='AVAILABLE'):
        self.name = name
        self.state = state


class TrafficRouter:
    def __init__(self, backends):
        self.backends = list(backends)
        self._idx = 0

    def add_backend(self, backend):
        self.backends.append(backend)

    def get_backend(self):
        n = len(self.backends)
        if n == 0:
            return None

        tried = 0
        while tried < n:
            b = self.backends[self._idx]
            self._idx = (self._idx + 1) % n
            tried += 1
            if b.state == 'AVAILABLE':
                return b
        return None

面試官聽什麼

Part 2:為什麼 Round Robin 不夠?(狀態/黏性會話)

如果後端是有狀態的(session、cache、shopping cart),Round Robin 會導致:

於是引出 一致性雜湊

Part 3:一致性雜湊設計(核心要點)

目標

基本做法

虛擬節點(Virtual Nodes)

為了更均勻,給每個 backend 放多個 vnode:

參考實作(簡化)

import bisect
import hashlib


def h32(s: str) -> int:
    return int(hashlib.md5(s.encode('utf-8')).hexdigest()[:8], 16)


class ConsistentHashRing:
    def __init__(self, replicas=100):
        self.replicas = replicas
        self.ring = []          # sorted hashes
        self.nodes = []         # parallel array of node ids
        self.live = set()

    def add_node(self, node_id: str):
        self.live.add(node_id)
        for i in range(self.replicas):
            key = f"{node_id}#{i}"
            hv = h32(key)
            idx = bisect.bisect_left(self.ring, hv)
            self.ring.insert(idx, hv)
            self.nodes.insert(idx, node_id)

    def remove_node(self, node_id: str):
        if node_id not in self.live:
            return
        self.live.remove(node_id)
        i = 0
        while i < len(self.nodes):
            if self.nodes[i] == node_id:
                self.nodes.pop(i)
                self.ring.pop(i)
            else:
                i += 1

    def route(self, request_key: str) -> str | None:
        if not self.ring:
            return None
        hv = h32(request_key)
        idx = bisect.bisect_left(self.ring, hv)
        if idx == len(self.ring):
            idx = 0
        return self.nodes[idx]

面試擴展點


如果你要準備 DoorDash / Uber / Stripe 這類後端 VO,oavoservice 會用這類「debug + 系統設計升級」的題把你的表達訓練成:先修正確性,再談可擴展與工程權衡。


需要面試真題? 立刻聯繫微信 Coding0201獲得真題