ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

浩鲸科技数据开发笔试C卷解析:SQL、Hive与数仓建模核心考点

浩鲸科技数据开发笔试C卷解析:SQL、Hive与数仓建模核心考点 我当年在数据开发岗上摸爬滚打这么多年前后也帮着朋友、学弟学妹们看过不少校招笔试题其中浩鲸科技这套2020届数据开发类C卷算是比较有代表性的。为什么这么说因为这套卷子不是单纯考你背了多少组件参数而是把“数据开发”这个岗位真正需要的底层能力挨个过了一遍SQL功底、大数据组件原理、数仓建模思维、甚至还有工程落地时的细节判断。换句话说它考的不是知识点而是你有没有“干过活”的思维习惯。如果你是准备数据开发岗位校招的同学或者刚转行大数据方向、想系统检验一下自己水平这篇文章值得认真看完。我会把这套卷子里最核心的考察逻辑拆开揉碎结合我自己实际写代码、做数仓、调优Hive作业的经验一条一条告诉你出题人到底想看到什么以及你该怎么答才能拿高分。文章里不会有那种“背答案式”的套路只会告诉你底层原理和踩坑经验顺便帮你把数据开发最核心的知识体系串一遍。1. 先搞清楚浩鲸科技是一家什么样的公司业务决定技术栈1.1 从公司背景看笔试出题方向浩鲸科技的前身是中兴软创2020年那会儿已经完成了品牌升级核心方向是数字化转型服务客户以通信运营商为主同时覆盖政务、交通、能源等行业。公司背景直接决定了数据开发岗位的工作内容运营商级别的海量数据、BSS/OSS系统里的计费详单、用户行为日志、网络信令数据全都是典型的大数据规模场景。所以这套C卷的出题方向非常明确不考花哨的算法不考深度学习考的是最贴近生产环境的各项硬功夫。你可以这么理解浩鲸要招的人是进去之后能直接上手处理几千张表、每天跑几百个调度任务、能在数据倾斜的时候快速定位问题的那种工程师而不是只会调包调参的“框架使用者”。1.2 C卷在整套笔试中的定位2020届校招笔试采用AB卷或者ABC卷多套并行主要是为了防止同场考生互相抄袭。C卷作为其中一套难度和考察范围和另外几套是平行的但具体题目会有差异。从题型分布来看数据开发类C卷基本覆盖了四个大方向SQL编程题、大数据组件原理题、数据仓库设计题、Linux及Shell脚本基础。这里要提醒一点很多同学容易忽略Linux和Shell部分觉得笔试又不考实操随便准备一下就行。实际上从出题人的角度看Shell脚本是数据开发最常用的粘合剂不管是数仓抽数、日志清洗、还是调度任务运维都离不开Shell。C卷里这部分题目往往不难但很能拉开差距因为基础扎不扎实几道小题目就能看出来。2. 数据开发岗位笔试的四大核心考察模块2.1 SQL与关系型数据库功底所有数据开发的真地基第一模块一定是SQL这是毋庸置疑的。但校招笔试里的SQL和你在学校课程里学的SQL完全是两码事。学校教的是增删改查笔试考的是复杂的多表关联、窗口函数、行列转换、累计统计、分组TopN这些实际业务场景里高频使用的写法。我见过太多同学LeetCode刷了一百多道算法题结果笔试遇到一道需要写开窗函数的SQL就卡住了。原因很简单平时的练习场景里面几乎没有用到过SQL更别说在限定时间内手写SQL了。C卷中SQL题目通常会出现这样几类排名类问题经典的分组TopN、连续类问题连续登录天数、占比类问题各类别的金额占比、同比环比类问题。每一类都有固定的解题套路本质上就是窗口函数加子查询的灵活组合。另外一个容易被忽视的点是手写SQL的规范性和严谨性。笔试不是机试不会有编译器告诉你语法错了所以你必须做到心中有一台“虚拟执行引擎”在落笔的时候就知道这段SQL的执行计划大概是什么样、会不会有语法歧义、NULL值会不会影响结果。这种能力没有捷径只能靠平时多写、多读执行计划。2.2 Java基础与Shell脚本工具型能力决定你的下限数据开发岗在大部分公司里并不要求你像后端开发一样精通Java但至少得能看懂、能写基础的Java程序。为什么因为绝大多数大数据框架都是Java生态MapReduce作业、Spark作业、Flink作业最终跑的都是JVM进程。笔试里Java题通常不会太深集中在集合框架、多线程基础、异常处理这些核心知识上。问这些问题不是为了招一个Java开发而是为了确认你没有“知识盲区”遇到问题时至少有排查的方向。相比之下Shell脚本反而是很多校招生的大坑。C卷里面给了几个常见的场景写一个脚本循环处理某个目录下的文件、用awk和sed处理文本、用crontab配置定时任务、检查某个进程是否存在并做重启操作。这些题目看起来简单但非常考验基本功。有过真实操作经验的人写出来的脚本会考虑到文件不存在、路径带空格、权限不够这些边界情况而没有实际操作过的同学写出的脚本往往只能处理“理想状态”这在出题人眼里一眼就能分辨。2.3 Hadoop生态组件从原理到调优的全链路理解重头戏来了。数据开发笔试必然绕不开Hadoop生态C卷里关于HDFS、MapReduce、Hive、Spark的题目占了相当大的比重。但这里有个很关键的区分点校招笔试不考你“用过哪些框架”而是考你“是否理解框架的底层原理”。比如同样问Hive常见的问题有这几个层次第一层是Hive的架构SQL是怎样转化为MapReduce或Spark作业的第二层是分区表和分桶表的区别、内部表和外部表的区别第三层是Hive on MR和Hive on Spark的区别以及为什么有时候Hive作业跑得特别慢。对于MapReduce重点则是整个作业的提交到执行流程客户端提交作业后ResourceManager是怎么分配容器的Map阶段的数据切片是怎么计算的Shuffle阶段的数据是怎么分区、排序、合并的Reduce阶段又是怎么拉取数据的。这些细节一个个串起来其实就是在考察你是否真的理解分布式计算的基本模型。很多同学能说出MapReduce的四个阶段但说不清每个阶段之间数据的流转格式这就不算真正理解。Spark相关的题目也类似。C卷里Spark主要考察RDD的依赖关系、宽窄依赖的区别、Stage的划分依据、Spark Streaming和Structured Streaming的基本原理。如果能顺带说出Spark Shuffle和MapReduce Shuffle的异同点基本就能拿高分了。实际上面试官和出题人想要的是那种能清晰表达“数据在框架里是怎么流动的”的人而不是只会背概念的人。2.4 数据仓库理论与建模思维思想层面的分水岭数据开发和数据仓库之间是分不开的。C卷里数据仓库相关的题目答得好不好往往是区分“只是会写SQL的人”和“真正有数仓思维的人”的分水岭。维度建模是必须掌握的核心理论。事实表和维度表的区别、星型模型和雪花模型的适用场景、缓慢变化维的处理方式这些都是高频考点。2020年前后国内互联网大厂已经在大量推行数仓分层体系ODS、DWD、DWS、ADS这四层分法是主流笔试中极大概率会出现让你画一个主题的数仓分层设计或者给定业务场景让你设计事实表和维度表。这部分的考察核心不是你能不能背出定义而是你能不能结合具体业务场景说出每张表该存什么、粒度怎么定、主键怎么选。另外数据质量相关的题目也值得注意比如数据重复、数据缺失、数据一致性校验这些。浩鲸做的是运营商系统每天跑完批处理任务后第二天早上必须有数据校验报告一旦发现异常要能回溯问题。所以笔试中出现“怎么保证数据质量”“怎么设计数据稽核方案”这类开放性问题千万不要只回答一两点要按事前预防、事中监控、事后补救三个维度来展开这样逻辑才完整。3. 典型题型还原与解析拿到题该怎么一步步拆解3.1 分组TopN问题从暴力写法到窗口函数优化这类题目是SQL笔试的常客。比如给定一张用户订单表user_id, order_date, amount求每个用户下单金额最高的前3笔订单。第一次接触的同学很可能第一时间想到用自连接或相关子查询大致逻辑是“找出每笔订单之前有多少笔比它金额大如果数量小于3那这笔订单就是Top3”。SELECT a.user_id, a.order_date, a.amount FROM orders a WHERE ( SELECT COUNT(*) FROM orders b WHERE b.user_id a.user_id AND b.amount a.amount ) 3;这种写法能跑但性能非常差。如果订单表有几千万行子查询会对每一行都扫描一次目标表基本就废了。正确做法是用窗口函数开一个按用户分区、按金额降序排列的排名窗口然后过滤排名小于等于3的行。SELECT user_id, order_date, amount FROM ( SELECT user_id, order_date, amount, ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY amount DESC) AS rn FROM orders ) t WHERE rn 3;这里有两个细节值得注意一是用ROW_NUMBER()还是DENSE_RANK()差异在于当金额并列时两类函数对排名的处理不一样很多实际业务要求下需要用DENSE_RANK二是窗口函数中的ORDER BY DESC如果是金额相同的情况还需要不要加第二排序字段取决于业务是否要求“先下单的排在前面”。笔试时写清楚这些边界情况能充分体现你的SQL功底。3.2 Hive优化类题目小文件问题如何处理小文件问题是Hive生产环境里最经典、也最让人头疼的问题之一。C卷里出了这样一道题一个Hive表每天产生大量小文件导致查询和写入性能严重下降请给出解决方案。从原理上讲HDFS上的每个文件都会在NameNode中对应一条元数据记录文件越多NameNode内存压力越大。同时MapReduce作业读取大量小文件时会产生大量Map任务每个Map任务的启动和调度都有固定开销导致整体执行效率极低。解决思路有几个层次。第一层是控制源头在写入阶段就尽量避免生成过多文件。比如使用Hive的distribute by配合sort by把相同分桶键的数据分到同一个Reduce任务里。更直接的办法是设置hive.merge.mapredfilestrue和合理的hive.merge.smallfiles.avgsize参数让Hive在作业结束后自动合并小文件。第二层是事后治理针对已经存在的大量小文件可以写一个临时作业用INSERT OVERWRITE把这些小文件读出来重新写一遍在写入时设置合适的Reduce数量。实际生产中我通常的做法是SET hive.exec.reducers.max50; SET mapreduce.job.reduces50; INSERT OVERWRITE TABLE target_table SELECT * FROM source_table DISTRIBUTE BY RAND();这里用DISTRIBUTE BY RAND()的核心思路是让数据随机分配到50个Reduce任务里这样输出文件数量不会超过50个。如果不加这个条件Reduce分配可能不均匀反而出现新的小文件。这个细节如果不实操过根本想不到。作答这类题目的关键是不要只给出一条方案要从“预防”和“治理”两个维度结合参数配置和具体SQL来回答这才是有实际项目经验的人的表现。3.3 数据仓库设计题电商订单数仓分层设计C卷里有一道典型的数仓设计题给定一个电商平台的订单业务场景要求设计一套数仓分层方案并说明每一层的核心表和主要字段。这道题考查的已经不只是理论知识了而是你有没有真正理解分层架构在实际业务中为什么要这样设计。我的答题思路一般是这样的ODS层操作数据存储层直接存放业务库同步过来的原始数据订单表、订单明细表、商品表等都原样保留字段不加工主要是方便日后的数据回溯和核对。这一层必须注意增量还是全量同步的问题订单表因为有状态变更通常是增量同步加更新操作而商品表这种小表基本是全量快照。DWD层明细数据层要做清洗和规范化。比如把订单状态字段从业务里的数字编码统一转换成可读的字符串把用户手机号脱敏处理把下单时间和支付时间统一格式化为标准时间戳。这层的数据粒度仍然和ODS保持一致还是明细级别的但已经是干净、可用的数据了。DWS层汇总数据层则按照主题进行轻度汇总。比如按用户维度汇总每日下单金额、订单数、支付金额按商品维度汇总每日销售数量、销售金额按地区维度汇总每日订单量等。这些汇总结果会被上层直接使用所以在设计时必须提前想清楚常用查询的条件和维度才能让汇总表的维度覆盖到位。ADS层应用数据层则完全是为具体报表或应用服务的说白了就是“你业务方想要什么表我就在这层给你拼什么表”。比如销售大屏要展示今日全平台GMV、各品类销售排行、各地区销售地图ADS层就单独建一张报表表把DWS层的数据再加工成最终展示结构。回答这类题目时我建议你在纸上把每一层的表和核心字段都列清楚并顺带说明为什么要分这么多层。理由很直接解耦。从ODS到DWS每一层都承担着明确的职责业务方如果临时要一个新的统计口径通常不需要回溯到ODS原始日志而是基于DWD或者DWS就能完成加工这样既节省了开发时间也降低了出错后排查问题的成本。3.4 MapReduce原理题WordCount之外的理解深度MapReduce原理题最怕的就是只会背WordCount流程。C卷里有一道题问的是一个MapReduce作业从提交到结束任务调度和数据流转是怎么完成的。我建议回答时一定要按时间线把全流程串起来客户端向ResourceManager提交作业后RM会先根据作业的输入路径和输入格式计算出分片split信息每个分片会对应生成一个Map任务随后RM在集群中分配容器并在NodeManager上启动ApplicationMasterApplicationMaster是作业的“管家”它负责向RM申请后续Map和Reduce任务所需的资源Map任务读取分片数据经过map函数处理后将输出结果写入缓冲区待缓冲区达到阈值后溢写spill到本地磁盘这个过程里要做分区、排序和合并Map任务全部完成后Reduce任务开始从各个Map任务所在节点拉取属于自己的那部分分区数据这一步就是Shuffle中的Fetch阶段Reduce端还会做一次归并排序然后交给reduce函数处理最终结果写到HDFS上。如果到这里就说完分数不会太低但想拿高分还得补充两个细节一是数据切片大小默认是块大小也就是128MB如果输入文件很小会启动大量Map任务这是小文件问题能拖垮整个集群的根源二是Reduce任务默认数量是1如果你想让输出结果有多个文件就需要手动设置mapreduce.job.reduces。这两个点能体现你对作业执行过程的理解不只停留在概念层面。4. 从笔试看日常准备怎么学才算学到点子上4.1 刷题之外的原理闭环把“知道”变成“理解”数据开发笔试的准备最忌讳的就是零散刷题东看一眼Hive优化西看一眼Spark原理看完就忘下一套题照样不会。我自己的经验是知识点是要形成“闭环”的。什么意思你学到一个新概念比如Hive的谓词下推不要停留在“知道有这么个参数”层面要主动追问几个问题它下推的逻辑是什么在Map阶段还是Reduce阶段执行在什么情况下不会下推然后动手去环境里造数据验证。这个过程走完了这个知识点才真正变成你的。笔试里很多题目看着是考原理实际考的是你能否将原理用于排查问题。比如为什么一个简单的关联查询跑了几个小时如果你知道MapReduce的执行计划知道关联操作里大表驱动小表时的MapJoin优化就能说出可能是其中一个表太大导致Reduce端数据倾斜。这种“原理到问题”的映射能力才是备考中最重要、也最花时间的能力。4.2 项目经历怎么讲才有说服力除笔试之外后续的面试一定会问项目经历。很多同学写项目经历就是罗列技术名词使用了Hive使用了Spark使用了Kafka。这种写法一点说服力都没有。要让项目经历有说服力必须包含三样东西数据量级、遇到的问题、以及你怎么解决的。同样是做用户行为日志分析你可以说“日处理日志约1亿条使用Flume采集到Kafka再用Spark Streaming做实时清洗写入ClickHouse。遇到数据重复消费的问题通过在Kafka消费者中记录已处理的offset并结合去重逻辑解决。”这样讲出来面试官立刻就能判断你确实解决了实际问题而不是照着教程搭了个Demo环境。C卷笔试里很多开放性问题其实也是在模拟这种“真实场景遇到问题”的作答方式。4.3 笔试作答的时间分配策略数据开发类笔试一般时长在90分钟到120分钟之间题目量和难度都不小。我见过很多同学在后面的大题上花太久导致前面的基础题没时间做非常可惜。我的建议是先快速通读全卷用2到3分钟判断每题难度和分值。通常SQL编程题是必须拿下的如果你在10分钟内没思路先做个标记跳过去组件原理题如果是选择题或简答题尽量一遍过不要反复纠结Shell脚本题和数仓设计题分值高、但理解门槛不高适合放在最后保障完成度。等基础题全部完成再回头攻克前面的难题这样即使最后大题没做完卷面的完成度和得分率也会高很多。5. 笔试中那些防不胜防的“坑”5.1 审题不清比不会做更可惜校招笔试里大量丢分不是因为题目难而是因为审题不清。数据开发题目通常会在题干里埋很多限定条件比如“统计每个用户最近7天的消费总额”你以为这是简单的分组求和但如果表里时间字段是字符串类型你就需要先做格式转换如果一天有多个订单你需要先按天聚合再去计算7天窗口。这类题目最容易出错的地方就是把日期格式化处理漏了直接导致结果偏差。另一个高频审题问题是“要不要去重”。统计用户数时用COUNT(USER_ID)和COUNT(DISTINCT USER_ID)结果差很多必须要看清题目问的是“总用户数”还是“活跃用户数”以及订单表里一个用户是否可能出现多次。5.2 手写SQL的规范和边界条件手写SQL时不少同学会犯一些很低级但致命的错误字段名写错、表别名没加、子查询没起别名、分组字段不完整。笔试没有编译器报错所以你必须养成“落笔就是正确代码”的习惯。尤其要注意的是聚合函数和NULL值的处理。COUNT(*)和COUNT(字段名)在存在NULL值的时候结果不同SUM遇到全NULL会有问题GROUP BY后的HAVING条件要写对位置。还有窗口函数的写法PARTITION BY和ORDER BY的顺序以及ROWS BETWEEN的边界定义都是非常容易写错的地方。5.3 原理题答不到点子上时怎么补救如果遇到一道原理题确实一知半解不要直接放弃或者写一堆无关内容。你可以尝试从已知的知识点推导出合理的结论。比如让你解释Spark作业为什么比MapReduce快即使你不记得所有细节也可以从“Spark基于内存计算中间结果不落盘”“Spark使用DAG调度能够减少不必要的Shuffle”“Spark的Task启动开销比MapReduce小”等几个方向展开至少能拿一半以上的分数。我在企业里做数据开发用的核心工具就是Hive、Spark、Flink这一套笔试后的第三年我又回头看过这套题。说句实话这些题考察的逻辑至今没有过时。现在很多公司校招数据开发笔试依然在用类似的框架SQL或者Python选一个作为主编程语言、大数据组件原理、数据仓库设计思维、项目实战分析。如果你能把这套C卷涉及的知识点彻底吃透后面再遇到别的公司笔试也不会慌因为底层的知识体系是一样的变的无非是业务包装换汤不换药。
返回列表