学习笔记——Unity3D与C#基础总结

1.Draw Call本身的含义就是CPU调用图像编程接口,像OpenGL或者 DirectX。简单来说,Draw Call就是由CPU发起的一个命令,添加到一个命令缓冲区,当GPU完成了上一次的渲染任务之后,会从命令缓冲区的命令队列中再取出一个并执行。CPU每次调用Draw Call之前需要向GPU发送很多内容,包括状态,数据,命令等等。而GPU的渲染能力是很强的,渲染200个网格和2000个网格没什么区别。所以当CPU调用的Draw Call过多时,会造成比较大的性能消耗,命令缓冲区中的命令已经被GPU执行完了,CPU还在准备下一个Draw Call,而GPU处于等待状态,就影响了效率了。

2.渲染流水线中的3个概念阶段:

(1).应用阶段(由开发者设置每个模型的渲染状态,材质,纹理,shader等,输出渲染图元)

(2).几何阶段(绘制图元,如何绘制,在哪里绘制,输出屏幕空间的顶点信息)

(3).光栅化阶段(根据上个阶段传递的数据产生屏幕上的像素,并渲染出最终图像)

3.单例模式:确保一个类只有一个实例,在系统中把这个实例当作一个工具来使用,当需要频繁创建销毁某个对象时,单例模式能提高性能。缺点:(1).不能继承(登记式模式可以被继承),难以拓展。(2).滥用单例模式会提高代码之间的耦合度。

观察者模式是为了定义对象间的一种一对多的依赖关系,以便于当一个对象的状态改变时,其他依赖于它的对象会被自动告知并更新。是一种松耦合的设计模式。

4. 引用类型继承自Systerm.Object类,值类型则是继承Systerm.Object的子类Systerm.ValueType类。值类型的数据存储在内存的栈中;引用类型的数据存储在内存的堆(new 出来的对象)中,在栈中存放数据引用或地址。值类型存取速度快,引用类型存取速度慢。值类型表示实际数据,引用类型表示指向存储在内存堆中的数据的指针或引用

5. 指针其实是一个整型的变量,用来存储其它变量的地址,地址表示数据在内存中的位置

6.string是String类的别名,字符串的本质是一个char数组,string类的内部定义了一个char类型的索引器,所有string可以用[ ]去读取内部的每一个字符,对string对象进行修改时,其实要重新分配内存,创建一个新的string对象,所以当需要频繁修改string的值的时候,会使GC频繁的去回收内存,性能消耗比较大;StringBuilder 实例化时可以指定一个容纳量,当修改的值没有超过容纳量的时候不会重新分配内存.

7.装箱是指将值类型转换为引用类型的过程,首先从托管堆中为新生成的引用对象分配内存,然后将值类型的数据拷贝到刚刚分配的内存中,返回托管堆中新分配对象的地址。拆箱是指引用类型转换为值类型的过程,首先获取托管堆中属于值类型那部分字段的地址,这一步是严格意义上的拆箱,然后将引用对象中的值拷贝到位于线程堆栈上的值类型实例中。

8.序列化是指对象的状态信息转换为可以存储或传输的形式的过程。序列化方式一般有两种,二进制和XML。

9.委托上注册了多个函数后,如果委托和事件有返回值,那么调用委托和事件时,返回的将是最后一个注册函数的返回值 . ActionFunc的本质是委托,系统内部定义的,前者为Void类型不具有返回值,后者具有返回值。(当脚本销毁时一定要释放方法)

10.事件对象的调用只能在声明事件的类的内部调用(安全),在类的外部只能对事件进行” +=”或者” -=”操作,相当于被限制了权限的委托。

11.二分查找

public static int binSearch(int[] array,int start,int end,int key)
{
            int mid = (end - start) / 2 + start;
            if (array[mid] == key) return key;
            if (start >= end) return -1;
            else if (key > array[mid]) return binSearch(array, mid+1, end, key);
            else if (key < array[mid]) return binSearch(array, start, mid-1, key);
            return -1;
}

12.快速排序

public static void QuickSort(int[] array, int start, int end)
        {
            if (start > end) return;    
            int index = Partition(array, start, end);
            QuickSort(array, start, index - 1);
            QuickSort(array, index + 1, end);
        }

        private static int Partition(int[] array, int start, int end)
        {
            int pivot = array[start];
            while (start < end)
            {
                while (start < end && array[end] >= pivot) end--;
                array[start] = array[end];
                while (start < end && array[start] <= pivot) start++;
                array[end] = array[start];
            }
            array[start] = pivot;
            return start;
        }

13.反射可以通过程序集,类型,类型实例获取该程序集内所有类型+属性+属性类型,方法,方法的访问类型,参数和返回值等等

14.Var用于在声明变量时,无法确定数据类型时使用。

(1).必须在定义时初始化

(2).一但初始化完成,就不能再给变量赋与初始化值类型不同的值

(3). 必须是局部变量

15.时间复杂度用于衡量一个算法执行所耗费的时间,空间复杂度用于衡量算法运行过程中临时占用的内存大小

16. GC即垃圾回收,自动管理内存,当我们创建对象时,系统会为对象分配一个内存空间,GC就开始监控这个对象的地址、大小以及使用情况,当对象没有被任何引用指向,或者不再会被用到的时候,GC就把对象当作垃圾回收,释放内存 。但是GC并不是实时性的,GC并不是能释放所有的资源。它不能自动释放非托管资源(正则表达式,数据库连接,定时器)。减少new产生对象的次数 来减少GC。

