jquave 发表于 2022-1-24 05:07

Unity面试题与基础

本篇统计一些网上的面试题然后简单分析一下可行性,属于Unity初级水平篇。
如有描述错误,欢迎大家纠正。
注意:不要大量用这些题去考核中高级程序。他们可能真的记不住,这样考他们反而起反作用(你觉得他不行,他觉得你是SB)。
<hr/>有效题目

关键字

Sealed的作用
有效原因:考察基本用法。

[*]在类前声明,可防止其他类继承。
[*]在方法前声明,可防止派生类重写。
作用域
有效原因:考察基本用法。

[*]pubilc:公开
[*]private:私有(默认)
[*]protected:私有 + 派生类公开(一般抽象继承后使用)
[*]internal:同一程序集(Assembly)内公开
参数前缀:ref和out
有效原因:考察基本用法。

[*]ref:在函数外初始化,在函数内改变值
[*]out:(不能在函数外初始化),在函数内初始化
virtual
有效原因:考察C#基本用法。将方法标记为:可重写。一般在继承后使用。
<hr/>基础结构

数组和List两者的主要区别?
有效原因:考察基本用法。两者处理大量数据效率差不多。

[*]数组:固定长度
[*]List:可变长度
序列化是什么?
有效原因:基本储存概念。将对象的状态信息转换为可以存储或传输的形式的过程,一般用于:储存数据,数据传输。
Prefab是什么,有什么用?
有效原因:这是一道很好的题,但答得好的人不多。

[*]Prefab正如其名:预制体,是个模板文件,它将多个通用对象封装成了一个独立对象。
[*]Prefab对于资源管理(场景、人物)非常重要,是一键修改的必备工具。
[*]Prefab使用需要注意,如果Prefab在场景上修改了,即使你改了资源文件夹内的Prefab,它也不会改变。(需要在场景上手动还原此Prefab)。
[*]Prefab避免了多人修改场景,导致的资源冲突问题。
Unity资源是否可以用中文命名?
有效原因:考察对Unity的理解是否深入。可以,不影响程序使用(特别是服务器传输、AB包索引)就行。
Unity有几种Animation,区别?
有效原因:考察对Unity的理解是否深入。两种。

[*]inspector,Debug模式下,勾选 legacy ->旧版:可以直接挂,使用自动播放。
[*]inspector,Debug模式下,不勾选 legacy ->新版:只能配合Anivator用。
<hr/>API

什么是Unity协程(协同程序)?和C#线程之间的区别是什么?
有效原因:基本概念,知道这个也能在书写代码时,有效避免GC。从 各种点 理解Unity中的协程 - 汪文魁的文章 - 知乎
Unity协程有很多种描述,简单描述:将一段代码延迟一段时间后再去执行。

[*]但由于协程基于unity生命周期,本质是迭代器,大量开启协程有GC,不建议使用(建议自己写个定时器)。
[*]协程一般仅用于资源加载。
[*]协程不是多线程,也不是异步。它在LateUpdate中每帧执行。
先使用Invoke方法,然后Enable = false脚本,Invoke会怎么样?
有效原因:委托题。考察对Unity的理解是否深入。Invoke仍在运行(使用的委托)。
Unity中要用"#dedbbd"这种颜色,怎么转换?
有效原因:考察用过Unity没。ColorUtility.TryParseHtmlString("#dedbdb", out dropColor);
物体发生碰撞的必要条件(粒子除外)
有效原因:考察用过Unity没。
[*]两个物体都有碰撞器(Collider)
[*]主动体有刚体(Rigidbody)
[*]IsTrigger = false
Unity函数生命周期
有效原因:考察用过Unity没。Awake->OnEnable->Start->Update->FixUpdate->LateUpdate->OnDisable->OnDestroy
射线检测,只想点击UI,不想点击到UI物体背后的3D物体怎么办?
有效原因:实用。

[*]EventSystem.current.IsPointerOverGameObject() == true -> 点到了UI上
[*]EventSystem.current.IsPointerOverGameObject() == false -> 点到了3D物体上
<hr/>算法类

