开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第N天,点击查看活动详情 🌿 3.3 布隆过滤器优点 增加和查询元素的时间复杂度为:O(K), (K为哈希函数的个数,一般比较小),与数据量大小无关 哈希函数相互之间没有关系,方便硬件并行运算 布隆过滤器不需要存储元素本身,在某些对保密要求比较严格的场合有很大优势 在能够承受一定的误判时,布隆过滤器比其他数据结构有这很大的空间优势 数据量很大时,布隆过滤器可以表示全集,其他数据结构不能 使用同一组散列函数的布隆过滤器可以进行交、并、差运算 🌿 3.4 布隆过滤器缺陷 有误判率,即存在假阳性(False Position),即不能准确判断元素是否在集合中(补救方法:再建立一个白名单,存储可能会误判的数据) 不能获取元素本身 一般情况下不能从布隆过滤器中删除元素 如果采用计数方式删除,可能会存在计数回绕问题 🌿 3.5 布隆过滤器模拟实现 //布隆过滤器实际上是对位图的改进,所以实现上也是对位图的封装,一般只提供set和test接口,不能实现reset(删除) template<size_t N, class K = std::string,class Hash1 = HashBKDR,class Hash2 = HashAP,class Hash3 = HashDJB> //后面几个是字符串哈希函数的仿函数 class BloomFilter { };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 🍃 4. 海量数据面试题 🌿 4.1 位图应用 题目一 给两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件交集?
思路:100亿的整数范围还是42亿,因此用一个位图来存储只需要512M 将一个文件映射到位图中,再依次读取另一个文件的数据,看在不在位图中,在就是交集;或者构建两个位图,求他们的交集;
题目二 给定100亿个整数,设计算法找到只出现一次的整数?
思路:用位图的思想,一个bit位能表示两种状态,这里至少是3种状态,因此需要两个bit位00表示没出现;01表示只出现一次;10表示出现过2次及以上;将所有数插入位图中,然后遍历位图,找出标志位01的位即为所求
🌿 4.2 哈希切分+布隆过滤器应用 哈希切分的原理:就是将一个大文件,利用哈希的原理(i = Hash()(ip) % 100, i表示小文件的编号),将其分为若干个小文件。
哈希切割的特点:相同的ip一定进入了同一个小文件当中。
题目三 给两个文件,分别有100亿个query,我们只有1G内存,如何找到两个文件交集?分别给出精确算法和近似算法
近似算法:利用布隆过滤器100亿个query(ip),可以看做string,假设为100G,那么两个文件一共是200G。将A文件依次映射到一个布隆过滤器中,再依次读取B文件中的数据,与布隆过滤器里的内容比较,在就是交集,但是会有一定的误判率。 精确算法:利用哈希切分 + 布隆过滤器 可以将AB文件都切割成200个小文件(哈希切分并不是均匀的,依次要保证小文件小于内存大小),按照同样的映射函数 i = Hash()(ip) % 200 这样AB中相同的ip,都进了各自对应的编号i的小文件,因此只需要依次比较Ai和Bi中的交集即可
题目四 给一个超过100G大小的log file, log中存着IP地址, 设计算法找到出现次数最多的IP地址?
与上题条件相同,如何找到top K的IP?如何直接用Linux系统命令实现?
思路:哈希切分,切分成100个小文件(相同的ip一定进入了同一个小文件)然后只需统计各个小文件各个ip的频次(比如用一个map<string, int>统计),找出每个小文件频次最高的ip地址进行比较即可;要求 top K的ip,可以建一个K个元素小堆,后面的元素依次与堆顶元素比较,比它大就替换进堆,最终这个小堆就是top K ;