目录
一、单项选择题
1、下面哪个操作是窄依赖?()
- join
- filter
- group
- sort
RDD之间的血缘关系又称依赖,包括两种,一种是窄依赖,RDDs之间分区是一一对应的,另一种是宽依赖,下游RDD的每个分区与上游RDD(也称之为父RDD)的每个分区都有关,是多对多的关系。
2、不属于Scala 7种数据类型之一的是?()
- Char
- Int
- Float
- LongLong
Byte、Char、Short、Int、Long、Float、Double
3、在Scala中如何获取字符串”Hello”的首字符和尾字符?()
- ”Hello”(0),”Hello”(5)
- “Hello”.take(1),”Hello”.reverse(0)
- “Hello”(1),”Hello”(5)
- “Hello”.take(0),”Hello”.takeRight(1)
获取首字符 :"Hello"(0) / "Hello".take(1)
获取尾字符 :"Hello".reverse(0) /"Hello".takeRight(1)
4、Scala 允许用数学去乘字符串,在REPL中输入”crazy”*3,这个操作结果返回什么?()
- ”crazy”*3
- ccrraazzyy
- crazycrazycrazy *是”crazy”这个字符串所具有的方法
- crazy
5、RDD和DataFrame最大的区别是?()
- 科学统计支持
- 多了schema
- 存储方式不一样
- 外部数据源支持
RDD以Person为类型参数,Spark框架本身不了解Person类的内部结构。DataFrame提供了详细的结构信息,使得Spark SQL可以清楚地知道该数据集中包含哪些列,每列的名称和类型各是什么。DataFrame多了数据的结构信息,即schema。RDD是分布式的Java对象的集合。DataFrame是分布式的Row对象的集合。
6、Spark中默认的存储级别()
- MEMORY_ONLY 存储在内存(jvm)中,内存不够不在缓存,需要时重新计算
- MEMORY_ONLY_SER 内存,每个分区是一个byte数组
- MEMORY_AND_DISK 存储在内存,如果内存不够,存储在磁盘
- MEMORY_AND_DISK_SER 类似B,溢出的分区存储在磁盘上
7、编写一个过程countdown(n:Int),打印从n到0的数字?()
- def countdown(n:Int){
0 to n foreach print //012345678910
}
- def countdown(n:Int){
(0 until n ).reverse foreach print //9876543210
}
- def countdown(n:Int){
0 to n reverse foreach print //x
}
- def countdown(n:Int){
(0 to n-1) reverse foreach print //x
}
正确答案:(0 to n).reverse foreach print //109876543210
8、下面哪个属于Spark组成部件?()
- Resource Manager
- Executor Driver
- RDD
- Client
9、下面哪个不是RDD的特点?()
- 不支持增量迭代计算
- 基于内存的计算
- 没有schema信息
- 支持细粒度的写和更新
spark写数据是粗粒度的。所谓粗粒度,就是批量写入数据,为了提高效率。但是读数据是细粒度的,也就是说是一条一条读的。不支持增量迭代计算,Flink支持。
10、对于函数
Def getGoodsPrice(goods:String)={
Val prices = Map (“book”-> 5 ,”pen” -> 2,”sticker” ->1)
Prices.getOrElse(goods,0)
}
结果说法错误的是?()
- getGoodsPrice(“book”)//等于5
- getGoodsPrice(“pen”)//等于2
- getGoodsPrice(“sticker”)//等于1
- getGoodsPrice(“sock”)//等于”sock” //0
二、不定项选题
- 关于数据及软件架构的CAP理论不包括下面哪些( D )
A. 可用性 B. 一致性 C. 分区容忍性 D. 分布性
CAP指的是在一个分布式系统中,一致性、可用性、分区容错性。这三个要素最多只能同时实现两点,不可能三者兼顾。
2 下列关于spark中的RDD描述正确的有 ( ABCD )
- RDD(Resilient Distributed Dataset)叫做弹性分布式数据集,是spark中最基本的数据抽象
- Resilient:表示弹性的,弹性表示内存不够存入磁盘
- Destributed:分布式,可以并行在集群计算
- Dataset:就是一个集合,用于存放数据的
3. 下列哪些是java技术的特征( ABC )
A. 封装 B. 继承 C. 多态 D.分布性
4. 下列描述正确的是( ABD )
A. 进程(Process)是程序的一次执行过程
B. 线程(Thread) 是比进程更小的执行单位
C. 线程不可共享相同的内存单元 同一个进程内的线程使用的是同一块内存
D.在同一个应用程序中可以有多个线程同时执行
5. 下面哪些是spark比Mapreduce计算快的原因( ABC )
A. 基于内存的计算 B. 基于DAG的调度框架
C. 基于Lineage的容错机制 D. 基于分布式计算的框架
RDD的Lineage会记录RDD的元数据信息和转换行为,当该RDD的部分分区数据丢失时,它可以根据这些信息来重新运算和恢复丢失的数据分区。
6. 下面哪个操作是窄依赖?( B )
A. join B. filter C. group D. sort
7.下面哪个操作肯定是宽依赖 ( C ) reduceBykey和groupByKey都是宽依赖
A. map B. flatMap
C. reduceByKey D. sample
8. 最早是Cloudera提供的日志收集系统,目前是Apache下的一个孵化项目,支持在日志系统中定制各类数据发送方,用于收集数据的工具是( A )
A. Flume B. Zookeeper C. Storm D. Sparkstreaming
9.一个分布式应用程序协调服务,分布式应用程序可以基于它实现同步服务,配置维护和命名服务等的工具有 ( B )
A. Flume B. Zookeeper C. Storm D. Sparkstreaming
10. 作为分布式消息队列,既有非常优秀的吞吐量,又有较高的可靠性和扩展性,同时接受Spark Streaming的请求,将流量日志按序发送给Spark Streaming集群是 ( C )
A. Flume B. Zookeeper C. Kafka D. Sparkstreaming
11. Hadoop框架的缺陷有( ABC )
A. MR编程框架的限制
B. 过多的磁盘操作,缺乏对分布式内存的支持
C. 无法高效的支持迭代式计算
D.海量的数据存储
Hadoop不支持迭代式计算,spark支持(RDD迭代)
12. Hadoop组件的核心功能包括( AD )
A、分布式数据存储 B、分析 C、挖掘 D、分布式计算
13. DataFrame 和 RDD 最大的区别 ( B )
A.科学统计支持 B.多了schema
C.存储方式不一样 D.外部数据源支持
14. spark中默认的存储级别 ( A )
A. MEMORY_ONLY B. MEMORY_ONLY_SER
C. MEMORY_AND_DISK D. MEMORY_AND_DISK_SER
15. Spark组成部件包括( BC )
A. Resource Manager B. Executor C. Driver D. RDD
16. Spark RDD的依赖机制包括( AD )
A. 宽依赖 B. 深度依赖 C. 广度依赖 D. 窄依赖
17. RDD有哪些缺陷? ACD
A.不支持细粒度的写和更新操作(如网络爬虫)
B.基于内存的计算
C.拥有schema信息
D.不支持增量迭代计算 (可以使用checkpoint)
18. Spark应用的计算逻辑会被解析成DAG,这个解析操作由以下哪个功能模块完成( CD )
A. Client B. ApplicationMaster
C. Executor D. Driver
19. spark的部署模式有? ABCD
A.本地模式 B.standalone 模式 C.spark on yarn 模式 D.mesos模式
20. 下面不是Spark 的四大组件的有( BD )
A. Spark Streaming
B. pyspark 为了用Spark支持Python,Apache Spark社区发布了一个工具PySpark
C. Graphx
D. Spark R SparkR是一个R语言包,它提供了轻量级的方式使得可以在R语言中使用Apache Spark
Spark 的四大组件有:Spark SQL、Spark Streaming、MLlib、GraphX
三、填空题
- 最早是Cloudera提供的日志收集系统,目前是Apache下的一个孵化项目,支持在日志系统中定制各类数据发送方,用于收集数据的工具是_______flume_________;一个分布式应用程序协调服务,分布式应用程序可以基于它实现同步服务,配置维护和命名服务等的工具是_____zookeeper_____;作为分布式信息队列,既有非常优秀的吞吐量,又有较高的可靠性和扩展性,同时接受Spark Streaming 的请求,将流量日志按序发送给Spark Streaming 集群是______kafka_______。
- 写出四种Spark的部署模式____local_____、____standalone_______、_____yarn______、______mesos_______。
- 定义一个类Counter,类里包含两个变量name,age 变量类型分别为String和Int的代码:
Class Counter __{
var name:String
var age:Int
}_。
- 函数 def fac(n:Int) = { var r = 1; for(i <- 1 to n )r = r * i } fac(5)输出结果是_____120_______。
- Scala的方法的参数都是_____ val _____类型,因此在函数体内不可以修改参数的值。
- 通过如下语句创建了一个______ SparkSession ________对象:
Scala>import org.apache.spark.sql.SparkSession
Scala>val spark = SparkSession.builder().getOrCreate();
四、判断题
- RDD叫做弹性分布式数据集,是分布式内存的一个抽象概念,提供了一种 高度受限的共享内存模型。(对)
- 基于分布式计算的框架是spark比Mapreduce计算快的原因之一。(错) 内存计算、DAG有向无环图
- Spark最大的特点就是将计算数据、中间结果都存储在内存中,大大减少I/O开销。(对)
- 关于辅助构造器,辅助构造器必须要带参数。(对) 构造器this,主构造器无参,辅助有参
- Scala中可以将函数赋值给变量,如 val fun = scala.math.cell。(错) scala.math.ceil(0.74)=1
- Spark 的四大组件分别是Spark Streaming、Spark MLlib、YARN、SparkSQL。(错) SparkSQL、SparkStreaming、MLlib、GraphX
- transformation和action是Spark支持的两种RDD操作。(对)
- 对于代码class Cat extends Animal{ }来讲,Cat是Animal的超类。(错)
- Scala中接口称为特质,跟java中的接口一样,特质中不可以有构造器。(错)
- 类和单例对象间的差别是单例对象不可以带参数,而类可以。(对)
单例对象相当于静态方法,不是new出来,所以没办法传值。与类同名即是伴生对象
五、简答题
- 下列JSON格式数据命名为employee.json,文件路径“usr/local/spark/examples/employee.json”。
{“id” : 1 , “name”: “Ella” , “age”: 36}
{“id” : 2 , “name”: “Bob” , “age”: 29}
{“id” : 3 , “name”: “Jack” , “age”: 29}
{“id” : 4 , “name”: “Jim” , “age”: 28}
{“id” : 4 , “name”: “Jim” , “age”: 28}
{“id” : 5 , “name”: “Damon” }
{“id” : 5 , “name”: “Damon” }
为employee.json创建DataFrame,并写出Scala语句完成下列操作:
- 查询所有数据,并去除重复的数据;
- 查询所有数据,打印时去除id字段;
- 筛选出age>30的记录;
- 查询所有记录的name列,并为其取名为username;
- 查询年龄age的平均值。
/**
* 读取元数据json,并使用sql语句完成以下功能
*/
object SqlOperation3 {
def main(args: Array[String]): Unit = {
val sc = new SparkContext(new SparkConf().setAppName("SparkSQL").setMaster("local[*]"))
//创建SQLContext对象
val sqlc = new SQLContext(sc)
val df: DataFrame = sqlc.read.json("in/info.json")
//使用Sql语法
//注册临时表,这个表相当于存储在 SQLContext中所创建对象中
df.registerTempTable("t_person")
//1 查询所有数据,并去除重复的数据;
val sql = "select distinct * from t_person"
//2 查询所有数据,打印时去除id字段;
val sql2 = "select id,name from t_person"
//3 筛选出age>30的记录;
val sql3 = "select * from t_person where age>30"
//4 查询所有记录的name列,并为其取名为username
val sql4 = "select name as username from t_person"
//5 查询年龄age的平均值
val sql5 = "select avg(age) from t_person"
//查询
val res = sqlc.sql(sql)
res.show() //默认打印是20行
// 固化数据,将数据写到文件中mode是以什么形式写 写成什么文件
// res.write.mode("append").json("out3")
//除了这两种还可以csv模式,json模式
// res.write.mode("append").save("out4")
}
//case class,编译器自动为你创建class和它的伴生 object,并实现了apply方法让你不需要通过 new 来创建类实例
case class Person(id: Int, name: String, age: Int)
}
2、spark中的RDD是什么,有哪些特征?
1.RDD是由一系列的partition组成的
2.RDD之间具有依赖关系
3.RDD作用在partition是上
4.partition作用在具有(k,v)格式的数据集
5.partition对外提供最佳计算位置,利于数据本地化的处理
3、阅读下面这段代码
Def joinRdd(sc:SparkContext) {
Val name = Array(
Tuple2(1,”spark”),
Tuple2(2,”tachyon”),
Tuple2(3,”hadoop”)
)
Val score = Array(
Tuple2(1,100),
Tuple2(2,90),
Tuple2(3,80)
)
Val namerdd = sc.parallelize(name);
Val scorerdd = sc.parallelize(score);
【代码】
}
写出在【代码】处填入以下代码时的输出结果。
- val result = namerdd.join(scorerdd);
- Result.collect.foreach(println);
- Result.count();
- Result.take(3)
object spark {
def main(args: Array[String]): Unit = {
val sc = new SparkContext(new SparkConf().setAppName("SparkSQL").setMaster("local[*]"))
joinRdd(sc)
def joinRdd(sc: SparkContext) {
val name = Array(
Tuple2(1, "spark"),
Tuple2(2, "tachyon"),
Tuple2(3, "hadoop")
)
val score = Array(
Tuple2(1, 100),
Tuple2(2, 90),
Tuple2(3, 80)
)
val namerdd: RDD[(Int, String)] = sc.parallelize(name);
val scorerdd: RDD[(Int, Int)] = sc.parallelize(score);
//join:在类型为(K,V)和(K,W)的RDD上调用,返回相同key对应的元素对的(K,(V,W))的RDD
val result: RDD[(Int, (String, Int))] = namerdd.join(scorerdd);
result.collect.foreach(println)
println(result.count())
println(result.take(3).mkString(","))
/*
(1,(spark,100))
(2,(tachyon,90))
(3,(hadoop,80))
--------------------------------------
3
--------------------------------------
(1,(spark,100)),(2,(tachyon,90)),(3,(hadoop,80))
*/
}
}
}
六、编程题
- 如何使用Spark解决分组排序问题?
组织数据形式
aa 11
bb 11
cc 34
aa 22
bb 67
cc 29
aa 36
bb 33
cc 30
aa 42
bb 44
cc 49
需求:
- 对上述数据按Key值进行分组;
- 对分组后的值进行排序;
- 截取分组后的值top3位一key-value 形式返回结果。
/**
* 将数据分组排序取top3
*/
object group_sort {
def main(args: Array[String]): Unit = {
val sparkContext = new SparkContext(new SparkConf().setMaster("local[*]").setAppName(""))
val lined: RDD[String] = sparkContext.textFile("in/group_sort")
val maped: RDD[(String, String)] = lined.map(r => {
val strings: Array[String] = r.split(" ")
val key: String = strings(0)
val value: String = strings(1)
(key, value)
})
val sorted: RDD[(String, Iterable[String])] = maped.groupByKey().sortBy(_._2)
val maped2: RDD[(String, List[String])] = sorted.map(x => {
val key: String = x._1
val strings: List[String] = x._2.toList.reverse.take(3)
(key, strings)
})
maped2.foreach(println)
}
}
2、编程实现将RDD转换为DataFrame
源文件是在“/usr/local/spark/”目录中的student.txt文件,其内容如下(每行数据从左到右分别是 id,name,score):
1:张三:87
2:李四:88
3:王五:55
请将student.txt加载到内存中生成一个DataFrame,并按“id:1,name:张三,score:87”的格式打印出DataFrame的所有数据。
/*
*请将student.txt加载到内存中生成一个DataFrame,并按“id:1,name:张三,score:87”的格式
* 打印出DataFrame的所有数据。
*/
object student {
def main(args: Array[String]): Unit = {
val sparkContext = new SparkContext(new SparkConf().setMaster("local[*]").setAppName(""))
val lined: RDD[String] = sparkContext.textFile("in/3.txt")
val maped: RDD[(String, String, String)] = lined.map(x => {
val strings: Array[String] = x.split(":")
(strings(0), strings(1), strings(2))
})
val personRDD: RDD[person] = maped.map(tuple => {
person(tuple._1.toInt, tuple._2, tuple._3.toInt)
})
val sqlc: SQLContext = new SQLContext(sparkContext)
import sqlc.implicits._
val personDF: DataFrame = personRDD.toDF()
personDF.foreachPartition(rdd => {
val row: List[Row] = rdd.toList
row.foreach(x => {
println("id:" + x(0) + ",name:" + x(1) + ",score:" + x(2))
})
})
}
case class person(id: Int, name: String, score: Int)
}
3、写出一个Spark Streaming 程序,监控某目录中的文件,指定监控的目录为“/home/hadoop/temp/”,其能获取在该间隔时间段内变化的数据,例如在文件里新增一部分单词(单词之间用空格隔开)(文件夹新增文件),然后通过计算得出改时间段内的单词统计数。
部分代码已给出。
Import org.apache.spark.SparkConf
Import org.apache.spark.streaming.{Seconds,StreamingContext}
Import org.apache.spark.steaming.StreamingContext._
Object FileWordCount {
Def main(args:Array[String]) {
/**
* 监控文件夹,实现单词统计,结果保存到HDFS
*/
object FileStream {
def main(args: Array[String]): Unit = {
//1.初始化Spark配置信息
val sparkConf = new SparkConf().setMaster("local[*]").setAppName("StreamWordCount")
//2.初始化SparkStreamingContext
val ssc: StreamingContext = new StreamingContext(sparkConf,Seconds(5))
//3.监控文件夹创建DStream
val dirStream: DStream[String] = ssc.textFileStream("file:///home/hadoop/temp/") //不支持嵌套
//4.将每一行数据做切分,形成一个个单词
val wordStreams: DStream[String] = dirStream.flatMap(_.split(" "))
//5.将单词映射成元组(word,1)
val wordAndOneStreams = wordStreams.map((_, 1))
//6.将相同的单词次数做统计
val wordAndCountStreams = wordAndOneStreams.reduceByKey(_ + _)
//7.打印
// wordAndCountStreams.foreachRDD(x=>println(x))
wordAndCountStreams.print()
//8.启动SparkStreamingContext
ssc.start()
ssc.awaitTermination()
}
}