.net面试问答(大汇总)

.NET
483
0
0
2022-03-22

用.net做B/S结构的系统,您是用几层结构来开发,每一层之间的关系以及为什么要这样分层? 

答:

从下至上分别为:数据访问层、业务逻辑层(又或成为领域层)、表示层 

数据访问层:有时候也称为是持久层,其功能主要是负责数据库的访问 

业务逻辑层:是整个系统的核心,它与这个系统的业务(领域)有关 

表示层:是系统的UI部分,负责使用者与整个系统的交互。  

优点: 分工明确,条理清晰,易于调试,而且具有可扩展性。 

缺点: 增加成本。

分层式结构究竟其优势何在? 

1、开发人员可以只关注整个结构中的其中某一层; 

2、可以很容易的用新的实现来替换原有层次的实现; 

3、可以降低层与层之间的依赖; 

4、有利于标准化; 

5、利于各层逻辑的复用。 

概括来说,分层式设计可以达至如下目的:分散关注、松散耦合、逻辑复用、标准定义。

分层式结构也不可避免具有一些缺陷: 

 1、降低了系统的性能。这是不言而喻的。如果不采用分层式结构,很多业务可以直接造访数据库,以此获取相应的数据,如今却必须通过中间层来完成。 

2、有时会导致级联的修改。这种修改尤其体现在自上而下的方向。如果在表示层中需要增加一个功能,为保证其设计符合分层式结构,可能需要在相应的业务逻辑层和数据访问层中都增加相应的代码。

MVC模式

MVC(Model-View-Controller)把交互系统的组成分解成模型、视图、控制器三种部件

mvc的优点:

1.通过把项目分成model view和controller,使得复杂项目更加容易维护。

2.没有使用view state和服务器表单控件,可以更方便的控制应用程序的行为

3.应用程序通过controller来控制程序请求,可以提供丰富的url重写。

4.对单元测试的支持更加出色

5.在团队开发模式下表现更出众

MVC的不足: 

(1)增加了系统结构和实现的复杂性。对于简单的界面,严格遵循MVC,使模型、视图与控制器分离,会增加结构的复杂性,并可能产生过多的更新操作,降低运行效率。    

(2)视图与控制器间的过于紧密的连接。视图与控制器是相互分离,但确实联系紧密的部件,视图没有控制器的存在,其应用是很有限的,反之亦然,这样就妨碍了他们的独立重用。    

(3)视图对模型数据的低效率访问。依据模型操作接口的不同,视图可能需要多次调用才能获得足够的显示数据。对未变化数据的不必要的频繁访问,也将损害操作性能。

asp.net如何实现MVC模式,举例说明!

web/business/dataaccess

列举ASP.NET 页面之间传递值的几种方式。 

1.使用QueryString, 如....?id=1; response. Redirect().... 

2.使用Session变量 

3.使用Server.Transfer

请说明在.net中常用的几种页面间传递参数的方法,并说出他们的优缺点。 

QueryString 传递一个或多个安全性要求不高或是结构简单的数值。但是对于传递数组或对象的话,就不能用这个方法了 

session(viewstate) 简单,但易丢失 作用于用户个人,过量的存储会导致服务器内存资源的耗尽。  

application 对象的作用范围是整个全局,也就是说对所有用户都有效。其常用的方法用Lock和UnLock 

cookie 简单,但可能不支持,可能被伪造 Cookie是存放在客户端的,而session是存放在服务器端的。而且Cookie的使用要配合ASP.NET内置对象Request来使用 

input ttype="hidden" 简单,可能被伪造 

url参数简单,显示于地址栏,长度有限 

Server.Transfer 把流程从当前页面引导到另一个页面中,新的页面使用前一个页面的应答流 

数据库稳定,安全,但性能相对弱

什么是Viewstate?它有什么作用?

ViewState用来保存页面状态,就是说提交之后我们还可以看到文本框里面的内容就是ViewState保存的功劳。 

ViewState只维护当前页面的状态,不同页面之间不能共享,Session可以。 

ViewState你可以理解为一个隐藏控件。

ASP.Net页面生命周期 

每个页面的生命周期为用户的每一次访问,也就是说每一次客户端与服务器之间的一个往返过程.全局变量的生命周期在此之间.

1. Page_Init(); 

2. Load ViewState and Postback data; 

3. Page_Load(); 

4. Handle control events; 

5. Page_PreRender(); 

6. Page_Render(); 

7. Unload event; 

8. Dispose method called; 

ADO.net中常用的对象有哪些?分别描述一下。 

答: 

Connection       打开数据库连接 

Command           执行数据库命令 

DataAdapter       连接数据,执行数据库命令,填充DataSet 

DataSet           数据在内存中的缓存,数据结构 

DataReader       只读向前的读取数据库

DataReader和DataSet的异同 

DataReader使用时始终占用SqlConnection,在线操作数据库..任何对SqlConnection的操作都会引发DataReader的异常..因为DataReader每次只在内存中加载一条数据,所以占用的内存是很小的..因为DataReader的特殊性和高性能.所以DataReader是只进的..你读了第一条后就不能再去读取第一条了.. 

DataSet则是将数据一次性加载在内存中.抛弃数据库连接..读取完毕即放弃数据库连接..因为DataSet将数据全部加载在内存中.所以比较消耗内存...但是确比DataReader要灵活..可以动态的添加行,列,数据.对数据库进行回传更新操作...

存储过程和sql语句的优缺点

优点: 

1.提高性能,减少网络传输,节约时间 。

2.减少网络流量   存储过程位于服务器上,调用的时候只须传递存储过程的名称以及参数,不用每次访问都传递很长的sql 语句。

4.安全性    减少sql 注入式攻击。

5.可维护性高   更新存储过程通常比更改、测试以及重新部署程序集需要较少的时间和精力。

缺点:

1.交互性差 。

2.可移植性差

说出你所了解的数据库访问组件(例如ADO,至少4种) 

答:ADO,ADO.Net,MDAC(Microsoft Data Access Components),Microsoft SQL Server OLE DB Provider,

Microsoft Jet OLE DB Provider,Desktop Database Drivers ODBC Driver,Visual FoxPro ODBC Driver 

什么是面向对象 

万物都是对象,其主要特征:封装、继承、多态 

怎样实现多态 

1.通过对象直接调用成员函数时,始终默认使用该对象的类的成员函数(除非用::显示指定类名)。

2.通过指向对象的指针或引用调用成员函数时:如果该函数是实函数,则调用该指针或引用的类的成员函数;如果该函

数是虚函数,则调用该指针或引用指向的对象的类的成员函数。 

面向对象的思想主要包括什么? 

答:任何事物都可以理解为对象,其主要特征: 继承。封装。多态。特点:代码好维护,安全,隐藏信息 

什么是装箱和拆箱? 

答:从值类型接口转换到引用类型装箱。从引用类型转换到值类型拆箱。装箱(boxing)是将值类型的数据转化成引用类型,int i=3; object o = i ;便是装箱过程,而拆箱(unboxing)是将饮用类型数据转换值类型,比如int j = (int)o;属于拆箱

什么是Interface?它与Abstract Class有什么区别?

接口(Interface)是用来定义行为规范的,不会有具体实现,而抽象类除定义行为规范外,可以有部分实现,但一

个类能实现多个接口,但只能继承一个父类   

什么时候使用抽象类,什么时候用接口 

接口用于规范,抽象类用于共性。接口中只能声明方法,属性,事件,索引器。而抽象类中可以有方法的实

现,也可以定义非静态的类变量。抽象类是类,所以只能被单继承,但是接口却可以一次实现多个。抽象类可以

提供某些方法的部分实现,接口不可以.抽象类的实例是它的子类给出的。接口的实例是实现接口的类给出的。

再抽象类中加入一个方法,那么它的子类就同时有了这个方法。而在接口中加入新的方法,那么实现它的类就要

重新编写(这就是为什么说接口是一个类的规范了)。接口成员被定义为公共的,但抽象类的成员也可以是私有

的、受保护的、内部的或受保护的内部成员(其中受保护的内部成员只能在应用程序的代码或派生类中访问)。

此外接口不能包含字段、构造函数、析构函数、静态成员或常量。 

什么是抽象类(abstract class)? 

一种不可以被实例化的类。抽象类中一般含有抽象方法,当然也可有具体实现。继承类只有实现过所有抽

象类的抽象方法后才能被实例化。

何时必须声明一个类为抽象类? 

当这个类中包含抽象方法时,或是该类并没有完全实现父类的抽象方法时。

口(interface)是什么? 

只含有共有抽象方法(public abstract method)的类。这些方法必须在子类中被实现。

为什么不能指定接口中方法的修饰符? 

