【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

时间:2022-01-27 08:30:25

目录:/Users/baidu/Documents/Data/Interview/Hadoop-Spark-Storm-Kafka

下了这本《大数据Spark企业级实战版》,

另外还有一本《Spark大数据处理:技术、应用与性能优化(全)》

先看前一篇。

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

根据书里的前言里面,对于阅读顺序的建议。先看最后的Scala实践三部曲吧。

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

scala学习,我觉得这一段写的很好:

object Hello{
def main(args: Array[String]): Unit = {
val ret = sum(x=> x*x)(1)(2)
println(ret)
} def sum(f: Int => Int)(a: Int)(b: Int): Int =
if (a > b) 0 else f(a) + sum(f)(a+1)(b) }

能够看出,上面是求出从a加到b的平方和。很巧妙。

Scala中有两点需要注意:

1. 函数体的最后一行的值就是整个函数的返回值;

2. 类型的声明位于变量、函数或者类的后面。

当函数不带参数时候,我们调用的时候,可以不加括号。

函数还可以这样定义:

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

要注意一下Scala的柯里化,currying,允许函数定义时候有多个括号,每个括号里面一个参数。在 Haskell 中,所有的函数都是柯里化的.

科里化(柯里化)这种现象是随着函数被当做一等公民自然而然地产生的。不然高阶函数会很麻烦。

注意Java和Python里面,都有可变参数的,可以看我的这篇文章:http://www.cnblogs.com/charlesblc/p/6226667.html

Scala里面也有可变函数。

如下:

def abc(s: String*) = {

s.foreach(x=>println(x))

}

然后就可以调用了

abc("I", "love", "you")

默认参数是这样的:

def abc(name :String = "default") : String = {

...

}

for循环:

查看我的这篇文章:http://www.cnblogs.com/charlesblc/p/6065424.html

Scala里面的面向对象

面向对象几点:

抽象和封装,继承,多态(多态也称为一个名字,多种方法)

注意 Scala里面的下划线,用的非常多,有个名字叫作Placeholder,下面这篇文章介绍了十几种用法:

https://my.oschina.net/leejun2005/blog/405305

没怎么看懂,慢慢领会。

文中用到了其中的第11中用法:

11、初始化默认值:default value var i: Int = _

另外,还有private[this]的使用:

class A{

private[this] val gender = "male"

}

那么在外面访问 val a = new A

a.gender 就会报错

看看主构造器的用法。有如下特点:

1. 主构造器直接跟在类名后面,参数会被编译成类的字段。

2. 执行时会执行类中的所有不包含在方法体中的语句。

class Person(val name: String, val age: Int) {

println("this is constructor!")

}

运行 val p = new Person("Rocky", 27) 会打印语句。

注意:

class Person(name: String, val age: Int) {

}

这样的话,运行会报错,找不到name,说明没有用val或者var加载主构造器函数的话,那么这个变量是 private[this]的,只能内部访问。(那类岂不是不能初始化?)

附属构造器

1) 附属构造器是通过this来声明的

2) 附属构造器必须调用主构造器或者其他附属构造器。

class Person(var name : String, val age: Int) {

var gender : String = _

def this(name: String, age: Int, gender: String) {

this(name, age)

this.gender = gender

}

}

继承

Scala继承用 extends来进行, 覆盖用 override来处理。

抽象类

abstract class A {

def speak

}

另外

object AAAClass extends App {

val worker = new Worker

worker.speak

}

App是trait的子类,内部帮助我们实现了main方法。

Scala的trait

trait支持部分实现,也就是说可以在scala的trait中可以实现部分方法。

trait可以有实现的方法,也可以有抽象方法。使用trait的方式是with而混入类中。不懂。

子trait可以覆盖父trait中的方法,如果父trait中已经实现了方法,子trait就必须用override关键字。

如果既要继承类,又要继承trait,可以用 with关键字,如下:

class MyAccount extends Account with FLogger {

def save {

log("10000")

}

}

其中 log 是定义在trait Flogger里面的函数。

然后在定义的时候,要这样写:

val acc = new MyAccount with MessageLogger

acc.save

上面的MessageLogger是实现了 Flogger 的trait,如下:

trait MessageLogger extends Flogger {

override def log(msg: String) {

}

}

另外,放在object里面的方法都是static方法,直接调用:

object abc {

def func{

}

}

abc.func

apply在object和class里面的应用

object里面可以定义apply

class A {

def test() {

println("test")

}

}

