布隆過濾器的原理及使用

背景介紹

????????在互聯網中,我們經常遇到需要在大量數據中判斷目標數據是否存在的情況。例如,在網絡爬蟲中,我們需要判斷某個網址是否已經被訪問過。為了實現這一功能,通常需要使用一個容器來存儲已訪問過的網址。如果將這些數據直接存儲在磁盤中,每次判斷都要進行磁盤查詢,這將導致大量的IO操作,效率較低。因此,我們希望將這些數據保存在內存中。在數據量較小的情況下,可以使用Redis來存儲這些數據。但是,當數據量超過上千萬時,將會消耗幾GB甚至幾十GB的內存空間。然而,對于僅需要記錄數據是否存在的情況而言,這樣使用大量內存顯然是浪費的。為了解決這個問題,我們可以使用布隆過濾器(Bloom Filter)。布隆過濾器是一種占用空間少且時間效率高的工具。

布隆過濾器介紹

布隆過濾器是一種空間效率極高的概率型數據結構,用于快速判斷一個元素是否可能存在于一個集合中。它的核心特點是以極小的存儲空間換取高效的查詢性能,但存在一定的誤判率(False Positive)。

核心原理

  1. 位數組(Bit Array)

    • 布隆過濾器使用一個長度為m的二進制位數組(初始全為0)作為底層存儲

    • 例如:[0, 0, 0, 0, 0, 0, 0, 0](m=8)

  2. 多個哈希函數

    • 使用k個不同的哈希函數(h?, h?, ..., h?)

    • 每個函數都能將輸入元素映射到位數組的某個位置

當一個元素被添加到集合中時,它會通過k個哈希函數映射到位數組中的m個位置,并將這些位置的值設置為 1。在檢查元素是否在集合中時,檢查這些位置是否全為 1。如果其中有任何一個位置為 0,則該元素一定不在集合中;如果所有位置均為 1,則該元素可能在集合中

簡單舉例

假設現在有3個哈希函數,和一個8位的bit數組。元素a和b,都經過三次哈希函數生成三個哈希值,并映射到位數組的不同的位置,并設置為1。元素a映射的位置是(0,3,7),元素b映射的位置是(2,5,7).

如果一個元素c過來,我們檢查它映射后的三個位置是否全是1,就可以判斷元素C是否在當前集合中了。

其實我們可以發現,元素a和元素b映射的位置7都是1,也就是說,位置是可能重疊的。假設當前集合已經有a和b了,但是呢一個元素c過來,它映射的位置為(0,2,7),這時候,它的所有位置都是1,布隆過濾器是認為它可能在集合中,但是我們看到元素c是不在當前集合中的。

也是就說,布隆過濾器是可能存在誤判的,通俗點說就是假陽性。

關鍵特性

  1. 沒有假陰性(False Negative)

    如果查詢返回"不存在",則元素一定不在集合中
  2. 存在假陽性(False Positive)

    可能誤判不存在的元素為存在(概率通常<1%)原因:不同元素的哈希位置可能重疊
  3. 不支持元素刪除

    簡單的布隆過濾器無法安全刪除元素(會影響到其他元素)

使用樣例

依賴導入

        <dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>30.1-jre</version> <!-- Use the latest version --></dependency>

Java代碼

