1. 程式人生 > >Unity全面的面試題(包含答案)

Unity全面的面試題(包含答案)

這個是我剛剛整理出的Unity面試題,為了幫助大家面試,同時幫助大家更好地複習Unity知識點,如果大家發現有什麼錯誤,(包括錯別字和知識點),或者發現哪裡描述的不清晰,請在下面留言,我會重新更新,希望大家共同來幫助開發者

一:什麼是協同程式?

在主執行緒執行的同時開啟另一段邏輯處理,來協助當前程式的執行,協程很像多執行緒,但是不是多執行緒,Unity的協程實在每幀結束之後去檢測yield的條件是否滿足。

二:Unity3d中的碰撞器和觸發器的區別?

碰撞器是觸發器的載體,而觸發器只是碰撞器身上的一個屬性。當Is Trigger=false時,碰撞器根據物理引擎引發碰撞,產生碰撞的效果,可以呼叫OnCollisionEnter/Stay/Exit函式;當Is Trigger=true時,碰撞器被物理引擎所忽略,沒有碰撞效果,可以呼叫OnTriggerEnter/Stay/Exit函式。如果既要檢測到物體的接觸又不想讓碰撞檢測影響物體移動或要檢測一個物件是否經過空間中的某個區域這時就可以用到觸發器

三:物體發生碰撞的必要條件?

兩個物體都必須帶有碰撞器(Collider),其中一個物體還必須帶有Rigidbody剛體,而且必須是運動的物體帶有Rigidbody指令碼才能檢測到碰撞。

四:請簡述ArrayList和List的主要區別?

ArrayList存在不安全型別(ArrayList會把所有插入其中的資料都當做Object來處理),裝箱拆箱的操作(費時),List是泛型類,功能跟ArrayList相似,但不存在ArrayList所說的問題。

五:如何安全的在不同工程間安全地遷移asset資料?三種方法

1.將Assets目錄和Library目錄一起遷移

2.匯出包,export Package

3.用unity自帶的assets Server功能

六:OnEnable、Awake、Start執行時的發生順序?哪些可能在同一個物件週期中反覆的發生

Awake –>OnEnable->Start,OnEnable在同一週期中可以反覆地發生。

七:MeshRender中material和sharedmaterial的區別?

修改sharedMaterial將改變所有物體使用這個材質的外觀,並且也改變儲存在工程裡的材質設定。不推薦修改由sharedMaterial返回的材質。如果你想修改渲染器的材質,使用material替代。

八:Unity提供了幾種光源,分別是什麼

四種。

平行光:Directional Light

點光源:Point Light

聚光燈:Spot Light

區域光源:Area Light

九:簡述一下物件池,你覺得在FPS裡哪些東西適合使用物件池

物件池就存放需要被反覆呼叫資源的一個空間,當一個物件回大量生成的時候如果每次都銷燬建立會很費時間,通過物件池把暫時不用的物件放到一個池中(也就是一個集合),當下次要重新生成這個物件的時候先去池中查詢一下是否有可用的物件,如果有的話就直接拿出來使用,不需要再建立,如果池中沒有可用的物件,才需要重新建立,利用空間換時間來達到遊戲的高速執行效果,在FPS遊戲中要常被大量複製的物件包括子彈,敵人,粒子等

十:CharacterController和Rigidbody的區別

Rigidbody具有完全真實物理的特性,Unity中物理系統最基本的一個元件,包含了常用的物理特性,而CharacterController可以說是受限的的Rigidbody,具有一定的物理效果但不是完全真實的,是Unity為了使開發者能方便的開發第一人稱視角的遊戲而封裝的一個元件

十一:簡述prefab的用處

在遊戲執行時例項化,prefab相當於一個模板,對你已經有的素材、指令碼、引數做一個預設的配置,以便於以後的修改,同時prefab打包的內容簡化了匯出的操作,便於團隊的交流。

十二:請簡述sealed關鍵字用在類宣告時與函式宣告時的作用

sealed修飾的類為密封類,類宣告時可防止其他類繼承此類,在方法中宣告則可防止派生類重寫此方法。

十三:請簡述private,public,protected,internal的區別

