腾讯游戏客户端面试-初面
- 写在前面
- 问题
- 1.值类型和引用类型?
- 2.Unity IL的定义?
- 3.之前处理比较深入的一些问题?
- 4.贴图常见的压缩策略?
- 5.Unity生命周期?
- 6.内存区域分配?
- 7.GC机制?
- 8.死锁的四个必要条件,常见原因?
- 9.TCP和UDP的区别?
- 10.虚函数的意思?
- 11.如何能减小游戏内的DP?
- 12.渲染管线?
- 13.Defer和Forward的区别?
- 14.简要说一下Phong 模型,以及知道别的光照模型么?
- 15.内联函数的含义?
- 16.直接光照和间接光照的区别?
- 17.Awake的具体执行阶段?
- 18.UGUI和NGUI的区别,UGUI的优化方式?
- 19.C#的对象生命周期?
- 20.引擎框架?
- 21.手机GPU架构?
- 22.GPU常见优化算法?
- 总结
写在前面
已经很久没有登录博客了,犹记得上次还是在两年前,那时候怀揣着对游戏行业的初心。
两年,没错,我依然还在游戏行业,虽然加班在做难免,但也时常鼓励自己不忘初心。
毕业的第一年我去了一家小公司,18年的盛夏,赶上游戏版号的事件,所以试用期满被裁。之后我去了某页游公司做客户端,知道的朋友大概能理解其中诸多加班,种种苦痛,经历了一段暗无天日的加班之后,迷茫不已的我有幸去了网易,不过是作为网易的新职能部门,代码写得少,话说得多。所以多多少少心里那点对于技术的追求在一个角落隐隐生根发芽。
面试的结果对我来说如果通过的话肯定最好,不能过也告诉自己顺其自然,随遇而安。但是却让我意识到一定要抓住自己的Free Time去学习,补好基础,Coding and Thinking more。
写于来网易后的一年。
问题
1.值类型和引用类型?
值类型的变量直接存储数据,而引用类型的变量持有的是数据的引用,数据存储在数据堆中。
值类型(value type):byte,short,int,long,float,double,decimal,char,bool 和 struct 统称为值类型。值类型变量声明后,不管是否已经赋值,编译器为其分配内存。
引用类型(reference type):string 和 class统称为引用类型。当声明一个类时,只在栈中分配一小片内存用于容纳一个地址,而此时并没有为其分配堆上的内存空间。当使用 new 创建一个类的实例时,分配堆上的空间,并把堆上空间的地址保存到栈上分配的小片空间中。
2.Unity IL的定义?
IL是.NET框架中中间语言(Intermediate Language)的缩写。使用.NET框架提供的编译器可以直接将源程序编译为.exe或.dll文件,但此时编译出来的程序代码并不是CPU能直接执行的机器代码,而是一种中间语言IL(Intermediate Language)的代码(来源百度)
3.之前处理比较深入的一些问题?
分别从代码上,渲染上,和美术沟通上说了三条问题。
4.贴图常见的压缩策略?
- 安卓:ETC1,ETC2
- IOS:ASTC,PVRTC
- PC:DXTC,DXTCX
5.Unity生命周期?
阶段 | 事务 |
---|---|
Awake | 只会被调用一次,在Start方法之前被调用 |
Start | 只执行一次,在Awake方法执行结束后执行 |
Update | 每一帧执行 |
FixedUpdate | 先执行Update,然后才去执行lateUpdate |
LateUpdate | / |
OnDestroy | 当前脚本销毁时调用 |
6.内存区域分配?
- 栈区(stack)— 程序运行时由编译器自动分配,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。程序结束时由编译器自动释放。
- 堆区(heap) — 在内存开辟另一块存储区域。一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收。
- 全局区(静态区)(static)—编译器编译时即分配内存。全局变量和静态变量的存储是放在一块的。对于C语言初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。而C++则没有这个区别 - 程序结束后由系统释放。
7.GC机制?
给对象添加一个应引用计数器,有一个地方引用他,就加一,当引用失效就减一,任何时刻计数器为0的对象就是不可能再被使用的。
很少使用,因为他很难解决对象之间相互引用的问题
8.死锁的四个必要条件,常见原因?
-
竞争不可抢占资源引起死锁
通常系统中拥有的不可抢占资源,其数量不足以满足多个进程运行的需要,使得进程在运行过程中,会因争夺资源而陷入僵局,如磁带机、打印机等。只有对不可抢占资源的竞争 才可能产生死锁,对可抢占资源的竞争是不会引起死锁的。 -
竞争可消耗资源引起死锁
-
进程推进顺序不当引起死锁
进程在运行过程中,请求和释放资源的顺序不当,也同样会导致死锁。例如,并发进程
P1、P2分别保持了资源R1、R2,而进程P1申请资源R2,进程P2申请资源R1时,两者都会因为所需资源被占用而阻塞。
9.TCP和UDP的区别?
TCP:三次握手,第四次挥手。
UDP:实时传递,同步,但不安全。
10.虚函数的意思?
面向对象的语言有三大特性:继承、封装、多态。虚函数作为多态的实现方式,重要性毋庸置疑。
多态意指相同的消息给予不同的对象会引发不同的动作(一个接口,多种方法)。其实更简单地来说,就是“在用父类指针调用函数时,实际调用的是指针指向的实际类型(子类)的成员函数”。多态性使得程序调用的函数是在运行时动态确定的,而不是在编译时静态确定的。
11.如何能减小游戏内的DP?
不要被重复绘制,相同资源放在同一个Layer,动态合批,静态合批,等等。
12.渲染管线?
13.Defer和Forward的区别?
延迟渲染,正向渲染。可以看出前向渲染和延迟渲染的不同点在于多了一个Gbuffer(缓冲区)。
14.简要说一下Phong 模型,以及知道别的光照模型么?
Phong光照模型中的环境光照(Ambient lighting)部分就是模拟全局光照中间接光照的影响(即来自于其他物体的反射光等),这里只是很简单的近似,因此结果很粗糙。
Lamert 光照模型
15.内联函数的含义?
inline是C++语言中的一个关键字,可以用于程序中定义内联函数,inline的引进使内联函数的定义更加简单。说到内联函数,这里给出比较常见的定义,内联函数是C++中的一种特殊函数,它可以像普通函数一样被调用,但是在调用时并不通过函数调用的机制而是通过将函数体直接插入调用处来实现的,这样可以大大减少由函数调用带来的开销,从而提高程序的运行效率。一般来说inline用于定义类的成员函数。
16.直接光照和间接光照的区别?
直接光照:点光源,聚光源,面光源。
间接光照:SH,GI,LightProbe。
17.Awake的具体执行阶段?
进程被唤起的时候。
18.UGUI和NGUI的区别,UGUI的优化方式?
19.C#的对象生命周期?
无论是指类型的变量或是类类型的变量,其存储单元都是在栈中分配的,唯一不同的是类类型的变量实际上存储的是该类对象的指针,相当于vc6中的CType*,只是在.net平台的语言中将指针的概念屏蔽掉了。我们都知道栈的一大特点就是LIFO(后进先出),这恰好与作用域的特点相对应(在作用域的嵌套层次中,越深层次的作用域,其变量的优先级越高)。因此,再出了“}”后,无论是值类型还是类类型的变量(对象指针)都会被立即释放(值得注意的是:该指针所指向的托管堆中的对象并未被释放,正等待GC的回收)。.NET中的栈空间是不归GC管理的,GC仅管理托管堆。
20.引擎框架?
简要回答了引擎中各大部分。
21.手机GPU架构?
TSR/TSDR
22.GPU常见优化算法?
HSR,EarlyZ。
总结
回答上来一半一半吧,但是真得还是要下功夫了解一下基础的。
因为做得事情多而不精,导致自己也没有很好的深入探究。
继续加油咯~