使用 Python、Perl、PHP、Ruby 等脚本语言开发 Web 程序,跟使用 Java 开发 Web 程序相比有什么优势?
程序员文章站
2024-02-02 14:25:28
...
回复内容:
两行python鸣翠柳,一坨java上西天。。。呵呵哒 大家都提到了开发快,我再提另一个:调试、测试都更加便捷。一方面,静态语言编译时间比较长,无论是调试和测试都不如动态语言快捷。我记得前段时间写 Android 程序,调试和跑测试都要经过漫长的编译、构建打包,我只好一边看电影一边等(编译一次半分钟左右,就先看个半分钟电影)。
另一方面,静态语言为了可测试性,已经往“动态”的方向做了许多努力。最明显的例子就是诸多 Java 开发框架都使用依赖注入容器来生产对象,以增加可测试性。看看它们是如何实现依赖注入的——写 XML 配置文件(或者 Annotation,一回事)然后运行时 DI 容器用反射 API 来动态实例化对象。想到这里我就想笑——静态语言将编译期-装载期-运行期三段严格分离,结果框架却费尽心思将装载期的动作转移到运行期。绕这么大一道弯,为何不直接使用动态语言呢?
动态代理实现 AOP 什么的,在 Java 框架中能炒出一堆概念,这在动态语言中早就是大家的日常了。静态语言打的多数是“有编译器检查”、“性能更优”两个旗号。这两个旗号中,前者根本保证不了什么——没有测试仅仅靠编译器的检查,后果是不堪设想的;后者在上述第二点中已经消磨得很厉害了,DI 容器、AOP 容器实现的动态化,性能上是没有办法和原生动态语言在 VM 内核中的实现相比的。加上 Web 应用一般不是处理器密集型,瓶颈一般在 IO 而不在运算,所以语言层面上跑循环、调函数高出来的那一点点效率根本算不了什么。
这些问题其实在大多数开发中都存在,不过在 Web 应用开发中暴露得特别明显,我想这和 Web 应用的快速生命周期有关。Web 应用的开发中,极快速迭代、大量依赖测试两个特点使上述问题被放大了,所以我想这也是为什么 Web 应用的开发大家更喜欢选择动态语言。 总的来说并不是Web程序的问题,而是Java这种语言在现在的编程时代已经过时了。
Java诞生在那个OOP(面向对象编程)的时代,它的设计初衷是用来完成一些非常巨大的软件工程的,在那个时代人们相信模块化、规范化、可重用性比什么都重要,而OOP是这些问题的唯一解决方案。而在互联网时代,代码规范性和重用性的重要程度下降了,快速、可用比任何指标都重要,因为慢意味着死。甚至,互联网时代的许多开发是允许一部分bug存在的,只要他们没有严重到影响用户体验。而FP(函数式编程)概念的兴起也在剧烈冲击Java的“一切都是对象”的世界观。
Java 程序通常是冗长、有非常多个文件组成,而且不把他们全部阅读一遍根本无法理解这些代码。很多文件仅仅定义了对象应遵循的规范(也就是 interface),而没有做任何实际的工作,但如果不做这样的工作就无法实现代码重用。许多对象仅仅包含了一组数据而没有任何实际的方法,而这些数据 必须首先定义存储变量、然后为每个变量来定义一组getter和setter来确保良好的访问控制能力。
即便你遵循了这些所有的原则,当你发现原 来的interface定义并不能满足实际需要,而需要增加新的接口函数的时候,你将面临着修改所有interface实现类的窘迫情形。如果这个新特性 仅仅在一部分实现这个接口的类中存在,那你的麻烦就更大了,你必须要定义一个新的interface并实现旧interface,然后将带有这个特性的类 重新实现新的interface。这使Java程序员变得不愿意修改接口实现,而是通过添加各种hack来完成功能,导致本来应该模块分明、结构清晰的代 码变得模块间强耦合、难以理解,越来越多的hack最终让程序变成一场灾难。
相对的,脚本语言都是强调实际功能的,基本上不存在不完成实 际功能的代码。动态语言特性使得修改数据结构变得异常容易,尤其配合json等序列化算法,很大程度上对于沿袭自C/C++的“不是严格定义的数据结构便 无法存储”的概念是一场革命。动态语言甚至可以更简单的实现可复用性,比如对于python来说,很多库函数并不要求传入的参数是某个数据类型,而是只要 具有某个名称的属性或接口便可以使用。最根本来说,脚本语言用定义的严格性来换取程序设计的灵活性,这样的程序不仅代码量少,而且“船小好调头”,才能适 应互联网时代需求经常发生变化的快节奏的开发模式。
Java、C/C++这类编译语言在开发非常复杂的系统的时候仍然是很有用的,但是对于互联网应用来说,这么复杂的系统不多。 说动态语言开发快的还算可以接受,说测试调试快我觉得真的是有些扯淡了。
无论是Java和C#,大家说起调试,默认的一定是IDE,断点,单步,动态语言呢?恕我对这些动态语言不熟,js这些年总算是可以在浏览器里面单步了,服务端的node有好用的单步debugger吗?python呢?pdb?ruby用什么?我真不知道,顺口问了一下旁边喜欢ruby的同事,回答是,好像有吧。说动态语言调试快的,你们真的觉得println的调试方法比IDE的断点单步快?
说Java打包发布要半天的,这个不算错,可你拿android来举例算什么?我们好像是在说web开发对不?先说说android,android慢是因为google做的android模拟器太慢,我当初做android的时候,用vbox做模拟器,从改完代码点debug按钮到停在断点处一般不超过20s,喘口气的时间是有的,要说喝咖啡看电影,还真来不及。
再说web应用的打包重启问题,跟动态语言完全不用重启比起来,我每天重启个七八次还是有的,但是,谁告诉你们每次修改代码一定要重启的?eclipse自带的tomcat插件每次都要你重新发布jsp才能生效那是因为那个插件太烂,还有很多好用的插件,干嘛非要用那个残废?java代码谁告诉你要重启才能生效的?说这话的人肯定没听说过jrebel吧?就算不用jrebel,hotspot本身支持代码热替换,你们知道吗?哦,你们公司的java程序员告诉你不行?那就是为什么他工资没我高的原因(如何在java web开发中避免重启: http://www.zhihu.com/question/20218920/answer/34155532 的后半段)。
再来说说编译检查的问题,说编译检查没什么用,反正有测试保证的,你们的代码做重构吗?在IDE里面对Java代码做重构,所有的引用关系都可以得到正确保证,这都得益于静态类型和编译检查,动态语言的重构有怎么容易吗?search and replace?别说有什么特牛x特强大的重构工具之类的,自己摸着良心说一句,有Java/C#这种静态语言这么方便,这么安全吗?你还在修复测试的时候,我已经push代码了好吗?
动态语言的好处就只有一个,开发快,可以快速的做出能用的原型来,这个在互联网时代是有重要意义的,谁也抹杀不了,但我们为什么还要用java来做web?因为java的静态特性能够给代码提供更长的生命周期,java好用的IDE能够大幅度提高代码调试的效率,当code base大到一定规模后,好用的IDE单步断点调试的优点是非常重要的,因为通读代码理解前后关系的效率是绝对比不上一个断点的。
好吧,我其实就是吐槽。 开发速度快?其实未必,java web开发有最成熟的框架吧,我觉得不是开发块。
而且java又比较强大的ide,如eclipse,调试之类的非常方便的。
脚本开发的话,我觉得主要是轻量,即不需要外围的许多工具即可,而且部署也简单,比如使用perl开发:
1. 下载mojolicious 这个模块:cpanm Mojolicious 然后就装好web框架了。
2. 使用mojo generate lite app 然后就生成一个web站点的模板了。
3. 你稍微改改,根据需要写点东西。
4. 使用 perl script/myapp.pl 就启动这个站点了。
ps: perl web开发还是很高效的,推荐用Mojolicious这个框架,代码风格非常好,实时,非阻塞,基于事件,依赖少,安装便捷:) 优势就是开发快,很多人提到了。DHH(Rails的创造者)也写过一篇文章说他为什么不用Java而发明Rails进行Web开发。
我只说一下调试的问题,既然有人问起。其实Ruby/Python这类语言的命令行调试工具就跟GDB差不多——用过GDB的就知道,其实也很好用的。当然如果想用IDE那也是有的,Eclipse就有插件,或者用其他一些Ruby/Python的IDE即可。其实对Web开发而言,能用IDE调试的情况非常少见——除了在本地测试环境下调试代码,其他情况基本没用。我做Web开发这么些年,没用过IDE调东西。命令行调试器可以让你在远程机器上,比如staging 甚至 production环境的机器上,比较方便地调代码,因此实用性更高一些。不过话说回来,在Web debug时,绝大部分情况下是看日志,各种日志,来分析问题,由于分布式系统的复杂性。真正需要用debugger的时候只是最后你通过日志把问题根源基本锁定了在一个很小的、可调试的范围了以后。
Anyway,你熟悉的工具对你自然有优势。你不熟悉Ruby,只熟悉Java,那Ruby再快你也用不到。 更多时间写代码,更少时间配环境。
在一台只有标准 Python 环境和 JDK 环境的 OS X 系统上,pip 安装 flask 写好一个 hello world 的时间,估计 Tomcat 还没下载启动完成…… 没什么优势。
关键看你熟不熟。
- Java 世界也有快速开发框架,其底层更加成熟,懂的人照样快速开发。比如 grails 和 play
- 脚本语言框架刚开始提供了脚手架和模板,让你快速搭建原型,但真做起应用来你要是不熟还是两眼一码黑,速度慢下来。
- xml 被很多人吐槽臃肿没错,但定义好的 xml 可以在很多 IDE 或者编辑器里轻松实现 DSL 代码提示,严谨又方便。
Java 当然很强大,但是太端正了。