找工作——大数据的处理方式
1. top K问题:在海量数据中找出出现频率最高的前K个数、或从海量数据中找出最大的前K个数,这类问题统称为top K问题。
针对top K类问题,通常比较好的方式是分治+hash+小顶堆
eg:在1亿个浮点数中找出其中最大的10000个。
方法一:排序取出前10000个。 每个float占4B,1亿个浮点数400MB,对于内存小于400MB的该方法不能一次将全部数据读入内存进行排序,而且排序是对所有元素进行排序,做了很多无用功。
方法二:局部淘汰法。 用一个容器保存前10000个数,然后将剩余数字一一与容器中的最小数字比较,如果所有后续的元素都比容器中10000个数还小,那么容器内的这10000个数就是最大的10000个数。若某一后续元素比容器内的最小元素大,则删除掉容器内的最小元素,并将该元素插入容器,最后遍历完这1亿个数,得到结果容器中保存的数即为最终结果。
方法三:分治法。 将1亿个数据分成100份,每份100万,找出每份数据中最大的10000个,最后在100*10000个数据里面找出最大的10000个。如果100万选的足够理想,那么可以滤掉1亿数据里面99%的数据。
方法四:最小堆。 先读10000个数据构造大小为10000的小顶堆,然后遍历后续的数字,并与堆顶(最小)数字进行比较,若比最小的数字小,则继续读取后续数字;若比堆顶数字大,则替换堆顶元素并重新调整堆为小顶堆。直到1亿个数据遍历完毕。
如果在求1亿个出现次数最多的100个数,MapReduce 直接将数据均分到不同的机器上进行处理是无法得到正确结果,由于一个数据可能被分到不同的主机上,而另一个完全可能狙击到一个机器上。
2. 重复问题:在海量数据中查找重复出现的元素或者去除重复出现的元素。针对此类问题,一般可以用位图法实现。 例如:已知某个文件中包含一些电话号码,每个号码为8位,统计不同号码的个数。
解决办法:8位整数可以表示的最大十进制数值为99999999,如果每个数字对应位图中的一个为,那么存储八位整数大约需要99Mbit,因为1Byte=8bit,所以99Mbit折合成内存为99/8=12.375MB的内存,既可以使用12.375的内存表示所有8位数电话号码的内容。
3. 排序法:海量数据排序。 例如:针对一个文件中有9亿条不重复的整数,对这个文件中数字进行排序。
方法一:位图法