如果您不打算使用 Spark,Scala 与 Java 的对比?

数据挖掘 爪哇 斯卡拉
2021-09-21 08:33:46

在选择如何在 Scala 和 Java 之间分配接下来几个月的学习时间时,我面临一些犹豫不决。

我想帮助客观地理解实际的权衡。

我对 Java 感兴趣的原因是,我认为我在工作中的一些生产、经常更新、预测和分析会在 Java 中运行得更快(与 R 或 Python 相比),并且通过更加精通 Java,我将使自己能够工作在有趣的副项目上,例如我想开发的非数据科学应用程序。目前我已经学习了几门 Java 课程,但我需要更多的教育和实践才能掌握它。

我开始考虑学习 Scala 的原因非常相似——我认为统计/ML 方向将有助于我作为数据科学家的工作,并且由于它基于 Java,我将在工作中获得帮助我的实践我对 Java 的兴趣在于,尽管存在一些主要差异,例如函数式与命令式以及特征与接口

似乎 Scala 的许多优势都围绕着与Spark的集成。我认为这应该是我决定的转折点,因为我的团队目前没有使用 Spark,而且我没有足够的理由要求它。但是,我想我应该在这里问一下,这样我就不会浪费太多时间 Scala 是否仍然是一个更好的选择。

出于这个问题的目的,请忽略 Python、R、Julia 等替代方案(出于其他原因,我已将这些替代方案排除在考虑范围之外,例如对于我的用例已经足够熟悉它们)。

3个回答

这对于这个 SE 来说有点偏离主题,或者可能是基于意见的,但是,我在这个领域工作,我推荐 Scala。

不,我不会将 Scala 描述为“面向统计”的 Java。如果您让 3 个人设计“Java 11”,然后一次使用他们的所有想法,我会将其描述为您得到的结果。

Java 8 仍然很棒,但 Scala 完全接受了您想要的语言中的所有好想法,例如类型安全和闭包和功能范式,以及更复杂的类型/泛型系统,以及更多的语法糖便利,例如案例类和懒惰的瓦尔斯。此外,您可以在同一个 JVM 中运行所有内容并与任何 Java 库进行互操作。

代价是复杂性:理解所有的 Scala 比所有的 Java 困难得多。Scala 的某些部分可能是一座太远的桥梁。而且,与标准 Java 工具相比,工具生态系统并不是很好。但是你可以再次使用 Maven 而不是 SBT。但是,如果您不需要 Scala 中那些复杂的部分,您基本上可以避免它们。设计 Scala 库需要很多技巧和诀窍;仅仅在 Scala 中开发普通代码是不行的。

从生产力的角度来看,一旦您习惯了 Scala,您的生产力就会更高。如果您是一位经验丰富的 Java 开发人员,我实际上认为您会喜欢 Scala。我不喜欢任何其他 JVM 语言,它们往往是一种单一问题的语言,会为了边际收益而改变很多东西。

当然,对于分析而言,Spark 的存在支持 Scala。你最终会使用它。

硬币的另一面:

我对 Scala 没有丰富的经验。我已经编写了大约 10,000 行 Scala 代码。但是,考虑到 Scala 代码通常比它粗略的 40,000 行 Java 代码要短得多。

简而言之,我根本不喜欢 Scala。我喜欢它的目标和想法,但对于生产用途,我认为这些想法的实施过于大胆,有时甚至是愚蠢的。我的信念是 Scala 代码很难以健壮和清晰的方式编写。有太多的概念经常因副作用而重叠,如果你不是专家,这会让你的生活变得非常艰难。有一种观点认为,只要不使用这些结构,就可以避免这些问题。我拒绝这种观点,因为如果您想避免有问题的事情,您必须知道您并不完全理解这些功能,这需要专业知识。我的信念是,Scala 语言的实现适合一所应该测试新概念的大学,而这正是 Scala 所发生的。有很多例子,

  • Java 泛型不完整主要是因为类型擦除,每个人都同意这一点。Scala 使用公共 API 至少以三种方式“解决”了这些问题:ManifestTypeTagClassTag在我看来,这意味着问题根本没有解决,或者如果解决了,某些解决方案就足够错误了。
  • 转换器是我认为有问题的功能的一个示例:一个简单的删除类型之间的强连接与柔软的东西,很容易被遗漏。在我开始使用第三方库之后,一些勇敢的人使用了很多第三方库,我的代码开始表现得很奇怪。我输入了一些错误,恰好被转换器覆盖并花了几个小时进行调试。
  • 带默认值的参数:可以定义带默认值的参数的方法;这很有用,主要是因为使用命名参数可以避免编写许多方法......直到您发现不能同时拥有两个方法都具有具有相同名称的默认值参数的那一刻。