public:對任何類和成員都公開,無限制訪問

private:僅對該類公開

protected:對該類和其派生類公開

internal:只能在包含該類的程式集中訪問該類

十四:使用Unity3d實現2d遊戲,有幾種方式?

  1. 使用本身的GUI,在Unity4.6以後出現的UGUI

2.把攝像機的Projection(投影)值調為Orthographic(正交投影),不考慮z軸;

3.使用2d外掛,如:2DToolKit,和NGUI

十五:在物體發生碰撞的整個過程中,有幾個階段,分別列出對應的函式

三個階段,1.OnCollisionEnter 2.OnCollisionStay 3.OnCollisionExit

十六:Unity3d的物理引擎中,有幾種施加力的方式,分別描述出來

rigidbody.AddForce/AddForceAtPosition,都在rigidbody系列函式中。大家可以自己去檢視一下rigidbody的API

十七:什麼叫做鏈條關節?

Hinge Joint,可以模擬兩個物體間用一根鏈條連線在一起的情況,能保持兩個物體在一個固定距離內部相互移動而不產生作用力,但是達到固定距離後就會產生拉力。

十八:物體自身旋轉使用的函式?

Transform.Rotate()

十九:Unity3d提供了一個用於儲存和讀取資料的類(PlayerPrefs),請列出儲存和讀取整形資料的函式

PlayerPrefs.SetInt() PlayerPrefs.GetInt()

二十:Unity3d指令碼從喚醒到銷燬有著一套比較完整的生命週期,請列出系統自帶的幾個重要的方法。

Awake——>OnEnable–>Start——>Update——>FixedUpdate——>LateUpdate——>OnGUI——>OnDisable——>OnDestroy

二十一:物理更新一般放在哪個系統函式裡?

FixedUpdate,固定時間間隔執行 可以在edit->project setting->time設定 update 是在渲染幀執行,和Update不同的是FixedUpdate是渲染幀執行,如果你的渲染效率低下的時候FixedUpdate呼叫次數就會跟著下降。FixedUpdate比較適用於物理引擎的計算,因為是跟每幀渲染有關。Update就比較適合做控制。

二十二:在場景中放置多個Camera並同時處於活動狀態會發生什麼?

遊戲介面可以看到很多攝像機的混合。

二十三:如何銷燬一個UnityEngine.Object及其子類?

使用Destroy()方法;

二十四:請描述為什麼Unity3d中會發生在元件上出現數據丟失的情況

一般是元件上繫結的物體物件被刪除了

二十五:LOD是什麼,優缺點是什麼?

LOD(Level of detail)多層次細節,是最常用的遊戲優化技術。它按照模型的位置和重要程度決定物體渲染的資源分配,降低非重要物體的面數和細節度,從而獲得高效率的渲染運算。缺點是增加了記憶體。

二十六:MipMap是什麼,作用?

MipMapping:在三維計算機圖形的貼圖渲染中有常用的技術,為加快渲染進度和減少影象鋸齒,貼圖被處理成由一系列被預先計算和優化過的圖片組成的檔案,這樣的貼圖被稱為MipMap。

二十七:請描述Interface與抽象類之間的不同

抽象類表示該類中可能已經有一些方法的具體定義,但介面就是公公只能定義各個方法的介面 ,不能具體的實現程式碼在成員方法中。類是子類用來繼承的,當父類已經有實際功能的方法時該方法在子類中可以不必實現,直接引用父類的方法,子類也可以重寫該父類的方法。實現介面的時候必須要實現介面中所有的方法,不能遺漏任何一個。

二十八:.Net與Mono的關係?

mono是.net的一個開源跨平臺工具,就類似java虛擬機器,java本身不是跨平臺語言,但執行在虛擬機器上就能夠實現了跨平臺。.net只能在windows下執行,mono可以實現跨平臺跑,可以運行於linux,Unix,Mac OS等。

二十九:簡述Unity3D支援的作為指令碼的語言的名稱

Unity的指令碼語言基於Mono的.Net平臺上執行,可以使用.NET庫,這也為XML、資料庫、正則表示式等問題提供了很好的解決方案。Unity裡的指令碼都會經過編譯,他們的執行速度也很快。這三種語言實際上的功能和執行速度是一樣的,區別主要體現在語言特性上。JavaScript、 C#、Boo

