Unity面試題

一:什么是協同程序?
答:在主線程運行時同時開啟另一段邏輯處理,來協助當前程序的執行。換句話說,開啟協程就是開啟一個可以與程序并行的邏輯。可以用來控制運動、序列以及對象的行為。


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


三:物體發生碰撞的必要條件
答:兩個物體都必須帶有碰撞器Collider,其中一個物體還必須帶有Rigidbody剛體。


四:請簡述ArrayList和List<Int>的主要區別
答:
ArrayList存在不安全類型

  • ArrayList會把所有插入其中的數據都當做Object來處理
  • 裝箱拆箱的操作

. net 2.0后不使用ArrayList,用List<Object>替代
IList是接口,ArrayList是一個實現了該接口的類,可以被實例化


五:請簡述GC(垃圾回收)產生的原因,并描述如何避免?
答:GC回收堆上的內存
避免:
1)減少new產生對象的次數
2)使用公用的對象(靜態成員)
3)將String換為StringBuilder


六:反射的實現原理?
答:審查元數據并收集關于它的類型信息的能力。
實現步驟:

  • 導入using System.Reflection;

  • Assembly.Load("程序集");//加載程序集,返回類型是一個Assembly

  • 得到程序集中所有類的名稱foreach (Type type in assembly.GetTypes())
    {
    string t = type.Name;
    }

  • Type type = assembly.GetType("程序集.類名");//獲取當前類的類型

  • Activator.CreateInstance(type); //創建此類型實例

  • MethodInfo mInfo = type.GetMethod("方法名");//獲取當前方法

  • mInfo.Invoke(null,方法參數);


七:簡述四元數Quaternion的作用,四元數對歐拉角的優點?
答:四元數用于表示旋轉
相對歐拉角的優點:

  • 能進行增量旋轉
  • 避免萬向鎖
  • 給定方位的表達方式有兩種,互為負(歐拉角有無數種表達方式)

八:如何安全的在不同工程間安全地遷移asset數據?三種方法
答:
1.將Assets和Library一起遷移
2.導出包package
3.用unity自帶的assets Server功能


九:OnEnable、Awake、Start運行時的發生順序?哪些可能在同一個對象周期中反復的發生?
答:Awake–>OnEnable->Start OnEnable在同一周期中可以反復地發生!


十:MeshRender中material和sharedmaterial的區別?
答:
修改sharedMaterial將改變所有物體使用這個材質的外觀,并且也改變儲存在工程里的材質設置。
不推薦修改由sharedMaterial返回的材質。如果你想修改渲染器的材質,使用material替代。


十一:請簡述ArrayList和List之間的主要區別。
答:
ArrayList的定義
  ArrayList是動態數組,是Array的復雜版本,它提供了動態添加和減少元素,實現了ICollection和IList接口,可以靈活設置數組的大小。

ArrayList的特點
(1)ArrayList數組的長度可以動態指定,其大小可以在初始化時指定,也可以不指定,因此其在托管堆上存放并不一定連續。
(2)ArrayList數據可以存放不同類型數據(因為它里面存放的都是被裝箱了的Object類型,實際上ArrayList內部就是使用"object[] _items;"這樣一個私有字段來封裝對象的)。
(3)ArrayList可以在任意位置插入或刪除數項。

ArrayList的優缺點
優點:
(1)初始化時可以不指定長度,并且可以動態插入或刪除項,其長度可以動態擴充和收縮。
(2)存放的數據類型可以是不同類型的數據。

缺點:
(1)ArrayList不是類型安全的,其插入的數據當做Object類型處理,因此在處理數據是可能會報類型不匹配錯誤。
(2)由于存在裝箱和拆箱操作,會帶來很大的性能損耗,所以存取效率低。

List的定義
  List是ArrayList的范型等效類,List類也繼承了IList接口,其大部分用法與ArrayList相似,最關鍵的區別是,在聲明List集合時需要為其聲明List集合內數據的對象類型,往List中插入其它(非聲明數據類型)數據類型元素時將會報錯,因此其是類型安全的。

