unity面试题

https://blog.csdn.net/qq_25601345/article/details/77102775#_Toc449099547

第一天


1.摄像机camera 中skybox、solid color、depth only、don’t Clear的区别

Clear Flags:
每帧绘制完后,都需要清空各种缓冲区,最主要的是color和depth,一个负责画面最终呈现的颜色,一个负责景深。重要的是,在当前Camera范围内color和depth会有被覆盖的可能性。在范围外的color和depth有被其它Camera使用的可能性。这里的清除很多时候是为了处理,在当前Camera范围外的区域。
Skybox, 可以理解为Camera范围外的区域,使用SkyBox来填充。
Solid color,可以理解为Camera范围外的区域,使用一个纯色来填充。
Depth only,可以理解为Camera范围外的区域,只清空depth,而不清除color。这就保留了其它Camera范围绘制的画面,但丢失了所有景深信息。这就是为什么,当一个Camera选择Depth only的时候,其它Camera的渲染画面可以保留。没有了景深,多个Camera之间的渲染层级就依赖Camera的Depth来设置。
Don’t clear, 就是不清除color和depth,每次绘制都会叠加在一起。

2.什么是观察者模式

观察者(Observer)模式又名发布-订阅(Publish/Subscribe)模式。GOF(设计模式的四个作者)给观察者模式如下定义:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
TencentNews 发布者—新闻信息的发布者
QQ用户 订阅者 — 接收发布者发布的新闻消息
微信用户 订阅者 — 接收发布者发布的新闻消息

3.谈谈什么是工厂模式

工厂模式(Factory Pattern)属于创建型模式,它提供了一种创建对象的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,而是通过使用一个共同的接口来指向新创建的对象。
工厂模式 | 菜鸟教程
http://www.runoob.com/design-pattern/factory-pattern.html
Car 基类(总生产厂根据4S店生产制定类型的车)–>4S店(根据用户的要求向厂家订车)—>用户
宝马 子类
兰博基尼 子类

4.重写和重载的区别

1、重写需要使用关键字override或new声明,而重载不需要使用关键字
2、重写发生在具有继承关系的派生类中,而重载发生在同一个类中
3、重写有覆盖隐藏的作用,而重载是扩展的作用
4、重写的函数必须要和原函数同名,且具有相同的函数(函数签名:函数),而重载则要求函数名称相同,参数列表不同,对函数分返回值没有要求
5、重写要求子类的重写函数不能比父类的访问权限小,而重载则对访问权限没有要求
6、重写和重载都是多态的表现方式,区别在于重写是动态的(运行时的多态),重载是静态的(编译时的多态)

5.事件和委托的区别

1、委托是一个类,可以实例化,可通过构造函数将方法作为参数传递给委托实例,而委托与事件的关系是:委托是事件的类型,事件是委托类型的对象
2、委托使用delegate定义,事件使用event定义
3、订阅方式不同,委托可使用+=,-=,=绑定和注销方法,事件使用+=,-=订阅和取消订阅方法(在事件定义的类中,可以使用=,在类外必须使用+=,-=)
4、触发方式不同,委托的触发有两种方式:委托对象.Invoke(参数列表),或委托对象(参数列表),事件的触发:事件对象(参数列表)
5、事件的触发必须在事件的定义类中执行
6、委托还有两种使用方式:Fanc<>和Action<>,两者的不同之处在于Action定义的委托是可以有参数但不具有返回值的委托类型,而Fanc定义的是可以有参数但必须具有返回值的委托类型


第二天


1.解释一下什么是面向对象和面向过程?

面向对象:以类为基础,所有功能在类中定义和实现,使用时通过对象调用,相对于面向过程来说,面向对象功能更加强大,也相对复杂。
面向过程:以方法为基础,把功能代码封装在函数进行调用。

2.使用字符串需要注意哪些问题?

String是字符串常量,是不可变的对象,当每次对String进行改变时都需要生成一个新的String对象,存储新的值,所以效率很低,建议在不断更改String对象的地方不要使用String类型。此时可使用StringBuilder,StringBuilder对象在做字符串连接操作时是在原来的字符串上进行修改。

