C# 常见面试问题汇总

一、c#垃圾回收机制html

    从如下方面入手展开:  一、压缩合并算法   二、代的机制  三、GC调用终结器 Garbage Collectorc++

   . NET采用了和Java相似的方法由CLR(Common Language Runtime)来管理 程序员

     .NET的GC机制有这样两个问题:web

  首先,GC并非能释放全部的资源。它不能自动释放非托管资源。面试

  第二,GC并非实时性的,这将会形成系统性能上的瓶颈和不肯定性。redis

  GC并非实时性的,这会形成系统性能上的瓶颈和不肯定性。因此有了IDisposable接口,IDisposable接口定义了Dispose方法,这个方法用来供程序员显式调用以释放非托管资源。使用using语句能够简化资源管理。算法

       具体详见:http://www.javashuo.com/article/p-gazsdfaq-ck.htmlsql

二、委托和事件数据库

     先说它的定义:委托的本质是类,类型安全的指针,而后从用途上考虑,事件是包装的委托,但事件不是委托。事件是由一个私有委托和add、remove 方法组成。编程

     事件、索引器、属性本质都是方法。接口只能够定义方法。因此接口也能够定义“事件、索引器、属性”,由于他们的本质也是add、remove 方法。

     委托是一种能够指向方法的数据类型,能够声明委托类型变量。

     声明委托的方式:delegate返回值类型   委托类型名(参数)

     好比delegate void MyDel(int n) 。C#中默认写了2中委托Action<>,Func<>,Action基本上都是void没有返回值,Func是有返回值的

    

 1 using System.Collections.Generic;
 2 using System.Linq;
 3 using System.Text;
 4 using System.Threading.Tasks;
 5 
 6 namespace TestConsole
 7 {
 8     delegate void MyDel();
 9     class Program
10     {
11 
12         static void Main(string[] args)
13         {
14             person p = new person();
15             p.QingZhu += ShowMsg;
16             p.age = 24;
17             Console.ReadKey();
18         }
19         static void ShowMsg()
20         {
21             Console.WriteLine("今年是你的本命年!恭喜你");
22         }
23     }
24     class person
25     {
26         private int Age;
27         public int age
28         {
29             get
30             {
31                 return age;
32             }
33             set
34             {
35                 if (value % 12 == 0)
36                 {
37                     if (QingZhu != null)
38                     {
39                         QingZhu();//执行事件
40                     }
41                 }
42             }
43         }
44         public event MyDel  QingZhu;
45     }
46 }
View Code

 

 1 using System;
 2 using System.Collections;
 3 using System.Collections.Generic;
 4 using System.Linq;
 5 using System.Text;
 6 using System.Threading.Tasks;
 7 
 8 namespace TestConsole
 9 {
10     delegate void MyDel();
11     class Program
12     {
13 
14         static void Main(string[] args)
15         {
16             person p = new person();
17             p.qingzhu += ShowMsg;
18             p.age = 24;
19             Console.ReadKey();
20         }
21         static void ShowMsg()
22         {
23             Console.WriteLine("今年是你的本命年!恭喜你");
24         }
25     }
26     class person
27     {
28         private int Age;
29         public int age
30         {
31             get
32             {
33                 return age;
34             }
35             set
36             {
37                 if (value % 12 == 0)
38                 {
39                     if (this.QingZhu != null)
40                     {
41                         this.QingZhu();//执行事件
42                     }
43                 }
44             }
45         }
46         private  MyDel  QingZhu;
47         public event MyDel qingzhu
48         {
49             add
50             {
51                 this.QingZhu += value;
52             }
53             remove
54             {
55                 this.QingZhu -= value;
56             }
57         }
58 
59     }
60 }
View Code

三、c#索引

    索引能够是字符串类型的,能够容许有多个索引参数,下面的方法我就能够定义多个参数。常见的Dictory<string,string>也是索引的一种。在IL中本质实际上是Get_Item 方法(无参数)、Set_Item 方法(参数:value)。

 1 class MyIntIndex
 2     {
 3         private static string[] name = { "dandan", "chizi", "jianguo" };
 4         public string this[int index]
 5         {
 6             get
 7             {
 8                 string n = name[index];
 9                 return n;
10             }
11             set
12             {
13                 name[index] = value;
14             }
15         }
16     }
17 }
View Code

