newagg新蛋笔试题(整理)

 
    下面是整理的一些新蛋笔试题,贡献下。比较乱,如果有需要的自己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对请求进行处理,然后到达 HttpHandler,HttpHandler处理完之后,仍经过Pipeline中各个HttpModule的处理,最后将HTML发送到客户端浏览 器中。
生命周期中涉及到几个非常重要的对象:HttpHandler,HttpModule,IHttpHandlerFactory,他们的执行(顺序)大致 的执行过程是这样的:client端发送页面请求,被IIS的某个进程截获,它根据申请的页 面后缀(.aspx)不同,调用不同的页面处理程序(.asp->asp.dll; .aspx->ISAPI.dll).而页面处理程序在处理过程中,则要经历HttpModule,HttpHandler的处理:前者 HttpModule用于页面处理前和处理后的一些事件的处理,后者HttpHandler进行真正的页面的处理。
如前所说,HttpModule会在页面处理前和后对页面进行处理,所以它不会影响真正的页面请求。
常用在给每个页面的头部或者尾部添加一些信息(如版 权声明)等.曾经见过一些免费的空间,我们的页面上传上去后,浏览的时候发现,
在每个页面的头部和尾部多了很多小广告....,如果理解了 HttpModule的原理,要做这个就不是很难了~

IHttpModule与IHttpHandler的区别整理
1.先后次序.先IHttpModule,后IHttpHandler. 注:Module要看你响应了哪个事件,一些事件是在Handler之前运行的,一些是在Handler之后运行的
2.对请求的处理上:
IHttpModule是属于大小通吃类型,无论客户端请求的是什么文件,都会调用到它;例如aspx,rar,html的请求.
IHttpHandler则属于挑食类型,只有ASP.net注册过的文件类型(例如aspx,asmx等等)才会轮到调用它.
3.IHttpHandler按照你的请求 生成响应的内容,IHttpModule对请求进行预处理,如验证、修改、过滤等等,同时也可以对响应进行处理
asp.net 事件模型机制

客户的请求页面由aspnet_isapi.dll这个动态连接库来处理,把请求的aspx文件发送给CLR进行编译执行,然后把Html流返回给浏览器
二 页面事件
执行顺序
Page_Init:初始化值或连接
Page_Load:主要使用IsPostBack,该事件主要执行一系列得操作来首次创建asp.net页面或响应
由投递引起得客户端事件。在此事件之前,已还原页面和控件视图状态。
Page_DataBind:在页面级别上调用,也可在单个控件中调用。
DataBind_PreRender:数据绑定预呈现,恰好在保存视图状态和呈现控件之前激发此事件。
Page_Unload:此事件是执行最终清理工作的。
非确定事件
Page_Error:如果在页面处理过程中出现未处理的例外,则激发error事件。
Page_AbortTransaction:交易事件,事务处理中如果已终止交易,则激发此事件,购物车常用。
Page_CommitTransaction:如果已成功交易,则激发此事件。
Global.asax中的事件(执行顺序)
Application_Start:应用程序启动时激发
Application_BeginRquest:http请求开始时激发
Application_AuthenticateRequest: 应用程序批准http请求时激发
Session_Start: 会话启动时激发
Application_EndRequest:Htttp请求结束时激发
Session_End:会话结束时激发
Application_End:应用程序结束时激发
Application_Error: 发生错误时激发
ISAPI: 向web服务器插入某些组建,扩展功能,增强web服务器功能。
ISAPI: 扩展,win32的动态链接库,譬如aspnet_isapi.dll,可以把ISAPI扩展看作是一个普通的应用程序,它处理的目标是HTTP请求。
ISAPI: 过滤器,web服务器把请求传递给相关的过滤器,接下来过滤器可能修改请求,执行某些操作等等。
ASP.NET请求的处理过程:
基于管道模型,在模型中ASP.NET把http请求传递给管道中所有的模块。每个模块都接收HTTP请求,并有完全的控制权。
一旦请求经过了所有的HTTP模块,最终被HTTP处理程序处理。HTTP处理程序对请求进行一些处理,并且结果将再次经过模块管道中的HTTP模块。
httpmodule 
ISAPI过滤器(筛选器):IIS本身是不支持动态页面的,也就是说他仅仅支持静态HTML页面的内容,对于.asp .aspx .cgi .php等,
IIS并不知道如果处理这些后缀标记,它就会把它当作文本,丝毫不做处理发送到客户端。为了解决这个问题,IIS有一种机制,叫做ISAPI的过滤器。它是一个COM组件。
ASP.NET服务在注册到IIS的时候,会把每个扩展可以处理的文件扩展名注册到IIS里面(如*.ascx *.aspx等)。
扩展启动后,就根据定义好的方式来处理IIS所不能处理的文件,然后把控制权跳转到专门处理代码的进程中,asp.net中是 aspnet_isapi.dll。让这个进程开始处理代码,生成标准的HTML代码,生成后把这些代码加入到原有的HTML中,最后把完整的HTML返 回给IIS,IIS再把内容发送到客户端。
HttpModule
Http模块实现了过滤器(ISAPI filter)的功能,它是实现了System.Web.IHttpModule接口的.net组件。
这些组件通过在某些事件中注册自身,把自己插入到ASP.NET请求处理管道。当这些事件发生的时候,ASP.NET调用对请求有兴趣的HTTP模块,
这样该模块就能处理请求了。有时候需要过虑一下http请求,注意它不是覆盖其他的包括系统自带的HttpModule,在Machine.config中配置完成。
HttpHandler
它实现了ISAPI Extention的功能,它处理请求(Request)的信息和发送响应(Response)。HttpHandler功能的通过必须实现IHttpHandler接口。
HTTP处理程序是实现System.Web.IHttpHandler接口的.NET组件。任何实现了该接口的类都可以用于处理输入的Http请求。它就是Http处理程序。
在以前的ASP时候,当请求一个*.asp页面文件的时候,这个HTTP请求首先会被一个名为inetinfo.exe进程所截获,这个进程实际上就是www服务。
截获之后它会将这个请求转交给asp.dll进程,这个进程就会解释这个asp页面,然后将解释后的数据流返回给客户端浏览器。
其实ASP.DLL是一个依附在IIS的ISAPI文件,它负责了对诸如ASP文件,ASA等文件的解释执行,
ASP.NET的HTTP请求处理方法
当客户端向web服务器请求一个*.aspx的页面文件时,同asp类似,这个http请求也会被inetinfo.exe进程截获(www服务),它判断文件后缀之后,
把这个请求转交给ASPNET_ISAPI.DLL而ASPNET_ISAPI.DLL则会通过一个Http PipeLine的管道,将这个http请求发送给ASPNET_WP.EXE进程,
当这个HTTP请求进入ASPNET_WP.EXE进程之后,asp.net framework就会通过HttpRuntime来处理这个Http请求,处理完毕后将结果返回给客户端。
当一个http请求被送入到HttpRuntime之后,这个Http请求会继续被送入到一个被称之为HttpApplication Factory的一个容器当中
,而这个容器会给出一个HttpApplication实例来处理传递进来的http请求,而后这个Http请求会依次进入到如下几个容器中:
HttpModule --> HttpHandler Factory --> HttpHandler
当系统内部的HttpHandler的ProcessRequest方法处理完毕之后,整个Http Request就被处理完成了,客户端也就得到相应的东东了。
完整的http请求在asp.net framework中的处理流程:
HttpRequest-->inetinfo.exe->ASPNET_ISAPI.DLL-->Http Pipeline-->ASPNET_WP.EXE-->HttpRuntime-->HttpApplication Factory-->
HttpApplication-->HttpModule-->HttpHandler Factory-->HttpHandler-->HttpHandler.ProcessRequest()
如果想在中途截获一个httpRequest并做些自己的处理,就应该在HttpRuntime运行时内部来做到这一点,确切的说时在HttpModule这个容器中做到这个的。
系统本身的HttpModule实现一个IHttpModule的接口,当然我们自己的类也能够实现IHttpModule接口,这就可以替代系统的HttpModule对象了。

