# Tổng hợp kiến thực một cách lộn xộn

Tổng hợp những mảnh kiến thức nhỏ về lập trình và Unity

# Đặc trưng của OOP

### Tính kế thừa

- ****Định nghĩa:****<span style="white-space:pre-wrap;"> Thừa hưởng các thuộc tính, hành vi từ một lớp khác.</span>
- ****Biểu hiện:****<span style="white-space:pre-wrap;"> Class có thể kế thừa (extends) lớp cha và triển khai (implements) các interface.</span>
- ****Lợi ích:****
    - Giúp tái sử dụng code đã có nhưng vẫn duy trì một hệ thống phân cấp thống nhất.
    - Lớp cha đơn giản và tổng quát hơn lớp con. Lớp con cụ thể và đa dạng hơn lớp cha.
- ****Khác:****<span style="white-space:pre-wrap;"> C# không hỗ trợ đa kế thừa nhưng có hỗ trợ sử dụng Interface. Trong một số trường hợp có thể sử dụng interface để mô phỏng đa kế thừa.</span>
- ****Ví dụ:****<span style="white-space:pre-wrap;"> Lớp cha là lớp động vật có các phương thức di chuyển, kêu, ăn… các lớp con như chó, mèo, chim, cá… kế thừa lớp cha động vật thì đều có các hành vi di chuyển, kêu, ăn…</span>

### Tính đóng gói

- ****Định nghĩa:****<span style="white-space:pre-wrap;"> Giữ tất cả các thông tin quan trọng (data, method) bên trong một lớp, chỉ cho phép truy cập nhưng thông tin cần thiết.</span>
- ****Biểu hiện:****<span style="white-space:pre-wrap;"> Xác định mức độ truy cập thông qua các accsess modifiers public, internal, protected, private</span>
- ****Lợi ích:****
    - Tăng cường bảo mật, bảo vệ dữ liệu quan trọng khỏi truy cập trái phép.
    - Hạn chế truy cập thông tin không cần giúp dễ đọc, dễ hiểu, dễ bảo trì hơn.
    - Cho phép thay đổi cách hoạt động bên trong lớp mà không ảnh hưởng đến chương trình.
    - Tăng khả năng tái sử dụng của class trong các dự án khác nhau.
- ****Ví dụ:****<span style="white-space:pre-wrap;"> Lớp chó có thuộc tính trạng thái (đói, no) là private để thay đổi trạng thái này người dùng phải sử dụng method public cho ăn (feed) không thể truy cập trực tiếp vào thuộc tính trạng thái.</span>

### Tính trừu tượng

- ****Định nghĩa:****<span style="white-space:pre-wrap;"> chỉ tiết lộ những thông tin cần thiết của một đối tượng. Bỏ qua những chi tiết phức tạp bên trong.</span>
- ****Biểu hiện:****<span style="white-space:pre-wrap;"> Thể hiện thông qua abstact class và interface. Thưởng chỉ đưa ra nhiệm vụ mà không nói cụ thể cách triển khai. Cách triển khai được thực hiện ở các class kế thừa nó.</span>
- ****Lợi ích:****
    - Đơn giản hoá, người dùng chỉ cần quan tâm đến các thuộc tính, phương thức được công khai không cần quan tâm đến cách thức hoạt động của nó.
    - Dễ dàng thay đổi cách thức hoạt động bên trong mà không ảnh hưởng đến phần còn lại của chương trình.
    - Tăng khả năng tái sử dụng
- ****Ví dụ:****
    - Khi cho động vật ăn thì nó thực hiện việc ăn. Người nuôi không cần quan tâm đến bộ não con chó ra lệnh gì, con chó nhai như thế nào…
    - Lái một chiếc ô tô thì người lái chỉ cần quan tâm đến côn, ga, số, phanh, vô lăng không cần quan tâm đến cách động cơ đốt nhiên liệu như nào các bánh răng truyền động ra sao để chuyển hướng…

### Tính đa hình

- ****Định nghĩa:****<span style="white-space:pre-wrap;"> Cho phép các đối tượng thuộc các lớp khác nhau có thể phản hồi một message theo nhiều cách khác nhau.</span>
- ****Biểu hiện:****<span style="white-space:pre-wrap;"> Overiding method, overloading method</span>
    - Overiding method (trong runtime): lớp con phản hồi khác lớp cha của nó.
    - Overloading method (compile time): Phương thức có cùng tên nhưng khác số lượng tham số và có thể khác dữ liệu trả về
- ****Lợi ích:****
    - Giảm thiểu lặp code, giúp dễ bảo trì hơn.
    - Cho phép chương trình thích ứng với các trường hợp khác nhau mà không cần sửa code nhiều.
    - Giúp tạo ra các mô hình dễ đọc, dễ hiểu.
- ****Ví dụ:****<span style="white-space:pre-wrap;"> Các động vật kế thừa lớp động vật đều có hành động di chuyển, kêu nhưng chó, chim, cá thực hiện các hành động di chuyển, kêu hoàn toàn khác nhau.</span>

# Cấu trúc dữ liệu

### Array, List và HashSet

Cả 3 đều là cấu trúc dữ liệu được sử dụng để lưu trữ một tập hợp các phần tử có cùng kiểu dữ liệu

<table id="bkmrk-ti%C3%AAu-ch%C3%ADarraylist%3Ct%3E"><colgroup><col></col><col></col><col></col><col></col></colgroup><tbody><tr><th>****Tiêu chí****

</th><th>****Array****</th><th>****List&lt;T&gt;****</th><th>****HashSet&lt;T&gt;****</th></tr><tr><td>****Cấu trúc****

</td><td>Mảng cố định kích thước

</td><td>Mảng động (có Capacity, tự tăng)

</td><td>Bảng băm (bucket + hash)

</td></tr><tr><td>****Kích thước****

</td><td>Cố định (khởi tạo xong không đổi)

</td><td>Linh hoạt (tự tăng Capacity)

</td><td>Linh hoạt

</td></tr><tr><td>****Truy cập theo index****

</td><td>O(1)

</td><td>O(1)

</td><td>****Không hỗ trợ****

</td></tr><tr><td>****Duyệt tuần tự****

</td><td>O(n)

</td><td>O(n)

</td><td>O(n)

</td></tr><tr><td>****Thêm phần tử****

</td><td>Không (phải cấp phát lại)

</td><td>Cuối danh sách: trung bình O(1); chèn giữa: O(n)

</td><td>Trung bình O(1)

</td></tr><tr><td>****Tìm****

</td><td>O(n)

</td><td>O(n)

</td><td>****Trung bình O(1)****

</td></tr><tr><td>****Cho phép trùng lặp****

</td><td>Có

</td><td>Có

</td><td>****Không****<span style="white-space:pre-wrap;"> (tập hợp duy nhất)</span>

</td></tr><tr><td>****Duy trì thứ tự****

