2021 .NET/dotnet Core/C# 面试题及参考答案

1. NET/dotnet core/.NET framework 的关系

先看2张图
最新的.NET 5的示意图
.NET 5
之前的(dotnet core3.x时代)的示意图
dotnet core .3.1
总结如下:

  1. 2016 年开始,分开了.NET Framework和.NET Core,后者开源、面向跨平台应用;
  2. 2019年,.NET Framework和.NET Core被.NET5完成了统一。未来只会有一个.NET,可以支持 Windows、Linux、macOS、iOS、Android、tvOS、watchOS 和 WebAssembly,等等
  3. .Net standard library 是之前.NET Framework和.NET Core公共的部分;

2. corefx, coreclr 都是什么?

dotnet 组织包含了.NET Core的核心代码, 包括coreclr和corefx等.

  1. coreclr是运行时代码,
  2. corefx是各种基础类库的代码. CoreFX主要包含数个公共库,例如 System.Collections, System.IO, System.Xml等。

3. asp.net core

3.1. 3.1 Kestrel

Kestrel是asp.net core引入的跨平台的网络服务器,是默认配置。可以没有iis, apache和nginx就可以单独运行。
Kestrel基于libuv实现;(node.js 也是基于libuv)

3.2. 3.2 asp.net core 主要的特性

  1. 依赖注入。
  2. 日志系统架构。
  3. 引入了一个跨平台的网络服务器,kestrel。可以没有iis, apache和nginx就可以单独运行。
  4. 可以使用命令行创建应用。
  5. 使用AppSettings.json 来配置工程。
  6. 使用start up来注册服务。
  7. 更好的支持异步编程。
  8. 支持web socket和signal IR。
  9. 对于跨网站的请求的预防和保护机制。

3.3. 3.3 startup class的作用?

Startup class是dot net core应用的入口。所有的dot net core应用必须有这个class。这个类用来配置应用。这个类的调用是在program main函数里面进行配置的。类的名字可以自己定义。

3.4. 3.4 Startup class的config service方法有什么作用?

在这个方法里我们可以添加一些service进入依赖注入容器。

3.5. 3.5 startup class的configure方法有什么作用?

这个方法来定义整个应用如何响应HTTP请求。它有几个比较重要的参数,application builder,Hosting environment, logo factory, 在这里我们可以配置一些中间件用来处理路径,验证和session等等。

3.6. 3.6 什么是meta packages?

Meta packages是指包含所有ASP dot net code依赖的一个包。叫做Microsoft.AspNetCore.All

3.7. 3.7 什么是中间件?

中间件在这里是指注入到应用中处理请求和响应的组件。asp.net core 的中间件模型也是洋葱模型(和node.js d Koa 一样)

3.8. 3.8 application builder的use和run方法有什么区别?

这两个方法都在start up class的configure方法里面调用。都是用来向应用请求管道里面添加中间件的。Use方法可以调用下一个中间件的添加,而run不会。

3.9. 3.9 dot net core 管道(pipeline)里面的map拓展有什么作用?

可以针对不同的路径添加不同的中间件。

 public void Configure(IApplicationBuilder app)
 {
   app.Map("/path1", Middleware1);
   app.Map("/path2", Middleware2);
 }

3.10. 3.10 如何在dot net core中激活session功能?

  1. 首先要添加session包.
  2. 其次要在config service方法里面添加session。
  3. 然后又在configure方法里面调用usesession。

3.11. 3.11 如何在controller中注入service?

依赖注入的思想:

  1. 在config services方法中配置这个service。
  2. 在controller的构造函数中,添加这个依赖注入。

3.12. dot net core里面的路径是如何处理的?

路径处理是用来为进入的请求寻找处理函数的机制。所有的路径在函数运行开始时进行注册。

主要有两种路径处理方式:

  1. 常规路径处理就是用MapRoute的方式设定调用路径
  2. 属性路径处理是指在调用函数的上方设定一个路径属性。

3.13. application builder的use和run方法有什么区别?

这两个方法都在start up class的configure方法里面调用。都是用来向应用请求管道里面添加中间件的。Use方法可以调用下一个中间件的添加,而run不会。

3.14. 3.12 依赖注入后的服务生命周期?

在dot net core中,我们不需要关心如何释放这些服务, 因为系统会帮我们释放掉。有三种服务的生命周期。

  1. 单实例服务, 通过add singleton方法来添加。在注册时即创建服务, 在随后的请求中都使用这一个服务。
  2. 短暂服务, 通过add transient方法来添加。是一种轻量级的服务,用于无状态服务的操作。
  3. 作用域服务,一个新的请求会创建一个服务实例。使用add scoped方法来添加。

