详解布隆过滤器(含面试考点)

Bloom Filter

  • 底层逻辑
  • 主要代码实现解析(以C++为例)
  • 优缺点
  • 应用场景
  • 面试常问
    • 问题1:什么是布隆过滤器?
    • 问题2:布隆过滤器如何处理误报?
    • 问题3:如何设计布隆过滤器以最小化误报率?
    • 问题4:布隆过滤器有哪些应用场景?
    • 问题5:布隆过滤器与哈希表有什么区别?
    • 问题6:布隆过滤器在插入元素后,其准确性主要体现在哪些方面?
    • 问题7:布隆过滤器的原理是什么?
    • 问题8:布隆过滤器如何处理哈希碰撞?
    • 问题9:在什么情况下不适合使用布隆过滤器?

底层逻辑

在这里插入图片描述

位数组:布隆过滤器使用一个很长的二进制位数组(bit array)来存储数据。这个数组的每个位置(bit)初始时都被设置为0。

哈希函数:布隆过滤器使用多个哈希函数(通常是k个不同的哈希函数)。每个哈希函数都能将输入的元素映射到位数组的某个位置上。具体来说,每个哈希函数会对元素进行哈希运算,并产生一个哈希值。这个哈希值会被模(取余)运算后,得到一个在位数组范围内的索引,该索引就是元素在位数组中的位置。

插入元素:当需要插入一个元素时,会用这个元素去计算k个哈希值,得到k个索引。然后,将位数组中这k个索引位置上的值都设置为1。

查询元素:当需要查询一个元素是否存在于集合中时,同样会用这个元素去计算k个哈希值,得到k个索引。然后,检查位数组中这k个索引位置上的值是否都为1。如果都为1,则认为该元素可能存在于集合中(注意是“可能”,因为存在哈希冲突的可能性);如果至少有一个为0,则确定该元素不存在于集合中。

主要代码实现解析(以C++为例)

这里提供一个简化的布隆过滤器实现示例:

#include <iostream>
#include <bitset>
#include <functional> // for std::hashclass BloomFilter {
private:std::bitset<1000000> bitArray; // 位数组,假设大小为1000000std::hash<std::string> hashFunction; // 哈希函数对象public:// 插入字符串元素到布隆过滤器中void insert(const std::string& str) {// 计算三次哈希值size_t hash1 = hashFunction(str);size_t hash2 = hashFunction(str + "salt"); // 添加盐增加哈希种子的多样性size_t hash3 = hashFunction(str + "pepper");// 将对应位数组位置设置为1bitArray[hash1 % bitArray.size()] = 1;bitArray[hash2 % bitArray.size()] = 1;bitArray[hash3 % bitArray.size()] = 1;}// 检查布隆过滤器中是否包含字符串元素bool contains(const std::string& str) {// 计算三次哈希值size_t hash1 = hashFunction(str);size_t hash2 = hashFunction(str + "salt");size_t hash3 = hashFunction(str + "pepper");// 检查对应位数组位置是否都为1return bitArray[hash1 % bitArray.size()] &&bitArray[hash2 % bitArray.size()] &&bitArray[hash3 % bitArray.size()];}
};int main() {BloomFilter filter;// 插入一些示例字符串filter.insert("apple");filter.insert("banana");filter.insert("cherry");// 检查某些字符串是否存在于布隆过滤器中std::cout << "Contains apple: " << filter.contains("apple") << std::endl; // 应该返回1 (true)std::cout << "Contains grape: " << filter.contains("grape") << std::endl; // 应该返回0 (false)return 0;
}

优缺点

优点

  1. 空间效率高:相比其他数据结构(如哈希表),布隆过滤器使用位数组来存储数据,因此空间占用非常小。
  2. 查询速度快:布隆过滤器的查询操作只涉及到位运算和哈希计算,因此查询速度非常快,接近O(1)时间复杂度。
  3. 灵活性高:布隆过滤器可以动态地添加元素,而不需要像传统数据结构那样进行扩容或重新哈希。

缺点

  1. 误报率:布隆过滤器存在误报的可能性。当查询一个不存在的元素时,由于哈希冲突的存在,布隆过滤器可能会错误地认为该元素存在于集合中。误报率可以通过调整位数组大小和哈希函数数量来控制,但无法完全消除。
  2. 不支持删除操作:布隆过滤器不支持从集合中删除元素。一旦一个元素被插入到布隆过滤器中,就无法直接删除它。这是因为删除操作可能会影响到其他元素的判断结果。
  3. 哈希函数的选择:哈希函数的选择对布隆过滤器的性能有很大影响。如果哈希函数设计不好,可能会导致误报率过高。因此,在选择哈希函数时需要考虑其均匀性和独立性等特性。