三十:U3D中用於記錄節點空間幾何資訊的元件名稱,及其父類名稱

Transform 父類是 Component

三十一:向量的點乘、叉乘以及歸一化的意義?

1.點乘描述了兩個向量的相似程度,結果越大兩向量越相似,還可表示投影

2.叉乘得到的向量垂直於原來的兩個向量

3.標準化向量:用在只關係方向,不關心大小的時候

三十二:為何大家都在移動裝置上尋求U3D原生GUI的替代方案

不美觀,OnGUI很耗費時間,效率不高,使用不方便

三十三:請簡述如何在不同解析度下保持UI的一致性

NGUI很好的解決了這一點,螢幕解析度的自適應性,原理就是計算出螢幕的寬高比跟原來的預設的螢幕解析度求出一個對比值,然後修改攝像機的size。UGUI通過錨點和中心點和解析度也解決這個問題

三十四:什麼是LightMap?

LightMap:就是指在三維軟體裡實現打好光,然後渲染把場景各表面的光照輸出到貼圖上,最後又通過引擎貼到場景上,這樣就使物體有了光照的感覺。

三十五:Unity和cocos2d的區別

  1. Unity3D支援C#、javascript等,cocos2d-x 支援c++、Html5、Lua等。

  2. cocos2d 開源 並且免費

  3. Unity3D支援iOS、Android、Flash、Windows、Mac、Wii等平臺的遊戲開發,cocos2d-x支援iOS、Android、WP等。

三十六:C#和C++的區別?

簡單的說:C# 與C++ 比較的話,最重要的特性就是C# 是一種完全面向物件的語言,而C++ 不是,另外C# 是基於IL 中間語言和.NET Framework CLR 的,在可移植性,可維護性和強壯性都比C++ 有很大的改進。C# 的設計目標是用來開發快速穩定可擴充套件的應用程式,當然也可以通過Interop 和Pinvoke 完成一些底層操作。更詳細的區別大家可以參考這裡

三十七:結構體和類有何區別?

結構體是一種值型別,而類是引用型別。(值型別、引用型別是根據資料儲存的角度來分的)就是值型別用於儲存資料的值,引用型別用於儲存對實際資料的引用。那麼結構體就是當成值來使用的,類則通過引用來對實際資料操作

三十八:ref引數和out引數是什麼?有什麼區別?

ref和out引數的效果一樣,都是通過關鍵字找到定義在主函式裡面的變數的記憶體地址,並通過方法體內的語法改變它的大小。不同點就是輸出引數必須對引數進行初始化。ref必須初始化,out 引數必須在函式裡賦值。ref引數是引用,out引數為輸出引數。

三十九:C#的委託是什麼?有何用處?

委託類似於一種安全的指標引用,在使用它時是當做類來看待而不是一個方法,相當於對一組方法的列表的引用。用處:使用委託使程式設計師可以將方法引用封裝在委託物件內。然後可以將該委託物件傳遞給可呼叫所引用方法的程式碼,而不必在編譯時知道將呼叫哪個方法。與C或C++中的函式指標不同,委託是面向物件,而且是型別安全的。

四十:C#中的排序方式有哪些?

選擇排序,氣泡排序,快速排序,插入排序,希爾排序,歸併排序

四十一:射線檢測碰撞物的原理是?

射線是3D世界中一個點向一個方向發射的一條無終點的線,在發射軌跡中與其他物體發生碰撞時,它將停止發射 。

四十二:Unity中,照相機的Clipping Planes的作用是什麼?調整Near、Fare兩個值時,應該注意什麼?

剪裁平面 。從相機到開始渲染和停止渲染之間的距離。

四十三:如何讓已經存在的GameObject在LoadLevel後不被解除安裝掉?

void Awake() { DontDestroyOnLoad(transform.gameObject); }
四十四:請簡述GC(垃圾回收)產生的原因,並描述如何避免?

GC回收堆上的記憶體

避免:1.減少new產生物件的次數

2.使用公用的物件(靜態成員)

3.將String換為StringBuilder

