您的位置:首页 > 移动开发 > Unity3D

Unity3d面试3

2016-05-02 23:17 281 查看
一、请简述GC(垃圾收集)产生的原因,并描述如何避免
产生的原因:GC 回收堆上的内存
避免:
1)减少用new创建对象的次数,在创建对象时会产生内存碎片,这样会造成碎片内存不法使用
2)使用公用的对象(静态成员,常量),但是不能乱用,因为静态成员和常量的生命周期是整个应用程序。
3 )将 String换为 StringBuilder
4)使用object pool(对象池)
二、什么是接口?接口有哪些好处,抽象类(abstract)和接口(interface)的区别 ...
什么是接口? 接口是一种用来定义程序的协议,它描述可属于任何类或结构的一组相关行为
接口是这样定义的: 接口,里面包含方法,但是没有方法的具体实现。
然后在继承该接口的类中 去实现接口中的所有方法。包括 属性、方法、事件、索引器,但是不能包括字段;;;; 接口中只能包含 属性、方法、事件、索引器; 接口可以实现C# 中的多继承。(c#不可以多继承,用接口可以实现) 接口可以继承接口,可以继承多个接口; 类可以继承接口,但是继承的类必须去实现接口中的方法代码。等。。 接口不能直接被实例化 接口一般不用什么修饰符,因为接口默认的修饰符是 public 公共的。 接口中的所有成员默认为public,因此接口中不能有private修饰符接口的好处: 对类的一种约束。
如果一个项目的需求可能在不断变化的情况下,用接口可以很容易进行拓展,并不影响以前写的功能模块的代码,只要新添加类,继承这个接口就可以了。 如果每个类都要用到一些公用的属性字段或者方法,则通过继承接口可以方便的实现,不用再每个类中都写一次公用的属性或方法。 接口中不能包含【常量、字段(域)、构造函数、析构函数、静态成员
抽象类(abstract)和接口(interface)的区别: abstract 类 和接口类似, 抽象类中定义方法,只有方法名,但不包含主体,不包含实现, 和接口一样, 可以把抽象方法 当作没有具体实现的虚方法。 抽象类不能被实例化。这个接口一样, 抽象类中并非一定有抽象方法,但是 有抽象方法的类, 一定是抽象类。 派生类必须覆盖基类的抽象方法,(也就是子类去实现继承类中的方法) 抽象类中可以包含: 属性、普通方法、可以包含虚方法、抽象方法;
using System;
public abstract class A //抽象类A
{
private int num=0;
public int Num //抽象类包含属性
{
get{return num;}set{num = value;}
}
public virtual int getNum() //抽象类包含虚方法
{
return num;
}
public void setNum(int n) // //抽象类包含普通方法
{
this.num = n;
}
public abstract void E(); //类A中的抽象方法E
}
public abstract class B : A // 抽象类B 继承了抽象类A, 所以抽象类B 也就继承了抽象方法E(), 类B 也是抽象类。
{
}
public class C :B // 在类C中 重写 类B 继承 类A 的抽象方法E(), 如果 类B中有自己的抽象方法,在类C中也必须去重写
{
// override 覆盖、 重写、覆写 public override void E() { }
}
public class Test
{
static void Main()
{
C c = new C(); // 实例化C, C也就有了E() 这个方法了。
c.E();
}
}
抽象类和接口相同点:
(1) 都可以被继承
(2) 都不能被实例化
(3) 都可以包含方法声明
(4) 派生类必须实现未实现的方法
区别:
(1) 抽象基类可以定义字段、属性、方法实现。接口只能定义属性、索引器、事件、和方法声明,不能包含字段。
(2) 抽象类是一个不完整的类,需要进一步细化,而接口是一个行为规范。微软的自定义接口总是后带able字段,证明其是表述一类“我能做。。。”
(3) 接口可以被多重实现,抽象类只能被单一继承
(4) 抽象类更多的是定义在一系列紧密相关的类间,而接口大多数是关系疏松但都实现某一功能的类中
(5) 抽象类是从一系列相关对象中抽象出来的概念, 因此反映的是事物的内部共性;接口是为了满足外部调用而定义的一个功能约定, 因此反映的是事物的外部特性
(6) 接口基本上不具备继承的任何具体特点,它仅仅承诺了能够调用的方法
(7) 接口可以用于支持回调,而继承并不具备这个特点
(8) 抽象类实现的具体方法默认为虚的,但实现接口的类中的接口方法却默认为非虚的,当然您也可以声明为虚的
三、.下列代码在运行中会产生几个临时对象?  string a = new string("abc");  a = (a.ToUpper() + "123").Substring(0, 2);  答:其实在C#中第一行是会出错的(Java中倒是可行)。应该这样初始化:  string b = new string(new char[]{'a','b','c'});四、.下列代码在运行中会发生什么问题?如何避免?  List ls = new List(new int[] { 1, 2, 3, 4, 5 });  foreach (int item in ls)  {  Console.WriteLine(item * item);  ls.Remove(item);  }  答:会产生运行时错误,因为foreach是只读的。不能一边遍历一边修改。
五、.请简述关键字Sealed用在类声明和函数声明时的作用  答:类声明时可防止其他类继承此类,在方法中声明则可防止派生类重写此方法。六、.请简述private,public,protected,internal的区别  答:  public:对任何类和成员都公开,无限制访问  private:仅对该类公开  protected:对该类和其派生类公开  internal:只能在包含该类的程序集中访问该类(程序集是包含一个或者多个类型定义文件和资源文件的集合。)七 .反射的实现原理?  答:审查元数据并收集关于它的类型信息的能力。  参考http://blog.163.com/xuanmingzhiy ... 762011612115124188/  反射个人认为,就是得到程序集中的属性和方法。  实现步骤:  1)导入using System.Reflection;  2)Assembly.Load("程序集")加载程序集,返回类型是一个Assembly  3)foreach (Type type in assembly.GetTypes())  {  string t = type.Name;  }  得到程序集中所有类的名称  4)Type type = assembly.GetType("程序集.类名");获取当前类的类型  5)Activator.CreateInstance(type); 创建此类型实例  6)MethodInfo mInfo = type.GetMethod("方法名");获取当前方法  7)mInfo.Invoke(null,方法参数); 八. .Net与Mono的关系?  答:Mono官网主页  Mono is a software platform designed to allow developers to easily create  cross platform applications. Sponsored by Xamarin, Mono is an open source  implementation of Microsoft's .NET Framework based on the ECMA standards for C# and the Common Language Runtime.  mono是.net的一个开源跨平台工具,就类似java虚拟机,java本身不是跨平台语言,但运行在虚拟机上就能够实现了跨平台。.net只能在windows下运行,mono可以实现跨平台跑,  可以运行于linux,Unix,Mac OS等。九、.简述unity3d支持的作为脚本的语言的名称  答:Unity的脚本语言基于Mono的.Net平台上运行,可以使用.NET库,这也为XML、数据库、正则表达式等问题提供了很好的解决方案。  Unity里的脚本都会经过编译,他们的运行速度也很快。这三种语言实际上的功能和运行速度是一样的,区别主要体现在语言特性上。  JavaScript:和网页中常用的JavaScript不一样,它编译后的运行速度很快,语法方面也会有不少区别。  C#  Boo:可以看做是Python语言的变种,又糅合了Ruby和C#的特性,它是静态类型语言十、.Unity3D是否支持写成多线程程序?如果支持的话需要注意什么?  答:参考http://www.unitymanual.com/3821.html  仅能从主线程中访问Unity3D的组件,对象和Unity3D系统调用  支持:如果同时你要处理很多事情或者与Unity的对象互动小可以用thread,否则使用coroutine。  注意:C#中有lock这个关键字,以确保只有一个线程可以在特定时间内访问特定的对象十一、.Unity3D的协程和C#线程之间的区别是什么?  答:http://blog.csdn.net/kongbu0622/article/details/8775037  多线程程序同时运行多个线程 ,而在任一指定时刻只有一个协程在运行,并且这个正在运行的协同程序只在必要时才被挂起。  除主线程之外的线程无法访问Unity3D的对象、组件、方法。  Unity3d没有多线程的概念,不过unity也给我们提供了StartCoroutine(协同程序)和LoadLevelAsync(异步加载关卡)后台加载场景的方法。 StartCoroutine为什么叫协同程序呢,所谓协同,就是当你在StartCoroutine的函数体里处理一段代码时,利用yield语句等待执行结果,这期间不影响主程序的继续执行,可以协同工作。	而LoadLevelAsync则允许你在后台加载新资源和场景,所以再利用协同,你就可以前台用loading条或动画提示玩家游戏未卡死,同时后台协同处理加载的事宜asynchronous[e ɪˈ s ɪŋ kr ə n ə s] .synchronous同步。    协程和线程的区别是:协程避免了无意义的调度,由此可以提高性能,但也因此,程序员必须自己承担调度的责任,同时,协程也失去了标准线程使用多CPU的能力。、进程:一个程序在一个数据集合上的一次运行运行过程。线程:是进程中的一个实体,是被系统独立调度和执行的基本单位。(状态:就绪、运行、等待)
十二、.U3D中用于记录节点空间几何信息的组件名称,及其父类名称  答:Transform 父类是 Component  16.简述四元数的作用,四元数对欧拉角的优点?  答:四元数用于表示旋转  相对欧拉角的优点:  1)能进行增量旋转  2)避免万向锁  3)给定方位的表达方式有两种,互为负(欧拉角有无数种表达方式)十三.向量的点乘、叉乘以及归一化的意义?  1)点乘描述了两个向量的相似程度,结果越大两向量越相似,还可表示投影  2)叉乘得到的向量垂直于原来的两个向量  3)标准化向量:用在只关系方向,不关心大小的时候14.矩阵相乘的意义及注意点
用于表示线性变换:旋转、缩放、投影、平移、仿射

