24

Spark技术栈-Scala

 3 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzA4NzA5NzE5Ng%3D%3D&%3Bmid=2650229961&%3Bidx=1&%3Bsn=eda5917e06edcf8cb2851402e3f5be1c
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

点击关注上方“ 知了小巷 ”,

设为“置顶或星标”,第一时间送达干货。

Spark技术栈-Scala

b2iqQbU.png!mobile

Scala combines object-oriented and functional programming in one concise, high-level language. Scala's static types help avoid bugs in complex applications, and its JVM and JavaScript runtimes let you build high-performance systems with easy access to huge ecosystems of libraries.

1. Scala的偏函数

偏函数,即Partial Function,是数学概念,它不是“函数”的一种,它跟函数是平行的概念。Scala中的Partial Function是一个Trait,类型为PartialFunction[A,B],其中接收一个类型为A的参数,返回一个类型为B的结果,它是一个 一元函数(a unary function)

trait PartialFunction[-A, +B] extends (A => B) { self =>
import PartialFunction._

def isDefinedAt(x: A): Boolean

def orElse[A1 <: A, B1 >: B](that: PartialFunction[A1, B1]): PartialFunction[A1, B1] =
new OrElse[A1, B1] (this, that)

override def andThen[C](k: B => C): PartialFunction[A, C] =
new AndThen[A, B, C] (this, k)

def lift: A => Option[B] = new Lifted(this)

def applyOrElse[A1 <: A, B1 >: B](x: A1, default: A1 => B1): B1 =
if (isDefinedAt(x)) apply(x) else default(x)

def runWith[U](action: B => U): A => Boolean = { x =>
val z = applyOrElse(x, checkFallback[B])
if (!fallbackOccurred(z)) { action(z); true } else false
}
}

简单举例:可以理解为枚举或者K-V或者case .. default

scala> val pf:PartialFunction[Int, String] = {
| case 1=>"One"
| case 2=>"Two"
| case 3=>"Three"
| case _=>"Other"
|}
}

pf:PartialFunction[Int, String] = <function1>

scala> pf(1)
res0: String = One

scala> pf(2)
res1: String = Two

scala> pf(3)
res2: String = Three

scala> pf(4)
res3: String = Other

2. Scala的柯里化

柯里化函数也叫做多参数列表函数,本身就是指把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。

简单理解就是改变函数的形式,不改变函数的功能。就是把多元函数变换为一元函数。

def add(x:Int,y:Int)=x+y
add(1,2)

def add(x:Int)(y:Int) = x + y
add(1)(2)

上面从add(1,2) ==> add(1)(2)就是柯里化。实现过程:

add(1)(2) 实际上是依次调用两个普通函数(非柯里化函数),第一次调用使用一个参数 x,返回一个函数类型的值,第二次使用参数y调用这个函数类型的值。

def add(x:Int)=(y:Int)=>x+y

接收一个x为参数,返回一个匿名函数,该匿名函数的定义是:接收一个Int型参数y,函数体为x+y。

// result: (y:Int)=>1+y
val result = add(1)
// 2 + 1
val sum = result(2)

3. Scala的apply和unapply方法是什么作用?

apply :通常,在一个类的伴生对象中定义apply方法,在生成这个类的对象时,就省去了new关键字。

unapply

:可以认为unapply方法是apply方法的反向操作,apply方法接受构造参数变成对象,而unapply方法接受一个对象,从中提取值(成员变量)。

4. Scala的元组定义之后可变吗?

元组在Scala语言中是一个非常有用的容器对象。与列表一样,元组也是不可变的;但是与列表不同,元组可以包含不同类型的元素。例如,列表只能写成List[Int]或者List[String],但是元组可以同时拥有Int和String。元组适用场景很多,比方说,如果需要在方法里返回多个对象。Java里的做法是创建JavaBean用来包含多个返回值,Scala里可以直接返回元组(翻版的Map,只是Key是顺序数字)。主要是用起来也很简单;只要把元组实例化需要的对象放在括号里,并用逗号分隔即可。元组实例化之后,可以用点号、下划线和基于1的索引访问其中的元素。目前Scala支持的元组最大长度为22。对于更大长度可以使用集合,或者扩展元组。

5. Java VS Scala

Scala来源于Java,又“高于”Java,在Java之上增加了一层编码的“API”,让程序员可以通过函数式编程的方式来开发程序。

Scala程序最终被编译为.class文件运行在JVM虚拟机中,所以它是JVM下的语言一种,其他的还有Groovy等。

