从闭包到开源商业智能,甚至是 .net。有请 andy。 框架)的 …...写了 java...

46
-1 Java 技术专区技术播客系列:第 1 季 Venkat Subramaniam 谈论多语言编程、JVM 和 多核处理 播出日期: 2010 年 12 月 28 日 LANINGHAM:这里是 Andy Glover 主持的一个特殊的 developerWorks 播客系列, Andy Glover 是一名开发人员、作家、演讲家和企业家。Andy 是 Beacon50 的执 行合伙人,也是包括 developerWorks 在内的多个技术出版物的定期撰稿人。他编 写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员 框架)的创建者。在这里,他将与 Java 和相关技术社区的不同专家探讨各种主题, 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 GLOVER:Venkat Subramaniam 是全球知名的演讲人和作者,也是一名极其出色 的开发人员。谈到他协作完成的工作,他曾写过四本书,一本介绍 Groovy,一 本介绍 Scala,一本介绍 .NET,还有一本介绍敏捷开发人员的实践。 但具体来说,我先提到的三本书涉及的均为不同的语言,甚至是不同的平台: .NET、Groovy 和 Scala。那么,Venkat,您为什么对所有这些不同的语言和平台 感兴趣?

Upload: others

Post on 30-Sep-2020

9 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-1

Java 技术专区技术播客系列:第 1 季Venkat Subramaniam 谈论多语言编程、JVM 和 多核处理播出日期: 2010 年 12 月 28 日

LANINGHAM:这里是 Andy Glover 主持的一个特殊的 developerWorks 播客系列,

Andy Glover 是一名开发人员、作家、演讲家和企业家。Andy 是 Beacon50 的执

行合伙人,也是包括 developerWorks 在内的多个技术出版物的定期撰稿人。他编

写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

框架)的创建者。在这里,他将与 Java 和相关技术社区的不同专家探讨各种主题,

从闭包到开源商业智能,甚至是 .NET。有请 Andy。

GLOVER:Venkat Subramaniam 是全球知名的演讲人和作者,也是一名极其出色

的开发人员。谈到他协作完成的工作,他曾写过四本书,一本介绍 Groovy,一

本介绍 Scala,一本介绍 .NET,还有一本介绍敏捷开发人员的实践。

但具体来说,我先提到的三本书涉及的均为不同的语言,甚至是不同的平台:

.NET、Groovy 和 Scala。那么,Venkat,您为什么对所有这些不同的语言和平台

感兴趣?

Page 2: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-2

SUBRAMANIAM:语言无疑非常重要,我认为语言会对我们设计软件的能力产生极大

的影响。

这方面最有趣的是一个称为沃尔夫假说的理论,这些人认为,我们所知的语言(他

们研究的是自然语言,而非编程语言)会影响我们的想法。这有些违背直觉。很多

时候,我们认为我们是通过语言来表达想法。而这些人认为我们所了解的语言会影

响我们的想法。

当然,我并不是自然语言专家。虽然我确实懂几种不同的自然语言,但我更擅长编

程语言。

我曾经只懂一种语言,当时我也能很好地设计软件,但在接触多种不同语言之后,

我对开发和设计软件的方式产生了不同的看法。如果您希望成为更出色的软件设

计人员,我认为您绝对有必要学习多种语言。

Page 3: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-3

GLOVER:您谈到的观点非常有趣,您的《敏捷开发人员实践》一书是与 Andy

Hunt 共同创作的,对吗?

SUBRAMANIAM:是的。

GLOVER:Andy Hunt 曾经为实用主义程序员撰写过《实用主义程序员》一书。在这

本书中,他们坚信每年学习一种新语言的信念,对吗?

SUBRAMANIAM:是的。实际上,假设您了解 C++,随后又学习了 Java 或 C#,

那并不算是学习新语言。您必须学习与熟悉的语言截然不同的语言。

这样做有很大的好处。《实用主义程序员》建议,我们至少每年学习一种新语言。

我的观点略有不同,我认为我们应该随时把握学习新语言的机会。

原因在于,我几个月前曾经为客户讲过一堂课,学员的年龄各有不同,其中有两

名学员的年龄比较相近,一名学员

Page 4: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-4

发现自己很难理解各种概念,但另一位经验和年龄相差无几的学员则可以轻松接

受各种概念。

我对这种情况进行了分析,发现可以轻松接受新内容的学员有着使用多种不同语

言编程的经历。

他并不是一直在学习新语言;而是着重关注语言间的差异。他的知识比较广博,在

学习过程中,他最关注的就是比较差异,了解这种语言与他熟知的语言有哪些不同

之处,有哪些相似之处。

GLOVER:我懂了。

SUBRAMANIAM:在学习过程中遇到最大困难的是那些精通某一种语言的学员,因

为他们要学习这种新语言中的全新概念。

所以我得出这样一个结论,学习一种新语言所需的时间与学员在过去十年间掌握的

语言数量成反比。只精通和使用过一种语言的学员在学习新语言时所花费的时间最

长。

Page 5: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-5

但是,比如说,如果他们在过去十年间掌握了四五种不同的语言,那么他们很可

能只需要几周时间就能学会一种新语言。

GLOVER:谈到不同的语言,显然我们这次网络广播的主题是 Java,但我们已经在

其他网络广播中谈到了 Clojure 和 Goovy。Venkat,您会建议 Java 开发人员关

注和学习哪些语言?

SUBRAMANIAM:这是如今这个世界最美好的地方。我们不受任何约束。作为程序员,

我们拥有自由选择的权利。如果您对面向对象的编程风格感兴趣,那么您可以选

择 Java 和 Scala 等语言,Scala 拥有比 Java 本身更强的面向对象、静态类型

特点,而且支持多种用法。

但如果您对函数式编程更感兴趣,那么您可以考虑 Clojure 或 Scala。如果您对动

态语言感兴趣,您可以选择 JRuby 或 Groovy 等等。

因此,您可以任意选择自己喜爱的语言,并在 Java 虚拟机上使用这些语言。更好

的消息是,您可以交互处理并很好地使用任何 Java 库,

Page 6: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-6

