整個內容是我在春招面試時候整理的一些題目,裏面涵蓋有網上搬運的(因爲當時沒有記錄來源,若是有轉載沒標註來源,請與我聯繫),還有我面試到的。整個排版很亂,後期我會一步一步整理。整個內容大概快有兩萬字。整理的過程也是自我知識體系梳理的過程,但願能獲得知識體系知識的提高。php
修改記錄:css
2020/4/19 修改1~4html
1、基礎知識前端
1 簡單名詞解釋java
OOP:面向對象編程。面向過程能夠理解成工廠裏的流水線,封裝的方式是按數據處理的流程。而面向對象更像是對工人的描述。將工人的工做方式封裝成一個個的函數,而後讓程序進行調用。jquery
OOD:面向對象設計。程序員
OOA:面向對象分析。web
高內聚:指一個軟件模塊是由相關性很強的代碼組成,只負責一項任務,也就是常說的單一職責原則。面試
低耦合:簡單理解,一個完整的系統,模塊與模塊之間,儘量的使其獨立存在。讓每個模塊儘量獨立完成某個特定的子功能。ajax
面向對象的好處:
(1)下降耦合。每一個功能分裝成相應的類,下降功能之間代碼上聯繫。
(2)提升可維護性。
2 封裝
封裝的優勢:
(1)即隱藏對象的屬性和實現細節,僅對外公開接口,控制在程序中屬性的讀和修改的訪問級別;將抽象獲得的數據和行爲(或功能)相結合,造成一個有機的總體,也就是將數據與操做數據的源代碼進行有機的結合,造成「類」,其中數據和函數都是類的成員
(2)設計類時,不但願直接存取類中的數據,而是但願經過方法來存取數據。這樣就能夠達到封裝數據的目的,方便之後的維護升級,也能夠在操做數據時多一層判斷。
(3)封裝還能夠解決數據存取的權限問題,能夠使用封裝將數據隱藏起來,造成一個封閉的空間,而後能夠設置哪些數據只能在這個空間中使用,哪些數據能夠在空間外部使用。一個類中包含敏感數據,有些人能夠訪問,有些人不能訪問,若是不對這些數據的訪問加以限制,後果將會很是嚴重。因此要對類的成員使用不一樣的訪問修飾符,從而定義他們的訪問級別。
(4)經過修改訪問修飾符實現
Public 數據類型 變量名 { get{return 變量名}//獲取數據 set{變量名=value;}//設置數據 }
使用封裝還能夠實現對屬性的只讀、只寫: public string Name { get; private set; }//只讀 public string Name { private get; set; }//只寫 這樣寫屬性時,編譯器會自動建立private string name。這種是會自動實現後備成員變量的自動實現屬性。 若是是: public string Name { get; set; } 這樣的沒有啥限定的屬性,其實和公有字段沒多大區別了。
3 繼承
繼承是面向對象最重要的特性之一。任何類均可以從另一個類繼承,這就是說,這個類擁有它繼承類的全部成員。在面向對象編程中,被繼承的類稱爲父類或基類。C#中提供了類的繼承機制,但只支持單繼承,而不支持多繼承,即在C#一次只容許繼承一個類,不能同時繼承多個類。
Public class 類名:父類名
如何使用父類裏面的成員變量,方法,構造函數?
關鍵字:base
成員變量:base.成員變量名
方法:base.方法名
4 多態
多態性意味着有多重形式。在面向對象編程範式中,多態性每每表現爲"一個接口,多個功能"。多態性能夠是靜態的或動態的。在靜態多態性中,函數的響應是在編譯時發生的。在動態多態性中,函數的響應是在運行時發生的。
4.1 靜態多態性:在編譯時,函數和對象的鏈接機制被稱爲早期綁定,也被稱爲靜態綁定。C# 提供了兩種技術來實現靜態多態性。
(1)方法重載:能夠在同一個範圍內對相同的方法名有多個定義。方法的定義必須彼此不一樣,能夠是參數列表中的參數類型不一樣,也能夠是參數個數不一樣。不能重載只有返回類型不一樣的方法聲明。
(2) 運算符重載:能夠重定義或重載 C# 中內置的運算符
4.2 動態多態性:當有一個定義在類中的函數須要在繼承類中實現時,能夠使用虛方法。
4.2.1 虛方法(virtual)
(1)虛方法是使用關鍵字 virtual 聲明的。
(2)虛方法能夠在不一樣的繼承類中有不一樣的實現。
(3)對虛方法的調用是在運行時發生的。
(4)動態多態性是經過抽象類和虛方法實現的。
4.2.2 接口(Interface)
接口和抽象類差很少,區別在於,接口內包含的所有是未實現的方法。並且接口類和方法的關鍵詞不須要再聲明abstract,接口類的關鍵詞,interface,通常定義接口名稱,按照約定,咱們會在名稱前面加上一個I。例以下圖的打印機接口。
虛方法:virtual
虛方法存在於相對於須要實現多態的子類的父類當中,同時也是實現多態的最基本的方法。
具體語法:父類的方法,用virtual修飾,表示虛方法。繼承它的子類,在內部用override進行重寫。下面進行案例分析:
4.2.3 抽象方法和抽象類
然而若是父類中的方法徹底不知道去幹什麼(即方法體中沒有必要的代碼),必需要子類進行重寫纔有意義的話,這種狀況就須要使用抽象方法。說話,可是不一樣的人會說不一樣的話,這個時候就要用抽象類,先聲明能夠說話,可是不實現。
抽象方法和抽象類的關鍵字都是:abstract
若是父類的方法很抽象,並且沒有具體的do(作什麼)即方法體,必需要子類進行重寫纔有實際意義的話,這種狀況就須要用抽象方法了。
父類、子類及輸出:
C# 容許您使用關鍵字 abstract 建立抽象類,用於提供接口的部分類的實現。當一個派生類繼承自該抽象類時,實現即完成。抽象類包含抽象方法,抽象方法可被派生類實現。派生類具備更專業的功能。
請注意,下面是有關抽象類的一些規則:
您不能建立一個抽象類的實例。
您不能在一個抽象類外部聲明一個抽象方法。
經過在類定義前面放置關鍵字 sealed,能夠將類聲明爲密封類。當一個類被聲明爲 sealed 時,它不能被繼承。抽象類不能被聲明爲 sealed。
下面的程序演示了一個抽象類:
3.抽象方法的特色
(1)只有方法頭沒有方法體的方法稱之爲抽象方法。(即只有方法的聲明,沒有方法的實現)
(2)抽象方法用abstract關鍵字來修飾。
(3)抽象方法表明一種不肯定的操做或行爲。(由子類去具體實現)
(4)抽象方法不能被調用。
4.抽象類的特色
(1)定義中含有抽象方法的類叫作抽象類。
(2)抽象類用abstract關鍵字來修飾。
(3)抽象類表明一種抽象的對象類型。
(4)抽象類不能實例化。
(5)抽象類中能夠有具體方法,能夠沒有抽象方法。(也就是說一個類中只要有一個方法是抽象方法那麼這個類必定是抽象類,反過來,一個抽象類中能夠沒有抽象方法,能夠帶有具體
實現的方法)
(6)一旦一個類中有抽象方法,那麼這個類必須也要用abstract來修飾,表明這個類是抽象類,它是不能被實例化的。
抽象類是實現多態的方法之一,一個類被abstract標記的類叫抽象類。當父類的方法不知道如何去實現或者要把某個類抽象出來的時候,能夠考慮將父類寫成抽象類,將方法寫成抽象方法,抽象類的成員也必須標記abstract,即抽象類不必定包含抽象方法,但抽象方法所在的類必定是抽象類,而且不能有任何實現,也就是沒有方法體,抽象成員的訪問修飾符能夠不寫,若是寫,不能是private,實現父類抽象方法的方法的參數和返回值都要同樣;
定義虛方法:
訪問修飾符 virtual 返回的數據類型/void 方法名()
{
//執行代碼,也能夠徹底不寫
}
重寫父類的方法(子類中):
訪問修飾符 override 返回的數據類型
void 方法名()
{
//執行代碼
}
一、重載(overload): 在同一個做用域(通常指一個類)的兩個或多個方法函數名相同,參數列表不一樣的方法叫作重載,它們有三個特色(俗稱兩必須一能夠):
方法名必須相同
參數列表必須不相同
返回值類型能夠不相同
二、重寫(override):子類中爲知足本身的須要來重複定義某個方法的不一樣實現,須要用 override 關鍵字,被重寫的方法必須是虛方法,用的是 virtual 關鍵字。它的特色是(三個相同):相同的方法名、相同的參數列表、相同的返回值
二、虛方法:即爲基類中定義的容許在派生類中重寫的方法,使用virtual關鍵字定義。如:
3.抽象方法:在基類中定義的而且必須在派生類中重寫的方法,使用 abstract 關鍵字定義。如:
注意:抽象方法只能在抽象類中定義,若是不在抽象類中定義,則會報出以下錯誤:
··················
一、值類型與引用類型
值類型:struct、enum、int、float、char、bool、decimal
什麼是值類型:
進一步研究文檔,你會發現全部的結構都是抽象類型System.ValueType的直接派生類,而System.ValueType自己又是直接從System.Object派生的。根據定義所知,全部的值類型都必須從System.ValueType派生,全部的枚舉都從System.Enum抽象類派生,然後者又從System.ValueType派生。
全部的值類型都是隱式密封的(sealed),目的是防止其餘任何類型從值類型進行派生。
基於值類型的變量直接包含值。 [2] 將一個值類型變量賦給另外一個值類型變量時,將複製包含的值。這與引用類型變量的賦值不一樣,引用類型變量的賦值只複製對對象的引用,而不復制對象自己。
全部的值類型均隱式派生自SystemValueType。
引用類型:class、delegate、interface、array、object、string
在c#中全部的類都是引用類型,包括接口。
委託(Delegate)特別用於實現事件和回調方法。全部的委託(Delegate)都派生自 System.Delegate 類。
三、裝箱與拆箱https://www.cnblogs.com/zjtao/p/11345442.html
四、一種最普通的場景是,調用一個含類型爲Object的參數的方法,該Object可支持任意爲型,以便通用。當你須要將一個值類型(如Int32)傳入時,須要裝箱。
另外一種用法是,一個非泛型的容器,一樣是爲了保證通用,而將元素類型定義爲Object。因而,要將值類型數據加入容器時,須要裝箱。
裝箱:把值類型轉換成引用類型
拆箱:把引用類型轉換成值類型
裝箱:對值類型在堆中分配一個對象實例,並將該值複製到新的對象中。
(1)第一步:新分配託管堆內存(大小爲值類型實例大小加上一個方法表指針。
(2)第二步:將值類型的實例字段拷貝到新分配的內存中。
(3)第三步:返回託管堆中新分配對象的地址。這個地址就是一個指向對象的引用了。
拆箱:檢查對象實例,確保它是給定值類型的一個裝箱值。將該值從實例複製到值類型變量中。
在裝箱時是不須要顯式的類型轉換的,不過拆箱須要顯式的類型轉換。
1.1 隱式數值轉換
隱式數值轉換包括如下幾種:
●從sbyte類型到short,int,long,float,double,或decimal類型。
●從byte類型到short,ushort,int,uint,long,ulong,float,double,或decimal類型。
●從short類型到int,long,float,double,或decimal類型。
●從ushort類型到int,uint,long,ulong,float,double,或decimal類型。
●從int類型到long,float,double,或decimal類型。
●從uint類型到long,ulong,float,double,或decimal類型。
●從long類型到float,double,或decimal類型。
●從ulong類型到float,double,或decimal類型。
●從char類型到ushort,int,uint,long,ulong,float,double,或decimal類型。
●從float類型到double類型。
其中,從int,uint,或long到float以及從long到double的轉換可能會致使精度降低,但決不會引發數量上的丟失。其它的隱式數值轉換則不會
爲何要使用集合?
數組的侷限性:
(1)數組元素個數是固定的,數組一但定義,就沒法改變元素總數。若是需求變化,則必須修改源碼
(2)若是初始化元素總數很是大,則會形成空間浪費。
集合的特色:
(1)根據須要動態增長元素個數,沒有限制。
(2)能夠用以存儲多個對象,這是個十分重要的屬性。
List泛型集合的特色:
(1)表示泛型,T是Type的簡寫,表示當前不肯定具體類型。
(2)能夠根據用戶的實際須要,肯定當前集合須要存放的數據類型,一旦肯定不可改變。
List泛型使用前的準備工做:
(1)引入命名空間:System.Collections.Generic
(2)肯定存儲類型:List students = new List();
4堆和棧
五、棧是編譯期間就分配好的內存空間,所以你的代碼中必須就棧的大小有明確的定義,一般用於值類型;堆是程序運行期間動態分配的內存空間,你能夠根據程序的運行狀況肯定要分配的堆內存的大小
引用類型老是存放在堆中。
存放在棧中時要管存儲順序,保持着先進後出的原則,他是一片連續的內存域,有系統自動分配和維護;
堆是無序的,他是一片不連續的內存域,有用戶本身來控制和釋放,若是用戶本身不釋放的話,當內存達到必定的特定值時,經過垃圾回收器(GC)來回收。
棧內存無需咱們管理,也不受GC管理。當棧頂元素使用完畢,立馬釋放。而堆則須要GC清理。
使用引用類型的時候,通常是對指針進行的操做而非引用類型對象自己。可是值類型則操做其自己。
四、GC(Garbage Collection)
當程序須要更多的堆空間時,GC須要進行垃圾清理工做,暫停全部線程,找出全部無被引用的對象,進行清理,並通知棧中的指針從新指向地址排序後的對象。
GC只能處理託管內存資源的釋放,對於非託管資源則不能使用GC進行回收,必須由程序員手動回收,例如FileStream或SqlConnection須要調用Dispose進行資源的回收。
五、CLR(Common Language Runtime)
公共語言運行庫,負責資源管理(包括內存分配、程序及加載、異常處理、線程同步、垃圾回收等),並保證應用和底層操做系統的分離。
六、靜態構造函數
最早被執行的構造函數,且在一個類裏只容許有一個無參的靜態構造函數
執行順序:靜態變量>靜態構造函數>實例變量>實例構造函數
七、文件I/O
經過流的方式對文件進行讀寫操做
(1)FileStream
(2)StreamReader/StreamWriter
八、序列化與反序列化
序列化:將對象狀態轉換爲可保持或傳輸的格式的過程。將對象實例的字段及類的名稱轉換成字節流,而後把字節流寫入數據流。
經過序列化,能夠執行以下操做:經過 Web 服務將對象發送到遠程應用程序、在域之間傳遞對象、以 XML 字符串的形式傳遞對象經過防火牆、跨應用程序維護安全性或用戶專屬信息。
反序列化:將流轉換爲對象。
這兩個過程結合起來,能夠輕鬆地存儲和傳輸數據。
九、線程同步
(1)方法一:阻塞(調用Sleep()或Join())
(2)方法二:加互斥鎖lock
1 代碼重用,繼承類都能用抽象類定義的方法
2 靈活,某個繼承類既能夠繼承改方法也能夠派生一個新的
3 抽象類是全部繼承類通用方法的最小集合,能夠封裝某一個繼承類的實例用來進行傳遞
十、抽象類abstract class與接口interface的異同
相同點:
(1)均可以被繼承
(2)都不能被實例化
(3)均可以包含方法的聲明
不一樣點:
(1)抽象類被子類繼承;接口被類實現
(2)抽象類只能被單個類繼承;接口可繼承接口,並可多繼承接口
(3)抽象基類能夠定義字段、屬性、方法實現;接口只能定義屬性、索引器、事件、和方法聲明,不能包含字段
(4)抽象類能夠作方法聲明,也可作方法實現;接口只能作方法聲明
(5)具體派生類必須覆蓋(override)抽象基類的抽象方法;派生類必須實現接口的全部方法
(6)抽象類是一個不完整的類,須要進一步細化;接口是一個行爲規範
(7)抽象類中的虛方法或抽象方法必須用public修飾;接口中的全部成員默認爲public,不能有private修飾符(也不能用public進行顯示修飾)
1、
(1) 抽象方法只做聲明,抽象類能夠作方法聲明,也可作方法實現;接口只能作方法聲明
(2) 抽象類不能被實例化
(3) 抽象類能夠但不是必須有抽象屬性和抽象方法,可是一旦有了抽象方法,就必定要把這個類聲明爲抽象類
(4) 具體派生類必須覆蓋基類的抽象方法
(5) 抽象派生類能夠覆蓋基類的抽象方法,也能夠不覆蓋。若是不覆蓋,則其具體派生類必須覆蓋它們。如:
2、接 口
(1) 接口不能被實例化
(2) 接口只能包含方法聲明
(3) 接口的成員包括方法、屬性、索引器、事件
(4) 接口中不能包含常量、字段(域)、構造函數、析構函數、靜態成員。如:
十一、類class與結構體struct的異同
Class屬於引用類型,是分配在內存的堆上的;
Struct屬於值類型,是分配在內存的棧上的;不能從另一個結構或者類繼承,自己也不能被繼承;沒有默認的構造函數,可是能夠添加構造函數;能夠不使用new 初始化
十二、using關鍵字的使用場景
(1)做爲指令:用於導入其餘命名空間中定義的類型或爲命名空間建立別名
(2)做爲語句:用於定義一個範圍,在此範圍的末尾將釋放對象
1三、new關鍵字的使用場景
(1)實例化對象
(2)隱藏父類方法
(3)new約束指定泛型類聲明中的任何類型參數都必須具備公共的無參數構造函數
1四、委託與事件
委託能夠把一個方法做爲參數傳入另外一個方法,能夠理解爲指向一個函數的引用;
事件是一種特殊的委託。
1五、重載(overload)與重寫(override)的區別
重載:是方法的名稱相同,參數或參數類型不一樣;重載是面向過程的概念。
重寫:是對基類中的虛方法進行重寫。重寫是面向對象的概念。
1六、return執行順序
try{} 裏有一個return語句,那麼finally{} 裏的code在return前執行。
1七、switch(expression)
其中expression支持任何數據類型,包括null。
1八、反射Reflection
動態獲取程序集信息。
1九、property與attribute的區別
property是屬性,用於存取類的字段;
attribute是特性,用來標識類,方法等的附加性質。
20、訪問修飾符
(1)public 公有訪問,不受任何限制。
(2)private 私有訪問,只限於本類成員訪問。
(3)protected 保護訪問,只限於本類和子類訪問。
(4)internal 內部訪問,只限於當前程序集內訪問。
2一、static關鍵字的應用
對類有意義的字段和方法使用static關鍵字修飾,稱爲靜態成員,經過類名加訪問操做符「.」進行訪問; 對類的實例有意義的字段和方法不加static關鍵字,稱爲非靜態成員或實例成員。
注: 靜態字段在內存中只有一個拷貝,非靜態字段則是在每一個實例對象中擁有一個拷貝。而方法不管是否爲靜態,在內存中只會有一份拷貝,區別只是經過類名來訪問仍是經過實例名來訪問。
2三、值傳遞與引用傳遞
值傳遞時,系統首先爲被調用方法的形參分配內存空間,並將實參的值按位置一一對應地複製給形參,此後,被調用方法中形參值得任何改變都不會影響到相應的實參;
引用傳遞時,系統不是將實參自己的值複製後傳遞給形參,而是將其引用值(即地址值)傳遞給形參,所以,形參所引用的該地址上的變量與傳遞的實參相同,方法體內相應形參值得任何改變都將影響到做爲引用傳遞的實參。
簡而言之,按值傳遞不是值參數是值類型,而是指形參變量會複製實參變量,也就是會在棧上多建立一個相同的變量。而按引用傳遞則不會。能夠經過 ref 和 out 來決定參數是否按照引用傳遞。
2四、參數傳遞 ref 與 out 的區別
(1)ref指定的參數在函數調用時必須先初始化,而out不用
(2)out指定的參數在進入函數時會清空本身,所以必須在函數內部進行初始化賦值操做,而ref不用
總結:ref能夠把值傳到方法裏,也能夠把值傳到方法外;out只能夠把值傳到方法外
注意:string做爲特殊的引用類型,其操做是與值類型看齊的,若要將方法內對形參賦值後的結果傳遞出來,須要加上ref或out關鍵字。
3、數據庫
http://www.javashuo.com/article/p-ywfrehrb-kq.html
通用數據庫鏈接流程
第一,使用SqlConnection對象鏈接數據庫;
第二,創建SqlCommand對象,負責SQL語句的執行和存儲過程的調用;
第三,對SQL或存儲過程執行後返回的「結果」進行操做。
對返回「結果」的操做能夠分爲兩類:
一是用SqlDataReader直接一行一行的讀取數據集;
二是DataSet聯合SqlDataAdapter來操做數據庫。
經常使用方法:
command.ExecuteNonQuery(): 返回受影響函數,如增、刪、改操做;
command.ExecuteScalar():執行查詢,返回首行首列的結果;
command.ExecuteReader():返回一個數據流(SqlDataReader對象)。
六、DataSet對象
6.1 SqlDataAdapter;
命名空間:System.Data.SqlClient.SqlDataAdapter;
SqlDataAdapter是SqlCommand和DataSet之間的橋樑,實例化SqlDataAdapter對象:
SqlConnection sqlCnt = new SqlConnection(connectString);
sqlCnt.Open();
// 建立SqlCommand
SqlCommand mySqlCommand = new SqlCommand();
mySqlCommand.CommandType = CommandType.Text;
mySqlCommand.CommandText = "select * from product";
mySqlCommand.Connection = sqlCnt;
// 建立SqlDataAdapter
SqlDataAdapter myDataAdapter = new SqlDataAdapter();
myDataAdapter.SelectCommand = mySqlCommand; // 爲SqlDataAdapter對象綁定所要執行的SqlCommand對象
上述SQL能夠簡化爲
SqlConnection sqlCnt = new SqlConnection(connectString);
sqlCnt.Open();
// 隱藏了SqlCommand對象的定義,同時隱藏了SqlCommand對象與SqlDataAdapter對象的綁定
SqlDataAdapter myDataAdapter = new SqlDataAdapter("select * from product", sqlCnt);
屬性和方法
myDataAdapter.SelectCommand屬性:SqlCommand變量,封裝Select語句;
myDataAdapter.InsertCommand屬性:SqlCommand變量,封裝Insert語句;
myDataAdapter.UpdateCommand屬性:SqlCommand變量,封裝Update語句;
myDataAdapter.DeleteCommand屬性:SqlCommand變量,封裝Delete語句。
myDataAdapter.fill():將執行結果填充到Dataset中,會隱藏打開SqlConnection並執行SQL等操做。
6.2 SqlCommandBuilder;
命名空間:System.Data.SqlClient.SqlCommandBuilder。
對DataSet的操做(更改、增長、刪除)僅是在本地修改,若要提交到「數據庫」中則須要SqlCommandBuilder對象。用於在客戶端編輯完數據後,總體一次更新數據。具體用法以下:
SqlCommandBuilder mySqlCommandBuilder = new SqlCommandBuilder(myDataAdapter); // 爲myDataAdapter賦予SqlCommandBuilder功能
myDataAdapter.Update(myDataSet, "表名"); // 向數據庫提交更改後的DataSet,第二個參數爲DataSet中的存儲表名,並不是數據庫中真實的表名(兩者在多數狀況下一致)。
6.3 DataSet
命名空間:System.Data.DataSet。
數據集,本地微型數據庫,能夠存儲多張表。
使用DataSet第一步就是將SqlDataAdapter返回的數據集(表)填充到Dataset對象中:
SqlDataAdapter myDataAdapter = new SqlDataAdapter("select * from product", sqlCnt);
DataSet myDataSet = new DataSet(); // 建立DataSet
myDataAdapter.Fill(myDataSet, "product"); // 將返回的數據集做爲「表」填入DataSet中,表名能夠與數據庫真實的表名不一樣,並不影響後續的增、刪、改等操做
① 訪問DataSet中的數據
SqlDataAdapter myDataAdapter = new SqlDataAdapter("select * from product", sqlCnt);
DataSet myDataSet = new DataSet();
myDataAdapter.Fill(myDataSet, "product");
DataTable myTable = myDataSet.Tables["product"];
foreach (DataRow myRow in myTable.Rows) {
foreach (DataColumn myColumn in myTable.Columns) {
Console.WriteLine(myRow[myColumn]); //遍歷表中的每一個單元格
}
}
4、
一、數據庫操做的相關類
特定類:Connection,Command,CommandBuilder,DataAdapter,DataReader,Parameter,Transaction
共享類:DataSet,DataTable,DataRow,DataColumn,DataRealtion,Constraint,DataColumnMapping,DataTableMapping
(1)Connection:開啓程序與數據庫之間的鏈接。
(2)Command:對數據庫發送一些指令。例如增刪改查等指令,以及調用存在數據庫中的存儲過程等。
(3)DataAdapter:主要在數據源及DataSet 之間執行傳輸工做,經過Command 下達命令後,將取得的數據放進DataSet對象中。
(4)DataSet:這個對象可視爲一個暫存區(Cache),能夠把數據庫中所查詢到的數據保存起來,甚至能夠將整個數據庫顯示出來,DataSet是放在內存中的。
備註:將DataAdapter對象當作DataSet 對象與數據源間傳輸數據的橋樑。DataSet包含若干DataTable、DataTableTable包含若干DataRow。
(5)DataReader:一筆向下循序的讀取數據源中的數據。
總結:http://ADO.NET 使用Connection對象來鏈接數據庫,使用Command或DataAdapter對象來執行SQL語句,並將執行的結果返回給DataReader或DataAdapter,而後再使用取得的DataReader或DataAdapter對象操做數據結果。
二、事務:將多個任務放在一塊進行運行,將多個sql語句放在一塊運行
三、索引
四、視圖
五、存儲過程
插入
string sqlconn = "Data Source=.;Initial Catalog=claa;Integrated Security=True";
using (SqlConnection sqlcon = new SqlConnection(sqlconn))
{
sqlcon.Open();
string text = "Insert into Class values('李四','我很快樂')";
using (SqlCommand conn = new SqlCommand(text,sqlcon))
{
int number= conn.ExecuteNonQuery();
刪除
string sql = "delete from Class where Class.cName='李四'";
using (SqlCommand conn = new SqlCommand(sql, con))
{
int i= conn.ExecuteNonQuery();
string connectionString = "Data Source=.;Initial Catalog=db_buiness;Integrated Security=True";
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
string commandText = "Update Class set cName=‘張三’ where id=2 "; using (SqlCommand cmd = new SqlCommand(commandText,conn)) { int num= cmd.ExecuteNonQuery();
3、數據結構(經常使用的排序算法)
一、冒泡排序
(1)原理
(2)實現代碼
二、快速排序
(1)原理
(2)實現代碼
5、軟件開發流程
需求分析 --> 概要設計 --> 詳細設計 --> 編碼 --> 測試 --> 交付 --> 驗收 --> 維護
熟悉API接口應用,封裝.OCX、.Dll組件開發。
1、DLL 與應用程序
動態連接庫(也稱爲 DLL ,即爲「 Dynamic Link Library 」的縮寫)是 Microsoft Windows 最重要的組成要素之一,打開 Windows 系統文件夾,你會發現文件夾中有不少 DLL 文件, Windows 就是將一些主要的系統功能以 DLL 模塊的形式實現。
動態連接庫是不能直接執行的,也不能接收消息,它只是一個獨立的文件,其中包含能被程序或其它 DLL 調用來完成必定操做的函數 ( 方法。注: C# 中通常稱爲「方法」 ) ,但這些函數不是執行程序自己的一部分,而是根據進程的須要按需載入,此時才能發揮做用。
DLL 只有在應用程序須要時才被系統加載到進程的虛擬空間中,成爲調用進程的一部分,此時該 DLL 也只能被該進程的線程訪問,它的句柄能夠被調用進程所使用,而調用進程的句柄也能夠被該 DLL 所使用。在內存中,一個 DLL 只有一個實例,且它的編制與具體的編程語言和編譯器都沒有關係,因此能夠經過 DLL 來實現混合語言編程。 DLL 函數中的代碼所建立的任何對象(包括變量)都歸調用它的線程或進程全部。
下面列出了當程序使用 DLL 時提供的一些優勢: [1]
1) 使用較少的資源
當多個程序使用同一個函數庫時, DLL 能夠減小在磁盤和物理內存中加載的代碼的重複量。這不只能夠大大影響在前臺運行的程序,並且能夠大大影響其餘在 Windows 操做系統上運行的程序。
2) 推廣模塊式體系結構
DLL 有助於促進模塊式程序的開發。這能夠幫助您開發要求提供多個語言版本的大型程序或要求具備模塊式體系結構的程序。模塊式程序的一個示例是具備多個能夠在運行時動態加載的模塊的計賬程序。
3) 簡化部署和安裝
當 DLL 中的函數須要更新或修復時,部署和安裝 DLL 不要求從新創建程序與該 DLL 的連接。此外,若是多個程序使用同一個 DLL ,那麼多個程序都將從該更新或修復中獲益。當您使用按期更新或修復的第三方 DLL 時,此問題可能會更頻繁地出現。
1.封裝本身的dll;
a.打開visual studio - 文件 - 新建 - 項目- 類庫 - 名稱MyTestDll;
b.右鍵Class1.cs - 修改成 TestDll.cs;
c.在裏面寫一個方法,如:
namespace MyTestDll
{
public static class TestDll
{
///
d.引用命令空間using MyTestDll;
主程序代碼:
static void Main(string[] args)
{
int var = TestDll
Console.WriteLine("{0}", var);
Console.ReadKey();
}
運行結果:
按F2查看封裝的TestDll
6、其餘(瞭解)
一、.NET Core 與 .NET Framework 的區別
.NET Core 就是 .NET Framework 的開源且跨平臺版本。但微軟畢竟不能維護兩個不一樣的分支,一個跑在Windows上,一個跑在Linux(Unix Like)系統上,因此微軟抽象出來一個標準庫.NET Standard Library,.NET Core 與 .NET Framework 都必須實現標準庫的API ,就這樣.NET Core、.NET Framework、Xamarin成了三兄弟,分別爲不一樣的平臺服務。
ASP.NET
ASP.NET 是新一代 ASP 。它與經典 ASP 是不兼容的,但 ASP.NET 可能包括經典 ASP。
ASP.NET 頁面是通過編譯的,這使得它們的運行速度比經典 ASP 快。
ASP.NET 具備更好的語言支持,有一大套的用戶控件和基於 XML 的組件,並集成了用戶身份驗證。
ASP.NET 頁面的擴展名是 .aspx ,一般是用 VB (Visual Basic) 或者 C# (C sharp) 編寫。
在 ASP.NET 中的控件能夠用不一樣的語言(包括 C++ 和 Java)編寫。
當瀏覽器請求 ASP.NET 文件時,ASP.NET 引擎讀取文件,編譯和執行腳本文件,並將結果以普通的 HTML 頁面返回給瀏覽器。
WinService、WebService開發
2、字段的使用
1.關於字段
a.字段又稱爲:「成員變量」,通常在類的內部作數據交互使用。
b.字段命名規範:camel命名法(首單詞字母小寫)。
2.通俗的理解:
私有化:字段就比如咱們的我的財產,僅供我的使用,因此通常是private修飾。
添加標準:根據程序的功能需求,具體來添加須要的不一樣類型的字段。
4、屬性
1.屬性的使用
做用:在面向對象設計中主要使用屬性描述對象的靜態特徵。
要求:通常採用Pascal命名法(首字母大寫),數據類型要和對應的字段要一致。
2.屬性的理解
a.屬性其實就是外界訪問私有字段的入口,屬性自己不保存任何數據,在對屬性賦值和讀取的時候其實就是操做的對應私有字段。
圖例:
b.屬性本質其實就是一個方法,經過get和set方法來操做對應的字段,經過反編譯工具咱們能夠看出,如圖:
1.大家對於應屆畢業生的能力要求通常是多少,是要有完整的項目經歷和紮實的基礎知識之間,大家會選什麼?
2.公司的在.net方向的技術棧主要在哪方面,實在winform桌面開發?
3.若是工做的話,我會在哪裏工做,是在上海?
三層架構是哪三層
界面層(User Interface layer):也就是UI層
業務邏輯層(Business Logic Layer)
數據訪問層(Data access layer):實現對於數據庫數據的訪問和數據存儲
Model類庫:實現各個實體類
一、 各層的任務
數據訪問層:使用ADO.NET中的數據操做類,爲數據庫中的每一個表,設計1個數據訪問類。類中實現:記錄的插入、刪除、單條記錄的查詢、記錄集的查詢、單條記錄的有無判斷等基本的數據操做方法。對於通常的管理信息軟件,此層的設計是相似的,包含的方法也基本相同。此層的任務是:封裝每一個數據表的基本記錄操做,爲實現業務邏輯提供數據庫訪問基礎。
業務邏輯層:爲用戶的每一個功能模塊,設計1個業務邏輯類,此時,須要利用相關的數據訪問層類中,記錄操做方法的特定集合,來實現每一個邏輯功能。
界面層:根據用戶的具體需求,爲每一個功能模塊,部署輸入控件、操做控件和輸出控件,並調用業務邏輯層中類的方法實現功能。
二、 層之間的調用關係
數據訪問層的類,直接訪問數據庫,實現基本記錄操做。
業務邏輯層的類,調用相關的數據訪問類,實現用戶所需功能。
界面層:部署控件後,調用業務邏輯層的類,實現功能。
將應用程序的功能分層後,對於固定的DBMS,數據訪問層基本能夠不變,一旦用戶的需求改變,首先修改業務邏輯層,界面層稍作改動便可。這種作法使程序的可複用性、可修改性,都獲得了很好的改善,大大提升了軟件工程的效率。
Html
HTML 是用來描述網頁的一種語言。‘
HTML 標記標籤一般被稱爲 HTML 標籤 (HTML tag)。
層疊樣式表(英文全稱:Cascading Style Sheets)是一種用來表現HTML(標準通用標記語言的一個應用)或XML(標準通用標記語言的一個子集)等文件樣式的計算機語言。CSS不只能夠靜態地修飾網頁,還能夠配合各類腳本語言動態地對網頁各元素進行格式化。 [1]
CSS 可以對網頁中元素位置的排版進行像素級精確控制,支持幾乎全部的字體字號樣式,擁有對網頁對象和模型樣式編輯的能力。 [2]
JavaScript是一種屬於網絡的腳本語言,已經被普遍用於Web應用開發,經常使用來爲網頁添加各式各樣的動態功能,爲用戶提供更流暢美觀的瀏覽效果。一般JavaScript腳本是經過嵌入在HTML中來實現自身的功能的。
數據庫用戶和登陸名即相關又不相關
數據庫訪問效率優化方法:
C#網頁端作後臺
MVC模式與三層架構的區別
轉載Fast_Snail 最後發佈於2017-03-10 09:31:09 閱讀數 1076 收藏
展開
以前老是混淆MVC表現模式和三層架構模式,爲此記錄下。
三層架構和MVC是有明顯區別的,MVC應該是展示模式(三個加起來之後纔是三層架構中的UI層) 三層架構(3-tier application) 一般意義上的三層架構就是將整個業務應用劃分爲:表現層(UI)、業務邏輯層(BLL)、數據訪問層(DAL)。區分層次的目的即爲了「高內聚,低耦合」的思想。 一、表現層(UI):通俗講就是展示給用戶的界面,即用戶在使用一個系統的時候他的所見所得。 二、業務邏輯層(BLL):針對具體問題的操做,也能夠說是對數據層的操做,對數據業務邏輯處理。 三、數據訪問層(DAL):該層所作事務直接操做數據庫,針對數據的增添、刪除、修改、更新、查找等。
MVC是 Model-View-Controller,嚴格說這三個加起來之後纔是三層架構中的UI層,也就是說,MVC把三層架構中的UI層再度進行了分化,分紅了控制器、視圖、實體三個部分,控制器完成頁面邏輯,經過實體來與界面層完成通話;而C層直接與三層中的BLL進行對話。
mvc能夠是三層中的一個表現層框架,屬於表現層。三層和mvc能夠共存。 三層是基於業務邏輯來分的,而mvc是基於頁面來分的。 MVC主要用於表現層,3層主要用於體系架構,3層通常是表現層、中間層、數據層,其中表現層又能夠分紅M、V、C,(Model View Controller)模型-視圖-控制器
曾把MVC模式和Web開發中的三層結構的概念混爲一談,直到今天才發現一直是個人理解錯誤。MVC模式是GUI界面開發的指導模式,基於表現層分離的思想把程序分爲三大部分:Model-View-Controller,呈三角形結構。Model是指數據以及應用程序邏輯,View是指 Model的視圖,也就是用戶界面。這二者都很好理解,關鍵點在於Controller的角色以及三者之間的關係。在MVC模式中,Controller和View同屬於表現層,一般成對出現。Controller被設計爲處理用戶交互的邏輯。一個一般的誤解是認爲Controller負責處理View和Model的交互,而實際上View和Model之間是能夠直接通訊的。因爲用戶的交互一般會涉及到Model的改變和View的更新,因此這些能夠認爲是Controller的反作用。
MVC是表現層的架構,MVC的Model其實是ViewModel,即供View進行展現的數據。 ViewModel不包含業務邏輯,也不包含數據讀取。 而在N層架構中,通常還會有一個Model層,用來與數據庫的表相對應,也就是所謂ORM中的O。這個Model多是POCO,也多是包含一些驗證邏輯的實體類,通常也不包含數據讀取。進行數據讀取的是數據訪問層。而做爲UI層的MVC通常不直接操做數據訪問層,中間會有一個業務邏輯層封裝業務邏輯、調用數據訪問層。UI層(Controller)經過業務邏輯層來獲得數據(Model),並進行封裝(ViewModel),而後選擇相應的View。
MVC原本是存在於Desktop程序中的,M是指數據模型,V是指用戶界面,C則是控制器。使用MVC的目的是將M和V的實現代碼分離,從而使同一個程序能夠使用不一樣的表現形式。好比一批統計數據你能夠分別用柱狀圖、餅圖來表示。C存在的目的則是確保M和V的同步,一旦M改變,V應該同步更新。 MVC如何工做 MVC是一個設計模式,它強制性的使應用程序的輸入、處理和輸出分開。使用MVC應用程序被分紅三個核心部件:模型、視圖、控制器。它們各自處理本身的任務。 視圖V 視圖是用戶看到並與之交互的界面。對老式的Web應用程序來講,視圖就是由HTML元素組成的界面,在新式的Web應用程序中,HTML依舊在視圖中扮演着重要的角色,但一些新的技術已層出不窮,它們包括Macromedia Flash和象XHTML,XML/XSL,WML等一些標識語言和Web services. 如何處理應用程序的界面變得愈來愈有挑戰性。MVC一個大的好處是它能爲你的應用程序處理不少不一樣的視圖。在視圖中其實沒有真正的處理髮生,無論這些數據是聯機存儲的仍是一個僱員列表,做爲視圖來說,它只是做爲一種輸出數據並容許用戶操縱的方式。 模型M 模型表示企業數據和業務規則。在MVC的三個部件中,模型擁有最多的處理任務。被模型返回的數據是中立的,就是說模型與數據格式無關,這樣一個模型能爲多個視圖提供數據。因爲應用於模型的代碼只需寫一次就能夠被多個視圖重用,因此減小了代碼的重複性。 控制器C 控制器接受用戶的輸入並調用模型和視圖去完成用戶的需求。因此當單擊Web頁面中的超連接和發送HTML表單時,控制器自己不輸出任何東西和作任何處理。它只是接收請求並決定調用哪一個模型構件去處理請求,而後再肯定用哪一個視圖來顯示返回的數據。
模型Model 模型是應用程序的主體部分。模型表示業務數據,或者業務邏輯. 實現具體的業務邏輯、狀態管理的功能。 視圖View 視圖是應用程序中用戶界面相關的部分,是用戶看到並與之交互的界面。 就是與用戶實現交互的頁面,一般實現數據的輸入和輸出功能。 控制器controller 控制器工做就是根據用戶的輸入,控制用戶界面數據顯示和更新model對象狀態。起到控制整個業務流程的做用,實現View層跟Model層的協同工做。
3層架構指:表現層(顯示層) 業務邏輯層 數據訪問層(持久化)若是你們非要「生搬硬套」把它和MVC扯上關係話那我就只能在這裏"強扭這個瓜"了即: V 3層架構中"表現層"aspx頁面對應MVC中View(繼承的類不同) C 三層架構中"表現層"的aspx.cs頁面(類)對應MVC中的Controller,理解這一點並不難,你們想想咱們之前寫過的 Redirect,固然它自己就是跳轉了一些連接頁面,而MVC中的Controller要作的更爽,它控制並顯示輸出了一個視圖。即然所起到的做用都是對業務流程和顯示信息的控制,只不過是實現手段不一樣而已。 M 3層架構中業務邏輯層和數據訪問層對應MVC中Model(一定View和Controller已找到「婆家」剩下Model只能是業務邏輯層和數據訪問層了)
爲何要使用 MVC 大部分Web應用程序都是用像ASP,PHP,或者CFML這樣的過程化(自PHP5.0版本後已全面支持面向對象模型)語言來建立的。它們將像數據庫查詢語句這樣的數據層代碼和像HTML這樣的表示層代碼混在一塊兒。經驗比較豐富的開發者會將數據從表示層分離開來,但這一般不是很容易作到的,它須要精心的計劃和不斷的嘗試。MVC從根本上強制性的將它們分開。儘管構造MVC應用程序須要一些額外的工做,可是它給咱們帶來的好處是無庸質疑的。 首先,最重要的一點是多個視圖能共享一個模型,如今須要用愈來愈多的方式來訪問你的應用程序。對此,其中一個解決之道是使用MVC,不管你的用戶想要Flash界面或是 WAP 界面;用一個模型就能處理它們。因爲你已經將數據和業務規則從表示層分開,因此你能夠最大化的重用你的代碼了。 因爲模型返回的數據沒有進行格式化,因此一樣的構件能被不一樣界面使用。例如,不少數據可能用HTML來表示,可是它們也有可能要用Adobe Flash和WAP來表示。模型也有狀態管理和數據持久性處理的功能,例如,基於會話的購物車和電子商務過程也能被Flash網站或者無線聯網的應用程序所重用。 由於模型是自包含的,而且與控制器和視圖相分離,因此很容易改變你的應用程序的數據層和業務規則。若是你想把你的數據庫從MySQL移植到Oracle,或者改變你的基於RDBMS數據源到LDAP,只需改變你的模型便可。一旦你正確的實現了模型,無論你的數據來自數據庫或是LDAP服務器,視圖將會正確的顯示它們。因爲運用MVC的應用程序的三個部件是相互獨立,改變其中一個不會影響其它兩個,因此依據這種設計思想你能構造良好的鬆耦合的構件。 對我來講,控制器也提供了一個好處,就是能夠使用控制器來聯接不一樣的模型和視圖去完成用戶的需求,這樣控制器能夠爲構造應用程序提供強有力的手段。給定一些可重用的模型和視圖,控制器能夠根據用戶的需求選擇模型進行處理,而後選擇視圖將處理結果顯示給用戶。
拿一個簡單的登錄模塊說,需求是你輸入一個用戶名、密碼,若是輸入的跟預先定義好的同樣,那麼就進入到正確頁面,若是不同,就提示個錯誤信息「你Y別在這兒蒙我,輸入的不對!」。 V 這個小小的模塊中,起始的輸入用戶名密碼的頁面跟通過校驗後顯示的頁面就至關於View C 而這裏還須要一個controller頁面,就是用於接收輸入進來的用戶名密碼,還有通過校驗後返回的一個flg(此flg就是用於判斷你輸入的是否正確,而跳轉到相應的頁面的) M 最後還缺一個Model,那麼就是你那個用於校驗的類了,他就是處理你輸入的是否跟預先訂好的同樣不同的,以後返回一個flg。 這樣就徹底實現了邏輯跟頁面的分離,我頁面無論你咋整,反正我就一個顯示,而controller呢也無論你Model咋判斷對不對,反正我給你了用戶名跟密碼,你就得給我整回來一個flg來,而Medol呢,則是反正你敢給我個用戶名跟密碼,我就給你整過去個flg
m 提供數據,數據之間的關係,轉化等。並能夠通知視圖和控制器本身哪些地方發生了變化。 v 提供顯示,能根據m的改變來更新本身 c 好比視圖作了點擊一個按鈕,會先發給這個視圖的控制器,而後這個控制器來決定作什麼操做(讓模型更新數據,控制視圖改變) mvc是一個複合模式 mv,mc都是觀察者模式 m內部的組件組合模式 vc之間是策略模式(能夠隨時更換不一樣的控制器)
MVC模式是上世紀70年代提出,最初用於Smalltalk平臺上的。 MVC是表現模式,是用來向用戶展示的許多組建的一個模式(UI/Presentation Patten) MVC有三種角色: Model:用來儲存數據的組件(與領域模型概念不一樣,二者會相互交叉) View:從Model中獲取數據進行內容展現的組件。一樣的Model在不一樣的View下可展現不一樣的效果。獲取Model的狀態,而不對其進行操做。 Controller:接受並處理用戶指令(操做Model(業務)),選擇一個View進行操做。
MVC概述:協做 存在單向引用,例如Model不知道View和Controller的存在。View不知道Controller的存在。這就隔離了表現和數據。View和controller是單向引用。而實際中View和Controller也是有數據交互的。
MVC的重要特色是分離。兩種分離: View和數據(Model)的分離 使用不一樣的View對相同的數據進行展現;分離可視和不可視的組件,可以對Model進行獨立測試。由於分離了可視組件減小了外部依賴利於測試。(數據庫也是一種外部組件) View和表現邏輯(Controller)的分離 Controller是一個表現邏輯的組件,並不是一個業務邏輯組件。MVC能夠做爲表現模式也能夠做爲建構模式,意味這Controller也能夠是業務邏輯。分離邏輯和具體展現,可以對邏輯進行獨立測試。
MVC和三層架構 MVC與三層架構相似麼? View-UI Layer | Controller-Bussiness Layer | Model-Data Access Layer 其實這樣是錯誤的 MVC是表現模式(Presentation Pattern) 三層架構是典型的架構模式(Architecture Pattern) 三層架構的分層模式是典型的上下關係,上層依賴於下層。但MVC做爲表現模式是不存在上下關係的,而是相互協做關係。即便將MVC看成架構模式,也不是分層模式。MVC和三層架構基本沒有可比性,是應用於不一樣領域的技術。
MVC模式與三層架構:
ui (view)←(contorller)
bll (model)
三、列舉ASP.NET 頁面之間傳遞值的幾種方式。
1.使用QueryString, 如....?id=1; response. Redirect()....
2.使用Session變量
3.使用Server.Transfer
4.Cookie傳值
四、C#中的委託是什麼?事件是否是一種委託?事件和委託的關係。
委託能夠把一個方法做爲參數代入另外一個方法。
委託能夠理解爲指向一個函數的指針。
委託和事件沒有可比性,由於委託是類型,事件是對象,下面說的是委託的對象(用委託方式實現的事件)和(標準的event方式實現)事件的區別。事件的內部是用委託實現的。由於對於事件來說,外部只能「註冊本身+=、註銷本身-=」,外界不能夠註銷其餘的註冊者,外界不能夠主動觸發事件,所以若是用Delegate就無法進行上面的控制,所以誕生了事件這種語法。事件是用來閹割委託實例的,類比用一個自定義類閹割List。事件只能add、remove本身,不能賦值。事件只能+=、-=,不能= 。加分的補充回答:事件內部就是一個private的委託和add、remove兩個方法
面試聊:用Reflector查看.Net的類的內部實現,解決問題。
五、override與重載(overload)的區別
重載是方法的名稱相同。參數或參數類型不一樣,進行屢次重載以適應不一樣的須要。重載(overload)是面向過程的概念。
Override 是進行基類中函數的重寫。Override是面向對象的概念
六、C#中索引器是否只能根據數字進行索引?是否容許多個索引器參數?
參數的個數和類型都是任意的。加分的補充回答:用reflector反編譯能夠看出,索引器的內部本質上就是set_item、get_item方法。
基礎知識:
索引的語法:
public string this[string s],經過get、set塊來定義取值、賦值的邏輯
索引能夠有多個參數、參數類型任意
索引能夠重載。
若是隻有get沒有set就是隻讀的索引。
索引其實就是set_Item、get_Item兩個方法。
七、屬性和public字段的區別是什麼?調用set方法爲一個屬性設值,而後用get方法讀取出來的值必定是set進去的值嗎?
屬性能夠對設值、取值的過程進行非法值控制,好比年齡禁止設值負數,而字段則不能進行這樣的設置。雖然通常狀況下get讀取的值就是set設置的值,可是可讓get讀取的值不是set設置的值的,極端的例子。Public Age{get{return 100;}set{}}。加分的補充回答:用reflector反編譯能夠看出,屬性內部本質上就是set_、get_方法
class Person
{
public int Age
{
get
{
return 3;
}
set
{
}
}
}
Person p1 = new Person();
p1.Age = 30;
p1.Age++;
Console.Write(p1.Age);//輸出3
必須手寫掌握的代碼(既包含拿電腦寫,拿筆寫):
手寫三層架構
手寫冒泡排序
手寫AJAX:XMLHttpRequest
手寫增刪改查、SQLHelper
八、三層架構
一般意義上的三層架構就是將整個業務應用劃分爲:表現層(UI)、業務邏輯層(BLL)、數據訪問層(DAL)。區分層次的目的即爲了「高內聚,低耦合」的思想。表現層(UI):通俗講就是展示給用戶的界面,即用戶在使用一個系統的時候的所見所得。業務邏輯層(BLL):針對具體問題的操做,也能夠說是對數據層的操做,對數據業務邏輯處理。數據訪問層(DAL):該層所作事務直接操做數據庫,針對數據的增添、刪除、修改、更新、查找等每層之間是一種垂直的關係。三層結構是N層結構的一種,通常來講,層次之間是向下依賴的,下層代碼未肯定其接口(契約)前,上層代碼是沒法開發的,下層代碼接口(契約)的變化將使上層的代碼一塊兒變化。
優勢: 分工明確,條理清晰,易於調試,並且具備可擴展性。
缺點: 增長成本。
九、什麼是裝箱(boxing)和拆箱(unboxing)? (*)
Object是引用類型,可是它的子類Int32居然不能去Object能去的「要求必須是引用類型」
的地方,違反了繼承的原則,因此須要把Int32裝在Object中才能傳遞。
裝箱:從值類型接口轉換到引用類型。
拆箱:從引用類型轉換到值類型。
object obj = null;//引用類型
obj = 1;//裝箱,boxing。把值類型包裝爲引用類型。
int i1 = (int)obj;//拆箱。unboxing
2)下面三句代碼有沒有錯,以inboxing或者unboxing爲例,解釋一下內存是怎麼變化的
int i=10;
object obj = i;
int j = obj;
分析:在inboxing(裝箱)時是不須要顯式的類型轉換的,不過unboxing(拆箱)須要顯式的類型轉換,因此第三行代碼應該改成:
3 int j = (int)obj;
要掌握裝箱與拆箱,就必須瞭解CTS及它的特色:
NET重要技術和基礎之一的CTS(Common Type System)。CTS是爲了實如今應用程序聲明和使用這些類型時必須遵循的規則而存在的通用類型系統。.Net將整個系統的類型分紅兩大類 :值類型和引用類型。
CTS中的全部東西都是對象;全部的對象都源自一個基類——System.Object類型。值類型的一個最大的特色是它們不能爲null,值類型的變量總有一個值。爲了解決值類型不能夠爲null,引用類型能夠爲null的問題,微軟在.Net中引入了裝箱和拆箱:裝箱就是將值類型用引用類型包裝起來轉換爲引用類型;而從引用類型中拿到被包裝的值類型數據進行拆箱。
十、CTS、CLS、CLR分別做何解釋(*)把英文全稱背過來。
C#和.Net的關係。
C#只是抽象的語言,能夠把C#編譯生成Java平臺的二進制代碼,也能夠把Java代碼編譯生成.Net平臺的二進制代碼。因此C#只是提供了if、while、+-*/、定義類、int、string等基礎的語法,而Convert.ToInt3二、FileStream、SqlConnection、String.Split等都屬於.Net的東西。深藍色是C#的,淺藍色是.Net的。
C# new→IL:newobj
C# string →.Net中的String
類型的差異:.net中的Int32在C#中是int,在VB.Net中是Integer。String、Int32等公共類型。
語法的差異:IL中建立一個對象的方法是L_0001: newobj instance void 索引.C1::.ctor()
C#中是new C1();VB.net中是 Dim c1 As New C1
CTS:Common Type System 通用類型系統。Int3二、Int16→int、String→string、Boolean→bool。每種語言都定義了本身的類型,.Net經過CTS提供了公共的類型,而後翻譯生成對應的.Net類型。
CLS:Common Language Specification 通用語言規範。不一樣語言語法的不一樣。每種語言都有本身的語法,.Net經過CLS提供了公共的語法,而後不一樣語言翻譯生成對應的.Net語法。
CLR:Common Language Runtime 公共語言運行時,就是GC、JIT等這些。有不一樣的CLR,好比服務器CLR、Linux CLR(Mono)、Silverlight CLR(CoreCLR)。至關於一個發動機,負責執行IL。
十一、在dotnet中類(class)與結構(struct)的異同?
Class能夠被實例化,屬於引用類型,是分配在內存的堆上的。類是引用傳遞的。
Struct屬於值類型,是分配在內存的棧上的。結構體是複製傳遞的。加分的回答:Int3二、Boolean等都屬於結構體
十二、堆和棧的區別?
棧是編譯期間就分配好的內存空間,所以你的代碼中必須就棧的大小有明確的定義;局部值類型變量、值類型參數等都在棧內存中。
堆是程序運行期間動態分配的內存空間,你能夠根據程序的運行狀況肯定要分配的堆內存的大小。
1三、能用foreach遍歷訪問的對象的要求
須要實現IEnumerable接口或聲明GetEnumerator方法的類型。
1四、GC是什麼? 爲何要有GC?
C/C++中由程序員進行對象的回收像學校食堂中由學生收盤子,.Net中由GC進行垃圾回收像餐館中店員去回收。
GC是垃圾收集器(Garbage Collection)。程序員不用擔憂內存管理,由於垃圾收集器會自動進行管理。GC只能處理託管內存資源的釋放,對於非託管資源則不能使用GC進行回收,必須由程序員手工回收,一個例子就是FileStream或者SqlConnection須要程序員調用Dispose進行資源的回收。
要請求垃圾收集,能夠調用下面的方法:GC.Collect()通常不須要手動調用GC.Collect()。當一個對象沒有任何變量指向(再也不能使用)的時候就能夠被回收了。
基礎知識:當沒有任何變量指向一個對象的時候對象就能夠被回收掉了,但不必定會當即被回收。
object obj = new object();//只有new纔會有新對象
Console.WriteLine(obj);
object obj2 = obj;
obj = null;
obj2 = null;
Console.WriteLine();
1五、值類型和引用類型的區別?
1.將一個值類型變量賦給另外一個值類型變量時,將複製包含的值。引用類型變量的賦值只複製對對象的引用,而不復制對象自己。
2.值類型不可能派生出新的類型:全部的值類型均隱式派生自 System.ValueType。但與引用類型相同的是,結構也能夠實現接口。
3.值類型不可能包含 null 值:然而,可空類型功能容許將 null 賦給值類型。
4.每種值類型均有一個隱式的默認構造函數來初始化該類型的默認值。
1六、C#中的接口和類有什麼異同。
不一樣點:
不能直接實例化接口。
接口不包含方法的實現。
接口能夠多繼承,類只能單繼承。
類定義可在不一樣的源文件之間進行拆分。
相同點:
接口、類和結構均可以從多個接口繼承。
接口相似於抽象基類:繼承接口的任何非抽象類型都必須實現接口的全部成員。
接口和類均可以包含事件、索引器、方法和屬性。
基礎知識:接口只能定義方法(只能定義行爲,不能定義實現也就是字段),由於事件、索引器、屬性本質上都是方法,因此接口中也能夠定義事件、索引器、屬性。
1七、abstract class和interface有什麼區別?
相同點:
都不能被直接實例化,均可以經過繼承實現其抽象方法。
不一樣點:
接口支持多繼承;抽象類不能實現多繼承。
接口只能定義行爲;抽象類既能夠定義行爲,還可能提供實現。
接口只包含方法(Method)、屬性(Property)、索引器(Index)、事件(Event)的簽名,但不能定義字段和包含實現的方法;
抽象類能夠定義字段、屬性、包含有實現的方法。
接口能夠做用於值類型(Struct)和引用類型(Class);抽象類只能做用於引用類型。例如,Struct就能夠繼承接口,而不能繼承類。
加分的補充回答:講設計模式的時候SettingsProvider的例子。
1八、是否能夠繼承String類?
String類是sealed類故不能夠繼承。
1九、int、DateTime、string是否能夠爲null?
null表示「不知道」,而不是「沒有」。沒有年齡和不知道年齡是不同。
數據庫中null不能用0表示。0歲和不知道多少歲不同。
Sex is zero。《色便是空》
//int i1 = null;
//int? i2 = null;//值類型後加?就成了可空數據類型
////int i3 = i2;//因此把可空的賦值給必定不能爲空的會報錯。
//int i4 = (int)i2;//能夠顯式轉換,由程序員來保證「必定不爲空」
//int? i5 = i4;//必定會成功!
//using()→try{]catch{}finally{}
//int?是微軟的一個語法糖。是一種和int沒有直接關係的Nullable類型
Nullable
Nullable
Console.WriteLine(d1==null);
int、DateTime不能,由於其爲Struct類型,而結構屬於值類型,值類型不能爲null,只有引用類型才能被賦值null。string能夠爲null。
C#中int等值類型不能夠爲null、而數據庫中的int能夠爲null,這就是糾結的地方。int?就變成了可空的int類型。bool?、DateTime?
int i1 = 3;
int? i2 = i1;
//int i3 = i2;//不能把可能爲空的賦值給必定不能爲空的變量
int i3 = (int)i2;//顯式轉換
可空數據類型經典應用場景:三層中的Model屬性的設計。
int?翻譯生成.Net的Nullable
20、using關鍵字有什麼用?什麼是IDisposable?
using能夠聲明namespace的引入,還能夠實現非託管資源的釋放,實現了IDisposiable的類在using中建立,using結束後會自動調用該對象的Dispose方法,釋放資源。加分的補充回答:using其實等價於try……finally,用起來更方便。
2一、XML 與 HTML 的主要區別
XML是區分大小寫字母的,HTML不區分。
在HTML中,若是上下文清楚地顯示出段落或者列表鍵在何處結尾,那麼你能夠省略
或者HTML:
XML:
在XML中,擁有單個標記而沒有匹配的結束標記的元素必須用一個 / 字符做爲結尾。這樣分析器就知道不用 查找結束標記了。
在XML中,屬性值必須分裝在引號中。在HTML中,引號是可用可不用的。
在HTML中,能夠擁有不帶值的屬性名。在XML中,全部的屬性都必須帶有相應的值。
XML是用來存儲和傳輸數據的
HTML是用來顯示數據的
若是使用了徹底符合XML語法要求的HTML,那麼就叫作符合XHTML標準。符合XHTML標準的頁面有利於SEO。
2二、string str = null 與 string str =」」說明其中的區別。
答:string str = null 是不給他分配內存空間,而string str = "" 給它分配長度爲空字符串的內存空間。 string str = null沒有string對象,string str = 「」有一個字符串對象。
string s3 = string.Empty;//反編譯發現,string.Empty就是在類構造函數中 Empty = "";
2三、寫出一條Sql語句:取出表A中第31到第40記錄(SQLServer,以自動增加的ID做爲主鍵,注意:ID可能不是連續的。
答:解1: select top 10 * from A where id not in (select top 30 id from A)
演變步驟:
1)select top 30 id from T_FilterWords--取前條
2)select * from T_FilterWords
where id not in (select top 30 id from T_FilterWords)--取id不等於前三十條的
--也就是把前條排除在外
3)select top 10 * from T_FilterWords
where id not in (select top 30 id from T_FilterWords)
--取把前條排除在外的前條,也就是-40條
解2: select top 10 * from A where id > (select max(id) from (select top 30 id from A )as A)
解答3:用ROW_NUMBER實現
2四、在.Net中全部可序列化的類都被標記爲
[serializable]
2五、什麼是code-Behind技術。
就是代碼隱藏,在ASP.NET中經過ASPX頁面指向CS文件的方法實現顯示邏輯和處理邏輯的分離,這樣有助於web應用程序的建立。好比分工,美工和編程的能夠個幹各的,不用再像之前asp那樣都代碼和html代碼混在一塊兒,難以維護。code-Behind是基於部分類技術實現的,在個人項目的三層代碼生成器中用到了部分類。
2六、接口是一種引用類型,在接口中能夠聲明( a),但不能夠聲明公有的域或私有的成員變量。
a) 方法、屬性、索引器和事件;
b) 索引器和字段;
c) 事件和字段;
解讀:接口中不能聲明字段只能聲明方法,屬性、索引器和事件 最終都編譯生成方法。由於字段屬於實現層面的東西,只有存取值的時候纔會用到字段,因此中接口中不能定義字段。
2七、在ADO.NET中,對於Command對象的ExecuteNonQuery()方法和ExecuteReader()方法,下面敘述錯誤的是(c)。
a) insert、update、delete等操做的Sql語句主要用ExecuteNonQuery()方法來執行;
b) ExecuteNonQuery()方法返回執行Sql語句所影響的行數。
c) Select操做的Sql語句只能由ExecuteReader()方法來執行;
d) ExecuteReader()方法返回一個DataReader對象;
拿SQLHelper實現一下。
2八、StringBuilder 和 String 的區別?
答:String 在進行運算時(如賦值、拼接等)會產生一個新的實例,而 StringBuilder 則不會。因此在大量字符串拼接或頻繁對某一字符串進行操做時最好使用 StringBuilder,不要使用 String
若是要操做一個不斷增加的字符串,儘可能不用String類,改用StringBuilder類。兩個類的工做原理不一樣:String類是一種傳統的修改字符串的方式,它確實能夠完成把一個字符串添加到另外一個字符串上的工做沒錯,可是在.NET框架下,這個操做實在是划不來。由於系統先是把兩個字符串寫入內存,接着刪除原來的String對象,而後建立一個String對象,並讀取內存中的數據賦給該對象。這一來二去的,耗了很多時間。而使用System.Text命名空間下面的StringBuilder類就不是這樣了,它提供的Append方法,可以在已有對象的原地進行字符串的修改,簡單並且直接。固然,通常狀況下覺察不到這兩者效率的差別,但若是你要對某個字符串進行大量的添加操做,那麼StringBuilder類所耗費的時間和String類簡直不是一個數量級的。
2九、請敘述屬性與索引器的區別。 (*)
屬性 索引器
經過名稱標識。 經過簽名標識。
經過簡單名稱或成員訪問來訪問。 經過元素訪問來訪問。
能夠爲靜態成員或實例成員。 必須爲實例成員。
屬性的 get 訪問器沒有參數。 索引器的 get 訪問器具備與索引器相同的形參表。
屬性的 set 訪問器包含隱式 value 參數。 除了 value 參數外,索引器的 set 訪問器還具備與索引器相同的形參表。
30、請解釋ASP。NET中的web頁面與其隱藏類之間的關係?
一個ASP.NET頁面通常都對應一個隱藏類,通常都在ASP.NET頁面的聲明中指定了隱藏類例如一個頁面Tst1.aspx的頁面聲明以下
<%@ Page language="c#" Codebehind="Tst1.aspx.cs" AutoEventWireup="false" Inherits="T1.Tst1" %>
Codebehind="Tst1.aspx.cs" 代表經編譯此頁面時使用哪個代碼文件
Inherits="T1.Tst1" 表用運行時使用哪個隱藏類
aspx頁面會編譯生成一個類,這個類從隱藏類繼承。
3一、您在什麼狀況下會用到虛方法?它與接口有什麼不一樣?
答案:子類從新定義父類的某一個方法時,必須把父類的方法定義爲virtual
在定義接口中不能有方法體,虛方法能夠。
實現時,子類能夠不從新定義虛方法,但若是一個類繼承接口,那必須實現這個接口。
3二、DataReader和DataSet的異同?
DataReader使用時始終佔用SqlConnection,在線操做數據庫
每次只在內存中加載一條數據,因此佔用的內存是很小的
是隻進的、 只讀的
DataSet則是將數據一次性加載在內存中.拋棄數據庫鏈接..讀取完畢即放棄數據庫鏈接(非鏈接模式)
DataSet將數據所有加載在內存中.因此比較消耗內存...可是確比DataReader要靈活..能夠動態的添加行,列,數據.對數據庫進行 回傳更新操做(動態操做讀入到內存的數據)
3三、public static const int A = 1;這段代碼有錯誤麼?
錯誤:const不能被修飾爲static ;由於定義爲常量 (const )後就是靜態的(static )。
3四、傳入某個屬性的set方法的隱含參數的名稱是什麼?
value,它的類型和屬性所聲名的類型相同。
3五、C#支持多重繼承麼?
類之間不支持,接口之間支持。類對接口叫作實現,不叫繼承。 類是爹、接口是能力,能有多個能力,但不能有多個爹。
3六、C#中全部對象共同的基類是什麼?
System.Object
3七、經過超連接怎樣傳遞中文參數?
答:用URL編碼,經過QueryString傳遞,用urlencode編碼 用urldecode解碼
3八、string、String;int、Int32;Boolean、bool的區別
String、Int3二、Boolean等都屬於.Net中定義的類,而string、int、bool至關於C#中對這些類定義的別名。CTS。
3九、Server.Transfer和Response.Redirect的區別是什麼?(常考)
答: Server.Transfer僅是服務器中控制權的轉向,在客戶端瀏覽器地址欄中不會顯示出轉向後的地址;Response.Redirect則是徹底的跳轉,瀏覽器將會獲得跳轉的地址,並從新發送請求連接。這樣,從瀏覽器的地址欄中能夠看到跳轉後的連接地址。
Server.Transfer是服務器請求資源,服務器直接訪問目標地址的URL,把那個URL的響應內容讀取過來,而後把這些內容再發給瀏覽器,瀏覽器根本不知道服務器發送的內容是從哪兒來的,因此它的地址欄中仍是原來的地址。 這個過程當中瀏覽器和Web服務器之間通過了一次交互。
Response.Redirect就是服務端根據邏輯,發送一個狀態碼,告訴瀏覽器從新去請求那個地址,通常來講瀏覽器會用剛纔請求的全部參數從新請求。這個過程當中瀏覽器和Web服務器之間通過了兩次交互。
Server.Transfer不能夠轉向外部網站,而Response.Redirect能夠。
Server.Execute效果和Server.Transfer相似,可是是把執行的結果嵌入當前頁面。
40、不是說字符串是不可變的嗎?string s="abc";s="123"不就是變了嗎?
String是不可變的在這段代碼中,s原先指向一個String對象,內容是 "abc",而後咱們將s指向"123",那麼s所指向的那個對象是否發生了改變呢?答案是沒有。這時,s不指向原來那個對象了,而指向了另外一個 String對象,內容爲"123",原來那個對象還存在於內存之中,只是s這個引用變量再也不指向它了。
4一、是否能夠從一個static方法內部發出對非static方法的調用?
不能夠。由於非static方法是要與對象關聯在一塊兒的,必須建立一個對象後,才能夠在該對象上進行方法調用,而static方法調用時不須要建立對象,能夠直接調用。也就是說,當一個static方法被調用時,可能尚未建立任何實例對象,若是從一個static方法中發出對非static方法的調用,那個非static方法是關聯到哪一個對象上的呢?這個邏輯沒法成立,因此,一個static方法內部不能發出對非static方法的調用。
4二、說出一些經常使用的類、接口,請各舉5個
要讓人家感受你對.Net開發很熟,因此,不能僅僅只列誰都能想到的那些東西,要多列你在作項目中涉及的那些東西。就寫你最近寫的那些程序中涉及的那些類。
經常使用的類:StreamReader、WebClient、Dictionary<K,V>、StringBuilder、SqlConnection、FileStream、File、Regex、List
經常使用的接口:IDisposable、IEnumerable、IDbConnection、IComparable、ICollection、IList、IDictionary
要出乎意料!不要僅僅完成任務!筆試不是高考!到處要顯出牛!
說出幾個開源軟件?MySQL、Linux、 Discuz、Apache、Paint.Net、Android、Chrome、Notepad++……
開源項目有一些是開發包。開源軟件指的是能夠直接用的。Jquery、NPOI、ASP.Net MVC、Silverlight Toolkit、AJAX toolkit、json.net
4三、編寫一個單例(Singleton)類。
把構造函數設置爲private,設置一個public、static的對象實例
public FileManager
{
private FileManager(){}
public readonly static FileManager Instance = new FileManager();
}
擴展:搜「C# Singleton」,有線程安全的更牛B的實現
4四、什麼是sql注入?如何避免sql注入?
用戶根據系統的程序構造非法的參數從而致使程序執行不是程序員指望的惡意SQL語句。使用參數化的SQL就能夠避免SQL注入。
詳細參考複習ppt。舉例子,擺事實!
1' or 1=1
4五、數據庫三範式是什麼?
用本身的話解釋,而不是背概念。
第一範式:字段不能有冗餘信息,全部字段都是必不可少的。
第二範式:知足第一範式而且表必須有主鍵。
第三範式:知足第二範式而且表引用其餘的表必須經過主鍵引用。
員工內部→本身的老大→外部的老大
記憶順序:本身內部不重複→別人引用本身→本身引用別人。
4六、post、get的區別
get的參數會顯示在瀏覽器地址欄中,而post的參數不會顯示在瀏覽器地址欄中;
使用post提交的頁面在點擊【刷新】按鈕的時候瀏覽器通常會提示「是否從新提交」,而get則不會;
用get的頁面能夠被搜索引擎抓取,而用post的則不能夠;
用post能夠提交的數據量很是大,而用get能夠提交的數據量則很是小(2k),受限於網頁地址的長度。
用post能夠進行文件的提交,而用get則不能夠。
參考閱讀:http://www.cnblogs.com/skynet/archive/2010/05/18/1738301.html
4七、.Net、ASP.Net、C#、VisualStudio之間的關係是什麼?
答:.Net通常指的是.Net Framework,提供了基礎的.Net類,這些類能夠被任何一種.Net編程語言調用,.Net Framework還提供了CLR、JIT、GC等基礎功能。
ASP.Net是.Net中用來進行Web開發的一種技術,ASP.Net的頁面部分寫在aspx 文件中,邏輯代碼一般經過Code-behind的方式用C#、VB.Net等支持.Net的語言編寫。
C#是使用最普遍的支持.Net的編程語言。除了C#還有VB.Net、IronPython等。
VisualStudio是微軟提供的用來進行.Net開發的集成開發環境(IDE),使用VisualStudio能夠簡化不少工做,不用程序員直接調用csc.exe等命令行進行程序的編譯,並且VisualStudio提供了代碼自動完成、代碼高亮等功能方便開發。除了VisualStudio,還有SharpDevelop、MonoDevelop等免費、開源的IDE,VisualStudio Express版這個免費版本。
4八、AJAX解決什麼問題?如何使用AJAX?AJAX有什麼問題須要注意?項目中哪裏用到了AJAX?
答:AJAX解決的問題就是「無刷新更新頁面」,用傳統的HTML表單方式進行頁面的更新時,每次都要將請求提交到服務器,服務器返回後再重繪界面,這樣界面就會經歷:提交→變白→從新顯示這樣一個過程,用戶體驗很是差,使用AJAX則不會致使頁面從新提交、刷新。
AJAX最本質的實現是在Javascript中使用XMLHttpRequest進行Http的請求,開發中一般使用UpdatePanel、JQuery等方式簡化AJAX的開發,UpdatePanel的方式實現AJAX最簡單,可是數據通信量比較大,由於要來回傳整個ViewState,並且不靈活,對於複雜的需求則能夠使用JQuery提供的ajax功能。
UpdatePanel的內部原理。
AJAX最重要的問題是沒法跨域請求(www.rupeng.com →so.rupeng.com),也就是沒法在頁面中向和當前域名不一樣的頁面發送請求,能夠使用在當前頁面所在的域的服務端作代理頁面的方式解決。
在如鵬網項目中發帖的時候顯示相關帖的功能、站內搜索項目中顯示搜索Suggestion、數據採集項目中都用到了AJAX。
常考:不用任何框架編寫一個AJAX程序。XHR:XmlHttpRequest。背也要背下來!
若是面試的時候談AJAX談到UpdatePanel的時候,就是NB的時候!!!先侃UpdatePanel的原理!引出爲何Dom操做的動態效果在用UpdatePanel提交刷新之後沒有了,以及CKEditor被套在UpdatePanel中提交之後也變成了textarea,爲何把Fileupload放到Updatepanel中沒法實現無刷新上傳。說成是公司內部的一個菜鳥用UpdatePanel遇到這樣問題,因爲我懂XHR、UpdatePanel的原理,因此輕鬆解決!UpdatePanel生成的上萬行JS腳本,不適合於互聯網項目。「WebForm怎麼可能把開發人員編程傻子呢!不明白原理苦命呀!仍是MVC好呀,MVC。。。。。。。」
4九、Application 、Cookie和 Session 兩種會話有什麼不一樣?
答:Application是用來存取整個網站全局的信息,而Session是用來存取與具體某個訪問者關聯的信息。Cookie是保存在客戶端的,機密信息不能保存在Cookie中,只能放小數據;Session是保存在服務器端的,比較安全,能夠放大數據。
談到Session的時候就侃Session和Cookie的關係:Cookie中的SessionId。和別人對比說本身懂這個原理而給工做帶來的方便之處。
50、開放式問題:你常常訪問的技術類的網站是什麼?
博客園(www.cnblogs.com)、csdn、codeplex、codeproject、msdn文檔、msdn論壇(遇到問題先到網上搜解決方案,還不行就問同事,同事也解決不了就去MSDN論壇提問,必定能獲得解決)。Cnbeta.com。
8、數據庫優化經驗(後端工程師很是常見)
出現指數:四顆星
主要考點:此題考察後端工程師操做數據庫的經驗。說實話,數據庫是博主的弱項,博主以爲對於這種考題,須要抓住幾個經常使用而且關鍵的優化經驗,若是說得不對,歡迎你們斧正。
參考答案:
一、數據庫運維方面的優化:啓用數據庫緩存。對於一些比較經常使用的查詢能夠採用數據庫緩存的機制,部署的時候須要注意設置好緩存依賴項,防止「過時」數據的產生。
二、數據庫索引方面的優化:好比經常使用的字段建索引,聯合查詢考慮聯合索引。(PS:若是你有基礎,能夠敞開談談彙集索引和非彙集索引的使用場景和區別)
三、數據庫查詢方面的優化:避免select * 的寫法、儘可能不用in和not in 這種耗性能的用法等等。
四、數據庫算法方面的優化:儘可能避免大事務操做、減小循環算法,對於大數據量的操做,避免使用遊標的用法等等。
一、什麼是面向對象?
面向對象說到底就是一種思想,任何事物均可以看做是一個對象。在有些面試題目中也稱之爲OOP(Object Oriented Programming)。分開來解讀就是:
Object:對象
Oriented: 面向的
Programming:程序設計
面向對象就是把一我的或事務的屬性,好比名字,年齡這些定義在一個實體類裏面。存和取的時候直接使用存取實體類就把這我的的名字,年齡這些所有存了,這個實體類就叫對象,這種思想就叫面向對象。
面向對象開發具備如下優勢:
代碼開發模塊化,便於維護。
代碼複用性強
代碼的可靠性和靈活性。
代碼的可讀性和可擴展性。
1、對於 Web 性能優化,您有哪些瞭解和經驗嗎?
出現指數:五顆星
主要考點:這道題是博主在博客園的新聞裏面看到的,回想以前幾年的面試經歷,發現此題出現機率仍是比較高的。由於它的考麪灰常廣,可讓面試官很快了解你的技術涉及面以及這些技術面的深度。
參考答案:這個問題能夠分前端和後端來講。
一、前端優化
(1)減小 HTTP 請求的次數。咱們知道每次發送http請求,創建鏈接和等待相應會花去至關一部分時間,因此在發送http請求的時候,儘可能減小請求的次數,一次請求能取出的數據就不要分屢次發送。
(2)啓用瀏覽器緩存,當肯定請求的數據不會發生變化時,可以直接讀瀏覽器緩存的就不要向服務端發送請求。好比咱們ajax裏面有一個參數可以設置請求的時候是否啓用緩存,這種狀況下就須要咱們在發送請求的時候作好相應的緩存處理。
(3)css文件放 在裏面,js文件儘可能放在頁面的底部。由於請求js文件是很花費時間,若是放在裏面,就會致使頁面的 DOM樹呈現須要等待js文件加載完成。這也就是爲何不少網站的源碼裏面看到引用的文件放在最後的緣由。
(4)使用壓縮的css和js文件。這個不用多說,網絡流量小。
(5)若是條件容許,儘可能使用CDN的方式引用文件,這樣就能減小網絡流量。好比咱們經常使用的網站http://www.bootcdn.cn/。
(6)在寫js和css的語法時,儘可能避免重複的css,儘可能減小js裏面循環的次數,諸如此類。
二、後端優化:
(1)程序的優化:這是一個很大的話題,我這裏就選幾個常見的。好比減小代碼的層級結構、避免循環嵌套、避免循環CURD數據庫、優化算法等等。
(2)數據庫的優化:(因爲數據庫優化不是本題重點,因此可選幾個主要的來講)好比啓用數據庫緩存、經常使用的字段建索引、儘可能避免大事務操做、避免select * 的寫法、儘可能不用in和not in 這種耗性能的用法等等。
(3)服務器優化:(這個可做爲可選項)負載均衡、Web服務器和數據庫分離、UI和Service分離等等。
2、MVC路由理解?(家常便飯)
出現指數:五顆星
主要考點:此題主要考點是MVC路由的理解。
參考答案:
一、首先咱們要理解MVC中路由的做用:url Routing的做用是將瀏覽器的URL請求映射到特定的MVC控制器動做。
二、當咱們訪問http://localhost:8080/Home/Index 這個地址的時候,請求首先被UrlRoutingModule截獲,截獲請求後,從Routes中獲得與當前請求URL相符合的RouteData對象, 將RouteData對象和當前URL封裝成一個RequestContext對象,而後從Requestcontext封裝的RouteData中獲得 Controller名字,根據Controller的名字,經過反射建立控制器對象,這個時候控制器才真正被激活,最後去執行控制器裏面對應的 action。
3、談談你以爲作的不錯系統,大概介紹下用到了哪些技術?
出現指數:五顆星
主要考點:這是一道很是開放的面試題。博主遇到過好幾家公司的面試官都問道了這個,博主以爲他們是想經過這個問題快速瞭解面試者的技術水平。此題只要結合你最近項目用到的技術談談就行了。
參考答案:
就拿我以前作過的一個項目爲例來簡單說明一下吧。項目分爲客戶端和服務端,客戶端分 爲BS客戶端和CS客戶端,BS客戶端採用MVC 5.0的框架,CS客戶端是Winform項目,服務端使用WebApi統一提供服務接口,考慮之後可能還要擴展手機端,因此服務接口的參數和返回值使用 通用的Json格式來傳遞數據。
一、服務端採用的面向接口編程,咱們在軟件架構的過程當中,層和層之間經過接口依賴, 下層不是直接給上層提供實現,而是提供接口,具體的實現以依賴注入的方式在運行的時候動態注入進去。MEF就是實現依賴注入的一種組件。它的使用使得UI 層不直接依賴於BLL層,而是依賴於中間的一個IBLL層,在程序運行的時候,經過MEF動態將BLL裏面的實現注入到UI層裏面去,這樣作的好處是減小 了層與層之間的耦合。服務端的異常裏面、權限驗證、日誌記錄等通用功能使用了AOP攔截的機制統一管理,項目中使用的是Postsharp這個組件,很好 地將通用需求功能從不相關的類當中分離出來,提升了代碼的可維護性。
二、BS的客戶端採用的jquery+bootstrap 的方式,全部頁面採用流式佈局,能更好適應各類不一樣的終端設備(PC、手機)。項目中使用了各類功能強大的bootstrap組件,能適應各類複雜的業務需求。
4、Js繼承實現。
出現指數:五顆星
主要考點:這道題考驗面試者對js理解的深度。根據博主的經歷,這種題通常在筆試出現的概率較大,爲何把它放在這裏,由於它確實太常見了。其實js實現繼承的方式不少,咱們只要寫好其中一種就行了。
參考答案:原型鏈繼承
1 //1.定義Persiong函數 2 function Person(name, age) { 3 this.name = name; 4 this.age = age; 5 } 6 //2.經過原型鏈給Person添加一個方法 7 Person.prototype.getInfo = function () { 8 console.log(this.name + " is " + this.age + " years old!"); 9 }10 function Teacher(staffId) {11 this.staffId = staffId;12 }13 //3.經過prototype生命 Teacher繼承Person14 Teacher.prototype = new Person();15 //4.實例Teacher函數16 var will = new Teacher(1000);17 will.name= "Will";18 will.age = 28;19 //5.調用父類函數20 will.getInfo();
5、談談你對設計模式的認識?結合你用得最多的一種設計模式說說它的使用。
出現指數:五顆星
主要考點:不用多說,這題考的就是對設計模式的理解。通常爲了簡單可能會要求你寫一個單例模式,注意最好是寫一個完整點的,考慮線程安全的那種。而後會讓你說說你在項目中什麼狀況下會用到這種模式
參考答案:
通用寫法
1 public class Singleton 2 { 3 // 定義一個靜態變量來保存類的實例 4 private static Singleton uniqueInstance; 5 // 定義一個標識確保線程同步 6 private static readonly object locker = new object(); 7 // 定義私有構造函數,使外界不能建立該類實例 8 private Singleton() 9 {10 }11 ///
單例模式確保一個類只有一個實例,並提供一個全局訪問點,它的使用場景好比任務管理 器整個系統中應該只有一個把,再好比操做文件的對象,同一時間咱們只能有一個對象做文件吧。最重要的,好比咱們項目中用得很是多的功能→日誌記錄,在 一個線程中,記錄日誌的對象應該也只能有一個吧。單例模式的目的是爲了保證程序的安全性和數據的惟一性。或者你也能夠結合你使用的其餘設計模式來講明。
6、IIS的工做原理?
出現指數:四顆星
主要考點:此題主要考的是.net framework和IIS是如何結合呈現頁面的。這是一個有點複雜的過程,面試的時候不可能說得完整,那麼咱們就抓住幾個關鍵點說說就能夠。其實博主也不能徹底理解這個過程,今天正好借這個機會溫下。
參考答案:
一、當客戶端發送HTTP Request時,服務端的HTTP.sys(能夠理解爲IIS的一個監聽組件) 攔截到這個請求;
二、HTTP.sys 聯繫 WAS 向配置存儲中心請求配置信息。
三、而後將請求傳入IIS的應用程序池。
四、檢查請求的後綴,啓動aspnet_isapi.dll這個dll,這個dll是.net framework裏面的,也就是說到這一步,請求進入了.net framework的管轄範圍。
五、這個時候若是是WebForm,開始執行復雜的頁面生命週期(HttpRuntime→ProcessRequest→HttpContext→HttpHandler);若是是MVC,則啓動mvc的路由機制,根據路由規則爲URL來指定HttpHandler。
六、httpHandler處理請求後,請求結束,給出Response,客戶端處理響應,整個過程結束。
7、Http協議
出現指數:四顆星
主要考點:此題主要考對於web裏面http協議的理解。
參考答案:
一、http協議是瀏覽器和服務器雙方共同遵循的規範,是一種基於TCP/IP應用層協議。
二、http是一種典型的請求/響應協議。客戶端發送請求,請求的內容以及參數存放到請求報文裏面,服務端收到請求後,作出響應,返回響應的結果放到響應報文裏面。經過F12能夠查看請求報文和響應報文。
三、http協議是」無狀態」的,當客戶端向服務端發送一次http請求後,服務端收到請求而後返回給客戶端相應的結果,服務器會當即斷開鏈接並釋放資源。在實際開發過程當中,咱們有時須要「保持」這種狀態,因此衍生出了Session/Cookie這些技術。
四、http請求的方式主要有get/post。
五、http狀態碼最好記幾個,博主有一次面試就被問到了。200(請求成功)、404(請求的資源不存在)、403(禁止訪問)、5xx(服務端錯誤)
9、關於代碼優化你怎麼理解?你會考慮去代碼重構嗎?
出現指數:四顆星
主要考點:此題考的是面試者對代碼優化的理解,以及代碼如何重構的相關知識。
參考答案:
一、對於代碼優化,以前的公司每週會作代碼審覈,審覈的主要做用就是保證代碼的正確性和執行效率,好比減小代碼的層級結構、避免循環嵌套、避免循環CURD數據庫、儘可能避免一次取出大量數據放在內存中(容易內存溢出)、優化算法等。
二、對於陳舊代碼,可能不少地方有調用,而且開發和維護人員頗有可能不是同一我的,因此重構時要格外當心,若是沒有十足的把握,不要輕易重構。若是必需要重構,必須作好充分的單元測試和全局測試。
10、談談你的優勢和缺點?
出現指數:四顆星
主要考點:這道題讓人有一種罵人的衝動,可是沒辦法,恰恰不少所謂的大公司會問這個。好比華爲。這個問題見仁見智,答案能夠本身組織。
參考答案:
優勢:對於新的技術學**能力強,能很快適應新環境等等
缺點:對技術太過於執着等等
11、關於服務器端 MVC 架構的技術實現,您是怎樣理解的?這種架構方式有什麼好處?您在項目中是如何應用這一架構的?
出現指數:三顆星
主要考點:此題主要考的對於MVC這種框架的理解。
參考答案:MVC,顧名思義,Model、View、Controller。全部的 界面代碼放在View裏面,全部涉及和界面交互以及URL路由相關的邏輯都在Controller裏面,Model提供數據模型。MVC的架構方式會讓系 統的可維護性更高,使得每一部分更加專一本身的職責,而且MVC提供了強大的路由機制,方便了頁面切換和界面交互。而後能夠結合和WebForm的比較, 談談MVC如何解決複雜的控件樹生成、如何避免了複雜的頁面生命週期。
12、網站優化:網站運行慢,如何定位問題?發現問題如何解決?
出現指數:三顆星
主要考點:此題和問題一相似,考察Web的問題定位能力和優化方案。
參考答案:
瀏覽器F12→網絡→查看http請求數以及每一個請求的耗時,找到問題的根源,而後依次解決,解決方案能夠參考問題一里面的Web優化方案。
十3、說說你最擅長的技術?並說說你是如何使用的?
出現指數:三顆星
主要考點:這是一道很是開放的面試題。最初遇到這種問題,博主很想來一句:你妹,這叫什麼問題!但確實有面試官問到。回頭想一想,其實此題考查你擅長的技術的涉及深度。其實博主以爲對於這個問題,能夠結合你項目中用到的某一個技術來講就行了。
參考答案:
簡單談談MEF在咱們項目裏面的使用吧。
在談MEF以前,咱們必需要先談談DIP、IOC、DI
依賴倒置原則(DIP):一種軟件架構設計的原則(抽象概念)
控制反轉(IoC):一種反轉流、依賴和接口的方式(DIP的具體實現方式)。
依賴注入(DI):IoC的一種實現方式,用來反轉依賴(IoC的具體實現方式)。
什麼意思呢?也就是說,咱們在軟件架構的過程當中,層和層之間經過接口依賴,下層不是 直接給上層提供實現,而是提供接口,具體的實現以依賴注入的方式在運行的時候動態注入進去。MEF就是實現依賴注入的一種組件。它的使用使得UI層不直接 依賴於BLL層,而是依賴於中間的一個IBLL層,在程序運行的時候,經過MEF動態將BLL裏面的實現注入到UI層裏面去,這樣作的好處是減小了層與層 之間的耦合。這也正是面向接口編程方式的體現。
十4、本身寫過JS組件嗎?舉例說明。
出現指數:三顆星
主要考點:此題考的js組件封裝和js閉包的一些用法。通常來講,仍是筆試出現的概率較大。
參考答案:自定義html的select組件
1 //combobox 2 (function ($) { 3 $.fn.combobox = function (options, param) { 4 if (typeof options == 'string') { 5 return $.fn.combobox.methods[options](this, param); 6 } 7 options = .fn.combobox.defaults, options || {}); 8 var target = $(this); 9 target.attr('valuefield', options.valueField);10 target.attr('textfield', options.textField);11 target.empty();12 var option = $('');13 option.attr('value', '');14 option.text(options.placeholder);15 target.append(option);16 if (options.data) {17 init(target, options.data);18 }19 else {20 //var param = {};21 options.onBeforeLoad.call(target, option.param);22 if (!options.url) return;23 $.getJSON(options.url, option.param, function (data) {24 init(target, data);25 });26 }27 28 function init(target, data) {29 $.each(data, function (i, item) {30 var option = $('');31 option.attr('value', item[options.valueField]);32 option.text(item[options.textField]);33 target.append(option);34 });35 options.onLoadSuccess.call(target);36 }37 target.unbind("change"); target.on("change", function (e) { if (options.onChange) return options.onChange(target.val()); }); } $.fn.combobox.methods = { getValue: function (jq) { return jq.val(); }, setValue: function (jq, param) { jq.val(param); }, load: function (jq, url) { (''); option.attr('value', ''); option.text('請選擇'); jq.append(option); (''); option.attr('value', item[jq.attr('valuefield')]); option.text(item[jq.attr('textfield')]); jq.append(option); }); }); } }; $.fn.combobox.defaults = { url: null, param: null, data: null, valueField: 'value', textField: 'text', placeholder: '請選擇', onBeforeLoad: function (param) { }, onLoadSuccess: function () { }, onChange: function (value) { }38 };39 })(jQuery);
調用的時候
1 $("#sel_search_orderstatus").combobox({2 url: '/apiaction/Order/OrderApi/GetOrderStatu',3 valueField: 'VALUE',4 textField: 'NAME'5 });
就能自動從後臺取數據,注意valueField和textField對應要顯示和實際值。
十5、本身寫過多線程組件嗎?簡要說明!
出現指數:三顆星
主要考點:此題是兩年前博主在攜程的一次電話面試中遇到的,其餘地方基本上沒遇到過,其實到如今也不能理解當時面試官問這個問題的目的。但我想,此問題必有出處,估計面試官是想了解你對多線程以及線程池等的理解深度。
知識點:
一、什麼是面向對象?
面向對象說到底就是一種思想,任何事物均可以看做是一個對象。在有些面試題目中也稱之爲OOP(Object Oriented Programming)。分開來解讀就是:
Object:對象
Oriented: 面向的
Programming:程序設計
面向對象就是把一我的或事務的屬性,好比名字,年齡這些定義在一個實體類裏面。存和取的時候直接使用存取實體類就把這我的的名字,年齡這些所有存了,這個實體類就叫對象,這種思想就叫面向對象。
面向對象開發具備如下優勢:
代碼開發模塊化,便於維護。
代碼複用性強
代碼的可靠性和靈活性。
代碼的可讀性和可擴展性。
3 .列舉ASP.NET 頁面之間傳遞值的幾種方式。
答. 1.Request.QueryString
2.Request.Form
3.Session
4.Application
5.Cache
6.Cookie
7.Server.Transfer
8.Database
9.HttpContext的Item屬性等
4.a=10,b=15,請在不使用第三方變量的狀況下,把a、b的值互換
答: int a=a+b; int b=a-b;int a=a-b;
5.用.net作B/S結構的系統,您是用幾層結構來開發,每一層之間的關係以及爲何要這樣分層?
答:通常爲3層:數據訪問層,業務層,表示層。
數據訪問層對數據庫進行增刪查改。
業務層通常分爲二層,業務表觀層實現與表示層的溝通,業務規則層實現用戶密碼的安全等。
表示層爲了與用戶交互例如用戶添加表單。
優勢: 分工明確,條理清晰,易於調試,並且具備可擴展性。
缺點: 增長成本。
6.能用foreach遍歷訪問的對象須要實現 ________________接口或聲明________________方法的類型。
答:IEnumerable 、 GetEnumerator。
7.GC是什麼? 爲何要有GC?
答:GC是垃圾收集器。程序員不用擔憂內存管理,由於垃圾收集器會自動進行管理。要請求垃圾收集,能夠調用下面的方法之一:
System.gc()
Runtime.getRuntime().gc()
8.啓動一個線程是用run()仍是start()?
答:啓動一個線程是調用start()方法,使線程所表明的虛擬處理機處於可運行狀態,這意味着它能夠由JVM調度並執行。這並不意味着線程就會當即運行。run() 方法能夠產生必須退出的標誌來中止一個線程。
9.是否能夠繼承String類?
答:String類是final類故不能夠繼承。
10.session喜歡丟值且佔內存,Cookis不安全,請問用什麼辦法代替這兩種原始的方法
答:redis 或者 memcache。固然,微軟也提供瞭解決方案。iis中因爲有進程回收機制,系統繁忙的話Session會丟失,能夠用Sate server或SQL Server數據庫的方式。
11.IOC容器?
十二、什麼是委託,事件是否是一種委託?
13.c#多線程是什麼?
多線程的優勢:能夠同時完成多個任務;能夠使程序的響應速度更快;能夠節省大量時間進行處理任務;能夠隨時中止任務;能夠設置每一個任務的優先級,以優化程序性能。
14.WebApi概述
Web API是在.NET Framework之上構建的Web的API的框架,Web API是一個編程接口,用於操做可經過標準HTTP方法和標頭訪問的系統,Web API須要基於.NET 3.5或更高版本才能夠進行開發
15.什麼是WebService
webservice是一種跨平臺,跨語言的規範,用於不一樣平臺,不一樣語言開發的應用之間的交互,是基於網絡的、分佈式的模塊化組件,它執行特定的任務,遵照具體的技術規範。
16.存儲過程是什麼?有什麼用?有什麼優勢?用什麼來調用?
存儲過程是預編譯,安全性高,也是大大提升了效率,存儲過程能夠重複使用以減小數據庫開發人員的工做量,複雜的邏輯咱們能夠使用存儲過程完成,在存儲過程當中咱們能夠使用臨時表,還能夠定義變量,拼接sql語句,調用時,只需執行這個存儲過程名,傳入咱們所須要的參數便可。
17.何爲觸發器?
觸發器是一種特殊的存儲過程,主要是經過事件觸發而被執行。它能夠強化約束來維護數據的完整性和一致性,能夠跟蹤數據庫內的操做從而不容許未經許可的更新和變化。能夠級聯運算。
常見的觸發器有三種:分別應用於Insert , Update , Delete 事件。
18.什麼叫作泛型?
只是爲了去掉重複代碼,應對不一樣類型的共同需求。
21 .NET的錯誤處理機制是什麼?
.net錯誤處理機制採用try->catch->finally結構,發生錯誤時,層層上拋,直到找到匹配的Catch爲止。
22.C#能否對內存進行直接的操做?
在.net下,.net引用了垃圾回收(GC)功能,它替代了程序員不過在C#中,不能直接實現Finalize方法,而是在析構函數中調用基類的Finalize()方法。
24.若是在一個B/S結構的系統中須要傳遞變量值,可是又不能使用Session、Cookie、Application,您有幾種方法進行處理?
this.Server.Transfer、Response.Redirect()、QueryString
26.簡要談一下您對微軟.NET架構下remoting和webservice兩項技術的理解以及實際中的應用。
WS主要是可利用HTTP,穿透防火牆。而Remoting能夠利用TCP/IP,二進制傳送提升效率。
remoting是.net中用來跨越machine,process, appdomain進行方法調用的技術,對於三成結構的程序,就能夠使用remoting技術來構建.它是分佈應用的基礎技術.至關於之前的DCOM。
Web Service是一種構建應用程序的普通模型,並能在全部支持internet網通信的操做系統上實施。Web Service令基於組件的開發和web的結合達到最佳,基於組件的對象模型。
27.什麼是反射?
動態獲取程序集信息。
28.override與重載的區別?
重載是方法的名稱相同。參數或參數類型不一樣,進行屢次重載以適應不一樣的須要。
Override是子類對基類中函數的重寫。爲了適應須要。
29.裝箱和拆箱的概念和原理
裝箱是將值類型轉化爲引用類型的過程;
拆箱是將引用類型轉化爲值類型的過程
30.Session有什麼重大BUG,微軟提出了什麼方法加以解決?
是iis中因爲有進程回收機制,系統繁忙的話Session會丟失,能夠用Sate server或SQL Server數據庫的方式存儲Session不過這種方式比較慢,並且沒法捕獲Session的END事件。
參考文獻:https://blog.csdn.net/user2041/article/details/80591365
特性一:正則表達式
相信你們都會很是喜歡這個特性,無須服務器端的檢測,使用瀏覽器的本地功能就能夠幫助你判斷電子郵件的格式,URL,或者是電話格式,防止用戶輸入錯誤的信息,經過使用HTML5的pattern屬性,咱們能夠很方便的整合這個功能,代碼以下:
運行以下:
若是在Firefox瀏覽器中運行,而且輸入錯誤的email地址,會看到以下:
特性二:數據列表元素
在沒有HTML5的日子裏,咱們會選擇使用一些JS或者知名的jQuery UI來實現自動補齊的功能,而在HTML5中,咱們能夠直接使用datalist元素,以下:
摘要:計算機網絡基礎
引言
網絡協議是每一個前端工程師都必需要掌握的知識,TCP/IP 中有兩個具備表明性的傳輸層協議,分別是 TCP 和 UDP,本文將介紹下這二者以及它們之間的區別。
1、TCP/IP網絡模型
計算機與網絡設備要相互通訊,雙方就必須基於相同的方法。好比,如何探測到通訊目標、由哪一邊先發起通訊、使用哪一種語言進行通訊、怎樣結束通訊等規則都須要事先肯定。不一樣的硬件、操做系統之間的通訊,全部的這一切都須要一種規則。而咱們就把這種規則稱爲協議(protocol)。
TCP/IP 是互聯網相關的各種協議族的總稱,好比:TCP,UDP,IP,FTP,HTTP,ICMP,SMTP 等都屬於 TCP/IP 族內的協議。
TCP/IP模型是互聯網的基礎,它是一系列網絡協議的總稱。這些協議能夠劃分爲四層,分別爲鏈路層、網絡層、傳輸層和應用層。
鏈路層:負責封裝和解封裝IP報文,發送和接受ARP/RARP報文等。
網絡層:負責路由以及把分組報文發送給目標網絡或主機。
傳輸層:負責對報文進行分組和重組,並以TCP或UDP協議格式封裝報文。
應用層:負責向用戶提供應用程序,好比HTTP、FTP、Telnet、DNS、SMTP等。
在網絡體系結構中網絡通訊的創建必須是在通訊雙方的對等層進行,不能交錯。 在整個數據傳輸過程當中,數據在發送端時通過各層時都要附加上相應層的協議頭和協議尾(僅數據鏈路層須要封裝協議尾)部分,也就是要對數據進行協議封裝,以標識對應層所用的通訊協議。接下去介紹TCP/IP 中有兩個具備表明性的傳輸層協議----TCP和UDP。
2、UDP
UDP協議全稱是用戶數據報協議,在網絡中它與TCP協議同樣用於處理數據包,是一種無鏈接的協議。在OSI模型中,在第四層——傳輸層,處於IP協議的上一層。UDP有不提供數據包分組、組裝和不能對數據包進行排序的缺點,也就是說,當報文發送以後,是沒法得知其是否安全完整到達的。
它有如下幾個特色:
從上面的動態圖能夠得知,UDP只會把想發的數據報文一股腦的丟給對方,並不在乎數據有無安全完整到達。
5. 頭部開銷小,傳輸數據報文時是很高效的。
UDP 頭部包含了如下幾個數據:
兩個十六位的端口號,分別爲源端口(可選字段)和目標端口
整個數據報文的長度
整個數據報文的檢驗和(IPv4 可選 字段),該字段用於發現頭部信息和數據中的錯誤
所以 UDP 的頭部開銷小,只有八字節,相比 TCP 的至少二十字節要少得多,在傳輸數據報文時是很高效的
3、TCP
當一臺計算機想要與另外一臺計算機通信時,兩臺計算機之間的通訊須要暢通且可靠,這樣才能保證正確收發數據。例如,當你想查看網頁或查看電子郵件時,但願完整且按順序查看網頁,而不丟失任何內容。當你下載文件時,但願得到的是完整的文件,而不只僅是文件的一部分,由於若是數據丟失或亂序,都不是你但願獲得的結果,因而就用到了TCP。
TCP協議全稱是傳輸控制協議是一種面向鏈接的、可靠的、基於字節流的傳輸層通訊協議,由 IETF 的RFC 793定義。TCP 是面向鏈接的、可靠的流協議。流就是指不間斷的數據結構,你能夠把它想象成排水管中的水流。
第一次握手
客戶端向服務端發送鏈接請求報文段。該報文段中包含自身的數據通信初始序號。請求發送後,客戶端便進入 SYN-SENT 狀態。
第二次握手
服務端收到鏈接請求報文段後,若是贊成鏈接,則會發送一個應答,該應答中也會包含自身的數據通信初始序號,發送完成後便進入 SYN-RECEIVED 狀態。
第三次握手
當客戶端收到鏈接贊成的應答後,還要向服務端發送一個確認報文。客戶端發完這個報文段後便進入 ESTABLISHED 狀態,服務端收到這個應答後也進入 ESTABLISHED 狀態,此時鏈接創建成功。
這裏可能你們會有個疑惑:爲何 TCP 創建鏈接須要三次握手,而不是兩次?這是由於這是爲了防止出現失效的鏈接請求報文段被服務端接收的狀況,從而產生錯誤。
TCP 是全雙工的,在斷開鏈接時兩端都須要發送 FIN 和 ACK。
第一次握手
若客戶端 A 認爲數據發送完成,則它須要向服務端 B 發送鏈接釋放請求。
第二次握手
B 收到鏈接釋放請求後,會告訴應用層要釋放 TCP 連接。而後會發送 ACK 包,並進入 CLOSE_WAIT 狀態,此時代表 A 到 B 的鏈接已經釋放,再也不接收 A 發的數據了。可是由於 TCP 鏈接是雙向的,因此 B 仍舊能夠發送數據給 A。
第三次握手
B 若是此時還有沒發完的數據會繼續發送,完畢後會向 A 發送鏈接釋放請求,而後 B 便進入 LAST-ACK 狀態。
第四次握手
A 收到釋放請求後,向 B 發送確認應答,此時 A 進入 TIME-WAIT 狀態。該狀態會持續 2MSL(最大段生存期,指報文段在網絡中生存的時間,超時會被拋棄) 時間,若該時間段內沒有 B 的重發請求的話,就進入 CLOSED 狀態。當 B 收到確認應答後,也便進入 CLOSED 狀態。
3. TCP協議的特色
面向鏈接
面向鏈接,是指發送數據以前必須在兩端創建鏈接。創建鏈接的方法是「三次握手」,這樣能創建可靠的鏈接。創建鏈接,是爲數據的可靠傳輸打下了基礎。
僅支持單播傳輸
每條TCP傳輸鏈接只能有兩個端點,只能進行點對點的數據傳輸,不支持多播和廣播傳輸方式。
面向字節流
TCP不像UDP同樣那樣一個個報文獨立地傳輸,而是在不保留報文邊界的狀況下以字節流方式進行傳輸。
可靠傳輸
對於可靠傳輸,判斷丟包,誤碼靠的是TCP的段編號以及確認號。TCP爲了保證報文傳輸的可靠,就給每一個包一個序號,同時序號也保證了傳送到接收端實體的包的按序接收。而後接收端實體對已成功收到的字節發回一個相應的確認(ACK);若是發送端實體在合理的往返時延(RTT)內未收到確認,那麼對應的數據(假設丟失了)將會被重傳。
提供擁塞控制
當網絡出現擁塞的時候,TCP可以減少向網絡注入數據的速率和數量,緩解擁塞
TCP提供全雙工通訊
TCP容許通訊雙方的應用程序在任什麼時候候都能發送數據,由於TCP鏈接的兩端都設有緩存,用來臨時存放雙向通訊的數據。固然,TCP能夠當即發送一個數據段,也能夠緩存一段時間以便一次發送更多的數據段(最大的數據段大小取決於MSS)
4、TCP和UDP的比較
基礎篇
怎樣建立一個線程
受託管的線程與 Windows線程
前臺線程與後臺線程
名爲BeginXXX和EndXXX的方法是作什麼用的
異步和多線程有什麼關聯
WinForm多線程編程篇
個人多線程WinForm程序總是拋出InvalidOperationException ,怎麼解決?
Invoke,BeginInvoke幹什麼用的,內部是怎麼實現的
每一個線程都有消息隊列嗎?
爲何Winform不容許跨線程修改UI線程控件的值
有沒有什麼辦法能夠簡化WinForm多線程的開發
線程池
線程池的做用是什麼?
全部進程使用一個共享的線程池,仍是每一個進程使用獨立的線程池?
爲何不要手動線程池設置最大值?
.Net線程池有什麼不足?
同步
CLR怎樣實現lock(obj)鎖定?
WaitHandle是什麼,他和他的派生類怎麼使用
什麼是用雙鎖實現Singleton,爲何要這樣作,爲何有人說雙鎖檢驗是不安全的
互斥對象(Mutex)、事件(Event)對象與lock語句的比較
何時須要鎖定
只有共享資源才須要鎖定
把鎖定交給數據庫
瞭解你的程序是怎麼運行的
業務邏輯對事務和線程安全的要求
計算一下衝突的可能性
請多使用lock,少用Mutex
Web和IIS
應用程序池,WebApplication,和線程池之間有什麼關係
Web頁面怎麼調用異步WebService
基礎篇
怎樣建立一個線程
我只簡單列舉幾種經常使用的方法,詳細可參考.Net多線程總結(一)
一)使用Thread類
ThreadStart threadStart=new ThreadStart(Calculate);//經過ThreadStart委託告訴子線程講執行什麼方法,這裏執行一個計算圓周長的方法
Thread thread=new Thread(threadStart);
thread.Start(); //啓動新線程
public void Calculate(){
double Diameter=0.5;
Console.Write("The perimeter Of Circle with a Diameter of {0} is {1}"Diameter,Diameter*Math.PI);
}
二)使用Delegate.BeginInvoke
delegate double CalculateMethod(double Diameter); //申明一個委託,代表須要在子線程上執行的方法的函數簽名
static CalculateMethod calcMethod = new CalculateMethod(Calculate);//把委託和具體的方法關聯起來
static void Main(string[] args)
{
//此處開始異步執行,而且能夠給出一個回調函數(若是不須要執行什麼後續操做也能夠不使用回調)
calcMethod.BeginInvoke(5, new AsyncCallback(TaskFinished), null);
Console.ReadLine();
}
//線程調用的函數,給出直徑做爲參數,計算周長
public static double Calculate(double Diameter)
{
return Diameter * Math.PI;
}
//線程完成以後回調的函數
public static void TaskFinished(IAsyncResult result)
{
double re = 0;
re = calcMethod.EndInvoke(result);
Console.WriteLine(re);
}
三)使用ThreadPool.QueueworkItem
WaitCallback w = new WaitCallback(Calculate);
//下面啓動四個線程,計算四個直徑下的圓周長
ThreadPool.QueueUserWorkItem(w, 1.0);
ThreadPool.QueueUserWorkItem(w, 2.0);
ThreadPool.QueueUserWorkItem(w, 3.0);
ThreadPool.QueueUserWorkItem(w, 4.0);
public static void Calculate(double Diameter)
{
return Diameter * Math.PI;
}
下面兩條來自於http://www.cnblogs.com/tonyman/archive/2007/09/13/891912.html
受託管的線程與 Windows線程
必需要了解,執行.NET應用的線程實際上仍然是Windows線程。可是,當某個線程被CLR所知時,咱們將它稱爲受託管的線程。具體來講,由受託管的代碼建立出來的線程就是受託管的線程。若是一個線程由非託管的代碼所建立,那麼它就是非託管的線程。不過,一旦該線程執行了受託管的代碼它就變成了受託管的線程。
一個受託管的線程和非託管的線程的區別在於,CLR將建立一個System.Threading.Thread類的實例來表明並操做前者。在內部實現中,CLR將一個包含了全部受託管線程的列表保存在一個叫作ThreadStore地方。
CLR確保每個受託管的線程在任意時刻都在一個AppDomain中執行,可是這並不表明一個線程將永遠處在一個AppDomain中,它能夠隨着時間的推移轉到其餘的AppDomain中。
從安全的角度來看,一個受託管的線程的主用戶與底層的非託管線程中的Windows主用戶是無關的。
前臺線程與後臺線程
啓動了多個線程的程序在關閉的時候卻出現了問題,若是程序退出的時候不關閉線程,那麼線程就會一直的存在,可是大多啓動的線程都是局部變量,不能一一的關閉,若是調用Thread.CurrentThread.Abort()方法關閉主線程的話,就會出現ThreadAbortException 異常,所以這樣不行。
後來找到了這個辦法: Thread.IsBackground 設置線程爲後臺線程。
msdn對前臺線程和後臺線程的解釋:託管線程或者是後臺線程,或者是前臺線程。後臺線程不會使託管執行環境處於活動狀態,除此以外,後臺線程與前臺線程是同樣的。一旦全部前臺線程在託管進程(其中 .exe 文件是託管程序集)中被中止,系統將中止全部後臺線程並關閉。經過設置 Thread.IsBackground 屬性,能夠將一個線程指定爲後臺線程或前臺線程。例如,經過將 Thread.IsBackground 設置爲 true,就能夠將線程指定爲後臺線程。一樣,經過將 IsBackground 設置爲 false,就能夠將線程指定爲前臺線程。從非託管代碼進入托管執行環境的全部線程都被標記爲後臺線程。經過建立並啓動新的 Thread 對象而生成的全部線程都是前臺線程。若是要建立但願用來偵聽某些活動(如套接字鏈接)的前臺線程,則應將 Thread.IsBackground 設置爲 true,以便進程能夠終止。
因此解決辦法就是在主線程初始化的時候,設置:Thread.CurrentThread.IsBackground = true;
這樣,主線程就是後臺線程,在關閉主程序的時候就會關閉主線程,從而關閉全部線程。可是這樣的話,就會強制關閉全部正在執行的線程,因此在關閉的時候要對線程工做的結果保存。
常常看到名爲BeginXXX和EndXXX的方法,他們是作什麼用的
這是.net的一個異步方法名稱規範
.Net在設計的時候爲異步編程設計了一個異步編程模型(APM),這個模型不只是使用.NET的開發人員使用,.Net內部也頻繁用到,好比全部的Stream就有BeginRead,EndRead,Socket,WebRequet,SqlCommand都運用到了這個模式,通常來說,調用BegionXXX的時候,通常會啓動一個異步過程去執行一個操做,EndEnvoke能夠接收這個異步操做的返回,固然若是異步操做在EndEnvoke調用的時候尚未執行完成,EndInvoke會一直等待異步操做完成或者超時
.Net的異步編程模型(APM)通常包含BeginXXX,EndXXX,IAsyncResult這三個元素,BeginXXX方法都要返回一個IAsyncResult,而EndXXX都須要接收一個IAsyncResult做爲參數,他們的函數簽名模式以下
IAsyncResult BeginXXX(...);
<返回類型> EndXXX(IAsyncResult ar);
BeginXXX和EndXXX中的XXX,通常都對應一個同步的方法,好比FileStream的Read方法是一個同步方法,相應的BeginRead(),EndRead()就是他的異步版本,HttpRequest有GetResponse來同步接收一個響應,也提供了BeginGetResponse和EndGetResponse這個異步版本,而IAsynResult是兩者聯繫的紐帶,只有把BeginXXX所返回的IAsyncResult傳給對應的EndXXX,EndXXX才知道須要去接收哪一個BeginXXX發起的異步操做的返回值。
這個模式在實際使用時稍顯繁瑣,雖然原則上咱們能夠隨時調用EndInvoke來得到返回值,而且能夠同步多個線程,可是大多數狀況下當咱們不須要同步不少線程的時候使用回調是更好的選擇,在這種狀況下三個元素中的IAsynResult就顯得多餘,咱們一不須要用其中的線程完結標誌來判斷線程是否成功完成(回調的時候線程應該已經完成了),二不須要他來傳遞數據,由於數據能夠寫在任何變量裏,而且回調時應該已經填充,因此能夠看到微軟在新的.Net Framework中已經增強了對回調事件的支持,這總模型下,典型的回調程序應該這樣寫
a.DoWork+=new SomeEventHandler(Caculate);
a.CallBack+=new SomeEventHandler(callback);
a.Run();
(注:我上面講的是廣泛的用法,然而BeginXXX,EndXXX僅僅是一種模式,而對這個模式的實現徹底取決於使用他的開發人員,具體實現的時候你能夠使用另一個線程來實現異步,也可能使用硬件的支持來實現異步,甚至可能根本和異步沒有關係(儘管幾乎沒有人會這樣作)-----好比直接在Beginxxx裏直接輸出一個"Helloworld",若是是這種極端的狀況,那麼上面說的一切都是廢話,因此上面的探討並不涉及內部實現,只是告訴你們微軟的模式,和框架中對這個模式的經典實現)
異步和多線程有什麼關聯
有一句話總結的很好:多線程是實現異步的一種手段和工具
咱們一般把多線程和異步等同起來,實際是一種誤解,在實際實現的時候,異步有許多種實現方法,咱們能夠用進程來作異步,或者使用纖程,或者硬件的一些特性,好比在實現異步IO的時候,能夠有下面兩個方案:
1)能夠經過初始化一個子線程,而後在子線程裏進行IO,而讓主線程順利往下執行,當子線程執行完畢就回調
2)也能夠根本不使用新線程,而使用硬件的支持(如今許多硬件都有本身的處理器),來實現徹底的異步,這是咱們只須要將IO請求告知硬件驅動程序,而後迅速返回,而後等着硬件IO就緒通知咱們就能夠了
實際上DotNet Framework裏面就有這樣的例子,當咱們使用文件流的時候,若是制定文件流屬性爲同步,則使用BeginRead進行讀取時,就是用一個子線程來調用同步的Read方法,而若是指定其爲異步,則一樣操做時就使用了須要硬件和操做系統支持的所謂IOCP的機制
WinForm多線程編程篇
個人多線程WinForm程序總是拋出InvalidOperationException ,怎麼解決?
在WinForm中使用多線程時,經常遇到一個問題,當在子線程(非UI線程)中修改一個控件的值:好比修改進度條進度,時會拋出以下錯誤
Cross-thread operation not valid: Control 'XXX' accessed from a thread other than the thread it was created on.
在VS2005或者更高版本中,只要不是在控件的建立線程(通常就是指UI主線程)上訪問控件的屬性就會拋出這個錯誤,解決方法就是利用控件提供的Invoke和BeginInvoke把調用封送回UI線程,也就是讓控件屬性修改在UI線程上執行,下面列出會報錯的代碼和他的修改版本
ThreadStart threadStart=new ThreadStart(Calculate);//經過ThreadStart委託告訴子線程講執行什麼方法
Thread thread=new Thread(threadStart);
thread.Start();
public void Calculate(){
double Diameter=0.5;
double result=Diameter*Math.PI;
CalcFinished(result);//計算完成須要在一個文本框裏顯示
}
public void CalcFinished(double result){
this.TextBox1.Text=result.ToString();//會拋出錯誤
}
上面加粗的地方在debug的時候會報錯,最直接的修改方法是修改Calculate這個方法以下
delegate void changeText(double result);
public void Calculate(){
double Diameter=0.5;
double result=Diameter*Math.PI;
this.BeginInvoke(new changeText(CalcFinished),t.Result);//計算完成須要在一個文本框裏顯示
}
這樣就ok了,可是最漂亮的方法是不去修改Calculate,而去修改CalcFinished這個方法,由於程序裏調用這個方法的地方可能不少,因爲加了是否須要封送的判斷,這樣修改還能提升非跨線程調用時的性能
delegate void changeText(double result);
public void CalcFinished(double result){
if(this.InvokeRequired){
this.BeginInvoke(new changeText(CalcFinished),t.Result);
}
else{
this.TextBox1.Text=result.ToString();
}
}
上面的作法用到了Control的一個屬性InvokeRequired(這個屬性是能夠在其餘線程裏訪問的),這個屬性代表調用是否來自另非UI線程,若是是,則使用BeginInvoke來調用這個函數,不然就直接調用,省去線程封送的過程
Invoke,BeginInvoke幹什麼用的,內部是怎麼實現的?
這兩個方法主要是讓給出的方法在控件建立的線程上執行
Invoke使用了Win32API的SendMessage,
UnsafeNativeMethods.PostMessage(new HandleRef(this, this.Handle), threadCallbackMessage, IntPtr.Zero, IntPtr.Zero);
BeginInvoke使用了Win32API的PostMessage
UnsafeNativeMethods.PostMessage(new HandleRef(this, this.Handle), threadCallbackMessage, IntPtr.Zero, IntPtr.Zero);
這兩個方法向UI線程的消息隊列中放入一個消息,當UI線程處理這個消息時,就會在本身的上下文中執行傳入的方法,換句話說凡是使用BeginInvoke和Invoke調用的線程都是在UI主線程中執行的,因此若是這些方法裏涉及一些靜態變量,不用考慮加鎖的問題
每一個線程都有消息隊列嗎?
不是,只有建立了窗體對象的線程纔會有消息隊列(下面給出<Windows 核心編程>關於這一段的描述)
當一個線程第一次被創建時,系統假定線程不會被用於任何與用戶相關的任務。這樣能夠減小線程對系統資源的要求。可是,一旦這個線程調用一個與圖形用戶界面有關的函數(例如檢查它的消息隊列或創建一個窗口),系統就會爲該線程分配一些另外的資源,以便它可以執行與用戶界面有關的任務。特別是,系統分配一個T H R E A D I N F O結構,並將這個數據結構與線程聯繫起來。
這個T H R E A D I N F O結構包含一組成員變量,利用這組成員,線程能夠認爲它是在本身獨佔的環境中運行。T H R E A D I N F O是一個內部的、未公開的數據結構,用來指定線程的登記消息隊列(posted-message queue)、發送消息隊列( send-message queue)、應答消息隊列( r e p l y -message queue)、虛擬輸入隊列(virtualized-input queue)、喚醒標誌(wake flag)、以及用來描述線程局部輸入狀態的若干變量。圖2 6 - 1描述了T H R E A D I N F O結構和與之相聯繫的三個線程。
爲何Winform不容許跨線程修改UI線程控件的值
在vs2003下,使用子線程調用ui線程建立的控件的屬性是不會有問題的,可是編譯的時候會出現警告,可是vs2005及以上版本就會有這樣的問題,下面是msdn上的描述
"當您在 Visual Studio 調試器中運行代碼時,若是您從一個線程訪問某個 UI 元素,而該線程不是建立該 UI 元素時所在的線程,則會引起 InvalidOperationException。調試器引起該異常以警告您存在危險的編程操做。UI 元素不是線程安全的,因此只應在建立它們的線程上進行訪問"
從上面能夠看出,這個異常實際是debugger耍的花招,也就是說,若是你直接運行程序的exe文件,或者利用運行而不調試(Ctrl+F5)來運行你的程序,是不會拋出這樣的異常的.大概ms發現v2003的警告對廣大開發者不起做用,因此用了一個比較狠一點的方法.
不過問題依然存在:既然這樣設計的緣由主要是由於控件的值非線程安全,那麼DotNet framework中非線程安全的類千千萬萬,爲何恰恰跨線程修改Control的屬性會有這樣嚴格的限制策略呢?
這個問題我還回答很差,但願博友們可以予以補充
有沒有什麼辦法能夠簡化WinForm多線程的開發
使用backgroundworker,使用這個組建能夠避免回調時的Invoke和BeginInvoke,而且提供了許多豐富的方法和事件
參見.Net多線程總結(二)-BackgroundWorker,我在這裏再也不贅訴
線程池
線程池的做用是什麼
做用是減少線程建立和銷燬的開銷
建立線程涉及用戶模式和內核模式的切換,內存分配,dll通知等一系列過程,線程銷燬的步驟也是開銷很大的,因此若是應用程序使用了完一個線程,咱們能把線程暫時存放起來,以備下次使用,就能夠減少這些開銷
全部進程使用一個共享的線程池,仍是每一個進程使用獨立的線程池?
每一個進程都有一個線程池,一個Process中只能有一個實例,它在各個應用程序域(AppDomain)是共享的,.Net2.0 中默認線程池的大小爲工做線程25個,IO線程1000個,有一個比較廣泛的誤解是線程池中會有1000個線程等着你去取,其實否則, ThreadPool僅僅保留至關少的線程,保留的線程能夠用SetMinThread這個方法來設置,當程序的某個地方須要建立一個線程來完成工做時,而線程池中又沒有空閒線程時,線程池就會負責建立這個線程,而且在調用完畢後,不會馬上銷燬,而是把他放在池子裏,預備下次使用,同時若是線程超過必定時間沒有被使用,線程池將會回收線程,因此線程池裏存在的線程數實際是個動態的過程
爲何不要手動線程池設置最大值?
當我首次看到線程池的時候,腦殼裏的第一個念頭就是給他設定一個最大值,然而當咱們查看ThreadPool的SetMaxThreads文檔時每每會看到一條警告:不要手動更改線程池的大小,這是爲何呢?
其實不管FileStream的異步讀寫,異步發送接受Web請求,甚至使用delegate的beginInvoke都會默認調用 ThreadPool,也就是說不只你的代碼可能使用到線程池,框架內部也可能使用到,更改的後果影響就很是大,特別在iis中,一個應用程序池中的全部 WebApplication會共享一個線程池,對最大值的設定會帶來不少意想不到的麻煩
線程池的線程爲什麼要分類?
線程池有一個方法可讓咱們看到線程池中可用的線程數量:GetAvaliableThread(out workerThreadCount,out iocompletedThreadCount),對於我來講,第一次看到這個函數的參數時十分困惑,由於我指望這個函數直接返回一個整形,代表還剩多少線程,這個函數竟然一次返回了兩個變量.
原來線程池裏的線程按照公用被分紅了兩大類:工做線程和IO線程,或者IO完成線程,前者用於執行普通的操做,後者專用於異步IO,好比文件和網絡請求,注意,分類並不說明兩種線程自己有差異,線程就是線程,是一種執行單元,從本質上來說都是同樣的,線程池這樣分類,舉例來講,就好像某施工工地如今有1000把鐵鍬,規定其中25把給後勤部門用,其餘都給施工部門,施工部門須要大量使用鐵鍬來挖地基(例子土了點,不過說明問題仍是有效的),後勤部門用鐵鍬也就是剷剷雪,剷剷垃圾,給工人師傅修修臨時住房,因此用量不大,顯然兩個部門的鐵鍬自己沒有區別,可是這樣的劃分就爲管理兩個部門的鐵鍬提供了方便
線程池中兩種線程分別在什麼狀況下被使用,兩者工做原理有什麼不一樣?
下面這個例子直接說明了兩者的區別,咱們用一個流讀出一個很大的文件(大一點操做的時間長,便於觀察),而後用另外一個輸出流把所讀出的文件的一部分寫到磁盤上
咱們用兩種方法建立輸出流,分別是
建立了一個異步的流(注意構造函數最後那個true)
FileStream outputfs=new FileStream(writepath, FileMode.Create, FileAccess.Write, FileShare.None,256,true);
建立了一個同步的流
FileStream outputfs = File.OpenWrite(writepath);
而後在寫文件期間查看線程池的情況
string readpath = "e:\RHEL4-U4-i386-AS-disc1.iso";
string writepath = "e:\kakakak.iso";
byte[] buffer = new byte[90000000];
//FileStream outputfs=new FileStream(writepath, FileMode.Create, FileAccess.Write, FileShare.None,256,true);
//Console.WriteLine("異步流");
//建立了一個同步的流
FileStream outputfs = File.OpenWrite(writepath);
Console.WriteLine("同步流");
//而後在寫文件期間查看線程池的情況
ShowThreadDetail("初始狀態");
FileStream fs = File.OpenRead(readpath);
fs.BeginRead(buffer, 0, 90000000, delegate(IAsyncResult o)
{
outputfs.BeginWrite(buffer, 0, buffer.Length,
delegate(IAsyncResult o1)
{
Thread.Sleep(1000);
ShowThreadDetail("BeginWrite的回調線程");
}, null);
Thread.Sleep(500);//this is important cause without this, this Thread and the one used for BeginRead May seem to be same one
},
null);
Console.ReadLine();
public static void ShowThreadDetail(string caller)
{
int IO;
int Worker;
ThreadPool.GetAvailableThreads(out Worker, out IO);
Console.WriteLine("Worker: {0}; IO: {1}", Worker, IO);
}
輸出結果
異步流
Worker: 500; IO: 1000
Worker: 500; IO: 999
同步流
Worker: 500; IO: 1000
Worker: 499; IO: 1000
這兩個構造函數建立的流均可以使用BeginWrite來異步寫數據,可是兩者行爲不一樣,當使用同步的流進行異步寫時,經過回調的輸出咱們能夠看到,他使用的是工做線程,而非IO線程,而異步流使用了IO線程而非工做線程
其實當沒有制定異步屬性的時候,.Net實現異步IO是用一個子線程調用fs的同步Write方法來實現的,這時這個子線程會一直阻塞直到調用完成.這個子線程其實就是線程池的一個工做線程,因此咱們能夠看到,同步流的異步寫回調中輸出的工做線程數少了一,而使用異步流,在進行異步寫時,採用了 IOCP方法,簡單說來,就是當BeginWrite執行時,把信息傳給硬件驅動程序,而後當即往下執行(注意這裏沒有額外的線程),而當硬件準備就緒, 就會通知線程池,使用一個IO線程來讀取
.Net線程池有什麼不足
沒有提供方法控制加入線程池的線程:一旦加入線程池,咱們沒有辦法掛起,終止這些線程,惟一能夠作的就是等他本身執行
1)不能爲線程設置優先級
2)一個Process中只能有一個實例,它在各個AppDomain是共享的。ThreadPool只提供了靜態方法,不只咱們本身添加進去的WorkItem使用這個Pool,並且.net framework中那些BeginXXX、EndXXX之類的方法都會使用此Pool。
3)所支持的Callback不能有返回值。WaitCallback只能帶一個object類型的參數,沒有任何返回值。
4)不適合用在長期執行某任務的場合。咱們經常須要作一個Service來提供不間斷的服務(除非服務器down掉),可是使用ThreadPool並不合適。
下面是另一個網友總結的什麼不須要使用線程池,我以爲挺好,引用下來
若是您須要使一個任務具備特定的優先級。
若是您具備可能會長時間運行(並所以阻塞其餘任務)的任務。
若是您須要將線程放置到單線程單元中(全部 ThreadPool 線程均處於多線程單元中)。
若是您須要與該線程關聯的穩定標識。例如,您應使用一個專用線程來停止該線程、將其掛起或按名稱發現它。
鎖定與同步
CLR怎樣實現lock(obj)鎖定?
從原理上講,lock和Syncronized Attribute都是用Moniter.Enter實現的,好比以下代碼
object lockobj=new object();
lock(obj){
//do things
}
在編譯時,會被編譯爲相似
try{
Moniter.Enter(obj){
//do things
}
}
catch{}
finally{
Moniter.Exit(obj);
}
而[MethodImpl(MethodImplOptions.Synchronized)]標記爲同步的方法會在編譯時被lock(this)語句所環繞
因此咱們只簡單探討Moniter.Enter的實現
(注:DotNet並不是使用Win32API的CriticalSection來實現Moniter.Enter,不過他爲託管對象提供了一個相似的結構叫作Syncblk)
每一個對象實例頭部都有一個指針,這個指針指向的結構,包含了對象的鎖定信息,當第一次使用Moniter.Enter(obj)時,這個obj對象的鎖定結構就會被初時化,第二次調用Moniter.Enter時,會檢驗這個object的鎖定結構,若是鎖沒有被釋放,則調用會阻塞
WaitHandle是什麼,他和他的派生類怎麼使用
WaitHandle是Mutex,Semaphore,EventWaitHandler,AutoResetEvent,ManualResetEvent共同的祖先,他們包裝了用於同步的內核對象,也就是說是這些內核對象的託管版本。
Mutex:相似於一個接力棒,拿到接力棒的線程才能夠開始跑,固然接力棒一次只屬於一個線程(Thread Affinity),若是這個線程不釋放接力棒(Mutex.ReleaseMutex),那麼沒辦法,其餘全部須要接力棒運行的線程都知道能等着看熱鬧
Semaphore:相似於一個小桶,裏面裝了幾個小球,凡是拿到小球就能夠跑,好比指定小桶裏最初有四個小球,那麼開始的四個線程就能夠直接拿着本身的小球開跑,可是第五個線程一看,小球被拿光了,就只好乖乖的等着有誰放一個小球到小桶裏(Semophore.Release),他才能跑,可是這裏的遊戲規則比較特殊,咱們能夠隨意向小桶裏放入小球,也就是說我能夠拿走一個小球,放回去倆,甚至一個都不拿,放回去5個,這樣就有五個線程能夠拿着這些小球運行了.咱們能夠規定小桶裏有開始有幾個小球(構造函數的第一個參數),也能夠規定最多不能超過多少小球(構造函數的第二個參數)
ManualResetEvent,AutoResetEvent能夠參考http://www.cnblogs.com/uubox/archive/2007/12/18/1003953.html
什麼是用雙鎖實現Singleton,爲何要這樣作,雙鎖檢驗是不安全的嗎?
使用雙鎖檢驗技巧來實現單件,來自於Java社區
public static MySingleton Instance{
get{
if(_instance!=null)}{
lock(_instance){
if(s_valuenull){
_instance= new MySingleton();
}
}
}
}
}
這樣作實際上是爲了提升效率,比起
public static MySingleton Instance{
get{
lock(_instance){
if(s_valuenull){
_instance= new MySingleton();
}
}
前一種方法在instance建立的時候不須要用lock同步,從而增進了效率
在java中這種技巧被證實是不安全的詳細見http://www.cs.umd.edu/~pugh/java/memoryModel/
可是在.Net下,這樣的技巧是成立的,由於.Net使用了改進的內存模型
而且在.Net下,咱們能夠使用LazyInit來實現單件
private static readonly _instance=new MySingleton()
public static MySingleton Instance{
get{return _instance}
}
當第一此使用_instance時,CLR會生成這個對象,之後再訪問這個字段,將會直接返回
互斥對象(Mutex),信號量(Semaphore),事件(Event)對象與lock語句的比較
首先這裏所謂的事件對象不是System.Event,而是一種用於同步的內核機制
互斥對象和事件對象屬於內核對象,利用內核對象進行線程同步,線程必需要在用戶模式和內核模式間切換,因此通常效率很低,但利用互斥對象和事件對象這樣的內核對象,能夠在多個進程中的各個線程間進行同步。
lock或者Moniter是.net用一個特殊結構實現的,不涉及模式切換,也就是說工做在用戶方式下,同步速度較快,可是不能跨進程同步
何時須要鎖定?
剛剛接觸鎖定的程序員每每以爲這個世界很是的危險,每一個靜態變量彷佛都有可能產生競爭
首先鎖定是解決競爭條件的,也就是多個線程同時訪問某個資源,形成意想不到的結果,好比,最簡單的狀況,一個計數器,若是兩個線程同時加一,後果就是損失了一個計數,可是頻繁的鎖定又可能帶來性能上的消耗,還有最可怕的狀況,死鎖
到底什麼狀況下咱們須要使用鎖,什麼狀況下不用呢?
只有共享資源才須要鎖定
首先,只有能夠被多線程訪問的共享資源才須要考慮鎖定,好比靜態變量,再好比某些緩存中的值,屬於線程內部的變量不須要鎖定
把鎖定交給數據庫
數據庫除了存儲數據以外,還有一個重要的用途就是同步,數據庫自己用了一套複雜的機制來保證數據的可靠和一致性,這就爲咱們節省了不少的精力.保證了數據源頭上的同步,咱們多數的精力就能夠集中在緩存等其餘一些資源的同步訪問上了
瞭解你的程序是怎麼運行的
實際上在web開發中大多數邏輯都是在單個線程中展開的,不管asp.net仍是php,一個請求都會在一個單獨的線程中處理,其中的大部分變量都是屬於這個線程的,根本沒有必要考慮鎖定,固然對於asp.net中的application對象中的數據,咱們就要當心一些了
WinForm中凡是使用BeginInvoke和Invoke調用的方法也都不須要考慮同步,由於這用這兩個方法調用的方法會在UI線程中執行,所以實際是同步的,因此若是調用的方法中存在某些靜態變量,不須要考慮鎖定
業務邏輯對事務和線程安全的要求
這條是最根本的東西,開發徹底線程安全的程序是件很費時費力的事情,在電子商務等涉及金融系統的案例中,許多邏輯都必須嚴格的線程安全,因此咱們不得不犧牲一些性能,和不少的開發時間來作這方面的工做,而通常的應用中,許多狀況下雖然程序有競爭的危險,咱們仍是能夠不使用鎖定,好比有的時候計數器少一多一,對結果無傷大雅的狀況下,咱們就能夠不用去管他
計算一下衝突的可能性
我之前曾經談到過,架構不要過設計,其實在這裏也同樣,假如你的全局緩存裏的某個值天天只有幾百或者幾千個訪問,而且訪問時間很短,而且分佈均勻(實際上這是大多數的狀況),那麼衝突的可能性就很是的少,也許每500天才會出現一次或者更長,從7*24小時安全服務的角度來看,也徹底符合要求,那麼你還會爲這樣萬分之一的可能性花80%的精力去設計嗎?
請多使用lock,少用Mutex
若是你必定要使用鎖定,請儘可能不要使用內核模塊的鎖定機制,好比.net的Mutex,Semaphore,AutoResetEvent,ManuResetEvent,使用這樣的機制涉及到了系統在用戶模式和內核模式間的切換,因此性能差不少,可是他們的優勢是能夠跨進程同步線程,因此應該清楚的瞭解到他們的不一樣和適用範圍
Web和IIS
應用程序池,WebApplication,和線程池之間有什麼關係
一個應用程序池是一個獨立的進程,擁有一個線程池,應用程序池中能夠有多個WebApplication,每一個運行在一個單獨的AppDomain中,這些WebApplication公用一個線程池
不一樣的AppDomain保證了每一個WebApplication的靜態變量不會互相干擾,不一樣的應用程序池保證了一個網站癱瘓,其餘不一樣進程中的站點還能正常運行
下圖說明了他們的關係
Web頁面怎麼調用異步WebService
把Page的Async屬性設置爲true,就能夠調用異步的方法,可是這樣調用的效果可能並不如咱們的相像,請參考Web中使用多線程來加強用戶體驗
序列化和反序列化的實現
http://www.javashuo.com/article/p-zvdeasuu-h.html
C#模態對話框和非模態對話框
模態對話框
彈出窗口阻止調用窗口的全部消息響應。
只有在彈出窗口結束後調用窗口才能繼續。
在模態窗口「關閉」後,能夠讀取模態窗口中信息,包括窗口的返回狀態,窗口子控件的值。
非模態對話框
能夠在彈出窗口和調用窗口之間隨意切換。
調用窗口調用show方法後,下面的代碼能夠當即執行。在非模態窗口關閉後,窗口的全部資源被釋放,窗口不存在,沒法獲取窗口的任何信息。
所謂模態對話框,就是指除非採起有效的關閉手段,用戶的鼠標焦點或者輸入光標將一直停留在其上的對話框。非模態對話框則不會強制此種特性,用戶能夠在當前對話框以及其餘窗口間進行切換
概念說明
1 模態窗口
打開模態窗口後,只要不關閉該窗口,鼠標焦點或者光標就會一直停留在該窗口上。只有關閉該窗口後,調用窗口才能繼續。模態窗口關閉後,仍能夠讀取模態窗口中的信息,如窗口的返回狀態等。
2 非模態窗口
打開非模態窗口後,仍能夠操做調用窗口。關閉非模態窗口,該窗口將不復存在,會釋放窗口的全部資源,因此沒法獲得該窗口的任何信息。
實例說明
1 創建Windows窗體程序ShowAndShowDialogExp,程序主畫面包含兩個按鈕,用於打開模態窗口和非模態窗口(以下圖所示)。
2 編寫按鈕的Click事件代碼
private void button1_Click(object sender, EventArgs e)
{
Form frm1 = new Form();
frm1.Text = "我是模態窗口!";
frm1.ShowDialog();//打開模態窗口(對話框)}
private void button2_Click(object sender, EventArgs e)
{
Form frm2 = new Form();
frm2.Text = "我是非模態窗口!";
frm2.Show();//打開非模態窗口(對話框)
}
3 運行代碼,進行操做體驗
點擊按鈕「打開模態窗口」,打開模態窗口frm1,窗口標題欄顯示「我是模態窗口!」,此時沒法切換到調用窗口,當關閉該窗口後,又能夠繼續操做調用窗口了。
點擊按鈕「打開非模態窗口」,打開非模態窗口frm2,此時,能夠仍切換到調用窗口操做調用窗口。
4 實例結論
C#中使用Show()方法打開非模態窗口,使用ShowDialog()方法打開模態窗口。
5 進階
修改前面按鈕的Click事件代碼,修改後的代碼以下所示。
private void button1_Click(object sender, EventArgs e)
{
Form frm1 = new Form();
frm1.Text = "我是模態窗口!";
frm1.ShowDialog();//打開模態窗口(輟對話框)MessageBox.Show(frm1.DialogResult.ToString());
}
private void button2_Click(object sender, EventArgs e)
{
Form frm2 = new Form();
frm2.Text = "我是非模態窗口!";
frm2.Show();//打開非模態窗口(對話框)MessageBox.Show(frm2.DialogResult.ToString());
}
朋友,發現跟前面代碼的區別了嗎?
呵呵,僅僅加了一句輸出彈出窗口的DialogResult屬性值的代碼而已。
再次執行代碼,程序的運行狀況是:
點擊「打開模態窗口」打開模態窗口,接着關閉模態窗口,會彈出消息框,輸出「Cancel」(frm1.DialogResult.ToString()的結果)。
點擊「打開非模態窗口」打開非模態窗口後,便會彈出消息框,輸出「None」(frm2.DialogResult.ToString()的結果)。
從程序執行狀況咱們瞭解到:
執行Show()方法後,後面的代碼會當即執行;而執行ShowDialog()方法後,後面的代碼須要等彈出窗口關閉後才能及時執行。
前面說到:模態窗口關閉後,仍能夠讀取模態窗口中的信息。
這主要是由於:當「關閉」模態窗口後,窗體並無被真的被「關閉」,由於用戶點擊「關閉」按鈕或者設置DialogResult屬性值時,並無調用窗體的Close方法,只是將窗體的Visible屬性賦值爲false,隱藏了窗體而已。這樣隱藏的窗體是能夠被從新顯示的,且窗體資源並無被釋放。因此,在你真的不須要這個窗體時,必定要記得Dispose一下哦。
爲了說明這一切,修改前面打開模態窗口的按鈕Click事件代碼。
private void button1_Click(object sender, EventArgs e)
{
Form frm1 = new Form();
frm1.Text = "我是模態窗口!";
frm1.ShowDialog();//打開模態窗口(對話框)MessageBox.Show(frm1.DialogResult.ToString());
frm1.Visible = true;
}
模塊之間的接口應該儘可能少而簡單。
Web api:http://www.javashuo.com/article/p-ygftwkxz-kp.html