为了账号安全,请及时绑定邮箱和手机立即绑定

学习编程基础知识,进阶成为更优秀的程序员

前言

2019年的1月份,我在自己的代码仓库里面创建了一个名为“Gaia(盖亚)”的项目,以此,开始了《编程必备基础知识》的备课之旅。 “Gaia(盖亚)”(希腊语:Γαία、英语:Gaia (Gaea)),是古希腊神话中的大地之神,是众神之母,所有神灵中德高望重的显赫之神。

为什么命名为Gaia呢?这和我们这门课程的主要内容有关系。这是一门关于计算机基础知识的理论课程,包括了大学计算机系中的三大基础课程《计算机组成原理》、《操作系统》和《计算机网络》。相对于繁花齐放的实践项目来说,这门课程对它们而言,就犹如Gaia对各有所长的众神一样,是基础、是根基,虽“力不及众神”,但亦是“德高望重”,因而,考虑再三,把这个项目命名为“Gaia(盖亚)”。我想,这个比喻也是颇为恰当的。

重度依赖计算机技术的互联网行业发展到今天,计算机的火热程度大家是有目共睹的,早些年还只是局限在计算机领域的互联网行业,到今天已经泛化成互联网+、oto、互联网金融、智慧零售、智慧城市等热门话题渗透进老百姓的生活当中了,众多的传统行业在互联网技术的加持下,正迸发着新的生命,薪资待遇水涨船高,吸引着更多的优秀人才前仆后继,人才的规模效应也促使着行业迈着更大的步伐发展,当你看到编程语言编进教材的时候,看到一个文科生也在编写Python程序进行数据分析的时候,你就会发现,这是一个万物皆互联网的时代,也是一个全民编程的时代。而在这个全民编程的时代中如何有效提升自己,让自己在激烈的竞争环境中脱颖而出,我想这是大家都在思考的问题。

计算机安全行业有一个著名的词叫做“脚本小子”,指的是只会使用一些别人的工具扫描一些别人已知的漏洞的“黑客”,“脚本小子”常常从某些网站上复制脚本代码,然后到处粘贴,却并不明白其中的方法与原理,因而“脚本小子”通常形容一些基础不扎实的入门黑客,“脚本小子”和“黑客”是计算机安全领域相去甚远的两类人群,安全领域尚已这样,而更为普遍的软件开发领域亦是如此。一个开发者的基础扎实与否,在和他合作的时候就能看得出来。

而关于普通程序员和优秀程序员,最大的区别就在于此,基础不扎实的程序员,其技术的天花板是很低的,当达到一定水平之后,往往后面的发展,都只会原地踏步,徘徊不前,而晋升往更深的领域,计算机的底层基础知识,是必不可少的。常常有些同学有这样的疑问,我是学习前端的、我是做客户端的又或者是我是写Java的等等,这样有必要学习编程基础知识吗;感觉这应该是很多同学都有过的思考,“我是专长于某种语言的,应不应该学习更加底层的知识?”我认为只要从事计算机编程的同学都应该补充或者学习一些计算机的基础知识,优秀的程序员不应该把自己局限于某种语言,而是应该放眼去看整个领域。当某种语言的使用到达一定阶段之后都会追求更高层次的阶段去发展,那往往意味着会更接近底层一些。 举个例子:当你使用某种语言,你是否了解这种语言对对象内存的管理方法、是否了解语言的线程、进程和锁同步等机制呢?而这些内容都可以在操作系统中补全,当了解了操作系统之后,学习新的语言时理解这些内容只不过是对知识的迁移和理解,原理无需重复学习。 当然,这样的例子还能找到很多,关于计算机网络、关于计算机组成原理等等。因此只要往更深层次去发展的话,就应该补充相关的底层原理,这些通用的基础知识,对你日后学习其他知识会有很好的帮助,也是你“打怪”晋升成为更加优秀的自己的必由之路。

