Spark-Core基础练习题30道

Spark-Core练习题

1、创建一个1-10数组的RDD,将所有元素*2形成新的RDD

val inputRDD = sc.parallelize(1 to 10)
val newRDD = inputRDD.map(_ * 2)

2、创建一个10-20数组的RDD,使用mapPartitions将所有元素*2形成新的RDD

val inputRDD = sc.parallelize(10 to 20)
val newRDD = inputRDD.mapPartitions(iter => {
  iter.map(_ * 2)
})
newRDD.foreach(println(_)) // 打印观察

3、创建一个元素为 1-5 的RDD,运用 flatMap创建一个新的 RDD,新的 RDD 为原 RDD 每个元素的 平方和三次方 来组成 1,1,4,8,9,27…

val inputRDD = sc.parallelize(1 to 5)
val newRDD = inputRDD.flatMap(n => {
  List(Math.pow(n, 2).toInt, Math.pow(n, 3).toInt)
})
newRDD.foreach(println(_)) // 打印观察

4、创建一个 4 个分区的 RDD数据为Array(10,20,30,40,50,60),使用glom将每个分区的数据放到一个数组

val inputRDD = sc.makeRDD(Array(10, 20, 30, 40, 50, 60), 4)
val newRDD: RDD[Array[Int]] = inputRDD.glom()

newRDD.foreach(x => println(x.mkString("Array(", ", ", ")"))) // 打印观察

5、创建一个 RDD数据为Array(1, 3, 4, 20, 4, 5, 8),按照元素的奇偶性进行分组

val inputRDD = sc.parallelize(Array(1, 3, 4, 20, 4, 5, 8), 4)
val newRDD = inputRDD.groupBy(x => x % 2 == 0)
newRDD.foreach(x => println(x))

6、创建一个 RDD(由字符串组成)Array(“xiaoli”, “laoli”, “laowang”, “xiaocang”, “xiaojing”, “xiaokong”),过滤出一个新 RDD(包含“xiao”子串)

val inputRDD = sc.makeRDD(Array("xiaoli", "laoli", "laowang", "xiaocang", "xiaojing", "xiaokong"))
val newRDD = inputRDD.filter(_.contains("xiao"))
newRDD.foreach(x => println(x))

7、创建一个 RDD数据为1 to 10,请使用sample不放回抽样

val inputRDD = sc.parallelize(1 to 10)
/*
  def sample(
    withReplacement: Boolean, // 抽取的数据是否放回,false:不放回
    // false:抽取的机率,范围[0,1]之间,0=全不取,1=全取
    // true:重复数据的机率,范围大于等于0.表示每个元素期望被抽取到的次数
    fraction: Double, // 抽取的几率
    seed: Long = Utils.random.nextLong // 随机数种子
  ): RDD[T]
 */
val newRDD = inputRDD.sample(withReplacement = false,0.5)
newRDD.foreach(x => println(x))

8、创建一个 RDD数据为1 to 10,请使用sample放回抽样

val inputRDD = sc.parallelize(1 to 10)
/*
  def sample(
    withReplacement: Boolean, // 抽取的数据是否放回,false:不放回
    // false:抽取的机率,范围[0,1]之间,0=全不取,1=全取
    // true:重复数据的机率,范围大于等于0.表示每个元素期望被抽取到的次数
    fraction: Double, // 抽取的几率
    seed: Long = Utils.random.nextLong // 随机数种子
  ): RDD[T]
 */
val newRDD = inputRDD.sample(withReplacement = true,0.5)
newRDD.foreach(x => println(x))

9、创建一个 RDD数据为Array(10,10,2,5,3,5,3,6,9,1),对 RDD 中元素执行去重操作

val inputRDD = sc.parallelize(Array(10,10,2,5,3,5,3,6,9,1))
val newRDD = inputRDD.distinct()
newRDD.foreach(x => println(x))

10、创建一个分区数为5的 RDD,数据为0 to 100,之后使用coalesce再重新减少分区的数量至 2

