通過心理學知識提高問題定位與解決能力(上)

本文由本人首次發佈在infoq中文站上:http://www.infoq.com/cn/articles/improve-problem-solve-ability-by-psychology-knowledge-part01。轉載請註明作者: 黃文海 出處:http://viscent.iteye.com

 

前言

軟件開發工作無論是從宏觀還是微觀上看,都可以看作一個問題解決的過程。從宏觀上看,軟件開發,簡單來說,就是弄清楚客戶的需求是什麼,然後通過分析、設計、編碼和測試等一系列活動解決如何將需求轉換爲代碼的問題。從微觀上看,開發人員的日常工作中也面臨各式各樣的問題。比如,用於調試代碼的Web服務器突然啓動不了,開發人員必須先解決這個問題,否則手頭上的工作可能無法進展。

作爲開發人員,與其抱怨加班,不如去反思下自己的時間都去哪裏了。我相信開發人員的大部分時間都花在解決各種各樣的問題上了。不管是資深的開發者、還是新手,在日常的工作中都會遇到各式各樣的問題。所不同的是,資深開發者可以在幾秒內解決的問題,新手卻可能要花上幾個小時,甚至一兩天的時間!可見,提高開發者的問題解決能力,無論對於個人還是對於團隊,都有着重要的意義。

其實,心理學作爲一門獨立的學科,對於問題解決有其專門的研究。其研究成果值得我們借鑑,以提高我們自身以及團隊中的其它成員的問題解決能力。本文將爲讀者介紹心理學關於問題解決方面的知識,並結合軟件開發工作的特點給出提高問題解決能力的相關指導意見。沒有心理學背景的讀者,也不必擔心“隔行如隔山”,本文所涉及到的一些心理學術語,大多都是淺顯易懂的。

重新審視什麼是“問題”

提高問題解決能力,首先要弄清楚究竟什麼是“問題”,然後才能談如何更有效率地去解決問題。

心理學將“問題”定義爲“給定信息和目標之間有某些障礙需要被克服的刺激情境”。通俗的理解就是,對於給定的事物的初始狀態(所謂“給定信息”)和目標狀態,我們不清楚如何將初始狀態轉換爲目標狀態(所謂“障礙”),“問題”就產生了。例如,著名的梵諾塔問題,其初始狀態是64個盤子在A杆,目標狀態是所有盤子在C杆,並且每個小盤都在大盤之上。所存在的需要被克服的“障礙”就是如何將64個盤子從A處移動到C杆。

圖 1. 梵諾塔問題

 

按照上述定義,解決問題就是克服“障礙”的過程,即尋找到一條從初始狀態通往目標狀態的通路的過程。如梵諾塔問題中,我們反覆藉助B杆,最終將A杆上的所有盤子“原封不動”地移動到C杆的過程就是問題解決的過程。

那麼,提高問題解決的能力就是提高我們找到一條從初始狀態通往目標狀態的路徑的能力。

爲了下文討論方便,這裏簡單地將軟件開發領域的“問題”劃分爲界定清晰的問題(Well-defined problem)和界定含糊的問題(Ill-defined problem)。前者指初始狀態和目標狀態都很清楚的問題,如梵諾塔問題。後者指初始狀態、目標狀態或者二者都很模糊的問題,這類問題往往更難解決,對問題解決者的要求也更高。與軟件運維有關的問題多屬於這類問題。比如這樣一個問題:某個生產環境上的數據庫系統自動重啓,需要查明其原因。

解決問題的心理過程

就像瞭解計算機處理信息的原理有助於我們更好地使用計算機,瞭解人類解決問題的過程有助於我們更好地解決問題。

心理學家一般把問題解決的過程分解爲問題表徵、設計解題計劃、執行解題計劃和監控這四個步驟。

問題表徵指明確問題的初始狀態、目標狀態和允許的操作和必須滿足的限制。梵諾塔問題中,問題解決者首先對問題進行表徵,即弄清楚:64個盤子在A杆上,小的盤子在大的盤子上面(初始狀態)、目標是將這64個盤子移動到C杆上,C杆上的每個盤子仍然保持小盤在上,大盤在下(目標狀態)、移動過程中可以藉助B杆,但是移動過程中保證小盤始終在大盤上面(允許的操作和必須滿足的限制)。

設計解題計劃指確定解題的步驟。梵諾塔問題的問題解決者通過比較問題的初始狀態和目標狀態,準備藉助B杆遞歸地將A杆的所有盤子逐步地移動到C杆,就是設計解題計劃。

