跨平台到底是不是谎言?

作者:老赵

前几天是个神奇的日子,博客园里咣咣咣地出现了三篇文章,都包含了跨平台谎言这两个关键字。从Java开始谈到.NET,最后哐地一下,跨平台本身也变成一种谎言了。从文章内容上看,我个人觉得基本不靠谱,主要论述方式是用气势或是自信来压倒对方……呃,是说服别人。我不打算谈那两篇文章的内容了,许多意见我和其他人也在文章后面回复过了。我现在只想在这里简单谈谈我对跨平台这个问题的看法。

关于跨平台这个问题,我感觉还是要分客户端服务器端两个方面来谈,或者说表现层服务层,或者说带界面的跑服务的”……总之您明白就好。当然无论拿方面都还是要再细说的。

说到客户端程序,譬如说是一个桌面应用,那么它的跨平台也是很尴尬的东西。就说UI吧,你说不靠谱,它的确能用;但如果你说它挺好,它从视觉效果,使用体验,样式风格方面,都会和周围环境有些格格不入的感觉,无论是SwingGTK还是QT,跨平台的UI库都有这个问题。其实这也十分容易理解,一个跨平台的UI库,它的确可以做到在不同平台上出现相同的样式或风格。但是,不同的平台,如WindowsLinux或是Mac,它们的桌面环境都有着非常明显的区别。而即便是XPVistaGnomeKDE,再加上各个参数细节的定制,想要在单一平台上做出合适的界面都是不太容易的事情,更何况跨平台。而且,即便一个界面的Look与周围环境一样了,那还有Feel这个说不清道不明的东西。水果公司为了保证界面美观,还提出了详细的用户界面规范,您说这让跨平台的UI库情何以堪?

当然,这方面还可以往细了说。例如,我觉得从某些小处来讲,跨平台的UI库还是很有市场的。比如说SilverlightFlash,它们的应用场景一般是网页中的一小部分,关注的可能是一个页面而不是系统应用的体验。再往大了里说,例如您在做一个游戏,那么选择OpenGL就比DirectX更容易移植到各个平台上去(如果拿SilverlightFlash做独立的RIA也可以算做这种情况)。在这些情况下,我觉得跨平台的UI库是很有意义的,但它们也有个特点,那就是对系统环境Look & Feel的依赖很小,它们的界面自成一体,更像是从一个空白的画布上自己重新造轮子的情况。对它们来说,老子本来就不需要来迎合你,那还有什么可担心的呢?

因此我对这方面的质疑,说的更具体些,可能应该是那些带窗体的、组件形式的可复用的UI吧。

那么服务器端是不是就没问题了呢?反正看不到。不过我倒感觉正好相反:客户端跨平台主要问题是感官上的,对我这种非艺术家来说忍忍便罢,而服务器端的问题在我看来就是叔可忍,婶不可忍了。说到服务器端跑的程序,总是给人一种高性能,高可用性啊,高稳定性的感觉,总而言之对运行效果的要求很高。那么,跨平台的服务器运行机制,能否做到在各个平台上都用最佳状态工作呢?

这并不容易,因为如果要提供最高质量的服务,往往都需要利用到平台自身的特性。即便是CPU密集型应用理论上也会受到操作系统的虚拟内存管理机制的影响——更别说网络通信等IO密集型应用了。举个例子吧,Nginx是个高性能的Web服务器,主要跑在*nix环境下,也可以运行在Windows下(是直接使用Win32 API开发的,不是利用Cygwin做中间层的方法)。这看上去做到了跨平台,但是说到细节的话,Nginx*nix下面用了高效的epollkqueue,而在Windows下使用的便是低效的select了。同样,JettyMina等框架所依赖的nio,在Java 6中已经开始使用epoll,而对WindowsIOCP的支持,只能等到尚未发布的Java 7了。要知道IOCP作为一种与epoll类似的基于事件的IO机制,早在NT 3.5 / Windows 2000就出现了,而Java 6诞生于2006年底,我相信时间不是问题。

