大数据面试问题总结

以下是一些常见面试题,不包含数据倾斜,小文件,内存模型与资源分配、性能优化等问题,这些会单独有几篇文章讲解.

hive面试问题?

面试题1:hive中四个by的区别?

1)Sort By:分区内有序;
不是全局排序,其在数据进入reducer前完成排序,也就是说它会在数据进入reduce之前为每个reducer都产生一个排序后的文件。因此,如果用sort by进行排序,并且设置mapreduce.job.reduces>1,则sort by只保证每个reducer的输出有序,不保证全局有序。

2)Order By:全局排序,只有一个 Reducer;
order by会对输入做全局排序,因此只有一个Reducer(多个Reducer无法保证全局有序),然而只有一个reducer,会导致当输入规模较大时,消耗较长的计算时间

3)Distrbute By:类似 MR 中 Partition,进行分区,结合 sort by 使用。
distribute by是控制在map端如何拆分数据给reduce端的。类似于MapReduce中分区partationer对数据进行分区

hive会根据distribute by后面列,将数据分发给对应的reducer,默认是采用hash算法+取余数的方式。

4)Cluster By:等同于Distribute by + Sort by,只能按默认升序排序

当 Distribute by 和 Sorts by 字段相同时,可以使用 Cluster by 方式。Cluster
by 除了具有 Distribute by 的功能外还兼具 Sort by 的功能。但是排序只能是升序排序,不能
指定排序规则为 ASC 或者 DESC

面试题2:hive中静态分区和动态分区的区别?

静态分区与动态分区的主要区别在于静态分区是手动指定,而动态分区是通过数据来进行判断。 详细来说,静态分区的列实在编译时期,通过用户传递来决定的;动态分区只有在SQL执行时才能决定。 静态分区不管有没有数据都将会创建该分区,动态分区是有结果集将创建,否则不创建。

静态分区 SP(static partition)
  1、静态分区是在编译期间指定的指定分区名
  2、支持load和insert两种插入方式
    2.1load方式
      1)会将分区字段的值全部修改为指定的内容
      2)一般是确定该分区内容是一致的时候才会使用
    2.2insert方式
      1)必须先将数据放在一个没有设置分区的普通表中
      2)该方式可以在一个分区内存储一个范围的内容
      3)从普通表中选出的字段不能包含分区字段
  3、适用于分区数少,分区名可以明确的数据

动态分区 DP(dynamic partition)
  1、根据分区字段的实际值,动态进行分区
  2、是在sql执行的时候进行分区
  3、需要先将动态分区设置打开(set hive.exec.dynamic.partition.mode=nonstrict )
  4、只能用insert方式

面试题3:hive内部表与外部表的区别?使用场景分别是?

区别:
内部表数据由Hive自身管理,外部表数据由HDFS管理;
内部表数据存储的位置是hive.metastore.warehouse.dir。hive自身管理,外部表数据由HDFS管理;
删除内部表会直接删除元数据(metadata)及存储数据;删除外部表仅仅会删除元数据,HDFS上的文件并不会被删除;
对内部表的修改会将修改直接同步给元数据,而对外部表的表结构和分区进行修改,则需要修复。

使用场景:
外部表:相对来说更加安全些,数据组织也更加灵活,方便共享源数据。如果数据的处理由hive和其他工具一起处理,则创建外部表。
内部表:如果所有的数据都由hive处理,则创建内部表。

kafka面试题

面试题4:kafka如何保证数据不丢失?

##broker端:
Topic 副本因子个数:replication.factor >= 3
同步副本列表(ISR):min.insync.replicas = 2
禁用unclean选举:unclean.leader.election.enable=false

##producer端:
#同步方式:
producer.type=sync
request.required.acks=1
副本数量>=2
增加重试次数

#异步方式
producer.type=async 
request.required.acks=1 
queue.buffering.max.ms=5000 
queue.buffering.max.messages=10000 
queue.enqueue.timeout.ms = -1 
batch.num.messages=200
queue.buffering.max.ms=5000
通过buffer来进行控制数据的发送,有两个值来进行控制,缓冲时间阈值与缓冲消息的数量阈值,
如果buffer满了数据还没有发送出去,如果设置的是立即清理模式,风险很大,一定要设置为阻塞模式

##consumner端:
1:关闭自动 offset,手动提交offset
设置 enable.auto.commit = false , 默认值true,自动提交
使用kafka的Consumer的类,用方法consumer.commitSync()提交
或者使用spring-kafka的 Acknowledgment类,用方法ack.acknowledge()提交(推荐使用)

2:另一个方法同样需要手动commit offset,另外在consumer端再将所有fetch到的数据缓存到queue里,
当把queue里所有的数据处理完之后,再批量提交offset,这样就能保证只有处理完的数据才被commit。

面试题5:kafka如何保证数据exactly-once

1) Producer exactly-once
enable.idempotence=true  
分区副本数>= 2
isr >=2
ProducerID+SequenceNumber+Ack=-1(幂等性)


2)Consumer exactly-once
手动维护并提交偏移量。
1:设置enable.auto.commit=false,关闭自动提交偏移量
2:借助外部数据库,如redis的pipeline,mysql的事务机制管理存储偏移量
再同一事物中,在消息被处理完之后在提交偏移量。并更新偏移量。
否则消息需回滚,并获取到上一次偏移量的位置从新进行处理。

面试题6:kafka数据积压怎么解决?

1、增加broker节点,增加分区数量,提高并行度
2、修改单个消费为批量消费
3、增加单线程消费为线程池异步消费
4、缩短批次时间间隔;
5、老版本SparkStreaming控制消费的速率(spark.streaming.kafka.maxRatePerPartition),可以控制最大的消费速率,在参数中设置;新版本设置背压机制实现消费处理的动态平衡。
6.对代码进行优化,尽可能的一次性计算多个结果,减少shuffer过程;
7.处理的结果如果过多,可以将数据保存到MySQL集群、MongoDB集群【支持事物】或ES【不支持事物】,增大吞吐量
8、消费线程将拉取的消息放到一个滑动窗口中,通过滑动窗口控制拉取的速度
9、对于倾斜的key加以处理,加随机数等方式打散

面试题7:kafka reblance发生时机和分区分配策略?

reblance触发时机?
     当出现以下几种情况时,Kafka 会进行一次重新分区分配操作,即 Kafka 消费者端的 Rebalance 操作
     ① 同一个 consumer 消费者组 group.id 中,新增了消费者进来,会执行 Rebalance 操作
     ② 消费者离开当期所属的 consumer group组。比如 主动停机  或者  宕机
     ③ 分区数量发生变化时(即 topic 的分区数量发生变化时)
     ④ 消费者主动取消订阅

reblance三种策略?
kafka新版本提供了三种rebalance分区分配策略:(partition.assignment.strategy)
    range
    round-robin
    sticky

面试题8:kafka的分区数如何确定?

在partition级别上达到均衡负载是实现吞吐量的关键,合适的partition数量可以达到高度并行读写和负载均衡的目的,需要根据每个分区的生产者和消费者的目标吞吐量进行估计。
可以遵循一定的步骤来确定分区数:根据某个topic日常"接收"的数据量等经验确定分区的初始值,然后测试这个topic的producer吞吐量和consumer吞吐量。假设它们的值分别是Tp和Tc,单位可以是MB/s。然后假设总的目标吞吐量是Tt,那么
numPartitions = Tt / max(Tp, Tc)

说明:Tp表示producer的吞吐量。测试producer通常是很容易的,因为它的逻辑非常简单,就是直接发送消息到Kafka就好了。Tc表示consumer的吞吐量。测试Tc通常与应用消费消息后进行什么处理的关系更大,相对复杂一些。

分区数过多的危害?
一、客户端/服务器端需要使用的内存就越多
二、文件句柄的开销
三、越多的分区可能增加端对端的延迟
四、降低高可用性

面试题9:数据发往kafka的分区规则?

key 和 value 的类型,一般都用字符串即可。 数据到底写入到哪一个分区中: 
    如果指定了分区,就写入到指定的分区中。 
    如果没有指定分区,指定了 key,按照 key 的 hashcode,取模,写入对应的分区 
    如果没有指定分区和 key,轮询机制

面试题10:kafka producer buffer pool的作用?

Kafka通过使用内存缓冲池的设计,让整个发送过程中的存储空间循环利用,有效减少JVM GC造成的影响,从而提高发送性能,提升吞吐量。

面试题11:kafka时间轮的作用?

kakfa通过时间轮来处理延迟任务,只将时间轮的槽保存到延迟队列,大大的减少了延迟队列的元素数量,这样对于元素的增加删除性能有很大提高;

kafka通过阻塞的方式poll延迟队列的,减少了大量的空转;

为了保证线程安全,灵活运用读写锁、原子对象、synchronized控制时间轮的操作;

面试题12:kafka为什么这么快? alt

spark面试问题?

面试题13::Spark为什么比mapreduce快?

这是一道常见的面试题,回答时可以从IO、shuffle与排序、资源、部署模式、内存管理策略等各个方面来回答。

1:MR基于磁盘的分布式计算引擎,频繁的磁盘IO。spark基于内存进行计算,DAG计算模型,大大减少了磁盘IO。
2:spark多线程运行,MR多进程运行
3:spark粗粒度资源申请,MR细粒度资源申请
4:spark支持多种部署模式,MR只支持yarn上部署
5:shuffle与排序;MR有reducer必排序,一般会经过3次排序,Spark Shuffle数据的排序操作不是必须的。
                  spark有多种shuffle类型,spark不一定会发生shuffle,MR一定会发生shuffle
6:spark具有灵活的内存管理策略

面试题14:spark Repartition和Coalesce 的关系与区别,能简单说说吗?

1)关系:
两者都是用来改变RDD的partition数量的,repartition底层调用的就是coalesce方法:coalesce(numPartitions, shuffle = true)

2)区别:
repartition一定会发生shuffle,coalesce 根据传入的参数来判断是否发生shuffle。
一般情况下增大rdd的partition数量使用repartition,减少partition数量时使用coalesce。

面试题15:简述下Spark中的缓存(cache和persist)与checkpoint机制,并指出两者的区别和联系?

关于Spark缓存和检查点的区别,大致可以从这4个角度去回答:

位置
Persist 和 Cache将数据保存在内存,Checkpoint将数据保存在HDFS

生命周期
Persist 和 Cache 程序结束后会被清除或手动调用unpersist方法,Checkpoint永久存储不会被删除。

RDD依赖关系
Persist 和 Cache,不会丢掉RDD间的依赖链/依赖关系,CheckPoint会斩断依赖链。

执行与使用
persist 中RDD的逻辑只会执行一次,而checkPoint会执行两次
生产环境中一般都是cache和checkPoint连用,这样RDD逻辑只会执行一次,并且会缓存到checkPoint中
alt

面试题16:spark on yarn client模式与cluster的区别?

1:driver所在位置不同。
client模式下driver线程只在spark-submit命令提交的机器上。
cluster模式下,driver线程只在applicationMaster所在的节点。

2:启动的任务进程名字不一样。
client模式下:ExecutorLanucher 只负责向yarn申请容器来启动executor
cluster模式下,applicationMaster既要负责申请运行executor的资源,又要调Driver线程来做task调度。

面试题17:spark rdd、dataframe、dataset的区别与联系?

三者的共性:
1. RDD、DataFrame、DataSet全都是spark平台下的分布式弹性数据集,为处理超大型数据提供便利;
2. 三者都有惰性机制,在进行创建、转换,如map方法时,不会立即执行,只有在遇到Action如foreach时,三者才会开始遍历运算;
3. 三者有许多共同的函数,如filter,排序等;
4. 在对DataFrame和Dataset进行操作许多操作都需要这个包:import spark.implicits._(在创建好SparkSession对象后尽量直接导入);
5. 三者都会根据 Spark 的内存情况自动缓存运算,这样即使数据量很大,也不用担心会内存溢出;
6. 三者都有partition的概念;
7. DataFrame和Dataset均可使用模式匹配获取各个字段的值和类型。

三者的区别:
1) RDD:
=> RDD 一般和spark mllib同时使用
=> RDD不支持sparksql操作
2) DataFrame:
=> 与RDD 和 DataSet不同,DataFrame每一行的类型固定为Row, 每一列的值没法直接访问,只有通过解析才能获取各个字段的值。
=> DataFrame 与 DataSet 一般不与spark mllib同时使用。
=> DataFrame 与 DataSet 均支持SparkSQL的操作,比如select,groupby 之类,还能注册临时表/视窗,进行sql语句操作。
=> DataFrame 与 DataSet支持一些特别方便的保存方式,比如保存成csv,可以带上表头,这样每一列的字段名一目了然
2) DataSet:
=> DataSet 和 DataFrame拥有完全相同的成员函数,区别只是每一行的数据类型不同。DataFrame其实就是DataSet的一个特例。 type DataFrame = DataSet[Row]
=> DataFrame也可以叫DataSet[Row],每一行类型是Row,不解析,每一行究竟有哪些字段,各个字段又是什么类型都无从得知,只能用上面的getAs方法或者共性中的第七条提到的模式匹配拿出特定字段,而DataSet中,每一行是什么类型是不一定的,在自定义case class之后可以很自由的获取每一行的信息。

三者的转换
1) RDD转DataFrame

方案一:直接将字段名称传入toDF中       .toDF(col1,col2...)
方案二:通过反射的方式   
java:  .createDataFrame(RDD1,JavaBean.class);
scala: 通过case class 如:
 spark.sparkContext.textFile(path).map(line => line.split(",")).map(x => {
            Person(x(0),x(1).trim.toLong)}).toDF()

方案三:构造Schema的方式   .createDataFrame(rdd,scheme)

2)DataFrame转RDD
df.rdd或者df.javaRDD()

3)RDD转DataSet
方案一:使用toDS()算子,需要导入隐式转换(import spark.implicits._)
方案二:使用spark.createDataset(rdd)

4) DataSet转RDD
直接使用.rdd

5)DataFrame转DataSet
封装样例类,调用df.as[xxx]
case class xxx()
df.as[xxx]

6) DataSet转DataFrame
ds.toDF()
alt

面试题18:updateStateByKey与mapWithState 使用区别?

updateStateByKey :统计全局的key的状态,就算没有数据输入,它也会在每一个批次的时候返回之前的key的状态。
缺点:若数据量太大的话,需要checkpoint的数据会占用较大的存储,效率低下。

mapWithState:也是用于全局统计key的状态,但是它如果没有数据输入,便不会返回之前的key的状态,有一点增量的感觉。效率更高,生产中建议使用
优点:我们可以只是关心那些已经发生的变化的key,对于没有数据输入,则不会返回那些没有变化的key的数据。这样的话,即使数据量很大,checkpoint也不会像updateStateByKey那样,占用太多的存储

面试题19:spark sql三种join方式?

Broadcast Hash Join:适合一张很小的表和一张大表进行Join;
Shuffle Hash Join:适合一张小表(比上一个大一点)和一张大表进行Join;
Sort Merge Join:适合两张大表进行Join;

shuffle Hash Join策略必须满足以下条件:
1.仅支持等值 Join,不要求参与 Join 的 Keys 可排序(这点是和sort-merge join相对应)
2.spark.sql.join.preferSortMergeJoin 参数必须设置为 false,参数是从 Spark 2.0.0 版本引入的,默认值为true,也就是默认情况下选择 Sort Merge Join;
3.小表的大小(plan.stats.sizeInBytes)必须小于 spark.sql.autoBroadcastJoinThreshold *spark.sql.shuffle.partitions(默认值200)其实就是让每一个小表的分区都类似于广播变量的小表;
4.而且小表大小(stats.sizeInBytes)的三倍必须小于等于大表的大小(stats.sizeInBytes),也就是a.stats.sizeInBytes * 3 < = b.stats.sizeInBytes

Broadcast Hash Join 策略必须满足以下条件:
1、小表的数据必须很小,可以通过 spark.sql.autoBroadcastJoinThreshold 参数来配置,默认是 10MB;
2、如果内存比较大,可以将阈值适当加大;
3、将 spark.sql.autoBroadcastJoinThreshold 参数设置为 -1,可以关闭这种连接方式;
4、只能用于等值 Join,不要求参与 Join 的 keys 可排序 。

要启用 Shuffle Sort Merge Join 必须满足的条件是仅支持等值 Join,并且要求参与 Join 的 Keys 可排序。

