- .NET Core部分
- 什么是ASP.NET Core?
- ASP.NET Core有哪些好的功能?
- .NET Core跟ASP.NET比较有哪些更好的地方?
- 什么是.NET Core的startup 类?
- startup 类的configservice方法有什么作用?
- startup 类的configure方法有什么作用?
- .NET Core工程里面有多少个工程文件?
- .NET Core 中AOP的支持有哪些?
- 在ASP.NET Core中激活Session功能?
- Applicationbuilder的Use和Run方法有什么区别?
- .NET Core Filter的注册方式有哪些?
- .NET Core 如何和读取配置文件中的内容?
- 什么是中间件?
- .NET Core里面的路径是如何处理的?
- 什么是Razor页面?
- 如何在Controller中注入service?
- 描述一下依赖注入后的服务生命周期?
- 说说.NET Core内置容器的特点;
- .NET Core中如何读取静态文件?
- .NET Core项目中,wwwroot文件夹内包含什么内容?
- 对.NET Core kestrel的理解
- corefx, coreclr 都是什么?
- dot net core 管道(pipeline)里面的map拓展有什么作用?
- 一个单例(Singleton)类
- abstract class和interface有什么区别?
- 什么情况下会用到虚方法?它与接口有什么不同?
- 谈下对Autofac的理解;
- 说说Core WebApi的Swagger
- 说说Core WebApi特性路由。
- 说说RESTful是什么。
- 说说脚本在请求Web CoreApi的时候,为什么会发生跨域问题?
- 如何解决跨域问题?
- EFCore
- EF相关
- 事务
- 面向对象
- gRPC
- 其他部分
- 英文单词
">
原文链接:https://blog.csdn.net/puzi0315/article/details/118653815
.NET Core部分
什么是ASP.NET Core?
- ASP.NET Core是 ASP.NET的升级版本。
- 它遵循了.NET的标准架构,是一个基于.NET Core的Web开发框架, 可以运行于多个操作系统上。
-
ASP.NET Core有哪些好的功能?
第一是依赖注入。
- 第二是日志系统架构。
- 第三是引入了一个跨平台的网络服务器,kestrel。它可以没有iis, apache和nginx就可以单独运行。
- 第四是可以使用命令行创建应用。
- 第五是使用appsettings来配置工程。
- 第六是使用startup来注册服务。
- 第七是更好的支持异步编程。
- 第八是支持web socket和signal IR。
-
.NET Core跟ASP.NET比较有哪些更好的地方?
第一是跨平台,它可以运行在windows, Linux和MACOS上;
- 第二是对架构本身安装没有依赖,所有的依赖都跟程序本身在一起;
- 第三是ASP.NET Core处理请求的效率更高,能够处理更多的请求;
-
什么是.NET Core的startup 类?
startup 类是ASP.NET Core应用的入口;
- 所有的ASP.NET Core应用应该有这个类;
- 这个类用来配置应用;
- 这个类的调用是在program main函数里面进行配置的;
-
startup 类的configservice方法有什么作用?
用以配置应用的服务;
- 在这个方法里我们可以添加一些service进入依赖注入容器;
- 如数据库连接池,mvc,swagger,controllers,filter,jwt,请求头,以及自己定义的接口;
- 最重要的参数为:IServiceCollection services;
- 在 ConfigureServices 中注册服务,并通过依赖关系注入 (DI) 或 ApplicationServices 在整个应用使用服务。
startup 类的configure方法有什么作用?
- 用以创建应用的请求处理管道;
- 这个方法用来定义整个应用如何响应HTTP请求;
- 它有几个比较重要的参数,IApplicationBuilder,Hostingenvironment, logfactory;
在这里我们可以配置一些中间件用来处理路径,验证和session等等。
.NET Core工程里面有多少个工程文件?
Program, Startup ,launchsetting,appsettings。
.NET Core 中AOP的支持有哪些?
aop就是面向切面的编程,.netcore里通过Filter来支持;
分别有AuthorizeFilter ResourceFilter ActionFilter ExceptionFilter ResultFilter,Filter也被称为拦截器。
在ASP.NET Core中激活Session功能?
首先要添加session包;
- 其次要在configservice方法里面添加session;
然后又在configure方法里面调用usesession。
Applicationbuilder的Use和Run方法有什么区别?
这两个方法都在startup 类的configure方法里面调用。
- 都是用来向应用请求管道里面添加中间件的。
Use可以调用下一个中间件的添加,而run不会,run是终结式的。
.NET Core Filter的注册方式有哪些?
方法注册:只对方法生效;
- 控制器注册:对控制器中的所有方法生效;
-
.NET Core 如何和读取配置文件中的内容?
可以有两种方式:
- 可以通过IConfiguration接口来读取;
- 也可以使用IOptionsSnapshot来读取,需要先根据配置文件结构一致的实体对象,来绑定到对象中去;
- 必须保证:DBConnectionOption和配置文件的内容结构一致。
NET Core管道里面的map拓展有什么作用?
可以针对不同的路径添加不同的中间件。
什么是中间件?
中间件在这里是指注入到应用中处理请求和响应的组件。是通过多个委托来嵌套形成的一个俄罗斯套娃。
微软官方原话:
中间件是一种装配到应用管道以处理请求和响应的组件。 每个组件:
- 选择是否将请求传递到管道中的下一个组件。
- 可在管道中的下一个组件前后执行工作。
请求委托用于生成请求管道。 请求委托处理每个 HTTP 请求。
.NET Core里面的路径是如何处理的?
- 路径处理是用来为进入的请求寻找处理函数的机制;
- 所有的路径在函数运行开始时进行注册;
主要有两种路径处理方式, 常规路径处理和属性路径处理。
在config services方法中配置/注册这个service;
-
描述一下依赖注入后的服务生命周期?
ASP.NET Core中,我们不需要关心如何释放这些服务, 因为系统会帮我们释放掉。有三种服务的生命周期。
单实例服务:通过addSingleton方法来添加。在注册时即创建服务, 在随后的请求中都使用这一个服务;
- 短暂服务:通过add transient方法来添加。是一种轻量级的服务,用于无状态服务的操作;
作用域服务:使用add scoped方法来添加。一个新的请求会创建一个服务实例。
说说.NET Core内置容器的特点;
ASP.NET Core内置容器IServiceCollection,只支持构造函数注入;
支持三种声明周期:单例、瞬时、Scoped三种声明周期管理。
.NET Core中如何读取静态文件?
可以通过中间件UseStaticFiles来配置读取静态文件;步骤如下:
安装静态文件中间件NuGet软件包,必须在请求管道中添加Microsoft.AspNetCore.StaticFiles中间件;
- 在ASP.NET Core中配置静态文件中间件;
- 在ASP.NET Core中提供静态文件。
.NET Core项目中,wwwroot文件夹内包含什么内容?
包含了css、js、js库、字体文件。对.NET Core kestrel的理解
- Kestrel 是一个跨平台的适用于 ASP.NET Core 的 Web 服务器。
- Kestrel 是包含在 .NET Core 项目中的 Web 服务器,默认处于启用状态。
Kestrel 支持以下方案:
coreclr是运行时代码,
corefx是各种基础类库的代码. CoreFX主要包含数个公共库,例如 System.Collections, System.IO, System.Xml等。
dot net core 管道(pipeline)里面的map拓展有什么作用?
可以针对不同的路径添加不同的中间件
public void Configure(IApplicationBuilder app){app.Map("/path1", Middleware1);app.Map("/path2", Middleware2);}
一个单例(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;}}}
abstract class和interface有什么区别?
相同点:都不能被直接实例化,都可以通过继承实现其抽象方法。
不同点:接口支持多继承;抽象类不能实现多继承。
- 接口只能定义行为;抽象类既可以定义行为,还可能提供实现。
- 接口只包含方法(Method)、属性(Property)、索引器(Index)、事件(Event)的签名,但不能定义字段和包含实现的方法;
-
什么情况下会用到虚方法?它与接口有什么不同?
子类重新定义父类的某一个方法时,必须把父类的方法定义为virtual
- 在定义接口中不能有方法体,虚方法可以。
- 实现时,子类可以不重新定义虚方法,但如果一个类继承接口,那必须实现这个接口。
谈下对Autofac的理解;
Autofac是一个IOC容器,支持三种类型的DI依赖注入(构造函数注入,属性注入,基于lambda表达式创建实例),配置文件配置映射关系,支持AOP扩展定制。
说说Core WebApi的Swagger
- Swagger是一个Api说明文档,支持Api测试;
- 现在CoreWebApi开发使用swagger还挺多的;
- 在.NET5中已经内置了Core WebApi;配置流程如下:
- 每一个URI代表1种资源;
- 客户端使用GET、POST、PUT、DELETE4个表示操作方式的动词对服务端资源进行操作:
- GET用来获取资源,
- POST用来新建资源(也可以用于更新资源),
- PUT用来更新资源,
- DELETE用来删除资源;
- 通过操作资源的表现形式来操作资源;
- 客户端与服务端之间的交互在请求之间是无状态的,从客户端到服务端的每个请求都必须包含理解请求所必需的信息。
说说脚本在请求Web CoreApi的时候,为什么会发生跨域问题?
跨域问题:本质是浏览器的行为,浏览器有一个同源策略,同源策略:协议、IP地址相同就认为是同源,否则就非同源;
同源策略限定脚本请求只能请求同源的服务器返回的内容才给正常的使用,否则就会报跨域问题;
其实我们在请求Core WebApi的时候,浏览器直接访问Api没有问题,如果是脚本请求,就会出现跨域问题;如何解决跨域问题?
三种方式:
- 后台模拟Http请求,既然是浏览器的行为,就避开浏览器,先来一个同源的服务器去请求,然后由服务器模拟http请求去请求到Core WebApi的资源,然后响应给前端;
- JSONP,思路:通过html部分标签发起请求,比方说 等等,发起请求是可以避开同源策略的,使用这些标签发起请求,然后带有一个回调函数,然后得到请求后,把回调函数之心一次,把数据解析后使用;
- 服务端允许跨域,多种方式,可以自己定义中间件支持跨域,只要把响应的Response的头信息Header中写入“Access-Control-Allow-Origin” 即可支持跨域;如果需要让所有的Api都支持跨域,就可以写一个中间件从管道处理模型中去支持跨域,如果要选择性的支持跨域,可以使用ActionFilter来完成,也可以通过Cors(ASP.NET Core中提供的中间件,可以支持配置不同的跨域规则)来配置支持跨域;
### 创建下面对象实例,需要申请多少内存空间
public class User{public int Age { get; set; }public string Name { get; set; }public string _Name = "123" + "abc";public List<string> _Names;}
- 对象大小估算,共计40个字节:
- 属性Age值类型Int,4字节;
- 属性Name,引用类型,初始为NULL,4个字节,指向空地址;
- 字段_Name初始赋值了,由前面的文章(.NET面试题解析(03)-string与字符串操作)可知,代码会被编译器优化为_Name=”123abc”。一个字符两个字节,字符串占用2×6+8(附加成员:4字节TypeHandle地址,4字节同步索引块)=20字节,总共内存大小=字符串对象20字节+_Name指向字符串的内存地址4字节=24字节;
- 引用类型字段List
_Names初始默认为NULL,4个字节; - User对象的初始附加成员(4字节TypeHandle地址,4字节同步索引块)8个字节;
- 内存申请: 申请44个字节的内存块,从指针NextObjPtr开始验证,空间是否足够,若不够则触发垃圾回收。
- 内存分配: 从指针NextObjPtr处开始划分44个字节内存块。
- 对象初始化: 首先初始化对象附加成员,再调用User对象的构造函数,对成员初始化,值类型默认初始为0,引用类型默认初始化为NULL;
- 托管堆指针后移: 指针NextObjPtr后移44个字节。
-
EFCore
对EFCore有了解吗?
EF Core 是一个ORM(对象关系映射)框架;
EF Core支持SQL Server/SQL Azure、SQLite、Azure Cosmos DB、MySQL、PostgreSQL 。
说说EFCore查询的性能调优小技巧。
(1).使用DbContext池
- (2).优先使用异步方法
- (3).批处理语句
- (4).关闭状态追踪,AsNoTracking()
(5).关闭状态同步,context.ChangeTracker.AutoDetectChangesEnabled = false。
说说什么是EF中导航属性和引用属性。
EF Core导航属性分为三种:
集合导航属性:主表中对子表相关数据的引用;
- 引用导航属性:子表中对主表数据的引用;
- 反转导航属性:一个导航属性对应的另一端的导航属性。
EF相关
EF如何处理并发?
- 什么叫并发:当多个用户同时更新同一数据的时候,由于更新可能导致数据的不一致性,使得程序的业务数据发生错误,这种情况可以称之为并发。并发又分为两种:乐观并发与悲观并发
- 乐观并发:即系统允许多个用户同时修改同一条记录,系统会预先定义由数据并发所引起的并发异常处理模式,去处理修改后可能发生的冲突。当出现乐观并发时应该怎么处理呢,通常有如下三种处理方法
- a 保留最后一次对象修改的值
- b 保留最初的修改值
- c 合并修改值
- 悲观并发:在同一时刻只允许一个用户修改相同数据,直接用Lock 与 unLock就可以处理.
EF四种隔离级别
- 01:Read uncommitted(读未提交):最低级别,任何情况都会发生。
- 02:Read Committed(读已提交):可避免脏读的发生。
- 03:Repeatable read(可重复读):可避免脏读、不可重复读的发生。
- 04:Serializable(串行化):避免脏读、不可重复读,幻读的发生。
使用EF update 怎么保证在并发时数据正确?
- RowVersion ( TimeStamp ) 时间戳
EF实现Rowversion 并发控制 需要借助 TimeStamp 标示 ,并且一个类只能有 一个此标示,标示的必须是byte[]类型。使用Rowversion会对整行数据进行并发检测。
- RowVersion ( TimeStamp ) 时间戳
- ConcurrencyCheck
有些时候并不需要控制针对整条记录的并发,只需要控制某个列的数据不会出现脏操作就ok,这个时候 就使用ConcurrencyCheck 。你必须将ConcurrencyCheck特性添加到实体需要控制并发的非主键属性上,使实体框架可以将所有标记的列包含到更新语句的Where子句中。
- DbUpdateConcurrencyException
您可以通过EF实体框架引发的DbUpdateConcurrencyException异常处理来解决冲突。
事务
事务的四大特性
- 原子性 (atomicity):强调事务的不可分割.
事务是数据库的逻辑工作单位,事务中包含的各操作要么都做,要么都不做
- 一致性 (consistency):事务的执行的前后数据的完整性保持一致.
事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。
- 隔离性 (isolation):一个事务执行的过程中,不应该受到其他事务的干扰。
即一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务之间不能互相干扰。
4 . 持续性 (durability) :事务一旦结束,数据就持久到数据库。
也称永久性,指一个事务一旦提交,它对数据库中的数据的改变就应该是永久性的。接下来的其它操作或故障不应该对其执行结果有任何影响。
面向对象
什么是面向对象?
面向对象的方法主要是把事物给对象化,包括其属性和行为。
面向对象编程更贴近实际生活的思想。
总体来说面向对象的底层还是面向过程,面向过程抽象成类,然后封装,方便使用就是面向对象(万物皆对象)。
三大基本特性:
- 封装
封装,就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。
- 继承
继承,指可以让某个类型的对象获得另一个类型的对象的属性的方法。它支持按级分类的概念。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。
- 多态
通过继承实现的不同对象,调用相同的方法,产生不同的执行结果.。
五大基本原则
- 单一职责原则SRP(Single Responsibility Principle)
是指一个类的功能要单一,不能包罗万象。
- 开放封闭原则OCP(Open-Close Principle)
一个模块在扩展性方面应该是开放的而在更改性方面应该是封闭的。
- 里式替换原则LSP(the Liskov Substitution Principle LSP)
子类应当可以替换父类并出现在父类能够出现的任何地方。
- 依赖倒置原则DIP(the Dependency Inversion Principle DIP)
高层模块不应该依赖低层模块,二者都应该依赖其抽象。
- 接口分离原则ISP(the Interface Segregation Principle ISP)
gRPC
说说gRPC
说gRPC可以先说RPC,所谓RPC(remote procedure call 远程过程调用)框架实际是提供了一套机制,使得应用程序之间可以进行通信,而且也遵从server/client模型。使用的时候客户端调用server端提供的接口就像是调用本地的函数一样。
所谓gRPC 是由谷歌开发的一个高性能、开源和通用的 RPC 框架,面向移动和 HTTP/2 设计。目前提供 C、Java 和 Go 语言版本,分别是:grpc, grpc-java, grpc-go. 其中 C 版本支持 C, C++, Node.js, Python,Ruby, Objective-C, PHP 和 C# 支持.
gRPC有几种模式?
四种模式:
- 简单模式:简单模式只是使用参数和返回值作为服务器与客户端传递数据的方式,最简单;
- 客户端流模式:即从客户端往服务器端发送数据使用的是流,即服务器端的参数为流类型,然而在服务器相应后返还数据给客户端,使用的也是流的send方法。一般在服务器端的代码,需要先recv再send,而客户端与此相反。但是在后面的双向模式中可以使用go的协程协作;
- 服务器端流模式:即服务器端返回结果的时候使用的是流模式,即传入的数据是通过参数形式传入的。但是在往客户端发送数据时使用send方法,与客户端返回数据的方式大同小异;
- 双向模式:客户端如果不适用协程,那么发送必须在接收之前。如果使用协程,发送与接收并没有先后顺序。为了保证协程的同步,可以使用互斥量进行约束。
gPRC作为一种被调用的服务,有什么保护安全的措施吗?
有的,可以使用JWT,无论是对称可逆加密还是非对称可逆加密,都是可以支持的;[
](https://blog.csdn.net/puzi0315/article/details/118653788)
其他部分
性能优化建议
参考性能优化文章
前端部分优化
- 骨架屏、懒加载
- loading优化
- 防抖、节流
- 等等等
后端部分优化要点
后端部分可以对缓存,dns查询时间,链接时间,处理请求时间,响应时间等进行优化。
dns查询时间可以使用httpdns或是dns预加载,域名收敛等手段优化。
建立连接的重点是长连接和链接复用,keep-alive,long-polling,http-straming,websocket或是自己写过别的协议,更好的是直接上http2。为了优化链接的环节,前端这里还需要对资源使用cdn,雪碧图,代码合并等手段。
服务器处理请求这里可以优化的点也不少,值得注意的就是移动端访问PC端页面需要跳转到移动端页面时,要再服务器端使用302跳转,不要在前端进行跳转。还有就是启用hsts,要求浏览器在之后的访问使用https,减少无谓的http跳转https,同时还可以防止ssl剥离攻击,提升安全性。
服务器发送响应环节,可以使用Transfer-Encoding=chunked,多次返回响应,具体操作查询bigpipe。还有就是减小cookie的体积等等。[
](https://blog.csdn.net/puzi0315/article/details/118653788)
英文单词
kestrel
configure
英 [kənˈfɪɡə(r)] 美 [kənˈfɪɡjər]
[
