注:数据研发侧重组件框架原理和编程实践经验,在面试中也会问到数据结构与算法、机器学习算法等。以下试题为作者日常整理的通用高频面经,包含题目,答案与参考文章,欢迎纠正与补充。

其他相应高频面试题可参考如下内容:

2020 BAT大厂数据分析面试经验:“高频面经”之数据分析篇

2020 BAT大厂数据挖掘面试经验:“高频面经”之数据结构与算法篇

2020 BAT大厂机器学习算法面试经验:“高频面经”之机器学习篇

2020 BAT大厂深度学习算法面试经验:“高频面经”之深度学习篇

目录

1.linux常用命令

2.Java虚拟机、垃圾回收机制

3.TCP “三次握手”、 “四次挥手

4.大数据常见组件

5.HDFS存储机制

6.MapReduce基本流程

7.Hadoop Shffule原理

8.Hadoop常用命令

9.Hadoop优化

10.Hadoop分片、分区

11.Hive常用高阶命令

12.Redis特性

13.Redis、传统数据库、HBase、Hive区别

14.Kafka、Flume对比

15.Spark执行流程

16.Spark RDD是什么?

17.Spark stage划分原理

18.Spark与Hadoop区别与联系

19.Flink API和流/批处理引擎

20.Storm Spark-streaming Flink对比


 

1.linux常用命令

    通过参考linuxTOY.org网站并制作出思维导图:

 

2.Java虚拟机、垃圾回收机制

    Java虚拟机即JVM(Java Virtual Machine),通过软件来模拟出来的具有完整的硬件系统功能、运行在完全隔离的环境中的完整的计算机系统。JVM 内存共分为虚拟机栈、堆、方法区、程序计数器、本地方法栈五个部分:

    程序计数器:内存空间小,线程私有。字节码解释器工作是就是通过改变这个计数器的值来选取下一条需要执行指令的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖计数器完成

    Java 虚拟机栈:线程私有,生命周期和线程一致。描述的是 Java 方法执行的内存模型:每个方法在执行时都会床创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至执行结束,就对应着一个栈帧从虚拟机栈中入栈到出栈的过程。

    本地方法栈:区别于 Java 虚拟机栈的是,Java 虚拟机栈为虚拟机执行 Java 方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的 Native 方法服务。也会有 StackOverflowError 和 OutOfMemoryError 异常。

    Java 堆:对于绝大多数应用来说,这块区域是 JVM 所管理的内存中最大的一块。线程共享,主要是存放对象实例和数组。内部会划分出多个线程私有的分配缓冲区(Thread Local Allocation Buffer, TLAB)。可以位于物理上不连续的空间,但是逻辑上要连续

    方法区:属于共享内存区域,存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

    参考链接:

    https://blog.csdn.net/qq_41701956/article/details/81664921

    Java内存回收机制:区别于C语言,C的垃圾回收是人工的,工作量大,但是可控性高。

                

    而Java是自动化的,但是可控性很差,甚至有时会出现内存溢出的情况,内存溢出也就是jvm分配的内存中对象过多,超出了最大可分配内存的大小。

                    

    以上两张图可以形象理解一下。

    参考链接:                                

    https://blog.csdn.net/weixin_39067991/article/details/81045201

 

