腾讯/网易/完美/字节 游戏客户端/游戏引擎(2020暑期实习岗) 综合笔/面经
前言
在写笔/面经之前还是先说一下最近招聘的感受
先说明一下我自己整个的应聘的时间跨度是从3月中旬到4月中旬,我是从3月9号陆续开始投递简历,直到四月初没正式确定前还在投递新简历,除了腾讯/网易/完美/字节外还投递了不少游戏和非游戏互联网企业,也包括华为和大疆等企业,大大小小包括了十几家。毕竟是人生第一次找工作的过程,以前从来没有自己笔试和面试过,所以并不清楚自己能去哪里。但除了这四个企业之外的其他企业都笔试面试地比较晚或是没有给我面试机会。(对于找实习的学生应聘时间问题,我问过很多前辈,大抵上是认为不要过早也不要太晚,尽量中前期开始投递提前批或一批 [特别招聘计划除外]。一是考虑自己的笔面试的复习情况不可能很早就准备完善,二是越早投递,企业HC越多,相对越容易)
今年实习和春招的情况很特殊,所以各类企业要么没有暑期实习,要么变相不招人,再比如有的企业这种要么只招立马能去长期实习,要么拖得比较久。百年一遇的情况大家也都明白,但游戏行业今年还算景气,也是很不容易,但转正情况就另外一说了。
另外,AI岗今年愈发艰难了,大厂尤是,周围不少同学,师兄找实习还是非常困难的,当然并非是找不到(拿过AI竞赛奖项、一区或顶会的近几年会有很大优势)。所以后来的研究生还是要注意考虑这些问题,如果自身能力不够过硬,或是找的团队科研能力不够强,请慎重考虑选AI方向,不要被自媒体和各类说辞带偏了自己的意向。(希望大家能读研时能找到自己真正感兴趣或是真正能帮助自己的方向)
需要说明的是我没有做录音,具体哪家公司提到了什么已经记不太清了,所以我笔/面经都是按点说的,没有按照网上常见的面经排版。而且每个人面试的问题其实还要看面试官和具体情况,说不定你提到了什么东西,面试官就按照这一点继续深挖了,也或许面试官认为你的简历不错,问的问题偏向你的项目中的具体问题展开。
笔经(客户端+引擎)
游戏客户端这个方向不论客户端还是引擎,大体上前置的基础笔试题都是以C++基础,STL为主,偶尔参杂一些数据结构和算法,整体而言对OS、数据库、网络、编译原理等等其他知识要求不高,甚至几乎不考。这部分分值一般不高。
重头戏一般是编程题,简答题,大分值都在这边。
编程题:基本算是ACM入门+进阶级别,例如基础的模拟题、搜索题、数学题、并查集等;稍难一些就是DP相关,以及部分变种题,比如有一次我碰到了一个树状DP,当场甚至没想出来。某些企业会结合游戏相关给你出一些比如渲染物先后排序问题和骨骼运动等算法题(网易雷火引擎实习 4小时),这类题一般都是要求你看懂题然后进行模拟,代码可能相对长一点(如果你本身就会相关的骨骼动画、四元数和透明度计算算法等等,那你看懂题会很顺利)。
简答题:这些题往往会结合游戏背景给你出一些简单的游戏架构设计题,或是功能设计题,某些不考编程题的企业会在这部分放入算法题让你写伪代码和思路。比如设计rouguelike游戏的随机地图(固定场景内生成多个随机可达的房间,要求出入口尽可能远),设计简易的游戏组队系统等等。
PS:多嘴一句,对于不少人而言,笔试很可能只是参考,如果你的简历很好,那你即便笔试0分也是可以收到面试的。当然前提是你的简历够出色,以至于HR和面试官对你感兴趣。相反,即便你笔试满分,如果岗位需求过高,HC不够了,或者部门对你的简历没有兴趣,也会直接把你筛掉。(我之前投阿里的计算机图形学,笔试题满分,照样没有人找我面试)因此,对于很多私企而言,笔试只是一种手段,不要太过在意。
面经(客户端+引擎)
面经的部分,具体问题我不分一面二面三面,因为各企业对不同阶段的面试要求不同,比如有的企业不管哪一面,都会很详细地问你C++基础,图形技术,游戏技术等等,但大部分企业是前面一部分面试偏重C++基础,简历印象面试,了解情况等等,后部分偏重对你简历中提到的项目,或者是实际工作时,可能会遇到的引擎或项目技术相关的问题进行提问。
1. 面试过程(四个)
腾讯
提前批没有笔试,开始我面的是引擎岗.
第一个部门的一面对我印象比较好,二面问了一个算法题和场景题(我后面会提到),答得不好,过了几天虽然到HR面了,但还没面HR就被从HR面的状态换成初试了(我问了其他HR,回复我是部门内部调整,给我换了部门,但是我估计是HC不够了).
第二个部门也是引擎,但是可能招满了,压根没看应聘信息,半个月了都没有面我,状态都是初试的状态,于是我让HR把这个部门的投递撤掉了。后面换成客户端开发重新进大池子等部门捞我…(…心酸)
第三个部门(游戏项目组)的面试官第二天跟我约了一面,这次的部门效率感人…(可能要到截止日期了)。
一面面完对我印象不错,当天改状态,下一个工作日二面。
二面问我自己的课题项目项目问了一个小时,非常之具体,包括改进问题,为什么不做各自改进等等都问得很清楚,二面貌似也是当天改状态HR面,然后约了第二天早上面HR,三天后OC。
网易雷火
引擎岗,网易的时间线很长,因为没有提前批,只有一批次,所以我是三月就投了简历,三月底才收到笔试通知。
笔试大概4道编程题4小时A掉前3道,最后一道思路有点问题。四月初面试,陆续一面二面三面。
一面一开始就摆出好几道选择填空让我当场做,一道道看,然后后面基本的C++底层,多态,然后面试官开始往深了挖我的C++内存结构(前面基础题我其实很多没答上来,dx也没写过,旋转矩阵逆推也没推出来...可能是面试官觉得我内存结构这一边答得比较有意思让我过了…)。
二面(一面当天下午),面试官一看就是阅游戏无数,开头就跟我聊玩过什么游戏什么的,聊家常(因为网易雷火邮件招聘系统貌似出了点问题,好几个人没收到面试通知,包括我,后面是HR打电话通知我面试的),然后开始聊我这边的项目,问我对游戏技术,引擎的了解什么的。
三面估计是部门主管,一开口就是老领导了…跟我聊了国内游戏发展现状,然后教育了我可以用我的方向来做游戏里面的一些东西,聊了很久…最后快结束的时候,突然开始面我数学算法题(后面说)和C++底层,问C++内存结构的,最后还问了我offer情况。
再过了几天就HR面了,和腾讯同一天面(晚腾讯一个半小时…),HR这里问的比较不一样的地方是问我遇到过最大的困难和难题是什么,怎么解决的,以及问了我其他的offer的情况。三天后OC(比腾讯晚一个半小时,这俩企业真准时…)
完美
提前批,我投的客户端,不过我稍微提下…我是面试后才知道完美世界是20年暑期实习和21届校招一起招的,意思就是你投的实习面的就是校招,过了明年就是他们的人了…(Hmmm…我该怎么说,这事情是不是该提前在招聘的时候说一下)。
笔试比较正常,大概一个半小时,有选择和填空,编程题很简单,4道题,A掉3.875道。
一面很注重基础,老样子C++基础,STL,不一样的是这个部门的面试官会让你手写渲染代码(比如phong模型),我写得不好…当时没复习,一脸懵逼,于是蒙蔽地说了一下我印象中的模型计算。
二面除了面少部分C++底层,主要是问我的项目和ACM竞赛的经历,遇到过什么算法的难题,怎么解决,该怎么在竞赛上进步等等。还有一点不一样的是,二面面试官会把企业工作编程的时候实际遇到的各种调bug,团队协作问题拿出来问我会怎么从代码上进行解决。二面面试官很有意思,实力很强,会帮你把你说错的地方或者算法讲漏的地方,甚至以前遇到的难题解决思路的漏洞都给你找出来,然后比较委婉地告诉你。应该是我遇到的印象最好的面试官了。大概是过了几天就给了HR面oc(比较早)。
字节跳动
引擎岗,说实话,字节游戏这边是新部门,去年才开始发力自研游戏,所以每个人见解不一样吧,工资给的虽然高,但还是需要多考虑一下。
笔试都是编程,4道题,前三道A掉,最后一道10% case水过…。过几天就提示笔试过了,准备面试,但字节面试周期贼长,一面结束下周再面,二面结束,也是下周才HR面给OC。
一面考察C++基础和底层,但不会很深,然后给两道简单的搜索算法题给我敲,第一题先敲完之后,可能面试官觉得我敲得太慢了,第二题就直接口述思路,都是DFS结束,第一题稍微利用到了栈。
二面面试考查范围比较大一点,但都不深,后面考我前序遍历非递归手写,开始搞成了中序遍历 (中序更复杂一点),写完才意识到要写前序…反正顺利写出来了,测试也过了。其中有个小插曲是我回答sizeof的时候没有注意”\078”这种八进制转义字符的问题,答错了…好尴尬…。但幸运的是,过了一周收到HR面OC了。
具体的问题我就在下面分类列举了,没有按企业来分,因为时间跨度太长,有一些问题哪些企业问到了我也不太记得了,甚至有些细节题我可能也忘了。我尽量回忆出比较关键的题目和所属企业。
2. C++基础、STL和底层部分
- const的作用(完美一面)
- static的作用(完美一面及其他),全局常量和变量如何使得整个程序可见(完美二面)
- new和malloc的区别,以及new的优点,能说多少说多少(完美一面)
- this指针
- inline函数和宏的区别,inline是否是在任何时候都展开代码(完美一面)
- extern “C”的作用(字节二面)
- 多态的底层实现,紧接着可能会问虚函数的内存布局,包含虚函数的对象本身的内存大小问题,多继承问题等(几乎所有企业都面到了)
- 虚函数的默认参数问题,以及为什么会这样,默认参数具体存在哪个C++分区等?(雷火一、三面)
- 虚析构函数的作用(多数企业都问过)
- C++的引用是怎么实现的,为什么要这样?(雷火三面)
- C++ STL中存在的陷阱,你碰到过哪些?(腾讯引擎一面)
- C++ 11的新特性有哪些(腾讯引擎一面)
- C++11智能指针(腾讯、完美面到了,其中完美一面要求手写实现一个shared_ptr)
- C++在什么情况下会发生拷贝?(莉莉丝一面)
- C++内存分区有哪些(企业面C++底层都会隐含涉及到这一点,完美一面直接问了)
- sizeof和strlen的区别,以及字符串的sizoef计算中\0和八进制转义字符问题,例如sizeof(“123\04567”)。引申有十六进制转义字符问题(字节二面)
- C++右值引用的作用,右值是什么等等(腾讯客户端一面,从另一个问题挖出来的问题)
- STL中vector的实现原理,map的实现原理(有序和无序)(大部分企业都面到了)
- C++所有的构造函数包括哪些?(腾讯客户端)
- 用内存拷贝的方式直接拷贝vector本身会发生什么?会存在什么陷阱?(腾讯引擎)
- 深拷贝、浅拷贝的区别
3. 数据结构
- hash表的构造、插入,查询和删除具体各有哪些方式?(雷火三面,莉莉丝,其中要注意删除的实现)
- map中红黑树的实现?以及对红黑树的了解? 无序map和有序map的差别、优缺点?自定义数据结构怎么使用map?(莉莉丝一面)
- 接着第2题,如果给定很多用户,其中key值可能包含地区、单位等两到三个。如果让你来设计,你会采用红黑树这种方式还是hash表这种方式来进行存储查询,为什么?(莉莉丝一面)
4. 图形图像、数学基础、引擎相关
- 齐次变换矩阵逆推,知道M(4*4的矩阵),求M=RST中的R、S、T三个矩阵具体是多少?(雷火一面)
- 光的反射计算公式?(雷火一面)
- 一张1024*2048的图片大小是多大?(字节二面)
- 是否写过引擎?对游戏引擎的了解?一个游戏引擎应该有什么样的功能,在游戏开发过程中承担什么样的责任?(不少引擎岗面试都问到了类似问题,因为我没有实际写过引擎,所以大部分没有和我聊过于具体的技术)
- 抗锯齿的方法?多重采样的实现?怎么找边缘(雷火二面)
- 知道哪些几何相关的算法?网格处理在游戏领域的运用具体可以做哪些事情?(腾讯引擎二面,雷火三面,雷火这里聊得很详细)
- 渲染管线的过程(腾讯引擎,字节,雷火)
- 渲染流水线中进行裁剪的地方有哪些?视锥体裁剪、背面剔除具体是怎么做的?背面剔除的实现方法?提前剔除应该怎么做?(雷火三面,答得不好,被教育要多看看相关的基础知识)
- 怎样做提前深度剔除?(雷火三面)
- 分离轴算法的计算过程?凸多边形如何利用分离轴进行判交,需要多少个轴?(莉莉丝)
- 了解PBR么?有什么实现方法?(腾讯引擎一面)
- 局部光照模型有哪些?全局光照方程要怎么计算?(腾讯引擎一面)
- OpenGL的可编程管线流程?几何shader的作用,为什么一开始就从应用程序输入到几何shader,而是顶点shader?还知道哪些shader?(完美一面)
- 了解哪些后处理技术?
- OpenGL ES了解多少?
5. 算法和编程相关(包括思路题和手撕代码题)
- (a^n) % 10,怎么实现,a和n都可以很大。(雷火三面,最快的是O(1),如果不知道可以网上找一下题解)
- 一个二维空间,x和y轴都是10000以内的正整数,其中有2n个随机顶点,求一个圆C。使得圆C内有n个顶点,圆外n个顶点,注意圆周上不能有点。(腾讯引擎二面,注意要尽可能地快,且保证算法收敛,并且不受浮点数误差影响)
- 场景题,一个地形网格(三维地形,有高有低,其中xy方向上为固定尺寸,每个网格都是一个1*1的单位正方形)。有一个camera在某一个位置,如何优化/简化网格,实现快速地形渲染,并保证渲染后屏幕像素误差不超过一个像素。(腾讯引擎二面)
- 有一个不包含重复数字的数组,比如A=[2,3,5,7], 有一个数字x,比如x=7,编程求解有多少组该数组中数字的和为x,并输出这些数组,数组中的数字可以重复使用,例如上例中,{2, 2, 3}, {2, 5} {7}这三组数据将被输出(字节一面)
- 有一个二维字符数组map,有一个单词word,查找map中是否存在word单词,类似成语接龙,该单词可以呈上下左右的接龙形式。例如有一个单词zoo,字符数组如下(字节一面):
w e z o
t w o q
w w o u
s g s s
6. 前序遍历的非递归实现,写代码(字节二面)
7. 单例模式的实现,写代码(雷火三面)
6. 项目、开放题相关
这里稍微说一下项目的问题,企业看简历还是非常看重项目的,如果项目够好或者够吸引面试官,很多到了项目面的时候,可能就不会谈太多C++和算法题,而是问你自己项目中的很多引申问题以及为什么要采取这样的技术,不去做那样的事情等等,这种时候因为都是自己做过的,所以会更容易回答。现在回忆到的游戏或项目较通用的问题如下
- 团队组成,项目中负责的是什么?遇到哪些难题?怎么解决的?(这种HR问得比较多)
- 如果你接手一组代码,可能被很多人修改过,组织比较混乱,你需要在很短的时间内把一组代码整理好,并组织成可读性更高的代码,你会怎么做?(完美二面)
- 怎样在保护一段代码的情况下,为它添加新的功能?(完美二面,设计模式相关)
- 有若干的人会用你自己写的内存池(因为我前面回答的时候提到了内存池的多态写法),但是其中有一个人写的代码没有释放资源,长时间会导致客户端崩掉,你要怎么从代码的层面修改代码以发现到底是谁的代码/哪一段代码出现了这种没有释放资源的问题?尽可能以自动化的方法自动检查?(完美二面)
- 你的项目中有什么现实的需求,可以做到哪些事情?(我的属于应用研究课题,大部分企业都问到了)
- 你用的网格简化算法具体是怎么实现的?有些特征不保持/形态丢失的情况怎么办?(腾讯客户端二面)
- 玩过哪些游戏?看的书和论文有哪些?平时是怎么学习的?(大部分企业都问到了)
- 你相比其他人在引擎岗上有什么优势?(因为我没写过引擎,所以腾讯引擎一面问了我,我回答是几何优化,所以二面问了我几何优化,但是我没答好,所以即便二面被挂我其实也是知道为啥的,这就是自己挖的坑,2333,不过居然二面也过了就比较神奇了)
后记
其实我最后还是选了腾讯客户端,主要的考量是引擎从业人数过少,而且面了这么多次之后,我大概也知道自己对引擎这个岗还是缺乏一些实际的经验。因为我本身是做数字几何处理的,因此自己的项目和课题都没有过多关注渲染,也没有实际用引擎写过游戏项目,因此直接上引擎岗会很吃亏。因为就目前的国内游戏行业来说,大部分情况下引擎岗也不需要那么多的较新的网格处理技术,而引擎开发的各个讨论区都是以渲染为主。这一点雷火那边的面试官也和我聊过很久,甚至也直接指出了国内游戏和国外3A的差距,很有意思。但不管怎样,这不是短期内能解决的。
但工作是工作,兴趣是兴趣,估计不管是引擎开发还是客户端开发,工作许久之后还是会厌倦的。有个已经工作的同学告诉我,如果我像他一样超长加班到12点,每日如此,工作两年以上,会很讨厌开发的。(我其实很认同这句话,但我也只能尽量不这样工作,同时尽可能对游戏开发保持一份热忱)
如果一定要做一个总结,笔试部分,不管怎样都逃不过刷题,至少leetcode级别的题目肯定都是要做不少的,这对面试也很有帮助,反复练习,就会得心应手。面试部分,如果临近面试招聘,还是尽可能地直接看面经总结自己的回答,加上自己的理解,遇到C++底层的问题,偶尔可以尝试直接用反汇编的方式看看汇编代码是如何实现的(特别是指针、地址和内存的部分)。如果时间还比较长,还是要尽可能在你做的项目里面活用语法、数据结构,尽可能多地使用C++11-20的新特性,尽可能多地尝试一些必要的设计模式,慢慢对C++和数据结构、设计模式这些内容有更深的理解会更好。
另外对C++底层的部分,我有一些个人的理解和看法,不管你会不会某个语法和库功能细节的底层知识,你考虑问题首先要把自己放在一个语言设计者或是标准库设计者的位置来思考这个问题,这样不管你的回答是否正确,至少在面试官眼中,你都是以一个底层设计者的思路在设计,而不只是一个使用者,或许这个时候真正的答案就不太重要了。(当然答错了还是要反思的,2333)