这些语言都支持访问 Java 库。我们目前有着如此强大的选择权,这在四五年前是

根本无法想象的。我觉得这对我们来说是一种奢侈。

GLOVER:我很赞同。让我们回到 Scala 这个话题。Scala 会如何改变我开发

或设计应用程序的方式?Scala 有哪些优势?

SUBRAMANIAM:Scala 是一种非常有趣的语言。在新手看来,这种语言或许有几分

令人畏惧。但如果耐下性子学习这种语言本身,您就会看到这种语言真正的美好之

处。

在我看来,Scala 最令人激动的方面之一在于它是一种静态类型语言。可以说,

所有语言都应该采用静态类型。但 Java 本身并不像 Scala 那样属于静态类型。

如果一种语言更倾向于静态类型,那么您需要亲自键入的代码就会更少。另一方面,

Java 的静态类型程度较低。您必须另外指定许多类型。Scala 略为详细地解释了

类型。因此 Scala 的类型静态程度较高。

Scala 较为精确,非常具有表述力。仔细观察用 Scala 编写的部分代码,

Page 7: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-7

您会发现它们非常简洁,表述力很高。XML 是 Scala 中的“一等公民”。格式良好

的 XML 语法在 Scala 中都是有效的语法。

如果您希望使用 Web 服务器,从中获取一些 XML 数据并处理它们,那么您只需

要两三行代码。在这种语言中,可以内置一些 XPath 查询语法。这非常方便。

Scala 中的模式匹配功能也很出色。当然,Scala 支持基于 Actor 的并发模型,

因此您可以编写非常强大的、高性能的代码,不像 Java 中那么容易出错,而且

可以非常高效地处理并发性。

从多个方面讲,我认为 Scala 是一种很有趣的语言。但 Scala 带来的最值得关注

的一个方面(也是 Scala 的作者 Martin Odersky 称之为重大挑战的一个方面)

是,这种语言融合了函数式编程和面向对象式的编程。

这种特点是福亦是祸,原因在于,如果您需要纯粹的函数式编程,Scala 无法实

现它,但如果您希望过渡到函数式编程,那么在 Scala 中就可以利用面向对象的

编码、函数式编码或两者的混合体。

Page 8: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-8

这给您带来了两方面的优势,让您可以利用命令式编程的优势,也可以彻底摒弃

命令式编程,在 Scala 中执行函数式编程。在必要情况下,可在一种语言中混合

两种模式,这种做法非常有趣。

GLOVER:让我们再来谈谈不同的平台、不同的语言,您甚至提到了不同的模式。

您谈到了面向对象的编程和函数式编程。

您能否为我们介绍一下,两者之间有什么区别?我相信有一些听众更熟悉面向对

象的编程,而对函数式编程不甚了解。究竟什么是函数式编程?应该在什么时候

使用函数式编程而非面向对象编程?

SUBRAMANIAM:我认为这是一个很有趣也很重要的问题。过去 20 年间,语言一直

在竭力简化。面向对象的编程无疑非常值得关注,很有价值,但不要误解我的意

思,我并不是说世界上的所有东西都要使用对象的方式处理。

考虑面向对象的原则本身,

Page 9: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-9

它的主旨就是抽象。抽象并不是面向对象的编程中的新概念。从人类开始思考那一

天起,就有了抽象。

最重要的并不是继承。继承实际上是一个被人们滥用了的概念。排除这两个概念,

面向对象编程中最重要的因素是封装和多态性。要利用封装和多态性的优势,我

们实际上并不需要对象。

对象可以拥有封装,可以提供多态性,但过程也能达到同样的效果。您完全可以编

写封装良好的过程,也可以在这些语言中注入多态性。

分解应用程序时,不一定要将其分解为对象。当然,您可以将应用程序分解成对象,

但也可以将它分解成函数。所以说,函数式编程的核心在于将函数视为“一等公民”

,创建和来回传递函数。

如果您更习惯于面向对象的编程,那么您也可以在函数中创建对象。您可以在函数

式编程语言中,在函数内创建函数。再回到面向对象的编程,我们可以将对象传递

给函数,可以将对象

Page 10: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-10

返回给函数。在函数式编程语言中,您可以从函数返回函数,也可以将函数传递给

函数。函数是一等公民。

可以说,这提供了细粒度的重用。但除此之外,函数属于高阶函数,因此可以将函

数传递给函数。但函数式编程中的函数没有任何不良效果。

这是一个值得考量的有趣概念,在使用 Java 编程时,如果是一名有着丰富 Java

使用经历的程序员,就像您和我一样,我们都习惯了可变状态。我们会创建对象,

随后对其调用函数,再继续修改对象。

仔细想一下,改变对象并不是坏事。如果仅仅着眼于改变对象,这本身并没有什么

不好的。如果您要共享对象,共享对象也不是坏事。共享绝对是件好事。我妈妈总

是会说,分享是好事,要与他人一起分享。

GLOVER:确实如此。

SUBRAMANIAM:因此,共享是好事,可变性也是好事,没有什么不足。但共享的可

变性就是绝对的坏事。只要

Page 11: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-11

您将共享对象或数据进行共享,就会立刻产生并行性的问题。因此函数式编程崇尚

不可变性。只要完成创建,就不能再做修改。

这将不可变性提到了更高的水准。假设您有一个函数,并向该函数传递了一个参

数,该函数不会修改所接受的参数。函数不会修改其作用域以外的任何对象,只

会创建新数据或新对象,然后将其返回给您。

换句话说,您可以将函数视为一个圆筒,您向它传递一些数据。只要保持传递相同

的数据,此函数的输出就总是会保持完全相同,无论调用多少次都是如此,因为此

函数没有任何副作用。由于函数没有副作用,所以它不会影响外部的任何事物,也

不会受任何外部事物影响。

您可能会疑惑,没有副作用的函数,这有什么意义?其中的一项意思在于,更易于

从数学上证明这些函数的正确性和行为。大多数听众对这个方面应该都不是很关注,

因此我们这里不再赘述。我们来谈谈表达式。

Page 12: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-12

