news 2026/9/1 22:18:48

游戏数仓校招笔试复盘:从维度建模到SQL实战的完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
游戏数仓校招笔试复盘:从维度建模到SQL实战的完整指南

秋招季总有人跑来问我:游戏公司的数据仓库开发工程师,笔试到底考什么?最近一个学弟把当年参加搜狐畅游2020校招笔试的回忆版题目发给我,让我帮他捋一捋复习方向。我把整套题过了一遍,最大的感受是:这套笔试题考的不是你会背多少概念,而是你有没有真正理解数仓从业务需求到数据落地的完整链路。尤其是最近“用户订单分析数据仓库”“维度表和事实表”这类热词频繁出现,说明行业对校招生的要求越来越明确——不是招一个只会写SQL的取数机器,而是招一个能理解数据模型、会做数仓设计的准工程师。

接下来我会从题型构成、维度建模、SQL实战、备考经验四个角度做一次完整复盘。别看这套题标着2020年,这类校招笔试的底层逻辑到现在依然适用,甚至可以说,把热点里的“核心维度表和事实表”吃透,比盲目刷一百道面试题都有用。

1. 拆解搜狐畅游笔试:数据仓库开发工程师到底考什么

1.1 题型构成与考察逻辑

校招笔试的编制思路通常不是“一套题定生死”,而是用综合题过滤一批人,再用专业题筛选出真正有数仓感觉的候选人。搜狐畅游这套数据仓库开发工程师的卷子,按网上回忆版和同类游戏公司笔试题的常见结构来看,大体可以分成这么几块:

题型考察点常见形式
数仓基础概念维度建模、事实表与维度表区别、数仓分层、ETL流程选择、填空、简答
SQL手写窗口函数、留存率、分组TopN、连续登录、聚合统计手写SQL,给表结构和数据
数仓建模设计给定业务场景,设计事实表、维度表、分区策略设计题,需要画出表结构或写建表语句
业务分析指标口径、数据质量、埋点日志和订单数据关联主观题,给出分析思路

这套结构看起来四平八稳,但真正的筛选点在后面两类题。基础概念题大家复习一下都能答出个大概,SQL题很多人也能写出来,但写出来的SQL是不是能处理重复数据、是否考虑了分区裁剪、遇到数据倾斜怎么办,这些才是区分“背过题”和“真做过”的地方。

说白了,校招不可能指望你有一两年大厂数仓实战经验,只能通过这些问题判断你有没有形成“从业务到表结构再到指标”的完整数仓思维。如果你能在设计题里答出“为什么这样设计”,而不是只扔出一堆字段,那在阅卷人眼里就已经高一档了。

1.2 题目背后的岗位画像:游戏数仓开发在做什么

笔试考什么,往往是由岗位日常做什么决定的。游戏公司的数仓开发,日常工作可以概括成:把散落各处的游戏埋点日志、订单流水、渠道数据、登录日志全部统一接入、清洗、建模、分层,最终变成运营、策划、发行看得懂、查得快的报表和分析数据集。

这就决定了笔试绝对不会考很难的算法,也不怎么考JVM调优,重点就是数据仓库建模和SQL能力。比如游戏运营每天要看的新增用户数、DAU、次日留存、付费率、ARPU、LTV,这些指标背后全都依赖一张张事实表和维度表的合理设计。笔试里出现“新增用户次日留存偏低,怎么从数据上定位原因”这类题,本质上就是看你能不能把业务问题翻译成数据问题。

再往深处说,游戏公司比一般互联网公司更看重渠道数据和买量归因。一款游戏上线,广告投放花出去几百万,运营需要知道每个渠道带来的用户质量怎么样、付费能力怎么样。这背后就是用户维度、渠道维度、订单事实表、活跃事实表之间的交叉分析。所以笔试题经常拿“用户订单”做背景,因为订单是游戏公司最核心的变现环节,没有之一。

2. 把用户订单拆成维度和事实:游戏数仓建模的实战推演

2.1 先定业务过程和粒度

很多人一上手做设计题就急着列字段,这是最大的误区。建模第一步,是先定义“你究竟要分析哪条业务过程”。用户订单分析这个场景,业务过程就是“用户在游戏内完成一次支付”。有了业务过程,接下来就要定粒度,也就是事实表里每一行到底代表什么。

