1.什么spark?
Spark是一种基于内存的快速、通用、可扩展的大数据分析引擎。
-------------------------------------------------------------------------------------------------------
2.spark生态
spark core:spark 的核心计算
spark sql :对历史数据的交互式查询(即席查询)
spark Streaming:近实时计算(微批处理)
spark Graphx:图计算  不仅关注事物本身,而且关注事物之间的联系
spark mllib :机器学习  
-------------------------------------------------------------------------------------------------------
3.即席查询:用户根据需求自定查询
-------------------------------------------------------------------------------------------------------
4.spark 资源调度器? 自带的(standalone) yarn  mesos
-------------------------------------------------------------------------------------------------------
5.什么是结构化数据和 非结构化数据?
结构化数据——能够用数据或统一的结构加以表示,如数字、文字、符号。结构化数据也称作行数据,是由二维表结构来逻辑表达和实现的数据,严格地遵循数据格式与长度规范,主要通过关系型数据库进行存储和管理。
半结构化数据——是介于完全结构化数据(如关系型数据库、面向对象数据库中的数据)和完全无结构的数据(如声音、图像文件等)之间的数据,XML、HTML文档就属于半结构化数据。它一般是自描述的,数据的结构和内容混在一起,没有明显的区分。
非结构化数据——非结构化数据是数据结构不规则或不完整,没有预定义的数据模型,不方便用数据库二维逻辑表来表现的数据。包括图像和音频/视频信息等等。丢失的视频数据就属于非结构化数据。
-------------------------------------------------------------------------------------------------------
6.spark的特点?
1)快:与 Hadoop的 Mapreduce/相比, Spark基于内存的运算要快100倍以上,基于硬盘的运算也要快10上。Spak实现了高效的DAG执行引擎,可以通过基于内存来高效处理数据流。计算的中间结果是存在于内存中
2)易用:spaは支持ava、 Python和a的AP,还支持超过so种高级算法,使用户可以快速构建不同的应用。而且Spak支持交互式的 Python和 Scala的 Shell,,可以非常方便地在这些Shel中使用 Spark集群来验证解决问题的方法。
3)通用: Spark提供了统一的解决方案。 Spark可以用于批处理、交互式查询( Spark SQL)、实时流处理( Spark Streaming)、机器学习( Spark Mllib)和图计算( Graphx)。这些不同类型的处理都可以在同一个应用中无缝使用。减少了开发和维护的人力成本和部署平台的物力成本
4)兼容性: Spark可以非常方便地与其他的开源产品进行融合。比如, Spark可以使用 Hadoop的YARN和Apache Mesos作为它的资源管理和调度器,并且可以处理所有 Hadoop支持的数据,包括HDFS、 Hbase等。这对于已经部署 Hadoop集群的用户特别重要,因为不需要做任何数据迁移就可以使用Spak的强大处理能力。
-------------------------------------------------------------------------------------------------------
7.spark的重要角色? 分别有什么作用?
Spark Executor 是一个工作进程,负责在 Spark 作业中运行任务,任务间相互独立。
Spark 应用启动时,Executor 节点被同时启动,并且始终伴随着整个 Spark 应用的生命周期而存 在。
如果有 Executor 节点发生了故障或崩溃,Spark 应用也可以继续执行,会将出错节点上的任务调度到其他 Executor 节点上继续运行。
    主要负责:
    1)负责运行组成 Spark 应用的任务,并将结果返回给驱动器进程;
    2)通过自身的块管理器(Block Manager)为用户程序中要求缓存的 RDD 提供内存式 存储。RDD 是直接缓存在 Executor 进程内的,因此任务可以在运行时充分利用缓存数据加速运算。
    Spark 的驱动器是执行开发程序中的 main 方法的进程。它负责开发人员编写的用来创 建 SparkContext、创建 RDD,以及进行 RDD 的转化操作和行动操作代码的执行。
启动 Spark shell 的时候,系统后台自启了一个 Spark 驱动器程序, 就是在 Spark shell 中预加载的一个叫作 sc 的 SparkContext 对象。如果驱动器程序终止,那 么 Spark 应用也就结束了。
    主要负责:
    1)把用户程序转为作业(JOB)
    2)跟踪 Executor 的运行状况
    3)为执行器节点调度任务
    4)UI 展示应用运行状况
-------------------------------------------------------------------------------------------------------
8.spark的提交方式?
 client  cluster
