C# Junior Developer 面試問題集 / C# 學徒模式

2021-06-23

筆記 C# 初階面試常見問題 🙂

logo

問題集

常見的應用程式架構為何

UI Layer, Business Layer, Data Access Layer, Common Library Layer

為什麼需要使用應用程式架構

讓程式碼能夠重複使用,同時也讓程式碼能夠基於架構的進行新增、異動,保持擴展的彈性。

什麼是 Class / Object

Class 翻譯為類別,是 Object (物件) 的藍圖與樣板,定義物件的資料 (Field, Property) 規格與操作方法 (Method) 規格

什麼是 Instantiate

由類別建立物件的過程,建立的過程會使用類別的 Constructor Method。

為什麼要使用單元測試

提升軟體的品質,更容易進行除錯,以及避免程式碼的異動造成未注意的影響。

什麼是 Constructor

也稱為建構子,當物件由類別被建立為實體(Instance)所執行的方法,可以作為建立時搭配的演算步驟所使用。

建構子可以呼叫靜態或者非靜態的方法(Call Static / Non-static Method is allowed)。

Field 、 Property 的差別

Field(Backing Field) 是封裝在物件之中的資料,不提供外界使用,僅供物件本身的方法邏輯所使用。

Property 是提供外界讀取、寫入的資料屬性,其背後實際的資料是 Field,Property 提供的可以是 Field 資料的運算處理的結果,寫入的資料也可以經運算處理後才保存至 Field。

Property 的用途

組合

public string FullName
{
  get { return FirstName + " " + LastName;}
}

計算

public DateTime BirthDate { get; set; }

public float Age 
{
    get { return (DateTime.Now - BirthDate).Days / (float)365; }
}

關聯物件的屬性

如果組合關係下的物件,經常需要使用子物件的屬性或者屬性的運算結果,可以藉由本身的 Property 來進行設定,減輕語法的程式碼量。

public ManagerName
{
  get { return Manager?.Name;}
}

為什麼要使用 Namespace

  1. 可以有架構、邏輯性的管理類別
  2. 避免類別名稱相同造成問題

Namespace Example:

Microsoft.AspNetCore.Mvc
System.Web.Mvc

什麼是 Static

翻譯為靜態,靜態是指系統對於記憶體的分配方式,是在程式初始化階段就預先分配,直到整個程式結束才會回收的記憶體管理方式

什麼是 Static Class

翻譯為靜態類別

可以不用建立實體就使用靜態類別中的方法,靜態類別中的成員(屬性及方法)都必須為靜態的。

什麼是 Static Members

非靜態類別的成員也可以是靜態的,不需要建立實體就可以使用靜態成員,而靜態成員是歸屬於類別,並非每個物件都有一份的存在。

靜態類別可以用於計算該類別的物件建立數量。

什麼是 Singleton Pattern

類別藉由 Static Property 或者 Private Constructor 的方式檢查 Instance 是否已經存在,如果不存在則建立,已存在就以目前的 Instance 進行回傳,用以保存類別僅有單一 Instance 的狀態。

什麼是 Lazy Loading

藉由 Property 的 Get 來檢查關聯物件是否存在,如果不存在則建立。相對於使用 Constructor 預設先建立好關聯物件的方式,Lazy Loading 是指當要使用時才建立,較不主動的方式。

private Person _person;
public Person Person
{
  get
  {
    if (_person == null)
    {
      _person = new Person();
    }
    return _person;
  }
  set { _person = value;}
}

什麼是 Object Initializers

C# Language Features.

可以不需要設定多種 Overloading 的 Parameterized Constructor,彈性的初始化物件、設定物件的資料。

var person = new Person
{
  Name = "Webber",
  Job = "Software Developer"
};

Data Encapsulation 的用途

...

Constant

翻譯為常數。

Simple Data Type Never chage values. Static / Assigned on declaration variable.

Const 必須為 Compile 期間能夠決定數值的 Type。適用於經常不變,不會更改的內容 (例如:單位、圓周率)。

Const 的 type 只能為 Integer, Float, String 等(不能是 Struct, Class)。

此外 Const 的初始化只能在 Declaration 中進行,無法在 Constructor 中進行。

public const double Pi = 3.14159;
public const double GravitationalConstant = 6.673e-11;

ReadOnly Field

Static or non-static

Readonly Field 可以由 Declaration 或者由 Constructor 進行賦值,並依照 Priority 的順序,如果先由 Priority 較小的賦予動作去執行,再由 Priority 高者覆蓋為新的賦值。