</td><td>****Thứ tự chỉ số****

</td><td>****Giữ thứ tự chèn****

</td><td>****Không đảm bảo thứ tự****

</td></tr><tr><td>****Khi nên dùng****

</td><td>Kích thước biết trước, tối đa hiệu năng/nhớ

</td><td>Danh sách tổng quát, thêm/xóa không quá nhiều ở giữa

</td><td>Kiểm tra tồn tại, phép toán tập hợp (union/intersect/diff)

</td></tr><tr><td>****Hạn chế****

</td><td>Cứng nhắc về kích thước

</td><td>Thêm/xóa giữa tốn kém O(n)

</td><td>Không truy cập theo index; overhead bộ nhớ lớn hơn

</td></tr></tbody></table>

### Hashtable và Dictionary

Đều là cấu trúc dữ liệu để lưu trữ dữ liệu dưới dạng cặp key/value.

<table id="bkmrk-ti%C3%AAu-ch%C3%ADhashtabledic"><colgroup><col style="width:169px;"></col><col style="width:278px;"></col><col></col></colgroup><tbody><tr><th>****Tiêu chí****

</th><th>****Hashtable****</th><th>****Dictionary&lt;TKey,TValue&gt;****</th></tr><tr><td>****IsGeneric****

</td><td>****Không****<span style="white-space:pre-wrap;"> (non-generic) → boxing với value types</span>

</td><td>****Có****<span style="white-space:pre-wrap;"> (generic) → tránh boxing</span>

</td></tr><tr><td>****Kiểu key/value****

</td><td>`<span class="editor-theme-code">object</span>`/`<span class="editor-theme-code">object</span>`

</td><td>`<span class="editor-theme-code">TKey</span>`/`<span class="editor-theme-code">TValue</span>`

</td></tr><tr><td>****Null Key****

</td><td>****Không cho phép****

</td><td>****Không cho phép****

</td></tr><tr style="height:10px;"><td>****Null Value****

</td><td>Cho phép (kiểu tham chiếu)

</td><td>Cho phép (kiểu tham chiếu)

</td></tr><tr><td>****Hiệu năng trung bình****

</td><td>Thấp hơn do boxing + cast

</td><td>****Tốt hơn****, đặc biệt với value types

</td></tr><tr><td>****An toàn kiểu (type-safety)****

</td><td>Thấp (dễ lỗi cast runtime)  
Trả về null

</td><td>****Cao****<span style="white-space:pre-wrap;"> (kiểm tra compile-time)</span>

Trả về exception

</td></tr><tr><td>****Thứ tự****

</td><td>Không đảm bảo

</td><td><span style="white-space:pre-wrap;">Không đảm bảo (thường là theo thứ tự chèn trên .NET hiện đại, </span>****đừng phụ thuộc****)

</td></tr><tr><td>****Thread-safety****

</td><td>Không an toàn luồng.  
<span style="white-space:pre-wrap;">Có thể bọc </span>`<span class="editor-theme-code">Hashtable.Synchronized</span>`<span style="white-space:pre-wrap;"> (overhead cao)</span>

</td><td>Không an toàn luồng.

<span style="white-space:pre-wrap;">Dùng </span>`<span class="editor-theme-code">ConcurrentDictionary<,></span>`<span style="white-space:pre-wrap;"> cho đa luồng.</span>

</td></tr><tr><td>****API****

</td><td>Cũ, chủ yếu vì tương thích legacy

</td><td>****Khuyến nghị mặc định****<span style="white-space:pre-wrap;"> trong hầu hết trường hợp</span>

</td></tr><tr><td>****Khi nên dùng****

</td><td>Chỉ khi phải tương thích code cũ

</td><td>****Lựa chọn mặc định****<span style="white-space:pre-wrap;"> cho map/tra cứu key/value.</span>

</td></tr></tbody></table>

# So sánh

### Equals và '=='

<table id="bkmrk-%C4%90%E1%BA%B7c-%C4%91i%E1%BB%83mto%C3%A1n-t%E1%BB%AD-%3D%3Dph"><colgroup><col style="width:109px;"></col><col></col><col style="width:334px;"></col></colgroup><tbody><tr><th>****Đặc điểm****

</th><th>****Toán tử** `<strong class="editor-theme-bold editor-theme-code">==</strong>`**

</th><th>****Phương thức** `<strong class="editor-theme-bold editor-theme-code">Equals()</strong>`**

</th></tr><tr><td>****Loại so sánh mặc định****

