假如程序員會武功?

從新給程序員下個定義

按照 Wikipedia 的定義,程序員又稱爲計算機程序員(Computer Programmer)、開發者(Developer)、編碼者(Coder)或計算機工程師(Computer Engineer),和網絡上普遍流傳的碼農或程序猿同義。我無心於也不可以爲程序員給出一個精確的定義,這裏,只是利用程序員的語言作一個簡單描述。不是故弄玄虛,不過博取讀者諸君一笑。程序員

class Programmer : public Thinker {
public:
void design(System &);
void model(Problem &);
void code(ProgrammingLanguage &);
void debug(Defect &);
void refactor(Code &);
void learn();
void communicate();
virtua voidl think(Logic &);
private:
vector _pls;
}


程序員是徹頭徹尾的腦力工做者 (Mind Worker),怠於思考者絕對不能成爲好的程序員。有鑑於此,類 Programmer 天生的就應該是 Thinker 的子類。就程序員所使用的思考技巧而言,Thinker 的具體內涵包括邏輯 (Logic) 和數學(Mathematics)。做爲程序員,不必定非要達到邏輯或數學領域的專業水準,而是必須具備邏輯和數學的基本素養。邏輯用來推理,數學用來培養邏輯。另外,數學還有助於程序員訓練另外兩項必不可少的思考的技能,分析和抽象。下文還要展開討論。算法

程序員的工具是編程語言,平常活動和主要工做包括設計(design)、建模(model)、編碼(code)、調試(debug)、重構(refactor)、溝通(communicate)、學習(learn)和思考(think)。編程

有關程序員有一個流傳甚廣的誤解,認爲作程序員門檻低,沒什麼技術含量。即便沒有學過計算機的課程如離散數學、數據結構、算法等,也能夠寫程序。寫幾行程序固然算不得什麼,但要修煉成有必定思想境界的一流程序員,卻殊非易事。這就如同會作飯的人不少,但真正的烹飪大師卻並不常見。所謂碼農者,乃是程序員的自我吐槽,豈足深信耶?因此,做爲程序員要有持續進階的強烈的進取心,斷不可妄自菲薄,自怨自艾。網絡

程序員的思惟「內力」數據結構

漫長的學生生涯中,我遇到的最好的數學老師是高中時的劉傳禹老師。他上課時講過這樣一段話,當面對一個數學問題,一要想的明白,二要算的準確,三要寫的清楚。直到今天,這句話對於個人程序員生涯也具備很強的現實意義,能不能想的明白實際上是考量一個程序員成敗的相當重要的因素。架構

金庸的武俠小說中有一個廣泛的規律,那就是武功一定之內力爲根基。好比張君寶與崑崙三絕何足道在少林寺的那場經典之戰中,張君寶可以「以少林拳中最平淡無奇的拳招,化解了最繁複的敵招」,始終不落下風,所恃者不過內力之渾厚爾。另外的著名戰例還包括少林寺小和尚虛竹 VS 吐蕃國師鳩摩智以及聚賢莊蕭峯 VS 玄難。內力達到登峯造極曠古絕倫的第一高手莫過於少林寺的掃地僧。也許風清揚是一個例外,好在咱們討論的是通常規律,因此就顧不得他了。app

計算機編程所特有的思惟(Thinking)就是程序員的」內力「,思惟能力不濟,功能再強大的編程語言也無用武之地。因此,我在這裏特別強調程序員的思惟藝術。異步

程序員的思惟有一個專業術語,叫作計算思惟(Computational Thinking)。計算思惟是按照計算機科學的基本概念和方法,用來理解需求、設計系統、實現編程、解決問題的思惟方法。編程語言

簡而言之,計算思惟就是程序員或計算機科學家是如何思考的。固然,計算機科學的理論知識如數理邏輯、離散數學、數據結構、算法以及面向對象是計算思惟的必要條件。計算思惟有一系列的智力工具,不能一一盡述,僅列舉關鍵的幾項以下:ide

抽象思惟(abstract thought)

