提问的智慧(中国版):程序员如何有效提问与高质量回答

写在前面

Eric S. Raymond 与 Rick Moen 写过一篇非常有名的文章——How To Ask Questions The Smart Way,中文通常翻译为《提问的智慧》。

这篇文章最早可以追溯到2001年。截至本文更新时,官网显示的最新版本仍是2014年5月21日发布的3.10版。

原文中的很多原则到现在依然适用,但这些年技术社区已经发生了很大变化。除了邮件列表、论坛和 Stack Overflow,我们现在还会使用 GitHub Issues、GitHub Discussions、微信群、QQ群、Slack、Discord,以及各种AI工具。

因此,本文不是对原文的逐字翻译,而是结合国内程序员和技术从业者的实际沟通场景,重新整理的一份本土化版本。

它想解决两个问题:

  1. 遇到技术问题时,怎样提问更容易得到有效回答?
  2. 别人向我们提问时,怎样回答才真正有帮助?

提问不是资格考试,也不是谁比谁高明。一个好问题的价值,在于让别人能够快速理解现状、缩小排查范围,并给出真正可执行的建议。

一、提问之前,先做一些准备

在向同事、技术社区或开源项目维护者提问之前,建议先做几项基础排查。

这不是为了证明你“有资格提问”,而是为了减少无效沟通,让别人更容易帮助你。

1. 先明确自己真正想解决什么

很多人描述了半天现象,却没有说清楚最终目标。

例如:

Nginx应该怎么修改配置?

这个问题缺少目标。你真正想解决的,可能是域名访问出现502、HTTPS证书不生效,或者前端跨域请求失败。

提问之前,先用一句话说明:

我希望实现什么?现在卡在哪里?

这一步还能避免常见的“XY问题”:你真正需要解决的是X,却因为认定Y是唯一方案,最后只围绕Y提问。

2. 搜索已有答案

可以先搜索以下位置:

  • 官方文档、使用手册和常见问题;
  • 项目的README、FAQ和更新日志;
  • GitHub Issues与GitHub Discussions;
  • Stack Overflow及其他技术社区;
  • 搜索引擎中的相关文章;
  • 团队内部文档和历史工单。

搜索时,尽量提取核心关键词,不要直接输入一大段口语描述。

例如,页面显示:

Error establishing a database connection

可以尝试搜索:

WordPress Error establishing a database connection

如果错误与特定环境有关,还可以补充版本、操作系统或者组件名称:

WordPress 6 database connection error MySQL 8

搜索完整报错时,可以给关键错误信息加引号。使用国外框架或开源项目时,优先尝试英文关键词,通常更容易找到官方文档和原始讨论。

不必争论哪个搜索引擎一定更好。中文本地化问题、国外开源项目和特定产品,适合使用的搜索渠道可能并不一样。关键是使用准确的关键词,并优先核对官方资料。

3. 自己做一次基础排查

在提问前,可以尝试:

  • 重启相关服务;
  • 检查日志和完整错误信息;
  • 对照正常环境与异常环境;
  • 回想最近修改过哪些配置;
  • 更换账号、浏览器或网络测试;
  • 回退最近的改动;
  • 在测试环境中复现问题;
  • 将复杂问题缩小到最小范围。

即使最后没有解决,你也能排除一些可能性,并为提问准备更多有效信息。

“我不知道为什么不能用”和“我已经排除了网络、权限和数据库连接,目前问题集中在应用启动阶段”,给回答者提供的信息完全不同。

4. 合理使用AI,但不要把AI答案当成结论

现在也可以先让AI帮助分析错误、解释日志、整理搜索关键词或者生成排查清单。

但需要注意:

  • 优先使用AI帮助理解问题,不要盲目执行生成的命令;
  • 对涉及删除、覆盖、权限和数据库修改的操作进行二次确认;
  • 使用官方文档验证关键结论;
  • 不要上传密码、Token、Cookie、私钥、客户资料和公司机密代码;
  • 把AI建议作为排查线索,而不是最终事实。

如果AI已经给过建议,可以在提问时说明哪些方法试过、结果是什么,避免别人重复提供相同方案。

5. 能复现的话,准备最小可复现示例

