BT

你的观点很重要! 快来参与InfoQ调研吧!

JRuby核心开发者Ola Bini谈语言的设计,多语言编程与信息安全
录制于:

| 受访者 Ola Bini 关注 0 他的粉丝 作者 丁雪丰 关注 3 他的粉丝 发布于 2013年9月27日 | ArchSummit社交架构图谱:Facebook、Snapchat、Tumblr等背后的核心技术
24:48

个人简介 Ola Bini是JRuby核心开发者,Seph和Ioke语言的创始人,JesCov等项目的发起人。他是瑞典人,目前是Thoughtworks的软件工程师。

   

1. 你好,Ola,很高兴你能接受采访。大家都知道你是JRuby的核心开发者之一,能否向大家透露一下当初是什么把你吸引到JRuby阵营的?

Ola:当然可以。我想那大概是七八年前了,那是相当久远的事情了,我做了很长时间的Java开发者,对Java非常不满意,我总是乐此不疲地寻找更好的语言。我曾是一个Lisp项目的成员——那个项目大概是叫Jatha,尝试在Java之上提供一个Common Lisp实现。但后来我意识到在我所效力的企业环境里不太可能在生产中使用Lisp,就算它能用,情况也是一样的。

我放弃了那个项目,后来就发现了JRuby,我知道Ruby有段时间了,还写了几年的Ruby代码。在我发现JRuby时,它真的只能算是个玩具,我、Charles Nutter和Tom Enebo一起做了很多艰苦卓绝的工作,Nick Sieger后来也加入了进来,我们四个人一起奋斗了两年,做得很辛苦,把它从一个玩具变成了一个能够运行任意Ruby应用的真正的Ruby实现。

如今,我已经不再活跃于JRuby社区了,但在我做Ruby项目时,我还是会使用JRuby,因为它真的很好用。不仅运行起来更快,而且垃圾收集也比普通的Ruby更好。

我想说,JRuby吸引我的地方,最初是能把JVM作为运行Ruby的平台。但是就现在而言,我喜欢JRuby是因为它是个高质量的实现。可以说它是我所知道的质量最好的一个。它很快,比原来的Ruby实现快多了,而且可以透明地访问所有的Java库,这意味着它是个完整的解决方案,你能用它做出你想要的各种东西。在ThoughtWorks做项目,这一点更为重要,因为我们经常在不同类型的企业里工作,这相当于变相地使用Java,能在Java平台上使用Ruby是非常棒的事情。

   

2. 那么你当初为什么不选择Rubinius或其他的Ruby实现呢?

Ola:在我开始参与JRuby时还没有Rubinius,它是几年后才出现的,即使它出现了,也没有带来比Java平台更多的好处,所以对我而言,选择JRuby是理所应当的。

我不认为当时还有别的Ruby实现,IronRuby姗姗来迟,XRuby也是如此,它们出现时我们已经在JRuby上下了不少功夫了。实际上当时有个Parrot,但它从没被完成过,并不是一个能实际使用的稳定环境。

   

3. 既然你已经有了JRuby,为什么还要创造你自己的语言——Ioke呢?

Ola:我为什么创造Ioke,是因为在Ioke之前,我学习了很多语言,但这仍不能阻止我去寻找一门终极语言,最好的语言。我一生中的大部分时间里,都觉得自己非常喜欢Lisp,认为它绝对是功能最强大的语言。但后来我失望了,意识到它们都不是最让我着迷的,甚至可以说它们都挺垃圾的。我渴望找到一门强力语言,能以我所期望的更强大的方式来做些事情,因此我创造了Ioke。
Ioke并不是种用于生产环境的语言,它是实验性质的语言。我想用这些语言特性来做些实验,看看语言究竟能有多强大。这就是我创造它的原因。

   

4. 那JRuby是不是也让你失望了?

Ola:应该这么说,“失望”这个词不太确切。记住,Ruby是语言,JRuby是种实现。Ruby语言在很多地方很出色,但它也有很多缺点,而且不如其他某些语言强大。我仍旧在很多工作中使用Ruby,但它只是个工具,我会在合适的地方使用它。

   

5. 你能否给出一些例子,Ruby不适合哪些场景呢?