給定一個問題,抽象就是去掉紛繁蕪雜的與計算無關的部分,用規約(Reduction)的方法還原到問題的本質。所謂本質即把原來的問題轉換爲一個或幾個可使用計算機描述並解決的問題,進一步講也就是轉換爲在算法上可計算的(algorithmically computable)一個或幾個問題,更準確更理論化更上檔次的描述是轉換爲邱奇 - 圖靈論題(TChurch-Turing thesis)可計算的可數個問題。圖靈機(Turing Machine)和λ演算(Lambda calculus)自己就是對可計算性(Computability)的漂亮的抽象,能夠做爲抽象思惟的經典案例來揣摩學習。

通常在實際工做中,經常須要把問題的實體對象根據需求表示爲各類數據結構如樹、堆、棧等,而業務邏輯(Business Logic)過程表示爲各類算法如排序和查找等。表示(Presentation)是解決問題的第一步,也是關鍵的一步。在程序員的實踐中,咱們都有很深的體會,一旦問題被準確的無歧義表示出來了,解決方案就烘雲托月般地呈現出來了。這就是「數據即代碼,代碼即數據」的道理。

抽象思惟也普遍用於數學家的工做。面對一個困難的問題,數學家們常從兩個方向開展研究。一方面,從特殊狀況入手,推廣到更通常的狀況;另外一方面,將一個通常問題具體化成幾種特殊狀況。兩個方向的結果最終匯聚在一塊兒,就找到了問題的答案。我想這多是論語中「我叩其兩端而竭焉」的一個最好註解。而從特殊到通常就是不斷抽象的過程。

咱們用一個具體的例子加以說明,有一個著名的六度分隔理論(Six Degrees of Separation)講的是世界上任意兩我的均可以經過最多另外 6 我的相互認識,若是要驗證這一理論,怎麼作呢?咱們能夠藉助一個圖(graph)來表示人與人之間的關係,每一個人用圖中的一個節點表示,若是 A 和 B 認識,那麼在表明他們的節點之間有一條邊鏈接。

那麼如今的問題就轉換爲檢查這個圖的直徑是否大於 6。考慮到世界人口衆多,且有生老病死,圖的規模必然超大,而且是動態的不斷變化的,算出它的直徑仍須要更多的簡化。這裏就到此爲止了。

邏輯推理(Reasoning)

邏輯推理對於程序員的重要性不言而喻。與其說邏輯推理用於程序新功能的開發,毋寧說更多的應用在程序調試修改 BUG 的過程當中。程序調試有點相似於 Sherlock Holmes 偵破案件的過程。

和 Dr. Wason 比較起來,Holmes 的推理優於常人的地方有兩點:第一,在觀察現場或聽取來訪者敘述時,他可以獲得更多的的數據,尤爲是一些別人容易忽略的關鍵的細節,這得益於他對犯罪領域知識的豐富積累,知道什麼纔是更重要的數據;第二,根據獲得的數據,他可以聯想到更多的可能的結論,這得益於他大量的案例儲存。有了這兩點,就可以經過一環套一環的推理鏈逐漸縮小偵察範圍,最終認清犯罪事實。

程序調試也是如此,首先必須掌握程序實際的執行過程的細節。而後從問題出發,分別朝着產生的緣由和致使的後果先後兩個方向推理。逐漸定位問題的範圍,最終找到問題的根源和解決的方案。咱們比 Sherlock Holmes 幸運的是 能夠藉助於調試工具來了解程序運行的過程,因此一個不能使用調試工具的程序真是令程序員感到無比沮喪,只能經過 trace 信息來跟蹤程序運行的過程。

若是不知道程序運行的過程,推理就只能靠猜,那麼修改 BUG 是很是危險的,很容易致使回退(Regression)的錯誤,由於這種狀況下如同瞎子摸象,根本不知道本身在作什麼。另外,Sherlock Holmes 還屢次表達過這樣的觀點,案子越是離奇,越容易解決,由於 Singularity is almost invariable a clue。

對程序員來說,也沒必要擔憂奇怪的問題,奇怪自己就是線索。關鍵看對程序運行細節的瞭解程度和邏輯推理的技術水平。

分析(Analysis)

