Tất cả câu hỏi

Ngân hàng câu hỏi trắc nghiệm có giải thích chi tiết.

5.940/20.347 câuCòn 14.407
Arouter.delete('/comments/:id')
Brouter.get('/comments/:id')
Crouter.post('/comments/:id')
Drouter.put('/comments/:id')
Lời giải
Đáp án đúng: "router.delete('/comments/:id')". Quy ước REST gắn hành động với method HTTP: xoá tài nguyên dùng DELETE, và :id là tham số đường dẫn mà handler đọc qua req.params.id để biết bình luận nào cần xoá; trong thực tế còn truyền hàm xử lý làm đối số thứ hai, ví dụ thêm deleteComment sau đường dẫn. "router.get('/comments/:id')" dành cho đọc một bình luận, GET phải an toàn và không đổi dữ liệu. "router.post('/comments/:id')" dùng POST, vốn để tạo mới hoặc gửi dữ liệu cần xử lý, không đúng ngữ nghĩa xoá. "router.put('/comments/:id')" dùng PUT để thay thế toàn bộ hoặc cập nhật tài nguyên, không phải để xoá.
Mở trang câu hỏi này →
Đề bài
const express = require('express');
const app = express();
app.use('/api', (req, res, next) => {
    console.log('Middleware');
    next();
});
app.get('/api', (req, res) => res.send('API'));
app.listen(3000);
AMiddleware API
BOnly the API response if middleware skipped
CLogs middleware then processes GET handler
DCombined output from both functions
Lời giải
Đáp án đúng: "Logs middleware then processes GET handler". Lần theo mã: request GET /api khớp app.use('/api') trước tiên vì nó được khai báo trước, hàm này chạy console.log('Middleware') in Middleware ra console của server rồi gọi next(); Express tìm tiếp và gặp app.get('/api'), handler gọi res.send('API') nên client nhận phản hồi API. Phương án được chọn mô tả đúng trình tự ghi log ở middleware rồi xử lý ở handler GET. Cần nói thẳng về "Middleware API": nó gộp dòng log ở server với nội dung phản hồi HTTP thành một đầu ra, chỉ đúng nếu hiểu output là cả hai nơi, còn trình duyệt thực tế chỉ nhận API. "Only the API response if middleware skipped" sai vì middleware không bị bỏ qua: đường dẫn khớp và nó gọi next() bình thường. "Combined output from both functions" sai vì chỉ handler GET gửi phản hồi, middleware không ghi gì vào response, nên client không nhận đầu ra gộp từ cả hai hàm.
Mở trang câu hỏi này →
AIaaS
BPaaS
CBaaS
DSaaS
Lời giải
Đáp án đúng: "BaaS". BaaS (Backend as a Service, phần phụ trợ như một dịch vụ) cung cấp sẵn các khối phía máy chủ như cơ sở dữ liệu, xác thực người dùng, lưu trữ tệp, thông báo đẩy, và lập trình viên gọi chúng qua API hoặc SDK mà không phải tự viết hay vận hành server; Firebase và Supabase là ví dụ quen thuộc. "IaaS" cho thuê hạ tầng thô như máy ảo, mạng, ổ đĩa, người dùng tự cài và quản lý mọi thứ phía trên. "PaaS" cung cấp nền tảng để triển khai mã ứng dụng của chính mình, như Heroku, nhưng phần backend vẫn do bạn viết. "SaaS" là phần mềm hoàn chỉnh cho người dùng cuối như Gmail, không phải bộ dịch vụ backend dành cho lập trình viên.
Mở trang câu hỏi này →
ATo serve HTML template files
BTo upload files from the client
CTo download and save files to database
DTo render dynamic content using EJS
Lời giải
Đáp án đúng: "To serve HTML template files". Phương thức res.sendFile gửi nguyên nội dung một tệp tĩnh về trình duyệt theo đường dẫn tuyệt đối (hoặc đường dẫn tương đối kèm tuỳ chọn root), tự đặt Content-Type theo đuôi tệp; cách dùng điển hình là trả về một trang HTML có sẵn, như res.sendFile với path.join(__dirname, 'index.html'). Cần nói rõ: sendFile không render template, tệp được gửi y nguyên không chèn dữ liệu nào, nên chữ template trong phương án là cách diễn đạt lỏng, nhưng đây là phương án gần nhất với việc phục vụ tệp HTML. "To upload files from the client" ngược chiều: nhận tệp từ client là việc của middleware như multer, còn sendFile gửi tệp từ máy chủ đi. "To download and save files to database" sai vì sendFile không ghi gì vào cơ sở dữ liệu. "To render dynamic content using EJS" là việc của res.render, hàm chạy template EJS với dữ liệu để sinh HTML động.
Mở trang câu hỏi này →
AHandle file uploads
BConnect to SQL databases
CProvide a web application framework
DCompile TypeScript files
Lời giải
Đáp án đúng: "Provide a web application framework". Express là web framework tối giản dựng trên module http của Node.js: nó cung cấp định tuyến (routing) theo phương thức và đường dẫn như app.get hay app.post, chuỗi middleware xử lý request theo thứ tự, các tiện ích trên req và res như res.json, res.status, res.render, cùng khả năng gắn view engine. Nhờ vậy viết API hay ứng dụng web gọn hơn nhiều so với dùng http trực tiếp. "Handle file uploads" không phải vai trò chính của Express; tải tệp lên được xử lý bằng middleware riêng như multer gắn vào Express. "Connect to SQL databases" là việc của driver hoặc ORM như pg, mysql2, Sequelize; Express không kèm sẵn kết nối cơ sở dữ liệu. "Compile TypeScript files" là việc của trình biên dịch tsc hoặc công cụ như ts-node, không liên quan tới Express.
Mở trang câu hỏi này →
Đề bài
const express = require('express');
const app = express();