如果你认为问题出在代码上,最好准备一个最小可复现示例。

它应该只保留触发问题所必需的代码、配置和依赖,不要直接上传整个项目,更不要公开公司的商业代码。

一个好的最小可复现示例,可以让别人快速运行、看到相同错误并验证解决方案。Stack Overflow也将“帮助别人复现问题”列为高质量提问的重要原则。

二、选择正确的提问渠道

同一个问题,放在不同地方,得到回复的概率可能完全不同。

GitHub Issues适合明确的问题

如果问题来自GitHub上的开源项目,先查看仓库中的:

  • README;
  • CONTRIBUTING;
  • Issue模板;
  • 已有Issues;
  • Discussions;
  • SECURITY.md。

GitHub Issues适合提交:

  • 可以稳定复现的Bug;
  • 明确的功能建议;
  • 文档错误;
  • 需要维护者跟踪和处理的事项。

提交Issue之前,先搜索是否已经有人反馈过相同问题,并按照项目提供的模板填写内容。不要删除模板中的必填信息,也不要用Issue催促维护者提供一对一技术支持。

普通咨询优先使用GitHub Discussions

如果只是询问使用方法、讨论设计思路,或者问题暂时无法确认是不是Bug,项目启用 Discussions 时,可以优先在这里提问。

GitHub官方将Discussions定位为社区问答、信息分享和开放式讨论的平台,而Issues更适合Bug报告和已经明确的改进事项。

安全漏洞不要公开提交Issue

如果发现的是安全漏洞,不要直接在公开Issue中公布漏洞细节、攻击方法和可利用代码。

先检查仓库中的SECURITY.md,或者使用项目提供的私密漏洞报告渠道。部分GitHub仓库支持向维护者私下提交安全漏洞。

Stack Overflow与Stack Exchange

Stack Overflow主要用于编程和软件开发问题,而且问题需要使用英文书写。提问前应确认问题符合社区范围,并准备清晰标题、相关代码和可复现步骤。

Stack Exchange目前包含180多个问答社区,常见的技术站点包括:

  • Stack Overflow:编程与软件开发;
  • Server Fault:服务器与网络管理;
  • Super User:电脑软件、硬件及高级用户问题;
  • Ask Ubuntu:Ubuntu相关问题;
  • Database Administrators:数据库管理;
  • Information Security:信息安全;
  • WordPress Development:WordPress开发。

可以在Stack Exchange站点列表中查找更匹配的社区。

即时聊天群适合快速交流,但不适合沉淀复杂问题

很多项目都有QQ群、微信群、Slack、Discord或其他聊天社区。

即时群聊的优点是反馈快,但消息容易被刷走,也不方便以后搜索。因此,复杂问题最好先整理完整,再发送到群里。

不要连续刷屏、重复@所有人,也不要未经允许私聊维护者。如果问题具有普遍价值,解决后可以整理到论坛、Issue、Discussion或团队知识库中。

三、怎样提出一个高质量问题?

1. 标题要能概括具体问题

不要使用下面这类标题:

  • 在吗?
  • 救命,系统崩了!
  • 求大神帮忙!
  • 为什么不能用?
  • 有人遇到过吗?

这些标题没有提供任何有效信息。

标题最好包含“环境或组件+具体症状+关键条件”。

例如:

不够清楚:

Java项目启动不了

比较清楚:

Spring Boot项目启动时无法连接MySQL

更加清楚:

Spring Boot 3项目升级MySQL驱动后启动失败,提示Communications link failure

好的标题不仅方便别人快速判断自己能不能回答,也能帮助以后遇到相同问题的人通过搜索找到答案。

2. 先说目标,再说问题

不要一上来就贴几百行代码或者整段日志。

先用一两句话说明:

  • 你正在做什么;
  • 想达到什么结果;
  • 目前出现了什么问题。

让回答者先理解上下文,再看代码和日志,沟通效率会高很多。

3. 提供完整环境信息

技术问题往往与环境有关,建议说明:

  • 操作系统及版本;
  • 软件、框架和依赖版本;
  • 部署方式;
  • 浏览器或客户端版本;
  • 数据库类型及版本;
  • 本地环境还是生产环境;
  • 问题从什么时候开始出现。

