之前在 知乎 回答问题总结的 ,总结到这里,只是自己的一些观点,欢迎交流。
发展进程
学哪一门编程语言,我们不妨先梳理一下语言的发展过程。
机器语言
计算机的世界是 0 与 1 的世界,如果编写过机器语言,你将会有更深的体会。让我们先看下边的代码片段。
为什么叫机器语言?这可以说很明显了,这段代码猜到下个世纪也猜不出来吧,真的是字如其名,机器才能懂的语言。
这每一条都是一条指令,这个每条指令总共是 32 位,前边 8 位可能表示这条指令是加法,后边 12 位可能是第一个加数的地址,再后边 12 位可能代表第二个加数的地址,然后结果可能保存到第二个加数的位置。
只是随便举了个例子,每条指令的规定是什么,当然就取决于硬件了,有单地址的指令,双地址的指令等等,犹记得当时计算机组成原理课设中,机器只提供了加法的指令,循环的指令,没有乘法的指令,3 * 5 怎么算嘞? 当然就可以转换成 3 + 3 + 3 + 3 + 3 了,还有除法怎么办呢?依旧可以实现的,记得当时写了满满一张纸的机器指令只为实现除法,用着高级语言的我们可以说是很幸福了。
这里我们可以看到,硬件和软件之间的相互配合,硬件如果没有实现,我们可以用软件,凭借硬件已经提供的功能和我们人类强大的逻辑,实现硬件暂时没实现的功能。当然软件实现的话速度和效率方面肯定会比硬件直接实现差一些。那为什么不用硬件把加减乘除乘方开方都实现了?这硬件的开销、复杂程度太大了,在速度可以容忍的情况下,乘方开方这些还是用软件实现比较好。
汇编语言
程序员如果每天写着 10101001010 ,大概会疯掉吧。于是第一反应就是,我能不能把这些指令用英语单词表示了,之前 10101 代表加法指令,我直接写个 add 岂不是更好?于是汇编语言出现了,它的可读性比机器语言增加了很多,可以看下边的代码片段。
我们终于能看懂些了,mov,loop,sub,add 等等都是见名思意,每条指令几乎和机器指令一一对应,这样只要再拥有一个类似「翻译器」的东西,把它翻译成机器语言就完全够了。
但是!!!!我们还可以看到 ax,bx 这些东西,他们是 CPU 中的寄存器,还有一些 0b800h 啥的,这些是内存的地址。可以看到我们仍旧直接面对硬件在编程,这样的好处是程序的速度会快一些,缺点当然是对程序员的不友好,我们只有懂了硬件才能进行编写程序,于是,面向我们程序员的高级语言渐渐诞生了。
C 语言
这可能是大多数人的入门语言了,让我们看一下它的样子。
这看起来就非常的舒服了,即使一个没有学过编程的人,基本也能猜出来这是在干什么。是的,它是在计算 1 * 2。但大家有没有想过,有了这段程序,机器看不懂呀,是的我们还需要一个能够把我们编写的 C 语言程序的代码变为机器语言的东西,我们把它叫做编译器。
编译器无非是一个软件,那么,我们用什么语言写呢?其实,在 C 语言之前,已经有了 A 语言,B 语言,我们不妨选择一个在当时用起来比较简单的 B 语言来去实现我们的编译器。等等等等,B 语言写出的程序用什么去编译成机器能够执行的程序呢?用 B 语言的编译器!!!那么 B 语言的编译器哪来的,用 A 语言写呗。
终极问题,A 语言的编译器呢?用汇编语言!!!是的,逻辑就是我们先用汇编语言写一个相对容易实现的语言的编译器,有了这个编译器我们就可以实现难度更大,更抽象语言的编译器。最终,一层一层的就实现了 C 语言的编译器。
当我们有了 C 语言的编译器,意味着我们用 C 语言写的任何程序都能够转化成机器语言去运行了。这时,我们甚至可以再用 C 语言写一个 C 语言的编译器,再用之前写好的 C 语言的编译器去编译它,一个新的编译器就诞生了,哈哈哈哈哈,好像绕口令。
知道了这些,我们现在甚至可以模仿其他语言设计的规则,然后自己实现一个编译器,然后属于你自己的语言就诞生了!当然说着简单,做起来就比较烧脑了,具体的可以去学习编译原理的东西。
语言分类
C 语言出现后又陆陆续续出现了很多语言,而它们的编译器也大都是用 C 语言去写,底层很多东西也去用 C 语言实现,C 语言可以说是高级语言中,离硬件最近的语言了。
编译型语言
常见的 C 语言,C++,C# 等等,这些语言都需要编译器将所有的东西翻译成机器语言,形成可执行文件,例如 windows 下的 .exe 文件,相对于解释型语言,编译只做一次,然后就可以多次运行了。
还有比较特殊的是 JAVA ,它的一大优势是跨平台,也就是他的代码写好以后,编译成 .class 文件, 然后只要机器里有 JAVA 虚拟机,不管你是什么操作系统,window 也好,linux 也罢,它都可以执行,所以实现了跨平台。它可以说是编译型和解释型语言的结合了,它没有直接编译成机器语言,而是先变成 .class 文件,再由 JAVA 虚拟机一条一条解释执行。但他的语法风格和 C 语言也有很大的相似之处,所以我也把它放到这里了。
解释型语言
常见的 python,JavaScript,Ruby,或者称他们为脚本语言,这种的话就是需要解释器,它是一句的一句的通过解释器将其翻译成机器语言去执行,很明显,在运行的时候,如果不做特殊的优化,它的速度肯定比不上编译型语言。
标记语言
常见的 html,xml,和上边两种完全不一样,它的作用主要是描述一些东西,然后用于显示或者传输,例如下边的 html 。
它不能做一些加减乘除的事情,它仅仅供浏览器读取,然后根据相应的语法把它显示出来。就是下边的效果。
总结
说了这么多,我们学哪一门一门语言呢?
我认为这取决你要做什么,不同的语言其实语法大同小异,不同之处在于它们的生态圈,它们所提供的库的方便程度与类别的不同,以及它们各自的一些特性。
如果你要写一些 windows 的桌面程序,你当然可以去学习 C++,C# 等。如果你要写安卓,你当然得学习 java/Kotlin 。如果你想写一些自动化的脚本,帮助你做一些事情,你可以学 python。如果你想做一些面向硬件的编程,C 语言当然是不错的选择。
不管你最开始学的是什么语言,都不会影响到其他语言的学习。我们要把语言当成一门工具,它是为我们服务的,需要啥就学啥呗,并不需要畏难。当你用熟了一门语言后,再上手一门语言会发现很快,快则两三天,慢则一周便能游刃有余,只要了解了新语言的分支语句、循环语句、函数封装、定义变量的一些语法,基本上就可以开始上手了。
你知道 C 语言怎么产生的吗? 写 UNIX 的时候,Dennis Ritchie 觉得 B语言所编译出来的核心效能不是很好,于是将 B 语言重新改写成 C 语言,再以 C 语言重新改写与编译 Unics 的核心, 最后发行出 Unix 的正式版本。是的,就是这么随便,令大家「头痛」的 C 语言,就是这样简简单单诞生了,惊不惊喜,意不意外。
而现在很火的 JavaScript ,当时也是 Brendan Eich ,为了应付公司安排的任务,用 10 天时间就设计出来了。
让我们看一下最新的编程语言的热度吧,截图自 https://www.tiobe.com/tiobe-index/
看上边的语言,很多可能连名字都没有听过,但事实是他们在各自的领域都发挥着很重要的作用。
学一门语言,首先要明确你为什么要学它,然后再去学。为了考试?为了做一个应用?为了写一个脚本?不管怎么样,有了这个目标导向,我们就会有动力。
当然如果你是非计算机专业的想学一下编程,这里我建议学习 python,可以做一些自动化的任务,处理文件啦,处理 word、EXCEL 的话会很方便。
困惑
为什么不用中文编程
刚开始学编程语言的话,肯定会觉得为什么是一大堆英文,为什么就不能用中文去编程呢?当然其实是有的,比如易语言,但真的有必要用中文编程吧?
如果只是简单的把 C 语言,java 的各种关键字映射成汉字,类似于这样。
1 | //求绝对值 |
然后是汉字
1 | 包含头文件 库函数 |
可以看到,用字母还是简洁的多,另外汉字的话,还需要输入完拼音,然后再去选汉字,反而多了一道流程。
当然如果未来有一种编程语言,就叫做「龙之语言」吧,这种语言完全抛弃了原来分支语句、循环语句、函数封装,只需要用汉语描述你想做什么,然后就会自动生成。例如
1 | 给我生成一个计算器 |
然后一个计算器程序就出来了。
1 | 给我生成一款游戏,类似于英雄联盟和自走棋。 |
然后一个游戏又自动生成了。
当有这样的一种语言诞生的时候,恐怕就是「全世界都在学中国话,孔夫子的话越来越国际化」。
刷题用什么语言
之前在 leetcode 刷题 这里提到了,无非是要想清楚语言和算法之间的关系。
算法就像是从家里到超市该怎么走?出门左拐,右拐直走….
语言是我们选择的交通工具,骑车?步行?开车?平衡车?每种交通工具都有自己的优点和缺点,语言也是如此。
好的算法可能更像是,我们偶然发现了一条近路,降低了我们的时间复杂度或者是空间复杂度。
所以其实并不需要纠结,选择自己熟悉的一门语言即可。
更多
上边的一些总结,就是在知乎陆陆续续看到一些提问然后回答的,也欢迎大家关注我的知乎账号,windliang
,哈哈。