应用场景

布隆过滤器在许多场景下都有广泛的应用,包括但不限于:

  1. 缓存穿透:在缓存系统中,布隆过滤器可以用来判断请求的数据是否存在于缓存中,从而避免直接穿透到数据库层。
  2. 垃圾邮件过滤:布隆过滤器可以用来过滤已知的垃圾邮件地址或内容,减少不必要的邮件处理开销。
  3. Web爬虫:在Web爬虫中,布隆过滤器可以用来记录已经爬取过的URL,避免重复爬取。
  4. 推荐系统:在推荐系统中,布隆过滤器可以用来快速判断用户是否对某个物品感兴趣(基于历史行为数据),从而快速生成推荐列表。

面试常问

问题1:什么是布隆过滤器?

解答:布隆过滤器是一个空间效率极高的概率型数据结构,它利用位数组和哈希函数来判断一个元素是否可能存在于一个集合中。布隆过滤器可以快速地告诉你某个元素很可能不存在于集合中(没有误报),或者某个元素可能存在(有误报)。

问题2:布隆过滤器如何处理误报?

解答:布隆过滤器存在误报的可能性,即它可能会错误地认为某个元素存在于集合中。这是由于哈希冲突和位数组的空间限制导致的。然而,布隆过滤器不会漏报,即它永远不会错误地告诉你某个元素不存在于集合中。如果布隆过滤器返回可能存在,那么你需要使用其他方法(如数据库查询)来确认该元素是否真的存在。

问题3:如何设计布隆过滤器以最小化误报率?

解答:要最小化布隆过滤器的误报率,你可以考虑以下方法:

  1. 增加位数组的大小:位数组越大,误报率越低。但是,这也会增加布隆过滤器的存储空间和计算成本。
  2. 增加哈希函数的数量:使用更多的哈希函数可以进一步降低误报率。但是,这也会增加计算复杂性和时间成本。
  3. 选择合适的哈希函数:哈希函数的选择对布隆过滤器的性能有很大影响。你应该选择那些均匀分布且独立的哈希函数。

问题4:布隆过滤器有哪些应用场景?

解答:布隆过滤器在许多场景下都有广泛的应用,包括但不限于:

  1. 缓存穿透:在缓存系统中,布隆过滤器可以用来判断请求的数据是否存在于缓存中,从而避免直接穿透到数据库层。
  2. 垃圾邮件过滤:布隆过滤器可以用来过滤已知的垃圾邮件地址或内容,减少不必要的邮件处理开销。
  3. Web爬虫:在Web爬虫中,布隆过滤器可以用来记录已经爬取过的URL,避免重复爬取。
  4. 推荐系统:在推荐系统中,布隆过滤器可以用来快速判断用户是否对某个物品感兴趣(基于历史行为数据),从而快速生成推荐列表。

问题5:布隆过滤器与哈希表有什么区别?

解答:布隆过滤器和哈希表在数据结构上有很大的区别。哈希表是一种确定性的数据结构,它使用哈希函数将键映射到桶中,并存储相应的值。哈希表可以准确地告诉你一个键是否存在(没有误报和漏报)。然而,哈希表需要为每个键存储值,因此其空间效率相对较低。布隆过滤器则是一种概率型数据结构,它只使用位数组和哈希函数来判断元素是否存在。布隆过滤器可以快速地告诉你一个元素很可能不存在(没有误报),但可能会误报。由于布隆过滤器不需要存储值,因此其空间效率非常高。

问题6:布隆过滤器在插入元素后,其准确性主要体现在哪些方面?

  1. 正确拒绝(False Negative):如果一个元素从未被添加到布隆过滤器中,并且布隆过滤器正确地判断它不存在,那么这是一个正确的结果(没有误报)。布隆过滤器永远不会错误地报告一个从未被添加的元素存在,即它不会产生假阴性(False Negative)。

  2. 误报(False Positive):然而,布隆过滤器的一个主要限制是可能会产生误报(False Positive)。这意味着布隆过滤器可能会错误地报告一个实际上并未被添加的元素存在。这是由于哈希冲突和位数组的空间限制导致的。当两个或多个不同的元素在多个哈希函数的作用下映射到位数组的相同位置时,这些位置上的位都会被设置为1。因此,当查询一个从未被添加的元素时,如果这些位置上的位都是1,布隆过滤器就会错误地认为该元素存在。

布隆过滤器的误报率取决于几个因素,包括位数组的大小、哈希函数的数量以及添加到过滤器中的元素数量。位数组越大,哈希函数数量越多,误报率就越低。但是,这也会增加布隆过滤器的存储空间和计算成本。因此,在设计布隆过滤器时,需要根据具体的应用场景和需求来权衡这些因素。