app.all('/users', (req, res, next) => {
  console.log('Accessing the /users endpoint...');
  next(); // pass control to the next handler
});

app.delete('/users', (req, res) => {
  res.send('DELETE request to the /users endpoint');
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
});
AThe response will be 'Accessing the /users endpoint...'
BThe response will be 'DELETE request to the /users endpoint'.
CThe response will be 'GET request to the /users endpoint'.
DThe response will be 'POST request to the /users endpoint'.
Lời giải
Đáp án đúng: "The response will be 'DELETE request to the /users endpoint'.". Lần theo mã: app.all('/users') khớp mọi phương thức HTTP tới /users nên chạy trước, in dòng Accessing the /users endpoint... ra console của server rồi gọi next() để chuyển tiếp; Express duyệt tiếp ngăn xếp route, gặp app.delete('/users') khớp cả đường dẫn lẫn phương thức DELETE, handler này gọi res.send nên client nhận chuỗi DELETE request to the /users endpoint. "The response will be 'Accessing the /users endpoint...'" sai vì console.log chỉ ghi log phía server, không gửi gì về client. "The response will be 'GET request to the /users endpoint'." sai vì mã không có route GET nào, và request ở đây là DELETE. "The response will be 'POST request to the /users endpoint'." sai vì cũng không có route POST, chuỗi đó không xuất hiện trong mã.
Mở trang câu hỏi này →
AEJS
BHandlebars
CPug
DMustache
Lời giải
Đáp án đúng: "EJS". EJS (Embedded JavaScript) nhúng JavaScript thẳng vào HTML bằng cặp thẻ phần trăm: thẻ trơn chạy mã như vòng lặp hay if, thẻ có dấu bằng in giá trị đã thoát ký tự HTML, thẻ có dấu gạch ngang in giá trị thô; trong Express bật bằng app.set('view engine', 'ejs') rồi gọi res.render(). "Handlebars" dùng cú pháp ngoặc nhọn kép cho biến và block helper như each, if. "Pug" không dùng thẻ đánh dấu mà dựa vào thụt lề và tên thẻ viết gọn, chẳng hạn một dòng h1= title. "Mustache" cũng dùng ngoặc nhọn kép, là ngôn ngữ template không logic mà Handlebars kế thừa và mở rộng.
Mở trang câu hỏi này →
AWildcard for simplicity
BWhitelist of trusted domains
CBoth are equally secure
DDisable CORS and use proxies
Lời giải
Đáp án đúng: "Whitelist of trusted domains". Danh sách trắng (whitelist) chỉ cho các origin được liệt kê, ví dụ cấu hình gói cors với tuỳ chọn origin là mảng tên miền frontend của mình, nên trang lạ không đọc được phản hồi API qua trình duyệt của người dùng; đây là nguyên tắc cấp quyền tối thiểu. "Wildcard for simplicity" đặt Access-Control-Allow-Origin bằng ký tự đại diện cho mọi trang đọc phản hồi, tiện cho API công khai nhưng mở rộng bề mặt tấn công, và không dùng được cùng credentials như cookie. "Both are equally secure" sai vì hai cách cho số lượng origin được phép khác hẳn nhau. "Disable CORS and use proxies" là đường vòng chứ không phải cấu hình CORS an toàn hơn: proxy cùng origin có thể dùng trong vài kiến trúc, nhưng câu hỏi so sánh hai cấu hình CORS và hạn chế origin mới trực tiếp tăng an toàn.
Mở trang câu hỏi này →
AdeleteMany
BremoveDocuments
CdeleteOne
DremoveMany
Lời giải
Đáp án đúng: "deleteMany". Phương thức deleteMany nhận một bộ lọc và xoá mọi document khớp điều kiện trong collection, ví dụ deleteMany với status bằng inactive xoá hết người dùng không hoạt động; kết quả trả về có deletedCount cho biết số document đã xoá. Truyền bộ lọc rỗng sẽ xoá toàn bộ document, nên phải cẩn thận. Phương thức này có cả trong MongoDB shell, Node.js driver lẫn model Mongoose. "removeDocuments" không phải phương thức nào của MongoDB. "deleteOne" có thật nhưng chỉ xoá document đầu tiên khớp bộ lọc, dù có nhiều document cùng thoả điều kiện. "removeMany" cũng không tồn tại; thứ có thật trước đây là remove(), đã bị đánh dấu lỗi thời và thay bằng cặp deleteOne, deleteMany.
Mở trang câu hỏi này →
ATo ensure that the cookie can only be accessed by the domain that created it.
BTo prevent the cookie from being sent over an unencrypted connection.
CTo prevent JavaScript code from accessing the cookie, which can help prevent cross-site scripting (XSS) attacks.
DTo set an expiration date for the cookie.
Lời giải
Đáp án đúng: "To prevent JavaScript code from accessing the cookie, which can help prevent cross-site scripting (XSS) attacks.". Cookie gắn cờ HttpOnly vẫn được trình duyệt gửi kèm mọi request tới máy chủ, nhưng không đọc được qua document.cookie trong JavaScript phía trình duyệt; vì vậy nếu trang bị chèn script độc (XSS), kẻ tấn công không lấy được cookie phiên hay token. Trong Express, cờ này đặt bằng tuỳ chọn httpOnly của res.cookie. "To ensure that the cookie can only be accessed by the domain" mô tả thuộc tính Domain cùng chính sách cùng nguồn, không phải HttpOnly. "To prevent the cookie from being sent over an unencrypted connection." là vai trò của cờ Secure, chỉ cho gửi cookie qua HTTPS. "To set an expiration date for the cookie." là việc của thuộc tính Expires hoặc Max-Age.
Mở trang câu hỏi này →
Aexpress.urlencoded()
Bexpress.static()
Cexpress.json()
Dexpress.parse()
Lời giải
Đáp án đúng: "express.json()". express.json() là middleware tích hợp sẵn trong Express từ bản 4.16 (dựa trên body-parser), đọc body của request có Content-Type là application/json, phân tích chuỗi JSON và gán kết quả vào req.body; thiếu nó thì req.body là undefined. Thường khai báo app.use(express.json()) trước các route cần đọc body. "express.urlencoded()" phân tích body dạng application/x-www-form-urlencoded do form HTML gửi, không phải JSON. "express.static()" phục vụ tệp tĩnh như ảnh, CSS từ một thư mục, không động tới body của request. "express.parse()" không tồn tại trong Express, gọi nó sẽ báo lỗi không phải hàm.
Mở trang câu hỏi này →
AFaster time to market
BBuilt-in server scaling
CCustom low-level hardware access
DPre-built authentication modules
Lời giải
Đáp án đúng: "Custom low-level hardware access". Câu hỏi phủ định: cần chọn thứ không phải lợi ích của BaaS (Backend as a Service). BaaS như Firebase hay Supabase gói sẵn hạ tầng sau những API dựng sẵn; đổi lại, người dùng không được chạm vào máy chủ vật lý, hệ điều hành hay phần cứng bên dưới, nên quyền truy cập phần cứng mức thấp tuỳ biến chính là thứ BaaS lấy đi chứ không mang lại. "Faster time to market" là lợi ích thật, vì không phải tự viết cơ sở dữ liệu, xác thực, lưu trữ nên sản phẩm ra mắt sớm hơn. "Built-in server scaling" cũng đúng, nhà cung cấp tự mở rộng tài nguyên khi lượng người dùng tăng. "Pre-built authentication modules" đúng nốt, ví dụ Firebase Authentication có sẵn đăng nhập bằng email, Google, số điện thoại. Ba điều này đều là lợi ích nên không được chọn.
Mở trang câu hỏi này →
5933What are the key features of Node.js?4 lựa chọn
AMultithreaded
BAsynchronous and Event-Driven
CSynchronous and Blocking
DSingle-Threaded but Highly Scalable
Lời giải
Đáp án đúng gồm hai ý: "Asynchronous and Event-Driven" và "Single-Threaded but Highly Scalable". Node.js chạy mã JavaScript trên một luồng chính với vòng lặp sự kiện (event loop): các thao tác I/O như đọc tệp, truy vấn cơ sở dữ liệu, gọi mạng được giao cho hệ điều hành hoặc thư viện libuv xử lý bất đồng bộ, khi xong thì callback hay Promise được đưa lại vào hàng đợi sự kiện; nhờ không chặn luồng để chờ I/O, một tiến trình phục vụ được hàng nghìn kết nối đồng thời. "Multithreaded" sai vì mô hình lập trình của Node.js là đơn luồng; libuv có thread pool nội bộ và module worker_threads cho phép tạo luồng phụ, nhưng đó là công cụ bổ sung chứ không phải đặc điểm cốt lõi. "Synchronous and Blocking" ngược hẳn với triết lý của Node.js; hàm đồng bộ như fs.readFileSync có tồn tại nhưng làm nghẽn event loop và nên tránh trong máy chủ.
Mở trang câu hỏi này →
ATo set response status
BTo access incoming request metadata
CTo parse URL paths
DTo handle errors
Lời giải
Đáp án đúng: "To access incoming request metadata". Trong module http của Node.js, req là đối tượng IncomingMessage và req.headers là một đối tượng chứa các header của yêu cầu gửi tới, với tên header đã chuyển về chữ thường, ví dụ req.headers['content-type'] hay req.headers.authorization để đọc token; đó là siêu dữ liệu (metadata) mô tả yêu cầu. "To set response status" là việc của res, qua res.statusCode hoặc res.writeHead(). "To parse URL paths" thuộc về req.url kết hợp lớp URL hoặc module url, header không chứa đường dẫn cần phân tích. "To handle errors" không phải vai trò của header; lỗi được xử lý qua sự kiện error, try/catch hoặc middleware xử lý lỗi trong Express.
Mở trang câu hỏi này →
5935What does the following Mongoose schema represent?4 lựa chọncó code
Đề bài
const userSchema = new mongoose.Schema({
  name: String,
  age: Number
});
AA model definition
BA middleware function
CA schema structure for documents
DA MongoDB query
Lời giải

