.NET高级面试题及答案详解

124 阅读4分钟

一、语言特性与底层机制

  1. 委托与事件的区别及应用场景?

    • 委托:引用方法的类型,允许动态绑定方法(如delegate void MyDelegate(string s))。
    • 事件:基于委托的发布-订阅模型,封装委托以控制订阅权限(如public event EventHandler MyEvent)。
    • 场景:事件用于解耦组件(如UI按钮点击),委托用于回调机制(如异步任务完成通知)。
  2. 解释async/await的工作原理及性能优势?

    • 原理:编译器将异步方法拆分为状态机,await释放线程执行后续任务,完成后恢复执行。

    • 优势:避免线程阻塞,提升吞吐量。示例:

      csharp
      	public async Task<string> FetchDataAsync() {
      
      	    using var client = new HttpClient();
      
      	    return await client.GetStringAsync("https://api.example.com");
      
      	}
      
  3. 泛型约束的主要类型及示例?

    • 主要约束

      • where T : class(引用类型)
      • where T : struct(值类型)
      • where T : new()(有公共无参构造函数)
    • 次要约束

      • where T : IComparable(实现接口)
    • 示例public class List<T> where T : IComparable { ... }

  4. 垃圾回收(GC)的分代回收策略及优化建议?

    • 策略:第0代(短期对象)、第1/2代(长期对象),标记-清除算法。
    • 优化:避免大对象在第0代频繁回收,手动释放非托管资源(实现IDisposable)。

二、框架与架构设计

  1. ASP.NET Core与ASP.NET的主要区别及优势?

    • 区别

      • ASP.NET Core跨平台(Kestrel服务器),ASP.NET仅限Windows。
      • ASP.NET Core模块化中间件,ASP.NET依赖IIS。
    • 优势:更高性能、灵活部署、内置依赖注入。

  2. 微服务架构中服务间通信的最佳实践?

    • 关键点

      • 通信协议:RESTful API(HTTP)、gRPC(高性能)。
      • 消息队列:RabbitMQ(发布-订阅)、Kafka(高吞吐量)。
      • 服务发现:Consul、Eureka。
    • 示例:订单服务通过RabbitMQ向库存服务发送扣减消息。

  3. CQRS模式在ASP.NET Core中的实现及优势?

    • 实现:通过MediatR分离命令(写入)与查询(读取)。

    • 示例

      csharp
      	public class CreateOrderCommandHandler : IRequestHandler<CreateOrderCommand, Order> {
      
      	    public Task<Order> Handle(CreateOrderCommand request, CancellationToken cancellationToken) {
      
      	        // 业务逻辑
      
      	    }
      
      	}
      
    • 优势:解耦读写逻辑,提升扩展性。

  4. 领域驱动设计(DDD)的核心概念及实践?

    • 核心概念

      • 聚合(Aggregate) :事务一致性边界(如订单聚合包含订单项)。
      • 仓储(Repository) :抽象数据访问层(如IOrderRepository)。
    • 实践:电商项目中划分订单、库存、支付边界上下文。

三、性能优化与并发

  1. 数据库查询性能优化的关键策略?

    • 策略

      • 索引优化(避免前置%通配符)。
      • 减少JOIN操作,使用EXISTS替代子查询。
      • 分页查询(OFFSET-FETCHKEYSET PAGINATION)。
    • 工具:Entity Framework Core的Include/ThenInclude避免N+1问题。

  2. Redis缓存策略设计及避免击穿的方法?

    • 策略

      • 高频低变数据缓存(如商品详情)。
      • 分布式锁(Redis.Lock)保证缓存更新原子性。
    • 示例

      csharp
      	var cacheKey = "product:123";
      
      	var cachedData = await _cache.GetStringAsync(cacheKey);
      
      	if (cachedData == null) {
      
      	    using var lock = await _cache.LockAsync($"{cacheKey}:lock", TimeSpan.FromSeconds(5));
      
      	    // 更新缓存
      
      	}
      
  3. 多线程编程中死锁的避免方法?

    • 方法

      • 按固定顺序请求资源(如锁A→锁B)。
      • 使用Timeout和重试机制。
    • 示例

      csharp
      	var lockA = new object();
      
      	var lockB = new object();
      
      	Parallel.Invoke(
      
      	    () => { lock (lockA) { Thread.Sleep(100); lock (lockB); } },
      
      	    () => { lock (lockB) { Thread.Sleep(100); lock (lockA); } } // 死锁!
      
      	);
      

四、设计模式与编码实践

  1. 工厂模式与依赖注入的区别及适用场景?

    • 区别

      • 工厂模式解耦对象创建,依赖注入解耦对象使用。
    • 场景

      • 工厂模式:创建复杂对象(如DbContext根据环境配置)。
      • 依赖注入:ASP.NET Core服务注册(services.AddScoped<IMyService, MyService>())。
  2. SOLID原则中的开放封闭原则如何实践?

    • 实践

      • 扩展功能通过新增类,而非修改现有代码(如策略模式)。
      • 示例:支付方式扩展(新增AlipayStrategy而不修改PaymentProcessor)。

五、安全与部署

  1. 敏感信息管理的最佳实践?

    • 实践

      • 使用Azure Key Vault或AWS Secrets Manager。
      • 配置文件引用(如appsettings.jsonConnectionStrings:Secret)。
    • 代码示例

      csharp
      	var secret = await new SecretClient(new Uri("https://myvault.vault.azure.net/"), new DefaultAzureCredential()).GetSecretAsync("my-secret");
      
  2. ASP.NET Core应用的高可用部署策略?

    • 策略

      • 跨区域部署(Azure Traffic Manager)。
      • 容器化(Docker + Kubernetes自动伸缩)。
    • 工具:Polly库实现断路器,防止级联故障。

六、问题解决与案例

  1. 团队中遇到技术冲突的解决步骤?

    • 步骤

      1. 明确冲突点(如架构设计分歧)。
      2. 提出数据支持(如性能测试报告)。
      3. 寻求第三方意见(如技术负责人仲裁)。
  2. 实时通信在ASP.NET Core中的实现方案?

    • 方案

      • SignalR(WebSocket协议)。
      • 示例:聊天应用通过HubConnection推送消息。
      csharp
      	public class ChatHub : Hub {
      
      	    public async Task SendMessage(string user, string message) {
      
      	        await Clients.All.SendAsync("ReceiveMessage", user, message);
      
      	    }
      
      	}