回答1:接口能夠繼承接口,並且能夠繼承多個接口,用「,」進行分割,接口不容許直接或間接地從自身繼承。和類的繼承類似,接口的繼承也造成接口之間的層次結構javascript
回答2:抽象類是能夠實現接口的,抽象類裏能夠有抽象方法,也能夠有具體的實現方法,也就是說繼承了接口後也是能夠實現接口裏定義的方法
參考文章:html
修飾訪問符這個算是挺基礎的了,不過也不能忘記哦前端
參考文章:
1.訪問修飾符(C# 編程指南)java
全局變量和靜態變量的存儲是放在一塊的,初始化的全局變量和靜態變量在一塊區域, 未初始化的全局變量和未初始化的靜態變量在相鄰的另外一塊區域。 當類首次被加載時static定義的變量被分配空間,程序結束後由系統釋放.
若是在一個程序裏過多的使用static定義的成員,確實很佔內存,由於他的生命週期是整個程序,程序運行時沒法被gc所回收,直到程序結束,釋放內存.jquery
參考文章:web
這題我tm面試的幾間都有啊,公司得有多懶sql
答案:會執行,在return後執行數據庫
參考文章:編程
this 關鍵字引用類的當前實例,還可用做擴展方法的第一個參數的修飾符。
用途:
public Employee(string name, string alias) { // Use this to qualify the fields, name and alias: this.name = name; this.alias = alias; }
CalcTax(this);
public int this[int param] { get { return array[param]; } set { array[param] = value; } }
參考文章:
this(C# 參考)
這個要詳細講的話得要一本書吧,我就說大概。ASP.NET MVC包含了三部分,Model,View和Controller。Controller負責後臺邏輯代碼,View是純淨的HTML頁面,Model是中間數據層。
前提固然是要搞懂這二者的聯繫了
三層架構是最基本的項目分層結果,而MVC則是三層架構的一個變體,MVC是一種好的開發模式。
首先你要明白MVC分別表明的是什麼意思.
三層:UI 界面層 BLL 業務邏輯層,DAL數據訪問層,Model 實體層
MVC中的的M 不是三層中的Model(實體層),他其實包括三層中的 BLL,DAL,Model,這是很是要注意的,這也是他們之間的區別的關鍵所在
三層是基於業務邏輯來分的,而mvc是基於頁面來分的
MVC是 Model-View-Controller,嚴格說這三個加起來之後纔是三層架構中的WEB層,也就是說,MVC把三層架構中的WEB層再度進行了分化,分紅了控制器、視圖、實體三個部分,控制器完成頁面邏輯,經過實體來與界面層完成通話;而C層直接與三層中的BLL進行對話
參考文章:
關於AOP,它面向的是一個切面,可以把公共的功能抽出來,獨立開發,而後將公共部分實現,在開發人員不知情的狀況下,添加進去。而在MVC前臺框架中,MVC中Controller中的Filter能夠將公共的代碼抽離出來。
Asp.Net MVC提供瞭如下幾種默認的Filter:
Filter Type | 實現接口 | 執行時間 | Default Implementation |
---|---|---|---|
Authorization filter | IAuthorizationFilter | 在全部Filter和Action執行以前執行 | AuthorizeAttribute |
Action filter | IActionFilter | 分別在Action執行以前和以後執行。 | ActionFilterAttribute |
Result filter | IResultFilter | 分別在Action Result執行以後和以前 | ResultFilterAttribute |
Exception filter | IExceptionFilter | 只有在filter,或者 action method, 或者 action result 拋出一個異常時候執行 | HandleErrorAttribute |
參考文章:
微軟官方提供的ORM工具,ORM讓開發人員節省數據庫訪問的代碼時間,將更多的時間放到業務邏輯層代碼上。EF提供變動跟蹤、惟一性約束、惰性加載、查詢事物等。開發人員使用Linq語言,對數據庫操做如同操做Object對象同樣省事。
EF有三種使用場景,
ORM 是將數據存儲從域對象自動映射到關係型數據庫的工具。ORM主要包括3個部分:域對象、關係數據庫對象、映射關係。ORM使類提供自動化CRUD,使開發人員從數據庫API和SQL中解放出來。
DbContext是EntityFramework很重要的部分,鏈接域模型與數據庫的橋樑,是與數據庫通訊的主要類。
DbContext主要負責如下活動:
參考文章:
有三種方式:Code First、DBFirst、Model First
//Querying with LINQ to Entities using (var context = newSchoolDBEntities()) { var L2EQuery = context.Students.where(s => s.StudentName == "Bill"); var student = L2EQuery.FirstOrDefault<Student>(); } LINQ Query syntax: using (var context = new SchoolDBEntities()) { var L2EQuery = from st in context.Students where st.StudentName == "Bill"select st; var student = L2EQuery.FirstOrDefault<Student>(); }
//Querying with Object Services and Entity SQL string sqlString = "SELECT VALUE st FROM SchoolDBEntities.Students " + "AS st WHERE st.StudentName == 'Bill'"; var objctx = (ctx as IObjectContextAdapter).ObjectContext; ObjectQuery<Student> student = objctx.CreateQuery<Student>(sqlString); Student newStudent = student.First<Student>(); //使用EntityDataReader using (var con = newEntityConnection("name=SchoolDBEntities")) { con.Open(); EntityCommand cmd = con.CreateCommand(); cmd.CommandText = "SELECT VALUE st FROM SchoolDBEntities.Students as st where st.StudentName='Bill'"; Dictionary<int, string> dict = newDictionary<int, string>(); using (EntityDataReader rdr = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.CloseConnection)) { while (rdr.Read()) { int a = rdr.GetInt32(0); var b = rdr.GetString(1); dict.Add(a, b); } } }
using (var ctx = newSchoolDBEntities()) { var studentName = ctx.Students.SqlQuery("Select studentid, studentname, standardId from Student where studentname='Bill'").FirstOrDefault<Student>(); }
提及題,咱們不禁得會想到幾個名詞:棧和堆,值類型和引用類型,裝箱和拆箱。
這些概念但是C#的入門基礎呀,我們仍是要搞懂的,詳細能夠查看參考文章。
這裏要提下一個知識點:C#新手都有一個誤區:值類型的值都是保存在棧裏,實際應該是:值類型的值是在它聲明的位置存儲的。即局部變量(參數)的值會在棧裏,而當值類型做爲引用類型的類型成員的話,會跟隨對象,即存儲在託管堆裏。
順便提供幾張經典圖片便於讀者理解:
最後在這些概念裏,我以爲比較重要的精華提要:
參考文章:
最普通的用法固然就是:
效率上:s.Length == 0 > s == string.Empty > s == ""
不過 net 2.0後,可用String.IsNullOrEmpty(s) 來進行判斷
參考文章:
String.IsNullOrWhiteSpace和String.IsNullOrEmpty的區別
關於lock的介紹就到這裏,有下面幾點須要注意的地方
還有摘自本篇評論的精彩回覆:
this 表示的就是當前實例,當你再new一個的時候,鎖定的就再也不是同一個對象了。 不能鎖定值類型的緣由是,當這個值類型傳遞到另外一個線程的時候,會建立一個副本,鎖定的也再也不是同一個對象了。 鎖定字符串帶來的問題是,字符串在CLR中會暫存在 內存中,若是有兩個變量被分配了相同的字符串內容,那麼這兩個引用會指向同一塊內存,實際鎖定也就是同一個對象,這就會致使整個應用程序的阻塞。因此鎖定字符串是很是危險的行爲。
參考文章:
1.[C#基礎]說說lock到底鎖誰?](http://www.cnblogs.com/wolf-sun/p/4209521.html)
這篇已經有提過了:請參閱:最近找工做面的面試題目彙總(一)
參考文章:
爲了將方法聲明爲能夠接受可變數量參數的方法,咱們可使用params關鍵字來聲明數組
要求:
參考文章:
string url=Request.Url.ToString();
參考文章:
這個我就不說了。 ?:
Queue是先進先出(first in first-out)數據結構,表示放進queue的第一個數據,會是第一個拿出來使用
示例:
//創建Queue的對象 var myqueue = new Queue<string>(); //新增數據進入queue myqueue.Enqueue("第1個"); myqueue.Enqueue("第2個"); myqueue.Enqueue("第3個"); //查看queue的全部資料 foreach (string queue in myqueue) { Console.WriteLine(queue); } //使用Peek()方法查看queue裏的第一條數據 Console.WriteLine(""); Console.WriteLine("使用peek方法的輸出值:" + myqueue.Peek()); //使用Dequeue()方法從queue中拿出值 //記得是先進先出的獲取方法 Console.WriteLine("第一個被我拿走了:" + myqueue.Dequeue()); //查看剩下的值 Console.WriteLine("查看myqueue剩下的值"); foreach (string queue in myqueue) { Console.WriteLine(queue.ToString()); } //查看某位置的值 Console.WriteLine("查看特定位置的值"); Console.WriteLine(myqueue.ElementAt(1));
運行結果
第1個
第2個
第3個
使用peek方法的輸出值:第1個 第一個被我拿走了:第1個 查看myqueue剩下的值 第2個 第3個 查看特定位置的值 第3個 第3個 第2個 第1個 Peek看到的數據:第3個 被拿走了:第3個 查看剩下的數據 第2個 第1個
Stack爲後進先出(first-in last-out)的數據結構,表示第一個進去的數據,反而是最後一個出來。
示例代碼
//創建Stack對象 var mystack = new Stack<string>(); //插入數據 mystack.Push("第1個"); mystack.Push("第2個"); mystack.Push("第3個"); //查看數據 foreach(string stack in mystack) { Console.WriteLine(stack.ToString()); } //Stack與Queue同樣有Peek方法查看第一條數據 Console.WriteLine(""); Console.WriteLine("Peek看到的數據:"+mystack.Peek()); //使用Pop方法取出數據 Console.WriteLine("被拿走了:"+mystack.Pop()); Console.WriteLine("查看剩下的數據"); foreach (string stack in mystack) { Console.WriteLine(stack.ToString()); }
運行結果
第3個 第2個 第1個 Peek看到的數據:第3個 被拿走了:第3個 查看剩下的數據 第2個 第1個
參考文章:
重載應該叫overload,重載某個方法是在同一個類或父子關係類中發生的!重載(overload)是提供了一種機制, 相同函數名經過不一樣的返回值類型以及參數來表來區分的機制
overload: 同一類中或父子關係類中皆可.
public string ToString(){return "a";} public string ToString(int id){return id.ToString();}
重寫叫override,重寫是在子類中重寫父類中的方法。重寫(override)是用於重寫基類的虛方法,這樣在派生類中提供一個新的方法
override: 父類:public virtual string ToString(){return "a";} 子類:public override string ToString(){return "b";}
很本質的區別就是看函數特徵:覆寫(Override)的兩個函數的函數特徵相同,重載(Overload)的兩個函數的函數名雖然相同,但函數特徵不一樣。
參考文章:
## 9. using的意義
簡述:
提供能確保正確使用 IDisposable 對象的方便語法。它的用途就是清理非託管資源,不受GC控制的資源。Using結束後會隱式的調用Disposable方法
如下兩段代碼的做用是一致的
using (Font font1 = new Font("Arial", 10.0f)) { byte charset = font1.GdiCharSet; }
{
Font font1 = new Font("Arial", 10.0f); try { byte charset = font1.GdiCharSet; } finally { if (font1 != null) ((IDisposable)font1).Dispose(); } }
參考文章:
由於ArrayList存在不安全類型與裝箱拆箱的缺點,因此出現了泛型的概念。List類是ArrayList類的泛型等效類,它的大部分用法都與ArrayList類似,由於List類也繼承了IList接口。最關鍵的區別在於,在聲明List集合時,咱們同時須要爲其聲明List集合內數據的對象類型。
不能初始化的類被叫作抽象類,它們只提供部分實現,可是另外一個類能夠繼承它而且能建立它們
的實例。抽象類可以被用於類,方法,屬性,索引器和事件,使用abstract 在一個類聲明中表示該類傾向要做爲其它類的基類,成員被標示成abstract,或被包含進一個抽象類,必須被其派生類實現。
一個抽象類必須爲全部的接口成員提供實現
一個用於實現接口的抽象類可能把接口方法安排到抽象方法上。例如
interface I { void M(); } abstract class C: I { public abstract void M(); }
虛方法(virtual)和抽象方法(abstract)的區別
虛方法與非虛方法的最大不一樣是,虛方法的實現能夠由派生類所取代,這種取代是經過方法的重寫實現的。
//抽象方法 public abstract class Animal { public abstract void Sleep(); public abstract void Eat(); } //虛方法 public class Animal { public virtual void Sleep(){} public virtual void Eat(){} }
public class Animal { public abstract void Sleep(); public abstract void Eat(); }
編譯器會報錯:
Main.cs(10): 'VSTest.Animal.Sleep()' is abstract but it is contained in nonabstract class 'VSTest.Animal'
Main.cs(11): 'VSTest.Animal.Eat()' is abstract but it is contained in nonabstract class 'VSTest.Animal'
public abstract class Animal { public abstract void Sleep(); public abstract void Eat(); } public class Cat : Animal { public override void Sleep() { Console.WriteLine( "Cat is sleeping" ); } // we need implement Animal.Eat() here }
編譯器會報錯:Main.cs(14): 'VSTest.Cat' does not implement inherited abstract member 'VSTest.Animal.Eat()'
由於咱們沒有實現抽象類中全部抽象方法。
它不屬於類的某一個具體的實例,而是屬於類自己。因此對靜態方法不須要首先建立一個類的實例,而是採用類名.靜態方法的格式 。
static方法是類中的一個成員方法,屬於整個類,即不用建立任何對象也能夠直接調用!
static內部只能出現static變量和其餘static方法!並且static方法中還不能使用this....等關鍵字..由於它是屬於整個類!
C#中的方法有兩種:實例方法,靜態方法.
靜態方法中用:
string className = System.Reflection.MethodBase. GetCurrentMethod().ReflectedType.FullName;
非靜態方法中還能夠用:
string className = this.GetType().FullName;
定義:靜態構造函數用於初始化任何 靜態 數據,或用於執行僅需執行一次的特定操做。 在建立第一個實例或引用任何靜態成員以前,將自動調用靜態構造函數。
靜態構造函數具備如下特色:
儘可能避免使用繼承來實現組建功能,而是使用黑箱複用,即對象組合。由於繼承的層次增多,形成最直接的後果就是當你調用這個類羣中某一類,就必須把他們所有加載到棧中!後果可想而知。(結合堆棧原理理解)。同時,有心的朋友能夠留意到微軟在構建一個類時,不少時候用到了對象組合的方法。好比 asp.net中,Page類,有Server Request等屬性,但其實他們都是某個類的對象。使用Page類的這個對象來調用另外的類的方法和屬性,這個是很是基本的一個設計原則;
若是抽象類實現接口,則能夠把接口中方法映射到抽象類中做爲抽象方法而沒必要實現,而在抽象類的子類中實現接口中方法。
如下是我在網上看到的幾個形象比喻。
1.飛機會飛,鳥會飛,他們都繼承了同一個接口「飛」;可是F22屬於飛機抽象類,鴿子屬於鳥抽象類;
2. 就像鐵門木門都是門(抽象類),你想要個門我給不了(不能實例化),但我能夠給你個具體的鐵門或木門(多態);並且只能是門,你不能說它是窗(單繼承),一個門能夠有鎖(接口)也能夠有門鈴(多實現)。門(抽象類)定義了你是什麼,接口(鎖)規定了你能作什麼(一個接口最好只能作一件事,你不能要求鎖也能發出聲音吧(接口污染))。
學習閉包:
(2).javascript的閉包
(3).圖解閉包