封面圖源自:Pexels
前言
看到標題的一瞬間,你或許在想 “什麼樣的問題算是好問題?”,在思否,每天或多或少都有十幾個(休息日除外)新的問題被提出來,而這裡面充斥著不少的 “質量” 問題。
如果你有曾讀過 《提問的智慧》 這本書,那你就應該知道該如何去提出一個問題,本文也算是對這本書的一個衍生補充。
下面,我將以我的視野,帶你提出一個好的問題。
真的需要提出這個問題嗎?
在提問之前,你應該先使用 Google、百度、必應等搜尋引擎嘗試尋找答案,因為在大部分時候,你能遇到的問題,其他人可能已經遇到過了,然後按照其中的解決方案進行處理,問題或許就解決了。
比如:Vue路由的實現原理? - SegmentFault 思否
一般可以描述出來的問題,或許更加容易檢索,沒準你花半個小時搜尋一番,你的問題就已經解決了。
而如果你選擇直接提出一個問題的話,大概率在三十分鐘內得不到解決。
如何檢索問題,大部分時候比較容易,但是遇到一些特殊情況,就變得麻煩了,比如我們在執行命令的時候出錯了,那麼可能會列印出來無比冗長的錯誤資訊,而且基本上都是英文,從中提取出有用的資訊至關重要。
舉個例子,就像 下面這一堆錯誤資訊。
D:\workplace\newcodebdc\back> npm install
npm ERR! code ERESOLVE
npm ERR! ERESOLVE could not resolve
npm ERR!
npm ERR! While resolving: vue-antd-jeecg@2.0.0
npm ERR! Found: webpack@4.46.0
npm ERR! node_modules/webpack
npm ERR! webpack@"^4.0.0" from @vue/cli-plugin-babel@3.12.1
npm ERR! node_modules/@vue/cli-plugin-babel
npm ERR! dev @vue/cli-plugin-babel@"^3.3.0" from the root project
npm ERR! webpack@"^4.0.0" from @vue/cli-plugin-eslint@3.12.1
npm ERR! node_modules/@vue/cli-plugin-eslint
npm ERR! dev @vue/cli-plugin-eslint@"^3.3.0" from the root project
npm ERR! 3 more (@vue/cli-service, less-loader, sass-loader)
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! vue-loader@"^15.7.0" from the root project
npm ERR!
npm ERR! Conflicting peer dependency: webpack@5.73.0
npm ERR! node_modules/webpack
npm ERR! peer webpack@"^5.0.0" from css-loader@6.7.1
npm ERR! node_modules/css-loader
npm ERR! peer css-loader@"*" from vue-loader@15.10.0
npm ERR! node_modules/vue-loader
npm ERR! vue-loader@"^15.7.0" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR!
npm ERR! See C:\Users\MaxThunder\AppData\Local\npm-cache\eresolve-report.txt for a full report.
npm ERR! A complete log of this run can be found in:
這時候我們只需要拷貝這部分錯誤資訊,先進行翻譯,嘗試去理解為什麼錯,如果不能理解,就到搜尋引擎進行搜尋,大多數情況下,你都能得到答案。
當產生錯誤的時候,我們應該先在報錯資訊中尋找一個關鍵字 Error
,大部分時候,出現這個關鍵字的時候,緊隨其後都會列印出具體的錯誤,部分的還會列印出一個錯誤的 CODE ,比如 MySQL 的報錯,你順著這個 CODE 加上軟體名字,沒準就能檢索到。
如上面的裡面,充斥著 ERR
,這就有很多錯誤的,一眼也無法分辨,如果你複製的翻譯後,大概就能知道,是“ xxx 依賴不能解析”,並且在後面還提供了一段 fix(修復)
方法,讓你嘗試在命令後面加上 --force
或者 --legacy-peer-deps
進行重試,或許你執行後問題就解決了,你也就不再需要提出一個問題了。
提出問題
合適的標題
大部分社群,都是以標題的形式在列表展示出來的,像 思否 這種還會在列表展示標籤。回答者並不是機器人,大多數時候,回答者並不會開啟所有帖子進行檢視,起一個合適的標題更能讓回答者判斷這個問題是否在自身的解決範圍之內,從而點開。
不好的例子
好的例子
高質量的問題描述
在你的問題被解決前,你需要做的最終重要的一件事,就是讓回答者知道你在問什麼,否則別人很難給你答覆。
正如思否的提問模板一樣:
- 你遇到了什麼問題?
- 你的預期是什麼?
- 你的環境是什麼(執行的軟體版本、作業系統)?
- 你做了哪些工作?
- 出現問題的程式碼
按照上面的規則,描述你的問題,讓回答者能更加清晰的知道你遇到的是什麼問題,除此之外,你可能還需要按照提供一些額外資訊,來幫助回答者更快的幫你解決問題,畢竟幫回答者節約時間,也是給你自己節約時間。
學習使用 Markdown 語法,這花不了你多少時間,頂多十分鐘,但是終生受益。
1、不要使用圖片上傳程式碼,現在討論的社群,基本都支援 Markdown 語法,花上少許的時間,學習一下如何貼程式碼,這樣回答者也可以直接把程式碼複製到自己的環境上執行,快速復現/定位問題所在。
使用 3 個 ` 符號(鍵盤左上角,ESC下面,數字 1 前面,英文狀態下輸入),後面緊跟語言型別,最後再以新起一行,寫下三個 ` 即可構成一個程式碼塊。
```js
alert('Hello')
```
最終將顯示為如下效果。
alert('Hello')
2、儘可能提供有用的資訊
在資料庫相關的問題中,尤為常見,大部分人提問的時候,都是直接把資料截圖和自己寫的查詢語句截圖發上來了。
因為 SQL 本身就是抽象的,尤其是複雜的 SQL,都要進行測試才能符合預期。
這就大幅降低了回答者的興趣,雖然現在 OCR 技術已經足夠強大,可能可以識別出來,但有時候還會要修正才行,而且,這類問題,大部分都是跟資料打交道,重要的就是資料呀,你什麼都不提供,別人只能遠而觀之。
對於 SQL 類的提問方式,應當附上建表語句、資料填充語句、以及你自己寫的查詢語句。
對於建表語句,你可以使用 show create table 表名稱;
來獲得。
對於資料填充語句,以 MySQL 為例,你可以使用 mysqldump
這個工具匯出,然而這可能複雜了一些。但是現在一些 SQL 管理工具,都提供了圖形化的匯出為 insert
語句。
而你要做的這些,只需要花費你幾分鐘的時間。
舉個例子:
# 建表語句
CREATE TABLE IF NOT EXISTS `myTable` (
`id` mediumint(8) unsigned NOT NULL auto_increment,
`name` varchar(255) default NULL,
`score` mediumint default NULL,
`sex` mediumint default NULL,
PRIMARY KEY (`id`)
) AUTO_INCREMENT=1;
# 資料插入語句
INSERT INTO `myTable` (`name`,`score`,`sex`)
VALUES
("Abdul Stanley",143,2),
("Chaney Pickett",62,2),
("Keelie Lindsey",99,2),
("Rae Hartman",146,2),
("Nevada Ward",72,1);
別人在拿到後,就可以方便的在自己的環境上進行處理了,你可能還需要提供 SQL_MODE
資訊。
除此之外,還有就是你所執行的 MySQL 版本了。
當然,有時候我們的資料可能存在敏感資訊,請一定要記得脫敏後釋出。
你也可以使用一些資料構建工具來構建資料跟你結構相似的資料,比如:generatedata
或者:mockaroo
拒絕 XY 問題
對於X-Y Problem的意思如下:
1)有人想解決問題X
2)他覺得Y可能是解決X問題的方法
3)但是他不知道Y應該怎麼做
4)於是他去問別人Y應該怎麼做?
簡而言之,沒有去問怎麼解決問題X,而是去問解決方案Y應該怎麼去實現和操作。於是乎:
1)熱心的人們幫助並告訴這個人Y應該怎麼搞,但是大家都覺得Y這個方案有點怪異。
2)在經過大量地討論和浪費了大量的時間後,熱心的人終於明白了原始的問題X是怎麼一回事。
3)於是大家都發現,Y根本就不是用來解決X的合適的方案。
X-Y Problem最大的嚴重的問題就是:在一個根本錯誤的方向上浪費他人大量的時間和精力!
舉個 ?
Q) 我怎麼用Shell取得一個字串的後3位字元?
A1) 如果這個字元的變數是$foo,你可以這樣來 echo ${foo:-3}
A2) 為什麼你要取後3位?你想幹什麼?
Q) 其實我就想取檔案的副檔名
A1) 我靠,原來你要幹這事,那我的方法不對,檔案的副檔名並不保證一定有3位啊。
A1) 如果你的檔案必然有副檔名的話,你可以這來樣來:echo ${foo##*.}
幫助回答者
在提問的時候,你可以多為回答者考慮一些,比如通過一些線上服務,讓回答者無需在本地環境上操作。
比如前面提到的資料庫問題,我們就可以使用 db-fiddle 來建立一個線上的 MySQL 執行環境,填寫完成後點選 Run
確認 OK 後,再點選 Save
將會為你生成一個唯一的連結地址,現在別人開啟這個連結,就可以在這上面直接編輯操作,方便了許多。
除此之外,像前端還可以使用
這倆個都是國外的服務,可能比較難開啟,你也可以選擇國內的:
如果你的問題比較複雜,你可能還要考慮提供一個「最小的可重現示例(Minimal reproducible example)」將其提交到 Git 服務,以提供給回答者。(☹️ 我想一般也不會複雜到這個程度)
複雜情況
還有一個問題,就是問題很小,但是程式碼很多。
常見於現代化前端的 CSS 問題,很多時候,問題是在專案或者某個元件中發生的,而即便是你提供了這個元件的程式碼,回答者也不能很好的復現問題,比如你的 DOM 可能是由資料渲染出來的。
這種情況,提問的時候,就應該把渲染後的結果+能夠復現的最少的程式碼貼上來,這樣更容易復現問題。
或者,可以使用一些瀏覽器擴充套件,把頁面儲存成單個 HTML 檔案,上傳到免登入/註冊的網盤或者 Git 上。
比如 SingleFile
,這個擴充套件就可以把網頁所有內容儲存成一個 HTML 檔案,從而讓回答者更加容易復現問題。
(當然,你也應該儘可能的提供原始程式碼)
Playground 或者 Sandbox
對於一些冷門點兒的語言,上面的這些工具,可能覆蓋不到,但是你也可以嘗試搜尋 語言 Playground
,大概率可以找到一些可以線上編輯、執行、分享的服務,比如 Laravel playground
。
維護好你的問題
很多時候,我都能在不同的社群看到同一個問題,毫無疑問,這個問題也是同一個人提的。
當然,多個地方就多了一分解決問題的機會,但是這些提問者往往都少有去 “維護” 自己的問題。
維護一個問題,往往比提出一個問題,更為重要。
1、及時回應/補充你的問題,有些人可能是第一次提問,遺漏了一些東西,有時候就會有人提醒你,需要補充哪些資訊,請及時處理。像思否,預設情況下就會郵件通知到你。
2、與回答者溝通,如果你的問題描述的不是那麼完美無瑕,或者回答者理解偏差導致給出了錯誤的回答,你應該及時的跟回答者進行溝通,而不是無視別人。
這樣也可以讓其他回答者知道具體的情況,對於我個人而言,如果一個問題,提問者自己沒有維護這個問題,那麼即使我有解決方案,我也不會選擇去回答。
3、不要重複提問,當你的問題幾個小時或者一兩天過去之後,仍然沒有人回答,請不要嘗試再重複提問,因為很有可能不是別人沒看到,而正是因為前面的種種原因疊加。當然,也有可能你的問題太過深奧,無法給你回答。你還可以嘗試邀請一些人進行回答。
4、選擇合適的答案,當你的問題被解決後,應該選擇幫助你解決問題的人的回答標記為答案。這樣也可以很好的幫助其他人在遇到這個問題的時候,及時找到正確答案。
5、找到解決方案後應當附上,如果回答裡面的都不能解決你的問題,最終你自己解決了,也應該附上答案。
6、同步解決方案,正如前面提到的,很多人都會在 N 個論壇發出同樣的提問,而往往可能只是其中某個論壇的回答者解決了問題,而其他論壇則未解決。作為提問者,你應該像你當初提出問題那樣,把正確的答案同步到你曾經發出過這個問題的地方,為後來者提供便利。
你做了什麼?
除了上面的以外,提出一個問題的前提是,你應該儘可能在自己的能力範圍內去嘗試解決他,比如通過搜尋引擎檢索、嘗試已有的方案、編寫相應的程式碼,或許在這些過程中,你的問題就已經解決了。
好的 ?
寫在最後
- 以上論點僅為個人觀點,如果有不足或錯誤,還請不吝賜教。
- 你還可以點選文章中的來源連結,瞭解更詳細的內容。
- 如果文中的內容侵犯到了你得權益,請與我聯絡處理。