Phỏng vấn vị trí lập trình NodeJS / NextJS


Dưới đây là danh sách 50 câu hỏi phỏng vấn chuyên sâu về NodeJS và NextJS, kèm theo lời giải chi tiết và code demo để bạn có thể chuẩn bị tốt nhất cho buổi phỏng vấn.


1. Event Loop trong NodeJS hoạt động như thế nào?

  • Lời giải: NodeJS là single-threaded nhưng có thể xử lý non-blocking I/O bằng cách chuyển các tác vụ nặng (file hệ thống, mạng) cho hệ điều hành hoặc Thread Pool. Event Loop có các pha chính: Timers, I/O Callbacks, Idle/Prepare, Poll, Check, và Close Callbacks.

  • Code Demo:

JavaScript
console.log('Start');
setTimeout(() => console.log('Timeout'), 0);
setImmediate(() => console.log('Immediate'));
process.nextTick(() => console.log('Next Tick'));
console.log('End');
// Thứ tự: Start -> End -> Next Tick -> Timeout -> Immediate

2. Phân biệt process.nextTick()setImmediate()?

  • Lời giải: process.nextTick() thực thi ngay sau khi hoạt động hiện tại kết thúc, trước khi Event Loop tiếp tục sang pha tiếp theo. setImmediate() được thực thi ở pha "Check" của Event Loop.

  • Code Demo:

JavaScript
setImmediate(() => console.log('Immediate'));
process.nextTick(() => console.log('Next Tick'));
// Next Tick luôn chạy trước Immediate

3. Stream trong NodeJS là gì? Có mấy loại?

  • Lời giải: Stream là cách xử lý dữ liệu lớn bằng cách chia nhỏ thành các "chunk" thay vì đọc toàn bộ vào bộ nhớ. Có 4 loại: Readable, Writable, Duplex (cả đọc và ghi), và Transform (thay đổi dữ liệu khi đọc/ghi).

  • Code Demo:

JavaScript
const fs = require('fs');
const readableStream = fs.createReadStream('largefile.txt');
const writableStream = fs.createWriteStream('output.txt');
readableStream.pipe(writableStream);

4. Middleware trong ExpressJS là gì?

  • Lời giải: Là các hàm có quyền truy cập vào đối tượng request (req), response (res) và hàm next() để chuyển tiếp sang middleware kế tiếp. Dùng để log, auth, parse data...

  • Code Demo:

JavaScript
app.use((req, res, next) => {
  console.log(`${req.method} ${req.url}`);
  next(); 
});

5. Làm thế nào để xử lý Uncaught Exceptions?

  • Lời giải: Sử dụng process.on('uncaughtException'). Tuy nhiên, tốt nhất là nên restart process vì ứng dụng lúc này có thể ở trạng thái không ổn định.

  • Code Demo:

JavaScript
process.on('uncaughtException', (err) => {
  console.error('Lỗi chưa được xử lý:', err);
  process.exit(1);
});

6. Cluster Module dùng để làm gì?

  • Lời giải: Cho phép tận dụng hệ thống đa nhân (multi-core) bằng cách tạo ra các worker processes con dùng chung cổng mạng.

  • Code Demo:

JavaScript
const cluster = require('cluster');
const http = require('http');
if (cluster.isMaster) {
  for (let i = 0; i < require('os').cpus().length; i++) cluster.fork();
} else {
  http.createServer((req, res) => res.end('Hello')).listen(8000);
}

7. Buffer trong NodeJS là gì?

  • Lời giải: Buffer là một vùng bộ nhớ tạm thời dùng để lưu trữ dữ liệu nhị phân thô, thường dùng khi làm việc với file hoặc stream.

  • Code Demo:

JavaScript
const buf = Buffer.from('Hello', 'utf8');
console.log(buf.toJSON()); // { type: 'Buffer', data: [ 72, 101, 108, 108, 111 ] }