您知道,函数毕竟是由表达式组成的。观察一个表达式……我回想起一件事,在

我曾经工作过的一家公司中,我们开展科学计算工作,我们将应用程序从……我

记得是 UNIX 平台,迁移到 Windows 平台。

当时我手下的一名程序员连续工作了好几天。我无法准确说出究竟是几天,因为

我们当时甚至无法靠近他。他身上散发出难闻的气味。他连续好几天都没有回家。

他真的用了好几天的时间去试着了解这个程序的响应在两种平台上为何不同。

最终他发现,是其中的一个表达式对某个变量采用了算后增量运算,导致变量递增

两次。在发现这个问题后,他无比兴奋。他拿出了 Bjorn Stoustroup 的书,说,

你们看,他在这一页上明确提醒过我们不要这么做,不知道是哪个家伙恰好用这种

方式写了代码。

这不仅体现了当年 C++ 造成的兼容性问题。而且体现了更深层次的问题。问题

在于,这是一个有副作用的表达式的例子。它发生了泄漏。

Page 13: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-13

如果有这样一个表达式,一切就会变得非常难以预测。但如果您使用无副作用的函

数或表达式(假设您有这样一个表达式),如果不会产生任何副作用,我可以中断

程序,运行第一个,第二个表达式,或者反过来,先运行第二个表达式,

再运行第一个表达式,甚至可以并行运行两个表达式。

这就是我们所说的引用透明性。函数式编程的特点使得函数更为高阶,函数没有副

作用,而且奉行不可变性,因此非常适合并行处理。

函数式编程发展至今已有四五十年的历史。这样的成熟度让我们可以非常有信心地

利用函数式编程。之所以说四五十年,是因为我没有将新出现、未经过测试的技术

计算在内。函数式编程由来已久。其应用一直极为有效。但如今,我们看到了一个

利用函数式编程的更好理由。

我认为现在正是采用函数式编程的理想时机,因为它以极为高效的方式解决了问题,

我们当前面临的形势迫切需要这种解决方案。

Page 14: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-14

GLOVER:使用 Scala,在采用函数式编程时,假设您正在开发一个函数,您之前曾

提到过,函数式编程不允许可变性,Scala 是否会保证这一点?能否在 Scala 中

编写本质上并非函数的函数程序?或者说,Scala 是否有足够强大的力量,保证您

在编写函数时不会产生问题,比如说 Java 中常见的那些混乱问题。

SUBRAMANIAM:这是一个好问题。Scala 无法保证这一点。如果有人决定捣乱,那

我们也没办法,我们毕竟生活在一个自由的国度。我们不能阻止别人这样做。非

常遗憾,Scala 无法提供这样的保证。

顺便提一句,这是由设计决定的。Scala 的意图在于融合,融合函数式和面向对象

式编程。它是命令式编程与函数式编程之间的桥梁。

在 Scala 中,您可以编写纯粹的命令式代码,就像在 Java 中那样;您也可以

编写纯粹的函数式代码,就像在 Erlang 中那样,也可以混合使用两种编程样式。

但还有一个好消息。在 Scala 中,如果您希望实现可变性,可以使用 var 类型。

如果您

Page 15: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-15

希望实现不可变性,那么您可以使用 val 类型。如果代码中使用了 var,那

么您可以轻松纠正问题。

如果能确保视为 var 的内容完全实现封装,不会在多个不同 actor 之间公开,

那么就可以轻松验证这一点。

总体而言,在编写 Scala 代码时,我使用 val 的频率要高于 var。在我确实想要

使用 var 时,我会反复考量,确保实现彻底封装,从不会公开,完全不会涉及到

多个 actor 或线程。因此我认为,尽管 Scala 语言本身无法保证这一点,但您可

以通过多种方式加以合理验证。

GLOVER:您写过一本关于 Scala 的书。还有一本关于 Groovy 的书。我猜测您可

以很好地阐明这两者之间的差异。我们之前曾提到过,如果您需要一种更具函数风

格,更严格或静态类型的语言,那么 Scala 或许是理想的选择。那么为什么还有

人会选择 Groovy?

SUBRAMANIAM:应该说,这两种语言最根本的差异在于 Scala 是静态类型语言。

Groovy 是动态语言。但除了类型本身,

Page 16: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-16

我认为 Groovy 这种语言最明显的优势就是元编程

(metaprogramming)功能。

如果您需要执行方法综合,那么您应该使用元编程功能来编写代码,以便在运行

时综合代码。这样做有很大的好处。Rails 和 Grails 等框架倚重于元编程功能。

Rails 使用 Ruby 的元编程功能,类似地,Grails 使用了 Groovy 的元编程功能。

在我看来,这是最明显的一个优势。

Ola Bini 曾在他的语言金字塔中很好地阐述过这方面的问题。在他的金字塔中,

底层是基础架构代码。在 Scala 或 Java 这种静态类型语言中,可以非常有效地

编写基础架构代码,因为您需要良好的类型验证,需要出色的性能,需要能通过接

口强制实现某种类型的转换,或许还需要解决并发性问题等。

在此基础之上,他谈到了一个更具动态性的分层。在这一层中,您可以利用元编程

功能。可以说,元编程给您带来的最大优势就是能够减少您需要编写的代码量。

Andy,最直观的体验就是代码数量的减少,您可以在代码中编写非常灵活的

Page 17: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-17

内容。在 Java 这样的语言中,您可能要编写数千行代码,而在 Groovy 这种语

言中,由于可以利用方法综合,因此可能只需要数百行甚至更少的代码就可以达

到相同的目的。

在此基础之上,金字塔的塔尖是更为特定于领域的语言层,即 DSL 层。您确实可

以在 Scala 这样的语言中编写 DSL,但很多时候,通过观察 DSL,我更感兴趣的

是其更为动态的行为,而非预先确定的一组关键字。

如果我希望执行命令驱动型操作,或者例如命令模式,语言如何根据特定情况、条

件或应用程序的状态实现学习和进化?如果您希望实现这种动态性,那么在静态类

型语言中很难实现这种动态性,除非使用 AspectJ 等外部工具,而这些工具非常

笨重,使用起来也很繁琐。

