题目重点:读取各host端口输入输出速率,先明确最高BPS定义,再流式聚合所有端口。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练四列host,port,input_bps,output_bps,速率非负整数bits/sec,一次快照每host-port唯一。选择metric=input/output/total,默认total为训练选择,不声称题目省略的metric已确定。
- 并列取host字典序小,空输入None;注释#行和空行忽略。跨时间重复快照不能直接相加,需另定义time/window。
解题路线
- CSV按行读取,每条根据metric取值,累加totals[host]。host可能多个端口,求host总率不是找单端口最大;大数字用整数保留精确,不转float。
- 读完整后对host聚合结果求max,tie按名称固定。用csv解析而不是手动split,支持字段引号;检查列数/空host/非负指标,失败显式报错。
- 文件大时先消除全文件read和sort全部rows:stream减少峰值到host数状态,时间仍必须看每条,因为最后一条可能改变赢家,不能承诺次线性精确扫描。
- 若host数本身超内存,按host哈希落盘分区后各区聚合,再比各区max;网络/磁盘吞吐可能主导。多线程纯求和并不能自动提高单磁盘读取带宽,先量测瓶颈。
手动走一遍
A两port总率8+7=15,B单port14,赢家A不是单行最大B。A input100/output1,B input2/output200,在input与output政策下赢家不同,必须先问口径。
Python 参考实现
下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。
代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。
import csv
from collections import defaultdict
def highest_bps(lines,metric='total'):
"""CSV host,port,input_bps,output_bps; snapshot rows unique per host/port.
metric input/output/total explicit; sum ports, tie lexical host. Empty ->None.
Lines starting # are comments. Nonnegative integer bits/sec, not bytes/sec.
"""
if metric not in ('input','output','total'):raise ValueError('metric')
totals=defaultdict(int)
for row in csv.reader(line for line in lines if line.strip() and not line.lstrip().startswith('#')):
if len(row)!=4:raise ValueError('four columns required')
host,port,incoming,outgoing=row;host=host.strip();a=int(incoming);b=int(outgoing)
if not host or not port.strip() or a<0 or b<0:raise ValueError('invalid row')
totals[host]+=a if metric=='input' else b if metric=='output' else a+b
if not totals:return None
host=min(totals,key=lambda h:(-totals[h],h));return host,totals[host]
复杂度
R行/H host,O(R+H)时间/O(H)聚合状态,加最长输入行缓冲。外部分区需额外磁盘I/O和空间;文件跨快照时存储/聚合grain不能忽略时间。
易错点与追问
容易失分的边界
- 最大port误当最大host。
- bps误当bytes/sec造成8倍差异。
- 多行同端口重复snapshot简单累加,值不再是某时点速率。
继续深挖
- 如果输出所有并列host,如何保留tie集合?
- 数据是计数器累计bytes而非速率,需用时间差和reset规则先计算bps。
