在海量数据中统计出现次数最多的n个
分两种情况,
1 如果数据能够在内存中放下,比如如果海量数据是ip地址,最多有4G个ip地址,每个ip地址占4个字节 需要内存16G,如果内存在几十G,则完全可以全部装入内存,
直接读取大文件,然后创建一个hash表,统计次数,最后再用堆统计最大的n个
2 如果不能在内存放下,比如海量数据是字符串,不同的字符串个数无限,内存中可能存不下,那么需要先将海量数据进行分堆,按照hash值进行分堆,分成适宜在内存中操作的小文件,比如内存1G,字符串有20G,那么就分成20个以上的小文件
为什么要用hash分堆,这样是为了保证同一个字符串只会出现在同一个文件
为了更好的理解上述两种算法,可以举个形象的例子
广场上有很多人,现在让你统计这些人的情况
1 统计哪个省份的人最多
可以依次问每个人是来自哪个省,记着每个省多少人了,然后再找最多的省份
2 统计哪天出生的人最多,此处的哪天,要包括具体年月日,即85年1月1号和86年1月1号是不同的日期
这种情况下,人脑要记录下每天有多少人,就没有办法记住了,所以要重新想办法
其实上面两种情况可以分别类比海量数据处理中,有充足内存和内存不够两种情况
当统计省份时,由于省份个数比较少,可以认为人脑可以记住
当统计日期时,不同日期太多,人脑一次处理不完,需要借助纸笔(外存)
那么统计哪天出生的人最多时,我们用什么办法呢
可以先把人群分堆,比如50~60的在一起,60~70的在一起等等,这样我们就把人群分成了大概10来份,如果还不够,继续分
1980年1月出生的 2月的。。。。等等 这样我们就把人群分成了12*80份(假设人群最大岁数为80岁)
如果没份人还是太多,继续细分
最终目的就是把问题细分为人脑能记住的规模