3.TCP “三次握手”、 “四次挥手

    三次握手:

    • 第一次握手:客户端发送初始序号x和syn=1请求标志

    • 第二次握手:服务器发送请求标志syn,发送确认标志ACK,发送自己的序号seq=y,发送客户端的确认序号ack=x+1

    • 第三次握手:客户端发送ACK确认号,发送自己的序号seq=x+1,发送对方的确认号ack=y+1

 

    四次挥手:

    • 第一次挥手:客户端发出释放FIN=1,自己序列号seq=u,进入FIN-WAIT-1状态

    • 第二次挥手:服务器收到客户端的后,发出ACK=1确认标志和客户端的确认号ack=u+1,自己的序列号seq=v,进入CLOSE-WAIT状态

    • 第三次挥手:客户端收到服务器确认结果后,进入FIN-WAIT-2状态。此时服务器发送释放FIN=1信号,确认标志ACK=1,确认序号ack=u+1,自己序号seq=w,服务器进入LAST-ACK(最后确认态)

    • 第四次挥手:客户端收到回复后,发送确认ACK=1,ack=w+1,自己的seq=u+1,客户端进入TIME-WAIT(时间等待)。客户端经过2个最长报文段寿命后,客户端CLOSE;服务器收到确认后,立刻进入CLOSE状态。

    参考链接:

    https://www.cnblogs.com/jainszhang/p/10641728.html

 

4.大数据常见组件

    Hadoop是一个由Apache基金会所开发的分布式系统基础架构。Hadoop的核心是YARN,HDFS和MapReduce。Hdfs是分布式文件存储系统,用于存储海量数据;MapReduce是并行处理框架,实现任务分解和调度。Hadoop可以用来搭建大型数据仓库,对海量数据进行存储、分析、处理和统计等业务,功能十分强大。Hadoop具有成熟的生态系统,包括众多的开源工具,如下图:

    HDFS:HDFS是Hadoop的核心组件,HDFS上的文件被分成块进行存储,默认块的大小是64M,块是文件存储处理的逻辑单元。HDFS是Master和Slave的结构。分NameNode(Master节点)、SecondaryNameNode(NameNode冷备份H)、DataNode(slave节点)这几个角色。

    MapReduce:MapReduce的工作原理用一句话概括就是,分而治之,然后归约,即将一个大任务分解为多个小任务(map),并行执行后,合并结果(reduce)。整个MapReduce的过程大致分为Map-->Shuffle(排序)-->Combine(组合)-->Reduce。

    YARN:YARN是Hadoop 2.0中的资源管理系统,它的基本设计思想是将MRv1中的JobTracker拆分成了两个独立的服务:一个全局的资源管理器ResourceManager和每个应用程序特有的ApplicationMaster。其中ResourceManager负责整个系统的资源管理和分配,而ApplicationMaster负责单个应用程序的管理。

    Hive:Hive是构建在Hadoop HDFS上的一个数据仓库,可以将结构化的数据文件映射为一张数据库表,并提供类SQL查询功能,其本质是将SQL转换为MapReduce程序。数据仓库是一个面向主题的、集成的、不可更新的、随时间变化的数据集合,它用于支持企业或组织的决策分析处理。Hive的表其实就是HDFS的目录/文件。

    Pig:Pig是yahoo捐献给apache的一个项目,使用SQL-like语言,是在MapReduce上构建的一种高级查询语言,把一些运算编译进MapReduce模型的Map和Reduce中。

    Zookeeper:ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

    Hbase:HBase – Hadoop Database,是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统,利用HBase技术可在廉价PC Server上搭建起大规模结构化存储集群。HBase是Google Bigtable的开源实现,类似Google Bigtable利用GFS作为其文件存储系统,HBase利用Hadoop HDFS作为其文件存储系统;Google运行MapReduce来处理Bigtable中的海量数据,HBase同样利用Hadoop MapReduce来处理HBase中的海量数据;Google Bigtable利用 Chubby作为协同服务,HBase利用Zookeeper作为对应。

    Sqoop:Hadoop正成为企业用于大数据分析的最热门选择,但想将你的数据移植过去并不容易。Apache Sqoop正在加紧帮助客户将重要数据从数据库移到Hadoop。随着Hadoop和关系型数据库之间的数据移动渐渐变成一个标准的流程,云管理员们能够利用Sqoop的并行批量数据加载能力来简化这一流程,降低编写自定义数据加载脚本的需求。

    Flume:Flume 作为cloudera 开发的实时日志收集系统,受到了业界的认可与广泛应用。Flume 初始的发行版本目前被统称为Flume OG(original generation),属于 cloudera。重构后的版本统称为 Flume NG(next generation),属于Apache。

    Kafka :是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模网站中的所有动作流数据,目前已成为大数据系统在异步和分布式消息之间的最佳选择。

     Spark:Spark 是一个高速、通用大数据计算处理引擎。拥有Hadoop MapReduce所具有的优点,但不同的是Job的中间输出结果可以保存在内存中,从而不再需要读写HDFS,因此Spark能更好地适用于数据挖掘与机器学习等需要迭代的MapReduce的算法。它可以与Hadoop和Apache Mesos一起使用,也可以独立使用

    Flink:Flink 于今年跻身Apache顶级开源项目,与HDFS完全兼容。Flink提供了基于Java和Scala的API,是一个高效、分布式的通用大数据分析引擎。更主要的是,Flink支持增量迭代计算,使得系统可以快速地处理数据密集型、迭代的任务。 

    Storm:Storm是Twitter开源的一个类似于Hadoop的实时数据处理框架。编程模型简单,显著地降低了实时处理的难度,也是当下最人气的流计算框架之一。与其他计算框架相比,Storm最大的优点是毫秒级低延时。

    参考链接:

    https://blog.csdn.net/lcm_linux/article/details/103206076?utm_source=distribute.pc_relevant.none-task

 

