当前位置: 首页 > news >正文

.NET/C#⾯试题汇总系列:集合、异常、泛型、LINQ、委托、EF!(完整版)

1.IList 接⼝与List的区别是什么?

  • 定义与继承关系‌:

    • IList<T> 是一个接口,定义了一组对象的集合,这些对象可以通过索引进行访问,并且支持插入、删除和搜索等操作。它继承自 ICollection<T> 和 IEnumerable<T>,以及它们的非泛型版本。
    • List<T> 是一个类,实现了 IList<T> 接口。它提供了接口中定义的所有方法的具体实现,并添加了一些额外的功能,如排序、搜索等。
  • 功能与灵活性‌:

    • 使用 IList<T> 接口时,你的代码更加灵活,因为它不依赖于具体的实现类(如 List<T>)。这意呀着你可以轻松地更换底层的数据存储结构,只要它实现了 IList<T> 接口。
    • List<T> 提供了更多的功能和性能优化,因为它是具体的实现类。但是,这也意味着你的代码与 List<T> 紧密耦合,更换数据存储结构时可能需要更多的工作。
  • 使用场景‌:

    • 当你的代码需要处理一个集合,但你不关心这个集合是如何实现的,或者你希望你的代码能够轻松地与不同的集合实现一起工作时,使用 IList<T> 接口是更好的选择。
    • 当你需要利用 List<T> 提供的特定功能(如 SortFind 等)时,或者当你确定你的应用程序将始终使用 List<T> 作为数据存储时,直接使用 List<T> 类可能更方便。

 2.泛型的主要约束和次要约束是什么?

当⼀个泛型参数没有任何约束时,它可以进⾏的操作和运算是⾮常有限的,因为不能对实参进⾏任何类型 上的保证,这时候就需要⽤到泛型约束。泛型的约束分为:主要约束和次要约束,它们都使实参必须满⾜ ⼀定的规范,C#编译器在编译的过程中可以根据约束来检查所有泛型类型的实参并确保其满⾜约束条件。

主要约束

⼀个泛型参数⾄多拥有⼀个主要约束,主要约束可以是⼀个引⽤类型、class或者struct。如果指定⼀个引 ⽤类型(class),那么实参必须是该类型或者该类型的派⽣类型。相反,struct则规定了实参必须是⼀个 值类型。

次要约束

次要约束主要是指实参实现的接⼝的限定。对于⼀个泛型,可以有0到⽆限的次要约束,次要约束规定了实 参必须实现所有的次要约束中规定的接⼝。

public class MyGenericClass<T> where T : class, IMyInterface // 引用类型约束和接口约束
{// ...
}public interface IMyInterface
{// ...
}

在这个例子中,MyGenericClass的泛型类型参数T被约束为必须是引用类型,并且必须实现IMyInterface接口。这同时使用了主要约束(引用类型约束)和次要约束(接口约束)。

3. 如何把⼀个array复制到arrayist⾥?

foreach( object arr in array)
{arrayist.Add(arr);
}

4.List, Set, Map是否继承⾃Collection接⼝?

List, Set,是否继承自Collection接口,Map不是。

  • List:
    • 1.可以允许重复的对象。
    • 2.可以插入多个null元素。
    • 3.是一个有序容器,保持了每个元素的插入顺序,输出的顺序就是插入的顺序。
    • 4.常用的实现类有 ArrayList、LinkedList 和 Vector。ArrayList 最为流行,它提供了使用索引的随意访问,而 LinkedList 则对于经常需要从 List 中添加或删除元素的场合更为合适。
  • Set:
    • 1.不允许重复对象
    • 2.无序容器,你无法保证每个元素的存储顺序,TreeSet通过 Comparator 或者 Comparable 维护了一个排序顺序。
    • 3.只允许一个 null 元素
    • 4.Set 接口最流行的几个实现类是 HashSet、LinkedHashSet 以及 TreeSet。
  • Map:
    • 1.Map不是collection的子接口或者实现类。Map是一个接口。
    • 2.Map 的 每个 Entry 都持有两个对象,也就是一个键一个值(键值对),Map 可能会持有相同的值对象但键对象必须是唯一的。
    • 3. TreeMap 也通过 Comparator 或者 Comparable 维护了一个排序顺序。
    • 4. Map 里你可以拥有随意个 null 值但最多只能有一个 null 键。
    • 5.Map 接口最流行的几个实现类是 HashMap、LinkedHashMap、Hashtable 和 TreeMap。(HashMap、TreeMap最常用)

5. Set⾥的元素是不能重复的,那么⽤什么⽅法来区分重复与否呢? 是⽤==还是equals()? 它 们有何区别?

