Explore all courses in this category.
Explore all courses in this category.
Nguyễn Đình Cường
0 comment
09 Nov, 2026
Node.js cho phép dùng JavaScript ở phía máy chủ và là lựa chọn phổ biến cho API, ứng dụng thời gian thực và các dịch vụ nhỏ. Khi phỏng vấn, bạn sẽ gặp những câu hỏi về cách Node xử lý nhiều kết nối, vai trò của middleware và cách viết code bất đồng bộ an toàn.
Node.js chạy code JavaScript trên một luồng chính và dùng mô hình vào/ra không chặn (non-blocking I/O) dựa trên event loop. Khi gặp thao tác chậm như đọc file hay truy vấn cơ sở dữ liệu, Node giao việc cho hệ điều hành hoặc nhóm luồng nền, rồi tiếp tục xử lý request khác. Khi việc xong, callback được đưa vào event loop để chạy. Nhờ vậy một tiến trình có thể phục vụ nhiều kết nối đồng thời, đặc biệt hiệu quả với tác vụ nặng về I/O.
Không lý tưởng, vì tính toán nặng sẽ chặn luồng chính và làm mọi request khác chờ. Cách xử lý gồm dùng worker_threads, tách thành dịch vụ riêng, hoặc đẩy vào hàng đợi cho tiến trình khác xử lý.
Middleware là hàm nhận req, res, next; nó có thể xử lý request, kết thúc response hoặc gọi next() để chuyển cho bước tiếp theo.
const express = require('express');const app = express();app.use(express.json());app.use((req, res, next) => { console.log(req.method, req.url); next();});app.get('/health', (req, res) => { res.json({ ok: true });});app.listen(3000);Thứ tự khai báo middleware rất quan trọng vì chúng chạy lần lượt theo thứ tự đăng ký.
Middleware xử lý lỗi có bốn tham số (err, req, res, next) và đặt cuối cùng. Với hàm bất đồng bộ, bạn cần bắt lỗi rồi chuyển cho next, vì Express 4 không tự bắt lỗi từ Promise bị từ chối.
app.get('/users/:id', async (req, res, next) => { try { const user = await findUser(req.params.id); if (!user) return res.status(404).json({ error: 'Không tìm thấy' }); res.json(user); } catch (err) { next(err); }});app.use((err, req, res, next) => { console.error(err); res.status(500).json({ error: 'Lỗi máy chủ' });});CommonJS dùng require và module.exports, nạp đồng bộ. ES Modules dùng import và export, là chuẩn của ngôn ngữ và hỗ trợ phân tích tĩnh. Node hỗ trợ cả hai; bạn bật ESM bằng đuôi .mjs hoặc khai báo "type": "module" trong package.json.
Stream cho phép xử lý dữ liệu theo từng phần thay vì tải toàn bộ vào bộ nhớ, rất hữu ích với file lớn. Bốn loại chính là readable, writable, duplex và transform. Ví dụ đọc một file lớn và gửi thẳng cho client bằng fs.createReadStream(path).pipe(res).
Thông tin nhạy cảm như mật khẩu cơ sở dữ liệu, khóa API đặt trong biến môi trường, truy cập qua process.env, không ghi cứng trong code hay đẩy lên kho mã. Thư viện như dotenv giúp nạp file .env khi phát triển.
cluster hoặc chạy nhiều tiến trình bằng trình quản lý như PM2 hay container.Trước hết xem có tác vụ đồng bộ nào chặn event loop không, ví dụ vòng lặp lớn, mã hóa nặng hoặc đọc file bằng hàm đồng bộ. Sau đó kiểm tra truy vấn cơ sở dữ liệu thiếu chỉ mục, kích thước pool kết nối, số lượng gọi đến dịch vụ bên ngoài và khả năng dùng cache. Bạn cũng nên nói về việc đo lường bằng log, số liệu thời gian phản hồi và công cụ profiling trước khi sửa, thay vì tối ưu theo cảm tính.
Lắng nghe tín hiệu SIGTERM, ngừng nhận kết nối mới bằng server.close(), chờ các request đang xử lý hoàn tất, đóng kết nối cơ sở dữ liệu rồi mới thoát. Điều này đặc biệt quan trọng khi triển khai bằng container, nơi tiến trình được dừng và thay thế thường xuyên.
Hãy chuẩn bị sẵn một API nhỏ bằng Express có xác thực, kiểm tra dữ liệu, kết nối cơ sở dữ liệu và xử lý lỗi tập trung. Khi bạn kể về nó một cách mạch lạc, phần lớn câu hỏi kỹ thuật sẽ trở thành cuộc trò chuyện tự nhiên.
Muốn học Node.js từ cơ bản đến xây dựng API hoàn chỉnh, bạn có thể tham khảo các khóa học tại codebem.com.
Nguyễn Đình Cường
0 comment