面试题20:RDD有什么缺陷?

1)不支持细粒度的写和更新操作(如网络爬虫),spark写数据是粗粒度的 所谓粗粒度,就是批量写入数据,为了提高效率。但是读数据是细粒度的也就是 说可以一条条的读 
2)不支持增量迭代计算,Flink支持

面试题21:groupByKey和reduceByKey区别?

reduceByKey 和 groupByKey 都存在 shuffle 的操作,但是 reduceByKey 可以在 shuffle 前对分区内相同 key 的数据进行预聚合(combine)功能,这样会减少落盘的 数据量,而 groupByKey 只是进行分组,不存在数据量减少的问题,reduceByKey 性能比较 高。 从功能的角度:reduceByKey 其实包含分组和聚合的功能。GroupByKey 只能分组,不能聚 合,所以在分组聚合的场合下,推荐使用 reduceByKey,如果仅仅是分组而不需要聚合。那 么还是只能使用 groupByKey

面试题22:RDD的弹性表现在哪几点?

1)自动的进行内存和磁盘的存储切换;
2)基于Lineage的高效容错;
3)task如果失败会自动进行特定次数的重试;
4)stage如果失败会自动进行特定次数的重试,而且只会计算失败的分片;
5)checkpoint和persist,数据计算之后持久化缓存;
6)数据调度弹性,DAG task调度和资源无关;
7)数据分片的高度弹性。

面试题23、RDD通过Linage(记录数据更新)的方式为何很高效?

1)lazy记录了数据的来源,RDD是不可变的,且是lazy级别的,且RDD之间构成了链条,lazy是弹性的基石。由于RDD不可变,所以每次操作就产生新的rdd,
不存在全局修改的问题,控制难度下降,所有有计算链条将复杂计算链条存储下来,计算的时候从后往前回溯 900步是上一个stage的结束,要么就checkpoint。

2)记录原数据,是每次修改都记录,代价很大如果修改一个集合,代价就很小,官方说rdd是粗粒度的操作,是为了效率,为了简化,每次都是操作数据集合,
写或者修改操作,都是基于集合的rdd的写操作是粗粒度的,rdd的读操作既可以是粗粒度的也可以是细粒度,读可以读其中的一条条的记录。

3)简化复杂度,是高效率的一方面,写的粗粒度限制了使用场景如网络爬虫,现实世界中,大多数写是粗粒度的场景。

面试题24:spark3.0 AQE新特性?

自动分区合并
自动数据倾斜处理
Join 策略调整
详细见:https://zhuanlan.zhihu.com/p/622617762

面试题25:spark Hash shuffle与Sort shuffle的区别?

Hash shuffle:一种是普通运行机制,另一种是合并的运行机制。

产生的磁盘小文件的个数为maptask*reducetask 每个分区是一个task 磁盘小文件多,I/O增多,产生的GC会增多。 这种shuffle产生的磁盘小文件,容易导致OOM

这种模式不单单产生的磁盘小文件比较多,而且占用内存也比较多。 我们应该降低这种磁盘之间的接触。 Hash shuffle的优化机制

启动HashShuffle的合并机制ConsolidatedShuffle的配置:spark.shuffle.consolidateFiles=true 两个task共用一个buffer缓冲区

如果 Reducer 端的并行任务或者是数据分片过多的话则 Core * Reducer Task 依旧过大,也会产生很多小文件。

sort shuffle:

Spark1.6之前用hash shuffle,在spark1.6之后使用sort shuffle Sort shuffle的两种机制: 估算,去要内存5.01*2-5 要不到的时候就去排序 最终溢写的小的磁盘小文件合并成为了一个大的磁盘小文件 当不需要排序的时候,默认使用Bypass机制

bypass运行机制的触发条件: Shuffle reduce task 数量小于spark.shuffle .sort.bypassMerge Threadshold参数的值小于200,不开启,溢写磁盘不需要排序,小于等于的时候是开启的。

不是聚合类的shuffle算子(比如reduceByKey)。

hash shuffle(合并运行机制)优化机制产生的磁盘小文件的个数:C*R(core*reducer)
Hash shuffle(普通):产生的磁盘小文件:M*R
Sort shuffle产生的磁盘小文件的个数为:2*M
Bypass机制产生的磁盘小文件的个数为:2*M

面试题26、哪些Spark算子会有shuffle过程

去重:distinct
排序:groupByKey ,reduceByKey,sortByKey
重分区:repartition、repartitionAndSortWithinPartitions、coalesce
集合或者表连接操作:join,cogroup

flink面试题?

27: flink中什么时候形成算子链,什么时候断链。

## 形成算子链的条件:
上下游的并行度一致(槽一致)
该节点必须要有上游节点跟下游节点;
下游StreamNode的输入StreamEdge只能有一个) 
上下游节点都在同一个 slot group 中(下面会解释 slot group) 
下游节点的 chain 策略为 ALWAYS(可以与上下游链接,map、flatmap、filter等默认是ALWAYS) 
上游节点的 chain 策略为 ALWAYS 或 HEAD(只能与下游链接,不能与上游链接,Source默认是HEAD) 
上下游算子之间没有数据shuffle (数据分区方式是 forward) 
用户没有禁用 chain 

## 禁用算子链的场景
某个算子需要单独设置资源:当某个算子需要单独设置资源时,比如说 Memory、CPU 等,这个算子就不能被放置在算子链里面,需要单独成为一个 Task。(背压时定位问题)

需要等待外部事件触发:某些算子需要等待外部事件触发才能继续处理数据,例如读取外部文件或者接收网络消息等,这时候算子如果被放到算子链里面,则整个链都会阻塞,产生性能问题,因此需要禁用算子链。

处理时间窗口非常大的数据集:对于非常大的数据集,特别是在窗口结束时间很大的情况下,算子链可能会消耗太长的时间,导致超时或者OOM错误。禁用算子链可以避免此类问题。

需要流数据处理与批数据处理共存:如果同时需要进行流式与批处理,禁用算子链可以让流和批处理同时运行,避免出现串行化的问题。
...

28:flink keyby之后出现数据倾斜的原因是什么?如何定位和解决的?

keyby之后出现数据倾斜常见原因?

Key的选择不合适:如果选择的Key不平衡或者有明显的热点数据,就容易出现数据倾斜的问题。应该尝试选择更加平衡的Key,例如多个属性组合的方式。

数据分布不均匀:有些数据在时间、空间上分布不均匀,导致某些Key的数据量比其他Key大很多。可以通过统计每个Key对应的数据量,找到数据分布不均匀的原因。

算子链长/复杂度高:当算子链过长或者算子的操作很复杂时,也容易导致某些Task的数据处理量过大。可以通过拆分算子链、优化算子操作等方式来解决。

并行度设置不当:并行度过高可能导致资源浪费,过低则会导致数据倾斜。应该根据实际情况,合理设置并行度。

定位:
步骤1:定位反压
定位反压有2种方式:Flink Web UI 自带的反压监控(直接方式)、Flink Task Metrics(间接方式)。通过监控反压的信息,可以获取到数据处理瓶颈的 Subtask。
步骤2:确定数据倾斜
Flink Web UI 自带Subtask 接收和发送的数据量。当 Subtasks 之间处理的数据量有较大的差距,则该 Subtask 出现数据倾斜。如下图所示,红框内的 Subtask 出现数据热点。

解决方案:
keyBy后聚合操作存在数据倾斜(通过Flink LocalKeyBy思想来解决)

在 keyBy 上游算子数据发送之前,首先在上游算子的本地对数据进行聚合后再发送到下游,使下游接收到的数据量大大减少,从而使得 keyBy 之后的聚合操作不再是任务的瓶颈。类似 MapReduce 中 Combiner 的思想,但是这要求聚合操作必须是多条数据或者一批数据才能聚合,单条数据没有办法通过聚合来减少数据量。从 Flink LocalKeyBy 实现原理来讲,必然会存在一个积攒批次的过程,在上游算子中必须攒够一定的数据量,对这些数据聚合后再发送到下游。

注意:Flink 是实时流处理,如果 keyby 之后的聚合操作存在数据倾斜,且没有开窗口
的情况下,简单的认为使用两阶段聚合,是不能解决问题的。因为这个时候 Flink 是来一条
处理一条,且向下游发送一条结果,对于原来 keyby 的维度(第二阶段聚合)来讲,数据
量并没有减少,且结果重复计算(非 FlinkSQL,未使用回撤流)

keyBy后窗口聚合操作存在数据倾斜(两阶段聚合)
因为使用了窗口,变成了有界数据的处理,窗口默认是触发时才会输出一条结果发往下游,所以可以使用两阶段聚合的方式:
实现思路:
第一阶段聚合:key 拼接随机数前缀或后缀,进行 keyby、开窗、聚合
注意:聚合完不再是 WindowedStream,要获取 WindowEnd 作为窗口标记作为第二阶段分组依据,避免不同窗口的结果聚合到一起)
第二阶段聚合:去掉随机数前缀或后缀,按照原来的 key 及 windowEnd 作 keyby、聚合
alt

29:flink taskmanger slot jobmanger 并行度之间资源怎么分配的?

## taskmanager、slot、并行度之间的关系
在Yarn集群中Job分离模式下,Taskmanger的数量=ceil(slot数量/并行度)。slotNumber>=taskmanger*并行度

## TaskManager/slots与cpu的关系
经验上讲Slot的数量与CPU-core的数量一致为好。但考虑到超线程,可以让slotNumber=2*cpuCore。

## slot与并行度
一般我们设置task的并行度不能超过slot的数量。
一个Task的并行度等于分配给它的Slot个数(前提槽资源充足)。

30:flink application、session、pre-job模式的区别和使用场景?

application:每个job独享一个集群,job退出则集群退出。main方法在集群上运行。
session:多个job共享集群资源,job退出集群也不会退出。main方法在客户端运行。
pre-job:每个job独享一个集群,job退出则集群退出。main方法在客户端运行。

适用场景:
Session模式一般用来部署那些对延迟非常敏感但运行时长较短的作业,需要频繁提交小job的场景。
Per-Job模式一般用来部署那些长时间运行的作业
Application模式综合了两种模式的所有优点,建议生产上适用。

alt

31:讲讲flink checkpoint原理?对齐式和非对齐式checkpoint有什么区别?

checkpoint作用?
保证Flink集群在某个算子因为某些原因(如异常退出)出现故障时,能够将整个应用流图的状态恢复到故障之前的某一状态,保证应用流图状态的一致性。checkpoint是一种容错恢复机制
checkpoint保存的是什么数据?
当前检查点开始时数据源(例如Kafka)中消息的offset。
记录了所有有状态的operator当前的状态信息(例如sum中的数值)。


Checkpoint有两种实现方式:对齐式(Aligned Checkpoint)和非对齐式(Unaligned Checkpoint)。
对齐式Checkpoint:

 计算所有执行中的任务完成当前状态后,最终整个程序的一个完整状态。
 取得一个全局会话锁,暂停所有输入数据源的操作,等待所有任务的结果输出。
 对任务进行Barrier插入,通过Barrier Barrier来将任务切分成Snapshotable 和 Non-Snapshotable 两类任务。Snapshotable任务需要将其状态发送到其他TaskManager进行二次备份,而Non-Snapshotable任务则不需要。
 在所有任务都完成Snapshotable操作之后,JobManager根据接收到的各个任务的实际状态,重新计算出恢复点位置。
 恢复以该状态为准的下一个CheckPoint,之前的CheckPoint使用完毕并且作废。

非对齐式Checkpoint:
 每个任务在被触发Checkpoint时,都记录下自己当前的状态信息。
 在所有任务完成状态保存之后,JobManager会选择其中任意一个Checkpoint作为重启点。当它恢复时,每个任务将自己记录的状态发送给它所属的Operator进行恢复。
 非对齐式Checkpoint允许各个Task在不同的时间点异步进行Checkpoint操作,节省了执行任务的总体时间。

对齐式Checkpoint可以保证所有任务的状态是一致的,但是需要等待所有任务都完成Checkpoint后才能进入下一个Checkpoint,因此会影响整个应用程序的处理速度,exactly once 精确一次性支持。
而非对齐式Checkpoint则可以保证任务相互之间的状态是独立的,每个任务在自己的频率上异步进行Checkpoint,可以大大提高系统的可扩展性和容错性,支持at least once语义 最少一次,消息不会丢失,但是可能会重复。

在Flink中,Checkpoint除了帮助我们实现分布式快照外,还可以通过控制Checkpoint的间隔、最大并发数、存储位置等参数来优化应用程序的性能,并确保应用程序的容错性。

32:讲讲watermark工作机制?

## watermark的意义:
标识 Flink 任务的事件时间进度,从而能够推动事件时间窗口的触发、计算。
解决事件时间窗口的乱序问题。

## watermark的触发时机:
1:watermark时间 >= window_end_time 即max(timestamp, currentMaxTimestamp....)-allowedLateness >= window_end_time
2:在[window_start_time,window_end_time)中有数据存在

## 乱序处理可归纳为:
窗口window 的作用是为了周期性的获取数据。
watermark的作用是防止数据出现乱序(经常),事件时间内获取不到指定的全部数据,而做的一种保险方法。
allowLateNess是将窗口关闭时间再延迟一段时间。
sideOutPut是最后兜底操作,所有过期延迟数据,指定窗口已经彻底关闭了,就会把数据放到侧输出流。

33:flink双流join?

1:flink window join
join()
通俗理解,将两条实时流中元素分配到同一个时间窗口中完成Join。两条实时流数据缓存在Window State中,当窗口触发计算时,执行join操作。(窗口对齐才会触发)
支持Tumbling Window Join (滚动窗口),Sliding Window Join (滑动窗口),Session Widnow Join(会话窗口),支持处理时间和事件时间两种时间特征。
源码核心总结:windows窗口 + state存储 + 双层for循环执行join()

coGroup()
coGroup的作用和join基本相同,但有一点不一样的是,如果未能找到新到来的数据与另一个流在window中存在的匹配数据,仍会将其输出。
只有 inner join 肯定还不够,如何实现 left/right outer join 呢?答案就是利用 coGroup() 算子。
它的调用方式类似于 join() 算子,也需要开窗,但是 CoGroupFunction 比 JoinFunction 更加灵活,
可以按照用户指定的逻辑匹配左流和/或右流的数据并输出。(二重循环)

2:Flink Interval Join
join() 和 coGroup() 都是基于窗口做关联的。但是在某些情况下,两条流的数据步调未必一致。例如,订单流的数据有可能在点击流的购买动作发生之后很久才被写入,如果用窗口来圈定,很容易 join 不上。所以 Flink 又提供了"Interval join"的语义,按照指定字段以及右流相对左流偏移的时间区间进行关联,即:
right.timestamp ∈ [left.timestamp + lowerBound; left.timestamp + upperBound]
interval join 也是 inner join,虽然不需要开窗,但是需要用户指定偏移区间的上下界,并且只支持事件时间。示例代码如下。注意在运行之前,需要分别在两个流上应用 assignTimestampsAndWatermarks() 方法获取事件时间戳和水印。 interval join 与 window join 不同,是两个 KeyedStream 之上的操作,并且需要调用 between() 方法指定偏移区间的上下界。
如果想令上下界是开区间,可以调用 upperBoundExclusive()/lowerBoundExclusive() 方法。

3:Flinksql Regular Join
Regular Join 是最为基础的没有缓存剔除策略的 Join。Regular Join 中两个表的输入和新都会对全局可见,影响之后所有的 Join 结果。举例,在一个如下的 Join 查询里,
Orders 表的新纪录会和 Product 表所有历史纪录以及未来的纪录进行匹配。-号代表回撤,+号代表最新数据
SELECT * FROM Orders
INNER JOIN Product
ON Orders.productId = Product.id
因为历史数据不会被清理,所以 Regular Join 允许对输入表进行任意种类的更新操作(insert、update、delete)。然而因为资源问题 Regular Join 通常是不可持续的,一般只用做有界数据流的 Join。

4:flinksql Time-Windowed Join
Time-Windowed Join 利用窗口给两个输入表设定一个 Join 的时间界限,超出时间范围的数据则对 JOIN 不可见并可以被清理掉。值得注意的是,这里涉及到的一个问题是时间的语义,时间可以指计算发生的系统时间(即 Processing Time),也可以指从数据本身的时间字段提取的 Event Time。如果是 Processing Time,Flink 根据系统时间自动划分 Join 的时间窗口并定时清理数据;如果是 Event Time,Flink 分配 Event Time 窗口并依据 Watermark 来清理数据。

