1p3a Question · May 2026

meta codesignal online assessment questions summary for software engineers

SWE OA newgrad
8 upvotes 5 replies

Question Details

最近在准备 Meta 的面试,OA 是 CodeSignal 的 Industry Coding Framework,也就是大家说的 ICF 那一套。攒了一些资料和地里、reddit、blind 上看到的题目,整理一下分享给大家,希望对后面要考的同学有帮助。也欢迎补充。

关于 ICF 的基本情况

不是传统那种四道独立题。一道题分四个 level,后面的 level 在前面的代码上加方法、加语义,状态是延续的。所以 L1 写得太随便,到 L3 L4 可能要大改。

时间一般 70 到 90 分钟,没有单独 level 的截止时间,自己分配。总分大概 600 满,过线靠的是 L3 完整 + L4 部分通过。听说 Meta senior 以上的 bar 大概在 500+。

类,方法签名都给你,自己实现就行。Python、Java、JS 都能选。

通用规律

我观察下来,几乎所有 ICF 题都是这个套路:

L1:基本的增删改查,几个方法
L2:加一个 top N 或者排序聚合查询
L3:加时间语义,比如 timestamp、TTL、过期
L4:merge 账户 / snapshot...

Full Details

最近在准备 Meta 的面试,OA 是 CodeSignal 的 Industry Coding Framework,也就是大家说的 ICF 那一套。攒了一些资料和地里、reddit、blind 上看到的题目,整理一下分享给大家,希望对后面要考的同学有帮助。也欢迎补充。

关于 ICF 的基本情况

不是传统那种四道独立题。一道题分四个 level,后面的 level 在前面的代码上加方法、加语义,状态是延续的。所以 L1 写得太随便,到 L3 L4 可能要大改。

时间一般 70 到 90 分钟,没有单独 level 的截止时间,自己分配。总分大概 600 满,过线靠的是 L3 完整 + L4 部分通过。听说 Meta senior 以上的 bar 大概在 500+。

类,方法签名都给你,自己实现就行。Python、Java、JS 都能选。

通用规律

我观察下来,几乎所有 ICF 题都是这个套路:

L1:基本的增删改查,几个方法
L2:加一个 top N 或者排序聚合查询
L3:加时间语义,比如 timestamp、TTL、过期
L4:merge 账户 / snapshot 和 restore / 多租户所以 L1 设计的时候就要预判后面要什么。比如 balance 和 outgoing 一定要分开存(L2 排序要用),event log 从 L1 就开始记(L4 大概率要查历史)。

题目 1:银行系统 Banking System

最高频,地里和 reddit 都报过很多次。

L1:create_account, deposit, transfer 三个方法。transfer 要处理几个 edge case:转给自己、余额不够、账户不存在。

L2:top_activity(n),按账户的总转出金额排序,取前 n。注意是「转出」总额,不包括存款。并列的话按 account_id 字典序。

思路:单独维护一个 outgoing 的计数器,每次 transfer 时累加。不要用 balance 排序,balance 会变。

L3:transfer 改成有 24 小时 acceptance window。源账户的钱立刻扣掉但不到目标账户,目标账户要主动 accept_transfer 才能收到。超过 24 小时自动退回源账户。

思路:lazy expire,每个操作进来第一步先扫一遍 pending transfers,过期的退钱。不要起后台线程。

L4:merge_accounts(account1, account2),把 2 合到 1 里。balance 合并、outgoing 合并、pending transfers 也要跟着过去。account2 之后不再存在。

还有一个 get_balance(account_id, time_at),查历史余额。这个就是为什么要从 L1 开始记 event log。

题目 2:云存储系统 Cloud Storage

第二高频。

L1:add_file(name, size), get_file_size(name), delete_file(name)。

L2:get_n_largest(prefix, n),按 size 降序、name 字典序升序,prefix 过滤。

L3:引入用户和容量限制。add_user(user_id, capacity), add_file_by(user_id, name, size)。文件挂在用户名下,超过容量上传失败。还有 merge_user 把两个用户合并,容量加和,文件全归到 user1。

思路:文件要有反向指针指向 owner,删除的时候才能正确释放容量。

L4:backup_user 和 restore_user。每个用户最多一个 backup,restore 是覆盖式的,不是 merge。

坑:restore 的时候要把当前用户的所有文件清掉,再从 snapshot 写回。文件名冲突(被别的用户占了)要处理一下。

题目 3:内存数据库 In-Memory DB (KV with TTL)

类似 Redis hash 的结构,key 下面有多个 field。

L1:set(key, field, value), get(key, field), delete(key, field)。

L2:scan(key) 返回 key 下所有 field,按字典序。scan_by_prefix(key, prefix) 加前缀过滤。

L3:所有方法第一个参数变成 timestamp。新增 set_with_ttl(timestamp, key, field, value, ttl),过期后 get 返回空,scan 跳过。

TTL 是相对于 set 时刻的,不是查询时刻。lazy 过期,读的时候判断就行。

L4:backup(timestamp) 和 restore(timestamp, timestamp_to_restore),整库 snapshot。这题最阴的地方就在这。