订单事实表的粒度,通常是一行代表一笔支付订单。举个例子:某玩家同一天早上通过iOS渠道充值了一个6元首充档,晚上又通过官网活动充值了一笔98元档,那订单事实表里就应该产生两行记录,都关联同一个用户维度键,但订单号不同、渠道维度不同、支付时间不同。如果你把粒度定成“一个用户一天一行”,那这两笔钱就会被揉在一起,渠道分析、档位分析、活动效果分析全都会乱掉。

笔试题里,粒度写没写清楚,是最容易被扣分的地方。我见过很多候选人设计表的时候字段写得密密麻麻,但问他一行的粒度是什么,支支吾吾说不出来。实际上粒度写不明白,后面所有统计逻辑都会飘。答题时第一行就写清楚“粒度:每笔支付订单一行”,这相当于给阅卷人一个定心丸。

2.2 事实表:度量指标的设计与选择

事实表是数据分析的“主体”,里面装的是业务过程产生的度量值。订单事实表的核心字段,大致长这样:

字段类型字段示例说明
维度外键user_id, channel_id, product_id, date_id关联用户、渠道、道具商品、时间等维度表
退化维度order_id, order_no订单号直接放事实表,方便查明细和去重
度量字段order_amount, pay_amount, discount_amount, item_count订单金额、实付金额、优惠金额、道具数量
状态字段pay_status, order_status, refund_status成功、失败、退款等状态,用于口径过滤

注意度量字段的“可加性”问题。订单金额、实付金额、道具数量都是可加性度量,任意维度组合都能直接sum,没问题。但比率类指标,比如付费率、转化率,就不能直接sum,必须先算分子分母再相除。这种题笔试里经常挖坑,比如让你统计各渠道总收入,你直接sum一个“付费率”字段,那就明显露怯了。

还有一个隐蔽细节:退单怎么处理。是支付成功后进入事实表,退款时把状态置为已退款,还是直接又插入一条负金额的抵消记录?这两种方案在实际项目里都有人用,但口径必须统一。如果笔试题给了状态字段,答案里最好主动说明“只统计订单状态为支付成功的记录,退款单用状态字段排除或者以负值冲减”,这样能体现出你对数据质量的敏感度。

2.3 维度表:常用维度与缓慢变化维处理

维度表是事实表的“通讯录”,用来描述事实数据的角度。订单分析常用的维度表有这几种:

  • 用户维度:用户ID、注册时间、注册渠道、首次登录时间、区服、设备型号、新手引导完成状态。
  • 渠道维度:渠道ID、渠道名称、渠道类型(官方包/广告投放/应用商店/线下活动)、推广活动归属。
  • 商品或道具维度:道具ID、道具名称、档位、原价、现价、道具类型,以及所属的礼包活动。
  • 时间维度:日期、周几、是否节假日、是否活动日、所属自然周/月。

维度表最难的点是缓慢变化维,也就是SCD问题。举个游戏场景下的例子:一个玩家一开始是通过广告渠道注册的,后面被归因到另一个渠道,渠道维度要怎么改?如果直接覆盖原名,那历史订单的渠道归属就全变了;如果保留原值不改,那后续分析又拿不到最新信息。实际中最常用的方案是拉链表,通过增加生效时间、失效时间和当前标志位,让维度表既能还原历史,也能支撑最新状态的查询。

笔试里如果出现“用户VIP等级持续变化,订单数据要按当时VIP等级分析”这种题,能想到用拉链表设计用户VIP维度,基本就是加分项。另外,订单号、支付流水号这类属性,不需要单独建维度表,直接退化放到事实表里,既能减少join又能方便排查问题,这也是维度建模里的经典设计。

2.4 数仓分层设计在订单场景中的落地

数仓分层几乎是必考题,但在订单场景里怎么落地,很多人只会背“ODS、DWD、DWS、ADS”这串字母,不知道每层到底放什么。我用订单分析场景串一遍:

  • ODS层:原样接入订单流水、支付回调日志、埋点事件日志,尽量保持和源系统一致,不做过多的数据清洗。
  • DWD层:订单明细表,对ODS数据做清洗、去重、格式统一、枚举值规范,补全用户维、渠道维等外键。这一层是事实表的真正落地位置,粒度还是每一笔订单一行。
  • DWS层:按用户维度汇总的每日付费表、按渠道维度汇总的每日收入表、按道具维度汇总的销售统计表。这里是公共汇总层,存储的是经过合理粒度汇总的指标。
  • ADS层:面向具体报表需求生成的数据,比如运营看板要的“活动期间各渠道ARPU”,或者是“大额付费用户榜单”。

