1、什么是数据仓库?
数据仓库:对数据进行采集、清洗、加工和输出
是一个面向主题的、集成的、随时间变化的、非易失的数据集合,用于支持管理决策过程。
2、通常情况下,分哪些层,分别干什么?
ods:数据贴源层。ODS层作为数据仓库的基础层,**主要用于存储从各个操作系统或业务系统中采集来的原始数据。**这些数据未经任何处理(一般情况xia),保持了数据的完整性和细节。
dwd:明细粒度事实层。DWD层作为数据仓库的明细层,存储了详细、完整的数据。每个数据元组都被完整地保存,没有任何聚合,方便后续的数据分析和挖掘。
dws:公共汇总粒度事实层。**DWS层通过对DWD层中的数据进行聚合和汇总,形成宽表,进而提升数据分析性能。**这些宽表通常按照主题进行组织,满足特定主题和不同维度的分析需求。
ads:数据应用层。ADS层是数据仓库的另一个重要组成部分,它提供了一个面向分析的高性能数据存储环境。
3、维度建模的过程?
选择业务过程、声明粒度、确定维度、确定事实、模型评审与验证、优化与维护
4、什么是雪花模型,什么是星型模型?
雪花模型:它是星型模型的一个扩展,有一个或多个维表没有直接连接到事实表上,而是通过其他维表连接到事实表上
星型模型:星型模型是多维的数据关系,它由事实表(Fact Table)和维表(Dimension Table)组成。每个维表中都会有一个维作为主键,所有这些维的主键结合成事实表的主键。所有维表都直接连接到“事实表”上
5、事实表分为哪些事实表?
事务事实表
周期快照事实表
累计快照事实表
6、什么是拉链表?
拉链表是针对数据仓库设计中表存储数据的方式而定义的一种数据结构,主要用于记录维度表中数据的历史变化。
就是通过记录历史的方式,来保存一个事物从开始到当前状态的所有变化信息。
7、datax中如何实现增量同步?
设置同步条件:“where”: “sum_score < 100”,
在reader(“name”: “mysqlreader”)中进行设置
8、dataworks中使用什么变量获取前一天的日期?${bizdate}
阿里云部分
${bizdate}
9、scala中函数柯里化?
面试题:什么是函数柯里化?
1、本身是一个数学界的一个名词,本意是原来一次传递多个参数,现在被改成了可以分开传递的形式,这种做法叫做柯里化
2、在scala中体现柯里化,指的是函数的返回值也是一个函数,将来调用时参数可以分开传递。
3、提高了程序的灵活性和代码复用性
4、在scala中也可以通过偏函数实现参数分开传递的功能
10、scala中的隐式转换聊一聊?
1、scala中的隐式转换,本质上就是将一个类型转换成另一个类型去使用另一个类型中的功能
2、scala中的隐式转换分为3种:隐式转换函数,隐式转换类,隐式转换变量
3、隐式转换函数,在使用隐式转换函数返回值类型的功能的时候,可以自动的将参数的类型转成返回值类型进行使用
4、隐式转换类,可以自动的将构造方法的参数类型转成类的类型,将来可以直接使用构造方法中的类型调用类中的方法
5、隐式转换变量,配合函数定义中的隐式转换参数使用,
将来调用函数的时候,可以不用传入隐式转换参数的值,自动使用对应类型的隐式转换变量
当然,也可以手动传入具体的值给隐式转换参数。
11、spark和MR的区别?
MapReduce:MapReduce是一种编程模型,用于大规模数据集(大于1TB)的并行运算。它通过将数据集分割成小块,分配给多个节点上的Map任务进行处理,然后将Map任务的输出进行Shuffle(洗牌)和Sort(排序)后,由Reduce任务进行汇总。MapReduce的核心操作是Map和Reduce。
Spark:Spark是一个快速、通用、可扩展的大数据处理引擎。它提供了一个统一的编程模型,支持多种数据源和数据处理方式。Spark的核心概念是弹性分布式数据集(RDD),RDD是一个不可变的分布式数据集合,可以在集群中进行并行处理。Spark还支持SQL查询(通过Spark SQL)、流式处理(通过Spark Streaming)和图计算(通过GraphX)等多种数据处理模式。
MR属于细粒度资源调度
MR中的map任务或者reduce任务,遇到要执行的时候才会向yarn中申请资源
任务的执行速度整体会变慢 --》 job作业执行速度变慢
优点:不会造成资源浪费
缺点:速度慢
Spark属于粗粒度资源调度
spark会在任务调度之前,先将所需要的所有资源申请下来,然后再将task任务发送执行
优点:速度快,执行过程中无需再次申请资源
缺点:有可能申请的资源不够,导致任务执行失败;也有可能申请的资源过多,在spark作业执行期间不会释放,会造成资源的浪费
12、你用过哪些spark中的操作算子?
面试题:
spark core中 groupBy算子与groupByKey算子的区别?
1、代码格式上:
groupBy的分组条件可以自己指定,并且绝大部分的RDD都可以调用该算子,返回的是键和元素本身组成的迭代器构成的kv格式RDD
groupByKey算子,只能由kv格式的RDD进行调用,分组的条件会自动根据键进行分组,不需要在自己指定,返回的是键和值组成的迭代器构成的kv格式RDD
2、执行shuffle数据量来看
groupBy产生的shuffle数据量在一定程度上要大于groupByKey产生的shuffle数据量
所以groupByKey算子的执行效率要比groupBy算子的执行效率要高
面试题:
groupByKey与reduceBykey的区别?
相同点:
它们都是kv格式的算子,只有kv格式的RDD才能调用
不同点:
1)groupByKey只是单纯地根据键进行分组,分组后的逻辑可以在后续的处理中调用其他的算子实现
2)reduceByKey 相当于MR中的预聚合,所以shuffle产生的数据量要比groupByKey中shuffle产生的数据量少,效率高,速度要快一些
3)groupByKey的灵活度要比reduceByKey灵活度要高,reduceBykey无法做一些复杂的操作,比如方差。但是groupByKey可以在分组之后的RDD进行方差
13、什么是rdd?
RDD: 弹性分布式数据集
弹性:数据量可大可小
RDD类似于容器,但是本身存储的不是数据,是计算逻辑
当遇到行动算子的时候,整个spark作业才会被触发执行,从第一个RDD开始执行,数据才开始产生流动
数据在RDD之间只是流动关系,不会存储
流动的数据量可以很大,也可以很小,所以称为弹性
分布式:
spark本质上它是需要从HDFS中读取数据的,HDFS是分布式,数据block块将来可能会在不同的datanode上
RDD中流动的数据,可能会来自不同的datanode中的block块数据
数据集:
计算流动过程中,可以短暂地将RDD看成一个容器,容器中有数据,默认情况下在内存中不会进行存储
后面会有办法将一个RDD的数据存储到磁盘中(缓存)
14、rdd的五大特性?
1、RDD是由一系列分区构成
1)读文件时的minPartitions参数只能决定最小分区数,实际读取文件后的RDD分区数,由数据内容本身以及集群的分布来共同决定的
2)若设置minPartitions的数量比block块数量还少的话,实际上以block块数量来决定分区数
3)产生shuffle的算子调用时,可以传入numPartitions(例如:groupby()),可以真正改变RDD的分区数,设置多少,最终RDD就有多少分区
4)文件会以block块的形式存储在HDFS上,若文件未达到128M默认值的话也会被一个block块存储。
一开始RDD中的分区数由读取数据的block块数量决定的。
后一个RDD中的分区数据,除KV函数以外,对应的是前一个RDD中的分区数据所进行逻辑处理后的结果。默认情况下,若后续分区不做处理的话,后续所有的RDD的分区数取决于第一个RDD。
最终RDD中有几个分区,将来在HDFS中就会看到几个结果文件(HDFS -> RDD -> HDFS)
2、算子是作用在每一个分区上的(每一个分区都会处理)
3、RDD与RDD之间存在一些依赖关系
1)窄依赖 前一个RDD中的某一个分区数据只会到后一个RDD中的某唯一分区中 一对一(也可能前多个分区到后一个分区中)的关系
2)宽依赖 前一个RDD中的某一个分区数据会进入到后一个RDD中的不同分区中 一对多的关系 也可以通过查看是否产生shuffle来判断
3)整个spark作业会被宽依赖的个数划分若干个stage, Num(stage) = Num(宽依赖) + 1
4)当遇到产生shuffle的算子的时候,涉及到从前一个RDD写数据到磁盘中,从磁盘中读取数据到后一个RDD的现象,
注意:第一次触发执行的时候,磁盘是没有数据的,所以会从第一个RDD产生开始执行
当重复触发相同的执行的时候,对于同一个DAG有向无环图而言,会直接从shuffle之后的RDD开始执行(省略从前一个RDD写数据到磁盘中的过程),可以直接从磁盘读取数据。
5)**在一个阶段中,RDD有几个分区,**就会有几个并行task任务
4、kv算子只能作用在kv格式的RDD上
5、spark会提供最优的任务计算方式,只移动计算,不移动数据。
Spark的设计原则之一是数据本地化(Data Locality),即尽量让计算任务在数据所在的节点上执行,从而减少数据的网络传输开销。
15、宽依赖、窄依赖的区分?
窄依赖:子RDD的分区与父RDD的分区之间是一对一或一对固定个数的关系。这种依赖关系不会引起数据的Shuffle(重新洗牌),因此处理起来相对简单和高效。常见的窄依赖操作包括map、filter、union等。
宽依赖:一个父RDD的Partition的数据会被传输到子RDD的多个Partition中。这种依赖关系会引起数据的Shuffle,因为数据需要在不同的节点之间重新分配。宽依赖要求跨节点进行数据混洗(Shuffle),以便将来自不同父RDD分区的数据重新分配到当前RDD的分区中。常见的宽依赖操作包括groupByKey、reduceByKey等。
16、stage个数 = 宽依赖的个数 + 1
Spark会根据宽依赖来划分阶段。每个宽依赖之前的操作会被划分到一个阶段中,因为宽依赖之前的操作可以并行执行,而宽依赖之后(包括宽依赖本身)的操作需要等待宽依赖完成后的数据混洗结果才能继续执行。因此,每当遇到宽依赖时,Spark就会开始一个新的阶段。
17、spark资源调度的过程?
18、spark任务调度的过程?
19、什么是累加器,为什么需要它?
在Spark中,累加器(Accumulator)是一种特殊的分布式变量,主要用于在并行操作中累积数据。累加器只能被添加(add)操作,即它的值可以被集群中的多个任务所更新,但只能通过特定的方法(如add)进行增加,而不能减少。累加器的值最终会汇总到驱动程序(Driver Program)中,供用户查看或使用。
当累加器被创建并注册到SparkContext中时,Spark会将其发送到所有的Executor上。