互联网大厂,不管是“行业老大哥”百度、腾讯、阿里还是“行业新星”美团、滴滴、拼多多、头条等等,在人才招聘的时候总更青睐于基础扎实的人,一方面是大部分高校毕业出来的同学项目经历都比较少,考察基础知识能够容易筛选合适的人选,而另一个方面则往往是基础扎实的人接受能力更强,能够更快学习新的知识,更能够满足企业的需求。如果把时间线拉长到五年甚至十年去看,去观察一些经验丰富的大厂从业者,你会发现那些基础扎实的开发者总是能够在新的技术或问题面前更容易的抓住重点,比如学习Go语言,当基础薄弱的人还在纠结语法的时候,他们已经在调研goroutine和channel了,又比如在调研框架,当部分人还在看API的使用文档的时候,那些基础扎实的开发者已经在了解架构了,扎实的基础加上日积月累的效应,所能带来的差距是很大的,因此互联网大厂都更青睐于基础扎实的人才。

相信大部分同学在笔试或者面试过程中都有被考察基础知识的经历,就比如编程语言中关键字volatile的作用就常常作为面试官考察应聘者基础知识的题目,对于一些涉及Java的面试,相信也有被问到volatile对比synchronized的区别等等的问题,咋一看还以为是考语言层面的知识。其实volatile这个关键字虽然从表面来说只是一些编程语言中用于声明变量的关键字,不少同学也能说出关于其中的一二,但其实这个关键字的背后所涉及的原理就是《计算机组成原理》中的存储器层次结构设计,了解存储器的层次结构的同学明显能够比不了解的要理解得更深并回答得更好。

对于工作中所涉及的关于计算机基础知识的场景就更多了,IO读写考虑阻塞,多线程并发考虑同步,服务部署考虑内存占用,网络传输考虑带宽效率等等,数不胜数;而对于工作中常见的疑难杂症、摸不着头脑的Bug,基础扎实的人往往更容易道破其中玄机,因而基础扎实的同学在工作中往往能够更胜任有难度的工作,获得更大的发展。

这里关于工作中的基础知识,我也想在分享一个真实的经历,在这里经历里面,大家都能够看到基础知识的重要性。

几年前,我们负责一个与底层计算资源(简单来说底层计算资源就是CPU、GPU和FPGA之类的资源)相关的SDK项目。硬件侧的计算资源是封装为16个“计算单元”向软件层提供服务的。在设计中,为了维护计算任务状态的一致性,需要在软件层和硬件层都维护下发任务的状态。但是要在软件层和硬件层都维护任务的状态,难点就在于两端任务状态的一致性(因为不管是软件层还是硬件层,都有很多异常的情况会影响这个一致性)。

当时第一个方案是尝试去掉软件层关于状态的缓存,而在软件需要获取状态时都通过接口查询硬件中的状态;但其中通信的开销非常昂贵,并且对于毫秒级别的任务会导致通信频率非常的高,因而整个方案因为状态一致而带来的开销是非常大的,所以最终这个方案被否掉了。

之后的方案讨论了很久,过程就不多说了。最终的方案是参考了TCP协议的可靠性来设计整个状态同步的,为什么参考了TCP协议呢?TCP协议可以维护客户端和服务端之间通信报文的可靠性,因而在我们设计的时候,就把软件层类比为客户端,硬件层类比为服务端,16个“计算单元”类比为TCP协议中的“滑动窗口”,在下发的任务和返回的结果中携带“ACK”信息,以此来实现了软件和硬件的任务状态一致性,大大降低了为了状态同步而带来的通信开销,并且TCP协议也是历经考验的,可靠性可以保证,参考TCP协议实现远比自己重新造轮子的成本要低。在这个经历里面,计算机底层的基础知识所发挥的作用是很大的,如果没有借鉴到这些基础知识中的设计,这个项目可能就大为延期,甚至直接“夭折”了。