5.HDFS存储机制

    HDFS存储机制,包括HDFS的写入过程读取过程两个部分:
    写入过程:

  • 客户端向namenode请求上传文件,namenode检查目标文件是否已存在,父目录是否存在。

  • namenode返回是否可以上传。

  • 客户端请求第一个 block上传到哪几个datanode服务器上。

  • namenode返回3个datanode节点,分别为dn1、dn2、dn3。

  • 客户端请求dn1上传数据,dn1收到请求会继续调用dn2,然后dn2调用dn3,将这个通信管道建立完成

  • dn1、dn2、dn3逐级应答客户端

  • 客户端开始往dn1上传第一个block(先从磁盘读取数据放到一个本地内存缓存),以packet为单位,dn1收到一个packet就会传给dn2,dn2传给dn3;dn1每传一个packet会放入一个应答队列等待应答

  • 当一个block传输完成之后,客户端再次请求namenode上传第二个block的服务器。(重复执行3-7步)

    读取过程:

  • 客户端向namenode请求下载文件,namenode通过查询元数据,找到文件块所在的datanode地址。

  • 挑选一台datanode(就近原则,然后随机)服务器,请求读取数据。

  • datanode开始传输数据给客户端(从磁盘里面读取数据放入流,以packet为单位来做校验)。

  • 客户端以packet为单位接收,先在本地缓存,然后写入目标文件。

    参考链接:
    https://blog.csdn.net/xiaohao95/article/details/89561088

 

6.MapReduce基本流程

    在MapReduce整个过程可以概括为以下过程:输入 --> map --> shuffle --> reduce -->输出。输入文件会被切分成多个块,每一块都有一个map task。map阶段的输出结果会先写到内存缓冲区,然后由缓冲区写到磁盘上。默认的缓冲区大小是100M,溢出的百分比是0.8,也就是说当缓冲区中达到80M的时候就会往磁盘上写。如果map计算完成后的中间结果没有达到80M,最终也是要写到磁盘上的,因为它最终还是要形成文件。那么,在往磁盘上写的时候会进行分区和排序。一个map的输出可能有多个这个的文件,这些文件最终会合并成一个,这就是这个map的输出文件。

    流程说明如下:

  • (1)输入文件分片,每一片都由一个MapTask来处理

  • (2)Map输出的中间结果会先放在内存缓冲区中,这个缓冲区的大小默认是100M,当缓冲区中的内容达到80%时(80M)会将缓冲区的内容写到磁盘上。也就是说,一个map会输出一个或者多个这样的文件,如果一个map输出的全部内容没有超过限制,那么最终也会发生这个写磁盘的操作,只不过是写几次的问题。

  • (3)从缓冲区写到磁盘的时候,会进行分区并排序,分区指的是某个key应该进入到哪个分区,同一分区中的key会进行排序,如果定义了Combiner的话,也会进行combine操作

  • (4)如果一个map产生的中间结果存放到多个文件,那么这些文件最终会合并成一个文件,这个合并过程不会改变分区数量,只会减少文件数量。例如,假设分了3个区,4个文件,那么最终会合并成1个文件,3个区

  • (5)以上只是一个map的输出,接下来进入reduce阶段

  • (6)每个reducer对应一个ReduceTask,在真正开始reduce之前,先要从分区中抓取数据

  • (7)相同的分区的数据会进入同一个reduce。这一步中会从所有map输出中抓取某一分区的数据,在抓取的过程中伴随着排序、合并。

  • (8)reduce输出

     参考链接:

    https://www.cnblogs.com/cjsblog/p/8168642.html

 