重点:snapshot 里存的必须是「剩余 TTL」,不能存「绝对过期时间」。如果存绝对时间,restore 到一个更晚的时刻,整个 snapshot 就全过期了。存剩余时间的话,restore 的时候用 restore_ts + remaining 重新算就行。这个细节错了 L4 几乎全挂,而且本地很难看出来。

题目 4:返现银行系统 Cashback Banking

银行的变种,Meta 单独报过几次。

L1:create_account, deposit, pay。注意 pay 和 transfer 不一样,钱直接出系统。

L2:top_spenders(n),按总消费排序。被退款的也算消费。

L3:每次 pay 之后 24 小时自动返 2%。pay 返回一个 payment_id(payment1, payment2 这种全局递增)。get_payment_status 查状态(IN_PROGRESS / CASHBACK_RECEIVED)。

思路:维护一个按 fire time 排序的小顶堆,每次操作进来先把到期的处理掉。

L4:merge_accounts。balance、total_spent 合并,pending 的返现 fire 的时候要落到 account1。payment_id 之前属于 account2 的,merge 之后用 account1 查也要能查到。

题目 5:库存管理系统 Inventory / Warehouse

DoorDash、Amazon 一些组也用这题。

L1:add_stock, remove_stock, get_quantity。

L2:top_items(n),按总「移动量」排序,加和减都算。movement 和 quantity 要分开。

L3:批次加过期时间。add_stock_with_expiry(item, quantity, expires_at)。同一个 item 可以有多个批次,过期时间不同。remove 的时候 FIFO,最早过期的先减。

思路:每个 item 下维护按 expires_at 排序的批次列表,读的时候跳过已过期的。

L4:加 warehouse 维度。transfer(src_wh, dst_wh, item, quantity) 跨仓库转移,批次的过期信息要原样带过去,不能简单地减一边加一边。

题目 6:酒店预订系统 Hotel Reservation

Meta 和 Marriott 都用过。

L1:book_room(room_id, guest_id, nights), cancel_booking, get_room_status。nights 决定占用时长。

L2:top_guests(n),按累积入住夜数排,取消的也算。

L3:set_rate 设置工作日和周末的价格。book_room 返回 booking_id 和总价。get_revenue(start, end) 查某段时间窗口里的总营收,部分重叠按比例算。

工作日还是周末用 (timestamp / DAY) % 7 算。

L4:move_booking 把预订转到另一间房,要检查新房间在那段时间没冲突。merge_room_history 把 room2 所有预订并到 room1(前提是 room1 没冲突)。

时间区间冲突检测这里要写干净,否则 L4 很容易写炸。

题目 7:广告竞价系统 Ad Bidding

频率稍低,但 Meta、TikTok 报过。值得过一遍。

L1:submit_bid(advertiser, slot, amount), cancel_bid, get_winning_bid。同一个广告主在同一个 slot 只能有一个 active bid,再投会替换。

L2:top_advertisers(n),按总赢得金额排。

L3:close_slot(slot_id) 关闭拍卖,最高价 active bid 赢,其它释放。submit_bid 在已关闭的 slot 上失败。

L4:set_budget(advertiser, budget)。submit_bid 要检查 active holds + won totals 不能超 budget,像信用卡预授权一样。get_budget_remaining 查剩余。

active hold 在 slot close 的时候,赢了转成 won_totals,输了释放。

几个反复出现的套路

写了几遍下来发现有些东西每道题都用得到:

  1. 每个操作的第一行都跑一遍 lazy expire。过期的 transfer、TTL field、cashback 都靠这个推进。多了用堆,少了直接扫。

  2. counter 和 current state 分开存。balance 会变,outgoing 不会变。top N 永远读 counter。

  3. snapshot 存剩余 TTL 不存绝对时间。这个不解释,KV 那题踩一次终身难忘。

  4. event log 从 L1 开始记。每个状态变更都 append (timestamp, value)。L4 要查历史用 bisect 一下就完事。Cost 一行,不要 L4 才回去改。

  5. top N 的字典序 tie break:

sort(key=lambda x: (-x[1], x[0]))
复制代码
。每道题都要这个,忘了负号就全错。

一些 OA 实操经验

浏览器里的编辑器有自动补全,习惯一下,别复制到本地 IDE 再贴回来,浪费时间
每个 level 写完先提交一次再优化,至少分数能落袋
4 个 level 提前粗略读一遍再开始写,不然 L1 设计错了 L3 重构来不及
时间大概一个 level 15 到 20 分钟,留点 buffer
Python 的话 sortedcontainers 不一定有,提前确认;Java 用 TreeMap 比较稳参考

CodeSignal 官方有 General Coding Framework Sample,强烈建议做一遍
Reddit r/csMajors 和 r/leetcode 搜 "CodeSignal ICF" 能挖到不少原题
Blind 上 Meta tag 下面也有人发祝大家 OA 顺利,攒人品,求加一些大米,谢谢

About This Question

This is a reported interview question from a meta interview for a swe role (newgrad level) during the oa round reported in 2026.

It covers the following topics: Binary Search, Queue .