写同一道题,一个人用 C++,一个人用 Python。在 45 分钟的面试里,Python 那位多出来 5-8 分钟——不是 Python 更聪明,是它更短,打同样的逻辑要少写一半代码。
但在 Codeforces 上,Python 选手在时间限制紧的题目里会超时。原因很直接:CPython 比 C++ 慢 20-50 倍,竞赛平台的时间限制是以 C++ 为基准设的,Python 超时是真的超时,不是错觉。
同一个"写算法"的问题,两个场景给出完全相反的答案。
所以"哪个语言适合写算法"基本是个伪问题。真正坑人的不是选错语言,是没搞清楚自己在哪个场景,然后拿错场景的标准来要求自己:抱着 C 学《算法导论》以为这叫练基本功,结果一半时间在跟指针和越界较劲;为了显得专业用 C++ 刷 LeetCode,写得又慢又容易错,面试官其实只想看思路。语言没选错,场景搞反了。
常见的写算法其实就四种情况,先对号入座。
抱着 CLRS 学算法理论、上数据结构课,要的是把分治、动归、图论这些思想装进脑子,代码只是验证理解的草稿纸,跑得快慢无所谓。
刷 LeetCode、牛客准备面试,是另一回事——45 分钟内写出能过判题、面试官还看得懂的解法,时间是这里唯一的硬通货。
打 Codeforces、ACM 这类竞赛,时间和内存限制卡到极限,常数、STL 的底层行为、读入优化全都要抠。
做科学计算,物理仿真、信号处理、数学建模那一类,核心是矩阵运算和数值精度,算法对不对、数值稳不稳定,比代码风格重要得多。
这四种情况下,"哪个语言好"的答案差得很远,下面分开说。
学算法理论:Python 几乎没有对手
《算法导论》的伪代码是这样的:
MERGE-SORT(A, p, r)
if p ≥ r
return
q = ⌊(p + r) / 2⌋
MERGE-SORT(A, p, q)
MERGE-SORT(A, q + 1, r)
MERGE(A, p, q, r)
Python 翻译这段几乎是逐行映射:
defmerge_sort(arr):
if len(arr) <= 1:
return arr
mid = len(arr) // 2
left = merge_sort(arr[:mid])
right = merge_sort(arr[mid:])
result, i, j = [], 0, 0
while i < len(left) and j < len(right):
if left[i] <= right[j]:
result.append(left[i]); i += 1
else:
result.append(right[j]); j += 1
return result + left[i:] + right[j:]
换 C 语言实现同一个算法,脑子里要同时管:临时数组开多大、三个推进指针的边界、l + (r - l) / 2 为什么不直接写 (l + r) / 2(整数溢出防护)。
这些细节本身没有错,但它们消耗的是同一份注意力,而目标是理解分治结构、理解递归树、理解为什么时间复杂度是 O(n log n)。衡量语言摩擦的标准很简单:实现过程中花了多少时间在"让代码通过编译"和"让代码在逻辑上正确"之间切换? Python 几乎把前者降到零。
C 有没有价值?有,但用法完全不一样:在需要往深处看的时候,提供一个向下的通道。
举个具体的例子。CLRS 提到快速排序是原址排序(in-place),缓存友好。这在 Python 里是个结论,接受就行。用 C 重写一遍 partition,能看见:所有操作在同一块内存上发生,没有任何临时拷贝,i 和 j 在连续地址上移动:
intpartition(int arr[], int low, int high){
int pivot = arr[high];
int i = low - 1;
for (int j = low; j < high; j++) {
if (arr[j] <= pivot) {
i++;
int tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp;
}
}
int tmp = arr[i+1]; arr[i+1] = arr[high]; arr[high] = tmp;
return i + 1;
}
"缓存友好"从结论变成了可以感知到的东西。
Python 是主战场,C 是偶尔往深处看一眼的工具。
面试刷题:默认 Python,但有例外
LeetCode 上 C++、Java、Python 的用户量大致三分天下,各占约 26%。但如果问面试官更希望候选人用什么,答案更多是 Python。
原因很实际:同一道题,Python 通常比 C++ 少写 30-40% 的代码。在 45 分钟的面试里,5-8 分钟的差距足够多处理一个边界情况,或者把解法解释得更清楚。面试官评分的是算法思维,不是代码执行速度。
但 Python 有几个真实的陷阱,在面试里踩到会直接出错:
陷阱一:list.pop(0) 是 O(n),不是 O(1)。
用列表模拟队列,做 BFS:
# 错误写法,pop(0) 是 O(n),BFS 会从 O(n) 变成 O(n²)
queue = [start]
while queue:
node = queue.pop(0)
# 正确写法
from collections import deque
queue = deque([start])
while queue:
node = queue.popleft() # O(1)
陷阱二:默认递归深度上限是 1000。
写 DFS 递归解法,数据量一大直接 RecursionError:
import sys
sys.setrecursionlimit(10000) # 要么提前调高上限,要么改成迭代写法
陷阱三:Python 没有内置最大堆,用负数模拟。
import heapq
# heapq 是最小堆,取最大值要取负
heap = []
heapq.heappush(heap, -val)
max_val = -heapq.heappop(heap)
踩到这些,算法逻辑本身通常没问题,基本是 Python 行为不熟。提前知道,遇到了能快速定位。
反过来,Python 刷题真正的优势是标准库,几个东西不知道就是白白多写代码。最值钱的是 functools.lru_cache,记忆化递归一行搞定,斐波那契、爬楼梯这类一加装饰器就从指数级降到线性:
from functools import lru_cache
@lru_cache(maxsize=None) # Python 3.9+ 可以直接用 @cache
defclimb(n):
if n <= 2: return n
return climb(n - 1) + climb(n - 2)
剩下几个高频的:collections.Counter 一行统计词频,defaultdict(list) 建邻接表不用判 key 在不在,bisect.bisect_left 在有序数组里二分定位、bisect.insort 二分插入,heapq.nlargest(k, ...) 直接拿前 k 大。这些底层都是 C 实现,比手写循环又快又短。会用和不会用,同一道中等题能差出十几行代码和五分钟。
例外情况: 本身 C++ 写得很熟练,或者面试高频交易(HFT)方向的岗位,C++ 是更合适的选择。用不熟悉的语言准备面试,反而是给自己加难度。
算法竞赛:C++ 没有商量余地
Codeforces 顶级选手几乎全用 C++,原因直接:
竞赛题目的时间限制以 C++ 为基准,Python 会真实超时。STL 的 sort、priority_queue、unordered_map 都是高度调优过的实现,竞赛里踩常数、卡内存,C++ 的底层控制权是最大的。
PyPy 比 CPython 快 5-10 倍(JIT 编译),部分平台支持,能解决一部分超时问题。但在时间限制极紧的题目上,还是会被 C++ 拉开差距。
想打竞赛,C++ 是唯一值得投入的选择。
科学计算:MATLAB 和 Python 的此消彼长
这里有一个近几年在发生的转变值得说清楚。
MATLAB 在数值算法领域的地位一直很特殊。语法接近数学公式:
x = A \ b; % 解线性方程组 Ax = b(自动选 LU 或 QR 分解)
[V, D] = eig(A); % 特征值分解
Y = fft(signal); % 快速傅里叶变换
背后调用的是工业级数值库,在纯矩阵运算上比 NumPy 快约 10-30%(R2025a vs NumPy 的最新基准数据)。
但 MATLAB 的处境在变。TIOBE 指数里 MATLAB 排第 17 位,Python 在前两名,差距超过十倍。AI/ML 的所有主流框架(TensorFlow、PyTorch、scikit-learn)全是 Python 生态。更实际的问题:MATLAB 是商业软件,一个完整授权每年几千到几万元,离开校园后很多公司根本不会买。
Python 的数值计算栈(NumPy + SciPy + Matplotlib)已经能覆盖绝大部分科学计算场景。学术圈用 MATLAB 的比例在下降,物理、化学、生物信息等领域的论文代码大量转移到 Python。
具体建议:如果课程或实验室要求 MATLAB,学它,用好它,在某些工程领域(Simulink 建模、控制系统)还没有等价替代。如果是为长期做准备,NumPy/SciPy 的投入回报更高,学的东西可以无缝对接 AI/ML。两者不是非此即彼,MATLAB 有 Python 基础的话一个月能上手。
Go 呢
Go 作为面试语言这几年有一小部分用户在增长,主要集中在 Stripe、Cloudflare 这类以 Go 为主要后端语言的公司——候选人日常写 Go,面试就用 Go,合理的。
不是专门写 Go 后端的,用 Go 学算法或者刷题,没什么特别的理由。标准库的算法工具不如 Python 丰富,学习资源少,社区里算法相关的讨论也小得多。
速查
| | |
|---|
| | |
| | |
| | |
| Python(NumPy/SciPy)或 MATLAB | Python 更通用,MATLAB 专业工具箱有独特优势 |
同一个 BFS,Python 版在 LeetCode 上直接 AC,搬到 Codeforces 时间限制紧的题目里可能超时,这两件事都对,因为两边判题标准不一样——这其实是选语言之前最该想清楚的事。
Python 那三个坑(deque vs list.pop(0)、递归上限 1000、最大堆取负)不知道有多少人是在真实面试里才踩到的,评论区说说是什么题触发的。