應(yīng)人民郵電出版社圖靈公司的邀請(qǐng),我有幸參與了Bob大叔所著Clean Coder的翻譯。

  與前作Clean Code不同,這本書著重講述的是開發(fā)人員的“職業(yè)素養(yǎng)”,也即職業(yè)開發(fā)人員應(yīng)當(dāng)如何做事。在閱讀中,我時(shí)常會(huì)忍俊不禁,也會(huì)拍案叫絕,感嘆Bob大叔把深刻的道理講得這樣通透。我雖然沒有Bob大叔那樣好的文筆,不過(guò)對(duì)“開發(fā)人員的職業(yè)素養(yǎng)”這個(gè)話題,仍然有很多話想說(shuō),索性分幾個(gè)方面寫下來(lái)。

  學(xué)習(xí)

  開發(fā)人員在工作之前,一般都已經(jīng)經(jīng)過(guò)大學(xué)階段的專業(yè)學(xué)習(xí)。眾所周知,大學(xué)的很多課程已經(jīng)相當(dāng)落后,教材也非常保守,所以我見過(guò)的好開發(fā)人員,不少都是自學(xué)成才。但是,這些問(wèn)題并不能否認(rèn)通過(guò)專業(yè)課程學(xué)習(xí)知識(shí)的意義,職業(yè)開發(fā)人員理解的“學(xué)習(xí)”,應(yīng)當(dāng)明確地區(qū)分知識(shí)、課程、教材:知識(shí)是重要的、穩(wěn)定的,課程和教材是不那么重要的、變化的。

  可以非?隙ǖ卣f(shuō),數(shù)據(jù)結(jié)構(gòu)、編譯原理、操作系統(tǒng)這類知識(shí),是整個(gè)計(jì)算機(jī)世界的基石,是任何時(shí)候也不會(huì)過(guò)時(shí)的。即便畢業(yè)后不從事專門的科研,這類知識(shí)也會(huì)從你接觸到的各種現(xiàn)象中體現(xiàn)出來(lái)。我在大學(xué)時(shí)基本拋棄了學(xué)校指定的課程和教材,但自己反復(fù)啃過(guò)影印版的《現(xiàn)代操作系統(tǒng)》,反復(fù)做過(guò)北大屈婉玲老師的三本《離散數(shù)學(xué)習(xí)題集》,后來(lái)在工作中受益匪淺??調(diào)優(yōu)程序的性能,很可能需要理解調(diào)度、死鎖、用戶空間與系統(tǒng)空間等知識(shí);重構(gòu)復(fù)雜的布爾邏輯,很可能要依賴數(shù)理邏輯中的定律。如果當(dāng)時(shí)沒有反復(fù)的研習(xí),沒有深入理解這背后的原理,并且沒有領(lǐng)悟到這些原理和各種現(xiàn)象之間的聯(lián)系,遇到很多問(wèn)題我很可能會(huì)兩眼抓瞎,充其量憑經(jīng)驗(yàn)試錯(cuò),無(wú)論如何,其效率遠(yuǎn)不及知識(shí)體系指導(dǎo)下的實(shí)踐。

  據(jù)我觀察,大學(xué)生之所以對(duì)課程不感冒,除去學(xué)校和教師的原因,另一個(gè)因素是,幾乎很少有教材能把看起來(lái)乏味的原理,和生活中遇到的問(wèn)題講清楚。學(xué)習(xí)圖算法時(shí),你是否想過(guò)“人、狼、羊、草過(guò)河”的問(wèn)題可以直接由它來(lái)解決?學(xué)習(xí)內(nèi)存管理時(shí),你是否想過(guò)為什么Windows 95、Windows 98都那么容易藍(lán)屏,到了Windows XP才有了長(zhǎng)足的進(jìn)步?我相信,如果能把原理與這類例子對(duì)應(yīng)起來(lái),你的理解會(huì)深刻許多,印象也會(huì)深刻許多。不幸的是,這類“聯(lián)系”的工作,在國(guó)內(nèi)教材基本是一片空白,國(guó)外教材也只有部分涉及。其結(jié)果是,不少“有經(jīng)驗(yàn)”的開發(fā)人員面對(duì)“32位機(jī)為什么只能支持4G內(nèi)存”、“一個(gè)字是多少個(gè)字節(jié)”、“進(jìn)程間通訊有哪幾種方式,各有什么優(yōu)劣”之類基本的問(wèn)題一臉茫然,不要小看了這些問(wèn)題,不懂它們,你開發(fā)出來(lái)的程序只能湊合用,后期遇到問(wèn)題要重構(gòu)、調(diào)優(yōu),簡(jiǎn)直難比登天。

  對(duì)此,我的建議是:如果你現(xiàn)在還在學(xué)校,不妨仔細(xì)想想知識(shí)、課程、教材之間的聯(lián)系,確定重要的知識(shí),選擇好的教材,自己安排自己的課程。如果你已經(jīng)離開學(xué)校,而且感覺自己的基礎(chǔ)并不牢靠,不妨從手頭的工作開始,想想它用到了哪些原理,對(duì)應(yīng)哪些知識(shí),逐步、有針對(duì)性地補(bǔ)習(xí)。這其實(shí)并沒有太多難度??我的朋友張東亮(@zhasm),之前幾乎沒有任何計(jì)算機(jī)基礎(chǔ)知識(shí),只是因?yàn)閷?duì)正則表達(dá)式的愛好,找到了一份開發(fā)人員的工作,一年之后,他已經(jīng)開始啃編譯原理之類的書籍了。

  以上說(shuō)的主要是“專門”的學(xué)習(xí),如果是工作之后的學(xué)習(xí),會(huì)有很大的不同。

  首先,工作之后的學(xué)習(xí)更多依靠自覺,沒有幾家公司會(huì)付出代價(jià)讓員工像學(xué)生那樣“學(xué)習(xí)”,所以更多時(shí)候,你只能花自己的時(shí)間、自己的金錢來(lái)學(xué)習(xí)。很多人一想到要花自己的時(shí)間,自己的金錢,心里打了退堂鼓。要明確的是,公司沒有老師那樣強(qiáng)烈的責(zé)任培養(yǎng)員工“成長(zhǎng)”,如果你找不到好的、薪水高的工作,恐怕很難責(zé)怪上一家公司沒給你好的培訓(xùn)。所以,擔(dān)心金錢和時(shí)間而放棄學(xué)習(xí),終的結(jié)果是自己停止了成長(zhǎng),逐漸喪失競(jìng)爭(zhēng)優(yōu)勢(shì)。相反,投入時(shí)間和金錢來(lái)學(xué)習(xí),不但可以保持甚至擴(kuò)大你的競(jìng)爭(zhēng)優(yōu)勢(shì),如果這種行為可以堅(jiān)持、內(nèi)化到生活中,也有助于保持健康、飽滿的精神狀態(tài)。

  其次,工作以后的學(xué)習(xí),需要努力擺脫工作環(huán)境的限制。我見過(guò)不少開發(fā)人員,因?yàn)楣ぷ飨薅ㄔ谀硞(gè)平臺(tái),某種語(yǔ)言,業(yè)余時(shí)間的學(xué)習(xí)便全部投入到這種平臺(tái)、這種語(yǔ)言上,而沒有思考自己是否合適做這些平臺(tái)和語(yǔ)言,這些平臺(tái)和語(yǔ)言是否在走下坡路。在學(xué)校里,考分或許往往是的度量,但在工作中,行將沒落的語(yǔ)言和平臺(tái),你運(yùn)用再熟練,也于事無(wú)補(bǔ)。況且,過(guò)于專精于一門語(yǔ)言、一個(gè)平臺(tái),反而會(huì)限制你的思維和視野,影響迅速學(xué)習(xí)陌生知識(shí)的能力??要在短時(shí)間內(nèi)熟悉陌生平臺(tái)和語(yǔ)言的例子,在我們工作中并不少見,在整個(gè)IT業(yè)界中更是家常便飯。為了讓它真的成為“便飯”,平時(shí)還是應(yīng)當(dāng)有意識(shí)地?cái)[脫工作環(huán)境的限制,挑戰(zhàn)自己的思維慣性。

  責(zé)任

  我曾經(jīng)見過(guò)很多的簡(jiǎn)歷,在“工作經(jīng)歷”里,項(xiàng)目描述寫得天花亂墜,如何先進(jìn),如何復(fù)雜,采用了多少新技術(shù),但是具體到個(gè)人責(zé)任,或者語(yǔ)焉不詳,或者極其潦草。這樣簡(jiǎn)歷,體現(xiàn)的是責(zé)任感的缺失??對(duì)于自身責(zé)任沒有明確的認(rèn)知,也沒有足夠的擔(dān)當(dāng);這樣的人,通常不用面試,可以知道并不是合格的“職業(yè)開發(fā)人員”。

  另一方面,我在面試時(shí),經(jīng)常會(huì)問(wèn)兩個(gè)問(wèn)題,其中很重要的一個(gè)是:在你的工作經(jīng)歷中,收獲大或者印象深的事件是什么。一般來(lái)說(shuō),如果能回答得有條理、有依據(jù),大多可以判定為合格的職業(yè)開發(fā)人員。因?yàn)椋胸?zé)任感的開發(fā)人員,大多不會(huì)把程序看成身外之物,更多地會(huì)把程序與自己的道德、聲譽(yù)等等聯(lián)系起來(lái),甚至把程序看成自己的孩子;所以,必然會(huì)投入時(shí)間精力去總結(jié)、反思、完善、改進(jìn),像照顧自己的孩子那樣。其實(shí),我的經(jīng)驗(yàn)看,真正的職業(yè)開發(fā)人員,不但能很好地回答這個(gè)問(wèn)題,而且說(shuō)起自己做過(guò)的事情,多有種充沛的自信感:XX項(xiàng)目是我做的,其特點(diǎn)是什么,我是如何如何做的,遇到什么問(wèn)題,是如何解決的……涉及的技術(shù)不必很先進(jìn),開發(fā)的系統(tǒng)也不必很復(fù)雜,只要能夠這么自信滿滿地一條條歷數(shù)下來(lái),你的職業(yè)素養(yǎng)是無(wú)可厚非的。

  業(yè)務(wù)

  軟件開發(fā)中,需求變化是無(wú)可避免的。雖然敏捷開發(fā)、極限編程宣稱要“擁抱變化”,但真正做到擁抱變化,卻是難上加難。原因在于:一方面,不少開發(fā)人員對(duì)變化本身持懷疑甚至抵觸態(tài)度;另一方面,許多需求
  這個(gè)問(wèn)題非常普遍,也很嚴(yán)重。我思考了很久,發(fā)現(xiàn)比較合適的解決辦法是進(jìn)行角色的互換,尤其是開發(fā)方(包括開發(fā)人員),不能局限于“按照規(guī)程實(shí)現(xiàn)功能”的角色,而應(yīng)當(dāng)深入思考和理解業(yè)務(wù)。

  不少開發(fā)人員“理想”的工作環(huán)境是:根本不關(guān)心自己的工作成果給誰(shuí)用,怎么用,會(huì)產(chǎn)生什么結(jié)果,他們更喜歡這樣的描述:什么類型的數(shù)據(jù)從哪里來(lái),怎樣處理之后,后交給哪里。在架構(gòu)清晰、流程完備的大公司里,或許你只需要安心填格子即可,但是擁有這樣工作環(huán)境的開發(fā)人員,占總數(shù)的多少呢?更多的人面對(duì)的還是變化不定的需求,甚至連業(yè)務(wù)部門自己都不清楚自己要的是什么,這種情況下,只關(guān)心“數(shù)據(jù)從哪里來(lái),怎樣處理,交給哪里”之類的問(wèn)題,無(wú)異于盲人騎瞎馬,無(wú)異于挖坑埋葬自己。

  相反,如果你清楚某個(gè)實(shí)現(xiàn)方案的緣由,知道它是基于何種應(yīng)用場(chǎng)景,如何設(shè)計(jì)出來(lái)的,可以在相當(dāng)程度上把握它的價(jià)值和所需的工作量。如果更主動(dòng)一些,可以和業(yè)務(wù)部門談,這么做,將來(lái)會(huì)遇到什么問(wèn)題,如果將來(lái)要改,哪些環(huán)節(jié)是可以改的,哪些環(huán)節(jié)是不能改的??如果你設(shè)身處地地為對(duì)方考慮,給出的建議一定比技術(shù)味道濃厚的“做不出來(lái)”更有說(shuō)服力。如果做不到這么主動(dòng),你也可以預(yù)估,哪些業(yè)務(wù)是穩(wěn)定不變的,哪些業(yè)務(wù)是一定會(huì)遇到問(wèn)題需要改變的,然后可以合理分配工作量:對(duì)那些明顯沒什么前途的項(xiàng)目,可以適當(dāng)保留資源,以免將來(lái)竹籃打水;對(duì)那些目前業(yè)務(wù)部門認(rèn)為不重要,其實(shí)又相當(dāng)有價(jià)值的項(xiàng)目,可以適當(dāng)多投入精力,以免將來(lái)措手不及??要知道,業(yè)務(wù)部門提的“緊急”需求,多半不會(huì)考慮開發(fā)的工作量。

  需要補(bǔ)充的是,做到上面這點(diǎn),其實(shí)有相當(dāng)?shù)碾y度:一方面,你的技術(shù)功底必須足夠扎實(shí),在滿足需求時(shí),不僅僅是“模仿”現(xiàn)實(shí),而應(yīng)當(dāng)知道這種現(xiàn)實(shí),在數(shù)字世界里應(yīng)當(dāng)如何表達(dá),如何重構(gòu),受到哪些條件和規(guī)則的限制(比如同一個(gè)抽象操作的不同實(shí)現(xiàn),到底是選擇Switch語(yǔ)句還是多態(tài),其實(shí)是有章可循的,必須根據(jù)實(shí)際情況選擇);另一方面,又要能跳開技術(shù)的局限,從更全面的視角理解、把握業(yè)務(wù)。不過(guò),這是非常值得花功夫的??從某種意義上可以說(shuō),當(dāng)前熱門的“領(lǐng)域驅(qū)動(dòng)開發(fā)(Domain Driven Development)”,說(shuō)的大抵是這回事。

  時(shí)間

  在軟件開發(fā)中,時(shí)間是一個(gè)非常重要的因素。在這方面,已經(jīng)有無(wú)數(shù)的巨著,無(wú)數(shù)的案例,無(wú)數(shù)的先烈,但是時(shí)間,仍然是一個(gè)值得討論的話題。

  總的來(lái)說(shuō),人月是一個(gè)神話,我們不可能精確地把握開發(fā)時(shí)間,但是這并不意味著,我們不能從某種程度上把握時(shí)間。我個(gè)人的經(jīng)驗(yàn)是,計(jì)劃是在現(xiàn)實(shí)參照下的不斷調(diào)整和修正中逐漸準(zhǔn)確的。重要的,并不是確定遠(yuǎn)大的目標(biāo),然后限定多長(zhǎng)時(shí)間必須完成;而是可以把大的項(xiàng)目拆分為不同的模塊,把整個(gè)開發(fā)流程劃分為不同的階段。如果你的模塊劃分得足夠細(xì)致,可以以每個(gè)模塊的工作量,相對(duì)準(zhǔn)確地得知整個(gè)項(xiàng)目的耗時(shí);如果你的流程劃分得足夠合理,可以在各個(gè)階段拿出看得見、用得著的結(jié)果,供業(yè)務(wù)方使用。這樣,一方面避免了“到后一起推出,卻發(fā)現(xiàn)與業(yè)務(wù)方想象大相徑庭”的尷尬;另一方面,在開發(fā)過(guò)程中,每個(gè)階段結(jié)束,可以提供一個(gè)階段的生產(chǎn)力,作為開發(fā)方,在面對(duì)質(zhì)疑時(shí),有足夠的資本和底氣。

  從個(gè)人方面,我注意到,職業(yè)開發(fā)人員還有另一個(gè)特點(diǎn):是可以相當(dāng)精確地估計(jì)某個(gè)“小活”的工作量。以我自己和我的一些朋友為例,面對(duì)一些細(xì)致而且明確的需求,我們經(jīng)?梢跃_估計(jì)到工作量,時(shí)間精確到以半小時(shí)計(jì)。在緊密協(xié)作的“背靠背”編程中,我會(huì)說(shuō):現(xiàn)在是幾點(diǎn),所以我會(huì)在幾點(diǎn)之前,給你提供怎樣的功能,其行為是怎樣的,接口是怎樣的(行為和接口可以事先約定)。這樣的自信,既要求對(duì)所需技術(shù)、會(huì)遇到難題的把握,也要求在頭腦里對(duì)任務(wù)有完整清晰的模型。雖然難度不小,但能做到這一點(diǎn),確實(shí)是職業(yè)素養(yǎng)的典型體現(xiàn)。