import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;public class BloomFilterIntersection {public static void main(String[] args) {// 生成兩個測試數據集Set<Integer> set1 = generateRandomSet(1_000_000, 10000000);Set<Integer> set2 = generateRandomSet(1_000_000, 10000000);// 人為添加一些共同元素for (int i = 0; i < 1000; i++) {int commonElement = 20000000 + i;set1.add(commonElement);set2.add(commonElement);}System.out.println("集合1大小: " + set1.size());System.out.println("集合2大小: " + set2.size());// 使用布隆過濾器查找交集long startTime = System.currentTimeMillis();Set<Integer> intersection = findIntersection(set1, set2);long endTime = System.currentTimeMillis();System.out.println("檢測到的交集元素數量: " + intersection.size());System.out.println("計算耗時: " + (endTime - startTime) + "ms");// 驗證前10個交集元素System.out.println("\n前10個交集元素示例:");intersection.stream().limit(10).forEach(System.out::println);}/*** 使用布隆過濾器找出兩個集合的交集* @param set1 第一個集合* @param set2 第二個集合* @return 兩個集合的交集*/public static Set<Integer> findIntersection(Set<Integer> set1, Set<Integer> set2) {// 創建布隆過濾器,預計插入set1的大小,誤判率1%//Funnel 是 Guava 提供的一個接口,用于 將對象轉換為字節流(PrimitiveSink)BloomFilter<Integer> filter = BloomFilter.create(Funnels.integerFunnel(),set1.size(),0.01);// 將第一個集合的所有元素添加到布隆過濾器for (Integer item : set1) {filter.put(item);}// 檢查第二個集合中的哪些元素可能在第一個集合中Set<Integer> possibleMatches = new HashSet<>();for (Integer item : set2) {if (filter.mightContain(item)) {possibleMatches.add(item);}}// 由于布隆過濾器可能有假陽性,需要二次驗證Set<Integer> actualIntersection = new HashSet<>(set1);actualIntersection.retainAll(possibleMatches);return actualIntersection;}/*** 生成隨機整數集合* @param size 集合大小* @param bound 隨機數范圍* @return 包含隨機整數的集合*/private static Set<Integer> generateRandomSet(int size, int bound) {Set<Integer> set = new HashSet<>();Random random = new Random();while (set.size() < size) {set.add(random.nextInt(bound));}return set;}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/918999.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/918999.shtml
英文地址,請注明出處:http://en.pswp.cn/news/918999.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

達夢 vs. Oracle :架構篇①——從“聯邦制”到“中央集權”

1. 引言&#xff1a;為何體系結構是第一課&#xff1f; 對于任何一個數據庫而言&#xff0c;其體系結構是決定其性格、性能和應用場景的“基因”。理解了體系結構&#xff0c;尤其是在兩種數據庫之間進行切換時&#xff0c;才能真正做到知其然&#xff0c;并知其所以然。在所有…

我的世界Java版1.21.4的Fabric模組開發教程(十九)自定義生物群系

這是適用于Minecraft Java版1.21.4的Fabric模組開發系列教程專欄第十九章——自定義生物群系。想要閱讀其他內容&#xff0c;請查看或訂閱上面的專欄。 生物群系(Biome) 是Minecraft中世界不同區域呈現特定的地貌景觀&#xff0c;這些區域與現實世界類似&#xff0c;都具有和其…

Mac (三)如何設置環境變量

目錄一、查看環境變量 &#x1f50d;1. 查看所有環境變量2. 查看特定變量二、臨時設置&#xff08;當前終端有效&#xff09; ?1. 基本語法2. 實戰示例三、永久設置&#xff08;全局生效&#xff09; &#x1f512;配置步驟&#xff1a;四、實戰案例 &#x1f6e0;?案例1&…

零改造遷移實錄:2000+存儲過程從SQL Server滑入KingbaseES V9R4C12的72小時

摘要&#xff1a;在信創窗口期&#xff0c;我們把擁有2000存儲過程、300鏈接服務器的核心業務&#xff0c;從 SQL Server 2016/2019 平移到 KingbaseES V9R4C12&#xff08;SQL Server 兼容版&#xff09;。本文以 30 分鐘部署、TPCH 100G 性能 PK、真實踩坑修復、灰度割接 4 小…

K8S HPA 彈性水平擴縮容 Pod 詳解

文章目錄1、前置準備2、需求場景3、Scale 靜態擴縮容3.1、創建 Deployment 腳本3.2、Scale 擴縮容3、HPA 自動擴縮容3.1、安裝 Metrics3.2、創建 Deployment 演示案例3.3、創建 HPA3.4、觸發 HPA 自動擴縮容1、前置準備 本次案例演示&#xff0c;我選擇了阿里云ECS&#xff08…

對話訪談|盤古信息×智晟威:深度挖掘數字化轉型的奧秘

在數字化轉型的浪潮中&#xff0c;傳統設備企業如何突破“純硬件”的邊界&#xff0c;實現從“賣產品”到“賣生態”的跨越&#xff1f;數字化轉型究竟是“高不可攀的奢侈品”&#xff0c;還是“觸手可及的生存技能”&#xff1f;近日&#xff0c;廣東盤古信息科技股份有限公司…

什么是模型預測控制?

一、概念模型預測控制&#xff08;Model Predictive Control, MPC&#xff09;是一種先進的控制方法&#xff0c;廣泛應用于工業過程控制、機器人控制、自動駕駛等領域。MPC的核心思想是利用系統的動態模型預測未來的行為&#xff0c;并通過優化算法計算出當前時刻的最優控制輸…

類與類加載器

在Java中&#xff0c;類和類加載器是密切相關的兩個概念&#xff0c;理解它們有助于我們更好地掌握Java的運行機制。什么是Java類&#xff1f;Java類就像是一個模板或藍圖&#xff0c;它定義了對象的屬性和行為。比如"汽車"可以看作一個類&#xff0c;它有顏色、品牌…

一文速通Python并行計算:14 Python異步編程-協程的管理和調度

一文速通 Python 并行計算&#xff1a;14 Python 異步編程-協程的管理和調度 摘要&#xff1a; Python 異步編程基于 async/await 構建協程&#xff0c;運行在事件循環中。協程生成 Task&#xff0c;遇到?await?時掛起&#xff0c;I/O 完成觸發回調恢復運行&#xff0c;通過…

Node.js面試題及詳細答案120題(16-30) -- 核心模塊篇

《前后端面試題》專欄集合了前后端各個知識模塊的面試題&#xff0c;包括html&#xff0c;javascript&#xff0c;css&#xff0c;vue&#xff0c;react&#xff0c;java&#xff0c;Openlayers&#xff0c;leaflet&#xff0c;cesium&#xff0c;mapboxGL&#xff0c;threejs&…

RabbitMQ:Windows版本安裝部署

目錄一、概述二、OPT三、安裝RabbitMQ四、登錄測試一、概述 什么是MQ&#xff0c;有什么做作用&#xff1f; MQ即MessageQueue&#xff0c;消息隊列。可以分為兩部分理解&#xff1a;消息Message用于在不同的應用程序中傳遞數據。隊列Queue&#xff0c;一種FIFO先進先出的數據…

酒店行業安全體系構建與優化策略

酒店行業安全體系構建與優化策略為確保酒店行業領導及賓客的安全&#xff0c;構建全面的治安聯防體系及事故處理預案至關重要。某招待所通過設立保衛部&#xff0c;細化內保、治安、防火及交通管理職能&#xff0c;并下設警衛班、監控中心和電瓶車班&#xff0c;以全方位保障安…

python30-正則表達式

在Python中需要通過正則表達式對字符串進?匹配的時候&#xff0c;可以使??個python自帶的模塊&#xff0c;名字為re。 re模塊的使用&#xff1a;import re 一、匹配函數 1-1、re.match函數&#xff1a;返回匹配對象 match函數實現的是精準匹配&#xff0c;嘗試從字符串的…

EP1C12F324I7N Altera Cyclone FPGA

EP1C12F324I7N 是 阿爾特拉 Altera Cyclone 系列中的一款 SRAM-based FPGA&#xff0c;定位為低成本、低功耗、面向嵌入式與消費/工業類量產應用的器件。該器件提供約 12,060 個邏輯單元&#xff08;Logic Elements&#xff09;&#xff0c;片上嵌入式存儲約 234 kbit&#xff…

html5語義元素

1、參考&#xff1a;HTML5 語義元素 | 菜鳥教程 2、實戰 HTML5 <section> 元素 <section> 標簽定義文檔中的節&#xff08;section、區段&#xff09;。比如章節、頁眉、頁腳或文檔中的其他部分。 根據W3C HTML5文檔: section 包含了一組內容及其標題。 <!D…

java調用PyTorch 訓練模型實現神經網絡全流程

以下是完整的操作流程:用 PyTorch 訓練模型 → 導出為 ONNX 格式 → 用 Java 加載并推理,兼顧開發效率(PyTorch 快速訓練)和生產部署(Java 穩定運行)。 一、PyTorch 訓練模型并導出為 ONNX 1. 安裝依賴 bash pip install torch onnx # PyTorch 和 ONNX 庫2. 訓練一個…

Maven - Spring Boot 項目打包本地 jar 的 3 種方法

文章目錄Pre概述方案思路構建流程圖工作機制說明目錄結構示例POM 配置模板構建與驗證注意事項方案優缺點Pre Maven - Manual Maven JAR Installation&#xff1a;用 mvn install:install-file 安裝本地 JAR 的實用指南 概述 在 Spring Boot 項目中&#xff0c;通常依賴包會從…

平替 Claude Code,API接入 GPT-5,Codex CLI 國內直接使用教程

最新升級接入GPT-5的 Codex 擁有可以媲美 Claude Code 的AI編碼能力&#xff0c;本文將指導你在 Windows系統上部署原生的 Codex CLI程序&#xff0c;并且接入超低價中轉API&#xff0c;讓你在國內直接用上超高性價比的 OpenAI Codex CLI 應用。關于 CodexCodex 是 OpenAI 開發…

kubernertes (K8S)部署

參考&#xff1a; https://blog.csdn.net/yu33575/article/details/135387548 二進制安裝k8s&#xff1a; https://blog.csdn.net/qq_73990369/article/details/143217084 K8S二進制安裝與部署 &#xff1a;https://blog.csdn.net/fantuan_sss/article/details/139073366 k8s…

LeetCode 簡單JS刷題

目錄 返回數組最后一個元素 2787.將一個數字表示成冪的和的方案數 326.3的冪 1780.判斷一個數字是否可以表示成三的冪的和 342.4的冪 返回數組最后一個元素 1.請你編寫一段代碼實現一個數組方法&#xff0c;使任何數組都可以調用 array.last() 方法&#xff0c;這個方法將…