1. 程式人生 > >高效程序猿的狂暴之路

高效程序猿的狂暴之路

鼠標 tty 標記語言 uml 軟件 pat python spring 就會

不覺間已經工作六年,回憶第一天實習的場景歷歷在目、恍若昨日。六年已足以令很多人轉管理、轉產品、轉測試、轉行,也一定有人還在堅守著編碼,僅僅因熱愛。遇到過形形色色的經理、架構師、運維、性能工程師等等,還是認為寫代碼的才是最厲害的!在這裏分享一些這些年來修習到的個人心得。或許並不適用於其它人,但對於我卻都是最珍貴的“寶藏”。

也謹以此文紀念在代碼堆裏度過的青春~ 看到這些點點滴滴的收獲,就會感到全部逝去的光陰和揮灑的汗水都是值得的。


1.啟動:得心應手的工具

1.1 全能IDE

關於IDE,眼下我使用Intellj IDEA和Sublime Text來應對各種語言的開發。

在大學期間初學Java時曾使用過MyEclipse。後來職業生涯的前期非常自然的過渡到了更加靈活的Eclipse。但兩年前經過不斷的試用丟棄再試用,終於我成功從Eclipse轉投到了Intellij IDEA陣營。

在那之後就一發不可收拾,不僅重度使用Intellij,並且還短暫試用過JetBrains旗下的各種產品,Phpstorm,Pycharm,RubyMine包含最新的Clion。Google也選擇Intellij作為其Android Studio的基礎。作為Java開發人員,當然最鐘愛的還是Intellij。其智能程度實在是太震撼了!

強烈建議還在觀望的同學們去官網上看一下介紹它的各種操作的小動圖。

好像非常easy地,Intellj IDEA就成了我Java開發的不二選擇。

然而對於其它語言,尤其是C/C++卻一直沒找到合適的IDE。

從Vim+各種插件打造IDE到Emacs到Visual Studio和CodeBlocks。一直沒有令我愜意的,直到碰見了Sublime Text。如今它不僅是我除了Java外全部語言的IDE,還是我的博客編寫工具和代碼庫。在後面的3.2 Codebase一節你將會看到。詳見《Sublime Text 3下C/C++開發環境搭建》。

1.2 UML和設計

UML領域中的好軟件不少,如Rose、EA。大多是商業付費軟件。

在開源免費軟件中。StarUML比較不錯。2.0版相比1.0做了不少改進,尤其是總體外觀美麗多了。配合Visio和Power Designer等補充UML以外的設計圖。如業務泳道圖、流程圖、拓撲圖、ER關系圖等,差點兒能夠滿足大部分日常需求。

1.3 Shell

日常工作中免不了要使用Unix/Linux命令,或者直接連接到遠程的server上做一些操作。在Windows上模擬Unix/Linux命令當然要用Cygwin,在Windows上使用那些有用的Unix命令能夠大幅度提升效率。特別是你經常須要處理文本時。

而SSHclient一般就用SSH Secure Shell或XShell,前者比較簡單,後者更強大但文件傳輸功能卻要裝另外的軟件XFtp。

當然,假設直接使用Linux做個人桌面那最好只是了,在Linux上開發和在Windows上不僅是工具多了順手了。簡直就是思維方式上的劇變!詳見《Linux Mint 17一周使用體驗》。

1.4 虛擬環境

VirtualBox是個不錯的小巧高速的虛擬機軟件,VMWare或許更加強大。可是有些太重型了。用VirtualBox裝一些經常使用的操作系統和軟件,以及測試環境和測試數據。然後做成快照留作以後重復使用,能夠免去非常多做環境的麻煩。

並且在虛擬機裏怎麽折騰都行。減少了使用實體機的風險。這方面,眼下後起之秀應該是Docker吧。造福了廣大的開發人員。由於還沒有研究過所以先不做評論了。


2.加速:簡單有效的方法論

2.1 動手前先思考

作為一名程序猿,拿到任務後就有要馬上編碼的沖動非常正常,但為了減少走彎路,我們要節制這樣的沖動。大到大型產品和項目的開發,小到一個算法的實現。都少不了先行設計和思考。大項目要做高層次架構設計,提前識別出那些“坑”。能夠有效地減少風險。避免返工。小算法要證明其正確性。避免一些邏輯思維上的漏洞。關於一段代碼的正確性,詳見《程序猿修煉之路-(1)基礎(下):正確性證明》。

關於思考的程度也要掌握一個“度”。不然就可能出現“過度設計”的問題。這個“度”感覺非常難掌握。僅僅能靠時間和經驗不斷培養推斷和直覺。一點點地就學會了評估哪些設計如今做非常費時應該放後,哪些設計如今做不麻煩但要是不做以後改起來就非常費時。

2.2 簡潔的代碼