不要只说“使用的是最新版”。你认为的最新版,可能和别人理解的完全不同,最好写出具体版本号。

4. 说明预期结果和实际结果

一个完整的问题至少应该包含:

  • 我原本希望发生什么;
  • 实际发生了什么;
  • 是否每次都会发生;
  • 在什么条件下发生;
  • 是否有正常环境可以对照。

只有错误信息,没有预期结果,别人很难判断这是程序异常、配置问题,还是对功能理解有误。

5. 提供完整报错和关键日志

尽量复制完整的报错文字和调用栈,并使用代码块排版,不要只发一张模糊截图。

日志太长时,可以截取错误发生前后的关键部分,并说明完整日志中是否还有相关异常。

发布前一定要检查并隐藏:

  • 密码;
  • API Key和Token;
  • Cookie及会话信息;
  • 私钥;
  • 用户个人信息;
  • 客户数据;
  • 内网地址和其他敏感配置。

6. 说明自己尝试过什么

不要只写“各种方法都试过了”。

应该具体说明:

  • 修改了什么;
  • 执行了什么命令;
  • 得到了什么结果;
  • 为什么认为这个方法没有解决问题。

即使尝试方向是错的,这些信息也能帮助别人理解你的判断过程。

7. 一次尽量只问一个核心问题

不要在同一个帖子里同时询问数据库、前端、服务器、支付接口和商业方案。

问题太多,回答者很难判断从哪里开始,也不利于以后搜索。不同问题最好拆开提问,并说明它们之间的关联。

8. 礼貌,但不用过度客套

“你好”“请问”“谢谢”可以让沟通更舒服,但不需要写很长的道歉或诉苦。

也不要反复强调“非常急”。你的问题很紧急,不代表社区里的其他人必须优先处理。

如果确实是生产事故,应通过公司内部的值班、工单或付费支持渠道处理,而不是把公共社区当成紧急技术支持。

四、可以直接使用的技术提问模板

问题标题:
用一句话概括环境、问题和关键症状。

我的目标:
我希望实现什么?

实际现象:
现在发生了什么?是否能够稳定复现?

预期结果:
正常情况下应该出现什么结果?

运行环境:
操作系统:
软件或框架版本:
数据库版本:
部署方式:
其他相关依赖:

复现步骤:
1.
2.
3.

完整报错或关键日志:
请使用代码块,并删除密码、Token和隐私信息。

已经尝试:
1. 尝试了什么,结果是什么?
2. 尝试了什么,结果是什么?

最近的改动:
出现问题前修改过哪些代码、配置、依赖或环境?

具体问题:
我目前无法确定的是哪一点?希望得到什么帮助?

这个模板不一定要全部填写,但信息越完整,别人越容易定位问题。

五、不要急着宣布“我发现了一个Bug”

遇到异常时,可以说:

我怀疑这可能是一个Bug。

然后提供复现条件、版本信息、实际结果和预期结果。

除非已经稳定复现并排除了配置、环境和使用方式问题,否则不要一开始就认定是项目代码有错。

即使最后证明真的是Bug,也应该客观描述事实。攻击作者、质疑对方能力,不能帮助问题更快解决。

如果需要提交Bug,可以参考 Simon Tatham 的《如何有效报告Bug》

六、怎样理解别人的回复?

收到“看文档”或“搜索一下”怎么办?

RTFMSTFW分别是让人阅读手册、搜索网络的粗鲁说法,其中含有不适合正式交流的词语。

如果对方指出了具体文档、关键词或章节,可以先沿着线索继续查找;如果回复只有嘲讽,没有任何有效信息,也不必把它当成“最好的答案”。

更好的回复方式应该是:

这个问题在官方文档的“连接配置”章节有说明,可以搜索connection timeout。如果看完仍然无法解决,请补充当前版本和完整报错。

技术社区应该鼓励自主解决问题,但不代表羞辱新手是合理的。

面对无礼或错误的回复

先判断回复中有没有可以验证的信息,不要因为语气不好就完全忽略技术线索,也不要因为对方语气坚定就直接相信。

对于可能造成数据丢失、服务中断或安全风险的命令,执行前一定要理解它的作用,并做好备份。

