C#开发常见面试题二(多线程)

背景

如果面试上位机岗位,多线程被考察的频率很高。

面试题

1.并发并行的区别?异步同步的区别?

并发单核处理器能够同时执行个线程,同一时间只能执行一个,其他线程挂起,通过时间片分配实现。
并行:指两个或更多事件或活动在同一时刻发生,通常与多核处理器相关。
同步:任务需依次执行,等待当前任务完成才能执行下一个。
异步:任务之间不相互等待,可以同时执行多个任务。

2. 什么时间用多线程?什么时间用异步编程?

多线程适用于IO密集型应用,如网络请求、文件操作等。
异步编程适用于计算密集型应用,如视频处理、科学计算等。

3.线程是如何工作的?

线程在内部由一个线程调度器(thread scheduler)管理,一般CLR会把这个任务交给操作系统完成。
单核处理器使用时间切片。多核处理器则是时间切片和并发混合使用。

4.举例说明多线程使用场景?缺点?

使用场景
维持用户界面的响应
有效利用 CPU
并行计算
推测执行(speculative execution)
允许同时处理请求

缺点:程序的复杂度
缺点处理:多线程逻辑使用可重用的类封装,以便于独立的检验和测试。

5.如果程序依赖finally(或是using)块来执行清理工作,例如释放资源或是删除临时文件,就可能会产生问题。如何处理?

如果是自己创建的线程,在线程上调用Join方法。
如果是使用线程池线程,使用事件等待句柄。

6.如何调用线程池?常见的线程池对象?

通过任务并行库(TPL)(Framework 4.0 中加入)
调用ThreadPool.QueueUserWorkItem
通过异步委托
通过BackgroundWorker

常见对象

WCF、Remoting、ASP.NET 和 ASMX 网络服务应用
System.Timers.Timer 和 System.Threading.Timer
.NET Framework 中名字以Async结尾的方法,例如WebClient上的方法,和大部分BeginXXX方法(异步编程模型模式,APM)
PLINQ

7. 最小线程池数量如何起作用?为何延迟创建线程?

需要时,立刻创建最小线程数量的线程,线程数<=min时,增量创建线程。通常min默认处理器数目。
延迟创建原因:了防止短生命周期的任务导致线程数量短暂高峰

8.C#中排他锁有哪些?区别?

lock(locker); Monitor.Enter/Monitor.Exit/Monitor.TryEnter;/Mutex(互斥体)
Mutex可以跨线程使用

9.任务并行(task parallelism)的作用?

调节任务调度
在一个任务中启动另一个任务时建立其父子关系
实现协作取消
等待一组任务,而无需使用信号构造
附加“延续”任务
基于多个前项任务调度延续任务
传递异常给父任务、延续任务和任务的使用方

10.WaitAll和WaitAny的区别?WaitAll和分别等待有什么区别?

WaitAll等待所有任务完成;
WaitAny等待任意任务完成;

WaitAll只会切换一次上下文;

11.Task如何实现取消任务?

CancellationTokenSource定义了Cancel方法。
CancellationToken定义了IsCancellationRequested属性和ThrowIfCancellationRequested方法。

CancellationToken是一个结构体,但是你可以把它当作类来看待。引用原始的CancellationTokenSource。
CancellationToken结构体提供了其它两个有用的成员。
第一个是WaitHandle,返回一个等待句柄,在取消时会对它发信号。
第二个是Register,使你可以注册一个在取消时调用的委托。

CancellationTokenSource定义了Cancel方法
它可以调度一个委托到线程池线程上运行。
它提供了管理工作项的丰富功能(延续、子任务、异常封送等等)。

public class TaskCompletionSource
{
  public void SetResult (TResult result);
  public void SetException (Exception exception);
  public void SetCanceled();

  public bool TrySetResult (TResult result);
  public bool TrySetException (Exception exception);
  public bool TrySetCanceled();
  // ...
}

12.C#中async、await关键字

异步方法:用async关键字修饰的方法。
await不会阻塞主线程,await后的主线程代码依然会执行。
异步方法的返回值一般是Task,T是真正的返回值类型,Task。惯例:异步方法的名字以Async结尾;
即使方法没有返回值,也最好把返回值声明为非泛型的Task;
调用泛型方法时,一般在方法前加上await关键字,这样拿到的返回值就是泛型指定的T类型;
异步方法的”传染性“:一个方法如果await调用,则这个方法也必须修改为async;
如果一个方法是异步方法,那么一般在调用这个方法的时候在方法前加await关键字;

13.async方法的缺点?

异步方法会生成一个类,运行效率没有普通方法高;
可能会占用非常多的线程;
用async和await配合来调用普通方法(推荐此方式,运行效率高)

异步暂停的情况
Thread.Sleep()方法,因为它会阻塞调用线程,而要用await Task.Delay()

14.yield return和return的区别?

return:立刻返回

yield return
适用lazy loading
定义一个迭代器块。它允许逐个产生序列的元素,而不是一次性产生整个集合。
当一个方法中包含yield return时,这个方法必须返回一个实现了IEnumerable、IEnumerator或IAsyncEnumerable的类型(取决于是否使用异步迭代器)

yield return 的优势在于,如果GetStrings 方法中的字符串是通过某种计算或I/O操作(如文件读取)获得的,
那么使用yield return可以减少内存占用并提高效率。普通的return则需要一次性创建和返回整个集合。

你可能感兴趣的:(C#常见面试题目,c#,开发语言,面试,wpf,microsoft,.net)