Java之父接受Evrone专访:您需要的软件可靠性越高,静态类型语言的帮助就越大...

每一次重大更改都会在开发人员社区中引发痛苦。如果您的开发人员不多,那么破坏性更改不是大问题。而且您还必须考虑成本效益的权衡。如果你做一个突破性的改变,它会增加一些痛苦,但也会带来一些好处。

James Gosling:“您需要的软件可靠性越高,静态类型语言的帮助就越大。”

介绍

0689b5136aabd6ffc6547acf24d74257.png

Java之父James Gosling

James Gosling,通常被称为“Dr. Java”,是加拿大计算机科学家,最著名的是 Java 编程语言之父。他做了Java的原始设计,并实现了它的原始编译器和虚拟机。

近日软件开发商evrone的技术布道师 Grigory Petrov 有机会采访了 James,聊了不少关于他自己的人生、编程语言特别是Java的事情,我整理了一下分享出来,希望能从大佬的话语中获取一些有价值的东西。

采访

Grigory:作为软件开发人员和软件顾问,我们试图在俄罗斯组织一个社区:Python、Ruby、Java 和 Go 社区。我们希望通过采访突出我们行业的基本问题来帮助我们的开发人员。我认为你的经验和你在 Java 方面的工作可以帮助开发人员变得更好。所以让我们努力帮助他们吧!

一些语言,比如 Go,省略了类和继承,而另一些语言则在 Rust 中尝试使用特性等特性。作为语言设计师,您认为编程语言进行组合的现代、通用、合理的方式是什么?

James:我不认为我不会上课。我实际上发现类对于组合非常有效。对于如何做不同的事情,我真的没有任何好的、清晰的想法。我会以不同方式做的一些事情有点奇怪。在 C 中有宏,这几乎是一场灾难,因为宏不是语言的一部分;他们有点不在乎。Rust 的人试图在语言中很好地拟合宏。

其他语言,如所有 Lisp 家族,设法更优雅地适应它们,但它们有一种定义语法的方法,其中语法几乎完全没有语义。在大多数语言中,语法和语义是齐头并进的。作为前世写过很多 Lisp 的人,我真的沉迷于使用 Lisp 程序来操作 Lisp 程序的技术。这是我非常非常想念的一件事。某些语言允许您以不同的方式执行此操作,因此就像在 Groovy 中一样,您可以直接使用 AST。Rust 有某种语法集成的宏。但我总觉得里面有一个有趣的研究问题:你能做更多吗?

我能体会到 Lisp 对代码片段进行计算以生成新代码的感觉吗?在 Java 世界中,人们会这样做。这是比较流行的功能之一,只是它的级别非常低。因为人们结合使用注释和您可以使用某些不同语言生成字节码的事实。那是超级强大。它被用在你意想不到的地方,比如在杰克逊。它通过计算序列化器获得了很多性能。

一方面,这是一种非常强大的技术。另一方面,它非常难以使用。事实证明这是可能的。但你能走多远?它们可能是有限的。所以,如果你看看像 Lombok 这样的东西,我发现它是其中之一......好吧,我对它有强烈的爱恨情仇。因为它添加了一堆非常好的 Java 特性,但另一方面,它也显示出弱点。部分在这个过程中,因为这是一组应该只是内置的功能。Java 社区的驱动力已经变弱了并没有推动这些特性的发展。我本人已经不再社区内很长时间了,但是这些你想干的事情仅仅停留在路线图上(but there are things you could do that are just all over the map 不太好翻译)。 

Grigory:这就是为什么我们准备了有关您创建语言的奇妙体验的问题,而不是一些现代 Java 增强提案。五年前,我可以承认,我操纵了一些 Java 字节码。当然,这是好的,但是从中创建特定于领域的语言有点棘手。有了 Ruby,事情就简单多了。我们 Evrone 精通 Ruby,我们有数十名 Ruby 开发人员。Ruby 开发人员很棒,但是他们需要经过多年的培训才能学习所有 DSL 魔法。

