提问的智慧

最后更新于2022.06.27

声明

知名黑客,开源运动的旗手Eric S. Raymond(同时也是《大教堂与集市》的作者)于2001年撰写了《提问的智慧》这篇文章,距今已经过去了20余年,但是如果我们回头看的话,这篇文章所提及的内容直到今天还是很有启发和借鉴意义的,笔者近日也重新拜读了一下这篇文章,筛选整理出了我比较认可的并且至今还是适用的内容,供大家参考。

尽管主要面向软件技术人员,但是实际上里面描述的思想是普遍适用的。

简介

当你拋出一个技术问题时,最终是否能得到有用的回答,往往取决于你所提问和追问的方式。

你应该明白,真正的技术牛人们喜爱有挑战性的,能激发他们思维的好问题。“好问题!”是他们对你诚挚的称赞。同时他们蔑视那些不愿思考、或者在发问前不做他们该做的事的人,因为那些人只想索取,从不付出,消耗他人本来可用在更有趣的问题或更值得回答的人身上的时间。

在你提问前

在你准备要通过电子邮件、论坛或者聊天室提出技术问题前,请先做到以下事情:

  1. 尝试在你准备提问的论坛的旧文章中搜索答案。

  2. 尝试上网搜索以找到答案(有很高的几率某人已经问了一个类似的问题)。

  3. 尝试阅读手册以找到答案。

  4. 尝试阅读常见问题文件(FAQ)以找到答案。

  5. 尝试自己检查或试验以找到答案。

  6. 向你身边的强者朋友打听以找到答案。

  7. 如果你是程序开发者,请尝试阅读源代码以找到答案。

当你提问的时候,请先表明你已经做了上述的努力;这将有助于树立你并不是一个不劳而获且浪费别人的时间的提问者的形象。

从你的提问可以看出你做了多少阅读与思考,不要将所有问题一股脑拋出,准备好你的问题,再将问题仔细的思考过一遍,因为草率的发问只能得到草率的回答,或者根本得不到任何答案。越是能表现出在寻求帮助前你为解决问题所付出的努力,你越有可能得到实质性的帮助。

另一方面,表明你愿意在找答案的过程中做点什么是一个非常好的开端。比如你可能会说:我的这个测试用例中是缺了什么条件么?我应该检查什么地方?谁能给点提示?这样的具体问题更加容易得到答复。因为你表现出只要有人能指个正确方向,你就有完成它的能力和决心。

当你提问时

尽量使用邮件列表

如果某个项目提供开发者邮件列表时,要向列表而不是其中的个别成员提问,即使你确信他能最好地回答你的问题。有几个很好的理由支持我们采用这种办法:

  • 好问题对整个项目群组有益。

  • 个别开发者也许太忙以至于没法回答你的问题。

  • 如果某些问题经常被问到,项目组可以利用此信息来改进说明文件或软件本身,以使其更清楚。

使用有意义且描述明确的标题

在邮件列表或论坛中,大约 50 字以内的标题是抓住资深专家注意力的好机会。别用喋喋不休的帮帮忙、跪求、急(更别说救命啊!!!!这样让人反感的话,用这种标题会被条件反射式地忽略)来浪费这个机会。不要妄想用你的痛苦程度来打动他们,而应该是使用极简单扼要的描述方式来提出问题。

一个好标题范例是“目标+差异”式的描述,许多技术支持组织就是这样做的。在目标部分指出是哪一个或哪一组东西有问题,在差异部分则描述与期望的行为不一致的地方。

蠢问题:救命啊!我的笔记本电脑不能正常显示了!

聪明问题:X.org 6.8.1 的鼠标指针会变形,某牌显卡 MV1005 芯片组。

更聪明问题:X.org 6.8.1 的鼠标指针,在某牌显卡 MV1005 芯片组环境下 - 会变形。

编写“目标+差异”式描述的过程有助于你组织对问题的细致思考。是什么被影响了? 仅仅是鼠标指针或者还有其它图形?只在 X.org 的 X 版中出现?或只是出现在 6.8.1 版中? 是针对某牌显卡芯片组?或者只是其中的 MV1005 型号? 开发人员也许只需瞄一眼就能够立即明白你的环境和你遇到的问题。

