难度:中级
题型:笔试(编程题)
题目描述:性能测试结束后拿到一份压测日志,请实现函数 p95_by_api:按接口分组,统计每个接口的 P95 响应时间(该接口所有请求耗时升序排列后,取第 ceil(0.95*n) 个,n 为请求数)。
代码框架:
def p95_by_api(logs):
"""
logs 形如 [{"api": "/order", "cost": 0.8}, ...],cost 单位秒
返回 {接口名: P95耗时},保留 2 位小数
"""
# 请在此处补全
pass
assert p95_by_api([
{"api": "/a", "cost": 1}, {"api": "/a", "cost": 2}, {"api": "/a", "cost": 3},
{"api": "/a", "cost": 4}, {"api": "/a", "cost": 100},
]) == {"/a": 100.0}
assert p95_by_api([
{"api": "/a", "cost": 0.1}, {"api": "/b", "cost": 0.5},
]) == {"/a": 0.1, "/b": 0.5}
assert p95_by_api([]) == {}
参考答案/答题要点:
参考题解:
import math
from collections import defaultdict
def p95_by_api(logs):
group = defaultdict(list)
for log in logs:
group[log["api"]].append(log["cost"])
result = {}
for api, costs in group.items():
costs.sort()
idx = math.ceil(0.95 * len(costs)) - 1 # 1-based 转下标
result[api] = round(costs[idx], 2)
return result
采分点:①分组用 defaultdict;②P95 下标换算 ceil(0.95*n)-1(写 int(0.95*n) 会差一位);③round 保留精度;④空输入边界;⑤加分项:数据量极大时用"计数排序/分桶近似"(耗时先分桶统计频次再累加找 95% 分位),不必全量排序。