.net基本面试题

OOP: Object Oriented Programming:

面向对象编程技术的关键性观念是它将数据及对数据的操作行为放在一起,作为一个相互依存、不可分割的整体——对象。对于相同类型的对象进行分类、抽象后,得出共同的特征而形成了类

AOP(面向切面编程)

在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

OIP

面向接口软件设计是一种软件设计模式,面向接口编程可以更好的降低系统的耦合度,实现高内聚的软件实现的一种手段。

PO

面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以。

svn和tfs区别

相比SVN,对于TFS的优点我有以下几点看法,供大家参考:

1. 总体比较:

TFS是一个应用软件生命周期管理(ALM)软件,是一个软件研发平台产品,其功能覆盖了软件研发过程中的所有环节(包括源代码管理)和所有角色;而SVN只是一个简单的源代码管理工具。

可以简单来说,TFS具备SVN的所有源代码管理功能,二者是一个包含和被包含的关系。

2. 源代码功能比较:

单就源代码管理方面,TFS的优势在于:

1)易用性。

在用户习惯上,TFS秉承了微软所有产品的特新,开发人员非常容易上手。软件使用过程中,用户会发现与日常导入操作系统、开发工具(VS),Office软件等有很多共同的体验。

2)高度集成其他工具。

TFS高度集成主流的开发工具和常见的办公工具。

例如Visual Studio, Eclipse, XCode, ItelliJ,

例如Excel, 浏览器,Project

同时,TFS提供方便的API(.NET API, Java API, Rest API)集成,可以与企业现有的系统实现数据共享

3)高度集成研发团队的工作项目

可以通过TFS的源代码,查询到代码变更的依据(需求、任务、Bug等)

反过来,可以通过项目管理的数据(需求、任务、Bug等),查询到相应代码的变动。例如,你可以查询到修复Bug所修改的代码行数。

4)支持分布式代码库(Git)

除了支持集中式代码库(SVN属于此类),TFS还支持分布式的源代码库Git。这为TFS开拓了分布式代码管理的一个广阔天地,是SVN望成莫及的。

5)搁置集

可以通过TFS将代码保持在服务器上,但是不签入到代码库中,实现将你的变更保存在服务器上一个临时的位置。这样,既备份了自己的代码,有不会影响其他团队成员的代码。

6)代码评审

TFS提供基于开放工具的便捷的代码评审机制,可以实现研发团队内部之间的代码评审,或者与外部专家的代码评审。

7)后台数据库存储

TFS的所有源代码和版本信息都存储在数据库中,在大型软件研发团队中,可以大幅提升数据的查询和存储速度。

同时,基于数据库存储,系统管理员可以方便的备份和还原TFS中的任何数据。

8)代码搜索

TFS提供非常方便的代码搜索功能,开发人员可以在代码库中基于方法、类、对象等查询相关文件和代码。

9)快速修改代码

你可以不需要任何开发工具,在浏览器上就可以完成代码的修改功能。

10)自动化生成和发布

开箱即用的TFS就集成的自动生成和发布功能。可以实现修改代码以后,生成和发布自动完成;也可以在发布过程中增加流程控制,例如需要项目经理审批才能继续发布过程。

 

Net2.0和3.5的区别?

NET 3.5在2.0的基础上加入了一些新的语法和特性,主要增加了:

WPF是原WINFORM的替代方案,使用DX底层显示驱动实现界面绘图,性能更好.

WCF是原webservice、COM+等分布式应用的替代方案.

LINQ更强大的内存对象查询语言

WF MS的workflow

SILVERLIGHT MS的RIA工具,在B/S上获得更好的用户体验.

.net framework各个版本介绍:

.NET框架 1.0      发行于2002年

.NET框架 1.1      发行于2003年

.NET框架 2.0      发行于2005年     Visual Studio 2005、SQL Server 2005

.NET框架 3.0      发布日期2006/11/21

  新增3个主要技术:

    Windows Presentation Foundation(WPF):提供更佳的用户体验,用来开发Windows Forms程序以及流览器应用程序.

    Windows Communication Foundation(WCF):提供SOA(面向服务的软件构架)支持的安全的网络服务(Web Service)框架。

    Windows Workflow Foundation(WF):提供一个设计与发展工作流程导向(Workflow-oriented)应用程序基础支持的应用程序接口。

.NET框架 3.5      Visual Studio 2008

    新增了以下新特性:

    LINQ, Language-Integrated Query

    扩展方法(Extension Method)属性(Attribute)用于为扩展方法提供支持LINQ支持,包括LINQ to Object、LINQ to ADO .NET以及LINQ to XML表达式目录树,用于为Lambda表达式提供支持与语言集成查询 (LINQ)和数据感知紧密集成。

    WCF服务的全新Web协议支持,包括AJAX、JSON、REST、POX、RSS、ATOM和若干新的WS-*标准。

    Visual Studio 2008中面向WF、WCF和WPF的完整工具支持。

  ADO .NET Entity Framework

.NET框架 4.0

  .NET框架 4.0主要增加了并行支持,异步编程。

SQL SERVER 2008 中常见的两种分页方法与比较

分页方案一:(利用Not In和SELECT TOP分页)

SELECT TOP 10 * FROM TableName WHERE ID NOT IN (SELECT TOP 20 id FROM TableName ORDER BY id) ORDER BY ID

通过SQL 查询分析器,显示比较:我的结论是:

分页方案一:(利用Not In和SELECT TOP分页)   效率高,但需要拼接SQL语句

分页方案二:利用Row Number完成分页,效率最高,但也需要拼接SQL语句

以上两种,可以使用存储过程封装使用。

分页方案二:利用Row Number完成分页

SELECT * FROM

(SELECT ROW_NUMBER() OVER(ORDER BY id asc) AS rownum, id FROM company ) AS D

WHERE rownum BETWEEN (@pageIndex-1)*@pageSize+1 AND @pageIndex*@pageSize

ORDER BY id asc

Cookie和Session区别与工作机制比较

1、cookie数据存放在客户的浏览器上,session数据放在服务器上。

2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗

   考虑到安全应当使用session。

3、session会在一定时间内保存在服务器上,通过SessionID 标识符来读取服务上存储的数据。

       session,默认为20分钟

       当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用COOKIE。

session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。

session是通过cookie的机制来实现的,保存session id的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发给服务器。由于cookie可以被人为的禁止,必须有其他机制以便在cookie被禁止时仍然能够把session id传递回服务器。经常被使用的一种技术叫做URL重写,就是把session id直接附加在URL路径的后面,附加方式也有两种,一种是作为URL路径的附加信息,表现形式为http://...../xxx; jsessionid=ByOK ... 99zWpBng!-145788764 另一种是作为查询字符串附加在URL后面,表现形式为http://...../xxx?jsessionid=ByOK ... 99zWpBng!-145788764 

4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。

5、所以个人建议:

   将登陆信息等重要信息存放为SESSION

    其他信息如果需要保留,可以放在COOKIE中

    Cookie和Session的工作机制比较详细说明

    http://www.cnblogs.com/notifier/archive/2010/10/11/1847959.html

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

Session

cookie

Get

Post

Application

ViewState

ASP.Net页面生命周期

页面初始化          Page_Init 

加载View State      LoadViewState  

回发数据处理      LoadPostData  

页面加载          Page_Load  

回发通知          RaisePostDataChangedEvent 

回发事件处理     RaisePostBackEvent 

页面预渲染       Page_PreRender  

保存             viewstate SaveViewState  

Page渲染         Page_Render  

Page 卸载       Page_UnLoad

什么是装箱和拆箱?

答:从值类型接口转换到引用类型即为装箱。从引用类型转换到值类型即为拆箱。

什么是协变和抗变(逆变)

协变,可以理解成:父类 -> 子类。父类的对象用子类替换,也可以理解成子类当父类用。

抗变,可以理解成:子类 -> 父类。子类的对象用父类替换,也可以理解成父类当子类用。抗变也常常翻译为逆变。

Abstract Class抽象类

抽象类往往用来表征对问题领域进行分析、设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象。

通常在编程语句中用 abstract 修饰的类是抽象类。

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

抽象类与接口的区别

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

接口用于规范,抽象类用于共性。接口中只能声明方法,属性,事件,索引器。而抽象类中可以有方法的实现,也可以定义非静态的类变量。抽象类是类,所以只能被单继承,但是接口却可以一次实现多个。抽象类可以提供某些方法的部分实现,接口则不可以.

抽象类的实例是它的子类给出的。接口的实例是实现接口的类给出的。

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

接口成员被定义为公共的,但抽象类的成员也可以是私有的、受保护的、内部的或受保护的内部成员。

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

 

接口和抽象类的相似之处有三点:

       1、不能实例化;

       2、包含未实现的方法声明;

       3、派生类必须实现未实现的方法及成员(抽象类是抽象方法,接口则是所有成员)。

抽象基类与接口的区别

A.抽象类可以包含非抽象方法,而接口只能包含抽象方法

B.抽象类可以被实例化,而接口不能被实例化

C.一个类可以同时实现多个接口,但一个类只能同时派生自一个基类。

D.接口只有成员的定义,不能含有任何成员的实现,而抽象类可以含有某些成员的具体实现。

const和readonly有什么区别?

readonly用来声明运行时常量,也称只读变量;readonly修饰的变量可在初始化时赋值,也可在类构造中初始化。

const关键字用来声明编译时常量,其值不能被修改。const修饰的常量必须在声明的同时赋值。

.Net 垃圾回收机制的理解

NET中的垃圾回收机制是引用程序对内存的回收和释放。当每次用new关键字创建对象时,运行库都要从托管堆中为其分配内存,因为空间是有限的,最终垃圾回收机制是要回收不用的内存,并释放内存空间,用以重新使用。垃圾回收机制会根据正在进行的分配情况确定对空间执行回收的最佳时机。当垃圾回收器执行回收时,它检查托管堆中不再被应用程序使用的对象并执行必要的操作来回收它们占用的内存。

密封类sealed的作用

sealed 类不允许有派生类。如果一个密封类被指定为其他类的基类,则发生编译时错误。

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

sealed 修饰符主要用于防止非有意的派生,但是它还能促使某些运行时优化。具体说来,由于密封类永远不会有任何派生类,所以对密封类的实例的虚拟函数成员的调用可以转换为非虚拟调用来处理。

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

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

sealed说明该类不可被继承

override重写基类的方法

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

重写(Override)和重载(Overload)有什么区别?

答:重载Overload是方法名称相同, 不同的参数类型,不同的参数个数,不同的参数顺序,可以完成重载。

重写Override提供了子类中覆盖父类中虚方法行为的实现(是进行基类中函数的重写)。

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

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

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

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

委托与事件的区别:

事件是基于委托实现的, 委托通过使用delegate关键词定义,委托可以在客户代码中直接调用委托来调用委托所指向的方法,而事件不可以,事件通过在委托基础之上,使用event关键词定义,事件所指向的方法的触发只能由代码自己完成,也就是在代码中委托你不但可以安排谁是它的调用者,还可以直接调用它,而事件一般不直接调用,只能通过某些操作间接触发。

C#中的堆和栈

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

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

C# ref与out区别:

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

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

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

HttpWebRequest和WebClient的区别:

功能区别:

1、WebRequest是 .NET Framework 的用于访问 Internet 数据的请求/响应模型的抽象基类。使用该请求/响应模型的应用程序可以用协议不可知的方式从 Internet 请求数据,在这种方式下,应用程序处理 WebRequest 类的实例,而协议特定的子类则执行请求的具体细节,编程中使用的是子类HttpWebRequest

2、WebClient 类提供向 URI 标识的资源发送数据和从 URI 标识的资源接收数据的公共方法,提供向 URI 标识的任何本地、Intranet 

或 Internet 资源发送数据以及从这些资源接收数据的公共方法,WebClient 类使用 WebRequest 类提供对 Internet 资源的访问

也就是说功能大致向同行,WebClient用来上传或下载数据,WebRequest用来请求服务器的监听,WebResponse获取服务器端的响应

对COOKIE和SEIION支持区别

WebClient不具持续性,因此不支持cookie和session,具体说来就是,常见的管理系统中,一般都有登录页和管理页,在登陆页输入用户名和密码,在管理页显示登录页输入的用户名,但是,WebClient实现不了这样的效果,在第一次请求登录页时,验证成功之后,WebClient不会保存http响应报文中的SetCookie,更不会设置下一次http请求报文的Cookie,因此跳转到管理页后,在管理页时接收不到存相应的cookie,因此,webclient更适用于多次请求没有联系的请求,而WebRequest则相反

用户对是否自动url转向的控制

               WebClient不支持

      WebRequest支持(HttpWebRequest有AllowAutoRedirect属性)

对用户代理服务器的支持

    WebClient不支持       

    WebRequest支持(HttpWebRequest有UserAgent属性)

 

1,HttpWebRequest是个抽象类,所以无法new的,需要调用HttpWebRequest.Create();

其Method指定了请求类型,这里用的GET,还有POST;也可以指定ConentType;

其请求的Uri必须是绝对地址;

其请求是异步回调方式的,从BeginGetResponse开始,并通过AsyncCallback指定回调方法;

2. WebClient 方式使用基于事件的异步编程模型,在HTTP响应返回时引发的WebClient回调是在UI线程中调用的,因此可用于更新UI元素的属性,例如把 HTTP响应中的数据绑定到UI的指定控件上进行显示。HttpWebRequest是基于后台进程运行的,回调不是UI线程,所以不能直接对UI进行操作,通常使用Dispatcher.BeginInvoke()跟界面进行通讯。

WebRequest类

命名空间: System.Net

发出对统一资源标识符 (URI) 的请求。这是一个抽象类。

WebRequest 是 .NET Framework 的用于访问 Internet 数据的请求/响应模型的抽象基类。使用该请求/响应模型的应用程序可以用协议不可知的方式从 Internet 请求数据。在这种方式下,应用程序处理 WebRequest 类的实例,而协议特定的子类则执行请求的具体细节。

请求从应用程序发送到某个特定的 URI,如服务器上的 Web 页。URI 从一个为应用程序注册的 WebRequest 子代列表中确定要创建的适当子类。注册 WebRequest 子代通常是为了处理某个特定的协议(如 HTTP 或 FTP),但是也可以注册它以处理对特定服务器或服务器上的路径的请求。

WebClient 类:

提供向 URI 标识的资源发送数据和从 URI 标识的资源接收数据的公共方法。不能继承此类。

WebClient 类提供向 URI 标识的任何本地、Intranet 或 Internet 资源发送数据以及从这些资源接收数据的公共方法。

WebClient 类使用 WebRequest 类提供对 Internet 资源的访问。WebClient 实例可以通过任何已向 WebRequest.RegisterPrefix 方法注册的 WebRequest 子代访问数据。

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

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

好处是类型安全和减少装箱、拆箱的性能消耗。

提高程序性能、减少类型安全检查、提高代码质量,减少重复性的编程代码。

New的三种用法

在 C# 中,new 关键字可用作运算符、修饰符或约束。

new 运算符 用于创建对象和调用构造函数。

new 修饰符 用于向基类成员隐藏继承成员。

new 约束 用于在泛型声明中约束可能用作类型参数的参数的类型。搜索

String类与StringBuilder类有什么区别?

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

String 对象是不可改变的。每次使用 System.String 类中的方法之一或进行运算时,都要在内存中创建一个新的字符串对象,开辟一个新的空间。

StringBuilder 则不会。在需要对字符串执行重复修改的情况下,创建新的 String 对象系统开销可能会非常昂贵。 比如当在循环中,需要将字符串多次结果累加时,使用 StringBuilder 类可以提升程序性能。

HashMap和Hashtable的区别

答:HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable.

GET与POST的区别

 (1)get可以从服务器上获取数据,向服务器传送数据可以使用get、post。

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

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

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

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

 

提高.NET项目的性能

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

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

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

//避免

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

//推荐

if(!strABC.IsNullOrEmpty(strABC)) {}

4 页面优化,页面静态化、页面缓存技术等技术

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

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

7 只读数据访问用SqlDataReader,不要使用DataSet,但要注意DataReader的关闭问题。

net中有哪几种缓存?缓存的优点是?

整页缓存       @OutputCache指令

局部缓存       @OutputCache指令

应用程序缓存Cache类、Response.Cache对象

缓存好处:缓存是网站性能优化不可缺少的一种数据处理机制,他能有效的缓解数据库压力

例:<%@OutputCache Duration="5"VaryByParam="none"%>

<%@OutputCache Duration="5"VaryByParam="none“ VaryByControl=a"TextBox"%>

VaryByParam属性基于使用post或者get方式发送的名称/值对来改变缓存。

VaryByControl属性通过用户控件文件中包含的服务器控件来改变缓存。

MVC中的页面缓存实现?

·  public class HomeController : Controller  

·  {  

·      [OutputCache(Duration = 5, VaryByParam = "none")]  

·      public ActionResult Index()  

·      {  

·          return View();  

·      }  

·  }  

缓存更新

在项目启动时,我们可以将数据库中的需要缓存的数据,一次性将全部缓存到memcached各个Key当中。当数据库中的相关表数据发生变化时,可以根据不同的Key进行缓存版本的更新。对于一些数据量大的表或者不需要即时显示的数据,我们可以采取一些策略:定时更新或根据更新的数据条目来判断是否需要更新。在缓存更新前,应首先判断是否有数据发生变化,如果未发现变化,则无需更新缓存。

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

CTS:通用语言系统。

CLS:通用语言规范。

CLR:公共语言运行库。

什么是受管制的代码?

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

什么是 RTTI 强类型系统?

答:强类型系统是对数据类型有严格的要求和限制,每一个变量和每一个表达式都有类型,在使用一个变量前系统都会进行类型检查。

什么是托管代码?

托管代码:使用CLR编译语言编辑器开发编写的代码就叫托管代码。 

O/R Mapping 的原理 ORM

答:利用反射技术或配置文件方式将对象和数据库中的表作一个映射。

什么是ORM?

Object Relational Mapping对象关系数据库映射工具用来把对象模型表示的对象映射到基于SQL的关系模型数据结构中去,通俗一点讲,就是按表结构 映射 出一个类,在具体开发中使用该类来完成对表的相关操作。

常见的ORM框架说明

Nhibernate

NHibernate是一个基于.Net的针对关系型数据库的对象持久化类库。

Nhibernate来源于非常优秀的基于Java的Hibernate关系型持久化工具。

NHibernate从数据库底层来持久化你的.Net对象到关系型数据库。

NHibernate为你处理这些,远胜于你不得不写SQL去从数据库存取对象。你的代码仅仅和对象关联。

NHibernat自动产生SQL语句,并确保对象提交到正确的表和字段中去。

    定义二

    Nhibernate是全自动化的ORM框架。Nhibernate减少了开发代码量及sql编写的开发工作,因为hibernate是映射到表的会把我们要用到的增、删、改的SQL语句都封装了,我们不需要再自己手动写,直接调用即可,不过他也有确定不适合统计查询系统。对于多表连查,复杂的sql实现比较复杂,而且有可能需要借助其他方案,并且由于自动生成sql语言,所以无法直接对sql语句进行优化。

IBatis

     iBatis 是又ORM工具之一,是一种“半自动化”的ORM实现。

    iBatis 是轻量级的ORM框架.它不象NHibernate那样映射到表,而是映射到SQL语句与存储过程。在项目中Ibatis可以增强系统的可维护性:通过业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护。iBatis 需要自己提前将sql入到配置文件中,这样直接优化sql语句,有利也有弊。当然还要写实体类,写配置文件比较麻烦一些。

