Câu hỏi phỏng vấn C#/.Net

Hãy xem các câu hỏi chúng tôi đã tổng hợp và cùng ôn luyện lại nhé!

C# là một ngôn ngữ lập trình mạnh mẽ và linh hoạt, được phát triển bởi Microsoft. Nó là một ngôn ngữ lập trình hướng đối tượng và cung cấp nền tảng cho việc phát triển ứng dụng trực quan, an toàn và hiệu suất cao trên nhiều nền tảng khác nhau.

.NET là một framework phát triển ứng dụng, cung cấp một nền tảng chung để xây dựng, triển khai và chạy các ứng dụng. Nó được phát triển bởi Microsoft và hỗ trợ nhiều ngôn ngữ lập trình như C#, VB.NET, F# và nhiều ngôn ngữ khác.

.NET cung cấp một tập hợp các thư viện lớn và các công cụ phát triển để giúp xây dựng các ứng dụng đa dạng, bao gồm các ứng dụng Windows, ứng dụng web, ứng dụng di động và cả phần mềm dịch vụ. Nó hỗ trợ các tính năng như quản lý bộ nhớ tự động, thu gom rác, tính năng đa luồng và tích hợp dịch vụ web.

C# và .NET là hai công nghệ phổ biến trong việc phát triển phần mềm và được sử dụng rộng rãi trên nhiều ứng dụng và lĩnh vực công nghiệp khác nhau.

Trong C#/.Net, var và dynamic là hai từ khóa khác nhau để khai báo biến với tính năng khác nhau.

Var được sử dụng để khai báo biến mà không cần xác định kiểu dữ liệu một cách rõ ràng. Dữ liệu của biến var được xác định dựa trên giá trị mà biến nhận khi khởi tạo. Kiểu dữ liệu cụ thể của biến var được xác định tại thời điểm biên dịch và không thể thay đổi sau đó. Sử dụng var cho biến giúp giảm bớt cú pháp và tăng tính linh hoạt.

Ví dụ:

var foo = "Hello";
var bar = 10;

foo = 10; // Lỗi biên dịch vì foo đã được khai báo là kiểu dữ liệu string

Dynamic được sử dụng để khai báo biến có kiểu dữ liệu động, có thể được xác định và thay đổi tại thời điểm chạy. Biến dynamic cho phép gán giá trị bất kỳ kiểu dữ liệu vào biến và thực hiện các phép tính, phương thức trên biến mà không cần kiểm tra kiểu tĩnh. Dynamic thường được sử dụng trong các tình huống cần tương tác với dữ liệu không xác định trước hoặc với các ngôn ngữ khác.

Ví dụ:

dynamic foo = "Hello";
dynamic bar = 10;

foo = 10; // Không có lỗi biên dịch vì foo là biến dynamic có kiểu dữ liệu động

Trong C#/.Net, để khai báo một biến không thay đổi (constant variable), bạn có thể sử dụng từ khóa "const" hoặc "readonly".

  1. Sử dụng từ khóa "const":

    const int pi = 3.14;

    Trên đây là một ví dụ về khai báo một biến số nguyên không thay đổi và gán giá trị cho nó là 3.14 bằng cách sử dụng từ khóa "const". Lưu ý rằng giá trị của biến const phải được gán ngay lập tức và không thể thay đổi sau đó.

  2. Sử dụng từ khóa "readonly":

    readonly string message = "Hello World";

    Trên đây là một ví dụ về khai báo một biến chuỗi không thay đổi và gán giá trị cho nó là "Hello World" bằng cách sử dụng từ khóa "readonly". Khác với const, giá trị của biến readonly có thể được gán trong constructor hoặc bên ngoài các phương thức tĩnh, và sau đó không thể thay đổi giá trị của nó.

Lưu ý rằng biến không thay đổi chỉ có thể được sử dụng trong phạm vi nơi nó được khai báo.

Trong C#/.Net, sự khác biệt giữa abstract class và interface là:

  1. Abstract class (lớp trừu tượng):

    • Có thể chứa cả các phương thức trừu tượng và không trừu tượng.
    • Có thể chứa các biến thành viên và các thuộc tính.
    • Có thể triển khai các phương thức mặc định.
    • Một lớp con chỉ có thể kế thừa từ một lớp trừu tượng duy nhất.
  2. Interface (giao diện):

    • Chỉ chứa phương thức trừu tượng, không chứa phương thức được triển khai.
    • Không có biến thành viên và thuộc tính.
    • Một lớp có thể triển khai nhiều giao diện cùng một lúc.
    • Một giao diện có thể kế thừa từ nhiều giao diện khác.