现在我不想发动战争,远非如此。Scala 有很多奇妙的想法,Java 陈旧,缺乏很多东西。但对于生产,我总是选择 Java。

稍后编辑

有关 Scala 类型擦除的更多详细信息,请参阅此处的简短评论。

为了澄清我对参数值的陈述,我只是举了一个假设的例子(所以像 Array 和 List 这样的反对实现了一些可遍历的接口不算在内):

class Plot {
  def histogram(x: Array[Double], bins: Int = 30): String = "test1"
  def histogram(x: List[Double], bins: Int = 30): String = "test2"
}

上面的代码无法编译:错误:在类 Plot 中,方法 f 的多个重载替代定义了默认参数

类型擦除清单和类型标签/

后来的另一个编辑 我收到了一个编辑建议,因为我不知道如何给投稿人发消息,所以我会在这里回答。他的想法是代码不正确,应该如下所示。

def histogram(x: Array[Double], bins: Int = 30): String = {
 var r = "test1"
 return r;
}

据我所知,这和上面的一样,因为我的版本是一个快捷方式。关键是代码无法编译,因为您在两个方法中有一个具有相同名称的默认值的参数,而不是因为没有正确声明方法。显然,就像在许多其他语言中一样,可以找到其他方法来解决这个问题。

整个想法是,对我来说,Scala 看起来像是一种过于慷慨的语言,有很多方法可以做很多事情,这会产生复杂性负担。在上下文中,拥有像我提到的那样的功能,它使事情变得更加困难。显然我不拥有真相,所以我冒昧地避免语言的复杂性,集中精力解决实际问题,其他任何人都可以自由地用这种语言解决它的问题。恕我直言。

由于 Scala 可以调用 Java 库,这两种语言的优势非常相似。因此,像 Weka ( http://www.cs.waikato.ac.nz/ml/weka/ ) 这样的 Java 机器学习包理论上可以很容易地与 Scala 一起使用。

但是,每个都有一些小的优点和缺点:

  • Java 是大多数拥有 5 年以上经验的软件工程师都能理解的语言。如果您去一家大型金融机构并需要将您的应用程序交给遗留团队,他们可能会知道如何支持 Java 应用程序而不是 Scala 应用程序(至少在我工作的地方)
  • Java 是稳定的,不会经常变化,但 Scala 似乎变化很快。从长远来看,这可能会使维护变得更加困难
  • 写得不好的 Java 代码可能很冗长,但写得不好的 Scala 代码可能完全无法理解(例如: ::: 是什么意思?)。Python 的创建者优化了 Python 的可读性;有时感觉 Scala 的创造者做了相反的事情
  • 编写 Scala 代码比编​​写 Java 代码要快得多。Scala 是临时原型代码的理想选择,因为您可以比使用 Java 更快地看到您的想法变为现实
  • Spark 使用 Scala 比使用 Java 更容易。机器学习 Spark 库足够好,您可能不需要使用像 Weka 这样的不同机器学习库。我见过有人在 Spark 中甚至在小型数据集上构建 Scala 模型。您无需拥有庞大的数据集即可使用 Spark。

总结:使用 Scala。大多数数据科学工作都是原型设计,而 Scala 将帮助您更快地完成原型设计。Spark ML 可能足以满足您的需求,而对于 Spark,Scala 比 Java 要好得多。