閑聊 Hash 算法

最近讀了一篇好文:【微信高并發(fā)資金交易系統(tǒng)設計方案——百億紅包背后的技術支撐】,其中關于高并發(fā)性能問題的解決方案中怎顾,有應用 hash 算法的思想。想起公眾號后臺里斷斷續(xù)續(xù)有讀者提起算法方面的問題,覺得可以寫篇文章聊聊算法中的 hash 算法戳气。順道科普下算法與數(shù)據(jù)結構的重要性句各。

開講前吸占,先跑題閑聊下程序員的技術功底。我常說每個程序員都有自己獨特的技術視野和知識盲區(qū)凿宾,不同程序員之間很難因為某些知識點儲備不一樣而分個高低好壞矾屯。但我們工作當中,又能明顯感覺不同團隊成員之間的技術水平存在差異初厚,到底差在哪呢件蚕?很多人調侃批量生產(chǎn)的培訓程序員,那這些人和四年的大學本科之間又有多少距離产禾?僅僅是時間嗎骤坐?

差在基本功,基本功有很多項下愈,數(shù)據(jù)結構與算法就是其中之一纽绍。雖然是基本功,卻是最難儲備和最易忽視的势似。行業(yè)越浮躁拌夏,變化越快,開發(fā)平臺越便捷履因,高級 API 越多障簿,基本功的重要性就越容易被忽視。即使能意識到基礎薄弱栅迄,肯下定決心騰出幾個月時間惡補基本功不是件容易的事站故,尤其是參加工作后,瑣事繁多,一時熱血下定的決心能堅持一周都屬不易西篓。后臺偶爾有人問及程序員如何進階的問題愈腾,以我這些年所經(jīng)驗,回過頭來夯實下基礎岂津,對大部分人都會有奇效虱黄。

數(shù)據(jù)結構與算法的學習難度經(jīng)常被夸大,不少人甚至談算法色變吮成,尤其無法忍受在面試當中問及算法問題橱乱。其實多點兒耐心,多投入些時間粱甫,學習算法并不難泳叠。至少學習基礎的算法并不難,理解算法和去 leetcode 刷題是兩回事茶宵,刷題所涉及的算法多需要技巧危纫,基礎的算法知識和其他計算機知識一樣,不需要特別「聰明」的大腦节预,大多數(shù)人都能學會叶摄。Peak 君沒刷過題属韧,但對算法方面的知識也比較有自信安拟。

數(shù)據(jù)結構和算法是相輔相成的,基礎的其實就那么些:時間復雜度的概念宵喂,List糠赦,Array,Stack锅棕,Queue拙泽,Tree 等。Graph 實際應用中較少遇到裸燎,可以不做深入了解顾瞻,但 BFS,DFS德绿,Dijkstra 還是應該知道荷荤。基礎的算法需要能達到手寫的程度移稳,比如排序至少能寫出兩種時間復雜度為 N*logN 的算法蕴纳。理解這些比去 leetcode 刷題重要,學習難度也并不高个粱。學習這些的意義在于掌握解決問題的基礎思路古毛,形成計算機思維,比如 divide and conque都许,recursive 等常規(guī)思想稻薇。

再回到本文重點 hash 算法嫂冻。關于 hash 算法的實現(xiàn)原理和關鍵概念,網(wǎng)絡上已有不少好文加以介紹颖低。本文不做原理層面的解釋絮吵,只談應用。對實現(xiàn)感興趣的可以搜索關鍵字:hash忱屑,load factor蹬敲,擴容,hash 沖突解決等莺戒。

Objective C 中對于 hash 的應用主要封裝在兩個數(shù)據(jù)類當中:NSDictionary 和 NSSet伴嗡。這點大家都知道,hash 算法能以空間換時間从铲,在 NSDictionary 和 NSSet 中瘪校,判斷一個元素是否存在只需要 O(1) 的時間復雜度。這一特點也使得在一些需要快速存取元素的場景名段,比如 Cache 設計阱扬,也能看到 NSDictionary 的身影。當然 hash 的應用遠不止如此伸辟,做的應用越多麻惶,解決問題越深入,碰到 hash 算法的概率也會更高信夫。

「The Algorithm Design Manual」一書中提到窃蹋,雅虎的 Chief Scientist ,Udi Manber 曾說過静稻,在 yahoo 所應用的算法中警没,最重要的三個是:hash,hash 和 hash振湾。其重要性不言而喻杀迹。書中還舉了一個很有趣的應用例子,請聽題:

一場拍賣會中押搪,物品是價高者得树酪,如果每個人只有一次出價機會,同時提交自己的價格后嵌言,最后一起公布嗅回,出價最高則勝出。這種形式存在作弊的可能摧茴,如果有出價者能 hack 進后臺绵载,然后將自己的價格改為最高價 + 1,則能以最低的代價獲得勝利。如何杜絕這種作弊呢娃豹?

三分鐘思考時間焚虱,一,二懂版,三鹃栽。

參與者都提交自身出價的 hash 值就可以了,即使有人能黑進后臺也無法得知明文價格躯畴,等到公布之時民鼓,再對比原出價與 hash 值是否對應即可。是不是很巧妙蓬抄?

看到這丰嘉,可能有朋友想到了 MD5,SHA嚷缭。是的饮亏,上面的做法,和我們在 server 端存儲密碼的 MD5 值而非明文阅爽,是同一種思想路幸,殊途同歸。hash 算法包含有多種解決問題的思路付翁,這里可以歸納為【通過 hash简肴,生成不可逆的信息摘要】。