7.Hadoop Shffule原理

    hadoop的核心思想是MapReduce,但shuffle又是MapReduce的核心。shuffle的主要工作是从Map结束到Reduce开始之间的过程。首先看下这张图,就能了解shuffle所处的位置。图中的partitions、copy phase、sort phase所代表的就是shuffle的不同阶段。

    shuffle阶段又可以分为Map端的shuffle和Reduce端的shuffle。

    Map端的shuffle:Map端会处理输入数据并产生中间结果,这个中间结果会写到本地磁盘,而不是HDFS。每个Map的输出会先写到内存缓冲区中,当写入的数据达到设定的阈值时,系统将会启动一个线程将缓冲区的数据写到磁盘,这个过程叫做spill。

    在spill写入之前,会先进行二次排序,首先根据数据所属的partition进行排序,然后每个partition中的数据再按key来排序。partition的目是将记录划分到不同的Reducer上去,以期望能够达到负载均衡,以后的Reducer就会根据partition来读取自己对应的数据。接着运行combiner(如果设置了的话),combiner的本质也是一个Reducer,其目的是对将要写入到磁盘上的文件先进行一次处理,这样,写入到磁盘的数据量就会减少。最后将数据写到本地磁盘产生spill文件(spill文件保存在{mapred.local.dir}指定的目录中,Map任务结束后就会被删除)。

    最后,每个Map任务可能产生多个spill文件,在每个Map任务完成前,会通过多路归并算法将这些spill文件归并成一个文件。至此,Map的shuffle过程就结束了。

    Reduce端的shuffle:Reduce端的shuffle主要包括三个阶段,copy、sort(merge)和reduce。

    首先要将Map端产生的输出文件拷贝到Reduce端,但每个Reducer如何知道自己应该处理哪些数据呢?因为Map端进行partition的时候,实际上就相当于指定了每个Reducer要处理的数据(partition就对应了Reducer),所以Reducer在拷贝数据的时候只需拷贝与自己对应的partition中的数据即可。每个Reducer会处理一个或者多个partition,但需要先将自己对应的partition中的数据从每个Map的输出结果中拷贝过来。

    接下来就是sort阶段,也成为merge阶段,因为这个阶段的主要工作是执行了归并排序。从Map端拷贝到Reduce端的数据都是有序的,所以很适合归并排序。最终在Reduce端生成一个较大的文件作为Reduce的输入。

    最后就是Reduce过程了,在这个过程中产生了最终的输出结果,并将其写到HDFS上。

    参考链接:

    https://blog.csdn.net/lilililililydia/article/details/89301021

 