James:具有计算代码片段等功能的事情之一,它在 Java 中很尴尬的原因之一是 Java 试图一路编译机器代码。Ruby 几乎总是被解释的。当你这样做时,当你不试图获得所有你能获得的表现时,生活就很容易了。但是,如果您想同时获得强大的功能和终极性能,生活就会变得更加艰难。

Grigory:最近,我们采访了 Ruby 的作者 Yukihiro Matsumoto,他提到他对他最新的 Ruby 3.0 主要版本进行了实验。他试图在不破坏更改的情况下发布这个版本,看看会发生什么。不会破坏任何内容的主要语言版本。我知道 Java 对不破坏事物持谨慎态度。所有语言都在没有不兼容的情况下发展是一个好主意吗?或者它是一种只能用于特定语言(如 Ruby 或 Java)的有限方法?

James:这几乎完全取决于开发者社区的规模。每一次重大更改都会在开发人员社区中引发痛苦。如果您的开发人员不多,那么破坏性更改不是大问题。而且您还必须考虑成本效益的权衡。如果你做一个突破性的改变,它会增加一些痛苦,但也会带来一些好处。例如,如果您将下标运算符从方括号更改为圆括号,它可能不会给您带来任何好处,并且会引起极大的痛苦。那将是一个愚蠢的想法。

在 JDK 9 中,发生了变化,这是引入的极少数破坏性更改之一,它破坏的是:如果您正在使用一些所谓的隐藏 API,封装机制会被打乱,而那些破坏的人封装边界和使用不应该使用的东西以不应该使用的方式使用,他们在从 8 到 9 的过程中遇到了一些痛苦。但是一旦我们超越了这个界限,它就会让平台有更多的创新自由。而在这种从 8 到 9 过渡的特殊情况下,这意味着平台可以切片和切块,您实际上可以进行自定义包装,这样 Java 运行时环境就会更小。

另一个总让人感到不舒服的地方是:当某事存在错误,并且人们为该错误制定了解决方法时,如果您修复了错误,则可能会破坏解决方法。在 Java 世界中肯定有过这样的例子,我们决定要么不修复错误,要么引入一种做正确事情的方法。这甚至出现在硬件中。sin 和 cos 有问题,它们有点不正确,所以你必须有正确和不正确的指令。

Grigory:25 年前,当我开始自己的软件开发职业生涯时,我编写了大量 C 和 C++ 代码。我记得这些每月发生一次的神秘指针错误。调试这样的错误很痛苦。但是现在,作为一名软件开发人员,我看到许多工具集成到我们的工作流程中,例如静态类型检查器。现代开发人员使用 IDE,如 NetBeans、IntelliJ IDEA,甚至 Visual Studio Code。他们编写源代码,静态类型检查器解析程序,构建抽象语法树,并检查所有可能的内容。然后在文本编辑器中突出显示可能的错误。这些技巧不仅适用于静态类型语言,甚至适用于动态类型语言,如 Python、Ruby 和 TypeScript。您对我们今天使用的这些静态类型检查器有何看法?它们是朝着编写更好的软件迈出一步,还是我们需要在语言语法中加入更多内容?

James:嗯,两个都需要。我是静态类型系统语言的忠实粉丝,因为它们为静态类型检查器和 IDE 的工作提供了一个脚手架。我一生中的大部分时间都是作为一名软件工程师度过的,对我来说,最不令人满意的消磨时间的方式就是寻找在奇怪的时间发生的晦涩的错误。我能做的任何事情都可以让错误在它们浪费我的时间之前消失,这是一件好事。所以,我非常喜欢 IDE 可以做的任何事情来降低出现错误的可能性。因此,当我们查看 JavaScript 和 Python 等动态类型语言时,它们没有足够的推理框架来解决这个问题,因为它们不一定知道任何东西的类型;他们只是在猜测。强类型语言(如 Java)为类型检查器提供了更严格的框架以供使用。和,更上一层楼,有些事情可以进行全自动定理证明。所以有像 Dafny 这样的系统,它有一个非常复杂的定理证明器。因此,如果您想构建一个加密算法,您将能够从数学上证明属性。你可以这样做。这可能有点过头了,但对于某些代码来说,它确实很有用。

