ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

游戏公司技术岗笔试题复盘:从编程题到帧同步的考点全解析

游戏公司技术岗笔试题复盘:从编程题到帧同步的考点全解析 2017年秋招我准备投游戏公司技术岗翻来覆去研究过好几家厂商的笔试题库。等到真正坐在考场上拿到吉比特这套“技术类笔试卷”时第一反应是这题出得确实够“游戏公司”——它不是单纯考你LeetCode刷了多少道而是每个考点都隐隐指向一个游戏研发岗位的真实工作场景。时隔几年再复盘这套题你会发现它考察的维度、题型排布、甚至某些“送分题”的陷阱放到今天的校招笔试里依然有很强的参考价值。无论你是准备投游戏公司技术岗的在校生还是想转行做游戏开发、想了解游戏公司技术笔试底细的工程师这篇复盘都能帮你少走弯路。我会尽量还原当时的题型分布、解题思路以及我踩过的坑和后来的反思。1. 吉比特这套卷和普通互联网公司笔试题差在哪先说一个很多人会忽略的背景吉比特在游戏圈里的位置比较特殊。它不像腾讯网易那样体量巨大、岗位划分极细但作为一家以自研产品起家的A股上市游戏公司它的技术团队对候选人的要求往往更“全栈”一些。2017年正是移动游戏从粗放增长转向精细化运营的节点吉比特旗下产品线也在快速扩张这时候招技术岗看重的绝不只是刷题能力而是能不能直接上手解决游戏研发中的实际问题。所以这套笔试卷有明显的“混合气质”。它包含了互联网公司常见的计算机基础知识选择题但选择题里会更偏向网络、内存、并发这些游戏服务器和客户端都会用到的底层知识它也包含算法编程题但这些题不是简单的“反转链表”或“两数之和”而是带着场景比如地图寻路、资源调度、状态同步需要你先把业务问题抽象成算法问题再动手写代码。同样值得注意的是这套卷子对“经验性知识”的考察。游戏开发领域有很多东西是学校里不教、但项目里天天用的比如渲染管线、DrawCall、热更新方案、帧同步与状态同步的区别。吉比特这套卷子里就有一部分题目专门考这些你光会写代码不行还得真对游戏研发流程有了解。这一点和当年很多互联网大厂的笔试题有本质区别——大厂校招更看重算法底子和学习能力游戏公司校招则更看重“你来了能不能快速融入项目”。我当时的感受是这套卷子的出题人大概率就是游戏项目组里的技术负责人而不是HR或专门的笔试出题团队。题目里藏着一股“我们踩过这些坑所以想看看你知不知道”的气息。这种风格在后来我面试其他游戏公司时也遇到过但吉比特这套卷算是我见到的第一批把“游戏研发实战”和“计算机基础”融合得比较自然的题目。2. 还原2017秋招笔试的题型结构分值、时长与考察权重网上关于这套卷的回忆版不少综合整理下来整体结构大致是这样的具体细节各年份会有出入但考察框架相对稳定题型题量分值占比核心考察方向单选题20题左右约30%C/C、数据结构、操作系统、计算机网络、数据库多选题5题左右约10%对基础概念的深度理解容易因漏选/多选丢分简答题3-4题约20%游戏研发相关概念如帧同步、渲染优化、内存管理编程题2-3题约40%算法设计、代码实现、边界处理能力单看分值分布编程题是大头和很多公司一样。但这里有个细节这套卷子的编程题并不是“一上来就写代码”而是每一道题前面都有一段不算短的场景描述。比如有一道题会先讲“在MMORPG中玩家头顶需要显示名字和称号服务端只下发基础数据客户端要负责排版和碰撞检测时的遮挡处理”然后才让你实现某个核心算法。这种出题方式意味着读题的时间成本很高。如果你习惯了纯算法题的一句话描述第一次做这种题时会很不适应。我当时就因为在第一道编程题上反复读题差点没时间做后面的简答题。这是第一个要记住的经验拿到卷子先扫一遍全部题目别陷进某一道题里。简答题的分值占比不低而且往往是最能拉开差距的部分。选择题大家都能蒙一蒙编程题靠平时积累但简答题完全看你对游戏研发领域的理解深度。比如“帧同步和状态同步各自的优缺点”这种题如果没有实际做过多人在线游戏或者认真研究过相关方案很难答到点子上。还有一个容易忽略的细节是答题时长。这套卷子一共给了120分钟题量不算特别大但加上读题和思考的时间节奏其实相当紧。我当时身边的同学有人做完了还有人时间不够用差距主要出在选择题上——有些人会在纠结某道网络题上花了8分钟结果后面编程题没时间写。所以后面会专门讲一套时间分配策略这部分在笔试里真的能当隐形的20分用。3. 编程题复盘地图寻路、数据解析与状态设计每一道都打在游戏开发的痛点上编程题是整个卷子的核心也是最有“游戏公司特色”的部分。以当年流传的回忆版来看三道编程题分别指向三个游戏开发里的典型场景地图寻路、配置数据解析、状态管理。3.1 地图寻路类题目不只是BFS/DFS有一道题非常典型大致是给一个二维网格地图0表示可通行1表示障碍物玩家从左上角出发需要到达右下角求最短路径长度如果不可达返回-1。这类题在LeetCode上就是“腐烂的橘子”“岛屿数量”那一类问题的变体核心解法是广度优先搜索BFS。但游戏公司的版本会多两个小变化一是地图规模可能很大需要你优化内存占用不能用太大的辅助数组二是可能会要求输出路径本身不仅仅是路径长度。我当时写的解法是标准BFS#include vector #include queue using namespace std; int shortestPath(vectorvectorint grid) { if (grid.empty() || grid[0].empty()) return -1; int rows grid.size(), cols grid[0].size(); if (grid[0][0] 1 || grid[rows-1][cols-1] 1) return -1; vectorvectorint dirs {{0,1},{0,-1},{1,0},{-1,0}}; vectorvectorint dist(rows, vectorint(cols, -1)); queuepairint,int q; q.push({0,0}); dist[0][0] 0; while (!q.empty()) { auto [r, c] q.front(); q.pop(); if (r rows-1 c cols-1) return dist[r][c]; for (auto d : dirs) { int nr r d[0], nc c d[1]; if (nr 0 nr rows nc 0 nc cols grid[nr][nc] 0 dist[nr][nc] -1) { dist[nr][nc] dist[r][c] 1; q.push({nr, nc}); } } } return -1; }但你光写出这个只能拿基础分。想拿高分需要在答案里体现两点思考第一解释为什么用BFS而不是DFS。因为网格是等权的BFS天然保证第一次到达终点时就是最短路径DFS虽然也能找到路径但要回溯所有可能才能确定最短复杂度高很多。第二说明状态设计。dist数组里存的不是“是否访问过”而是“到当前位置的最短步数”这一步其实就隐含了visited标记的作用避免走回头路。如果再进一步可以把dist数组改成原地修改grid值用2表示已访问省掉额外的O(m×n)空间。这种优化在游戏地图很大、内存受限的时候是真实需求。3.2 配置数据解析字符串处理是游戏开发的日常第二道编程题是给一段模拟的玩家日志或配置文件要求解析出指定字段并统计。这种题在LeetCode上对应的就是字符串处理、split、KV解析一类。我记得类似题是给一行一行“keyvalue;key2value2”的配置文本要求解析出某个key对应的value并且值可能是带引号的字符串可能包含转义字符。这道题考察的不是算法而是代码基本功是否会熟练处理字符串边界、是否知道转义、是否考虑到空值和异常格式。游戏开发里这种场景太常见了——策划配表、服务器日志、热更配置大部分数据都是这种“不太规范”的文本格式你要写一个能容忍脏数据的解析器。我当时的反思是这类题没有捷径就是平时多写、注意边界。比如用C写字符串处理时getline、find、substr这些API要熟还要能处理末尾换行符、Windows和Linux换行差异。如果时间紧张先实现主流程再补异常分支比一开始就想把所有边界都覆盖到更稳妥因为考试时间不允许你写完完美解法。3.3 状态设计题有限状态机在游戏逻辑里的应用第三道题比较进阶和游戏里的角色状态、技能释放、AI行为树有关。场景大致是一个角色有站立、移动、攻击、受击、死亡等多个状态不同状态下能响应的事件不同要求设计一个状态管理器实现状态切换并限制非法转换。这道题不是纯粹的算法题更像“设计题代码实现题”的结合。核心是有限状态机FSM的理解和应用。我当时给出的示例思路是enum class State { Idle, Move, Attack, Hit, Dead }; class FSM { public: void addTransition(State from, State to, bool allowed); bool canTransition(State from, State to) const; void changeState(State next); private: State current; mappairState, State, bool transitions; };然后重点解释用二维状态矩阵或map来存合法的状态转换关系比在changeState里写一堆if-else清晰得多。而且游戏里的状态管理通常要触发进入/退出回调比如进入Attack状态时要播放攻击动画退出时恢复移动速度这些都可以挂在状态转换函数里。游戏公司考这种题的目的很清楚想看你有没有“设计可扩展代码”的意识而不只是“能跑就行”。写法上如果能提到“状态模式”或“有限状态机”的设计模式会加分不少。4. 选择题与基础题并发、内存、网络协议想进游戏公司先过这三关编程题决定你能不能进下一轮选择题决定你能不能过线。吉比特这套卷子里的选择题知识点覆盖其实和大部分校招笔试差不多但侧重点有明显倾斜。出了考场之后我和一起笔试的同学对了对题发现大家丢分最多的地方出奇一致并发、内存管理、TCP/UDP相关细节。4.1 并发与多线程游戏服务器的基础课选择题里有多道并发相关题。比如问“多个线程同时读写同一个变量如何保证线程安全”选项里有mutex、atomic、volatile、加锁顺序等。很多校招生只知道加锁但游戏公司更希望你理解mutex开销大但安全适合临界区较大的场景atomic适合整数、布尔值的简单读写性能更高volatile并不保证线程安全它只保证编译器不优化掉读取操作很多新手会在这里踩坑还有一道经典的死锁题两个线程各自持有一把锁然后互相等待对方的锁问如何避免死锁。解法无非是“按固定顺序加锁”或“使用trylock带超时回退”。但放到游戏场景里还要联想到服务器在锁玩家数据时如果不按玩家ID的顺序加锁就可能出现死锁——这点如果能写出来会显得你真的思考过。4.2 内存管理从“什么是内存泄漏”到“如何排查”游戏客户端对内存的敏感度远高于普通应用。选择题里就有“以下哪种操作会造成内存泄漏”这类题目。C方向会考new了没delete基类析构函数没有声明为virtual导致删除派生类对象时只调用了基类析构容器中存放了指针clear之后没有遍历删除指向的对象还有一道我印象深刻的题问“栈上分配和堆上分配的最大区别是什么”。答案不是“速度不同”而是“生命周期不同”。栈上变量作用域结束自动回收堆上变量需要手动释放理解这一点是理解后面内存池、GC的基础。游戏公司考这些是因为3D游戏每一帧都在分配和释放内存如果写代码不注意内存性能会变得很难看。我在答题时专门对“内存池”这个选项做了批注式解释虽然卷子上只是选择题但面试时考官确实会顺着追问“那你知不知道Unity里的GC Alloc是什么”。这种追问逻辑在笔试题目里其实已经埋下了伏笔。4.3 网络协议与SocketMMORPG离不开的底层知识网络部分的题目风格非常“游戏”。有一道题是问“TCP和UDP的区别哪些场景用TCP哪些用UDP”这题本身不难但选项里放了好几个游戏场景比如登录、移动同步、聊天、战斗指令。正确答案方向是登录、充值等需要可靠传输的用TCP角色移动、技能释放等对延迟敏感、可容忍丢失的实时操作用UDP或者用UDP自定义可靠层。这里有个反向认知在竞技游戏里玩家的移动同步很少直接用纯TCP因为TCP的粘包和拥塞控制会导致延迟增加。还有一道关于粘包的题TCP是流式协议接收方怎么判断一条消息的边界答案通常是“定义消息头包含消息长度字段”或“用特殊分隔符”。这几乎是游戏服务器开发最常见的考题。我后来在面试环节还被追问了“Netty的LengthFieldBasedFrameDecoder怎么配置”所以笔试里看似很基础的知识点往往是面试深挖的起点。数据库和操作系统在这套卷子里也会考但权重不及以上三类。数据库无非是索引失效场景、事务隔离级别操作系统则是进程线程区别、虚拟内存、进程调度。这些和互联网公司笔试重合度很高按常规准备即可。5. 游戏研发特色题帧同步、渲染优化、资源管理答出层次才能拉开分这套卷子最有辨识度的题目是简答题里那几个只有游戏公司才会考的题目。它们分值不算最高但区分度极大。不少计算机基础很好的同学在这一块直接懵了因为学校里根本没教过。5.1 帧同步与状态同步怎么答才完整有一道比较典型的简答题解释帧同步和状态同步的区别并分别给出适用场景。我当时的答题思路是三层递进第一层说清楚定义。状态同步是服务器计算所有战斗结果把广播状态给客户端帧同步是所有客户端一致地执行每帧操作逻辑在本地跑服务器只做转发和校验。第二层对比优缺点。状态同步防作弊能力更强逻辑集中在服务端容易做维护和校验但开发和带宽成本高帧同步省带宽、打击感更强、手感更跟手但反作弊难度大客户端要求高度一致。第三层结合游戏类型。类似MMORPG这种角色属性、掉落、养成很复杂的游戏更适合状态同步而“格斗游戏”或“多人竞技塔防”这种强调手感和精确反馈的帧同步更合适。如果能再补一句“帧同步要处理好浮点数一致性和随机种子问题”面试官基本就会在心里给你加分了。这道题没有标准答案但层次感很重要。只写一个优缺点列表的和能把知识点联系到实际游戏类型的得分差距很明显。5.2 渲染管线与DrawCall优化还有一道题是问“Unity或游戏中如何减少DrawCall提升渲染性能”。这题一看就是客户端方向的人出的。回答要点要覆盖合批Batching把同材质、同纹理的小物体合并成一次DrawCall纹理图集Atlas把多个小图合并成一张大图减少实时光照和阴影使用LODLevel of Detail远处用低模遮挡剔除Occlusion Culling不可见的物体不渲染我当时还在答案里写了“静态合批和动态合批的取舍”因为静态合批会额外占用内存动态合批对顶点数有要求。这种细节不是基础知识的堆砌而是看你对渲染优化的理解有没有到项目层面。游戏客户端岗的面试官通常喜欢顺着这道题追问“UI的DrawCall怎么优化”“图片格式用ETC还是ASTC”能把这条线串起来的人笔试分数一般都不低。5.3 资源加载与热更新简答题里还出现过类似“游戏热更新方案对比”的题。2017年前后正是Lua热更和AssetBundleAB包方案混战的时期所以这类题很有时代感但底层思路到现在还在用。答题时可以分三个维度更新什么资源、怎么保证更新过程不断线、怎么减少下载体积。对应到技术上就是资源版本号管理、增量更新、强更与弱更的选择。我提到的是“先下AB包再下Lua脚本顺序不能反过来因为脚本可能依赖新资源”这种项目里踩坑总结出来的经验比背书有用得多。如果你做过Unity项目甚至可以画一个简单的资源加载流程图笔试时用文字描述清楚也一样有效。6. 答题节奏与手写代码考场上的隐形分很多在校生低估了“答题节奏”的重要性。吉比特这套卷子120分钟题量不算变态但陷阱不少——尤其是选择题和简答题之间如果你时间分配不科学很容易出现“编程题没写完、简答题只写一行”的惨状。我给的策略是“三轮答题法”轮次时间任务目标第一轮0-15分钟快速做完会做的选择题确保基础分到手第二轮15-60分钟编程题主流程代码拿稳算法题的主体分第三轮60-100分钟简答题剩余选择题编程题补充优化拿深度分、拉档次最后20分钟100-120分钟检查边界、补注释、检查漏洞减少失分第一轮最重要的原则是遇到不会的选择题先凭第一印象选一个标记出来绝不停留超过1分钟。很多多选题是漏选扣分制如果你没把握宁可选少不要选多这是考了无数场笔试总结出来的血泪经验。编程题的答题顺序也有讲究。我习惯先做“数据解析”那道字符串题因为它套路固定、边界明确做完能快速建立信心地图寻路用BFS也不难状态设计题放到最后因为它更开放、容易写偏。如果一上来就死磕状态设计题后面时间可能就崩了。手写代码时尽量把变量命名写清楚哪怕没法运行也要让阅卷人一眼看懂思路。我认识一位在游戏公司做过校招笔试阅卷的工程师朋友他说批卷时最怕看到一大坨“a、b、c”变量名就算逻辑对也很难给高分因为“代码是给人读的不是只给机器跑的”。另外一个小技巧编程题如果一时间没有完整思路先写一个能过部分测试用例的暴力解法并在注释里注明“此处可优化为XX算法”。这比留白强很多因为笔试阅卷通常是按点给分暴力解法能拿到基础分优化方向说明能拿到一部分思路分。在“只能看纸质代码”的笔试模式下把思路写出来本身就是一种能力展示。7. 把笔试当情报站考后复盘如何反哺后面的面试笔试结束不是扔下笔就走而是把卷子当成一次“技术情报收集”。我在复盘吉比特这套卷子时最大的收获不是分数而是通过题目反推了目标公司技术栈和项目方向。举个例子卷子里出现了大量帧同步、状态同步相关的题目说明这家公司当时正在做或者准备做强实时性、强竞技性的游戏出现了不少Unity和渲染优化相关题目说明客户端岗位很可能以Unity为主。这些信息在后来的面试自我介绍时非常有用——你可以主动提“我了解你们在战斗同步上的技术选型也研究过帧同步的一些注意点”面试官很难不对你多一分好感。具体复盘方法建议分三步第一步整理错题和蒙对的题。蒙对的题比错题更有价值因为那说明你的知识有盲区只是运气好没被抓住。把每一道题逆向回溯到一个知识点不要停留在“我会了这道题”而是问自己“这道题背后的知识网络我还有哪里没打通”。第二步根据题目反推岗位技能树。吉比特这套卷基本覆盖了游戏服务端、客户端、引擎底层三个方向的基础知识。你面试的是客户端那就重点补渲染管线和资源优化面试的是服务端那就深挖网络多线程和数据库设计。同一套试卷不同岗位的复习重点完全可以不同。第三步把题目改造成面试问答。很多笔试选择题面试时会被考官挖成“说下你对这个知识点的理解”。比如笔试考了TCP粘包面试就可能让你手写一个拆包函数。所以复盘时要把选择题“为什么对”和“为什么错”都理清楚不要只看答案。最后说点个人体会。这套2017年的吉比特笔试试卷放在今天看算法题的难度并不算高甚至比很多大厂的通用笔试要温和但它的行业特色题和场景化编程题恰恰是普通刷题训练很难覆盖的。它考的不是“你有多聪明”而是“你有没有真的想过游戏是怎么做出来的”。如果你正在准备游戏公司校招我的建议是不要只刷LeetCode花点时间去理解一套完整游戏项目的运行机制客户端怎么渲染一帧画面服务端怎么处理玩家并发操作客户端和服务端怎么同步状态。这些东西不是一门课能教完的但一套笔试卷会帮你把知识碎片串起来。这也是吉比特这套卷子留给我最大的启发——笔试不仅是筛选更是一次关于游戏研发的系统性提示。
返回列表