8.Hadoop常用命令

  • 创建目录:hadoop dfs -mkdir /home

  • 上传文件或目录到hdfs:hadoop dfs -put hello /  、 hadoop dfs -put hellodir/ /

  • 查看目录:hadoop dfs -ls /

  • 创建一个空文件:hadoop dfs -touchz /wahaha

  • 删除一个文件:hadoop dfs -rm /wahaha

  • 删除一个目录:hadoop dfs -rmr /home

  • 重命名:hadoop dfs -mv /hello /hello2

  • 查看文件:hadoop dfs -cat /hello

  • 将指定目录下的所有内容merge成一个文件,下载到本地:hadoop dfs -getmerge /hellodir wa

  • 使用du文件和目录大小:hadoop dfs -du /

  • 将目录拷贝到本地:hadoop dfs -copyToLocal /home localdir

  • 查看dfs的情况:hadoop dfsadmin -report

  • 查看正在跑的Java程序:jps

    参考链接:

    https://baijiahao.baidu.com/s?id=1605161577224027726&wfr=spider&for=pc

 

9.Hadoop优化

    对于Hadoop平台,现在主要有三种优化思路,分别为:从应用程序角度角度进行优化;从参数配置角度进行优化;从系统实现角度进行优化。对于第一种思路,需要根据具体应用需求而定,同时也需要在长期实践中积累和总结;对于第二种思路,大部分采用的方法是根据自己集群硬件和具体应用调整参数,找到一个最优的。对于第三种思路,难度较大,但效果往往非常明显,总结这方面的优化思路,主要有以下几个:

  • 对namenode进行优化,包括增加其吞吐率和解决其单点故障问题。当前主要解决方案有3种:分布式namenode,namenode热备和zookeeper。

  • HDFS小文件问题。当Hadoop中存储大量小文件时,namenode扩展性和性能受到极大制约。现在Hadoop中已有的解决方案包括:Hadoop Archive,Sequence file和CombineFileInputFormat。

  • 调度框架优化。在Hadoop中,每当出现一个空闲slot后,tasktracker都需要通过HEARBEAT向jobtracker所要task,这个过程的延迟比较大。可以用task预调度的策略解决该问题。

  • 共享环境下的文件并发存取。在共享环境下,HDFS的随机寻道次数增加,这大大降低了文件存取效率。可以通过优化磁盘调度策略的方法改进。

  •  索引。索引可以大大提高数据读取效率,如果能根据实际应用需求,为HDFS上的数据添加索引,将大大提高效率。

    参考链接:

    https://blog.csdn.net/pansaky/article/details/83347357

 

10.Hadoop分片、分区

    分片:对于HDFS中存储的一个文件,要进行Map处理前,需要将它切分成多个块,才能分配给不同的MapTask去执行。 分片的数量等于启动的MapTask的数量。默认情况下,分片的大小就是HDFS的blockSize。

    blockSize:默认大小是128M(dfs.blocksize)

    minSize:默认是1byte(mapreduce.input.fileinputformat.split.minsize)

    实际使用中,建议不要去修改maxSize,通过调整minSize(使他大于blockSize)就可以设定分片(Split)的大小了。总之通过minSize和maxSize的来设置切片大小,使之在blockSize的上下自由调整。

    分区:在Reduce过程中,可以根据实际需求(比如按某个维度进行归档,类似于数据库的分组),把Map完的数据Reduce到不同的文件中。分区的设置需要与ReduceTaskNum配合使用。比如想要得到5个分区的数据结果。那么就得设置5个ReduceTask。

    参考链接:

    https://blog.csdn.net/lcalqf/article/details/80754204

 

