Danh sách câu hỏi của đề

Câu hỏi: PRJ301 Phát triển ứng dụng Java web – Bộ ôn tập cuối kỳ số 3

50 câu trắc nghiệm kèm lời giải của môn PRJ301 - Phát triển ứng dụng Java web, xếp đúng thứ tự trong đề. Trang 2/3 — câu 21–40.

Danh sách câu hỏi

40/50 câuCòn 10
ATo ensure all operations are executed simultaneously
BTo group operations together as a single unit of work
CTo increase the likelihood of data corruption
DTo decrease database performance
Lời giải
Đáp án đúng: "To group operations together as a single unit of work". Giao dịch tồn tại để nhiều lệnh ghi được coi là một khối nguyên tử: trong JDBC, tắt chế độ tự chốt rồi chỉ gọi commit() khi mọi bước đã thành công, còn gặp lỗi thì rollback() đưa dữ liệu về trạng thái trước đó, nhờ vậy không còn cảnh chuyển tiền đã trừ bên gửi mà chưa cộng cho bên nhận. "To ensure all operations are executed simultaneously" nhầm nguyên tử với đồng thời: các lệnh vẫn chạy lần lượt theo thứ tự mã, giao dịch chỉ bảo đảm chúng cùng có hiệu lực hoặc cùng bị bỏ. "To increase the likelihood of data corruption" ngược hẳn mục đích, vì giao dịch chính là cơ chế giảm hỏng dữ liệu. "To decrease database performance" lấy một tác dụng phụ làm mục đích: giữ giao dịch mở lâu có thể sinh khoá và chi phí, nhưng đó là giá phải trả chứ không phải điều người ta mong muốn.
Mở trang câu hỏi này →
AThe model processes the request
BThe controller receives the request and processes it
CThe view updates the data
DThe database returns the result
Lời giải
Đáp án đúng: "The controller receives the request and processes it". Trong MVC hướng web, mọi lượt gọi đi vào bộ điều khiển trước: servlet đã ghép với mẫu đường dẫn nhận request, đọc tham số, kiểm tính hợp lệ, rồi quyết định nghiệp vụ nào cần gọi. Chỉ sau đó tầng mô hình mới làm việc, và cuối cùng bộ điều khiển chọn trang để hiển thị kết quả. Lựa chọn "The model processes the request" đảo thứ tự: tầng mô hình không mở cửa ra ngoài, nó chỉ được gọi khi bộ điều khiển chuyển dữ liệu đã lọc vào. Lựa chọn "The view updates the data" sai cả thứ tự lẫn vai, vì phần hiển thị chỉ đọc dữ liệu đã dọn sẵn để vẽ ra chứ không sửa dữ liệu. Lựa chọn "The database returns the result" là mắt gần cuối của chuỗi truy xuất, nằm sau khi tầng mô hình đã gửi câu lệnh xuống, nên không thể là bước đầu tiên.
Mở trang câu hỏi này →
ASession cookies can store any Java object as a value
BSession cookies are deleted when the browser closes
CSession cookies store the session ID on the client side
DSession cookies can be marked as HttpOnly for security
Lời giải
Đáp án đúng: "Session cookies can store any Java object as a value". Cookie là một tiêu đề HTTP, nên tên và giá trị của nó chỉ có thể là văn bản; muốn giữ một đối tượng Java thì phải đặt vào HttpSession phía máy chủ, còn cookie chỉ mang theo định danh phiên. Đó chính là phát biểu sai mà câu hỏi đang tìm. "Session cookies are deleted when the browser closes" đúng, vì cookie phiên không khai thời điểm hết hạn nên trình duyệt chỉ giữ nó trong bộ nhớ của lần chạy đó. "Session cookies store the session ID on the client side" cũng đúng và chính là cơ chế theo dấu phiên mặc định, với cookie quen gọi là JSESSIONID. "Session cookies can be marked as HttpOnly for security" đúng nữa: cờ này khiến mã kịch bản bên trình duyệt không đọc được cookie, giảm rủi ro bị đánh cắp phiên qua lỗ hổng chèn mã.
Mở trang câu hỏi này →
AView
BController
CModel
DNone, servlets are not used in MVC2 architecture
Lời giải
Đáp án đúng: "Controller". MVC2 dồn mọi lượt gọi vào một servlet điều phối: nó nhận request, đọc tham số, gọi lớp nghiệp vụ và lớp truy xuất dữ liệu, đặt kết quả vào phạm vi request rồi chuyển sang trang hiển thị. Servlet là lớp Java chạy trên luồng của container nên thích hợp cho việc điều phối và quyết định, chứ không phải cho việc sinh mã HTML. Lựa chọn "View" ứng với trang JSP, nơi chỉ còn thẻ hiển thị và biểu thức đọc dữ liệu; viết HTML bằng lệnh in trong servlet chính là lối cũ mà kiến trúc này muốn bỏ. Lựa chọn "Model" ứng với các lớp mang dữ liệu và quy tắc nghiệp vụ, chúng không biết gì về HTTP. Lựa chọn "None, servlets are not used in MVC2 architecture" nói ngược hẳn, vì không có servlet điều phối thì không còn cấu hình MVC2 nào để nói tới.
Mở trang câu hỏi này →
AUser Interface App Layer
BApplication Logic Layer
CData Layer
DConnection Layer
Lời giải
Đáp án đúng: "Application Logic Layer". Trong mô hình nhiều tầng, tầng logic ứng dụng là nơi đặt luật nghiệp vụ: kiểm tra dữ liệu đầu vào, tính toán, quyết định thứ tự các bước, rồi mới yêu cầu tầng dữ liệu đọc ghi; trong ứng dụng Java web thì servlet điều phối cùng các lớp nghiệp vụ nằm ở tầng này. "User Interface App Layer" sai vì tầng đó chỉ nhận thao tác của người dùng và hiển thị kết quả, nó không được chứa luật nghiệp vụ nếu muốn thay giao diện mà không viết lại nghiệp vụ. "Data Layer" sai vì nó chỉ chịu trách nhiệm lưu trữ và truy xuất, trả về dữ liệu thô cho tầng trên quyết định. "Connection Layer" sai vì việc mở, giữ và trả kết nối chỉ là chi tiết kỹ thuật bên trong tầng dữ liệu, không phải một tầng mang logic ứng dụng.
Mở trang câu hỏi này →
AHttpSessionListener
BSessionEventHandler
CServletContextListener
DSessionHandler
Lời giải
Đáp án đúng: "HttpSessionListener". Muốn biết lúc một phiên vừa được tạo hay vừa bị huỷ, lớp của bạn phải cài giao diện này rồi viết sessionCreated và sessionDestroyed, mỗi phương thức nhận một HttpSessionEvent, sau đó đăng ký bằng thẻ listener trong mô tả triển khai hoặc bằng chú giải tương ứng; container sẽ gọi lại đúng thời điểm, nên đây là chỗ hợp lý để đếm số người đang truy cập. "SessionEventHandler" không có trong API servlet, nên dù đặt tên lớp như vậy cũng không có móc nào để container gọi. "ServletContextListener" là giao diện thật nhưng theo dõi vòng đời của cả ứng dụng, với contextInitialized và contextDestroyed, chứ không báo việc tạo phiên. "SessionHandler" cũng là tên tự đặt, không thuộc đặc tả servlet, nên ứng dụng cài nó thì container vẫn không biết phải gọi gì.
Mở trang câu hỏi này →
ARedirects all errors to error.jsp
BHandles errors by including error.jsp
CDeclares a default error page for the entire application
DHas no effect in JSP
Lời giải
Đáp án đúng: "Redirects all errors to error.jsp". Chỉ thị này khai cho riêng trang chứa nó một trang nhận lỗi: khi trang sinh ra ngoại lệ không được bắt, container dừng việc dựng phản hồi và đưa lượt yêu cầu sang trang đã khai, nơi thường bật thuộc tính tự nhận là trang lỗi để đọc được vật thể ngoại lệ, nên nói nó dồn mọi lỗi của trang sang trang kia là mô tả sát nhất. Mô tả "Handles errors by including error.jsp" nói sai cơ chế: chèn thì nội dung trang lỗi được ghép vào phản hồi đang dở, còn ở đây trang lỗi thay hẳn kết quả. Mô tả "Declares a default error page for the entire application" nhầm phạm vi: chỉ thị page chỉ có hiệu lực trong một trang, muốn áp cho toàn ứng dụng thì phải khai trang lỗi trong mô tả triển khai. Mô tả "Has no effect in JSP" sai hẳn vì đây là một thuộc tính chuẩn của chỉ thị page.
Mở trang câu hỏi này →
ASet-Cookie
BCookie-Set
CCookie
DSet-Cookie-Header
Lời giải
Đáp án đúng: "Set-Cookie". Khi servlet gọi response.addCookie, container chuyển cookie thành một dòng tiêu đề Set-Cookie trong phần đầu của phản hồi, mỗi cookie một dòng, kèm các thuộc tính như đường dẫn, thời gian sống, cờ chỉ dùng cho HTTP; trình duyệt đọc tiêu đề đó rồi lưu lại. Vì tiêu đề nằm ở phần đầu phản hồi, cookie chỉ thêm được trước khi nội dung bắt đầu gửi đi. Lựa chọn "Cookie" là tiêu đề của chiều ngược lại: trình duyệt dùng nó để gửi các cookie đã lưu lên máy chủ trong những lượt gọi sau, phía servlet đọc qua request.getCookies. Lựa chọn "Cookie-Set" chỉ đảo trật tự hai từ, không có tiêu đề nào tên như vậy. Lựa chọn "Set-Cookie-Header" ghép thêm một từ vào tên thật; tên tiêu đề phải khớp từng ký tự nên dạng này không trình duyệt nào hiểu.
Mở trang câu hỏi này →
Acontext.setAttribute("key", value);
Brequest.setAttribute("key", value);
Csession.setAttribute("key", value);
Dresponse.setAttribute("key", value);
Lời giải

Đáp án đúng: "context.setAttribute("key", value); ". ServletContext là vùng dữ liệu dùng chung cho toàn ứng dụng: lấy nó bằng getServletContext() rồi ghi bằng setAttribute, giá trị đó mọi servlet và mọi người dùng đều đọc được và sống tới khi ứng dụng bị dỡ. "request.setAttribute("key", value); " sai vì phạm vi request chỉ sống trong một lần xử lý yêu cầu, hết lượt forward là mất, không dùng để chia sẻ toàn ứng dụng. "session.setAttribute("key", value); " sai vì dữ liệu khi đó chỉ thuộc về một người dùng và biến mất khi phiên hết thời gian chờ hoặc bị invalidate. "response.setAttribute("key", value); " sai vì HttpServletResponse không có phương thức setAttribute; phản hồi chỉ dùng để đặt tiêu đề, mã trạng thái và ghi nội dung trả về.

Mở trang câu hỏi này →
AIt first checks application scope, then session, then request, then page scope.
BIt first checks if the variable is one of the eleven implicit variables.
CIt searches through all available scopes (page, request, session, application) simultaneously.
DIt relies solely on explicit variable declarations within the JSP page.
Lời giải
Đáp án đúng: "It first checks if the variable is one of the eleven implicit variables.". Khi gặp một tên trong biểu thức, bộ định giá EL tra trước trong danh sách biến ẩn gồm pageScope, requestScope, sessionScope, applicationScope, param, paramValues, header, headerValues, cookie, initParam và pageContext; chỉ khi tên không thuộc nhóm đó, nó mới đi tìm thuộc tính theo phạm vi từ hẹp ra rộng, tức page rồi request rồi session rồi application. "It first checks application scope, then session, then request, then page scope." đảo ngược thứ tự thật, hệ quả là một thuộc tính trùng tên ở phạm vi rộng sẽ che thuộc tính của trang, trái với hành vi quan sát được. "It searches through all available scopes (page, request, session, application) simultaneously." sai vì nếu tra song song thì khi trùng tên sẽ không có cách nào quyết định giá trị nào thắng, trong khi EL luôn trả giá trị ở phạm vi hẹp nhất. "It relies solely on explicit variable declarations within the JSP page." cũng sai, bởi EL đọc được thuộc tính do servlet đặt vào phạm vi mà trang không khai báo gì trước.
Mở trang câu hỏi này →
A<c:if test="${empty myVar}">
B<c:when test="${myVar == null}">
C<c:check value="${myVar}">
D<c:validate test="${empty myVar}">
Lời giải

