为什么转行

因为混得不好。

在成为程序员之前,我干过很多工作。由于学历的问题(高中),我的工作基本上都是体力活。包括但不限于:工厂普工、销售(没有干销售的才能)、搬运工、摆地摊等,转行前最后一份工作是修电脑。这么多年,月薪没高过 3300......

后来偶然一个机会我发现了知乎这个网站,在上面了解到程序员的各种优点。于是,我下定决心转行(2016 年,当时 28 了),辞职在家自学编程。并且也得到了媳妇的支持,感谢我的媳妇。

转行准备

转行选择前端也是在知乎上看网友分析的,比后端好入门。

如何选择教程?

最好在网上多查查资料,找评价高的或者去豆瓣上找评分高的书。

我在网上查了很多资料,最终确定 HTML、CSS 在 w3cschool 学习。JavaScript 则选择了JavaScript 高级程序设计第三版(俗称红宝书,现在已经有第四版了)。

光看不练是学不好编程的,我非常幸运的遇到了百度前端技术学院。它从易到难设置了 52 个任务,共分为四个阶段。任务难度循序渐进,每一个任务都有清晰的讲解和学习参考资料。它还怕你不会做,允许你查看其他人上传的任务答案。

我先学习了 HTML、CSS,做完了第一阶段任务。再看完红宝书前十三章,做完了第二阶段任务。然后把红宝石剩下的全看完,做到第三阶段的任务四十五。后面的任务对于当时的我来说实在太难了,就没往下做。在 1 月的时候,又学习了 ajax,了解了前后端如何相互通信。

我从 16 年 11 月开始自学前端,一直到 17 年 2 月。历时 3 个月,平均每天学习 3-4 个小时。中间有好几次因为太难想过放弃,不过最后还是坚持下来了。

找工作的过程非常艰难,我在网上各大招聘平台投了很多简历,但由于没学历、没经验,所以一个回复都没有。最后还是我媳妇工作的公司在招前端,给了我一个内推的机会,才有了第一次面试。并且第一次面试也很顺利,居然过了,这是我没想到的。直到多年后我和面试官又在一个公司的时候,才知道原因。他的意思是:看在我这么努力自学编程的份上,愿意给我一个机会。

虽然人生很艰难,但很有可能,遇到一个愿意给你机会的人,就能改变你的命运。

正式工作

第一年

在正式的项目中写代码和在学习时写代码是不一样的。你必须得考虑这样写安不安全,会不会引起 BUG,会不会引起性能问题。在工作的第一年,写业务代码对我的提升非常大。

第一年的主要任务,就是提升前端基础能力。因此我看了很多 JavaScript 的书籍来提升自己的水平:

  1. JavaScript高级程序设计(第三版)
  2. 高性能JavaScript
  3. JavaScript语言精粹
  4. 你不知道的JavaScript(上中下三卷)
  5. ES6标准入门
  6. 深入浅出Node.js

这些书都是非常经典的书籍,有几本我还看了好几篇。

除了看书外,我还做了百度前端技术学院 2017 年的任务,它比 2016 年的任务(转行时做的是 2016 年的任务)更有难度和深度,非常适合进阶。

另外还学习了 jquery 和 nodejs。jquery 是工作中要用,nodejs 则是出于兴趣学习的,没有多深入。

第二年

到了第二年,写业务代码对于我来说,已经提升不大了,就像一个熟练工一样。而且感觉前端方面掌握的知识已经足够把工作做好了。于是我就想,为了成为一名顶尖的程序员,还需要做什么。我在网上查了很多资料,看了很多前辈的回答,最后决定自学计算机专业。

我制定了一个自学计算机专业的计划,并且减少花在前端上的时间。因为说到底,基础是地基。基础打好了,楼才能建得高。

计算机系统要素

计算机系统要素是我制订计划后开始学习的第一本书。它主要讲解了计算机原理(1-5章)、编译原理(6-11章)、操作系统相关知识(12章)。不要看内容这么多,其实这本书的内容非常通俗易懂,翻译也很给力。每一章后面都有相关的实验,需要你手写代码去完成,堪称理论与实践结合的经典。

这里引用一下书里的简介,大家可以感受一下:

本书通过展现简单但功能强大的计算机系统之构建过程,为读者呈现了一幅完整、严格的计算机应用科学大图景。本书作者认为,理解计算机工作原理的最好方法就是亲自动手,从零开始构建计算机系统。
通过12个章节和项目来引领读者从头开始,本书逐步地构建一个基本的硬件平台和现代软件阶层体系。在这个过程中,读者能够获得关于硬件体系结构、操作系统、编程语言、编译器、数据结构、算法以及软件工程的详实知识。通过这种逐步构造的方法,本书揭示了计算机科学知识中的重要成分,并展示其它课程中所介绍的理论和应用技术如何融入这幅全局大图景当中去。
全书基于“先抽象再实现”的阐述模式,每一章都介绍一个关键的硬件或软件抽象,一种实现方式以及一个实际的项目。完成这些项目所必要的计算机科学知识在本书中都有涵盖,只要求读者具备程序设计经验。本书配套的支持网站提供了书中描述的用于构建所有硬件和软件系统所必需的工具和资料,以及用于12个项目的200个测试程序。
全书内容广泛、涉猎全面,适合计算机及相关专业本科生、研究生、技术开发人员、教师以及技术爱好者参考和学习。

做完这些实验,让我有了一个质的提升。以前感觉计算机就是一个黑盒,但现在不一样了。我开始了解计算机内部是如何运作的。明白了自己写的代码是怎么经过编译变成指令,最后在 CPU 中执行的。也明白了指令、数据怎么在 CPU 和内存之间流转的。

这本书所有实验的答案我都放在了 github 上,有兴趣不妨了解一下。

Vue

这一年还学会了 Vue。除了熟读文档外,还为了研究源码而模仿 Vue1.0 版本写了一个 mini-vue。不过学习源码对于我写业务代码并没有什么帮助。如果不是出于兴趣去研究源码,最好不要去学,熟读文档就能完全应付工作了。如果是为了面试,那也不需要阅读源码。只需要在网上找一些质量高的源码分析文章看一看,作一下笔记就 OK 了。

为什么我不建议阅读源码?因为阅读源码效率太低,而且相对于你的付出,收益并不大。到后面 Vue 出了 3.0 版本时,我也是有选择地阅读部分源码。

第三年

第三年有大半年的时间浪费在王者荣耀上,那会天天只想着冲荣耀,根本没心思学习。后来终于醒悟过来了,王者荣耀是我成为顶级程序员的阻碍。于是痛定思痛,给戒掉了。

由于打王者的原因,第三年没学习多少新知识。基本上只做了三件事:

  1. 写了几个 Vue 相关的插件和项目。
  2. 将过去所学的前端知识,整理了一下放在 github 上,有空就复习一下。
  3. 学习数据结构与算法。

数据结构与算法

数据结构和算法有什么用?学了算法后,我觉得至少会懂得去分析程序的性能问题。

一个程序的性能有问题,需要你去优化。如果学过数据结构和算法,你会从时间复杂度和空间复杂度去分析代码,然后解决问题。如果没学过,你只能靠猜、碰运气来解决问题。

理论知识上,我主要看的是算法这本书,课后习题没做,改成用刷 leetcode 代替。目前已经刷了 300+ 道题,还在继续刷。不过由于数学差,稍微复杂一点的算法知识都看不懂,效果不是很好。

第四年

第四年,也就是今年(2020),是我重新奋斗的一年。今年比以往的任何一年都要努力,每天保证 3 小时以上的学习时间。如果实在太忙了,达不到要求,那就改天把时间补上。附上我今年的学习时长图(记录软件为 Now Then):


v2-5aef1dac2807ce87514a942de76c81f1_720w


今年我做了非常多的事情:

  1. 研究前端工程化。
  2. 学习操作系统。
  3. 学习计算机网络。
  4. 学习软件工程。
  5. 学习 C++。
  6. 学英语。

前端工程化

研究前端工程化的目的,就是为了提高团队的开发效率。为此我看了很多书和资料:

研究了一年的时间,写了一篇质量较高的入门教程——手把手带你入门前端工程化——超详细教程。除此之外,还有其他工程化相关的一系列文章:

操作系统

操作系统是管理计算机硬件与软件资源的计算机程序。通常情况下,程序是运行在操作系统上的,而不是直接和硬件交互。一个程序如果想和硬件交互就得通过操作系统。

如果你掌握了操作系统的知识,你就知道程序是怎么和硬件交互的。