5:flinksql 时态表
虽然 Timed-Windowed Join 解决了资源问题,但也限制了使用场景: Join 两个输入流都必须有时间下界,超过之后则不可访问。这对于很多 Join 维表的业务来说是不适用的,因为很多情况下维表并没有时间界限。针对这个问题,Flink 提供了 Temporal Table Join 来满足用户需求。
Temporal Table Join 类似于 Hash Join,将输入分为 Build Table 和 Probe Table。前者一般是纬度表的 changelog,后者一般是业务数据流,典型情况下后者的数据量应该远大于前者。在 Temporal Table Join 中,Build Table 是一个基于 append-only 数据流的带时间版本的视图,所以又称为 Temporal Table。Temporal Table 要求定义一个主键和用于版本化的字段(通常就是 Event Time 时间字段),以反映记录在不同时间的内容。

时态表可以划分成一系列带版本的表快照集合,表快照中的版本代表了快照中所有记录的有效区间,有效区间的开始时间和结束时间可以通过用户指定,根据时态表是否可以追踪自身的历史版本与否,时态表可以分为 版本表 和 普通表。

34: 讲讲flink状态后端,怎么选择,各有什么优缺点?

Flink状态后端是指用来存储和管理分布式数据流应用程序的状态数据的底层系统。Flink提供了多种状态后端实现,包括内存状态后端、文件系统状态后端和RocksDB状态后端。

内存状态后端
内存状态后端是默认的状态后端,使用哈希表来管理状态,并将所有状态存储在JVM堆中。
优点:速度快、延迟低,适合用于非常小的状态或者需要最佳性能的应用场景。
缺点:容量有限,无法处理大量状态或长时间运行的应用程序,同时,当任务发生故障时,由于状态存储在堆中,可能会导致状态丢失。

文件系统状态后端
文件系统状态后端利用Hadoop的文件系统(HDFS)来存储状态信息。
优点:具有较高的容量和可扩展性,支持持久化状态和快速恢复,适合用于高可用方案。
缺点:延迟较高,不适合对状态的实时操作。

RocksDB 状态后端
将工作状态保存在RocksDB数据库(RocksDB 是一个基于 LSM 实现的 KV 数据库,所以个人理解State数据部分存储在内存中,一部分存储在磁盘文件上)。

优点:可以高效地管理大规模状态数据,非常适合在长时间运行的应用程序中使用。RocksDB状态后端比文件系统状态后端具有更好的性能和容量,RocksDB状态后端具有高可用性,并支持快速故障恢复。并且支持增量checkpint,支持长窗口大键控状态,适合用于高可用方案。
缺点:需要更多的资源支持。

选择哪种状态后端,需要根据业务场景和要求进行评估。一般来说,如果关注的是低延迟和高性能,那么使用内存状态后端或者RocksDB状态后端会是比较好的选择;如果注重可靠性和可扩展性,则可以选择文件系统状态后端。在实际的使用中,还可以通过配置Flink的参数调整状态后端的功能、容量以及性能表现等方面,以达到更优的效果。

35:flink 维表关联的各种方案和优缺点?

1:预加载维表
通过定义一个类实现RichMapFunction,在open()中读取维表数据加载到内存中,在probe流map()方法中与维表数据进行关联。RichMapFunction中open方法里加载维表数据到内存的方式特点如下:
优点:实现简单。
缺点:因为数据存于内存维度信息全量加载到内存中,所以只适合小数据量并且维表数据更新频率不高的情况下。虽然可以中定义一个定时器定时更新维表,但是还是存在维表更新不及时的情况。

2:热存储维表(look up join)
这种方式是将维表Redis、Hbase、MySQL等外部存储中,实时流在关联维表数据的时候实时去外部存储中查询,这种方式特点如下:
优点:维度数据量不受内存限制,可以存储很大的数据量
缺点:因为维表数据在外部存储中,读取速度受制于外部存储的读取速度;另外维表的同步也有延迟。

3:广播维表
利用Flink的Broadcast State将维度数据流广播到下游做join操作。特点如下:
优点:维度数据变更后可以即时更新到结果中。
缺点:数据保存在内存中,支持的维度数据量比较小。
使用:
1.将维度数据发送到Kafka作为流S1。事实数据是流S2。
2.定义状态描述符MapStateDescriptor,如descriptor。
3.结合状态描述符,将S1广播出去,如S1.broadcast(descriptor),形成广播流(BroadcastStream) B1。
4.事实流S2和广播流B1连接,形成连接后的流BroadcastConnectedStream BC。
5.基于BC流,在KeyedBroadcastProcessFunction/BroadcastProcessFunction中实现Join的逻辑处理。


4:异步IO+guava
异步IO主要目的是为了解决与外部系统交互时网络延迟成为了系统瓶颈的问题
使用Aysnc I/O的前提条件
1)为了实现以异步I/O访问数据库或K/V存储,数据库等需要有能支持异步请求的client;若是没有,可以通过创建多个同步的client并使用线程池处理同步call的方式实现类似并发的client,但是这方式没有异步I/O的性能好。
2)AsyncFunction不是以多线程方式调用的,一个AsyncFunction实例按顺序为每个独立消息发送请求;
Flink中可以使用异步IO来读写外部系统,这要求外部系统客户端支持异步IO,不过目前很多系统都支持异步IO客户端。但是如果使用异步就要涉及到三个问题:
超时:如果查询超时那么就认为是读写失败,需要按失败处理;
并发数量:如果并发数量太多,就要触发Flink的反压机制来抑制上游的写入;
返回顺序错乱:顺序错乱了要根据实际情况来处理,Flink支持两种方式:允许乱序、保证顺序
使用缓存来存储一部分常访问的维表数据,以减少访问外部系统的次数,比如使用guava Cache
优点:维度数据不受限于内存,支持较多维度数据
缺点:需要热存储资源,维度更新反馈到结果有延迟(热存储导入,cache)
适用场景:维度数据量大,可接受维度更新有一定的延迟。

5:Temporal table function Join
Temporal table是持续变化表上某一时刻的视图,Temporal table function是一个表函数,(历史表)
传递一个时间参数,返回Temporal table这一指定时刻的视图。
可以将维度数据流映射为Temporal table,主流与这个Temporal table进行关联,可以关联到某一个版本(历史上某一个时刻)的维度数据。
优点:维度数据量可以很大,维度数据更新及时,不依赖外部存储,可以关联不同版本的维度数据。
缺点:只支持在Flink SQL API中使用。
alt

36:flink异步io?

Flink异步I/O是一种高效的 I/O 方案,通过异步方式(非阻塞)实现了 I/O 操作和计算之间的解耦,避免了等待I/O操作完成所造成的阻塞。这种技术常用于大量网络I/O请求高并发的场景,如数据流处理和批处理。

在Flink中,异步I/O主要用于维表关联操作,通常使用异步database client(如AsyncMySQLClient)从外部存储系统中查询数据,并将查询到的结果与DataStream进行join操作。相对于同步I/O,异步I/O可以充分利用后台线程的资源,提高了系统的吞吐量和响应性能。

下面是 Flink 异步 I/O 的优势和使用方法:
优势:
非阻塞:异步执行I/O操作,不会阻塞计算操作;
高吞吐量:能够处理大量并发的I/O请求;
低延迟性:不需要等待I/O操作完成,有助于缩短处理时间;
减少CPU占用:异步I/O可以释放CPU资源,提高了系统的效率。

使用方法:
实现 AsyncFunction 接口:需要自己实现AsyncFunction接口,并在其中编写异步I/O的逻辑代码。
使用 AsyncDataStream API:Flink提供了 AsyncDataStream 类作为支持异步I/O的扩展,可以通过该类将异步I/O集成到DataStream API中。
配置 AsyncWaitOperator:在异步 I/O 的数据处理过程中,Flink提供了 AsyncWaitOperator 作为一个Buffer,用于缓存等待异步操作的结果。
需要注意的是,在使用Flink异步I/O时,需要细心处理异常和超时的情况,避免因为异步I/O导致整个应用程序崩溃。另外也要根据具体情况,合理调节AsyncWaitOperator的大小以及并发度等参数,以提高异步I/O的效果。

37: flink savepoint与checkpoint的应用和区别?

alt
Flink中的Checkpoint和Savepoint是两种不同的机制,它们都用于容错,并且在恢复失败任务时起到了重要作用,但二者有着不同的应用场景和使用方法。

Checkpoint
Checkpoint是Flink中提供的一种机制,用于防止数据流处理过程中的数据丢失或错误。Checkpoint会将当前状态的快照备份到持久化存储中,并在发生故障时,使用这些快照来重新启动任务。Checkpoint机制需要开启后才能使用,并且通过设置间隔时间和最大并发数等参数进行配置。

Savepoint
Savepoint是Flink中提供的一种手动触发的机制,用于保存任务当前状态的一个快照,并可以在之后的时间点重新启动任务,或在另一个集群上恢复该状态。与Checkpoint不同,Savepoint是由用户主动触发的,用户可以选择在任何时候保存任务状态。这种机制常用于灰度升级或版本升级后的任务恢复。

区别:

Checkpoint是自动触发的,而Savepoint是手动触发的;
Checkpoint会定期进行,在任务执行过程中会多次生成checkpoint,而Savepoint只在手动发起时生成一次;
在任务停止时,Checkpoint产生的状态快照会被删除,而Savepoint生成的状态快照则会被保留以供后续使用或版本升级;
在任务恢复时,Checkpoint是在本地文件系统或分布式存储中进行,而Savepoint可以在另一个集群或不同的版本上进行。
总的来说,Checkpoint和Savepoint都是Flink中用于容错的机制。Checkpoint用于防止数据丢失或错误,而Savepoint则常用于灰度升级、版本升级等场景下生成状态备份。因此,在实际应用中需要根据具体需求选择合适的机制。

38:flink 背压原理?定位与解决方式? alt 反压定位:

通过 Flink Web UI 自带的反压监控面板;
通过 Flink Task Metrics。
使用火焰图、线程 Dump、CPU Profiler分析:

监控面板: alt alt

alt backpressure Tab页面:backpressure status 和backpressured/Idle/busy idleTimeMsPerSecond busyTimeMsPerSecond backPressuredTimeMsPerSecond

Flink Task Metrics: alt ① floatingBuffersUsage 为高则表明反压正在传导至上游。

② exclusiveBuffersUsage 则表明了反压可能存在倾斜。如果floatingBuffersUsage 高、exclusiveBuffersUsage 低,则存在倾斜。因为少数 channel 占用了大部分的 floating Buffer(channel 有自己的 exclusive buffer,当 exclusive buffer 消耗完,就会使用floating Buffer)。

使用火焰图、线程 Dump、CPU Profiler分析: alt 使用方法和说明详见:

官网:/nightlies.apache.org/flink/flink-docs-release-1.16/zh/docs/ops/debugging/flame_graphs/

微信公众号文章:https://mp.weixin.qq.com/s/6GXuL7WcWhTu2Aq_k2vqAw

常见背压解决方式:

增加资源
通过增加资源(例如 TaskManager、CPU、内存等)的方式,来提高整个系统的处理能力,从而降低背压的风险。需要注意的是,增加资源是一种比较暴力的解决方式,并非所有情况都适用。

调整拓扑结构
通过调整 Flink 的拓扑结构,使得数据流更加合理地流动,从而减少背压的出现。具体来说,可采取以下措施:

 增加缓存队列的长度,以容纳更多的未处理数据。
 优化算子之间的并行度数量,避免出现单节点瓶颈。上下游并行度保持一致,合并算子链,使用共享资源槽位组。
 使用窗口(Window)或 State 来帮助管理状态,降低内存占用率。
 对于大规模任务,可以将任务拆分成多个小任务,以减少单个算子积压数据的风险。
 checkpoint相关优化

数据倾斜解决
  keyby前:把数据进行打散,重新均匀分配。
         通过调整并发度,解决数据源消费不均匀或者数据源反压的情况
 keyby之后:LocalKeyBy思想,本地聚合攒批后发往下游
        两阶段聚合。要获取 WindowEnd 作为窗口标记作为第二阶段分组依据(key+WindowEnd分组)

外部组件交互
如果发现我们的 Source 端数据读取性能比较低或者 Sink 端写入性能较差,需要检查第三方组件是否遇到瓶颈,还有就是做维表 join 时的性能问题。 
例如:
 1)Kafka 集群是否需要扩容,Kafka 连接器是否并行度较低;
 2)HBase 的 rowkey 是否遇到热点问题,是否请求处理不过来;
 3)ClickHouse 并发能力较弱,是否达到瓶颈。
关于第三方组件的性能问题,需要结合具体的组件来分析,最常用的思路:
1)异步 io+热缓存来优化读写性能
2)先攒批再读写
维表 join 的合理使用与优化

39:flink数据倾斜怎么定位?怎么处理? flink 数据倾斜的常见处理方式

40:flink去重方案?

1:mapState/ValueState+状态后端
使用RocksDBStateBackend,因为数据是存储在磁盘上,元数据保存在内存
                中。适合非常大的状态。在算子中,使用MapState数据结构,对key进行保存。
                数据来了查看MapState是否存在,存在 + 1,不存在设置为1。
       缺点:
   如果使用机械硬盘的话,flink数据量过大,磁盘会成为性能瓶颈。
   随之导致整个IO急剧下降。可能会出现背压情况!
      优点:精确去重

2:基于HyperLogLog:
HyperLogLog是去重计数的利器,能够以很小的精确度误差作为trade-off大幅减少空间占用,在不要求100%准确的计数场景极为常用
优点:高效,占用空间少
缺点:近似去重

3:布隆过滤器+状态后端/布隆过滤器+redis
   类似Set集合,用于判断当前元素是否存在当前集合中。
  布隆过滤器,当前的key是否存在容器中,不存在直接返回
    缺点:
    不能百分之百的保证精确。
    优点:
    插入和查询效率是非常的高
      
4:基于BitMap
用一个bit位来标记某个元素对应的Value,而Key即是该元素。由于采用了Bit为单位来存储数据,因此可以大大节省存储空间。

5:基于外部数据库
选择使用Redis或者HBase存储数据,我们只需要设计好存储的Key即可,不需要关心Flink任务重启造成的状态丢失问题

6:RoaringBitmap去重(推荐)
BitMap - 优点:精确去重,占用空间小(在数据相对均匀的情况下)。 缺点:只能用于数字类型(int或者long)。
RoaringBitmap:BitMap固然好用,但是对去重的字段只能用int或者long类型;但是如果去重字段不是int或者long怎么办呢?那我们就构建一个字段与BitIndex的映射关系表,通过MapFunction拿到字段对应的BitIndex之后,就可以直接进行去重逻辑了。

7:flink+starrocks/hudi(推荐)
通过starrocks和hudi的主键直接去重
优点:高效快速去重
缺点:超大规模数据性能待验证

41:flink如何保证端到端的exactly-once ?

不能百分之百保证exactly-once,只能尽可能的保证。需从每个阶段保证。

source端保证:使用可以记录数据位置并重设读取位置的组件(如kafka,文件)

flink内部保证:使用checkpint+state 将状态值保存在状态后端里,并且checkpoint需要设置为精确一次性语义

sink端保证:从故障恢复时,数据不会重复写入外部系统(幂等写入、事务写入)

幂等写入:幂等操作是指,同一个操作,可以执行很多次,但是不会对结果造成影响,与执行一次的结果保持一致
事务写入:在CheckPoint开始构建一个事务,当CheckPoint彻底完成时,提交事务。
事务写入又可以分为两种---WAL预写日志和2pc两阶段提交。DataStream API 提供了GenericWriteAheadSink模板类和TwoPhaseCommitSinkFunction 接口,可以方便地实现这两种方式的事务性写入。

42: flink两阶段提交?

两阶段提交流程:
1. jobMaster 会周期性的发送执行checkpoint命令(start checkpoint);

2.当source端收到执行指令后会产生一条barrier消息插入到input消息队列中,当处理到barrier时会执行本地checkpoint, 并且会将barrier发送到下一个节点,当checkpoint完成之后会发送一条ack信息给jobMaster ;

3. 当DAG图中所有节点都完成checkpoint之后,jobMaster会收到来自所有节点的ack信息,那么就表示一次完整的checkpoint的完成;