Set⾥的元素是不能重复的,那么⽤iterator()⽅法来区分重复与否。equals()是判读两个Set是否相等。 equals()和==⽅法决定引⽤值是否指向同⼀对像,equals()在类中被覆盖,为的是当两个分离的对象的内 容和类型相配的话,返回真值。

6.有50万个int类型的数字,现在需要判断⼀下⾥⾯是否存在重复的数字,请你简要说⼀下思路。

  1. 使用HashSet:创建一个HashSet对象,遍历整个数字集合,将每个数字添加到HashSet中。由于HashSet不允许重复元素,如果添加操作失败(即add方法返回false),则说明该数字已经存在于集合中,因此存在重复的数字。

  2. 排序后检查相邻元素:首先对数字集合进行排序,然后遍历排序后的集合,比较相邻的元素是否相等。如果发现相等的相邻元素,则说明存在重复的数字。

7.数组有没有length()这个⽅法? String有没有length()这个⽅法?

数组和字符串都使用Length属性来获取它们的长度,而不是length()方法

  • 数组没有length()这个方法。在C#中,获取数组的长度是通过其属性.Length来获取的。例如,对于一个整型数组arr,可以使用arr.Length来获取数组的长度。
  • String类有Length属性而不是length()方法。通过访问字符串对象的Length属性,可以获取字符串的长度,即字符的数量。例如,对于一个字符串s,可以使用s.Length来获取字符串的长度。

8.⼀个整数List中取出最⼤数(找最⼤值)。不能⽤Max⽅法。

遍历比较

这种方法通过遍历列表中的每个元素,并将当前元素与已知的最大值进行比较,从而找到最大值。如果当前元素大于已知的最大值,则更新最大值。

9. C#异常类有哪些信息?

C#异常类(通常继承自System.Exception类)

  1. Message 属性‌:这个属性包含了异常的描述性消息,是一个字符串类型。它是最常用于了解异常原因的属性之一。

  2. StackTrace 属性‌:这个属性提供了异常发生时调用堆栈的快照。调用堆栈是一个方法调用序列,展示了异常被抛出时的方法调用路径。这对于调试和定位问题非常有用。

  3. InnerException 属性‌:如果当前异常是由另一个异常引起的(即在一个异常的catch块中抛出了新的异常,并将原始异常作为新异常的InnerException),则此属性包含了对那个原始异常的引用。这允许你追踪异常的根源。

10. 如何创建⼀个⾃定义异常?

根据类继承原则和异常处理原则,我们可以使⽤以下⽅式来⾃定义⼀个类: 

public class CustomException : Exception
{
}

11. 利⽤IEnumerable实现斐波那契数列⽣成?

IEnumerable<int> GenerateFibonacci(int n)
{if (n >= 1) yield return 1;int a = 1, b = 0;for (int i = 2; i <= n; ++i){int t = b;b = a;a += t;yield return a;}
}

12.请利⽤ foreach 和 ref 为⼀个数组中的每个元素加 1

int[] arr= { 1, 2, 3, 4, 5 };
Console.WriteLine(string.Join(",",arr));
foreach (ref int i in arr.AsSpan())
{i++;
}
Console.WriteLine(string.Join(",", arr));

13.如何针对不同的异常进⾏捕捉?

  • 捕捉并处理文件读写异常
