編程難在哪裏? 一個美國實習生的故事。

記得以前組裏來了一個美國實習生小夥子,很geek的那種,幹活快,一天能給你寫2000行代碼(我code review的速度跟不上他寫的速度),讓作什麼東西,上午告訴作個這個功能,下午就能在測試環境跑起來演示了。java

 

跟他單獨開會的時候,他說以爲普通的編程沒什麼意思,太簡單了,寫程序這方面已經沒什麼追求了,他比較想跟我研究大數據的框架,數據庫,或者機器學習之類的工做,作設計,早日脫離代碼這種無腦工做。程序員

 

我足足花了1周時間,天天review他的代碼到凌晨。給他寫的comments反饋快遇上我在知乎寫的答案文章之和了。。。期間幾小時幾小時的開會論戰,孩子狂,語速快,腦力靈,辯論角度刁鑽。他每天要與我論戰,看個人評語,速度還算慢下來了。算法

 

沒來得及討論完,隔週我要休假了,2周。交代了些他要作的工做。數據庫

 

2週迴來,讓他改的那個java包爆炸了,原本咱們一個支持了7個功能的框架包,總代碼量也就5k吧,等我回來這包代碼量1w5+。也就是說他爲了一個小功能加了1w行代碼。編程

 

這無法review,只能跟他坐一塊,先讓他給我講講這代碼都幹什麼的,而後他說:設計模式

 

(沉思+100)這塊我如今也看不太懂當時爲何這麼寫了。。。api

 

(沉思)這邊寫的比較複雜是由於當初那邊是那樣寫的,因此這邊沒辦法才只能這麼寫。數組

 

(沉思)把當初那邊改好很麻煩,影響也很大,不如就這樣吧。promise

 

(沉思)這裏這麼寫是由於你看着是這樣的, 而後這裏有這個邏輯,而後這裏。。。網絡

 

(來回來去翻n個類以後)。。。 因此你看我這裏雖然寫的比較詭異,可是徹底沒問題的!(得意ing)

 

(沉思)這邊作得這麼奇怪是由於有個bug,經過這麼寫,這個就bug沒了,我也不知道怎麼回事。。。因此你看我在這邊註釋,這行不能刪了。。。

 

(沉思)我以爲這個功能很酷,大家雖然如今不須要,不過有總比沒有好吧,未來若是……%¥……&%&……%*7&%……*%…(我沒聽懂)的話,這個就頗有用!!... 

 

一次一次被我打回去重寫,後來總算簡化成大概5k行了;臨走時候跟我說:你這樣編程也太難了。。。

 

再後來因爲一些額外複雜的代碼形成咱們實現新東西會很複雜,我又重寫了一遍,總共大概不到1k行代碼。

 

這裏邊有幾件事情我想說:

 

1. 作出來容易, 作正確難,這裏作出來指沒bug且完成須要的功能,這是最基本要求,很少加討論。這裏正確,不是指功能正確,而是指程序能夠很容易理解,理解意圖, 理解如何作到的,理解爲何系統不會出錯。理解爲何要這麼作。

 

正確是如今怎麼寫不會挖坑害未來的人,如今怎麼寫能讓別人1年後看你代碼時候不可能理解錯你如今的意圖,如今怎麼寫能在別人未來犯錯的時候提示他你錯了。

 

2. 編程是給將來的未知人講故事,你沒法知道未來這我的是誰,他都懂什麼,他經歷過什麼,這個系統未來已是什麼樣子了。咱們須要在這種無知,缺少信息的狀況下作決定,從千萬種把這件事作出來的方法裏,選出你以爲最能把這個故事給講好的那種方式,把故事寫下來。編程是一種溝通,溝通是一種藝術,用程序跨越時空之溝通則是一門屬於程序員的特有的藝術(就比如數學家用數學公式來溝通) coding is all about the art of communication(引用)。 

 

3. 壞的決定會致使壞的決定,甚至致使人們去扭曲一個好的決定去迎合壞的決定。垃圾會製造垃圾,一個放在系統裏不經清理的額外複雜度,會致使更多的額外複雜度的生成。

 

4. 每一個人甚至同一我的的不一樣時刻都有本身的不一樣的製造額外複雜度的缺陷,好比我每一年去看去年本身寫的代碼,以爲都是垃圾。

 

而後我又想問幾個問題:

 

咱們所在的部門,所在的組,公司,它們的文化,究竟是關心做出了一個東西,仍是關心作好了一個東西。一個老是給系統添加垃圾,留坑給後人,可是能很快作出能跑起來的系統的程序員,咱們到底認爲他是作了好事仍是作了壞事?咱們到底認爲他很強,仍是他很弱?用超過必要而爲了突顯技術實力(或者練手)的複雜工具,技術框架搭建系統,作完跑路,在一個組,一個部門,一個公司,那裏的文化,到底應該是鼓勵仍是抑制這種行爲?咱們又應該如何在一個環境中,去倡導推崇什麼樣的文化,相遇什麼樣的人?

 

人與文化,決定了什麼人留在這裏,什麼人離開,什麼人吸引什麼人,什麼人成長成什麼樣子。而設計/技術這些枝末細節則必順應此中的人與文化而天然變化,或自愈,或走向毀滅;哪怕在惡劣的環境中,向下引導,向上規諫,潛移默化,最終改天換日,此爲編程之大道也!

 