Có một số lý do để sử dụng try-catch trong C#:

  1. Xử lý ngoại lệ: Try-catch được sử dụng để bắt và xử lý các ngoại lệ (exception) trong quá trình thực thi chương trình. Ngoại lệ có thể xảy ra do các lỗi logic, lỗi hệ thống, hoặc lỗi cú pháp. Bằng cách sử dụng try-catch, chúng ta có thể chắt lọc ngoại lệ, thông báo cho người dùng và thực hiện các hành động phù hợp để xử lý ngoại lệ.

  2. Bảo vệ chương trình: Những đoạn mã có thể gây ra ngoại lệ không mong muốn có thể được bao bọc trong một khối try-catch để đảm bảo không gây dừng chương trình. Nếu một ngoại lệ xảy ra trong khối try, nó sẽ được bắt bởi catch và chương trình sẽ tiếp tục thực thi từ khối catch mà không bị dừng.

  3. Gỡ lỗi: Sử dụng try-catch cũng giúp chúng ta dễ dàng gỡ lỗi và tìm ra nguyên nhân của lỗi. Khi một ngoại lệ xảy ra, thông tin chi tiết về ngoại lệ (bao gồm thông tin vị trí, loại ngoại lệ và thông điệp lỗi) có thể được ghi log hoặc hiển thị để chúng ta có thể kiểm tra và khắc phục lỗi.

  4. Xử lý lỗi ngầm: Một số lỗi có thể xảy ra trong quá trình chạy chương trình mà không được thông báo rõ ràng. Bằng cách sử dụng try-catch, chúng ta có thể bắt lỗi ngầm và xử lý chúng một cách hợp lý.

  5. Tốt cho tương tác người dùng: Một khối try-catch cung cấp một cơ chế để hiển thị thông báo tùy chỉnh cho người dùng khi có lỗi xảy ra. Chúng ta có thể thông báo cho người dùng về lỗi cụ thể và yêu cầu họ thực hiện các hành động cần thiết để khắc phục lỗi.

Tóm lại, sử dụng try-catch trong C# giúp chúng ta xử lý ngoại lệ, bảo vệ chương trình, gỡ lỗi, xử lý lỗi ngầm và tương tác tốt với người dùng. Điều này giúp nâng cao độ tin cậy và tính ổn định của chương trình.

Access Modifier (public, private, protected) trong C# được sử dụng để quản lý quyền truy cập vào các thành phần của một lớp (class) hoặc một thành viên của lớp (biến, phương thức). Các lợi ích của việc sử dụng Access Modifier trong C# là:

  1. Bảo mật dữ liệu: Access Modifier cho phép chỉ định mức độ truy cập vào các thành phần của lớp, từ đó giúp bảo vệ dữ liệu từ sự can thiệp trái phép bên ngoài.

  2. Đảm bảo tính cohesiveness: Access Modifier giúp xác định rõ vai trò và phạm vi sử dụng của từng thành phần trong lớp. Điều này giúp tăng tính rõ ràng và linh hoạt trong thiết kế và quản lý mã nguồn.

  3. Tính tái sử dụng mã nguồn: Access Modifier cho phép chia sẻ mã nguồn và chức năng của một lớp một cách linh hoạt, bằng cách chỉ nắm rõ các thành phần cần được truy cập giao diện công khai (public) và ẩn (private, protected) các chi tiết bên trong.

  4. Nâng cao khả năng bảo trì: Access Modifier giúp quản lý mã nguồn và tài liệu dễ dàng hơn. Với các thành phần được đánh dấu public, các lập trình viên có thể sử dụng và tương tác với chúng một cách rõ ràng và dễ hiểu, trong khi các thành phần được đánh dấu private và protected chỉ được sử dụng và thay đổi bên trong lớp.

Tóm lại, việc sử dụng Access Modifier trong C# là một cách quản lý và tăng tính bảo mật, linh hoạt, và rõ ràng trong lập trình.

Constructor trong C# là một phương thức đặc biệt được sử dụng để khởi tạo đối tượng của một lớp. Nó được sử dụng để cung cấp các giá trị khởi tạo ban đầu cho các thành viên dữ liệu của lớp và thực hiện các tác vụ khác liên quan đến khởi tạo.

Có hai loại constructor:

  1. Constructor mặc định (default constructor): Đây là một constructor không có tham số. Nó được tạo tự động khi một lớp được khai báo và không có constructor nào được định nghĩa. Constructor mặc định được sử dụng để khởi tạo giá trị mặc định cho các thành viên dữ liệu của lớp.

Ví dụ:

class MyClass
{
    public MyClass() // Constructor mặc định
    {
        // Khởi tạo giá trị mặc định cho các thành viên dữ liệu
    }
}
  1. Constructor tùy chỉnh (parameterized constructor): Đây là một constructor có các tham số truyền vào. Nó được sử dụng để khởi tạo đối tượng với các giá trị được chuyển vào từ bên ngoài.

Ví dụ:

class MyClass
{
    public MyClass(int value) // Constructor tùy chỉnh
    {
        // Khởi tạo đối tượng với giá trị được chuyển vào
    }
}

Constructor có thể được overload, tức là khai báo nhiều constructor cùng tên nhưng có số lượng hoặc kiểu dữ liệu tham số khác nhau. Điều này cho phép chúng ta khởi tạo đối tượng một cách linh hoạt với các giá trị khác nhau.

Constructor cũng có thể kết hợp với các từ khóa khác như this (để gọi constructor khác) và base (để gọi constructor của lớp cơ sở).

Constructor không trả về giá trị và không có kiểu trả về, nhưng có thể thực hiện các tác vụ khởi tạo, tính toán, gọi phương thức khác, v.v.

Constructor được gọi khi ta tạo một đối tượng mới bằng từ khoá new.

Trong C#/.Net, bạn có thể sử dụng lớp BigInteger trong không gian tên System.Numerics để xử lý số lớn. Lớp BigInteger cho phép bạn thực hiện các phép tính toán số học cơ bản với các số nguyên rất lớn mà không gặp vấn đề về diện rộng.

Dưới đây là một ví dụ về cách sử dụng lớp BigInteger để xử lý số lớn trong C#:

using System;
using System.Numerics;

class Program
{
    static void Main(string[] args)
    {
        BigInteger num1 = BigInteger.Parse("12345678901234567890");
        BigInteger num2 = BigInteger.Parse("98765432109876543210");

        BigInteger sum = num1 + num2;
        BigInteger difference = num1 - num2;
        BigInteger product = num1 * num2;
        BigInteger quotient = num1 / num2;

        Console.WriteLine("Sum: " + sum);
        Console.WriteLine("Difference: " + difference);
        Console.WriteLine("Product: " + product);
        Console.WriteLine("Quotient: " + quotient);
    }
}

Kết quả:

Sum: 111111111011111111100
Difference: -86419753108641975320
Product: 1219326311370217950030005831728971090
Quotient: 0

Trong ví dụ này, chúng ta sử dụng phương thức Parse của lớp BigInteger để chuyển đổi chuỗi thành giá trị của kiểu dữ liệu BigInteger. Sau đó, chúng ta thực hiện các phép tính toán số học cơ bản và in ra kết quả.

Delegate trong C# là một kiểu dữ liệu đặc biệt, dùng để định nghĩa một biến có thể tham chiếu đến một phương thức hoặc một tập hợp các phương thức. Nó cho phép truyền phương thức như một tham số cho một phương thức khác hoặc lưu trữ trong một biến. Delegate giúp xây dựng các ứng dụng linh hoạt hơn, cho phép ánh xạ các phương thức vào những sự kiện hoặc các công việc được thực hiện sau khi xử lý.

Cú pháp khai báo delegate trong C#:

delegate <kiểu trả về> <tên delegate>(<các tham số>);

Ví dụ, để khai báo một delegate có kiểu trả về là int và không có tham số, ta có thể sử dụng cú pháp sau:

delegate int MyDelegate();

Sau khi một delegate được khai báo, ta có thể tạo một biến delegate và gán cho nó một phương thức thỏa mãn kiểu delegate đó. Ví dụ sau đây minh họa việc sử dụng delegate để truyền phương thức như một tham số:

class Program
{
    delegate void MyDelegate(string message);

    public static void Welcome(string name)
    {
        Console.WriteLine("Welcome, " + name);
    }

    public static void Goodbye(string name)
    {
        Console.WriteLine("Goodbye, " + name);
    }

    public static void Greet(MyDelegate greetDelegate, string name)
    {
        greetDelegate(name);
    }

    static void Main(string[] args)
    {
        MyDelegate myDelegate = Welcome;
        Greet(myDelegate, "John");

        myDelegate = Goodbye;
        Greet(myDelegate, "Kate");
    }
}

Kết quả:

Welcome, John
Goodbye, Kate