說到簡潔和幹凈,就不得不提一些經典書籍對我的巨大影響。在大學時入手了《Code Complete》(代碼大全。聽了這狗血的中譯名真以為是各種代碼的百科全書)。非常幸運地能在正式入行前就看到這本書,它讓我少走了非常多彎路,甚至養成了一些代碼“潔癖”,有時甚至起個類名都要想半天,但時間證明一切都是值得的。

後來又看到了《Clean Code》。不僅講述了簡潔代碼方方面面的技巧,還將寫出簡潔的代碼上升到了職業宣言的高度。

詳情見《代碼整潔之道》讀書筆記。

《Clean Code》中結尾的一段話令人印象深刻。至今難忘:
“2005年。Elisabeth遞給我一條綠色腕帶。上面寫著Test Obsessed沈迷測試的字樣,我高興地帶上。

我發現自己無法取下腕帶,不僅是由於腕帶非常緊,並且那也是精神上的緊箍咒。那腕帶就是我職業道德的宣告。也是我承諾盡己所能寫出最好代碼的提示。寫代碼時,我用余光瞟見它。它一直提醒我,我做了寫出整潔代碼的承諾。”

2.3 重構

個人雖然沒有深入接觸過敏捷開發,但潛移默化中還是接觸到了不少敏捷開發中好的思想和方法。比方接下來要說的重構。

重構的技巧有非常多。可能不知不覺中我們就已經用到了。從最簡單的重命名、成員變量提取,到類提取、繼承層次中的上下移動等等。MF的那本《重構:改善既有代碼的設計》配上侯捷的翻譯非常經典。這裏再次強烈推薦Intellij IDEA。由於它的重構功能實在太強大了,能夠節省非常多時間,大幅度提升我們的開發效率。

2.4 單元測試與TDD

測試驅動開發(TDD)的方法和技巧事實上非常easy。隨之而來的優點卻非常多。一是對於非常復雜的功能能夠先實現最簡單功能,再逐步完好;二是有了單元測試,能夠通過失敗的用例直接找到相應出問題的代碼。三是通過TDD不斷叠代出的代碼。設計比較合理,後期更加easy維護。

不論什麽技術都不可避免的有兩面性。TDD也不例外,詳見《TDD實踐感悟》。

關於其它測試。如集成測試,使用Selenium還能夠將測試自己主動化。錄制好的測試腳本能夠自己主動播放,鼠標鍵盤就像“無人自己主動駕駛”一樣。

2.5 持續集成

持續集成(CI)被譽為項目的心跳。善加利用的話。不僅能統一大家開發的步調。集成上各種有用的插件,比如JCoverage、FindBugs、CheckStyle和各種打包部署腳本,就能有效地提高代碼質量和開發測試速度。CI配合上UAT環境能讓客戶盡早地看到眼下的產品是否是自己想要的那個樣子,避免越到後期越是不好改動。盡早暴露問題。

Java世界裏最流行的開源CIserver應該就是Jenkins了吧。參考《Jenkins持續集成環境搭建》。

2.6 代碼審查

雖然TDD和CI能自己主動化一部分工作,幫助我們提升代碼質量和開發效率。但人工的代碼審查還是少不了的。自查、互查、一起查。就像結對編程一樣,這也是像高手“取經”的好機會!

2.7 領域模型

一套準確而穩定的模型層的價值是難以估量的,這對於當前業務代碼以及未來升級版本號都是具有非常大作用的。

這也是面向對象分析設計(OOAD)、領域驅動設計(DDD)等方法論的“戰場”。雖然對DDD沒有太多的實踐經驗。但還是推薦一下,不是要全盤接收。而是從中汲取最精華的思想。

DDD Sample Application是不錯的上手學習資料。此外,配合領域模型定制領域語言(DSL)也是個趨勢,值得關註。


3.增壓:持續的知識積累

3.1 知識體系

前兩部分已經介紹了工具和方法論,能讓我們迅速地加速到百公裏。然而這些知識大部分是誰都能夠從網上獲得的。像工具誰都能安裝,除非你有“私房”插件。像方法論也都有非常多著作能夠學習。要想彪到二百邁,唯有厚積薄發,形成個人風格和套路。

因此,一定要有自己的長期計劃。並堅定地實行,畢竟慢工出細活。這是我的長期計劃《程序猿修煉之路》:

  • 計算機數學:離散數學與詳細數學。

  • 算法分析設計:經常使用設計技巧和數據結構。
  • 系統平臺:體系結構、操作系統、網絡、編譯原理和數據庫。
  • 代碼設計:架構設計、設計模式、方法論。

  • 代碼實現:開發工具和主流編程語言。

  • 測試驗證:單元測試、性能測試和優化。

3.2 Codebase

傳說每一個高手都有自己的一套代碼庫。為了成為高手,我也再不斷積累自己的代碼庫。我的代碼庫主要來自工作中的項目實踐和業務時間的編程練習。