四、装箱和拆箱

    值类型和引用类型之间的转换。频繁装箱和拆箱会致使系统性能下降,可考虑用泛型。值类型赋值给object为装箱操做,值类型赋值给object拆箱(显示转换)。装什么类型拆箱就是什么类型,除非C#中convert.toInt32 等内置的这些方法能够强制拆箱。

五、泛型

   考得很少,但咱们日常用的比较多。因此对泛型的一些东西须要了解,如泛型约束等。 

   泛型约束 public void GetEntity<T>() where T:class

    where T :struct //约束T必须为值类型
    where K : class //约束K必须为引用类型
    where V : IComparable //约束V必须是实现了IComparable接口
    where W : K //要求W必须是K类型,或者K类型的子类
    where X :class ,new () // 或者写出 new class() ;   X必须是引用类型,而且要有一个无参的构造函数(对于一个类型有多有约束,中间用逗号隔开)

六、c#如何调用c++ 的dll?为何能够调用

     右击添加类中的“TypeLib中的MFC类”选项实现跨平台调用。添加好后会生成h文件和cpp文件

   tjdmwj2tjdmwj3tjdmwj4

   填写完后Function.h文件会报错,错误类型以下。这里须要在C++项目里面设置,让动态库受到公共语言运行时的支持。以下图所示:打开项目属性

   tjdmwj4tjdmwj5tjdmwj6

     C#和C++在vs中的语法类型都会编译成CTS(Common Type System通用数据类型)生成.net 中有CLS(Common Language Specification公共语言允规范) 并在IL代码中的CLR(Common Language Runtime 公共语言运行池)中运行。

     Int和Int32,string与String的区别,一个是C#代码中的类型,一个是IL中的CTS通用数据类型

七、托管资源和非托管资源

    问题:一、定义  二、如何释放

   托管资源是指由CLR管理分配和释放的资源。托管资源有GC释放,非托管资源由程序员本身释放,能够实现dispose接口。

   关于托管资源,就不用说了撒,像简单的int,string,float,DateTime等等,.net中超过80%的资源都是托管资源。

   非托管资源如何释放,.NET Framework 提供 Object.Finalize 方法,它容许对象在垃圾回收器回收该对象使用的内存时适当清理其非托管资源。

   值类型在栈内存中,方法结束自动释放,引用类型在堆内存中须要GC来回收

   

~MyClass()
{
  // Perform some cleanup operations here.
}
  该代码隐式翻译为下面的代码。
protected override void Finalize()
{
  try
  {
    // Perform some cleanup operations here.
  }
  finally
  {
    base.Finalize();
  }
}

 

在一个包含非托管资源的类中,关于资源释放的标准作法是:

(1) 继承IDisposable接口;

(2) 实现Dispose()方法,在其中释放托管资源和非托管资源,并将对象自己从垃圾回收器中移除(垃圾回收器不在回收此资源);

(3) 实现类析构函数,在其中释放非托管资源。

 

 1 PublicclassBaseResource:IDisposable
 2 {
 3   PrivateIntPtr handle; // 句柄,属于非托管资源
 4   PrivateComponet comp; // 组件,托管资源
 5   Privateboo isDisposed = false;// 是否已释放资源的标志
 6    PublicBaseResource()
 7    {
 8    }
 9    //实现接口方法
10    //由类的使用者,在外部显示调用,释放类资源
11    Publicvoid Dispose()
12    {
13      Dispose(true);// 释放托管和非托管资源
14      //将对象从垃圾回收器链表中移除,
15     // 从而在垃圾回收器工做时,只释放托管资源,而不执行此对象的析构函 
16 17     GC.SuppressFinalize(this);
18     }
19     //由垃圾回收器调用,释放非托管资源
20     ~BaseResource()
21      {
22       Dispose(false);// 释放非托管资源
23      }
24     //参数为true表示释放全部资源,只能由使用者调用
25     //参数为false表示释放非托管资源,只能由垃圾回收器自动调用
26    //若是子类有本身的非托管资源,能够重载这个函数,添加本身的非托管 
27     资源的释放
28    //可是要记住,重载此函数必须保证调用基类的版本,以保证基类的资源 
29     正常释放
30     Protected virtual void Dispose(booldisposing)
31    {
32      If(!this.disposed)// 若是资源未释放 这个判断主要用了防止对象被多 
33 34       释放
35     {
36      If(disposing)
37      {
38       Comp.Dispose();// 释放托管资源
39      }
40        closeHandle(handle);// 释放非托管资源
41        handle= IntPtr.Zero;
42       }
43       this.disposed=true;// 标识此对象已释放
44     }
45 }
View Code

 