object A {

def apply() = new A

}

val a = A()

a.test

上面的 A() 直接调用 object A里面的apply(),返回了 class A,所以最后打印 "test"

class里面也可以定义apply

class A {

def apply() = "hi"

}

val a = new A

println(a())

上面的 () 调用了 apply(),所以打印了"hi"

因为object里面的方法和属性都是static的,所以用来实现单例,很方便。

object A {

def apply() = new A

var count = 0

def incr = {

count = count + 1

}

}

用法:

for (i <- 1 to 10) {

A.incr

}

println(A.count)

打印了10

总结:object本身就是一个单例对象!!!

Scala函数式编程

P773

函数式编程的核心特点之一,就是把函数作为参数传给函数、在函数内部可以定义函数等。

1. 函数式编程定义:其实是方法论(programming paradigm)

5个特点:

1. 函数是第一等公民

2. 总用表达式 expression,不用语句statement,(意思是总有返回值)

3. 没有副作用 (避免全局变量)

4. 不修改状态(只返回新的值,不修改系统变量)

5. 引用透明(运行只依赖于输入的参数)

好处:

1. 代码简洁,开发迅速; 2. 接近自然语言; 3. 方便的代码管理(不依赖外界状态)4. 并发编程方便 5. 易于热升级(只要接口不变,内部实现外部无关,erlang就是为了不关机升级)

Scala的函数形式:

def func(var : type) : retType = {}

返回类型,有时候可以直接推断出;但是写出来更好。如果是递归的,那么返回类型必须明确写出来。

如果函数体只是一句,也可以不加花括号。

Unit是返回类型,指的是没有有效的返回值,有点类似于Java的void。Java中返回void的方法,会被映射成Scala返回Unit的方法。

值函数

值函数指的就是将一个函数赋值给一个变量进行保存,这时候变量就变成了一个函数,用的时候跟函数一样用就可以了。

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

var result = add _   (注意,把函数赋值给变量的时候,必须在后面加上空格和_)

result(1, 2) 得到3

匿名函数

(x:Int) => x + 3

可以赋值给一个常量:  val fun = (x: Int) => x + 3

这就相当于  def fun(x: Int) = x + 3

调用是这样的 fun(7)

主要用途是作为参数传递,比如:

scala.collection.mutable.ArrayBuffer(1,2,3,4).map((x:Int)=>x+3)

Scala中的闭包

闭包 = 代码 + 用到的非局部变量

var y = 1

val sum = (x : Int) => x + y

sum(15)

这时候y是外部变量。

Scala中的SAM

Java中有些接口只有单个抽象方法(Single Abstract Method),在Java里面被称为 SAM类型。

为了在传入Java ActionListener对象的地方,传入 (ActionEvent)=>Unit函数参数,需要加一个隐式转换。

Scala中的Curry

柯里化,指的就是都变成一个参数的函数,新的函数返回一个以原有第二个参数为参数的函数。

def multi(x:Int) = (y: Int) => x * y

multi(6)(7)

柯里化可以简写成:

def multi(x:Int)(y:Int) = x * y

控制抽象 + 换名调用参数

可以组成不带参数也没有返回值的函数:

def runInThread(block: ()=>Unit) {

new Thread {

override def run() {block()}

}.start()

}

注意:如果方法的返回类型为Unit,则可以忽略result type 和 = 号。

runInThread{ ()=> println("Hi"); Thread.sleep(10000); println("Bye")}

可以去掉()=>,

def runInThread(block: =>Unit) {

new Thread {

override def run() {block}

}.start()

}

runInThread {println("Hi"); Thread.sleep(10000); println("Bye")}

Scala程序员可以构建控制抽象,看起来就像是关键字:

def until(condition: => Boolean) (block: =>Unit) {

if (!condition) {

block

until(condition)(block)

}

}

// 使用

var x = 10

until(x == 0) {

x -= 1

println(x)

}

这样的函数就叫做换名调用函数(常规的参数叫作换值调用参数)。函数在调用的时候,换名调用参数的表达式不会求值,表达式会被当做参数传递下去。

return表达式

P783 略

高阶函数

函数作为参数或作为返回值的函数称为 高阶函数

val a = List(1,2,3)

这里能够直接使用List实例化对象,其实是用了List的object对象的apply方法。

val newList = l.map((x:Int)=>2*x)

类型一样的话可以省略类型   l.map((x)=>2*x)

只有一个参数,可以省略括号  l.map(x=>2*x)

