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