我們前面講到雜湊表,雜湊函式,這裡又是雜湊演算法,實際上,雜湊函式就是雜湊演算法的乙個特例。只不過在雜湊表中,我們通常希望雜湊函式簡單,才不會影響查詢等的效能。雜湊演算法的定義和原理很簡單,就是把任意二進位制串值對映為固定長度的二進位制值串,這個對映的規則就是雜湊演算法,而通過原始的資料對映之後得到的二進位制值串就是雜湊值。
雜湊演算法滿足的幾點要求:
最常用的加密演算法是md5,和sha。對用於加密的雜湊演算法來說,有兩點格外重要。第一點是很難根據雜湊值反向推導出原始資料,第二點是雜湊衝突的概率很小。
實際上,不管是什麼雜湊演算法,我們只能儘量減少碰撞衝突的概率,理論上是沒有辦法做到完全不衝突的。這裡基於組合數學乙個非常基礎的理論,鴿巢原理。如果有10個鴿巢,有11只鴿子,那肯定有乙個鴿巢中的鴿子數量多於1個。
同樣的,雜湊演算法產生的雜湊值的長度是固定且有限的。比如前面的md5演算法,雜湊值是固定的128位,能表示的資料是有限的,但是我們要雜湊的資料是無窮的,基於鴿巢原理,如果我們對2^128+1個資料求雜湊值,就必定會存在乙個雜湊值相同的情況。一般情況下,雜湊值越長的雜湊演算法,雜湊衝突的概率越低。
不過,即使雜湊演算法存在雜湊衝突的情況,但是因為雜湊值的範圍很大,衝突的概率很低,所以相對來說還是很難破解的。
舉個例子,如果要在海量的相簿中,搜尋一張圖是否存在,我們不能單純地用的原資訊(比如名稱)來對比,因為有可能存在名稱相同但名稱不同,或者名稱不同內容相同的情況。
我們知道,任何檔案在計算中都可以表示成二進位製碼串。我們可以給每乙個取乙個唯一標識或者說是資訊摘要。我們可以從的二進位制串開頭取100個位元組,從中間取100個位元組,從最後取100個位元組,然後將這300個位元組放到一起,通過雜湊演算法,得到乙個雜湊字串,用它來做的唯一標識。通過這個唯一標識來判定是否在相簿中,這樣就可以減少很多任務作量。
如果還想繼續提高效率,我們可以以唯一標識作為key,相應的檔案在相簿中的路徑資訊作為value,構建乙個雜湊表。當要檢視某個是否在相簿中的時候,我們先通過雜湊演算法對這個取唯一的標識,然後在雜湊表中查詢。
假設我們使用鍊錶法來解決衝突,我們通過一張取唯一標識,經過雜湊函式得到陣列下標,看這個槽中的唯一標識是否相同,如果不相同,則說明不存在,如果相同,為了提高準確率,我們在利用雜湊表中儲存的檔案標識,進行全圖比對。
如何實現乙個會話粘滯的負載均衡演算法?也就是說,我們需要在同乙個客戶端上,在一次會話中的請求都路由到同乙個伺服器上。如我們可以通過雜湊演算法,對客戶端id位址或者會話id計算雜湊值,將取得的雜湊值與伺服器列表的大小進行取模運算,最終得到的值就是應該被路由到的伺服器端號。這樣,我們就可以把同乙個ip過來的所有請求,都路由到同乙個後端伺服器上。
假設我們的相簿有1億張,顯然,在單台機器上構建雜湊表是行不通的。因為單台機器的記憶體有限,而1億張構建雜湊表顯然遠遠超過了單台機器的記憶體上限。
我們可以對資料進行分片,然後採用多機處理。我們準備n臺機器,讓每台機器只維護某一部分對應的雜湊表。我們每次從相簿中讀取乙個,計算唯一標識,然後與機器個數n求餘取模,得到的值就是要對應要分配的機器編號,然後將這個的唯一標識和的路徑發往相應的機器構建雜湊表。
當我們要判斷乙個是否在相簿的時候,我們通過同樣的雜湊演算法,計算這個的唯一標識,然後與機器個數n求餘取模,假設我們得到的是k,然後我們就去編號為k的機器構建的雜湊表中查詢。
實際上,針對這種海量資料的處理問題,我們都可以採用多機分布式處理。借助這種分布的思路,可以突破單機記憶體,cpu等資源的限制。
對於海量的資料,海量的使用者。我們為了提高資料的讀取,寫入能力,一般都採用分布式的方式來儲存資料,比如分布式快取,如果有海量的資料需要快取,乙個快取機器肯定不夠,於是,我們就需要將資料分布到多台機器上。
我們可以借用前面的資料分片的方法,通過雜湊演算法對資料計算雜湊值,得到機器編號。但是如果資料增多,這10個機器不夠了怎麼辦?這裡就不是加乙個機器那麼簡單了,因為所有的資料都需要重新計算雜湊值。這個時候,我們需要一種方法,使得再加入乙個機器後,並不需要大量的資料搬移。這個時候,我們需要使用一致性雜湊演算法。
假設我們有k個機器,資料的雜湊值的範圍是[0,max],我們將整個範圍劃分為m個小的區間(m遠大於k),每個機器負責m/k個小區間。當有先機器加入的時候,我們就將某幾個小區間的資料,從原來的機器搬移到新的機器上。這樣就不用全部重新計算並且搬移了。
《資料結構與演算法之美》9講學習筆記
一 什麼是佇列?1.先進者先出,這就是典型的 佇列 結構。2.支援兩個操作 入隊enqueue 放乙個資料到隊尾 出隊dequeue 從隊頭取乙個元素。3.所以,和棧一樣,佇列也是一種操作受限的線性表。二 如何實現佇列?1.佇列api public inte ce queue2.陣列實現 順序佇列 ...
資料結構和演算法之美 22 雜湊演算法
實現乙個會話粘滯 session sticky 的負載均衡的演算法即在同乙個客戶端上一次會話的所有請求都能路由到同乙個伺服器上。最簡單的辦法就是維護一張對映表,對映表中記錄會話id或者客戶端ip與伺服器編號的對映關係。客戶端每次發出的請求都先到對映表中查詢伺服器對應的編號,再請求編號對應的伺服器。這...
資料結構與演算法之美
什麼是資料結構?什麼是演算法 狹義重點 複雜度分析 方法 邊學邊練,適度刷題 複雜度分析 時間複雜度 常見時間複雜度 非多項式量級 非常低效的演算法 空間複雜度 漸進空間複雜度,表示演算法的儲存空間和資料規模的增長關係 最好情況時間複雜度 理想情況的時間複雜度 最壞情況時間複雜度 最糟糕的情況下的時...