八、MVC原理

   路由机制,我以为此题,根据本身的理解回答便可,可深刻回答  从view上请求到controller组织model,反映到view上.详细框架原理,能够查看:https://blog.csdn.net/jehuyang/article/details/100575686

九、MVC中,后台向前台页面传对象的方式

   强类型的模型绑定、ViewData、ViewBag 。其中ViewData是ViewDataDictory类型,而VieBag是dynamic类型. dynamic 能够动态给不一样的类型。例如:dynamic p1=new Expandobject(); p1.Age=10; p1.Age="222";这样也不会报错。

十、MVC中过滤器

   Filter过滤器.AOP 面向切面编程。

   IAuthorizationFilter 通常检查用户是否有Action执行权限。在每一个Action以前执行OnAuthorization方法。

   IActionFilter在每一个Action以前执行OnActionExcuting方法,在每一个Action执行完成后执行OnActionExecuted 方法. IAuthorizationFilter在IActionFilter执行以前执行,因此检查权限通常写在IAuthorizationFilter中的OnAuthorization方法中。

   IResultFilter在每一个ActionResult的先后执行,通常不多用

   IExceptionFilter当每一个Action有未处理的异常执行OnException 方法。MVC中可使用Application_Error,但建议使用IExceptionFilter方法。

   定义的类能够在Global中Global.Filters.Filter.Add(new XXXFilter())添加使用。

十一、c#扩展方法如何写?

    静态类+静态方法+this,例以下面代码:

class Program
    {
        static void Main(string[] args)
        {
            string str = "Hello World!";
            str.ShowMsg(str);
            Console.ReadKey();
        }
  }
    #region 扩展方法
    static class MyString
    {
        public static void ShowMsg(this string a, string msg)
        {
            Console.WriteLine(msg);
        }
    }
    #endregion 扩展方法