4. JobMaster会给所有节点发送一条callback信息,表示通知checkpoint完成消息,这个过程是异步的,并非必须的,方便做一些其他的事情,例如kafka offset提交到kafka。

Flink将两阶段提交协议中的通用逻辑抽象为了一个类—TwoPhaseCommitSinkFunction。
我们在实现端到端exactly-once的应用程序时,只需实现这个类的4个方法即可:
beginTransaction:开始事务时,会在目标文件系统上的临时目录中创建一个临时文件,之后将处理数据写入该文件。
preCommit:在预提交时,我们会刷新文件,关闭它并不再写入数据。我们还将为下一个Checkpoint的写操作启动一个新事务。
commit:在提交事务时,我们自动将预提交的文件移动到实际的目标目录。
abort:中止时,将临时文件删除。
如果出现任何故障,Flink将应用程序的状态恢复到最近一次成功的Checkpoint。如果故障发生在预提交成功之后,但还没来得及通知JobManager之前,在这种情况下,Flink会将operator恢复到已经预提交但尚未提交的状态。

43:Operator State与keyed State的区别? alt

44:任务链(Operator Chains)和 SlotSharing(子任务共享)有什么区别?

任务链(Operator Chains)和 SlotSharing(子任务共享)是 Flink 中用于优化数据流任务的两种机制,二者有着不同的作用和特点。

任务链(Operator Chains)是指把多个算子(operator)连接起来形成一个链式结构,将它们放入同一个线程中执行,从而减少了线程间的通信和序列化开销。在任务链中,一旦开始执行,就会生成一个长时间运行的计算单元,可以有效地提高任务的性能。任务链适用于那些需要频繁传输数据、中间结果计算复杂的场景,在这些场景下,使用任务链可以减少任务之间的通信开销,提高运行效率。

SlotSharing(子任务共享)是指在一个 TaskManager 上启动多个任务(subtask),并将这些任务分配到同一个 slot 中运行。每个 slot 有自己的资源限制和硬件资源,每个任务可以独立地调整资源配置。在 SlotSharing 中,多个任务共享同一个物理节点(TaskManager),可以有效地提高集群的资源利用率。SlotSharing 适用于那些需要大量并发处理的场景,在这些场景下,SlotSharing 可以最大限度地利用资源和加速任务执行。

总的来说,任务链和 SlotSharing 都是 Flink 中用于优化数据流任务的重要机制,但它们的应用场景和特点并不相同。在实际应用中,需要根据具体的需求选择合适的优化机制,以提高任务执行效率和系统的稳定性。

离线数仓常见面试问题?

面试题45:谈谈你对宽表的理解,以及企业建设中宽表的优缺点?

宽表一般是指基于相同粒度的数据进行拉宽整合的表,其中每一行包含多个相关的属性特征或特征,可以分为明细宽表和聚合宽表。相比于传统的长表,宽表具有更好的可读性、可维护性和数据库利用率。

在企业建设过程中,宽表的优点主要包括:
1:数据整合性好:宽表的结构使得不同来源的数据可以更方便地整合在一起,方便进行跨系统、跨部门的数据分析和决策。
2:数据冗余性低:宽表通过将多个属性或特征存储在同一行中,避免了数据的冗余存储,降低了存储和维护的成本。
3:数据查询效率高:宽表的结构有利于数据的快速查询和聚合,减少了多表数据关联的频次,提高了数据的利用率和分析效率。
然而。宽表也存在一些缺点,主要包括:
1:数据结构复杂:宽表的结构相对长表更为复杂,需要更多的数据处理和整合工作,增加了数据处理的难度和成本。
2:数据规模较大:由于宽表需要存储多个维度的数据,数据规模通常较大,需要更多的存储和计算资源。
3:可能存在数据一致性问题:由于宽表中不同属性或特征的更新可能不是同步进行的,来源于不同的业务系统。可能会导致数据的不一致性,需要采取一些措施进行数据一致性的维护。

因此,在企业建设中,宽表的使用需要根据具体情况进行权衡和选择,综合考虑数据的规模、复杂度、资源效率、使用场景等因素,以达到更好的数据分析和决策效果。

面试题46:星型模型、雪花模型的优缺点?以及使用场景?

雪花模型去除了冗余,设计复杂,可读性差,关联的维度表多,查询效率低,但是可扩展性好。
星型模型冗余度高,设计简单,可读性高,关联的维度表少,查询效率高,可扩展性低。

1:查询性能:雪花模型维度表、事实表之间的联接很多,性能比较低;星型模型数据冗余存储所以很多统计查询不需要做外部的连接。
2:模型复杂度:星型架构更简单。雪花模型数据模型的业务层级是由一个不同维度表主键-外键的关系来代表的。而在星形模型中,所有必要的维度表在事实表中都只拥有外键。
3:层次概念:雪花型架构更加贴近OLTP系统的结构,比较符合业务逻辑,层次比较清晰。
4:存储空间:雪花模型使用的是规范化数据,不会产生冗余数据,能够减少数据量,而相比之下星型架构会产生数据冗余。
5:ETL处理:雪花模型由于附属模型的限制,ETL相对复杂,不能并行化。星形模型加载维度表,不需要再维度之间添加附属模型,因此ETL就相对简单,而且可以实现高度的并行化。

总结:适用场景:雪花模型更加适合维度分析的场景,星型模型更加适合指标分析的场景。

根据我们的项目经验,一般建议使用星型架构。因为我们在实际项目中,往往最关注的是查询性能问题,至于磁盘空间一般都不是问题。当然,在维度表数据量极大,需要节省存储空间的情况下,或者是业务逻辑比较复杂、必须要体现清晰的层次概念情况下,可以使用雪花型维度。
alt

面试题47:每天需要全量的删除和插入,数据量比较大,中间会有几分钟的空白时间,在这个期间可能会有人来访问这个数据,会出现查询不到数据的情况,怎么解决这个问题呢?

针对这个问题,可以考虑采用以下两种方案:
1:使用临时表:在每次全量更新前,先创建一张临时表,将新的全量数据插入到这张临时表中,再将主表中的数据全部删除,最后将临时表中数据插入到主表中。这样可以避免在更新过程中出现查询不到的情况,因为在更新期间,主表中的数据并没有被删除,只是被替换了。在更新完成后,再将临时表数据删除即可。
2:使用分区表:将数据按照时间分成多个分区表,每次全量更新时只更新最新的分区,其它分区不受影响。这样可以避免在更新过程中出现查询不到的情况,其它分区数据仍在。同时,分区表的查询性能也比较好,可以提高查询效率。

需要注意的是,这两种方案都需要在更新过程中禁止其它用户对主表进行查询,开通通过锁表或其它机制来实现。另外,在更新过程中需要保证数据的一致性和完整性,可以使用事务来保证更新操作的原子性。

面试题48:仓库中如何保证指标的准确性?

可以从事前,事中,事后三个方面来讲。
事前规范定义、统一计算口径、理解业务、保证业务逻辑正确
事中通过数据质量监控规则和数据血缘发现异常发生的节点和影响的库表,逻辑复核、代码审查,规范建模。
事后和业务人员确认有无异常,建立巡检机制,数据回溯和补数机制。建立相应的监控指标(波动范围、异动率...等指标)

面试题49:数据模型设计好以后,上游业务侧增加、修改或删除字段,该怎么处理?

事前:与上游建立知会机制与协同流程,及时同步业务与模型变更;接管 ODS 层,控制源头,ODS 是业务数据进入数仓的第一站,
是所有数据加工的源头,控制住源头,才能从根本上防止一个重复的数据体系的出现。

事中:通过技术手段捕捉上游元数据与字典值变更,从而方便以后问题追踪与影响分析
对于这种变化,人工处理的话,就是手动在数仓对应的表中增加、修改字段,然后修改同步任务;
这个最好可以搞成自动化的,比如,自动监控上游表结构的变更,变化后,自动去修改数仓中的表结构,自动修改同步任务。

事后:通过事后复盘优化流程与迭代技术

面试题50:离线数仓任务如何保证稳定性和可靠性?

离线数仓通常用于存储、处理和分析大量历史数据。为了保证任务的稳定性,可以采取以下措施:
1.数据备份:定期对数据仓库进行备份,确保在发生故障时可以快速恢复数据。
2.数据质量监控:实施数据质量检测和监控,对数据仓库中的数据进行清洗、整合和校验,以保证数据准确性。
3.分布式架构:采用分布式存储和计算架构,确保数据仓库的扩展性和弹性。在遇到大量请求或负载增加时,可以自动扩展资源来应对。
4.容错机制:实施容错机制,确保在单个节点发生故障时,任务可以继续执行。例如,使用Hadoop等大数据处理框架,它们自带容错和恢复机制。
5.监控与报警:对任务的执行状态进行实时监控,发现异常时及时报警,便于快速诊断和处理问题。
6.任务调度优化:使用任务调度工具(如Apache Airflow、Azkaban等)对任务进行合理的调度,避免任务之间的资源竞争,确保任务按照预期执行。
7.代码质量管理:对开发团队进行代码审查,确保代码质量高,减少因代码问题导致的任务失败。
8.文档和知识库:建立完善的文档和知识库,确保团队成员对系统有深入理解,便于解决问题和提高工作效率。
通过以上措施,可以有效地保证离线数仓任务的稳定性。同时,持续优化和改进系统架构,以适应不断变化的业务需求和技术挑战,是确保离线数仓任务稳定性的关键。

面试题51:flink ttl的几种策略?

根据程序的运行时间,我们的状态是不断的积累,占用的空间越来越多,当达到内存瓶颈时,容易出现OOM。
 因此引入了TTL特性,对作业的状态(state)进行清理。
 自flink1.8后,一共有三种ttl清理策略。
 1、全量快照清理策略(cleanupFullSnapshot):
  是针对checkpoint/savepoint全局快照的。
  当快照过期,并不会删除。等待重启checkpoint/savepoint时,才会删除过期的
                全局快照状态。过期时间是在代码中设置。
 2、清理增量策略(cleanupIncrementally) 
  是针对状态后端的。
  存储后端会为状态条目维护一个惰性全局迭代器。每次触发时,就会向前迭代删
                除已遍历的数据。过期的数据是根据代码来设置。
  .cleanupIncrementally(5false) 第一个参数条目数量,第二个参数是是否删除
 3、RocksDB过滤器清理策略(cleanupInRocksdbCompactFilter):
  Flink会异步对RocksDB的状态进行压缩合并更新,减少存储空间。
  对Flink条目进行清理达到1000条,会检查当前的条目是否处于属于过期状态。
  如果是过期状态会进行删除。
  .cleanupInRocksdbCompactFilter(1000)

面试题52:Doris中的视图和物化视图有啥区别?

视图:
 视图(view),也称虚表, 不占用物理空间,这个也是相对概念,因为视图本身的定义语句还是要存储在数据字典里的。视图只有逻辑定义。每次使用的时候, 只是重新执行SQL。视图是从一个或多个实际表中获得的,这些表的数据存放在数据库中。那些用于产生视图的表叫做该视图的基表。一个视图也可以从另一个视图中产生。视图的定义存在数据库中,与此定义相关的数据并没有再存一份于数据库中。通过视图看到的数据存放在基表中。视图看上去非常象数据库的物理表,对它的操作同任何其它的表一样。

物化视图:
 物化视图用于预先计算并保存表连接或聚集等耗时较多的操作的结果,这样,在执行查询时,就可以避免进行这些耗时的操作,从而快速的得到结果。物化视图有很多方面和索引很相似:使用物化视图的目的是为了提高查询性能;物化视图对应用透明,增加和删除物化视图不会影响应用程序中SQL 语句的正确性和有效性;物化视图需要占用存储空间;当基表发生变化时,物化视图也应当刷新。   

区别:

作用不同
视图是为了简化复杂查询,比如如果需要经常执行某项复杂查询,可以基于这个复杂查询建立视图,此后查询此视图即可,简化复杂查询;
物化视图是将预先计算(根据定义好的 SELECT 语句)好的数据集,存储在 Doris 中的一个特殊的表。以起到查询加速的目的

本质不同
视图只是一张虚拟表,通过用户定义的一个查询方式作为另外一个集合,后续用户直接访问该集合即可而不用管该集合的实现逻辑
物化视图的本质是基于原表的一个子表,数据在导入时,会按照构建物化视图创建的逻辑,将数据冗余存储在这个子表对应的存储空间。当查询命中物化视图的逻辑的时候,就可以直接利用提前进行过预处理的物化视图的结果为查询加速。

刷新方式不同
每当用户去查询视图的时候,内部会将用户查询基于视图的创建转化为另外一个查询去做SQL查询,因此可以理解不存在刷新概念
物化视图是当数据在导入的时候就会发生实时的更新,新导入的数据会不断的按照用户的定义逻辑更新到物化视图当中,因此创建多个物化视图的时候会严重影响数据导入速度

面试题53:HDFS读写流程?

HDFS写数据
    1. 客户端发出请求 
    2. namenode查看维护的目录结构,检查data是否存在,如不存在直接报错”,如存在返回给客户端同意上传文件请求,将操作写入日志文件
    3. 客户端请求上传第一个块,询问namenode块的存储位置
    4. namenode查看自己的datanode池,返回给客户端一个datanode列表
    5. 客户端发出请求建立pipeline
    6. 客户端先把文件写入缓存,达到一个块的大小时,会在客户端和第一个datanode建立连接开始流式 的传输数据,这个datanode会一小部分一小部分的接收数据然后写入本地仓库,同时会把 这些数据传输到第二个datanode,第二个datanode也同样一小部分一小部分的接收数据并写入本 地仓库,同时传输给第三个datanode... (在流式复制时,逐级传输和响应采用响应队列来等待传输结果。队列响应完成后返回给客户端)
    7. 第一个数据块传输完成后会使用同样的方式传输下面的数据块直到整个文件上传完成。
    8. 整个文件完成,namenode更新内存元数据
img
img
HDFS读数据
    1. 客户端向namenode发起RPC调用,请求读取文件数据。
    2. namenode检查文件是否存在,如果存在则获取文件的元信息(blockid以及对应的datanode列 表)。
    3. 客户端收到元信息后选取一个网络距离最近的datanode,依次请求读取每个数据块。客户端首先 要校检文件是否损坏,如果损坏,客户端会选取另外的datanode请求。
    4. datanode与客户端建立socket连接,传输对应的数据块,客户端收到数据缓存到本地,之后写入 文件。
    5. 依次传输剩下的数据块,直到整个文件合并完成。
img
img

面试题54:如何理解spark 广播变量与闭包?

闭包是指在一个函数中引用了外部变量的函数。在分布式计算中,闭包可以帮助我们将函数和它所引用的外部变量一起传递给远程节点上的任务。在 Spark 中,闭包主要用于在 RDD 的转换操作(如 map、filter 等)中传递函数。

任务闭包包含了任务所需要的代码和数据,如果一个 executor 数量小于 RDD partition 的数量,
那么每个 executor 就会得到多个同样的任务闭包,这通常是低效的。
多个task都有一份只读的少量数据,如果数据量大,则用广播变量,减少内存消耗
闭包引用的对象必须实现序列化接口,否则报错Task not serializable.
闭包的本质:代码块+上下文

广播变量:通过缓存变量副本到每个节点上从而减少数据传输。
在driver端利用广播变量,executor端使用,使用广播变量能保证一个 executor 中的所有的 task 共用一份数据。
减少了数据的反序列化和 GC

什么时候使用广播变量:
中间数据,应用数据,需要广播。知识库的数据
数据特点:数据稳定,数据量不大,数据会被频繁使用

广播变量使用时注意事项:
1, 除了 RDD 不能被广播之后,其他的类/集合/对象等都可以广播
2, 被广播的数据,可以在任意的 executor 中通过.value 调用
3, 广播变量是只读的,不能修改
4, 最大的功能,就是保证一个 executor 中的所有的 task 共用一份数据,提升效率

总结:Spark 中的广播变量和闭包分别解决了数据共享和函数传递的问题

面试题55:hive/spark数据倾斜调优?

