答:ios
裝箱操做:程序員
值類型隱式轉換爲object類型或由此值類型實現的任何接口類型的過程。面試
1.在堆中開闢內存空間。算法
2.將值類型的數據複製到堆中。數據庫
3.返回堆中新分配對象的地址。express
拆箱操做:編程
object類型顯示轉換爲值類型或從接口類型到實現該接口值類型的過程。設計模式
1.判斷給定類型是不是裝箱時的類型。數組
2.返回已裝箱實例中屬於原值類型字段的地址。緩存
答:attribute翻譯成特性,用來標識類,方法 。
property翻譯爲屬性,性質用於存取類的字段 。
markup翻譯成標記。
tag翻譯成標籤。
答:程序集的一個重要特性是它們包含的元數據描述了對應代碼中定義的類型和方法。
答:ref 關鍵字使參數按引用傳遞。其效果是,當控制權傳遞迴調用方法時,在方法中對參數所作的任何更改都將反映在該變量中。若要使用 ref 參數,則方法定義和調用方法都必須顯式使用 ref 關鍵字。
out 關鍵字會致使參數經過引用來傳遞。這與 ref 關鍵字相似,不一樣之處在於 ref 要求變量必須在傳遞以前進行初始化。若要使用 out 參數,方法定義和調用方法都必須顯式使用 out 關鍵字。
答:1) new 運算符 :用於建立對象和調用構造函數。
2) new 修飾符 :用於向基類成員隱藏繼承成員。
3) new 約束 :用於在泛型聲明中約束可能用做類型參數的參數的類型。
答:string str = "" 初始化對象分配空間。
string str = null 表示一個空引用,沒有佔用空間。//實際狀況是,string爲null時依然爲"",但該題常考。
答:序列化是將對象狀態轉換爲可保持或傳輸的格式的過程。 與序列化相對的是反序列化,它將流轉換爲對象。這兩個過程結合起來,能夠輕鬆地存儲和傳輸數據。
答:
1) sealed 修飾符能夠應用於類、實例方法和屬性。密封類不能被繼承。密封方法會重寫基類中的方法,但其自己不能在任何派生類中進一步重寫。當應用於方法或屬性時,sealed 修飾符必須始終與 override一塊兒使用。
2) 將密封類用做基類或將 abstract 修飾符與密封類一塊兒使用是錯誤的。
3) 結構是隱式密封的;所以它們不能被繼承。
答:
相同點:
1) 語法相似。
不一樣點:
1) class是引用類型,繼承自System.Object類; struct是值類型,繼承自System.ValueType類,所以不具多態性。可是注意,System.ValueType是個引用類型。
2) 從職能觀點來看,class表現爲行爲; 而struct經常使用於存儲數據。
3) class支持繼承,能夠繼承自類和接口; 而struct沒有繼承性,struct不能從class繼承,也不能做爲class的基類,但struct支持接口繼承。
4) 實例化時,class要使用new關鍵字; 而struct能夠不使用new關鍵字,struct在聲明時就進行了初始化過程,全部的成員變量均默認爲0或null。
答:1) 堆棧的空間有限,對於大量的邏輯的對象,建立類要比建立結構好一些。
2) 結構表示如點、矩形和顏色這樣的輕量對象。例如,若是聲明一個含有 1000 個點對象的數組,則將爲引用每一個對象分配附加的內存。在此狀況下,結構的成本較低。
3) 在表現抽象和多級別的對象層次時,類是最好的選擇。
4) 大多數狀況下該類型只是一些數據時,結構時最佳的選擇。
答:
抽象類:
1) 抽象方法只做聲明,而不包含實現,能夠當作是沒有實現體的虛方法。
2) 抽象類不能被實例化。
3) 抽象類能夠但不是必須有抽象屬性和抽象方法,可是一旦有了抽象方法,就必定要把這個類聲明爲抽象類。
4) 具體派生類必須覆蓋基類的抽象方法。
5) 抽象派生類能夠覆蓋基類的抽象方法,也能夠不覆蓋。若是不覆蓋,則其具體派生類必須覆蓋它們。
接口:
1) 接口不能被實例化。
2) 接口只能包含方法聲明。
3) 接口的成員包括方法、屬性、索引器、事件。
4) 接口中不能包含常量、字段(域)、構造函數、析構函數、靜態成員。
5) 接口中的全部成員默認爲public,所以接口中不能有private修飾符。
6) 派生類必須實現接口的全部成員。
7) 一個類能夠直接實現多個接口,接口之間用逗號隔開。
8) 一個接口能夠有多個父接口,實現該接口的類必須實現全部父接口中的全部成員。
抽象類和接口的異同:
相同點:
1) 均可以被繼承。
2) 都不能被實例化。
3) 均可以包含方法聲明。
4) 派生類必須實現未實現的方法。
區 別:
1) 抽象基類能夠定義字段、屬性、方法實現。接口只能定義屬性、索引器、事件、和方法聲明,不能包含字段。
2) 抽象類是一個不完整的類,須要進一步細化,而接口是一個行爲規範。微軟的自定義接口老是後帶able字段,證實其是表述一類「我能作。。。」。
3) 接口能夠被多重實現,抽象類只能被單一繼承。
4) 抽象類更多的是定義在一系列緊密相關的類間,而接口大多數是關係疏鬆但都實現某一功能的類中。
5) 抽象類是從一系列相關對象中抽象出來的概念, 所以反映的是事物的內部共性;接口是爲了知足外部調用而定義的一個功能約定, 所以反映的是事物的外部特性。
6) 接口基本上不具有繼承的任何具體特色,它僅僅承諾了可以調用的方法。
7) 接口能夠用於支持回調,而繼承並不具有這個特色。
8) 抽象類實現的具體方法默認爲虛的,但實現接口的類中的接口方法卻默認爲非虛的,固然您也能夠聲明爲虛的。
9) 若是抽象類實現接口,則能夠把接口中方法映射到抽象類中做爲抽象方法而沒必要實現,而在抽象類的子類中實現接口中方法。
答:1) 操做系統和運行庫環境一般會在應用程序間提供某種形式的隔離。
2) 應用程序域爲安全性、可靠性、版本控制以及卸載程序集提供了隔離邊界。
3) 應用程序域能夠理解爲一種輕量級進程。起到安全的做用。佔用資源小。
答:爲全部變量指定數據類型稱爲「強類型」。C#是強類型語言。
答:使用基於公共語言運行庫的語言編譯器開發的代碼稱爲託管代碼;託管代碼具備許多優勢,例如:跨語言集成、跨語言異常處理、加強的安全性、版本控制和部署支持、簡化的組件交互模型、調試和分析服務等。
答:CTS:通用系統類型 Common Type System。全部.NET語言共享這一類型系統,實現它們之間無縫的互操做。該方案還提供了語言之間的繼承性。
答:CLR:公共語言運行庫 Common Language Runtime。是一個運行時環境,它負責資源管理(內存分配和垃圾收集),並保證應用和底層操做系統之間必要的分離。
答:CLS:公共語言規範 Common Language Specification。能夠保證C#組件與其餘語言組件間的互操做性。
答:1) 委託是一種引用方法的類型。
2) 委託相似於 C++ 函數指針,但它是類型安全的。
3) 委託容許將方法做爲參數進行傳遞。
4) 委託可用於定義回調方法。
答:1) Active Directory存儲了有關網絡對象的信息,而且讓管理員和用戶可以輕鬆地查找和使用這些信息。
2) Active Directory使用了一種結構化的數據存儲方式,並以此做爲基礎對目錄信息進行合乎邏輯的分層組織。
答:程序集(中間語言,源數據,資源,裝配清單)。
答:1) 值類型一般被分配在棧上,它的變量直接包含變量的實例,使用效率比較高。
2) 引用類型分配在託管堆上,引用類型的變量一般包含一個指向實例的指針,變量經過該指針來引用實例。
3) 一個是值COPY,一個是地址COPY。
值類型 |
引用類型 |
||
內存分配地點 |
分配在棧中 |
分配在堆中 |
|
效率 |
效率高,不須要地址轉換 |
效率低,須要進行地址轉換 |
|
內存回收 |
使用完後,當即回收 |
使用完後,不是當即回收,等待GC回收 |
|
賦值操做 |
進行復制,建立一個同值新對象 |
只是對原有對象的引用 |
|
函數參數與返回值 |
是對象的複製 |
是原有對象的引用,並不產生新的對象 |
|
類型擴展 |
不易擴展 |
容易擴展,方便與類型擴展 |
答:.NET Framework 的垃圾回收器管理應用程序的內存分配和釋放。每次使用 new 運算符建立對象時,運行庫都從託管堆爲該對象分配內存。只要託管堆中有地址空間可用,運行庫就會繼續爲新對象分配空間。可是,內存不是無限大的。最終,垃圾回收器必須執行回收以釋放一些內存。垃圾回收器優化引擎根據正在進行的分配狀況肯定執行回收的最佳時間。當垃圾回收器執行回收時,它檢查託管堆中再也不被應用程序使用的對象並執行必要的操做來回收它們佔用的內存。
答:索引器容許類或結構的實例按照與數組相同的方式進行索引。索引器相似於屬性,不一樣之處在於它們的訪問器採用參數。能夠用任意類型索引。
1) 索引器使得對象可按照與數組類似的方法進行索引。
2) get 訪問器返回值。set 訪問器分配值。
3) this 關鍵字用於定義索引器。
4) value 關鍵字用於定義由 set 索引器分配的值。
5) 索引器沒必要根據整數值進行索引,由您決定如何定義特定的查找機制。
6) 索引器可被重載。
7) 索引器能夠有多個形參,例如當訪問二維數組時。
答:1) 進程是系統進行資源分配和調度的單位。
2) 線程是CPU調度和分派的單位。
3) 一個進程能夠有多個線程,這些線程共享這個進程的資源。
答:啓動一個線程是調用start()方法,致使操做系統將當前實例的狀態更改成ThreadState.Running。
答:構造器Constructor不能被繼承,所以不能重寫override,但能夠被重載Overloade。
答:靜態成員override、virtual 或 abstract。
抽象類不能是密封的sealed或靜態的static。
答:using 關鍵字有兩個主要用途:
1) 做爲指令,用於爲命名空間建立別名或導入其餘命名空間中定義的類型。
2) 做爲語句,用於定義一個範圍,在此範圍的末尾將釋放對象。
new 關鍵字:新建實例或者隱藏父類方法
答:.NET錯誤處理機制採用try->catch->finally結構。 throw
發生錯誤時,層層上拋,直到找到匹配的catch爲止。
答:error 表示恢復不是不可能但很困難的狀況下的一種嚴重問題。好比說內存溢出。
不可能期望程序能處理這樣的狀況。
exception 表示一種設計或實現問題。
也就是說,它表示若是程序運行正常,從不會發生的狀況。
答:1) TCP(Transmission Control Protocol)傳輸控制協議:一種面向鏈接的、可靠的、基於字節流的運輸層通訊協議,三次握手。
2) UDP(User Datagram Protocol)用戶數據報協議:它不屬於鏈接型協議,於是具備資源消耗小,處理速度快的優勢。缺點是易丟失數據包。
答:1) System.String是不可變的字符串。
2) System.StringBuilder存放了一個可變的字符串,並提供一些對這個字符串修改的方法。
3) String類在執行字符串拼接的操做上,用「+」會產生新的對象,佔用內存。
4) StringBuilder類只是修改字符串的內容,不創建新的對象。
答:1) const 字段只能在該字段的聲明中初始化。
2) 不容許在常數聲明中使用 static 修飾符。
3) readonly 字段能夠在聲明或構造函數中初始化。所以,根據所使用的構造函數,readonly 字段可能具備不一樣的值。
4) 另外,const 字段是編譯時常數,而 readonly 字段可用於運行時常數。
答:委託能夠把一個方法做爲參數代入另外一個方法。
委託能夠理解爲指向一個函數的引用。
事件是一種特殊的委託。
答:在類型或成員的聲明中使用 unsafe 修飾符。所以,類型或成員的整個正文範圍均被視爲不安全上下文,沒法由 CLR 進行驗證的代碼。
答:封裝、繼承、多態。
答:聲明IEnumerable接口或實現GetEnumerator()方法。
答:接口能夠繼承接口。抽象類能夠實現(implements)接口,抽象類是否可繼承實體類,但前提是實體類必須有明確的構造函數。
答:String類是sealed類故不能夠繼承。
答:數組、String類都沒有Length()方法,它們只有Length屬性。
答:即便沒有建立類的實例,也能夠調用該類中的靜態方法、字段、屬性或事件。若是建立了該類的任何實例,不能使用實例來訪問靜態成員。靜態成員一般用於表示不會隨對象狀態而變化的數據或計算。
答:1) 虛函數:沒有實現的,可由子類繼承並重寫的函數。
2) 抽象函數:規定其非虛子類必須實現的函數,必須被重寫。
答:?:。格式以下:ndition ? first_expression : second_expression。
答:裝箱。
答:delegate.
答:[Serializable]
答:要同時修改Equale和GetHash() ? 重載了"==" 就必須重載 "!="。
答:62移動成2的6次方,26。
答:能夠使用指針。也就是非安全代碼,就是不在 CLR 徹底控制下執行的代碼,它有可能會致使一些問題,所以他們必須用 「unsafe」 進行代表。
&是位運算符,表示按位與運算。
&&是邏輯運算符,表示邏輯與(and)
能夠。
(1) 實現1
string[] s ={ "111", "22222" };
ArrayList list = new ArrayList();
list.AddRange(s);
(2)實現2
string[] s ={ "111", "22222" };
ArrayList list = new ArrayList(s);
強名是由程序集的標識加上公鑰和數字簽名組成的,其中,程序集的標識包括簡單文本名稱、版本號和區域性信息(若是提供的話)。它使用對應的私鑰從程序集文件中生成。(程序集文件包含程序集清單,其中包含組成程序集的全部文件的名稱和哈希。)
1. for:使用於肯定次數的循環。
2. foreach:使用於遍歷的元素是隻讀的。//Unity中此處是個坑,建議不要用foreach
3. while:次數不肯定,條件隨機變化。
4. do...while:次數不肯定,條件隨機變化,但至少要保證能被執行一次。
1. 在應用程序和遠程設備中使用協議和網絡地址初始化套接字。
2. 在應用程序中經過指定端口和地址創建監聽。
3. 遠程設備發出鏈接請求。
4. 應用程序接受鏈接產生通訊scoket。
5. 應用程序和遠程設備開始通信(在通信中應用程序將掛起直到通信結束)。
6. 通信結束,關閉應用程序和遠程設備的Socket回收資源。
答:會執行,在return前執行。
public class A { public virtual void Fun1( int i ) { Console.WriteLine( i ); } public void Fun2( A a ) { a.Fun1( 1 ); Fun1( 5 ); } } public class B : A { public override void Fun1( int i ) { base.Fun1( i + 1 ); } public static void Main() { B b = new B(); A a = new A(); a.Fun2( b ); b.Fun2( a ); } }
答案:
2
5
1
6
答案:
public static void Main() { int input = int.Parse( Console.ReadLine() ); int sum = 0; for( int i = 0; i <= input; i++ ) { if( ( i % 2 ) == 1 ) { sum += i; } else { sum = sum - i; } } Console.WriteLine( sum ); }
答:不對,有相同的hash code。
答案:能夠做用在byte和long上,也能夠做用在string上。
答: 1. short s1 = 1; s1 = s1 + 1;有錯,s1是short型,s1+1是int型,不能隱式轉化爲short型。可修改成s1 =(short)(s1 + 1) 。
2. short s1 = 1; s1 += 1正確。
題目:須要實現對一個字符串的處理,首先將該字符串首尾的空格去掉,若是字符串中間還有連續空格的話,僅保留一個空格,即容許字符串中間有多個空格,但連續的空格數不可超過一個。
答案:
string inputStr = " xx xx ";
inputStr = Regex.Replace( inputStr.Trim(), @"/s+", " " );
int i = 5;
int j = 5;
if( Object.ReferenceEquals( i, j ) )
Console.WriteLine( "Equal" );
else
Console.WriteLine( "Not Equal" );
答案:Not Equal。由於比較的是對象
答:const不能用static修飾。
class A { public virtual void F() { Console.WriteLine( "A.F" ); } } abstract class B : A { public abstract override void F();//abstract與override關鍵字能夠同時使用 }
答案:沒有錯誤!能夠經過編譯器。
注意:網上有資料說abstract與override關鍵字不能夠同時使用,這種說法是錯誤的 !
A. public enum var1{ Mike = 100, Nike = 102, Jike }
B. public enum var1{ Mike = 「1」, Nike, Jike }
C. public enum var1{ Mike=-1 , Nike, Jike }
D. public enum var1{ Mike , Nike , Jike }
答案B
class A
{
public static int X;
static A()
{
X = B.Y + 1;
}
}
class B
{
public static int Y = A.X + 1;
static B()
{
}
static void Main()
{
Console.WriteLine( "X={0},Y={1}", A.X, B.Y );
}
}
答:x=1,y=2
class Class1
{
private string str = "Class1.str";
private int i = 0;
static void StringConvert( string str )
{
str = "string being converted.";
}
static void StringConvert( Class1 c )
{
c.str = "string being converted.";
}
static void Add( int i )
{
i++;
}
static void AddWithRef( ref int i )
{
i++;
}
static void Main()
{
int i1 = 10;
int i2 = 20;
string str = "str";
Class1 c = new Class1();
Add( i1 );
AddWithRef( ref i2 );
Add( c.i );
StringConvert( str );
StringConvert( c );
Console.WriteLine( i1 );
Console.WriteLine( i2 );
Console.WriteLine( c.i );
Console.WriteLine( str );
Console.WriteLine( c.str );
}
}
答案:10, 21, 0, str, string being converted
注意:此處加逗號「,」是爲了答案看起來清晰,實際結果是縱向排列的,由於調用了Console.WriteLine()。
public abstract class A
{
public A()
{
Console.WriteLine( 'A' );
}
public virtual void Fun()
{
Console.WriteLine( "A.Fun()" );
}
}
public class B : A
{
public B()
{
Console.WriteLine( 'B' );
}
public new void Fun()
{
Console.WriteLine( "B.Fun()" );
}
public static void Main()
{
A a = new B();
a.Fun();
}
}
答案:
A
B
A.Fun()
答:
string的字符串爲常量不可修改。
1.能夠知足字符串常量池的須要。即對於建立相同文本時,string爲同一對象。
2.容許string對象緩存HashCode。字符串不變形保證了hash碼的惟一性。
3.安全性,string被許多的類庫用來當作參數。
StringBuilder實際是一個char類型的集合,完成了組裝拼接等工做。
String更適合作程序的參數,StringBuilder用於作String類型的組裝。
答:
StringBuilder的優點在於拼接字符串。
//String的優點在於對字符串作一些處理,在使用過程當中看具體的需求。
答:
int number = 46234;
string strNumber=number.ToString();
int length = strNumber.Length;
方法1:
int result=0;
for (int i = 0; i < length; i++)
{
result += number % 10;
number \= 10;
}
方法2:
for (int i = 0; i < length; i++)
{
result += number / (int)Math.Pow(10, i) % 10;
}
方法3:
for (int i = 0; i < strNumber.Length; i++)
{
result += int.Parse(strNumber[i].ToString());
}
注:
答:
冒泡排序:它重複地走訪過要排序的數列,一次比較兩個元素,若是它們的順序錯誤就把他們交換過來。走訪數列的工做是重複地進行直到沒有再須要交換。
冒泡排序算法的運做以下:
l 比較相鄰元素。若是第一個比第二個大,就交換它們。
l 對每一對相鄰元素作一樣的工做,從開始第一隊到結尾的最後一對。在這一點,最後的元素會使最大的數。
l 針對全部的元素重複以上的步驟,除了最後一個。
l 持續每次對愈來愈少的元素重複上面的步驟,知道沒有任何一對數字須要比較。
寫法1
public void Bubble1(int[] a)
{
bool b;
int tmp;
for (int i = 0; i < a.Length; i++)
{
b = false;
for (int j = i+1; j < a.Length ; j++)
{
if (a[j] > a[i])
{
tmp = a[j];
a[j] = a[i];
a[i] = tmp;
b = true;
}
}
if(!b)break;
}
}
寫法2
void Bubble2(int[] a)
{
bool b=false;
int tmp;
for(int i=0;i<a.Length;i++)
{
b=false;
for(int j=0;j<a.Length-i;j++)
{
if(a[j]<a[j+1])
{
tmp=a[j];
a[j]=a[j+1];
a[j+1]=tmp;
b=true;
}
}
if(!b) break;
}
}
寫法3
void Bubble3(int[] a)
{
bool b=true;
int j=0;
int temp;
do
{
b=false;
for(int i;i<a.Length-j;i++)
{
if(a[i]<a[i+1])
{
temp=a[i];
a[i]=a[i+1];
a[i+1]=temp;
b=true;
}
}
j++;
}
while(b);
}
object o1 = 1;
object o2 = o1;
o1 = 2;
Console.WriteLine(o2);
答:
1;
緣由:o1將數據1在堆中引用賦值給o2,然後又將引用指向數據2,故o2仍指向數據1的引用。
答:
[訪問修飾符][可選修飾符] 返回類型 方法名稱(參數列表)
{
//方法體;
return 結果;
}
答:
在不少語言當中如Java\C#中字符串string被設計成具備不可變性的。從系統優化方面考慮這樣的設計好處主要由三點。
首先,它容許在一個字符串上執行各類操做,而不實際地更改字符串。
字符串不可變,還由於這在操做或訪問一個字符串時不會發成線程同步問題。
除此以外,CLR可經過一個String對象共享多個徹底一致的String內容。這樣能減小系統中的字符串數量,者正是字符串留用技術的目的。
1.字符串常量池的須要。字符串常量池是內存堆中一個特殊的存儲區域,當建立一個string對象時,假設此字符串值已經存在於常量池中,則不會建立一個新的對象,而是引用已經存在的對象。
2.容許string對象緩存HashCode。字符串不變性保證了hash碼的惟一性,所以能夠放心地進行緩存,這是一種性能優化手段,由於這沒必要每次都去計算新的哈希碼。
3.安全性。string被許多的類庫用來當作參數,例如網絡鏈接URL,文件路徑Path,還有反射機制所須要的String參數等,倘若string可變的,將會引發各類安全隱患。
綜上,string不可變的緣由包括設計考慮,效率優化問題,以及安全性三大方面。
另:在C++中string類型是可變的。
答:
方法名稱相同,但參數列表不一樣稱爲方法重載。用於在不一樣條件下解決同一類型的問題。
class A
{
public static int a;
static A()
{
a = B.b + 1;
}
}
class B
{
public static int b;
static B()
{
b = A.a + 1;
}
}
static void Main()
{
Console.WriteLine(A.a);
Console.WriteLine(B.b);
}
答:2 ,1
class C
{
public static int a;
public C()
{
a++;
}
static C()
{
a++;
}
}
static void Main()
{
C c1 = new C();
C c2 = new C();
C c3 = new C();
Console.WriteLine(C.a);
}
答:4
答:
靜態函數沒有訪問修飾符,其餘C#代碼歷來不調用它,但在加載類時,老是由.NET運行庫調用它,因此像public或private這樣的訪問修飾符就沒有任何意義。出於一樣緣由,靜態構造函數不能帶任何參數,一個類也只能有一個靜態構造函數。靜態構造函數只能訪問類的靜態成員,不能訪問類的實例成員。
也就是說只加static不會報錯,加了static再加了別的就會報錯。
答:(a,b)=>{}
注:該題有兩種錯誤可能:
一種是方法沒有些返回值即Func(string a,string b)爲 void Func(string a,string b)此時,Lambda表達式可寫做(a,b)=>{}
一種是Func爲Func<string,string>此時Lambda可寫做a=>b//a,b爲string類型
public static int Fibonacci(int num)//Fibonacci
{
return (num==0||num==1)?1:(Fibonacci(num-2)+Fibonacci(num-1));
}
注:計算斐波那契數列依據數列定義來創建方法是不推薦的寫法。由於此時計算第n位的數的時間複雜度爲O((3/2)n)。相比較而言,利用循環能夠將時間複雜度縮小到O(n)該方法較爲實用,並且實現簡單,在沒有特殊要求的狀況下屬於建議的寫法。另外一種優化的寫法能夠將時間複雜度優化到O(logn),實現代碼較複雜,且隱含的時間常數較大。但適合面試者展現其知識面和代碼實現的能力。
兩種寫法以下:
寫法一:
public long Fibonacci1(int num)
{
return (num==0||num==1)?1:(Fibonacci1(num-2)+Fibonacci1(num-1));
}
寫法二:
public long Fibonacci2(int num)
{
int result[2]={0,1};
if(n<2)
return result[n];
long fibOne=1;
long fibTwo=0;
long fibN=0;
for(int i=2;i<=n;i++)
{
fibN=fibOne+fibTwo;
fibTwo=fibOne;
fibOne=fibN;
}
return fibN;
}
答:
從概念上區分,值類型時直接存儲其值,而引用類型是存儲對值的引用。
實際中,對於值類型的對象,初始化一個實例,該實例表明的是其內部存儲的數據自己。而引用類型的對象,初始化一個實例,該實例表明的是其初始化數據在內存當中的引用。
值類型隱式繼承自System.ValueType.該類爲抽象類,只能序列化,不能被顯式繼承。
值類型:枚舉,結構
引用類型:數組,委託,類,接口
答:
ArrayList是非泛型列表,存儲數據是把全部的數據都當成object類型數據,存在裝箱問題,取出來使用的時候存在拆箱問題,裝箱拆箱會使性能變差,並且存在數據安全問題,可是優勢在於可讓值類型和引用類型相互轉換。
List是泛型列表,在使用的時候纔會去定義數據類型,泛型避免了拆裝箱的問題,存入讀取熟讀較快,類型也更安全。
解析:首先,這道題的描述是不嚴謹的,GC做爲CLR的一種機制是由系統調用的,只要運行與CLR上的託管代碼GC的工做自己是不可避免的。
可是拋開這些細節不談,我能夠在這裏寫把我認爲這道題可能涉及到的東西寫一下。
若是隻把GC理解成一種能夠自動釋放內存的方式,使程序員省去了手動釋放內存的煩惱,或試圖引用已釋放的內存空間的錯誤,這無疑是片面的,雖然這的確是GC很是重要的功能。但GC的做用遠不如此。
GC的產生是與CLR堆內存特殊的分配方式有關的。CLR要求全部的資源都從託管堆分配,託管堆有一個指針NextObjPtr它的初始爲保留地址空間的基地址。NextObjPtr指向下一個對象在堆中的分配位置。每當添加一個對象,NextObjPtr指針的值就會加上對象佔據的字節數。這樣作有兩個好處:
首先,在許多應用程序中,差很少同時分配的對象彼此間有較強的聯繫,並且常常差很少在同一時間訪問。在垃圾回收環境中,若是對象在內存中連續分配,會因爲引用的本地性而得到性能上的提高。具體地說,這意味着進程的工做集小於非託管環境中運行類似的應用程序。
另外一方面,這意味着代碼使用的對象能夠所有駐留在CPU的緩存中,加快CPU對這些對象的訪問速度。
但託管堆具備這些好處,是由於它作了一個至關大膽的假設,地址的空間和存儲是無限的。那麼如何讓它由假設變爲可實現的,這就是GC垃圾回收的工做。
GC的垃圾回收算法是基於世代法和啓發式算法的。
世代法是指將堆分爲0代,1代,2代。每當0代的堆滿時就觸發一次垃圾回收。當第0代的的內存並沒被釋放,就會被提高到1代,若是1代在被回收時仍然保留的內存,就會被提高到2代。這樣壓縮空間的的方法保證了堆內存的連續性,增長了訪問對象的速度。而啓發式算法是指在基於應用程序對新建對象的模式,進行啓發式的對第1代,第2代堆進行釋放,或擴大第0代的堆空間。
建議只有在如下兩種狀況下才調用Dispose或Close:肯定必須清理資源;或者肯定能夠安全地調用Dispose或Close,並但願將對象從中介列表中刪除,禁止對象提高(到另外一代)從而提升性能。
那麼避免由於GC過程而影響性能的編程方法以下:
答:
語法不一樣:
1.抽象類中能夠有字段,接口沒有。
2.抽象類中能夠有實現成員,接口只能包含抽象成員。
3.抽象類中全部成員修飾符均可以使用,接口中全部的成員都是對外的,因此不須要修飾符修飾。
用法不一樣:
1.抽象類是概念的抽象,接口關注與行爲。
2.抽象類的子類與父類的關係是泛化關係,耦合度較高,而實現類和接口之間是實現關係,耦合度比泛化低。
3.一個類只能繼承自一個類,可是能夠實現多個接口。
string a="abc";//1個對象
a=(a.ToUpper()+"123").Substring(0,2);
答:三個臨時對象
注:string a="abc";//1個對象
a=(a.ToUpper()+"123").Substring(0,2);
a.ToUpper()//1個臨時對象
"123"//1個臨時對象
a.ToUpper()+"123"//1臨時個對象
.Substring(0,2)//1個對象因爲它將引用賦給了a因此它不是臨時對象
在語句運行時結束後不存在引用的對象。
List<int> Is=new List<int>(new int[]{1,2,3,4,5});
foreach(int item in Is)
{
Console.WriteLine(item*item);
Is.Remove(item);
}
答:會產生運行時錯誤,拋出一個InvalidOperationException異常,由於foreach是隻讀的。不能一邊遍歷一邊修改。使用foreach時候不要對內容進行修改。
答:sealed訪問修飾符用於類時,表示該類不能被繼承;對於方法表示不能重寫該方法。當應用於方法或屬性時,sealed 修飾符必須始終與 override 一塊兒使用。
注:
若要肯定是否密封類、方法或屬性,一般應考慮如下兩點:
派生類利用自定義類的功能所得到的可能好處。
派生類在修改類以後致使其沒法正常工做或按預期工做的可能性。
答:public:對任何類和成員都公開,無限制訪問
private:僅對該類公開
protected:對該類和其餘派生類公開
internal:只能在包含該類的程序集中訪問該類
protected internal:protected+internal
注:
可見性修飾符:
修飾符 |
應用於 |
說明 |
public |
全部類型或成員 |
任何代碼都可以訪問該項 |
protected |
類型和內嵌類型的全部成員 |
只有派生的類型可以訪問該項 |
internal |
全部類型或成員 |
只能在包含它的程序集中訪問該項 |
prvate |
類型和內嵌類型的全部成員 |
只能在它所述的類型中訪問該項 |
protected internal |
類型和內嵌類型的全部成員 |
只能在包含它的程序集和派生類型的代碼中訪問該項。 |
其餘修飾符
修飾符 |
應用於 |
說明 |
new |
函數成員 |
成員用相同的簽名隱藏繼承的成員 |
static |
全部成員 |
成員不做用於類的具體實例 |
virtual |
僅函數成員 |
成員能夠由派生類重寫 |
abstract |
僅函數成員 |
虛擬成員定義了成員的簽名,但沒有提供實現代碼 |
override |
僅函數成員 |
成員重寫了繼承的而虛擬或抽象成員 |
sealed |
類、方法和屬性 |
對於類,不能繼承自密封類。對於屬性和方法,成員重寫已繼承的虛擬成員,但任何派生類中的任何成員都不能重寫該成員。當應用於方法或屬性時,sealed 修飾符必須始終與 override 一塊兒使用。 |
extern |
僅靜態[DllImport]方法 |
成員在外部用另外一種語言實現
|
答:審查元數據並收集關於它的類型信息的能力。
注:
公共語言運行時程序管理應用程序域,應用程序域構成具備相同應用程序範圍的對象周圍定義的邊界。 此管理包括將每一個程序集加載到相應的應用程序域中和控制每一個程序集內的類型層次結構的內存佈局。
程序集包含模塊、模塊包含類型,而類型包含成員。 反射提供封裝程序集、模塊和類型的對象。 能夠使用反射動態地建立類型的實例,將類型綁定到現有對象,或從現有對象中獲取類型。而後,能夠調用類型的方法或訪問其字段和屬性。
Reflection,中文翻譯爲反射。
這是.Net中獲取運行時類型信息的方式,.Net的應用程序由幾個部分:‘程序集(Assembly)’、‘模塊(Module)’、‘類型(class)’組成,而反射提供一種編程的方式,讓程序員能夠在程序運行期得到這幾個組成部分的相關信息,例如:
Assembly類能夠得到正在運行的裝配件信息,也能夠動態的加載裝配件,以及在裝配件中查找類型信息,並建立該類型的實例。
Type類能夠得到對象的類型信息,此信息包含對象的全部要素:方法、構造器、屬性等等,經過Type類能夠獲得這些要素的信息,而且調用之。
MethodInfo包含方法的信息,經過這個類能夠獲得方法的名稱、參數、返回值等,而且能夠調用之。
諸如此類,還有FieldInfo、EventInfo等等,這些類都包含在System.Reflection命名空間下。
答:MONO是.NET的一個開源跨平臺工具。.NET只能在Windows下運行,Mono能夠實現跨平臺,能夠運行與Linux,Unix,Mac OS等。
答:
1)單一職責原則:一個類,最好只作一件事,只有一個引發它的變化。
2)開放-封閉原則:對於擴展是開放的,對於更改是封閉的。
3)里氏替換原則:子類必須可以替換其基類。
4)依賴倒置原則:設計應該依賴於抽象而不是具體實現。
A.高層模塊不該該依賴底層模塊,兩個都應該依賴抽象。
B.抽象不該該依賴細節,細節應該依賴抽象(要對抽象編程,不要對實現編程。)
5)接口隔離原則:使用多個小的專門的接口而不要使用一個大的總接口。
6)迪米特法則:若是兩個類不彼此直接通訊,那麼這兩個類就不該當發生直接的相互做用。若是其中一個類須要調用另外一個類的某一個方法的話,能夠經過第三者轉發這個調用。
7)合成/聚合複用原則:儘可能使用合成/聚合,儘可能不要使用類繼承。
注:
答:電腦沒有絕對的無序,hashtable是經過哈希碼讓開發者感受無序。
注:這裏的無序是指集合的添加順序與其輸出順序無關。Hashtable是經過哈希碼或哈希函數,對其內部元素進行排列的,因此其元素的添加順序與其輸出順序無關。
答:
單例: 對象池,遊戲管理器
抽象工廠,
狀態:有限狀態機,
橋接:有限狀態機
策略:AI自動行爲操控中每種操控算法的獨例
注:擴展補充。
建立型模式:單例模式、抽象工廠模式、建造者模式、工廠模式、原型模式。
結構型模式:適配器模式、橋接模式、裝飾模式、組合模式、外觀模式、享元模式、代理模式。
行爲型模式:模版方法模式、命令模式、迭代器模式、觀察者模式、中介者模式、備忘錄模式、解釋器模式(Interpreter模式)、狀態模式、策略模式、職責鏈模式(責任鏈模式)、訪問者模式。
答:列表:
特色:有序,內存空間連續,讀取速度快,大小可變,經過位置索引取元素.
缺點:輸入,刪除的速度慢
類庫已實現:List<T>、 ArrayList
字典:
特色:鍵值對的集合,經過鍵查找值,查找方便,無序
類庫已實現:Dictionary<TKey,TValue>、Hashtable
棧:
特色:後進前出 LIFO(Last In First Out)
支持操做:入棧,出棧,讀棧頂,
類庫已實現:Stack<T>、Stack
隊列:
特色:前進前出 FIFO(First In First Out)
支持操做:入隊,出隊,讀隊首
類庫已實現:Queue<T>、Queue
鏈表:
特色:節點內存空間不連續,插入,刪除速度快,讀取速度慢.
類庫已實現:LinkedList<T>
數組:
特色:內存空間連續,長度固定,讀取速度快
類庫已實現:Array
樹:
特色:能夠將對象組織爲層次結構,
實現:可以使用設計模式中的組合模式實現樹結構
答:
Override: 是指方法的重寫,C#中可重寫abstract、vritual 、override三類方法,重寫是子類重寫父類的以上三種方法,是動態綁定的,調用速度比方法隱藏慢,但靈活性好,重寫本質是對方法表的修改
Overload:是指方法的重載,一個類中的多個同名方法,參數列表不一樣,主要指參數個數或類型不一樣,重載的目的是爲了讓實現類似功能的方法用一個名稱表示,方便程序員編寫和理解代碼。可讀性好。
重寫和重載都是多態的一種體現。
答:
數組:長度固定,大小不變,存儲空間連續,讀取速度快,插入,刪除速度慢。
集合:長度不定,大小可變,存儲空間可能不連續,適合存放不肯定數量的數據。
答:
方法一:實現IComparer, 使用Array.Sort(Array, IComparer )
方法二:使用OrderBy或OrderByDescending 方法加Lambda表達式
如:arr = arr.OrderBy(p=>p.age).ToArray();
答: 在按鈕上綁定一個帶有OnClick事件List<EventDelegate>;
EventDelegate();
EventDelegate(Callback call);//void Callback()
EventDelegate(MonoBehaviour target,string methodName)
答:必須安裝QuickTime播放器,不支持FLV視頻格式。
答:MovieTexture。
答:
存儲:PlayerPrefs.SetInt ("MyKey", 1);
獲取:int myKey = PlayerPrefs.GetInt ("MyKey");
答:
PlayerPrefs.DeleteKey ("MyKey");
PlayerPrefs.DeleteAll ();
答:NavMeshAgent。
答:尋路網格動態碰撞組件,用於運動的物體阻礙尋路物體效果。
答:射線碰到的碰撞信息
答:經過LayerMask(層的遮罩),RaycastHit返回的碰撞的標籤。
答:Generic Humanoid類人樣式。
關鍵幀動畫
默認骨骼動畫(人型)
CAT
動畫->點緩存->關鍵幀
答:
l 簡單化對類人角色動畫設計與功能實現的工做流程。
l Mecanim動畫系統使用一個可視化編程工具來管理動畫之間複雜的交互。
l 對完成綁定骨骼的類人角色,可以對身體不一樣的地方使用不一樣的邏輯進行動畫控制。
l 能夠在角色動畫播放過程當中添加動畫事件。
l 人形動畫骨骼動畫可重複使用。
答:Panel是一個容器,它將包含全部UI小部件,並負責將所包含的部件組合。
Anchor是NGUI中屏幕分辨率的自適應性,來適應不一樣的分辨率的屏幕顯示。
注:
答:以平面任意兩點,取兩平面法向量,連接兩點線段,線段是否與法向量的夾角來判斷是否平行。
法向量若是平行,看線段與法向量的夾角,若是平行則兩平面重合,判斷邊界是否相交。
若是平行,且有夾角,說明不重合兩平面平行,必定不相交。
若是法向量不平行,將該線段的在兩平面投影方向上的射線判斷與平面的邊界條件,若是兩條射線的交點都在邊界內,則相交,不然不相交。
注:
答:MeshCollider是網格碰撞器,對於複雜網狀模型上的碰撞檢測,比其餘的碰撞檢測精確的多,可是相對其餘的碰撞檢測計算也增多了,因此通常使用網格碰撞也不會在面數比較高的模型上添加,而會作出兩個模型,一個超簡模能表示物體的形狀用於作碰撞檢測,一個用於顯示。
MeshCollider有Mesh屬性
答:
答:兩個物體都必須帶有碰撞器(Collider),其中一個物體還必須帶有Rigidbody剛體。
注:動的物體,你但願發生碰撞效果的物體要帶能接受物理引擎的操做,最多見的就是掛載Rigidbody組件。
答:CharacterController自帶膠囊碰撞器,裏面包含有剛體的屬性;
Rigidbody就是剛體,使物體帶有剛體的特徵。
注:
答:穿透(碰撞檢測失敗)。將物體移動放在FixedUpdate中,儘可能使用物理引擎本身的移動方法。
避免的方法:把剛體的實時碰撞檢測打開Collision Detection修改成Continuous Dynamic
注:
答:
主要是三個階段:
1.Collider.OnCollisionEnter 進入碰撞,當collider/rigidbody開始觸動另外一個rigidbody/collider時OnCollisionEnter被調用。
2.Collider.OnCollisionStay 逗留碰撞,每一個collider/rigidbody觸動rigidbody/collider,將在每幀調用OnCollisionStay。通俗的說,一個碰撞器或剛體觸動另外一個剛體或碰撞器,在每幀都會調用OnCollisionStay,直到它們之間離開不接觸。
3.Collider.OnCollisionExit 退出碰撞,當 collider/rigidbody中止觸動另外一個 rigidbody/collider時,OnCollisionExit被調用。
答:
答:主要有關節動畫、單一網格模型動畫(關鍵幀動畫)、骨骼動畫。
1.關節動畫:把角色分紅若干獨立部分,一個部分對應一個網格模型,部分的動畫鏈接成一個總體的動畫,角色比較靈活,Quake2中使用這種動畫。
2.單一網格模型動畫由一個完整的網格模型構成,在動畫序列的關鍵幀裏記錄各個頂點的原位置及其改變量,而後插值運算實現動畫效果,角色動畫較真實。
3.骨骼動畫,普遍應用的動畫方式,集成了以上兩個方式的優勢,骨骼按角色特色組成必定的層次結構,有關節相連,可作相對運動,皮膚做爲單一網格蒙在骨骼以外,決定角色的外觀,皮膚網格每個頂點都會受到骨骼的影響,從而實現完美的動畫。
答:反轉動畫,將動畫的播放速度調到-1。
答:AddClip 添加剪輯、Blend 混合、Play 播放、Stop 中止、Sample 採樣 、CrossFade淡入淡出切換動畫、IsPlaying是否正在播放某個動畫
答:動畫層做爲一個具備層級動畫編輯概念的工具,能夠用來製做和處理任何類型的動畫。202,203題
答:ITween是補間動畫的一個插件,主要做用就是給出開始、結束的值、時間,此插件實現各類動畫,晃動,旋轉,移動,褪色,上色,音量控制等等。
方法: 1.MoveTo 物體移動
2.ColorTo:隨着時間改變對象的顏色組
3.LookTo:隨時間旋轉物體讓其臉部朝向所提供的Vector3或Transform位置
答:
法線貼圖:是一種特殊的紋理,能夠應用在3D表面,讓低模呈現出更明顯的凹凸效果。一
般應用在CG動畫、美術效果要求較高的單機遊戲
CG動畫:遊戲中的CG動畫實際上是用3D模擬引擎製做的遊戲短片,通常畫面效果比較真實。
答:Unity支持多線程,若是同時要處理不少事情或者與Unity的對象互動小能夠用thread,不然使用coroutine。
注意:1.雖然支持多線程,可是僅能從主線程中訪問Unity3D的組件,對象和Unity3D系統調用,因此若是使用的話須要把組件中的數值傳到開啓的新線程中。
2.C#中有lock這個關鍵字,以確保只有一個線程能夠在特定時間內訪問特定的對象
答:多線程程序同時運行多個線程,除主線程以外的線程沒法訪問Unity3D的對象、組件、方法,而在任一指定時刻只有一個協程在運行。
答:在主線程運行時同時開啓另外一段邏輯處理,來協助當前程序的執行。使用戶能夠編寫更靈活的程序來控制運動、序列以及對象的行爲。
答:所謂四元數,就是把4個實數組合起來的東西。4個元素中,一個是實部,其他3個是虛部
做用:四元數用於表示旋轉
優勢:
1)能進行增量旋轉
2)避免萬向鎖
3)給定方位的表達方式有兩種,互爲負(歐拉角有無數種表達方式)
四元數不會有歐拉角存在的 gimbal lock 問題[萬向節死鎖]
四元數由4個數組成,旋轉矩陣須要9個數
兩個四元數之間更容易插值
四元數、矩陣在屢次運算後會積攢偏差,須要分別對其作規範化(normalize)和正交化 (orthogonalize),對四元數規範化更容易
與旋轉矩陣相似,兩個四元組相乘可表示兩次旋轉
答:遊戲界面能夠看到不少攝像機的混合。
答:正交和透視。
正交沒法看到一個物體距離本身有多遠,或者遠近的變化,物體也不會隨着距離而收縮,因此通常作2D遊戲或者是UI時會使用正交攝像機。
透視通常看物體會隨着距離有大小的變化,通常3D遊戲裏常用這種攝像機。
答:Prefab是預製件(預製物),通常當遊戲中須要頻繁建立一個物體時,使用預製物能夠節省內存,方便建立,方便對遊戲物體進行操做,方便對屬性進行修改。
答:動態加載再實例化,若是本身不主動清理內存的話,再次加載不會增長內存的,會自動去取以前已經加載好的assets,若是這一個assets你都嫌多的話,那你只能減資源了,好比,模型面數,紋理尺寸等
答:實際光照強度l=環境光(lambient)+漫反射光(Idiffuse)+鏡面高光(lspecular)
環境光:lambient=環境光強度(Aintensity)*環境光顏色(Acolor)
漫反射光:ldiffuse=鏡面光照強度(Dintensity)*鏡面光顏色(Scolor)*(光的反射向量(R).觀察者向量(V))^鏡面光指數(n)
答:MeshRender是模型渲染的組件,有此組件物體才能顯示出來
Material是材質球,實際就是shader的實例,並進行賦值,貼圖、紋理、顏色等。
Shader是着色器,其實是一段程序,還能夠用來實現一些僅靠貼圖不容易實現的效果,如玻璃。
Shader大體分爲:1.表面着色器
2.頂點和片元着色器
3.固定功能着色器
答:Alpha Blend是 實現透明效果,Color = 原顏色*alpha/255+目標色*(255-alpha)/255
答:1.使用光照貼圖比使用實時光源渲染要快
2.能夠下降遊戲內存消耗
3.多個物體能夠使用同一張光照貼圖
答:頂點着色器:頂點着色器是一段執行在GPU上的程序,用來取代fixed pipeline中的
transformation和lighting,Vertex Shader主要操做頂點。
Vertex Shader對輸入頂點完成了從local space到homogeneous space(齊次空間)的變換過程,homogeneous space即projection space的下一個space。在這其間共有world transformation, view transformation和projection transformation及lighting幾個過程。
答:4種,Directionl light ,Point Light ,Spot Light,Area Light
平行光:Directional Light
點光源:Point Light
聚光燈:Spot Light
區域光源:Area Light
答:FixedUpdate,每固定幀繪製時執行一次,和Update不一樣的是FixedUpdate是渲染幀執行,若是你的渲染效率低下的時候FixedUpdate調用次數就會跟着降低。FixedUpdate比較適用於物理引擎的計算,由於是跟每幀渲染有關。Update就比較適合作控制。
答:Awake –>OnEnable->Start
OnEnable在同一週期中能夠反覆地發生
Awake用於在遊戲開始以前初始化變量或遊戲狀態。在腳本整個生命週期內它僅被調用一次.Awake在全部對象被初始化以後調用,因此你能夠安全的與其餘對象對話或用諸如GameObject.FindWithTag這樣的函數搜索它們。每一個遊戲物體上的Awke以隨機的順序被調用。所以,你應該用Awake來設置腳本間的引用,並用Start來傳遞信息。
Start在腳本的生命週期中只被調用一次。它和Awake的不一樣是Start只在腳本實例被啓用時調用。你能夠按需調整延遲初始化代碼。Awake老是在Start以前執行。這容許你協調初始化順序。
但Start能夠做爲協程,達到在同一週期調用屢次的效果。不過實質上依然是調用一次。
答:ExcutionOrder有關,不設定順序的時候初始化Start的順序不肯定。
答:
|
方法名(按腳本聲明週期排列) |
做用 |
備註 |
Editor |
Reset |
重置爲默認值。 |
在用戶點擊見識版面的Reset按鈕或者首次添加該組件時被調用。此方法只在編輯模式下被調用。 |
Initialization |
Awake |
|
|
OnEnable |
|
|
|
Start |
Start在behaviour的生命週期中只被調用一次。它和Awake的不一樣是Start只在腳本實例被啓用時調用。你能夠按需調整延遲初始化代碼。Awake老是在Start以前執行。這容許你協調初始化順序。 |
Start僅在Update方法第一次被調用前調用。 |
|
Physics |
FixedUpdate |
處理Rigidbody時,須要用FixedUpdate代替Update。例如:給剛體加一個做用力時,你必須應用做用力在FixedUpdate裏的固定幀,而不是Update中的幀。(二者幀長不一樣) |
若是固定時間步長小於實際幀更新時間,那麼每一幀物理週期將會可能發生不止一次。 |
yield WaitForFixedUpdate |
|
||
Internal physics update |
|
||
OnTriggerXXX |
|
||
OnCollisionXXX |
|
||
Input events |
OnMouseXXX |
|
|
Game logic |
Update |
|
若是一個協成以前已經yield了,可是如今因爲恢復了,那麼將執行剩下的部分。 |
yield null |
|
||
yield WaitForSeconds |
|
||
yield WWW |
|
||
yield StartCoroutine |
|
||
Internal animation update |
|
||
LateUpdate |
|
||
Scene rendering |
OnWillRenderObject |
若是對象可見每一個相機都會調用它。此函數在消隱過程當中被調用,在渲染全部被消隱的物體以前被調用。你能夠用它來建立具備依賴性的紋理而且只有在被渲染的物體可見時才更新這個紋理。舉例來說,它已用於水組件中。 |
|
OnPreCull |
消隱決定哪一個物體對於相機來講是可見的.OnPreCull僅是在這個過程被調用。 |
只有腳本被附加到相機上時纔會調用這個函數。 |
|
OnBecameVisible |
|
|
|
OnBecameInvisible |
|
|
|
OnPreRender |
在相機渲染場景以前被調用。 |
只有腳本被附加到相機並被啓用時纔會調用這個函數。 |
|
OnRenderObject |
|
|
|
OnPostRender |
在相機完成場景渲染以後被調用。 |
只有該腳本附於相機並啓用時纔會調用這個函數。OnPostRender能夠是一個協同程序。 |
|
OnRenderImage |
|
|
|
Gizmo rendering |
OnDrawGizmos |
|
只在編輯模式下調用 |
GUI rendering |
OnGUI |
|
在每一幀更新時調用屢次 |
End of frame |
yield WaitForEndOfFrame |
|
|
Pausing |
OnApplicationPause |
|
在程序檢測到暫停時,會在幀的結尾處被調用。 |
Disable/enable |
OnDisable |
|
在腳本是失效時被調用,被銷燬時也會被調用。若是再啓用的話,OnEnable會再一次被調用。 |
Decommissioning |
OnDestroy |
|
|
OnApplicationQuit |
|
|
答:FixedUpdate由於不受到計算機幀頻的影響,因此適合於作物理方面的更新。
答:LateUpdate,它是在Update結束後才調用。通常來講攝像機的跟隨,都是在全部Update操做完成後進行的,以避免出現攝像機已經推動了,可是還有角色未刷新的空幀出現。
答:當物體是否可見切換之時。能夠用於只須要在物體可見時才進行的計算。
當renderer(渲染器)在任何相機上都不可見時調用:OnBecameInvisible
當renderer(渲染器)在任何相機上可見時調用:OnBecameVisible
答:PlayerPrefs.SetInt()
PlayerPrefs.GetInt()
答:單獨的動畫狀態,混合樹。
答:
動畫層中的權重是指某個動畫層在整個動畫中的影響,Weight的取值範圍爲(0~1)
若權重值爲1則此層動畫將與整個動畫融合
若權重值爲0則此層動畫與整個動畫徹底不融合
答:使用動畫層來管理身體不一樣部分的複雜狀態機。好比:你能夠使用下半身(動畫)層來管理走動/跑動;使用上半身(動畫)層來控制攻擊/揮手動做。
Animator anim ;
int idle = Animator.StringToHash("Base Layer.Idle");
AnimatorStateInfo currentBaseStage;
void Start () {
anim = GetComponent<Animator>();
}
void Update () {
currentBaseStage = anim.GetCurrentAnimatorStateInfo(0);
if (currentBaseStage.nameHash == idle && !anim.IsInTransition(0)) {
anim.SetBool("hit", false);
}
答:判斷當前播放的動畫名字如果默認層的Idle,而且沒有在進行動畫切換,則設置hit動畫參數爲false。
答案:9
答:動畫事件。
答:
1D是使用一個動畫參數來控制blend tree中幾個動畫判斷的融合,
2D是使用兩個動畫參數來控制blend tree中幾個動畫判斷的融合。
答:
public Camera myCamera;
myCamera.WorldToScreenPoint(hit);
答:網格尋路。
答:
1.Resources.Load();
2.AssetBundle
區別:
Resources資源的加載是動態加載內部的,AssetBundle 是動態加載外部的。
Resources是動態內部調用,Resources在編輯環境下是project窗口的一個文件夾,調用裏面的資源,能夠用Resources類,好比Resources.Load,打包後這個文件夾是不存在的,會統一輩子成Assets資源。
AssetBundle 是外部調用,要用AssetBundle 首先要先把資源打包爲.assetbundle文件,再動態的去加載這個文件,本地或者網絡服務器均可以。
WWW讀取文件
答: MonoBehaviour.OnLevelWasLoaded
答:Destory
答:獲取:GetComponent
增長:AddComponent
沒有刪除組件只有讓組件不生效:enable
答:加載關卡 。
UnityEngine.SceneManagement名稱空間下
SceneManager.LoadScene//加載場景
SceneManager.LoadSceneAsync//異步加載場景
答: Debug.Log();
答:層索引。射線。
答:
localPosition:自身位置,相對於父級物體的變換的位置,局部座標其實就是自身的座標。
Position:在世界座標transform的位置,世界座標是不會變的,一直以世界座標軸的XYZ爲標準。
答:Transform.Rotate()。
答:
public class TestAround : MonoBehaviour
{
public GameObject ObjA;
public GameObject ObjB;
Vector3 NormalVector3;//法線
float speed = 5;
void Start()
{
GetNormal(AroundType.Horizontal);
}
private void GetNormal(AroundType aroundType)
{
Vector3 temp = ObjB.transform.position - ObjA.transform.position;
switch (aroundType)
{
case AroundType.Vertical:
NormalVector3=Vector3.Cross(Vector3.forward,temp);
break;
case AroundType.Horizontal:
NormalVector3 = Vector3.Cross(Vector3.up, temp);
break;
default:
break;
}
}
void Update()
{
Debug.DrawLine(NormalVector3,ObjA.transform.position);
Vector3 temp = ObjB.transform.position - ObjA.transform.position;
Debug.DrawLine(temp, ObjA.transform.position);
Around(ObjA, ObjB);
}
private void Around(GameObject objA, GameObject objB)
{
Quaternion quater=Quaternion.Euler( NormalVector3*Time.deltaTime*speed);
objB.transform.position = quater * objB.transform.position;
}
}
enum AroundType
{
Vertical,
Horizontal
}
答:Transform 父類是 Component
答:添加剛體使小鳥模擬受到重力和空氣阻力影響。不添加剛體的話寫受力分析。
設橫軸爲方向的加速度爲ax,垂直軸爲ay。
小鳥的Vx,Vy
Vx=Vx+t*ax;(Vx>=0)
Vy=Vy+t*ay;
答:PhysicMaterial 物理材質:主要是控制物體的摩擦,彈力等物理屬性。
Material材質:主要是控制一個物體的顏色,質感等顯示。
答:rigidbody.AddForce/AddForceAtPosition,都在rigidbody系列函數中。
答:Hinge Joint,能夠模擬兩個物體間用一根鏈條鏈接在一塊兒的狀況,能保持兩個物體在一個固定距離內部相互移動而不產生做用力,可是達到固定距離後就會產生拉力。
答: Unity內一種用於實現自動尋路的網格。
答: JavaScript,C#,Boo
答:1)點乘計算兩個向量之間的夾角,還可表示某一方向的投影。
2)叉乘獲得的是法向量。
3)標準化向量:用在只關係方向,不關心大小的時候。
答:用於表示線性變換:旋轉、縮放、投影、平移、仿射。
注意:矩陣的蠕變:偏差的積累。
答:Unicode是國際組織制定的能夠容納世界上全部文字和符號的字符編碼方案。
使用動態字體時,Unity將不會預先生成一個與全部字體的字符紋理。當須要支持亞洲語言或者較大的字體的時候,若使用正常紋理,則字體的紋理將很是大。
答:render是渲染器,渲染器能夠使物體顯示在屏幕上。
MeshRender是網格渲染,SkinnedMeshRender是蒙皮網格渲染器
答:骨骼蒙皮動畫,模型自己是靜態的,是由於經過蒙皮,使模型每一個點都有Skin數據,Skin數據包括頂點受到哪些骨骼影響以及這些骨骼影響頂點的權重值,還有動畫數據,有了Skin數據的模型就能夠根據動畫數據進行顯示動畫了。
答:1)將Assets目錄和Library目錄一塊兒遷移。
2)導出包。
3)用unity自帶的assets Server功能。
答:LOD是Level of detail簡稱,意爲多層次細節,是最經常使用的遊戲優化技術,LOD技術指根據物體模型的幾點在顯示環境中所處的位置和重要性,決定物體渲染的資源分配,下降非重要物體的面數和細節度,從而得到高效率的渲染運算。
優勢:可根據距離動態的選擇渲染不一樣細節的模型
缺點:增長美工工做量,增大了遊戲的容量。
注:精簡文字描述。
答:LOD(Level of detail)多層次細節,是最經常使用的遊戲優化技術,LOD技術指根據物體模型的幾點在顯示環境中所處的位置和重要性,決定物體渲染的資源分配,下降非重要物體的面數和細節度,從而得到高效率的渲染運算。
優勢:可根據距離動態的選擇渲染不一樣細節的模型
缺點:增長美工工做量,增大了遊戲的容量。
答:自身陰影:因物體自身的遮擋而使光線照射不到它上面的某些可見面
工做原理:利用背面剔除的方法求出,即假設視點在點光源的位置。
投射陰影:因不透明物體遮擋光線使得場景中位於該物體後面的物體或區域收不到光照照射而造成的陰影。
工做原理:從光源處向物體的全部可見面投射光線,將這些面投影到場景中獲得投影面,再將這些投影面與場景中的其餘平面求交得出陰影多邊形,保存這些陰影多邊形信息,而後在按視點位置對場景進行相應處理獲得所要求的視圖(利用空間換時間,每次只需依據視點位置進行一次陰影計算便可,省去了一次消隱過程)如果動態光源此方法就無效了。
答:MipMapping:在三維計算機圖形的貼圖渲染中有經常使用的技術,爲加快渲染進度和減小圖像鋸齒,貼圖被處理成由一系列被預先計算和優化過的圖片組成的文件,這樣的貼圖被稱爲MipMap。
答:指定身體的某一部分是否參與渲染
答:須要獲得Mono.Data.Sqlite.dll 文件與System.Data.dll文件。
答:1.壓縮自帶類庫;
2.將暫時不用的之後還須要使用的物體隱藏起來而不是直接Destroy掉;
3.釋放AssetBundle佔用的資源;
4.下降模型的片面數,下降模型的骨骼數量,下降貼圖的大小;
5.使用光照貼圖;
6.使用多層次細節(LOD);
7.使用着色器(Shader);
8.使用預設(Prefab)等。
解析:內存開銷無外乎三大部分:1.資源內存佔用;2.引擎模塊自身內存佔用;3.託管堆內存佔用
在一個較爲複雜的大型項目中,資源的內存佔用每每佔據了整體內存的70%以上。所以,資源使用是否恰當直接決定了項目的內存佔用狀況。通常來講,一款遊戲項目的資源主要能夠分爲如下幾種:紋理(Texture),網絡(Mesh),動畫片斷(AnimationClip)、音頻片斷(AudioClip)、材質(Material)、着色器(shader)、字體資源(Font)以及文本資源(TextAsset)等等。其中,紋理,網格、動畫片斷和音頻片斷則容易形成較大內存開銷的資源。
紋理資源能夠說是幾乎全部遊戲項目中佔據最大內存開銷的資源。一個6萬片的場景,網格資源最大才不過10MB,但一個2048*2048的紋理,可能直接就達到16MB,所以,項目中紋理資源的使用是否恰當會及大地印象項目的內存佔用。
那麼,紋理資源再使用時應該注意哪些地方呢?
紋理格式。紋理格式是研發團隊最須要關注的紋理屬性。由於它不只影響紋理的內粗你佔用,同時還決定了紋理的加載效率。通常來講,咱們建議開發團隊儘量根據硬件的種類選擇硬件支持的紋理格式好比Android平臺的ETC、iOS平臺的PVRTC、WindowsPC上的DXT等等。所以,咱們在UWA測評報告中,將紋理格式進行了羅列,一邊開發團隊進行快速查找,一步定位。
在使用硬件支持的紋理格式時,你可能會遇到如下幾個問題:
色階問題
因爲ETC、PVRTC等格式均爲有損壓縮,所以,當紋理色差範圍跨度較大時,均不可避免地形成不一樣程度的階梯狀的色階問題。所以,不少研發團隊使用RGBA32/ARGB32格式來實現更好的效果。可是,這種作法將形成很大的內存佔用。好比,一樣一張1024*1024的紋理,若是不開啓Mipmap,而且爲PVRTC格式,則其內存佔用爲512KB,而若是轉換爲RGBA32位,則極可能佔用更達到4MB。因此,研發團隊在使用RGBA32或ARGB32格式的紋理時,必定要慎重考慮,更爲明智的選擇是儘可能減小紋理的色差範圍,時期儘量使用硬件支持的壓縮格式進行存儲。
ETC1不支持透明通道問題
在Android平臺上,對於使用OpenGLES2.0的設備,其紋理格式僅能支持ETC1格式,該格式有個較爲嚴重的問題,即不支持Alpha透明通道,使得透明貼圖沒法直接經過ETC1格式來進行存儲。對此。咱們建議研發團隊將透明貼圖儘量分紅兩張,即一張RGB24位紋理記錄原始紋理的顏色部分和一張Alpha8紋理記錄原始紋理的透明通道部分。而後,將這輛張貼圖分別轉化爲ETC1格式的紋理,並經過特定的Shader來進行渲染,從而來達到支持透明貼圖的效果。該種方法不只能夠極大程度上逼近RGBA透明貼圖的渲染效果,同時還能夠下降紋理的內存佔用,是咱們很是推薦的使用方式。
固然,目前已經有愈來愈多的設備支持了OpenGLES3.0這樣Android平臺上你能夠進一步使用ETC2甚至ASTC,這些紋理格式均爲支持透明通道且壓縮比更爲理想的紋理格式。若是你的遊戲適合人羣爲中高端設備用戶,那麼不妨直接使用這兩種格式來做爲主要存儲格式。
紋理尺寸
通常來講,紋理尺寸越大,佔用內存越大。
Mipmap功能
Mipmap旨在有效下降渲染帶寬的壓力,提高遊戲的渲染效率。可是,開啓Mipmap會有將紋理內存提高1.33倍。對於具備較大縱深感的3D遊戲來講,3D場景模型和角色咱們通常是建議開啓Mipmap功能的,但不少2DUI紋理就沒必要要了。
Read&Write
通常狀況下,文理資源「Read&Write」功能在Unity引擎中是默認關閉的。可是,咱們仍然在項目深度優化時發現了很多項目的紋理資源會開啓該選項。對此,咱們建議壓發團隊密切關注文理資源中該選項的使用,由於開啓該選項將會使文理內存增大一倍。
網格資源在比較複雜的遊戲中,每每佔據較高的內存。對於網格資源來講,它在使用時應該注意那方面呢?
1) Normal\Color和Tangent(切線)
在咱們深度優化過的大量項目中,Mesh資源的數據常常會含有大量的Color數據,Normal數據和Tangent數據。這些數據的存在將大幅增長Mesh資源的文件體積和內存佔用。其中Color數據和Normal數據主要爲3DMax、Maya等建模軟件導出時設計所生成,而Tangent通常爲導入引擎時生成。
更爲麻煩的是,若是項目對Mesh進行DrawCallBatching操做的話,那麼狠有可能進一步增長整體內存的佔用。正因如此,咱們在UWA測評報告中爲每一個Mesh展現了其Normal,Color和Tangent屬性的具體使用狀況,研發團隊能夠直接針對每種屬性進行排序查看,直接定位出現冗餘數據的資源。通常來講這些數據主要爲Shader所用,來生成較爲酷炫的效果。因此,建議研發團隊針對項目中的網格資源進行詳細檢測,查看該模型的渲染Shader中是否須要這些數據進行渲染。
答:
解析:CPU方面
就目前Unity移動遊戲而言,CPU方面的性能開銷主要可歸結爲兩大類:引擎模塊性能開銷和自身代碼性能開銷。其中,引擎模塊中又可細緻劃分爲渲染模塊、動畫模塊、物理模塊、UI模塊、粒子系統、加載模塊和GC調用等等。
經過大量的性能測評數據,咱們發現渲染模塊、UI模塊和加載模塊,每每佔用了CPU性能開銷的Top3。
1下降DrawCall
下降DrawCall的方法則主要是減小渲染物體的材質種類,並經過DrawCallBatching來減小其數量。Unity文檔對DrawCallBatching的原理和注意事項很是詳盡,感興趣的朋友能夠直接查看Unity官方文登。
可是,須要注意的是遊戲性能並不是DrawCall越小越好。這是由於,決定渲染模塊心梗的除了DrawCall以外,還有用於傳輸渲染數據的總先帶寬。當咱們使用DrawCallBatching將同種的材質和網絡模型拼合在儀器室,可能會形成同一時間須要傳輸的數據(Texture、VB/IB等)大大增長,以致於形成堵塞。在資源沒法計時傳輸過去的狀況下,GPU只能等待,從而反倒下降了遊戲的運行幀率。
DrawCall和總線帶寬是天平的兩端,咱們須要作的是儘量維持天平的平衡,任何一邊太高或太低,對性能來講都是無益的。
2簡化資源
簡化資源師很是行之有效的優化手段。在大量的移動遊戲中,其渲染資源實際上是過量的。過量的過量的網絡資源、不合規的紋理資源等等。
關於渲染模塊在CPU方面的優化方法還有不少,好比LOD、Occlusion Culling和Culling Distance等等。
2 UI模塊
UI模塊一樣也是幾乎全部的遊戲項目中必備的模塊。一個性能優異的UI模塊能夠將遊戲的用戶體驗再擡高一個檔次。
在NGUI優化方面,UIPanel.LateUpdate爲性能優化的重中之重。
對於UIPanel.LateUpdate的優化,主要着眼與UIPanel的佈局,其原則以下:
儘量將動態UI元素和靜態UI元素分離到不一樣的UIPanel中,從而儘量將由於變更的UI元素引發的衝歐控制在較小的範圍內;
儘量讓動態UI元素按照同步性進行劃分,即運動幀率不一樣的UI元素儘量分離放在不一樣的UIPanel中;
控制同一個UIPanel中動態UI元素的數量,數量越多,所建立的Mesh越大,從而使得重構的開銷曾加。好比戰鬥過程當中的HUD運動協調會出現的比較多,此時,建議研發團隊將運動血條分離成不一樣的UIPanel,每組UIPanel下5~10個動態UI爲宜。這種作法,其本質是從機率上儘量下降單振中UIPanel的重建開銷。
3加載模塊
加載模塊一樣也是任何遊戲項目中所不可缺乏的組成成分。與以前兩個模塊不一樣的是,加載模塊的性能開銷比較集中,主要出現於場景切換處,且CPU佔用峯值均較高。
這裏,咱們先來講說場景切換時,其性能開銷的主要體現形式。對於目前的Unity版本而言,場景切換時的主要性能開銷主要體如今兩個方面,前一場景的場景卸載和下一場景的場景加載。下面,咱們就具體來講說兩個方面的性能瓶頸:
1場景卸載,對於Unity引擎而言,場景卸載通常是由引擎自動完成的,即當咱們調用相似Application.LoadLevel的API時,引擎即會開始對上一場景進行處理,其性能開銷主要被如下幾部分佔據。
Destroy
引擎在切換場景時會手機爲表示成DontDestoryOnLoad的GameObject及其Component,而後進行Destroy。同時,代碼中的OnDestory被觸發執行,這裏的性能開銷主要取決於OnDestroy回調函數中的代碼邏輯。
Resources.UnloadUnusedAssets
通常狀況下,場景切換過程當中,該API會被調用兩次,依次爲引擎在切換場景是自動調用,另外一次則爲用戶手動調用(通常出如今場景加載後,用戶調用它來確保上一場景的資源被卸載乾淨)。在咱們測評過的大量項目中,該API的CPU開銷主要集中在500ms~3000m之間。其耗時開銷主要取決於場景中Asset和Object的數量,數量越多,則耗時越慢。
2場景加載
場景加載過程的性能開銷又可細分紅如下幾個部分:
資源加載
資源加載幾乎佔據整個加載過程的90%以上,其加載效率主要取決於資源的加載方式(Resource.Load或AssetBundle加載)、加載量(紋理、網格、材質等資源數據的大小)和資源格式(紋理、音頻格式等)。不一樣的加載方式、不一樣的資源格式,其加載效率可謂千差萬別。
Instantiate實例化
在場景加載過程當中,每每伴隨着大量的Instantiate實例化操做。在Instantiate實例化時,引擎底層會查看相關的資源是否已經被加載,若是沒有,則會先加載其相關資源,再進行實例化,這實際上是你們遇到大多數「Instantiate」實例化問題的根本緣由。
AssetBundle文章中所提倡的資源依賴關係打包並進行預加載,從而來緩解Instantiate實例化的壓力。
另外一方面,Instantiate實例化的性能開銷還體如今腳本代碼的序列化上,若是腳本中序列化的信息不少,則Instantiate實例化時的時間亦會很長。最直接的例子就是NGUI,其代碼中存在不少SerializedField標識,從而在實例化時帶來了較多的代碼序列化開銷。所以,在打架增長序列化信息時,這一點是須要你們時刻關注的
以上是遊戲項目中性能開銷最大的三個模塊,固然,遊戲類型的不一樣、設計的不一樣,其餘模塊仍然會有較大的CPU佔用。好比ARPG遊戲中動畫系統和物理系統,音樂休閒類遊戲中的音頻系統和例子系統等。
4 代碼效率
邏輯代碼在一個較爲複雜的遊戲項目中每每佔據較大的CPU開銷。這種狀況在MOBA\ARPG\MMORPG等遊戲類型中很是常見。
在項目優化過程當中,咱們常常會想知道,到底哪些函數佔據了大量的CPU開銷。同時,絕大多數的項目其中性能開銷都遵循着「二八原則」,即80%的性能消耗都集中在20%的函數上。
答:
插件功能 |
插件名稱 |
界面製做 |
NGUI |
2D遊戲製做 |
2D Toolkit |
可視化編程 |
PlayMaker |
插值插件 |
iTween、HOTween |
路徑搜尋 |
SimplePath |
美術及動畫製做 |
RageSpline、Smooth Moves |
畫面加強 |
Bitmap2Material、Strumpy Shader Editor |
攝像機管理 |
Security Camera |
資源包 |
Nature Pack |
造路插件 |
EasyRoads3D |
即時遮擋剔除/LOD多細節層次 |
Instant Occlusion Culling |
答:是指在顯示器上爲了顯示出圖像而通過的一系列必要操做。
渲染管道中的不少步驟,都要將幾何物體從一個座標系中變換到另外一個座標系中去。
主要有三步:應用程序階段,幾何階段 光柵階段
本地座標->視圖座標->背面裁剪->光照->裁剪->投影->視圖變換->光柵化。
答:計算機中顯示的圖形通常能夠分爲兩大類——矢量圖和位圖。矢量圖使用直線和曲線來描述圖形,這些圖形的元素是一些點、線、矩形、多邊形、圓和弧線等等,它們都是經過數學公式計算得到的。例如一幅花的矢量圖形其實是由線段造成外框輪廓,由外框的顏色以及外框所封閉的顏色決定顯示出的顏色。因爲矢量圖形可經過公式計算得到,因此矢量圖形文件體積通常較小。矢量圖形最大的優勢是不管放大、縮小或旋轉等不會失真;最大的缺點是難以表現色彩層次豐富的逼真圖像效果。
答:矩陣:橫軸排列的二維數據表格
矩陣運算:
加減 限制條件:行和列必須相同,對應相加相減獲得結果
乘法 限制條件:要求左矩陣的行和右矩陣的列必須同,行數和左矩陣相等,列數和右矩陣相等,結果的第i行第j列,是左矩陣的第i行和右矩陣的第j列逐個相乘並把結果相加,獲得結果是結果 的 第i行第j列。
答:角度和弧度
度和弧度之間的換算 1弧度 = 180度 /pi(約57.3)
1度=pi/180弧度(約0.017)
答:矢量有方向如力速度 標量只有大小沒有方向如溫度
矢量取模就是隻要大小不要方向
單位向量 有方向 大小爲1的向量
矢量的加法:是矢量的幾何和,服從平行四邊形規則
矢量知足交換律,知足結合律
在直角座標系中,矢量等於騎在座標軸上投影的矢量之和(二維矢量能夠看作三維矢量的特例也就是說,三維成立,二維也成立)
矢量減法:
大小相等 方向相反 稱爲逆矢量。
任意多個矢量首尾相鏈接組成閉合多邊形,其結果必爲0
矢量的乘法:點積(內積、標量積)、叉積(外積)結果是矢量
點積方法 dot
注:這題要問什麼?
答:
1.Resources
2.AssetBundle
3.WWW
答:實時光源會對性能有影響,解決方案有如下幾種:
1使用unity的烘焙系統烘焙替代實時光源。
2使用三維建模軟件的烘焙系統烘焙代替實時光源。
3通常移動端開發實時光源只爲了提供實時陰影效果,因此設置實施光照的有效層。
答:
Time.timeScale = 0;便可讓遊戲暫停。
Time.timeScale = 1時,Update、LateUpdate、FixedUpdate 都按正常的時間來執行。
Time.timeScale = 2時,Update和 LateUpdate的執行速度是以前的2倍,而FixedUpdate仍是按正常時間來執行
答:Prefab能夠理解爲是一個遊戲對象及其組件的集臺,做用是使遊戲對象及資源可以被重複使用。相同的對象能夠經過一個預設來建立,此過程可理解爲實例化,預設能夠進行批量修改。
答:NGUI 很好的解決了這一點,屏幕分辨率的自適應性,原理就是計算出屏幕的寬高比跟原來的預設的屏幕分辨率求出一個對比值,而後修改攝像機的 size 。
注:
答:
SceneManager.LoadScene//加載場景
SceneManager.LoadSceneAsync//異步加載場景
答:一、表面着色器(surface shaders)
一般狀況下用戶都會使用這種Shader,它能夠與燈光、陰影、投影器進行交互。表面着色器的抽象層次比較高,它能夠容易地以簡潔方式實現複雜的着色器效果。表面着色器可同時正常工做在前向渲染及延遲渲染模式下。表面着色器以句Cg/HLsL語言進行編寫。
二、頂點和片斷着色器(Vertex and fragment Shaders)
若是須要一些表面着色器沒法處理的酷炫效果,或者編寫的Shader不須要與燈光進行交互,或是想要的只是全屏圖像效果,那麼能夠使用頂點和片斷着色器。這種Shader能夠很是靈活地實現須要的效果,可是須要編寫更多的代碼,而且很難與Unity的渲染管線完美集成。頂點和片斷着色器一樣是用Cg/HLsL語言來編寫。
三、固定功能管線着色器(Fixed Function Shaders)
若是遊戲要運行在不支持可編程管線的老舊硬件上,那麼須要編寫這種Shader了。固定功能管線着色器能夠做爲片斷或表面着色器的備用選擇,這在當硬件沒法運行那些酷炫Shader的時候,還能夠經過固定功能管線着色器來繪製出一些基本的內容。固定功能管線着色器徹底以ShaderLab語言編寫,相似於微軟的Effects或是Nvidia的CgFX。
答:UI紋理不須要強制使用2次冪,以NGUI舉例,NGUI會製做圖集,圖集是2次冪的。
答:
碰撞器(Collider)有碰撞效果,IsTrigger=false,能夠調用OnCollisionEnter/Stay/Exit函數
觸發器(Trigger)沒有碰撞效果,isTrigger=true,能夠調用OnTriggerEnter/Stay/Exit函數
答:TCP是基於鏈接的,UDP基於無鏈接的
TCP對系統資源的要求多,UDP較少
UDP程序結構較簡單
TCP是面向流數據的,UDP是數據報
TCP保證數據正確性,UDP可能丟包。
TCP保證數據的順序,UDP不保證。
答:這是由於服務段的LISTEN狀態下的SOCKET當收到SYN報文的創建請求後,它能夠把ACK和SYN(ACK起應答做用,而SYN起同步做用)放在一個報文裏來發送。但關閉鏈接時,當收到對方的FIN報文通知時,它僅僅表示對方沒有數據發送給你了;但未必你全部的數據都所有發送給對方了,因此你未必會立刻關閉SOCKET,也即你可能還須要發送一些數據給對方以後,再發送FIN報文給對方來表示你贊成如今能夠關閉鏈接了,因此它這裏的ACK報文和FIN報文多數狀況下都是分開發的。
答:這是由於雖然雙反都贊成關閉鏈接了,並且握手的4個報文也都協調和發送完畢,案例能夠直接回到CLOSED狀態(就比如從SYN_SEND狀態到ESTABLISH狀態那樣);可是由於咱們必需要家鄉網絡是不可靠的,你沒法保證你最後發送的ACK報文會必定被對方收到,所以對方處於LASK_ACK狀態下的SOCKET可能會由於超時未收到ACK報文,而重發FIN報文,因此這個TIME_WAIT狀態的做用就是來重發可能都是的ACK報文。
答:角色控制器中Move和SimpleMove函數都是用於實現角色遊戲對象移動的函數,它們的區別在於當咱們在每一幀調用SimpleMove函數時,引擎將爲該角色控制器對象添加一個重力,而Move函數則不會添加劇力,須要咱們經過代碼去實現重力的效果。
答:遊戲引擎是指一些已經編寫好的可編輯電腦遊戲系統或者一些交互式實時圖像應用程序的核心組件。這些系統爲遊戲設計者提供各類編寫遊戲所須要的各類工具,其目的在於讓遊戲設計者能容易和快速地作出遊戲程序而不用由零開始。大部分都支持多種操做系統平臺,如Linux、Mac OS、微軟Windows。遊戲引擎包含如下系統:渲染引擎(即「渲染器」,含二維圖像引擎和三維圖像引擎)、物理引擎、碰撞檢測系統、音效、腳本引擎、電腦動畫、人工智能、網絡引擎以及場景管理。
1.Editor
Editor文件夾能夠在根目錄下,也能夠在子目錄裏,只要名子叫Editor就能夠。好比目錄:/xxx/xxx/Editor 和 /Editor 是同樣的,不管多少個叫Editor的文件夾均可以。Editor下面放的全部資源文件或者腳本文件都不會被打進發布包中,而且腳本也只能在編輯時使用。通常呢會把一些工具類的腳本放在這裏,或者是一些編輯時用的DLL。 好比咱們如今要作相似技能編輯器,那麼編輯器的代碼放在這裏是再好不過了,由於實際運行時咱們只須要編輯器生成的文件,而不須要編輯器的核心代碼。
2.Editor Default Resources
Editor Default Resources注意中間是有空格的,它必須放在Project視圖的根目錄下,若是你想放在/xxx/xxx/Editor Default Resources 這樣是不行的。你能夠把編輯器用到的一些資源放在這裏,好比圖片、文本文件、等等。它和Editor文件夾同樣都不會被打到最終發佈包裏,僅僅用於開發時使用。
3.Gizmos
我以爲這個文件夾其實沒什麼用處,以下代碼所示它能夠在Scene視圖裏給某個座標繪製一個icon。它的好處是能夠傳一個Vecotor3 做爲圖片顯示的位置。
4.Plugins
若是作手機遊戲開發通常 andoird 或者 ios 要接一些sdk 能夠把sdk依賴的庫文件 放在這裏,好比 .so .jar .a 文件。這樣打完包之後就會自動把這些文件打在你的包中。
5.Resources
能夠在根目錄下,也能夠在子目錄裏,只要名子叫Resources就能夠。好比目錄:/xxx/xxx/Resources 和 /Resources 是同樣的,不管多少個叫Resources的文件夾均可以。Resources文件夾下的資源無論你用仍是不用都會被打包進.apk或者.ipa
Resource.Load :編輯時和運行時均可以經過Resource.Load來直接讀取。
Resources.LoadAssetAtPath() :它能夠讀取Assets目錄下的任意文件夾下的資源,它能夠在編輯時或者編輯器運行時用,它可是它不能在真機上用,它的路徑是」Assets/xx/xx.xxx」 必須是這種路徑,而且要帶文件的後綴名。
AssetDatabase.LoadAssetAtPath():它能夠讀取Assets目錄下的任意文件夾下的資源,它只能在編輯時用。它的路徑是」Assets/xx/xx.xxx」 必須是這種路徑,而且要帶文件的後綴名。
我以爲在電腦上開發的時候儘可能來用Resource.Load() 或者 Resources.LoadAssetAtPath() ,假如手機上選擇一部分資源要打assetbundle,一部分資源Resource.Load().那麼在作.apk或者.ipa的時候 如今都是用腳原本自動化打包,在打包以前 能夠用AssetDatabase.MoveAsset()把已經打包成assetbundle的原始文件從Resources文件夾下移動出去在打包,這樣打出來的運行包就不會包行多餘的文件了。打完包之後再把移動出去的文件夾移動回來。
6. StreamingAssets
這個文件夾下的資源也會全都打包在.apk或者.ipa 它和Resources的區別是,Resources會壓縮文件,可是它不會壓縮原封不動的打包進去。而且它是一個只讀的文件夾,就是程序運行時只能讀不能寫。它在各個平臺下的路徑是不一樣的,不過能夠用Application.streamingAssetsPath 它會根據當前的平臺選擇對應的路徑。
有些遊戲爲了讓全部的資源所有使用assetbundle,會把一些初始的assetbundle放在StreamingAssets目錄下,運行程序的時候在把這些assetbundle拷貝在Application.persistentDataPath目錄下,若是這些assetbundle有更新的話,那麼下載到新的assetbundle在把Application.persistentDataPath目錄下原有的覆蓋掉。
由於Application.persistentDataPath目錄是應用程序的沙盒目錄,因此打包以前是沒有這個目錄的,直到應用程序在手機上安裝完畢纔有這個目錄。
StreamingAssets目錄下的資源都是不壓縮的,因此它比較大會佔空間。
http://www.xuanyusong.com/archives/3229