海量数据处理
处理海量数据的常规思路
分而治之/Hash映射 + Hash_map统计 + 堆/快速/归并排序
1、海量日志数据,提取出某日访问百度次数最多的那个IP
1.)分而治之/hash映射:把大文件化成(取模映射)小文件
2)hash_map统计:当大文件转化了小文件,那么我们便可以采用常规的hash_map(ip,value)来进行频率统计O(n)复杂度
3)堆/快速排序:得到每个文件次数最多的IP,然后汇总这几个文件排序取最大的ip次数
首先是这一天,并且是访问百度的日志中的IP取出来,逐个写入到一个大文件中。注意到IP是32位的,最多有个2^32个IP。同样可以采用 hash映射 的方法,比如%1000,把整个大文件映射为1000个小文件,再找出每个小文件中出现频率最大的IP(可以采用 hash_map 对那1000个文件中的所有IP进行频率统计,然后 依次找出各个文件中频率最大的那个IP )及相应的频率。然后再在这 1000个最大的IP中 ,找出那个频率 最大的IP ,即为所求。
2、寻找热门查询,300万个查询字符串中统计最热门的10个查询
1. hash映射 :顺序读文件中,对于每个词x,取hash(x)%5000,然后按照该值存到5000个小文件(记为x0,x1,...x4999)中
这样每个文件大概是200k左右。如果其中的有的文件超过了1M大小,还可以按照类似的方法继续往下分,直到分解得到的小文件的大小都不超过1M
2. hash_map统计 :对每个小文件,采用trie树/hash_map等统计每个文件中出现的词以及相应的频率
3. 堆/归并排序 :取出出现频率最大的100个词(可以用含100个结点的 最小堆 )后,再把100个词及相应的频率存入文件,这样又得到了5000个文件。最后就是把这5000个文件进行 归并(类似于归并排序) 的过程了
5、有10个文件,每个文件1G,每个文件的每一行存放的都是用户的query,每个文件的query都可能重复。要求你按照query的频度排序
hash映射/取模->hashMap统计->单文件堆排序->多文件归并
6、 给定a、b两个文件,各存放50亿个url,每个url各占64字节,内存限制是4G,让你找出a、b文件***同的url?
1. 分而治之/hash映射 :遍历文件a,对每个url求取,然后根据所取得的值将url分别存储到1000个小文件。这样每个小文件的大约为300M。遍历文件b,采取和a相同的方式将url分别存储到1000小文件中(记为)。这样处理后,所有可能相同的url都在对应的小文件(
O(N) + N' * O(logK),(N为1万,N’为hashmap的key的元素 算1万吧,K=10)
用一个含100个元素的最小堆完成。复杂度为O(100w*lg100)
13、2.5亿个整数中找出不重复的整数的个数,内存空间不足以容纳这2.5亿个整数。
/writer#/notebooks/45731388/notes/70253940/preview
对于这道题,顺序读取这 5 亿个数字,对于读取到的数字 num,如果它对应的二进制中最高位为 1,则把这个数字写到 f1 中,否则写入 f0 中。通过这一步,可以把这 5 亿个数划分为两部分,而且 f1 中的数都大于 f0中的数。
划分之后,可以非常容易地知道中位数是在 f0 还是 f1 中。假设 f0中有 1 亿个数,那么中位数一定在 f1 中,且是在 f1 中,从小到大排列的第 1.5 亿个数与它后面的一个数的平均值。
对于 f1可以用次高位的二进制继续将文件一分为二,如此划分下去,直到划分后的文件可以被加载到内存中,把数据加载到内存中以后直接排序或使用快排或堆排序(小顶堆) 找出第K大的数,从而找出中位数。
/s/rdz4pfTCeX1ahOM4KAi3oQ
/s/VXGtJ9Miwfc1yD3v44kvnw