这是一篇 失败复盘。我拿到 Citadel New Grad 的三轮 back-to-back video interview,题目其实都做出来了大半,最后却挂在其中一轮——不是败给算法,而是败给沟通。这篇不重点讲题(三道题只做简要说明),而是把镜头对准那轮翻车:一道不熟的原题、一个全程冷漠的面试官、一场关于「数据该怎么表示」的拉锯战,以及连面无休息的 2 小时 15 分对判断力的消耗。如果你正在准备高强度连面,希望我的教训能帮你少踩一个坑。
一、面试概览
| 维度 | 详情 |
|---|---|
| 入口 | 海投冷投,无内推、无 OA,简历直接被捞进 screening |
| Screening | 45 分钟,轻松,项目闲聊 + 几道 BQ + 1 道回溯 |
| 正式面 | 三轮 back-to-back,共 2 小时 15 分,中间无休息 |
| 每轮结构 | 前半简历 / BQ,后半算法 coding,各约 45 分钟 |
| 平台 | Citadel 自研 video + 编辑器一体平台,UI 干净,非 HackerRank / CoderPad |
| 结果 | 3–4 天后收到拒信 |
先说结论:Citadel 流程快、技术门槛高、题目贴近真实工作(模型设计、系统模拟、贪心)。但真正决定成败的,是 你能不能在压力下把一个不配合你的面试官带进你的思路。
二、三道题(简要)
1. Screening:排列等式回溯
把 1–9 填进 ABC、DEF、GHI 三个三位数,数字不重复,问有多少组满足 ABC + DEF = GHI。9! 全排列暴力即可,轻松过,不展开。
2. 第一轮:DMV 任务分配(负载均衡)
每个员工有一个 multiplier 代表速度(multiplier=2 表示耗时翻倍),每个任务有 base duration(multiplier=1 的标准耗时)。员工串行工作、任务不可拆分、由你决定分配,求完成所有任务的最短总时间。
典型 load balancing:任务按耗时从大到小排序,用最小堆维护每个员工的累积完成时间,贪心地把当前最大的任务塞给最空闲的员工(乘以其 multiplier)。这轮做对了。
import heapq
def min_time_to_finish(tasks, multipliers):
# tasks: 每个任务的 base duration 列表
# multipliers: 每个员工的速度倍率(值越大越慢)
# 堆里存 (员工当前累积完成时间, 该员工倍率),初始都为 0
heap = [(0.0, m) for m in multipliers]
heapq.heapify(heap)
# 大任务优先分配,避免最后无处安放
for dur in sorted(tasks, reverse=True):
finish, mult = heapq.heappop(heap)
finish += dur * mult # 该员工做这个任务的实际耗时
heapq.heappush(heap, (finish, mult))
# 最晚完成的那个员工的时间 = 全部完成时间
return max(finish for finish, _ in heap)
if __name__ == "__main__":
# 3 个任务,2 个员工(倍率 1 和 2)
print(min_time_to_finish([4, 2, 3], [1, 2])) # 6.0
时间复杂度 O(n log m)(n 任务、m 员工);空间复杂度 O(m)。
3. 第三轮:字符版拓扑排序
输入若干字符对(有向边 A→B)与一个字符全集,输出任意一个满足全部先后约束的合法顺序(类似 Alien Dictionary)。
构图 + 入度表,Kahn 算法(BFS)。这轮面试官很松弛,还一起聊了优化,体验很好。
from collections import deque, defaultdict
def valid_char_order(pairs, chars):
# pairs: [(a, b), ...] 表示 a 必须排在 b 之前
# chars: 字符全集
graph = defaultdict(list)
indeg = {c: 0 for c in chars}
for a, b in pairs: # a -> b
graph[a].append(b)
indeg[b] += 1
# 所有入度为 0 的字符先入队
queue = deque(c for c in chars if indeg[c] == 0)
order = []
while queue:
c = queue.popleft()
order.append(c)
for nxt in graph[c]:
indeg[nxt] -= 1
if indeg[nxt] == 0:
queue.append(nxt)
# 若长度不足说明有环,无合法顺序
return order if len(order) == len(chars) else []
if __name__ == "__main__":
pairs = [("a", "b"), ("b", "c"), ("a", "d")]
chars = ["a", "b", "c", "d"]
print(valid_char_order(pairs, chars)) # 例如 ['a', 'b', 'd', 'c']
时间复杂度 O(V+E);空间复杂度 O(V+E)。
三、翻车的那一轮:到底发生了什么
第一轮和第三轮都顺,问题出在中间那轮。复盘下来,翻车是三件事叠加的结果:
1)题不熟,开场先慌了。 那是一道没刷过的原创题,不是任何眼熟的模板。一上来我脑子空了几十秒——而连面到这时已经过去一个多小时,没休息,判断力本就打了折。开场慌乱直接吃掉了后面本该用来 debug 的时间。
2)面试官冷,不给任何缓冲。 前两轮面试官会顺着我的话往下接,这轮的面试官全程面无表情、不给提示、不做引导。我抛出思路,对面没有反馈,我无法判断方向对不对,只能自己硬扛。
3)在「数据怎么表示」上僵持太久。 我的思路其实可行——想用一种结构来存状态。但面试官坚持要我换成另一种类型。我们在 representation 上来回拉锯了很久,最后我硬着头皮迁就他的类型。切换之后类型转换把我绕晕,逻辑写出 bug,等发现时已经没时间 debug 了。
事后我几乎能确定:我原来的方法是能跑通的。挂点不是算法能力,是我 没能在冲突里既守住可行方案、又让面试官愿意跟着走。
四、给你的可操作建议
针对上面三个坑,我把教训拆成能直接用的动作:
遇到不熟的题,先出声、别默想。 沉默几十秒对冷面试官是灾难,对面只会觉得你卡住了。哪怕只是复述题意、列出输入输出、说「我先想暴力解再优化」,也要让思考过程可见。把慌乱转成结构化的自言自语。
面对冷场面试官,主动制造反馈点。 不要等他给提示。每推进一步就停下来确认一句:「我打算这样存状态,你觉得这个方向 OK 吗?」把「他不给反馈」变成「我主动要反馈」。一个不表态的面试官,往往会在你直接提问时给出信号。
遇到 representation 分歧,先问意图、再决定要不要换。 当面试官坚持另一种类型时,别急着推翻自己、也别硬顶。先问一句:「你倾向这个类型是出于什么考虑?是后面有扩展,还是接口约束?」——理解他的意图后,要么发现他是对的、心服口服地换;要么说明「我的结构也能满足这点,能否让我先按它写,跑通再讨论」。关键是别在没搞清动机前就盲目迁就,盲目切换比坚持己见更危险——因为你会用一种你没想清楚的表示去写逻辑。
留出 debug 缓冲。 连面无休息、时间吃紧时,宁可方案朴素也要留下最后几分钟跑样例。一个能跑通的朴素解,远胜一个漂亮但没时间验证的解。
一句话总结:在 Citadel 这种连面里,算法只是入场券,能不能带着一个不配合你的人走完你的思路,才是真正的分水岭。
五、连面节奏的备考建议
- 按真实节奏模拟。 找人陪你连做 2 小时以上、中间不休息,训练疲劳状态下的判断力,而不是每题都精神饱满地单独刷。
- 刻意练「冷面试官 + 生题」。 让陪练故意不给反馈、故意在 representation 上唱反调,逼你练出主动确认和据理力争的肌肉记忆。
- 准备沟通话术模板。 「我先复述题意」「我打算这样存,方向 OK 吗」「你倾向这个类型是出于什么考虑」——把这些句子练到脱口而出,压力下才用得出来。
- BQ 也别裸上。 每轮前半都有简历 / BQ,「Why Citadel」「哪个项目让你收获最大」这类要提前想好。
FAQ
Q1:Citadel New Grad 一定要做 OA 吗?
不一定。我这次是海投冷投、没有内推,也没做 OA,简历直接被捞进 screening 电话。他们似乎会根据简历挑一批人直接进流程,所以简历质量很关键。
Q2:三轮 back-to-back 到底多累?
三轮共 2 小时 15 分,中间完全没有休息,每轮约 45 分钟(前半 BQ、后半 coding)。真正难的不是单题,而是连着做到第二、三轮时判断力和沟通耐心的下滑——我翻车那轮正好卡在体力和注意力开始掉的时间点。
Q3:第二轮到底为什么挂?是算法不会吗?
不是。题我大方向想对了,方法事后确认能跑通。挂点是:题不熟导致开场慌乱、面试官全程冷漠不给反馈、以及和他在数据表示上僵持太久。硬着头皮换了类型后被类型转换绕晕、逻辑出 bug、没时间 debug。是沟通和临场处理,不是算法。
Q4:面试官坚持另一种数据表示时该怎么办?
先别急着推翻自己。问清他为什么倾向那种类型(扩展性?接口约束?),理解意图后再决定:要么心服口服地换,要么说明你的结构也能满足需求、请求先按你的写跑通再讨论。最忌讳在没搞清动机前盲目迁就,用一个自己没想透的表示去写逻辑。
Q5:Citadel 的题偏什么方向?
贴近真实工作——模型设计、系统模拟、贪心策略,比如 DMV 任务分配负载均衡。也有偏标准的题如字符版拓扑排序、排列回溯。整体技术门槛高,但决定成败的常常是临场沟通。
正在准备 Citadel New Grad 连面?
Citadel 三轮连面强度大、节奏快,算法之外,「冷面试官」「生题僵持」「表示分歧」这些临场场景才最容易翻车。如果你想按真实连面节奏做一次高压模拟,练一练主动确认、据理力争和折中的话术,欢迎交流:发岗位 JD,我们先做题型预测,再排一套连面陪练计划。
立即添加微信 Coding0201,获取 Citadel 连面陪练方案。
联系方式
- 微信:Coding0201
- Email:[email protected]
- Telegram:@OAVOProxy