需要注意的是,虽然布隆过滤器可能会产生误报,但它通常用于那些可以容忍一定误报率的场景。例如,在缓存穿透、垃圾邮件过滤和Web爬虫等应用中,即使布隆过滤器偶尔会产生误报,也不会对整体应用产生太大的影响。在这些场景中,布隆过滤器的优点(如空间效率高、查询速度快)往往超过了其可能产生的误报率所带来的缺点。

问题7:布隆过滤器的原理是什么?

解答: 布隆过滤器基于位数组和哈希函数。当一个元素被加入到布隆过滤器中时,通过多个哈希函数对该元素进行哈希计算,得到多个哈希值,然后将对应的位数组位置设为1。当需要判断一个元素是否存在于布隆过滤器中时,同样通过多个哈希函数计算该元素的哈希值,并检查对应的位数组位置是否都为1。如果所有位置都为1,则说明该元素可能存在于集合中;如果存在任意一个位置不为1,则说明该元素一定不在集合中。

问题8:布隆过滤器如何处理哈希碰撞?

解答: 布隆过滤器使用多个哈希函数来减少碰撞的可能性。如果发生了哈希碰撞,即两个不同的元素被映射到了相同的位数组位置,那么在检查元素是否存在时,如果有任意一个哈希位置不为1,则该元素被判断为不存在于集合中。

问题9:在什么情况下不适合使用布隆过滤器?

解答: 布隆过滤器适用于需要快速判断一个元素是否属于一个集合的场景,但它不适用于需要精确判断元素是否存在的场景,因为存在一定的误判率。此外,由于布隆过滤器需要消耗额外的空间来存储位数组和哈希函数,因此在内存资源受限的情况下,不适合使用布隆过滤器。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/17624.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Jetpack架构组件_2. 数据绑定库

1.理论基础 数据绑定库是一个支持库&#xff0c;可让您使用声明性格式&#xff08;而不是以程序化方式&#xff09;将布局中的界面组件绑定到应用中的数据源。 布局通常使用调用界面框架方法的代码在 activity 中定义。例如&#xff0c;以下代码会调用 findViewById() 来查找 T…

zabbix自定义监控项

文章目录 1、配置conf文件(zabbix_agent2)linuxwindows 2、配置监控项3、配置触发器4、查看监控数据 示例自定义程序 hash_tool&#xff1a;输出指定目录的哈希值 调用指令&#xff1a; hash_tool --path [指定目录] 1、配置conf文件(zabbix_agent2) linux vim /etc/zabbix/z…

安卓获取内部存储信息

目录 前言获取存储容量 前言 原生系统设置里的存储容量到底是怎么计算的&#xff0c;跟踪源码&#xff0c;涉及到VolumeInfo、StorageManagerVolumeProvider、PrivateStorageInfo、StorageStatsManager......等等&#xff0c;java上层没有办法使用简单的api获取到吗&#xff1f…

深入解析Python中的两种导入方法:from...import与import

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言 二、from...import与import的基本区别 1. 导入方式的不同 2. 命名空间的差异 三…

Linux基础知识点总结!超详细

Linux 的学习对于一个IT工程师的重要性是不言而喻的&#xff0c;学好它是工程师必备修养之一。 Linux 基础 操作系统 操作系统Operating System简称OS&#xff0c;是软件的一部分&#xff0c;它是硬件基础上的第一层软件&#xff0c;是硬件和其它软件沟通的桥梁。 操作系统…

软件项目管理 - 作业集合

软件项目管理 - 作业集合 作业一 1、项目与日常运作的主要区别有哪些&#xff1f; 项目&#xff1a;为提供一项独特产品、服务或成果所做的临时性努力 运作&#xff1a;连续不断周而复始的活动 项目是一次性的&#xff0c;日常运作是重复进行的&#xff1b; 项目是以目标为导…

CI/CD:持续集成/持续部署

1. 安装docker、docker-compose # 安装Docker yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo sed -i sdownload.docker.commirrors.aliyun.com/docker-ce /…

neo4j docker安装使用,py2neo python包使用

参考&#xff1a;https://neo4j.com/docs/operations-manual/current/docker/introduction/ 运行&#xff1a; docker run --publish7474:7474 --publish7687:7687 neo4j查看&#xff1a; http://192***ip:7474 username/password 都是 neo4j/neo4j 简单案例 创建例子&am…

重生之 SpringBoot3 入门保姆级学习(04、 包扫描)

