那些可以問得更好的程式問題

Huli
9 min readJul 22, 2020
Photo by Duangphorn Wiriya on Unsplash

提問很難,尤其是對初學者來說。

所以我在教學的時候一直在想,除了提問的智慧以外,有沒有什麼文章是可以讓學生看了之後,能夠更快速、更深刻地去體會為什麼他們問的問題不夠好?

舉例應該是最快的,而且不能是假想的例子,因為身為一個已經比較會提問的人,我想出來的例子跟真實的例子應該會差很遠。因此,我特別從學生那邊搜集了一些問題,這樣就可以直接來看這些被真實提出的問題,再來分析它們哪邊不夠好,哪邊可以再改進。

文章的問題皆為真實的提問,而我有把能夠識別出提問者身份的資訊去除,事前也有徵得本人同意。在看這些問題之前,我先講一下我整理出來的提問心法:一大原則,三大要素。

問問題一大原則

這個原則就是:

角色互換

或是你要想成「設身處地」、「將心比心」之類的也可以。

當你把問題寫好要提出來的時候,你要想的第一件事情應該是:「如果我今天被其他人問一樣問題,我有足夠的資訊去 debug 嗎?」

很多人會以為問題的好壞取決於難易度,例如說這個問題只是少打一個字,所以是個壞問題;這問題很難 debug,所以是個好問題。不是的,問題的難易度取決於個人,儘管只是打錯字,但你就是卡了一個小時還解不出來,那就代表對你來說,這是一個困難的問題。

提問的好壞取決於資訊量,太少資訊量就是需要通靈人出場的時候,太多資訊量反倒變成一種雜訊,甚至是干擾。以初學者來說,寧可多給資訊,也不要少給。

很多時候你的提問之所以資訊量太少,是因為這些資訊量存在於你的腦海中,而不是你的提問裡面,通常有可能 3 成在提問裡,7 成在你腦海。所以對他人而言,他只看到了你理解的 3 成,或甚至是更少。

在這種狀況下,其他人就只能靠經驗或者是通靈能力,才能理解你到底想問什麼。所以你必須要把你腦海中儲存的那些 context 一起放到問題裡面,其他人才知道這個問題完整的樣子到底是什麼。

這也是為什麼角色互換很重要,你要像開無痕視窗那樣,把你對這個問題的背景知識都拿掉,然後只看那個問題本身,去想一下如果有人這樣來問你,你有沒有辦法拿到你需要的資訊?如果沒有,通常就代表資訊量不足;如果有,但是你發現「你需要的資訊」其實存在你腦中,而不是你的提問,就代表你應該把這項資訊放到問題裡面。

不過這對初學者來說其實也不容易,因為有時候很難知道到底哪些是背景知識,哪些又是一定要放進問題裡的。

因此,我整理了底下的三大元素,可以先跟著做就是了。

問問題三大要素

  1. 問題描述
  2. 程式碼
  3. 截圖與文字

第一點就是這問題想提問的點到底是什麼?你碰到的狀況到底是什麼?預期的狀況是什麼?

第二點就是程式碼,如果它是一個程式相關的問題,請把程式碼附上。

第三點就是附上截圖,把出現錯誤的畫面或是覺得有問題的地方截圖附上來。另外,程式碼也可以一起截圖,但這不代表就不需要「文字的程式碼了」,兩個都有的話其實會更好。

為什麼呢?因為要回答你問題的人,看到你問題時手邊不一定立刻就有電腦,所以沒辦法把你的程式碼跑起來確認結果。這時候如果有截圖,看程式碼就比較容易,也更有機會早一點幫你把 bug 找出來。

再者,這個要素是「截圖與文字」,意思是光有截圖是不夠的,你要把截圖中的重要訊息再用文字打一遍。為什麼?因為我可能會需要幫你把錯誤訊息拿去 Google,才知道這是什麼意思。如果你只有附截圖,那我就要自己再看著截圖打一遍——但通常沒有人會這麼勤勞。

截圖只是為了方便手邊沒有電腦的人解題,以及比較能確認整體的狀況為何,但裡面的重要資訊還是要再以文字來表示,才能完整表達問題。

知道以上三大要素以後,我們來看看各種真實世界的提問範例。

範例一

我想請問一下
你寫oddnumbersum 和 evennumbersum 的時候,都有先set sum = 0,再一個一個加上去。
最後return sum但做完oddnumbersum 後,sum不是應該是32嗎?

那為什麼在做 evennumbersum 的時候,又要重新let sum = 0?

問題描述

勉強算是清楚,但最大的問題是缺乏 context,我知道他在講我曾經寫過的程式碼,但我不知道是哪一段,而且我也忘記原本的程式碼長怎樣了

程式碼

完全沒有附,導致我不知道怎麼回答他

截圖與文字

分析

因為少了程式碼,所以我完全不知道該怎麼回答,因此我只能回:「你可能要附一下程式碼或是截圖喔」

附截圖是因為在 Slack 上程式碼可能比較不容易觀看,所以附截圖會更清楚。但截圖的缺點就是只適合比較短的程式碼,而且沒辦法複製,因此我覺得程式碼跟截圖一起附上是比較好的。

後來把截圖補上以後,我就有足夠資訊回答他的問題了。

範例二

卡關了QQ,為什麼我看不太懂我為什麼不能push?

問題描述

因為有搭配截圖,所以看得出來他想問什麼,但資訊還是不足

程式碼

這題不需要

截圖與文字

分析

從截圖可以看出來,是在做 git push 的時候出錯,但除了截圖以外,應該要附上截圖中的重要資訊的文字版,所以應該要附上截圖中出現的 git repo 的網址,這樣我才能去 GitHub 看一下那個 repo 有沒有什麼異狀。

