布隆过滤器:基于哈希函数的原理、应用解析

文章目录

  • 一、引言
    • 1、布隆过滤器的概念简介
    • 2、布隆过滤器是基于哈希函数的强大工具
  • 二、布隆过滤器基础知识
    • 1、布隆过滤器的工作原理
    • 2、布隆过滤器的空间效率分析
    • 3、布隆过滤器的性能特点
  • 三、布隆过滤器的应用场景
    • 1、数据库查询优化
    • 2、例子
  • 四、布隆过滤器的实现与优化
    • 1、常见的布隆过滤器库
    • 2、自定义布隆过滤器的实现步骤
    • 3、降低误报率的策略

一、引言

1、布隆过滤器的概念简介

**布隆过滤器(Bloom Filter)**是一种空间效率极高的概率型数据结构,它利用位图和哈希函数来快速判断一个元素是否属于某个集合。布隆过滤器不是传统意义上的过滤器,它不能完整地存储数据,而是以一种紧凑的方式表示数据可能存在的集合。

2、布隆过滤器是基于哈希函数的强大工具

布隆过滤器的核心机制是基于哈希函数的映射和位图将哈希与位图结合。哈希函数能够将输入数据均匀地映射到一个固定大小的范围内,而位图则提供了一种紧凑的数据表示方式。在布隆过滤器中,多个哈希函数被用于将数据映射到位图的不同位置上,并设置相应的位为1来表示数据可能存在。在查询时,只需通过同样的哈希函数计算并检查位图中对应位置的值即可判断数据是否存在。这种基于哈希函数的映射方式不仅实现了空间的高效利用,还保证了查询的快速性。


二、布隆过滤器基础知识

1、布隆过滤器的工作原理

  • 位图与哈希函数的结合

布隆过滤器主要由两部分组成:一个很长的二进制向量(即位图)和一系列随机映射函数(即哈希函数)。二进制向量中的每一位初始时都设置为0。当添加一个新元素时,该元素会经过k个哈希函数的计算,得到k个哈希值。这k个哈希值对应到位图中的k个位置,并将这些位置上的值设置为1。因此,布隆过滤器利用位图和哈希函数的结合,实现了对元素的添加操作。

下图中假设 x,y,z 通过三个不同的哈希函数映射在不同的位置上,集合元素x、y、z分别被映射到位图的某些位置,并且这些位置被标记为1。这表明这些位置在布隆过滤器中已经被设置为1,表示这些元素可能存在于集合中。

在这里插入图片描述

元素w不在集合{x, y, z}中,因为它哈希到了一个包含0的位图位置。

哈希函数的选择对布隆过滤器的性能至关重要。好的哈希函数应该具有均匀性、一致性和冲突最小化等特点,以确保布隆过滤器的误报率尽可能低。同时,哈希函数的计算速度也直接影响到布隆过滤器的查询性能。因此,在实际应用中,需要根据具体场景选择合适的哈希函数来构建高效的布隆过滤器。

  • 元素添加与查询过程

添加元素到布隆过滤器中的过程相对简单。首先,将要添加的元素通过k个哈希函数进行计算,得到k个哈希值。然后,根据这些哈希值在位图中找到对应的k个位置,并将这些位置上的值设置为1。如果某些位置上的值已经是1,则不需要进行任何操作。

由于哈希函数的特性,布隆过滤器在处理数据时具有一定的概率性。这意味着它可能会存在误报(false positive)的情况,即判断某个元素属于集合但实际上并不属于。然而,通过合理选择哈希函数和调整位图的大小,可以降低误报率,使得布隆过滤器在实际应用中仍然具有非常高的实用价值。

在这里插入图片描述

{ A,B,C }通过哈希函数映射在不同的位置。此时我们查找元素 X,通过哈希函数得到的三个下标上的元素均为1,但是元素 X 不存在于集合中。

查询一个元素是否存在于布隆过滤器中的过程也相对直接。同样地,将要查询的元素通过k个哈希函数进行计算,得到k个哈希值。然后,检查这些哈希值对应到位图上的位置,如果所有位置上的值都是1,则认为该元素可能存在于集合中。然而,需要注意的是,由于哈希冲突的存在,即使所有位置上的值都是1,也不能确定该元素一定存在于集合中,因此布隆过滤器的查询结果具有概率性。

  • 误报率(False Positive Rate)的解释

