1. 给定 a、b 两个文件,各存放 50 亿个 url,每个 url 各占 64 字节,内存限制是 4G,让你
找出 a、b 文件共同的 url?
方案 1:可以估计每个文件安的大小为 50G×64=320G,远远大于内存限制的 4G。所以
不可能将其完全加载到内存中处理。考虑采取分而治之的方法。
s 遍历文件 a,对每个 url 求取
,然后根据所取得的值将 url 分别存储到 1000 个小文件(记为
)中。这样每个小文件的大约为 300M。
s 遍历文件 b,采取和 a 相同的方式将 url 分别存储到 1000 各小文件(记为
)。这样处理后,所有可能相同的 url 都在对应的小文件(
)中,不对应的小文件不可能有相同的 url。然后我们只要求出 1000 对小文件中相同的
url 即可。
s 求每对小文件中相同的 url 时,可以把其中一个小文件的 url 存储到 hash_set 中。然后
遍历另一个小文件的每个 url,看其是否在刚才构建的 hash_set 中,如果是,那么就是共
同的 url,存到文件里面就可以了。
方 案 2:如果允许有一定的错误率,可以使用 Bloom lter,4G 内存大概可以表示 340
亿 bit。将其中一个文件中的 url 使用 Bloom lter 映射为这 340 亿 bit,然后挨个读取另
外一个文件的 url,检查是否与 Bloom lter,如果是,那么该 url 应该是共同的 url(注
意会有一定的错误率)。
ps:个人认为方案 1 中的估计是不是有问题 50 亿就是 5*10 的 9 次方。小于等于 5*2 的 30 次
方,即 5G,
2. 有 10 个文件,每个文件 1G,每个文件的每一行存放的都是用户的 query,每个文件
的 query 都可能重复。要求你按照 query 的频度排序。
方案 1:
s 顺序读取 10 个文件,按照 hash(query)%10 的结果将 query 写入到另外 10 个文件
(记为
)中。这样新生成的文件每个的大小大约也 1G(假设 hash 函数是随机的)。
s 找一台内存在 2G 左右的机器,依次对
用 hash_map(query, query_count)来统计每个 query 出现的次数。利用快速/堆/归并
排序按照出现次数进行排序。将排序好的 query 和对应的 query_cout 输出到文件中。这
样得到了 10 个排好序的文件(记为