← 返回部落格列表 Stripe OA 真題分享:2026 春招實測題型與避坑清單|一畝三分地
Stripe

Stripe OA 真題分享:2026 春招實測題型與避坑清單|一畝三分地

2026-05-13

Stripe OA 在所有金融科技公司中風格最獨特——不考演算法 Hard 題,但隱藏測試用例多達 15-20 個,常常出現「思路對、程式錯」的尷尬情況。本文彙總 2026 春招(Q1-Q2)一畝三分地最新的 Stripe OA 真題分享,按出現頻率排序給出三道實戰原題、完整 Python 解法以及評分系統的扣分細節。所有題目來源於 2026 年 1-4 月的真實候選人回饋,與既往 brace expansion、shipping cost 等老題完全不同

Stripe 2026 春招 OA 概覽

維度 詳情
平台 HackerRank for Work
總時長 120 分鐘
題量 通常 1 道大題(分 4 個 Part)
難度 單題 LeetCode Easy ~ Medium,但 Part 間難度遞增
隱藏測試 15-20 個,每個 Part 5-7 個
通過線 80%+ 測試通過

題目一:Payment Reconciliation(支付對帳,出現率最高)

Part 1:基礎對帳

題意:給定兩個資料源 bank_transactionsinternal_records,每條資料是 (transaction_id, amount, timestamp)。返回只在內部記錄中存在、銀行未確認的交易。

def find_unreconciled(bank_transactions, internal_records):
    """
    bank_transactions: List[Tuple[str, int, int]]
    internal_records: List[Tuple[str, int, int]]
    return: List[Tuple[str, int, int]],按 timestamp 升序
    """
    bank_ids = {tx[0] for tx in bank_transactions}
    unreconciled = [r for r in internal_records if r[0] not in bank_ids]
    unreconciled.sort(key=lambda x: x[2])
    return unreconciled

時間複雜度:O(n + m log m),n 為銀行交易數,m 為內部記錄數。

Part 2:金額匹配但 ID 不一致

題意:在 Part 1 的「未對帳」中,找出金額相同、時間戳差 ≤ 60 秒的交易對。可能是同一筆交易但 ID 寫錯了。

from collections import defaultdict

def find_fuzzy_matches(unreconciled, bank_transactions, time_tolerance=60):
    """
    在 unreconciled 中,找出可以與 bank_transactions 模糊匹配的交易對
    """
    bank_by_amount = defaultdict(list)
    for tx in bank_transactions:
        bank_by_amount[tx[1]].append(tx)
    
    matches = []
    for internal_tx in unreconciled:
        amount = internal_tx[1]
        for bank_tx in bank_by_amount[amount]:
            if abs(bank_tx[2] - internal_tx[2]) <= time_tolerance:
                matches.append((internal_tx, bank_tx))
                break
    
    return matches

Stripe 扣分點

Part 3:批量對帳與衝突解決

題意:當多筆內部交易可以匹配同一筆銀行交易時,按 timestamp 最近原則分配。

def assign_conflicts(unreconciled, bank_transactions, time_tolerance=60):
    bank_by_amount = defaultdict(list)
    for tx in bank_transactions:
        bank_by_amount[tx[1]].append(tx)
    
    used_bank = set()
    result = []
    unreconciled_sorted = sorted(unreconciled, key=lambda x: x[2])
    
    for internal_tx in unreconciled_sorted:
        amount = internal_tx[1]
        best_match = None
        best_diff = time_tolerance + 1
        for bank_tx in bank_by_amount[amount]:
            if bank_tx[0] in used_bank:
                continue
            diff = abs(bank_tx[2] - internal_tx[2])
            if diff < best_diff:
                best_diff = diff
                best_match = bank_tx
        
        if best_match:
            used_bank.add(best_match[0])
            result.append((internal_tx, best_match))
    
    return result

Part 4:流式對帳(State Reset)

最難的一 Part:要求即時處理串流輸入,每條新交易立即匹配或掛起,超過 5 分鐘未匹配則標記為「待人工審核」。

from collections import deque

class StreamReconciler:
    def __init__(self, time_tolerance=60, escalation_timeout=300):
        self.time_tolerance = time_tolerance
        self.escalation_timeout = escalation_timeout
        self.pending_internal = deque()
        self.pending_bank = deque()
        self.matched = []
        self.escalated = []
    
    def process(self, tx_type, tx):
        if tx_type == "internal":
            self.pending_internal.append(tx)
        else:
            self.pending_bank.append(tx)
        
        self._try_match(tx[2])
        self._escalate_old(tx[2])
    
    def _try_match(self, current_time):
        for internal_tx in list(self.pending_internal):
            for bank_tx in list(self.pending_bank):
                if (internal_tx[1] == bank_tx[1] and 
                    abs(internal_tx[2] - bank_tx[2]) <= self.time_tolerance):
                    self.matched.append((internal_tx, bank_tx))
                    self.pending_internal.remove(internal_tx)
                    self.pending_bank.remove(bank_tx)
                    return self._try_match(current_time)
    
    def _escalate_old(self, current_time):
        while self.pending_internal and current_time - self.pending_internal[0][2] > self.escalation_timeout:
            self.escalated.append(self.pending_internal.popleft())
        while self.pending_bank and current_time - self.pending_bank[0][2] > self.escalation_timeout:
            self.escalated.append(self.pending_bank.popleft())

