C#的基礎知識問答

1. 簡述 private、 protected、 public、 internal、internal protected 修飾符的訪問權限。

答:
沒有標明訪問級別的就是private。
private:私有成員,只能在類的內部纔可以訪問。
protected: 保護成員,只能從所在類和所在類派生的子類進行訪問
public: 公共成員,不限制對該類的訪問。
internal: 訪問僅限於當前程序集(Assembly)。
internal protected: 訪問僅限於程序集(Assembly)和程序集(Assembly)所屬的類派生的類型。

2.什麼是命名空間?它的作用是什麼?

答:命名空間是一組保持唯一的名稱。命名空間用於聲明一個範圍,此命名空間範圍允許您組織代碼並提供了創建全局唯一類型的方法。命名空間是避免命名衝突的一種方式。(MSDN)

3.什麼是程序集(Assembly)?它有什麼特性。
   答:程序集(Assembly)是自我描述的安裝單元,由一個或多個文件組成,一個程序集可以是一個包括元數據的DLL或EXE,也可以由多個文件組成。(C#高級編程)
   程序集是可重用、無版本衝突並且可自我描述的公共語言運行庫應用程序構造塊。程序集提供使運行庫能夠充分了解應用程序的內容並強制使用應用程序定義的版本控制和依賴項規則的結構。這些概念對解決版本控制問題和簡化運行庫應用程序的部署至關重要。(MSDN)
   特性:
   (1) 程序集是自我描述的.程序集包含描述程序集的元數據,元數據包括從程序集導出的類和一個清單。
   (2) 版本的互相依賴性在程序集的清單中進行了記錄。引用程序集的版本被存儲在程序集的清單中。
   (3) 程序集可以進行並行加載 .在。NET中同一個程序集的不同版本可以在同一個進程中使用。
   (4) 應用程序使用應用程序域(Application Domain)來確保其獨立性.使用應用域,許多應用程序可以獨立的運行在一個進程中。
   (5) 安裝非簡單,只要複製一個程序集中的所有文件。

4.什麼是應用程序域AppDomain?
    答1:在.NET結構中,應用程序域是應用程序的一個邊界,運行時就不能訪問同一個進程中另外一個應用程序的內存,多個應用程序可以運行在多個應用域的一個進程中。(C#高級編程)
    答2:應用程序域(通常爲 AppDomain)是一個用於隔離應用程序的虛擬進程。在同一應用程序範圍內(換句話說,以應用程序入口點開頭的對象激活序列中的任何位置)創建的所有對象都創建在同一應用程序域中。多個應用程序域可以存在於單個操作系統進程中,這使它們成爲應用程序隔離的輕量方法。
    操作系統進程通過提供一個獨特的內存地址空間來提供隔離。雖然這很有效,但成本很高,而且不能擴展到大型 Web 服務器所需的數目。另一方面,公共語言運行庫通過管理運行在應用程序域中的代碼的內存使用來強制應用程序隔離。這可確保它不會訪問域邊界以外的內存。注意只有類型安全代碼才能以這種方式進行管理(運行庫在不安全代碼加載到應用程序域中時無法保證隔離)很重要。(http://www.w3sky.com/2469.html)
     答3:應用程序域 (AppDomain) 可以被看作一個輕型的進程。在一個 Win32 進程中可以存在多個ppDomain。AppDomain 的主要目的是將應用程序和其它應用程序隔離開來。
     通過使用獨立的地址空間,Win32 進程提供隔離性。這種方法很有效,但開銷很大並且伸縮性不好。.NET 運行庫通過控制對內存的是用來施加 AppDomain 隔離—AppDomain 中的所有內存是由 .NET 運行庫來管理的,所以運行庫可以確保 AppDomain 之間不能訪問彼此的內存。(http://blog.csdn.net/ianc/)
    單個進程可以運行多個應用程序域,並具有在單獨進程中所存在的隔離級別。在單個進程中運行多個應用程序提高了服務器伸縮性。

4. 一列數的規則如下: 1、1、2、3、5、8、13、21、34......  求第30位數是多少, 用遞歸算法實現。
答1:
class Recursion
 {
  static void Main(string[] args)
  {
            int result;           
   Recursion rc = new Recursion();
   result = rc.RecursionCal(30);
   Console.Write("The result:{0}",result);  

  }

  private int RecursionCal(int i)
  {
   int result;
   
   if( i <= 2)
   {
    result = 1;
   }
   else
   {
    result = RecursionCal(i - 2) + RecursionCal(i - 1);
   }
   return result;
  }
 }

答2:

public class MainClass
    {
        public static void Main()  
        {
            Console.WriteLine(Foo(30));
        }
        public static int Foo(int i)
        {
            if (i <= 0)
                return 0;
            else if(i > 0 && i <= 2)
                return 1;
            else return Foo(i -1) + Foo(i - 2);
        }
    }

5 什麼時候使用static?它的優點是什麼?使用static應該注意什麼?

   當成員函數和成員變量不依賴具體對象,爲整個類而非某個對象提供服務時,就使用static。使用static 修飾符聲明屬於類型本身而不是屬於特定對象的靜態成員。

優勢:
(1)節省內存
(2)static的方法就是類級別的,不需實例化出一個對象,即可使用該方法。
注意事項:
(1)類的靜態成員函數是屬於整個類而非類的對象,所以它沒有this指針,這就導致
了它僅能訪問類的靜態數據和靜態成員函數。
(2)靜態數據成員是靜態存儲的,所以必須對它進行初始化。(C#會自動初始化,C++則需要人工初始化)
(3)訪問靜態成員函數或靜態成員變量只能通過類來訪問,不能通過對象來訪問。

6 C#中的委託是什麼?事件是不是一種委託?

   委託在C#中可以看作是對象的一種新類型。委託把一個方法作爲參數傳入到另一個方法,通過傳遞地址的機制完成。它相當於C/C++的函數指針。
   事件是一種特殊的委託。委託支持事件處理,可以將事件處理過程註冊給委託。觸發事件就調用委託。

7 重載(Overload)、覆蓋(Override)、隱藏(Hide)幾個的區別

    重載(overload):在一個類中定義方法的不同版本,重載方法的名稱相同但是重載的簽名不同--即參數名稱、參數個數或參數類型不同。只有返回類型相同是不行的。

   覆蓋(Override):將基類的方法聲明爲virtual,在派生類中提供另外一個帶有相同簽名的方法並在聲明中含有override關鍵字,則重寫了基類的方法。

   隱藏(Hide):在基類中方法沒有聲明爲virtual,則在派生類中提供另外一個帶有相同簽名的方法並在聲明中含有new關鍵字,則新方法隱藏基類的方法。
   方法的簽名:描述如何調用該方法所需要的一組信息:方法的名稱、返回類型,參數個數,參數類型。

8 請編程實現一個冒泡排序算法?

答1:C語言

#include<stdio.h>
main()
{
 int num[10];
 int i, j, temp;
 printf("Please input 10 numbers:/n");
 for(i = 0 ; i < 10; i++)
  scanf("%d", &num[i]);
 for(i = 1; i < 10; i++)
  for(j = 0; j < 10 - i; j++)
  {
   if(num[j] > num[j+1])
   {
             temp = num[j] ;
    num[j] = num[j+1];
    num[j+1] = temp;
   }
  }
 printf("The sorted numbers:/n");
 for(i = 0 ; i < 10; i++)
  printf("%d/n",num[i]);
}

答2:C#語言

static void Main(string[] args)
  {
   
   int[] num = new int[10];
   Console.WriteLine("Please input 10 numbers:");
   for(int i = 0; i < 10; i++)
    num[i] = Int32.Parse(Console.ReadLine());
   for(int i = 1; i < 10; i++)
    for(int j = 0; j < 10 - i; j++)
    {
     if(num[j] > num[j+1])
     {
                        num[j] = num[j] + num[j+1];
      num[j+1] = num[j] - num[j+1];
      num[j] = num[j] - num[j+1];
     }
    }
   Console.WriteLine("The sorted numbers:");
   for(int i = 0; i < 10; i++)
    Console.WriteLine("{0}", num[i]);
         
  }

 

9 請編程實現一個選擇排序算法?

答1:C語言

#include<stdio.h>
main()
{
 int num[10];
 int i, j, temp;
 printf("Please input 10 numbers:/n");
 for(i = 0 ; i < 10; i++)
  scanf("%d", &num[i]);
 for(i = 0; i < 9; i++)
  for(j = i+1; j < 10; j++)
  {
   if(num[j] < num[i])
   {
             temp = num[i] ;
    num[i] = num[j];
    num[j] = temp;
   }
  }
 printf("The sorted numbers:/n");
 for(i = 0 ; i < 10; i++)
  printf("%d/n",num[i]);
}

答2:C#語言

static void Main(string[] args)
  {
   
   int[] num = new int[10];
   Console.WriteLine("Please input 10 numbers:");
   for(int i = 0; i < 10; i++)
    num[i] = Int32.Parse(Console.ReadLine());
   for(int i = 0; i < 9; i++)
    for(int j = i + 1; j < 10; j++)
    {
     if(num[j] < num[i])
     {
      num[i] = num[i] + num[j];
      num[j] = num[i] - num[j];
      num[i] = num[i] - num[j];
     }
    }
   Console.WriteLine("The sorted numbers:");
   for(int i = 0; i < 10; i++)
    Console.WriteLine("{0}", num[i]);
         
  }


10 描述一下C#中索引符的實現過程,是否只能根據數字進行索引?
答:C#通過提供索引器,可以象處理數組一樣處理對象。
定義索引符的方式與定義屬性的方式一樣,使用get和set函數,索引符的名稱是關鍵字this.
實現過程:
(1)在類裏面定義索引符
public string this [int index]
  {
   get {
    if(index < 0 || index > length)
    {
     throw new IndexOutOfRangeException();
    }     
    return "Value" + index; }

   set{
    if(index < 0 || index > length)
    {
     throw new IndexOutOfRangeException();
    }
    myObjectValue = value;    
   }
  }
(2)使用類創建對象後,就可以使用索引符
NewClass newClass = new NewClass();
然後就象使用數組一樣使用newClass[i]。


11 索引和屬性的異同?
相同點:
(1)獲取對象或是類的靜態成員的值。
(2)定義類似,使用get和set函數。
不同點:
(1)類的每一個屬性都必須擁有唯一的名稱,而類裏定義的每一個索引器都必須擁有唯一的簽名(signature)或者參數列表(這樣就可以實現索引器重載)。
(2)屬性可以是static(靜態的)而索引器則必須是實例成員。
(3)爲索引器定義的訪問,函數可以訪問傳遞給索引器的參數,而屬性訪問函數則沒有參數。


12 求以下表達式的值,寫出您想到的一種或幾種實現方法: 1-2+3-4+……+m
答:我寫出了三種:
答1:
private static int CalResult(int m)
  {
   if(m % 2 == 0)
   {
    return -(m / 2);
   }
   else
   {
    return m - (int)(m / 2);
   }
  }

答2:  

private static int CalResult(int m)
  {
   int result = 0;
   for(int i = 1; i < m + 1; i++)
   {
    if(i % 2 == 0)
    {
     result =  result - i;
    }
    else
    {
                    result =  result + i;
    }
   }
   return result;
  }

答3:

  private static int CalResult(int m)
  {
   int result = 0;
   for(int i = 1; i < m + 1; i++)
   {
    result = (i % 2 == 0) ? result - i : result + i;  

  
   }
   return result;
  }

13 CTS、CLS、CLR分別作何解釋?

答1:CTS:公共類型系統。爲了實現語言的互操作性,必須有一組各種語言都認可的基本數據類型,這樣才能對所有語言進行標準化處理。CTS就提供了這個功能,還提供了定義定製類的規則。
CLS:公共語言規範。這是確保代碼可以在任何語言中訪問的最小標準集體。所有用.NET的編譯器都應支持CLS。CLS構成了可以在.NET和IL中使用的功能子集,代碼也可以使用CLS外部的功能。如果非CLS功能在代碼所在裝配件的外部是可見的,那麼這些功能就不能在某些語言中使用。
CLR:公共語言運行庫。它可以處理加載程序、運行程序的代碼,以及提供所有支持服務的代碼。


14 什麼是受管制的代碼和未受管制的代碼?

答:受管制的代碼:在.NET環境中運行的任何代碼成爲受管制的代碼(managed code),.NET環境外部的其他代碼也運行在Windows上,這些代碼稱爲未受管制的代碼(unmanaged code)。

15 解釋一下中間語言(IL)。
答:在.NET運行時加載和運行代碼時候,這種語言確定代碼的位置,在編譯受管制的代碼時,編譯器實際上使用中間語言,CLR處理執行前的最後編譯階段,IL可以非常快速的編譯爲內部的機器代碼,同時支持.NET功能。

16 解釋以下JIT編譯。
答:Just-in-Time(JIT)編譯,表示執行編譯過程的最後階段,即從中間語言轉換爲內部機器代碼。部分代碼是按需要即時編譯的。

17 在下面的例子裏
 class A
 {
  public A()
  {
   PrintFields();
  }
  public virtual void PrintFields(){}
 }
 class B:A
 {
  int x=1;
  int y;
  public B()
  {
   y=-1;
  }
  public override void PrintFields()
  {
   Console.WriteLine("x={0},y={1}",x,y);
  }
 }
當使用new B()創建B的實例時,產生什麼輸出?
答:答:x=1,y=0

18 什麼是裝箱和拆箱?
答:裝箱是從值類型轉換到引用類型。拆箱是從引用類型轉換到值類型。

19 什麼是強類型系統?
答:每個變量有類型,每個表達式有類型,而且每種類型是嚴格定義的。其次,所有的數值傳遞,不管是直接的還是通過方法調用經由參數傳過去的都要先進行類型相容性的檢查。編譯器對所有的表達式和參數都要進行類型相容性的檢查以保證類型是兼容的。任何類型的不匹配都是錯誤的,在編譯器完成編譯以前,錯誤必須被改正。


20 .NET中讀寫數據庫需要用到那些類?他們的作用?
答:
數據庫共享的類:

DataSet--它創建的對象包含一組DataTables,以及這些表之間的關係。
DataTable--它創建的對象作爲數據的一個容器,DataTable由一個或多個DataColumn組成,每個DataColumn

由一個或多個DataRow生成。
DataRow-- 類似與數據庫表的一行。
DataColumn-- 包含列的含義。例如名稱和數據類型。
Constraint--爲DataColumn(或一組數據列)定義規則,例如惟一值。
DataColumnMapping--用DataTable中的列名映射數據中的列名。
DataTableMapping--將數據庫中的表名映射到DataSet中的DataTable中。

數據庫特定的類:

Sqlcommand、Oledbcommand --SQL語句的包裝或存儲過程的調用。
SqlcommandBuilder、OledbcommandBuilder --用於從一個select子句中生成SQL語句(例如插入、更新、刪
除)的類。
Sqlconnection、 Oledbconnection--數據庫連接
SqlDataAdapter、OledbDataAdapter--用語存儲選擇插入、更新、刪除語句的類,因此可以用於生產

DataSet和更新Database.
SqlDataReader、OledbDataReader--只向前的連接數據讀取器。DataSet和更新Database.
SqlParameter、OledbParameter--爲存儲過程定義一個參數。
SqlTransaction、OledbTransaction--一個數據庫處理事物,包裝在一個對象中。

 

21 列舉在.NET數據訪問中使用的類和接口的命名空間。

System.Data。包含獨立於提供程序的類型,如 DataSet 和 DataTable
System.Data.SqlClient。包含 SQL Server .NET 數據提供程序類型。
System.Data.OracleClient。包含 Oracle .NET 數據提供程序。
System.Data.OleDb。包含 OLE DB .NET 數據提供程序類型。
System.Data.Odbc。包含 ODBC .NET 數據提供程序類型。


22 列舉 ADO.NET 對象。

(1)連接的對象
Connection對象:表示與數據源之間的連接。可通過Connection對象的各種不同屬性指定數據源的類型、位置以及其他屬性,可用它來與數據庫建立連接或斷開連接。Connection對象起到渠道的作用,其他對象如DataAdapter和Command對象通過它與數據庫通信。

Command對象:表示對數據庫的查詢、對存儲過程的調用或要返回特定表內容的直接請求。可使用Command對象對數據庫執行任何一種查詢操作。

DataReader對象:DataReder用於以最快的數據檢索並檢查查詢所返回的行。可使用DataReader對象來檢查查詢結果,一次查詢一行,當移到下一行時,前一行的內容就會被放棄。DataReader不支持更新操作,由DataReader返回的數據是隻讀的。由於DataReader對象支持最小特性集,所以它的速度非常快,而且是輕量的。

Transaction對象:Connection對象有一個BeginTransaction方法,可用來創建Transaction對象。該對象可用來在 Transaction對象的生存期提交或取消對數據庫所做的更改。

Parameter對象:要使用參數化的Command對象,可先爲查詢中的每個參數創建Parameter對象,並將它們添加到Command對象的Paramters集合中。ADO.NET的Parameter對象公開一些屬性和方法,可用來定義參數的數據類型和值。

DataAdapter對象:DataAdapter對象充當數據庫和ADO.NET對象模型中斷開連接的對象之間的橋樑。

DataAdapter對象會填充DataSet對象中的表,而且能讀取緩存的更改並將其提交給數據庫。

(2) 斷開連接的對象

DataTable對象:DataTable對象允許您通過行和列的集合查看數據。通過DataAdapter對象的Fill方法,可以將查詢的結果存儲在DataTable中。一旦從數據庫中讀出了數據,將其存儲在DataTable對象中,數據與服務器之間的連接就斷開拉。DataTable類包含了其他斷開連接對象的集合。例如:

DataRow,DataColumn,Constraints等。

DataColumn對象:每個DataTable都有一個Columns集合,該集合是DataColumn對象的容器。DataColumn對存儲了有關列結構的信息。

Constraint對象:Constraint對象存在於DataTable對象的Constraints集合中,可以建立一個Constraint對象,確保某一列或多個列中的值在DataTable中是惟一的。

 DataRow對象:想要訪問存儲在DataTable對象中的實際值,可以使用對象的Rows集合,該集合中包含了一組DataRow對象。DataTable通過DataRows的集合使得所有數據行都可以訪問。DataRow對象也是更新的起點。

DataSet對象:  可以將DataSet對象視爲一些DataTable對象的容器。DataSet對象還有一些屬性,可以向文件、內存地址寫入,或讀出該對象;可以只保存DataSet對象的內容或只保存DataSet對象的結構,也可以兩者都保存。

DataRelation對象:DataSet類定義了一個Realtion屬性,該屬性是DataRelation對象的一個集合,可以使用DataRelation對象來表明DataSet中不同的DataTable對象之間的關係。DataRelation對象還引入了一些屬性,來強化引用的完整性。

DataView對象:一旦獲取了DataTable對象中查詢的結果,就可以使用DataView對象以不同方式來查看數據。可以使用多個DataView對象在同時查看同一DataTable。

(http://www.sozz.cn/00091/27353.htm

23 在C#中,string str = null 與 string str = “” 請儘量使用文字或圖象說明其中的區別。
答:string str = null 是不給他分配內存空間,而string str = "" 給它分配長度爲空字符串的內存空間。

24 請詳述在dotnet中類(class)與結構(struct)的異同?
答1:類是一種數據結構,它可以包含數據成員(常數和字段)、函數成員(方法、屬性、事件、索引器、運算符、實例構造函數、靜態構造函數、析構函數),以及嵌套類型。類類型支持繼承,它使派生類可以對基類進行擴展和專用化。
    結構也可以包含數據成員和函數成員,對於具有值語義的小的數據結構很有用。
    類(class)可以被實例化,屬於引用類型,是分配在內存的堆上的。類類型的變量包含對數據的引用。
    結構(struct)屬於值類型,是分配在內存的棧上的. 結構類型的變量直接包含結構的數據。當它們只有少量數據成員,不要求使用繼承或引用標識,而且它們適合使用值語義,這時候使用結構。
    與類不同,結構不支持繼承。結構類型永遠不是抽象的,並且始終是隱式密封的。
    結構不能聲明無參數的實例構造函數。實際上每個結構類型都隱含地含有一個無參數實例構造函數,將所有的值類型設置爲它們的默認值,並將所有引用類型字段設置爲null.
    結構不能聲明析構函數。
    結構的實例字段不能設置初始值,但是靜態字段聲明中可以設置初始值。
    this意義不同。在類的實例構造函數和實例函數成員中,this爲值類別.this可以用語引用該函數成員調用所涉及的實例,但是不可能在類的函數成員中對this本身賦值。
     在結構的實例構造函數中,this爲變量類別,相當於該結構類型的out參數,而在結構的實例函數成員內,this相當於該結構類型的ref參數。

答2:結構與類共享幾乎所有相同的語法,但結構比類受到的限制更多:
儘管結構的靜態字段可以初始化,結構實例字段聲明還是不能使用初始值設定項。
結構不能聲明默認構造函數(沒有參數的構造函數)或析構函數。
結構的副本由編譯器自動創建和銷燬,因此不需要使用默認構造函數和析構函數。實際上,編譯器通過爲所有字段賦予默認值(參見默認值表)來實現默認構造函數。結構不能從類或其他結構繼承。
結構是值類型 -- 如果從結構創建一個對象並將該對象賦給某個變量,變量則包含結構的全部值。複製包含結構的變量時,將複製所有數據,對新副本所做的任何修改都不會改變舊副本的數據。由於結構不使用引用,因此結構沒有標識 -- 具有相同數據的兩個值類型實例是無法區分的。C# 中的所有值類型本質上都繼承自 ValueType,後者繼承自 Object。編譯器可以在一個稱爲裝箱的過程中將值類型轉換爲引用類型。

25 params,ref,out 三者。

     params 關鍵字可以指定在參數數目可變處採用參數的方法參數。在方法聲明中的 params 關鍵字之後不允許任何其他參數,並且在方法聲明中只允許一個 params 關鍵字。 
    方法參數上的 out 方法參數關鍵字使方法引用傳遞到方法的同一個變量。當控制傳遞迴調用方法時,在方法中對參數所做的任何更改都將反映在該變量中。若要使用 out 參數,必須將參數作爲 out 參數顯式傳遞到方法。out 參數的值不會傳遞到 out 參數。不必初始化作爲 out 參數傳遞的變量。然而,必須在方法返回之前爲 out 參數賦值。屬性不是變量,不能作爲 out 參數傳遞。如果兩個方法的聲明僅在 out 的使用方面不同,則會發生重載。
    方法參數上的 ref 方法參數關鍵字使方法引用傳遞到方法的同一個變量。當控制傳遞迴調用方法時,在方法中對參數所做的任何更改都將反映在該變量中。 若要使用 ref 參數,必須將參數作爲 ref 參數顯式傳遞到方法。ref 參數的值被傳遞到 ref 參數。傳遞到 ref 參數的參數必須最先初始化。屬性不是變量,不能作爲 ref 參數傳遞。如果兩種方法的聲明僅在它們對 ref 的使用方面不同,則將出現重載。

26 分析以下代碼,完成填空
string strTmp = "abcdefg某某某";
int i= System.Text.Encoding.Default.GetBytes(strTmp).Length;
int j= strTmp.Length;
以上代碼執行完後,i= j=

答:i=13,j=10

27 根據線程安全的相關知識,分析以下代碼,當調用test方法時i>10時是否會引起死鎖?並簡要說明理由。
public void test(int i)
{
   lock(this)
 {
   if (i>10)
   {
     i--;
     test(i);
   }
 }
}
答:不會發生死鎖,(但有一點int是按值傳遞的,所以每次改變的都只是一個副本,因此不會出現死鎖。但如果把int換做一個object,那麼死鎖會發生)

28 面向對象的語言具有________性、_________性、________性
答:封裝、繼承、多態。

29 能用foreach遍歷訪問的對象需要實現 ________________接口或聲明________________方法的類型。
答:IEnumerable 、 GetEnumerator。

30 GC是什麼? 爲什麼要有GC?
答:GC是垃圾收集器。程序員不用擔心內存管理,因爲垃圾收集器會自動進行管理。要請求垃圾收集,可以

調用下面的方法之一:
  System.gc()
  Runtime.getRuntime().gc()

31 String s = new String("xyz");創建了幾個String Object?
答:兩個對象,一個是“xyx”,一個是指向“xyx”的引用對象s。

32 abstract class和interface有什麼區別?
  答:聲明方法的存在而不去實現它的類被叫做抽象類(abstract class),它用於要創建一個體現某些基本行爲的類,併爲該類聲明方法,但不能在該類中實現該類的情況。不能創建abstract 類的實例。然而可以創建一個變量,其類型是一個抽象類,並讓它指向具體子類的一個實例。不能有抽象構造函數或抽象靜態方法。Abstract 類的子類爲它們父類中的所有抽象方法提供實現,否則它們也是抽象類爲。取而代之,在子類中實現該方法。知道其行爲的其它類可以在類中實現這些方法。
  接口(interface)是抽象類的變體。在接口中,所有方法都是抽象的。多繼承性可通過實現這樣的接口而獲得。接口中的所有方法都是抽象的,沒有一個有程序體。接口只可以定義static final成員變量。接口的實現與子類相似,除了該實現類不能從接口定義中繼承行爲。當類實現特殊接口時,它定義(即將程序體給予)所有這種接口的方法。然後,它可以在實現了該接口的類的任何對象上調用接口的方法。由於有抽象類,它允許使用接口名作爲引用變量的類型。通常的動態聯編將生效。引用可以轉換到接口類型或從接口類型轉換,instanceof 運算符可以用來決定某對象的類是否實現了接口。
(1)一個類可以實現任意多個接口,但是最多隻能對一個抽象類進行子類化。
(2)一個抽象類可以包括非抽象方法,而一個接口所有的方法都是抽象的
(3)一個可以使用變量,而一個接口不能
(4)一個抽象類的方法可以有各種訪問修飾符,但是在聲明接口時候不允許有訪問修飾符,默認爲public.
(5)一個抽象類可以定義構造函數,而一個接口不能。
(C#設計模式)
補充:一個C#接口可以包含方法,屬性,事件和索引器,但是不能包容委託?
delegate關鍵字引入的是一個新的類型,而event關鍵字引入的是一個新的成員。一個接口聲明規範了成員,而不是類型。所以不能包含委託。


33 接口是否可繼承接口? 抽象類是否可實現(implements)接口? 抽象類是否可繼承實體類(concrete class)?
答:接口可以繼承接口。抽象類可以實現(implements)接口,抽象類是可繼承實體類,但前提是實體類必須有明確的構造函數。

34 類繼承和接口繼承
答:類繼承不僅說明繼承,而且也實現繼承;接口繼承只說明繼承。換句話說,派生類可以繼承基類的方法實現,而派生的接口只繼承了父接口的成員方法說明,而沒有繼承父接口的實現。
  類繼承只允許單繼承,但是接口繼承允許多繼承,一個子接口可以有多個父接口。

35 啓動一個線程是用run()還是start()?
答:啓動一個線程是調用start()方法,使線程所代表的虛擬處理機處於可運行狀態,這意味着它可以由JVM調度並執行。這並不意味着線程就會立即運行。run()方法可以產生必須退出的標誌來停止一個線程。
 
36 構造器Constructor是否可被override?
答:構造器Constructor不能被繼承,因此不能覆蓋Override,但可以被重載Overloading。

37 是否可以繼承string類?
  string類型是直接從object繼承的密封類類型,不能被繼承。

38 try {}裏有一個return語句,那麼緊跟在這個try後的finally {}裏的code會不會被執行,什麼時候被執行,在return前還是後?
答:會執行,在return前執行。
 
39 swtich是否能作用在byte上,是否能作用在long上,是否能作用在string上?
  答:switch(expr1)中,expr1是一個表達式,類型爲sbyte,byte,short,ushort,int ,uint,long,ulong,char,string或枚舉類型。所以能作用在byte,long和string上。

40 當一個線程進入一個對象的一個synchronized方法後,其它線程是否可進入此對象的其它方法?
  答:不能,一個對象的一個synchronized方法只能由一個線程訪問。

41 使用抽象方法和抽象類有什麼優點?
答:一 可以使用類具有更好的層次結構,該結構能更清晰地反映我們建立的模型;二是使用抽象類可以把某些很難定位的運行時錯誤變成易於定位的編譯時錯誤。

42 抽象方法(abstract的method)的特性?是否可同時是static,是否可同時是native,是否可同時是synchronized?
答:抽象方法具有以下特性:抽象方法是隱式的虛方法,只允許在抽象類中使用抽象方法聲明,抽象方法聲明不提供實際的實現。在抽象方法聲明中使用 static 或 virtual 修飾符是錯誤的。
都不能。
(Native 序列化格式使用非常簡單的算法,使 SQL Server 能夠在磁盤上存儲 UDT 的有效表示形式。標記爲 Native 序列化的類型只能將值類型(在 Microsoft Visual C# 中爲 struct,在 Microsoft Visual Basic .NET 中爲 structure)用作成員。不支持引用類型(如 Visual C# 和 Visual Basic 中的類)的成員,無論它們是用戶定義的成員還是框架中已有的成員(如 String),均是如此。 (來自MSDN))

43 進程和線程的區別?
答:進程是系統進行資源分配和調度的單位;線程是CPU調度和分派的單位,一個進程可以有多個線程,這些線程共享這個進程的資源。

44 堆和棧的區別?
答:
    棧:由編譯器自動分配、釋放。在函數體中定義的變量通常在棧上。
    堆:一般由程序員分配釋放。用new、malloc等分配內存函數分配得到的就是在堆上。

45 成員變量和成員函數前加static的作用?
答:它們被稱爲常成員變量和常成員函數,又稱爲類成員變量和類成員函數。分別用來反映類的狀態。

46 請指出GAC的含義?
答:全局程序集緩存。

47 在c#中using和new這兩個關鍵字有什麼意義,請寫出你所知道的意義?
答:
using 關鍵字:
using 指令:   創建命名空間的別名, 導入在其他命名空間中定義的類型
using 語句:   定義一個範圍,在此範圍末尾將處置對象。 在 using 語句中創建一個實例,確保退出using 語句時在對象上調用 Dispose(執行與釋放或重置非託管資源相關的應用程序定義的任務。).實例化的對象必須實現 System.IDisposable 接口。

new 關鍵字:
new 運算符:  用於在堆上創建對象和調用構造函數。
new 修飾符:  用於隱藏基類成員的繼承成員。
new 約束:    用於在泛型聲明中約束可能用作類型參數的參數的類型。

48 需要實現對一個字符串的處理,首先將該字符串首尾的空格去掉,如果字符串中間還有連續空格的話,僅保留一個空格,即允許字符串中間有多個空格,但連續的空格數不可超過一個.
答:string inputStr=" xx   xx  ";
inputStr=Regex.Replace(inputStr.Trim()," *"," ");

49 C#中 property 與 attribute的區別,他們各有什麼用處,這種機制的好處在哪裏?
答:一個是屬性,用於存取類的字段,一個是特性,用來標識類,方法等的附加性質

50  #inline,#region,#endregion, #warning, #error.
答: #region,#endregion 指令用於把一段代碼標記爲有給定名稱的一個塊。
#inline 指令用於改變編譯器在警告和錯誤信息中顯示文件名和行號信息。
#warning 編譯器遇見它會產生一個警告。
#error 編譯器遇見它會產生一個錯誤。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章