11月23日開(kāi)源中國源創(chuàng )會(huì )年度(北京萬(wàn)豪酒店)千人盛典正在報名中

Joel 測試
The Joel Test
Do you use source control?
Can you make a build in one step?
Do you make daily builds?
Do you have a bug database?
Do you fix bugs before writing new code?
Do you have an up-to-date schedule?
Do you have a spec?
Do programmers have quiet working conditions?
Do you use the best tools money can buy?
Do you have testers?
Do new candidates write code during their interview?
Do you do hallway usability testing?
Joel測試的好處是很容易快速得出針對每一個(gè)問(wèn)題的“是”或“不是”。你不必去翻出那些每日編程行數和每個(gè)拐點(diǎn)的平均bug數。如果你的團隊有一個(gè)“是”就得一分。關(guān)于Joel測試令人失望的是,你真的不應該用它來(lái)確保你的核電站軟件的安全。
獲得12分是完美的,11分也還可以容忍,但10分或更低的分數表明你有嚴重的問(wèn)題。事實(shí)上,大多數軟件企業(yè)都以2分或3分的分數在運轉著(zhù),他們真的很需要幫助,因為像微軟這樣的公司一直以來(lái)都以12分的完美表現在運轉。
當 然,這些都不是決定成敗的唯一因素:特別是當你有一個(gè)正在開(kāi)發(fā)沒(méi)人要的產(chǎn)品的偉大的軟件團隊的時(shí)候,那么,人們是真的不會(huì )接受這個(gè)產(chǎn)品的。同時(shí)一個(gè)沒(méi)有這 么做的“神槍手”仍然能產(chǎn)生出令人難以置信的改變世界的軟件也是可能存在的。但是,在其他條件相同的情況下,如果你把這12件事情都做好了,你就會(huì )擁有一 個(gè)能始終如一完成任務(wù)的團隊。
我 用過(guò)商業(yè)源代碼管理包,也用過(guò)CVS,它是免費的,讓我來(lái)告訴你,CVS很好用。但如果你沒(méi)有對源代碼進(jìn)行管理,你就要應激嘗試把程序員都弄到一塊來(lái)工 作。程序員根本不會(huì )知道別人都做了什么。犯過(guò)的錯誤不能輕易改過(guò)來(lái)。關(guān)于源代碼管理系統的另一個(gè)好處就是源代碼本身可以在每個(gè)程序員的硬盤(pán)上進(jìn)行驗證 ---我還從沒(méi)聽(tīng)說(shuō)過(guò)哪個(gè)使用源代碼管理的項目丟失了很多代碼。
通 過(guò)這條測試我想明白:從最新的源代碼的快速復制到進(jìn)行能輸出的編譯需要多少步驟?再優(yōu)秀的團隊里,有一個(gè)單獨的腳本,它能從零開(kāi)始對代碼做一個(gè)全面的檢 查,重新編譯每一行代碼,生成EXE文件,在他們各種各樣的版本、編程語(yǔ)言和#ifdef宏定義組合,創(chuàng )建安裝包和最終媒體--CDROM布局、下載網(wǎng)站 等等。
如果這個(gè)過(guò)程需要一個(gè)以上的步驟,就很容易出現誤差。當你接近完工的時(shí)候,你很想有很快的修復“最后一個(gè)”bug的周期,生成最后的EXE文件等。如果編譯代碼要用20步才能完成,運行安裝編譯器,……,等等,你會(huì )抓狂的,并且會(huì )導致你犯下愚蠢的錯誤。
正式由于這個(gè)原因,我曾工作過(guò)的上個(gè)公司就從“聰敏”模式切換到了“軟件安裝打包”模式:我們要求安裝過(guò)程中可以運行,使用NT調度從腳本整晚自動(dòng)地運行,“聰明”模式做不到這些,所以我們就拋棄了這個(gè)模式。
當 你使用源代碼管理的時(shí)候,有時(shí)候程序員偶然會(huì )檢查出會(huì )停止編譯的東西。比如,他們添加了一個(gè)源文件,一切在他們的機器上編譯起來(lái)都很好,但他們忘記把源文 件添加到代碼庫里了。所以他們鎖定了機器就回家去了,比較健忘也比較高興。但其他人都不能繼續工作了,所以他們也不得不很不愉快地卷鋪蓋回家了。
打 斷編譯是很糟糕的(也很常見(jiàn)的),但它能幫助程序員每天都編譯代碼,以確保不會(huì )出現沒(méi)有預兆的編譯中斷。在大型團隊里面,一個(gè)很好的確保中斷能迅速修復的 方法是每天下午都對代碼進(jìn)行編譯,比如可以在午飯時(shí)間做這個(gè)。每個(gè)人都盡可能多地在午飯前做代碼檢查。這樣當他們吃完午飯回來(lái)的時(shí)候,這個(gè)編譯就已經(jīng)完成 了。如果它能用,就太好了!每個(gè)人都對最新的源代碼進(jìn)行檢查,然后才繼續工作。如果編譯失敗了,你就修復它,但每個(gè)人還能在預編譯、沒(méi)有中斷版本的源代碼 上繼續工作。
在Excel項目組,我們有一條規則:誰(shuí)中斷了編譯,作為對他的“懲罰”,他就要在其他人中斷編譯之前臨時(shí)照顧代碼編譯的工作。這是一個(gè)很好的不中斷編譯的激勵方式,也是一個(gè)讓每個(gè)人輪流參與編譯工作從而都能知道編譯原理的好方法。
我 不在乎你怎么說(shuō)。如果你在開(kāi)發(fā)代碼,即使是在一個(gè)人的團隊,沒(méi)有一個(gè)組織的列出代碼里所有已知bug的數據庫,你將會(huì )產(chǎn)生出低質(zhì)量代碼。許多程序員都認為 他們能把眾多的bud存在腦子里。真是胡說(shuō)八道。我根本就不能再同一時(shí)間記住兩個(gè)或三個(gè)bug,第二天早上,或者在寫(xiě)代碼的高峰時(shí)期,就記不起它們了。你 絕對要正式地跟蹤bug。
但數據庫可以是復雜或簡(jiǎn)單的。一個(gè)最小限度的bug數據庫必須包含以下對每個(gè)bug的數據:
再次出現這個(gè)bug的完整步驟
預期的行為
觀(guān)察到的行為
它是被設計來(lái)干嘛的
它是否已被修復
如果bug跟蹤軟件的復雜性是讓你不想跟蹤你的bug的唯一理由,只用上面包含簡(jiǎn)單的5個(gè)元素的表格用在這些至關(guān)重要的領(lǐng)域,開(kāi)始使用它吧。
第 一個(gè)版本的Windows系統上的微軟Word被認為是一個(gè)“死亡行軍”項目。不知道這項目要什么時(shí)候才能完成,它不斷的延期。整個(gè)項目組在荒謬的時(shí)間里 工作著(zhù),項目再次、再次、再次延期,這時(shí)候的壓力的令人難以置信的。當討厭的事情最終出貨,幾年以后,微軟把這整個(gè)團隊都送到坎昆去度假了,他們可以靜下 來(lái)做些嚴重的自我反省了。
他 們意識到,項目經(jīng)理一直在堅持按照“日程安排”部署工作,而程序員們只是頭腦簡(jiǎn)單的趕緊完成敲代碼的過(guò)程,又因為修復bug階段并沒(méi)有成為正式日程安排的 一部分,這導致他們寫(xiě)出了及其惡劣的代碼。沒(méi)有能試圖保持住bug不發(fā)作的倒計時(shí)。恰恰相反,據說(shuō)一個(gè)程序員寫(xiě)了計算文本行高的代碼,僅僅寫(xiě)了 “renturn 12;”然后就開(kāi)始等待關(guān)于他的功能總是正確的bug報道。日程安排僅僅是即將變?yōu)閎ug的功能的檢查清單。事后,這個(gè)被稱(chēng)為“無(wú)窮大缺陷的方法”。
為 了解決這個(gè)問(wèn)題,微軟普遍地采取了一種叫做“零缺陷方法”的東西。公司的許多程序員都咯咯地笑,因為它聽(tīng)起來(lái)是一種好像通過(guò)行政法令就能夠減少bug數量 的管理思想。其實(shí),“零缺陷”意味著(zhù)在任意給定的時(shí)間內,優(yōu)先級最高的是消除bug,然后才是編寫(xiě)新代碼。讓我來(lái)講講為什么。
一般情況下,你等待修復bug的時(shí)間越長(cháng),這個(gè)bug就需要付出的代價(jià)就越大(在實(shí)踐和金錢(qián)上)。
比如,當你犯了一個(gè)編譯器能捕捉的拼寫(xiě)或語(yǔ)法錯誤時(shí),修復它的代價(jià)微不足道。當你第一時(shí)間看到你嘗試運行的代碼里有bug的時(shí)候,你能夠很快的把它解決掉,因為所以的代碼在你腦子里印象還很清楚。
如果你在幾天前的代碼里發(fā)現了bug,你會(huì )花費一段時(shí)間來(lái)找到它,但當你重讀先前寫(xiě)下的代碼后,你就會(huì )記起一切然后就能在一個(gè)合理的時(shí)間內修復這個(gè)bug。
但 如果你在幾個(gè)月前的代碼里發(fā)現了bug,你很可能把關(guān)于這段代碼的大部分東西都忘了,要修復它就很難了。這個(gè)時(shí)候你可能正在修復別人代碼里的bug,他們 可能會(huì )在阿魯巴島度假,這種情況下,修復bug就像科學(xué)一樣:你不得不放緩步調、有條不紊、細致地開(kāi)始工作,并且你還不能確定需要多長(cháng)時(shí)間才能找到問(wèn)題的 治療方法。
如果你在已經(jīng)售出的代碼中發(fā)現了bug,你會(huì )招致令人難以置信的代價(jià)修復它。
這 是要立刻修復bug的一個(gè)原因:因為這樣花費更少的時(shí)間。這關(guān)系到寫(xiě)新代碼之前而不是修復bug之前還要等多長(cháng)時(shí)間。比如,如果我要你預測寫(xiě)一個(gè)給列表排 序的代買(mǎi)要多長(cháng)時(shí)間,你可以給我一個(gè)很好的估計值。但如果我要你預測修復一個(gè)安裝Explorer 5.5版本后代碼就不能工作的bug需要多長(cháng)時(shí)間,你猜都猜不出來(lái),因為根本不知道到底什么導致了這個(gè)bug。它可能需要3天時(shí)間才能跟蹤到,或者僅僅3 分鐘就足夠了。
這句話(huà)的意思是,如果你有一個(gè)很多bug有待修復的日程安排,這個(gè)日程是不靠譜的。但如果你修復了所有已知的bug,并且所有剩下的都是新代碼,這樣你的日程安排才會(huì )更加驚人的精確。
關(guān)于把bug控制到零還有另一件重要的事,那就是你可以對競爭響應更快。一些程序員認為這點(diǎn)能讓產(chǎn)品在任何時(shí)候為發(fā)售準備好。如果你的競爭對手從你的客戶(hù)那里引入了一個(gè)殺手級的新功能,你就能在發(fā)售之前只實(shí)現這個(gè)功能,而不必去修復大量累計下來(lái)的bug。
這條測試把我們帶到了日程安排上來(lái)。如果你的代碼對生意是很重要的,會(huì )有很多知道代碼完成日期怎么對生意很重要的原因。程序員在制定日程安排上是出了名的倔?!霸撏瓿傻臅r(shí)候就完成了!”他們會(huì )這樣對商務(wù)人士尖叫。
不幸的是,這并沒(méi)有讓一切變得更好。在發(fā)售代碼之前,公司需要做太多的計劃好的決定:軟件演示,展會(huì ),廣告等。而要做到這一點(diǎn)的唯一方法就是擁有一個(gè)日程安排,并保證其為最新版本。
關(guān)于要有一個(gè)日程安排的另一個(gè)至關(guān)重要的原因是,它能強迫你決定要做哪些功能,然后迫使你挑選出最無(wú)關(guān)緊要的功能并砍掉它們,而不是陷入長(cháng)期的猶豫中去。
同時(shí),跟隨日程安排做事并不一定要很苛刻。
書(shū)寫(xiě)規范就像牙線(xiàn),每個(gè)人都同意這是一個(gè)很好的事情,但卻沒(méi)人做。
我不知道這是為什么,但很可能是因為大多數程序員討厭寫(xiě)文檔。結果,對一個(gè)大部分有程序員組成的團隊遇到了一個(gè)難題的時(shí)候,他們更傾向于用代碼來(lái)表達他們的解決辦法,而不是用文檔。他們寧愿埋頭寫(xiě)代碼而不是先寫(xiě)一份規范。
在 設計階段,當你發(fā)現問(wèn)題時(shí),你可以很容易地通過(guò)編輯幾行文本就修復它。一旦開(kāi)始寫(xiě)代碼,修復問(wèn)題的代價(jià)就大大地提高了,無(wú)論在感情上(人們討厭扔掉代碼) 還是在時(shí)間上,所以這時(shí)候修復問(wèn)題是有阻力的。不是從規范開(kāi)始建立起來(lái)的軟件通常會(huì )很糟糕地結束設計,并且日程安排會(huì )不受控。這個(gè)在Netscape好像 已經(jīng)成為大問(wèn)題了,Netscape的前四個(gè)版本慢慢變得一團糟,然后管理層愚蠢地決定拋棄舊代碼再重新開(kāi)始。然后他們又在Mozilla上再一次犯了這 個(gè)錯誤,創(chuàng )建了一個(gè)失控的怪物,并且浪費了好幾年時(shí)間才又回到初始階段。
我的一貫主張是,這問(wèn)題可以通過(guò)把程序員送去學(xué)習寫(xiě)作的集中課程,把他們變?yōu)椴畈欢嗟膶?xiě)手來(lái)解決。另一個(gè)方案是雇傭一些聰明的程序管理人員,讓他們來(lái)寫(xiě)代碼規范。在這兩種情況下,你應該執行簡(jiǎn)單的規則“無(wú)規范不出代碼”。
廣泛的記錄表明,通過(guò)給知識型員工提供空間、安靜和隱私就能提高生產(chǎn)力。經(jīng)典的軟件管理書(shū)《人件》就廣泛地記錄了生產(chǎn)力受益于這些方面。
問(wèn) 題來(lái)了。我們都知道知識型員工隨著(zhù)“靈感流動(dòng)”工作最好,就是我們所說(shuō)的“進(jìn)入狀態(tài)”,在哪里他們會(huì )全身心專(zhuān)注于他們的工作,并且完全脫離了周?chē)沫h(huán)境。 通過(guò)絕對的專(zhuān)注,他們忘記了時(shí)間,產(chǎn)生出偉大的代碼。這是他們把工作完成的過(guò)程。作家、程序員、科學(xué)家,甚至籃球運動(dòng)員都會(huì )告訴你要進(jìn)入狀態(tài)。
問(wèn)題是,進(jìn)入狀態(tài)并不那么容易。當你嘗試去考量它的時(shí)候,在最大生產(chǎn)力下好像需要15分鐘才能開(kāi)始工作。有時(shí),如果你累了或那天已做了很多創(chuàng )造性工作時(shí),你就是進(jìn)入不了狀態(tài),你會(huì )把這天剩下的時(shí)間都用來(lái)擺弄點(diǎn)什么,看看網(wǎng)頁(yè),或玩玩俄羅斯方塊。
另 一個(gè)問(wèn)題是,很容易脫離那個(gè)狀態(tài)。噪聲,來(lái)電話(huà),出去吃午飯,不得不開(kāi)5分鐘車(chē)去星巴克喝咖啡,還有被同事打擾--尤其是被同事打擾--都會(huì )把你從那個(gè)狀 態(tài)里拉出來(lái)。如果同事問(wèn)你問(wèn)題,導致了一分鐘的中斷,但這個(gè)會(huì )很悲慘地把你從狀態(tài)里脫離出來(lái),你的話(huà)費半個(gè)小時(shí)才能再次變的高效起來(lái),你的整體生產(chǎn)力會(huì )遇 到很大的麻煩。如果你在一個(gè)含咖啡因的網(wǎng)絡(luò )公司喜歡創(chuàng )造的嘈雜的牛棚一樣的環(huán)境里,有營(yíng)銷(xiāo)人員在程序員身邊尖叫著(zhù)打電話(huà),你的工作效率會(huì )大幅下跌,因為知 識型工作者一次又一次的被打斷,一直都進(jìn)入不了狀態(tài)。
對 程序員來(lái)說(shuō),這就更難了。工作效率依賴(lài)于能夠同時(shí)在短期記憶中兼顧很多小細節。任何類(lèi)型的打斷都會(huì )導致這些細節轟然倒下。當你重新開(kāi)始工作,你已經(jīng)記不起 任何細節(比如你剛才還在使用的本地變量名字,或你剛想出來(lái)的實(shí)施搜索算法的好點(diǎn)子)了,你不得不一直回想這些事情,這會(huì )讓你變得很慢,直到你重新變得高 效起來(lái)。
這 有一個(gè)簡(jiǎn)單的代數運算??梢赃@么說(shuō)(有證據暗示)如果我們打斷了一個(gè)程序員,即使只有一分鐘,我們真的會(huì )失去15分鐘的工作效率。在這個(gè)例子里,我們假設 有兩個(gè)程序員,Jeff和Mutt,在一個(gè)標準的相鄰開(kāi)放的格子間里。Mutt記不起strcpy函數的Unicode版本的名字。他可以查一查,這需要 30秒,或者他可以問(wèn)問(wèn)Jeff,這需要15秒。因為他就坐在Jeff旁邊,所以他選擇直接問(wèn)Jeff。Jeff被分心了,失去了15分鐘的工作效率(僅 僅節省了Mutt的15秒)。
現 在我們把他們兩個(gè)分到有門(mén)和墻隔開(kāi)的兩個(gè)辦公室去。這時(shí)如果Mutt忘記那個(gè)函數名,他可以花30秒去查一查,或者花45秒去問(wèn)問(wèn)Jeff,這過(guò)程包括了 站立起來(lái)(考慮到程序員的平均體能這并不是一項簡(jiǎn)單的任務(wù)?。?。所以他會(huì )選擇自己查一查。這樣Mutt失去了30秒的工作效率,但同時(shí)為Jeff節省了 15分鐘。哈哈哈哈!
在 公園里使用家用電腦立即用一門(mén)編譯語(yǔ)言寫(xiě)代碼仍然是最不能做的事情之一。如果你的編譯過(guò)程超過(guò)幾秒鐘,使用最新和性能最強的電腦會(huì )讓你節省點(diǎn)時(shí)間,當編譯 器運行的時(shí)候,程序員會(huì )感到厭倦,這是他們會(huì )切換到閱讀點(diǎn)別的書(shū)籍,這會(huì )吸引他們的注意力,失去好幾個(gè)小時(shí)的工作效率。
使用單個(gè)顯示器調試GUI代碼是很痛苦的,這也不是不可能。如果你在寫(xiě)GUI代碼,兩臺顯示器會(huì )讓很多事情變得更加容易。
大多數程序員最終要處理圖標或工具欄的位圖,但他們大多數都沒(méi)有一個(gè)好用的位圖編輯器。嘗試用Microsoft Paint來(lái)處理位圖是個(gè)笑話(huà),但這就是大部分程序員們所要做的。
在 我上一份工作中,系統管理員一直給我發(fā)自動(dòng)的垃圾郵件抱怨,說(shuō)我用了超過(guò)220兆字節的服務(wù)器上的硬盤(pán)存貯空間。我指出,鑒于最近硬盤(pán)的價(jià)格,這些硬盤(pán)空 間的成本比我使用的衛生紙的成本都低多了。甚至花費我10分鐘來(lái)清理我的郵件目錄,這真是對我工作效率的極為荒誕的浪費。
頂尖的開(kāi)發(fā)團隊不會(huì )折磨他們的程序員。即使是因為功能不完善的工具引起的小挫折累加起來(lái),也會(huì )使程序員脾氣暴躁和不愉快。一個(gè)脾氣暴躁的程序員是不會(huì )有工作效率的。
程序員最容易接受最酷、最新的東西賄賂了。與支付有競爭力的薪水比起來(lái),這是一種讓他們?yōu)槟愎ぷ鞲阋说姆绞健?/p>
如 果你的團隊沒(méi)有專(zhuān)門(mén)的測試人員,至少應該為兩三個(gè)程序員就配一個(gè)測試人員,你會(huì )寫(xiě)出有很多bug的產(chǎn)品,或者你在花冤枉錢(qián)讓測試人員30刀每小時(shí)就能做的 工作交給100刀每小時(shí)的程序員來(lái)做。在測試人員身上節省下來(lái)的錢(qián)是一個(gè)離譜的虛假的經(jīng)濟,我只是想讓更多的人認識到這一點(diǎn)。
你會(huì )雇傭一個(gè)沒(méi)看過(guò)他魔術(shù)技巧的魔術(shù)師么?當然不會(huì )。
你會(huì )雇傭一個(gè)沒(méi)嘗過(guò)他的食物的餐飲服務(wù)商來(lái)為你的婚禮服務(wù)么?我對此表示懷疑。
然 而,一天天的,程序員通過(guò)讓人印象深刻的簡(jiǎn)歷被雇用,或是因為面試者喜歡跟他們聊天?;蛘咚麄儽粏?wèn)到很細的問(wèn)題(“CreateDialog()和 DialogBox()之間有啥不同?”),這些看文檔就能回答了。你不關(guān)心他們是否記得關(guān)于編程的成千上萬(wàn)的細節,你只關(guān)心他們到底能不能寫(xiě)出代碼?;?者,更糟糕的是,他們被問(wèn)到的都是“???”問(wèn)題:就是那種你知道答案就看起來(lái)很簡(jiǎn)單,但如果不知道答案就什么也回答不上來(lái)的問(wèn)題。
拜托,以后不要這么干了。在面試期間你想怎么問(wèn)就怎么問(wèn),但一定要讓參加招聘的程序員寫(xiě)點(diǎn)代碼。
走廊可用性測試就是當你在走廊上遇到一個(gè)路人就強迫他試著(zhù)用你剛寫(xiě)的代碼。如果你對五個(gè)人做過(guò)這種事,你會(huì )學(xué)到你代碼里需要學(xué)習的95%的實(shí)用性問(wèn)題的答案。
好的用戶(hù)界面設計并不像你想的那么難,如果你想讓用戶(hù)喜歡并購買(mǎi)你的產(chǎn)品這就至關(guān)重要了。
但關(guān)于用戶(hù)界面最重要的事情是,如果你把你的程序展示給很多人看(實(shí)際上五六個(gè)就足夠了),你就會(huì )發(fā)現人們存在的最大的問(wèn)題。即使你的用戶(hù)界面設計技術(shù)還不怎么樣,只要你強迫自己去做走廊可用性測試,這并沒(méi)什么代價(jià),而你的用戶(hù)界面會(huì )越來(lái)越好的。(完)
(翻譯:PHP100_Alex)
原文:
http://www.joelonsoftware.com/articles/fog0000000043.html
聯(lián)系客服