15.              执行一个界面的最先调用的那个方法(见上题)?

16.              继承与组合的公优缺点。

答; 继承关系最大的弱点是打破了封装,子类能够访问父类的实现细节,子类与父类之间紧密耦合,子类缺乏独立性,从而影响了子类的可维护性。为了尽可能地克服继承的这一缺陷,应该遵循以下原则:

·精心设计专门用于被继承的类,继承树的抽象层应该比较稳定。

·对于父类中不允许覆盖的方法,采用final修饰符来禁止其被子类覆盖。

·对于不是专门用于被继承的类,禁止其被继承。

·优先考虑用组合关系来提高代码的可重用性。

本章对组合关系和继承关系进行了比较,表6-2对这两种关系的优缺点做了总结。

表6-2 比较组合关系与继承关系

组 合 关 系

继 承 关 系

优点:不破坏封装,整体类与局部类之间松耦合,彼此相对独立

缺点:破坏封装,子类与父类之间紧密耦合,子类依赖于父类的实现,子类缺乏独立性

优点:具有较好的可扩展性

缺点:支持扩展,但是往往以增加系统结构的复杂度为代价

优点:支持动态组合。在运行时,整体对象可以选择不同类型的局部对象

缺点:不支持动态继承。在运行时,子类无法选择不同的父类

优点:整体类可以对局部类进行包装,封装局部类的接口,提供新的接口

缺点:子类不能改变父类的接口

缺点:整体类不能自动获得和局部类同样的接口

优点:子类能自动继承父类的接口

缺点:创建整体类的对象时,需要创建所有局部类的对象

优点:创建子类的对象时,无须创建父类的对象

 

 

 

 

 

 

 

11、    Attribute的参数?
答:Attribute类的构造函数没有参数,
AttributeUsageAttribute类指定另一特性类的用法,有一个参数
public AttributeUsageAttribute( AttributeTargets validOn);
12、    怎样确定垃圾确实被回收了,调用了supressfinalize或collect方法就一定销毁了对象吗?显示调用了析构方法就一定销毁了对象吗?
答:垃圾回收 GC 类提供 GC.Collect 方法,您可以使用该方法让应用程序在一定程度上直接控制垃圾回收器,这就是强制垃圾回收。
Finalize 方法和析构函数如何允许对象在垃圾回收器自动回收对象的内存之前执行必要的清理操作。
对于您的应用程序创建的大多数对象,可以依靠 .NET Framework 的垃圾回收器隐式地执行所有必要的内存管理任务。但是,在您创建封装非托管资源的对象时,当您在应用程序中使用完这些非托管资源之后,您必须显式地释放它们。最常见的一类非托管资源就是包装操作系统资源的对象,例如文件、窗口或网络连接。虽然垃圾回收器可以跟踪封装非托管资源的对象的生存期,但它不了解具体如何清理这些资源。对于这些类型的对象,.NET Framework 提供 Object.Finalize 方法,它允许对象在垃圾回收器回收该对象使用的内存时适当清理其非托管资源。默认情况下,Finalize 方法不执行任何操作。如果您要让垃圾回收器在回收对象的内存之前对对象执行清理操作,您必须在类中重写 Finalize 方法。当使用 C# 和 C++ 的托管扩展以外的编程语言进行开发时,您可以实现 Finalize 方法。C# 和托管扩展提供析构函数作为编写终止代码的简化机制。析构函数自动生成 Finalize 方法和对基类的 Finalize 方法的调用。在 C# 和托管扩展编程语言中,您必须为终止代码使用析构函数语法
13、    怎样进行Forms的身份验证
就是考 FormsAuthentication
Web。Config文件设置如下:
<?xml version=”1.0″ encoding=”utf-8″ ?>
<configuration>

