1.面试官:TCP和UDP的区别
答:TCP和UDP是TCP/IP协议簇中传输层的传输协议。
Tcp是面向连接的,可靠的,面向字节流的传输。TCP在连接时需要三次握手,断开时需要四次挥手。TCP的连接是点到点的连接。Tcp收到的数据保证顺序,TCP有着拥塞控制,超时重发,丢弃重复数据,检验数据等机制。
UDP是面向数据包的,不可靠,包头简单,传输速度快。可以一对一,一对多,多对多,多对一发送,无需建立连接,没有拥塞控制,即使网络拥塞了也会不断的发送数据。目前在实时应用中,如游戏直播等,虽然UDP不可靠,但是得益于网速的提升以及可以自己编写重传机制来保证UDP的可靠性。
2.面试官:Http和Https的区别
答:简单来说,Http属于明文传输,不安全,Https属于加密传输,较安全。
Http是无状态的连接,通过明文传输,信息可能被拦截,篡改等等。Https是HTTP的安全加强版,Https 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,比 Http 协议安全。
3.面试官:Animation和Animator的区别
答:Animation需要通过代码手动控制动画的播放和迁移。而Animator拥有动画状态机,可以通过动画状态机来设置动画之间的状态,并且可以为单个动画设置脚本代码来控制事件。
4.面试官:MonoBehaviour的生命周期
答:
5.面试官:类和结构体的区别?使用环境?
答:结构体是值类型,类是引用类型。结构体存储在栈中,类存储在堆中,栈的空间小但是访问快,堆的空间大但是访问速度较慢。
结构体不能继承,不能创建默认构造函数和析构函数。结构成员不能指定为 abstract、virtual 或 protected。结构体的构造函数必须为所有值赋初值。
结构体一般存储较为轻量的数据,类一般存储具有较为复杂逻辑结构的数据。
使用环境:
- 当堆栈的空间很有限,且有大量的逻辑对象时,创建类要比创建结构好一些。
- 对于点、矩形和颜色这样的轻量对象,假如要声明一个含有许多个颜色对象的数组,则CLR需要为每个对象分配内存,在这种情况下,使用结构的成本较低。
- 在表现抽象和多级别的对象层次时,类是最好的选择,因为结构不支持继承。
6.面试官:抽象类和接口的区别?
答: - 抽象类和接口都不能实例化。
- 抽象类可以有抽象的的方法和未抽象的的方法,可以通过子类来重写。
- 抽象类主要是子类的通用结构。常量、字段、运算符、实例构造函数、析构函数或类型、不能包含静态成员。
- 接口不能有实现的方法,接口主要是作为规范来使用。
7.面试官:MeshCollider和其他Collider的一个主要不同点?
答:
MeshCollider是网格碰撞器,对于复杂网状模型上的碰撞检测,比其他的碰撞检测精确的多,但是相对其他的碰撞检测计算也增多了,所以一般使用网格碰撞也不会在面数比较高的模型上添加,而会做出两个模型,一个超简模能表示物体的形状用于做碰撞检测,一个用于显示。
8.面试官:Unity3d中的碰撞器和触发器的区别?
答:
碰撞器是触发器的载体,而触发器只是碰撞器身上的一个属性。当Is Trigger=false时,碰撞器根据物理引擎引发碰撞,产生碰撞的效果,可以调用OnCollisionEnter/Stay/Exit函数;当Is Trigger=true时,碰撞器被物理引擎所忽略,没有碰撞效果,可以调用OnTriggerEnter/Stay/Exit函数。如果既要检测到物体的接触又不想让碰撞检测影响物体移动或要检测一个物件是否经过空间中的某个区域这时就可以用到触发器。
9.面试官:请描述你所了解的设计模式,并说明在你的项目中哪里使用过?
答:
单例:对象池,游戏管理器,抽象工厂
状态:有限状态机
桥接:有限状态机
策略:AI自动行为操控中每种操控算法的独例
10.面试官:请说出4种面向对象的设计原则,并分别简述它们的含义。
答:
单一职责原则:一个类,最好只做一件事,只有一个引起它的变化。
开放-封闭原则:对于扩展是开放的,对于更改是封闭的。
里氏替换原则:子类必须能够替换其基类。
依赖倒置原则:设计应该依赖于抽象而不是具体实现。
接口隔离原则:使用多个小的专门的接口而不要使用一个大的总接口。
11.面试官:Image和RawImage的区别?
答: - Imgae比RawImage更消耗性能。
- Image只能使用Sprite属性的图片,但是RawImage什么样的都可以使用。
- Image适合放一些有操作的图片(裁剪、平铺、旋转等),针对Image Type属性。
- RawImage只放单独展示的图片就可以,性能会比Image好很多。
12.面试官:Resources和AssetBundle使用区别?
答:
Resources是动态内部调用,Resources在编辑环境下是project窗口的一个文件夹,调用里面的资源,可以用Resources类,比如Resources.Load,打包后这个文件夹是不存在的,会统一生成assets资源。
AssetBundle是外部调用,要用AssetBundle首先要先把资源打包为.assetbundle文件,再动态的去加载这个文件,本地或者网络服务器都可以。
13.面试官:协程的用法?
答:
在主线程运行的同时开启另一段逻辑处理,来协助当前程序的执行,协程很像多线程,但不是多线程。Unity的协程是在每帧结束之后去检测yield的条件是否满足。 - 用来延时
- 用来异步加载等待
- 加载WWW
- 基本就是控制代码在特定的时机执行
14.面试官:四元数是什么?主要作用什么?对欧拉角的优点是什么?
答:
所谓四元数,就是把4个实数组合起来的东西。4个元素中,一个是实部,其余3个是虚部。
作用:四元数用于表示旋转。
优点: - 能进行增量旋转
- 避免万向锁
- 给定方位的表达方式有两种,互为负(欧拉角有无数种表达方式)
15.面试官:对渲染管线的理解?
答:
渲染管线流程: - 应用阶段(由CPU负责,输出是渲染所需要的几何信息,即渲染图元)
- 几何阶段(由GPU负责,处理渲染图元,这一阶段中最重要的就是把顶点坐标变换到屏幕空间中交给光栅器处理,这阶段输出的是屏幕空间中二维顶点坐标、每个顶点对应的深度值、着色等相关信息)
- 光栅化阶段(由GPU负责,这一阶段会使用上个阶段传递的数据来产生屏幕上的像素,并渲染出最终的图像)
16.面试官:叉乘和点乘的意义?
答:
叉乘:
几何意义:得到一个与这两个向量都垂直的向量,这个向量的模是以两个向量为边的平行四边形的面积。
在同一平面内,结果>0表示B在A的逆时针方向,结果<0表示B在A的顺时针方向, 结果=0表示B与A同向。
点乘:
几何意义:可以用来表征或计算两个向量之间的夹角,以及b向量在a向量方向上的投影。
两个向量的点乘所得到的是两个向量的余弦值,也就是-1到1之间,0表示垂直,-1表示相反,1表示相同方向。
17.面试官:虚方法和抽象方法的区别?
答: - 抽象方法是只有方法名称,没有方法体,即没有方法的具体实现,子类必须重写父类抽象方法才能实现具体功能;虚函数有方法名称也也有方法体,但是子类可覆盖,也可不覆盖。
- 抽象方法是一种强制派生类覆盖的方法,否则派生类将不能被实例化。
- 抽象方法只能在抽象类中声明,虚方法不是。
- 派生类必须重写抽象类中的抽象方法,虚方法则不必要。
18.面试官:Addcomponent后哪个生命周期函数会被调用?
答:
对于AddComponent添加的脚本,其Awake,Start,OnEnable是在Add的当前帧被调用的,其中Awake,OnEnable与AddComponent处于同一调用链上,Start会在当前帧稍晚一些的时候被调用,Update则是根据Add调用时机决定何时调用:如果Add是在当前帧的Update前调用,那么新脚本的Update也会在当前帧被调用,否则会被延迟到下一帧调用。
19.面试官:Unity中协程是如何实现的?
答:
协程不是线程,也不是异步执行的。协程和MonoBehaviour的Update函数一样也是在MainThread中执行的。使用协程你不用考虑同步和锁的问题。
协程其实就是一个IEnumerator(迭代器),IEnumerator 接口有两个方法Current和MoveNext() ,只有当MoveNext()返回 true时才可以访问Current,否则会报错。迭代器方法运行到yield return语句时,会返回一个expression表达式并保留当前在代码中的位置,当下次调用迭代器函数时执行从该位置重新启动。
20.面试官:图集打包怎么分类?
答: - 按业务功能的预制,寻找依赖,收集所有预制引用的图片。
- 如果有多个预制使用了同一张图片,我们就把它扔到common文件夹。
- 让图集尽量紧凑,没有太多空白,尽量让图集处于2的n次方大小。
21.面试官:数组和List两者效率之间哪个好?
答:
数组:数组在C#中是最早出现的。它在内存中是连续的存储的,所以索引速度很快,而且赋值与修改元素也很简单。可以利用偏移地址访问元素,时间复杂度为O(1);删除时间复杂度为O(n),数组没有添加数据选项。
List:基于数组,时间复杂度相同,插入为O(n);不过在数据少量的时候跟数组差不多,数据庞大的时候效率会低于数组。
22.面试官:哈希表与字典的区别?
答:
字典:内部用了Hashtable作为存储结构。 - 如果我们试图找到一个不存在的键,它将返回 / 抛出异常。
- 它比哈希表更快,因为没有装箱和拆箱,尤其是值类型。
- 仅公共静态成员是线程安全的。
- 字典是一种通用类型,这意味着我们可以将其与任何数据类型一起使用(创建时,必须同时指定键和值的数据类型)。
- Dictionay 是 Hashtable 的类型安全实现, Keys和Values是强类型的。Dictionary遍历输出的顺序,就是加入的顺序。
哈希表: - 如果我们尝试查找不存在的键,则返回 null。
- 它比字典慢,因为它需要装箱和拆箱。
- 哈希表中的所有成员都是线程安全的。
- 哈希表不是通用类型。
- Hashtable 是松散类型的数据结构,我们可以添加任何类型的键和值。
- HashTable是经过优化的,访问下标的对象先散列过,所以内部是无序散列的。
23.面试官:值类型和引用类型的区别?
答: - 值类型存取快,引用类型存取慢。
- 值类型表示的是数据,引用类型表示的是指向存储在内存堆中的数据的指针和引用。
- 值类型继承自System.ValueType,引用类型继承自System.Object。
- 值类型根据声明位置不同堆和栈中都有可能存储,引用类型分配在堆中。
24.面试官:什么是序列化?
答:
序列化是通过将对象转换为字节流,从而存储对象或将对象传输到内存,数据库或文件的过程。主要用途是保存对象的状态,包括对象的数据,以便能够在需要是重建对象。反向过程称为反序列化。
25.面试官:委托是什么,event关键字有什么用?
答:
委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。
event关键字的作用,为了限制委托的调用条件,使之只能在外部进行,-=、+=操作不能调用,但可以在类内部调用。
26.面试官:在C#中using和new这两个关键字有什么意义?
答:
using 关键字有两个主要用途:
作为指令,用于为命名空间创建别名或导入其他命名空间中定义的类型。
作为语句,用于定义一个范围,在此范围的末尾将释放对象。
new 关键字:新建实例或者隐藏父类方法。
27.面试官:System.String 和System.StringBuilder有什么区别?
答:
System.String是不可变的字符串。
System.StringBuilder存放了一个可变的字符串,并提供一些对这个字符串修改的方法。
String类在执行字符串拼接的操作上,用“+”会产生新的对象,占用内存。
StringBuilder类只是修改字符串的内容,不建立新的对象。
28.面试官:const和readonly有什么区别?
答:
const 字段只能在该字段的声明中初始化。
不允许在常数声明中使用 static 修饰符。
readonly 字段可以在声明或构造函数中初始化。
29.面试官:C#中的委托是什么?事件是不是一种委托?
答:
委托可以把一个方法作为参数代入另一个方法。委托可以理解为指向一个函数的引用。
事件是一种特殊的委托。
30.面试官:请简述ArrayList和List<>的主要区别。
答:
ArrayList是非泛型列表,存储数据是把所有的数据都当成object类型数据,存在装箱问题,取出来使用的时候存在拆箱问题,装箱拆箱会使性能变差,而且存在数据安全问题,但是优点在于可以让值类型和引用类型相互转换。
List是泛型列表,在使用的时候才会去定义数据类型,泛型避免了拆装箱的问题,存入读取熟读较快,类型也更安全。
31.面试官:简述一下对象池,你觉得在FPS里哪些东西适合使用对象池?
答:
对象池就存放需要被反复调用资源的一个空间,当一个对象回大量生成的时候如果每次都销毁创建会很费时间,通过对象池把暂时不用的对象放到一个池中(也就是一个集合),当下次要重新生成这个对象的时候先去池中查找一下是否有可用的对象,如果有的话就直接拿出来使用,不需要再创建,如果池中没有可用的对象,才需要重新创建,利用空间换时间来达到游戏的高速运行效果,在FPS游戏中要常被大量复制的对象包括子弹,敌人,粒子等。
32.面试官:CharacterController和Rigidbody的区别?
答:
Rigidbody具有完全真实物理的特性,Unity中物理系统最基本的一个组件,包含了常用的物理特性,而CharacterController可以说是受限的的Rigidbody,具有一定的物理效果但不是完全真实的,是Unity为了使开发者能方便的开发第一人称视角的游戏而封装的一个组件。
33.面试官:简述prefab的用处?
答:
在游戏运行时实例化,prefab相当于一个模板,对你已经有的素材、脚本、参数做一个默认的配置,以便于以后的修改,同时prefab打包的内容简化了导出的操作,便于团队的交流。
34.面试官:请简述sealed关键字用在类声明时与函数声明时的作用?
答:
sealed修饰的类为密封类,类声明时可防止其他类继承此类,在方法中声明则可防止派生类重写此方法。
35.面试官:使用Unity3d实现2d游戏,有几种方式?
答:
1.使用本身的GUI,在Unity4.6以后出现的UGUI
2.把摄像机的Projection(投影)值调为Orthographic(正交投影),不考虑z轴
3.使用2d插件,如:2DToolKit,和NGUI