四十五:反射的實現原理?

審查元資料並收集關於它的型別資訊的能力。實現原理:在執行時根據程式集及其中的型別得到元資料。下面是實現步驟:

  1. 匯入using System.Reflection;

  2. Assembly.Load(“程式集”)載入程式集,返回型別是一個Assembly

  3. 得到程式集中所有類的名稱

foreach (Type type in assembly.GetTypes()) { string t = type.Name; }
4. Type type = assembly.GetType(“程式集.類名”);獲取當前類的型別

  1. Activator.CreateInstance(type); 建立此型別例項

  2. MethodInfo mInfo = type.GetMethod(“方法名”);獲取當前方法

  3. m.Info.Invoke(null,方法引數);

四十六:簡述四元數的作用,四元數對尤拉角的優點?

四元數用於表示旋轉

相對尤拉角的優點:

1.能進行增量旋轉

2.避免萬向鎖

3.給定方位的表達方式有兩種,互為負(尤拉角有無數種表達方式)

四十七:移動相機動作在哪個函式裡,為什麼在這個函式裡?

LateUpdate,是在所有的update結束後才呼叫,比較適合用於命令指令碼的執行。官網上例子是攝像機的跟隨,都是所有的update操作完才進行攝像機的跟進,不然就有可能出現攝像機已經推進了,但是視角里還未有角色的空幀出現。

四十八:GPU的工作原理

簡而言之,GPU的圖形(處理)流水線完成如下的工作:(並不一定是按照如下順序) 頂點處理:這階段GPU讀取描述3D圖形外觀的頂點資料並根據頂點資料確定3D圖形的形狀及位置關係,建立起3D圖形的骨架。在支援DX8和DX9規格的GPU中,這些工作由硬體實現的Vertex Shader(定點著色器)完成。 光柵化計算:顯示器實際顯示的影象是由畫素組成的,我們需要將上面生成的圖形上的點和線通過一定的演算法轉換到相應的畫素點。把一個向量圖形轉換為一系列畫素點的過程就稱為光柵化。例如,一條數學表示的斜線段,最終被轉化成階梯狀的連續畫素點。 紋理帖圖:頂點單元生成的多邊形只構成了3D物體的輪廓,而紋理對映(texture mapping)工作完成對多變形表面的帖圖,通俗的說,就是將多邊形的表面貼上相應的圖片,從而生成“真實”的圖形。TMU(Texture mapping unit)即是用來完成此項工作。 畫素處理:這階段(在對每個畫素進行光柵化處理期間)GPU完成對畫素的計算和處理,從而確定每個畫素的最終屬性。在支援DX8和DX9規格的GPU中,這些工作由硬體實現的Pixel Shader(畫素著色器)完成。 最終輸出:由ROP(光柵化引擎)最終完成畫素的輸出,1幀渲染完畢後,被送到視訊記憶體幀緩衝區。

總結:GPU的工作通俗的來說就是完成3D圖形的生成,將圖形對映到相應的畫素點上,對每個畫素進行計算確定最終顏色並完成輸出。

四十九:什麼是渲染管道?

是指在顯示器上為了顯示出影象而經過的一系列必要操作。 渲染管道中的很多步驟,都要將幾何物體從一個座標系中變換到另一個座標系中去。主要步驟有:

本地座標->檢視座標->背面裁剪->光照->裁剪->投影->檢視變換->光柵化

五十:如何優化記憶體?

有很多種方式,例如

1.壓縮自帶類庫;

2.將暫時不用的以後還需要使用的物體隱藏起來而不是直接Destroy掉;

3.釋放AssetBundle佔用的資源;

4.降低模型的片面數,降低模型的骨骼數量,降低貼圖的大小;

5.使用光照貼圖,使用多層次細節(LOD),使用著色器(Shader),使用預設(Prefab)。

6.程式碼中少產生臨時變數

五十一:動態載入資源的方式?他們之間的區別

1.Resources.Load();

2.AssetBundle

區別參考

五十二:請描述遊戲動畫有哪幾種,以及其原理?

主要有關節動畫、骨骼動畫、單一網格模型動畫(關鍵幀動畫)。

