编程到底难在哪里? 从一个美国实习生的故事说起
記得之前組里來了一個(gè)美國實(shí)習(xí)生小伙子,很極客的那種,干活快,一天能給你寫2000行代碼(我復(fù)查的速度跟不上他寫的速度),讓做什么東西,上午告訴做個(gè)這個(gè)功能,下午就能在測試環(huán)境跑起來演示了。跟他單獨(dú)開會的時(shí)候,他說覺的普通的編程沒什么意思,太簡單了,寫程序這方面已經(jīng)沒什么追求了,他比較想跟我研究大數(shù)據(jù)的框架,數(shù)據(jù)庫,或者機(jī)器學(xué)習(xí)之類的工作,做設(shè)計(jì),早日脫離代碼這種無腦工作。
我足足花了1周時(shí)間,每天讀他的代碼到凌晨。給他寫的評語反饋快趕上我在知乎寫的答案文章之和了。。。期間幾小時(shí)幾小時(shí)的開會論戰(zhàn),孩子狂,語速快,腦力靈,辯論角度刁鉆。他天天要與我論戰(zhàn),看我的評語,速度還算慢下來了。
沒來得及討論完,隔周我要休假了,2周。交代了些他要做的工作。
2周回來,讓他改的那個(gè)java包爆炸了,本來我們一個(gè)支持了7個(gè)功能的框架包,總代碼量也就5k吧,等我回來這包代碼量1w5+。也就是說他為了一個(gè)小功能加了1w行代碼。
這沒法復(fù)審,只能跟他坐一塊,先讓他給我講講這代碼都干什么的,然后他說:
“en。。。這塊我現(xiàn)在也看不太懂當(dāng)時(shí)為什么這么寫了。。。”
“en。。。這邊寫的比較復(fù)雜是因?yàn)楫?dāng)初那邊是那樣寫的,所以這邊沒辦法才只能這么寫。”
“en。。。把當(dāng)初那邊改好很麻煩,影響也很大,不如就這樣吧。”
“en。。。這里這么寫是因?yàn)槟憧粗锸沁@樣的, 然后這里有這個(gè)邏輯,然后這里。。。(來回來去翻n個(gè)類之后)。。。 所以你看我這里雖然寫的比較詭異,但是完全沒問題的!(得意ing)”
“en。。。這邊做的這么奇怪是因?yàn)橛袀€(gè)bug,通過這么寫,這個(gè)就bug沒了,我也不知道怎么回事。。。所以你看我在這邊注釋,這行不能刪了。。。”
“en。。。我覺得這個(gè)功能很酷,你們雖然現(xiàn)在不需要,不過有總比沒有好吧,將來如果……%¥……&%&……%*7&%……*%…(我沒聽懂)的話,這個(gè)就很有用!!”
...
一次次被我打回去重寫,后來總算簡化成大概5k行了;臨走時(shí)候跟我說:你這樣編程也太難了。。。
再后來由于一些額外復(fù)雜的代碼造成我們實(shí)現(xiàn)新東西會很復(fù)雜,我又重寫了一遍,總共大概不到1k行代碼。
這里邊有幾件事情我想說
做出來容易, 做正確難,這里做出來指沒bug且完成需要的功能,這是最基本要求,不多加討論。這里正確,不是指功能正確,而是指程序可以很容易推理理解,理解意圖, 理解如何做到的,理解為什么系統(tǒng)不會出錯(cuò)。理解為什么要這么做。正確是現(xiàn)在怎么寫不會挖坑害將來的人,現(xiàn)在怎么寫能讓別人1年后看你代碼時(shí)候不可能理解錯(cuò)你現(xiàn)在的意圖,現(xiàn)在怎么寫能在別人將來犯錯(cuò)的時(shí)候提示他你錯(cuò)了。
編程是給未來的未知人講故事,你無法知道將來這個(gè)人是誰,他都懂什么,他經(jīng)歷過什么,這個(gè)系統(tǒng)將來已經(jīng)是什么樣子了。我們需要在這種無知,缺乏信息的情況下做決定,從千萬種把這件事做出來的方法里,選出你覺得最能把這個(gè)故事給講好的那種方式,把故事寫下來。編程是一種溝通,溝通是一種藝術(shù),用程序跨越時(shí)空之溝通則是一門屬于程序員的特有的藝術(shù)(就好比數(shù)學(xué)家用數(shù)學(xué)公式來溝通) coding is all about the art of communication(引用)。
壞的決定會導(dǎo)致壞的決定,甚至導(dǎo)致人們?nèi)ヅで粋€(gè)好的決定去迎合壞的決定。垃圾會制造垃圾,一個(gè)放在系統(tǒng)里不經(jīng)清理的額外復(fù)雜度,會導(dǎo)致更多的額外復(fù)雜度的生成。
每個(gè)人甚至同一個(gè)人的不同時(shí)刻都有自己的不同的制造額外復(fù)雜度的缺陷,比如我每年去看去年自己寫的代碼,覺得都是垃圾。
然后我又想問幾個(gè)問題
我們所在的部門,所在的組,公司,它們的文化,到底是關(guān)心做出了一個(gè)東西,還是關(guān)心做好了一個(gè)東西。一個(gè)總是給系統(tǒng)添加垃圾,留坑給后人,但是能很快做出能跑起來的系統(tǒng)的程序猿,我們到底認(rèn)為他是做了好事還是做了壞事?我們到底認(rèn)為他很強(qiáng),還是他很弱?用超過必要而為了突顯技術(shù)實(shí)力的復(fù)雜工具,技術(shù)框架搭建系統(tǒng),做完跑路,在一個(gè)組,一個(gè)部門,一個(gè)公司,那里的文化,到底應(yīng)該是鼓勵(lì)還是抑制這種行為?我們又應(yīng)該如何在一個(gè)環(huán)境中,去倡導(dǎo)推崇什么樣的文化,相遇什么樣的人?
人與文化,決定了什么人留在這里,什么人離開,什么人吸引什么人,什么人成長成什么樣子。而設(shè)計(jì)/技術(shù)這些枝末細(xì)節(jié)則必順應(yīng)此中的人與文化而自然變化,或自愈,或走向毀滅;哪怕在惡劣的環(huán)境中,向下引導(dǎo),向上規(guī)諫,潛移默化,最終改天換日,此為編程之大道也!
下邊是定理證明
======畫風(fēng)突變高能預(yù)警!!!!!!
最小垃圾存在定律:定義垃圾為系統(tǒng)的總復(fù)雜度減去系統(tǒng)的本質(zhì)復(fù)雜度;那么得到:如存在多種方法可以設(shè)計(jì)與實(shí)現(xiàn)一個(gè)系統(tǒng)或功能,存在且只存在一種實(shí)現(xiàn)會引入最少的垃圾;
垃圾與復(fù)雜度正比定律:根據(jù)定義可得,系統(tǒng)存在的垃圾越多,系統(tǒng)越復(fù)雜;
垃圾倍增定律:基于已有垃圾量a的現(xiàn)狀來演化,進(jìn)化此系統(tǒng),增加的新垃圾量與已有垃圾量a成正比;
系統(tǒng)腐敗定律:當(dāng)基于垃圾量a來實(shí)現(xiàn)新功能的cost大于新功能本身的價(jià)值時(shí),系統(tǒng)腐敗,需要重構(gòu);
戰(zhàn)斗人員負(fù)戰(zhàn)力定律:如果程序員a引入的垃圾,在n次迭代中經(jīng)過倍增所造成的成本,大于其所清掃的垃圾經(jīng)過倍增所獲得的機(jī)會成本,和其實(shí)現(xiàn)的新功能價(jià)值之和。此時(shí),我們稱此程序員戰(zhàn)力為負(fù)值,其戰(zhàn)力絕對值與其引入垃圾的能力和其清掃垃圾的能力的差值成正比
以一敵百存在定律:由負(fù)戰(zhàn)力定律可知,對所有的自然數(shù)n,一個(gè)正戰(zhàn)力的戰(zhàn)斗人員的戰(zhàn)力 > (負(fù)戰(zhàn)力戰(zhàn)斗員1+負(fù)戰(zhàn)力戰(zhàn)斗員2+ … 負(fù)戰(zhàn)力戰(zhàn)斗員n)的戰(zhàn)力和
系統(tǒng)本質(zhì)復(fù)雜度不可知定律與系統(tǒng)表征復(fù)雜度無限接近本質(zhì)定律:取決于戰(zhàn)斗人員的知識量,經(jīng)驗(yàn),天賦等,對于任何戰(zhàn)斗人員n,都必定存在一個(gè)戰(zhàn)斗人員m(考慮歷史長河)使得戰(zhàn)斗人員n觀察系中的純凈無垃圾系統(tǒng)(復(fù)雜度總為1)是戰(zhàn)斗人員m觀察系中的含垃圾系統(tǒng)(復(fù)雜度為1+x),這使得在所有觀察系中(包含外星生物),系統(tǒng)的表征復(fù)雜度(或者說觀察復(fù)雜度)無限趨近與本質(zhì)復(fù)雜度。然而我們只能通過觀察來感知事物的本質(zhì)復(fù)雜度,卻永遠(yuǎn)無法得知我們離本質(zhì)復(fù)雜度還有多遠(yuǎn)。
以有限的生命去追求可以無限的提升的凈化方法與視野,我們稱之程序藝術(shù)家,也就是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》
打星際… 哦,不, 錯(cuò)了重來… ?寫程序,你快樂嘛?
寫在最后,看到大家最關(guān)心的是他拿到正式錄取資格了么?還有也許通過我的描述關(guān)于他的這個(gè)側(cè)面,你會覺得他很不稱職。其實(shí)不是的,他代碼寫的絕對是平均值往上的水平,他的問題在于:
1、是他根本沒有想過去簡化業(yè)務(wù)邏輯,所以很多符合最初需求的代碼在簡單優(yōu)化業(yè)務(wù)邏輯之后完全不需要;
2、是自己加了很多功能;
3、是自己加了很多自以為是的優(yōu)化,比如用一個(gè)算法估算某個(gè)函數(shù)的輸入數(shù)組的最大可能值,然后用那個(gè)值來初始化一個(gè)數(shù)組,因?yàn)檫@樣就不會重新分配內(nèi)存了(他原話)
4、抽象能力有限,這個(gè)畢竟經(jīng)驗(yàn)少, 年輕;
5、濫用設(shè)計(jì)模式(關(guān)于設(shè)計(jì)模式,最多程序員被絆住的一關(guān):設(shè)計(jì)模式是面向?qū)ο缶幊棠P椭?#xff0c;應(yīng)對經(jīng)典問題的經(jīng)典解決方案。
這里有兩個(gè)問題
第一,設(shè)計(jì)模式的場景用對了么?
第二,為什么要用面向?qū)ο?strong>范式,選擇編程語言范式時(shí),要從表達(dá)力最弱最簡單的語言范式開始選擇。
這叫做最弱表達(dá)力原則,而面向?qū)ο蠓妒阶鳛樽顝?fù)雜,表達(dá)力最強(qiáng)的語言范式,在大多數(shù)時(shí)候都可以避免使用。關(guān)于第二點(diǎn)的論述證明,你可以看concept techniques and models of computer programming這本書。注意,這里說的是語言范式,而不是語言。即使你用java,如果你從來不使用mutable(專業(yè)詞匯)的功能,和繼承。那么你就沒有使用面向?qū)ο蠓妒?
他其實(shí)有非常強(qiáng)的解決問題的能力,想法天馬行空,通過自己設(shè)計(jì)算法來猜函數(shù)可能需要的數(shù)組大小就可見一斑,還有一個(gè)從s3(專業(yè)詞匯)讀數(shù)據(jù)的需求,他不是簡單調(diào)api完了,而是寫了一個(gè)環(huán)狀buffer(專業(yè)詞匯),使得網(wǎng)絡(luò),硬盤,app可以在理論上最大效率的適應(yīng)程序當(dāng)時(shí)的場景(為了協(xié)調(diào)異步,他自己發(fā)明了一個(gè)很笨拙的promise(專業(yè)詞匯))
這非常厲害,一般的實(shí)習(xí)生哪怕sde1可能都寫不出來(可惜的是場景會隨業(yè)務(wù)邏輯激烈變化,今天的優(yōu)化可以是明日的累贅,這就叫做過度優(yōu)化,過度優(yōu)化是一種強(qiáng)耦合,會把你的系統(tǒng)死死的釘死在當(dāng)前版本)。他只是不明白簡單是美這件事情而已。如果能有人幫他斧正,日后必成大器。
他最終拿到了正式錄取資格,這其中還有個(gè)小波折,終審的bar raiser(amazon內(nèi)部的一個(gè)可以一票否決招聘結(jié)果的角色)看到他在代碼復(fù)查系統(tǒng)里跟我的各種激辯,覺得這人不能留。好說歹說才給了正式錄取資格。不過最后人家沒接,去讀博啦。
最最后,在一個(gè)相對干凈的環(huán)境寫程序,不斷找出新的本來以為不是垃圾的垃圾,對我來說,是一件非常愉快的事情。然而幫別人打掃他本就不該制造的垃圾則是非常痛苦的一件事。
寫程序,本應(yīng)是多么快樂的一件事啊!
作者:阿萊克西斯
來源:
https://www.zhihu.com/question/22508677/answer/276595266
版權(quán)歸原作者所有,轉(zhuǎn)載僅供學(xué)習(xí)使用,不用于任何商業(yè)用途,如有侵權(quán)請留言聯(lián)系刪除,感謝合作。
數(shù)據(jù)與算法之美
用數(shù)據(jù)解決不可能
長按掃碼關(guān)注
總結(jié)
以上是生活随笔為你收集整理的编程到底难在哪里? 从一个美国实习生的故事说起的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何解开机器学习的面纱?
- 下一篇: 数据可视化,带给你的惊艳并不止这一点!