《Spark编程基础》(Scala版)第二章简答题答案(自制)
2 Scala 语言基础
简答题
T1 简述 Scala 语言与 Java 语言的联系与区别。
答:
① 联系:
(1)Scala 和 Java 均运行在 JVM 之上;
(2)Scala 和 Java 均有面向对象语言特点;
② 区别:
(1)Scala 是类 Java 的多范式编程;Java 是命令式编程。
T2 简述 Scala 语言的基本特性。🌱
答:
① Scala 运行于 Java 虚拟机(JVM)之上,并且兼容现有的 Java 程序,可以与 Java 类进行互操作,包括调用 Java 方法、创建 Java 对象、继承 Java 类和实现 Java 接口。
② Scala 是一门面向对象的语言。在 Scala 语言中,每个值都是对象,每个操作都是方法调用。
③ Scala 也是一门函数式语言。在 Scala 语言中,每个函数都是一个对象,并且和其他类型(如整数、字符串等)的值处于同一地位。
T3 请分别用脚本和编译运行两种形式输出"Hello World"。❌
T4 Scala 有哪些基本数据类型和操作符?❌
答:
① 
② 
T5 在 Scala 里怎样定义一个变量?与Java的变量定义有什么区别?
答:
| Scala | Java | 补充说明 |
|---|---|---|
| val/var 变量名:数据类型 = 初始值 | 变量类型 变量名 = 值 | 语法结构 |
| val 变量名:数据类型 = 初始值 | val 声明时必须初始化,初始化后不再赋新的值 | |
| var 变量名:数据类型 = 初始值 | var 声明不必初始化,可以被多次赋值 |
类型推断机制会让 ”:数据类型“这一部分可以被忽略掉
T6 什么是 s 插值字符串?❌
答:这是在 Scala 提供的字符串插值机制中提供的两种方法之一。s 插值字符串是指在字符串字面量前加一个 ”s“ 字符,然后,在字符串中即可用 ”$“ 来插入变量的值,需要注意的是 s 字符串不支持格式化。
示例
val i = 10 val f = 1.14514 println(s"i=$i,f=$f") // 输出 i = 10,f=1.14514
T7 什么是 Scala 的类型推断机制?
答:类型推断机制是指 Scala 会根据初始值自动判断变量的类型,这使得定义变量时可以省略具体的数据类型以及前面的冒号。
T8 Scala 提供哪些控制结构?
答:
① 选择控制结构:包括 if 语句;
② 循环控制结构:包括 for 语句和 while 语句。
T9 什么是 for 推导式和生成器表达式?
答:
① 推导式:for (变量<-表达式) yield {语句块},”推导“是指通过 for 循环遍历一个或多个集合,对集合中的元素进行推导,从而计算得到新的集合,用于后续其他处理;
② 生成器表达式:for (变量<-表达式) {语句块} ,其中”变量<-表达式“被称为生成器。
T10 下述脚本的目的是输出数组中的偶数,请尝试在REPL下运行,并修改相应错误:🌱
Val array = Array(1,2,3,4,5,6)
For(a<-array;a%2==0) println(a)
答:for 循环语法错误,修改后如下:
for(a<-array if a % 2 == 0) println(a)
T11 Scala 如何实现 Java 循环中的 break 和 continue 功能?🌱
答:通过调用 Breaks 类,调用方法 breakable 和 break,通过配对使用来达到 Java 循环中 break 和 continue 的功能。
T12 Scala 的方法或函数中的参数是否可变?这种规定的好处是什么?❌
答:① 不能;② 没找着。
T13 Scala 通过什么机制暴露 private 的字段成员?什么是统一访问原则?
答:
① Scala 采用类似 Java 中的 getter 和 setter 方法,定义了两个成对的方法 value 和 value_=,其中的 value 是需要向用户暴露的字段名字;
② 当编译器看到以 value 和 value_= 这种成对形式出现的方法时,它允许用户去掉下划线"__",而采用类似赋值表达式的形式。从而使用户访问私有字段和公共字段的代码在形式上统一。
myCounter.value = 3 //等价于 myCounter.value_= (3)
T14 Scala 的类有哪两种类型的构造器?其中的参数作用有什么区别?🌱
答:
① 主构造器和辅助构造器;
② 主构造器的参数可以在整个类的定义中使用,相当于类的成员变量;辅助构造器的参数只在辅助构造器内部有效。
T15 简述Scala的类层次结构。❌
P58 大概率不考
T16 在 Scala 中,Nothing、Null、null、Option、Some、None分别代表什么,有何作用?❌
答:① Null 和 Nothing 是 Scala 类层级结构的最底层;
其中 Null 是所有引用类型的子类,其唯一示例为 null,表示一个”空“对象,可以赋值给任何引用类型的变量,但不能赋值给值类型的变量;Nothing 是所有其他类型的子类,包括 Null。Nothing 没有实例,主要用于异常处 理函数的返回类型。
② Option 是一个抽象类,用于统一表示对象有值或无值;
其有一个具体的子类 Some 和一个对象 None ,其中,前者表示有值的情形,后者表示没有值。
T17 什么是单例对象和伴生对象?
答:
① Scala 中的静态成员。单例对象的定义与类定义类似,只是用 object 关键字替换了 class 关键字。
② 单例对象包括两种,其一就是伴生对象。当一个单例对象和它的同名类一起出现时,这时的单例对象被称为这个同名类的伴生对象。
T18 简述 apply 方法和 unapply 方法的调用约定以及通常的应用场景。❌
答:
① apply 方法的调用约定:用括号传递给类实例或对象名一个或多个参数时,Scala 会在相应的类或对象中查找方法名为 apply 且参数列表与传入的参数一致的方法,并用传入的参数来调用该 apply 方法。
也就是括号传参给变量时,找这个变量的类/对象,看看有不有与参数对应的 apply 方法进行调用。
② apply 的通常应用场景:定义在类的伴生对象中,即将所有类的构造方法以 apply 方法的形式定义在伴生对象。
unapply 书上没具体说P56
T19 什么是 Scala 的特质,它与 Java 接口的联系和区别有哪些?
答:
① Scala 的特质是代码重用的基本单元,可以同时拥有抽象方法和具体方法。
② Scala 的特质是对 Java 接口的概念进行的改进,不仅实现了接口功能,同时具备许多其他特性。
T21 Scala 有哪几种常用的模式匹配用法?
答:
① match 语句:适用于多个分支中进行选择的场景,类似于 Java 中的 switch 语句;
② case 类:通常在 match 表达式中进行模式匹配,也可以在定义变量时直接从对象中提取属性值。
T22 什么是 case 类,它和普通类的区别是什么?
答:
① 当定义一个类时,如果在 class 关键字前加上 case 关键字,则该类称为 case 类;
② Scala 会为 case 类自动重载一些实用的方法,包括 toString、equals等方法;同时,会为每一个 case 类自动生成一个伴生对象,在该伴生对象中自动生成 一个 apply 方法和 unapply 方法的模板代码。
T23 为什么说 Scala 里的函数是“头等公民”,表现在哪些方面?
答:
① 在纯函数编程中,变量是不可变的,这种不变性造就了函数和普通的值之间的天然对等关系,所以说函数成为了和值一样的“头等公民”;
② 函数可以像任何其他数据类型的值一样被传递和操作。
T24 函数的类型和值指的是什么?
答:
① 类型:需要明确函数接受多少个参数、每个参数的类型以及函数返回结果的类型;
② 值:函数的一个具体体现。
T25 分别阐述高阶函数、闭包的概念。
答:
① 高阶函数:当一个函数包含其他函数作为其参数或者返回结果为一个函数时,该函数被称为高阶函数;
② 闭包:当函数的执行依赖于声明在函数外部的一个或多个变量时,则称这个函数为闭包。
T26 简要描述 Scala 的容器库层次结构,有哪些常用的容器类型?❌
答:
① 根据容器中元素的组织方式和操作方式,区分为有序和无序、可变和不可变等容器类别。在 Scala 中用了三个包来组织容器类,分别是scala.collection、scala.collection.mutable 和 scala.collection.immutable;其中 scala.collection.immutable 包是指元素不可变的容器;scala.collection.mutable 包指的是元素可变的容器;而 scala.collection 封装了一些可变容器和不可变容器的超类或特质,定义了可变容器和不可变容器的一些通用操作。
不确定咋答,不知道算不算层次结构,原文给薅过来了
② 列表(List)、映射(Map)、集合(Set)等常用数据结构。
T27 容器和迭代器的联系和区别是什么?
答:
① 联系:两者构造类似;均可访问容器内元素;
② 区别:(与容器相比,)迭代器不支持随机访问;迭代器只能按从前往后的顺序依次访问其元素,并且只能访问一次。
T28 如果c1是一个不可变的容器变量,c2是一个可变的容器变量,elem是一个对象,则cl+=elem 和c2+=elem的作用分别是什么?
答:
① 当执行c1 += elem时,它会创建一个新的容器,其中包含c1的元素和elem,然后将新的容器赋值给c1。这相当于执行c1 = c1 + elem。原始的不可变容器c1不会被修改,而是创建一个新的容器。
② 当你执行c2 += elem时,它会修改原始容器c2,将elem添加到容器中。这相当于执行c2.append(elem)。原始的可变容器c2会被修改,而不会创建一个新的容器。
GPT 警告(我个人觉着这个回答没啥问题)
T29 请描述map和flatMap的区别。
答:
① map:将某个函数应用到集合中的每个元素,映射得到一个新的元素,因此,map方法会返回一个与原容器类型大小都相同的新容器,只不过元素的类型可能不同。
② flatMap:将某个函数应用到容器中的元素时,对每个元素都会返回一个容器(而不是一个元素),然后,flatMap把生成的多个容器”拍扁”成为一个容器并返回。返回的容器与原容器类型相同,但大小可能不同,其中元素的类型也可能不同。
③ 区别:与 map 对容器内每一个元素映射得到一个新的元素,这导致 map 方法会返回一个与原函数类型大小都相同的新容器;与之相比,flatMap 是通过映射得到一个容器,并最后会将生成的多个容器”拍扁成一个容器返回,这导致返回的新容器类型相同,但是大小可能不同。
T30 请描述 reduce 和 fold 的区别。
答:
① reduce:接受一个二元函数 f 作为参数,首先将 f 作用在某两个元素上并返回一个值,然后再将 f 作用在上一个返回值和容器的下一个元素上,再返回一个值,依此类推,最后容器中的所有值会被规约为一个值。
② fold:是一个双参数列表的函数,第一个参数列表接受一个规约的初始值,第二个参数列表接受与 reduce 中一样的二元函数参数。
③ 区别:reduce 是从容器的两个元素开始规约,而 fold 则是从提供的初始值开始规约。

浙公网安备 33010602011771号