Spark面试题(一)

目录

 

一、单项选择题

二、不定项选题  

三、填空题

四、判断题

五、简答题

六、编程题


一、单项选择题

1、下面哪个操作是窄依赖?()

  1. join 
  2. filter 
  3. group 
  4. sort

RDD之间的血缘关系又称依赖,包括两种,一种是窄依赖,RDDs之间分区是一一对应的,另一种是宽依赖,下游RDD的每个分区与上游RDD(也称之为父RDD)的每个分区都有关,是多对多的关系。

2、不属于Scala 7种数据类型之一的是?()

  1. Char
  2. Int
  3. Float
  4. LongLong

Byte、Char、Short、Int、Long、Float、Double

3、在Scala中如何获取字符串”Hello”的首字符和尾字符?()

  1. ”Hello”(0),”Hello”(5)
  2. “Hello”.take(1),”Hello”.reverse(0)
  3. “Hello”(1),”Hello”(5)
  4. “Hello”.take(0),”Hello”.takeRight(1)

获取首字符  :"Hello"(0) / "Hello".take(1)  

获取尾字符  :"Hello".reverse(0)  /"Hello".takeRight(1) 

4、Scala 允许用数学去乘字符串,在REPL中输入”crazy”*3,这个操作结果返回什么?()

  1. ”crazy”*3
  2. ccrraazzyy
  3. crazycrazycrazy     *是”crazy”这个字符串所具有的方法
  4. crazy

5、RDD和DataFrame最大的区别是?()

  1. 科学统计支持
  2. 多了schema
  3. 存储方式不一样
  4. 外部数据源支持

RDD以Person为类型参数,Spark框架本身不了解Person类的内部结构。DataFrame提供了详细的结构信息,使得Spark SQL可以清楚地知道该数据集中包含哪些列,每列的名称和类型各是什么。DataFrame多了数据的结构信息,即schema。RDD是分布式的Java对象的集合。DataFrame是分布式的Row对象的集合。

6、Spark中默认的存储级别()

  1. MEMORY_ONLY              存储在内存(jvm)中,内存不够不在缓存,需要时重新计算
  2. MEMORY_ONLY_SER          内存,每个分区是一个byte数组
  3. MEMORY_AND_DISK          存储在内存,如果内存不够,存储在磁盘
  4. MEMORY_AND_DISK_SER      类似B,溢出的分区存储在磁盘上

7、编写一个过程countdown(n:Int),打印从n到0的数字?()

  1. def countdown(n:Int){

          0 to n foreach print                       //012345678910

}

  1. def countdown(n:Int){

         (0 until n ).reverse foreach print            //9876543210

}

  1. def countdown(n:Int){

        0 to n reverse foreach print          //x

}

  1. def countdown(n:Int){

        (0 to n-1) reverse foreach print       //x

}

 

正确答案:(0 to n).reverse foreach print              //109876543210

 

8、下面哪个属于Spark组成部件?()

  1. Resource Manager
  2. Executor  Driver
  3. RDD
  4. Client

 

9、下面哪个不是RDD的特点?()

  1. 不支持增量迭代计算
  2. 基于内存的计算
  3. 没有schema信息
  4. 支持细粒度的写和更新

spark写数据是粗粒度的。所谓粗粒度,就是批量写入数据,为了提高效率。但是读数据是细粒度的,也就是说是一条一条读的。不支持增量迭代计算,Flink支持。

10、对于函数

Def getGoodsPrice(goods:String)={

Val prices = Map (“book”-> 5 ,”pen” -> 2,”sticker” ->1)

Prices.getOrElse(goods,0)

}

结果说法错误的是?()

  1. getGoodsPrice(“book”)//等于5
  2. getGoodsPrice(“pen”)//等于2
  3. getGoodsPrice(“sticker”)//等于1
  4. getGoodsPrice(“sock”)//等于”sock”     //0