EF

ADO.NET Entity Framework 是微软以 ADO.NET 为基础所发展出来的对象关系对应 (O/R Mapping) 解决方案,现已包含在 Visual Studio中,可以直接用以开发数据库应用,要求在.NET3.5以上平台。目前主要支持SqlServer数据库,开发快捷,代码维护量少。

什么是反射?

答:反射(Reflection)是.NET中的重要机制,通过放射,可以动态获得.NET程序集中的成员信息(包括类、结构、委托、接口和枚举等),包括方法、属性、事件,以及构造函数等。有了反射,即可对每一个类型了如指掌。如果获得了构造函数的信息,即可直接创建对象,即使这个对象的类型在编译时还不知道。

通过反射技术,可以动态的获取有关已加载程序集和在其中定义的类型(如类、接口和值类型)的信息。使用反射在运行时可以创建类型实例,以及调用和访问这些实例的成员。

概述反射和序列化

反射是.NET中的重要机制,通过反射,可以在运行时获得程序或程序集中每一个类型(包括类、结构、委托、接口和枚举等)的成员和成员的信息。

 

NET支持对象序列化的几种方式

二进制序列化:对象序列化之后是二进制形式的,通过BinaryFormatter类来实现的,这个类位于System.Runtime.Serialization.Formatters.Binary命名空间下。

 

SOAP序列化:对象序列化之后的结果符合SOAP协议,也就是可以通过SOAP 协议传输,通过System.Runtime.Serialization.Formatters.Soap命名空间下的SoapFormatter类来实现的。

 

XML序列化:对象序列化之后的结果是XML形式的,通过XmlSerializer 类来实现的,这个类位于System.Xml.Serialization命名空间下。XML序列化不能序列化私有数据。

反射通常需要用到的类,及其作用

(1)使用Assembly定义和加载程序集,加载在程序集清单中列出模块,以及从此程序集中查找类型并创建该类型的实例。

(2)使用Module了解包含模块的程序集以及模块中的类等,还可以获取在模块上定义的所有全局方法或其他特定的非全局方法。

(3)使用ConstructorInfo了解构造函数的名称、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。使用Type的GetConstructors或GetConstructor方法来调用特定的构造函数。

(4)使用MethodInfo了解方法的名称、返回类型、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。使用Type的GetMethods或GetMethod方法来调用特定的方法。

(5)使用FiedInfo了解字段的名称、访问修饰符(如public或private)和实现详细信息(如static)等,并获取或设置字段值。

(6)使用EventInfo了解事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等,添加或移除事件处理程序。

(7)使用PropertyInfo了解属性的名称、数据类型、声明类型、反射类型和只读或可写状态等,获取或设置属性值。

(8)使用ParameterInfo了解参数的名称、数据类型、是输入参数还是输出参数,以及参数在方法签名中的位置等。

什么是WebService

WebService是一种跨编程语言和跨操作系统平台的远程调用技术。是实现SOA分布式应用程序的一种手段。WebService采用HTTP协议传输数据,采用XML格式封装数据,即以SOAP传递消息。

什么是WSE?目前最新的版本是多少?

答:WSE (Web Service Extension) 包来提供最新的WEB服务安全保证,目前最新版本2.0

WCF与WebService的区别

WCF 支持多种通信协议 Http/Https 、TCP/UDP、MSMQ、命名管道、对等网、消息可达性、事务流等。

WCF 支持多种消息传输格式 :text,binary,mtom,Json 等。

WCF 安全性要强:支持对称安全、非对称安全、消息安全、传输安全、SSL 流安全、Windows 流安全等。

WCF 支持多种会话模式:请求/响应、单工、双工。

WCF 支持REST调用 。

WCF 支持多种格式化方式。DataContractSerializer、XmlSerializer、DataContractJsonSerializer 等。

WCF 支持多种服务承载方式: WAS hosting、Windows 服务 hosting、Self-Hosting、IIS hosting 等。

WCF 支持多种并发模式:单例、单调、会话

WebService:严格来说是行业标准,使用XML扩展标记语言来表示数据。

它使用Soap简单对象访问协议来实现分布式环境里应用程序之间的数据交互。

使用WSDL来实现服务接口相关的描述。

与WCF相比,只支持Http/Https协议及请求应答模式

.net remoting和WebService两项技术的应用。

答:WebService主要是可利用HTTP,可以轻易穿透防火墙,使用的是SOAP消息机制。Remoting使用底层TCP/IP协议,使用二进制传送数据,效率高。

Remoting采用的RPC远程进程调用.

Web Service能用于不同平台,不同语言的跨平台开发。.net Remoting只适用于.Net。 效率上Remoting高于Xml Web Service

WCF

Windows Communication Foundation(WCF)是由微软开发的一系列支持数据通信的应用程序框架,即Windows 通讯开发平台。其整合了原有的windows通讯的 .net Remoting,WebService,Socket的机制,并支持HTTP,TCP,Named Pipe,MSMQ,Peer-To-Peer TCP 等协议。目前WCF是Windows平台上开发SOA分布式应用的不错选择。WCF可以用于应用程序接口开发。

WCF主要包括以下部分:

    四种契约(描述了该服务的功能和作用)

    服务契约(WCF服务的对外接口作定义和声明)

    数据契约(定义了服务端和客户端之间要传送的自定义数据类型。)

    错误契约(错误类型)

    消息契约(消息的格式)

    寄宿(部署方式)

    IIS承载、WAS承载(IIS7.5以上支持)、应用程序承载(也称自承载)

    服务行为

    消息(消息的传输方式、消息的编码与解码、安全性)

WCF一个服务终结点主要由:Address、Binding、Contract构成。

     Address: Address通过一个URI唯一地标识一个Endpoint,并告诉潜在的WCF service的调用者如何找到这个Endpoint。

    Binding: Binding实现在Client和Service通信的所有底层细节。

    Contract: Contract的主要的作用是暴露某个WCF Service所提供的所有有效的功能。

WCF支持的协议有:

    ·BasicHttpBinding: 通常用于 Web Services。使用 HTTP 协议,Text/XML 编码方式。

    ·WSHttpBinding: 比 BasicHttpBinding 更加安全,通常用于 non-duplex 服务通讯。

    ·WSDualHttpBinding: 和 WSHttpBinding 相比,它支持 duplex 类型的服务。

    ·WSFederationHttpBinding: 支持 WS-Federation 安全通讯协议。

    ·NetTcpBinding: 效率最高,安全的跨机器通讯方式。

    ·NetNamedPipeBinding: 安全、可靠、高效的单机服务通讯方式,可以连接到同一台计算机上的其它WCF终结点。

    ·NetMsmqBinding: 使用消息队列在不同机器间进行通讯。

    ·NetPeerTcpBinding: 使用 P2P 协议在多机器间通讯。

    ·MsmqIntegrationBinding: 使用现有的消息队列系统进行跨机器通讯。如 MSMQ。

WCF加密方式、身份验证:

    1. 无身份验证:         所有的调用者都能访问服务

    2.Windows身份验证:Kerberos(有域服务器)和NTLM(工作组)

    3.用户名与密码:       客户端向服务端发送一个用户名和密码,服务端通过一些凭证库来验证

    4.X509证书:           客户端包含一个证书,服务端预先知道这些证书,当客户端发送请求时,服务端会验证客户端的证书。(通过makecert.exe 生成服务端证书、客户端证书,通过证书来验证用户身份)

    5.定制机制:            允许开发者任意使用一种身份验证机制

    6.发布口令:             调用者与服务同事依赖一个安全口令

WCF 中可以使用不同的安全方式来实现数据传输安全。

    •None 指定客户端不需要提供凭据。这相当于匿名客户端。

    •Windows 允许在使用 Windows 凭据建立的安全上下文中交换 SOAP 消息。

    •UserName、Password允许服务可以要求使用用户名凭据对客户端进行身份验证。

    •Certificate 允许服务可以要求使用 X.509 证书对客户端进行身份验证。

•IssuedToken 根据安全策略配置的自定义令牌类型。默认令牌类型为安全断言标记语言 (SAML)。令牌由安全令牌服务颁发。

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

答:1.使用命令行工具(WSDL.exe或svcutil.exe)。

    2.使用VS.NET中的添加Web引用或添加服务引用

解释一下UDDI、WSDL的意义及其作用。

答:

UDDI即统一描述、发现和集成协议。

    作用:用来说明一个服务的一些信息类型,帮助服务的请求者确定如下问题: 

    How : 服务如何使用,相关描述信息位置,如何与服务通讯,就是协议是什么。

    Where:服务在网络中的所处位置。 

WSDL: Web Services Description Language的缩写,是一个用来描述Web服务和说明如何与Web服务通信的XML语言。 

    WSDL用来提供对服务的描述,它的主要构成要素有五个:

    1)Types: 定义WSDL定义中所用到的数据类型,即XML Schema Types

    2)Message : 对一组消息的输入和输出参数的定义 

3)PortType : 定义Web服务的操作 

4) Binding :描述特定服务接口的协议、数据格式、安全性和其它属性.

5) Services : 制定特定服务的URL和提供的调用接口,包含一组端口元素 

什么是SOAP?

答:SOAP(Simpe Object Access Protoco )简单对象访问协议是在分散或分布式的环境中交换信息并执行远程过程调用的协议,是一个基于XML的协议。使用SOAP,不用考虑任何特定的传输协议(最常用的还是HTTP协议),可以允许任何类型的对象或代码,在任何平台上,以任何一直语言相互通信。

  SOAP 是一种轻量级协议,用于在分散型、分布式环境中交换结构化信息。 SOAP 利用 XML 技术定义一种可扩展的消息处理框架,它提供了一种可通过多种底层协议进行交换的消息结构。这种框架的设计思想是要独立于任何一种特定的编程模型和其他特定实现的语义。

    SOAP 定义了一种方法以便将 XML 消息从 A 点传送到 B 点。为此,它提供了一种基于 XML且具有以下特性的消息处理框架:1) 可扩展,2) 可通过多种底层网络协议使用,3) 独立于编程模型。

WCF的三种实例模式:

在WCF通过服务行为ServiceBehavior 的InstanceContextMode枚举进行设置.InstanceContextMode有三种枚举类型

           PerSession=0 会话实例,此为默认值

           PerCall=1 

           Single=2

PerSession实例行为

PerSession表示会话实例行为,当客户端调用服务器后,服务器端会为客户端分配一个新的服务实例,这个实例在服务器端SESSION时间过期后将失效。客户端每调用一次服务,在客户端生成一个新的代理实例,都会产生一个新的会话。

     PerSession实例行为有点类似于ASP.NET中的session,但又些不同.

     在WCF中使用PerSession实例,需要手动设置行为

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)], 默认情况下,WCF的实例行为为PerSession

在WCF中,并不是所有通信协议都可以使用PerSession实例行为的,只有支持会话的通信协议才可以使用PerSession实例,如:NetTcpBinding, NetNamePipeBinding,wsHttpBinding, wsFederationHttpBinding,wsDualHttpBinding.

PerCall实例行为

PerCall实例策略是指WCF为每个客户端的每一次请求,都会生成一个新的服务实例,各个实例不会相互影响,客户端调用结束后,服务器端立刻销毁该实例.

Single实例行为

类似于单件设计模式,所有可以客户端共享一个服务实例,这个服务实例是一个全局变量,该实例第一次被调用的时候初始化,到服务器关闭的时候停止。

设置服务为Single实例行为,只要设置 [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]即可。

承载服务的三种方式:

IIS承载

在Windows进程激活服务(WAS)中承载

托管应用程序中承载(自承载)

Web API

1、ASP.NET MVC4中的Web API提供了很好的API接口开发方式。可以更好地适应现在的跨平台移动互联网开发。相信大家很多的项目现在都在使用Web Service作为提供数据的接口。好吧,那么Web API(http)将是用来革Web Service(http、https)的命。

2、Web API 框架是一个面向 Http 协议的通信框架。相对于 WCF 而言,Web API 只面向于 Http 协议设计,而且没有 WCF 那么繁琐的配置。Web API 的开发类似于 ASP.NET MVC 中控制器的开发,但是相对于直接使用 ASP.NET MVC 来返回 Json 对象的方式而言,Web API 封装了数据的序列化、反序列化,接口、实现都更加简单。

3、简单地说,如果要向浏览器、移动端提供 Json、XML 数据格式的 API,则应该首选 Web API 作为通信框架。

4、WebAPI用于提供REST风格的WebService,个人比较喜欢REST风格的WebService,感觉比SOAP要轻量级一些,而且对客户端的要求也更少,更符合网络数据传输的一般模式,客户端完全摆脱了代理和管道来直接和WebService进行交互。

WebAPI数据序列化

Web API 框架目前支持两种数据格式的序列化:Json 及 Xml。在不做任何配置的情况下,如果 Http 请求中,HttpHeader 中 Accept 被指定为 accept: application/xml,则 Web API 会自动把数据使用 xml 进行序列化,否则使用 json 序列化。

net Remoting 的工作原理是什么?

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

Remoting示例代码

// 1. 使用默认构造函数创建一个TCP侦听信道

TcpServerChannel serverChannel = new TcpServerChannel(9090);

ChannelServices.RegisterChannel(serverChannel);

// 2. 使用带信道配置属性的形式创建TCP侦听信道

IDictionary dict = new Hashtable();

dict["port"] = 9090;

dict["authenticationMode"] = "IdentifyCallers";

TcpServerChannel serverChannel = new TcpServerChannel(dict, null);

ChannelServices.RegisterChannel(serverChannel);          

// 3. 指定信道名称、端口及格式标识符提供程序的形式创建信道

BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();

serverProvider.TypeFilterLevel = TypeFilterLevel.Full;

TcpServerChannel channel = new TcpServerChannel( "Server Channel",9090, serverProvider);

ChannelServices.RegisterChannel(serverChannel,false);

C#中params关键字的作用理解:

params 关键字可以指定在参数数目可变处采用参数的方法参数。主要是当参数为数组并且长度未知时,可以使用。

public static void UseParams(params object[] list)

PDB是什么东西?

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

程序集相同目录。

根据线程安全的相关知识,分析以下代码,当调用test方法时i>10时是否会引起死锁?

public void test(int i)

{

   lock(this)

{

   if (i>10)

   {

     i--;

     test(i);

   }

}

}

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

Debug Build和Release Build的区别,是否会有明显的速度变化?

Debug会产生pdb文件,release不会。

Debug用于开发时的调试,不能用于部署。

release用于部署,并且不产生pdb文件及各种调试信息,当然有明显的速度提升。.

debug编译一些特殊代码,比如调试信息,而Release则会将那些特殊标记省略。

JIT(Just-In-Time Compiler)即时编译是以assembly为单位发生还是以方法为单位发生?

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

使用,此时CLR傻乎乎的给整个程序集都给Compile了,CLR会变的效率低下。

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

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

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

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

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

实现IClonable接口,并实现其的Clone方法。

深拷贝是指源对象与拷贝对象互相独立,其中任何一个对象的改动都不会对另外一个对象造成影响。

浅拷贝是指源对象与拷贝对象共用一份实体,仅仅是引用的变量不同(名称不同)。对其中任何一个对象的改动都会影响另外一个对象。

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

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

system.web 系统配置

compilation动态调试编译设置

customErrors自定义错误信息设置

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

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

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

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

base关键字有几种用法?

答案:两种,分别是调用基类构造和调用基类方法

解释一下ajax及实现原理

答:Ajax是一种无刷新技术,通过使用Ajax可以开发出无刷新应用,提高用户体验。XmlHttpRequest对象对Ajax技术提供完整的支持。,它使您可以使用JavaScript向服务器提出请求并处理响应, 而不阻塞用户,异步请求。可以完成无刷新效果,改善用户体验。

Ajax应用程序的优势在于:

      1. 通过异步模式,提升了用户体验

      2. 优化了浏览器和服务器之间的传输,减少不必要的数据往返,减少了带宽占用

      3. Ajax引擎在客户端运行,承担了一部分本来由服务器承担的工作,从而减少了大用户量下的服务器负载。

 Ajax可以使用javaScript、JQuery或其它js框架来实现

我们一般使用jquery来实现一般的Ajax调用,比如:

 $.post()、$.Ajax()、$.get()、$.getJson()、 $.load()

$.ajax()方法有那些主要参数

1.url:

要求为String类型的参数,(默认为当前页地址)发送请求的地址。

2.type:

要求为String类型的参数,请求方式(post或get)默认为get。注意其他http请求方法,例如put和delete也可以使用,但仅部分浏览器支持。

3.timeout:

要求为Number类型的参数,设置请求超时时间(毫秒)。此设置将覆盖$.ajaxSetup()方法的全局设置。

4.data:

要求为 Object或String类型的参数,发送到服务器的数据。如果已经不是字符串,将自动转换为字符串格式。get请求中将附加在url后。防止这种自动 转换,可以查看  processData选项。对象必须为key/value格式,例如{foo1:"bar1",foo2:"bar2"}转换 为&foo1=bar1&foo2=bar2。如果是数组,JQuery将自动为不同值对应同一个名称。例如{foo: ["bar1","bar2"]}转换为&foo=bar1&foo=bar2。

5.dataType:

要求为String类型的参数,预期服务器返回的数据类型。如果不指定,JQuery将自动根据http包mime信息返回responseXML或responseText,并作为回调函数参数传递。可用的类型如下:

xml:返回XML文档,可用JQuery处理。

html:返回纯文本HTML信息;包含的script标签会在插入DOM时执行。

script:返回纯文本JavaScript代码。不会自动缓存结果。除非设置了cache参数。注意在远程请求时(不在同一个域下),所有post请求都将转为get请求。

json:返回JSON数据。

jsonp:JSONP格式。使用SONP形式调用函数时,例如myurl?callback=?,JQuery将自动替换后一个“?”为正确的函数名,以执行回调函数。

text:返回纯文本字符串。

6.beforeSend:

要求为Function类型的参数,发送请求前可以修改XMLHttpRequest对象的函数,例如添加自定义HTTP头。在beforeSend中如果返回false可以取消本次ajax请求。XMLHttpRequest对象是惟一的参数。

            function(XMLHttpRequest){

               this;   //调用本次ajax请求时传递的options参数

            }

7.complete:

要求为Function类型的参数,请求完成后调用的回调函数(请求成功或失败时均调用)。参数:XMLHttpRequest对象和一个描述成功请求类型的字符串。

          function(XMLHttpRequest, textStatus){

             this;    //调用本次ajax请求时传递的options参数

          }

8.success:要求为Function类型的参数,请求成功后调用的回调函数,有两个参数。

         (1)由服务器返回,并根据dataType参数进行处理后的数据。

         (2)描述状态的字符串。

         function(data, textStatus){

            //data可能是xmlDoc、jsonObj、html、text等等

            this;  //调用本次ajax请求时传递的options参数

         }

9.error:

要求为Function类型的参数,请求失败时被调用的函数。该函数有3个参数,即XMLHttpRequest对象、错误信息、捕获的错误对象(可选)。ajax事件函数如下:

       function(XMLHttpRequest, textStatus, errorThrown){

          //通常情况下textStatus和errorThrown只有其中一个包含信息

          this;   //调用本次ajax请求时传递的options参数

       }

