1.String與Stringbuilder的區別:
String自動分配內存大小,每次往里面寫新東西,就會重新分配一段內存,然后把地址指向新的這塊空間,是由C#內存管理自動管理的。
Stringbuilder會事先分配好一段空間,append的時候,是操作的同一塊空間,如果新串超過原本大小,內存空間自動加倍。
2.C#如何調用c++靜態庫(lib):
可以用CLR(新)或者Managed c++(老)將lib封裝成managed? dll供C#直接調用。
將lib封裝成native dll,C#中通過DllImport調用dll。
將lib封裝成native dll, 再用CLR封裝native dll成managed? dll供C#直接調用。
將lib封裝為COM,在C#中調用COM。
3.長度為100的字符串,從abcdefgh中隨機抽取100個字符組成:
usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;namespacecsharpconsole{classProgram{staticvoidMain(string[] args)? ? ? ? {? ? ? ? ? ? StringBuilder strOut =newStringBuilder(0,100);? ? ? ? ? ? String strSrc ="a, b, c, d, e, f, g, h";? ? ? ? ? ? String[] strDes = strSrc.Split(',');intlen = strDes.Length;? ? ? ? ? ? Random rd =newRandom();inti =0;for(; i <100; i++)? ? ? ? ? ? {? ? ? ? ? ? ? ? StrOut = strDes[rd.Next(len)];? ? ? ? ? ? }? ? ? ? ? ? Console.ReadKey();? ? ? ? }? ? }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
4.產生一個int數組,長度為100,并向其中隨機插入1-100,并且不能重復:
usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;usingSystem.Collections;namespacecsharpconsole{classProgram{staticvoidMain(string[] args)? ? ? ? {int[] intArr =newint[100];? ? ? ? ? ? ArrayList myList =newArrayList();? ? ? ? ? ? Random rd =newRandom();intnum =0;/* 1-100產生隨機數 */inti =0;/* 生成100個不重復的1-100的數 */while(myList.Count <100)? ? ? ? ? ? {? ? ? ? ? ? ? ? num = rd.Next(1,101);? ? ? ? ? ? ? ? if (!myList.Contains(num))? ? ? ? ? ? ? ? {? ? ? ? ? ? ? ? ? ? myList.Add(num);? ? ? ? ? ? ? ? }? ? ? ? ? ? }for(; i <100; i++)? ? ? ? ? ? {? ? ? ? ? ? ? ? intArr[i] = (int)myList[i];? ? ? ? ? ? }foreach(inta in intArr)? ? ? ? ? ? {? ? ? ? ? ? ? ? Console.WriteLine(a);? ? ? ? ? ? }? ? ? ? ? ? Console.ReadKey();? ? ? ? }? ? }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
5.把一個Array復制到ArrayList里:
foreach(objectoinarray){? ? arrayList.Add(o);}
1
2
3
4
1
2
3
4
6.寫一個函數計算當參數為N的值:1-2+3-4+5-6+7……+N:
usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;namespacecsharpconsole{classProgram{staticvoidMain(string[] args)? ? ? ? {intnum =0;? ? ? ? ? ? String str ="";intsum =0;? ? ? ? ? ? Console.WriteLine("請輸入一個100以內的數:");? ? ? ? ? ? str = Console.ReadLine();? ? ? ? ? ? num =int.Parse(str);for(inti =1; i <= num; i++)? ? ? ? ? ? {? ? ? ? ? ? ? ? sum += ((int)Math.Pow(-1, i +1)) * i;? ? ? ? ? ? }? ? ? ? ? ? Console.WriteLine(sum);? ? ? ? ? ? Console.ReadKey();? ? ? ? }? ? }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
7.斐波拉契數列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34……:
usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;namespacecsharpconsole{classProgram{staticintMyALG(intnum)? ? ? ? {? ? ? ? ? ? if (num <=0)? ? ? ? ? ? {return0;? ? ? ? ? ? }elseif ((1== num) || (2== num))? ? ? ? ? ? {return1;? ? ? ? ? ? }else{return(MyALG(num -1) + MyALG(num -2));? ? ? ? ? ? }? ? ? ? }staticvoidMain(string[] args)? ? ? ? {intresult =0;? ? ? ? ? ? result = MyALG(30);? ? ? ? ? ? Console.WriteLine(result.ToString());? ? ? ? ? ? Console.ReadKey();? ? ? ? }? ? }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
8.理解接口的作用:
9.虛方法(virtual)和抽象類(abstract)的區別和聯系:
(1)、抽象方法只有聲明沒有實現代碼,需要在子類中實現;虛擬方法有聲明和實現代碼,并且可以在子類中重寫,也可以不重寫使用父類的默認實現。
(2)、抽象類不能被實例化(不可以new),只能實例化實現了全部抽象方法的派生類;而包含虛方法的類可以實例化。
(3)、虛方法與多態性關系密切,虛方法允許派生類完全或部分重寫該類的方法,需寫方法體。抽象方法只是一個定義,沒有方法體,也就是沒有{},也不要在里面寫內容。
(4)、抽象方法是虛擬方法兩個相像的一點是都用override重寫。
10.值類型和引用類型的區別:
值類型:存儲在堆棧中。bool, byte, chat, decimal, double, enum, float, int, long, sbyte, short, strut, uint, ulong, ushort。
引用類型:存儲在托管堆中。class, delegate, interface, object, string。引用類型包含一個指針,指向堆中存儲對象本身的位置。因為引用類型只包含引用,不包含實際的值,對方法體內參數所做的任何修改都將影響傳遞給方法調用的引用類型的變量。
托管代碼:基于CLR的語言編譯器開發的代碼稱為托管代碼。
托管堆:是CLR中自動內存管理的基礎。初始化新進程時,運行時會為進程保留一個連續的地址空間區域。這個保留的地址空間被稱為托管堆。托管堆維護著一個指針,用它指向將在堆中分配的下一個對象的地址。最初,該指針設置為指向托管堆的基址。
由于對對象的引用會在程序運行過程中被傳遞,所以引用類型不能夠被用戶方便的釋放,.NET的垃圾收集處理機制,會在引用為0的時候,自動釋放掉引用類型變量。
11.結構和類的區別:
結構是值類型,類是引用類型;結構不能有構造函數和析構函數;類可以同時有構造函數和析構函數;結構不支持繼承,而類支持繼承。
12.委托(delegate)和事件(event):
委托:委托是類型安全,面向對象的函數指針的實現,并且在許多一個組件需要回調到使用它的組件這樣的情況下使用。
事件:事件是使一個類或對象能夠提供通知的成員。事件聲明像域聲明一樣,除了聲明包含event關鍵字并且類型必須為委托類型。
13.對象類型(object)和動態類型(dynamic)的區別:
對象類型:是所有數據類型的終極基類。Object是System.Object類的別名。當一個值類型轉換為對象類型時,則被稱為裝箱;另一方面,當一個對象類型轉換為值類型時,則被稱為 拆箱。
動態類型:可以存儲任何類型的值在動態數據類型變量中。這些變量的類型檢查是在運行時發生的。
動態類型與對象類型相似,但是對象類型變量的類型檢查是在編譯時發生的,而動態類型變量的類型檢查是在運行時發生的。
14.傳入參數:
包括值參數,引用參數,輸出參數和參數數組。
引用參數(ref關鍵字):實參在調用前需要初始化,并且值可以被傳入和傳出;
輸出參數(out關鍵字):實參在調用前不必初始化,在方法中必須要初始化,值只能傳出不能傳入。
15.C#與C的區別:
C#不支持#include語句。它只用using語句。
C#中,類定義在最后不使用分號。
C#不支持多重繼承。
數據類型的顯示轉換在C#中比C中安全很多。
C#中switch也可用于字符串值。
命令行參數數組(params,即可變參數)的行為在C#中和C中不一樣。
16.接口和類的區別:
(1)、接口類似于類,但接口的成員都沒有執行方式,它只是方法、屬性、事件和索引符的組合而已,并且也只能包含這四種成員;類除了這四種成員之外還可以別的成員(如字段)。
(2)、不能實例化一個接口,接口只包括成員的簽名;而類可以實例化(abstract類除外)。
(3)、接口沒有構造函數,類有構造函數。
(4)、接口不能進行運算符的重載,類可以進行運算符重載。
(5)、接口的成員沒有任何修飾符,其成員總是公共的,而類的成員則可以有修飾符(如:虛擬或者靜態)。
(6)、派生于接口的類必須實現接口中所有成員的執行方式,而從類派生則不然。
17.const和readonly區別:
readonly修飾的字段,其初始化僅是固定了其引用(地址不能修改),但它引用的對象的屬性是可以更改的。
const聲明的字段不能使用static修飾符,而readonly可以使用static修飾符。
const字段只能在聲明時初始化,而readonly可以在聲明時或在構造函數中初始化。
const字段的值在在編譯階段就計算出來了,而readonly的值在運行時計算。
18.異常(try、catch、finally、throw):
try:可能拋出異常的代碼;
catch:出現異常后針對的處理辦法;
finally:不論是否出現異常都執行的代碼(通常是一些釋放資源的代碼),finally塊是可以省略的。
一個try塊可以對應多個catch塊,其中按拋出的異常類尋找對應的catch塊,也可能找不到,如果一直沒有找到就會終止程序,返回一條錯誤代碼。
異常處理可以互相嵌套,在內層找不到對應的處理代碼,會向外層找。
(1)、try、catch、finally例子:
/*
結果:
finally1
試圖除以0.
finally2
*/staticvoidMain(string[] args){intn1 =10;intn2 =0;intresult;/* 由于除數為0,拋出異常,內層找不到會找外層的異常catch處理 */try{/* try catch的嵌套 */try{? ? ? ? ? ? result = n1 / n2;? ? ? ? ? ? Console.WriteLine("{0}", result);? ? ? ? }catch(MemberAccessException e)? ? ? ? {? ? ? ? ? ? Console.WriteLine(e.Message);? ? ? ? }finally{? ? ? ? ? ? Console.WriteLine("finally1");? ? ? ? }? ? }/* 2個外層catch */catch(DivideByZeroException e)? ? {/* 最后找到是由此catch處理 */Console.WriteLine(e.Message);? ? }catch(Exception e)? ? {? ? ? ? Console.WriteLine(e.Message);? ? }finally{? ? ? ? Console.WriteLine("finally2");? ? }? ? Console.ReadKey();}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
(2)、自定義異常throw例子:
/*
結果:
除數為0
*//* 自定義異常必須繼承于ApplicationException類 */privateclassTestException : ApplicationException{publicstringmsg;publicTestException(stringmsg)? ? {this.msg = msg;? ? }}/* 定義方法和異常拋出代碼 */staticdoublemul(doublen1,doublen2){if(n2 ==0.0)? ? {/* 除數為0就拋出異常 */thrownewTestException("除數為0");? ? }returnn1 / n2;}staticvoidMain(string[] args){doublen1 =10.0;doublen2 =0.0;doubleresult;try{/* double除法默認除數為0會返回一個很大的值 */result = mul(n1, n2);? ? ? ? Console.WriteLine(result);? ? }catch(TestException e)? ? {? ? ? ? Console.WriteLine(e.msg);? ? }? ? Console.ReadKey();}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
19.特性(Attribute)和反射(Reflection):
特性為類、方法、結構、枚舉、組件等添加自定義的屬性(元數據),反射可以獲取這些屬性,需要的時候通過反射提取出來使用。
20.屬性(Property)和索引器(Indexer):
屬性要通過一個叫做訪問器(accessor)的東東,對私有成員變量進行安全帶驗證的訪問方式。即get、set屬性。
索引器是可以通過方便的方式訪問對象(實例化的類)中的成員數組或集合。(注意這里是數組或集合)
21.線程:
System.Threading名字空間。
Start():啟動線程;
Sleep(int):靜態方法,暫停當前線程指定的毫秒數;
Abort():通常使用該方法來終止一個線程;
Suspend():該方法并不終止未完成的線程,它僅僅掛起線程,以后還可恢復;
Resume():恢復被Suspend()方法掛起的線程的執行。
(1)、線程使用:
namespace Test{? ? class Program? ? {staticvoidMain(string[] args)? ? ? ? {? ? ? ? ? ? Thread t1 =newThread(newThreadStart(TestMethod));? ? ? ? ? ? Thread t2 =newThread(newParameterizedThreadStart(TestMethod));? ? ? ? ? ? t1.IsBackground =true;//設置當前子線程為后臺線程,為后臺線程意味著,主線程關閉后,其他子線程都同時關閉t2.IsBackground =true;? ? ? ? ? ? t1.Start();? ? ? ? ? ? t2.Start("hello");? ? ? ? ? ? Console.ReadKey();? ? ? ? }publicstaticvoidTestMethod()? ? ? ? {? ? ? ? ? ? Console.WriteLine("不帶參數的線程函數");? ? ? ? }publicstaticvoidTestMethod(objectdata)? ? ? ? {stringdatastr = dataasstring;? ? ? ? ? ? Console.WriteLine("帶參數的線程函數,參數為:{0}", datastr);? ? ? ? }? ? } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
(2)、線程池:
namespace Test{? ? class Program? ? {staticvoidMain(string[] args)? ? ? ? {//將工作項加入到線程池隊列中,這里可以傳遞一個線程參數ThreadPool.QueueUserWorkItem(TestMethod,"Hello");? ? ? ? ? ? Console.ReadKey();? ? ? ? }publicstaticvoidTestMethod(objectdata)? ? ? ? {stringdatastr = dataasstring;? ? ? ? ? ? Console.WriteLine(datastr);? ? ? ? }? ? }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
(3)、Lock互斥鎖:
就是多線程訪問臨界區代碼,一次只能讓一個線程調用,以保護全局變量。這里要注意,lock只能鎖定一個引用類型變量,即一個地址。
22.task/taskfactory:
后面補充,暫時用不到這么深入的技術。
23.Parallel:
后面補充,暫時用不到這么深入的技術。
24.有空的時候研究一下CLR、元數據、IL。