海量数据处理问题的解题关键
1.海量日志数据,提取出某日访问百度次数最多的那个IP.
访问百度的日志中取出IP,逐个写入一个大文件中,采用映射的方法,比如说模1000,将大文件映射成1000个小文件,再找出每个小文件中出现频率最大的IP,以及相应的频率(构建IP为key,出现频率为value的Hash Map)。然后在这1000个最大的IP,然后找出频率最大的IP(通过内排序算法)。
2.搜索引擎会通过日志文件把用户每次检索使用的所有检索串都记录下来,每个查询串的长度为1-255个字节,假设目前有1000W个记录(其中有大量的重复,去重后大约还剩300W个, 一个查询的重复度越高,该记录越热门),请统计当前最热门的10个查询串,要求使用内存不能超过1G.
Top K算法:
1.对这些海量数据进行批处理,在O(n)的时间内使用hash表完成统计()。
2.借助于堆,找出Top K,时间复杂度为N LogK (此时N为300W)。
3.有一个1G大小的文件,里面的每一行是一个词,词的大小不超过16个字节,内存限制大小事1M,返回频度最高的100个词。
顺序读取文件,对于每个词x,取hash(x)%5000存到500个小文件当中,每个小文件大概是200K左右(若其中有的文件超贵过1M,则继续往下分),
对于每个小文件,采用hash_map或者trie统计每个文件中每个出现的词以及出现的频率,选取频率最大的100个词(用含100个节点的最小堆),并把这100个词以及频率存入一个新的文件,这样就又有5000个文件,下一步吧500个文件进行归并排序。(内外排序相结合)
4.有10个文件,每个文件1G,每个文件的每一行存放的使用户的query,每个文件的query可能重复,按照query的频度排序
TOP K算法
1.去重:顺序读取10个文件,按照hash(query)%10的结果将query写入另外10个文件中,这样每个文件的大小也约为1G.
2.找一台内存2G的机器,依次对hash_map(query,query_count),来统计每个query出现的次数,对每个文件中的词频进行排序,(可以采用快排,堆排,归并进行排序),得到10个排好序的文件。
对10个文件进行归并排序。
5.给定a、b两个文件各存放50亿个url,每个url各占64个字节,内存限制4G,找出ab中相同的url.
如果允许一定的错误率,可以使用Bloom filter,4G内存为340亿个bit,将其中一个文件的url映射为这340亿个bit ,然后读取另一个文件的url,检查是否与Bloom filter ,
6.在2.5万亿个整数中找出不重复的整数
进行划分小文件,在小文件中找出不重复的整数,进行排序,然后再归并
或者采用2-bitmap,共需内存2 ^32*2bit = 1G,扫描这2.5亿个整数,查看其对应的bit位
7.腾讯面试题:给40万亿个不重复的unsigned int 的整数,没排过序的,再给一个数,如何快速判断这个数是否在那40亿个数当中。
将这40亿个数个两类:最高位为0和最高位1,并分别写到两个文件中
找到对应的文件,再对该文件内的数字按次高位分类
…..
以此类推即可找到,时间复杂度为O(logn)
或者采用位图的方法,时间复杂度为O(n)
8.在海量数据中找出重复数字最多的一个
先做hash,然后求模映射为小文件,求每个小文件中重复次数最多的,并记录频率,然后排序找出频度最 大的。
9.成千上万或亿,统计其中出现次数最多的前N个数据。
10.一个文本文件,大约有一万行,每行一个单词,要求统计出其中最频繁出现的前10个词,请给出思想,分析时间复杂度。
用trie树统计出每个词出现的次数,时间复杂度是O(n*le)——le是单词的平均长度,找出出现最频繁的10个词, 用堆来实现,时间复*杂度是O(n*log10)
所以算法的时间复杂度是两者之间较大的一个。
11.在包含20亿个32位整数的⽂文件中,找到出现次数最多的数,内存限制2G,请提出解决方法:
解答:1,了解哈希函数(散列函数)的概念和基本功能
2,对于哈希表一条记录占用多少空间有准确的估计
3,根据步骤2的估计,将大文件哈希成若干个小文件,然后求出每个小文件的No.1
4,比较各个No.1,找出最多的那个
12.由若干服务器组成的集群一起提供服务,共同承担访问压力,请设计集群的增减策略,使得当集群增加或减少机器时,数据移动的代价尽量小。
解答:负载均衡,采用一致性哈希算法。
在设计分布式系统的时候,我们需要让key的分布均衡,并且在增加 server后,数据的迁移做到最少。
常规的方式比如hash取模的方式,以hash(K) mod N的算法来操作对应的机器,这种结构简单实用,但是在一些高速发展的web系统中,这样的解决方案存在着巨大的缺陷。比如其中一台服务器挂了,或者需要增加一台服务的时候,大量的缓存命不中,缓存数据需要重新建立,甚至是进行整体的缓存数据迁移,瞬间会给DB带来极高的系统负载,甚至导致DB服务器宕机。
使用一致性hash算法能够当一个节点失效的时候,其他节点的数据不会受到破坏,这个节点的数据会被分流到另外一个节点。当增加一个节点时,只会对一个节点的一分部数据有影响,能够满足大型集群架构的要求。
方法一:
先将每个ip地址转化为无符号整型数,然后将整数排序后转回ip地址
方法二:使用bitmap,申请长度为2^32的bit类型的数组,数组中每个位置是一个bit,记为bitamp,如果整数i出现就将相应位置上的bit置为1.将10亿个ip地址整数对应的bit位置1,最后从头到尾扫描,转化为对应的ip地址即可。
使用hashmap对所有出现的数进行词频统计,hash表的key为整型,,表示具体某一种数,value表示某个数出现的次数,但是这样会导致内存不足
将大文件通过hash函数分流为小文件,同一种数不会被分流到不同的小文件,小文件各自得到其中出现频率最高的数,再找到全部出现次数最高的
1.Bloom filter
适用范围:实现数据字典,进行判重或者求集合的交集。
基本原理: 位数组+k个独立的hash函数,将hash函数对对应值的位数组 置1,查找时如果发现所有hash函数对应的位都是1,则说明存在。
2.Hashing
适用范围:快速查找,删除的基本数据结构,通常总数 据量可以放入内存。
基本原理:
hsah函数的选择:
碰撞处理:拉链法,开放地址法
3.bit-map
适用范围:可进行数据的快速查找,判重,删除(一般来说数据范围是int的10倍以下)
基本原理:
4.堆
使用范围:找出海量数据的前k个数,并且数据总量n比较小,堆可以放入内存。
基本原理:最大堆求前n小,最小堆求前n大,
5.trie树
适用范围:数据量大,重复多,但是数据中类小,可以放入内存