10.contentType:

要求为String类型的参数,当发送信息至服务器时,内容编码类型默认为"application/x-www-form-urlencoded"。该默认值适合大多数应用场合。

11.jsonp:

要求 为String类型的参数,在一个jsonp请求中重写回调函数的名字。该值用来替代在"callback=?"这种GET或POST请求中URL参数里 的"callback"部分,例如{jsonp:'onJsonPLoad'}会导致将"onJsonPLoad=?"传给服务器。

什么是jQuery

Jquery是继prototype之后又一个优秀的Javascrīpt框架。它是轻量级的js库(压缩后只有21k) ,它兼容CSS3,还兼容各种浏览器 (IE 6.0+, FF 1.5+, Safari 2.0+, Opera 9.0+)。jQuery使用户能更方便地处理HTML documents、events、实现动画效果,并且方便地为网站提供AJAX交互。jQuery还有一个比较大的优势是,它的文档说明很全,而且各种应用也说得很详细,同时还有许多成熟的插件可供选择。jQuery能够使用户的html页保持代码和html内容分离,也就是说,不用再在html里面插入一堆js来调用命令了,只需定义id即可。

白盒测试和黑盒测试

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

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

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

第七层:应用层 

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

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

第六层:表示层

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

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

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

第五层:会话层

    管理用户会话和对话;

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

    报告上一层发生的错误

第四层:传输层

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

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

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

第三层:网络层

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

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

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

第二层:数据链路层 

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

    封装数据包为数据帧; 

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

第一层:物理层 

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

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

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

ASP.NET身份验证

Windows 身份验证提供程序:

       提供有关如何将 Windows 身份验证与 Microsoft Internet 信息服务 (IIS) 身份验证结合使用来确保 ASP.NET 应用程序安全的信息。

Forms 身份验证提供程序 :

       提供有关如何使用您自己的代码创建应用程序特定的登录窗体并执行身份验证的信息。使用 Forms 身份验证的一种简便方法是使用 ASP.NET 成员资格和 ASP.NET 登录控件,它们一起提供了一种只需少量或无需代码就可以收集、验证和管理用户凭据的方法。

Passport 身份验证提供程序 :

       提供有关由 Microsoft 提供的集中身份验证服务的信息,该服务为成员站点提供单一登录和核心配置

ASP.NET MVC 身份验证

使用MVC中的action拦截器(重写OnActionExecuting),在action执行之前会先运行拦截器中的代码。在这里可以进行身份验证。

.net的错误处理机制是什么?

答:.net错误处理机制采用try->catch->finally结构,发生错误时,层层上抛,直到找到匹配的Catch为止。

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

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

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

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

4、有利于标准化;

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

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

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

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

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

视图与表的区别

       视图是张“虚拟表”不占用物理空间,表中存储的是数据而视图中存储是SQL查询。是由SELECT语句组成的查询定义的虚拟表

       视图的优点:      

              1.视图具有安全性,视图中的数据不能影响基表中的数据。

              2.视图可以屏蔽一些细节。

              3.视图可以简化用户SQL命令。

Linq           

LINQ(Language  INtegrated  Query,语言级集成查询)是Visual  Studio  2008 、Net framework 3.5中新添加的一种集成查询语言,支持泛型集合的各种操作。结合Lambda表达式,更能够方便对数据进行各种操作。

Linq主要包括LinqToObject、LinqToXML、LinqToSQL(EF)几个方向。可操作的对象主要包括xml、集合、sql server数据库等。

LinqToSQL的底层是生成的T-SQL语句。

优点:查询语法融入了C#语法中,把复杂的查询进行了封装,封装后语法变得更加清晰易懂,可读性较高,可查询的数据源扩展,提高了开发效率、提高了代码优化空间,便于代码维护和调试。缺点:数据的事实更新、内存中保存了大量的数据模型

LINQ查询关键字

答:在使用LINQ查询数据源时经常用到的关键字有

from ,select,where,order by、group by,join,into

Json                         

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于JavaScript的一个子集.他以键值对的关系存在于josn字符串中。

序列化、反序列化             

    将对象转换为另一种媒介格式传输的过程 如 序列化一个对象在两者之间传递该对象,在另一端用反序列化从该流中重新得到对象。

设计模式             

    设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。

    在项目中,我使用过的或了解的设计模式有:

单例模式Singleton:

    主要目的是确保某个类,只有一份实例,而且存在一个全局的访问点来访问这个实例对象。

    对象应在实际使用时,才被创建。单例模式中,负责实施这种约束的是类自身,而不是类的客户。

           具体实现:

           1、让构造函数成为私有,同时添加一个私有的静态构造函数。

           2、添加一个私有的静态只读对象,这个对象通过私有的构造函数在类的内部实例化。

       3、添加一个访问此私有对象的公有静态属性。

    public class Singleton

    {

        static readonly Singleton instance = new Singleton();

        static Singleton()

        {

        }

        public static Singleton Instance

        {

            get

            {

                return instance;

            }

        }

    }

观察者模式Observer:

       定义了对象之间的一种联系,使得当一个对象改变状态时,所有其它对象都可以相应地被通知到。

       具体实现与应用:

       该模式可以理解为新闻订阅,当新闻发布后,通知订阅者的一种机制。

工厂模式Factory Method

           一种创建对象的方法,在使用该类时,由需求决定具体实例化那个类。

    案例:

设一种水果,一年四季在商店销售时,为保证一年四季可以销售,需要从不同的产地采购。在这里,商店就可以看作一个工厂类。

依赖注入

依赖注入又称控制反转IoC,或依赖倒置,是一种全新的设计模式,但出现相对较晚,并没有包含在GoF24种设计模式中。

具体的规则就是:

    高层的模块不应该依赖低层的模块,二者都应该依赖于抽象。

    抽象不应该依赖于细节,细节应该依赖于抽象。

主要的注入方式有:

    1、构造注入2、属性注入方式3、参数注入

我们在平时开发时,基本都是使用第三方的类库,比如:NInject,Autofactory,Spring.Net。

 

依赖注入的三种方式:

set注入,最常用的,需要在对应的类中声明一个本类的对象,然后添加set方法。通过Spring的配置bean来实例化它。 

还有构造器注入,需要添加构造器,默认的是无参的,可以重载构造器,然后在配置文件中配置好constructer标签。注意参数的顺序。 

再就是接口注入,ref引用其他配置好的bean。

 

接口注入: 接口注入模式因为历史较为悠久,在很多容器中都已经得到应用。但由于其在灵活性、易用性上不如其他两种注入模式,因而在 IOC 的专题世界内并不被看好。

 Setter(属性) 注入: 对于习惯了传统 javabean 开发的程序员,通过 setter 方法设定依赖关系更加直观。 如果依赖关系较为复杂,那么构造子注入模式的构造函数也会相当庞大,而此时设值注入模式则更为简洁。 如果用到了第三方类库,可能要求我们的组件提供一个默认的构造函数,此时构造子注入模式也不适用。

 构造注入: 在构造期间完成一个完整的、合法的对象。 所有依赖关系在构造函数中集中呈现。 依赖关系在构造时由容器一次性设定,组件被创建之后一直处于相对“不变”的稳定状态。 只有组件的创建者关心其内部依赖关系,对调用者而言,该依赖关系处于“黑盒”之中。

抽象工厂模式和工厂模式的区别?

    工厂方法模式:一个抽象产品类,可以派生出多个具体产品类。

    一个抽象工厂类,可以派生出多个具体工厂类。

    每个具体工厂类只能创建一个具体产品类的实例。

    抽象工厂模式:多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。

    一个抽象工厂类,可以派生出多个具体工厂类。

    每个具体工厂类可以创建多个具体产品类的实例。

    主要区别:工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。

    工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。

软件工程的最终目的

    a.付出较低的开发成本;

    b.达到要求的软件功能;

    c.取得较好的软件性能;

    d.开发的软件易于移植;

    e.需要较低的维护费用;

    f.能按时完成开发工作,及时交付使用。

如何部署一个ASP.net页面?

    VS里边都有发布机制,vs2013可以发布然后,自行复制部署,也可以借助发布向导直接部署到相应位置。

linq to xml

    Linq to Xml是一种结合了Linq语法及操作方法的Xml编程接口,使用它可以在.NET Framework编程语言中轻松处理Xml资料。

Collection 和 Collections的区别。

    Collection是集合类的上级接口,继承与他的接口主要有Set 和List.

    Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。

什么时候用assert。 ?

    Assert用于检查不应该发生情况,用来帮助开发人员对问题的快速定位。异常处理用于对程序发生异常情况的处理,增强程序的健壮性、容错性,减少程序使用中对用户不有好的行为,屏蔽一些与用户无关的错误信息。

    Debug.Assert(container==null, "container argument is null");

    另一个Assert类,使用 UnitTestingFramework 命名空间的 Assert 类可对特定功能进行断言。

数组有没有length()这个方法? String有没有length()这个方法?

    数组没有length()方法,但有length的属性。

    String有length()方法。

是否可以继承String类?

String类是final类,故不可以继承。

.NET中的值类型和引用类型

.net中的数据类型是程序员需要认真掌握的基础知识。.NET 中类型的两个基本类别是“值类型”和“引用类型”。基元类型、枚举和结构为值类型。类、字符串、标准模块、接口、数组和委托为引用类型。

    所有的类型要么是值类型,要么是引用类型,但有一种情况例外。根类型 System.Object ,它非常特殊,因为它既不是引用类型也不是值类型,而且不能实例化。因此,类型 Object 的变量可包含值类型或引用类型。

    值类型:

    C#的所有值类型均隐式派生自System.ValueType,每种值类型均有一个隐式的默认构造函数来初始化该类型的默认值。

主要有以下几种(CLR2.0之后类型有所增加):

    * bool

    * byte

    * char

    * decimal

    * double

    * enum

    * float

    * int

    * long

    * sbyte

    * short

    * struct

    * uint

    * ulong

    * ushort

    Var

引用类型:

 

引用类型,继承自System.Object:

    指针:

    在内存区中,指向一个类型的引用,通常被称为“指针”,它是受CLR( Common Language Runtime:公共语言运行时)管理,我们不能显示使用。需要注意的是,一个类型的引用即指针跟引用类型是两个完全不同的概念。指针在内存中占一块

        数组(派生于System.Array)

        用户用定义的以下类型:

            类:class(派生于System.Object);

            接口:interface(接口不是一个“东西”,所以不存在派生于何处的问题。Anders在《C# Programming Language》中说,接口只是表示一种约定[contract]);

            委托:delegate(派生于System.Delegate)。

        object(System.Object的别名);

        字符串:string(System.String的别名)。

    dynamic  

    可以看出:

        引用类型与值类型相同的是,结构体也可以实现接口;

        引用类型可以派生出新的类型,而值类型不能;

        引用类型可以包含null值,值类型不能(可空类型功能允许将 null 赋给值类型);

        引用类型变量的赋值只复制对对象的引用,而不复制对象本身。而将一个值类型变量赋给另一个值类型变量时,将复制包含的值。

Swtich可以接收的数据类型有?

Switch 表达式支持的类型为 sbyte、byte、short、ushort、int、uint、long、ulong、char、string 或枚举类型,或者可以隐试转换到这些类型的自定义对象或其他内置类型。

UML中哪些图表示系统行为? (多选)

A、状态图 B、用例图 C、协作图 D、类图 E、活动图 F、时序图

考点:UML (ACEF)

ASP.NET有几种存储会话状态的方式

会话状态的存储方式有3种,分别是

    InProc

    StateServer

SqlSevrer.   

  在ASP.NET中,最常用的是InProc模式,这也是默认方式。

Inproc特点:具有最佳的性能,速递最快,但不能跨多台服务器存储共享。

缺点是这种模式下,Session值会有丢失问题。

StateServer特点:适合于需要跨服务器维护用户会话信息的情况,由于信息存储在状态服务器上,一旦状态服务器出现故障,信息将会丢失。

SqlServer特点:可跨服务器维护用户会话信息,且信息不回丢失,但工作负载较大。

什么是Silverlight

  Silverlight是一个垮浏览器、跨客户平台的技术,能够设计、开发和发布有多媒体体验与富交互(Rich InterFace Application,RIA)的网络交互程序。因为Silverlight提供了一个强大的平台,能够开发出具有专业图形,音频和视频的Web应用程序,增强了用户体验,所以Silverlight吸引了设计人员和开发人员的眼球。同时,Silverlight还提供了插件来提高ASP.NET的开发效率。

静态方法与非静态方法的区别

静态变量使用 static修饰符进行声明,类无需实例化,可以直接通过类名使用。

不带有 static 修饰符声明的变量称做非静态变量,在对象被实例化时创建,通过对象名进行使用。

一个类的所有实例的同一静态变量都是同一个值,同一个类的不同实例的同一非静态变量可以是不同的值

静态函数的实现里不能使用非静态成员,如非静态变量、非静态函数等

谈谈final, finally, finalize的区别。

Final 修饰符来限定变量、字段、方法和类。

1)当用于变量时,该变量只能赋值一次,不可修改;

2)用于方法时,该方法不能被重写或隐藏;

    3)当用于类时,该类不能被继承。

    4)在接口中,其成员不能使用该关键字,同样abstract类中,其成员也不能使用final。

Finally 异常处理机制中,提供 finally 块来执行任何清除操作。如果抛出一个异常,那么相匹配的 catch 子句就会执行,然后控制就会进入 finally 块(如果有的话)。

Finalize 是一个方法名,主要功能将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。C#中,不能直接实现Finalize方法,而是在析构函数Dispose()中调用基类的Finalize()方法,由系统调用完成资源释放。

Final 修饰符 与 sealed 修饰符对比

sealed 修饰符可以应用于类、实例方法和属性。用于类时,该类被称为密封类,密封类不能被继承;用于方法时,该方法被称为密封方法,密封方法会重写基类中的方法;sealed修饰符应用于方法或属性时,必须始终与override一起使用;结构是隐式密封的,因此它们不能被继承。

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

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

c#中用什么工具进行单元测试和模块测试的?

答:Nunit

写出软件的开发流程

1.需求分析:主要了解客户想要的是什么样的一个系统,要有哪些功能等。

2.问题定义:主要是要搞清楚,我们要解决什么样的问题

3.可行性分析:我们要明确所定义的项目是不是能够实现和值得开发,也就是在技术,经济,运行可行性,法律可行性方面进行分析。

4.概要设计与结构化设计,这个阶段主要是要分析出,我们要怎样实现系统,软件设计包括概要设计时应该遵循的基本原理。

5.详细设计,确定具体怎么样实现所要求的系统

6.编码与软件测试:

7.软件测试与维护。

软件开发流程(软件生命周期)

a)需求分析                               

b)概要设计  详细设计                    

c)编码                                                    

d)设计          

e)维护

列举ADO.NET当中的类,知道多少写多少,并且画出它们之间的关系,或写出代码/伪码

Command         connection

           |___________|

           |

        Adapter

           |

        DataSet

           |

       DataTable

_________|___________________________________

|                |         |              |

DataColumn    DataRow    DataView     Relation

列举ADO.NET中的共享类和数据库特定类

共享类

DataSet

DataTable

DataRow

DataColumn

特定类

(x)Connection

(x)Command

(x)CommandBuilder

(x)DataAdapter

(x)DataReader

(x)Parameter

(x)Transaction

Ado.Net中连接池的作用和原理?

答:当net打开连接后,使用完毕,虽然调用close但是并没有销毁,而是闲置等待被重用,这就是连接池的作用,连接池能减少连接对象的创建和释放的开销,使得频繁操作数据库的开销降低。

连接池能够减少新连接需要打开的次数。池进程保持物理连接的所有权。通过为每个给定的连接配置保留一组活动连接来管理连接。只要用户在连接上调用 Open,池进程就会检查池中是否有可用的连接。如果某个池连接可用,会将该连接返回给调用者,而不是打开新连接。应用程序在该连接上调用 Close 时,池进程会将连接返回到活动连接池集中,而不是真正关闭连接。连接返回到池中之后,即可在下一个 Open 调用中重复使用。

只有配置相同的连接可以建立池连接。ADO.NET 同时保留多个池,每个配置一个池。连接由连接字符串以及 Windows 标识(在使用集成的安全性时)分为多个池。

池连接可以大大提高应用程序的性能和可缩放性。默认情况下,ADO.NET 中启用连接池。除非显式禁用,否则,连接在应用程序中打开和关闭时,池进程将对连接进行优化。

Server=(local); Integrated Security=SSPI; Database=Northwind;   Max Pool Size=75; Min Pool Size=5

优点:当数据库操作和访问频繁的时候,减少创建连接和打开连接所耗的时间,提升数据库服务器的性能。

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

什么是MVC设计模式

MVC(Model-View-Controller)把交互系统的主要组成部分,分解成三部分,分别是模型Model、视图View、控制器Controller三种部件,三个部分各司其职,协同完成任务处理工作。...讲讲三部分各自的职责。

mvc设计模式的优点:

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

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

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

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

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

MVC的不足:

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

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

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

MVC路由系统的主要功能

       主要有两个功能:

       1.检查一个输入请求,并决定调用那个控制器和动作

       2.生成输出URL,用户点击这些连接时调用特定的动作方法。

路由的相关定义在System.Web.Routing命名空间中。

构造器Constructor是否可以被继承?是否可以被Override?

答:Constructor不可以被继承,因此不能被重写(Overriding),但可以被重载(Overloading).

sleep() 和 wait() 有什么区别?

  sleep()方法是使线程停止一段时间的方法。在sleep 时间间隔期满后,线程不一定立即恢复执行。这是因为在那个时刻,其它线程可能正在运行而且没有被调度为放弃执行,除非(a)“醒来”的线程具有更高的优先级 (b)正在运行的线程因为其它原因而阻塞。

    wait()是线程交互时,如果线程对一个同步对象x 发出一个wait()调用,该线程会暂停执行,被调对象进入等待状态,直到被唤醒或等待时间到。

数据库

什么是触发器?

    答:触发器是一种特殊类型的存储过程,出发器主要通过事件触发而被执行的,

    触发器的优点:

    1.强化约束,触发器能够提供比CHECK约束;

  2.跟踪变化,触发器可以跟踪数据库内的操作,从而不允许未经允许许可的更新和变化;

  3.联级运算,比如某个表上的触发器中包含对另一个表的数据操作,而该操作又导致该表上的触发器被触发

触发器,优点是什么:

触发器在被添加后,会自动触发并工作。它们在对表的数据作了任何修改之后,都会被立即被激活。

触发器可以用于,在数据操作结束后,进行一些事后的数据处理。比如,删除一条数据时,需要将相关表中的数据也同步清空。

触发器也可用于强制限制,这些限制比用 CHECK 约束所定义的可以更加复杂。与 CHECK 约束不同的是,触发器可以引用其它表中的列。例如,触发器可以回滚视图对价格低于 10 美元的书(存储在 titles 表中)应用折扣(存储在 discounts 表中)的更新。

触发器中的临时表:

SqlServer触发器中的临时表

inserted 表

    临时保存了插入或更新后的记录行

deleted 表

    临时保存了删除或更新前的记录行

Oracle获取原数据的:new 对象与旧数据的:old对象为:

:new是新插入的数据,:old是原来的数据

insert只会有new,代表着要插入的新记录

delete只会有old,代表着要删除的记录