<system.web>

<!–  身份验证
此节设置应用程序的身份验证策略。可能的模式是 “Windows”、
“Forms”、 “Passport” 和 “None”

“None” 不执行身份验证。
“Windows” IIS 根据应用程序的设置执行身份验证
(基本、简要或集成 Windows)。在 IIS 中必须禁用匿名访问。
“Forms” 您为用户提供一个输入凭据的自定义窗体(Web 页),然后
在您的应用程序中验证他们的身份。用户凭据标记存储在 Cookie 中。
“Passport” 身份验证是通过 Microsoft 的集中身份验证服务执行的,
它为成员站点提供单独登录和核心配置文件服务。
–>
<authentication mode=”Forms” >
<forms name=”FrmMain” loginUrl=”PageLogin.aspx” protection=”None” timeout=”60″>
<credentials passwordFormat=”Clear”>
<user name=”User1″ password=”user1!”/>
<user name=”User2″ password=”user2@”/>
<user name=”User3″ password=”user3#”/>

</credentials>
</forms>
</authentication>
<!–  授权
此节设置应用程序的授权策略。可以允许或拒绝不同的用户或角色访问
应用程序资源。通配符: “*” 表示任何人,”?” 表示匿名
(未经身份验证的)用户。
–>
<authorization>
<allow users=”user2,user3″ /> <!– 允许所有用户 –>
<deny user=”user1″/><!–否定的用户列表–>
<!–  <allow     users=”[逗号分隔的用户列表]”
roles=”[逗号分隔的角色列表]“/>
<deny      users=”[逗号分隔的用户列表]”
roles=”[逗号分隔的角色列表]“/>
–>
</authorization>

<!–  会话状态设置
默认情况下,ASP.NET 使用 Cookie 来标识哪些请求属于特定的会话。
如果 Cookie 不可用,则可以通过将会话标识符添加到 URL 来跟踪会话。
若要禁用 Cookie,请设置 sessionState cookieless=”true”。
–>
<sessionState
mode=”InProc”
stateConnectionString=”tcpip=127.0.0.1:42424″
sqlConnectionString=”data source=127.0.0.1;Trusted_Connection=yes”
cookieless=”false”
timeout=”20″
/>

<!–  全球化
此节设置应用程序的全球化设置。
–>

</system.web>

</configuration>

14、    Thread中的Sleep与Suspend有什么区别,Abort的用法
Sleep //定期休眠
Suspend //暂停直到被唤醒
Abort //强制杀死线程(不建议使用)
15、    定义一个有索引器的类,并能枚举
public class MyArray
{
private string innerArray[];
public MyArray(int length)
{
this.innerArray = new string[length];
}
public string this[int index]
{
get
{
return this.innerArray[index];
}
set
{
this.innerArray[index] = value;
}
}
}

16、    SessionState的状态值:InProc?、On、Off、SQL Server?
为当前应用程序配置会话状态设置。

<sessionState mode=”Off|InProc|StateServer|SQLServer”
cookieless=”true|false”
timeout=”number of minutes”
stateConnectionString=”tcpip=server:port”
sqlConnectionString=”sql connection string”
stateNetworkTimeout=”number of seconds”/>

17、    HttpHandler

18、    StringBuilder与“+”的本质区别
StringBuilder // StringBuilder是可变的
String + string = AnotherString //字符串不可变,+会返回一个全新的字符串
19、    强指针与弱指针
强引用被C#语法直接支持,只要有强引用指向对象,一定不回收
弱引用被WeakReference类支持,当对象被回收时,指向对象的所有弱引用置空

1、    存储过程在软件开发中有什么样的优势和劣势,有什么样的缺点。
答:存储过程的优点:
(1)    允许模块化程序设计,以后可以重复调用;可以由专人来完成,并可独立于程序源代码而单独修改。这样一个项目在需求分析、界面设计以及数据库设计完了以后,就可以开始写存储过程了,同一时间数据访问层也可以开始写了。没有必要等详细设计说明完成了在编码的时候才开始写SQL语句。
(2)    执行更快
存储过程都是预编译命令,执行起来比SQL语句更快。
(3)    减少网络流量
(4)    可作为安全机制,能够屏蔽数据库,用户并不知道数据库的真实结构。
存储过程的缺点
最大的缺点就是更换数据库的时候,比如SQL_Server数据库换成Oracle数据库时SQL_Server数据库的存储过程在Oracle当中完全不能用,只能重新用Oracle的命令来写存储过程。
2、    如果你的项目在开发时使用了存储过程,在改换数据库时,会发生什么样的问题,如何解决?
答:更换数据库的时候,比如SQL_Server数据库换成Oracle数据库时SQL_Server数据库的存储过程在Oracle当中完全不能用,只能重新用Oracle的命令来写存储过程。
对于这个问题,解决的办法是:采用统一的数据库建模工具,比如( ),所有的数据库设计全部在这个统一个数据库建模工具里进行,存储过程也可以在这里完成。最后在根据需要转设成具体的某一种数据库,如果需要SQL_Server就转变成SQL_Server数据库,如果需要Oracle就转变成Oracle数据库。
3、    在存储过程中如果前面的语句发生错误,后面的语句会不会执行,为什么。

4、    在存储过程中,怎样进行异常处理?