像 Groovy 这样的语言内置了这种能力。在 Groovy 内实现这种动态性则轻而易举。

典型企业应用无疑需要混合使用这些语言。如果我们需要处理繁重任务,非常繁重

的 XML 处理,模式匹配、并发解决方案、函数式编程,那么我就会

Page 18: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-18

选择使用 Scala 这样的语言。

另一方面,如果我希望编写 DSL,希望编写应用程序中的 Web 层,那么我会选择使

用 Groovy 这样的语言,它提供了更高的灵活性,以及元编程功能。

因此这些语言没有互斥的关系。我想,我们可以根据需要自行选择。我经常将这些

语言比喻成交通工具。我可以骑自行车去公园,驾驶汽车在城市中穿梭,在需要长

途旅行时乘坐飞机。在任何一天,我都可能要混合使用几种不同的交通工具。

语言是一种在应用程序 - 开发环境中导航的交通工具,我认为,我们惟一的明智

方法就是设法获得这样一种能力:根据要处理的问题,合理选择能够以最佳方式

解决问题的语言。

GLOVER:我百分之百同意您的观点。我喜欢你这个旅行的比喻。这种模式最大的

优势在于,JVM 本身支持所有这些不同的模式:就像您之前提到的那些,

Groovy、JRuby、Scala 等等。

我认为另外一个同样值得关注的问题的是:这从本质上来说并不是全新的模式,

就此,我希望听听您的意见。这种模式出现已有数年。它

Page 19: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-19

现在对 JVM 本身产生了怎样的影响?我们都在等待 Java 7 的推出。根据 JRuby、

Groovy、Scala 的当前趋势,是否存在某些影响反应到了核心 JVM 本身。

SUBRAMANIAM:这真是一个不错的问题。尽管我们有这些多种多样的语言,但任何程

序员在最初都无法明确划分 Java 语言和 Java 平台。众所周知,这两者最初几乎

是捆绑在一起的。

GLOVER:是的。

SUBRAMANIAM:但随着时间的推移,我们开始认识到,最强大的方面在于 Java 虚

拟机。它提供了一种无比强大的平台。该平台的垃圾回收功能,以及 Java 虚拟

机的性能和稳定性都非常出色。在过去 15 年间,Java 虚拟机越来越强大。

同样在过去 15 年间,Java 库也在变得越来越强大。另一方面,从某种程度讲,

Java 语言成为了三者之中最薄弱的环节。因此正确的陈述应该是:Java 比 C++ 更

简单,但随着时间推移,Java 本身正在变得越来越复杂。试想一下

Page 20: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-20

Java 语言中添加的各种功能,它们导致 Java 语言日渐复杂,而且无法达到

预期的效率水平。

但我们掌握着强大的力量。我们完全不必去抱怨 Java 语言的问题,而是可以着

眼于 Java 平台,从 Java 平台的各种语言中任意选择。如果您更喜爱静态类型

和极具表述性的语言,那么您可以使用 Scala 这样的语言编程,同时也可以在

Java 虚拟机上进行编程,充分利用现有库,因为您可以很好地与这些库交互。

另一方面,如果您希望更多地利用动态语言功能,那么您可以使用 JRuby 或

Groovy 这样的语言,这些语言赋予了我们强大的力量。那么随即出现的问题就是:

好吧,这很好,我已经决定要使用 Groovy 或 JRuby 这样的语言编程,是否有某

些应该注意的陷阱?

这里的问题在于,观察您编写的 Java 或 Scala 代码,在您按下编译按钮那一刻

起,它就要使用 javac 或 scalac 将 Java 或 Scala 代码编译为字节码,在检查

字节码时,您只要执行 javap -c,观察任何此类语言生成的字节码,您会注意到

字节码中包含 invokevirtual

Page 21: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-21

和 invokespecial、invokeinterface 之类的内容。

字节码级别支持这四种调用方法。结果表明,字节码级别的调用方法从本质上讲

是静态类型的。换言之,在将字节码编译为更低级的代码时,Java 虚拟机和 JIT

编译器明确要求您指定对象类型。

在 JRuby 或 Groovy 这样的语言中,您可以推迟类型声明,甚至不必去关注类型

究竟是什么,无疑,这些语言有一些不足之处。问题在于,Java 代码中的优化分

为两个级别。第一级别的优化是 Java 编译器本身或任何编译器实现的优化。

但第二级别的优化则是由 JIT 编译器(即时编译器)实现的优化。但由于即时编

译器并不处理直接调用,而是要处理大量调用,因此动态语言代码能实现的优化比

静态类型代码要少得多。

因此可以说,就目前而言,与静态语言相比,动态语言从最初起就处于明显的

Page 22: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-22

劣势。这就是 Java 7 希望改变的情况——致力为动态语言和静态语言打造

一个公平平等的环境。

GLOVER:这就是 invokedynamic……

SUBRAMANIAM:没错。字节码级引进的第四个关键词是 invokedynamic。这样

您就有了 invokevirtual、invokespecial 等,现在还增加了

invokedynamic。

invokedynamic 的用途就是表示:嘿,我们继续在编译时接受调用吧。不必对它执

行完整类型校验,直接原样接受就可以,该对象的类型将在稍后解析,随后在执行

时,让我们执行方法分派,在运行时验证类型信息,再恰当地分派调用。

这让代码实现真正的动态化,而且也为 JIT 编译器级别的优化铺平了道路。现在,

这些动态语言不必再经过复杂的字节码中间层。它们可以直接调用

invokedynamic,然后享受 JIT 编译器在幕后提供的优化。

>> 本 developerWorks 访谈将在第 2 部分继续。

Page 23: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-23

[第 1 部分结束]

LANINGHAM:这是 Andy Glover 采访 Venkat Subramaniam 的第 2 部分的内容。

GLOVER:每次将动态和静态语言这两种类型放在一起时,都会有一方表示,动态

类型是正确的选择;另一方表示,静态类型是正确的选择,因为动态类型过于危

险。

您对两种类型有何看法?如今的形势是怎样的?此外,就像我之前提到的那样,过

