unity面试题整理----50道常见

本文整理了50道关于Unity面试中常见的C#和Unity技术问题,涵盖值类型与引用类型的区别、C#引用类型基类、ArrayList与List<T>的区别、垃圾回收机制、接口与抽象类对比、多线程与协程的运用,以及Unity中的碰撞器、渲染、资源管理等多个方面,帮助开发者深入理解Unity开发中的关键概念和技术要点。
摘要由CSDN通过智能技术生成

1.、请简述值类型与引用类型的区别

区别:

  1. 值类型存储在内存栈中,引用类型数据存储在内存堆中,而内存单元中存放的是堆中存放的地址。
  2. 值类型存取快,引用类型存取慢。
  3. 值类型表示实际数据,引用类型表示指向存储在内存堆中的数据的指针和引用。
  4. 栈的内存是自动释放的,堆内存是.NET中会由GC来自动释放。
  5. 值类型继承自System.ValueType,引用类型继承自System.Object。

2、C#中所有引用类型的基类是什么

  1. 引用类型的基类是System.Object 。
  2. 值类型的基类是System.ValueType。
  3. 值类型也隐式继承自System.Object。

3.请简述ArrayList和List<T>的主要区别

  1. List是接口,ArrayList是一个实现了该接口的类,可以被实例化。(这一条应该就是面试想知道的答案)
  2. ArrayList存在不安全类型(ArrayList会把所有插入其中的数据都当做Object来处理);装箱拆箱的操作(费时)

4、请简述GC(垃圾回收)产生的原因,并描述如何避免?

new对象时,当可分配的内存不足GC就会去回收未使用的对象,但是GC的操作是非常复杂的,会占用很多CPU时间,对于移动设备来说频繁的垃圾回收会严重影响性能。下面的建议可以避免GC频繁操作。

  1. 减少用new创建对象的次数,在创建对象时会产生内存碎片,这样会造成碎片内存不法使用
  2. 使用公用的对象(静态成员,常量),但是不能乱用,因为静态成员和常量的生命周期是整个应用程序。
  3. 在拼接大量字符串时StringBuilder。在使用注意,创建StringBuilder对象时要设置StringBuilder的初始大小如:
  4. StringBuilder sbHtml = new StringBuilder (size);
  5. 使用object pool(对象池)

5、请描述Interface与抽象类之间的不同

相同点:

  1. 都可以被继承
  2. 都不能被实例化
  3. 都可以包含方法声明
  4. 派生类必须实现未实现的方法

区别:

  1. 抽象基类可以定义字段、属性、方法实现。接口只能定义属性、索引器、事件、和方法声明,不能包含字段。
  2. 抽象类是一个不完整的类,需要进一步细化,而接口是一个行为规范。
  3. 抽象类只能被单一继承,接口可以被多重实现。
  4. 抽象类更多的是定义在一系列紧密相关的类间,而接口大多数是关系疏松但都实现某一功能的类中
  5. 抽象类是从一系列相关对象中抽象出来的概念,因此反映的是事物的内部共性;接口是为了满足外部调用而定义的一个功能约定, 因此反映的是事物的外部特性
  6. 接口基本上不具备继承的任何具体特点,它仅仅承诺了能够调用的方法
  7. 接口可以用于支持回调,而继承并不具备这个特点
  8. 抽象类实现的具体方法默认为虚的,但实现接口的类中的接口方法却默认为非虚的,当然您也可以声明为虚的
  9. 如果抽象类实现接口,则可以把接口中方法映射到抽象类中作为抽象方法而不必实现,而在抽象类的子类中实现接口中方法

6、下列代码在运行中会产生几个临时对象?

  1. string a = new string("abc"); a = (a.ToUpper() +"123").Substring(0, 2);C#会报错,java可行(个人认为答完这个即可)。
  2. C#中应该是 string b = new string(new char[] {'a','b','c'});产生五个临时变量。

7、下列代码在运行中会发生什么问题?如何避免?

    List<int> ls = new List<int>(new int[] { 1,2,3,4,5});
            foreach (var item in ls)
            {
                Console.WriteLine(item*item);
                ls.Remove(item);
            }

会产生运行时错误,不能一边遍历一边修改。建议使用for循环来代替,foreach建议只用在读取上,不用在修改上。