11.Hive常用高阶命令

    应用场景:

    用于分区排序、动态Group By、Top N、累计计算、层次查询

    窗口函数:

  • FIRST_VALUE:取分组内排序后,截止到当前行,第一个值

  • LAST_VALUE:取分组内排序后,截止到当前行,最后一个值

  • LEAD(col,n,DEFAULT) :用于统计窗口内往下第n行值。第一个参数为列名,第二个参数为往下第n行(可选,默认为1),第三个参数为默认值(当往下第n行为NULL时候,取默认值,如不指定,则为NULL)

  • LAG(col,n,DEFAULT) :与lead相反,用于统计窗口内往上第n行值。第一个参数为列名,第二个参数为往上第n行(可选,默认为1),第三个参数为默认值(当往上第n行为NULL时候,取默认值,如不指定,则为NULL)

    OVER从句:

  • 使用标准的聚合函数COUNT、SUM、MIN、MAX、AVG

  • 使用PARTITION BY语句,使用一个或者多个原始数据类型的列

  • 使用PARTITION BY与ORDER BY语句,使用一个或者多个数据类型的分区或者排序列

  • 使用窗口规范,窗口规范支持以下格式:

(ROWS | RANGE) BETWEEN (UNBOUNDED | [num]) PRECEDING AND ([num] PRECEDING | CURRENT ROW | (UNBOUNDED | [num]) FOLLOWING)(ROWS | RANGE) BETWEEN CURRENT ROW AND (CURRENT ROW | (UNBOUNDED | [num]) FOLLOWING)(ROWS | RANGE) BETWEEN [num] FOLLOWING AND (UNBOUNDED | [num]) FOLLOWING

    分析函数:

  • ROW_NUMBER() 从1开始,按照顺序,生成分组内记录的序列,比如,按照pv降序排列,生成分组内每天的pv名次,ROW_NUMBER()的应用场景非常多,再比如,获取分组内排序第一的记录;获取一个session中的第一条refer等。

  • RANK() 生成数据项在分组中的排名,排名相等会在名次中留下空位
    DENSE_RANK() 生成数据项在分组中的排名,排名相等会在名次中不会留下空位

  • CUME_DIST 小于等于当前值的行数/分组内总行数。比如,统计小于等于当前薪水的人数,所占总人数的比例

  • PERCENT_RANK 分组内当前行的RANK值-1/分组内总行数-1

  • NTILE(n) 用于将分组数据按照顺序切分成n片,返回当前切片值,如果切片不均匀,默认增加第一个切片的分布。NTILE不支持ROWS

  • BETWEEN,比如 NTILE(2) OVER(PARTITION BY cookieid ORDER BY createtime ROWS BETWEEN 3 PRECEDING AND CURRENT ROW)。

    增强的聚合 Cube和Grouping 和Rollup

    这几个分析函数通常用于OLAP中,不能累加,而且需要根据不同维度上钻和下钻的指标统计,比如,分小时、天、月的UV数。

    参考链接:
    https://blog.csdn.net/smile_lty/article/details/79760422

 

12.Redis特性

    Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。从2010年3月15日起,Redis的开发工作由VMware主持。从2013年5月开始,Redis的开发由Pivotal赞助。

    edis 与其他 key - value 缓存产品有以下三个特点:

  • Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。

  • Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。

  • Redis支持数据的备份,即master-slave模式的数据备份。

    参考链接:

    https://www.cnblogs.com/wf-skylark/p/9306994.html

 

13.Redis、传统数据库、HBase、Hive区别

  • Redis:分布式缓存,强调缓存,内存中数据

  • 传统数据库:注重关系,注重事务性

  • Hbase:列式数据库,字典查询,稀疏性存储,无法做关系数据库的主外键,用于存储海量数据,底层基于HDFS

  • Hive:数据仓库工具,底层是MapReduce。不是数据库,不能用来做用户的交互存储

    参考链接:

    http://blog.sina.com.cn/s/blog_18fdb2e180103196t.html

 

14.Kafka、Flume对比

  • Kafka 是分布式消息中间件自带存储,提供 push 和 pull 存取数据的功能,是一个非常通用消息缓存的系统,可以有许多生产者和很多的消费者共享多个主题

  • Flume分为agent(数据采集器),collector(数据简单处理和写入),storage(存储器)三部分,每一部分都是可以定制的

  • Kafka 做日志缓存应该是更为合适的,但是Flume 的数据采集部分做的很好,可以定制很多数据源,减少开发量。所以比较流行Flume+Kafka 模式

    参考链接:

    https://blog.csdn.net/gyshun/article/details/79710534

 

