跳轉到

1968 - NATO 軟體工程會議:「軟體工程」的誕生#

案件摘要#

1968 年 10 月,北約(NATO)科學委員會在西德 Garmisch 召開了一場只有約 50 人的工作會議。 與會者面對的是同一個控訴:軟體失控了——IBM OS/360 延期、專案超支、bug 泛濫。 會議的結論只有一個詞,卻改寫了此後五十年的行業:「engineering」—— 把軟體從個人手工藝,變成一门有理論、有流程、有品質保證的工程學科。 這是「軟體工程(software engineering)」一詞的正式誕生現場。

前因 -- 為什麼會有這個案子#

  • 1960 年代的軟體危機:硬體靠摩爾定律每 18–24 個月性能倍增、價格減半, 軟體卻反其道而行——IBM OS/360(見「1964-IBMSystem360.md」)第一版拖了數年、 每個版本修正 1000+ 個 bug、預算超支數倍;隔年(1967)IBM 開發 FMS 大型 OS 案直接取消,損失逾 $5000 萬。
  • 對比的失控曲線:硬體成本 \(C_{hw}(t) \sim r^{-t}\) ( \(r \approx 2\) ,每兩年減半), 軟體成本卻隨系統規模超線性成長:
\[ C_{sw}(S) \sim S^{1.3\text{–}1.5} \quad\Longrightarrow\quad \text{系統加倍,成本不止加倍。} \]
  • 專案失敗成常態:SAGE(1958)的軟體維護費超過硬體;GE、Honeywell、 美國空軍的專案屢屢延期或交付即報廢——沒有人能預估軟體要多久、多少錢。
  • 「craft」的罩門:寫程式靠個人天賦,沒有可複製的方法——一個天才離職,專案就斷線。
  • 關鍵推理:NATO 科學委員會(主持者 Peter Naur、Fritz Bauer、Brian Randell) 從土木與機械工程借來「engineering」一詞,其用意是宣告:
\[ \text{軟體} = \underbrace{\text{需求}}_{\text{spec}} + \underbrace{\text{設計}}_{\text{design}} + \underbrace{\text{實作}}_{\text{code}} + \underbrace{\text{測試}}_{\text{test}} + \underbrace{\text{維護}}_{\text{maintain}} \quad\text{而非「寫程式」一個動作。} \]

線索與推理 -- 數學式、程式、理論#

第一條線索:bug 修復成本的指數上升#

軟體界最經典的經驗律:同一個 bug,被發現得越晚,修復成本越高, 且以數量級的方式上升——每跨一個階段,成本約乘以 10:

\[ C(k) = C_0 \cdot 10^{k}, \qquad k = \text{發現階段(0=需求, 1=設計, 2=編碼, 3=測試, 4=上線)} \]
  • 為什麼是 \(O(10^k)\) ? 需求階段的 bug 只需改一頁文件;編碼階段要改程式、重編、重測; 測試階段要動員整個團隊回歸;上線之後則要發補丁、召回、承擔商譽與法律賠償—— 影響面每跨一個階段呈十倍級擴大。
  • Barry Boehm 的實測(1981, Software Engineering Economics):在 TRW 的資料中, 需求階段修一個 bug 約 \(1\) 單位,上線後則為 \(100\text{–}1000\) 單位。
  • 推論:品質不是測出來的,是前段階段保證出來的—— 需求審查(review)比多寫十倍測試便宜,這成為「軟體品質保證(SQA)」的數學基礎。

第二條線索:人力與生產力的非線性(Brooks 定律前兆)#

直覺:任務量 \(W\) 人月, \(n\) 人做,工期 \(T = W/n\) ——線性可互換。 現實: \(n\) 人之間的溝通路徑為 \(\frac{n(n-1)}{2}\) 條,生產力打折:

\[ T = \frac{W}{n \cdot \eta(n)} + \tau \cdot \frac{n(n-1)}{2}, \qquad \eta(n) = \frac{1}{1 + c\,(n-1)} \]
  • \(\tau\) :每次溝通的平均耗損(人月); \(c\) :溝通摩擦係數。
  • \(n\) 越大, \(\eta(n)\) 越小——加人不只攤薄產出,還新增溝通負債。
  • 這正是 Fred Brooks(360 專案經理,見「1975-神話人月.md」)在 360 開發中親身經歷的現象, 1968 年會議上被當作軟體危機的證詞提出,1975 年才正式成為 Brooks's Law。

第三條線索:軟體成本在總系統成本中的佔比反轉#

1950 年代:硬體 >> 軟體(軟體常是隨機附贈)。 1960 年代末:曲線交叉——

\[ \frac{C_{sw}}{C_{sw} + C_{hw}} \;\xrightarrow{\;1960s\text{–}80s\;}\; 50\% \to 80\%+ \]
  • Bauer 的判詞:整個產業的重心正在從「造機器」移向「造軟體」, 但行業的方法論還停留在手工藝時代——這就是危機的本質。
  • 這條交叉曲線今天仍在延續:現在軟體佔系統成本 90%+, 摩爾定律只照顧硬體,軟體只能靠工程方法自救。