这里想特别强调DWS层的作用。如果每个报表需求都直接从DWD层拉数,每一次都扫全量订单明细,又慢又浪费资源,而且不同报表算出来的口径还可能对不上。DWS层把高频指标提前算好,业务方查询的时候直接按维度过滤聚合,效率和口径一致性都会好很多。笔试设计题能写出这一层的设计思想,说明你不是光会建表,而是真的理解数仓分层的价值。

3. SQL题拉开的分差:数据质量与业务口径

3.1 留存率计算:一道典型的Hive SQL笔试改编题

留存率是游戏数仓最经典的面试题,笔试出现的频率也极高。题目通常给两张表:一张用户注册表,记录每个用户的注册日期;一张活跃表,记录用户每天的登录行为。要求计算某种渠道或全量新增用户的次日留存率。

这类题本身不难,但坑很多。先看一个标准写法,Hive/Spark SQL语法都能跑:

-- 用户注册表:user_reg(reg_date, user_id, channel_id) -- 用户活跃表:user_active(active_date, user_id) with new_users as ( select user_id from user_reg where reg_date = '2020-08-01' ), active_next as ( select distinct user_id from user_active where active_date = '2020-08-02' ) select count(a.user_id) as new_user_cnt, count(b.user_id) as retained_user_cnt, round(count(b.user_id) / count(a.user_id), 4) as retention_rate from new_users a left join active_next b on a.user_id = b.user_id;

先说说为什么这么写。第一步先把“2020-08-01注册的用户”取出来,得到新增用户集合;第二步取“2020-08-02活跃的用户”并去重,因为一个用户一天可能登录很多次,不去重就会把留存人数算高;第三步用left join把新增用户和次日活跃用户关联起来,再统计人数和比率。

这种题的加分点在于,你能主动说明口径。比如“新增用户”的定义是注册成功就算,还是需要完成创角才纳入统计;“次日”是自然日还是按用户首次登录时间往后推24小时;是否要剔除测试账号和内部账号。你在答案里写一句“按自然日统计且剔除测试账号”,阅卷人立刻知道你在真实项目里待过,而不是只会套模板。

3.2 窗口函数三板斧:连续登录、分组TopN、滑动计算

窗口函数是数据仓库笔试的高频区,连续登录、分组TopN、滑动计算这三类题,基本是“必刷三件套”。

先看连续登录。经典问题是“找出每个用户连续登录天数最长的区间”。核心思路是去重后,用row_number()给每个用户的登录日期编号,然后用登录日期减去编号得到一个“标记日期”。同一段连续登录的记录,它们的标记日期是一样的。最后按用户和标记日期分组,统计天数即可。这个巧妙点在于把“连续性”转化成了“差值相等”,在笔试现场能写出这个思路的,说明是真正练过窗口函数。

再看分组TopN。比如“统计每个渠道收入排名前三的用户”,只需要用row_number()或rank()按渠道分区、按收入降序排列,然后取rn <= 3。注意row_number和rank的区别:如果两个人收入一样,row_number会随机分1和2,rank会都给1然后跳过2。题目如果要求并列,就要选rank。

滑动计算比如“近7天每个用户的累计付费金额”,用sum(amount) over(partition by user_id order by pay_date rows between 6 preceding and current row)就能实现。这道题考的不只是函数语法,还考察你是否理解窗口的范围定义。总体来说,窗口函数题没有太多捷径,把执行顺序搞明白——先where过滤、再分组、再开窗——比背一百道SQL题都管用。

3.3 笔试里最容易失分的脏数据与口径处理

校招笔试很多时候不会给你一份“干干净净”的数据,而是故意埋一些脏数据。比如订单表里有重复订单、有支付失败的记录、有测试账号的充值、有退款单。这种题想看你有没有真实的数据处理经验,而不是理想化的“select sum(amount) from order”。

我实际工作中就遇到过,线上订单表里居然有超过10%的重复流水,原因是支付回调的重试机制导致同一笔订单被写入多次。在这种数据状态下,直接按订单号去重、保留每个订单最新状态的那条记录,是必须有的操作。笔试里如果遇到类似表结构,答题时第一句话就应该写明“先按订单号去重,按支付时间取最新一条,并过滤支付失败和退款记录,再统计收入”。

