後端好書閱讀與推

NO IMAGE

後端好書閱讀與推薦

這一兩年來養成了買書看書的習慣,陸陸續續也買了幾十本書了,但是一直沒有養成一個天天看書的習慣。今天突然想要做個決定:每天至少花1-3小時用來看書。這裡我準備把這兩年來看的書挑出好的做一個簡要總結、即將要看的書做一個計劃,以便整理成書單留給自己學習,也順便推薦給需要的童鞋。

ps:本書單針對同一大類的知識點大致遵循著循序漸進,越學越深入越具體的順序。

JavaScript高階程式設計

JavaScript高階程式設計(第3版) (豆瓣) https://book.douban.com/subje…

有人可能會有疑問,後端為啥要學JavaScript呢?其實就是為了更好的使用node.js做鋪墊。這本書說是高階程式設計,其實還是比較基礎,但是難能可貴的是它幾乎包含了所有的基礎知識,而且對基礎知識的講解比較深入,至少看了過後就不會犯那些常見的錯誤(比如for迴圈繫結變數i,這個問題幾乎天天有人問(⊙﹏⊙)),能知其然、知其所以然,而且講了許多最佳實踐,所以還真的是高階。對於後端的同學可以只看基礎部分,不看瀏覽器相關的部分(當然時間多也可以瞭解)。

本書有很多值得學習的地方,比如

建議始終語句結尾要加分號,分支始終要加花括號,這樣雖然多了些小麻煩,但能省去很多大麻煩:提高解析器效能,避免壓縮錯誤,程式碼易讀性可維護性更好。
推薦使用 === 和 !== 而不是用 == 和 != ,這樣才能保證程式碼中資料的完整性,避免歧義。
with語句不僅容易造成混淆,還會影響效能,不建議使用。
函式按值傳參,沒有按引用傳參,基本型別就不用說了,即使是引用型別引數a,函式也並不能修改a,使得a指向堆裡面的另一個物件,所以也是按值傳遞。
函式傳參之時,使用物件字面量{}來封裝大量的可選引數,比直接命名多個引數更靈活。
函式宣告才有提升,函式表示式不會提升。
apply 和 call 的作用是擴充函式賴以執行的作用域,使得函式和物件(呼叫者)解耦,從而可複用。
建構函式與其相應的原型物件相互有指標指向,重寫函式原型物件會切斷已有物件與現有原型的聯絡。
建立自定義型別時,建構函式放置例項屬性,原型中放置共享的方法和屬性,這樣既保證了共享性,節約記憶體,也保證了私有性,達到封裝的目的。
利用惰性載入來提高程式碼執行效率。
將一個函式中多次用到的全域性物件儲存為區域性變數可以減少查詢開銷。
變數和陣列訪問時O(1),物件屬性訪問時O(n)。
減值迴圈優於加值迴圈,如果是大資料集,甚至可以展開迴圈來提升效能。

當然這本書也有點問題,主要就是時效性,本書主要按照ECMAScript 3 來講解,最多提到了ECMAScript 5 但是現在都有ECMAScript 8 了,所以在看相關部分的時候,要注意檢視最新的特性是否已經解決了某些問題(比如es8提出了Object.values 來直接獲得物件的所有值而不需要先Object.keys,再來按key遍歷),對本書要有所取捨(by the way ,幾乎所有技術書籍,甚至我這篇文章,遲早都會有時效性問題,畢竟我們處於一個變化巨大的時代,但這並不影響它們成為經典,只要我們有所取捨,取其神,去其形即可)。

深入淺出Node.js

深入淺出Node.js (豆瓣) https://book.douban.com/subje…

和一般的講node的書不同,這本書不是簡單的講一講怎麼使用npm,用一用express或者連一連mysql這樣的API文件式書籍,而是真正的深入淺出,本書首先介紹了node的來源,用處,讓我們知道它存在的意義,然後依次介紹了模組機制,非同步IO的實現,非同步程式設計的解決方案,記憶體控制,buffer,網路程式設計,web應用,程序管理,測試,產品化。

本書的優點相當多:

對於非同步IO的闡釋相當深入,首先闡釋了node是單執行緒的,能避免死鎖,同步等問題,而其非同步IO在核心中本質上是用了執行緒池,也能達到充分使用多核的效果,提升吞吐量。
對於非同步程式設計這個痛點作者提到了釋出訂閱模式,Promise,以及各種流程庫,更讚的是作者自己還寫了個庫EventProxy,我自己用過,可以說是非常好使的。這一章幫助我們很好的解決了深度巢狀的問題。
記憶體控制講到了分代垃圾回收機制,V8把記憶體分為新生代和老生代,新生代採用空間劃分(from、to)和複製機制來回收非存活物件,若新生代物件在多次複製後依然存活,則移動至老生代,老生代採用標記清除和標記整理的做法。這種針對不同代使用不同演算法的做法能夠到達效率最優的效果。同Java一樣,垃圾回收時也會stop the world,所以要儘量避免(雖然老生代採用了增量標記、延遲清理、增量式整理來減少停頓時間)低效或者頻繁的垃圾回收,比如要主動釋放變數,減少使用閉包等。
Buffer可以解決資料拼接時的中文亂碼問題;直接使用buffer來進行IO,網路傳輸可以提高吞吐量。
採用多程序來最大化利用核心的資源,控制代碼傳遞達到多程序監聽同一埠的目的。
把靜態資源交給nginx等伺服器或者CDN來處理,能提高效能。

本書的不足之處可能在於組織上吧,感覺有點頭重腳輕,比如對於初學者來說,一般想先看看node如何做web,或者做網路服務,體驗點成就感,然後才是學習其實現原理,而本書反了過來;而對於進階者來說,後面的web、網路服務部分似乎淺的有點用不上,有點雞肋(⊙﹏⊙)。但是我們可以根據自己的需要有選擇的進行章節閱讀,就能避免這個問題。

Java程式設計思想

Java程式設計思想 (第4版) (豆瓣) https://book.douban.com/subje…

本書可謂是經典了,它不是基礎知識面面俱到的入門書籍(Java核心技術·卷1:基礎知識(原書第9版) (豆瓣),這本書就講全了基礎知識,而且不是淺嘗輒止,還進行了深入探討,所以也推薦),而真的是如翻譯的書名一樣,體現了Java的思想,是Java中一些精要的集合,我們不必按照作者的順序去閱讀,可以根據需要選擇性的閱讀。本書還融合了許多設計模式,需要我們去感悟其中的思想。

這本書比較精彩的部分:

把物件導向程式設計人員分為兩類:“類建立者”(建立新資料型別的人)以及“客戶程式設計師”(在自己的應用程式中採用現成資料型別的人),前者負責構建類,只開放必要的東西而隱藏其他細節(開放封閉原則),後者負責蒐集這些類來完成特定任務。
需要採取一種最適合自己需要(以及習慣)的方法來制定計劃。不管制訂出的計劃有多麼小,但與完全沒有計劃相比,一些形式的計劃會極大改善你的專案。

首次建立物件或者訪問該類的靜態欄位、方法時會初始化這個類,static初始化僅在第一次執行,其它欄位每次建立物件都會執行,我這裡順便總結一下物件的初始化過程:

   (1) 主類的每一個父類由高到低按順序初始化靜態成員及其靜態初始化塊,無論靜態成員是否為private。 
(2) 主類靜態成員的初始化,靜態初始化塊的初始化。
//建立例項時,如果不建立例項,則後面的不執行 
(3) 主類的父類由高到低進行預設構造方法的呼叫。在呼叫每一個父類的預設構造方法前,先進行對此父類進行非靜態成員,
非靜態初始化塊的初始化。  
(4) 主類非靜態成員的初始化,非靜態初始化塊的初始化。 
(5) 呼叫主類的構造方法。

