欢迎来到 Scala 面试问题和解答。如今,大多数金融/银行、政府、电信、社交网络等公司都在使用Scala、Play 和 Akka 框架开发他们的项目,因为这些框架同时支持 OOP 和 FP 功能,并且还提供了许多优势。
I am going to share my Interview’s Knowledge and Scala Ecosystem or Fullstack Scala (Scala/Play/Akka) Development experience with you through couple of posts. I’m going to share you 3 separate posts. Some questions are just one question and some have some sub-questions. Totally am going to discuss around 200 questions. I bet if you are familiarise with all these questions, you will definitely clear all Scala Developer interviews. However, if you want to continue as a Fullstack Scala developer, you should learn all these Fullstack Scala technologies thoroughly.
我将分三部分提供 Scala/Play/Akka 面试问答:
- Scala 面试问题及解答:
我们将在这里讨论一些基本的 Scala 面试问题,这些问题对于想要转向 Scala 开发或拥有 1 年以上 Scala 开发经验的 Java 开发人员很有用。2。Scala 中级面试题及答案:-我们将讨论一些面试问题,这些问题对于 2 年以上 Scala/Java 开发人员经验很有用。3。Scala 高级面试问题与解答:-我们将讨论一些面试问题,这些问题对于高级或有经验的 Scala/Java 开发人员很有用。4。Scala/Java 并发与并行面试题及解答:-我们将讨论 Scala/Java 并发和并行面试问题和答案,这对于高级或经验丰富的 Scala/Java 开发人员非常有用。
我们还将讨论 Scala 和 Java 构造之间的一些差异,以便用户(从 Java 迁移到 Scala)可以从这些帖子中受益。在这篇文章中,我们将讨论一些基本的 Scala 面试问题。请阅读我即将发布的文章以了解其余两个部分。
在本节中,我们将列出所有 Scala 基本面试问题,在下一节中我们将详细讨论它们。
- 什么是斯卡拉?它是一种语言还是平台?它支持OOP还是FP吗?斯卡拉之父是谁?
- Scala 是静态类型语言吗?什么是静态类型语言,什么是动态类型语言?静态类型和动态类型语言有什么区别?
- Scala 是一种纯 OOP 语言吗? Java 是一种纯 OOP 语言吗?
- Scala 支持所有函数式编程概念吗? Java 8 支持所有函数式编程概念吗?
- Scala 语言的主要优点是什么? Scala 语言有什么缺点吗?
- Scala 语言的主要缺点是什么?
- Scala 语言的主要座右铭是什么?
- 现在流行的 JVM 语言有哪些?
- 就像Java的java.lang.Object类一样,Scala中所有类的超类是什么?
- Scala 中的默认访问修饰符是什么?Scala 有“public”关键字吗?
- Scala 中的“类型推断”是什么?
- Scala 的 Int 和 Java 的 java.lang.Integer 之间的区别? Scala中Int和RichInt是什么关系?
- Scala 中什么是 Nothing? Scala 中的 Nil 是什么? Scala 中 Nothing 和 Nil 是什么关系?
- Scala 中的 Null 是什么? Scala 中什么是 null? Scala 中 Null 和 null 有什么区别?
- Scala 中的单位是什么? Java的void和Scala的Unit有什么区别?
- Scala 中 val 和 var 有什么区别?
- Scala 中的 REPL 是什么? Scala的REPL有什么用?如何从 CMD 提示符访问 Scala REPL?
- Scala 有哪些功能?
- 我们如何在功能上实现循环? OOP 和 FP 风格的循环有什么区别?
- Scala 中的“应用程序”是什么?或者什么是 Scala 应用程序? Scala 中的“应用程序”是什么? Scala的App有什么用?
- Scala 支持运算符重载吗? Java支持运算符重载吗?
- 什么是表达式?什么是声明?表达式和语句之间的区别?
- Java 的“If…Else”和 Scala 的“If…Else”有什么区别?
- Scala 是基于表达式的语言还是基于语句的语言? Java 是基于表达式的语言还是基于语句的语言?
- 告诉我一些 Java 支持但 Scala 不支持的功能,反之亦然?
- Scala 中的函数和方法有什么区别?
- Scala 源文件中可以定义多少个公共类文件?
- 与 Java 一样,Scala 语言中的默认导入是什么?
- Scala 中有多少个运算符?为什么?
- 提到一些 Java 使用但 Scala 不需要的关键字吗?为什么 Scala 不需要它们?
- Scala 中的 PreDef 是什么?
请参阅我之前的帖子以了解更多信息函数式编程(点击此链接可以打开我之前的帖子)。
在本节中,我们将从上面的列表中挑选每个问题,并通过合适的示例进行详细讨论(如果需要)。如果您想通过示例深入了解这些概念,请阅读我之前在 Scala 教程部分的帖子。
Scala 代表SCAlable LA语言。马丁·奥德斯基是斯卡拉之父。 Scala 是一种多范式编程语言,支持面向对象和函数式编程概念。它由 Martin Odersky 设计和开发。 Scala 是一种类型安全的对象函数式编程 JVM 语言。 Scala 运行在 JVM(Java 虚拟机)上。 Scala 是一种混合函数式(面向对象和函数式)编程 JVM 语言。 Scala 拥有强大的静态类型系统。在 Scala 中,所有类型都会在编译时进行检查。
是的,Scala 是一种静态类型语言。静态类型语言意味着类型检查是由编译器在编译时完成的,而不是在运行时完成的。这些语言的主要优点是: 作为开发人员,我们应该关心编写正确的代码以避免所有编译时错误。由于编译器在编译时检查许多错误,因此我们在运行时不会遇到太多问题或错误。Examples:- Java、Scala、C、C++、Haskell 等。动态类型语言意味着类型检查是在运行时完成的,而不是由编译器在编译时完成的。由于编译器不会在编译时检查任何类型检查,因此我们可以预期会出现更多运行时问题或错误。Example:- Groovy、JavaScript、Ruby、Python、Smalltalk 等。
纯粹的面向对象编程语言意味着一切都应该是对象。 Java 不是纯面向对象编程 (OOP) 语言,因为它支持以下两个非 OOP 概念:
- Java 支持原始数据类型。它们不是物体。
- Java 支持静态成员。它们与对象无关。
是的,Scala 是一种纯粹的面向对象编程语言,因为在 Scala 中,一切都是对象,一切都是值。函数是值,值是对象。 Scala 没有原始数据类型,也没有静态成员。
是的,Scala 支持所有函数式编程 (FP) 概念。 Java 8 引入了一些函数式编程结构,但它并不支持所有函数式编程概念。例如,Java 8 不支持模式匹配、函数柯里化、隐式等。
如果我们使用Scala语言来开发我们的应用程序,我们可以获得以下好处或优缺点:Scala 语言的优点:-
- 简单简洁的代码
- 非常富有表现力的代码
- 更具可读性的代码
- 100% 类型安全的语言
- 不变性和无副作用
- 更多可重用代码
- 更多模块化
- 用更少的代码做更多的事情
- 非常灵活的语法
- 支持所有 OOP 功能
- 支持所有 FP 功能。功能强大。
- 不易出错的代码
- 更好的并行和并发编程
- 高度可扩展和可维护的代码
- 高生产力
- 分布式应用程序
- 完整的 Java 互操作性
- 提供强大的 Scala DSL
- REPL 学习 Scala 基础知识
Scala 语言的缺点:-
- 可读性较差的代码
- 对于初学者来说理解代码有点困难
- 需要学习的复杂语法
- 向后兼容性较差
NOTE:-我们可以以可读性更高或可读性较差的方式编写 Scala 代码。
除了 Scala 的诸多优点之外,它还有一个主要缺点:向后兼容性问题。如果我们想升级到最新版本的 Scala,那么我们需要注意更改一些包名称、类名称、方法或函数名称等。例如,如果您使用旧的 Scala 版本并且您的项目正在使用 BeanProperty 注释。它在“scala.reflect”中可用,就像旧版本中的“scala.reflect.BeanProperty”一样。如果我们想升级到新的 Scala 版本,那么我们需要将此包从“scala.reflect”更改为“scala.beans”。
就像 Java 的座右铭“一次编写,到处运行”一样,Scala 也有“用更少的资源做更多的事情”或“用更少的代码做更多的事情”座右铭。 “用更少的资源做更多的事情”意味着我们可以用更少的代码开发更复杂的程序或逻辑。
Java、Scala、Groovy 和 Closure 是最流行的 JVM(Java 虚拟机)语言。 Scala、Groovy 和 Closure JVM 语言同时支持面向对象编程功能和函数式编程功能。 Java SE 8 支持所有面向对象的编程功能。但是,它支持的函数式编程功能非常少,例如 Lambda 表达式、函数、类型推断、高阶函数。
正如我们所知,在 Java 中,所有类(Java API 类或用户定义类)的超类是 java.lang.Object。同样,在 Scala 中,所有类或特征的超类是“Any”类。任何类都在 scala 包中定义,如“scala.Any”。
在 Scala 中,如果我们不提及方法、函数、特征、对象或类的任何访问修饰符,则默认访问修饰符是“public”。即使对于字段来说,“public”也是默认的访问修饰符。由于这个默认功能,Scala 没有“public”关键字。
Scala 编译器可以在编译时推断类型。它被称为“类型推断”。类型表示数据类型或结果类型。我们在 Scala 程序中的很多地方使用类型,例如变量类型、对象类型、方法/函数参数类型、方法/函数返回类型等。简单来说,编译器在编译时确定变量、表达式或对象等的类型称为“类型推断”。
Scala 的 Int 和 Java 的 java.lang.Integer 的相似之处:
- 两者都是班级。
- 两者都用来表示整数。
- 两者都是 32 位有符号整数。
Scala 的 Int 和 Java 的 java.lang.Integer 的区别:
- Scala 的 Int 类没有实现 Comparable 接口。
- Java 的 java.lang.Integer 类实现了 Comparable 接口。
Java 的 Integer 与 Scala 的 Int 和 RichInt 类似。 RichInt 是 scala.runtime 包中定义的最终类,如“scala.runtime.RichInt”。在Scala中,Int和RichInt之间的关系是,当我们在Scala程序中使用Int时,它会自动转换为RichInt以利用该类中可用的所有方法。我们可以说 RichInt 是 Int 的隐式类。 (我们将在下一篇文章中讨论“什么是隐式以及隐式的优点)。
在 Scala 中,没有什么是类型(最终类)。它是在 Scala 类型系统的底部定义的,这意味着它是 Scala 中任何内容的子类型。不存在 Nothing 的实例。Scala 中无任何内容的用例:-如果 Nothing 没有任何实例,那么我们什么时候在 Scala 应用程序中使用这个实例呢?
- Nil 是使用 Nothing 定义的(参见下面的示例)。
- None 是使用 Nothing 定义的。
object None extends Option[Nothing]
- 我们可以使用 Nothing 作为从不返回的方法的返回类型。
- 我们可以使用 Nothing 作为异常终止方法的返回类型。
Nil 是一个对象,用于表示一个空列表。它在“scala.collection.immutable”包中定义如下:
object Nil extends List[Nothing]
例子:-
scala> Nil
res5: scala.collection.immutable.Nil.type = List()
scala> Nil.length
res6: Int = 0
Null 是 Scala 中的一个类型(最终类)。 Null 类型在“scala”包中以“scala.Null”形式提供。它有且仅有一个为 null 的实例。在 Scala 中,“null”是 scala.Null 类型的实例。例子:-
scala> val myNullRef : Null = null
myNullRef: Null = null
我们不能将其他值分配给 Null 类型引用。它只接受“null”值。 Null 是所有引用类型的子类型。 Null 位于 Scala 类型系统的底部。由于它不是值类型的子类型,因此我们可以将“null”分配给值类型的任何变量。例子:-
scala> val myInt : Int = null
:10: error: an expression of type Null is ineligible for implicit conversion
val myInt : Int = null
^ 此处类型不匹配错误。找到:Null(null) 但必需:Int。 Null 和 Int 之间的隐式转换不适用,因为它们是不明确的。
在 Scala 中,Unit 用于表示“无值”或“无有用值”。 Unit 是“scala”包中定义的最终类,即“scala.Unit”。 Unit 类似于 Java 的 void 。但它们几乎没有什么区别。
- Java的void没有任何价值。没什么。
- Scala 的 Unit 只有一个值 ()
- () 是 Scala 中唯一的 Unit 类型值。然而,Java 中没有 void 类型的值。
- Java的void是一个关键字。 Scala 的单元是最后一课。
两者都用来表示方法或函数不返回任何内容。
在Scala中,val和var都用来定义变量。然而,它们有一些显着的差异。
- var 代表变量。
- val 代表值。
- 众所周知,变量意味着可变,值意味着恒定。
- var 用于定义可变变量,这意味着我们可以在创建变量后重新分配值。
- val 用于定义不可变变量,这意味着一旦创建就无法重新分配值。
- 在简单的 Java 术语中,var 表示“变量”,val 表示“最终变量”。
REPL 代表读取-评估-打印循环。我们可以将其发音为“波纹”。在 Scala 中,REPL 充当解释器,从命令提示符执行 Scala 代码。这就是为什么 REPL 也被称为 Scala CLI(命令行界面)或 Scala 命令行 shell。 REPL 的主要目的是为了实践目的开发和测试 Scala 代码的小片段。对于Scala初学者练习基本程序非常有用。我们可以使用“scala”命令访问 REPL。当我们在 CMD 提示符下输入“scala”命令时,我们将获得 REPL shell,我们可以在其中输入并执行 scala 代码。
D:\> scala
scala>
Scala 语言支持以下功能:
- 支持 OOP 风格(命令式)和函数式编程
- 纯面向对象编程语言
- 支持所有功能特性
- REPL(读取-评估-打印循环)解释器
- 强类型系统
- 静态类型语言
- 类型推断
- 支持模式匹配
- 支持闭包
- 支持持久数据结构
- 使用Actor模型开发并发应用程序
- 可与 Java 互操作
- 可用的所有开发工具 - IDE、构建工具、Web 框架、TDD 和 BDD 框架
我们知道如何以面向对象的方式实现循环:使用可变临时变量、更新变量值并使用循环构造。这是非常乏味且不安全的方法。它不是线程安全的。面向对象风格使用以下构造来实现循环:
我们可以以函数方式不同地实现相同的循环。它是线程安全的。我们可以使用以下两种技术以函数式方式实现循环:
斯卡拉应用:在 Scala 中,App 是 scala 包中定义的特征,如“scala.App”。它定义了主要方法。如果一个对象或类扩展了这个特性,那么它们将自动成为 Scala 可执行程序,因为它们将从应用程序继承 main 方法。使用App的主要优点是我们不需要编写main方法。使用 App 的主要缺点是我们应该使用相同的名称“args”来引用命令行参数,因为 scala.App 的 main() 方法使用这个名称。例子:- 没有 Scala 应用程序:
object MyApp {
def main( args: Array[String]){
println("Hello World!")
}
}
使用 Scala 应用程序:
object MyApp extends App{
println("Hello World!")
}
如果我们观察上面的两个例子,在第二个例子中我们没有定义 main 方法,因为我们继承自 Scala App(Application)。在 Scala 2.9 之前,我们有 scala.Application 特征。但自 Scala 2.9 版本起,它已被 scala.App 弃用。
Java 不支持运算符重载。 Scala 支持运算符重载。原因是Java不希望支持一些误导性的方法名称,例如“+*/”。 Scala 为开发人员提供了这种灵活性,让他们可以决定应使用哪些方法/函数名称。当我们调用 2 + 3 时,意味着“+”不是一个运算符,它是 Int 类中可用的方法(或者它是隐式类型)。在内部,这个调用被转换为“2.+(3)”.
表达:表达式是一个值,这意味着它将计算出一个值。当表达式返回一个值时,我们可以将其分配给一个变量。示例:Scala 的 If 条件、Java 的三元运算符。陈述:语句定义一个或多个动作或操作。这意味着 Statement 执行操作。由于它不返回值,因此我们无法将其分配给变量。示例:- Java 的 If 条件。
Java 的“If...Else”:在Java中,“If…Else”是一个语句,而不是一个表达式。它不返回值,也不能将其分配给变量。例子:-
int year;
if( count == 0)
year = 2014;
else
year = 2015;
Scala 的“如果……否则”:在 Scala 中,“If...Else”是一个表达式。它评估一个值,即返回一个值。我们可以将它分配给一个变量。
val year = if( count == 0) 2014 else 2015
**注意:-**Scala 的“If…Else”的工作方式类似于 Java 的三元运算符。我们可以像Java的“If...Else”语句一样使用Scala的“If...Else”语句,如下所示:
val year = 0
if( count == 0)
year = 2014
else
year = 2015
在 Scala 中,一切都是值。所有表达式或语句的计算结果都是一个值。我们可以将表达式、函数、闭包、对象等分配给变量。所以Scala是一种面向表达式的语言。在 Java 中,语句不是表达式或值。我们不能将它们分配给变量。所以Java不是一种面向表达式的语言。它是一种基于语句的语言。
- Java不支持运算符重载,但Scala支持。
- Java支持++ and --运算符,但 Scala 不支持它们。
- Java 有受检异常和非受检异常,但 Scala 没有受检异常。
- Scala 不支持 break 和 continue 语句,但 Java 使用它们。
- Scala 没有显式类型转换,但 Java 支持此功能。
- Scala 支持模式匹配,但 Java 不支持。
- Java 使用原始数据类型,但 Scala 没有。
- Java支持静态成员,但Scala没有静态成员概念。
- Scala 支持隐式和特征,Java 不支持它们。
**注意:-**此列表超出一页。然而,在面对 Scala 面试时,需要记住一些关于 Scala 和 Java 功能差异的重要要点。
Scala 支持函数和方法。我们使用相同的语法来定义函数和方法,没有语法差异。然而,它们有一个细微的差别:
- 我们可以在 Scala 类或特征中定义方法。方法与一个对象(类的实例)相关联。我们可以使用类的实例来调用方法。我们不能在不使用对象的情况下直接使用 Scala 方法。
- 功能与类别或特征无关。它在 Scala 包中定义。我们可以不使用对象来访问函数,就像 Java 的静态方法一样。
NOTE:-我们将在接下来的帖子中讨论类、特征、包、对象等。
在Java中,我们最多可以在源文件中定义一个公共类/接口。与 Java 不同,Scala 支持同一源文件中的多个公共类。我们可以在 Scala 源文件中定义任意数量的公共类/接口/特征。
我们知道,java.lang是JVM自动导入所有Java程序的默认包。我们不需要显式导入这个包。同样,以下是所有 Scala 程序中可用的默认导入:
- java.lang包
- 斯卡拉包
- scala.PreDef
与 Java 和 C++ 不同,Scala 支持运算符重载。 Scala 有一个且唯一的运算符,即“=”(等于)运算符。除此之外,一切都只是方法。例如2 + 3,这里的“+”不是Scala中的运算符。 “+”是 Int 类中可用的方法。 Scala 编译器观察到 2 和 3 是整数,并尝试在 Int 类中找到“+”方法。因此,Scala 编译器将“2 + 3”表达式转换为“2.+(3)”,并调用整数对象“2”上的“+”方法,并将整数对象“3”作为参数传递给“+”方法。 “2 + 3”和“2.+(3)”相等。它只是 Scala 的语法糖,用于以函数式风格编写程序。
Java 广泛使用以下关键字:
- “public”关键字 - 定义类、接口、变量等。
- ‘static’关键字 - 定义静态成员。
Scala 不需要这两个关键字。 Scala 没有“public”和“static”关键字。
- 在 Scala 中,类、特征、方法/函数、字段等的默认访问修饰符是“public”。这就是为什么不需要“public”关键字。
- 为了支持 OOP 原则,Scala 团队避免使用“static”关键字。这就是为什么 Scala 是一种纯 OOP 语言。在并发应用程序中处理静态成员是非常困难的。
h3>Scala 中的 PreDef 是什么? Scala 中 PreDef 的主要用途是什么?在Scala中,PreDef是一个在scala包中定义为“scala.PreDef”的对象。它是一个实用对象。它定义了许多实用方法,如下所示:
- 控制台 IO(打印、println 等)
- 集合实用方法
- 字符串实用方法
- 隐式转换方法
- 断言实用方法等
例如,PreDef 对象中定义了 print、println、readLine、readInt、require 等方法。在 Scala 中,PreDef 可以使用其方法,而无需导入到所有 Scala 程序中,因为 Scala 编译器会自动将该对象导入到所有编译单元中,如类、对象、特征等。这就是“Scala 基本面试问题和答案”的全部内容。我们将在接下来的帖子中讨论一些中级、高级和实时 Scala 面试问题和答案。如果您喜欢我的帖子或有任何问题/建议,请给我留言。