再者,也應該一併附上之前下其他指令的截圖,才有辦法 debug。

範例三

目前在寫 week3 作業,但依照 ESlint 給的回饋修改程式碼後,仍有兩個錯誤,都是同樣的:error Parsing error: Unexpected token = (如圖所示)

根據這個回傳的錯誤訊息,我找到 stackoverflow 說是因為環境設置不同的關係

所以又找到這篇文章的解決方式:修改 package.json,新增 standard,並在裡頭設置 parser: babel-eslint(如下)

"standard": {
"parser": "babel-eslint"
}

不過依然出現相同的 error 問題,也無法以 /* eslint-disable */ 阻止噴出這個錯誤。
所以來詢問是否有建議的解決方式

問題描述

描述的滿清楚的,而且有附上自己嘗試解決問題的過程。

程式碼

這題最大的重點在於從截圖中可以明確看出,這是 eslint 偵測到某一段程式碼不符合規則所以報錯,但因為沒有附上程式碼,所以無從 debug

截圖與文字

有截圖,但應該附上裡面的文字,也就是那個錯誤訊息的文字版

分析

既然錯誤跟程式碼有關,那就一定要附上程式碼,不然缺少必要資訊,沒辦法判斷問題在哪。

於是我回說:「eslint 報錯一定是有原因的,錯誤訊息寫說是第10行那邊有出錯,但沒有看到程式碼沒辦法判斷原因,可以把程式碼 10 行左右那邊整個截圖貼上來,不然沒辦法判斷」

後來學生把程式碼貼上,就能看到錯誤在哪邊,修掉之後就沒問題了。

範例四

大家安安
前幾天我寫好了第三週的功課,也都已經得到 LIOJ 的 AC,今天打算來把他們都通過 Eslint 的測試然後交作業。
結果今天再次測試的時候發現結果都變得怪怪的… 我在想會不會是因為我前天寫完作業之後更新了 Windows 10 的 2004 Build,另外今天 Command Line 也變得有點奇怪,我之前都是使用 Sublime Text 3 搭配 Git Bash 編寫程式,有人有遇到一樣的問題嗎?

問題描述

描述的滿不清楚,只有講「結果都變得怪怪的」,但卻沒有講說到底怎樣叫做怪怪的?是結果有出錯嗎?是出現奇怪的字元嗎?除非我會通靈,不然我不會知道。

程式碼

截圖與文字

分析

這題的資訊量不足,因為都只有講說「怪怪的」,卻沒有具體指出哪裡怪。應該附上的資訊為:

  1. 之前是什麼樣子
  2. 現在是什麼樣子,差別在哪
  3. 預期中的結果是什麼
  4. 相關程式碼與截圖

這一題後來有其他同學幫忙解答,在獲得以上資訊之後,順利解決問題。

後記

再複習一次三大要素:

  1. 問題描述
  2. 程式碼
  3. 截圖與文字

除非你真的很有自信某一個不需要,不然請全部都附上。問題的完整度直接決定了這個問題是否能夠被快速且有效率地解決,有時候錯誤的問題只會引來錯誤的回覆(尤其是回答的人經驗不太夠的時候,這個在社群裡面很常出現),而更糟的是因為你也不知道那個回覆是錯的,所以也一起被帶偏了。

不過我寫這篇文章不是叫大家停止問問題或是停止幫其他人解決問題啦,在一個學習氣氛良好的社群之下,是可以盡情發問跟解惑的,在 Lidemy 的社群裡面因為有我跟助教在,所以回答錯也沒關係,因為最後有人會跑出來給正確答案,點出錯誤在哪裡。

還有一點想特別提的,是有關於回答問題。那就是儘管問問題的人給了許多資訊,你必須去意識到一件事,那就是「提問者給的資訊有可能是錯的」。這很重要,因為有些人會想說既然是提問者自己給的,那就一定 100% 是正確的,但事實往往不然。

例如說可能會有這樣的提問:「我程式碼一開始都是好的,但是跑 eslint 把錯誤修正之後就壞了,可是邏輯我都沒動,只有加分號而已」,這時如果你完全相信他說的,就很有可能找不出問題在哪裡。

因為有可能真相是,在修錯誤的時候,也有把某個變數修掉,所以不只是加分號而已,其實還有其他變動。提問者沒有騙你,因為他自己也忘記,或是根本沒有發現這件事。

以這個觀點來看,我覺得回答問題可能可以分成幾個等級:

  1. Level1:根據提問者給的資訊回答,沒給的就回答不出來
  2. Level2:承上,但可以透過通靈推敲出沒給的資訊大概是什麼
  3. Level3:承上,而且可以分析出提問者給的某些資訊其實是錯的

第三個 level 之所以難,是因為有可能他給的資訊是對的,而問題真正的根源是某個你想像不到的地方,所以你才會覺得他的說法不合理。

最後做個總結,其實無論是提問或是回答問題都是需要經驗的累積,看過的問題愈多,自然就能夠愈快從過去的經驗中尋找答案,畢竟很多常見的問題都是類似的。提問也是,在一開始學程式時背景知識嚴重不足,所以不知道該怎麼提問其實也滿合理的,但是當你會的東西愈來愈多,你就會漸漸知道某些資訊是重要的,在提問的時候就會一併奉上。

這篇如果之後有些案例會繼續更新,希望能整理得越來越完整。感謝 Lidemy,感謝助教以及學生們。

--

--

Huli

重度拖延症患者,興趣是光想不做,有很多想做的事,卻幾乎都沒有執行。相信分享與交流可以讓世界更美好。想持續關注可以追蹤這個粉專:https://www.facebook.com/huli.blog ,Medium 文章列表請參考:https://aszx87410.github.io/blog/medium