众所周知,优秀的程序员会构建惊人的功能、网站、应用程序等。但是它们有什么共同点呢?
在我的研究中,这不仅仅是真正了解一门语言或具有特定的教育背景。而是真正有才华的程序员已经掌握了基础知识。这个基础使他们能够建造伟大的东西并提出突破性的想法。
想想金字塔。它有一个大的底座,但逐渐变小变薄到顶部。学习编程的基础知识构成了基础。一切都从那里起飞。
那么这些基本面是什么?根据我的经验和我研究过的程序员的背景,我认为编程基础知识是一个由两部分组成的方法。
非凡的问题解决者
首先,你必须成为一个有效的问题解决者。这是一个重要的起点,因为编程是解决问题的。
虽然有很多方法可以解决问题,但这个过程的几个部分对我来说很突出。程序员也是伟大的问题解决者,他们提炼出问题的本质,以确定他们的总体目标,并以目的开始问题。然后,他们将每个问题分解成小的、可管理的部分——依次攻击每个部分,有时通过绘制图片来使其成为“真实世界”。
这个过程比听起来更难。当我开始编程时,我碰壁了:像许多其他人一样,我从未在学校学会如何解决问题;这是一项不容易教授的技能。我在数学课上得到了一个问题集,然后就一头扎进去了,这就是我开始编程时所做的。不出所料,我不必要地转动轮子,并在最简单的问题上遇到障碍。
当我开始学习解决问题的过程以及如何有效地解决问题时,事情开始发生变化。我现在开始一个意图问题。我有乔治·波利亚(George Polya)的书《如何解决它》(How to Solve It),感谢你的建议。
我已经将Polya的一些想法应用于编程,比如理解问题。“必须理解这个问题,”波利亚写道。这包括能够“指出问题的主要部分,未知,数据和条件”。对于每个问题,我都会拿出一张纸,写下这些问题的答案:我在解决或试图找到什么?(未知);我得到了什么?(数据);我需要注意哪些限制或细节?(条件)。
理解问题似乎很明显,但显而易见的事情很容易被忽视。不止一次,我在一个问题上投入了几个小时,但后来才意识到我错过了问题陈述中一个小但关键的细节。写出问题细节会让我在精神上放慢速度,并帮助我思考我需要做什么,这是成功的一半。
从那里,我制定一个计划,这是Polya的另一个建议。这是有道理的。我在写文章之前先写一个大纲。艺术家在创作绘画本身之前先绘制画作草图。建筑商使用图纸和蓝图来建造房屋。编程也不例外。与其急于做,我需要先考虑我要做什么,并制定一个攻击计划。
有很多方法可以做到这一点。有时我会按数字顺序概述我需要采取的步骤:首先做这个,然后做那个。其他时候,我会使问题可视化。当我学习循环时,我拿出一把杏仁,在一堆杏仁中物理地迭代。这是一个愚蠢的例子,但它帮助我思考了这个问题。
我还会画画或图表。对于递归问题,我将绘制每个递归调用上发生的事情的图表,直到我达到基本情况。然而,几乎总是我会找到一种方法来简化问题,使其更易于管理并帮助我发现模式。最重要的是,我的目标是进入一个有目的的问题,并始终保持这种目标感。
尽管制定了最好的计划,但问题仍然很困难,我仍然陷入困境。成为一个伟大的问题解决者需要时间;这是我仍在努力的一项技能,绝对值得付出努力。这是你可以看到的差异。
当我阅读由一个伟大的问题解决者编写的代码时,它干净且易于理解。变量命名良好。功能简短明了。每行代码都有特定的用途;绒毛被去除。代码的清晰度反映了程序员的思维过程:我可以从上到下阅读程序并确切地知道发生了什么。这是很好的解决问题的方法,这就是我正在努力的目标。
你的电脑呢?
学习计算机科学是第二个编程基础。我最近开始学习计算机科学,并且喜欢它,因为我正在超越表面水平。例如,我将进入“幕后”以了解当我使用内置函数时会发生什么。我还在学习内存和运行时,以及许多其他主题。简而言之,我正在学习为什么计算机会做它所做的事情。
知道“为什么”可以增强我的上下文知识,使我成为一个更知情的程序员。因此,我对我编写的代码更加深思熟虑。例如,现在我对运行时有所了解,我将选择使用二进制搜索,而不是遍历列表中的每个元素。
这也丰富了我对核心编程概念如何工作的理解。例如,我正在处理一个递归问题,但我没有得到我预期的解决方案。经过仔细检查,我明白了原因:这与调用堆栈的执行有关,这个想法在几个月前我就已经逃脱了。
或者上课。我在课堂上挣扎了很长时间,并且害怕使用一个。我知道如何编写一个类,但不确定何时以及为什么使用一个类。当我了解创建实例和调用方法时计算机中实际发生的情况时,情况发生了变化。一旦我有了一定的背景,它终于点击了。对于递归和类,计算机科学弥合了我知识上的差距。
很多时候,基本面被推到一边。进展可能很慢,当有选择时,人们倾向于选择更多“有趣”的东西来工作。真可惜。掌握基础知识的程序员似乎自信地编码:他们知道自己编程选择的“方式”和“原因”,这改善了他们的工作并建立了他们在其他人中的信誉。
此外,对基础知识的扎实掌握使学习新语言和技术更容易。例如,花时间真正理解一种语言的迭代、递归和抽象等核心概念将有助于学习另一种语言。简而言之,掌握基本面可以得到很多,几乎没有什么损失。