版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
net笔试面试试题及答案一、基础概念与语法1.值类型与引用类型的核心区别有哪些?请举例说明。值类型直接存储数据值,内存分配在栈(或结构体嵌入引用类型时在堆),包括基本类型(int、double)、枚举(enum)、结构体(struct);引用类型存储对象的内存地址(引用),内存分配在堆,如类(class)、接口(interface)、字符串(string)、委托(delegate)。区别:复制方式:值类型复制时创建副本,修改副本不影响原对象;引用类型复制引用,修改对象会影响所有引用。生命周期:值类型随声明作用域结束自动释放;引用类型由GC回收。默认值:值类型有默认值(如int默认0),引用类型默认null。示例:`inta=10;intb=a;b=20;`后a仍为10(值类型);`varobj1=newList<int>();varobj2=obj1;obj2.Add(1);`后obj1也包含1(引用类型)。2.简述async/await的底层实现原理,它如何避免线程阻塞?async/await是C提供的异步编程语法糖,底层通过状态机(StateMachine)实现。当方法标记为async并包含await关键字时,编译器会提供一个继承自IAsyncStateMachine的结构体,将方法拆分为多个状态:遇到await时,检查任务(Task)是否完成:若完成,继续执行后续代码;若未完成,保存当前状态(如局部变量),返回一个未完成的Task,将剩余逻辑作为任务完成后的回调。任务完成后,状态机恢复执行,上下文(如UI线程的SynchronizationContext)会自动切换(若需要),避免阻塞原线程。本质是通过异步任务的回调机制,让线程在等待I/O操作(如文件读写、网络请求)时释放回线程池,执行其他任务,而非阻塞等待。3.垃圾回收(GC)的三代回收策略是什么?大对象堆(LOH)的特殊处理逻辑有哪些?GC将对象按存活时间分为三代(Generation0、1、2):0代:新创建的对象(除大对象),存活时间短,回收频率最高。1代:0代回收后未被回收的对象,作为1代对象,回收频率次之。2代:1代回收后未被回收的对象,存活时间长,回收频率最低(可能触发完整GC)。大对象堆(LOH)存储大小≥85,000字节的对象(如大数组),特点:不参与0代、1代回收,仅在2代回收或显式调用GC.Collect()时回收。采用标记-压缩算法(Mark-Compact),但压缩成本高,因此LOH对象尽量避免频繁创建和销毁,否则可能导致性能下降。4.委托(Delegate)与事件(Event)的联系与区别是什么?联系:事件基于委托实现,本质是委托的封装,提供“发布-订阅”模式。区别:访问权限:事件通常声明为public,且只能在声明类内部触发(+=/-=操作符限制);委托可以在任何位置调用(可能导致外部错误触发)。设计目的:事件用于定义可观察的“动作”(如按钮点击),限制外部对回调的控制;委托是通用的函数指针,用于封装方法。空引用处理:事件触发前需检查是否为null(避免NullReferenceException);委托调用同样需检查,但事件的封装性更安全。5.接口(Interface)与抽象类(AbstractClass)的使用场景如何选择?选择依据:代码复用:抽象类可提供默认实现(非抽象方法),适合需要共享公共逻辑的场景(如基类Service);接口仅定义契约,无实现,适合跨不相关类的功能约束(如IEnumerable定义迭代行为)。继承限制:类只能继承一个抽象类,但可实现多个接口,因此接口适合多维度功能扩展(如IComparable、IDisposable)。版本兼容性:抽象类新增方法需修改所有子类(除非提供默认实现);接口在.NET8+支持默认方法(DefaultInterfaceMethods),但历史版本需子类显式实现。二、ASP.NETCore核心6.中间件(Middleware)的执行顺序如何影响请求处理?请描述完整的中间件管道流程。中间件按Startup.Configure方法中添加的顺序执行,形成“请求-响应”的双向管道:请求阶段:按添加顺序依次执行中间件的Invoke/InvokeAsync方法,直到最后一个中间件调用_next()。响应阶段:从最后一个中间件开始,反向执行各中间件中在_next()之后的代码(如日志记录、异常处理)。示例:若顺序为`app.UseA();app.UseB();`,则请求流程为A→B→业务处理→B(响应逻辑)→A(响应逻辑)。关键注意点:异常处理中间件通常放在管道最前面(捕获后续中间件异常),静态文件中间件(UseStaticFiles)放在认证(UseAuthentication)前(避免静态文件需要认证)。7.依赖注入(DI)的三种生命周期(Singleton/Scoped/Transient)的适用场景是什么?Singleton(单例):全局唯一实例,适合无状态或共享状态的服务(如配置读取服务IConfiguration)、高频调用的轻量级服务(如缓存服务)。注意:若服务依赖Scoped/Transient服务,可能导致生命周期延长(“作用域泄漏”)。Scoped(作用域):每个HTTP请求创建一个实例,适合与请求相关的服务(如DbContext,需保证单次请求内数据一致性)、需要临时状态的服务(如用户会话信息)。Transient(瞬时):每次注入时创建新实例,适合无状态、轻量级且需要隔离的服务(如简单计算工具类)。若服务被多次注入(如同一方法中多次获取),每次均为新实例。8.如何实现JWT身份验证?简述关键步骤及核心配置。步骤:1.安装NuGet包`Microsoft.AspNetCore.Authentication.JwtBearer`。2.在Startup/Program.cs中配置认证服务:```csharpbuilder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options=>{options.TokenValidationParameters=newTokenValidationParameters{ValidateIssuer=true,//验证颁发者ValidIssuer="YourIssuer",ValidateAudience=true,//验证接收方ValidAudience="YourAudience",ValidateLifetime=true,//验证过期时间IssuerSigningKey=newSymmetricSecurityKey(Encoding.UTF8.GetBytes("YourSecretKey"))//签名密钥};});```3.添加授权中间件`app.UseAuthentication();app.UseAuthorization();`。4.在控制器/方法上添加`[Authorize]`特性,限制访问。核心逻辑:客户端登录时获取JWT(包含用户声明、过期时间等),后续请求在HTTP头中携带`Authorization:Bearer{Token}`,中间件验证Token签名、有效期等,通过后将用户信息存入HttpContext.User。9.简述MVC中过滤器(Filter)的类型及执行顺序。过滤器按执行阶段分为5类,顺序(从早到晚):1.授权过滤器(AuthorizationFilter):最先执行,用于权限验证(如[Authorize]),可终止请求。2.资源过滤器(ResourceFilter):在授权后、模型绑定前执行,可缓存响应或修改请求(如[ResponseCache])。3.动作过滤器(ActionFilter):在动作方法执行前后执行,可修改输入参数或返回结果(如[LogAction])。4.异常过滤器(ExceptionFilter):捕获动作方法或后续过滤器的异常,提供错误响应(如[HandleException])。5.结果过滤器(ResultFilter):在动作结果执行前后执行,可修改输出内容(如[CompressResult])。执行顺序:授权→资源(前)→动作(前)→异常(若有)→结果(前)→结果(后)→动作(后)→资源(后)。10.如何优化ASP.NETCore应用的启动时间?优化策略:减少服务注册:移除未使用的服务(如不必要的Swagger、健康检查),使用`AddHttpClient`替代手动创建HttpClient。延迟初始化:对非立即需要的服务使用`Lazy<T>`或`IServiceProvider.GetService`延迟加载。预编译视图:使用RazorSDK的`<MvcRazorCompileOnPublish>true</MvcRazorCompileOnPublish>`预编译Razor视图,避免运行时编译。缩小程序集扫描范围:在`AddControllers()`中使用`ConfigureApplicationPartManager`排除无关程序集(如测试项目)。使用更快的序列化库:替换默认的System.Text.Json为Utf8Json或MessagePack(需兼容API客户端)。三、EntityFrameworkCore(EFCore)11.延迟加载(LazyLoading)与预加载(EagerLoading)的区别是什么?如何避免N+1查询问题?延迟加载:访问导航属性时,EFCore自动触发一次数据库查询加载相关数据(需启用`UseLazyLoadingProxies`或手动配置`ICollection<T>`为virtual)。预加载:通过`Include()`/`ThenInclude()`方法在主查询中一次性加载相关数据(如`db.Users.Include(u=>u.Posts).ToList()`)。N+1问题:查询主实体(如10个User)时,若每个User的Posts使用延迟加载,会触发1次主查询+10次Posts查询(共11次)。解决方案:使用预加载(EagerLoading)一次性加载所有关联数据。使用投影(Select)直接加载需要的字段(如`db.Users.Select(u=>new{u.Name,Posts=u.Posts.Select(p=>p.Title)}).ToList()`),减少数据传输量。启用全局查询筛选(GlobalQueryFilters)或使用原生SQL(FromSqlRaw)优化复杂查询。12.如何处理EFCore的并发冲突(乐观锁)?请给出代码示例。乐观锁通过“版本号”或“时间戳”字段实现,步骤:1.在实体类中添加`[Timestamp]`或`[ConcurrencyCheck]`特性的字段(如byte[]Version)。2.更新实体时,EFCore会将当前Version值作为WHERE条件,若数据库中Version已变更(其他事务修改),抛出DbUpdateConcurrencyException。示例:```csharppublicclassProduct{publicintId{get;set;}publicstringName{get;set;}[Timestamp]publicbyte[]Version{get;set;}}//更新逻辑varproduct=awaitdb.Products.FindAsync(id);product.Name="NewName";try{awaitdb.SaveChangesAsync();}catch(DbUpdateConcurrencyExceptionex){//处理冲突:获取数据库当前值varexceptionEntry=ex.Entries.Single();varcurrentValues=exceptionEntry.CurrentValues;vardatabaseValues=awaitexceptionEntry.GetDatabaseValuesAsync();//合并数据或提示用户}```13.FluentAPI与数据注释(DataAnnotations)的优先级如何?请举例说明常用配置。FluentAPI优先级高于数据注释,当两者冲突时(如列名、长度),FluentAPI配置生效。常用FluentAPI配置:```csharpmodelBuilder.Entity<Product>(entity=>{entity.ToTable("T_Products");//表名entity.HasKey(p=>p.Id);//主键entity.Property(p=>p.Name).IsRequired()//非空.HasMaxLength(100);//最大长度entity.HasIndex(p=>p.Code).IsUnique();//唯一索引entity.HasOne(p=>p.Category)//一对一/多对一关系.WithMany(c=>c.Products).HasForeignKey(p=>p.CategoryId).OnDelete(DeleteBehavior.Restrict);//级联删除策略});```14.简述DbContext的生命周期管理最佳实践。避免单例DbContext:DbContext非线程安全,单例可能导致并发问题(如多个请求同时修改同一实例)。使用Scoped生命周期:在ASP.NETCore中,默认将DbContext注册为Scoped(与HTTP请求同生命周期),确保单次请求内数据一致性。手动释放:若在非DI场景使用(如控制台应用),需通过`using`语句确保DbContext及时释放(释放数据库连接、清理资源)。禁用自动检测更改:对只读操作,可设置`context.ChangeTracker.AutoDetectChangesEnabled=false`提升性能(如`context.Users.AsNoTracking().ToList()`)。四、设计模式与性能优化15.单例模式(Singleton)的线程安全实现有哪些方式?对比其优缺点。静态初始化(线程安全):```csharppublicsealedclassSingleton{privatestaticreadonlySingletoninstance=newSingleton();privateSingleton(){}publicstaticSingletonInstance=>instance;}```优点:简单,由CLR保证线程安全(静态构造函数仅执行一次)。缺点:无法延迟初始化(实例在类首次被访问时创建,即使未使用)。双重检查锁定(Double-CheckedLocking,线程安全):```csharppublicsealedclassSingleton{privatestaticSingletoninstance;privatestaticreadonlyobjectlockObj=newobject();privateSingleton(){}publicstaticSingletonInstance{get{if(instance==null)//第一次检查{lock(lockObj){if(instance==null)//第二次检查instance=newSingleton();}}returninstance;}}}```优点:延迟初始化,线程安全。缺点:代码略复杂,需注意`volatile`关键字(C5+编译器已优化,无需显式声明)。Lazy<T>(推荐,线程安全):```csharppublicsealedclassSingleton{privatestaticreadonlyLazy<Singleton>instance=newLazy<Singleton>(()=>newSingleton());privateSingleton(){}publicstaticSingletonInstance=>instance.Value;}```优点:简洁,Lazy<T>默认线程安全(通过LazyThreadSafetyMode.ExecutionAndPublication),支持延迟初始化。16.如何优化高频调用的数据库查询性能?优化策略:索引优化:为查询条件字段(如WHERE、JOIN、ORDERBY)添加索引,避免全表扫描。使用`EXPLAIN`分析执行计划(EFCore5+支持`context.Database.Log`或第三方工具)。减少数据量:使用`Select()`投影仅需要的字段,避免加载冗余数据(如`context.Users.Select(u=>u.Name).ToList()`)。批量操作:使用`ExecuteUpdateAsync`/`ExecuteDeleteAsync`(EFCore7+)替代逐条更新,减少网络往返(如`context.Users.Where(u=>u.Age<18).ExecuteUpdate(u=>u.SetProperty(x=>x.IsMinor,true))`)。缓存查询结果:对不常变更的数据使用内存缓存(IMemoryCache)或分布式缓存(IDistributedCache),如`cache.TryGetValue(key,outvarusers)?users:awaitLoadFromDbAndCache()`。分库分表:对超大数据量(如亿级记录),按时间或业务维度拆分数据库或表(如按月分表)。17.内存泄漏的常见原因及检测方法有哪些?常见原因:未释放非托管资源:如未调用`Dispose()`的FileStream、SqlConnection(即使使用`using`,若代码异常可能提前退出)。事件订阅未取消:订阅者未调用`-=`取消事件,导致发布者持有订阅者引用(即使订阅者不再使用)。缓存未设置过期策略:如使用`Dictionary`缓存对象,未清理过期条目(可用`MemoryCache`的AbsoluteExpiration或SlidingExpiration)。静态集合未清理:静态变量生命周期与应用程序一致,若持续添加对象且未移除,会导致内存增长。检测方法:性能计数器:监控“进程/工作集”“.NETCLR内存/堆大小”等指标,观察是否持续增长。PerfView:捕获GC堆转储(GCHeapSnapshot),分析大对象、未释放的对象引用链。dotMemory(JetBrains):可视化内存占用,追踪对象生命周期。代码审查:检查`IDisposable`实现(是否正确释放资源)、事件订阅(是否成对取消)、缓存策略(是否有过期机制)。五、并发与异步编程18.线程(Thread)、任务(Task)、异步(async/await)的核心区别是什么?线程(Thread):操作系统级执行单元,创建和切换成本高(涉及内核模式切换),需手动管理生命周期(如Start()、Join())。任务(Task):.NET基于线程池的抽象,代表一个异步操作(可能在后台线程执行,也可能同步完成),支持组合(ContinueWith)、取消(CancellationToken)、异常聚合(AggregateException)。async/await:语法糖,将异步代码转换为状态机,简化任务的链式调用(避免回调地狱),本质是对Task的封装。关键差异:线程是底层执行资源,Task是高层抽象(可能使用线程池线程或同步执行),async/await是编写异步代码的方式(不直接创建线程)。19.如何避免锁(lock)导致的死锁问题?死锁条件:互斥、持有并等待、不可抢占、循环等待。避免策略:按固定顺序加锁:所有代码以相同顺序获取多个锁(如先锁A再锁B,避免A→B和B
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026重庆市涪陵区龙潭镇人民政府选聘公益性岗位1人备考题库及答案详解(真题汇编)
- 边锋网络销售培训
- 虚拟货币交易安全保障协议2025年
- 2025年在线医疗咨询的隐私保护协议服务合同
- 《GB-T 25355-2010航空器 地面除冰防冰液体法》专题研究报告
- 《GB-T 25032-2010生活垃圾焚烧炉渣集料》专题研究报告
- 《JB 6221-1992工业X射线探伤机电气通 用技术条件》专题研究报告
- 议论文的相关知识
- 议事规则培训
- 森林消防员休假制度
- “住改商”登记利害关系业主同意证明(参考样本)
- DB42-T 2157-2023 乡镇生活污水治理设施运营维护管理技术规程
- 支气管哮喘防治指南(2024年版)解读
- 《UBM检查适应症》课件
- 安徽省合肥市庐阳区2024-2025学年数学三上期末质量检测试题含解析
- 2025年炉渣处理设施安全运行与维护合同4篇
- 文书模板-《更换业主委员会的申请》
- 夫妻债务约定协议书
- 肺源性心脏病超声
- DL-T5366-2014发电厂汽水管道应力计算技术规程
- 土地管理学课件
评论
0/150
提交评论