學(xué)編程難免遇到問題,遇到問題難免要上網(wǎng)求助。然而有過不少同學(xué)向我訴苦,說在網(wǎng)上提問沒有人回答,有的還收到一些不是很友好的回復(fù)。我自己也在經(jīng)常上的論壇上目睹過類似的帖子。以至于有人說,程序員社區(qū)就是對新人不友好,不愿幫助新人,甚至說這是怕別人學(xué)會(huì)了來搶飯碗。
對此我想正名一下,程序員們大多很單純,而且這或許是這個(gè)星球上最樂于分享的群體。但在這個(gè)充滿理性、邏輯至上的群體里,有著自己一套規(guī)則。當(dāng)一個(gè)不懂規(guī)則的人出現(xiàn)在群體中,往往會(huì)被“教做人”。
如果你也曾遭遇這樣的問題,或今后打算在編程社區(qū)里成長,請務(wù)必看看我接下來要說的東西:
如何正確地在編程社區(qū)提問?
絕大部分得不到滿意回答甚至引來不滿的問題,都是問題本身的原因。我本人在網(wǎng)上回答了這么多年問題,也經(jīng)常是深感困擾。提出一個(gè)好問題,對于提問者和回答者,都有很大幫助。
提問前準(zhǔn)備
當(dāng)你打算上網(wǎng)求助前,先問自己2個(gè)問題:
我搜索了沒有?
我檢查了沒有?
學(xué)編程,你不是一個(gè)人。幾乎所有你遇到的坑,都有前人踩過,搜索一下就會(huì)有答案。各種文檔、教程里的內(nèi)容也都會(huì)包含在網(wǎng)頁結(jié)果中。搜索的關(guān)鍵是如何描述問題,所以要學(xué)會(huì)看報(bào)錯(cuò),能找到報(bào)錯(cuò)中的關(guān)鍵信息。關(guān)于更多搜索的技巧,參考之前的文章《編程初學(xué)者如何使用搜索引擎》。
編程屆有兩個(gè)詞:RTFM、STFW,含義我不解釋,自己去查。當(dāng)有人在你問題下回復(fù)類似詞時(shí),想想自己有沒有動(dòng)手搜索過。
如果網(wǎng)上找不出你的問題,有幾種可能:1.關(guān)鍵詞選得不準(zhǔn)確;2.你確實(shí)碰上了特殊情況;3.你犯了某些低級錯(cuò)誤。對新手來說,3的可能性更大。所以請務(wù)必自己檢查下,單詞拼寫對不對、標(biāo)點(diǎn)是不是英文、縮進(jìn)空格對不對、括號引號是否成對、文件路徑是否正確……
排除低級錯(cuò)誤外,你還應(yīng)當(dāng)對錯(cuò)誤做定位,盡量縮小范圍,增加必要的輸出。這在提問時(shí)也會(huì)極大方便回答者。而且我也經(jīng)常跟人說,當(dāng)你自己把必要的值都輸出出來看清楚后,通常問題已經(jīng)很明顯了。關(guān)于 debug 的技巧,參考之前的文章《開發(fā)5分鐘,調(diào)試2小時(shí) - 你的問題在哪里?》
提問的內(nèi)容
一個(gè)好的問題,應(yīng)當(dāng)是準(zhǔn)確、具體、簡潔、完整,也就是既要清楚地表達(dá)了問題涉及的信息,又不要夾雜無關(guān)的噪音。
具體來說,通常應(yīng)包括這幾種信息:
問題的表現(xiàn)
平臺和版本
輸出的報(bào)錯(cuò)信息
相關(guān)部分的代碼
最好還附上你的屏幕截圖(避免你沒意識到的錯(cuò)誤)以及中間變量的輸出(方便回答者,同時(shí)也說明你自己嘗試過)。
特別說一下附上的代碼。對新手來說,最好同時(shí)提供截圖和代碼文字,截圖是展示電腦上的真實(shí)情況,文字是方便別人復(fù)現(xiàn)。如果你的代碼短,就全部發(fā)上;如果是很多代碼文件的項(xiàng)目,請自己先做初步的定位,只發(fā)關(guān)鍵部分的代碼。
如果你是在論壇、問答網(wǎng)站上發(fā)帖,取個(gè)好標(biāo)題很重要。把問題在標(biāo)題里簡要描述清楚遠(yuǎn)好過“求助!在線等!挺急的”這種無意義的標(biāo)題。
提問的形式
提問時(shí),要選擇合適的地方,說合適的話。
比如你在一個(gè)進(jìn)階論壇中問初學(xué)者的問題,往往會(huì)遭到排斥。反過來也不合適。比較可惜的是,在編程屆,進(jìn)階、深入的論壇更多,初學(xué)者論壇則較少。所以如果你愿意,歡迎來我們的論壇提問,當(dāng)然別忘了上面說的幾點(diǎn)。
而至于什么才是合適的話,這個(gè)比較難把握??偟膩碚f,禮貌永遠(yuǎn)是好的,沒人愿意搭理傲慢、粗魯?shù)奶釂?。但有時(shí)候,效率比禮貌更重要。比如 StackOverflow 就禁止打招呼、感謝,因?yàn)檫@會(huì)帶來無效信息。你只需要精確描述問題、采納優(yōu)秀回答即可。同樣,當(dāng)你給別人提問時(shí),直接了當(dāng)?shù)卣f明問題,絕對不要一句“你好,在嗎?”,等到回復(fù)再來一句“我可不可以問你一個(gè)問題?”這樣留言。或許你覺得這是禮貌,但對于別人來說,本來一次就可以回復(fù)的事情,硬生生被拖成幾個(gè)小時(shí),可能根本就不理你了。
而當(dāng)你發(fā)布在網(wǎng)上的問題最終被解決后,在問題后附上解法說明,按社區(qū)規(guī)則采納/點(diǎn)贊有用的答案,是值得推薦的做法。對于回答者來說,這比一句口頭贊賞更禮貌。
提問的禁忌
上面說了些建議,如果你還不夠理解,那么請記住,不要像這樣提問:
搜一步就可以解決的問題。比如“Python 里怎么讀取一個(gè)文件的內(nèi)容?”
X-Y 問題。所謂 X-Y 問題,就是你要解決 X 問題,你認(rèn)為可以用 Y 方法解決,然后你就問怎么實(shí)現(xiàn) Y,但其實(shí) X 問題根本就有更合適的解法。比如“我怎么取一個(gè)字符串的后3位?”,而實(shí)際他想解決的是“怎樣獲取文件的文件類型?”
籠統(tǒng)而抽象的問題。比如“我能不能學(xué)會(huì) Python?”。這個(gè)問題被問的頻率很高,但這不該問別人,問你自己。
不要亂猜原因,甚至聲稱是別人代碼的 bug。你需要客觀描述和分析問題。比如“我一輸比10大的數(shù)就不對,是不是 Python 在我電腦上有問題?”
不要把多個(gè)問題混為一談,分清楚因果。代碼有不止一個(gè)錯(cuò)誤是很正常的,如果別人的方法讓你的報(bào)錯(cuò)發(fā)生變化,說明對上一個(gè)問題起了作用,這種情況需要進(jìn)一步分析,而不是立刻回復(fù)一句“按照你的方法改了還是不行”。(這種屬于真的不禮貌,會(huì)讓回答者不想再理你)
在開放的論壇、討論組、問答網(wǎng)站,盡量不要通過發(fā)私信、加好友的方式來提問。(事實(shí)上,這種方式大多也無效)
不要妄想讓別人替你調(diào)試 bug、寫作業(yè)、開發(fā)。
一個(gè)糟糕問題的例子:
哪位懂Python的幫我看下這是什么問題?
(一張幾十行的代碼截圖)
一個(gè)好問題的例子:
我的程序里將輸入和變量比較大小,結(jié)果報(bào)錯(cuò),請問是為什么?
我是Python3
報(bào)錯(cuò):TypeError: '<' not supported between instances of 'int' and 'str'
(代碼+輸出的截屏、代碼文本)
一個(gè)更好問題的例子:
我的程序里將輸入和變量比較大小,結(jié)果報(bào)錯(cuò),請問是為什么?
我是 Windows 下的 Python 3.7
報(bào)錯(cuò):TypeError: '<' not supported between instances of 'int' and 'str'
提示是第11行:if answer < num:
我在前面加了 print,兩個(gè)變量都是有值的。
(代碼+輸出的截屏、代碼文本)
提問的本質(zhì)還是思考。如果你能提出一個(gè)好問題,必定是對問題思考后的結(jié)果。這對你本身也是一種練習(xí)。不思考就直接提問,既浪費(fèi)了鍛煉的機(jī)會(huì),也很難得到滿意答復(fù)。
從另一個(gè)角度來說,天下沒有免費(fèi)的午餐(也許有,但必另有所圖),不要把別人回答你當(dāng)做一件理所當(dāng)然的事情。所以請尊重別人的勞動(dòng),并盡可能讓別人樂于回答你。不要提糟糕的問題就是最基本的要求。
說了這么多,你也不要因此而不想提問題。該問的還是得問,要敢于提問和討論,甚至要上 StackOverflow 等英語網(wǎng)站去問。不然怎么提高自己?不但要問,還要回答,“教”是最好的“學(xué)”。當(dāng)你能向別人解釋清楚一個(gè)東西時(shí),才是你真的理解了它。既回饋了社區(qū),又提升了自己,何樂而不為?
Crossin的編程教室永遠(yuǎn)歡迎好問題。
最后,編程有篇很經(jīng)典的文章,推薦給大家:
How To Ask Questions The Smart Way
http://www.catb.org/~esr/faqs/smart-questions.html
【中文版】提問的智慧
https://github.com/FredWe/How-To-Ask-Questions-The-Smart-Way/blob/master/README-zh_CN.md
上述這一切,不僅針對編程。