15.Spark执行流程

  • (1)构建Spark Application的运行环境(启动SparkContext),SparkContext向资源管理器(可以是Standalone、Mesos或YARN)注册并申请运行Executor资源;

  • (2)资源管理器分配Executor资源并启动StandaloneExecutorBackend,Executor运行情况将随着心跳发送到资源管理器上;

  • (3)SparkContext构建成DAG图,将DAG图分解成Stage,并把Taskset发送给Task Scheduler。Executor向SparkContext申请Task

  • (4)Task Scheduler将Task发放给Executor运行同时SparkContext将应用程序代码发放给Executor。

  • (5)Task在Executor上运行,运行完毕释放所有资源。

    参考链接:

    https://www.cnblogs.com/frankdeng/p/9301485.html

 

16.Spark RDD是什么?

    RDD 是 Spark 提供的最重要的抽象概念,它是一种有容错机制的特殊数据集合,可以分布在集群的结点上,以函数式操作集合的方式进行各种并行操作。

    通俗点来讲,可以将 RDD 理解为一个分布式对象集合,本质上是一个只读的分区记录集合。每个 RDD 可以分成多个分区,每个分区就是一个数据集片段。一个 RDD 的不同分区可以保存到集群中的不同结点上,从而可以在集群中的不同结点上进行并行计算。下图展示 RDD 的分区及分区与工作结点(Worker Node)的分布关系。

    

 

    RDD 具有容错机制,并且只读不能修改,可以执行确定的转换操作创建新的 RDD。具体来讲,RDD 具有以下几个属性。

  • 只读:不能修改,只能通过转换操作生成新的 RDD。

  • 分布式:可以分布在多台机器上进行并行处理。

  • 弹性:计算过程中内存不够时它会和磁盘进行数据交换。

  • 基于内存:可以全部或部分缓存在内存中,在多次计算间重用。

    参考链接:

    https://blog.csdn.net/dsdaasaaa/article/details/94181269

 

17.Spark stage划分原理

    RDD之间有一系列的依赖关系,依赖关系又分为窄依赖宽依赖。Spark中的Stage其实就是一组并行的任务,任务是一个个的task 。

    窄依赖:父RDD和子RDD partition之间的关系是一对一的。或者父RDD一个partition只对应一个子RDD的partition情况下的父RDD和子RDD partition关系是多对一的。不会有shuffle的产生。父RDD的一个分区去到子RDD的一个分区。

    宽依赖:父RDD与子RDD partition之间的关系是一对多。会有shuffle的产生。父RDD的一个分区的数据去到子RDD的不同分区里面。    

    Spark任务会根据RDD之间的依赖关系,形成一个DAG有向无环图,DAG会提交给DAGScheduler,DAGScheduler会把DAG划分相互依赖的多个stage,划分stage的依据就是RDD之间的宽窄依赖。遇到宽依赖就划分stage,每个stage包含一个或多个task任务。然后将这些task以taskSet的形式提交给TaskScheduler运行。stage是由一组并行的task组成。

    参考链接:

    https://blog.csdn.net/yimeng1994/article/details/94832472

 

