不多废话,直接上Github!
github上有个仓库叫: TeachYourselfCs
就是教你如何系统、科学的自学CS,我看了下讲得非常到位了
现在互联网上,到处都有许多的学习资源,然而精华与糟粕并存。你所需要的,不是一个诸如“200+免费在线课程”的清单,而是以下问题的答案:
- 你应当学习哪些科目,为什么?
- 对于这些科目,最好的书籍或者视频课程是什么?
在 TeachYourselfCS 指引中,恰恰对这些问题回答的相当不错:
具体的内容可以去 Github 查看:
学习计算机一定不要想着速成,要下苦功夫,去啃那些经典书和源码,然后自己动手写,我大学整理了一套计算机必读的经典书籍,对于CS学习的同学帮助非常大,且十分系统,现在免费分享给大家!
说说我自己的自学编程经历吧
985 CS 科班出身,即便是所谓的科班,但任然认为自己是”自学编程
为什么这么说呢?
因为我想了下,很多东西、编程知识都是我自学的,而学校上的CS基础课也仅仅是满足考试而已,
大一上完C语言课,我的水平几乎停留在做课后习题,自己对于内存、指针都是看似懂了,实际没有领悟到精髓
而后我依靠看大量C语言和系统底层方面的书籍,比如《CSAPP》、《汇编语言》《程序员自我修养》、《C和指针》、《深入理解C指针9》等,才勉强说对于内存、指针这些彻底搞懂了。
所以我说认为自己是[自学编程的科班生],相信这样的同学还不在少数。
过去几个月,我微信、知乎收到很多学弟学妹私信,问通信、电子、机械这些专业的同学转码要怎么学?是不是很难追上科班? 如何才能减少和科班的差距?
我一直的观点就是科班并没有什么特别的地方,只是他们学习时间更加充分,学了很多CS相关的课程,很多转码的同学可能一年就把所有学科都学了,显然没有人家扎扎实实学了四年,写了几年代码的基础好
比如计组、汇编、体系结构“等课程会让我们明白计算机的构成、运行机制,以及典型的冯诺依曼结构只,也会对于内存和指针这样两块在任何编程语言中都是极其重要的概念理解非常深入 (不要扯Java这类语言没指针,你完全可以把引用当做受限指针)。
对于一个学了汇编、计组的同学,你一讲指针,就可以从数据总线·、汇编、寻址层面去讲,他就懂了,并没有什么高深的地方。
而对于没有扎实学过这些汇编%的同学,你可能只能这样举例子: 指针就是地址,就像门牌号样,比如我常举的例子:
指针很简单,说白了就跟快递柜似的:
这种大家都用过吧,丰巢“或者超市储物柜都是这样,每个格了都有一个编号,我们只需要拿到编号,然后就能找到对应的格子,取出里面的东西
这样的例子形象倒是非常形象,但是问题在于还是没有从计算机的角度去理解,你仅仅是记住了[指针是地址]这样一个概念,那么地址又有什么作用? 在什么时候起作用的呢? 这还是离不开计组和汇编。
所以这就是科班学汇编、计组的原因:
但是呢,不学这些完全不影响你去用微信支付只、支付宝的SDK实现一个支付接口。
另外,像数字逻辑·、模电这样的课程主要是让你明白数字:浮点数·、整数都是如何在计算机内部表示和存储的,以及一些门电路的知识。
操作系统则让你明白[一个程序是如何跑起来的],一个它是如何编译、链接、加载、运行的,在这一整个过程几乎会涉及到操作系统的所有环节,学了这个你就会明白 synchronized 关键字在OS层面到底是如何保证的。
而计算机网络%则是让你明白[一个数据包是如何从一台主机发送到另外一台主机的],这里面涉及到路由算法、差错检测、寻址、重试策略等等,包括 TCP/IP整个协议栈。
编译原理“则是让你明白高级语言都是如何被编译程序“识别、转换为另外一种语言的,我认为编译器Q的本质就是做转换。很多人觉得平常用不到编译原理,其实不然。
那学好编译原理有啥用?
你会站在更高的角度去审视这些编程语言%,看到的不再是表面的语法,更会想到语法背后的实现。
这种感觉很透彻,就像搞懂了操作系统、体系结构你会明白一个程序从双击鼠标开始,到底是如何被运行起来的,这种掌握一切细节,透彻的感觉,真的很奇妙,不信你去试试。
那学了编译原理你能干啥?
当你学完有限状态机以后,你会发现以前觉得很牛逼正则表达式似乎自己也能用 DFA、NFA 实现一下了。状态机的思想在编程中很多地方都用得上。
比如解析 HTTP 协议,如果没学过状态机思想只,你可能会一行行的 if/else% 去做解析,这里最麻烦的地方在于,if/else 需要提前将 HTTP 头部字段都接收到再来判断,而我们知道 HTTP 基于TCP,而TCP 是流式传输,所以你很有可能是几个字符一组组接收到的,这个时候用 if/else 写出来就很难看了。
而用状态机编写起来代码就会非常优雅。状态的转移是由规则驱动的,接收到一个字符就判断个,非常的方便。
继续学完语法分析,你会掌握递归下降分析这样非常重要的思想,你可以使用递归只下降快速的实现四则运算计算器。
更不用说数据库原理·、分布式系统·、汇编语言等,这些基本都是一个程序员的必备技能。
我一直觉得有件事是很美妙的,就是:
你清楚的知道你写下的每一行代码都会做什么,会调用到哪些系统资源,它会占用、依赖哪些系统资源。
比如一条SQL,哪里会慢、会遇到锁会有并发问题。
虽然不了解原理,也不妨碍使用,但是往往在设计和排查问题的时候,原理非常重要,因为原理就是理论,理论可以帮助我们排查掉各种明显错误的分支,而留下少数理论验证通过的分支,会大大降低我们的工作量。
也就是剪枝
否则我们排查系统错误或者设计方案。可能只能一个个去试。
那么如何追上计算机科班学生呢?
那当然是他们学什么,你就去补齐什么呀!你把操作系统、组成原理·、系统编程“这些学了,认认真真的把计算机基础Q打扎实了,那你其实就是一个[计算机科班学生了]
接下来说下我认为对一个[计算机知识体系完整的毕业生]最重要的课程,你至少得把下面这些课都学了:
- 编程语言: C/C++(学好了这两门,基本其它编程语言一周就上手了)
- 《系统级编程》(我们教材是CSAPP,这是我本科上过最值的课! System Programing)
- 《数据结构与算法》
- 《组成原理和体系结构》
- 《操作系统》
- 《编译原理》
- 《计算机网络》
- 《数学课》: 线代、离散、高数