责任编辑最初发布于 Peter Wayner 博客,经原作许可由 InfoQ 英文站译者并撷取。
在排序历史上,1995 年是一段狂热的光阴。首先 Java 再次出现了,随即 JavaScript 也再次出现了。Java 和 JavaScript 的名字看上去像是一对孪生,但实际上它差异巨大,Java 是被撰写和动态入役的,而 JavaScript 则是被解释和动态入役的。但这仅仅是这两个全然相同的词汇的控制技术差异的两个开始,Node.js 的再次出现使两种词汇经历了四条全然相同的发展抛物线。
如果你比较早的碰触了 IT 控制技术,那么你也许提过 Java 曾经红极一时,每个人都将其视作一项革命,指出它将全然代替排序。但在我看来,这一预测只有一部分是恰当的,Java 统治者了Android手机、企业排序和许多PDP设备,如光碟CD。但它唯独没有统治者过图形界面或插件。人们曾试著出售过小插件和 Java 辅助工具的强大,但表现差强人意。
同时,以后被开发人员们错指出是 Java“孪生”的 JavaScript,如今也能平步青云了。在 HTML 和 web 推出 Borg 的几年间,JavaScript 一直紧随,AJAX 的再次出现使 JavaScript 突然之间保有了力量,冲破了以后的局面。
随即 Node.js 问世了,大大降低了开发速率。JavaScript 不仅在伺服器上比大多数人预期的要快,甚至与 Java 或者其他辅助工具相比,速率也要快。JavaScript 能够更为稳定地处理小的、快速的和连续不断的数据允诺,因此,当页面显得更为动态时,Node.js 就显得更为常见了。
虽然这在 20 天前可能将是无法想象的,但现在 Java 和 JavaScript 正在争夺战程式设计领域的“统治者权”,它两个特别强调以厚实的工程和构架为微细此基础,另两个特别强调简约和社会性。到底是旧式的C++驱动力的 Java 会开疆拓土,还是在 Node.js 帮助下的 JavaScript 将所向无敌呢?
Java 获得胜利之处:长存的此基础
看到这个杜博韦,可能将有些开发人员会有批评。当然,我们不驳斥 Java 还存在许多小 Bug,但相比之下,Java 已经称得上很“厚实”的了,Node.js 想让我保有这样的信心,还需要很多年。
事实上,要写出与 Sun/Oracle 在测试 Java 虚拟机时所写数量相同的回归测试,JavaScript 开发人员也许要花上几十年。当你启动 JVM 时,你将获得来自两个质量可靠的管理者的 20 年经验,而这个管理者一直决心要统治者企业伺服器领域。
不过,JavaScript 也在迅速迎头赶上。当 Web 的大部分依赖于 JavaScript 执行引擎时,开发人员的时间大部分花在了打磨边边角角上面。然而,所有的创新都有两个缺点,那就是新的功能可能将扩散太快,以至于开发人员们来不及吸收这些功能。许多老派的开发人员经常会对充斥着最新 ECMAScript 句法的增强特性感到困惑。另外,这些新代码可能将还会导致某些旧版插件崩溃。
创新性的预处理器,如 CoffeeScript 和 JSX 等,源源不断地再次出现,对于需要这些功能的开发人员来说是件好事,但对于不需要的开发人员来说增加了难度。
尽管 Java 也在不断推出新的功能和选项,但总体而言,它是两个稳定的平台,它给那些需要开发更长久的东西的开发人员带来了便利。
Node.js 获得胜利之处:社会性
多亏了 Node.js,JavaScript 在伺服器以及插件领域找到了一席之地。你给伺服器写的代码很可能将在插件上也能运行。很明显,比起在 Java 和 JavaScript 中分别写代码,直接使用 JavaScript 更简单。
如果你决定要把 Java 中的伺服器业务逻辑迁移到插件中,或者老板执意要你把给插件写的逻辑迁移到伺服器上。在这两种情况下,Node.js 和 JavaScript 都能让代码迁移显得更简单。
不仅如此,Node.js 的领导地位似乎还在扩大,例如比较复杂的 Web 框架,类似 React,是要把代码运行在伺服器还是客户端上呢?另外,还有可能再次出现这种情况,代码前一天是运行在客户端上的,但后一天可能将就运行在伺服器上。某些智能的逻辑将在运行时根据负载、闲置 RAM 容量和其他因素来决定究竟代码运行在什么上面。有些框架会把 JavaScript 作为一条查询,输入到数据库,并在那里执行。你的代码可能将在任何地方运行,所以,你很难了解究竟是在什么地方,因为代码根本不会返回任何东西。但也无需担心,因为你不需要考虑太多细节。
Java 获得胜利之处:更好的集成开发环境 (IDE)
Java 开发人员保有三大 IDE,Eclipse、NetBeans 和 IntelliJ,这三个 IDE 是与调试程序、反C++和伺服器良好地集成的顶尖辅助工具。每个辅助工具都经过了数年的开发,保有忠实的用户、厚实的生态系统和数不尽的插件。
大多数 Node.js 开发人员会将文字输入命令行,再编码到他们最喜爱的文本编辑器中。诚然,市面上最好的许多文本编辑器,像 Atom,都拥有琳琅满目且几乎无所不能的插件,但如果和 Eclipse 进行比较,Node.js 给人的感觉要更旧式许多。在不久的将来,Atari 操纵杆将代替我们的鼠标。
另外,有些 Node.js 开发人员会使用 Eclipse 或 Visual Studio。开发人员对 Node.js 突然激增的兴趣可能将会有新辅助工具问世,例如IBM 的 Node-RED 给我们提供了许多极具吸引力的方法,但这些辅助工具还远未达到像 Eclipse 或 IntelliJ 那样的完整度和统治者地位。
但奇怪的是,开发人员好像并没有使用这些辅助工具。命令行本该在 35 天前 Mac 到来时就消失,但却没人把这个消息告诉 Node.js 的开发者们。但选择一直都在那里。例如,WebStorm 就是两个可靠的由 JetBrains 开发的商业化辅助工具,它集成了许多命令行构建辅助工具。
当然,如果你正在寻找一款能够编辑和调整代码的集成开发环境,那么现在支持 Node.js 的新辅助工具已经足够使用了。但如果你希望集成开发环境能够让你一边操作正在运行的源代码,一边编辑代码,那么 Java 的辅助工具显然会更强大许多。
Node.js 获得胜利之处:数据库查询
许多较新的数据库,如 CouchDB 和 MongoDB 的查询是由 JavaScript 撰写的。将 Node.js 和数据库调用合并不需要任何换挡,也不需要记住任何句法差异。
而许多 Java 开发人员都在使用 SQL。即使是在他们使用 Java DB——前身是 Derby (一种由 Java 撰写的数据库)时,他们的查询也是用 SQL 写的。你可能将会以为他们会简单地调用 Java 方法,但其实没有,开发人员必须要用 SQL 写数据库代码,然后再用 Derby 解析 SQL。 虽然 SQL 是很好的词汇,但它与 Java 全然相同,许多开发团队需要有相同的人来分别写 SQL 和 Java。
更糟糕的是,许多 Java 开发人员使用复杂的库和模式来将 SQL 查询数据转换成 Java 对象,目的是让自己能够将这些东西重新导入到模板中。这个过程非常狂热,而且非常浪费。
Java 获得胜利之处:类型
许多入门级的程式设计课程都使用 Java,因为许多开发人员都喜欢动态类型编码,动态类型编码很简约而且安全。在C++找出了许多明显的 bug 后,代码看上去更为严谨了。
不过,JavaScript 也在追赶,许多开发人员已经转到 TypeScript。TypeScript 是两个动态类型的 JavaScript 超集,首先会应用所有的类型检查手段,然后剔除掉运行在插件上的 JavaScript 堆栈中的许多东西。
对于喜欢类型的开发人员来说,TypeScript 足以让你喜欢上 JavaScript。当然,你可以把 JavaScript 这种模仿视作是对 Java 最真诚的恭维,并且继续使用 Java,因为 Java 从一开始就是使用动态类型的。
Node.js 获得胜利之处:语法灵活性
JavaScript 曾经是两个简单的词汇,用于弹出警示框和双重检查输入表。后来,开发人员社区创造了 JavaScript 的许多相同版本,它能够被转编译为插件可用的东西。例如,CoffeeScript 提供了许多相同的句法,旨在使标点符号更为清晰。React/Vue 群体将 HTML 和 JavaScript 混合。此外,还有针对类型爱好者的 TypeScript 和针对功能词汇信徒的 LiveScript。
而在 Java 中,你会发现有很多创新,但这些创新由于某些原因,并未用预处理器进行表达。还有许多词汇如 Kotlin、Scala 和 Clojure,为了 JVM 专门变成了字节代码,但不知为何,它可以说是全然独立的词汇。对于喜欢试著相同的代码撰写方式或标点符号的 JavaScript 开发人员来说,所有的预处理器均使他们的生活显得更为有趣了。
Java 获得胜利之处:简单的构建流程
复杂的构建辅助工具如 Ant 和 Maven 使 Java 程式设计发生了革命。但还是有两个问题,开发人员需要将说明用 XML 写出来,而 XML 并不是两个支持程式设计逻辑的数据格式。
当然,使用嵌套标签来表达分支相比之下比较简单,但仅仅是为了构建,就要从 Java 切换到 XML,有些令人讨厌。有了 JavaScript 后,你就不需要再切换。
之前,Node.js 的构建很简单,只需要编辑代码,点击“运行”就可以了。但随着 Node.js 开发人员不断改进流程,添加了许多预处理器来抓取你最喜欢的 JavaScript 方言,并将这种方言转换成可以运行的东西。然后,Node 包管理器需要找到恰当的库,因为有时可能将会找不到,所以需要花时间寻找某个工件恰当的版本号,而这个工件必须在单独的步骤中自行构建。而且,如果你在工件库中引入了许多错误,那么,这个版本号便无效了,需要重新做。
Java 也有与 Node.js 方法类似的复杂的构建过程,但给人的感觉不会比 Node.js 更复杂,从某种意义上说,Maven 和 Ant 貌似已经成为了 Java 此基础的一部分,许多粗糙的边角已经被去除了,因此构建的工作成功率更高了。
如果非要对它的构建难度进行衡量的话,它可能将不分伯仲,但如果从 JavaScript 快速增加的复杂度的角度来看,Java 在这方面获得胜利了。
Node.js 获得胜利之处:JSON
当数据库给出答案时,Java 需要花费大量时间把结果变成 Java 对象。开发人员会就 POJO 映射、Hibernate 和其他辅助工具争辩上好几个小时。配置这些东西耗费数小时甚至数天时间。最终,在所有的转换之后,Java 代码获得了 Java 对象。而来到配置阶段时,Java 使用的仍然是 XML,并且提供了 2 个主要的解析器,这给开发人员带来了更多的烦恼。
如今,许多 Web 服务和数据库都以JSON的形式返回数据,JSON 是 JavaScript 天然的一部分。JSON 现在非常常见和有用,以至于许多 Java 开发人员都在使用这种格式,而且还有许多非常好的 JSON 解析器可以作为 Java 库被使用。相比之下,JSON 本身就是 JavaScript 此基础的一部分,不需要库,直接使用就可以了。
Java 获得胜利之处:远程调试
Java 保有许多非常棒的监控机器集群的辅助工具。JVM 有微细的钩子和精细的剖析辅助工具来帮助我们识别瓶颈和故障。Java 企业堆栈上运行着全世界最复杂的伺服器,而使用这些伺服器的公司对遥测的要求非常之高,所有这些监控和调试辅助工具都较为成熟,并且可以立即部署它。
Node.js 获得胜利之处:图形界面
也许有人在使用 Java 小程序,但我仍然保留了许多可以点击运行的 Java JAR 文件。总体来说,图形界面领域大体上是不用 Java 的。另一方面,随着插件取代了图形界面的大部分角色,JavaScript 的作用也越来越大。当微软重写了 Office 并使其能够在插件上运行时,一切就注定了。如果你还想了解更多,那么市面上还有许多有趣的选择,比如Electron,它能够抓取你的 Web 代码,然后转换成独立的图形界面 app。
Java 获得胜利之处:手持设备
Android app 大多都是用 Java 写的,而且 90% 的新手机都运行着各种版本的Android系统。很多人根本就不使用图形界面了,因为手机已经可以做任何事情了。
许多开发人员都在撰写 Node.js Web 应用,这些应用主要用在 iPhone 和Android手机上的移动插件上。如果这些应用写得比较好,性能通常会比较好。但 Java 正以另外的一种方式入侵。最新的 Chromebook 将支持Android应用,从而给 Java 开发人员进入 Chromebook 用户的图形界面开辟了道路。那么 Java 是否仍有机会征服图形界面呢?
Node.js 获得胜利之处:库
Java 提供了大量的库,而且这些库做得都非常好,文本索引辅助工具如 Lucene 和排序机视觉辅助工具包如 OpenCV 都是非常好的开源项目,它都将成为其它重大项目的基石。JavaScript 开发人员也在追赶,创造出了很多了不起的项目。
在某些领域,Java 就是两个远程的存储器,市场上可能将有无数相同的 Web 框架,所以 Java 不能在这个新兴市场中参与竞争。
Java 获得胜利之处:厚实的工程
类的详情。市场上有 BigIntegers、精巧的 IO 例程和复杂的日期代码,它均实现了格里高里和罗马儒略日历。
JavaScript 适合简单的任务,但其内部有很多令人混淆的地方。举两个简单的例子,JavaScript 针对没有答案的函数会生成三种相同的答案,分别是:undefined、NaN 和 null。那么,哪两个是恰当的呢?其实每个答案都有各自的作用,其中两个便是驱使开发人员保持代码统一。JavaScript 更怪异的方面是虽然它在简单的表格工作很少出问题,但对于复杂的数学和入役工作而言,JavaScript 并不是两个好选择。
Node.js 获得胜利之处:速率
Node.js 的速率一直很受开发人员的欢迎,数据输入和答案输出的速率如同闪电。Node.js 不需要单独设置线程,也没有上锁等令人头疼的问题,也没有拖慢速率的额外开销,只需要写许多简单的代码,Node.js 就会快速地采取正确的步骤。
Node.js 的回调模型已经改变了其程式设计方式,使开发人员避免同时操作多个任务。JavaScript 引擎能够确定何时运行什么代码。因此,开发人员可以撰写更短和事件驱动力的代码,并且关注重要的逻辑。
但 Node.js 也存在许多问题,Node.js 代码要尽可能将的简单一点且工作正常,因为如果它锁死了,整个伺服器都可能将锁死。操作系统开发人员努力创建了许多安全网来抵抗程式设计错误,但 Node.js 会让这些安全网失效。
此外,当开发人员将回调函数如俄罗斯套娃一层又一层不断地嵌套时,还会再次出现两个代码复杂性的问题。两个回调还好,但一系列的回调令人抓狂,好消息是 Promise 模型很容易读。但你需要记住,在执行代码行期间,许多事情都可能将发生。
Java 获得胜利之处:线程
代码速率快虽然好,但更重要的是代码要准确,而使用 Java 可以享受到许多额外功能:
Java 的 Web 伺服器是多线程的。创建多个线程可能将要花费时间和存储,但这是值得的。因为,如果两个线程锁死了,其他的还可以继续用。如果两个线程需要很久的排序时间,那么其他线程可以分担。更重要的是,代码一直在掌管之下,并且能够进行调整。
如果某两个 Node.js 允诺运行速率过慢,其他允诺的速率也会降下来。Node.js 只有 1 个线程,因此只有它准备好了,事件才能被处理。也许它看上去超级快,但本质上它的构架就如同春节的时候,邮局只开两个办理窗口一样,即它不能同时处理多个允诺。
人们花了几十年构建智能的操作系统,能够同时处理许多相同进程的操作系统。那为什么还要回到那个电脑只能处理单线程的年代呢?的确,处理多个线程意味着要做更多的工作,但多线程更强大,不是吗?
Node.js 获得胜利之处:势头
看见硅谷的开发人员总是积极献身于最新和最具颠覆性的东西,但有时清理掉遗毒也很重要。Java 有新的 IO 例程,但它也有许多旧的代码,例如许多小程序和 util 类会阻挡你前进的道路。Node.js 在 Git 库中也留下了很多垃圾,但由于 Node.js 再次出现的比 Java 晚几十年,且 Node.js 开发人员还在研发许多针对 Web 堆栈软件的增强功能,所以,Node.js 动力十足。
两方不分伯仲之处:Java 和 Node.js 之间的交叉编译
伺服器到底是用 Java 还是 Node.js 的辩论可能将还会持续很多年,但与其他辩论相同的是,这场辩论可能将会是双赢的局面。Java 可以交叉编译到 JavaScript 中去,谷歌就经常在 Google Web Toolkit 中这么做,而且谷歌最受欢迎的网站也运行着 Java 代码,这些代码就是从 Java 译者为 JavaScript 的。
当然,反过来也是如此。JavaScript 引擎如Rhino和 Nashorn同样在 Java 应用里面运行 JavaScript,然后你可以链接到这些应用。如果还不满足的话,你还可以链接到谷歌的V8 引擎。
所有的 Java 和 JavaScript 代码都可以和谐地彼此链接,因此,你不需要在两者之间选择。
作者简介:Peter Wayner 是 InfoWorld 的特约编辑,并且是 16 本涉及相同主题的书的作者,包括《开源软件(统统免费)》,《自动化汽车(未来出行)》,《隐私增强排序(透明数据库)》,《数字交易(数字现金)》,《和隐写术(密码学的消失)》。他的书定期发布在 InfoWorld 上,并且他还为许多大小型软件项目提供咨询。他关于机器人汽车的《未来出行》这本书的第二版已经出版。查看英文原文:Node.js vs. Java: An epic battle for developer mindshare
推荐阅读
开发人员应该了解的五款 Julia IDE
推荐阅读点击了解更多