[转载] 我喜欢的一道软件工程面试题:计算中位数
原文出处: https://krisshamloo.com/blog/007
作者: Kris Shamloo
原文发布日期: 2026-05-03
许可协议: 本文为原文的中文翻译,所有权利归原文作者所有。
我喜欢的一道软件工程面试题:计算中位数
我手头攒了不少题目,用来在技术面试中考察候选人。它们的风格都比较相似。我不问脑筋急转弯式的题目——我觉得那种题价值很低。相反,我倾向于问一些看似直白、却能从几个不同角度深入探讨的题目。
这就引出了不起眼的「中位数」。
写一个函数,接收一个数字数组,返回它的中位数。
- 最低限度: 这能给你一个类似「Fizz Buzz」的信号,确认候选人确实会写代码。对一组数值做归约,这是基本功。
- 一上来就有讲究: 数组必须先排序。该让这个函数来排序,还是让调用方来排?如果数组是按引用传入的,直接就地修改(mutate)合适吗?API 的设计会如何影响性能?
- 它有一个 off-by-one 陷阱: 说实话,我不在乎谁掉进这个陷阱——我自己也经常掉进去。但你通常能借机观察一个人是如何调试一个小问题的。
- 它有一个分支: 数组长度为偶数和奇数两种情况。
- 它能引出关于统计学的讨论: 以及为什么在大多数场景下,你可能更偏爱中位数而不是平均数。
- 给候选人加分的机会: 因为这道题太容易写测试了。
- 展示标准库知识的机会: 比如直接用统计模块。
- 给候选人一个教我点东西的机会: 关于一个很酷的算法技巧——快速选择(quickselect)——在写这篇博文之前我自己都不知道它。
下面是一个带讨论注释的 Python 实现。
def median(numbers: list[float]) -> float:
# 如果列表是空的,我们该怎么办?
# 抛异常?还是返回一个哨兵值?
if not numbers:
raise ValueError("median called with empty list")
# Python 是按引用传递的,那么使用 sorted()
# 还是 numbers.sort() 各有什么影响?
numbers = sorted(numbers)
length = len(numbers)
mid = length // 2
# 高质量的候选人会勇敢地引入 1000 个依赖,
# 只为拿到一个判断偶数的 is_even 库函数。
if length % 2 == 0:
return (numbers[mid - 1] + numbers[mid]) / 2.0
else:
return numbers[mid]