-------------------------------------------------------------------------------------------------------
9.spark submit 的参数有哪些?

参数名    参数说明
--master     master 的地址,提交任务到哪里执行,例如 spark://host:port,  yarn,  local
--deploy-mode     在本地 (client) 启动 driver 或在 cluster 上启动,默认是 client
--class     应用程序的主类,仅针对 java 或 scala 应用
--name     应用程序的名称
--jars     用逗号分隔的本地 jar 包,设置后,这些 jar 将包含在 driver 和 executor 的 classpath 下
--packages     包含在driver 和executor 的 classpath 中的 jar 的 maven 坐标
--exclude-packages     为了避免冲突 而指定不包含的 package
--repositories     远程 repository
--conf PROP=VALUE    
 指定 spark 配置属性的值,
 例如 -conf spark.executor.extraJavaOptions="-XX:MaxPermSize=256m"
--properties-file     加载的配置文件,默认为 conf/spark-defaults.conf
--driver-memory     Driver内存,默认 1G
--driver-java-options     传给 driver 的额外的 Java 选项
--driver-library-path     传给 driver 的额外的库路径
--driver-class-path     传给 driver 的额外的类路径
--driver-cores     Driver 的核数,默认是1。在 yarn 或者 standalone 下使用
--executor-memory     每个 executor 的内存,默认是1G
--total-executor-cores     所有 executor 总共的核数。仅仅在 mesos 或者 standalone 下使用
--num-executors     启动的 executor 数量。默认为2。在 yarn 下使用
--executor-core     每个 executor 的核数。在yarn或者standalone下使用
-------------------------------------------------------------------------------------------------------
10.什么是Rdd?
弹性分布式数据集
这三个特性分别为:分区,不可变,并行操作。
RDD(Reslilent Distributed Dataset,弹性分布式数据集),是Spark中最基本的数据抽象。代码中是一个抽象类,它代表一个不可变、可分区、里面的元素可并行计算的集合

-------------------------------------------------------------------------------------------------------
11.RDD的属性?:
    1.一组分区(Partition),即数据集的基本单位
    2.一个计算每个分区的函数
    3.RDD之间的依赖关系
    4.一个Partition,即RDD的分片函数
    5.一个列表,存储存取每个partition的优先位置(preferred location)
-------------------------------------------------------------------------------------------------------
12.RDD的特点:RDD表示只读的分区的数据集,对RDD进行改动,只能通过RDD转换的操作,由一个
  RDD得到一个新的RDD,新的RDD包含了从其他RDD衍生所必需的信息,RDDs之间存在依赖,
  RDD的执行是按照血缘关系延时计算的,如果血缘关系较长,可以通过持久化RDD来切断血缘关系
-------------------------------------------------------------------------------------------------------
13.spark的容错?
  lineage(血缘)  checkpoint(设置检查点     )
Lineage:血缘关系,根据血缘关系重新计算进行容错。
    RDD 的 Lineage 会记录 RDD 的元数据信息和转换行为,当该 RDD 的部分分区数据丢失时,它可以根据这些信息来重新运算和恢复丢失的数据分区。
    checkpoint :将数据直接保存到持久化存储中,血缘关系越来越长,checkpoint设置检查点,持久化可切断血缘关系,防止节点挂掉,数据丢失

-------------------------------------------------------------------------------------------------------
14.spark的持久化 ?
 cache    persist   (是优化的一种重要手段)
RDD多次被复用的情况,可以提高效率,是Spark常用的一种优化方式
    cache和persist都是用于将一个RDD进行缓存的,这样在之后使用的过程中就不需要重新计算了,可以大大节省程序运行时间。
    cache
    persist
    区别:cache只有一个默认的缓存级别MEMORY_ONLY ,而persist可以根据情况设置其它的缓存级别。
