一位写技术博客的独立开发者 Kris Shamloo,5月3日在自己的网站上贴出一道他常年用来筛选工程师的面试题:写一个函数,求一个数组的中位数。乍看像是入门练习,甚至有点像“送分题”,但他真正想说的是——这道题能在几分钟内,把候选人对API设计、边界条件、统计直觉的真实功力全部照出来,比“为什么下水道盖是圆的”这类脑筋急转弯题更接近工程师日常真实的判断场景。

这不是一次新闻事件,更像一次方法论的自我暴露。但它恰好撞上了技术面试设计这些年的一次风向转变。

脑筋急转弯题为什么被淘汰了

十几年前,硅谷面试圈流行过一阵“智力谜题热”,谷歌这类公司都问过类似“下水道盖为什么是圆的”的问题。后来业界逐渐达成共识:这类题目更多考验的是候选人有没有听过标准答案,跟实际写代码的能力关联很弱。

FizzBuzz 式的基础编码题因此接棒,成为筛选“候选人是否真的会写代码”的第一道门槛。Kris Shamloo 的中位数题延续的正是这个思路,但比 FizzBuzz 多了一层——它不仅测试编码能力,还天然带出设计追问。

这道题真正测的不是算法,是设计判断力

中位数的计算逻辑本身没什么难度:排序、取中间值,奇偶分两种情况处理。但 Kris Shamloo 强调,真正拉开候选人差距的是几个追问:

  • 排序职责该放在函数内部,还是交给调用方?
  • 如果数组是引用传入的,函数能不能直接原地修改?
  • 空数组要不要抛异常,抛什么类型的异常?

这几个问题背后,其实是两种截然不同的API设计路径:一种是函数内部统一做拷贝排序,保证调用方不用操心输入状态,代价是每次调用都要付出排序的时间开销;另一种是约定调用方必须传入已排序数组,函数直接按索引取值,换来常数时间复杂度,但把“数组必须有序”这个隐性契约甩给了调用方,一旦对方传错,函数本身毫无察觉。

两种API设计取舍 函数内部排序 复杂度:O(n log n) 契约:调用方无需操心 代价:每次都重排 适合:调用频率低 数据源不受控场景 预排序索引取值 复杂度:O(1) 契约:调用方须保证有序 代价:违约无提示,易出错 适合:高频调用 数据本就有序的系统

没有哪种设计绝对正确,关键是候选人有没有意识到这是一个权衡,而不是背出一个标准答案。这也是为什么 Kris Shamloo 说自己不在乎有人在奇偶分支或数组下标上踩坑——重要的是能不能看到候选人怎么调试、怎么解释自己的选择。

从这道入门题到更硬核的中位数变体

中位数问题在算法面试里其实还有更进阶的版本,比如经典的“寻找两个有序数组的中位数”,要求对数时间复杂度完成,是公认的算法面试难题;再往上是大规模或流式数据下的中位数近似算法,工程上常用双堆结构或分位数草图来处理数据源源不断涌入、无法一次性排序的场景。

检索中出现过一些声称与大规模中位数面试题相关的社区讨论线索,但暂未能确认这些案例与本文所述场景确实对应,这里只作为未核实的旁证提及,不当作既定事实使用。

中位数问题的算法谱系 排序取中位数 入门级 O(n log n) 两数组中位数 算法面试 Hard 级 流式/近似中位数 大规模工程场景

谁该在意这道“简单题”

对面试官来说,这类题的启发在于:一道题只要留足追问空间,就不需要靠难度堆砌来筛人。对求职者来说,更现实的提醒是——死记硬背中位数的标准代码没有用,考官盯的是你能不能主动说出“这里有两种做法,各自代价是什么”。

好的面试题不比谁更难,比谁更能逼出真实判断

这也解释了 median 相较 mean 在工程实践里更受青睐的原因:均值容易被极端值带偏,中位数天然对异常值不敏感,更适合描述“典型情况”。但中位数也有代价——它会抹掉数据分布的形状,样本量小或分布本身有意义时,只看中位数反而会漏掉关键信息。

  • 风险.如果候选人只把这道题当成“背标准答案就能过”的关卡,反而会在追问环节暴露对设计权衡毫无准备。

这类“简单但有层次”的题型能不能真正预测工程能力,目前还缺乏严格的实证支持,更多停留在资深面试官的经验判断层面。但至少它比脑筋急转弯题多了一样东西:追问的每一层都对应候选人未来写代码时真实会遇到的选择。