下邊是定理證實(霧)

======畫風突變高能預警!!!!!!

 

最小垃圾存在定律:定義垃圾爲系統的總複雜度減去系統的本質複雜度;那麼獲得:如存在多種方法能夠設計與實現一個系統或功能,存在且只存在一種實現會引入最少的垃圾;

 

垃圾與複雜度正比定律:根據定義可得,系統存在的垃圾越多,系統越複雜;

 

垃圾倍增定律:基於已有垃圾量a的現狀來演化,進化此係統,增長的新垃圾量與已有垃圾量a成正比;

 

系統腐敗定律:當基於垃圾量a來實現新功能的cost大於新功能自己的價值時,系統腐敗,須要重構;

 

戰鬥人員負戰力定律:若是程序員a引入的垃圾,在n次迭代中通過倍增所形成的成本,大於其所清掃的垃圾通過倍增所得到的機會成本,和其實現的新功能價值之和。此時,咱們稱此程序員戰力爲負值,其戰力絕對值與其引入垃圾的能力和其清掃垃圾的能力的差值成正比

 

以一敵百存在定律:由負戰力定律可知,對全部的天然數n,一個正戰力的戰鬥人員的戰力 > (負戰力戰鬥員1+負戰力戰鬥員2+ … 負戰力戰鬥員n)的戰力和

 

系統本質複雜度不可知定律與系統表徵複雜度無限接近本質定律:取決於戰鬥人員的知識量,經驗,天賦等,對於任何戰鬥人員n,都一定存在一個戰鬥人員m(考慮歷史長河)使得戰鬥人員n觀察系中的純淨無垃圾系統(複雜度總爲1)是戰鬥人員m觀察系中的含垃圾系統(複雜度爲1+x),這使得在全部觀察系中(包含外星生物),系統的表徵複雜度(或者說觀察複雜度)無限趨近與本質複雜度。然而咱們只能經過觀察來感知事物的本質複雜度,卻永遠沒法得知咱們離本質複雜度還有多遠。

 

以有限的生命去追求能夠無限的提高的淨化方法與視野,咱們稱之程序藝術家,也就是SDA(Software Development Artist)… it's extraordinarily important that we in computer science keep fun in computing…         ——— Alan J. Perlis (April 1, 1922-February 7, 1990) 《SICP》

 

打星際… 哦,不, 錯了重來…  寫程序,你快樂嘛?

 

寫在最後,看到你們最關心的是他拿到正式錄取資格了麼?還有也許經過個人描述關於他的這個側面,你會以爲他很不稱職。其實不是的,他代碼寫的絕對是平均值往上的水平,他的問題在於:

 

1.是他根本沒有想過去簡化業務邏輯,因此不少符合最初需求的代碼在簡單優化業務邏輯以後徹底不須要。

 

2. 是本身加了不少功能。

 

3.是本身加了不少自覺得是的優化,好比用一個算法估算某個函數的輸入數組的最大可能值,而後用那個值來初始化一個數組,由於這樣就不會從新分配內存了(他原話)。

 

4. 抽象能力有限,這個畢竟經驗少, 年輕。

 

5. 濫用設計模式(關於設計模式,最多程序員被絆住的一關:設計模式是面向對象編程模型中,應對經典問題的經典解決方案。這裏就有兩個問題,第一,設計模式的場景用對了麼?第二,爲何要用面向對象範式,選擇編程語言範式時,要從表達力最弱最簡單的語言範式開始選擇。這叫作最弱表達力原則,而面向對象範式做爲最複雜,表達力最強的語言範式,在大多數時候均可以免使用。關於第二點的論述證實,你能夠看concept techniques and models of computer programming這本書。注意,這裏說的是語言範式,而不是語言。即便你用java,若是你歷來不使用mutable(專業詞彙)的功能,和繼承。那麼你就沒有使用面向對象範式)

 

他其實有很是強的解決問題的能力,想法天馬行空,經過本身設計算法來猜函數可能須要的數組大小就可見一斑,還有一個從s3(專業詞彙)讀數據的需求,他不是簡單調api完了,而是寫了一個環狀buffer(專業詞彙),使得網絡,硬盤,app能夠在理論上最大效率的適應程序當時的場景(爲了協調異步,他本身發明了一個很笨拙的promise(專業詞彙)),這很是厲害,通常的實習生哪怕sde1可能都寫不出來(惋惜的是場景會隨業務邏輯激烈變化,今天的優化能夠是明日的累贅,這就叫作過分優化,過分優化是一種強耦合,會把你的系統死死的釘死在當前版本)。

 

他只是不明白簡單是美這件事情而已。若是能有人幫他斧正,往後必成大器。

 

他最終拿到了正式錄取資格,這其中還有個小波折,終審的bar raiser(amazon內部的一個能夠一票否決招聘結果的角色)看到他在代碼複查系統裏跟個人各類激辯,以爲這人不能留。好說歹說纔給了正式錄取資格。不過最後人家沒接,去讀博啦。

 

最最後:在一個相對乾淨的環境寫程序,不斷找出新的原本覺得不是垃圾的垃圾,對我來講,是一件很是愉快的事情。然而幫別人打掃他本就不應制造的垃圾則是很是痛苦的一件事。 寫程序,本應是多麼快樂的一件事啊!

相關文章
相關標籤/搜索