1、Question
给定 a、b 两个文件,各存放 50 亿个 URL,每个 URL 各占 64B,内存限制是 4G。请找出 a、b 两个文件共同的 URL
2、分析
50亿 * 64B = 320GB (1GB=1000 MB=1000 000 KB=1000 000 000 B)
320GB的文件,无法直接加载到内存中进行处理。对于数据量太大无法一次加载到内存的题目,一般采用分治法。把大的文件拆分中多个小文件,然后单独处理每个小文件,最终再汇总每个计算结果。把320GB分成1000份,一份大概300MB。具体分多少份,根据内存大小来决定。分成1000份,具体怎么分?对于一个具体的url,要把它分到哪个文件,此处采用hash取模的方式,对每个url,使用hash函数求hash值,然后对1000求模,结果就是此url要保存到的文件序号。
比如www.baidu.com,假设计算url的hash值是1111,则模是111,所以把此url保存到文件111中。其他类推。
进行hash计算后,
A文件被分拆成1000份,记为a1,a2,。。。。a1000
B文件被分拆成1000份,记为b1,b2,。。。。b1000
则接下来需要知道:如果vi是a和b中共同包含的url,则vi一定同时在ai和bi中。因为都是采用相同的hash函数,且都是对1000求模。所以模值一定相同。
有个问题是:
如果许多url计算出的hash值一样,则会导致存入的文件过大,极端情况下可能导致A 文件的ai和B文件的bi的文件大小和大于4GB。导致还是无法一次性加载到内存中。此时可继续对文件进行拆分,知道满足要求。
如果不存在上述情况,则针对每个ai和bi文件。先把ai文件中的url都加载到内存,放入到一个hashset中,然后再遍历bi文件。如果hashset中包含则说明是共同的url。最终返回所有共同的url即可。