題目二:Webhook 重試系統(出現率 30%)

題意

實作 Stripe Webhook 的指數退避重試邏輯。每次 webhook 投遞失敗後,下次重試間隔翻倍(1s, 2s, 4s, 8s, ...),最多重試 8 次。需支援:

from collections import defaultdict
import heapq

class WebhookRetrySystem:
    def __init__(self, max_attempts=8, base_delay=1):
        self.max_attempts = max_attempts
        self.base_delay = base_delay
        self.attempts = defaultdict(int)
        self.due_heap = []
        self.failed_permanently = []
    
    def dispatch(self, event_id, attempt_at):
        self.attempts[event_id] += 1
    
    def mark_failed(self, event_id, failed_at):
        attempt_num = self.attempts[event_id]
        if attempt_num >= self.max_attempts:
            self.failed_permanently.append(event_id)
            return
        delay = self.base_delay * (2 ** (attempt_num - 1))
        retry_time = failed_at + delay
        heapq.heappush(self.due_heap, (retry_time, event_id))
    
    def get_due_events(self, now):
        due = []
        while self.due_heap and self.due_heap[0][0] <= now:
            _, event_id = heapq.heappop(self.due_heap)
            due.append(event_id)
        return due

Stripe 扣分點

題目三:Currency Conversion Graph(出現率 25%)

題意

給定一組貨幣匯率 rates = [(from, to, rate), ...],實作一個 convert(from_currency, to_currency, amount) 方法。如果沒有直接匯率,需要找出中間轉換路徑

from collections import defaultdict, deque

class CurrencyConverter:
    def __init__(self, rates):
        self.graph = defaultdict(dict)
        for from_cur, to_cur, rate in rates:
            self.graph[from_cur][to_cur] = rate
            self.graph[to_cur][from_cur] = 1.0 / rate
    
    def convert(self, from_cur, to_cur, amount):
        if from_cur == to_cur:
            return amount
        if from_cur not in self.graph:
            return None
        
        queue = deque([(from_cur, amount)])
        visited = {from_cur}
        
        while queue:
            current_cur, current_amount = queue.popleft()
            if current_cur == to_cur:
                return current_amount
            for neighbor, rate in self.graph[current_cur].items():
                if neighbor not in visited:
                    visited.add(neighbor)
                    queue.append((neighbor, current_amount * rate))
        
        return None

測試

rates = [
    ("USD", "EUR", 0.9),
    ("EUR", "GBP", 0.85),
    ("GBP", "JPY", 180),
]
conv = CurrencyConverter(rates)
print(conv.convert("USD", "JPY", 100))  # 100 * 0.9 * 0.85 * 180 = 13770.0

Stripe 隱藏測試

Stripe OA 答題策略總結

錯誤 扣分 修正
沒考慮空輸入 5 分/Part 第一行寫 if not data: return [...]
沒考慮負數/0 3 分/Part 業務上 refund 是負數
暴力 O(n²) 解 0 分(超時) 用 hashmap 或 heap
函數命名縮寫 1 分/方法 bank_txbt
沒寫單元測試 5 分總分 至少加 3 個 assert

FAQ

Stripe OA 一定要做完所有 Part 嗎?

不一定。Stripe 評分採用絕對分數 + Part 完成度雙指標。如果 Part 1+2 全對(約 60%),通過率仍然有 30%。優先保證前兩個 Part 100% 正確,再嘗試 Part 3。

Stripe OA 可以查 Google 嗎?

理論上禁止(HackerRank 攝影機會記錄),但實際監管不嚴。建議查文件(如 heapq 用法)但不要查演算法答案——評分員會看程式風格識別「非候選人原創」。

Stripe OA 通過後多久會有回饋?

通常 5-10 個工作日。Stripe HR 節奏穩定,不通過會發明確拒信(這點比 Google、Meta 友好)。

這些題目和 1point3acres 上面經一致嗎?

是。本文所有題目來自 2026 Q1-Q2 一畝三分地 Stripe 板塊的真實分享,但變數名和 Part 劃分會隨每個 candidate 略有不同——Stripe 的題庫每月輪換一次。

Stripe OA 推薦用什麼語言?

Python(首選)、JavaScript(次選)。Stripe 內部主要用 Ruby,但 OA 不強制——評分員只看正確性。避免 C++:Stripe OA 的字串處理多,C++ 寫起來慢。


正在準備 Stripe OA?

oavoservice 持續整理 Stripe 真題(包括本文未覆蓋的 brace expansion、shipping cost、subscription notifications 等老題),提供 OA 限時模擬與隱藏測試用例預演。導師團隊包括前 Stripe Engineer,熟悉評分系統的所有扣分點。

立即新增微信:Coding0201獲取 Stripe OA 真題包

#Stripe #OA #支付系統 #Webhook #真題分享 #一畝三分地


聯絡方式

Email: [email protected]
Telegram: @OAVOProxy