val inputRDD = sc.parallelize(0 to 100, 5)
val newRDD = inputRDD.coalesce(2)
newRDD.foreach(x => println(x))

11、创建一个分区数为5的 RDD,数据为0 to 100,之后使用repartition再重新减少分区的数量至 3

val inputRDD = sc.parallelize(0 to 100, 5)
val newRDD = inputRDD.repartition(3)
newRDD.foreach(x => println(x))

12、创建一个 RDD数据为1,3,4,10,4,6,9,20,30,16,请给RDD进行分别进行升序和降序排列

val inputRDD = sc.parallelize(Seq(1, 3, 4, 10, 4, 6, 9, 20, 30, 16),1)
inputRDD.sortBy(x => x).foreach(println(_))
inputRDD.sortBy(x => x, ascending = false).foreach(println(_))

13、创建两个RDD,分别为rdd1和rdd2数据分别为1 to 6和4 to 10,求并集

val rdd1 = sc.parallelize(1 to 6)
val rdd2 = sc.parallelize(4 to 10)
val rdd3 = rdd1.intersection(rdd2, 1)
rdd3.foreach(println(_))

14、创建两个RDD,分别为rdd1和rdd2数据分别为1 to 6和4 to 10,计算差集,两个都算

val rdd1 = sc.parallelize(1 to 6)
val rdd2 = sc.parallelize(4 to 10)
rdd1.subtract(rdd2, 1).foreach(println(_))
rdd2.subtract(rdd1, 1).foreach(println(_))

15、创建两个RDD,分别为rdd1和rdd2数据分别为1 to 6和4 to 10,计算交集

val rdd1 = sc.parallelize(1 to 6)
val rdd2 = sc.parallelize(4 to 10)
rdd1.union(rdd2).foreach(println(_))

16、创建两个RDD,分别为rdd1和rdd2数据分别为1 to 6和4 to 10,计算 2 个 RDD 的笛卡尔积

val rdd1 = sc.parallelize(1 to 6)
val rdd2 = sc.parallelize(4 to 10)
rdd1.cartesian(rdd2).foreach(println(_))

17、创建两个RDD,分别为rdd1和rdd2数据分别为1 to 5和11 to 15,对两个RDD拉链操作

val rdd1 = sc.parallelize(1 to 5)
val rdd2 = sc.parallelize(11 to 15)
rdd1.zip(rdd2).foreach(println(_))

18、创建一个RDD数据为List((“female”,1),(“male”,5),(“female”,5),(“male”,2)),请计算出female和male的总数分别为多少

val rdd = sc.parallelize(List(("female", 1), ("male", 5), ("female", 5), ("male", 2)))
rdd.reduceByKey(_ + _).foreach(println(_))

19、创建一个有两个分区的 RDD数据为List((“a”,3),(“a”,2),(“c”,4),(“b”,3),(“c”,6),(“c”,8)),取出每个分区相同key对应值的最大值,然后相加

val rdd = sc.parallelize(List(("a", 3), ("a", 2), ("c", 4), ("b", 5), ("c", 6), ("c", 8)), 2)
rdd.aggregateByKey(0)(
  (tmp, item) => {
    println(tmp,item,"---")
    Math.max(tmp, item)
  },
  (tmp, result) => {
    println(tmp,result,"--")
    tmp + result
  }
).foreach(println(_))

20、 创建一个有两个分区的 pairRDD数据为Array((“a”, 88), (“b”, 95), (“a”, 91), (“b”, 93), (“a”, 95), (“b”, 98)),根据 key 计算每种 key 的value的平均值

val pairRDD = sc.parallelize(Array(("a", 88), ("b", 95), ("a", 91), ("b", 93), ("a", 95), ("b", 98)), 2)
pairRDD
  .groupByKey()
  .map(x => x._2.sum / x._2.size)
  .foreach(println)

21、统计出每一个省份广告被点击次数的 TOP3,数据在access.log文件中