關節動畫:把角色分成若干獨立部分,一個部分對應一個網格模型,部分的動畫連線成一個整體的動畫,角色比較靈活,Quake2中使用這種動畫;

骨骼動畫,廣泛應用的動畫方式,集成了以上兩個方式的優點,骨骼按角色特點組成一定的層次結構,有關節相連,可做相對運動,面板作為單一網格蒙在骨骼之外,決定角色的外觀;

單一網格模型動畫由一個完整的網格模型構成,在動畫序列的關鍵幀裡記錄各個頂點的原位置及其改變數,然後插值運算實現動畫效果,角色動畫較真實。

五十三:alpha blend工作原理

Alpha Blend 實現透明效果,不過只能針對某塊區域進行alpha操作,透明度可設。

五十四:寫出光照計算中的diffuse的計算公式

diffuse = Kd x colorLight x max(N*L,0);Kd 漫反射係數、colorLight 光的顏色、N 單位法線向量、L 由點指向光源的單位向量、其中N與L點乘,如果結果小於等於0,則漫反射為0。

五十五:兩種陰影判斷的方法、工作原理。

本影和半影:參考本影和半影

本影:景物表面上那些沒有被光源直接照射的區域(全黑的輪廓分明的區域)。

半影:景物表面上那些被某些特定光源直接照射但並非被所有特定光源直接照射的區域(半明半暗區域)

工作原理:從光源處向物體的所有可見面投射光線,將這些面投影到場景中得到投影面,再將這些投影面與場景中的其他平面求交得出陰影多邊形,儲存這些陰影多邊形資訊,然後再按視點位置對場景進行相應處理得到所要求的檢視(利用空間換時間,每次只需依據視點位置進行一次陰影計算即可,省去了一次消隱過程)

五十六:Vertex Shader是什麼,怎麼計算?

頂點著色器是一段執行在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幾個過程。

五十七:下列程式碼在執行中會產生幾個臨時物件?

string a = new string(“abc”); a = (a.ToUpper() + “123”).Substring(0, 2);
在C#中第一行是會報錯的(Java中倒是可行)。

應該這樣初始化:

string b = new string(new char[]{‘a’,’b’,’c’});
答案為:5個臨時物件

五十八:下列程式碼在執行中會發生什麼問題?如何避免?

List ls = new List(new int[] { 1, 2, 3, 4, 5 }); foreach (int item in ls) { Console.WriteLine(item * item); ls.Remove(item); }
產生執行時錯誤,在 ls.Remove(item)這行,因為foreach是隻讀的。不能一邊遍歷一邊修改。

五十九:Unity3D是否支援寫成多執行緒程式?如果支援的話需要注意什麼?

僅能從主執行緒中訪問Unity3D的元件,物件和Unity3D系統呼叫

支援:如果同時你要處理很多事情或者與Unity的物件互動小可以用thread,否則使用coroutine。

注意:C#中有lock這個關鍵字,以確保只有一個執行緒可以在特定時間內訪問特定的物件

六十:Unity3D的協程和C#執行緒之間的區別是什麼?

多執行緒程式同時執行多個執行緒 ,而在任一指定時刻只有一個協程在執行,並且這個正在執行的協同程式只在必要時才被掛起。除主執行緒之外的執行緒無法訪問Unity3D的物件、元件、方法。

Unity3d沒有多執行緒的概念,不過unity也給我們提供了StartCoroutine(協同程式)和LoadLevelAsync(非同步載入關卡)後臺載入場景的方法。 StartCoroutine為什麼叫協同程式呢,所謂協同,就是當你在StartCoroutine的函式體裡處理一段程式碼時,利用yield語句等待執行結果,這期間不影響主程式的繼續執行,可以協同工作。

六十一:矩陣相乘的意義及注意點

用於表示線性變換:旋轉、縮放、投影、平移、仿射

注意矩陣的蠕變:誤差的積累

六十二:為什麼dynamic font在unicode環境下優於static font

Unicode是國際組織制定的可以容納世界上所有文字和符號的字元編碼方案。

使用動態字型時,Unity將不會預先生成一個與所有字型的字元紋理。當需要支援亞洲語言或者較大的字型的時候,若使用正常紋理,則字型的紋理將非常大。

