最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java面試之如何實(shí)現(xiàn)10億數(shù)據(jù)判重

 更新時(shí)間:2024年02月19日 15:10:09   作者:Java中文社群  
當(dāng)數(shù)據(jù)量比較大時(shí),使用常規(guī)的方式來(lái)判重就不行了,所以這篇文章小編主要來(lái)和大家介紹一下Java實(shí)現(xiàn)10億數(shù)據(jù)判重的相關(guān)方法,希望對(duì)大家有所幫助

當(dāng)數(shù)據(jù)量比較大時(shí),使用常規(guī)的方式來(lái)判重就不行了。

例如,使用 MySQL 數(shù)據(jù)庫(kù)判重,或使用 List.contains() 或 Set.contains() 判重就不可行,因?yàn)?MySQL 在數(shù)據(jù)量大時(shí)查詢就會(huì)非常慢,而數(shù)據(jù)庫(kù)又是及其珍貴的全局?jǐn)?shù)據(jù)庫(kù)資源。

《阿里巴巴Java開(kāi)發(fā)手冊(cè)》上也說(shuō)了,如果單表數(shù)據(jù)量超過(guò) 500 萬(wàn)或 2GB 時(shí)就建議分庫(kù)分表了,如下圖所示:

所以數(shù)據(jù)庫(kù)去重顯然是不行的。而使用集合也是不合適的,因?yàn)閿?shù)據(jù)量太大,使用集合會(huì)導(dǎo)致內(nèi)存不夠用或內(nèi)存溢出和 Full GC 頻繁等問(wèn)題,所以此時(shí)我們的解決方案通常是采用布隆過(guò)濾器來(lái)實(shí)現(xiàn)判重,布隆過(guò)濾器的詳情請(qǐng)參開(kāi)文末補(bǔ)充內(nèi)容

知識(shí)擴(kuò)展

除了布隆過(guò)濾器之外,我們還可以使用 BitMap(位圖)的數(shù)據(jù)類型來(lái)實(shí)現(xiàn)判重。

位圖(BitMap)是一種數(shù)據(jù)結(jié)構(gòu),用于表示一個(gè)特定范圍內(nèi)的元素是否存在或者某種狀態(tài),通常用二進(jìn)制位來(lái)表示。在位圖中,每一個(gè)位只能是 0 或 1,分別表示元素不存在或存在。位圖通常用一個(gè) bit 數(shù)組來(lái)實(shí)現(xiàn),每個(gè) bit 位對(duì)應(yīng)一個(gè)元素,如下圖所示:

其中,上圖中的 1 表示有值,上面 BitMap 描述的值是 1,3,5。

BitMap 優(yōu)點(diǎn)分析

位圖的優(yōu)勢(shì)包括:

  • 空間效率優(yōu)勢(shì):位圖極大地節(jié)省了存儲(chǔ)空間。對(duì)于大量稀疏數(shù)據(jù),特別是當(dāng)元素?cái)?shù)量遠(yuǎn)大于實(shí)際存在的項(xiàng)時(shí),相比于使用傳統(tǒng)的列表、集合等數(shù)據(jù)結(jié)構(gòu),位圖占用的空間極小。
  • 查詢速度:由于內(nèi)存訪問(wèn)是按字節(jié)或字進(jìn)行的,因此對(duì)單個(gè)元素的存在性檢查時(shí)間復(fù)雜度為 O(1),即常量時(shí)間,非常快速。
  • 批量操作高效:對(duì)于批量插入、刪除和查詢操作,尤其是統(tǒng)計(jì)某一范圍內(nèi)元素的數(shù)量,位圖表現(xiàn)出優(yōu)秀的性能。

BitMap VS int

以 Java 中的 int 為例,來(lái)對(duì)比觀察 BitMap 的優(yōu)勢(shì),在 Java 中,int 類型通常需要 32 位(4 字節(jié)*8),而 BitMap 使用 1 位就可以來(lái)標(biāo)識(shí)此元素是否存在,所以可以認(rèn)為 BitMap 占用的空間大小,只有 int 類型的 1/32,所以有大數(shù)據(jù)量判重時(shí),使用 BitMap 也可以實(shí)現(xiàn)。

PS:布隆過(guò)濾器的底層就是基于 BitMap 數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)的。

BitMap 在 Java 中的使用

BitMap 在 Java 中的具體實(shí)現(xiàn)是 java.util 中的 BitSet,BitSet 是一個(gè)可變大小的位向量,能夠動(dòng)態(tài)增長(zhǎng)以容納更多的位數(shù)據(jù),以下是 BitSet 基本使用示例:

import java.util.BitSet;