問題解決者設計好解題計劃後,就執行解題計劃,並在執行過程中時刻進行自我檢查當前的操作是否有助於解決問題、相關操作是否滿足問題的限制,即執行監控。如梵諾塔問題的問題解決者在移動盤子過程中要注意小的盤子是否在大的盤子上面,移動盤子的結果是否如事先預期的那樣能夠使越來越多的盤子放在了C杆上。

下面我們討論,影響問題解決的心理因素。

影響問題解決的心理因素

問題的表徵方式

問題解決的第一個步驟中的問題表徵,還可以再分爲兩個小步驟:問題表層理解和深層理解。

問題表層理解就是將問題用問題解決者自身的語言來描述的過程,這是解決問題的最基礎的一步。問題的深層理解是在問題表層理解的基礎上,進一步把問題的每一陳述綜合成條件和目標的統一體。這一子步驟中,非常重要的一點是區分問題中有關的信息和無關的信息。對於無關的信息,可以忽略之,也可以採用不同的方式去理解和表示之(即表徵)。

在問題深層理解的過程中,問題的表徵採用的方式不同對問題的解決難度可能有很大的影響。這點,可以從典型的一個問題——和尚上山問題(見左邊側欄)反映出來。

和尚上山問題給人的直覺的反映是似乎不大可能存在這樣一個點,因爲和尚上下山的速度不一樣。然而,當我們發現這個問題可以看作這樣一個問題時:兩個和尚在同一時間點,沿着同一條山路,一個下山,另一個上山,答案就非常直白:這條山路上必然存在一個點,在某一時刻這兩個和尚會相遇。那麼,原問題的答案也是肯定的。這個問題的解決中關鍵的一步是,在對問題進行深層理解的過程中,我們採用與問題表層理解中不同的方式來表徵問題:表層理解中問題描述的是同一個和尚上下山,而深層理解時我們發現是否是一個和尚上下山是一個“無關”的信息,我們可以將這個信息理解成兩個和尚同時上下山。

 

下面看一個軟件開發中的實際例子:我們要對網頁上的一個表示文章關鍵字列表的字段的值進行合法性校驗。校驗的規則是該字段的值不能爲空,若字段值不爲空,則多個關鍵字間用英文分號分隔。例如:“keyword1;keyword2;keyword3”。顯然,這個可以用正則表達式來校驗。問題就轉化爲這個正則表達怎麼寫。按照問題的表層理解(如上面文字的描述),關鍵字列表的字段值的格式會被表徵爲:

(關鍵字1)+;+(關鍵字2)+;+(關鍵字3)+...

這樣的表徵固然直白簡單,但依照這個表徵,相應的校驗正則表達式不是那麼容易寫。相反,如果把字段值的格式換作另外一種表徵,相應的正則表達式就容易寫得多:

(關鍵字1)+(;關鍵字2)+(;關鍵字3)+ ...

依照上述表徵(即從第二個關鍵字開始,每個關鍵字都需要以";"爲前綴),可以得出相應的正則表達式(Javascript語言表述)爲:“^[^;]*(;[^;]+)*$”。

因此,當我們在解決問題,尤其是一些比較困難的問題時,若沒有什麼進展,而又沒有什麼新的思路時,不妨回到問題的原點,重新去表徵問題,換一種新的方式去表徵問題。或許,這個時候就會豁然開朗。這就好比我們在偵探題材的影視作品中經常看到的情景:偵探在查案過程中,費了許多人力和時間案情都沒有什麼進展,這個時候要突破困境的一個好的方法是從“零”開始:重新回到案發現場,重新去尋找蛛絲馬跡,重新進行推敲。這個時候,案情往往就柳暗花明了!

問題的表徵充分程度

若我有一小時的時間來拯救世界,我會花59分鐘來定義這個問題,並花一分鐘的時間來尋找解決方案(If I had an hour to save the world, I would spend 59 minutes defining the problem and one minute finding solutions)。––– Albert Einstein

 

心理學研究表明,在解決常規問題時,專家比新手快得多。而在解決困難問題時,專家用於表徵問題的時間比新手要長一些,他們會用更多的時間去收集問題的相關信息,因而對問題的表徵更加充分。

有這樣一個個案。運維人員報告某個生產環境的進程數過多,向研發人員求助定位該問題。而對方所提供的信息僅僅是說“主機上的進程數過多”,附帶一款監控軟件所報的告警信息:“XXX主機上的進程數超過260”。