8、请简述关键字Sealed用在类声明和函数声明时的作用

类声明时可防止其他类继承此类,在方法中声明则可防止派生类重写此方法。

9、请简述private,public,protected,internal的区别

  1. public:对任何类和成员都公开,无限制访问
  2. private:仅对该类公开
  3. protected:对该类和其派生类公开
  4. internal:只能在包含该类的程序集中访问该类
  5. protected internal:protected + internal

10、反射的实现原理?

审查元数据并收集关于它的类型信息的能力。反射个人认为,就是得到程序集中的属性和方法。
实现步骤:

  1. 导入using System.Reflection。
  2. Assembly.Load("程序集")加载程序集,返回类型是一个Assembly。
  3.  foreach (Type type in assembly.GetTypes()) {          string t = type.Name;            }
  4. 得到程序集中所有类的名称。
  5. Type type = assembly.GetType("程序集.类名");获取当前类的类型。
  6. Activator.CreateInstance(type); 创建此类型实例。
  7. MethodInfo mInfo = type.GetMethod("方法名");获取当前方法。
  8. mInfo.Invoke(null,方法参数)。

11、Unity3D是否支持写成多线程程序?如果支持的话需要注意什么?

  1. 仅能从主线程中访问Unity3D的组件,对象和Unity3D系统调用
  2. 支持:如果同时你要处理很多事情或者与Unity的对象互动小可以用thread,否则使用coroutine。
  3. 注意:C#中有lock这个关键字,以确保只有一个线程可以在特定时间内访问特定的对象。

12、Unity3D的协程和C#线程之间的区别是什么?

  1. 多线程程序同时运行多个线程 ,而在任一指定时刻只有一个协程在运行,并且这个正在运行的协同程序只在必要时才被挂起。
  2. 除主线程之外的线程无法访问Unity3D的对象、组件、方法。
  3. 在主线程运行时同时开启另一段逻辑处理,来协助当前程序的执行。换句话说,开启协程就是开启一个线程。可以用来控制运动、序列以及对象的行为。

13、U3D中用于记录节点空间几何信息的组件名称,及其父类名称?

U3D中用于记录节点空间几何信息的组件名称是 Transform ,它的父类是 Component。

14、简述四元数的作用,四元数对欧拉角的优点?

四元数用于表示旋转。
相对欧拉角的优点:

  1. 能进行增量旋转。
  2. 避免万向锁。
  3. 给定方位的表达方式有两种,互为负(欧拉角有无数种表达方式)。

17.向量的点乘、叉乘以及归一化的意义?

  1. 点乘描述了两个向量的相似程度,结果越大两向量越相似,还可表示投影
  2. 叉乘得到的向量垂直于原来的两个向量
  3. 标准化向量:用在只关系方向,不关心大小的时候

18、在场景中放置多个Camera并同时处于活动状态会发生什么?

实际看到的画面由多个camera的画面组成;由depth、Clear Flag、Culling Mask都会影响最终合成效果。

19、Prefab的作用?如何在移动环境的设备下恰当地使用它?

在游戏运行时实例化,prefab相当于一个模版,对你已有的素材、脚本、参数做一个默认配置,以便于以后修改,同时prefab打包的内容简化了导出的操作,便于团队的交流。

20、如何安全的在不同工程间安全地迁移asset数据?

  1. 将Assets目录和Library目录一起迁移。
  2. 导出包。
  3. 用unity自带的assets Server功能。

21、MeshRender中material和sharedmaterial的区别?

修改sharedMaterial将改变所有物体使用这个材质的外观,并且也改变储存在工程里的材质设置。不推荐修改由sharedMaterial返回的材质。如果你想修改渲染器的材质,使用material替代。

22、请描述游戏动画有哪几种,以及其原理?

关节动画:把角色分成若干独立部分,一个部分对应一个网格模型,部分的动画连接成一个整体的动画,角色比较灵活Quake2中使用了这种动画。

单一网络模型动画:由一个完整的网格模型构成,在动画序列的关键帧里记录各个顶点的原位置及其改变量,然后插值运算实现动画效果,角色动画较真实。

