So sánh ref và out là gì?
Trong C#, ref và out là hai từ khóa được sử dụng để truyền tham chiếu vào phương thức hoặc hàm. Tuy chúng đều cho phép thay đổi giá trị của biến bên ngoài phạm vi của hàm, nhưng chúng có những điểm khác biệt cụ thể:
-
ref được sử dụng để truyền tham chiếu cho một biến đã được khởi tạo. Giá trị của biến truyền vào phương thức có thể được thay đổi bởi phương thức đó.
-
out cũng được sử dụng để truyền tham chiếu cho một biến, nhưng không cần phải khởi tạo trước khi truyền vào phương thức.
Ví dụ:
using System;
class Program
{
static void Main()
{
int x = 10;
int y;
// Sử dụng ref
Add(ref x);
Console.WriteLine($"Sau khi sử dụng ref: {x}"); // Output: 15
// Sử dụng out
Multiply(5, 2, out y);
Console.WriteLine($"Sau khi sử dụng out: {y}"); // Output: 10
}
static void Add(ref int num)
{
num += 5;
}
static void Multiply(int a, int b, out int result)
{
result = a * b;
}
}
Sự khác nhau giữa overloading và overriding là gì?
Overloading (Nạp chồng phương thức):
-
Overloading là quá trình khi một lớp có nhiều phương thức cùng tên nhưng có danh sách tham số khác nhau.
-
Khi gọi một phương thức, trình biên dịch sẽ xác định phương thức cụ thể dựa trên số lượng và loại đối số được truyền.
-
Overloading không liên quan đến kế thừa và có thể xảy ra trong cùng một lớp hoặc giữa các lớp khác nhau.
Overriding (Ghi đè phương thức):
-
Overriding là quá trình khi một lớp con cung cấp một triển khai mới cho một phương thức đã được định nghĩa trong lớp cha.
-
Điều này cho phép lớp con thay đổi hoặc mở rộng hành vi của phương thức từ lớp cha.
-
Để ghi đè một phương thức, phương thức trong lớp con phải có cùng tên, kiểu trả về và danh sách tham số với phương thức trong lớp cha và được đánh dấu bằng từ khóa override
.
Có sự khác biệt giữa throw và throw ex không?
throw:
- Khi bạn sử dụng
throw
mà không kèm theo một biểu thức nào sau nó, ngoại lệ hiện tại sẽ được ném lại với cùng một ngữ cảnh mà nó đã được ném.
- Điều này có nghĩa là cả ngữ cảnh của ngoại lệ, bao gồm thông tin về dòng lệnh, dòng stack trace, và thông tin debug, sẽ được giữ nguyên.
throw ex:
- Khi bạn sử dụng
throw ex
, bạn đang ném lại ngoại lệ mới, và ngoại lệ gốc (ngoại lệ đã được ném trước đó) sẽ bị mất đi, và một ngoại lệ mới sẽ được tạo ra.
- Điều này dẫn đến mất mát thông tin ngữ cảnh của ngoại lệ gốc, bao gồm thông tin về stack trace, dẫn đến việc gặp khó khăn trong việc xác định lý do gốc của ngoại lệ.
Sự khác biệt giữa toán tử == và phương thức Equals() trong C # là gì?
Toán tử ==:
-
Toán tử ==
được sử dụng để so sánh giữa hai đối tượng và trả về true nếu chúng tham chiếu đến cùng một đối tượng trong bộ nhớ.
-
Mặc định, toán tử ==
sẽ so sánh tham chiếu đến đối tượng, tức là nếu hai biến đều trỏ đến cùng một đối tượng trong bộ nhớ, kết quả sẽ là true.
-
Tuy nhiên, toán tử ==
có thể được ghi đè trong các lớp tùy chỉnh để thực hiện so sánh theo một cách khác, như so sánh dựa trên các thuộc tính hoặc trạng thái của đối tượng.
Phương thức Equals():
-
Phương thức Equals()
được kế thừa từ lớp Object
và được sử dụng để so sánh giữa hai đối tượng để xác định xem chúng có "bằng nhau" hay không.
-
Mặc định, phương thức Equals()
thực hiện so sánh tham chiếu giống như toán tử ==
.
-
Tuy nhiên, phương thức Equals()
cũng có thể được ghi đè để thực hiện so sánh dựa trên logic tùy chỉnh, giúp xác định xem hai đối tượng có cùng một giá trị hay không, không chỉ là cùng một tham chiếu.
Virtual Method trong C # là gì?
Một phương thức được đánh dấu bằng từ khóa virtual
là một phương thức ảo (virtual method). Điều này có nghĩa là phương thức đó có thể được ghi đè (override) trong các lớp con (derived classes).
using System;
// Lớp cha
class Animal
{
// Phương thức ảo
public virtual void MakeSound()
{
Console.WriteLine("Animal makes a sound");
}
}
// Lớp con kế thừa từ lớp cha
class Dog : Animal
{
// Ghi đè phương thức ảo
public override void MakeSound()
{
Console.WriteLine("Dog barks");
}
}
class Program
{
static void Main()
{
Animal animal = new Animal();
animal.MakeSound(); // Kết quả: "Animal makes a sound"
Dog dog = new Dog();
dog.MakeSound(); // Kết quả: "Dog barks"
}
}
Công dụng của using trong C# là gì?
Dùng để giải phòng tài nguyên. Khi kết thúc sử dụng using tài nguyên sẽ được giải phóng bằng cách tự động gọi Dispose.
Điều này giúp tránh tình trạng rò rỉ tài nguyên và giảm bớt tác động tiêu cực lên hiệu suất hệ thống.
using (var connection = new SqlConnection(connectionString))
{
// Sử dụng kết nối cơ sở dữ liệu
connection.Open();
// Thực hiện các thao tác với cơ sở dữ liệu
// Khi kết thúc, kết nối sẽ tự động được giải phóng
}
Anonymous trong C# là gì?
Anonymous là một khái niệm được sử dụng để tạo ra các đối tượng không có tên hoặc không được khai báo một cách rõ ràng.
Các đối tượng Anonymous được tạo ra bằng cách sử dụng từ khóa new.
var person = new { Name = "John", Age = 30 };
Console.WriteLine($"Name: {person.Name}, Age: {person.Age}");
Sự khác biệt giữa constant và readonly là gì?
Const là hằng số được khởi tạo trong quá trình biên dịch và không thể thay đổi được.
Readonly là biến chỉ để đọc và được khởi tạo trong quá trình runtime. Readonly chỉ có thể gán lại giá trị trong hàm khởi tạo (Constructor)
Sự khác biệt giữa biến kiểu dynamic và biến kiểu object là gì?
dynamic:
-
Biến kiểu dynamic
cho phép bạn làm việc với các đối tượng mà kiểu của chúng được xác định tại thời điểm chạy (runtime).
-
Phép gán và các phép toán được thực hiện theo ngữ cảnh của đối tượng ở thời điểm chạy, không phải theo kiểu dữ liệu được xác định tĩnh trước đó.
-
dynamic
cho phép gọi các phương thức, truy cập các thuộc tính và thực hiện các phép toán mà không cần kiểm tra kiểu dữ liệu tĩnh.
-
Mặc dù dynamic
cung cấp tính linh hoạt cao, nhưng nó có thể làm giảm hiệu suất và làm giảm sự an toàn trong mã nguồn.
object:
-
Biến kiểu object
là biến của một lớp cơ sở trong C#, tức là System.Object
.
-
Tất cả các kiểu dữ liệu trong C# đều là dẫn xuất của object
, vì vậy biến kiểu object
có thể chứa bất kỳ giá trị nào, bao gồm các kiểu dữ liệu tùy chỉnh.
-
Khi sử dụng biến kiểu object
, bạn cần phải ép kiểu (cast) khi muốn truy cập các thành viên cụ thể của đối tượng.
-
object
thường được sử dụng trong các tình huống mà bạn cần đối tượng có thể chứa bất kỳ giá trị nào và không cần quan tâm đến kiểu dữ liệu cụ thể.
AddScoped, AddSingleton, và AddTransient là gì?
AddScoped, AddSingleton, và AddTransient là các phương thức mở rộng của interface IServiceCollection được sử dụng để đăng ký các dịch vụ trong container DI (Dependency Injection).
AddScoped: Mỗi khi có một request mới được tạo ra, một instance mới của dịch vụ sẽ được tạo và sử dụng trong phạm vi của request đó.
AddSingleton: Chỉ có một instance duy nhất của dịch vụ được tạo ra và sử dụng trong toàn bộ vòng đời của ứng dụng.
AddTransient: Mỗi khi được yêu cầu, một instance mới của dịch vụ sẽ được tạo ra.
#Instance có thể được hiểu như 1 object khi đc khởi tạo: Car myCar = new Car();
Khi nào dùng float và khi nào dùng double?
Trong trường hợp này tùy thuộc vào ngữ cảnh và độ chính xác đề ra.
double hoặc decimal thường được dùng cho đơn vị tiền tệ.
float có thể nhanh hơn double trong 1 số hệ thống
Sự khác nhau giữa Cookie và Session là gì?
Cookie và Session đều dùng để lưu trữ thông tin và trạng thái của người dùng.
Cookie Lưu trữ phía người dùng (Browser) còn Session sẽ lưu ở phía Server và được xác định thông qua Session ID ở phía người dùng (Thương được lưu ở Cookie)
Cookie có thời gian sử dụng cụ thể có thể là tạm thời hoặc cố định. Sesssion thời gian sẽ được quản lý bởi Server.
Bảo mật thì Session sẽ bảo mật hơn Cookie do được lưu trên Server .
So sánh sự khác nhau giữa IQueryale và IEnumable trong C#?
IQueryable:
IQueryable
là một giao diện trong LINQ (Language Integrated Query) của .NET Framework, được sử dụng để thực hiện các truy vấn dữ liệu trên các nguồn dữ liệu khác nhau như cơ sở dữ liệu, tệp tin XML, hay bất kỳ nguồn dữ liệu nào khác có thể truy cập được.
IQueryable
là một giao diện dựa trên IQueryable, cho phép thực hiện các truy vấn LINQ trên các nguồn dữ liệu mà hỗ trợ LINQ to SQL, LINQ to Entities, LINQ to XML, v.v.
IQueryable
tạo ra các câu truy vấn được lập kế hoạch (deferred execution), có nghĩa là các truy vấn không được thực thi ngay lập tức mà được trì hoãn cho đến khi dữ liệu được yêu cầu.
IQueryable
thường được sử dụng trong các kịch bản khi cần thực hiện truy vấn dữ liệu phức tạp, hoặc khi cần tương tác với các nguồn dữ liệu từ xa như cơ sở dữ liệu.
IEnumerable:
IEnumerable
là một giao diện được sử dụng để lặp qua các tập hợp dữ liệu trong C#, cho phép truy cập tuần tự từng phần tử của tập hợp.
IEnumerable
chỉ cung cấp phương thức GetEnumerator() để lặp qua các phần tử của tập hợp, và không hỗ trợ truy vấn dữ liệu phức tạp như IQueryable.
IEnumerable
không trì hoãn việc thực thi, nghĩa là các phần tử của tập hợp sẽ được lấy ra và xử lý ngay lập tức khi cần thiết.
IEnumerable
thường được sử dụng trong các kịch bản đơn giản như lặp qua một mảng, danh sách, hoặc bất kỳ cấu trúc dữ liệu nào khác.
Garbage collector là gì?
Garbage collector (GC) là một phần của môi trường thực thi của một ngôn ngữ lập trình có quản lý bộ nhớ tự động. Trong môi trường này, GC đảm nhận trách nhiệm thu gom và giải phóng bộ nhớ mà các đối tượng không còn sử dụng nữa, giúp cho việc quản lý bộ nhớ trở nên dễ dàng hơn cho lập trình viên.
Cách hoạt động của Garbage Collector:
- Phát hiện đối tượng không sử dụng: GC quét qua toàn bộ bộ nhớ được cấp phát và xác định những đối tượng nào không còn được tham chiếu đến từ bất kỳ đâu trong chương trình.
- Xóa đối tượng không sử dụng: Sau khi xác định các đối tượng không còn sử dụng, GC sẽ giải phóng bộ nhớ được cấp phát cho các đối tượng đó, giúp giảm bớt sự chiếm dụng bộ nhớ và tránh lỗi rò rỉ bộ nhớ.
- Chạy trong nền: GC thường chạy trong nền của chương trình, tức là nó sẽ tự động chạy trong một quá trình phụ mà không làm gián đoạn việc thực thi chính của chương trình.
Làm cách nào để phân biệt ASP.NET Core với .NET Core?
.NET Core là nền tảng chung cho việc phát triển ứng dụng trên nhiều nền tảng, trong khi ASP.NET Core là một framework cụ thể được sử dụng để phát triển ứng dụng web trên nền tảng .NET Core.
Middleware trong .NET core là gì?
Middleware trong .NET Core là một phần quan trọng của pipeline xử lý HTTP. Nó là các thành phần trung gian được thêm vào pipeline xử lý yêu cầu và phản hồi trong ứng dụng web ASP.NET Core. Middleware được sử dụng để thực hiện các công việc như xác thực, ghi log, nén dữ liệu, định tuyến, và nhiều công việc khác.
Các điểm chính về Middleware:
- Chuỗi Middleware: Middleware được sắp xếp theo một chuỗi, và mỗi middleware trong chuỗi có thể thực hiện một loạt các công việc xử lý yêu cầu và phản hồi.
- Xử lý yêu cầu và phản hồi: Mỗi middleware có thể xử lý yêu cầu trước khi chuyển nó đến middleware tiếp theo trong chuỗi, và cũng có thể xử lý phản hồi sau khi nó đã được xử lý bởi middleware trước đó.
- Thực hiện logic xử lý: Middleware có thể thực hiện một loạt các công việc như kiểm tra xác thực, ghi log, định tuyến, xử lý ngoại lệ, nén dữ liệu, và nhiều công việc khác để xử lý yêu cầu và phản hồi.
- Dễ dàng mở rộng và tái sử dụng: Middleware là một phần của cấu trúc linh hoạt trong ASP.NET Core, cho phép bạn dễ dàng thêm, xóa, và tái sử dụng chúng theo nhu cầu của ứng dụng.
Ví dụ về một số middleware phổ biến trong ASP.NET Core bao gồm Middleware xác thực (Authentication Middleware), Middleware ghi log (Logging Middleware), Middleware định tuyến (Routing Middleware), Middleware xử lý ngoại lệ (Exception Handling Middleware), Middleware nén dữ liệu (Compression Middleware), và nhiều middleware khác.
MSBuild trong .NET là gì?
MSBuild (Microsoft Build Engine) là một công cụ được phát triển bởi Microsoft để tự động hóa quá trình xây dựng (build) và triển khai (deploy) ứng dụng và dự án phần mềm trong môi trường phát triển phần mềm. MSBuild là một phần quan trọng của Visual Studio và .NET Framework.
Các tính năng chính của MSBuild bao gồm:
- Tự động hóa quá trình build: MSBuild cho phép tự động hóa việc biên dịch mã nguồn, tạo tập tin nhị phân và thực hiện các tác vụ khác như gộp mã, sao chép tệp tin, v.v.
- File dự án XML: MSBuild sử dụng các file dự án XML để mô tả cấu trúc của dự án và các công việc cần thực hiện trong quá trình build. Các file dự án này có thể được tạo ra tự động bằng cách sử dụng Visual Studio hoặc viết bằng tay.
- Tích hợp với Visual Studio: MSBuild là công cụ mặc định cho quá trình build trong Visual Studio. Visual Studio sử dụng MSBuild để thực hiện quá trình build của các dự án và các tập tin mã nguồn.
- Tích hợp với .NET Framework: MSBuild là một phần quan trọng của .NET Framework, giúp cho việc xây dựng ứng dụng .NET trở nên dễ dàng và linh hoạt hơn.
- Cấu hình linh hoạt: MSBuild cung cấp cơ chế linh hoạt để cấu hình và tùy chỉnh quá trình build theo nhu cầu cụ thể của dự án hoặc ứng dụng.
Claims trong .NET là gì?
Claims là các phát biểu về người dùng hoặc yêu cầu, chứa thông tin như tên, quyền truy cập và các thông tin khác.
Các Claims được sử dụng trong hệ thống xác thực và phân quyền dựa trên Token, như JSON Web Token (JWT) hoặc Security Assertion Markup Language (SAML), để xác định danh tính và quyền hạn của người dùng.
Claims là 1 cặp giá trị key-value
Toán tử "?." và "??" trong C#?
Toán tử ?. trong C# được gọi là "toán tử điều kiện Null" hoặc "toán tử null-conditional". Nó được sử dụng để truy cập thành viên của một đối tượng mà có thể là null mà không gây ra lỗi null reference.
public class Car
{
public int Number {get;set;}
}
Car myCar = null;
myCar?.Number;
?? được sử dụng để kiểm tra và trả về giá trị của biểu thức bên trái nếu nó không null, nếu không sẽ trả về giá trị của biểu thức bên phải.
int? a = null;
int b = a ?? 10;
Console.WriteLine(b); // Output: 10
int? c = 20;
int d = c ?? 10;
Console.WriteLine(d); // Output: 20
Sự khác biệt giữa Virtual method và Abstract method là gì?
Virtual Method:
- Virtual method là một phương thức trong một lớp cơ sở (base class) được đánh dấu bằng từ khóa
virtual
.
- Phương thức virtual có thể được ghi đè (override) trong các lớp kế thừa (derived classes).
- Khi một phương thức virtual được gọi từ một đối tượng của lớp con, phương thức được gọi là phương thức của lớp con, không phải của lớp cơ sở.
- Đối tượng của lớp con có thể chứa một triển khai mới của phương thức virtual, nếu nó được ghi đè trong lớp con.
Abstract Method:
- Abstract method là một phương thức trong một lớp cơ sở (base class) được đánh dấu bằng từ khóa
abstract
.
- Phương thức abstract không có triển khai (implementation) trong lớp cơ sở và cần phải được triển khai trong các lớp kế thừa (derived classes).
- Lớp chứa phương thức abstract cũng phải được đánh dấu là
abstract
, và không thể tạo ra một đối tượng từ lớp đó.
- Mỗi lớp kế thừa từ lớp chứa phương thức abstract phải cung cấp một triển khai (implementation) cho mọi phương thức abstract của lớp cơ sở.
Tại sao cần sử dụng IDisposable interface?
Interface IDisposable được sử dụng để giải phóng tài nguyên không quản lý và đảm bảo việc dọn dẹp tài nguyên khi không còn cần thiết.
Parallel trong C# là gì?
Parallel là một tập hợp các công cụ cho phép thực hiện các tác vụ đồng thời trên nhiều luồng một cách dễ dàng.
Parallel.For(0, 10, i =>
{
Console.WriteLine("Task " + i);
});
Thứ tự các sự kiện diễn ra trong vòng đời của trang là gì?
- Page_PreInit
- Page_Init
- Page_InitComplete
- Page_PreLoad
- Page_Load
- Page_LoadComplete
- Page_PreRender
- Render
Sự khác nhau giữa .NET Core và .NET Framework.
Đa Nền Tảng (Cross-Platform):
.NET Core: .NET Core được thiết kế để chạy trên nhiều hệ điều hành, bao gồm Windows, macOS và Linux. Điều này cho phép phát triển ứng dụng đa nền tảng.
.NET Framework: .NET Framework chỉ chạy trên hệ điều hành Windows.
Open Source:
.NET Core: .NET Core là mã nguồn mở (open source), cho phép cộng đồng phát triển và đóng góp vào mã nguồn của nó trên GitHub.
.NET Framework: .NET Framework không phải là mã nguồn mở và không có cơ chế tham gia của cộng đồng.
Size và Hiệu Suất:
.NET Core: .NET Core có kích thước nhẹ và hiệu suất tốt hơn so với .NET Framework. Điều này làm cho .NET Core phù hợp cho việc phát triển ứng dụng web, microservices và ứng dụng đa nền tảng.
.NET Framework: .NET Framework có kích thước lớn hơn và chủ yếu được sử dụng cho các ứng dụng Windows truyền thống.
Hỗ trợ API và Tính Năng:
.NET Core: .NET Core hỗ trợ một phần của .NET Framework và cung cấp một số tính năng mới như Dependency Injection (DI) tích hợp sẵn và Configuration.
.NET Framework: .NET Framework có sẵn nhiều API và tính năng mạnh mẽ cho việc phát triển ứng dụng Windows, bao gồm Windows Presentation Foundation (WPF), Windows Communication Foundation (WCF), và Windows Forms.
Cập Nhật và Hỗ Trợ:
.NET Core: .NET Core có chu kỳ cập nhật nhanh hơn và nhận được sự hỗ trợ liên tục từ Microsoft.
.NET Framework: .NET Framework thường nhận được các cập nhật lớn trong các phiên bản mới của Windows và không nhận được sự hỗ trợ liên tục như .NET Core.
Làm thế nào để một lớp không bị ghi đè trong C#?
Để ngăn chặn một lớp được ghi đè (subclass) trong C#, bạn có thể sử dụng từ khóa sealed
.
Khi một lớp được đánh dấu là sealed
, nó không thể được kế thừa (subclassed), nghĩa là không thể tạo ra lớp con từ nó.
public sealed class MyClass
{
}
Reflection trong C#.Net là gì?
Reflection trong C# là khả năng của một chương trình để xem, kiểm tra và thay đổi cấu trúc và hành vi của chính nó trong thời gian chạy.
using System;
using System.Reflection;
class Program
{
static void Main()
{
Type type = typeof(string);
Console.WriteLine(type.FullName); // In ra: System.String
}
}
Phạm vi sử dụng của public, private, protected, internal và public internal là gì?
public:
Các thành viên được đánh dấu là public
có thể truy cập từ mọi nơi trong cùng hoặc khác namespace.
Các thành viên public
có thể được truy cập từ bên ngoài lớp.
private:
Các thành viên được đánh dấu là private
chỉ có thể truy cập từ bên trong cùng một lớp.
Các thành viên private
không thể được truy cập từ bên ngoài lớp.
protected:
Các thành viên được đánh dấu là protected
có thể truy cập từ bên trong cùng một lớp và từ các lớp kế thừa.
Các thành viên protected
không thể truy cập từ bên ngoài lớp hoặc các lớp không liên quan.
internal:
Các thành viên được đánh dấu là internal
có thể truy cập từ bên trong cùng một assembly (dll hoặc exe), nhưng không thể truy cập từ các assembly bên ngoài.
internal
là phạm vi mặc định cho các thành viên nếu không có phạm vi được xác định rõ.
public internal:
Các thành viên được đánh dấu là public internal
có thể truy cập từ bên trong cùng một assembly và từ bên ngoài assembly đó.
public internal
thường được sử dụng khi bạn muốn chia sẻ một phần của lớp hoặc thư viện với các assembly bên ngoài mà không muốn tiết lộ tất cả các thành viên public
.
Extension method là gì?
Extension method trong C# là một cách để thêm các phương thức mới vào một lớp đã tồn tại mà không cần phải sửa đổi mã nguồn của lớp đó.