8. Worker Threads là gì? Khác gì với Cluster?

  • Lời giải: Cluster tạo ra nhiều Process (tốn RAM hơn), còn Worker Threads chạy nhiều luồng trong cùng một Process (dùng chung bộ nhớ). Dùng Worker Threads cho các tác vụ tính toán nặng (CPU intensive).

  • Code Demo:

JavaScript
const { Worker, isMainThread } = require('worker_threads');
if (isMainThread) {
  new Worker(__filename);
} else {
  console.log('Chạy trong worker thread');
}

9. Giải thích cơ chế của EventEmitter?

  • Lời giải: Là core module cho phép các đối tượng phát ra (emit) các sự kiện có tên và đăng ký các hàm lắng nghe (listener).

  • Code Demo:

JavaScript
const EventEmitter = require('events');
const myEmitter = new EventEmitter();
myEmitter.on('greet', (name) => console.log('Hello ' + name));
myEmitter.emit('greet', 'Diep');

10. Tại sao nên dùng require thay vì import (hoặc ngược lại)?

  • Lời giải: require là CommonJS (đồng bộ, runtime), import là ES Modules (bất đồng bộ, compile-time). NodeJS hiện tại đã hỗ trợ tốt cả hai, nhưng ESM là tiêu chuẩn mới.

  • Code Demo:

JavaScript
// CommonJS
const fs = require('fs');
// ESM (cần "type": "module" trong package.json)
import fs from 'fs';

11. package-lock.json dùng để làm gì?

  • Lời giải: Đảm bảo tính nhất quán của các dependency tree giữa các môi trường cài đặt khác nhau bằng cách khóa chính xác phiên bản của từng sub-dependency.

12. Cách ngăn chặn Callback Hell?

  • Lời giải: Sử dụng Promises hoặc Async/Await.

  • Code Demo:

JavaScript
async function getData() {
  try {
    const res = await fetch('api/data');
    const data = await res.json();
    return data;
  } catch (err) { console.error(err); }
}

13. Phân biệt dependenciesdevDependencies?

  • Lời giải: dependencies là các gói cần để chạy app ở production. devDependencies chỉ cần cho quá trình phát triển (như nodemon, jest, typescript).

14. Làm thế nào để bảo mật ứng dụng Express?

  • Lời giải: Sử dụng thư viện helmet để thiết lập các HTTP headers bảo mật, giới hạn rate-limit, validate dữ liệu đầu vào.

  • Code Demo:

JavaScript
const helmet = require('helmet');
app.use(helmet());

15. Garbage Collection trong NodeJS hoạt động như thế nào?

  • Lời giải: V8 engine sử dụng thuật toán "Mark-and-Sweep". Nó đánh dấu các object còn tham chiếu và giải phóng những object không còn được truy cập từ gốc (root).

16. REPL trong NodeJS là gì?

  • Lời giải: Viết tắt của Read-Eval-Print Loop. Là môi trường dòng lệnh tương tác để chạy code JS trực tiếp (gõ lệnh node trên terminal).

17. Libuv là gì?

  • Lời giải: Là thư viện C++ giúp NodeJS xử lý các tác vụ bất đồng bộ (I/O, Thread pool). Nó là trái tim xử lý Event Loop.

18. NVM là gì? Tại sao nên dùng?

  • Lời giải: Node Version Manager. Giúp cài đặt và chuyển đổi giữa nhiều phiên bản Node trên cùng một máy tính dễ dàng.

19. Làm sao để đọc file lớn mà không làm treo app?

  • Lời giải: Sử dụng Stream thay vì fs.readFile.

  • Code Demo:

JavaScript
fs.createReadStream('big.file').on('data', (chunk) => {
  // xử lý từng phần
});

20. JWT (JSON Web Token) gồm những phần nào?

  • Lời giải: Gồm 3 phần phân tách bởi dấu chấm: Header (thuật toán), Payload (dữ liệu người dùng), Signature (chữ ký bảo mật).

