文/赵玉锡
2004 年进入华为,一直在消息产品开发一线耕耘,今年下半年转入华为融合视频业务。曾参与多个重要项目与重要版本的设计、重构与开发,辗转多个语言:长期从事 C、C++ 开发,Java 与 Python 也有约 30K+ 代码的开发经验,目前正在基于 Go 语言开发,对 HTML/JS/Shell 等脚本语言也有一定掌握。
本文主要分析 C、C++98、C++11、Java 与 Go,主要论述语言的关键能力。在论述的过程中会结合华为各语言编程专家和华为电信软件内部的骨干开发人员的交流,摒弃语言偏好或者语言教派之争,尽量以客观公正的角度来论述下各个语言的特点和不足,对语言选型作为一个客观的参考。
把这些写出来,期望得到大家的指正与反馈,让整个分析更客观,性能方面,着重对 Go 做深入剖析参考。内容很多,期望不会让你望而却步。
语言整体概要
1、Go
在并发方面, goroutine 和 channel 机制提供了语言层面的轻量级和毫无拖泥带水的并发机制;在性能方面,提供了不弱于 Java 的性能(性能是个伪命题),而内存资源消耗方面,相对 Java 和其它动态语言,具备明显的优势;在语法方面,具备了部分 Python 的动态语言特性,在对象初始化、构造和序列化等方面提供了无比简洁的表述方式,而这些处理代码可能占据 10%~50% 的代码分量,尤其对于处理数据、配置和协议映射场景,相比 C、C++、Java 在此方面拙笨,这就是动态语言为何让人着迷的关键所在。
这也是为啥 Go 语言第一个版本发布时就如此受人瞩目的关键所在,尤其是对于动态语言来说,它提供了动态语言所不具有的并发与性能优势,Pike 设计 Go 语言目的是想作为 C/C++ 的另外一个可选的角色(注意不是替换,其设计目标不是替换),Go 语言之父 Google 首席软件工程师 Pike 2012 年“大道至简”演讲稿中对于此目标充满沮丧,引用其中一句话:“Although we expected C++ programmers to see Go as an alternative, instead most Go programmers come from languages like Python and Ruby. Very few come from C++.” C++ 的价值精髓在于:语言提供更加广泛的抽象、优雅和灵活的特性,而这些表达能力是硬件零成本的,而 C 语言一开始就把硬件零成本作为其设计目的,但语言表述力是 C++ 来解决,Go 思考的方向显然不是零成本,至少不是零 CPU 成本,Go 的主张更多考虑的是最小化程序员的工作量。
一个是硬件零成本的极致追求,一个是最小化程序员的工作量,谁都替换不了谁最有价值的部分,Go 无法同时符合两个目标,它选择了动态语法和 gc,就注定了它选择开发效率,会为开发效率牺牲硬件效率,所以它走向另外一个方向,也就是 Java 所擅长的应用方向,尤其是目前的网络和 HTPP 应用方面,这就需要有良好的标准库和生态系统支持,而在标准库方面,Go 已提供了处理 tcp/http/xml/json/ 加解密等更轻量级和优秀的代码库,对网络的核心协议 http 的高并发支持,已经为它提供了撬动 Java 的敲门砖。
但是我们必须面对它目前的不足,在其语言重要特性和严谨性方面还远未成熟,还有不少断层或临时解决方案,而这也会影响到其生态的成熟度,这些问题还需要在新版本中解决。Go 语言 2012 年 3 月 28 日正式发布第一个版本,截止目前 1.7 版本发布,差不多一年两个大版本发布,中间还有数个 beta 与 RC 版本发布,这也基本能说明 Go 语言还未完全准备好。
小结
Go 已经证明在动态语言需要性能方面,是作为 Python 和 Ruby 的理想候选者;在应用开发方面,尤其是 HTTP 相关应用方面,目前已经是站在 Java 面前的一位挑战者,同时在对资源的掌控力不是那么强烈诉求的地方也是 C/C++ 之外提供另外一种角色。
在生产力方面,其语言特性和生态系统还未成熟,版本还在快速迭代中,相比动态语言和 Java,并不具有优势,目前阶段是这些语言在某些场景下的可选角色。长期看,在 Google 的鼎力支持下,新特性和库的应用能力还会不断加入,是一门欣欣向荣的编程语言,但目前阶段,建议必须控制好程序的规模和复杂度,语言和生态还未提供健全的支撑,同时还必须留意它的不成熟和版本快速迭代带来的风险。
2、Java
Java 的成功得益于 10 年前以 Unix 系统为主的 SUN、IBM、Oracle 等大型公司的强力支持,这让它在企业应用领域和 WEB 应用方面站稳了脚跟,而随后的 10 年,前半段是靠 x86+Linux 带来的革命继续保持份额,后半段就是 android 的成功让其在步履蹒跚停止脚步后再一次登顶。这二十年,Java 积累了最强大的生态系统,你可以说它无所不包, 毋庸置疑,Java 早已是一艘航空母舰的巨大身躯,这足已证明它的地位与成功。但是其语言、库、框架和生态系统的复杂度,对技术人员构筑其巨大的障碍,比如并发方面,语言的 synchronized 机制,标准库的 notify 再到 concurrent,也可以通过 Apache+tomcat 容器来获得 HTTP 等的并,而基于 JVM 技术,Java 又与其它语言具有良好的互操作性,比如并发方面的 Scala,可以选择其 Actor 或者也是用 Scala 写的 Akka,当然业界选择 nginx 等混搭的场景更多,太多太多…
这就是 Java 的世界,永远不嫌多,无需要重复造车马,这是 Java 成功的关键所在,历史沉淀下来的,让 Java 提供的选项太多,深入后就知道 Java 的学习成本比 C++ 更高,对程序员的要求比 C++ 更高,除非掉队了,还在用 7 年甚至 10 年前的 Java 技术,技术人员要非常精心地组织框架和设计,否则各种复用的结果就是堆砌出一个异常臃肿的程序,其运行时对资源的消耗有时候会让你感到恐惧,而这是太多的基于 Java 所开发的平台被广泛诟病的关键所在,重用是个双刃剑,需要量体裁衣而不是一锅端,拿捏的尺度对开发人员要求无疑是最高昂的,除非语言和标准库提供了最好最直接的选项。
小结
Java 早已证明它的无所不包,近十年基本都是排名最好的语言,积累最强大的生态系统。要澄清下一个误区:如今 Java 的学习成本和对开发人员的技能要求,已经远高于 C/C++ 的,也许大多数的开发人员无法驾驭 Java 这艘航空母舰。若要长期使用 Java,务必跟上 Java 的最新技术,同时在重用方面一定要拿捏好尺度,这会对人员技能提出更高要求,否则及其容易写出资源占用和运行时效率让人感到恐惧的应用。
3、C、C++98、C++11……
C/C++ 在嵌入式和系统级编程方面,依然占据着牢固的位置,因为诸如 Java 和 Go 等语言的关键发力点显然在开发效率这一侧,参考前面 Go 一章节的论述。
但是在并发、网络和应用编程等方面,一直处于讳莫如深的黑暗时代,语言本身未提供任何支持,而太单薄的标准库也毫无此方面的野心,C/C++ 的标准库的规模恐怕始终无法比拟 Java 与 Go,因为 C/C++ 不受任何一家大型商业公司控制而完全是“放养”状态,标准库需要得到大型商业公司持续的投资,这就是为啥 C++98 的标准库在 13 年后才获得一次大的更新。这直接导致 C/C++ 必须封装各种硬件平台的系统 API,而在 linux+x86 大面积击败 Unix 之前,众多的 Unix 系统更加剧了跨平台编程的难度,2000 年前出现一个很糟糕的跨平台的 ACE,还有 windows 平台上充斥大量宏静态全局变量的同样糟糕的 MFC 库,这些都曾经被程序员当成救命稻草,这些技术显然很快都被历史丢弃,这下可以知道为啥如此多的人对 C/C++ 讳莫如深感到恐惧。而此时 Java 提供了多线程、网络和应用开发方面的标准库和基于 JVM 技术的跨平台支持,把 Java 推向主流编程语言,也就是 Java 前十年成功的关键所在。
对于 C/C++ 程序员,有一个振奋人心的大事件,C++11 发布,相比 C++98,无论在语言和标准库上,都是一个极大飞跃,C++ 之父说它是一门新语言,这不为过,同时如此多的顶尖 C++ 高手对 boost 库的贡献(其实已是实时上的标准库),在网络、并发编程和一些基本应用方面,已经提供了性能最优秀的库,极大地降低了此方面的开发难度。传统的 C++ 程序员,尽快过渡到 C++11 上,这需要编译环境的更新,而编译环境更新又会带来内存检测和性能分析方面最强力的工具,C\C++ 曾经最广受诟病的内存越界与泄露问题,在 gcc5.2 版本和 Intel 最新 CPU 面前,内存飞踩可以被抓在第一现场,同时Intel提供的 vtune 性能分析工具,是个人目前为止所遇到的最强大工具。
小结
传统的 C++ 程序员,尽快过渡到 C++11 上,拥抱新的标准库和 boost,这会极大提高在嵌入式和系统级编程方面的开发与维护效率。要拥抱全新语言,而语言的重大升级,广义上看也是一门新语言,也要放到同样重要位置,更好地发挥已有资产的产效。而在应用开发方面,由于标准库方面就不要指望它可以匹敌目前阶段的 Go,更不要说 Java,所以老老实实做好它最擅长的领域。
语言特性
1、并发
Go 在轻量级和简洁方面具备最大优势:goroutine 和 channel 机制提供语言层面的轻量级和毫无拖泥带水的并发机制,标准库也提供了基于此的应用库;
在并发世界的混合编程方面,Java 提供了最多的选择项和生态支持:十年前 java.util.concurrent 发布后就已经把 Java 推向了并发编程高峰,在云化下,Java 与 Scala 等高并发框架和语言具有良好互操作性;
C++11 相对于 C/C++98,向前迈出了一大步,标准库和扩展库 boost 库已提供了优秀的跨平台封装,告别对操作系统 API 的维护,如同 10 年前 Java 的 concurrent 包发布一样,极大降低了此语言在并发编程方面的跨平台的心智负担,但在线程调度和管理方面,还是需要自己精心维护;
而对于 C/C++98 来说,仅华为电信软件,有依赖 SNE/ENIP、有依赖 ACE、有风格各异的自行跨平台封装,尤其是 10 年前要支持 windows、linux、solaris、aix 等平台,并发编程的黑暗时代,C/C++ 的开发难度也多半因为其并发和网络编程,语言和库未提供支撑,必须白手起家。
小结
开发难度 Go < Java < C++11 < C/C98,学习曲线 Go < C++11 < Java < C/C98。可能有人会疑惑为啥 Java 比 C++11 的并发还难学,是因为 Java 提供的选择项太多,语言、标准库和其它语言框架互操作方面,要掌握和拿捏好,学习成本非常高昂,否则写出来的程序可能非常低效或者不健壮或者复杂。
2、面向对象
Java、C++、Python 均提供了良好的面向对象的语言支持,配合设计模式、类型系统和工具链的支持等,Java 和 C++ 具备构建大规模程序所具备的基本要素;Go 语言虽然号称支持面向对象,但它是通过方法与 interface 等间接模拟,无法直接清晰地组织对象结构并初始化销毁它们,与 C 一样,会充斥大量的全局对象和结构体,管理对象的成本比较高,在构建大规模程序方面,语言能力还比较弱,还需要新的语言特性加入。
3、物理结构组织
物理结构的组织,对于中大规模的程序来说,相比类接口等逻辑结构的表述,具有更至关重要的作用,比如100万行左右的C++代码,如果结构组织不好,影响是战略层面的(逻辑结构组织对于大规模程序影响是战术层面):一行代码变更,编译链接时间可能都是10分钟以上,甚至数小时,仅仅编译和重启耗费的时间可能已击垮整个开发效率。
包:在代码组织方面,包的作用无需要在阐述,Java 与 Go 基本上是天生就具备了此语言特性,而 C/C++ 显然还不具备,C++ 只有比较弱的名字空间来避免名字冲突(更多的是逻辑结构组织),更多是通过目录、头文件/源文件/HPP 文件来组织代码分类,需要非常精心地处理和设计,否则引入循环和混乱依赖是家常便饭,对大规模程序的组织,对人员技能要求更高。
库:在程序运行方面,Java 支持 jar 包的动态加载,具备良好地扩展和升级能力,而 C/C++ 支持静态和动态两种链接方式,但在加载方式方面,基本没有控制力,未能如 Java 般灵活,Go 编译后 linux 下基本只依赖 libc 库,不支持动态链接,只支持静态链接,最终编译出一个兼容 gdb 格式的执行程序,在部署方面具有极简配置,但必须控制程序规模,否则在作业域可能会带来联动升级。
小结
Java 在此方面是最优的,而 C++ 必须要谨慎处理,Go 介于两者之间。
4、类型系统和泛型
Java/C++ 均支持强类型的编译时检测,提供了编译时的类型安全,便于发现低级的类型错误,同时支持泛型,便于表述通用的算法和容器;Go 语言支持 Python 的动态语法,在处理类型申明定义方面代码更简洁,但类型方面稍弱,目前阶段还不支持泛型,这为表述通用的算法和容器方面带来了极大障碍和类型不安全,需要通过 interface {} 来模拟,如同 C 语言世界的 void *,或者 10 年前没有泛型的 Java,其对象都继承自 Object,当然 interface {} 不只是对象或数据结构类型,Java 的历史已经证明此路不通,迟早会走到泛型,所以 Go语言只是目前阶段不支持而已,长期看应该是支持的,其发明者也说过,目前还未找到好的支持办法。
小结
Go 还需要语言层面的新特性加入,相信这也是迟早的,在泛型方面,目前这几门语言中,C++11 是做得最好的,Java 次之,而 C++98 在处理泛型类型方面常常会遇到晦涩和极难处理的语法错误。
5、初始化
初始化对于程序的健壮性、灵活性和可读性,是至关重要一环,程序无法在各种复杂场景下良好地对变量赋值,其结果可想而知。
Java 做得比较好,有良好的 gc,面向对象,不支持全局变量,数据成员支持分阶段的初始化,未显示赋值也有明确含义的初值,而类加载过程中也可以控制类、jar 包之间的复杂依赖关系。
C 在初始化方面的语言支持是最原始的,贬义点来说就是“最糟糕的”,不支持面向对象,全局变量、自由函数和没有明确含义的初值带来了大量程序问题。
C++ 支持得比较好,面向对象,这几门语言中唯一支持对象的析构和 RAII,在复杂对象和对象协作之间的初始化管理方面具有最强控制力,而 C++11 引入了 auto 与 decltype 等偏动态点的特性,让 C++ 表现得更好;但是同时兼容 C 语言的糟糕初始化,如果像 C 一样用 C++,结果与 C 语言一样,而这可能很普遍,这也是 C++ 被诟病的地方,这是继承 C 语言资产带来的其中一个负面,可以做得很好,也可能做得非常非常糟糕。
Go 在初始化方面,Go 借鉴了 Python 部分动态语言,在变量、数组、struct、list 和 map 等结构方面,相信看过的都会为其简洁点个赞。但目前还需要更多的版本催熟:gc 相比 1.5 之前版本已经有较大提升,目前还不支持构造和析构,而 defer 一定程度上模拟了,但相比 C++ 的 RAII 和 Java 的对象、finally 等机制,还不成熟,很容易引入诸如性能和资源泄漏方面的缺陷;初始化不统一, New、make、{}等各种特定领域的初始化方式,这也是暴露 Go 的语言设计方面还不成熟的一方面,要知道 Java 与 C++、C 只需要一个 new 或者 malloc。
6、错误处理
错误处理对于复杂逻辑的组织和程序的健壮性,是至关重要的,比如一个简单的读文件,C 语言处理需要打开文件,判断打开结果;读取数据,判断读取数据结果;把数据映射为对象,判断每个参数结果….,就知道错误处理是多么地繁琐。
健全的编程语言 Java/C++/Python/C# 等无疑都把异常处理放在第一优先位置。可惜 Go 目前还不支持,而是通过多值返回错误码方式,或者 panic – recover 机制,让错误处理代码充满整个逻辑,相比 C 的错误返回,有时候可能更糟糕。
7、动态语法
为啥要把动态语法作为一个关键项呢,相信用过 Python 等的,不考虑其它运行效率因素,无疑会对其简洁耳目一新,尤其是在对象初始化和构造方面,而这是程序代码中可能占据 10% 甚至 50% 代码的地方,尤其对于处理数据、配置和分析的系统。
Go 借鉴了 Python 的部分动态语法,在反射的配合下,相比传统的 JAVA、C++ 的拙笨,是一个大的提升,当然此方面还需要不断提升,尤其字符串和类型兼容方面,断层还比较多,无疑在做数据处理方面,相对 Java、C++、C,Go 是更好的选择。
8、其它重要语言特性
运算符重载对于可扩展的类型运算来说,无疑是最优雅的;函数重载对于增量维护开发和支持各种简便调用来说,也是必不可少的;lambda 已经是健全的通用语言 C++11/Java/python/C# 的必选项,lambda 在数据的初始化和控制逻辑表述方面,无疑是一个利器…… Go语言还不支持这些重要的语法特性,需要后续版本增强。
生态
1、标准库
Java 的标准库无疑是最成熟最强大的,提供了拿来即用的高可复用的类和库,无需要重复造车马,这是 Java 成功的关键所在,但 Java 发展至今,其语言、类库和框架早已经是一艘航空母舰,且围绕其 JVM 不断有新技术新库涌现,要掌握拿捏好的学习成本是最高昂的,许多 Java 程序员其实掉队了,如同 C++ 一样,可能还在使用 7 年前甚至 10 年前的 Java 技术,Java 应用领域,必须跟上新技术步伐,同时要非常精心地组织框架和设计,否则各种复用的结果就是堆砌出一个异常臃肿的程序,其运行时对资源的消耗有时候会让你感到恐惧,而这是一些平台被广泛诟病的关键所在,重用是个双刃剑,需要量体裁衣而不是一锅端,拿捏的尺度对开发人员要求无疑是最高昂的。
Go 除了提供雷同 C++11 标准库和 boost 库的基础能力,同时在应用库方面,尤其是网络和 WEB 编程,提供了支持并发的优秀库,如果对于 C++ 的应用能力薄弱和 java 的庞大感到恐惧,无疑 Go 是需要面对一个好的选择。
C++11,并发编程等已经纳入到标准库,同时实时上的标准扩展库 boost 无疑提供了基本的应用复用能力,C++11 在做跨平台并发和网络应用编程方面,完全可替代传统的 C/C++98,让曾经的黑暗年代往前迈出一大步。但是在做 WEB、数据库和数据分析等企业应用开发方面,C++11 的库还是非常地单薄。
2、工具链
C/C++/Java 的工具链,就不用详细叙述了,从编辑器、代码浏览跳转、调试、代码文档自动生成、复杂度度量、findbug、内存排查、性能监控等已经非常鉴权,华为的 CI 环境也提供该了良好支持,就不详细叙述了。
重点审视 Go 语言,开发环境通常会选择 Eclipse 或者 LiteIDE,选择 Eclipse,麻烦就许多,由于 Great wall 的原因,不能直接获取插件:Go 工程需要 GoEclipse、代码跳转需要 gocode、代码调试需要装 gdb,这些都单独下载下来,健全点还需要安装 guru 和 godef,有些需要做编译,安装 Eclipse 的 Go 的健全环境,看个人情况,差不多要 0.5~2 天就能工作了,所以推荐 LiteIDE,它的包里基本都有,装上差不多也能用了。但是这些环境只能简单用,开发工作中会遇到许多重要体验问题,如下:
-
编辑阅读重要体验欠缺
代码浏览:没有代码的对象、函数、变量的全局浏览和查找功能,只能一个个文件地打开进去看,这对于大型工程,文件多,文件大,习惯了 Eclipse、source insight 和 .net,没有浏览,会抓狂;代码搜索和跳转:不能打印名字,函数类接口等能够自动罗列出来,而前后跳转功能基本上也不能用,对于大型工程又是个重大体验丢失; 其它重要体验:无重构工具、无代码自动生成工具、编译错误不能随见随得……
-
代码调试重要体验欠缺
Windows的调试依赖 gdb,gdb 在 windows 环境不大可靠,所以不要期望它在 windows 环境能够如期工作良好,调试就最好到 linux 环境下,或者写 print 打印到控制台,习惯 Windows 环境滋养的,恐怕又要适应下新的非图形化环境。
-
动静态检测工具欠缺
缺乏圈复杂度、codex 套件安全检查(可以直接调用 C/C++ 的代码)、内存检查(可直接使用指针和调用 C 代码)。
小结
基本能用,但是一些提高效率的重要体验丧失,目前阶段如果给 Java/C++ 的开发环境打 5 分,Go 的环境,目前只能给 2 分,且 Go 一年差不多 2 个大版本,对开发环境也是个重要的挑战(Java/C++ 甚至用 5 年甚至 10 年前的环境),公司要做的工作还非常多,且要管控其版本快速迭代带来的切换冲击。Google 公司在还未成熟就早早开源的目的之一就是期望业界能够提供更多工具,而工具基本都是开源世界贡献,而 Android 基于 Java 开发,所以 Google 能直接拿来用,而 Go 作为一门全新语言,在开发环境方面,Go 目前还未及格。
3、语言流行度和开源项目分析
说到语言,必然会想到 TIOBE、PYPL 和 GitHub 的排名,我们看看它们的数据:
-
TIOBE 数据
语言的热度必然得看权威的 TIOBE 世界语言排名, 2016 年 6 月最新数据排行榜:
新语言 Go 的最新排名是 48 位,与 Java 的热度差距是 100 倍。2 年前的 2014 年 7 月,Go 语言排名 30 位,指数是 0.222%,2015 年 7 月 Go 未排入前 50,2016 年最近 5 月排名分别是:50+、38、48、44 和 42。
近三十年语言热度排行榜:
-
PYPL 的最新数据
-
GITHUB 的数据
开源社区,挑选最具代表的 github 上的开源语言排名:
点评
主流编程语言始终具有强大的生命力,Java、C、C++、C#、Python、JavaScript、PHP 从近十年数据看,都未离开过前十名,其它语言扮演的是在某些情况下的一种可选角色,注意不是替代这些主流语言,因为目前还未见它们衰落的迹象。
Java 近十年始终是王者;C/C++ 地位也始终稳固,在嵌入式、系统级编程方面始终占据统治地位,在动态语言方面;Python 的简洁和生态让它占据着胶水语言的角色,当然也有用它来写不那么苛求性能的服务端程序;而网站,PHP 和 JS 就不用多说了,70% 的网站依然是用 PHP 写的。
Go 2009 年正式版本离发布还有两年就掀起了一阵子热潮,正如 Go 语言的之父所说,创造了另外一种角色,在 Python/Ruby 需要性能时的一种可选角色;而相对于 Java,它创造了更轻量级更高效率的一种角色,为撬动史前巨兽 Java 提供了敲门砖,但是语言、标准库和工具链的成熟度牵扯到关键的生产力,这方面它还未准备,而在性能方面,作为新语言,它的调度器也未准备好,还有诸多性能陷阱,看另外一篇文章单独论述。
4、行业应用
对于 Java、C、C++,前面已有说明,在生产力方面,Java 已经无所不包的航空母舰了,而在苛求性能方面,C/C++ 依然占据着牢固的地位。对于 Go,的确已经证明了它在需要性能时是 Python 与 Ruby 这些脚本语言的一个选项,而这些动态语言脚本基本应用在管理域:环境资源应用的监控和部署等,也有些把它们拿来做服务端开发,而在苛求性能时,这些语言的确就不擅长了;在 Java/C/C++ 所擅长的领域,成功的应用太多太多,Go 在某些场景下,比如数据分析或 HTTP 应用方面,它是一种可选的角色,而在通用和复杂应用业务域,无论语言、生态和成熟度,都未准备好。Go 要做的工作还很多,还需要更多地迭代。
其它业界主流语言简要
Python/JavaScript/C# 近十年,也是最流行的语言之一,与 Java/C/C++/PHP 语言一样在各自领域独领风骚,而这些语言在部门也或多或少有应用,但由于非业务模块,重视度没那么高,其实页面、工具和管理域,涉及到重要体验问题,还是需要引起足够重视,否则积累的代码多了,可维护性和体验都会带来越来越大的负担。
1、Shell/Python
历史遗产及其惯性,安装、部署、升级和监视管理任务等方面,基本还在使用 c shell 或 b shell 脚本,shell 的语法深晦,可读性极差,同时编辑调试环境都是最原始的,开发和维护效率基本都是最低的,而这些非业务部件,平时都是三不管的,积累的代码也不少,要专人熟悉 shell 的维护。而 Python 在处理字符串、容器和环境方面,是本文所列的语言中,最简洁生产力最高的语言。
建议作业域的脚本尽量用 Python,在管理域,胶水语言的名号无出其右,而 Python 基本也是排行榜前五的语言。
2、JavaScript/Typescript
JavaScript 可以说是最流行的网页脚本语言了,但它的设计有两个一直被诟病的缺陷,一是太简单;二是弱类型,语法错误到运行时才会发现,应该没人没遇到过网页不知为啥跳出一个警告框的情况吧。当 JS 代码超过万行时,它的简单语法和弱类型会给维护人员带来巨大的负担,个人只写过几百行的 JS 页面,对弱类型基本无法忍受,以前也下载过新浪这样的复杂门户网站看 JS 代码,说实话,深入不下去,直接放弃。Typescript 出现,刚好是为了解决 JavaScript 这两个设计缺陷。
对于 Typescript,或许习惯 JavaScript 会拒绝它的面向对象等增强表达力的语言特性,觉得是让简单变复杂。但另外一个特性,也就是免费为 JavaScript 增加编译时的类型检查,相信没有人会拒绝这样的特性,就跟写文章指出错误的做法。所以写 JS 页面的,还是切换到 TS 这个超集。
3、C#
C# 在华为就更小众了,但它也是最流行的语言之一,而真真能挑战 Java 地位就是 C#,可惜微软把它禁锢在 windows 系统,也限制了世界最顶尖的语言和编译器专家丹麦人 Anders Hejlsberg 的影响力,C# 目前正在逐步走向开源,同时它依附于目前最强大的集成环境 .net 也在走向开源。