十二、.NET Core Api 安全验证以及中间件 (本人没有了解过,代深刻了解

     采用jwt,生成token验证,好比咱们用来错误处理的中间件,能够定义其它功能的中间件。了解详细页面:https://www.cnblogs.com/savorboard/p/aspnetcore-authentication.html

1三、设计模式(本人没有了解过,代深刻了解)

     经常使用的设计模式:工厂、抽象工厂、代理、适配器、模板、策略、单例、观察者等,根据本身在项目中的使用状况,能够谈一谈。介绍连接:http://www.javashuo.com/article/p-pidygqoa-cp.html

1四、单点登陆

      单点登陆(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一。SSO的定义是在多个应用系统中,用户只须要登陆一次就能够访问全部相互信任的应用系统。使用“单点登陆”整合后,只须要登陆一次就能够进入多个系统,而不须要重        新登陆,这不只仅带来了更好的用户体验,更重要的是下降了安全的风险和管理的消耗。介绍连接:http://www.javashuo.com/article/p-brhboyeu-bo.html

1五、汇集索引和非汇集索引

      汇集索引:也叫聚簇(cu)索引。数据行的物理顺序与列值(通常是主键的那一列)的逻辑顺序相同,一个表中只能拥有一个汇集索引。

      非汇集索引:该索引中索引的逻辑顺序与磁盘上行的物理存储顺序不一样,一个表中能够拥有多个非汇集索引。

1六、char,varchar、nvarchar区别   

char 

char是定长的,这个怎么说呢,好比你用char(10),当你输入6个字符时,它会用英文的空格给补全。当你输入的15个字符时,它会自动截取前10个字符。取值范围1-8000

优势:适合存储定长的数据,存储效率快

缺点:使用不当会形成存储空间的浪费
varchar

varchar可变长度的,存储的大小为输入数据的字节的实际长度,所输入的数据字符长度能够为0。取值范围0-8000

优势:适合存储不固定长度的数据,它能够识别出字节用于保存实际使用多大的长度。合理的利用的存储空间。

缺点:存储效率低

nvarchar

咱们都知道英文字母占一个字节,汉字占两个字节,若是咱们的数据中又有英文,又有汉字,这时nvarchar就该上场了,nvarchar不管是英文仍是汉字都是用两个字节来表示。

优势:适合存储既有英文和汉字的数据

缺点:它最多能存储4000个字符,对英文存储上有些损失

1七、数据库死锁产生的缘由及解决办法(本人没有了解过,代深刻了解)

      两个进程各自占有资源,而后它们都还想获得对方的资源,而本身不愿释放资源。我以为死锁的活该,谁叫你那么贪婪。

1八、有用过缓存吗?有用过redis吗?

     你若回答用过,面试官继续追问;你若回答没用过,他会以为这都没有用过。

     缓存为了提升应用程序性能,由于请求数据库的次数少了。redis有不少特色:一、key-value   二、内存数据库,能够持久化到硬盘上  三、能够用做消息队列

1九、IOC、依赖注入、容器

      IOC是一种思想,控制反转,反转的是对象的控制权,把生成对象的权利交到外部。好比在方法中要使用一个Student对象,有三种方法,一、用的时候,直接New一个对象  二、从方法参数中传入Student对象   三、从容器中获取一个Student对象

20、大文件上传与下载,如何考虑?好比说50G的大文件

      能够分段下载,webconfig中必须配置大小。具体没有研究过待研究       

2一、Linq

2二、AOP

    面向切面的编程。好比给每一个Controller,添加日志功能,AOP是横向思惟的一种体现。和问题10有重复

2三、SOA、Webservice、WCF  (具体没有研究过待研究 )      

    问题:Webservice与WCF区别

    WCF是一个统一的框架,包括了remotting、Webservice,msmq,能够采用tcp和http等协议。也能够进行安全设置和验证。缺点:配置复杂

2四、有研究过Docker吗

    Docker是一个平台,解决部署问题。须要理解Image(镜像)和Container的关系,了解运行机理

2五、有研究过微服务吗

2六、sql性能优化

      查看sql执行计划、拆库、拆表、优化语句等

2七、你了解串口编程吗

     就是控制摄像头之类的设备编程,得了解计算机的基本原理

2八、js字符串和数组相互转化

2九、请设计一个递归算法

      好比5的阶乘,递归算法的一个要点是要设置结束条件,不然会栈溢出。

30、如何考虑作一个网站

3一、线性表和链表的区别

3二、谈谈你对js闭包的理解

3三、多线程中的同步、异步、Task

     异步主要为了提高吞吐量,防止阻塞。Task主要提供了一个管理线程的接口,好比获取线程的结果、状态、取消线程的执行等

3四、用过NoSql吗

    redis  、Memcached、MongoDB等

    redis 的优势: 

       1)  支持 string、list、set、geo 等复杂的数据结构。

       2)  高命中的数据运行时是在内存中,数据最终仍是能够保存到磁盘中,这样服务器重启以后数据还在。

       3)  服务器是单线程的,来自全部客户端的全部命令都是串行执行的,所以不用担忧并发修改(串行操做固然仍是有并发问题)的问题,编程模型简单;

       4)  支持消息订阅/通知机制,能够用做消息队列;

       5)  Key、Value 最大长度容许 512M; 

     redis 的缺点: 

1)  Redis 是单线程的,所以单个 Redis 实例只能使用一个 CPU 核,不能充分发挥服务器的性能。能够在一台服务器上运行多个 Redis 实例,不一样实例监听不一样端口,再互相组成集群。

2)  作缓存性能不如 Memcached; 

    Memcached 的优势:
              1) 多线程,能够充分利用 CPU 多核的性能; 2) 作缓存性能最高;

    Memcached 的缺点: 

       1)  只能保存键值对数据,键值对只能是字符串,若是有对象数据只能本身序列化成 json 字符串;

       2)  数据保存在内存中,重启后会丢失;

       3)  Key 最大长度 255 个字符,Value 最长 1M。 

redis 命令行管理客户端:
1)直接启动 redis 安装目录下的 redis-cli 便可。不用管恶心的自动提示。 执行 set name yzk,就是设置键值对 name=yzk

执行 get name 就是查找名字是 name 的值;

keys *是查找全部的 key

key *n*是查找全部名字中含有 n 的 key

2) 和 Redis 同样,Redis 也是不一样系统放到 Redis 中的数据都是不隔离的,所以设定 Key 的 时候也要选择好 Key。