21. module.exportsexports khác nhau thế nào?

  • Lời giải: module.exports là đối tượng thực sự được trả về. exports chỉ là một tham chiếu (reference) đến module.exports. Nếu bạn gán exports = {} thì nó sẽ mất tham chiếu.

22. Tại sao NodeJS không phù hợp cho tác vụ tính toán CPU nặng (như render video)?

  • Lời giải: Vì nó single-threaded. Tác vụ nặng sẽ block Event Loop, khiến các request khác không được xử lý. Giải pháp là dùng Worker Threads.

23. Cách quản lý biến môi trường trong Node?

  • Lời giải: Dùng gói dotenv và file .env.

  • Code Demo:

JavaScript
require('dotenv').config();
console.log(process.env.DB_URL);

24. Socket.io là gì?

  • Lời giải: Thư viện hỗ trợ giao tiếp hai chiều (bi-directional) thời gian thực giữa client và server dựa trên WebSockets.

25. Sự khác biệt giữa spawnexec trong child_process?

  • Lời giải: spawn trả về stream (dùng cho dữ liệu lớn), exec trả về buffer (đợi lệnh chạy xong mới trả kết quả, giới hạn dung lượng mặc định 200kb).


26. NextJS là gì? Tại sao nên dùng NextJS thay vì React thuần?

  • Lời giải: NextJS là Framework cho React hỗ trợ SSR, SSG, Routing tự động và Image Optimization. Giúp SEO tốt hơn và hiệu năng cao hơn.

27. Phân biệt SSR và SSG?

  • Lời giải:

    • SSR (Server-Side Rendering): Tạo HTML mỗi khi có request. Phù hợp dữ liệu thay đổi liên tục.

    • SSG (Static Site Generation): Tạo HTML một lần duy nhất lúc Build. Phù hợp blog, trang tin tức.

28. ISR (Incremental Static Regeneration) là gì?

  • Lời giải: Cho phép cập nhật trang tĩnh sau khi đã build mà không cần build lại toàn bộ site.

  • Code Demo:

JavaScript
export async function getStaticProps() {
  return {
    props: { data },
    revalidate: 60, // Cập nhật lại sau mỗi 60 giây
  };
}

29. App Router (Next 13+) khác gì Pages Router?

  • Lời giải: App Router sử dụng React Server Components, hỗ trợ lồng layout (nested layouts) và mặc định các component là Server Components.

30. Server Components là gì?

  • Lời giải: Là component chỉ render ở Server, không gửi JS về Client. Giúp giảm bundle size.

  • Code Demo:

JavaScript
// Mặc định là Server Component trong App Router
async function Page() {
  const data = await fetchData(); // Gọi DB trực tiếp được
  return <div>{data.title}</div>;
}

31. Khi nào dùng "use client"?

  • Lời giải: Khi component cần dùng React Hooks (useState, useEffect), dùng Browser API hoặc các sự kiện tương tác (onClick).

32. getStaticPaths dùng để làm gì?

  • Lời giải: Trong Pages Router, nó định nghĩa danh sách các dynamic routes (ví dụ /post/[id]) cần được render tĩnh lúc build.

33. Image Component trong NextJS có lợi ích gì?

  • Lời giải: Tự động resize ảnh theo thiết bị, lazy loading, và chống Cumulative Layout Shift (CLS).

  • Code Demo:

JavaScript
import Image from 'next/image';
<Image src="/logo.png" width={500} height={500} alt="Logo" />

34. Làm thế nào để fetch data trong App Router?

  • Lời giải: Dùng fetch trực tiếp trong Server Component với cú pháp async/await. NextJS mở rộng hàm fetch để hỗ trợ caching.

  • Code Demo:

JavaScript
const res = await fetch('https://api...', { cache: 'no-store' }); // Tương đương SSR