數組結構的特點:
(1)聲明時必須指定數據集內元素的數據類型,且數據元素類型必須相同。
(2)可以動態插入或刪除數據元素。
(3)數據操作是類型安全的且不存在裝箱和拆箱操作,因此效率較高。


十二:TCP/IP協議棧各個層次及分別的功能
答:網絡接口層:這是協議棧的最低層,對應OSI的物理層和數據鏈路層,主要完成數據幀的實際發送和接收。
網絡層:處理分組在網絡中的活動,例如路由選擇和轉發等,這一層主要包括IP協議、ARP、ICMP協議等。
傳輸層:主要功能是提供應用程序之間的通信,這一層主要是TCP/UDP協議。
應用層:用來處理特定的應用,針對不同的應用提供了不同的協議,例如進行文件傳輸時用到的FTP協議,發送email用到的SMTP等。


十三題:Unity提供了幾種光源,分別是什么
答:
四種。
平行光:Directional Light
點光源:Point Light
聚光燈:Spot Light
區域光源:Area Light


十四:簡述一下對象池,你覺得在FPS里哪些東西適合使用對象池?
對象池就存放需要被反復調用資源的一個空間,比如游戲中要常被大量復制的對象,子彈,敵人,以及任何重復出現的對象。


十五:CharacterController和Rigidbody的區別?
Rigidbody具有完全真實物理的特性,而CharacterController可以說是受限的的Rigidbody,具有一定的物理效果但不是完全真實的。


十六:移動相機動作在哪個函數里,為什么在這個函數里?
LateUpdate,是在所有的Update結束后才調用,比較適合用于命令腳本的執行。官網上例子是攝像機的跟隨,都是所有的Update操作完才進行攝像機的跟進,不然就有可能出現攝像機已經推進了,但是視角里還未有角色的空幀出現。


十七:簡述prefab的用處
在游戲運行時實例化,prefab相當于一個模板,對你已經有的素材、腳本、參數做一個默認的配置,以便于以后的修改,同事prefab打包的內容簡化了導出的操作,便于團隊的交流。


十八:請簡述sealed關鍵字用在類聲明時與函數聲明時的作用。
答:類聲明時可防止其他類繼承此類,在方法中聲明則可防止派生類重寫此方法。


十九:請簡述private,public,protected,internal的區別。
public:對任何類和成員都公開,無限制訪問
private:僅對該類公開
protected:對該類和其派生類公開
internal:只能在包含該類的程序集中訪問該類
protected internal:protected + internal


二十:簡述SkinnedMesh的實現原理
答:Skinned Mesh中文一般稱作骨骼蒙皮動畫,正如其名,這種動畫中包含骨骼(Bone)和蒙皮(Skinned Mesh)兩個部分,Bone的層次結構和關節動畫類似,Mesh則和關節動畫不同:關節動畫中是使用多個分散的Mesh,而Skinned Mesh中Mesh是一個整體,也就是說只有一個Mesh,實際上如果沒有骨骼讓Mesh運動變形,Mesh就和靜態模型一樣了。Skinned Mesh技術的精華在于蒙皮,所謂的皮并不是模型的貼圖(也許會有人這么想過吧),而是Mesh本身,蒙皮是指將Mesh中的頂點附著(綁定)在骨骼之上,而且每個頂點可以被多個骨骼所控制,這樣在關節處的頂點由于同時受到父子骨骼的拉扯而改變位置就消除了裂縫。Skinned Mesh這個詞從字面上理解似乎是有皮的模型,哦,如果貼圖是皮,那么普通靜態模型不也都有嗎?所以我覺得應該理解為具有蒙皮信息的Mesh或可當做皮膚用的Mesh,這個皮膚就是Mesh。而為了有皮膚功能,Mesh還需要蒙皮信息,即Skin數據,沒有Skin數據就是一個普通的靜態Mesh了。Skin數據決定頂點如何綁定到骨骼上。頂點的Skin數據包括頂點受哪些骨骼影響以及這些骨骼影響該頂點時的權重(weight),另外對于每塊骨骼還需要骨骼偏移矩陣(BoneOffsetMatrix)用來將頂點從Mesh空間變換到骨骼空間。骨骼動畫中的Mesh特指這個皮膚Mesh,模型是指骨骼動畫模型整體。骨骼控制蒙皮運動,而骨骼本身的運動呢?當然是動畫數據了。每個關鍵幀中包含時間和骨骼運動信息,運動信息可以用一個矩陣直接表示骨骼新的變換,也可用四元數表示骨骼的旋轉,也可以隨便自己定義什么只要能讓骨骼動就行。除了使用編輯設定好的動畫幀數據,也可以使用物理計算對骨骼進行實時控制。