update由于执行的是先删除旧的记录,再插入新的记录,因此new和old都会有,且含义与上面的相同

注:update触发器,可根据具体需求选择记录旧记录还是新记录。

 

使用格式:

:new.字段名 或 :old.字段名

if :new.num!=:old.num then

      :new.num:=:old.num;

end if;

触发器删除数据示例

CREATE TRIGGER A表_DEL

            ON A表FOR DELETE

AS

    DELETE E

          FROM A表 E

               INNER JOIN deleted D ON E.主键ID = D.主键ID

左链接   右连接

Left  join左连接是查询JOIN左边的表中的所有记录(包括右边表中与其没有相匹配的记录)

Right join右连接是查询JOIN左边的表中的所有记录(包括左边表中与其没有相匹配的记录)

Inner join内连接是查询JOIN左边的表中的所有记录(左、右表中必须匹配的记录)

全连接是查询JOIN左边的表中的所有记录(包括右边表中与其没有相匹配的记录,以及左边表中与其没有相匹配的记录)

select * from A left join B on A.id=B.id             左链接

select * from A right join B on A.id=B.id           右连接

--两表连接

SELECT  S.NAME,T.NAME FROM STUDENT AS S INNER JOIN TEACHER AS T ON S. CNO = T. CNO ORDER BY  SNAME

--三表连接

select a.*,c.f from (select * from a inner join b on a.a = b.a) as a inner join c on a.d = c.d

SQL truncate 、delete与drop区别

    truncate 和 delete 只删除数据不删除表的结构(定义)

    drop 语句将删除表的结构被依赖的约束(constrain)、触发器(trigger)、索引(index);依赖于该表的存储过程/函数将保留,但是变为 invalid 状态。

    delete 语句是数据库操作语言(dml),这个操作会放到 rollback segement 中,事务提交之后才生效;

    truncate、drop 是数据库定义语言(ddl),操作立即生效,原数据不放到 rollback segment 中,不能回滚,操作不触发 trigger。

    delete 语句不释放所占用的存储空间

    drop 语句将表所占用的空间全部释放。

速度,一般来说: drop > truncate > delete

DDL和DML分别代表什么?

DDL表示数据定义语言,主要包括CREATE,ALTER,DROP,...等;

DML表示数据操作语言,主要有SELECT,INSERT,UPDATE,DELETE等.

维护数据库的完整性、一致性、你喜欢用触发器还是自写业务逻辑?为什么?

答:尽可能用约束(包括CHECK、主键、唯一键、外键、非空字段)实现,这种方式的效率最好;其次用触发器,这种方式可以保证无论何种业务系统访问数据库都能维持数据库的完整性、一致性;最后再考虑用自写业务逻辑实现,但这种方式效率最低、编程最复杂,当为下下之策。

游标是什么

    游标对查询出来的结果集作为一个单元来有效的处理,游标可以定位在结果集的特定行、从结果集的当前位置检索一行或多行、可以对结果集中当前位置的数据进行修改。

    游标是系统为用户开设的一个数据缓冲区,存放SQL语句的执行结果,每个游标区都有一个名字,可以用fetch 语句逐一从游标中获取记录,并赋给变量,对游标中的数据进行依次读取处理。

    显然,使用游标可以对数据集进行循环处理,在一些特定的情况下,是非常有作用的,但是游标存在效率问题,特别是存储数据量比较大时;

在具体应用中,如果数据表中有几十万或者更大量的数据时,游标的效率是要考虑的。

因为游标相当于在这么大的表中不停地查找,直到你想要的结果,实际上与你一个特征一个特征地取数据是一样的,只是那样子你也穷举无数种可能,而游标在这种情况下会按一种你定义的规则自动进行。

例:

declare @id nvarchar(20)  --定义变量来保存ID号

declare @A float                  --定义变量来保存值

declare mycursor cursor for select * from tb_c   --为所获得的数据集指定游标

open mycursor                   --打开游标

fetch next from mycursor  into @id,@A   --开始抓第一条数据

while(@@fetch_status=0)     --如果数据集里一直有数据

begin

 select tb_b.name,(tb_b.gz + @A) from tb_b where tb_b.id = @id   --开始做想做的事(什么更新呀,删除呀)

        fetch next from mycursor into @id,@A     --跳到下一条数据

end

close mycursor        --关闭游标

deallocate mycursor  --删除游标

Sql查询题

Sql查询时的case关键词使用

在成绩表中,效率60分为不及格,大于60分为及格,大于80分为优秀,请用一条SQL语句查询。

答:设有成绩表Scores  包含字段ScoreId  Score

查询语句如下:

Select 成绩=case

    When  score  between(0 and 59) then ‘不及格’

    When  score  between(60 and 79)  then ‘及格’

    When   score between(80 and 100) then ‘优秀’

    Else ‘无效成绩’

    End

From Score

请用SQL语句查处当天所有记录.

答: select * from tb_send where datediff(day,sendTime, getdate())=0

sql查询,表table(id,lastUpdateDate);使用一条sql语句查出最近一次的修改时间

答:select top 1 lastUpdateDate from [table] order by lastUpdateDate desc

游标的声明与使用,如何判断记录已到达最末尾

declare @myCur Cursor

declare mySet Cursor for

select * from 表名

set @muCur=mySet

open mySet

fetch next from mySet

while @@FETCH_STATUS=0

begin

fetch next from mySet

end

close mySet

deallocate mySet

性能优化

程序访问数据库记录速度很慢,分析什么原因造成以及解决办法。

答案:

原因很多种,其可能的典型如下:

查询语句本身造成的。优化语句

表结构问题。增加索引

网络环境造成。优化网络

系统瓶颈。优化系统

硬件造成的。升级硬件

索引的概念

索引就是加快查询表中数据的方法。

数据库的索引类似于书籍的索引。

在书籍中,索引允许用户不必翻阅完整个书就能迅速地找到所需要的信息。

在数据库中,索引也允许数据库程序迅速地找到表中的数据,而不必扫描整个数据库.

索引的特点

1.索引可以加快数据库的检索速度

2.索引降低了数据库插入、修改、删除等维护任务的速度,因为数据变化后,需要同步维护索引。

3.索引只能创建在表上,不能创建在视图上

索引的优点

1.创建唯一性索引,保证数据库表中每一行数据的唯一性

2.大大加快数据的检索速度,这也是创建索引的最主要的原因

3.减少磁盘IO

索引的缺点

  1.创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加

  2.索引需要占物理空间,除了数据表占数据空间之外,索引还要占一定的物理空间

  3.当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,降低了数据的维护速度

微软的SQL SERVER提供了两种索引:

聚集索引(clustered index)

非聚集索引(nonclustered index)

聚集索引中键值的逻辑顺序决定了表中相应行的物理存储顺序。

适用场合:

  含有大量非重复值的列

  会使用BETWEEN,>,>=,<或<=返回一个范围值的列

  会被连续访问的列

  返回大型结果集的查询

  经常被使用连接或GROUP BY子句的查询访问的列

如果用 新华字典 作例子来一个例子的话。

  [拼音]就可以看作是聚集索引

    例如 吖、阿、啊 在字典的最前面。

    左、作、坐 在字典的最后面。

    拼音[逻辑顺序]很接近,在字典中页数的位置[物理顺序]也很接近。

而非聚集索引是不将表和视图中的数据进行物理排序。

  非聚集索引与聚集索引一样有 B 树结构,但是有两个重大差别:

  数据行不按非聚集索引键的顺序排序和存储。

  非聚集索引的叶层不包含数据页。

  相反,叶节点包含索引行。每个索引行包含非聚集键值以及一个或多个行定位器,

  这些行定位器指向有该键值的数据行(如果索引不唯一,则可能是多行)。

适用场合:

  含有大量非重复值的列

  非连续访问的列

  返回小型结果集的查询

如果用 新华字典 作例子来一个例子的话。

  [笔画]就可以看作是非聚集索引

    例如 化 仇 仃 仅 仂 这几个字,都是 单人旁,笔画数相同的。

    笔画[逻辑顺序]很接近,在字典中页数的位置[物理顺序]则在不同的位置上。

SqlServer中支持在表和视图上,添加索引。

一个表或视图中最多可以有250个非聚集索引 或 有249个非聚集索引 + 一个聚集索引。

如何处理几百万条并发数据?

答:具体处理可以有很多方案,

比如使用存储过程+事务,保证数据植入的速度,及原子性问题。在植入标识时,注意主键是不是自增量方式这种方法,并发的时候是不会有重复主键的问题,如果没有使用自增量方式,生成标识的工作最好使用存储过程来完成.

还可以使用以下技术来优化,那块好,可以扩展谈一下,不好算了

使用队列机

使用事务,保持原子性。

引入锁机制。

可以控制连接池的连接数量,

负载均衡

如果有100万条记录,请问你如何优化表结构查询提高速度?

一.水平分割

根据一列或多列数据的值把数据行放到两个独立的表中。即按记录进分分割,不同的记录可以分开保存,每个子表的列数相同。

水平分区将表分为多个表。每个表包含的列数相同,但是行更少。例如,可以将一个包含十亿行的表水平分区成 12 个表,每个小表表示特定年份内一个月的数据。任何需要特定月份数据的查询只需引用相应月份的表。

水平分割通常在下面的情况下使用:

(1)    表很大,分割后可以降低在查询时需要读的数据和索引的页数,同时也降低了索引的层数,提高查询速度。

(2)    表中的数据本来就有独立性,例如表中分别记录各个地区的数据或不同时期的数据,特别是有些数据常用,而另外一些数据不常用。

(3)    需要把数据存放到多个介质上。

水平分割会给应用增加复杂度,它通常在查询时需要多个表名,查询所有数据需要union操作。在许多数据库应用中,这种复杂性会超过它带来的优点,因为只要索引关键字不大,则在索引用于查询时,表中增加两到三倍数据量,查询时也就增加读一个索引层的磁盘次数。

二.垂直分割

垂直分割表(不破坏第三范式),把主码和一些列放到一个表,然后把主码和另外的列放到另一个表中。将原始表分成多个只包含较少列的表。如果一个表中某些列常用,而另外一些列不常用,则可以采用垂直分割,另外垂直分割可以使得数据行变小,一个数据页就能存放更多的数据,在查询时就会减少I/O次数(每次查询时读取的block 就少)。其缺点是需要管理冗余列,查询所有数据需要join操作。

垂直分割表可以达到最大化利用Cache的目的。

其它优化手段:

1.合理的使用索引(例如在频繁作为条件的列,经常作为排序或分组的列)

2.只查询必要的列,避免 *

3.按已建立索引的列进行数据查询

4.避免或简化排序,并避免按非索引列排序输出

5.使用存储过程,减少服务器通讯次数,尽量多个处理一次提交。

存储过程:

存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中。用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象。

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

优点:

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

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

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

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

缺点:

1.交互性差 。

2.可移植性差

什么是存储过程?有什么优点?

答:存储过程是一组予编译的SQL语句

    它的优点:

    1.允许模块化程序设计,就是说只需要创建一次过程,以后在程序中就可以调用该过程任意次。

    2.允许更快执行,如果某操作需要执行大量SQL语句或重复执行,存储过程比SQL语句执行的要快。

    3.减少网络流量,例如一个需要数百行的SQL代码的操作有一条执行语句完成,不需要在网络中发送数百行代码。

  4.更好的安全机制,对于没有权限执行存储过程的用户,也可授权他们执行存储过程。

事务:

事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。事务是恢复和并发控制的基本单位。

事务应满足:原子性、一致性、隔离性、持续性等要求。这四个要求通常称为ACID特性。

原子性(atomicity)。一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。

一致性(consistency)。事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。

隔离性(isolation)。一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。

持久性(durability)。持续性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。

事务是指一个工作单元,它包含了一组数据操作命令,并且所有的命令作为一个整体一起向系统提交或撤消请求操作,即这组命令要么都执行,要么都不执行。

在应用中,使用事务的手段:

1.      在数据库t-sql编程中,如存储过程:

begin transaction

commit transaction

rollback transaction

begin transaction

--修改数据

--判断修改数据是否出现异常

      if @@ERROR<>0

        begin

          rollback transaction

        end

      else

        begin

          commit transaction

2.            End

3.      在ado.net中

SqlTransaction trans = conn.BeginTransaction();//开启conn连接的事务处理

trans.Commit();  事务提交

trans.Rollback();//对于conn连接的数据库操作都会被回滚

         SqlConnection conn = Database.GetConn();

         SqlTransaction st = conn.BeginTransaction();

         try

         {

           

             string sql = "Insert Into T_Test(F_Name) values('A')";           

             Database.ExecuteNonQuery(st, CommandType.Text, sql);

 

            //这里会报错,在挂起的事务中,该事务分配的连接,不能再独占使用

             //string A = Database.ExecuteScalarToStr(conn,CommandType.Text,"Select F_ID From T_Test where F_Name='A'");

            

             sql = "Insert Into T_Test2(F_ID,F_Age) values(1,2)";

             Database.ExecuteNonQuery(st, CommandType.Text, sql);

             st.Commit();          

          

         }

         catch (Exception Ex)

         {

             st.Rollback();

             Website.WriteError(Ex);

         }

         finally

         {

             Database.Dispose(conn);

4.               }

5.      在EF中

使用db.BeginTransaction()开始一个事务

使用db.Commit()提交一个事务

使用db.Rollback()回滚一个事务。