-------------------------------------------------------------------------------------------------------
15.spark可以代替hadoop?  
不能,只能是mr的一种替代方案
    Spark只是分布式计算平台,而hadoop已经是分布式计算、存储、管理的生态系统。
    与Spark相对应的是Hadoop MapReduce。我认为Spark是可以取代MapReduce的,从而成为Hadoop系统中不可或缺的一部分。
    Spark更适合于迭代运算比较多的ML和DM运算。因为在Spark里面,有RDD的概念。RDD可以cache到内存中,那么每次对RDD数据集的操作之后的结果,都可以存放到内存中,下一个操作可以直接从内存中输入,省去了MapReduce大量的磁盘IO操作。但是,我们也要看到spark的限制:内存。我认为Hadoop虽然费时,但是在OLAP等大规模数据的应用场景,还是受欢迎的。目前Hadoop涵盖了从数据收集、到分布式存储,再到分布式计算的各个领域,在各领域都有自己独特优势。
    至于Spark相对于Hadoop的优势,我已经说了,分布式计算仅仅是hadoop的一部分。所以以下比较内容实际上是Spark和MapReduce的对比:
       (1) 更快
       (2) 更容易使用
    编程的时候没有蛋疼的map+reduce函数,而且配置起来超级方便。除支持JAVA外,支持scala、python、R。特别是scala,简直是太适合写数据分析的程序了,mapreduce用JAVA实在是太蛋疼了。而且RDD自带的函数超级好用,真心比mapreduce方便太多
       (3) 巨好用的库
    能解决90%问题的四大组件,无论是SQL、还是流数据处理、机器学习库、图计算,相当好用。当然,hadoop相关的库也不少,不过spark是原生包含,用起来方便点。
       (4) 运行方便
    Spark是可以脱离hadoop运行的,比如数据可以从数据库或者本地文件里面抽取。不过毕竟大数据时代,大家都习惯于将Spark和hadoop通过mesos或者yarn结合起来用;主要用Hadoop的HDFS,当然HBASE或者HIVE这种HDFS之上的组件,Spark也支持。

-------------------------------------------------------------------------------------------------------
16.spark算子?
RDD 的操作算子包括两类,一类叫做 transformations,它是用来将 RDD 进行转化,构 建 RDD 的血缘关系;
另一类叫做 actions,它是用来触发 RDD 的计算,得到 RDD 的相关计 算结果或者将 RDD 保存的文件系统中。
-------------------------------------------------------------------------------------------------------
17.算子的区别?
转换算子(transformations)只记录一系列的操作,只记录依赖关系,并没有真正的执行,
转换算子返回的一定是RDD,判断是否是转换算子,就看返回的是否是RDD
actions:当遇到action算子代码才开始真正执行
-------------------------------------------------------------------------------------------------------
18.spark RDD之间的依赖关系?
 宽依赖(Wide Dependencies)  :下游RDFD的每一个分区与上游RDD(也称为父RDD)的每个分区都有关,是多对多的关系
 窄依赖  (Narrow Dependencies):RDDs之间分区是一一对应的
宽依赖的算子:只要发生shuffle都是宽依赖算子
-------------------------------------------------------------------------------------------------------
19.collect : 将excutor 计算的数据 以数组的形式 发送到driver
    spark collect 算子的作用:
    收集一个弹性分布式数据集的所有元素到一个数组中,从远程集群拉取数据到driver端。
-------------------------------------------------------------------------------------------------------
20.RDD的创建方式?
① 从集合中创建
    使用 parallelize( ) 从集合创建:`val rdd = sc.parallelize(Array(1,2,3,5,3,4))`,
    使用 makeRDD( ) 从集合创建:`val rdd1 = sc.makeRDD(Array(1,2,3,5,3,4))`
    ② 从外部存储系统的数据集创建RDD:`val rdd2=sc.textFile("hdfs://jh/RELEASE")`
    包括本地的文件系统,还有所有 Hadoop 支持的数据集,比如:HDFS、Cassandra、HBase等
    ③ 从其他 RDD 创建
    根据原RDD创建新的RDD
-------------------------------------------------------------------------------------------------------
21.Rdd的分区个数 由什么决定?  默认  指定  从hdfs获取数据由切片的个数  从kafka获取由topic的partition个数决定
-------------------------------------------------------------------------------------------------------
22.总结spark算子?  40个左右
-------------------------------------------------------------------------------------------------------
23.map 和 mapPartiton 有什么区别?
-------------------------------------------------------------------------------------------------------
24.oom: out of memory 内存溢出
-------------------------------------------------------------------------------------------------------
25.RDD 的转换(面试开发重点)
 RDD 整体上分为 Value 类型和 Key-Value 类型