分析是上文提到的數學家所用思惟方式中從通常到若干特殊狀況的過程。面對一個問題,若是一會兒描述不清楚或者表示不出來,能夠先找出知足問題條件的幾種特殊狀況。經過仔細檢查這幾種特殊狀況,求同存異,找出他們共同的規律或模式,並對這些模式或規律加以驗證,就能夠找出描述或表示問題的方法。這就是猜想加驗證(guess-and-verify)的過程。項目需求分析時常見的應用案例分析(Use Case Analysis)方法,就是用一個個具體的使用案例將模糊的項目需求生動的表達出來。

分解(Decomposing)

把一個大問題分解爲幾個小問題,或者把一個複雜的過程分解爲幾個子過程,固然有助於問題的解決。這也是程序員經常使用的手段,如算法策咯中的分而治之(Divide-and-Conquer)和合並排序就是這方面的例子。

遞歸(Recursion)

對於初學編程的人,遞歸多是一個比較詭異的較難掌握的概念。可是一個程序員若是不懂遞歸,很難再稱之爲程序員。由於不少稍微複雜的算法他都不可能理解,如回溯和動態規劃,甚至於樹的遍歷。遞歸經常能夠用簡單的方法很是優雅的表達複雜的算法。

另外,有關計算思惟的特有方法還有並行、異步 / 同步、模擬 / 近似、優化、分層、封裝、解耦等等。程序員的思惟藝術即計算思惟不是一天兩天短期能夠造成的,須要在實踐中慢慢琢磨,不斷提高,且永無止境

程序員的「戰鬥力」技藝

圖片

程序員的思惟藝術融化到到對編程語言的使用上,最終造成程序員的技藝。所以,編程語言之於程序員,就如同青龍偃月刀之於關羽,如意金箍棒之於孫悟空。離開了青龍偃月刀和如意金箍棒,關羽和孫悟空的戰鬥力就無從談起。因此,脫離編程語言來討論程序員的技藝也無異於緣木求魚,自欺欺人。結合編程語言,程序員的技藝有四個境界,從低到高分別是

初窺門徑

編程語言的初學者,如同小兒咿呀學語,也許能夠寫一個相似於「Hello World」這樣的程序,但對語言的全部東西都是隻知其一;不知其二,不可能應用於實際的項目中。這是咱們很容易就能夠達到的級別。有些人初窺門徑以後,往裏面看看,感受不容易,就放棄了。

登堂入室

對編程語言所共有的基本表達方式有了必定的瞭解,如變量、賦值、循環、選擇等。能夠用在通常的項目中,可是寫出來的代碼看起來滯澀笨拙,很難作出高質量的程序。這個時候,程序員很容易產生自滿的情緒,覺得徹底掌握了這種編程語言,編程也不過如此。若是陷入這種自滿情緒中不能自拔,就失去了進一步進階的機會。

熟能生巧

掌握了編程語言特有的功能,並能得心應手,靈活使用。所以,寫出的代碼更加的精煉易懂,經常使用簡單的方法表達較爲複雜的算法。這是一個成熟的程序員的水平,也是咱們大多數程序員所能追求的目標。

妙趣橫生

這是傳說中神龍見首不見尾大師級的境界。柏楊在《中國人史綱》描述李白的才華稱,李白寫詩時,對漢語的使用就像魔術師手中翻轉的手帕同樣,神鬼莫測。如同李白做詩同樣,我想這個境界的程序員對編程的各類精微之處瞭如指掌,可以將編程語言的各類功能特性發揮到極致,且恰到好處。運用之妙,存乎一心。而且每每可以別出機杼,奇思妙想,層出不窮。寫出的程序優雅、高效、別緻。這是咱們通常程序員望塵莫及的。

程序員的精神「修煉」

開放

在以往的工做中,曾經遇到過這樣的程序員,自覺得掌握了某些核心的、關鍵的技術或技能,卻不肯意和別人共享,處心積慮的保護着他的「地盤」,擔憂別人染指他的工做。也遇到過這樣的組織,幾個被信任的程序員把持着產品的所謂關鍵模塊,其餘人莫想參與,即使再有才華,也只能扮演跑龍套的角色。

