1.?????? [C#語言基礎]請簡述拆箱和裝箱。
答:
裝箱操作:
值類型隱式轉換為object類型或由此值類型實現的任何接口類型的過程。
1.在堆中開辟內存空間。
2.將值類型的數據復制到堆中。
3.返回堆中新分配對象的地址。
拆箱操作:
object類型顯示轉換為值類型或從接口類型到實現該接口值類型的過程。
1.判斷給定類型是否是裝箱時的類型。
2.返回已裝箱實例中屬于原值類型字段的地址。
2.?????? ?[.NET(C#)] attribute,property,markup,tap翻譯
答:attribute翻譯成特性,用來標識類,方法 。
property翻譯為屬性,性質用于存取類的字段 。
markup翻譯成標記。
tag翻譯成標簽。
3.?????? [.NET(C#)] 程序集的重要特性
答:程序集的一個重要特性是它們包含的元數據描述了對應代碼中定義的類型和方法。
4.?????? ?[.NET(C#)] ref與out關鍵字
答:ref 關鍵字使參數按引用傳遞。其效果是,當控制權傳遞回調用方法時,在方法中對參數所做的任何更改都將反映在該變量中。若要使用 ref 參數,則方法定義和調用方法都必須顯式使用 ref 關鍵字。
out 關鍵字會導致參數通過引用來傳遞。這與 ref 關鍵字類似,不同之處在于 ref 要求變量必須在傳遞之前進行初始化。若要使用 out 參數,方法定義和調用方法都必須顯式使用 out 關鍵字。
5.?????? ?[.NET(C#)] new 關鍵字用法。
答:1) new 運算符 :用于創建對象和調用構造函數。
2) new 修飾符 :用于向基類成員隱藏繼承成員。
3) new 約束 :用于在泛型聲明中約束可能用作類型參數的參數的類型。
6.?????? [.NET(C#)] C#中,string str = null 與 string str = "",說明區別。
答:string str = "" 初始化對象分配空間。
string str = null 表示一個空引用,沒有占用空間。//實際情況是,string為null時依然為"",但該題常考。
7.?????? [.NET(C#)]什么是序列化?
答:序列化是將對象狀態轉換為可保持或傳輸的格式的過程。 與序列化相對的是反序列化,它將流轉換為對象。這兩個過程結合起來,可以輕松地存儲和傳輸數據。
8.?????? ?[.NET(C#)] sealed 修飾符有什么特點
答:
1) sealed 修飾符可以應用于類、實例方法和屬性。密封類不能被繼承。密封方法會重寫基類中的方法,但其本身不能在任何派生類中進一步重寫。當應用于方法或屬性時,sealed 修飾符必須始終與 override一起使用。
2) 將密封類用作基類或將 abstract 修飾符與密封類一起使用是錯誤的。
3) 結構是隱式密封的;因此它們不能被繼承。
9.?????? [.NET(C#)] 詳述.NET里class和struct的異同。
答:
相同點:
1) 語法類似。
不同點:
1) class是引用類型,繼承自System.Object類; struct是值類型,繼承自System.ValueType類,因此不具多態性。但是注意,System.ValueType是個引用類型。
2) 從職能觀點來看,class表現為行為; 而struct常用于存儲數據。
3) class支持繼承,可以繼承自類和接口; 而struct沒有繼承性,struct不能從class繼承,也不能作為class的基類,但struct支持接口繼承。
4) 實例化時,class要使用new關鍵字; 而struct可以不使用new關鍵字,struct在聲明時就進行了初始化過程,所有的成員變量均默認為0或null。
10.? [.NET(C#)]如何選擇結構還是類。
答:1) 堆棧的空間有限,對于大量的邏輯的對象,創建類要比創建結構好一些。
2) 結構表示如點、矩形和顏色這樣的輕量對象。例如,如果聲明一個含有 1000 個點對象的數組,則將為引用每個對象分配附加的內存。在此情況下,結構的成本較低。
3) 在表現抽象和多級別的對象層次時,類是最好的選擇。
4) 大多數情況下該類型只是一些數據時,結構時最佳的選擇。
11.? [.NET(C#)]抽象類(abstract class)和接口(interface)的區別。
答:
抽象類:
1) 抽象方法只作聲明,而不包含實現,可以看成是沒有實現體的虛方法。
2) 抽象類不能被實例化。
3) 抽象類可以但不是必須有抽象屬性和抽象方法,但是一旦有了抽象方法,就一定要把這個類聲明為抽象類。
4) 具體派生類必須覆蓋基類的抽象方法。
5) 抽象派生類可以覆蓋基類的抽象方法,也可以不覆蓋。如果不覆蓋,則其具體派生類必須覆蓋它們。
接口:
1) 接口不能被實例化。
2) 接口只能包含方法聲明。
3) 接口的成員包括方法、屬性、索引器、事件。
4) 接口中不能包含常量、字段(域)、構造函數、析構函數、靜態成員。
5) 接口中的所有成員默認為public,因此接口中不能有private修飾符。
6) 派生類必須實現接口的所有成員。
7) 一個類可以直接實現多個接口,接口之間用逗號隔開。
8) 一個接口可以有多個父接口,實現該接口的類必須實現所有父接口中的所有成員。
抽象類和接口的異同:
相同點:
1) 都可以被繼承。
2) 都不能被實例化。
3) 都可以包含方法聲明。
4) 派生類必須實現未實現的方法。
區 別:
1) 抽象基類可以定義字段、屬性、方法實現。接口只能定義屬性、索引器、事件、和方法聲明,不能包含字段。
2) 抽象類是一個不完整的類,需要進一步細化,而接口是一個行為規范。微軟的自定義接口總是后帶able字段,證明其是表述一類“我能做。。。”。
3) 接口可以被多重實現,抽象類只能被單一繼承。
4) 抽象類更多的是定義在一系列緊密相關的類間,而接口大多數是關系疏松但都實現某一功能的類中。
5) 抽象類是從一系列相關對象中抽象出來的概念, 因此反映的是事物的內部共性;接口是為了滿足外部調用而定義的一個功能約定, 因此反映的是事物的外部特性。
6) 接口基本上不具備繼承的任何具體特點,它僅僅承諾了能夠調用的方法。
7) 接口可以用于支持回調,而繼承并不具備這個特點。
8) 抽象類實現的具體方法默認為虛的,但實現接口的類中的接口方法卻默認為非虛的,當然您也可以聲明為虛的。
9) 如果抽象類實現接口,則可以把接口中方法映射到抽象類中作為抽象方法而不必實現,而在抽象類的子類中實現接口中方法。
12.? [.NET(C#)]什么叫應用程序域?
答:1) 操作系統和運行庫環境通常會在應用程序間提供某種形式的隔離。
2) 應用程序域為安全性、可靠性、版本控制以及卸載程序集提供了隔離邊界。
3) 應用程序域可以理解為一種輕量級進程。起到安全的作用。占用資源小。
13.? [.NET(C#)]什么是強類型?
答:為所有變量指定數據類型稱為“強類型”。C#是強類型語言。
14.? [.NET(C#)]托管代碼。
答:使用基于公共語言運行庫的語言編譯器開發的代碼稱為托管代碼;托管代碼具有許多優點,例如:跨語言集成、跨語言異常處理、增強的安全性、版本控制和部署支持、簡化的組件交互模型、調試和分析服務等。
15.? [.NET(C#)]什么是CTS?
答:CTS:通用系統類型 Common Type System。所有.NET語言共享這一類型系統,實現它們之間無縫的互操作。該方案還提供了語言之間的繼承性。
16.? [.NET(C#)]什么是CLR?
答:CLR:公共語言運行庫 Common Language Runtime。是一個運行時環境,它負責資源管理(內存分配和垃圾收集),并保證應用和底層操作系統之間必要的分離。
17.? [.NET(C#)]什么是CLS?
答:CLS:公共語言規范 Common Language Specification。可以保證C#組件與其他語言組件間的互操作性。
18.? [.NET(C#)]什么是委托?
答:1) 委托是一種引用方法的類型。
2) 委托類似于 C++ 函數指針,但它是類型安全的。
3) 委托允許將方法作為參數進行傳遞。
4) 委托可用于定義回調方法。
19.? [.NET(C#)]活動目錄的作用。
答:1) Active Directory存儲了有關網絡對象的信息,并且讓管理員和用戶能夠輕松地查找和使用這些信息。
2) Active Directory使用了一種結構化的數據存儲方式,并以此作為基礎對目錄信息進行合乎邏輯的分層組織。
20.? [.NET(C#)]在.NET中,配件的意思。
答:程序集(中間語言,源數據,資源,裝配清單)。
21.? ?[.NET(C#)]值類型和引用類型的區別。
答:1) 值類型通常被分配在棧上,它的變量直接包含變量的實例,使用效率比較高。
2) 引用類型分配在托管堆上,引用類型的變量通常包含一個指向實例的指針,變量通過該指針來引用實例。
3) 一個是值COPY,一個是地址COPY。
值類型
引用類型
內存分配地點
分配在棧中
分配在堆中
效率
效率高,不需要地址轉換
效率低,需要進行地址轉換
內存回收
使用完后,立即回收
使用完后,不是立即回收,等待GC回收
賦值操作
進行復制,創建一個同值新對象
只是對原有對象的引用
函數參數與返回值
是對象的復制
是原有對象的引用,并不產生新的對象
類型擴展
不易擴展
容易擴展,方便與類型擴展
22.? ?[.NET(C#)].NET中的垃圾回收機制。
答:.NET Framework 的垃圾回收器管理應用程序的內存分配和釋放。每次使用 new
運算符創建對象時,運行庫都從托管堆為該對象分配內存。只要托管堆中有地址空間可用,運行庫就會繼續為新對象分配空間。但是,內存不是無限大的。最終,垃圾回收器必須執行回收以釋放一些內存。垃圾回收器優化引擎根據正在進行的分配情況確定執行回收的最佳時間。當垃圾回收器執行回收時,它檢查托管堆中不再被應用程序使用的對象并執行必要的操作來回收它們占用的內存。
23.? ?[.NET(C#)]什么是索引器?如何使用索引器?
答:索引器允許類或結構的實例按照與數組相同的方式進行索引。索引器類似于屬性,不同之處在于它們的訪問器采用參數。可以用任意類型索引。
1) 索引器使得對象可按照與數組相似的方法進行索引。
2) get 訪問器返回值。set 訪問器分配值。
3) this 關鍵字用于定義索引器。
4) value 關鍵字用于定義由 set 索引器分配的值。
5) 索引器不必根據整數值進行索引,由您決定如何定義特定的查找機制。
6) 索引器可被重載。
7) 索引器可以有多個形參,例如當訪問二維數組時。
24.? [.NET(C#)]進程和線程的區別。
答:1) 進程是系統進行資源分配和調度的單位。
2) 線程是CPU調度和分派的單位。
3) 一個進程可以有多個線程,這些線程共享這個進程的資源。
25.? [.NET(C#)]啟動一個線程是用run()還是start()?
答:啟動一個線程是調用start()方法,導致操作系統將當前實例的狀態更改為ThreadState.Running。
26.? [.NET(C#)]構造器Constructor是否可被override(重寫)?
答:構造器Constructor不能被繼承,因此不能重寫override,但可以被重載Overloade。
27.? [.NET(C#)]靜態成員和抽象類
答:靜態成員override、virtual 或 abstract。
抽象類不能是密封的sealed或靜態的static。
28.? ?[.NET(C#)]在C#中using和new這兩個關鍵字有什么意義。
答:using 關鍵字有兩個主要用途:
1) 作為指令,用于為命名空間創建別名或導入其他命名空間中定義的類型。
2) 作為語句,用于定義一個范圍,在此范圍的末尾將釋放對象。
new 關鍵字:新建實例或者隱藏父類方法
29.? [.NET(C#)].NET的錯誤處理機制。
答:.NET錯誤處理機制采用try->catch->finally結構。 throw
發生錯誤時,層層上拋,直到找到匹配的catch為止。
30.? [.NET(C#)]error和exception有什么區別。
答:error 表示恢復不是不可能但很困難的情況下的一種嚴重問題。比如說內存溢出。
不可能指望程序能處理這樣的情況。
exception 表示一種設計或實現問題。
也就是說,它表示如果程序運行正常,從不會發生的情況。
31.? [.NET(C#)]UDP連接和TCP連接的異同。
答:1) TCP(Transmission Control Protocol)傳輸控制協議:一種面向連接的、可靠的、基于字節流的運輸層通信協議,三次握手。
2) UDP(User Datagram Protocol)用戶數據報協議:它不屬于連接型協議,因而具有資源消耗小,處理速度快的優點。缺點是易丟失數據包。
32.? [.NET(C#)]System.String 和System.StringBuilder有什么區別?
答:1) System.String是不可變的字符串。
2) System.StringBuilder存放了一個可變的字符串,并提供一些對這個字符串修改的方法。
3) String類在執行字符串拼接的操作上,用“+”會產生新的對象,占用內存。
4) StringBuilder類只是修改字符串的內容,不建立新的對象。
33.? [.NET(C#)]const和readonly有什么區別?
答:1) const 字段只能在該字段的聲明中初始化。
2) 不允許在常數聲明中使用 static 修飾符。
3) readonly 字段可以在聲明或構造函數中初始化。因此,根據所使用的構造函數,readonly 字段可能具有不同的值。
4) 另外,const 字段是編譯時常數,而 readonly 字段可用于運行時常數。
34.? [.NET(C#)]C#中的委托是什么?事件是不是一種委托?
答:委托可以把一個方法作為參數代入另一個方法。
委托可以理解為指向一個函數的引用。
事件是一種特殊的委托。
35.? ?[.NET(C#)]什么是受管制的代碼?
答:在類型或成員的聲明中使用 unsafe 修飾符。因此,類型或成員的整個正文范圍均被視為不安全上下文,無法由 CLR 進行驗證的代碼。
36.? ?[.NET(C#)]面向對象語言三大特性。
答:封裝、繼承、多態。
37.? [.NET(C#)]能用foreach遍歷訪問的對象需要實現什么接口或聲明什么方法的類型。
答:聲明IEnumerable接口或實現GetEnumerator()方法。
38.? [.NET(C#)]接口是否可繼承接口? 抽象類是否可實現(implements)接口? 抽象類是否可繼承實體類(concrete class)?
答:接口可以繼承接口。抽象類可以實現(implements)接口,抽象類是否可繼承實體類,但前提是實體類必須有明確的構造函數。
39.? [.NET(C#)]是否可以繼承String類?
答:String類是sealed類故不可以繼承。
40.? [.NET(C#)]數組有沒有length()這個方法? String有沒有length()這個方法?
答:數組、String類都沒有Length()方法,它們只有Length屬性。
41.? [.NET(C#)]成員變量和成員函數前加static的作用。
答:即使沒有創建類的實例,也可以調用該類中的靜態方法、字段、屬性或事件。如果創建了該類的任何實例,不能使用實例來訪問靜態成員。靜態成員通常用于表示不會隨對象狀態而變化的數據或計算。
42.? [.NET(C#)]什么是虛函數?什么是抽象函數?
答:1) 虛函數:沒有實現的,可由子類繼承并重寫的函數。
2) 抽象函數:規定其非虛子類必須實現的函數,必須被重寫。
43.? [.NET(C#)]C#中的三元運算符是?
答:?:。格式如下:ndition ? first_expression : second_expression。
44.? [.NET(C#)]當整數a賦值給一個object對象時,整數a將會被?
答:裝箱。
45.? [.NET(C#)]委托聲明的關鍵字是?
答:delegate.
46.? ?[.NET(C#)]在.Net中所有可序列化的類都被標記為?
答:[Serializable]
47.? ?[.NET(C#)]利用operator聲明且僅聲明了==,有什么錯誤么?
答:要同時修改Equale和GetHash() ? 重載了"==" 就必須重載 "!="。
48.? [智力題] 62-63=1 等式不成立,請移動一個數字(不可以移動減號和等于號),使得等式成立,如何移動?
答:62移動成2的6次方,26。
49.? [.NET(C#)]C#可否對內存進行直接的操作?
答:可以使用指針。也就是非安全代碼,就是不在 CLR 完全控制下執行的代碼,它有可能會導致一些問題,因此他們必須用 “unsafe” 進行表明。
50.? ?[.NET(C#)] &和&&的區別。
&是位運算符,表示按位與運算。
&&是邏輯運算符,表示邏輯與(and)
51.? [.NET(C#)]重載的方法是否可以改變返回值的類型?
可以。
52.? [.NET(C#)]如何把一個Array復制到ArrayList里?
(1) 實現1
string[] s ={ "111", "22222" };
ArrayList list = new ArrayList();
list.AddRange(s);
(2)實現2
string[] s ={ "111", "22222" };
ArrayList list = new ArrayList(s);
53.? [.NET(C#)]什么是強名?
強名是由程序集的標識加上公鑰和數字簽名組成的,其中,程序集的標識包括簡單文本名稱、版本號和區域性信息(如果提供的話)。它使用對應的私鑰從程序集文件中生成。(程序集文件包含程序集清單,其中包含組成程序集的所有文件的名稱和哈希。)
54.? [.NET(C#)]C#中幾種循環的方法,并指出他們的不同:
1. for:使用于確定次數的循環。
2. foreach:使用于遍歷的元素是只讀的。//Unity中此處是個坑,建議不要用foreach
3. while:次數不確定,條件隨機變化。
4. do...while:次數不確定,條件隨機變化,但至少要保證能被執行一次。
55.? [.NET(C#)]請簡述一下用Socket進行同步通訊編程的詳細步驟
1. 在應用程序和遠程設備中使用協議和網絡地址初始化套接字。
2. 在應用程序中通過指定端口和地址建立監聽。
3. 遠程設備發出連接請求。
4. 應用程序接受連接產生通信scoket。
5. 應用程序和遠程設備開始通訊(在通訊中應用程序將掛起直到通訊結束)。
6. 通訊結束,關閉應用程序和遠程設備的Socket回收資源。
56.? [.NET(C#)] try {}里有一個return語句,那么緊跟在這個try后的finally {}里的code會不會被執行,什么時候被執行,在return前還是后?
答:會執行,在return前執行。
57.? [.NET(C#)] 寫出程序的輸出結果:
publicclassA
{publicvirtualvoidFun1(inti )
{
Console.WriteLine( i );
}publicvoidFun2( A a )
{
a.Fun1(1);
Fun1(5);
}
}publicclassB : A
{publicoverridevoidFun1(inti )
{base.Fun1( i +1);
}publicstaticvoidMain()
{
B b=newB();
A a=newA();
a.Fun2( b );
b.Fun2( a );
}
}
答案:
2
5
1
6
58.? [.NET(C#)]求以下表達式的值,寫出您想到的一種或幾種實現方法:1 - 2 + 3 - 4 +......+ m
答案:
publicstaticvoidMain()
{intinput =int.Parse( Console.ReadLine() );intsum =0;for(inti =0; i <= input; i++)
{if( ( i %2) ==1)
{
sum+=i;
}else{
sum= sum -i;
}
}
Console.WriteLine( sum );
}
59.? ?[.NET(C#)]兩個對象值相同(x.equals(y) == true),但卻可有不同的hash code,這句話對不對?
答:不對,有相同的hash code。
60.? [.NET(C#)] swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上?
答案:可以作用在byte和long上,也可以作用在string上。
61.? [.NET(C#)] short s1 = 1; s1 = s1 + 1;有什么錯?short s1 = 1; s1 += 1;有什么錯?
答: 1. short s1 = 1; s1 = s1 + 1;有錯,s1是short型,s1+1是int型,不能隱式轉化為short型。可修改為s1 =(short)(s1 + 1) 。
2. short s1 = 1; s1 += 1正確。
62.? ?[.NET(C#)] 字符串處理問題
題目:需要實現對一個字符串的處理,首先將該字符串首尾的空格去掉,如果字符串中間還有連續空格的話,僅保留一個空格,即允許字符串中間有多個空格,但連續的空格數不可超過一個。
答案:
string inputStr = " xx xx ";
inputStr = Regex.Replace( inputStr.Trim(), @"/s+", " " );
63.? [.NET(C#)]下面這段代碼輸出什么?為什么?
int i = 5;
int j = 5;
if( Object.ReferenceEquals( i, j ) )
Console.WriteLine( "Equal" );
else
Console.WriteLine( "Not Equal" );
答案:Not Equal。因為比較的是對象
64.? [.NET(C#)] public static const int A=1;這段代碼有錯誤么?是什么?
答:const不能用static修飾。
65.? ?[.NET(C#)]下面的代碼中有什么錯誤嗎?
class A
{
public virtual void F()
{
Console.WriteLine( "A.F" );
}
}
abstract class B : A
{
public abstract override void F();//abstract與override關鍵字可以同時使用
}
答案:沒有錯誤!可以通過編譯器。
注意:網上有資料說abstract與override關鍵字不可以同時使用,這種說法是錯誤的 !
66.? [.NET(C#)] 以下是一些C#中的枚舉型的定義,其中錯誤的用法有?
A. public enum var1{ Mike = 100, Nike = 102, Jike }
B. public enum var1{ Mike = “1”, Nike, Jike }
C. public enum var1{ Mike=-1 , Nike, Jike }
D. public enum var1{ Mike , Nike , Jike }
答案B
67.???? [.NET(C#)] 下面的例子中產生的輸出結果是什么?
class A
{
public static int X;
static A()
{
X = B.Y + 1;
}
}
class B
{
public static int Y = A.X + 1;
static B()
{
}
static void Main()
{
Console.WriteLine( "X={0},Y={1}", A.X, B.Y );
}
}
答:x=1,y=2
68.? [.NET(C#)] 寫出程序的輸出結果
class Class1
{
private string str = "Class1.str";
private int i = 0;
static void StringConvert( string str )
{
str = "string being converted.";
}
static void StringConvert( Class1 c )
{
c.str = "string being converted.";
}
static void Add( int i )
{
i++;
}
static void AddWithRef( ref int i )
{
i++;
}
static void Main()
{
int i1 = 10;
int i2 = 20;
string str = "str";
Class1 c = new Class1();
Add( i1 );
AddWithRef( ref i2 );
Add( c.i );
StringConvert( str );
StringConvert( c );
Console.WriteLine( i1 );
Console.WriteLine( i2 );
Console.WriteLine( c.i );
Console.WriteLine( str );
Console.WriteLine( c.str );
}
}
答案:10, 21, 0, str, string being converted
注意:此處加逗號“,”是為了答案看起來清晰,實際結果是縱向排列的,因為調用了Console.WriteLine()。
69.? [.NET(C#)] 寫出程序的輸出結果
public abstract class A
{
public A()
{
Console.WriteLine( ‘A‘ );
}
public virtual void Fun()
{
Console.WriteLine( "A.Fun()" );
}
}
public class B : A
{
public B()
{
Console.WriteLine( ‘B‘ );
}
public new void Fun()
{
Console.WriteLine( "B.Fun()" );
}
public static void Main()
{
A a = new B();
a.Fun();
}
}
答案:
A
B
A.Fun()
70.? [C#語言基礎]簡述string與StringBuilder相比的優點。
答:
string的字符串為常量不可修改。
1.可以滿足字符串常量池的需要。即對于創建相同文本時,string為同一對象。
2.允許string對象緩存HashCode。字符串不變形保證了hash碼的唯一性。
3.安全性,string被許多的類庫用來當做參數。
StringBuilder實際是一個char類型的集合,完成了組裝拼接等工作。
String更適合做程序的參數,StringBuilder用于做String類型的組裝。
71.? [C#語言基礎]C#StringBuilder類型比string類型的優勢是什么?
答:
StringBuilder的優勢在于拼接字符串。
//String的優勢在于對字符串做一些處理,在使用過程中看具體的需求。
72.? ?[C#語言基礎]編寫程序判斷整數46234的每位相加和。
答:
int number = 46234;
string strNumber=number.ToString();
int length = strNumber.Length;
方法1:
int result=0;
for (int i = 0; i < length; i++)
{
result += number % 10;
number \= 10;
}
方法2:
for (int i = 0; i < length; i++)
{
result += number / (int)Math.Pow(10, i) % 10;
}
方法3:
for (int i = 0; i < strNumber.Length; i++)
{
result += int.Parse(strNumber[i].ToString());
}
注:
73.? [算法]請使用冒泡排序,對一維數組進行降序排列。
答:
冒泡排序:它重復地走訪過要排序的數列,一次比較兩個元素,如果它們的順序錯誤就把他們交換過來。走訪數列的工作是重復地進行直到沒有再需要交換。
冒泡排序算法的運作如下:
l? 比較相鄰元素。如果第一個比第二個大,就交換它們。
l? 對每一對相鄰元素做同樣的工作,從開始第一隊到結尾的最后一對。在這一點,最后的元素會使最大的數。
l? 針對所有的元素重復以上的步驟,除了最后一個。
l? 持續每次對越來越少的元素重復上面的步驟,知道沒有任何一對數字需要比較。
寫法1
public void Bubble1(int[] a)
{
bool b;
int tmp;
for (int i = 0; i < a.Length; i++)
{
b = false;
for (int j = i+1; j < a.Length ; j++)
{
if (a[j] > a[i])
{
tmp = a[j];
a[j] = a[i];
a[i] = tmp;
b = true;
}
}
if(!b)break;
}
}
寫法2
void Bubble2(int[] a)
{
bool b=false;
int tmp;
for(int i=0;i
{
b=false;
for(int j=0;j
{
if(a[j]
{
tmp=a[j];
a[j]=a[j+1];
a[j+1]=tmp;
b=true;
}
}
if(!b) break;
}
}
寫法3
void Bubble3(int[] a)
{
bool b=true;
int j=0;
int temp;
do
{
b=false;
for(int i;i
{
if(a[i]
{
temp=a[i];
a[i]=a[i+1];
a[i+1]=temp;
b=true;
}
}
j++;
}
while(b);
}
74.? ?[C#語言基礎][值類型引用類型]以下代碼輸出結果是什么?原因是什么?
object o1 = 1;
object o2 = o1;
o1 = 2;
Console.WriteLine(o2);
答:
1;
原因:o1將數據1在堆中引用賦值給o2,而后又將引用指向數據2,故o2仍指向數據1的引用。
75.? [C#語言基礎]請寫出定義方法的語法。
答:
[訪問修飾符][可選修飾符] 返回類型 方法名稱(參數列表)
{
//方法體;
return 結果;
}
76.? [C#語言基礎]請簡述string字符串不可變性的原因?
答:
在很多語言當中如Java\C#中字符串string被設計成具有不可變性的。從系統優化方面考慮這樣的設計好處主要由三點。
首先,它允許在一個字符串上執行各種操作,而不實際地更改字符串。
字符串不可變,還因為這在操作或訪問一個字符串時不會發成線程同步問題。
除此之外,CLR可通過一個String對象共享多個完全一致的String內容。這樣能減少系統中的字符串數量,者正是字符串留用技術的目的。
1.字符串常量池的需要。字符串常量池是內存堆中一個特殊的存儲區域,當創建一個string對象時,假設此字符串值已經存在于常量池中,則不會創建一個新的對象,而是引用已經存在的對象。
2.允許string對象緩存HashCode。字符串不變性保證了hash碼的唯一性,因此可以放心地進行緩存,這是一種性能優化手段,因為這不必每次都去計算新的哈希碼。
3.安全性。string被許多的類庫用來當做參數,例如網絡連接URL,文件路徑Path,還有反射機制所需要的String參數等,假若string可變的,將會引起各種安全隱患。
綜上,string不可變的原因包括設計考慮,效率優化問題,以及安全性三大方面。
另:在C++中string類型是可變的。
77.? [C#語言基礎]請簡述方法重載OverLoad?
答:
方法名稱相同,但參數列表不同稱為方法重載。用于在不同條件下解決同一類型的問題。
78.? [C#語言基礎]請給出以下代碼輸出結果:
class A
{
public static int a;
static A()
{
a = B.b + 1;
}
}
class B
{
public static int b;
static B()
{
b = A.a + 1;
}
}
static void Main()
{
Console.WriteLine(A.a);
Console.WriteLine(B.b);
}
答:2? ,1
79.? [C#語言基礎]請給出以下代碼輸出結果:
class C
{
public static int a;
public C()
{
a++;
}
static C()
{
a++;
}
}
static void Main()
{
C c1 = new C();
C c2 = new C();
C c3 = new C();
Console.WriteLine(C.a);
}
答:4
80.? [C#語言基礎]在類的構造函數前加上static會報什么錯?為什么?
答:
靜態函數沒有訪問修飾符,其他C#代碼從來不調用它,但在加載類時,總是由.NET運行庫調用它,所以像public或private這樣的訪問修飾符就沒有任何意義。出于同樣原因,靜態構造函數不能帶任何參數,一個類也只能有一個靜態構造函數。靜態構造函數只能訪問類的靜態成員,不能訪問類的實例成員。
也就是說只加static不會報錯,加了static再加了別的就會報錯。
81.? ?[C#語言基礎]C#函數Func(string a,string b)用Lambda表達式怎么寫?
答:(a,b)=>{}
注:該題有兩種錯誤可能:
一種是方法沒有些返回值即Func(string a,string b)為 void Func(string a,string b)此時,Lambda表達式可寫作(a,b)=>{}
一種是Func為Func此時Lambda可寫作a=>b//a,b為string類型
82.? [C#語言基礎]數列1,1,2,3,5,8,13...第n為數是多少?用C#遞歸算法實現。答:
public static int Fibonacci(int num)//Fibonacci
{
return (num==0||num==1)?1:(Fibonacci(num-2)+Fibonacci(num-1));
}
注:計算斐波那契數列依據數列定義來建立方法是不推薦的寫法。因為此時計算第n位的數的時間復雜度為O((3/2)n)。相比較而言,利用循環可以將時間復雜度縮小到O(n)該方法較為實用,而且實現簡單,在沒有特殊要求的情況下屬于建議的寫法。另一種優化的寫法可以將時間復雜度優化到O(logn),實現代碼較復雜,且隱含的時間常數較大。但適合面試者展示其知識面和代碼實現的能力。
兩種寫法如下:
寫法一:
public long Fibonacci1(int num)
{
return (num==0||num==1)?1:(Fibonacci1(num-2)+Fibonacci1(num-1));
}
寫法二:
public long Fibonacci2(int num)
{
int result[2]={0,1};
if(n<2)
return result[n];
long fibOne=1;
long fibTwo=0;
long fibN=0;
for(int i=2;i<=n;i++)
{
fibN=fibOne+fibTwo;
fibTwo=fibOne;
fibOne=fibN;
}
return fibN;
}
83.? [C#語言基礎]請簡述值類型和引用類型的區別。
答:
從概念上區分,值類型時直接存儲其值,而引用類型是存儲對值的引用。
實際中,對于值類型的對象,初始化一個實例,該實例代表的是其內部存儲的數據本身。而引用類型的對象,初始化一個實例,該實例代表的是其初始化數據在內存當中的引用。
值類型隱式繼承自System.ValueType.該類為抽象類,只能序列化,不能被顯式繼承。
值類型:枚舉,結構
引用類型:數組,委托,類,接口
84.? [C#語言基礎]請簡述ArrayList和List<>的主要區別
答:
ArrayList是非泛型列表,存儲數據是把所有的數據都當成object類型數據,存在裝箱問題,取出來使用的時候存在拆箱問題,裝箱拆箱會使性能變差,而且存在數據安全問題,但是優點在于可以讓值類型和引用類型相互轉換。
List是泛型列表,在使用的時候才會去定義數據類型,泛型避免了拆裝箱的問題,存入讀取熟讀較快,類型也更安全。
85.? [C#語言基礎]請簡述GC(垃圾回收)產生的原因,并描述如何避免?
解析:首先,這道題的描述是不嚴謹的,GC作為CLR的一種機制是由系統調用的,只要運行與CLR上的托管代碼GC的工作本身是不可避免的。
但是拋開這些細節不談,我可以在這里寫把我認為這道題可能涉及到的東西寫一下。
如果只把GC理解成一種可以自動釋放內存的方式,使程序員省去了手動釋放內存的煩惱,或試圖引用已釋放的內存空間的錯誤,這無疑是片面的,雖然這的確是GC非常重要的功能。但GC的作用遠不如此。
GC的產生是與CLR堆內存特殊的分配方式有關的。CLR要求所有的資源都從托管堆分配,托管堆有一個指針NextObjPtr它的初始為保留地址空間的基地址。NextObjPtr指向下一個對象在堆中的分配位置。每當添加一個對象,NextObjPtr指針的值就會加上對象占據的字節數。這樣做有兩個好處:
首先,在許多應用程序中,差不多同時分配的對象彼此間有較強的聯系,而且經常差不多在同一時間訪問。在垃圾回收環境中,如果對象在內存中連續分配,會由于引用的本地性而獲得性能上的提升。具體地說,這意味著進程的工作集小于非托管環境中運行相似的應用程序。
另一方面,這意味著代碼使用的對象可以全部駐留在CPU的緩存中,加快CPU對這些對象的訪問速度。
但托管堆具有這些好處,是因為它做了一個相當大膽的假設,地址的空間和存儲是無限的。那么如何讓它由假設變為可實現的,這就是GC垃圾回收的工作。
GC的垃圾回收算法是基于世代法和啟發式算法的。
世代法是指將堆分為0代,1代,2代。每當0代的堆滿時就觸發一次垃圾回收。當第0代的的內存并沒被釋放,就會被提升到1代,如果1代在被回收時仍然保留的內存,就會被提升到2代。這樣壓縮空間的的方法保證了堆內存的連續性,增加了訪問對象的速度。而啟發式算法是指在基于應用程序對新建對象的模式,進行啟發式的對第1代,第2代堆進行釋放,或擴大第0代的堆空間。
建議只有在以下兩種情況下才調用Dispose或Close:確定必須清理資源;或者確定可以安全地調用Dispose或Close,并希望將對象從中介列表中刪除,禁止對象提升(到另一代)從而提高性能。
那么避免因為GC過程而影響性能的編程方法如下:
因為GC的目標引用地址都是存在棧上的,所以盡量不要用太深的棧,比如遞歸。
合理的使用new避免不必要的對象新建次數。
不要一次性大量申請內存。
對運行時string對象盡量不要使用+來構建,而要用StringBuilder
86.? ?[C#語言基礎]請描述Interface接口與abstract抽象類之間的不同。
答:
語法不同:
1.抽象類中可以有字段,接口沒有。
2.抽象類中可以有實現成員,接口只能包含抽象成員。
3.抽象類中所有成員修飾符都可以使用,接口中所有的成員都是對外的,所以不需要修飾符修飾。
用法不同:
1.抽象類是概念的抽象,接口關注與行為。
2.抽象類的子類與父類的關系是泛化關系,耦合度較高,而實現類和接口之間是實現關系,耦合度比泛化低。
3.一個類只能繼承自一個類,但是可以實現多個接口。
87.? ?[C#語言基礎]下列代碼在運行時會產生幾個臨時對象?
string a="abc";//1個對象
a=(a.ToUpper()+"123").Substring(0,2);
答:三個臨時對象
注:string a="abc";//1個對象
a=(a.ToUpper()+"123").Substring(0,2);
a.ToUpper()//1個臨時對象
"123"http://1個臨時對象
a.ToUpper()+"123"http://1臨時個對象
.Substring(0,2)//1個對象由于它將引用賦給了a所以它不是臨時對象
在語句運行時結束后不存在引用的對象。
88.? [C#語言基礎]下列代碼在運行中會發生什么問題?如何避免?
List Is=new List(new int[]{1,2,3,4,5});
foreach(int item in Is)
{
Console.WriteLine(item*item);
Is.Remove(item);
}
答:會產生運行時錯誤,拋出一個InvalidOperationException異常,因為foreach是只讀的。不能一邊遍歷一邊修改。使用foreach時候不要對內容進行修改。
89.? [C#語言基礎]請簡述關鍵字Sealed用在類聲明和函數(方法)聲明時的作用?
答:sealed訪問修飾符用于類時,表示該類不能被繼承;對于方法表示不能重寫該方法。當應用于方法或屬性時,sealed 修飾符必須始終與 override 一起使用。
注:
若要確定是否密封類、方法或屬性,通常應考慮以下兩點:
派生類利用自定義類的功能所獲得的可能好處。
派生類在修改類之后導致其無法正常工作或按預期工作的可能性。
90.? [C#語言基礎]請簡述private,public,protected,internal的區別?
答:public:對任何類和成員都公開,無限制訪問
private:僅對該類公開
protected:對該類和其他派生類公開
internal:只能在包含該類的程序集中訪問該類
protected internal:protected+internal
注:
可見性修飾符:
修飾符
應用于
說明
public
所有類型或成員
任何代碼均可以訪問該項
protected
類型和內嵌類型的所有成員
只有派生的類型能夠訪問該項
internal
所有類型或成員
只能在包含它的程序集中訪問該項
prvate
類型和內嵌類型的所有成員
只能在它所述的類型中訪問該項
protected internal
類型和內嵌類型的所有成員
只能在包含它的程序集和派生類型的代碼中訪問該項。
其他修飾符
修飾符
應用于
說明
new
函數成員
成員用相同的簽名隱藏繼承的成員
static
所有成員
成員不作用于類的具體實例
virtual
僅函數成員
成員可以由派生類重寫
abstract
僅函數成員
虛擬成員定義了成員的簽名,但沒有提供實現代碼
override
僅函數成員
成員重寫了繼承的而虛擬或抽象成員
sealed
類、方法和屬性
對于類,不能繼承自密封類。對于屬性和方法,成員重寫已繼承的虛擬成員,但任何派生類中的任何成員都不能重寫該成員。當應用于方法或屬性時,sealed 修飾符必須始終與 override 一起使用。
extern
僅靜態[DllImport]方法
成員在外部用另一種語言實現
91.? [C#語言基礎]反射的實現原理?
答:審查元數據并收集關于它的類型信息的能力。
注:
公共語言運行時程序管理應用程序域,應用程序域構成具有相同應用程序范圍的對象周圍定義的邊界。 此管理包括將每個程序集加載到相應的應用程序域中和控制每個程序集內的類型層次結構的內存布局。
程序集包含模塊、模塊包含類型,而類型包含成員。 反射提供封裝程序集、模塊和類型的對象。 可以使用反射動態地創建類型的實例,將類型綁定到現有對象,或從現有對象中獲取類型。然后,可以調用類型的方法或訪問其字段和屬性。
Reflection,中文翻譯為反射。
這是.Net中獲取運行時類型信息的方式,.Net的應用程序由幾個部分:‘程序集(Assembly)’、‘模塊(Module)’、‘類型(class)’組成,而反射提供一種編程的方式,讓程序員可以在程序運行期獲得這幾個組成部分的相關信息,例如:
Assembly類可以獲得正在運行的裝配件信息,也可以動態的加載裝配件,以及在裝配件中查找類型信息,并創建該類型的實例。
Type類可以獲得對象的類型信息,此信息包含對象的所有要素:方法、構造器、屬性等等,通過Type類可以得到這些要素的信息,并且調用之。
MethodInfo包含方法的信息,通過這個類可以得到方法的名稱、參數、返回值等,并且可以調用之。
諸如此類,還有FieldInfo、EventInfo等等,這些類都包含在System.Reflection命名空間下。
92.
[C#語言基礎].NET與Mono的關系?
答:MONO是.NET的一個開源跨平臺工具。.NET只能在Windows下運行,Mono可以實現跨平臺,可以運行與Linux,Unix,Mac OS等。
93.
[面對對象]請說出4中面向對象的設計原則,并分別簡述它們的含義。
答:
1)單一職責原則:一個類,最好只做一件事,只有一個引起它的變化。
2)開放-封閉原則:對于擴展是開放的,對于更改是封閉的。
3)里氏替換原則:子類必須能夠替換其基類。
4)依賴倒置原則:設計應該依賴于抽象而不是具體實現。
A.高層模塊不應該依賴底層模塊,兩個都應該依賴抽象。
B.抽象不應該依賴細節,細節應該依賴抽象(要對抽象編程,不要對實現編程。)
5)接口隔離原則:使用多個小的專門的接口而不要使用一個大的總接口。
6)迪米特法則:如果兩個類不彼此直接通信,那么這兩個類就不應當發生直接的相互作用。如果其中一個類需要調用另一個類的某一個方法的話,可以通過第三者轉發這個調用。
7)合成/聚合復用原則:盡量使用合成/聚合,盡量不要使用類繼承。
注:
94.
[C#語言基礎]Hashtable是無序的嗎?
答:電腦沒有絕對的無序,hashtable是通過哈希碼讓開發者感覺無序。
注:這里的無序是指集合的添加順序與其輸出順序無關。Hashtable是通過哈希碼或哈希函數,對其內部元素進行排列的,所以其元素的添加順序與其輸出順序無關。
95.
[設計模式]請描述你所了解的設計模式,并說明在你的項目中哪里使用過?
答:
單例: 對象池,游戲管理器
抽象工廠,
狀態:有限狀態機,
橋接:有限狀態機
策略:AI自動行為操控中每種操控算法的獨例
注:擴展補充。
創建型模式:單例模式、抽象工廠模式、建造者模式、工廠模式、原型模式。
結構型模式:適配器模式、橋接模式、裝飾模式、組合模式、外觀模式、享元模式、代理模式。
行為型模式:模版方法模式、命令模式、迭代器模式、觀察者模式、中介者模式、備忘錄模式、解釋器模式(Interpreter模式)、狀態模式、策略模式、職責鏈模式(責任鏈模式)、訪問者模式。
96.
[數據結構]說出你所了解的數據結構,并說明它們的特點。
答:列表:
特點:有序,內存空間連續,讀取速度快,大小可變,通過位置索引取元素.
缺點:輸入,刪除的速度慢
類庫已實現:List、
ArrayList
字典:
特點:鍵值對的集合,通過鍵查找值,查找方便,無序
類庫已實現:Dictionary、Hashtable
棧:
特點:后進前出 LIFO(Last
In First Out)
支持操作:入棧,出棧,讀棧頂,
類庫已實現:Stack、Stack
隊列:
特點:前進前出 FIFO(First In First Out)
支持操作:入隊,出隊,讀隊首
類庫已實現:Queue、Queue
鏈表:
特點:節點內存空間不連續,插入,刪除速度快,讀取速度慢.
類庫已實現:LinkedList
數組:
特點:內存空間連續,長度固定,讀取速度快
類庫已實現:Array
樹:
特點:可以將對象組織為層次結構,
實現:可使用設計模式中的組合模式實現樹結構
97.
[C#語言基礎]Override 與 Overload的區別。
答:
Override:
是指方法的重寫,C#中可重寫abstract、vritual 、override三類方法,重寫是子類重寫父類的以上三種方法,是動態綁定的,調用速度比方法隱藏慢,但靈活性好,重寫本質是對方法表的修改
Overload:是指方法的重載,一個類中的多個同名方法,參數列表不同,主要指參數個數或類型不同,重載的目的是為了讓實現相似功能的方法用一個名稱表示,方便程序員編寫和理解代碼。可讀性好。
重寫和重載都是多態的一種體現。
98.
[C#語言基礎]對比數組與集合。
答:
數組:長度固定,大小不變,存儲空間連續,讀取速度快,插入,刪除速度慢。
集合:長度不定,大小可變,存儲空間可能不連續,適合存放不確定數量的數據。
99.
[C#語言基礎]假如有一個Person類,包含姓名,年齡字段,如對Person數組按年齡升序排列,也可以按姓名升序排列,將來可以會有更多的排序方式,你該怎么實現,說出思路。
答:
方法一:實現IComparer, 使用Array.Sort(Array, IComparer )
方法二:使用OrderBy或OrderByDescending 方法加Lambda表達式
如:arr =
arr.OrderBy(p=>p.age).ToArray();
Uinty筆試題
100.
[UI]NGUI
Button怎樣接受用戶點擊并調用函數,具體方法名稱是什么?
答: 在按鈕上綁定一個帶有OnClick事件List;
EventDelegate();
EventDelegate(Callback call);//void Callback()
EventDelegate(MonoBehaviour target,string methodName)
101.
[Unity]Unity在PC端播放視頻注意的問題是什么?
答:必須安裝QuickTime播放器,不支持FLV視頻格式。
102.
[Unity]PC端播放視頻是與哪一個類有關?
答:MovieTexture。
103.
[Unity]通過Unity持久化存儲PlayerPrefs,如何實現存儲以及獲取一個整數數據。
答:
存儲:PlayerPrefs.SetInt
("MyKey", 1);
獲取:int myKey = PlayerPrefs.GetInt
("MyKey");
104.
[Unity]通過Unity持久化存儲PlayerPrefs,如何刪除數據。
答:
PlayerPrefs.DeleteKey ("MyKey");
PlayerPrefs.DeleteAll ();
105.
[Unity]一個角色要用到unity中尋路系統,應該添加哪個組件?
答:NavMeshAgent。
106.
[Unity]NavMeshObstacle組件的作用?
答:尋路網格動態碰撞組件,用于運動的物體阻礙尋路物體效果。
107.
[Unity]射線中RaycastHit代表什么?
答:射線碰到的碰撞信息
108.
[Unity]通過什么可以區分射線碰到的游戲對象?
答:通過LayerMask(層的遮罩),RaycastHit返回的碰撞的標簽。
109.
[動畫系統]角色的AnimationType中(Generic,Legacy ,Humanoid),哪個動畫樣式可應用在Mecanim動畫系統。
答:Generic Humanoid類人樣式。
110.
[動畫系統]Unity支持幾種動畫?
關鍵幀動畫
默認骨骼動畫(人型)
CAT