去五年、六年或者七年间,一直存在一个争议。我们是否仍然需要解答这个问题?

这个争议如今是否仍然存在?是否仍然有针锋相对的两方?

SUBRAMANIAM:当然。我想这种争议目前仍然存在。

您提出的这个问题让我想起那个故事,我想一下,名字是……格列佛游记。您或

许还记得,小人国里那些小个子一直在相互争斗,他们争斗的原因就是鸡蛋应该

从大头敲破,还是从小头敲破。我们的争论就像是这个故事的程序员版本:是该

使用静态语言,还是动态语言。

Page 24: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-24

有那么一段时间,我只用静态语言编程,我坚持认为动态语言是不好的,使用

动态语言编程是有害的。多年后,我的想法彻底发生了改变。

我后来认识到,当初自己痛恨(甚至可以说害怕)使用动态语言编程,原因在于当

时的动态语言还不具备如今的某些特征。

回顾一下,大概 10 年前或者更早的时候,那时互联网还没有普及。部分动态语

言非常封闭。普通大众或普通程序员受众无法访问和使用这些语言。

但现在,随着互联网和开源社区的兴起,任何人都可以 a) 下载、体验和试用市

面上几乎任何语言;不仅如此,还能 b)开始参与这些语言的开发和扩展工作,

为之做出贡献。

我认为这一点是最吸引人的。如果您十年前向我提出这个问题,我可能还不会这么

说。但如今,我们

Page 25: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-25

所在的世界已经有了翻天覆地的变化,任何程序员,无论他们身在何处,无论他

们的能力如何,只要他们有意愿和能力,就可以参与这些语言的扩展和发展。

在过去 10 年或者 15 年间,发生的第二件大事就是计算机能力的显著提升。我

们不断获得更出色、更高速的硬件,机器速度极大地补偿了之前我们担心动态语

言速度过慢的问题。

第三件事,在我看来或许也是最重要的就是对于测试驱动型开发和单元测试代码

需求的更好的意识,或许不能称之为更好的认可,而是应该称之为更好的意识。

我要强调的最后一点是:使用动态语言编程时,最重要的是设定更出色的准则,

以便指导单元测试的编写,确保代码不会偏离原意,准确执行您希望的操作,我

并不是说这在静态语言、静态类型的语言中不重要,但它在动态类型的语言中确

实更重要。

我认为这一点尤为重要。更好的意识是一方面,我认为认真使用并

Page 26: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-26

成功受益于动态语言的人是那些采用了测试驱动方法的人。

因此可以回答您之前提出的问题,如果我要成为“牛仔式”程序员,不遵循任何准

则,只是闷头写代码,那么我的第一个答案就是应该停止编写代码,但第二个答案

是,如果您无法停止编写代码,那么静态语言或许更适合您。

但如果您是饱含热情、认真负责、富有工匠精神的人员,而且秉承某种准则编写

经过单元测试的代码,那么我认为您无论是使用静态类型的语言,还是使用动态

类型的语言,取得成功的机会都会更大一些。

然后就出现了这样一个问题,为什么应该使用动态类型语言?编译器无疑非常有用。

我不想否认编译器的价值。它非常有用。但我认为认为大家过度强调了编译器的好

处。

尽管编译器非常有用,如果我手头的具体问题需要元编程功能,就可以从静态语

言中获益。利用合理的单元测试工具和准则,我可以编写更少的代码,通过动态

类型语言获得比静态类型语言多得多的收益。

Page 27: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-27

经过一段时间后,我认识到这并不是一个二选一问题。我想在有些时候,我确实

希望使用静态类型语言,而有些时候则希望使用动态类型语言,我不必坚持使用

任何一种类型,而是可以根据需要,在同一个项目中明智地选择结合使用两种类

型。目前,我真的不认为应该只使用静态语言,或者只使用动态语言。

GLOVER:我懂了。是的。实际上,我曾经有幸听到您或者其他人在某次演讲或会议

上谈到过编译器和动态语言,也曾提到过这样的观点,可能是 Stu Halloway?总

之您或者他曾经说过,在动态语言中测试的内容最终会变成某种编译器,支持执行

检查。

SUBRAMANIAM:正是如此。实际上,Stu 曾提到过,在大约五年后,我们就会将编

译器视为单元测试中最薄弱的环节。从那时到现在,已经将近五年,所以我们应

该来看看现在的情况究竟怎样。

GLOVER:当然。您之前提到,这并不是二选一的问题,而是时机问题,也就

是说,应该在什么时候使用这种,

Page 28: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-28

又该在什么时候使用那种,两种都有对应的用例。我们回到这次谈话开始时的话

题,就是多语言编程,我们已经谈了 Scala,Jruby,还有 Groovy。

我们之前讨论了这三种产品。显然它们都与 Java 有关。有关 Scala、Groovy 和

JRuby 的讨论至少已经延续了五年多。

目前市场上还有哪些选择?是否有其他值得考虑的语言?是否有其他已经引起人

们注意的语言,或许与 Groovy 或者 Scala 类似有着这样那样的不足之处?考虑

到 JMV 现在已经开始调整自身,对这些替代语言表现出更友好的态度,您认为未

来的趋势如何?您的看法是怎样的?

SUBRAMANIAM:在 JVM 上的 200 多种语言中,无疑有一些语言要比其他语言更难

懂。我要说,选择哪种语言实际上并不那么重要。更重要的是选择哪种范式。

就范式而言,现在的主流无疑是面向对象范例、函数式编程、动态编程功能,是

动态编程功能,而不是动态编程,当然还有我们没有提到,但

Page 29: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-29

逻辑编程同样非常重要,比如像 Prolog 这样的语言。在这方面,我没有注意到任

何明显的趋势,但我非常希望未来能看到一些新鲜动向。或许在整个体系全面稳定

后,这方面的新动向真正出现时,就意味着新一轮革新的开始。

Andy,您肯定会记得,在 80 年代末或者 90 年代初,人们曾经就面向对象编程

的正确与否的问题争论不休。现在想起当时的情况都觉得很有趣,但那时确实有

一些人坚持认为对象编程非常糟糕,根本不可能有效,只会造成极度糟糕的性能。

