我是如何在自学编程9个月后找到工作的
昨天在我在国外网站 reddit 上看到一篇文章,作者分享了他自学编程 9 个月后找到工作的经历。文章不到一天就得到3千多赞,2百条回复。我看了下内容,非常中肯,其中有不少建议也是我在编程教室屡次提过的。所以我连夜翻译了出来。原文略长,我做了适当的缩减。另外加上了一点我的想法(括号内斜体字)。虽说国情有不同,但本质是相同的,对想要入行的朋友很有参考价值。
长话短说,2017年12月,我处于人生的十字路口,无论是继续完成看不到尽头的化学硕士学位还是重新寻找自己的出路都令我感到纠结。那时我写了一些代码(也就几百行 Python),感觉不错。我决定靠着积蓄来学习编程,直到找到一份开发的工作。
回顾这个漫长而艰难的旅程,我想分享一些经验,它是如何开始以及如何结束的。我的观点没有特别的顺序,虽然我会先写一些我认为最重要的。
1)设定一个非常精确的目标。我是指现实的目标。这是你旅程中最重要的方面,你需要对终点线有清晰的认识。你学习编程,是因为想解决一些实际问题吗?也许你想要自动处理你工作/生活中的一些任务,也许你想破解游戏,也许你出于好奇心,也许你喜欢学习新事物,又也许你是一个想开发应用却没有资金的企业家。而本文中,我主要针对想要通过学习编程找工作的角度来谈。
2)如果你的目标是找工作,就盯着就业市场看,而不是 Twitter 和 Medium 上的热点。还记得第一点吗?你必须设定一个非常精确的目标。诸如“我想成为一名开发人员并从事游戏行业”这样的目标就过于模糊。你的首要任务是什么?是寻找一个真实的开发工作,还是在游戏行业工作?如果你在游戏行业找不到工作怎么办?你的城市没有此类公司,或者你达不到游戏公司的要求怎么办?其实不论你学习哪种编程语言,我敢说将来某一天这些知识都可能用在游戏开发上,只要这是你的目标。你将需要学习大量的新东西。但是你有解决问题的能力和编程知识才能迈出第一步。
你是一名自学成才的开发人员,不是 MIT 的优秀毕业生,找到一份异地的工作会更难。我在2017年12月犯了一个错误:我认为首要任务是找到一份前端开发的工作。但我没意识到,在我的地区 C#/php/Java 的工作与前端 JS 工作的比例为9:1。因此,请查查你所在地区的公司,看看它们的职位和要求。
(如果你的目标是转行,不妨从初级职位先入行,再不断调整到你期望的方向)
3)永远永远不要假设在编程中什么更难什么更容易。当我决定学习前端时,我这样做了。这是一个巨大的错误。不好说前端比后端更容易,或是更难。关键是,你也无法知道自己会更喜欢什么,更适应什么。所以不要假设。永远不要认为 JavaScript 比 C 更容易或是更难。不同工具对于不同问题的有不同的复杂性,你还没有到能区分什么“更难”什么“更容易”的程度,我也是。就别去衡量。你能说清,从现在开始的24个月内,在某平台上提升渲染和网络性能比优化基于地理空间数据预测天气的算法“更容易”吗?你确定在复杂的实时应用程序中管理状态比编写着色器或教电脑如何翻译或绘画更容易吗?你根本就不知道。所以,千万不要做这种无脑的假设。
4)坚持学习。你有多少时间学习编程?你是学生吗?还是失业了(就像我一样)但是有足够的积蓄来投入学习。你的目标要符合实际,但要坚持。每天写1小时代码会比每周写一次7小时的代码会使你成为一个更好的程序员。
5)不必懂得职位所需的一切。对于框架和库尤其如此。顶级公司非常关注数据结构和算法,这表明你可以思考并解决问题。更具体地说,无论你选择何种编程语言(Java,JavaScript,C#,Python 和 PHP 中的任何一种都可能找到工作),尽可能地学习它的基础知识。我学习了前端开发。我觉得这需要从 html 到 dom,学大量的库,transpiling,webpack 等等。但实际上,在求职面试中,这些话题很少被问起,他们只想知道我是否真的了解 JavaScript。我申请了3个前端 React 工作,没有人关心你是否知道 React 的调用(我的意思是,如果你学习 React,你应该至少具备它的工作原理的基本知识),但成为一名优秀的 React 开发人员所需的核心知识就是了解 JavaScript。如果你了解 JavaScript 和 dom,那么学习 React 只需要一周的时间。否则你永远不会成为一个好的 React 开发者。高阶函数,this 绑定,这些是 React 开发人员每天需要真正面对的问题和知识,其余的都是谷歌搜索。这同样适用于任何其他语言。如果没有扎实的语言基础,各种 bug 会让你一筹莫展。仅仅读过一些东西,并不意味着你吸收了它,更不谈掌握它了。一个会 10 种技能/工具,但并不真正精通一个的人,很难取得别人信任。
6)尝试寻找一个导师。Slacks, IRC, Discord 上很多人比你有经验,你也许能找到愿意长期帮助你的。感谢 freenode 的 javascript 频道所有成员对我学习的帮助(特别是 ljharb,slikts,stennowork,liste,innovati,zsoc,cjhonson,qswz,GreenJello,sillyslux)。请注意,我不是让你们去联系这些人,他们在讨论组中提供帮助而不是一对一。两个建议:1. 不要考验导师的耐心和意愿。如果你一直在问可以搜索或书上查到的基本问题,他们会厌烦并懒得回答你。2. 程序员,包括你在内,都希望别人认可自己的聪明,我认为这是理性人的本质。你可以利用这一点,比如:如果你进入聊天室并写“平心而论,我觉得在座各位不会绑定箭头函数”,你会得到20个回复。而如果你问“箭头函数怎么用?” 可能不会有任何答案。
(一个过来人的建议和指导对于学习非常有帮助,这是任何书本、教程或者视频都无法达到。关于这点,参与过编程教室码上行动的各位同学应该深有体会
)
7)了解什么是编程:将数据作为输入,对它做一些处理,生成一个输出。这就是每个程序所干的事情。把两个数字相加:输入数字 -> 处理 -> 输出总和。在屏幕上渲染3D模型:相机+顶点矩阵 -> 处理 -> 屏幕上的2D图像。在网站上设置你的个人资料图片:数据输入+地址 -> 处理 -> 来自服务器的响应。这就是编程的全部,一切都是为了计算。数据 -> 处理 -> 数据。不过我对数据结构和算法知之甚少。我不太能实现归并算法或实现复杂的数据结构,在面试中也没有真正要求它们。知道时间复杂度和不同数据结构的应用对于我的面试来说已经足够了。但在其他公司和职位上可能会有所不同。
8)了解程序员做什么。他们通过代码解决问题。作为程序员,你需要解决问题(通常由你自己创建)。不能解决代码的问题,那要你何用。如果你认为跟随 youtube/udemy 上的一些废话视频可能会让你成为一名程序员,那就大错特错了。看别人替你解决问题意味着你没有提高问题解决技巧。所以当你无法理解某些代码时,别急着谷歌或问人。要知道,这就是你要面对的工作。善于解决问题,有些可能是语法问题(如前所述),有些可能与性能有关,等等。学会使用调试器。代码只是想法的实现,习惯用铅笔和纸编程。定义好你的问题,输入,输出以及如何从一个到另一个。整理你的代码,看看你乱七八糟的面条代码,看看你凌乱和命名不佳的函数和变量,超过几百行就难以维护的代码,试着改进它。
9)掌握计算机的基本常识。认真脸。你起码要了解冯·诺伊曼结构和内存模型,这些几小时就能学完。哪怕是通过维基百科、Youtube 或者是一些博客,至少做下这件事。搞懂内存模型和调用栈,你的代码水平将会提升,你也会码得更快。你再也不会搞不清:为什么你不能修改一个字符串,或者为什么是通过引用而不是值来传递非基本类型。这对提升你的学习速度,加深你对计算机运行原理的了解具有重要意义。
10)不要跟着视频学习。你需要做得事情越高级,越小众,你能使用的资源就越来越少。你要习惯用谷歌也搜索不到多少信息的情况。你将会需要使用文档很少或者为零的程序库,需要查看代码来搞清楚为什么这个库改变了那个对象类型,或者运行情况和预期不同。去 Github 上看一些热门的库,那里有很多问题可研究。在你之前,那些优秀的工程师从来没遇到过这些问题。我知道这不容易,但这是个好习惯。我还没见到过哪个编程问题在视频中比在出色的书或文章中写得更好。而且要注意,很多做这些课程的人并不一定是优秀的程序员;即使他们是,他们也不见得是好的老师。我不是说“不要使用视频”。有很多视频帮了我大忙,帮我理解概念,解决问题,以及看怎么使用一些技术。但是不到最后,不要用这个资源,不要依赖它。比如我自己很喜欢 Andrew Mead 的 React 课程,但如果我没有自己去研究,一遍遍尝试,那我看到过的内容都没变成我自己的。靠着某个视频,了解关于某个软件特定版本的例子,只是不得已的替代方案。
(你觉得真正的编程大牛会整天开直播给你讲怎么写入门代码吗?)
11)调试和版本控制。这对于学习语言和计算机基础是最重要的,也是工作环境中最需要的东西。其次是工具的使用。如果你掌握 Java,那么学习 Spring 比学习 docker 和 git 要容易得多。但你可能会花 95% 的时间来编写 Spring 代码。又比如你掌握 Python,你可以在一个周末学会 Django,但需要花更多时间学会调试错误的 Python 代码。关于 IDE 也是,知道 5 个 IDE 不如熟练使用 1 个。这些未必是初级职位的必备技能,你可以不去了解它们,但这个东西是长期有用的。
(调试 debug 和版本控制是区分新手与程序员的重要标志,对求职也很加分,参考 开发5分钟,调试2小时 - 你的问题在哪里?)
12)不要试图一次学习太多东西。小步走,但要稳。我犯过这样的错,并且付出不小的代价。不是说读 Hennessy 和 Patterson 的著作没用,或者说关于设计模式的阅读是无用的,也不是说看 Youtube 视频、有趣的技术讨论、阅读行为驱动设计没用,但是还记得第一点吗?你必须明白什么是首要的,扎实走好每一小步。如果你和我一样,充满好奇心,那很好。但是,先找到一份工作,在一个舒适的环境中,拿着一份薪水,跟着资深开发者学习,然后回家尝试用 Rust 编程,看关于不可变性的谈话,难道不是更好吗?
关于招聘:
13)人脉 > 经验 > 知识。
大多数公司都是长期招聘,但没对外公布,可能他们的网站上连个“联系我们”都没有。所以在找工作时,人脉至关重要。我强烈建议你加入当地线上的社区,线下的更好。我寄出的简历全都没有回应,我得到的所有面试机会都来自我认识的人。当对方知道你是个开发者时,可能会对你说,“你感兴趣的话,我可以把你的简历递给我的头儿。”
如果你是自学的开发,那求职可能有些难(不过这个视地区和职位而定)。尽管你技术很强,知识丰富,但你的简历上没有经验可写。只是说我会 Python,没人会给你面试机会,因为你没法证明。招了你可能意味着公司要赔钱。养着几个不产出还拿工资的开发者,人力部门不如做一些别的事。我知道技术过硬却没法展示是怎样地痛苦,但现实就是这样。
所以人脉之后,第二重要的是有经验。你有两个选择:参与开源项目(写点有用的库/模块,哪怕提交一个好的修改也能加分)或者开发一些人们会用到的东西,甚至是给别人免费使用。我选择了第二种。我为我们市的一个足球俱乐部开发了一个应用,这个俱乐部需要通知球员周日哪些青年球队会来比赛。这个应用算不上好,但每周数百人都要用到。你能用代码解决一个现实生活中的问题,满足人们的需求,已经很了不起了。我还给我叔叔写了一个短租网站,没有实时预定的复杂数据库,但是解决了他的问题。就算它有很多反模式,影响大吗?可能你做了一个精致的 Instagram 复刻版,代码也更清晰,但是会有人用它吗?其中有你的原创吗?可能你有一部智能电视,你总是要把硬盘里的各种节目拷贝到电视机上来看,为此感到心累时,有想过做些什么吗?你有一个路由器,还有一个可以安装软件的程序的电视机。不如花一个月写一个粗糙简陋,但却有用的 app,可以让你的电脑和电视进行数据传输。这些写到简历上也很好看,因为他们给你机会来谈论你是怎样解决问题的,比如你什么地方做得好,什么地方做得不好。我的第一个 React app 没有用状态管理器,随后我遇到很多由此导致的问题,维护代码也越来越难。我遇到了问题,解决它,而且能知道我的解决办法是好是坏。看看你的周围,你能做哪些事情来帮人们解决问题?从你自己的问题开始,继而关注别人的,哪怕是做免费服务。而你用 Django+PostgreSQL 完美复刻 Twitter 有什么好谈的呢?
(很多人说学完基础不知道做什么,但其实身边处处都可能用到编程。我们也举过很多例子,公众号Crossin的编程教室里回复关键字 项目)
最后就是你的知识,而且这很重要。如果没人帮你递简历,说你是个优质资源,那知识就是你最后的王牌。你发布了两个安卓的应用,简历上至少有东西可写。可能你回答不了被问到的问题,但如果给你时间,你总能做出一个产品。所以知识成了你唯一的资源,但不那么有力。当你坐在一个 10 年经验的人面前,说着“value”而不是“variable”,别人就对你的水平有所了解了。假设没人推荐你,没人用你写的代码,你的 GitHub 上是一堆刚初始化或者废弃了的项目,或者是从教程里复制来的一些片段;假设你被问到一些基础问题(其实也是最难的),而你不能自信地给出一个清晰的答案,谁会付你钱呢?
14)小贴士1:如果在你正式找工作前有 6 至 7 个月的准备时间,我推荐学下 C 语言。这是一门很小的语言,但可以教会你很多。这么说吧,如果我在花 4 个月学习另一门高阶语言之前,先花 2 个月学习 C 语言(每天至少 4 小时),并且解决一些 Leetcode 上简单和中等难度的问题,我会成为一名比现在更优秀的程序员。现在技术太多,高阶语言中有大量“噪音”。你很快就会从“我怎么样从 input 到 output ”这样的问题上被引诱到别的关注点上,而这却是写一个完整代码最最基本的步骤。我知道编写“input”和“output”一点也不酷,但还记得第一点吗?我们需要尽快找到一份让自己能挣钱的体面工作。学习 C 语言,可能起初比较慢。但当你学习下一门语言时,你最后会发现和使用 C 语言解决问题是一样的,只不过要使用无数的 API。
15)小贴士2:学会管理你的时间。你整天坐在电脑前学编程,顺手刷一刷各种网站很有诱惑力的,但这些都是在浪费时间。如果你能把时间管理好,那你的准备时间可以大大缩减掉几个星期甚至几个月。
16)小贴士3:休息,社交,恋爱,娱乐,照顾自己,这些都超级重要。一个人坐在那里,整天看着博客,盯着Visual Studio,对你的精神健康没有好处,而且会让你和别人格格不入。努力学习,懂得自制,但是在生活的其他方面也要自制。因为一旦这个平衡被打破,其他地方也会出问题。
就写这么多,如果写太长了,请不要介意。希望有人会觉得这篇文章有帮助,且这只是我个人的见解,可能会有很多人不赞同。
作者:ep1939