只有一个参数,可以继续省略  l.map(_*2)

常见的高阶函数有 map, filter, reduce

1. map

array.map(1 + _) 其中的 _代表列表里面的每一个元素

2. filter

array.filter( _ > 33) 大于33的

3. reduce

array.reduce(_ - _) 是第一个减去第二个,然后结果再减去第三个

Scala中的集合

主要有 List, Set, Tuple, Map等

关于 Array, List, Tuple的区别,可以看这篇文章:

https://my.oschina.net/u/1034176/blog/512314

在Scala 2.7中,Array、List都不能混合类型,只有Tuple可以;而在Scala以上版本中,3者的元素都可以混合不同的类型(转化为Any类型),只不过是当使用混合类型时,Array和List会将元素类型转化为Any类型,而Tuple则保留每一个元素的初始类型;

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

    1. 关于初始化

      1) Array:val array= new Array[String](3) // Array(null, null, null)相当于声明了3个null值的空元素

    2. val array= Array("a","b","c","d") //  相当于 Array.apply("a","b","c","d")

定义一个类型为Any的Array:

val aa = Array[Any](1, 2)或:val aa: Array[Any] = Array(1, 2)或:val aa: Array[_] = Array(1, 2)

2) List:

val list:List[Int] = List(1,3,4,5,6) // 或者 val list = List(1,3,4,5,6)

(:::)实现叠加List,(::)cons:将新元素组合到列表的最前端。元素合并使用::,集合合并使用:::,示例如下:其中Nil代表空元素

val list2 = "a"::"b"::"c"::Nil // Nil

val list4 = list2:::list3

3) Tuple:

元组也是不可变的,但是元组可以是不同类型的数据,实例化:var a = (,),可以通过点号,下划线,-N(N从1开始)的索引访问元素

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

对Tuple而言,如果只有两个元素,还可以通过下面的方式创建:

"a" -> "b"

得到:res7: (String, String) = (a, b)

Map类型

Map("a"->"b", "c"->"d")

Option类型

Option代表一个可有可无的值。

Option有两个子类:Some 和 None . 下面我们看一下Option的使用。

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

Option[T] 是一个类型为 T 的可选值的容器: 如果值存在, Option[T] 就是一个 Some[T] ,如果不存在, Option[T] 就是对象 None 。

优点大概是让有值和无值的操作变得统一吧。

filter的处理

下面两个是等价的:

l.filter(x=>x %2 ==0)

l.filter(x%2 == 0)

看一下zip的操作

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

partition的操作

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

flatten 和 flatMap 的操作

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

Scala中的泛型

p790

在Scala中用 [] 来代替Java中的 <> 来表现类型参数表。

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

Scala中的隐式转换、隐式参数、隐式类

P784

泛型和隐式转换都看不懂。以后再看吧。

回到第13页,第一章,开始看起。

Spark术语

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

Spark的容错主要是 Lineage机制。 分布式数据容错主要方式有:数据检查点,和记录数据的更新。 Spark是粗粒度的记录数据的更新,只记录数据怎么从其他RDD转换而来。

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

RDD依赖关系

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

Stage DAG

通常Shuffle是Stage的边界

看到第36页。

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

持久化与persist

通常每次运行会重新计算,如果不想重复计算,可以用 RDD.persist().  会存储在内存里(或者磁盘?)

不是必须,不应该持久化,因为浪费空间。

如果多次需要结果,可以持久化,如下:

right.persist()

right.first()

right.count()

另外关于 cache(),查了一下,就是全内存化的persist(),是用persist()实现的,即 persist(StorageLevel.MEMORY_ONLY)

创建RDD

Spark提供了两种创建RDD的方式:加载外部数据集,和在驱动程序中平行化集合。

分别是:

val lines = spark.textFile("hdfs://master:9000/input/in.txt")

val lines = spark.parallelize(List("pandas", "i like pandas"))

RDD操作

P38 下面这段讲的非常好:

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

转换和动作的示例

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

用take()可以检索一个小数目的结果。

还有一个collect()会输出全部结果。但是量比较大。可以使用 saveAsTextFile() 或者 saveAsSequenceFile()来存储到HDFS上。

惰性评估(Lazy Evaluation)

比如 sc.textFile(),数据没有被加载,只有到动作需要执行时候,才会真正加载。

Spark子框架解析

P30

Spark GraphX 看了一会 不懂。

Spark Stream

