我喜欢解决问题,也欣赏能够解决问题的人。

我们通常给这类人的评价是:「靠谱」。

靠谱的人能赢得他人的信任,而大家的信任则是权力的基础。

可以说,解决问题的能力在一定程度上决定了人生的高度。那么,我们该如何提升解决问题的能力呢?

必要性

这个问题需要解决吗?

这是第一个要问的问题。

人的精力和时间是有限的。同一段时间,如果我打了游戏,就无法读书。读书就是打游戏的机会成本,也可以理解为代价。

我在「以少胜多的基本逻辑」中提到了「二八定律」:重要的问题是较少的,但是解决它们能够带来巨大的收益;而不重要的问题则很多,解决它们的效益不甚明显。

老毛在「矛盾论」中写道:

任何过程如果有多数矛盾存在的话,其中必定有一种是主要的,起着领导的、决定的作用,其他则处于次要和服从的地位。因此,研究任何过程,如果是存在着两个以上矛盾的复杂过程的话,就要用全力找出它的主要矛盾。捉住了这个主要矛盾,一切问题就迎刃而解了

如果我们看到任何问题都想要立刻解决,则可能会解决了一些无关痛痒的问题,而忽略掉一些真正重要的问题。这相当于本来应该用来解决主要问题的时间和精力被浪费了。

如何区分主次呢?

四象限

如下图所示,我们可以根据重要和紧急来将事情划到四个象限里去。

那我们游戏来举例。我们已经进入到了线上运营和线下开发并行的阶段,该如何区分问题的优先级呢?

我们将重要定义为能够我们带来巨大价值的事项,紧急表示这件事情需要立刻得到响应。

首先,我们将线上的所有突发情况都定义为紧急情况,但是它们不是都重要。

线上的严重bug,被定义为重要且紧急的事项。因为不及时处理它们会给我们造成很大损失,若处理得当则会挽回我们的损失,从而变相的创造了价值。所以出现了线上严重bug,我们应放下手头工作第一时间来解决。

迭代里的需求,被定义为重要且不紧急的事项。因为产品靠不断迭代来保持活力,所以它很重要。它的期限是两周甚至更长,所以并不紧急。如果线上没有发生严重bug,我们应该第一时间来处理迭代需求。

线上的轻微bug,被定义为不重要且紧急的事项。因为其影响面较小,对我们和玩家带来的损失较小。所以我们可以先将它们收集起来,推后统一处理。

纯玩我们自己的游戏,被定义为既不重要又不紧急的事项。因为单纯的玩而非用心体验并不能创造价值,何况它一点也不紧急。这种事情我们要少做。

我之所以花了很长的篇幅来说一个问题需不需要被解决,是因为选择比努力重要。如果一开始选择了一个错误的方向,越努力只能错的越深。

选择那些对你重要的问题去解决,在这些问题里面优先解决紧急的。

可行性

我很喜欢阿迪达斯的广告语:「impossible is nothing」。

当很多人都告诉你,问题不可能被解决,难道它就真的不能被解决吗?

在「硅谷钢铁侠」中,马斯克极力推崇第一性原理的思考方式。

不要从别人那去求证一件事的可行性,而是遵循物理规则,从基础和源头推导一件事情的可行性。

凭借着这个思考方式,他创立了SpaceX和特斯拉,创造了无数在他人看来不可思议的壮举。

如果确定了问题需要解决,且它不违背物理定律,是可以被解决的,那么让我们开始吧!

理解问题

在「怎样解题」中,波利亚提到:

我们必须理解该题目;我们必须清楚地看到所要求的是什么

在做题前,审题很重要。如果你连题目都不理解,是不可能给出正确答案的。

解决问题也是一样,首先我们要将问题完整清晰的描述一遍,确保自己和其他人都能理解。

在调试代码的时候,有一种方法叫「小黄鸭调试法」。

即向桌上一只橡皮小黄鸭或者一个完全不懂代码的人一遍又一遍的阐述问题,虽然小黄鸭们不会给你有效回应,但是在一遍遍阐述问题的过程中,往往能找到问题解决方法。