Đáp án đúng: "<c:

Lời giải
if test="${empty myVar}">".

Toán tử empty của EL trả về true cho cả bốn trường hợp: giá trị null, chuỗi rỗng, mảng hay Collection không có phần tử và Map không có khoá, nên ghép nó với thẻ điều kiện của thư viện lõi là cách gọn nhất để xét một biến hoặc thuộc tính có dữ liệu hay không. "<c:when test="${myVar == null}">" hụt hai mặt: thẻ chỉ hợp lệ khi nằm trong c:choose, và phép so sánh với null bỏ qua trường hợp chuỗi rỗng hay danh sách rỗng. "<c:check value="${myVar}">" không tồn tại trong thư viện lõi nên trang sẽ lỗi ngay ở pha dịch vì bộ mô tả thư viện không khai thẻ nào như vậy. "<c:validate test="${empty myVar}">" dùng đúng biểu thức nhưng cũng là thẻ tự đặt; JSTL không có thẻ đó, việc kiểm tra dữ liệu nhập thuộc thư viện khác hoặc do mã tự viết.

Mở trang câu hỏi này →
A${product.stockPerStore["store101"]}
B${product.stockPerStore.store101}
C${product.stockPerStore.get("store101")}
D${product.stockPerStore["store101"].value}
Lời giải