是按照时间节点,比如2秒,分成一段一段的,作为Dstream(Discretized Stream),然后这一段数据转换成RDD,那么Spark Streaming对于Dstream的操作就转换成了 Spark对于RDD的操作。

流程图如下:

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

Spark Streaming编程模型

P55 主要是这一句:

val wordCount = words.map(x=>(x,1)).reduceByKeyAndWindow(_+_, Seconds(5s), seconds(1))

P57

Kafka 和 Spark Streaming结合。

Spark SQL

P58

Spark MLlib

P61

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

上面提到的L1和L2,在下面这篇文章讲得很好:

http://blog.csdn.net/*_shi/article/details/52433975

L1正则和L2正则,其实都是加在损失函数后面的一个额外项。L1正则化和L2正则化可以看做是损失函数的惩罚项。

对于线性回归模型,使用L1正则化的模型建叫做Lasso回归,使用L2正则化的模型叫做Ridge回归(岭回归)。下图是Python中Lasso回归的损失函数,式中加号后面一项α||w||1即为L1正则化项。

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

下图是Python中Ridge回归的损失函数,式中加号后面一项α||w||22即为L2正则化项。

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

一般回归分析中回归w表示特征的系数,从上式可以看到正则化项是对系数做了处理。L1正则化和L2正则化的说明如下:

  • L1正则化是指权值向量w中各个元素的绝对值之和,通常表示为||w||1
  • L2正则化是指权值向量w中各个元素的平方和然后再求平方根(可以看到Ridge回归的L2正则化项有平方符号),通常表示为||w||2

一般都会在正则化项之前添加一个系数,Python中用α表示,一些文章也用λ表示。这个系数需要用户指定。

那添加L1和L2正则化有什么用?下面是L1正则化和L2正则化的作用,这些表述可以在很多文章中找到。

  • L1正则化可以产生稀疏权值矩阵,即产生一个稀疏模型,因此可以用于特征选择
  • L2正则化可以防止模型过拟合(overfitting);一定程度上,L1也可以防止过拟合

原因和解释,可以看上面那篇文章的原文。不细说了。

聚类

聚类是一种非监督学习。聚类常被用于探索性分析,或者作为层次化监督学习的一部分(聚类之后再对不同的类簇采用不同的分类器或者回归模型)。

MLLib 实现了 kmeans.

协同过滤

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

注意显性反馈与隐性反馈。

目前Spark里面可用的算法:

ALS

基础算法-梯度下降算法

P63

二元分类 线性回归 聚类 协同过滤ALS 例子

P64

第四章 Spark RDD与编程API实战

P171

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

P193

通过 toDebugString 函数可以查看 lineage信息。

P195

有一个实战搜狗日志的例子,不知道是不是跟之前的实战例子类似。

P198

实例,按条件搜索:

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

实例,排序,按照val排序的方式

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

P206

Spark支持的Transformation操作

Spark支持的Action操作

P219

Spark运行的主要流程,包括Master,Driver,Worker,DAGScheduler各自参与的工作。

P259

6.1 Spark内核核心术语

Application 等术语的解释和描述。

看到P299 GraphX 图运算 先跳过不看

先看P431里面的 Spark MLLib吧

还有 P665的第14章 性能调优 可以看,锦上添花那种。

MLLib实际对应 P443

P444介绍了机器学习的基本概念:

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习

讲了各种机器学习算法。

P455 介绍了一个基于Spark MLLib的SVM的实例。

代码非常简洁明了。

P474

MLLib经典算法案例解析(重点看线性回归、协同过滤)

