Review_Week3 - 如何像程序员一样思考 — 问题解决的课程

How to think like a programmer — lessons in problem solving

By Richard Reis

If you’re interested in programming, you may well have seen this quote before:
如果你对编程感兴趣,你可能在此之前已经见过以下引用:

“Everyone in this country should learn to program a computer, because it teaches you to think.” — Steve Jobs
“在这个国家的每一个人都应该学习编程,因为它会教会你如何思考。” – 史蒂夫.乔布斯

You probably also wondered what does it mean, exactly, to think like a programmer? And how do you do it??
你可能会想知道像一个程序员一样思考是什么意思?如何才能做到?

Essentially, it’s all about a more effective way for problem solving.
实际上,这其实主要是关于如何解决问题的一种高效的方式。

In this post, my goal is to teach you that way.
在这篇文章中,我的目的主要是教你们这个方法。

By the end of it, you’ll know exactly what steps to take to be a better problem-solver.
到文章的末尾,你们将会知道采取什么步骤可以更高效解决一个问题。

Why is this important?
为啥这个这么重要呢?

Problem solving is the meta-skill.
解决问题是一种元认知技能。

We all have problems. Big and small. How we deal with them is sometimes, well…pretty random.
我们都会遇到问题。大问题和小问题。有时我们如何处理这些问题都是随机的。

Unless you have a system, this is probably how you “solve” problems (which is what I did when I started coding):
除非你有一个系统,也就是你如何解决问题(这也是我最初开始编程时候做的):

Try a solution.
尝试一个方法。
If that doesn’t work, try another one.
如果它不能工作,换一个试试。
If that doesn’t work, repeat step 2 until you luck out.
如果还不行,重复步骤2直到你很幸运的找到解决方法。

Look, sometimes you luck out. But that is the worst way to solve problems! And it’s a huge, huge waste of time.
看吧,有时候你还是很幸运的。但这是一种最差的解决问题的方法!并且,这种方法非常非常的浪费时间。

The best way involves a) having a framework and b) practicing it.
最佳的方法应该是 a)有一个框架 b)不断练习。

“Almost all employers prioritize problem-solving skills first.
“基本上所有的雇员都优先把解决问题的技能放在第一位。

Problem-solving skills are almost unanimously the most important qualification that employers look for….more than programming languages proficiency, debugging, and system design.
解决问题的技能几乎是所有雇主寻找的最重要的特质,相比起程序语言的熟练,代码调试和系统设计来说。

Demonstrating computational thinking or the ability to break down large, complex problems is just as valuable (if not more so) than the baseline technical skills required for a job.” — Hacker Rank (2018 Developer Skills Report)
“能被证实的计算能力或者是将一个大的复杂的问题拆分的能力相比起一份工作所需的基本技术技能要更有价值,或者更甚。”— Hacker Rank (2018 Developer Skills Report)

Have a framework
拥有一个框架
To find the right framework, I followed the advice in Tim Ferriss’ book on learning, “The 4-Hour Chef”.
找到一个合适的框架,我遵循 Tim Ferriss的书《The 4-Hour Chef》学习到。

It led me to interview two really impressive people: C. Jordan Ball (ranked 1st or 2nd out of 65,000+ users on Coderbyte), and V. Anton Spraul (author of the book “Think Like a Programmer: An Introduction to Creative Problem Solving”).
它指引我面试了两个印象非常深刻的人:C. Jordan Ball(Coderbyte上65,000+的用户中排名数一数二)和 V. Anton Spraul(书《Think Like a Programmer: An Introduction to Creative Problem Solving》的作者)。

I asked them the same questions, and guess what? Their answers were pretty similar!
我问了他们相同的问题,你猜怎么着?他们的答案非常相似!

Soon, you too will know them.
很快你就会会知道了。

Sidenote: this doesn’t mean they did everything the same way. Everyone is different. You’ll be different. But if you start with principles we all agree are good, you’ll get a lot further a lot quicker.
旁注: 这并不意味着他们都是按照同样的方式做事。每个人都不一样。你是独一无二的。但如果你一开始遵循我们认为好的原则,你将会收获更快的成长速度。

“The biggest mistake I see new programmers make is focusing on learning syntax instead of learning how to solve problems.” — V. Anton Spraul
“我所见过的新手犯的最大的错误就是过于专注语法的学习,而不是去学习如何解决问题。” — V. Anton Spraul