3.15. 3.13 什么么是Razor页面?

是dot net core中支持ASP网页表格的一种开发模型。@page 作为页面的起始标志。可以看做是asp.net core使用的模板引擎。

3.16. 3.14 如何在Razor页面中实现数据模型绑定?

使用bindproperty属性。

3.17. 3.15 Server.Transfer和Response.Redirect的区别是什么

  1. Server.Transfer仅是服务器中控制权的转向,在客户端浏览器地址栏中不会显示出转向后的地址;
  2. Response.Redirect则是完全的跳转,浏览器将会得到跳转的地址,并重新发送请求链接。这样,从浏览器的地址栏中可以看到跳转后的链接地址。

3.18. API,什么时候用Get/Post/Put/Delete

  1. GET: 查询
  2. POST :创建对象
  3. PUT: 修改对象
  4. DELETE:删除

4. C#

4.1. 一个单例(Singleton)类

单线程下的简单实现:

public MySingleton
{
  private MySingleton(){}	// 禁止被实例化
  public readonly static MySingletonInstance = new MySingleton();	// 程序加载时就会初始化
}

线程安全的加锁双检查

public class MySingleton
{
    private static MySingleton _instance = null;
    private static readonly object SynObject = new object();

    MySingleton() { }

    public static MySingleton Instance
    {
        get
        {
            if (null == _instance)
            {
                lock (SynObject)
                {
                    if (null == _instance)
                    {
                        _instance = new MySingleton();
                    }
                }
            }
            return _instance;
        }
    }
}

4.2. abstract class和interface有什么区别?

相同点:都不能被直接实例化,都可以通过继承实现其抽象方法。

不同点:

  1. 接口支持多继承;抽象类不能实现多继承。
  2. 接口只能定义行为;抽象类既可以定义行为,还可能提供实现。
  3. 接口只包含方法(Method)、属性(Property)、索引器(Index)、事件(Event)的签名,但不能定义字段和包含实现的方法;
  4. 抽象类可以定义字段、属性、包含有实现的方法。

4.3. 是否可以继承String类?

String类是sealed类故不可以继承。

4.4. StringBuilder 和 String 的区别?

String 在进行运算时(如赋值、拼接等)会产生一个新的实例,而 StringBuilder 则不会。所以在大量字符串拼接或频繁对某一字符串进行操作时最好使用 StringBuilder,不要使用 String。
但是简单的字符拼接,String还是首选。(100?次以内用String,以上用StringBuilder)

4.5. 什么情况下会用到虚方法?它与接口有什么不同?

  1. 子类重新定义父类的某一个方法时,必须把父类的方法定义为virtual
  2. 在定义接口中不能有方法体,虚方法可以。
  3. 实现时,子类可以不重新定义虚方法,但如果一个类继承接口,那必须实现这个接口。

4.6. string、String;int、Int32;Boolean、bool的区别

String、Int32、Boolean等都属于.Net中定义的类,而string、int、bool相当于C#中对这些类定义的别名。CTS。

4.7. private、 protected、 public、 internal 修饰符的访问权限。

  1. private : 私有成员, 在类的内部才可以访问。
  2. protected : 保护成员,该类内部和继承类中可以访问。
  3. public : 公共成员,完全公开,没有访问限制。
  4. internal: 当前程序集内可以访问。

4.8. C#中的委托是什么?事件是不是一种委托?事件和委托的关系。

委托可以把一个方法作为参数代入另一个方法,可以理解为指向一个函数的指针。
换个说法来解释,委托就是函数指针,事件就是保存多个函数指针的数组。

事件和委托的区别如下:

  1. 事件只能在方法的外部进行声明,而委在方法的外部和内部都可以声明。
  2. 事件只能在类的内部触发,不能在类的外部触发。而委托在类的内部和外都都可以触发。
  3. 委托一般用于回调,而事件用于外部接口。例如在观察者模式中,在被观察者中可以声明一个事件作为外部观察者注册的接口。

4.9. override与重载(overload)的区别

  1. 重载是方法的名称相同。参数或参数类型不同,进行多次重载以适应不同的需要。重载(overload)是面向过程的概念。
  2. Override 是进行基类中函数的重写。Override是面向对象的概念

4.10. 什么是装箱(boxing)和拆箱(unboxing)

装箱:从值类型接口转换到引用类型。
拆箱:从引用类型转换到值类型。

--------END--------

参考:
https://www.webtrainingroom.com/interview/asp-net-core-interview-questions-answers
https://www.talkingdotnet.com/asp-net-core-interview-questions/

posted on 2021-04-16 15:30  Jack Niu  阅读(11752)  评论(0编辑  收藏  举报

Affiliate Marketing and Web Technology