Đáp án đúng: "${product.stockPerStore["store101"]}". Trong EL, toán tử ngoặc vuông là cách tổng quát để tra một bản đồ: giá trị trong ngoặc được coi là khoá, nên biểu thức này lấy đúng phần tử ứng với khoá đã nêu rồi in ra số lượng tồn. Cách viết "${product.stockPerStore.store101}" cũng tra được bản đồ, nhưng chỉ khi tên khoá là một định danh hợp lệ, nên nó phụ thuộc hình dạng khoá chứ không phải lối truy cập chung cho mọi khoá, ví dụ khoá có dấu cách hoặc mở đầu bằng chữ số. Cách viết "${

Lời giải
product.stockPerStore.get("store101")
}
"

gọi thẳng phương thức Java, chỉ chạy trên bản EL có hỗ trợ gọi phương thức, lại đi đường vòng qua chính toán tử tra khoá đã có sẵn. Cách viết "${product.stockPerStore["store101"].value}" thêm một bước đọc thuộc tính trên giá trị trả về, mà giá trị đó là một số nguyên bọc, không có hàm đọc thuộc tính mang tên ấy, nên biểu thức không ra kết quả.

Mở trang câu hỏi này →
ATo play a game of catch.
BTo store data in a session.
CTo deal with errors that happen when the JSP page is running.
DTo capture user input.
Lời giải
Đáp án đúng: "To deal with errors that happen when the JSP page is running.". Thẻ này bọc một đoạn trang, bắt ngoại lệ phát sinh khi đoạn đó thực thi và đặt vật thể ngoại lệ vào biến nêu ở thuộc tính lưu, nhờ vậy trang không ném lỗi ra ngoài mà tự xử lý tiếp, thường kèm một thẻ kiểm xem biến đó có giá trị hay không. Diễn giải "To play a game of catch." chỉ là lối chơi chữ theo nghĩa thông thường của từ, không có liên hệ nào với thư viện thẻ. Diễn giải "To store data in a session." là việc của thẻ gán giá trị với phạm vi phiên, không phải của thẻ bắt lỗi. Diễn giải "To capture user input." thuộc về biểu mẫu HTML cùng các tham số đọc qua EL, cũng nằm ngoài vai trò xử lý ngoại lệ.
Mở trang câu hỏi này →
AWhen a servlet is initialized.
BWhen the web application is deployed.
CWhen a session is created.
DWhen a request is received.
Lời giải
Đáp án đúng: "When the web application is deployed.". Phương thức này là móc vòng đời của cả ứng dụng: container gọi nó đúng một lần khi ngữ cảnh web vừa được dựng, trước khi bất kỳ servlet, filter hay yêu cầu nào được phục vụ, và đối số sự kiện cho phép lấy ServletContext để nạp cấu hình, mở sẵn kết nối hay đặt thuộc tính dùng chung; cặp đối xứng của nó là contextDestroyed lúc ứng dụng bị dỡ. "When a servlet is initialized." lẫn với init() của chính servlet đó; hơn nữa servlet có thể được khởi tạo muộn ở lần gọi đầu tiên, tức sau khi ngữ cảnh đã sẵn sàng từ lâu. "When a session is created." là việc của sessionCreated trong giao diện lắng nghe phiên, xảy ra nhiều lần theo từng người dùng. "When a request is received." không ứng với móc nào của ngữ cảnh; muốn chen vào từng yêu cầu thì dùng filter hoặc giao diện lắng nghe yêu cầu.
Mở trang câu hỏi này →
AHttpSessionListener
BHttpSessionAttributeListener
CServletContextListener
DServletRequestListener
Lời giải
Đáp án đúng: "HttpSessionAttributeListener". Đây là listener nghe trên dữ liệu đặt trong phiên: container gọi attributeAdded() khi một thuộc tính được đặt lần đầu, attributeReplaced() khi giá trị cũ bị ghi đè và attributeRemoved() khi thuộc tính bị gỡ, nên muốn theo dõi giá trị của biến trong session đổi ra sao thì dùng đúng giao diện này. "HttpSessionListener" chỉ nghe việc phiên được tạo và bị phá qua sessionCreated() và sessionDestroyed(), tức là vòng đời của phiên chứ không phải nội dung bên trong nó. "ServletContextListener" nghe vòng đời của toàn ứng dụng, chạy lúc ServletContext khởi tạo và lúc bị tháo, không liên quan tới phiên. "ServletRequestListener" nghe một yêu cầu vào và ra khỏi phạm vi xử lý, phạm vi này ngắn hơn phiên và cũng không báo gì về thay đổi giá trị trong session.
Mở trang câu hỏi này →
AWhen a user submits a form
BWhen a new session is created
CWhen the servlet context is initialized
DWhen a session is invalidated
Lời giải
Đáp án đúng: "When a new session is created". HttpSessionListener là bộ lắng nghe vòng đời của phiên: container gọi sessionCreated ngay sau khi nó cấp một HttpSession mới, tức ở lần đầu mã nguồn gọi request.getSession() mà chưa có phiên nào gắn với trình duyệt này, và gọi sessionDestroyed ở đầu kia của vòng đời. Lựa chọn "When a user submits a form" nhầm sự kiện: gửi biểu mẫu chỉ là một request HTTP thường, nó chỉ kéo theo việc sinh phiên nếu đó là lượt gọi đầu tiên cần tới phiên, còn bản thân hành vi gửi không phải sự kiện phiên. Lựa chọn "When the servlet context is initialized" thuộc bộ lắng nghe khác: thời điểm nạp ứng dụng được báo qua contextInitialized của ServletContextListener, xảy ra một lần cho cả ứng dụng và trước mọi phiên. Lựa chọn "When a session is invalidated" mô tả đúng thời điểm của sessionDestroyed, tức lúc phiên bị huỷ hoặc hết hiệu lực, không phải lúc phiên sinh ra.
Mở trang câu hỏi này →
AContext initialization
BSession creation
CSession destruction
DRequest handling
Lời giải
Đáp án đúng: "Session destruction". Phương thức sessionDestroyed là callback container gọi khi một phiên hết hiệu lực, do mã gọi huỷ phiên hoặc do quá thời gian chờ không hoạt động; đây là chỗ hợp lý để giải phóng tài nguyên gắn với phiên hay giảm bộ đếm người đang đăng nhập. Lựa chọn "Context initialization" thuộc contextInitialized của ServletContextListener, xảy ra một lần ở mức ứng dụng và không liên quan phiên nào. Lựa chọn "Session creation" do phương thức còn lại của chính giao diện này là sessionCreated xử lý, tức là mốc đối lập trong vòng đời phiên. Lựa chọn "Request handling" là việc của servlet, hoặc của ServletRequestListener nếu chỉ cần bắt mốc một request bắt đầu và kết thúc, chứ không phải việc của sessionDestroyed.
Mở trang câu hỏi này →
A<c:out value="${userEmail}" default="No email provided" />
B<c:out value="${if (userEmail != null) { 'No email provided'}}" />
C<c:out value="${userEmail}" ifNull="No email provided" />
D<c:out value="${userEmail}" nullVal="No email provided" />
E<c:out value="${userEmail}" null="No email provided" />
Lời giải