public class BitmapExample {
    public static void main(String[] args) {
        // 創(chuàng)建一個(gè)BitSet實(shí)例
        BitSet bitmap = new BitSet();

        // 設(shè)置第5個(gè)位置為1,表示第5個(gè)元素存在
        bitmap.set(5);

        // 檢查第5個(gè)位置是否已設(shè)置
        boolean exists = bitmap.get(5);
        System.out.println("Element at position 5 exists: " + exists);  // 輸出: Element at position 5 exists: true

        // 設(shè)置從索引10到20的所有位置為1
        bitmap.set(10, 21);  // 參數(shù)是包含起始點(diǎn)和不包含終點(diǎn)的區(qū)間

        // 計(jì)算bitset中所有值為1的位的數(shù)量,相當(dāng)于計(jì)算設(shè)置了的元素個(gè)數(shù)
        int count = bitmap.cardinality();
        System.out.println("Number of set bits: " + count);

        // 清除第5個(gè)位置
        bitmap.clear(5);

        // 判斷位圖是否為空
        boolean isEmpty = bitmap.isEmpty();
        System.out.println("Is the bitset empty after clearing some bits? " + isEmpty);
    }
}

課后思考

除了布隆過(guò)濾器和 BitMap 之外,還有哪些大數(shù)據(jù)量判重的實(shí)現(xiàn)方案呢?布隆過(guò)濾器實(shí)現(xiàn)判重的原理又是啥呢?

知識(shí)補(bǔ)充

什么是布隆過(guò)濾器?如何實(shí)現(xiàn)布隆過(guò)濾器?

布隆過(guò)濾器(Bloom Filter)是一種空間效率極高的概率型數(shù)據(jù)結(jié)構(gòu),用于判斷一個(gè)元素是否在一個(gè)集合中。它基于位數(shù)組和多個(gè)哈希函數(shù)的原理,可以高效地進(jìn)行元素的查詢,而且占用的空間相對(duì)較小,如下圖所示:

根據(jù) key 值計(jì)算出它的存儲(chǔ)位置,然后將此位置標(biāo)識(shí)全部標(biāo)識(shí)為 1(未存放數(shù)據(jù)的位置全部為 0),查詢時(shí)也是查詢對(duì)應(yīng)的位置是否全部為 1,如果全部為 1,則說(shuō)明數(shù)據(jù)是可能存在的,否則一定不存在。

也就是說(shuō),如果布隆過(guò)濾器說(shuō)一個(gè)元素不在集合中,那么它一定不在這個(gè)集合中;但如果它說(shuō)一個(gè)元素在集合中,則有可能是不存在的(存在誤差)。

1.布隆執(zhí)行過(guò)程

布隆過(guò)濾器的具體執(zhí)行步驟如下:

  • 在 Redis 中創(chuàng)建一個(gè)位數(shù)組,用于存儲(chǔ)布隆過(guò)濾器的位向量。
  • 初始化多個(gè)哈希函數(shù),并將每個(gè)哈希函數(shù)的計(jì)算結(jié)果對(duì)應(yīng)的位數(shù)組位置設(shè)置為 1。
  • 添加元素到布隆過(guò)濾器時(shí),對(duì)元素進(jìn)行多次哈希計(jì)算,并將對(duì)應(yīng)的位數(shù)組位置設(shè)置為 1。
  • 查詢?cè)厥欠翊嬖跁r(shí),對(duì)元素進(jìn)行多次哈希計(jì)算,并檢查對(duì)應(yīng)的位數(shù)組位置是否都為 1。

2.布隆使用場(chǎng)景

布隆過(guò)濾器的主要使用場(chǎng)景有以下幾個(gè):

  • 大數(shù)據(jù)量去重:可以用布隆過(guò)濾器來(lái)進(jìn)行數(shù)據(jù)去重,判斷一個(gè)數(shù)據(jù)是否已經(jīng)存在,避免重復(fù)插入。
  • 緩存穿透:可以用布隆過(guò)濾器來(lái)過(guò)濾掉惡意請(qǐng)求或請(qǐng)求不存在的數(shù)據(jù),避免對(duì)后端存儲(chǔ)的頻繁訪問(wèn)。
  • 網(wǎng)絡(luò)爬蟲的 URL 去重:可以用布隆過(guò)濾器來(lái)判斷 URL 是否已經(jīng)被爬取,避免重復(fù)爬取。

3.如何實(shí)現(xiàn)布隆過(guò)濾器?

在 Redis 中不能直接使用布隆過(guò)濾器,但我們可以通過(guò) Redis 4.0 版本之后提供的 modules (擴(kuò)展模塊) 的方式引入,它的實(shí)現(xiàn)步驟如下。

① 打包RedisBloom插件

git clone github.com/RedisLabsModules/redisbloom.git

cd redisbloom

make # 編譯redisbloom

編譯正常執(zhí)行完,會(huì)在根目錄生成一個(gè) redisbloom.so 文件。

② 啟用RedisBloom插件

重新啟動(dòng) Redis 服務(wù),并指定啟動(dòng) RedisBloom 插件,具體命令如下:

redis-server redis.conf --loadmodule ./src/modules/RedisBloom-master/redisbloom.so

③ 創(chuàng)建布隆過(guò)濾器

創(chuàng)建一個(gè)布隆過(guò)濾器,并設(shè)置期望插入的元素?cái)?shù)量和誤差率,在 Redis 客戶端中輸入以下命令:

BF.RESERVE my_bloom_filter 0.01 100000