書里還有關于 hash 應用的其他有趣的場景(比如論文內容抄襲檢測)胆敞,都值得一讀着帽。

回到微信紅包的例子杂伟,后臺工程師為了防止搶紅包時移层,用戶的流量都涌進同個服務器,在同個 DB 上讀寫而導致的性能下降赫粥,采用了通過 hash 算法來分流的策略观话。每個紅包創(chuàng)建的時候分配一個 ID,通過算法將 ID 映射到不同的邏輯服務器越平,一氣呵成的解決方案频蛔。這里體現(xiàn)的是 hash 算法的另一種思想:【hash 能以 O(1)的復雜度將內容映射到位置】。這種應用 hash 的思路非常常見秦叛,還有不少例子晦溪。

去年寫過一篇多線程文章【正確使用多線程同步鎖@synchronized()】,當時閱讀 OC 源碼的時候也看到了 hash 的身影挣跋。@synchronized(token) 中的 token 通過 hash 算法存儲到了一份手動維護的 cache 中三圆,cache 的 key 使用的是 token 的內存地址。@synchronized 使用多了之后,如何快速的通過 token 取出對應的鎖舟肉,對多線程的性能至關重要修噪。hash 算法恰能以 O(1)的時間復雜度,以 token 為 key 取出對應的鎖路媚,和上面紅包的例子本質上是同一種思想黄琼。即內容與位置之間的快速映射關系。

我還見到過很多例子整慎,多多少少都有 hash 算法的影子脏款。大家說 hash 算法是不是很重要?數(shù)據(jù)結構與算法是不是要學裤园?不懂算法弛矛,有時候看別人代碼就真如「過眼云煙」了,觀其形而不知其意比然。別人賞雪丈氓,心中所念是:「都城十日雪,庭戶皓已盈」强法,你只能一句「我靠万俗!好美!」以抒胸臆饮怯,豈不煞風景闰歪?

之前有幾位讀者在后臺留言,求算法書推薦蓖墅。算法方面的好書有不少库倘,不過大多是英文的,除去一些專業(yè)術語外论矾,多是一些簡單的詞匯教翩,閱讀難度不算大,維堅持二字贪壳。推薦一本現(xiàn)今還留有印象的:《編程珠璣》饱亿,英文名《Programming Pearls》,不是大部頭闰靴,建議啃英文原版彪笼。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市蚂且,隨后出現(xiàn)的幾起案子配猫,更是在濱河造成了極大的恐慌,老刑警劉巖杏死,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件泵肄,死亡現(xiàn)場離奇詭異佳遣,居然都是意外死亡,警方通過查閱死者的電腦和手機凡伊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進店門零渐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人系忙,你說我怎么就攤上這事诵盼。” “怎么了银还?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵风宁,是天一觀的道長。 經(jīng)常有香客問我蛹疯,道長戒财,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任捺弦,我火速辦了婚禮饮寞,結果婚禮上,老公的妹妹穿的比我還像新娘列吼。我一直安慰自己幽崩,他們只是感情好,可當我...
    茶點故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布寞钥。 她就那樣靜靜地躺著慌申,像睡著了一般。 火紅的嫁衣襯著肌膚如雪理郑。 梳的紋絲不亂的頭發(fā)上蹄溉,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天,我揣著相機與錄音您炉,去河邊找鬼柒爵。 笑死,一個胖子當著我的面吹牛邻吭,可吹牛的內容都是我干的餐弱。 我是一名探鬼主播宴霸,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼囱晴,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了瓢谢?” 一聲冷哼從身側響起畸写,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎氓扛,沒想到半個月后枯芬,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體论笔,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年千所,在試婚紗的時候發(fā)現(xiàn)自己被綠了狂魔。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡淫痰,死狀恐怖最楷,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情待错,我是刑警寧澤籽孙,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站火俄,受9級特大地震影響犯建,放射性物質發(fā)生泄漏。R本人自食惡果不足惜瓜客,卻給世界環(huán)境...
    茶點故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一适瓦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧谱仪,春花似錦犹菇、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至卸例,卻和暖如春称杨,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背筷转。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工姑原, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人呜舒。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓锭汛,卻偏偏與公主長得像,于是被迫代替她去往敵國和親袭蝗。 傳聞我的和親對象是個殘疾皇子唤殴,可洞房花燭夜當晚...
    茶點故事閱讀 45,044評論 2 355

推薦閱讀更多精彩內容

  • 數(shù)據(jù)結構和算法是相輔相成的,基礎的其實就那么些:時間復雜度的概念到腥,List朵逝,Array,Stack乡范,Queue配名,T...
    其實也沒有閱讀 305評論 0 0
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,167評論 25 707
  • 你贏我陪你君臨天下啤咽,你輸我陪你醉酒天涯
    愛昔閱讀 207評論 0 1
  • 我使用的是android studio 1.1,新建項目后Activity繼承ActionBarActivity,...
    SHUTUP閱讀 8,772評論 0 1
  • 以前對學生總是批評多渠脉,鼓勵少宇整。作業(yè)不交,上課說話芋膘,集合散漫没陡,我對他們總是沒有好臉色。今天拔河索赏,驀然發(fā)覺盼玄,平時不愛學...
    采采芣苡閱讀 211評論 0 0