Dưới đây là một số nguyên tắc về Clean Code trong C# và .NET:

  1. Đặt tên biến, phương thức và lớp một cách rõ ràng và mô tả chính xác chức năng của chúng.

  2. Giới hạn số lượng tham số đầu vào mà một phương thức có thể nhận. Nếu một phương thức có quá nhiều tham số, hãy xem xét việc tạo ra một lớp hoặc cấu trúc đóng gói các tham số đó.

  3. Sử dụng các kiểu dữ liệu cụ thể và có ý nghĩa. Tránh sử dụng kiểu dữ liệu nguyên thủy (primitive type) khi có thể sử dụng kiểu dữ liệu có sẵn trong .NET Framework.

  4. Hạn chế việc sử dụng các biến toàn cục và biến có thay đổi tình trạng (mutable). Điều này giúp giảm thiểu các vấn đề về đồng bộ và logic phức tạp.

  5. Sắp xếp mã nguồn theo một quy tắc nhất định, ví dụ như sắp xếp theo thứ tự bảng chữ cái, hoặc theo vị trí của các phương thức trong lớp.

  6. Sử dụng những phương thức nhỏ và chỉ thực hiện một nhiệm vụ duy nhất. Điều này giúp giảm bớt sự phức tạp và dễ dàng hiểu mã nguồn hơn.

  7. Sử dụng chính xác các cấu trúc điều khiển như vòng lặp, điều kiện và exception handling. Tránh việc sử dụng lệnh nhảy (goto) và các mẹo không rõ ràng khác.

  8. Viết các đoạn mã có tính tái sử dụng cao. Sử dụng các phương thức, lớp và gói mã để đóng gói các đoạn mã có chức năng tương tự và có thể sử dụng được ở nhiều dự án khác nhau.

  9. Sử dụng các công cụ hỗ trợ phân tích mã nguồn như ReSharper để tìm ra các lỗi tiềm ẩn và cải thiện mã nguồn.

  10. Luôn chú ý đến hiệu suất của mã nguồn. Tránh việc tạo ra những vòng lặp không cần thiết, sử dụng các thuật toán hiệu quả và tốn ít tài nguyên.

Trong ngôn ngữ lập trình C#, class và object là hai khái niệm liên quan nhưng có ý nghĩa khác nhau.

  1. Class:
    • Class là một mô hình để định nghĩa một kiểu dữ liệu mới. Nó định nghĩa các thuộc tính (fields) và phương thức (methods) mà đối tượng thuộc kiểu dữ liệu này có thể thực hiện.
    • Một class được sử dụng để tạo ra các object (đối tượng).
    • Có thể hiểu class là bản thiết kế để tạo ra các object cụ thể a từ class.

Ví dụ:

class Circle
{
    // Thuộc tính
    public double Radius;

    // Phương thức
    public double GetArea()
    {
        return Math.PI * Radius * Radius;
    }
}

// Khởi tạo một object từ class Circle
Circle myCircle = new Circle();
  1. Object:
    • Object là một thực thể cụ thể được tạo ra từ một class thông qua quá trình khởi tạo (instantiated).
    • Một object có thể được xem như một biểu diễn cụ thể của một class, chứa các giá trị của các thuộc tính và có thể thực hiện các phương thức của class.
    • Mỗi object có thể có các giá trị khác nhau cho các thuộc tính của nó.

Ví dụ:

// Khởi tạo một object từ class Circle
Circle myCircle = new Circle();

// Gán giá trị cho thuộc tính Radius của object myCircle
myCircle.Radius = 5;

// Gọi phương thức GetArea() của object myCircle để tính diện tích hình tròn
double area = myCircle.GetArea();

Tóm lại, class định nghĩa một mô hình và object là một thể hiện cụ thể của class đó.

Trong C#/.Net, inheritance (kế thừa) và composition (sở hữu) là hai khái niệm quan trọng được sử dụng để tái sử dụng mã và xây dựng các quan hệ giữa các lớp.

  1. Inheritance (kế thừa):
    • Inheritance cho phép một lớp (lớp con) kế thừa các thuộc tính và phương thức từ một lớp khác (lớp cha).
    • Lớp con có thể sử dụng các thành phần kế thừa từ lớp cha mà không cần viết lại mã.
    • Cú pháp: class SubClass : SuperClass
    • Ví dụ:
class Animal
{
    public void Eat()
    {
        Console.WriteLine("Animal is eating...");
    }
}

class Dog : Animal
{
    public void Bark()
    {
        Console.WriteLine("Dog is barking...");
    }
}

class Program
{
    static void Main(string[] args)
    {
        Dog dog = new Dog();
        dog.Eat(); // Kế thừa từ lớp Animal
        dog.Bark(); // Phương thức của lớp Dog
    }
}
  1. Composition (sở hữu):
    • Composition cho phép một lớp (lớp sở hữu) chứa đựng một hoặc nhiều đối tượng của các lớp khác.
    • Lớp sở hữu có quyền truy cập đến các phương thức và thuộc tính của các đối tượng được sở hữu.
    • Composition thường được sử dụng khi cần xây dựng quan hệ "has-a" giữa các đối tượng.
    • Ví dụ:
class Engine
{
    public void Start()
    {
        Console.WriteLine("Engine is starting...");
    }
}

class Car
{
    private Engine engine; // Sở hữu một đối tượng Engine

    public Car()
    {
        engine = new Engine();
    }

    public void StartCar()
    {
        engine.Start();
    }
}

class Program
{
    static void Main(string[] args)
    {
        Car car = new Car();
        car.StartCar(); // Gọi phương thức Start() của đối tượng Engine
    }
}

