日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

算法练习day12——190331(哈希函数、哈希表、布隆过滤器、一致性哈希)

發(fā)布時間:2024/10/14 70 豆豆
生活随笔 收集整理的這篇文章主要介紹了 算法练习day12——190331(哈希函数、哈希表、布隆过滤器、一致性哈希) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1.哈希函數(shù)

1.1 特點:

  • 經(jīng)典的哈希函數(shù)輸入域是無窮大的。
  • 輸出域是有窮盡的;
  • 相同輸入得到的輸出肯定是一樣的;
  • 不同的輸入得到的輸出也可能一樣(輸入域>輸出域);
  • 哈希函數(shù)的離散型:給定多個不同的輸入,得到的輸出在輸出域上均勻分布。
    • 可用來打亂輸入規(guī)律,輸出的規(guī)律和輸入規(guī)律是沒有關(guān)系的。
    • 若輸出在整個輸出域上均勻分布,那么輸出mod m之后得到的結(jié)果在0~m-1上也是均勻分布的。

    1.2 由給定的一個哈希函數(shù)得到1000個互相獨立的哈希函數(shù)

    假設(shè)給定哈希函數(shù)h,它的輸出是16位的。

    將其高8位作為h1,低8位作為h2。h1和h2相互獨立,因為16位輸出中的每一位都和其他位無關(guān)。

    那么,可構(gòu)造:

    • ...

    構(gòu)造的多個哈希函數(shù)之間是相互獨立的。

    2.哈希表

    2.1 put(K,V)

    hashCode(K)-->h1

    將(K,V)放到下標為h1的桶中:

    • 若桶不空,則判斷有無K;
      • 有,V若不等,則更新V;
      • 無,直接將(K,V)鏈在此桶元素的后面。

    若桶中的鏈較長,需要擴容。

    重新以新容量進行hashCode的運算。

    各種操作都是級別的。即使擴容操作費時,但這操作不頻繁,也可以押得很低。(還可在離線的時候進行擴容,不占用在線時間)。

    JVM中每個桶中放的是一棵紅黑樹。不太需要擴容。

    有一個100T的大文件,其中每一行存的是一個字符串,去掉其中重復(fù)的字符串。假設(shè)可用的機器為1000臺。

    具體做法:

    用哈希函數(shù)作分流——讀出每一行字符串,然后進行hashCode計算,之后模1000。這樣相同的字符串就會分配到同一臺機器。——利用哈希函數(shù)可以將100T大文件中的字符串(假設(shè)M種 )按種類平均分配到1000臺機器上。

    3.設(shè)計RandomPool結(jié)構(gòu)

    【題目】 設(shè)計一種結(jié)構(gòu), 在該結(jié)構(gòu)中有如下三個功能:

    • insert(key): 將某個key加入到該結(jié)構(gòu), 做到不重復(fù)加入。
    • delete(key): 將原本在結(jié)構(gòu)中的某個key移除。
    • getRandom():等概率隨機返回結(jié)構(gòu)中的任何一個key。

    【要求】 Insert、 delete和getRandom方法的時間復(fù)雜度都是O(1)

    3.1 分析

    哈希表的結(jié)構(gòu)中:

    • 若數(shù)據(jù)量較少,有的桶可能會沒元素,此時無法做到均勻取出(遍歷取出的話,復(fù)雜度會達到O(N))
    • 若數(shù)據(jù)量較多,每個桶中的鏈長度也不是絕對相等的。無法做到等待率。

    本題中使用兩個哈希表map1和map2實現(xiàn)。

    比如A元素是第0個進來的,那么:

    • 在map1中就存(A,0)——A是第0個進來的;
    • 在map2中存(0,A)——第0個進來的是A。

    同時需要有個int型的變量記錄某個元素是第幾個進來的。

    3.1.1 先考慮add(),忽略remove()。

    • 若目前進來了26個元素,size=26,此時調(diào)用了getRandom():
      • 使用Math.random()*size生成0~25中隨機一個數(shù)indexm;
      • 然后在map2中由Key=index找到對應(yīng)的value,返回 。

    3.2.1 remove()

    若刪除時不做任何操作,則在刪除之后,會產(chǎn)生多個“洞”,使得在計算index時無法做到等概率,因為某些位置上沒元素。

    假設(shè)有1000條記錄(str0~str999),現(xiàn)在要刪除str17,在刪除時:

    • map1中:將str999放在str17的位置(即,將自己的value改為17即可);
    • map2中:將str999放在17的位置上(即,將自己的key改為17即可,也就是將17對應(yīng)的value由str17改為str999);
    • 刪除map1和map2中的最后一條記錄;
    • size-1=999.

    保證了存儲數(shù)據(jù)位置的連續(xù)。

    3.2 代碼實現(xiàn)

    package Hash;import java.util.HashMap;public class RandomPoolTest {public static class RandomPool{HashMap<String,Integer> map1;HashMap<Integer,String> map2;int size;public RandomPool() {this.map1=new HashMap<>();this.map2=new HashMap<>();this.size=0;}public void insert(String str) {if(!this.map1.containsKey(str)) {this.map1.put(str, this.size);this.map2.put(this.size, str);this.size++;}}public void delete(String str) {if(this.map1.containsKey(str)) {int index=this.map1.get(str);String laststr=this.map2.get(--this.size);this.map1.put(laststr, index);this.map2.put(index, laststr);this.map1.remove(str);this.map2.remove(index);size--;}}public String getRandom() {if(size==0)return null;int index=(int)(Math.random()*size);return this.map2.get(index);}} }

    4.布隆過濾器

    4.1 簡介

    應(yīng)用場景:判斷某一個東西是否在一個集合中(布隆過濾器本身就是一個集合)

    舉例:看一個url是否在已有的黑名單(100億個64字節(jié)的url)中,在返回true,不在返回false。

    若使用哈希函數(shù),不存value,則使用HashSet,最起碼需要6400億字節(jié)(640G)才能把所有的黑名單url裝下。

    缺點:有失誤率

    • 若一個url確實屬于黑名單,則它肯定返回true;
    • 若一個url不在黑名單中,可能返回true,也可能返回false。

    布隆過濾器是一個比特類型的map

    int[] arr=new int[1000]; //一個整型是4個字節(jié),32個比特,則int[] arr=new int[1000];一句申請了32000個比特位int index=30000;int intIndex=index/32;//由除數(shù)定位到給定的數(shù)在哪個桶中(一個桶32bit) int bitIndex=intIndex%32;//由余數(shù)定位到給定的數(shù)在桶中的具體哪個比特位上

    arr[intIndex]=arr[intIndex]|(1<<bitIndex);

    1左移16位=num——>只有第16位上為1,其余為0;

    arr[937]和num進行或運算,則num的第16位就置為1了——表示30000這個值在集合中存在了。

    怎么得到比特數(shù)組?

    用基礎(chǔ)類型拼,類似于前面的int[1000]——32000個比特位;

    若給定的index太大,可換為long[1000]——64000個比特位;

    若還是很大,可換為long[1000][1000]——1000*1000*64個比特位。

    4.2 上面黑名單的實現(xiàn)

    4.2.1 分析

    一個url進入布隆過濾器的過程:

    • 先使用哈希函數(shù)h將url變?yōu)橐粋€hashcode,
    • 然后hashcode%m得到一個范圍在0~m-1的值;
    • 將得到的值對應(yīng)于數(shù)組的位置上的值置為1.
    • 布隆過濾器是使用k個哈希函數(shù)h1~hk,計算k個hashcode,將得到的k個位置上的值置為1.

    查一個url是否在黑名單中:

    • 將這個url進入k個哈希函數(shù)的運算,得到k個值;
    • 在給定的數(shù)組中查看這k個值對應(yīng)的位置是否都為1;
      • 若都為1,返回true;
      • 否則返回false。

    數(shù)組范圍應(yīng)長一點,要不100億個url進去之后,幾乎所有的位置都已置為1了,無法查詢——所有的url查詢都會返回true。

    • 空間越大,失誤率越低;
    • 空間越小,失誤率越高。

    哈希函數(shù)的個數(shù)k,只和url個數(shù)有關(guān)系,和url具體大小,多少字節(jié)無關(guān)。

    比特數(shù)組大小m的計算公式:

    • n:樣本量——100億;
    • p:預(yù)期失誤率——萬分之一0.0001
    • m:單位是bit,算出來小數(shù)的話,向上取整。

    k也是向上取整

    當k和m向上取整之后,真實的錯誤率為:

    【當給定題目后,首先給出經(jīng)典解法,——占用空間太大——允不允許失誤率?——允許——講解布隆過濾器、算出m(在給定范圍內(nèi)盡量大),K,再算出真正的失誤率,比給定的失誤率要低——】

    若在乎I/O,則將m內(nèi)存分布式存儲;

    5.一致性哈希

    5.1 經(jīng)典服務(wù)器抗壓結(jié)構(gòu)

    當需要加減機器的時候,這個結(jié)構(gòu)就不合適了。所有已存儲的數(shù)據(jù)歸屬全變了。

    ——引入了一致性哈希結(jié)構(gòu)

    5.2 一致性哈希

    可降低數(shù)據(jù)遷移的代價,同時又負載均衡。

    將哈希函數(shù)的返回值()想象為一個環(huán):

    有3臺機器m1、m2、m3,假設(shè)它們是以IP進行區(qū)分的。

    • 將m1、m2、m3的IP串經(jīng)過哈希運算,對應(yīng)到環(huán)上一點。

    假設(shè)存儲(zuo,31),將zuo 進行哈希運算后,不用進行模運算,直接對應(yīng)到環(huán)上一點:

    順時針找到離zuo在環(huán)上這一點最近的機器(m2),將(zuo,31)存儲在此機器上。

    查的時候也一樣。

    5.2.1 實現(xiàn)

    后端還是三臺機器,前端還是無差別的負載服務(wù)器。

    將m1、m2、m3的哈希值排序(有小到大)后組成一個數(shù)組{m1,m2,m3},將這個數(shù)組存到前端的每一個服務(wù)器中。

    當zuo進來后,以二分查找的方式確定它在那個機器上:

    • 知道第一個大于等于zuo的哈希值的機器哈希值(以順時針選的機器)。

    現(xiàn)在需要添加一個機器m4,將它的IP經(jīng)過哈希運算映射到如圖所示的點中:

    則需要做數(shù)據(jù)遷移的部分如圖所示:

    哈希函數(shù)的性質(zhì)保證的是:量多的情況下,機器數(shù)據(jù)量均分。

    這種結(jié)構(gòu)存在的問題是,機器負載會不均衡。

    虛擬節(jié)點技術(shù)可以解決這個問題。

    5.3 虛擬節(jié)點技術(shù)

    有三臺機器:m1、m2、m3

    給每個節(jié)點分配1000個虛擬節(jié)點:

    • m1:m1-1,m1-2,m1-3,...
    • m2:...
    • m3:...

    準備一個物理映射表:

    • 可以從表中得知一個機器有哪些節(jié)點;
    • 也可知道一個節(jié)點屬于哪個機器。

    令這3000個虛擬節(jié)點搶環(huán)上的位置,由虛擬節(jié)點負責的域,實際上是讓它屬于的實際機器去處理。——這樣就使得三臺機器負責的區(qū)域是差不多的。

    加機器m4時,它也擁有1000個虛擬節(jié)點,這些虛擬節(jié)點進環(huán),瓜分之前節(jié)點的負責的區(qū)域。

    淡化物理機器的概念,強調(diào)虛擬節(jié)點的概念。

    5.5 應(yīng)用場景

    用到集群特性,抗壓的

    ?

    ?

    ?

    總結(jié)

    以上是生活随笔為你收集整理的算法练习day12——190331(哈希函数、哈希表、布隆过滤器、一致性哈希)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。