如何优化数据库?

       *(1、表优化(数据类型,定长,尽量不用Identity、定长的字段尽量放在前面)

        (2、查询优化({不能用select*、having、去掉重复项、IS NULL"、 ""、"!="、"!", "!", "NOT", "NOT EXISTS", "NOT IN", "NOT LIKE", and "LIKE '%500'})

       *(3、用存储过程

       *(4、索引(更新速度慢,查询速度快)

        (5、视图、临时表(少用)

       *(6、不用游标

       *(7、横向、纵向分割表

       *(8、数据库读写分离(数据同步,sql中有订阅与发布功能)

       * (9、分布式

        (10、分页

        (11、锁

数据库查询优化,请给出以下问题的解决方案

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

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

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

什么是锁

锁是实现数据库并 发控制的一个非常重要的技术。在并发执行时,会出现资源的竞争问题。所以可以使用锁,锁定相关资源。锁一般可分为排它锁、共享锁。

什么是死锁,如何避免死锁?

死锁的四个必要条件

在计算机专业的本科教材中,通常都会介绍死锁的四个必要条件。这四个条件缺一不可,或者说只要破坏了其中任何一个条件,死锁就不可能发生。我们来复习一下,这四个条件是:

互斥(Mutual exclusion):存在这样一种资源,它在某个时刻只能被分配给一个执行绪(也称为线程)使用;

持有(Hold and wait):当请求的资源已被占用从而导致执行绪阻塞时,资源占用者不但无需释放该资源,而且还可以继续请求更多资源;

不可剥夺(No preemption):执行绪获得到的互斥资源不可被强行剥夺,换句话说,只有资源占用者自己才能释放资源;

环形等待(Circular wait):若干执行绪以不同的次序获取互斥资源,从而形成环形等待的局面,想象在由多个执行绪组成的环形链中,每个执行绪都在等待下一个执行绪释放它持有的资源。

解决方法:

1 使用事务时,尽量缩短事务的逻辑处理过程,及早提交或回滚事务; (细化处理逻辑,执行一段逻辑后便回滚或者提交,然后再执行其它逻辑,直到事物执行完毕提交)

2 设置死锁超时参数为合理范围,如:3分钟-10分种;超过时间,自动放弃本次操作,避免进程悬挂;

3 优化程序,检查并避免死锁现象出现;

4 .对所有的脚本和SP都要仔细测试,在正是版本之前。

5 所有的SP都要有错误处理(通过@error)

6 一般不要修改SQL SERVER事务的默认级别。不推荐强行加锁另外参考的解决方法:

按同一顺序访问对象

    如果所有并发事务按同一顺序访问对象,则发生死锁的可能性会降低。例如,如果两个并发事务获得 Supplier 表上的锁,然后获得 Part 表上的锁,则在其中一个事务完成之前,另一个事务被阻塞在 Supplier 表上。第一个事务提交或回滚后,第二个事务继续进行。不发生死锁。将存储过程用于所有的数据修改可以标准化访问对象的顺序。

   

    避免事务中的用户交互

    避免编写包含用户交互的事务,因为运行没有用户交互的批处理的速度要远远快于用户手动响应查询的速度,例如答复应用程序请求参数的提示。例如,如果事务正在等待用户输入,而用户去吃午餐了或者甚至回家过周末了,则用户将此事务挂起使之不能完成。这样将降低系统的吞吐量,因为事务持有的任何锁只有在事务提交或回滚时才会释放。即使不出现死锁的情况,访问同一资源的其它事务也会被阻塞,等待该事务完成。

   

    保持事务简短并在一个批处理中

    在同一数据库中并发执行多个需要长时间运行的事务时通常发生死锁。事务运行时间越长,其持有排它锁或更新锁的时间也就越长,从而堵塞了其它活动并可能导致死锁。保持事务在一个批处理中,可以最小化事务的网络通信往返量,减少完成事务可能的延迟并释放锁。

   

    使用低隔离级别

    确定事务是否能在更低的隔离级别上运行。执行提交读允许事务读取另一个事务已读取(未修改)的数据,而不必等待第一个事务完成。使用较低的隔离级别(例如提交读)而不使用较高的隔离级别(例如可串行读)可以缩短持有共享锁的时间,从而降低了锁定争夺。

   

    使用绑定连接

    使用绑定连接使同一应用程序所打开的两个或多个连接可以相互合作。次级连接所获得的任何锁可以象由主连接获得的锁那样持有,反之亦然,因此不会相互阻塞。

死锁的必要条件?怎么克服?

答:系统的资源不足,进程的推进的顺序不合适,资源分配不当,一个资源每次只能被一个进程使用,一个

资源请求资源时,而此时这个资源已阻塞,对已获得资源不放,进程获得资源时,未使用完前,不能强行剥夺。

在查询和更新数据时,会涉及到那几种类型的锁。

答:

1.共享锁  用于只读操作(select),锁定共享的资源。共享锁不会阻止其他用户读,但是阻止其他的用户写和修改。

2.更新锁   更新锁是一种意图锁,当一个事务已经请求共享琐后并试图请求一个独占锁的时候发生更新琐。例如当两个事务在几行数据行上都使用了共享锁,并同时试图获取独占锁以执行更新操作时,就发生了死锁:都在等待对方释放共享锁而实现独占锁。更新锁的目的是只让一个事务获得更新锁,防止这种情况的发生。

3.独占锁  一次只能有一个独占锁用在一个资源上,并且阻止其他所有的锁包括共享缩。写是独占锁,可以有效的防止’脏读’。

4.意图缩  在使用共享锁和独占锁之前,使用意图锁。从表的层次上查看意图锁,以判断事务能否获得共享锁和独占锁,提高了系统的性能,不需从页或者行上检查。

计划锁   sch-m,sch-s。对数据库结构改变时用sch-m,对查询进行编译时用sch-s。这两种锁不会阻塞任何事务锁,包括独占锁。

什么是锁

锁是在多用户环境中对数据的访问的限制。SqlServer自动锁定特定记录、字段或文件,防止用户访问,以维护数据安全或防止并发数据操作问题,锁可以保证事务的完整性和并发性。

什么叫SQL注入?如何防止?请举例说明

答:SQL注入是常见的利用程序漏洞进行攻击的方法。导致sql注入攻击并非系统造成的,主要是程序中忽略了安全因素,利用sql语言漏洞获得合法身份登陆系统

例如:

"Select * from users where name='"+uName+"' and pwd='"+uPwd+"' "

如用户在t_name中输入tom’ or 1=‘1 就可以进入系统了。

生成语句:

Select * from users where name = ‘tom’ or 1=‘1’ and pwd=‘123’

怎样防止SQL注入?

 所谓SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令,比如先前的很多影视网站泄露VIP会员密码大多就是通过WEB表单递交查询字符暴出的,这类表单特别容易受到SQL注入式攻击.

防范方法:

1、使用Parameter提交数据

2、使用存储过程开发数据库应用

3、使用关键词过滤技术

4、检查用户输入的合法性

 

SQL Server语句执行顺序:

1、from子句组装来自不同数据源的数据;

2、where子句基于指定的条件对记录行进行筛选;

3、group by子句将数据划分为多个分组;

4、使用聚集函数进行计算;

5、使用having子句筛选分组;

6、计算所有的表达式;

7、使用order by对结果集进行排序。

 

举例说明:

在学生成绩表中 (暂记为 tb_Grade), 把 "考生姓名"内容不为空的记录按照 "考生姓名" 分组, 并且筛选分组结果, 选出 "总成绩" 大于 600 分的.

 

标准顺序的 SQL 语句为:

Select 考生姓名, max(总成绩) as max总成绩

from tb_Grade

where 考生姓名 is not null

group by 考生姓名

having max(总成绩) > 600

order by max总成绩

 

在上面的示例中 SQL 语句的执行顺序如下:

(1). 首先执行 from 子句, 从 tb_Grade 表组装数据源的数据

(2). 执行 where 子句, 筛选 tb_Grade 表中所有数据不为 NULL 的数据

(3). 执行 group by 子句, 把 tb_Grade 表按 "学生姓名" 列进行分组

(4). 计算 max() 聚集函数, 按 "总成绩" 求出总成绩中最大的一些数值

(5). 执行 having 子句, 筛选课程的总成绩大于 600 分的.

(7). 执行 ORDER BY 子句, 把最后的结果按 "Max 成绩" 进行排序.

From子句-->where子句-->group by子句-->max-->having子句-->order by子句

 

Sql语句优化:

1、 保证不查询多余的列与行。

    尽量避免select * 的存在,使用具体的列代替*,避免多余的列,字段的提取一定要按照“用多少提多少”的原则,避免使用“select *”这样的操作

例如,表T_表 里有10000条记录:

select top 10000 c1, c2, c3, c4 from T_表 order by c1 desc  --用时:4673毫秒

select top 10000 c1, c2, c3 from T_表 order by c1 desc --用时:1376毫秒

select top 10000 c1, c2 from T_表 order by c1 desc --用时:80毫秒

由此看来,我们每少提取一个字段,数据的提取速度就会有相应的提升。

 

 

!查看执行时间和cpu占用时间:

 set statistics time on

 select * from dbo.Product  --查询表的语句

 set statistics time off

执行后打开消息会看到如下信息:

 

 

 

2、字段名和表名要书写规范,注意大小写。

    这一点要多注意,如果大小写写错的话,虽然SQL仍然能正常执行,但数据库系统会花一定的开销和时间先要把您写的规范成正确的,然后再执行SQL。写对的话,这个时间就省了。

    正常的写法:select top 10 dteTransaction, txtSystem_id from tblTransactionSystem

    不小心的: select top 10 dtetransaction, txtsystem_id from tbltransactionsystem

3 别在where条件中做函数计算

 这样做的后果是将在每个行上进行运算,这将导致该列的索引失效而触发全表扫描。如下SQL:

select * from users where YEAR(dteCreated) < 2015

可以改成

select * from users where dteCreated <‘2015-01-01’

这样会使用针对dteCreated的索引,提高查询效率。

4、 少用In(not in)操作符与多使用exists(not exists)操作符

有时候会将一列和一系列值相比较。最简单的办法就是在where子句中使用子查询。在where子句中可以使用两种方式的子查询。如下:

第一种方式使用IN操作符:

select a.id from tblA a where a.id in (select b.id from tblB b)

第二种方式使用EXIST操作符:

select a.id from tblA a where exists (select 1 from tblB b where b.id = a.id)

用in写出来的SQL的优点是比较容易写及清晰易懂。但是用in的SQL性能总是比较低的,而第二种格式要远比第一种格式的效率高。从SQL执行的步骤来分析用in的SQL与不用in的SQL有以下区别:SQL试图将其转换成多个表的连接,如果转换不成功则先执行IN里面的子查询,再查询外层的表记录,如果转换成功则直接采用多个表的连接方式查询。由此可见用IN的SQL至少多了一个转换的过程。第二种格式中,子查询以’select 1’开始。运用EXISTS子句不管子查询从表中抽取什么数据它只查看where子句。这样优化器就不必遍历整个表而仅根据索引就可完成工作

5、is null 或 is not null操作(判断字段是否为空)

Is null 或 is not null 不能使用索引

任何在where子句中使用is null或is not null的语句优化器是不允许使用索引的.

推荐:用其它相同功能的操作运算代替,如a is not null 改为 a>0 或a>’等.

6、连接查询语句的优化

多表连接语句的优化注意点:

 A、多表连接的时候,连接条件必须写全,宁可重复,不要缺漏。

 B、连接条件尽量使用聚集索引

 C、注意ON、WHERE和HAVING部分条件的区别

 ON是最先执行, WHERE次之,HAVING最后,因为ON是先把不符合条件的记录过滤后才进行统计,它就可以减少中间运算要处理的数据,按理说应该速度是最快的,WHERE也应该比HAVING快点的,因为它过滤数据后才进行SUM,在两个表联接时才用ON的,所以在一个表的时候,就剩下WHERE跟HAVING比较了。  

 

考虑联接优先顺序:

 (1) INNER JOIN

 (2) LEFT JOIN (注:RIGHT JOIN 用 LEFT JOIN 替代)

 (3) CROSS JOIN

 

优化工具:

在sqlServer中,可以使用执行计划,或者用Profiler来监视和调优查询语句或者存储过程慢的原因。

其它注意和了解的地方有:

   A、在IN后面值的列表中,将出现最频繁的值放在最前面,出现得最少的放在最后面,减少判断的次数。

   B、注意UNION和UNION ALL的区别。-- 允许重复数据用UNION ALL好

   C、注意使用DISTINCT,在没有必要时不要用。

   D、TRUNCATE TABLE 与 DELETE 区别。

   E、减少访问数据库的次数。

   

 

编写存储过程时,一般可以加上下面这段,这样可以将方便的进行错误检查

BEGIN TRANSACTION

--事务回滚开始

--检查报错

IF ( @@ERROR0 )

 BEGIN

--回滚操作

ROLLBACK TRANSACTION

 RAISERROR('删除工作报告错误', 16, 3)

 RETURN

 END

--结束事务

COMMIT TRANSACTION

事务示例代码

BEGIN TRANSACTION DataDelete

    WITH MARK N'删除数据';

GO

insert into 商品档案表(ProductId, ProductName) values(5, '烟灰岗');

GO

DELETE FROM AdventureWorks2012.HumanResources.JobCandidate

    WHERE JobCandidateID = 13;

GO

COMMIT TRANSACTION DataDelete;

GO

Sql语句执行顺序:

查询的逻辑执行顺序

   (1) FROM left_table

  (3) join_type JOIN right_table (2) ON join_condition

  (4) WHERE where_condition

  (5) GROUP BY group_by_list

  (6) WITH {cube | rollup}

  (7) HAVING having_condition

  (8) SELECT (9) DISTINCT (11) top_specification select_list

  (9) ORDER BY order_by_list

标准的 SQL 的解析顺序为:

  (1) FROM 子句 组装来自不同数据源的数据

   (2) WHERE 子句 基于指定的条件对记录进行筛选

   (3) GROUP BY 子句 将数据划分为多个分组

   (4) 使用聚合函数进行计算

   (5) 使用HAVING子句筛选分组

   (6) 计算所有的表达式

   (7) 使用ORDER BY对结果集进行排序

执行顺序

   1. FROM:对FROM子句中前两个表执行笛卡尔积生成虚拟表vt1

  2. ON: 对vt1表应用ON筛选器只有满足 join_condition 为真的行才被插入vt2

  3. OUTER(join):如果指定了 OUTER JOIN保留表(preserved table)中未找到的行将行作为外部行添加到vt2,生成t3,如果from包含两个以上表,则对上一个联结生成的结果表和下一个表重复执行步骤和步骤直接结束。

   4. WHERE:对vt3应用 WHERE 筛选器只有使 where_condition 为true的行才被插入vt4

  5. GROUP BY:按GROUP BY子句中的列列表对vt4中的行分组生成vt5

  6. CUBE|ROLLUP:把超组(supergroups)插入vt6,生成vt6

  7. HAVING:对vt6应用HAVING筛选器只有使 having_condition 为true的组才插入vt7

  8. SELECT:处理select列表产生vt8

  9. DISTINCT:将重复的行从vt8中去除产生vt9

  10. ORDER BY:将vt9的行按order by子句中的列列表排序生成一个游标vc10

TOP:从vc10的开始处选择指定数量或比例的行生成vt11 并返回调用者

MVC路由配置

 

4.1

routes.MapRoute(

    "Default",

    "admin/{controller}/{action}/{id}", new { controller = "home", action = "Index", id = UrlParameter.Optional } );

 

4.2

routes.MapRoute(

    "d2", "{controller}/{action}/{id}",

    new { controller = "home", action = "Index", id = UrlParameter.Optional }

);

4.3

routes.MapRoute("d3", "{controller}/{action}/{id}",new { controller = "home", action = "Index", id = UrlParameter.Optional } ).DataTokens.Add("Area", "admin");

4.4

在index Action上添加过滤器,借助Stopwatch类,进行计时,分别在OnActionExecuting中,开始计时,在OnActionExecuted 中,结束计时,并计算时长,输出。

设置一个Area为默认起始页的办法:

两个作法:

1、修改路由,直接将外部路由,映射到 area路由上

 

2.不修改路由,直接在大mvc中的home/index

中,添加一条转向的指令,如:Response.Rediect("/lottorymanage/frame");

递归

程序调用自身的编程技巧称为递归(recursion)。一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。   

    注意:   

    (1) 递归就是在过程或函数里调用自身;   

    (2) (2) 在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。

最好有几个递归的例子

//使用递归,计算1到n总和

public int sum(int n)

{

     if(n>0)

     {

            return sum(n-1)+n;

     }

     else

     {

            return 0;

     }

}

1、阶乘,指从1乘以2乘以3乘以4一直乘到所要求的数。

例如所要求的数是6,则阶乘式是1×2×3×……×6,得到的积是720,720就是6的阶乘。例如所要求的数是n,则阶乘式是1×2×3×……×n,设得到的积是x,x就是n的阶乘。

任何大于1的自然数n阶乘表示方法:

n!=1×2×3×……×n  或  n!=n×(n-1)! 注:0!=1

1)请编写一个函数,能够计算10以内数的阶乘,尽量采用递归算法。(10!=3628800)。

10的阶乘

public static int  GetResult(int 10)

{

    if (n == 1)

        return 1;

    else

        return n * GetResult(n - 1);

}

//非递归版本

public int GetResult(int number)

{

    int F = 1;

    for (int i = 1; i <= number; i++)

    {

        F *= i;

    }

    return F;

}

//一列数的规则如下: 1、1、2、3、5、8、13、21、34...... 求第30位数是多少, 用递归算法实现。

public 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);   

}

编程题

编写一个程序 输入一个0-6的整数,转换成星期输出

实现一

int num = Convert.ToInt32(Console.ReadLine());

for (int i = 0; i < 7; i++)

{

    if (num == 0)

    {

        Console.WriteLine("星期日");

    }

    else if (i == num)

    {

        Console.WriteLine(string.Format("星期{0}", i));

    }

    else

    {

        Console.WriteLine("请输入一个0-6的整数");

    }

}

实现二

Console.Write("输入一个数:");

int shu=Convert.ToInt32(Console.ReadLine());

switch(shu)

{

   case 0:

     Console.WriteLine("星期天");

     break;

   case 1:

     Console.WriteLine("星期一");

     break;

   case 2:

     Console.WriteLine("星期二");

     break;

   case 3:

     Console.WriteLine("星期三");

     break;

   case 4:

     Console.WriteLine("星期四");

     break;

   case 5:

     Console.WriteLine("星期五");

     break;

   case 6:

     Console.WriteLine("星期六");

     break;

}

实现三:

        public enum Week

        {

            星期天,

            星期一,

            星期二,

            星期三,

            星期四,

            星期五,

            星期六

        }

        static void Main(string[] args)

        {

            string num = Console.ReadLine();

            Week week = (Week)(Enum.Parse(typeof(Week), num));

            Console.WriteLine(week);

            Console.ReadKey();

        }

使用Js生成长度100的数组,随机插入1-100间的值,并要求不重复。

// 定义存放生成随机数的数组

var array = new Array();

// 循环N次生成随机数

for (var i = 0 ; ; i++) {

    // 只生成10个随机数

    if (array.length < 100) {

        generateRandom(100);

    } else {

        break;

    }

}

// 生成随机数的方法

function generateRandom(count) {

    var rand = parseInt(Math.random() * count);

    for (var i = 0 ; i < array.length; i++) {

        if (array[i] == rand) {

            return false;

        }

    }

    array.push(rand);

}

// 输出随机数数组

alert(array);

对int[]数组进行快速排序

public static int QuickSort_Once(int[] _pnArray, int _pnLow, int _pnHigh)

{

    int nPivot = _pnArray[_pnLow];

    int i = _pnLow, j = _pnHigh;

    int sa;

    while (i < j)

    {

        while (_pnArray[j] >= nPivot && i < j) j--;                               

        nPivot = _pnArray[j];

        while (_pnArray[i] <= nPivot && i < j) i++;

        sa = _pnArray[i];

        _pnArray[i] = _pnArray[j];

        _pnArray[j] = sa;

    }

    _pnArray[i] = nPivot;

    return i;

}

public static void QuickSort(int[] _pnArray, int _pnLow, int _pnHigh)

{

    if (_pnLow >= _pnHigh) return;

    int _nPivotIndex = QuickSort_Once(_pnArray, _pnLow, _pnHigh);

    QuickSort(_pnArray, _pnLow, _nPivotIndex - 1);

    QuickSort(_pnArray, _nPivotIndex + 1, _pnHigh);

}

int[] _nArray = {57,68,....自己写};

QuickSort(_nArray, 0, _nLength - 1);

请将字符串 I am a student 逆序输出

string str = "I am a student";

var reversed = str.ToArray().Reverse();

foreach (char c in reversed)

{

    Console.Write(c);

}

计算1到100之间的素数(只能被1和本身整除)和,当和大于等于1000,则不再求,最后输出和值。

实现一:

int i = 0;

int j = 0;

Console.WriteLine("所有素数为:");

for (i = 2; i <= 100; i++)

{

    for (j = 2; j <= i; j++)

    {

        if (i % j == 0)

        {

            break;

        }

    }

    if (j > i - 1)

    {

        Console.Write(i + "\t");

    }

}

实现二:

int i = 0;

int j = 0;

int sum = 0;    //素数和值

int count = 0;

for (i = 2; i <= 100; i++)

{

    for (j = 2; j <= i; j++)

    {

        if (i % j == 0)

        {

            break;

        }

    }

    if (j > i - 1)

    {

        sum = sum + i;

        count++;

        if (sum > 1000)

        {

            break;//和值大于1000,中止计算

        }

    }

}

移动、前端技术

什么是HTML5?

HTML5是最新的HTML标准,他的主要目标是提供所有内容而不需要任何的像flash,silverlight等的额外插件,这些内容来自动画,视频,富GUI等,HTML5是万维网联盟(W3C)和网络超文本应用技术工作组(WHATWG)合作制定的下一代网页开发标准。目前html5已经获取了,Safari,Chrome,Firefox,Opera,IE等大部分浏览器的支持。

如果识别一个网页是使用html5标准开发的?

 

Html5主要增加了一下标签及事件:

音频播放

视频播放

替代Flash的标签画布标签

定义任何类型的任务的进度。可以使用标签来显示javascript中耗费时间的函数的进度

定义下拉列表,与input元素配合使用该元素

标签定义外部的内容

标签定义文档中的节(section,区段)。比如章节,页眉,页脚或文档中的其他部分

 

html5中还提供了Web存储能力:

localStorage

       localStorage  是没有时间限制的数据存储,持久化的本地存储,数据不会自动消失除非自己删除数据。

sessionStorage

       sessionStorage是针对一个 session 的数据存储,当用户关闭浏览器窗口后,数据会被删除,不是一种持久的本地存储。

 

Html5 中还定义了一种新的通讯协议WebSocket,它实现了浏览器与服务器全双工通信。使用js定义一个WebScoket对象,来实现与服务器的通信

WebSocket有两大好处:

一,互相沟通的Header是很小的-大概只有 2 Bytes,所以速度比较快。

二,Server Push服务器可以主动传送数据给客户端。

 

Html5 还有一个地图的一个实现 。他是用Geolocation API 用于获得用户的地理位置。其中 getCurrentPosition()获取当前的地理位置,WatchPosition  持续获取点前位置信息,clearWatch  停止获取位置信息。他的显示使用的是十进制和DMS。可以进行IP定位、GPS定位、Wi-fi定位、手机定位、自定义定位。

他的特殊实例就像谷歌地图.

 

特别在表单方面,添加了email url  number  range  search  tel  color 等表单控件。

例:

还添加了一些属性比如autocomplete  是一个可以实现自动完成内容输入的属性不过只有OPera浏览器支持 ,他有三个值:on  off  空值。

autofocus  是一个自动获取焦点的属性,他的值是bool类型的。

还有两个验证属性像Pattern  是一个正则表达式的验证Required  是一个非空验证的属性。

Html5中不再推荐使用的标签及事件有:

                          

  

JavaScript的变量作用域。

答 :JavaScript的变量作用域如下:

     A )全局变量:在整个页面都可访问,声明在Script块内

     B )局部变量:只在方法中可用,声明在函数体内

注:javascript的变量可不声明直接使用,如果在函数内直接使用了一个变量,如函数外没有同名变脸的声明,则此变量为局部变量

JavaScript是面向对象的语言?

Javascript是一种基于对象(object-based)的语言,你遇到的所有东西几乎都是对象。但是,它又不是一种真正的面向对象编程(OOP)语言,因为它的语法中没有class(类)。它主要是通过function来实现面向对象的开发。可以使用this定义公共成员,也可以后期动态添加,动态添加可使用prototype实现。其成员作用域可以是private的,也可以是public的。

JS的类定义:

function cat()

{}

以上代码,具体是类定义,还是方法定义,取决你如何使用,如下

如下,则当成方法使用:

cat() ==》 把cat当函数

如下,则当成类定义:

var cat1 = new cat()  ==> 当cat当类

定义类时,同时声明属性与方法的类定义

var cat3 = new function () {

    this.Name = "小黑";

    this.Color = "black";

    this.func1=function(){

    Alert(‘’);

    }

};

//调用类实例的一个方法

cat3.func1();

使用instanceof,判断一个对象是不是Person类的实例?

if(a instanceof Person){

       window.alert("a 是 Person1");

}

if(a.constructor==Person){

       window.alert("a 是 Person2");

}

访问对象的属性有两种方法:

普通方式

  对象名.属性名

动态访问

    对象名[“属性名”]

Js中,可以通过使用this来声明类属性:

    function Person(){

           this.name="abc";

           this.age=30;

    }

类的成员作用域:

        function Person() {

            //私有属性

            var name = "abc";       //私有的,只能在内部使用

            //私有字段

            var age = 30;           //私有的,只能在内部使用

            //公开属性

            this.name2 = "abc2";    //this.name2 表示name2这个属性是公开的

            //私有属性

            sex = "女";

            //公开方法

            this.show = function () {

                window.alert("name" + name + "age" + age + "sex" + sex);

            }

            //私有方法

            function show2() {

                window.alert("show2()" + name + "age" + age);

            }

        }

        var p1 = new Person();

        alert(p1.show());

添加向类中添加成员,主要通过prototype实现:

        //类定义

        function Dog() {

        }

        //动态的为类添加行为

        Dog.prototype.shout = function () {

            window.alert('小狗');

        }

        Dog.prototype.Name = "";

以上代码看不明白,对比以下代码

        var dog2 = new Dog();

        var dog3 = new Dog();

        var dog0 = Dog();

        dog0.shout = function () {

            window.alert('小狗');

        };

        var dog1 = Dog();

C/S和B/S的区别?

C/S=Client/Server 用客户端软件和服务器通信(比如杀毒软件的在线升级模块可以看作一个C/S结构)

B/S=Brower/Server 用浏览器和服务器通信 (比如淘宝网)

C/S结构常用于特定的一些系统,对效率要求较低,数据保密程度较高的系统。而且往往只支持一种操作系统。

B/S结构常用于一些效率要求高,数据保密程度相对较低的系统。

什么是Windows服务,它与EXE程序有什么不同

Windows服务是运行在windows后台指定用户下(默认System)的应用程序,它没有标准的UI界面,Windows服务应用是在服务开始的时候创建,并得到执行。而在服务结束的时候被操作系统销毁。当时也可以自主启动或停止windows服务。

其支持的启动模式有三种方式:1)自动方式 2)手动方式 3)禁止。

自动方式的时候,windows服务将在OS启动后自动启动运行

手动方式则必须手工启动服务

禁用的情况下服务将不能被启动。

另外标准的EXE默认权限,是使用的当前OS操作者的权限,而windows服务则默认使用System用户,对系统资源访问权限,将受此影响。

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

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

处理器下,单个进程所能访问的最大内存量为:232 /2 = 2G 。单个进程能访问的最大内存量是最大虚拟内存的1/2,因为要分配给操作系统一半虚拟内存。

多线程有几种实现方法,都是什么?同步有几种实现方法,都是什么?

答:多线程有两种实现方法,分别是继承Thread类与实现Runnable接口

同步的实现方面有两种,分别是synchronized,wait与notify

进程,线程联系与区别:

进程是操作系统进行资源分配和调度的基本单位。

线程是CPU调度和分派的基本单位。

线程是进程的一部分

一个进程可以包含多个线程,一个进程最少包含一个线程。

多个线程可以并发执行。

模态和非模态对话框的区别

模态对话框工作状态:当它获得焦点时,后面已经打开的窗口不能再进行操作。

非模态对话框则不受此影响。

Thread类实现多线程

Thread类的主要属性有:

    Thread.CurrentThread 当前线程

    ThreadState 线程状态

Name    线程的名称

主要方法有:

    1、Abort:          终止线程。

    3、Interrupt:           中断处于WaitSleepJoin线程状态的线程。

    9、Suspend;挂起线程。

6、Resume:         继续已挂起的线程。

7、Sleep:静态方法,将当前线程阻塞指定的毫秒数。

8、Start:启动线程。

2、GetDomain:   返回当前线程正在其中运行的当前域。(返回当前应用程序信息)静态方法。

4、Join: 阻塞调用线程,直到某个线程终止时为止。

5、ResetAbort:    取消为当前线程请求的Abort。

示例代码:

Thread SecondThread = new Thread(new ThreadStart(方法名));

SecondThread.Name = "次线程";

//次线程开始执行指向的方法

SecondThread.Start();

说一下你对多线程、线程池的理解

答: 多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务。

多线程的好处:

可以提高CPU的利用率。在多线程程序中,一个线程必须等待的时候,CPU可以运行其它的线程而不是等待,这样就大大提高了程序的效率。

多线程的不利方面:

线程也是程序,所以线程需要占用内存,线程越多占用内存也越多; 多线程需要协调和管理,所以需要CPU时间跟踪线程; 线程之间对共享资源的访问会相互影响,必须解决竞用共享资源的问题; 线程太多会导致控制太复杂,最终可能造成很多Bug;

   线程池的作用主要是缓解线程新建(分配资源)和销毁(垃圾回收)所带来的资源浪费,不用的线程并不销毁而保留在池中,用的时候再拿来用,池有一定的容量只有达到上限才会以一定的算法来销毁线程,这个上限也是你可以设置的。

异步编程

所谓异步:如果不等待调用的方法执行完,就执行下一行代码。

异步调用并不是要减少线程的开销, 它的主要目的是让调用方法的主线程不需要同步等待

在这个函数调用上, 从而可以让主线程继续执行它下面的代码.与此同时, 系统会通过从ThreadPool中取一个线程来执行,来完成某一个任务.

由于不需要我们等待, 我们等于在同一时间做了两件事情. 这个效果跟自己另外启动一个线程来执行等待方式的写操作是一样的.

但是, 异步线程可以利用操作系统/.Net的线程池, 系统可以根据吞吐量动态的管理线程池的大小.

  为实现应用程序具有快速和流畅的响应能力, Windows Runtime 中加入了许多可能受输入/输出限制的 API 进行了异步化处理。如果编写同步代码,则这些 API 对性能的影响将变得显而易见(例如,执行时间超过 50 毫秒)。这种异步化 API 的方法不仅允许您编写可默认实现快速流畅风格的代码,而且还提升了应用程序开发中应用程序响应速度的重要性。

异步和多线程有什么区别?

异步是目的,多线程是实现这个目的的方法。异步是说,A发起一个操作后(一般都是比较耗时的操作),可以继续自顾自的处理它自己的事儿,不用干等着这个耗时操作返回。.Net中的这种异步编程模型,简化了多线程编程,甚至不需要去了解Thread类的作用,就可以做一个支持异步操作的软件。

异步编程的三种模式:

APM      异步编程模型,Asynchronous Programming Model

EAP       基于事务的异步编程模式,Event-based Asynchronous Pattern

TAP        基于任务的异步编程模式,Task-based Asynchronous Pattern

异步编程模型 (APM) 模式(也称 IAsyncResult 模式),在此模式中异步操作需要 Begin 和 End 方法(比如用于异步写入操作的 BeginWrite 和 EndWrite)。 对于新的开发工作不再建议采用此模式。

  public class MyClass

  {

      public IAsyncResult BeginRead(byte [] buffer, int offset, int count, AsyncCallback callback, object state);

      public int EndRead(IAsyncResult asyncResult);

  }

基于事件的异步模式 (EAP),这种模式需要 Async 后缀,也需要一个或多个事件、事件处理程序委托类型和 EventArg 派生类型。 EAP 是在 .NET Framework 2.0 中引入的。 对于新的开发工作不再建议采用此模式。 有关详细信息,请参阅基于事件的异步模式 (EAP)。

基于任务的异步模式 (TAP) 使用一种方法来表示异步操作的启动和完成。 TAP 是在 .NET Framework 4 中引入的,并且它是在 .NET Framework 中进行异步编程的推荐使用方法。 C# 中的 async 和 await 关键词以及 Visual Basic 语言中的 Async 和 Await 运算符为 TAP 添加了语言支持。 此种模式应重点了解。

基于任务的异步模式 (TAP) 是基于 System.Threading.Tasks 命名空间的 Task 和 Task,用于表示任意异步操作。

TAP主要通过:async、await、Task类实现。

代码截图:

 

 

Task类使用总结

由于Framework 4.0和Framework 4.5对Task类稍微有些不同,此处声明以下代码都是基于Framework 4.5

Task类和Task类,后者是前者的泛型版本。TResult类型为Task所调用方法的返回值。

主要区别在于Task构造函数接受的参数是Action委托,而Task接受的是Func委托。

Task(Action)

Task(Func

启动一个异步任务

Task.Run(() => Console.WriteLine("Foo"));

Invoke and BeginInvoke

 

Delegate.BeginInvoke 实现异步

通过一个委托来进行同步方法的异步调用,也是.net提供的异步调用机制之一。但是Delegate.BeginInvoke方法是从ThreadPool取出一个线程来执行这个方法,以获得异步执行效果的。也就是说,如果采用这种方式提交多个异步委托,那么这些调用的顺序无法得到保证。而且由于是使用线程池里面的线程来完成任务,使用频繁,会对系统的性能造成影响。

Delegate.BeginInvoke也是讲一个委托方法封送到其它线程,从而通过异步机制执行一个方法。调用者线程则可以在完成封送以后去继续它的工作。但是这个方法封送到的最终执行线程是运行库从ThreadPool里面选取的一个线程。

这里需要纠正一个误区,那就是Control类上的异步调用BeginInvoke并没有开辟新的线程完成委托任务,而是让界面控件的所属线程完成委托任务的。看来异步操作就是开辟新线程的说法不一定准确。

                                                        Invoke or BeginInvoke(看不明白,可以看以下网址)

http://www.cnblogs.com/marksun/archive/2012/02/29/2373383.html

Invoke或者BeginInvoke方法都需要一个委托对象作为参数。委托类似于回调函数的地址,因此调用者通过这两个方法就可以把需要调用的函数地址封送给界面线程。这些方法里面如果包含了更改控件状态的代码,那么由于最终执行这个方法的是界面线程,从而避免了竞争条件,避免了不可预料的问题。如果其它线程直接操作界面线程所属的控件,那么将会产生竞争条件,造成不可预料的结果。

使用Invoke完成一个委托方法的封送,就类似于使用SendMessage方法来给界面线程发送消息,是一个同步方法。也就是说在Invoke封送的方法被执行完毕前,Invoke方法不会返回,从而调用者线程将被阻塞。

使用BeginInvoke方法封送一个委托方法,类似于使用PostMessage进行通信,这是一个异步方法。也就是该方法封送完毕后马上返回,不会等待委托方法的执行结束,调用者线程将不会被阻塞。但是调用者也可以使用EndInvoke方法或者其它类似WaitHandle机制等待异步操作的完成。

但是在内部实现上,Invoke和BeginInvoke都是用了PostMessage方法,从而避免了SendMessage带来的问题。而Invoke方法的同步阻塞是靠WaitHandle机制来完成的。

MVC的优缺点

优点:

耦合性低:

视图层和业务层分离,这样就允许更改视图层代码而不用重新编译模型和控制器代码,同样,一个应用的业务流程或者业务规则的改变只需要改动MVC的模型层即可。因为模型与控制器和视图相分离,所以很容易改变应用程序的数据层和业务规则。

重用性高:

允许使用各种不同样式的视图来访问同一个服务器端的代码,因为多个视图能共享一个模型

生命周期 成本低:

MVC使开发和维护用户接口 的技术含量降低。

部署快

使用MVC模式使开发时间得到相当大的缩减,它使程序员集中精力于业务逻辑,界面程序员集中精力于表现形式上。

可维护性高

分离视图层和业务逻辑层也使得WEB应用更易于维护和修改。

缺点:

不适合小型,中等规模的应用程序

花费大量时间将MVC应用到规模并不是很大的应用程序通常会得不偿失。

视图与控制器间的过于紧密的连接

视图与控制器是相互分离,但却是联系紧密的部件,视图没有控制器的存在,其应用是很有限的,反之亦然,这样就妨碍了他们的独立重用

视图对模型数据的低效率访问

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

ASP.NET mvc的运行机制?

1.用户通过浏览器输入地址,通过路由映射到相应的控制器的action上。

2.控制器接受命令后调用模型, 请求获得相关的数据;

3.模型将相应的数据返回给控制器;

4.然后由控制器将通过return view() 返回给相应的视图

5.由视图 结合传递过来的数据,完成最终的页面显示工作。

设计模式

单例模式Singleton:

       主要目的是确保某个类,只有一份实例,而且存在一个全局的访问点来访问这个实例对象。

此外,对象应在实际使用时,才被创建。

单例模式中,负责实施这种约束的是类自身。

       具体实现:

       1、让构造函数成为私有,同时添加一个私有的静态构造函数。

       2、添加一个私有的静态只读对象,这个对象通过私有的构造函数在类的内部实化。

       3、添加一个访问此私有对象的公有静态属性。

public class Singleton

{

    private static Singleton _instance = null;

    private Singleton(){}

    public static Singleton CreateInstance()

    {

        if(_instance == null)

        {

            _instance = new Singleton();

        }

        return _instance;

    }

}

观察者模式Observer:

定义了对象之间的一种联系,使得当一个对象改变状态时,所有其它对象都可以相应地被通知到。

具体应用:

1、邮件订阅

2、控件

工厂模式Factory Method

定义:一种创建对象的方法,但它让子类来决定创建哪种类型的对象。

{有一个工厂类,负责根据客户类的请求,来创建一个类的对象}

定义二:一种创建对象的方法,在使用该类时,由需求决定具体实例化那个类。

具体应用:

       项目中,可以通过一个DALFactory工厂类,来帮助创建访问数据库的类实例。

适配器模式

将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。

网站优化

针对并发量的方案:

1、高性能的服务器。

2、高性能的数据库。

3、高效率的编程语言。

4、高性能的WEB容器。

HTML静态化

特点:

效率最高、消耗最小、避免大量数据访问请求。采用静态页面来实现。

场景:

针对新闻类的信息

图片服务器

Web服务器来说,图片是最消耗资源的,于是我们有必要将图片与页面进行分离。

MongoDB的技术使用,把图片存储到MongoDB数据库。 分布式存储。主从模式。

特点:

降低提供页面访问请求的服务器系统压力,并且可以保证系统更好的运行。

数据库集群、库表散列

应用:面对大量访问的时候,数据库的瓶颈很快就能显现出来,这时一台数据库将很快无法满足应用,于是我们需要使用数据库集群或者库表散列。

特点:

配置文件中进行简单的配置便能让系统随时增加一台低成本的数据库进来补充系统性能

缓存

C#有单机缓存Cache类,整页缓存outputCache,局部缓存。

第三方的缓存技术有:MemCached  Redis,其也可以完成数据的分布式缓存。

Memcached简介

Memcached是以LiveJurnal旗下Danga Interactive公司的Bard Fitzpatric为首开发的高性能分布式内存缓存服务器。其本质上就是一个内存key-value数据库,但是不支持数据的持久化,服务器关闭之后数据全部丢失。Memcached使用C语言开发,在大多数像Linux、BSD和Solaris等POSIX系统上,只要安装了libevent即可使用。在Windows下,它也有一个可用的非官方版本(http://code.jellycan.com/memcached/)。Memcached的客户端软件实现非常多,包括C/C++, PHP, Java, Python, Ruby, Perl, Erlang, Lua等。当前Memcached使用广泛,除了LiveJournal以外还有Wikipedia、Flickr、Twitter、Youtube和WordPress等。

启动Memcached命令行:memcached.exe -d RunService -l 127.0.0.1 -p 11211 -m 500

memcached.exe -d install

memcached.exe -d start 该命令启动 Memcached,默认监听端口为 11211

C#支持类库:Enyim.Caching.dll

示例

MemcachedClient mc = new MemcachedClient();

mc.Store(StoreMode.Set, "MyKey", "Hello World");

Console.WriteLine(mc.Get("MyKey"));

Redis简介

Redis是一个开源的key-value存储系统。与Memcached类似,Redis将大部分数据存储在内存中,支持的数据类型包括5种:字符串(String)、哈希表(hash)、链表(map)、集合(list)、有序集合(sortset)以及基于这些数据类型的相关操作。Redis使用C语言开发,在大多数像Linux、BSD和Solaris等POSIX系统上无需任何外部依赖就可以使用。Redis支持的客户端语言也非常丰富,常用的计算机语言如C、C#、C++、Object-C、PHP、Python、Java、Perl、Lua、Erlang等均有可用的客户端来访问Redis服务器。当前Redis的应用已经非常广泛,国内像新浪、淘宝,国外像Flickr、Github等均在使用Redis的缓存服务。

如果简单地比较Redis与Memcached的区别,大多数都会得到以下观点:

1  Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。

2  Redis支持数据的备份,即master-slave模式的数据备份。

3  Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。

总结:

  1.Redis使用最佳方式是全部数据in-memory。

  2.Redis更多场景是作为Memcached的替代者来使用。

    3.当需要除key/value之外的更多数据类型支持时,使用Redis更合适。

    4.当存储的数据不能被剔除时,使用Redis更合适。

分布式缓存,你了解几种?

Memcache是一个高性能的分布式的内存对象缓存系统,用于动态Web应用以减轻数据库负载。通过在内存里维护一个统一的巨大的hash表,它可以储存的数据类型包括图像、视频、文件以及数据库检索的结果等。简单的说就是将数据调用到内存中,然后从内存中读取,从而减少读取数据库的次数。大大提高读取速度。

我们在项目中使用redis做为缓存,放弃使用memcache,考虑因素主要有两点:

1.redis丰富的数据结构,其hash,list,set以及功能丰富的String的支持,对于实际项目中的使用有很大的帮忙。

2.redis单点的性能也非常高效(利用项目中的数据测试,表现优于memcache).

3.Redis支持数据持久化,虽然无法像数据库那样完善,但对于互联网这种场景,完全够用。

4.redis支持master-slave复制模式(主从复制模式:即一台主写入服务器,多台从备份服务器。从服务器可以实现备份,和读扩展,分担主服务器读密集时压力,充当查询服务器。 )基于以上考虑,因此选用了redis来做为缓存应用。

其他分布式缓存技术:

Cache4J

Cacheman

OSCache

Enhence

【redis如何注册成服务】

1、微软针对如何把Redis注册成服务,没有直接发布,而是提供了一份开源代码

https://github.com/MSOpenTech/redis

项目类型:Windows服务

可以直接生成服务,注册服务即可。

【Redis数据类型】

String

Hash

List

Set

Sort Set

镜像

镜像的技术可以解决不同网络接入商和地域带来的用户访问速度差异,有很多专业的现成的解决架构和产品可选

负载均衡

 负载均衡将是大型网站解决高负荷访问和大量并发请求采用的高端解决办法。其是由一组相互独立的计算机系统构成,通过常规网络或专用网络进行连接在一起,各节点相互协作、共同负载、均衡压力,对客户端来说,整个群集可以视为一台具有超高性能的独立服务器。

实现负载均衡的主要手段有:

1、软件实现:

    使用软件实现,可使用Nginx完成。

    Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件代理服务器。由俄罗斯的工程师Igor Sysoev所开发,供俄国大型的入口网站及搜索引擎Rambler使用。其特点是占有内存少,并发能力强,使用免费的特点。事实上nginx的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:新浪、网易、腾讯等。

2、

 

3、硬件实现:

    使用硬件实现,可购买专业的配置完成,比如:BIG IP 6400、F5 BIG-LTM-1500-RS,价格在10、20万元不等。

 

数据库的读写分离

实现原理:读写分离简单的说是把对数据库读和写的操作分开对应不同的数据库服务器,这样能有效地减轻数据库压力,也能减轻io压力。主数据库提供写操作,从数据库提供读操作,其实在很多系统中,主要是读的操作。当主数据库进行写操作时,数据要同步到从的数据库,这样才能有效保证数据库完整性。

实现方法

SQL SERVER复制技术类型有三种,分别是:快照复制、事务复制、合并复制。

SQL SERVER 主要采用出版物、订阅的方式来处理复制。

2,优缺点

(1)数据的实时性差:数据不是实时同步到自读服务器上的,当数据写入主服务器后,要在下次同步后才能查询到。

  (2)数据量大时同步效率差:单表数据量过大时插入和更新因索引,磁盘IO等问题,性能会变的很差。

  (3)同时连接多个(至少两个)数据库:至少要连接到两个数据数据库,实际的读写操作是在程序代码中完成的,容易引起混乱

    (4)读具有高性能高可靠性和可伸缩:只读服务器,因为没有写操作,会大大减轻磁盘IO等性能问题,大大提高效率;只读服务器可以采用负载均衡,主数据库发布到多个只读服务器上实现读操作的可伸缩性。

数据库/数据表 拆分(分布式)

通过某种特定的条件,将存放在同一个数据库中的数据分散存放到多个数据库上,实现分布存储,通过路由规则路由访问特定的数据库,这样一来每次访问面对的就不是单台服务器了,而是N台服务器,这样就可以降低单台机器的负载压力。提示:sqlserver 2005版本之后,可以友好的支持“表分区”。

垂直(纵向)拆分:是指按功能模块拆分,比如分为订单库、商品库、用户库...这种方式多个数据库之间的表结构不同。

水平(横向)拆分:将同一个表的数据进行分块保存到不同的数据库中,这些数据库中的表结构完全相同。

 

 

▲(纵向拆分)

 

 

水平(横向)拆分

临时表:

SqlServer中可以创建本地和全局临时表。本地临时表仅在当前会话中可见;全局临时表在所有会话中都可见。

本地临时表的名称前面有一个#,如(#table_name),而全局临时表的名称前面有两个## ,如(##table_name)。

临时表与普通表的区别:

本地临时表,仅限于当前访问者访问,创建方法去如下:

create table #TableName(表结构)

储存于数据库tempdb内(硬盘),当前用户断开连接,自动删除

如果使用中不断开连接,且不需要该临时表请执行:drop table #TableName

全局临时表,所有访问用户访问,创建方法去如下:

create table ##TableName(表结构)

储存于数据库tempdb内,当所有访问用户断开连接,自动删除

删除语句:drop table ##TableName

--创建临时表

CREATE TABLE #MyTempTable (cola INT PRIMARY KEY)

--向临时表,插入数据

INSERT INTO #MyTempTable VALUES (1)

--向临时表中批量复制数据

insert into #tablename(a,b,c,d) select a,b,c,d from T

C#中等于号的使用:

= :作用赋值

==:将高级转化为基础类型,进行“值”比较

===:值和类型都参与比较,任何一个不同就为false

.NET的GC(Gabage Collection)机制

GC并不是能释放所有的资源。只能释放托管资源即继承了IDispose接口的,它不能自动释放非托管资源。

GC并不是实时性的,这将会造成系统性能上的瓶颈和不确定性。

ASP.NET MVC 路由机制

MVC路由 是从URL模式开始的,它指定了与路由相匹配的映射模式,路由可以指定它的URL及其默认值,还可以约束URL的各个部分,提供关于路由对请求URL相匹配的严格控制。创建新MVC应用程序时,会创建了一个默认路由表,其在RouteConfig.cs中被定义。

MVC中的路由主要有两种用途:

l、匹配传入URL网址请求,映射到控制器的Action上。

2、在View中,根据给定的信息(Html.ActionLink(“index”, “home”)),根据路由表生成相应的URL地址。

路由映射的映射过程主要由全局路由表RouteTable的静态变量Routes来完成。Routes是RouteCollection类的一个实例,其的MapPageRoute()方法完成对路由的解析工作。

RouteCollection类型定义中,还提供了一系列的扩大办法以实现文件路径无关的路由映射,这些扩大办法定义在RouteCollectionExtensions类型中。

RouteCollectionExtensions定义了办法IgnoreRoute用于注册不须要进行路由映射的URL模板

路由例子:

routes.MapRoute("Default","{first}/{second}/{third}");

Cookie对象的主要属性和方法

属性:

(1).Name:获取或设置Cookie的名称

(2).Value:获取或设置Cookie的值

(3).Expires:获取或设置Cookie的过期时间

(4).Version:获取或设置Cookie的符合HTTP维护状态的版本

方法:

(1).Add:增加Cookie变量,将指定的cookie保存到Cookies集合中

(2).Clear:清除Cookie集合中变量

(3).Get:通过变量名或索引得到Cookie变量的值

(4).Remove:通过Cookie变量名或索引删除Cookie对象

IHttpModule与IHttpHandler的区别

1、先后次序.先IHttpModule,后IHttpHandler. 注:Module要看你响应了哪个事件,一些事件是在Handler之前运行的,一些是在Handler之后运行的

2、对请求的区别:

IHttpModule无论客户端请求的是什么文件,都会调用到它;例如aspx,rar,html的请求.

IHttpHandler则只有ASP.net注册过的文件类型(例如aspx,asmx等等)才会轮到被调用.

4、IHttpHandler按照你的请求生成响应的内容,IHttpModule对请求进行预处理,如验证、修改、过滤等等,同时也可以对响应进行处理。

5、在http请求的处理过程中,只能调用一个HttpHandler,但可以调用多个HttpModule。

JQuery中ready和load的区别 

JS中,load是所有Dom元素创建完毕、图片、Css等都加载完毕后才被触发,而ready则是Dom元素创建完毕后就被触发,这样可以提高网页的响应速度。

在jQuery中可以用$(document).ready()来实现ready事件的响应,通过$(window).load()来实现load事件的响应。

比方说我们得网站上有个美女图片,点击图片就可以有某某效果,如果是ready的话,即使没有加载完,他也可以出来效果,但是onload却不可以,所以ready可以提高响应速度。我们一般也使用ready。ready的简写方式为$();

讲一讲你了解的复杂控件:

datagrid,reapter、datalist、tree、treegrid、分页控件aspnetpager、mvcpager

Tree:   TreeView、jQueryEasyTree、ExtJS Tree、Treegrid.

无限级分类库结构:分类编号、分类名称、父结点

ArrayList与List泛型的区别?

ArrayList是.Net Framework提供的用于数据存储和检索的专用类,它是命名空间System.Collections下的一部分。它的大小是按照其中存储的数据来动态扩充与收缩的。所以,我们在声明ArrayList对象时并不需要指定它的长度。

泛型List

因为ArrayList存在不安全类型与装箱拆箱的缺点,所以在C#2.0后提出了泛型。而List类是ArrayList类的泛型等效类。它的大部分用法都与ArrayList相似,List类实现了IList接口。其两者最关键区别在于,在声明List集合时,我们同时需要为其声明List集合内数据的对象类型。如List list=new List();

泛型的优点、缺点

    泛型的优点主要是可以免了拆箱和装箱操作,不容易出现类型转换的错误,使用起来更加灵活。

    缺点主要是效率问题,特别是使用反射机制后会有一定的程序效率问题。

处理上百万条的数据库如何提高处理查询效率

1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。

2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:   select id from t where num is null   可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:  select id from t where num=0  

3.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。  

4.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:   select id from t where num=10 or num=20  可以这样查询:   select id from t where num=10  union all   select id from t where num=20  

5.in 和 not in 也要慎用,否则会导致全表扫描,如:  select id from t where num in(1,2,3)   对于连续的数值,能用 between 就不要用 in 了:  select id from t where num between 1 and 3 

6.下面的查询也将导致全表扫描:   select id from t where name like '%abc%'  若要提高效率,可以考虑全文检索。  

7.如果在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然 而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描:  select id from t where num=@num  可以改为强制查询使用索引:   select id from t with(index(索引名)) where num=@num  

8.应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:   select id from t where num/2=100  应改为:   select id from t where num=100*2

 9.应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:  

 select id from t where substring(name,1,3)='abc'--name以abc开头的id   select id from t where datediff(day,createdate,'2005-11-30')=0--‘2005-11-30’生成的id  应改为:   select id from t where name like 'abc%'   select id from t where createdate>='2005-11-30' and createdate<'2005-12-1'  

10.不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。  

11.在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。 

12.不要写一些没有意义的查询,如需要生成一个空表结构:  select col1,col2 into #t from t where 1=0   这类代码不会返回任何结果集,但是会消耗系统资源的,应改成这样:  create table #t(...)  

13.很多时候用 exists 代替 in 是一个好的选择:   select num from a where num in(select num from b)  用下面的语句替换:   select num from a where exists(select 1 from b where num=a.num) 

14.并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。  

15.索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有 必要。  

16.应尽可能的避免更新 clustered 索引数据列,因为 clustered 索引数据列的顺序就是表记录的物理存储顺序,一旦该列值改变将导致整个表记录的顺序的调整,会耗费相当大的资源。若应用系统需要频繁更新 clustered 索引数据列,那么需要考虑是否应将该索引建为 clustered 索引。  

17.尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。  

18.尽可能的使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。  

19.任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。  

20.尽量使用表变量来代替临时表。如果表变量包含大量数据,请注意索引非常有限(只有主键索引)。  

21.避免频繁创建和删除临时表,以减少系统表资源的消耗。  

22.临时表并不是不可使用,适当地使用它们可以使某些例程更有效,例如,当需要重复引用大型表或常用表中的某个数据集时。但是,对于一次性事件,最好使用导出表。  

23.在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后insert。  

24.如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。  

25.尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写。  

26.使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题,基于集的方法通常更有效。  

27.与临时表一样,游标并不是不可使用。对小型数据集使用 FAST_FORWARD 游标通常要优于其他逐行处理方法,尤其是在必须引用几个表才能获得所需的数据时。在结果集中包括“合计”的例程通常要比使用游标执行的速度快。如果开发时 间允许,基于游标的方法和基于集的方法都可以尝试一下,看哪一种方法的效果更好。  

28.在所有的存储过程和触发器的开始处设置 SET NOCOUNT ON ,在结束时设置 SET NOCOUNT OFF 。无需在执行存储过程和触发器的每个语句后向客户端发送 DONE_IN_PROC 消息。

29.尽量避免大事务操作,提高系统并发能力。

30.尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。

XAML

XAML是eXtensible Application Markup Language的英文缩写,相应的中文名称为可扩展应用程序标记语言,它是微软公司为构建应用程序用户界面而创建的一种新的描述性语言。XAML是一种解析性的语言,尽管它也可以被编译。它的优点是简化编程式上的用户创建过程,应用时要添加代码等。

基于UDP、TCP协议的C#网络编程之一

TCP(传输控制协议)是 TCP/IP 协议栈中的传输层协议,它通过序列确认以及包重发机制,提供可靠的数据流发送和到应用程序的虚拟连接服务。与IP协议相结合, TCP组成了因特网协议的核心。

UDP(用户数据报协议)是ISO参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。 UDP协议基本上是 IP 协议与上层协议的接口。UDP协议适用端口分辨运行在同一台设备上的多个应用程序。

C#中针对Socket编程的支持

主要由System.Net.Socket命名空间中的类提供,重要类:

  ·Socket类           

  ·NetworkStream类    这个类是从Stream派生出来的,它表示来自网络的数据流

  ·TcpClient类        允许创建和使用TCP连接

  ·TcpListener类           允许监听传入的TCP连接请求

  ·UdpClient类             用于UDP客户创建连接

Socket类的构造方法:

public Socket(AddressFamily addressFamily,SocketType socketType,ProtocolType protocolType);

注:

AddressFamily    参数指定

Socket          使用的寻址方案

SocketType  参数指定

Socket          类型

ProtocolType      参数指定

Socket          使用的协议。

声明一个基于 TCP/IP 的网络上通讯的实例

Socket temp = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

声明一个基于 UDP 的网络上通讯的实例

Socket temp = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

创建 Socket 实例后,你可以通过Connect方法连接到指定的服务器

Send()   发送数据

Receive()      接收数据

Bind()           绑定端口

Listen()  侦听接口上的请求

Accept()       接收请求

Close()

相关概念:

EndPoint     网络地址和服务端口的组合称为终结点,代表了一个特定服务的位置。

IPEndPoint类

IPAddress 类      代表一个IP地址。其Parse方法可将 IP 地址字符串转换为 IPAddress

IPAddress myIP = IPAddress.Parse("192.168.0.1");

Socket 类支持两种基本模式:同步和异步。

同步模式中:按块传输,对执行网络操作的函数(如 Send 和 Receive)的调用一直等到所有内容传送操作完成后才将控制返回给调用程序。

异步模式中:是按位传输,需要指定发送的开始和结束。

同步模式是最常用的模式

实例,同步模式下的一次数据传输:  服务器端

static void Main(string[] args)

{

    try

    {

        int port = 2000;

        string host = "127.0.0.1";

        IPAddress ip = IPAddress.Parse(host);

        IPEndPoint ipep = new IPEndPoint(ip, port);

        Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);    

        s.Bind(ipep);//绑定2000端口

        s.Listen(0);//开始监听

        Console.WriteLine("Wait for connect");

        Socket temp = s.Accept();//为新建连接创建新的Socket。

        Console.WriteLine("Get a connect");

        string recvStr = "";

        byte[] recvBytes = new byte[1024];

        int bytes;

        bytes = temp.Receive(recvBytes, recvBytes.Length, 0);//从客户端接受信息

        recvStr += Encoding.ASCII.GetString(recvBytes, 0, bytes);

        Console.WriteLine("Server Get Message:{0}", recvStr);//把客户端传来的信息显示出来

        string sendStr = "Ok!Client Send Message Sucessful!";

        byte[] bs = Encoding.ASCII.GetBytes(sendStr);

        temp.Send(bs, bs.Length, 0);//返回客户端成功信息

        temp.Close();

        s.Close();

    }

    catch (ArgumentNullException e)

    {

        Console.WriteLine("ArgumentNullException: {0}", e);

    }

    catch (SocketException e)

    {

        Console.WriteLine("SocketException: {0}", e);

    }

    Console.WriteLine("Press Enter to Exit");

    Console.ReadLine();

}

客户端代码:

static void Main(string[] args)

{

    try

    {

        int port = 2000;

        string host = "127.0.0.1";

        IPAddress ip = IPAddress.Parse(host);

        IPEndPoint ipep = new IPEndPoint(ip, port);//把ip和端口转化为IPEndPoint实例

       //创建一个Socket

        Socket c = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        Console.WriteLine("Connecting……");

        c.Connect(ipep);//连接到服务器

        string sendStr = "hello!This is a socket test";

        byte[] bs = Encoding.ASCII.GetBytes(sendStr);

        Console.WriteLine("Send Message");

        c.Send(bs, bs.Length, 0);//发送消息

        string recvStr = "";

        byte[] recvBytes = new byte[1024];

        int bytes;

        bytes = c.Receive(recvBytes, recvBytes.Length, 0);//从服务器端接受返回信息

        recvStr += Encoding.ASCII.GetString(recvBytes, 0, bytes);

        Console.WriteLine("Client Get Message:{0}", recvStr);//显示服务器返回信息

        c.Close();

    }

    catch (SocketException e)

    {

        Console.WriteLine("SocketException: {0}", e);

    }

    Console.WriteLine("Press Enter to Exit");

    Console.ReadLine();

}

对两个无序字符串,合并后排序

string s1 = "...";       

string s2 = "...";             

var arry = new ArrayList();       

//将无序的字符加入数组中   

for (int ii = 0; ii < (s1.Length > s2.Length ? s1.Length : s2.Length); ii++)

{

        if (ii < s1.Length) str.Add(s1.Substring(ii, 1));

        if (ii < s2.Length) str.Add(s2.Substring(ii, 1));

}

string newStr = "";

//将排序后的数组重组为字符串       

foreach (string _str in str.ToArray().OrderBy(i => i))

{           

       newStr += _str;       

}

五险一金缴纳比例

养老保险:缴费比例: 单位21%, 个人8%。

医疗保险:医疗保险缴费比例: 单位9%, 个人2%+3元

失业保险:失业保险缴费比例: 单位2%, 个人1%;

工伤保险: 单位缴纳0.5%, 个人不用缴

生育保险: 单位缴纳1%, 个人不用缴;

住房公积金:公积金缴费比例: 单位按工资的12%。个人工资的12%  

这是个比率,和工资多少挂钩,

http://www.bankrate.com.cn/tools/five-insurance-one-fund-calc.html

这有个计算器,可以去算算

等你老了或出问题了,用这个保险保障你

数据采集流程

1、通过WebRequest类,从 一个url 获取网页的数据。

2、在项目中,使用正则表达式Regex类,匹配出需要采集的数据。

3、循环遍历匹配到的数据,将数据依次插入到数据库中。

到此完成数据采集。

sqlserver 多库查询sp_addlinkedserver

mssql在使用多库查询的时候会用到链接服务器,以下为链接服务器的添加方法,添加完了即可实现任意改服务器的多库查询了

Exec sp_droplinkedsrvlogin ZYB,Null --删除映射(录与链接服务器上远程登录之间的映射)

Exec sp_dropserver ZYB --删除远程服务器链接

EXEC sp_addlinkedserver

@server='ZYB',--被访问的服务器别名

@srvproduct='',

@provider='SQLOLEDB',

@datasrc="/Server2" --要访问的服务器

EXEC sp_addlinkedsrvlogin

'ZYB', --被访问的服务器别名

'false',

NULL,

'sa', --帐号

'sa' --密码

使用实例:

Select * from ZYB.CDCenter20110822.dbo.cardbase

 

对象时对其进行初始化,写出你的代码

(本题实际考的是 单例模式 + 多线程的锁应用)

    public class Singleton

    {

        private static Singleton uniqueInstance = null;

        private Singleton() { }

        public static Singleton getInstance()

        {

            lock (uniqueInstance)

            {

                if (uniqueInstance == null)

                {

                    uniqueInstance = new Singleton();

                }

                return uniqueInstance;

            }

        }

    }

查询当前用户总量,当数量少于50时,发送邮件提醒系统管理员,请使用观察者模式完成代码

public class UserObserver

{

        public delegate void UserDelegate(IList users);

        public event UserDelegate AddEnvent;

        public IList UserList;

        public virtual int Add(User user)

        {

            //完成数据库插入...

            Console.WriteLine("数据插入成功");

            //完成通知

            // 直接在这里面通知     不要这样作,将这个机会留给别人

            if (AddEnvent != null)

            {

                AddEnvent(UserList);

                Console.WriteLine("事件调用成功");

            }

            return 1;

        }

}

A标签的href与onclick事件的区别详解

执行顺序,onclick 事件先执行,其次是 href 属性下的动作

同时存在 href 与 onclick,如果想让 href 属性下的动作不执行,onclick 必须得到一个 false 的返回值。

href 属性中调用一个有返回值的函数,当前页面的内容将被此函数的返回值代替;

Sql Server 预编译、重编译与执行计划重用原理

当 Sql Server 收到任何一个指令,包括:查询、批处理、存储过程、触发器、预编译指令和动态SQL Server语句,要完成语法解析、语义分析,然后再进行"编译",生成能够运行的"执行计划"。在编译的过程中,SQL Server 会根据所涉及的对象的架构、统计信息,以及指令的具体内容,估算可能的执行计划,以及它们的成本,最后选择一个SQL Server认为成本最低的语句。

 

执行计划生成之后,SQL Server 通常会把它们缓存到内存里,术语统称它们叫“Plane Cache”。以后同样的语句执行,SQL Server就可以使用同样的执行计划,而无须再做一次编译。这种行为,叫做“重用”。但是有时候,哪怕是一模一样的语句,SQL Server 下次执行还是要再做一次编译。这种行为叫“重编译”。执行计划的编译和重编译都是要耗费资源的。

 

执行计划的好坏当然决定了语句的执行速度。对于同样一条语句,使用好的执行计划可能会比差的要快几百倍,甚至几千倍。所以从这一角度上来讲,没运行一条语 句,都把它先编译一遍当然是最好的。它能够保证使用的执行计划是 SQL Server 能找到的最优的。但是 SQL Server 每秒钟可能会运行成百上千的指令。如果每个都编译一遍,是资源的严重浪费。所以 SQL Server 在这里也试图寻找一个平衡点,使用优先的 complie/recomplie,得到最好的 整体性能。

C#位运算操作符:

 & 与    | 或             ^ 异或 ~ 取补 << 左移             >> 右移

C#冒泡排序

static void Bubble(List list)

{

    int temp = 0;

    for (int i = list.Count; i > 0; i--)

    {

        for (int j = 0; j < i - 1; j++)

        {

            if (list[j] > list[j + 1])

            {

                temp = list[j];

                list[j] = list[j + 1];

                list[j + 1] = temp;

            }

        }

           foreach (var item in list)

           {

               Console.Write(string.Format("{0} ", item));

           }

           Console.WriteLine();

    }

}

Action和Func是什么,他们有什么区别?

Func 是.NET里面的内置委托,它有很多重载。Func都是有返回类型,其类型TResult为范型。传入参数的类型,可以通过泛型指定。

Action 委托:没有传入参数,也没有返回类型,即Void。

如何优化JavaScript文件的加载速度

将js脚本放入一个外部js文件,并对该js文件进行压缩

如果一个页面中,有多个js脚本,可以将多个js文件合并成一个js文件,以提高加载速度

ASP.NET 常用传值手段

1.URL传值

可使用get、post方式请求数据,在服务器端可使用Request.QueryString或Form集合获取数据。

2.Session传值

这种方法将每份数据存储于服务器变量中,可以传递比较多的数据,并且安全性较高,所以常用于用户身份的验证功能中。

3.Cookie传值

Cookie是一种比较特殊的数据存储方式,因为这种方式将数据存储于浏览用户的电脑中,以文本文件的形式存在于磁盘中。

4.Server.Transfer传值

5.Application传值 

JS全选、反选

$(function () {

    $('#inputCheck').click(function () {

        $("input[name='Checkbox1']").attr("checked", $(this).attr("checked"));

    });

}); // 全选

$(function () {

    $("#select_reverse").click(function () {

        $("input[name='Checkbox1']").each(function (idx, item) {

            $(item).attr("checked", !$(item).attr("checked"));

        })

    });

});//反选

给定以下xml文件,完成递归算法流程图

 

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 );

    }

}

数据库弱一致性四个隔离级别

SQL-92标准中定义了四个隔离级别,这四个隔离级别在以前版本的SQL Server中即受到支持:

READ UNCOMMITTED

READ UNCOMMITTED是限制性最弱的隔离级别,因为该级别忽略其他事务放置的锁。使用READ UNCOMMITTED级别执行的事务,可以读取尚未由其他事务提交的修改后的数据值,这些行为称为“脏”读。这是因为在Read Uncommitted级别下,读取数据不需要加S锁,这样就不会跟被修改的数据上的X锁冲突。比如,事务1修改一行,事务2在事务1提交之前读取了这一行。如果事务1回滚,事务2就读取了一行没有提交的数据,这样的数据我们认为是不存在的。

READ COMMITTED

READ COMMITTED(Nonrepeatable reads)是SQL Server默认的隔离级别。该级别通过指定语句不能读取其他事务已修改但是尚未提交的数据值,禁止执行脏读。在当前事务中的各个语句执行之间,其他事务仍可以修改、插入或删除数据,从而产生无法重复的读操作,或“影子”数据。比如,事务1读取了一行,事务2修改或者删除这一行并且提交。如果事务1想再一次读取这一行,它将获得修改后的数据或者发现这一样已经被删除,因此事务的第二次读取结果与第一次读取结果不同,因此也叫不可重复读。

实验1

query1:事务1

--step1:创建实验数据select * into Employee from AdventureWorks.HumanResources.Employe

alter table Employee add constraint pk_Employee_EmployeeID primary key(EmployeeID)

--step2:设置隔离级别,这是数据库的默认隔离界别SET TRANSACTION ISOLATION LEVEL READ COMMITTED

--step3:开启第一个事务BEGIN TRAN tran1

    --step4:执行select操作,查看VacationHours,对查找的记录加S锁,在语句执行完以后自动释放S锁

    SELECT EmployeeID, VacationHours

        FROM Employee 

        WHERE EmployeeID = 4;

    --step5:查看当前加锁情况,没有发现在Employee表上面有锁,这是因为当前的隔离界别是READ COMMITTED

    --在执行完step2以后马上释放了S锁.

    SELECT request_session_id, resource_type, resource_associated_entity_id,

        request_status, request_mode, resource_description

        FROM sys.dm_tran_locks

查看锁的情况如下图所示,我们发现在只有在数据库级别的S锁,而没有在表级别或者更低级别的锁,这是因为在Read Committed级别下,S锁在语句执行完以后就被释放。

 

query2:事务2

--step6:开启第二个事务BEGIN TRAN tran2;

    --step7:修改VacationHours,需要获得排它锁X,在VacationHours上没有有S锁

    UPDATE Employee 

        SET VacationHours = VacationHours - 8  

        WHERE EmployeeID = 4;

    --step8:查看当前加锁情况

    SELECT request_session_id, resource_type, resource_associated_entity_id,

        request_status, request_mode, resource_description

        FROM sys.dm_tran_locks

在开启另外一个update事务以后,我们再去查看当前的锁状况,如下图所示,我们发现在表(Object)级别上加了IX锁,在这张表所在的Page上也加了IX锁,因为表加了聚集索引,所以在叶子结点上加了X锁,这个锁的类型是KEY。

 

然后我们回到事务1当中再次执行查询语句,我们会发现查询被阻塞,我们新建一个查询query3来查看这个时候的锁状况,其查询结果如下,我们可以 发现查询操作需要在KEY级别上申请S锁,在Page和表(Object)上面申请IS锁,但是因为Key上面原先有了X锁,与当前读操作申请的S锁冲 突,所以这一步处于WAIT状态。

 

如果此时提交事务2的update操作,那么事务1的select操作不再被阻塞,得到查询结果,但是我们发现此时得到的查询结果与第一次得到的查询结果不同,这也是为什么将read committed称为不可重复读,因为同一个事物内的两次相同的查询操作的结果可能不同。

REPEATABLE READ

REPEATABLE READ是比READ COMMITTED限制性更强的隔离级别。该级别包括READ COMMITTED,并且另外指定了在当前事务提交之前,其他任何事务均不可以修改或删除当前事务已读取的数据。并发性低于 READ COMMITTED,因为已读数据的共享锁在整个事务期间持有,而不是在每个语句结束时释放。比如,事务1读取了一行,事务2想修改或者删除这一行并且提交,但是因为事务1尚未提交,数据行中有事务1的锁,事务2无法进行更新操作,因此事务2阻塞。如果这时候事务1想再一次读取这一行,它读取结果与第一次读取结果相同,因此叫可重复读。

实验2

query1:事务1

--step1:创建实验数据select * into Employee from AdventureWorks.HumanResources.Employeealter table Employee add constraint pk_Employee_EmployeeID primary key(EmployeeID)

--step2:设置隔离级别SET TRANSACTION ISOLATION LEVEL REPEATABLE READ

--step3:开启第一个事务BEGIN TRAN tran1

    --step4:执行select操作,查看VacationHours

    SELECT EmployeeID, VacationHours

        FROM Employee 

        WHERE EmployeeID = 4;

    --step5:查看当前加锁情况,发现在Employee表上面有S锁,这是因为当前的隔离界别是REPEATABLE READ

    --S锁只有在事务执行完以后才会被释放.

    SELECT request_session_id, resource_type, resource_associated_entity_id,

        request_status, request_mode, resource_description

        FROM sys.dm_tran_locks

查询锁状态的结果如下图所示,我们发现在KEY上面加了S锁,在Page和Object上面加了IS锁,这是因为在Repeatable Read级别下S锁要在事务执行完以后才会被释放。

 

 query2:事务2

--step6:开启第二个事务BEGIN TRAN tran2;

    --step7:修改VacationHours,需要获得排他锁X,在VacationHours上有S锁,出现冲突,所以update操作被阻塞

    UPDATE Employee 

        SET VacationHours = VacationHours - 8  

        WHERE EmployeeID = 4;

执行上述update操作的时候发现该操作被阻塞,这是因为update操作要加排它锁X,而因为原先的查询操作的S锁没有释放,所以两者冲突。我们新建一个查询3执行查询锁状态操作,发现结果如下图所示,我们可以发现是WAIT发生在对KEY加X锁的操作上面。

 

此时再次执行查询1中的select操作,我们发现查询结果跟第一次相同,所以这个叫做可重复读操作。但是可重复读操作并不是特定指两次读取的数据 一模一样,Repeatable Read存在的一个问题是幻读,就是第二次读取的数据返回的条目数比第一次返回的条目数更多。

比如在Repeatable Read隔离级别下,事务1第一次执行查询select id from users where id>1 and id <10,返回的结果是2,4,6,8。这个时候事务1没有提交,那么对2,4,6,8上面依然保持有S锁。此时事务2执行一次插入操作insert into user(id) valuse(3),插入成功。此时再次执行事务1中的查询,那么返回结果就是2,3,4,6,8。这里的3就是因为幻读而出现的。因此可以得出结论:REPEATABLE READ隔离级别保证了在相同的查询条件下,同一个事务中的两个查询,第二次读取的内容肯定包换第一次读到的内容。

SERIALIZABLE 

SERIALIZABLE 是限制性最强的隔离级别,因为该级别锁定整个范围的键,并一直持有锁,直到事务完成。该级别包括REPEATABLE READ,并增加了在事务完成之前,其他事务不能向事务已读取的范围插入新行的限制。比如,事务1读取了一系列满足搜索条件的行。事务2在执行SQL statement产生一行或者多行满足事务1搜索条件的行时会冲突,则事务2回滚。这时事务1再次读取了一系列满足相同搜索条件的行,第二次读取的结果和第一次读取的结果相同。

重复读与幻读

重复读是为了保证在一个事务中,相同查询条件下读取的数据值不发生改变,但是不能保证下次同样条件查询,结果记录数不会增加。

幻读就是为了解决这个问题而存在的,他将这个查询范围都加锁了,所以就不能再往这个范围内插入数据,这就是SERIALIZABLE 隔离级别做的事情。

隔离级别与锁的关系

1.      在Read Uncommitted级别下,读操作不加S锁;

2.      在Read Committed级别下,读操作需要加S锁,但是在语句执行完以后释放S锁;

3.      在Repeatable Read级别下,读操作需要加S锁,但是在事务提交之前并不释放S锁,也就是必须等待事务执行完毕以后才释放S锁。

4.      在Serialize级别下,会在Repeatable Read级别的基础上,添加一个范围锁。保证一个事务内的两次查询结果完全一样,而不会出现第一次查询结果是第二次查询结果的子集。

using语句的作用

1、  引用命名空间,这样可以在程序中引用命名空间的类型而不必指定详细的命名空间.

2、  为命名空间或类型创建别名。例:Using ADO = System.Data.SqlClient;

3、  指定使用资源的对象释放资源.using语句中使用的对象必须实现IDisposable接口.此接口提供了Dispose方法,该方法将释放此对象的资源.例:Using(SqlConnection cn = new SqlConnection(SqlConnectionString)){......}

Assembly.Load()方法,Assembly.LoadFrom()方法,Assembly.LoadFile()方法的区别

Assembly.Load() 方法通过程序集的长名称来加载程序集的,会加载此程序集引用的其他程序集,一般情况下都应该优先使用 这个方法,他的执行效率比LoadFrom要高很多,而且不会造成重复加载的问题

Assembly.LoadFrom()方法从指定的路径来加载程序集,实际上这个方法被调用的时候,CLR会打开这个文件,获取其中的程序集版本,语言文化,公钥标记等信息,把他们传递给 Load方法,接着,Load方法采用上面的策略来查找程序集。

Assembly.LoadFile()方法是从指定的文件来加载程序集,和上面方法的不同之处是这个方法不会加载此程序集引用的其他程序集!

error和exception有什么区别?

error 表示恢复不是不可能但很困难的情况下的一种严重问题。

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

什么是View视图,何时应用?

视图是一个虚拟表,其是存储在数据库中的查询的SQL语句。视图中的数据是在被引用时动态生成的。

使用时可以基于以下情况:

1 需要隐藏一些数据时

2 需要从一个或多个表导出数据

3 安全性

存储过程的优点

1.创建一次,多次调用。

2.更快执行,如果某操作需要执行大量SQL语句或重复执行,存储过程比SQL语句执行要快。

3.减少网络流量,例如一个需要数百行的SQL代码的操作有一条执行语句完成,不需要在网络中发送数百行代码。

4.更好的安全机制,对于没有权限执行存储过程的用户,也可授权他们执行存储过程。

C#静态构造与普通构造的区别

    public class A

    {

        static A(){Console.WriteLine("static A");}

        public A(){Console.WriteLine("A");}

    }

    public class B : A

    {

        static B(){Console.WriteLine("static B");}

        public B(){Console.WriteLine("B");}

    }

    请写出var b = new B();,输出结果

 

Linq延迟加载

1、延迟加载:在查询某对象时,实际上你只查询该对象。不会同时自动获取这个对象。

其优点是你可以使用Linq延迟加载特性,将检索操作延迟到你确实需要检索的时候再进行。

var custs = from c in db.Customers where c.City == "Sao Paulo" select c; 

//上句查询句法不会导致语句立即执行,仅仅是一个描述性的语句

//只有需要使用其的时候才会真正被执行,如下句

foreach (var cust in custs) {...}

2、不延迟加载

有时我们想同步查询出对象的结果集合。

我们可以使用以下两个方法:

LoadWith 方法,用于立即加载与主目标相关的数据。

AssociateWith 方法,用于筛选为特定关系检索到的对象。

Web.Config中的重要结点

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

System.web        系统配置

compilation 动态调试编译设置

customErrors      自定义错误信息设置

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

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

应用程序域

.NET建立的可执行程序 *.exe,并没有直接装载到进程当中,而是装载到应用程序域(AppDomain)当中。

应用程序域是.NET的一个新概念,它比进程所占用的资源要少,可以被看作是一个轻量级的进程。

一个进程中可以包含多个应用程序域,一个应用程序域可以装载一个可执行程序(*.exe)或者多个程序集(*.dll)。

这样可使应用程序域之间实现深度隔离,即使进程中的某个应用程序域出现错误,也不会影响其他应用程序域的正常运作。

应用程序域:

应用程序域为安全性、可靠性、版本控制以及卸载程序集提供了隔离边界。应用程序域通常由运行库宿主创建,运行库宿主负责在运行应用程序之前引导公共语言运行库。应用程序域提供了一个更安全、用途更广的处理单元,公共语言运行库可使用该单元提供应用程序之间的隔离。

托管代码:

    使用基于公共语言运行库的语言编译器开发的代码称为托管代码;托管代码具有许多优点,例如:跨语言集成、跨语言异常处理、增强的安全性、版本控制和部署支持、简化的组件交互模型、调试和分析服务等。

强类型:

    C# 是强类型语言;因此每个变量和对象都必须具有声明类型。

  装箱和拆箱:装箱和拆箱使值类型能够被视为对象。对值类型装箱将把该值类型打包到 Object 引用类型的一个实例中。这使得值类型可以存储于垃圾回收堆中。拆箱将从对象中提取值类型。

重载:

    每个类型成员都有一个唯一的签名。方法签名由方法名称和一个参数列表(方法的参数的顺序和类型)组成。只要签名不同,就可以在一种类型内定义具有相同名称的多种方法。当定义两种或多种具有相同名称的方法时,就称作重载。

CTS通用类型系统 (common type system) :

    一种确定公共语言运行库如何定义、使用和管理类型的规范。

CLR公共语言运行库:

    .NET Framework 提供了一个称为公共语言运行库的运行时环境,它运行代码并提供使开发过程更轻松的服务。

CLS公共语言规范:

要和其他对象完全交互,而不管这些对象是以何种语言实现的,对象必须只向调用方公开那些它们必须与之互用的所有语言的通用功能。为此定义了公共语言规范 (CLS),它是许多应用程序所需的一套基本语言功能。

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

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

GAC是什么?

GAC的全称叫做全局程序集缓存,通俗的理解就是存放各种.net平台下面需要使用的dll的地方。GAC的具体目录在windows/ assembly。

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

    (1)点对点(P2P)的电子商务模型。用XML 定义企业之间交换的信息,然后用XML消息直接进行信息的饿交换,这种方式是对传统电子数据交换EDI(Electronic Data Exchange)的直接扩展。典型应用有微软的Biztalk框架。

    (2)基于代理(agent)的电子商务模型。在点对点模型的基础上,增加一个代理程序。代理程序作用就是自动在网络上找到有用的信息,并将起转发到本企业的数据库。典型应用有CommerceNet的eCo架构。

    (3)机遇门户(portal)的电子商务模型。企业将各种不同的信息发布到相应的门户上,然后各自根据自己的需求到不同的门户上寻找到企业感兴趣的信息。另外,各门户还可以实现信息的共享和互联,具有很大的扩展性。

(4)基于web服务的电子商务模型。Web服务是一种基于标准的应用集成方式,它可以将运行在通过Intranet、Extranet或Internet连接的分布式服务器上的应用集成在一起。也就是通过互联网的开放标准,实现业务流程的导航、搜索以及与其他应用的交互。典型应用有基于XML技术和标准的ebXML技术框架

Foreach遍历访问的对象需要实现什么接口或声明什么方法的类型。

    实现接口IEnumerator及声明 GetEnumerator 方法的类型

实现以下功能,左键点击页面时显示“您好”,右键点击时显示“禁止右键”。并在2分钟后自动关闭窗口。

    

ASP.NET MVC 与WebFrom的区别

    ASP.NET MVC无控件方式开发,其基于mvc设计模式,由微软提供的开发框架,主要由三部分构成Controller、View、Model

    Controller主要实现中间调度,业务实现。View实现界面呈现

    Model完成数据仓储任务

    WebFrom主要是基于控件开发,使用WebControl完成网页开发工作。

转载于:https://www.cnblogs.com/flms/p/9566024.html

你可能感兴趣的:(c#,操作系统,memcached)