二十一: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)。


二十四:動態加載資源的方式?
1.Resources.Load();
2.AssetBundle Unity5.1版本后可以選擇使用Git: https://github.com/applexiaohao/LOAssetFramework.git


二十五:你用過哪些插件?
二十六: 使用Unity3d實現2d游戲,有幾種方式?
答:
1.使用本身的GUI、UGUI
2.把攝像機的Projection(投影)值調為Orthographic(正交投影),不考慮z軸;
3.使用2d插件,如:2DToolKit、NGUI


二十七:在物體發生碰撞的整個過程中,有幾個階段,分別列出對應的函數 三個階段
答:

  • OnCollisionEnter
  • OnCollisionStay
  • OnCollisionExit

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

  • rigidbody.AddForce
  • rigidbody.AddForceAtPosition

二十九:什么叫做鏈條關節?
答:Hinge Joint,可以模擬兩個物體間用一根鏈條連接在一起的情況,能保持兩個物體在一個固定距離內部相互移動而不產生作用力,但是達到固定距離后就會產生拉力。


三十:物體自身旋轉使用的函數?
答: Transform.Rotate()
三十一:Unity3d提供了一個用于保存和讀取數據的類(PlayerPrefs),請列出保存和讀取整形數據的函數
答:

  • PlayerPrefs.SetInt()
  • PlayerPrefs.GetInt()

三十二:Unity3d腳本從喚醒到銷毀有著一套比較完整的生命周期,請列出系統自帶的幾個重要的方法。
答:Awake——>Start——>Update——>FixedUpdate——>LateUpdate——>OnGUI——>Reset——>OnDisable——>OnDestroy


三十三:物理更新一般放在哪個系統函數里?
答:
FixedUpdate,每固定幀繪制時執行一次,和Update不同的是FixedUpdate是渲染幀執行,如果你的渲染效率低下的時候FixedUpdate調用次數就會跟著下降。

  • FixedUpdate比較適用于物理引擎的計算,因為是跟每幀渲染有關。
  • Update就比較適合做控制。

三十四:在場景中放置多個Camera并同時處于活動狀態會發生什么?
答:游戲界面可以看到很多攝像機的混合。


三十五:如何銷毀一個UnityEngine.Object及其子類?
答: 使用Destroy()方法;


三十六:請描述游戲動畫有哪幾種,以及其原理?
答:主要有關節動畫、骨骼動畫、單一網格模型動畫(關鍵幀動畫)。 關節動畫:把角色分成若干獨立部分,一個部分對應一個網格模型,部分的動畫連接成一個整體的動畫,角色比較靈活,Quake2中使用這種動畫;
骨骼動畫,廣泛應用的動畫方式,集成了以上兩個方式的優點,骨骼按角色特點組成一定的層次結構,有關節相連,可做相對運動,皮膚作為單一網格蒙在骨骼之外,決定角色的外觀;
單一網格模型動畫由一個完整的網格模型構成,在動畫序列的關鍵幀里記錄各個頂點的原位置及其改變量,然后插值運算實現動畫效果,角色動畫較真實。


三十七:請描述為什么Unity3d中會發生在組件上出現數據丟失的情況
答: 一般是組件上綁定的物體對象被刪除了