final的引用型別變數本身是不可變得,但是其引用的物件是可變的(陣列也適用這個規則),所以不要期望能夠一步達到一個常數物件的效果
方法程式碼少或者想禁止覆蓋時使用final方法能夠得到一定程度的效能提升。
將一個方法呼叫同一個方法主體連線到一起就稱為“繫結”(Binding)。若在程式執行以前執行繫結(由編譯器和連結程式,如果有的話),就叫作“早期繫結”,“後期繫結”,它意味著繫結在執行期間進行,以物件的型別為基礎。後期繫結也叫作“動態繫結”或“執行期繫結”。Java 中繫結的所有方法都採用後期繫結技術,除非一個方法已被宣告成 final。這意味著我們通常不必決定是否應進行後期繫結——它是自動發生的。
Java 包含了一個名為 Throwable 的類,它對可以作為違例“擲”出的所有東西進行了描述。Throwable 物件有兩種常規型別(亦即“從 Throwable 繼承”)。其中,Error 代表編譯期和系統錯誤,我們一般不必特意捕獲它們(除在特殊情況以外)。Exception 是可以從任何標準 Java 庫的類方法中“擲”出的基本型別。此外,它們亦可從我們自己的方法以及執行期偶發事件中“擲”出。
對於作為程式一部分的每個類,它們都有一個 Class 物件。換言之,每次寫一個新類時,同時也會建立一個Class 物件(更恰當地說,是儲存在一個完全同名的.class 檔案中)。在執行期,一旦我們想生成那個類的一個物件,用於執行程式的 Java 虛擬機器(JVM)首先就會檢查那個型別的 Class 物件是否已經載入。若尚未載入,JVM 就會查詢同名的.class 檔案,並將其載入。

如上所述,本書也有時效性問題,所以要配合最新的Java8甚至Java9來查閱;同時,本書的程式碼實在是太多,有些可以忽略不看,並不影響理解。
本書作為一本整體大致地把握Java的書籍是合適的,但是Java實在是太大了,要真正細緻的掌握每一個知識點比如多執行緒、網路程式設計、Spring,還得看專門的書,比如下面要講的這本。

Java併發程式設計實戰

Java併發程式設計實戰 (豆瓣) https://book.douban.com/subje…

本書從併發性和安全性的基本概念入手逐步深入,講到用類庫構建執行緒安全類,然後講到了如何利用多執行緒來提升吞吐量,Java中的一些現有多執行緒框架的使用,效能測試,最後講了顯示鎖,原子變數等進階知識點。基本囊括了能用到的多執行緒所有知識點。

本書亮點:

執行緒安全性定義:當多個執行緒訪問某個類時,這個類總是能表現出正確的行為。執行緒安全類自己封裝了必要的同步機制,呼叫者無需再進一步採取同步措施。無狀態的物件一定是安全的。
併發程式設計由於不恰當的執行時序造成錯誤叫做競態條件,最常見的就是先檢查後執行的操作,比如i 就是典型的例子,
無狀態的類新增一個狀態,若該狀態執行緒安全,則這個類也安全,但是若新增了多個狀態,僅僅是每個狀態執行緒安全還不夠,還需要保證單個操作中同時更新所有狀態(如果每個狀態都是獨立的就不必)
內建鎖是可重入的,這意味著獲取鎖的粒度是執行緒而不是呼叫,也就是說鎖和一個執行緒對應。
加鎖機制可以保證可見性和原子性,而volatile只能保證可見性
ConcurrentHashMap採用了分段加鎖的機制來實現更大程度的共享,任意數量讀執行緒可以訪問Map,一定數量的寫執行緒可以並行修改同一個Map,一般情況只有在需要獨佔訪問Map時才應該放棄使用ConcurrentHashMap。
使用tryLock來替換會永遠等待的內建鎖,這樣就能消除死鎖發生的可能性。
確保執行緒在獲取多個鎖時才用一致的順序,也能避免一些死鎖。
不應當依賴於執行緒優先順序來實現業務邏輯,因為這與平臺有關,不能得到保證。
避免不成熟的優化,首先使程式正確,必要時再提高執行速度-如果嫌它不夠快的話。
使用併發安全的容器類、讀寫鎖、不可變物件、原子變數等來替換獨佔鎖,提高吞吐量。
使用顯示鎖時,要在finally中釋放,因為它不會像內建鎖一樣自動釋放。
一般情況下公平鎖(先到先得)會比非公平鎖的效能低得多(數倍,數十倍),不必要的話不要用公平鎖,非公平鎖在統計意義上是公平的,就夠用了,而且ReentrantLock 預設就是非公平的,內建鎖也是。