Ola:Ruby的很多方面都很不错,但有时它的标准库会挡道,有时语法会碍事,很多语法级变换是做不到的。在Ioke的主实现中,它的宏要比Lisp的宏更强大,那些宏能让你的代码同时兼具可读性,又十分短小精悍。这应该能算是一个例子。

我的意思是很难通过口述的方式来回答这个问题,给出代码示例应该会更方便一些,人们给出了很多例子演示Ioke能轻松地办到某些事情。

我也是基于原型的面向对象模型的大粉丝,我并不认为基于类的面向对象能多么有用,即使大多数语言在使用基于类的面向对象。我觉得大多数语言这么做是因为它易于实现而且更快,对我而言这只是一种优化。出于易于优化的目的来选择语言结构,这种做法不对。

   

6. OK,能否向大家简单介绍一下Ioke,因为大多数读者朋友并不熟悉这门语言。

Ola:这是门动态类型语言,一切都发生在运行时,它非常灵活,拥有宏,而且是真正的宏。你所运行的所有代码在运行时都是可访问的,一切都是可变的。Ioke并非函数式语言,它是基于原型的,也就是说对象是继承自对象的,与另一门基于原型的语言JavaScript相比,JavaScript中的对象实现更讨厌,还很困难。Ioke让你能轻松地构建大的对象层次,用它来建模你的程序。

我用TDD编写了整个语言,也可以说我用TDD设计了这门语言。我在拥有能编写代码的语言之前就用Ioke写了第一个测试,但这也意味着我有能覆盖整个语言的测试用例。我还创建了一个运行得很好的.Net实现。Ioke还有个不错的Java集成,你能使用Java库等等。

Ioke拥有很多特性,几乎所有特性都是用Ioke本身来实现的,Ioke语言足够强大,你那些用C和Ruby实现的很多东西都能用Ioke来实现。以Python中的推导式(comprehensions)为例,这是Python的一项语言特性,在Ioke中只是一个小的库而已。

   

7. 这么说JRuby和Ioke都是基于JVM的?

Ola:是的,当然Ioke也能很好地运行在CLR上。

   

8. 看得出你非常喜欢JVM平台。我们现在有了invokedynamic,在不久的将来,JVM上的动态语言将拥有更好的性能,我们该如何充分利用该重要特性呢?

Ola:是的,我很喜欢JVM。我认为JVM有很多特性,让它成为很多语言的基础。对Ruby VM而言,它拥有垃圾回收、线程和一大堆库,即便如此,JVM也许不是最理想的,但你可以利用这些东西。

说到invokedynamic,我实际是定义invokedynamic的专家组的成员,它的主要目的是更方便地在JVM上实现语言。invokedynamic是字节码,使用它的方式不太容易解释清楚,基本上你可以认为invokedynamic能让你加速调用点依赖、使用应用、说明逻辑,还可以使用名为方法处理器(method handles)的东西,可以将其组织成图(graph)——图是比字节码更底层的东西,也就是说你能用它和即时(just-in-time)编译器通信,如此一来编译器能更好地进行决策,知道怎么做内联(in-line),诸如此类的事情。因此invokedynamic不仅针对动态语言,它针对的是需要其他调用行为的任意语言。

以Ruby为例,这是个好例子,在现在的JRuby实现里,Ruby语言里有常量,但常量可以被重新定义,因此它们不是真正的常量。然而,这种重定义并不常见。所以我们使用invokedynamic来缓存常量值,只要它们不重新定义,就能一直缓存,我们使用名为切换点(switch point)的东西在需要时将值换掉。 我想说,无论你使用的语言实现是否理解或使用invokedynamic,JRuby的实现中都有很多好东西可以参考。JSR292专家组中的另一位成员——Remi Forax,他有一个代码库,其中的代码演示了各种不同的使用模式,你在实现语言时能用invokedynamic做很多想做的事情,比如实现多态内联缓存等等。 要上手invokedynamic,我认为那是最好的入门材料。我只是想让你知道,Java语言中没有invokedynamic的语法,你不得不自己构造字节码来执行它。

   

9. 好的,接下来让我们聊聊Golang,它最近很流行,你是如何看待Golang的?

