更多好的文章就在 blog.haoitsoft.com,請大家多多支持!
還可以通過好電影網:www.haotv8.cc,看你喜歡的電影,勞逸結合,效率更高哦!
1、簡述 private、 protected、 public、 internal 修飾符的訪問權限。
private :私有成員,在類的內部纔可以訪問。
protected :保護成員,該類內部和繼承類中可以訪問。
public :公共成員,完全公開,沒有訪問限制。
internal:當前程序集內可以訪問。
2、ADO.NET中的五個主要對象
Connection:主要是開啓程序和數據庫之間的連接。沒有利用連接對象將數據庫打開,是無法從數據庫中取得數據的。Close和Dispose的區別,Close以後還可以Open,Dispose以後則不能再用。
Command:主要可以用來對數據庫發出一些指令,例如可以對數據庫下達查詢、新增、修改、刪除數據等指令,以及調用存在數據庫中的存儲過程等。這個對象是架構在Connection對象上,也就是Command對象是透過連接到數據源。
DataAdapter:主要是在數據源以及DataSet之間執行數據傳輸的工作,它可以透過Command對象下達命令後,並將取得的數據放入DataSet對象中。這個對象是架構在Command對象上,並提供了許多配合DataSet使用的功能。
DataSet:這個對象可以視爲一個暫存區(Cache),可以把從數據庫中所查詢到的數據保留起來,甚至可以將整個數據庫顯示出來,DataSet是放在內存中的。DataSet的能力不只是可以儲存多個Table而已,還可以透過DataAdapter對象取得一些例如主鍵等的數據表結構,並可以記錄數據表間的關聯。DataSet對象可以說是ADO.NET中重量級的對象,這個對象架構在DataAdapter對象上,本身不具備和數據源溝通的能力;也就是說我們是將DataAdapter對象當做DataSet對象以及數據源間傳輸數據的橋樑。DataSet包含若干DataTable、DataTableTable包含若干DataRow。
DataReader:當我們只需要循序的讀取數據而不需要其它操作時,可以使用DataReader對象。DataReader對象只是一次一筆向下循序的讀取數據源中的數據,這些數據是存在數據庫服務器中的,而不是一次性加載到程序的內存中的,只能(通過遊標)讀取當前行的數據,而且這些數據是隻讀的,並不允許作其它的操作。因爲DataReader在讀取數據的時候限制了每次只讀取一筆,而且只能只讀,所以使用起來不但節省資源而且效率很好。使用DataReader對象除了效率較好之外,因爲不用把數據全部傳回,故可以降低網絡的負載。
ADO.NET使用Connection對象來連接數據庫,使用Command或DataAdapter對象來執行SQL語句,並將執行的結果返回給DataReader或 DataAdapter ,然後再使用取得的DataReader或DataAdapter對象操作數據結果。
3、列舉ASP.NET頁面之間傳遞值的幾種方式。
1.使用QueryString,如....?id=1; response. Redirect()....
2.使用Session變量
3.使用Server.Transfer
4.Cookie傳值
5.Application傳值
6.PreviosPage
Server.Transfer和Response.Redirect的區別:Server.Transfer是服務器內部的轉接,瀏覽器不知曉;Response.Redirect是有瀏覽器參與的,所以在地址欄中可以看到地址的變化。
4、C#中的委託是什麼?事件是不是一種委託?事件和委託的關係。
委託可以把一個方法作爲參數代入另一個方法。
委託可以理解爲指向一個函數的指針。
委託和事件沒有可比性,因爲委託是類型,事件是對象,下面說的是委託的對象(用委託方式實現的事件)和(標準的event方式實現)事件的區別。事件的內部是用委託實現的。因爲對於事件來講,外部只能“註冊自己+=、註銷自己-=”,外界不可以註銷其他的註冊者,外界不可以主動觸發事件,因此如果用Delegate就沒法進行上面的控制,因此誕生了事件這種語法。事件是用來閹割委託實例的,類比用一個自定義類閹割List。事件只能add、remove自己,不能賦值。事件只能+=、-=,不能=。加分的補充回答:事件內部就是一個private的委託和add、remove兩個方法。
面試聊:用Reflector查看.Net的類的內部實現,解決問題。
5、override與重載(overload)的區別
重載是方法的名稱相同。參數或參數類型不同,進行多次重載以適應不同的需要。重載(overload)是面向過程的概念。
Override是進行基類中函數的重寫。Override是面向對象的概念
6、C#中索引器是否只能根據數字進行索引?是否允許多個索引器參數?
參數的個數和類型都是任意的。加分的補充回答:用reflector反編譯可以看出,索引器的內部本質上就是set_item、get_item方法。加分的補充回答:回答傳智播客.net培訓中講解設計模式中開發的SettingsProvider就是用的string類型的參數名做索引器參數。
7、屬性和public字段的區別是什麼?調用set方法爲一個屬性設值,然後用get方法讀取出來的值一定是set進去的值嗎?
屬性可以對設值、取值的過程進行非法值控制,比如年齡禁止設值負數,而字段則不能進行這樣的設置。雖然一般情況下get讀取的值就是set設置的值,但是可以讓get讀取的值不是set設置的值的,極端的例子。Public Age{get{return 100;}set{}}。加分的補充回答:用reflector反編譯可以看出,屬性內部本質上就是set_***、get_***方法,詳細參考傳智播客.net培訓視頻中串講.net基礎的部分。
class Person
{
public int Age
{
get
{
return 3;
}
set
{
}
}
}
Person p1 = newPerson();
p1.Age = 30;
p1.Age++;
Console.Write(p1.Age);//輸出3
8、三層架構
通常意義上的三層架構就是將整個業務應用劃分爲:表現層(UI)、業務邏輯層(BLL)、數據訪問層(DAL)。
區分層次的目的即爲了“高內聚,低耦合”的思想。
表現層(UI):通俗講就是展現給用戶的界面,即用戶在使用一個系統的時候的所見所得。
業務邏輯層(BLL):針對具體問題的操作,也可以說是對數據層的操作,對數據業務邏輯處理。
數據訪問層(DAL):該層所做事務直接操作數據庫,針對數據的增添、刪除、修改、更新、查找等每層之間是一種垂直的關係。
三層結構是N層結構的一種,一般來說,層次之間是向下依賴的,下層代碼未確定其接口(契約)前,上層代碼是無法開發的,下層代碼接口(契約)的變化將使上層的代碼一起變化。
優點:分工明確,條理清晰,易於調試,而且具有可擴展性。
缺點:增加成本。
9、MVC模式(*)
MVC(Model View Controller)模型-視圖-控制器
aspx就是View,視圖;Model:DataSet、Reader、對象;Controller:cs代碼。
MVC是典型的平行關係,沒有說誰在上誰在下的關係,模型負責業務領域的事情,視圖負責顯示的事情,控制器把數據讀取出來填充模型後把模型交給視圖去處理。而各種驗證什麼的應該是在模型裏處理了。它強制性的使應用程序的輸入、處理和輸出分開。MVC最大的好處是將邏輯和頁面分離。
10、什麼是裝箱(boxing)和拆箱(unboxing)?(*)
裝箱:從值類型接口轉換到引用類型。
拆箱:從引用類型轉換到值類型。
object obj = null;//引用類型
obj = 1;//裝箱,boxing。把值類型包裝爲引用類型。
int i1 = (int)obj;//拆箱。unboxing
11、什麼叫應用程序域(AppDomain)(*)
一種邊界,它由公共語言運行庫圍繞同一應用程序範圍內創建的對象建立(即,從應用程序入口點開始,沿着對象激活的序列的任何位置)。
應用程序域有助於將在一個應用程序中創建的對象與在其他應用程序中創建的對象隔離,以使運行時行爲可以預知。
在一個單獨的進程中可以存在多個應用程序域。應用程序域可以理解爲一種輕量級進程。起到安全的作用。佔用資源小。
12、CTS、CLS、CLR分別作何解釋(*)
CTS:Common Type System 通用系統類型。Int32、Int16→int、String→string、Boolean→bool
CLS:Common Language Specification 通用語言規範。不同語言語法的不同。
CLR:Common Language Runtime 公共語言運行時,就是.Net提供的那些類。
13、在dotnet中類(class)與結構(struct)的異同?
Class可以被實例化,屬於引用類型,是分配在內存的堆上的。類是引用傳遞的。
Struct屬於值類型,是分配在內存的棧上的。結構體是複製傳遞的。加分的回答:Int32、Boolean等都屬於結構體。
14、堆和棧的區別?
棧是編譯期間就分配好的內存空間,因此你的代碼中必須就棧的大小有明確的定義;局部值類型變量、值類型參數等都在棧內存中。
堆是程序運行期間動態分配的內存空間,你可以根據程序的運行情況確定要分配的堆內存的大小。
15、能用foreach遍歷訪問的對象的要求
需要實現IEnumerable接口或聲明GetEnumerator方法的類型。
16、GC是什麼?爲什麼要有GC?
GC是垃圾收集器。程序員不用擔心內存管理,因爲垃圾收集器會自動進行管理。GC只能處理託管內存資源的釋放,對於非託管資源則不能使用GC進行回收,必須由程序員手工回收,一個例子就是FileStream或者SqlConnection需要程序員調用Dispose進行資源的回收。
要請求垃圾收集,可以調用下面的方法:GC.Collection()一般不需要手動調用GC.Collection()。加分的回答:有一次用OLEAutomation的方式操作Excel的時候,Excel經常不能正常退出,在MSDN網站上找到官方解答說要調用一下GC.Collection(),至於爲什麼這樣就可以也沒找到答案。
17、String s = new String("xyz");創建了幾個String Object?
兩個對象,一個是“xyx”,一個是指向“xyx”的引用對象。
18、值類型和引用類型的區別?
1.將一個值類型變量賦給另一個值類型變量時,將複製包含的值。引用類型變量的賦值只複製對對象的引用,而不復制對象本身。
2.值類型不可能派生出新的類型:所有的值類型均隱式派生自 System.ValueType。但與引用類型相同的是,結構也可以實現接口。
3.值類型不可能包含 null 值:然而,可空類型功能允許將 null賦給值類型。
4.每種值類型均有一個隱式的默認構造函數來初始化該類型的默認值。
19、C#中的接口和類有什麼異同。
不同點:
不能直接實例化接口。
接口不包含方法的實現。
接口可以多繼承,類只能單繼承。
類定義可在不同的源文件之間進行拆分。
相同點:
接口、類和結構都可以從多個接口繼承。
接口類似於抽象基類:繼承接口的任何非抽象類型都必須實現接口的所有成員。
接口和類都可以包含事件、索引器、方法和屬性。
20、abstract class和interface有什麼區別?
相同點:
都不能被直接實例化,都可以通過繼承實現其抽象方法。
不同點:
接口支持多繼承;抽象類不能實現多繼承。
接口只能定義行爲;抽象類既可以定義行爲,還可能提供實現。
接口可以用於支持回調(CallBack);抽象類不能實現回調,因爲繼承不支持。
接口只包含方法(Method)、屬性(Property)、索引器(Index)、事件(Event)的簽名,但不能定義字段和包含實現的方法;
抽象類可以定義字段、屬性、包含有實現的方法。
接口可以作用於值類型(Struct)和引用類型(Class);抽象類只能作用於引用類型。例如,Struct就可以繼承接口,而不能繼承類。
加分的補充回答:講設計模式的時候SettingsProvider的例子。
21、是否可以繼承String類?
String類是sealed類故不可以繼承。
22、try {}裏有一個return語句,那麼緊跟在這個try後的finally {}裏的code會不會被執行,什麼時候被執行?
會執行,在return前執行。
加分的補充回答(也助記):讀取數據庫中數據的條數的程序
public int QueryCount()
{
…..
try
{
return cmd.ExecuteScalar();
}
finally
{
cmd.Dispose();
}
}
如果C#設計的是先執行cmd.Dispose()再執行return就會出現return執行失敗了,因爲cmd已經Dispose了。
23、new關鍵字用法(*)
new運算符用於創建對象和調用構造函數。
new修飾符用於向基類成員隱藏繼承成員。
new約束用於在泛型聲明中約束可能用作類型參數的參數的類型。
24、如何把一個Array複製到ArrayList裏(*)
實現1 string[] s ={ "111", "22222" }; ArrayList list = new ArrayList(); list.AddRange(s);
實現2 string[] s ={ "111", "22222" }; ArrayList list = new ArrayList(s);
25、描述線程與進程的區別?(*)
1.線程(Thread)與進程(Process)二者都定義了某種邊界,不同的是進程定義的是應用程序與應用程序之間的邊界,不同的進程之間不能共享代碼和數據空間,而線程定義的是代碼執行堆棧和執行上下文的邊界。
2.一個進程可以包括若干個線程,同時創建多個線程來完成某項任務,便是多線程。而同一進程中的不同線程共享代碼和數據空間。用一個比喻來說,如果一個家庭代表一個進程,在家庭內部,各個成員就是線程,家庭中的每個成員都有義務對家庭的財富進行積累,同時也有權利對家庭財富進行消費,當面對一個任務的時候,家庭也可以派出幾個成員來協同完成,而家庭之外的人則沒有辦法直接消費不屬於自己家庭的財產。
加分的回答:舉例,傳智播客的.Net培訓中用多線程(ThreadPool)實現網站蜘蛛的案例。
26、什麼是強類型,什麼是弱類型?哪種更好些?爲什麼?
C#中
int i=3;
i="a";
不可以
JavaScript中
var i=3;
i="a";
可以
強類型是在編譯的時候就確定類型的數據,在執行時類型不能更改,而弱類型在執行的時候纔會確定類型。
沒有好不好,二者各有好處,強類型安全,因爲它事先已經確定好了,而且效率高。弱類型更靈活,但是效率低,而且出錯概率高
一般用於編譯型編程語言,如c++,java,c#,pascal等,弱類型相比而言不安全,在運行的時候容易出現錯誤,但它靈活,多用於解釋型編程語言,如javascript,vb等
加分的補充回答:引用傳智播客.net培訓呼叫中心項目中用強類型DataSet的例子,侃一通用強類型DataSet是多麼方便。
27、什麼是反射?
程序集包含模塊,而模塊又包括類型,類型下有成員,反射就是管理程序集,模塊,類型的對象,它能夠動態的創建類型的實例,設置現有對象的類型或者獲取現有對象的類型,能調用類型的方法和訪問類型的字段屬性。它是在運行時創建和使用類型實例
加分的補充回答:聊用反射實現編輯器動態插件和如鵬網項目中插件體系實現第三方支付和定時任務的案例。
28、int、DateTime、string是否可以爲null?
int、DateTime不能,因爲其爲Struct類型,而結構屬於值類型,值類型不能爲null,只有引用類型才能被賦值null。string可以爲null。
29、using關鍵字有什麼用?什麼是IDisposable?
using可以聲明namespace的引入,還可以實現非託管資源的釋放,實現了IDisposiable的類在using中創建,using結束後會自動調用該對象的Dispose方法,釋放資源。加分的補充回答:using其實等價於try……finally,用起來更方便。
int?→Nullable<int>
30、Assembly.Load("foo.dll");這句話是否正確?(*)
錯誤,正確的應該是Assembly.Load("foo");或者Assembly.LoadFrom("foo.dll");
31、XML與 HTML的主要區別
1. XML是區分大小寫字母的,HTML不區分。
2.在HTML中,如果上下文清楚地顯示出段落或者列表鍵在何處結尾,那麼你可以省略</p>或者</li>之類的結束標記。在XML中,絕對不能省略掉結束標記。
HTML:<img src="1.jpg"><br><br>
XML:<img src="1.jpg"></img><br/><br/>
3.在XML中,擁有單個標記而沒有匹配的結束標記的元素必須用一個 /字符作爲結尾。這樣分析器就知道不用查找結束標記了。
4.在XML中,屬性值必須分裝在引號中。在HTML中,引號是可用可不用的。
5.在HTML中,可以擁有不帶值的屬性名。在XML中,所有的屬性都必須帶有相應的值。
XML是用來存儲和傳輸數據的
HTML是用來顯示數據的
32、string str = null 與 string str = “”說明其中的區別。
答:string str = null是不給他分配內存空間,而string str = /"/"給它分配長度爲空字符串的內存空間。string str = null沒有string對象,string str = “”有一個字符串對象。
33.寫出一條Sql語句:取出表A中第31到第40記錄(SQLServer,以自動增長的ID作爲主鍵,注意:ID可能不是連續的。
答:解1: select top 10 * from A where id not in (select top 30 id from A)
解2: select top 10 * from A where id > (select max(id) from (select top 30 id from A )as A)
解答3:ROW_NUMBER(推薦)
34.面向對象的語言具有________性、_________性、________性
答:封裝、繼承、多態。
不要背,腦子中要有聯想。
35.在.Net中所有可序列化的類都被標記爲_____?
答:[serializable]
36.在.Net託管代碼中我們不用擔心內存漏洞,這是因爲有了______?
答:GC。
37、什麼叫應用程序域?什麼是受管制的代碼?什麼是託管代碼?什麼是強類型系統?什麼是裝箱和拆箱?什麼是重載?CTS、CLS和CLR分別作何解釋?
應用程序域爲安全性、可靠性、版本控制以及卸載程序集提供了隔離邊界。應用程序域通常由運行庫宿主創建,運行庫宿主負責在運行應用程序之前引導公共語言運行庫。應用程序域提供了一個更安全、用途更廣的處理單元,公共語言運行庫可使用該單元提供應用程序之間的隔離。
受管制的代碼:在.Net環境中運行的任何代碼都是受管制的代碼(managed code),.Net外部的代碼也運行在windows上,這些代碼稱爲未受管制的代碼(unmanaged code)。
使用基於公共語言運行庫的語言編譯器開發的代碼稱爲託管代碼;託管代碼具有許多優點,例如:跨語言集成、跨語言異常處理、增強的安全性、版本控制和部署支持、簡化的組件交互模型、調試和分析服務等。
強類型語言是能夠禁止任何違反類型系統的代碼的語言,或者說是能夠捕獲所有違反類型系統的錯誤的語言。我們說C++相對於C是強類型的,是因爲C++禁止了一些C中的隱式轉換,比如將void*轉換爲任意的指針類型。
裝箱和拆箱使值類型能夠被視爲對象。對值類型裝箱將把該值類型打包到 Object引用類型的一個實例中。這使得值類型可以存儲於垃圾回收堆中。拆箱將從對象中提取值類型。
每個類型成員都有一個唯一的簽名。方法簽名由方法名稱和一個參數列表(方法的參數的順序和類型)組成。只要簽名不同,就可以在一種類型內定義具有相同名稱的多種方法。當定義兩種或多種具有相同名稱的方法時,就稱作重載。
CTS通用類型系統 (common type system)
一種確定公共語言運行庫如何定義、使用和管理類型的規範。
CLR公共語言運行庫
.NET Framework提供了一個稱爲公共語言運行庫的運行時環境,它運行代碼並提供使開發過程更輕鬆的服務。
CLS公共語言規範
要和其他對象完全交互,而不管這些對象是以何種語言實現的,對象必須只向調用方公開那些它們必須與之互用的所有語言的通用功能。爲此定義了公共語言規範 (CLS),它是許多應用程序所需的一套基本語言功能。
38、什麼是code-Behind技術。
就是代碼隱藏,在ASP.NET中通過ASPX頁面指向CS文件的方法實現顯示邏輯和處理邏輯的分離,這樣有助於web應用程序的創建。比如分工,美工和編程的可以個幹各的,不用再像以前asp那樣都代碼和html代碼混在一起,難以維護。
39、接口是一種引用類型,在接口中可以聲明( a),但不可以聲明公有的域或私有的成員變量。
a) 方法、屬性、索引器和事件;
c) 索引器和字段;
d) 事件和字段;
40.在ADO.NET中,對於Command對象的ExecuteNonQuery()方法和ExecuteReader()方法,下面敘述錯誤的是(c)。
a) insert、update、delete等操作的Sql語句主要用ExecuteNonQuery()方法來執行;
b) ExecuteNonQuery()方法返回執行Sql語句所影響的行數。
c) Select操作的Sql語句只能由ExecuteReader()方法來執行;
d) ExecuteReader()方法返回一個DataReder對象;
解答:ExecuteScalar→select getdate()。
41. 下列關於C#中索引器理解正確的是(c )
a) 索引器的參數必須是兩個或兩個以上
b) 索引器的參數類型必須是整數型
c) 索引器沒有名字
d) 以上皆非
42.要創建多文檔應用程序,需要將窗體的(d )屬性設爲true。
a) DrawGrid;
b) ShowInTaskbar;
c) Enabled;
d) IsMdiContainer;
43.如果設treeView1=new TreeView(),則treeView1.Nodes.Add("根節點")返回的是一個 (a)類型的值。
a) TreeNode;
b) int;
c) string;
d) TreeView;
44. 下面關於XML的描述錯誤的是(d)。
a) XML提供一種描述結構化數據的方法;
b) XML 是一種簡單、與平臺無關並被廣泛採用的標準;
c) XML文檔可承載各種信息;
d) XML只是爲了生成結構化文檔;
45、以下的C#代碼,試圖用來定義一個接口:
public interface IFile
{
int A;
int delFile()
{
A = 3;
}
void disFile();
}
關於以上的代碼,以下描述錯誤的是(d )。
a) 以上的代碼中存在的錯誤包括:不能在接口中定義變量,所以int A代碼行將出現錯誤;
b) 以上的代碼中存在的錯誤包括:接口方法delFile是不允許實現的,所以不能編寫具體的實現函數;
c) 代碼void disFile();聲明無錯誤,接口可以沒有返回值;
d) 代碼void disFile();應該編寫爲void disFile(){};
空和null不一樣。
46在ASP.NET中有Button控件myButton,要是單擊控件時,導航到其他頁面http://www.abc.com, 正確的代碼爲( c)。
a) private void myButton_Click(object sender, System.EventArgs e){Redirect(“http://www.abc.com”);}
b) private void myButton_Click(object sender, System.EventArgs e){Request.Redirect(“http://www.abc.com”);}
c) private void myButton_Click(object sender, System.EventArgs e){Reponse.Redirect(“http://www.abc.com”);}
d) private void myButton_Click(object sender, System.EventArgs e){Request.Redirect(“http://www.abc.com”);return true;}
47.聲明一個委託public delegate int myCallBack(int x); 則用該委託產生的回調方法的原型應該是(b )。
a) void myCallBack(int x) ;
b) int receive(int num) ;
c) string receive(int x) ;
d) 不確定的;
48.StringBuilder和 String的區別?
答:String在進行運算時(如賦值、拼接等)會產生一個新的實例,而 StringBuilder 則不會。所以在大量字符串拼接或頻繁對某一字符串進行操作時最好使用 StringBuilder,不要使用 String
如果要操作一個不斷增長的字符串,儘量不用String類,改用StringBuilder類。兩個類的工作原理不同:String類是一種傳統的修改字符串的方式,它確實可以完成把一個字符串添加到另一個字符串上的工作沒錯,但是在.NET框架下,這個操作實在是划不來。因爲系統先是把兩個字符串寫入內存,接着刪除原來的String對象,然後創建一個String對象,並讀取內存中的數據賦給該對象。這一來二去的,耗了不少時間。而使用System.Text命名空間下面的StringBuilder類就不是這樣了,它提供的Append方法,能夠在已有對象的原地進行字符串的修改,簡單而且直接。當然,一般情況下覺察不到這二者效率的差異,但如果你要對某個字符串進行大量的添加操作,那麼StringBuilder類所耗費的時間和String類簡直不是一個數量級的。
49、.請敘述屬性與索引器的區別。 (*)沒啥意義
屬性 索引器
通過名稱標識。 通過簽名標識。
通過簡單名稱或成員訪問來訪問。 通過元素訪問來訪問。
可以爲靜態成員或實例成員。 必須爲實例成員。
屬性的 get 訪問器沒有參數。 索引器的 get 訪問器具有與索引器相同的形參表。
屬性的 set 訪問器包含隱式 value 參數。 除了 value 參數外,索引器的 set 訪問器還具有與索引器相同的形參表。
50.請敘述const與readonly的區別。(*)
const關鍵字用於修改字段或局部變量的聲明。它指定字段或局部變量的值不能被修改。常數聲明引入給定類型的一個或多個常數。
const數據成員的聲明式必須包含初值,且初值必須是一個常量表達式。因爲它是在編譯時就需要完全評估。
const成員可以使用另一個const成員來初始化,前提是兩者之間沒有循環依賴。
readonly在運行期評估賦值,使我們得以在確保“只讀訪問”的前提下,把object的初始化動作推遲到運行期進行。
readonly關鍵字與 const關鍵字不同: const字段只能在該字段的聲明中初始化。readonly字段可以在聲明或構造函數中初始化。因此,根據所使用的構造函數,readonly字段可能具有不同的值。另外,const字段是編譯時常數,而 readonly字段可用於運行時常數。
readonly只能在聲明時或者構造函數裏面初始化,並且不能在 static修飾的構造函數裏面。