這讓我想起《三國演義》中諸葛亮舌戰羣儒的情節,在回答江東首席謀士張召的詰難時,諸葛亮將儒生分爲君子之儒和小人之儒。這裏不妨將這樣的程序員稱爲「小」程序員吧。程序員的技藝根植於計算思惟中,沒有所謂的不傳的絕招或祕笈。交流和實踐是程序員持續進階的必要且有效途徑。固步自封和抱殘守缺是程序員的大忌,徹底是做繭自縛,毫無出息

嚴謹縝密

在軟件開發中,任何事情在邏輯上緣由和結果都是清晰明瞭的,不存在任何意義上的說不清道不明的神祕主義。程序員也是軟件工程師,討論問題時,固然應該使用工程師的語言,即用數據而不是猜想,用邏輯而不是臆斷,來表達本身觀點。

有兩種狀況可能形成本身表述時似是而非,模棱兩可:第一,數據掌握的不夠;第二,沒有「想的很明白」。例如,當咱們討論性能(Performance)時,必定要用響應時間(Response Time)或吞吐量(Throughput)這樣有意義的參數,而不僅是泛泛的講「這系統咋這麼慢啊」,「計算機在幹什麼呢,等的時間太長了」,「簡直受不了這樣的程序了」。用戶能夠這樣抱怨,而程序員則不可。

一樣當咱們講到系統開銷時,要用 CPU 佔用率、內存這樣定量的參數。所以,一個腦筋清楚的程序員不會把這樣的話掛在嘴邊,「太神奇了,不知道爲何」,「弄不清楚是否能夠解決這個問題」,「先這樣吧,之後再說」。通常地講,智能和非智能並無清晰的界限,由於咱們並不知道如何嚴格地定義智能。

然而,有了圖靈—邱奇論題,可計算的和不可計算的確實有明肯定義的界限,也就是說,計算機能夠解決的問題和不能夠解決的問題是涇渭分明的,且是能夠區分的。對於一個問題,可以解決就是可以解決,不能解決就是不能解決,不至於難以肯定是否能夠解決。因此,全部以上這些說法都不該該是程序員使用的語言,程序員就是要把一切都弄得清清楚楚,不放過任何潛在的問題。

完美主義

我不瞭解完美主義的真實意義,也不大拿得準完美主義是褒義詞和貶義詞。我用這個詞是爲了 強調程序員要堅持追求工做的完美。寫代碼時是要有潔癖,不容許有任何瑕疵,這樣的代碼纔可能正確、易讀、高效、簡單、優雅。對一項任務,不只僅是作完就算了,還應該仔細想一想是不是否能夠作的再好一點。對遇到的問題,即便看似解決了,也要從頭到尾徹底弄明白,不能似是而非,不求甚解。

面對變化

變化意味着在新的征程上,要面對許多未知的東西,加之對安定狀態下的安樂窩(Comfortable Zone)的眷戀,讓咱們有着或多或少的畏懼和抗拒。我認爲這些都是人之常情, 無可厚非。

不幸的是,對程序員來講,變化就是屢見不鮮,如新的項目、新的應用領域、新的編程語言、新的技術架構、開發過程當中新的問題、新的功能等,能夠說不變的只有變化。其實,好逸惡勞是畏懼變化的根源。只有克服「懶」的思想,強迫走出本身的安樂窩,對新的事物充滿好奇心和求知慾,才能適應永遠的變化

程序員的價值提高

有的公司把程序員看做和水電、機器同樣的冷冰冰資源,作項目計劃時,一些項目經理覺得只要給項目分配足夠的資源(包括程序員、水電、機器)並加以正確的管控,項目就能夠預期的順利完成。就好像作東北亂燉,只要把各類食材往鍋裏一丟,開火等着就萬事大吉了。

可是,程序員首先是有血有肉的人,毫不等同於毫無感情的機器。一個有雄心的公司要不斷提高產品的競爭力,什麼是競爭力?就是把產品作的好到不能再好,天下第一,誰與爭鋒?產品向好的每一步都須要藉助於程序員創造力和想象力,這纔是程序員的價值之所在。沒有程序員願意把最寶貴的創造力和想象力奉獻給只把本身看做資源的公司。因此,聰明的管理者會千方百計把程序員這種創造力和想象力激發出來。

相關文章
相關標籤/搜索