相應最經常使用的兩種開發工具。我的代碼庫也分為兩大部分:Java代碼和LinuxC系統編程代碼。

首先來看一下我個人Java庫的編排,經過多次改動定為例如以下結構:cs算法/編譯原理等計算機科學基礎、java基礎API、framework主流框架、mobile移動開發、bigdata大數據hadoop/緩存/機器學習等、ui用戶界面、architecture架構設計、project業余和開源項目代碼、verification測試驗證代碼等。依賴管理方面使用了最順手的Maven。

$ tree -I "target|*.iml|pom.xml" -L 1 codebase/
codebase/
|-- 01-cs
|-- 02-java
|-- 03-framework
|-- 04-mobile
|-- 05-bigdata
|-- 06-ui
|-- 07-architecture
|-- 08-project
|-- 09-verification
|-- autobak.sh
`-- README.md

眼下我使用Sublime Text管理Java領域外的各種知識和代碼。其編排主要依照系統由底層向上分為:匯編語言、C語言(基礎、算法、系統、實踐、開源軟件)、腳本(批處理、Shell腳本、Cheatsheet)、其它語言(Golang和Python等等)。

$ tree -L 2 syspace
syspace
|-- 1-assembly
|-- 2-ccpp
|   |-- 21-basic
|   |-- 22-algorithm
|   |-- 23-system
|   |-- 24-pragmatic
|   `-- 25-opensource
|-- 3-batch
|   |-- 31-bat
|   |-- 32-shell
|   `-- 33-cheatsheet
|-- 4-lang
|   |-- 41-golang
|   |-- 42-python
|   `-- 43-php
|-- autobak.sh
`-- index.md

此外。不僅要整理自己的代碼,還能夠收集一些小巧精悍的開源軟件來學習。比方通過Nginx代碼學習網絡編程,通過Redis學習C語言和數據結構,通過Lua學習編譯解釋原理,通過libevent學習並發編程。

Linus說過:RTFSC(Read The F***ing Source Code)。

實習時在OpenJPA源代碼裏尋尋覓覓,由於找不到一個功能的擴展點而改了源代碼並替到Jar包裏,最後還真好使了。然後就一發不可收拾,沈浸在了Spring源代碼的海洋。有時一馬平川地,從上到下看究竟。如當時OSGi有個開源的小內核Felix。有時也會碰壁而半途而廢。記得有次看Derby,一直看到存儲層,記得好像用antrl生成的SQL解釋器吧。由於功力不夠而擱淺了。如今無論是C、Java還是其它主流編程語言的開源代碼,不能說毫不費力,可是非常高速地就都能看出個大概流程,不得不說也是不斷閱讀的結果。總而言之。閱讀優秀源代碼的收獲之大是無法用語言形容的。

3.3 Cheatsheet

Cheatsheet小抄,也就是一些來自日常工作經常使用操作的速查表,主要由經常使用配置、命令、快捷鍵等組成。我眼下分為數據庫、IDE、各種語言、中間件、操作系統等。

網上有一些現成的在線Cheatsheet,只是還是自己整理的比較熟悉。實際工作中它也幫助我節約了大量的重復查詢工作和寶貴時間。

$ tree 33-cheatsheet/
33-cheatsheet/
|-- db
|-- ide
|-- lang
|-- midware
|-- os
`-- revctl

關於這一部分,每一個人可能都會攢了一些有用的小腳本。但要註意的是,有些工作是不適合或者說不值得用腳本自己主動化的。

《卓有成效的程序猿》裏說過:“別讓自己主動化的努力變成剪牦牛毛”

剪牦牛毛是一件非常危急的事,它會吃掉你大把的時間,得到的卻僅僅是一個不有用、僅僅能用幾次或者隱患非常大的腳本工具。

3.4 腳手架

腳手架(Scaffold)是個好東西,它能夠幫助我們自己主動生成代碼的“骨架”。之後利用我們代碼庫的積累對骨架做微調。不斷在上面加入功能就能高速地形成一個可用的應用程序。Maven提供的Archetype插件是個不錯的腳手架。非常多項目都基於它提供了代碼模板。

當然假設想要定制自己的模板也非常easy,詳細參照《Maven原型骨架及常見問題》。

除了Maven這樣的構建工具外。IDE一般也提供了各種小腳手架來生成小段代碼。

最常見的就是IDE裏的代碼模板和補全功能。假設認為只是癮能夠編寫自己的模板和IDE擴展插件,就像RubyMine對Rails的腳手架的支持一樣。詳情見《Intellij IDEA插件開發入門》。

3.5 Blog

寫博客的作用可不容小覷!沒做過總結的知識那僅僅是別人的知識,沒做過讀書筆記的書不久後就變得跟沒讀過一樣。