Trong ví dụ trên, lớp Car sở hữu một đối tượng của lớp Engine. Khi gọi phương thức StartCar(), nó sẽ gọi phương thức Start() của đối tượng Engine.

Override và overload là hai khái niệm quan trọng trong lập trình C#.

  • Override: Được sử dụng trong việc kế thừa và cho phép lớp con ghi đè (override) lại các phương thức, thuộc tính hoặc sự kiện từ lớp cha. Khi một phương thức trong lớp con có cùng tên, cùng kiểu trả về và cùng danh sách tham số với phương thức trong lớp cha, ta có thể sử dụng từ khóa "override" để thông báo rằng phương thức này đang được ghi đè từ phương thức trong lớp cha. Khi gọi phương thức từ đối tượng của lớp con, phương thức đã được ghi đè sẽ được thực thi.

Ví dụ:

class Animal
{
   public virtual void Sound()
   {
      Console.WriteLine("The animal makes a sound");
   }
}

class Cat : Animal
{
   public override void Sound()
   {
      Console.WriteLine("The cat makes 'Meow' sound");
   }
}

class Program
{
   static void Main(string[] args)
   {
      Animal myAnimal = new Animal();
      myAnimal.Sound(); // Kết quả: The animal makes a sound

      Animal myCat = new Cat();
      myCat.Sound(); // Kết quả: The cat makes 'Meow' sound
   }
}
  • Overload: Được sử dụng khi ta muốn định nghĩa nhiều biến thể của một phương thức với cùng tên nhưng khác nhau về số lượng tham số hoặc kiểu dữ liệu của các tham số. Khi gọi phương thức với cùng tên, trình biên dịch sẽ phân biệt chúng dựa trên số lượng và kiểu dữ liệu của các tham số trong cuộc gọi.

Ví dụ:

class Calculator
{
   public int Add(int a, int b)
   {
      return a + b;
   }

   public int Add(int a, int b, int c)
   {
      return a + b + c;
   }

   public double Add(double a, double b)
   {
      return a + b;
   }
}

class Program
{
   static void Main(string[] args)
   {
      Calculator cal = new Calculator();
      Console.WriteLine(cal.Add(5, 10)); // Kết quả: 15
      Console.WriteLine(cal.Add(5, 10, 15)); // Kết quả: 30
      Console.WriteLine(cal.Add(2.5, 4.7)); // Kết quả: 7.2
   }
}

Trên đây là sự khác biệt giữa override và overload trong C#.

Có, trong C#/.Net, thuộc tính và phương thức tĩnh được định nghĩa bằng từ khóa "static".

  • Thuộc tính tĩnh là thuộc tính thuộc về lớp chứ không thuộc về đối tượng cụ thể của lớp đó. Khi một thuộc tính tĩnh được định nghĩa, nó chỉ có một bản sao trong bộ nhớ được chia sẻ bởi tất cả các đối tượng thuộc về lớp đó. Điều này có nghĩa là mọi đối tượng của lớp đó đều có thể truy cập và sử dụng giá trị của thuộc tính tĩnh đó. Để truy cập một thuộc tính tĩnh, ta không cần tạo một đối tượng từ lớp đó, mà ta có thể truy cập trực tiếp thông qua tên của lớp.

  • Phương thức tĩnh là phương thức thuộc về lớp chứ không thuộc về đối tượng cụ thể của lớp đó. Phương thức tĩnh có thể được gọi trực tiếp thông qua tên của lớp mà không cần tạo một đối tượng từ lớp đó. Phương thức tĩnh không thể truy cập vào các thành viên không tĩnh của lớp, bởi vì các thành viên không tĩnh cần được gọi thông qua một đối tượng.

Để tạo một instance của một class trong C#/.Net, bạn có thể sử dụng từ khóa new cùng với tên của class và thông tin khởi tạo (nếu có).

Ví dụ, giả sử bạn có một class có tên là Person:

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

Để tạo một instance của class Person, bạn có thể làm như sau:

Person person = new Person();

Trong ví dụ trên, person là một biến để lưu trữ instance của class Person. Bạn có thể truy cập vào các thuộc tính của person để đặt giá trị cho chúng:

person.Name = "John";
person.Age = 25;

Bạn cũng có thể khởi tạo instance của class có hàm khởi tạo (constructor) cho phép. Ví dụ:

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }

    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }
}

Person person = new Person("John", 25);

Trong ví dụ này, class Person có một hàm khởi tạo nhận hai tham số là nameage. Khi tạo instance của Person, bạn cần truyền giá trị cho hai tham số này.

Trong C#/.Net, exception handling (xử lý ngoại lệ) là quá trình xử lý các điều kiện ngoại lệ hoặc lỗi trong quá trình thực thi chương trình. Khi một ngoại lệ xảy ra trong một khối mã, ta có thể sử dụng cơ chế xử lý ngoại lệ để điều chỉnh hoặc thay đổi luồng thực thi của chương trình.

