我曾在面试桌的两端都坐过。我曾一边在白板上设计系统架构,一边看着面试官默默点头;我也曾扮演那个默默点头的人,看着候选人在白板上设计通知系统。
候选人准备的内容与面试官实际评估的内容之间,存在着惊人的鸿沟。
候选人准备的内容
- LeetCode 困难题
- 冷门算法知识
- "请分享一个你曾经……的经历"
- 死记硬背的系统设计答案
面试官实际评估的内容
你如何处理模糊性。 拿到系统设计题时,我做的第一件事就是提出澄清性问题。"多少用户?延迟要求是什么?预算多少?"那些还没问问题就开始画框的候选人是个危险信号。他们在不了解需求的情况下就开始构建——在工作中也会如此。
对权衡的认知。 没有完美的架构。每个选择都有代价。当候选人说"我们应该用 Kafka 做消息队列"时,我会问"为什么不用 SQS?"如果他能清晰阐述权衡(Kafka:更高吞吐量、更大运维开销、更好的重放能力;SQS:更简单、托管服务、对大多数场景足够好),说明他理解工程。如果他说"Kafka 是行业标准",那他只是盲目跟风。
故障模式思维。 "这个服务宕机了怎么办?"如果答案是"它不会宕机",我就知道他从没在生产环境运维过系统。一切都会宕机。关键在于你是否为此做了设计。
沟通清晰度。 你能向房间里的非技术人员解释你的设计吗?高级职位需要与产品经理、设计师和高管沟通。如果你只能向其他工程师解释你的系统,那你的天花板就到了。
我问的问题(以及我真正在测试什么)
"请介绍一个你最近引以为豪的项目。"
我在测试:你能讲一个连贯的故事吗?你是否提到约束条件,而不仅仅是技术?你是否归功于团队,还是把所有功劳都揽在自己身上?你是否提到会做哪些改进?
"生产环境出现 500 错误。请描述你的调试过程。"
我在测试:你有系统化的方法,还是靠猜测?你是先检查日志和指标,还是直接改代码?你是否考虑影响范围?
"请为 [X] 设计一个系统。你有 45 分钟。"
我在测试:你是先提问,还是直接开始?你是从需求出发,还是从技术出发?你是否提到监控、错误处理和扩展——还是只考虑理想路径?
当我开始面试后,什么改变了
作为候选人时,我以为面试官想要"正确答案"。作为面试官时,我明白了根本没有正确答案。我评估的是你的思考过程。
那个设计简单系统、承认其局限性、并解释何时需要增加复杂度的候选人,比那个设计复杂系统却无法解释的候选人要强得多。
我的建议(来自面试桌两端)
给候选人:
- 在设计任何东西之前,先问 3-5 个澄清性问题
- 从简单开始,被要求时再增加复杂度
- 主动提及故障模式("如果这个服务宕机,会发生以下情况")
- 对每个重大决策解释权衡
- 诚实地承认你不知道的东西——"我没有大规模使用过 Kafka,但我理解它的吞吐量优势。对于这个场景,我会先用 SQS,如果需要重放功能再迁移"
给面试官:
- 不要测试特定技术知识——要测试工程判断力
- 问"你会做哪些改进?"——最优秀的工程师对自己的工作有强烈的见解
- 给候选人从错误中恢复的空间——他们如何应对犯错,比他们答对问题更能说明问题
最好的面试感觉像工作讨论。最差的面试感觉像审讯。请设计成前者。
