擁抱 unix 哲學
每個程式設計師入門的第一堂和第二堂課應該是和 unix 哲學相關的內容,簡言之就是:做一件事,做好它。具體點:
小即是美。
讓程式只做好一件事。
儘可能早地建立原型。
可移植性比效率更重要。
資料應該儲存為文字檔案。
儘可能地榨取軟體的全部價值。
使用 shell 指令碼來提高效率和可移植性。
避免使用可定製性低下的使用者介面。
所有程式都是資料的過濾器。
選一個樣板,follow 之
每個 NBA 新秀都有自己的樣板,我們也總習慣稱某足球新星為『小羅』,『小小羅』。樣板為你提供了可模仿可追趕的物件,同時也讓你審視自己究竟想成為什麼樣的程式設計師。我的樣板是 Greg Pass 和 Werner Vogels,雖然我這輩子可能也達不到他們的高度,可這並不妨礙向著我心目中的明星一步步靠近。
寫程式碼,而不是調程式碼
寫軟體最糟糕的體驗恐怕是邊寫邊調,寫一點,執行一下,再寫一點。是很多程式設計師都會這麼幹。原因有二:1. 不熟悉相關的程式碼(類庫),需要邊寫邊執行保證程式碼的正確。2. 現代程式語言的 REPL (Read-Evaluate-Print-Loop,就是語言的 shell)能力助長了這一行為。
寫系統軟體的人很少這麼做。他們手頭糟糕的工具讓邊寫邊調的行為成為效率殺手 —— 如果稍稍改動,編譯就要花去幾分鐘,甚至更長的時間,你還會這麼幹麼?所以他們往往是寫完一個模組,再編譯除錯。(由此看來,高效的工具有時候是把雙刃劍啊)
我覺得寫程式碼就跟寫文章一樣,構思好,有了大綱,就應該行雲流水一樣寫下去,一氣呵成,然後回過頭來再調整語句,修改錯別字。如果寫完一段,就要回溯檢查之前寫的內容,效率很低,思維也會被打散。
靠邊寫邊調做出來的程式碼還往往質量不高。雖然區域性經過了雕琢,但整體上不那麼協調,看著總是彆扭。這就好比雕刻,拿著一塊石頭,你先是精修了鼻子,然後再一點一點刻畫面部。等修到耳朵的時候,鼻子可能過大或過小,即便再精美,它也得不到讚賞。
聰明地除錯
軟體總會出問題。遇到問題,很多程式設計師就會用 IDE 在各種可能的地方加斷點除錯,如果沒有 IDE,那麼各種 print/log 手段一齊丟擲,有棗沒棗打一杆子再說。
優秀的程式設計師會在撰寫程式碼的時候就考慮到除錯問題,在系統關鍵的節點上注入各種等級的除錯資訊,然後在需要的時候開啟相應的除錯級別,順藤摸瓜,避免了不靠譜的臆測。這是除錯之『道』。
很多問題開啟除錯開關後就原形畢露,但有時候靠除錯資訊找到了初步原因,進一步定位問題還需要具體的工具,也就是除錯之『術』,如上文所述之斷點除錯。有些時候,遇到靠類似 gdb(如 python 的 pdb)的工具無法解決的問題時(如效能問題),你還需要更多的除錯工具做 runtime profiling,如 systemtap。
使用標記語言來寫文件,而非 word/power point
不要使用只能使用特定軟體才能開啟的工具寫文件,如 word/page 或者 power point/keynote。要使用『放之四海而皆可用』的工具。
java 的市場口號是:『一次編寫,到處執行』,對於文件,你也需要這樣的工具。Markdown (md) / Restructured Text (rst)(以及任何編輯語言,甚至是 jade)就是這樣的工具。透過使用一種特定的文字格式,你的文件可以被編譯成幾乎任意格式(html,rtf,latex,pdf,epub,...),真正達到了『一次編寫,到處執行』。最重要的是,由於邏輯層(文章本身)和表現層(各種格式,字型,行距等)分離,同樣的文件,換個模板,就有完全不一樣的形象。
除非必須,我現在所有的文件都是 md 或者 rst 格式。
一切皆專案
程式設計師的所有產出應該專案制。軟體自不必說,文件和各種碎片思想也要根據相關性組織成專案。舉一些我自己的例子:
我的部落格是一個名叫 jobs 的 github 專案
我的微信文章全部放在 craftsman 這個專案中
我學習某種知識的過程(比如說 golang)會放在一個或若干個專案中
我工作上每個專案的各種產出(包括會議紀要)會按照專案對應生成 git repo
專案制的好處是具備可回溯性。每個專案我可以用 git 來管理,這樣,幾乎在任何一臺裝置上我都可以看到我之前的工作。想想你三年前寫的某個文件,你還能找到它麼?你還能找回你的修改歷史麼?
專案制的另一大好處是可以在其之上使能工具。比如說你看到的這些微信文章,我隨時可以
make publish YEAR=2014
來生成包含了 2014 年我所寫文章的 pdf。
心態開放,勇於嘗試
在程式設計師社群裡,語言之爭,系統之爭,軟體思想之爭幾乎是常態。python vs ruby,go vs java vs erlang vs rust,scala vs cljure,OOP vs FP,iOS vs Android。其實不管黑貓白貓,抓到老鼠的就是好貓,facebook 還用 php 呢。程式設計師應該用開放的心態去包容新的技術,新的思想,勇於嘗試,而不是立即否定。這個世界最悲哀的是,手裡有把錘子,看什麼都是釘子(或者說,眼裡就只能看見釘子)。
我接觸 mac 時間不過三年。可這三年時間,我從對 mac 不屑,到深深熱愛,最終成為 mac 的一個重度使用者。很多東西用過才知道,不嘗試不接觸我可能永遠活在自己下意識構築的無形之牆的另一邊。
最近的兩年裡我學習了 erlang,golang,scala,還看了一點點 clojure 和 rust。目前我熱衷於 golang 開發,但並不妨礙我繼續擁抱 python 和 nodejs。每個程式設計師要在不同的層級上有一門主力語言,比如說我:
系統級(realtime):C (可能以後會是 rust)
系統應用級(realtime):erlang(養成中)
系統應用級(非 realtime):golang(養成中)
應用級:python
Web 後端:python,nodejs,golang
Web 前端:javascript
裝置端:Android Java(暫無計劃)
這個列表你不必參考,我只是想用此來說明心態越開放,你看到的世界就越大。