使用清晰、正确、精准且合乎语法的语句

我们从经验中发现,粗心的提问者通常也会粗心地写程序与思考(我敢打包票)。回答粗心大意者的问题很不值得,我们宁愿把时间耗在别处。

正确的拼写、标点符号和大小写是很重要的。一般来说,如果你觉得这样做很麻烦,不想在乎这些,那我们也觉得麻烦,不想在乎你的提问。花点额外的精力斟酌一下字句,它必须很准确,而且有迹象表明你是在思考和关注问题。

你可以犯点拼写和语法上的小错,但决不能在思考上马虎(没错,我们通常能弄清两者的分别)。同时,除非你知道回复者使用的语言,否则请使用英语书写。

精确地描述问题并言之有物

  • 仔细、清楚地描述你的问题或 Bug 的症状。

  • 描述问题发生的环境(机器配置、操作系统、应用程序、以及相关的信息)。

  • 描述在提问前你是怎样去研究和理解这个问题的。

  • 描述在提问前为确定问题而采取的诊断步骤。

  • 描述最近做过什么可能相关的硬件或软件变更。

  • 尽可能地提供一个可以重现这个问题的可控环境的方法。

尽量去揣测对方会怎样反问你,在你提问之前预先将对方可能提出的问题回答一遍。

以上几点中,当你报告的是你认为可能在代码中的问题时,给对方一个可以重现你的问题的环境尤其重要。当你这么做时,你得到有效的回答的机会和速度都会大大的提升。

Simon Tatham 写过一篇名为《如何有效的报告 Bug》的出色文章。强力推荐你也读一读。

话不在多而在精

你需要提供精确有内容的信息。这并不是要求你简单的把成堆的出错代码或者资料完全拷贝到你的提问中。如果你有庞大而复杂的测试样例能重现程序挂掉的情境,尽量将它剪裁得越小越好。

这样做的用处至少有三点。 第一,表现出你为简化问题付出了努力,这可以使你得到回答的机会增加; 第二,简化问题使你更有可能得到有用的答案; 第三,在精炼你的bug报告的过程中,你很可能就自己找到了解决方法或权宜之计。

别动辄声称找到 Bug

当你在使用软件中遇到问题,除非你非常、非常的有根据,不要动辄声称找到了Bug,因为有可能是你弄错了(比如配置错误)而不是软件本身有问题。

即使你私下非常确信已经发现一个真正的Bug,最好写得像是你做错了什么。如果真的有 Bug,你会在回复中看到这点。这样做的话,如果真有Bug,维护者就会向你道歉,这总比你惹恼别人然后欠别人一个道歉要好一点。

描述问题症状而非你的猜测

告诉开发人员你认为问题是怎样造成的并没什么帮助。因此要确信你原原本本告诉了他们问题的症状,而不是你的解释和理论;让他们自己来推测和诊断。如果你认为陈述自己的猜测很重要,清楚地说明这只是你的猜测,并描述为什么它们不起作用。

蠢问题

我在编译内核时接连遇到 SIG11 错误, 我怀疑某条飞线搭在主板的走线上了,这种情况应该怎样检查最好?

聪明问题

我的组装电脑是 FIC-PA2007 主机板搭载 AMD K6/233 CPU(威盛 Apollo VP2 芯片组), 256MB Corsair PC133 SDRAM 内存,在编译内核时,从开机 20 分钟以后就频频产生 SIG11 错误, 但是在头 20 分钟内从没发生过相同的问题。重新启动也没有用,但是关机一晚上就又能工作 20 分钟。 所有内存都换过了,没有效果。相关部分的标准编译记录如下…

按发生时间先后列出问题症状

问题发生前的一系列操作,往往就是对找出问题最有帮助的线索。因此,你的说明里应该包含你的操作步骤,以及机器和软件的反应,直到问题发生。在命令行处理的情况下,提供一段操作记录(例如运行脚本工具所生成的),并引用相关的若干行记录会非常有帮助。

