C#开发常见面试题一

背景

总结一下最近遇见的面试题。

面试题目

1.C#中托管对象和非托管对象的区别?

托管对象和非托管对象是.NET环境中的两种对象处理方式。
托管对象:
托管对象是由.NET的垃圾回收器(GC)管理的对象,它们遵循.NET的垃圾回收机制。
托管资源包括内存、文件句柄、数据库连接等。
在.NET中,大部分的基础数据类型(int, float, double等)、基础数据类型的包装类(Int32, Double等)、字符串(String)、集合(List, Dictionary等)都是托管对象。
非托管对象:
非托管对象是不受.NET的垃圾回收器直接管理的对象,需要手动进行资源的释放。
非托管资源包括指针、文件句柄、数据库连接、网络连接等。
在.NET中,如果需要直接操作内存或者和系统资源打交道,可能需要使用非托管对象,如使用指针操作内存或者调用Windows API。

2.CLR如何进行垃圾回收?如何识别需要回收的对象?

GC垃圾回收:.NET中的垃圾回收是指清理托管堆上不会再被使用的对象内存,并且移动仍在被使用的对象使它们紧靠托管堆的一边。每GGC分三代,执行N次0代的回收,才会执行一次1代的回收,而每执行N次1代的回收,才会执行一次2代的回收。

回收对象:当没有任何引用指向堆中的某个对象实例时,这个对象就被视为不再使用。
在GC执行垃圾回收时,会把引用分为以下两类:
  (1)根引用:往往指那些静态字段的引用,或者存活的局部变量的引用;
  (2)非根引用:指那些不属于根引用的引用,往往是对象实例中的字段。
垃圾回收时,GC从所有仍在被使用的根引用出发遍历所有的对象实例,那些不能被遍历到的对象将被视为不再被使用而进行回收。

3.winform中begininvoke和invoke的区别?

Invoke:
Invoke 方法用于直接在UI线程上同步执行一个委托(Delegate)。
当你调用 Invoke 时,如果当前线程是UI线程,委托会立即执行;如果不是UI线程,Invoke 会等待直到UI线程可用,然后同步执行委托。
由于 Invoke 是同步执行的,所以调用线程会被阻塞,直到委托执行完成。
示例代码:

// 假设 button1 是UI上的控件
this.Invoke(new Action(() => button1.Text = "Clicked"));


BeginInvoke:
BeginInvoke 方法用于异步地在UI线程上执行一个委托。
与 Invoke 不同,BeginInvoke 不会阻塞调用线程。它将委托排队等待UI线程执行,并立即返回。
BeginInvoke 返回一个 IAsyncResult 对象,你可以使用它来检查委托的执行状态或获取委托执行的结果。
示例代码:
 

// 假设 button1 是UI上的控件
IAsyncResult result = this.BeginInvoke(new Action(() => button1.Text = "Clicked"));
// 可以立即继续执行其他任务,而不会阻塞UI线程

4.什么是装箱?什么是拆箱?

装箱:CLR需要做额外的工作把堆栈上的值类型移动到堆上,这个操作就被称为装箱。
拆箱:装箱操作的反操作,把堆中的对象复制到堆栈中,并且返回其值。

5.值类型和引用类型的区别?

其共同点是都继承自System.Object,但最明显的区分标准却是是否继承自System.ValueType(System.ValueType继承自System.Object),也就是说所有继承自System.ValueType的类型是值类型,而其他类型都是引用类型。
值类型在栈上,引用类型在堆上。

6.winform如何处理假死问题?

后台处理:
使用后台线程或任务(例如 Task)来处理数据导入,以避免阻塞UI线程。
异步编程:
使用 async 和 await 关键字来异步执行数据导入操作,这样可以在等待操作完成时释放UI线程。
分批处理:
将大量数据分成小批次处理,每处理完一批数据后,更新UI以反映进度。
进度指示:
在UI上显示进度条或进度信息,让用户知道应用程序正在工作,而不是假死。
使用 BackgroundWorker:
BackgroundWorker 组件可以用来在后台线程上执行操作,并提供进度更新和完成通知。

7.winform如何处理内存泄漏?

1、使用using语句:
使用using语句来确保实现了IDisposable接口的对象在使用完毕后会被及时释放。例如:

using (var resource = new SomeDisposableResource())
{
    // 使用 resource
 } // 在这里资源会被自动释放


2、手动释放资源:
对于自己管理资源的对象,确保在不再需要的时候手动调用其Dispose方法。例如:

SomeDisposableResource resource = new SomeDisposableResource();
// 使用 resource
resource.Dispose(); // 在不再需要的时候手动释放资源


3、避免循环引用:
当两个对象相互引用,而且它们的生命周期没有正确管理时,可能导致内存泄漏。确保在不需要的时候及时解除引用。使用弱引用(WeakReference)可以帮助避免一些循环引用问题。

 

你可能感兴趣的:(C#常见面试题目,c#,面试,wpf,windows,microsoft,后端)