如果对方只有人身攻击,可以停止争论,使用平台的举报、屏蔽或管理员处理机制。把精力放回问题本身,通常比争个输赢更有价值。

七、问题解决后,不要直接消失

如果别人提供的方法解决了问题,应该回复最终结果:

  • 哪个方法有效;
  • 问题的真正原因是什么;
  • 最终修改了哪些内容;
  • 是否还有需要注意的地方。

在问答平台上,可以接受正确答案或标记问题已经解决;在GitHub中,可以补充验证结果并关闭Issue;在聊天群里,也可以简单说明已经解决。

如果问题比较复杂,可以整理成一篇文章、FAQ或团队文档。这样不仅能帮助后来者,也能让自己的排查过程真正沉淀下来。

八、如何更好地回答别人?

会提问很重要,会回答同样重要。

1. 先解决问题,再解释原理

回答技术问题时,可以先给出最关键的判断或下一步操作,再解释原因。

例如:

先检查应用实际监听的端口是否与Nginx配置一致。出现502时,通常需要分别确认上游服务是否启动、端口是否可访问,以及Nginx错误日志中的具体信息。

这样既方便对方立即排查,也能帮助他理解思路。

2. 区分事实、推测和经验判断

如果已经确定,就说明依据;如果只是推测,可以明确写:

  • “从这段日志来看,可能是……”
  • “我暂时无法确认,建议先检查……”
  • “在某个版本中我遇到过类似问题,但需要核对你当前的版本。”

不确定并不可耻。一个语气坚定但结论错误的回答,往往比暂时没有答案更危险。

3. 不要羞辱新手

新手可能不知道如何搜索、怎样复制日志,甚至不知道应该提供版本号。

可以指出问题缺少信息,但没有必要通过嘲讽来证明自己更专业。

比起回复“这都不会”,更有效的说法是:

目前的信息还不能定位问题,请补充操作系统、软件版本、完整报错和复现步骤。

4. 用问题帮助对方缩小范围

有时候,直接给答案不如提出几个关键问题:

  • 这个问题能否稳定复现?
  • 最近修改过什么?
  • 正常环境和异常环境有什么区别?
  • 本地可以运行,还是只有服务器上失败?
  • 日志中最早出现的异常是什么?

探索性提问可以帮助对方建立排查思路,但不要把交流变成审问。

5. 对危险操作明确提示风险

涉及删除文件、修改数据库、重置权限、覆盖配置或者重启生产服务时,要明确说明:

  • 操作可能造成什么影响;
  • 是否需要备份;
  • 适用于什么环境;
  • 如何验证目标;
  • 出现问题后怎样回退。

不要把危险命令当成玩笑发给新手,因为对方可能真的会执行。

6. 不只给结果,也说明判断过程

如果条件允许,可以说明:

  • 你根据哪条日志作出判断;
  • 为什么先检查这个位置;
  • 哪些可能性已经被排除;
  • 如何验证修复是否真正有效。

答案中的推理过程,往往比一条孤立的命令更有长期价值。

7. 重复出现的问题,应该改进产品或文档

如果很多人都在询问同一个问题,不一定都是用户没有认真看文档,也可能说明:

  • 错误提示不够清楚;
  • 默认配置不合理;
  • 安装流程容易误解;
  • 文档入口太难找到;
  • FAQ没有覆盖真实使用场景。

一个好问题不仅能帮助提问者,也可能暴露软件、流程和文档中需要改进的地方。

总结

高质量提问的核心,不是使用多少专业术语,而是让别人快速理解以下内容:

  • 你想做什么;
  • 现在发生了什么;
  • 正常情况下应该怎样;
  • 问题出现在哪个环境;
  • 你已经做过哪些排查;
  • 你具体希望别人帮助什么。

高质量回答的核心,则是减少不确定性,并给出安全、清楚、可以验证的下一步。

提问者尊重回答者的时间,回答者也尊重提问者遇到的困难。双方都把注意力放在事实、证据和解决问题上,技术交流才会真正有效。

正文完
 0
简子
版权声明:本站原创文章,由 简子 于2022-12-19发表,共计6124字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。