虽然对于这种难度级别的开发,可能在大家的学习、工作生涯中并不多见,而且相信大多数从事开发的同学都是忙碌于业务逻辑的开发,对基础知识的感知甚少。而有些知识就是这样,平时感觉不到他的存在,可真到关键的时候,才恨“书到用时方恨少”。所以要想在众多的开发者和激烈的竞争当中脱颖而出,要在未来的工作中独当一面,扎实的基础知识是必不可少的,是的,你大概很难找到拒绝学习基础知识的理由。

或许在很多时候,你也曾有过想要补充基础知识的意识,可等你要补充的时候,才发现了自己的时间不再充裕而大部头书籍过于沉重,再难以重拾。又或者是这些基础知识的体系结构早已分崩瓦解,渴望快速重建知识结构却又不知从何补起。更或者是想更快掌握其中和工作更相关的知识,却又苦于学习无门。

我想《编程必备基础知识》这门课或许是你的一个好的开始。

这门课程的在内容定位就是“基础知识”,覆盖计算机领域的基础知识,真正做到夯实基础,目的就是帮助大家快速建立起对计算机基础知识的结构,夯实计算机的基础知识,补全计算机知识的短板。针对《计算机组成原理》、《操作系统》和《计算机网络》,都将会有深入的讲解。

纯粹的理论学习是相对枯燥的,这点从大学过来的同学多少有些深切体会,我也是从大学过来的,虽说是师资雄厚的985高校, 但也免不了枯燥,犹记得大学课堂学生入座那个“前排三两个,中间一窝蜂,后排瞌睡中”的经典分布。因而本课程在内容上结合了不少实践章节进行讲解,在《计算机组成原理》就实践了经典的缓存置换算法,在《操作系统》就实践了线程池和异步任务,在《计算机网路》则实践了网络嗅探工具,实践内容是非常丰富的,并且也是十分有用的实践,比如缓存置换算法就常是作为笔试题来考察,工作中涉及缓存设计的开发时,也是经常用到;另外除了实践部分,课程还添加了相当的笔试面试和工作中常用到的知识点的习题,以此来辅助记忆知识点,这其中的比例大约是,理论:实践:习题=6:3:1。

同时,为了避免课程讲述过程中的枯燥,课程对于PPT的准备也是非常充分的,整门课程的PPT累计超过1000+页,课程的PPT拥有丰富的图示,既避免了课程内容学习过程中的枯燥,又帮助了知识点的理解。

此外,对内容的大量重组也是课程的一个特点,考虑到大部分的同学都是对编程开发感兴趣的或者是从事软件开发的,对涉及硬件的知识点的需求相对较少,因而课程在设计上就避免了涉及硬件的一些知识点,比如计算机组成原理的部分就摒弃了关于ALU结构、门电路等的硬件内容的讲解,整个课程的内容更加紧凑,更加符合大家的需求。

课程内容更贴合工作应该是大家对于实战课程的需求,相信很多同学都有过高校课程“理论与实践脱节”的体会,因而这个问题也是课程内容所考虑的问题之一,所以课程内容在设计的时候糅合了很多个人关于工作的体会,在这一点上我付出了很多的努力,努力地让自己的经历和体会结构化形成课程进行输出,这些内容将主要会体现在各个大小章节内,就好比在操作系统的第七章,对线程与进程的同步和通信进行了深入的讲解,一方面保证了重要知识点的深度,另一方面是互斥量、读写锁、自旋锁和条件变量等等的知识点在工作中确实尤为重要。同时也强调了一些对开发重要的概念,比如操作系统的内核态,近年来变得很火的协程等等,因而课程内容更贴合实际。

互联网行业有个不成文的约定就是终身学习,层出不穷的框架,各显神通的新语言,不断拓展的未知领域等等,这些都是开发者们孜孜不倦地学习的动力。但正如万丈高楼平地起,基础设施决定上层建筑,掌握《编程必备基础知识》你才更容易“一招致敌”,走得更远。

“送君千里,终须一别”,关于基础知识就分享这么多了。最后祝愿同学们都能“款款框架无师自通”,“行行代码无一漏洞”。

点击查看更多内容
44人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消