.net面试题及详解

时间:2022-07-03 11:30:23 面试 我要投稿
  • 相关推荐

.net面试题及详解

1.什么是CLR

.net面试题及详解

公共语言运行时(Comman language Runtime),是一个可由多种编程语言使用的“运行时”。CLR的核心功能:程序集加载,异常处理,线程同步,内存管理等可由CLR

的所有语言使用.

2.什么是IL

Intermediate language

中间语言,.net程序在经过编译后就成为IL代码。运行时CLR将IL语言编译成CPU能识别的CRU指令。IL也可以叫做托管代码,IL可以访问CLR所提供的所有功能。

3.什么是JIT,它是如何工作的?

即时编译器,由CLR调用,负责将IL语言编译成本地CPU指令。

工作原理:

当程序被第一次调用的时候,CLR会指向包含在CLR内部定义的特殊函数,这个函数就是JITCompiler。JITComliler负责将IL代码编译成本地指令。

JITCompiler知道实际调用了哪个方法,以及该方法是哪些类型定义的。JITCompiler会在定义该类型的程序集的元数据中查找该方法的IL代码。

并将IL编译成本地CPU指令。编译好的结果被放在一个内存块中,JITCompiler返回CLR为类型定义的内部数据结构。找到被调用方法对应的那条记录,

并修改最初对于JITCompiler的引用。让其指向内存块中被调用方法刚刚编译好的CPU指令地址,最后执行被调用方法的CPU指令。

4.GC是什么,简述一下GC的工作方式?

垃圾回收(garbage collection)

Dot Net的垃圾回收可以分为两个步骤,第一步进行“标记”,垃圾回收器假设所有的对象都是垃圾,然后开始遍历每一个“根”(根包含指向引用类型对象的一个指针,值类型对象永远不会被认为是一个根),如果发现一个根引用了一个对象(非NULL),就对对象进行标记。没有被标记的对象被认为是垃圾。第二个阶段就是“压缩”,其实就是将后面的对象移动到已经成为垃圾的对象位置,使得原来的托管堆更为紧凑。从而释放了托管堆。

GC类中的方法影响何时对对象进行垃圾回收以及何时释放对象所分配的资源。此类中的属性提供以下信息:系统可用内存总量、分配给对象的内存的周期类别(代)。

GC跟踪并回收托管内存中分配的对象。垃圾回收器定期执行垃圾回收以回收分配给没有有效引用的对象的内存。当使用可用内存不能满足内存请求时,垃圾回收会自动进行。或者,应用程序可以使用 Collect 方法强制进行垃圾回收。

垃圾回收由以下步骤组成:

GC搜索托管代码中引用的托管对象。

GC尝试完成没有被引用的对象。

GC释放没有被引用的对象并回收它们的内存。

在回收期间,如果GC在托管代码中找到对某对象的一个或多个引用,则不会释放该对象。然而,GC不识别非托管代码中对对象的引用,因此,除非明确禁止,否则它有可能释放非托管代码中以独占方式使用的对象。KeepAlive 方法提供一种机制,该机制可防止垃圾回收器回收在非托管代码中仍使用的对象。

5.在.NET程序运行过程中,什么是堆,什么是栈?什么情况下会在堆(栈)上分配数据?它们有性能上的区别吗?“结构”对象可能分配在堆上吗?什么情况下会发生,有什么需要注意的?

.NET进程被创建时就会有一个堆随之被创建, 用来保存该进程在运行中需要使用的对象/数据; 当一个线程被创建时, 会有一个栈被创建,用来保存方法调用参数, 局部变量等轻量型数据.

当一个类里面包含一个结构体类型的变量时, 该结构体类型会被分配在堆上.

>泛型的作用是什么?它有什么优势?它对性能有影响吗?它在执行时的行为是什么?.NET BCL中有哪些泛型类型?举例说明平时编程中您定义的泛型类型

泛型的作用是什么?

泛型的作用在于“算法的重用”。(这点其实很好理解,原来的ArrayList只能接受Object,现在通过List可以接受任何类型,也就是说ArrayList的方法都被各个类型重用了。但是Dot Net的泛型有个比较制肘地方,就是你很难对数值类型(值类型)进行算法抽象,因为这牵涉到运算符重载的问题,同时Dot Net的泛型的类型参数也不能约束成一个基元值类型(如int、double、float) 。)

它有什么优势?

第一:源代码保护。(如果你知道C++模板对泛型的实现机制,就会知道C++在编译的时候根据对泛型的调用,自动“内联”了一个实现,这样泛型的内容就暴露了,尔DotNet的实现方式就不同了,泛型类和方法会被编译成IL,在执行的时候由JIT负责将IL变化为指定类型参数的本地代码,从而保护了源代码)

第二:类型安全。(这点是最显而易见的,抛弃了使用ArrayList时各种丑陋的强制类型转换)

第三:更清晰地代码。因为没有了强制类型转换,所以代码自然显得更清晰,但是使用泛型时候带来的<>有时候确实也会让人搞糊涂,幸好泛型方法可以用类型推断或者using语句来进一步简化写法。

第四:更好的性能,因为值类型可以避免装箱和拆箱所带来的损耗(垃圾回收的次数也会减少)。(这点正是泛型神奇的地方,开发历史上抽象能力的上升往往意味着性能的下降,但是泛型却不是!泛型抽象了算法,但是C++和DotNet对泛型的实现能够让性能无损,并且更快。Java的擦除法泛型就没有这种性能上的好处。)