第四條線索:Garmisch 的結論——軟體生產的五道工序與兩大支柱#

會議並沒有提出任何新演算法——它的產物是一份診斷書與一張處方箋:

工序 內容 1968 年的現狀
需求 規格化、與客戶確認 幾乎不存在,直接開工
設計 架構與模組劃分 憑直覺,無文件
實作 編碼 唯一被重視的環節
測試 驗證與確認 混在編碼裡,常被省略
維護 修正與演化 佔成本 60%+ 卻無人規劃
  • 兩大支柱:與會者總結,軟體生產需要—— (1)方法:可複製的設計與管理流程,取代個人手工藝; (2)教育:大學必須開出軟體工程課程,培養「會工程」的程式設計師。
  • Bauer 的會議定義(日後被反覆引用):

    「軟體工程是建立並使用健全的工程原則(經濟學意義上的), 以經濟地獲得可靠的、且在真實機器上有效運作的軟體。」 三個關鍵詞——經濟、可靠、真實——把軟體從數學遊戲拉回工程現實。

  • 兩年後的續集:1969 年 NATO 在羅馬召開第二次會議(Software Engineering Techniques), 討論焦點從「危機是什麼」轉向「技術怎麼做」——學科的動線就此鋪設。

Python 實作:bug 修復成本模擬#

# 各階段發現 bug 的修復成本:C(k) = C0 * 10^k
# 需求(0) -> 設計(1) -> 編碼(2) -> 測試(3) -> 上線(4)

STAGES = ["需求", "設計", "編碼", "測試", "上線"]
C0 = 1.0                                          # 需求階段修一個 bug 的基準成本(人時)

def fix_cost(stage_index, bugs=1):
    return C0 * (10 ** stage_index) * bugs

# 同樣 10 個 bug,分別在「全部早期發現」vs「全部上線才發現」
early = fix_cost(0, bugs=10)                      # 需求階段就抓到
late  = fix_cost(4, bugs=10)                      # 上線後才爆發
print(f"10 個 bug 在需求階段修好:{early:.0f} 人時")
print(f"10 個 bug 在上線階段修好:{late:.0f} 人時")
print(f"成本比:{late / early:.0f} 倍")

# 各階段逐項列出
for i, s in enumerate(STAGES):
    print(f"階段 {i}({s}):{fix_cost(i, 10):>8.0f} 人時")
# 10 個 bug 在需求階段修好:10 人時
# 10 個 bug 在上線階段修好:100000 人時
# 成本比:10000 倍
# 階段 0(需求):      10 人時 / 階段 1(設計):     100 人時
# 階段 2(編碼):    1000 人時 / 階段 3(測試):   10000 人時
# 階段 4(上線):  100000 人時

結案 -- 後果與影響#

  • 學科誕生:「軟體工程」從此成為大學科系、研究領域與職業稱謂; IEEE 與 ACM 後續制定 SWEBOK(軟體工程知識體系)。
  • 方法學的源頭:Garmisch 會議確立「需求、設計、實作、測試、維護」的分工—— 1970 年 Royce 的瀑布模型(見「1970-Waterfall瀑布模型.md」)、 以及 2001 年的敏捷宣言,都是對這個分工的不同回答。
  • 品質意識:code review、測試先行、需求審查——「愈早抓 bug 愈便宜」成為行業共識, 這是品質保證(SQA)與 CMM/CMMI 認證體系的遠因。
  • 工具鏈的遠因:版本控制(SCCS 1972、RCS、Git)、單元測試、CI/CD—— 目的都是把「手工藝」變成「可重複的工程流程」——Garmisch 的遺願。
  • 危機從未結案:1994 年 Standish CHAOS 報告仍指出逾半數專案延期或失敗—— 軟體工程是一場永遠在追趕的學科。
  • 會議精神的當代回聲:AI 輔助程式設計(2020s)再度引發同樣的辯論—— 「寫程式變快了,但工程(需求、設計、驗證)跟上了嗎?」 Garmisch 的問題在六十年後仍是同一個。

關鍵人物與文獻#

  • Fritz Bauer(慕尼黑工大):會議共同主席,給出「軟體工程」的經典定義 ——「建立並使用健全的工程原則,以經濟地獲得可靠且在真實機器上運作的軟體」。
  • Peter Naur(哥本哈根,Algol 60 作者之一)、Brian Randell(Newcastle): 會議報告編輯者;Naur 後續提出 Programming as Theory Building(1985)。
  • Fred Brooks(IBM):以 OS/360 的慘痛經驗為軟體危機提供第一手證詞 ——見「1964-IBMSystem360.md」與「1975-神話人月.md」。
  • Barry Boehm(TRW/USC):《Software Engineering Economics》(1981) ——bug 成本 \(O(10^k)\) 與 COCOMO 估算模型的作者。
  • 文獻:P. Naur & B. Randell (eds.), Software Engineering: Report on a Conference sponsored by the NATO Science Committee, Garmisch, Germany, 1968——「軟體工程」的出生證明。
  • 相關案件:1964-IBMSystem360.md、1970-Waterfall瀑布模型.md、1975-神話人月.md。