搜尋此網誌

2009年9月6日 星期日

[個人意見] 問題的問題 (四之一)

在我自己軟體與資安產品開發的工作經驗中,經常需要解決所謂的”問題”。雖然問題種類有各種形式,但是在面對這類問題時通常都有一定的方法可以遵守。很可惜的是,大部分的人都憑著直覺在解決問題,而直覺很多時候其實也並不是那麼直覺。甚至有人說,解決問題是一門藝術。真的是如此嗎?不只在工作上,其實在日常生活中我們也常常需要面對問題、解決問題。一個看似簡單的動作,往往卻存在了很多必須小心應付的陷阱。稍有不慎,輕則問題依舊,重則問題一發不可收拾。

以我個人從事軟體開發的經驗而言,因為軟體是大多數使用者接觸系統的”介面”,所以通常一遇到問題就認為是軟體的問題。更不幸的是,程式設計師通常又是軟體的最直接關係人,所以問題不用考慮就是丟到程式設計師的身上。而此時,程式設計師就必須具備良好的問題分析能力,才能將問題的責任歸屬釐清,甚至是解決問題。此外因為軟體是架構在硬體、作業系統、相關協定(如網路協定)之上,如果對這些底層的技術沒有一定的了解,往往除了啞巴吃黃蓮外,更無法解決問題。

這件事跟資安有甚麼關係?因為資安的問題,通常更為複雜。除了與各式各樣不同的技術及系統緊緊相依外,更是牽扯到各個不同的團體,而人永遠是最難處理的一環。所以如何能夠有效地解決資安問題,是一項相當嚴厲的挑戰。如果不能有效的釐清問題並訂定出可行的解決方案,有再好技術、再好的產品也是枉然。所以在接下來的幾篇文章中,我想要談談我對於解決問題的一些想法。

在討論如何解決問題之前,我們先對”問題”本身做個簡單的分類,其中包含邏輯性的問題與非邏輯性的問題兩類。邏輯性問題包含工程問題、系統問題、軟體問題等。非邏輯性問題則包含親子關係、人際關係、政治等。因為兩者本質上有很大的不同,所以處理方式也不一樣。例如當一個家庭裡有一個小孩循規蹈矩、但是另一個小孩卻作姦犯科,如果硬要用科學的方式加以解釋,很多時候只是牽強附會罷了。而我在此討論的問題比較偏向於邏輯性的問題。為何說比較偏向,因為很多邏輯性的問題背後都跟非邏輯性問題有所牽扯。這個議題我們會在第三篇文章中看到。

通常我們可以將解決問題分成三個階段,第一個階段是觀察問題,第二個階段是找出問題發生的原因,第三個階段是解決問題。雖說是解決問題,其實我們大部分能做的是解決問題發生的原因,而不是解決問題,因為問題往往只是一個表現出來的現象。嚴格來說,比較好的作法還包含了第四個階段,那就是如何預防類似的問題再發生。而有些時候,我們也可以把第三個階段跟第四個階段合併一起處理。不論如何,基本的原則都一樣,所以我們就以三個階段來看即可。

第一個階段(觀察問題)其實是最重要的一環,卻往往也是最容易被忽視的一個動作。透過仔細觀察問題的過程,不但可以更了解問題,也可能可以據此找出問題發生的原因。而且,唯有實際觀察過問題的發生,才有辦法在日後確認問題已被解決。

在第二個階段(找出問題發生的原因)可能發生的情況有下列幾種:

  1. 完全跳過。
  2. 天馬行空的想像。
  3. 天馬行空的想像,並想辦法證明之。
  4. 根據過去的經驗加以猜測。
  5. 根據過去的經驗加以猜測,並想辦法證明之。
  6. 尋求其他人或資源的協助。
  7. 尋求其他人或資源的協助,並想辦法證明之。
  8. 第2種+第4種+第6種。
  9. 第3種+第5種+第7種。

如果在此一階段,你是屬於第1或第2種人,那麼我的建議是這篇文章並不適合你,你可以把時間省下來去做更有趣的事情。原因很簡單,因為在前面我提到其實我們能解決的是問題的發生原因,而不是問題本身。所以如果連原因都不知道,一切就只能憑運氣了。

第9種算是比較嚴謹的作法,首先透過自己的經驗與其他人或資源的協助,找出可能的原因。如果這樣的方式還是無法找到,有時候就只得靠天馬行空的想像力,去找到可能的原因。重點在於,不管如何找到可能的原因,都必須想辦法加以證明。沒有證明就貿然進行下一階段,屆時可能因為猜測錯誤而白費工。唯有透過實際的觀察,問題與原因之間才能有比較明確的關聯性。能夠這樣做的人,老實說是少之又少,倒是第1種與第2種還為數不少。所以很多時候,看到有些問題處理了很久卻沒有任何進展,直到新的問題產生,原先的問題自然而然就被大家淡忘了(這也是一種解決問題的方法,而且似乎是政治人物的最愛)。

當在第二個階段找到可能的原因後,接下來就要開始動手解決了。因為通常每個原因都有不只一個解法,所以這時候又有幾種可能性:

  1. 隨便找一個解法下手。
  2. 找最熟悉的解法下手。
  3. 找最簡單的解法下手。
  4. 找最有效果的解法下手。
  5. 評估一個最有效率的解法下手。

關於第5點需要再做進一步的說明。因為問題本身有不同的解法,而每個解法所能得到的效果卻不一樣,所以如果考慮到所需資源與效果這兩個因素的交互作用,在大部分的情況下我們希望採取效果與所需資源比例較高的解法,這個概念類似盡量選購C/P值高的產品。這樣的評估方式可能是透過定量分析的方式,更多的情況則是透過定性分析決定的。

但是有時候,我們為了盡快”解決”問題會採取一些 Quick Fix,通常也就是上述的第3點。Quick Fix 的風險是,問題往往並沒有被真正的解決,甚至會帶來新的問題。所以當(不得不)採用 Quick Fix 時必須更加注意對原有事物所帶來的(負面)影響,而且必須搭配後續的正規解法,以便徹底解決問題。

不管採用哪一個解法,都必須注意的原則就是必須確保問題已被確實解決。同樣地,這必須透過實際的觀察,而不是假設。這也是為什麼在第一個階段必須實際觀察問題的原因之一,因為這樣才有辦法明確地比對解法實施前後的差異性,以確保問題已被解決並且沒有產生不良的副作用。

針對一般的邏輯性問題(如修改程式的臭蟲),運用以上的原則應該可以解決絕大部分的問題。其他不能解決的問題,通常不是因為”靈異現象”作祟,更不是因為七月半忘了拜拜,而是你還沒有找到問題發生的點。Debugging 這本書對如何分析此類問題有相當詳盡的解說, 推薦各位加以參考。

在下一篇文章中,我們來看看當問題背後還有問題時(Question behind Question),我們該怎麼解決問題。

About