Trong C#, chúng ta sử dụng cú pháp try-catch-finally để xử lý ngoại lệ. Mã nguồn có khả năng gây ra ngoại lệ được đặt trong khối try. Nếu một ngoại lệ xảy ra trong khối try, quá trình thực thi chương trình sẽ bị ngắt và nó sẽ tìm các khối catch phù hợp để xử lý ngoại lệ.

Một khối catch có thể được sử dụng để xử lý một loại ngoại lệ cụ thể hoặc nhiều loại ngoại lệ. Khi một loại ngoại lệ xảy ra, hệ thống tìm các khối catch theo trình tự từ trên xuống dưới cho đến khi tìm được khối catch phù hợp để xử lý ngoại lệ.

Ngoài ra, ta cũng có thể sử dụng khối finally để xử lý các công việc "dọn dẹp" như đóng tài nguyên hay giải phóng bộ nhớ.

Exception handling là một cơ chế quan trọng trong việc kiểm soát lỗi và đảm bảo tính ổn định của chương trình. Nó giúp ngăn chặn lỗi không kiểm soát và cung cấp cách để thông báo cho người dùng về các vấn đề xảy ra.

Trong C#/.Net, using statement được sử dụng để quản lý tài nguyên không gian tới các đối tượng IDisposable. Nó đảm bảo rằng các tài nguyên này sẽ được giải phóng một cách đúng đắn sau khi đã được sử dụng xong, bất kể có bị ngoại lệ xảy ra hay không.

Khi sử dụng using statement, chúng ta không cần phải gọi phương thức Dispose() một cách rõ ràng để giải phóng tài nguyên, mà chỉ cần đặt các khối mã cần sử dụng đối tượng trong cặp dấu ngoặc nhọn ({}) của using statement. Khi khối mã kết thúc, Dispose() sẽ được tự động gọi, đảm bảo rằng các tài nguyên được giải phóng một cách an toàn và hiệu quả.

Ví dụ:

using (StreamReader sr = new StreamReader("file.txt"))
{
    string line = sr.ReadLine();
    // Các hoạt động khác trên đối tượng sr
}

Trong ví dụ trên, đối tượng StreamReader được tạo và được sử dụng trong khối mã của using statement. Khi khối mã kết thúc, Dispose() của đối tượng StreamReader được gọi để giải phóng tài nguyên.

Trong C#/.Net, delegate là một kiểu dữ liệu đặc biệt được sử dụng để tạo ra các con trỏ hàm. Nó cho phép bạn truyền một hàm như một tham số cho một phương thức khác hoặc lưu trữ một hàm trong một biến.

Delegate cung cấp sự trừu tượng cho việc sử dụng con trỏ hàm, giúp tăng tính linh hoạt và tái sử dụng trong việc xử lý sự kiện hoặc triển khai các hàm callback.

Trong khi đó, event là một cơ chế trong C#/.Net để thông báo và xử lý các sự kiện. Event là một thực thể của delegate và cho phép các phương thức đăng ký (subscribe) và hủy đăng ký (unsubscribe) để xử lý sự kiện như sự nhấn nút, chuột di chuyển, thay đổi trạng thái, vv.

Event bắt buộc phải kết hợp với delegate để định rõ kiểu của nó. Khi sự kiện xảy ra, các phương thức đã đăng ký sẽ được gọi theo thứ tự đăng ký. Event là một phần quan trọng trong việc triển khai mô hình Observer trong C#/.Net.

Đối tượng DataSet trong C# là một thành phần của C#/.NET Framework được sử dụng để lưu trữ và xử lý dữ liệu từ nguồn dữ liệu khác nhau như cơ sở dữ liệu, tệp tin XML, dữ liệu nhớ đệm, v.v.

DataSet chứa một tập hợp các đối tượng DataTable, được tổ chức theo cấu trúc quan hệ tổ chức - chứa dữ liệu dưới dạng các bảng có thể tham chiếu chéo và chia sẻ.

Một số thuộc tính và phương thức quan trọng của DataSet:

  1. Tables: Một tập hợp các đối tượng DataTable trong DataSet.
  2. Relations: Một tập hợp các đối tượng DataRelation, cho phép thiết lập quan hệ giữa các bảng trong DataSet.
  3. ReadXml/WriteXml: Phương thức để đọc dữ liệu từ tệp XML hoặc ghi dữ liệu vào tệp XML.
  4. ReadXmlSchema/WriteXmlSchema: Phương thức để đọc/giữ cấu trúc dữ liệu từ/tới tệp XML.
  5. Merge: Phương thức để kết hợp dữ liệu từ DataSet khác vào DataSet hiện tại.
  6. GetChanges: Phương thức trả về một DataSet mới chứa các thay đổi từ DataSet hiện tại.
  7. AcceptChanges/RejectChanges: Phương thức để chấp nhận hoặc từ chối các thay đổi được thực hiện trên DataSet.