三十八:alpha blend工作原理
答:Alpha Blend 實現透明效果,不過只能針對某塊區域進行alpha操作,透明度可設。


三十九:寫出光照計算中的diffuse的計算公式
答:diffuse = Kd x colorLight x max(N*L,0);Kd 漫反射系數、colorLight 光的顏色、N 單位法線向量、L 由點指向光源的單位向量、其中N與L點乘,如果結果小于等于0,則漫反射為0。


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


四十一:兩種陰影判斷的方法、工作原理。
本影和半影:
本影:景物表面上那些沒有被光源直接照射的區域(全黑的輪廓分明的區域)。
半影:景物表面上那些被某些特定光源直接照射但并非被所有特定光源直接照射的區域(半明半暗區域)
工作原理:從光源處向物體的所有可見面投射光線,將這些面投影到場景中得到投影面,再將這些投影面與場景中的其他平面求交得出陰影多邊形,保存這些陰影多邊形信息,然后再按視點位置對場景進行相應處理得到所要求的視圖(利用空間換時間,每次只需依據視點位置進行一次陰影計算即可,省去了一次消隱過程)


四十二: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幾個過程。


四十三:MipMap是什么,作用?
答:MipMapping:在三維計算機圖形的貼圖渲染中有常用的技術,為加快渲染進度和減少圖像鋸齒,貼圖被處理成由一系列被預先計算和優化過的圖片組成的文件,這樣的貼圖被稱為MipMap。


四十四:請描述Interface與抽象類之間的不同
答:抽象類表示該類中可能已經有一些方法的具體定義,但接口就是公公只能定義各個方法的界面 ,不能具體的實現代碼在成員方法中。
類是子類用來繼承的,當父類已經有實際功能的方法時該方法在子類中可以不必實現,直接引用父類的方法,子類也可以重寫該父類的方法。
實現接口的時候必須要實現接口中所有的方法,不能遺漏任何一個。


四十五:下列代碼在運行中會產生幾個臨時對象?
string a = new string("abc");
a = (a.ToUpper() + "123").Substring(0, 2);
答:其實在C#中第一行是會出錯的(Java中倒是可行)。應該這樣初始化:string b = new string(new char[]{'a','b','c'});


四十六:下列代碼在運行中會發生什么問題?如何避免?

List<int> ls = new List<int>(new int[] { 1, 2, 3, 4, 5 });
foreach (int item in ls)
{
Console.WriteLine(item * item);
ls.Remove(item);
}

答:會產生運行時錯誤,因為foreach是只讀的。不能一邊遍歷一邊修改。


四十七:.Net與Mono的關系?
答:mono是.net的一個開源跨平臺工具,就類似java虛擬機,java本身不是跨平臺語言,但運行在虛擬機上就能夠實現了跨平臺。.net只能在windows下運行,mono可以實現跨平臺編譯運行,可以運行于linux,Unix,Mac OS等。


四十八:簡述Unity3D支持的作為腳本的語言的名稱
答:Unity的腳本語言基于Mono的.Net平臺上運行,可以使用.NET庫,這也為XML、數據庫、正則表達式等問題提供了很好的解決方案。
Unity里的腳本都會經過編譯,他們的運行速度也很快。這三種語言實際上的功能和運行速度是一樣的,區別主要體現在語言特性上。
JavaScript、 C#、Boo


四十九:Unity3D是否支持寫成多線程程序?如果支持的話需要注意什么?
答:僅能從主線程中訪問Unity3D的組件,對象和Unity3D系統調用
支持:如果同時你要處理很多事情或者與Unity的對象互動小可以用thread,否則使用coroutine。
注意:C#中有lock這個關鍵字,以確保只有一個線程可以在特定時間內訪問特定的對象