例如你知道申请内存,释放内存的内部过程是怎样的;当你按下 k 键,你也知道 k 是怎么出现在屏幕上的;知道文件是怎么读出、写入的。

对于操作系统,我主要学习了以下书籍:

  1. x86汇编语言:从实模式到保护模式
  2. xv6-chinese
  3. 操作系统导论

然后做 MIT6.828 的实验,实现了一个简单的操作系统内核。

计算机网络

计算机网络的作用主要是解决计算机之间如何通信的问题。

例如 A 地区和 B 地区的的计算机怎么通信?同一局域网的两台电脑又如何通信?学习计算机网络知识就是了解它们是怎么通信的以及怎么将它们联通起来。

对于计算机网络,我主要学习了以下书籍:

  1. 计算机网络--自顶向下
  2. 计算机网络
  3. HTTP权威指南
  4. HTTP/2基础教程

并且做了计算机网络--自顶向下的实验。

软件工程

软件工程是一门研究用工程化方法构建和维护有效的、实用的和高质量的软件的学科。它涉及程序设计语言、数据库、软件开发工具、系统平台、标准、设计模式等方面。

学习以下书籍:

  1. 代码大全(第2版)
  2. 重构(第2版)
  3. 软件工程

软件工程是一门非常庞大的学科,我只学习了一点皮毛。主要学习的是关于代码怎么写得更好、结构组织更合理的知识,这需要一边学习一边在工作中运用。

C++

学习 C++ 其实是为了研究 nodejs 源码用的,看的这本书C++ Primer 中文版(第 5 版)

英语

我从转行开始就一直在学习英语,不过今年花的时间比较多。

英语对于程序员的好处非常非常多,就我知道的有:

  1. 可以用 google 和 stackoverflow 来解决问题。
  2. 知道怎么给变量、函数起一个好的命名。
  3. 很多流行的软件都是国外程序员写的,有问题你可以直接看文档以及和别人交流。

在我转行前英语词汇量只有几百,三年多过去了,现在词汇量有 6000(都是用百词斩测的)。


v2-4823ecdbcc18db565490fad74ae9817b_720w


写作

写作的好处是非常多的,越早写越好。我还记得第一篇文章是 2017 年 2 月发表的,是我工作后的第 13 天,发表在 CSDN 上。


v2-88efe9ce43b6474443117721cbd0ce60_720w


个人认为写作的好处有三点:

  1. 锻炼你的写作能力。一般情况下,写得越多,写作能力越好。这个好,不是说你的文章遣词造句有多好,而是指文章条理清晰,通俗易懂,容易让人理解。
  2. 写作其实是费曼学习法的运用,帮助自己加深理解所学的知识。有没有试过,学完一个知识点后,觉得自己懂了。但让你向别人讲述这个知识点时,反而吞吞吐吐不知道怎么讲。其实这是没理解透才会这样的,要让别人明白你在表达什么,首先你得非常熟悉这个知识点。一知半解是不可能把它讲明白的,所以写作也是在帮你梳理知识。
  3. 增加自己的曝光度。在我三年多的程序员生涯中,一共写了 50 多篇文章,因此在一些平台上也收获了不少赞和粉丝。因为我写的某些文章质量还行,不少大厂的程序员找过我,给我内推。不过由于个人学历问题,基本上都没下文...

总之一句话,写作对你只有好处,没有坏处。

学习

有选择的学习

我觉得学习一定要有非常清晰的目标,知道你要学什么,怎么学。对于前端来说,我认为很多框架和库都是不用学的。例如前端三大框架,没有必要三个都学,把你工作中要用的那个掌握好就行。

比如你公司用的是 Vue,就深入学习 Vue,如果要看源码就只看重点部分的源码。例如模板编译、Diff 算法、Vue 原生组件实现、指令实现等等。

剩下的两个框架 React、Angular 做个 DEMO 熟悉一下就行,毕竟原理都是相通的。等你公司要上这两个再深入学习,不过也不建议阅读源码了,太累。看别人写的现成的源码分析文章就好。

其他的,像 easyui、Backbone.js、各种小程序... 用不到的坚决不学,浪费时间。用的时候看文档就行了,当然,如果有兴趣了解如何实现也是可以的。

学习方法

我觉得好的学习方法非常重要,对我比较有用的两个是:

  1. 费曼学习法。
  2. 学习一个知识点,最好把它吃透。