-------------------------------------------------------------------------------------------------------
26.spark可以代替hadoop吗?
可以代替mapreudce,不能代替hadoop
-------------------------------------------------------------------------------------------------------
27.总结spark算子?  40个左右
1)Value数据类型的Transformation算子  
  一、输入分区与输出分区一对一型
    1、map算子:返回一个新的 RDD,该 RDD 由每一个输入元素经过 func 函数转换后组成
    2、flatMap算子:类似于 map,但是每一个输入元素可以被映射为 0 或多个输出元素(所以 func 应 该返回一个序列,而不是单一元素)
    3、mapPartitions算子:类似于 map,但独立地在 RDD 的每一个分片上运行,
            因此在类型为 T 的 RDD 上 运行时,
            func 的函数类型必须是 Iterator[T] => Iterator[U]。
            假设有 N 个元素,有 M 个分区, 那么 map 的函数的将被调用 N 次,而 mapPartitions 被调用 M 次,
            一个函数一次处理所有分区。 2. 需求:创建一个 RDD,使每个元素*2 组成新的 RDD
             4.repartition算子:根据分区数,重新通过网络随机洗牌所有数据
    5、glom算子:将每一个分区形成一个数组,形成新的 RDD 类型时 RDD[Array[T]]
             5.mapPartitionsWithIndex(func)算子:类似于 mapPartitions,但 func 带有一个整数参数表示分片的索引值,因此在类型 为 T 的 RDD 上运行时,
            func 的函数类型必须是(Int, Interator[T]) => Iterator[U]
  二、输入分区与输出分区多对一型 
    6、union算子:对源 RDD 和参数 RDD 求并集后返回一个新的 RDD
    7、cartesian算子:笛卡尔积(尽量避免使用)
             8、coalesce算子:缩减分区数,用于大数据集过滤后,提高小数据集的执行效率
  三、输入分区与输出分区多对多型
    9、grouBy算子:分组,按照传入函数的返回值进行分组。将相同的 key 对应的值放入一个迭代器。
  四、输出分区为输入分区子集型
    8、filter算子:过滤。返回一个新的 RDD,该 RDD 由经过 func 函数计算后返回值为 true 的输入 元素组成
    9、distinct算子:对源 RDD 进行去重后返回一个新的 RDD。默认情况下,只有 8 个并行任务来操 作,但是可以传入一个可选的 numTasks 参数改变它
    10、subtract算子:计算差的一种函数,去除两个 RDD 中相同的元素,不同的 RDD 将保留下来
    11、sample算子:以指定的随机种子随机抽样出数量为 fraction 的数据,withReplacement 表示是抽 出的数据是否放回,
            true 为有放回的抽样,false 为无放回的抽样,seed 用于指定随机数生成 器种子
        12、takeSample算子
   五、Cache型
    13、cache算子  
    14、persist算子
2)Key-Value数据类型的Transfromation算子
  一、输入分区与输出分区一对一
    15、mapValues算子
              16.  pipe算子:管道,针对每个分区,都执行一个 shell 脚本,返回输出的 RDD。 注意:脚本需要放在 Worker 节点可以访问到的位置
  二、对单个RDD或两个RDD聚集
   单个RDD聚集
            13.foldByKey算子:(zeroValue: V)(func: (V, V) => V): RDD[(K, V)] 1. 作用:aggregateByKey 的简化操作,seqop 和 combop 相同
            14.aggregateByKey算子:参数:(zeroValue:U,[partitioner: Partitioner]) (seqOp: (U, V) => U,combOp: (U, U) => U) 1. 作用:在 kv 对的 RDD 中,,按 key 将 value 进行分组合并,合并时,
将每个 value 和初 始值作为 seq 函数的参数,进行计算,返回的结果作为一个新的 kv 对,然后再将结果按照 key 进行合并,
最后将每个分组的 value 传递给 combine 函数进行计算(先将前两个 value 进行计算,将返回结果和下一个 value 传给 combine 函数,以此类推),
将 key 与计算结果作 为一个新的 kv 对输出。
 2. 参数描述: (1)zeroValue:给每一个分区中的每一个 key 一个初始值;
