public class RegisterModel
{[???]
public string Email { get; set;}}
A[Url]
B[StringLength(50)]
C[EmailAddress]
D[Required]
Lời giải
Đáp án đúng: "[EmailAddress]". EmailAddressAttribute trong System.ComponentModel.DataAnnotations kiểm tra giá trị chuỗi có dạng địa chỉ email, khi model binding chạy, lỗi được ghi vào ModelState và tag helper còn sinh thuộc tính kiểm tra phía client cho trường Email. "[Url]" sai vì attribute này kiểm tra chuỗi là URL tuyệt đối bắt đầu bằng http, https hoặc ftp, không phải email. "[StringLength(50)]" sai vì nó chỉ giới hạn độ dài tối đa 50 ký tự, chuỗi bất kỳ ngắn hơn đều qua dù không phải email. "[Required]" sai vì nó chỉ bắt buộc trường có giá trị khác rỗng, không kiểm tra định dạng, nên thường được đặt cùng EmailAddress chứ không thay thế được nó.
Đáp án đúng: "To return data in JSON format.". JsonResult, thường tạo bằng phương thức Json trong controller, tuần tự hoá đối tượng bằng System.Text.Json và đặt Content-Type là application/json, phù hợp cho API hoặc lời gọi AJAX từ trình duyệt. "To return a view." sai vì trả về giao diện là việc của ViewResult tạo bằng phương thức View. "To return a file download." sai vì tải tệp dùng FileResult và các lớp con như FileContentResult, PhysicalFileResult tạo bằng phương thức File. "To redirect to another action." sai vì chuyển hướng dùng RedirectToActionResult tạo bằng RedirectToAction, phản hồi là mã 302 kèm header Location chứ không phải nội dung JSON.
đăng ký lớp worker, thường kế thừa BackgroundService, như một IHostedService dạng Singleton, khi host khởi động nó gọi StartAsync và chạy ExecuteAsync của worker cho tới khi ứng dụng dừng. "Using app.MapControllerRoute()." sai vì phương thức này ánh xạ route quy ước cho controller MVC trong pipeline HTTP. "Using app.UseStaticFiles()." sai vì đó là middleware phục vụ tệp tĩnh từ thư mục wwwroot. "Using services.AddDbContext<YourDbContext>()." sai vì nó đăng ký DbContext của EF Core với vòng đời Scoped, không chạy gì nền, và worker muốn dùng DbContext còn phải tự tạo scope qua IServiceScopeFactory.
Đáp án đúng: ".razor". Component Blazor là tệp .razor kết hợp markup HTML với C# theo cú pháp Razor, logic đặt trong khối @code, khi biên dịch mỗi tệp sinh ra một lớp C# cùng tên kế thừa ComponentBase, dùng lại được như một thẻ trong component khác. ".cshtml" sai vì đó là Razor view hoặc Razor Page của MVC và Razor Pages, render ở máy chủ theo từng request chứ không phải component tương tác. ".html" sai vì HTML tĩnh không chứa C#, như wwwroot/index.html của Blazor WebAssembly chỉ là trang vỏ nạp ứng dụng. ".blazor" sai vì không tồn tại đuôi tệp này, trình biên dịch Razor chỉ nhận .razor cho component.
Đáp án đúng: "Persists data only for a single request". TempData (TempDataDictionary) giữ dữ liệu sống qua đúng một lần chuyển request, điển hình là mẫu Post-Redirect-Get: action POST gán thông báo rồi redirect, request GET kế tiếp đọc và hiển thị nó một lần, sau đó giá trị bị đánh dấu xoá. Tài liệu API ASP.NET Core mô tả nó là dữ liệu chỉ tồn tại từ request này sang request kế tiếp. Nói chặt thì câu chữ này chưa thật chính xác, vì TempData sống tới khi được đọc ở request sau (Keep hoặc Peek còn giữ lại lâu hơn) chứ không chỉ gói trong một request, nhưng nó vẫn là phát biểu đúng bản chất ngắn hạn, dùng một lần của TempData. "Stores data permanently in the database" sai vì TempData mặc định lưu trong cookie hoặc session, không bao giờ lưu vĩnh viễn. "Works like cookies" chỉ đúng về nơi lưu mặc định (CookieTempDataProvider), không mô tả bản chất: cookie sống tới khi hết hạn, còn TempData bị xoá ngay sau khi đọc. "Must be strongly typed" sai vì TempData là từ điển khoá chuỗi giá trị object, không bắt buộc kiểu mạnh.
public class ChatHub : Hub
{
public async Task SendMessage(string user, string message){
await Clients.All.SendAsync("ReceiveMessage", user, message);}}
What will this hub method do?
ASend a message only to the calling client.
BSend a message to all connected clients.
CSend a message only to a specific group.
DSave the message in the database automatically.
Lời giải
Đáp án đúng: "Send a message to all connected clients.". Khi một client gọi SendMessage với user và message, Clients.All chọn mọi kết nối đang mở tới ChatHub, kể cả chính người gọi, rồi SendAsync yêu cầu từng client chạy phương thức ReceiveMessage đã đăng ký phía client với hai đối số đó, await chờ việc gửi đi xong. "Send a message only to the calling client." sai vì muốn chỉ trả về người gọi phải dùng Clients.Caller. "Send a message only to a specific group." sai vì gửi theo nhóm phải dùng Clients.Group kèm tên nhóm, sau khi đã thêm kết nối vào nhóm bằng Groups.AddToGroupAsync. "Save the message in the database automatically." sai vì SignalR chỉ chuyển tin theo thời gian thực, không lưu gì, muốn lưu phải tự gọi DbContext trong phương thức hub.
Đáp án đúng: "By setting properties on the PageModel.". Trong Razor Pages, trang .cshtml khai báo @model trỏ tới lớp PageModel, handler như OnGet gán giá trị cho các thuộc tính public (ví dụ danh sách sản phẩm), rồi trang đọc lại qua Model và tên thuộc tính khi render, còn thuộc tính đánh dấu BindProperty nhận dữ liệu form theo chiều ngược lại. "Using database queries." sai vì truy vấn chỉ để lấy dữ liệu, kết quả vẫn phải gán vào thuộc tính của PageModel mới tới được trang, trang không nên tự truy vấn. "Using JavaScript only." sai vì Razor Pages render ở máy chủ, dữ liệu đi qua mô hình C#, JavaScript chỉ là tuỳ chọn ở trình duyệt. "Using static HTML attributes." sai vì thuộc tính HTML tĩnh viết cứng trong markup, không mang được dữ liệu động mà handler tính ra.
Đáp án đúng: "_Imports.razor". Tệp _Imports.razor chứa các chỉ thị @using (cùng @inject, @layout khi cần) áp dụng cho mọi component .razor trong cùng thư mục và các thư mục con, nhờ vậy namespace dùng chung chỉ khai báo một lần thay vì lặp ở đầu từng component. "Startup.cs" sai vì đó là tệp cấu hình dịch vụ và pipeline của mẫu dự án cũ (từ .NET 5 trở về trước), không khai báo namespace cho component. "Program.cs" sai vì đó là điểm vào ứng dụng nơi đăng ký dịch vụ và middleware, chỉ thị using trong đó chỉ có hiệu lực trong chính tệp C# ấy (trừ khi viết global using). "App.razor" sai vì đó là component gốc chứa Router hoặc khung HTML của Blazor Web App, không phải nơi khai báo using dùng chung.
AThe response received from a server after a WebRequest.
BThe network configuration settings.
CThe data sent to a server.
DThe client-side application.
Lời giải
Đáp án đúng: "The response received from a server after a WebRequest.". Trong System.Net, WebResponse là lớp cơ sở trừu tượng cho phản hồi, được trả về bởi WebRequest.GetResponse hoặc GetResponseAsync, lớp con HttpWebResponse cho biết mã trạng thái, header và có GetResponseStream để đọc nội dung máy chủ gửi về (ngày nay HttpClient được khuyên dùng thay cho cặp lớp này). "The network configuration settings." sai vì thiết lập mạng thuộc các lớp như ServicePointManager hay namespace System.Net.NetworkInformation. "The data sent to a server." sai vì đó là phía WebRequest: dữ liệu gửi đi được ghi vào luồng lấy từ GetRequestStream. "The client-side application." sai vì WebResponse chỉ là một đối tượng chứa dữ liệu phản hồi, không đại diện cho ứng dụng nào.
Đáp án đúng: "An IP address". DNS (Domain Name System, hệ thống phân giải tên miền) tra bản ghi A (IPv4) hoặc AAAA (IPv6) để đổi một tên miền như example.com thành địa chỉ IP mà máy tính dùng để định tuyến gói tin. "A URL" sai vì URL là chuỗi chứa cả giao thức, tên miền và đường dẫn, DNS không sinh ra URL mà chỉ phân giải phần tên máy nằm trong nó. "A MAC address" sai vì địa chỉ MAC là địa chỉ phần cứng ở tầng liên kết, được tìm từ địa chỉ IP bằng giao thức ARP trong mạng cục bộ chứ không qua DNS. "A hostname" sai vì tên máy chính là đầu vào của DNS, chỉ có truy vấn ngược bản ghi PTR mới đổi IP thành tên, còn câu hỏi hỏi chiều từ tên miền sang địa chỉ.
Đáp án đúng: "Ensure type safety". jsonDecode trả về Map với giá trị kiểu dynamic, truy cập kiểu data['name'] không được trình biên dịch kiểm tra: gõ sai tên khoá hay nhầm kiểu chỉ lộ ra lúc chạy. Ánh xạ phản hồi vào lớp model với constructor fromJson, như User có trường final String name và final int age, gom việc chuyển kiểu vào một chỗ; phần còn lại của ứng dụng dùng user.name có kiểu rõ ràng, được trình phân tích và null safety kiểm tra, IDE gợi ý được, API đổi thì chỉ cần sửa model. "Reduce JSON size" sai vì kích thước JSON do máy chủ gửi về, ánh xạ phía ứng dụng không đổi được. "Speed up UI" sai vì ánh xạ thêm một bước xử lý nhỏ chứ không làm giao diện nhanh hơn. "Improve theme" sai vì theme là chuyện màu sắc và kiểu chữ, không liên quan dữ liệu API.
Đáp án đúng: "Unit test". Unit test kiểm một hàm hay lớp Dart thuần, không dựng widget, không cần thiết bị hay máy ảo Android, iOS, chạy thẳng trên máy ảo Dart nên rất nhanh, hàng trăm ca có thể xong trong thời gian ngắn; đây là tầng đáy của kim tự tháp kiểm thử. "Widget test" cũng chạy không cần thiết bị nhưng phải dựng cây widget, bố cục và mô phỏng khung hình qua WidgetTester nên chậm hơn unit test. "Integration test" chạy cả ứng dụng trên thiết bị hay máy ảo, phải build và cài đặt, chậm nhất trong ba loại kiểm thử tự động. "Manual test" do con người thao tác bằng tay, chậm nhất trong tất cả vì không tự động hoá được.
Đáp án đúng: "Column". Column xếp danh sách children theo chiều dọc, từ trên xuống dưới; mainAxisAlignment căn theo trục dọc, crossAxisAlignment căn theo trục ngang, và bọc con trong Expanded để chia phần không gian còn lại. Ví dụ màn hình đăng nhập gồm logo, hai ô nhập và nút bấm xếp dọc. Nội dung vượt chiều cao màn hình thì nên dùng ListView hoặc bọc trong SingleChildScrollView. "Row" sai vì nó xếp các con theo chiều ngang. "Stack" sai vì nó xếp các con chồng lên nhau theo chiều sâu, không theo hàng hay cột. "Expanded" sai vì nó không xếp nhiều con mà chỉ bọc một con trong Row hoặc Column để con đó giãn ra chiếm phần còn trống.
Đáp án đúng: "404". 404 Not Found thuộc nhóm 4xx lỗi phía máy khách, nghĩa là máy chủ vẫn hoạt động nhưng không tìm thấy tài nguyên ở URL được yêu cầu, ví dụ gọi sai đường dẫn hay mã sản phẩm đã bị xoá; trong Flutter, sau http.get nên kiểm response.statusCode bằng 404 để báo cho người dùng rằng dữ liệu không tồn tại. "200" là OK, yêu cầu thành công. "301" là Moved Permanently, tài nguyên đã chuyển hẳn sang URL mới ghi trong header Location, máy khách nên theo đường dẫn đó. "500" là Internal Server Error, lỗi xảy ra ở phía máy chủ khi xử lý yêu cầu chứ không phải do tài nguyên không tồn tại.
Đáp án đúng: "Error messages are shown". Khi gọi formKey.currentState!.validate(), Form chạy validator của từng TextFormField; trường nào trả về chuỗi khác null thì chuỗi đó hiện thành thông báo lỗi màu đỏ dưới trường, và validate() trả về false. Mã xử lý thường chỉ gọi save() rồi gửi dữ liệu khi validate() trả về true, nên khi kiểm tra thất bại người dùng chỉ thấy lỗi để sửa lại. "Form submits" sai vì dữ liệu không được gửi khi validate() trả về false. "App crashes" sai vì dữ liệu không hợp lệ là một luồng xử lý bình thường, không ném ngoại lệ. "Data is saved" sai vì onSaved chỉ chạy khi gọi save(), mà save() thường chỉ được gọi sau khi kiểm tra thành công.
Đáp án đúng: "Business Logic Component". BLoC là mẫu kiến trúc do Google giới thiệu cho Flutter, tách logic nghiệp vụ (business logic) khỏi giao diện: widget chỉ gửi sự kiện vào và nhận trạng thái ra qua Stream, còn mọi quy tắc xử lý nằm trong thành phần BLoC, dễ kiểm thử và tái sử dụng; gói flutter_bloc hiện thực mẫu này với Bloc, Cubit, BlocProvider, BlocBuilder. "Backend Logic Controller" sai vì BLoC chạy ngay trong ứng dụng phía người dùng, không phải bộ điều khiển phía máy chủ. "Build Logic Component" sai vì BLoC không liên quan tới quá trình build giao diện hay biên dịch, nó nằm tách khỏi hàm build. "Basic Logic Controller" sai vì chữ B là Business, nhấn mạnh logic nghiệp vụ, và chữ C là Component chứ không phải Controller.
Đáp án đúng: "Calling setState()". Widget được dựng lại khi framework đánh dấu Element của nó cần build lại; nguyên nhân thường gặp nhất là gọi setState() trong State của StatefulWidget, ngoài ra còn khi widget cha dựng lại và truyền cấu hình mới, khi InheritedWidget mà nó phụ thuộc thay đổi (Theme, MediaQuery, Provider), hay khi StreamBuilder, FutureBuilder nhận dữ liệu mới. "Navigation only" sai vì điều hướng có thể gây dựng lại nhưng chữ only loại bỏ mọi nguyên nhân khác, nhất là setState. "Restarting the IDE" sai vì khởi động lại trình soạn thảo không tác động tới ứng dụng đang chạy. "Changing the SDK" sai vì đổi phiên bản Flutter SDK đòi biên dịch lại cả ứng dụng, không phải cơ chế rebuild trong lúc chạy.
Đáp án đúng: "Reduced development and maintenance effort". Với một mã nguồn chung, nhóm chỉ viết tính năng, sửa lỗi, kiểm thử và cập nhật một lần cho cả Android, iOS, web, desktop, thay vì duy trì song song mã Kotlin và Swift; cần ít người hơn, ra mắt đồng thời và hành vi nhất quán giữa các nền tảng. "Higher memory usage" sai vì đó không phải ưu điểm, và cũng không phải hệ quả tất yếu của việc dùng chung mã. "Simpler UI customization" không phải lợi ích của mã nguồn chung: tuỳ biến giao diện dễ là nhờ hệ thống widget tự vẽ của Flutter, còn khi cần giao diện riêng cho từng nền tảng thì một mã nguồn lại phải rẽ nhánh. "Automatic database synchronization" sai vì đồng bộ dữ liệu phải tự hiện thực hoặc dùng dịch vụ như Firebase, mã nguồn chung không tự làm việc đó.
Đáp án đúng: "Widgets are recreated instead of modified". Widget trong Flutter là bản mô tả cấu hình bất biến, mọi trường đều final và lớp được gắn @immutable; muốn giao diện đổi, ta không sửa widget cũ mà gọi setState để build trả về widget mới với giá trị mới, rồi Flutter so sánh với lần trước và cập nhật Element cùng RenderObject bền vững bên dưới. Widget rẻ nên tạo lại liên tục cũng không sao. "Widgets cannot be removed" sai vì khi build lần sau không trả về một widget nữa, nó bị gỡ khỏi cây và Element tương ứng bị huỷ. "Widgets are stored permanently" sai vì widget sống rất ngắn, mỗi lần dựng lại lại có thể hiện mới; thứ tồn tại lâu là Element và State. "Widgets cannot contain data" sai vì widget vẫn chứa dữ liệu cấu hình như chuỗi của Text hay màu của Container, chỉ là dữ liệu đó không đổi sau khi tạo.
Đáp án đúng: "Prepare app for distribution". Bản release được dựng bằng flutter build apk, appbundle hoặc ipa: mã Dart biên dịch AOT thành mã máy, tắt assert, tắt kết nối gỡ lỗi và hot reload, tối ưu kích thước và tốc độ, rồi ký bằng khoá phát hành để đưa lên Google Play hay App Store cho người dùng thật cài đặt. "Debug code" sai vì gỡ lỗi dùng chế độ debug, chạy JIT kèm hot reload và DevTools; bản release đã bỏ hết các công cụ đó. "Test UI" sai vì kiểm thử giao diện thường chạy ở chế độ debug hoặc trong flutter test, còn đo hiệu năng sát thực tế dùng chế độ profile; mục đích chính của bản release không phải kiểm thử. "Change theme" sai vì đổi giao diện là sửa ThemeData trong mã, không cần tới chế độ dựng nào.