public void SafeReadFile(string filePath)
{try{// 尝试读取文件string content = System.IO.File.ReadAllText(filePath);Console.WriteLine($"文件内容: {content}");}catch (System.IO.FileNotFoundException ex){Console.WriteLine($"文件未找到: {ex.Message}");}catch (System.IO.IOException ex){Console.WriteLine($"读写文件时发生错误: {ex.Message}");}catch (Exception ex){// 捕捉所有未处理的异常Console.WriteLine($"发生未知错误: {ex.Message}");}
}
  • 捕捉并处理网络请求异常
using System.Net.Http;
using System.Threading.Tasks;public async Task<string> SafeWebRequest(string url)
{try{using (HttpClient client = new HttpClient()){HttpResponseMessage response = await client.GetAsync(url);response.EnsureSuccessStatusCode(); // 抛出异常如果响应状态码表示失败string responseBody = await response.Content.ReadAsStringAsync();return responseBody;}}catch (HttpRequestException ex){Console.WriteLine($"网络请求错误: {ex.Message}");return null;}catch (TaskCanceledException ex){Console.WriteLine($"网络请求超时或被取消: {ex.Message}");return null;}catch (Exception ex){// 捕捉所有未处理的异常Console.WriteLine($"网络请求发生未知错误: {ex.Message}");return null;}
}
  • 捕捉并处理数据库操作异常
    using System.Data.SqlClient;public void SafeDatabaseOperation(string connectionString, string query)
    {try{using (SqlConnection connection = new SqlConnection(connectionString)){connection.Open();using (SqlCommand command = new SqlCommand(query, connection)){command.ExecuteNonQuery();}}}catch (SqlException ex){// 根据SqlException的Number属性可以进一步区分错误类型Console.WriteLine($"数据库操作错误: {ex.Message}");if (ex.Number == -2) // 假设-2代表连接超时{Console.WriteLine("可能是数据库连接超时了。");}}catch (Exception ex){// 捕捉所有未处理的异常Console.WriteLine($"数据库操作中发生未知错误: {ex.Message}");}
    }

14.如何避免类型转换时的异常?

  • 使用as关键字进行安全的类型转换:as关键字用于尝试将对象转换为指定的类型,如果转换失败,它会返回null而不是抛出异常。
    object obj = "Hello";
    string str = obj as string; // 成功转换
    if (str != null)
    {Console.WriteLine(str);
    }
    else
    {Console.WriteLine("转换失败");
    }
    
  • 使用is关键字检查对象是否为特定类型的实例:is关键字用于检查对象是否属于指定的类型或实现了指定的接口。
    object obj = "Hello";
    if (obj is string)
    {string str = (string)obj;Console.WriteLine(str);
    }
    else
    {Console.WriteLine("不是字符串类型");
    }
    

15.Serializable特性有什么作⽤?

Serializable 是一个属性(Attribute),用于指示一个类可以被序列化。序列化是将对象的状态信息转换为可以存储或传输的形式的过程,比如转换为二进制流或XML文档。反序列化则是这个过程的逆操作,即将存储或传输的信息恢复为原始对象。

作用:

  1. 持久化:通过将对象序列化到磁盘上,可以将其状态保存下来,以便稍后重新加载和使用。这对于需要长时间运行的程序非常有用,因为它允许程序在中断后恢复其状态。

  2. 远程调用:序列化的对象可以通过网络发送给远程计算机,然后在远程计算机上进行反序列化以恢复原始对象的状态。这允许在不同的系统之间共享数据和对象。

  3. 复制对象:序列化可以将对象转换为字节流,然后可以在内存中复制该字节流以创建对象的副本。这对于实现深拷贝非常有用,因为这样可以确保对象及其所有子对象都被正确地复制。

  4. 跨应用程序通信:序列化的对象可以作为参数传递给其他应用程序或组件,从而实现跨应用程序的通信和数据交换。

16.委托是什么?

委托是一种类型,它封装了对方法的引用。在C#中,委托(Delegate)是一种引用类型,它可以用来封装一个方法,并在需要时调用这个方法。

17.如何自定义委托?

委托(Delegate)是一种类型安全的函数指针,它允许将方法作为参数传递给其他方法,或者将方法作为其他方法的返回值。

  1. 定义委托类型
  2. ‌创建委托实例
  3. ‌调用委托
internal class Program
{static void Main(string[] args){StrDelegate sd = GetTime;//2、创建委托实例string getsd = sd();//3、调用委托Console.WriteLine(getsd);}public delegate string StrDelegate();//1、定义委托类型public static string GetTime() {return DateTime.Now.ToString("HH:mm:ss");}
}

18 .NET默认的委托类型有哪⼏种?

Action 委托(无返回值的委托)

  • 用途‌:用于表示不返回任何值(即void返回类型)的方法。
  • 重载‌:Action 委托有多个重载版本,允许传递不同数量的参数(从0个到16个不等)。
  • 示例‌:
    static void Main(string[] args)
    {EAction();EAction("你好");
    }
    public static void EAction()
    {Action action = () => { Console.WriteLine("Hello world"); };action();
    }
    public static void EAction(string message)
    {Action<string> action = (x) => { Console.WriteLine(message); };action(message);
    }

    Func 委托(有返回值的委托)

  • 用途‌:用于表示具有返回值的方法。
  • 重载‌:Func 委托有多个重载版本,每个版本都至少有一个输入参数(代表方法的输入),并有一个返回类型(代表方法的返回值)。输入参数的数量可以从0个到16个不等。
  • 示例‌:
    Func<int, int, int> FAdd = (a, b) => { return a + b; };
    Console.WriteLine(FAdd(1, 2));//3
    Func<string, string> FMsg = (x) => { return "Hello" + x; };
    Console.WriteLine(FMsg("小明"));//Hello小明

19.什么是泛型委托?

泛型委托是一种特殊类型的委托,它允许你定义一个委托类型,该类型可以引用任何具有特定签名的方法,而不需要事先知道这些方法的参数类型或返回类型。泛型委托提供了一种灵活的方式来处理不同类型的方法调用,并提高了代码的重用性和类型安全性。

  • 有参数有返回值的泛型委托
static void Main(string[] args)
{// 2、创建一个泛型委托实例,用于引用两个整数相乘的方法MyDelegate<int, int, int> myDele = (x, y) => (x * y);//3、调用委托实例,执行乘法操作int result =myDele(3, 4);
}
//1、// 定义一个泛型委托,它接受两个整数参数并返回它们的乘积
public delegate TMyResult MyDelegate<T1,T2, TMyResult>(T1 x,T2 y);
  • 有参数无返回值的泛型委托
static void Main(string[] args)
{MyDelegate<string> my = (x) => { Console.WriteLine(x); };my("Hello");
}
public delegate void MyDelegate<T>(T t);
  • 无参数无返回值的泛型委托    
static void Main(string[] args)
{MyDelegate<int> my = GetT<int>;Console.WriteLine(my());// 调用委托并输出返回值
}
public delegate T MyDelegate<T>();
public static T GetT<T>() { return default(T);//返回默认值
}

20. 什么是匿名⽅法?

匿名⽅法是⽤作委托的参数的⼀段代码。

匿名方法是一种没有显式声明的名称但可作为委托参数或表达式树中的表达式的代码块

示例:

有参数有返回值的匿名方法

Func<int, int, int> Add = delegate(int a, int b)
{return a + b;
};// 调用
int result = Add(5, 3);
Console.WriteLine(result); // 输出 8

21.什么是闭包?

通过Lambda表达式可以访问Lambda表达式块外部的变量,这成为闭包。 当引⽤外部变量时,需要注意,外部变量变化时,lambda表达式的结果也可能会随着外部变量变化⽽变 化。

例子:

  •  int y = 5;
  •  Func lambda = x => x + y;
  •  Console.WriteLine(lambda(1));
  •  y = 10;
  •  Console.WriteLine(lambda(1));

22.EF(Entity Framework)是什么?

Entity Framework(简称EF)是微软提供的一个对象关系映射(ORM)框架,用于.NET应用程序。

主要有三种⽅式

  1. Database First“数据库优先”
  2. Model First“模型优先”
  3. Code First“代码优先”

EF的主要特点如下:

  1. 对象关系映射:EF将数据库表映射为.NET对象,使得开发者可以使用面向对象的方式来操作数据库。
  2. LINQ支持:EF支持使用LINQ查询来操作数据,提高了代码的可读性和编写效率。
  3. 变更跟踪:EF能够自动跟踪对象的变化,并生成相应的SQL语句来更新数据库。
  4. 延迟加载:EF支持延迟加载(Lazy Loading),只有在真正访问对象时才加载数据,提高了性能。
  5. 代码优先、模型优先和数据库优先:EF支持三种开发模式,可以根据项目需求选择合适的模式。
  6. 多个数据库提供商支持:EF支持多种数据库,如SQL Server、MySQL、PostgreSQL等。
  7. 与Visual Studio集成:EF与Visual Studio集成,提供了可视化的设计器和工具,方便开发者操作和管理数据模型。

23.什么是ORM?

ORM(对象关系映射,Object-Relational Mapping)是一种编程技术,用于将对象模型与数据库中的关系数据模型相互转换

它使得开发者能够使用面向对象的方式来操作数据库,而不需要直接编写SQL语句

ORM框架会自动生成相应的SQL语句并执行,从而使得数据访问更加高效。

  • O=>表实体
  • R=>数据库.表
  • M=>映射关系

优点

  1. 简化数据访问代码:ORM将数据库操作转换为对象操作,使得数据访问代码更简洁、易读。
  2. 提高开发效率:ORM提供了丰富的API和工具,减少了手动编写SQL语句的工作量。
  3. 跨数据库支持:ORM支持多种数据库,可以方便地切换数据库提供商。
  4. 自动处理事务:ORM框架可以自动处理事务,确保数据的完整性和一致性。
  5. 支持复杂的数据模型:ORM支持复杂的数据模型,如继承、关联等。
  6. 集成开发工具:ORM与开发工具集成,提供了可视化的设计器和工具,方便开发者操作和管理数据模型。

缺点

  1. 性能问题:ORM生成的SQL语句可能不是最优的,可能导致性能问题。
  2. 灵活性受限:ORM可能不支持某些特定的数据库特性或优化。
  3. 学习成本:ORM有一定的学习成本,需要了解其原理和使用方法。
  4. 代码冗余:ORM可能生成冗余的代码,增加了应用程序的体积。

24.为什么⽤EF⽽不⽤原⽣的ADO.NET?

  1. 简化数据访问代码:EF将数据库操作转换为对象操作,使得数据访问代码更简洁、易读。开发者可以使用面向对象的方式来操作数据库,而不需要编写SQL语句。

  2. 提高开发效率:EF提供了丰富的API和工具,减少了手动编写SQL语句的工作量。它支持LINQ查询,提高了代码的可读性和编写效率。

  3. 跨数据库支持:EF支持多种数据库,可以方便地切换数据库提供商。这使得应用程序更具灵活性,能够适应不同的数据库需求。

  4. 自动处理事务:EF框架可以自动处理事务,确保数据的完整性和一致性。这简化了事务管理的复杂性,并减少了出错的可能性。

  5. 支持复杂的数据模型:EF支持复杂的数据模型,如继承、关联等。这使得应用程序能够更好地处理复杂的数据关系,并提高数据的一致性。

  6. 集成开发工具:EF与开发工具(如Visual Studio)集成,提供了可视化的设计器和工具,方便开发者操作和管理数据模型。这提高了开发效率,并使得数据模型管理更加直观。

  7. 变更跟踪和延迟加载:EF能够自动跟踪对象的变化,并生成相应的SQL语句来更新数据库。它还支持延迟加载,只有在真正访问对象时才加载数据,提高了性能。

25.如何提⾼LINQ性能问题?

  • 选择合适的数据结构
  • 避免不必要的数据转换
  • 缓存结果:如果某个LINQ查询会被频繁地调用,那么可以考虑将结果缓存起来,以减少数据库访问的次数。
  • 优化数据库
  • 使用分页

26.什么是协变和逆变?

可变性是以⼀种类型安全的⽅式,将⼀个对象作为另⼀个对象来使⽤。其对应的术语则是不变性 (invariant)。

可变性: 可变性是以⼀种类型安全的⽅式,将⼀个对象作为另⼀个对象来使⽤

例如对普通继承中的可变性:若某 ⽅法声明返回类型为Stream,在实现时可以返回⼀个MemoryStream。

可变性有两种类型:协变和逆变。

协变性

可以建⽴⼀个较为⼀般类型的变量,然后为其赋值,值是⼀个较为特殊类型的变量。

例如:

  • string str = "test";
  • object obj = str

逆变性:

在上⾯的例⼦中,我们⽆法将str和⼀个新的object对象画等号。如果强⾏要实现的话,只能这么 ⼲:

  • string s = (string) new object();

27.什么是IEnumerable?

  • IEnumerable及IEnumerable的泛型版本IEnumerable是⼀个接⼝,它只含有⼀个⽅法GetEnumerator。
  • Enumerable这个静态类型含有很多扩展⽅法,其扩展的⽬标是IEnumerable。
  • 实现了这个接⼝的类可以使⽤Foreach关键字进⾏迭代(迭代的意思是对于⼀个集合,可以逐⼀取出元素 并遍历之)。
  • 实现这个接⼝必须实现⽅法GetEnumerator

28.IEnumerable的缺点有哪些?

  1. 性能问题:IEnumerable接口的实现通常需要额外的内存开销,因为它需要维护一个迭代器的状态。对于大型集合或需要频繁遍历的场景,这可能会导致性能下降。

  2. 类型限制:IEnumerable接口只能用于遍历集合,它不能提供其他集合操作,如添加、删除元素等。如果需要进行这些操作,你需要使用具体的集合类型(如List、Dictionary等)。

  3. 缺乏并发性支持:IEnumerable接口不支持并行遍历,这意味着在多线程环境中,多个线程无法同时遍历同一个集合。如果需要在多线程环境下处理集合,你可能需要使用其他并发集合类型(如ConcurrentBag、ConcurrentQueue等)。

  4. 缺乏延迟执行:IEnumerable接口的遍历是在调用GetEnumerator方法时立即开始的,而不是等到真正需要数据时才进行。这意味着如果你只需要部分数据,那么整个集合都会被遍历,即使只需要其中的一部分。

  5. 缺乏索引访问:IEnumerable接口没有提供直接通过索引访问集合元素的方法。如果你需要随机访问集合中的元素,那么你需要使用其他类型的集合,如数组或List。

28.延迟执行 (Lazy Loading)是什么?

通常与 LINQ(Language Integrated Query)一起使用,实现了查询的延迟执行。

这意味着当你创建一个 IEnumerable 查询时,查询本身不会立即执行,而是会等到需要遍历集合中的元素时才执行。这种机制在某些情况下可能会导致性能问题,尤其是在进行复杂或昂贵的操作时,因为每个元素在迭代时都可能重新计算。

29.LINQ可视化⼯具简单介绍⼀下?

LINQ(Language Integrated Query)是.NET框架中的一种查询技术,它允许开发者使用类似于SQL的语法来查询各种数据源,包括集合、数据库、XML等。

  1. LINQPad:LINQPad是一个免费的开源工具,提供了强大的LINQ查询编辑器和调试器。它支持多种编程语言,包括C#、VB.NET和F#,并且内置了丰富的示例代码库。LINQPad还提供了实时编译和执行的功能,使得开发者能够立即看到查询结果。

  2. SQL Server Data Tools (SSDT):如果你正在使用SQL Server作为数据存储,那么可以使用SQL Server Data Tools来进行LINQ查询的开发和调试。SSDT是一个集成开发环境(IDE),它提供了丰富的功能,包括数据库设计、查询构建、调试等。通过使用SSDT,你可以方便地将LINQ查询与数据库进行交互。

  3. Visual Studio:Visual Studio是微软官方提供的集成开发环境,它也支持LINQ查询的开发和调试。在Visual Studio中,你可以使用C#或VB.NET编写LINQ查询,并利用其强大的调试工具来检查和优化查询性能。

29.LINQ to Object和LINQ to SQL有何区别?

  • LINQ to SQL可以将查询表达式转换为SQL语句,然后在数据库中执⾏。
  • 相⽐LINQ to Object,则是将查 询表达式直接转化为Enumerable的⼀系列⽅法,最终在C#内部执⾏。
  • LINQ to Object的数据源总是实现 IEnumerable(所以不如叫做LINQ to IEnumerable),相对的,LINQ to SQL的数据源总是实现 IQueryable并使⽤Queryable的扩展⽅法。

30.除了EF,列举出你知道的ORM框架?

dapper EntityFramework、 EJB、Hibernate、IBATIS、TopLink、OJB

31.如何如何获取EF⽣成的Sql脚本?

  • 1.可以调试起来通过SqlServerProfiler 来获取Sql
  • 2.EF Dbcontext 注册⽇志事件输出⽇志查看Sql

32.在哪些类型额项⽬中你会选择EF? 为什么?

EF主要是以⾯向对象的思想来做数据库数据操作,对Sql语句能⼒没什么要求,开发使⽤效率⾼!便于上⼿,⼀般来说,使⽤EF框架,肯定会⽐直接使⽤ADO.NET,消耗的时间多⼀ 些。

所以在⼀般企业级开发,管理型系统,对数据性能要求不是特别⾼的情况下,优先选择EF,这样可以 ⼤⼤的推进开发效率!如果像⼀些互联⽹项⽬中,对性能要求精度很⾼!可以另外做技术选型,选择原⽣ ADO.NET。

33.请说明EF中映射实体对象的⼏种状态?

  1. Detached:该实体未由上下⽂跟踪。刚使⽤新运算符或某个 System.Data.Entity.DbSet Create ⽅法创 建实体后,实体就处于此状态。
  2. Unchanged:实体将由上下⽂跟踪并存在于数据库中,其属性值与数据库中的值相同。
  3. Added:实体将由上下⽂跟踪,但是在数据库中还不存在。
  4. Deleted:实体将由上下⽂跟踪并存在于数据库中,但是已被标记为在下次调⽤ SaveChanges 时从数据 库中删除。
  5. Modified:实体将由上下⽂跟踪并存在于数据库中,已修改其中的⼀些或所有属性值。

34.如果实体名称和数据库表名不⼀致,该如何处理?

实体名称和数据库表名称不⼀致:可以通过使⽤TableAttribute 特性;

using System.ComponentModel.DataAnnotations;[Table("数据库表名")]
public class 实体类名
{// 实体属性和方法
}

35. 泛型的优点有哪些?

  • 代码的可重⽤性。
  • ⽆需从基类型继承,⽆需重写成员。
  • 扩展性好。
  • 类型安全性提⾼。
  • 泛型将类型安全的负担从你那⾥转移到编译器。 没有必要编写代码来测试正确的数据类 型,因为它会在编译时强制执⾏。
  • 降低了强制类型转换的必要性和运⾏时错误的可能性。
  • 性能提⾼。
  • 泛型集合类型通常能更好地存储和操作值类型,因为⽆需对值类型进⾏装箱。

36.try {}⾥有⼀个return语句,那么紧跟在这个try后的finally {}⾥的code会不会被执⾏,什么时候被执⾏,在return前还是后?

会执⾏,在return前执⾏。

finally块中的代码会在try块(包括其中的return语句)执行完毕后,但在整个try-catch-finally结构完成并真正返回之前执行。这意味着finally块中的代码会在return语句指定的值被返回给调用者之前执行。

无论try块中的代码是否成功执行,或者是否遇到了return语句、throw异常等,finally块中的代码总是会被执行(除非程序在trycatch块中遇到了导致程序终止的严重错误,如System.Exit调用或操作系统级别的错误)。

37.C# 中的异常类有哪些?

  • C# 异常是使⽤类来表示的,异常类主要是直接或间接地派⽣于 System.Exception 类。
  • System.ApplicationException 和 System.SystemException 类是派⽣于 System.Exception 类的异常 类。
  • System.ApplicationException 类⽀持由应⽤程序⽣成的异常,所以我们⾃⼰定义的异常都应派⽣⾃该 类。
  • System.SystemException 类是所有预定义的系统异常的基类。
  • System.IO.IOException ⽤于处理 I/O 错误(读写⽂件)。
  • System.IndexOutOfRangeException ⽤于处理当⽅法指向超出范围的数组索引时⽣成的错误。
  • System.ArrayTypeMismatchException ⽤于处理当数组类型不匹配时⽣成的错误。
  • System.NullReferenceException ⽤于处理当依从⼀个空对象时⽣成的错误。
  • System.DivideByZeroException ⽤于处理当除以零时⽣成的错误。例如:100/0就会报这个错误。
  • System.InvalidCastException ⽤于处理在类型转换期间⽣成的错误。
  • System.OutOfMemoryException ⽤于处理空闲内存不⾜⽣成的错误。
  • System.StackOverflowException ⽤于处理栈溢出⽣成的错误。

38.泛型有哪些常⻅的约束?

  • 泛型约束 public void GetEntity() where T:class
  • where T :struct //约束T必须为值类型
  • where K : class //约束K必须为引⽤类型
  • where V : IComparable //约束V必须是实现了IComparable接⼝
  • where W : K //要求W必须是K类型,或者K类型的⼦类
  • where X :class ,new () // 或者写出 new class() ; X必须是引⽤类型,并且要有⼀个⽆参的构造函数 (对于⼀个类型有多有约束,中间⽤逗号隔开)

39.Collection和Collections的区别?

  1. Collection:Collection是一个抽象基类,它提供了一组用于操作集合的基本方法,如添加、删除、遍历等。它是各种集合类的基类,例如List<T>、Queue<T>、Stack<T>等。

  2. Collections:Collections是一个静态类,它提供了许多静态方法来操作或返回集合。这些方法主要用于对集合进行排序、查找、同步等操作。例如,可以使用Collections.Sort()方法对列表进行排序,或者使用Collections.BinarySearch()方法在已排序的列表中查找元素。

Collection是一个抽象基类,用于表示一组对象;

Collections是一个实用程序类,提供了一系列静态方法来操作集合。

40.能⽤foreach 遍历访问的对象的要求?

需要实现IEnumerable接⼝声明GetEnumerator⽅法的类型。

41.一些常见的集合类

  1. List:表示一个可变大小的列表,可以包含重复的元素。它提供了添加、删除、插入和访问元素的方法。

  2. ArrayList:类似于List,但它是一个非泛型类,用于存储对象类型的元素。

  3. Queue:表示一个先进先出(FIFO)的数据结构,用于存储和管理元素。它提供了添加元素到队尾、从队头移除元素以及查看队头元素的方法。

  4. Stack:表示一个后进先出(LIFO)的数据结构,用于存储和管理元素。它提供了向栈顶添加元素、从栈顶移除元素以及查看栈顶元素的方法。

  5. HashSet:表示一个不包含重复元素的集合。它提供了添加、删除和检查元素是否存在的方法。

  6. SortedSet:表示一个按排序顺序存储元素的集合。它提供了添加、删除和查找元素的方法,并且元素会按照指定的比较器进行排序。

  7. Dictionary<TKey, TValue>:表示一个键值对的集合,其中每个键都是唯一的。它提供了添加、删除和查找特定键对应的值的方法。

  8. SortedDictionary<TKey, TValue>:表示一个按键排序的键值对集合。它提供了添加、删除和查找键值对的方法,并且键值对会按照指定的比较器进行排序。

  9. LinkedList:表示一个双向链表,可以用于存储和管理元素。它提供了添加、删除和遍历链表的方法。

  10. BitArray:表示一个位数组,可以用于存储和操作位值。它提供了设置、清除和翻转位的方法

42.C#可否对内存进⾏直接的操作?

1.在 Visual Studio 开发环境中设置/unsafe(启⽤不安全模式)编译器选项 打开项⽬的“属性”⻚。 单击“⽣成”属性⻚。 选中“允许不安全代码”复选框

2.unsafe关键字表示不安全上下⽂,该上下⽂是任何涉及指针的操作所必需的。 可以在类型或成员的声明中使⽤ unsafe修饰符。

因此,类型或成员的整个正⽂范围均被视为不安全上下⽂。例如,以下是⽤ unsafe 修饰符声明的⽅法:

unsafe static void FastCopy(byte[] src, byte[] dst, int count)
{
// Unsafe context: can use pointers here.
}

不安全上下⽂的范围从参数列表扩展到⽅法的结尾,因此指针在以下参数列表中也可以使⽤:

unsafe static void FastCopy ( byte* ps, byte* pd, int count )
{...}

还可以使⽤不安全块从⽽能够使⽤该块内的不安全代码。例如:

unsafe
{
// Unsafe context: can use pointers here.
}

若要编译不安全代码,必须指定 /unsafe编译器选项。

⽆法通过公共语⾔运⾏库验证不安全代码。

43.HashMap和Hashtable区别?

数据结构
HashMap和Hashtable都是基于哈希表实现的Map接口的实现类,但是它们采用的哈希算法和数据结构有所不同。

HashMap
HashMap底层采用数组+链表/红黑树的数据结构实现,当哈希冲突发生时,会使用链表或者红黑树来解决冲突。HashMap中有一个负载因子(load factor)的概念,默认情况下负载因子为0.75,如果容量和负载因子的乘积大于元素个数时,就需要进行扩容操作。扩容一般是将原来的HashMap数组翻倍,再重新计算哈希码,将元素插入到新的数组中。

Hashtable
Hashtable底层也采用数组+链表的数据结构进行实现,当哈希冲突发生时,使用链表来解决冲突。与HashMap不同的是,Hashtable在JDK 8及以前没有使用红黑树解决哈希冲突,这导致了其效率相对较低。初始容量为11,负载因子为0.75,每次扩容时容量翻倍再加1。HashTable容量可以为任意整数,最小为1。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 大模型从失败中学习 —— 微调大模型以提升Agent性能
  • 【贪心算法】贪心算法
  • 油耳用什么掏耳朵比较好?可视挖耳勺推荐平价
  • 【linux】 cd命令
  • DMA与AXI DMA ip
  • 【干货分享】Ftrans安全数据交换系统 搭建跨网数据传输通道
  • 工业大模型市场图谱:53个工业大模型全面梳理
  • CSS 笔记 1
  • 利用apache-pdfbox库修改pdf文件模板,进行信息替换
  • 【C++高阶】解锁C++的深层魅力——探索特殊类的奥秘
  • JVM面试真题总结(八)
  • 2024年华为9月4日秋招笔试真题题解
  • pdf文件转图片,base64或保存到本地
  • Linux 离线安装 Docker
  • 网络插件 Cilium 更换 Calico
  • 【挥舞JS】JS实现继承,封装一个extends方法
  • Apache Spark Streaming 使用实例
  • Debian下无root权限使用Python访问Oracle
  • ES学习笔记(12)--Symbol
  • go语言学习初探(一)
  • JavaScript创建对象的四种方式
  • java中具有继承关系的类及其对象初始化顺序
  • Python打包系统简单入门
  • SpringCloud集成分布式事务LCN (一)
  • sublime配置文件
  • 动态魔术使用DBMS_SQL
  • 坑!为什么View.startAnimation不起作用?
  • 前端面试题总结
  • 前端学习笔记之观察者模式
  • 如何选择开源的机器学习框架?
  • 实习面试笔记
  • 使用Swoole加速Laravel(正式环境中)
  • 我的面试准备过程--容器(更新中)
  • 想写好前端,先练好内功
  • linux 淘宝开源监控工具tsar
  • ​LeetCode解法汇总2583. 二叉树中的第 K 大层和
  • #绘制圆心_R语言——绘制一个诚意满满的圆 祝你2021圆圆满满
  • $.ajax中的eval及dataType
  • (1)(1.8) MSP(MultiWii 串行协议)(4.1 版)
  • (10)Linux冯诺依曼结构操作系统的再次理解
  • (2024.6.23)最新版MAVEN的安装和配置教程(超详细)
  • (javaweb)Http协议
  • (python)数据结构---字典
  • (vue)el-checkbox 实现展示区分 label 和 value(展示值与选中获取值需不同)
  • (附源码)计算机毕业设计高校学生选课系统
  • (七)Flink Watermark
  • (四)js前端开发中设计模式之工厂方法模式
  • (五)MySQL的备份及恢复
  • (转)ORM
  • (转载)利用webkit抓取动态网页和链接
  • (转载)微软数据挖掘算法:Microsoft 时序算法(5)
  • ***利用Ms05002溢出找“肉鸡
  • .NET Core 发展历程和版本迭代
  • .NET Micro Framework初体验(二)
  • .NET 中让 Task 支持带超时的异步等待