← 返回博客列表 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