.NET面试题 - 2
这一部分简单整理了一些我在网上遇到的面试题中不是很熟悉的部分,简单起见直接把答案列在题目后方。
-
表征数据传输可靠性的指标是误码率。
-
关于广义表的叙述中正确的是广义表是0个或多个单元素或子表组成的有限序列。
-
二叉树的对称序遍历即指中序遍历。
-
根据XML注释生成文档的编译选项是/doc
-
判断字符串是否为空最快的方法是str.Lenght == 0
1 static void Main() 2 { 3 int i = 2000; 4 object o = i; 5 i = 2001; 6 int j = (int)o; 7 Console.WriteLine("i={0},o={1},j={2}", i, o, j); 8 }
请问此程序的输出是什么,为什么?
其输出结果如下:
i=2001,o=2000,j=2000
原因是,i为值类型,o为引用类型,当把i给o时,执行一个装箱操作,当把值2001赋给i时,i的值变为2001,此时o中存放的仍然是2000被装箱的对象,当把o赋给j后,执行一个拆箱操作,把包含2000的对象拆为值类型放入2000,即j的值为2000。
1 class Class1 2 { 3 public static int Count = 0; 4 static Class1() 5 { 6 Count++; 7 } 8 public Class1() 9 { 10 Count++; 11 } 12 static void Main() 13 { 14 Class1 o1 = new Class1(); 15 Class1 o2 = new Class1(); 16 Console.WriteLine(Class1.Count); 17 Console.Read(); 18 } 19 }
输出什么?
解答:添加如下程序语句(黑体表示)可以看到程序执行的过程:
1 class Class1 2 { 3 public static int Count = 0; 4 static Class1() 5 { 6 Count++; 7 Console.WriteLine("静态构造函数!"); 8 } 9 public Class1() 10 { 11 Count++; 12 Console.WriteLine("实例构造函数!"); 13 } 14 static void Main() 15 { 16 Class1 o1 = new Class1(); 17 Class1 o2 = new Class1(); 18 Console.WriteLine(Class1.Count); 19 Console.Read(); 20 } 21 }
注意:静态构造函数只会被执行一次。也就是在创建第一个实例或引用任何静态成员之前,由.NET自动调用。
以下语句执行后myTable的名称是什么?
System.Data.DataTable myTable = new System.Data.DataTable();
解答:使用如下语句显示一下myTable的TableName属性即可:
Console.WriteLine(myTable.TableName);
名称为空字符串,即"";
如下的IDimensions接口和Box类,该类显示实现接口成员Length和Width。myDimensions是IDimensions接口的一个实例。
1 interface IDimensions 2 { 3 float Length(); 4 float Width(); 5 } 6 7 class Box : IDimensions 8 { 9 float lengthInches; 10 float widthInches; 11 public Box(float length, float width) 12 { 13 lengthInches = length; 14 widthInches = width; 15 } 16 17 float IDimensions.Length() 18 { 19 return lengthInches; 20 } 21 22 float IDimensions.Width() 23 { 24 return widthInches; 25 } 26 27 public static void Main() 28 { 29 Box myBox = new Box(30.0f, 20.0f); 30 IDimensions myDimensions = (IDimensions)myBox; 31 Console.WriteLine("Length: {0}", myBox.Length()); 32 Console.WriteLine("Width: {0}", myBox.Width()); 33 } 34 }
执行以上程序控制台输出为?
解答:这段程序不会通过编译,因为类实现接口时使用的显式实现,而显式实现的方法只能通过接口对象访问,无法通过类对象访问。隐式实现接口的方法既可以通过接口对象,也可以通过类对象访问。
所以可以改为这种方式
……
1 public static void Main() 2 { 3 Box myBox = new Box(30.0f, 20.0f); 4 IDimensions myDimensions = (IDimensions)myBox; 5 Console.WriteLine("Length: {0}", myDimensions.Length()); 6 Console.WriteLine("Width: {0}", myDimensions.Width()); 7 }
或者是改为隐式实现接口方法:
1 public float Length() 2 { 3 return lengthInches; 4 } 5 public float Width() 6 { 7 return widthInches; 8 }
1. 填空:(1)面向对象的语言具有继承性、封装性和多态性。
(2)能用foreach遍历访问的对象需要实现IEnumerable接口的IEnumerator方法(这个方法的返回类型IEnumerator实现了foreach所需要的方法)
(3)列举ADO.NET中的五个主要对象Command、Connection、DataSet、DataAdapter、DataReader。
2. 不定项选择:
(1).以下叙述正确的是:
A. 接口中可以有虚方法。 B. 一个类可以实现多个接口。
C. 接口不能被实例化。 D. 接口中可以包含已实现的方法。
以上正确的是:B,C
解释A项,因为接口的方法不能用修饰符修饰,所以A不正确。
(2). 从数据库读取记录,你可能用到的方法有:
A.ExecuteNonQuery B.ExecuteScalar C.Fill D.ExcuteReader
以上正确的项是:C,D
说明:B项会返回受影响的行数,此项可选。
3. 简述private、protected、public、internal修饰符的访问权限。
答:private: 私有,只限于在类(所声明于的对象)内部访问。
protected: 保护,只限于在被声明于的类及其子类中被访问。
public: 公共,无访问限制
internal: 内部,在同一程序集内可以被访问。
4. 写出一条Sql语句:取出表A中第31到第40记录(SQLServer,以自动增长的ID作为主键,注意:ID可能不是连续的。)
两种写法如下所示:
1 SELECT TOP 10 * FROM TestTable 2 WHERE (ID NOT IN 3 (SELECT TOP 30 ID FROM TestTable ORDER BY ID)) 4 ORDER BY ID 5 6 SELECT TOP 10 * FROM T 7 WHERE ID > 8 (SELECT MAX(ID) FROM (SELECT TOP 30 ID FROM TestTable) AS T)
5. 列举ASP.NET页面之间传递值的几种方式。
答: 基本上有如下4种方式,依次介绍:
(1) 使用QueryString:
方法都明白,说一下优缺点,优点:1.使用简单,对于安全性要求不高时传递数字或是文本值非常有效。缺点:1.缺乏安全性,由于它的值暴露在浏览器的URL地址中的。2.不能传递对象。难点问题:传递文字或者特殊字符时使用
(2) 使用Application变量,可以传递各类对象,但是有一个缺点就是作为全局变量容易被误操作。
(3) 使用Session。没有Application的缺点,但是大量应用Session可能会消耗服务器资源。
(4) 使用cookie对象,类似于Session针对单用户的特性,但cookie存储于客户端。读写方式可以概括为以下两句:
1 HttpCookie cookie_name = new HttpCookie("name"); 2 cookie_name.Value = Label1.Text; 3 Reponse.AppendCookie(cookie_name); 4 Request.Cookie["name"].Value.ToString();
(5) 使用Server.Transfer在页面见传递参数
直接给出示例:首先在页面a.aspx的代码文件中编写如下代码:
1 protected void Page_Load(object sender, EventArgs e) 2 { 3 Label1.Text = "待传递" + DateTime.Now.ToString(); 4 } 5 6 public string Name 7 { 8 get { return Label1.Text; } 9 } 10 11 12 protected void Button1_Click(object sender, EventArgs e) 13 { 14 Server.Transfer("b.aspx"); 15 }
当然页面中首先需要添加如下两个Server Control
1 <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" /> 2 <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
b页面的设计如下所示:
1 protected void Page_Load(object sender, EventArgs e) 2 { 3 a newWeb; //实例a窗体 4 newWeb = (a)Context.Handler; 5 string name; 6 name = newWeb.Name; 7 Response.Write("这是页面b:" + name); 8 }
这样当点击按钮后,a将传递信息给b(或者说b可以有a获取信息)
主要参考:
http://www.cnblogs.com/changhai-xuri/archive/2008/09/26/1299647.html
http://blog.csdn.net/baoxuetianxia/archive/2009/05/22/4208404.aspx
6. 写出程序的输出结果
1 public class Class1 2 { 3 private string str = "Class1.str"; 4 private int i = 0; 5 static void StringConvert(string str) 6 { 7 str = "string being converted."; 8 } 9 10 static void StringConvert(Class1 c) 11 { 12 c.str = "string being converted."; 13 } 14 15 static void Add(int i) { 16 i++; 17 } 18 19 static void AddWithRef(ref int i) { 20 i++; 21 } 22 23 static void Main() { 24 int i1 = 10; 25 int i2 = 20; 26 string str = "str"; 27 Class1 c = new Class1(); 28 Add(i1); 29 AddWithRef(ref i2); 30 Add(c.i); 31 StringConvert(str); 32 StringConvert(c); 33 Console.WriteLine(i1); 34 Console.WriteLine(i2); 35 Console.WriteLine(c.i); 36 Console.WriteLine(str); 37 Console.WriteLine(c.str); 38 } 39 }
输出结果如下:
10
21
0
str
string being converted.
个人总结:主要考察值类型与应用类型在作为参数时的一些处理,以及string这种特殊的引用类型一些类似值类型的特性。
7. 写出程序的输出结果
1 public abstract class A 2 { 3 public A() 4 { 5 Console.WriteLine('A'); 6 } 7 public virtual void Fun() 8 { 9 Console.WriteLine("A.Fun()"); 10 } 11 } 12 13 public class B : A 14 { 15 public B() 16 { 17 Console.WriteLine('B'); 18 } 19 20 public new void Fun() 21 { 22 Console.WriteLine("B.Fun()"); 23 } 24 25 public static void Main() 26 { 27 A a = new B(); 28 a.Fun(); 29 } 30 }
输出结果为:
A
B
A.Fun()
说明:首先调用父类型的构造函数,然后调用派生类型的构造函数。
8. 写出程序的输出结果:
1 public class A 2 { 3 public virtual void Fun1(int i) 4 { 5 Console.WriteLine(i); 6 } 7 8 public void Fun2(A a) 9 { 10 a.Fun1(1); 11 Fun1(5); 12 } 13 } 14 15 public class B : A 16 { 17 public override void Fun1(int i) 18 { 19 base.Fun1(i + 1); 20 } 21 22 public static void Main() 23 { 24 B b = new B(); 25 A a = new A(); 26 a.Fun2(b); 27 b.Fun2(a); 28 } 29 }
输出结果:
2
5
1
6
9. 一列数的规则如下: 1、1、2、3、5、8、13、21、34......求第30位数是多少,用递归算法实现。(C#语言)
解答:
1 public class MainClass 2 { 3 public static void Main() 4 { 5 Console.WriteLine(Foo(30)); 6 Console.Read(); 7 } 8 9 public static int Foo(int i) 10 { 11 if (i <= 0) 12 return 0; 13 else if (i > 0 && i <= 2) 14 return 1; 15 else 16 return Foo(i - 1) + Foo(i - 2); 17 } 18 }
结果为:832040
10. 程序设计:猫大叫一声,所有的老鼠都开始逃跑,主人被惊醒。(C#语言)
要求:1.要有联动性,老鼠和主人的行为是被动的。
2.考虑可扩展性,猫的叫声可能引起其他联动效应。
解法1:
1 public interface Observer 2 { 3 //观察者的响应,如是老鼠见到猫的反映 4 void Response(); 5 } 6 7 public interface Subject 8 { 9 //针对哪些观察者,这里指猫的要捕捉的对象 --- 老鼠 10 void AimAt(Observer obs); 11 } 12 13 public class Mouse : Observer 14 { 15 private string name; 16 public Mouse(string name, Subject subj) 17 { 18 this.name = name; 19 subj.AimAt(this); 20 } 21 22 public void Response() 23 { 24 Console.WriteLine(name + "attempt to escape!"); 25 } 26 } 27 28 public class Master : Observer 29 { 30 public Master(Subject subj) 31 { 32 subj.AimAt(this); 33 } 34 35 public void Response() 36 { 37 Console.WriteLine("Host waken!"); 38 } 39 } 40 41 public class Cat : Subject 42 { 43 private ArrayList observers; 44 45 public Cat() 46 { 47 this.observers = new ArrayList(); 48 } 49 50 public void AimAt(Observer obs) 51 { 52 this.observers.Add(obs); 53 } 54 55 public void Cry() 56 { 57 Console.WriteLine("Cat cayed!"); 58 foreach (Observer obs in this.observers) 59 { 60 obs.Response(); 61 } 62 } 63 } 64 65 class MainClass 66 { 67 static void Main(string[] args) 68 { 69 Cat cat = new Cat(); 70 Mouse mouse1 = new Mouse("mouse1", cat); 71 Mouse mouse2 = new Mouse("mouse2", cat); 72 Master master = new Master(cat); 73 cat.Cry(); 74 75 Console.Read(); 76 } 77 }
解法2:(使用event – delegate设计)
1 public delegate void SubEventHandler(); 2 3 public abstract class Subject 4 { 5 public event SubEventHandler SubEvent; 6 protected void FireAway() 7 { 8 if (this.SubEvent != null) 9 { 10 this.SubEvent(); 11 } 12 } 13 } 14 15 public class Cat : Subject 16 { 17 public void Cry() 18 { 19 Console.WriteLine("cat cryed."); 20 this.FireAway(); 21 } 22 } 23 24 public abstract class Observer 25 { 26 public Observer(Subject sub) 27 { 28 sub.SubEvent += new SubEventHandler(Response); 29 } 30 31 public abstract void Response(); 32 } 33 34 public class Mouse : Observer 35 { 36 private string name; 37 public Mouse(string name, Subject sub) 38 : base(sub) 39 { 40 this.name = name; 41 } 42 43 public override void Response() 44 { 45 Console.WriteLine(name + " attempt to escape!"); 46 } 47 } 48 49 public class Master : Observer 50 { 51 public Master(Subject sub) : base(sub) { } 52 public override void Response() 53 { 54 Console.WriteLine("host waken"); 55 } 56 } 57 58 class Class1 59 { 60 static void Main(string[] args) 61 { 62 Cat cat = new Cat(); 63 Mouse mouse1 = new Mouse("mouse1", cat); 64 Mouse mouse2 = new Mouse("mouse2", cat); 65 Master master = new Master(cat); 66 cat.Cry(); 67 68 Console.Read(); 69 } 70 }
运行结果为:
cat cryed.
mouse1 attempt to escape!
mouse2 attempt to escape!
host waken
几个需要注意的地方:
1. Mouse与Master需要得到一个抽象,即解法1中的接口与解法2中的抽象类。