Đáp án đúng: "A schema structure for documents". Đoạn mã gọi new mongoose.Schema với hai trường, name kiểu String và age kiểu Number, tức là mô tả hình dạng mà mỗi document người dùng sẽ có; Mongoose dùng nó để ép kiểu (cast) và kiểm tra dữ liệu trước khi lưu. Bản thân userSchema chưa làm việc gì với cơ sở dữ liệu. "A model definition" sai vì model chỉ có khi đem schema biên dịch bằng mongoose.model('User', userSchema); khi đó mới gọi được find hay save. "A middleware function" sai vì middleware (hook) của Mongoose được gắn lên schema bằng userSchema.pre hoặc userSchema.post với một hàm, còn đoạn này chỉ khai báo trường. "A MongoDB query" sai vì truy vấn là lời gọi như User.find với bộ lọc, gửi yêu cầu tới máy chủ; khai báo schema không gửi gì tới MongoDB.

Mở trang câu hỏi này →
AApache License
BMIT License
CGNU General Public License
DBSD License
Lời giải
Đáp án đúng: "MIT License". Express.js được phát hành theo giấy phép MIT, một giấy phép mã nguồn mở dễ dãi (permissive): ai cũng được dùng, sửa, phân phối, kể cả trong sản phẩm thương mại đóng mã, chỉ cần giữ nguyên thông báo bản quyền và nội dung giấy phép; điều này ghi trong tệp LICENSE của kho mã và trường license của package.json. "Apache License" cũng là giấy phép dễ dãi, có thêm điều khoản cấp quyền sáng chế, nhưng Express không dùng nó. "GNU General Public License" là giấy phép copyleft buộc sản phẩm phái sinh phải mở mã theo cùng giấy phép, khác hẳn MIT và không phải giấy phép của Express. "BSD License" gần giống MIT về tinh thần nhưng là một họ giấy phép khác, Express không phát hành theo nó.
Mở trang câu hỏi này →
Đề bài
const express = require('express');
const exphbs = require('express-handlebars');
const app = express();
app.engine('handlebars', exphbs({ defaultLayout: false }));
app.set('view engine', 'handlebars');
app.get('/profile', (req, res) => {
  res.render('profile', { name: 'Charlie', hobbies: ['reading', 'gaming'] });
});
app.listen(3000);

