1. 一场笔试背后的游戏研发能力地图
看到标题里的“游戏研发B试卷”几个字,我第一反应是:2019年这个时间点很特殊,移动游戏市场刚刚经历过一轮大洗牌,快手又在积极布局游戏内容生态,这时候的游戏研发笔试,已经不只是考察“会不会写代码”这么简单了。
作为一名游戏行业老开发者,我接触过不少应届生和社招候选人的笔试作业。说句实话,很多人在笔试前拼命刷LeetCode,结果到了考场上发现,算法题只是开胃菜,真正拉开差距的,恰恰是那些“不像编程题”的题目——它们考察的是一个人有没有建立起完整、立体的游戏研发认知体系。
这份试卷的名字叫“游戏研发B试卷”,从命名就能看出,它大概率是针对客户端方向或通用研发方向的岗位。和A卷(可能是算法岗或服务端岗)相比,B卷更侧重于游戏客户端开发的基础功,包括但不限于C++语言特性、数据结构与算法、图形学基础、网络同步、内存管理,以及一部分游戏引擎相关的知识。
如果你正在准备游戏研发岗的校招笔试,或者你已经在行业里,只是想通过复盘笔试题目来查漏补缺,这篇博文就是给你写的。我会把这类试卷背后的出题逻辑、核心考点、备考策略,以及我在实际开发中踩过的坑,所有能让你少走弯路的经验,都一并梳理出来。
2. 破译“B卷”的出题逻辑与考察目标
2.1 为什么笔试前先要读懂出题人的意图
很多人觉得笔试就是“做题”,这个认知害了不少人。其实笔试本质上是一场能力扫描,出题人通过有限的题目,快速判断你作为一个游戏开发者的“底层系统”是否完善。
2019年前后的游戏行业,尤其是快手这个平台,正在大力布局游戏内容。当时行业里有一个普遍痛点:游戏研发人才的缺口巨大,但很多计算机专业的应届生,虽然算法功底扎实,却对游戏开发的理解停留在“写UI逻辑”“调接口”的层面,缺乏对游戏引擎底层原理、性能优化、网络同步等关键领域的感知。
所以你可以看到,这类试卷的题目设置往往呈现出三个明显特征。
第一,覆盖面广但深度适中。一道题可能同时涉及到C++内存管理和STL容器的底层实现,这对没读过源码的候选人来说就是致命伤。第二,游戏场景驱动。很多题目会包装在一个游戏业务场景里,比如“玩家A移动时如何同步给玩家B”“场景内有10000个物体如何快速碰撞检测”,考察的是你能否把基础理论知识迁移到实际问题中。第三,陷阱密集。不少题目表面上是考语言基础,实际上是考你在真实项目中会踩的坑,比如迭代器失效、隐式类型转换、深浅拷贝问题。
2.2 从出题风格反推技术栈要求
快手游戏研发在2019年正处于布局期,技术栈上既有自研引擎的使用,也有Unity、Unreal这类商业引擎的深度应用。从B卷的命名来推断,大概率考察的是偏C++的技术栈,因为Unity的IL2CPP层、Unreal的整个底层框架,都是C++写的,客户端研发想深入引擎源码,绕不开C++这道门槛。
这也就解释了为什么这类校招笔试卷里,C++相关题目往往占比最大。出题人想要筛选的不是“会用C++语法”的人,而是能在内存受限、性能敏感的游戏环境中写出高效、安全、可维护代码的人。
另外还有一个容易被忽略的信号——试卷里“游戏研发”四个字,说明了岗位定位是广义的游戏开发,而不是单纯的引擎开发或工具开发。这意味着你可能还需要具备一定的游戏逻辑架构能力,比如对状态机、行为树、观察者模式等设计模式在游戏中的应用有基本认知。
3. 核心考点逐个拆解:每个模块背后的真实项目影子
3.1 C++底子:不是会用,而是要懂“为什么”
在游戏研发岗笔试中,C++基本上是最核心的考察模块。但我见过太多候选人,能熟练写出for循环和vector的操作,却答不上来“vector扩容为什么是1.5倍或2倍”“虚函数表存在哪里”“空类为什么是1字节”。这些问题不是面试官故意刁难,而是实际开发中真正会遇到的问题。
拿vector扩容举例。在游戏服务端处理玩家进入场景的实体列表时,如果一个容器在逻辑帧内频繁触发扩容,会发生内存分配和拷贝。GC的压力不说,光是时间消耗就可能让逻辑帧超时,造成卡顿。所以游戏引擎里很多容器在初始化时就会预估容量,提前reserve。能理解这个问题,说明你真的在考虑代码运行时的性能,而不只是让代码“能跑”。
再比如虚函数。游戏中的多态无处不在,战斗系统里的技能、AI系统里的状态、UI系统里的控件,都会用到虚函数。但如果你知道虚函数的调用是一次间接跳转,在每帧调用数万次的系统里,这也是不可忽视的性能开销,你就会理解为什么有些核心循环里会改用模板或手动分派,而不是依赖虚函数。
笔试中这类“语言特性和性能结合”的题目,本质上是考察你有没有性能敏感的开发意识。学习建议也很直接:不要只看语法书,一定要结合游戏或引擎源码去理解。
3.2 数据结构与算法:场景化是最大的分水岭
纯粹的数据结构题目,比如手写红黑树、B+树,在游戏研发岗位里并不多见,但数据结构的思想却融入了几乎每一个游戏系统。
我在项目里经常遇到这类问题:场景里有几千个怪物,玩家放一个范围技能,需要快速找出以玩家为中心、半径10米内的所有怪物。如果线性遍历所有怪物,每帧做几千次距离计算,性能再好也会顶不住。解决方案就是用空间分区结构,比如四叉树、八叉树或者网格划分,先把怪物挂载到格子或节点里,然后只检测周围几个格子里的怪物。
笔试出现这类题目,考的不是你会不会背八叉树的定义,而是你能不能想到用空间换时间,能不能估算出不同方案在大规模对象下的性能差异。备考的时候,建议大家牢牢掌握这些数据结构:数组、链表、栈、队列、哈希表、树(二叉树、平衡树、堆)、图的基础遍历算法。每一个都要能回答三个问题:底层实现是什么?时间/空间复杂度是多少?在游戏业务里我会用它来解决什么问题?
这里有一个我特别推荐的练习方法:把算法题套进游戏场景里做。比如“求从A点到B点的最短路径”,不要满足于在网格图上做BFS,而是思考如果地图中有河流(障碍)、有地形消耗(不同区块移动成本不同),应该怎么改。这样练过之后,笔试出现任何场景化算法题,你都能自然地联想到对应的数据结构。
3.3 图形学基础:入门容易,深入全是坑
图形学是客户端游戏研发的“看家本领”,但校招笔试不会考太深的渲染管线实现,而会更侧重于基础概念的掌握和数学推导的扎实程度。
我遇到过一道经典题目:给一个三维坐标系的向量,要求将其旋转90度后输出。看似简单,但很多候选人矩阵乘法忘了顺序,把旋转矩阵左乘右乘搞反了。这个细节在引擎里就是“模型旋转方向相反”的致命bug,调试起来能让人崩溃。
还有一个高频考点是变换矩阵的分解,比如模型从本地空间变换到世界空间、相机空间、裁剪空间,整个过程中矩阵乘法的顺序是什么。这个问题的背后是Unity和Unreal渲染流程的基础逻辑,笔试考的就是你对引擎底层空间的感知力。
如果你是零基础,我的建议是先把线性代数的核心找回来:向量点乘(判断前后关系)、叉乘(求法向量)、矩阵乘法、四元数基本概念。然后找一篇Unity或Unreal的渲染流水线介绍,把顶点从本地坐标到屏幕坐标的完整路径走一遍,这样图形学题目基本能拿到大部分分数。
3.4 网络与同步:最容易暴露“缺乏项目经验”的模块
网络同步是游戏研发里最复杂、最“吃经验”的领域之一,也是笔试中区分度最高的模块。没有做过完整联网项目的候选人,在这个模块上的答错率极高,因为这类题目没有标准“教科书答案”,考的是对实际情况的理解。
一个典型的题目会是:玩家A在客户端移动一个单位,如何让玩家B看到同样的效果?如果每帧同步位置,相同条件下带宽够不够?如果状态同步和帧同步分别适用什么类型的游戏?
这些问题的背后,牵扯到几个核心概念:帧率与网络条件的匹配、状态同步和帧同步的取舍、插值和延迟补偿、“防作弊”的考虑。
关于状态同步和帧同步,我用一个类比来解释:状态同步就像老板每周汇报一次工作,条理清楚,适合复杂项目;帧同步就像每个员工每秒钟同步一次操作键盘的指令,精确到每个动作,效率高但适合规则简单、逻辑固定的项目,比如格斗游戏、RTS游戏。
笔试里这类题不需要你写完整同步框架,但你要能说清楚选择方案的核心依据:游戏类型、网络环境、客户端算力、服务器成本。如果你在项目里写过聊天系统、道具同步、移动同步中的任何一种,都有助于形成自己的判断,而不是生搬硬套概念。
3.5 设计模式与架构:笔试中最“软”的硬实力
谈到游戏架构,很多应届生会觉得“这是主程该考虑的事”,但笔试偏偏就爱考这类题,比如“如何设计一个背包系统”“如何设计一个技能系统”“如何管理UI窗口的打开关闭”。
这种题目考察的是实体组件系统(ECS)思想、状态机、观察者模式、工厂模式在游戏中的实际应用。见过不少候选人在这种题上写一堆类图和接口,但实际推演时逻辑混乱,这是因为缺少“以数据驱动为核心”的架构直觉。
以UI管理系统为例,如果只是简单地把每个打开窗口的实例丢进一个栈里,那么“打开新的窗口同时关闭旧的”“界面被弹窗覆盖时不应响应底层操作”这类需求就会变成一个接一个的if else。更好的方案是设计一个UI管理器,通过栈管理窗口层级,配合事件系统对外广播窗口生命周期事件。笔试中能写出这种方案,你的架构能力就能和普通候选人拉开差距。
4. 笔试实战方法论:从刷题到模拟的训练全流程
4.1 专项突破阶段:把知识体系“模块化”
我从辅导过的一些候选人身上总结出一个规律:仓促刷题三个月,不如模块化备战六周。备战的第一阶段,应该按照上面梳理的核心知识点,把复习拆分成几个独立的模块。
模块一是C++底层机制,重点复习内存布局、虚函数机制、智能指针、STL底层、移动语义;模块二是数据结构与算法,从链表、树、图到动态规划,每个都用游戏场景去包装;模块三是图形学和数学基础,矩阵变换、光照模型、空间划分结构;模块四是网络同步,从TCP/UDP的差异出发,延展到游戏中的同步策略;模块五是架构设计,多分析经典游戏系统的模块划分。
每个模块复习结束后,我会建议你给自己出一份模拟卷,按真实考试的时间约束来闭卷作答。没有真实项目经验没关系,但要把“行业里最合理的做法”推理出来,并写下自己的思考过程,这个过程本身就是笔试能力的一部分。
4.2 “白盒化”学习:看引擎源码胜过刷十道题
我在这个行业做了十几年,见过太多候选人背了一堆概念却对引擎源码一无所知。如果你真的想和“普通候选人”拉开差距,我强烈建议你在笔试前,把Unity的Transform组件或Unreal的Actor组件生命周期源码认真读一遍。
以Unity的Transform为例,很多候选人知道“父子节点会影响子物体位置”,但如果你去读源码,就会知道Transform的localPosition和position之间的换算关系,知道当修改父节点时引擎会如何标记children的transform被“dirty”,进而影响下一次渲染的矩阵更新。笔试若出现“为什么频繁修改父物体Transform会导致性能下降”这类问题,你就能给出比“因为Unity要重新计算”深好几层的答案。
4.3 实战输出阶段:用“讲给自己听”验证理解
当核心知识复习完两遍以后,就到了输出阶段。这一步很多人会忽略,但它恰恰是检验理解深度最高效的方法。
方法很简单:挑一个你在项目里做过或笔试中遇到过的模块,比如“技能系统”,把它拆解为需求分析、数据结构、核心逻辑、优化思路四个维度,然后完整地讲给“身边的小白”(或者录音下来放给自己听)。如果在讲的过程中你发现自己卡壳了,甚至发现自己用了“大概”“可能”这样的词,说明你对这个模块的理解还存在盲区。
这个方法对应的正是笔试大题中“设计一个XX系统”的答题思路。出题人看不到你写代码的过程,只能通过你写在卷面上的组织能力来评估你的工程素养。能用清楚的语言把复杂系统讲解明白,这项能力本身就能让你在笔试卷面上多拿不少分。
5. 那些年我们绕不开的“坑”:高频失分点速查
5.1 C++中的“冰山陷阱”
C++的题目之所以有区分度,是因为它表面考语法,深层考机制。几个我在批改试卷时经常看到候选人失分的重灾区,集中在这里。
一是迭代器失效问题。在遍历vector时插入或删除元素,很多候选人以为“越界了也没事”。实际上底层的连续性决定了插入后会触发内存移动,所有迭代器都可能失效,在游戏实体的动态增删中尤为致命。正确的做法是利用返回的新迭代器,或改用“先标记后统一处理”的延迟删除思路。
二是浅拷贝和深拷贝。游戏里的背包、装备、Buff类,如果包含堆内存资源却只用默认拷贝构造,会出现多个对象指向同一块内存,轻则逻辑错乱,重则二次释放导致崩溃。笔试考到拷贝构造和赋值运算符重载时,一定要有“是否涉及指针管理”的判断意识。
三是隐式类型转换。一个很容易踩的例子是:类里定义了单参数的构造函数,且没有加explicit,那么一个int或一个字符串就会被隐式地转成这个类的对象。在游戏战斗逻辑中,这种隐式转换可能会导致一个技能ID被悄悄包装成一个无关的对象,查错时极其隐蔽。
备考建议是:每学一个C++特性,就追问自己一句“这个特性在游戏引擎或项目里是如何被使用的”,带着这个问题去读源码,比你单纯背语法规则高效得多。
5.2 算法中的“性能不合规”思维
算法题在笔试里占的比重不算小,但游戏研发岗的算法题和平常刷的LeetCode有一个非常大的差异:游戏研发更关注在线场景下的持续性能,而不仅仅是“一次运行有结果”。
例如同样是“判断玩家当前位置是否在某个凸多边形区域内”,如果你选择了射线法但每帧对所有多边形做全量检测,100个玩家×100个区域,每帧就是10000次计算,在移动端帧率直接崩掉。而如果你能想到先用AABB包围盒做粗筛,再做精细的射线法判断,就把性能降了一个数量级。
所以在准备算法题时,建议在解出题目之后,再多思考两个问题:这个算法如果跑在每帧的循环里,性能可不可接受?如果数据规模扩大10倍,我的方案还成立吗?这种“性能合规”的思维,才是游戏研发笔试真正希望看到的东西。
5.3 图形学中的“维度混淆”
图形学题目失分,往往不是候选人不会算,而是空间维度没理清。
一个很常见的错误是,把世界空间和本地空间的变换顺序混淆。假设一个怪物模型挂在小车上,小车在场景中移动,怪物相对于小车还有一个偏移。要求怪物在世界空间中的位置,必须先应用怪物的本地偏移,再应用小车的世界变换;如果顺序反了,怪物就会在“你的期待”之外出现一个奇怪的浮动偏移。
类似的还有将方向向量(无位置属性)和点向量(含位置属性)混为一谈。在平移变换中,点的w分量是1,方向向量w分量是0;如果处理时没有区分,方向向量也会被平移,造成光照方向或法线方向错误,这在渲染中就会呈现“阴影飘了”的诡异Bug。
这种失分非常可惜,因为不是不会,而是基础知识没有形成系统。建议你亲手在纸上推导一遍Unity/Unreal的MVP矩阵(模型-视图-投影矩阵)流程,把每个空间的名字和作用写清楚,再对着引擎文档核对自己答案。
6. 从笔试到Offer:时间规划与临场技巧
6.1 八周备战时间线(针对非科班/基础薄弱者)
很多人在看到这类笔试题后第一反应是“完了,我什么都还没准备”,然后陷入焦虑刷题的循环。实际上,合理的备考时间安排比盲目投入更重要。我按自己辅导过的成功案例,给出一份八周时间线,供你参考。
第一周至第二周,集中巩固C++基础,重点复习面向对象三要素、内存管理、STL常用容器底层原理;第三周至第四周,进入数据结构和算法专项,每天固定2道算法题,必须用纸笔手写一遍再上机验证;第五周,主攻图形学基础和渲染流水线,配合Unity或Unreal的文档阅读;第六周,研究网络同步、空间划分和性能优化思路,多读行业内技术分享;第七周,搜寻目标公司近两年的真题,掐时间进行全真模拟;第八周,查漏补缺,整理错题本,复习自己写的系统设计方案。
这份时间线最大的特点是:每周只专注一个大目标,避免“一天看好几门课”的浅尝辄止。如果你想压缩到四周,那每一部分的时间都要减半,C++和算法仍然是不可放弃的底线。
6.2 考场上的答题顺序与时间分配原则
笔试过程中,答题顺序直接关系到最终分数,这个经验是很多成功上岸的候选人验证过的。我建议的通用策略是:先花2到3分钟浏览全卷,标记出“有把握的题”“需要思考的题”“完全没有思路的题”,然后按顺序答题,但有技巧。
优先解决有把握的题,确保这部分拿满基础分;然后攻有思考空间的题,这类题通常是大题,比如“设计一个系统”或“推导一个变换过程”,即使结果不够完美,只要思路清晰、步骤详尽,也能拿到过程分;最后剩下的时间,可以去“碰”完全没思路的题,写一些基础的公式或概念,尽量不要留白。
很多人在“最难的题”上死磕半小时,结果后面简单的题反而没时间写。这个坑一定要规避,校招笔试的分数线往往不是靠难题拉开的,而是靠中低档题的准确性拉开的。
6.3 技术招聘之外:怎样让笔试转化为面试优势
笔试的结束不是战斗的结束。一次笔试本身,就是你面试时最宝贵的谈资。
我认识的一位候选人,笔试时有一道题不会,但他把题目抄下来,回去后用引擎跑了一个Demo,模拟了那个场景,并把过程整理成一篇笔记。面试时他主动提起了这件事,面试官对他的评价是“有技术好奇心且行动力很强”。
建议你在笔试后把能回忆起的题目全部记录下来,尤其是自己没有答好的部分,用48小时内的时间查资料、复盘、整理成文档。这不仅是为了面试,更是帮你把一次笔试转化成真正的能力沉淀。每经历一次笔试,你对游戏研发的知识体系、对行业的需求方向,都能有一个质的提升。
7. 写在最后:游戏研发这条路上的“长期主义”
游戏研发岗的笔试,考察的从来不是“临阵磨枪”的突击能力,而是你过去几年在计算机基础、编程实践、游戏认知上沉淀的总和。一场笔试,更像是一面镜子,如实反映了你的知识盲区、思维习惯和工程素养。
我自己在这些年的招聘中看过太多简历,见过太多“刷题机器”和“项目空壳”——简历上写着精通C++、熟悉渲染管线,却连自己的Demo在低端机上跑不满帧的原因都说不清楚。反而是那些踏踏实实把每一个类、每一个系统都想明白、写明白的人,不论笔试还是面试,都能走得最远。
如果你正在准备笔试,请把这份冲刺当成一次系统性学习的机会,而不是单纯“通关”任务。每梳理一个知识点、每写完一套模拟卷、每复盘一道错题,都是在为你未来真正进入游戏行业搭建地基。毕竟,考场上的答案只是起点,能够做出让玩家沉浸其中的游戏,才是我们做游戏研发最终极的考核。