Ola:我不知道为什么人们会说它流行,它为什么流行?我的意思是很多人都在谈论它,但我却没看到多少人实际用它。

就我个人而言,我觉得它很无聊,没有使用它的理由,但这仅是我的个人观点。我觉得它是一个奇怪的混合体,太高层了以至于它做不了太底层的东西,但它又高的不够,做不了真正有用的高层的事情。其中有些有趣的语言特性,但总的来说我不觉得我会使用它。

   

10. OK。你既然已经实现了这么多语言,那就你看来,实现一门语言时最困难的是什么?

Ola:这个问题很难回答。我觉得实现一门语言要下很多功夫,最困难的部分是设计语言,正确地设计语言,设计能为开发者带来良好用户体验的库,与此同时还要尽可能地以高效的方式来进行实现。找到其中的平衡点并实现这部分内容是件难事。实现部分虽然不简单,但相比设计而言,已经简单不少了。

我在很多实现细节上都不够用心,因为我的语言是高度实验性质的,所以我并没要求自己有高性能的实现,这不是Ioak的目标。因此我在语言设计上花了更多的时间。

但在JRuby中,在JVM上最困难的部分是实现一种和Java有着截然不同语义的语言,还要兼具高性能。以JVM为例,它是面向对象的,它能理解类,但那些类必须和Java的类相似。它们事后不能改变。如果你想让语言跑得更快,还要考虑诸如原子类型之类的问题,因为Java有原子类型,而实际上在实现语言时它带来了不少的麻烦。因此你需要考虑一些专门的问题,做些特殊处理。

但从另一方面来看,我不需要去编写线程子系统,不需要编写编译器、即时汇编程序或其他类似的东西,也不需要编写垃圾回收器。做这些东西都需要在普通的语言实现里花费很多时间和精力,而我在JVM里不需要做这些事。这是种权衡,但我说不上哪个更困难一点。

我可以告诉你的是语法分析这件事一点都不难。语法分析很简单,每个程序员都应该知道如何进行语法分析,因为这是个非常有用的工具,你的腰带上少不了这么一个工具。你读了龙书之后就感觉自己会惧怕语法分析,但实际上语法分析真的很简单。虽然它不是最重要的部分,但语法是语言的用户体验的一部分,设计语法是很重要的。语言的语义的重要程度还要更高一级。

   

11. 你鼓励大家以适当的方式使用多种语言。能否就混合(hybrid)编程给大家提供些建议?

Ola:我们通常称其为多语言(polyglot)编程。我在Agile China和其他一些地方就多语言编程做了些演讲。
一般来说,为任务选择一门正确的语言是很重要的事。你不能随随便便跑出去,操起一门语言,把它和另一门语言比较一下,希望这样能奏效。在选择向项目中添加新的语言时,要小心谨慎。要考虑到如何让它与人和产品打交道,但也不要畏惧添加新语言。学习一门新语言其实和学习新框架差不多,是学习Ruby容易一点,还是从头开始学习Spring Framework更容易一点呢?我觉得就算你会Java,也是学习Ruby更容易。因此我认为我们不该过高地估计学习新语言的困难程度。
在我最近做的一个项目里,我们把Clojure作为主要语言,同时使用Ruby做了很多数据处理的工作,一开始前端用了JavaScript,后来切换到了CoffeeScript。我们使用Python和Puppet来处理基础设施,因为它们处理这些事情得心应手……每个时刻我们都有很好的理由使用某种语言,而且我们也充分地理解我们正在做的事情。
另外,我认为入手更方便,更容易取得丰厚回报的方式是在测试中使用更好的语言。要是你摆脱不了Java,那么你仍然可以说服利益相关者或项目经理“如果用Ruby来做测试,我能多写一倍的测试,而且还易于管理,项目的质量也会更好”,诸如此类的。

   

12. 最近我注意到你发表了不少安全相关的内容,同时涉及个人安全和机构安全。为什么你现在开始关心这方面的东西了呢?

Ola:安全、隐私和匿名性都是重要的问题。它们被我抛在脑后已经很多年了,实际上我的第一份工作就是安全编程。Aaron Schwartz是我们的同事,他也是我的朋友,惊闻他的噩耗时,我决定重新关注这些问题,因为我认为它们正变得越来越重要了,我们开发者有义务考虑、关注这些事情,我们做的还不够。