So, what should you do when you encounter a new problem?
所以,当你面对一个新的问题的时候,你会怎么做呢?

Here are the steps:
以下是一些步骤:

  1. Understand 理解
    Know exactly what is being asked. Most hard problems are hard because you don’t understand them (hence why this is the first step).
    搞清楚被问的是什么。大多数难题之所以困难是因为你并没有理解他们(因此,这为什么是第一步)。

How to know when you understand a problem? When you can explain it in plain English.
如何知道你真正理解了一个问题? 当你可以用言简意赅的解释这个问题的时候。

Do you remember being stuck on a problem, you start explaining it, and you instantly see holes in the logic you didn’t see before?
你还记得当年被一个问题困住的时候,你开始试图向别人解释它,突然你就注意到了你之前忽略的逻辑上的漏洞了?

Most programmers know this feeling.
大多数程序员都有过这种感觉。

This is why you should write down your problem, doodle a diagram, or tell someone else about it (or thing… some people use a rubber duck).
这也是为什么你应该写下你的问题,画一个草图或者尝试把问题讲解给别人听(或者别的招术,一些人用橡皮鸭替代)。

“If you can’t explain something in simple terms, you don’t understand it.” — Richard Feynman
“如果你不能言简意赅地把问题解释给别人,你就还没有真正搞明白这个问题。” — Richard Feynman

  1. Plan 计划
    Don’t dive right into solving without a plan (and somehow hope you can muddle your way through). Plan your solution!
    不要在没有计划的情况下直接解决问题(如果不是,希望你可以蒙混过关)。请为你的解决方案制定计划。

Nothing can help you if you can’t write down the exact steps.
谁也帮不了你,如果你不把具体的步骤写下来的话。

In programming, this means don’t start hacking straight away. Give your brain time to analyze the problem and process the information.
在编程方面,这意味着不要马上开始黑客攻击。给你的大脑一些时间去分析这个问题,处理一些信息。

To get a good plan, answer this question:
要制定一个好的计划,请回答这个问题:

“Given input X, what are the steps necessary to return output Y?”
“给定的输入 X, 什么是输出Y的必要的步骤?”

Sidenote: Programmers have a great tool to help them with this… Comments!
旁注: 程序员有一个非常好的工具帮助他们做到这点…注释!

  1. Divide 分解
    Pay attention. This is the most important step of all.
    注意,这是最最重要的步骤。

Do not try to solve one big problem. You will cry.
不要尝试一次解决一个很大的问题。你一定会哭的。

Instead, break it into sub-problems. These sub-problems are much easier to solve.
相反,把它拆解成一些子问题。并且这些子问题要更容易解决。

Then, solve each sub-problem one by one. Begin with the simplest. Simplest means you know the answer (or are closer to that answer).
然后,一次解决每一个子问题。从最简单的开始。最简单意味着你知道答案(或者接近答案)。

After that, simplest means this sub-problem being solved doesn’t depend on others being solved.
除此之外,最简单意味着这个子问题不依赖其他问题的解决。

Once you solved every sub-problem, connect the dots.
一旦你解决了所有子问题,把他们串起来。

Connecting all your “sub-solutions” will give you the solution to the original problem. Congratulations!
把所有的”子问题的解”串起来后将得到原问题的解。恭喜你!

This technique is a cornerstone of problem-solving. Remember it (read this step again, if you must).
这个方法是问题解决的转折。请千万要记住(如果有必要的话,请再读一遍步骤三)。

“If I could teach every beginning programmer one problem-solving skill, it would be the ‘reduce the problem technique.’
“如果我要教给每一个刚踏入编程领域的新人一个解决问题的方法的话,那就是缩小问题规模的技术。
For example, suppose you’re a new programmer and you’re asked to write a program that reads ten numbers and figures out which number is the third highest. For a brand-new programmer, that can be a tough assignment, even though it only requires basic programming syntax.
比如,假设你是一个新手,你被要求写一个程序读取10个数字并找出第三大的数字。对于一个菜鸟来说,这是个难题,尽管它只需要基本的编程语法就可以做到。

