大数据——面试题总结(1)

来源:互联网 发布:js div跟随滚动条滑动 编辑:程序博客网 时间:2024/06/06 00:23
1、给出一个超过100G的log file,log中存着ip地址,设计算法找到出现次数最多的ip地址?
分析:
  由于文件超过100G,所以我们必须先对文件进行切分,然后再利用数据结构的知识求解。关键是如何切分效率最高???

解决方法:
  我们可以使用哈希切分,将同一个ip都分割到同一个文件中,注意同一个ip经过同一个散列函数 一定会进入到同一个文件中,然后再统计每一个文件中出现最多的ip的次数,最后再将这些结果放到一起再经过比较就能得出结果。

问题:
  最极端的情况是经过哈希切分后有一个ip出现次数特别多,切分后存放这个ip的文件还是太大加载不到内存中,这时候应该怎么办呢???
  这时候可以将这个文件再切分(普通的切分)成若干个小文件,将每一个文件加载到内存中使用hash表求出ip出现的次数,最后再将这些小文件的结果汇总后在求出出现次数最多的ip。


2、与上题条件相同,如何找到top K的ip?
  与第1题一样,我们统计出每个文件中每个ip出现的次数然后再利用最小堆分别求出每个文件中出现次数最多的前k个ip,最后再将这些文件的结果汇总到一起再利用最小堆求出出现次数最多的前K个ip。

3、给定100亿个整数,设计算法找到只出现一次的整数?
分析:100亿个整形大约需要40G才能存下,一次性读入到内存中是不现实的。

方法1:切分文件+数据结构
  把这100亿个整数分成100份,这样算下来平均每份大约占400M左右。再把每一份加载到内存中,使用哈希表进行查找只出现一次的数,最后再将这100份的结果汇总到一起再进行查找。

方法2:bitmap
  对于这个题,需要对位图做一点扩展,因为这些数有可能出现0次、1次、多次,只用一个bit位是无法表示的,所以我们需要用两个bit位来表示一个整数的存在状态即:00表示没出现,01表示只出现1次,10(或11)表示出现多次。
  因为整型大约能表示42亿9千万个数,至少要16G才能存下这些数字,如果换成两个bit位表示的话只需要1G的内存就足够了。因为这些整数有可能有负数,所以我们可以将负数映射到位图的后半部分,也就是将这些负数当做无符号的数看待。
bitmap:  http://blog.csdn.net/lf_2016/article/details/53081447

方法3:
   整数有32位,我们先按最高位0和1将这些数据划分成两个数据,然后拿要查找的数的最高位比较看要去哪个文件中找,一次类推,直到划分到最低位。这样的话最多进行32次划分就能判断出这个数在不在这100亿个整数里面。


4、给定两个文件,分别有100亿个整数,只提供1G内存,如何找出两文件交集?
分析:100亿个整形大约需要40G才能存下,一次性读入到内存中是不现实的。

方法1:
   把一个文件切分成100份,分别把每一份加载到内存中,然后用第二个文件中的数据到每一份中都进行查找。这种方法的时间复杂度是O(N^2)。

方法2:哈希切分
   先对一个文件进行切分,不过这次切分的时候使用一个散列函数,将相同的数都分割到一个文件中去,注意相同的数一定会进入同一个文件,并给这些文件进行编号。再对第二个文件中的数据也使用这个散列函数,并给切分后的文件也进行编号。最后,如果两个文件有交集的话,一定会在编号相同的文件中产生交集,这时候只需要把他们编号相同的文件进行比较即可。这种方法的时间复杂度是O(N).

方法3:bitmap
   将一个文件中的数据映射到位图中(大约需要500M),然后再用第二个文件中的数据到位图中去寻找。这种方法的时间复杂度是O(N)。
bitmap:  http://blog.csdn.net/lf_2016/article/details/53081447


5、给定两个文件,分别有100亿个query,我们只有1G内存,如何找到两个文件的交集?分别给出精确算法和近似算法?

精确算法:哈希切分
   如果要得到精确的结果的话,我们可以使用哈希切分,第四题的方法2是一样的,不过在这个题中要将query转换成一个整形,然后再经过散列函数映射到文件中去。

近似算法:bloomfilter(布隆过滤器)
   如果要得到近似结果的话可以使用布隆过滤器,将其中一个文件的内容映射到位图中,然后再用另一个文件中的内容到这个位图中寻找。
BloomFilter:    http://blog.csdn.net/lf_2016/article/details/53081858

6、如何扩展BloomFilter使得它支持删除操作?如何扩展BloomFilter使得它支持计数操作?
要支持删除操作,就要用到引用计数的方法。不用一个bit位表示一个数据,该用size_t表示一个数。
BloomFilter:    http://blog.csdn.net/lf_2016/article/details/53081858

7、5亿个整数找它们的中位数,只有1G内存。   
   5亿个整数大约需要2G的内存才能表示的下。我们可以先对整数划分若干个区间,然后每个区间都建立一个小文件,再遍历这个大文件,将里面的数按照大小放到相应的小文件中,最后我们只要统计出每个文件中整数的个数,就可以计算出中位数的位置。

8、有一个词典,包含N个英文单词,现在任意给一个字符串,设计算法找出包含这个字符串的所有英文单词?

方法:字典树
  首先把这N个英文单词建立一颗字典树,然后再用给定的字符串到字典树中去找,如果找到就是存在的,找不到就是不存在的。但是如果字典树的深度比较深的话是比较耗费内存的,这时候我们可以使用"字典树+hash表"的方式解决,例如:我们将字典树第10层以后的数据存放到hash表里面。

总结:
  对于大数据问题,一般都采取分而治之的方法,即:对数据进行分割,之后再利用数据结构的知识求解。可以说这种方法是能够解决绝大多数大数据问题的,但是重点是我怎么划分,有时候如果划分合理的话,就能够极大的提高解决问题的效率。
  此外针对某些大数据问题还有其它更优的解决办法,比如bitmap、bloomfilter、Trie树等,所以针对具体问题我们要具体分析,看哪一种方法更优。
  针对大数据问题百试不爽的方法就是:切分+数据结构。
2 0
原创粉丝点击