我曾經(jīng)認(rèn)為編程很容易, 但多年之后我慢慢意識(shí)到我錯(cuò)了: 一份程序員的工作和我理解的”寫(xiě)程序”是不同的.
起初我覺(jué)得編程無(wú)非就是命令計(jì)算機(jī)工作, 而這相對(duì)來(lái)說(shuō)并不算難. 在工作了二十多年之后,我愈發(fā)覺(jué)得這實(shí)在是非常容易的事情,
為什么說(shuō)編程不是一件容易的事兒
。定義1:程序是一種由輸入到輸出的變換。
程序員即是寫(xiě)程序的人,編程即是寫(xiě)程序的過(guò)程。
現(xiàn)在再讓我們?yōu)樯厦娴亩x加上一些限制條件。
定義2:程序是一種滿足以下條件的,由輸入到輸出的變換:
1、輸出要優(yōu)雅(原文beautiful)。
2、輸入要優(yōu)雅。
3、程序本身要優(yōu)雅。
4、輸入文檔詳盡準(zhǔn)確。
5、程序本身的文檔詳盡準(zhǔn)確。
6、程序經(jīng)歷過(guò)嚴(yán)格的測(cè)試,能夠保證正確的結(jié)果。
7、程序提供的解決方案的文檔詳盡。
8、程序要解決的問(wèn)題本身的文檔詳盡。
當(dāng)添加了這些限制之后,編程就變得非常困難了。對(duì)于一些特定的情況,我們可以適當(dāng)放寬以上的限制條件。下面就來(lái)介紹幾種典型的情況:
不需要維護(hù)的程序
我們寫(xiě)程序常常只是為了輸出。這種情況下,輸入和程序本身并不一定要考慮未來(lái)維護(hù)的問(wèn)題,也不必一定要寫(xiě)得那么優(yōu)雅并配備詳盡的文檔。
我寫(xiě)過(guò)的一本關(guān)于Erlang的書(shū)的排版程序就是這種情況。當(dāng)這本書(shū)發(fā)表之后,再維護(hù)輸入和排版程序就顯得沒(méi)什么必要了。只要輸出看起來(lái)不錯(cuò)就可以了,雜亂的XML輸入文件和測(cè)試程序不需要維護(hù)。
如果這本書(shū)再版,訂正只需要稍微更改一下輸入就可以了。即使輸入文件沒(méi)有詳細(xì)的文檔,這件事做起來(lái)也非常容易。
需要被維護(hù)的程序
需要被維護(hù)的程序剛好和上面的情況相反。輸入和程序本身要優(yōu)雅,相關(guān)文檔也要詳盡。
我前些天和一個(gè)寫(xiě)網(wǎng)絡(luò)應(yīng)用的顧問(wèn)聊天,他說(shuō)只要程序的輸出了正確的結(jié)果(網(wǎng)站看起來(lái)沒(méi)什么問(wèn)題各種功能也能正常工作),用戶就認(rèn)定這個(gè)項(xiàng)目已經(jīng)完成了然后項(xiàng)目經(jīng)理就把他加進(jìn)下一個(gè)項(xiàng)目組里。
他們不明白對(duì)于網(wǎng)站來(lái)講僅僅看起來(lái)OK是不夠的,也根本沒(méi)有預(yù)留時(shí)間給整理代碼,編寫(xiě)文檔這些對(duì)未來(lái)網(wǎng)站維護(hù)有幫助的事情,下一個(gè)項(xiàng)目就開(kāi)始了。
其他使編程變得困難的事
還有三件事會(huì)使編程變得困難:
1、處理本來(lái)不應(yīng)當(dāng)出現(xiàn)的問(wèn)題。
2、沒(méi)有慢吞吞地學(xué)習(xí)新知識(shí)的時(shí)間。
3、苛刻的系統(tǒng)環(huán)境。
就讓我們來(lái)看看程序員的時(shí)間是怎樣被這些家伙吃掉的吧。
處理本來(lái)不應(yīng)當(dāng)出現(xiàn)的問(wèn)題
我經(jīng)常要用一些別人編寫(xiě)的軟件來(lái)解決問(wèn)題,但我往往并不能夠很好地理解這些程序。
一款優(yōu)秀的軟件有準(zhǔn)確的文檔告訴我如何使用它,但真實(shí)世界中的情況常常要糟糕得多:不是沒(méi)有文檔就是文檔寫(xiě)得不準(zhǔn)確。
文檔這樣寫(xiě)道:“依次執(zhí)行XYZ命令,就會(huì)得到結(jié)果PQR。”而你執(zhí)行XYZ之后得到的結(jié)果根本不是PQR!這種情況下你要怎么辦?如果你足夠走運(yùn),寫(xiě)這個(gè)程序的老兄就在附近,你大可以走上去掐死他;大多數(shù)人只能去Google一下試試運(yùn)氣,或者試著讀一下源代碼看看能否找到答案。
利用Google搜索一個(gè)bug的解決方案簡(jiǎn)直像賭博一樣令人沮喪。我用Google搜索了半天終于發(fā)現(xiàn)了一個(gè)倒霉蛋也遇到和我一模一樣的問(wèn)題,哈哈哈哈哈。但是當(dāng)我滿懷期盼地點(diǎn)開(kāi)鏈接的時(shí)候。。。什么都沒(méi)有,這個(gè)問(wèn)題還沒(méi)有人解答。
為什么這個(gè)補(bǔ)丁別人可以用我就不行,是因?yàn)槲宜ド窀襟w了嗎?還是我所處的空間扭曲到正常人類(lèi)世界的物理定律已經(jīng)失效的地步?雖然這很令人沮喪,但不同的機(jī)器初始狀態(tài)會(huì)不一樣也很正常,因此能夠解決別人bug的補(bǔ)丁在我的機(jī)器上可能并不適用,
電腦資料
《為什么說(shuō)編程不是一件容易的事兒》(http://www.szmdbiao.com)。有時(shí)我會(huì)這樣想:要是我們都用Smalltalk編程,都從同樣的起始狀態(tài)開(kāi)始運(yùn)行就好了。Smalltalk程序員一定生活在一個(gè)根本不用擔(dān)心這種問(wèn)題的美好的世界里,但那也只是暫時(shí)的,當(dāng)他們的程序和其他語(yǔ)言編寫(xiě)的程序通訊的時(shí)候,他們終究會(huì)明白這個(gè)世界有多么的殘酷。
排查程序的錯(cuò)誤也是令人沮喪的,因?yàn)槟悴⒉磺宄㧏ug最后到底為什么消失了,是因?yàn)槟阕詈笠淮蔚母膭?dòng)嗎?還是因?yàn)槟阒八懈膭?dòng)效果的總和?
問(wèn)題的關(guān)鍵在于諸如此類(lèi)的事情占據(jù)了程序員60%到70%的時(shí)間。我曾經(jīng)花了一周才讓一個(gè)出問(wèn)題的LDAP服務(wù)器重新工作了,因?yàn)槔洗蟛蛔屛易约簩?xiě)這個(gè)服務(wù)器。我在折騰了一周這個(gè)用C語(yǔ)言開(kāi)發(fā)的,文檔寫(xiě)得很爛的破玩意之后,終于決定把老大的話拋在腦后,用中午吃飯的時(shí)間自己寫(xiě)了一個(gè)Erlang的版本,問(wèn)題才終于解決了。
我承認(rèn)我寫(xiě)的并不是一個(gè)完整的LDAP服務(wù)器,但我也不需要一個(gè)完整的LDAP服務(wù)器,只要其中的一些命令行可以工作就可以了,這解決起來(lái)非常容易。
現(xiàn)在我已經(jīng)不會(huì)對(duì)實(shí)現(xiàn)那些古董級(jí)的協(xié)議感到興奮了,但一般說(shuō)來(lái)和用別人的代碼相比自己重新實(shí)現(xiàn)往往會(huì)節(jié)省更多的時(shí)間。
解決問(wèn)題和學(xué)習(xí)是不同的
我是一個(gè)徹頭徹尾的懶鬼。當(dāng)我想用Latex插入一個(gè)圖表的之前我不想先看完391頁(yè)文檔。你當(dāng)然可以指責(zé)我懶惰,我也明白照理來(lái)說(shuō)我應(yīng)當(dāng)先把那篇熱情洋溢的文檔讀完,但我只有十分鐘,根本沒(méi)法讀完那篇文檔。
當(dāng)我需要解決問(wèn)題的時(shí)候,我需要的是快速的解決方案,這個(gè)時(shí)候過(guò)于冗長(zhǎng)的說(shuō)明文檔對(duì)我我來(lái)說(shuō)就是災(zāi)難。
以排版程序?yàn)槔以?jīng)在這三款軟件面前搖擺不定:Tex/Latex,XSLT-FO,Erlguten。
差不多每三年我都會(huì)強(qiáng)烈地想使用postscript來(lái)寫(xiě)文檔,每當(dāng)我有這種感覺(jué)的時(shí)候,我都會(huì)深吸一口氣,然后靜靜地等待這種感覺(jué)自己消失。
我猜詹巴蒂斯塔波多尼在1818年制作他的Manuale Tipografico (詹巴蒂斯塔波多尼的Manuale Tipografico被稱(chēng)為最偉大的模式標(biāo)本的書(shū)的印刷。發(fā)行追授于1818年在帕爾馬由波多尼的忠實(shí)遺孀瑪格麗特,兩卷本著作中包含的142羅馬字母琳瑯滿目相應(yīng)斜體,許多腳本和異國(guó)情調(diào)的字體,以及鮮花和裝飾品驚人的集合)無(wú)人問(wèn)津,可能排版一頁(yè)都要耗時(shí)一周,讓機(jī)器完成枯燥而危險(xiǎn)的任務(wù)可以使我們解放出更多的時(shí)間
我問(wèn)過(guò)我的老板,他是否需要漂亮的幻燈片來(lái)演講。他說(shuō)需要,但要我明天之前給他。這讓我沒(méi)有合適的時(shí)間來(lái)學(xué)習(xí)TeX (我猜可能需要一兩年),沒(méi)時(shí)間實(shí)現(xiàn)自己的排版語(yǔ)言(我猜需要5-10年),沒(méi)時(shí)間把它記載到附錄中,我權(quán)衡了需要時(shí)間去學(xué)習(xí)的幾個(gè)方案,最終選擇了 PowerPoint。
惡劣的編程環(huán)境
有些工作場(chǎng)所的設(shè)計(jì)使編程更加困難,無(wú)隔板開(kāi)放式辦公室那嘈雜的環(huán)境,破壞了我們的注意力,移動(dòng)電話的打擾,以及互聯(lián)網(wǎng)都會(huì)分散我們的注意力。 幸運(yùn)的是我們還有可去的地方,那就是睡覺(jué)。很多編程問(wèn)題是在睡覺(jué)過(guò)程中解決的。 有兩種方法:首先將考慮的問(wèn)題記住,然后睡覺(jué),第二天醒來(lái)一些問(wèn)題就被解決了,So Easy; 另一種方法是睡覺(jué)前在一些論壇或者用 tweet 發(fā)個(gè)帖子,第二天已經(jīng)有人將解決方法發(fā)給你了。 做一名優(yōu)秀程序員需要很長(zhǎng)的時(shí)間,你需要學(xué)習(xí)很多東西,當(dāng)遇到問(wèn)題的時(shí)候,你需要知道向誰(shuí)請(qǐng)教。
驚人但是事實(shí)
當(dāng)我完成本文檢查內(nèi)容的拼寫(xiě)時(shí),但我使用emacs-ispell模式檢查拼寫(xiě),它罷工了,并顯示沒(méi)發(fā)現(xiàn)aspell
我的emacs 拼寫(xiě)檢查器在本地忠實(shí)的工作了好幾年.就在我抱怨生活一成不變時(shí),它跌破我的眼鏡.
我不相信上帝有惡意,也不相信我房間里左手沙發(fā)的物理定律和我右手的不同,但有間接證據(jù)表明正好相反.
我不明白我明明什么都沒(méi)做,我的拼寫(xiě)檢查器就出了問(wèn)題.為了檢查上次文檔的拼寫(xiě),我安裝一個(gè)Erlang新版本和Julia,并寫(xiě)下了一些講義
幸運(yùn)的是,11分鐘如同在Google賭場(chǎng)工作. 第二個(gè)建議性的工作:我不知道問(wèn)什么我的emacs不能找到aspell-生命太短,問(wèn)題太莫名.
我猜有些事我們永遠(yuǎn)不知道答案.