// views/profile.handlebars
<div>
  <h1>{{name}}</h1>
  <ul>
    {{#each hobbies}}
      <li>{{this}}</li>

{{/each}} </ul> </div>

A<div> <h1>Charlie</h1> <ul> <li>reading</li> <li>gaming</li> </ul> </div>
B<div> <h1>Charlie</h1> <ul></ul> </div>
C<div> <h1>undefined</h1> <ul> <li>reading</li> <li>gaming</li> </ul> </div>
DThrows an error due to invalid Handlebars syntax
Lời giải

Đáp án đúng: "

Lời giải
<div>
  <h1>Charlie</h1>
  <ul>
    <li>reading</li>
    <li>gaming</li>
  </ul>
</div>

". Lần theo mã: app.engine đăng ký express-handlebars cho đuôi handlebars với defaultLayout false, nghĩa là không bọc layout ngoài, và app.set chọn nó làm view engine. Khi GET tới /profile, res.render tìm tệp views/profile.handlebars và truyền dữ liệu gồm name là Charlie, hobbies là mảng reading, gaming. Trong template, {{name}} được thay bằng Charlie; khối each lặp qua mảng hobbies, và trong mỗi lượt {{this}} là phần tử hiện tại, nên sinh ra hai thẻ li là reading và gaming. Cách gọi exphbs() trực tiếp như hàm là kiểu của các bản express-handlebars cũ (bản mới dùng exphbs.engine()), câu hỏi xét kết quả render với cấu hình chạy được này. "<div> <h1>Charlie</h1> <ul></ul> </div> " chỉ xảy ra khi hobbies rỗng hoặc không được truyền, trong khi dữ liệu có hai phần tử. Kết quả có <h1>undefined</h1> sai vì name đã được truyền, và kể cả khi thiếu, Handlebars in chuỗi rỗng chứ không in chữ undefined. "Throws an error due to invalid Handlebars syntax" sai vì mọi thẻ đều đúng cú pháp và khối each được đóng đầy đủ.

Mở trang câu hỏi này →
AStep 1 is to create a new database reference using client.db('library') Step 2 is to create a new collection using await db.createCollection('books'); Step 3 is to list all databases using await adminDb.listDatabases();
BStep 1 is to create a new collection using await db.createCollection('books'); Step 2 is to create a new database reference using client.db('library') Step 3 is to list all databases using await adminDb.listDatabases();
CStep 1 is to list all databases using await adminDb.listDatabases(); Step 2 is to create a new collection using await db.createCollection('books'); Step 3 is to create a new database reference using client.db('library')
DStep 1 is to list all databases using await adminDb.listDatabases(); Step 2 is to create a new database reference using client.db('library') Step 3 is to create a new collection using await db.createCollection('books');
Lời giải

Đáp án đúng: "Step 1 is to create a

Lời giải
new database reference using client.db('library') Step 2 is to create a new collection using await db.createCollection('books');

Step 3 is to list all databases using await adminDb.listDatabases(); ". Sau khi client.connect() xong, client.db('library') chỉ tạo một tham chiếu tới cơ sở dữ liệu, MongoDB tạo nó thật khi có collection hoặc dữ liệu đầu tiên; vì vậy phải có tham chiếu db trước thì mới gọi được db.createCollection('books'), và lệnh này làm library thực sự xuất hiện trên máy chủ. Cuối cùng adminDb, lấy từ client.db().admin(), gọi listDatabases() thì danh sách đã có library. Thứ tự mở đầu bằng "Step 1 is to create a new collection" sai vì biến db chưa tồn tại lúc gọi createCollection. Thứ tự "Step 1 is to list all databases using await adminDb.listDatabases(); Step 2 is to create a new collection" vừa liệt kê quá sớm khi library chưa có trong danh sách, vừa tạo collection trước khi có tham chiếu db. Thứ tự "Step 1 is to list all databases using await adminDb.listDatabases(); Step 2 is to create a new database reference" tạo đúng trình tự nhưng liệt kê trước nên không thấy library vừa tạo, trái yêu cầu.

Mở trang câu hỏi này →
AGET
BPOST
CPUT
DDELETE
Lời giải
Đáp án đúng: "PUT". Theo quy ước REST, PUT gửi biểu diễn đầy đủ của tài nguyên tới URL của nó, như PUT /users/42, để thay thế bản hiện có, và có tính idempotent (lặp lại nhiều lần vẫn cho cùng kết quả); khi chỉ sửa một phần thường dùng PATCH. Trong Express, thao tác này ứng với app.put('/users/:id', handler). "GET" chỉ đọc tài nguyên và không được làm thay đổi dữ liệu trên máy chủ. "POST" thường dùng để tạo tài nguyên mới trong một tập hợp như POST /users, mỗi lần gọi có thể tạo thêm một bản ghi nên không idempotent. "DELETE" dùng để xoá tài nguyên khỏi máy chủ chứ không cập nhật nội dung của nó.
Mở trang câu hỏi này →
A<% users.forEach(user => { %> <%= user %> <% }); %>
B{ users.map(user => {user} ) }
C<% users.forEach(user => { %>{ user }<% }); %>
D<%= users.forEach(user => { %> <%= user %> <% }); %>
Lời giải

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

Lời giải
users.forEach(user => {
  %> <%= user %> <%
}

); %>". EJS phân biệt hai loại thẻ: thẻ <% … %> chỉ chạy mã JavaScript và không in gì, còn thẻ <%= … %> in giá trị của biểu thức sau khi thoát ký tự HTML. Lần theo đoạn mã: dòng đầu mở vòng forEach trên mảng users, dòng giữa in giá trị user ở mỗi lượt lặp, dòng cuối đóng hàm và vòng lặp, nên mỗi tên trong mảng được in một lần (giả sử users chứa tên; nếu là đối tượng thì in user.name). "{

Lời giải
users.map(user => {
  user
}

) }" là cú pháp JSX của React, EJS không hiểu dấu ngoặc nhọn đơn nên in nguyên văn chuỗi đó ra trang. "<%

Lời giải
users.forEach(user => {
  %>{
    user
  }
  <%
}

); %>" có vòng lặp đúng nhưng phần giữa nằm ngoài thẻ EJS, nên mỗi lượt chỉ in ra chữ thô { user } thay vì tên. "<%=

Lời giải
users.forEach(user => {
  %> <%= user %> <%
}

); %>" dùng thẻ in cho dòng mở vòng lặp, EJS sẽ cố biến đoạn chưa đóng đó thành một biểu thức cần in nên khi biên dịch template sẽ báo lỗi cú pháp.

Mở trang câu hỏi này →