2023春招总结
行业的寒气是否退散尚不得知,但就2023年春招的形势来看,面向24届的实习岗还是不在少数,几乎各家都有在积极筹备暑期实习与一些零散的日常实习招聘,总的而言身边很多24届的朋友都有不错的进展。尽管博主还是25届,但是抱着试一试的心态,还是投递了几家公司的春招,幸运的是,也是在最后拿到一些offer,也更加明确了以后需要提升的方向。
首先说一下投递情况:
腾讯:投递后无消息(简历挂,推测是去年的面评很差)
吉比特:简历挂。
米哈游:简历挂。
字节朝夕光年:简历挂。
剑心互娱:笔试挂。
心动游戏:拒绝笔试。
疯狂游戏:拒绝笔试。
育碧成都:笔试+一轮技术面,一周后hr通知需求变化无hc挂。
西山居:笔试+一轮技术面,一面挂。
网易互娱:HR面+一轮技术面,无后续默认挂。
网易雷火:笔试+一轮技术面,一面挂。
————–5.9更新———–
西山居:seed免面试通过
英雄游戏:流程中
电魂游戏:5.5投递,当天hr电话联系约面,5.6日面试,半小时后hr通知通过…
跌跌撞撞也算是春招有成果了(开森)
这样一看感觉好像挺挂彩的,也确实挺打击的,总觉得自己的工程能力似乎还不错,但其实真正去招聘才知道自己的竞争力有多差。尽管投递的公司没有几家,但那段时间整个人都非常折磨:等通知,做笔试,补八股,面试后抱着期待的心情等结果。也确实挺丢人的,刚面完的那个晚上会有点睡不着觉,总是感觉似乎答得还不错,会不会第二天就OC,结果却往往让人失望。到后面也算是慢慢有了磨练的感觉,无论面试反问面试官给你什么样的反馈,都应该明白横向是不可缺少的环节,所以也不必抱有太大的期待。
由于笔试的内容我没有特意去记录,所以笔试题就不分享了,主要是把各家的面试内容进行记录与总结,也希望这一部分能对看到的人起到帮助。项目部分的内容还是见仁见智,根据每个人的项目经历与实习经历应该做出区分。
面试内容与答案
育碧成都
1.聊一下实习期间具体用行为树做了什么。
主要是用行为树去设计几类怪物AI,用自拓展节点去组织具体的行为模块,并且参考htn的形式对行为模块做了分层处理,同时做了数据分离。
2.对于行为树中的各个模块是如何组织设计的。
将行为分类,划分通用子树,设置明确的行为条件与特殊状况的事件处理机制….
推荐参考:AI的被动式处理
3.AI感知器,寻路以及战斗部分的具体实现。
推荐参考:
4.表现资产的配置问题。
动画的处理方式;战斗表现是用timeline的形式去处理,还是用其他方式去生成。
推荐参考:
5.数据分离做了哪些工作,共享行为树的设计与使用场景
用一个共享单例管理某种类型行为树的通用数据,数据由SO配置,供多个AI实体访问,实体做到逻辑与表现分离,每个实体的行为树只需要执行逻辑部分。这种设计在后端同样适用。在场景中有较多同类型怪物的情况下使用,可以节省开销。
推荐参考:黑板与共享数据
6.行为树的GC问题
行为树的数据类型设计,比如shared类型数据是否会拆箱装箱,利用泛型的设计可以避免拆箱装箱。
行为树的加载需要反序列化,可能会引发GC问题。
推荐参考:
7.讲一下项目中对象池的工作流程,做了哪些接口,如何设计。
工作流程:池初始化->拿取对象->容量检查->回收机制->回收…..
一个通用性强的对象池除了需要有基础的拿取回收接口外,最好定义一些生命周期函数的委托方法供外部注册,比如OnGetBefore()
,OnReleaseBefore()
等等,也要有良好的扩容收缩机制,类比stl中的vector,很值得一提的是不同数据容器的选取会对池的各种操作产生影响,同时也会影响到池中对象的活跃度,类比栈对象池与队列对象池,队列对象池的对象平均活跃程度是更高的(栈底的对象可能永远不会被拿取)。
推荐参考:基于队列的对象池
8.项目中的全局消息机制如何实现,消息从广播分发到相应执行的过程,中断与注销机制。
利用枚举加字典可以很快的设计好需要的数据结构。提供给外部需要的注册与注销方法,响应时遍历指定消息类型的整个订阅列表进行invoke
。参考的话等我以后补一篇相应内容的帖子好了(鸽)。
9.项目中UI的搭建,注意过相关开销没有。
对于UI的搭建,不同项目处理的方式不同,不做赘述,只是需要简单注意一下基本原则与优化即可。
推荐参考:
10.Unity中资源的动态加载与本地保存。
我在项目中用得比较多的加载方式还是Resource,本地保存的是用的PlayerPrefs。
推荐参考:Resource与AB包的区别讨论
11.2D游戏中的AI如何设计,做了哪些模块。
寻路上直接用的Pathfinding插件,其余的部分用的状态模式处理的AI行为。
12.C#中用List做对象池怎么处理拿取与回收,用链表怎么实现对象池。
碰巧的是我确实也用List做过对象池,实际上选什么类型的数据容器都是大差不差,而对于List的对象池的拿取其实是想问你优化。最直接的优化策略就是双指针,一个指针记录上一次拿取的index,需要拿取的时候往后拿,同时每次做取余操作防止溢出。另一个指针在回收时指向最后被回收的index,判断池满的条件就是前者追上后者。而链表实现对象池在内存池中的应用非常常见,
推荐参考:STL空间配置器解析
总结:
育碧的面试确实很出人意料,没有问很多的八股,更多的是考察你对项目的理解以及你的开发能力,包括对相关部分的深度。是三个面试官一起问,所以压力很大,但是总的而言整个面试很务实,体验也是非常不错,遗憾的是没有oc,hr后续通知需求变化,应该就是横向比较所以筛掉了,毕竟25届加双非本,确实不具备很强的竞争性。
西山居:剑侠世界三项目组
1.C++与C的区别
虽然这个问题可以扯非常多的东西,但是并不建议在面试官面前卖弄见解打开你的话匣子。最简单直接的就是说明C++在oop上的优越性以及C++的新特性,C++几乎是C的超集。
2.面向对象的三大特性,什么是多态
基础中的基础但是重点中的重点。
3.对象的内存模型
头部虚指针,按照类的继承顺序与声明顺序布局。
4.虚函数的实现方式,虚表的建立时间
虚函数的实现通过虚表与虚表指针,虚表在编译时就已经确定。
5.深拷贝与浅拷贝
浅拷贝只复制某个对象的引用,而不复制对象本身,新旧对象还是共享同一块内存;深拷贝会创造一个一摸一样的对象,新对象和原对象不共享内存,修改新对象不会改变原对对象。
6.父类构造函数能不能调用虚函数
可以,但是会屏蔽多态机制。因为在父类的构造函数中子类特有的成分尚未初始化。
7.值传递与引用传递
传引用直接访问对象,不会产生拷贝,传值的拷贝可能造成很大开销,比如传递vector类型变量。
8.拷贝构造函数的常见形式
构造函数加引用参数
9.delete与delete[]
new
申请的内存,释放时用delete
;使用new [ ]
申请的内存释放时要用delete [ ]
,否则可能产生内存泄漏
10.vector与list有什么区别,各自的使用场景
两种的区别还挺大的,但是面试一直很喜欢问这个问题。
list是由双向链表实现的,内存空间是不连续的。由链表的实现原理可知:
- 优点:插入和删除效率较高。只需要在插入的地方更改指针的指向即可,不用移动数据。
- 缺点:List查询效率较低,时间复杂度为O(n)
vector拥有一段连续的内存空间,并且起始地址不变,与数组类似:
优点:便于随机访问,时间复杂度为O(1),
缺点:因为内存空间是连续的,所以在进入插入和删除操作时,会造成内存块的拷贝,时间复杂度为O(n)。
使用场景跟据需求操作的时间复杂度去确定。
11.红黑树与平衡二叉树的区别
不描述直接上链接了。推荐参考:知乎帅地:红黑树与平衡二叉树区别
12.树上的查找时间复杂度分析
推荐参考:二叉树,二叉搜索树,平衡二叉树与红黑树的时间复杂分析
13.哈希表的实现方式
常见的有桶数组加链表
14.哈希冲突解决方法,列举3个上
拉链法,开放寻址法,再哈希法…..
15.push_back跟emplace_back的具体区别
emplace_back()
函数在原理上比 push_back()
有了一定的改进,包括在内存优化方面和运行效率方面。内存优化主要体现在使用了就地构造(直接在容器内构造对象,不用拷贝一个复制品再使用)+强制类型转换的方法来实现,在运行效率方面,由于省去了拷贝构造过程,因此也有一定的提升。
16.aoi算法
MMORPG游戏中最常见的优化算法之一,推荐参考: 知乎:AOI算法
17.navmesh的原理
主要是三角形寻路网格的构建与基于该网格的A*寻路方法。
推荐参考:
18.A*算法的具体实现与优化
非常经典的高频次问题。
推荐参考:
19.行为树模块的的设计与实现
20.讲一下全局消息机制的实现
重复的问题就不再复述了,C++的八股推荐参考:知乎Steven王:游戏开发面经汇总
总结:
不是很走运,面试官在一开始就跟我坦言他是服务器开发方向,而我是客户端。整个面试过程非常的轻松愉悦,并且值得开心的是面试官也给了我一个不错的评价,虽然没有后续,但确实是一次非常好的面试体验。
网易互娱:在线游戏事业部
1.讲一下行为树模块的实现
2.讲一下你的全局消息系统的实现
3.讲一下你在项目中如何设计UI模块的
从需求出发,根据功能设计层级面板,分离数据的处理与表现,管理器提供泛型接口。
4.UI的多界面打开后返回上一级实现
听到返回上一级直接栈,非常经典的问题。
5.实现一个面板管理器的Open方法
主要是考虑相似面板实现相同的接口以及利用继承管理子元素。然后open()
方法中接受接口类型或者基类。
6.委托的本质是什么
委托是一个类,有invoke方法….
总结:
感觉得到面试官并不是很赞成我大二过去实习。问得也比较简单,可能也是因为不会lua的原因,与项目需求并不是特别匹配。
网易雷火:逆水寒项目组(补档)
1.项目中的UI如何搭建的
2.对象池的实现
3.项目中的问题与瓶颈
在跟面试官说做过肉鸽类游戏后面试官一针见血的指出了项目中是不是存在性能问题,确实是在场景中子弹与怪物过多的情况下会遇到帧率降低游戏卡顿的情况,面试官也试着问了一下有没有做优化处理,回答的是通过游戏设计层面去限制了子弹射速并且加速了回收策略,但是情况确实还是会出现。也被面试官吐槽了一句做得太粗糙了。
4.帧率低是因为场景中物体过多还是因为生成与销毁太密集
当时完全没有去做相关的测试,所以没有答上来。也确实在遇到这种情况需要去用profile做性能检测。
5.四叉树优化场景中物体的碰撞检测
还是基于上面卡顿的情景,提到可以用二叉树或者四叉树做碰撞检测优化。
推荐参考:KillerAery:空间数据结构
6.做过多少种UI,用过什么框架
做过背包,滑动列表,功能性界面等等还有基础UI,框架的话说用过MVC跟MVI,还有消息机制的UI,但是面试官并没有再细问。
7.对背包系统做优化(同一面板有大量UI元素如何避免加载卡顿)
提问场景是背包中有大量元素,如果打开时发现加载卡顿如何优化。当时的回答主要是从预加载,缓存队列跟对象池进行的分析,感觉面试官还比较满意。
预加载:在很有可能打开背包的情况的下提前进行部分元素的预加载,比如战斗结束领取完奖励这种情景,很有可能会打开背包查看物品,进行预加载,设置一个时间戳假如到时间没有打开背包再销毁….
利用缓存队列分批放在多帧内加载,按照批次对物品进行加载避免某一帧大量元素的加载。
对象池:牺牲内存保留部分背包内UI元素,打开背包时只需进行初始化。
8.如何降低draw call
当时被问到一瞬间很懵,然后明白可能面试官可能希望对背包系统的优化是从引擎层面来讲。就答了网格合并跟批处理,然后就掉进了陷阱。
9.动静态图集
基于第七题与第八题的情景,面试官问背包内有大量UI图标如何减少draw call,还问我日常开发有没有关注过,我诚实地说了没有。回答说把图标全部划分到同一个图集里,优化批处理降低draw call。面试官就继续说如果图标元素有很多张图集,然后这些图标都来自不同的图集,那draw call并没有得到优化,这种情况怎么办。我当时就懵懵的了,答了个分类处理图标并把背包按类别查看可以提高命中率,他问还有什么更好的方法吗,当时脑子一抽没想到动态图集,然后面试官就笑着说你做过图集没有,我说没有,他说还可以运行时动态生成图集。我才恍然大悟,直接在运行时把当前页面的图标动态合并到一张图集上就行。
10.全局消息机制的实现
11.行为树模块的实现
12.技能系统与角色属性管理
问了怎么实现的技能系统,回答每个技能都是一个单独类,然后带有各自的属性与一些依赖条件,与角色的属性绑定,计算单独放在属性管理器里面。
13.数据配置与工具开发
用得最多的还是SO,策划直接在引擎里面配置数据,因为没有后端采取的是最方便的方法。然后面试官问有没有为行为树或者其他系统做过数据配置的工具跟一些可视化工具。巧合的是因为之前开发的时候都有考虑过,回答说都做了数据分离方便策划改数据,可视化在战斗上做了,也算是半个工具吧。
14.介绍Unity的动画系统
介绍完还问我对Unity的动画系统哪些最熟悉,做过哪些动画到了什么地步。这问题太宽泛了就不贴答案了,感兴趣可以问gpt。
15.Avatar Mask的使用
经典上下半身分离的动画功能。这一点的话官方文档就有很好的说明:Unity:AvatarMask
16.动画混合树与分层动画
推荐参考:Unity动画系统详解
17.骨骼动画原理
当时回答了一堆概念,然后面试官说方式是这么个方式,怎么实现了解过吗,答没有。
推荐参考:骨骼动画的实现
18.骨骼如何带动蒙皮
也是答了一堆概念然后问我蒙皮算法实现,也不会。
推荐参考:线性蒙皮分解算法
19.会不会python
会但不多,不想挖坑直接说了不会。
20.有没有写过ECS跟jobsystem
了解但没有写过。推荐参考:烟雨:Unity DOTS
21.讲讲UnityShader
说了一些工作流与UnityShader的设计,但是实际开发项目中没有用过,只跟书实现过效果,被面试官批评了简历应该写了解而不是熟悉。
22.对简历的一些建议
23.讲讲对引擎基础架构的认识
聊了一些104学到的东西,已经被问麻了当时不知道该怎么回答了。
24.对开发哪些模块最感兴趣
25.讲一下C++11
26.右值引用与左值引用
当时脑子一团浆糊,说了一点简单的然后其余的记不清了。
推荐参考:详解左值引用与右值引用
27.智能指针的使用场景
确实c++开发的经验很少,面试官问我那几种智能指针的使用场景,答得支支吾吾的,基本上只会说智能管理内存,更安全更方便。还问我shared_ptr跟单例的分别作用场景,为什么在这要用shared_ptr不选择用单例,也没有答好。后面还断网了。
28.对mmo游戏的讨论
29.对游戏中UI开发的讨论
聊得很开心但是经常断网…..
总结:
被狠狠拷打了,面试官一上来就说自己是引擎负责人,然后说会问一些偏引擎跟优化的东西,被问了很多细节跟实操,确实对很多知识还停留在了解层面。本来感觉反问环节是很好拉近距离的时候,结果聊得挺开心的但是经常断网,真的难绷,还不知道是哪边的问题。但是面试官确实给出了非常多的学习方向与内容,问的问题很拓展我的思考,非常有用的一次面试。
电魂游戏:野蛮人2项目组
1.对大学一些经历的询问
2.介绍项目并且简单介绍技术点
3.事件系统的流程
4.之前做游戏的一些经历
5.行为树的内部运行方式
6.二叉树的遍历
7.以往的经历中对自己提升最大的事情
8.对过去参加过的游戏开发类活动的总结
9.构造函数与析构函数
10.虚析构函数的作用
11.new与malloc
12.申请内存会调用哪些底层接口
13.是否了解Windows编程
14.红黑树的特征
15.红黑树的构造过程
16.对常见算法的理解,比如贪心与搜索
17.挑一个最熟悉的算法讲一下实现与应用场景
18.口述BFS并且打印路径
19.C#值类型与引用类型
20.C#内存管理机制
21.GC与CLR
22.编译原理
23.tcp与udp的区别
24.udp如何实现稳定传输
25.说一下UnityShader
26.后处理的实现与原理
27.口述边缘检测的大致shader
28.渲染状态的设置
29.深度检测与透明度测试
30.项目中行为树的详细实现
31.对未来的工作规划
反问:
1.实习负责哪些内容
2.项目使用的大致架构
总结:
面试的内容非常宽泛,但是并不是非常深入,能感觉到项目组会希望你的潜力大一点比较好,面试官也说会希望实习生会的方向多一点,项目中负责的内容主要是看能力。面试官也很温柔,就是因为腾讯会议出了问题所以声音有点小。后面有接近10分钟面试官对我的主动输出,说了项目架构,项目人员情况与团队氛围,最后结束语是hr会联系你的,当时感觉应该是稳了,半小时后hr口头告知通过下周发正式录用,好耶好耶~
写在最后
整个春招的内容大概就是这些了,写这篇博客也是写了半天累死了,不过希望能给大家带来帮助。越面试是会越有经验的,在你回答当前这个问题的时候,你就应该猜到面试官很有可能会从你的回答中去提出下一个问题来挖掘你的深度,所以面试的表现应该始终把握在一个量内,能完整的回答上当前问题,但是不要过于卖弄你的知识面以防被深挖太多从而丢掉原有的分数。同时对自己简历内容的把控跟项目经验也是非常重要的一部分,你知道应该要知道面试官从你的简历上会提问哪些内容,提早做好应对,会让你更加的从容。再就是基础是一切的根基,并且深深地影响着你的面试内容。像西山居的面试官感觉我太小,计网跟操作系统都还不会,所以只能往八股跟项目去问,而网易那边也是因为我不会lua,直接丢失了很核心的竞争力。所以今后的学习方向,也是要从这些踩坑踩出来的经验出发,打好一个计算机学科该有的基础,完善的cpp项目经验以及工程能力,当然还有算法。希望日后能取得不错的成果。