Unity3D游戏开发岗笔试 笔记
目录
C#中的委托是什么?事件是一种委托吗?
什么是协同程序?
Heap与Stack的区别
数组中存放了某一类型得到数据集合,用泛型实现对这个数组的排序
StringBuilder和String的区别
Animation和Animator的区别
Unity3D脚本从唤醒到销毁有一套比较完整的生命周期,例举出系统自带的方法。
Unity3D动态加载资源的方式
Unity内存优化的方法(至少五种)
什么是AssetBundle?谈谈你对AssetBundle内存分配情况的理解。
谈谈你对3D渲染管道的理解。
下列代码,会出现什么问题?为什么?
委托本质上是一种“方法接口”,它相当于C/C++中的函数指针,但比函数指针安全,在C#中通常用于事件处理。事件不是委托,不过由于事件的性质决定了处理它的程序逻辑能访问的参数,因此,在C#中处理事件的逻辑都包装为委托。
委托的简单运动:
//第1步:声明一个委托
public delegate void CalculateDelegate(int x, int y);
//第2步:创建与委托关联的方法,二者具有相同的返回值类型和参数列表
public void Add(int i, int j)
{
MessageBox.Show((i+j).ToString());
}
//第3步:定义委托类型变量
private CalculateDelegate myDelegate;
public void GetDelegateEx()
{
//第4步:进行委托绑定
myDelegate = new CalculateDelegate(Add);
//第5步:回调Add方法
myDelegate(1, 2);
}
协程是在主程序运行时同时开启另一段逻辑处理,来协同当前程序的执行。换句话说,开启协同程序就是开启一个线程,但是协程并不是线程。
在Unity3D中,使用MonoBehaviour.StartCoroutine方法即可开启一个协同程序,也就是说该方法必须在 MonoBehaviour 或继承于MonoBehaviour的类中调用。
协程是一个分部执行,遇到条件(yield return语句)会挂起,直到条件满足才会被唤醒继续执行后面的代码。
Unity在每一帧都会去处理对象上的协程。主要是在Update后去处理协程(检查协程的条件是否满足)。
扩展:线程和协同程序的主要不同在于,在多处理器情况下,从概念上来讲多线程程序同时运行多个线程;而协同程序是通过协作来完成,在任一指定时刻只有一个协同程序在运行,并且这个正在运行的协同程序只在必要时才会被挂起。
内存分为两类,一类是栈内存,一类是堆内存。
栈内存是指程序进入一个方法时,会为这个方法单独分配一块私属存储空间,用于存储这个方法内部的局部变量,当这个方法结束时,分配给这个方法的栈会释放,这个栈中的变量也将随之释放。
堆是与栈作用不同的内存,一般用于存放不放在当前方法栈中的那些数据,例如,使用 new创建的对象都放在堆里,所以,它不会随方法的结束而消失。 方法中的局部变量使用 final修饰后,放在堆中,而不是栈中。
1.heap是堆,stack是栈;
2.stack的空间由操作系统自动分配和释放,heap的空间是手动申请和释放的,heap常用new关键字来分配;
3.stack空间有限,heap的空间是很大的自由区;
4.若只是声明一个对象,则先在栈内存中为其分配地址空间,
若再new一下,实例化它,则在堆内存中为其分配地址。
使用委托进行排序的条件设置。
public delegate bool Compare(T t1,T t2);
publc void Sort(T[] array,Compare del)
{
for(int i=0;i(array,Compare(t1,t2){return (t1-t2)>0;});
}
String对象是不可改变的,每次只能赋值一次,在每次改变时,都会生成一个新的字符串令原有的对象引用新生成的对象;
StringBuilder每次的操作都是对自身的对象进行操作,其所占的空间会随着内容的增加而扩充。
在做字符串的操作时,需要大量进行修改增加的操作时,为了避免生成许多不必要的匿名字符串对象影响性能,一般都使用StringBuider,如果对字符串只进行一次或少量操作,使用String就行。
Animation和Animator 虽然都是控制动画的播放,但是它们的用法和相关语法都是大有不同的。Animation 控制一个动画的播放,而Animator是多个动画之间相互切换,并且Animator 有一个动画控制器,俗称动画状态机。
Animator 利用它做动画的切换是很方便的,但是它有一个缺点就是占用内存比Animation大。
Awake->OnEnable->Start->FixedUpdate->OnTriggerXXX->OnCollision->Update->LateUpdate->OnGUI->OnDisable->OnDestroy->OnApplicationQuit
1、Resources.Load()
把需要用到的资源全部放入名为Resource的文件夹里,需要调用的时候则通过方法调用;
2、AssetBundle.Load()
把对象打包成asset bundle格式,上传到本地磁盘或者服务器上,然后通过WWW模块在服务器端把需要的资源下载下来,在场景中进行资源的加载。
这个看的很懵,链接在这里,大家可以参考一下:https://blog.csdn.net/cyxisgreat/article/details/8761877
参考自:https://blog.csdn.net/nliki/article/details/51822812
渲染管道是指在显示器上为了显示出图像而经过的一系列必要操作。
分为三个阶段:应用程序阶段(CPU)、几何阶段(GPU)、光栅阶段
应用程序阶段在CPU里进行,把模型的顶点坐标、纹理等数据计算之后传给GPU;
几何阶段在GPU进行,传入GPU的坐标是物体的局部坐标,每个顶点的坐标都是以自身为坐标系的坐标,这个时候需要进行四个阶段的坐标转换:局部坐标系-->世界坐标系-->观察坐标系-->视口坐标系,使模型在转换绘制完成之后可以在2D的屏幕上看起来有3D的效果。
坐标转换后模型会被分割成多块三角片,对三角片进行裁剪(包含视域裁剪、视口裁剪、背面剔除)后进行光栅阶段。
光栅阶段则是对于三角片进行着色,遮挡剔除。
public static void Main()
{
List arr=new List (new int[] {1,2,3,4,5,6,7});
foreach(int item in arr)
{
Console.WriteLine(item);
arr.Remove(item);
}
}
上述代码会在第二次调用迭代器的时候抛出异常,因为在使用迭代器时,不允许对容器的内容进行更改,在对容器更改之后,迭代器会报错(个人理解,有错误希望在评论指出,小弟一定更改)。