(2)seqOp:函数用于在每一个分区中用初始值逐步迭代 value;
(3)combOp:函数用于合并每个分区中的结果。
             15.groupByKey算子:groupByKey 也是对每个 key 进行操作,但只生成一个 sequence。
    16、combineByKey算子
    17、reduceByKey算子:在一个(K,V)的 RDD 上调用,返回一个(K,V)的 RDD,使用指定的 reduce 函数,将相同 key 的值聚合到一起,reduce 任务的个数可以通过第二个可选的参数来设置。
    18、partitionBy算子:对 pairRDD 进行分区操作,如果原有的 partionRDD 和现有的 partionRDD 是一致 的话就不进行分区, 否则会生成 ShuffleRDD,即会产生 shuffle 过程。
              19.   sortBy算子:使用 func 先对数据进行处理,按照处理后的数据比较结果排序,默认为正序。
   两个RDD聚集
    19、Cogroup算子
  三、连接
    20、join算子
    21、leftOutJoin和 rightOutJoin算子
 3)Action算子
  一、无输出
    22、foreach算子
  二、HDFS
    23、saveAsTextFile算子
    24、saveAsObjectFile算子
  三、Scala集合和数据类型
    25、collect算子
    26、collectAsMap算子
      27、reduceByKeyLocally算子
      28、lookup算子
    29、count算子
    30、top算子
    31、reduce算子
    32、fold算子
    33、aggregate算子
             34.  intersection算子:对源 RDD 和参数 RDD 求交集后返回一个新的 RDD
             35.zip算子:将两个 RDD 组合成 Key/Value 形式的 RDD,这里默认两个 RDD 的 partition 数量以 及元素数量都相同,否则会抛出异常。
-------------------------------------------------------------------------------------------------------
28.map 和 mapPartiton 有什么区别?
map是一条数据计算一次,mapPartiton是把数据进行分区,分为默认分区和指定分区,一次处理一组分区的数据,
 在计算大量数据时,mapPartition比map更快
-------------------------------------------------------------------------------------------------------
29.oom: out of memory 内存溢出
-------------------------------------------------------------------------------------------------------
30.从分区的算子?区别?
  coalesce 重新分区,可以选择是否进行 Shuffle 过程。由参数 shuffle:Boolean=false/true 决定。
  repartition 实际上是调用的 coalesce,默认是进行 shuffle 的。

-------------------------------------------------------------------------------------------------------
31.reduceByKey和groupByKey的区别
 reduceByKey:按照 key 进行聚合,在 Shuffle 之前有 combine(预聚合)操作,返回结果是 RDD[k,v]。
 groupByKey:按照 key 进行分组,直接进行 shuffle。
-------------------------------------------------------------------------------------------------------
32.宽依赖的算子? 1.所有bykey的算子  2.repartition、笛卡尔积   3.部分join
-------------------------------------------------------------------------------------------------------
33.什么是DAG?  如何划分Stage?
DAG(Directed Acyclic Graph)叫做有向无环图,原始的 RDD 通过一系列的转换就就形成了 DAG,根据RDD之间的依赖关系的不同将 DAG 划分成不同的 Stage,对于窄依赖,partition 的转换处理在 Stage 中完成计算。对于宽依赖,由于有 Shuffle 的存在,只能在 parent RDD 处理完成后,才能开始接下来的计算,因此宽依赖是划分 Stage 的依据。
    当遇到一个 Shuffle类的算子,就会划分一个stage
-------------------------------------------------------------------------------------------------------
34.job如何划分?
> 1)Application:初始化一个SparkContext即生成一个Application;
>
> 2)Job:一个Action算子就会生成一个Job;
>
> 3)Stage:根据RDD之间的依赖关系的不同将Job划分成不同的Stage,遇到一个宽依赖则划分一个Stage;
>
> ==对于宽依赖,由于有Shuffle的存在,只能在parent RDD处理完成后,才能开始接下来的计算,因此宽依赖是划分Stage的依据.==
>
> 4)Task:Stage是一个TaskSet,将Stage划分的结果发送到不同的Executor执行即为一个Task。
>
> 注意:Application->Job->Stage-> Task 每一层都是 1 对 n 的关系。
-------------------------------------------------------------------------------------------------------
35.持久化的级别?
    级别:
| StorageLevel                      | 说明                                                         |
| ----------------------------  | ----------------------------------------------------------- |
| NONE                                |  没有一个                                                     |
| MEMORY_ONLY                |  使用未序列化的Java对象格式,将数据保存在内存中。如果内存不够存放所有的数据,则数据可能就不会进            行持久化,默认的持久化策略 |
| MEMORY_AND_DISK         |  使用未序列化的Java对象格式,优先尝试将数据保存在内存中。如果内存不够存放所有的数据,会将数据写            入磁盘文件中。不会立刻输出到磁盘 |
| MEMORY_ONLY_SER         |  RDD的每个partition会被序列化成一个字节数组,节省空间,读取时间更占CPU |
| MEMORY_AND_DISK_SER  |  序列化存储,超出部分写入磁盘文件中                           |
| DISK_ONLY                        |  使用未序列化的Java对象格式,将数据全部写入磁盘文件中         |
| MEMORY_ONLY_2             |  对于上述任意一种持久化策略,如果加上后缀_2,代表的是将每个持久化的数据,都复制一份副本,并将副            本保存到其他节点上 |
| OFF_HEAP                         |  RDD序列化存储在Tachyon  优点:减少频繁的GC,减少内存的使用,提高程序性能。 缺点:没有数据备份            ,也不能像alluxio那样保证数据高可用,丢失数据则需要重新计算。 |

        级别的选择:
    -1.优先使用内存
    -2.如果内存放不下 进行序列化
    -3.不到万不得已不建议使用磁盘
---------------------------------------------------------------------------------------------------------
36.spark的分区器?
(1)只有 Key-Value 类型的 RDD 才有分区器的,非 Key-Value 类型的 RDD 分区器的值是 None
(2)每个 RDD 的分区 ID 范围:0~numPartitions-1,决定这个值是属于那个分区的。

---------------------------------------------------------------------------------------------------------
37.master 资源调度算法?    
    local模式
    standalone
    on-yarn : yarn-cluster  yarn-client
    mesos  (粗细粒度)
---------------------------------------------------------------------------------------------------------
38.client 和 cluster 提交方式的区别? driver 在哪里运行?
spark的提交方式总体来说有两种,分别是standalone模式和yarn模式。
    这两种模式又分别有两种提交方式,分别是:
        (一)standalone下的client提交方式。(客户端提交)
        (二)standalone下的cluster提交方式。(集群提交)
        (三)yarn下的client提交方式。(客户端提交)
        (四)yarn下的cluster提交方式。(集群提交)
        (一)Standalone-client适合测试使用,不适合生产使用。
    Driver进程是在客户端启动的,这里的客户端是指提交任务的那个节点。Driver端可以看到Task执行的情况。
    Standalone-client为什么不适合生产环境呢?是因为假如要提交100个Application到集群运行,Driver每次都会在client端启动,会导致客户端100次网卡流量暴增的问题。
        (二)Standalone-cluster模式提交任务:
    执行流程:
    1、cluster模式下提交应用程序后,会向Master申请启动Driver。
    2、Master接受请求后,随机在一台Worker启动Driver。
    3、Driver启动后,向Master申请资源。
    4、资源申请成功后,Driver将Task发送到Worker执行。
    5、Worker将执行情况和执行结果返回给Driver端。
    Driver进程是在集群中某一台Worker上执行的,客户端无法查看Task执行情况。假如要提交100个应用程序到集群上,每次Driver会随机在集群中某台Worker上执行。

      ——   总结Standalone两种方式提交任务,Driver与集群通信包括:
    1、申请资源。2、分发任务。3、回收结果。4、监控Task执行情况。

        (三)Yarn-clien方式提交任务:
    与Standalone-client类似,Yarn-client同样适用于测试环境,因为Driver运行在本地,大量提交Application会导致网卡流量激增问题。
      ——   client模式下ApplicationMaster的作用(注意,client模式的AM和cluster的AM作用不同):
    1、为Application申请资源。2、给NM发送消息启动Executor。
    注意:这里的AM只用申请资源的功能,没用任务调度的功能。

        (四)Yarn-cluster任务提交方式:
    cluster方式提交任务后,Driver(AM)是分布到集群各个节点的,不会造成网卡流量激增的问题。缺点是任务提交后无法查看日志,只能通过Yarn查看日志。
       ——  ApplicationMaster作用:
    1、申请资源。2、给NM发消息启动Executor。3、任务调度。