35. Middleware trong NextJS nằm ở đâu?

  • Lời giải: File middleware.ts nằm ở thư mục gốc. Dùng để xử lý logic trước khi request hoàn tất (auth, redirect).

36. Link component trong NextJS khác gì thẻ <a>?

  • Lời giải: Link hỗ trợ client-side chuyển trang mà không load lại trang và tự động pre-fetch code của trang đích.

37. SEO trong NextJS App Router xử lý như thế nào?

  • Lời giải: Sử dụng object metadata hoặc hàm generateMetadata.

  • Code Demo:

JavaScript
export const metadata = { title: 'Trang chủ', description: '...' };

38. Cấu trúc folder app/ cơ bản?

  • Lời giải: page.tsx (nội dung trang), layout.tsx (giao diện chung), loading.tsx (trạng thái chờ), error.tsx (xử lý lỗi).

39. Làm sao để tạo API Route trong NextJS?

  • Lời giải: Tạo file route.ts trong folder api/.

  • Code Demo:

JavaScript
export async function GET() {
  return Response.json({ message: 'Hello' });
}

40. NextJS tự động tối ưu Font như thế nào?

  • Lời giải: Sử dụng next/font. Nó tự động tải font về lúc build và phục vụ từ cùng domain để tránh request bên thứ 3 (Google Fonts).

41. Hydration là gì?

  • Lời giải: Là quá trình React ở Client "gắn" các sự kiện (event handlers) vào HTML tĩnh đã được server trả về để trang web có thể tương tác.

42. Làm thế nào để bắt lỗi Global trong NextJS?

  • Lời giải: Sử dụng file global-error.tsx ở cấp cao nhất của thư mục app/.

43. dynamic import trong NextJS dùng khi nào?

  • Lời giải: Để code-splitting, chỉ load component khi cần thiết (ví dụ: Modal hoặc đồ thị nặng).

  • Code Demo:

JavaScript
import dynamic from 'next/dynamic';
const HeavyComp = dynamic(() => import('./HeavyComponent'), { ssr: false });

44. Cách xử lý Authentication trong NextJS?

  • Lời giải: Phổ biến nhất là dùng NextAuth.js (Auth.js) hỗ trợ OAuth, Credentials, và Session Management.

45. Biến môi trường ở Client Side trong NextJS?

  • Lời giải: Phải có tiền tố NEXT_PUBLIC_. Ví dụ: NEXT_PUBLIC_API_KEY.

46. parallel routes là gì?

  • Lời giải: Cho phép render nhiều trang trong cùng một layout (ví dụ: Dashboard có cả bảng tin và tin nhắn cùng lúc). Sử dụng folder @slot.

47. intercepting routes là gì?

  • Lời giải: Cho phép load một route bên trong route hiện tại (ví dụ: click vào ảnh hiện Modal thay vì chuyển trang hoàn toàn).

48. Cache trong NextJS hoạt động như thế nào?

  • Lời giải: Có 4 tầng cache: Request Memoization, Data Cache, Full Route Cache, và Router Cache.

49. Làm thế nào để ép buộc một route luôn là Dynamic (không cache)?

  • Lời giải: Thêm export const dynamic = 'force-dynamic' vào file page hoặc layout.

50. Deployment NextJS ở đâu là tốt nhất?

  • Lời giải: Vercel (nhà sáng lập NextJS) là tốt nhất vì hỗ trợ full các tính năng như Edge Functions, ISR và tối ưu hóa ảnh tự động.

Phản hồi từ học viên

5

Tổng 0 đánh giá
Developer Toolbox

TEXT CASE

FORMAT & CLEAN

ENCODE & DECODE

JSON & CRYPTO

Đã sao chép!!!
Gozic - Hệ thống học lập trình, luyện thi, kiểm tra trắc nghiệm trực tuyến uy tín tại Việt Nam.
Hotline: 0967025996
Gozic - Hệ thống học lập trình, luyện thi, kiểm tra trắc nghiệm trực tuyến uy tín tại Việt Nam.