5、    存储过程的输出参数有几种形式,分别介绍一下, 返回值的类型有没有什么限制?
答:在SQL_Server中有四种形式:
(1)、以OUTPUT参数形式返回数据,返回值的类型限制为:整形值、字符值也可以是游标变量,这种形式,可以一次返回多个值。
(2)、以Return的形式返回值,返回值的类型限制为:整形值, 以表明过程的执行状态。
(3)、返回SELECT语句的结果集。
(4)、可以返回能从存储过程外引用的全局游标。
在Oracle中有三种形式:
(1)、以OUT参数形式返回数据,返回值的类型限制为:不可以是大数据类型如:LOB、CLOB、BFILE等。
(2)、以IN OUT形式返回数据,返回值的类型限制为:也不可以是大数据类型。
(3)、返回SELECT语句的结果集。
在Oracle中存储过程没有Return的返回值,只有方法Function才有返回值
6、    如果两个不同的存储过程在一个方中被同是调用,当其中任一个发生异常时,要求同时回滚两个存储过程的操作,怎么样处理?
答:可以创建另个一个存储过程,在这个存储中,创建一个自组事务,在这个自组事务中分别去调用那两个存储过程。语法如下:
create procedure CallTwoProc
as
begin transaction
execute 第一个存储过程
execute 第二个存储过程
commit transaction
go
7、    请谈一谈视图的优点(创建视图的必要性)。基于视图的增删改会带来什么样的问题,如何解决样的的问题?
答:视图的优点:
(1)、可以筛选表中的行。
(2)、可以将多个物理数据表抽象为一个逻辑表,有利于跨库操作。
(3)、防止未经许可的用户访问敏感数据。
(4)、降低数据库的复杂程度。
(5)、视图是一种抽象表,它不占用存储空间。
基于视图的增删改会带来两个的问题:
(1)、INSERT、UPDATE和DELETE语句都必须要满足视图的条件,即视图要能看得到的才能INSERT、UPDATE和DELETE。通过视图的删除数据,要慎用,如果视图看不到的,无法删除。
解决办法:给视图加上with check option约束之后,基于视图的更改,凡是不符合视图约束(where……)的修改、插入、删除时会报错,用以限制对视图的修改。
(2)、当一个视图是基于多个基表建立的,在视图上修改数据时,只能INSERT或UPDATE基于一个基表的字段的值,无法同时修改两个或以上的基表的字段。DELETE不能运行,因为DELETE语句仅在视图的FROM子句中只包含一个表时才可以引用更新视图。
解决办法:建立INSTEAD OF触发器,把对视图的INSERT、UPDATE、DELETE操作转换为分别对几个基表的INSERT、UPDATE、DELETE操作,分作几步进行。这样对视图的INSERT、UPDATE、DELETE操作就有效了。
8、    索引有什么样的优点,也有什么样的缺点,我们在运用索引的时候,是显示运用的吗,那是怎么样应用的呢,请举例说明。
答:索引的优点:可以加快我们的查询速度。
索引的缺点:
(1)、当我们INSERT、UPDATE、DELETE时 ,数据库系统总是要去 更新每一个索引,因此而浪费很多时间。所以在基于事务的系统中,应尽量少建立索引。
(2)、带索引的给在数据库中会占据更多的存储空间。
索引并不显示使用,而是在执行SQL语句时,当中含有WHERE、ORDER BY、GROUP BY、HAVING等了句时,即凡是有对数据进行搜索和排序的语句,查询优化器组件会找出查询效率最高的办法,而查询优化器就会选择最优的索引进行工作。
9、    如果一个表其中有三个字段很常用,它们是A,B,C三个字段 ,其中B字段更常用,那么这时我们应该怎么样创建索引。
答:创建一个组合索引,其中包括A、B、C三个字段 ,但一定要把B字段放在最前面。
因为B字段最常用,它的唯一性应该是最高的。
10、如果一个表有10万条记录,其中有10个它段非常常用,我们应该怎么样他建索引。
答:创建一个组合索引,其中只包括非常常用的10个字段 ,排列的顺序一定是按唯一性的高低进行排列,唯一性最高的字段放在最前面,唯一性最低的放在最后面。
11.触发器会产生递归调用吗,请举例说明,像这种情况,我们应该怎么样避免呢?
答:触发器会产生递归调用。有两种情况
第一种:直接递归 即触发器被激发并执行一个操作,而该操作又使同一个触发器被激发。
第二种:间接递归 即触发器被激发并执行一个操作,而该操作又使另一个触发器被激发。第二个触发器又使得第一个触发器的原始表得到更新,从而再一次引发第一个触发器。
避免的办法有:
(1)、在编写触发器里,人为的注意到这一点。
(2)、防止直接递归:alter database pubs set RECURSIVE_TRIGGERS OFF
防止间接递归:请将 nested triggers 服务器选项设置为 0。
12、如果基于一个基表创建了很多个同种类型的触发器,比如UPDATA触发器,我们跟据什么来确定他们所执行的顺序?

13、(1)在数据查询中,我们需要把两个或者多个表作横方向联接,用什么命令?
答:用联接来解决这个问题join…..on
(2)请问联接有多少种类,分别是哪几种?
答:有三种,他们是左联接 left join ….on,右联接 right join…..on, 内联接inner join……on或者join……on。
(3)在联接中,用什么来指定联接的条件?
答:用on
(4)在联接查询查询中,有没有规定在所查询的两个表的字段中一定要有主鍵字段?
答:没有这种说法,不一定必须查询主鍵,正确的说法是:典型的联接是指定一个表的外鍵以及在另一个表上的关联鍵。
14(1)在数据查询中,我们需要把两个或者多个表作纵方向联接,用什么命令?
答:使用Union联合命令。
(2)在使用Union联合命令时,我们应注意些什么?
答:所联合的几个查询,字段名可以不相同,但是字段类型、字段数都必须要相同。
(3)请说一说Union和Union All这两个命令的区别?
答:Union命令得到的结果会去掉重复项,作了一个distinct操作。
Union All命令不会去掉重复项。
15、数据库的安全和管理方面的间题没有问。