Đáp án đúng: "<c:out value="${userEmail}" default="No email provided" />". Thẻ c:out vừa thoát các ký tự đặc biệt của HTML trước khi in, vừa có thuộc tính default dùng khi biểu thức cho null hoặc chuỗi rỗng, nên một thẻ duy nhất làm trọn cả hai yêu cầu của đề mà không cần thêm điều kiện nào. "<c:out value="${

Lời giải
if (userEmail != null) {
  'No email provided'
}

}" />" sai từ nền tảng: EL là ngôn ngữ biểu thức, không có câu lệnh điều kiện lẫn khối ngoặc nhọn, nên chuỗi đó không dịch được. "<c:out value="${userEmail}" ifNull="No email provided" />" đặt đúng ý nhưng tên thuộc tính không có trong bộ mô tả thư viện, mà thẻ JSTL thì báo lỗi ngay ở pha dịch khi gặp thuộc tính lạ. "<c:out value="${userEmail}" nullVal="No email provided" />" cũng là tên tự nghĩ ra, không thuộc thư viện lõi. "<c:out value="${userEmail}" null="No email provided" />" ngoài việc sai tên thuộc tính còn lấy một từ khoá của EL làm tên, càng không thể hợp lệ.

Mở trang câu hỏi này →
Đề bài
var="item" value="5"/> <c:forEach var="item" begin="1" end="1"> <c:out value="${item}"/> </c:forEach>
A1
B5
CNo output
DError
Lời giải
Đáp án đúng: "1". Thẻ set tạo biến item ở phạm vi trang với giá trị 5, nhưng thẻ forEach lại khai biến vòng lặp cũng mang tên item, và trong thân vòng lặp biến vòng lặp che mất biến cũ; vòng lặp đếm từ giá trị begin đến giá trị end là từ 1 đến 1 nên chạy đúng một lượt với item bằng 1, vì vậy thẻ out in ra 1. Lựa chọn "5" chỉ đúng nếu đọc biến item ở ngoài vòng lặp, còn thẻ out ở đây nằm trong thân nên luôn thấy giá trị của biến vòng lặp. Lựa chọn "No output" sai vì begin và end đều bằng 1 nên khoảng lặp không rỗng và thân vẫn chạy một lượt. Lựa chọn "Error" sai vì chỉ thị taglib của thư viện core đã có mặt với tiền tố c, mọi thẻ đều dùng đúng tiền tố đó, và việc trùng tên biến giữa set với forEach không bị coi là lỗi ở pha dịch trang.
Mở trang câu hỏi này →
ATo pick the main language for the website.
BTo tell other tags which language and country format to use.
CTo change the user's language settings.
DTo choose the language for database information.
Lời giải
Đáp án đúng: "To tell other tags which language and country format to use.". Thẻ này ghi locale vào cấu hình định dạng của trang và đè lên locale mà trình duyệt gửi kèm trong tiêu đề yêu cầu, nên mọi thẻ định dạng đứng sau nó trong phạm vi đó, từ in số, in ngày cho tới tra gói tài nguyên, đều dùng chung một quy ước ngôn ngữ và quốc gia; nhờ vậy cùng một dữ liệu có thể hiện ra theo kiểu Việt Nam hay kiểu Mỹ mà không sửa mã. "To pick the main language for the website." sai vì nó chỉ ảnh hưởng tới các thẻ định dạng trong phạm vi nơi đặt, không phải một thiết lập ngôn ngữ chung cho cả website. "To change the user's language settings." sai vì mã phía server không sửa được thiết lập trên máy khách; trình duyệt của người dùng vẫn nguyên. "To choose the language for database information." sai vì dữ liệu lấy ra bằng thứ ngôn ngữ nào là do câu truy vấn và nội dung đã lưu, thẻ định dạng không can thiệp.
Mở trang câu hỏi này →