六十三:當一個細小的高速物體撞向另一個較大的物體時,會出現什麼情況?如何避免?

穿透(碰撞檢測失敗)

六十四:請簡述OnBecameVisible及OnBecameInvisible的發生時機,以及這一對回撥函式的意義?

當物體是否可見切換之時。可以用於只需要在物體可見時才進行的計算。

六十五:什麼叫動態合批?跟靜態合批有什麼區別?

如果動態物體共用著相同的材質,那麼Unity會自動對這些物體進行批處理。動態批處理操作是自動完成的,並不需要你進行額外的操作。

區別:動態批處理一切都是自動的,不需要做任何操作,而且物體是可以移動的,但是限制很多。靜態批處理:自由度很高,限制很少,缺點可能會佔用更多的記憶體,而且經過靜態批處理後的所有物體都不可以再移動了。

參考

六十六:簡述StringBuilder和String的區別?

String是字串常量。

StringBuffer是字串變數 ,執行緒安全。

StringBuilder是字串變數,執行緒不安全。

String型別是個不可變的物件,當每次對String進行改變時都需要生成一個新的String物件,然後將指標指向一個新的物件,如果在一個迴圈裡面,不斷的改變一個物件,就要不斷的生成新的物件,所以效率很低,建議在不斷更改String物件的地方不要使用String型別。

StringBuilder物件在做字串連線操作時是在原來的字串上進行修改,改善了效能。這一點我們平時使用中也許都知道,連線操作頻繁的時候,使用StringBuilder物件。

六十七:Unity3D Shader分哪幾種,有什麼區別?

表面著色器的抽象層次比較高,它可以輕鬆地以簡潔方式實現複雜著色。表面著色器可同時在前向渲染及延遲渲染模式下正常工作。

頂點片段著色器可以非常靈活地實現需要的效果,但是需要編寫更多的程式碼,並且很難與Unity的渲染管線完美整合。

固定功能管線著色器可以作為前兩種著色器的備用選擇,當硬體無法執行那些酷炫Shader的時,還可以通過固定功能管線著色器來繪製出一些基本的內容。

六十八:已知strcpy函式的原型是:char * strcpy(char * strDest,const char * strSrc); 1.不呼叫庫函式,實現strcpy函式。2.解釋為什麼要返回char *

char * strcpy(char * strDest,const char * strSrc)
{
if ((strDest==NULL)||(strSrc==NULL))
throw “Invalid argument(s)”;
char * strDestCopy=strDest;
while ((*strDest++=*strSrc++)!=’\0’);
return strDestCopy;
}
六十九: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 修飾符修飾它。

七十:Heap與Stack有何區別?

1.heap是堆,stack是棧。

2.stack的空間由作業系統自動分配和釋放,heap的空間是手動申請和釋放的,heap常用new關鍵字來分配。

3.stack空間有限,heap的空間是很大的自由區。

七十一:值型別和引用型別有何區別?

1.值型別的資料儲存在記憶體的棧中;引用型別的資料儲存在記憶體的堆中,而記憶體單元中只存放堆中物件的地址。

2.值型別存取速度快,引用型別存取速度慢。

3.值型別表示實際資料,引用型別表示指向儲存在記憶體堆中的資料的指標或引用

4.值型別繼承自System.ValueType,引用型別繼承自System.Object

5.棧的記憶體分配是自動釋放;而堆在.NET中會有GC來釋放

6.值型別的變數直接存放實際的資料,而引用型別的變數存放的則是資料的地址,即物件的引用。

七十二:請寫出求斐波那契數列任意一位的值得演算法

遞迴實現:

int Fib1(int index)
{
if(index<1)
{
return -1;
}
if(index==1|| index==2)
{
return 1;
}
return Fib1(index-1)+Fib1(index-2);
}
迭代實現:

int Fib5(int index)
{
if(index<1)
{
return -1;
}
int a1 - 1, a2 = 1, a3 = 1;
for(int i = 0; i < index - 2; i++)
{
a3=a1+a2;
a1=a2;
a2=a3;
}
return a3;
}
參看更多實現方法