给出下面三个表的关系如下:S(sid,sname),C(cid,cname,teacher),SC(sid,cid,scgrade)
1.    写出查询语句得到学生课程成绩表,要求有以下字段:sname,cname,teacher,scgrade
select S.sname,C.cname,C.teacher,SC.scgrade from S,C,SC where S.Sid=SC.sid and C.cid=SC.cid
2.    写出查询语句得到每个教师所认学科不极格的学生人数。
select C.teacher,C.cname,count(SC.scgrade) AS NotPassCount from C,SC
where C.cid=SC.cid and SC.scgrade<60
GROUP By C.teacher,C.cname
order by C.teacher,cname
3.    写出查询语句得到学生课程成绩表,要求有以下字段:sname,cname,teacher,等级。要求等级有四等,>=90为A等,>=80为B等,>=60为C等,<60为D等。

select S.sname,C.cname,C.teacher,grade=
case
when SC.scgrade>=90 then ‘A’
when SC.scgrade>=80 then ‘B’
when SC.scgrade>=60 then ‘C’
when SC.scgrade<60 then ‘D’
end
from S,C,SC
where S.Sid=SC.sid and C.cid=SC.cid
4.    写出查询语句得到每个教师所认学科中,为A等和B等的学生人数。
第一种:查询语句得到每个教师所认所有学科的,为A等和B等的学生人数。
select A.teacher,M1.gradeCount_A ,M2.gradeCount_B from
(select distinct C.teacher from C)
as A
join
(select C.teacher,count(SC.scgrade)as gradeCount_A
from S,C,SC
where S.Sid=SC.sid and C.cid=SC.cid and SC.scgrade>=90
group by C.teacher
) as M1 on M1.teacher=A.teacher
join
(select C.teacher,count(SC.scgrade)as gradeCount_B
from S,C,SC
where S.Sid=SC.sid and C.cid=SC.cid and SC.scgrade>=80 and SC.scgrade<90
group by C.teacher
) as M2
on M2.teacher=A.teacher
第二种:查询语句得到每个教师所认每个学科的,为A等和B等的学生人数。
select A.teacher,A.cname,M1.gradeCount_A ,M2.gradeCount_B from
(select distinct C.teacher,C.cname from C)
as A
left join
(select C.teacher,C.cname,count(SC.scgrade)as gradeCount_A
from S,C,SC
where S.Sid=SC.sid and C.cid=SC.cid and SC.scgrade>=90
group by C.teacher,C.cname

) as M1 on M1.teacher=A.teacher and M1.cname=A.cname
left join
(select C.teacher,C.cname,count(SC.scgrade)as gradeCount_B
from S,C,SC
where S.Sid=SC.sid and C.cid=SC.cid and SC.scgrade>=80 and SC.scgrade<90
group by C.teacher,C.cname

) as M2
on M2.teacher=A.teacher and M2.cname=A.cname

 

 

 

 

9点半守约来到万航渡路开开大厦12层。。首先填了张表。然后得到一份试题。。试题大概有50道题。40道选择,1道英文翻译。9道简答题。。因为试题涉及知识面很广。。你可以选择熟悉的领域答题,比如选择面向对象,SOA/web serivce,算法。。
  答完题,大概到了11点10分。然后由人事下到11楼进行技术面试。面试时候问的问题。。涉及面很广。SQL(比如索引,全文索引),面向对象(如:反射,delegate等。),项目中的技术(如:线程池,自定义控件,workflow,jquery,wcf),
设计模式。。整个过程聊了1个小时。。看下表12点半。。到附近买了一杯草莓牛奶冰和小笼包对付一餐。。
  不知道这次面试官会给我一个什么样的评价。。难道是技术一般。。问的怎么全面的面试官。。应该是我碰到的第三位了。
  把我的面试经历描述给大家。。希望对正在找工作的朋友。。有所帮助。

 

 

 

笔试题

1.       线程与进程的区别是什么?      

答:1一个程序至少有一个进程,一个进程至少有一个线程。一个进程就好比一个沙箱。线程就如同沙箱中的孩子们。孩子们在沙箱子中跑来跑去,并且可能将沙子攘到别的孩子眼中,他们会互相踢打或撕咬。但是,这些沙箱略有不同之处就在于每个沙箱完全由墙壁和顶棚封闭起来,无论箱中的孩子如何狠命地攘沙,他们也不会影响到其它沙箱中的其他孩子。因此,每个进程就象一个被保护起来的沙箱。未经许可,无人可以进出。进程和线程的区别在于: 
线程的划分尺度小于进程,使得多线程程序的并发性高。 
另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。

线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。

2.       编译型语言与解释型的优缺点是什么?

答:编译语言是把要编译的语言编译成中间语言,而解释型的语言是到一句,解释一句,执行一句。所以解释型的语言比较慢。 
区别就是:如果在C中,你有语法错误,它会在编译阶段就报错;但在BASIC中,你可以执行,直到出错的语句时才报错。

3.       有一个酒吧卖酒,有一次来了一个叼酸的顾客来买酒他只要6L酒,而他们店每桶酒是12L,问酒吧如何才能一点不多一点不少的卖6L酒给顾客,酒吧有一个8L和5L的容器。

答:

4.       一个游客到了一个撒谎王国,其中男人在一周的1,2,3撒谎,女人是在4,5,6撒谎,别的时候都说真话,他也没有看日期的工具,而他又想知道今天是星期几,他问男人说,昨天是我撒谎的日子,又问了个女人,女人也说昨天是我撒谎的日子,请说出今天是星期几。