而且很大程度上取决于您的目标是什么。如果你是一名大学生并且你正在努力完成你的作业,或者你是一名博士。学生,并且您正在尝试毕业,那么当您编写程序时,您的目标是它应该运行一次。至少一次。因为你必须做一个演示并能够展示它,看看它是否有效。如果您在工业环境中,我一生中的大部分时间都在那里工作,那么工作一次只会有点用处。它必须每次都有效。一次工作和每次工作之间的差异是巨大的。因此,如果它只需要工作一次,那么更动态的语言工作得相当好。如果您必须确保它会一遍又一遍地工作,那么所有静态类型工具都可以帮助您建立信心。但如果你正在做的事情是......说,你是一个物理学家,你想找出一些计算的结果,它只需要运行一次。这取决于你正在做的工作的背景。您对软件的可靠性要求越高,静态类型语言的帮助就越大。

Grigory:谈企业和产业发展。我从来没有给机器人编程过,但我花时间在为数百万人开发软件的公司工作,我可以将今天和 20-25 年前进行比较。我现在看到,像 GitHub 这样的社交编码平台得到了大公司的支持,它们帮助个人开发人员和企业或工业软件开发人员进行开源开发。那么我们可以将今天称为开源软件的黄金时代,还是不是很清楚?你怎么看待这件事?

James:我不知道。你在问一个关于未来的问题。而问题的问题,“今天是黄金时代吗?”……这个问题含蓄地说:“从这里开始走下坡路了吗?”如果这是黄金时代,那么明天就不会那么黄金了。我认为我们正在引领它,无论黄金时代是什么。我认为可能会发生很多有趣的改进。目前,我们面临着各种围绕安全以及人们如何进行网络恐怖主义的危机。当这种事情发生时正在发生,我不认为这是黄金时代。如果人们社区的合作有某种方式可以导致网络恐怖主义的终结 - 那将是非常黄金的。我们会看到。我的意思是,这是一个真是美好的时光,但可能会更好。

Grigory:您使用 JIT(即时编译)创建了 Java 和 JVM(Java 虚拟机)。JIT 提供了非常惊人的速度,同时保持语言语法愉快和高级。许多语言都跟随您的脚步,例如 C# 和 JavaScript。通过热路径编译和重新编译代码的速度接近 C 和 C++。但是许多其他语言,Python、Ruby、PHP,都有不那么流行的可选 JIT。并且许多主流语言不使用 JIT 来获得如此巨大的速度提升。为什么不是所有语言都使用 JIT 为软件开发人员提供极好的速度?

James:要真正获得您所看到的性能改进,拥有一种静态类型语言非常有帮助。对于像 Python 这样的动态类型语言,这真的非常困难。通常情况下,人们最终会在语言中添加注释,以便获得类似 TypeScript 的语言,它本质上是带有类型注释的 JavaScript。这真的很有趣,因为 JavaScript 本质上是 Java,删除了类型声明。因此,TypeScript 本质上是具有排列语法的 Java。他们有一些 Pascal 风格的声明。但是,如果您只是在 Python 中编写快速脚本,那么这个世界上的很多人都会发现声明很烦人。考虑变量的类型很烦人。

在 Python 和许多其他语言中,通常只有一种数字,那就是双精度浮点数。没有真正的整数,没有字节和 16 位整数以及类似概念上增加复杂性的东西,但它们也提高了性能。如果你有一个双精度浮点数和一个单精度浮点数,那么就会有认知负担。要做出明智的权衡,您必须了解一些数值分析。对于软件工程师来说,对数值分析几乎一无所知是很常见的。所以他们宁愿不去想它。如果您是一名使用 Python 的物理学家,您可能希望获得几乎总是可以获得的所有精度。当然,除非你需要在内存中放入一个非常大的数组,其中单精度和双精度或 8 位整数之间的区别真的很重要。如果你生活在一个这些东西都没有任何影响的空间里,那对人们来说就更容易了。