# 数据结构:时间戳,省份,城市,用户,广告 ,样本如下,字段使用空格分割
1516609143867 6 7 64 16
1516609143869 9 4 75 18
1516609143869 1 7 87 12
val inputRDD: RDD[String] = sc.textFile("datas/analysis/access.log")
inputRDD
  .map { log =>
    val Array(_, province, _, _, advertising) = log.split("\\s+")
    (province, advertising.toInt)
  }
  .reduceByKey(_ + _)
  .sortBy(tp => tp._2, ascending = false)
  .take(3)
  .foreach(println)

22、读取本地文件words.txt,统计出每个单词的个数,保存数据到 hdfs 上

val inputRDD: RDD[String] = sc.textFile("datas/analysis/words.txt")
inputRDD
  .flatMap(line => line.trim.split("\\s+"))
  .map(x => (x, 1))
  .reduceByKey(_ + _)
  .saveAsTextFile("hdfs://node1:8020/wordsOutput")

23、读取 people.json 数据的文件, 每行是一个 json 对象,进行解析输出

val inputRDD: RDD[String] = sc.textFile("datas/analysis/people.json")
inputRDD
  .map(line => new Gson().fromJson(line, classOf[people])) // 使用谷歌json解析
  .foreach(println)
  
case class people(name: String, age: Int)

24、保存一个 SequenceFile 文件,使用spark创建一个RDD数据为Array((“a”, 1),(“b”, 2),(“c”, 3)),保存为SequenceFile格式的文件到hdfs上

val inputRDD: RDD[(String, Int)] = sc.makeRDD(Array(("a", 1), ("b", 2), ("c", 3)))
inputRDD
  .saveAsSequenceFile("hdfs://node1:8020/sequence_output")

25、读取24题的SequenceFile 文件并输出

val inputRDD = sc.sequenceFile[String, Int]("hdfs://node1:8020/sequenceOutput")
inputRDD.foreach(println)

26、读写 objectFile 文件,把 RDD 保存为objectFile,RDD数据为Array((“a”, 1),(“b”, 2),(“c”, 3)),并进行读取出来

val inputRDD = sc.makeRDD(Array(("a", 1), ("b", 2), ("c", 3)))
inputRDD.saveAsObjectFile("datas/analysis/object")
sc.objectFile("datas/analysis/object").foreach(println)

27、使用内置累加器计算Accumulator.txt文件中空行的数量

val inputRDD = sc.textFile("datas/analysis/Accumulator.txt")
val acc = sc.longAccumulator("count")
inputRDD.foreach { line => if (line.isEmpty) acc.add(1) }
println(acc.value)

28、使用Spark广播变量

# 学生表:
id name age gender(0|1)
001,刘向前,18,0
002,冯 剑,28,1
003,李志杰,38,0
004,郭 鹏,48,1
# 要求,输出学生信息,gender必须为男或者女,不能为0,1
# 使用广播变量把Map("0" -> "女", "1" -> "男")设置为广播变量,最终输出格式为:
001,刘向前,18,003,李志杰,38,002,冯 剑,28,004,郭 鹏,48,
val inputRDD = sc.textFile("datas/analysis/student.txt")
val broad = sc.broadcast(Map("0" -> "女", "1" -> "男"))
inputRDD.map { line =>
  val arr = line.trim.split(",")
  arr(3) = broad.value.getOrElse(arr.last, null)
  arr.mkString(",")
}.foreach(println)

29、mysql创建一个数据库bigdata0407,在此数据库中创建一张表