五十:Unity3D的協程和C#線程之間的區別是什么?
答:多線程程序同時運行多個線程 ,而在任一指定時刻只有一個協程在運行,并且這個正在運行的協同程序只在必要時才被掛起。
除主線程之外的線程無法訪問Unity3D的對象、組件、方法。
Unity3d沒有多線程的概念,不過unity也給我們提供了StartCoroutine(協同程序)和LoadLevelAsync(異步加載關卡)后臺加載場景的方法。 StartCoroutine為什么叫協同程序呢,所謂協同,就是當你在StartCoroutine的函數體里處理一段代碼時,利用yield語句等待執行結果,這期間不影響主程序的繼續執行,可以協同工作。


五十一:U3D中用于記錄節點空間幾何信息的組件名稱,及其父類名稱
答:Transform 父類是 Component


五十二:向量的點乘、叉乘以及歸一化的意義?
答:
1)點乘描述了兩個向量的相似程度,結果越大兩向量越相似,還可表示投影
2)叉乘得到的向量垂直于原來的兩個向量
3)標準化向量:用在只關系方向,不關心大小的時候


五十三:矩陣相乘的意義及注意點
答:用于表示線性變換:旋轉、縮放、投影、平移、仿射
注意矩陣的蠕變:誤差的積累


五十四:為何大家都在移動設備上尋求U3D原生GUI的替代方案
答:不美觀,OnGUI很耗費時間,使用不方便


五十五:請簡述如何在不同分辨率下保持UI的一致性
答:NGUI很好的解決了這一點,屏幕分辨率的自適應性,原理就是計算出屏幕的寬高比跟原來的預設的屏幕分辨率求出一個對比值,然后修改攝像機的size。


五十六:為什么dynamic font在unicode環境下優于static font
答:Unicode是國際組織制定的可以容納世界上所有文字和符號的字符編碼方案。
使用動態字體時,Unity將不會預先生成一個與所有字體的字符紋理。當需要支持亞洲語言或者較大的字體的時候,若使用正常紋理,則字體的紋理將非常大。


五十七:當一個細小的高速物體撞向另一個較大的物體時,會出現什么情況?如何避免?
答:穿透(碰撞檢測失?。?/p>


五十八:請簡述OnBecameVisible及OnBecameInvisible的發生時機,以及這一對回調函數的意義?
答:當物體是否可見切換之時。可以用于只需要在物體可見時才進行的計算。


五十九:什么叫動態合批?跟靜態合批有什么區別?
答:如果動態物體共用著相同的材質,那么Unity會自動對這些物體進行批處理。動態批處理操作是自動完成的,并不需要你進行額外的操作。
區別:動態批處理一切都是自動的,不需要做任何操作,而且物體是可以移動的,但是限制很多。靜態批處理:自由度很高,限制很少,缺點可能會占用更多的內存,而且經過靜態批處理后的所有物體都不可以再移動了。


六十:簡述StringBuilder和String的區別?
答:
String是字符串常量。
StringBuffer是字符串變量 ,線程安全。
StringBuilder是字符串變量,線程不安全。
String類型是個不可變的對象,當每次對String進行改變時都需要生成一個新的String對象,然后將指針指向一個新的對象,如果在一個循環里面,不斷的改變一個對象,就要不斷的生成新的對象,所以效率很低,建議在不斷更改String對象的地方不要使用String類型。
StringBuilder對象在做字符串連接操作時是在原來的字符串上進行修改,改善了性能。這一點我們平時使用中也許都知道,連接操作頻繁的時候,使用StringBuilder對象。


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


六十二:Unity和cocos2d的區別
答:

Unity3D支持C#、javascript等,cocos2d-x 支持c++、Html5、Lua等。
cocos2d 開源 并且免費
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 完成一些底層操作


六十四: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)) //[1]
throw "Invalid argument(s)"; //[2]
char * strDestCopy=strDest; //[3]
while ((strDest++=strSrc++)!='\0'); //[4]
return strDestCopy;
}

