欢迎来到Scala面试问题与答案。如今,大多数金融/银行、政府、电信、社交网络等公司都在使用Scala、Play和Akka框架开发他们的项目,因为这些框架支持面向对象编程(OOP)和函数式编程(FP)特性,并提供许多优势。
Scala面试问题
我将通过几篇文章与您分享我的面试经验和Scala生态系统或全栈Scala(Scala/Play/Akka)开发经验。我将分享3篇单独的文章。有些问题只是一个问题,而有些问题有一些子问题。我将总共讨论约200个问题。我敢打赌,如果您熟悉所有这些问题,您肯定能够顺利通过所有Scala开发人员的面试。然而,如果您想继续作为全栈Scala开发人员,您应该彻底学习所有这些全栈Scala技术。
介绍
I’m going to deliver Scala/Play/Akka Interview Questions and Answers in three parts:
- Scala 面试问题与回答:
我们将在这里讨论一些基本的 Scala 面试问题,这对于初学者或者想转向 Scala 开发的 Java 开发人员或有 1 年以上 Scala 开发经验的开发人员都很有用。
Scala 中级面试问题与回答:
我们将讨论一些面试问题,这对于有 2 年以上 Scala/Java 开发经验的开发人员很有用。
Scala 高级面试问题与回答:
我们将讨论一些面试问题,这对于资深或有经验的 Scala/Java 开发人员很有用。
Scala/Java 并发与并行面试问题与回答:
我们将讨论 Scala/Java 并发与并行面试问题与回答,这对于资深或有经验的 Scala/Java 开发人员很有用。
我们还将讨论 Scala 和 Java 结构之间的一些区别,以便用户(从 Java 转向 Scala 的用户)能够从这些帖子中获益。在本帖中,我们将讨论一些基本的 Scala 面试问题。阅读我的后续帖子以了解其余两个部分。
Scala 基础面试问题
在这一部分,我们将列出所有Scala基本面试问题,在下一部分中我们将详细讨论它们。
- Scala是什么?它是一种语言还是平台?它支持面向对象编程还是函数式编程?Scala的创始人是谁?
- Scala是静态类型语言吗?什么是静态类型语言?什么是动态类型语言?静态类型语言和动态类型语言之间的区别是什么?
- Scala是纯面向对象语言吗?Java是纯面向对象语言吗?
- 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是什么?Null和null在Scala中有什么区别?
- Scala中的Unit是什么?Java的void和Scala的Unit之间有什么区别?
- 什么是Scala中val和var的区别?
- 什么是Scala中的REPL?Scala的REPL有什么用途?如何从CMD提示符中访问Scala的REPL?
- Scala有哪些特性?
- 我们如何函数式地实现循环?面向对象编程和函数式编程风格循环有什么区别?
- 在Scala中,“Application”是什么?Scala中的“App”是什么?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教程部分的先前帖子。
什么是Scala?它是一种语言还是平台?它支持面向对象编程还是函数式编程?Scala的创始人是谁?
Scala代表着可伸缩的语言。Martin Odersky是Scala的创始人。Scala是一种多范式编程语言,支持面向对象和函数式编程概念。它由Martin Odersky设计和开发。Scala是一种类型安全的面向对象和函数式编程JVM语言。Scala运行在JVM(Java虚拟机)上。Scala是一种混合的功能(面向对象和函数式)编程JVM语言。Scala具有强大和静态类型系统。在Scala中,所有类型在编译时都会进行检查。
Scala是静态类型语言吗?静态类型语言和动态类型语言是什么?静态类型语言和动态类型语言之间有什么区别?
是的,Scala是一种静态类型语言。静态类型语言意味着类型检查由编译器在编译时完成,而不是在运行时。这类语言的主要优势是:作为开发者,我们应该关心编写正确的代码以避免所有编译时错误。由于编译器在编译时检查许多错误,我们在运行时不会遇到太多问题或错误。示例:Java、Scala、C、C++、Haskell等。动态类型语言意味着类型检查是在运行时而不是在编译时由编译器完成的。由于编译器不在编译时检查任何类型检查,我们可以预期会有更多的运行时问题或错误。示例:Groovy、JavaScript、Ruby、Python、Smalltalk等。
Scala是一种纯面向对象的语言吗?Java是一种纯面向对象的语言吗?
纯面向对象编程语言意味着一切都应该是对象。Java不是一种纯面向对象编程(OOP)语言,因为它支持以下两个非OOP概念:
- Java支持原始数据类型。它们不是对象。
- Java支持静态成员。它们与对象无关。
是的,Scala是一种纯面向对象编程语言,因为在Scala中,一切都是对象,一切都是值。函数是值,值是对象。Scala没有原始数据类型,也没有静态成员。
Scala是否支持所有函数式编程概念?Java 8是否支持所有函数式编程概念?
是的,Scala支持所有函数式编程(FP)概念。Java 8引入了一些函数式编程构造,但并不支持所有函数式编程概念。例如,Java 8不支持模式匹配、函数柯里化、隐式等。
Scala语言的主要优势是什么?Scala语言有什么缺点吗?
如果我们使用Scala语言开发应用程序,我们可以获得以下优势和缺点:Scala语言的优势:
- 简洁明了的代码
- 非常具有表现力的代码
- 更易读的代码
- 百分之百类型安全的语言
- 不可变性和无副作用
- 更可重用的代码
- 更具模块化
- 做更多的事情,代码更简洁
- 语法非常灵活
- 支持所有面向对象编程特性
- 支持所有函数式编程特性。功能非常强大
- 代码容易出错
- 更好的并行和并发编程
- 高度可扩展和可维护的代码
- 高度的生产力
- 分布式应用
- 完全支持Java互操作性
- 强大的Scala领域特定语言可用
- REPL用于学习Scala基础知识
Scala语言的缺点:-
- 可读性较差的代码
- 对于初学者来说,理解代码有点困难
- 学习的语法较为复杂
- 向后兼容性较差
注意:- 我们可以以更可读或不太可读的方式编写Scala代码。
Scala语言的主要缺点是什么?
除了 Scala 的许多好处之外,它还有一个主要的缺点:向后兼容性问题。如果我们想要升级到最新版本的 Scala,那么我们需要注意更改一些包名称、类名称、方法或函数名称等。例如,如果您正在使用旧版 Scala,并且您的项目正在使用 BeanProperty 注释。在旧版本中,它可在“scala.reflect”中找到,如“scala.reflect.BeanProperty”。如果我们想要升级到新的 Scala 版本,那么我们需要将此包从“scala.reflect”更改为“scala.beans”。
Scala 语言的主要口号是什么?
与 Java 的口号“一次编写,到处运行”不同,Scala 的口号是“用更少的代码做更多事情”或“用更少的代码做更多事情”。“用更少的代码做更多事情”意味着我们可以用更少的代码开发更复杂的程序或逻辑。
现在有哪些流行的 JVM 语言?
Java、Scala、Groovy和Closure是最受欢迎的JVM(Java虚拟机)语言。Scala、Groovy和Closure JVM语言支持面向对象编程特性和函数式编程特性。Java SE 8支持所有面向对象编程特性。然而,它支持的函数式编程特性很少,比如Lambda表达式、函数、类型推断、高阶函数。
像Java的java.lang.Object类一样,Scala中所有类的超类是什么?
我们知道在Java中,所有类(Java API类或用户定义的类)的超类是java.lang.Object。同样在Scala中,所有类或特质的超类是“Any”类。Any类定义在scala包中,如“scala.Any”。
Scala中的默认访问修饰符是什么?Scala有“public”关键字吗?
在Scala中,如果我们不对方法、函数、特质、对象或类指定任何访问修饰符,那么默认的访问修饰符是“public”。即使对于字段(Fields)而言,“public”也是默认的访问修饰符。由于这一默认特性,Scala没有“public”关键字。
在Scala中,“类型推断”是什么?
Scala编译器可以在编译时推断类型,这被称为“类型推断”。类型指的是数据类型或结果类型。在Scala程序中,我们在许多地方使用类型,如变量类型、对象类型、方法/函数参数类型、方法/函数返回类型等。简单来说,编译器在编译时确定变量、表达式或对象等的类型被称为“类型推断”。
Scala的Int和Java的java.lang.Integer之间有哪些相似之处和区别?在Scala中,Int和RichInt之间的关系是什么?
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中Nothing是什么?Scala中的Nil是什么?Nothing和Nil在Scala中的关系是什么?
在Scala中,Nothing是一个类型(最终类)。它被定义在Scala类型系统的底部,这意味着它是Scala中任何类型的子类型。Nothing没有任何实例。在Scala中使用Nothing的情况: 如果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
在 Scala 中什么是 Null?Scala 中的 null 是什么?Null 和 Scala 中的 null 有什么区别?
Null 是 Scala 中的一种类型(final class)。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是什么?Java的void和Scala的Unit有什么区别?
在Scala中,Unit用于表示“无值”或“无用的值”。 Unit是在“scala”包中定义的最终类,即“scala.Unit”。 Unit与Java的void类似,但它们有一些区别。
- Java的void没有任何值。它什么都不是。
- Scala的Unit有一个值 ()
- ()是Scala中类型为Unit的唯一值。然而,在Java中,void类型没有任何值。
- Java的void是一个关键字,而Scala的Unit是一个最终类。
两者都用于表示方法或函数不返回任何内容。
在Scala中val和var有什么区别?
在Scala中,val和var都用于定义变量。然而,它们有一些显著的区别。
- var代表变量。
- val代表值。
- 正如我们所知,变量意味着可变,而值意味着常量。
- `var` 用于定义可变变量,这意味着一旦创建,我们可以重新分配值。
- `val` 用于定义不可变变量,这意味着一旦创建,我们无法重新分配值。
- 在简单的 Java 术语中,`var` 意味着“变量”,`val` 意味着“最终变量”。
Scala 中的 REPL 是什么?Scala 的 REPL 有什么用?如何从 CMD Prompt 访问 Scala 的 REPL?
REPL 代表读取-求值-打印循环。我们可以将其发音为“ripple”。在 Scala 中,REPL 作为一个解释器,用于从命令提示符执行 Scala 代码。这就是为什么 REPL 也被称为 Scala CLI(命令行界面)或 Scala 命令行 shell。REPL 的主要目的是开发和测试用于练习的小段 Scala 代码。对于 Scala 初学者来说,这非常有用,可以练习基本的程序。我们可以使用“scala”命令访问 REPL。当我们在 CMD 提示符处键入“scala”命令时,我们将获得 REPL shell,在那里我们可以输入和执行 Scala 代码。
D:\> scala
scala>
Scala 的特性有哪些?
Scala 语言支持以下特性:
- 支持面向对象(命令式)和函数式编程风格
- 纯面向对象编程语言
- 支持所有函数特性
- REPL(读取-求值-打印 循环)解释器
- 强类型系统
- 静态类型语言
- 类型推断
- 支持模式匹配
- 支持闭包
- 支持持久化数据结构
- 使用Actor模型开发并发应用
- 与Java互操作
- 可用所有开发工具 – IDE、构建工具、Web框架、TDD和BDD框架
我们如何以函数式方式实现循环?面向对象和函数式风格的循环有什么区别?
我们知道如何以面向对象的方式实现循环:使用可变临时变量,更新变量值并使用循环结构。这是一种非常繁琐且不安全的方法。它不是线程安全的。面向对象风格使用以下结构来实现循环:
- 循环结构
- 可变性
- 副作用
我们可以以函数式的方式以不同的方式实现相同的循环。它是线程安全的。我们可以使用以下两种技术以函数式风格实现循环:
- 递归
- 尾递归
- 不可变性
- 无副作用
在Scala中,“Application”是什么或Scala中的“App”是什么?Scala的App有什么用途?
Scala Application: 在Scala中,App是在scala包中定义的一个特质,如“scala.App”。它定义了main方法。如果对象或类扩展了此特质,它们将自动成为Scala可执行程序,因为它们将继承Application的main方法。使用App的主要优点是我们不需要编写main方法。使用App的主要缺点是我们应该使用相同的名称“args”来引用命令行参数,因为scala.App的main()方法使用这个名称。示例: 没有使用Scala App:
object MyApp {
def main( args: Array[String]){
println("Hello World!")
}
}
使用Scala App:
object MyApp extends App{
println("Hello World!")
}
如果我们观察上面的两个例子,在第二个例子中,我们没有定义main方法,因为我们已经继承了Scala App(Application)。在Scala 2.9之前,我们有scala.Application特质。但自Scala 2.9版本以来,它已被scala.App弃用。
Scala支持运算符重载吗?Java支持运算符重载吗?
Java不支持运算符重载。Scala支持运算符重载。原因是Java不希望支持一些误导性的方法名称,比如“+*/”。Scala给了开发者这种灵活性来决定应该使用哪些方法/函数名称。当我们调用2 + 3时,意思是‘+’不是运算符,它是Int类中的一个方法(或者是它的隐式类型)。在内部,这个调用被转换成“2.+(3)”。
什么是表达式?什么是语句?表达式和语句的区别是什么?
表达式: 表达式是一个值,意味着它将会求值为一个值。由于表达式返回一个值,我们可以将其赋给一个变量。例如:- Scala 的 If 条件,Java 的三元操作符。语句: 语句定义一个或多个操作。这意味着语句执行操作。由于它不返回值,我们不能将其赋给一个变量。例如:- Java 的 If 条件。
Java 的 “If…Else” 和 Scala 的 “If…Else” 有什么区别?
Java 的 “If…Else”: 在 Java 中,“If…Else” 是一个语句,而不是一个表达式。它不返回值,不能赋给一个变量。例如:-
int year;
if( count == 0)
year = 2014;
else
year = 2015;
Scala 的 “If…Else”: 在 Scala 中,“If…Else” 是一个表达式。它求值为一个值,即返回一个值。我们可以将其赋给一个变量。
val year = if( count == 0) 2014 else 2015
**注意:**Scala 的 “If…Else” 的工作方式类似于 Java 的三元操作符。我们可以像下面展示的那样使用 Scala 的 “If…Else”,就像使用 Java 的 “If…Else” 语句:
val year = 0
if( count == 0)
year = 2014
else
year = 2015
Scala是一种基于表达式还是基于语句的语言?Java是一种基于表达式还是基于语句的语言?
在Scala中,一切都是一个值。所有表达式或语句都会求值为一个值。我们可以将表达式、函数、闭包、对象等赋值给一个变量。因此,Scala是一种面向表达式的语言。在Java中,语句不是表达式或值。我们无法将它们赋值给一个变量。因此,Java不是一种面向表达式的语言,而是一种基于语句的语言。
告诉我一些Java支持但Scala不支持的特性,反之亦然?
- Java不支持运算符重载,但Scala支持它。
- Java支持++和—运算符,但Scala不支持。
- Java有检查异常和未检查异常,但Scala没有检查异常。
- Scala不支持break和continue语句,但Java使用它们。
- Scala没有显式类型转换,但Java支持此功能。
- Scala支持模式匹配,但Java不支持。
- Java使用原始数据类型,但Scala没有。
- Java支持静态成员,但Scala没有静态成员的概念。
- Scala支持隐式和特征,Java不支持它们。
**注意:**此列表超出了一页。但是,这些是关于Scala和Java特性差异的一些重要要点,以应对Scala面试。
Scala中函数和方法有什么区别?
Scala支持函数和方法两者。我们使用相同的语法来定义函数和方法,它们之间没有语法区别。然而,它们有一个小的区别:
- 我们可以在Scala类或特征中定义方法。方法与对象关联(类的实例)。我们可以通过使用类的实例来调用方法。我们不能在不使用对象的情况下直接使用Scala方法。
- 函数与类或特征无关。它在Scala包中定义。我们可以在不使用对象的情况下访问函数,就像Java的静态方法一样。
注意:在我的后续文章中,我们将讨论类、特征、包、对象等。
在Scala源文件中能够定义多少个公共类文件?
在Java中,我们最多可以在一个源文件中定义一个公共类/接口。与Java不同,Scala支持在同一个源文件中定义多个公共类。我们可以在Scala源文件中定义任意数量的公共类/接口/特征。
与Java一样,Scala语言中有哪些默认导入?
我们知道,java.lang是JVM自动导入所有Java程序中的默认包。我们不需要显式导入这个包。同样地,在所有Scala程序中都有以下默认导入:
- java.lang包
- scala包
- scala.PreDef
Scala有多少个操作符,为什么?
与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中使用但在Scala中不需要的关键字?为什么Scala不需要它们?
Java广泛使用以下关键字:
- ‘public’关键字 – 用于定义类、接口、变量等。
- ‘static’关键字 – 用于定义静态成员。
Scala不需要这两个关键字。Scala没有’public’和’static’关键字。
- 在Scala中,默认访问修饰符对于类、特质、方法/函数、字段等是’public’。这就是为什么不需要’public’关键字。
- 为了支持面向对象编程原则,Scala团队避免使用’static’关键字。这就是为什么Scala是一种纯面向对象的语言。在并发应用程序中处理静态成员非常困难。
Scala中的PreDef是什么?PreDef在Scala中的主要目的是什么?在Scala中,PreDef是作为”scala.PreDef”定义的对象,它是一个实用对象。它定义了许多实用方法,如下所示:
- 控制台IO(print、println等)
- 集合实用方法
- 字符串实用方法
- 隐式转换方法
- 断言实用方法等。
例如,print、println、readLine、readInt、require等方法都在PreDef对象中定义。在Scala中,PreDef可用于在所有Scala程序中使用其方法,因为Scala编译器会自动将此对象导入所有编译单元,如类、对象、特质等。就是关于“Scala基本面试问题和答案”的全部内容。我们将在接下来的文章中讨论一些中级、高级和实时Scala面试问题和答案。如果您喜欢我的文章或有任何问题/建议,请给我留言。
Source:
https://www.digitalocean.com/community/tutorials/scala-interview-questions-answers