误报率表示的是当一个元素查询结果为存在时,但实际上该元素并不存在的概率。由于布隆过滤器是通过哈希函数将元素映射到位图上的,因此存在哈希冲突的可能性。当两个不同的元素经过哈希函数计算后得到相同的哈希值时,就会发生哈希冲突。在这种情况下,如果一个元素被错误地标记为存在(即其对应的位图位置上的值为1),就会导致误报。误报率与布隆过滤器的位图大小、哈希函数的个数以及集合中元素的个数有关。通常情况下,通过增加位图的大小和哈希函数的个数,可以降低误报率,但也会增加空间和时间开销。

⚠️总结来说,布隆过滤器通过位图和哈希函数的结合,实现了高效的元素添加和查询操作。然而,由于其基于哈希函数的特性,布隆过滤器的查询结果具有概率性,存在误报的可能性。因此,在使用布隆过滤器,要注意:布隆过滤器如果说某个元素不存在时,该元素一定不存在,如果该元素存在时,该元素可能存在,因为有些哈希函数存在一定的误判。

  • 删除布隆过滤器中的元素

布隆过滤器的一个主要限制是它不支持删除操作。这是因为布隆过滤器是基于位图和哈希函数实现的,当一个元素被添加到过滤器中时,它会被哈希到多个位上并将这些位设置为1。然而,当尝试删除一个元素时,我们无法简单地将其对应的位重置为0,因为这可能会影响到其他已经添加的元素。

具体来说,如果我们将某个元素对应的位重置为0,那么可能会破坏掉其他已经添加到过滤器中的元素的哈希表示。因为多个元素可能哈希到同一个位上,而这个位被某个元素“占用”时,我们不能确定它是否只被这一个元素所使用。

因此,一旦一个元素被添加到布隆过滤器中,它就不能被直接删除。这是布隆过滤器的一个固有特性,也是它与其他数据结构(如哈希表或集合)相比的一个主要区别。

⭕️ 但是我们可以通过将布隆过滤器中的每个比特位扩展成一个小的计数器(通常称为计数布隆过滤器或Counting Bloom Filter),可以实现对元素的删除操作。这种方法通过牺牲更多的存储空间来换取删除功能。

在计数布隆过滤器中,每个位不再是一个简单的0或1,而是一个可以递增和递减的计数器。当插入一个元素时,通过k个哈希函数计算出的k个哈希地址,将对应的k个计数器加一。当需要删除一个元素时,同样通过这k个哈希函数找到对应的计数器,并将它们减一。

通过这种方法,可以准确地跟踪每个位置上的元素计数,从而支持删除操作。然而,需要注意的是,计数布隆过滤器仍然无法完全避免误报(False Positive)的情况。即使某个元素的计数器被正确减至零,由于哈希冲突的存在,其他元素可能仍然会导致该位置上的计数器非零,从而产生误报。

此外,计数布隆过滤器还需要考虑计数器溢出的问题。如果计数器的值超过了其能够表示的范围,就会导致数据丢失和误操作。因此,在选择计数器的位数时需要根据实际应用场景进行权衡。

2、布隆过滤器的空间效率分析

布隆过滤器的空间效率分析主要体现在其相对于其他数据结构的空间占用优势上。布隆过滤器通过使用位图和哈希函数,实现了对元素存在性的高效判断,同时显著降低了空间占用。

  • 与其他数据结构的空间对比

