zoukankan      html  css  js  c++  java
  • .NET面试题系列(五)数据结构(Array、List、Queue、Stack)及线程安全问题

    常用数据结构的时间复杂度

    如何选择数据结构

    Array (T[])

    • 当元素的数量是固定的,并且需要使用下标时。

    Linked list (LinkedList<T>)

    • 当元素需要能够在列表的两端添加时。否则使用 List<T>。

    Resizable array list (List<T>)

    • 当元素的数量不是固定的,并且需要使用下标时。

    Stack (Stack<T>)

    • 当需要实现 LIFO(Last In First Out)时。

    Queue (Queue<T>)

    • 当需要实现 FIFO(First In First Out)时。

    Hash table (Dictionary<K,T>)

    • 当需要使用键值对(Key-Value)来快速添加和查找,并且元素没有特定的顺序时。

    Tree-based dictionary (SortedDictionary<K,T>)

    • 当需要使用价值对(Key-Value)来快速添加和查找,并且元素根据 Key 来排序时。

    Hash table based set (HashSet<T>)

    • 当需要保存一组唯一的值,并且元素没有特定顺序时。

    Tree based set (SortedSet<T>)

    • 当需要保存一组唯一的值,并且元素需要排序时。

    http://www.cnblogs.com/gaochundong/p/data_structures_and_asymptotic_analysis.html#hashtable

    集合

    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是迭代器的状态机,能做到延迟查询,使用的时候才查询,可以实现按序加载

  • 相关阅读:
    visual studio notes
    使用.net创建activex控件
    在程序中打开/关闭monitor or lcd
    Memory Barrier in Compiler and CPU
    被动工作与主动工作
    排序算法总结
    经典计算机基础数据结构:二叉树
    微软的Challenge文化
    海量数据处理方法的分析
    数组
  • 原文地址:https://www.cnblogs.com/cnki/p/9248929.html
Copyright © 2011-2022 走看看