c# 知識記錄

1、C#代理和C++指針的異同點
委託就是一種引用方法的類型。委託與分配的方法具有相同的行爲,委託可以看作是函數的抽象,委託的實例是一個具體的函數。
----委託VS函數指針
委託和函數指針都描述了函數或者是方法,並且通過統一的接口調用不同的實現。兩者之間的區別
(1)委託是函數的抽象,委託對象是真正的對象。函數指針只是指向函數入口的地址,不具有對象性質。
(2)委託對象可以指向不同類的方法,只要符合委託要求。而C++函數不能指向不同類的方法。
(3)在應用時,C++的指針沒有C#的委託靈活。

委託與事件:
2、事件封裝了委託類型的變量,使得在類的內部,不管你聲明它是public還是protected,它總是private的。
在類的外部,註冊“+=”和註銷“-=”的訪問限定符與你在聲明事件時使用的訪問符相同。
事件的聲明與委託變量delegate的聲明唯一的區別是多了一個event關鍵字。所以聲明一個事件不過類似於聲明一個進行了封裝的委託類型的變量而已。
總結主要區別:

1.事件在類外綁定事件只能用“+=”(“-=”解綁),不能使用‘=’綁定;如果在類內部綁定事件可以用‘=’;

2.委託在類內類外都可以用"+="、"-="、"=";

3.事件的調用(執行)只能在類內調用;委託(公有)在類內類外都可以調用。事件調用比較安全。

2、struct和類的異同點。
類與結構的區別:
(1)C#允許在類裏對字段進行初始化,不允許在結構裏也這樣做。結構裏的字段將被自動設置爲0或NULL。
(2)C#不允許在結構裏聲明一個無參構造器,C#做出這一限制的目的是爲了加快基於結構的數組的創建速度。
(3)繼承能力是類和結構的重要區別之一。結構不支持繼承機制。所有的結構都是從System.ValueType類間接地派生出來的,而System.ValueType類又是從System.Object類派生出來的。但C#不允許程序員聲明一個繼承自某個結構的類,也不允許程序員聲明一個繼承自另一個結構的結構。一旦聲明瞭一個結構,從System.ValueType類一直延續到這個結構的“家譜線”就走到盡頭了。
(4)結構是值類型,類是引用類型。

4、數組,arrylist和list和異同點,
數組
優點:比如說數組在內存中是連續存儲的,所以它的索引速度是非常的快,而且賦值與修改元素也很簡單
缺點:在數組的兩個數據間插入數據也是很麻煩的。還有我們在聲明數組的時候,必須同時指明數組的長度,數組的長度過長,會造成內存浪費,數組和長度過短,會造成數據溢出的錯誤。

ArrayList是.Net Framework提供的用於數據存儲和檢索的專用類,它是命名空間System.Collections下的一部分。它的大小是按照其中存儲的數據來動態擴充與收縮的。所以,我們在聲明ArrayList對象時並不需要指定它的長度。

ArrayList繼承了IList接口,所以它可以很方便的進行數據的添加,插入和移除.

List
數據類型要求相同,類型安全,不需要頻繁裝箱拆箱。可視爲是ArrayList的改進,底層實現與ArrayList一樣,都使用Array

字典存儲的內部邏輯

Dictionary<Tkey,Tvalue>是Hastbale的泛型實現。
Dictionary和HashTable內部實現差不多,但前者無需裝箱拆箱操作,效率略高一點。

Hashtable 和 Dictionary <K, V> 類型

1):單線程程序中推薦使用 Dictionary, 有泛型優勢, 且讀取速度較快, 容量利用更充分.
2):多線程程序中推薦使用 Hashtable, 默認的 Hashtable 允許單線程寫入, 多線程讀取, 對 Hashtable 進一步調用 Synchronized()方法可以獲得完全線程安全的類型. 而Dictionary 非線程安全, 必須人爲使用 lock 語句進行保護, 效率大減.
3):Dictionary 有按插入順序排列數據的特性 (注: 但當調用 Remove() 刪除過節點後順序被打亂), 因此在需要體現順序的情境中使用 Dictionary 能獲得一定方便.

HashTable中的key/value均爲object類型,由包含集合元素的存儲桶組成。存儲桶是 HashTable中各元素的虛擬子組,與大多數集合中進行的搜索和檢索相比,存儲桶可令搜索和檢索更爲便捷。每一存儲桶都與一個哈希代碼關聯,該哈希代碼是使用哈希函數生成的並基於該元素的鍵。HashTable的優點就在於其索引的方式,速度非常快。如果以任意類型鍵值訪問其中元素會快於其他集合,特別是當數據量特別大的時候,效率差別尤其大。

HashTable的應用場合有:做對象緩存,樹遞歸算法的替代,和各種需提升效率的場合。

對於C# 中的Dictionary,具體實現如下
(1)最小數據單元是一個叫Entry的結構體。用entry[]存放元素
(2)buckets[]用於存放hash桶。
(3)數據Add進字典的時候,會根據Key生成一個hashcode,根據這個hashcode去決定該數據所在的桶。
每個桶中會存放一個整型值,這個值指向桶中存放的第一個元素(真正數據都在entry數組中)。entry中的每一個值都有next指針,從而指向下一個值(拉鍊法)。
(4)Remove的時候,把把要刪除元素的前一個節點的next指針置爲-1即可
(5)C#中碰撞次數的閾值是100,碰撞過多或者數組已滿的時候就說明該擴容了。擴容過程是:
①如果是數組滿了:直接申請兩倍於現在大小的buckets[]、entries[],然後將現有元素拷貝到新的數組中
②如果是碰撞過多:在.net framework中會直接擴容,並重新計算哈希值,在.net core中採取和JDK相似的策略(使用紅黑樹來存儲元素)

鏈表和循環鏈表的使用.

堆內存的GC問題,

設計模式,

AssetBundle打包的資源是存在依賴關係的,你打包了這個資源依賴於另一個資源他會自動的把依賴資源也打進這個包,如果不注意打包的策略,就會發生同一個資源被重複的打包,產生資源冗餘,比如你要把不同的UI類型分開打包,他們都會把自己使用的圖集都打到AB包中,這樣直接進行打包,那這個貼圖就會被打入AB包兩次,很浪費資源,所以在打包的時候要注意打包策略
UI公用資源包打成一個包
模型動畫可以根據角色來分開打包
特效部分可以打入一個包裏
聲音部分可以打到一個包裏
打包前先使用AssetDatabase.CollectDependencies遍歷所有資源收集他們間的依賴關係,在後面打包的時候按照每個資源被依賴的深度進行分級,先打包級別較低的,如shader,script這些資源被其他資源依賴但不會依賴別的資源,級別最低。如prefab依賴前面的所有資源,級別最高,放在最後打包。一般是按照資源的類型(prefab,mesh,animator,texture,script…)進行分級。即使這樣按類型分好級後仍是不夠的,因爲同一級的資源也有可能產生相互依賴的關係。比如使用NGUI,一個面板prefab依賴於幾個掛UIAtlas的prefab,這種同級的依賴需要用深度優先遍歷對他們進行排序以確定依賴關係。這個依賴關係使用序列化文件記錄下來,供後面加載包的時候先加載所有被依賴的包使用。每次更新的時候這個依賴關係的序列化文件也要同其他資源一起更新。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章