【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习的更多相关文章

  1. 《大数据Spark企业级实战 》

    基本信息 作者: Spark亚太研究院   王家林 丛书名:决胜大数据时代Spark全系列书籍 出版社:电子工业出版社 ISBN:9787121247446 上架时间:2015-1-6 出版日期:20 ...

  2. Spark GraphX宝刀出鞘,图文并茂研习图计算秘笈与熟练的掌握Scala语言【大数据Spark实战高手之路】

    Spark GraphX宝刀出鞘,图文并茂研习图计算秘笈 大数据的概念与应用,正随着智能手机.平板电脑的快速流行而日渐普及,大数据中图的并行化处理一直是一个非常热门的话题.图计算正在被广泛地应用于社交 ...

  3. 大数据Spark超经典视频链接全集

    论坛贴吧等信息发布参考模板 Scala.Spark史上最全面.最详细.最彻底的一整套视频全集(特别是机器学习.Spark Core解密.Spark性能优化.Spark面试宝典.Spark项目案例等). ...

  4. 王家林 大数据Spark超经典视频链接全集&lbrack;转&rsqb;

    压缩过的大数据Spark蘑菇云行动前置课程视频百度云分享链接 链接:http://pan.baidu.com/s/1cFqjQu SCALA专辑 Scala深入浅出经典视频 链接:http://pan ...

  5. 以某课网日志分析为例 进入大数据 Spark SQL 的世界

    第1章 初探大数据 本章将介绍为什么要学习大数据.如何学好大数据.如何快速转型大数据岗位.本项目实战课程的内容安排.本项目实战课程的前置内容介绍.开发环境介绍.同时为大家介绍项目中涉及的Hadoop. ...

  6. 大数据存储&colon;MongoDB实战指南——常见问题解答

    锁粒度与并发性能怎么样? 数据库的读写并发性能与锁的粒度息息相关,不管是读操作还是写操作开始运行时,都会请求相应的锁资源,如果请求不到,操作就会被阻塞.读操作请求的是读锁,能够与其它读操作共享,但是当 ...

  7. 大数据spark学习第一周Scala语言基础

    Scala简单介绍 Scala(Scala Language的简称)语言是一种能够执行于JVM和.Net平台之上的通用编程语言.既可用于大规模应用程序开发,也可用于脚本编程,它由由Martin Ode ...

  8. Java开发想尝试大数据和数据挖掘,如何规划学习?

    大数据火了几年了,但是今年好像进入了全民大数据时代,本着对科学的钻(zhun)研(bei)精(tiao)神(cao),我在17年年初开始自学大数据,后经过系统全面学习,于这个月跳槽到现任公司. 现在已 ...

  9. 【慕课网实战】一、以慕课网日志分析为例 进入大数据 Spark SQL 的世界

    课程整套CDH相关的软件下载地址:http://archive.cloudera.com/cdh5/cdh/5/ cdh-5.7.0 生产或者测试环境选择对应CDH版本时,一定要采用尾号是一样的版本 ...

随机推荐

  1. &lt&semi;八&gt&semi;面向对象分析之UML核心元素之分析类

    一:基本概念        ---->在那大数项目中,分析类是被忽视的一种非常有用的元素.        ---->分析类用于获取系统中主要的“职责簇”,他们代表系统的原型类,是系统必须处 ...

  2. SSH 连接慢的解决方案详解

    SSH 连接慢的解决方案详解 http://www.codeceo.com/article/ssh-slow.html

  3. 验证合法的url

    package test; import java.util.regex.Matcher;import java.util.regex.Pattern; public class Test { pub ...

  4. NAT详解

    1.为什么出现了NAT? IP地址只有32位,最多只有42.9亿个地址,还要去掉保留地址.组播地址,能用的地址只有36亿左右,但是当下有数以万亿的主机,没有这么多IP地址怎么办,后面有了IPv6,但是 ...

  5. Struts2单文件上传原理及示例

    一.文件上传的原理 表单元素的enctype属性指定的是表单数据的编码方式,该属性有3个值: 1.application/x-www-form-urlencoded:这是默认编码方式,它只处理表单域里 ...

  6. C&num;-命名空间(十五)

    概念 命名空间的设计目的是提供一种让一组名称与其他名称分隔开的方式 在一个命名空间中声明的类的名称与另一个命名空间中声明的相同的类的名称不冲突 命名空间的定义是有一定的规范,避免引起不必要的麻烦 命名 ...

  7. hibernate&lpar;一&rpar; 第一个hibernate工程

    序言 其实hibernate已经学过一遍,不过因为太糊弄,急于求成,导致现在需要重新来学习,通过亲自去敲每一行代码,来去理解每一个知识点. ---WH 一.什么是Hibernate? 轻量级JavaE ...

  8. oracle学习笔记一:用户管理(2)创建删除用户

    本文主要介绍如何创建和删除用户,当然里面牵涉很多知识,慢慢道来. 1,创建用户 需求:假设你是oracle管理员,当一个同事入职,你需要分配给一个账号. 创建用户,一般需要有相应权限的用户才可以创建用 ...

  9. bartender学习

    参考: 官网  https://www.seagullscientific.com/label-software/barcode-label-design-and-printing 文章 http:/ ...

  10. 微信小程序 scroll-view隐藏横向滚动条

    ::-webkit-scrollbar { width: 0; height: 0; color: transparent; }