面试题

 

 

 

周六到新蛋面试去了,之前听说新蛋面试挺严的,我又有三个月没碰.Net,说实话,我根本没报多大的希望,临时抱了几天的佛脚,仓促就上阵了。

好不容易找到天府大道南沿线,进了公司,给我的第一感觉就是装修的好漂亮呀,果然是个大公司。人事部的Julia给了我一叠卷子,好多呀,有15页吧,花了半小时做完,说实话,有些真的有点偏,比如像这面这个题(我只记得大概):

下面的代码为何不能通过编译?

public int this[int index] {
    get {
        return 1;
    }
}

public int get_Item(int index) {
    return 1;
}

错误     1            类型“Fibo.ConsoleApplication.Parent”已保留了一个名为“get_Item”的具有相同参数类型的成员              D:\Visual Studio 2010\FiboStudy\Fibo.ConsoleApplication\Parent.cs              11         13         Fibo.ConsoleApplication

 

平常的应用应该不会碰到这种情况,但是如果不是对.Net的索引器很了解,是不可能答出这道题的。还好我把《.Net程序设计》看了N遍,我知道Why,by the way,再次吐血推荐这本书,做.Net不看此书就算白活了,不贵,买了保你不后悔,我现在还很期待2.0版的《CLR via C#》。卷子里的题基本上都是数据库操作、OO、.Net的一些基础概念。还好没有考我数据结构和算法,不然我就抓瞎了:)

交了卷又到了三楼Eric的办公室和一位技术人员(我估计的)聊了半个小时吧,他问的问题我基本上答的都是“不知道”:(。的确有很多不懂,再次感到差距……

最后那位技术人员要我稍等,就出去了,过了5分钟他又进来,对我说因为我还未毕业,如果对公司没有问题的话,就打算录用我来实习。有点吃惊,但更多的是高兴,没想到我还成功了,呵呵,新蛋强人蛮多,又是做.Net的,总算找着组织了:)

我打算把现在公司的事情做完再过去,不管怎么样,还是要做好现在手上的事吧。以后既然有那么好的条件,就要好好学东西、做事了。

 

 

 

面试的是高级软件工程师。在延安西路上,靠近江苏路。
进去,拿了个职位申请单和面试题。
笔试的题目,恩,怎么说呢。大家看看题目就知道了哦。
1.用Forms实现用户验证、区分角色、根据不同的角色访问不同的页面。可以利用wcf。(这个和WCF有关系吗?)
2.输入框失去焦点验证数据是否合法。
3.2个Linq的题目:从一个{1,3,5,6,2}数组中,找出小3的数字。

答;  关注.NET的程序员,对LinQ这个名词应该已经听说过了,上个星期和THIN见了一下面,他给我演示了一下LinQ,觉得很有意思,有些东西很像JavaScript。后来在他的博客里也看到他写的一编文章。自己也写了一个小Demo,现在拿出来和大家分享一下,这编都是比较简单的例子,因为我也是才自学那么几天时间。

  Demo1:

  从一个整型数组中找出偶数:

  原始写法:

以下是引用片段:
  int[] numbers = { 12, 234, 15, 43254, 2, 1, 4, 5 }; 
   
   foreach (int i in numbers) 
   { 
   if (i % 2 == 0) 
   Console.WriteLine(i); 
   }

  LinQ写法1:

以下是引用片段:

var numbers_1 = from number in numbers where (number % 2 == 0) orderby number descending select number;//orderby number descending 这是对筛选出来的数值进行排序


   foreach (var i in numbers_1) 
   { 
   Console.WriteLine(i); 
   }

LinQ写法2:

以下是引用片段:
  var numbers_1 = numbers.Where(i => i % 2 == 0).Select(i => i);//输出用写法1一样

  LinQ中使用到了var 关键字,它和JavaScript很像,您给他赋予什么类型它就是什么类型,但不能不赋值。

  这只是一个简单的小例子,并不能说明LinQ的好处,在将来的时间里,我会不断地把自己写的Demo拿出来和大家分享一下。

 关注.NET的程序员,对LinQ这个名词应该已经听说过了,上个星期和THIN见了一下面,他给我演示了一下LinQ,觉得很有意思,有些东西很像JavaScript。后来在他的博客里也看到他写的一编文章。自己也写了一个小Demo,现在拿出来和大家分享一下,这编都是比较简单的例子,因为我也是才自学那么几天时间。

  Demo1:

  从一个整型数组中找出偶数:

  原始写法:

以下是引用片段:
  int[] numbers = { 12, 234, 15, 43254, 2, 1, 4, 5 }; 
   
   foreach (int i in numbers) 
   { 
   if (i % 2 == 0) 
   Console.WriteLine(i); 
   }

  LinQ写法1:

以下是引用片段:

var numbers_1 = from number in numbers where (number % 2 == 0) orderby number descending select number;//orderby number descending 这是对筛选出来的数值进行排序


   foreach (var i in numbers_1) 
   { 
   Console.WriteLine(i); 
   }

LinQ写法2:

以下是引用片段:
  var numbers_1 = numbers.Where(i => i % 2 == 0).Select(i => i);//输出用写法1一样

  LinQ中使用到了var 关键字,它和JavaScript很像,您给他赋予什么类型它就是什么类型,但不能不赋值。

  这只是一个简单的小例子,并不能说明LinQ的好处,在将来的时间里,我会不断地把自己写的Demo拿出来和大家分享一下。