七十三:協同程式的執行程式碼是什麼?有何用處,有何缺點?

function Start() {
// 協同程式WaitAndPrint在Start函式內執行,可以視同於它與Start函式同步執行.
StartCoroutine(WaitAndPrint(2.0));
print (“Before WaitAndPrint Finishes ” + Time.time );
}
function WaitAndPrint (waitTime : float) {
// 暫停執行waitTime秒
yield WaitForSeconds (waitTime);
print (“WaitAndPrint “+ Time.time );
}

作用:一個協同程式在執行過程中,可以在任意位置使用yield語句。yield的返回值控制何時恢復協同程式向下執行。協同程式在物件自有幀執行過程中堪稱優秀。協同程式在效能上沒有更多的開銷。

缺點:協同程式並非真執行緒,可能會發生堵塞。

七十四:什麼是里氏代換元則?

里氏替換原則(Liskov Substitution Principle LSP)面向物件設計的基本原則之一。通俗點:就是子類物件可以賦值給基類物件,基類物件不能賦值給子類物件

參考

七十五:Mock和Stub有何區別?

Mock與Stub的區別:Mock:關注行為驗證。細粒度的測試,即程式碼的邏輯,多數情況下用於單元測試。Stub:關注狀態驗證。粗粒度的測試,在某個依賴系統不存在或者還沒實現或者難以測試的情況下使用,例如訪問檔案系統,資料庫連線,遠端協議等。

七十六:概述序列化:

序列化簡單理解成把物件轉換為容易傳輸的格式的過程。比如,可以序列化一個物件,然後使用HTTP通過Internet在客戶端和伺服器端之間傳輸該物件

七十七:堆和棧的區別?

棧通常儲存著我們程式碼執行的步驟,如在程式碼段1中 AddFive()方法,int pValue變數,int result變數等等。而堆上存放的則多是物件,資料等。我們可以把棧想象成一個接著一個疊放在一起的盒子。當我們使用的時候,每次從最頂部取走一個盒子。棧也是如此,當一個方法(或型別)被呼叫完成的時候,就從棧頂取走,接著下一個。堆則不然,像是一個倉庫,儲存著我們使用的各種物件等資訊,跟棧不同的是他們被呼叫完畢不會立即被清理掉。

七十八:概述c#中代理和事件?

代理就是用來定義指向方法的引用。

C#事件本質就是對訊息的封裝,用作物件之間的通訊;傳送方叫事件傳送器,接收方叫事件接收器

七十九:客戶端與伺服器互動方式有幾種?

socket通常也稱作”套接字”,實現伺服器和客戶端之間的物理連線,並進行資料傳輸,主要有UDP和TCP兩個協議。Socket處於網路協議的傳輸層。

http協議傳輸的主要有http協議 和基於http協議的Soap協議(web service),常見的方式是 http 的post 和get 請求,web 服務。

八十:Unity和Android與iOS如何互動?

Unity可以到處Android和iOS的工程,然後通過安卓或者iOS的類去給Unity發訊息,呼叫Unity中的方法

八十一:如何在Unity3D中檢視場景的面試,頂點數和Draw Call數?如何降低Draw Call數?

在Game檢視右上角點選Stats。降低Draw Call 的技術是Draw Call Batching

