如何提出一个高质量的问题()

封面图源自: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 进行重试,或许你执行后问题就解决了,你也就不再需要提出一个问题了。
提出问题 合适的标题
大部分社区,都是以标题的形式在列表展示出来的,像 思否 这种还会在列表展示标签。回答者并不是机器人,大多数时候,回答者并不会打开所有帖子进行查看,起一个合适的标题更能让回答者判断这个问题是否在自身的解决范围之内,从而点开。
不好的例子
  • 求求大佬解答求求大佬解答 - SegmentFault 思否
好的例子
  • 现在常见的不同app互相“监听”用户需求是怎么实现的呢? - SegmentFault 思否
  • 编写一个js算法,用一次循环将数组中出现2次或者以上的值删掉 - SegmentFault 思否
高质量的问题描述
在你的问题被解决前,你需要做的最终重要的一件事,就是让回答者知道你在问什么,否则别人很难给你答复。
正如思否的提问模板一样:
  • 你遇到了什么问题?
  • 你的预期是什么?
  • 你的环境是什么(运行的软件版本、操作系统)?
  • 你做了哪些工作?
  • 出现问题的代码
按照上面的规则,描述你的问题,让回答者能更加清晰的知道你遇到的是什么问题,除此之外,你可能还需要按照提供一些额外信息,来帮助回答者更快的帮你解决问题,毕竟帮回答者节约时间,也是给你自己节约时间。
学习使用 Markdown 语法,这花不了你多少时间,顶多十分钟,但是终生受益。
  • 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##*.}
  • X-Y Problem | 酷 壳 - CoolShell
帮助回答者 在提问的时候,你可以多为回答者考虑一些,比如通过一些在线服务,让回答者无需在本地环境上操作。
比如前面提到的数据库问题,我们就可以使用 db-fiddle 来创建一个在线的 MySQL 运行环境,填写完成后点击 Run 确认 OK 后,再点击 Save 将会为你生成一个唯一的链接地址,现在别人打开这个链接,就可以在这上面直接编辑操作,方便了许多。
如何提出一个高质量的问题()
文章图片

除此之外,像前端还可以使用
  • CodePen: Online Code Editor and Front End Web Developer Community
  • jsfiddle
这俩个都是国外的服务,可能比较难打开,你也可以选择国内的:
  • 小闪电 - JSRUN可以用手机写代码的JS在线编辑器网站
如果你的问题比较复杂,你可能还要考虑提供一个「最小的可重现示例(Minimal reproducible example)」将其提交到 Git 服务,以提供给回答者。(?? 我想一般也不会复杂到这个程度)
复杂情况
还有一个问题,就是问题很小,但是代码很多。
常见于现代化前端的 CSS 问题,很多时候,问题是在项目或者某个组件中发生的,而即便是你提供了这个组件的代码,回答者也不能很好的复现问题,比如你的 DOM 可能是由数据渲染出来的。
这种情况,提问的时候,就应该把渲染后的结果+能够复现的最少的代码贴上来,这样更容易复现问题。
或者,可以使用一些浏览器扩展,把页面保存成单个 HTML 文件,上传到免登录/注册的网盘或者 Git 上。
比如 SingleFile ,这个扩展就可以把网页所有内容保存成一个 HTML 文件,从而让回答者更加容易复现问题。
(当然,你也应该尽可能的提供原始代码)
gildas-lormeau/SingleFile: Web Extension for Firefox/Chrome/MS Edge and CLI tool to save a faithful copy of an entire web page in a single HTML file
Playground 或者 Sandbox
对于一些冷门点儿的语言,上面的这些工具,可能覆盖不到,但是你也可以尝试搜索 语言 Playground ,大概率可以找到一些可以在线编辑、运行、分享的服务,比如 Laravel playground
维护好你的问题 很多时候,我都能在不同的社区看到同一个问题,毫无疑问,这个问题也是同一个人提的。
当然,多个地方就多了一分解决问题的机会,但是这些提问者往往都少有去 “维护” 自己的问题。
维护一个问题,往往比提出一个问题,更为重要。
1、及时回应/补充你的问题,有些人可能是第一次提问,遗漏了一些东西,有时候就会有人提醒你,需要补充哪些信息,请及时处理。像思否,默认情况下就会邮件通知到你。
2、与回答者沟通,如果你的问题描述的不是那么完美无瑕,或者回答者理解偏差导致给出了错误的回答,你应该及时的跟回答者进行沟通,而不是无视别人。
这样也可以让其他回答者知道具体的情况,对于我个人而言,如果一个问题,提问者自己没有维护这个问题,那么即使我有解决方案,我也不会选择去回答。
3、不要重复提问,当你的问题几个小时或者一两天过去之后,仍然没有人回答,请不要尝试再重复提问,因为很有可能不是别人没看到,而正是因为前面的种种原因叠加。当然,也有可能你的问题太过深奥,无法给你回答。你还可以尝试邀请一些人进行回答。
4、选择合适的答案,当你的问题被解决后,应该选择帮助你解决问题的人的回答标记为答案。这样也可以很好的帮助其他人在遇到这个问题的时候,及时找到正确答案。
5、找到解决方案后应当附上,如果回答里面的都不能解决你的问题,最终你自己解决了,也应该附上答案。
6、同步解决方案,正如前面提到的,很多人都会在 N 个论坛发出同样的提问,而往往可能只是其中某个论坛的回答者解决了问题,而其他论坛则未解决。作为提问者,你应该像你当初提出问题那样,把正确的答案同步到你曾经发出过这个问题的地方,为后来者提供便利。
你做了什么? 除了上面的以外,提出一个问题的前提是,你应该尽可能在自己的能力范围内去尝试解决他,比如通过搜索引擎检索、尝试已有的方案、编写相应的代码,或许在这些过程中,你的问题就已经解决了。
好的
  • 编写一个js算法,用一次循环将数组中出现2次或者以上的值删掉 - SegmentFault 思否
写在最后
  • 以上论点仅为个人观点,如果有不足或错误,还请不吝赐教。
  • 你还可以点击文章中的来源链接,了解更详细的内容。
  • 如果文中的内容侵犯到了你得权益,请与我联系处理。
参考
  • X-Y Problem | 酷 壳 - CoolShell
  • Markdown 基本语法 | Markdown 官方教程
  • How-To-Ask-Questions-The-Smart-Way/README-zh_CN.md at main · ryanhanwu/How-To-Ask-Questions-The-Smart-Way
  • 关于 Markdown | Learning-Markdown (Markdown 入门参考)

    推荐阅读