接口中的方法用来定义对象之间通信的契约,指定接口中的方法为私有或保护没有意义。他们默认为公有方法。

可以继承多个接口么? 

当然。

那么如果这些接口中有重复的方法名称呢? 

这种情况中你可以决定如何实现。当然需要特别得小心。但是在编译环节是没有问题的。

接口和抽象类的区别是什么? 

接口中所有方法必须是抽象的,并且不能指定方法的访问修饰符。抽象类中可以有方法的实现,也可以指

定方法的访问修饰符。

详述.NET里class和struct的异同!

类是引用类型,可以继承类、接口和被继承,有默认的构造函数,有析构函数,可以使用abstract和sealed,有protected修饰符,必须使用new初始化。 

结构是值类型,只能继承接口,不能被继承,没有默认的构造函数,可以创建,没有析构函数,不可以用abstract和sealed,没有protected修饰符,可以不用new初始化。 

如何选择结构还是类 

1. 堆栈的空间有限,对于大量的逻辑的对象,创建类要比创建结构好一些 

2. 结构表示如点、矩形和颜色这样的轻量对象 

例如,如果声明一个含有 1000 个点对象的数组,则将为引用每个对象分配附加的内存。 

在此情况下,结构的成本较低。 

3. 在表现抽象和多级别的对象层次时,类是最好的选择 

4. 大多数情况下该类型只是一些数据时,结构时最佳的选择 

C#中的接口和类有什么异同。  

异: 

不能直接实例化接口。 

接口不包含方法的实现。 

接口、类和结构可从多个接口继承。但是C# 只支持单继承:类只能从一个基类继承实现。 

类定义可在不同的源文件之间进行拆分。 

同: 

接口、类和结构可从多个接口继承。 

接口类似于抽象基类:继承接口的任何非抽象类型都必须实现接口的所有成员。 

接口可以包含事件、索引器、方法和属性。 

一个类可以实现多个接口。

const和readonly有什么区别? 

const关键字用来声明编译时常量,readonly用来声明运行时常量。

用sealed修饰的类有什么特点 

sealed 修饰符用于防止从所修饰的类派生出其它类。如果一个密封类被指定为其他类的基类,则会发生编译时错误。 

密封类不能同时为抽象类。 

sealed 修饰符主要用于防止非有意的派生,但是它还能促使某些运行时优化。具体说来,由于密封类永

远不会有任何派生类,所以对密封类的实例的虚拟函数成员的调用可以转换为非虚拟调用来处理。 

虚函数的用法 

答: 

1)virtual指明一成员函数为虚函数,而virtual仅用于类的定义里,在类外可不加此关键字. 

2)一个类的成员函数被定义为虚函数时,子类该函数仍保持虚函数特征. 

3)子类覆盖此函数时,定义里可不加virtual关键字,但函数声明要和基类的完全一致!且此声明是必须的. 

4)不是纯虚函数时,父类的虚函数必须要实现; 而若将父类的虚函数设定为纯虚函数时,子类必需要覆盖之而且必须要实现之! 

解释virtual、sealed、override和abstract的区别 

virtual申明虚方法的关键字,说明该方法可以被重写 

sealed说明该类不可被继承 

override重写基类的方法 

abstract申明抽象类和抽象方法的关键字,抽象方法不提供实现,由子类实现,抽象类不可实例化。 

重载和覆写有什么区别? 

答:重载是方法的名称相同,不同的参数类型,不同的参数个数,不同的参数顺序。覆写提供了子类中改变父类方法行为的实现(是进行基类中函数的重写)。 

在方法定义中,virtual有什么含义? 

答:被virtual修饰的方法可以被子类覆写 

能够将非静态的方法覆写成静态方法吗? 

答:不能,覆写方法的签名必须与被覆写方法的签名保持一致,除了将virtual改为override。 

可以覆写私有的虚方法吗? 

答:不可以,甚至子类中无法访问父类中的私有方法 

能够阻止某一个类被其他类继承吗? 

答:可以,使用关键字sealed 

能够实现允许某个类别继承,但不允许其中的某个方法被覆写吗? 

答:可以,标记这个类为public,并标记这个方法为sealed。 

如何区别重载方法? 

不同的参数类型,不同的参数个数,不同的参数顺序

c#继承:

base 表示当前对象基类的实例(使用base关键字可以调用基类的成员)this表示当前类的实例     

在静态方法中不可以使用basethis关键字     

派生类会继承基类所有的成员但是构造函数和析构函数不会被继承    

注意如果派生类的方法和基类的方法同名则基类中的方法将会被隐藏如果需要隐藏则可以使用关键字new来隐藏如果不写new关键字默认处理为隐藏虽然基类中同名的方法被隐藏了但是还是可以通过base关键字来调用     

//如果子类方法的方法名和基类的方法名相同时,系统将隐藏基类同名方法,自动调用子类的同名方法     

//派生类会继承基类所有的成员,但是不能显示调用基类的是有成员     

//在派生类中不可以调用基类的是有成员,如num1,num2,但是可以实现调用基类方法     

virtual 用在基类中指定一个虚方法属性表示这个方法属性可以重写     

override 用在派生类中表示对基类虚方法属性的重写     

不能重写非虚方法或静态方法重写的基方法必须是 virtualabstract 或 override 的为什么 override 也可以重写呢因为基类中的 override 实际上是对基类的基类进行的重写由于继承可传递所以也可以对基类中 override 的方法进行重写     

override 声明不能更改 virtual 方法的可访问性override 方法和 virtual 方法必须具有相同的访问级别修饰符     

不能使用修饰符 newstaticvirtual 或 abstract 来修改 override 方法     

重写属性声明必须指定与继承属性完全相同的访问修饰符类型和名称并且被重写的属性必须是 virtualabstract 或 override 的     

标记允许被重写修饰静态方法中不允许使用virtual关键字成员变量允许使用virtual关键字     

属性可以被声明为虚属性(使用virtual关键字)     

重写基类的方法(重写同名的方法中有virtual关键字的方法)     

重写和隐藏的区别隐藏(new关键字)是给子类的同名方法分配新的内存空间重写(override关键字)是子类的同名方法放在基类同名方法的原来所在位置基类的同名方法位置向后移     

属性也可以重写    

virtual关键字和override关键字是成对出现的否则是语法错误     

派生类可以通过将重写声明为 sealed 来停止虚拟继承这需要在类成员声明中的 override 关键字前面放置 sealed 关键字     

在子类中重写基类中的虚方法时可以使用base关键字调用基类中的虚方法     

//使用base关键可以在子类中访问基类同名的方法     

//父类的引用指向子类的实例     

Test ts = new Test2();     

父类的引用指向子类的实例(调用的是子类的方法)    

父类的引用只认识父类的方法不认识子类的新方法可以用来调用被子类覆盖的父类的方法    

父类的引用依然到父类方法位置去调用如果基类方法被声明为virtual并且在子类中被override结果访问到的是被子类override的方法     

C#中的委托是什么?事件是不是一种委托?      

委托可以把一个方法作为参数代入另一个方法。委托可以理解为指向一个函数的引用。是,是一种特殊的委托  

C#中的堆和栈

栈(Stack)由系统管理生存期,存储代码执行和调用路径,执行或调用完毕即从栈中清除; 

堆(Heap)中保存值和对象,调用完毕之后依然存在,由垃圾回收器查找栈中有无指向该值或对象的引用,无则从堆中删除

C# ref与out区别: 

1、使用ref型参数时,传入的参数必须先被初始化。对out而言,必须在方法中对其完成初始化。

2、使用ref和out时,在方法的参数和执行方法时,都要加Ref或Out关键字。以满足匹配。

3、out适合用在需要retrun多个返回值的地方,而ref则用在需要被调用的方法修改调用者的引用的时候。

你对泛型了解吗?简单说明一下泛型的有什么好处?

泛型:通过参数化类型来实现在同一份代码上操作多种数据类型。利用“参数化类型”将类型抽象化,从而实现灵活的复用 

好处是——类型安全和减少装箱、拆箱。提高性能、类型安全和质量,减少重复性的编程任务 

C#中所有对象共同的基类是什么? 

System.Object. 

如何在C#中实现继承? 

在类名后加上一个冒号,再加上基类的名称。 

C#支持多重继承吗? 

不支持。可以用接口来实现。 

被protected修饰的属性/方法在何处可以访问? 

在继承或间接继承与这个类的子类中可以访问。 

私有成员会被继承么? 

会,但是不能被访问。所以看上去他们似乎是不能被继承的,但实际上确实被继承了。 

C#提供一个默认的无参构造函数,当我实现了另外一个有一个参数的构造函数时,还想保留这个无参数的构

造函数。这样我应该写几个构造函数? 

