C#面试试题.docx
- 文档编号:11562797
- 上传时间:2023-03-19
- 格式:DOCX
- 页数:18
- 大小:33.84KB
C#面试试题.docx
《C#面试试题.docx》由会员分享,可在线阅读,更多相关《C#面试试题.docx(18页珍藏版)》请在冰豆网上搜索。
C#面试试题
C#面试题
1.C#中property与attribute的区别,他们各有什么用处,这种机制的好处在哪里?
property和attribute汉语都称之为属性。
不过property是指类向外提供的数据区域。
而attribute则是描述对象在编译时或运行时属性的。
这两者是有本质区别的,attribute:
自定义属性的基类;property:
类中的属性
2.讲一讲你理解的webservice,在dotnetframework中,怎么很好的结合xml?
参考答案:
WebService主要是为了使原来各孤立的站点之间的信息能够相互通信、共享而提出的一种接口。
WebService所使用的是Internet上统一、开放的标准,如HTTP、XML、SOAP(简单对象访问协议)、WSDL等,所以WebService可以在任何支持这些标准的环境(Windows,Linux)中使用。
因为webservice的数据传输基本是基于xml,而我们在dotnetframework可以很方便的来进行各种数据的xml转化。
比如,我们常用的dataset可以直接转为xml格式,而且其它的大部分来都可以进行XML序列化,因此,我们在设计自定义类的时候,可以同时标明它的xml序列化方法。
另外,dotnetframework提供了大量的xml处理类库,使得我们对xml的处理非常简单。
点评:
这个试题主要考察面试者对web服务和xml的理解,因为这些都是最近几年非常热门的技术,面试者应该多了解相关的知识。
3.C#,Java和c++的特点,有什么相同的地方,不同的地方,C#分别从c++和java中吸取了他们那些优点?
C#,Java和c++的特点,有什么相同的地方,不同的地方,C#分别从c++和java中吸取了他们那些优点
C#看起来与Java有着惊人的相似;它包括了诸如单一继承,界面,与Java几乎同样的语法,和编译成中间代码再运行的过程.但是C#与Java有着明显的不同,它借鉴了Delphi的一个特点,与COM(组件对象模型)是直接集成。
微软c#语言定义主要是从C和C++继承而来的,而且语言中的许多元素也反映了这一点.C#在设计者从C++继承的可选选项方面比Java要广泛一些(比如说structs),它还增加了自己新的特点(比方说源代码版本定义).
C#从Java继承而来的特点
类:
在C#中类的申明与Java很相似。
特点看起来与Java相比没有变化.布尔运算:
条件表达式的结果是布尔数据类型,布尔数据类型是这种语言中独立的一种数据类型.从布尔类型到其他类型没有直接的转换过程.布尔常量true和false是C#中的关键字.错误处理:
如Java中那样,通过抛出和捕捉异常对象来管理错误处理过程.内存管理:
由底层.NET框架进行自动内存垃圾回收.
C#从C和C++继承的特点
编译:
程序直接编译成标准的二进制可执行形式.
结构体:
一个C#的结构体与C++的结构体是相似的,因为它能够包含数据申明和方法.但是,不象C++,C#结构体与类是不同的而且不支持继承.但是,与Java相同的是,一个结构体可以实现界面.
预编译:
C#中存在预编译指令支持条件编译,警告,错误报告和编译行控制.#error
C#独有的特点
中间代码:
微软在用户选择何时MSIL应该编译成机器码的时候是留了很大的余地.微软公司很小心的声称MSIL不是解释性的,而是被编译成了机器码.它也明白许多--如果不是大多数的话--程序员认为Java程序要不可避免的比C编写的任何东西都要慢.而这种实现方式决定了基于MSIL的程序(指的是用C#,VisualBasic,"ManagedC++"--C++的一个符合CLS的版本--等语言编写的程序)将在性能上超过"解释性的"Java代码.当然,这一点还需要得到事实证明,因为C#和其他生成MSIL的编译器还没有发布.但是JavaJIT编译器的普遍存在使得Java和C#在性能上相对相同.象"C#是编译语言而Java是解释性的,"之类的声明只是商业技巧.Java的中间代码和MSIL都是中间的汇编形式的语言,它们在运行时或其它的时候被编译成机器代码.
命名空间中的申明:
当你创建一个程序的时候,你在一个命名空间里创建了一个或多个类.同在这个命名空间里(在类的外面)你还有可能声明界面,枚举类型和结构体.必须使用using关键字来引用其他命名空间的内容.
基本的数据类型:
C#拥有比C,C++或者Java更广泛的数据类型.这些类型是bool,byte,ubyte,short,ushort,int,uint,long,ulong,float,double,和decimal.象Java一样,所有这些类型都有一个固定的大小.又象C和C++一样,每个数据类型都有有符号和无符号两种类型.与Java相同的是,一个字符变量包含的是一个16位的Unicode字符.C#新的数据类型是decimal数据类型,对于货币数据,它能存放28位10进制数字.
两个基本类:
一个名叫object的类是所有其他类的基类.而一个名叫string的类也象object一样是这个语言的一部分.作为语言的一部分存在意味着编译器有可能使用它--无论何时你在程序中写入一句带引号的字符串,编译器会创建一个string对象来保存它.
参数传递:
方法可以被声明接受可变数目的参数.缺省的参数传递方法是对基本数据类型进行值传递.ref关键字可以用来强迫一个变量通过引用传递,这使得一个变量可以接受一个返回值.out关键字也能声明引用传递过程,与ref不同的地方是,它指明这个参数并不需要初始值.
与COM的集成:
C#对Windows程序最大的卖点可能就是它与COM的无缝集成了,COM就是微软的Win32组件技术.实际上,最终有可能在任何.NET语言里编写COM客户和服务器端.C#编写的类可以子类化一个以存在的COM组件;生成的类也能被作为一个COM组件使用,然后又能使用,比方说,JScript语言子类化它从而得到第三个COM组件.这种现象的结果是导致了一个运行环境的产生,在这个环境里的组件是网络服务,可用用任何.NET语言子类化.
索引下标:
一个索引与属性除了不使用属性名来引用类成员而是用一个方括号中的数字来匿名引用(就象用数组下标一样)以外是相似的.
代理和反馈:
一个代理对象包括了访问一个特定对象的特定方法所需的信息.只要把它当成一个聪明的方法指针就行了.代理对象可以被移动到另一个地方,然后可以通过访问它来对已存在的方法进行类型安全的调用.一个反馈方法是代理的特例.event关键字用在将在事件发生的时候被当成代理调用的方法声明中.
(本答案参考了cnblog上的一篇文章)
点评:
了解C#和java,c++的关系,可以让我们更好的了解c#的特点,这些也是考察面试者知识范围广度的一个很重要的方面。
4.C#可否对内存进行直接的操作?
(这可是个难点哦?
要注意!
)
可以。
但是为了保持类型安全,默认情况下,C#不支持指针运算。
不过,通过使用unsafe关键字,可以定义可使用指针的不安全上下文。
在不安全的上下文中,类型可以是指针类型以及值类型或引用类型。
指针类型声明具有下列形式之一:
unmanagedtype*identifier;
void*identifier;
参数说明:
unmanagedtype
下列类型之一:
sbyte、byte、short、ushort、int、uint、long、ulong、char、float、double、decimal或bool。
任何枚举类型。
任何指针类型。
仅包含非托管类型的字段的任何用户定义的结构类型。
identifier
指针变量名称。
备注
指针类型不继承object,并且指针类型与object之间不存在转换。
此外,装箱和取消装箱不支持指针。
但是,允许在不同指针类型之间以及指针类型与整型之间进行转换。
当在同一个声明中声明多个指针时,*仅与基础类型一起使用,而不是作为每个指针名称的前缀。
例如:
int*p1,p2,p3; //Ok
int*p1,*p2,*p3; //InvalidinC#
指针不能指向引用或包含引用的结构,因为垃圾回收器不知道关于指针的任何信息,但知道关于引用的信息。
myType*类型的指针变量的值是myType类型的变量的地址。
下面是指针类型声明的示例:
示例 说明
int*p p是指向整数的指针
int**p p是指向整数的指针的指针
int*[]p p是指向整数的指针的一维数组
char*p p是指向字符的指针
void*p p是指向未知类型的指针
点评:
因为C#为了提高安全型,默认是运行在托管代码下的,在我们正常的企业mis开发中很少会有用到非托管代码的情况,致使大部分c#初学者误以为C#不能直接操作内存。
当然,面试时很少会有人问起这个,这个我们只需要做简单的了解就可以了,如果不是开发的需要,没有必要深究。
5.用VisualC++6.0编写的代码(unmanagedcode),如何在CLR下和其他dotnetcomponent结合?
参考答案:
利用平台调用服务,托管代码可以调用在动态链接库(DLL)(如Win32API中的DLL)中实现的非托管函数。
此服务将查找并调用导出的函数,然后根据需要跨越互用边界封送其参数(整数、字符串、数组、结构等)。
示例如下:
usingSystem.Runtime.InteropServices;
publicclassWin32{
[DllImport("user32.dll",CharSet=CharSet.Auto)]
publicstaticexternintMessageBox(inthWnd,Stringtext,
Stringcaption,uinttype);
}
publicclassHelloWorld{
publicstaticvoidMain(){
Win32.MessageBox(0,"HelloWorld","PlatformInvokeSample",0);
}
}
点评:
这种用法主要使用在需要我们调用windowsAPI的编程中,因为windosapi封装了很多常用的系统方法,而这些方法很有可能在dotnetframework中直接提供,为了减少开发时间,我们需要这种调用。
6.以前作过的一些项目?
介绍一下自己的编程经验。
(这是蒙混不过去的,基本一问就知道是真是假)
7.你对公司有什么期望?
你的薪水期望值?
为什么学计算机?
以前的工作经验(这非常重要)?
Q3:
维护数据库的完整性、一致性、你喜欢用触发器还是自写业务逻辑?
为什么
Q4:
ADO。
NET相对于ADO等主要有什么改进?
参考答案:
数据的内存中表示形式
在ADO中,数据的内存中表示形式为记录集。
在ADO.NET中,它为数据集。
它们之间有重要的差异。
表的个数
记录集看起来像单个表。
如果记录集将包含来自多个数据库表的数据,则它必须使用JOIN查询,将来自各个数据库表的数据组合到单个结果表中。
相反,数据集是一个或多个表的集合。
数据集内的表称为数据表;明确地说,它们是DataTable对象。
如果数据集包含来自多个数据库表的数据,它通常将包含多个DataTable对象。
即,每个DataTable对象通常对应于单个数据库表或视图。
这样,数据集可以模仿基础数据库的结构。
数据集通常还包含关系。
数据集内的关系类似于数据库中的外键关系,即它使多个表中的行彼此关联。
例如,如果数据集包含一个有关投资者的表和另一个有关每个投资者的股票购买情况的表,则数据集可能还包含一个关系来连接投资者表的各个行和购买表的对应行。
由于数据集可以保存多个独立的表并维护有关表之间关系的信息,因此它可以保存比记录集丰富得多的数据结构,包括自关联的表和具有多对多关系的表。
数据导航和游标
在ADO中,您使用ADOMoveNext方法顺序扫描记录集的行。
在ADO.NET中,行表示为集合,因此您可以像依次通过任何集合那样依次通过表,或通过序号索引或主键索引访问特定行。
DataRelation对象维护有关主记录和详细资料记录的信息,并提供方法使您可以获取与正在操作的记录相关的记录。
例如,从Investor表的“NateSun”的行开始,可以定位到Purchase表中描述其购买情况的那组行。
将打开连接的时间降至最低
在ADO.NET中,打开连接的时间仅足够执行数据库操作,例如“选择”(Select)或“更新”(Update)。
您可以将行读入数据集中,然后在不保持与数据源的连接的情况下使用它们。
在ADO中,记录集可以提供不连接的访问,但ADO主要是为连接的访问设计的。
ADO和ADO.NET中的不连接处理之间存在一个显著差异。
在ADO中,通过调用OLEDB提供程序来与数据库通信。
ADO.NET中通过TableAdapter或数据适配器(如SqlDataAdapter)与数据库通信,这会调用OLEDB提供程序或基础数据源提供的API。
ADO和ADO.NET之间的主要区别在于:
在ADO.NET中,适配器允许您控制将对数据集所做的更改传输到数据库的方式,方法是实现性能优化、执行数据验证检查或添加其他任何额外处理。
在应用程序间共享数据
在应用程序间传输ADO.NET数据集比传输ADO不连接的记录集要容易得多。
若要将ADO不连接的记录集从一个组件传输到另一个组件,请使用COM封送。
若要在ADO.NET中传输数据,请使用数据集,它可以传输XML流。
相对于COM封送,XML文件的传输提供以下便利之处:
更丰富的数据类型
COM封送处理提供一组有限的数据类型(由COM标准定义的那些类型)。
由于ADO.NET中的数据集传输基于XML格式,所以对数据类型没有限制。
因此,共享数据集的组件可以使用这些组件一般会使用的任何丰富的数据类型集。
性能
传输大型ADO记录集或大型ADO.NET数据集会使用网络资源;随着数据量的增长,施加于网络的压力也在增加。
ADO和ADO.NET都使您可以最大限度地降低所传输的数据。
但ADO.NET还提供另一个性能优势:
ADO.NET不需要数据类型转换。
而需要COM封送来在组件间传输记录集的ADO,则需要将ADO数据类型转换为COM数据类型。
穿透防火墙
防火墙可以影响试图传输不连接的ADO记录集的两个组件。
请记住,防火墙通常配置为允许HTML文本通过,但防止系统级请求(如COM封送)通过。
因为组件使用XML交换ADO.NET数据库,所以防火墙可以允许数据集通过
点评:
从ado升级到,是微软数据处理技术的一个飞跃,而了解它们之间的区别,可以让我们更好的掌握特点。
Q5:
ASP。
NET与ASP相比,主要有哪些进步?
参考答案:
执行效率的大幅提高
ASP以源码形式存放,以解释方式运行,每次ASP网页调用都需要对源码进行解释,运行效率不高. ASP.net是把基于通用语言的程序在服务器上运行。
不像以前的ASP即时解释程序,而是将程序在服务器端首次运行时进行编译,这样的执行效果,当然比一条一条的解释强很多.
强大的开发工具支持
ASP.net可以使用VSStudio系列的强大的开发工具,只是所见即所得的开发支持。
可扩充的适应性
A可以完美支持windows平台,也可以通过mono来支持linux的平台。
而且,asp.Net是语言独立的,也就是说不但可以用C#编写相关的代码,你也可以使用vb,jscript等语言来编写。
多处理器环境的可靠性
ASP.net已经被刻意设计成为一种可以用于多处理器的开发工具,它在多处理器的环境下用特殊的无缝连接技术,将很大的提高运行速度。
即使你现在的ASP.net应用软件是为一个处理器开发的,将来多处理器运行时不需要任何改变都能提高他们的效能,但现在的ASP确做不到这一点。
安全型
AspNet内置了强大的安全型管理机制,相对asp,安全型得到了很大的提高。
点评:
和asp相比,确实有了很大的飞跃,特别是这种代码分类的方式,给编程人员带来了很大的方便,了解的进步,可以让我们更有信心学习asp。
net.。
Q6:
C#中的委托是什么?
事件是不是一种委托?
参考答案:
委托是一种安全地封装方法的类型,它与C和C++中的函数指针类似。
与C中的函数指针不同,委托是面向对象的、类型安全的和保险的。
委托的类型由委托的名称定义。
下面的示例声明了一个名为Del的委托,该委托可以封装一个采用字符串作为参数并返回void的方法。
publicdelegatevoidDel(stringmessage);
委托具有以下特点:
委托类似于C++函数指针,但它是类型安全的。
委托允许将方法作为参数进行传递。
委托可用于定义回调方法。
委托可以链接在一起;例如,可以对一个事件调用多个方法。
方法不需要与委托签名精确匹配。
有关更多信息,请参见协变和逆变。
C#2.0版引入了匿名方法的概念,此类方法允许将代码块作为参数传递,以代替单独定义的方法.
事件显然不是一种委托,事件是类在发生其关注的事情时用来提供通知的一种方式。
例如,封装用户界面控件的类可以定义一个在用户单击该控件时发生的事件。
控件类不关心单击按钮时发生了什么,但它需要告知派生类单击事件已发生。
然后,派生类可选择如何响应。
事件使用委托来为触发时将调用的方法提供类型安全的封装
点评:
委托和事件有很紧密的关系,但两者是不同的。
熟练掌握委托的定义和用法,对于我们在制作自定义控件等需要抛出自定义事件的地方很有好处。
委托是C#中一个非常重要的概念,一定要熟练掌握。
Q7:
描述一下C#中索引器的实现过程,是否只能根据数字进行索引?
参考答案:
索引器允许类或结构的实例按照与数组相同的方式进行索引。
索引器类似于属性,不同之处在于它们的访问器使用参数。
要实现索引器需要使用this关键字声明,然后象属性那样实现set和get访问器方法就可以了。
索引器不仅仅只能根据数字来进行索引,也可以使用字符串等方式。
点评:
灵活使用索引器能使我们的开发更加人性化,这些是c#开发人员必须的技术点之一。
Q8:
C#中要使一个类支持FOREACH遍历,实现过程怎样?
参考答案:
要是一个类支持实现FOREACH遍历,通常的做法是让这个类实现IEnumerable接口,这个接口有一个GetEnumerator方法,它返回一个一个循环访问集合的枚举数。
但是,在这个方法返回的是一个实现了IEnumerator接口的对象,也就是说我们还需要一个实现了IEnumerator接口的类。
该类需要实现Current属性和MoveNext,Reset方法。
其中Current用来获取集合中的当前元素,MoveNext将枚举数推进到集合的下一个元素。
Reset 将枚举数设置为其初始位置,该位置位于集合中第一个元素之前。
点评:
FOREACH的出现的确给我们编程带来了很大的好处,但是对于其中的原来大家也要作些了解,这样当需要的时候,我们可以让我们自己的类实现迭代功能。
Q10:
写一个HTML页面,实现以下功能,左键点击页面时显示“您好”,右键点击时显示“禁止右键”。
并在2分钟后自动关闭页面。
答:
functionwindow_onmousedown(){
if(window.event.button==1)
alert("你好");
elseif(window.event.button==2)
{
alert("禁止右键");
setTimeout("this.close();",2000);
}
}