时至 2010 年的今天,再不会有人会产生这种疑问。我们几乎不假思索地选择面

向对象编程语言。

或许再经过五年左右,我们也会更广泛地采用函数式编程,或者混合使用函数式编

程和面向对象编程风格,随后我们可能会开始学着应用一些逻辑编程功能和范例,

并从中受益。

最吸引我的方面在于,有很多我们整个行业范围内尚未利用起来的创新,

Page 30: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-30

但实际上这些创新已经在规模较小的相关领域专业社区中得到了利用。

这是我要说的一个方面。当然,Clojure 是一种语法类似于 Lisp 的动态语言。

近年来 Clojure 赢得了广泛关注。它当然是一种值得关注的出色语言。JVM 上还

有多个版本的 Haskell。我也在关注 Erlang 的各种变体。当然,我也很关心

Erlang 何时能在 JVM 上运行。那会让我感到非常兴奋。

我使用 Erlang 已经有几年了,我认为在 JVM 上如果能有 Erlang 这样一种语言

(一种结合了纯函数式功能的动态语言),也会非常有价值。

但我所想到的不只是语言,语言给我们带来的主要是各种语法,让我更兴奋的不

仅是语言或者语法,而是其中蕴含的编程范式和风格理念。这才是引起我关注的

关键所在。目前有哪些风格理念?如何才能学习、利用它们?我的应用程序要如

何才能受益于这些理念?我现在考虑的是这些问题。

GLOVER:当然。在我们先前的对话中,在您提到风格和不同的平台与语言时,我

们只是浅谈即止,

Page 31: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-31

只谈了它们对于并行性的处理方法,对吗?在先前与 Alex Miller 对话时,Alex

也是我们的一位老朋友,他谈到了抽象并行性的不同方法,包括 actor、agent、

线程等。

我想延续这个话题,请您谈谈并行性的发展趋势。作为 Java 开发人员,我们是否

需要进一步关注并行性?它与 Groovy 和 Scala 等语言又有怎样的关系?

SUBRAMANIAM:问题就在这里。Java 的问题并不是无法创建线程。Java 的问题在

于 Java 从根本上推行的就是处理可变状态的范式。要在 Java 中推广不可变性,

我们还有很长的路要走,有很多工作要做。

如果您看过《高效 Java》这本书,书中给出的一个提示是,我们应该竭尽所能推

行不可变性。但首先,这与我们在 Java 中习惯的方式截然不同,此外,Java 语

言本身也让我们能更轻松地处理可变状态,比处理不可变性要轻松。

我收到过这样一封有趣的电子邮件。我觉得很有趣,但我不确定发邮件的那个人是

不是也这样认为。他在电子邮件里说,

Page 32: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-32

他遇到一个运行良好的应用程序,他们在多核处理器上部署了这个应用程序,然后

一切就乱套了。

他继续说道:不要告诉我方法不对,我知道正确的方法是什么,但现在无法实现。

请告诉我让这个应用程序在这种多核处理器上正常运行的最简单的方法。

我答复他说:好吧,最简单的方法就是关闭一个内核。为什么这个程序在单核平台

上一切正常,但在多核系统中就出现了问题。首先,这个程序最初在单核平台上的

运行可能也存在问题,只是看似一切正常而已。

GLOVER:没错。

SUBRAMANIAM:可想而知,这就像是在凌晨 3 点钟,在单行车道上逆向行驶,只

是因为没有发生问题,就说这种做法是正确的,这样是不对的,不是吗?

在单核处理器上,多个线程通常共享相同的缓存。有两个可能发生问题的位置。其

一是 JIT 编译器

Page 33: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-33

优化,JIT 编译器可能表示:我不需要将这个值返回到内存中,我可以直接将它保

留在缓存中。我根本不需要将它传输到内存中。

这就是可变性的问题。Brian Goetz 的《Java 并行性实践》是一本很优秀的书,

值得一读。他谈到了可变性会造成重大隐忧的情景。

除了 JIT 编译器优化之外,第二个值得注意的方面是缓存……数据在任意给定时

间都处于本地。如果多个线程在同一个处理器的同一枚内核中运行,即便应用程

序崩溃,在单核处理器上,您可能也不会直接看到问题。

但如果使用的是多核处理器,可以这样设想一下,我们有一间很大的会议室,您和

我坐在一张会议桌旁,我在查找墙壁上的某些数据,因此走到墙边,将数据抄录到

即时贴上,走回来将即时贴放到桌上,然后在桌上更改数据,但我懒得回头再去改

墙上的数据。

由于您坐在同一张桌子旁,因此您可以编辑、更改和查看桌子上的即时贴,

Page 34: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-34

我们共享相同的数据。假设在这个例子中,您和我是两个不同的线程。

如果在此同时,还有一个人在会议室里,只是坐在另一张桌子旁,他要查看相同数

据的不同副本,我们无法看到他们所做的更改,他们也无法看到我们所做的更改。

这就是多核处理器上发生的情况。使用多核处理器时,不同内核最终要使用不同

的缓存,根据线程是否处于本地,它们所使用的可能是内存中不同的缓存。因此,

如果程序编写不当,就极有可能产生问题。

正因如此,这个问题在多核处理器上表现得比在单核处理器上更明显。部署到多核

处理器后,原本以为能正常运行多年的代码突然意外崩溃,无法再正常工作。

这里的根本症结在于未获取并同步数据。这是同步的问题,对吗?

Page 35: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-35

如果您获取并同步了一个对象(我确信您之前肯定这样做过),编写代码并使用同

步功能,在开车回家的路上,您忽然意识到同步可能并未正确实现,然后整个晚上

您都心神不宁,因为您无法保证代码能正常运行,非常担心在有多个线程访问这个

对象时,对象状态会发生问题。然后,您匆忙跑回办公室,检查代码,结果发现确

实存在问题。

Java 的症结不是我们没有同步的能力。Java 的症结在于,只有在用到同步的每一

行代码中合理实现代码同步后,同步才能正常工作。只要一个地方出现问题,整个

