Bộ câu hỏi phỏng vấn .Net Core phần 3

Sự khác biệt giữa .NET Standard và PCL (Portable Class Libraries) là gì?


Các cấu hình .NET Standard và PCL được tạo ra cho các mục đích giống nhau nhưng cũng khác nhau về các điểm chính.

Điểm tương đồng:

  • Định nghĩa các API được sử dụng để chia sẻ mã nhị phân.

Điểm khác nhau:

  • .NET Standard là một tập hợp các API được chọn, còn các cấu hình PCL được xác định bởi các điểm chung của các nền tảng hiện có.
  • .NET Standard ấn bản một cách tuyến tính, trong khi cấu hình PCL thì không. Cấu hình PCL đại diện cho các nền tảng của Microsoft còn .NET Standard là platform-agnostic.

.NET Standard là gì?


  • .NET Standard giải quyết vấn đề chia sẻ mã cho nhà phát triển .NET trên tất cả nền tảng bằng cách mang tất cả APIs mà bạn mong đợi và yêu thích vào các môi trường mà bạn cần như: desktop applications, mobile apps & games, và cloud services.
  • .NET Standard là một tập hợp các APIs mà tất cả nền tảng .NET phải triển khai. Điều này hợp nhất các nền tảng .NET và ngăn chặn sự phân mảnh trong tương lai.
  • .NET Standard 2.0 sẽ được thực thi bởi .NET Framework, .NET Core và Xamarin. Đối với .NET Core, nó sẽ có thêm nhiều API được yêu cầu.
  • .NET Standard 2.0 bao gồm một miếng đệm tương thích cho các .NET Framework binaries, làm tăng đáng kể bộ thư viện mà bạn có thể tham khảo từ các .NET Standard libraries của mình.
  • .NET Standard sẽ thay thế các Portable Class Libraries (PCLs) để làm công cụ xây dựng các thư viện .NET đa nền tảng.

Framework Class Library (FCL) là gì?


  • .NET Framework Class Library đúng như tên gọi của nó: một thư viện của lớp và các loại khác mà các nhà phát triển có thể sử dụng để làm cho cuộc sống của họ dễ dàng hơn. Mặc dù bản thân các lớp này được viết bằng C#, chúng có thể được sử dụng từ bất kỳ ngôn ngữ nào dựa trên CLR.
  • Framework Class Library (FCL) là thư viện rộng hơn chứa toàn bộ: ASP.NET, WinForms, XML stack, ADO.NET và hơn thế nữa. Bạn có thể nói rằng FCL bao gồm BCL.
  • Ở mức độ đơn giản, .NET Framework = libraries (FCL, BCL), trình biên dịch ngôn ngữ (C#, VB.NET) và Common Language Runtime (CLR).

Có cách nào để bắt multiple exceptions cùng một lúc mà không bị trùng lặp mã không?


Ví dụ:

try
{
   WebId = new Guid(queryString["web"]);
}
catch (FormatException)
{
   WebId = Guid.Empty;
}
catch (OverflowException)
{
   WebId = Guid.Empty;
}

Có cách nào để bắt hai exceptions mà chỉ gọi lệnh WebId = Guid.Empty một lần không?

Giải pháp:

catch (Exception ex)
{
   if (ex is FormatException || ex is OverflowException)
   {
      WebId = Guid.Empty;
      return;
   }
   throw;
}

CoreCLR là gì?


CoreCLR là công cụ thực thi .NET trong .NET Core, thực hiện các chức năng như thu gom rác và biên dịch thành mã máy.

image

Khi nào chúng ta nên sử dụng .NET Core Class Library và .NET Standard Class Library?


Sử dụng .NET Standard library khi bạn muốn tăng số lượng ứng dụng tương thích với thư viện của mình và bạn đồng ý với việc giảm số lượng .NET API mà thư viện của bạn có thể truy cập.

Sử dụng .NET Core library khi bạn muốn tăng số lượng .NET API mà thư viện của bạn có thể truy cập và bạn có thể chỉ cho phép các ứng dụng .NET Core tương thích với thư viện của bạn.

Sự khác biệt giữa .NET Core và .NET Framework là gì?


.NET hiện nay nói chung có 2 hương vị:

  • .NET Framework
  • .NET Core

.NET Core và .NET Framework (đối với hầu hết các phần) đều có mối quan hệ subset-superset. .NET Core được đặt tên là “Core” vì nó chứa các tính năng cốt lõi từ .NET Framework, cho cả các thư viện runtime và framework. Ví dụ: .NET Core và .NET Framework chia sẻ GC, JIT và các loại như String và List.

.NET Core được tạo ra để .NET có thể là mã nguồn mở, đa nền tảng và được sử dụng trong nhiều môi trường bị hạn chế về tài nguyên hơn.

Giải thích sự khác biệt giữa Task và Thread trong .NET?


Thread đại diện cho một luồng (thread) cấp hệ điều hành, với stack và tài nguyên hạt nhân (kernel resources) của riêng nó. Thread cho phép mức độ kiểm soát cao nhất; bạn có thể Abort() hoặc Suspend() hoặc Resume() một luồng, bạn có thể quan sát trạng thái của nó và bạn có thể thiết lập các thuộc tính cấp luồng như stack size, apartment state, hoặc culture. ThreadPool là một trình bao bọc xung quanh một nhóm các threads được duy trì bởi CLR.

Lớp Task từ Task Parallel Library cung cấp những gì tốt nhất của cả hai thế giới. Giống như ThreadPool, một tác vụ (task) không tạo luồng cấp hệ điều hành của riêng nó. Thay vào đó, các tác vụ được thực thi bởi TaskScheduler; bộ lập lịch mặc định chỉ chạy trên ThreadPool. Không giống như ThreadPool, Task cho phép bạn biết được khi nào nó kết thúc và (thông qua generic Task) để trả về kết quả.

Những lợi ích của việc sử dụng JIT là gì?


JIT có thể tạo mã nhanh hơn, vì nó nhắm mục tiêu đến nền tảng thực thi hiện tại. Biên dịch AOT phải nhắm mục tiêu đến mẫu số chung thấp nhất trong số tất cả các nền tảng thực thi có thể có. JIT có thể định cấu hình ứng dụng trong khi nó chạy và tự động biên dịch lại mã để mang lại hiệu suất tốt hơn trong hot path (các chức năng được sử dụng nhiều nhất).

Các tác vụ bất đồng bộ (Async / Await) hoạt động như thế nào trong .NET?


private async Task<bool> TestFunction()
{
   var x = await DoesSomethingExists();
   var y = await DoesSomethingElseExists();
   return y;
}
  • Câu lệnh await thứ hai có được thực thi ngay lập tức hay sau khi câu lệnh await đầu tiên hoàn thành?
  • await tạm dừng phương thức cho đến khi hành động của nó hoàn tất. Vì vậy, await thứ hai sẽ được thực thi sau khi await đầu tiên hoàn thành.
  • Mục đích của await là nó sẽ trả lại thread hiện tại cho nhóm thread trong khi hoạt động được await chạy và thực hiện bất cứ điều gì.
  • Điều này đặc biệt hữu ích trong các môi trường hiệu suất cao, chẳng hạn như một máy chủ web, nơi một yêu cầu nhất định được xử lý trên một thread nhất định từ nhóm thread tổng thể. Nếu chúng ta không await, thì thread đã cho xử lý request (và tất cả tài nguyên của nó) vẫn "được sử dụng" trong khi lệnh gọi db / dịch vụ hoàn tất. Quá trình này có thể mất vài giây hoặc hơn, đặc biệt là đối với các cuộc gọi dịch vụ bên ngoài.

Sự khác biệt giữa AppDomain, Assembly, Process và Thread là gì?


  • Một AppDomain là một đơn vị độc lập trong một process. AppDomains có thể được tạo trong runtime, được tải bằng mã và được tải xuống. Ranh giới độc lập của nó được thiết kế để làm cho các ứng dụng .NET đáng tin cậy hơn.
  • Một Assembly chứa một hoặc nhiều modules, chứa các đoạn mã đã được biên dịch. Bạn thường sẽ thấy một assembly dưới dạng .EXE hoặc .DLL.
  • Một Process là một ứng dụng đang thực thi.
  • Một Thread là một execution context. Hệ điều hành thực thi mã trong một thread. Hệ điều hành chuyển đổi qua lại giữa các threads, cho phép từng thread thực thi lần lượt, do đó tạo cảm giác rằng nhiều ứng dụng đang chạy cùng một lúc.

Để tổng hợp tất cả lại với nhau (rất đơn giản) ...

Một chương trình được thực thi. Một process được tạo bởi hệ điều hành, và trong thread đơn của nó, nó bắt đầu tải mã để thực thi. Trong một ứng dụng .NET, một AppDomain duy nhất được tạo bởi CLR. Cụm assembly thực thi của ứng dụng (.EXE) được tải vào AppDomain này và bắt đầu thực thi. Ứng dụng có thể sinh ra các processes mới, tạo các AppDomains, tải các assemblies khác vào các AppDomains này, sau đó tạo các Threads mới để thực thi mã trong bất kỳ AppDomains nào trong số này.

Sự khác biệt giữa các dự án .NET Framework / Core và các dự án .NET Standard Class Library?


  • Sử dụng .NET Standard library khi bạn muốn tăng số lượng ứng dụng tương thích với thư viện của mình và bạn đồng ý với việc giảm số lượng .NET API mà thư viện của bạn có thể truy cập.
  • Việc triển khai .Net Standard Library cho phép chia sẻ mã trên tất cả các phiên bản khác nhau của các ứng dụng .NET như .NET Framework, .NET Core và Xamarin.

Làm thế nào để chọn target version của .NET Standard library?


Khi chọn phiên bản .NET Standard, bạn nên cân nhắc sự đánh đổi này:

  • Phiên bản càng cao, càng nhiều API có sẵn cho bạn.
  • Phiên bản càng thấp, càng có nhiều nền tảng triển khai nó.

Bạn nên chọn target version thấp nhất có thể của .NET Standard. Vì vậy, sau khi bạn tìm thấy phiên bản .NET Standard cao nhất mà bạn có thể nhắm đến, hãy làm theo các bước sau:

  • Hãy chọn phiên bản thấp hơn tiếp theo của .NET Standard và xây dựng dự án của bạn.
  • Nếu dự án của bạn xây dựng thành công, hãy lặp lại bước 1. Nếu không, hãy chọn lại phiên bản cao hơn tiếp theo và đó là phiên bản bạn nên sử dụng.

Tại sao .NET sử dụng trình biên dịch JIT thay vì chỉ biên dịch mã một lần trên máy đích?


Có hai thứ cần đạt được bằng cách sử dụng định dạng trung gian (intermediate format) như .NET hoặc Java:

  • Bạn có thể chạy chương trình trên bất kỳ nền tảng nào, chính xác là vì mã được biểu diễn ở định dạng trung gian thay vì native code. Bạn chỉ cần viết một trình thông dịch cho định dạng trung gian.
  • Nó cho phép một số tối ưu hóa run-time không thể (dễ dàng) tại thời gian biên dịch (compile-time): ví dụ: bạn có thể tận dụng các tính năng đặc biệt trên CPU mới, ngay cả khi những CPU đó không tồn tại khi bạn viết chương trình của mình - chỉ có trình biên dịch JIT mới cần biết về điều đó.

Tại sao thư viện .NET Standard tồn tại?


  • Lý do mà .NET Standard tồn tại là vì tính di động; nó xác định một tập hợp các API mà các nền tảng .NET đồng ý triển khai. Bất kỳ nền tảng nào triển khai .NET Standard đều tương thích với các thư viện sử dụng .NET Standard đó. Một trong những nền tảng tương thích đó là .NET Core.
  • Các mẫu thư viện .NET Standard tồn tại để chạy trên nhiều runtime. Ngược lại, các mẫu thư viện .NET Core tồn tại để truy cập nhiều API hơn (với chi phí tương thích) và để chỉ định một nền tảng mà dựa vào đó để xây dựng tệp thực thi.

Sự khác biệt giữa RyuJIT và Roslyn là gì?


  • Roslyn là trình biên dịch sẽ biên dịch mã của bạn (C# hoặc VB) sang IL.
  • RyuJIT là một trình biên dịch Just In Time biên dịch IL của bạn thành native code.

Hiện tại cả hai đều là mã nguồn mở

Sự khác biệt giữa CIL và MSIL(IL) là gì?


CIL là thuật ngữ được sử dụng trong CLI Standard. MSIL là (tôi nghĩ là) CIL được tạo bởi các công cụ MS. Về hiệu quả, chúng đồng nghĩa với nhau.

  • CIL - Common Intermediate Language - là thuật ngữ được sử dụng trong International Standard.
  • MSIL - Microsoft Intermediate Language - là thuật ngữ sản phẩm để chỉ việc triển khai tiêu chuẩn đó của Microsoft.

Giải thích cách sử dụng Finalize và Dispose?


  • Phương thức Finalizer được gọi khi đối tượng của bạn được thu gom rác và bạn không có gì đảm bảo khi nào điều này sẽ xảy ra (bạn có thể ép buộc nó, nhưng nó sẽ ảnh hưởng đến hiệu suất).
  • Mặt khác, phương thức Dispose được gọi bằng code đã tạo ra class của bạn để bạn có thể dọn dẹp và giải phóng bất kỳ tài nguyên nào bạn đã có được (dữ liệu không được quản lý, kết nối cơ sở dữ liệu, xử lý tệp,...) tại thời điểm mã được hoàn thành với đối tượng của bạn.- Các sử dụng thực tế là triển khai IDisposable và Dispose để bạn có thể sử dụng đối tượng của mình trong một câu lệnh using, chẳng hạn như using (var foo = new MyObject ()) {}. Và trong phần finalizer của bạn, bạn gọi Dispose, đề phòng trường hợp mã đang chạy của bạn quên "dispose".

Bạn biết bao nhiêu loại JIT Compilations?


Có ba kiểu JIT compilation trong .NET framework:

  • Pre-JIT biên dịch mã nguồn hoàn chỉnh thành native code trong một chu kỳ biên dịch duy nhất. Trong các ngôn ngữ .NET, điều này được thực hiện trong Ngen.exe (Native Image Generator). Tất cả các quy trình CIL được biên dịch thành native code trước khi khởi động. Bằng cách này, runtime có thể sử dụng các native images từ bộ đệm (cache) thay vì gọi JIT Compiler.
  • Econo-JIT chỉ biên dịch những phương thức được gọi trong runtime. Tuy nhiên, các phương thức được biên dịch này sẽ bị loại bỏ khi chúng không được yêu cầu.
  • Normal-JIT chỉ biên dịch những phương thức được gọi trong runtime. Các phương thức này được biên dịch ở lần đầu tiên chúng được gọi, và sau đó chúng được lưu trữ trong bộ nhớ cache. Khi các phương thức tương tự được gọi lại, mã được biên dịch từ bộ nhớ cache sẽ được sử dụng để thực thi.

Sự khác biệt giữa mô hình bất đồng bộ Node.js và async/await trong .NET?


Mô hình bất đồng bộ trong Node.js tương tự như mô hình bất đồng bộ cũ trong C# và .Net được gọi là Event-based Asynchronous Pattern (EAP). Các từ khóa async / await của C# làm cho mã bất đồng bộ trở nên tuyến tính và cho phép bạn tránh "Callback Hell" tốt hơn nhiều trong bất kỳ ngôn ngữ lập trình nào khác.

Node.js là đơn luồng (single-threaded) bất đồng bộ, trong khi ASP.NET là đa luồng (multi-threaded) bất đồng bộ. Điều này có nghĩa là mã Node.js có thể tạo ra một số giả định đơn giản hóa vì tất cả mã của bạn luôn chạy trên cùng một thread. Vì vậy, khi mã ASP.NET của bạn đang await, nó có thể tiếp tục trên một thread khác và tùy thuộc vào bạn để tránh những thứ như trạng thái luồng cục bộ (thread-local state).

Sự khác biệt tương tự cũng là một điểm mạnh của ASP.NET, bởi vì nó có nghĩa là ASP.NET bất đồng bộ có thể mở rộng quy mô tối đa với khả năng đầy đủ của máy chủ của bạn. Nếu bạn xem xét, chẳng hạn như một máy 8 lõi, thì ASP.NET có thể xử lý (các phần đồng bộ của) 8 request cùng một lúc. Nếu bạn đặt Node.js trên một máy chủ được cải tiến, thì thông thường bạn sẽ thực sự chạy 8 instances riêng biệt của Node.js và thêm một cái gì đó như nginx hoặc một trình cân bằng tải tùy chỉnh đơn giản để xử lý các yêu cầu định tuyến (routing) cho máy chủ đó.

Avatar Techmely Team
VIẾT BỞI

Techmely Team