DataSet giúp giải quyết nhiều vấn đề như hỗ trợ cập nhật dữ liệu có hệ thống, lưu trữ tạm thời dữ liệu, quản lý dữ liệu ở cấp độ ứng dụng và chuyển dữ liệu giữa các ứng dụng.

Để đọc và ghi dữ liệu từ một file text trong C#, bạn có thể sử dụng các lớp có sẵn của namespace System.IO. Dưới đây là một ví dụ cụ thể về cách thực hiện việc này:

Để đọc dữ liệu từ một file text:

string filePath = "path\\to\\file.txt";
string[] lines = File.ReadAllLines(filePath);
foreach (string line in lines)
{
    Console.WriteLine(line);
}

Để ghi dữ liệu vào một file text:

string filePath = "path\\to\\file.txt";
string[] lines = { "Line 1", "Line 2", "Line 3" };
File.WriteAllLines(filePath, lines);

Bạn cần nhớ thay đổi đường dẫn tương ứng của file trong biến filePath.

Các câu hỏi phỏng vấn C#/.Net - Phỏng vấn IT - PhongvanIT.com

2 days ago 119 câu hỏi phỏng vấn C#/.Net. 1. Sự khác nhau giữa static readonly và const? basic. 15.532 lượt xem. 2. Sự khác nhau giữa các lớp Trace và Debug? basic. 10.377 lượt xem.

› Tạo Tài Khoản Ngay PhongvanIT.com là nền tảng cung cấp các thông tin để bạn có thể ôn luyện, củng …

90

Tổng hợp 500+ câu hỏi phỏng vấn C#/.Net - Phong-Van.com

5 days ago Jun 8, 2023  · Top 15+ Câu Hỏi Phỏng Vấn .NET Phổ Biến Nhất - MasterSkills. 1 week ago Top 15+ Câu Hỏi Phỏng Vấn .NET Phổ Biến Nhất. Đã đăng Bởi Baolong trong Tháng Mười Hai …

199

Top 15+ Câu Hỏi Phỏng Vấn .NET Phổ Biến Nhất - MasterSkills

6 days ago Dưới đây là danh sách toàn diện gồm hơn 15 câu hỏi phỏng vấn .NET phổ biến nhất do Masterskills tổng hợp được phân loại cho cả ứng viên mới vào nghề và ứng viên đã có kinh …

200

Top 10+ Câu Hỏi Phỏng Vấn C# Được Hỏi Nhiều Nhất

2 days ago Lập trình OPP là lập trình hướng đối tượng, bao gồm 4 tính chất như sau: 1. Tính đóng gói 2. Tính kế thừa 3. Tính đa hình 4. Tính trừu tượng

› 4/5 (5)
› Published: Jan 4, 2023

344

Tuyển tập những câu hỏi phỏng vấn .NET thường gặp nhất

2 days ago Nov 1, 2023  · Trên đây là bộ câu hỏi phỏng vấn .NET mà thường gặp nhất. Ngoài những câu hỏi này, vẫn sẽ có thêm một số câu hỏi phỏng vấn khác tùy thuộc vào nhà tuyển dụng. Do đó, …

467

Top những câu hỏi phỏng vấn C# phổ biến nhất từ nhà tuyển dụng

2 days ago Tuy nhiên, đây lại là công việc có tính đặc thù cao, đòi hỏi rất nhiều về trình độ, kiến thức và các kỹ năng thì mới có thể làm được. Các hỏi phỏng vấn C# được nhà tuyển dụng hỏi nhiều nhất. …

155

Bộ 30 câu hỏi phỏng vấn lập trình viên .NET thường gặp nhất

2 days ago Jul 31, 2021  · 30 câu hỏi cần biết trước khi phỏng vấn lập trình viên .NET. Câu 1: Khái niệm .NET là gì? .NET là khung phát triển phần mềm, website hay là một framework để các lập trình viên …

451

Những câu hỏi phỏng vấn IT Ngôn ngữ C#/.Net (junior + middle)

1 week ago Feb 21, 2023  · Khi một lớp được định nghĩa là một lớp sealed, thì lớp đó không thể được kế thừa. Các struct cũng được sealed. RECOMMENDED. Những câu hỏi phỏng vấn IT ngôn ngữ …

291

Những Câu Hỏi Phỏng Vấn Với C# .NET Thường Gặp | CodeLearn

2 days ago Nếu bạn là một lập trình viên đam mê với C# .Net và đang chuẩn bị ứng tuyển vào một vị trí nào đó của một công ty phần mềm thì hãy đọc bài viết này nhé