17.ref 关键字使参数按引用传递。使用 ref 参数,则方法定义和调用方法都必须显式使用 ref 关键字。ref指定的参数在进入方法前必须初始化。out指定的参数在进入函数时会清空自己,必须在函数内部赋初值。如果一个方法采用 ref 参数,而另一个方法采用 out 参数,无法重载这两个方法。

18.数据结构

学习笔记——Unity3D与C#基础总结_第1张图片

哈希表又称散列表,是根据关键码值(Key value)而直接进行访问的数据结构,通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表,值类型。当一个HashTable被占用一大半的时候我们通过计算散列值取得的地址值可能会重复指向同一地址,这就造成哈希冲突。

字典是引用类型,一种变种的哈希表,实现方式与哈希表相同,但是在声明的时候必须指定key和item的类型,它采用一种分离链接散列表的数据结构来解决哈希冲突的问题。

数组是最简单的数据结构. 1.顺序存储,数据存储在连续的内存上。2.数组的内容都是相同类型。3.数组可以直接通过下标访问,故索引时间非常快而且是固定的,与数组大小内容无关。

ArrayList不必在声明ArrayList时指定它的长度, 可以存储不同类型的元素, 不是类型安全的。因为把不同的类型都当做Object来做处理,很有可能会在使用ArrayList时发生类型不匹配的情况。会导致大量拆箱,装箱操作

List内部使用数组来实现,即确保了类型安全,也取消了装箱和拆箱的操作,而且长度可以灵活变化。

链表LinkedList不是连续存储,而是靠各对象的指针所决定,所以向链表中插入删除元素的时候不用调整容量,但是访问某个元素的时候只能从头节点开始遍历。

19.Unity3D 协程是在主线程中执行的,在Update()方法之后,LateUpdate()方法之前调用。Unity在每一帧都会去处理对象上的协程,遇到yield return 语句会挂起,直到条件满足才会被唤醒继续执行后面的代码。使用StartCoroutine和StopCoroutine()方法来开启,结束协程,也可以在启动协程时定义一个Coroutine变量去保存协程,然后调用stop方法去停止协程。

20.Unity3D生命周期表学习笔记——Unity3D与C#基础总结_第2张图片

21.动态语言是在运行时才确定数据类型的语言。变量使用之前不需要类型声明,通常变量的类型是被赋值的那个值的类型。 例如PHP、ASP、Python、JavaScript等等。

静态语言是在编译时变量的数据类型就可确定的语言,多数静态类型语言要求在使用变量之前必须声明数据类型。 例如:C、C++、Golang、Java、C#等,优势:由于类型的强制声明,使得IDE有很强的代码感知能力,所以在实现复杂的业务逻辑、开发大型商业系统、以及那些生命周期很长的应用中,依托IDE对系统的开发很有保障;由于静态语言相对比较封闭,使得第三方开发包对代码的侵害性可以降到最低。

解释型语言是不需要在运行前进行编译成机器语言,而是程序在运行时先翻译成中间代码,再由解释器对中间代码进行解释运行。这样解释型语言每执行一次就要翻译一次,效率比较低。常见的解释型语言包括:Java、C#、PHP、JavaScript、Python、VBScript、Perl、Ruby、MATLAB等;解释型语言的优点:①解释型语言提供了极佳的调试支持;②解释器比编译器容易实现;③中间语言代码的大小比编译型可执行代码小很多。例如,C/C++的.exe文件要比同样功能的Java的.class文件大很多;④可移植性好,只要有解释环境,可以在不同的操作系统上运行。比如在解释执行时可以动态改变变量的类型、对程序进行修改以及在程序中插入良好的调试诊断信息等,而将解释器移植到不同的系统上,则程序不用改动就可以在移植了解释器系统上运行;⑤解释型语言也可以保证高度的安全性——这是互联网应用迫切需要的。解释型语言的缺点:①运行需要解释环境,程序严重依赖平台;②运行起来比编译的要慢,占用的资源也要多一些,代码效率低。因为不仅要给用户程序分配空间,解释器本身也占用了宝贵的系统资源;③由于解释型应用的decode-fetch-execute(解码-抓取-执行)的周期,它们比编译型程序慢很多。

编译型语言是相对于解释型语言存在的,编译型语言首先将源代码编译生成机器语言,再由机器运行机器码(二进制)。

常见的有:C、C++等,优点:运行速度快,代码效率高,编译后程序不可以修改,保密性好;缺点:①代码需要经过编译方可运行,可移植性差,只能在兼容的操作系统上运行;②安全性不如解释性语言,一个编译型的程序可以访问内存的任何区域,并且可以对你的PC做它想做的任何事情(大部分病毒是使用编译型语言编写的)。

脚本语言又被称为扩建的语言,或者动态语言,是一种编程语言,用来控制软件应用程序,脚本通常以文本保存,只在被调用时进行解释或编译。脚本语言有:PHP、Python、JavaScript、Lua、Scala、VBScript,ActionScript,MAXScript,ASP,JSP,SQL,Perl,Shell,Ruby,JavaFX,AutoIt等;它是一种解释性的语言,它不象c/c++等可以编译成二进制代码,以可执行文件的形式存在,脚本语言不需要编译,可以直接用,由解释器来负责解释。

你可能感兴趣的:(学习笔记——Unity3D与C#基础总结)