.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是迭代器的状态机,能做到延迟查询,使用的时候才查询,可以实现按序加载
.NET面试题系列(五)数据结构(Array、List、Queue、Stack)及线程安全问题的更多相关文章
- ASP.NET MVC深入浅出系列(持续更新) ORM系列之Entity FrameWork详解(持续更新) 第十六节:语法总结(3)(C#6.0和C#7.0新语法) 第三节:深度剖析各类数据结构(Array、List、Queue、Stack)及线程安全问题和yeild关键字 各种通讯连接方式 设计模式篇 第十二节: 总结Quartz.Net几种部署模式(IIS、Exe、服务部署【借
ASP.NET MVC深入浅出系列(持续更新) 一. ASP.NET体系 从事.Net开发以来,最先接触的Web开发框架是Asp.Net WebForm,该框架高度封装,为了隐藏Http的无状态模 ...
- 第三节:深度剖析各类数据结构(Array、List、Queue、Stack)及线程安全问题和yeild关键字
一. 各类数据结构比较及其线程安全问题 1. Array(数组): 分配在连续内存中,不能随意扩展,数组中数值类型必须是一致的.数组的声明有两种形式:直接定义长度,然后赋值:直接赋值. 缺点:插入数据 ...
- 【C#复习总结】探究各类数据结构(Array、List、Queue、Stack)及线程安全问题和yeild关键字
前言 先普及一下线程安全和类型安全 线程安全: 如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码.如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的 ...
- 开玩笑Web它servlet(五岁以下儿童)---- 如何解决servlet线程安全问题
servlet默认值是安全线的存在,但说白,servlet安全线实际上是一个多线程线程安全问题.因为servlet它正好是一个多线程的安全问题出现. 每次通过浏览器http同意提交请求,将一个实例se ...
- Java容器--2021面试题系列教程(附答案解析)--大白话解读--JavaPub版本
Java容器--2021面试题系列教程(附答案解析)--大白话解读--JavaPub版本 前言 序言 再高大上的框架,也需要扎实的基础才能玩转,高频面试问题更是基础中的高频实战要点. 适合阅读人群 J ...
- .NET面试题系列[12] - C# 3.0 LINQ的准备工作
"为了使LINQ能够正常工作,代码必须简化到它要求的程度." - Jon Skeet 为了提高园子中诸位兄弟的英语水平,我将重要的术语后面配备了对应的英文. .NET面试题系列目录 ...
- .NET面试题系列[11] - IEnumerable<T>的派生类
“你每次都选择合适的数据结构了吗?” - Jeffery Zhao .NET面试题系列目录 ICollection<T>继承IEnumerable<T>.在其基础上,增加了Ad ...
- C#刷遍Leetcode面试题系列连载(1) - 入门与工具简介
目录 为什么要刷LeetCode 刷LeetCode有哪些好处? LeetCode vs 传统的 OJ LeetCode刷题时的心态建设 C#如何刷遍LeetCode 选项1: VS本地Debug + ...
- .NET面试题系列[0] - 写在前面
.NET面试题系列目录 .NET面试题系列[1] - .NET框架基础知识(1) .NET面试题系列[2] - .NET框架基础知识(2) .NET面试题系列[3] - C# 基础知识(1) .NET ...
随机推荐
- Unity插件-NGUI学习笔记
Anchors 的作用 类似Android里面的.9格式图片的功能, 边框可以随着文字变大而变大. 实现方法: 用NGUI 创建一个Sprite, 命名为TextBg, 一个Label, Label的 ...
- 20135202闫佳歆--week3 跟踪分析Linux内核的启动过程--实验及总结
实验三:跟踪分析Linux内核的启动过程 一.调试步骤如下: 使用gdb跟踪调试内核 qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd r ...
- 《Linux内核分析》第一周学习小结 计算机是如何工作的?
<Linux内核分析>第一周.计算机是如何工作的? 20135204 郝智宇 一.存储程序计算机工作模型 1. 冯诺依曼体系结构: 数字计算机的数制采用二进制:计算机应该按照程 ...
- YQCB冲刺第二周第五天
今天的任务为实现由用户设置每月初始额度的功能. 昨天的任务为实现精准查账的功能. 遇到的问题为界面的布局以及精准查账按什么标准查找,最后决定按分类查账与时间查账相结合. 站立会议 任务面板
- [转载]ValidationExpression验证规则
ValidationExpression验证规则 在ASP.NET中,ValidationExpression 验证规则属性可以根据自已的需要,对输入的数据进行限制,其常用符号如下表所示: 符号 ...
- [转帖] Linux 下面 Find的使用...--- 自己不会用 find
13个实用的Linux find命令示例 原始博客地址: https://www.cnblogs.com/chenshoubiao/p/4838089.html 之前只会用locate 基础 ...
- golang 实现线程池
package main import ( "fmt" "time" ) type Pool struct { Queue chan func() error; ...
- join()方法跟踪
#join方法跟踪java.lang.Thread.join() 进入线程的join方法,实际上线程thread是实现的 runnable接口 class Thread implements Runn ...
- 浅谈final修饰的变量
一直大概的知道final关键字的作用,但是自己实际工作中却很少用,除非在声明一些常量值的时候,今天忽然自己在项目中用一个map进行存储一些值.一开始我只是用private修饰的,心里想的是如果fina ...
- Shell命令——文件目录
Linux只有一个文件系统树,不同的硬件设备可以挂载在不同目录下. 文件或目录有两种表示方式: - 绝对路径:从根目录”/”开始 - 相对路径:从工作目录开始,使用”..”指向父目录,”.”指向当 ...