④ 添加元素到布隆過(guò)濾器

在 Redis 客戶端中輸入以下命令:

BF.ADD my_bloom_filter leige

⑤ 檢查元素是否存在

在 Redis 客戶端中輸入以下命令:

BF.EXISTS my_bloom_filter leige

到此這篇關(guān)于Java面試之如何實(shí)現(xiàn)10億數(shù)據(jù)判重的文章就介紹到這了,更多相關(guān)Java數(shù)據(jù)判重內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java守護(hù)線程用法實(shí)例分析

    Java守護(hù)線程用法實(shí)例分析

    這篇文章主要介紹了Java守護(hù)線程用法,結(jié)合實(shí)例形式分析了java守護(hù)線程相關(guān)的原理、用法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2019-10-10
  • Java內(nèi)存溢出案例模擬和原理分析過(guò)程

    Java內(nèi)存溢出案例模擬和原理分析過(guò)程

    這篇文章主要介紹了Java內(nèi)存溢出案例模擬和原理分析過(guò)程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • AgentScope Java 核心架構(gòu)深度解析(推薦)

    AgentScope Java 核心架構(gòu)深度解析(推薦)

    AgentScopeJava是一個(gè)面向生產(chǎn)環(huán)境的智能體編程框架,它將大語(yǔ)言模型的推理能力、工具調(diào)用、記憶管理和多智能體協(xié)作整合在一起,本文從ReAct推理循環(huán)、工具系統(tǒng)、記憶管理、多智能體協(xié)作和生產(chǎn)就緒特性五個(gè)維度,深入剖析了框架的核心機(jī)制,感興趣的朋友一起看看吧
    2025-12-12
  • JDBC的基本操作與Statement和PreparedStateMent使用區(qū)別分析

    JDBC的基本操作與Statement和PreparedStateMent使用區(qū)別分析

    這篇文章主要介紹了JDBC的基本操作與Statement和PreparedStateMent使用區(qū)別,Java Database Connectivity,它是代表一組獨(dú)立于任何數(shù)據(jù)庫(kù)管理系統(tǒng)(DBMS)的API,聲明在java.sql與javax.sql包中,是SUN(現(xiàn)在Oracle)提供的一組接口規(guī)范
    2023-04-04
  • Maven多模塊項(xiàng)目調(diào)試與問(wèn)題排查的完整指南

    Maven多模塊項(xiàng)目調(diào)試與問(wèn)題排查的完整指南

    在現(xiàn)代企業(yè)級(jí)Java開(kāi)發(fā)中,Maven多模塊項(xiàng)目因其清晰的代碼組織,依賴管理和高效的構(gòu)建流程已成為主流架構(gòu)模式,本文深入剖析多模塊項(xiàng)目的四大核心痛點(diǎn)解決方案,感興趣的小伙伴可以跟隨小編一起了解下
    2025-06-06
  • spring cloud gateway如何獲取請(qǐng)求的真實(shí)地址

    spring cloud gateway如何獲取請(qǐng)求的真實(shí)地址

    這篇文章主要介紹了spring cloud gateway如何獲取請(qǐng)求的真實(shí)地址問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • java加載properties文件的六種方法總結(jié)

    java加載properties文件的六種方法總結(jié)

    這篇文章主要介紹了java加載properties文件的六種方法總結(jié)的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • 關(guān)于slf4j_log4j2源碼學(xué)習(xí)心得

    關(guān)于slf4j_log4j2源碼學(xué)習(xí)心得

    這篇文章主要介紹了slf4j_log4j2源碼學(xué)習(xí)心得,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • SpringBoot使用MockMvc測(cè)試get和post接口的示例代碼

    SpringBoot使用MockMvc測(cè)試get和post接口的示例代碼

    Spring Boot MockMvc是一個(gè)用于單元測(cè)試的模塊,它是Spring框架的一部分,專注于簡(jiǎn)化Web應(yīng)用程序的測(cè)試,MockMvc主要用來(lái)模擬一個(gè)完整的HTTP請(qǐng)求-響應(yīng)生命周期,本文給大家介紹了SpringBoot使用MockMvc測(cè)試get和post接口,需要的朋友可以參考下
    2024-06-06
  • Java中ArrayBlockingQueue和LinkedBlockingQueue

    Java中ArrayBlockingQueue和LinkedBlockingQueue

    這篇文章主要介紹了Java中ArrayBlockingQueue和LinkedBlockingQueue,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下
    2022-09-09

最新評(píng)論

安仁县| 万源市| 青州市| 会同县| 富宁县| 柳江县| 舟曲县| 科尔| 府谷县| 井陉县| 陈巴尔虎旗| 集安市| 嘉善县| 黑山县| 贵德县| 延边| 凤凰县| 确山县| 青阳县| 轮台县| 瓮安县| 公安县| 深州市| 陇西县| 垦利县| 昌吉市| 黑河市| 绵竹市| 新沂市| 英德市| 鄂伦春自治旗| 呼玛县| 乐至县| 沛县| 剑阁县| 广灵县| 文登市| 那曲县| 香港| 南陵县| 丰台区|