If you’re stuck, you should reduce the problem to something simpler. Instead of the third-highest number, what about finding the highest overall? Still too tough? What about finding the largest of just three numbers? Or the larger of two?
如果你被卡住了,你应该先把原问题拆分成简单的子问题。如果不是第三大的数字,而是找到所有数字中最大的一个?还会很难么?找到三个数字中最大一个呢?或者两个数字中最大的一个?

Reduce the problem to the point where you know how to solve it and write the solution. Then expand the problem slightly and rewrite the solution to match, and keep going until you are back where you started.” — V. Anton Spraul
缩小问题的规模旨在你知道如何解决子问题并写出解。然后逐渐延伸扩展问题并重新解决,如此反复直到你回到最初的起点(解决了原始的问题)。” — V. Anton Spraul

  1. Stuck? 卡住了?
    By now, you’re probably sitting there thinking “Hey Richard… That’s cool and all, but what if I’m stuck and can’t even solve a sub-problem??”
    到目前为止,你可能会说: “我说Richard…这个方法并不酷,如果我被问题卡住了,甚至不能解决一个子问题咋办?”

First off, take a deep breath. Second, that’s fair.
首先,深呼吸。然后,当然可以搞定。

Don’t worry though, friend. This happens to everyone!
不要慌,我的朋友。每个人都会遇到过此类情况。

The difference is the best programmers/problem-solvers are more curious about bugs/errors than irritated.
不同之处在于最好的程序员/问题解决者显得更好奇,而不是恼怒。

In fact, here are three things to try when facing a whammy:
实际上,当你遇到难题的时候,这三件事你可以试试:

Debug: 调试
Go step by step through your solution trying to find where you went wrong. Programmers call this debugging (in fact, this is all a debugger does).
一步一步的调试你的解直到找到问题所在。程序员称之为debugging(实际上,这都是一个飞蛾给闹的)。

“The art of debugging is figuring out what you really told your program to do rather than what you thought you told it to do.”” — Andrew Singer
“调试的艺术是搞清楚你真正告诉程序去执行的动作,而不是你想当然的事情。” — Andrew Singer

Reassess: 回溯
Take a step back. Look at the problem from another perspective. Is there anything that can be abstracted to a more general approach?
退一步。从另一个角度来观察问题。有没有什么可以被抽象成更一般的方法?
“Sometimes we get so lost in the details of a problem that we overlook general principles that would solve the problem at a more general level. […]
“有时候我们会困在问题的细枝末节中,那是因为我们忽略了通用适用于各个级别的解决问题的原则”

The classic example of this, of course, is the summation of a long list of consecutive integers, 1 + 2 + 3 + … + n, which a very young Gauss quickly recognized was simply n(n+1)/2, thus avoiding the effort of having to do the addition.” — C. Jordan Ball
经典例子如下,求连续整数的和,1 + 2 + 3 + … + n, 年轻的高斯识别出是 n(n+1)/2, 避免了用于加法的额外运算。” — C. Jordan Ball

Sidenote: Another way of reassessing is starting anew. Delete everything and begin again with fresh eyes. I’m serious. You’ll be dumbfounded at how effective this is.
旁注:另一种重新评估的方法是重新开始。删除剩余的所有东西,我是认真的。

Research: 研究
Ahh, good ol’ Google. You read that right. No matter what problem you have, someone has probably solved it. Find that person/ solution. In fact, do this even if you solved the problem! (You can learn a lot from other people’s solutions).
啊,好啊,谷歌。你读的是对的。无论你的问题是啥呢么,别人早就解决了。找出那个人或者问题的解。实际上,即使你解决了这个问题,也要这样做!

Caveat:警告
Don’t look for a solution to the big problem. Only look for solutions to sub-problems. Why? Because unless you struggle (even a little bit), you won’t learn anything. If you don’t learn anything, you wasted your time.
不要花时间去找规模很大的问题的解。只寻找子问题的解。为啥呢?因为除非你挣扎(尽管可能一丁点儿),否则你不会学到任何东西,如果你不学习,那么就是在浪费时间。

Practice 练习
Don’t expect to be great after just one week. If you want to be a good problem-solver, solve a lot of problems!
不要期望在仅仅过了一个星期后就会很好。如果你想成为一个问题的解决者,你还需要解决很多问题!

Practice. Practice. Practice. It’ll only be a matter of time before you recognize that “this problem could easily be solved with.”
练习,练习,再练习。在你发现“这个问题可以被快速的解决”前只是一个时间的问题。

