现在的位置: 首页 > 综合 > 正文

newagg新蛋笔试题(整理)

2012年06月29日 ⁄ 综合 ⁄ 共 26341字 ⁄ 字号 评论关闭
文章目录
 
    下面是整理的一些新蛋笔试题,贡献下。比较乱,如果有需要的自己copy下去整理吧。
 
 
 
 
  1. 在没有使用Ref关键字的情况下,如何区别方法是按引用传递,还是按值传递?

答:值类型的变量(结构体、枚举、基本数据类型)是按值传递。引用类型的变量(数组、字符串、类、接口)是按引用传递。利用out关键字标记的参数是按引用传递的。

  1. 如果要将基本数据类型按引用传递,怎么办?

答:如果要将基本数据类型按引用传递,使用Ref关键字,或者out关键字。

(      out 和ref 参数,使参数按引用传递, 经常用来通过方法传递参数来获取值,当您的方法不只有一个返回值的时候,这两个参数就发挥作用了。ref是传递参数的地址,out是返回值,两者有一定的相同之处,不过也有不同点。 
在这篇文章里,我将解释如何在c#应用中使用这两个参数。

out 方法参数关键字使方法引用传递到方法的同一个变量。当控制传递回调用方法时,在方法中对参数所做的任何更改都将反映在该变量中。

ref 方法参数关键字使方法引用传递到方法的同一个变量。当控制传递回调用方法时,在方法中对参数所做的任何更改都将反映在该变量中。

使用ref前必须对变量赋值,out不用。

out的函数会清空变量,即使变量已经赋值也不行,退出函数时所有out引用的变量都要赋值,ref引用的可以修改,也可以不修改。

 

按值传递和按引用传递各有什么特点。它们有什么区别?
答:在按值传递中,在被调方法中对变量所做的修改不会影响主调方法中的变量。
在按引用传递中,在被调方法中对变量所做的修改会反映到主调方法中的变量。

  1. 请举例说明.NET的code-behind模式实现的原理,以及它的优点。

答:前台化码是后台代码的子类,后台C#代码是父类. 后台C#代码中所有的控件都没有实例化,是在前台代码中实例化的, 前台代码通过反射机制来实例化C#代码是父类的.

优点:实现了HTML代码和服务器逻辑代码的分离,这样更方便于代码编写、整理及调试.,实现显示逻辑和处理逻辑的分离,这样有助于web应用程序的创建。比如分工,美工和编程的可以个干各的,不用再像以前asp那样都代码和html代码混在一起,难以维护,以事件来驱动,完全按照OO的观点来开发程序

 

  1. NET工程最后生成了多少个DLL,分别是什么?

答:Web项目中所有的WebForm网页的代码后置类文件会被编译成一个动态链接程序庫.dll。每个.aspx网页文件亦会被编译,但是有些差异。当用户第一次浏览.aspx网页时,ASP。NET会自动产生一个代表该网页的.NET类文件,并将它编译成第二个.dll文件。这一给.aspx网页所产生的类会继承已编译至项目的.dll文件中的代码后置类。当用户请求网页时,服务器上的.dll文件会自动产生网页的HTML输出。

 

  1. 请举例说明Cookie和Session的区别和共同点。以及各自的实现机制

答; 为了解决HTTP协议无状态的特性所作的努力,具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。

Cookie是由服务器端生成,发送给浏览器,浏览器会将Cookie的key/value保存到某个目录下的文本文件内,下次请求同一网站时就发送该Cookie给服务器(前提是浏览器设置为启用cookie)。Cookie名称和值可以由服务器端开发自己定义,对于JSP而言也可以直接写入jsessionid,这样服务器可以知道该用户是否合法用户以及是否需要重新登录等。
Cookies最典型的应用是判定注册用户是否已经登录网站,用户可能会得到提示,是否在下一次进入此网站时保留用户信息以便简化登录手续,这些都是Cookies的功用。比如说在两周内登陆某网站都不用再重新输入用户名密码。
   Cookie可以保持登录信息到用户下次与服务器的会话,换句话说,下次访问同一网站时,用户会发现不必输入用户名和密码就已经登录了(当然,不排除用户手工删除Cookie)。而还有一些Cookie在用户退出会话的时候就被删除了,这样可以有效保护个人隐私。    Cookie在生成时就会被指定一个Expire值,这就是Cookie的生存周期,在这个周期内Cookie有效,超出周期Cookie就会被清除。有些页面将Cookie的生存周期设置为0或负值,这样在关闭页面时,就马上清除Cookie,不会记录用户信息,更加安全。    当在浏览器地址栏中键入了Amazon的URL,浏览器会向Amazon发送一个读取网页的请求,并将结果在显示器上显示。这时该网页在你的电脑上寻找Amazon网站设置的Cookie文件,如果找到,浏览器会把Cookie文件中的数据连同前面输入的URL一同发送到Amazon服务器。服务器收到Cookie数据,就会在他的数据库中检索你的ID,你的购物记录、个人喜好等信息,并记录下新的内容,增加到数据库和Cookie文件中去。如果没有检测到Cookie或者你的Cookie信息与数据库中的信息不符合,则说明你是第一次浏览该网站,服务器的CGI程序将为你创建新的ID信息,并保存到数据库中。  Cookie是利用了网页代码中的HTTP头信息进行传递的,浏览器的每一次网页请求,都可以伴随Cookie传递,例如,浏览器的打开或刷新网页操作。服务器将Cookie添加到网页的HTTP头信息中,伴随网页数据传回到你的浏览器,浏览器会根据你电脑中的Cookie设置选择是否保存这些数据。通常情况下,Cookie包含Server、Expires、Name、value这几个字段,其中对服务器有用的只是Name和value字段,Expires等字段的内容仅仅是为了告诉浏览器如何处理这些Cookies。

具体来说cookie机制采用的是在客户端保持状态的方案。它是在用户端的会话状态的存贮机制,他需要用户打开客户端的cookie支持。cookie的作用就是为了解决HTTP协议无状态的缺陷所作的努力.而session机制采用的是一种在客户端与服务器之间保持状态的解决方案。同时我们也看到,由于采用服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制来达到保存标识的目的。而session提供了方便管理全局变量的方式session是针对每一个用户的,变量的值保存在服务器上,用一个sessionID来区分是哪个用户session变量,这个值是通过用户的浏览器在访问的时候返回给服务器,当客户禁用cookie时,这个值也可能设置为由get来返回给服务器。
就安全性来说:当你访问一个使用session 的站点,同时在自己机子上建立一个cookie,建议在服务器端的SESSION机制更安全些.因为它不会任意读取客户存储的信息。正统的cookie分发是通过扩展HTTP协议来实现的,服务器通过在HTTP的响应头中加上一行特殊的指示以提示浏览器按照指示生成相应的cookie从网络服务器观点看所有HTTP请求都独立于先前请求。就是说每一个HTTP响应完全依赖于相应请求中包含的信息
状态管理机制克服了HTTP的一些限制并允许网络客户端及服务器端维护请求间的关系。在这种关系维持的期间叫做会话(session)。Cookies是服务器在本地机器上存储的小段文本并随每一个请求发送至同一个服务器。网络服务器用HTTP头向客户端发送cookies,在客户终端,浏览器解析这些cookies并将它们保存为一个本地文件,它会自动将同一服务器的任何请求缚上这些cookies,session在浏览器中可以通过cookie的方式进行保存,用户端是保存cookies, cookies 里面保存了个session_id;服务器端保存其他session变量,比如用户名和密码。当用户请求服务器时也把session_id一起发送到服务器,通过session_id提取所保存在服务器端的变量,就能识别用户是谁了。session的常见实现形式是会话cookie(session cookie),即未设置过期时间的cookie,这个cookie的默认生命周期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了。实现机制是当用户发起一个请求的时候,服务器会检查该请求中是否包含sessionid,如果未包含,则系统会创造一个名为JSESSIONID的输出 cookie返回给浏览器(只放入内存,并不存在硬盘中),并将其以HashTable的形式写到服务器的内存里面;当已经包含sessionid是,服务端会检查找到与该session相匹配的信息,如果存在则直接使用该sessionid,若不存在则重新生成新的session。这里需要注意的是 session始终是有服务端创建的,并非浏览器自己生成的。

 

  1. NET工程如何布署?

答:上周终于都完成了项目的打包部署。现在总结一下,打包ASP.NET网站有做些那些事情。
1.打包时安装数据库,是通过数据库备份文件进行恢复,而不是SQL语句新建(因为项目初始化数据很多)。同时修改web.config文件。2.新建网站,并设置网站的相关属性,包括匿名访问,集成WINDOWS认证,文档,ASP.NET选项设置为2.0等。3.操作注册表。将相关信息写入注册表,例如安装路径等等。4.如果安装的路径所在盘符是NTFS格式,那么要设置网站中相应的文件夹让Everyone有修改权限,因为传放上传文件的文件夹需要设置权限。5.如果安装机器没有.NET Frameword2.0框架,自动安装框架。在安装项目的属性页中找到“系统必备”按钮,点击按钮可以看到,安装程序所需要的组件(当然包括.NET   Framwork2005),  选中.NET   Framwork,然后在下边的选项中选择“从我的应用程序相同的位置下载系统必备组件”,   这样生成安装包里会包括“.NET   Framwork”  

 

  1. .NET中页面级缓存如何进行?

答:ASP.NET 提供三种主要形式的缓存:页面级输出缓存、用户控件级输出缓存(或称为片段缓存)和缓存 API。输出缓存和片段缓存的优点是非常易于实现,在大多数情况下,使用这两种缓存就足够了。而缓存 API 则提供了额外的灵活性(实际上是相当大的灵活性),可用于在应用程序的每一层利用缓存。

         要实现页面输出缓存,只要将一条 OutputCache 指令添加到页面即可。

<%@ OutputCache Duration="60" VaryByParam="*" %>如同其他页面指令一样,该指令应该出现在 ASPX 页面的顶部,即在任何输出之前。它支持五个属性(或参数),其中两个是必需的。利用必需的 Duration 和 VaryByParam 选项的组合可以处理大多数情况。例如,如果您的产品目录允许用户基于 categoryID 和页变量查看目录页,您可以用参数值为 "categoryID;page" 的 VaryByParam 将产品目录缓存一段时间(如果产品不是随时都在改变,一小时还是可以接受的,因此,持续时间是 3600 秒)。这将为每个种类的每个目录页创建单独的缓存条目。每个条目从其第一个请求算起将维持一个小时。

VaryByHeader 和 VaryByCustom 主要用于根据访问页面的客户端对页面的外观或内容进行自定义。同一个 URL 可能需要同时为浏览器和移动电话客户端呈现输出,因此,需要针对不同的客户端缓存不同的内容版本。或者,页面有可能已经针对 IE 进行了优化,但需要能针对 Netscape 或 Opera 完全降低优化(而不仅仅是破坏页面)。后一个例子非常普遍,我们将提供一个说明如何实现此目标的示例:示例: VaryByCustom 用于支持浏览器自定义,为了使每个浏览器都具有单独的缓存条目,VaryByCustom 的值可以设置为 "browser"。此功能已经内置在缓存模块中,并且将针对每个浏览器名称和主要版本插入单独的页面缓存版本。<%@ OutputCache Duration="60" VaryByParam="None" VaryByCustom="browser"  %>,片段缓存,用户控件输出缓存,缓存整个页面通常并不可行,因为页面的某些部分是针对用户定制的。不过,页面的其他部分是整个应用程序共有的。这些部分最适合使用片段缓存和用户控件进行缓存。菜单和其他布局元素,尤其是那些从数据源动态生成的元素,也应该用这种方法进行缓存。如果需要,可以将缓存的控件配置为基于对其控件(或其他属性)的更改或由页面级输出缓存支持的任何其他变动进行改变。使用同一组控件的几百个页面还可以共享那些控件的缓存条目,而不是为每个页面保留单独的缓存版本。实现,片段缓存使用的语法与页面级输出缓存一样,但其应用于用户控件(.ascx 文件)而不是 Web 窗体(.aspx 文件)。除了 Location 属性,对于 OutputCache 在 Web 窗体上支持的所有属性,用户控件也同样支持。用户控件还支持名为 VaryByControl 的 OutputCache 属性,该属性将根据用户控件(通常是页面上的控件,例如,DropDownList)的成员的值改变该控件的缓存。如果指定了 VaryByControl,可以省略 VaryByParam。最后,在默认情况下,对每个页面上的每个用户控件都单独进行缓存。不过,如果一个用户控件不随应用程序中的页面改变,并且在所有页面都使用相同的名称,则可以应用 Shared="true" 参数,该参数将使用户控件的缓存版本供所有引用该控件的页面使用。示例<%@ OutputCache Duration="60" VaryByParam="*" %>该示例将缓存用户控件 60 秒,并且将针对查询字符串的每个变动、针对此控件所在的每个页面创建单独的缓存条目。<%@ OutputCache Duration="60" VaryByParam="none"  VaryByControl="CategoryDropDownList" %>该示例将缓存用户控件 60 秒,并且将针对 CategoryDropDownList 控件的每个不同的值、针对此控件所在的每个页面创建单独的缓存条目。<%@ OutputCache Duration="60" VaryByParam="none" VaryByCustom="browser"  Shared="true %>最后,该示例将缓存用户控件 60 秒,并且将针对每个浏览器名称和主要版本创建一个缓存条目。然后,每个浏览器的缓存条目将由引用此用户控件的所有页面共享(只要所有页面都用相同的 ID 引用该控件即可)。

 

缓存 API,使用 Cache 对象,页面级和用户控件级输出缓存的确是一种可以迅速而简便地提高站点性能的方法,但是在 ASP.NET 中,缓存的真正灵活性和强大功能是通过 Cache 对象提供的。使用 Cache 对象,您可以存储任何可序列化的数据对象,基于一个或多个依赖项的组合来控制缓存条目到期的方式。这些依赖项可以包括自从项被缓存后经过的时间、自从项上次被访问后经过的时间、对文件和/或文件夹的更改以及对其他缓存项的更改,在略作处理后还可以包括对数据库中特定表的更改。在 Cache 中存储数据,在 Cache 中存储数据的最简单的方法就是使用一个键为其赋值,就像 HashTable 或Dictionary 对象一样:Cache["key"] = "value";这种做法将在缓存中存储项,同时不带任何依赖项,因此它不会到期,除非缓存引擎为了给其他缓存数据提供空间而将其删除。要包括特定的缓存依赖项,可使用 Add() 或 Insert() 方法。其中每个方法都有几个重载。Add() 和 Insert() 之间的唯一区别是,Add() 返回对已缓存对象的引用,而 Insert() 没有返回值(在 C# 中为空,在 VB 中为 Sub)。示例Cache.Insert("key", myXMLFileData, new  System.Web.Caching.CacheDependency(Server.MapPath("users.xml")));该示例可将文件中的 xml 数据插入缓存,无需在以后请求时从文件读取。 CacheDependency 的作用是确保缓存在文件更改后立即到期,以便可以从文件中提取最新数据,重新进行缓存。如果缓存的数据来自若干个文件,还可以指定一个文件名的数组。Cache.Insert("dependentkey", myDependentData, new  System.Web.Caching.CacheDependency(new string[] {}, new string[]  {"key"}));该示例可插入键值为 "key" 的第二个数据块(取决于是否存在第一个数据块)。如果缓存中不存在名为 "key" 的键,或者如果与该键相关联的项已到期或被更新,则 "dependentkey" 的缓存条目将到期。Cache.Insert("key", myTimeSensitiveData, null,  DateTime.Now.AddMinutes(1), TimeSpan.Zero);绝对到期:此示例将对受时间影响的数据缓存一分钟,一分钟过后,缓存将到期。注意,绝对到期和滑动到期(见下文)不能一起使用。Cache.Insert("key", myFrequentlyAccessedData, null,  System.Web.Caching.Cache.NoAbsoluteExpiration,  TimeSpan.FromMinutes(1));滑动到期:此示例将缓存一些频繁使用的数据。数据将在缓存中一直保留下去,除非数据未被引用的时间达到了一分钟。注意,滑动到期和绝对到期不能一起使用。

  1. DataSet和DataReader的区别和相同点,分别适合用于什么样的情况?

答:dataset表示一个数据集,是数据在内存中的缓存。 可以包括多个表
DatSet 连接数据库时是非面向连接的。把表全部读到Sql中的缓冲池,并断开于数据库的连接

datareader 连接数据库时是面向连接的。读表时,只能向前读取,读完数据后有用户决定是否断开连接。

分布式系统的数据可能会用dataset做数据载体,因为dataset是保存数据的数据结构,而DataReader不承担保存数据的责任,它只负责从数据源读取数据到本地而已,它不是数据结构,而是网络通讯组件的高层封装。 DataAdapter也只是使用DataReader从数据源读取数据并Add到dataset保存起来而已。假如我们单独使用DataReader也可以把数据写入到业务类或者dataset里。那只是根据业务需要而选择不同的数据载体而已。实际上我们从数据库获得数据都会通过DataReader,只不过DataAdapter把这一切都封装起来了

dataset 和 datareader对象有什么区别?
DataSet可以离线处理,前后滚动.DataReader不能离线处理,且是只读的向前的,不过速度明显会很快 DataSet可以存储数据库各种对象的,比如表触发器等,而DataReader只能存储游标记录  
DataSet可以更新回原来的数据库,DataReader不行;   
DataSet可以FORWORD     PREVIUS,而DataReader只能FW;   
DataReader类似一个只能向前的游标记录集   
DataSet叫数据集!是ADO.net相对与ADO实现断开式数据库连接性的主要体现!DateReader是一个客户端的只向前游标,两者的应用领域不同!读取数据后!如果要进行比较频繁的改动,可以使用DataSet,并且DataSet也支持串行化,可与xslt结合!进行web开发!   
DataReader则偏向于快速读取数据!针对数据量比较大的数据可能应用的更加频繁点! <[三]>ADO.NET提供以下两个对象,用于检索关系数据并将其存储在内存中:DataSet和DataReader。DataSet提供一个内存中数据的关系表示形式,一整套包括一些表在内的数据(这些表包含数据、对数据进行排序并约束数据),以及表之间的关系。DataReader提供一个来自数据库的快速、仅向前、只读数据流。

当使用DataSet时,经常会利用DataAdapter(也可能是CommandBuilder)与数据源进行交互。当使用DataSet时,也可以利用DataView对DataSet中的数据应用排序和筛选。也可以从DataSet继承,创建强类型DataSet,用于将表、行和列作为强类型对象属性公开。

下列主题包括的信息涉及:使用DataSet或DataReader的最佳时机、如何优化访问它们所包含数据、以及如何优化使用DataAdapter(包括CommandBuilder)和DataView的技巧。

DataSet与DataReader

当设计应用程序时,要考虑应用程序所需功能的等级,以确定使用DataSet或者是DataReader。

要通过应用程序执行以下操作,就要使用DataSet:

r 在结果的多个离散表之间进行导航。

r 操作来自多个数据源(例如,来自多个数据库、一个XML文件和一个电子表格的混合数据)的数据。

r 在各层之间交换数据或使用XML Web服务。与DataReader不同的是,DataSet能传递给远程客户端。

r 重用同样的记录集合,以便通过缓存获得性能改善(例如排序、搜索或筛选数据)。

r 每条记录都需要执行大量处理。对使用DataReader返回的每一行进行扩展处理会延长服务于DataReader的连接的必要时间,这影响了性能。

r 使用XML操作对数据进行操作,例如可扩展样式表语言转换(XSLT转换)或XPath查询。

对于下列情况,要在应用程序中使用DataReader:

r 不需要缓存数据。

r 要处理的结果集太大,内存中放不下。

r 一旦需要以仅向前、只读方式快速访问数据。

注填充DataSet时,DataAdapter使用DataReader。因此,使用DataAdapter取代DataSet提升的性能表现为节省了DataSet占用内存和填充DataSet需要的循环。一般来说,此性能提升只是象征性的,因此,设计决策应以所需功能为基础。<[四]>

经常听到有人问这个问题:“在ASP.NET Web应用程序中我应该用DataReader类还是DataSet类呢?”在很多文章以及新闻组的贴子中我经常看到这样的误解,即认为DataReader(SqlDataReader或OleDbDataReader的缩写)比DataSet好。有时候我也会看到相反的说法。事实上,Microsoft创建了这两个数据存取类是因为它们都是我们所需要的。每个类都有其优点和不足,你可以根据应用环境来选择用哪一个。

本文就两者的选择问题做了很清楚的讲述,可以让你在运用ASP.NET时,在选择DataReader类或DataSet类的方面得到一些指南。在基于客户端的Windows Form应用程序环境下,这些规则可能会改变。我在做这些讲述时,假设你已经用过DataReader和DataSet类了,并对它们很熟悉。

运用DataReader类 
下面就是运用DataReader类的理想条件: 你读取的数据必须是新的,所以在每次需要数据的时候,你都必须从数据库读取。创建一个DataReader类不会消耗很多内存,不过随着负荷的增加,DataSet上的性能也会很快地提高(参考资源中Visual Studio Magazine中的文章)。 
你对每行数据的需求很简单。该情况的最好的例子就是简单地将DataReader绑定到一个Web控件,如DataGrid或DropDownList。 
你只需要从数据库中以只向前的(forward-only) 、只读的形式来存取XML数据。在这种情况下,你可以用SQLCommand对象的ExcecuteXmlReader()方法来得到一个XmlReader类(相当于XML版的DataReader)。这就需要一个运用FOR XML子句的SQL Server查询,或者一个包含有效XML的ntext字段。 
你计划对数据库进行几个重复的调用,来读取一小块信息。在这种情况下,我们前面提到过的性能数据会有更大的提高。 
的确,使DataSet类更强大的许多功能只适用于基于客户端的Windows Form应用程序,比如在多个表之间建立关系的功能。在很多情况下,DataSet类都比DataReader类更有优势,而且在有些情况下,你根本就不能用DataReader类。

运用DataSet类 
在下面的情况,你应该考虑运用DataSet类: 你构建了一个Web service,它运用的数据是你作为返回值读取的数据。因为DataReader类必须保持到数据库的连接,所以它们不能被序列化到XML中,也不能被发送给一个Web service的调用者。 
你需要排序或筛选数据。在运用一个DataView对象(呈现为DataTable类的DefaultView属性,它包含一个DataSet类)来排序或筛选数据前,我们先试着用SQL查询(如WHERE和ORDER BY语句)来实现这些功能,并运用更轻量级、更快的DataReader类。然而,有时侯用这种方法是不行的,或者当你需要多次地对数据进行排序或筛选时就不能用DataReader。 
针对同一请求,你需要多次遍历数据。你只能在DataReader中循环一次。如果你想将多个ServerControl类绑定到同一个数据集,那么选择DataSet就更好。DataReader类不能被绑定到多个ServerControl类,因为它是只向前读取的。在这种情况下,如果要使用DataReader,必须从数据库读取两次数据。 
你需要存储数据,而后续的页面请求可能会用到的这些数据。如果数据只被请求它的专门的人使用,你可以将DataSet类保存在一个Session变量中。如果数据可以被任何人访问,那么你可以将它保存在一个Application变量中,或保存在Cache中(我建议使用后一种方法,因为它支持时间期限和回调(callback))。因为DataReader类必须一直打开对数据库的连接,而且它一次只能保存一行数据,所以它们不能在跨页面请求中被保存。 
你需要对一个结果集的每个元素实现特殊的、耗时的功能。例如,如果你从一个数据库读取一列邮政编码,并想通过调用一个Web service来得到每个地区的详细的天气状况信息,那么选择DataSet就会更好。这是因为,当你在用DataReader类时,在关闭DataReader类前,与数据库的连接不会被释放回连接池。在数千页面请求之间潜在的一个很小的延时都会造成Web应用程序的很高的访问量,从而就会消耗完可用的连接。相反,DataSet可以在前端读取所有的数据,并可以马上关闭与数据库的连接,将它返回到连接池,因此其它的页面请求就可以用这个连接了。 
你需要在一个两维范例中加载并处理XML数据。DataSet类对于XML很有用,因为你可以将DataView用于XML,对根本的数据进行排序和筛选,就同处理一个数据库结果集一样。然而,需要注意的是在System.Xml名字空间中有很多类,你可以将它们用于更复杂的XML操作。 
你的数据源不是一个数据库。虽然OleDbDataReader可以用于任何OLEDB数据提供者(可能指向一个数据库,也可能不指向一个数据库),但DataSet对象可以从一个XML文件直接加载数据,并动态地解释它的schema。DataSet类也可以将XML数据写回一个数据流或一个文件。

从上面的讲述我们就可以看到,DataSet类比DataReader类有更多的功能,这就可以让你在更多的情况下运用它们。但这并不意味着你总是在用DataSet类。你需要在ASP.NET中完成的相当大一部分的任务都属于DataReader的范畴。

尽管如此,毫无疑问,从重要程度或复杂程度的角度来说,DataSet类在很多ASP.NET Web应用程序中都起着很重要的作用。你可以通过明智的缓存来最小化数据库往返,从而降低DataSet类的“性能损害”。DataReader和DataSet都是一个成功的ASP.NET Web应用程序的重要的部件。重要的是,我们需要了解何时、在哪里可以最好的使用它们。

 

  1. 有基类如下:
    public class parent
    {

public parent()
{
Console.Write(“Parent”);
}
}
请写出一个子类Son,要求子类的构造函数实现如下的功能:(1)输出儿子的NAME、SEX、AGE、以及Parent,(2)要求在Son的构造函数里不能有任何的命令语句出现。
public class parent
{
public parent()
{
Console.Write(“Parent”);
}
}
public class Son:parent
{ static string name=null;
static int sex=0;
static int age=0;
public parent(string name,int sex,int age):base()
{
name=name;
sex=sex;
age=age;
display();
}
publci void display()
{
Console.WriteLine(“name=”+name);
Console.WriteLine(“sex=”+sex);
Console.WriteLine(“age=”+age);
}
}
(前一阵子我参加了一次笔试,其中有一道选择题让我印象深刻,是这样的:

实例化一个X类型对象时所执行的顺序:

A.调用X类型构造函数,调用X类型基类的构造函数,调用X类型内部字段的构造函数

B.调用X类型内部字段的构造函数,调用X类型基类的构造函数,调用X类型构造函数

C.调用X类型基类的构造函数,调用X类型构造函数,调用X类型内部字段的构造函数

D.调用X类型基类的构造函数,调用X类型内部字段的构造函数,调用X类型构造函数
 

我觉的这道题出得很没水平。在C++的世界里,我会毫不犹豫的选D。但是,由于C#引入了字段初始化器,所以选什么答案完全依赖于类具体是如何设计的。好吧,我们今天就来谈谈C#在类型实例化时都有哪些步骤。

首先我们都知道,对于类对象,在执行构造函数之前,我们需要使用关键字new来为新实例分配内存。new可以根据对象的类型来为其在堆上分配足够的空间,并且将这个对象的所有字段都设为默认值。也就是说,CLR会把该对象的所有引用类型字段设为null,而把值类型字段的所有底层二进制表示位设为0(本质上来说,不论是将值类型或引用类型字段初始化为“默认值”,其实都是把他们底层的数据位设为0)。这是任何类对象实例化的第一步。

我们暂且先不考虑对象有指定基类的情况,先看看下面的代码吧:

class MyClass{  
   static MyClass()  
   {     
       Console.WriteLine("静态构造函数被调用。");  
   }
   privatestatic Component staticField =new Component("静态字段被实例化。");
   private Component instanceField =new Component("实例成员字段被实例化。");
   public MyClass()  
   {     
      Console.WriteLine("对象构造函数被调用。");  
   }
}

//此类型用于作MyClass类的成员//此类型在实例化的时候可以再控制台输出自定义信息,以给出相关提示class Component
{  
   public Component(String info)  
   {     
      Console.WriteLine(info);  
   }
}

class Program
{
   staticvoid Main(string[] args)
   {
      MyClass instance =new MyClass();
   }

复制代码

很显然,静态构造函数和静态字段的构造函数会首先被调用。因为CLR在使用任何类型实例之前一定会先装载该类型,也就需要调用静态构造函数并且初始化静态成员。但是,到底是先初始化静态成员呢,还是调用静态构造函数呢?答案是初始化静态成员,因为CLR必须保证在执行构造函数的方法体时,相关的成员变量应该都可以被安全地使用。同样的道理也适用于实例构造函数和字段,也就是说对象成员的实例化会先于成员构造函数被执行。顺便说一句,类定义直接初始化类\对象字段的功能是由类\对象字段初始化器完成的。以下是实例化MyClass对象时控制台的输出:

静态字段被实例化。
静态构造函数被调用。
实例成员字段被实例化。
对象构造函数被调用。

复制代码

接下来,我们看看如果对象有指定的基类的情况:

class Base
{
   static Base()
   {
      Console.WriteLine("基类静态构造函数被调用。");
   }  

   privatestatic Component baseStaticField =new Component("基类静态字段被实例化。");
   private Component baseInstanceField =new Component("基类实例成员字段被实例化。");

   public Base()
   {
      Console.WriteLine("基类构造函数被调用。");
   }
}

//此类型用作派生类,同基类一样,它也包含静态构造函数,以及静态字段、实例成员字段各一个。class Derived : Base
{
   static Derived()
   {
      Console.WriteLine("派生类静态构造函数被调用。");
   }

   privatestatic Component derivedStaticField =new Component("派生类静态字段被实例化。");
   private Component derivedInstanceField =new Component("派生类实例成员字段被实例化。");

   public Derived()
   {
      Console.WriteLine("派生类构造函数被调用。");
   }
}

//此类型用于作为Base类和Derived类的成员
//此类型在实例化的时候可以在控制台输出自定义信息,以给出相关提示class Component
{
   public Component(String info)
   {
      Console.WriteLine(info);
   }
}

//在主程序里实例化了一个子类对象class Program
{
   staticvoid Main(string[] args)
   {
      Derived derivedObject =new Derived();
   }
}

复制代码

类似于上个例子里的MyClass,这里的子类Derived和基类Base都有静态构造函数,也包含静态和实例成员各一个。当实例化一个子类Derived对象的实例时,输出的结果可能并不容易想到:

派生类静态字段被实例化。
派生类静态构造函数被调用。
派生类实例成员字段被实例化。
基类静态字段被实例化。
基类静态构造函数被调用。
基类实例成员字段被实例化。
基类构造函数被调用。
派生类构造函数被调用。

复制代码

从结果我们可以看出,派生类的静态字段初始化,静态构造函数调用,实例成员字段初始化都会先于基类的任何初始化动作被执行。对于派生类静态部分先被构造这一点比较容易理解,因为毕竟在CLR装载派生类Derived之前,基类Base还未被使用过,也就不会先被装载。

但是,为什么派生类的实例成员字段会在基类被构造之前被初始化呢?答案和虚函数有关。试想有这么一个基类,它在构造函数中调用了一个虚方法。然后又有这么一个派生类,它重写了基类的那个虚方法,并且在这个虚方法中访问了它自己的一个实例成员字段。这一切都是完全合法的(至少在C#的世界里是这样的),对吧?在实例化一个派生类对象的过程中,其基类的构造函数会被调用,接着那个虚方法也会被调用,再接着派生类的实例成员字段会被访问。所以此时此刻,这个类的实例成员字段必须是已被准备好了的!因此,派生类的实例成员字段必须先于基类部分被构造。

好了,再回到我们的例子。剩下的部分很容易理解:基类按照我们预想的方式被生成,然后派生类的构造函数被调用。至此,一个派生类的对象就被实例化了。

顺便说一句,关于类字段初始化器,或对象字段初始化器,他们初始化成员字段的顺序是成员在类定义中出现的先后顺序。再顺便说一句,如果程序的逻辑依赖于成员在类定义中出现的顺序则是不好的设计,这可能会大大降低您代码的易读性。

现在当我们再回过头看文章开头的题目时,一切都明朗了——根本就没有一个正确答案!因为如果X类型有对象字段初始化器,且其构造函数内没有初始化任何实例字段的话,答案应该选B。如果X类型没有对象字段初始化器,且其构造函数内初始化了实例字段的话,答案选C。如果X类型没有对象字段初始化器,且其构造函数内没有初始化任何实例字段的话,答案选D。再其他的情况,则没有答案可选了。)

  1. 请例举出三种以上进行页面重定向的方式(包括服务端和客户端)

答:第一种: Response.Redirect,

第二种: Server.Transfer

第三种: <a href = “url”></a>
function redirect(url) {
document.theForm.action = url;
document.theForm.submit();
}

第四种: StringBuilder sb=new StringBuilder();
sb.Append(“<script language=javascript>parent.frames[\"main\"].location=\”");
sb.Append(“GetResult.aspx”);
sb.Append(“?minVal=”);        sb.Append(TextBox1.Text);
sb.Append(“&maxVal=”);        sb.Append(TextBox2.Text);
sb.Append(“\”;</script>”);
Response.Write(sb.ToString());

(<a>标签

1.         <a href=”test.aspx”></a>

2.         这是最常见的一种转向方法;

HyperLink控件

1.         Asp.net 服务器端控件 属性NavigateUrl指定要跳转到的Url地址

2.         NavigateUrl是可以在服务器端使用代码修改,这个区别于<a>

3.         由于HyperLink本身没有事件所以要在服务器端其它事件中设置NavigateUrl

4.         代码示例

<Asp:HyperLink id=”hyperlink” runat=”server” NavigatoeUrl=”test.aspx”>ok</Asp:HyperLink>

Response.Redirect()方法

1.         过程:发送一个Http响应到客户端,通知客户端跳转到一个新的页面,然后客户端再发送跳转请求到服务器端。

2.         页面跳转之后内部控件保存的所有信息丢失,当A跳转到B,B页面将不能访问A页面提交的数据信息。

3.         使用这个方法使用这个方法跳转后浏览器地址栏的Url信息改变

4.         可以使用Session Cookies Application等对象进行页面间的数据传递

5.         重定向操作发生在客户端,总共涉及到两次与Web服务器的通信:一次是对原始页面的请求,另一次是重定向新页面的请求

Server.Transfer()方法

1.         实现页面跳转的同时将页面的控制权进行移交

2.         页面跳转过程中Request Session等保存的信息不变,跳转之后可以使用上一个页面提交的数据

3.         跳转之后浏览器地址栏的Url不变

4.         这种方法的重定向请求是在服务器端的进行的,浏览器不知道页面已经发生了一次跳转

Server.Execute()方法

1.         该方法允许当前页面执行同一个Web服务器上的另一个页面

2.         页面执行完毕之后重新回到原始页面发出Server.Execute()的位置。

3.         这种方式类似针对页面的一次函数调用 被请求的页面可以使用原始页面的表单数据和查询字符串集合

4.         被调用页面的Page指令的EnableViewStateMac属性设置为False

JavaScript

        string str = "<script language=javascript>history.go(-2);</script>";
        Response.Write(str);

话题相关:

1.         为了确保HTML输出的合法性 最好使用Response.Redirect方法;因为Server.Execute 或者Server.Transfer方法返回给客户端的页面包含多个<Html><body>标记,不是合法的HTML页面,在非IE浏览器中可能会发生错误。

2.         由于Server.Transfer在服务器端执行重定向,所以避免了不必要的网络通信,从而获得了更好的性能和浏览效果

  1. 写出禁用ViewState的语句

答:默认情况下,ViewState是被启用的,比如提交表单后,表单中输入的值会自动保留。但是如果不需要保留,也可以将其禁用,这样可以节省资源。下面3种方式就可以分别禁用某一个控件、某一个页面和整个应用程序的ViewState。

1) 控件禁用:将控件的EnableViewState属性设置为false;
2) 页面禁用:在页面的Page指令中添加EnableViewState="false";
3) 应用程序禁用:在Web.Config文件中添加
程序代码 程序代码
<configuration>
    <system.web>
        <pages enableViewState="false"/>
    </system.web>
</configuration>

也可以在页面的page指令中禁用 EnableViewState="false"

有的时候我们发现ViewState不能正常传值了,可能是被禁用,再次启用就可以了!

简单的说它就是ASP.NET中用来保存页面中信息以及控件值(上次返回的信息)的一种机制。客户端需要和服务器端进行交互的时候,服务器端在返回处理后的值给客户端之后,是没有保存处理后的值得。所以,有些必要的值都会保存到ViewState中。

需要在回发过程中保留的页面的当前状态的值将被序列化为Base64编码的字符串,并输出到ViewState的隐藏字段中。通过自定义的PageStatePersiste类以存储页数据。

默认情况下ASP.NET是启用ViewState的,这样在页面中会生成一大坨隐藏字段。但是,只有需要交互的页面中,也就是需要postback处理的页面才可能会用到它。所有,如果这个控件只是用来展示数据,而不需要提交数据的话,我们就可以将该控件的ViewState禁用掉。

 

  1. 怎样从弹出窗口中刷新主窗口?

答:

后台方法:

private void button1_Click(object sender, System.EventArgs e)
{
Form2 frm = new Form2();
try
{
frm.ShowDialog(this);
}
finally
{
frm.Dispose();
}
}

private void button1_Click(object sender, System.EventArgs e)
{
Form parent = this.Owner as Form;
if(parent != null)
parent.Refresh();
}

js方法:window.opener     或者   window.parent 或者  window.dialogArguments

(a   页面 
var   s   =window.showModalDialog( "b.aspx ",window   , " "); 
      if(s!=null){   //返回值 
                  document.location.replace(document.location.href);//刷新     
      } 

b页面 
if(!IsClientScriptBlockRegistered   ( "ClientScript ")) 

string   strScript= " <script   language= 'javascript '> "; 
strScript+= "window.parent.returnValue= ' "+strDetailSearch+ " '; "; 
strScript+= "window.parent.close(); "; 
strScript+= " </script> "; 
Page.RegisterClientScriptBlock( "ClientScript ",strScript); 

window.location.reload();)

 

 

 

 

 

1. C#的垃圾回收机制是怎样的?

答:析构函数一般情况是不需要,系统垃圾回收自动管理。但是当对象中有用到系统资源的时候,需要即时释放,而不能等系统自动回收,所以这个时候需要析构函数,也就是我们调用dispose的时候

2.  委托的作用是什么?

答; 委托是用来处理其他语言(如 C++、Pascal 和 Modula)需用函数指针来处理的情况的。不过与 C++ 函数 指针不同,委托是完全面对对象的;另外,C++ 指针仅指向成员函数,而委托同时封装了对象实例和方法。

简单的说委托就是对函数指针的一个封装。所谓的函数指针,了解C++的人都应该知道,函数指针中存放的 是函数的地址,当调用是,使用这个指针就可以调用到函数。而委托只不过是给这个指针穿的件漂亮的衣服, 使他变的更安全更强大。

了解了什么是委托,以及如何建立一个委托我们已经知道了。但是委托有什么用呢?为什么要用委托呢? 前面提到了,委托是用来用来处理其他语言需用函数指针来处理的情况的。这是他作用之一,总的说来在.NET 平台上委托有三大作用:实现委托功能,实现回调函数功能,实现事件功能。

3. As 和is的区别?

答:is 是类型的判断,如果一个类型是这个类型的父类返回true,他永远不会抛出异常. As是类型的转换 ,他必须就用于引用类型之间的转换, 他转换失败返回的为NULL,他也不会抛出异常。

4. 值类型与引用类型的区别?

答:1. 值类型是存在栈上,引用类型是存在堆上

           2. 值类型的是存的有效值,引用类型是存的对像的引用。

           3. 值类型存取速度快,引用类型存取速度慢。

5. 应用程序集与应用程序域

答:(一) 应用程序集,就像是EXE和DLL

程序集仅在需要时才加载到内存中。

(二)应用程序域通常由运行库宿主创建和操作。他使应用程序与数据彼此分离可以提高安全性,单个进程可以执行多个应用程序域。

应用程序域中,程序集的代码只需加载一次,实例和静态成员不能在应用程序域之间共享,也不能直接访问另一个应用程序域中的对像。此时就需要一个代理(proxy)

6.  接口与抽象类的区别?

答:区别一,两者表达的概念不一样。抽象类是一类事物的高度聚合,那么对于继承抽象类的子类来说,对于抽象类来说,属于“是”的关系;而接口是定义行为规范,因此对于实现接口的子类来说,相对于接口来说,是“行为需要按照接口来完成”。

区别二,抽象类在定义类型方法的时候,可以给出方法的实现部分,也可以不给出;而对于接口来说,其中所定义的方法都不能给出实现部分。

区别三,继承类对于两者所涉及方法的实现是不同的。继承类对于抽象类所定义的抽象方法,可以不用重写,也就是说,可以延用抽象类的方法;而对于接口类所定义的方法或者属性来说,在继承类中必须要给出相应的方法和属性实现。

区别四,在抽象类中,新增一个方法的话,继承类中可以不用作任何处理;而对于接口来说,则需要修改继承类,提供新定义的方法。

如下给出两者的简单对比表格。

 

接口

抽象类

多继承

支持

不支持

类型限制

没有

有,只能是引用类型

方法实现

继承类型中必须给出方法实现

继承类中可以不给出

扩展性

比较麻烦

相对比较灵活

多层继承

比较麻烦,需要借助虚函数

比较灵活

 

 

7. 索引的作用是什么?

答:就象是书的目录,可以加快查找数据的速度,提高数据库的性能,他还可以使表与表的之间的连接速度加快.

聚集索引:他会对表和视图进行物理排序,他们之间只能有一个聚集索引.

非聚集索引:他不会对表和视图进行物理排序,

唯一索引:他不允许两列有相同的值.

8. 存储过程与函数的区别?

1.  一般来说,存储过程实现的功能要复杂一点,而函数的实现的功能针对性比较强。
    2.  对于存储过程来说可以返回参数,而函数只能返回值或者表对象。
    3.  存储过程一般是作为一个独立的部分来执行,而函数可以作为查询语句的一个部分来调用,由于函数可以返回一个表对象,因此它可以在查询语句中位于FROM关键字的后面。

可以出现量,和运算都可以用做函数

存储过程的值不能参于运算。

9.  inner join 与 left join 和right join的区别?

 答: inner join,full outer join,left join,right jion
内部连接 inner join 两表都满足的组合
full outer 全连 两表相同的组合在一起,A表有,B表没有的数据(显示为null),同样B表有
A表没有的显示为(null)
A表 left join  B表 左连,以A表为基础,A表的全部数据,B表有的组合。没有的为null
A表 right join B表 右连,以B表为基础,B表的全部数据,A表的有的组合。没有的为null

举个例子:   
  假设a表和b表的数据是这样的。   
  a                         b     
  id     name  id     stock    
  1  a             1         15   
  2         b             2         50   
  3         c                   
    
  select   *   from   a   inner   join   b   on   a.id=b.id   
  这个语法是连接查询中的内连接,它产生的结果是   
  两个表相匹配的记录出现在结果列表中。   
  根据上面的表,出现的结果是这样的   
  a.id     name     b.id     stock   
  1       a             1         15   
  2             b             2         50   
  ----------------------------   
  select   *   from   a,b   where   a.id=b.id   
  这个语法是内连接的另外一种写法,其执行结果与inner   join   一样   
    
  --------------------------------     
    
  select   *   from   a   left/right   join   b   on   a.id=b.id   
  这个是外连接语法中的左外连接或右外连接   
  如果是左外连接的话,它将显示a表的所有记录,   
  select   a.*,b.*   from   a   left   join   b   on   a.id=b.id   
  查询的结果是这样的:   
  a.id     name     b.id     stock   
  1         a         1             15   
  2               b         2             50   
  3               c       null         null    
  --------------------------------------------   
  如果是右外连接的话,它将显示b表的所有记录,   
  select   a.*,b.*   from   a   right   join   b   on   a.id=b.id   
  查询的结果是这样的:   
  a.id     name     b.id     stock   
  1         a         1             15   
  2               b         2             50  

10.              数据库的四种变量有,char,nchar ,varchar,nvarchar,的区别?

答:1、CHAR。CHAR存储定长数据很方便,CHAR字段上的索引效率级高,比如定义char(10),那么不论你存储的数据是否达到了10个字节,都要占去10个字节的空间,不足的自动用空格填充,所以在读取的时候可能要多次用到trim()。

2、VARCHAR。存储变长数据,但存储效率没有CHAR高。如果一个字段可能的值是不固定长度的,我们只知道它不可能超过10个字符,把它定义为 VARCHAR(10)是最合算的。VARCHAR类型的实际长度是它的值的实际长度+1。为什么“+1”呢?这一个字节用于保存实际使用了多大的长度。从空间上考虑,用varchar合适;从效率上考虑,用char合适,关键是根据实际情况找到权衡点。

3、TEXT。text存储可变长度的非Unicode数据,最大长度为2^31-1(2,147,483,647)个字符。

4、NCHAR、NVARCHAR、NTEXT。这三种从名字上看比前面三种多了个“N”。它表示存储 的是Unicode数据类型的字符。我们知道字符中,英文字符只需要一个字节存储就足够了,但汉字众多,需要两个字节存储,英文与汉字同时存在时容易造成 混乱,Unicode字符集就是为了解决字符集这种不兼容的问题而产生的,它所有的字符都用两个字节表示,即英文字符也是用两个字节表示。nchar、 nvarchar的长度是在1到4000之间。和char、varchar比较起来,nchar、nvarchar则最多存储4000个字符,不论是英文 还是汉字;而char、varchar最多能存储8000个英文,4000个汉字。可以看出使用nchar、nvarchar数据类型时不用担心输入的字 符是英文还是汉字,较为方便,但在存储英文时数量上有些损失。

所以一般来说,如果含有中文字符,用nchar/nvarchar,如果纯英文和数字,用char/varchar

我把他们的区别概括成:
CHAR,NCHAR 定长,速度快,占空间大,需处理
VARCHAR,NVARCHAR,TEXT 不定长,空间小,速度慢,无需处理
NCHAR、NVARCHAR、NTEXT处理Unicode码

 

11.              临时表和表变量的区别?

答:临时表:临时表与永久表相似,但临时表存储在数据库中,当不使用时就自动删除。

           临时表分为两种:本地(名称以#)和全局(名称以##)两种类型的临时表。二者的名称,可见性和可使用性上均有不同。

尽可以使用表变量不使用临时表,他有以下优点

1.  他类似于局部变量,有明确的作用域,该作用域为声明该变量的函数,存储过程,或批处理。

2.  在存储过程使用表变量和临时表相比,减少的存储过程的重新编译量。

3.  涉及表变量的事务只在表变量更新期间存在,这样就减少了表变量对锁定和记录资源的需求

区别:1. 临时表可以支持事务级的回滚操作、但不支持前滚操作,表变量不支持事务级回滚操作,只支持语句级的回滚

           2. 临时表上的统计信息是键全而可靠的,但表变量上的统计信息是不可靠的。

           3. 范围不同。临时表为会话级,表变量为变量级,在自己代码声明区间内有效。

           4. 表变量只能指定PK做隐式的索引,临时表可以显示创造各种索引。

           5. 临时表有锁机制,面表变量中没有锁机制

           6. 如何用户访问时表变量不会产生日志,而临时表会产生日志。  

12.              Viewstate 的作用是什么?

答:是用于往返过程之间的页和控件的值。

13.              Cookie 与 session和application的区别?

答; 额,简单点说,session和cookie是针对每个用户的,application是针对所有用户有效的。
session和application是服务器上储存的,cookie是存储在客户端。一次浏览过程结束后session就没了,cookie可以保存很久(所以网站能记住帐号,自动登录等)

 

简言之, ViewState是维护页面状态的 Application是维护Web应用程序状态的,整个Web应用程序(站点/虚拟目录)只有一个 Session是维护会话状态的,每个客户有一个——是用Cookie和服务器端的信息联合实现的 具体的你看msdn吧


>>> 此贴的回复 >> Application状态为应用程序提供了一个全局的状态。所有客户都可以使用该状态。从设计的角度来说,我们通常用Application来存储一些标准的数据。同时,我们在使用它时要注意避免性能的降低,存储的数据尽可能提供给客户只读的功能。

我们可以使用HttpApplication类的Application属性来访问Application状态,它返回一个HttpApplicationState类的实例。这个类是一个对象集合,可以存储任何类型的数据,并以键/值对的形式存储。一旦数据被存储到状态后,就不会删除,除非应用程序重新启动或者被终止或回收。

我们可以在Global.asax的Application_Start函数中存储数据: void Application_Start(object src, EventArgs e) { int exp = 0; // population of dataset from ADO.NET query not shown // Cache DataSet reference Application["Experiment"] = exp; }

现在你可以在任意页面下使用它:

private void Page_Load(object src, EventArgs e) { int expr = Int32.Parse((Application["Experiment"])); }

由于Application状态对于所有客户都是共享的,如果客户只是读取该数据,则没有什么问题,一旦要进行写操作,就不能保证线程的安全以及出现同步争用的问题。我们可以使用HttpApplicationStateLock类,它派生于ReadWriteObjectLock类,它提供了读/写锁的两种属性。在ASP.Net下,隐式地调用了AcquireWrite()和AcquireRead()方法以保证避免上面的问题。当然,我们也可以显示地使用Lock()和Unlock():

private void Page_Load(object sender, System.EventArgs e) { Application.Lock(); int expr = Int32.Parse((Application["Experiment"])); if (expr>=something) { //do something } Else { //do something else } Application.UnLock(); //Some other thing goes here }

session,cookie,view状态都是用来保存客户端信息的。它们之间又有什么区别呢?

Session状态是在客户登录的时候创建的,它保存了客户特定的信息,并以Session ID来标识。当一个新客户访问应用程序时,先生成一个新的Session ID(或是Session Key),并为同一个客户接下来的请求创建联系。你可以在Session State中存储任意类型的数据,作为你的应用,状态被同一个进程和AppDomain(App域)维护。Session State的特点是为每一个特定的客户创建状态以维护客户的信息,这些状态信息存储在服务器端的默认的会话状态配置中。

Session(“Value”) = expr ; // Storing the data into session object SomeFunction() { int expr = Int32.Parse(Session(“Value”));//Accessing from it if (expr>=something) { //do something } Else { //do something else } //Some other thing goes here }

既然Session State针对特定的客户建立,通过它来识别客户的请求。Asp.Net提供了一种加密机制和编码算法生成自己的Session Key。这是非常必要的,因为知道了你的Session Key,就有权限访问指定的页面了。

在ASP.Net中生成Session Key的方法:

byte[] sessionkey = new byte[15];

//Generates a random number RNGCryptoServiceProvider rngkey = new RNGCryptoServiceProvider (); rngkey.GetBytes (sessionkey); string clientsessionKey = SessionId.Encode (sessionkey);

但是Session和客户端的Cookie是有关的,当客户关掉Cookie时,Session就失效了。不过在ASP.Net 中可以在web.config中修改设置,使Session的传递脱离Cookie。方法是:

对于Cookie大家并不陌生,每个Cookie存储了多个名/值对,我们可以通过HttpCookie类的值集合来访问它,也可以间接地通过类所提供的索引器访问。Cookie在ASP.Net下的使用: protected void Page_Load(Object sender, EventArgs E) { int expr = 0; if (Request.Cookies["Expr"] == null) { // "Expr" cookie not set, set with this response HttpCookie cokExpr = new HttpCookie("Expr"); cokExpr.Value = exprTextBox.Text; Response.Cookies.Add(cokExpr); expr = Convert.ToInt32(exprTextBox.Text); } else { // use existing cookie value... expr = Convert.ToInt32(Request.Cookies["Expr"].Value); } // use expr to customize page }

由于Cookie存储的信息是放到客户端的,用户在访问服务器端页面时,必然在客户端和服务器端之间频繁交换信息,影响了程序的性能。而Session由于存储在服务器内存中,因此不存在这个问题。不过,Session存储的信息是临时的,用户一旦关闭浏览器,状态即失去。而Cookie则相反。

至于View State,主要是指控件和页面的状态信息,它以_VIEWSTATE值传递给服务器端。有兴趣的可以看我另外一篇文章:ASP.Net中控件的EnableViewState属性

Application、Session和Cookie,可以借用Carfield的总结:

COOKIE 是本地文件,是 40 大盗在阿里巴巴家做的记号,或者是送牛奶的人在你家门口钉的箱子。

SESSION 是服务器端内存,是你洗澡时浴池发给你的钥匙。自己专用,可以开自己的好多箱子。

APPLICATION 是公共浴池。在这里能看见所有人,包括 ppmm 哦:)。

 

 

14.              Httphandles 与 HttpModels的区别?

答:ASP.Net处理Http Request时,使用Pipeline(管道)方式,由各个HttpModule对请求进行处理

抱歉!评论已关闭.