它对性能有影响吗?

对性能有积极的影响,因为值类型可以避免装箱和拆箱所带来的负面影响,避免了垃圾回收,使得性能显著提高。但是对引用类型这种影响就不明显了。但是需要注意的是首次为一个特定数据类型调用方法时,CLR都会为这个方法生成本地代码。这会增大应用程序的工作集大小,从而影响性能。

它在执行时的行为是什么?

使用泛型类型参数的一个方法在进行JIT编译时,CLR获取IL,用指定的类型实参进行替换,然后创建本地代码。需要特别注意的是引用类型是共享代码的,而对值类型就会为每一种生成独立的一份类型代码。但是需要指出的是引用类型的这种代码共享并不会造成封闭类型只执行一次构造函数(就算是静态构造函数也是这样的)。

.NET BCL中有哪些泛型类型?

List、Dictionary、Queue、Stack、SortedList和SortedDictionary、LinkedList等等。

举例说明平时编程中您定义的泛型类型。

泛型的出现会替换原来一部分使用多态的地方从而提高性能和带来更好的编译时检查,这样就不需要在子类和超类(接口)间频繁转换了。比如你要根据情况打出各种报表,那么先把报表类定义成泛型类从而可以共享报表一系列的算法。

> 异常的作用是什么?.NET BCL中有哪些常见的异常?在代码中您是如何捕获/处理异常的?在“catch (ex)”中,“throw”和“throw ex”有什么区别?您会如何设计异常的结构,什么情况下您会抛出异常?

异常的作用是什么?

异常用于处理系统级或者应用程序级的错误状态。这就会引发另外几个问题,异常相比原来使用的返回错误代码的优点在哪里?异常处理是一种结构化的处理过程,个人认为他最大的优点就在于将“成功场景”剥离出来,使得代码更加清晰自然。但是异常处理相对于返回错误码有一个缺点,那就是他会失去发生异常的位置。不过异常本身提供了很多帮助调试问题的工具,一般都带有栈跟踪,这样位置的问题就得到一定程度的解决。还有就是IF和异常之间的选择,我记得以前有人讨论过在各种分支下是使用异常来处理各种“失败场景”的分支还是使用IF或者SWITCH来处理呢?这其实是一个假问题,因为异常和错误是有概念上的不同的,这里的错误是指有违“主成功场景”的“异常场景”,尔异常是指当程序不能完成其名字所表示功能时的错误。所以需要强调不要使用异常来区分各种失败场景,异常压根就不是用来干这件事情的!

.NET BCL中有哪些常见的异常?

随便说几个,最著名的恐怕就是那句像绕口令一样的“未将对象引用设置到对象实例”了,还有那些基本一出现整个应用程序就被判死刑的“堆栈溢出”、“内存无法分配”异常了。

在代码中您是如何捕获/处理异常的?

这道题的回答可以体现你是什么“级别”的程序员,这个级别倒不是说水平的高低,是指经常写哪一类的程序,如果对异常的捕获比较“激进”(经常捕获异常)那么这个人应该是一个应用级的程序员。如果对捕获异常比较谨慎那么应该是框架级别的程序员,这些人经常写给别人使用的代码,如果无故的使用异常处理来越俎代庖,那后果很严重了,这里说一个我经历的事,刚毕业的时候我和同事做一个WEB的项目,项目里用第三方的Grid,那个Grid在发生异常的时候会自己报一个错误,你知道我们有多傻眼了吧,我们需要的是我们来抓住异常,然后报出一句对用户友好的错误,但是那个控件却干了这么个蠢事。

我觉得普通程序员用的最多的CATCH就是抓住数据的异常,然后回滚数据库来事务处理。这是一个典型的场景,因为你明确并且能够很好的恢复状态。

在“catch (ex)”中,“throw”和“throw ex”有什么区别?

throw 重新抛出异常但是不破坏异常发生的调用栈尔“throw ex”会重置调用栈这样捕获异常的人会以为代码出错在这里。

您会如何设计异常的结构,什么情况下您会抛出异常?

首先我会尽量的使用系统定义的那些异常,如果我需要处理某一特定类别的异常,而且处理方式和通常处理方式不同那么就考虑自定义异常,还有如果需要调用方用一种统一的方式来处理异常那么自定义异常就是一个好的选择。结构的话当然基类是Sysytem.Exception,尽量使用扁平化异常的层次。可以考虑用泛型类来定义异常。

我写的代码不能完成名字所说明的功能,那么我就会抛出异常。

> List和T[]的区别是什么,平时你如何进行选择?Dictionary是做什么的?.NET BCL中还有哪些常用的容器?它们分别是如何实现的(哪种数据结构)?分别是适用于哪些场景?

List和T[]的区别明显有本质的区别,List 是动态分配内存的链表,

【.net面试题及详解】相关文章:

2011最新asp.net面试题与答案07-11

资深HR详解面试题的潜台词07-13

关于一道.NET程序员面试题的遐想07-13

WAP网络与NET网络的区别于定义!07-10

京东为什么在用.net07-11

面试题07-13

《济南的秋天》详解07-04

除夕的由来详解07-04

房屋保险详解07-13

牛轧糖的做法详解08-04