答:两个,一旦你实现了一个构造函数,C#就不会再提供默认的构造函数了,所以需要手动实现那个无参构造

函数。 

简述 private、 protected、 public、 internal 修饰符的访问权限。 

private : 私有成员, 在类的内部才可以访问。 

protected : 保护成员,该类内部和继承类中可以访问。 

public : 公共成员,完全公开,没有访问限制。 

internal: 在同一命名空间内可以访问。 

new的两种用法 

答:实例话对象,隐藏基类方法。

.new有几种用法 

第一种:new Class();

第二种:覆盖方法

public new XXXX(){}

第三种:new 约束指定泛型类声明中的任何类型参数都必须有公共的无参数构造函数。 

3.datagrid.datasouse可以连接什么数据源 [dataset,datatable,dataview]

dataset,datatable,dataview , IList 

类成员有( )种可访问形式

可访问性:public ,protected ,private,internal 

委托与事件的用法 

答:public delegate void handels();//返回值是void,没有参数 

public event handels eventHandels; 

his.eventHandels = new handels(fun); 

public void fun() 

   { }

传入某个属性的SET方法的隐含参数的名称是什么? 

答:value,它的类型和属性所声明的类型相同。 

string是值类型还是引用类型?

引用类型 

String类与StringBuilder类有什么区别?为什么在.Net类库中要同时存在这2个类?(简答)

stringBuilder比string更节约内存,所以stringBuilder更快

String 对象是不可改变的。每次使用 System.String 类中的方法之一或进行运算时(如赋值、拼接等)时,都要

在内存中创建一个新的字符串对象,这就需要为该新对象分配新的空间。而 StringBuilder 则不会。在需要对字

符串执行重复修改的情况下,与创建新的 String 对象相关的系统开销可能会非常昂贵。如果要修改字符串而不

创建新的对象,则可以使用 System.Text.StringBuilder 类。例如,当在一个循环中将许多字符串连接在一起时

,使用 StringBuilder 类可以提升性能。 

在C#中,string str = null 与 string str = “” 请尽量使用文字或图象说明其中的区别。 

答:string str = null 是不给他分配内存空间,而string str = "" 给它分配长度为空字符串的内存空间。 

ASP.net的身份验证方式有哪些?分别是什么原理? 

答:Windwos(默认)     用IIS...From(窗体)     用帐户....Passport(密钥)

Session有什么重大BUG,微软提出了什么方法加以解决? 

答:是iis中由于有进程回收机制,系统繁忙的话Session会丢失,可以用Sate server或SQL Server数据库的方式存储Session不过这种方式比较慢,而且无法捕获Session的END事件 

c#中的三元运算符是 ?: 

.能用foreach遍历访问的对象需要实现() 接口或声明 ( GetEnumerator)方法的类型。 

.<%# %> 和 <% %> 有什么区别?

<%# %>表示绑定的数据源 <% %>是服务器端代码块 常量 

在.net(C# or vb.net)中如何获得当前窗体或控件的句柄,特别是控件本身的句柄(请列举)

this(C#) Me(vb.net). 

.C#可否对内存进行直接的操作?

在.net下,.net引用了垃圾回收(GC)功能,它替代了程序员 不过在C#中,不能直接实现Finalize方法,而是在析构函数中调用基类的Finalize()方法 

DateTime是否可以为null? 不能,因为其为Struct类型,而结构属于值类型,值类型不能为null,只有引用类型才能被赋值null 

DateTime.Parse(myString); 这行代码有什么问题?

有问题,当myString不能满足时间格式要求的时候,会引发异常,建议使用DateTime.TryParse() 

net的错误处理机制是:

采用try->catch->finally结构, 

为什么不提倡catch(Exception) 

try..catch在出现异常的时候影响性能; 应该捕获更具体得异常,比如IOExeception,OutOfMemoryException等 

catch(Exception e){throw e;}和catch(Exception e){throw;}的区别

将发生的异常对象抛出,另一个只是抛出异常,并没有抛出原异常对象) 

error和exception区别:

error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。

exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。

GET与POST的区别 

在FORM提交的时候,如果不指定Method,则默认为GET请求,Form中提交的数据将会附加在url之后,以?分开与url分开。字母数字字符原样发送,但空格转换为“+“号,其它符号转换为%XX,其中XX为该符号以16进制表示的ASCII(或ISO Latin-1)值。GET请求请提交的数据放置在HTTP请求协议头中,而POST提交的数据则放在实体数据中;

在使用 POST 方法的情况下,传输数据时不会将数据作为 URL 的一部分;它们会作为一个独立的实体来传输。因此,POST 方法更安全,你也可以用这个方法传输更多的数据。而且用 POST 传输的数据不一定要是文本,用 GET 方法传输的却一定要是文本。

(1)get是从服务器上获取数据,post是向服务器传送数据。

(1)在客户端,Get方式在通过URL提交数据,数据在URL中可以看到;POST方式,数据放置在HTML HEADER内提交。

(2)对于get方式,服务器端用Request.QueryString获取变量的值,对于post方式,服务器端用Request.Form获取提交的数据。

(2)GET方式提交的数据最多只能有1024字节,而POST则没有此限制。

(3)安全性问题。正如在(1)中提到,使用 Get 的时候,参数会显示在地址栏上,而 Post 不会。所以,如果这些数据是中文数据而且是非敏感数据,那么使用 get;如果用户输入的数据不是中文字符而且包含敏感数据,那么还是使用 post为好。

Bind和Eval函数的区别

     绑定表达式 

       <%# Eval("字段名") %> 

      <%# Bind("字段名") %> 

1 Eval 单向绑定:数据是只读的 

   Bind 双向绑定:数据可以更改,并返回服务器端,服务器可以处理更改后的数据,如存入数据库. 

2.当对次表达式操作时候,必须用Eval 如<%# Eval("字段名").ToString().Trim() %> 

3 绑定控件的属性时要用Bind,而Eval则是其它一些。 

   例如:<asp:TextBox ID="First" RunAt="Server" Text='<%# Bind("FirstName") %>' /> 

   例如:<td><%# Eval("ProductID") %></td>

Response.Redirect和Server.Transfer 

请求的过程: 

1)浏览器aspx文件请求--->服务器执行--->遇到Response.Redirect语句->服务器发送Response.Redirect后面的地址给客户机端的浏览器--->浏览器请求执行新的地址 

2)浏览器aspx文件请求->服务器执行->遇到Server.Transfer语句->服务器转向新的文件 

可以见Server.Transfer比Response.Redirect少了一次服务器发送回来和客户端再请求的过程. 

跳转对象: 

1)Response.Redirect可以切换到任何存在的网页。 

2)Server.Transfer只能切换到同目录或者子目录的网页. 

数据保密: 

1、Response.Redirect后地址会变成跳转后的页面地址。 

2、Server.Transfer后地址不变,隐藏了新网页的地址及附带在地址后边的参数值。具有数据保密功能。 

传递的数据量(网址后附带的参数): 

1、Response.Redirect能够传递的数据以2KB(也就是地址栏中地址的最大的长度)为限。 

2、传递的数据超过2KB时,务必使用Server.Transfer。

Server.UrlEncode、HttpUtility.UrlDecode的区别 

Server.UrlEncode的编码方式是按照本地程序设置的编码方式进行编码的,而HttpUtility.UrlEncode是默认的按照.net的utf-8格式进行编码的。

Static 和 非Static的区别: 

一、用Static声明的方法和变量,不需要实例化该类就调用;

二、Static的,就一定要用实例化的对象来调用,即用new来实例化。

举例说:

如果有一个类People,有一个Static的方法MiaoShu(), 调用方法就是 People.MisoShu()

有一个非Static的方法getName(), 调用方法就是 People p= new People(); p.getName(); 

如何实现连接池

确保你每一次的连接使用相同的连接字符串(和连接池相同);只有连接字符串相同时连接池才会工作。如果连接字符串不相同,应用程序就不会使用连接池而是创建一个新的连接。

优点

使用连接池的最主要的优点是性能。创建一个新的数据库连接所耗费的时间主要取决于网络的速度以及应用程序和数据库服务器的(网络)距离,而且这个过程通常是一个很耗时的过程。而采用数据库连接池后,数据库连接请求可以直接通过连接池满足而不需要为该请求重新连接、认证到数据库服务器,这样就节省了时间。

缺点

数据库连接池中可能存在着多个没有被使用的连接一直连接着数据库(这意味着资源的浪费)。

技巧和提示

1. 当你需要数据库连接时才去创建连接池,而不是提前建立。一旦你使用完连接立即关闭它,不要等到垃圾收集器来处理它。

2. 在关闭数据库连接前确保关闭了所有用户定义的事务。

3. 不要关闭数据库中所有的连接,至少保证连接池中有一个连接可用。如果内存和其他资源是你必须首先考虑的问题,可以关闭所有的连接,然后在下一个请求到来时创建连接池。

连接池FAQ

1. 何时创建连接池?

当第一个连接请求到来时创建连接池;连接池的建立由数据库连接的连接字符创来决定。每一个连接池都与一个不同的连接字符串相关。当一个新的连接请求到来时如果连接字符串和连接池使用的字符串相同,就从连接池取出一个连接;如果不相同,就新建一个连接池。

2. 何时关闭连接池?

当连接池中的所有连接都已经关闭时关闭连接池。

3. 当连接池中的连接都已经用完,而有新的连接请求到来时会发生什么?

当连接池已经达到它的最大连接数目时,有新的连接请求到来时,新的连接请求将放置到连接队列中。当有连接释放给连接池时,连接池将新释放的连接分配给在队列中排队的连接请求。你可以调用close和dispose将连接归还给连接池。

4. 我应该如何允许连接池?

对于.NET应用程序而言,默认为允许连接池。(这意味着你可以不必为这件事情做任何的事情)当然,如果你可以在SQLConnection对象的连接字符串中加进Pooling=true;确保你的应用程序允许连接池的使用。

5. 我应该如何禁止连接池?

ADO.NET默认为允许数据库连接池,如果你希望禁止连接池,可以使用如下的方式:

1) 使用SQLConnection对象时,往连接字符串加入如下内容:Pooling=False;

2) 使用OLEDBConnection对象时,往连接字符串加入如下内容:OLE DB Services=-4;

提高.NET的性能 

1 使用异步方式调用Web服务和远程对象

只要有可能就要避免在请求的处理过程中对Web服务和远程对象的同步调用,因为它占用的是的ASP.NET 线程池中的工作线程,这将直接影响Web服务器响应其它请求的能力。

2 使用适当的Caching策略来提高性能

3 判断字符串,不要用""比较。

//避免 

if(strABC!=null && strABC!="") 

{}

//推荐 

if(!strABC.IsNullOrEmpty) 

{}

4 页面优化

5 用完马上关闭数据库连接 

6 尽量使用存储过程,并优化查询语句 

7 只读数据访问用SqlDataReader,不要使用DataSet

……….

.UDP连接和TCP连接的异同 

答:前者只管传,不管数据到不到,无须建立连接.后者保证传输的数据准确,须要连结. 

请解释转发与跳转的区别 

转发就是服务端的跳转A页面提交数据到B页面,B页面进行处理然后从服务端跳转到其它页面 

跳转就是指客户端的跳转

简述你对XML Web Service的原理的认识? 

答:利用SOAP(简单对象访问协议)在http上执行远程方法的调用,也可以使用WSDL(Web服务描述语言)来

完成完整的描述Web服务,然后用UDDI注册各个服务提供商提供的服务,以便共享他们。

什么叫应用程序域? 

答:应用程序域可以理解为一种轻量级进程。起到安全的作用。占用资源小。

CTS、CLS、CLR分别作何解释? 

答:CTS:通用语言系统。CLS:通用语言规范。CLR:公共语言运行库。

什么是受管制的代码? 

答:unsafe:非托管代码。不经过CLR运行。

什么是强类型系统? 

答:RTTI:类型识别系统。

什么是code-behind技术 

codebehind是指代码和用户界面分开 

aspx and cs

在.net中,配件的意思是? 

答:程序集。(中间语言,源数据,资源,装配清单)

常用的调用WebService的方法有哪些? 

答:1.使用WSDL.exe命令行工具。 

   2.使用VS.NET中的Add Web Reference菜单选项

net Remoting 的工作原理是什么? 

答:服务器端向客户端发送一个进程编号,一个程序域编号,以确定对象的位置。

O/R Mapping 的原理 

答:利用反射,配置将对象和数据库表映射

remoting和webservice两项技术的理解以及实际中的应用。 

答:WS主要是可利用HTTP,穿透防火墙。而Remoting可以利用TCP/IP,二进制传送提高效率。

out保留字怎么使用,什么时候使用 

答:有时为了从一个函数中返回多个值,我们需要使用out关键字,把输出值赋给通过引用传递给方法的变量(也就是参数)。但C#要求变量再被引用的前必须初始化。在调用该方法时,还需要添加out关键字

PDB是什么东西? 在调试中它应该放在哪里?

PDB是用于保存调试和项目状态信息的文件,在debug的时候将产生pdb文件,调试的时候应该放在和对应应用

程序集相同目录。

使用ASMX的XML Web服务与使用SOAP的.NET Remoting的区别?

Web服务使用的消息机制,而Remoting采用的RPC. Web Service能用于不同平台,不同语言,Remoting只适用

于.Net。效率上Remoting高于Xml Web Service

类型系统是由XMLSchema表示的吗?CLS是XMLSchema表示的吗?

不清楚

从概念上阐述前期绑定(early-binding)和后期绑定(late-binding)的区别?

这个就像是强弱类型的比较相似,前期绑定是在编译的时候就确定了要绑定的数据,而后期绑定是在运行的时候

才填充数据。所以前期绑定如果失败,会在编译时报编译错误,而后期绑定失败只有在运行时的时候才发生

调用Assembly.Load算静态引用还是动态引用?

动态

 列举一下你所了解的XML技术及其应用 

答:保存配置,站与站之间的交流,WEB SERVICE。以及与数据库的数据交互等地方都要用它. 

7.如何理解委托? 

答: 

相当于函数指针,定义了委托就可以在不调用原方法名称的情况下调用那个方法. 

委托具有以下特点: 

委托类似于 C++ 函数指针,但它是类型安全的。 

委托允许将方法作为参数进行传递。 

委托可用于定义回调方法。 

委托可以链接在一起;例如,可以对一个事件调用多个方法。 

方法不需要与委托签名精确匹配。有关更多信息,请参见协变和逆变。 

C# 2.0 版引入了匿名方法的概念,此类方法允许将代码块作为参数传递,以代替单独定义的方法。

概述反射和序列化

反射:程序集包含模块,而模块包含类型,类型又包含成员。反射则提供了封装程序集、模块和类型的对

象。您可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,

可以调用类型的方法或访问其字段和属性

序列化:序列化是将对象转换为容易传输的格式的过程。例如,可以序列化一个对象,然后使用 HTTP 通

过 Internet 在客户端和服务器之间传输该对象。在另一端,反序列化将从该流重新构造对象。

11) XmlSerializer是如何工作的?使用这个类的进程需要什么ACL权限?

我只知道XmlSerializer是将对象的属性和字段进行序列化和反序列化的,序列化成为xml数据,反序列化再将xml

转换成对象。应该至少需要ACL权限中的读权限.

23)XmlSerializer使用的针对属性的模式有什么好处?解决了什么问题?

只序列化有用的数据,而不是序列化整个对象。实现没必要的数据冗余,和提升序列化时的性能。

26.根据委托(delegate)的知识,请完成以下用户控件中代码片段的填写: 

namespace test
{
    public delegate void OnDBOperate();
    public class UserControlBase : System.Windows.Forms.UserControl
    {
        public event OnDBOperate OnNew;
        privatevoidtoolBar_ButtonClick(objectsender,System.Windows.Forms.ToolBarButtonClickEventArgs e)
        {
            if(e.Button.Equals(BtnNew))
            {
            //请在以下补齐代码用来调用OnDBOperate委托签名的OnNew事件。
            }
        }
    }
}

答:if( OnNew != null )  

   OnNew( this, e );

27.分析以下代码,完成填空 

string strTmp = "abcdefg某某某"; 

int i= System.Text.Encoding.Default.GetBytes(strTmp).Length; 

int j= strTmp.Length; 

以上代码执行完后,i= j= 

答:i=13,j=10

28.SQLSERVER服务器中,给定表 table1 中有两个字段 ID、LastUpdateDate,ID表示更新的事务号,

LastUpdateDate表示更新时的服务器时间,请使用一句SQL语句获得最后更新的事务号 

答:Select ID FROM table1 Where LastUpdateDate = (Select MAX(LastUpdateDate) FROM table1)

29.根据线程安全的相关知识,分析以下代码,当调用test方法时i>10时是否会引起死锁?并简要说明理由。 

public void test(int i)
{
    lock(this)
    {
        if (i>10)
        {
            i--;
            test(i);
        }
    }
} 

答:不会发生死锁,(但有一点int是按值传递的,所以每次改变的都只是一个副本,因此不会出现死锁。但如果

把int换做一个object,那么死锁会发生)

3) 什么叫圈复杂度(cyclomatic complexity)?为什么它很重要?

不知道,望指教 ?

4) 写一个标准的lock(),在访问变量的前后创建临界区,要有"双重检查",

见:评论回复

5) 什么叫FullTrust?放入GAC的assembly是否是FullTrust的?

FullTrust完全信任。放入GAC中的Assembly是否FullTrust我的理解不是。我理解FullTrust是可以通过代码设定的

6) 代码加上需要安全权限的特性有什么好处?

可以更加灵活的设置对代码的访问权限,实现代码级保护。?这点不是特清楚,有明白的给讲解下

7) gacutil /l | find /i "Corillian" 这句命令的作用是什么?

全局程序集缓存中如果有Corillian就更新该程序集,没有就安装

8) sn -t foo.dll 这句命令是干嘛的?

显示程序集foo.dll的公钥标记

9) DCOM需要防火墙打开哪些端口?端口135是干嘛用的?

135端口,因为DCOM的端口号是随机分配的,默认情况下,会分配1024以上的端口号,所以默认情况下,DCOM

不能穿越防火墙。因为根本不晓得开哪个端口。但有解决办法可以使DCOM分配的端口号固定,135是远程过程

调用(RPC)的默认端口

10)对比OOP和SOA,它们的目的分别是什么?

我想OOP和SOA应该没有对比性吧。OOP是一种编程模型,强调将复杂的逻辑分解出小的模块,特性是继承,封

装和多态 。而SOA是一个技术框架,技术框架和编程模型应该说不是一码事吧?SOA的思想是将业务逻辑封装

成服务或者中间件提供给应用程序来调用,当然其组件化思想是继承和发扬了OOP的优点。

13)Debug.Write和Trace.Write有什么不同?何时应该使用哪一个?

Debug.Write是调试的时候向跟踪窗口输出信息。当编译模式为debug的时候才有效,为release的时

候Debug.Write在编译的时候会忽略,而Trace则是在debug和release两种模式下均可以向跟踪窗口输出信息。

14)Debug Build和Release Build的区别,是否会有明显的速度变化?请说明理由。

Debug会产生pdb文件,release不会。Debug用于开发时的调试,不能要于部署,而release用于部署.debug编

译一些特殊代码,比如#IFDEBUG Debug.Write等,而Release则会将那些特殊标记省略

15)JIT是以assembly为单位发生还是以方法为单位发生?这对于工作区有何影响?

方法,道理很简单,因为对于一次运行,很可能只用到一个程序集中极少数类型和对象,而大部分可能并不会被

使用,此时CLR傻乎乎的给整个程序集都给Compile了,CLR不是傻疯了么 

17)a.Equals(b)和a == b一样吗?

不一样。a.Equals(b)表示a与b一致, a==b表示a与b的值相等

18)在对象比较中,对象一致和对象相等分别是指什么?

对象一致是指两个对象是同一个对象,引用相同。而对象相等是指两个对象的值相同,但引用不一定相同

19)在.NET中如何实现深拷贝(deep copy)?

实现IClonable接口

20)请解释一下IClonable

IClonable方法是实现深度复制的接口,实现它应该能深度复制一个对象出来。深度复制的特征的调用对象的构造

方法,创建新的对象,包括创建对象中嵌套的引用对象的新实例。而Shadow复制则不同,是浅表复制,不重新

创建新实例。浅表复制的实现是Object.MemberWiseClone().

深度复制(Deep Copy)与浅表复制(Shadow Copy)的比较 

 public class Name
{
    public string FirstName;
    public string LastName;
}
public class Person:ICloneable
{
    public Name PersonName;
    public string Email;
    /**//// <summary> 
    /// Deep Copy的例子 
    /// </summary> 
    /// <returns></returns> 
    public Object Clone()
    {
        Person p = new Person();
        p.Email = this.Email;
        p.PersonName = new Name();
        p.PersonName.FirstName = this.PersonName.FirstName;
        p.PersonName.LastName = this.PersonName.LastName;
        return p;
    }
    public void ChangLastName(string lastName)
    {
        this.PersonName.LastName = lastName;
    }
    public static void Main()
    {
        Person p = new Person();
        p.PersonName = new Name();
        p.PersonName.LastName = "jill";
        p.PersonName.FirstName = "zhang";
        p.Email = "jillzhang@126.com";
        Person sameNamePerson = p.Clone() as Person;
        sameNamePerson.ChangLastName("clr_");
        Console.WriteLine(p.PersonName.LastName);
        Console.WriteLine(sameNamePerson.PersonName.LastName);
        Person samePerson = p.MemberwiseClone() as Person;
        samePerson.ChangLastName("Shadow");
        Console.WriteLine(p.PersonName.LastName);
        Console.WriteLine(sameNamePerson.PersonName.LastName);
        Console.Read();
    }
}

24)为什么不应该在.NET中使用out参数?它究竟好不好?

我挺喜欢用out参数的,特别是当函数需要有多于1个返回的时候,我比较愿意用out,至于它好不好没研究过 ?

25)特性能够放到某个方法的参数上?如果可以,这有什么用?

可以,作用可以对参数有进一步限定,比如输入参数为int类型,可以通过允许AttributeTargets=ParameterInfo

的Attribute自定义实现来限定输入参数的大小,比如当输入参数小于100的时候便抱错。

对方法的参数设置Attribute的例子 

 [AttributeUsage(AttributeTargets.Parameter)] 
   public class ParameterAtt : Attribute 
   { 
       public int Min = 100; 
   }
   public class AttributeTest 
   {       
       public void TestMethod([ParameterAtt(Min = 100)] int par1) 
       { 
           ParameterInfo para = MethodInfo.GetCurrentMethod().GetParameters()[0]; 
           ParameterAtt att = ParameterAtt.GetCustomAttribute(para, typeof(ParameterAtt)) as
ParameterAtt; 
           if (att.Min > par1) 
           { 
               throw new Exception("要求para1最小为" + att.Min); 
           } 
       } 
   }

9.执行下面代码后:

String strTemp ="abcdefg 某某某";

Int i System.Text.Encoding.Default.GetBytes(strTemp).Length;

Int j = strTemp.Length;

问:i=(14 ) ;j=(11 )

i=(14 ) ;j=(11 ) 中文两个字节

12.概述.NET里对 remoting 和 webservice 两项技术的理解和实际中的应用。

远程逻辑调用,remoing接口只能用在.net中

9. 如何给服务器端控件增加客户端脚本。 

答:控件的Attributes

6. 私有程序集与共享程序集有什么区别? 

一个私有程序集通常为单个应用程序所使用,并且存储于这个应用程序所在的目录之中,或此目录下面的一个子

目录中。共享程序集通常存储在全局程序集缓存(Global Assembly Cache)之中,这是一个由.NET运行时所维

护的程序集仓库。共享程序集通常是对许多应用程序都有用的代码库,比如.NET Framework类。

10 .请解释ASP.NET中以什么方式进行数据验证 

Aps.net 中有非空验证,比较验证,取值范围验证,正则表达式验证及客户自定义验证五大控件,另还有一个集

中验证信息处理控件

11.WEB控件可以激发服务端事件,请谈谈服务端事件是怎么发生并解释其原理?自动传回是什么?为什么要

使用自动传回。 

在web控件发生事件时,客户端采用提交的形式将数据交回服务端,服务端先调用Page_Load事件,然后根据传

回的状态信息自动调用服务端事件自动传回是当我们在点击客户端控件时,采用提交表单的形式将数据直接传回

到务端 

只有通过自动传回才能实现服务端事件的机制,如果没有自动回传机制就只能调用客户端事件,而不能调用服务

端事件

13. 请解释web.config文件中的重要节点 

appSettings包含自定义应用程序设置。 

system.web 系统配置 

compilation动态调试编译设置 

customErrors自定义错误信息设置 

authentication身份验证,此节设置应用程序的身份验证策略。 

authorization授权, 此节设置应用程序的授权策略.

14. 请解释ASP。NET中的web页面与其隐藏类之间的关系? 

一个ASP.NET页面一般都对应一个隐藏类,一般都在ASP.NET页面的声明中指定了隐藏类例如一个页面Tst1.aspx

的页面声明如下 

<%@ Page language="c#" Codebehind="Tst1.aspx.cs" AutoEventWireup="false" Inherits="T1.Tst1" %> 

Codebehind="Tst1.aspx.cs" 表明经编译此页面时使用哪一个代码文件 

Inherits="T1.Tst1" 表用运行时使用哪一个隐藏类

15. 什么是viewstate,能否禁用?是否所用控件都可以禁用? 

Viewstate是保存状态的一种机制,EnableViewState属性设置为false即可禁用

16. 当发现不能读取页面上的输入的数据时很有可能是什么原因造成的?怎么解决? 

很有可能是在Page_Load中数据处理时没有进行Page的IsPostBack属性判断

17. 请解释什么是上下文对象,在什么情况下要使用上下文对象 

上下文对象是指HttpContext类的Current 属性,当我们在一个普通类中要访问内置对

象(Response,Request,Session,Server,Appliction等)时就要以使用此对象

16、解释一下ajax及实现原理 

答:Ajax的核心是JavaScript对象XmlHttpRequest,它使您可以使用JavaScript向服务器提出请求并处理响应, 而不阻塞用户,异步请求。

1、delegate是引用类型还是值类型?enum、int[]和string呢(难度系数40%)?

答案:delegate引用类型,enum值类型,int[]引用类型,string引用类型。

3、base这个关键字有哪几种语法?override呢?

答案:base两个语法,分别是调用基类构造函数和调用基类方法,override用于重写基类方法。

4、请指出C#中是否有下列关键字?virtual、sealed、abstract、import、as、in、goto、final、Const、signed、

String(提示,仅指出C#中没有的即可)(难度系数50%)。

答案:没有的关键字:import、final、Const、signed、String

5、在循环:for( int i = 0; i < 100; i++ ) Console.WriteLine( i );中,请指出i++的执行时机。

答案:在Console.WriterLine( i );执行之后

6、试说明continue关键字的用处。

答案:马上开始下一次循环,忽略循环体余下的语句

7、object是C#的关键字吗?请指出C#中有哪些类型关键字,如int、float。(提示,写得越多越好)。

答案:是,object、int、uint、long、ulong、short、ushort、byte、sbyte、char、float、double、decimal、boo

l,如回答:enum、struct、class、delegate也算对。

8、C#的XML文档注释中(以///开头的注释),<summary>标签用于描述什么?<param>标签呢?

答案:<summary>用于某个元素的概要说明,<param>用于某个方法的参数概要说明。

9、我们知道[]是数组和索引器的访问操作符,但它还有一个语法,是什么?

答案:特性(Attribute)

18.请叙述属性与索引器的区别。 

属性 索引器     

 通过名称标识。 通过签名标识。     

 通过简单名称或成员访问来访问。 通过元素访问来访问。     

 可以为静态成员或实例成员。 必须为实例成员。     

 属性的  get  访问器没有参数。 索引器的  get  访问器具有与索引器相同的形参表。     

 属性的  set  访问器包含隐式  value  参数。 除了  value  参数外,索引器的  set  访问器还具有与索引

器相同的形参表。

1) 描述线程与进程的区别?

线程(Thread)与进程(Process)二者都定义了某种边界,不同的是进程定义的是应用程序与应用程序之间的边

界,不同的进程之间不能共享代码和数据空间,而线程定义的是代码执行堆栈和执行上下文的边界。一个进程可

以包括若干个线程,同时创建多个线程来完成某项任务,便是多线程。而同一进程中的不同线程共享代码和数据

空间。用一个比喻来说,如果一个家庭代表一个进程,在家庭内部,各个成员就是线程,家庭中的每个成员都有

义务对家庭的财富进行积累,同时也有权利对家庭财富进行消费,当面对一个任务的时候,家庭也可以派出几个

成员来协同完成,而家庭之外的人则没有办法直接消费不属于自己家庭的财产。

2) 什么是Windows服务,它的生命周期与标准的EXE程序有什么不同

Windows服务是运行在windows后台指定用户下(默认System)的应用程序,它没有标准的UI界面,想比标准

的EXE程序,Windows服务是在服务开始的时候创建,而在服务结束的时候销毁,而且可以设置服务是否与操作

系统一起启动,一起关闭。它支持三种方式:1)自动方式 2)手动方式 3)禁用 。自动方式的时

候,windows服务将在OS启动后自动启动运行,而手动方式则必须手工启动服务,禁用的情况下服务将不能被

启动。另外标准的EXE默认使用的当前登录的用户,而windows服务则默认使用System用户,这在对系统资源访

问的时候特别需要注意。

3) Windows单个进程所能访问的最大内存量是多少?它与系统的最大虚拟内存一样吗?这对于系统设计有什么

影响?

这个需要针对硬件平台,公式为单个进程能访问的最大内存量=2的处理器位数次方/2,比如通常情况下,32位

处理器下,单个进程所能访问的最大内存量为:232 /2 = 2G 。单个进程能访问的最大内存量是最大虚拟内存

的1/2,因为要分配给操作系统一半虚拟内存。

4) 什么是强类型,什么是弱类型?哪种更好些?为什么?

强类型是在编译的时候就确定类型的数据,在执行时类型不能更改,而弱类型在执行的时候才会确定类型。没有

好不好,二者各有好处,强类型安全,因为它事先已经确定好了,而且效率高。一般用于编译型编程语

言,如c++,java,c#,pascal等,弱类型相比而言不安全,在运行的时候容易出现错误,但它灵活,多用于解释型编

程语言,如javascript,vb等

5) PID是什么?在做系统的故障排除时如何使用它?

PID是进程编号,在系统发现故障的时候,可以根据它寻找故障所发生的具体进程,并且可通过visual studio.net

等ide将故障进程附加到进程中进行调试(debug)

6) 单个TCP/IP端口上能够被多少个进程侦听?

1个

7) 什么是GAC?它解决了什么问题?

Gloal Assembly Cache,全局应用程序集缓存。它解决了几个程序共享某一个程序集的问题。不必再将那个被共

享的程序集拷贝到应用程序目录了,其实这道理很简单,.net应用程序在加载的时候,会首先查看全局应用程序

集缓存,如果有就可以直接使用,没有再到应用程序目录进行查找。

1.白盒测试和黑盒测试 

答:黑盒测试:已知产品的功能设计规格,可以进行测试证明每个实现了的功能是否符合要求。

白盒测试:已知产品的内部工作过程,可以通过测试证明每种内部操作是否符合设计规格要求,所有内部成

分是否以经过检查。

软件的黑盒测试意味着测试要在软件的接口处进行。这种方法是把测试对象看做一个黑盒子,测试人员完全

不考虑程序内部的逻辑结构和内部特性,只依据程序的需求规格说明书,检查程序的功能是否符合它的功能说明

。因此黑盒测试又叫功能测试或数据驱动测试。黑盒测试主要是为了发现以下几类错误:

1、是否有不正确或遗漏的功能?

2、在接口上,输入是否能正确的接受?能否输出正确的结果?

3、是否有数据结构错误或外部信息(例如数据文件)访问错误?

4、性能上是否能够满足要求?

5、是否有初始化或终止性错误?

软件的白盒测试是对软件的过程性细节做细致的检查。这种方法是把测试对象看做一个打开的盒子,它允许

测试人员利用程序内部的逻辑结构及有关信息,设计或选择测试用例,对程序所有逻辑路径进行测试。通过在不

同点检查程序状态,确定实际状态是否与预期的状态一致。因此白盒测试又称为结构测试或逻辑驱动测试。白盒

测试主要是想对程序模块进行如下检查:

1、对程序模块的所有独立的执行路径至少测试一遍。

2、对所有的逻辑判定,取“真”与取“假”的两种情况都能至少测一遍。

3、在循环的边界和运行的界限内执行循环体。

4、测试内部数据结构的有效性,等等。

请简述一下用Socket进行同步通讯编程的详细步骤 

1、在应用程序和远程设备中使用协议和网络地址初始化套接字 

2、在应用程序中通过指定端口和地址建立监听 

3、远程设备发出连接请求 

4、应用程序接受连接产生通信scoket 

5、应用程序和远程设备开始通讯(在通讯中应用程序将挂起直到通讯结束) 

6、通讯结束,关闭应用程序和远程设备的Socket回收资源

OSI网络结构的七层模型及其核心思想是什么 

第七层:应用层  

    定义了用于在网络中进行通信和数据传输的接口 - 用户程式;  

    提供标准服务,比如虚拟终端、文件以及任务的传输和处理; 

第六层:表示层 

   掩盖不同系统间的数据格式的不同性; 

   指定独立结构的数据传输格式; 

   数据的编码和解码;加密和解密;压缩和解压缩 

第五层:会话层 

   管理用户会话和对话; 

   控制用户间逻辑连接的建立和挂断; 

   报告上一层发生的错误 

第四层:传输层 

   管理网络中端到端的信息传送; 

   通过错误纠正和流控制机制提供可靠且有序的数据包传送; 

   提供面向无连接的数据包的传送; 

第三层:网络层 

   定义网络设备间如何传输数据; 

   根据唯一的网络设备地址路由数据包; 

   提供流和拥塞控制以防止网络资源的损耗 

第二层:数据链路层  

   定义操作通信连接的程序;  

   封装数据包为数据帧;  

   监测和纠正数据包传输错误 

