C#基础及相关知识点

基本概念:

程序:数据+算法

面向对象的三大特性:封装,继承,多态

堆栈(stack):在RAM区域,编译器自动分配释放,通过操作堆栈指针可以直接操作这部分内存,创建程序时编译器需要知道从栈里分配多少存储空间
堆(heap):也在RAM中,由程序员分配释放,区别于栈就是堆不需要知道创建对象时需要从堆里分配多大的存储空间,也不知道存储多长时间
值类型的实例分配在栈上,引用类型分配在托管堆上。
装箱:把值类型转换为 object 类型或由此值类型实现的任何接口类型
拆箱:把引用类型转换为值类型
装箱比拆箱更消耗内存和CPU处理时间,尽量避免拆装箱。

委托:委托是一个,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。

事件:对象的某个状态发生了变化所引起的行为。

抽象类:抽象类是能够包含抽象成员的类。抽象类只能作为基类使用,不能被实例化(为子类提供模板,但不具体实现,如编写数据访问抽象基础类)。

抽象方法:只包含方法定义,但没有具体实现的方法,需要其子类或者子类的子类来具体实现。

虚方法:虚方法就是可以被子类重写的方法,如果子类重写了虚方法,那么运行时将使用重写后的逻辑,如果没有重写,则使用父类中虚方法的逻辑.(选择性重写,如报表)

接口:接口是从抽象类演变而来的,如果抽象类中的所有方法都是抽象方法,这个抽象类就可以叫做接口(要求子类实现所有接口方法,可多继承,可以包含属性,索引器,不能用成员变量)。

进程(Process):是Windows系统中的一个基本概念,它包含着一个运行程序所需要的资源。一个正在运行的应用程序在操作系统中被视为一个进程,进程可以包括一个或多个线程。线程是操作系统分配处理器时间的基本单元,在进程中可以有多个线程同时执行代码。进程之间是相对独立的,一个进程无法访问另一个进程的数据(除非利用分布式计算方式),一个进程运行的失败也不会影响其他进程的运行,Windows系统就是利用进程把工作划分为多个独立的区域的。进程可以理解为一个程序的基本边界。是应用程序的一个运行例程,是应用程序的一次动态执行过程。

线程(Thread):是进程中的基本执行单元,是操作系统分配CPU时间的基本单位,一个进程可以包含若干个线程,在进程入口执行的第一个线程被视为这个进程的主线程。在.NET应用程序中,都是以Main()方法作为入口的,当调用此方法时系统就会自动创建一个主线程。线程主要是由CPU寄存器、调用栈和线程本地存储器(Thread Local Storage,TLS)组成的。CPU寄存器主要记录当前所执行线程的状态,调用栈主要用于维护线程所调用到的内存与数据,TLS主要用于存放线程的状态信息。

设计模式

单例模式:一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,避免频繁创建对象,节约内存。(饥饿、懒汉模式)

工厂模式:现了对责任的分割,它提供了专门的工厂类用于创建对象,客户端可以免除直接创建产品对象的责任,而仅仅“消费”产品。

抽象工厂模式(多个抽象产品类,增加抽象类),建造者模式,原型模式,适配器模式,策略模式等

框架模式

MVC(Model-View-Controller)、MVVM(Model-View-ViewModel)、MTV、MVP、CBD、ORM(对象关系映射 如:EF)

排序算法:选择排序,插入排序,冒泡排序,希尔排序,归并排序,快速排序,堆排序,基数排序,桶排序,基数排序   参考:https://blog.csdn.net/chenlong_cxy/article/details/116563972

哈希:是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值,简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数(MD5,SHA-1)。

同步与异步:
同步是顺序执行,执行完一个再执行下一个,需要等待和协调运行。异步是彼此独立运行,在等待某事件的过程中继续做其他事情。

并发与并行:
并发:一个处理器同时处理多个任务。
并行:多个处理器或者多核处理器同时处理多个不同任务。

多线程:
优点:1.资源分配更合理,并行处理程序。2.随时可以停止 。3.可设置优先级。
缺点:1.在耗时或占用大量资源时容易引发阻塞,使界面卡死。2.增加了CPU额外开销。3.产生竞争关系,导致线程死锁。