费曼学习法在《写作》一节中已经说过了,这里着重说说第二个。

你有没有过这种感觉:觉得自己会的东西很多,但其实掌握的知识很多都停留在表面上,别人要是往深一问,就懵逼了。

我以前就有过这种感觉,主要问题出在对知识的学习仅停留在浅尝即止的状态。就是学习新知识,能写个 DEMO,就觉得自己学得差不多了。这种学习方法是很有害的,首先知识存留度不高,其次是浪费时间,因为很快就会忘掉。

后来我尝试改正这种状态,在学习新的知识点时,时常问自己三个问题:

  1. 这是什么?
  2. 为什么要这样?可以不这样吗?
  3. 有没有更好的方式?

当然,不是所有问题都能适用灵魂三问,但它适用大多数情况。

举个例子:看过性能优化相关文章的同学应该知道有这么一条规则,要减少页面上的 HTTP 请求。

这是什么?

先了解一下 HTTP 请求是啥,查资料发现原来是向服务器请求资源用的。

为什么要减少 HTTP 请求?

查资料发现:HTTP 请求需要经历 DNS 查找,TCP 握手,SSL 握手(如果有的话)等一系列过程,才能真正发出这个请求。并且现代浏览器对于 TCP 并发数也是有限制的,超过 TCP 并发数的 HTTP 请求只能等前面的请求完成了才能继续发送。

我们可以打开 chrome 开发者工具看一下一个 HTTP 请求所花费的具体时间。

这是一个 HTTP 请求,请求的文件大小为 28.4KB。

名词解释:

  1. Queueing: 在请求队列中的时间。
  2. Stalled: 从TCP 连接建立完成,到真正可以传输数据之间的时间差,此时间包括代理协商时间。
  3. Proxy negotiation: 与代理服务器连接进行协商所花费的时间。
  4. DNS Lookup: 执行DNS查找所花费的时间,页面上的每个不同的域都需要进行DNS查找。
  5. Initial Connection / Connecting: 建立连接所花费的时间,包括TCP握手/重试和协商SSL。
  6. SSL: 完成SSL握手所花费的时间。
  7. Request sent: 发出网络请求所花费的时间,通常为一毫秒的时间。
  8. Waiting(TFFB): TFFB 是发出页面请求到接收到应答数据第一个字节的时间总和,它包含了 DNS 解析时间、 TCP 连接时间、发送 HTTP 请求时间和获得响应消息第一个字节的时间。
  9. Content Download: 接收响应数据所花费的时间。
    从这个例子可以看出,真正下载数据的时间占比为 13.05 / 204.16 = 6.39%。文件越小,这个比例越小,文件越大,比例就越高。这就是为什么要建议将多个小文件合并为一个大文件,从而减少 HTTP 请求次数的原因。

有没有更好的方式?

使用 HTTP2,所有的请求都可以放在一个 TCP 连接上发送。HTTP2 还有好多东西要学,这里不深入讲解了。

经过灵魂三问后,是不是这条优化规则的来龙去脉全都理清了,并且在你查资料动手的过程中,知识会理解得更加深刻。

掌握了这种学习方法,并且时刻运用在学习中、工作中,突破瓶颈只是时间的问题

总结

下面提前回答一下可能会有的问题。

百度前端技术学院

百度前端技术学院 2017 年及往后的任务,如果没有报名,那就只能做部分任务。2016 年的任务则由于百度服务器的问题,很多题的示例图都裂了。这个其实是有解决方案的,那就是看别人的答案。把别人的源码下载下来,用浏览器打开 html 文件当示例图看。这两年的任务我都做了大部分,附上答案:

  1. 百度前端技术学院2016任务
  2. 百度前端技术学院2017任务

学历提升

我从 18 年开始,已经报考了成人高考大专,19 年报了自考本科。大专明年 1 月就能毕业,自考本科比较难,可能 2021 年或 2022 年才能考下来。

写在最后

从转行到现在,已经过去 3 年多了。不得不说转行当程序员给了我人生第二次机会,我也很喜欢这个职业。不过这几年一直都是在小公司,导致自己的技术和视野得不到很大的提升。所以现在的目标除了学习计算机专业外,就是进大厂,希望有一天能实现。

虽然今年已经 32 了,但我对未来仍然充满希望。努力地学习,努力地提升自己,为了成为一名顶尖的程序员而努力。