成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

后端好書(shū)閱讀與推薦(續(xù))

劉福 / 1248人閱讀

摘要:續(xù)前文后端好書(shū)閱讀與推薦,幾十天過(guò)去了,又看了兩本好書(shū)還有以前看過(guò)的書(shū),這里依然把它們總結(jié)歸納一下,加入一些自己的看法有用的鏈接和可能的延伸閱讀,并推薦給需要的同學(xué)。

續(xù)前文 后端好書(shū)閱讀與推薦 - Mageek`s Wonderland ,幾十天過(guò)去了,又看了兩本好書(shū)(還有以前看過(guò)的書(shū)),這里依然把它們總結(jié)歸納一下,加入一些自己的看法、有用的鏈接和可能的延伸閱讀,并推薦給需要的同學(xué)。

深入理解Java虛擬機(jī)

深入理解Java虛擬機(jī) (豆瓣) https://book.douban.com/subje...

Java怎么用,是一個(gè)問(wèn)題;怎么用好是一個(gè)大問(wèn)題;這么用是為什么,是一個(gè)更大的問(wèn)題。搞懂這三個(gè)問(wèn)題應(yīng)該是每一個(gè)搞Java的人都要追求的目標(biāo),讀完本書(shū),就能把這個(gè)更大的問(wèn)題搞懂了。

本書(shū)亮點(diǎn):

模塊化是解決應(yīng)用系統(tǒng)與技術(shù)平臺(tái)越來(lái)越復(fù)雜,越來(lái)越龐大的問(wèn)題的一個(gè)重要途徑,也是建立各種功能的標(biāo)準(zhǔn)件的前提。

Java運(yùn)行時(shí)數(shù)據(jù)區(qū)幾個(gè)主要部分:程序計(jì)數(shù)器(可看作當(dāng)前線程所執(zhí)行的字節(jié)碼的行號(hào)指示器)、虛擬機(jī)棧(每一個(gè)方法從調(diào)用直至執(zhí)行完成的過(guò)程,就對(duì)應(yīng)著一個(gè)棧幀在虛擬機(jī)棧中入棧到出棧的過(guò)程,而棧幀存儲(chǔ)局部變量表、 操作數(shù)棧、 動(dòng)態(tài)鏈接、 方法出口等信息)、本地方法棧(Native方法對(duì)應(yīng)的棧)、(所有線程共享的一塊內(nèi)存區(qū)域,存放對(duì)象實(shí)例)、方法區(qū)(各個(gè)線程共享的內(nèi)存區(qū)域,存儲(chǔ)已被虛擬機(jī)加載的類(lèi)信息、常量、靜態(tài)變量、即時(shí)編譯器編譯后的代碼等數(shù)據(jù))、常量池(方法區(qū)的一部分,存放編譯期生成的各種字面量和符號(hào)引用)。

對(duì)象訪問(wèn)方式取決于虛擬機(jī)實(shí)現(xiàn)而定的,目前主流的訪問(wèn)方式有使用句柄和直接指針兩種:如果使用句柄訪問(wèn)的話,那么Java堆中將會(huì)劃分出一塊內(nèi)存來(lái)作為句柄池,reference中存儲(chǔ)的就是對(duì)象的句柄地址,而句柄中包含了對(duì)象實(shí)例數(shù)據(jù)與類(lèi)型數(shù)據(jù)各自的具體地址信息;如果使用直接指針訪問(wèn),reference中存儲(chǔ)的直接就是對(duì)象地址。

Java垃圾回收采用分代回收機(jī)制,新生代和老生代采用不同的算法(node.js也是),而不管什么機(jī)制,判斷一個(gè)對(duì)象是否存活都是基本的步驟,方法有:引用計(jì)數(shù)法,給對(duì)象添加一個(gè)引用計(jì)數(shù)器,每當(dāng)一個(gè)地方引用它時(shí),計(jì)數(shù)器就加1,引用失效時(shí),計(jì)數(shù)器就減1,任何時(shí)刻計(jì)數(shù)器為0的對(duì)象就是不可能再被使用的,這個(gè)方法實(shí)現(xiàn)簡(jiǎn)單,但是不能解決循環(huán)引用問(wèn)題,所以主流JVM不使用,但是這個(gè)算法也適用于許多地方如Python,微軟的COM;可達(dá)性分析,按照對(duì)象之間的引用關(guān)系維護(hù)一個(gè)引用鏈,如果一個(gè)對(duì)象不可達(dá)GC Roots,那么就是可回收的,應(yīng)用于主流JVM中。

finalize是一種迎合C++程序員的妥協(xié),運(yùn)行代價(jià)高昂,不確定性大,無(wú)法保證各個(gè)對(duì)象的調(diào)用順序。有些教材中描述它適合做“關(guān)閉外部資源”之類(lèi)的工作,這完全是對(duì)這個(gè)方法用途的一種自我安慰。finalize能做的所有工作,使用try-finally或者其他方式都可以做得更好、更及時(shí),所以建議大家完全可以忘掉Java語(yǔ)言中有這個(gè)方法的存在。

幾乎各種語(yǔ)言或多或少都提供過(guò)一些語(yǔ)法糖來(lái)方便程序員的代碼開(kāi)發(fā),這些語(yǔ)法糖雖然不會(huì)提供實(shí)質(zhì)性的功能改進(jìn),但是它們或能提高效率,或能提升語(yǔ)法的嚴(yán)謹(jǐn)性,或能減少編碼出錯(cuò)的機(jī)會(huì)。不過(guò)也有一種觀點(diǎn)認(rèn)為語(yǔ)法糖并不一定都是有益的,大量添加和使用“含糖”的語(yǔ)法,容易讓程序員產(chǎn)生依賴,無(wú)法看清語(yǔ)法糖的糖衣背后代碼的真實(shí)面目。所以我們既要會(huì)使用語(yǔ)法糖,同時(shí)也要搞懂背后的原理,這樣才能進(jìn)階呀。比如泛型技術(shù):泛型只在程序源碼中存在,在編譯后的字節(jié)碼文件中,就已經(jīng)替換為原來(lái)的原生類(lèi)型。

Java程序最初是通過(guò)解釋器(Interpreter)進(jìn)行解釋執(zhí)行的,當(dāng)虛擬機(jī)發(fā)現(xiàn)某個(gè)方法或代碼塊的運(yùn)行特別頻繁時(shí),就會(huì)把這些代碼認(rèn)定“熱點(diǎn)代碼”(Hot Spot Code)。 為了提高熱點(diǎn)代碼的執(zhí)行效率,在運(yùn)行時(shí),虛擬機(jī)將會(huì)把這些代碼編譯成與本地平臺(tái)相關(guān)的機(jī)器碼,并進(jìn)行各種層次的優(yōu)化,完成這個(gè)任務(wù)的編譯器稱為即時(shí)編譯器(Just In Time Compiler,簡(jiǎn)稱JIT編譯器)

基于高速緩存(Cache)的存儲(chǔ)交互很好地解決了處理器與內(nèi)存的速度矛盾,但是也為計(jì)算機(jī)系統(tǒng)帶來(lái)更高的復(fù)雜度,因?yàn)樗肓艘粋€(gè)新的問(wèn)題:緩存一致性;除了增加高速緩存之外,為了使得處理器內(nèi)部的運(yùn)算單元能盡量被充分利用,處理器可能會(huì)對(duì)輸入代碼進(jìn)行亂序執(zhí)行(Out-Of-Order Execution)優(yōu)化,類(lèi)似的JVM也有指令重排(Instruction Reorder)。這兩點(diǎn)是提高程序運(yùn)行的主要方法,然而也是多線程程序難以正確編寫(xiě)的主要原因。

先行發(fā)生(happens-before)是Java內(nèi)存模型中定義的兩項(xiàng)操作之間的偏序關(guān)系,如果說(shuō)操作A先行發(fā)生于操作B,其實(shí)就是說(shuō)在發(fā)生操作B之前,操作A產(chǎn)生的影響能被操作B觀察到,“影響”包括修改了內(nèi)存中共享變量的值、發(fā)送了消息、調(diào)用了方法等。時(shí)間先后順序與先行發(fā)生原則之間基本沒(méi)有太大的關(guān)系,所以我們衡量并發(fā)安全問(wèn)題的時(shí)候不要受到時(shí)間順序的干擾,一切必須以先行發(fā)生原則為準(zhǔn)。

這本書(shū)是基于jdk1.7的,如果要追蹤最新的Java和JVM規(guī)范,可以看這里。
另外,上面提到的第一個(gè)問(wèn)題可以參閱Java核心技術(shù),第二個(gè)問(wèn)題可以參閱Java編程思想、Effective Java,第三個(gè)問(wèn)題還可以參閱HotSpot實(shí)戰(zhàn)。這幾本書(shū)我都瀏覽過(guò),部分有細(xì)讀,都是相當(dāng)經(jīng)典的。

高性能MySQL

高性能MySQL (豆瓣) https://book.douban.com/subje...

這本書(shū)可謂是MySQL領(lǐng)域的權(quán)威之作,從架構(gòu)到測(cè)試,從性能分析到查詢優(yōu)化,從軟件配置優(yōu)化到服務(wù)器硬件優(yōu)化,從單實(shí)例到主從復(fù)制、負(fù)載均衡,從底層數(shù)據(jù)庫(kù)優(yōu)化到應(yīng)用層優(yōu)化......本書(shū)真可謂是面面俱到,同時(shí)又很有深度,絕非淺嘗輒止。

本書(shū)亮點(diǎn):

所謂的鎖策略,就是在鎖的開(kāi)銷(xiāo)和數(shù)據(jù)的安全性之間尋求平衡,這種平衡自然也影響到性能。這句話適用于世間的一切工具,安全性和可用性總是矛盾的,我們?cè)谑褂霉ぞ呋蛘唛_(kāi)發(fā)工具的時(shí)候,都要尋求一個(gè)最佳平衡點(diǎn)。

除非需要使用InnoDB不具備的的特性,并且沒(méi)有其他辦法可以替代,則都應(yīng)該優(yōu)先使用InnoDB引擎,也不要多引擎混用,例如全文索引可以使用InnoDB+Sphinx,而不要使用MyISAM引擎,因?yàn)镮nnoDB其他方面的優(yōu)點(diǎn)可以完全碾壓MyISAM,比如崩潰恢復(fù)快,支持事務(wù),支持行級(jí)鎖,支持真正的熱備份等等。

基準(zhǔn)測(cè)試可以驗(yàn)證對(duì)于系統(tǒng)的假設(shè),檢查異常行為,找出擴(kuò)展性瓶頸等等。需要注意的是不要使用真實(shí)數(shù)據(jù)的子集,作物的數(shù)據(jù)分布,忽略預(yù)熱等等,這些錯(cuò)誤的操作會(huì)使得測(cè)試結(jié)果無(wú)用或者不精確。而且要建立參數(shù)與結(jié)果文檔化的規(guī)范,這樣才利于結(jié)果分析與優(yōu)化。

很多人在優(yōu)化時(shí)都將精力放在修改某些東西上,卻很少去測(cè)量;正確的做法是要盡量測(cè)量響應(yīng)花的時(shí)間在哪,正確的測(cè)量一般都能將性能問(wèn)題的點(diǎn)暴露出來(lái),我們就能更好的對(duì)癥下藥,而不是盲目?jī)?yōu)化(花1000塊優(yōu)化一個(gè)只值500塊的業(yè)務(wù),或者已經(jīng)處于頂點(diǎn)的業(yè)務(wù)不就是虧了嗎)。所以說(shuō),決策要基于數(shù)據(jù)而不是感覺(jué)。

良好的邏輯設(shè)計(jì)和物理設(shè)計(jì)是高性能的基石,某些反范式的設(shè)計(jì)可能加快某些查詢,比如計(jì)數(shù)表和匯總表是一種很好的查詢優(yōu)化方式,能提高統(tǒng)計(jì)類(lèi)的查詢速度,但是維護(hù)起來(lái)就比較麻煩,可能降低數(shù)據(jù)插入速度。這些都需要自己根據(jù)業(yè)務(wù)來(lái)進(jìn)行權(quán)衡(比如讀寫(xiě)比),有陰就有陽(yáng)嘛。

選擇能正確存儲(chǔ)數(shù)據(jù)的最小類(lèi)型:既省空間又省計(jì)算時(shí)間,簡(jiǎn)單就好:比如使用MySQL內(nèi)建時(shí)間戳而不是自己使用字符串,盡量避免null:因?yàn)閚ull使得索引、統(tǒng)計(jì)、值比較都更加復(fù)雜還可能會(huì)占用更多空間。

InnoDB有一個(gè)“自適應(yīng)哈希索引”的功能,當(dāng)引擎注意到某些索引值被頻繁使用時(shí)就會(huì)在內(nèi)存中基于B+Tree索引之上再創(chuàng)建一個(gè)hash索引,這樣就讓B+Tree也具有hash索引的優(yōu)點(diǎn)比如快速查找。

小表通常全表掃描更高效,中大型表才適合用索引,使用索引過(guò)程中要注意,索引列必須多帶帶的出現(xiàn)在比較符號(hào)的右側(cè)而不是表達(dá)式的一部分(這會(huì)使索引失效),使用前綴索引來(lái)節(jié)省空間提高檢索效率,多列索引要注意順序不然容易失效,聚簇索引可以提高訪問(wèn)速度。

慢查詢優(yōu)化:只向數(shù)據(jù)庫(kù)請(qǐng)求需要的列(比如不要隨意select * )、避免不必要的行掃描、必要的時(shí)候分解查詢(拆分大的查詢,分解關(guān)聯(lián)查詢)。

默認(rèn)配置文件是經(jīng)過(guò)大量測(cè)試,所以屬于較優(yōu)解,一般符合普通用戶,要修改也主要是根據(jù)業(yè)務(wù)而不是服務(wù)器配置;任何打算長(zhǎng)期使用的配置都應(yīng)該寫(xiě)到全局配置文件而不是在命令行指定,因?yàn)槿绻既粏?dòng)忘了(事實(shí)是經(jīng)常會(huì)忘,好記性不如爛筆頭是個(gè)真理)設(shè)置就會(huì)有風(fēng)險(xiǎn)。

MySQL復(fù)制功能不僅有利于構(gòu)建高性能應(yīng)用,同時(shí)也是高可用性(負(fù)載均衡、故障切換)、可擴(kuò)展性(升級(jí))、災(zāi)難恢復(fù)、備份以及數(shù)據(jù)倉(cāng)庫(kù)等工作的基礎(chǔ)。

數(shù)據(jù)如果非常龐大,比如幾億行了,單臺(tái)機(jī)器已經(jīng)撐不住了,通常要采取分片技術(shù),分片最大的問(wèn)題就是查詢與獲取數(shù)據(jù),我們的目標(biāo)是對(duì)最重要且頻繁查詢的數(shù)據(jù)減少分片(熱點(diǎn)數(shù)據(jù)通常就那么多)。所以分片關(guān)鍵問(wèn)題就在于選擇一個(gè)好的分區(qū)鍵,通常是一個(gè)數(shù)據(jù)庫(kù)中非常重要的實(shí)體的主鍵。

不僅要關(guān)注MySQL,還要關(guān)注應(yīng)用層優(yōu)化:Apache服務(wù)器處理靜態(tài)文件都可能使用一個(gè)占用內(nèi)存很大的進(jìn)程(上一個(gè)請(qǐng)求處理完后,該進(jìn)程仍然保持著),所以最好使用Nginx或者Lighttpd來(lái)處理靜態(tài)內(nèi)容服務(wù),而且靜態(tài)文件名不要重用,要加上版本號(hào),這樣就能避免瀏覽器緩存問(wèn)題;主動(dòng)緩存如Squid,被動(dòng)緩存如Memcached,都可以對(duì)性能獲得數(shù)量級(jí)的提升,關(guān)鍵就在于找到正確的粒度和緩存過(guò)期策略組合,通常主動(dòng)緩存更好,因?yàn)閷?duì)應(yīng)用層隱藏了檢查-生成-存儲(chǔ)這個(gè)過(guò)程;

......

亮點(diǎn)太多,列不完了,需要大家自己去尋找。另外,這本書(shū)不適宜一次性的精讀完畢(太厚,內(nèi)容太多),可以快速瀏覽一遍,大概了解,以后遇上問(wèn)題就可以把這本書(shū)當(dāng)作一本問(wèn)題解答手冊(cè)來(lái)查詢解決方案,或者找找靈感。

Redis實(shí)戰(zhàn)

Redis實(shí)戰(zhàn) (豆瓣) https://book.douban.com/subje...

本書(shū)對(duì)redis的介紹是相當(dāng)全面了,從基本用法講起,然后講了許多應(yīng)用場(chǎng)景,包括購(gòu)物車(chē)、數(shù)據(jù)庫(kù)緩存等,然后講了一些常見(jiàn)問(wèn)題的解決辦法,比如內(nèi)存占用過(guò)高,自定義擴(kuò)展來(lái)豐富redis的用法等等,看完一本書(shū)過(guò)后就能很好的使用redis了(還有本好書(shū):redis設(shè)計(jì)與實(shí)現(xiàn),我大致瀏覽了一下,這本書(shū)主要講了redis的實(shí)現(xiàn)原理,這兩本書(shū)加起來(lái)就能既懂原理又會(huì)使用,把redis搞個(gè)透徹)。

本書(shū)亮點(diǎn):

使用冒號(hào) : 或者管道號(hào) | 等來(lái)實(shí)現(xiàn)命名空間的作用,比如一個(gè)名為 article:12222 的hash存了這篇article的title,link,time等屬性,article:12223又是另一篇文章,這個(gè)可以部分實(shí)現(xiàn)數(shù)據(jù)庫(kù)檢索的功能。

為了減少redis與客戶端之間的通信次數(shù),可以用multi和exec來(lái)做事務(wù)處理,事務(wù)會(huì)一次性的把一批命令一次發(fā)給redis,提高吞吐率;另外事務(wù)還能保證一批操作的原子性。在node-redis實(shí)現(xiàn)中,如果只是想提高吞吐率則可以用batch替代multi。

通過(guò)復(fù)制(主從)和AOF能夠增強(qiáng)redis抵抗系統(tǒng)崩潰損失數(shù)據(jù)的能力,AOF如果用得不好的話,要么損失很多數(shù)據(jù),要么嚴(yán)重降低吞吐量,比較合適的做法是appendfsync everysec 亦即把每一秒的命令一次同步進(jìn)文件。

使用 redis 的 setnx 來(lái)實(shí)現(xiàn)基本上正確的的分布式鎖,再加上expire可以實(shí)現(xiàn)具有超時(shí)功能的鎖,保證即使獲得鎖的客戶端崩潰沒(méi)有主動(dòng)釋放鎖時(shí),其他進(jìn)程也有機(jī)會(huì)獲得鎖。

用 list 來(lái)替代 subscribe、publish 實(shí)現(xiàn)更可靠的發(fā)布訂閱系統(tǒng);另外,利用subscribe、publish加list來(lái)實(shí)現(xiàn)具有離線緩存的消息隊(duì)列系統(tǒng),保證即使發(fā)生連接故障也能把消息送達(dá)。

利用反向索引以及 redis 集合的并、交、差功能可以實(shí)現(xiàn)簡(jiǎn)易的搜索引擎,利用 hash 結(jié)構(gòu)的 sort 功能還能對(duì)搜索結(jié)果進(jìn)行簡(jiǎn)易的排序功能,利用有序集合 zset 能實(shí)現(xiàn)更高級(jí)的排序功能。

社交網(wǎng)站通常是用時(shí)間線這一數(shù)據(jù)結(jié)構(gòu)來(lái)實(shí)現(xiàn)新鮮事瀏覽這一功能,雖然導(dǎo)致了大量的冗余信息,但是能夠節(jié)省查詢時(shí)間,這是典型的以空間換時(shí)間的操作,我以前做社交APP后臺(tái)的時(shí)候直接把所有新鮮事直接放在一張表中,然后按用戶id查詢,這樣雖然省了空間,但是如果用戶劇增((⊙﹏⊙)b,我們的APP并沒(méi)有用戶劇增)就不行了,一張表幾億行還怎么查。

使用短結(jié)構(gòu)來(lái)節(jié)約內(nèi)存,使用較短的鍵名節(jié)約內(nèi)存,分片降低單實(shí)例的內(nèi)存占用。

使用lua腳本,在不編寫(xiě)C代碼的情況下,為redis添加新的功能。

時(shí)效性問(wèn)題,本書(shū)沒(méi)有一些最新特性 比如 geohash 解決了地理坐標(biāo)問(wèn)題,鍵的異步釋放使得我們可以放心刪除而不必?fù)?dān)心大量數(shù)據(jù)的刪除使得redis短暫不可用??傊玫睦胷edis還是要追蹤redis的最新變化,以便更簡(jiǎn)潔、更靠譜的解決問(wèn)題。

深入剖析Nginx

深入剖析Nginx (豆瓣) https://book.douban.com/subje...

本書(shū)從源碼入手,依次講解了進(jìn)程模型、模塊、響應(yīng)處理機(jī)制、過(guò)濾、負(fù)載均衡等相關(guān)原理,極大的滿足了我的好奇心,因?yàn)橹耙恢本蛯?duì)nginx高并發(fā)處理能力有一丟丟了解(比如nginx采用事件驅(qū)動(dòng)機(jī)制而非apache的進(jìn)程、線程每請(qǐng)求方式),自己也用過(guò)nginx,但是對(duì)他的原理還不是特別的明白,本書(shū)算是填補(bǔ)了我的這個(gè)空白。

本書(shū)亮點(diǎn):

Nginx 將職責(zé)分為監(jiān)控進(jìn)程(主進(jìn)程)和工作進(jìn)程(主進(jìn)程fork的子進(jìn)程),監(jiān)控進(jìn)程與用戶交互并對(duì)工作進(jìn)程進(jìn)行監(jiān)控管理,工作進(jìn)程完成具體業(yè)務(wù)邏輯,兩者都有一個(gè)無(wú)限的for循環(huán),這是服務(wù)進(jìn)程的基本寫(xiě)法。

Nginx僅提供針對(duì)大塊內(nèi)存的回收不提供小塊內(nèi)存的回收,這是因?yàn)閣eb server的特殊性亦即階段和時(shí)效,請(qǐng)求就申請(qǐng)內(nèi)存,處理完畢就釋放內(nèi)存,所以不會(huì)存在nginx長(zhǎng)時(shí)間占據(jù)大量無(wú)用內(nèi)存的情況,那么小內(nèi)存也自然不必急于回收,而是成為大內(nèi)存后在回收。

對(duì)于客戶端的請(qǐng)求,nginx將整個(gè)過(guò)程分為11個(gè)階段,每個(gè)階段有數(shù)個(gè)回調(diào)函數(shù)進(jìn)行專門(mén)的處理,每個(gè)階段的處理功能都比較單一,達(dá)到高內(nèi)聚低耦合的目的。

Nginx是以事件為驅(qū)動(dòng)的,也就是說(shuō)Nginx內(nèi)部流程的向前推進(jìn)基本都是靠各種事件的觸發(fā)來(lái)驅(qū)動(dòng),內(nèi)部事件主要有兩類(lèi):IO事件與定時(shí)器事件。其中IO事件主要靠epoll,epoll主要優(yōu)點(diǎn)是監(jiān)控?cái)?shù)目不受文件描述符限制、事件響應(yīng)是觸發(fā)式的,不需要遍歷描述符(select需要)。

Nginx要處理動(dòng)態(tài)的內(nèi)容一般需要轉(zhuǎn)發(fā)給后端服務(wù)器,常見(jiàn)的搭配是nginx+fastcgi+php,nginx把http請(qǐng)求轉(zhuǎn)化為fastcgi協(xié)議的數(shù)據(jù)后轉(zhuǎn)發(fā)給PHP引擎,PHP引擎處理結(jié)果后把數(shù)據(jù)返回給nginx,nginx把數(shù)據(jù)轉(zhuǎn)化為http格式返回給客戶端。

負(fù)載均衡有多重含義(或者說(shuō)多重級(jí)別),可以是進(jìn)程上的(根據(jù)master進(jìn)程根據(jù)子進(jìn)程壓力調(diào)整其獲取監(jiān)聽(tīng)套接口的幾率),更廣的意義上是指反向代理上,亦即nginx把請(qǐng)求均衡的轉(zhuǎn)發(fā)給后端服務(wù)器如PHP引擎,發(fā)揮多個(gè)單元的整體效能。一般采取加權(quán)輪詢、IP hash等策略,但是只靠nginx是不能實(shí)現(xiàn)完整的負(fù)載均衡的,詳見(jiàn)我以前寫(xiě)的一篇文章。

這本書(shū)主要從應(yīng)用及其原理方面來(lái)介紹nginx,對(duì)于后端程序員應(yīng)該是夠用了(我也忽略了許多源碼,因?yàn)橹皇窍肓私庖幌略恚5菍?duì)于要想自己深入、進(jìn)行模塊編寫(xiě)的讀者應(yīng)該還不夠用,可以再參考一下這本書(shū) 深入理解Nginx(第2版)(我大概瀏覽了一下,本書(shū)會(huì)指導(dǎo)讀者編寫(xiě)具體的模塊及其底層原理,比我們今天介紹的書(shū)更深入一些)。

第一本Docker書(shū)

第一本Docker書(shū) 修訂版 (豆瓣) https://book.douban.com/subje...

書(shū)如其名,這就是真正的第一本docker書(shū)。docker是什么、怎么安裝、如何使用、測(cè)試集成、構(gòu)建服務(wù)等都有介紹。之前就久仰docker大名,也試著試用了一下,但是直到這本書(shū)讀完我才對(duì)docker有了一個(gè)完整的認(rèn)知。另外,不出意料,本書(shū)的推薦序也很精彩。

本書(shū)亮點(diǎn):

docker的核心價(jià)值在于可能改變軟件的交付方式和運(yùn)行方式。傳統(tǒng)的交付方式下,軟件運(yùn)行期依賴的環(huán)境是無(wú)法控制,不能標(biāo)準(zhǔn)化的,開(kāi)發(fā)人員常常需要解決開(kāi)發(fā)環(huán)境和生產(chǎn)環(huán)境的差別帶來(lái)的問(wèn)題,而docker則把軟件及其依賴環(huán)境打包在一起,以鏡像形式交付,讓軟件運(yùn)行在標(biāo)準(zhǔn)環(huán)境中,非常符合云計(jì)算的需求,同時(shí)docker的輕量虛擬化技術(shù)也符合實(shí)例水平擴(kuò)展,資源動(dòng)態(tài)調(diào)整的要求。

docker提供以下幾個(gè)好處:簡(jiǎn)單輕量的建模方式,工程容易docker化,隨時(shí)修改代碼,運(yùn)行快速;職責(zé)分離,開(kāi)發(fā)人員只管開(kāi)發(fā),運(yùn)維人員只管容器管理,減少環(huán)境不同帶來(lái)的問(wèn)題;快速高效的開(kāi)發(fā)生命周期,程序容易部署、移植和協(xié)作;容易實(shí)現(xiàn)面向服務(wù)的架構(gòu)和微服務(wù)架構(gòu)。

docker只支持64位架構(gòu),原生的Linux容器格式:libcontainer,使用命名空間來(lái)隔離文件系統(tǒng)(每個(gè)容器都有自己的root系統(tǒng))、進(jìn)程(每個(gè)容器都運(yùn)行在自己的進(jìn)程環(huán)境中)和網(wǎng)絡(luò)(容器間虛擬網(wǎng)絡(luò)地址和IP地址都是分開(kāi)的),使用cgroups將CPU內(nèi)存之類(lèi)的資源獨(dú)立分配給容器,寫(xiě)時(shí)復(fù)制使得文件系統(tǒng)分層隔離、速度更快、占用空間更小,還提供日志和交互式shell。

鏡像分層:新鏡像是從 base 鏡像一層一層疊加生成的,文件系統(tǒng)發(fā)生變化時(shí),就在現(xiàn)有鏡像的基礎(chǔ)上增加一層,這一層叫做“容器層”(讀寫(xiě)層),“容器層”之下的都叫“鏡像層”(只讀層),只有當(dāng)需要修改時(shí)才從鏡像層復(fù)制一份數(shù)據(jù)到容器層,這種特性被稱作寫(xiě)時(shí)復(fù)制(Copy-on-Write),達(dá)到了鏡像共享,快速構(gòu)建的目的。

可以使用docker commit來(lái)構(gòu)建鏡像,也可以基于dockerfile和docker build命令構(gòu)建,通常建議使用后者,因?yàn)閐ockerfile更具備透明性(可以清晰地看出安裝了什么軟件,修改了什么配置)、可重復(fù)性(一次編寫(xiě),多次使用。此外構(gòu)建緩存還可以制作構(gòu)建模板)、冪等性(同一個(gè)dockerfile不論執(zhí)行多少次,結(jié)果都是相同的)。

docker容器之間通訊有3種方式,1.9之前推薦用Docker Link(安全:只有l(wèi)ink之前的容器可以通信,不必硬編碼,不支持多主機(jī)),1.9之后推薦Docker Networking(支持多主機(jī)容器連接,可以熱更新容器,Networking網(wǎng)絡(luò)內(nèi)部容器可以自主發(fā)現(xiàn)),不太推薦docker內(nèi)部網(wǎng)絡(luò)(IP硬編碼等導(dǎo)致該方法不夠靈活)。

volume(卷)具有一些有用的特性:容器之間共享數(shù)據(jù),對(duì)卷的修改會(huì)直接反映在包含改卷的容器里所以可以在不修改容器的情況下向容器里加入、更新、刪除數(shù)據(jù),更新鏡像時(shí)不會(huì)影響卷。利用這些特性可以更好的進(jìn)行數(shù)據(jù)共享與持久化。

docker編排與集群化之路:Docker Compose 是用來(lái)做 docker 的多容器控制,使用Compose ,你可以在一個(gè)文件中定義多個(gè)容器應(yīng)用,然后使用一條命令來(lái)啟動(dòng)你的所有應(yīng)用,避免繁復(fù)操作,docker 自動(dòng)化構(gòu)建容器棧;Consul提供了一個(gè)易于使用,基于開(kāi)放標(biāo)準(zhǔn)的服務(wù)發(fā)現(xiàn)解決方案,服務(wù)發(fā)現(xiàn)允許某個(gè)組件在想與其他組件通訊時(shí)自動(dòng)找到對(duì)方;Docker Swarm是一個(gè)用于創(chuàng)建Docker主機(jī)(運(yùn)行Docker守護(hù)進(jìn)程的服務(wù)器)集群的工具,使用Swarm操作集群,會(huì)使用戶感覺(jué)就像是在一臺(tái)主機(jī)上進(jìn)行操作亦即將容器抽象到集群級(jí)別。還有其他很多工具如:fleet、etcd、Kubernetes、Apache Mesos、Helios、Centurion。

時(shí)效性原因,書(shū)中一些例子已經(jīng)過(guò)時(shí)(如Docker1.12開(kāi)始內(nèi)置編排機(jī)制,Docker1.13正式支持docker stack),需要結(jié)合最新版本來(lái)使用。
另外,想要深入理解docker可以閱讀這本書(shū) Docker——容器與容器云。我大致瀏覽了下,這本書(shū)不僅講了docker如何使用,還深入講解了docker的核心原理如namespace資源隔離、cgroups資源限制、libcontainer原理和一些高級(jí)實(shí)踐技巧。此外,還講了對(duì)容器、容器云的思考,包括如何構(gòu)建自己的容器云,以及Kubernetes實(shí)現(xiàn)一切皆容器的“大同理想”。

UNIX/Linux 系統(tǒng)管理技術(shù)手冊(cè)

UNIX/Linux 系統(tǒng)管理技術(shù)手冊(cè) (豆瓣) https://book.douban.com/subje...

又是一本進(jìn)千頁(yè)的大部頭,但是不怕,這本書(shū)如其名,是一本手冊(cè)性質(zhì)的書(shū),非常大而全,包括基本管理技術(shù)、網(wǎng)絡(luò)管理技術(shù)和其他補(bǔ)充管理技術(shù),幾乎包攬了所有我們可能用到的功能(小到一行代碼整么寫(xiě),大到數(shù)據(jù)中心怎么建),對(duì)于宏觀把握整個(gè)Linux生態(tài)系統(tǒng)有很大作用。我的應(yīng)對(duì)策略是跳躍式閱讀(不錯(cuò),就像上面那本MySQL),留下整體映像,等遇上問(wèn)題時(shí)再來(lái)具體的查詢相關(guān)部分的內(nèi)容。也就是說(shuō),大腦相當(dāng)于內(nèi)存,書(shū)本相當(dāng)于硬盤(pán)數(shù)據(jù)庫(kù),我們首次閱讀就是在內(nèi)存中建立索引,便于提升以后的查找速度:-D。

本書(shū)亮點(diǎn):

Linux各個(gè)發(fā)行版其實(shí)并沒(méi)有那么巨大的差別,我們選擇一個(gè)發(fā)行版時(shí)主要考慮幾點(diǎn):是否能長(zhǎng)期存在,是否會(huì)有持續(xù)的安全補(bǔ)丁,是否會(huì)持續(xù)更新軟件,發(fā)行商是否會(huì)在出了問(wèn)題時(shí)幫我們解決,不同發(fā)行版?zhèn)戎攸c(diǎn)會(huì)有所不同我們要根據(jù)自己的業(yè)務(wù)來(lái)進(jìn)行選擇。

編寫(xiě)腳本時(shí)注意形成一種指導(dǎo)風(fēng)格,這樣你和你的團(tuán)隊(duì)成員可以按照相同的規(guī)范來(lái)書(shū)寫(xiě)代碼,有了這種指導(dǎo)在閱讀別人寫(xiě)的代碼或者別人閱讀你的代碼時(shí)都會(huì)更容易;注釋不要多也不要少,最好的效果是一兩個(gè)月后再來(lái)讀代碼發(fā)現(xiàn)注釋和有用。

一個(gè)進(jìn)程由一個(gè)地址空間(一組內(nèi)存頁(yè)面)和內(nèi)核一部分?jǐn)?shù)據(jù)(有關(guān)進(jìn)程的信息如地址空間映射、狀態(tài)、優(yōu)先級(jí)、資源)組成;一個(gè)線程是在進(jìn)程內(nèi)執(zhí)行fork的結(jié)果,繼承了包含它的進(jìn)程的許多屬性,多個(gè)線程可以共享該進(jìn)程內(nèi)數(shù)據(jù),并行(多核)或并發(fā)(單核,模擬并行)執(zhí)行

Unix家族的文件系統(tǒng)目前沒(méi)有一個(gè)標(biāo)準(zhǔn),我們盡量按照如下標(biāo)準(zhǔn)來(lái)組織。bin:核心操作系統(tǒng)命令;sbin:系統(tǒng)最小規(guī)模運(yùn)行所需命令;boot:內(nèi)核及加載內(nèi)核所需軟件;etc:關(guān)鍵啟動(dòng)文件及配置文件;usr:次要的命令文件;var:隨主機(jī)變化的文件如日志,數(shù)據(jù)文件;mnt:可移動(dòng)介質(zhì)臨時(shí)掛載點(diǎn);opt:可選的應(yīng)用軟件包;proc:正在運(yùn)行的進(jìn)程信息;tmp:臨時(shí)文件;

合適的備份計(jì)劃取決于:文件系統(tǒng)的活躍性,轉(zhuǎn)儲(chǔ)設(shè)備的容量,用戶期望的冗余度,想要購(gòu)買(mǎi)的備份介質(zhì)數(shù)量。

版本控制與多人合作:svn是集中式的,一臺(tái)中央服務(wù)器充當(dāng)了一個(gè)項(xiàng)目的權(quán)威庫(kù);git是分布式的,沒(méi)有中央庫(kù),每個(gè)用戶都含有一個(gè)完整的項(xiàng)目,采用的是拷貝-分支策略。

信息安全領(lǐng)域的基本思想——CIA原則:Confidentiality(機(jī)密性),Integrity(完整性),Availability(可用性)。在設(shè)計(jì)、實(shí)現(xiàn)或者維護(hù)系統(tǒng)的時(shí)候,需要考慮CIA安全三原則,正如老話所說(shuō)“安全性是一個(gè)過(guò)程”。

負(fù)載均衡既提高了性能又增加了冗余性,包括幾種方式:循環(huán)域名服務(wù)(也就是DNS輪詢)、負(fù)載均衡硬件(比如Big-IP Controller、Content Services Switches等)、軟件負(fù)載均衡(比如Nginx)。

Squid既是一個(gè)高速緩存軟件也是一個(gè)代理服務(wù)程序,代理服務(wù)很有用,但是Squid真正厲害之處是其高速緩存,它甚至能夠形成一個(gè)緩存層次結(jié)構(gòu),以最大化提高緩存命中率。Squid是有意義的,因?yàn)橛脩魧?duì)web的探索具有趨同性,所以在適度的規(guī)模上會(huì)出現(xiàn)相當(dāng)多重復(fù)請(qǐng)求,運(yùn)行高速緩存可以節(jié)省帶寬和計(jì)算資源。

虛擬化技術(shù)讓多個(gè)彼此獨(dú)立的操作系統(tǒng)同時(shí)運(yùn)行在相同的物理硬件上,系統(tǒng)管理員把每個(gè)虛擬機(jī)當(dāng)做一臺(tái)獨(dú)立的服務(wù)器,既滿足了軟件廠商的要求,又降低了單一服務(wù)的成本。包括全虛擬化(如VMwareESX)、半虛擬化(Xen)、操作系統(tǒng)級(jí)別虛擬化(如workload partition)。除了傳統(tǒng)的虛擬化技術(shù),近年來(lái)的云計(jì)算也是一種(或者說(shuō)類(lèi))虛擬化技術(shù),它把計(jì)算能力作為對(duì)外提供的服務(wù)類(lèi)似于水電等基礎(chǔ)設(shè)施,直接使得硬件層對(duì)開(kāi)發(fā)人員和系統(tǒng)管理員透明,提高了效率。

分析性能問(wèn)題步驟:明確表述問(wèn)題、收集證據(jù)并分類(lèi)、批判性的評(píng)價(jià)數(shù)據(jù)、用語(yǔ)言和圖示總結(jié)證據(jù)、形成一份總結(jié)說(shuō)明。這一套其實(shí)不止適用于性能分析問(wèn)題,也適用于大多數(shù)其他問(wèn)題,比如架構(gòu)、重構(gòu)、debug等等。

系統(tǒng)管理不是一種行為藝術(shù)。無(wú)論做的什么,都應(yīng)該能重復(fù)完成,切前后一致。通常意味著最底層的變化應(yīng)該有腳本或者配置程序來(lái)做,而不是管理員來(lái)做。配置上的變化應(yīng)該體現(xiàn)在系統(tǒng)管理軟件的配置文件里。說(shuō)白了,就是文檔的重要性,在我看來(lái):首先文檔就是一家公司的財(cái)富,沒(méi)有文檔,人走了,那么之前公司的積累也就沒(méi)了,又得重頭來(lái),損失很大;其次,文檔是一種保證,大家都按約定辦事,保證操作可重復(fù),避免歧義與甩鍋;再其次,文檔能節(jié)約時(shí)間,雖然寫(xiě)的時(shí)候可能費(fèi)點(diǎn)事,但是能節(jié)省后面大量的人員溝通的時(shí)間;最后,文檔保證了系統(tǒng)的完整性,亦即文檔保證了系統(tǒng)的后續(xù)修改遵循一致的思路和風(fēng)格,才不至于系統(tǒng)隨著時(shí)間流逝而越來(lái)越亂,難以維護(hù)與使用。

本書(shū)教會(huì)了我們?cè)趺词褂肔inux,這對(duì)于我們后端開(kāi)發(fā)人員是足夠受用了。而這本書(shū)Linux內(nèi)核設(shè)計(jì)與實(shí)現(xiàn)(原書(shū)第3版)就會(huì)告訴我們Linux是如何實(shí)現(xiàn)它這么多這么強(qiáng)大的功能的內(nèi)在原理,精力有限,我只是瀏覽了一下沒(méi)有細(xì)讀,等以后真的用得上Linux的深入知識(shí)時(shí),或者遇上了什么解決不了的問(wèn)題,我會(huì)再來(lái)求助于這本書(shū)的。

代碼整潔之道

代碼整潔之道 (豆瓣) https://book.douban.com/subje...

本書(shū)提出一個(gè)觀點(diǎn)就是:代碼質(zhì)量與整潔度成正比,圍繞提高整潔度,作者展開(kāi)了方方面面的闡述,從命名的方法到函數(shù)的定義,從注釋的使用到格式的目的,還介紹了對(duì)象,錯(cuò)誤處理等等等等。看完后的感覺(jué)就是:寫(xiě)好代碼,從本書(shū)開(kāi)始。雖然我現(xiàn)在寫(xiě)的代碼還比較“亂”,但是今后的代碼中會(huì)努力踐行書(shū)中的原則,爭(zhēng)取寫(xiě)出整潔的代碼。

本書(shū)亮點(diǎn):

軟件質(zhì)量既依賴于架構(gòu)和項(xiàng)目管理,又與代碼質(zhì)量緊密相關(guān),而代碼質(zhì)量與整潔度成正比,所以我們要致力于寫(xiě)出干凈整潔的代碼。并且不僅要知道書(shū)寫(xiě)整潔代碼的原則,還有查看大量代碼實(shí)例,進(jìn)行案例研究,在實(shí)踐中貫徹這些原則,才能真正做到知行合一

不同的人對(duì)整潔代碼有不同的理解,總歸起來(lái),有如下一些特點(diǎn):代碼邏輯直截了當(dāng),依賴關(guān)系很少,性能最優(yōu),每個(gè)函數(shù)模塊類(lèi)專注于一件事,可以輕易的被其他人閱讀,具有完整的測(cè)試,作者自己要在乎自己的代碼悉心維護(hù),沒(méi)有重復(fù)代碼提前構(gòu)建重復(fù)代碼應(yīng)有的抽象,體現(xiàn)系統(tǒng)的所有設(shè)計(jì)理念,包含盡量少的實(shí)體。

命名看似簡(jiǎn)單卻無(wú)處不在,所以我們不妨命好名,幾個(gè)原則:名副其實(shí),不用注釋也能明白這個(gè)變量代表什么;避免誤導(dǎo),不要用保留詞或太相同的詞引起歧義;做有意義的區(qū)分,不要添加在名字后數(shù)字或者廢話而是以讀者能鑒別不同之處的方式來(lái)區(qū)分;名字要讀的出來(lái),便于交流;名稱要便于搜索;一個(gè)概念統(tǒng)一用一個(gè)詞,比如不要混用manager和Controller;避免雙關(guān)詞;給名詞添加語(yǔ)境,但是避免冗余的語(yǔ)境,含義明確的情況下,短名字總是比長(zhǎng)名字好呀......

函數(shù)構(gòu)成了當(dāng)今程序的基石,函數(shù)要寫(xiě)的明白要遵循如下原則:短小;只做一件事,也就是函數(shù)中的語(yǔ)句要在同一個(gè)抽象層級(jí)上,不在同一個(gè)抽象層級(jí)就得拆出來(lái)形成一個(gè)新的函數(shù);把switch埋藏在較低的抽象層級(jí),比如抽象工廠中,雖然依然免不了判斷或者條件增多時(shí)要增添代碼,但是能夠把變化截留在工廠內(nèi),減少影響范圍;不要向函數(shù)傳入標(biāo)志參數(shù),比如TRUE/FALSE,而是應(yīng)該直接把這個(gè)函數(shù)重構(gòu)成兩個(gè)函數(shù);一個(gè)函數(shù)要么下達(dá)什么指令(set)要么回答什么問(wèn)題(get),不要添加副作用;DRY(別重復(fù)自己)。

注釋是一種必須的惡,如果代碼寫(xiě)的好根本不需要注釋(感覺(jué)有點(diǎn)過(guò)了,至少一個(gè)大的模塊用來(lái)干啥還是因該用注釋或者說(shuō)文檔直接來(lái)說(shuō)明),而且代碼才是真實(shí)的地方,注釋很可能沒(méi)有被維護(hù)而導(dǎo)致失效;別給糟糕的代碼加注釋,重寫(xiě)吧;版本控制系統(tǒng)可以幫我們省掉許多注釋如作者署名,注釋掉的代碼。

或許你認(rèn)為“讓代碼工作”是開(kāi)發(fā)者的頭等大事,但是其實(shí)并不是這樣的,代碼風(fēng)格關(guān)系著溝通,而溝通才是頭等大事。代碼風(fēng)格影響著可維護(hù)性和擴(kuò)展性,即使代碼已不復(fù)存在,其風(fēng)格和律條依然存在,因而一個(gè)團(tuán)隊(duì)?wèi)?yīng)該形成一個(gè)統(tǒng)一的風(fēng)格,便于溝通與維護(hù)。

隱藏實(shí)現(xiàn)并非就是簡(jiǎn)單的在變量之間放一個(gè)函數(shù)層。隱藏關(guān)乎抽象,類(lèi)并不是簡(jiǎn)單的用取值器和賦值器將變量向外推,而是暴露抽象接口,以便用戶無(wú)需了解數(shù)據(jù)的具體實(shí)現(xiàn)就能操作數(shù)據(jù)本身。對(duì)象暴露行為,隱藏?cái)?shù)據(jù);數(shù)據(jù)結(jié)構(gòu)暴露數(shù)據(jù),沒(méi)有明顯的行為。要合理的利用二者。

錯(cuò)誤處理一旦處理不好就容易污染整潔的代碼:使用異常來(lái)保證錯(cuò)誤處理不會(huì)打亂正常的程序邏輯;可檢異常可能會(huì)破壞開(kāi)閉原則,要謹(jǐn)慎使用;打包第三方API就降低了對(duì)它的依賴;不要返回null值,只是突然增加了工作量,可以用異常或者特例對(duì)象來(lái)代替。

測(cè)試非常重要:測(cè)試代碼和生產(chǎn)代碼一樣重要,臟測(cè)試就等于沒(méi)測(cè)試;有了測(cè)試就可以毫無(wú)顧慮的進(jìn)行重構(gòu)和改善,因?yàn)橛斜WC,消除了清理代碼就會(huì)破壞代碼的恐懼(這句話可謂是戳中了我,我之前的項(xiàng)目也有過(guò)一些重構(gòu)的努力,但是就是怕重構(gòu)過(guò)后不能正常運(yùn)行,導(dǎo)致重構(gòu)舉步維艱);測(cè)試代碼要清晰,符合構(gòu)造-操作-檢驗(yàn)三個(gè)環(huán)節(jié);單個(gè)測(cè)試中的斷言應(yīng)該最小化,保證一個(gè)測(cè)試對(duì)應(yīng)一個(gè)概念;整潔的測(cè)試遵循 FIRST 原則(fast,independent,repeatable,self-validing,timely)。

系統(tǒng)層級(jí)的整潔:城市能有效運(yùn)轉(zhuǎn)是因?yàn)檠莼隽?strong>恰當(dāng)?shù)某橄髮蛹?jí)和模塊,有人負(fù)責(zé)全局有人負(fù)責(zé)細(xì)節(jié),所以軟件系統(tǒng)也有架構(gòu)師和項(xiàng)目經(jīng)理等;將構(gòu)造和使用分開(kāi)(依賴注入,控制反轉(zhuǎn));擴(kuò)容(要考慮可擴(kuò)展性,但是注重現(xiàn)有的系統(tǒng)的構(gòu)造,將來(lái)再重構(gòu)和添加,沒(méi)必要Big Design Up Front,考慮好模塊化和關(guān)注切面劃分就好)。

KISS(Keep It Simple, Stupid),簡(jiǎn)單設(shè)計(jì)原則:運(yùn)行所有測(cè)試(測(cè)試是對(duì)一個(gè)系統(tǒng)的保證);不要重復(fù)(重復(fù)意味著額外的工作、風(fēng)險(xiǎn)、復(fù)雜度);表達(dá)了程序員的意圖(清晰可讀);盡可能少的類(lèi)和方法數(shù)量(避免教條如:每個(gè)類(lèi)都要有接口)。

編程是一種技藝甚于科學(xué)的東西,不要指望一開(kāi)始就寫(xiě)出優(yōu)雅整潔的代碼,一般是先寫(xiě)出骯臟的代碼,然后進(jìn)行重構(gòu),清理。所以代碼僅僅能工作還不夠,滿足于代碼能工作的程序員不夠?qū)I(yè),他們害怕沒(méi)時(shí)間進(jìn)行代碼結(jié)構(gòu)的重新設(shè)計(jì),其實(shí)沒(méi)有什么比糟糕的代碼給項(xiàng)目帶來(lái)更長(zhǎng)遠(yuǎn)的損害了,糟糕的代碼會(huì)一直腐敗發(fā)酵,影響各個(gè)模塊(找出這些依賴和影響相當(dāng)不容易)無(wú)情的腐蝕整個(gè)項(xiàng)目和團(tuán)隊(duì)。

......

這本書(shū)里面的良心建議實(shí)在是太多了,無(wú)法一一列舉,真的得自己看一遍才能有收獲。

重構(gòu)-改善既有代碼的設(shè)計(jì)

重構(gòu) (豆瓣) https://book.douban.com/subje...

上一本書(shū)教會(huì)我們?cè)鯓訒?shū)寫(xiě)整潔的代碼,那么面對(duì)不整潔的代碼,我們?cè)趺崔k呢?這本書(shū)就手把手教我們?cè)趺粗貥?gòu),改善現(xiàn)有的代碼。從一個(gè)實(shí)例入手,講了重構(gòu)的理由、原則、技巧、步驟與時(shí)機(jī)。我讀完過(guò)后感覺(jué)心里就有了些烙印,無(wú)論是寫(xiě)代碼還是改代碼,基本都會(huì)不自主的向這本書(shū)靠攏,很有收獲。

本書(shū)亮點(diǎn):

重構(gòu)是在不改變代碼外在行為的前提下對(duì)代碼作出修改,以改進(jìn)程序的內(nèi)部結(jié)構(gòu),本質(zhì)上說(shuō)重構(gòu)就是在代碼寫(xiě)好后改進(jìn)其設(shè)計(jì),提高其可理解性,降低修改成本;記住所有代碼的“壞味道”及其對(duì)應(yīng)的重構(gòu)手法,才能有信心面對(duì)各種情況——學(xué)會(huì)所有招式才可能“無(wú)招勝有招”;為了避免自掘墳?zāi)梗貥?gòu)必須系統(tǒng)化進(jìn)行,用一些經(jīng)過(guò)檢驗(yàn)的重構(gòu)手法,就可以一次一小步的修改代碼,所以任何錯(cuò)誤都可以比較容易的發(fā)現(xiàn),降低了重構(gòu)過(guò)程中的風(fēng)險(xiǎn)。

如果你發(fā)現(xiàn)自己需要為程序添加一個(gè)特性,而現(xiàn)有的代碼結(jié)構(gòu)使你無(wú)法方便的添加,那就先重構(gòu)程序,使得特性添加變得容易,然后再添加這個(gè)特性。而重構(gòu)的第一步就是建立一組可靠的測(cè)試,來(lái)盡量避免bug,保證重構(gòu)的正確性。

對(duì)象A最好不要在另外一個(gè)對(duì)象B的屬性基礎(chǔ)上使用switch語(yǔ)句,因?yàn)閷?lái)B變了A也必須變,如果不得不使用switch也要在自己的屬性上使用,也就是把switch移動(dòng)至B里面去;最好是用多態(tài)替換switch語(yǔ)句(其實(shí)也不是替換,而是把switch放在了較低的抽象層級(jí),使得可能變化的部分就在一個(gè)對(duì)象里面,將其與不變的部分隔離開(kāi))。

添加新功能和重構(gòu)是兩種行為,一定要加以區(qū)分,并且同一時(shí)刻只做好一件事就行。

任何能夠查詢的東西,我都不太愿意去記,因?yàn)榕掳汛竽X擠爆了。所以說(shuō)大腦這個(gè)珍貴而有限的內(nèi)存主要做的事一定是建好索引,而非存儲(chǔ)數(shù)據(jù);另一方面,常用的數(shù)據(jù)也應(yīng)該存進(jìn)大腦,以提高效率,這和內(nèi)存中的緩存是一個(gè)道理

不要為了重構(gòu)而重構(gòu),一定是因?yàn)槟阆胱瞿臣聲r(shí)重構(gòu)恰好可以幫你做好,重構(gòu)的幾個(gè)時(shí)機(jī):添加新特性時(shí),修補(bǔ)錯(cuò)誤時(shí),復(fù)審代碼時(shí)。

程序有兩面價(jià)值“今天可以為你做什么”和“明天可以為你做什么”,如果只關(guān)注今天的工作,那么明天我們將無(wú)法工作,所以需要重構(gòu),來(lái)避免代碼出現(xiàn)以下四個(gè)情況:難以閱讀,重復(fù)太多,新行為無(wú)法簡(jiǎn)單添加,邏輯復(fù)雜。這四個(gè)情況導(dǎo)致的結(jié)果都是程序難以改變(修改),而唯一不變的就是改變:-D

代碼的壞味道——重構(gòu)的時(shí)機(jī):重復(fù)代碼、過(guò)長(zhǎng)函數(shù)、過(guò)大的類(lèi)、過(guò)長(zhǎng)的參數(shù)列、發(fā)散式變化、霰彈式修改、依戀情結(jié)、數(shù)據(jù)泥團(tuán)、基本類(lèi)型偏執(zhí)、switch語(yǔ)句、平行繼承體系、冗贅類(lèi)、夸夸其談未來(lái)性、臨時(shí)字段、過(guò)渡耦合的消息鏈、中間人、不適合的親昵關(guān)系、異曲同工的類(lèi)......

本書(shū)給出了一份重構(gòu)列表,包含了很多很多的重構(gòu)類(lèi)型的名稱、動(dòng)機(jī)、方法、范例,涵蓋了函數(shù)、對(duì)象、數(shù)據(jù)、表達(dá)式、調(diào)用、概括關(guān)系、大型項(xiàng)目等方方面面,值得我們借鑒,下面摘抄幾條作為示例。

當(dāng)我看見(jiàn)一個(gè)過(guò)長(zhǎng)的函數(shù)或者一段需要注釋才能讓人理解用途的代碼就會(huì)把這段代碼放進(jìn)一個(gè)獨(dú)立的函數(shù)中。短函數(shù)的好處:更可能被復(fù)用,讓高層函數(shù)看起來(lái)更清晰易懂,復(fù)寫(xiě)更容易?!岸獭钡暮x不在代碼行數(shù),而在于函數(shù)名稱和函數(shù)本體之間的語(yǔ)義距離。

如果一個(gè)類(lèi)的某個(gè)方法、字段被另一個(gè)類(lèi)頻繁使用,就應(yīng)該搬移該方法、字段。

混亂的繼承體系是一個(gè)嚴(yán)重的問(wèn)題,因?yàn)樗鼤?huì)導(dǎo)致重復(fù)的代碼,這正是程序員職業(yè)生涯的致命毒藥。它還會(huì)使修改變得困難,因?yàn)樘囟▎?wèn)題的解決策略被分散到了整個(gè)繼承體系,最終你的代碼難以理解。所以可以通過(guò)建立多個(gè)繼承體系,并利用委托來(lái)互相調(diào)用,使得原來(lái)負(fù)責(zé)多個(gè)任務(wù)的繼承體系變成多個(gè)負(fù)責(zé)單個(gè)任務(wù)的繼承體系。

......

感覺(jué)本書(shū)最大的問(wèn)題就是太老了(1999年),有些工具或者方法在如今技術(shù)進(jìn)步的情況下顯得有些多余,比如現(xiàn)在的IDE如Eclipse或者IDEA都有很強(qiáng)大的功能,書(shū)里提到的一些技巧完全用不著。不過(guò)經(jīng)典終究是經(jīng)典,里面的絕大部分思想我們?nèi)缃穸歼€是可以借鑒的,尤其是對(duì)于重復(fù)代碼的觀點(diǎn)——應(yīng)該堅(jiān)決消滅重復(fù)。

2017.9.8 后記

花費(fèi)了幾個(gè)月來(lái)看書(shū),又花了幾天來(lái)整理,希望對(duì)我們都有所幫助:-D。歡迎拍磚,我的主頁(yè)Mageek`s Wonderland。
查看原文

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/70368.html

