
每年一到春招实习季游戏客户端开发方向的笔试题总能在各大技术社区刷一波存在感。网易2018年实习生招聘的这份卷子我印象很深不是因为题目有多偏多难而是它把“客户端开发到底需要什么样的人”这件事讲得很清楚。它不追求让你当场手写一个渲染引擎也不搞那种“茴字有几种写法”的抠字眼题而是用一套组合拳考察你的语言基础、算法思维、数学功底和工程感觉。这篇文章不打算给你逐题报答案而是把这份卷子拆开来看它考了什么、为什么考这些、背后对应哪些实际开发能力以及如果你现在准备投游戏客户端实习应该怎么备战。先给个结论这份笔试的核心逻辑是“用有限的题量探测你三年后能不能独立扛起一个玩法模块”。所以它考察的不是背题能力而是你有没有形成一套属于程序员的思维方式。下面我按考察维度和题型逻辑逐步拆解最后会附上几类代表性题目的完整思路演示和避坑记录。1. 笔试到底想筛什么样的人1.1 客户端开发岗位的能力画像网易游戏客户端开发实习生日常工作会接触到玩法逻辑、UI系统、战斗表现、性能优化、资源管理这些模块。也就是说这个岗位需要的人不是纯算法竞赛选手也不是只会拖拽节点的“引擎操作工”而是能理解底层原理、同时具备工程落地能力的人。笔试设计的第一步就是给这个能力画像描边。这份卷子有一个明显特征大部分题目你都能看懂没有任何一道是“没见过就完全不会”的竞赛题。但每道题背后都藏着几个层次。比如一道关于链表操作的题第一层是考察指针操作是否熟练第二层是考察边界条件全不全面第三层是考察你能否用递归或迭代两种思路各写一遍并分析复杂度。很多同学只停留在第一层觉得“我写出来了就行”但实际上笔试阅卷时解题思路的清晰度和代码风格也在打量范围内。从岗位角度看客户端开发特别看重内存管理和生命周期意识。因为游戏是长跑型应用一个玩家可能连续在线几个小时任何内存泄漏、野指针、资源未释放的问题都会被时间放大。所以笔试里关于C指针、STL容器、内存布局的题目不只是考语法而是在模拟你写战斗逻辑时是否会被“悬垂引用”和“循环引用”坑到。1.2 笔试题型的分布逻辑网易这份卷子的题型分布基本可以概括为“六三一”——六成基础、三成进阶、一成开放。基础部分包括C语法、数据结构、简单算法进阶部分涉及动态规划、图论、计算几何开放部分往往是系统设计或场景题比如“描述一个RPG技能系统的数据结构和更新流程”。这个比例不是随手定的。它对应实际开发中的工作分配你和策划对接日常需求时大部分时间是写业务逻辑考验C熟练度和模块划分能力遇到性能瓶颈或复杂玩法时需要算法和数学功底来托底而设计技能系统这类任务考察的是结构化思维和全局视野。所以笔试不是故意设门槛它在用一种高效率的方式预演你入职后的真实状态。再补充一个容易被忽略的观察点题型分值分布。基础题每题分值低但数量多进阶题分值高但只要求选做部分。这意味着策略上并不需要“全做完”而是要在保证基础题正确率的前提下挑选自己有把握的进阶题深入展开。我见过太多同学在某一两道难题上死磕结果前面容易拿分的选择填空没时间检查这是最可惜的丢分方式。2. 核心知识点拆解每一类题背后的考察意图2.1 C语言基础指针、内存、STLC是客户端开发的主力语言笔试中这部分题量占比最大。你可能会遇到诸如“const成员函数的意义”“智能指针的底层实现原理”“vector扩容时迭代器为什么失效”这类问题。它们看起来很理论但每一个都能在引擎源码或实际开发中找到对应场景。以“vector扩容”为例。你在战斗系统中会有大量技能Buff列表每帧可能增删元素。如果不懂扩容原理就不会理解为什么提前reserve能明显减少卡顿。再比如“迭代器失效”当你在遍历一个容器并同时删除元素时底层就涉及迭代器管理的问题这在写技能逻辑时几乎一定会遇到。所以这里我不是在教你背答案而是建议你把每个C考点都映射到一个游戏开发场景中去理解。内存这块要特别说一下。除了栈和堆的区别、内存对齐这些基础题网易笔试还喜欢考“如何检测内存泄漏”这类偏实践的问题。常见的回答是“用工具如Valgrind”但更进阶的答法是“在Debug版本中重载new/delete记录分配信息配合定时快照比对”。后面这种回答能直接体现你有没有经历过真实项目中的内存排查而这类经验靠刷题是刷不出来的。2.2 数据结构与算法刷题之外的战术数据结构的部分链表、二叉树、哈希表是绝对重点。二叉树相关的遍历、深度计算、最近公共祖先问题几乎年年出现。哈希表则喜欢考“冲突解决方法”和“底层实现区别”比如开放寻址法和链地址法的对比。算法部分动态规划和搜索是重头戏。不过网易笔试的动态规划题有一个特点很少出纯粹的背包问题模板更多是“披着游戏外衣”的情景题。比如“一个角色从地图左上走到右下每格有不同金币求最大收益且统计路径数”这类题本质还是DP但你需要先读懂题目描述剥离场景外壳识别出状态转移的骨架。这要求你在刷题时不要只背模板要训练“翻译题意”的能力。图论算法也需要重视。最短路径Dijkstra和拓扑排序在客户端开发中有广泛的实用基础。A寻路本质上就是启发式搜索在网格地图上的应用而技能树、任务链等系统则和拓扑排序紧密相关。笔试不会直接考A但会考它的基础组件比如优先队列的用法、曼哈顿距离的计算。2.3 游戏数学与图形学躲不开的向量和矩阵这是客户端卷子和后端卷子最明显的分水岭。游戏客户端必须和三维空间打交道所以向量点乘、叉乘、矩阵变换这些基础题一定会出现。它们看似是数学题实际上是在考察你是否具备“游戏开发者的空间直觉”。一个很典型的考法给一个角色位置、一个怪物的朝向和攻击范围问如何判断怪物是否能看到角色。这里的标准解法是用向量点乘计算角度和视野半角比较。你要是没做过游戏可能会觉得这只是一道数学题但只要写过相机系统或AI行为就会立刻联想到这是每个框架里都在用的“视野检测”功能。叉乘相关的题常见的是判断点在三角形内、求平面法线、判断多边形顶点顺序CW/CCW这些在物理碰撞和几何处理模块中极为常见。矩阵方面平移、旋转、缩放对应的矩阵表示是基本要求更进一步会考“视图矩阵”或“世界坐标到局部坐标的转换”。这类题不一定要求你写出完整矩阵但会给你一个场景让你描述变换顺序。记住一个关键原则矩阵乘法不满足交换律先旋转再平移和先平移再旋转是两个完全不同的结果。陷阱题往往就在这里。2.4 网络同步与操作系统容易被忽视的加分项你可能没想到客户端笔试题里会夹杂一些网络和操作系统的内容。这其实反映了网易游戏客户端的技术栈特色——特别是在大型多人在线游戏中客户端需要处理网络同步、延迟补偿、资源加载等底层问题。网络相关的常见考点包括TCP和UDP的区别、如何设计一个可靠的UDP协议、同步方案帧同步和状态同步的对比。笔试一般不深挖代码而是考概念辨析和应用场景判断。比如“MOBA游戏为什么适合帧同步”“RPG游戏为什么更多用状态同步”这类问题没有标准答案但需要你理解两种同步方案在带宽占用、断线重连、反作弊难度上的本质差异。操作系统知识也不能完全放弃。进程和线程的区别、死锁产生的四个必要条件、虚拟内存和物理内存的映射关系这些基础概念偶尔会出现。它们对应着客户端开发中“多线程渲染”“资源异步加载”“内存池设计”等实际工程问题。这里想强调一点就算这些题占比不大也不建议直接放弃。因为当你把“线程安全队列”的概念讲清楚时面试官会认为你具备处理复杂工程问题的潜力。3. 从读题到AC几类代表性题目的完整解题演示3.1 链表与指针操作细节之中的魔鬼先看一道典型的链表题。题目大意是给定一个单链表每K个节点一组反转不足K个的保持原序。这道题在LeetCode上是Hard级别但它本身不涉及高深算法纯粹考验链表指针操作的功力和逻辑缜密性。建议的答题思路分三步。第一步边界条件先行链表为空、K等于1、链表长度正好是K的整数倍这三种情况先列出来。第二步设计递归结构定义一个函数reverseKGroup(ListNode* head, int k)函数内先数出k个节点若不足则直接返回head若足够反转这一组然后递归处理剩余部分。第三步处理递归后的连接关系反转后的组尾要指向下一组反转后的新头。用代码表示核心部分是这样的ListNode* reverseKGroup(ListNode* head, int k) { ListNode* cur head; int count 0; while (cur count k) { cur cur-next; count; } if (count k) return head; ListNode* prev nullptr; ListNode* curr head; while (curr ! cur) { ListNode* nextTemp curr-next; curr-next prev; prev curr; curr nextTemp; } head-next reverseKGroup(cur, k); return prev; }这段代码的核心技巧是用cur记录“下一组起点”反转时只处理当前组最后通过递归把组与组串起来。很多同学在写这一步时会漏掉head-next reverseKGroup(cur, k)导致后面的链表全部丢掉了。这里无论如何都要检查“反转后的末尾是否接到了下一组的开头”。3.2 动态规划剥掉游戏外壳看状态转移网易笔试的一道经典DP题是这样的有一个n行m列的棋盘每个格子有不同数量的金币。你从左上角出发只能向右或向下走到达右下角。求能收集到的最大金币数。这题本身不难但它有一个“强化版”加入一个传送门可以从某个格子一步跳到另一个指定格子求最大金币数。加入传送门后状态转移需要特别小心因为传送可能改变常规的遍历顺序。如果你不理解DP的“无后效性”原则很容易在这里写错。基础版本的状态转移很简单// dp[i][j] max(dp[i-1][j], dp[i][j-1]) coins[i][j] for (int i 0; i n; i) { for (int j 0; j m; j) { if (i 0 j 0) continue; int fromUp (i 0) ? dp[i-1][j] : -1; int fromLeft (j 0) ? dp[i][j-1] : -1; dp[i][j] max(fromUp, fromLeft) coins[i][j]; } }但如果你要处理传送门建议不用“逐个格子更新”的思路而是先把传送边存下来在标准DP完成后再检查传送门是否能产生更优解并且要允许多次迭代直到状态稳定。现实中这种题往往把传送门设计成“最多使用一次”那就更简单先用正着跑一遍算出到每个格子的最大收益再额外考虑传送起点和终点的补充更新。我想强调一个考场战术DP题先写最简单的版本哪怕你已经看穿了更复杂的版本。两步走策略能保证你在时间不够的情况下至少拿到稳定分数同时给后续优化留出思路。一上来就追求最优解一旦卡住全题覆没。3.3 计算几何用叉乘“一招鲜”计算几何的题在客户端笔试中的出场频率不低但很少考到特别复杂的凸包或半平面交更多是“点与多边形关系”这类基础问题。解决这类问题最核心的工具是叉乘Cross Product。比如一道真题还原“给定一个凸多边形顶点坐标按顺序和任意点P判断P是否在多边形内部。”解法很直接对多边形的每一条边v_i, v_{i1}计算向量边和v_i, P的叉乘。如果所有叉乘的符号一致同正或同负则点在多边形内如果有零说明点在边上若符号不一致则点在外面。bool isInside(const vectorPoint poly, Point p) { bool hasPos false, hasNeg false; for (int i 0; i poly.size(); i) { Point a poly[i]; Point b poly[(i1) % poly.size()]; int cross (b.x - a.x) * (p.y - a.y) - (b.y - a.y) * (p.x - a.x); if (cross 0) hasPos true; if (cross 0) hasNeg true; if (hasPos hasNeg) return false; // 符号不一致直接返回 } return true; // 全部正或全部负或者全部零点在边上 }这个思路不需要记住任何高深公式只要理解叉乘的几何意义叉乘的正负代表旋转方向在逆时针排列的凸多边形中内部点会始终位于每条边的同一侧。这本质上就是在做“射线法”的优化版本。再说一句机考时千万别忘记处理点恰好落在边上的情况这在工程里对应了“角色踩在边界上”的物理判定实际项目里非常常见。3.4 系统设计题如何展示你的工程思维网易笔试的最后一题往往是开放性的系统设计题比如“设计一个MMORPG的背包系统”或“实现一个技能冷却管理系统”。这类题没有标准答案但阅卷时能快速区分布置经验丰富的人和只刷算法题的人。我的建议是回答一定要分层。第一层讲数据设计背包通常用二维数组或哈希表存储物品ID和数量特殊格子装备栏、材料栏需要单独标记。第二层讲操作逻辑放置、堆叠、拆分、排序、移动这些操作对应的复杂度以及如何避免频繁的数组拷贝。第三层讲扩展性如果未来要加“一键整理”“筛选显示”“快捷使用”架构上需要预留哪些接口。拿技能冷却管理举例。最naive的实现是每个技能记录一个CD时间每帧遍历所有技能减少剩余CD。这在技能数量少时没问题但如果你有上百个技能或Buff每帧全量遍历就是性能浪费。更优的方案是用一个优先队列小顶堆存储所有“生效中”的冷却事件每次只需检查堆顶要不要触发回调。这种从“每帧遍历”到“事件驱动”的优化思路正是阅卷人想看到的工程敏感度。4. 常见失误与实战避坑记录4.1 时间分配两小时该怎么花网易笔试时长通常为两小时左右。我的建议是前30分钟通读全卷标记出“秒杀题”和“需要思考的题”。秒杀题指那些你一眼就知道思路、只需要小心边界条件的题比如简单的遍历、字符串处理。先把它们全部解决并检查一遍确保基础分稳稳到手。第二步处理中等难度的题比如二叉树遍历、简单的DP。这类题分值中等但你不应该长时间卡住。如果10分钟内没有清晰思路立即跳过回头再看。最后留20到30分钟给开放题或难题这时候时间本来就不多你的目标是写一个“结构完整但可能不是最优”的方案而不是憋一个完美的AC代码。我见过太多同学在最后一道系统设计题上写了很长很长的文字前面算法题却空白一片。说实话判卷时一道算法题AC的分值远大于你系统设计题多写两百字的分值。这跟实际工作很像能跑的正确代码远比没跑通的长篇设计方案有价值。4.2 环境与工具你玩明白笔试平台了吗网易笔试通常有自己的在线判题系统和牛客网、LeetCode这类平台有一些差异。首先要提前弄清它的输入输出格式是一口气读入全部数据还是逐行读入空行结尾还是EOF结尾。很多同学不是不会做而是卡在输入解析上白白丢分。另一个容易踩坑的地方是编译标准。笔试题默认支持C11有的甚至支持C17但如果你在代码里使用了C20的特性可能直接编译失败。我建议就按C11的标准写避免使用太新的语法比如结构化绑定其实C17就有了、concept等。还有如果你的代码在本地VS集成开发环境跑得通但提交后编译错误优先检查是否用了非标准头文件或平台相关函数。最后一个建议提交前一定清掉调试输出。我有个朋友曾因忘记注释cout调试信息导致超时判罚一题直接归零。这种错误不值当但它每年都在发生。4.3 容易丢分的细节和习惯第一是变量命名。阅卷虽然不一定看代码风格但在面试讲解环节你写的变量名会被翻出来。用desc表示description没问题但用a、b、c这种就完全看不出含义。建议在笔试时就养成写有意义的变量名的习惯这也是一种职业素养。第二是边界条件。数组越界、空指针、空数组、单元素数组、题目给出的数据范围上下限这五类边界条件必须覆盖。准备笔试时每做完一道题就问自己这个代码在n0时会不会崩K1时逻辑正确吗坐标有没有可能为负这种自测习惯能帮你省下大量的重写时间。第三是复杂度分析。很多题你写完了AC通过所有测试用例还不够最好在注释里补一句“时间复杂度O(n)空间复杂度O(n)”。这不仅方便阅卷人理解你的思路也在暗示你是一个有算法素养的候选人。我自己参与校招阅卷时看到这种带复杂度注释的代码通常都会多给一些正面的印象分。4.4 笔试和面试的衔接秘密这里分享一个很多人不知道的信息差笔试成绩不只是用来筛人还会被面试官直接看到并作为面试提问的线索。你笔试里做对的题、做错的题、甚至你的代码风格都会被面试官拿来当话头。举个例子如果笔试题有一道“判断点在多边形内”的题你答对了面试官可能会顺着问你“A*寻路中如何判断障碍物的扩张碰撞体”如果你答错了他可能会问“考后有没有复盘现在知道怎么做吗”。所以笔试结束后不要急着把题目忘掉。建议立即把每道题重新做一遍并把涉及的知识点整理成笔记。这份笔记会成为你面试问答的高质量素材库。那些“面经”里让人觉得厉害的回答往往就是这么来的不是临场发挥得妙而是笔试题复盘时已经推导过一遍。还有笔试中的系统设计题尤其容易成为面试深挖点。你写的方案面试官会针对其中某个细节连续追问。比如你写了“用HashMap管理技能CD”他可能会问“CD结束时需要通知UI显示技能可用这个通知机制怎么设计”。如果你在笔试阶段已经想清楚数据结构层、逻辑层、表现层三层拆分就能从容应对。5. 备战建议与关键心得5.1 刷题优先级怎么排如果你的目标就是游戏客户端开发方向的招聘不建议盲目刷30天LeetCode热题。按优先级排我的建议是这样的C基础知识熟练掌握指针、内存、STL → 二叉树和链表相关题目 → 动态规划和图论基础 → 计算几何入门 → 系统设计思路积累。C基础是第一优先级的理由很简单它考察频率最高而且一旦掌握面试问答环节也能复用。这里想推荐一个高效的训练方式不要只刷选择题试着把每个概念用“给小白讲解”的方式写一段文字比如“智能指针shared_ptr的循环引用问题为什么用weak_ptr可以解开”。能讲清楚才说明真的理解了。算法训练方面我建议按“主题刷题法”而不是“随机刷题法”。比如花一周时间专门刷二叉树遍历刷到能闭眼写出递归和非递归版本再花一周刷DP从“斐波那契”到“背包”到“路径问题”。这样主题化训练能让你的知识形成体系而不是一盘散沙。5.2 数学和图形学怎么补如果你在大学里没有扎实学过线性代数现在补完全来得及。不需要啃完一整本教材只需要抓住几个核心主题向量加减和点乘叉乘、矩阵乘法、坐标变换和三阶矩阵表示旋转与缩放。每学一个概念就立即查阅它在游戏里的典型应用场景。比如“点乘判断朝向”和“叉乘判断左右”可以同时学因为它们在角色控制模块里经常一起出现。图形学方面暂时不需要深入PBR基于物理的渲染和光线追踪。笔试涉及的是入门级的理解什么是顶点和片段着色器、渲染管线大致有哪些阶段、什么是UV坐标、什么是法线贴图。你只需保持“我理解图形程序大致怎么运作”的状态就能应付基础题。5.3 复盘才是真正的提升环节最后想说说刷题之后最重要的复盘步骤。每次做完一套模拟题把错题归成三类知识性错误不知道这个知识点、逻辑性错误思路对但边界不对、实现性错误思路对且边界对但代码写错了。各类错误对应不同的补救方式知识性错误需要补学习资料逻辑性错误需要多看题解和多画图模拟实现性错误则纯粹是敲码量不够需要多打几遍。复盘频率上我建议每周做一次完整的总结而不是每天草草看一遍。另外强烈建议做“讲题”练习把一道你做过的题假想自己在给面试官讲解说清楚思路、复杂度、边界条件、为什么做这个选择。这个练习能同时锻炼你笔试后的面试衔接能力一箭双雕。说点个人体会吧。我带过不少实习生也参与过几次校招卷的评审。从阅卷角度看的感受是一套笔试答卷往往能暴露出候选人是否真的对游戏开发有热情。有热情的人就算某道算法题没AC他在系统设计题里写出来的思路会透露出“他想过这个问题很久了”的质感。而那些只把笔试当八股文背的人就算分数高面试两三轮也会露馅。如果你正打算投游戏客户端实习不妨把这份笔试当作一次自我体检。别计较一题的得失而是从中看清楚自己的知识结构哪里是短板哪里是真优势。工作之后你会发现笔试的终点其实是工程能力的起点。基础打得越扎实进入商业引擎的项目里你就越能自如地在代码层面表达自己的想法。祝你好运也期待未来在游戏行业里见到你的作品。