与常见的数据结构如listsetmap等相比,布隆过滤器在空间效率上具有显著优势。这些传统数据结构通常需要存储元素的完整信息,而布隆过滤器只存储位图中的位信息,且每一位只占用极少的空间(通常是1比特)。因此,在存储相同数量的元素时,布隆过滤器所需的存储空间远小于其他数据结构。

  • 影响空间效率的关键因素
  1. 位图的大小:位图是布隆过滤器存储元素信息的主要数据结构。位图的大小直接决定了布隆过滤器能够存储的元素数量以及误报率的高低。通常情况下,位图越大,能够存储的元素数量越多,同时误报率也会相应降低。
  2. 哈希函数的个数和性质:哈希函数在布隆过滤器中起到了将元素映射到位图的关键作用。哈希函数的个数和性质直接影响到布隆过滤器的空间效率和误报率。一般来说,使用更多的哈希函数可以降低误报率,但同时也会增加计算开销和空间占用。此外,哈希函数的均匀性和分散性也对布隆过滤器的性能有重要影响。
  3. 元素的数量:存储的元素数量越多,布隆过滤器所需的位图空间就越大。这是因为每个元素都需要通过哈希函数映射到位图中的多个位置,并设置相应的位为1。
  4. 误报率的设定:误报率是布隆过滤器的一个重要指标,它表示了当查询一个不存在的元素时错误地返回存在的概率。误报率的设定会直接影响到布隆过滤器的空间占用。通常情况下,误报率越低,所需的位图空间就越大。

3、布隆过滤器的性能特点

插入和查询的时间复杂度都是O(k),这意味着无论集合中元素的数量如何增加,插入和查询的时间都将保持稳定,不会随着元素数量的增长而显著增长。这是因为布隆过滤器使用位图和哈希函数来表示集合,查询和插入操作只涉及到位图的访问和更新,而无需遍历整个集合。

其次,哈希函数的选择对布隆过滤器的性能具有重要影响。一个好的哈希函数能够近似等概率地将字符串映射到各个位上,从而减少哈希冲突的可能性,提高布隆过滤器的准确性和性能。哈希函数的个数k也是影响性能的关键因素,k值的选择需要根据实际情况进行权衡。过多的哈希函数会增加计算复杂度,而过少的哈希函数则可能导致较高的误报率。

总的来说,布隆过滤器以其高效的插入和查询操作以及灵活的哈希函数选择,成为了处理大规模数据集合的理想选择。然而,需要注意的是,布隆过滤器存在误报的可能性,即可能会错误地判断一个不存在的元素为存在。因此,在使用布隆过滤器时,需要根据具体的应用场景和需求来选择合适的参数配置,以达到最优的性能和准确性。


三、布隆过滤器的应用场景

1、数据库查询优化

  • 过滤不存在的记录,减少磁盘I/O

布隆过滤器可以有效地过滤不存在的记录,从而避免不必要的磁盘I/O操作。那么,当一个新的查询请求到达时,首先通过布隆过滤器检查该记录是否可能存在于数据库中。如果布隆过滤器返回结果为“不存在”,则可以直接拒绝该查询请求,无需进一步访问数据库。这样可以显著减少磁盘I/O操作,提高查询效率。

在实际应用中,布隆过滤器可以与数据库查询语句结合使用。例如,在执行查询操作之前,可以先将查询条件通过布隆过滤器进行过滤,只保留可能存在于数据库中的记录,然后再执行实际的查询操作。这样可以确保查询操作只针对可能存在的记录进行,避免了对大量不存在记录的无效查询。

2、例子

假设给了两个文件,分别有100亿个query,我们只有1G内存,如何找到两个文件交集?分别给出精确算法和近似算法?

假设一个 query 平均是50byte,1G约等于10亿字节。那么100亿个query是500G。

精确算法

由于内存限制,我们不能一次性加载所有query到内存中。因此,需要采用分块处理的策略。

  1. 哈希分块
    • 使用哈希函数将两个文件分别分成多个小块,每个块的大小适中,使得可以加载到内存中。
    • 对每个块进行排序,以便后续快速查找交集。
  2. 逐块对比
    • 逐块比较两个文件中的query。对于每一对块,将其中一个块加载到内存中,另一个块则使用外部排序的方法(如多路归并排序)进行遍历。
    • 在内存中执行二分查找或使用哈希表来查找交集。
  3. 合并结果
    • 将所有找到的交集合并到一个输出文件中。
  4. 去重:
    • 由于可能存在重复的交集,在写入输出文件之前,需要对结果进行去重处理。可以使用 map、set等容器。

这个算法虽然精确,但可能非常耗时,因为它涉及到多次磁盘I/O操作和排序操作。该文中也有涉猎 -> 深入探索位图技术:原理及应用

近似算法