3.正交摄像机和透视摄像机的区别,第一人称摄像机Fov变化会产生怎样的摄像机效果

摄像机的模式不同,渲染出来的画面也不同,正交模式渲染2d平面,制作UI时使用,透视模式可以渲染3d物体,会根据对象和摄像机的距离,产生远小近大的效果,一般在3d世界中使用。
Fov可调节摄像机的视口效果,改变Fov的值会影响摄像机渲染的物体的大小

4.给定屏幕一个点(x,y)如何进行对场景中的GameObject进行射线拾取

碰撞检测,RPG类型游戏捡装备,3D拾取技术,原理是当玩家用手指单击屏幕时生成一条由屏幕发射到游戏世界的射线,起点就是玩家手指触摸的地方。
需要把屏幕坐标转换成世界坐标进行射线检测
代码:Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

5.一个Terrain,分别贴3张,4张,5张地表贴图,渲染速度有什么区别吗?为什么

没有区别,因为不管几张贴图只渲染一次。


第三天


1.单例模式

一个类全局仅有一个实例,并提供一个访问它的全局访问点。
构造方法私有化啊,防止在外部new对象
提供一个全局访问点,保证只有一个实例
判断系统是否已经有这个单例,如果有则返回,如果没有则创建。
注意事项:getInstance() 方法中需要使用同步锁防止多线程同时进入造成 instance 被多次实例化。

2.快速排序

using System;

namespace 面试题
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] arr = { 32, 23, 12, 8, 9, 13, 22 };
            QuickSort(arr, 0, arr.Length - 1);

            foreach (int item in arr)
            {
                Console.Write(item + " ");
            }
        }

        static void QuickSort(int[] arr, int left, int right)
        {
            int mid = QuickSortUnit(arr, left, right);
            if (left < mid - 1)
            {
                QuickSort(arr, left, mid - 1);
            }
            if (mid + 1 < right)
            {
                QuickSort(arr, mid + 1, right);
            }
        }

        static int QuickSortUnit(int[] arr, int left, int right)
        {
            int temp = arr[left];

            while (left < right)
            {
                while (left < right && arr[right] >= temp)
                {
                    right--;
                }
                arr[left] = arr[right];
                while (left < right && arr[left] < temp)
                {
                    left++;
                }
                arr[right] = arr[left];
            }
            arr[left] = temp;

            return left;
        }
    }
}

3.
0000a0000
000a0a000
00a0a0a00
0a0a0a0a0
a0a0a0a0a
0a0a0a0a0
00a0a0a00
000a0a000
0000a0000
递归实现:求每一层的菱形,进行平移

using System;

namespace 面试题
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = 9;
            bool[,] rect = new bool[9, 9];
            SetStart(rect, n, 0);
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    if (rect[i, j])
                    {
                        Console.Write("*");
                    }
                    else
                    {
                        Console.Write(" ");
                    }
                }
                Console.WriteLine();
            }

        }

        static void SetStart(bool[,] rect, int n, int offset)
        {
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    if (i + j == n / 2 || i + j == n + n / 2 - 1 || i - j == -n / 2 || i - j == n / 2)
                    {
                        rect[i + offset, j + offset] = true;
                    }
                }
            }
            n -= 4;
            offset += 2;
            if (n > 0)
            {
                SetStart(rect, n, offset);
            }
        }
    }
}

数学线性规划写法:用方程表示菱形区域的范围

using System;

namespace 面试题
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = 9;
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    if (((i + j - n / 2) % 2 == 0) && i + j >= n / 2 && i + j <= n + n / 2 - 1 && i - j >= -n / 2 && i - j <= n / 2)
                    {
                        Console.Write("*");
                    }
                    else
                    {
                        Console.Write(" ");
                    }
                }
                Console.WriteLine();
            }
        }
    }
}

4.什么是DrawCall 博友解释