当然,6月的斯诺登事件让我们变得更加重要了,但这并没有改变现状,现在的因特网对任何人都是开放的。安全是小,隐私是大,我们离监管状态已经不远了——全球性监管,而不是一个国家一个国家单独监管。因此我决定改变我的关注点,花时间寻找与我刚才说到的内容相关的不同问题。我了解的还不多,但就我目前了解到的内容我已经做了不少思考。

有不少大规模问题,比如因特网架构问题、DNS问题、SSL问题、美国云基础设施的集中化问题等等。但我们也有一些小问题,比如你知不知道那些按钮?Facebook的“Like”按钮,Twitter的“Share”和“Like”诸如此类的。

大多数人都不知道如果他们访问一个页面,上面有这些按钮,你不用点击按钮,Facebook、Google或Twitter就能知道你访问过这个页面。所以,如果你在看卫报,正在读斯诺登的文章或别的东西,如果在中国,你正在看在线的报刊,上面有一个分享到微博的按钮,就算不点击链接,微博也能知道你在看哪篇文章。也就是说,Google、Twitter和Facebook等所有公司,以及中国的类似公司,它们拥有比你的浏览器里更完整的历史记录。现在,我们的政府和这些公司能更清楚地知道你在做什么,远比从你的电脑上能获知的内容要多,这是件很恐怖的事。

另一件恐怖的事情和密码有关,大多数人并不知道如何安全地使用密码。如果你能记住全部的密码,而且还不去用它们,我们看看会是什么情况。有一个例外,你就记一个密码,而且这个密码是用在密码管理器上的,这样很好。但如果你记住了全部的密码,那么你的密码是不安全的,它们并不保险。如果你能记住它们,就说明密码的定义不够强,不足以抵御破解。

有个名为Hashcat的很酷的程序,它是用来破解密码的。Hashcat在一台主流的Windows电脑上能在一秒里测试20亿个密码,不是200万,是20亿。因此,如果你用弱密码——弱密码是所有16个字符以内的非随机字符组合,攻击它的人就能把它猜出来。我们已经看到很多公司在这上面栽跟头了,几个月前在美国,LivingSocial宣布他们被黑了,损失了5000万密码,那些密码是用SHA1散列过的,也就是说它们很容易破解,这种情况无时无刻地发生在世界上的各个角落里。

目前的状态是我们作为个人没能很好地保护好自己。但作为技术人员,我们没能做好我们的工作,保护好大家,与此相关的事都责任重大,我们都责无旁贷。这就是为什么我会关注安全话题。

   

13. 最后一个问题是关于JesCov的,我们都知道这是你开发的一个JavaScript测试覆盖工具。能否向中国的开发者社区介绍一下这款工具,以及你开发它的初衷?

Ola:JesCov是个非常简单的工具,它允许你对JavaScript进行测试,获得测试覆盖率的报告。我创造这个工具是因为JavaScript是门糟糕的语言,糟糕透了。如果我能从所有浏览器中除掉JavaScript,那我会义无反顾地去做这件事,可惜我不能。所以问题就来了,既然它这么糟糕,那么做测试就非常重要了,我们要认真对待测试。运行JavaScript时也要非常小心。由于人们很容易就能写出不好的JavaScript代码,所以就要加倍小心地去写好的JavaScript代码。

为了写好JavaScript,我们需要工具,人们开始对JavaScript代码进行测试。关于JavaScript测试涌现出了越来越多的工具。看得出来,大家都在做测试,可是如果你对测试的覆盖率一无所知,那么自然也就不知道哪些代码没有被覆盖到。基本上错误就是静静地等待发生的那一刻。JesCov能让你获得一份报告,显示出哪部分代码被测试覆盖了,哪部分没有被覆盖到。

为了实现JesCov,我在Rhino上做了些不太优雅的修改。既然我们在绝大部分项目里进行测试覆盖,我们也覆盖了绝大部分的东西,那么为什么在JavaScript上不这么做呢?原因就这么简单。

采访人:我们的采访到此告一段落了,非常感谢!

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT