1、进程 | 线程 | 协程 进程:有独立的堆和栈,既不共享堆也不共享栈,由操作系统调度。 线程:有独立的栈和共享的堆,共享堆不共享栈,由操作系统调度。 协程:和线程一样共享堆不共享栈,unity中的协程不是多线程,协程还是在主线程里面(unity中非主线程不可以访问unity资源)。
一个应用程序一般对应一个进程,一个进程一般有一个主线程,若干辅助线程。线程之间是平行的,线程里面可以开启协程,让程序在特定的时间内运行。
协程和线程区别:协程避免了无意义调度,可以提高性能,但是程序必须自己承担调度责任,协程也失去了标准线程使用多cpu的能力。
unity运行时,调用协程就是开启了一个IEnumerator,执行到yield return 之前和其他的正常程序没有差别,遇到yield return之后会立刻返回,并将该函数挂起,在下一帧遇到FixedUpdate或者Update之后判断yield return之后的条件是否满足,如果满足则向下执行。
WaitForSeconds受Time.timeScale影响,当其为0时,yield return new WaitForSeconds()将不会满足。
协程不是只能做简单延迟,其真正作用是分步做一些比较耗时的事情:比如加载游戏里的资源。
2、Unity中的四种坐标系 1)世界坐标系 按照笛卡尔坐标系定义出来的绝对坐标系,是左手坐标系。我们用transform.position获取场景物体的世界坐标,与有没有父物体无关。transform.localPosition获取场景物体基于父物体的位置坐标。
2)屏幕坐标系 屏幕坐标以像素来定义,左下角为(0,0),右上角为(Screen.width, Screen.height)定义的一个矩形。屏幕坐标的Z轴以相机的世界单位来衡量,满足:Screen.width = Camera.pixelWidth和Screen.height = Camera.pixelHeight。UGUI的坐标本质是特殊的屏幕坐标。anchor决定该坐标系的原点,pivot决定元素本身坐标系的远点。anchoredPosition是UI元素的屏幕坐标,对UI进行操作时应该考虑使用这个坐标。
3)视口坐标系 视口坐标是标准化后的屏幕坐标,以0~1之间的数字来表示。范围是左下角为(0,0),右上角为(1,1)定义的一个矩形。其Z轴也是以相机的世界单位来衡量。
4)GUI坐标系 GUI坐标系是一个2D坐标(绝对坐标),是屏幕坐标去除Z轴的结果。
各种坐标系的转换: 屏幕->世界 Camera.ScreenToWorldPoint() 第一人称射击游戏 世界->屏幕 Camera.WorldToScreenPoint() 血条
屏幕->视口 Camera.ScreenToViewportPoint() 视口->屏幕 Camera.ViewportToScreenPoint()
世界->视口 Camera.WorldToViewportPoint() 视口->世界 Camera.ViewportToWorldPoint()
屏幕->GUI RectTransformUtility.ScreenPointToLocalPointInRectangle() 1.Canvas的RenderMode为Overlay时,camera参数要为null; 2.rect必须为直接父物体。
3、单例 一个类能返回一个引用(永远同一个)和一个获取该实例的方法(必须静态),我们将该类的构造函数定义为私有方法避免其他代码通过调用构造函数来实例化该类对象,保证唯一实例。
某个服务器程序的配置信息存放在一个文件中,由一个单例对象统一读取,服务进程的其他对象再通过这个单例对象获取这些配置信息,这种方式简化了在复杂环境下的配置管理。
优:单一实例;提供受控访问;内存中只存在一个对象,节约系统资源;避免对共享资源多重占用。 缺:不适用变化的对象;难扩展;某种程度违背“单一职责原则”;懒汉式在多线程时会创建多个实例(加锁)。
4、反射 审查元数据并收集关于它的类型信息的能力。
- using System.Reflection;
- Assembly.Load(“程序集”);
- 得到程序集中所有类的名称;
- Type type = assembly.GetType("程序集.类名”);
- Activator.CreateInstance(type);
- MethodInfo methodInfo = type.GetMethod(“方法名”);
- methodInfo.Invoke(null, 方法参数);
5、简述四元数Quaternion作用,其相对欧拉角的优点? 四元素用于表示旋转。优点:能进行增量旋转;避免万向锁;给定方位的表达方式有两种,互为负(欧拉角有无数种)
6、如何安全的在不同工程见迁移asset数据? Assets和Library一起迁移;导出package;unity自带的assets server。
7、TCP/IP协议栈各个层次及分别的功能? 网络接口层:最低层,主要完成数据帧的实际发送和接受。 网络层:处理分组在网路中的活动,如路由选择和转发等,主要包括IP、ARP、ICMP协议等。 传输层:主要是提供应用程序之间的通信,如TCP/UDP协议。 应用层:处理特定的应用,如进行文件传输的FTP协议,发送email的SMTP等。
8、GUP的工作原理? 顶点处理:读取3D图形外观顶点数据确定形状及位置关系。支持DX8和DX9的cpu中,由Vertex Shader完成。 光栅化计算:将上面生成的图形上点和线通过一定算法转换到相应像素点。 纹理贴图:顶点单元生成多边形只构成了3D物体轮廓,纹理映射完成对多边形表面的贴图。Texture mapping unit用来完成此项工作。 像素处理:对每个像素光栅化期间,GPU完成对象素的计算和处理,确定每个像素的最终属性。支持DX8和DX9的cpu中,由Pixel Shader完成。 最终输出:由ROP(光栅化引擎)完成像素的输出,一帧渲染完毕后送到显存帧缓冲区。
9、什么是渲染管道? 显示图像经过的一系列必要操作。本地坐标->视图坐标->背面裁剪->光照->裁剪->投影->视图变化->光栅化。
10、C#中四种访问修饰符是哪些?各有什么区别? 答:1.属性修饰符 2.存取修饰符 3.类修饰符 4.成员修饰符。 属性修饰符: Serializable:按值将对象封送到远程服务器。 STATread:是单线程套间的意思,是一种线程模型。 MATAThread:是多线程套间的意思,也是一种线程模型。
存取修饰符: public:存取不受限制。 private:只有包含该成员的类可以存取。 internal:只有当前命名空间可以存取。 protected:只有包含该成员的类以及派生类可以存取。
类修饰符: abstract:抽象类。指示一个类只能作为其它类的基类。 sealed:密封类。指示一个类不能被继承。理所当然,密封类不能同时又是抽象类,因为抽象总是希望被继承的。
成员修饰符: abstract:指示该方法或属性没有实现。 sealed:密封方法。可以防止在派生类中对该方法的override(重载)。不是类的每个成员方法都可以作为密封方法密封方法,必须对基类的虚方法进行重载,提供具体的实现方法。所以,在方法的声明中,sealed修饰符总是和override修饰符同时使用。 delegate:委托。用来定义一个函数指针。C#中的事件驱动是基于delegate + event的。 const:指定该成员的值只读不允许修改。 event:声明一个事件。 extern:指示方法在外部实现。 override:重写。对由基类继承成员的新实现。 readonly:指示一个域只能在声明时以及相同类的内部被赋值。 static:指示一个成员属于类型本身,而不是属于特定的对象。即在定义后可不经实例化,就可使用。 virtual:指示一个方法或存取器的实现可以在继承类中被覆盖。 new:在派生类中隐藏指定的基类成员,从而实现重写的功能。 若要隐藏继承类的成员,请使用相同名称在派生类中声明该成员,并用 new 修饰符修饰它。
11、值类型和引用类型有何区别? 1.值类型的数据存储在内存的栈中;引用类型的数据存储在内存的堆中,而内存单元中只存放堆中对象的地址。 2.值类型存取速度快,引用类型存取速度慢。 3.值类型表示实际数据,引用类型表示指向存储在内存堆中的数据的指针或引用 4.值类型继承自System.ValueType,引用类型继承自System.Object 5.栈的内存分配是自动释放;而堆在.NET中会有GC来释放 6.值类型的变量直接存放实际的数据,而引用类型的变量存放的则是数据的地址,即对象的引用。 7.值类型变量直接把变量的值保存在堆栈中,引用类型的变量把实际数据的地址保存在堆栈中。
|