15:为何大家都在移动设备上寻求U3D原生GUI的替代方案

不美观,OnGUI很耗费时间,效率不高,使用不方便

16.请简述如何在不同分辨率下保持UI的一致性  NGUI很好的解决了这一点,屏幕分辨率的自适应性,原理就是计算出屏幕的宽高比跟原来的预设的屏幕分辨率求出一个对比值,然后修改摄像机的size。
17 .为什么dynamic font在unicode环境下优于static font  Unicode是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案。  使用动态字体时,Unity将不会预先生成一个与所有字体的字符纹理。当需要支持亚洲语言或者较大的字体的时候,若使用正常纹理,则字体的纹理将非常大。18.Render 的作用?描述 MeshRender 和 SkinnedMeshRender 的关系与不同
A renderer is what makes an object appear on the screen 。Mesh 就是指模型的网格(同名组件是用于调整网格属性的), MeshFilter 一般是用于获得模型网格的组件,而 MeshRender 是用于把网格渲染出来的组件, 19. 简述SkinnedMesh 的实现原理  http://blog.csdn.net/n5/article/details/3105872 Skinned Mesh 中文一般称作骨骼蒙皮动画,正如其名,这种动画中包含骨骼( Bone )和蒙皮 (Skinned Mesh) 两个部分, Bone 的层次结构和关节动画类似, Mesh 则和关节动画不同:关节动画中是使用多个分散的 Mesh, 而 Skinned Mesh 中 Mesh 是一个整体,也就是说只有一个 Mesh, 实际上如果没有骨骼让 Mesh 运动变形, Mesh 就和静态模型一样了。 Skinned Mesh 技术的精华在于蒙皮,所谓的皮并不是模型的贴图(也许会有人这么想过吧),而是 Mesh 本身,蒙皮是指将 Mesh 中的顶点附着(绑定)在骨骼之上,而且每个顶点可以被多个骨骼所控制,这样在关节处的顶点由于同时受到父子骨骼的拉扯而改变位置就消除了裂缝。 Skinned Mesh 这个词从字面上理解似乎是有皮的模型,哦,如果贴图是皮,那么普通静态模型不也都有吗?所以我觉得应该理解为具有蒙皮信息的 Mesh 或可当做皮肤用的 Mesh ,这个皮肤就是 Mesh 。而为了有皮肤功能, Mesh 还需要蒙皮信息,即 Skin 数据,没有 Skin 数据就是一个普通的静态 Mesh 了。Skin 数据决定顶点如何绑定到骨骼上。顶点的 Skin 数据包括顶点受哪些骨骼影响以及这些骨骼影响该顶点时的权重(weight) ,另外对于每块骨骼还需要骨骼偏移矩阵 (BoneOffsetMatrix) 用来将顶点从 Mesh 空间变换到骨骼空间。在本文中,提到骨骼动画中的 Mesh 特指这个皮肤 Mesh ,提到模型是指骨骼动画模型整体。骨骼控制蒙皮运动,而骨骼本身的运动呢?当然是动画数据了。每个关键帧中包含时间和骨骼运动信息,运动信息可以用一个矩阵直接表示骨骼新的变换,也可用四元数表示骨骼的旋转,也可以随便自己定义什么只要能让骨骼动就行。除了使用编辑设定好的动画帧数据,也可以使用物理计算对骨骼进行实时控制。
下面分别具体分析骨骼蒙皮动画中的结构部件。20.Prefab的作用?如何在移动环境的设备下恰当地使用它?
  答:Prefab在实例化的时候用到,主要用于经常会用到的物体,属性方便修改21、请简述Unity3D下如何安全的在不同工程间迁移asset数据,请举出三种方法。