18.Spark与Hadoop区别与联系

  • (1)Spark对标于Hadoop中的计算模块MR,但是速度和效率比MR要快得多;

  • (2)Spark没有提供文件管理系统,所以,它必须和其他的分布式文件系统进行集成才能运作,它只是一个计算分析框架,专门用来对分布式存储的数据进行计算处理,它本身并不能存储数据;

  • (3)Spark可以使用Hadoop的HDFS或者其他云数据平台进行数据存储,但是一般使用HDFS;

  • (4)Spark可以使用基于HDFS的HBase数据库,也可以使用HDFS的数据文件,还可以通过jdbc连接使用Mysql数据库数据;Spark可以对数据库数据进行修改删除,而HDFS只能对数据进行追加和全表删除;

  • (5)Spark数据处理速度秒杀Hadoop中MR;

  • (6)Spark处理数据的设计模式与MR不一样,Hadoop是从HDFS读取数据,通过MR将中间结果写入HDFS;然后再重新从HDFS读取数据进行MR,再刷写到HDFS,这个过程涉及多次落盘操作,多次磁盘IO,效率并不高;而Spark的设计模式是读取集群中的数据后,在内存中存储和运算,直到全部运算完毕后,再存储到集群中;

  • (7)Spark是由于Hadoop中MR效率低下而产生的高效率快速计算引擎,批处理速度比MR快近10倍,内存中的数据分析速度比Hadoop快近100倍(源自官网描述);

  • (8)Spark中RDD一般存放在内存中,如果内存不够存放数据,会同时使用磁盘存储数据;通过RDD之间的血缘连接、数据存入内存中切断血缘关系等机制,可以实现灾难恢复,当数据丢失时可以恢复数据;这一点与Hadoop类似,Hadoop基于磁盘读写,天生数据具备可恢复性;

  • (9)Spark引进了内存集群计算的概念,可在内存集群计算中将数据集缓存在内存中,以缩短访问延迟,对7的补充;

  • (10)Spark中通过DAG图可以实现良好的容错。

    参考链接:

    https://www.cnblogs.com/shijingxiang/articles/12101965.html

 

19.Flink API和流/批处理引擎

    Flink核心是一个流式的数据流执行引擎,其针对数据流的分布式计算提供了数据分布、数据通信以及容错机制等功能。基于流执行引擎,Flink提供了诸多更高抽象层的API以便用户编写分布式任务:

  • DataSet API, 对静态数据进行批处理操作,将静态数据抽象成分布式的数据集,用户可以方便地使用Flink提供的各种操作符对分布式数据集进行处理,支持Java、Scala和Python。

  • DataStream API,对数据流进行流处理操作,将流式的数据抽象成分布式的数据流,用户可以方便地对分布式数据流进行各种操作,支持Java和Scala。

  • Table API,对结构化数据进行查询操作,将结构化数据抽象成关系表,并通过类SQL的DSL对关系表进行各种查询操作,支持Java和Scala。

  • Flink ML,Flink的机器学习库,提供了机器学习Pipelines API并实现了多种机器学习算法。

  • Gelly,Flink的图计算库,提供了图计算的相关API及多种图计算算法实现

    在执行引擎这一层,流处理系统与批处理系统最大不同在于节点间的数据传输方式。

    对于一个流处理系统,其节点间数据传输的标准模型是:当一条数据被处理完成后,序列化到缓存中,然后立刻通过网络传输到下一个节点,由下一个节点继续处理。

    而对于一个批处理系统,其节点间数据传输的标准模型是:当一条数据被处理完成后,序列化到缓存中,并不会立刻通过网络传输到下一个节点,当缓存写满,就持久化到本地硬盘上,当所有数据都被处理完成后,才开始将处理后的数据通过网络传输到下一个节点。

    参考链接:

    https://www.cnblogs.com/zzjhn/p/11525125.html

 

20.Storm Spark-streaming Flink对比

    参考链接:

    https://segmentfault.com/a/1190000020465688?utm_source=tag-newest

 

其他相应高频面试题可参考如下内容:

2020 BAT大厂数据分析面试经验:“高频面经”之数据分析篇

2020 BAT大厂数据挖掘面试经验:“高频面经”之数据结构与算法篇

2020 BAT大厂机器学习算法面试经验:“高频面经”之机器学习篇

2020 BAT大厂深度学习算法面试经验:“高频面经”之深度学习篇

 

       欢迎关注作者微信公众号:学习号,涉及数据分析与挖掘、数据结构与算法、大数据与机器学习等内容

Logo

更多推荐