菲波纳契数列1,1,2,3,5,8,求第N位数。(递归实现)
有效原因:考察基础递归。注意不止下面一种方法,主要考察递归。    void Start()
    {
      Debug.Log(Func(3));
    }

    int Func(int num)
    {
      if (num <= 0)//陷阱1
            return 0;
      else if (num == 1 || num == 2)//陷阱2
            return 1;
      else
            return Func(num - 1) + Func(num - 2);
    }<hr/>优化类

简述GC产生的原因,并描述如何避免?
有效原因:知道这个能在书写代码时,有效避免GC。产生原因:一般,new 对象时,当可分配的内存不足时,就会GC去回收未使用的对象。(只知道New就行)
Unity游戏开发 - CPU优化篇

[*]少用协程(开启一个协程,至少分配37B的内存,实例(21B),Enumerator(16B))
[*]避免运行时New
[*]避免字符串+连接:建议使用stringBuilder或String.Format
[*]少用obj.name(39B)/obj.tag:都会返回新的字符串
[*]集合Clear代替 New集合
[*]使用缓存思想:对象池、公用对象
[*]避免装箱
[*]用List代替ArrayList
[*]unity5.5(2017)以下版本,避免Foreach(会把代码转成IL,有装箱操作)
[*]谨慎在项目中使用不知细节的插件
<hr/>无效题目

我建议不要用这些题考核初级程序,作用不大。但是鉴于还是有好多公司用这些题筛选人,还是尝试解释下。
关键字

委托:Action、Delegate
无效原因:对初学者要求太高。

[*]委托是类型安全的指针引用(与C++不同)
[*]委托可以把方法封装到委托对象内,然后委托对象传递给需要使用的地方(不必在编译时知道将调用哪个方法)
<hr/>基础结构

值类型和引用类型区别
无效原因:只能考验面试者背诵能力。实际上大部分编程都只会用到Class。值类型(Struct)引用类型(Class)内存栈内存堆存取快(因为在栈中)存取慢(相对来说)表示:实际值表示:内存堆中的指针和引用内存自动释放内存GC释放基类:System.ValueType - 隐式继承:System.Object基类:System.Object
接口和抽象类的区别
无效原因:只能考验面试者背诵能力。这2个东西很有用,但我从未见过初学者正确写出来过。
甚至网上描述的这2个东西都有点糊弄人,比如:接口是一个行为规范,这种描述,知其然不知其所以然。

[*]接口:实际用于分类(一类行为),便于识别(有这类行为的Class)。
[*]抽象类:实际用于极有可能有派生类(继承)的情况,它抽出了共性。
【相同点】

[*]都可以被继承
[*]都不能被实例化
[*]都可以含方法声明(但前缀不同)
[*]派生类都需要实现未实现的方法(抽象类:抽象方法;接口:定义的方法)
【区别】
接口抽象类不能定义属性,不能实现方法可定义属性,可实现方法多继承单继承反射的实现原理
无效原因:对初学者要求太高。反射由于性能问题,一般只用于编辑器或者导表(或生成代码)。反射:在了解程序集和类名的前提下,通过程序集和类名(获得属性)、方法名调用方法。
<hr/>API

Unity是否支持写多线程程序?如果支持的话需要注意什么?
无效原因:对初学者要求太高。一般ECS、战斗等需求才会考虑多线程。游戏编程一般单线程更容易理清逻辑,多线程容易出现死锁,脏数据等行为。

[*]Unity只能从主线程访问Unity对象(或者说:和Unity相关的功能都只能在主线程完成)。
[*]但与Unity无关的,如:数据计算等行为可以用线程去做。
[*]注意:C# lock关键字(用于同步),保证一个线程在特定时间内访问特定的对象。
主摄像机只显示第x层,y层,怎么写?
无效原因:只能考验面试者背诵能力,我也经常记不住。

[*]camera.cullingMask = (1 << x) + (1 << y) + (1 << z); // 摄像机只显示第x层,y层,z层.
[*]camera.cullingMask = ~(1 << x);// 渲染除了某x层外的所有层
[*]camera.cullingMask &= ~(1 << x); // 关闭(减掉)x层
[*]camera.cullingMask |= (1 << x);// 打开(增加)x层
[*]camera.cullingMask = -1; // 渲染所有层(everything)
[*]camera.cullingMask = 0; // 任何层都不渲染(nothing)
<hr/>数学