當碰到了總結整理過的知識時,搜索你的Blog會給你最高速的答案。不要以為這跟用谷歌搜索一樣。一遍遍翻看你自己用心寫的東西和看別人的東西是全然不同的概念!並且中文技術文章裏有太多的粗制濫造的內容、亂七八糟的排版和無數不註明出處的轉發。所以看完書的一章或做完什麽有用的練習後。一定要趁熱打鐵趕緊總結一下!

那麽用什麽寫呢?之前試用過Emacs下的Orgmode。之前接觸過輕量級標記語言。配合Emcas感覺挺驚艷的!後來遇到了Sublime後連寫博客都遷到它上面了,由於它的Markdown插件實在是太好用了。詳見《Markdown語法及SublimeText下使用技巧》。

3.6 多元化

隨著寫代碼的時間長了、見識多了,解決這個問題的手段就會多元化起來。什麽樣的編程語言適合用什麽樣的項目。什麽樣的架構設計適合什麽樣的場景。編程語言多元化。架構設計的多元化,開發工具的多元化,終於才幹促成我們解決現實問題的思維的多元化。Thoughtworks維護了一個技術雷達,定期會更新技術、平臺、工具等方面的技術趨勢。


4.狂暴:專註與抗幹擾

雖然有了上面各種輔助。可是假設不能靜下心來編碼一切都白費了。要麽看會這兒看會那兒,要麽就是在嘈雜的環境中無法集中註意力。雖然不起眼,這卻是提高效率的“最後一公裏”。

4.1 免分心模式

各種IDE一般都提供了全屏模式。像Sublime Text還額外提供了”Distraction Free Mode”抗幹擾模式,讓你專心地投入到一個打開文件的編輯工作。

4.2 虛擬桌面

用過Linux桌面版的都知道,非常多Linux分發版都提供了4個獨立的桌面工作區。一個工作區能夠做交流用,像收發郵件、即時通訊等。一個工作區用來訪問遠程server或FTP環境,一個工作區則專心編碼不受幹擾。Windows下也有如Dexpot這樣能夠實現虛擬桌面的軟件,最好還是試用一下。

4.3 盲打與打字速度

一般大家經常網上聊天的話。打字速度應該不成問題。但除了盲打26個字母外,像經常使用的標點符號分號括號引號、數字1-3和8-0、功能鍵F1和F2、Ctrl/Alt/Shift等最好也能熟悉其位置,這樣敲起來才幹快如風。

此外,無論用什麽IDE和工具,掌握快捷鍵,讓雙手留在鍵盤脫離鼠標是基本功。不然空有快如風的盲打速度也是不行的。關於我最常使用的IDE的快捷鍵介紹請參考《十大Intellij IDEA快捷鍵》。關於這一部分的積累。別忘了保存到自己的Cheatsheet裏。

4.4 音樂

關於為什麽編程時要聽音樂有不少研究,還都挺有意思的,說是不僅抗幹擾還能促興奮。

萬能的知乎上還真有這個問題,以及一份推薦的榜單。見有哪些適合編程時聽的音樂?。甚至還有個專門的站點http://musicforprogramming.net/。這方面因人而異,我個人還是比較習慣這樣的“抗噪”方式的,近期在聽剛看完兩季的《Silicon Valley》的OST。

4.5 面包屑

當然,被別人幹擾和打斷在所難免。

在離開手頭工作之前,一定留下一些線索。比方關鍵點、思考到哪了等,這就是“面包屑”。這樣等繼續時就能略微快一些恢復出“現場”。就像進程的上下文切換一樣。


5.高效編程=工具+方法+體系+專註

前面依據個人的經驗,分享了一些提高編程效率的個人心得。

每一個人的經歷經驗不盡同樣,相信事實上每一個人心中都有一份自己的清單。但最最重要的是堅持投入,不斷地練習、練習、練習、練習、練習……

這裏引用近期看到的名言自我勉勵一下,來自Bruce Lee李小龍:

“I fear not the man who has practiced 10,000 kicks once, but I fear the man who has practiced one kick 10,000 times.”
我不懼怕把一萬種踢法都練一次的人。但我害怕把一種踢法練一萬次的人。

“There are many paths you can follow to reach your destination. However, you’ll never reach the end if you keep changing paths along the way.”
到達目的地的途徑有多種。

但假設你沿途不斷變換路線,你是永遠不會到達終點的。

李笑來老師在《把時間當作朋友》曾說過:“全部學習上的成功,都僅僅靠兩件事:策略和堅持。而堅持本身就應該是最重要的策略之中的一個。”水滴石穿,繩鋸木斷。不要害怕走彎路,僅僅要專註地一直走就一定會到終點!

祝福大家都能抵達夢想的彼岸。成為自己心中最厲害的那個人!

高效程序猿的狂暴之路