hive/spark数据倾斜调优?
数据倾斜根本问题存在于key的分布不均,在进行shuffle的时候,必须将各个节点上相同的key拉取到某个节点上的一个task来进行处理,比如按照key进行聚合或join等操作。此时如果某个key对应的数据量特别大的话,就会发生数据倾斜
    参数层面 
        hive
            sethive.auto.convert.join = true; (是否自动转化成Map Join)
            sethive.map.aggr=true; (用于控制负载均衡,顶层的聚合操作放在Map阶段执行,从而减轻清洗阶段数据传输和Reduce阶段的执行时间,提升总体性能,该设置会消耗更多的内存)
            sethive.groupby.skewindata=true; (用于控制负载均衡,当数据出现倾斜时,如果该变量设置为true,那么Hive会自动进行负载均衡)
            sethive.merge.mapfiles=true;  (用于hive引擎合并小文件使用)
            set mapreduce.map.memory.mb=4096;   (设置Map内存大小,解决Memory占用过大/小)
            setmapreduce.reduce.memory.mb=4096;(设置Reduce内存大小,解决Memory占用过大/小)

        spark
            setspark.sql.adaptive.enabled=true;(是否开启调整Partition功能,如果开启,spark.sql.shuffle.partitions设置的Partition可能会被合并到一个Reducer里运行。平台默认开启,同时强烈建议开启。理由:更好利用单个Executor的性能,还能缓解小文件问题)
            setspark.sql.hive.convertInsertingPartitionedTable=false;(解决数据无法同步Impala问题,使用Spark3引擎必填)
            setspark.sql.finalStage.adaptive.advisoryPartitionSizeInBytes=2048M;(Spark小文件合并)


    map阶段层面
        剪裁列和剪裁行
            减少全表 全字段查询

        条件限制
            查询一定要带分区字段,子查询需要先限制分区再限制时间及条件限制,减少非必要数据输入

        distribute by rand()
            distribute by :用来控制map输出结果的分发,即map端如何拆分数据给reduce端。 会根据distribute by 后边定义的列,根据reduce的个数进行数据分发,默认是采用hash算法。当 distribute by 后边跟的列是:rand()时,即保证每个分区的数据量基本一致。


    reduce阶段层面
        group by
            distinct 改为group by   count(distinct)改成 count() from (group by)因为distinct是按distinct字段排序,一般这种分布方式是很倾斜的,group by是多次reduce

        笛卡尔积优化
            1对多关联导致倾斜

        大key的过滤
            先过滤再计算

        大key重组计算
            将大key打上随机值计算,再去除进行重组

        map join
            map join会把小表全部读入内存中,在map阶段直接拿另外一个表的数据和内存中表数据做匹配,由于在map是进行了join操作,省去了reduce运行的效率也会高很多mapjoin还有一个很大的好处是能够进行不等连接的join操作,如果将不等条件写在where中,那么mapreduce过程中会进行笛卡尔积,运行效率特别低,如果使用mapjoin操作,在map的过程中就完成了不等值的join操作,效率会高很多。


    其他层面
        小文件优化
            对于分区较多使用Spark3进行动态分区刷新
            对于分区较少或未分区的表采用重建表,补数据方法回刷
            小文件预防:
                (1)使用Spark3引擎,自动合并小文件
                (2)减少Reduce的数量(可以使用参数进行控制)
                (3)用Distribute By Rand控制分区中数据量
                (4)添加合并小文件参数 
                (5)将数据源抽取后的表做一个任务(本质也是回刷分区合并小文件任务)去处理小文件保障从数据源开始小文件不向下游流去


        z-order 
            Z-Order是一种可以将多维数据压缩到一维的技术,在时空索引以及图像方面使用较广,比如我们常用order by a,b,c 会面临索引覆盖的问题,Z-Order by a,b,c 效果对每个字段是对等的

        spark3切换使用aqe
            aqe解释:Spark 社区在 DAGScheduler 中,新增了一个 API 在支持提交单个Map 阶段,以及在运行时修改 shuffle 分区数等等,而这些就是 AQE,在 Spark 运行时,每当一个 Shuffle、Map 阶段进行完毕,AQE就会统计这个阶段的信息,并且基于规则进行动态调整并修正还未执行的任务逻辑计算与物理计划(在条件运行的情况下),使得 Spark 程序在接下来的运行过程中得到优化。
   
 spark的数据倾斜通用解决方案:
        使用Hive ETL预处理数据
  过滤少数导致倾斜的key
  提高shuffle操作的并行度
  两阶段聚合(局部聚合+全局聚合)
  将reduce join转为map join(广播大变量)
  采样倾斜key并分拆join操作
  使用随机前缀和扩容RDD进行join
  自定义分区器

面试题56:数据治理相关的治理项和推进?

治理工作你们是如何对接下游推进的
    我们从3个点出发,
 1.让下游配合最重要的是调动积极性,让下游感觉到治理能对他们起作用 或者说能让业务方也能做大蛋糕,因为数据治理对于下游来说可有可无 没你数据治理 下游数据模型不也跑的没问题嘛,所以就如花姐刚才说的该警告的警告 该配合的配合,但这个警告也只是表面你可以从费用分摊上去说,也可以从下游痛点去说,共同做好保障措施,让他们也能分到项目大家一起分蛋糕(下游肯定有需要治理的点,其中最痛的是数据质量)
 2.除了这些还可以加一些奖惩措施比如我之前说的解决dq吃dq的活动,让下游觉得配合是有价值的
 3.还可以做到更大的推进作用,比如我们在和bi一起做治理等起了一定规模后可以发治理效果月报/周报 发送全部门,让其他部门也有感知



具体治理的点(模型合规、安全合规、数据质量、计算&存储资源、人员roi、数据价值)是从哪些小点去考虑,具体要做哪些事情
    模型合规(包括了元数据治理,原来只到了元数据层次):
 1.数据标准重制定及修复,包括对原来数据域重构,表字段命名体系重构,并对原来模型按照新标准合规改造  
 2.元数据补充 owner、使用说明、字段中文名具体内容、颗粒度声明、主键声明等补充保障下游及内部使用时候清晰 
 3.制度建设:完善模型评审制度、代码提交强审核,保障内容合规后上线 
 4.分层合理性,治理不规范的模型分层引用,例如ADS层表依赖了非DWS层的表,建议优化  
 5.数据链路合理性(本次新补充内容):减少因内容不足产出烟囱模型,从而相互依赖加长链路情况

    数据质量合规:
 1.流程化,任务上线/变更流程,指标变更流程 
 2.dqc管控:对原4大基础dqc进行补充以及核心业务模型dqc补充,并对原无效dqc下线,对常触发dqc进行调整(例如表行数波动,可通过算法对近7天数据量监测) 
 3.sla及基线治理(这里也可以放到人员运维roi治理中):上线前把控,保障基线正常运行,核心任务优先产出且分配高资源,培训及整理值班运维手册,建设容灾备份快恢能力临时修复数据 
 4.上游问题数据治理:数据质量长期监测体系(详情见课程3-数据质量课件)
 
 
    数据安全合规:
 1.角色权限管控,对不同使用/开发角色提供不同使用权限,根据报表、看板的权限等级,在同一个图表中限制不同的用户能够看到的数据也不一样(常用于报表各模块内容展示) 
 2.数据脱敏,通过脱敏防止数据泄漏 
 3.表/字段分级:对每个表及字段进行打标,保障每张表都有数据安全管控 
 4.数据权限使用 表/字段走审批流程 并设置数据使用申请时卡点负责人/组  
 5.其他 数据下载管控(一般来说最多下载1000行/次),离职数据风险管控等等
 
 
    存储资源治理:
 1.设置统一表生命周期,并对当前表按照新标准裁剪,对未分区表重制定分区 
 2.长期未引用/被使用/临时的表下线 
 3.压缩格式/存储格式优化 
 4.根据业务对表存储重划分:对较大数据量表可以采取全量转增量操作、拉链表操作
 
    计算资源治理:
 1.数据倾斜任务治理(后面我会细讲治理方法 这里跳过)
 2.消耗大core/内存任务治理 
 3.无效监控项、重复开发情况占用计算资源、数据价值低的模型占用计算资源及时下线 
 4.梳理数据链路并对任务调度治理 
 5.规划核心任务 并分配任务执行优先级 把非核心的任务靠后运行 
 6.小文件治理 
 7.其他 例如hive spark2 切换spark3采用aqe特性  采用z-order+spark排序算法解决join时读取效果提升
 
    数据价值治理 (整体来说是提升模型复用性):
 1.烟囱数据模型及对应任务、模型粒度重复及时下线 
 2.ads指标下沉到dws  
 3.建立模型价值度指标,持续下线低价值模型 
 4.下线ads层对应业务不再使用的场景模型
 
    人力成本治理(这个可以不说):
 1.指导培训组员技术侧/业务侧能力能够独挡一面,并完善文档沉淀帮助后续新人培训开展 
 2.让熟悉不同数据域的组员安排在合理的数据域范围,同时做backup 
 3.建立相应需求开发流程机制,统计人员产出效率,方便针对性安排后续开发内容
 4.为当前需求及项目难度打分,帮助大家更好意识到项目能否落地、以及产出时间,同时衡量每人产出roi

面试题57:计算资源治理怎么做的(包括数据倾斜优化)?

分析角度
        1.sql优化
        2.表优化(比如z-order、spark3切换、小文件等等)
        3.任务优化(任务流程和服务器资源)
        4.参数优化(shew.join convert join等)

    案例
        场景1:在开发阶段,发现调度中某些任务执行时间过长,导致无法在数据基线前输出结果,需要对任务进行优化
            优化角度:
                1.首先对任务sql进行检查,是否有明显优化项;
                2.后对任务相关的表进行优化;
                3.考虑集群资源方面,从任务流程和集群资源方面进行优化;
                4.相关参数优化(很少使用,有效果的配置很多时候都已经配置好了)

            实际操作过程:
                1.在sql中进行优化,在sql中不使用distinct ,改用group by;在获取数据时列和行未裁剪、分区未限定、Where条件未限定;关联表过多,进行拆分;join关联时,一个表比较小,使用mapjoin,省去了Reduce运行,提高效率;代码结尾添加Distribute By Rand(),用来控制Map输出结果的分发,有效避免数据倾斜;
                2.任务相关表优化:根据表的数据写入和读取,探寻表是否进行分区;表数据进行压缩,我们一般使用gzip,例如:需要多次读写的表需要进行压缩,需要经常进行计算的少压缩;
                3.集群资源方面:从任务流程方面,给每个任务一个优先级,根据任务资源消耗情况和执行时长还有任务本身的紧急度,将任务执行时间进行调整,保障核心任务能平稳运行,减少资源抢占情况;但从集群资源方面考虑,根据实际情况,增加内存、cpu和集群节点,扩大资源池
                4.相关参数优化(较少进行使用):举例:
                    set hive.auto.convert.join = true; (是否自动转化成Map Join)
                    set hive.map.aggr=true; (用于控制负载均衡,顶层的聚合操作放在Map阶段执行,从而减轻清洗阶段数据传输和Reduce阶段的执行时间,提升总体性能,该设置会消耗更多的内存)
                    set hive.groupby.skewindata=true; (用于控制负载均衡,当数据出现倾斜时,如果该变量设置为true,那么Hive会自动进行负载均衡)
                    set hive.merge.mapfiles=true;  (用于hive引擎合并小文件使用)
                    set mapreduce.map.memory.mb=4096;      (设置Map内存大小,解决Memory占用过大/小)set mapreduce.reduce.memory.mb=4096;(设置Reduce内存大小,解决Memory占用过大/小)



        场景2:在数据治理阶段,发现投入产出比不高,需要对模型调度任务进行优化
            问题(列举2-3个,并针对性回答)
                高消耗任务:由于数仓前中期业务扩张,要覆盖大量场景应用,存在大量问题代码运行时数据倾斜,在消耗大量集群计算资源下,产出时间也久
                大量的小文件:当前任务存在未合并小文件、任务Reduce数量过多、上游数据源接入(尤其是API数据接入)会造成过多小文件出现,小文件过多会开启更多数据读取,执行会浪费大量的资源,严重影响性能;
                任务调度安排不合理:多数任务集中在凌晨2-5点执行且该区间CPU满载,导致该时间段资源消耗成了重灾区,所有核心/非核心任务都在争抢资源,部分核心任务不能按时产出一直在等待阶段;
                重复开发任务/无用任务:早期协助下游做了较多烟囱数据模型,因为种种原因,部分任务不再被使用,烟囱模型分散加工导致资源复用率降低;
                数据监控合理化和监控配置资源过小:存在部分历史任务没下线表及DQC场景,每日都在空跑无意义DQC浪费资源,同时DQC资源过少导致DQC需要运行过长时间;
                任务缺少调优参数&部分任务仍然使用MapReduce/Spark2计算引擎:任务缺少调优参数导致资源不能适配及动态调整,甚至线上仍有早期配置MapReduce/Spark2计算引擎导致运行效率较低。

            该怎么开始(跨部门沟通(加分点)及阐述优化顺序)
                初期完成各类元数据接入搭建治理看板以及团队治理产出统计数据模型,目的:让业务部门和领导能够较为直观的感觉到其中的价值(业务部门能直观及时的查看到所需结果,提高模型的抗风险能力)
                对当前治理进行优先级排序,从改动成本大小和难度两个角度进行衡量:简单的参数调优&任务引擎切换开始->小文件治理->DQC数据监控治理->高消耗任务治理->调度安排->下线无用模型及沉淀指标提高模型复用率

            实际操作过程:
                1.设置调优的参数,任务计算引擎的升级和切换(有两套引擎的情况下,例如spark3和spark2)
                2.小文件治理:对于分区较多使用Spark3进行动态分区刷新;对于分区较少或未分区的表采用重建表,补数据方法回刷;
                3.数据监控合理化和监控配置资源过小:无效数据监控下线,监控任务与实际任务一一匹配;由于之前DQC配置资源为集群默认参数,导致部分监控执行缓慢,通常参数调整的方式增加任务可使用资源,提高时效;
                4.高消耗任务、任务调度、集群资源 方案使用场景一的应对方式,进行简单描述
                5.重复开发任务/无用任务:因为模型的完善,部分烟囱表需要下线,要下沉指标到模型中提高模型的复用,前提:元数据的完善、数据


        场景3:查询100亿数据量的表,长时间卡某个节点,运行不动该如何处理
            遇到先看logview找到对应节点表,其次看任务执行引擎,查看执行分区和sql语句如未有问题或笛卡尔积,再看关联是否有小表能map join,那只是单独大key倾斜,通过大key重组先跳过或者打随机数对数据重新分发

面试题58:大促场景下实时链路数据积压,rps为100w,导致数据大屏不动了,上线前该如何保障,临时处理该如何操作,兜底方案该如何做?

        提前做好压测,调整好任务资源(slots、TM内存、JM内存、并发数),利用好flink反压机制,如消费能力不足可以增加分区数同时提升消费组消费者数量,必要时准备实时双链路保障1条链路出问题时,另外一条能够立刻切换,大屏多链路,准备多块不同链路的备屏(保障内容要与主屏不差)能够在主屏挂了后立刻无缝隙切换,其次要准备好数据,当所有大屏都挂了后将上次同样活动数据及时灌入,并在切换后能够及时修复主链路,不被业务方看出问题

面试题59:实时数仓如何保障时效性?

  1:查看kafka延迟监控:flink 消费上游的 lag(比如看消费 kafka lag 情况)
  2:分层和时延之间做好平衡和取舍,既需要保证复用性,又要避免造成链路过长。
  3:乱序数据的处理。
  4:提前压测,应对流量高峰期,特别是大促场景下,提前做好资源保障、任务优化等措施。
  5:设置好延时基线,通过优化程序代码、资源、解决倾斜与反压等问题,使其控制在base line之内。
  6:指标监控,监控任务failover情况、checkpoint指标、GC情况、作业反压等,出现异常告警。
  7:Flink链路延迟监控的LatencyMarker观测延迟情况。

面试题60:实时数仓数据体系保障?

实时数仓保障体系,可分为稳定性保障、数据质量保障两个个方面。
        稳定性保障:
  稳定性保障目前主要从压测、任务等级划分、 监控三方面实施:
  提前压测,应对流量高峰期,特别是大促场景下,提前做好资源保障、任务优化等措施。
  制定保障等级,从任务影响面大小、数据使用方来划分,一般情况公司层面优先于部门层面,外部使用优先于内部使用, 高优先级任务需要优先/及时响应、必要情况下做双链路保障机制;
  指标监控,监控任务failover情况、checkpoint指标、GC情况、作业反压等,出现异常告警。

  数据质量保障:
  质量保障主要是保障数据正确性与时效性。
  正确性实时计算端到端的一致性,对数据正确性的影响,常用手段就是通过输出幂等方式保障,这种方式要求输出使用存储介质支持重写,对于不支持幂等的存储,比较常用的就是DWD层的kafka, 可能会产生重复的数据,那么在下游使用的时候可以使用row_number() 语法进行去重,保证相同的key不会被多次计算;
  离线与实时的一致性,需要保证使用数据源一致、加工业务逻辑一致。
  时效性保障实时指标的时效性,常用的手段就是提前压测与监控。
  提前压测:提前发现可能会影响任务处理速度的瓶颈,常见的就是数据倾斜、大状态的算子操作(join);
  监控:监控任务当前的消费进度,在数据源处通过使用数据时间与当前系统时间对比判断其消费进度。
  未来规划实时DWS层建设当前虽然做了统一DWD层的建设,但是在应用层商家看板、实时特征等的场景应用中,仍然存在重复建设的工作,例如小时维度的商品曝光指标被多个链路重复计算,这种存在数据一致性的风险,另外也会造成资源浪费,可以将公共的汇总指标抽象出来统一计算,建设DWS层。

面试题61:通常都是发现任务超时或者超过基线 然后去处理 问如何在数据量激增 热key不固定的情况下提前发现问题 降低超时风险?

1 上线阶段审核-无论是加字段还是表上线试运行高于1小时且ui上在某个节点卡住的任务都需要优化后才能上线 

2 临时发现问题需要通过经验判断任务发生问题发生情况(基本不好使,谁大半夜能头脑清醒还能在短时间内准时判断) 如果不能看是不是全量的 全量的话用快恢(t-2到t-1),临时解决问题让下游跑起来同时看问题

3 事后复盘 做好规范流程,并且增强夜间值班大家意识,在阿里时候我们夜间值班会有个手册 让所有值班同学能立刻定位问题

面试题62:业务要求 你两天内必须出报表 ,实际分层开发需要五天,并且要完成数据测试,请问您怎么解决 ?

    0.5天了解业务,1天写代码建模型直接从ods到ads产出数据并且这里先做ads 支持bi看板搭建同时进行 ,等看板完事+模型开发完,0.5天数据测试

面试题63:如果你从之前的行业换到现在这个行业,不用的业务,你是怎么快速学习融入的?

    入职后先去看部门核心数据表(强烈建议看dwd),从明层数据模型反推业务环节和ods表再与上游后端同学,下游数据分析同学沟通学习,如果部门有业务文档沉淀则去看文档,如没有需要如上内容交流沟通,还可以去使用app,作为用户去体验业务流程

面试题64:给你一个业务场景你如何0-1初步建设离线数仓(从leader角度出发)?

初始期(一般来说只讲出始期)
  1.明确组织架构业务流程及内容
  2.根据业务场景制定架构方向及技术栈选型或者买平台具体资源要根据部门预算调整  
  3.对当前业务梳理 明确数据源及数据域、主题域划分
  4.确定一期要做的大方向 数据版图梳理okr制定 
  5.业务及主题域命名规范、数仓分层规范、元数据规范、模型建设规范、流程制定制定 
  6.确认核心指标口径,完成核心数据表接入及模型建设ods->dwd->dws 
  7.根据业务场景完成应用层场景数据模型建设支撑下游1期的专题报告及看板搭建
 
 扩张期
 治理期(缓慢发展期)
 变革期

面试题65:scala函数和方法的区别?

Scala中,函数和方法有一些区别,尽管它们在很多方面非常相似。下面是它们之间的主要区别:

定义方式:函数可以独立定义,而方法必须依附于类或对象的上下文中。

调用方式:函数可以直接调用,而方法必须通过类或对象进行调用。

声明:函数可以在任何地方声明,而方法只能在类、对象或特质中声明。

参数传递:函数可以接受参数,也可以没有参数,而方法必须至少有一个隐式参数列表,即使没有显式参数。

可见性:函数可以具有任何可见性(public、privateprotected等),而方法受类或对象的可见性规则限制。

返回值类型推断:函数的返回值类型可以根据函数体中的表达式进行推断,而方法必须显式地声明返回值类型。
                函数可以使用函数式编程的特性,如高阶函数、柯里化等,而方法则不能。

面试题66:hadoop3新特性?

1. 最低要求的Java版本从Java 7增加到Java 8
现在,已针对Java 8的运行时版本编译了所有Hadoop JAR。仍在使用Java 7或更低版本的用户必须升级到Java 8

2. 支持HDFS中的纠删码
纠删码是一种持久存储数据的方法,可节省大量空间。与标准HDFS副本机制的3倍开销相比,像Reed-Solomon(10,4) 这样的标准编码的空间开销是1.4倍。

由于纠删码在重建期间会带来额外的开销,并且大多数情况下会执行远程读取,因此传统上已将其用于存储较冷,访问频率较低的数据。

在部署此功能时应考虑纠删码机制的网络和CPU开销。

3. Shell脚本重写
Hadoop Shell脚本已被重写,以修复许多长期存在的错误并包括一些新功能。Hadoop的开发人员尽管一直在寻求兼容性,但是某些更改可能会破坏现有的安装。

4. MapReduce 任务本地优化
MapReduce 增加了对 map output 收集器的本地执行的支持,对于 shuffle 密集型工作,这可以使性能提高30%或更多。

5. 支持两个以上的 NameNode
在之前的版本中,HDFS的高可用最多支持两个NameNode。在HDFS 3.x 版本中,通过将编辑复制到法定数量的三个JournalNode,该体系结构能够容忍系统中任何一个节点的故障。
但是,某些部署需要更高的容错度。这个新特性启用了这一点,该功能允许用户运行多个备用NameNode。例如,通过配置三个NameNode和五个JournalNode,群集可以忍受两个节点的故障,而不仅仅是一个节点的故障。

6. 多个服务的默认端口已更改
以前,多个Hadoop服务的默认端口在Linux临时端口范围内(32768-61000)。这意味着在启动时,服务有时会由于与另一个应用程序的冲突而无法绑定到端口。
这些冲突的端口已移出临时范围,具体的端口更改如下:
NameNode 的端口: 50070 --> 98708020 --> 982050470 --> 9871;
Secondary NameNode 的端口: 50091 --> 986950090 --> 9868;
DataNode 的端口: 50020 --> 986750010 --> 986650475 --> 986550075 --> 9864;
Hadoop KMS 的端口: 16000 --> 9600HBaseHMaster端口号与Hadoop KMS端口号冲突。两者都使用16000,因此 Hadoop KMS 更改为9600)。

7. 支持Microsoft Azure数据湖和阿里云对象存储系统文件系统连接器
Hadoop现在支持与Microsoft Azure数据湖和Aliyun对象存储系统集成,作为与Hadoop兼容的替代文件系统。

8. 数据内节点平衡器
单个DataNode可管理多个磁盘。在正常的写操作过程中,磁盘将被均匀填充。但是,添加或替换磁盘可能会导致DataNode内部出现严重偏差。原有的HDFS平衡器无法处理这种情况。新版本的HDFS中有平衡功能处理,该功能通过hdfs diskbalancer CLI调用。

9. 基于HDFS路由器的联合
基于HDFS路由器的联合添加了一个RPC路由层,该层提供了多个HDFS名称空间的联合视图。这简化了现有HDFS客户端对联合群集的访问。

10. YARN资源类型
YARN资源模型已被通用化,以支持用户定义的CPU和内存以外的可计数资源类型。例如,集群管理员可以定义资源,例如GPU,软件许可证或本地连接的存储。然后可以根据这些资源的可用性来调度YARN任务。

面试题66:如何确定一个业务过程中的维度,以及如何设计多层次的维度结构?

确定业务过程中的维度需要考虑以下因素:
  业务需求:维度应该围绕业务需求展开,采用与业务过程相匹配的维度。例如,在销售业务中,时间、地点、产品、客户等可以作为关键维度。
  数据可用性和完整性:维度必须是可用和完整的数据元素,能够反映实际情况。如果缺少任何一个核心元素,则可能会影响对业务过程的分析和理解
  数据标准化:使用标准的格式和定义来描述维度元素,以确保在数据仓库中具有一致性和可比性。

设计多层次的维度结构需要考虑以下因素:
  维度属性:确定每个维度有哪些属性,包括哪些属性是可分层次的。
  层次结构:设计每个层次之间的关系,如父节点和子节点的关系。
  层次粒度:确定每个层次的粒度,并确保每个层次都有一个明确的粒度定义。
  聚合规则:针对每个层次的聚合规则进行定义,以确保正确的聚合结果。
  维度表连接:对于多层次的维度结构,需要通过多个维度表之间的连接进行操作和查询。
  数据建模工具:使用数据建模工具对多层次的维度结构进行建模和实现。

总的来说,确定业务过程中的维度和设计多层次的维度结构需要根据具体的业务需求和数据特征进行综合分析和设计,以确保数据的准确性和完整性,并为企业提供更好的决策支持。

面试题67:如何选择事实表的粒度?请举例说明。

选择事实表的粒度需要根据具体业务需求和数据特征进行综合分析和设计。一般来说,事实表的粒度应该既不过细也不过粗,而是能够充分反映业务过程中的核心指标。
在选择事实表粒度时,应考虑以下因素:
  业务需求:应根据业务需求选择粒度,以确保度量指标能够反映出业务过程的本质特征。
  数据可用性和完整性:选取的粒度必须是可用和完整的数据元素,能够反映实际情况。
  数据存储和处理成本:选择过大的粒度会增加数据存储和处理成本,而选择过小的粒度则可能会导致数据量过大,影响查询效率。

例如,在销售业务中,可以选择以订单为粒度,记录每个订单的销售额、销售数量、销售时间等相关信息。这样的粒度可以很好地反映出销售业务的核心指标,且不会造成数据存储和处理上的大量浪费。另外,在库存管理业务中,可以选择以日为粒度,记录每天的销售量、进货量、退货量等核心指标,以反映该业务的运营状态。
总之,在选择事实表的粒度时,需要结合具体业务需求和数据特征进行设计,并要注意避免过细或过粗的粒度,以确保数据仓库的有效性和高效性。

面试题68:.如何处理缺失维度数据和重复数据?

处理缺失维度数据的方法:
  默认值填充:如果某些维度缺失,可以将其用默认值填充,例如用“未知”、“其他”等代替缺失值。
  外部关联:如果可以从其他数据源获取相关信息,则可以通过外部关联来进行补充。例如,可以通过邮编查询关联城市、区域等信息。
  删除数据:如果缺失的数据影响不大,或者比例较小,则可以删除这些数据行或列。但在做出决策之前一定要确认删除这些数据是否会导致后续分析结果不准确。

处理重复数据的方法:
  去重:去除完全相同的数据记录。
  合并数据:如果存在部分字段相同但不完全相同的数据记录,可以考虑将这些记录合并成一个记录,例如求和、平均等聚合函数操作。
  保留最新数据:如果数据记录是时间序列的,可以根据时间戳保留最新的数据记录,同时排除掉旧的数据记录。
  人工判断:对于少数重复数据无法自动处理的情况,可以通过人工判断来进行处理。例如,对于姓名、地址等字段较为相似的数据记录,需要人工进行核实和确认。

面试题69:如何评估数据建模的性能和效果?如何优化数据建模的性能?

数据建模的性能和效果评估通常需要考虑以下几个方面:
  数据仓库查询性能:这是衡量数据建模效果的关键指标之一。如果查询时间很长,用户体验就会变差,导致不良的商业决策。因此,需要评估查询性能并确定如何优化。
  数据中断率:如果数据仓库经常出现数据中断或故障,那么整个系统的效果就会下降。因此,需要定期检查数据中断率并采取必要的措施进行修复和预防。
  数据一致性:在数据建模过程中,需要确保数据仓库与源系统之间的数据始终保持一致,以便提供准确的分析结果。因此,需要评估数据一致性并确保它得到维护。
  数据质量:数据建模的性能和效果也受数据质量的影响。如果数据存在错误、缺失、重复等问题,则可能导致分析结果不准确。因此,需要评估数据质量并采取相应的措施来修复和预防这些问题。
  数据安全性:数据安全性是保护数据不受未授权访问和攻击的关键因素。因此,需要评估数据安全性并采取必要的安全措施保护数据。

为了优化数据建模的性能,可以采用以下方法:
  精简数据模型:简化数据模型,删除不必要的表和字段,使查询时间更快。
  优化索引:根据查询需求优化索引,增加索引以提高查询性能。
  优化 ETL 程序:通过调整 ETL 程序来减少数据处理时间,同时避免对源系统造成过大的负载。
  数据压缩:对数据进行压缩可以减小存储空间,同时提高查询速度。

总之,数据建模的性能和效果评估是数据仓库开发中非常重要的一步。通过评估查询性能、数据一致性、数据质量、数据安全性等因素,并采取相应的优化措施,可以最大限度地提高数据建模的性能和效果。

面试题70:请描述您在以前的项目中如何设计数据建模方案,并解释它的优缺点?

一般来说,数据仓库建模的设计需要考虑以下几个方面:
1.确定业务需求:根据业务需求选择合适的建模方法以及建模粒度。
2.设计数据模型:使用实体关系图(ERD)将各种实体、属性和关系进行建模。
3.选择ETL工具:使用ETL工具从源系统抽取、转换和加载数据到数据仓库中。
4.进行物理建模:基于数据模型设计数据库中的表结构、列定义、主键、外键等。
5.优化查询性能:使用索引、分区、聚簇等技术优化查询性能。
6.测试和验证:通过测试和验证确保建模方案的正确性和可靠性。

优点:
数据仓库建模可以提供一致性和标准化的数据视图,使企业能够更好的监控和管理业务。
建模过程中可以对数据进行清洗、整合和转换,提高数据质量。
数据仓库建模可以支持灵活的数据查询和分析。

缺点:
数据仓库建模需要耗费大量时间和资源,需要充分评估商业价值和成本效益。
数据仓库建模可能会受到数据来源变化或新需求的影响,需要维护和更新。
数据仓库建模需要专业的技术知识和经验,难度较高。

面试题71:什么是粒度?为什么粒度很重要?如何确保粒度的正确性?

粒度是指数据被分组、聚合或汇总的程度。在数据仓库中,粒度通常是通过对事实表进行分组和聚合来定义的。例如,在销售数据中,每个订单可能包含多个产品和销售金额,如果按照订单进行聚合就是以订单为粒度,而如果按照每个产品和销售金额进行聚合就是以产品为粒度。
粒度非常重要,因为它决定了我们可以从数据仓库中获得的信息深度和准确性。粒度过大会导致丢失细节信息,难以进行详细的分析,而粒度过小则会增加查询的复杂度和计算量,并且可能会占用大量存储空间。因此,正确的粒度设计需要根据业务需求平衡这些因素。

确保粒度的正确性需要考虑以下几点:
 需要明确定义粒度,确保各个部门和人员使用相同的定义。
 粒度应该符合业务需求和分析要求,需要对业务模型和数据模型进行深入理解。
 在建立事实表时应该注意粒度的一致性,避免出现错误的汇总方式。
 在ETL过程中需要对数据进行清洗和转换,确保数据的一致性和准确性,避免粒度不一致的情况。
 在数据仓库查询和分析时需要认真选择粒度,确保能够满足分析要求并提高查询效率。

面试题72:如何应对数据建模中的一些变更,例如业务需求的变化、数据源的变化等?

在数据建模过程中,变化是不可避免的。以下是一些应对数据建模变化的方法:
1:及时响应业务需求变化:业务需求的变化可能导致数据建模的改变,因此需要及时响应并进行相应的修改。
2:保持灵活性:在设计数据模型时,可以考虑采用灵活的架构和设计,以便在变化发生时能够更容易地进行调整。
3:采用标准化的设计:使用标准化的设计可以使数据建模更加稳定和可维护,从而更容易适应变化。
4:建立变更管理流程:建立变更管理流程可以确保在进行任何更改之前,没有疏漏或错误,并确保更改得到了适当的批准和记录。
5:使用版本控制软件:使用版本控制软件可以记录数据模型的历史变化,并使回滚和恢复变得更加容易和可靠。
6:监测数据源变化:监测数据源的变化可以及时发现与数据建模不符的情况,从而更快地进行调整。