什么是四元数,有什么用?什么是欧拉角,四元数相对欧拉角有什么好处?
无效原因:这是我目前见过最离谱的问题,只能考验面试者背诵能力。四元数很难理解,理解会了也不一定能用到。唯一有用的就是避免万向锁,万向锁也不是那么好遇到的。四元数是超复数,一般可表示为a + bi+ cj + dk,其中a、b、c 、d是实数。在Unity中用于描述旋转。
欧拉角是用来唯一确定:定点转动刚体位置的三个一组独立角参量。
【四元数相对欧拉角有什么好处】

[*]能进行增量旋转(不知道啥意思,求大佬解释)
[*]避免万向锁
[*]给定方位,四元数只有2种表达方式,且互为负(欧拉角有无数种)
向量的点乘、叉乘、归一化的意义
无效原因:只能考验面试者背诵能力。过段时间就还给数学老师了,很难用到。

[*]归一化的意义:得到单位矢量,一般用于:计算方向。
[*]点乘的意义:描述2个向量相似程度,结果越大越相似,一般用于:投影。
[*]叉乘的意义:叉乘得到的向量垂直于原来的两个向量,一般用于:光学计算。
如何确定2个平面相交?
无效原因:对初学者要求太高。这是切片机才可能遇到的问题。分为平面长宽有限和无限的情况。
[*]如果两平面长宽无限
假设平面方程:

https://www.zhihu.com/equation?tex=%5Cfrac%7Bx%7D%7B%5Csqrt%7B2%7D%7D%2B%5Cfrac%7By%7D%7B3%7D%2B%5Cfrac%7Bz%7D%7B2%7D%3D1
从而法向量(垂直于平面的向量):(另外:2个平面内向量也可确定法向量)

https://www.zhihu.com/equation?tex=%7B%5Cbold+n%7D%3D%28%5Cfrac%7B1%7D%7B%5Csqrt%7B2%7D%7D%2C%5Cfrac%7B1%7D%7B3%7D%2C%5Cfrac%7B1%7D%7B2%7D%29

[*]两平面法向量点乘等于0,两法向量垂直
[*]两平面法向量叉乘等于0(或法向量1=λ法向量2,有倍率关系),两法向量平行
[*]若两法向量既不平行也不垂直,那么就说明两平面相交
【法向量乘积】

[*]假设向量a=(a1,b1,c1),向量b=(a2,b2,c2)
[*]点乘(值):向量a·向量b=a1a2+b1b2+c1c2
[*]叉乘(向量):向量a×向量b=(b1c2-b2c1,c1a2-a1c2,a1b2-a2b1)
2. 如果两平面有长宽
……(后续补上,有点麻烦)
<hr/>渲染类

Alpha Blend原理
无效原因:只能考验面试者背诵能力。这是道美术题,而且涉及(特效类)Shader。AlphaBlend:目标(当前)像素颜色值与源(已有)像素的颜色值的组合方式的控制命令。
最终的颜色 = (目标颜色*SrcFactor) + (源颜色*DstFactor)
什么是渲染管线,流程?
无效原因:只能考验面试者背诵能力,初学者并不建议直接开始Shader之旅,也学不会。渲染管线(也称为渲染流水线),是显示芯片内部处理图形信号相互独立的的并行处理单元。

[*]应用阶段(由CPU负责,输出是渲染所需要的几何信息)
[*]几何阶段(由GPU负责,处理渲染图元,这阶段中最重要的就是把顶点坐标变换屏幕空间中,交给光栅器处理,这阶段输出的是屏幕空间中二维顶点坐标、每个顶点对应的深度值、着色等相关信息)
[*]光栅化阶段(由GPU,负责这一阶段会使用上个阶段传递的数据来产生屏幕上的像素,并渲染出最终的图像)
<hr/>优化类

描述你知道的优化方案
无效原因:问题本身就有问题,这坨内容量很大,而且涉及大量细节,你要和面试者聊一天么?建议还是有重点地询问优化方案。
LOD、MipMap等优化方案
无效原因:这些优化都是有使用场景和条件的,初学者根本遇不到,最多也就了解,问来干什么?
页: [1]
查看完整版本: Unity面试题与基础