如上所述,本書時效性也有問題,主要用的是Java5,6,所以也要注意查閱最新文件對比(實戰Java高併發程式設計 (豆瓣) https://book.douban.com/subje… 這本書在時效性方面就要強一些,講到Java8了,而且也比較通俗易懂,推薦~),另外,Swing那一段可以跳過不看了。

Java Web高階程式設計

Java Web高階程式設計 (豆瓣) https://book.douban.com/subje…

這本書的強大之處就在於一本書幾乎包攬了java web 所有的主流技術,所謂此書在手,Java我有(⊙﹏⊙)……開個玩笑,本書非常大非常厚,所以也非常全,所以我也並沒有看完,但是我看過的部分真的讓我認為這是一本好書。本書從servlet原理講起,講到jsp,一步步講到Spring,過度很自然,讓人明白Spring存在的理由,然後講了Hibernate(雖然我沒看),最後講了Spring security,可謂一氣呵成,同時又不失條理,系統性很強,看完之後對於Java web 應該能有個整體的把握。

本書亮點:

多使用jdk7的try with source ,它會幫助自動釋放資源,減少錯誤。
Java EE 一般採用子女優先類載入方式,Java SE 一般採用雙親優先類載入方式。
Servlet是所有web應用程式核心類,它是唯一即可以直接處理和響應使用者請求又可以將處理工作委託給其他部分的類。java EE 7 唯一支援的Servlet協議就是http。
表示層與業務層應該分開,所以jsp中不應使用Java程式碼,而且jsp表示式EL本身已足夠強大。
Controller依賴於Service,Service依賴於Repository,Repository依賴於資料庫,這四者就像食物鏈中的肉食者,雜食者,植物,大自然。不同於傳統MVC架構,這種架構中Service才是真正的業務邏輯,Controller是負責不同的頁面邏輯,比如web頁面和移動應用的API,這種架構能夠複用真正的業務邏輯,優於MVC。

我感覺這本書唯一的缺點就是太厚了吧:-D,會嚇跑許多人(包括我)。

Head First 設計模式

Head First 設計模式(中文版) (豆瓣) https://book.douban.com/subje…

這本書最大的特點就是不拘一格講知識,他不會板起臉來告訴你這個叫觀察者模式,那個叫裝飾器模式……而是通過一些通俗易懂的例子(會飛會叫的鴨子,氣象站檢測應用的建設)和豐富的圖例、遊戲(運用了認知科學的方法)來說明不同的設計模式的含義、用途、優點和缺點,使人印象深刻,容易理解和記憶。

本書展示了很多有意義的設計原則,比如:

封裝變化,即找出應用中的變化之處,把他們獨立出來,不要和不變的程式碼混在一起。所以設計系統之時就要開始考慮可能變化的東西把它隔離出來,並且在做的過程中可能會需要重構,畢竟唯一不變的就是變化。
針對介面程式設計,而不是實現程式設計。也就是變數的宣告應該是超型別,這樣執行時就會根據實際情況執行到真正的行為,而不必綁死在超類的行為上。
多用組合,少用繼承。組合比繼承具有更大的靈活性和更穩定的結構,只有當確實是 is-a 的時候才應該使用繼承
……

對於設計模式初學者來說,這本書似乎比四人組的設計模式更容易接受,因為它不是那麼嚴肅,不是那麼學究,當然如果希望嚴肅的學習,或者本身水平較高,那還是看四人組的比較好~

程式設計師修煉之道

程式設計師修煉之道 (豆瓣) https://book.douban.com/subje…

本書可以說是一本學習方法論,或者工作方法論的書,再高一點可以說是一本哲學的書。本書原名The Practical Programmer,亦即注重實效的程式設計師,全書圍繞注重實效展開討論,包括注重實效的哲學(負責,變化,權衡,管理知識,交流)、途徑(避免重複,隨時記錄,估計)、工具(文字,shell,遊戲,原始碼控制)、偏執或者說講究(規範合約、斷言、異常使用)等等等等。

本書從推薦序開始就相當精彩:

如果僅僅以普通的瀏覽方式閱讀就會很簡單的陷入“啊,這個我知道啊,啊,這個我瞭解啊,嗯,這個以後要注意”的套路中。這樣的閱讀方式只會強化原有的自己知道的知識,而不大可能把“以後需要注意”這部分全部內化。所以自負的讀者讀完必然覺得“哈哈,高手不過如此,大部分我也知道嘛”,而不是“是的,我還有不少要注意”。這一段可謂是抓住了我的一個大毛病,我以前看完書老是覺得啥都懂了,可是真開始做還是一臉懵逼,這就是為啥我們上學都有作業做的原因,體會很深刻啊
定期為你的知識資產投資,比如每年學習一門新的語言來拓寬思維,每季度讀一本書(是不是有點少:-D)。
不要重複自己,重複是維護的災難(因為你可能根本記不住哪裡還用了這個東西)。
估算,以避免意外。學會估算,並發展到對事物的數量級有直覺的程度,就能更好的確定任務可行性。
按合約設計,這樣才能明確責任和權利,解決與人打交道的問題。說實話,做了兩個小專案我就真的體會到了這一點的重要性,沒有文件,沒有合約,只會導致進度拖拉,到處甩鍋,軍心不穩
分析工作流,以改善併發性,這樣確定哪些任務可以並行,哪些不可以,從而更合理的安排,加快進度。當然這是屬於較大的任務的處理方法,小任務有這些分析的時間我都做完了

本書讀起來可謂非常暢快,但是要落實真的是不容易,而且我覺得應該反覆讀,因為每增加一些工作經驗就會遇到一些問題,對書裡面提到的要點也就感悟更深,從而能更好的解決問題。

架構即未來

架構即未來:現代企業可擴充套件的Web架構、流程和組織(原書第2版) (豆瓣) https://book.douban.com/subje…

這本書乍一聽可能會覺得它是講的架構是諸如MySQL 讀寫分離,redis cluster,CDN,負載均衡等架構問題,看完緒論和第一章才發現不是那麼回事(⊙﹏⊙),原來它前面很大的篇幅都在講人事上的架構,後面才是技術上的架構,會不會有種受騙的感覺?其實不必,這本書相當於是站在了更高的角度來看問題,畢竟要把技術上的事做好做大都離不開強大的團隊,離不開完善的人事管理。

結構上本書分4部分:團隊的組織、管理和領導,構建可擴充套件技術平臺的方案與危機管理,可擴充套件的架構方案,新興技術如大資料雲端計算等的架構。

我感覺比較精彩的一些點是:

如果汽車沒有油量表和速度表,大多數人都不會考慮開這種車,同理,系統也需要一系列指標幫助我們達到希望的結果。
管理是推,領導是拉。領導設定目的地和路線圖,管理設法達到目的地。
責任不清,則意味著有些事沒人去做,或者一件事被多個人做了,直接後果就是進度拖拉,效率低下。當你在定義一個組織的角色和責任時,就是在設計一幅權力下放的藍圖。
對團隊而言,少於6人就沒必要單獨成為一個團隊,超過15人經理管理會產生困難,成員之間溝通也會更困難,所以一個團隊的人數要根據經理的能力,人員熟悉程度,要實現的目標來共同制定。
總體而言,相信自己被賦予權力的個人會比那些相信自己只是在執行命令的人會有更高的效率,在我理解來就是主觀能動性更高,有了主人翁意識自然就會盡力去把事情做好,而非僅僅是打工仔:-D。
架構原則:監控設計能使我們進行自我修復自我診斷,在使用者發現問題前就解決問題;多活資料中心可以達到負載均衡和容災的目的;使用成熟的技術,謹慎的線上上系統採用新技術,因為通常有較高的故障率,我們一般可以自己先做許多的試用,再決定是否使用;水平擴充套件而非垂直擴充套件,亦即系統擴充套件性依賴於更多的機器而非更強大的機器。
……

2017.8.3 後記

7.26 就開始著手寫了,但是為了能更好的總結這些書,我又把它們全部過了一遍然後才寫,直到 8.3 才寫完,希望能起到一些作用。後面我還會持續更新更多的好書,會涉及到Linux、Jvm、Redis、MySQL、Docker等,歡迎拍磚交流,我的主頁 – Mageek`s Wonderland http://mageek.cn/archives/33/