You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

120 lines
15 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 加餐 | 再八卦几门语言!
你好,我是郑晔!
软件设计是一个比较烧脑的话题,对于一些同学来说,学起来还是有一些辛苦的。所以,我准备了这次加餐,让大家在前面高密度地狂奔了一段时间之后,稍微休息一下。
我在第8讲中讲了程序设计语言的发展有同学觉得不过瘾想了解其他语言的发展过程。那好我们就来谈谈几门比较吸引眼球的程序设计语言。
## C#
当年Java开始起势的时候微软还处于自己的巅峰它当然不想错过Java这么有前景的东西。但是微软从来就不会老老实实按照标准做事所以你会看到微软手中的Basic已经很不像Basic了微软的C++也有着自己的扩展。
于是微软也想做出一个自己的JavaJ++就出现了。但是这不是一个正常的Java引发了SUN的不满将微软告上法庭。最终双方庭外和解微软不再祸害JavaJ++停止更新。
但有一点不得不承认微软在Windows上的JVM性能是当时最好的因为操刀J++的是Anders Hejlsberg他是全世界最顶级的程序员。微软为了不与Java开启的受控Managed代码浪潮擦肩而过于是转身又推出了C#和.NET。
C#的初版本简直和Java一模一样一个Java程序员几乎不用培训就可以成为一个C#程序员。所以从语言的角度来说最初的C#并没有对行业做出什么贡献。
不过既然有Anders Hejlsberg在背后事情当然不会就这么简单收尾。C#在语言特性上开始一路狂奔一个更强大的C#崭露头角。像Lambda、类型推演这些特性早早就落户C#了。
然而C#时运不济它的上升期遇到了微软的下降期。越来越多的公司选择了Java越来越多的程序员拥抱了Java而语言模型上表现优秀的C#则遭遇了冷落。
当年Java号称“一个语言多个平台”而.NET则是“一个平台多个语言”。结果呢.NET的“一个平台”并不足以吸引更多的公司和程序员的投入除了微软自己其他在上面开发语言的尝试通常都是浅尝辄止。而JVM虽然目标不是为了多语言但丝毫不妨碍很多人在上面开发新语言比如Groovy、Scala、Clojure等等。
最终,**JVM成了“多个语言多个平台”**。随着微软的逐步开放,.NET也开始迈向了多平台**C#也成了一门跨平台的语言**遗憾的是为时已晚Java 已经成就了一番霸业。
如果出于学习的目的C#绝对是值得一学的程序设计语言毕竟微软在语言设计上还是很有一套的。Java语言的进化是非常缓慢的尤其是SUN的衰退又耽误了很多年。所以从语言特性上来看说C#领先Java十年并不夸张。
## JavaScript
JavaScript从诞生之日起就扮演着一个不受待见的角色Brendan Eich发明JavaScript完全是为了应付工作因为他当时供职的Netscape需要让网页上的元素动起来。
雷锋和雷锋塔有什么关系Java和JavaScript有什么关系这是一个经常被人提起的段子但实际上JavaScript和Java真的有关系关系就是蹭热度。当时的Java给世界描绘了一个美好的未来让无数人心潮澎湃JavaScript就想借一下Java的东风。
JavaScript仅仅用10天就设计出来所以在它的实现中包含了各种奇怪的问题。不过它还是体现出了BrendanEich的功底比如JavaScript提供了对各种编程范式的支持。其实他真正想做的是一门函数式编程的语言但向现实妥协的结果就是借助了C风格的语法函数式编程的底子却留在了JavaScript里。
虽然在今天看来在浏览器上JavaScript一枝独秀但当年它也是有竞争对手的那个年代无处不在的微软出手做了一个VBScript。但是如同微软错过了互联网时代一样与Windows结合更加紧密的VBScript也在这场竞争中败下阵来。
当年与JavaScript联系在一起的更多的是像走马灯之类的页面特效。让JavaScript真正第一次得到重视是Ajax这门技术。Ajax的出现让页面的元素可以与远程的服务器进行交互JavaScript开始由一个小玩具变成了一门值得研究的技术前端的表现力得到了大幅度的提升。
但很长一段时间里JavaScript一直都不是一门正式的语言对于很多人来说它只是要做前端时顺便学习的语言。这种现象一直持续到Node.js的诞生。
Node.js其实是一个集成商它之所以能有良好的表现要归功于V8这个JavaScript引擎。而V8的出现则要归因于Google对于网络应用前景的格局。
想当年的浏览器大战Netscape和IE拼得你死我活最终IE凭借Windows的优势成了赢家Netscape也退出了历史舞台。然而胜利后的微软认为天下已平竟然解散了IE的团队导致了程序员们要在很长时间内忍受IE这个既不标准又慢的浏览器。
这就给后来居上者留下了空间。最有名的两个后来者一个是Netscape的转世Firefox另外一个就是Google出品的Chrome。
**Chrome认为未来的页面一定要有更强的表现力所以一个高效强大的浏览器是必需的**。既然慢是个大问题Chrome就着力解决慢这个问题甚至不惜开发了一个新的JavaScript引擎也就是V8它的重点就是解决JavaScript执行慢的问题。可等微软看懂Google的操作幡然悔悟重新投入浏览器的开发之时大势已去。Chrome成了新的霸主。
Chrome有一点做得很好V8一开始就是一个独立的JavaScript引擎。所以Node.js才可以很方便地把它借鉴过去。除了V8的性能优势Node.js还引入了异步IO的模型这刚好与JavaScript事件驱动的特点相吻合。
Node.js刚一登场便赢得了满堂喝彩。因为人们认识到JavaScript原来不只能在浏览器中运行也可以跑在服务器端。很快**NPM这个包管理器登场降低了众多开发者参与的门槛JavaScript迎来了属于自己的爆发**,各种各样的程序库让人眼花缭乱。
前端开发也由少数人的爱好成为了一个专属的职位像React、Angular、Vue等框架的出现更是让前端开发有了工程的味道而不再是小打小闹了。
一旦JavaScript突破了浏览器的限制给人们的想象空间就大了许多。除了服务器端有人想把JavaScript用在嵌入式开发中有人想把它用在手机开发中。**JavaScript成了一门全平台覆盖的语言**,大有一统天下的架势。
不过JavaScript作为一门语言其问题之多也是由来已久的。虽然JavaScript本身也在不断进化但沉重的历史包袱让很多人都想开发出新的语言去替代它。所以在JavaScript社区中很多人把它看成了一种Web上的汇编语言把新的语言编译成JavaScript这样就可以在浏览器上运行了。从早先的CoffeeScript到现在的TypeScript甚至新一代的JavaScript标准都是以这种方式进行开发的。
当然还有人有更高的追求他们认为仅仅在语言层面屏蔽JavaScript是不够的。**WebAssembly就是想成为Web上真正的汇编**真正取JavaScript而代之事实上它也得到了很多人的支持。不过这种努力至今仍在继续中还有很长的路要走。
JavaScript就是这样从一出生就不受待见到今天很多人仍想把它干掉。但这并不妨碍它在软件开发的历史中写下浓墨重彩的一笔。
## Go和Rust
在系统编程方面C语言是当之无愧的霸主然而C语言已经快50岁了。在计算机这个快速变化的行业里50年长得令人发指。在这50年中C从被人质疑发展到如日中天再到应用开发的地位逐步被取代。如今它只在系统编程有着无可替代的作用。事实上人们也一直想着替代它。
C的强项是对于计算机模型的适度抽象弱项却是在程序的组织上。因为在C诞生那个年代程序的规模还不算太大。然而C的成功却让程序的规模越来越大大到超出了C语言的能力范畴。于是有人想着把面向对象加到C语言里扩大程序的组织规模。这方面的尝试我们都熟悉的是C++。
不过C++只风光了一段时间就被Java盖了过去。C++本身有一段时间变成了语言特性的试验田,泛型编程,尤其是模板元编程的出现,一度让人怀疑人生。它成了高手极度喜爱,普通人一脸懵硬着头皮写的程序语言。
但更重要的是C++背负了C语言所有的历史负担。所以很多C的问题在C++里面依然存在比如内存管理。虽然C++有各种补丁方案但你必须对C++极其了解才能写好C++,然而,这个要求对于一个工程化的语言来说,实在是太高了。
所以无论是C还是C++,都是在执行性能上无可挑剔,在代码编写上一地鸡毛,人们还是需要一门更有开发效率的系统编程语言。
时间来到新千年又有人出手想代替C语言这回出手的人物背景强大他就是Ken ThompsonC语言的亲爹。2009年如日中天的Google推出了Go语言再加上Ken Thompson和Rob Pike这样早期的Unix先驱站在它背后Go语言的前景给人无限的遐想。
Go语言的语法设计是简单的基本上你花一个晚上就可以把Go语言完整地学习一遍。**它在接口设计和并发上的处理方式都给人眼前一亮的感觉**。人们热切地期盼着它成为下一个系统编程语言的霸主。
但事实并没有像人们想象地那样发生除了初生之时引起了一片欢呼Go语言很长一段时间都在低位徘徊。比较有趣的是中国有很多开发者对于Go的喜爱程度极高一度让Go语言在中国的热度远远超过了全球的平均水平。之所以Go没有很快赢得人们的关注因为它关注的系统编程领域并没有太多的机会留给它人们嘴上喊着热爱手里还依然用C写着代码。
不过机会总是留给做好准备的人语言也不例外。随着Docker这套虚拟化软件登上历史舞台Go语言终于有了用武之地。人们开始意识到**原来云计算领域还有一些基础设施要写用C的话不好维护用Java的话浪费资源Go恰如其分地解决了大部分问题**。
一批新生代的基础设施纷纷出炉除了Docker之外还有帮助人们实现容器部署的Kubernetes也就是k8s还有辅助Service Mesh的istio等等。
虽然在云计算基础设施中Go赢得了一席之地这属于开辟了一片蓝海。在传统系统编程的红海中Go语言其实并没有做出什么特别的成绩对于实时性和性能要求极高的领域Go语言有一个拿不出手的弱项也就是它的GC。
自动的内存管理固然是简化程序员工作的一项重要手段但对于系统编程这个领域而言GC显然还没有表现得能够赢得大家的信任而且在可见的未来也不会有明显的起色。
所以在系统编程领域替代C的征程上大家都还有机会。这条赛道上目前最有力的竞争者是Rust。
Rust出自Mozilla这是浏览器Firefox背后的公司它原本是Mozilla员工Graydon Hoare的个人项目后来得到了公司赞助由一个练手的项目成为了一个正式的项目。
Rust对初学者并不友好对于习惯“少废话、先动手”的程序员而言Rust的初体验可能一点都不好按照习惯方式写出来的代码很可能是无法编译的。比如Rust的“变”量缺省是不变的再有想写好Rust程序先要了解所有权的概念。不过也恰恰是因为这些限制让Rust写出来的程序犯下低级错误的概率大大降低了。
**如果你理解系统编程面临的问题以及现代软件开发的趋势你会发现Rust提供的选项很好地规避了许多问题**。比如,之所以要用不变性,是因为它可以规避掉很多因为“变”带来的问题,这是函数式编程给软件开发贡献的一个重要思路。再比如,所有权的概念也是为了防止一块内存不同的人去改,造成各种问题,同时,也给内存管理提供了新的思路。
内存不能让程序员管这已经成了共识但主流的GC方案又不能满足系统编程的需要Rust则给出了第三种方案把内存当作一种资源申请下来就初始化好出了生命周期就销毁掉。之所以能够做到这点还是要拜Rust强大的编译器所赐因为所有权的存在编译器可以很好地分析出内存到底该什么时候释放。
Rust成为系统编程语言的有力竞争者还有一个原因它背靠着LLVM。LLVM是一套编译器的基础设施它的出现是因为传统的工具链GCC太过沉重。LLVM把编译器的前端和后端分离开来语言开发者只要关注前端设计好各种语言特性就可以利用LLVM的后端进步的优势比如不断优化带来的性能提升。对系统编程语言来说一个重点就是可移植性。
系统编程一个重要的战场就是各种嵌入式设备而绝大多数设备都只支持C/C++语言。一个重要的原因就是谁来移植编译器C/C++的后端常常是厂商提供支持的而其他语言则多半无人理睬。现在有了LLVM的基础设施一个芯片厂商只要支持了LLVM的后端用LLVM前端开发出的语言也就都得到了支持。这对于新兴语言来说绝对是一个巨大的好消息。
Rust在语言层面表现出来的安全特性帮它赢得了像微软、亚马逊这样大厂的注意占用资源少的内存管理方式让一些人开始尝试使用它编写Linux驱动更多的移植可能也让它成为了嵌入式开发的一种考虑。在这场C语言替代者的竞争中Rust值得期待
## 总结时刻
今天的内容主要是为了让大家放松一下,所以,我们也不做内容上的总结了。
每个程序员除了学习当下要用到的知识之外,一般都会对自己的未来做一些技术储备,其中,判断技术趋势就是我们在投资未来时的一个重要参考。
如何才能更好地判断未来技术发展趋势呢?就是去知道一些技术的发展历史。
## 思考题
最后,我想请你分享一下,你看好哪门语言未来的发展?为什么?欢迎在留言区分享你的想法。
感谢阅读,如果你觉得这一讲的内容对你有帮助的话,也欢迎把它分享给你的朋友。