一些C#面试题(无聊之举)

既然无聊,又不能浪费时间,那就做点无聊的事情打发时间: 

1.Thread和Process之间有什么区别?.NET新引入了Application Domain的概念,这样他们三个之间有什么区别?引入了Application Domain会带来一些潜在的问题么?  
  进程是程序的组织形式,线程是系统调度的基本单元,一个进程至少包含一个以上的线程,线程存在于进程内;
  应用程序域是为了像IIS这类程序提供的一种进程内隔离方法,便于在一个进程内运行多个应用。进程>应用程序域>线程.对于像IIS这样的应用程序而言,
它可以运行多个应用程序,如果一个应用崩溃,整个程序都崩溃是有问题的,所以引入应用程序域就起到了这种隔离效果.在运行时上述关系成立,但由于应用程序域是逻辑的,因此具体一线程代码是在哪个应用程序域里执行,需要根据调用来决定的。
2.Windows Service与普通的EXE在执行过程中有什么区别?  
  最大的不同在于启动和控制。前者是由操作系统的服务管理程序来完成,后者由用户来完成.
3.一个进程可以访问的Windows地址空间有多大?等于系统的虚拟内存大小么?这两方面将对系统的设计产生什么样的影响?  
  理论上是2机器位数方(32位就是2^32,但实际要排除操作系统掌控的部分),当然不等于系统虚拟内存大小,虚拟内存可以远远大于
进程地址空间大小。因为多个虚拟内存页可以调度到一个实际内存页中。影响就是需要对内存进行页式调
度管理,需要内存页提高命中率等。
4.EXE和DLL之间的区别是什么?在系统设计中应该如何选择使用它们?
  Exe是直接允许的,dll是可以共享的执行代码。  
5.普通的EXE与.NET EXE的执行过程有什么不同?
  普通的exe是机器代码,直接由操作系统调度执行;.net exe是一种中间语言代码,由框架来及时编译和执行。  
6.什么是弱类型,什么是强类型?在系统设计中应该首先考虑使用哪种类型?
  弱类型就是变量的具体类型由存储的东西来决定,强类型就是变量的类型提前就声明好,用的过程中也只能存当初
指定定类型的数据。弱类型的代表有vb,javascript等。强类型语言就多了.系统设计当然首先考虑强类型,因为可以
让编译器帮你进行一定的逻辑检查。  
7.PDB文件是作什么用的?里面包含了什么信息?
  主要提供给调式器调式用,保存的都是些调试用信息。但具体包含什么从没去看过.  
8.Cycloramic Complexity是什么?为什么它很重要?  
  圈复杂度,衡量代码逻辑的复杂程度,实践中没整个这个玩意.
9.为创建一个critical section以访问某个变量书写一个标准的lock() 并加上double check。
  这个经常搞,主要是用于多线程并发。加双检查是为了更线程安全。代码上面有人给了.  
10.为某个对象实现标准的Dispose模式。  
  实现IDispose接口就可以.
11.什么是FullTrust? 存在于GAC中的 assembly 拥有FullTrust么?
  这个完全信任是对程序的,不是针对操作系统的吧,其它的不懂。  
12.下面这个命令是做什么的?gacutil /l | find /i “system”  
  没用过,一般很少整全局程序集.
13.下面这个命令是作什么的? sn -t something.dll
  产生强类型程序集的密钥对.  
14.跨防火墙的 DCOM必须打开哪个端口?端口135是用来做什么的?
  135是远程过程调用端口.DCOM要打开那些端口需要google.  
15.有什么办法可以与现有unmanaged code集成?在集成的时候应该考虑什么问题?
  加一个unsafe标签就可以,考虑的问题主要是垃圾回收和资源释放.  
16.简要解释一下OOP与SOA都是用来作什么的?  
  面向对象和面向服务,都是看问题的方法,OOP处于较低层次,SOA处于较高层次。OOP是一种编程底层技术,面向服务更
多的是一种功能组织方式.

17.XmlSerializer是如何工作的?进程运行XmlSerializer时候需要什么样的ACL权限?
  利用反射机制和元数据来进行。需要能访问数据集元数据的
权限,同时如果是反序列化,需要实例化类型的权限。  
18.在系统设计时,何时应该使用try catch?何时需要避免使用?
  如果代码执行可能发生异常就需要,如果你能确保代码执行不会产生异常就没必要。但不要为
了数据合法性之类检查做try catch.这样可以提高性能.  
19.Debug.Write()和Trace.Write()之间有什么区别?二者分别应该用于何处?
  两者都很少用。前面有人解释过.  
20.Debug Build和Release Build有什么区别?在执行效率上有什么明显的区别么?
  区别就是生成的代码一个包含调试信息,一个不饱含调式信息,前者效率肯定比后面差.  
21.JIT是针对Assembly还是Method发生的?解释一下为什么.NET的设计者要这样做? 
  感觉应该是针对方法,因为这样效率高,程序集比较大,不是所有的东西都会用到。
  大家可以google一下. 
