一些面试题的备忘
ASP.NET Core
服务的注册方式和获取方式
解答
- 使用框架自带的
IoC框架是通过Startup的ConfigureService方法里的IServiceCollerction进行注册 - 一般通过接口与实现类的方式实现,也可以通过工厂的方式进行注册服务,不推荐直接
new服务进行注册,这样IoC框架是不会进行该服务的生命周期管理 - 获取方式一般可以通过构造函数、参数的
[FromService]、通过BuilderServiceProvider获取serviceProvider对象,在serviceProvider里获取服务
- 使用框架自带的
autofac和自带的IoC框架的区别解答
- Autofac新增基于名称的注入、属性注入、AOP
- 注册服务的地方是在
Startup里新增的ConfigureContainer方法里
WebAPI的CQRS策略JWT的组成和加密方式解答
- 加密方式.经过base64转码的消息主体.签名
- 使用HS256的签名加密方式
ViewData、ViewBag、TempData的区别解答:
ViewBag是在ViewData上面加一层dynamic,如果用同个key,比如ViewBag.Info="ABC",在页面其实也可以通过ViewData["Info"]来获取,同时也以为着ViewBag="ABC";ViewData["info"]="123",后面会覆盖前面的;TempData是存放在session里面,意味着可以跨action来取值,比如ActionA中赋值了TempData["Info"]="ABC",在ActionA对应的ViewA中点击跳转到ActionB,则可以直接在ActionB中通过TempData["Info"]来取得"ABC"- 但是要注意,
TempData在被取值之后就会被删除,所以上面的场景如果在ActionA对应的ViewA中把TempData["Info"]取出来,则在ActionB中就获取不到TempData["Info"]的值,获取到的是个null
API的版本管理解答
- 使用URL带版本的方式,在
Controller里使用[Route('')]来指定版本
- 使用URL带版本的方式,在
使用中间件Use/Run/Map的区别
解答
- 通常使用的
Use Run起到的是断路器的作用,即不再执行后面的中间件Map一般是针对特殊的路径使用特殊的中间件管道
- 通常使用的
中间件里面怎么获取服务
解答
- 使用中间件的
Invoke方法中的HttpContext对象context.RequestServices.GetService<T>()来获取
- 使用中间件的
EFCore的TPHEFCore的lazyload
数据库相关
delete、truncate的区别解答:
delete可以带where,truncate不能带wheredelete慢,truncate快delete每删一条数据都会在数据库日志里记录这条记录,truncate只会记录整表做了清除记录,这意味这delete可以被回滚,truncate是不能回滚的delete会触发delete触发器,truncate是不会触发任何触发器的
view、table的区别go做了什么,go上面定义的变量go下面能获得到吗?- 定义事务的标准
- 连续自增的主键删除掉一个断开了,怎么补回这个断掉的逐渐
select * into A from B、insert into A select * from B的区别
上面的执行结果是什么create table #tmp_A(id int) go insert into #tmp_A values(1) --select * from #tmp_A if @@error<>0 print @@error else print @@rowcount- 存储过程中
@、#、##、CTE的区别 - 聚集索引与非聚集所以区别
其他
.xsd、XML的schemasjson是什么rabbitmq中的topic、queue是什么,消息持久化是在哪个位置说一下
pub/sub,订阅的时候能获得订阅之前的消息吗?Queue、ConQueue的区别从数据结构说一下
stack、queue的区别编译的时候
Debug模式和Release模式的区别解答:
- 在
Debug模式可以使用#IF DEBUG来跑一些调试模式下的特殊代码,在打包成Release的DLL的时候,#IF DEBUG的代码会被忽略
- 在
编译时选择
Any CPU、x86、x64的区别DDD是怎么分层的说一下 聚合根、实体、值对象
DDD的仓储层是怎么实现的async/await会不会堵塞主线程,如果会,那为什么还要用?解答
- 调用线程在遇到
await的时候,会直接返回去做调用后的事情,不会执行await后面的代码 - 可以粗暴的认为,在
await后面的代码会被包装成一个回调,在await代码执行完成之后,再执行回调代码,其中回调的线程具备多种可能行,可能是执行await代码的线程,也可能是新线程 - 反编译查看:首先IL里面是没有
async/await的,就是常规代码,代码正常执行的时候,会实例化一个状态机,状态=-1,然后执行Task前面的普通代码,遇到await Task.Run()的时候会启动线程去执行Task,然后判断是否完成,这时候线程刚启动肯定没完成,所以判断为未完成,并将状态重置=0,然后递归调用一下自己,调用之后再次判断是否状态,发现状态=0,则表示调用线程任务完成,返回去做自己原来的事
- 调用线程在遇到