如果你对编程感兴趣,你可能看过这句话:

“这个国家的每个人都应该学习计算机编程,因为它会教你思考。” -  Steve Jobs

你很可能想知道这句话是什么意思?以及如何做到?本质上讲,这句话是关于更高效解决问题的方法

在这篇文章中,我的目标是教会你这种方法。读完本文,你将明确知道要采取哪些步骤来成为更好的问题解决者。

为什么这很重要?

解决问题是元技能

我们都面临问题。大的和小的。有时,我们处理它们的方式,呃......很随意。

你需要有一个系统方法,这可能是你“解决”问题的方式(我开始编程时就是这么做的): 1. 尝试一个方案。 2. 如果这不起作用,请尝试另一个。 3. 如果还不起作用,请重复步骤2直到解决。

可能你运气好解决了问题。但这是最糟糕方法!浪费大量的时间。

最佳方法是:a)有一个框架, b)练习掌握这个框架。

“几乎所有雇主都优先考虑解决问题的技能。

相比编程语言的熟练程度、调试和系统设计,解决问题的技能几乎是雇主寻求的最重要的技能。

展示计算思维或将大型、复杂问题拆分的能力与工作所需的基线技能一样有价值(如果不是更多)。” - Hacker Rank(2018年开发人员技能报告

拥有一个框架

为了找到合适的框架,我参考了Tim Ferriss关于学习的书《The 4-Hour Chef》中的建议。

这让我采访了两个人,他们非常令人印象深刻:C.Jordan Ball(在Coderbyte的65000多名用户中排名第一或第二)和V.Anton Spraul《像程序员一样思考:解决创造性问题导论》一书的作者“)。

我问他们同样的问题,猜猜结果如何? 他们的回答非常相似!

很快,你也会认识他们。

旁注:这并不意味着他们对待每件事都用同样的方式。每个人都是不同的,你也和大家不一样。但是如果你遵从我们都认可的原则,你会更快进步。

“我看到新程序员犯下的最大错误就是专注于学习语法,而不是学习如何解决问题。” - V.Anton Spraul

那么,当遇到新问题你该应该怎么做?

下面是步骤:

1. 理解你的问题

明确被问的问题是什么。大多数问题很难是因为你不理解它们(因此这是第一步)。

如何确定你理解了问题?当你能用简单的语言准确描述它,你就理解了这个问题了

你还记得曾经被困在一个问题上,你尝试描述它,却立即发现之前没有考虑到的逻辑漏洞?

大多数程序员都知道这种感觉。

这就是为什么你应该写下你的问题、画画涂鸦,或告诉别人你的问题(或者有些人使用橡皮鸭调试法)。

“如果你不能用简单的术语来解释某事,那你还没理解它。” - Richard Feynman

2. 做好计划

没有计划前就不要开始解决问题。你需要计划你的解决方案。

如果你不能写下明确的步骤,别人就没法帮你。

在编程中,这意味着不要立即开始hacking。给大脑时间来分析问题和处理信息。

要想获得一个好的计划,请回答这个问题:“给定输入X,返回输出Y所需的步骤是什么?”

3. 分割问题

请注意,这是最重要的一步。不要试图解决一个大问题,你会哭的。相反,将其分解为子问题。这些子问题更容易解决。

然后,逐个解决每个子问题。从最简单的开始。最简单意味着你知道答案(或者很接近答案),还意味着要解决的这个子问题不依赖于其它问题。

一旦解决了每个子问题,请连接所有“子解决方案”,你就得到原始问题的解决方案了。恭喜!

这种方法是解决问题的基石。务必记住它(如果有必要,这个步骤要多读几遍)。

“如果我能教会每个初学程序员解决问题的技巧,那就是'减少问题的技巧性'。

例如,假设你是一名程序员新手,被要求编写一个程序:读取十个数字,确定第三大的数字。对于一个全新的程序员来说,这可能是一个艰难的任务,即使它只需要基本的编程语法。

如果你遇到困难,你应该把问题简化为更简单的问题。找到最大的那个数,而不是第三大的数字。还是太难了?那找到三个数字中最大的一个呢?或者两个数中较大的一个?