骨骼动画:广泛应用的动画方式,集成了以上两个方式的优点,骨骼按角色特点组成一定的层次结构,由关节相连,可做相对运动,皮肤作为单一网格蒙在骨骼之外,决定角色的外观。皮肤网格每一个顶点都会受到骨骼的影响,从而实现完美的动画。(骨骼动画是由关节动画发展而来的,如今基本都使用骨骼动画来实现角色动画)。

23、alpha blend 工作原理?

实际显示颜色 = 前景颜色*Alpha/255 + 背景颜色*(255-Alpha)/255。

24、lod是什么?优缺点是什么?

LOD技术即Levels of Detail的简称,意为多细节层次。

LOD技术指根据物体模型的节点在显示环境中所处的位置和重要度,决定物体渲染的资源分配,降低非重要物体的面数和细节度,从而获得高效率的渲染运算。

优点:可根据距离动态地选择渲染不同细节的模型

缺点:加重美工的负担,要准备不同细节的同一模型,同样的会稍微增加游戏的容量。

25、MipMap是什么?作用?

在三维计算机图形的贴图渲染中有一个常用的技术被称为Mipmapping。为了加快渲染速度和减少图像锯齿,贴图被处理成由一系列被预先计算和优化过的图片组成的文件,这样的贴图被称为 MIP map 或者 mipmap。

26、u3d中碰撞器和触发器的区别?

collider碰撞器会有碰撞的效果,IsTrigger = false,可以调用OnCollisionEnter/Stay/Exit函数。

trigger触发器没有碰撞效果,isTrigger = true,可以调用OnTriggerEnter/stay/exit函数。

27、物体发生碰撞的必要条件?

物体A必须带有(collider+rigidbody)或者CharacterController,另一个物体也必须至少带有collider。

28、什么叫做链条关节?

Hinge Joint ,他可以模拟两个物体间用一根链条连接在一起的情况,能保持两个物体在一个固定距离内部相互移动而不产生作用力,但是达到固定距离后就会产生拉力。(简单说就是弹簧)

29、物体自旋转使用的函数叫什么?绕某点旋转使用函数叫什么?

 transform.Rotate和   transform.RotateAround

30、u3d提供了一个用于保存读取数据的类,(playerPrefs),请列出保存读取整形数据的函数?

PlayerPrefs.SetInt ()与 PlayerPrefs.GetInt()。

31、unity3d提供了几种光源,分别是什么?

  1. 平行光:Directional Light;
  2. 聚光灯:Spot Light;
  3. 点光源:Point Light;
  4. 区域光源:Area Light(只用于烘培)

32、unity3d从唤醒到销毁有一段生命周期,请列出系统自己调用的几个重要方法。

Awake –>OnEnable –> Start  –> Update –> FixedUpdate –> LateUpdate –> OnDisable –> OnDestroy;

FixedUpdate,每固定帧绘制时执行一次,和update不同的是FixedUpdate是渲染帧执行,如果你的渲染效率低下的时候FixedUpdate调用次数就会跟着下降。

FixedUpdate比较适用于物理引擎的计算,因为是跟每帧渲染有关。

Update就比较适合做控制。

33、移动相机动作在哪个函数里,为什么在这个函数里。

LateUpdate,,是在所有update结束后才调,比较适合用于命令脚本的执行。官网上例子是摄像机的跟随,都是在所有update操作完才跟进摄像机,不然就有可能出现摄像机已经推进了,但是视角里还未有角色的空帧出现。

34、什么是渲染管道?

是指在显示器上为了显示出图像而经过的一系列必要操作。 渲染管道中的很多步骤,都要将几何物体从一个坐标系中变换到另一个坐标系中去。

主要步骤有:

本地坐标->视图坐标->背面裁剪->光照->裁剪->投影->视图变换->光栅化。

35、如何优化内存?

  1. 压缩自带类库;(只用到一个简单方法就可以自己写而不用using)。
  2. 将暂时不用的以后还需要使用的物体隐藏起来而不是直接Destroy掉。
  3. 释放AssetBundle占用的资源。
  4. 降低模型的片面数,降低模型的骨骼数量,降低贴图的大小。
  5. 使用光照贴图,使用多层次细节(LOD),使用着色器(Shader),使用预设(Prefab)。