完整且清晰的阐述问题,理解问题是解决问题的第一步。

溯源

解决代码的bug需要知道代码为什么会出bug。因为只有知道了为什么,才能稳定地复现这个bug,才能确认bug是否真正得到解决。

对抗疫情,需要知道传染源,知道了源头,才能抽丝剥茧的梳理出整个传染路径。从而选择一个较为简单的点对整个传染链条进行切断。

「为什么思考为什么很重要」我提到了思考「为什么」很重要,因为理解了为什么能带来更加长久和坚固的影响。

为什么这个问题会发生?为什么会发生在这个时间?这个地点?这个场合?为什么是这个地方发生了问题?为什么其他地方没有出问题?……

读书百遍其义自见。

多问几个为什么,在回答为什么的时候,答案也可能自然就会显现。

分治

分治的意思是「分而治之」。

分治法是一种很重要的算法思想:面对一个复杂的问题时,将其分为两个或多个相似的子问题,然后再将子问题分成更小的子问题,直到最后的子问题简单到可以直接求解。然后将子问题的解合并,则得到原来复杂问题的解。

让我来举一个直观的例子:

如上图所示,假设我们的代码位于蓝色的提交。目前代码出问题了,但不知道是哪个提交出的问题。

我们应该如何快速找出错误的提交呢?

如果从上往下,一个一个去查,就太慢了。

我们可以回滚到中间红框的提交,如果它有问题,则证明问题不可能发生在这个提交上面的区域,我们只需要向下查就行了;同理,如果它没问题,这时候往上查就行了。

这是一个二分法查找错误提交的思路,每一次查找都能排除掉一半的选项。

孙子兵法说:「十则围之,五则攻之,倍则分之」。秦灭六国,也是采用分而治之,逐个击破的策略。

分治能够将复杂问题简单化,也很适合团队协作。

将复杂问题分解为简单任务,然后分配给不同的人同时进行处理,可以有效利用团队合作,大大推进问题解决的速度。

观察与推断

面对一些很难找到原因的问题时,我们需要仔细观察,收集更多的线索。

巧妇难为无米之炊,当线索不够时,福尔摩斯也无法断定凶手是谁。

当线索收集的差不多时,如果我们还不能确定问题发生的原因。这时候我们需要加上一点推断。

我在「如何科学的应对恐惧」中提到了「贝叶斯推断」是一种科学的推断方式。其本质是利用观察到的线索将求解空间缩小,然后在缩小的范围内运用想象力或头脑风暴找到最终的原因。

一个月前,我们游戏偶尔会出现整个联盟的人进游戏就闪退的问题。这个问题最诡异的地方在于:其他玩家都正常,只有这个联盟的人进游戏就闪退。

这个问题在线上大概一个礼拜会出现一次,毫无复现规律。

解决它的临时方法也很奇葩,就是踢掉一个人,再加一个人进来,这样重复几次就好了。我们一直没有找到这个问题的真正原因,所以一直不能彻底的解决这个问题。

直到有一天,线上又出现了这种情况,我们仔细查看客户端的错误日志,发现某个文本控件(TMP)报错了。

我瞬间有了一个推断:是主界面的联盟聊天出现了问题。一定是该联盟的人发了一些特殊字符让TMP报错。而之所以踢人再加人能解决问题,是因为踢人和加人会在联盟聊天频道产生记录,从而顶掉之前的聊天记录。由于我们主界面只显示最后3次聊天记录,所以一旦特殊字符的记录被顶掉,该联盟玩家进游戏则不会报错闪退。

事后,我们发现果然如此,一桩悬案就此告破。

我是怎么解决这个问题的呢?首先是线索,只有某联盟会出问题,说明这不是一个普遍问题;加载完毕就闪退,说明是首个场景的问题;文本控件报错,说明是UI问题。

推断范围一步步被缩小到首个场景的UI上,再联系上反复踢和加联盟成员可以解决这个问题,联想到主界面的聊天缩略框便是一个自然的推断。