将问题简化到你知道如何解决,然后写下解决方案。然后稍微扩展问题并重写解决方案以匹配,并继续扩展直到你回到起点。“ - V.Anton Spraul

4. 卡住了?

到现在为止,你可能正坐在那里思考“嘿理查德......这很酷,但是如果我被困住,甚至无法解决一个子问题怎么办?”

首先,深吸一口气。其次,这很公平。因为每个人都会遇到这个情况!

不同之处在于,最好的程序员/问题解决者面对bug/错误时,他们很感兴趣而不是恼火。

事实上,面对打击时可以尝试以下三件事:

调试

逐步执行你的解决方案,尝试找到出错的地方。程序员称这为调用(事实上,这都是调试器做的)。

“调试的艺术是弄清楚你真正告诉程序要做什么,而不是你认为你告诉它要做的事情是什么。” - Andrew Singer

重新评估

退后一步,换个角度看问题。是否有地方可以被抽象为更一般的方法?

“有时我们会在问题的细节上迷失方向,而忽略了在更一般的层面上解决问题这个原则。 当然,这个经典的例子是连续整数求和,1 + 2 + 3 + ... + n,非常年轻的高斯很快就认识到结果是n(n + 1)/ 2,从而避免了冗余计算。“ - C.Jordan Ball

旁注:另一种重新评估方式是重新开始。删除所有内容,然后重新开始。我是认真的,你会惊讶于这个方法很有效。

研究

啊,尝试谷歌。不管你遇到什么问题,有人可能已经遇到并解决了,你要找到那个人/解决方案。事实上,即使你已经解决了问题,也要这样做!(你可以从其他人的解决方案中学到很多东西)。

警告:不要寻找解决这个大问题的方法,只寻找子问题的解决方案。为什么? 因为除非你挣扎(甚至一点点),否则你将无法学到任何东西。如果你什么都不学,那就浪费了你的时间。

练习

不要指望练习一周后就变得更好。如果你想成为一个好的问题解决者,你需要解决很多问题!

实践。实践。实践。在你意识到“这个问题可以通过某个方法解决前”,你需要大量时间来练习。

如何练习?你有很多问题可以选择:国际象棋谜题、数学问题、数独、围棋、大富翁、视频游戏、加密......

事实上,成功人士的共同点是他们有练习“解决微观问题”的习惯。例如,Peter Thiel下棋、Elon Musk玩视频游戏。

“Byron Reeves说:'如果你想看看三到五年里的商业领导力是什么样的,那就看看在线游戏中正在发生什么。'

回到今天,Elon Musk、Reid Hoffman、Mark Zuckerberg和其他许多人都认为游戏是他们在建立公司方面取得成功的基础。” - Mary Meeker(2017年互联网趋势报告

这是否意味着你应该只玩视频游戏?当然不。但是视频游戏到底带给人们什么?解决问题!

所以,你应该做的是找到练习的方法。可以让你解决许多微观问题的东西(理想情况下,是一些你喜欢的东西)。

例如,我喜欢编程挑战。每天,我都尝试解决至少一个问题(通常在Coderbyte上)。

就像我说的,所有问题都有相似的模式。

结论

现在,你更清楚理解什么是“像程序员一样思考”。你也意识到解决问题的能力是一项需要培养的令人难以置信的技能(元技能)。这好像这还不够,请记住如何练习解决问题的能力!

“就在你认为自己已成功驾驭一个问题时,另一个问题出现了。但生活也因此而变得有趣。

生活是突破这些障碍的过程 - 我们也必须突破。

每一次,你都会学到一些。

每一次,你都锻炼力量、智慧和观点。

每一次,竞争会减少一点,直到最后剩下的就是你:最好的你。” - Ryan Holiday(《The Obstacle is the Way》

现在,去解决问题吧,祝你好运。

译者说

本文以“像程序员一样思考”为题,介绍了如何成为合格、优秀的程序员。作者结合两位顶尖程序员的回答、参考一些关于学习的书籍,认为最重要的是培养解决问题的能力/技能,分享了培养这个能力的方法:形成思维框架,然后在实践中不断练习。笔者理解为多刷OJ。

说明