布隆过滤器

问题假设

在讲布隆过滤器之前,我们先设想这样的一个问题,目前有100亿个网络黑名单URL,假设一个URL是64字节,设计一种方法,该方法使得用户访问这些网址时,给予警告信息。

注:该方法可以实现加入URL,查询URL,但是没有删除URL的功能

想法一

用HashSet,将所有的这些URL根据哈希函数算出的哈希值得知对应放进HashSet的位置,用户在访问的时候查找哈希表即可。

分析

因为一个URL占有64字节,那么100亿就是6400亿字节,因为10亿字节约等于1G,故需要640G的内存空间。这是十分吓人的。

对应思考

由于所用的内存空间实在是过于巨大,那么有没有其他可以节省空间的做法呢?如果允许一定的失误率的?

想法二

我们观察到,一个4字节的空间就占有32位,一个8字节的空间就占有64位,这是极大的利用空间,如果我们可以基于位运算,就会方便不少。布隆过滤器就是这样,在讲具体的方法之前,我们先回顾一下有关位运算的一些操作。

位运算回顾
    public static void main(String[] args) {
        //a 是 32bit
        int a = 0;
        int[] arr = new int[10];//320bit
        //arr[0] int 为0 ~ 31位位置
        //arr[1] int 为32 ~ 63位位置
        //arr[2] int 为64 ~ 95位位置

        int i = 178;//i表示想取到的178个bit的状态

        int numIndex = 178 / 32;//定位到178位在那一个arr[?]中
        int bitIndex = 178 % 32;//定位到在arr[?]的具体那一个位置上

        //拿到178位的状态
        int s = ((arr[numIndex] >> (bitIndex)) & 1);

        //把178位的状态改成1
        arr[numIndex] = arr[numIndex] | (1 << (bitIndex));

        //把178位的状态改成0
        arr[numIndex] = arr[numIndex] & (~(1 << bitIndex));

        //整体来讲
        i = 178;
        int bit = (arr[i / 32] >> (i % 32)) & 1;
    }
布隆过滤器讲解

在回顾完位运算之后,那么我们就开始讲解布隆过滤器。布隆过滤器就是一个大的位图。是一个长度为m的bite类型的数组。实际占用m / 8的字节数(内存)。

加入黑名单URL1的步骤
  1. 将黑名单URL1经过哈希函数f1(x)得到一个哈希值out1,对out1%m得到在具体哪一位上
  2. 将对应位标黑
  3. 再将URL1经过哈希函数f2(x)得到一个哈希值out2,对out2%m得到在具体哪一位上
  4. 将对应位标黑
  5. 再将URL1经过哈希函数fk(x)得到一个哈希值outk,对outk%m得到在具体哪一位上(一共经历了K个哈希函数)
  6. 将对应位标黑
  7. 至此URL1加入完毕

对100亿个黑名单URL都进行上面的步骤,将得到很多位标黑的一个m位位图

image.png

查询某个URL是不是黑名单中的URL
  1. 调用k个哈希函数得到k个哈希值,%m得到k个位置
  2. 在位图中拿状态,只要有一个位置不是1(标黑),就是白名单,全是1就认为是黑名单中的URL

注:黑名单 --> 白名单 不会发生。但是,白名单 --> 黑名单 可能会发生,原因就是m可能很小,或者k很小或者k很大,都会造成相应的失误率。也就是说,布隆过滤器会有一定的失误率。

参数的确定

上面介绍了参数的选择会影响相应的失误率,那么该怎样确定参数呢?

当n固定,m过小的时候,不同的URL标黑的位置可能会出现重合,造成误判。m变大会使误判变小,但是随着m的增大误判率减小的趋势会越来越缓慢。

image.png

当n、m固定,k过小的时候,由于没有足够的采集信息点,所以导致不同的URL标黑的位置可能会出现重合,造成误判。k过大的时候,由于过多的采集信息,相当于m变小了,也会造成误判。

image.png

鉴于上面的情况,大神家们总结出了相应的公式:

image.png

上面的图片中可以加上一项,就是询问面试官可不可以扩充空间,可以的话,最大是多少。这样得到了新m,将新m和第二个公式算出来的k结合算出最小的失误率。

相关建议

遇到类似黑名单的问题,明显特征是大数据、只加入数据和查询数据,但是不删除数据的类似问题。询问面试官允许有失误率吗?这样一看你就是会的。

到最后根据面试官给出的失误率算出来自己的m大小,问可不可以扩充空间,可以的话,最大是多少。这样得到了新m,将新m和第二个公式算出来的k结合算出最小的失误率。完美解决。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值