這個在5.0以後在window-》Profiler下面,快捷鍵是cmd + 7(ctl + 7

八十二:請問alpha test在何時使用?能達到什麼效果?

Alpha Test ,中文就是透明度測試。簡而言之就是V&F shader中最後fragment函式輸出的該點顏色值(即上一講frag的輸出half4)的alpha值與固定值進行比較。AlphaTest語句通常於Pass{}中的起始位置。Alpha Test產生的效果也很極端,要麼完全透明,即看不到,要麼完全不透明。

八十三:UNITY3d在移動裝置上的一些優化資源的方法

1.使用assetbundle,實現資源分離和共享,將記憶體控制到200m之內,同時也可以實現資源的線上更新

2.頂點數對渲染無論是cpu還是gpu都是壓力最大的貢獻者,降低頂點數到8萬以下,fps穩定到了30幀左右

3.只使用一盞動態光,不是用陰影,不使用光照探頭

粒子系統是cpu上的大頭

4.剪裁粒子系統

5.合併同時出現的粒子系統

6.自己實現輕量級的粒子系統

animator也是一個效率奇差的地方

7.把不需要跟骨骼動畫和動作過渡的地方全部使用animation,控制骨骼數量在30根以下

8.animator出視野不更新

9.刪除無意義的animator

10.animator的初始化很耗時(粒子上能不能儘量不用animator)

11.除主角外都不要跟骨骼運動apply root motion

12.絕對禁止掉那些不帶剛體帶包圍盒的物體(static collider )運動

NUGI的程式碼效率很差,基本上runtime的時候對cpu的貢獻和render不相上下

13每幀遞迴的計算finalalpha改為只有初始化和變動時計算

14去掉法線計算

15不要每幀計算viewsize 和windowsize

16filldrawcall時構建頂點快取使用array.copy

17.程式碼剪裁:使用strip level ,使用.net2.0 subset

18.儘量減少smooth group

19.給美術定一個嚴格的經過科學驗證的美術標準,並在U3D裡面配以相應的檢查工具

八十四:四元數有什麼作用?

對旋轉角度進行計算時用到四元數

八十五:將Camera元件的ClearFlags選項選成Depth only是什麼意思?有何用處?

如果把攝像機的ClearFlags勾選為Deapth Only,那麼攝像機就會只渲染看得見的物件,把背景會完全透明,這種情況一般用在兩個攝像機以上的場景中

八十六:在編輯場景時將GameObject設定為Static有何作用?

設定遊戲物件為Static時,這些部分被靜態物體擋住而不可見時,將會剔除(或禁用)網格物件。因此,在你的場景中的所有不會動的物體都應該標記為Static。

八十七:有A和B兩組物體,有什麼辦法能夠保證A組物體永遠比B組物體先渲染?

把A組物體的渲染對列大於B物體的渲染佇列,通過shader裡面的渲染佇列來渲染

八十八:將圖片的TextureType選項分別選為““Texture”和“Sprite”有什麼區別

Sprite作為UI精靈使用,Texture作用模型貼圖使用。Sprite需要2的整次冪,打包圖片省資源

八十九:問一個Terrain,分別貼3張,4張,5張地表貼圖,渲染速度有什麼區別?為什麼?

沒有區別,因為不管幾張貼圖只渲染一次。

九十:什麼是DrawCall?DrawCall高了又什麼影響?如何降低DrawCall?

Unity中,每次引擎準備資料並通知GPU的過程稱為一次Draw Call。DrawCall越高對顯示卡的消耗就越大。降低DrawCall的方法:

  1. Dynamic Batching

  2. Static Batching

  3. 高階特性Shader降級為統一的低階特性的Shader。

九十一:實時點光源的優缺點是什麼?

可以有cookies – 帶有 alpha通道的立方圖(Cubemap )紋理。點光源是最耗費資源的。

九十二:Unity的Shader中,Blend SrcAlpha OneMinusSrcAlpha這句話是什麼意思?

作用就是Alpha混合。公式:最終顏色 = 源顏色 x 源透明值 + 目標顏色 x(1 - 源透明值)

九十三:簡述水面倒影的渲染原理

原理就是對水面的貼圖紋理進行擾動,以產生波光玲玲的效果。用shader可以通過GPU在畫素級別作擾動,效果細膩,需要的頂點少,速度快

九十四:簡述NGUI中Grid和Table的作用?

對Grid和Table下的子物體進行排序和定位

九十五:請簡述NGUI中Panel和Anchor的作用

  1. 只要提供一個half-pixel偏移量,它可以讓一個控制元件的位置在Windows系統上精確的顯示出來(只有這個Anchor的子控制元件會受到影響)

  2. 如果掛載到一個物件上,那麼他可以將這個物件依附到螢幕的角落或者邊緣

3.UIPanel用來收集和管理它下面所有widget的元件。通過widget的geometry建立實際的draw call。沒有panel所有東西都不能夠被渲染出來,你可以把UIPanel當做Renderer

九十六:能用foreach遍歷訪問的物件需要實現介面或宣告___方法的型別

IEnumerable;GetEnumerator