但是如果你需要关心的话……我这辈子上过太多的数值分析课程,并且被劣质数值分析烧伤了足够多的时间,我倾向于关心。这取决于您在频谱上的位置,脚本语言世界中的大多数人并不关心这类问题。他们的担忧处于非常不同的水平。很多人实际上并不关心性能和数字的细节;他们关心的是:“速度够快吗?” 性能有点像布尔值:它足够快,或者它不够快。对于某些人来说,这更像是调整赛车。如果您的汽车每小时能多跑两到三英里,那么您就更有可能赢得比赛。

Grigory:我记得几个月前,Ruby on Rails(广受欢迎的 Web 框架之一)的作者 David Heinemeier Hansson 提到,他的云预算中只有 15% 用于语言本身。剩下的就是一些缓存、消息队列、存储等。他告诉我们,无论 Ruby 有多“慢”,它都不是很重要,因为即使 Ruby 快了 100 倍并且 15% 变成了 1%,这也没有太大变化。现代语言确实“足够快”。

James:这在很大程度上取决于您的任务在程序空间中的位置。如果你想要完成的事情真的是由网络和数据库以及其他所有东西主导的,如果你一直在做 RPC,那么你应该做的第一件事可能是质疑所有这些 RPC 是否都是有价值的。当人们谈论微服务时,它们是一件好事,但只要明白它们至少比方法调用慢一百万倍。仔细想想这意味着什么。通常,对于大多数人来说,通过确保他们的大型架构是干净的,他们会获得更高的性能。但是对于很多人来说,所有细节确实很重要。如果您知道高度并发很重要,能够同时驱动数千个进程,进行主要计算。. 如果您正在做诸如数据库本身或主要存储服务之类的事情,您真的非常关心。所以这一切都取决于手头的任务。

Grigory:最近,我们看到许多语言都采用协程和 async/await 方法来处理诸如网络之类的事情,这很慢。它被添加到 Python 中,它被添加到最近的 Ruby、JavaScript、许多语言中。但是这种在一个线程中的 async/await 和协程和调度程序并不是灵丹妙药。它们带来了自己的复杂性,有时它们会使软件变慢。那么你如何看待这种现代的 async/await 炒作?它是处理网络的好方法,还是我们只是滥用它,我们需要检查 Erlang 和其他方法?

James:这是上下文决定一切的事情之一。协程非常好;它们从 60 年代就存在了。第一种带有协程的语言是 Simula 67。Simula 是一种可爱的语言。我仍然很想念它。它没有线程,它有协程,但是他们做协程的方式——它们看起来很像线程。协程有点神奇地回避了真正并行中的一些顽皮问题。对我来说,协程的问题之一,这就是我很久没有使用它们的原因,是它们实际上并没有让你这样做或让你利用多个处理器。你不能做真正的并行。

所以人们会用具有真正并行性的语言来看待事物,比如 Erlang 和 Java。你必须做的事情增加了另一个层次的复杂性。尽管通常情况下,您处理这种复杂性的方式是通过精心策划的原语。你可以用 Java 中的 ConcurrentHashMap 做的事情很神奇。但是,一旦您获得了这些基于协程的语言中的一种并尝试利用多个处理器,如果您正在执行大量协程类型的操作而您没有足够的处理器,那么您只会使一个饱和处理器。你真的很想使用多个处理器,因为世界上不再有单位处理器了,对吧?一切都有很多核心,如果你真的想一次使用你所有的电脑,在一个问题上,

然后是风格问题。想象一下这样的环境,你可以说“等待这个”和“等待那个”,他们会在你被动让步的情况下进行这种透明的控制反转。这为您提供了看起来很像真正线程的语法外观。但这意味着您可以避免真正线程中的许多棘手问题。因此,如果您说“a = a + 1”,您就知道在该操作的中间您不会被中断,因此您不必进行同步。但是在其他地方,它不是做那种风格,而是变成了一种事件导向的风格,在那里你做你的事情,然后你把一个事件处理程序插入一些东西来处理当事情完成时发生的事情。这往往是 JavaScript 中的主要风格。效果很好,