4.sqlserver中varchar(max)、text、xml的区别。
5.写分页存储过程。根据pageindex、pagesize查询。
6.sqlserver 2005创建分区表的步骤。
其他的想不起来了。我5年工作经验了,大家看了有什么感想?反正写了5分钟不到就交了。
然后=了将近10分钟。恩,技术面试来了。
大家来解答下这位"牛人"的问题:
1.你没用过Forms认证吗? (我说可以利用httpmodule,判断Authentication,再授权。)
2.一个控件,能post到另外一个页面吗?能的话,怎么接收数据。(我回答说request.form,他说不行。我说是什么,他说回去查下就知道了。
我就有点糊涂了,http协议里面的get和post还接收不到数据?那PreviousPage.FindControl这个一定需要知道吗?)
3.remoting的过程,发送remoting的时候,怎么把对象里面某个不想显示的字段隐藏掉。remoting对象怎么释放。
我的理解:remoting调用了singcall,好像会自动释放掉。他说不是,remoting对象会一直存在,你回去查查就知道了。
4.页面的生命周期:这个惭愧,自己搞不清楚了,不过把控件的生命周期说出来了。
5.get和post的区别。这个我觉得答得不错,研究过http协议

答:1.HTTP请求格式:

<request line>

<headers>

<blank line>

[<request-body>]

在HTTP请求中,第一行必须是一个请求行(request line),用来说明请求类型、要访问的资源以及使用的HTTP版本。紧接着是一个首部(header)小节,用来说明服务器要使用的附加信息。在首部之后是一个空行,再此之后可以添加任意的其他数据[称之为主体(body)]。

2.GET与POST区别

HTTP定义了与服务器交互的不同方法,最基本的方法是 GET 和 POST.

HTTP-GET和HTTP-POST是使用HTTP的标准协议动词,用于编码和传送变量名/变量值对参数,并且使用相关的请求语义。每个HTTP-GET和HTTP-POST都由一系列HTTP请求头组成,这些请求头定义了客户端从服务器请求了什么,而响应则是由一系列HTTP应答头和应答数据组成,如果请求成功则返回应答。
  HTTP-GET以使用MIME类型application/x-www-form-urlencoded的urlencoded文本的格式传递参数。Urlencoding是一种字符编码,保证被传送的参数由遵循规范的文本组成,例如一个空格的编码是"%20"。附加参数还能被认为是一个查询字符串。
  与HTTP-GET类似,HTTP-POST参数也是被URL编码的。然而,变量名/变量值不作为URL的一部分被传送,而是放在实际的HTTP请求消息内部被传送。

