認(rèn)真學(xué)完計(jì)算機(jī)體系結(jié)構(gòu),操作系統(tǒng),數(shù)據(jù)結(jié)構(gòu),算法之后,我究竟得到了什么?

套路都這么說,更加理解了計(jì)算機(jī)體系結(jié)構(gòu),操作系統(tǒng),數(shù)據(jù)結(jié)構(gòu),算法.

然而,今天我們不搞這些八股文.我們來談一下,究竟得到了什么.

無論各位看沒看過玄幻類小說,都知道其中的修道者,需要經(jīng)過一次次的歷練,然后渡劫,上升到更高的境界.

之前雖然也會用不少框架,但是終究是不能知其所以然.這種境界,就是人們常說的碼農(nóng).

而雖然早就想到了飛升的方法,卻并沒有飛升.為何?因?yàn)椴恢佬枰裁礃拥臈l件,不知道應(yīng)該怎樣渡劫.

而認(rèn)真學(xué)完這些之后,可算是具有了渡劫的條件,也了解了如何來渡劫.

其實(shí),每次渡劫需要的條件,都是那些理論知識.現(xiàn)在我了解了這些知識,渡完了這次劫.下次要想渡分布式的劫,就需要了解分布式系統(tǒng)的理論知識.

說實(shí)話,之前做東西,都是做到能使用就行了,即使想要進(jìn)行性能調(diào)優(yōu),也一直苦于無處下手.

學(xué)完計(jì)算機(jī)體系結(jié)構(gòu)和操作系統(tǒng)之后,更深入的了解了線程和信號量等內(nèi)容之后,我開始有意識的考慮寫的程序是不是線程安全的,會不會因?yàn)楦卟l(fā)而出現(xiàn)不可預(yù)期的錯誤.

學(xué)習(xí)了JVM之后,我了解了如何在JVM層面進(jìn)行調(diào)優(yōu),以及分析出現(xiàn)錯誤的原因.比如說,昨天的文章的末尾,我們說到,我們還可以采用Hibernate緩存或者Redis緩存來進(jìn)一步提升性能,但是,如果讓我們選擇的話,我們會采取Redis緩存.因?yàn)镠ibernate緩存應(yīng)該是在內(nèi)存中存儲一個跟Hash表一樣的東西,其中查詢語句是這張表的Key,而Value是以前Hibernate查詢的結(jié)果.這樣的話,Hibernate一直維護(hù)這張表,GC就不能回收它.如果這張表很大的話,就會消耗相當(dāng)大的一部分內(nèi)存.我昨天計(jì)算了一下,存儲一千個我們項(xiàng)目中的對象后,至少需要330M內(nèi)存.我們的這個對象的大小的計(jì)算,還是沒有經(jīng)過對齊所計(jì)算出來的大小.在考慮到對齊,以及方法等需要的內(nèi)存,計(jì)算出來的值,比上面的值還要大很多.所以,Hibernate緩存雖然確實(shí)減少了建立JDBC Connection以及執(zhí)行操作的花銷,但是,數(shù)據(jù)量一多,就會占用大量的內(nèi)存,因?yàn)檫€被引用,又不能被回收.而如果采用Redis緩存的話,我們將查詢的結(jié)果,序列化成JSON字符串之后,存到Redis,下次需要的時候,就直接根據(jù)Key,從Redis中取出來數(shù)據(jù),這樣就不用擔(dān)心內(nèi)存的問題了,只需要考慮帶寬的問題,以及過期數(shù)據(jù)的處理問題.我們還可以在再項(xiàng)目中增加一個本地緩存,如Java中的EhCache,實(shí)現(xiàn)熱點(diǎn)數(shù)據(jù)存到本地緩存,其他數(shù)據(jù)緩存到Redis.這樣可以進(jìn)一步提高性能.因?yàn)橐话闱闆r下,都是熱點(diǎn)數(shù)據(jù)訪問的比較多.所以,Redis的方案,對比Hibernate緩存的方案,是更為好用的.

學(xué)習(xí)了數(shù)據(jù)結(jié)構(gòu)之后,特別是樹,現(xiàn)在要自己設(shè)計(jì)一個需要的數(shù)據(jù)結(jié)構(gòu)的時候,就顯的游刃有余了.了解了每種結(jié)構(gòu)的特點(diǎn),在需要一種數(shù)據(jù)結(jié)構(gòu)的時候,我們就能快速的反應(yīng)出到底什么樣的數(shù)據(jù)結(jié)構(gòu)合適.而如果用了錯誤的合適結(jié)構(gòu),會造成操作起來以及理解起來都有困難.比如說,我們要保存到來的消息,然后按其到來的先后順序來消費(fèi),我們采取什么樣的數(shù)據(jù)結(jié)構(gòu)比較好?當(dāng)然是隊(duì)列.這就是消息隊(duì)列的采用的數(shù)據(jù)結(jié)構(gòu).如果我們采用數(shù)組,我們需要為其限定長度.大了浪費(fèi)空間,小了又不夠用.如果小了,前面的消息沒有處理完,又來了新的消息的話,我們該怎么辦?為數(shù)組調(diào)整長度,本身就是很不方便的.甚至是不可能的.而如果采用隊(duì)列的結(jié)構(gòu),因?yàn)殛?duì)列會自動伸縮,我們就沒有尺寸的問題了.可見,采用的合適的數(shù)據(jù)結(jié)構(gòu),真是事半功倍.

學(xué)習(xí)完算法之后,開始有意識的衡量自己寫的代碼的算法復(fù)雜度了.比如說,寫的一個根據(jù)Hibernate查詢出來的數(shù)據(jù)構(gòu)建出一棵樹并遞歸的生成一個JSON字符串,方便我們保存到Redis的工具類,寫完之后,分析了一下算法的時間復(fù)雜度和空間復(fù)雜度,發(fā)現(xiàn)每次都從全部查詢結(jié)果中來匹配模式,使得需要大量的時間來遍歷.而實(shí)際上,那些我們已經(jīng)匹配完的查詢結(jié)果,下次再用新的模式匹配時,是不需要的.空間復(fù)雜度上,因?yàn)楝F(xiàn)在是把全部的數(shù)據(jù)全都取出來放在內(nèi)存中,如果數(shù)據(jù)比較多的情況下,本身就對內(nèi)存是一個比較大的消耗.而且,如果是分頁查詢的話,將全部數(shù)據(jù)都取出來,是沒有必要的.一般來說,最多查詢?nèi)捻?所以說,我們其實(shí)浪費(fèi)了大量的空間.

而且,了解了現(xiàn)在常用的算法之后,比如說了解常用的排序算法,我們需要對元素進(jìn)行排序時,就能根據(jù)我們的場景選擇最優(yōu)的算法.而我以前只理解冒泡排序!!!

同樣,計(jì)算機(jī)體系結(jié)構(gòu),操作系統(tǒng),數(shù)據(jù)結(jié)構(gòu),算法,在進(jìn)行性能優(yōu)化的時候也很重要,因?yàn)樾阅軆?yōu)化涉及到各個方面,計(jì)算機(jī)網(wǎng)絡(luò),編譯原理,匯編也都有涉及到.如果不清楚這些知識,注定是舉步維艱.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容