36、C# 的Lambda表达式怎么写?

 表达式形式:(Input Param)=>Expression。在表达式左侧的表示输入参数,右侧的为相应的运算语句或者判断语句等,可包含函数调用等复杂方式。运算符=>读作为goes to,例如下面这个表达t=>t.ClassCode='1001',多做goes to ClassCode equal 1001。

       在上述的表达式中,仅仅只有当参数只有一个的时候,括号是可选择的,例如下面这种含有两个参数时候的情况应该是这样子的写法:(a,b)=>a==b

  当表达式中的多个参数编译器无法自动判断类型的时候,则需要显式指定类型。

(int firstIndex, string str) => str.IndexOf('Hello') > firstIndex

37、数列1,1,2,3,5,8,13...第n位数是多少?用C#递归算法实现

private void Start()
    {
        print(FunTest(4));
    }
    public int FunTest(int num)
    {
        if (num <= 0)
        {
            return 0;
        }
        else if (num == 1 || num == 2)
        {
            return 1;
        }
        else
        {
            return FunTest(num - 1) + FunTest(num - 2);
        }
    }

38、unity的mathf?

Mathf.Abs绝对值

计算并返回指定参数 f 绝对值。

Mathf.Acos反余弦

static function Acos (f : float) : float 以弧度为单位计算并返回参数 f 中指定的数字的反余弦值。

Mathf.Clamp01限制0~1

static function Clamp01 (value : float) :float 限制value在0,1之间并返回value。如果value小于0,返回0。如果value大于1,返回1,否则返回value 。

Mathf.Clamp限制

static function Clamp (value : float, min :float, max : float) : float 限制value的值在min和max之间, 如果value小于min,返回min。 如果value大于max,返回max,否则返回value static function Clamp (value : int, min :int, max : int) : int 限制value的值在min和max之间,并返回value。

Mathf.Deg2Rad度转弧度

static var Deg2Rad : float 度到弧度的转化常量。(只读) 这等于(PI * 2) / 360。

Mathf.Mathf.Rad2Deg 弧度转度

static var Rad2Deg : float 弧度到度的转化常量。(只读) 这等于 360 / (PI * 2)。

Mathf.Infinity正无穷

static var Infinity : float 表示正无穷,也就是无穷大,∞ (只读)

Mathf.Lerp插值
static function Lerp (from : float, to :float, t : float) : float 基于浮点数t返回a到b之间的插值,t限制在0~1之间。 当t = 0返回from,当t = 1 返回to。当t = 0.5 返回from和to的平均值。

Mathf.MoveTowards移向
static function MoveTowards (current :float, target : float, maxDelta : float) : float 改变一个当前值向目标值靠近。 这实际上和 Mathf.Lerp相同,而是该函数将确保我们的速度不会超过maxDelta。maxDelta为负值将目标从推离。

Mathf.RoundToInt四舍五入到整数
static function RoundToInt (f : float) :int 返回 f 指定的值四舍五入到最近的整数。 如果数字末尾是.5,因此它是在两个整数中间,不管是偶数或是奇数,将返回偶数。

Mathf.Round四舍五入

static function Round (f : float) : float 返回浮点数 f 进行四舍五入最接近的整数。 如果数字末尾是.5,因此它是在两个整数中间,不管是偶数或是奇数,将返回偶数。

Mathf.Sqrt平方根

static function Sqrt (f : float) : float 计算并返回 f 的平方根。

39、结构体和类有何区别?

结构体是一种值类型,而类是引用类型。

(值类型、引用类型是根据数据存储的角度来分的)就是值类型用于存储数据的值,引用类型用于存储对实际数据的引用。那么结构体就是当成值来使用的,类则通过引用来对实际数据操作。

40、ref参数和out参数是什么?有什么区别?

相同点:refout参数的效果一样,都是通过关键字找到定义在主函数里面的变量的内存地址,并通过方法体内的语法改变它的小。

不同点:就是输出参数必须对参数进行初始化。ref必须初始化,out 参数必须在函数里赋值。

ref参数是引用,out参数为输出参数。

41、C#的委托是什么?有何用处?

委托类似于一种安全的指针引用,在使用它时是当做类来看待而不是一个方法,相当于对一组方法的列表的引用。

