1,值类型与引用类型的区别
值类型:struct,enum,int,double,float,char,bool,decimal
引用类型:class,delegate,interface,array,object,string
相同点:
- 引用类型可以实现接口,值类型中的struct也可以实现接口
- 都继承自System.Object类
不同点:
- 范围方面
- 内存分配方面:
- 数组的元素不管是值类型还是引用类型,都存储在托管堆上。
- 引用类型在栈中存储一个引用,其实际的存储位置位于托管堆。简称引用类型部署在托管堆上。
- 值类型总是分配在它声明的地方:作为字段时,跟随其所属的变量(实例)存储;作为局部变量时,存储在栈上。
- 适用场合:
- 值类型在内存管理方面具有更好的效率,并且不支持多态,适合用做存储数据的载体;
- 引用类型支持多态,适用于定义应用程序的行为。
- 引用类型可以派生出新的类型,而值类型不能,因为所有的值类型都是密封(seal)的;
- 引用类型可以包含null值,值类型不能(int? 是通过int 装箱 为引用类型实现的)
- 引用类型变量的赋值只复制对对象的引用,而不复制对象本身。而将一个值类型变量赋给另一个值类型变量时。将复制包含值
2,什么是装箱、拆箱
装箱:把值类型转换成引用类型 (对值类型在堆中分配一个对象实例,并将该值复制到新的对象中)
拆箱:把引用类型转换成值类型(检查对象实例,确保它是给定值类型的一个装箱值,将该值从实例复制到值类型变量中)
int i = 1;
System.Object obj = i; //将i装箱
int j = (int)obj; //将obj拆箱
在装箱的时候不需要显式转换,拆箱时需要
3,实现多线程的几种方法
一,异步多线程
二,Threads线程
三,ThreadPool线程池
四,Task
五,Parallel
4,多线程下C#如何保证线程安全?
多线程编程相对于单线程会出现一个特有的问题,就是线程安全的问题。所谓的线程安全,就是如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。线程安全问题都是由全局变量及静态变量引起的。
低版本C#中可以用锁机制来保证,高版本C#中加入async和await来保证线程安全
public async Task<List<ModelList>> GetList(ModelRequest model) => await bll.GetList(model);
5,内存溢出与内存泄露
内存溢出 out of memory:程序申请内存时,没有足够的内存空间供其使用,出现内存溢出。比如申请给一个int类型赋值一个超出最大字节的long型数值,就是内存溢出。
内存泄露 memory leak:指程序在申请内存后,无法释放已经申请的内存空间,一次内存泄露危害可以忽略,但是内存泄露堆积后果很严重,无论多少内存,迟早被占光。
(比如一个for循环里面,每一次循环都开一个线程,让它一直跑,当跑到后面时,前面的线程申请的内存空间有一部分未能释放,内存泄露堆积,慢慢的内存就不够用了,就造成了内存溢出)
6,GC原理
GC如其名,就是垃圾收集,当然这里仅就内存而言。Garbage Collector(垃圾收集器,在不至于混淆的情况下也称为GC)以应用程序的root为基础,遍历应用程序在Heap上动态分配的所有对象,通过识别它们是否被引用来确定哪些对象是已经死亡的、哪些仍需要被使用。已经不再被应用程序的root或者别的对象所引用的对象就是已经死亡的对象,即所谓的垃圾,需要被回收。这就是GC工作的原理
7,虚方法与抽象方法的区别
抽象方法是只有方法名称,没有方法体(也就是没有方法具体实现),子类必须重写父类抽象方法;
虚函数是该方法有方法体,但是子类可以覆盖,也可不覆盖。
(1)虚方法有方法体,抽象方法没有方法体。抽象方法是一种强制派生类覆盖的方法,否则派生类将不能被实例化;
(2)抽象方法只能在抽象类中声明,虚方法不是;
(3)派生类必须重写抽象类中的抽象方法,虚方法则不必要。
8,高并发抢购业务场景如何避免超售问题 Redis缓存+消息队列
1,用户下单,Redis存储用户标识,判断用户是否重复下单,否,将该请求丢进队列后返回;若是,返回;
2,接收到消息后,往数据库(或redis服务器)存储一条记录,此时用户界面展示动态效果
3,每2~5s读取数据库(或redis服务器)中的的数据,拿到前N条后判断是否超出库存,若未超出,改变下单记录的状态为下单成功(或将redis的数据插入订单数据库),返回结果。若超出,排序将前X条(库存数)设为有效订单,其余失败。
9,Hashtable哈希表及其与Dictionary字典的区别
两者都是键值对的形式,但区别在于:
序号 | 键 | HashTable 哈希表 | Dictionary 字典 |
---|---|---|---|
1 | 定义 | HashTable是集合的非通用类型,用于在键/值对中存储数据,并在System.Collections命名空间中定义。 | Dictionary是在System.Collection.Generics命名空间下定义的通用类型集合,该命名空间还以键/值对的形式存储数据。 |
2 | 数据类型 | 在HashTable中,可以将相同或不同的数据类型数据存储为键和值,没有限制,键和值必须具有相同的DataType,然后只能存储在HashTable中。同样,也无需指定键和值的类型。 | 如果Dictionary的键和值必须具有相同的DataType,则只能将其存储在Dictionary中,并且必须在创建时指定键和值的类型。 |
3 | 数据检索 | 在HashTable的情况下,由于装箱和拆箱,数据检索比Dictionary中的数据检索要慢。 | 在Dictionary数据的情况下,检索速度更快,因为在Dictionary的情况下不会进行装箱和拆箱。 |
4 | 空值 | 如果HashTable空值作为访问时的键处理,则该键在给定的HashTable中不存在,则返回空值作为结果。 | 在Dictionary的情况下,如果尝试访问给定Dictionary中不存在的键,则会出错。 |
5 | 数据顺序 | HashTable不维护插入键值数据的任何顺序。 | Dictionary保持存储值的插入顺序。 |