22.简要描述一下GC的执行过程。
  google到处。  
23.应该如何选择使用abstract class还是interface?  
  基于分类学用abstract,给予契约或者标准用interface.Is用abstract,Has用interface.
24.在设计一个自定义类型时应如何选择使用Value Type还是Reference Type?
  看效率。小数据量用值类型,数据量大用reference.  
25.对于Value Type和Reference Type,a.Equals(b)的默认实现方式有什么不同?
  前者比较值,后者仅比较引用地址是否相同,而不是比较值.string比较特殊,是比较值.  
26..NET中为什么不提供默认的deep copy?如果需要,要如何实现deep copy?  
  因为深度复制很容易出现复制循环。如果需要可以自己实现克隆接口.
27.相对于.NET 1.1,.NET2.0为了避免过度的boxing/unboxing造成的系统开销提供了哪些支持?
  真不知道.  
28.String是Value Type还是Reference Type?为什么.NET中的String对象被设置成immutable?  
  string是引用类型,但很多行为却是值类型的。String变量的值一旦赋值,是不会改变的,
就是为了保证其行为与值类型一样.

============贴一点别人的货,这个对string研究比较细=========

(1)string是引用类型:
string是引用类型,这就是说string在堆上保存数据,而在栈中存储的是对象地址,在理解string类型特性时首先需要记住这点。只不过与其它一些引用类型相比,它又有一些比较特殊的特性,比如下面的这些:
 
(2)string是不可变的(immutable):
string的这一特性是指,对于已有的一个string对象,当你修改它时,实际是重新创建了一个符合你要求的string对象。我通过以下的例子进行演示:
staticvoid Main(string[] args)
{
    string x = "should it matter";
    x = x + " ?"//breakpoint (1)
}//breakpoint (2)

F5运行至breakpoint (1)处,在即时窗口中执行以下sos调试命令(关于sos调试扩展,可以参见《VS 2005中Sos调试扩展简介》):
 
!load sos.dll
extension C:"WINDOWS"Microsoft.NET"Framework"v2.0.50727"sos.dll loaded
!clrstack -a
PDB symbol for mscorwks.dll not loaded
OS Thread Id: 0x1508 (5384)
ESP       EIP    
0012f440 012f009f ConsoleApplication1.Program.Main(System.String[])
    PARAMETERS:
        args = 0x0137cdc8
    LOCALS:
        <CLR reg> = 0x0137cdd8
0012f69c 79e7c74b [GCFrame: 0012f69c]
 
F5运行至breakpoint (2)处,重新执行clrstack命令,结果如下。可清楚看到对象x内存中的地址发生了变化,由原来的0x0137cdd8变成0x0137ce24
 
!clrstack -a
OS Thread Id: 0x1508 (5384)
ESP       EIP    
0012f440 012f00b0 ConsoleApplication1.Program.Main(System.String[])
    PARAMETERS:
        args = 0x0137cdc8
    LOCALS:
        <CLR reg> = 0x0137ce24
0012f69c 79e7c74b [GCFrame: 0012f69c]

(3)string判等:
对于string类型来说,其equals()方法与“==”操作符起到的效果都是一样的,这点可以从“==”操作的反编译代码中可以看出来:
public static bool operator ==(string a, string b)
{
    return Equals(a, b);
}
跟其它引用类型一样,如果你需要判断两个字符串变量的是否引用相等(即指向托管堆上的同一地址),可以使用object.ReferenceEquals()方法。
 
(4)string留用:
staticvoid Main(string[] args)
{
    string x = "should it matter";
    string y = "should it matter";
    if (object.ReferenceEquals(x, y))
    {
        Console.WriteLine("same reference.");
    }
    Console.Read();
}
程序运行的结果是输出了“same reference.”,照理说我声明两个string变量,它们不应该指向相同的托管堆地址啊?!事实上这里涉及到一个所谓的“字符串留用”机制,根据Jeffrey Richter在《框架设计CLR via C#》中所说,CLR存在一种机制,当它初始化时,它会创建一个内部哈希表,此表中key是字符串,value是对托管堆中的string对象的引用。当定义一个string时,就会在内部哈希表中检查是否有相匹配的。如果不存在完全相同的字符串,就创建字符串副本,将字符串副本添加到内部哈希表中,并返回这个副本的引用。如果存在完全相同的字符串,就返回对现有字符串的引用。
事实上,我认为该机制有通常情况下有害无益:(1)以上述程序为例,它会导致字符串比较(判等),以便确定是否已存在相同的字符串;(2)它会造成开发人员的一种混乱感觉,因为按照正常逻辑,上述程序中的两个对象不应该是引用相等。可惜在.net framework 2.0及以上版本中,该机制是默认工作的。
关于字符串的留用机制,详细可以看Jeffrey Richter的《框架设计:CLR via C#》,包括其中对string.intern()方法的描述

===========****************************=====

装箱拆箱,可以去看看这篇文章http://www.cnblogs.com/huashanlin/archive/2007/05/16/749359.html

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值