多线程处理:
1.主线程等待一个或多个子线程执行完后再执行(或者)等待多个子线程中任何一个任务完成再执行
task1.Wait():等待task1线程完成再执行后面操作
Task.WaitAll(task1,task2):等待task1,task2线程完成再执行后面操作
Task.WaitAny(task1,task2):等待task1或者task2完成再执行后面操作
2.某个子线程等待一个或多个子线程执行完后再执行(或者)等待多个子线程中任何一个任务完成再执行
Task.WhenAll(task1,task2)
Task.WhenAny(task1,task2)
3.线程嵌套(父子关系):在复杂的多线程编程中,需要更清晰的表现出线程之间的关系时使用。
TaskCreationOptions.AttachedToParent(附加到父级线程),parentTask.Start();parentTask.Wait();
4.开启长耗时任务的线程
TaskCreationOptions.LongRunning
5.线程取消 
CancellationTokenSource cts=new CancellationTokenSource();cts.Token,cts.Cancel();
6.线程取消并自动清理
cts.Token.Register(()=>{//业务});
7.线程延时自动取消,不需要手动取消
CancellationTokenSource cts=new CancellationTokenSource(2000);
异常处理:
单线程发生异常,如果需要捕捉,只是try-catch;但是多线程内部发生异常之后,在子线程内部try-catch是无法捕捉到的。但是异常会在Wait中抛出
try{tasl.wait()}catch(AggregateException ex){//异常处理}
参考url:https://blog.csdn.net/qq_33101689/article/details/106228965

线程池:使那些休眠或等待的线程暂时挂起,以减少占用资源,等需要用时重新启动,减少了大量创建和销毁线程的开销.
设置线程池最大最小:ThreadPool.SetMaxThreads(int workerThreads,int CompletionPortThreads);
添加任务到线程池:ThreadPool.QueueUserWorkItem(new WaitCallBack(方法名),?参数);
Control.Invoke:在拥有此控件的基础窗口句柄的线程上同步执行指定委托;Control.BeginInvoke:在拥有此控件的基础窗口句柄的线程上异步执行指定委托;
多线程缺点:1.等候使用共享资源时造成程序的运行速度变慢。这些共享资源主要是独占性的资源 ,如打印机等。 2.对线程进行管理要求额外的 CPU开销。 3.线程的死锁。即较长时间的等待或资源竞争以及死锁等多线程症状。

内存泄漏解决方案:1.检测未退订的事件 2.静态变量 3.非托管资源手动回收资源 4.Dispose方法没被调用 5.当一个查询语句查询出来的数据量很大,达到几百万条数据时存放到datatable 或dataset中也会造成内存溢出,这是可以采用分页查询等其他方法来解决 URL: https://www.cnblogs.com/bile/p/4966796.html
托管资源和非托管资源:托管资源.net自动回收, 非托管资源指的是.NET不知道如何回收的资源,最常见的一类非托管资源是包装操作系统资源的对象,例如文件,窗口,网络连接,数据库连接,画刷,图标等。Microsoft为非托管资源的回收专门定义了一个接口:IDisposable,接口中只包含一个Dispose()方法。url:https://blog.csdn.net/zlwzlwzlw/article/details/7918633

数据结构:数据结构(Data Structure) 是在相互之间存在的一种或多种特定关系的数据元素集合.
常用数据结构:1.数组Array 2.数组列表ArrayList 3.列表List 4.哈希表 Hashtable<K,T> 5. 字典Dictionary<K,T>  6.链表LinkedList 7.队列Queue<T> 8. 栈Stack<T> 

海量数据库优化:
1.选择正确的存储引擎, MySQL为例,包括有两个存储引擎 MyISAM 和 InnoDB
2.优化字段的数据类型
3.为搜索字段添加索引
4.避免使用Select *
5.使用 ENUM 而不是 VARCHAR:ENUM 类型是非常快和紧凑的。在实际上,其保存的是 TINYINT,但其外表上显示为字符串。
6.尽可能的使用 NOT NULL
7.固定长度的表会更快
8.垂直分割:“垂直分割”是一种把数据库中的表按列变成几张表的方法
9.EXPLAIN 你的 SELECT 查询:使用 EXPLAIN 关键字可以让你知道MySQL是如何处理你的SQL语句的
10.使用缓存(Nosql,Redis)
11.提升硬件

缓存原理

  1. 检查用户请求的数据时缓存中是否存在,若存在直接返回,无需查询数据库。
  2. 若请求数据在缓存中查询不到,去查询数据库,返回数据,同时把数据存储到缓存中一份。
  3. 保持缓存的“新鲜性”,每当数据发生变化的时候,要同步更新缓存的信息,确保用户不会在缓存取到旧的数据。

WPF技术:

依赖属性:可以自己没有值,并能通过使用Binding从数据源获取值得属性
附加属性:实际上是一种依赖属性,把自己的属性附加给其他对象,使其他对象能引用该附加属性。(如Grid.row) 

Entity Framework(EF):微软官方提供的ORM工具,ORM让开发人员节省数据库访问的代码时间,将更多的时间放到业务逻辑层代码上。EF提供变更跟踪、唯一性约束、惰性加载、查询事物等。开发人员使用Linq语言,对数据库操作如同操作Object对象一样省事。
EF有三种使用场景,1. 从数据库生成Class,2.由实体类生成数据库表结构,3.  通过数据库可视化设计器设计数据库,同时生成实体类。对应三种编程方式:
1.DataBase First:在设计器中逆向生成Model,并有Model自动生成所有的类。
2.Model First:在设计器中创建Model,并用Model生成数据库。所有的类由Model自动生成。
3.Code First(又分New DataBase,Existing DataBase):代码优先,同Model First方式,区别在于不再需要EDM文件,所有的映射通过“数据注释”和“fluent API”进行映射和配置,"Code First"并不代表一定就必须通过数据类来定义模型,事实上也可以通过现有数据库生成数据类。

ORM:是将数据存储从域对象自动映射到关系型数据库的工具。ORM主要包括3个部分:域对象、关系数据库对象、映射关系。ORM使类提供自动化CRUD,使开发人员从数据库API和SQL中解放出来。

EF优缺点:
优点:
1.简洁的Linq to Sql语句大大提高了开发人员的效率,不要再写复杂的sql语句;
2.不再需要再管应用程序如何去连接数据库;
3.EF可以用作用于数据服务和OData Service的基础设施;
缺点:
1.由于linq语句编译之后就是sql,对于这种自动生成的sql语句无法控制;
2.EF的运行机制会消耗大量内存,大大降低了程序运行效率,从而导致降低了用户在客户端的体验效果;
3.一旦数据结构发生变化,需要更新EF数据model;有时还可能会出现找不到更新过的实体类这种情况;

UML(统一建模语言):一个支持模型化和软件系统开发的图形化语言,为软件开发的所有阶段提供模型化和可视化支持,包括由需求分析到规格,到构造和配置。

测试:

测试分类:单元测试(对单独的代码块分别进行测试,常用assert(断言)代码),集成测试,系统测试。
测试用例(Test Case):是指对一项特定的软件产品进行测试任务的描述,体现测试方案、方法、技术和策略。其内容包括测试目标、测试环境、输入数据、测试步骤、预期结果、测试脚本等,最终形成文档。简单地认为,测试用例是为某个特殊目标而编制的一组测试输入、执行条件以及预期结果,用于核实是否满足某个特定软件需求。
黑盒测试:又名为功能测试,主要目的是发现软件设计的需求或者是软件设计规格说明书中的错误缺陷。将程序看成不能打开的黑盒子,不考虑程序内部结构和特性的基础上通过程序接口进行测试,检查程序功能是否按照设计需求以及说明书的规定能够正常打开使用(),测试方法:等价类划分法,边界值分析法,因果图法,错误推测法。
白盒测试:白盒测试也称为结构测试,主要用于检测软件编码过程中的错误。程序员的编程经验、对编程软件的掌握程度、工作状态等因素都会影响到编程质量,导致代码错误。

Web技术:

AOP(面向切面编程),oAuth(API访问授权的开发标准),OData(开放数据协议),OA:办公自动化
IOC(控制反转)与DI(依赖注入):设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制,减少耦合.--https://www.cnblogs.com/atomy/p/12516304.html
Unity:微软推出的IOC框架,实现AOP面向切面编程,便于代码的后期维护.--https://www.cnblogs.com/shiyh/p/10648608.html
MVC模式:及模型,视图,控制器。模型:MVC需要提供的数据源,负责数据的访问和维护。视图:用于显示模型中数据的用户界面。
控制器:用来处理用户的输入,负责改变模型的状态并选择适当的视图来显示模型的数据。
MVVM模式:MVVM是Model-View-ViewModel的简写。它本质上就是MVC (Model-View- Controller)的改进版。即模型-视图-视图模型。【模型】指的是后端传递的数据。【视图】指的是所看到的页面。【视图模型】mvvm模式的核心,它是连接view和model的桥梁。它有两个方向:一是将【模型】转化成【视图】,即将后端传递的数据转化成所看到的页面。实现的方式是:数据绑定。二是将【视图】转化成【模型】,即将所看到的页面转化成后端的数据。实现的方式是:DOM 事件监听。这两个方向都实现的,我们称之为数据的双向绑定。
Web消息队列:消息队列中间件是分布式系统中重要的组件,主要解决应用耦合,异步消息,流量削锋等问题。实现高性能,高可用,可伸缩和最终一致性架构。是大型分布式系统不可缺少的中间件。目前在生产环境,使用较多的消息队列有ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ等。
Web高并发解决方案:分离,缓存,HTML静态,数据库集群,CDN加速技术。
Web缓存:数据库缓存(redis),服务器缓存,客户端缓存(浏览器缓存.) URL:https://zhuanlan.zhihu.com/p/90507417
内存管理:1.减少无用的堆数据 2.及时释放和回收资源(如:dispose,using) 3.检测内存泄漏. 4.注意代码编写时少产生垃圾,比如String + String就会产生大量的垃圾,建议使用StringBuilder。
.Net Core注入方式:1.构造函数注入 2.view注入 4.通过 HttpContext来获取实例 4.直接注入
.Net Core常用注入:1.ConfigureServices 2.SuppressModelStateInvalidFilter 3.AddControllers 4.AddControllersAsServices  5.AddNewtonsoftJson 6.AddHttpContextAccesso

C++技术:

 句柄(handle):是一个用来标识对象或者项目的标识符,可以用来描述窗体、文件等,值得注意的是句柄不能是常量,Windows之所以要设立句柄,根本上源于内存管理机制的问题,即虚拟地址。简而言之数据的地址需要变动,变动以后就需要有人来记录、管理变动,因此系统用句柄来记载数据地址的变更。在程序设计中,句柄是一种特殊的智能指针,当一个应用程序要引用其他系统(如数据库、操作系统)所管理的内存块或对象时,就要使用句柄.
好处:
  1、我们可以在实现中用尺寸大小固定的(constant-sized)对象来表示尺寸大小不定的(variable-sized)值
  2、我们可以在实现中用运行时绑定(run-time bounding)而不是编译时(compile-timebounding)绑定的方式来处理对象
  3、对于实现的改变通常只会引起一次重新链接,而不是重新编译
  4、我们可以对他人隐藏对象的实现

面试常见问题:

1、单例的懒汉与饥饿

饥饿式天生就是线程安全的,先实例化。

private static Singleton  _singleton = new Singleton();
public static Singleton GetInstance() {   return _singleton;}

懒汉式本身是非线程安全的,后实例化。

private static Singleton  _singleton = null;
public static Singleton GetInstance() {  if(_singleton;}==null) _singleton = new Singleton(); return _singleton;}

2、Socket UDP通信怎么判断是否连接?

a.通过心跳包  

3、thread 与task区别

a.thread是单线程,task是多线程 单线程只能一核多任务,多线程能多核多任务.

b.task可以使用取消令牌来支持取消,thread不能取消.

c.task一个任务可以执行多个线程,thread只能执行一个线程.

d.task可以使用async和await关键字轻松实现异步

e.task可以直接返回结果

f.task默认是后台线程,thread默认是前台线程(前台线程会阻止进程关闭,后台线程随进程关闭而关闭).


版权声明:本文为lvxingzhe3原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。