在Unity中,每次引擎准备数据并通知GPU的过程称为一次Draw Call。
这一过程是逐个物体进行的,对于每个物体,不止GPU的渲染,引擎重新设置材质/Shader也是一项非常耗时的操作。
因此每帧的Draw Call次数是一项非常重要的性能指标,对于iOS来说应尽量控制在20次以内,这个值可以在编辑器的Statistic窗口看到。

另一种解释:drawcall是CPU对底层图形绘制接口的调用命令GPU执行渲染操作,渲染流程采用流水线实现,CPU和GPU并行工作,它们之间通过命令缓冲区连接,CPU向其中发送渲染命令,GPU接收并执行对应的渲染命令。

5.二叉树前序列

前序遍历:根结点 —> 左子树 —> 右子树

public void preOrderTraverse1(TreeNode root) {  
    if (root != null) {  
        System.out.print(root.val+"  ");  
        preOrderTraverse1(root.left);  
        preOrderTraverse1(root.right);  
    }  
}  

第四天


1.unity shader 分哪几种,有什么区别?
2.unity3D物理引擎中,有几种施加力的方式,分别描述出来?
3.四元数有什么作用?
4.进程和线程的区别?
5.什么是协程?


第五天


1.点乘Dot;

点乘:A.Dot(B) 用于判断A和B所形成的角度 灯光渲染问题,可以根据点乘计算光照效果,点积越大,表示夹角越小,光照强度更大。

2.叉乘Cross;

叉乘:A.Cross(B)用于判断A位于B的哪个方向 如在RPG游戏中,可以判断一个其他的游戏角色在你英雄的哪个方向。

3.什么是GC?

GC(Garbage
Collector)是垃圾回收机制,会遍历应用程序在Heap上动态分配的所有对象[2],通过识别它们是否被引用来确定哪些对象是不需要使用、哪些仍需要被使用,并释放不需要的空间。GC不能自动释放非托管资源。

4.基本数据类型所占字节数,其默认值?

5.int 的最大值是多少,+1之后会怎么样?

Int 4字节 32位 2^31-1 = 2147483647 +1之后溢出,变为-2147483648


第六天


1.GameObject和Transform和关系

每个GameObject对象身上都有一个Transform组件,Transform组建可调节对象在3D世界中的位置信息,以及控制对象的旋转和缩放,是游戏对象比不可少的组建。

2.如何处理网络延时造成的丢包,粘包,半包问题

解决方案1:在数据包中添加长度的方式,即在数据包中的固定位置封装数据包的长度信息,服务器接收到数据后,先是解析包长度,然后根据包长度截取数据包,但是有个小问题就是如果客户端第一个数据包数据长度封装的有错误,那么很可能就会导致后面接收到的所有数据包都解析出错,需要开发者对接收到的有问题的包进行人为的丢弃处理(客户端有自动重发机制,故而在应用层不会导致数据的不完整性)

解决方案2: 可在数据尾部添加结尾符,标志一个数据包的结束
即我们在封装要传输的数据包的时候,采用固定的符号作为结尾符(数据中不能含结尾符),这样我们接收到数据后,如果出现结尾标识,即人为的将粘包分开,如果一个包中没有出现结尾符,认为出现了分包,则等待下个包中出现后
组合成一个完整的数据包,这种方式适合于文本传输的数据,如采用/r/n之类的分隔符


第七天


1.你用过Soscket通信吗?简单描述一下Socket通信

Socket是网络套接字,包含ip地址和端口号,两个主机之间通过套接字进行连接和传输数据。

2.简述下对象池,你觉得在FPS哪些东西适合使对象池

对象池是指在Unity开发中使用列表的方式存储一组对象,在需要用到时从列表中拿出对象进行使用,不需要该对象时,就将其设置为隐藏状态,这样就可避免重复性的创建和销毁对象,减少了内存消耗,也优化了程序的执行效率。
在FPS游戏中,频繁使用的子弹对象可以放入对象池中进行管理。

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cchoop

有用的话请杯肥宅水

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值