为了在处理大数据集时提高效率,可以采用近似算法来找到交集的近似解。

  1. 布隆过滤器

    • 使用布隆过滤器来存储一个文件中的所有query。布隆过滤器允许快速检查一个元素是否可能存在于集合中,但可能会产生误报(即,将不存在的元素错误地识别为存在)。
    • 加载第一个文件的query到布隆过滤器中。由于布隆过滤器的内存占用相对较小,因此可以在有限的内存中存储大量的query。
  2. 检查交集

    • 遍历第二个文件的query,使用布隆过滤器检查每个query是否可能存在于第一个文件中。
    • 将布隆过滤器识别为可能存在的query作为交集的近似结果输出。

请注意,由于布隆过滤器的误报性质,这种算法只能给出交集的近似解,而不是精确解。误报率取决于布隆过滤器的大小和哈希函数的数量。通过调整这些参数,可以在一定程度上控制误报率,但无法完全消除它。


四、布隆过滤器的实现与优化

1、常见的布隆过滤器库

  • 开源库
    • Google Guava:Java语言的开源库,提供了布隆过滤器的实现。
    • RedisBloom:针对Redis的布隆过滤器模块,提供丰富的布隆过滤器功能。
    • pybloom:Python语言的布隆过滤器库。
    • bloomfilter-cpp:C++语言的布隆过滤器库

2、自定义布隆过滤器的实现步骤

struct HashFunc1 {//BKDRsize_t operator()(const string& s){size_t hash = 0;for (auto ch : s){hash *= 131;hash += ch;}return hash;}
};
struct HashFunc2 {// APsize_t operator()(const string& s){size_t hash = 0;for (size_t i = 0; i < s.size(); i++){if ((i & 1) == 0) // 偶数位字符hash ^= ((hash << 7) ^ (s[i]) ^ (hash >> 3));else              // 奇数位字符hash ^= (~((hash << 11) ^ (s[i]) ^ (hash >> 5)));}return hash;}
};
struct HashFunc3 {// DJBsize_t operator()(const string& s){size_t hash = 5381;for (auto ch : s)hash = hash * 33 ^ ch;return hash;}
};
template<size_t N, class K = string,class Hash1 = HashFunc1,class Hash2 = HashFunc2,class Hash3 = HashFunc3>
class BloomFilter {
public:void Set(const K& key) {size_t hash1 = Hash1()(key) % M;size_t hash2 = Hash2()(key) % M;size_t hash3 = Hash3()(key) % M;_bs->set(hash1);_bs->set(hash2);_bs->set(hash3);}bool Test(const K& key) {size_t hash1 = Hash1()(key) % M;if (_bs->test(hash1) == false)return false;size_t hash2 = Hash2()(key) % M;if (_bs->test(hash2) == false)return false;size_t hash3 = Hash3()(key) % M;if (_bs->test(hash3) == false)return false;// 存在误判(有可能3个位都是跟别人冲突的,所以误判)return true;}
private:static const size_t M = 5 * N;std::bitset<M>* _bs = new std::bitset<M>;
};
  1. Set方法:用于将元素添加到布隆过滤器中。它计算元素的三个哈希值,并将对应位置上的位设置为1。
  2. Test方法:用于检查元素是否可能存在于布隆过滤器中。它同样计算元素的三个哈希值,并检查对应位置上的位是否都为1。如果有任何一位为0,则确定元素一定不存在;如果所有位都为1,则返回true,但存在误报的可能。

3、降低误报率的策略

  • 增加位图长度

布隆过滤器的误报率与其使用的位图(bit array)大小直接相关。位图越长,能提供的唯一标识就越多,从而减少了哈希冲突的可能性。因此,增加位图长度可以有效降低误报率。但需要注意的是,位图长度的增加也会导致空间需求的增加,所以需要在误报率和空间使用之间找到平衡。

  • 使用多个独立的哈希函数

布隆过滤器通常使用多个哈希函数将元素映射到位图的不同位置。使用更多的哈希函数可以增加元素在位图中的覆盖面积,进一步减少哈希冲突的可能性。然而,这也增加了计算复杂性和哈希函数的选择难度。因此,在选择哈希函数数量时,需要权衡误报率和计算效率。