How to practice? There are options out the wazoo!
如何练习?有很多选择!

Chess puzzles, math problems, Sudoku, Go, Monopoly, video-games, cryptokitties, bla… bla… bla….
国际象棋,数学问题,数独,围棋,强手游戏,电子游戏,以太猫等等。

In fact, a common pattern amongst successful people is their habit of practicing “micro problem-solving.” For example, Peter Thiel plays chess, and Elon Musk plays video-games.
实际上,一个成功人士的通用的模式就是他们训练“解决微问题”。比如Peter Thiel 玩象棋, Elon Musk 打游戏。

“Byron Reeves said ‘If you want to see what business leadership may look like in three to five years, look at what’s happening in online games.’
Byron Reeves说:“如果你想看看未来3到5年的商业领导力可能是什么样子,看看网络游戏中发生了什么吧。”

Fast-forward to today. Elon [Musk], Reid [Hoffman], Mark Zuckerberg and many others say that games have been foundational to their success in building their companies.” — Mary Meeker (2017 internet trends report)
回到今天。Elon Musk、Reid Hoffman、Mark Zuckerberg,还有其他人说过游戏是他们成功建立公司的基础。“ — Mary Meeker (2017 internet trends report)。
Does this mean you should just play video-games? Not at all.
这是不是意味着你要打游戏?并非如此。

But what are video-games all about? That’s right, problem-solving!
但是什么是电子游戏呢?对了,解决问题!

So, what you should do is find an outlet to practice. Something that allows you to solve many micro-problems (ideally, something you enjoy).
所以,你要做的就是找到一个练习的途径。可以能让你解决许多微问题(理想情况下,你喜欢的东西)。

For example, I enjoy coding challenges. Every day, I try to solve at least one challenge (usually on Coderbyte).
比如,我喜欢程序挑战赛。每天我都要尝试解决至少一个挑战(通常在Coderbyte上)。

Like I said, all problems share similar patterns.
正如我所说的,所有问题都有一个相似的模式。

Conclusion 总结
That’s all folks!
这些就是全部了!

Now, you know better what it means to “think like a programmer.”
现在你对”像程序员一样思考“理解的更深刻一些了。

You also know that problem-solving is an incredible skill to cultivate (the meta-skill).
你也知道解决问题是一种难以置信的技能(元技能)。

As if that wasn’t enough, notice how you also know what to do to practice your problem-solving skills!
似乎这还不够,你也知道如何去实践解决问题的技巧!

Phew… Pretty cool right?
恩,很酷对吧?

Finally, I wish you encounter many problems.
最后,我祝愿你们面对很多问题。

You read that right. At least now you know how to solve them! (also, you’ll learn that with every solution, you improve).
你阅读这个就对了。至少现在你知道如何解决问题(同时,你会发现在每一个解决方案中,你都会改进)。

“Just when you think you’ve successfully navigated one obstacle, another emerges. But that’s what keeps life interesting.
就在你认为你已经成功地越过了一个障碍时,另一个又出现了。但这就是让生活变得有趣的原因。

Life is a process of breaking through these impediments — a series of fortified lines that we must break through.
生活是一个突破这些障碍的过程——我们必须突破一系列的强化路线。

Each time, you’ll learn something.
每一次你都会学到新东西。

Each time, you’ll develop strength, wisdom, and perspective.
每一次,你都将发展力量、智慧和眼界。

Each time, a little more of the competition falls away. Until all that is left is you: the best version of you.” — Ryan Holiday (The Obstacle is the Way)
每一次,更多的竞争就会消失。直到剩下的是你:最好的版本的你。”— Ryan Holiday (The Obstacle is the Way)

Now, go solve some problems!
现在去解决问题吧!

And best of luck
祝你好运

Special thanks to C. Jordan Ball and V. Anton Spraul. All the good advice here came from them.
特别感谢C. Jordan Ball 和 V. Anton Spraul。所有的好的建议都出自他俩。

Also, all the programming knowledge I’ve acquired in such a short time wouldn’t have happened without Lambda School. Can’t thank/ recommend them enough.
同样,我在这么短的时间内获得的所有编程知识不会在没有Lambda School的情况下发生。不能感谢/推荐他们。

------本文结束感谢阅读------
坚持原创技术分享,您的支持将鼓励我继续创作!
显示 Gitment 评论