一句话摘要:Ramp OA 是 CodeSignal Industry 风格的 4 题递增设计——一道贯穿全场的"银行交易系统",每题在前一题基础上加新规则。关键不是会算法,而是能不能干净地组织代码。
Ramp 是美国知名的 B2B 财务自动化(公司卡 + 报销 + 账单支付)独角兽,工程文化非常推崇"reliability",因此 OA 完全模仿真实业务——你做的每一道题都像在 build 一个 mini banking core。这篇文章按 2026 年最新真题给出完整解析。
一、Ramp OA 基本信息
| 项目 | 详情 |
|---|---|
| 平台 | CodeSignal Industry Coding Framework |
| 时长 | 70 分钟 |
| 题数 | 4 道(递增式:Level 1 → Level 4) |
| 语言 | Python / TypeScript / Go / Java |
| 通过线 | 通常 3 道全 AC + 第 4 道部分通过 |
| 测试用例 | 每题 ~15 个 hidden tests |
最大特点:4 道题共享同一个数据模型(账户、交易、退款),后题在前题代码上扩展。这意味着:
- 第 1 题写得好 → 后面省一半时间
- 第 1 题代码乱 → 第 4 题基本不可能 AC
二、4 道题完整解析(Bank Transaction System)
Level 1:基础账户操作
题面:实现 4 个 API:
CREATE_ACCOUNT(timestamp, account_id)DEPOSIT(timestamp, account_id, amount)PAY(timestamp, account_id, amount)TOP_K_ACCOUNTS_BY_OUTGOING_PAYMENTS(timestamp, k)
思路:HashMap 存账户余额 + HashMap 存累计支出。
class BankSystem:
def __init__(self):
self.balances = {} # acc_id -> balance
self.outgoing = {} # acc_id -> total spent
def create(self, ts, acc):
if acc in self.balances:
return ""
self.balances[acc] = 0
self.outgoing[acc] = 0
return "true"
def deposit(self, ts, acc, amt):
if acc not in self.balances:
return ""
self.balances[acc] += amt
return str(self.balances[acc])
def pay(self, ts, acc, amt):
if acc not in self.balances or self.balances[acc] < amt:
return ""
self.balances[acc] -= amt
self.outgoing[acc] += amt
return str(self.balances[acc])
def top_k(self, ts, k):
ranked = sorted(self.outgoing.items(),
key=lambda x: (-x[1], x[0]))
return ", ".join(f"{a}({v})" for a, v in ranked[:k])
Level 2:转账与时间排序
新增 API:
TRANSFER(timestamp, source_id, target_id, amount)
注意:转账要保证原子性(任一账户失败则全失败)。
def transfer(self, ts, src, tgt, amt):
if src == tgt or src not in self.balances or tgt not in self.balances:
return ""
if self.balances[src] < amt:
return ""
self.balances[src] -= amt
self.balances[tgt] += amt
self.outgoing[src] += amt
return str(self.balances[src])
Level 3:定时退款(Refund Queue)
新增 API:
SCHEDULE_REFUND(timestamp, account_id, amount, delay_ms):在 timestamp + delay_ms 后退款- 后续所有操作都要先扫描已到期的退款并执行
思路:用最小堆维护待执行退款,每次 API 调用前 flush 到当前时间。
import heapq
class BankSystem:
def __init__(self):
self.balances = {}
self.outgoing = {}
self.pending = [] # min-heap (exec_ts, acc, amt)
def _flush(self, now):
while self.pending and self.pending[0][0] <= now:
ts, acc, amt = heapq.heappop(self.pending)
if acc in self.balances:
self.balances[acc] += amt
def schedule_refund(self, ts, acc, amt, delay):
self._flush(ts)
if acc not in self.balances:
return ""
heapq.heappush(self.pending, (ts + delay, acc, amt))
return "true"
关键易错点:每个 API 入口都要先调用 _flush(ts),否则后续 query 会读到过期数据。
Level 4:消费限额(Spending Limit)
新增 API:
SET_PAYMENT_LIMIT(timestamp, account_id, limit, window_ms):在过去 window_ms 内总支出不能超过 limit
思路:每个账户维护一个双端队列记录最近支出 (timestamp, amount),每次 PAY 前清理过期记录。
from collections import deque
class BankSystem:
def __init__(self):
self.balances = {}
self.outgoing = {}
self.pending = []
self.limits = {} # acc -> (limit, window)
self.recent_pay = {} # acc -> deque of (ts, amt)
def set_limit(self, ts, acc, limit, window):
if acc not in self.balances:
return ""
self.limits[acc] = (limit, window)
self.recent_pay.setdefault(acc, deque())
return "true"
def pay(self, ts, acc, amt):
self._flush(ts)
if acc not in self.balances:
return ""
# check limit
if acc in self.limits:
limit, window = self.limits[acc]
dq = self.recent_pay[acc]
while dq and dq[0][0] < ts - window:
dq.popleft()
recent_total = sum(a for _, a in dq)
if recent_total + amt > limit:
return ""
if self.balances[acc] < amt:
return ""
self.balances[acc] -= amt
self.outgoing[acc] += amt
if acc in self.limits:
self.recent_pay[acc].append((ts, amt))
return str(self.balances[acc])
复杂度:每次 PAY 均摊 O(1)(双端队列)。
三、4 题难度与时间分配
| 题号 | 难度 | 推荐用时 | 关键技巧 |
|---|---|---|---|
| Level 1 | ⭐ | 8 min | 干净的 HashMap + 排序 |
| Level 2 | ⭐⭐ | 12 min | 转账原子性 |
| Level 3 | ⭐⭐⭐ | 20 min | 优先队列 + flush 机制 |
| Level 4 | ⭐⭐⭐⭐ | 25 min | 双端队列 + 限额检查 |
时间预算:留 5 分钟给 debug,不要追求 4 题全 AC,3 题 AC + 第 4 题部分通过 = 进面试。
四、Ramp OA 备考策略
| 阶段 | 周期 | 重点 |
|---|---|---|
| 基础 | 1 周 | LeetCode 设计题 30 题(LRU、Twitter、HashMap) |
| 仿真 | 1 周 | CodeSignal Industry Framework 官方 Bank/Inventory 模板 |
| 冲刺 | 3 天 | Ramp 风格 4 题真题 + 时间分配 |
重要原则:
- 不要每题重写:把 Level 1 的 class 写成可扩展的,后面只加方法
- 统一返回格式:所有 API 失败返回
"",成功返回字符串数字 - 预留 _flush hook:从 Level 1 就埋好钩子,Level 3 直接接入
五、FAQ:Ramp OA / Ramp CodeSignal 高频问答
Q1:Ramp OA 多少分能进面?
通常 3 题全 AC + 第 4 题 50%+ 部分通过。CodeSignal 满分 600,建议 ≥ 480。
Q2:Ramp OA 可以用 ChatGPT 辅助吗?
官方禁止 AI 辅助。CodeSignal 部分版本会监控键盘行为与浏览器切换,作弊会被永久拉黑。
Q3:Ramp OA 题库会变吗?
Bank System 模板半年内变化不大,但具体 API 名称、字段会换。所以重点是理解模式,不是背代码。
Q4:用 Python 还是 TypeScript?
Python 写得最快。TypeScript 适合后端候选人,但 OA 阶段不影响排名。
Q5:Ramp OA 之后流程是什么?
OA 通过 → 1 轮 Recruiter Call → 1 轮 Phone Coding → Onsite(2 Coding + 1 SD + 1 BQ + 1 Hiring Manager)。
Q6:Ramp OA 看哪些 LeetCode 标签?
Design + HashMap + Heap。重点:LC 146 (LRU), LC 355 (Twitter), LC 460 (LFU), LC 1396 (Subway Stat)。
六、外链资源
🚀 需要 Ramp OA / VO 辅助?
如果你正在准备 Ramp、Brex、Stripe、Mercury 等 Fintech 公司的 OA / VO,欢迎交流:可提供 CodeSignal Industry 风格题型拆解、设计题代码组织模板与 onsite SD 模拟。
👉 立即添加微信:Coding0201,获取真题与一对一备考方案
联系方式
- 微信:Coding0201
- Email:[email protected]
- Telegram:@OAVOProxy