</td><td>****Kiểu tham chiếu (class):****<span style="white-space:pre-wrap;"> mặc định so sánh </span>****tham chiếu****<span style="white-space:pre-wrap;"> (trừ khi kiểu đó </span>**overload** `<span class="editor-theme-code">==</span>`<span style="white-space:pre-wrap;"> (Ví dụ: </span>`<span class="editor-theme-code">string</span>`<span style="white-space:pre-wrap;">, </span>`<span class="editor-theme-code">record</span>`).

  
****Kiểu giá trị (struct):****<span style="white-space:pre-wrap;"> chỉ </span>****một số kiểu dựng sẵn****<span style="white-space:pre-wrap;"> (int, double, bool, enum, char, …) có </span>`<span class="editor-theme-code">==</span>`<span style="white-space:pre-wrap;"> sẵn và so sánh </span>****giá trị****<span style="white-space:pre-wrap;">; với </span>**struct tự định nghĩa**<span style="white-space:pre-wrap;">, </span>****không có** `<strong class="editor-theme-bold editor-theme-code">==</strong>` **mặc định****<span style="white-space:pre-wrap;"> — muốn dùng phải tự overload.</span>

</td><td>****Kiểu tham chiếu (class):****<span style="white-space:pre-wrap;"> mặc định là </span>****tham chiếu****<span style="white-space:pre-wrap;"> như </span>`<span class="editor-theme-code">==</span>`<span style="white-space:pre-wrap;"> (trừ khi kiểu override </span>`<span class="editor-theme-code">Equals</span>`<span style="white-space:pre-wrap;">). </span>`<span class="editor-theme-code">string.Equals</span>`<span style="white-space:pre-wrap;"> mặc định so sánh </span>****theo nội dung****<span style="white-space:pre-wrap;"> (giá trị).</span>  
  
****Kiểu giá trị (struct):****<span style="white-space:pre-wrap;"> mặc định so sánh </span>****giá trị****<span style="white-space:pre-wrap;"> (field-by-field) thông qua </span>`<span class="editor-theme-code">ValueType.Equals</span>`, trừ khi bạn override/IEquatable.

</td></tr><tr><td>****Ghi đè / tuỳ biến****

</td><td>****Có thể**** *****overload*****<span style="white-space:pre-wrap;"> (không phải </span>**override**<span style="white-space:pre-wrap;">) bằng cách khai báo </span>`<span class="editor-theme-code">public static bool operator ==(...)</span>`<span style="white-space:pre-wrap;">. </span>  
  
<span style="white-space:pre-wrap;">Khi overload </span>`<span class="editor-theme-code">==</span>`<span style="white-space:pre-wrap;"> </span>****phải overload luôn** `<strong class="editor-theme-bold editor-theme-code">!=</strong>`**<span style="white-space:pre-wrap;">, và thường </span>****nên****<span style="white-space:pre-wrap;"> override </span>`<span class="editor-theme-code">Equals</span>`<span style="white-space:pre-wrap;"> + </span>`<span class="editor-theme-code">GetHashCode</span>`<span style="white-space:pre-wrap;"> cho nhất quán.</span>

</td><td>****Có thể**** *****override*****<span style="white-space:pre-wrap;"> (virtual method </span>`<span class="editor-theme-code">System.Object</span>`<span style="white-space:pre-wrap;">). </span>

<span style="white-space:pre-wrap;">Với generics/hiệu năng, </span>****nên****<span style="white-space:pre-wrap;"> triển khai </span>`<span class="editor-theme-code">IEquatable<T>.Equals(T other)</span>`<span style="white-space:pre-wrap;"> và đảm bảo tương thích với </span>`<span class="editor-theme-code">Equals(object)</span>`<span style="white-space:pre-wrap;"> + </span>`<span class="editor-theme-code">GetHashCode()</span>`.

</td></tr><tr><td>****Tính linh hoạt****

</td><td><span style="white-space:pre-wrap;">Ít linh hoạt hơn (chỉ 1 toán tử; phải cẩn thận tương thích với </span>`<span class="editor-theme-code">Equals</span>`/`<span class="editor-theme-code">GetHashCode</span>`).

</td><td><span style="white-space:pre-wrap;">Linh hoạt hơn: có thể override/triển khai </span>`<span class="editor-theme-code">IEquatable<T></span>`<span style="white-space:pre-wrap;">, và có thêm </span>`<span class="editor-theme-code">object.Equals(a,b)</span>`<span style="white-space:pre-wrap;"> (static) </span>****an toàn null****<span style="white-space:pre-wrap;">. Với </span>`<span class="editor-theme-code">string.Equals</span>`<span style="white-space:pre-wrap;"> có overload chọn </span>`<span class="editor-theme-code">StringComparison</span>`.

</td></tr><tr><td>****Tốc độ****

</td><td><span style="white-space:pre-wrap;">Không có quy tắc “nhanh hơn” nói chung. Với </span>`<span class="editor-theme-code">string</span>`<span style="white-space:pre-wrap;">, </span>`<span class="editor-theme-code">==</span>`<span style="white-space:pre-wrap;"> thực chất gọi </span>`<span class="editor-theme-code">string.Equals(a,b)</span>`<span style="white-space:pre-wrap;">. Chênh lệch thường </span>****không đáng kể****<span style="white-space:pre-wrap;"> sau JIT inline.</span>

</td><td><span style="white-space:pre-wrap;">Tương tự: phụ thuộc kiểu cụ thể và triển khai </span>`<span class="editor-theme-code">Equals</span>`<span style="white-space:pre-wrap;">. Dùng </span>`<span class="editor-theme-code">EqualityComparer<T>.Default</span>`<span style="white-space:pre-wrap;"> để nhận cách so sánh tối ưu cho T.</span>

</td></tr><tr><td>****Sử dụng với****

**`<strong class="editor-theme-bold editor-theme-code">null</strong>`**

</td><td>****An toàn****<span style="white-space:pre-wrap;"> (không ném NRE); </span>`<span class="editor-theme-code">a == null</span>`<span style="white-space:pre-wrap;"> hợp lệ. Nếu tự overload, nhớ xử lý null đúng cách.</span>

</td><td><span style="white-space:pre-wrap;">Gọi </span>****instance****<span style="white-space:pre-wrap;"> </span>`<span class="editor-theme-code">a.Equals(b)</span>`<span style="white-space:pre-wrap;"> sẽ </span>****ném NRE****<span style="white-space:pre-wrap;"> nếu </span>`<span class="editor-theme-code">a</span>`<span style="white-space:pre-wrap;"> là </span>`<span class="editor-theme-code">null</span>`<span style="white-space:pre-wrap;">. Dùng </span>`<span class="editor-theme-code">object.Equals(a,b)</span>`<span style="white-space:pre-wrap;"> hoặc </span>`<span class="editor-theme-code">a?.Equals(b) ?? false</span>`<span style="white-space:pre-wrap;"> để </span>****an toàn null****.

</td></tr></tbody></table>

### Generic và Non-Generic

<table id="bkmrk-%C4%90%E1%BA%B7c-%C4%91i%E1%BB%83mnon-genericg"><colgroup><col style="width:152px;"></col><col></col><col></col></colgroup><tbody><tr><th>****Đặc điểm****

</th><th>****Non-generic****

</th><th>****Generic****

</th></tr><tr><td>****Khái niệm****

</td><td>Là kiểu dữ liệu truyền thống. Không khai báo cụ thể khi định nghĩa class, method, interface. Kiểu dữ liệu thực tế được xác định khi sử dụng.

</td><td>Là kiểu dữ liệu được tham số hoá bởi một hoặc nhiều kiểu khác nhau. Cho phép khai báo class, method, interface với kiểu cụ thể. Kiểu này sẽ được định nghĩa và sử dụng xuyên suốt.

</td></tr><tr><td>****Ưu điểm****

</td><td>Đơn giản, dễ hiểu

Hiệu quả cao hơn với các kiểu dữ liệu nguyên thuỷ

</td><td>Tăng khả năng tái sử dụng code

Đảm bảo an toàn dữ liệu vào và ra khi sử dụng

Tốt hơn do được tối ưu hoá cho kiểu dữ liệu cụ thể

</td></tr><tr><td>****Nhược điểm****

</td><td>Kém linh hoạt, khó tái sử dụng.

Thiếu an toàn do có thể sử dụng sai kiểu dữ liệu

</td><td>Phức tạp hơn so với non-generic.

Có thể ảnh hưởng hiệu suất với những kiểu dữ liệu phức tạp.

</td></tr><tr><td>****Sử dụng****

</td><td>Khi cần code đơn giản dễ hiểu, không yêu cầu tái sử dụng cao, không yêu cầu an toàn dữ liệu cao.

</td><td>Khi cần code có khả năng tái sử dụng cao và yêu cầu tính an toàn dữ liệu cao.

</td></tr></tbody></table>

### Delegate và Event

<table id="bkmrk-delegateevent--l%C3%A0-m%E1%BB%99"><colgroup><col></col><col></col></colgroup><tbody><tr><th>****Delegate****

</th><th>****Event****

</th></tr><tr><td>\- Là một tham chiếu đại diện cho phương thức.

\- Có thể gọi trực tiếp từ bất kỳ đâu có quyền truy cập.

\- Có thể gọi trực tiếp mà không có cơ chế bảo vệ nào nên có thể dẫn đến lỗi.

\- Ưu tiên tính linh hoạt.

</td><td>\- Là thành phần của lớp sử dụng delegate để quản lý danh sách các phương thức.

\- Chỉ có thể kích hoạt bên trong lớp mà nó được khai báo.

<span style="white-space:pre-wrap;">- Có cơ chế bảo vệ ngăn chặn gọi từ bên ngoài. Chỉ cho phép đăng ký bên trong class thông quan </span>

**+=**

<span style="white-space:pre-wrap;"> hoặc huỷ đăng ký qua </span>

**-=**

\- Ưu tiên an toàn và kiểm soát.

</td></tr></tbody></table>

### Struct và Class

<table id="bkmrk-ti%C3%AAu-ch%C3%ADstructclassb"><colgroup><col></col><col style="width:315px;"></col><col></col></colgroup><tbody><tr><th>Tiêu chí

</th><th>****struct****</th><th>****class****</th></tr><tr><td>****Bản chất****

</td><td><span style="white-space:pre-wrap;">Kiểu </span>****giá trị****<span style="white-space:pre-wrap;"> (value type)</span>

</td><td><span style="white-space:pre-wrap;">Kiểu </span>****tham chiếu****<span style="white-space:pre-wrap;"> (reference type)</span>

</td></tr><tr><td>****Cấp phát &amp; bộ nhớ****

</td><td><span style="white-space:pre-wrap;">Nằm trên </span>****stack hoặc heap****<span style="white-space:pre-wrap;"> tùy vào nơi nó sống.</span>

****Sao chép theo giá trị****

</td><td><span style="white-space:pre-wrap;">Luôn cấp phát trên </span>****heap****<span style="white-space:pre-wrap;">, biến giữ </span>****tham chiếu****<span style="white-space:pre-wrap;"></span>

****Sao chép tham chiếu****

</td></tr><tr><td>****Vòng đời &amp; GC****

</td><td><span style="white-space:pre-wrap;">Không tạo đối tượng riêng trên heap ⇒ </span>****ít áp lực GC****<span style="white-space:pre-wrap;"> (trừ khi bị boxing)</span>

</td><td><span style="white-space:pre-wrap;">Đối tượng do </span>****GC****<span style="white-space:pre-wrap;"> quản lý; cần cân nhắc phân bổ/thu hồi.</span>

</td></tr><tr><td>****Kế thừa****

</td><td>****Không****<span style="white-space:pre-wrap;"> kế thừa class; chỉ </span>****implement interface****

</td><td>****Có****<span style="white-space:pre-wrap;"> inheritance + implement interface</span>

</td></tr><tr><td>****Constructor mặc định****

</td><td><span style="white-space:pre-wrap;">Luôn có </span>`<span class="editor-theme-code">default</span>`<span style="white-space:pre-wrap;"> (zero-init); từ </span>****C# 10****<span style="white-space:pre-wrap;"> có thể </span>

****tự định nghĩa****<span style="white-space:pre-wrap;"> constructor không tham số</span>

</td><td>Tự do định nghĩa constructor; không có zero-init bắt buộc

</td></tr><tr><td>****Nullability****

</td><td><span style="white-space:pre-wrap;">Không thể </span>`<span class="editor-theme-code">null</span>`<span style="white-space:pre-wrap;"> (trừ </span>****nullable struct**** `<span class="editor-theme-code">T?</span>`)

</td><td><span style="white-space:pre-wrap;">Có thể </span>`<span class="editor-theme-code">null</span>`<span style="white-space:pre-wrap;"> (nullable reference types)</span>

</td></tr><tr><td>****Equality mặc định****

</td><td><span style="white-space:pre-wrap;">So sánh </span>****theo giá trị****<span style="white-space:pre-wrap;"> (field-by-field)</span>

</td><td><span style="white-space:pre-wrap;">So sánh </span>****tham chiếu****<span style="white-space:pre-wrap;"> (trừ khi override/record)</span>

</td></tr><tr><td>****Boxing****

</td><td><span style="white-space:pre-wrap;">Bị </span>****boxing****<span style="white-space:pre-wrap;"> khi chuyển sang </span>`<span class="editor-theme-code">object/interface</span>`<span style="white-space:pre-wrap;"> (nếu không dùng generics ràng buộc) → phát sinh cấp phát</span>

</td><td>Không có khái niệm boxing

</td></tr><tr><td>****Bất biến/biến đổi****

</td><td><span style="white-space:pre-wrap;">Nên thiết kế </span>****nhỏ &amp; bất biến****<span style="white-space:pre-wrap;"> (immutable) để tránh chi phí copy</span>

</td><td><span style="white-space:pre-wrap;">Linh hoạt cho </span>****đối tượng phức tạp****, nhiều trạng thái

</td></tr><tr><td>****Hiệu năng (quy tắc thực tế)****

</td><td>****Tốt****<span style="white-space:pre-wrap;"> cho dữ liệu </span>****nhỏ****<span style="white-space:pre-wrap;"> (≈ ≤ 16–32 byte), sống ngắn, dùng thường xuyên; tránh struct lớn/mutable vì </span>****tốn copy****

</td><td>Tốt cho mô hình phức tạp, cần chia sẻ qua tham chiếu, vòng đời dài

</td></tr><tr><td>****Generics****

</td><td><span style="white-space:pre-wrap;">Tránh boxing với </span>`<span class="editor-theme-code">where T : struct</span>`<span style="white-space:pre-wrap;">; hỗ trợ </span>`<span class="editor-theme-code">Nullable<T></span>`

</td><td><span style="white-space:pre-wrap;">Ràng buộc </span>`<span class="editor-theme-code">where T : class</span>`<span style="white-space:pre-wrap;"> cho API dùng tham chiếu</span>

</td></tr><tr><td>****Khi nên dùng****

</td><td>Để lưu những dữ liệu đơn giản, bất biến.

</td><td>Đa phần các đối tượng có đối tượng có dữ liệu, hành vi phức tạp..

</td></tr><tr><td>****Unity lưu ý****

</td><td><span style="white-space:pre-wrap;">Dùng </span>****struct****<span style="white-space:pre-wrap;"> (hoặc </span>`<span class="editor-theme-code">readonly struct</span>`<span style="white-space:pre-wrap;">) cho dữ liệu để </span>****giảm GC****

Cẩn thận copy trong Update

</td><td><span style="white-space:pre-wrap;">Dùng </span>****class****<span style="white-space:pre-wrap;"> cho </span>`<span class="editor-theme-code">MonoBehaviour</span>`, managers, asset refs; quản lý GC bằng pooling

</td></tr></tbody></table>

### Abstract class và Interface

<table id="bkmrk-ti%C3%AAu-ch%C3%ADabstract-cla"><colgroup><col></col><col></col><col></col></colgroup><tbody><tr><th>Tiêu chí

</th><th>****Abstract class****</th><th>****Interface****</th></tr><tr><td>****Định nghĩa****

</td><td><span style="white-space:pre-wrap;">Là lớp nền tảng có </span>****biến chung****<span style="white-space:pre-wrap;"> và </span>****một phần code sẵn****. Lớp con kế thừa và hoàn thiện.

</td><td><span style="white-space:pre-wrap;">Là </span>****bản hợp đồng****<span style="white-space:pre-wrap;"> liệt kê chức năng. Lớp/struct thực hiện (implement) các chức năng đó.</span>

</td></tr><tr><td>****Access Modifiers****

</td><td>****Có****

</td><td>****Không****. Mặc định là public

</td></tr><tr><td>****Field, Method dùng chung****

</td><td>****Có****

</td><td>****Có thể****<span style="white-space:pre-wrap;"> có method mặc định (từ C# 8 trở lên), nhưng không có field, constructor</span>

</td></tr><tr><td>****Kế thừa / triển khai****

</td><td><span style="white-space:pre-wrap;">Mỗi lớp chỉ kế thừa </span>****1 abstract class****.

</td><td><span style="white-space:pre-wrap;">Một lớp/struct có thể </span>****implement nhiều interface****.

</td></tr><tr><td>****Dùng cho struct****

</td><td>****Không dùng****<span style="white-space:pre-wrap;"> cho struct.</span>

</td><td>****Dùng được****<span style="white-space:pre-wrap;"> cho struct.</span>

</td></tr><tr><td>****Khi nên dùng****

</td><td><span style="white-space:pre-wrap;">Dùng để tạo một </span>****bản thiết kế**** chung cho các đối tượng liên quan đến nhau. Cung cấp các chi tiết mà các đối tượng đó phải tuân theo.

<span style="white-space:pre-wrap;">Khi cần constructor. </span>

</td><td><span style="white-space:pre-wrap;">Tạo ra một </span>****vai trò/chức năng**** mà các đối tượng triển khai nó sẽ đảm nhiệm.

</td></tr><tr><td>****Ưu điểm****

</td><td>Tái sử dụng code mạnh, quản lý chung dễ, thêm thành viên thường ít phá vỡ lớp con.

</td><td>Linh hoạt, áp dụng rộng (kể cả struct), hỗ trợ nhiều vai trò, rất hợp cho test/DI.

</td></tr><tr><td>****Nhược điểm****

</td><td>Ràng buộc thừa kế (chỉ 1 lớp cha), dễ tạo cây thừa kế sâu nếu lạm dụng.

</td><td><span style="white-space:pre-wrap;">Không có dữ liệu chung; nếu thêm phương thức mới có thể ảnh hưởng kiểu đã implement </span>****(giảm rủi ro nhờ “method mặc định” từ C# 8).****

</td></tr><tr style="height:10px;"><td>****Ví dụ Unity****

</td><td>`<span class="editor-theme-code">BaseController</span>`<span style="white-space:pre-wrap;">, </span>`<span class="editor-theme-code">BaseState</span>`<span style="white-space:pre-wrap;"> chứa biến/logic chung cho nhiều state.</span>

</td><td>`<span class="editor-theme-code">IService</span>`<span style="white-space:pre-wrap;">, </span>`<span class="editor-theme-code">IRepository</span>`<span style="white-space:pre-wrap;">, </span>`<span class="editor-theme-code">ISaveSystem</span>`<span style="white-space:pre-wrap;"> để tiêm phụ thuộc và viết unit test.</span>

</td></tr></tbody></table>

### Stack và Heap

<table id="bkmrk-ti%C3%AAu-ch%C3%ADstackheapb%E1%BA%A3n"><colgroup><col style="width:166px;"></col><col></col><col></col></colgroup><tbody><tr><th>Tiêu chí

</th><th>****Stack****</th><th>****Heap****</th></tr><tr><td>****Bản chất****

</td><td><span style="white-space:pre-wrap;">Vùng nhớ tạm cho </span>****biến cục bộ****<span style="white-space:pre-wrap;"> &amp; </span>****method****

</td><td><span style="white-space:pre-wrap;">Vùng nhớ động cho </span>****đối tượng sống lâu****

</td></tr><tr><td>****Lưu gì****

</td><td><span style="white-space:pre-wrap;">Giá trị của biến cục bộ (bao gồm </span>****struct nhỏ****), con trỏ return address

</td><td>****Object của class****<span style="white-space:pre-wrap;">, mảng, </span>****struct nằm trong object/mảng****, dữ liệu boxed

</td></tr><tr><td>****Cấp phát/giải phóng****

</td><td><span style="white-space:pre-wrap;">Rất nhanh theo kiểu </span>****LIFO****, trong method

</td><td>****Linh hoạt****<span style="white-space:pre-wrap;">: cấp phát tự do, thu gom bởi </span>****GC****

</td></tr><tr><td>****Quản lý****

</td><td>Tự động khi vào/ra hàm (không có GC)

</td><td>****Managed heap****<span style="white-space:pre-wrap;"> do GC quản lý (Gen0/1/2, LOH)</span>

</td></tr><tr><td>****Tốc độ****

</td><td>Rất nhanh, liên tục, cache-friendly

</td><td><span style="white-space:pre-wrap;">Chậm hơn stack; có thể bị </span>****tạm dừng (GC pause)****

</td></tr><tr><td>****Kích thước****

</td><td>Giới hạn (stack size)

</td><td>Rộng hơn, tùy RAM/GC

</td></tr><tr><td>****Thời gian sống****

</td><td>****Ngắn****, theo phạm vi hàm

</td><td>****Dài/linh hoạt****, theo tham chiếu còn sống

</td></tr><tr><td>****Khi nào xảy ra****

</td><td><span style="white-space:pre-wrap;">Biến cục bộ, tham số, </span>****struct****<span style="white-space:pre-wrap;"> cục bộ</span>

</td><td>`<span class="editor-theme-code">new</span>`<span style="white-space:pre-wrap;"> class, mảng; </span>****struct****<span style="white-space:pre-wrap;"> là field trong class/mảng; </span>****boxing****

</td></tr><tr><td>****Lưu ý quan trọng****

</td><td><span style="white-space:pre-wrap;">Dữ liệu </span>****biến mất****<span style="white-space:pre-wrap;"> khi ra khỏi hàm</span>

</td><td><span style="white-space:pre-wrap;">Tránh rác nhiều/đối tượng lớn gây áp lực </span>****GC/LOH****

</td></tr></tbody></table>

### For và Foreach

<table id="bkmrk-ti%C3%AAu-ch%C3%ADforforeachkh"><colgroup><col style="width:114px;"></col><col style="width:330px;"></col><col></col></colgroup><tbody><tr><th>Tiêu chí

</th><th>****for****</th><th>****foreach****</th></tr><tr><td>****Khái niệm****

</td><td><span style="white-space:pre-wrap;">Vòng lặp theo </span>****index****<span style="white-space:pre-wrap;"> (</span>`<span class="editor-theme-code">i = 0..n-1</span>`)

</td><td><span style="white-space:pre-wrap;">Vòng lặp </span>****duyệt từng phần tử****<span style="white-space:pre-wrap;"> qua </span>**enumerator.**

</td></tr><tr><td>****Cách hoạt động****

</td><td><span style="white-space:pre-wrap;">Truy cập </span>`<span class="editor-theme-code">collection[i]</span>`<span style="white-space:pre-wrap;"> mỗi bước</span>

</td><td><span style="white-space:pre-wrap;">Gọi </span>`<span class="editor-theme-code">GetEnumerator()</span>`<span style="white-space:pre-wrap;"> → </span>`<span class="editor-theme-code">MoveNext()</span>`<span style="white-space:pre-wrap;"> → </span>`<span class="editor-theme-code">Current</span>`

</td></tr><tr><td>****Truy cập theo index****

</td><td>****Có****

</td><td>****Không có****

</td></tr><tr><td>****Sửa phần tử****

</td><td>****Có thể****

Sửa phần tử chỉ định qua index

</td><td>****Không thể sửa****<span style="white-space:pre-wrap;"> trong vòng lặp</span>

</td></tr><tr><td>****Thêm/Xóa khi lặp****

</td><td><span style="white-space:pre-wrap;">Có thể làm được (cẩn thận cập nhật chỉ số; thường lặp </span>****ngược****<span style="white-space:pre-wrap;"> khi xóa)</span>

</td><td>****Không được****<span style="white-space:pre-wrap;"> thay đổi collection đang duyệt → dễ ném </span>`<span class="editor-theme-code">InvalidOperationException</span>`

</td></tr><tr><td>****Hiệu năng (thực tế)****

</td><td><span style="white-space:pre-wrap;">Rất nhanh cho </span>****mảng****<span style="white-space:pre-wrap;"> và khi cần truy cập ngẫu nhiên</span>

</td><td><span style="white-space:pre-wrap;">Rất nhanh cho </span>****List****<span style="white-space:pre-wrap;"> (enumerator là struct, thường </span>

****không cấp phát****<span style="white-space:pre-wrap;">); nhìn chung chênh lệch nhỏ, chọn theo </span>****độ rõ ràng****

</td></tr><tr><td>****Độ rõ ràng mã****

</td><td>Tốt khi cần index/điều kiện bước nhảy tùy biến

</td><td><span style="white-space:pre-wrap;">Ngắn gọn, dễ đọc khi </span>****chỉ duyệt****

</td></tr><tr><td>****Khi nên dùng****

</td><td><span style="white-space:pre-wrap;">Cần </span>****index****<span style="white-space:pre-wrap;">, cần </span>****chèn/xóa****<span style="white-space:pre-wrap;"> trong lúc lặp, hoặc cần nhảy bước</span>

</td><td>Duyệt đọc, không chỉnh sửa cấu trúc collection, code gọn

</td></tr><tr><td>****Lỗi thường gặp****

</td><td><span style="white-space:pre-wrap;">Quên cập nhật </span>`<span class="editor-theme-code">i</span>`, truy cập vượt biên

</td><td>Thêm/xóa trong vòng lặp.

</td></tr></tbody></table>

### Static và non-Static

#### class

<table id="bkmrk-ti%C3%AAu-ch%C3%ADstaticnon-st"><colgroup><col></col><col></col><col></col></colgroup><tbody><tr><th>Tiêu chí

</th><th>****Static****</th><th>****Non-static****</th></tr><tr><td>****Khởi tạo****

</td><td><span style="white-space:pre-wrap;">Không thể </span>`<span class="editor-theme-code">new</span>`; không có instance

</td><td><span style="white-space:pre-wrap;">Có thể </span>`<span class="editor-theme-code">new</span>`; nhiều instance

</td></tr><tr><td>****Thành viên****

</td><td>****Tất cả phải là static****

</td><td>Có cả instance và static

</td></tr><tr><td>****Kế thừa****

</td><td><span style="white-space:pre-wrap;">Không kế thừa/không implement interface; ngầm </span>`<span class="editor-theme-code">sealed</span>`

</td><td>Có thể kế thừa/implement interface

</td></tr><tr><td>****Dùng khi****

</td><td><span style="white-space:pre-wrap;">Nhóm </span>****hàm tiện ích/hằng số****<span style="white-space:pre-wrap;"> không cần state riêng</span>

</td><td><span style="white-space:pre-wrap;">Mô hình đối tượng có </span>****state/đa hình****

</td></tr></tbody></table>

####  field/method/property

<table id="bkmrk-ti%C3%AAu-ch%C3%ADstaticnon-st-1"><colgroup><col></col><col></col><col style="width:362px;"></col></colgroup><tbody><tr style="height:10px;"><th>Tiêu chí

</th><th>****Static****</th><th>****Non-static****</th></tr><tr><td>****Thuộc về****

</td><td>Class

</td><td>Instance

</td></tr><tr><td>****Truy cập****

</td><td>`<span class="editor-theme-code">Type.Member</span>`

</td><td>`<span class="editor-theme-code">obj.Member</span>`

</td></tr><tr><td>****Vòng đời****

</td><td>Tồn tại suốt thời gian chạy

</td><td>Sống theo vòng đời instance (GC)

</td></tr><tr><td>****Trạng thái****

</td><td>****Chung toàn cục****<span style="white-space:pre-wrap;"> → cần chú ý </span>****thread-safety****

</td><td>Tách biệt theo từng đối tượng

</td></tr><tr><td>****Dùng khi****

</td><td>Cấu hình bất biến, cache dùng chung, hằng số

</td><td><span style="white-space:pre-wrap;">Dữ liệu/hành vi gắn với </span>****một****<span style="white-space:pre-wrap;"> đối tượng</span>

</td></tr></tbody></table>

# Others

### Lập trình bất đồng bộ

Lập trình bất đồng bộ là kỹ thuật lập trình cho phép dừng tiến trình mà không chặn luồng chính.

- ****async****<span style="white-space:pre-wrap;"> là từ khóa dùng để khai báo phương thức bất đồng bộ. Phương thức bất đồng bộ có thể trả về giá trị hoặc không.</span>
- ****await**** cho phép nhường quyền điều khiển và tiếp tục thực thi khi tác vụ hoàn tất.

****Tác dụng:****

- Giữ UI/Gameplay mượt khi chờ I/O (HTTP, file, DB).
- <span style="white-space:pre-wrap;">Dễ chạy </span>****đồng thời****<span style="white-space:pre-wrap;"> nhiều I/O với </span>`<span class="editor-theme-code">Task.WhenAll(...)</span>`.
- <span style="white-space:pre-wrap;">Đẩy việc </span>****CPU-bound****<span style="white-space:pre-wrap;"> ra nền bằng </span>`<span class="editor-theme-code">Task.Run(...)</span>`.

****Ưu điểm:****

- Code tuyến tính, dễ đọc.
- Không block thread → scalable.
- Hỗ trợ hủy (`<span class="editor-theme-code">CancellationToken</span>`) và gom lỗi chuẩn.

****Nhược điểm / Lỗi hay gặp:****

- `<span class="editor-theme-code">.Result</span>`/`<span class="editor-theme-code">.Wait()</span>`<span style="white-space:pre-wrap;"> trên main/UI → deadlock.</span>
- `<span class="editor-theme-code">async void</span>`<span style="white-space:pre-wrap;"> (trừ event) khó bắt lỗi.</span>
- <span style="white-space:pre-wrap;">Đồng bộ hoá context phức tạp (cẩn trọng </span>`<span class="editor-theme-code">ConfigureAwait(false)</span>`<span style="white-space:pre-wrap;"> trong lib).</span>

### UniTask

<span style="white-space:pre-wrap;">UniTask là thư viện async tối ưu GC cho Unity. Cung cấp awaiter cho </span>`<span class="editor-theme-code">AsyncOperation</span>`<span style="white-space:pre-wrap;">, </span>`<span class="editor-theme-code">UnityWebRequest</span>`, Addressables… và tích hợp PlayerLoop.

****Tác dụng:****

- `<span class="editor-theme-code">await</span>`<span style="white-space:pre-wrap;"> trực tiếp Unity API (load scene, asset, web request).</span>
- <span style="white-space:pre-wrap;">Giảm cấp phát so với </span>`<span class="editor-theme-code">Task</span>`.
- Điều khiển thời điểm tiếp tục (Update/LateUpdate/FixedUpdate).
- <span style="white-space:pre-wrap;">Hủy theo vòng đời object: </span>`<span class="editor-theme-code">GetCancellationTokenOnDestroy()</span>`.

****Ưu điểm:****

- Hiệu năng/GC tốt, sát Unity main thread.
- <span style="white-space:pre-wrap;">API phong phú: </span>`<span class="editor-theme-code">UniTask.WhenAll</span>`<span style="white-space:pre-wrap;">, </span>`<span class="editor-theme-code">Delay</span>`<span style="white-space:pre-wrap;">, </span>`<span class="editor-theme-code">Yield</span>`<span style="white-space:pre-wrap;">, </span>`<span class="editor-theme-code">.Forget(handler)</span>`.

****Nhược điểm / Lưu ý:****

- Thêm phụ thuộc vào bên thứ ba.
- Cần quản lý PlayerLoop &amp; hủy đúng cách để tránh leak.
- <span style="white-space:pre-wrap;">Fire-and-forget phải </span>****log/bắt lỗi****<span style="white-space:pre-wrap;"> (</span>`<span class="editor-theme-code">.Forget(ex => LogException)</span>`).

****Gợi ý nhanh:****

- <span style="white-space:pre-wrap;">I/O: tạo nhiều tác vụ → </span>`<span class="editor-theme-code">WhenAll</span>`.
- <span style="white-space:pre-wrap;">CPU: </span>`<span class="editor-theme-code">Task.Run</span>`.
- <span style="white-space:pre-wrap;">Tránh </span>`<span class="editor-theme-code">.Result</span>`/`<span class="editor-theme-code">.Wait()</span>`<span style="white-space:pre-wrap;">; tránh </span>`<span class="editor-theme-code">async void</span>`.
- <span style="white-space:pre-wrap;">Unity: ưu tiên </span>****UniTask****<span style="white-space:pre-wrap;">, luôn dùng </span>`<span class="editor-theme-code">CancellationToken</span>`<span style="white-space:pre-wrap;"> gắn vòng đời object.</span>

### Garbage Collection (GC)

****GC****<span style="white-space:pre-wrap;"> là bộ thu gom rác tự động của .NET quản lý </span>****vòng đời đối tượng****<span style="white-space:pre-wrap;"> trên </span>****managed heap. GC**** <span style="white-space:pre-wrap;">tự phát hiện đối tượng </span>****không còn tham chiếu****<span style="white-space:pre-wrap;">, thu hồi bộ nhớ, và (thường) </span>****nén****<span style="white-space:pre-wrap;"> vùng heap để giảm phân mảnh.</span>

#### Cách hoạt động

- ****Phân tầng****<span style="white-space:pre-wrap;">: </span>
    - Gen0: ngắn hạn, được dọn dẹp thường xuyên và rất nhanh
    - Gen1, Gen2: trung hạn và dài hạn, dữ liệu không bị dọn dẹp ở Gen0 sẽ được chuyển lên Gen1 và Gen2. Những tầng này ít bị dọn dẹp hơn. Khi dọn dẹp sẽ tốn thời gian hơn.
- ****LOH (Large Object Heap)****<span style="white-space:pre-wrap;">: </span>
    - <span style="white-space:pre-wrap;">Dữ liệu ≥ ~85KB cấp phát ở LOH; </span>
    - <span style="white-space:pre-wrap;">Dữ liệu này thường </span>****không nén****<span style="white-space:pre-wrap;"> mỗi lần GC. Được sắp xếp lại mỗi lần dọn dẹp.</span>
    - Có thể gây phân mảnh
- ****Tạm dừng (STW)****: Để đảm bảo dọn dẹp hiệu quả GC sẽ yêu cầu chương trình tạm dừng để dọn dẹp.
- ****Thời điểm kích hoạt****<span style="white-space:pre-wrap;">: </span>
    - Khi thiếu bộ nhớ để cấp phát, áp lực bộ nhớ cao.
    - <span style="white-space:pre-wrap;">Khi gọi </span>`<span class="editor-theme-code">GC.Collect()</span>`<span style="white-space:pre-wrap;"> (không khuyến khích).</span>

#### <span style="white-space:pre-wrap;">Destructor &amp; </span>`<span class="editor-theme-code">IDisposable</span>`

- ****destructor**** (`<span class="editor-theme-code">~Type()</span>`<span style="white-space:pre-wrap;">): chạy </span>****không xác định thời điểm****<span style="white-space:pre-wrap;"> trên thread GC; chỉ dùng khi giữ </span>****tài nguyên unmanaged****.
- **`<strong class="editor-theme-bold editor-theme-code">IDisposable</strong>`**/**`<strong class="editor-theme-bold editor-theme-code">using</strong>`**<span style="white-space:pre-wrap;">: giải phóng tài nguyên </span>****đúng lúc****<span style="white-space:pre-wrap;"> (socket, file, handle…). Với unmanaged, dùng pattern </span>`<span class="editor-theme-code">Dispose</span>`<span style="white-space:pre-wrap;"> + </span>`<span class="editor-theme-code">SafeHandle</span>`.
- <span style="white-space:pre-wrap;">Quy tắc: </span>****Ưu tiên** `<strong class="editor-theme-bold editor-theme-code">Dispose</strong>`**; chỉ dùng destructor như “lưới an toàn”.

#### Những hiểu lầm thường gặp

- <span style="white-space:pre-wrap;">“Dùng </span>`<span class="editor-theme-code">GC.Collect()</span>`<span style="white-space:pre-wrap;"> là tối ưu” → </span>****Sai****<span style="white-space:pre-wrap;">: thường làm </span>****tệ hơn****<span style="white-space:pre-wrap;"> vì tăng STW.</span>
- <span style="white-space:pre-wrap;">“Dùng List/Dictionary để tránh phân mảnh” → </span>****Không chính xác****<span style="white-space:pre-wrap;">: GC mới xử lý phân mảnh; vấn đề lớn ở </span>****LOH****<span style="white-space:pre-wrap;"> và </span>****pinning****.
- <span style="white-space:pre-wrap;">“GC luôn chậm” → </span>****Phụ thuộc mẫu cấp phát****<span style="white-space:pre-wrap;">; tối ưu </span>****mẫu cấp phát****<span style="white-space:pre-wrap;"> thường hiệu quả hơn “tắt/bắt” GC.</span>

#### Best practices

- ****Giảm cấp phát****<span style="white-space:pre-wrap;">: tái sử dụng buffer; dùng </span>`<span class="editor-theme-code">ArrayPool<T></span>`<span style="white-space:pre-wrap;">, </span>`<span class="editor-theme-code">StringBuilder</span>`, cache hợp lý.
- ****Tránh boxing****<span style="white-space:pre-wrap;"> (struct → object), tránh LINQ tạo rác trong hot path.</span>
- ****Chú ý vòng đời tham chiếu****<span style="white-space:pre-wrap;">: đừng giữ tham chiếu lâu “vô tình” (static cache, event không hủy đăng ký) → đối tượng lên </span>****Gen2****.
- ****LOH****<span style="white-space:pre-wrap;">: hạn chế tạo nhiều mảng lớn; chia nhỏ/thuê từ </span>`<span class="editor-theme-code">ArrayPool<T></span>`.
- ****Pinning****<span style="white-space:pre-wrap;"> (</span>`<span class="editor-theme-code">fixed</span>`<span style="white-space:pre-wrap;">, </span>`<span class="editor-theme-code">GCHandleType.Pinned</span>`): dùng ít – pin lâu gây phân mảnh.
- ****API hiện đại****<span style="white-space:pre-wrap;">: </span>`<span class="editor-theme-code">Span<T></span>`<span style="white-space:pre-wrap;">, </span>`<span class="editor-theme-code">Memory<T></span>`<span style="white-space:pre-wrap;">, </span>`<span class="editor-theme-code">ReadOnlySpan<T></span>`<span style="white-space:pre-wrap;"> cho xử lý dữ liệu không cấp phát.</span>
- ****Thiết lập GC****:
    - ****Server GC****<span style="white-space:pre-wrap;"> (dịch vụ/đa nhân nặng) vs </span>****Workstation GC****<span style="white-space:pre-wrap;"> (ứng dụng desktop).</span>
    - `<span class="editor-theme-code">GCLatencyMode.LowLatency</span>`/`<span class="editor-theme-code">TryStartNoGCRegion</span>`<span style="white-space:pre-wrap;"> chỉ dùng ngắn hạn, có kiểm soát.</span>

#### Với Unity

- ****Incremental GC****<span style="white-space:pre-wrap;"> (Unity 2019.3+): giảm thời gian dừng bằng cách chia nhỏ công việc GC. Bật trong </span>****Project Settings &gt; Player &gt; Garbage Collector****.
- ****Tránh cấp phát mỗi frame****:
    - Không tạo string/`<span class="editor-theme-code">new</span>`<span style="white-space:pre-wrap;"> trong </span>`<span class="editor-theme-code">Update()</span>`<span style="white-space:pre-wrap;">; tránh LINQ/closure/boxing trong </span>`<span class="editor-theme-code">Update()</span>`.
    - <span style="white-space:pre-wrap;">Dùng </span>****object pooling****<span style="white-space:pre-wrap;"> cho bullets, VFX, particle, v.v.</span>
    - <span style="white-space:pre-wrap;">Ưu tiên </span>****struct****/Burst/DOTS cho luồng hiệu năng cao.
- ****Profiler****<span style="white-space:pre-wrap;">: theo dõi </span>`<span class="editor-theme-code">GC.Alloc</span>`<span style="white-space:pre-wrap;"> và spikes; kiểm tra callsite gây rác.</span>
- ****Addressables/Assets****: giải phóng đúng cách (`<span class="editor-theme-code">Release</span>`/`<span class="editor-theme-code">UnloadUnusedAssets</span>`) để giảm áp lực heap.

#### Checklist tối ưu GC

- <span style="white-space:pre-wrap;"> Không gọi </span>`<span class="editor-theme-code">GC.Collect()</span>`<span style="white-space:pre-wrap;"> trừ khi thật cần.</span>
- <span style="white-space:pre-wrap;"> Dọn </span>****event handlers****<span style="white-space:pre-wrap;"> (unsubscribe) để tránh giữ tham chiếu lâu.</span>
- <span style="white-space:pre-wrap;"> Dùng </span>`<span class="editor-theme-code">using</span>`/`<span class="editor-theme-code">Dispose()</span>`<span style="white-space:pre-wrap;"> cho tài nguyên ngoài managed.</span>
- <span style="white-space:pre-wrap;"> Pool hóa bộ nhớ &amp; đối tượng “ngắn hạn nóng”.</span>
- <span style="white-space:pre-wrap;"> Tránh cấp phát trong </span>`<span class="editor-theme-code">Update()</span>`<span style="white-space:pre-wrap;">/hot path; kiểm tra bằng </span>****Profiler****.
- <span style="white-space:pre-wrap;"> Cẩn trọng với </span>****LOH****<span style="white-space:pre-wrap;"> &amp; </span>****pinning****<span style="white-space:pre-wrap;">; ưu tiên chia nhỏ hoặc </span>`<span class="editor-theme-code">ArrayPool<T></span>`.
- <span style="white-space:pre-wrap;"> Với Unity: bật </span>****Incremental GC****<span style="white-space:pre-wrap;"> khi phù hợp, tránh tạo rác frame-by-frame.</span>

<p class="callout danger">**Tối ưu GC = tối ưu* ****mẫu cấp phát**** *+ quản* ****vòng đời tham chiếu*****, không phải “gọi GC nhiều hơn”.</p>