Asp.net面试题
Asp.net核心技术思想
1、概述反射和序列化
反射:程序集包含模块,而模块包含类型,类型又包含成员。反射则提供了封装程序集、模块和类型的对象。您可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性
序列化:序列化是将对象转换为容易传输的格式的过程。例如,可以序列化一个对象,然后使用 HTTP 通过 Internet 在客户端和服务器之间
传输该对象。在另一端,反序列化将从该流重新构造对象。
2.如何把一个array复制到arrayList里
方法一、使用foreach循环,将array数组中的数据逐步放入ArrayList的对象中;
方法二、使用Copy方法,进行数据的复制;
方法三、使用ArrayList的adpater的方法 ,将整个Array对象封装到ArrayList对象中。
// author:renfuming
public static void Main(string[] renargs)
{
int[] arrayInt=new int[]{1,2,3,4};
ArrayList arrlistInt=new ArrayList();
//方法一
foreach(int a in arrayInt)
{
arrlistInt.Add(a);
}
Console.WriteLine(arrlistInt[2].ToString());//输出3
//方法二:
ArrayList arrlistInt2=new ArrayList();
arrlistInt2=ArrayList.Adapter(arrayInt);
Console.WriteLine(arrlistInt2[2].ToString());//输出3
//逆向转换
Array resultArr=(int[])arrlistInt2.ToArray(typeof(int));
Console.WriteLine(resultArr.GetValue(2));//输出3
}
3.datagrid.datasouse可以连接什么数据源
[dataset,datatable,dataview,IList]等接口类型的对象
4. new有几种用法
第一种:new Class(),新建一个类的对象,但是此类必须的又可访问的构造函数
第二种:显式覆盖基类的方法:public new Menthod(){}
5.概述o/r mapping 的原理
利用反射,配置 将类于数据库表映射
O/RMapping(有学习曲线,没有工具支持会相当大):存在的时间已经很长,我认为它的最主要的作用是关系型数据库的反设计——关系型数据库的设计就是要把现实中的对象和对象间关系设计成实体和实体间的关系映射。而O/RMapping恰好相反,它是把实体和实体间的关系映射还原回对象和对象间的关系。
6.类成员有( )种可访问形式
可访问性:public ,protected ,private,internal
可能还有其他的访问形式,具体的情况视编码需要而定
7.用sealed修饰的类有什么特点
sealed 修饰符用于防止从所修饰的类派生出其它类。如果一个密封类被指定为其他类的基类,则会发生编译时错误。
密封类不能同时为抽象类。
sealed 修饰符主要用于防止非有意的派生,但是它还能促使某些运行时优化。具体说来,由于密封类永远不会有任何派生类,所以对密封类的
实例的虚拟函数成员的调用可以转换为非虚拟调用来处理。
8.列举ADO.NET中的五个主要对象,并简单描述
connection,command,dataReader,transaction,dataset ...
其上对于各种对象,连接不同的数据库将会有不同的对象变体
Connection: 数据库的连接需要此对象
Command:执行数据表变化的命令
dataReader和dataset主要是对数据库的表信息进行两种不同方式的读取,具体的读取得区别,后面将会有讲解
9.执行下面代码后:
String strTemp ="yyaccpx 某某某";
Int i System.Text.Encoding.Default.GetBytes(strTemp).Length;
Int j = strTemp.Length;
结果:i=(14 ) ;j=(11 )
i=(14 ) ;j=(11 ) 中文在内存中占两个字节
但是只算是一个字符
10.C#中,string str = null 与 string str ="",请尽量用文字说明区别。(要点:说明详细的内存空间分配)
string str ="" 在栈中存取地址,在堆中存放对象的值
而String str=null;仅仅在内存栈中分配了空间
11.详述.NET里class和struct的异同!
class:放在属于引用类型,故其存放于内存的堆中
Struct属于值类型,其存放于栈中,作为参数传递的时候属于值传递
类与结构有很多相似之处:结构可以实现接口,并且可以具有与类相同的成员类型。然而,结构在几个重要方面不同于类:结构为值类型而不
是引用类型,并且结构不支持继承。结构的值存储在“在堆栈上”或“内联”。细心的程序员有时可以通过聪明地使用结构来增强性能。
12.概述.NET里对 remoting 和 webservice 两项技术的理解和实际中的应用。
其实现的原理并没有本质的区别,在应用开发层面上有以下区别:
1、Remoting可以灵活的定义其所基于的协议,如果定义为HTTP,则与Web Service就没有什么区别了,一般都喜欢定义为TCP,这样
比Web Service稍为高效一些
2、Remoting不是标准,而Web Service是标准;
3、Remoting一般需要通过一个WinForm或是Windows服务进行启动,而Web Service则需要IIS进行启动。
4、在VS.net开发环境中,专门对Web Service的调用进行了封装,用起来比Remoting方便
我建议还是采用Web Service好些,对于开发来说更容易控制
Remoting一般用在C/S的系统中,Web Service是用在B/S系统中
后者还是各语言的通用接口
相同之处就是都基于XML
为了能清楚地描述Web Service 和Remoting之间得区别,我打算从他们的体系结构上来说起:
Web Service大体上分为5个层次:
1. Http传输信道
2. XML的数据格式
3. SOAP封装格式
4. WSDL的描述方式
5. UDDI
总体上来讲,.NET 下的 Web Service结构比较简单,也比较容易理解和应用:
一般来讲在.NET结构下的WebService应用都是基于.net framework以及IIS的架构之下,所以部署(Dispose)起来相对比较容易点.
从实现的角度来讲,
首先WebService必须把暴露给客户端的方法所在的类继承于:System.Web.Services.WebService这个基类
其次所暴露的方法前面必须有[WebMethod]或者[WebMethodAttribute]
WebService的运行机理
首先客户端从服务器的到WebService的WSDL,同时在客户端声称一个代理类(Proxy Class)
这个代理类负责与WebService服务器进行Request 和Response
当一个数据(XML格式的)被封装成SOAP格式的数据流发送到服务器端的时候,就会生成一个进程对象并且把接收到这个Request的
SOAP包进行解析,然后对事物进行处理,处理结束以后再对这个计算结果进行SOAP包装,然后把这个包作为一个Response发送给客户
端的代理类(Proxy Class),同样地,这个代理类也对这个SOAP包进行解析处理,继而进行后续操作。
这就是WebService的一个运行过程。
下面对.net Remoting进行概括的阐述:
.net Remoting 是在DCOM等基础上发展起来的一种技术,它的主要目的是实现跨平台、跨语言、穿透企业防火墙,这也是他的基本特
点,与WebService有所不同的是,它支持HTTP以及TCP信道,而且它不仅能传输XML格式的SOAP包,也可以传输传统意义上的二进制流
,这使得它变得效率更高也更加灵活。而且它不依赖于IIS,用户可以自己开发(Development)并部署(Dispose)自己喜欢的宿主服务
器,所以从这些方面上来讲WebService其实上是.net Remoting的一种特例。
ASP.NET Web 服务基础结构通过将 SOAP 消息映射到方法调用,为 Web 服务提供了简单的 API。通过提供一种非常简单的编程模型(基于将 SOAP 消息交换映射到方法调用),它实现了此机制。ASP.NET Web 服务的客户端不需要了解用于创建它们的平台、对象模型或编程语言。而服务也不需要了解向它们发送消息的客户端。唯一的要求是:双方都要认可正在创建和使用的 SOAP 消息的格式,该格式是由使用 WSDL 和 XML 架构 (XSD) 表示的 Web 服务合约定义来定义的。
. NET Remoting 为分布式对象提供了一个基础结构。它使用既灵活又可扩展的管线向远程进程提供 .NET 的完全对象语义。ASP.NET Web 服务基于消息传递提供非常简单的编程模型,而 .NET Remoting 提供较为复杂的功能,包括支持通过值或引用传递对象、回调,以及多对象激活和生命周期管理策略等。要使用 .NET Remoting,客户端需要了解所有这些详细信息,简而言之,需要使用 .NET 建立客户端。.NET Remoting 管线还支持 SOAP 消息,但必须注意这并没有改变其对客户端的要求。如果 Remoting 端点提供 .NET 专用的对象语义,不管是否通过 SOAP,客户端必须理解它们。
13.什么是code-behind技术
对于每一个Aspx文件可以相对应一个CS文件类,aspx继承自对应的CodeBehind类,在编译时,CodeBhind类编译到webui工程对应的dll中,而aspx页面中的内含代码和aspx一起编译到temporary.dll中,被客户端浏览器访问。
14.概述三层结构体系
webUI层:封装基本的页面布局形式,即表示层
DataAccess(DAO)层:数据访问层,利用各种相关的技术,与底层数据库进行交互
Business层:业务逻辑层,封装整个程序的业务逻辑代码,主要与DAO层相关联
Model 层: 封装程序领域对象,该层可以在上面的三层之间进行很好的交互
这只是基本的三层架构设计,如果利用设计模式,则可以在此基础上进行灵活的变化
15.asp.net如何实现MVC模式,举例说明!
在Asp.net 中实现MVC模式,相对于 JAVA没有那么快捷,但是仍是可以实现的
且由于代码隐藏和事件驱动得引入,意义不时很大,具体的实现,可以利用HttpHandler,如此,则应在Web.config文件中配置相关的节点
//Author:renfuming
<httpHandlers>
<add verb="*" path="SendTopic.aspx" type="wyzBBS.Servers.SendRootHandler"/>
<add verb="*" path="SelectTopic.aspx" type="wyzBBS.Servers.SelectTopicHandler"/>
<add verb="*" path="Question.aspx" type="wyzBBS.Servers.QuestionHandler"/>
<add verb="POST,GET" path="ajaxpro/*.ashx" type="AjaxPro.AjaxHandlerFactory, AjaxPro"/>
</httpHandlers>
16.值类型和引用类型的区别?
C# 支持两种类型:“值类型”和“引用类型”。
值类型(如 char、int 和 float)、枚举类型和结构类型。
引用类型包括类 (Class) 类型、接口类型、委托类型和数组类型。
值类型与引用类型的区别在于值类型的变量直接包含其数据,而引用类型的变量则存储对象引用。对于引用类型,两个变量可能引用同一个对
象,因此对一个变量的操作可能影响另一个变量所引用的对象。对于值类型,每个变量都有自己的数据副本,对一个变量的操作不可能影响另一个变量
17.了解程序集强签名吗?
用强名称来给程序集签名即谓之程序集强签名!
通过签发具有强签名的程序集合,可以确保名称的全局唯一性!因为强名称是依赖于唯一的密钥对来确保名称的唯一性,其他人不会生成与你
相同的程序集名称(不同的私钥产生的名称不同)
强名称保护程序集的版本沿袭,因为强名称的唯一性能够确保没有其他人能够生成你的程序集的后续版本
强名称提供可靠的完整性检查,通过.NET Framework安全检查后,可以确保程序集内容在生成后未被更改过!
要注意的是,具有强名称的程序集引用其他程序集,如果这个程序集没有强名称,那么具有强名称的程序集所带来的好处,并依旧会产生DLL冲
突!因此具有强名称的程序集只能引用其他具有强名称的程序集。
18. C#中接口和类有什么区别?
接口是负责功能的定义,项目中通过接口来规范类,操作类以及抽象类的概念!
而类是负责功能的具体实现!
在类中也有抽象类的定义,抽象类与接口的区别在于:
抽象类是一个不完全的类,类里面有抽象的方法,属性,也可以有具体的方法和属性,需要进一步的专业化。
但接口是一个行为的规范,里面的所有东西都是抽象的!
一个类只可以继承一个基类也就是父类,但可以实现多个接口
19.View State 的作用和实现方式?
设置是否要保存控件的状态,其功能的实质是利用隐藏表单域实现
如果设为false且在Page_Load中没有重新绑定数据的话,只要页面一刷新,控件的内容就没了 如果设为true,则页面会保存控件的内容
在一些不需要保存状态的页面中最好把它设为false,为什设为true会增加服务器的负担 隐藏域
20.在ASP.net中可以利用哪些对象存储状态?几种维持状态的对象应用场合以及优缺点?
主要用Application,session,viewstate,cookie,cache。
Application:应用程序级别的共享变量,优点是应用程序一开启该站点都能访问此变量。缺点:所有对此进行写入操作要加锁,由此共享变
量锁带来的内存开销只有此应用程序关闭才能结束。
Session:维护用户个人的状态信息,优点:个人所从事活动,如登录信息,购物车信息等较安全而且又服务器维护较稳定。缺点:维持http
连接的sessionID仍然有缺陷,同时为每个用户维护状态信息,服务器内存开销很大。
Viewsate:如4所说,在一些场合能体现它的特点,但同时带来的缺点:影响整个页面的速度以及隐藏字段未加密。
Cookie:优点是将状态信息维护在客户端的一个文本文件,不需要耗用服务器的内存,是目前各大网站主要采用的方式。 缺点:由于其将状态
信息存贮在客户端,很可能由别人破解此文件而获得此人的个人隐私和机密信息。其受限大小为4K.
Cache:优点是提供的此功能很强大,如文件缓存依赖、API依赖、数据库依赖以用于存贮数据变化而更换缓存状态数据。提供存储周期
从httpcontext到httpruntime。缺点:耗用服务器内存。
Request
21.简单说说 ASP.NET 中基于表单的身份验证方式的用法?
配置文件提供对站点那些目录的保护以及登录页面,当访问该目录的文件时,如果用户未认证通过,将转入登录页面, 用户输入用户名和密码
,将此参数传入认证模块authentication,该模块负责认证,如果通过将isauthentication设置为true,并返回用户的identity对象,此
时页面将转入初始请求页,如果未通过,将不允许访问此目录。
22.是否了解 URL Rewrite?请简要说明其原理和在 ASP.NET 中的实现方式?
一般放在httpmodule中applicatioin_request事情中,当每次http请求,将此URL定位到重写的url函数中并返回重写后的URL地址。主要用
于当我们站点板块移动时由于链接仍然指向旧地址,故可以重定向到新的地址,当然查询参数也可以重写。url-mapping配置
23. 在超过10万条记录的页面显示时,你如何处理分页,有多少种替代方案?
一般根据页面选择的第几页PageIndex,以及服务端配置文件配置的每页行数PageSize,通过传入参数传入存贮过程,由其返回相应行
数pagesize的记录。即每一页数据都由服务端返回。
可以利用缓存Cache,将数据一次加载,在结合asp.net2.0中数据库缓存方式,跟踪数据库表的信息的变化,自动更新缓存信息
对于数据分野页,也可以利用gridview的数据邦定控件的自动分页的方式
24. DataReader和DataSet的异同?
Daatareader和datatset都是通过从数据源取数据。不同点:datareader提供只进行流的方式读取数据。Dataset提供一种容器里面主要由表
以及表关系,由适配器来提供从数据源取得数据填充到此容器的表中。
DataReader和DataSet最大的区别在于,DataReader使用时始终占用SqlConnection,在线操作数据库..任何对SqlConnection的操作都会引
发DataReader的异常..因为DataReader每次只在内存中加载一条数据,所以占用的内存是很小的..因为DataReader的特殊性和高性能.所以DataReader是只进的..你读了第一条后就不能再去读取第一条了..
DataSet则是将数据一次性加载在内存中.抛弃数据库连接..读取完毕即放弃数据库连接..因为DataSet将数据全部加载在内存中.所以比较消
耗内存...但是确比DataReader要灵活..可以动态的添加行,列,数据.对数据库进行回传更新操作
25. 你会利用那些工具进行数据库的性能分析及其优化?说说你觉得优化数据库需要注意的方面。比如:如何设计优化查询为主、插入更新为
主的表。
我主要通过执行计划以及索引优化以及客户统计和服务器跟踪工具来检测从SQL到索引、硬盘IO和时间等信息。 对于查询为主的表,首先对数
据量的大小有一定的估计,当达到一定程度应采用水平分区,有的根据主键有的根据时间段来区分。由于此表往往插入更新不是太快,可对适
当字段采用索引并且填充因子可以尽量大。SQL优化等。 对于插入更新为主的表,我觉得健壮性更重要,只要根据标准外部采用存贮过程就可
以了。
26. 数据库某表主键自增,是很常见的情形。在ASP. Net或C#程序中,要求向该表插入一条记录,并马上从该表查出这条记录。不能使用时间戳,请问你如何实现?
插入一条记录会返回◎◎identity,通过它就是该记录的主键,再select一下就可以了
27.Xhtml的三种DOCTYPE分别有什么含义?请说明。简单说明各个情况下,那些标签可以使用,那些不可以使用?
XHTML 1.0 提供了三种DTD声明可供选择:W3C规范
过渡的(Transitional):要求非常宽松的DTD,它允许你继续使用HTML4.01的标识(但是要符合xhtml的写法)。完整代码如下:<!DOCTYPE
html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
严格的(Strict):要求严格的DTD,你不能使用任何表现层的标识和属性,例如<br>。完整代码如下:<!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
框架的(Frameset):专门针对框架页面设计使用的DTD,如果你的页面中包含有框架,需要采用这种DTD。完整代码如下:<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
28.请举例说明XHtml代码规范,越多越好。
1.所有的标记都必须要有一个相应的结束标记
以前在HTML中,你可以打开许多标签,例如<p>和<li>而不一定写对应的</p>和</li>来关闭它们。但在XHTML中这是不合法的。XHTML要求有
严谨的结构,所有标签必须关闭。如果是单独不成对的标签,在标签最后加一个"/"来关闭它。例如:
<br /><img height="80" alt="网页设计师" src="../images/logo_w3cn_200x80.gif" width="200" />
2.所有标签的元素和属性的名字都必须使用小写
与HTML不一样,XHTML对大小写是敏感的,<title>和<TITLE>是不同的标签。XHTML要求所有的标签和属性的名字都必须使用小写。例
如:<BODY>必须写成<body> 。大小写夹杂也是不被认可的,通常dreamweaver自动生成的属性名字"onMouseOver"也必须修改
成"onmouseover"。
3.所有的XML标记都必须合理嵌套
同样因为XHTML要求有严谨的结构,因此所有的嵌套都必须按顺序,以前我们这样写的代码:
<p><b></p></b>
必须修改为:
<p><b></b></p>
就是说,一层一层的嵌套必须是严格对称。
4.所有的属性必须用引号""括起来
在HTML中,你可以不需要给属性值加引号,但是在XHTML中,它们必须被加引号。例如:
<height=80>
必须修改为:
<height="80">
特殊情况,你需要在属性值里使用双引号,你可以用",单引号可以使用',例如:
<alt="say'hello'">
5.把所有<和&特殊符号用编码表示
任何小于号(<),不是标签的一部分,都必须被编码为& l t ;
任何大于号(>),不是标签的一部分,都必须被编码为& g t ;
任何与号(&),不是实体的一部分的,都必须被编码为& a m p;
注:以上字符之间无空格。
6.给所有属性赋一个值
XHTML规定所有属性都必须有一个值,没有值的就重复本身。例如:
<td nowrap> <input type="checkbox" name="shirt" value="medium" checked>
必须修改为:
<td nowrap="nowrap"> <input type="checkbox" name="shirt" value="medium" checked="checked">
7.不要在注释内容中使“--”
“--”只能发生在XHTML注释的开头和结束,也就是说,在内容中它们不再有效。例如下面的代码是无效的:
<!--这里是注释-----------这里是注释-->
用等号或者空格替换内部的虚线。
<!--这里是注释============这里是注释-->
以上这些规范有的看上去比较奇怪,但这一切都是为了使我们的代码有一个统一、唯一的标准,便于以后的数据再利用。
29. 客户端与浏览器:如果让你做一个TreeView控件,你的思路
我会采用javascript来做,主要采用htc。 数据通过XML.
通过htc操作XML并定义一些方法如:load、addnode、deletenode、updatenode、selectednode等方法一些属性如对图标、节点位置、节
点前复选框等属性,也会提供一些默认事件如修改节点前后刷新等。
30.谈谈论坛聊天室IM和各种网站程序的交互与刷新思路的差异与共同点。
IM交互式信息通信 ajax刷新思路,对于集中刷新方式,应该有部分和全部刷新的区别
这个希望大家上网去找详细的资料
31.谈谈对WSE的认识。
目前Web Service广泛采用Https来保障安全,但是该方法也有很多的缺点,尤其是应用于现在越来越复杂的Web Service安全需求。
1.Https提供的是点对点安全保护,而Web Service的特点就是消息往往就要经过多个中介才能到达最终的服务提供方,每个中介还有可能对消息做出些处理,也就是说它需要的是端到端的保护。这显然是Https所不能提供的。
2.Https是在传输层提供的安全,而不是在消息层面,也就是只有在传输的过程中才有消息才是安全的(加密的),而一旦到达了终点就是明文的了。比如可以从消息队列中将重要的信息窃取出来。
3.在Https的建立完共享密钥后,传递消息的时候并没有使用数字签名技术,所以也就无法得到抗否认性的能力。而这又是在电子商务中不可豁缺的。
4.由于Https提供的是传输层的安全,当然也就不可能达到消息安全所需要的灵活性的要求。比如加密消息中的部分元素;用不同的密钥加密消息的不同部分,从而让不同的消息接受者查看与之对应的信息。
因此,为了适应Web Service对安全的特殊要求,IBM和MS等公司共同制定了WS-Security规范。重新回顾安全问题的三个概念:Confidentiality(机密性), Integrity(完整性), Authentication(身份鉴别),在Web Service使用SOAP(XML 格式)作为消息传输协议的背景下,分别产生了XML Digital Signature,XML Encryption和SAML(XML格式的Security Token), 而WS-Security则是如何将他们组合起来以满足Web Service安全需求的一套规范
Web Services Enhancements 2.0 for Microsoft .NET (WSE)是一个用来建设Web服务的.NET类库,它支持最新的Web服务协议,包
括WS-Security、WS-SecureConversation、WS-Trust、WS-Policy、WS-SecurityPolicy、WS-Addressing和 WS-Attachments。
WSE可使开发人员跨安全平台建设可升级的、安全的Web服务。它支持用传输的方式发送SOAP消息,而不是HTTP。另一个特点是具有建立SOAP路
由器的功能,SOAP消息被发送给SOAP路由器,路由器再将工作交付给托管该服务的Web服务器。
32. 你用过哪些版本控制工具
--------------各位同学兄弟可以根据自己的实际情况,谈论一些自己在使用这些工具时所遇到的问题以及体会
TFS(ASP.Net)、cvs、svn
33. 在开发中你利用那些工具进行单元测试和模块测试
NUNIT和PDM.页面测试 httpunuit
34.如何进行Bug管理
由一个BUG跟踪平台,提供该程序的各个模块的BUG,以及级别,以及解决时间等信息
35. 如何生成和管理开发文档
一般用NDOC来生成文档,大部分文档主要还是Word为主。主要是各个模块以及版本的控制等
36.请用代码简单描述一下Singleton、抽象工厂、策略模式、Composite(任选三个)的设计模式的概念
Singleton 单一模式所有类共享一个实例
下面这种实现方式对多线程来说是安全的,同时线程不是每次都加锁,只有判断对象实例没有被创建时它才加锁,有了我们上面第一部分的里面的分析,我们知道,加锁后还得再进行对象是否已被创建的判断。它解决了线程并发问题,同时避免在每个 Instance 属性方法的调用中都出现独占锁定。它还允许您将实例化延迟到第一次访问对象时发生。实际上,应用程序很少需要这种类型的实现。大多数情况下我们会用静态初始化。这种方式仍然有很多缺点:无法实现延迟初始化。
//author:renfuming
public sealed class Singleton
2{
3 static Singleton instance=null;
4 static readonly object padlock = new object();
6 Singleton(){}
10 public static Singleton Instance{
12 get{
14 if (instance==null){
16 lock (padlock){
18 if (instance==null){
20 instance = new Singleton();
21 }
22 }
23 }
24 return instance;
25 }
26 }
27}
抽象工厂(工厂方法)
using System;
//author:renfuming
namespace TestStrategy
{
public interface IFactory
{
void Method();
}
public class MyProductA:IFactory
{
public MyProductA()
{
Console.WriteLine("已经生产产品A");
}
public void Method()
{
Console.WriteLine("实现产品A的具体功能!");
}
}
public class MyProductB:IFactory
{
public MyProductB()
{
Console.WriteLine("已经生产产品B");
}
public void Method()
{
Console.WriteLine("实现产品B的具体功能!");
}
}
public class CreateProductAFractory
{
public static MyProductA CreateProductA()
{
return new MyProductA();
}
}
public class CreateProductBFractory
{
public static MyProductB CreateProductB()
{
return new MyProductB();
}
}
public class TestFactory
{
public static void Main(string[] args)
{
IFactory ifact=CreateProductAFractory.CreateProductA();
ifact.Method();
Console.WriteLine("--------------------------------------");
ifact=CreateProductBFractory.CreateProductB();
ifact.Method();
}
}
}
策略模式:属于对象行为型模式,主要针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得他们可以相互替换。策略模式适合用于当一个应用程序需要实现一种特定的服务或者功能,而且该程序有多种不同的实现方式可以使用时使用。
策略模式中有三个对象:
1、 环境对象:该类中实现了对抽象策略中定义的接口或者抽象类的引用。
2、 抽象策略对象:他可以又接口或者抽象类进行实现
3、 具体策略对象:他封装了实现对同一动作不同功能的不同算法;
利用策略模式构建的应用程序,可以根据用户配置等内容,选择不同算法来实现应用程序的功能,具体的选择由环境对象来完成。采用这种方式可以避免由于使用条件语句而带来的代码混乱,提高应用程序的灵活性和条理性。
using System;
//author:renfuming
namespace TestStrategy
{
public interface Strategy
{
void PrintCount(string fruitName,int count);
}
public class MyChoilceA:Strategy
{
public void PrintCount(string fruitName,int count)
{
Console.WriteLine("{0}实现5折后的价格是:{1}",fruitName,count*0.5);
}
}
public class MyChoiceB:Strategy
{
public void PrintCount(string fruitName, int count)
{
Console.WriteLine("{0}实现6折后的价格是:{1}",fruitName,count*0.6);
}
}
public class MyChoiceC:Strategy
{
public void PrintCount(string fruitName, int count)
{
Console.WriteLine("{0}实现7折后的价格是:{1}",fruitName,count*0.7);
}
}
public class ChoiceContext
{
Strategy objStrategy;
public ChoiceContext(Strategy obj)
{
this.objStrategy=obj;
}
public void Execute(string name,int count)
{
this.objStrategy.PrintCount(name,count);
}
}
class MyTestClass
{
[STAThread]
static void Main(string[] args)
{
ChoiceContext objA=new ChoiceContext(new MyChoilceA());
objA.Execute("苹果",1000);
ChoiceContext objB=new ChoiceContext(new MyChoiceB());
objB.Execute("香蕉",1000);
ChoiceContext objC=new ChoiceContext(new MyChoiceC());
objC.Execute("橘子",1000);
}
}
}
上面的例子是我自己写的,有不足之处,请自己网上更正!
37.如果你是一位软件架构师,您将如何去搭建一个符合n-tie的架构?并请描述一下您搭建的每一层的作用。(注意:请您考虑项目中
有WebService的情况)
主要根据实际情况来决定搭建的层数以及各层的规格。 一般情况下,可如下搭:
数据层:主要提供数据服务,该层继承实体的接口并定制自己的数据提取和存储。并根据数据库类型如sqlserver、oracle等来建立此层服务。执行逻辑我个人偏好采用存贮过程。
业务层:由于定制的实体的属性和操作实体的方法已由数据层获得和执行,故业务逻辑组件对此实体进行组合以满足上层对业务逻辑组件的调用,webservice也是建在此层,以用于提供数据服务和逻辑执行。
表示层:一般定制不同的容器控件,以用于加载从业务层不同类型的数据便于呈现。当然也要此层的风格以及各种显示设置,webservice显示页面建在层,通过加载对指定目录的webservice提供的方法用于呈现。
38.可否简要的介绍asp.net 2.0 Membership,WebPart和C#的匿名函数和泛型等你认为.net 2.0自己感兴趣的内容,希望可以简要地阐述其中的特点(本题非常的重要)
1 Membership:成员管理主要提供了一套对用户信息、用户角色、用户配置信息的用户系统。通过MembershipConfigHandler加载配置文件
中公有的基础信息,对配置文件中的信息进行了严格的边界检查和类型检查。通过MembershipProvider提供了实现membership的抽象方法以
及配置信息。由SqlMembershipProvider继承MembershipProvider来实现sqlclient的数据提供服务。业务和实现相剥离,以利于扩展。当
然里面有很多特点也有很多细节等。
2 WebPart:主要提供页面布局和自定义以及换皮肤的功能。通过定义主题Theme来决定整体的布局风格,以及版面通过设定不同的区域Zone来
决定版面各块的区域设置。通过不同的skin和css来确定风格。让用户能够保存自己的个人设置以及回复默认设置的功能。
3 匿名函数:使用匿名方法可以减少因实例化委托所需要的开销,1.0中使用委托必须实例化委托并且必须将所调用的类和方法作为参数传入也
即命名方法,当然如果所调用的委托具有多变性应该还采用命名方法。
4 泛型:一般用于集合类。由于以前集合类数据都由framework隐式转化为object类型,这种开销很大。而用泛型,你就可以指定传入对象类
型,而用于生成强类型的数据集,这样各种操作就可以使用指定类型的特性和优势了,自然速度也快了很多。当然接口、方法、类等都同样使用这种方式
5 编译模型除了asp.net1.0支持的批编译,也提供新的编译模式。
6 在httpmodule和httphander的处理速度要比以前1.0要快。
7 在请求响应输出中,将缓冲区由asp.net宿主进程移到本机内存,可以消除资源瓶颈。
8 其缓存模型提供了数据库依赖和缓存后替功能。
9 与IIS6.0集中能提供更好的性能,主要体现在缓存和缓冲操作上。
39.Asp.net中的内建对象
Page对象:Web Form 网页在执行的时候会被编译成Page 对象,Page对象通知来设置与网页有关的属性、方法和事件;
Response对象:用来决定服务器端在什么时候或如何输出数据到客户端;
Request对象:用来捕获由客户端返回服务器的数据;
Server对象:提供服务器端最基本的属性和方法;
Application对象:用来记录不击客户端共享的变量;
Session对象:用来记录各客户端的专用变量;
Cookies对象:为Web应用程序保存访问者相关信息.
40..NET具有跨平台的性质吗?现在是否可以在UNIX平台上广泛的应用?
非常了不起的工具INET,实现.NET跨平台!
执行摘要
微软的.NET是一套连接信息、人、系统、设备的软件技术。此新一代的技术是基于Web服务和小模块创建的应用,可以使任何应用彼此互连并且
能连接到Internet上的其他大型应用。.NET的基础核心是集成开发设备(IDE), Visual Studio.NET和一种新的应用执行环境-Microsoft
.net开发框架。这些系统使开发人员能够像灵活使用 Visual Basic 和C#一样开发强大的应用程序和Web服务。
但是有局限的一点是:用.net开发的应用程序必须运行于.net服务器或者客户端。如果所有的用户都按照.NET运行环境技术标准化这也许可行
,但是实际上当然不是这样。成千上百万台电脑运行的是Linux、Unix, OS X 和其他操作系统,而这种环境不是.NET应用程序的标准化运行
环境。因此软件开发组织需要考虑: 如何有效利用它们的 Microsoft开发人员和Visual Studio.NET的技术特征和优势但是仍然可以访问非
微软服务器, PC机,手提电脑和移动设备?怎样才能使他们用.NET编写的程序运行时不受运行环境的局限?
Stryon公司开发的iNET解决了这一难题。iNET可以使应用程序和Web服务在Visual Basic 和C#下开发,但发布于任何支持Java的运行环境,
网络主机也从IBM网络服务器扩展到Linux和Unix的服务器。有了iNET技术,开发人员既可以利用Visual Studio .net开发环境的优势,但是又不局限于Microsoft的运行环境。
41.写出global.asax文件的主要用途?
作用和asp的global.asa一样,它可以使我们执行asp.net应用程序一层事件的代码,如:application_start等等,使你可以在这些事件中作一些自定义的处理;也可以定义应用程序一层的变量,如:Session等,这在整个asp.net应用程序中起作用。
42.列出web.config的常用的配置段,并对每个配置段进行简要的说明。
Web.config文件是一个XML文本文件,它用来储存 ASP.NET Web 应用程序的配置信息(如最常用的设置ASP.NET Web 应用程序的身份验证方
式),它可以出现在应用程序的每一个目录中。当你通过VB.NET新建一个Web应用程序后,默认情况下会在根目录自动创建一个默认的
Web.config文件,包括默认的配置设置,所有的子目录都继承它的配置设置。如果你想修改子目录的配置设置,你可以在该子目录下新建一个
Web.config文件。它可以提供除从父目录继承的配置信息以外的配置信息,也可以重写或修改父目录中定义的设置。
在运行时对Web.config文件的修改不需要重启服务就可以生效(注:<processModel> 节例外)。当然Web.config文件是可以扩展的。appSettings包含自定义应用程序设置。
system.web 系统配置
compilation动态调试编译设置
customErrors自定义错误信息设置
authentication身份验证,此节设置应用程序的身份验证策略。
authorization授权, 此节设置应用程序的授权策略.
43.ASP.NET中的组件相对于ASP的组件部署方面有什么优点?
asp.net和asp的最大区别在于编程思维的转换,而不仅仅在于功能的增强。asp使用vbs/js这样的脚本语言混合html来编程,而那些脚本语言
属于弱类型、面向结构的编程语言,而非面向对象,这就明显产生以下几个问题:
1、代码逻辑混乱,难于管理:由于asp是脚本语言混合html编程,所以你很难看清代码的逻辑关系,并且随着程序的复杂性增加,使得代
码的管理十分困难,甚至超出一个程序员所能达到的管理能力,从而造成出错或这样那样的问题。
2、代码的可重用性差:由于是面向结构的编程方式,并且混合html,所以可能页面原型修改一点,整个程序都需要修改,更别提代码重
用了。
3、弱类型造成潜在的出错可能:尽管弱数据类型的编程语言使用起来回方便一些,但相对于它所造成的出错几率是远远得不偿失的。
以上是语言本身的弱点,在功能方面asp同样存在问题,第一是功能太弱,一些底层操作只能通过组件来完成,在这点上是远远比不
上php/jsp,其次就是缺乏完善的纠错/调试功能,这点上asp/php/jsp差不多。那么,asp.net有哪些改进呢?
asp.net摆脱了以前asp使用脚本语言来编程的缺点,理论上可以使用任何编程语言包括c++ , vb , js等等,当然,最合适的编程语言还是ms为.net frmaework专门推出的c#(读csharp),它可以看作是vc和java的混合体吧,尽管ms自己讲c#内核中更多的象vc,但
实际上我还是认为它和java更象一些吧。首先它是面向对象的编程语言,而不是一种脚本,所以它具有面向对象编程语言的一切特性,比如封装性、继承性、多态性等等,这就解决了刚才谈到的asp的那些弱点。封装性使得代码逻辑清晰,易于管理,并且应用到asp.net上就可以使业务逻辑和html页面分离,这样无论页面原型如何改变,业务逻辑代码都不必做任何改动;继承性和多态性使得代码的可重用性大大提高,你可以通过继承已有的对象最大限度保护你以前的投资。并且c#和c++、java一样提供了完善的调试/纠错体系
1、 经过解释的语言有两个缺点,一是缺乏强类型,二是缺乏一个编译环境,这将导致性能和伸缩性的问题
2、asp并没有为应用程序提供一个固有的结构,将代码和页面混合在一起使代码变得很复杂,源文件变的很大,结构和代码复用很难,维护也很难。
3、ASP中无论工作多简单都必须在ASP中编写代码完成绝大多数工作,如验证表单字段等,其他还包括告诉缓存页面内容,保持表单状态等,甚至添加新HTML控件也需要写原始HTML。
4、浏览器兼容性。移动设备访问站点,必须编写代码检测这些设备,同时为其提供合适内容。
5、标准兼容性,XHTML被越来越多人接受,XML和XSL/T也得到广泛应用,并且与移动设备进行通信还应该支持WML,这意味着ASP应用不仅
要利用现有标准工作,还要易于升级以支持将来的标准
ASP.NET四个主要目标
使代码更清晰
提高可部署性,可伸缩性,安全性以及可靠性
为不同浏览器和设备提供更好的支持
支持一种全新的web应用程序。
44.简述一下webservice技术,在何种场合下适合使用这项技术?
Web Service 是一种新的web应用程序分支,他们是自包含、自描述、模块化的应用,可以发布、定位、通过web调用。Web Service可以执行从简单的请求到复杂商务处理的任何功能。一旦部署以后,其他Web Service应用程序可以发现并调用它部署的服务。
Web Service是一种应用程序,它可以使用标准的互联网协议,像超文本传输协议(HTTP)和XML,将功能纲领性地体现在互联网和企业内部网上。可将Web服务视作Web上的组件编程。P2P 跨平台技术性应用 Web Services扮演什么角色?
Web services角度所预示的四个趋势:
◆内容更加动态:一个web service必须能合并从多个不同源来的内容,可以包括股票,天气,新闻等,在传统环境中的内容,如存货水平,
购物订单或者目录信息等,都从后端系统而来
◆带宽更加便宜:web services可以分发各种类型的内容(音频,视频流等)
◆存储更便宜: web services必须能聪明地处理大量数据,意味着要使用数据库,LDAP目录,缓冲,和负载平衡软件等技术保持可扩展能力
◆普遍式计算更重要:web services不能要求客户使用某一版本的windows的传统浏览器,必须支持各种设备,平台,浏览器类型,各种内容类型。
两种重要技术
要达到这样的目标,Web services要使用两种技术:
◆XML XML是在web上传送结构化数据的伟大方式,Web services要以一种可靠的自动的方式操作数据,HTML不会满足要求,而XML可以使web services十分方便的处理数据,它的内容与表示的分离十分理想
◆SOAP SOAP使用XML消息调用远程方法,这样web services可以通过HTTP协议的post和get方法与远程机器交互,而且,SOAP更加健壮和灵活易用。
45.C#说明一下虚函数和接口的区别?
虚函数是动态联编的基础,它是引入派生概念之后用来表现基类和派生类成员函数之间的一种关系的。虚函数在基类中定义,它也是一种成员函数,而且是非静态成员函数。
若一个实例方法的声明中含有 virtual 修饰符,则称该方法为虚拟方法;一个虚拟方法的实现可以由派生类取代。取代所继承的虚拟方法的实现的过程称为重写该方法;在一个虚拟方法调用中,该调用所涉及的那个实例的运行时类型确定了要被调用的究竟是该方法的哪一个实现。
虚函数的限制:
1.虚函数仅适用于有继承关系的类对象, 所以只有类的成员函数才能说明为虚函数.
2.静态成员函数不能是虚函数.
3.内联函数不能是虚函数.
4构造函数不能是虚函数.
5.析构函数可以是虚函数.
接口可以有静态成员、嵌套类型、抽象、虚拟成员、属性和事件。实现接口的任何类都必须提供接口中所声明的抽象成员的定义。接口可以要求任何实现类必须实现一个或多个其他接口。
对接口有以下限制:
接口可以用任何可访问性来声明,但接口成员必须全都具有公共可访问性。
不能向成员或接口自身附加安全性权限。
接口可以定义类构造函数,但不能定义实例构造函数。
每种语言都必须为需要成员的接口映射一个实现提供规则,因为不只一个接口可以用相同的签名声明成员,且这些成员可以有单独的实现。
接口可以由类和结构来实现。为了指示类或结构实现了某接口,在该类或结构的基类列表中应该包含该接口的标识符。如果一个类或结构
实现某接口,则它还隐式实现该接口的所有基接口。即使在类或结构的基类列表中没有显式列出所有基接口,也是这样。
46.什么是ASP.net中的用户控件
答:用户控件就是.ascx扩展名的东西喽,可以拖到不同的页面中调用,以节省代码.比如登陆可能在多个页面上有,就可以做成用户控件,但是有
一个问题就是用户控件拖到不同级别的目录下后里面的图片等的相对路径会变得不准确,需要自已写方法调整.
47.什么叫应用程序域?什么是受管制的代码?什么是强类型系统?什么是装箱和拆箱?什么是重载?CTS、CLS和CLR分别作何解释?
答:装箱就是把值类型转成引用类型,从MS IL角度看好像是boxing,没记错的话是把值从堆栈转到堆中.拆箱相反,重载就是指一个方法名同,参数个数不同,返回值可以相同的方法.CLR是通用语言运行时,其它的不清楚.
48.列举一下你所了解的XML技术及其应用
答:XML应用非常广泛,站与站之间的交流,WEB SERVICE都要用它.
如:序列化数据信息等
49.如何理解委托?
答:据说相当于函数指针,定义了委托就可以在不调用原方法名称的情况下调用那个方法.
msdn2005中是这样解释的:
委托具有以下特点:
委托类似于 C++ 函数指针,但它是类型安全的。
委托允许将方法作为参数进行传递。
委托可用于定义回调方法。
委托可以链接在一起;例如,可以对一个事件调用多个方法。
方法不需要与委托签名精确匹配。有关更多信息,请参见协变和逆变。
C# 2.0 版引入了匿名方法的概念,此类方法允许将代码块作为参数传递,以代替单独定义的方法。
50.什么是SOAP,有哪些应用。
答:SOAP(Simple Object Access Protocol )简单对象访问协议是在分散或分布式的环境中交换信息并执行远程过程调用的协议,是一个
基于XML的协议。使用SOAP,不用考虑任何特定的传输协议(最常用的还是HTTP协议),可以允许任何类型的对象或代码,在任何平台上,以任何一直语言相互通信。这种相互通信采用的是XML格式的消息,具体请看:http://playist.blogchina.com/2521621.html、
51.Params是什么含义?
Params是C#中的关键字,采用此关键字可以指定参数数目为可变; 在方法声明中的 params 关键字之后不允许任何其他参数,并且在方
法声明中只允许一个 params 关键字。
如:
public int fConvert(params int[] iParas)
{
}
52. C#中有没有运算符重载?能否使用指针?
有,C#中也有运算符重载,如对运算符“+”进行重载;
C#中也可以使用指针,但要声明为unsafe。
53.Internal修饰符有什么含义?
internal数据访问修饰符,表示对所修饰的成员在当前程序集内可以进行没有任何限制的访问;但在当前程序集外部则不能进行访问,其可访
问性级别低于public ,高于protected。
54. JAVA的代码是半编译半解释的,C#的代码是否也是这样
C#中对于程序代码的处理很类似于Java中的程序代码处理机制;也可以称作半编译半解释,具体为:所有.NET源代码(不管用哪种语言编写)
在进行编译时都被编译成IL。在应用程序运行时被即时(Just-In-Time,JIT)编译器处理成为机器码,被解释及执行。
55. 私有程序集与共享程序集有什么区别?
一个私有程序集通常为单个应用程序所使用,并且存储于这个应用程序所在的目录之中,或此目录下面的一个子目录中。共享程序集通常存储
在全局程序集缓存(Global Assembly Cache)之中,这是一个由.NET运行时所维护的程序集仓库。共享程序集通常是对许多应用程序都有用
的代码库,比如.NET Framework类。
56. 请解释进程与线程的区别?进程与程序的区别?
一般,一个应用程序对应于一个或多个进程,可以把进程看作是该应用程序在操作系统中的标识;而一个进程通常由多个线程组成,而线程是操作系统为该应用程序分配处理时间的最小单元。
57. CLR与IL分别是什么含义?
CLR:公共语言运行时,类似于Java中的JVM,Java虚拟机;在.Net环境下,各种编程语言使用一种共同的基础资源环境,这就是CLR,CLR将直
接与操作系统进行通信,而编程语言如C#.NET将尽量避免直接与操作系统直接通信,加强了程序代码的执行安全性,可以这样看:CLR就是具体的编程语言如:C#.NET与操作系统之间的翻译,同时它为具体的编程语言提供了许多资源:
• 面向对象的编程模型(继承、多态、异常处理和垃圾收集等)
• 安全模型
• 类型系统
• 所有.NET基类
• 许多.NET Framework类
• 开发、调试和评测(profiling)工具
• 执行和代码管理
• IL到本地代码(IL-to-native)转换器和优化器
IL,中间语言,也称MSIL,微软中间语言,或CIL,通用中间语言;所有.NET源代码(不管用哪种语言编写)在进行编译时都被编译成IL。在应用程序运行时被即时(Just-In-Time,JIT)编译器处理成为机器码,被解释及执行。
58 .请解释ASP。NET中以什么方式进行数据验证
Aps.net 中有非空验证,比较验证,取值范围验证,正则表达式验证及客户自定义验证五大控件,另还有一个集中验证信息处理控件
59(1).WEB控件可以激发服务端事件,请谈谈服务端事件是怎么发生并解释其原理?自动传回是什么?为什么要使用自动传回。
在web控件发生事件时,客户端采用提交的形式将数据交回服务端,服务端先调用Page_Load事件,然后根据传回的状态信息自动调用服务端事件
自动传回是当我们在点击客户端控件时,采用提交表单的形式将数据直接传回到
务端
只有通过自动传回才能实现服务端事件的机制,如果没有自动回传机制就只能调用客户端事件,而不能调用服务端事件
59(2).WEB控件及HTML服务端控件能否调用客户端方法?如果能,请解释如何调用?
可以调用
例如:<asp:TextBox id="TextBox1" onclick="clientfunction();" runat="server">
</asp:TextBox>
<INPUT id="Button2" value="Button" name="Button2"
runat="server" onclick="clientfunction();">
59(3).请解释ASP。NET中的web页面与其隐藏类之间的关系?
一个ASP.NET页面一般都对应一个隐藏类,一般都在ASP.NET页面的声明中指定了隐藏类例如一个页面Tst1.aspx的页面声明如下
<%@ Page language="c#" Codebehind="Tst1.aspx.cs" AutoEventWireup="false" Inherits="T1.Tst1" %>
Codebehind="Tst1.aspx.cs" 表明经编译此页面时使用哪一个代码文件
Inherits="T1.Tst1" 表用运行时使用哪一个隐藏类
60.下面的代码中有什么错误吗?_ abstract override 是不可以一起修饰______
using System;
class A
{
public virtual void F(){
Console.WriteLine("A.F");
}
}
abstract class B:A
{
public abstract override void F();
}
61.请问: String类与StringBuilder类有什么区别?为什么在.Net类库中要同时存在这2个类?(简答)
如果要操作一个不断增长的字符串,尽量不用String类,改用StringBuilder类。两个类的工作原理不同:String类是一种传统的修改字符串的方式,它确实可以完成把一个字符串添加到另一个字符串上的工作没错,但是在.NET框架下,这个操作实在是划不来。因为系统先是把两个字符串写入内存,接着删除原来的String对象,然后创建一个String对象,并读取内存中的数据赋给该对象。这一来二去的,耗了不少时间。而使用System.Text命名空间下面的StringBuilder类就不是这样了,它提供的Append方法,能够在已有对象的原地进行字符串的修改,简单而且直接。当然,一般情况下觉察不到这二者效率的差异,但如果你要对某个字符串进行大量的添加操作,那么StringBuilder类所耗费的时间和String类简直不是一个数量级的。
62.class Class1
{
private static int count = 0;
static Class1()
{
count++;
}
public Class1()
{
count++;
}
}
Class1 o1 = new Class1();
Class1 o2 = new Class1();
请问,o1.Count的值是多少?( C )
A.1 B.2 C.3 D.4
63.abstract class BaseClass
{
public virtual void MethodA()
{
}
public virtual void MethodB()
{
}
}
class Class1: BaseClass
{
public void MethodA(string arg)
{
}
public override void MethodB()
{
}
}
class Class2: Class1
{
new public void MethodB()
{
}
}
class MainClass
{
public static void Main(string[] args)
{
Class2 o = new Class2();
Console.WriteLine(o.MethodA());
}
}
请问,o.MethodA调用的是: ( A )
A.BaseClass.MethodAB.Class2.MethodA
C.Class1.MethodAD.都不是
64.请叙述属性与索引器的区别。
属性 索引器
通过名称标识。 通过签名标识。
通过简单名称或成员访问来访问。 通过元素访问来访问。
可以为静态成员或实例成员。 必须为实例成员。
属性的 get 访问器没有参数。 索引器的 get 访问器具有与索引器相同的形参表。
属性的 set 访问器包含隐式 value 参数。 除了 value 参数外,索引器的 set 访问器还具有与索引器相同的形参表
65.请叙述const与readonly的区别。
每一个class至多只可以定义一个static构造函数,并且不允许增加访问级别关键字,参数列必须为空。
为了不违背编码规则,通常把static数据成员声明为private,然后通过statci property提供读写访问。
const 关键字用于修改字段或局部变量的声明。它指定字段或局部变量的值不能被修改。常数声明引入给定类型的一个或多个常数。
const数据成员的声明式必须包含初值,且初值必须是一个常量表达式。因为它是在编译时就需要完全评估。
const成员可以使用另一个const成员来初始化,前提是两者之间没有循环依赖。
readonly在运行期评估赋值,使我们得以在确保“只读访问”的前提下,把object的初始化动作推迟到运行期进行。
readonly 关键字与 const 关键字不同: const 字段只能在该字段的声明中初始化。readonly 字段可以在声明或构造函数中初始化。因此,根据所使用的构造函数,readonly 字段可能具有不同的值。另外,const 字段是编译时常数,而 readonly 字段可用于运行时常数。
readonly 只能在声明时或者构造函数里面初始化,并且不能在 static 修饰的构造函数里面。
66.您需要创建一个ASP.NET应用程序,公司考虑使用Windows身份认证。所有的用户都存在于AllWin这个域中。您想要使用下列认证规则来配置这个应用程序:
a、 匿名用户不允许访问这个应用程序。
b、 所有雇员除了Tess和King都允许访问这个应用程序。
请问您应该使用以下哪一个代码段来配置这个应用程序?( A )
A. <authorization>
<deny users=”allwin\tess, allwin\king”>
<allow users=”*”>
<deny users=”?”>
</authorization〉
67.您要创建一个ASP.NET应用程序在DataGrid控件中显示一个经过排序的列表。产品数据被存放于一个名为PubBase的Microsoft SQL
Server 数据库。每个产品的主键是ProductID,Numeric型并且每个产品有一个字母描述字段,名为ProductName。您使用一个SqlDataAdapter对象和一个SqlCommand对象通过调用一个存储过程从数据库中获取产品数据。您将SqlCommand对象的CommandType属性设
置为CommandType.StoredProcedure,并将它的CommandText属性设置为procProductList。您成功的获取了一个DataTable对象
68. 写出一条Sql语句: 取出表A中第31到第40记录(SQLServer, 以自动增长的ID作为主键, 注意:ID可能不是连续的。)
select top 10 * from A where id not in (select top 30 id from A)
解2: select top 10 * from A where id > (select max(id) from (select top 30 id from A )as A)
69 .列举ASP.NET 页面之间传递值的几种方式。
1. 使用QueryString, 如....?id=1; response. Redirect()....
2.使用Session变量
3.使用Server.Transfer
70。请说明在.net中常用的几种页面间传递参数的方法,并说出他们的优缺点。
session(viewstate) 简单,但易丢失
application 全局
cookie 简单,但可能不支持,可能被伪造
input ttype="hidden" 简单,可能被伪造
url参数简单,显示于地址栏,长度有限
数据库稳定,安全,但性能相对弱
Using 引入一个名子空间,或在使用了一个对像后自动调用其IDespose,New 实例化一个对像,或修饰一个方法,表此方法完全重写此方法
71.请简述一下用Socket进行同步通讯编程的详细步骤
1、在应用程序和远程设备中使用协议和网络地址初始化套接字
2、在应用程序中通过指定端口和地址建立监听
3、远程设备发出连接请求
4、应用程序接受连接产生通信scoket
5、应用程序和远程设备开始通讯(在通讯中应用程序将挂起直到通讯结束)
6、通讯结束,关闭应用程序和远程设备的Socket回收资源
72.什么叫做SQL注入,如何防止?请举例说明。
利用sql关键字对网站进行攻击。过滤关键字'等
所谓SQL注入(SQL Injection),就是利用程序员对用户输入数据的合法性检测不严或不检测的特点,故意从客户端提交特殊的代码,从而收集程序及服务器的信息,从而获取想得到的资料。
http://localhost/lawjia/show.asp?ID=444 and user>0,这时,服务器运行Select * from 表名 where 字段=444 and user>0这样的查询,当然,这个语句是运行不下去的,肯定出错,错误信息如下:
•错误类型:
Microsoft OLE DB Provider for ODBC Drivers (0x80040E07)
[Microsoft][ODBC SQL Server Driver][SQL Server]将 nvarchar 值 'sonybb' 转换为数据类型为 int 的列时发生语法错误。
73、一列数的规则如下: 1、1、2、3、5、8、13、21、34...... 求第30位数是多少, 用递归算法实现。
答:public class MainClass
{
public static void Main()
{
Console.WriteLine(Foo(30));
}
public static int Foo(int i)
{
if (i <= 0)
return 0;
else if(i > 0 && i <= 2)
return 1;
else return Foo(i -1) + Foo(i - 2);
}
}
74.请编程实现一个冒泡排序算法?
答: int [] array = new int [*] ;
int temp = 0 ;
for (int i = 0 ; i < array.Length - 1 ; i++)
{
for (int j = i + 1 ; j < array.Length ; j++)
{
if (array[j] < array[i])
{
temp = array[i] ;
array[i] = array[j] ;
array[j] = temp ;
}
}
}
75.求以下表达式的值,写出您想到的一种或几种实现方法: 1-2+3-4+……+m
答:
int Num = this.TextBox1.Text.ToString() ;
int Sum = 0 ;
for (int i = 0 ; i < Num + 1 ; i++)
{
if((i%2) == 1)
{
Sum += i ;
}
else
{
Sum = Sum - I ;
}
}
System.Console.WriteLine(Sum.ToString());
System.Console.ReadLine() ;
76.在下面的例子里
using System;
class A
{
public A()
{
PrintFields();
}
public virtual void PrintFields(){}
}
class B:A
{
int x=1;
int y;
public B()
{
y=-1;
}
public override void PrintFields()
{
Console.WriteLine("x={0},y={1}",x,y);
}
当使用new B()创建B的实例时,产生什么输出?
答:X=1,Y=0;x= 1 y = -1
78.根据委托(delegate)的知识,请完成以下用户控件中代码片段的填写:
namespace test
{
public delegate void OnDBOperate();
public class UserControlBase : System.Windows.Forms.UserControl
{
public event OnDBOperate OnNew;
privatevoidtoolBar_ButtonClick(objectsender,System.Windows.Forms.ToolBarButtonClickEventArgs e)
{
if(e.Button.Equals(BtnNew))
{
//请在以下补齐代码用来调用OnDBOperate委托签名的OnNew事件。
}
}
}
答:if( OnNew != null )
OnNew( this, e );
79.根据线程安全的相关知识,分析以下代码,当调用test方法时i>10时是否会引起死锁?并简要说明理由。
public void test(int i)
{
lock(this)
{
if (i>10)
{
i--;
test(i);
}
}
}
答:不会发生死锁,(但有一点int是按值传递的,所以每次改变的都只是一个副本,因此不会出现死锁。但如果把int换做一个object,那么死锁会发生)
80.给定以下XML文件,完成算法流程图。
<FileSystem>
< DriverC >
<Dir DirName=”MSDOS622”>
<File FileName =” Command.com” ></File>
</Dir>
<File FileName =”MSDOS.SYS” ></File>
<File FileName =” IO.SYS” ></File>
</DriverC>
</FileSystem>
请画出遍历所有文件名(FileName)的流程图(请使用递归算法)。
答:
void FindFile( Directory d )
{
FileOrFolders = d.GetFileOrFolders();
foreach( FileOrFolder fof in FileOrFolders )
{
if( fof is File )
You Found a file;
else if ( fof is Directory )
FindFile( fof );
}
}
81.abstract class和interface有什么区别?
答:
声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量,其类型是一个抽象类,并让它指向具体子类的一个实例。
不能有抽象构造函数或抽象静态方法。Abstract 类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。接口(interface)是抽象类的变体。在接口中,所有方法都是抽象的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽象的,没有一个有程序体。接口只可以定义static final成员变量。接口的实现与子类相似,除了该实现类不能从接口定义中继承行为。当类实现特殊接口时,它定义(即将程序体给予)所有这种接口的方法。然后,它可以在实现了该接口的类的任何对象上调用接口的方法。由于有抽象类,它允许使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换到接口类型或从接口类型转换,instanceof 运算符可以用来决定某对象的类是否实现了接口。
82.启动一个线程是用run()还是start()?
答:启动一个线程是调用start()方法,使线程所代表的虚拟处理机处于可运行状态,这意味着它可以由JVM调度并执行。这并不意味着线程就
会立即运行。run()方法可以产生必须退出的标志来停止一个线程。
83.构造器Constructor是否可被override?
答:构造器Constructor不能被继承,因此不能重写Overriding,但可以被重载Overloading。
84.是否可以继承String类?
答:String类是final类故不可以继承。
85.try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?
答:会执行,在return前执行。
86.swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上?
答:switch(expr1)中,expr1是一个整数表达式。因此传递给 switch 和 case 语句的参数应该是 int、 short、 char 或者 byte。long,string 都不能作用于swtich。
87.当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?
不能,一个对象的一个synchronized方法只能由一个线程访问。
88.abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized?
答:都不能。
89.List, Set, Map是否继承自Collection接口?
答:List,Set是Map不是
161.Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?
答:Set里的元素是不能重复的,那么用iterator()方法来区分重复与否。equals()是判读两个Set是否相等。
equals()和==方法决定引用值是否指向同一对象equals()在类中被覆盖,为的是当两个分离的对象的内容和类型相配的话,返回真值。
90.数组有没有length()这个方法? String有没有length()这个方法?
答:数组没有length()这个方法,有length的属性。String有有length()这个方法。
91.sleep() 和 wait() 有什么区别?
答:sleep()方法是使线程停止一段时间的方法。在sleep 时间间隔期满后,线程不一定立即恢复执行。这是因为在那个时刻,其它线程可能正在运行而且没有被调度为放弃执行,除非(a)“醒来”的线程具有更高的优先级
(b)正在运行的线程因为其它原因而阻塞。
wait()是线程交互时,如果线程对一个同步对象x 发出一个wait()调用,该线程会暂停执行,被调对象进入等待状态,直到被唤醒或等待时间到。
92.short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?
答:short s1 = 1; s1 = s1 + 1;有错,s1是short型,s1+1是int型,不能显式转化为short型。可修改为s1 =(short)(s1 + 1) 。short s1 = 1; s1 += 1正确。
93.谈谈final, finally, finalize的区别。
答:
final—修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。因此 一个类不能既被声明为 abstract的,又被声明为final的。将变量或方法声明为final,可以保证它们在使用中不被改变。被声明为final的变量必须在
声明时给定初值,而在以后的引用中只能读取,不可修改。被声明为 final的方法也同样只能使用,不能重载finally—再异常处理时提供 finally 块来执行任何清除操作。如果抛出一个异常,那么相匹配的 catch 子句就会 执行,然后控制就会进入 finally 块(如果有的话)。
finalize—方法名。Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理 工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的 ,因此所有的类都继承了它。子类覆盖
finalize() 方法以整理系统资源或者执行其他清理工作。finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的。
93.如何处理几十万条并发数据?
答:用存储过程或事务。取得最大标识的时候同时更新..注意主键不是自增量方式这种方法并发的时候是不会有重复主键的..取得最大标识要有一个存储过程来获取.
94.Session有什么重大BUG,微软提出了什么方法加以解决?
答:是iis中由于有进程回收机制,系统繁忙的话Session会丢失,可以用Sate server或SQL Server数据库的方式存储Session不过这种方式比较慢,而且无法捕获Session的END事件。
95.产生一个int数组,长度为100,并向其中随机插入1-100,并且不能重复。
int[] intArr=new int[100];
ArrayList myList=new ArrayList();
Random rnd=new Random();
while(myList.Count<100)
{
int num=rnd.Next(1,101);
if(!myList.Contains(num))
myList.Add(num);
}
for(int i=0;i<100;i++)
intArr[i]=(int)myList[i];
94,给我一个你最常见到的runtime exception。
ArithmeticException, ArrayStoreException, BufferOverflowException, BufferUnderflowException, CannotRedoException,
CannotUndoException, ClassCastException, CMMException, ConcurrentModificationException, DOMException,
EmptyStackException, IllegalArgumentException, IllegalMonitorStateException, IllegalPathStateException,
IllegalStateException,
ImagingOpException, IndexOutOfBoundsException, MissingResourceException, NegativeArraySizeException,
NoSuchElementException, NullPointerException, ProfileDataException, ProviderException, RasterFORMatException,
SecurityException, SystemException, UndeclaredThrowableException, UnmodifiableSetException,
UnsupportedOperationException
95,error和exception有什么区别?
error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。
exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。
96、另外一道题目的要求是查询表A中存在ID重复三次以上的记录,完整的查询语句如下:
select * from(select count(ID) as count from table group by ID)T where T.count>3
97、比较truncate和delete 命令
解答:两者都可以用来删除表中所有的记录。区别在于:truncate是DDL操作,它移动HWK,不需要 rollback segment .而Delete是DML操作, 需要rollback segment 且花费较长时间.
98、将单引号用两个单引号替换:
SqlConnection coreDB=new SqlConnection();
coreDB.ConnectionString= "workstation id=\"GQA-ERIC-LV\";packet size=4096;integrated security=SSPI;" +
"data source=\"gqa-eric-lv\";persist security info=False;initial catalog=CoreDB";
//单引号用"''"替换,以插入'到SQL Server中;
string Title=TextBox1.Text.Replace("'","''");
string Content=TextBox2.Text.Replace("'","''");
if(Title.Trim()==""||Content.Trim()=="")return;
string insertCMD =@"insert into myBBS (Title,Content) Values('"+ Title + "','" +Content+"')";
SqlCommand myCommand = new SqlCommand(insertCMD,coreDB);
coreDB.Open();
SqlDataReader myReader = myCommand.ExecuteReader();
myReader.Close();
coreDB.Close();
99、使用存储过程来插入
1) 创建存储过程:
Create proc InsertMyBBSProc(@Title char(160), @Author char(20), @Content ntext)
AS
Insert into myBBS(Title,Author,Content) Values(@Title, @Author, @Content)
2) 查询分析器中测试存储过程:
declare @title char(160)
declare @author char(20)
declare @content char(600)
set @title='test title 3'
set @author='david euler 3'
set @content='it is the content 3'
exec InsertMyBBSProc @title, @author, @content
3) C#中通过SqlCommand执行存储过程:
SqlConnection coreDB=new SqlConnection();
coreDB.ConnectionString= "workstation id=\"GQA-ERIC-LV\";packet size=4096;integrated security=SSPI;" +
"data source=\"gqa-eric-lv\";persist security info=False;initial catalog=CoreDB";
string Title=TextBox1.Text;
string Content=TextBox2.Text;
if(Title.Trim()==""||Content.Trim()=="")return;
//InsertMyBBSProc是向MyBBS中插入数据的Procedure:
SqlCommand insertCMD = new SqlCommand("InsertMyBBSProc",coreDB);
insertCMD.CommandType=CommandType.StoredProcedure;//命令类型为存储过程;下面定义参数对象:
SqlParameter prm1=new SqlParameter("@Title", SqlDbType.Char,160);
SqlParameter prm2=new SqlParameter("@Author", SqlDbType.Char,20);
SqlParameter prm3=new SqlParameter("@Content",SqlDbType.NText,1073741823);
prm1.Direction=ParameterDirection.Input;
prm2.Direction=ParameterDirection.Input;
prm3.Direction=ParameterDirection.Input;
//为insertCMD添加SQL参数:
insertCMD.Parameters.Add(prm1);
insertCMD.Parameters.Add(prm2);
insertCMD.Parameters.Add(prm3);
//为SQL参数赋值:
prm1.Value=Title;
prm2.Value="David Euler";
prm3.Value=Content;
coreDB.Open();
int recordsAffected=insertCMD.ExecuteNonQuery();
if(recordsAffected==1)Response.Write("<script>alert('"+ "插入成功" +"');</script>");
coreDB.Close();
100、请简单介绍SOA
什么是服务?如前所述,在一个典型的业务环境里,服务意味着业务函数、业务事务和系统服务。业务函数可能是 getStockQuote、getCustomerAddress 或 checkCreditRating。业务事务可能是 commitInventory、sellCoveredOption 或 scheduleDelivery。系统服务可能是 logMessageIn、getTimeStamp 或 openFile。请注意各种类型服务之间的区别。从应用程序的角度来看,业务函数实际上是原子的非系统函数。业务事务很像是调用应用程序的简单函数,但是它们可能是作为自己的事务的上下文所包含的复合函数来实现的。它们可能包括多个底层函数,这些底层函数对调用者来说是透明的。系统函数是能够从诸如 Windows 或者 Linux 这样的特定平台中抽象出来的广义函数。应用程序框架可能提供像 openFile 这样的广义函数来有效地虚拟化数据源,从而可以在不考虑真实数据源的类型和位置的情况下使用这类函数。
Web 服务的出现产生了根本的改变,因为很多 Web 服务项目的成功显示这种技术事实上确实存在,借此您可以实现真正的面向服务的体系结构。它使您又往回走了一步,不仅分析您的应用程序的体系结构,而且还要分析您正设法解决的基本业务问题。从业务的角度来看,它不再是一个技术问题,而是要开发一种应用程序体系结构和框架,可以在其中定义业务问题,还可以以一致的可重复的方式来实现解决方案。
不过,首先必须理解 Web 服务并不等同于 面向服务的体系结构。Web 服务是包括 XML,SOAP,WSDL 和 UDDI 在内的技术的集合,它使您能够针对特定的消息传递和应用程序集成问题构建编程解决方案。随着时间的推移,您有理由相信这些技术将逐渐成熟并最终为更好、更有效、更健壮的技术所取代,但是,就目前的情况而言,它们可以发挥作用。至少,它们是 SOAs 能够最终实现这种观念的证明。那么,面向服务的体系结构实际上是由什么组成的呢?
SOA 只不过是一种体系结构。它不是任何诸如 Web 服务这样的特定技术的集合;而是超越它们的,在理想的情况下,是完全独立于它们的。在业务环境中,SOA 的纯粹的体系结构定义可能会是这样的“一种应用程序体系结构,在这种体系结构中,所有功能都定义为独立的服务,这些服务带有定义明确的可调用接口,可以以定义好的顺序调用这些服务来形成业务流程”。请注意这里的表述:
1. 所有功能都定义为服务。这仅仅包括业务功能、由底层功能组成的业务事务和系统服务功能。这将会产生粒度问题,后面我们将对此进行讨论。
2. 所有的服务都是独立的。它们就像“黑匣子”一样运行:外部组件既不知道也不关心它们如何执行它们的功能,而仅仅关心它们是否返回期望的结果。
3. 在其最一般的意义上来说,接口是可调用的;也就是说,在体系结构的层面上,它们究竟是本地的(在本系统内)还是远程的(在直接系统外)、是用什么互连 Scheme 或协议来调用或需要什么样的基础架构组件来连接,都是无关紧要的。服务可能是在相同的应用程序中,也可能是在公司内部网内完全不同的系统上的不对称多处理器的不同地址空间中,还有可能是在用于 B2B 配置的合作伙伴的系统上的应用程序中。
在所有这些表述中,接口是最关键的,同时也是调用应用程序关注的焦点。它定义了必需的参数和结果的类型;因而,它定义了服务的类型,而不是实现服务的技术。系统的责任是实现和管理服务的调用,而不是调用应用程序。这使得可以认识到两个关键的特征:其一,服务是真正独立的;其二,它们是可以管理的。管理包括许多功能,其中有:
1. 安全性——请求的授权、加密和解密(在需要时)、确认等等
2. 部署——出于性能、可用性冗余或其他方面的原因,允许服务在网络内重新部署(移动)
3. 日志——用于审核、测量等等
4. 动态重新路由——用于故障排除(fail over)或负载平衡
5. 维护——管理服务的新版本
101、什么是ajax技术,请简单介绍
自从开始 Web 编程以来,在 Web 应用程序和桌面应用程序之间一直存在着许多取舍。例如,人们通常认为 Web 应用程序提供的用户界面类型没有桌面应用程序提供的用户界面类型那样丰富。另一方面,Web 应用程序是独立的平台,其开发机制比较简单。提供响应更及时的应用程序看似是一项简单的任务,但对于 Web 开发人员来说却是一直以来需要攻克的领域。
传统意义上,只能通过向 Web 服务器提交新的请求来检索对用户输入所做的响应。在某些情况下,开发人员可以使用 JavaScript 在客户端上加载所有响应,从而提供更好的用户体验。此技术的常见示例是基于所选国家/地区来动态加载一系列州或省。遗憾的是,在很多情况下,不将所有响应都返回或加载到 JavaScript 要更好。返回操作会使过多的 UI 断开连接,或在客户端上需要过量的数据,这经常导致生成不易读的 JavaScript。AJAX 提供了一种新的中间选择,能够在维持及时响应和灵活性的同时利用基于服务器的应用程序。
AJAX 是 Asynchronous JavaScript And XML(异步 JavaScript 和 XML)的缩写,它不是一项技术,而是很多技术的集合。AJAX 使用通信技术(通常为 SOAP 和 XML)发送和接收对服务器的异步请求/响应,然后利用显示技术(JavaScript、DOM、HTML 和 CSS)处理响应。如今,使用 AJAX 的应用程序是合法的,因为多数浏览器都支持这项必需的技术。有关 AJAX 更详细的定义。
102、请简单介绍微软工作流技术:
一、什么是工作流,工作流做什么用呢?
一个工作流本质是一种方法-用来归档包含在完成一个单元的工作中的活动。典型地,在处理过程中,工作"流"流过一项或更多活动。这些活动可以通过机器或人工来实现,并且有可能象在一个互联网应用程序定义页面顺序一样得简单,也有可能象管理必须为任何数目的人都要看到、更改并同意的文件或产品一样得复杂。
二、WWF是什么呢?它的整体框架?
WWF说到底也是一个程序,只不过它是一个专门控制工作流的程序,它为开发工作流提供了框架、模型、以及工作流的工作引擎(即WorkflowRuntime),让开发人员快速的建立工作流。
1、Activities(活动)
工作流的组成部分,一个工作流由若干个activity组成,每个activity都包含特定的功能,去完成一件工作。
2、Serivices(服务)
当一个工作流实例运行时,可以伴随运行许多个Serivices,这些Services都是采用可插式调用的,即这些Serivices是为了满足不同的工作流的运行实例的需求,伴随实例而运行的。如:在一个工作流的运行实例中,我们可以同时加载与宿主程序通信的Service,监听和跟踪工作流实例运行的Service等等。
3、WWF与宿主程序的通信和关系。
宿主程序能够与工作流通讯交换数据通过通信Service服务,同时,宿主程序也可以与WWF中一些特殊的Activiy活动通过定义一些接口,采用事件传递参数的形式进行通信,交换数据。
4、WWF持久化(“钝化”)
WWF工作流程序可以长时间的运行,而且当WWF运行时所在的计算机重新启动后,这些实例仍然可以正常准确的运行,是由WWF的“钝化”机制来实现的。在WWF内部包含了一个非常有用的Service服务,用来把这些运行的数据保存到SQlServer中。
5、WWF跟踪
WWF中在工作流运行的同时,能够监视工作流的操作,而其这些操作可记录在数据库中或文件里。
6、WWF序列化
WWF的activity活动是可以被序列化的,通过序列化可将自定义的Activity的自定义样式进行保存。
7、WWF动态更新
WWF工作流允许工作流在运行的状态中,动态的更新工作的状态,或动态的控制工作流的流向,更改预期的流程。
通过使用WWF,你可以创建基于处理器流的工作流并且把它们部署在任何类型的.NET应用程序中。此外,本文还讨论了ASP.NET开发者面对的一些特有的问题-这些问题可能通过使用工作流得到解决,如维持状态和页面导航等。
在2005年9月,微软在它的一年两次的专业开发者会议上公开了Windows Workflow Foundation(WWF,Windows工作流基础)。作为WinFX API的支柱之一,WWF提供给开发者一个普通框架-在其上开发过程驱动的和以工作流为中心的应用程序。
当前,有些组织力图把整个商业过程自动化;他们的标准答案就是集合一队开发者来开发相应的代码。尽管这种方式对于这些组织带来良好的作用,然而也有一些固有的问题。为了深入理解这一问题,你需要理解一个工作流的基本特征。
一个工作流本质是一种方法-用来归档包含在完成一个单元的工作中的活动。典型地,在处理过程中,工作"流"流过一项或更多活动。这些活动可以通过机器或人工来实现,并且有可能象在一个互联网应用程序定义页面顺序一样得简单,也有可能象管理必须为任何数目的人都要看到、更改并同意的文件或产品一样得复杂。
因为如此多的工作流必须考虑到人工参预,所以可能需要花费很长工期才能完成,时间可能为几小时到数月或更长。例如,参预在该过程中的人可能无法找到,不在本地或忙于另外的任务;因此,工作流必须在所有非活动期间能够把自身持续性存储。而且,通过编码独立实现的过程可能对非技术人员难于理解而对开发者却难于更改。这一点和其它一些因素正是例如WindowsWF等通用工作流框架的目标-其目的就在于使创建、改变和管理工作流更容易-这是通过向它们提供一个可视化接口或通过定义一组普通API来实现的。
你可以把WWF工作流放置在任何类型的.NET应用程序中-包括Windows表单程序,控制台应用程序,Windows服务和ASP.NET Web应用程序。每种类型都需要专门的考虑。尽管一些现有示例已经足够说明如何把工作流宿主到Windows表单程序和控制台应用程序中,但是本文将集中于讨论ASP.NET开发者的问题-他们希望把工作流集成到自己的应用程序中。
Windows WF和MVC模式
在开发一个ASP.NET应用程序时,你可能使用WWF的一个普通的方法是实现一种模型-视图-控制器(MVC)方法。实质上,MVC的目标是把描述层、应用程序逻辑和应用程序流逻辑分离开来。
搞清楚这个将十分有益于一个ASP.NET应用程序的开发,请考虑一个帮助桌面票工作流的场所。假定有一个商业用户通过填写一个ASP.NET Web表单并点击一个提交按钮来启动该工作流。接下来,服务器就会通知一个使用Windows表单应用程序和帮助桌面的雇员--"有新票可用了"。该帮助桌面雇员然后将在这一问题上工作,并在最后关闭该票。如果使用Windows WF来开发这个工作流情形,那么所有的处理逻辑和流程可以被包含在工作流本身,而该ASP.NET应用程序将完全不需要了解这一逻辑。
这种场所提供了一些稳固的证据-把描述与逻辑相分离是一件好事情。因为这个处理帮助桌面请求的过程是非常普通的,如果使用C#或VB.NET代码在若干不同的.NET应用程序中实现这一逻辑,那么你将会冒着重复编码的危险甚至更坏的情形--用完全不同的代码导致同样的商业处理过程的不同实现。但是如果你使用WWF来实现这一过程,那么需要这一过程的应用程序开发者将仅需在一处修改这些步骤-工作流本身-而不必担心这样会改变应用程序逻辑。代码复制和在哪里实现该过程可以通过Windows WF的使用来加以缓和。
当使用Windows WF在ASP.NET中实现MVC架构时,开发者应该尝试构建独立于应用程序的工作流-而该工作流仍然宿主于该应用程序中。这将有助于保持逻辑独立于描述并且保持在该Web应用程序中的工作步骤顺序和页面流之间的高度独立性。
一个WWF开发新手可能试图用一固定数目的活动以某种顺序去开发一个工作流,然后开发一组ASP.NET Web表单--这些表单以与之相同的顺序从一个表单流向另一个表单。很遗憾,尽管这看上去挺符合逻辑,但是实际上这是非常不具有生产效率的,因为你将会再次实现这个工作流逻辑。Web页面X不需要知道是否它需要转到页面Y或页面Z来正确地实现该工作流步骤。代之的是,该工作流(模型)应该告诉ASP.NET(控制器)下一步该干什么;然后ASP.NET应该决定要显示哪个页面。这样,每个页面几乎不需要了解整个过程;它仅需要知道怎样完成一个不同的活动并且让该工作流来关心页面是如何从一处流向另一处的。这种分离在开发者处理页面流时带来了一种极大的灵活性。例如,如果你决定改变该页面显示顺序,那么你可以从工作流中容易地实现这一点,而不需要改变该ASP.NET应用程序中的一行代码。
103、请简单介绍Asp.net2.0 泛型技术
1、类型安全;2、减少装箱拆箱,运行速度加快;3、增强代码重用用
1、泛型实现
表面上,C# 泛型的语法看起来与 C++ 模板类似,但是编译器实现和支持它们的方式存在重要差异。正如您将在后文中看到的那样,这对于泛
型的使用方式具有重大意义。
注 在本文中,当提到 C++ 时,指的是传统 C++,而不是带有托管扩展的 Microsoft C++。
与 C++ 模板相比,C# 泛型可以提供增强的安全性,但是在功能方面也受到某种程度的限制。
在一些 C++ 编译器中,在您通过特定类型使用模板类之前,编译器甚至不会编译模板代码。当您确实指定了类型时,编译器会以内联方式插入
代码,并且将每个出现一般类型参数的地方替换为指定的类型。此外,每当您使用特定类型时,编译器都会插入特定于该类型的代码,而不管
您是否已经在应用程序中的其他某个位置为模板类指定了该类型。C++ 链接器负责解决该问题,并且并不总是有效。这可能会导致代码膨胀,
从而增加加载时间和内存足迹。
在 .NET 2.0 中,泛型在 IL(中间语言)和 CLR 本身中具有本机支持。在编译一般 C# 服务器端代码时,编译器会将其编译为 IL,就像其
他任何类型一样。但是,IL 只包含实际特定类型的参数或占位符。此外,一般服务器的元数据包含一般信息。
客户端编译器使用该一般元数据来支持类型安全。当客户端提供特定类型而不是一般类型参数时,客户端的编译器将用指定的类型实参来替换
服务器元数据中的一般类型参数。这会向客户端的编译器提供类型特定的服务器定义,就好像从未涉及到泛型一样。这样,客户端编译器就可
以确保方法参数的正确性,实施类型安全检查,甚至执行类型特定的 IntelliSense。
有趣的问题是,.NET 如何将服务器的一般 IL 编译为机器码。原来,所产生的实际机器码取决于指定的类型是值类型还是引用类型。如果客
户端指定值类型,则 JIT 编译器将 IL 中的一般类型参数替换为特定的值类型,并且将其编译为本机代码。但是,JIT 编译器会跟踪它已经
生成的类型特定的服务器代码。如果请求 JIT 编译器用它已经编译为机器码的值类型编译一般服务器,则它只是返回对该服务器代码的引用。
因为 JIT 编译器在以后的所有场合中都将使用相同的值类型特定的服务器代码,所以不存在代码膨胀问题。
如果客户端指定引用类型,则 JIT 编译器将服务器 IL 中的一般参数替换为 Object,并将其编译为本机代码。在以后的任何针对引用类型而
不是一般类型参数的请求中,都将使用该代码。请注意,采用这种方式,JIT 编译器只会重新使用实际代码。实例仍然按照它们离开托管堆的
大小分配空间,并且没有强制类型转换。
泛型的好处
.NET 中的泛型使您可以重用代码以及在实现它时付出的努力。类型和内部数据可以在不导致代码膨胀的情况下更改,而不管您使用的是值类型
还是引用类型。您可以一次性地开发、测试和部署代码,通过任何类型(包括将来的类型)来重用它,并且全部具有编译器支持和类型安全。
因为一般代码不会强行对值类型进行装箱和取消装箱,或者对引用类型进行向下强制类型转换,所以性能得到显著提高。对于值类型,性能通
常会提高 200%;对于引用类型,在访问该类型时,可以预期性能最多提高 100%(当然,整个应用程序的性能可能会提高,也可能不会提高)
。本文随附的源代码包含一个微型基准应用程序,它在紧密循环中执行堆栈。该应用程序使您可以在基于 Object 的堆栈和一般堆栈上试验值
类型和引用类型,以及更改循环迭代的次数以查看泛型对性能产生的影响。
104、详细讲解Webservices技术
Web Service是基于网络的、分布式的模块化组件,它执行特定的任务,遵守具体的技术规范,这些规范使得Web Service能与其他兼容的组件进行互操作[21]。它可以使用标准的互联网协议,像超文本传输协议HTTP和XML,将功能体现在互联网和企业内部网上。Web Service平台
是一套标准,它定义了应用程序如何在Web上实现互操作性。可以使用任何语言,在任何平台上写WebService。
Web Service平台需要一套协议来实现分布式应用程序的创建。任何平台都有它的数据表示方法和类型系统。要实现互操作性,Web Service
平台必须提供一套标准的类型系统,用于沟通不同平台、编程语言和组件模型中的不同类型系统。目前这些协议有:
1.XML和XSD
可扩展的标记语言XML是Web Service平台中表示数据的基本格式。除了易于建立和易于分析外,XML主要的优点在于它既与平台无关,又与
厂商无关。XML是由万维网协会(W3C)创建,W3C制定的XML SchemaXSD定义了一套标准的数据类型,并给出了一种语言来扩展这套数据类型
Web Service平台是用XSD来作为数据类型系统的。当你用某种语言如VB.NET或C#来构造一个Web Service时,为了符合Web Service标准,
所有你使用的数据类型都必须被转换为XSD类型。如想让它使用在不同平台和不同软件的不同组织间传递,还需要用某种东西将它包装起来。这
种东西就是一种协议,如 SOAP。
2.SOAP
SOAP即简单对象访问协议(Simple Object Access Protocol),它是用于交换XML编码信息的轻量级协议。它有三个主要方
面:XML-envelope为描述信息内容和如何处理内容定义了框架,将程序对象编码成为XML对象的规则,执行远程过程调用(RPC)的约定。SOAP
可以运行在任何其他传输协议上。例如,你可以使用 SMTP,即因特网电子邮件协议来传递SOAP消息,这可是很有诱惑力的。在传输层之间的
头是不同的,但XML有效负载保持相同。
Web Service 希望实现不同的系统之间能够用“软件-软件对话”的方式相互调用,打破了软件应用、网站和各种设备之间的格格不入的状态
,实现“基于Web无缝集成”的目标。
3.WSDL
Web Service描述语言WSDL就是用机器能阅读的方式提供的一个正式描述文档而基于XML的语言,用于描述Web Service及其函数、参数和
返回值。因为是基于XML的,所以WSDL既是机器可阅读的,又是人可阅读的。
4.UDDI
UDDI 的目的是为电子商务建立标准;UDDI是一套基于Web的、分布式的、为Web Service提供的、信息注册中心的实现标准规范,同时也包含
一组使企业能将自身提供的Web Service注册,以使别的企业能够发现的访问协议的实现标准。
5.远程过程调用RPC与消息传递
Web Service本身其实是在实现应用程序间的通信。我们现在有两种应用程序通信的方法:RPC远程过程调用和消息传递。使用RPC的时候,
客户端的概念是调用服务器上的远程过程,通常方式为实例化一个远程对象并调用其方法和属性。RPC系统试图达到一种位置上的透明性:服务
器暴露出远程对象的接口,而客户端就好像在本地使用的这些对象的接口一样,这样就隐藏了底层的信息,客户端也就根本不需要知道对象是
在哪台机器上。
微软的.NET技术应该算是时下最好的Web Service 开发技术。.NET平台不仅延续了微软一贯的编程风格,而且还增加了许多支持Web 服务的
关键性技术,使得.NET在操作的简单性和执行的稳定性,高效性上达到了一个非常好的结合。微软的Visual Studio.NET便是一个便于 Web
服务的开发工具。微软的目标是,将其新编程语言——C#作为Web Service的首选语言。
.Net Remoting
.Net Remoting是.Net环境下的另外一种分布式处理方式。从某种意义上来说,Remoting就是DCOM的一种升级,它改善了很多功能,并极好
的融合到.Net平台下。Microsoft® .NET Remoting 提供了一种允许对象通过应用程序域与另一对象进行交互的框架[22]。
在Remoting中是通过通道(channel)来实现两个应用程序域之间对象的通信的。
105、简单介绍消息队列(Message Queue)简介及其使用
利用 MSMQ(Microsoft Message Queue),应用程序开发人员可以通过发送和接收消息方便地与应用程序进行快速可靠的通信。消息处理为您提供了有保障的消息传递和执行许多业务处理的可靠的防故障方法。
MSMQ与XML Web Services和.Net Remoting一样,是一种分布式开发技术。但是在使用XML Web Services或.Net Remoting组件时,Client端需要和Server端实时交换信息,Server需要保持联机。MSMQ则可以在Server离线的情况下工作,将Message临时保存在Client端的消息队列中,以后联机时再发送到Server端处理。
显然,MSMQ不适合于Client需要Server端及时响应的这种情况,MSMQ以异步的方式和Server端交互,不用担心等待Server端的长时间处理过程。
虽然XML Web Services和.Net Remoting都提供了[OneWay]属性来处理异步调用,用来解决Server端长方法调用长时间阻碍Client端。但是不能解决大量Client负载的问题,此时Server接受的请求快于处理请求。
一般情况下,[OneWay]属性不用于专门的消息服务中。
1. 基本术语和概念(Basic terms and concepts)
“消息”是在两台计算机间传送的数据单位。消息可以非常简单,例如只包含文本字符串;也可以更复杂,可能包含嵌入对象。
消息被发送到队列中。“消息队列”是在消息的传输过程中保存消息的容器。消息队列管理器在将消息从它的源中继到它的目标时充当中间人。队列的主要目的是提供路由并保证消息的传递;如果发送消息时接收者不可用,消息队列会保留消息,直到可以成功地传递它。
“消息队列”是 Microsoft 的消息处理技术,它在任何安装了 Microsoft Windows 的计算机组合中,为任何应用程序提供消息处理和消息队列功能,无论这些计算机是否在同一个网络上或者是否同时联机。
“消息队列网络”是能够相互间来回发送消息的任何一组计算机。网络中的不同计算机在确保消息顺利处理的过程中扮演不同的角色。它们中有些提供路由信息以确定如何发送消息,有些保存整个网络的重要信息,而有些只是发送和接收消息。
“消息队列”安装期间,管理员确定哪些服务器可以互相通信,并设置特定服务器的特殊角色。构成此“消息队列”网络的计算机称为“站点”,它们之间通过“站点链接”相互连接。每个站点链接都有一个关联的“开销”,它由管理员确定,指示了经过此站点链接传递消息的频率。
“消息队列”管理员还在网络中设置一台或多台作为“路由服务器”的计算机。路由服务器查看各站点链接的开销,确定经过多个站点传递消息的最快和最有效的方法,以此决定如何传递消息。
2. 队列类型(Queue Type)
有两种主要的队列类型:由您或网络中的其他用户创建的队列和系统队列。
用户创建的队列可能是以下任何一种队列:
“公共队列”在整个“消息队列”网络中复制,并且有可能由网络连接的所有站点访问。
“专用队列”不在整个网络中发布。相反,它们仅在所驻留的本地计算机上可用。专用队列只能由知道队列的完整路径名或标签的应用程序访问。
“管理队列”包含确认在给定“消息队列”网络中发送的消息回执的消息。指定希望 MessageQueue 组件使用的管理队列(如果有的话)。
“响应队列”包含目标应用程序接收到消息时返回给发送应用程序的响应消息。指定希望 MessageQueue 组件使用的响应队列(如果有的话)。
系统生成的队列一般分为以下几类:
“日记队列”可选地存储发送消息的副本和从队列中移除的消息副本。每个“消息队列”客户端上的单个日记队列存储从该计算机发送的消息副本。在服务器上为每个队列创建了一个单独的日记队列。此日记跟踪从该队列中移除的消息。
“死信队列”存储无法传递或已过期的消息的副本。如果过期或无法传递的消息是事务性消息,则被存储在一种特殊的死信队列中,称为“事务性死信队列”。死信存储在过期消息所在的计算机上。有关超时期限和过期消息的更多信息,请参见默认消息属性。
“报告队列”包含指示消息到达目标所经过的路由的消息,还可以包含测试消息。每台计算机上只能有一个报告队列。
“专用系统队列”是一系列存储系统执行消息处理操作所需的管理和通知消息的专用队列。
在应用程序中进行的大多数工作都涉及访问公共队列及其消息。但是,根据应用程序的日记记录、确认和其他特殊处理需要,在日常操作中很可能要使用几种不同的系统队列。
3. 同步和异步通信(Synchronous VS. Asynchronous Communication)
队列通信天生就是异步的,因为将消息发送到队列和从队列中接收消息是在不同的进程中完成的。另外,可以异步执行接收操作,因为要接收消息的人可以对任何给定的队列调用 BeginReceive 方法,然后立即继续其他任务而不用等待答复。这与人们所了解的“同步通信”截然不同。
在同步通信中,请求的发送方在执行其他任务前,必须等待来自预定接收方的响应。发送方等待的时间完全取决于接收方处理请求和发送响应所用的时间。
4. 同消息队列交互(Interacting with Message Queues)
消息处理和消息为基于服务器的应用程序组件之间的进程间通信提供了强大灵活的机制。同组件间的直接调用相比,它们具有若干优点,其中包括:
稳定性 — 组件失败对消息的影响程度远远小于组件间的直接调用,因为消息存储在队列中并一直留在那里,直到被适当地处理。消息处理同事务处理相似,因为消息处理是有保证的。
消息优先级 — 更紧急或更重要的消息可在相对不重要的消息之前接收,因此可以为关键的应用程序保证足够的响应时间。
脱机能力 — 发送消息时,它们可被发送到临时队列中并一直留在那里,直到被成功地传递。当因任何原因对所需队列的访问不可用时,用户可以继续执行操作。同时,其他操作可以继续进行,如同消息已经得到了处理一样,这是因为网络连接恢复时消息传递是有保证的。
事务性消息处理 — 将多个相关消息耦合为单个事务,确保消息按顺序传递、只传递一次并且可以从它们的目标队列中被成功地检索。如果出现任何错误,将取消整个事务。
安全性 — MessageQueue 组件基于的消息队列技术使用 Windows 安全来保护访问控制,提供审核,并对组件发送和接收的消息进行加密和验证。
5. 在.Net环境下编写简单的Message Queue程序
(1)先安装Message Queuing Services
通过Control Panel,“Add/Remove Programs” – “Add/Remove Windows Components”步骤安装MSMQ。
MSMQ可以安装为工作组模式或域模式。如果安装程序没有找到一台运行提供目录服务的消息队列的服务器,则只可以安装为工作组模式,此计算机上的“消息队列”只支持创建专用队列和创建与其他运行“消息队列”的计算机的直接连接。
(2)配置MSMQ
打开Computer Management – Message Queuing,在Private Queues下创建MSMQDemo队列
(3)编写代码-简单演示MSMQ对象
MessageQueue 类是“消息队列”周围的包装。MessageQueue 类提供对“消息队列”队列的引用。可以在 MessageQueue 构造函数中指定一个连接到现有资源的路径,或者可在服务器上创建新队列。在调用 Send、Peek 或 Receive 之前,必须将 MessageQueue 类的新实例与某个现有队列关联。
MessageQueue 支持两种类型的消息检索:同步和异步。同步的 Peek 和 Receive 方法使进程线程用指定的间隔时间等待新消息到达队列。异步的 BeginPeek 和 BeginReceive 方法允许主应用程序任务在消息到达队列之前,在单独的线程中继续执行。这些方法通过使用回调对象和状态对象进行工作,以便在线程之间进行信息通讯。
106、面向对象软件设计的“开-----闭”原则
1.什么是开闭原则
“开—闭”原则是指软件实体应当对扩展性开放,对修改关闭。即软件实体应该在不修改的前提下扩展,这个原则实际上为软件设计指明了目标。我们知道软件设计应当充分考虑软件的可维护性,即需求发生变化的时候软件结构能够灵活地适应这种变化。就评价软件的可维护性而言,“开—闭”原则提供了一个依据。实际上,设计模式的应用就是使软件的结构在某种程度上满足“开—闭”原则。
2.“开—闭”原则的实现
“开—闭”原则为设计提供了目标,但却没有明确给出实现的手段,下面说明在面向对象的设计中实现“开—闭”原则的方法。
(1)面向接口的编程
面向接口的编程的优势如下:
a.降低程序各部分之间的耦合性,使程序模块互换成为可能。这样客户无需知道自己使用的对象的类型,只要对象有客户所期望的接口即可。并且客户也不需要知道对象是如何实现的,只要知道定义接口的抽象类。
b.使软件各部分便于单元测试,通过编制与接口一致的模拟类(Mock),可以很容易地实现软件各部分的单元测试。从而提高软件的可靠性,降低错误率。
c.已于实现软件的模块的呼唤,软件升级时可以只部署发生变化的部分,而不会影响其它部分。
对于设计模式来说,创建型模式的产生是面向接口编程的必然结果,面向接口编程要求使用对象的客户不了解对象的具体类型,客户只能通过一个负责实例化对象的对象——我们称之为“工厂”——来实例化对象,而工厂对象在应用初始化时集中进行实例化或者在集中的模块中进行。
3.封装变化
程序中任何可能发生变化的部分都可以封装为对象,包括命令、事件、属性、算法和状态等。封装变化是实现“开—闭”原则的重要手段,也是在设计中发现对象的重要途径。因此在分析需求时,一定要注意什么是不变的,什么是可能发生变化的,以及这些可能的变化会对封装带来的影响。
例如,如果对象的行为基本不变,那么这些行为可以作为对象的方法;否则就要考虑是否抽象和封装这些行为。再如,状态可以用状态参数来表示,例如温度和压力等。可以将状态参数作为独立的属性,但如果状态参数之间相互关联,则有必要进行抽象。
总之,封装可能发生变化的部分,将可能的变化作为对象。在面向对象设计中,对象不仅是指现实中存在的事物或者可视的事物,任何可能变化的部分都是侯选对象。
4.采用组合替代继承
继承是面向对象系统的特点之一,没有继承,很多面向对象的设计就无从谈起。在设计模式中,没有哪个模式不涉及到继承。采用组合替代继承并不适合任何情况,实际上,如果没有继承,很多组合根本无法实现,涉及到基础结构的继承无法替换。
组合和继承针对模块中的复用而言,当功能需要扩展时,采用继承实现复用比较简单直观。只要派生一个类,在这个类中增加新的特性,即可实现对现有类复用。然而类继承在编译时定义,无法在运行时改变 。并且继承对子类暴露了父类的实现细节,从而破坏了封装性,使子类与父类耦合性非常强。一旦父类发生变化,必然导致子类也发生变化。如果继承下来的实现不能解决新问题,则需要修改父类,这种依赖性限制了灵活性。
通过与行为对象的组合,可以扩展“人”的行为。通过增加新的行为类来实现扩展,类层次并没有增加。
对象组合在运行时通过获得对其他对象的引用来实现,组合要求对象遵守彼此的接口约定。只要符合这个约定,一个对象可以在运行时动态地玮不同的对象组合,从而实现复用。在设计时,每一部分只要关注接口约定即可,不必考虑具体的实现。因此对象组合有最小的耦合性并且更灵活,在设计模式中大量地采用了对象组合。
再次强调,继承是面向对象的基石之一。采用组合代替继承者是在需要复用的前提下,并不是所有的继承都可以用组合替代。不仅如此,没有继承,组合也无从谈起。在上面的例子中,行为的扩展仍然需要增加行为子类。
107、请详细介绍你所了解的AOP技术:
什么是AOP?
最初听到AOP这个名词,我总是错觉其与OOP是否具有孪生性?那么,所谓AOP,即面向方面编程(Aspect Oriented Programming),是否是面向对象编程的一种进化呢?关键就在于我们对“方面(Aspect)”的理解。确实,“方面”这个词语是够抽象的,简单地说,它就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任,例如事务处理、日志管理、权限控制等,封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。
对于OOP,Bruce Eckel有一句名言,“Everything is Object.”确实,在程序的世界里,我们可以将万事万物定义为一种对象,并将这些对象的行为和属性封装起来,同时定义好对象与对象之间的关系。很显然,对于AOP而言,我们无法套用这句名言,妄言“Everything is Aspect.”实质上,AOP只是OOP的一种补充或某种改进,它转换了编程的范式和视角,关注了一直以来被OOP忽略或者说未能解决好的角落,使开发人员可以更好地将本不该彼此纠缠在一起的责任(如银行业务和事务处理)分离开来。通过面向方面的编程,可以将程序的责任分开,对象与方面互不干扰。面向方面的模块并非显式地为对象所调用,而是通过或注入或截取的方式,去获得被封装的对象内部方法间的消息,然后做出相应地处理。也许面向方面的模式破坏了对象的封装,却正其如此,方才能降低模块与模块之间的耦合度。同样地,通过对“方面”的封装,将这些通用的功能从不同的类中分离出来,使不同的模块都能共享同样的“方面”,这也极大地减少了重复代码。
如果说“对象”是一个空心的圆柱体,其中封装的是对象的属性和行为;那么面向方面编程的方法,就仿佛一把利刃,将这些空心圆柱体剖开,以获得其内部的消息。而剖开的切面,也就是所谓的“方面”了。然后它又以巧夺天功的妙手将这些剖开的切面复原,不留痕迹。
AOP,并不具有革命的驱动力
个人认为,AOP还谈不上是一种编程的思想,只能说是一种方法而已。溯其根源,一般认为,面向方面编程(AOP)是施乐公司帕洛阿尔托研究中心(Xerox PARC)在上世纪90年代发明的一种编程范式。它在OOP的缝隙之中,抽象出“方面”的概念,目的就是为了打破对象的封装性,以“方面”的方式对原有的模块进行重组,抽取那些与业务无关却为整个系统所通用的功能,最终封装在一起。
那么,最终封装好的这些所谓“方面”,如何被业务对象所调用呢?这就需要“方面”拥有截取封装对象消息的能力。在JAVA世界里,AOP的应用已经走向比较成熟的应用。AspectJ、Spring,在体现AOP能力上来说,已经渐趋成熟。甚至在JBOSS4.0中,已经引入了AOP框架进行开发,并在权限管理(Authentication)、错误处理(Error Handling)、事务处理(Transactions)、持久化(Persistence)等方面取得了很好的应用。在.Net平台下,对于AOP的应用似乎却走到了后面。在Microsoft 推出的.Net Framework 1.1中,并没有应用AOP,也未曾提供AOP的框架。不过.Net Framework仍然提供了实现AOP的技术可能,即通过.Net Framework的反射机制或.Net Remoting的代理机制获取元数据信息或对象内部间传递的消息。同时,我也看到开源社区中的AOP.Net项目,采用了非托管的.Net Profilling API,它采用了非托管的C++ COM组件,可以在相关事件发生时,通过.Net系统捕获其消息并发送通知。
AOP在企业应用中正逐渐体现其自身的价值。但正如其名,它的作用更多地是关注于系统的某一方面。AOP还缺乏革命的驱动力,并不足以颠覆OOP世界。我们不可能预见AOP之于OOP,象当初面向对象编程取代面向过程编程那样,具有强大至可以颠覆程序员思想的力量。而事实上,AOP从一诞生以来,就从未贴上“革命”的标签。相反,它更多地起到了推波助澜的作用,弥补着OOP的缺失,进而在OO程序设计中,扩展了一种更宽广的模式。
AOP,“设计模式”的延续
不错,AOP的目的,恰恰就是做了“设计模式”想做却一直未曾做到的功能。GOF的“设计模式”给了我们设计的典范与准则,通过最大程度的利用面向对象的特性,诸如利用继承、多态,对责任进行分离、对依赖进行倒置,面向抽象,面向接口,最终设计出灵活、可扩展、可重用的类库、组件,乃至于整个系统的架构。在设计的过程中,通过各种模式体现了对象的行为,暴露的接口,对象间关系,以及对象分别在不同层次中表现出来的形态。然而鉴于对象封装的特殊性,“设计模式”的触角始终在接口与抽象中大做文章,而对于对象内部则无能为力。
举例来说,我们需要为系统提供日志的能力。虽然我们可以通过装饰模式(Decorate Pattern),提供各种日志的组合,但不可避免的是,大量的日志对象实例代码的存在,导致了重复代码的坏味道,同时也导致了强依赖性,这并不利于模块间的解耦。如果我们通过AOP,将这些日志的功能看作是一个“方面”,然后将系统中需要日志能力的模块置于该“方面”的侦听之中,抽象出来的“方面”好像是一个容器,在其内部的世界里,不分贫富贵贱。只要执行了某种业务,这个容器就会忠实地记录这些模块间传递的消息。至于这些模块到底实现了何种业务,却并非“方面”所关注的。
前面已经叙述到,面向方面编程的价值主要体现在事务处理、日志管理、权限控制等与业务无关,却为业务模块所共同调用的逻辑或责任上,而这些所谓的“方面”,恰恰是企业应用时非常必须的。因此,与其说AOP是一种编程的技术,毋宁说AOP是一种企业的“设计模式”。它弥补了OOP之拙,却未曾也不可能超越OOP而单独存在。
Aspect-Oriented Programming(面向方面编程,AOP)正好可以解决这一问题。它允许开发者动态地修改静态的OO模型,构造出一个能够不断增长以满足新增需求的系统,就象现实世界中的对象会在其生命周期中不断改变自身,应用程序也可以在发展中拥有新的功能。AOP利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的行为封装到一个可重用模块,并将其名为“Aspect”,即方面。所谓“方面”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任,例如事务处理、日志管理、权限控制等,封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。
面向方面编程(AOP)是施乐公司帕洛阿尔托研究中心(Xerox PARC)在上世纪90年代发明的一种编程范式。但真正的发展却兴起于近几年对软件设计方兴未艾的研究。由于软件系统越来越复杂,大型的企业级应用越来越需要人们将核心业务与公共业务分离。AOP技术正是通过编写横切关注点的代码,即“方面”,分离出通用的服务以形成统一的功能架构。它能够将应用程序中的商业逻辑同对其提供支持的通用服务进行分离,使得开发人员从重复解决通用服务的劳动中解脱出来,而仅专注于企业的核心商业逻辑。因此,AOP技术也就受到越来越多的关注,而应用于各种平台下的AOP技术也应运而生。但由于AOP技术相对于成熟的OOP技术而言,在性能、稳定性、适用性等方面还有待完善,同时AOP技术也没有形成一个统一的标准,这使得AOP技术的研究更具有前沿性的探索价值。
108、请问你在项目中是否用到存储过程,并请你谈谈存储过程以及它的特点
存储过程(stored procedure)是一组为了完成特定功能的sql 语句集,经编译后存储在数据库。中用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。 在sql server 的系列版本中存储过程分为两类:系统提供的存储过程和用户自定义存储过程。系统过程主要存储在master 数据库中并以sp_为前缀,并且系统存储过程主要是从系统表中获取信息,从而为系统管理员管理sql server 提供支持。通过系统存储过程,ms sql server 中的许多管理性或信息性的活动(如了解数据库对象、数据库信息)都可以被顺利有效地完成。尽管这些系统存储过程被放在master 数据库中,但是仍可以在其它数据库中对其进行调用,在调用时不必在存储过程名前加上数据库名。而且当创建一个新数据库时,一些系统存储过程会在新数据库中被自动创建。用户自定义存储过程是由用户创建并能完成某一特定功能(如查询用户所需数据信息)的存储过程。在本章中所涉及到的存储过程主要是指用户自定义存储过程。
存储过程的优点
当利用ms sql server 创建一个应用程序时,transaction-sql 是一种主要的编程语言。若运用transaction-sql 来进行编程,有两种方法。其一是,在本地存储transaction- sql 程序,并创建应用程序向sql server 发送命令来对结果进行处理。其二是,可以把部分用transaction-sql 编写的程序作为存储过程存储在sql server 中,并创建应用程序来调用存储过程,对数据结果进行处理存储过程能够通过接收参数向调用者返回结果集,结果集的格式由调用者确定;返回状态值给调用者,指明调用是成功或是失败;包括针对数据库的操作语句,并且可以在一个存储过程中调用另一存储过程。
存储过程具有以下优点:
(1) 存储过程允许标准组件式编程
存储过程在被创建以后可以在程序中被多次调用,而不必重新编写该存储过程的sql 语句。而且数据库专业人员可随时对存储过程进行修改,但对应用程序源代码毫无影响(因为应用程序源代码只包含存储过程的调用语句),从而极大地提高了程序的可移植性。
(2) 存储过程能够实现较快的执行速度
如果某一操作包含大量的transaction-sql 代码或分别被多次执行,那么存储过程要比批处理的执行速度快很多。因为存储过程是预编译的,在首次运行一个存储过程时,查询优化器对其进行分析、优化,并给出最终被存在系统表中的执行计划。而批处理的transaction- sql 语句在每次运行时都要进行编译和优化,因此速度相对要慢一些。
(3) 存储过程能够减少网络流量
对于同一个针对数据数据库对象的操作(如查询、修改),如果这一操作所涉及到的 transaction-sql 语句被组织成一存储过程,那么当在客户计算机上调用该存储过程时,网络中传送的只是该调用语句,否则将是多条sql 语句,从而大大增加了网络流量,降低网络负载。
(4) 存储过程可被作为一种安全机制来充分利用
系统管理员通过对执行某一存储过程的权限进行限制,从而能够实现对相应的数据访问权限的限制,避免非授权用户对数据的访问,保证数据的安全。(我们将在14 章“sqlserver 的用户和安全性管理”中对存储过程的这一应用作更为清晰的介绍)
109、请简单介绍一下使用js脚本的好处以及其本身的特点
JavaScript是一种基于对象(Object)和事件驱动(Event Driven)并具有安全性能的脚本语言。使用它的目的是与HTML超文本标记语言、Java 脚本语言(Java小程序)一起实现在一个Web页面中链接多个对象,与Web客户交互作用。从而可以开发客户端的应用程序等。它是通过嵌入或调入在标准的HTML语言中实现的。它的出现弥补了HTML语言的缺陷,它是Java与HTML折衷的选择,具有以下几个基本特点:
是一种脚本编写语言
JavaScript是一种脚本语言,它采用小程序段的方式实现编程。像其它脚本语言一样,JavaScript同样已是一种解释性语言,它提供了一个易的开发过程。
它的基本结构形式与C、C++、VB、Delphi十分类似。但它不像这些语言一样,需要先编译,而是在程序运行过程中被逐行地解释。它与HTML标识结合在一起,从而方便用户的使用操作。 基于对象的语言。
JavaScript是一种基于对象的语言,同时以可以看作一种面向对象的。这意味着它能运用自己已经创建的对象。因此,许多功能可以来自于脚本环境中对象的方法与脚本的相互作用。
简单性
JavaScript的简单性主要体现在:首先它是一种基于Java基本语句和控制流之上的简单而紧凑的设计, 从而对于学习Java是一种非常好的过渡。其次它的变量类型是采用弱类型,并未使用严格的数据类型。
安全性
JavaScript是一种安全性语言,它不允许访问本地的硬盘,并不能将数据存入到服务器上,不允许对网络文档进行修改和删除,只能通过浏览器实现信息浏览或动态交互。从而有效地防止数据的丢失。
动态性的
JavaScript是动态的,它可以直接对用户或客户输入做出响应,无须经过Web服务程序。它对用户的反映响应,是采用以事件驱动的方式进行的。所谓事件驱动,就是指在主页(Home Page)中执行了某种操作所产生的动作,就称为“事件”(Event)。比如按下鼠标、移动窗口、选择菜单等都可以视为事件。当事件发生后,可能会引起相应的事件响应。
跨平台性
JavaScript是依赖于浏览器本身,与操作环境无关,只要能运行浏览器的计算机,并支持JavaScript的浏览器就可正确执行。从而实现了“编写一次,走遍天下”的梦想。
实际上JavaScript最杰出之处在于可以用很小的程序做大量的事。无须有高性能的电脑,软件仅需一个字处理软件及一浏览器,无须WEB服务器通道,通过自己的电脑即可完成所有的事情。
综合所述JavaScript 是一种新的描述语言,它可以被箝入到 HTML 的文件之中。 JavaScript语言可以做到回应使用者的需求事件 (如: form 的输入) ,而不用任何的网路来回传输资料,所以当一位使用者输入一项资料时,它不用经过传给伺服端 (server)处理,再传回来的过程,而直接可以被客户端 (client) 的应用程式所处理。
JavaScript 和 Java 很类似,但到底并不一样! Java 是一种比 JavaScript 更复杂许多的程式语言,而 JavaScript 则是相当容易了解的语言。JavaScript 创作者可以不那麽注重程式技巧,所以许多 Java 的特性在 Java Script 中并不支援。
110、gridview控件基本总结(一招在手,走遍天下renfuming-to-all schoolmates)
/*author:renfuming
date:2007/5/12
send to:yyaccp's schoolmates who are studying asp.net
*/
public partial class _Default : System.Web.UI.Page
{
private SqlConnection conn;
private SqlCommand comm;
private string connstring = ConfigurationManager.ConnectionStrings[1].ConnectionString;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
bind();
}
}
//数据邦定
private void bind()
{
string sqlstr = "select * from teacher";
this.conn = new SqlConnection(connstring);
SqlDataAdapter adapter = new SqlDataAdapter(sqlstr, conn);
DataSet ds = new DataSet();
adapter.Fill(ds,"teacher");
this.GridView1.DataSource = ds;
GridView1.DataKeyNames = new string[] { "teaid" };//主建
this.GridView1.DataBind();
conn.Close();
}
//编辑数据信息
protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
this.GridView1.EditIndex = e.NewEditIndex;
bind();
}
//更新数据信息
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
try
{
this.conn = new SqlConnection(connstring);
string col1 = ((TextBox)(GridView1.Rows[e.RowIndex].Cells[2].Controls[0])).Text.ToString().Trim();//cell索引从1开始,这是从第二列开
始修改数据信息,主建不能修改
int col2 = int.Parse(((TextBox)(GridView1.Rows[e.RowIndex].Cells[3].Controls[0])).Text.ToString().Trim());
int id = int.Parse(this.GridView1.DataKeys[e.RowIndex].Value.ToString());
string sqlstr = "update teacher set teaname='" + col1 + "',teaage=" + col2 + " where teaid=" + id + "";
this.comm = new SqlCommand(sqlstr, conn);
conn.Open();
comm.ExecuteNonQuery();
conn.Close();
this.GridView1.EditIndex = -1;
bind();
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
}
//删除信息
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
string sql = "delete from teacher where teaid='"+this.GridView1.DataKeys[e.RowIndex].Value.ToString()+"'";
this.conn = new SqlConnection(connstring);
this.comm = new SqlCommand(sql,conn);
this.conn.Open();
response.write("<script language='javascript'>return confirm('您真的要删除此纪录吗?');</script>");
this.comm.ExecuteNonQuery();
this.conn.Close();
bind();s
}
protected void GridView1_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
this.GridView1.EditIndex = -1;
bind();
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
//如果是绑定数据行
if (e.Row.RowType == DataControlRowType.DataRow)
{
//鼠标经过时,行背景色变
e.Row.Attributes.Add("onmouseover", "this.style.backgroundColor='#E6F5FA'");
//鼠标移出时,行背景色变
e.Row.Attributes.Add("onmouseout", "this.style.backgroundColor='#FFFFFF'");
}
}
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
this.GridView1.PageIndex = e.NewPageIndex;
}
protected void GridView1_PageIndexChanged(object sender, EventArgs e)
{
bind();
}
//通过存储过程插入数据信息
protected void btnInsert_Click(object sender, EventArgs e)
{
SqlParameter[] para = new SqlParameter[] {
new SqlParameter("@name",TypeCode.String),new SqlParameter("@age",TypeCode.Int32)};
this.conn = new SqlConnection(connstring);
conn.Open();
this.comm = new SqlCommand("Myproc",conn);
this.comm.CommandType = CommandType.StoredProcedure;
para[0].Value = this.txtname.Text;
para[1].Value = int.Parse(this.txtage.Text.Trim());
this.comm.Parameters.AddRange(para);
this.comm.ExecuteNonQuery();
this.conn.Close();
bind();
}
}
111、请举例说明ref的基本用法
//Author:renfuming
//相当于传引用
public static void Userref(ref int i)
{
i += 100;
Console.WriteLine("使用ref后的结果是:"+i);
}
static void Main()
{
int i = 10;
Console.WriteLine("先前的值是:"+i);
Userref(ref i);
Console.WriteLine("使用函数后的值是:"+i);//如果不是用的ref,则此处的打印结果是10
}
112、请问在Asp.net中xml文件与xsl文件如何进行整合
//Author:renfuming
System.Xml.XmlDocument xmldoc = new System.Xml.XmlDocument();
xmldoc.Load(Server.MapPath("user.xml"));
System.Xml.Xsl.XslTransform xmltrans = new System.Xml.Xsl.XslTransform();
xmltrans.Load(Server.MapPath("user.xsl"));
Xml1.Document = xmldoc;
Xml1.Transform = xmltrans;
113、请用C#语言调用Oracle的存储过程
//Author:renfuming
Function GetList(keywords In varchar2
,p_info_list_Cursor out get_data_cur_type)
Return Number
As
Begin
open p_info_list_Cursor For
Select * from Test where Key=keywords;
Return 0;
End;
----------------
OracleConnection OracleConn = new OracleConnection(连接字符串);
OracleCommand cmd = new OracleCommand("GetList", OracleConn);
cmd.Parameters.AddRange(new OracleParameter[]
{
new OracleParameter("keyWords", OracleType.VarChar),
new OracleParameter("ReturnValue", OracleType.Number, 0, ParameterDirection.ReturnValue, true, 0, 0, "",DataRowVersion.Default, Convert.DBNull),
new OracleParameter("p_info_list_Cursor", OracleType.Cursor, 2000, ParameterDirection.Output, true, 0, 0, "",DataRowVersion.Default, Convert.DBNull)
});
cmd.Parameters[0].Value = 't07美女';
cmd.Parameters[0].Direction = ParameterDirection.Input;
cmd.CommandType = CommandType.StoredProcedure;
OracleConn.Open()
OracleDataReader rdr=cmd.ExecuteReader();
//其他代码
OracleConn.Close();
C#执行Oracle的参数过程,Sql 语句中使用":" 表示参数。
在Sql Server 中我们可以按以下方式使用SQL 语句: "Insert into Table (Field1,field2) values(@Value1,@Value2) ", 然后我们再New 几个Paramter: new SqlParameter("@Value1",value)...
在查询字符串中使用@+字符 来描述参数,在SqlParameter中的参数名也要使用"@"符号。
而在Oracle中Sql 语句不能使用@符号, 以冒号":"代替. 如:
------string Sql = "Insert into SEARCH_HISTORY(KEYWORDS,PHONE,RESULT_ID,SEARCH_TIME) values(:KEYWORDS,:PHONE,:RESULT_ID,:SEARCH_TIME)";
OracleCommand cmd = new OracleCommand(Sql, OracleConn);
cmd.Parameters.AddRange(new OracleParameter[]{
new OracleParameter("KEYWORDS",OracleType.VarChar),
new OracleParameter("PHONE",OracleType.VarChar),
new OracleParameter("RESULT_ID",OracleType.Number),
new OracleParameter("SEARCH_TIME",OracleType.DateTime)
});
cmd.Parameters[0].Value = Keywords;
cmd.Parameters[1].Value = Phone;
cmd.Parameters[2].Value=2;
cmd.Parameters[3].Value = DateTime.Now;
114、请简单介绍依赖注入在asp.net中的基本体现
所谓“依赖注入”,就是将应用程序所依赖的组件在运行的时候动态的加载到应用程序中间。依赖注入的目标并非为、应用程序添加更多的功能,而是提升了组件的重用性,并为应用程序搭建一个具有较强灵活性和扩展性的平台。在Asp.net中,程序的实现是如此实现的:Assembly.Load(AssemblyName).CreateInstance(TypeName(类名等)),如此可以在程序中得到一个要求的对象实例。在程序的实现过程中间,可以配合反射技术,达到更加灵活的变化。
115、任复明整理经典sql语句集:
(qq)、说明:删除数据库
drop database dbname
(qq)、说明:备份sql server
--- 创建 备份数据的 device
USE master
EXEC sp_addumpdevice 'disk', 'testBack', 'c:\mssql7backup\MyNwind_1.dat'
--- 开始 备份
BACKUP DATABASE pubs TO testBack
(qq)、说明:创建新表
create table tabname(col1 type1 [not null] [primary key],col2 type2 [not null],..)
根据已有的表创建新表:
A:create table tab_new like tab_old (使用旧表创建新表)
B:create table tab_new as select col1,col2… from tab_old definition only
(qq)、说明:删除新表
drop table tabname
(qq)、说明:增加一个列
Alter table tabname add column col type
注:列增加后将不能删除。DB2中列加上后数据类型也不能改变,唯一能改变的是增加varchar类型的长度。
(qq)、说明:添加主键: Alter table tabname add primary key(col)
(qq)、说明:删除主键: Alter table tabname drop primary key(col)
(qq)、说明:创建索引:create [unique] index idxname on tabname(col….)
删除索引:drop index idxname
注:索引是不可更改的,想更改必须删除重新建。
(qq)、说明:创建视图:create view viewname as select statement
删除视图:drop view viewname
(qq)、说明:几个高级查询运算词
A: UNION 运算符
UNION 运算符通过组合其他两个结果表(例如 TABLE1 和 TABLE2)并消去表中任何重复行而派生出一个结果表。当
ALL 随 UNION 一起使用时(即 UNION ALL),不消除重复行。两种情况下,派生表的每一行不是来自 TABLE1 就是
来自 TABLE2。
B: EXCEPT 运算符
EXCEPT 运算符通过包括所有在 TABLE1 中但不在 TABLE2 中的行并消除所有重复行而派生出一个结果表。当 ALL
随 EXCEPT 一起使用时 (EXCEPT ALL),不消除重复行。
C: INTERSECT 运算符
INTERSECT 运算符通过只包括 TABLE1 和 TABLE2 中都有的行并消除所有重复行而派生出一个结果表。当 ALL 随
INTERSECT 一起使用时 (INTERSECT ALL),不消除重复行。
注:使用运算词的几个查询结果行必须是一致的。
(qq)、说明:使用外连接
A、left outer join:
左外连接(左连接):结果集几包括连接表的匹配行,也包括左连接表的所有行。
SQL: select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c
B:right outer join:
右外连接(右连接):结果集既包括连接表的匹配连接行,也包括右连接表的所有行。
C:full outer join:
全外连接:不仅包括符号连接表的匹配行,还包括两个连接表中的所有记录。
(qq)、说明:复制表(只复制结构,源表名:a 新表名:b) (Access可用)
法一:select * into b from a where 1<>1
法二:select top 0 * into b from a
说明:拷贝表(拷贝数据,源表名:a 目标表名:b) (Access可用)
insert into b(a, b, c) select d,e,f from b;
(qq)、说明:跨数据库之间表的拷贝(具体数据使用绝对路径) (Access可用)
insert into b(a, b, c) select d,e,f from b in ‘具体数据库’ where 条件
例子:..from b in '"&Server.MapPath(".")&"\data.mdb" &"' where..
(qq)、说明:子查询(表名1:a 表名2:b)
select a,b,c from a where a IN (select d from b ) 或者: select a,b,c from a where a IN (1,2,3)
(qq)、说明:外连接查询(表名1:a 表名2:b)
select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c
(qq)、说明:在线视图查询(表名1:a )
select * from (SELECT a,b,c FROM a) T where t.a > 1;
(qq)、说明:between的用法,between限制查询数据范围时包括了边界值,not between不包括
select * from table1 where time between time1 and time2
select a,b,c, from table1 where a not between 数值1 and 数值2
(qq)、说明:in 的使用方法
select * from table1 where a [not] in (‘值1’,’值2’,’值4’,’值6’)
(qq)、说明:两张关联表,删除主表中已经在副表中没有的信息
delete from table1 where not exists ( select * from table2 where table1.field1=table2.field1 )
(qq)、说明:四表联查问题:
select * from a left inner join b on a.a=b.b right inner join c on a.a=c.c inner join d on a.a=d.d
where .....
(qq)、说明:日程安排提前五分钟提醒
SQL: select * from 日程安排 where datediff('minute',f开始时间,getdate())>5
(qq)、说明:一条sql 语句搞定数据库分页
select top 10 b.* from (select top 20 主键字段,排序字段 from 表名 order by 排序字段 desc) a,表名 b
where b.主键字段 = a.主键字段 order by a.排序字段
(qq)、说明:前10条记录
select top 10 * form table1 where 范围
(qq)、说明:选择在每一组b值相同的数据中对应的a最大的记录的所有信息(类似这样的用法可以用于论坛每月排行
榜,每月热销产品分析,按科目成绩排名,等等.)
select a,b,c from tablename ta where a=(select max(a) from tablename tb where tb.b=ta.b)
(qq)、说明:包括所有在 TableA 中但不在 TableB和TableC 中的行并消除所有重复行而派生出一个结果表
(select a from tableA ) except (select a from tableB) except (select a from tableC)
(qq)、说明:随机取出10条数据
select top 10 * from tablename order by newid()
(qq)、说明:随机选择记录
select newid()
(qq)、说明:删除重复记录
Delete from tablename where id not in (select max(id) from tablename group by col1,col2,...)
(qq)、说明:列出数据库里所有的表名
(qq)、select name from sysobjects where type='U'
(qq)、说明:列出表里的所有的
select name from syscolumns where id=object_id('TableName')
(qq)、22、说明:列示type、vender、pcs字段,以type字段排列,case可以方便地实现多重选择,类似select 中
的case
select type,sum(case vender when 'A' then pcs else 0 end),sum(case vender when 'C' then pcs else 0
end),sum(case vender when 'B' then pcs else 0 end) FROM tablename group by type
显示结果:
type vender pcs
电脑 A 1
电脑 A 1
光盘 B 2
光盘 A 2
手机 B 3
手机 C 3
(qq)、说明:初始化表table1
TRUNCATE TABLE table1
(qq)、说明:选择从10到15的记录
select top 5 * from (select top 15 * from table order by id asc) table_别名 order by id desc
技巧
(qq)、1=1,1=2的使用,在SQL语句组合时用的较多
“where 1=1” 是表示选择全部 “where 1=2”全部不选,
如:
if @strWhere !=''
begin
set @strSQL = 'select count(*) as Total from [' + @tblName + '] where ' + @strWhere
end
else
begin
set @strSQL = 'select count(*) as Total from [' + @tblName + ']'
end
我们可以直接写成
set @strSQL = 'select count(*) as Total from [' + @tblName + '] where 1=1 安定 '+ @strWhere
(qq)、收缩数据库
--重建索引
DBCC REINDEX
DBCC INDEXDEFRAG
--收缩数据和日志
DBCC SHRINKDB
DBCC SHRINKFILE
(qq)、压缩数据库
dbcc shrinkdatabase(dbname)
(qq)、转移数据库给新用户以已存在用户权限
exec sp_change_users_login 'update_one','newname','oldname'
go
(qq)、检查备份集
RESTORE VERIFYONLY from disk='E:\dvbbs.bak'
(qq)、修复数据库
ALTER DATABASE [dvbbs] SET SINGLE_USER
GO
DBCC CHECKDB('dvbbs',repair_allow_data_loss) WITH TABLOCK
GO
ALTER DATABASE [dvbbs] SET MULTI_USER
GO
(qq)、说明:更改某个表
exec sp_changeobjectowner 'tablename','dbo'