答:将 Assets 目录和 Library 目录一起迁移导出包用 unity 自带的 assets Server 功能 22.MeshCollider 和其他 Collider 的一个主要不同点?答: Meshcollider 再快也是基于 V3 顶点 ~~ 建议还是用 boxcollider , boxcollider 本身是基于算法,没有面的概念。
23、当一个细小的高速运动的物体(如子弹)撞向另一个较大的物体时,可能出现什么
情况?如何避免?
24、当一个细小的高速运动的物体(如子弹)撞向另一个较大的物体时,可能出现什么
情况?如何避免?
穿透(碰撞检测失败)http://forum.unity3d.com/threads/3353-collision-detection-at-high-speed(碰撞体变大, FixedUpdate, 代码限制 )
25、请简述OnEnable,Aawake和Start在运行时的发生顺序。哪些可能在同一个对象的生
命期中发生。
Awake - 》 OnEnable- 》Start OnEnable
26、请简述OnBecameVisible及OnBecameInvisible的发生时机,以及这一对回调方法的
意义。
答:当物体是否可见切换之时。可以用于只需要在物体可见时才进行的计算。
27  请简述Unity3D如何获知场景中需要加载的数据。
Resource.LoadAssetBundle28
请简述MeshRenderer中material和sharedmaterial的区别。
当使用Renderer.material的时候,每次调用都会生成一个新的material到内存中去,这在销毁物体的时候需要我们手动去销毁该material,否则会一直存在内存中。
也可以在场景替换的时候使用Resources.UnloadUnusedAssets去统一释放内存。
当使用Renderer.sharedMaterial的时候并不会生成新的material,而是直接在原material上修改,并且修改后的设置就会被保存到项目工程中。一般不推荐使用这个去修改,当某个材质球只被一个gameobject使用的时候可以使用这个去修改,并且最好在修改之前把原属性设置保存,当使用完毕后立即恢复原设置,防止下次加载后的gameobject上还会残留之前的设置信息。
如果是主角这一类gameobject身上需要修改材质的属性或者shader属性比较多的时候,可以第一次使用material,这样可以动态的生成一个material实例,然后再使用sharedmaterial,动态的修改这个新生成的material,而且不会创建新的material。

修改sharedMaterial将改变所有物体使用这个材质的外观,并且也改变储存在工程里的材质设置。

不推荐修改由sharedMaterial返回的材质。如果你想修改渲染器的材质,使用material替代。

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: