前言

今天大环境不好,再加上一些不可言说的原因,所以萌生了想出去面试瞧瞧的想法,主要也是想看看行情,毕竟目前高不成低不就的阶段。投了很多家公司,面试机会确实不多……多说无益,直接开整。

这是一家杭州的大数据公司,面试官上来详细介绍了自己,具体说明了面试的流程和期望候选人回答的问题,算是在我面试中比较专业的面试官了,后面提问的问题就可以看的出,有点东西。

Q1:简单介绍一下你的工作经历,项目经历,以及具体的项目成果?

这个问题其实就是想更一步了解一下你,看看你自己对自己的工作和做的项目有没有自己的想法,还是一个只会听从leader,埋头coding的开发。没什么好说的,这个问题应该是老早准备充分的,也应该是最熟悉的,注意不要给自己挖坑,如果可以,也可站在更高的视角进行回答,例如从项目的必要性,成果的效益等回答自己的经验和经历。对于提到的项目和技术栈,一定要了然于胸,否则就讲不通了。

Q2:你刚说了XXX项目,这个项目的数据流向和技术架构是怎样的?

一般大数据的项目,如果是业务较多的非数仓项目,大概率会问数据流向,就是数据采集,数据加工,数据分析的相关问题,结合项目使用的技术栈,阐述清楚即可。

Q3:你会负责一些接口的开发么?

因为上面提到了一些数据平台的东西,所以面试官根据他的需求出发,问下数据接口是否有做过,那必须有。

Q4:主题域模型可以说一下么?如何进行主题域的划分?

接着就是具体的知识点了,考察数仓建模中的主题域知识。这里可以从WWH的方式进行说明:

  1. 主题是一个抽象的概念,是对业务系统中的数据进行综合、归类并进行分析利用的概念。每个主题对应一个分析领域。说白了就是对我们业务开发中的领域进行分类,主题根据分析的需求划定。

  2. 主题域就是一系列联系比较紧密的主题的集合。主题域的建立需要设计人员和数仓开发一起确定。

  3. 主题域的划分有多种方式,一般要么按照业务系统进行划分,要么按照业务线、功能模块进行划分。比如销售行业的客户主题域、渠道主题域、营销主题域等。分别对应不同的模块。

  4. 主题域的划分需要抽象提炼,长期稳定,便于维护。可以涵盖当前的业务需求也可以动态发展。主题域划分比较推荐按照业务系统划分或者BU部门来划分主题域(一级主题),这样的话边界较为清晰,然后根据各个系统中的业务过程抽象整合出主题(二级主题)。 这个东西每个公司都有自己的一套方法论,没有最合适的,只有更合适的。要因地制宜,灵活根据自己的业务场景制定合适的主题和主题域划分。

Q4:说一下双流JOIN的使用场景和注意事项?

因为项目中Flink用的比较多,所以接下来连续三问都是关于Flink的知识,回答的时候可以结合实际的项目使用来回答,如果可以,可以扯一些深入的底层知识,效果更好。

双流JOIN的核心说白了还是无界数据的关联问题。流数据到达Flink的时间不一定,会导致A流先到,A不知道B流对应的同一个Key的数据什么时候到,从而导致无法关联。B数据没有到,可能是B数据本身的问题,上游的延迟?质量问题?那么B数据不能一直等啊,如何让A继续往下走呢,即如何保证A的时效性问题。

方案一:使用Flink window,开一个time window,在窗口中进行JOIN。既然已经划分了窗口,就要按照约定,只要在窗口中进行JOIN即可。Trigger触发器触发,窗口结束即collect。如果AB没有关联上,就可以丢弃或者侧输出进行收集然后特殊处理。这种解决方法当窗口很短的情况下,会导致数据很多无法关联,但是时效性较高。除非业务窗口里关联率较高,一般不建议使用。

方案二:Flink Interval join。也是开一个窗口,变成有界数据处理。这里的Interval即给窗口一个区间进行均衡,A流可以关联B流前后N个时间的数据。通过水位线进行触发。只要延迟在可控范围内,就可以有比较好的数据质量和时效性。适用于两个流可以知道具体延迟多久的情况。

方案三:Flink regular join,这个是直接关联,不是基于窗口了,能关联就关联,关联不上继续走,当后面数据来了,再回撤,这个只适用于FlinkSQL。虽然数据关联率和时效性很高,但是相应的代价是回撤机制会导致state过大,引发OOM问题。另外下游也要支持。

三个方案其实都是依赖state,所以双流join的热点问题是状态过大的问题。优化思路就是尽量减少state的大小,比如共享state,或者借助缓存中间件处理。

Q5:你们使用的是DataStream API还是FlinkSQL? 为什么?

看业务场景,一般业务比较复杂的需求实用DataStreamAPI,例如需要调用外部接口,结合项目阐述即可。

Q6:可以说下checkpoint的机制么?

CK是Flink的容错的核心。可以从定义,实现方式,原理进行回答。

首先,CK即快照,我们知道流数据是源源不断的,要保证数据24*365天稳定运行,Flink一定要有一个故障恢复机制。Flink给的答案就是checkpoint。

通过定期做快照,把各个算子的状态记录下来,当发生故障的时候,就可以从上个检查点进行快速恢复。思路非常简单,实现起来并不容易。

Flink借鉴了“Chandy-Lamport 算法” (这里可以装X扯一波算法)

CK的实现是有检查点协调器全权负责的。步骤如下:

  1. CKC周期性的向job的所有source算子发送barrier。

  2. 当source收到一个barrier,就会暂停数据处理,然后把自己的状态制作快照,然后持久化。完事给CKC报告完成,同时给自己的下游广播barrier,然后恢复数据处理。

  3. 下游收到barrier,类似2的操作,继续广播。直到最后barrier到达sink算子。

  4. 当CKC收到所有算子的完成信号,则认为该周期CK成功。如果在超时时间内,没有完成,则认为失败,任务重启。

从CK的流程可以看出,如果有个别算子很慢,将会拖慢整个流程,导致超时失败,数据反压,恶性循环,从而导致数据积压。

这里可以扯一下,barrier对齐,反压,exactly-once语义等。(尽可能引导面试官,前提你要会)。

总结

好累,东西太多,下次再搞一波。