没有线索,推断便如大海捞针,无从着手;而光有线索,不进行推断,则依然解决不了问题。

所以一方面我们要搜集足够多的线索,来缩小推断范围;一方面我们还要展开想象力去进行合理推断。

变与不变

当一个系统一直可以工作的很好,突然在某一天挂掉时。这时候我们就需要找出变量和不变量,将注意力投射到变量上。

这周三,我们需要在凌晨4点发布一次停服更新。凌晨2点,我们发现登录校验无法通过,报错非常含糊,具体原因未知。

我很着急,因为游戏无法登录,则一切更新都是空谈。看到问题迟迟没有进展,我于是介入了进去。

我首先问客户端,有无相关改动,得到的答复是没有;我再问服务器有无相关改动,服务器也说没有。

再三确认后,我跟他们说了一句话:你们不生产数据,都是数据的搬运工,那么问题肯定不出在你们身上。

于是,我们在半夜将发行公司SDK部的同学叫了起来,发行同学说是不是登录校验超时了。

我们恍然大悟,之前我们登录是直接进游戏,所以不大可能出现超时问题。这一次更新后,我们登录需要选服点击确认进去,所以只要在登陆界面停留超过5分钟,则会触发超时问题。

如果我们一直纠结于不变的地方,想去里面找出个所以然来,而不敢鼓起勇气去直面改变的地方。那么我想问题可能永远也没有进展。

求助

如果真的百思不得其解,各种方式都尝试了,还是没有效果。这时候我们应该鼓起勇气去求助。

求助之前,我们必须要先自助。

熟练使用搜索引擎可以帮助我们,很多问题也许别人早就遇到过了,网上有各种解决方案。

对于中文资料,可能百度更适合;对于技术或者专业资料,则Google是不二之选。

至于如何上Google,百度一下,就会有各种答案。或者花钱买个梯子,则会轻松省事一些。

使用搜索引擎时,学会分词是一件很重要的事情。尽可能的将无关的信息剔除,将语气助词和标点符号去除,则可能会得到更加精确的搜索结果。

如果搜索引擎还不能解决你的问题,那么去专业的论坛提问,或者请教相关的专业人士。

他们的时间很宝贵,所以如果你显现出的是对问题一无所知,或者自己毫无努力的话,那么也许你会得不到回答。

提问需要完整清晰的描述问题过程、表现和自己所做过的尝试,语气需要谦逊。这样的提问能赢得别人的尊重,也能提高被回答的几率。

绕过去

在代码中,有一种快速修正bug的方式,叫「Dirty Hack」。这种修复是临时性的修复,所以它们都称之为脏办法。

脏办法往往是不得已而为之,比如联盟闪退那个例子中,我们反复踢人加人就是一个脏办法。

它们往往能达成目的,但是它们不够可靠,也不能一劳永逸的解决问题。

在时间压力非常大的情况下,我不排斥使用脏办法。但是在时间充裕的情况下,还是应该追根溯源,找到原因,从而对问题进行斩草除根。

绕过去也是一种手段,即使用替代方案。比如说你要去巴黎,飞机是一种方法,坐火车也是一种办法,甚至骑行也是一种办法。

绕过问题,需要你脑子里时刻明白解决这个问题的目的。

条条大路通罗马,并不一定非要解决这个问题才能达到目的。如果通过曲线救国的方式可以达到目的,也不失为一种明智之举。

总结

问题不一定需要立刻解决,如果确定了问题必须要解决,且可以被解决时,那么我们才开始着手解决问题。

我们首先需要描述和理解问题,对于复杂问题可以用分治的手段将复杂问题简单化。

对于疑难问题需要收集足够多的线索,通过科学的推断来找到原因。

对于突发问题,需要区分变量和不变量,将焦点聚焦于变量。

实在得不到解决时,我们需要果断求助,求助前需要先通过搜索引擎自助。

如果短时间内问题无法得到解决,则可以考虑用其他办法绕过去。毕竟,不管黑猫还是白猫,只要能抓到老鼠就是好猫!