题目
如何从大量的 URL 中找出相同的 URL?(百度) 如何从大量数据中找出高频词?(百度) 如何找出某一天访问百度网站最多的 IP?(百度) 如何在大量的数据中找出不重复的整数?(百度) 如何在大量的数据中判断一个数是否存在?(腾讯) 如何查询最热门的查询串?(腾讯) 如何统计不同电话号码的个数?(百度) 如何从 5 亿个数中找出中位数?(百度) 如何按照 query 的频度排序?(百度) 如何找出排名前 500 的数?(腾讯)
背景知识
1024B=1KB 1024KB=1MB 1024MB=1GB
2^32次B=2^32/1024/1024/1024=4GB
2的32次方是:4294967296, 大约是43亿
寻找共同的URL
题目描述
给定 a、b 两个文件,各存放 50 亿个 URL,每个 URL 各占 64B,内存限制是 4G。请找出 a、b 两个文件共同的 URL。
解答思路
(1) 一份文件50亿URL, 认为如果一个URL一B的话, 大约5GB, 那么每个URL 64B的话, 就需要大概320G内存.
(2) 内存需要太大, 因此肯定不能放入到内存中比较. 那么就考虑将a, b两个文件进行拆分, 拆分到能够放入到内存中的地步.
(3) 4G内存的话 能放下 2^32 / 2^6 = 2 ^ 26条URL, 大约5000W条吧.
(4) 那么50亿数据就需要分成 50亿 / 5000W = 100个组, 考虑到数据可能存在倾斜, 那就分配到1000个组.
(5) 因此对于a文件中的50亿URL, 逐个计算 hash值, 然后取余 1000, 即index = hash(url) % 1000, 然后根据index放到一个新文件中, 一共会形成1000个文件, a0, a1, ..a1000
(6) 同样的b文件也会生成b0, b1, ..b1000, 一共1000个文件
步骤5, 6的做法, 就跟hashMap根据每个元素的key值, 找在数组中的位置一样
(7) 因为是根据url的值计算放入哪个文件, 因此相同的URL, 在a, b文件拆分出来的小文件中一定是对应的, 即一定是a0文件和b0文件中, 可能存在相同的URL, 依次类推.
(8) 比对a0, b0文件, 将a0文件中的所有url加载到内存中, 放入一个hashMap, 然后将b0文件中的url, 依次读入内存中(注意无需全部读入), 一旦出现重复的key的时候, 就将该url写入一个新的文件, 表示是重复的URL.
(9) 重复步骤8, 直到比对完1000个文件, 就找到了所有重复的URL