在不浪费时间和金钱的情况下学习编程
本文翻译自 Aleksandr Hovhannisyan 的文章:《Learn to Code Without Wasting Time & Money》,原文:Learn to Code Without Wasting Time & Money | Aleksandr Hovhannisyan
我记得在高中时读过一个短篇小说,讲的是一位有抱负的作家投入大量时间和金钱购买了一支精美的钢笔和一本装帧华丽的笔记本,买了一张只有严肃作家才会坐的桌子,在书房里摆满了他从未读过的旧书,并对写作的前景做了白日梦。这张照片遗漏了任何有墨水的纸张,他什么都做了,就是没有动笔写作。
同样的事情经常发生在想要进入软件开发的初学者身上,他们安装了各种各样的 IDE 和工具,但他们并不真正了解这些工具的用途,他们仔细阅读供初学者学习的最佳编程语言的清单,并且通常将大部分时间花在思考编程和试图提出项目想法上,而不是…嗯,编程。
选择一种语言,任何一种语言
选一个开始学编程就行了…所有现代编程语言都非常强大,它们可以做各种事情。
我记得在我本科学习的第二学期,当我的编程基础老师听到我抱怨我们学习 C++ 时,他传授了一些非常明智的话,在那个时候,C++ 对我来说是完全陌生的,而且伴随着大量的挫折。他说,这个学位的目的不是教我们如何用任何特定的语言编程,语言只是做程序员工作的工具。希望我们毕业后,能够按需学习任何一种语言。我们的目标是学习如何像计算机科学家一样思考,而不是把自己局限在任何特定语言的狭隘背景中。
语言仅仅是程序员工作的工具。
现在,这里有一个值得一提的警告:您作为初学者选择的语言将影响您对软件开发的初始看法,并决定您是最终享受编程,还是失望地离开。
许多大学课程向初学者介绍 Java、C++ 或 Python(就麻省理工学院而言)是有原因的:这三种语言非常流行,并且跨越了许多软件开发领域,这使得了解它们既实用又有用。它们对初学者来说也更容易理解,因为它们是通用语言。
我的建议是:不要仅仅选择一种语言,并拒绝与之分道扬镳(译者注:不要画地为牢)。最明显的原因是,并不是每种语言都适用于所有问题。但除此之外,将您的世界观限制在单一的语言范例上会严重阻碍您作为开发人员的成长。
相反,我建议使用您最喜欢的语言来学习编程基础知识、算法和数据结构,并逐步走出您的舒适区。所有这些东西都是与语言无关的(language agnostic)的,而且能够容易地转移(easily transferable)。一旦您掌握了这些技能,您就会发现学习新的编程语言只是需要习惯新的语法(也许还有一种新的思维方式,比如从面向对象语言转向函数式语言)。
别把钱浪费在你永远学不完的课程上
Udemy,Udacity,Lynda,Vertabelo Academy,Codeacademy Pro 等等。这些东西有什么共同之处呢?它们是在线平台,其目标用户是那些感到不知所措或幻想破灭的希望尽快转行的职场人士。这些平台无处不在,但我认为它们不利于学习如何实际编码,因为它们很少提供比在线上随时可用的免费内容更高质量的材料。
这些课程最大的问题是持续地手把手教学——这是有害的。做你自己的研究,犯错误,破坏你的代码,并学习如何调试,所有这些令人难以置信的有价值的体验将永远伴随着你,并最终让你成为一名更好的程序员。简单地模仿教练所做的可能会帮助你发展肌肉记忆,但它不会给你带来只有第一手经验才能带来的深入理解。
你有没有注意到 Udemy 的课程总是在打折?或者这些平台几乎对每一个问题都有提示,或者讲师直接告诉你如何做某事,或者他们甚至在视频中就在谷歌上搜索了一下,而不是鼓励学生自己研究这些东西?这些都是危险信号。
这些课程中有很多都是被动学习的,即使它们鼓励你一边打字一边在自己的机器上做事情,就像你看到的讲师他们做的那样。为什么?因为你实际上并没有自己发现问题,然后寻找解决这些问题的方法。那就是人们学习的方式——通过经历、好奇心和失败。
在许多这样的平台上,积极学习的面纱很薄(there’s a thin veil of active learning)。实际上,您正在做以下三件事之一:
-
把教师手写的代码都打出来。
-
直接从他们在 GitHub 的仓库上复制粘贴代码或者克隆下来。
-
甚至一行代码也不用写——只是倾听并且希望都能学会(剧透:并不会)。
然后,一周后,你发现自己不得不重温过去的一次练习(甚至是相关的视频)来回忆如何做某事。如果是这样的话,你显然什么都没学到。
在现实世界中,开发人员必须不断地在网上搜索东西,筛选 Stack Overflow 帖子、Reddit、YouTube 教程、文章和官方文档(我敢这么说吗?)以找到他们问题的答案。但是,既然你可以花钱请一位讲师告诉你如何做到这一点,为什么还要费心自己去寻找这些答案呢?那会让你在里面感觉很好很安全。
同样,这些平台还可以让您避免在自己的机器上设置技术(setting up a technology)这一有点棘手(但很有价值)的过程。相反,它们为您提供了一个很好的小沙箱环境,在该环境中,您可以尽情编写代码,而无需了解在编写代码和计算机解释和理解代码之间发生了什么。如果您计划认真投入时间在现实世界中学习和使用一项技术,为什么不花时间了解一下如何在您自己的计算机上使用它呢?
我承认:我确实理解沙箱环境的吸引力。它可以让你专注于重要的事情——学习语言——而不会陷入任何障碍。毕竟,医学院的学生不会在真实的病人身上做手术。但你也不能指望永远给尸体做手术。
以下是我曾经购买的两个 Udemy 课程,当时我认为它们是实现所有目标的关键(显然,是网络开发和游戏开发):
我两次都在大约 10% 进度时放弃了,因为我无聊得发疯了。我不是那种可以忍受坐在一堂又一堂课的前面,伴随着间歇性“现在你试试”练习的人,这些练习大部分都是非常琐碎的。我所做的任何事情都需要一个背景——一个我想要从事的真正相关、有趣和具有挑战性的项目。待办事项列表应用程序不适合我,因为它们不是我真正想要构建的东西。按照别人的方式制作游戏不是我在学习游戏开发时想做的事情。
例如,通过制作我的个人网站,我学习了我所知道的关于 HTML、CSS 和(一些)JavaScript 的几乎所有东西——对我想要的东西有一个想象,然后研究所有必要的部分来实现它。我在自己的时间里,按照自己的方式学习了网络开发和游戏开发。
进入佛罗里达大学的人工智能游戏课程,我对 Unity 游戏引擎或 C#——我们将使用的主要技术——一无所知。我是怎么在这么短的时间里学会它们的?通过开发一款我想出来的游戏,这确实让我很感兴趣。通过谷歌搜索,阅读教程,实际上经历了一个艰苦的过程,试图让一些事情奏效,但在此过程中遇到了障碍。通过与其他开发人员合作-在线课程很少会让您接触到这一点。
你想做什么?弄清楚这一点,然后开始用谷歌搜索。如果你认为学习一门课程对你来说是正确的道路,至少不要浪费你的钱去买一门——网上有很多免费的资源可以带你去你想去的地方。
通过阅读代码学习编程
乐于阅读他人的代码对于任何开发人员来说都是一项基本技能。就像阅读书籍可以让您接触到不同的文学风格、技术、流派和主要主题,从而帮助您成为一名更好的作家一样,阅读代码可以让您接触到不同的解决方案、体系结构、设计模式和语言范例,从而使您成为更好的程序员。
我清楚地记得,当我只有大约一年的编程经验时,我害怕阅读别人的代码。您不熟悉这些代码,所以一切对您来说自然都是陌生的,您会感到沮丧,并质疑作者为什么要使用特定的命名约定或设计模式。如果你有这样的感觉,你可能是在一头扎进一个复杂的项目,而不是把脚趾浸入水中。
以下是我关于如何提高代码阅读技能的建议:
-
加入类似 Stack Exchange 的 Code Review 的站点。初学者(甚至是高级程序员)经常在这里发布他们的代码,供更有经验的开发人员审阅。对于初出茅庐的程序员来说,这是一个非常有价值的资源。我建议你尽可能慢地完整地阅读楼主的代码。然后,查看其他开发人员提供了哪些类型的反馈。了解他们为什么提出这些建议可以帮助您避免在自己的代码中犯类似的错误。如果需要,您可以编写关于常见常见错误和提供的相应建议的列表。然而,随着时间的推移,你不应该需要这样的参考——通过反复暴露于相同类型的问题,这都会成为第二天性。
-
阅读教程。 但需要注意的是:永远不要盲目地遵循单个教程,在不了解代码实际作用的情况下复制粘贴内容。 相反,请打开一个主题的几(2–3)个教程,并对其进行彻底检查。 这是有好处的,原因有两个:1)您不太可能被经验不足的开发人员误导,他们实际上在传授不良做法,并且2)如果两个教程之间有任何差异,您可以研究这些差异以获得更好的理解。 例如为什么某些决定在某一个代码段中做出而不是在另一代码段中。
我发现第二个技巧在从头开始学习 CSS 时特别有用。起初,我非常害怕阅读别人的样式表,因为我从未真正理解过他们的规则在做什么。那我做了什么?我阅读了 W3School、MDN、CSS-Tricks 和其他网站,以找到在前端做同样事情的多种方式。然后,对于呈现给我的每一行CSS,我都会在本地输入代码,刷新我的浏览器,并在脑海中记下所发生的可视更改。如果有不清楚的地方,我会马上停下来,用Google搜索那个特定的CSS属性,看看它到底做了什么。所有这些都涉及到阅读,阅读,还有…更多阅读。它永远不会停止——如果您对开发是认真的,那么无论您选择追求什么专业化,这都是一项需要发展的重要技能。
轻松设置开发环境
在使用大型代码库时,尤其是那些不是您自己的代码库,您必须知道如何使用所有正确的工具和依赖项正确设置本地开发环境,这一点很重要。如果您是新手,请考虑以下练习:使用GitHub Explore 查找一个有趣的项目,并将其克隆到您自己的机器上。然后,按照他们的自述文件中的任何说明设置您的开发环境,并在本地成功构建项目。
在这个练习中可以发现巨大的价值,因为这是所有开发人员都需要知道如何在工作中完成的事情。如果您遇到任何问题,可以在网上搜索一下,很可能其他人以前也遇到过同样的问题,他们已经在 GitHub、StackOverflow 或 Reddit 上报告过。如果你运气不佳,那么可以考虑在 repo 提一个 issue 寻求帮助。
其中很大一部分是学习如何轻松进入终端环境,减少对传统 GUI 的依赖。特别是,了解如何使用 Bash shell 及其最流行的命令将使您作为开发人员的工作变得轻松得多。如果您想两全其美,请考虑使用 Visual Studio Code 作为您的 IDE——它是免费的,具有对终端的内置支持,具有免费扩展的市场,并提供与 Git 等版本控制软件的流畅集成。所有这些都是您作为程序员最终需要使用的东西。
一个关于 Git 的笔记
说到版本控制,如果您对 Git 感到迷茫,那就知道这一点:没有什么比实际使用 Git 更好的“学习”或学习 Git 的方法了。有大量在线教程和视频声称可以在短短15分钟之内帮助您了解 Git,但具有讽刺意味的是,它们都错过了关键点:Git 是一种应用技术,当单独使用它时,很难理解或欣赏。观看视频时,事情就像点击鼠标一样简单,但是除非您自己使用 Git,否则第二天会忘记它。
您绝对需要将 Git 与实际操作的项目(理想情况下是涉及多个合作者的项目)相关联,才能理解为什么特性分支工作流是普遍接受的标准,或者为什么您永远不应该改变公共分支的基础。这还将帮助您轻松地隐藏您的工作、切换分支、修改提交和检查特定的提交。当我几乎没有使用 Git 的经验时,这些都是我曾经害怕的东西,但一旦你掌握了它们,你就会明白它们为什么如此重要。
我还强烈建议您避免使用 Git 的 GUI 客户端,因为它们会阻止您掌握和记忆常见的 Git 命令。命令行是您的朋友,而不是您的敌人。如果您很难记住某个命令是做什么的,或者如何在 Git 中实现某些东西,请随意参考 Atlassian 文档——它们写得非常好。您还可以在 StackOverflow 上找到许多常见 Git 问题的优秀答案。
要知道 Leetcode 不是答案
还记得 SAT 和 ACTS 吗?大多数人都不愿意。那个时候你把在未来可能永远不需要用到的材料和词汇塞进脑袋,仅仅是为了验证你的智力,这样你就可以进入大学了。我讨厌整个过程,只欣赏一路走来学到的一两个数学技巧。
Leetcode 是一样的。在招聘行业,有一种普遍的(可以说是有害的)做法,程序员的能力是通过他们在白板上解决编码难题的能力来衡量的,这已经催生了许多平台,比如 Leetcode、HackerRank 和其他致力于帮助开发人员掌握解决晦涩难题的艺术。我个人很幸运,在面试中不用经历这种磨难,我希望你也不会。
有没有人告诉过你,如果你想在科技行业找到一份好工作,就应该死记硬背 Leetcode?别再听他们的了。如果你想进入精英独角兽公司,情况可能就是这样,但对于大多数开发人员来说,情况并非如此。你能做的最好的事情就是从事个人项目,更深入地了解你未来想要使用的技术,以及扎实地掌握 CS 基础知识(这肯定会在面试中提到)。如果你发现自己在背东西,那么你就走错了路。
综上所述,我承认有一些相当有趣的 Leetcode 问题,它们实际上会让您思考并测试您对基本 CS 数据结构的理解。以下是我个人的最爱:
- Reversing a linked list
- Merging two sorted linked lists
- Implementing a prefix tree from scratch
- Validating stack sequences
- Map sum pairs (prefix trees)
所以,如果你对解决这些问题感兴趣,一定要试一试。但不要浪费你的时间专门练习 Leetcode,自认为这会让你成为一名更好的程序员(或者你正在寻找的任何职位的更合格的候选人)。这在整体情况中只占很小的一部分。
别再自责了
失败太糟糕了。但是您需要习惯编程通常带来的挫折感,因为这是不可避免的。
这就是在线编程课程往往令人失望的地方——一旦培训结束,当你遇到一个陌生的问题,恐慌就开始了。因为到目前为止,你遇到的每一个问题都有一个解决方案:一位会很高兴地告诉你如何做某事的导师。
然后会发生什么呢?人们求助于 Quora、Reddit 或他们经常去的任何其他论坛寻求安慰,他们被告知编码并不那么困难,他们并不愚蠢,随着时间的推移,他们会变得更好。
真相是你并不愚蠢。学习编程实际上就是学习说一门新的语言——在开始的时候有一个艰难的过渡期,在这段时间里,你主要是通过死记硬背和重复来做事情,几乎没有什么事情真正有直觉意义。但最终会有开悟的时刻,当你回首往事,意识到你在这段时间里一直在做的是什么。它最终确实会顺理成章,成为第二天性。
不过,别搞错了:实现这一目标的过程并非易事。一旦你到了那里,你就会意识到你不是编程奇才(有人是吗?)。你们之间的知识差距还很大。不幸的是,人们被误导了,认为编程在某种程度上比任何其他高薪技能更容易掌握,或者花钱在课程上就能保证他们的成功。实际上,成为一名优秀的开发人员需要多年的实践、自我激励和努力工作。
当然,你永远不应该停止学习。