錯誤的做法:
//不檢查指針的有效性,說明答題者不注重代碼的健壯性。
//檢查指針的有效性時使用((!strDest)||(!strSrc))或(!(strDest&&strSrc)),說明答題者對C語言中類型的隱式轉換沒有深刻認識。在本例中char *轉換為bool即是類型隱式轉換,這種功能雖然靈活,但更多的是導致出錯概率增大和維護成本升高。所以C++專門增加了bool、true、false三個關鍵字以提供更安全的條件表達式。
//檢查指針的有效性時使用((strDest==0)||(strSrc==0)),說明答題者不知道使用常量的好處。直接使用字面常量(如本例中的0)會減少程序的可維護性。0雖然簡單,但程序中可能出現很多處對指針的檢查,萬一出現筆誤,編譯器不能發現,生成的程序內含邏輯錯誤,很難排除。而使用NULL代替0,如果出現拼寫錯誤,編譯器就會檢查出來。

//return new string("Invalid argument(s)");,說明答題者根本不知道返回值的用途,并且他對內存泄漏也沒有警惕心。從函數中返回函數體內分配的內存是十分危險的做法,他把釋放內存的義務拋給不知情的調用者,絕大多數情況下,調用者不會釋放內存,這導致內存泄漏。
//return 0;,說明答題者沒有掌握異常機制。調用者有可能忘記檢查返回值,調用者還可能無法檢查返回值(見后面的鏈式表達式)。妄想讓返回值肩負返回正確值和異常值的雙重功能,其結果往往是兩種功能都失效。應該以拋出異常來代替返回值,這樣可以減輕調用者的負擔、使錯誤不會被忽略、增強程序的可維護性。
//忘記保存原始的strDest值,說明答題者邏輯思維不嚴密。
//循環寫成while (strDest++=strSrc++);,同1。
//循環寫成while (strSrc!='\0') strDest++=strSrc++;,說明答題者對邊界條件的檢查不力。循環體結束后,strDest字符串的末尾沒有正確地加上'\0'。
/
*
*返回strDest的原始值使函數能夠支持鏈式表達式,增加了函數的“附加值”。同樣功能的函數,如果能合理地提高的可用性,自然就更加理想。
鏈式表達式的形式如:
`nt iLength=strlen(strcpy(strA,strB));
又如:
char * strA=strcpy(new char[10],strB);
返回strSrc的原始值是錯誤的。其一,源字符串肯定是已知的,返回它沒有意義。其二,不能支持形如第二例的表達式。其三,為了保護源字符串,形參用const限定strSrc所指的內容,把const char *作為char *返回,類型不符,編譯報錯。
*/


六十六: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.值類型的變量直接存放實際的數據,而引用類型的變量存放的則是數據的地址,即對象的引用。
7.值類型變量直接把變量的值保存在堆棧中,引用類型的變量把實際數據的地址保存在堆棧中。


六十九:結構體和類有何區別?
答:結構體是一種值類型,而類是引用類型。(值類型、引用類型是根據數據存儲的角度來分的)
就是值類型用于存儲數據的值,引用類型用于存儲對實際數據的引用。那么結構體就是當成值來使用的,類則通過引用來對實際數據操作。


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

static int Fn(int n)
{
if (n <= 0)
{
throw new ArgumentOutOfRangeException();
}
if (n == 1||n==2)
{
return 1;
}
return checked(Fn(n - 1) + Fn(n - 2)); // when n>46 memory will overflow
}


七十一:ref參數和out參數是什么?有什么區別?
答:ref和out參數的效果一樣,都是通過關鍵字找到定義在主函數里面的變量的內存地址,并通過方法體內的語法改變它的大小。
不同點就是輸出參數必須對參數進行初始化。 ref參數是引用,out參數為輸出參數。


七十二:C#的委托是什么?有何用處?
答:委托類似于一種安全的指針引用,在使用它時是當做類來看待而不是一個方法,相當于對一組方法的列表的引用。
用處:使用委托使程序員可以將方法引用封裝在委托對象內。然后可以將該委托對象傳遞給可調用所引用方法的代碼,而不必在編譯時知道將調用哪個方法。與C或C++中的函數指針不同,委托是面向對象,而且是類型安全的。


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

function Start() {
// - After 0 seconds, prints "Starting 0.0"
// - After 0 seconds, prints "Before WaitAndPrint Finishes 0.0"
// - After 2 seconds, prints "WaitAndPrint 2.0"
// 先打印"Starting 0.0"和"Before WaitAndPrint Finishes 0.0"兩句,2秒后打印"WaitAndPrint 2.0"
print ("Starting " + Time.time );
// Start function WaitAndPrint as a coroutine. And continue execution while it is running
// this is the same as WaintAndPrint(2.0) as the compiler does it for you automatically
// 協同程序WaitAndPrint在Start函數內執行,可以視同于它與Start函數同步執行.
StartCoroutine(WaitAndPrint(2.0));
print ("Before WaitAndPrint Finishes " + Time.time );
}

function WaitAndPrint (waitTime : float) {
// suspend execution for waitTime seconds
// 暫停執行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變量等等。而堆上存放的則多是對象,數據等。(譯者注:忽略編譯器優化)我們可以把棧想象成一個接著一個疊放在一起的盒子。當我們使用的時候,每次從最頂部取走一個盒子。棧也是如此,當一個方法(或類型)被調用完成的時候,就從棧頂取走(called a Frame,譯注:調用幀),接著下一個。堆則不然,像是一個倉庫,儲存著我們使用的各種對象等信息,跟棧不同的是他們被調用完畢不會立即被清理掉。


七十八:概述c#中代理和事件?
答:代理就是用來定義指向方法的引用。
C#事件本質就是對消息的封裝,用作對象之間的通信;發送方叫事件發送器,接收方叫事件接收器;


七十九:C#中的排序方式有哪些?
答:選擇排序,冒泡排序,快速排序,插入排序,希爾排序,歸并排序


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


八十一:客戶端與服務器交互方式有幾種?
答: socket通常也稱作"套接字",實現服務器和客戶端之間的物理連接,并進行數據傳輸,主要有UDP和TCP兩個協議。Socket處于網絡協議的傳輸層。
http協議傳輸的主要有http協議 和基于http協議的Soap協議(web service),常見的方式是 http 的post 和get 請求,web 服務。


八十二:Unity和Android與iOS如何交互?
答:

1. Unity主動調用iOS、Android

Unity -> iOS

實現方案Unity的官方文檔已經給出了
我自己做了一些總結:

第一,Unity是支持 C# 通過調用DLL的方式來調用 C++ 的
第二,iOS是支持 C++ 和 OC混編的,所以 C++ 自然可以調用 OC

所以,我們的實現方案為 C# -> C++ -> OC

Unity -> Android

同樣,實現方案Unity的官方文檔也已經給出了
文檔中給出了兩種方法:

Plan A:使用Android NDK的方式
Plan B:使用Java Native Interface (JNI)的方式

關于JNI的方式官方給了詳細的示例,我自己也做了一些總結:

第一,Unity提供了UnityEngine.AndroidJNI,可以實現在C#創建Java對象并調用函數
第二,在Android下做原生的Java調用Java實現不了的可以自掛東南枝了

所以,我們的實現方案為 C# -> Java

2. iOS、Android主動調用Unity

iOS -> Unity 、 Android -> Unity
Unity都只為我們提供了一個官方的方法

UnitySendMessage("GameObjectName1", "MethodName1", "Message to send");

解釋一下這個函數:

返回值:無
函數類型:靜態函數,直接調用即可(Java中包含在com.unity3d.player.UnityPlayer中)
參數1:場景內某GameObject物體的名稱
參數2:該GameObject物體上組件所掛載的函數名
參數3:調用該函數時傳入的參數

所以,我們的實現方案為 Java/OC -> C#


八十三:Unity中,照相機的Clipping Planes的作用是什么?調整Near、Fare兩個值時,應該注意什么?
答:剪裁平面 。從相機到開始渲染和停止渲染之間的距離。


八十四:如何在Unity3D中查看場景的面試,頂點數和Draw Call數?如何降低Draw Call數?
答:在Game視圖右上角點擊Stats。降低Draw Call 的技術是Draw Call Batching


八十五:請問alpha test在何時使用?能達到什么效果?
Alpha Test,中文就是透明度測試。簡而言之就是V&F shader中最后fragment函數輸出的該點顏色值(即上一講frag的輸出half4)的alpha值與固定值進行比較。Alpha Test語句通常于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
  16. filldrawcall時構建頂點緩存使用array.copy
  17. 代碼剪裁:使用strip level ,使用.net2.0 subset
  18. 盡量減少smooth group
  19. 給美術定一個嚴格的經過科學驗證的美術標準,并在U3D里面配以相應的檢查工具

八十七:四元數有什么作用?
答:對旋轉角度進行計算時用到四元數


八十八:將Camera組件的ClearFlags選項選成Depth only是什么意思?有何用處?
答:僅深度,該模式用于對象不被裁剪。


八十九:如何讓已經存在的GameObject在LoadLevel后不被卸載掉?

void Awake()
{
DontDestroyOnLoad(transform.gameObject);
}


九十:在編輯場景時將GameObject設置為Static有何作用?
答:設置游戲對象為Static將會剔除(或禁用)網格對象當這些部分被靜態物體擋住而不可見時。因此,在你的場景中的所有不會動的物體都應該標記為Static。


九十一:有A和B兩組物體,有什么辦法能夠保證A組物體永遠比B組物體先渲染?
答:把A組物體的渲染對列大于B物體的渲染隊列


九十二:將圖片的TextureType選項分別選為Texture和Sprite有什么區別
答:Sprite作為UI精靈使用,Texture作用模型貼圖使用。


九十三:問一個Terrain,分別貼3張,4張,5張地表貼圖,渲染速度有什么區別?為什么?
答:沒有區別,因為不管幾張貼圖只渲染一次。


九十四:什么是DrawCall?DrawCall高了又什么影響?如何降低DrawCall?
答:Unity中,每次引擎準備數據并通知GPU的過程稱為一次Draw Call。DrawCall越高對顯卡的消耗就越大。降低DrawCall的方法:
Dynamic Batching
Static Batching
高級特性Shader降級為統一的低級特性的Shader。


九十五:實時點光源的優缺點是什么?
答:可以有cookies – 帶有 alpha通道的立方圖(Cubemap )紋理。點光源是最耗費資源的。


九十六:Unity的Shader中,Blend SrcAlpha OneMinusSrcAlpha這句話是什么意思?
答:作用就是Alpha混合。公式:最終顏色 = 源顏色 源透明值 + 目標顏色(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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,182評論 6 543
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,489評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,290評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,776評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,510評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,866評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,860評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,036評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,585評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,331評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,536評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,058評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,754評論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,154評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,469評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,273評論 3 399
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,505評論 2 379

推薦閱讀更多精彩內容

  • Unity技術面試題 一:什么是協同程序? 答:在主線程運行時同時開啟另一段邏輯處理,來協助當前程序的執行。換句話...
    沐冉閱讀 2,906評論 1 19
  • [Unity]技術學習路線圖(長期更新) Unity技術面試題 一:什么是協同程序?答:在主線程運行時同時開啟另一...
    肖浩唄閱讀 23,581評論 15 243
  • 111. [動畫系統]如何將其他類型的動畫轉換成關鍵幀動畫? 動畫->點緩存->關鍵幀 112. [動畫]Unit...
    胤醚貔貅閱讀 13,143評論 3 90
  • 一:什么是協同程序? 答:在主線程運行時同時開啟另一段邏輯處理,來協助當前程序的執行。換句話說,開啟協程就是開啟一...
    好怕怕閱讀 3,913評論 2 23
  • “Seeing really clearly what we get when we get caughtup i...
    qf平凡的凡閱讀 2,309評論 0 3