2009年8月3日 星期一

儘早發表, 經常發表新版本 (Release Early, Release Often)

儘早, 經常發表新版本是 Linux 發展模式中非常重要的一環. 過去, 大部份的 程式發展者 (包括我) 認為這個策略對較大型的專案是不好的, 因為早期的版本 幾乎可以定義為多錯的版本, 我們並不想把使用者的耐心消磨殆盡.
這個過去的信念加強了軟體的發展要用建造教堂的方式的想法. 假如我們極欲 強調的目標是讓使用者在軟體中發現最少的錯誤, 那你何不每半年 (或更長) 才 發表一個新版本, 並且在發展新版本的期間, 賣力地除錯而累得像條狗似的. Emacs 的核心部分 (用 C 語言寫的) 就是用這種方式發展的, 但它的 Lisp 程式 庫就不是. 因為 Emacs 的 Lisp 資源庫不在自由軟體基金會的管轄內, 你可以在 其中找到新發展的 Lisp 程式使用, 而不受限於 Emacs 的發表週期.
在 Emacs 的 Lisp 程式庫中, 最重要的一個來源是俄亥俄州的 elisp 資源庫, 它先前的精神就已經具有今日大規模 Linux 資源庫的特色, 但當時我們之中卻 很少有人思考過我們到底做了什麼, 甚至想過我們已對自由軟體基金會的 ``建造 教堂'' 的發展模式提出質疑. 1992 年左右, 我很認真地要把俄亥俄州 elisp 資源庫中許多程式加入 Emacs 正式的 Lisp 程式庫中, 但卻遭遇到官方的阻礙 而失敗了.
但一年之後, Linux 已受到四方的矚目, 也帶來不同而且更健康的觀點, Linus 的開放性發展策略和 ``建造教堂'' 非常不同. 當時 Linux 的兩大資源庫 sunsite 和 tsx-11 正在萌芽, 有許多版本在交流著, Linux 核心系統發表新版本 的頻繁程度前所未有.
Linus 以最有效的方法, 視使用者為協同發展者:
[格言 7] 儘早, 經常發表新版本, 並且傾聽使用者的意見.
Release early. Release often. And listen to your customers.
Linus 的創新並不完全在此 (這在 UNIX 世界是行之有年的傳統了), 而在於提高 這個做法效力的層次, 使其能匹配他在發展的系統的複雜度. 早期在 1991 年左右 , 許多人都知道他一天內發表一次以上 Linux 核心程式旳新版本. 因為他善用網 際網路和協同發展者們合作更勝於其他人.
他能我也能嗎? 還是只有像他這樣的天才才辦得到?
我並不認為如此, 雖然 Linus 是一位很厲害的高手 (在我們之間, 有多少人能夠 完整地寫出一個具有商品品質的作業系統核心呢? ), 但 Linux 並不是一個空前 耀進的觀念, Linus 也並非 (或者說至少目前還不是) 如 Richard Stallman 或 James Cosling (NeWS 和 java 的創始者) 這樣的天才創新者, 而我個人認為他 是一位天才工程師, 他有避免程式錯誤及避免程式發展掉入死胡同的第六感, 和 找到兩點間最省力路徑的技巧. 事實上, 整個 Linux 的設計中, 我們可以看到 Linus 表現出的品質和他保守而簡單的設計取向.
承上所說, 如果快速地發表新版本和徹底地善用網際網路媒介不是突然冒出, 而是 以 Linus 天才工程師洞見所得的最省力路徑, 那麼他把網際網路的什麼功用發揮 到最大?
其實問題的本身已反應出答案, Linus 讓 Linux 的高手和使用者們經常感覺刺激 和有收穫 -- 感覺刺激是因協助發展 Linux 得到自我滿足, 感覺有收獲是因經常 (甚至每天) 進步的 Linux 幫助他們把工作做得更好.
Linus 想直接將投入除錯和發展的 ``人-時'' (person-hours) 數加到最大, 即使要付出的代價是程式碼的不穩定, 或是因一些程式錯誤被證實無法追蹤而 嚇走原有的使用者. Linus 會如此做是因為他相信:
[格言 8] 以足夠多的 ``beta 版'' 測試者和協同發展者做基礎, 幾乎程式 中的每一個問題都可以很快地找出來, 並且對某些人而言, 針對發現的問題的解決方法是顯而易見的.
8. Given a large enough beta-tester and co-developer base, almost every problem will be characterized quickly and the fix obvious to someone.
或者用比較不那麼正式的說法: ``足夠多的人來看程式, 所有的錯誤都變得淺顯'', 我將此命名為 ``Linus 定律''.
我原本先前的論述是: ``某些問題對某些人而言是容易解決的'', 但 Linus 有不同的意見: ``瞭解並解決問題的人不一定是第一個發現問題的人'', 他說: ``有些人發現問題, 有些人解決問題, 我願正式強調 -- 發現問題是 較大的挑戰. '' 而在 Linux 的世界, 發現問題和解決問題的速度都很快.
我想這就是教堂模式和市集模式最主要的不同, 以教堂建造者的觀點來看程式 發展, 程式錯誤和相關問題難以處理, 並隱伏在深處, 需要數個月的工夫仔細察看 來找到它們, 而這對程式發展者的自信少有加許. 發展的期間越長, 一旦經冗長等 待的新版本發表後不如預期完美, 使用者的失望也越大.
另一方面就市集發展模式的觀點來看, 它假設程式錯誤都是顯而易見的, 或者說 至少在上千位渴望新版的協同發展者面前, 程式錯誤很快地都變得淺顯, 因此經常 發表新版本是為了獲得更多的指正, 以及避免偶爾笨拙的修補.
以上已說明足夠 ``Linus 定律''. 如果 ``Linus 定律'' 是假的, 那麼任何像 Linux 核心程式這樣複雜的系統, 並且擁有像 Linux 核心程式這麼多的高手 在發展, 早就因溝通不良及未被發現的程式錯誤而崩塌. 反過來說如果 ``Linus 定律'' 是真的, 那正可解釋為什麼相對地 Linux 比較沒有程式錯誤.
也許 Linus 定律並不是一個驚奇, 社會學家多年前發現到在一群素質相同的觀察 家中, 他們共同做出的預測要比其中任一位單獨所做的要來得可信. 這被稱為 ``Delphi 效應''. 可見 Linus 只是把 ``Delphi 效應'' 用在發展作業系統時 對程式的除錯上, 所以 ``Delphi 效應'' 能夠克服發展系統的複雜度, 即使複雜如作業系統核心.
[譯注] Delphi 是希臘古都, 以善作預言的 Apollo 神殿而聞名.
我在此要感謝 Jeff Dutky dutky@wam.umd.edu, 他指出 ``Linus 定律'' 亦可稱 之為 ``程式除錯可併行處理''. Jeff 觀察到多位程式除錯者在工作時需要和一些 程式發展者溝通協調, 但是程式除錯者彼此間卻不需如此. 所以增加程式除錯者 並不會像增加程式發展者那樣, 多出平方倍的複雜度和管理成本.
理論上造成程式除錯效率減低的原因是多位除錯者重複同一件工作, 就實際的情形 而言, 在 Linux 的世界中幾乎不會發生這樣的狀況. ``儘早, 經常發表新版本'' 這個策略使得程式錯誤的修補回饋得很快, 藉此將除錯者重複同一件工作 的機會減至最低.
Brooks 曾發表過一個即席的看法, 和 Jeff 的看法相關: ``維護一個廣為人用 的程式的總成本通常是發展這個程式成本的百分之四十或更多, 令人訝異的是 這維護成本深受使用者人數的影響, 越多的使用者發現越多的程式錯誤.'' (這正是我所要強調的)
因為增加越多的使用者, 就會增加考驗程式的方法, 所以使用者越多, 發現的程式 錯誤也越多, 當使用者也是協同發展者時這種效應會再被放大, 每一位使用者以不 同的直覺 , 不同的分析工具, 和不同的角度來標明程式錯誤, 因為這些不同, ``Delphi 效應''似乎真的有作用了, 在個別情況下的除錯工作, 也因這些不同而 減少重複出力的可能.
所以, 以程式發展者的眼光看來, 增加更多的 beta 版測試者也許不會減少目前藏 在深處的程式錯誤的複雜度, 但可以增加某位除錯者以他的工具程式找到這個程式 錯誤的機會, 而這個程式錯誤對這位除錯者來說是淺顯的.
Linus 也在這種方式上下了賭注. 因為程式都會有錯誤, Linux 核心程式 以一種特別的方式來定出版本號碼, 讓使用者可以選擇要用上一個比較穩定的版本 , 還是選擇錯誤風險比較高的新版來使用新功能. 這個策略尚未正式為大部分的 Linux 高手所採行, 但是它也顯示出一個事實, 就是使用者可做選擇使得這兩種版 本都更有吸引力.

沒有留言:

張貼留言

推到 Twitter!
推到 Plurk!
推到 Facebook!