区别

  1. 变量声明

  • var变量;val常量;Scala支持自动类型推断

  • Scala更多的是采用常量,而不是变量来解决问题,这样带来的好处是可以减少多线程并发安全问题,特别适合高并发分布式的场景。

  1. 函数的声明

  • 关键字def,Scala函数没有返回值时使用Unit,相当于Java的void。

  • Scala支持函数式编程,可以使用高阶函数,函数是一等公民。

  1. 基本类型

    Scala中没有真正意义上的基本类型,类型都是类。

  2. 静态

  • Java中静态static是违背Java OOP编程思想和封装特性。

  • Scala取消了静态的概念,使用了单例对象Object来实现。

  1. 字符串

  • Scala支持使用字符串插值的方式对字符串进行格式化,使用$开头进行取值。

  • 另外支持使用三引号将其中的内容直接包起来(Python也有三引号),其中可以包括任何字符,而不需要进行特别转义。

  • Scala类中的字段自动带有getter和setter方法,另外可以使用@BeanProperty注解来生成Java中的Get/Set方法。

  • Scala中的每个类都有一个主构造方法,这个构造方法和类定义“交织在一起”,类的参数直接成为类的字段,主构造方法执行类体中的所有语句。

  1. Scala中不支持break

  • 使用return替代

  • 在循环中使用if和布尔类型变量

  • 导入Java中支持break的包

  1. 访问范围

  • Java中外部看不到内部,内部能看到外部

  • Scala中外部看不到内部,内部也看不到外部

  1. 通配符

  • Java中使用* 进行通配

  • Scala中使用_ 进行通配

  1. 默认导入的类

  • Scala默认java.lang包、Scala包、Scala.Predef类

  • Java默认导入java.lang包

  1. 特质trait可以类比Java中的接口,但是和接口非常不一样

  • Java中称为 类实现了接口,Scala中称为 混入了特质

  • 和Java中的接口不同,Scala中的特质可以包含带有方法体的方法(JDK8接口也可以的,比如default方法)。

6. Scala有哪些优点?

  • Scala是一门多范式(multi-paradigm)的编程语言,设计初衷是要集成面向对象编程和函数式编程的各种特性。

  • Scala运行在JVM上,并兼容现有的Java程序。

  • Scala源代码被编译为Java字节码,所以可以运行在JVM上,并可以调用现有的Java类库。

  • 作为流行的开源大数据内存计算引擎Spark的源码编程语言,Spark有着良好的性能优势。

  • Scala将成为未来大数据处理的主流语言。(Java也挺多,Python也可以)

7. Scala中的隐式函数

关键字:implicit

Scala在面对编译出现类型错误时,提供了一个由编译器自我修复的机制,编译器试图去寻找一个隐式implicit的转换方法,转换出正确的类型,完成编译,这就是implicit的意义。

8. val x=y=1 会报错

9. 编译好的Scala程序,运行时还需要Scala环境吗?

不需要

10. trait特质和abstract class(抽象类)的区别?

  1. 一个类只能继承一个抽象类,但是可以通过with关键字继承多个特质

  2. 抽象类有带参数的构造函数,特质不行

一个类混入多个特质是很方便的,但却只能扩展一个抽象类。所以优先使用特质,如果需要构造函数参数,则使用抽象类。

11. Scala数据类型有哪些?

Byte、Short、Int、Long、Float、Double、Char、String、Boolean、Unit、Null、Nothing、Any。

Any是所有类的超类。

AnyRef类是Scala里所有引用类reference class的基类。

12. Scala中String对象是可变的还是不可变的?假如要创建一个可以修改的字符串,应该使用哪个类?

Scala本身没有String,依然是Java String,当然是不可变的。

可变的话,依然是StringBuilder或StringBuffer。

13. Scala的闭包

闭包是一个函数,返回值依赖于声明在函数外部的一个或多个变量。

闭包的实质是代码与用到的非局部变量的混合,即:闭包 = 代码 + 用到的非局部变量。

var y = 1
val sum = (x: Int) => x + y
println(sum(1)) // 结果为2
y = 10
println(sum(1)) // 结果为11

14. 函数中的Unit

Scala中的Unit类型类似于Java中的void,没有返回值。主要的不同是在Scala中可以有一个Unit类型值,也就是();然而Java中是没有void类型的值的。除此之外,Unit和void是等效的。一般来说每一个返回void的Java方法对应一个返回Unit的Scala方法。

15. val a = 10,怎样将a转为double类型,String类型

a.toString
a.toDouble

16. ArrayBuffer和Array的区别

  • 数组里面可以放数字、字符串、布尔值以及对象和数组等,ArrayBuffer放0和1组成的二进制数据

  • 数组放在堆中,ArrayBuffer则把数据放在栈里面(取数更快)

  • ArrayBuffer初始化后固定大小,数组可以自由增减

猜你喜欢:

数据中台实战系列笔记

浅谈OLAP系统核心技术点(建议收藏)

HBase基础面试题总结

Hive基础面试题总结

MapReduce和YARN基础面试题总结

HDFS基础面试题总结

nIzeUzu.png!mobile


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK