这类问题一般都是上亿条数据,内存几个GB或者几十MB的限制,先说一个空间大小转换:我们建立哈希表<key,value>
;,若key可以覆盖Int32所有范围,即32 unsigned int: 0~4294967295,key
需要4B,value
也需要4B,则一条记录8B,当记录数为2亿条,至少需要1.6GB(注意1000要除1024)。
布隆过滤器
题目:假设有100亿个URL的黑名单,每个URL最多占用64B,设计一个过滤系统,判断某条URL是否在黑名单里。要求:不高于万分之一的判断失误率;额外内存不超过30GB
100亿个64B的URL需要640GB的内存,显然直接存哈希表不合理。考虑布隆过滤器,假设有一个长度为m的bit类型数组,如图所示:
输入阶段:
有k个哈希函数,函数的输出域S大于或等于m,假设哈希函数彼此独立,对于同一个输入(以字符串表示的URL),经过k个哈希函数的计算结果也是相互独立。对计算的每一个结果Mod m,将bit array
上对应的位置置1,如下:
一个输入对象会将bitmap某些位置涂黑,处理完所有输入对象,会将bitmap相当多位置涂黑,至此,布隆过滤器生成完毕,代表之前所有输入对象的集合。
检测阶段:
假设有一条新的URL a,把a输入k个哈希函数计算k个输出,Mod m,得到[0,m-1]
的k个值,比较bitmap在这k个位置是否为黑,有一个不为黑,说明a不在这个集合里;若都为黑,说明a在这个集合,但可能有误判。产生误判的情况:a不是输入对象,但是生成的布隆过滤器因为输入对象过多,而bitmap过小,导致bitmap绝大部分都已经变黑,那么在输入a时,可能a对于的k个位置也是黑的。
失误率分析:
n=100亿,p=0.01%,布隆过滤器的大小由以下确定: