C# asp.net Sql2000 UML 学习分享ing......

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 :: 管理 ::

ASP.NET开发 笔试题目详解系列123456

ASP.NET开发 笔试题目详解系列(一)


1. SQL部分:
   问:聚集索引和非聚集索引区别:

   答:正文内容本身就是一种按照一定规则排列的目录称为聚集索引
         
目录纯粹是目录,正文纯粹是正文的排序方式称为非聚集索引
  
索引有什么意义?简单解释 簇索引(clustered),及其优缺点

答:聚集索引通常可加快 UPDATE DELETE 操作的速度,因为这两个操作需要读取大量的数据。创建或修改聚集索引可能要花很长时间,因为执行这两个操作时要在磁盘上对表的行进行重组。




但是INSERT会变慢。




可考虑将聚集索引用于:





包含数量有限的唯一值的列,如 state 列只包含 50 个唯一的州代码。




使用下列运算符返回一个范围值的查询:BETWEEN>>=< <=










  隔离级别什么意思?有几种隔离级别,分别简单解释?

答:事务准备接受不一致数据的级别称为隔离级别。隔离级别是一个事务必须与其它事务进行隔离的程度。较低的隔离级别可以增加并发,但代价是降低数据的正确性。相反,较高的隔离级别可以确保数据的正确性,但可能对并发产生负面影响。应用程序要求的隔离级别确定了 SQL Server 使用的锁定行为。




SQL-92 定义了下列四种隔离级别,SQL Server 支持所有这些隔离级别:





未提交读(事务隔离的最低级别,仅可保证不读取物理损坏的数据)。




提交读(SQL Server 默认级别)。




可重复读。




可串行读(事务隔离的最高级别,事务之间完全隔离)。





如果事务在可串行读隔离级别上运行,则可以保证任何并发重叠事务均是串行的。








  简述对事务的理解
答:事务必须运行于可重复读或更高的隔离级别以防止丢失更新。当两个事务检索相同的行,然后基于原检索的值对行进行更新时,会发生丢失更新。如果两个事务使用一个 UPDATE 语句更新行,并且不基于以前检索的值进行更新,则在默认的提交读隔离级别不会发生丢失更新。


2. 编程语言部分(C/C++/C#)

   问: 进程和线程

   
答: 一般进程被定义为一个程序运行中的实例。进程有两个部分组成
            1.
系统内核对象(进程控制块)
            2.  
运行空间(包跨运行所需的代码,数据和资源,如堆和栈);
            
进程是不活跃的,它只提供了一个运行环境。
            
线程是进程中的运行分支,他在进程提供的的环境中执行代码。一个进程至少有一个线程,否则就没有存在的必要.
           
线程包跨一个内核对象和一个栈.线程是CPU的调度单位
.
           
线程是进程运行的最小单位,进程参与分配资源,如句柄,内存等,线程不参与分配,呵呵,进程间通过同步,互斥,共享保持通信!




问:何时进行装箱、拆箱操作
答: 当引用类型与值类型之间转换时






问:什么是CLR
答: CLR(Common Language Runtime)普通语言运行时是整个.net framework构建的基础,是实现.Net跨平台,跨语言,代码安全等核心特性的关键






问:.Net与COM的关系是什么
答:.Net 支持COM和.Net组件之间的互操作性,实际上可通过Runtime Callable Wrapper(RCW)来实现在.Net中获取COM组件,通过COM Callable Wrapper(CCW)来实现在COM中获取.Net组件。



问:.Net中的中间语言(IL)是什么
答:.Net中的中间语言是指可以在普通语言运行时规范下,.执行时通过即时(Just In Time)编译器转化为本地代码的,与CPU独立的一族指令集合。它在.Net平台中是实现语言互操作的一个核心环节,所有.Net平台的语言都要先被编译成中间语言(IL)。






3. WEB开发部分

问:在ASP文件头部写一句什么话将使WEB SERVER强制检查任何程序中使用到的变量必须先定义
:Option explicit

如果不希望某个错误影响到整个ASP页面的执行,在头部写一句什么话可以做到

答:On error resume next








问:希望ASP页面不进入缓存,即每次执行都自动刷新,写一句什么话可以做到
答: Response.Expires = -1
        Response.ExpiresAbsolute = Now() - 1
        Response.cachecontrol = "no-cache"


[ 本帖最后由 thinking 于 2006-9-7 06:15 PM 编辑 ]
2006-9-7 06:14 PM #1
 引用回复 回复 顶部
查看资料  文集  发短消息  QQ 
 
thinking
版主
Rank: 7Rank: 7Rank: 7
Sure Win!


UID 1
精华 4
积分 4784
帖子 949
金币 9 枚
现金 3931 P
存款 645 P
阅读权限 100
注册 2006-7-22
状态 离线

ASP.NET开发 笔试题目详解系列(二)

ASP.NET开发 笔试题目详解系列(二)分类:C#&ASP.NET
问题一 C#中 property 与 attribute的区别,他们各有什么用处,这种机制的好处在哪里?







答:

关于property和attribute在很多书中都没有明显区分。我偏向于如下的理解:







特性(Attributes)是对设计时支持且又能在程序编译时起到作用的,方法/字段/类/程序集的属性声明。







属性(property)是更好地避免直接暴露你的私有成员而在类的声明的成员;

















问题二 ADO.NET相对于ADO有何区别和改进?
答:

1.  ADO以Recordset存储,而ADO.NET则以DataSet表示。Recordset看起来更像单表,如果让Recordset以多表的方式表示就必须在SQL中进行多表连接。反之,DataSet可以是多个表的集合。







2.  ADO 的运作是一种在线方式,这意味着不论是浏览或更新数据都必须是实时的。ADO.NET则使用离线方式,在访问数据的时候ADO.NET会利用XML制作数据的一份幅本,ADO.NET的数据库连接也只有在这段时间需要在线。







3. 由于ADO使用COM技术,这就要求所使用的数据类型必须符合COM规范,而ADO.NET基于XML格式,数据类型更为丰富并且不需要再做COM编排导致的数据类型转换,从而提高了整体性能。







                                
                 ADO架构图表                                                   ADO.NET架构图表

















问题三ASP.NET与ASP相比,主要有哪些进步?







答:







ASP.NET优点:

1.   代码和内容分离使代码更清晰







2.   提高可部署性、可伸缩性、安全性以及可靠性







3.   为不同的浏览器和设备提供更好的支持

















ASP缺点:

1.   ASP只能使用脚本语言属于解释性语言,主要是javascript或VBScript。而解释性语言,而解释性语言缺乏强类型和编译环境。这些将不可避免地导致性能和伸缩性问题。







2.   ASP代码杂乱、功能有限,浏览器兼容以及浏览设备的兼容性差,而ASP.NET能够很好的解决。
2006-9-7 06:15 PM #2
 引用回复 回复 顶部
查看资料  文集  发短消息  QQ 
 
thinking
版主
Rank: 7Rank: 7Rank: 7
Sure Win!


UID 1
精华 4
积分 4784
帖子 949
金币 9 枚
现金 3931 P
存款 645 P
阅读权限 100
注册 2006-7-22
状态 离线

ASP.NET开发 笔试题目详解系列(三)

ASP.NET开发 笔试题目详解系列(三) 分类:C#&ASP.NET
  
问题四 C#中的委托是什么?事件是不是一种委托?







答:








委托







委托是C#中的一种引用类型,类似于C/C++中的函数指针。与函数指针不同的是,委托是面向对象、类型安全的,而且委托可以引用静态方法和实例方法,而函数指针只能引用静态函数。委托主要用于 .NET Framework 中的事件处理程序和回调函数。

一个委托可以看作一个特殊的类,因而它的定义可以像常规类一样放在同样的位置。与其他类一样,委托必须先定义以后,再实例化。







委托派生于基类System.Delegate,不过委托的定义和常规类的定义方法不太一样。委托的定义通过关键字delegate来定义:

public delegate int myDelegate(int x,int y);

上面的代码定义了一个新委托,它可以封装任何返回为int,带有两个int类型参数的方法。任何一个方法无论是实例方法还是静态方法,只要他们的签名(参数类型在一个方法中的顺序)和定义的委托是一样的,都可以把他们封装到委托中去。







产生委托实例和产生类实例(对象)差不多,假如我们有如下的方法:

public int sub(int x,int y){
       return(x+y);
}







我们就可以使用如下的代码得到一个委托实例:

myDelegate calculatin=new myDelegate(sub); // 呵呵,用方法名!!!








接下来我们就可以直接使用calculation调用sub方法了:

calculation(10,3);
当然也可以新建 委托数组,如下就建立了一个委托数组Calculation[]






接下来我们就可以直接使用calculation调用sub方法了:

calculation(10,3);
当然也可以新建 委托数组,如下就建立了一个委托数组Calculation[]






接下来我们就可以直接使用calculation调用sub方法了:

calculation(10,3);
当然也可以新建 委托数组,如下就建立了一个委托数组Calculation[]







       private delegate int Calculation(int a, int b);

       private static Calculation[] myCalculation=new Calculation[2];
此时,可以用委托数组中的成员来封装待委托方法,实现新建委托实例.
如:

myCalculation[0]=new Calculation(MathClass.max); // 方法名
myCalculation[1]=new Calculation(MathClass.min); // 方法名









这样,也就可以用新建的委托实例数组,来直接调用方法了.

事件







在C#中,委托的最基本的一个用处就是用于事件处理。是对象发送的消息,以发信号通知操作的发生,通俗一点讲,事件就是程序中产生了一件需要处理的信号。

事件的定义用关键字event声明,不过声明事件之前必须存在一个多路广播委托(一个委托同时委托多个方法):







public delegate void Calculate(int x,int y);//返回值为void的委托自动成为多路广播委托;
public event  Calculate OnCalculate;

可以看出,事件的声明仅仅是比委托实例的声明多了个关键字event,事实上事件可以看作是一个为事件处理过程定制的多路广播委托。因此,定义了事件后,我们就可以通过向事件中操作符+=添加方法实现事件的预定或者是通过操作符-=取消一个事件,这些都与委托实例的处理是相同的。

下面再单独谈谈 事件代理 的相关概念及其应用:

我们就一起来模仿一个Button类及Button值改变后引发事件并执行自定义的ButtonTextChangeEvent事件处理函数的过程,从而以事件数据得到该Button赋值过多少次。







Using System;
namespace MyServerControlTest {
   public delegate void ButtonTextChangeEventHander ( object sender , EventArgs e ); //事件委托的声明。
   public class Button {
   public event ButtonTextChangeEventHander TxtChange;//定义一个事件委托的引用,以备外部进行事件的绑定.
   private string _Text;;
   public string Text {
            get { return _Text;; }
       set {
                     _Text = value;;
                     System.EventArgs e = new EventArgs();; //这里是事件的基类实例.
                     ChangeTxt(e);; //调用事件处理函数.
                }
   }
   private void ChangeTxt(EventArgs e)  { //事件处理函数.
   if( TxtChange != null )
   TxtChange(this,e);;//真正调用外部指派的处理函数.
   }
   }
}
为什么要这样定义委托声明:
delegate ButtonTextChangeEventHander (Object sender , EventArgs e )
原因也很简单,为了符合.net framework CLS的约定
Sender :引发事件的对象 ; e:事件所带的数据,而之所以用EventArgs e 是因为这里的事件是无数据的,如果自定义具有数据的事件的话,还是要从System.EventArgs基类中继承。







需要指出的是:
if( TxtChange != null )

   TxtChange(this,e);;
如果不加 if( TxtChange != null )
那么当TxtChange并没有绑定事件处理函数时,它将会引发“未将对象引用到实例”的Exception。







   /**//**//**//// 〈summary〉
   /// 事件处理类
   /// 〈/summary〉
   public class DelegateDemo {
   //定义一个实例
   private Button button;







   public DelegateDemo(){
   InitializeComponent();
   //构造函数调用时,就开始操作button进行赋值。
   SetValues();







}

   public void InitializeComponent(){
   button = new Button();;
   //对button对象的TxtChange事件引用,进行事件与处理函数的绑定。
   //前面已经说过了,EventHandler是一个类,所以要用new进行创建它的实例,其主要是把button_TxtChange事件处理函数的地址传至这个委托实例。
   button.TxtChange += new ButtonTextChangeEventHander(button_TxtChange);;
   }
   public void SetValues() {
   string[] values = {"AAA","BBB","CCC","DDD","EEE"};;
             for( int i = 0;; i 〈 5;; i++ ) {
            //进行赋值,从而引发事件而直接调用button_TxtChange事件处理函数。
             button.Text = values;;
            }
   }
  private void button_TxtChange(object sender, System.EventArgs e) {
   Console.WriteLine( " Button实例新值。其值为:" + ((Button)sender).Text );
   }
}
   public class MyMain  {
            public static void Main() {
             DelegateDemo delegateDemo = new DelegateDemo();;
             Console.Read();;
        }
   }
}





































感觉还是讲的不是很清楚。再来看一个:







public class MyObject
{
   public delegate void ClickHandler(object sender, EventArgs e);
   public event ClickHandler Click;
   protected void OnClick()
   {
      if (Click != null)
         Click(this, null);
   }
}














ClickHandler 代理使用事件代理的标准模式来定义事件的签名。其名称的末尾是处理程序,它带有两个参数。第一个参数是发送对象的对象,第二个参数用于传递事件的伴随信息。这种情况下没有要传递的信息,因此直接使用 EventArgs,但是如果有数据要传递,则使用从 EventArgs 派生的类(例如 MouseEventArgs)。

“Click”事件的声明执行两项操作:首先,它声明一个名为“Click”的代理成员变量,该变量从类的内部进行使用。其次,它声明一个名为“Click”的事件,该事件可按照常规访问规则从类的外部进行使用。







通常,将包括 OnClick() 等函数,以便使类型或派生类型能够触发事件。由于“Click”是代理,您将会注意到,用来触发事件的代码与代理的代码相同。

与代理类似,我们使用 += 和 -= 来挂接到事件或解除事件挂接,但与代理不同的是,仅可对事件执行这些操作。这可确保不会发生先前所讨论的两种错误。

使用事件是一种直截了当的方法。



class Test
{
   static void ClickFunction(object sender, EventArgs args)
   {
      // process the event here.
   }
   public static void Main()
   {
      MyObject myObject = new MyObject();

      myObject.Click += new MyObject.ClickHandler(ClickFunction);      
   }
}



我们创建一个与代理签名相匹配的静态函数或成员函数,然后用 += 向事件中添加代理的一个新实例

还没有相关回复
2006-9-7 06:16 PM #3
 引用回复 回复 顶部
查看资料  文集  发短消息  QQ 
 
thinking
版主
Rank: 7Rank: 7Rank: 7
Sure Win!


UID 1
精华 4
积分 4784
帖子 949
金币 9 枚
现金 3931 P
存款 645 P
阅读权限 100
注册 2006-7-22
状态 离线

ASP.NET开发 笔试题目详解系列(四)

问题五  描述一下C#中索引器的实现过程,是否只能根据数字进行索引?



参考答案:
索引器(Indexer)是C#引入的一个新型的类成员,它使得对象可以像数组那样被方便,直观的引用。索引器非常类似于我们前面讲到的属性,但索引器可以有参数列表,且只能作用在实例对象上,而不能在类上直接作用。下面是典型的索引器的设计,我们在这里忽略了具体的实现。



class MyClass{
public object this [int index]{
get{
     // 取数据
   }
set{
     // 存数据
    }
}
}



注意,这里的属性名是this,意思是回引类的当前实例,参数列表包含在方括号而非括号之内。索引器参数可以采用任何类型,不过int是通常采用也是最为合理的类型。同一类中还可能拥有一个以上的索引器(重载)。



问题六  C#中要使一个类支持FOREACH遍历,实现过程怎样?

若要循环访问集合,集合必须满足特定的要求。例如,在下面的 foreach 语句中:



   foreach (ItemType item in myCollection)



myCollection 必须满足下列要求:



集合类型:

必须是 interface、class 或 struct。

必须包括返回类型的名为 GetEnumerator 的实例方法,例如 Enumerator。

Enumerator 类型(类或结构)必须包含:

一个名为 Current 的属性,它返回 ItemType 或者可以转换为此类型的类型。属性访问器返回集合的当前元素。

一个名为 MoveNext 的 bool 方法,它递增项计数器并在集合中存在更多项时返回 true。

有三种使用集合的方法:



1.      使用上述指导创建一个集合。此集合只能用于 C# 程序。



2.      使用上述指导创建一个一般集合,另外实现 IEnumerable 接口。此集合可用于其他语言(如 Visual Basic)。



3.      在集合类中使用一个预定义的集合。



(ms-help://MS.NETFrameworkSDKv1.1.CHS/csref/html/vclrfusingforeachwithcollections.htm#vclrfforeachcollections_example1)




问题七  ASP.NET 服务器控件的生命周期:



·             1. 初始化  - Init 事件 (OnInit 方法)
2. 加载视图状态 - LoadViewState 方法
3. 处理回发数据 - LoadPostData 方法
    对实现 IPostBackDataHandler 接口的控件,即可以自动加载回发数据的控件,如 TextBox, DropDownList 等。
4. 加载 - Load 事件 (OnLoad 方法)
5. 发送回发更改通知 - RaisePostDataChangedEvent 方法
    对实现 IPostBackDataHandler 接口的控件,即可以自动加载回发数据的控件。
    在第 3 步中加载回发数据,如果回发前后数据发生更改,则在这一步触发相应的服务端事件。
6. 处理回发事件 - RaisePostBackEvent 方法
    对实现 IPostBackEventHandler 接口的控件,即能引起回发的控件,如 Button, LinkButton, Calendar 等
7. 预呈现 - PreRender 事件 (OnPreRender 方法)
8. 保存视图状态 - SaveViewState 方法
9. 呈现 - Render 方法
10. 处置 - Dispose 方法
11. 卸载 - UnLoad 事件 (OnUnLoad 方法)

问题八  接口和抽象类有什么区别?你选择使用接口和抽象类的依据是什么?

“抽象类”是一种不能实例化而必须从中继承的类。抽象类可以完全实现,但更常见的是部分实现或者根本不实现,从而封装继承类的通用功能。

“接口”是完全抽象的成员集合,可以被看作是为操作定义合同。接口的实现完全留给开发者去做。
这里是一些建议,帮助您决定使用接口还是抽象类为组件提供多态性:



如果预计要创建组件的多个版本,则创建抽象类。抽象类提供简单易行的方法来控制组件版本。通过更新基类,所有继承类都随更改自动更新。另一方面,接口一旦创建就不能更改。如果需要接口的新版本,必须创建一个全新的接口。  

如果创建的功能将在大范围的全异对象间使用,则使用接口。抽象类应主要用于关系密切的对象,而接口最适合为不相关的类提供通用功能。

如果要设计小而简练的功能块,则使用接口。如果要设计大的功能单元,则使用抽象类。

如果要在组件的所有实现间提供通用的已实现功能,则使用抽象类。抽象类允许部分实现类,而接口不包含任何成员的实现。

问题九  自定义控件和一般用户控件的异同?


用户控件模型适合创建内部,应用程序特定的控件,而自定义控件模型更适合创建通用的和可再分发的控件

问题十  面向对象的概念,主要特点

封装(wrap)、继承(inheritance)、重载(override)、多态(polymorphism)
2006-9-7 06:16 PM #4
 引用回复 回复 顶部
查看资料  文集  发短消息  QQ 
 
thinking
版主
Rank: 7Rank: 7Rank: 7
Sure Win!


UID 1
精华 4
积分 4784
帖子 949
金币 9 枚
现金 3931 P
存款 645 P
阅读权限 100
注册 2006-7-22
状态 离线

ASP.NET开发 笔试题目详解系列(五)

问题十一  override与重载的区别

override(函数覆盖)修饰符,覆写一个基类中的方法。



重载(reload)则是将将同名方法重新写过,达到同名的函数实现不同的功能.从而实现了一个方法有不同的版本.



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



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









问题十三  C#的异常处理机制

Try...Catch...Finally 异常处理程序的 Try 块包含希望错误处理程序监视的代码节。如果该代码节中的任何代码在执行期间发生错误, 将检查 Try...Catch...Finally 内的每个 Catch 语句,直到找到条件与该错误匹配的语句。如果找到了这样的语句,则控制转移到 Catch 块内的第一个代码行。如果没有找到匹配的 Catch 语句,则继续搜索包含发生异常的块的外部 Try...Catch...Finally 块的 Catch 语句。此过程在整个堆栈中继续,直到在当前过程中找到匹配的 Catch 块。如果没有找到,将产生错误。



Finally 节中的代码总是最后执行,并且刚好在错误处理块失去范围之前执行,不论 Catch 块内的代码是否已执行。将清理代码(如用于关闭文件和释放对象的代码)放在 Finally 节中。



详细解释如下



Throw



在发生引发异常的条件时,可以用 throw 语句来对发出信号。例如,如果例程要求非空字符串作为参数,则它可能包含下列代码:



public void Process(string location){

   if (location == null)



   throw new ArgumentNullException("null value", "location");



}



在该示例中,ArgumentNullException 的新实例是用特定的消息和参数名称来创建的,throw 语句用于引发它。



Try-Catch



用于编写错误处理的最基本的构造是 try-catch。考虑下列代码:



   try{



      Process(currentLocation);



      Console.WriteLine("Done processing");



   }



   catch (ArgumentNullException e)



   {



      // handle the exception here



   }



在该示例中,如果 ArgumentNullException 被 try 块中的代码引发(在此情况下,是 Process() 函数),控制将被立即转到 catch 块,而不会执行 Console.WriteLine() 调用。



更通用的捕捉



在上一个示例中,catch 子句捕捉到了 ArgumentNullException,它完全与 Process() 所引发的异常匹配。



不过,这不是一项要求。Catch 子句将捕捉指定的异常或者任何从该类派生的异常。例如:



   try



   {



      Process(currentLocation);



      Console.WriteLine("Done processing");



   }



   catch (ArgumentException e)



   {



      // handle the exception here



   }



由于 ArgumentNullException 是从 ArgumentException 派生的,因此该 catch 子句将捕捉任何一种异常。此外,它还将捕捉其他的派生异常:ArgumentOutOfRangeException、InvalidEnumArgumentException 和 DuplicateWaitObjectException。



由于所有的异常归根到底都是从 Exception 类派生的,因此捕捉 Exception 将捕捉任何异常。对了,不是捕捉任何异常;这是因为 C++ 不会将用户限制为只引发从 Exception 派生的类,C# 提供了捕捉所有异常的语法:



   catch



   {



      // handle the exception here



   }



尽管这个语法是为了完整性而提供的,但是实际上很少使用它。大部分的 C++ 程序都将选择引发从 Exception 派生的异常,并且即使它们不这样做,此 catch 语法也不会让您超出引发了什么。



Catch 排序



对于给定的 try 子句,可以有一个以上的 catch 子句,每个 catch 捕捉不同的异常类型。在上一个示例中,对 ArgumentException 进行特殊处理,然后对所有其他异常进行别的处理可能很合适。选择最具体的(即,派生程度最大的)catch 子句。



那么示例将是这样的:



   try



   {



      Process(currentLocation);



      Console.WriteLine("Done processing");



   }



   catch (ArgumentException e)



   {



      // handle the exception here



   }



   catch (Exception e)



   {



      // handle the more general exception here



   }



当使用多个 catch 子句时,导出类型必须始终列在任何基类型之前(或者,以从比较合适到不太合适的顺序列出)。这是为了提高可读性。通过阅读较早的 catch 子句,您可以确定运行时行为将是什么。



Catch 操作



既然我们已经捕捉到了异常,我们可能希望对它来做一些有意义的事情。我们可能想做的第一件事是用一些附加的上下文信息包装异常。



这是以下面的方式来实现的:



   try



   {



      Process(currentLocation);



      Console.WriteLine("Done processing");



   }



   catch (ArgumentException e)



   {



      throw new ArgumentException("Error while processing", e);



   }



它为 ArgumentException 使用获取一个消息和另一个异常的构造函数。该构造函数将把传递的异常包装在新的异常中,而那个新的将被引发。



此过程为开发人员带来了巨大的好处。不是只获得单个一条有关所发生的事情的信息,包装异常还提供了一种类似堆栈跟踪的东西:



Exception occurred:



System.Exception: Exception in Test1



---> System.Exception: Exception in Test2



---> System.DivideByZeroException: Attempted to divide by zero.



这样的输出使调试变得容易得多。如果用 /debug 编译,在各个等级上还将获得文件名和行号。



包装有助于为调试提供附加的信息。另一种方案是针对需要根据异常采取一些操作的情况。将输出发送到文件的代码看起来可能是这样的:



   try



   {



FileStream f = new FileStream(filename, FileMode.Create);



StreamWriter s = new StreamWriter(f);



        



s.WriteLine("{0} {1}", "test", 55);



s.Close();



f.Close();      



   }



   catch (IOException e)



   {



      Console.WriteLine("Error opening file {0}", filename);



      Console.WriteLine(e);



   }



如果文件不能打开,则引发异常,激发 catch,出现错误会,而程序可以继续执行。在许多情况下,这没问题。



不过,在这种情况下就存在问题。如果异常在文件打开之后发生,则文件将无法关闭。这很糟糕。



所需要的是确保即使发生了异常也可以关闭文件的方法。



Try-Finally



finally 构造用于指定即使发生异常也始终会运行的代码。finally 通常用于清理发生异常时所产生的内容。修订上一个示例:



   try



   {



FileStream f = new FileStream(filename, FileMode.Create);



StreamWriter s = new StreamWriter(f);



        



s.WriteLine("{0} {1}", "test", 55);



s.Close();



f.Close();      



   }



   catch (IOException e)



   {



      Console.WriteLine("Error opening file {0}", filename);



      Console.WriteLine(e);



   }



   finally



   {



      if (f != null)



         f.Close();



   }
2006-9-7 06:17 PM #5
 引用回复 回复 顶部
查看资料  文集  发短消息  QQ 
 
thinking
版主
Rank: 7Rank: 7Rank: 7
Sure Win!


UID 1
精华 4
积分 4784
帖子 949
金币 9 枚
现金 3931 P
存款 645 P
阅读权限 100
注册 2006-7-22
状态 离线

ASP.NET开发 笔试题目详解系列(六)

问题十四  构造函数的概念




构造函数是一种特殊的方法,调用它来初始化对象。构造函数的名称总是和包含它的类名称相同,并且从不返回值。
构造函数分为两类:实例构造函数和静态构造函数。
实例构造函数用来初始化特定的对象实例。
静态构造函数也称类构造函数,在第一次使用类之前调用。
一个类可以有多个构造函数。例如,可以声明一个不带参数的构造函数(如 Point())和一个带参数的构造函数(如 Point(int x, int y))。




问题十五  值类型和引用类型的区别?写出C#的样例代码

C# 支持两种类型:"值类型"和"引用类型"。
值类型(如 char、int 和 float)、枚举类型和结构类型。
引用类型包括类 (Class) 类型、接口类型、委托类型和数组类型。
值类型与引用类型的区别在于值类型的变量直接包含其数据,而引用类型的变量则存储对象引用。深层次的说,值类型的值在堆栈里存储,存储的是内存块。而引用类型值则是在堆里分配,通俗地讲,引用类型是指针性质的。
对于引用类型,两个变量可能引用同一个对象,因此对一个变量的操作可能影响另一个变量所引用的对象。对于值类型,每个变量都有自己的数据副本,对一个变量的操作不可能影响另一个变量。



示例
using System;
class Class1 {
           public int Value = 0;
}
class Test {
          static void Main() {
                           int val1 = 0;
                           int val2 = val1;
                           val2 = 123;
                           Class1 ref1 = new Class1();
                           Class1 ref2 = ref1;
                           ref2.Value = 123;
                           Console.WriteLine("Values: {0}, {1}", val1, val2);
                           Console.WriteLine("Refs: {0}, {1}", ref1.Value, ref2.Value);
                           }
}

问题十六ViewState 的作用

ViewState是asp.net中的一个特性,它用于把生成页面要用的一状态值保存在一个隐藏域中。当页面被回传到服务器时,服务器要解析,校验和应用ViewState中的数据以还原页面的控件树。ViewState是一个非常有用的特性,它能持久化客户端的状态而不用cookie或者服务器的内存。大部分的服务器控件都是用ViewState来持久化那些在页面中与用户交互的元素的状态值。例如,用以保存用于分页的当前页的页码。




问题十七  web.config,Global.asax, Machine.Config 作用




Global.asax 文件,有时候叫做 ASP.NET 应用程序文件,包含用于响应 ASP.NET 或 HttpModule 引发的应用程序级别事件的代码。



web.config为每个站点级的基于XML的配置文件,负责一些ASP.NET的安全认证,编码选择,诊断测试等ASP.NET的配置工作,为浏览器请求ASP.NET Web表单时通过 IIS处理后的第一站。

整个服务器的配置信息保存在Machine.Config文件中,它包含了运行一个ASP.NET服务器需要的所有配置信息。

问题十八  如何实现Icomparable接口



class 猪{
int 重量;
public int compareTo(另一头猪的对象){
         if(this.重量==另一头猪的对象.重量)
         return 0;
}
}



其实这个问题算不上问题,这是我学习ASP.NET Forum时遇到的一个疑惑,后来决定写出来。
这里需要注意的是compareTo 的Object是另一头猪对象。而比较的则是两头猪的属性(这里是重量)
下面再看一个。
         public int CompareTo(object obj)
         { //仔细看这里的参数是Object类型的东东
              if (obj == null) return 1;



              int compareOrder = ((ValueGroup)obj).SortOrder;



//int compareOrder = (ValueGroup) obj;



//如果当初这样写我就不会那么不爽了。



              if (this.SortOrder == compareOrder) return 0;
              //当然这里要改成如下格式 *_*
              //if (this.SortOrder == compareOrder.SortOrder) return 0;



              if (this.SortOrder < compareOrder) return -1;



              if (this.SortOrder > compareOrder) return 1;



              return 0;
}







问题十九  ASP.NET支持的部署机制







ASP.NET Web应用程序支持下列三种部署方案:



⑴ XCOPY部署



⑵ 利用VS.NET的“复制项目”功能部署



⑶ 使用VS.NET的“Web安装项目”部署







问题二十  ASP.NET 页面间传递参数的方法







使用QueryString
使用QuerySting在页面间传递值已经是一种很老的机制了,这种方法的主要优点是实现起来非常简单,然而它的缺点是传递的值是会显示在浏览器的地址栏上的(不安全),同时又不能传递对象,但是在传递的值少而安全性要求不高的情况下,这个方法还是一个不错的方案。使用这种方法的步骤如下:
1,使用控件创建web表单(form)
2,创建可以返回表单的按钮或链接按钮
3,在按钮或链接按钮的单击事件里创建一个保存URL的字符变量
4,在保存的URL里添加QueryString参数
5,使用Response.Redirect重定向到上面保存的URL
下面的代码片断演示了如何实现这个方法:
源页面代码:
private void Button1_Click
(object sender, System.EventArgs e)
{
string url;
url="anotherwebform.aspx?name=" + TextBox1.Text + "&email=" + TextBox2.Text;
Response.Redirect(url);
}
目标页面代码:
private void Page_Load
(object sender, System.EventArgs e)
{
Label1.Text=Request.QueryString["name"];
Label2.Text=Request.QueryString["email"];
}



使用Session变量
使用Session变量是可以在页面间传递值的的另一种方式,在本例中我们把控件中的值存在Session变量中,然后在另一个页面中使用它,以不同页面间实现值传递的目的。但是,需要注意的是在Session变量存储过多的数据会消耗比较多的服务器资源,在使用session时应该慎重,当然了,我们也应该使用一些清理动作来去除一些不需要的session来降低资源的无谓消耗。使用Session变量传递值的一般步骤如下:
1,在页面里添加必要的控件
2,创建可以返回表单的按钮或链接按钮
3,在按钮或链接按钮的单击事件里,把控件的值添加到session变量里
4,使用Response.Redirect方法重定向到另一个页面
5,在另一个页面提取session的值,在确定不需要使用该session时,要显式清除它
下面的代码片断演示了如何实现这个方法:
源页面代码:
private void Button1_Click
(object sender, System.EventArgs e)
{
//textbox1 and textbox2 are webform
//controls
Session["name"]=TextBox1.Text;
Session["email"]=TextBox2.Text;
Server.Transfer("anotherwebform.aspx");
}
目标页面代码:
private void Page_Load
(object sender, System.EventArgs e)
{
Label1.Text=Session["name"].ToString();
Label2.Text=Session["email"].ToString();
Session.Remove("name");
Session.Remove("email");
}



使用Server.Transfer
这个方法相比上面介绍的方法稍微复杂一点,但在页面间值传递中却是特别有用的,使用该方法你可以在另一个页面以对象属性的方式来存取显露的值,当然了,使用这种方法,你需要额外写一些代码以创建一些属性以便可以在另一个页面访问它,但是,这个方式带来的好处也是显而易见的。总体来说,使用这种方法是简洁的同时又是面向对象的。使用这种方法的整个过程如下:
1,在页面里添加必要的控件
2,创建返回值的Get属性过程
3,创建可以返回表单的按钮和链接按钮
4,在按钮单击事件处理程序中调用Server.Transfer方法转移到指定的页面
5,在第二个页面中,我们就可以使用Context.Handler属性来获得前一个页面实例对象的引用,通过它,就可以使用存取前一个页面的控件的值了
以下代码综合实现上述步骤过程的代码:
源页面代码:
把以下的代码添加到页面中
public string Name
{
get
{
return TextBox1.Text;
}
}



public string EMail
{
get
{
return TextBox2.Text;
}
}
然后调用Server.Transfer方法
private void Button1_Click
(object sender, System.EventArgs e)
{
Server.Transfer("anotherwebform.aspx");
}
目标页面代码:
private void Page_Load
(object sender, System.EventArgs e)
{
//create instance of source web form
WebForm1 wf1;
//get reference to current handler instance
wf1=(WebForm1)Context.Handler;
Label1.Text=wf1.Name;
Label2.Text=wf1.EMail;
}



在ASP.NET 2.0中启用了跨页面传送功能,其功能和用法在以后在做介绍!



页面之间传递值



方式1:
   
在接收页 的html代码里加上一行: <%@ Reference Page = "WebForm1.aspx" %>            
     
    WebForm1 fp=(WebForm1)Context.Handler;
    this.TextBox1.Text=fp.name;   //name 是第一页的public变量




Context  提供对整个当前上下文(包括请求对象)的访问。您可以使用此类共享页之间的信息。



方式2:GET方式
    在发送页
      public int sum=0;



           int i =int.Parse(this.TextBox1.Text)*2;



           Server.Transfer("WebForm2.aspx?sum="+i);



    接收页
        this.TextBox1.Text=Request["sum"].ToString();
    or  this.TextBox1.Text=Request.Params["sum"].ToString();
        this.TextBox1.Text=Request.QueryString["sum"];




方法3:全局变量



   发送页:
       Application["sum"]=this.TextBox1.Text;
       Server.Transfer("WebForm2.aspx");



   接收页:
       this.TextBox1.Text=(string)Application["sum"];



Application实质上是整个虚拟目录中所有文件的集合,如果想在整个应用范围内使用某个变量值,Application对象将是最佳的选择



在这里用Session[""]的方法雷同



方法4:



发送页:
    1.定义静态变量:  public static string str="";
    2. str=this.TextBox1.Text;
       Server.Transfer("webform2.aspx");
接收页:
    1.引入第一页的命名空间:using WebApplication1;
    2  this.TextBox1.Text=WebForm1.str;
posted on 2007-04-03 09:14  2007—2008C#年  阅读(738)  评论(0)    收藏  举报