---------------------------------------------------------------------------------------------------------
39.总结spark的提交流程?
1、Driver端会调用SparkSubmit类(内部执行submit->doRunMain->通过反射获取应用程序的主类对象->执行主类的main方法)
    2、构建sparkConf和sparkContext对象,在sparkContext入口做了三件事,创建了sparkEnv对象(创建了ActorSystem对象)TaskScheduler(用来生成并发送task给Executor)DAGScheduler(用来划分Stage)
    3、clientActor将任务封装到ApplicationDescription对象并且提交给Master
    4、Master收到任务信息后,将任务信息存到内存中,同时放到队列中(waitingApp)
    5、任务信息开始执行后,调用schedule方法,进行资源的调度。
    6、将调度好的资源封装到LaunchExecutor(发起执行)并发送给对应的worker。
    7、worker接收到master发送来的任务调度信息(LaunchExecutor),将信息封装成一个ExecutorRunner对象。
    8、封装成ExecutorRunner后,调用ExecutorRunner的·start方法,开始启动GoarseGrainedExecutorBackend对象
    9、Executor启动后DriverActor进行反向注册。
    10、与DriverActor注册成功后,创建一个线程池(TreadPool)用来执行任务
    11、当所有的Executor注册完成后,意味着作业环境准备好了,Driver端会结束与sparkContext对象的初始化。
    12、当Driver初始化完成后(创建一个sc实例)会继续执行我们自己提交的App代码,当触发了action算子时就会触发一个job,这时就会调用DAGScheduler对象进行Stage划分。
    13、DagScheduler开始进行stage划分。
    14、将划分好的stage按照分区生成一个一个的task,并且封装到TaskSet对象中,然后TaskSet提交到TaskScheduler
    15、TaskScheduler按照提交过来的TaskSet,拿到一个序列化器,将TaskSet序列化,将序列化好的Task封装到LaunchExecutor并且提交到DriverActor。
    16、DriverActor把LauchExcutor发送到Excutro上。
    17、Executor接收到DriverActor发送过来的任务(LaunchExecutro),会将其封装成为TaskRunner,然后从线程池中获取线程来执行TaskRunner。
    18、TaskRunner拿到反序列化器,反序列Taskset,然后执行App代码,也就是对RDD分区上执行的算子和自定义函数。
        ClientActor:负责和Master通信,向Master注册任务信息
        DriverActor:负责和Executor进行通信,接收到 Executor反向注册和把任务发送到Executer。
---------------------------------------------------------------------------------------------------------
40.常用的宽依赖算子和窄依赖算子有哪些?

    宽依赖算子:宽依赖都会发生shuffer

    ① 所有byKey算子:

        partitionBy、groupByKey、reduceByKey、aggregateByKey、foldByKey、combineByKey、

        sortByKey

    ② repartition、cartesian算子

    ③ 部分 join 算子

    窄依赖算子:

    map、flatMap、filter
---------------------------------------------------------------------------------------------------------
41.什么是SparkStreaming?
spark-streaming用于流式数据的处理(流式计算)
计算的是实时传输过来的数据,五秒作为一批计算,不管五秒内传输多少数据,即使没有数据也会计算一次(批处理)
---------------------------------------------------------------------------------------------------------
42.SparkStreaming的核心抽象?
DStream
---------------------------------------------------------------------------------------------------------
43.sparksteaming和storm对比:sparksteaming是积攒五秒计算一次,近实时的微批处理,吞吐量,(一直在处理),容错性好,形成生态,可以做数据无缝整合
            storm是来一条处理一条,实时性高(容错只能靠checkpoint),事务性没有sparksteaming好,单一组件,只能做实时计算
---------------------------------------------------------------------------------------------------------
44.sparkStreaming 的receiver

50.sparkStreaming 消费kafka数据的方式?
2.0以前 有两种方式 receiver(高阶API,由zk管理offset)、direct(低阶API,由spark自己管理偏移量)
    2.0以后 只有direct
---------------------------------------------------------------------------------------------------------
51.基于drict方式  如果来管理偏移量?
  1.zk  2.ck
---------------------------------------------------------------------------------------------------------
53.基于receive方式 如果保证数据不丢失?
 设置WAL  
---------------------------------------------------------------------------------------------------------
54.sparkStream 独有的算子? 有什么特点?
50.1.window()
两个重载方法,第一个只传窗口长度(滑动间隔默认为实例化ssc时的时间间隔),第二个传窗口长度与滑动间隔
50.2.reduceByWindow()
需要传3个参数,依次为reduce()方法,窗口长度,滑动长度。
50.3.countByWindow()
需要两个参数,依次为:窗口长度,滑动间隔
50.4.countByValueAndWindow()
需要三个参数,依次为:窗口长度,滑动间隔,分区数(有默认值,可不传)
50.5.reduceByKeyAndWindow()
参数为:聚合函数,窗口长度
该方法主要过程为:调reduceByKey()函数