还有一个很多人忽略的点:业务口径。比如“付费收入”到底是毛收入还是净收入?是否剔除退款?一个订单分了三期支付算一单还是三单?这些口径不定义清楚,SQL写得再漂亮也没用,因为算出来的数字不一样。笔试阅卷人往往更看重你有没有主动定义口径的意识,这比SQL语法对不对更能说明你的数仓素养。

3.4 SQL之外的隐形加分项:分区、压缩、数据倾斜

有些笔试设计题不要求你真跑一个SQL,但你可以在方案里顺手写出工程化的细节,这是隐形加分项。

比如订单表规模巨大,该怎么设计分区?比较常见的是按天分区,数据量特别大时再考虑按渠道或业务线做二级分区。存储格式上,生产环境一般用ORC或Parquet,配snappy或zstd压缩,能大幅度减少扫描量。笔试答题时加一句“采用ORC格式按天分区存储”,会显得你懂真正的生产环境,而不是只会写demo。

另一个高频考点是数据倾斜。游戏数仓里“官方包”这种渠道用户量极大,join的时候很容易把某个reduce任务压垮。常见的解法包括:大key加随机前缀打散,然后再做二次聚合;或者利用map join让小表直接加载到内存,避免shuffle;再或者先用过滤条件把大部分数据剔除再join。能把倾斜问题讲出两三招的人,实际工作里大概率已经处理过真实数据了。

4. 从笔试到入职:数据仓库开发岗的备考路线与实战心得

4.1 知识框架搭建与资料选择

如果你现在正准备校招,想体系化地复习数据仓库方向,我建议按四个阶段来安排时间。

第一阶段是数仓基础,核心就是数仓分层、维度建模理论、事实表和维度表的设计方法。这阶段推荐《数据仓库工具箱》也就是Kimball那本经典书,重点看维度建模的部分,不用从头啃到尾,把维度和事实的设计准则看完,配合例子动手画一遍表结构,比只看书强很多。

第二阶段是Hive和Spark SQL,重点练窗口函数、复杂查询、UDF/UDAF的基本写法。这个没有捷径,就是刷题,但刷完每道题最好都记一下这题的“考点关键词”,比如“distinct去重”“row_number用于连续问题”“left join算留存”等,方便考前快速过。

第三阶段是真实场景的建模练习,可以找一个订单数据自己设计一套从ODS到DWS的表结构,再把几个核心指标的SQL写出来。这是笔试设计题的关键对应能力,也是面试时能拿出来讲的项目素材。

第四阶段是周边知识,包括调度工具Airflow/DolphinScheduler的基本原理,元数据和数据血缘的概念,数据质量监控的常用手段。这部分笔试不一定考,面试却大概率会聊到。

4.2 做一次“从零到一”的建模练习

我给所有准备数仓岗笔试的同学都提过同一个建议:找一个业务场景,把整个数仓设计流程完整走一遍。最简单也最贴近笔试热点的场景,就是“用户订单分析”。

具体做法大概是这样的:先明确需求,比如运营要看每天不同渠道的付费金额、订单数、付费用户数和客单价;接着按业务过程确定粒度,设计DWD层的订单事实表,字段包括订单号、用户维度外键、渠道维度外键、时间维度外键、订单金额、实付金额、支付状态;再设计用户维度表、渠道维度表和时间维度表,把每个字段的类型、含义、主键都列清楚;最后写出两三条统计SQL,分别把“各渠道日收入”“各渠道付费用户数”“按用户维度汇总的月付费金额”算出来,并说明这些SQL应该挂在DWS层的哪张汇总表上。

这套练习做完,你会发现笔试设计题基本就是这套流程的简化版。更重要的是,你能理解为什么事实表要存度量值、维度表要处理缓慢变化维、分层要建在什么位置,这些是背概念背不出来的。

4.3 我复盘笔试时发现的三个典型错误

带过不少简历和面试,也批过大大小小的笔试记录,我发现准备数仓岗的人容易踩三个坑。

第一个坑是只写表结构不写粒度。很多人设计订单事实表,字段写得满满当当,但一问他这一行代表什么,支支吾吾说不清。笔试答题时,开头就把“每行代表一笔支付订单”写清楚,是体现建模基本功最简单的一步。