当我在 70 年代初发现 Simula 时,它有一种自然的风格。你只是编程,你可以把你的计算看作是一个独立的东西。其他事物是否与它交织对您来说是透明的。我发现它作为一个概念模型,比事件编程要简洁得多。在幕后实施更难,但通常更容易考虑。

Grigory:毕竟 Simula 是第一个面向对象的语言!我从来没有机会使用它,但我查看了文档,它看起来很有特色。然而,如果我们回顾一些像 Ruby 这样的现代语言,并发模型是复杂的:我们有进程、进程中的单独解释器、单独解释器中的线程和线程中的核心例程——就像一个俄罗斯娃娃。如果您允许,现在是一个非技术问题。当我们谈论不同的语言时,在您个人看来,现在教新软件开发人员的最佳语言是什么,作为他们的第一语言?也许在研究生院或大学。

James:我显然有偏见。Java 已经以这种方式成功使用了很长时间。但我学习的第一种编程语言是 PDP-8 汇编代码,大致与 Fortran 并行。你可以教人们任何东西。它会比其他人更容易进入他们中的一些人,但这在很大程度上取决于一个人最终的职业道路将是什么。如果您打算成为一名全面的软件开发人员,在其中构建某种大型、高性能系统,那么很难击败任何在 JVM 上运行的语言。而且我实际上并不关心您在 JVM 上使用哪种语言。我的意思是,Scala 和 Kotlin 都很好。Clojure 真的很有趣,但您必须真正以不同的方式思考。如果你是一名物理学生,Python 很好。

而且我认为您选择哪个实际上并不是什么大问题。虽然很多人只是坚持他们学到的第一件事并这样做,但如果你能让人们学习多种语言并来回......每所大学都应该为每个学生开设的一个非常好的课程是一个比较编程语言课程。在这个学期,你有 5 个不同的程序语言的 5 个作业,这让人们习惯于快速学习它们,因为它们实际上并没有什么不同,并让他们思考哪些更好。很久以前,我参加了其中一门课程,我在每项作业中都使用了绝对最差的语言。在 Cobol 中进行数值计算。那只是有趣!和 Fortran 中的符号操作......令人惊讶的是,我仍然得到了 A。

Grigory:正如预期的那样。所以,下一个问题是关于模式匹配。最近,它光荣地登陆了 Python 和 Ruby,并且有很多不同语言的提案。我们查看了开发人员白皮书,他们并不完全确定模式匹配在现代高级语言中的作用。这种模式匹配的想法,对于使用 Java、Python、Ruby 或某些高级语言的普通现代开发人员,我们真的需要模式匹配吗,还是它是针对特定用例的一些小众语法?

James:首先,我认为编程语言中的术语“模式匹配”有些误导。因为当我听到“模式匹配”这个词时,首先想到的是正则表达式,无论是字符串上的正则表达式还是树上的正则表达式。也许模式匹配树的形状,无论如何。但是回到Simula。Simula 有一个检查语句,检查语句几乎就是这些模式匹配语句中的许多语句。即,inspect 语句是一个 case 语句,其中 case 标签是类型名称,所以你会说:

Inspect P
    When Image do Show;
    When Vector do Draw;

所以你可以把它想象成一个 case 语句,它在类型上有 case。而这些模式匹配语言提案中的大多数都属于这种类型。就我个人而言,我很想念它。我真的很喜欢那个。特别是如果发生的事情就像 C 中的隐式强制转换一样。所以如果你说“在图像 P 做 P 时检查 P”,在 case 语句的主体中,P 现在是 switch 标签的类型。这让生活变得更加轻松。在所有这些地方,在具有类似 C 语法的语言中,您总是以强制转换告终。它看起来像:“如果 a 是 x 的实例,否则如果 a 是 y 的实例,然后……” Simula 中的“检查”语句非常漂亮;我爱它。从那以后,我每天都在怀念它,许多这些模式匹配提议和语言特性看起来就是这样。如果你称它们为“类型案例”——好主意。但是如果你称它为“模式匹配”,而且它的威力比正则表达式要小,那感觉它是误导性的,或者像虚假广告。但是,作为一个功能,我认为它很棒。