該問題的解決過程是:首先,弄清所謂“進程數過多”,具體是什麼意思。結合監控軟件的告警信息,可以回答該疑問:所謂進程數過多,是指主機上所啓動的進程數大於監控軟件所預設的進程數量(如260)。此時,問題似乎明朗了:找出260個進程之外的進程是哪些,問題應該就能解決。但這也存在一個問題,假設進行問題定位的時候,該主機的進程數是265個,這其中的每個進程對我們來說都是沒有差別的,我們又如何將這些進程區分爲兩部分呢?進一步向對方詢問得知,問題所涉及的主機系一個集羣環境(共幾十臺主機)中的一臺,而經過確認其它主機上並沒有出現該問題。那麼,通過比較該主機上的進程名稱列表和集羣環境中另外一臺主機的進程名稱列表,可以發現出現問題的主機“多出”了哪些進程。最後發現,該問題系運維人員定製了一個定時任務,該定時任務調用的Shell腳本重複運行(前一次腳本運行對應的進程未結束,新的腳本運行又開始了),從而導致進程數越來越多。

當筆者將上述問題寫爲問題定位案例給新手進行定位時,新手的反應是懵了,不知從何下手。

正如上述個案所展示的,軟件行業中遇到的問題多數是定義模糊的問題,尤其是一些生產環境中出現的問題。對於這樣的問題,專家能夠通過自己的分析判斷、進一步收集與問題有關的信息,使問題逐步轉化爲定義良好的問題,再通過適當的問題解決策略(如上述的比較法),從而解決問題。而新手往往不知所措。

因此,對於定義模糊的問題,其解決思路大體上是試圖將其轉化爲定義良好的問題,途徑是通過分析判斷,收集有關問題的更多信息。而對於新手,平時通過觀察專家解決問題的過程,並試圖模仿之,也是一個提高解決問題能力的方法。

觀察能力

一切推理都應該從觀察和實驗中得來。

––– 伽利略

在解決軟件行業的問題過程中,視覺是人腦獲取信息的主要途徑。解決問題的過程中,人腦並不是被動地接受視覺信息,而是通過有意識的、帶有目的性的主動觀察獲取信息。另外,軟件開發過程中遇到的問題多數是界定含糊的問題,通過觀察獲得有關問題的更多信息有助於對問題進行充分的表徵。因此,觀察能力在解決問題的過程中顯得非常重要。在我們的日常工作中也不難發現一點:專家在解決問題過程往往能夠從一堆視覺信息中快速捕捉到其所需的關鍵信息,而新手面對專家所賴以解決問題的信息時卻往往視若無睹!

例如,如圖2所示的一個幾十行的Call Stack信息中,專家可以快速地定位到第35行這行關鍵信息,從而斷定問題系磁盤空間不足所致,而新手則可能不知從何下手。

圖 2. 從錯誤信息中快速定位關鍵信息

日誌文件、軟件界面等所呈現的錯誤信息是問題定位的一個重要信息來源。但是經驗告訴我們,“二八原則”在此也是適用的:這些錯誤信息中的大部分對於解決問題來說是無用或者用處不大的,而那些對問題的定位和解決能夠起到決定性作用的關鍵信息往往就那麼幾行甚至一行。因此,能否在這些大量的錯誤信息快速找出那些我們需要的關鍵信息,往往決定了問題解決的效率。

快速找到我們所需的關鍵信息,需要問題定位者的擁有敏銳的觀察能力。提高觀察能力,首先需要意識到觀察能力的重要性。其次,在日常工作中逐步地學會區分自己在問題定位過程中所遇到的錯誤信息,哪些是關鍵的,哪些是幫助不大的。再次,掌握一些獲取關鍵信息的基本技能。例如,對於與數據庫有關的錯誤信息,要能夠重點關注數據庫系統所報的錯誤碼。對於Java Call Stack信息,重點關注“Caused by”部分的頭幾行。

筆者曾經通過引導組員意識到其觀察能力的薄弱和觀察能力的重要性,並通過實際的問題定位向其展示如何快速獲取關鍵信息,幫助了組員一定程度上提高了觀察能力。

小結

本篇介紹了問題解決的心理過程以及問題表徵階段影響問題解決的一些心理因素。並結合筆者實際經歷的例子通過比較專家與新手在解決問題時表現出的差異給出提高問題定位與解決能力的指導意見。下篇將介紹影響問題解決的其它心理因素,並給出相關指導意見。

作者簡介

黃文海,著有《Java多線程編程實戰指南(設計模式篇)》。有多年敏捷項目管理經驗和豐富的技術指導經驗。關注敏捷開發、Java多線程編程和Web開發。在InfoQ中文站和IBM DeveloperWorks上發表過多篇文章。其博客:http://viscent.iteye.com/


感謝張龍對本文的審校。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章