程序就会乱成一团。但要保证程序正常工作,访问数据的每个位置都必须得到合理

保护。

经过一段时间,我认识到两件事。一是在 Java 中确保代码正确支持多线程需要

非凡的能力;像我这样的普通人很难做到。更糟糕的是,如果不慎失误,Java 根

本不会告诉您出现了错误。

他不会给 Andy 打电话,告诉 Andy 说:你的代码糟透了,存在问题。他也不会

给 Venkat 打电话说:你的代码糟透了,存在问题。它

Page 36: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-36

或许会调用其他 JVM,告诉其他 JVM 去检查 Venkat 编写的代码。我认识到,

让多线程代码在 Java 中正常工作就像跟岳母相处一样困难。几乎注定是要失

败。而我们无法承受这样的失败。

我想,现在有两种方法可以解决这个问题。一种方法是推行不可变性,也就是说:

我不会更改任何东西。您处理的所有数据都是不可变,由于不可变,因此也不需

要同步。

这解决了冲突问题,但我要如何在线程间通信?如何交换数据?为此,我们可以

使用 Erlang 和 Scala 奉行的基于 Actor 的模型。使用 Actor,然后通过来回

传递数据在 Actor 之间通信,但数据仍然保持不可变,整个过程极为安全。这是

一种方法。

另外还有一种方法,顺便说一句,在 Scala 和 Clojure 这些语言中,还有一种不

同的方法,稍后我们再说一说这种方法。假设在 Java 中同步和访问对象,然后您

忘记了执行同步,或者同步失败了。Java 不会默默地出错,而是会明确告诉您:

你忘了同步这个代码。

Page 37: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-37

我对你很不满,所以抛出了一个异常。想象一下这种情况吧。

GLOVER:这会对您很有帮助。

SUBRAMANIAM:这确实很有帮助。这实际上就是 STM,软件事务处理内存模型。软

件事务处理内存模型所做的是将您的数据访问绑定到事务边界内,就像数据库为您

提供 ACID(原子性、一致性、隔离和持久性)时一样。它为您提供了这种功能,

但您无法在内存中实现数据持久性,因此它会处理原子性、一致性和隔离。

您的访问将限制在事务边界内。如果您尝试访问并更改此事务边界以外的数据,

就会立刻得到异常。但是,如果您为此操作启动一个事务,然后完成事务,就像

是乐观锁定那样。在结束时,如果您尝试修改的数据确已修改,那么系统将会重

复您的事务。

重复您的事务,这听起来可能有点吓人;但如果您只有一个写入程序或者一个执

行频率很低的写入程序,

Page 38: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-38

同时还有大量读取程序,那么这种方法效果良好。

在存在不频繁的写入操作和极其频繁的读取操作的应用程序中,这种模型的表现

良好。因此,Clojure 中的软件事务内存是一种非常高效的模型。

不要单纯地将这些视为语言功能,我们应该将它视为一种范式。您可以通过三种

方法处理并行性。在解决并行性时,最糟糕的方法就是共享的可变性,这就是同步

模型。

更好的方法是采用基于 Actor 的模型,在线程间传输不可变数据。如果存在不频

繁的写入操作和极其频繁的读取操作,那么第三个选择就是事务软件内存。

我想在未来两三年,或者是四年中,我们还不必对软件的并行性功能过于担心,但

我们对处理并行性的范式会越来越感兴趣。随后,我们就可以开始研究库,在 JVM

上的几乎任何语言中利用这些库。

使用 Java、Groovy、JRuby、Clojure 还是其他什么语言编程并不重要,

Page 39: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-39

您可能会说,这里有三种不同的模型,我要选择最合理的一种,我希望您能

进一步了解基于 Actor 的模型,在特殊情况下,可以选择事务内存模型,因

为在读取频繁、写入较少的情况下,这种模型更为合理,至少我是这样认为

的。

GLOVER:我想我们可以总结一下并行性的顾虑:不要过度关注语言,而是应该像

您之前提到的那样,关注范式、库或者某种具体方法,然后,由于 JVM 上的一

切都是“可交互的”,如果能够找到一种使用 Java 编写的 STM 库,那么就会

一马平川,在 Groovy 中使用这个库时可以确定,您需要 Groovy 中与 STM 相

符的某些功能,或者说就是您提到的 Actor。显然,那是在 Scala 中构建的,

但也有一些适用于 Java 的 Actor 库,如果需要的话,您可以在 JRuby 中使用

它。

我想这再次凸显了 JVM 目前的优势。就像您说过的那样,10 年前,在 JVM 编写

代码时,我们最终要自行编写许多内容。我仍然记得编写自己的日志框架的经历,

我当时不禁问自己:为什么要浪费这么多时间来做这件事?我仍然记得

Page 40: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-40

当时编写自己的测试框架的经历。

现在,一切都现成可用。有许多比我聪明得多的人已经为 A、B、C 和 D 编写了各

种各样优秀的库,我可以直接利用他们的智慧结晶,通过组合这些片段迅速构造出

自己的解决方案。

我想您之前已经强调了我们现在能享受到的便捷优势,我们可以利用 JVM,我们可

以选择驾车还是乘飞机出行,在乘飞机出行时,我们还可以选择机型和座位。对于

Java 平台来说,我想这是一个非常让人振奋的时代。我相信您也是这样认为的。

SUBRAMANIAM:当然!这赋予程序员无穷力量。这赋予 Java 平台强大的优势,

支持任意选择框架和库。如今,这样的灵活性和强大力量得到了延续,您甚至可

以选择更好的编程范式。

我想这真的很让人振奋。这让我比以往任何时候都更加强大,让我振作精神、

鼓足力量去解决虚拟机上的更多难题。我想这是此平台程序员的一个美好时代。

Page 41: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-41

GLOVER:好的,Venkat,我要代表所有听众感谢您今天抽时间跟我们交流,感谢

您详细介绍了所有这些不同的思路、看法和语言。

下面我们简要总结一下。我们谈到了 Scala、Groovy、Clojure,还有 JRuby。我

们两人的朋友 Ted Neward 曾经为 developerWorks 写过大量关于 Scala 的文章。