总之,在数据建模中,变化是不可避免的,因此需要采取相应的方法来应对。为了适应变化,需要保持灵活性、采用标准化设计、建立变更管理流程、使用版本控制软件等,以确保数据模型的稳定性和可维护性。

面试题73:如何解决数据建模中的一些挑战,例如复杂的业务规则、数据粒度的把控等?

在数据建模过程中,可能会遇到很多挑战,例如复杂的业务规则、数据粒度的把控等。以下是一些解决这些挑战的方法:
1:深入了解业务需求:复杂的业务规则是数据建模中的一个重要挑战,因为它们可能包含大量的条件和限制。为了解决这个问题,需要深入了解业务需求,并与业务专家合作进行详细的讨论和分析。
2:使用标准化的术语和定义:在数据建模中,使用标准化的术语和定义是非常重要的,因为它可以消除歧义和不必要的复杂性。建议采用行业标准和最佳实践来确定术语和定义,并确保所有参与者都了解和遵守这些标准。
3:把握数据粒度:数据建模中正确把握数据粒度是至关重要的,因为它直接影响到数据分析的结果。建议从实际业务需求出发,根据不同级别的数据粒度设计相应的数据模型,以确保数据的完整性和准确性。
4:分阶段设计:在处理复杂的业务规则时,建议将数据建模分成多个阶段进行设计,以便逐步深入了解业务需求并逐步完善数据模型。
5:合理使用工具和技术:在解决数据建模的挑战时,可以考虑使用各种工具和技术,例如数据建模工具、业务流程管理工具、UML建模等。这些工具和技术可以使数据建模更加高效和准确。

面试题74:如何处理周期性数据?请举例说明?

处理周期性数据通常需要考虑以下几个方面:
 1:选择合适的时间粒度:根据业务需求和数据量大小,选择合适的时间粒度进行分析,例如日、周、月、季度或年等。
 2:平滑处理:对于周期性波动较大的数据,可以使用平滑处理方法,例如移动平均、指数平滑等方法,以便更好地观察趋势和周期性变化。
 3:季节性调整:如果数据中存在明显的季节性变化,可以使用季节性调整方法,例如季节性因子法或回归分析法等方法,以消除季节性的影响。

举例来说,假设我们要处理一家零售店的销售数据,并发现其中存在明显的季节性变化。我们可以按照以下步骤进行:
 1:选择合适的时间粒度:根据业务需求和数据量大小,选择月度作为时间粒度进行分析。
 2:平滑处理:对于每个月的销售数据,可以使用移动平均或指数平滑等方法进行平滑处理,以便更好地观察销售趋势和周期性变化。
 3:季节性调整:对于已经平滑处理过的销售数据,可以使用季节性因子法进行季节性调整,以消除季节性的影响,得到更准确的销售趋势和预测结果。

通过以上步骤,我们可以更好地处理周期性数据,找出隐藏在数据中的规律和趋势,并为业务决策提供更有力的支持。

面试题75:如何进行增量更新?请介绍一下增量更新的策略。

增量更新是指在数据仓库中仅更新已经发生变化的数据,而不是对整个数据进行重新加载。这种方式可以大大减少更新时间和成本,并且可以确保数据的一致性和准确性。以下是几种常见的增量更新策略:

1:增量抽取(Incremental Extract):从源系统中仅提取新增、修改或删除的数据,避免全量抽取,从而减少数据传输和处理时间。
2:增量装载(Incremental Load):将增量数据与已有数据合并,只更新已经发生变化的行或列,避免对整个数据仓库进行重新加载。
3:增量更新(Incremental Update):将增量数据与已有数据进行匹配和比较,找出已经发生变化的行或列,然后只对这些数据进行更新。
4:增量删除(Incremental Delete):将需要删除的数据标记为已删除状态,而不是直接从数据仓库中删除,这样可以避免对已经存在的数据造成影响。

以上策略可以根据具体情况进行组合和调整,以适应不同的业务需求和数据更新频率。同时,在实施增量更新时,还需要注意数据的一致性和准确性,并确保增量更新过程的可靠性和稳定性。

面试题76:如何设计增量更新策略?如何应对数据源变化和数据质量问题?

设计增量更新策略的目的是将数据仓库中的数据与源系统中的数据保持同步,避免数据过期和不准确。以下是一些常用的增量更新策略:
 1:根据时间戳更新:通过比较源系统中的时间戳和数据仓库中的时间戳来判断哪些数据需要更新。
 2:根据版本号更新:将源系统中的每个记录都分配一个唯一的版本号,当源系统中的记录发生变化时,版本号也会发生变化,并且与数据仓库中的版本号进行比较,以确定哪些记录需要更新。
 3:增量抽取:仅抽取源系统中发生变化的数据,并将其合并到数据仓库中,避免对整张表进行全量更新。

在处理数据源变化和数据质量问题时,可以采取以下措施:
 1:监控数据源:及时监测数据源变化,如新增、删除或更新字段等,并及时更新数据仓库的元数据,保证数据仓库的正确性。
 2:数据清洗:在ETL过程中,应该对数据进行规范化、去重、转换和格式化等数据清洗操作,保证数据质量。
 3:数据验证:在更新数据仓库之前,应该对数据进行验证,确保数据的完整性、准确性和一致性。
 4:异常处理:对于异常数据,例如无法解析或者格式错误的数据,应该及时标记并进行处理。
 5:数据回滚:在进行数据更新时,应该备份原始数据,以防万一出现问题,可以随时回滚。

总之,在建立数据仓库的过程中,需要注重数据质量控制和数据源监控,同时采取合适的增量更新策略,确保数据仓库中的数据与源系统保持同步和一致。

面试题77:如何衡量和提升数据质量?提供一些具体的数据质量评估指标和方法。

数据质量是指数据是否准确、完整、一致、可靠和有效,对于数据仓库的建设来说,数据质量的高低直接关系到业务分析的精度和决策的正确性。以下是一些常用的数据质量评估指标和方法:
  准确性:数据是否正确无误,可以根据对比与外部数据源的一致性来衡量。
  完整性:数据是否完整,不缺失重要的信息,可以通过缺失值比例、缺失值位置等指标来评估。
  一致性:数据是否一致,同一个实体的数据是否相同,可以通过验证数据库中唯一键值的重复率来进行评估。
  可靠性:数据是否可靠,数据来源是否可信、数据是否被篡改等,可以通过数据审计和数据元数据管理来评估。
  实时性:数据是否及时,数据更新频率、数据过期时间等指标可以衡量数据的实时性。
  格式规范性:数据是否符合统一的格式规范,例如日期格式、数字格式等,可以通过数据清洗操作来实现。

提升数据质量的方法包括:
  数据清洗:对数据进行去重、转换、格式化、规范化等操作,以提高数据的准确性和一致性。
  数据验证:在进行ETL操作之前,先对数据进行验证,确保数据的完整性和正确性。
  数据审计:对数据进行审计,记录数据变更、访问历史等信息,以确保数据的可靠性和安全性。
  数据质量监控:设置数据质量监控指标,如数据更新频率、异常数据比例等,并及时发出预警提醒。
  数据管理:建立数据字典、数据目录、数据分类体系等,加强对数据的管理,提高数据的可发现性和可用性。

总之,提升数据质量需要一系列的工具和流程支持,需要结合具体业务场景,采取适当的措施,从而有效地提高数据质量。

面试题78:如何处理维度数据缺失的情况?提供一些具体的解决方案。

维度数据的缺失可能会导致查询和分析结果不准确,并且会影响决策的正确性。处理维度数据缺失的方法包括以下几个方面:
  1:人工修复:如果数据量较小,可以通过手动输入或其他手段进行修复。
  2:默认值填充:对于一些确定的属性,可以使用默认值来填充缺失的数据,例如把地址缺失的记录设置为“未知”。
  3:聚合替代:利用现有数据的特点对缺失的数据进行推测,例如根据地理位置、时间等因素对缺失的销售额进行估算。
  4:外部数据补充:可以考虑从外部数据源中获取相应的维度数据,如从第三方数据提供商、社交网络等获取。
  5:建立新类别:对于分类变量,可以将缺失的记录归为一个新的类别,如“未知”或“其他”。
  6:使用机器学习算法预测:可以使用机器学习算法,如回归模型或聚类算法来预测缺失的数据。
总之,在处理维度数据缺失时需要根据具体情况采用合适的方法,并尽量避免对数据精度的影响。同时,在建立数据仓库的过程中,也要注重数据质量控制,减少数据缺失的可能性。

面试题79:如何设计增量更新策略,防止数据出现重复?

为了防止数据出现重复,我们需要设计一个合理的增量更新策略。具体的实现方法如下:
 1:标识每个数据记录:对于需要进行增量更新的表,可以添加自增主键或者唯一标识符,这样可以避免相同的数据记录被多次插入。
 2:增量更新的条件:在进行增量更新时,要根据某些特定的条件来判断数据是否已经存在。例如,在更新订单信息时,可以判断订单号是否已经存在。
 3:逐条比较:在进行增量更新时,可以采用逐条比较的方式,即将待更新的数据和目标表中的数据进行一一比较。如果数据已经存在,则进行更新操作;否则进行插入操作。
 4:使用时间戳:在数据表中添加时间戳字段,表示该数据记录的最后修改时间。在进行增量更新时,只处理时间戳比当前时间更晚的数据记录。
 5:进行批量更新:对于大规模的数据更新操作,可以采用批量更新的方式,将需要更新的数据进行分批次处理,减少系统负载和内存占用,并且提高效率。
总之,设计增量更新策略时,需要考虑数据的唯一性、比较时间戳等因素,以确保数据不会出现重复。

面试题80:如何进行数据仓库的性能优化?请举例说明。

数据仓库的性能优化包括以下几个方面:
  1:确定合适的数据模型:选择合适的数据模型,可以提高查询效率。例如,采用星型、雪花型等维度建模方式,可以减少多表关联操作。
  2:合理的索引设计:在数据仓库中加入索引可以提高查询效率。但是过多的索引会影响写入性能,因此需要在权衡后进行设计。
  3:优化查询语句:避免使用子查询、过多的连接操作和复杂的函数计算等,这些操作会大幅降低查询效率。
  4:分析查询热点:通过监控查询日志等手段,了解用户最常用的查询语句和表,对热点查询进行优化。
  5:硬件资源的优化:增加系统的内存、CPU等硬件资源,可以提高数据仓库的查询速度。
  6:数据分区存储、分块存储:将数据划分为不同的分区,可以减小查询范围,提高查询效率。
  7:减少冗余数据:在数据建模中,可以通过维度规范化和事实表聚合等方法来减少冗余数据。维度规范化是指将重复的数据放在一个单独的维度表中,以避免在多个事实表中出现冗余数据。事实表聚合是指将相同的度量值组合成更高级别的行,并将其存储在一个单独的事实表中。
  8:使用聚合表缓存经常使用的查询结果
  9:尽可能使用整数类型:在设计数据模型时,应尽可能使用整数类型(如整型或长整型)而不是文本类型,因为整数类型在计算和比较时比文本类型更快。
  10:使用最小化的数据类型:对于某些列,如日期和货币,使用最小化的数据类型可以减少存储空间并提高查询性能。
  11:建立适当的约束:在数据建模中,应该建立适当的约束,以确保数据的完整性和一致性。例如,主键和外键约束可以确保数据的参照完整性,检查约束可以确保数据的正确性。

举例说明:假设一个电商公司有一个销售数据仓库,其中包含了订单信息、用户信息、商品信息等,该公司想要优化查询效率。可以采取以下措施:
  使用星型模型或者雪花模型来构建数据模型,减少多表关联操作。
  对经常被查询的字段添加索引。
  避免使用过于复杂的查询语句,例如使用子查询、过多的连接操作和复杂的函数计算等。
  监控查询日志,识别查询热点,对热点查询进行优化。例如,考虑对经常被查询的表进行数据分区。
  增加硬件资源,例如增加内存、CPU等硬件资源,提高查询速度。

面试题81:数据仓库建设生命周期 面试题66:如何确定一个业务过程中的维度,以及如何设计多层次的维度结构?

确定业务过程中的维度需要考虑以下因素:
  业务需求:维度应该围绕业务需求展开,采用与业务过程相匹配的维度。例如,在销售业务中,时间、地点、产品、客户等可以作为关键维度。
  数据可用性和完整性:维度必须是可用和完整的数据元素,能够反映实际情况。如果缺少任何一个核心元素,则可能会影响对业务过程的分析和理解
  数据标准化:使用标准的格式和定义来描述维度元素,以确保在数据仓库中具有一致性和可比性。

设计多层次的维度结构需要考虑以下因素:
  维度属性:确定每个维度有哪些属性,包括哪些属性是可分层次的。
  层次结构:设计每个层次之间的关系,如父节点和子节点的关系。
  层次粒度:确定每个层次的粒度,并确保每个层次都有一个明确的粒度定义。
  聚合规则:针对每个层次的聚合规则进行定义,以确保正确的聚合结果。
  维度表连接:对于多层次的维度结构,需要通过多个维度表之间的连接进行操作和查询。
  数据建模工具:使用数据建模工具对多层次的维度结构进行建模和实现。

总的来说,确定业务过程中的维度和设计多层次的维度结构需要根据具体的业务需求和数据特征进行综合分析和设计,以确保数据的准确性和完整性,并为企业提供更好的决策支持。

面试题67:如何选择事实表的粒度?请举例说明。

选择事实表的粒度需要根据具体业务需求和数据特征进行综合分析和设计。一般来说,事实表的粒度应该既不过细也不过粗,而是能够充分反映业务过程中的核心指标。
在选择事实表粒度时,应考虑以下因素:
  业务需求:应根据业务需求选择粒度,以确保度量指标能够反映出业务过程的本质特征。
  数据可用性和完整性:选取的粒度必须是可用和完整的数据元素,能够反映实际情况。
  数据存储和处理成本:选择过大的粒度会增加数据存储和处理成本,而选择过小的粒度则可能会导致数据量过大,影响查询效率。

例如,在销售业务中,可以选择以订单为粒度,记录每个订单的销售额、销售数量、销售时间等相关信息。这样的粒度可以很好地反映出销售业务的核心指标,且不会造成数据存储和处理上的大量浪费。另外,在库存管理业务中,可以选择以日为粒度,记录每天的销售量、进货量、退货量等核心指标,以反映该业务的运营状态。
总之,在选择事实表的粒度时,需要结合具体业务需求和数据特征进行设计,并要注意避免过细或过粗的粒度,以确保数据仓库的有效性和高效性。

面试题68:.如何处理缺失维度数据和重复数据?

处理缺失维度数据的方法:
  默认值填充:如果某些维度缺失,可以将其用默认值填充,例如用“未知”、“其他”等代替缺失值。
  外部关联:如果可以从其他数据源获取相关信息,则可以通过外部关联来进行补充。例如,可以通过邮编查询关联城市、区域等信息。
  删除数据:如果缺失的数据影响不大,或者比例较小,则可以删除这些数据行或列。但在做出决策之前一定要确认删除这些数据是否会导致后续分析结果不准确。

处理重复数据的方法:
  去重:去除完全相同的数据记录。
  合并数据:如果存在部分字段相同但不完全相同的数据记录,可以考虑将这些记录合并成一个记录,例如求和、平均等聚合函数操作。
  保留最新数据:如果数据记录是时间序列的,可以根据时间戳保留最新的数据记录,同时排除掉旧的数据记录。
  人工判断:对于少数重复数据无法自动处理的情况,可以通过人工判断来进行处理。例如,对于姓名、地址等字段较为相似的数据记录,需要人工进行核实和确认。

面试题69:如何评估数据建模的性能和效果?如何优化数据建模的性能?

数据建模的性能和效果评估通常需要考虑以下几个方面:
  数据仓库查询性能:这是衡量数据建模效果的关键指标之一。如果查询时间很长,用户体验就会变差,导致不良的商业决策。因此,需要评估查询性能并确定如何优化。
  数据中断率:如果数据仓库经常出现数据中断或故障,那么整个系统的效果就会下降。因此,需要定期检查数据中断率并采取必要的措施进行修复和预防。
  数据一致性:在数据建模过程中,需要确保数据仓库与源系统之间的数据始终保持一致,以便提供准确的分析结果。因此,需要评估数据一致性并确保它得到维护。
  数据质量:数据建模的性能和效果也受数据质量的影响。如果数据存在错误、缺失、重复等问题,则可能导致分析结果不准确。因此,需要评估数据质量并采取相应的措施来修复和预防这些问题。
  数据安全性:数据安全性是保护数据不受未授权访问和攻击的关键因素。因此,需要评估数据安全性并采取必要的安全措施保护数据。

