如何問好問題

怎樣問好問題,釐清你的疑問,有效溝通

如何問好問題
Photo by Brooke Cagle / Unsplash

寫軟體時,問對問題超級重要。這幾年下來,我問問題的功力大增(同事都常常稱讚我)。以下是一些我的小撇步!

問爛問題沒關係

我其實蠻相信問蠢問題或「不好」問題的價值。我常常問一些 Google 或程式碼搜尋一下就有答案的蠢問題。雖然我盡量避免,但偶爾還是會問,而且我覺得沒什麼大不了。

所以這篇文章不是要告訴你「問問題前你一定要做這些事,不然你就是個爛人」,而是「這些方法幫助我問出更好的問題,也得到想要的答案!」。

如果有人堅持只回答「好」問題,我另外寫了一篇文章給他們看:《如何好好回答問題》。

什麼是好問題?

我們的目標是問一些關於技術概念,而且「好回答」的問題。我身邊常有一些高手,但他們不一定知道怎麼好好跟我解釋。

如果我能問出一系列好問題,就能引導對方有效地解釋,並講到我想知道的重點。接下來我們就來看看怎麼做吧!

先講你懂的

這是我最喜歡的技巧之一!這種問題的格式大概是:

  1. 先講你目前對這個主題的理解
  2. 問「這樣對嗎?」

例如,我最近跟一位高手(也很會問問題)聊網路!他說:「所以,我的理解是有一串遞迴的 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 跟我討論這個話題!