Grigory:我们的最后一个问题有点强制性。俄罗斯软件开发人员为 JetBrains 和 Kotlin 的开发感到自豪。当然,我不会问一些像Java vs. Kotlin之类的琐碎事情。我会试着问一些不同的事情。Kotlin 和许多其他语言(如 Clojure 或 Scala)在您创建的现有 Java 虚拟机以及现有的库、框架和现有代码生态系统上蓬勃发展。所有这些语言都面临任何挑战吗?有什么东西可以把他们团结起来吗?对他们来说有些困难?当他们试图用一些不同的语法热交换 Java 语法时,他们面临哪些挑战?

James:有点取决于你想要做什么。Java 虚拟机的特点之一是它内置了许多安全性和可靠性的概念。它们主要与内存模型的完整性有关。指针之类的。所以你不能伪造一个指针。如果你看看像 C 这样的语言,如果你没有伪造的能力,你就不能做 C。有一些虚拟机没有严格的安全模型。在 JVM 之类的东西上,如果您尝试实现 C - 有些人已经这样做了,尽管这很奇怪 - 如果您有一个严格安全的虚拟机,那么有些地方您就不能去。但是有些人构建的虚拟机并不严格安全,没有内存分配模型。

所以这取决于你愿意去哪里。当然,在 Java 诞生之初,我的个人规则之一是:我不想调试另一个该死的内存损坏错误。我已经浪费了太多时间在需要数天时间在内存损坏错误上。这只是一个循环中的一个错误,恰好从数组末尾移出一个条目,直到数百万条指令之后您才会发现。而且我真的,真的很讨厌追逐内存损坏错误。所以这取决于你对什么感到舒服。有些人,你知道的,认为花时间这样做非常有男子气概。但是也有人喜欢使用 vi,它在 70 年代是出色的编辑器,在 80 年代是出色的编辑器……加油,伙计们!

James:内存安全模型确实是核心,它提供了一些东西,但限制了一些东西。非常感谢你,詹姆斯!很高兴与您进行这次谈话,我希望在经历了这场僵尸启示录之后,我们可以在某个线下会议上见面。谢谢你,祝你有美好的一天!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
作为一家电影网站,我们的主要目标是为用户提供一个全面、便捷、高质量的电影信息、购票、观影体验平台。以下是我们的概要设计: 1. 首页:我们的首页将展示近期上映电影、热门电影、热门演员、用户评分排行榜等内容,用户可以通过点击相应的电影海报或演员头像进入电影详情页或演员详情页。 2. 电影详情页:电影详情页将提供电影的基本信息、剧情介绍、演员、导演、制作团队等信息,用户可以在该页面购买电影票、查看相关评论、写评价、收藏电影等操作。 3. 影院选择页:用户可以在该页面选择自己所在的城市和区域,显示附近的影院和电影排片信息,用户可以查看影院详细信息、购买电影票等操作。 4. 用户个人中心:用户可以在该页面管理自己的个人资料、查看历史观影记录、收藏电影、写评价、参与电影活动等操作。 5. 电影资讯页:该页面将提供电影行业的最新资讯、影评、专访等内容,帮助用户了解电影行业的最新动态。 6. 电影活动页:我们将组织一些线上或线下的电影活动,比如电影讲座、电影同好会等,用户可以在该页面查看活动详情、报名参加等操作。 7. 搜索功能:我们将提供强大的搜索功能,用户可以根据电影名字、演员名字、电影类等关键词搜索相关电影信息。 8. 社交功能:我们将提供社交功能,用户可以关注其他用户、查看其他用户的评价、写评价、点赞等操作。 我们的电影网站将致力于提供优质的电影信息、便捷的购票、观影体验、丰富的电影活动,让用户在这里享受到最佳的电影体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值