3) Redis 服务器默认建了 16 个数据库,Redis 的想法是让你们把不一样系统的数据放到不一样 的数据库中。可是建议你们不要这样用,由于 Redis 是单线程的,不一样业务都放到同一个 Redis 实例的话效率就不高,建议放到不一样的实例中。所以尽可能只用默认的 db0 数据库。

命令行下能够用 select 0、select 1 这样的指令切换数据库,最高为 15。试试在不一样数据 库下新建、查询数据。

3五、用过负载均衡吗

3六、大数据处理

3七、数据库表数据量特别大时,如何优化查询,提升速度?

3八、数据库中如何循环读取数据库表中的记录?

      游标

3九、数据库中删除重复数据

40、Session有什么缺点,微软如何改进

   这是道笔试题,咱们知道IIS会回收资源,因此可能会致使Session失效

4一、有没有用过消息队列

     RabbitMQ

4二、设计一个老鼠、猫和主人的程序,要求可扩展性强,老鼠的叫声惊动猫和主人

    真无趣的一道题,用事件

4三、Vue权限管理,如何控制界面的显示

4四、WCF的部署方式

     通常在IIS上,还有人部署在Window服务上

4五、简介应用程序池

4六、冒泡算法

      c#写一个,双层循环

4七、简述应用程序域

4八、数据库设计三范式

4九、SQL 事务的隔离级别有哪几个?

     sql 事务隔离级别有四种分种为:

     一 Read Uncommitted(未提交读)

     二 Read Committed(提交读)

     三 Repeated Read(可重复读)

      四 Serializable(序列)

      资料连接:http://www.javashuo.com/article/p-tzedstaa-cs.html

50、IQueryable和IEnumberable and IList与List区别      

 基本概念:
IEnumerable:使用的是LINQ to Object方式,它会将AsEnumerable()时对应的全部记录都先加载到内存,而后在此基础上再执行后来的Query
IQeurable(IQuerable<T>):不在内存加载持久数据,由于这家伙只是在组装SQL,(延迟执行) 到你要使用的时候,例如 list.Tolist() or list.Count()的时候,数据才从数据库进行加载 (AsQueryable())。
IList(IList<T>):泛型接口是 ICollection 泛型接口的子代,做为全部泛型列表的基接口,在用途方面若是做为数据集合的载体这是莫有问题的,只是若是须要对集合作各类的操做,例如 排序 编辑 统计等等,它不行。
List <> :泛型类,它已经实现了IList <> 定义的那些方法,IList<T> list=new List<T>();只是想建立一个基于接口IList<Class1>的对象的实例,这个接口是由List<T>实现的。只是但愿使用到IList<T>接口规定的功能而已抽象场景:
其实在咱们以前没有使用 ORM 的的好久好久之前,咱们 在ADO.net 里面使用的 DataReader 和 DataAdapter or DataSet 和这几个货的基本原理都接近的,就是读取数据的时候,一个必须独占着数据库的链接,而另外一个就是先把数据库的的局加载到了本身本地,而后再进行操做。
使用场景模拟:
//IList
IList users = res.ToList(); //此时已把users加载到内存,而每一个user的关联实体 
                               //UserInfos)未被加载,因此下一行代码没法顺利经过
var ss = users.Where(p => p.UserInfos.ID != 3); //此处报错,由于P的UserInfos实体没法被加载  
// IQuerable的
IQueryable users = res.AsQueryable(); //users未被当即加载,关联实体可经过“延迟加载”得到
var ss = users.Where(p => p.UserInfos.ID != 3);//此处顺利得到对应的ss

  总结: 

基于性能和数据一致性这两点,使用IQueryable时必须谨慎,而在大多数状况下咱们应使用IList。 

1.当你打算立刻使用查询后的结果(好比循环做逻辑处理或者填充到一个table/grid中), 而且你不介意该查询即时被执行后的结果能够供调用者(Consummer)做后续查询(好比这是一个"GetAll"的方法),或者你但愿该查执行,使用ToList()

2.当你但愿查询后的结果能够供调用者(Consummer)做后续查询(好比这是一个"GetAll"的方法),或者你但愿该查询延时执行,使用AsQueryable()

3.按照功能由低到高:List<T> IList<T> IQueryable<T> IEnumerable<T>

4.按照性能由低到高:IEnumerable<T> IQueryable<T> IList<T> List<T>

       参考连接:http://www.javashuo.com/article/p-gccyyuzg-cv.html

相关文章
相关标签/搜索