118

Những câu hỏi phỏng vấn IT Ngôn ngữ C#/.Net (Senior) - ITDEV

6 days ago Feb 21, 2023  · 0. Những câu hỏi phỏng vấn C#/.Net (Senior) 72. Phạm vi của biến thành viên Protected Internal trong một lớp C# là gì? Protected internal access specifier cho phép một …

264

Top 5 câu hỏi phỏng vấn .NET Developer - TopDev

5 days ago Hữu dụng khi giá trị vào hàm ra hàm phát là thay đổi mãi mãi luôn, không cần quay lại giá trị cũ như pass by value. Không cần khởi tạo nên nhận vào một nhưng trả về 3,4,5. Hữu dụng khi …

141

LIST CÂU HỎI PHỎNG VẤN - Interview C#/.NET - Studocu

4 days ago Download. LIST CÂU HỎI PHỎNG VẤN .NET D EVELOPER. 1. OOP. a) OOP: là một phương pháp lập trình dựa trên lớp và đối tượng. Nó tập trung và o. các đối tượng hoạt động hơn là …

388

Top 54 câu hỏi phỏng vấn thường gặp và cách trả lời hay nhất

1 day ago 3 days ago  · Top 54 câu hỏi phỏng vấn thường gặp và cách trả lời hay nhất - Phần 1. Chuyên mục : Phỏng vấn - 2024-11-15 18:30:02 - 296388 lượt xem. Tổng hợp các câu hỏi phỏng vấn …

299

Top 5 câu hỏi phỏng vấn ASP.NET thường gặp và cách trả lời

1 week ago Cứ tự tin mà xúc thôi à. Bắt đầu thôi anh em, điểm qua lần lượt 5 câu nha! 1. Giải thích mô hình MVC trong ASP.NET. Câu hỏi đầu tiên phỏng vấn ASP.NET tất nhiên là câu hỏi về …

214

Top 40+ câu hỏi phỏng vấn Mobile Developer phổ biến

5 days ago Nov 12, 2024  · Top 50+ câu hỏi phỏng vấn OOP và trả lời mới nhất (Phần 2) Các câu hỏi phỏng vấn Mobile Developer cụ thể cho hệ điều hành iOS ... Flutter cung cấp bộ widget phong phú, …

380

Top 20+ câu hỏi phỏng vấn PHP phổ biến - ITviec Blog

1 week ago Nov 12, 2024  · Top 20+ câu hỏi phỏng vấn PHP phổ biến. Khi chuẩn bị cho một buổi phỏng vấn liên quan đến PHP, việc nắm vững các câu hỏi thường gặp là điều vô cùng quan trọng. Các …

392

FAQs - Câu hỏi thường gặp về phỏng vấn?

Những câu hỏi thường gặp để phản ánh chính sách và quy trình cụ thể của bạn hoặc để phù hợp với mục đích cụ thể của phỏng vấn.

Phỏng vấn giúp nhà tuyển dụng hiểu rõ hơn về kỹ năng, kinh nghiệm, và tính cách của ứng viên, đồng thời giúp ứng viên thể hiện năng lực và sự phù hợp với công ty.

Chuẩn bị bằng cách nghiên cứu về công ty, làm rõ vị trí công việc, và thực hành trả lời các câu hỏi phỏng vấn phổ biến.

Phỏng vấn cá nhân, nhóm, kỹ thuật, và phỏng vấn hỏi đáp trực tiếp là những loại phổ biến.

Tập trung vào kỹ năng, kinh nghiệm, và động lực cá nhân, giúp bạn nổi bật trong mắt nhà tuyển dụng.

Giữ bình tĩnh, tập trung vào giải quyết vấn đề, và không ngần ngại đưa ra suy luận logic.

Kỹ năng mềm như giao tiếp, làm việc nhóm, và quản lý thời gian là quan trọng vì chúng thể hiện khả năng làm việc hiệu quả trong môi trường làm việc.

Gửi một email cảm ơn, thể hiện sự quan tâm và sẵn sàng hợp tác.

Tránh nói xấu về công ty cũ, không chuẩn bị kỹ, và tránh những câu trả lời quá cá nhân.

Thể hiện sự chắc chắn, tận tâm học hỏi, và sẵn sàng đối mặt với những thách thức mới.

Kỹ năng này cho thấy khả năng đưa ra giải pháp hiệu quả và tư duy logic, quan trọng trong nhiều ngành nghề.

Kiểm tra thiết bị, tạo không gian làm việc chuyên nghiệp, và đảm bảo kết nối internet ổn định.

Kỹ năng quản lý thời gian giúp đảm bảo công việc được hoàn thành đúng hạn và đồng thời tăng hiệu suất làm việc.