第一层:物理层  

   定义通过网络设备发送数据的物理方式;  

   作为网络媒介和设备间的接口; 

   定义光学、电气以及机械特性。

2 几十上百万行,如何快速查询出表数据 

答:用分页存储过程 

/* 
 函数名称: GetRecordFromPage 
 函数功能: 获取指定页的数据 
 参数说明: @tblName     包含数据的表名 
          @fldName     关键字段名 
          @PageSize    每页记录数 
          @PageIndex   要获取的页码 
          @OrderType   排序类型, 0 - 升序, 1 - 降序 
          @strWhere    查询条件 (注意: 不要加 where) 
*/ 
CREATE PROCEDURE GetRecordFromPage 
   @tblName     varchar(255),      -- 表名 
   @fldName     varchar(255),      -- 字段名 
   @PageSize    int = 10,          -- 页尺寸 
   @PageIndex   int = 1,           -- 页码 
   @OrderType   bit = 0,           -- 设置排序类型, 非 0 值则降序 
   @strWhere    varchar(2000) = '' -- 查询条件 (注意: 不要加 where) 
AS
declare @strSQL  varchar(6000)      -- 主语句 
declare @strTmp  varchar(1000)      -- 临时变量 
declare @strOrder varchar(500)       -- 排序类型
if @OrderType != 0 
begin 
   set @strTmp = '<(select min' 
   set @strOrder = ' order by [' + @fldName + '] desc' 
end 
else 
begin 
   set @strTmp = '>(select max' 
   set @strOrder = ' order by [' + @fldName +'] asc' 
end
set @strSQL = 'select top ' + str(@PageSize) + ' * from [' 
   + @tblName + '] where [' + @fldName + ']' + @strTmp + '([' 
   + @fldName + ']) from (select top ' + str((@PageIndex-1)*@PageSize) + ' [' 
   + @fldName + '] from [' + @tblName + ']' + @strOrder + ') as tblTmp)' 
   + @strOrder
if @strWhere != '' 
   set @strSQL = 'select top ' + str(@PageSize) + ' * from [' 
       + @tblName + '] where [' + @fldName + ']' + @strTmp + '([' 
       + @fldName + ']) from (select top ' + str((@PageIndex-1)*@PageSize) + ' [' 
       + @fldName + '] from [' + @tblName + '] where ' + @strWhere + ' ' 
       + @strOrder + ') as tblTmp) and ' + @strWhere + ' ' + @strOrder
if @PageIndex = 1 
begin 
   set @strTmp = '' 
   if @strWhere != '' 
       set @strTmp = ' where (' + @strWhere + ')'
   set @strSQL = 'select top ' + str(@PageSize) + ' * from [' 
       + @tblName + ']' + @strTmp + ' ' + @strOrder 
end
exec (@strSQL)

三、数据库查询优化: 

1、多态性,多种数据库兼容; 

2、支持翻页,支持查询总数,页码显示; 

3、能处理100万以上数据量; 

答: 

CREATE  PROCEDURE  dbo.LSP_SP_SelectElementByPage       
 @SelectFields  varchar(200),/*要查询的字段列表*/   
 @Condition  varchar(300),/*查询条件*/   
 @PageSize  int  =20,/*页面大小,默认为20*/   
 @PageNumber  int  =1/*页号,默认为第一页*/   
 /*@PageCount  int  out返回满足条件的总页数*/   
 AS   
 begin   
 declare  @count  int   
 select  @count  =count(*)  from  lsp_t_elementInfo   
 if(@count  %@PageSize=0)   
 set  @count  =  @count/@PageSize   
 else   
 set  @count  =  @count/@PageSize  +1   
 select  @count  PageCount   
 select  IDENTITY(int,1,1)  as  iid,ElementName,Type  into  #temptable  from  LSP_T_ElementInfo   
 select    *  from  #temptable  where  iid  between    @PageSize  *  (@PageNumber  -1)  and  @PageSize  *  @PageNumber   
 end   

1.两个表,写查询语句,根据两个字段一个是升序,一个将序。 

答:select * from a,b where a.字段1 = b.字段1 order by a.字段2 asc,b.字段2 desc 

2.根据第一题,每页面显示10条记录,在第25页时怎样显示 

答: 

/* 
 函数名称: GetRecordFromPage 
 函数功能: 获取指定页的数据 
 参数说明: @tblName     包含数据的表名 
          @fldName     关键字段名 
          @PageSize    每页记录数 
          @PageIndex   要获取的页码 
          @OrderType   排序类型, 0 - 升序, 1 - 降序 
          @strWhere    查询条件 (注意: 不要加 where) 
*/ 
CREATE PROCEDURE GetRecordFromPage 
   @tblName     varchar(255),      -- 表名 
   @fldName     varchar(255),      -- 字段名 
   @PageSize    int = 10,          -- 页尺寸 
   @PageIndex   int = 1,           -- 页码 
   @OrderType   bit = 0,           -- 设置排序类型, 非 0 值则降序 
   @strWhere    varchar(2000) = '' -- 查询条件 (注意: 不要加 where) 
AS
declare @strSQL  varchar(6000)      -- 主语句 
declare @strTmp  varchar(1000)      -- 临时变量 
declare @strOrder varchar(500)       -- 排序类型
if @OrderType != 0 
begin 
   set @strTmp = '<(select min' 
   set @strOrder = ' order by [' + @fldName + '] desc' 
end 
else 
begin 
   set @strTmp = '>(select max' 
   set @strOrder = ' order by [' + @fldName +'] asc' 
end
set @strSQL = 'select top ' + str(@PageSize) + ' * from [' 
   + @tblName + '] where [' + @fldName + ']' + @strTmp + '([' 
   + @fldName + ']) from (select top ' + str((@PageIndex-1)*@PageSize) + ' [' 
   + @fldName + '] from [' + @tblName + ']' + @strOrder + ') as tblTmp)' 
   + @strOrder
if @strWhere != '' 
   set @strSQL = 'select top ' + str(@PageSize) + ' * from [' 
       + @tblName + '] where [' + @fldName + ']' + @strTmp + '([' 
       + @fldName + ']) from (select top ' + str((@PageIndex-1)*@PageSize) + ' [' 
       + @fldName + '] from [' + @tblName + '] where ' + @strWhere + ' ' 
       + @strOrder + ') as tblTmp) and ' + @strWhere + ' ' + @strOrder
if @PageIndex = 1 
begin 
   set @strTmp = '' 
   if @strWhere != '' 
       set @strTmp = ' where (' + @strWhere + ')'
   set @strSQL = 'select top ' + str(@PageSize) + ' * from [' 
       + @tblName + ']' + @strTmp + ' ' + @strOrder 
end
exec (@strSQL)

2.写出一条Sql语句: 取出表A中第31到第40记录(SQLServer, 以自动增长的ID作为主键, 注意:ID可能不是连续的。) 

select top 10 * from A where id not in (select top 30 id from A) 

解2: select top 10 * from A where id > (select max(id) from (select top 30 id from A )as A)

3.public class c{ public c(string a) : this() {;}; public c() {;} } 解释第一个构造函数中发生了什么?这个构造函数有什么用? 

(第一个构造函数调用了第二个构造函数,这个构造函数构造了一个c对象的实例。)

4.一个长度为10000的字符串,通过随机从a-z中抽取10000个字符组成。请用c#语言编写主要程序来实现。 

答: 

using System.Text;
StringBuilder sb = new StringBuilder(0, 10000);
string strABC = "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z";
string[] ABC = strABC.Split(',');
int len = ABC.Length;
Random rd = new Random();
for (int i = 0; i < 10000; i++)
{
    sb.Append(ABC[rd.Next(len)]);
}

5.产生一个int数组,长度为100,并向其中随机插入1-100,并且不能重复。 

int[] intArr=new int[100];
ArrayList myList=new ArrayList();
Random rnd=new Random();
while(myList.Count<100)
{
    int num=rnd.Next(1,101);
    if(!myList.Contains(num))
    myList.Add(num);
}
for(int i=0;i<100;i++)
    intArr[i]=(int)myList[i];

2.如何把一个Array复制到ArrayList里 

答: 

foreach( object o in array )arrayList.Add(o);

8.用C#写一段选择排序算法,要求用自己的编程风格。 

答:private int min; 

public void xuanZhe(int[] list)//选择排序
{
    for (int i = 0; i < list.Length - 1; i++)
    {
        min = i;
        for (int j = i + 1; j < list.Length; j++)
        {
            if (list[j] < list[min])
            min = j;
        }
        int t = list[min];
        list[min] = list[i];
        list[i] = t;
    }
}

4.写一个函数计算当参数为N的值:1-2+3-4+5-6+7……+N 

答:

public int returnSum(int n)
{
    int sum = 0;
    for (int i = 1; i <= n; i++)
    {
        int k = i;
        if (i % 2 == 0)
        {
            k = -k;
        }
        sum = sum + k;
    }
    return sum;
}
public int returnSum1(int n)
{
    int k = n;
    if (n == 0)
    {
        return 0;
    }
    if (n % 2 == 0)
    {
        k = -k;
    }
    return aaa(n - 1) + k;
}

7. 某一密码仅使用K、L、M、N、O共5个字母,密码中的单词从左向右排列,密码单词必须遵循如下规则 : 

(1) 密码单词的最小长度是两个字母,可以相同,也可以不同 

(2) K不可能是单词的第一个字母 

(3) 如果L出现,则出现次数不止一次 

(4) M不能使最后一个也不能是倒数第二个字母 

(5) K出现,则N就一定出现 

(6) O如果是最后一个字母,则L一定出现 

问题一:下列哪一个字母可以放在LO中的O后面,形成一个3个字母的密码单词? 

A) K B)L C) M D) N 

答案:B 

问题二:如果能得到的字母是K、L、M,那么能够形成的两个字母长的密码单词的总数是多少? 

A)1个 B)3个 C)6个 D)9个 

答案:A 

问题三:下列哪一个是单词密码? 

A) KLLN B) LOML C) MLLO D)NMKO 

答案:C

62-63=1 等式不成立,请移动一个数字(不可以移动减号和等于号),使得等式成立,如何移动? 

答案:62移动成2的6次方

17、列出常用的使用javascript操作xml的类包 

答: 

XML.prototype.xmlDoc = new ActiveXObject("Microsoft.XMLDOM")
XML.prototype.InitXML=InitXML
XML.prototype.getFirstChild=getFirstChild
XML.prototype.getLastChild=getLastChild
XML.prototype.getChild=getChild;     // 取得节点值 
XML.prototype.getNodeslength=getNodeslength;  // 最得节点下的子节点的个数 
XML.prototype.getNode=getNode;      // 取得指定节点 
XML.prototype.delNode=delNode;      // 删除指定节点,如果节点相同,则删除最前面的节点. 
XML.prototype.getNodeAttrib=getNodeAttrib;   // 取得节点的指定属性值. 
XML.prototype.InsertBeforeChild=InsertBeforeChild; // 在指定节点之前插入一个节点. 
XML.prototype.InsertChild=InsertChild;    // 在指定节点下插入节点. 
XML.prototype.setAttrib=setAttrib;     // 设置指定属性的值. 
XML.prototype.setNodeValue=setNodeValue;   // 设置指定节点的值. 
XML.prototype.CreateNodeS=CreateNodeS;    // 创建一个指定名的节点. 
XML.prototype.addAttrib=addAttrib;     // 为指定节点添加指定属性,并设置初值. 
XML.prototype.FindString=FindString;    // 在指定节点下查找字符串.

给定以下XML文件,完成算法流程图<FileSystem> 

< DriverC > 
<Dir DirName=”MSDOS622”> 
<File FileName = Command.com” ></File> 
</Dir> 
<File FileName =”MSDOS.SYS” ></File> 
<File FileName = IO.SYS” ></File> 
</DriverC> 
</FileSystem> 

请画出遍历所有文件名(FileName)的流程图(请使用递归算法)。 

答: 

void FindFile( Directory d )
{
    FileOrFolders = d.GetFileOrFolders();
    foreach( FileOrFolder fof in FileOrFolders )
    {
        if( fof is File )
            You Found a file;
        else if ( fof is Directory )
            FindFile( fof );
    }
}

6.C#代码实现,确保windows程序只有一个实例(instance) 

///<summary>
///应用程序的主入口点。
///</summary>
[STAThread]
staticvoid Main()
{
    //防止程序多次运行 
    if(!OneInstance.IsFirst("GetPayInfo"))
    {
        MessageBox.Show ("警告:程序正在运行中! 请不要重复打开程序!可在右下角系统栏找到!","程序错误提
        示:",MessageBoxButtons.OK,MessageBoxIcon.Stop);
        return;
    }
    Application.Run(new Form1());
}
// ******************* 防止程序多次执行 **************************
publicabstractclass OneInstance
{
    ///<summary> 
    ///判断程序是否正在运行 
    ///</summary> 
    ///<param name="appId">程序名称</param> 
    ///<returns>如果程序是第一次运行返回True,否则返回False</returns>
    publicstaticbool IsFirst(string appId)
    {
        bool ret=false;
        if(OpenMutex(0x1F0001,0,appId)==IntPtr.Zero)
        {
            CreateMutex(IntPtr.Zero,0,appId);
            ret=true;
        }
        return ret;
    }
    [DllImport("Kernel32.dll",CharSet=CharSet.Auto)]
    privatestaticextern IntPtr OpenMutex(
        uint dwDesiredAccess, // access
        int bInheritHandle,   // inheritance option
        string lpName         // object name
    );
    [DllImport("Kernel32.dll",CharSet=CharSet.Auto)]
    privatestaticextern IntPtr CreateMutex(
        IntPtr lpMutexAttributes, // SD
        int bInitialOwner,                      // initial owner
        string lpName                           // object name
    );
}

创建一个本地的委托副本

很多人都在使用的, 微软建议的模式: 创建一个本地的委托副本.

LocalCopyMessenger : IMessenger
{      
    EventHandler<MessageReceivedEventArgs> MessageReceived;           
    OnNewMessage( message)    
    {        
        var target = MessageReceived;         (target != )        
        {            
            target(,  MessageReceivedEventArgs(message));        
        }    
    }
}

********************************************************************************

static void Main(string[] args)
{        
    int[] array = { 2, 9, 34, 201 };
    Console.Write(binary_search(array, array.Count(), 9));
    Console.ReadKey();        //输出1
}    
/// <summary>
/// 二分查找
/// </summary>
/// <param name="array">数组</param>
/// <param name="n">个数</param>
/// <param name="value">查找的值</param>
/// <returns></returns>
public static int binary_search(int[] array, int n, int value)
{        
    int left = 0;        
    int right = n - 1;        
    while (left <= right)
    {            
        int middle = left + ((right - left) >> 1);            
        if (array[middle] > value)
        {
            right = middle - 1;
        }            
        else if (array[middle] < value)
        {
            left = middle + 1;
        }            
        else 
            return middle;
    }        
    return -1;
}
************************************************************************
static void Main(string[] args)
{            
    int[] array = { 2, 9, 34, 201 };            
    string sourc = "abaabcaba";            
    string pattern = "abc";
    Console.WriteLine(kmp_find(sourc, pattern));
    compute_overlay(sourc);
    Console.ReadKey();
    // 3//-1   -1   0   0   1   -1   0   1   2
}        
// KMP算法
public static int kmp_find(string target, string pattern)
{            
    int target_length = target.Length;            
    int pattern_length = pattern.Length;
    int[] overlay_value = new int[pattern_length];
    overlay_value[0] = -1;            
    int index = 0;            
    for (int i = 1; i < pattern_length; ++i)            
    //注,此处的i是从1开始的
    {
        index = overlay_value[i - 1];               
        while (index >= 0 && pattern[index + 1] != pattern[i])
        {
            index = overlay_value[index];
        }                
        if (pattern[index + 1] == pattern[i])
        {
            overlay_value[i] = index + 1;
        }                
        else
        {
            overlay_value[i] = -1;
        }
    }            
    int pattern_index = 0;            
    int target_index = 0;            
    while (pattern_index < pattern_length && target_index < target_length)
    {                
        if (target[target_index] == pattern[pattern_index])
        {
            ++target_index;
            ++pattern_index;
        }                
        else if (pattern_index == 0)
        {
            ++target_index;
        }                
        else
        {
            pattern_index = overlay_value[pattern_index - 1] + 1;
        }
    }            
    if (pattern_index == pattern_length)
    {                
        return target_index - pattern_index;
    }            
    else
    {                
        return -1;
    }
}        
//   覆盖函数
public static  void compute_overlay(string pattern)
{            
    int pattern_length = pattern.Length;            
    int[] overlay_function = new int[pattern_length];            
    int index;
    overlay_function[0] = -1;            
    for (int i = 1; i < pattern_length; ++i)
    {
        index = overlay_function[i - 1];                
        //store previous fail position k to index; 
        while (index >= 0 && pattern[i] != pattern[index + 1])
        {
            index = overlay_function[index];
        }                
        if (pattern[i] == pattern[index + 1])
        {
            overlay_function[i] = index + 1;
        }                
        else
        {
            overlay_function[i] = -1;
        }
    }           
    for (int i = 0; i < pattern_length; ++i)
    {
        Console.Write(overlay_function[i]+"   ");
    }
    Console.ReadKey();
}