二、不定项选题  

  1.  关于数据及软件架构的CAP理论不包括下面哪些( D  )

             A. 可用性 B. 一致性 C. 分区容忍性 D. 分布性 

     CAP指的是在一个分布式系统中,一致性可用性、分区容错性。这三个要素最多只能同时实现两点,不可能三者兼顾。

 

 2 下列关于spark中的RDD描述正确的有 ( ABCD   ) 

  1.  RDD(Resilient Distributed Dataset)叫做弹性分布式数据集,是spark中最基本的数据抽象 
  2.  Resilient:表示弹性的,弹性表示内存不够存入磁盘 
  3.  Destributed:分布式,可以并行在集群计算
  4.  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. 基于分布式计算的框架 

       RDDLineage会记录RDD的元数据信息和转换行为,当该RDD的部分分区数据丢失时,它可以根据这些信息来重新运算和恢复丢失的数据分区。

6. 下面哪个操作是窄依赖?(  B  )
 A. join    B. filter  C. group   D. sort   

7.下面哪个操作肯定是宽依赖 (  C )     reduceBykeygroupByKey都是宽依赖
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

三、填空题

  1. 最早是Cloudera提供的日志收集系统,目前是Apache下的一个孵化项目,支持在日志系统中定制各类数据发送方,用于收集数据的工具是_______flume_________;一个分布式应用程序协调服务,分布式应用程序可以基于它实现同步服务,配置维护和命名服务等的工具是_____zookeeper_____;作为分布式信息队列,既有非常优秀的吞吐量,又有较高的可靠性和扩展性,同时接受Spark Streaming 的请求,将流量日志按序发送给Spark Streaming 集群是______kafka_______
  2. 写出四种Spark的部署模式____local_________standalone____________yarn____________mesos_______
  3. 定义一个类Counter,类里包含两个变量name,age 变量类型分别为String和Int的代码:

Class Counter __{

var name:String

var age:Int

}_。

  1. 函数 def fac(n:Int) = { var r = 1; for(i <- 1 to n )r = r * i } fac(5)输出结果是_____120_______。
  2. Scala的方法的参数都是_____ val _____类型,因此在函数体内不可以修改参数的值。
  3. 通过如下语句创建了一个______ SparkSession ________对象:

   Scala>import org.apache.spark.sql.SparkSession

   Scala>val spark = SparkSession.builder().getOrCreate();

四、判断题

  1. RDD叫做弹性分布式数据集,是分布式内存的一个抽象概念,提供了一种 高度受限的共享内存模型。(对)
  2. 基于分布式计算的框架是spark比Mapreduce计算快的原因之一。(错)     内存计算、DAG有向无环图
  3. Spark最大的特点就是将计算数据、中间结果都存储在内存中,大大减少I/O开销。(对)
  4. 关于辅助构造器,辅助构造器必须要带参数。(对)     构造器this,主构造器无参,辅助有参
  5. Scala中可以将函数赋值给变量,如 val fun = scala.math.cell。(错)      scala.math.ceil(0.74)=1
  6. Spark 的四大组件分别是Spark Streaming、Spark MLlib、YARN、SparkSQL。(错)    SparkSQL、SparkStreaming、MLlib、GraphX
  7. transformation和action是Spark支持的两种RDD操作。(对)
  8. 对于代码class Cat extends Animal{ }来讲,Cat是Animal的超类。(错)
  9. Scala中接口称为特质,跟java中的接口一样,特质中不可以有构造器。(错)
  10. 类和单例对象间的差别是单例对象不可以带参数,而类可以。(对)

       单例对象相当于静态方法,不是new出来,所以没办法传值。与类同名即是伴生对象

五、简答题

  1. 下列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语句完成下列操作:

  1. 查询所有数据,并去除重复的数据;
  2. 查询所有数据,打印时去除id字段;
  3. 筛选出age>30的记录;
  4. 查询所有记录的name列,并为其取名为username;
  5. 查询年龄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);

【代码】

}

写出在【代码】处填入以下代码时的输出结果。

  1. val result = namerdd.join(scorerdd);
  2. Result.collect.foreach(println);
  3. Result.count();
  4. 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))
       */
    }
  }
}

六、编程题

  1. 如何使用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

需求:

  1. 对上述数据按Key值进行分组;
  2. 对分组后的值进行排序;
  3. 截取分组后的值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()
  }
}
发布了77 篇原创文章 · 获赞 19 · 访问量 4050

猜你喜欢

转载自blog.csdn.net/qq_41861558/article/details/103798466