学编程,学化学 和 学开车
这是在我的知识星球上,一个同学问我的问题。
波波老师您好,我是学习编程不久的非科班学生。在写代码的这些日子里,我感到非常困惑😕:书写的代码逻辑,怎么就能被计算机给执行了?从点击执行的一刹那,计算机的内部又发生怎样的不为人知的故事?
我似乎可以编写一些逻辑,让计算机帮我做一些事情,但是它怎么帮我做的,这一点好像完全对我屏蔽了。书上说一行行代码,不过是一行行的字符串。但这些字符串是怎么深入到计算机的内部,控制了处理器的执行呢?
我知道这个问题跨度很大,不知道想要把“计算机从通上电的那一刻开始,整个系统是如何运行的”搞清楚,需要学习哪些知识,从哪里开始学习?
bobo 老师的回答:
是的。我们书写的程序只不过是字符串而已。这些字符串是怎么被计算机执行的?这是编译原理领域处理的问题。
编译器通常只是将我们书写的高级程序转换成汇编语言,计算机需要通过汇编器,再转换成计算机真正可以理解的零和一。
当然,不同语言的这个中间过程可能并不一样,但不管怎样,汇编语言是一种公认的介于高级语言和机器识别的零和一(机器语言)之间的桥梁,所以掌握汇编语言,会对你理解高级语言的运行机制,包括计算机的底层原理,有更深刻的认识。
尽管如此,在执行汇编程序的过程中,仍有很多内容计算机对我们屏蔽了。比如分配内存,计算机到底是怎么分配内存的?这些内容,是操作系统这个领域处理的问题。
实际上,从汇编语言转换到零和一,需要操作系统的介入。也正是这个原因,才存在系统相关这个概念。
那计算机到底是怎么解析这些零和一的?为什么一堆零和一对计算机来说是有意义的?这背后要学习的内容,叫计算机体系结构。计算机体系结构会告诉你计算机执行这些零和一的完整过程。
但是,在计算机体系结构的世界里,CPU 就是CPU。可现实世界是复杂的,CPU 有不同的架构,x86?arm?i586?虽然大多数程序员不太会学习不同架构的具体指令集区别,但是,为什么会有这些架构上的区别?指令集到底是怎么回事?这部分知识通常会在一个叫做微机原理的课程中学习。
学习微机原理,就已经接触到芯片的底层逻辑了。可是芯片到底是怎么设计的?怎么优化的?这部分学习,涵盖在一门称为数字逻辑的课程中。值得一提的是,我个人特别喜欢数字逻辑:)
在我上学的年代,学习完上面的全部内容,就可以使用仿真软件,自己设计一个 CPU 了。当然,我们自己设计的 CPU 很简陋,指令集很少,但做完这件事情,就能完全理解计算机到底是如何根据一堆零一,就能完成各种复杂的工作的了。
这个课程设计被我评为我本科阶段做过的最有意义的课程设计,没有之一。
但是,在仿真软件上做 CPU 模拟,其实还是停留在“逻辑”层面。零和一的解析过程到底在芯片底层,是怎么被元器件们实现出来的?这是模拟电路这门课程要处理的问题。
那么这些元器件的底层,又是怎样的过程?这就已经追溯到物理学了。虽然在我上学的时候,大学物理也是计算机专业的必修课,但我学习完大物以后,也没搞懂这些元器件底层的物理原理。
我上面讲的这些领域:编译原理,汇编,操作系统,体系结构,微机原理,数字逻辑,模拟电路,物理,至少在我上学的年代,都是科班的必修课。
但是在这里,我想特别强调一下,作为转专业的同学,不适合一上来就接触这么底层的知识。还是应该先认真掌握一门编程语言。
在学习编程语言的过程中,不仅仅是在学习语法知识,更是在学习基本的逻辑搭建方式;以及不同的编程范式,如面向过程编程,面向对象编程,函数式编程,等等等等。
在这个基础上,应该学习基本的算法和数据结构。同时,如果你有很明确的就业方向,应该学习相应的业务框架。比如前端,比如移动开发。
这些底层的知识,应该放到最后学习。其实,即使是计算机专业科班的培养计划,也是这么设计的,除了可能不会学习某个特定的业务框架之外。
我非常理解很多同学想把底层原理了解得一清二楚的心理,但是有些时候,这些心理会阻止我们前进。
所谓完美主义害死人。
我在我的文章《如果高效学习有什么秘诀的话,那就都在这里了》,多次强调这一点。
在这里,我再随便举两个小例子。
第一个例子是学习化学的过程。
大多数同学应该都是在初三接触的化学这门学科。我在最初学习化学的时候,觉得非常不适应。
为什么?我相信数学比较好的同学都有同感。因为我们学习数学的过程,是从一个一个底层的基本定理一点一点搭建起整个数学体系的,所以逻辑秩序井井有条。尤其是初中学习平面几何的过程,近乎是欧几里得的《几何原本》的另一种呈现,优美至极。
但是学习化学却不同。我们初中学习化学,学一章氧气,学一章碳,又学习一章二氧化碳。看起来东一榔头西一棒头,毫无体系逻辑可言。
但到了高中,我们就会看到,化学这门学科也是有体系的。
这个体系是什么?就是元素周期表。所有的元素整整齐齐地码放在元素周期表这个“化学体系结构”中,每一列元素有着相似的化学性质,每一行元素有着相似的变化关系,井井有条,一清二楚。
但是,元素周期表如此有体系,如此清晰,为什么在初中学习化学的时候,不让初中生直接接触?
答案是:有体系的底层知识,不意味着简单。
实际上,从个体到总体,从特殊到一般,从现象到本质,从一个一个的实例提炼出背后的规律,恰恰是一种非常重要的,通用的,被应用在很多领域的一般学习方法。
计算机的世界也是如此。
我们学习高级语言的过程中,会学习与和或的逻辑,这些逻辑恰恰是计算机底层各个元器件的逻辑运算基础;
我们会学习优先队列或者哈希表这样的数据结构,这些数据结构被大量应用在底层操作系统中;
我们会学习值和引用的区别,这在我看来是理解计算机底层内存存储的关键一步......
我们接触的所有表象,都是为深入理解底层打基础。
很多时候,要想学懂理解底层知识,捷径并非是一头扎入底层的深渊,而是接触更多“表层的知识”,让这些“表层的知识”,带我们一步一步走进底层的世界。
第二个例子是我学习开车的过程。
在学开车的过程中,我学的是手动挡,死活不能理解离合器这个东西。
于是我就问我的教练,离合器到底是个什么玩意儿?
我到现在都不确定我那个教练到底懂不懂离合器是个什么玩意儿。反正他跟我解释了一大堆,我天生愚钝,没有懂。
我本来以为,如果我不懂离合器的原理,就无法学会开车。但后来,我惊讶地发现,虽然我对离合器的原理一无所知,我也能开车。
因为学会开车,不意味着要了解汽车内部每一个零件的工作原理。
这是一个非常简单的常识,如果你留心去看,就会发现这个现象出现在我们生活中的每一个角落。
当然,大家不要按照标题去理解这篇文章的中心思想。这篇文章的中心思想是:精通算法不一定软件开发者的必须,可是,每一个人必须找到自己的核心竞争力。
不管怎么样,在这里,我想强调的是:初学计算机,不应该接触这么底层的,晦涩难懂的问题。
其实不仅仅是计算机,在我看来来,学习所有的科目都是如此。
最后,我想随便聊一聊,这些底层知识,到底有没有用?
这个问题,我觉得在我的文章《学算法有什么用?没用》中,已经说得很清楚了:如果你未来的职业路径是向更深层次的技术进军,或者要去解决一些计算机底层的技术问题,势必有用。
即使不是如此,我的体会也是:学好这些内容,再看高层的软件开发的内容,简直是小菜一碟。
而且,这些知识近乎永不过时。
这类底层原理的课程,是科班专业的灵魂,是科班学生和非科班学生之间最本质的差别。
当然,如果你未来的发展方向不是更深入的技术方向,不学他们无妨。
很多同学看计算机本科的课程设置,发现学习完以后,既做不出网页,又做不出 App,也做不出游戏,就自以为是地开始“批判教育”。殊不知,他们想要学习的东西,其实去个大专,甚至是培训班,就能轻松学到。
对了,我在本科修过一门课程,叫《Flash 设计与开发》。那门课程是我当时学的最 high 的一个课程,做了一段我自认为非常完整的 mv 动画。
但现在回头看,那是我本科学过的最没用的课程,没有之一。
当然了,每一个个体都是不同的,具体到每一个人身上,这些底层知识到底有没有用,有多大用?每个人应该有属于自己的答案。
在这篇文章最开始,我说了那么多的学科:编译原理,汇编,操作系统,体系结构,微机原理,数字逻辑,模拟电路,物理。
从我的角度看,我认为数字逻辑之前的所有学科,都对软件工程师非常有帮助;而模拟电路和物理,没有什么用。
但有的同学可能会觉得操作系统以后的知识都没什么用。
有的同学可能会觉得,模拟电路和大学物理也非常有用。
有的同学可能会觉得,所有这些底层知识都没什么用。
我觉得这些都是正确答案。
这个世界的魅力就在于:每个人都有着属于自己的不同的观点和看法。正是这些不同,催生出了不同的人和事,不同的你和我,不同的成就和结果,我们才有了这个如此丰富多彩的世界。
关键是,每个人都应该努力找到自己在这个世界上的位置,去追求真正的自己。
大家加油!
本文相关阅读推荐:
《是不是很酷》坚持用心做技术原创,陪你一起,用技术人的眼光,观察这个世界,探索这个世界。
如果喜欢我的文章,点个”在看“吧