Net软件工程师面试题.docx
《Net软件工程师面试题.docx》由会员分享,可在线阅读,更多相关《Net软件工程师面试题.docx(18页珍藏版)》请在冰豆网上搜索。
Net软件工程师面试题
一.填空题(每空1分,共12分)
1面向对象的语言具有__封装______性、__继承_______性、__多态______性。
2能用foreach遍历访问的对象需要实现 ____Ienumerable____________接口或声明_____GetEnumerator___________方法的类型。
3当类T只声明了私有实例构造函数时,则在T的程序文本外部,___不可以___(可以 or 不可以)从T派生出新的类,在T的内部__可以__(可以 or 不可以)直接创建T的任何实例,在T的外部__不可以__(可以 or 不可以)直接创建T的任何实例。
4. 委托声明的关键字是__Delegate____
5. override与重载的区别:
override覆盖是基类中函数的重写。
重载:
方法或函数的名称相同,参数或许参数类型不同,进行多次重载实现功能。
二. 不定项选择(每题2分,共18)
Question1
以下叙述正确的是:
A. 接口中可以有虚方法。
B. 一个类可以实现多个接口。
C. 接口不能被实例化。
D. 接口中可以包含已实现的方法。
Question2
以下描述错误的是()
1. 在C++中支持抽象类而在C#中不支持抽象类。
2.C++中可在头文件中声明类的成员而在CPP文件中定义类的成员,在C#中没有头文件并且在同一处声明和定义类的成员。
3. 在C#中可使用 new 修饰符显式隐藏从基类继承的成员。
4. 在C#中要在派生类中重新定义基类的虚函数必须在前面加Override。
Question3
声明一个委托publicdelegateintmyCallBack(intx)。
则用该委托产生的回调方法的原型应该是
1.voidmyCallBack(intx)
2.intreceive(intnum)
3.stringreceive(intx)
4. 不确定的
Question4
下列描述错误的是()
a) 类不可以多重继承而接口可以;
b) 抽象类自身可以定义成员而接口不可以;
c) 抽象类和接口都不能被实例化;
d) 一个类可以有多个基类和多个基接口;
Question5
下列关于构造函数的描述正确的是()
a) 构造函数可以声明返回类型。
b) 构造函数不可以用private修饰
c) 构造函数必须与类名相同 d) 构造函数不能带参数
Question6
接口是一种引用类型,在接口中可以声明( ),但不可以声明公有的域或私有的成员变量。
a) 方法、属性、索引器和事件;
b) 方法、属性信息、属性;
c) 索引器和字段;
d) 事件和字段;
Question7
以下的C#代码,试图用来定义一个接口:
publicinterfaceIFile
{
intA。
intdelFile()
{
A=3。
}
voiddisFile()。
}
关于以上的代码,以下描述错误的是()。
a) 以上的代码中存在的错误包括:
不能在接口中定义变量,所以intA代码行将出现错误; b) 以上的代码中存在的错误包括:
接口方法delFile是不允许实现的,所以不能编写具体的实现函数;
c) 代码voiddisFile()。
声明无错误,接口可以没有返回值;
d) 代码voiddisFile()。
应该编写为voiddisFile(){};
Question8.
classClass1
{
publicstaticintCount=0。
staticClass1()
{
Count++。
}
publicClass1()
{
Count++。
}
}
Class1o1=newClass1()。
Class1o2=newClass1()。
请问,Class1.Count的值是多少?
()
1.1
2.2
3.3
4.4
Question9
abstractclassBaseClass
{
publicvirtualvoidMethodA()
{
Console.WriteLine("BaseClass")。
}
publicvirtualvoidMethodB()
{
}
}
classClass1:
BaseClass
{
publicvoidMethodA()
{
Console.WriteLine("Class1")。
}
publicoverridevoidMethodB()
{
}
}
classClass2:
Class1
{
newpublicvoidMethodB()
{
}
}
classMainClass
{
publicstaticvoidMain(string[]args)
{
Class2o=newClass2()。
o.MethodA()。
}
}
请问,此程序输出结果是:
1.BaseClass
2.BassClassClass1
3.Class1
4.Class1BassClass
(解读,三重继承问题,孙类只是继承父类,而不是直接继承祖父类)
三.问答题(每题3分,共15分)
1. 简述 private、 protected、 public、 internal 修饰符的访问权限。
private:
私有访问,它只能在声明自身的类中进行访问。
protected:
表示受保护的访问,该类内部和继承类中可以访问
.public:
表示公共访问,在代码任何位置都可对其进行访问
internal表示内部成员,在同一命名空间内可以访问。
2.C#中的委托是什么?
事件是不是一种委托?
委托是指具有相同属性(也称具有相同的函数签名:
返回类型相同,参数类型、参数顺序及参数个数相同)的函数或方法的抽象,关键字为delegate。
主要用途是三个:
1)函数回调;2)传递方法;3)事件机制
事件就是一个狭义的委托,也就是事件是一个用于事件驱动模型的专用委托,对事件的声明, 实际是声明一个私有的委托变量,对委托变量进行封装,即委托变量加上event关键字后,不管其前面的访问修饰符是public还是private,编译器都会将其编译为private。
委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。
以委托为参数的函数具有一定的通用性。
使用委托可以将多个方法绑定到同一个委托变量,当调用此变量时(这里用“调用”这个词,是因为此变量代表一个方法),可以依次调用所有绑定的方法。
3. abstract 可以和 virtual 一起使用吗?
可以和 override 一起使用吗?
不可以一起使用,但是可以和override一起使用。
4. 请叙述属性与索引器的区别。
属性:
它是存取类的字段,索引器:
Indexer它是特殊的属性,用它可以使用户像访问数组一样访问类的成员。
5. 请详述在dotnet中类(class)与结构(struct)的异同。
类class可以进行实例化,它是引用类型,内存分配在栈中,效率高,它有默认的构造函数,有析构函数可以使用 abstract 和 sealed, protected 修饰符。
要用new进行初始化,
结构它是属于值类型,内存分配在堆中,效率低,它没有默认的构造函数,但是可以添加构造函数,没有析构函数没有 abstract 和 sealed(因为不能继承) 不能有protected 修饰符可以不使用new 初始化,但是可以在结构中初始化实例字段。
四.分析程序(每题5分,共25分) (此题不能调试,若发现调试,扣除分数)
1. 写出程序的输出结果
classClass1 {
privatestringstr="Class1.str"。
privateinti=0。
staticvoidStringConvert(stringstr) {
str="stringbeingconverted."。
}
staticvoidStringConvert(Class1c) {
c.str="stringbeingconverted."。
}
staticvoidAdd(inti) {
i++。
}
staticvoidAddWithRef(refinti) {
i++。
}
staticvoidMain() {
inti1=10。
inti2=20。
stringstr="str"。
Class1c=newClass1()。
Add(i1)。
AddWithRef(refi2)。
Add(c.i)。
StringConvert(str)。
StringConvert(c)。
Console.WriteLine(i1)。
Console.WriteLine(i2)。
Console.WriteLine(c.i)。
Console.WriteLine(str)。
Console.WriteLine(c.str)。
}
}
10
21
0
str
stringbeingconverted
2.写出程序的输出结果
publicabstractclassA
{
publicA()
{
Console.WriteLine('A')。
}
publicvirtualvoidFun()
{
Console.WriteLine("A.Fun()")。
}
}
publicclassB:
A
{
publicB()
{
Console.WriteLine('B')。
}
publicoverridevoidFun()
{
Console.WriteLine("B.Fun()")。
}
publicstaticvoidMain()
{
Aa=newB()。
a.Fun()。
}
}
解读:
主函数 Aa=newB();首先声明了一个A的对象a,但被赋给不同于A的对象B,在此期间分别调用了A类的构造函数和B类的构造函数,然后调用a的fun()函数,因为a的fun()函数是虚函数,被b的fun()的函数覆盖,所以实际执行的是b的fun().
答案:
A
B
B.Fun()
3.写出程序的输出结果:
publicclassA
{
publicvirtualvoidFun1(inti)
{
Console.WriteLine(i)。
}
publicvoidFun2(Aa)
{
a.Fun1
(1)。
Fun1(5)。
}
}
publicclassB:
A
{
publicoverridevoidFun1(inti)
{
base.Fun1(i+1)。
}
publicstaticvoidMain()
{
Bb=newB()。
Aa=newA()。
b.Fun2(a)。
a.Fun2(b)。
}
}
输出结果为:
2
5
1
6
(一个函数的执行必须在一个具体的对象中实现,如果函数明确告诉是哪个对象,则在改该对象下执行;如果没有,则在默认的对象下执行)
4. 在下面的例子里usingSystem。
classA
{
publicA()
{
PrintFields()。
}
publicvirtualvoidPrintFields(){}
}
classB:
A
{
intx=4。
inty。
publicB()
{
y=-1。
}
publicoverridevoidPrintFields()
{
x+=1。
Console.WriteLine("x={0},y={1}",x,y)。
y+=1。
}
当使用Bb=newB()创建的实例时,产生什么输出?
b.PrintFields()。
结果是什么?
X=5,y=0
b.PrintFields 结果是x=6。
y=1
5. 下面的例子中usingSystem。
classA
{
publicstaticintX。
staticA()
{
X=B.Y+1。
}
}
classB
{
publicstaticintY=A.X+1。
staticB()
{}
staticvoidMain()
{
Console.WriteLine("X={0},Y={1}",A.X,B.Y)。
}
}
产生的输出结果是什么?
X=2,Y=1
五.程序设计(每题7分,共28分)
1. 请编程实现一个冒泡排序算法?
//比较法
using System。
using System.Collections.Generic。
using System.Text。
namespace test1
{
class Program
{
static void Main(string[]args)
{
int[]Array={6,18,12,23,19,28,30}。
Console.WriteLine("排序前的数组:
")。
foreach(int n in Array)
{
Console.Write(n+"")。
}
Console.WriteLine()。
for (int i=1。
ii++) //控制趟数
{
for (int j=0。
jj++)
{
if (Array[j]>Array[j+1]) //交换
{
int temp=Array[j]。
Array[j]=Array[j+1]。
Array[j+1]=temp。
}
}
}
//排序后
Console.WriteLine("排序后的数组:
")。
for (int n=0。
nn++)
{
Console.Write(Array[n]+ "")。
}
Console.WriteLine()。
}
}
}
2. 编程程序实现委托,事件。
using System。
using System.Collections.Generic。
using System.Text。
namespace delegateDemo
{
class Program
{
static void Main(string[]args)
{
Cat cat= new Cat()。
Mouse mouse= new Mouse()。
Master master= new Master()。
cat.Calling+= new EventHandler(mouse.Escape)。
cat.Calling+= new EventHandler(master.Wakened)。
cat.Call()。
}
}
public sealed class Cat //猫类
{
public event EventHandler Calling。
public void Call()
{
Console.WriteLine("猫开始叫了……")。
if(Calling!
=null) //检查事件是否被注册
Calling(this,EventArgs.Empty)。
//调用事件注册的方法
}
}
public sealed class Mouse //老鼠类
{
public void Escape(object sender, EventArgs e)
{
Console.WriteLine("老鼠逃跑了...")。
}
}
public sealed class Master //主人
{
public void Wakened(object sender, EventArgs e)
{
Console.WriteLine("主人惊醒了...")。
}
}
}
3. 写一个程序,语言不限,打印出100的阶乘(即1*2*3*…*100)的精确数值结果(不能是浮点数)。
如5的阶乘是1*2*3*4*5=120。
using System。
using System.Collections.Generic。
using System.Text。
//,打印出100的阶乘(即1*2*3*…*100)的精确数值结果(不能是浮点数)。
如5的阶乘是1*2*3*4*5=120
namespace shuzu
{
class Program
{
static void Main(string[]args)
{
Console.WriteLine("请输入一个正数")。
int n= int.Parse(Console.ReadLine())。
Console.WriteLine("{0}的阶乘1*2*3*…*{1}={2}",n,n,Fn(n))。
}
public static double Fn(int n)
{
if (n==1)
{
return 1。
}
else
{
return n*Fn(n-1)。
}
}
}
}
4. 写一个程序,语言不限,能将人民币金额从阿拉伯数字转换为大写汉字表示。
例如,把1234.56转换为壹仟贰佰叁拾肆圆零伍角陆分。
using System。
using System.Collections.Generic。
using System.Text。
namespace ConsoleApplication1
{
class Program
{
static void Main(string[]args)
{
Console.WriteLine("请输入数字:
")。
string s= Console.ReadLine()。
Console.Write("转换后¥:
")。
for (int i=0。
ii++)
{
//switch(Convert.ToInt32(Console.ReadLine()))
switch (s[i]-48)