如果挂掉的程序有诊断选项(如 -v 的详述开关),试着选择这些能在记录中增加调试信息的选项。记住,多不等于好。试着选取适当的调试级别以便提供有用的信息而不是让对方淹没在垃圾信息中。

描述目标而不是过程

如果你想弄清楚如何做某事(而不是报告一个 Bug),在开头就描述你的目标,然后才陈述重现你所卡住的特定步骤。

寻求技术帮助的人有时候会在他们在自以为能达到目标的特定道路上被卡住,然后跑来问该怎么走,但没有意识到这条路本身就有问题。结果要费很大的劲才能搞定。

蠢问题

我怎样才能从某绘图程序的颜色选择器中取得十六进制的 RGB 值?

聪明问题

我正试着用替换一幅图片的色码(color table)成自己选定的色码,我现在知道的唯一方法是编辑每个色码区块(table slot), 但却无法从某绘图程序的颜色选择器取得十六进制的 RGB 值。

第二种提问法比较聪明,你可能得到像是建议采用另一个更合适的工具的回复。

清楚明确的表达你的问题以及需求

漫无边际的提问是近乎无休无止的时间黑洞。最有可能给你有用答案的人通常也正是最忙的人(他们忙是因为要亲自完成大部分工作)。这样的人对无节制的时间黑洞相当厌恶,所以他们也倾向于厌恶那些漫无边际的提问。

如果你明确表述需要回答者做什么(如提供指点、发送一段代码、检查你的补丁、或是其他等等),就最有可能得到有用的答案。因为这会定出一个时间和精力的上限,便于回答者能集中精力来帮你。

要理解专家们所处的世界,请把专业技能想像为充裕的资源,而回复的时间则是稀缺的资源。你要求他们奉献的时间越少,你越有可能从真正专业而且很忙的专家那里得到解答。

询问有关代码的问题时

别要求他人帮你调试有问题的代码,不提示一下应该从何入手。张贴几百行的代码,然后说一声:它不能工作会让你完全被忽略。只贴几十行代码,然后说一句:在第七行以后,我期待它显示 <x>,但实际出现的是 <y>比较有可能让你得到回应。

最有效描述程序问题的方法是提供最精简的 Bug 展示测试用例。什么是最精简的测试用例?那是问题的缩影;一小个程序片段能刚好展示出程序的异常行为,而不包含其他令人分散注意力的内容。总之,测试用例越小越好。

一般而言,要得到一段相当精简的测试用例并不太容易,但永远先尝试这样做的是种好习惯。这种方式可以帮助你了解如何自行解决这个问题 —— 而且即使你的尝试不成功,对方也会看到你在尝试取得答案的过程中付出了努力,这可以让他们更愿意与你合作。

如果你只是想让别人帮忙审查(Review)一下代码,在信的开头就要说出来,并且一定要提到你认为哪一部分特别需要关注以及为什么。

问题解决后,加个简短的补充说明

问题解决后,向所有帮助过你的人发个说明,让他们知道问题是怎样解决的,并再一次向他们表示感谢。

回复标题中包含“已修正”,“已解决”或其它同等含义的明显标记。补充说明不必很长或是很深入;简单的一句“你好,原来是网线出了问题!谢谢大家 – Bill”比什么也不说要来的好。事实上,除非结论真的很有技术含量,否则简短可爱的小结比长篇大论更好。说明问题是怎样解决的,但大可不必将解决问题的过程复述一遍。这种类型的补充也有助于他人在邮件列表、论坛中搜索到真正解决你问题的方案,让他们也从中受益。

思考一下怎样才能避免他人将来也遇到类似的问题,自问写一份文件或加个常见问题(FAQ)会不会有帮助。如果是的话就将它们发给维护者。

这种良好的后继行动实际上比传统的礼节更为重要,也是你如何透过善待他人而赢得声誉的方式,这是非常有价值的资产。

好问题与蠢问题

最后,我将透过举一些例子,来说明怎样聪明的提问;同一个问题的两种问法被放在一起,一种是愚蠢的,另一种才是明智的。

蠢问题

我可以在哪儿找到关于 Foonly Flurbamatic 的资料?

这种问法无非想得到 STFW (Search The Fucking Web)这样的回答。

聪明问题

我用 Google 搜索过 "Foonly Flurbamatic 2600",但是没找到有用的结果。谁知道上哪儿去找对这种设备编程的资料?

这个问题已经 STFW 过了,看起来他真的遇到了麻烦。

蠢问题

我从 foo 项目找来的源码没法编译。它怎么这么烂?

他觉得都是别人的错,这个傲慢自大的提问者。

聪明问题

foo 项目代码在 Nulix 6.2 版下无法编译通过。我读过了 FAQ,但里面没有提到跟 Nulix 有关的问题。这是我编译过程的记录,我有什么做的不对的地方吗?

提问者已经指明了环境,也读过了 FAQ,还列出了错误,并且他没有把问题的责任推到别人头上,他的问题值得被关注。

蠢问题

我的主机板有问题了,谁来帮我?

对这类问题的回答通常是:好的,还要帮你拍拍背和换尿布吗?,然后按下删除键。

聪明问题

我在 S2464 主机板上试过了 X 、 Y 和 Z ,但没什么作用,我又试了 A 、 B 和 C 。请注意当我尝试 C 时的奇怪现象。显然 florbish 正在 grommicking,但结果出人意料。通常在 Athlon MP 主机板上引起 grommicking 的原因是什么?有谁知道接下来我该做些什么测试才能找出问题?

这个家伙,从另一个角度来看,值得去回答他。他表现出了解决问题的能力,而不是坐等天上掉答案。

在最后一个问题中,注意“告诉我答案'和"给我启示,指出我还应该做什么诊断工作"之间微妙而又重要的区别。

事实上,后一个问题源自于 2001 年 8 月在 Linux 内核邮件列表(lkml)上的一个真实的提问。我(Eric)就是那个提出问题的人。我在 Tyan S2464 主板上观察到了这种无法解释的锁定现象,列表成员们提供了解决这一问题的重要信息。

通过我的提问方法,我给了别人可以咀嚼玩味的东西;我设法让人们很容易参与并且被吸引进来。我显示了自己具备和他们同等的能力,并邀请他们与我共同探讨。通过告诉他们我所走过的弯路,以避免他们再浪费时间,我也表明了对他们宝贵时间的尊重。

事后,当我向每个人表示感谢,并且赞赏这次良好的讨论经历的时候,一个 Linux 内核邮件列表的成员表示,他觉得我的问题得到解决并非由于我是这个列表中的名人,而是因为我用了正确的方式来提问。

当你回答问题时

态度和善一点。 问题带来的压力常使人显得无礼或愚蠢,其实并不是这样。

对初犯者私下回复。 对那些坦诚犯错之人没有必要当众羞辱,一个真正的新手也许连怎么搜索或在哪找常见问题都不知道。

如果你不确定,一定要说出来! 一个听起来权威的错误回复比没有还要糟,别因为听起来像个专家很好玩,就给别人乱指路。要谦虚和诚实,给提问者与同行都树个好榜样。

如果帮不了忙,也别妨碍他。 不要在实际步骤上开玩笑,那样也许会毁了提问者,有些可怜的呆瓜会把它当成真的指令。

试探性的反问以引出更多的细节。 如果你做得好,提问者可以学到点东西,你也可以。试试将蠢问题转变成好问题,别忘了我们都曾是新手。

尽管对那些懒虫抱怨一声 RTFM 是正当的,但能给出文档的链接(即使只是建议个 Google 搜索关键词)会更好。

如果你决定回答,就请给出好的答案。 当别人正在用错误的工具或方法时别建议笨拙的权宜之计(workaround),应推荐更好的工具,重新界定问题。

帮助你的团队从问题中学习。 当回复一个好问题时,问问自己如何修改相关文件或常见问题文件以免再次解答同样的问题?接着再向文件维护者发一份补丁。

如果你在研究一番后才作出了回答,展现你的技巧而不是直接端出结果。毕竟授人以鱼不如授人以渔。

鸣谢

原文:http://www.catb.org/~esr/faqs/smart-questions.html

中译:https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way

Last updated

Was this helpful?