重生之 SpringBoot3 入门保姆级学习&#xff08;04、 包扫描&#xff09; 2.1 包扫描 2.1 包扫描 默认包扫描规则&#xff1a; SpringBootApplication 标注的就是主程序 SpringBoot 只会扫描主程序下面的包 自动的 component-scan 功能 在 SpringBootApplication 添加参数可以…

前端开发工程师——AngularJS

一.表达式和语句 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-w…

创新融合,5G+工业操作系统引领未来工厂

为加速企业完成生产制造自动化和经营管理自动化&#xff0c;从而走向未来工厂&#xff0c;蓝卓不断探索supOS工业操作系统与前沿技术的的创新融合&#xff0c;而5G技术为工业操作系统提供了更多元化的赋能手段和想象空间。目前&#xff0c;supOS围绕生产、安全、质检、监控等领…

语音转文字软件哪个好?掌握这3个方法,告别手写记录

开会多又杂&#xff0c;手写记录累死人&#xff1f; 每天的工作日程中&#xff0c;会议总是不可或缺的一部分。不论是团队讨论还是项目汇报&#xff0c;会议记录都是必不可少的。但手写记录会议内容不仅耗时耗力&#xff0c;还容易遗漏重要信息。 那么&#xff0c;有没有更高…

张驰咨询:六西格玛培训,IT界的“福尔摩斯”

六西格玛&#xff0c;这个曾以制造业为背景的管理理念&#xff0c;如今却在IT领域大放异彩。其背后的原因&#xff0c;不仅仅是因为六西格玛追求零缺陷、持续改进的核心价值观与IT行业对产品质量和用户体验的极致追求不谋而合&#xff0c;更是因为它提供了一种全新的思维方式和…

C语言作为计算机行业的基础之一,是否制约了行业本身的发展?

c不是计算机行业的基础啦&#xff0c;你想&#xff0c;c语言出现时已经有一套成熟的计算机体系&#xff0c;有基于内存地址的寻找指令、数据的工作方式&#xff0c;有汇编语言&#xff0c;那搞出c这种高级语言就很正常啊&#xff01;刚好我有一些资料&#xff0c;是我根据网友给…

西安航空学院电子工程学院领导莅临泰迪智能科技参观交流

5月26日&#xff0c;西安航空学院电子工程学院院长杨亚萍、专业教师刘坤莅临广东泰迪智能科技股份有限公司产教融合实训基地参观交流。泰迪智能科技董事长张良均、副总经理施兴、产品中心负责周东平、校企合作经理吴桂锋与泰迪智能科技韩伟进行热情了接待。双方就专业建设、协同…

Alamofire常见GET/POST等请求方式的使用,响应直接为json

Alamofire 官方仓库地址&#xff1a;https://github.com/Alamofire/Alamofire xcode中安装和使用&#xff1a;swift网络库Alamofire的安装及简单使用&#xff0c;苹果开发必备-CSDN博客 Alamofire是一个基于Swift语言开发的优秀网络请求库。它封装了底层的网络请求工作&…

正邦科技(day1)

1&#xff1a;充电桩工作了两个半小时&#xff0c;已用电量13度电&#xff08;一般的话是一个小时7度电&#xff09; 2&#xff1a;火线&#xff08;红色&#xff0c;棕色&#xff09;&#xff0c;零线&#xff08;蓝色&#xff09; 3&#xff1a;充电桩工作了两个半小时&#…

【ARM+Codesys案例】RK3568 +Codesys 软PLC方案在电镀生产线的应用

1 电镀生产简介 电镀是一种比较重要的工艺&#xff0c;产品经过电镀工艺处理后&#xff0c;不仅产品质量获得提高&#xff0c;产品性能也会大幅度提高&#xff0c;同时延长了产品的使用时间。电镀生产线是指按一定的电镀生产工艺要求,将有关的各种电镀处理槽、电镀行车运动装置…

STM32_USART

1、USART简介 USART&#xff0c;即Universal Synchronous/Asynchronous Receiver/Transmitter&#xff0c;通用同步/异步收发器。USART是STM32内部集成的硬件外设&#xff0c;可根据数据寄存器的一个字节数据自动生成数据帧时序&#xff0c;从TX引脚发送出去&#xff0c;也可自…

香橙派 AIpro开发板开箱测评(代码开源)

前言&#xff1a;有幸能够收到一块梦寐以求的 AI 边缘计算开发板 OrangePi AIpro&#xff0c;非常感谢官方大大给予的宝贵机会。OrangePi AIpro是香橙派官方跟华为昇腾合作的新一代边缘计算产品&#xff0c;其使用华为昇腾 AI 技术路线&#xff0c;搭配集成图像处理器&#xff…