相關(guān)文章

  • 后端好書(shū)閱讀推薦續(xù)

    摘要:續(xù)前文后端好書(shū)閱讀與推薦,幾十天過(guò)去了,又看了兩本好書(shū)還有以前看過(guò)的書(shū),這里依然把它們總結(jié)歸納一下,加入一些自己的看法有用的鏈接和可能的延伸閱讀,并推薦給需要的同學(xué)。 續(xù)前文 后端好書(shū)閱讀與推薦 - Mageek`s Wonderland ,幾十天過(guò)去了,又看了兩本好書(shū)(還有以前看過(guò)的書(shū)),這里依然把它們總結(jié)歸納一下,加入一些自己的看法、有用的鏈接和可能的延伸閱讀,并推薦給需要的同學(xué)。...

    OnlyLing 評(píng)論0 收藏0
  • 后端好書(shū)閱讀推薦續(xù)六)

    摘要:可以通過(guò)大數(shù)據(jù)生態(tài)的一系列工具生態(tài)來(lái)解決大數(shù)據(jù)問(wèn)題數(shù)據(jù)分片主要有兩種方式哈希和范圍。哈希的問(wèn)題是范圍查詢支持不佳,范圍的問(wèn)題是可能冷熱數(shù)據(jù)不均。 后端好書(shū)閱讀與推薦系列文章:后端好書(shū)閱讀與推薦后端好書(shū)閱讀與推薦(續(xù))后端好書(shū)閱讀與推薦(續(xù)二)后端好書(shū)閱讀與推薦(續(xù)三)后端好書(shū)閱讀與推薦(續(xù)四)后端好書(shū)閱讀與推薦(續(xù)五)后端好書(shū)閱讀與推薦(續(xù)六) Elasticsearch權(quán)威指南 El...

    shleyZ 評(píng)論0 收藏0
  • 后端好書(shū)閱讀推薦續(xù)六)

    摘要:可以通過(guò)大數(shù)據(jù)生態(tài)的一系列工具生態(tài)來(lái)解決大數(shù)據(jù)問(wèn)題數(shù)據(jù)分片主要有兩種方式哈希和范圍。哈希的問(wèn)題是范圍查詢支持不佳,范圍的問(wèn)題是可能冷熱數(shù)據(jù)不均。 后端好書(shū)閱讀與推薦系列文章:后端好書(shū)閱讀與推薦后端好書(shū)閱讀與推薦(續(xù))后端好書(shū)閱讀與推薦(續(xù)二)后端好書(shū)閱讀與推薦(續(xù)三)后端好書(shū)閱讀與推薦(續(xù)四)后端好書(shū)閱讀與推薦(續(xù)五)后端好書(shū)閱讀與推薦(續(xù)六) Elasticsearch權(quán)威指南 El...

    z2xy 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<