用处:使用委托使程序员可以将方法引用封装在委托对象内。然后可以将该委托对象传递给可调用所引用方法的代码,而不必在编译时知道将调用哪个方法。

CC++中的函数指针不同,委托是面向对象,而且是类型安全的。

42、Unity中,照相机的Clipping Planes的作用是什么?调整NearFar两个值时,应该注意什么?

Unity中,照相机的Clipping Planes的作用是什么剪裁平面

Near和Far是从相机到开始渲染和停止渲染之间的距离。

43、HeapStack有何区别?

  1. heap是堆,stack是栈。

  2. stack的空间由操作系统自动分配和释放,heap的空间是手动申请和释放的,heap常用new关键字来分配。

  3. stack空间有限,heap的空间是很大的自由区。

44、什么是里氏代换元则?

里氏替换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。

通俗点:就是子类对象可以赋值给基类对象,基类对象不能赋值给子类对象。(可以说猪是动物但不能说动物是猪)

45、概述序列化:

序列化简单理解成把对象转换为容易传输的格式的过程。

比如:可以序列化一个对象,然后使用HTTP通过Internet在客户端和服务器端之间传输该对象。

46、堆和栈的区别?

栈通常保存着我们代码执行的步骤,如在代码段1 AddFive()方法,int pValue变量,int result变量等等。

而堆上存放的则多是对象,数据等。我们可以把栈想象成一个接着一个叠放在一起的盒子。当我们使用的时候,每次从最顶部取走一个盒子。

栈也是如此,当一个方法(或类型)被调用完成的时候,就从栈顶取走,接着下一个。堆则不然,像是一个仓库,储存着我们使用的各种对象等信息,跟栈不同的是他们被调用完毕不会立即被清理掉。

47、客户端与服务器交互方式有几种?

socket通常也称作套接字”,实现服务器和客户端之间的物理连接,并进行数据传输,主要有UDPTCP两个协议。Socket处于网络协议的传输层。

http协议传输的主要有http协议 和基于http协议的Soap协议(web service,常见的方式是 http post get 请求,web 服务。

48、unity在移动设备上的一些优化资源的方法?

  1. 使用assetbundle,实现资源分离和共享,将内存控制到200m之内,同时也可以实现资源的在线更新。
  2. 顶点数对渲染无论是cpu还是gpu都是压力最大的贡献者,降低顶点数到8万以下,fps稳定到了30帧左右。
  3. 只使用一盏动态光,不是用阴影,不使用光照探头,粒子系统是cpu上的大头。
  4. 剪裁粒子系统。合并同时出现的粒子系统。自己实现轻量级的粒子系统。
  5. 把不需要跟骨骼动画和动作过渡的地方全部使用animation,控制骨骼数量在30根以下。
  6. animator出视野不更新,animator也是一个效率奇差的地方,删除无意义的animator。animator的初始化很耗时(粒子上能不能尽量不用animator)。
  7. 除主角外都不要跟骨骼运动apply root motion。
  8. 绝对禁止掉那些不带刚体带包围盒的物体(static collider )运动。
  9. NUGI的代码效率很差,基本上runtime的时候对cpu的贡献和render不相上下。
  10. 每帧递归的计算finalalpha改为只有初始化和变动时计算。
  11. 去掉法线计算。
  12. 不要每帧计算viewsize windowsize。
  13. filldrawcall时构建顶点缓存使用array.copy。
  14. 代码剪裁:使用strip level ,使用.net2.0 subset。
  15. 尽量减少smooth group。
  16. 给美术定一个严格的经过科学验证的美术标准,并在U3D里面配以相应的检查工具。

49、将图片的TextureType选项分别选为““Texture”“Sprite”有什么区别?

Sprite作为UI精灵使用,Texture作用模型贴图使用。Sprite需要2的整次幂,打包图片省资源。

50、什么是DrawCallDrawCall高了又什么影响?如何降低DrawCall

Unity中,每次引擎准备数据并通知GPU的过程称为一次Draw CallDrawCall越高对显卡的消耗就越大。

降低DrawCall的方法:

1. Dynamic Batching

2. Static Batching

3. 高级特性Shader降级为统一的低级特性的Shader

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值