← 返回部落格列表 Goldman Sachs SDE 面試四輪全復盤:DP + 外部排序 + Splitwise LLD + 系統設計
Goldman Sachs

Goldman Sachs SDE 面試四輪全復盤:DP + 外部排序 + Splitwise LLD + 系統設計

2026-06-03

Goldman Sachs 的 SDE VO 不是那種「秒殺一道 Hard 就過」的面試。它的風格非常一致:從暴力解一步步最佳化到最優,全程要你講清楚每一步的時間/空間複雜度。面試官人不錯、會給提示,但你必須展現清晰的思路鏈條。

這篇把一位候選人的四輪 VO 完整復盤——每輪的真題、解法、空間最佳化點,以及口述結構。

四輪總覽

輪次 內容 考察重點
Round 1 Distinct Subsequences + 原地排序 DP + 空間最佳化 + 演算法選型
Round 2 Maximal Square + 大檔案外部排序 2D DP + 海量資料處理
Round 3 Maze BFS(30min)+ Splitwise LLD(30min) 最短路 + 物件導向設計
Round 4 系統設計 + 設計模式(1h) 架構 + 技術選型權衡

Round 1:Distinct Subsequences + 原地排序

第一題:Distinct Subsequences(經典 DP)

給字串 s 和 t,求 s 的子序列中等於 t 的個數。

先寫 2D DP,再被要求最佳化空間複雜度。

def numDistinct(s, t):
    n, m = len(s), len(t)
    # dp[j] = s 的前綴裡等於 t[:j] 的子序列數
    dp = [0] * (m + 1)
    dp[0] = 1
    for i in range(1, n + 1):
        # 從右往左滾動,避免覆蓋本輪還要用的 dp[j-1]
        for j in range(m, 0, -1):
            if s[i-1] == t[j-1]:
                dp[j] += dp[j-1]
    return dp[m]

空間最佳化關鍵:2D 壓成 1D 滾動陣列時,內層迴圈必須從右往左,否則 dp[j-1] 會被本輪提前更新污染。這是面試官最愛追問的點。

第二題:原地排序(不用額外空間)

面試官問 quicksort 還是 heapsort,候選人選了 quicksort。關鍵是從暴力解逐步最佳化到最優,並清楚講出時間/空間複雜度:quicksort 平均 O(n log n)、原地、最壞 O(n²)(用隨機 pivot 緩解)。

Round 2:Maximal Square + 大檔案外部排序

第一題:Maximal Square(2D DP)

在 0/1 矩陣裡找最大全 1 正方形的面積。

def maximalSquare(matrix):
    if not matrix:
        return 0
    n, m = len(matrix), len(matrix[0])
    # dp[i][j] = 以 (i,j) 為右下角的最大正方形邊長
    prev = [0] * (m + 1)
    best = 0
    for i in range(1, n + 1):
        cur = [0] * (m + 1)
        for j in range(1, m + 1):
            if matrix[i-1][j-1] == '1':
                cur[j] = min(prev[j], cur[j-1], prev[j-1]) + 1
                best = max(best, cur[j])
        prev = cur
    return best * best

轉移核心dp[i][j] = min(上, 左, 左上) + 1。被追問空間最佳化時,用滾動陣列壓到 O(m)。

第二題:大檔案外部排序

2GB 檔案、250MB 記憶體,如何排序?

框架:external sort——

  1. 分塊讀入,每塊(約 200MB)在記憶體裡排序後寫回磁碟
  2. k-way merge:用最小堆管理每個 chunk 的當前元素,每次彈出最小的寫入輸出
import heapq

def k_way_merge(sorted_chunks):
    # sorted_chunks: 多個已排序的迭代器
    heap = []
    iters = [iter(c) for c in sorted_chunks]
    for idx, it in enumerate(iters):
        v = next(it, None)
        if v is not None:
            heapq.heappush(heap, (v, idx))
    out = []
    while heap:
        v, idx = heapq.heappop(heap)
        out.append(v)
        nv = next(iters[idx], None)
        if nv is not None:
            heapq.heappush(heap, (nv, idx))
    return out

被問 merge 階段細節時,強調「用最小堆管理各 chunk 當前元素」就是標準答案。

Round 3:Maze BFS + Splitwise LLD

前 30 分鐘 DSA:Maze 2(BFS 求最短路 + 最佳化)

標準 grid BFS,注意 visited 標記 + 佇列。最佳化點:雙向 BFS 或 A*(如果給了啟發函數)。

後 30 分鐘 LLD:設計 Splitwise

LLD 真正考綜合能力。結構化方法:

  1. 需求澄清:支援誰欠誰多少、分帳方式(均分/按比例/按份額)、群組、結算
  2. 核心類別設計
class User:
    def __init__(self, uid, name):
        self.uid, self.name = uid, name

class Expense:
    def __init__(self, paid_by, amount, split_type, splits):
        self.paid_by = paid_by        # User
        self.amount = amount
        self.split_type = split_type  # EQUAL / EXACT / PERCENT
        self.splits = splits          # {user: share}

class BalanceSheet:
    def __init__(self):
        # balances[a][b] = a 欠 b 多少
        self.balances = defaultdict(lambda: defaultdict(float))

    def add_expense(self, expense):
        share = self._compute_shares(expense)
        for user, owed in share.items():
            if user != expense.paid_by:
                self.balances[user][expense.paid_by] += owed
  1. 擴展討論:簡化債務(debt simplification)、並發結算、edge case(自己付自己)。

要點:先澄清需求 → 定義類別與介面 → 最後討論擴展性與邊界。時間緊,不要求寫完整程式,但思路要清晰。

Round 4:系統設計 + 設計模式(最難)

1 小時分兩部分,深入討論當前專案架構 + 設計模式 / OOP 原則的應用。

備考建議

FAQ

Q1:GS SDE VO 幾輪? 通常 4 輪 superday,覆蓋 DSA、LLD、系統設計、專案深挖。

Q2:演算法題難度如何? 以 LeetCode Medium 為主,但極其看重逐步最佳化 + 複雜度分析,不是 AC 就行。

Q3:LLD 要寫完整程式嗎? 不要求。重點是類別設計、關係、介面,時間不夠時講清結構即可。

Q4:系統設計會考標準題(如設計 Twitter)嗎? 更常見的是深挖你履歷裡的專案,讓你解釋架構與技術選型,比標準題更難準備。


正在準備 Goldman Sachs SDE 面試?

如果你卡在「能 AC 但講不清最佳化路徑」「LLD 沒框架」「系統設計被追問就慌」,可以聊聊看完整的面試陪跑方案:四輪真題精講 + 限時 mock + 全程即時輔助 + 逐輪複盤。


聯絡方式

需要面試真題與客製化備戰計畫?立刻聯絡微信 Coding0201獲取真題

Email: [email protected] Telegram: @OAVOProxy