(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为好。

注:所谓安全的意味着该操作用于获取信息而非修改信息。幂等的意味着对同一 URL 的多个请求应该返回同样的结果。完整的定义并不像看起来那样严格。换句话说,GET 请求一般不应产生副作用。从根本上讲,其目标是当用户打开一个链接时,她可以确信从自身的角度来看没有改变资源。比如,新闻站点的头版不断更新。虽然第二次请求会返回不同的一批新闻,该操作仍然被认为是安全的和幂等的,因为它总是返回当前的新闻。反之亦然。POST 请求就不那么轻松了。POST 表示可能改变服务器上的资源的请求。仍然以新闻站点为例,读者对文章的注解应该通过 POST 请求实现,因为在注解提交之后站点已经不同了(比方说文章下面出现一条注解)。

下面举一个简单的例子来说明它们的区别:

<!-分别通过get和post方式提交表单--> 
<FORM ACTION="getpost.asp" METHOD="get"> 
<INPUT TYPE="text" NAME="Text" VALUE="http://wxf0701.cnblogs.com//
<INPUT TYPE="submit" VALUE="Get方式"></INPUT> 
</FORM> 
<BR> 
<FORM ACTION="getpost.asp" METHOD="post"> 
<INPUT TYPE="text" NAME="Text" VALUE="http://wxf0701.cnblogs.com/
<INPUT TYPE="submit" VALUE="Post方式"></INPUT> 
</FORM> 
<BR>

<% If Request.QueryString("Text") <> "" Then %> 
通过get方式传递的字符串是: "<B><%= Request.QueryString("Text") %></B>"<BR> 
<% End If %>

<% If Request.Form("Text") <> "" Then %> 
通过Post方式传递的字符串是: "<B><%= Request.Form("Text") %></B>"<BR> 
<% End If %>


最好他说,好了,今天的面试就到此结束了。有消息会通知你的。
我说好,然后就自己率先出门了。什么再见之类的话都懒得讲。整个过程10分钟不到吧。

不知道这个"牛人"在新蛋什么级别,面试过不少大公司,没见过这么高傲的。我们公司比他们公司大,我们的总监、CTO都没他那么神气呢。上海技术圈子就这么小,有必要吗?
除了第四题,没答对,是自己基础没打好。其他的几个题目,我不知道有多少人能答出来。
对新蛋很失望。感觉就是浪费我半天的时间撒。好像回到了刚工作一年时找工作的情形了。
以上只是个人看法,可能包含一些情绪,大家智者见智。

 

 

 

 

 

 

根据记忆整理如下:

 

  1. 有一个集合a,里面有n个正整数,乱序排列。给定一个正整数N,求,a中任意两个数相加等于N,共有哪些种组合情况。例如,集合为{1,3,44,2,4,5,54,222,368}  N=6,则结果集为{1,5},{2,4}

      这个题网上有类似的

 

  1. Treemap的实现。

   各种集合类的结构和优缺点,大家都挺爱考的。以前做行业信息化,没什么感觉,但是如果很在意性能,搞清楚还是挺有用的。

 

  1. 有两个很大的文件,每个文件中都有1亿行,每行一个整数。问这两个集合的交集是什么。给定的前提是机器内存不足以完全装入任意一个文件。

   这个几乎是网上的原题了

 

  1. 堆和栈的定义,堆和栈里面的对象,哪个运行速度快。

    还问了一些衍生的问题,记不清了,只要看清楚java教材关于这方面的介绍足矣

 

  1. 为了实现一个折线图,需要将数据存入一种数据结构,折线图横坐标是时间,纵坐标是值,经常的查询是按时间段进行查询,如select value from t where begin>’20110101’and end<’20111212’,问,使用java中的那种数据结构比较好。

   还是考java中的各种集合类,本质上是问各种数据结构在顺序/随机的读取/插入上的效率

 

  1. 数据库的索引通常用什么数据结构实现?为什么用这种数据结构。

   就知道是btree,但是btree是咋回事,为啥不能用其他tree或者别的结构,这个看过一篇帖子以后才明白。算是学习了。

 

  1. 如果数据库中有2个表,表a字段为姓名、年龄,表b字段为姓名、单位。现在使用姓名字段做left join查询,假设姓名字段都有索引了。问数据库是怎么实现的。如果把这两个表看为在内存中的数组,要自己实现left join,怎么实现?

   面试官看我实在不知道数据库里leftjoin怎么实现的,就让我自己实现一个内存中的,勉强答出来了吧,但是可能不太好。

 

  1. 数据库各种事务隔离级别

   这个是纯不记得了,以前工作中从来用不到,真是汗颜。

 

  1. wait()方法和notify()方法干什么用的,wait()方法有什么使用限制,是哪儿都能用么?

   对于一个从来不用多线程的人,这么简单的问题也变得有点儿难。只知道干什么用的,不知道有什么限制。

 

  1. 数据库中有一个表有上亿的数据量,怎么优化?(主要是拆分,除了按业务拆分外,还有什么从技术角度的,可扩展性好的水平拆分方式)

   思路是拆没错,但是面试官问的不是业务拆分策略,而是从技术上考虑。还得考虑扩展性,比如拆好以后,数据量增长迅速,又要拆了,怎么办。这个水平拆分策略有好多,网上能搜到。但是我说的都不是很有体系,以前没弄过,都是现场想。。

 

 

 

 

 

ps:当时上新东方的时候,老师说,有的时候虽然你英语不好,但是有几个单词只要你记住了,说的时候塞到句子里,人家就会觉得你特地道,比如absolutely之流。我觉得面试的时候也有这种key words,比如位排序之流,说的时候还得特举重若轻。适用于各类新手和平时工作中压根用不到各种排序算法的人,仅供参考。

 

 

1、    谈一谈你做过的.NET工程的系统架构是怎么样设计的,以及当时为什么要这样设计?(着重设计模式方面)
2、    请谈一谈数据访问层都做些做,具体是怎么样实现的?
3、    请谈一谈业务规则层与业务外观层以及数据访问层他们之间的怎么样发生联系的,业务规则层有什么样的特点,业务外观层都做些什么?
4、    请谈一谈你对多态的认识,举例说明多态在软件开发中给我们带来的好处(特别是在.NET方面。
5、    XMLWebService虽然它让我们开发分布式软件,但是它有一个天生的毛病:就是XMLWebService与和层之间,以级他们相互之间传递信息是依靠HTTP协议进行,所以会比较缓慢,针对这种情况,我们该如何处理。
答:增大XMLWebService中WebMethod方法的粒度,也就是便每个WebMethod方法尽量的多做一些事情,从而减少XMLWebService中WebMethod方法的数量,也就减少了依靠HTTP协议传递信息的次数,加快了速度。
6、    谈一谈你对Remoting的技术认识,
答:NET的Remoting采用代理技术,这个代理技术是由编译器自动完成的,NET的Remoting为我们的Remoting中的每一个类都产生一个代理。当我们调用Remoting中的类的方法时,首先调用的是系统产生的那个代理,由这个代理把相关的参数信息打包成一个二进制包,通过TCP/IP协议传送给我们真实的类。真实的类把运行的结果打包成一个二进制包,再通过TCP/IP协议传送给代理类。代理类再把结果打包成一个二进制包,再通过TCP/IP协议传送给调用类。
因此NET的Remoting是基于TCP/IP协议传送二进制文件,速度要比XMLWebService快。
它更适合于区域较小的局域网。
7、    Remoting与XMLWebService的区别是什么,他们各自的优缺点是什么?
答:(1)、NET的Remoting是基于TCP/IP协议传送二进制文件,速度要比XMLWebService快。
(2)、NET的Remoting也和XMLWebService一样需要在调用端生成代理。但是XMLWebService是手动生成代理。
在NET的Remoting中a.对于凡是继承于System.ContextBoundObject类的类,就是由编译器自动生成代理类;b. 对于凡是继承于System.MarshalByRefObject类的类,就是要手动生成代理的;c、对于中是继承于System.Object类的类,就是不能生成代理的类;d. 对于凡是继承于System.ContextBoundObject类的子类System.EnterpriseServices.ServicedComponent类的类,实质上就是COM+服务.
NET的Remoting可以对对调用进行捕获,并进行处理,因此它类似于COM+服务,所以说NET的Remoting是DCOM+的升级产品.
XMLWebService是基于HTTP协议传送soap包的,每点之间都是把信息打包成SOAP包,基于HTTP协议传输.就像是访问网页一样,来调用XMLWebService服务.所以XMLWebService比较慢.
8、   什么情况下适合用Remoting,什么情况下适合用XMLWebService
答: Remoting适合于这样的情况:区域较少,速度要求快,安全性要求高的环境.还适合用需要对调用进行捕获,并进行处理的情况.
XMLWebService适合于这样的情况:大距离的远程调用,速度要求不高,安全性要求也不是很高的情况.

 

 

 

 

posted on 2011-12-21 16:42  付之一笑  阅读(1979)  评论(3编辑  收藏  举报

导航