题目重点:Nvidia System Software 面经明确要求按 status code 聚合 count 和 average response time;本文定义日志记录、一次扫描实现、异常值和流式追问。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练输入为 (HTTP 状态码, 毫秒响应时间) 二元组流;状态码限 100–599,响应时间为非负有限数。题目只说 status code,未限定 HTTP。
- 同一状态码每条有效日志计一次;没有出现的状态码不输出。空输入返回空映射。
- 遇非法记录抛错而不是跳过;若面试官要求部分成功,应额外报告 bad record 数及跳过规则。
解题路线
- 按状态码维护 count 与 latency_sum 两个累加量。读到一条记录时先校验,再令 count+=1、sum+=latency。
- 扫描结束后按状态码排序输出 (count,sum/count)。只有已出现的状态码会有非零分母。
- 解释为何只保留 sum 和 count 已足够求均值;如果要 p95,就需要直方图、采样或可合并分位数摘要,不能从均值推回。
手动走一遍
输入 (200,10)、(500,40)、(200,30)、(500,60) 后,200 的 count=2、sum=40、mean=20ms;500 的 count=2、sum=100、mean=50ms。若某状态码没有记录,不产生均值,也不存在除以零。
Python 参考实现
下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。
代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。
from collections import defaultdict
from math import isfinite
def aggregate_status_latency(records):
"""Each record is (HTTP status code, response time in milliseconds)."""
totals = defaultdict(lambda: [0, 0])
for status, latency_ms in records:
if not isinstance(status, int) or not 100 <= status <= 599:
raise ValueError("invalid HTTP status")
if not isinstance(latency_ms, (int, float)) or not isfinite(latency_ms) or latency_ms < 0:
raise ValueError("invalid response time")
totals[status][0] += 1
totals[status][1] += latency_ms
return {
status: (count, duration / count)
for status, (count, duration) in sorted(totals.items())
}
复杂度
N 条记录、K 个不同状态码:聚合时间期望 O(N),排序输出 O(K log K),空间 O(K)。若输出不要求稳定排序,可省掉排序成本。流式跨分片聚合只需合并各分片的 sum 与 count。
易错点与追问
容易失分的边界
- 先计算每个分片平均值再对这些均值取平均,会在分片样本量不同时产生错误结果;应合并 sum/count。
- 把响应时间秒与毫秒混用,输出的平均数虽可计算但意义错误。
- 接受 NaN 或无限值后,聚合结果被污染;训练代码拒绝这类输入。
- 根据当前状态码数量固定数组大小,忽略未知或非标准状态码;题面未规定全集时用映射更稳妥。
继续深挖
- 若要求按时间窗和服务一起聚合,键扩展为 (service,status,window),并定义事件时间和迟到窗口。
- 若要近似 p95,讨论桶化直方图或可合并摘要的精度与内存取舍。
- 日志量巨大时分区聚合,再按 status 合并 count 和 sum;溢出风险取决于延迟单位与计数上限。
