真实面经题目 · 原创解析
10G IP 文件、1G 内存,如何找出现最多的 Top10 IP?
这题考察海量数据精确 TopK 的分治思路、内存估算、全局正确性和数据倾斜处理。
真实面经题目 · 原创解析
这题考察海量数据精确 TopK 的分治思路、内存估算、全局正确性和数据倾斜处理。
精确方案是流式读取 10G 文件,按 `hash(ip) % N` 写入多个桶文件,保证相同 IP 必须落到同一桶,并让最大桶能在 1G 内存内处理。然后逐桶加载,用 HashMap 统计该桶内每个 IP 的全局频次,再把每个计数结果送入大小为 10 的小根堆;堆顶是当前第 10 大,只有更高频的 IP 才替换。最后堆中就是全局 Top10。若单桶仍过大,增加桶数或二次分片;允许误差时才考虑 Count-Min Sketch。
1G 内存不是只能看文件大小,还要估算唯一 IP 数、字符串或整数表示、HashMap entry 开销和堆对象开销。通常要把 IP 转成 32 位整数并预留安全系数。
对每个 IP 使用同一个 hash 规则落桶,相同 IP 必须进入同一个桶。这样某个 IP 的所有出现次数都能在一个桶里被完整统计,不会被拆散到多个局部计数里。
每次只加载一个桶文件,使用 HashMap 统计 `ip -> count`。处理完一个桶就把计数结果合并到全局小根堆并释放内存,峰值由最大桶决定。
堆大小固定为 10。遍历所有桶内计数项时,堆未满就入堆;堆满后只有频次大于堆顶才替换。这样不用保存所有候选,也不会漏掉高频 IP。
如果某个桶异常大,可以加大 N 或对该桶二次分片。Count-Min Sketch、Space-Saving 等近似算法省内存但有误差,只有题目允许近似时才能替代精确方案。
10G 文件里的唯一 IP 数和对象开销可能远超 1G,尤其用字符串和普通对象时内存放大会很明显。
增加桶数、二次分片,或先把 IP 转整数减少内存。如果数据极端倾斜,单个超高频 IP 本身不占太多唯一键,但桶里其他唯一键仍要继续拆。
如果每个 IP 的完整频次已经在桶内算准,取每桶 Top10 再全局合并是可行的;但必须说明相同 IP 不跨桶,否则局部 TopK 会漏全局候选。
题目没要求时可任意;生产里要定义 tie-break,例如按 IP 数值、首次出现时间或字典序,保证结果可重复。