你是不是覺得數(shù)據(jù)結(jié)構(gòu)和算法渣玲,跟操作系統(tǒng)逗概、計(jì)算機(jī)網(wǎng)絡(luò)一樣,是脫離實(shí)際工作的知識柜蜈?可能除了面試仗谆,這輩子也用不著指巡?
盡管計(jì)算機(jī)相關(guān)專業(yè)的同學(xué)在大學(xué)都學(xué)過這門課程淑履,甚至很多培訓(xùn)機(jī)構(gòu)也會培訓(xùn)這方面的知識,但是據(jù)我了解藻雪,很多程序員對數(shù)據(jù)結(jié)構(gòu)和算法依舊一竅不通秘噪。還有一些人也只聽說過數(shù)組、鏈表勉耀、快排這些最最基本的數(shù)據(jù)結(jié)構(gòu)和算法指煎,稍微復(fù)雜一點(diǎn)的就完全沒概念蹋偏。
當(dāng)然,也有很多人說至壤,自己實(shí)際工作中根本用不到數(shù)據(jù)結(jié)構(gòu)和算法威始。所以,就算不懂這塊知識像街,只要 Java API黎棠、開發(fā)框架用得熟練,照樣可以把代碼寫得“飛”起來镰绎。事實(shí)真的是這樣嗎脓斩?
今天我們就來詳細(xì)聊一聊,為什么要學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)和算法畴栖。
想要通關(guān)大廠面試随静,千萬別讓數(shù)據(jù)結(jié)構(gòu)和算法拖了后腿
很多大公司,比如 BAT吗讶、Google燎猛、Facebook,面試的時候都喜歡考算法照皆、讓人現(xiàn)場寫代碼扛门。有些人雖然技術(shù)不錯,但每次去面試都會“跪”在算法上纵寝,很是可惜论寨。那你有沒有想過,為什么這些大公司都喜歡考算法呢爽茴?
校招的時候葬凳,參加面試的學(xué)生通常沒有實(shí)際項(xiàng)目經(jīng)驗(yàn),公司只能考察他們的基礎(chǔ)知識是否牢固室奏。社招就更不用說了火焰,越是厲害的公司,越是注重考察數(shù)據(jù)結(jié)構(gòu)與算法這類基礎(chǔ)知識胧沫。相比短期能力昌简,他們更看中你的長期潛力。
你可能要說了绒怨,我不懂?dāng)?shù)據(jù)結(jié)構(gòu)與算法纯赎,照樣找到了好工作啊。那我是不是就不用學(xué)數(shù)據(jù)結(jié)構(gòu)和算法呢南蹂?當(dāng)然不是犬金,你別忘了,我們學(xué)任何知識都是為了“用”的,是為了解決實(shí)際工作問題的晚顷,學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)和算法自然也不例外峰伙。
業(yè)務(wù)開發(fā)工程師,你真的愿意做一輩子 CRUD boy 嗎该默?
如果你是一名業(yè)務(wù)開發(fā)工程師瞳氓,你可能要說,我整天就是做數(shù)據(jù)庫 CRUD(增刪改查)栓袖,哪里用得到數(shù)據(jù)結(jié)構(gòu)和算法岸倥颉?
是的叽赊,對于大部分業(yè)務(wù)開發(fā)來說恋沃,我們平時可能更多的是利用已經(jīng)封裝好的現(xiàn)成的接口、類庫來堆砌必指、翻譯業(yè)務(wù)邏輯囊咏,很少需要自己實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)和算法。但是塔橡,不需要自己實(shí)現(xiàn)梅割,并不代表什么都不需要了解。
如果不知道這些類庫背后的原理葛家,不懂得時間户辞、空間復(fù)雜度分析,你如何能用好癞谒、用對它們底燎?存儲某個業(yè)務(wù)數(shù)據(jù)的時候,你如何知道應(yīng)該用 ArrayList弹砚,還是 Linked List 呢双仍?調(diào)用了某個函數(shù)之后,你又該如何評估代碼的性能和資源的消耗呢桌吃?
作為業(yè)務(wù)開發(fā)朱沃,我們會用到各種框架、中間件和底層系統(tǒng)茅诱,比如 Spring逗物、RPC 框架、消息中間件瑟俭、Redis 等等翎卓。在這些基礎(chǔ)框架中,一般都揉和了很多基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)和算法的設(shè)計(jì)思想尔当。
比如莲祸,我們常用的 Key-Value 數(shù)據(jù)庫 Redis 中蹂安,里面的有序集合是用什么數(shù)據(jù)結(jié)構(gòu)來實(shí)現(xiàn)的呢椭迎?為什么要用跳表來實(shí)現(xiàn)呢锐帜?為什么不用二叉樹呢?
如果你能弄明白這些底層原理畜号,你就能更好地使用它們缴阎。即便出現(xiàn)問題,也很容易就能定位简软。因此蛮拔,掌握數(shù)據(jù)結(jié)構(gòu)和算法,不管對于閱讀框架源碼痹升,還是理解其背后的設(shè)計(jì)思想建炫,都是非常有用的。
在平時的工作中疼蛾,數(shù)據(jù)結(jié)構(gòu)和算法的應(yīng)用到處可見肛跌。我來舉一個你非常熟悉的例子:如何實(shí)時地統(tǒng)計(jì)業(yè)務(wù)接口的 99% 響應(yīng)時間?
你可能最先想到察郁,每次查詢時衍慎,從小到大排序所有的響應(yīng)時間,如果總共有 1200 個數(shù)據(jù)皮钠,那第 1188 個數(shù)據(jù)就是 99% 的響應(yīng)時間稳捆。很顯然,每次用這個方法查詢的話都要排序麦轰,效率是非常低的乔夯。但是,如果你知道“堆”這個數(shù)據(jù)結(jié)構(gòu)款侵,用兩個堆可以非常高效地解決這個問題驯嘱。
基礎(chǔ)架構(gòu)研發(fā)工程師,寫出達(dá)到開源水平的框架才是你的目標(biāo)喳坠!
現(xiàn)在互聯(lián)網(wǎng)上的技術(shù)文章鞠评、架構(gòu)分享、開源項(xiàng)目滿天飛壕鹉,照貓畫虎做一套基礎(chǔ)框架并不難剃幌。我就拿 RPC 框架舉例。
不同的公司晾浴、不同的人做出的 RPC 框架负乡,架構(gòu)設(shè)計(jì)思路都差不多,最后實(shí)現(xiàn)的功能也都差不多脊凰。但是有的人做出來的框架抖棘,Bug 很多茂腥、性能一般、擴(kuò)展性也不好切省,只能在自己公司僅有的幾個項(xiàng)目里面用一下最岗。而有的人做的框架可以開源到 GitHub 上給很多人用,甚至被 Apache 收錄朝捆。為什么會有這么大的差距呢般渡?
我覺得,高手之間的競爭其實(shí)就在細(xì)節(jié)芙盘。這些細(xì)節(jié)包括:你用的算法是不是夠優(yōu)化驯用,數(shù)據(jù)存取的效率是不是夠高,內(nèi)存是不是夠節(jié)省等等儒老。這些累積起來蝴乔,決定了一個框架是不是優(yōu)秀。所以驮樊,如果你還不懂?dāng)?shù)據(jù)結(jié)構(gòu)和算法薇正,沒聽說過大 O 復(fù)雜度分析,不知道怎么分析代碼的時間復(fù)雜度和空間復(fù)雜度巩剖,那肯定說不過去了铝穷,趕緊來補(bǔ)一補(bǔ)吧!
對編程還有追求佳魔?不想被行業(yè)淘汰曙聂?那就不要只會寫湊合能用的代碼!
何為編程能力強(qiáng)鞠鲜?是代碼的可讀性好宁脊、健壯?還是擴(kuò)展性好贤姆?我覺得沒法列榆苞,也列不全。但是霞捡,在我看來坐漏,性能好壞起碼是其中一個非常重要的評判標(biāo)準(zhǔn)。但是碧信,如果你連代碼的時間復(fù)雜度赊琳、空間復(fù)雜度都不知道怎么分析,怎么寫出高性能的代碼呢砰碴?
你可能會說躏筏,我在小公司工作,用戶量很少呈枉,需要處理的數(shù)據(jù)量也很少趁尼,開發(fā)中不需要考慮那么多性能的問題埃碱,完成功能就可以,用什么數(shù)據(jù)結(jié)構(gòu)和算法酥泞,差別根本不大砚殿。但是你真的想“十年如一日”地做一樣的工作嗎?
經(jīng)常有人說婶博,程序員 35 歲之后很容易陷入瓶頸瓮具,被行業(yè)淘汰荧飞,我覺得原因其實(shí)就在此凡人。有的人寫代碼的時候,從來都不考慮非功能性的需求叹阔,只是完成功能挠轴,湊合能用就好;做事情的時候耳幢,也從來沒有長遠(yuǎn)規(guī)劃岸晦,只把眼前事情做好就滿足了。
我曾經(jīng)面試過很多大齡候選人睛藻,簡歷能寫十幾頁启上,經(jīng)歷的項(xiàng)目有幾十個,但是細(xì)看下來店印,每個項(xiàng)目都是重復(fù)地堆砌業(yè)務(wù)邏輯而已冈在,完全沒有難度遞進(jìn),看不出有能力提升按摘。久而久之包券,十年的積累可能跟一年的積累沒有任何區(qū)別。這樣的人炫贤,怎么不會被行業(yè)淘汰呢溅固?
如果你在一家成熟的公司,或者 BAT 這樣的大公司兰珍,面對的是千萬級甚至億級的用戶侍郭,開發(fā)的是 TB、PB 級別數(shù)據(jù)的處理系統(tǒng)掠河。性能幾乎是開發(fā)過程中時刻都要考慮的問題亮元。一個簡單的 ArrayList、Linked List 的選擇問題口柳,就可能會產(chǎn)生成千上萬倍的性能差別苹粟。這個時候,數(shù)據(jù)結(jié)構(gòu)和算法的意義就完全凸顯出來了跃闹。
其實(shí)嵌削,我覺得毛好,數(shù)據(jù)結(jié)構(gòu)和算法這個東西,如果你不去學(xué)苛秕,可能真的這輩子都用不到肌访,也感受不到它的好。但是一旦掌握艇劫,你就會常常被它的強(qiáng)大威力所折服吼驶。之前你可能需要費(fèi)很大勁兒來優(yōu)化的代碼,需要花很多心思來設(shè)計(jì)的架構(gòu)蟹演,用了數(shù)據(jù)結(jié)構(gòu)和算法之后,很容易就可以解決了顷蟀。
我們學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)和算法,并不是為了死記硬背幾個知識點(diǎn)鸣个。我們的目的是建立時間復(fù)雜度、空間復(fù)雜度意識囤萤,寫出高質(zhì)量的代碼昼窗,能夠設(shè)計(jì)基礎(chǔ)架構(gòu),提升編程技能涛舍,訓(xùn)練邏輯思維澄惊,積攢人生經(jīng)驗(yàn),以此獲得工作回報(bào)做盅,實(shí)現(xiàn)你的價值缤削,完善你的人生。
所以吹榴,不管你是業(yè)務(wù)開發(fā)工程師亭敢,還是基礎(chǔ)架構(gòu)工程師图筹;不管你是初入職場的初級工程師帅刀,還是工作多年的資深架構(gòu)師,又或者是想轉(zhuǎn)人工智能远剩、區(qū)塊鏈這些熱門領(lǐng)域的程序員扣溺,數(shù)據(jù)結(jié)構(gòu)與算法作為計(jì)算機(jī)的基礎(chǔ)知識、核心知識瓜晤,都是必須要掌握的锥余。
掌握了數(shù)據(jù)結(jié)構(gòu)與算法,你看待問題的深度痢掠,解決問題的角度就會完全不一樣驱犹。因?yàn)檫@樣的你双妨,就像是站在巨人的肩膀上然低,拿著生存利器行走世界。數(shù)據(jù)結(jié)構(gòu)與算法绊含,會為你的編程之路膏孟,甚至人生之路打開一扇通往新世界的大門地沮。
你為什么要學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)和算法呢炕柔?在過去的軟件開發(fā)中振坚,數(shù)據(jù)結(jié)構(gòu)和算法在哪些地方幫到了你?
歡迎留言和我分享蔬将。