CREATE TABLE bigdata.user (
 id int(11) NOT NULL AUTO_INCREMENT,
 username varchar(32) NOT NULL COMMENT '用户名称',
 birthday date DEFAULT NULL COMMENT '生日',
 sex char(1) DEFAULT NULL COMMENT '性别',
 address varchar(256) DEFAULT NULL COMMENT '地址',
 PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
-- 数据如下:
-- 依次是:姓名 生日 性别 省份
安荷 1998/2/7 女 江苏省
白秋 2000/3/7 女 天津市
雪莲 1998/6/7 女 湖北省
宾白 1999/7/3 男 河北省
宾实 2000/8/7 男 河北省
斌斌 1998/3/7 男 江苏省
-- 请使用spark将以上数据写入mysql中,并读取出来
val url = "jdbc:mysql://node1:3306/?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true"
val user = "root"
val passowrd = "123456"
// 往MySQL写入数据
val inputRDD = sc.textFile("datas/analysis/user.tet")
inputRDD
  .map { line =>
    val arr = line.trim.split(" ")
    (arr(0), arr(1), arr(2), arr(3))
  }
  .coalesce(1)
  .foreachPartition { iter =>
    Class.forName("com.mysql.cj.jdbc.Driver")
    var conn: Connection = null
    var ps: PreparedStatement = null
    try {
      // 获取连接
      conn = DriverManager.getConnection(url, user, passowrd)
      ps = conn.prepareStatement(
        """
          |INSERT INTO bigdata.user (username, birthday, sex, address)
          |VALUES (?, ?, ?, ?)
          |""".stripMargin)
      // 插入数据
      iter.foreach { tp =>
        ps.setString(1, tp._1)
        ps.setString(2, tp._2)
        ps.setString(3, tp._3)
        ps.setString(4, tp._4)
        ps.addBatch() // 加入批次
      }
      ps.executeBatch()
    } catch {
      case e: Exception => e.printStackTrace()
    } finally {
      if (null != ps) ps.close()
      if (null != conn) conn.close()
    }
  }

// 从MySQL读取数据,鸡肋
val jdbcRDD = new JdbcRDD(
  sc,
  () => {
    Class.forName("com.mysql.cj.jdbc.Driver")
    // 获取连接
    DriverManager.getConnection(url, user, passowrd)
  },
  "SELECT * FROM bigdata.user WHERE id BETWEEN ? AND ?",
  1, 6, 2,
  result => {
    println(s"id=${result.getInt(1)},username=${result.getString(2)}" +
      s",birthday=${result.getDate(3)},sex=${result.getString(4)}" +
      s",address=${result.getString(5)}")
  }
)
jdbcRDD.collect()

30、在hbase中创建一个表student,有一个 message列族

create 'student', 'message'
scan 'student', {COLUMNS => 'message'}
# 给出以下数据,请使用spark将数据写入到hbase中的student表中,并进行查询出来
# 依次是:姓名 班级 性别 省份,对应表中的字段依次是:name,class,sex,province
飞松   3   女  山东省
刚洁   1   男  深圳市
格格   4   女  四川省
谷菱   5   女  河北省
国立   2   男  四川省
海涛   3   男  广东省
含芙   3   女  四川省
华敏   4   女  上海市
乐和   2   男  上海市
乐家   3   男  黑龙江
乐康   4   男  湖北省
乐人   5   男  四川省
乐水   3   男  北京市
乐天   4   男  河北省
乐童   5   男  江苏省
乐贤   1   男  陕西省
乐音   2   男  广东省
李仁   3   男  湖北省
立涛   3   女  陕西省
凌青   4   女  湖北省
陆涛   4   男  山东省
媚媚   5   女  河南省
梦亿   4   男  江苏省
铭忠   5   男  四川省
慕梅   3   女  北京市
鹏吉   1   男  上海市
娉婷   4   女  河南省
淇峰   2   男  广东省
庆元   3   男  上海市
庆滋   4   男  北京市
丘东   5   男  江苏省
荣郑   1   男  黑龙江
蕊蕊   5   女  四川省
尚凯   2   男  北京市
诗涵   1   女  河南省
淑凤   2   女  天津市
淑娇   3   女  上海市
淑燕   4   女  河北省
淑怡   4   女  广东省
思璇   2   女  湖北省
苏华   3   女  山东省
苏梅   4   女  四川省
听荷   5   女  深圳市
文怡   1   女  天津市
文怡   2   女  河北省
香凝   3   女  山东省
翔云   4   女  河南省
小芸   5   女  深圳市
val inputRDD = sc.textFile("datas/analysis/stu.txt")
val putsRDD = inputRDD.map { line =>
  val Array(name, cls, sex, province) = line.trim.split("\\s+")
  val rowkey = new ImmutableBytesWritable(name.getBytes()) // 构建rowkey
  val put = new Put(rowkey.get()) // 构建put对象
  put.addColumn("message".getBytes, "name".getBytes, name.getBytes)
  put.addColumn("message".getBytes, "class".getBytes, cls.getBytes)
  put.addColumn("message".getBytes, "sex".getBytes, sex.getBytes)
  put.addColumn("message".getBytes, "province".getBytes, province.getBytes)
  (rowkey, put)
}

// 连接HBase表Zookeeper配置信息
val conf = HBaseConfiguration.create()
conf.set("hbase.zookeeper.quorum", "node1")
conf.set(TableOutputFormat.OUTPUT_TABLE, "student")

// 调用TableOutputFormat保存数据至HBase表
putsRDD.saveAsNewAPIHadoopFile(
  "datas/hbase/stu-1001",
  classOf[ImmutableBytesWritable],
  classOf[Put],
  classOf[TableOutputFormat[ImmutableBytesWritable]],
  conf
)

// 读取HBase Client 配置信息
val conf1: Configuration = HBaseConfiguration.create()
conf1.set("hbase.zookeeper.quorum", "node1")
conf1.set(TableInputFormat.INPUT_TABLE, "student")

sc.newAPIHadoopRDD(
  conf1,
  classOf[TableInputFormat],
  classOf[ImmutableBytesWritable],
  classOf[Result]
).foreach { case (_, result) =>
  // HBase表中的每条数据封装在result对象中,解析获取每列的值
  result.rawCells().foreach { cell =>
    println(s"RowKey = ${Bytes.toString(result.getRow)}")
    println(s"\t列族=> ${Bytes.toString(CellUtil.cloneFamily(cell))}" +
      s" 列名=> ${Bytes.toString(CellUtil.cloneQualifier(cell))}" +
      s" 列值=> ${Bytes.toString(CellUtil.cloneValue(cell))}")
  }
}
  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 好的,以下是spark-shell的基础操作: 1. 启动spark-shell:在终端中输入spark-shell即可启动。 2. 加载数据:使用SparkContext的textFile方法加载文本数据,如: val data = sc.textFile("path/to/data") 3. 转换数据:使用Spark的转换操作对数据进行处理,如: val words = data.flatMap(line => line.split(" ")) 4. 操作数据:使用Spark的操作操作对数据进行操作,如: val wordCounts = words.map(word => (word, 1)).reduceByKey(_ + _) 5. 输出数据:使用Spark的输出操作将结果保存到文件或打印到控制台,如: wordCounts.saveAsTextFile("path/to/output") 6. 关闭spark-shell:在终端中输入:quit或使用Ctrl+D即可关闭spark-shell。 希望对您有所帮助,如有需要请随时联系我。 ### 回答2: Spark-shell是基于Scala编写的交互式的Shell,可以在命令行中输入Scala代码,对Spark进行操作。Spark-shell有助于快速调试和学习Spark,因为它允许用户像使用Scala REPL一样来执行和实验Scala代码。在这里,我们将讨论一些Spark-shell的基础操作。 1.打开Spark-shell 在Linux系统中,打开终端,输入spark-shell,打开Spark-shell。然后,控制台上会显示如下内容: 使用 “:help” 可以获取帮助 和 “:quit” 退出 Spark Shell 2.查看Spark的版本 在Spark-shell中,输入:sc.version,可以查看Spark的版本信息。 3.从文件加载数据 在Spark-shell中读取文件,可以使用sc.textFile(path)函数,该函数将文件加载到RDD中。 4.过滤数据 在Spark-shell中对RDD进行过滤,可以使用filter函数。例如,如果要过滤掉所有不是数字的项,可以使用以下代码: ``` val numbers = sc.textFile("path/to/file").filter(_.matches("\\d+")) ``` 5.操作数据 在Spark-shell中操作数据,通常需要使用map函数。该函数可以将RDD中的每个元素进行转换。例如,将RDD中的每个元素转换为大写,可以使用以下代码: ``` val upperCase = sc.textFile("path/to/file").map(_.toUpperCase()) ``` 6.计算从文件中读取的数字的平均值 在Spark-shell中计算数字的平均值,可以使用以下代码: ``` val numbers = sc.textFile("path/to/file").filter(_.matches("\\d+")) val sum = numbers.map(_.toInt).reduce(_+_) val count = numbers.count() val avg = sum.toDouble / count ``` 7.保存数据 在Spark-shell中,可以使用saveAsTextFile(path)函数把RDD中的内容保存到文件中。例如,以下是一个将结果保存到文件的示例代码: ``` val numbers = sc.textFile("path/to/file").filter(_.matches("\\d+")) val sum = numbers.map(_.toInt).reduce(_+_) val count = numbers.count() val avg = sum.toDouble / count avg.saveAsTextFile("path/to/output") ``` 这是一些Spark-shell的基础操作。掌握这些基础知识之后,您就可以开始编写更复杂的代码了。Spark-shell还有许多其他功能,如使用各种算子操作RDD、调用Spark的API、使用线程和调试Spark Shell等,可以在学习Spark的过程中继续了解和掌握。 ### 回答3: Spark是目前最受欢迎的大数据处理框架之一,它提供了可靠、高效和灵活的数据处理方案。Spark-shell是Spark的一个交互式Shell,它使得开发人员能够以交互式的方式从控制台使用Spark。 1.启动Spark-shell 要使用Spark Shell,首先需要安装Spark,并将其配置为您的系统路径。默认情况下,它会安装在/usr/local/spark目录下。要启动Spark-shell,请输入以下命令: /usr/local/spark/bin/spark-shell 2.创建RDD 通过Spark-shell,可以从HDFS或本地文件系统加载数据,创建RDD并开始处理数据。以下是在Spark-shell中创建RDD的示例: val rdd = sc.parallelize(List(1, 2, 3, 4, 5)) 3.转换RDD Spark提供了各种各样的转换函数,用于转换和转换RDD。以下是一些常用的示例: // 将所有元素加倍 val rdd = sc.parallelize(List(1, 2, 3, 4, 5)) val doubledRdd = rdd.map(x => x * 2) // 过滤偶数 val rdd = sc.parallelize(List(1, 2, 3, 4, 5)) val filteredRdd = rdd.filter(x => x % 2 == 1) // 求和 val rdd = sc.parallelize(List(1, 2, 3, 4, 5)) val sum = rdd.reduce((a, b) => a + b) 4.操作RDD 除了转换,Spark还提供了一系列操作函数,可用于操作RDD。以下是一些常用的示例: // 返回RDD中的元素数 val rdd = sc.parallelize(List(1, 2, 3, 4, 5)) val count = rdd.count() // 返回RDD中的前N个元素 val rdd = sc.parallelize(List(1, 2, 3, 4, 5)) val firstThree = rdd.take(3) // 按键聚合 val rdd = sc.parallelize(List(("a", 1), ("a", 2), ("b", 1))) val groupBy = rdd.groupByKey() 5.关闭Spark-shell 最后,当您完成Spark-shell的使用时,需要关闭Spark-shell。请按Ctrl + D退出Spark-shell命令行。 这些是在Spark-shell中的基本操作,它们可以帮助您开始处理大规模数据。另外,Spark提供了强大的API和生态系统,可帮助您执行更复杂的任务,例如机器学习和图形计算。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值