internal class Template
{
    private readonly int _myVar = 30; // Priority 0

    public int MyVar { get { return _myVar; } }

    public Template()
    {
        _myVar = 100; // Priority 1
    }

    public Template(bool b) : this()
    {
        _myVar = 120; // Priority 2
    }
}

Constant And Readonly Field Diff

Constant 只能在 Declaration 賦值;Readonly Field 可以在 Declaration 以及 Constructor 賦值。

Constant 是 Compile Time 的固定值;Readonly Field 是 Runtime 的固定值。

Auto-Implemented Property

C# Language Features.

Short cut syntax for implicit field and associated property getter and setter.

在 Field 透過 Property 提供 get 與 set 沒有特別的程式邏輯的時候,藉由 Auto-Implemented Property 可以保持程式的簡潔,達到原本較繁瑣的宣告效果。

詳盡的情境使用 propfull 來分別設定 Field, Property getter, setter;簡單的情境使用 prop 來使用 Auto-Implemented Property。

Method

Implement the logic for specific behavior or functionality in a class

翻譯為方法

方法相較於屬性是較為複雜的演算邏輯步驟,但是方法的設計仍不應該過於複雜:

The first rule of functions is that they should be small. The second rule of functions is that they should be smaller than that. Functions should not be 100 lines long. Functions should hardly ever be 20 lines long.
Bob Martin

Parameter

part of method signature

翻譯為參數

Argument

part of method call

翻譯為引數

Method Overloading

Methods with same name and purpose but different signatures

翻譯為方法多載

藉由 Signature (Method 的參數型別、數量) 的不同,允許同名的 Method。依據 Caller 所使用的 Signature 決定要使用的 Method。需要注意的是 Method 的回傳型別不屬於 Signature 的一部分,此外參數的

Method Chaining

One method overload call another overload to prevent repeated code.

Expression-bodied method

C# Language Features.

Syntax short cut for single statement methods that returns a value

readonly

Property With Getter 的完整寫法:

public string FirstName { get; set; }
public string LastName { get; set; }

public string FullName
{
    get { return $"{FirstName} {LastName}"; }
}

Expression-bodied 的簡寫方式:

public string FullName => $"{FirstName} {LastName}";

Named Arguement

Clarify the purpose of an argument and define argument without concern for their position in the parameter list.

藉由在 Caller 主動具名的方式呼叫所要使用的 Method 讓程式碼更容易理解,但要注意過於明確的項目不需要畫蛇添足,造成反效果。

// ❌ 不易識別 Argument 的 true, false 用途
OrderProduct(product, 10, true, false)

// ⭕ 容易識別 Argument 的 true, false 分別代表
OrderProduct(
  product, 
  productNumber: 10, 
  deliveryService: true, 
  productMemo: false)

Enum 的使用情境

處理 Boolean Prameter 問題。

使用 Enum Over Boolean Parameter / Constant

避免使用在經常改變的情況

Optional Parameter

By specifying Parameter with a default value.

參數的預設值宣告於 Method Signature,可以減少 Method OverLoading 的使用。

public Order OrderProduct(Product product, int quantity = 1, DateTime? orderDate = null)

Call by value vs Call by reference

...

Ref

C# Language Features.

Allow method to modify the ref parameter.

Argument must be Initialized.

Parameter value can be changed in the method.

Out

C# Language Features.

Ask method must provide the out parameter value.

Argument Must be declared.

Parameter value must be set in the method.

Immutable

...

StringBuilder Benefits

Mutable, easily to change values.

Efficient to append lots of strings.

Initailizing Auto-Implemented Properties

public string PlantType {get; set;} = "Vegetable";

Static Method Call Only;

Verbatim String Literals

翻譯為逐字識別項

可以讓 Escape Char 不發揮作用。

var normalString = "Hello\r\nWorld";
// Hello
// World

var verbatimString = @"Hello\r\nWorld";
// Hello\r\nWorld

String Interpolation

翻譯為字串插值

可以幫助組合字串以更容易閱讀的方式進行。

string name = "Mark";
var date = DateTime.Now;

// Composite formatting:
Console.WriteLine("Hello, {0}! Today is {1}, it's {2:HH:mm} now.", name, date.DayOfWeek, date);
// String interpolation:
Console.WriteLine($"Hello, {name}! Today is {date.DayOfWeek}, it's {date:HH:mm} now.");