第二个坑是把业务属性一股脑塞进事实表。比如把优惠券ID、活动ID当作字段直接放事实表,看起来能查,但这其实是维度属性,应该通过维度表外键关联,而不是在事实表里存一堆业务代码。这样设计会导致后续维度更新时事实表跟着遭殃,维护成本极高。

第三个坑是只看重“写SQL”不看重“翻译需求”。实际上,入职后你每天要接到的需求大多是运营的一句话,比如“帮我看下最近活动哪个渠道拉新效果最好”。这句话翻译过来,是要先定义活动期、再定义拉新、再按渠道分组、再对转化和留存做对比。笔试里的业务分析题就是在模拟这种场景。前期把这种翻译能力练好,入职适应期会短很多,也更对面试官胃口。

4.4 真想进游戏公司数仓,还要补什么

如果目标就是搜狐畅游这类游戏公司,除了通用的数仓知识,我建议再重点补几个游戏行业特有的话题。

首先是游戏埋点。游戏客户端会上报海量事件,比如注册事件、创角事件、登录事件、关卡事件、新手引导完成事件、支付事件。这些事件数据怎么组织成事件表和用户行为明细表,是游戏数仓绕不开的设计点。你会看到很多游戏公司的事实表,不只有订单一种,还有大量行为事实,这是和电商数仓很不一样的地方。

其次是LTV和ROI。游戏公司对买量投放效果极其敏感,所以数仓要为渠道归因、LTV预估、ROI分析提供基础数据。了解用户生命周期价值这个指标的计算逻辑,以及渠道归因的基本方案,面试聊起业务场景会非常有优势。

最后是离线和实时的边界。校招笔试一般只考离线数仓,但游戏公司对实时指标的需求越来越强烈,比如实时DAU、实时流水、活动实时战报。提前了解Flink、Kafka的基本概念,以及实时数仓和离线数仓的架构差异,哪怕只是能说出分层思路,也会在面试中成为亮点。

最后说一点个人体会。当年我准备笔试的时候,也走过一段刷题刷到麻木的路,后来真正入职做数仓才发现,最好的复习方式不是把题库背完,而是把“一份订单数据从产生到变成运营报表”的整个过程亲手做一遍。你越理解业务方怎么用数据,就越知道维度表和事实表该怎么设计,越知道分层该怎么搭。希望这份复盘能帮你把复习重点从“背概念”转到“建模型”上,在笔试里写出让阅卷人眼前一亮的答案。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/1 22:17:06

360春招笔试复盘:从字符串模拟到贪心二分的工程化考查

1. 先说说360笔试的题量布局和时间分配 2023年春招笔试&#xff08;第二批&#xff09;我实际参加下来&#xff0c;整体感觉和互联网大厂常见的"两道编程题搞定一场笔试"的路子不太一样。360的笔试系统里&#xff0c;编程题占大头但不是全部&#xff0c;前面还有一块…

作者头像 李华
网站建设 2026/9/1 22:11:36

高校自助打印系统哪家稳定耐用:【印萌】硬核抗耗

导读&#xff1a;随着国内高等教育数字化建设持续推进&#xff0c;校园文印服务的数字化转型已经成为众多高校后勤升级的重点方向。根据行业调研数据显示&#xff0c;全国超七成本科院校已经部署或者计划部署高校自助打印系统&#xff0c;传统人工打印门店的运营模式&#xff0…

作者头像 李华
网站建设 2026/9/1 22:11:18

基于卡尔曼滤波的视频目标跟踪实战:运动小球轨迹平滑

简介&#xff1a;本资源是一套面向计算机视觉初学者与图像处理实践者的卡尔曼滤波视频跟踪教学实践包&#xff0c;聚焦运动小球这一典型目标&#xff0c;解决噪声干扰下目标位置估计不稳、轨迹跳变等实际跟踪难题&#xff0c;适用于课程设计、毕业设计及算法入门项目。压缩包共…

作者头像 李华
网站建设 2026/9/1 22:10:57

【OFDM通信】高速铁路场景下的OTFS与 OFDM性能对比Matlab仿真

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。&#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室&#x1f447; 关注我领取海量matlab电子书和…

作者头像 李华
网站建设 2026/9/1 22:09:59

【单片机毕设案例分享】基于单片机的环境参数采集与智能加湿报警系统设计 基于 STM32 或 51 单片机的语音声光双重提示加湿控制系统开发(024905)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于单片机&#xff0c;STM32单片机&#xff0c;51单片机&#xff0c;J…

作者头像 李华