所以问题就来了,在我看来跨平台不仅仅是能够运行的意思,运行的好不好也是十分重要的一点。前一段时间水果教主Flash的指责得到了果粉们的一致拥护,许多人还补充了更多理由,其中一点便是“FlashMac的支持很不好,虽然能运行但是资源消耗严重(事实的确如此),接下来就是说Flash目前的处境是自找的等等,不提。那么,比如NginxMina,它们在*nix下表现良好,而跑到Windows下面如并发能力就大大折扣了,这又算是谁的问题呢?与Flash问题的看法相同,我不认为这是WindowsMac OS的问题,问题出在跨平台的机制上。

但我也不会去责怪NginxJava(但我会去XX那些因此认为Windows性能差的说法),因为跨平台本来就是很不容易的事情。有时候,即使两个平台都提供了高性能的编程模型,但是它们的编程模型不同,很难用相同的模型进行统一,而强制统一带来的折衷效果可能就变成都不是最佳。而且即便能够做到在多个平台上实现最好的性能,也需要我们去投入更多的分散的精力——那么,如果我们把这些精力放在对单一平台的努力优化上面呢?因此,我也很能理解如Go语言不支持Windows的情况,用来做服务器的语言么,只支持单一平台也无可厚非。

而且说实话,我也并不是很看中跨平台这一点。有些人说Java.NET好的理由是,Java能跨平台,而LinuxWindowsXX,又YY,还不要钱。但事实上,那些朋友看中的是“Java能运行在Linux而不是“Java能跨平台。而即便Java只能运行在Linux上,对他们来说也就够了。对于一个正经的应用,您会动辄迁移它的运行平台吗?就我许多年前写Java的微薄经验来说,就见到过一次把应用服务器从Websphere迁移到WebLogic而导致问题不断的情况。完美的基于标准的(这是跨平台的必要条件)实现只能存在于理想之中,想想浏览器就能理解这点了。同理,我中意mono,也不会强求它多么多么追求与MS .NET实现一致,我对它的期望只是个足够好的.NET运行环境就行了(当然也不能跨得太差了)。

顺便插一句,我上面的说法可以得到一个推论:对于一个服务器应用来说,程序员在工作时的运行/调试环境要尽可能与生产环境相符。例如一个在Windows下运行调试的Java程序,但生产环境下却是部署在Linux下的做法我就感觉不靠谱。如果真因为条件限制,至少持续集成时的环境要和生产环境尽可能一致吧?同样的情况还有在Windows XP上开发ASP.NET应用程序的人,在我眼中这就是无比山寨的做法,甚至我认为对此没有怨言的程序员也是相当不专业的。

这样看来,不知道是否有朋友会认为我觉得跨平台是谎言”——我可没这么说。我常干的事情(例如就是这次的谎言事件),便是跳到某个针锋相对的场景,比如.NET vs Java,左边扯扯右边拉拉,谈点楼主的问题,也反对一些楼主反对方的看法,所以千万不要以为我反对您的(部分)说法就是在赞同您的对手的(反之亦然)——总之,千万要仔细理解我的意思才好。事实上,虽然我指出了跨平台的一些问题,也可以理解不跨平台的做法,但是我同样认为,无论是.NETJava在二进制层面上,还是如C++C语言(也包括如PHPJavaScript等)在语言层面上的跨平台,都是有足够优秀的案例,或者说是实现的。而各种跨平台的机制本身,也可以显著减少程序员对于平台的依赖,也大大简化了开发跨平台应用程序的难度。

总而言之,我认为跨平台不是谎言,它是成功的,也是必要的,虽然有缺点,但还是值得努力的——就是这样。

此外,文章里的平台大都是指操作系统,但事实上平台这个概念远大于此,比如CPU体系结构,浏览器等等都算是平台——因此,其实我的意愿是您可以用一种泛化的方式来理解文章的意思。

 

posted @ 2010-06-30 14:15  博文视点  阅读(353)  评论(0编辑  收藏  举报