在谈到 Groovy 时,我们的另一位老朋友 Scott Davis 也在 developerWorks 写

过一些关于 Groovy 的文章。我自己也写过一些相关文章。

谈到 Clojure,developerWorks 确实有一些关于 Clojuer 的文章,在之前的

一期网络广播中,我曾有幸与 Stu Halloway 进行交谈,他是我们两个人的另

一位老朋友。当然,我还与 Alex Miller 进行过愉快的交流,他谈到了一些

并行性模型之类的话题,此外,他也在为 developerWorks 撰稿。

您曾经写过四本书,我们之前谈到了其中的两本,《Scala 编程》给务实的程序员

提供了极有价值的参考,您还为这些注重实务的程序员写过《Groovy 编程》。

您认为开发人员还能从哪些地方获得更多

Page 42: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-42

相关信息?您有什么推荐?我们谈了很多,我相信很多开发人员都在说:这听起来

真不错,但是我应该从哪里开始?您是否有进一步的建议?

SUBRAMANIAM:读书绝对是个好主意。作为一名图书作者,我想推荐所有人都多读书。

在研究某个具体主题时,我不会选定一本书阅读下去。而是会选择六七本书,或者

阅读能够找到的更多的书。

原因很简单,因为一名作者不可能无所不知。每位作者都有不同的视角。每位作者

对同一个主题都有不同的观点。在阅读探讨我已经比较熟悉的某个主题的书籍时,

我会把握机会,从不同的角度来看待某些观点。因此,我建议大家多读书。

当然,您之前也提到过,现在也有很多有优秀的文章。在网络上搜索阅读这些文

章也是一种很好的学习方式。我的另一本书《敏捷开发人员实践》中提到了这种

观点。在那本书中,我们推荐的一种方法就是善于借助您合作团队的力量。

就此而言,这并不是什么全新的观点,

Page 43: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-43

但在很多时候,人们都会忽略这一点,在公司中,您最好的学习机会就蕴藏

在您的同事身上。

作为一名企业程序员,如果您在公司中工作,您可以选定两名、三名或者四名同事。

不要选五六十人那么多,只要少数几个人就可以。每周选择一天,比如星期三下午,

午餐时间,自带食品聚餐会,或者午餐学习讨论会。

根据我在几家公司工作的经历,最有价值的就是自带食品聚餐会和午餐学习讨论会。

您可以选择一本具体的图书。我曾经收到过来自多家公司的电子邮件,表示:我们

这周、这个月或这个季度选了您的书来学习,我们每周将学习一章的内容。

这是一个非常难得的机会。大家围坐桌边,写下一些例子,展示他们学到的知识。

这是相互学习的好机会。

另外一个怎样强调都不过分的资源就是您当地的 Java 用户群。Java 用户群是非

常有价值的资源。我会把握一切机会访问用户群。最近,我的差旅日程非常紧张,

很难找到机会访问用户群,但在之前的很多年中,用户群都给我带来了很多宝贵的

资源。

Page 44: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-44

我要再次提醒大家,如果您还没有访问过用户群,请一定抓紧机会访问它们。这是

一种投资。用户群非常有价值,因为您不用花费一分钱就可以加入,他们会给您

“免费的午餐”。还有什么比这更容易?所以我认为这是一个不能错过的机会。

读书,阅读文章是好事,但我更倾向于这样学习。Andy,我参加会议的原因之一就

是能与像您和 Stuart Halloway、Scott Davis、Neal Ford,以及我们之前提到的

许多人、一些有智慧的人进行接触。

这就是我比较自私的一个动机,也就是通过倾听这些人的谈话学习知识。即便是那

些我认为自己可能已经熟悉的领域,通过这样的沟通也能给我带来一些新灵感。我

曾与合作的团队共同尝试和测试过自己的许多想法。我会向人们提出我的点子,看

他们是否有反对或赞同意见。

社区的价值非常重要。如果您是居住在城市中的程序员,无论您身处哪个城市,

都应该知道您所在社区中最优秀的程序员是谁。一种最好的方法就是参加本地用

户群。

Page 45: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-45

此外,在地方会议上,您也有机会接触到很多优秀资源。我们这里有 No Fluff

Just Stuff 研讨会,这无疑是一个非常值得出席的会议。当然也有其他很多会议,

但您应该寻找不涉及市场营销内容,包含大量技术内容的会议,明智地利用自己的

时间。

我总是向别人提起我从社区、从他人身上学到了多少东西,但我从朋友身上学到的

东西最多。我想,不同的人有不同的学习方式。我个人的学习方式就是向他人学习。

GLOVER:Venkat,我举双手赞成。说到这里,我有一个向他人学习的成功案例,我

无比熟悉、与我密切相关的 easyb 框架,就是从您 Venkat、Jeff Brown(Groovy

平台提交者和开发人员,专注于 Grails)那里吸取的灵感。

您和 Jeff 指导并实际制作了 easyb 的非常早期的一个版本,后来我自私地将其

据为己有。那是一次我绝对不会忘记的机会,我相信有数以千计的程序员会提到类

似的经历——与像您这样的良师益友促膝相谈,不经意间学到了某些新知识,然后

将其投入实践

Page 46: 从闭包到开源商业智能,甚至是 .NET。有请 Andy。 框架)的 …...写了 Java 开发 2.0 专栏。他还是屡获殊荣的 easyb(一个行为驱动的开发人员

-46

非常感谢您给我们提出了这些宝贵的建议,还畅谈了 Scala 和 Groovy,告诉我

们可以从哪里学到更多知识。您有关并行性和函数式编程的言论让人印象深刻。

我很高兴能有次机会与您交流,Venkat,让我再次代表我个人和我们的所有听众

感谢您今天抽出时间参加这次访谈。

SUBRAMANIAM:Andy,感谢您今天邀请我与您交流。

LANINGHAM:这里是 Andy Glover 主持的 developerWorks 播客。请在

iTunes 和 ibm.com/developerworks 上关注我们。具体地讲,请在

ibm.com/developerworks/java 上随时关注 Andy 的访谈系列。感谢大家的

收听。

[访谈结束]