Unix編程藝術--讀書筆記(轉)

 

今天掃了一遍Unix編程藝術。很是粗略看了下目錄。前端

收穫幾個名詞:模塊化、文本化、透明性、正交性、數據驅動、專用代碼生成、可配置
--------------------- 
版權聲明:本文爲CSDN博主「just_record」的原創文章,遵循CC 4.0 by-sa版權協議,轉載請附上原文出處連接及本聲明。
原文連接:https://blog.csdn.net/just_record/article/details/79774034git

 

I-場景
1. 哲學
機制而不是策略,自由放縱注意風格,產生了多樣性。好比Unix應用程序提供不少的行爲選項,讓非技術的用戶暈頭轉向,而失去了不少用戶;可是策略相對短壽、機制纔會長存,具備很大的靈活性。
趣味性是一個峯值效率的標誌。對於程序員和開發人員來講,若是完成某項任務所須要付出的努力對他們是個挑戰又剛好還在力所能及的範圍,他們就會以爲頗有樂趣。 而UNIX有Hack趣味。
UNIX哲學是自下而上的,注重實效,鼓勵分清輕重緩急的感受以及懷疑一切的態度,並鼓勵你以幽默達觀的態度對待這些。
簡潔是UNIX程序的核心風格。 UNIX哲學的KISS原則:Keep it simple, stupid!
先製做原型,再精雕細琢。優化以前,先肯定能用。
2. 歷史–雙流記
本章主要回顧UNIX的歷史,來闡明現在的UNIX文化爲何呈現當前的狀態。 兩個歷史分別是UNIX的起源和歷史以及黑客的起源和歷史程序員

UNIX的起源和歷史
UNIX的祖輩是CTSS–兼容分時系統,父輩是頗具開拓性的Multics項目(試圖創建一個具有衆多功能的系統);
創世紀:1969-1971年,UNIX誕生於貝爾實驗室;
*出埃及記:1971-1980,C語言的加入,其表述方式帶來的可讀性、可改性和可移植性,給UNIX帶來了必定的成功。
TCP/IP和UNIX內戰:1980-1990, TCP/IP的引入,讓UNIX更加有活力。 然而微軟的興起和AT&T的拆分,讓UNIX進入了煉獄。UNIX的產業化,破壞了UNIX源碼的自由交流,而自由交流卻正是滋養UNIX系統早期的活力。
反擊帝國:1991-1995,Linus Torvalds宣佈了Linux項目,依賴分佈式開發和patch(補丁)工具,加入了Internet和圖形界面,實現了Unix的平價之夢,並拼裝了UNIX的傳統元素。 1995年以後,UNIX的故事就變成了開源運動的故事。
黑客的起源和歷史:1961-1995
遊戲在校園的林間:1961-1980年,MIT的人工智能實驗室的程序員應該是第一批自稱」hacker「的人;
互聯網大融合與自由軟件運動:1981-1991. 1983年,BSD植入了TCP/IP,UNIX文化和ARPANET文化開始融合。RMS建立了GNU項目,致力於編一個徹底自由的操做系統。自由軟件術語的提出,讓黑客文化更加有自我意識。
Linux和實用主義者的應對:1991-1998. Linus Torvalds巧妙地跨越了GPL和反GPL的派別之爭。他利用GNU工具包搭建了自創的Linux內核,用GPL的傳染性質保護它。Torvalds明確的表示他認爲自由軟件一般很好,但他偶爾也用專有軟件,他拒絕成爲狂熱分子。
開源運動:1998年及以後
一個部落的零距離可能來自他們維護的代碼庫,或是一個或多個有着超凡影響力的領導者,或是一門語言,一個開發工具,或是一個特定的軟件許可,或是一種技術標準,或是基礎結構某個部分的管理組織。 1995年以後,Linux扮演了一個特殊的角色:既是社區內多數軟件的統一平臺,又是黑客中最被承認的品牌。整個黑客文化開始凝聚在一個共同目標:推進Linux和集市開發模式向前發展。
」開源「背後另外一個意圖就是但願將黑客社區的方法以一種更親和市場、更少對抗性的方式介紹給外部世界。
Unix的歷史教訓
距開源越近就越繁榮;
過分依賴任何一種技術或者商業模式都是錯誤的–相反,保持軟件及其設計傳統的靈活性纔是生存之道;
別和低價而靈活的方案較勁;
真正的專業和奉獻精神,正是咱們在屈服於世俗觀念的」合理商業作法「以前的所做所爲。
3. 對比:Unix哲學同其餘哲學的比較
操做系統的風格元素
操做系統的統一性理念。好比UNIX系統的」一切皆文件「模型和由此基礎上創建的管道概念。
多任務能力。Unix系統擁有搶先式多任務的能力。 多任務和多用戶不是一回事。
協做進程:UNIX的IPC(進程間通訊方式)很靈活。
內部邊界: Unix是相信程序員的,可是程序員不能破壞其餘人的數據,因此Unix設立了內部邊界來防範惡意用戶或者有缺陷的程序。
開發的門坎: Unix將編譯器和腳本工具放在默認安裝中,支持了一種跨越衆多機器的玩家開發文化。
操做系統的比較
列舉了若干操做系統的優缺點。
種什麼籽,得什麼果
競爭對手的一些缺點: 好比不可移植性、不具有良好的網絡支持能力。
而Windows在服務器上的缺陷(安全等緣由),使得Linux取得了重大突破。
就像造房子同樣,在堅實的地基上修理上層建築固然要比更換地基而不破壞上層建築來得容易。
II–設計
4. 模塊化:保持清晰,保持簡潔。
早期的Unix程序員擅長模塊化是由於他們被迫如此,若是沒有良好的架構,操做系統就會崩潰。
封裝良好的模塊,不會過多向外部披露自身的細節,不會直接調用其餘模塊的實現碼,也不會胡亂共享全局數據。
具備最佳尺寸的模塊並不意味着代碼有高質量,還得考慮緊湊性和正交性。
緊湊性就是一個設計可否裝入人腦。好比一個設計有經驗的用戶不須要操做手冊,這個設計就是緊湊的。
正交性是指任何操做均無反作用,每個動做只改變一件事,不會影響其餘。
不要重複自身(don’t repeat yourself)。
軟件的分層:自頂向下和自底向上。 當自頂向下和自底向上發生衝突時,頂層的應用邏輯和底層的域原語集必須用膠合邏輯層來進行阻抗匹配。 膠合層是個挺討厭的東西,必須儘量薄。
OO語言使抽象變得容易,可是過多的層次破壞了透明性,咱們很難看清層次,沒法理清代碼的運行過程。
單個函數與其說是行數計算問題,不如說是內部複雜度性的問題(好比說局部變量太多、代碼存在太多縮進)。
5. 文本化:好協議產生好實踐
設計文件格式和應用協議須要考慮的重要方面:互用性、透明性、可擴展性以及經濟型。
使用二進制的惟一正當理由:處理大批量的數據集或者關心時間或指令開銷。
數據文件元格式有多重不一樣的元格式,好比DSV、RFC 82二、Cookie-Jar、Record-Jar、XML、Windows INI等;
應用協議若是是文本格式的,憑肉眼能夠很容易地分析,不少事情變得容易。能夠看看SMTP、POP3和IMAP三種經典的應用協議。
應用協議元格式:儘管網絡帶寬比存儲昂貴許多,須要重視事物處理的經濟性,可是文本格式的透明性和互用性優點仍是十分顯著,大多數設計者仍是選擇了採用可讀性更高的文本格式。好比HTTP協議、BEEP協議、XML-RPC/SOAP/Jabber協議。
6.透明性:來點光
在第五章中,討論了數據格式和應用協議進行文本化的重要性,文本化讓透明性和可顯性的品質獲得了提高。
* 若是實際上可以預測到程序行爲的所有或大部分狀況,這個程序就是透明的;
* 若是程序能夠幫助人們創建「作什麼、怎樣作」,這個軟件系統就是可顯的。好比對用戶來講,文檔有助於可顯性; 對程序員而言,好的命名規範有助於提升可顯性。
* 要追求代碼的透明,最有效的方法很簡單,就是不要在具體操做的代碼上疊放太多的抽象層。
* 透明的系統在bug發做時,更容易實施恢復措施;同時,透明的系統更容易讓人理解,從而更加方便維護。github

7. 多道程序設計
UNIX最具特色的程序模塊化方法就是將大型程序分解成多個協做進程。
多個併發進程除了帶來模塊化的好處以外,另外一個緣由是爲了更強的安全性。
UNIX IPC:把任務轉給專門程序(shell out)、管道/重定向(管道主要缺點是單向性,命名管道能夠做爲二者間的配接器)、從進程、對等進程(臨時文件、信號、套接字、共享內存)。
8. 微型語言:尋找歌唱的樂符
UNIX班有個長期傳統,存在小型的、爲專門應用領域特製、大量減小程序行數的語言。 好比無數Unix排版語言(troff/pic)、shell使用程序(awk/sed/dc/bc)和軟件開發工具(make/yacc/lex等)。 微型語言與腳本語言之間的界限都很模糊。
* 一切可計算的問題均可以計算,叫作圖靈完備。
* 明白微型語言在何時什麼場景下使用。
* 某些狀況下,須要咱們咱們去設計一個微型語言。 首先要儘量保持微型語言的簡單(複雜度),思考可否經過擴展或者嵌入現有腳本語言來實現本身的微型語言(這是實現命令性語言的正確方法),慎用宏。shell

9. 生成:提高規格說明的層次
數據比程序邏輯更易駕馭,更加直觀,透明性和清晰性方面更勝一籌。
數據驅動編程,將代碼和數據結構劃分清楚,在改變程序邏輯時,只要改變數據結構而不用修改代碼。
專用代碼的生成,好比用工具生成HTML代碼。儘量少幹活,建設性的懶惰是大師級程序員的基本美德之一。
10.配置:邁出正確的第一步
配置在哪裏?在下面這些地方,查詢一般按照下面的順序進行,後面的設置會覆蓋前面的設置。
運行控制文件,在/etc/目錄下。
環境變量,系統環境變量、用戶環境變量。
命令行選項
上述配置是從最不易改變到最易改變的順序排列的。
11. 接口:Unix環境下的用戶接口設計模式
程序的接口就是程序同用戶或者其它程序通訊的方法總和。
最小立異原則:少來標新立異,是全部接口設計中的通用原則,且並不是僅侷限於軟件設計。一心不能二用,應該把中心放在接口所屬的任務上。而這個原則,也不該被理解爲機械的保守主義。 若有可能,儘可能容許用戶將接口功能委派給熟悉的程序來完成,不能委派時就效仿。
Unix程序中存在豐富的接口風格:面向行的、面向屏幕字符陣列的和基於X的,不一樣的接口風格,適用於不一樣的任務。
接口的幾種度量標準:簡潔、表現力、易用、透明性和腳本化能力。
CLI和可視化接口之間的權衡。命令行更具表達力,尤爲是針對複雜的任務,同時具備高度的腳本化能力,可是CLI須要費勁地記憶(易用性低),而且透明性也很是低。好比說數據庫的SQL語句和圖形界面操做來講,能夠很明顯看出兩者之間的差異,一樣命令行的計算器和圖形界面的計算器對比也比較明顯。
Unix接口設計模式。根據輸入和輸出能夠分爲這些模式:過濾器模式(好比grep)、Cantrip模式(好比clear)、源模式(不須要輸入,好比ls)、接收器模式(只接收不輸出,例子較少,好比lpr)、編譯器模式(既無標準輸入也無標準輸出,將錯誤消息發送到標準錯誤端)、ed模式(好比ftp、sh)、Roguelike模式(字符陣列好比vi)、「引擎和接口分離」模式(MVC模式做爲GUI原型的建議)、CLI服務器模式
網頁瀏覽器做爲通用前端,無需編寫一個定製的GUI前端。
12. 優化
過早優化是萬惡之源
不到萬不得已,儘可能別去優化一個工做中的系統,而是等上幾個月,期待硬件性能更好。
先估量,再優化。經過profiler,去明確瓶頸所在,而profiler自己也是存在工具偏差的。
最有效的代碼優化方法是保持代碼短小簡單。目標機器是分層的,將核心的數據結構和指令代碼放在快速緩存。
快速處理器的另外一個效應是性能常常受限於I/O以及網絡事務的開銷,要儘可能避免協議的往返。
有三種常規策略來減小延遲:批操做、重疊操做、緩存操做結果。
13. 複雜度:儘量簡單,但別簡單過了頭
「Keep it simple, stupid」, 對於簡單的理解實際上是很複雜的。
複雜度的三個來源:程序員實現的複雜度、顧客和用戶使用的複雜度以及代碼量,關於怎麼去折中,是沒有標準答案的。
經過五個編輯器的故事,瞭解編輯器在處理更復雜任務時產生的不一樣程度的選擇複雜度。
吝嗇原則:只有實證了其它方法不通時才寫龐大程序。
III– 工具
14. 語言:C仍是非C
Unix下面存在很是多的語言種類。一是由於Unix普遍應用於研究和教學平臺,二是由於應用設計和實現語言的合理搭配對生產力有極大促進。
C語言很厲害、很經濟。可是要求程序員本身完成內存管理,很複雜,而且隨着硬件設備的性能提高,主要瓶頸集中在I/O事件等待、網絡延遲以及緩存列填充等限制上,因此Python、Java等語言慢慢興起。
15. 工具:開發的藝術
本章將介紹Unix下的開發策略–編譯代碼、管理代碼配置、性能分析、調試以及自動完成各類髒活累活。 這一套工具比起IDE更加靈活。
* 編輯器選擇:vi和Emacs
* 專用代碼生成器:yacc、lex
* 自動化編譯:make。 一個笑話:輸入」make love」,輸出是「Don’t know how to make love」。
* 版本控制系統
* 性能分析:gprof數據庫

16. 重用:論不要從新發明輪子
不少人喜歡本身造輪子,由於庫可能不是透明的、充滿bug,還不如本身來的痛快。
隨着開源的提出,咱們應當選擇好的輪子,這樣能夠節省時間,提升效率。
不少開源的網站,如github等。
注意一些許可證的問題。
IV–社區
17. 可移植性:軟件可移植性與遵循標準
移植性一直是Unix的主要優點,可移植的戒律每每在架構、接口和實現上施加了一種簡單化的影響,提升了項目成功的概率也下降了生命週期的維護成本。
C語言、Unix標準,IETF、RFC標準,一系列的標準和草案讓接口更加規範,從而更方便移植。
編程語言的可移植:Java和Python具有良好的可移植性。
可移植工具:autoconf來處理移植問題,configure/make/make install來乾淨利落的編譯。
可移植性須要標準,而開放源代碼一樣給標準化的過程帶來了重要的影響。
18. 文檔:向網絡世界闡述代碼
文檔通常分爲兩類,所見即所得(word)和標記爲中心(XML、markdown),各有優缺點;
編寫Unix文檔最佳實踐:信息密度適中、不要過於龐大、也不要省略功能細節和存在的問題、將文檔放在網上。
19. 開放源碼:在Unix新社區中編程
開源開發的規則很簡單:源碼公開、儘早發佈-常常發佈、給貢獻以表揚(物質獎勵或者精神獎勵)
與開源工做者協同工做的最佳實踐:版本控制系統(Git、svn等)、良好的代碼註釋、良好的代碼規範和文件命名規範、測試好再發布大媽、良好的交流實踐(郵件列表、網站等)。
許可證的邏輯,挑選合適的許可證。
20. 將來:危機與機遇
回顧過去,網絡互聯、位圖圖形顯示以及我的計算機這三個特殊的技術變化驅動了Unix設計風格的重大變革。
儘管伴隨着許多創新,但全部對這三個技術的響應都保持着Unix的設計準則–模塊化、透明性、機制同策略分離以及以前提到的品質。
Unix對GUI的支持較弱。Unix的API沒有使用異常(C語言缺少拋出異常的機制)。
從歷史來看,咱們只要可以從錯誤中汲取教訓,文化薪火相傳,Unix是不會輸的。編程

相關文章
相關標籤/搜索