.NET面試題系列(五)數據結構(Array、List、Queue、Stack)及線程安全問題
集合
1. Array(數組):
分配在連續內存中,不能隨意擴展,數組中數值類型必須是一致的。數組的聲明有兩種形式:直接定義長度,然後賦值;直接賦值。
缺點:插入數據慢。
優點:性能高,數據再多性能也沒有影響
特別註意:Array不是線程安全,在多線程中需要配合鎖機制來進行,如果不想使用鎖,可以用ConcurrentStack這個線程安全的數組來替代Array。
2. ArrayList(可變長度的數組)
不必在聲明的時候指定長度,即長度可變;可以存放不同的類型的元素。
致命缺點:無論什麽類型存到ArrayList中都變為object類型,使用的時候又被還原成原先的類型,所以它是類型不安全的,當值類型存入的時候,
會發生裝箱操作, 變為object引用類型,而使用的時候,又將object類型拆箱,變為原先的值類型,這尼瑪,你能忍?
結論:不推薦使用,建議使用List代替!!
特別註意:ArrayList不是線程安全,在多線程中需要配合鎖機制來進行。
3. List<T> (泛型集合) 推薦使用
內部采用array實現,但沒有拆箱和裝箱的風險,是類型安全的
特別註意:List<T>不是線程安全,在多線程中需要配合鎖機制來進行,如果不想使用鎖,可以用ConcurrentBag這個線程安全的數組來替代List<T>
4. LinkedList<T> 鏈表
在內存空間中存儲的不一定是連續的,所以和數組最大的區別就是,無法用下標訪問。
優點:增加刪除快,適用於經常增減節點的情況。
缺點:無法用下標訪問,查詢慢,需要從頭挨個找。
特別註意:LinkedList<T>不是線程安全,在多線程中需要配合鎖機制來進行。
5. Queue<T> 隊列
先進先出,入隊(Enqueue)和出隊(Dequeue)兩個操作
特別註意:Queue<T>不是線程安全,在多線程中需要配合鎖機制來進行,如果不想使用鎖,線程安全的隊列為 ConcurrentQueue。
實際應用場景:利用隊列解決高並發問題(詳見:http://www.cnblogs.com/yaopengfei/p/8322016.html)
6. Stack<T> 棧
後進先出,入棧(push)和出棧(pop)兩個操作
特別註意:Stack<T>不是線程安全
7. Hashtable
典型的空間換時間,存儲數據不能太多,但增刪改查速度非常快。
特別註意:Hashtable是線程安全的,不需要配合鎖使用。
8. Dictionary<K,T>字典 (泛型的Hashtable)
增刪改查速度非常快,可以用來代替實體只有id和另一個屬性的時候,大幅度提升效率。
特別註意:Dictionary<K,T>不是線程安全,在多線程中需要配合鎖機制來進行,如果不想使用鎖,線程安全的字典為 ConcurrentDictionary。
強調: 以上8種類型,除了Hashtable是線程安全,其余都不是,都需要配合lock鎖來進行,或者采用 ConcurrentXXX來替代。
四大接口
1. IEnumerable
是最基本的一個接口,用於叠代使用,裏面有GetEnumerator方法。
2. ICollection
繼承了IEnumerable接口,主要用於集合,內部有Count屬性表示個數,像ArrayList、List、LinkedList均實現了該接口。
3. IList
繼承了IEnumerable 和 ICollection,實現IList接口的數據接口可以使用索引訪問,表示在內存上是連續分配的,比如Array、List。
4. IQueryable
這裏主要和IEnumerable接口進行對比。
Enumerable裏實現方法的參數是Func委托,Queryable裏實現的方法的參數是Expression表達式。
實現IQueryable和IEnumabler均為延遲加載,但二者的實現方式不同,前者為叠代器模式,參數為Func委托,後者為Expression表達式目錄樹實現。
yield關鍵字
1. yield必須出現在IEunmerable中
2. yield是叠代器的狀態機,能做到延遲查詢,使用的時候才查詢,可以實現按序加載
.NET面試題系列(五)數據結構(Array、List、Queue、Stack)及線程安全問題