在海量數(shù)據(jù)如何確定一個(gè)值是否存在?這是一道非常經(jīng)典的面試場(chǎng)景題。
那怎么回答這個(gè)問(wèn)題呢?接下來(lái)咱們就詳細(xì)的聊一聊。
判斷一個(gè)值是否存在?通常有以下兩種解決方案:
它們兩的相同點(diǎn)是:它們都存在誤判的情況。例如,使用哈希表時(shí),不同元素的哈希值可能相同,所以這樣就產(chǎn)生誤判了;而布隆過(guò)濾器的特征是,當(dāng)布隆過(guò)濾器說(shuō),某個(gè)數(shù)據(jù)存在時(shí),這個(gè)數(shù)據(jù)可能不存在;當(dāng)布隆過(guò)濾器說(shuō),某個(gè)數(shù)據(jù)不存在時(shí),那么這個(gè)數(shù)據(jù)一定不存在。
它們兩的區(qū)別主要有以下幾點(diǎn):
哈希表和布隆過(guò)濾器都能實(shí)現(xiàn)判重,但它們都會(huì)存在誤判的情況,但布隆過(guò)濾器存儲(chǔ)占用的空間更小,更適合海量數(shù)據(jù)的判重。
布隆過(guò)濾器的實(shí)現(xiàn),主要依靠的是它數(shù)據(jù)結(jié)構(gòu)中的一個(gè)位數(shù)組,每次存儲(chǔ)鍵值的時(shí)候,不是直接把數(shù)據(jù)存儲(chǔ)在數(shù)據(jù)結(jié)構(gòu)中,因?yàn)檫@樣太占空間了,它是利用幾個(gè)不同的無(wú)偏哈希函數(shù),把此元素的 hash 值均勻的存儲(chǔ)在位數(shù)組中,也就是說(shuō),每次添加時(shí)會(huì)通過(guò)幾個(gè)無(wú)偏哈希函數(shù)算出它的位置,把這些位置設(shè)置成 1 就完成了添加操作。
當(dāng)進(jìn)行元素判斷時(shí),查詢(xún)此元素的幾個(gè)哈希位置上的值是否為 1,如果全部為 1,則表示此值存在,如果有一個(gè)值為 0,則表示不存在。因?yàn)榇宋恢檬峭ㄟ^(guò) hash 計(jì)算得來(lái)的,所以即使這個(gè)位置是 1,并不能確定是那個(gè)元素把它標(biāo)識(shí)為 1 的,因此布隆過(guò)濾器查詢(xún)此值存在時(shí),此值不一定存在,但查詢(xún)此值不存在時(shí),此值一定不存在。
并且當(dāng)位數(shù)組存儲(chǔ)值比較稀疏的時(shí)候,查詢(xún)的準(zhǔn)確率越高,而當(dāng)位數(shù)組存儲(chǔ)的值越來(lái)越多時(shí),誤差也會(huì)增大。
位數(shù)組和 key 之間的關(guān)系,如下圖所示:
布隆過(guò)濾器的實(shí)現(xiàn)通常有以下兩種方案:
使用 Google Guava 庫(kù)實(shí)現(xiàn)布隆過(guò)濾器總共分為以下兩步:
具體實(shí)現(xiàn)如下。
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId></dependency>import com.google.common.hash.BloomFilter;import com.google.common.hash.Funnels;public class BloomFilterExample { public static void main(String[] args) { // 創(chuàng)建一個(gè)布隆過(guò)濾器,設(shè)置期望插入的數(shù)據(jù)量為10000,期望的誤判率為0.01 BloomFilter<String> bloomFilter = BloomFilter.create(Funnels.unencodedCharsFunnel(), 10000, 0.01); // 向布隆過(guò)濾器中插入數(shù)據(jù) bloomFilter.put("data1"); bloomFilter.put("data2"); bloomFilter.put("data3"); // 查詢(xún)?cè)厥欠翊嬖谟诓悸∵^(guò)濾器中 System.out.println(bloomFilter.mightContain("data1")); // true System.out.println(bloomFilter.mightContain("data4")); // false }}在上述示例中,我們通過(guò) BloomFilter.create() 方法創(chuàng)建一個(gè)布隆過(guò)濾器,指定了元素序列化方式、期望插入的數(shù)據(jù)量和期望的誤判率。然后,我們可以使用 put() 方法向布隆過(guò)濾器中插入數(shù)據(jù),使用 mightContain() 方法來(lái)判斷元素是否存在于布隆過(guò)濾器中。
在海量數(shù)據(jù)如何確定一個(gè)值是否存在?通常有兩種解決方案:哈希表和布隆過(guò)濾器,而它們兩都存在誤判的情況,但布隆過(guò)濾器更適合海量數(shù)據(jù)的判斷,因?yàn)樗加玫臄?shù)據(jù)空間更小。布隆過(guò)濾器的特征是:當(dāng)布隆過(guò)濾器說(shuō),某個(gè)數(shù)據(jù)存在時(shí),這個(gè)數(shù)據(jù)可能不存在;當(dāng)布隆過(guò)濾器說(shuō),某個(gè)數(shù)據(jù)不存在時(shí),那么這個(gè)數(shù)據(jù)一定不存在。
本文鏈接:http://m.www897cc.com/showinfo-26-10404-0.html場(chǎng)景題:海量數(shù)據(jù)如何判重?
聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com
上一篇: IDC下調(diào)中國(guó)政務(wù)云整體市場(chǎng)5年復(fù)合增長(zhǎng)率至16.14%
下一篇: 性能測(cè)試的需求分析