  • 动态调整布隆过滤器大小

在某些情况下,可以根据实际需求动态调整布隆过滤器的大小。例如,当检测到误报率较高时,可以扩大位图长度或增加哈希函数数量来降低误报率。同样地,当空间资源紧张时,也可以适当缩小位图长度或减少哈希函数数量以节省空间。这种动态调整策略需要根据实际应用场景进行灵活配置。

需要注意的是,虽然这些策略可以降低误报率,但它们并不能完全消除误报。布隆过滤器是一种概率数据结构,其设计本身就允许存在一定的误报率。因此,在使用布隆过滤器时,需要充分考虑其特性并根据实际需求进行权衡和配置。

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

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

相关文章

NFG技术引领电商新潮流:普通商品的高端奢侈品化之路

随着网络技术、移动互联网等科技领域的迅猛进步&#xff0c;电子商务在众多新兴行业中逐渐崭露头角。然而&#xff0c;电子商务的蓬勃发展也带来了产品同质化现象加剧、市场竞争日趋激烈的问题&#xff0c;这使得商品在海量产品中脱颖而出变得愈发困难。值得注意的是&#xff0…

AI在行业大模型中的机会及爆发赚钱的行业有哪些?

人工智能(AI)正逐渐成为驱动各行业发展的核心力量,尤其是在应用层,AI结合具体细分领域所带来的生产力提升是巨大的。随着技术的不断进步和人口老龄化趋势的加剧,AI将在多个行业中发挥关键作用,为这些行业带来爆发式增长和丰厚的利润。 一、医疗行业:AI辅助诊断的崛起…

Linux:查询类型的命令type

相关阅读 Linuxhttps://blog.csdn.net/weixin_45791458/category_12234591.html?spm1001.2014.3001.5482 type命令是Linux中一个查询类型的命令&#xff0c;它可以查询name是alias别名、keyword关键字、function函数名、builtin内建命令名&#xff08;这很有用&#xff09;或…

【粉丝福利社】鸿蒙App开发全流程实战(文末送书-进行中)

&#x1f3c6; 作者简介&#xff0c;愚公搬代码 &#x1f3c6;《头衔》&#xff1a;华为云特约编辑&#xff0c;华为云云享专家&#xff0c;华为开发者专家&#xff0c;华为产品云测专家&#xff0c;CSDN博客专家&#xff0c;CSDN商业化专家&#xff0c;阿里云专家博主&#xf…

鸿蒙:滑动条组件Slider

滑动条组件&#xff0c;通常用于快速调节设置值&#xff0c;如音量调节、亮度调节等应用场景。 说明 该组件从API Version 7开始支持。 子组件 无 接口 Slider(options?: {value?: number, min?: number, max?: number, step?: number, style?: SliderStyle, direc…

书生 浦语大模型全链路开源体系

通用大模型成为发展通用人工智能的重要途径 书生 浦语大模型的开源历程 书生 浦语 2.0体系&#xff0c;面向不同的使用需求&#xff0c;每个规格包含三个模型版本&#xff0c;&#xff08;7B、20B&#xff09;InternLM2-Base、InternLM2、InternLM2-Chat。 大模型是回归语言建…

数据可视化-ECharts Html项目实战(9)

在之前的文章中&#xff0c;我们学习了如何在ECharts中编写气泡图&#xff0c;词云图。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢谢。 数据可视化-ECharts Ht…

鸿蒙OS开发问题:【尺寸适配算法】

背景 如何在HarmonyOS 系统上出设计稿&#xff1f; 问题1: 为什么要计算虚拟高度&#xff0c;即 virtualHeight static adaptDimension(value: number): number {let deviceDisplay: display.Display GlobalContext.getContext().getObject(display) as display.Display;le…

PEReDi 完全隐私的央行数字货币方案

第一个对完全隐私保护建模的方案&#xff0c;基于账户模型&#xff0c;要求交易双方都在线。 角色分类 中央银行 B B B&#xff1a;负责发行数字货币和货币政策&#xff0c;但不控制用户账户的状态&#xff0c;没有能力对交易的发送者或接收者进行去匿名化或披露与特定交易相…

瑞吉外卖实战学习--11、分类管理的列表分页查询

分类管理的列表分页查询 前言1、创建接口2、基于分页组件来实现的 前言 通过前端接口可以看到请求和传递的参数&#xff0c;本文章是基于mybatisPlus的分页插件来实现的 1、创建接口 GetMapping("/page")public R<Page> page(int page,int pageSize){ // …

halcon图像腐蚀

1、原理 使用结构元素在图像上移动&#xff0c;只有结构元素上的所有像素点都属于图像中时&#xff0c;才保留结构元素中心点所在的像素&#xff0c;常用于分离连接的两个物体、消除噪声。 2、halcon代码 dev_open_file_dialog (read_image, default, default, Selection) r…

【Python刷题】将有序数组转换为二叉搜索树

问题描述 给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你将其转换为一棵 平衡 二叉搜索树。 高度平衡的意思是&#xff1a;二叉树是一颗满足“每个结点的左右两个子树的高度差的绝对值不超过1”的二叉树。 示例 1&#xff1a; 输入&#xf…

Java学习33-Java 多线程Thread 多线程安全问题

Thread的生命周期 JDK1.5之前 JDK1.5之后分为 NEW RUNNABLE BLOCKED WAITING TIMED_WAITING TERMINATED 多线程安全问题 举例&#xff0c;要求三个窗口同时卖票&#xff0c;总共有100张票&#xff0c;打印出卖票过程&#xff0c;不允许重复售卖 package Thread;public class …

Codeforces Round 930 (Div. 2) C. Bitwise Operation Wizard

题目 思路&#xff1a; #include <bits/stdc.h> using namespace std; #define int long long #define pb push_back #define fi first #define se second #define lson p << 1 #define rson p << 1 | 1 const int maxn 1e6 5, inf 1e9, maxm 4e4 5; co…

linux:生产者消费者模型

个人主页 &#xff1a; 个人主页 个人专栏 &#xff1a; 《数据结构》 《C语言》《C》《Linux》 文章目录 前言一、生产者消费者模型二、基于阻塞队列的生产者消费者模型代码实现 总结 前言 本文是对于生产者消费者模型的知识总结 一、生产者消费者模型 生产者消费者模型就是…

OpenHarmony实战开发-如何实现购物示例应用

​介绍 本示例展示在进场时加载进场动画&#xff0c;整体使用Tabs容器设计应用框架&#xff0c;通过TabContent组件设置分页面&#xff0c;在子页面中绘制界面。通过Navigation完成页面之间的切换。在详情页中通过 Video组件加载视频资源&#xff0c;使用CustomDialogControll…

Python 代码混淆工具概述

在保护Python代码安全方面&#xff0c;有多种混淆工具可供选择&#xff0c;包括 Cython, Nuitka, Pyminifier 和 IPA guard。本文将介绍这些工具的特点和适用情况&#xff0c;以及在实际应用中的注意事项。 &#x1f4dd; 摘要 本文探讨了几种常见的 Python 代码混淆工具&am…

用Typora+picgo+cloudflare+Telegraph-image的免费,无需服务器,无限空间的图床搭建(避坑指南)

用TyporapicgocloudflareTelegraph-image的免费&#xff0c;无需服务器&#xff0c;无限空间的图床搭建&#xff08;避坑指南&#xff09; 前提&#xff1a;有github何cloudflare (没有的话注册也很快) 首先&#xff0c;是一个别人写的详细的配置流程&#xff0c;傻瓜式教程&am…

嵌入式网络硬件方案

一. 简介 本文来了解一下嵌入式有些网络中&#xff0c;涉及的网络硬件方案。 注意&#xff1a;本文说明的是有些网络。 提起网络&#xff0c;我们一般想到的硬件就是“网卡”&#xff0c;“网卡”这个概念最早从电脑领域传出来&#xff0c;顾名思义就是能上网的卡。在电脑领…

Android12 简单的共享内存驱动实现 参考Ashmem

Android12 共享内存驱动实现 SOC&#xff1a;RK3568 system&#xff1a;Android12 概述&#xff1a; 1. 概述 Ashmem&#xff08;Anonymous Shared Memory&#xff0c;Android 匿名共享内存&#xff09;&#xff0c;它基于 mmap 系统调用&#xff0c;可以让不同进程将同一段…