为了优化数据建模的性能,可以采用以下方法:
  精简数据模型:简化数据模型,删除不必要的表和字段,使查询时间更快。
  优化索引:根据查询需求优化索引,增加索引以提高查询性能。
  优化 ETL 程序:通过调整 ETL 程序来减少数据处理时间,同时避免对源系统造成过大的负载。
  数据压缩:对数据进行压缩可以减小存储空间,同时提高查询速度。

总之,数据建模的性能和效果评估是数据仓库开发中非常重要的一步。通过评估查询性能、数据一致性、数据质量、数据安全性等因素,并采取相应的优化措施,可以最大限度地提高数据建模的性能和效果。

面试题70:请描述您在以前的项目中如何设计数据建模方案,并解释它的优缺点?

一般来说,数据仓库建模的设计需要考虑以下几个方面:
1.确定业务需求:根据业务需求选择合适的建模方法以及建模粒度。
2.设计数据模型:使用实体关系图(ERD)将各种实体、属性和关系进行建模。
3.选择ETL工具:使用ETL工具从源系统抽取、转换和加载数据到数据仓库中。
4.进行物理建模:基于数据模型设计数据库中的表结构、列定义、主键、外键等。
5.优化查询性能:使用索引、分区、聚簇等技术优化查询性能。
6.测试和验证:通过测试和验证确保建模方案的正确性和可靠性。

优点:
数据仓库建模可以提供一致性和标准化的数据视图,使企业能够更好的监控和管理业务。
建模过程中可以对数据进行清洗、整合和转换,提高数据质量。
数据仓库建模可以支持灵活的数据查询和分析。

缺点:
数据仓库建模需要耗费大量时间和资源,需要充分评估商业价值和成本效益。
数据仓库建模可能会受到数据来源变化或新需求的影响,需要维护和更新。
数据仓库建模需要专业的技术知识和经验,难度较高。

面试题71:什么是粒度?为什么粒度很重要?如何确保粒度的正确性?

粒度是指数据被分组、聚合或汇总的程度。在数据仓库中,粒度通常是通过对事实表进行分组和聚合来定义的。例如,在销售数据中,每个订单可能包含多个产品和销售金额,如果按照订单进行聚合就是以订单为粒度,而如果按照每个产品和销售金额进行聚合就是以产品为粒度。
粒度非常重要,因为它决定了我们可以从数据仓库中获得的信息深度和准确性。粒度过大会导致丢失细节信息,难以进行详细的分析,而粒度过小则会增加查询的复杂度和计算量,并且可能会占用大量存储空间。因此,正确的粒度设计需要根据业务需求平衡这些因素。

确保粒度的正确性需要考虑以下几点:
 需要明确定义粒度,确保各个部门和人员使用相同的定义。
 粒度应该符合业务需求和分析要求,需要对业务模型和数据模型进行深入理解。
 在建立事实表时应该注意粒度的一致性,避免出现错误的汇总方式。
 在ETL过程中需要对数据进行清洗和转换,确保数据的一致性和准确性,避免粒度不一致的情况。
 在数据仓库查询和分析时需要认真选择粒度,确保能够满足分析要求并提高查询效率。

面试题72:如何应对数据建模中的一些变更,例如业务需求的变化、数据源的变化等?

在数据建模过程中,变化是不可避免的。以下是一些应对数据建模变化的方法:
1:及时响应业务需求变化:业务需求的变化可能导致数据建模的改变,因此需要及时响应并进行相应的修改。
2:保持灵活性:在设计数据模型时,可以考虑采用灵活的架构和设计,以便在变化发生时能够更容易地进行调整。
3:采用标准化的设计:使用标准化的设计可以使数据建模更加稳定和可维护,从而更容易适应变化。
4:建立变更管理流程:建立变更管理流程可以确保在进行任何更改之前,没有疏漏或错误,并确保更改得到了适当的批准和记录。
5:使用版本控制软件:使用版本控制软件可以记录数据模型的历史变化,并使回滚和恢复变得更加容易和可靠。
6:监测数据源变化:监测数据源的变化可以及时发现与数据建模不符的情况,从而更快地进行调整。

总之,在数据建模中,变化是不可避免的,因此需要采取相应的方法来应对。为了适应变化,需要保持灵活性、采用标准化设计、建立变更管理流程、使用版本控制软件等,以确保数据模型的稳定性和可维护性。

面试题73:如何解决数据建模中的一些挑战,例如复杂的业务规则、数据粒度的把控等?

在数据建模过程中,可能会遇到很多挑战,例如复杂的业务规则、数据粒度的把控等。以下是一些解决这些挑战的方法:
1:深入了解业务需求:复杂的业务规则是数据建模中的一个重要挑战,因为它们可能包含大量的条件和限制。为了解决这个问题,需要深入了解业务需求,并与业务专家合作进行详细的讨论和分析。
2:使用标准化的术语和定义:在数据建模中,使用标准化的术语和定义是非常重要的,因为它可以消除歧义和不必要的复杂性。建议采用行业标准和最佳实践来确定术语和定义,并确保所有参与者都了解和遵守这些标准。
3:把握数据粒度:数据建模中正确把握数据粒度是至关重要的,因为它直接影响到数据分析的结果。建议从实际业务需求出发,根据不同级别的数据粒度设计相应的数据模型,以确保数据的完整性和准确性。
4:分阶段设计:在处理复杂的业务规则时,建议将数据建模分成多个阶段进行设计,以便逐步深入了解业务需求并逐步完善数据模型。
5:合理使用工具和技术:在解决数据建模的挑战时,可以考虑使用各种工具和技术,例如数据建模工具、业务流程管理工具、UML建模等。这些工具和技术可以使数据建模更加高效和准确。

面试题74:如何处理周期性数据?请举例说明?

处理周期性数据通常需要考虑以下几个方面:
 1:选择合适的时间粒度:根据业务需求和数据量大小,选择合适的时间粒度进行分析,例如日、周、月、季度或年等。
 2:平滑处理:对于周期性波动较大的数据,可以使用平滑处理方法,例如移动平均、指数平滑等方法,以便更好地观察趋势和周期性变化。
 3:季节性调整:如果数据中存在明显的季节性变化,可以使用季节性调整方法,例如季节性因子法或回归分析法等方法,以消除季节性的影响。

举例来说,假设我们要处理一家零售店的销售数据,并发现其中存在明显的季节性变化。我们可以按照以下步骤进行:
 1:选择合适的时间粒度:根据业务需求和数据量大小,选择月度作为时间粒度进行分析。
 2:平滑处理:对于每个月的销售数据,可以使用移动平均或指数平滑等方法进行平滑处理,以便更好地观察销售趋势和周期性变化。
 3:季节性调整:对于已经平滑处理过的销售数据,可以使用季节性因子法进行季节性调整,以消除季节性的影响,得到更准确的销售趋势和预测结果。

通过以上步骤,我们可以更好地处理周期性数据,找出隐藏在数据中的规律和趋势,并为业务决策提供更有力的支持。

面试题75:如何进行增量更新?请介绍一下增量更新的策略。

增量更新是指在数据仓库中仅更新已经发生变化的数据,而不是对整个数据进行重新加载。这种方式可以大大减少更新时间和成本,并且可以确保数据的一致性和准确性。以下是几种常见的增量更新策略:

1:增量抽取(Incremental Extract):从源系统中仅提取新增、修改或删除的数据,避免全量抽取,从而减少数据传输和处理时间。
2:增量装载(Incremental Load):将增量数据与已有数据合并,只更新已经发生变化的行或列,避免对整个数据仓库进行重新加载。
3:增量更新(Incremental Update):将增量数据与已有数据进行匹配和比较,找出已经发生变化的行或列,然后只对这些数据进行更新。
4:增量删除(Incremental Delete):将需要删除的数据标记为已删除状态,而不是直接从数据仓库中删除,这样可以避免对已经存在的数据造成影响。

以上策略可以根据具体情况进行组合和调整,以适应不同的业务需求和数据更新频率。同时,在实施增量更新时,还需要注意数据的一致性和准确性,并确保增量更新过程的可靠性和稳定性。

面试题76:如何设计增量更新策略?如何应对数据源变化和数据质量问题?

设计增量更新策略的目的是将数据仓库中的数据与源系统中的数据保持同步,避免数据过期和不准确。以下是一些常用的增量更新策略:
 1:根据时间戳更新:通过比较源系统中的时间戳和数据仓库中的时间戳来判断哪些数据需要更新。
 2:根据版本号更新:将源系统中的每个记录都分配一个唯一的版本号,当源系统中的记录发生变化时,版本号也会发生变化,并且与数据仓库中的版本号进行比较,以确定哪些记录需要更新。
 3:增量抽取:仅抽取源系统中发生变化的数据,并将其合并到数据仓库中,避免对整张表进行全量更新。

在处理数据源变化和数据质量问题时,可以采取以下措施:
 1:监控数据源:及时监测数据源变化,如新增、删除或更新字段等,并及时更新数据仓库的元数据,保证数据仓库的正确性。
 2:数据清洗:在ETL过程中,应该对数据进行规范化、去重、转换和格式化等数据清洗操作,保证数据质量。
 3:数据验证:在更新数据仓库之前,应该对数据进行验证,确保数据的完整性、准确性和一致性。
 4:异常处理:对于异常数据,例如无法解析或者格式错误的数据,应该及时标记并进行处理。
 5:数据回滚:在进行数据更新时,应该备份原始数据,以防万一出现问题,可以随时回滚。

总之,在建立数据仓库的过程中,需要注重数据质量控制和数据源监控,同时采取合适的增量更新策略,确保数据仓库中的数据与源系统保持同步和一致。

面试题77:如何衡量和提升数据质量?提供一些具体的数据质量评估指标和方法。

数据质量是指数据是否准确、完整、一致、可靠和有效,对于数据仓库的建设来说,数据质量的高低直接关系到业务分析的精度和决策的正确性。以下是一些常用的数据质量评估指标和方法:
  准确性:数据是否正确无误,可以根据对比与外部数据源的一致性来衡量。
  完整性:数据是否完整,不缺失重要的信息,可以通过缺失值比例、缺失值位置等指标来评估。
  一致性:数据是否一致,同一个实体的数据是否相同,可以通过验证数据库中唯一键值的重复率来进行评估。
  可靠性:数据是否可靠,数据来源是否可信、数据是否被篡改等,可以通过数据审计和数据元数据管理来评估。
  实时性:数据是否及时,数据更新频率、数据过期时间等指标可以衡量数据的实时性。
  格式规范性:数据是否符合统一的格式规范,例如日期格式、数字格式等,可以通过数据清洗操作来实现。

提升数据质量的方法包括:
  数据清洗:对数据进行去重、转换、格式化、规范化等操作,以提高数据的准确性和一致性。
  数据验证:在进行ETL操作之前,先对数据进行验证,确保数据的完整性和正确性。
  数据审计:对数据进行审计,记录数据变更、访问历史等信息,以确保数据的可靠性和安全性。
  数据质量监控:设置数据质量监控指标,如数据更新频率、异常数据比例等,并及时发出预警提醒。
  数据管理:建立数据字典、数据目录、数据分类体系等,加强对数据的管理,提高数据的可发现性和可用性。

总之,提升数据质量需要一系列的工具和流程支持,需要结合具体业务场景,采取适当的措施,从而有效地提高数据质量。

面试题78:如何处理维度数据缺失的情况?提供一些具体的解决方案。

维度数据的缺失可能会导致查询和分析结果不准确,并且会影响决策的正确性。处理维度数据缺失的方法包括以下几个方面:
  1:人工修复:如果数据量较小,可以通过手动输入或其他手段进行修复。
  2:默认值填充:对于一些确定的属性,可以使用默认值来填充缺失的数据,例如把地址缺失的记录设置为“未知”。
  3:聚合替代:利用现有数据的特点对缺失的数据进行推测,例如根据地理位置、时间等因素对缺失的销售额进行估算。
  4:外部数据补充:可以考虑从外部数据源中获取相应的维度数据,如从第三方数据提供商、社交网络等获取。
  5:建立新类别:对于分类变量,可以将缺失的记录归为一个新的类别,如“未知”或“其他”。
  6:使用机器学习算法预测:可以使用机器学习算法,如回归模型或聚类算法来预测缺失的数据。
总之,在处理维度数据缺失时需要根据具体情况采用合适的方法,并尽量避免对数据精度的影响。同时,在建立数据仓库的过程中,也要注重数据质量控制,减少数据缺失的可能性。

面试题79:如何设计增量更新策略,防止数据出现重复?

为了防止数据出现重复,我们需要设计一个合理的增量更新策略。具体的实现方法如下:
 1:标识每个数据记录:对于需要进行增量更新的表,可以添加自增主键或者唯一标识符,这样可以避免相同的数据记录被多次插入。
 2:增量更新的条件:在进行增量更新时,要根据某些特定的条件来判断数据是否已经存在。例如,在更新订单信息时,可以判断订单号是否已经存在。
 3:逐条比较:在进行增量更新时,可以采用逐条比较的方式,即将待更新的数据和目标表中的数据进行一一比较。如果数据已经存在,则进行更新操作;否则进行插入操作。
 4:使用时间戳:在数据表中添加时间戳字段,表示该数据记录的最后修改时间。在进行增量更新时,只处理时间戳比当前时间更晚的数据记录。
 5:进行批量更新:对于大规模的数据更新操作,可以采用批量更新的方式,将需要更新的数据进行分批次处理,减少系统负载和内存占用,并且提高效率。
总之,设计增量更新策略时,需要考虑数据的唯一性、比较时间戳等因素,以确保数据不会出现重复。

面试题80:如何进行数据仓库的性能优化?请举例说明。

数据仓库的性能优化包括以下几个方面:
  1:确定合适的数据模型:选择合适的数据模型,可以提高查询效率。例如,采用星型、雪花型等维度建模方式,可以减少多表关联操作。
  2:合理的索引设计:在数据仓库中加入索引可以提高查询效率。但是过多的索引会影响写入性能,因此需要在权衡后进行设计。
  3:优化查询语句:避免使用子查询、过多的连接操作和复杂的函数计算等,这些操作会大幅降低查询效率。
  4:分析查询热点:通过监控查询日志等手段,了解用户最常用的查询语句和表,对热点查询进行优化。
  5:硬件资源的优化:增加系统的内存、CPU等硬件资源,可以提高数据仓库的查询速度。
  6:数据分区存储、分块存储:将数据划分为不同的分区,可以减小查询范围,提高查询效率。
  7:减少冗余数据:在数据建模中,可以通过维度规范化和事实表聚合等方法来减少冗余数据。维度规范化是指将重复的数据放在一个单独的维度表中,以避免在多个事实表中出现冗余数据。事实表聚合是指将相同的度量值组合成更高级别的行,并将其存储在一个单独的事实表中。
  8:使用聚合表缓存经常使用的查询结果
  9:尽可能使用整数类型:在设计数据模型时,应尽可能使用整数类型(如整型或长整型)而不是文本类型,因为整数类型在计算和比较时比文本类型更快。
  10:使用最小化的数据类型:对于某些列,如日期和货币,使用最小化的数据类型可以减少存储空间并提高查询性能。
  11:建立适当的约束:在数据建模中,应该建立适当的约束,以确保数据的完整性和一致性。例如,主键和外键约束可以确保数据的参照完整性,检查约束可以确保数据的正确性。

举例说明:假设一个电商公司有一个销售数据仓库,其中包含了订单信息、用户信息、商品信息等,该公司想要优化查询效率。可以采取以下措施:
  使用星型模型或者雪花模型来构建数据模型,减少多表关联操作。
  对经常被查询的字段添加索引。
  避免使用过于复杂的查询语句,例如使用子查询、过多的连接操作和复杂的函数计算等。
  监控查询日志,识别查询热点,对热点查询进行优化。例如,考虑对经常被查询的表进行数据分区。
  增加硬件资源,例如增加内存、CPU等硬件资源,提高查询速度。

面试题81:数据仓库建设生命周期 alt alt

本文由 mdnice 多平台发布

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值