找不出系統的錯誤

如何利用科學方法來除錯

Laurence Chen
Aug 14, 2021

不知道你有沒有類似如下的經驗:

  1. 你需要使用某個 command line 的指令,你明明曾經成功地使用過,甚至有寫下筆記。但是,照著筆記去使用,無論如何,卻不管用。然後,用指令的名稱,卯起來去查 stackoverflow.com ,查到了一堆資料,卻沒有任何一個真的能協助你前進。
  2. 你的工作在業務部,公司的產品給客戶用,客戶回報有問題。但是,客戶的回報時使用的文字是客戶覺得自然的用語。原文複製貼上,拿去問產品部。產品部則回覆,『公司的產品沒有錯誤』。你夾在兩者之間,不知該如何是好?
  3. 你需要使用某個複雜的工具,比方說,需要操作 15 個步驟。但是,照著步驟做了,但是,出來的結果不對。下一步該怎麼辦呢?

上述的困難,是系統的使用者在使用自己不熟悉的系統常遭遇到的困難,無論該系統是指令、軟體產品、或是某個複雜的工具。我曾經擔任過系統的設計者、也常常是系統的使用者,對於這種情況,有很深刻的感受。我認為,想要協助別人順利使用系統,或是想要自助的人,需要去了解「如何除錯」。

如何除錯

除錯這件事的核心,非常近似於「否証方法派的科學方法」:

科學家想要解釋特定的現象時,會對某個現象提出假說,然後做實驗,看是否可以証明該假說為真、或是証明為偽。觀察實驗的結果,進而去修改假說。 經過數輪的反覆之後,該假說的許多不完美之處逐步被修正,成為了可以解釋現象的理論。除錯這件事極為相似。想要抓出系統的錯誤,可以套用科學方法,而假說就是「錯誤的所在」。

科學方法應該是現代教育的基礎之一,畢竟我們從國小就開始上實驗課。然而實務上,我在協助客戶除錯時,卻發現,如果只解釋完科學方法就期待學習者會除錯的話,得到的成效,往往極差無比。

前述的科學方法,大致上可以拆分成幾個步驟:

  1. 假設
  2. 實驗
  3. 觀察
  4. 根據結果修正

而我觀察,使用科學方法來除錯,做得不成功的,大致上也可以歸納成幾種形式:

  • 不會做實驗
  • 不會做假設、沒有合適的量測工具

不會做實驗

要做對「實驗」,需要「控制變因」,換言之,要觀察實驗的結果之前,要確認自己這一次的實驗只改動一件事。說成一件事,其實有點抽象,因為有時候,步驟的操作,有其依賴關系,步驟一改了,步驟三、四、五都必須同時修改,才會合理。

實驗應該是要基於「驗証假設」而做的。我看過的許多失敗案例是這樣子:「要除錯的人,並沒有仔細思考,自己為什麼要做這個實驗,心裡想的就是:應該是這邊吧,然後就一次改動操作步驟的三個地方」。然而,事後檢討,為什麼會抓不出問題,因為一次改動的三個地方,每一個地方的改動,其實都隱含了不同的假設。換言之,失敗的原因是一次企圖驗証三個不同的假設,恰好違反了「控制變因」的精神。

不會做假設、沒有合適的量測工具

做假設時,有個需要思考的面向:「系統之內的錯誤往往與外在世界的異常有其對應關系。」

我們除錯時,往往需要反復做『假設、驗証假設、觀察』這樣子的步驟來定位問題之所在。我們可以刻意對系統內部的特定環節做假設、也可以對系統存在的外在世界做假設,來開始除錯的流程。我的經驗是,「由於外在世界的可能性太多了,通常要從系統內部開始做假設,才能有效地去定位問題。」

我大學的時候,曾經做過電路學實驗。我在麵包板上,照著電路圖,把主動元件、被動元件都放上之後,輸出的電壓卻不正確。我做的假設是,可能是我使用的麵包板的某處壞掉,或是某個電阻壞了,而由於覺得要一一驗証,似乎成本過高,於是我考慮拿一個新的板子,整個重做。而助教做的假設,則認為電路裡某一段的電壓很可能也沒有正確,於是,他用三用電表量測了幾個關鍵的點,迅速地定位電路中的一小部分與規畫不合,讓我針對那個小部分的電路去修正。而我接受了助教的意見之後,也很快地找到了某個壞掉的電阻。

在上述的例子裡,昔日的我,做假設的時候,重點並不是將電路視為一個系統,思考系統之內的互動關系,而是把重點放在系統存在的物理世界中可能發生的錯誤。助教做假設的方式,則是把重點放在電路的系統之內,一環與一環的互動關系,此外,而助教應用了三用電錶做為量測工具。

總結

我在協助客戶除錯時,往往在建議客戶利用,合適的「量測系統內部狀態的工具」之後,取得了極大的進展。客戶問我,「為什麼要這樣子做?」我講了上頭一大串,客戶一臉茫然,我想了一下,換個說法:「如果你的車有點異常,而修車師傅聽完汽車發出的怪聲之後,就立刻定位問題,這個故事聽起來有點熟悉嗎?」

--

--

Laurence Chen

IT 顧問、講者、作家。喜歡快速迭代 (fast iteration) 與提高產出。 著作:「從錯誤到創新」 https://leanpub.com/errors_to_innovation/ 網站:https://replware.dev/