50.6.updatestateByKey()
传入一个更新方法,该方法两个参数:一个为当前时间间隔内数据,
类型为Seq,一个为之前的数据,可能无数据(第一次提交计算的时候),
类型为Option,返回值也为Option类型
---------------------------------------------------------------------------------------------------------
55.什么是sparkSql
Spark SQL 是 Spark 用来处理结构化数据的一个模块,
它提供了 2 个编程抽象:DataFrame 和 DataSet,并且作为分布式 SQL 查询引擎的作用。
---------------------------------------------------------------------------------------------------------
56.hive 和 spark的关系?
 hive on spark 借助spark作为底层计算框架 ,    spark on hive :hive 作为数据源 spark 计算
---------------------------------------------------------------------------------------------------------
57.spark sql 的核心抽象?
DataFrame
DataSet
---------------------------------------------------------------------------------------------------------
58.什么是DataFrame?
DataFrame分布式的数据容器,与RDD类似,
DataFrame类似于数据库的二维表(包含行和列)
DataFrame也是懒执行,调用的时候才执行
---------------------------------------------------------------------------------------------------------
59.Rdd和DataFrame的区别?
DataFrame不仅记录数据本身,还记录数据类型,带有元数据的结构信息(schema),比RDD性能高
RDD(弹性式分布式数据集)只记录数据本身
---------------------------------------------------------------------------------------------------------
60.什么是DataSet?
Dataset也是一个分布式数据容器,简单来说是类似二维表,Dataset里头存有schema数据结构信息和原生数据,Dataset的底层封装的是RDD,当RDD的泛型是Row类型的时候,我们也可以称它为DataFrame。即Dataset<Row> = DataFrame。DataFrame是特殊的Dataset。
DataSet是DataFrame API的一个扩展,是spark最新的数据抽象
---------------------------------------------------------------------------------------------------------
61.创建DF的几种方式?
通过Seq生成
读取Json文件生成
读取csv文件生成
通过Json格式的RDD生成(弃用)
通过Json格式的DataSet生成
通过csv格式的DataSet生成
动态创建schema
通过jdbc创建
---------------------------------------------------------------------------------------------------------
63.Rdd转换成DF的方式?
如果需要 RDD 与 DF 或者 DS 之间操作,那么都需要引入 import spark.implicits._ 【spark 不是包名,而是 sparkSession 对象的名称】
导入隐式转换并创建一个 RDD
通过手动确定转换
通过反射确定(需要用到样例类)
根据样例类将 RDD 转换为 DataFrame
通过编程的方式(了解)
DataFrame和DataSet的
---------------------------------------------------------------------------------------------------------
64.DataFrame和DataSet的区别?
DataFrame也可以叫Dataset[Row],每一行的类型是Row,不解析,每一行究竟有哪些字段,各个字段又是什么类型都无从得知,只能用上面提到的getAS方法或者共性中的拿出特定字段
而Dataset中,每一行是什么类型是不一定的,在自定义了case class之后可以很自由的获得每一行的信息
DataFrame 是dataSet中的一个特例

---------------------------------------------------------------------------------------------------------
65.hive的自定义函数?  如何经行使用的、
UDF分为三种,分别如下
1、UDF(User-Defined-Function),一进一出(输入一行,输出一行),比如:upper()、lowser()等。
2、UDAF(User-Defined Aggregation Funcation),多进一出(输入多行,输出一行),比如:avg()、sum()等。
3、UDTF(User-Defined Table-Generating Functions),一进多出(输入一行,输出多行),比如:collect_set()、collect_list()等。

---------------------------------------------------------------------------------------------------------
66.sparksql 数据源?
hive数据源
jdbc数据源
json文件
parquet文件

---------------------------------------------------------------------------------------------------------
67.sparksql 保存数据的几种模式?
     *Append(如果有数据就追加)
     * Overwrite(有没有数据都覆盖)
     * ErrorIfEXists(有数据就报错)
     * Ignore(数据存在则忽略)
---------------------------------------------------------------------------------------------------------
67.sparksql 保存数据的几种模式?
error  (default)  报错  默认
append 追加
overwrite 覆写
ignore 数据存在 忽略