如何問好問題
怎樣問好問題,釐清你的疑問,有效溝通
寫軟體時,問對問題超級重要。這幾年下來,我問問題的功力大增(同事都常常稱讚我)。以下是一些我的小撇步!
問爛問題沒關係
我其實蠻相信問蠢問題或「不好」問題的價值。我常常問一些 Google 或程式碼搜尋一下就有答案的蠢問題。雖然我盡量避免,但偶爾還是會問,而且我覺得沒什麼大不了。
所以這篇文章不是要告訴你「問問題前你一定要做這些事,不然你就是個爛人」,而是「這些方法幫助我問出更好的問題,也得到想要的答案!」。
如果有人堅持只回答「好」問題,我另外寫了一篇文章給他們看:《如何好好回答問題》。
什麼是好問題?
我們的目標是問一些關於技術概念,而且「好回答」的問題。我身邊常有一些高手,但他們不一定知道怎麼好好跟我解釋。
如果我能問出一系列好問題,就能引導對方有效地解釋,並講到我想知道的重點。接下來我們就來看看怎麼做吧!
先講你懂的
這是我最喜歡的技巧之一!這種問題的格式大概是:
- 先講你目前對這個主題的理解
- 問「這樣對嗎?」
例如,我最近跟一位高手(也很會問問題)聊網路!他說:「所以,我的理解是有一串遞迴的 DNS 伺服器…」。這其實是錯的!遞迴 DNS 伺服器運作時,只有一台伺服器參與。也因為他講了他的理解,我們才能釐清實際的運作方式。
我之前研究 rkt 時,不懂為什麼 rkt 跑容器比 Docker 佔更多硬碟空間。
直接問「為什麼 rkt 比 Docker 佔更多空間?」好像不太對,因為我大概懂程式碼怎麼寫,但不理解「為什麼」要這樣寫。所以我寫了這個問題到 rkt 開發者郵件論壇:「為什麼 rkt 儲存容器映像檔的方式跟 Docker 不同?」
- 我寫下我對 rkt 和 Docker 如何儲存容器的理解
- 提出一些我猜想他們這樣設計的理由
- 然後問:「我的理解對嗎?」
我得到的答案超級有幫助,完全就是我要的。我花了不少時間才把問題寫好,但我很高興我花了這些時間,因為這讓我更了解狀況。
講出你的理解並不容易(你要花時間思考並釐清想法!),但效果很好,也能讓對方更容易幫助你。
問答案是事實的問題
很多我的問題一開始都很模糊,例如「SQL JOIN 怎麼運作的?」。這問題不太好,因為 JOIN 的運作有很多面向!對方怎麼會知道我想了解哪一部分?
我喜歡問答案是明確事實的問題。例如,關於 SQL JOIN,可以問:
- JOIN 兩個大小為 N 和 M 的表格的時間複雜度是多少?是 O(NM)?還是 O(NlogN) + O(MlogM)?
- MySQL JOIN 前一定會先排序 JOIN 的欄位嗎?
- 我知道 Hadoop 有時會用「雜湊 JOIN」——其他資料庫引擎也會用嗎?
- JOIN 一個有索引的欄位和一個沒索引的欄位時,需要排序沒索引的欄位嗎?
問這種很具體的問題時,對方不一定知道答案(沒關係!),但至少他們知道我想了解的「類型」,例如,我顯然不是想知道怎麼「用」JOIN,而是想了解一些實作細節和演算法。
不懂就說
別人跟我解釋事情時,常常會講到我不懂的東西。例如,有人在講資料庫,說「我們用 MySQL 的樂觀鎖定,所以…」。我不知道「樂觀鎖定」是什麼。這時候就該問了!
能打斷對方說「等等,那是什麼意思?」是很重要的能力。我覺得這是一個有自信的工程師的特質,也是很棒的成長目標。我看很多資深工程師常常問清楚,我想當你對自己的能力更有信心時,就會更容易做到這點。
我越常這樣做,就越習慣請人解釋。事實上,如果我解釋事情時對方「沒」問清楚,我會擔心他們根本沒在聽!
這也讓回答問題的人有機會承認他們不懂!我問問題時,常常會問到對方不知道的事。我問的人通常都很擅長說「我不知道耶!」
找出你不懂的術語
我剛到現在這家公司時,加入了資料團隊。我開始了解工作內容時,看到一堆術語! Hadoop、Scalding、Hive、Impala、HDFS、zoolander 等等。我只聽過 Hadoop,其他都不知道是什麼。有些是內部專案,有些是開源專案。所以我一開始就問人每個術語的意思,還有它們之間的關係。我會問:
- HDFS 是資料庫嗎?(不是,是分散式檔案系統)
- Scalding 用 Hadoop 嗎?(對)
- Hive 用 Scalding 嗎?(不對)
我還寫了一本「字典」紀錄所有術語,因為真的太多了,了解這些術語幫助我快速上手,之後也能問出更好的問題。
做點功課
我打上面那些 SQL 問題時,有先 Google「SQL JOIN 如何實作」。我點了一些連結,看到「原來有時會排序,有時會用雜湊 JOIN,我聽過這個」,然後寫下一些更具體的問題。先 Google 一下能幫助我問出更好的問題!
不過,我覺得有些人太強調「Google 後再問」——有時候我跟同事吃飯,好奇他們的工作,就會問一些基本問題。這完全沒問題!
但做功課真的很有用,而且能做到問出一堆好問題其實很有趣。
決定要問誰
我這裡主要講的是問「同事」問題,因為我大部分時間都跟他們相處。
問同事問題前,我會思考:
- 現在適合問嗎?(如果他們在忙,可能就不適合)
- 問這個問題能幫我省下的時間,有比他們花費的時間多嗎?(如果我問一個 5 分鐘就能回答的問題,能幫我省 2 小時,那就太棒了!)
- 他們要花多少時間回答?如果我有半小時的問題要問,我可能會跟他們約時間;如果只有一個小問題,我可能就直接問了。
- 這個人會不會太資深了?很容易陷入一個陷阱,就是把每個問題都問最有經驗的人。但通常找一個資歷淺一點的人會更好——他們通常也能回答大部分問題,這樣也能分擔工作量,還能讓他們展現自己的知識(很棒)。
我不一定每次都判斷正確,但思考這些事情對我很有幫助。
另外,我通常會花更多時間問比較熟的同事——有些同事我幾乎每天都聊天,我可以很輕鬆地問他們問題,因為他們很了解我的工作內容,也能很快給我答案。
ESR 寫的《提問的智慧》是一篇很有名的文章,但也常常被批評(它開頭就說「我們稱這種人為『魯蛇』」,後面也沒好到哪去)。它主要講的是「在網路上問陌生人問題」。在網路上問陌生人問題是很重要的技能,能讓你獲得很多資訊,但這也是問問題的「困難模式」。對方不太了解你的狀況,所以更要仔細說明你想知道什麼。我覺得《提問的智慧》對提問者太嚴苛了(它說提問前應該先想盡辦法找答案,不然就是「懶惰鬼」),但它的「如何好好回答問題」那部分寫得不錯。
問問題來揭露隱藏的假設
更進階的提問技巧是問一些能揭露隱藏假設或知識的問題。這種問題有兩個目的:一是得到答案(一定有人知道其他人不知道的資訊!),二是指出「有」隱藏的資訊,而且分享這些資訊很有用。
Etsy 的《事後檢討引導手冊》中的「提問的藝術」對這點有很好的介紹,它是在討論事件發生後的檢討。以下是手冊中的一些問題:
「你懷疑發生這種錯誤時,會注意哪些事?」
「你怎麼判斷這個情況是『正常』的?」
「你怎麼知道資料庫掛了?」
「你怎麼知道要通知哪個團隊?」
這類問題(看起來很基本,但其實不容易回答)在由有權威的人提出時,特別有力量。我很喜歡主管/資深工程師問一些基本但重要的問題,例如「你怎麼知道資料庫掛了?」,因為這能讓資淺的人之後也敢問這類問題。
回答問題
André Arko 的好文《如何貢獻開源專案》中,我最喜歡的一段是:
「既然你已經看過所有 issue 和 pull request 了,就開始注意你能回答的問題吧。很快你就會發現有人問了之前已經被回答過的問題,或是在你剛讀過的文檔裡就有答案。回答你會回答的問題吧。」
如果你在學習新專案,回答別人關於你剛學到的東西的問題,是很棒的鞏固知識的方法。我每次第一次回答新主題的問題時,都會想「天啊,如果我答錯怎麼辦」。但通常我都能答對,然後就會覺得很棒,也更了解這個主題!
好問題是很大的貢獻
好問題能為社群做出很大的貢獻!我之前在 Twitter 上問了一堆關於 CDN 的問題,然後把答案寫成文章《CDN 不只是快取》。很多人跟我說他們很喜歡那篇文章,我覺得我問那些問題不只幫助了我自己,也幫助了很多人。
很多人很喜歡回答問題!我覺得重要的是要把好問題看成是能促進討論的好事,而不是「問好問題才不會惹人厭」。
感謝 Charity Majors 提醒我可以分享問問題的心得,也感謝 Jeff Fowler 和 Dan Puttick 跟我討論這個話題!