注:本篇文章很多并没有给出具体答案,因为每一个问题点都可以摊开讲许多相关联内容,其实最终还是需要我们自已去理解和实践,只有理解了其中本质才不会去做一个重复工作的程序员。写代码的时候时候都需要多问自已为什么要这种方式,它后面的实现原理是什么,这样自己会提高的非常快。水平有限,文章中若有不对之处,请园友指正。
One:数据库篇
一、SQLSERVER视图包括:
1、普通视图
2、索引视图(对应ORACLE中是物化视图)
主要用于多表连接、表自身多次连接的情况,并有数据运算逻辑时,可用索引视图。
缺点:会带来性能的消耗,由于是真实表的物理镜像,所以会导致物理表发生改变时会同步索引视图。
3、分割视图
二、事务(ACID)
A:原子性,C:一致性,I:隔离性,D:持久性
所有SQL Insert/Delete/Update/Query都是基于事务处理的,非显示指定Begin Tran,也执行了事务
事务SQL语法
Begin Tran
select * from Tpage
if @@ERROR >0
rollback tran
else
commit tran
三、索引
1、索引基础知识(图例引用自CareySon大神博客)
索引是以B树存储,数据以页存储,页的大小为8KB。删除聚集索引会导致所有非聚集索引重建。
索引分为聚集索引和非聚集索引。
聚集索引为在物理上有序排列,占用实际磁盘空间并且当插入或删除行时会引起磁盘中物理顺序重新排列。导致性能的消耗。
可以将非聚集索引放到另一磁盘空间,以减少一个磁盘的IO消耗。
2、索引碎片
当数据量增长或是其它原因(索引列选择不当)导致索引碎片增加,碎片增加后影响索引性能,此时需要重新建立索引,以提高性能
3、锁和锁的粒度
锁 lock
查询不加锁nolock,存在问题:会读取到脏数据,具体使用场景看业务逻辑
two:asp.net
1、接口和抽象类的区别
对于公用的实现代码,抽象类能够保证实现的层次关系,避免代码重复。(如DbHelper操作类)。接口定义行为能够更有效地分离行为与实现,为代码的维护和修改带来方便。
2、SESSION&END事件
Session需要知道的是什么是SessionID,SessionID是什么是时候产生,保存在哪里?
Session存储于数据库时,是不会触发Session_end事件的,那这时服务器如何知道客户端已断开连接了呢?我们可以通过心跳的方式来确认当前用户的状态。
3、禁用COOKIE后是否能登录
不能,COOKIE的数据在HTTP请求时会一起发送至服务器,否则服务器无法识别当前用户。可以通过 IE F12 查看,每次请求都提交了哪些内容。
4、浏览器中登录网页后,再新开一个窗口(注:同一会话中),服务器如何知道这两个网页的请求来自同一个客户?
由于HTTP是无状态的,无法知道两次访问是否为同一用户,所以在HTTP请求时,同时发送了SessionID至服务器,用于标识身份。
5、如何实现单点登录
要点:首先了解SSO,以及了解如何解决单点登录之后的退出,同原系统的兼容,跨站点域名访问等等。
6、堆和栈的区别
建议查看这篇文章
http://www.c-sharpcorner.com/UploadFile/rmcochran/csharp_memory01122006130034PM/csharp_memory.aspx
7、MVC Controller 如何自定议实现构造有参构造函数?Controller是什么时候初始化的?
感谢@刘慧烽为本题提供答案。如何自定义构造函数请查看此文章:
8、MVC依赖注入?
依赖注入为解决多层之间的藕合,通过接口实现多态的方法。
基本思想是,分离可变部分和不可变部分的业务,将不可变业务单独抽出来,待以后需要添加新的属性时,此业务不需要改变。
依赖注入+反射:可以实现当前不存在实例的动态添加。
9、Cache
可以查看我写的这篇文章:http://www.cnblogs.com/vinzhou/p/4418108.html
10、List[1]和String[1]哪个读取更快
(不知道哇,园友帮帮忙解答下,感谢啊!)
本题感谢园友(@刘慧烽 @Loui @浩GE @Kevin.Choi @KMSFan)参与的讨论。我通过查询网上文章和查看Reflect,个人理解得出的结论是(仅仅在讨论当前题目的前提下)它们的速度是一样快的,欢迎讨论。
//前提:本题只讨论lst1[1]和arr1[1]读取哪个快,而不讨论数组的插入、删除、修改操作 //初始化后两个对象如下 List<string> lst1 = new List<string>() { "A", "B", "C" }; string[] arr1 = new string[] { "A", "B", "C" };
理由:通过Reflect的查看,它们仅仅的区别是List[1] 比string[1]仅仅是多了一句代码 this._items[index];而_items其实就是一个 string[]数组。
具体还是通过查看以下Reflect代码吧:
string[]继承于Array,那么我们先看Array是如何通过索引获取数据的,以下为Array获取 this[int index] 代码
//string[1]调用的代码为 GetValue(index)方法
[__DynamicallyInvokable] object IList.this[int index] { [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get { return this.GetValue(index); } [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] set { this.SetValue(value, index); } } |
//以下为GetValue(index)方法实现
[SecuritySafeCritical, __DynamicallyInvokable] public unsafe object GetValue(int index) { if (this.Rank != 1) { throw new ArgumentException(Environment.GetResourceString("Arg_Need1DArray")); } TypedReference reference = new TypedReference(); this.InternalGetReference((void*) &reference, 1, &index); return TypedReference.InternalToObject((void*) &reference); } |
List<T>属于 System.Collections.Generic 命名空间下,而List[1]调用的方法为
[__DynamicallyInvokable]
public T this[int index] { [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable] get; [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable] set; }
我们查看 T this[int index]方法的实现
//List[1]调用的代码
[__DynamicallyInvokable] public T this[int index] { [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable] get { if (index >= this._size) { ThrowHelper.ThrowArgumentOutOfRangeException(); } return this._items[index]; } [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable] set { if (index >= this._size) { ThrowHelper.ThrowArgumentOutOfRangeException(); } this._items[index] = value; this._version++; } } |
//items的定义为T[]数组
private T[] _items; |