当前位置: 首页 > article >正文

布隆过滤器和布谷鸟过滤器

布隆过滤器

布隆鸟过滤器(Bloom Filter)是一中数据结构,由一个bit数组和多个hash函数构成,可以用于快速判断某个元素是否在某个集合里面。相比于传统的哈希表,更加节省空间,但存在一定的误报率(false positives),即可能会错误地报告一个元素存在于集合中,但实际上并不存在。

在这里插入图片描述

布隆过滤器的基本原理

  1. 初始化
    • 布隆过滤器由一个很长的二进制bit数组和 k 个独立的哈希函数组成。
    • 位数组初始化时所有位都是0。
  2. 插入操作
    • 当一个元素被加入到布隆过滤器时,它会通过多个不同的哈希函数进行哈希。
    • 每个哈希函数会产生一个索引位置,该位置在位数组中对应的位会被设置为1。
  3. 查询操作
    • 查询一个元素是否存在时,同样使用k个哈希函数计算出位数组中的索引位置。
    • 如果所有这些位置上的值都为1,则认为该元素可能存在于集合中;否则确定该元素不在集合中

优点

  • 因为只存储0或1,在只需要判定元素是否存在的情况下,极大地节省存储空间
  • 插入和查询的时间复杂度接近O(1),非常高效。

缺点

  • 无法删除元素(因为直接把某个元素的key都置为零会影响到其它元素),只能增加或者查询元素
  • 只能准确判断元素不存在,若判定某个元素存在集合中,有误判的可能(可通过添加多个hash函数来解决),不容许误判的场合不适用
  • 只是判断元素是否存在,没有进行冲突处理

应用场景

布隆过滤器适用于对存储空间敏感且可以接受一定误报率的场景,例如:

  • 解决缓存穿透问题,比如查询redis前先经过布隆过滤器,那些不存在于MySQL的数据就会被提前过滤掉
  • 网络爬虫中过滤已访问的网页URL。
  • 数据库系统中快速判断一个键是否存在于大型数据集中。
  • 内存缓存系统中检查数据是否已被缓存。
  • 黑名单或白名单的实现。

由于布隆过滤器的这些特性,它在大数据处理、数据库优化以及网络应用中都有广泛的应用。

如何降低误判率?

增加hash函数个数

如何实现过滤?

被布隆过滤器判定为不存在集合中的元素可以直接排除掉(实现过滤),当然,被布隆过滤器判定存在时,只是可能存在,需要要做进一步判定,这就是过滤的意义,把绝大多数不存在的情况先排除掉,剩下的小部分情况做特殊操作。

面试问到布隆鸟过滤器是什么怎么回答?

布隆鸟过滤器是一个数据结构,由一个bit数组和多个hash函数构成,可以用于快速判断某个元素是否在某个集合里面。它的基本工作原理是:当添加一个元素到集合里的时,依次通过各个hash函数去计算对应的hash值,每个hash值对应bit数组的一个位置,让对应位置的都置为1。然后要判断某个元素是否在集合里面时,只需要依次判断对应hash值的位置的值是否全为1即可,如果不是全为1则说明不在集合里,如果全为1则说明在集合里(当然全1的情况可能存在误判)。

布谷鸟过滤器

布谷鸟也就是纠缠雀巢中的“鸠”,习惯于把蛋下在别人的鸟窝,然后占领别人的地盘。

布隆过滤有一个很严重的问题就是无法删除元素,这样会导致误判率越来越高。

布谷鸟过滤器有2个hash函数,插入时是让hash值对应位置存入数据的指纹信息,而不是像布隆过滤器一样存入0或1,如果所有hash值对应位置已经有指纹信息,则换下一个,全都有则随机踢走一个,然后给踢走的元素重新找一个位置。

数据结构

在这里插入图片描述
注:布谷鸟过滤器里面存储的不是0和1,而是原数据的指纹信息,放在桶里面,空间占用非常小。

如何添加数据?

依次往两个位置尝试添加

在这里插入图片描述

都不行则随机抢占一个位置,然后让被抢占的元素重新找位置

在这里插入图片描述

注意:只有第一个hash计算时需要用到原数据x;计算后续hash值的时候不需要对原数据x做hash,只需要对其指纹做hash然后和上一个hash做异或即可

如何判断某个元素在不在集合里面?

只需要查找两个hash位置对应的桶里有没有元素的指纹即可,

在这里插入图片描述

删除过程

在这里插入图片描述

如何降低误判率?

增加hash函数个数;进行分块;扩容

优点:

  • 查找、插入速度快,空间占用率低
  • 支持删除元素

缺点:

  • 实现相对复杂。

  • 因为指纹信息也可能重复,也有误判的情况,把不存在的判定为存在了;另外,还有误删除(删除一个不存在的元素时把真实存在的元素删除了)的可能

  • 插入性能可能会随着冲突的增加而显著下降,因为需要重新定位现有元素


http://www.kler.cn/a/291688.html

相关文章:

  • go面试问题
  • 全脐点曲面当且仅当平面或者球面的一部分
  • 数据结构_平衡二叉树
  • SQL Server 解决游标性能问题的替代方案
  • Java性能测试Benchmark使用总结
  • 机动车油耗计算API集成指南
  • 设计模式 | 单例模式
  • 修改jupyter notebook 默认浏览器(不动配置文件,改系统默认浏览器)
  • Python基础语法(17多线程线程锁单例模式)
  • JS中【普通函数中的this】vs【箭头函数中的this】
  • 【Python控制台小游戏】剑与魔法
  • P3631 [APIO2011] 方格染色
  • 深度学习速通系列:Bert模型vs大型语言模型(LLM)
  • 【前端面试】采用react前后,浏览器-解析渲染UI的变化
  • 解决jupyter notebook启动需要密码的问题
  • Zabbix_Proxy自动化安装脚本
  • 五分钟搭建微信机器人保姆级教程
  • SSG页面加上了 revalidate,是不是就变成了 ISG?
  • WebRTC协议下的视频汇聚融合技术:EasyCVR视频技术构建高效视频交互体验
  • python-Flask搭建简易登录界面
  • Java 7.3 - 分布式 id
  • linux——进程
  • v$session_longops监控 PDB clone 进度
  • Elasticsearch在高并发下如何保证读写一致性
  • Git创建项目
  • 一款云笔记支持在线协同文档,脑图,白板演示的工具,多个设备同步,让灵感与你同行(附源码)