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.

87 lines
9.5 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.

# 第22讲 | 如何选择合适的开发语言?
有许多编程语言可以用来开发服务器端。一些语言对于网络开发有先天优势,一些语言没有先天优势,但是能完成任务,而有一些语言,则不太适合。今天,我就来具体讲一讲这些语言来开发网络服务的优劣势。
## 你了解这些编程语言吗?
**C/C++** 是最标准的开发语言速度快并发性能高能最大程度利用机器资源完成任务。现在C/C++层面拥有无数网络开发库和SDK知名的有ACE、Boost/Asio、ICE等等。但是缺点是开发效率不比别的语言来得高出错后常常只有熟练的程序员才能定位问题并且作出修复。
**Go**是2009年新出现的语言。Go天生适合编写网络程序。它也是一种系统级的语言可以直接编译为执行文件当然由于封装了大量的语法糖所以编译出来的文件会更大它天生支持并发操作所以很多时候你不需要像C/C++一样手工去处理。缺点是Go语言仍然存在许多语法方面的坑你可以去 [https://studygolang.com/](https://studygolang.com/) 学习最新的资料。
**Java**是公认的编写网络服务的第一大语言。在运行性能和开发效率上有很好的折中效果。Java拥有众多的中间件和开发库调试方便一般的运维人员也有极为广泛可用的第三方维护工具可以使用。缺点是Java的运行效率虽然有了质的飞跃但因为中间隔了一层虚拟机所以仍然比不上系统开发语言编写的软件。另外Java的发布和部署需要众多的依赖包和库软件体积庞大也是其重要弊病。
如果深入理解,**Python、Ruby**这两种语言的相似程度以及对系统的支持程度可以用C和C++的相似程度来相比。你或许会很疑惑毕竟Python和Ruby的语法几乎不一样Python需要格式化源代码而Ruby并不需要Python更严谨Ruby更开放Python用户更多Ruby用户更少。
不可否认的是两种语言编写网络程序都非常方便也非常高效。两种语言都可以在100行内编写出一个简单的、完全可以直接使用的网络服务器程序。但是这两种语言的弊病也很明显那就是速度不够快。
比之Java或许运行效率更慢一点但由于目前机器硬件水平的提升软件效率不足的缺点一部分已经被硬件所弥补但是仍然不能否认Python、Ruby语言适合IO密集型开发而不适合计算密集型的开发。
Python的书籍比Ruby多好几倍然而你如果仔细去看的话就会发现Ruby的书籍质量明显比Python高几个等级所以如果要看好的脚本语言的书籍Ruby相关的书籍是首选我这里推荐一本[Programming in Ruby](https://book.douban.com/subject/2032343/),有兴趣的话可以找来看看。
**Node.js**从前端语言变成后端语言让编程界眼前为之一亮。随后的发展大家也有目共睹Node.js由于使用JavaScript语言语法所以我们一般采用事件驱动的形式以及非阻塞的模型来进行网络开发。因为这些特点它非常适合做分布式的、数据密集型的工作。但是缺点也很明显Node.js是单线程无法很好地使用多核CPU这个问题在Python、Ruby语言中也很明显。
或许你没有听说过**Erlang**这种语言这种语言最初是由爱立信开发的。它的初衷是让程序员应对大规模并发、分布式、软件实时并行系统进行编程。最早期的版本在80年代就出现了但是一直到1998年才开源。
Erlang也不是系统语言它有自己的虚拟机和解释器。当然和Java一样Erlang也支持将代码编译为Native Code来运行。Erlang的缺点就是类型问题它并非强类型语言。由于是事件编程所以导致会在运行时无法匹配类型而出错不过这些问题可以使用规范的编程方法来规避。
这么多种编程语言,整合起来看,大致可以把他们分为三类。
**系统级编程语言**诸如汇编、C、C++。这种编程语言执行效率快,并发量也比较高,作为编写网络服务的第一语言,一台服务器就能支撑许多人。缺点是开发效率不够高,需要几年以上经验的程序员才能搞定。
**专门为网络服务器开发的语言**诸如Go、Erlang。这种语言编写高并发和开发效率都不是问题有很好的折中效果。缺点就是语言比较新有许多的坑等着后来的程序员去填而且语言、语法等系统机制要随着进一步的发展才能稳定下来。
**解释型脚本语言**诸如Python、Ruby。 这类语言的开发效率非常高效,在现在的服务器硬件上,也能支撑不少用户,但是唯一的缺点是,运行效率低下。虽然也有解决方案,但仍然不能对抗高性能的系统编程语言和专业网络开发的语言。
## 如何选择一种合适的语言来编写网络服务?
### Web服务
现在有一种流行的说法叫前后端分离。对于编写C/S结构的程序员听到这种说法应该会比较蒙客户端和服务器端难道不是本来就分离的吗
很长的一段时间里在Web的世界中前后端都是混合在一起编写的比如PHP的方式只有用到Ajax交互的时候才需要用到后端的代码。但是前后端一分离后台就需要做更多的工作了当然前端的工作也不会变少。
编写Web服务需要HTTP和HTTPS的服务体系那么在这种情况下使用nginx、Apache作为静态页面路由Java、Tomcat、Python、Ruby等脚本语言就有了用武之地。因为页面只需要使用JSON交互即可。
所以编写Web服务我们可以选择Java、Python、Ruby。但是如果公司财力物力有限再考虑到招人成本的问题次选也可以是Java语言第一是写Java的人够多第二是Java成熟的类库够多因此一旦出问题有解决经验的人也比较多。
### Socket服务
传统TCP/IP和UDP服务或者最近的WebSocket等都需要快速响应和并发操作在这种情况下系统级编程语言和网络编程语言就可以派上用场了。
如果公司的项目需要更快更高效并且财力也允许那么选择C、C++、Go、Erlang等编程语言未尝不是一种选择。当然Java也能很好地提供服务但是从业务上来讲既然选择了Socket服务模式那么就必然是对并发量有一定的要求所以选择上述这些语言更合适。
### 混合模式
这类业务既有HTTP/HTTPS的服务也有Socket服务那么如何平衡两者之间的语言成本如何平衡程序员之间技术栈的问题呢
如果要做一款短期内必须上线的产品我建议选择成熟的、有大量解决方案的开发人员不短缺的语言比如Java或者能快速做出原型的语言比如服务器专有语言Go。如果是长期发展的产品并不那么着急成型那么选择稳定成熟的人员素质高的语言比如Python、Java等。
至于平衡技术栈的问题首先要选择网上有众多解决方案的语言其次是找成熟的语言比如Python、Java、Ruby。如果针对某种特殊的产品比如并发要求特别高的那么只有选择系统语言或者专门的语言比如Go、C++等。
看到这里你是不是觉得Java语言是一种万能药或者是银弹错了这个世界上没有银弹。Java虽然有其独特的优势但是其被人诟病的地方也是有不少的。
第一点莫过于速度。就算拥有JIT编译总体速度仍然比不上C/C++,但是事实上这些因素综合考虑并不算特别大的弊病,因为硬件资源提升后,速度这些问题已经可以“得过且过”了。
那么从语言本身来看如果说C/C++语言本身的弊病是因为系统平台导致的那么Java语言的弊病就是因为继承自C++,却没有做更彻底的改革而导致的。
我随便举一个例子比如说switch case判断语句硬生生地从C/C++处直接继承了下来因为C/C++只允许使用int、enum其实是int、char提升为int作为判断类型而Java也是直接将这套规范继承了下来。
再比如在Java里面异常检查也是一个痛苦的根源程序员不得不写下无数try catch语句以使得将捕获的异常转变为运行时的异常然后再将之抛出去这样一来使用Java编写的API将缺少灵活和扩展性。
那如果选择了Python或者Ruby等脚本语言进行开发却需要大量高并发的操作该怎么办呢我们可以选择多进程不是多线程编程的方式进行开发代码尽量简洁、高效一个进程兼顾一个任务进程之间的通信方式要尽量高效、简洁比如可以使用自定义的队列等方式。
## 小结
学完这一节,你应该对使用各种编程语言来编写网络服务有了一个更深的了解。我主要讲了以下几个内容。
* 编程语言可以大致分为三类,系统级编程语言、专为网络服务器开发的编程语言和解释型脚本语言。
* 在编写网络服务的时候可以根据要编写的是Web服务、Socket服务还是混合模式来选择合适的编程语言。
给你留一个小问题吧。
如果让你来使用C/C++粘合Lua脚本来编写网络服务器你会怎么设计这个程序框架
欢迎留言说出你的看法。我在下一节的挑战中等你!