C#面试题及详细答案120道(51-60)-- LINQ与Lambda

前后端面试题》专栏集合了前后端各个知识模块的面试题,包括html,javascript,css,vue,react,java,Openlayers,leaflet,cesium,mapboxGL,threejs,nodejs,mangoDB,SQL,Linux... 。

前后端面试题-专栏总目录

文章目录

  • 一、本文面试题目录
      • [51. 什么是LINQ?LINQ的类型有哪些(LINQ to Objects、LINQ to SQL等)](#51. 什么是LINQ?LINQ的类型有哪些(LINQ to Objects、LINQ to SQL等))
      • [52. LINQ查询表达式与方法语法的区别](#52. LINQ查询表达式与方法语法的区别)
      • [53. 简述延迟执行(Deferred Execution)和即时执行(Immediate Execution)](#53. 简述延迟执行(Deferred Execution)和即时执行(Immediate Execution))
      • [54. 什么是IQueryable?与IEnumerable的区别](#54. 什么是IQueryable?与IEnumerable的区别)
      • [55. LINQ中的常见操作符(Where、Select、OrderBy、GroupBy等)的作用](#55. LINQ中的常见操作符(Where、Select、OrderBy、GroupBy等)的作用)
      • [56. 如何使用LINQ进行连接查询(Join)?](#56. 如何使用LINQ进行连接查询(Join)?)
      • [57. 什么是Lambda表达式?其结构是什么?](#57. 什么是Lambda表达式?其结构是什么?)
      • [58. LINQ to SQL和Entity Framework的区别](#58. LINQ to SQL和Entity Framework的区别)
      • [59. 如何优化LINQ查询性能?](#59. 如何优化LINQ查询性能?)
      • [60. 什么是表达式树(Expression Tree)?应用场景是什么?](#60. 什么是表达式树(Expression Tree)?应用场景是什么?)
  • 二、120道C#面试题目录列表

一、本文面试题目录

51. 什么是LINQ?LINQ的类型有哪些(LINQ to Objects、LINQ to SQL等)

  • 原理说明

    LINQ(Language Integrated Query,语言集成查询)是C#中用于查询数据的统一语法,它将查询能力直接集成到编程语言中,支持对各种数据源(集合、数据库、XML等)使用一致的语法进行查询。

    LINQ的核心思想是"将数据查询视为语言的一部分",无需针对不同数据源学习不同的查询语法(如SQL、XPath等)。

  • 常见LINQ类型

    • LINQ to Objects :查询内存中的集合(如List<T>Array等)。
    • LINQ to SQL:查询关系型数据库(如SQL Server),通过映射将数据库表转换为C#类。
    • LINQ to XML:查询和操作XML文档。
    • LINQ to Entities:基于Entity Framework查询数据库,是LINQ to SQL的进化版。
    • Parallel LINQ (PLINQ):并行查询,利用多核CPU加速查询过程。
  • 示例代码

    csharp 复制代码
    using System;
    using System.Linq;
    using System.Collections.Generic;
    
    class Program
    {
        static void Main()
        {
            // LINQ to Objects示例:查询整数集合中大于5的元素
            List<int> numbers = new List<int> { 3, 7, 2, 8, 5, 10 };
            var result = from num in numbers
                         where num > 5
                         select num;
    
            Console.WriteLine("LINQ to Objects结果:");
            foreach (var num in result)
            {
                Console.Write(num + " "); // 输出:7 8 10
            }
        }
    }

52. LINQ查询表达式与方法语法的区别

  • 原理说明

    LINQ有两种语法形式,两者功能等价,可相互转换:

    • 查询表达式 :类SQL的声明式语法,以from开头,selectgroup by结尾,结构清晰,适合复杂查询。
    • 方法语法 :通过调用扩展方法(如Where()Select())实现查询,更简洁,适合简单查询或链式调用。

    编译器会将查询表达式自动转换为方法语法执行。

  • 区别对比

    特性 查询表达式 方法语法
    语法风格 类SQL,声明式 方法调用,链式编程
    可读性 复杂查询更易读 简单查询更简洁
    适用场景 多表连接、分组、排序等复杂查询 简单过滤、投影等操作
  • 示例代码

    csharp 复制代码
    // 数据源
    List<string> fruits = new List<string> { "apple", "banana", "cherry", "date" };
    
    // 1. 查询表达式
    var queryExpr = from fruit in fruits
                    where fruit.Length > 5
                    orderby fruit
                    select fruit;
    
    // 2. 方法语法(等价于查询表达式)
    var methodSyntax = fruits
        .Where(fruit => fruit.Length > 5)
        .OrderBy(fruit => fruit);
    
    // 输出结果相同:banana cherry

53. 简述延迟执行(Deferred Execution)和即时执行(Immediate Execution)

  • 原理说明

    • 延迟执行 :LINQ查询在定义时不会立即执行,而是在首次枚举结果 (如foreach循环、ToList()等)时才执行。这使得查询可以被多次执行,且每次执行都基于数据源的最新状态。
    • 即时执行 :查询在定义时立即执行,结果被缓存。通常通过调用返回具体结果的方法(如ToList()Count())触发。
  • 关键区别

    • 延迟执行的查询可视为"查询计划",而非实际结果;即时执行则直接生成结果。
    • 延迟执行适合大数据集或需要动态更新数据源的场景;即时执行适合需要立即获取结果并复用的场景。
  • 示例代码

    csharp 复制代码
    List<int> numbers = new List<int> { 1, 2, 3 };
    
    // 延迟执行:查询未立即执行
    var deferredQuery = numbers.Where(n => n > 1);
    
    // 修改数据源
    numbers.Add(4);
    
    // 首次枚举时执行查询(结果:2,3,4)
    foreach (var num in deferredQuery)
    {
        Console.Write(num + " ");
    }
    
    // 即时执行:调用ToList()立即执行并缓存结果
    var immediateResult = numbers.Where(n => n > 1).ToList();
    numbers.Add(5);
    
    // 结果不变(仍为2,3,4),因为已缓存
    foreach (var num in immediateResult)
    {
        Console.Write(num + " ");
    }

54. 什么是IQueryable?与IEnumerable的区别

  • 原理说明

    • IQueryable :继承自IEnumerable,用于表示可查询的数据源(如数据库),支持将查询转换为底层数据源的查询语言(如SQL),实现远程查询
    • IEnumerable :表示内存中可枚举的集合,查询在本地内存中执行,适用于内存中的数据 (如List<T>)。
  • 核心区别

    特性 IQueryable IEnumerable
    执行位置 远程数据源(如数据库) 本地内存
    查询转换 支持转换为SQL等底层语言 不支持,直接在内存中执行
    延迟执行 支持(基于表达式树) 支持(基于委托)
    适用场景 数据库查询(如EF Core) 内存集合查询(如List)
  • 示例代码

    csharp 复制代码
    using System.Linq;
    using Microsoft.EntityFrameworkCore;
    
    // 假设DbContext中有一个Users表
    public class AppDbContext : DbContext
    {
        public DbSet<User> Users { get; set; }
    }
    
    class Program
    {
        static void Main()
        {
            using (var context = new AppDbContext())
            {
                // IQueryable:查询在数据库执行(生成SQL:SELECT * FROM Users WHERE Age > 18)
                IQueryable<User> dbQuery = context.Users.Where(u => u.Age > 18);
    
                // IEnumerable:查询在内存中执行(先加载所有数据到内存,再过滤)
                IEnumerable<User> memoryQuery = context.Users.ToList().Where(u => u.Age > 18);
            }
        }
    }
    
    public class User { public int Age { get; set; } }

55. LINQ中的常见操作符(Where、Select、OrderBy、GroupBy等)的作用

  • 原理说明

    LINQ操作符是用于构建查询的扩展方法,按功能可分为过滤、投影、排序、分组等类型。

  • 常见操作符及作用

    • Where:过滤元素,保留满足条件的元素。
    • Select:投影,将元素转换为新的形式(如提取属性或转换为匿名类型)。
    • OrderBy/OrderByDescending:按指定键升序/降序排序。
    • GroupBy:按指定键分组,返回键值与分组元素的集合。
    • Join:连接两个集合(类似SQL的JOIN)。
    • Count:返回元素数量(即时执行)。
    • First/FirstOrDefault:返回第一个元素(或默认值)。
  • 示例代码

    csharp 复制代码
    List<Student> students = new List<Student>
    {
        new Student { Name = "Alice", Age = 18, Score = 90 },
        new Student { Name = "Bob", Age = 20, Score = 85 },
        new Student { Name = "Charlie", Age = 18, Score = 95 }
    };
    
    // Where:筛选年龄大于18的学生
    var adults = students.Where(s => s.Age > 18);
    
    // Select:提取姓名和分数(投影为匿名类型)
    var nameScores = students.Select(s => new { s.Name, s.Score });
    
    // OrderBy:按分数降序排序
    var sortedByScore = students.OrderByDescending(s => s.Score);
    
    // GroupBy:按年龄分组
    var groupedByAge = students.GroupBy(s => s.Age);
    
    public class Student
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public int Score { get; set; }
    }

56. 如何使用LINQ进行连接查询(Join)?

  • 原理说明

    LINQ的Join操作用于根据两个集合中的共同键连接数据,类似SQL中的内连接(INNER JOIN)。GroupJoin则类似左外连接(LEFT JOIN),保留左集合中未匹配的元素。

  • 语法说明

    • 内连接:from a in 集合A join b in 集合B on a.键 equals b.键 select ...
    • 左外连接:结合GroupJoinDefaultIfEmpty()实现。
  • 示例代码

    csharp 复制代码
    // 数据源
    List<Student> students = new List<Student>
    {
        new Student { Id = 1, Name = "Alice", ClassId = 1 },
        new Student { Id = 2, Name = "Bob", ClassId = 2 }
    };
    
    List<Class> classes = new List<Class>
    {
        new Class { Id = 1, Name = "一班" },
        new Class { Id = 2, Name = "二班" }
    };
    
    // 1. 内连接:查询学生及其所属班级
    var innerJoin = from s in students
                    join c in classes on s.ClassId equals c.Id
                    select new { s.Name, ClassName = c.Name };
    // 结果:Alice-一班,Bob-二班
    
    // 2. 左外连接:查询所有学生(包括无班级的学生)
    var leftJoin = from s in students
                   join c in classes on s.ClassId equals c.Id into joinedClasses
                   from c in joinedClasses.DefaultIfEmpty() // 无匹配时返回默认值(null)
                   select new { s.Name, ClassName = c?.Name ?? "无班级" };
    
    public class Student { public int Id { get; set; } public string Name { get; set; } public int ClassId { get; set; } }
    public class Class { public int Id { get; set; } public string Name { get; set; } }

57. 什么是Lambda表达式?其结构是什么?

  • 原理说明

    Lambda表达式是一种简洁的匿名函数写法,可用于定义委托或表达式树,广泛应用于LINQ、事件等场景。其核心是"输入参数 => 表达式或语句块"。

  • 结构

    • 参数列表 :零个或多个参数,若单个参数可省略括号,无参数用()表示。
    • Lambda运算符=>(读作"goes to")。
    • 主体 :表达式(返回值类型自动推断)或语句块(需显式return)。
  • 示例代码

    csharp 复制代码
    // 1. 无参数,返回常量
    Func<string> greet = () => "Hello";
    Console.WriteLine(greet()); // 输出:Hello
    
    // 2. 单个参数(省略括号)
    Func<int, int> square = x => x * x;
    Console.WriteLine(square(5)); // 输出:25
    
    // 3. 多个参数
    Func<int, int, int> add = (a, b) => a + b;
    Console.WriteLine(add(3, 4)); // 输出:7
    
    // 4. 语句块主体(需显式return)
    Func<int, string> checkEven = num =>
    {
        if (num % 2 == 0)
            return "偶数";
        else
            return "奇数";
    };
    Console.WriteLine(checkEven(7)); // 输出:奇数

58. LINQ to SQL和Entity Framework的区别

  • 原理说明

    两者均为微软的ORM(对象关系映射)技术,用于将C#对象与数据库表映射,但定位和功能不同:

    • LINQ to SQL:轻量级ORM,仅支持SQL Server,功能简单,已逐渐被淘汰。
    • Entity Framework (EF):功能更强大的ORM,支持多数据库(SQL Server、MySQL等),提供Code First、Database First等开发模式,是LINQ to SQL的替代者。
  • 核心区别

    特性 LINQ to SQL Entity Framework
    数据库支持 仅SQL Server 多数据库(SQL Server、MySQL等)
    模型灵活性 仅支持表到类的映射 支持复杂模型(继承、关联等)
    开发模式 仅Database First Code First、Database First、Model First
    扩展性 较弱 强(可自定义映射、拦截器等)
    现状 已停止更新 持续维护(如EF Core)
  • 示例代码

    csharp 复制代码
    // LINQ to SQL示例(需手动创建DataContext)
    public class SchoolDataContext : System.Data.Linq.DataContext
    {
        public SchoolDataContext(string connectionString) : base(connectionString) { }
        public System.Data.Linq.Table<Student> Students { get; set; }
    }
    
    // Entity Framework示例(EF Core)
    public class SchoolDbContext : DbContext
    {
        public DbSet<Student> Students { get; set; }
        protected override void OnConfiguring(DbContextOptionsBuilder options)
            => options.UseSqlServer("连接字符串");
    }

59. 如何优化LINQ查询性能?

  • 原理说明

    LINQ查询性能受数据源类型、查询复杂度、执行时机等因素影响,优化目标是减少不必要的计算和数据传输。

  • 优化方法

    1. 使用IQueryable而非IEnumerable :对数据库查询,IQueryable可将过滤逻辑转换为SQL,减少内存加载的数据量。
    2. 延迟执行与即时执行结合 :避免过早调用ToList(),只在需要时加载数据。
    3. 减少返回字段 :使用Select投影必要字段,而非返回整个对象。
    4. 避免N+1查询问题 :使用Include()预加载关联数据(EF Core中)。
    5. 合理使用索引:对查询频繁的字段在数据库中创建索引。
    6. 分页查询 :使用Skip()Take()减少一次性加载的数据量。
  • 示例代码

    csharp 复制代码
    using Microsoft.EntityFrameworkCore;
    
    // 反例:IEnumerable导致全表加载后过滤
    var badQuery = context.Users.ToList().Where(u => u.Age > 18); // 先加载所有用户
    
    // 正例:IQueryable在数据库中过滤
    var goodQuery = context.Users.Where(u => u.Age > 18); // 仅加载符合条件的用户
    
    // 优化:只返回必要字段
    var projectedQuery = context.Users
        .Where(u => u.Age > 18)
        .Select(u => new { u.Name, u.Email }); // 仅查询Name和Email
    
    // 优化:预加载关联数据(避免N+1问题)
    var withInclude = context.Users
        .Include(u => u.Orders) // 一次性加载用户及其订单
        .Where(u => u.Age > 18);
    
    // 分页查询
    int pageSize = 10;
    int pageNumber = 1;
    var paginated = context.Users
        .Skip((pageNumber - 1) * pageSize)
        .Take(pageSize);

60. 什么是表达式树(Expression Tree)?应用场景是什么?

  • 原理说明

    表达式树是一种数据结构,用于表示代码表达式的语法结构(如变量、运算符、方法调用等)。它将代码转换为可遍历、修改的对象树,而非直接编译为可执行代码。

  • 核心特性

    • 可在运行时解析和修改表达式逻辑。
    • 常用于将C#表达式转换为其他语言(如SQL)。
  • 应用场景

    1. LINQ to Entities:将Lambda表达式转换为SQL查询。
    2. 动态查询构建:在运行时动态生成查询条件。
    3. ORM框架:映射对象操作到数据库操作。
  • 示例代码

    csharp 复制代码
    using System;
    using System.Linq.Expressions;
    
    class Program
    {
        static void Main()
        {
            // 构建表达式树:(x, y) => x + y
            ParameterExpression x = Expression.Parameter(typeof(int), "x");
            ParameterExpression y = Expression.Parameter(typeof(int), "y");
            BinaryExpression add = Expression.Add(x, y);
            Expression<Func<int, int, int>> addExpr = Expression.Lambda<Func<int, int, int>>(add, x, y);
    
            // 编译表达式树为委托并执行
            Func<int, int, int> addFunc = addExpr.Compile();
            Console.WriteLine(addFunc(3, 5)); // 输出:8
    
            // 解析表达式树(打印表达式结构)
            Console.WriteLine(addExpr.Body.ToString()); // 输出:(x + y)
        }
    }

    上述示例中,表达式树addExpr表示x + y的逻辑,可在运行时解析其结构,或编译为委托执行。

二、120道C#面试题目录列表

文章序号 C#面试题120道
1 C#面试题及详细答案120道(01-10)
2 C#面试题及详细答案120道(11-20)
3 C#面试题及详细答案120道(21-30)
4 C#面试题及详细答案120道(31-40)
5 C#面试题及详细答案120道(41-50)
6 C#面试题及详细答案120道(51-60)
7 C#面试题及详细答案120道(61-75)
8 C#面试题及详细答案120道(76-85)
9 C#面试题及详细答案120道(86-95)
10 C#面试题及详细答案120道(96-105)
11 C#面试题及详细答案120道(106-115)
12 C#面试题及详细答案120道(116-120)
相关推荐
loong_XL6 小时前
AC自动机算法-字符串搜索算法:敏感词检测
开发语言·算法·c#
宝桥南山8 小时前
.NET10 - 尝试一下Blazor Web Assembly Standalone App的fingerprint新特性
microsoft·微软·c#·asp.net·.net·.netcore
我是唐青枫9 小时前
C#.NET DbContext 池化机制深入解析:提升 EF Core 性能的关键
c#·.net
用户37215742613511 小时前
如何使用 C# 将 CSV 数据轻松转换为 PDF
c#
未孤_有青山1 天前
库卡机器人通讯-EtherKRL-XML格式
xml·c#
課代表1 天前
VB.NET 与 C# 文件操作文本到二进制文件的读写
c#·二进制文件·vb.net·streamwriter·文本文件·读写·streamreader
我是唐青枫1 天前
C#.NET Cronos 实战:优雅解析与执行 Cron 表达式
c#·.net
还是大剑师兰特1 天前
C#面试题及详细答案120道(41-50)-- 异常处理
c#·大剑师
Hare_bai1 天前
WPF的MVVM模式核心架构与实现细节
ui·架构·c#·wpf·交互·xaml·mvvm