Intern — Node.js & Express Basics
For an intern backend or full-stack role, interviewers check that you know what Node.js is, how modules and npm work, the basics of HTTP and REST, and how to build a small Express API with routes, middleware and JSON. Explaining clearly what you built and why matters more than covering every feature.
1. What is Node.js?
Node.js is a JavaScript runtime that runs JavaScript outside the browser, built on Chrome's V8 engine. It's mainly used for servers, APIs, command-line tools and build tools. Its strength is handling many network connections at once with non-blocking, asynchronous I/O on a single thread.
2. How is Node.js different from JavaScript in the browser?
Both run the same language, but the environment differs. The browser gives you the DOM, window and web APIs, and runs code in a sandbox. Node gives you access to the file system, processes, network sockets and environment variables through modules like fs, path and http, but has no DOM. Both now share standard APIs such as fetch, URL and AbortController.
3. What is the V8 engine?
V8 is Google's open-source JavaScript engine, written in C++, used by Chrome and Node.js. It compiles JavaScript to fast machine code using just-in-time compilation and manages memory with a garbage collector. Node adds the system APIs and the event loop on top of V8.
4. What does it mean that Node.js is single-threaded and non-blocking?
Your JavaScript runs on one main thread, so only one piece of your code executes at a time. But slow operations like reading files or calling a database don't block that thread: Node starts them, keeps handling other requests, and runs your callback or resumes your await when the result is ready. That's why one Node process can serve thousands of concurrent connections.
5. What is npm, and what is package.json for?
npm is Node's package manager and the public registry of libraries. package.json describes your project: its name and version, the dependencies and dev dependencies it needs, and scripts like start, dev and test. Running npm install reads it and downloads everything into node_modules.
6. What is the difference between dependencies and devDependencies?
dependencies are needed when the app runs in production — Express, a database driver, a validation library. devDependencies are only needed while developing or building — test runners, linters, TypeScript, nodemon. In production you can install only the runtime ones with npm ci --omit=dev, which keeps the deployment smaller and safer.
7. What is the package-lock.json file for?
The lock file records the exact version of every package installed, including dependencies of dependencies. Committing it makes every developer, CI run and server install the same tree, so "it works on my machine" problems disappear. Use npm ci in CI to install strictly from the lock file.
8. What do the version numbers ^1.2.3 and ~1.2.3 mean?
Packages use semantic versioning: MAJOR.MINOR.PATCH. A caret ^1.2.3 allows minor and patch updates (1.x.x, below 2.0.0), which should be backwards compatible. A tilde ~1.2.3 allows only patch updates (1.2.x). An exact 1.2.3 pins the version completely.
9. What is the difference between CommonJS and ES modules in Node?
CommonJS uses require() and module.exports and was Node's original module system. ES modules use import and export, the JavaScript standard. Node treats .mjs files, or .js files when package.json has "type": "module", as ES modules. New projects usually use ES modules.
// CommonJSconst path = require("node:path");module.exports = { greet }; // ES modulesimport path from "node:path";export function greet(name) { return `Hello, ${name}`;}10. What are some core modules built into Node.js?
Node ships with modules you can use without installing anything; prefix them with node: to make that clear.
node:fs— read and write filesnode:path— build and parse file paths safelynode:http— create HTTP servers and clientsnode:events— the EventEmitter patternnode:crypto— hashing, random values and encryption
11. How do you read a file in Node.js?
Use the promise-based fs/promises API with await so the server isn't blocked while the file is read. The synchronous readFileSync is fine in a startup script, but in a request handler it blocks every other request.
import { readFile } from "node:fs/promises"; try { const text = await readFile("./data/users.json", "utf8"); const users = JSON.parse(text); console.log(users.length, "users");} catch (err) { console.error("Could not read users:", err.message);}12. Why should you use the path module instead of joining strings?
File paths differ between operating systems — Windows uses backslashes, macOS and Linux use slashes. path.join and path.resolve build correct paths for the current system and handle extra or missing separators. For ES modules, import.meta.dirname gives you the current file's folder.
13. What is the process object?
process is a global object that describes the running Node program. It gives you environment variables (process.env), command-line arguments (process.argv), the working directory (process.cwd()), memory usage, and events like exit and SIGTERM. process.exit(code) ends the program with a status code.
14. How do you use environment variables in a Node app?
Read configuration from process.env — the port, database URL, API keys — instead of hard-coding it. Locally you can keep them in a .env file and load it with node --env-file=.env app.js (built into modern Node) or the dotenv package. Never commit .env files with real secrets to Git.
15. What is a callback, and what is callback hell?
A callback is a function passed to an asynchronous operation and called when it finishes. Node's older APIs use error-first callbacks: (err, result) => {}. When several async steps depend on each other, callbacks nest deeper and deeper — "callback hell" — making code hard to read and errors easy to miss. Promises and async/await solve this.
16. How do Promises and async/await help in Node?
A Promise represents a future result, and async/await lets you write asynchronous code that reads top to bottom, with normal try/catch for errors. Most Node APIs have promise versions (fs/promises, timers/promises), and you can wrap old callback functions with util.promisify.
17. What is the event loop, in simple terms?
The event loop is the mechanism that lets single-threaded Node handle many tasks. When an async operation such as a database query finishes, its callback is placed in a queue. The event loop keeps picking callbacks from the queues and running them whenever the main thread is free. If your code runs a long synchronous loop, the event loop can't run anything else until it finishes.
18. What is the EventEmitter?
EventEmitter from node:events lets objects emit named events and lets other code listen for them with on. Many Node objects are emitters — HTTP servers, streams, process. It's a simple way to decouple code: one part announces that something happened, others react.
import { EventEmitter } from "node:events"; const orders = new EventEmitter();orders.on("created", (order) => { console.log("Send email for order", order.id);});orders.emit("created", { id: 42 });19. How do you create a basic HTTP server without Express?
Use http.createServer with a function that receives the request and response. It works, but you have to parse URLs, bodies and routes yourself — which is why frameworks like Express exist.
import http from "node:http"; const server = http.createServer((req, res) => { res.writeHead(200, { "Content-Type": "application/json" }); res.end(JSON.stringify({ message: "Hello from Node" }));}); server.listen(3000, () => console.log("Listening on :3000"));20. What is Express.js and why use it?
Express is a minimal web framework for Node. It adds routing by method and path, a middleware system, helpers to read requests and send responses (res.json, res.status), and a huge ecosystem of middleware for things like CORS, sessions and security headers. It stays small and lets you choose the rest of your stack.
21. How do you create a basic Express app?
Install express, create an app, add middleware and routes, and start listening on a port. express.json() parses JSON request bodies so they appear on req.body.
import express from "express"; const app = express();app.use(express.json()); app.get("/", (req, res) => { res.json({ status: "ok" });}); const port = process.env.PORT ?? 3000;app.listen(port, () => console.log(`API on port ${port}`));22. What is routing in Express?
Routing maps an HTTP method and a path to the function that handles it: app.get("/users", ...), app.post("/users", ...), app.delete("/users/:id", ...). Express checks routes in the order they were added and runs the first one that matches. Routes that don't match anything fall through to a 404 handler.
23. What are route parameters and query strings?
Route parameters are named parts of the path, like :id in /users/:id, available on req.params. Query strings are the optional key-value pairs after ?, like /users?page=2&limit=20, available on req.query. Both arrive as strings, so convert and validate them before use.
// GET /users/42?include=postsapp.get("/users/:id", (req, res) => { const id = Number(req.params.id); // 42 const include = req.query.include; // "posts" res.json({ id, include });});24. What is the difference between req and res?
req (request) holds everything the client sent: method, URL, params, query, headers, cookies and body. res (response) is how you answer: res.status(201), res.json(data), res.send(text), res.redirect(url) and setting headers. Every request must end with exactly one response.
25. What is middleware in Express?
Middleware is a function (req, res, next) that runs during a request, before the final route handler. It can read or change the request, end the response, or call next() to pass control on. Logging, parsing JSON, authentication, CORS and rate limiting are all middleware.
function logger(req, res, next) { const start = Date.now(); res.on("finish", () => { console.log(req.method, req.url, res.statusCode, `${Date.now() - start}ms`); }); next();} app.use(logger);26. What does next() do?
next() tells Express to move to the next matching middleware or route handler. If a middleware neither sends a response nor calls next(), the request hangs until it times out. Calling next(err) with an error skips normal handlers and jumps to the error-handling middleware.
27. How do you parse a JSON request body?
Add the built-in express.json() middleware before your routes. It reads requests with a Content-Type: application/json header, parses the body and puts it on req.body. For HTML form posts, use express.urlencoded(). You can set a size limit, such as express.json({ limit: "100kb" }), to protect the server.
28. How do you send JSON with a status code?
Chain res.status(code) with res.json(data). Choose a status that matches the result: 200 for success, 201 when something was created, 204 for success with no body, 400 for invalid input, 401 when not logged in, 403 when not allowed, 404 when not found and 500 for unexpected server errors.
app.post("/users", async (req, res) => { if (!req.body.email) { return res.status(400).json({ error: "Email is required" }); } const user = await createUser(req.body); res.status(201).json(user);});29. How do you serve static files with Express?
Use express.static with a folder: app.use(express.static("public")) serves public/logo.png at /logo.png. It handles caching headers and content types for you. In production, static files are often served by a CDN or a reverse proxy like Nginx instead, which is faster.
30. What is REST?
REST is a style for designing APIs around resources identified by URLs, using HTTP methods for actions: GET /users lists users, POST /users creates one, GET /users/42 reads one, PATCH /users/42 updates part of it and DELETE /users/42 removes it. Responses use standard status codes and are stateless — each request carries everything the server needs.
31. What do the HTTP methods GET, POST, PUT, PATCH and DELETE mean?
Each method states the intent of the request.
- GET — read data; must not change anything
- POST — create a resource or trigger an action
- PUT — replace a resource completely
- PATCH — update part of a resource
- DELETE — remove a resource
32. What is JSON, and why is it used in APIs?
JSON (JavaScript Object Notation) is a lightweight text format for structured data: objects, arrays, strings, numbers, booleans and null. It's easy for humans to read and every language can parse it, so it's the default format for web APIs. In Node, JSON.stringify and JSON.parse convert between JSON text and JavaScript values.
33. What is CORS, and how do you enable it in Express?
CORS is a browser security rule: a web page can only read responses from another origin if that server allows it with headers like Access-Control-Allow-Origin. In Express, the cors middleware sets these headers. Allow only the origins you trust, such as your front-end URL, rather than * for APIs that use cookies.
import cors from "cors"; app.use( cors({ origin: ["https://myapp.com"], credentials: true, }),);34. How do you handle a 404 for unknown routes in Express?
Add a middleware after all your routes. If a request reaches it, no route matched, so it responds with 404. Keep it before the error-handling middleware.
// after all routesapp.use((req, res) => { res.status(404).json({ error: `Not found: ${req.method} ${req.path}` });});35. What is error-handling middleware in Express?
It's middleware with four arguments: (err, req, res, next). Express calls it when a route calls next(err) or throws — and in Express 5, also when an async handler's promise rejects. Put it last, log the error and send a safe message without leaking stack traces to clients.
app.use((err, req, res, next) => { console.error(err); const status = err.status ?? 500; res.status(status).json({ error: status === 500 ? "Something went wrong" : err.message, });});36. What is express.Router and why use it?
express.Router() creates a mini app with its own routes and middleware. You group related routes in separate files — users, orders, auth — and mount them with a prefix, like app.use("/api/users", usersRouter). It keeps a growing API organised.
// routes/users.jsimport { Router } from "express";export const usersRouter = Router(); usersRouter.get("/", listUsers);usersRouter.get("/:id", getUser);usersRouter.post("/", createUser); // app.jsapp.use("/api/users", usersRouter);37. What is nodemon, and does modern Node need it?
nodemon restarts your Node app automatically whenever you save a file, which speeds up development. Modern Node has this built in: node --watch app.js restarts on file changes. Neither should be used in production.
38. How do you connect an Express app to a database?
Install a driver or library for your database — pg for PostgreSQL, mongodb or Mongoose for MongoDB, or an ORM like Prisma or Drizzle. Create one connection or connection pool when the app starts, reuse it in every request, and read the connection string from an environment variable. Handle connection errors and close the pool on shutdown.
39. What is the difference between SQL and NoSQL databases?
SQL databases (PostgreSQL, MySQL) store data in tables with a fixed schema and relationships, and use SQL for powerful queries and transactions. NoSQL databases (MongoDB, Redis, DynamoDB) use other models — documents, key-value pairs — with more flexible schemas and easy horizontal scaling. Choose based on your data's shape and the queries you need.
40. What is Mongoose?
Mongoose is an ODM (object-document mapper) for MongoDB in Node. You define schemas with types and validation, create models from them, and use methods like find, create and updateOne. It adds structure, validation and helpers like population on top of the plain MongoDB driver.
41. Why must you never store passwords in plain text?
If the database leaks, every user's password — often reused on other sites — is exposed. Store only a slow, salted hash made with a password-hashing algorithm such as bcrypt or argon2. At login, hash the attempt and compare. Never use fast hashes like MD5 or SHA-256 alone for passwords.
42. How do you validate input in an Express API?
Never trust req.body, req.params or req.query. Check that the required fields exist and have the right type and format before using them, and return a 400 with a clear message when they don't. Libraries like Zod or Joi let you describe the expected shape once and validate it in one line.
43. What is a status code 500 and how do you avoid sending it for user mistakes?
500 means an unexpected error on the server. It should be rare and always investigated. When the client did something wrong — missing field, bad ID, unknown resource — respond with a 4xx code and a helpful message instead, so the client knows how to fix the request and your monitoring isn't flooded.
44. How do you test an API endpoint manually?
Use a tool that sends HTTP requests: curl in the terminal, Postman, Insomnia, Bruno or the REST client in your editor. Set the method, URL, headers like Content-Type: application/json and a body, then check the status code and response. Save the requests in a collection so teammates can reuse them.
45. What are logging basics for a Node app?
Log useful events — the server starting, each request with method, path, status and duration, and every error with its stack. Use levels (info, warn, error) so you can filter. console.log is fine for learning; real apps use a structured logger such as pino. Never log passwords, tokens or personal data.
46. How do you run a Node app with npm scripts?
Define commands in the scripts section of package.json, such as "dev": "node --watch --env-file=.env src/server.js" and "start": "node src/server.js", then run npm run dev or npm start. Scripts give everyone on the team the same commands and can chain tools like tests and linting.
47. What is the difference between setTimeout, setImmediate and process.nextTick?
process.nextTick runs a callback right after the current operation, before any I/O or timers. setImmediate runs it in the "check" phase of the event loop, after I/O callbacks. setTimeout(fn, 0) runs it after at least the given delay, in the timers phase. Overusing nextTick can starve I/O, so prefer promises or setImmediate.
48. Can Node.js run TypeScript?
Yes. Modern Node versions can run .ts files directly by stripping type annotations, as long as you use only erasable TypeScript syntax. Many projects still compile with tsc, or use runners like tsx, and run tsc --noEmit in CI for type checking, because Node itself doesn't check types.
49. How do you deploy a simple Node and Express API?
Pick a platform such as Railway, Render, Fly.io or a VPS. Set environment variables there, make sure the app listens on process.env.PORT, install with npm ci --omit=dev and start with node (not nodemon). Add a health-check route, put HTTPS in front, and keep secrets out of the repository.
50. Tell me about a small Node or Express project you built.
Pick one real project and explain it briefly: what the API does, the main routes and data model, how you handled validation and errors, how it connects to a database, one problem you solved, and what you'd improve. Have the repository or a deployed URL ready — a small, clean, working API you can explain beats a big unfinished one.
Mid-Level — Building Production APIs
Mid-level interviews expect you to build and run a real API on your own: the event loop and streams, structuring an Express codebase, authentication, validation, databases, testing and error handling. Interviewers look for practical judgement — why you chose an approach and what can go wrong with it.
51. Describe the phases of the Node.js event loop.
Each turn of the event loop moves through phases in order.
- timers — callbacks from
setTimeoutandsetIntervalwhose time has come - pending callbacks — some deferred system I/O callbacks
- poll — wait for and run I/O callbacks (most of your work happens here)
- check —
setImmediatecallbacks - close callbacks — e.g. a socket's
closeevent; between every callback,process.nextTickand promise microtasks run
52. What is libuv, and what is the thread pool used for?
libuv is the C library under Node that implements the event loop and asynchronous I/O. Network I/O uses the operating system's non-blocking mechanisms, but some work can't be done that way — file system calls, DNS lookups with dns.lookup, some crypto and zlib functions — so libuv runs it on a small thread pool (4 threads by default, set with UV_THREADPOOL_SIZE).
53. How do microtasks and process.nextTick fit into the event loop?
After each callback finishes, Node empties the process.nextTick queue first, then the promise microtask queue, before moving on. So nextTick callbacks run before resolved promises, and both run before timers or I/O. A recursive nextTick or endless chain of microtasks can starve the event loop.
setTimeout(() => console.log("timeout"), 0);setImmediate(() => console.log("immediate"));Promise.resolve().then(() => console.log("promise"));process.nextTick(() => console.log("nextTick"));console.log("sync");// sync, nextTick, promise, then timeout/immediate54. What does it mean to block the event loop, and how do you avoid it?
Blocking means running long synchronous work — a big loop, a huge JSON.parse, a synchronous crypto or file call, a catastrophic regular expression — so the single thread can't serve other requests. Keep request handlers asynchronous, paginate and stream large data, use async versions of APIs, and move CPU-heavy work to worker threads or a background job.
55. What are streams in Node.js?
Streams process data piece by piece instead of loading it all into memory. There are four types: Readable (a file being read, an HTTP request), Writable (a file being written, an HTTP response), Duplex (a TCP socket) and Transform (gzip compression). They let you handle files and responses of any size with constant memory.
56. What is backpressure, and how does pipeline handle it?
Backpressure happens when data arrives faster than the destination can write it; without handling it, memory fills up. Writable streams signal this by returning false from write(). stream.pipeline connects streams, pauses the source when the destination is full, and forwards errors and cleans up every stream if any of them fails.
import { pipeline } from "node:stream/promises";import { createReadStream, createWriteStream } from "node:fs";import { createGzip } from "node:zlib"; await pipeline( createReadStream("access.log"), createGzip(), createWriteStream("access.log.gz"),);57. What is a Buffer?
A Buffer is Node's type for raw binary data — a fixed-size chunk of bytes outside the V8 heap. You get Buffers when reading files without an encoding, from network sockets and from crypto functions. Convert with buf.toString("utf8") or Buffer.from(text, "utf8"), and be careful to decode multi-byte text correctly at chunk boundaries.
58. How would you send a large file to a client efficiently?
Stream it rather than reading it into memory: pipe a read stream into the response, or use res.sendFile / res.download, which stream and set headers for you. Set Content-Type and Content-Disposition, support range requests for media, and for big public files consider redirecting to a signed URL on object storage such as S3.
59. How does middleware order matter in Express?
Express runs middleware and routes in the order they are registered, so order is behaviour. Body parsers must come before routes that read req.body, authentication before the routes it protects, CORS and security headers early, the 404 handler after all routes and the error handler last. A misplaced app.use is a common source of bugs.
60. How does error handling for async code work in Express 5 versus Express 4?
In Express 4, a rejected promise in an async handler was not caught: you had to wrap handlers or call next(err) yourself, or the request hung. Express 5 catches rejected promises and thrown errors in async handlers and middleware automatically and passes them to your error handler, so you can simply throw or let await reject.
// Express 5: no wrapper neededapp.get("/users/:id", async (req, res) => { const user = await db.users.findById(req.params.id); if (!user) throw new NotFoundError("User not found"); res.json(user);});61. What changed in route path syntax in Express 5?
Express 5 uses a newer path-to-regexp, so some patterns changed. Wildcards must be named — /*splat instead of /* — and they capture segments as an array. Optional parts use braces, like /:file{.:ext}, instead of ?. Regular-expression characters inside path strings are no longer supported, and req.query is now read-only.
62. How would you structure a medium-sized Express project?
Separate layers so each has one job: routes declare endpoints, controllers translate HTTP to function calls, services hold business logic, and repositories or data-access modules talk to the database. Group code by feature (users/, orders/), keep config and the app setup separate from server.js so tests can import the app without starting a server.
63. What is the difference between authentication and authorisation?
Authentication answers "who are you?" — verifying identity with a password, token or OAuth login. Authorisation answers "what are you allowed to do?" — checking permissions such as roles or ownership of a resource. A request can be authenticated but still forbidden: that's a 403, whereas missing or invalid credentials is a 401.
64. How does JWT authentication work?
After login, the server signs a JSON Web Token containing claims like the user ID and an expiry, and gives it to the client. The client sends it on later requests, usually in an Authorization: Bearer header or a cookie, and the server verifies the signature instead of looking up a session. Keep tokens short-lived, never put secrets in the payload (it's only encoded, not encrypted), and plan for refresh and revocation.
65. Sessions or JWTs — how do you choose?
Server-side sessions store state in a store like Redis and give the browser an opaque ID cookie; they're easy to revoke and simple for web apps. JWTs are self-contained, so services can verify them without a shared store, which suits APIs and microservices, but they're hard to revoke before they expire. Many web apps use sessions; many APIs use short-lived JWTs plus refresh tokens.
66. How should a web app store authentication tokens?
For browser apps, prefer an HttpOnly, Secure, SameSite cookie set by the server: JavaScript can't read it, so an XSS bug can't steal it. Tokens in localStorage are readable by any injected script. If you use cookies, protect state-changing requests against CSRF with SameSite and, where needed, CSRF tokens.
67. How do you hash passwords correctly in Node?
Use a slow, salted password-hashing function — bcrypt or argon2 — with a cost factor tuned so hashing takes tens of milliseconds. Hash with the library's async function so the event loop isn't blocked, and compare with its verify function, which is safe against timing attacks. Re-hash when you raise the cost factor.
import bcrypt from "bcrypt"; export async function hashPassword(plain) { return bcrypt.hash(plain, 12);} export async function checkPassword(plain, hash) { return bcrypt.compare(plain, hash);}68. How do you validate requests in Express with a schema?
Describe the expected body, params and query with a schema library such as Zod, and validate in a small middleware before the controller runs. On failure, respond with 400 and the list of problems. On success, replace the raw input with the parsed, typed value so the controller only sees clean data.
import { z } from "zod"; const CreateUser = z.object({ email: z.string().email(), name: z.string().min(1).max(80),}); const validate = (schema) => (req, res, next) => { const result = schema.safeParse(req.body); if (!result.success) { return res.status(400).json({ errors: result.error.issues }); } req.body = result.data; next();}; app.post("/users", validate(CreateUser), createUser);69. How do you design a consistent error response format?
Pick one shape and use it everywhere, for example { error: { code, message, details } }, or the RFC 9457 Problem Details format. Use stable machine-readable codes like VALIDATION_FAILED alongside human messages, include a request ID for support, and never include stack traces or internal details in production responses.
70. How do you implement pagination in an API?
Offset pagination (?page=3&limit=20) is simple and lets users jump to a page, but it gets slow on large tables and can skip or repeat rows when data changes. Cursor pagination (?after=<lastId>&limit=20) uses an indexed column, stays fast and is stable for feeds and infinite scroll. Always cap the limit and return the next cursor or total as metadata.
71. What is the N+1 query problem?
It's when code runs one query to fetch a list and then one more query for each item — 1 query for 50 posts plus 50 queries for their authors. It's slow and overloads the database. Fix it with a join, an IN (...) batch query, the ORM's eager loading (include, populate), or a DataLoader that batches lookups.
72. Why use a database connection pool?
Opening a database connection is slow, and databases allow a limited number of connections. A pool keeps a set of open connections and lends them to requests, returning them when the query finishes. Create one pool per process at startup, size it to what the database can handle across all instances, and always release connections, even on errors.
73. What are database transactions, and when do you need them?
A transaction groups several writes so they either all succeed or all roll back — for example, deducting stock and creating an order together. Use them whenever a business operation touches multiple rows or tables that must stay consistent. Keep transactions short, and handle conflicts or deadlocks with retries.
74. How do you prevent SQL and NoSQL injection?
Never build queries by concatenating user input. Use parameterised queries or an ORM/query builder that parameterises for you. For MongoDB, validate input types so an attacker can't send objects like { "$gt": "" } where you expect a string, and avoid passing raw request objects straight into queries.
// unsafe: string concatenation// db.query(`SELECT * FROM users WHERE email = '${email}'`) // safe: parameterisedconst { rows } = await pool.query( "SELECT id, email FROM users WHERE email = $1", [email],);75. Which security middleware would you add to an Express app?
A few well-known packages cover the basics.
helmet— sets secure HTTP headerscors— allows only trusted originsexpress-rate-limit— limits requests per client to slow brute force and abuse- Body size limits on
express.json()to block huge payloads - A validation layer (Zod, Joi) for every input
76. How do you add rate limiting?
Use middleware such as express-rate-limit to cap requests per IP or per user in a time window, and return 429 Too Many Requests with a Retry-After header when exceeded. Apply stricter limits to sensitive routes like login and password reset. With several server instances, store the counters in Redis so the limit is shared.
77. How do you use caching to speed up an API?
Cache at the right layer: HTTP caching headers (Cache-Control, ETag) for public responses, an in-memory or Redis cache for expensive queries, and a CDN in front of public endpoints. Define how entries expire and are invalidated when data changes — stale caches are a common source of bugs.
78. What is the cache-aside pattern?
The application checks the cache first; on a miss it reads from the database, stores the result in the cache with an expiry, and returns it. On writes, it updates the database and deletes or updates the cache entry. It's simple and the most common pattern with Redis.
async function getProduct(id) { const key = `product:${id}`; const cached = await redis.get(key); if (cached) return JSON.parse(cached); const product = await db.products.findById(id); await redis.set(key, JSON.stringify(product), { EX: 300 }); return product;}79. How do you handle file uploads in Express?
Use middleware like multer (or busboy) to parse multipart/form-data. Limit file size and count, check the real file type rather than trusting the extension, generate your own file names, and store files on object storage (S3, GCS) instead of the server's disk. For large files, let the client upload directly to storage with a pre-signed URL.
80. What is the difference between unit, integration and end-to-end tests for an API?
Unit tests check one function in isolation, such as a service with its dependencies mocked. Integration tests check pieces together — a route with the real database in a test container. End-to-end tests run the deployed system through realistic flows. For APIs, integration tests on routes give the most confidence per test.
81. How do you test Express routes?
Export the app without calling listen, then use Supertest to send requests to it in your test runner (Vitest, Jest or Node's built-in node:test). Use a real test database, reset it between tests, and assert on status codes and response bodies.
import request from "supertest";import { test } from "node:test";import assert from "node:assert/strict";import { app } from "../src/app.js"; test("POST /users rejects a missing email", async () => { const res = await request(app).post("/users").send({ name: "Aye" }); assert.equal(res.status, 400);});82. What is Node's built-in test runner?
Modern Node includes node:test and node:assert, so you can write and run tests with node --test and no extra dependencies. It supports describe/it, hooks, mocking, subtests, watch mode and coverage. Many teams still use Vitest or Jest for their ecosystem, but the built-in runner is great for libraries and small services.
83. How do you manage configuration across environments?
Read all config from environment variables, validate it once at startup with a schema, and fail fast if anything is missing or invalid. Export a typed config object instead of reading process.env all over the code. Keep separate values per environment (development, staging, production) in the platform's secret manager, not in the repository.
84. What is structured logging, and why use it?
Structured logging writes each log line as JSON with fields — level, time, message, request ID, user ID, duration — instead of free text. Log tools can then search, filter and aggregate them. Libraries like pino are fast and add request logging middleware; include a correlation ID on every log line of a request.
85. What are the uses of the cluster module?
One Node process uses one CPU core for JavaScript. The cluster module forks several worker processes that share the same server port, so a machine with 8 cores can run 8 workers. Today, process managers (PM2) or containers with several replicas usually do this job instead, but the idea is the same: run one process per core.
86. What are worker threads, and when would you use them?
worker_threads run JavaScript in parallel threads inside the same process, each with its own event loop, communicating by messages or shared memory. Use them for CPU-heavy tasks — image processing, parsing, hashing large data — that would otherwise block the event loop. For I/O-bound work they don't help; async I/O is already efficient.
87. How do you handle uncaught exceptions and unhandled promise rejections?
Treat them as bugs: catch errors where they happen. As a last line of defence, listen for uncaughtException and unhandledRejection, log the error with full detail, and then shut down the process gracefully — the app may be in an unknown state. Let a process manager or orchestrator restart it.
88. What is graceful shutdown, and how do you implement it?
On SIGTERM (sent when a container or deploy stops the app), stop accepting new connections, let in-flight requests finish, close database pools and queues, then exit. Add a timeout so a stuck request can't block shutdown forever. This avoids dropped requests during deploys.
const server = app.listen(port); process.on("SIGTERM", () => { server.close(async () => { await db.end(); process.exit(0); }); setTimeout(() => process.exit(1), 10_000).unref();});89. How do you version an API?
The most common approach is a version in the URL path (/v1/users), which is explicit and easy to route. Alternatives are a header or media type. Whichever you choose, avoid breaking changes inside a version: add fields rather than renaming or removing them, deprecate with warnings and dates, and support the old version long enough for clients to move.
90. What are WebSockets, and how do they differ from HTTP?
HTTP is request–response: the client asks, the server answers. A WebSocket is a long-lived, two-way connection where either side can send messages at any time, ideal for chat, live dashboards and multiplayer features. In Node you can use ws or Socket.IO, which adds rooms, reconnection and fallbacks.
91. When would you choose Server-Sent Events over WebSockets?
Server-Sent Events send a one-way stream of events from server to client over normal HTTP. They're simpler than WebSockets, reconnect automatically and work well with proxies — great for notifications, progress updates and AI-style token streaming. If the client also needs to send frequent messages, use WebSockets.
92. Why use background jobs and queues?
Some work shouldn't happen inside a request: sending emails, generating PDFs, resizing images, calling slow third-party APIs. Put a job on a queue (BullMQ with Redis, SQS, RabbitMQ) and process it in a separate worker, with retries and backoff. The API responds quickly and failures can be retried without the user waiting.
93. How do you schedule recurring tasks in Node?
For simple cases, libraries like node-cron run functions on a cron schedule inside a process — but with several instances, every instance runs the task. Prefer a job queue with repeatable jobs (BullMQ), the platform's scheduled jobs, or a distributed lock so a task runs exactly once per schedule.
94. What is the difference between PUT and PATCH, and what is idempotency?
PUT replaces the whole resource with what you send; PATCH changes only the fields you send. Idempotent means repeating the request has the same effect as doing it once: GET, PUT and DELETE are idempotent, POST is not. For POST operations like payments, accept an idempotency key header so retries don't create duplicates.
95. How do you make outgoing HTTP calls from Node?
Modern Node has a global fetch built on undici, so you rarely need axios. Always set a timeout with AbortSignal.timeout(ms), check res.ok, handle errors, and retry only idempotent requests with backoff. Reuse connections (keep-alive is on by default in undici) for performance.
const res = await fetch("https://api.example.com/rates", { signal: AbortSignal.timeout(3000), headers: { Accept: "application/json" },});if (!res.ok) throw new Error(`Rates API failed: ${res.status}`);const rates = await res.json();96. How do you document an API?
Describe it with an OpenAPI specification — endpoints, parameters, request and response schemas, errors and authentication — and serve interactive docs with Swagger UI, Redoc or Scalar. Generating the spec from your validation schemas (for example Zod) keeps docs and code in sync. Add examples for every endpoint.
97. How do you use TypeScript in a Node and Express project?
Type your request bodies, params and responses, your services and config. Install @types/express, enable strict mode, and derive types from validation schemas so runtime checks and types agree. Run with a compiler or type-stripping runtime in development, run tsc --noEmit in CI, and build to JavaScript or run type-stripped code in production.
98. How do you containerise a Node app with Docker?
Use an official slim Node image, copy package.json and the lock file first and run npm ci --omit=dev so dependency layers are cached, then copy the source. Use a multi-stage build when compiling TypeScript, run as the non-root node user, set NODE_ENV=production, and start with node directly so it receives shutdown signals.
99. How do you keep a Node project's dependencies up to date and secure?
Keep the dependency list short, commit the lock file and install with npm ci. Run npm audit (or a tool like Snyk) in CI, and let Renovate or Dependabot open small update pull requests that your tests verify. Review new packages before adding them — maintenance activity, downloads, install scripts — to reduce supply-chain risk, and stay on a supported Node LTS version.
100. How do you debug a Node.js application?
Start with good logs and reproduce the problem. For step-by-step debugging, run node --inspect and attach Chrome DevTools or your editor's debugger to set breakpoints and inspect variables. For performance, use --cpu-prof or the DevTools profiler; for memory, take heap snapshots and compare them.
Senior — Performance, Reliability & Architecture
Senior Node.js interviews dig into how the runtime behaves under load and how you design services that stay fast, secure and observable in production: profiling and memory, scaling and concurrency, data consistency, security, architecture boundaries and operations. Good answers explain the mechanism, the trade-offs and how you would measure the result.
101. How do you find and fix a CPU bottleneck in a Node service?
Reproduce the load, then profile: run with --cpu-prof or attach the DevTools profiler and read the flame graph to see which functions use the most time. Common culprits are synchronous JSON work on large payloads, heavy regular expressions, crypto or compression on the main thread and inefficient loops. Fix the hot path, move CPU-heavy work to worker threads or a job, and measure again.
102. How do you diagnose a memory leak in Node.js?
Watch heap usage over time in monitoring; a leak shows memory that grows and never returns after garbage collection. Take heap snapshots a few minutes apart under load and compare them to find object types that keep growing, then follow their retainers. Typical causes are unbounded caches or maps, listeners never removed, closures holding large objects, timers never cleared and global arrays of requests.
103. How does garbage collection work in V8?
V8 uses generational garbage collection. New objects go into the small young generation, which is collected often and quickly by copying survivors. Objects that survive several collections are promoted to the old generation, collected less often with mark-sweep-compact, mostly concurrently. Allocating many short-lived objects is cheap; holding references longer than needed keeps memory alive.
104. How do you set Node's memory limits in containers?
V8 sizes its heap from available memory, but the container limit and the heap limit should be aligned: set --max-old-space-size to roughly 70–80% of the container's memory so the process garbage-collects before the kernel kills it. Remember memory outside the heap — Buffers, native modules, thread stacks — and monitor resident memory, not only heap size.
105. What is event loop lag, and how do you measure it?
Event loop lag is how long callbacks wait before they can run because the thread is busy. High lag means every request gets slower. Measure it with perf_hooks.monitorEventLoopDelay() or your APM, export it as a metric with percentiles, and alert when p99 rises. It's often the first sign of blocking code or CPU saturation.
import { monitorEventLoopDelay } from "node:perf_hooks"; const histogram = monitorEventLoopDelay({ resolution: 20 });histogram.enable(); setInterval(() => { const p99 = histogram.percentile(99) / 1e6; // ns → ms metrics.gauge("event_loop_lag_p99_ms", p99); histogram.reset();}, 10_000).unref();106. How do you scale a Node.js API horizontally?
Keep instances stateless — no sessions, uploads or caches that must live in one process — and put shared state in Redis, the database or object storage. Run several instances behind a load balancer, one process per CPU core, and scale the number of replicas on CPU, latency or queue depth. Make sure the database and other dependencies can handle the extra connections.
107. What is the difference between concurrency and parallelism in Node?
Concurrency means many tasks are in progress at once; Node does this on one thread by interleaving work while waiting on I/O. Parallelism means tasks literally run at the same time on several cores, which in Node requires multiple processes (cluster, replicas) or worker threads. I/O-bound services scale through concurrency; CPU-bound work needs parallelism.
108. How do you limit concurrency when calling external services?
Firing thousands of requests at once with Promise.all can exhaust sockets, memory or the other service's rate limit. Process items in batches or with a concurrency limiter (such as p-limit), respect the remote rate limit, and add timeouts. For large or ongoing workloads, push items onto a queue with a fixed number of workers.
import pLimit from "p-limit"; const limit = pLimit(10); // at most 10 requests at a timeconst results = await Promise.all( userIds.map((id) => limit(() => fetchProfile(id))),);109. How do you design for failure when calling other services?
Assume every dependency can be slow or down. Set timeouts on every call, retry only idempotent operations with exponential backoff and jitter, and use a circuit breaker to stop hammering a failing service. Degrade gracefully — serve cached data or a partial response — and use bulkheads so one slow dependency can't consume all your connections.
110. What is a circuit breaker?
A circuit breaker wraps calls to a dependency and tracks failures. When failures pass a threshold it "opens" and fails fast for a while instead of waiting on timeouts; then it lets a few trial requests through ("half-open") and closes again if they succeed. It protects your service's resources and gives the failing service time to recover. Libraries like opossum implement it.
111. How do you make an API endpoint idempotent?
Accept an Idempotency-Key header on operations like payments or order creation. Store the key with the result the first time; if the same key arrives again, return the stored result instead of repeating the work. Use a unique constraint or atomic insert so two concurrent requests with the same key can't both succeed.
112. How do you keep data consistent across a database write and a message publish?
Writing to the database and then publishing an event can fail halfway, leaving them out of sync. The transactional outbox pattern fixes this: write the business change and an outbox row in the same transaction, then a separate process reads the outbox and publishes the events, marking them sent. Consumers must be idempotent because events can be delivered more than once.
113. What delivery guarantees do message queues give, and how do you handle duplicates?
Most queues offer at-least-once delivery: a message is redelivered if the consumer crashes before acknowledging it, so duplicates happen. Exactly-once is rarely available end to end. Make consumers idempotent — track processed message IDs or use natural unique keys — acknowledge only after the work is committed, and send repeatedly failing messages to a dead-letter queue.
114. How do you design a reliable background job system in Node?
Use a durable queue (BullMQ with Redis, SQS, RabbitMQ) and separate worker processes. Give jobs IDs, retries with backoff, timeouts and a dead-letter destination; make handlers idempotent; limit concurrency per worker; and expose metrics on queue depth, failures and processing time. Deploy workers separately so heavy jobs can't slow the API.
115. How would you structure a large Node.js codebase?
Organise by business domain (modules such as billing, catalog, identity) rather than by technical layer, with clear public interfaces between modules. Inside each, keep HTTP handling, business logic and data access separate, and make dependencies point inwards so business rules don't depend on Express or the database. Enforce module boundaries with lint rules and keep the app composable for tests.
116. What is dependency injection, and does it help in Node?
Dependency injection means passing a module its dependencies — database client, logger, other services — instead of importing them directly. It makes code easier to test (pass fakes), configure and replace. In Node, plain factory functions or constructor parameters are usually enough; containers like Awilix or the ones in NestJS help in larger codebases.
117. Monolith or microservices for a Node backend?
Start with a well-structured modular monolith: one deployable with strong internal boundaries is simpler to develop, test, deploy and debug. Split out services only when there's a clear reason — independent scaling, separate team ownership, different reliability or technology needs. Microservices add network failures, data consistency challenges and operational cost.
118. How would you choose between Express, Fastify and NestJS?
Express is minimal, stable and has the largest ecosystem; Express 5 fixed async error handling. Fastify is faster, has schema-based validation and serialisation built in, and a strong plugin system. NestJS adds an opinionated architecture with modules, dependency injection and decorators, useful for large teams. Choose by team experience, performance needs and how much structure you want imposed.
119. REST, GraphQL or gRPC — when would you use each?
REST is simple, cacheable over HTTP and suits most public and web APIs. GraphQL lets clients request exactly the fields they need across related data, good for complex front ends, but needs care with N+1 queries, query cost limits and caching. gRPC uses Protocol Buffers over HTTP/2 for fast, strongly typed service-to-service calls and streaming, but isn't browser-native.
120. How do you secure a GraphQL API built on Node?
Authenticate requests, then authorise at the resolver or data-access level, not only at the edge. Limit query depth and complexity, set timeouts and pagination limits, disable introspection in production if the schema is private, use persisted queries for public clients, and batch database access with DataLoader to avoid N+1 queries.
121. Which OWASP API risks matter most for a Node service?
Most real incidents come from a handful of API risks.
- Broken object-level authorisation — users accessing other users' records by changing an ID
- Broken authentication — weak tokens, no rate limit on login, leaked secrets
- Excessive data exposure — returning whole database objects instead of explicit fields
- Lack of rate limiting and resource limits — abuse and denial of service
- Injection and unsafe consumption of third-party APIs — trusting input or responses without validation
122. What is prototype pollution, and how do you prevent it?
Prototype pollution happens when attacker-controlled keys like __proto__ or constructor.prototype are merged into objects, adding properties to every object in the process and sometimes leading to privilege escalation or remote code execution. Validate input with strict schemas, avoid unsafe deep-merge utilities, create maps with Object.create(null) or Map, and keep dependencies patched.
123. How do you protect a Node service against ReDoS?
Some regular expressions with nested quantifiers take exponential time on crafted input, blocking the event loop — a regular-expression denial of service. Avoid ambiguous patterns like (a+)+, limit input length before matching, use lint rules or tools to detect unsafe regexes, and prefer well-tested validation libraries for formats like emails and URLs.
124. How do you manage secrets in production?
Keep secrets out of the code, images and logs. Store them in a secret manager (AWS Secrets Manager, Vault, the platform's encrypted variables), inject them at runtime, give each service only the secrets it needs, and rotate them regularly. Validate that required secrets exist at startup and redact them from logs and error reports.
125. How do you secure service-to-service communication?
Encrypt traffic with TLS everywhere, including inside the network. Authenticate services to each other with mutual TLS, signed short-lived tokens (for example OAuth client credentials) or a service mesh, and authorise what each service may call. Never rely only on being inside a private network.
126. How do you implement OAuth 2.0 / OpenID Connect login?
Use a well-maintained library or identity provider rather than writing the protocol yourself. For web apps, use the Authorization Code flow with PKCE, validate the state and nonce, verify ID token signatures, audience and expiry, and store the resulting session in a secure HttpOnly cookie. Keep client secrets on the server and refresh tokens server-side only.
127. What does observability mean for a Node service?
Observability is being able to understand what the system is doing from its outputs: structured logs with request IDs, metrics (request rate, errors, latency percentiles, event loop lag, memory), and distributed traces that follow a request across services. OpenTelemetry gives you vendor-neutral instrumentation for Node, Express, HTTP clients and databases.
128. How does distributed tracing work?
Each incoming request gets a trace ID; every operation inside it — the handler, database query, call to another service — becomes a span with timing. The trace context is passed to downstream services in headers (W3C traceparent), so you can see the whole request path and find where time is spent. In Node, OpenTelemetry auto-instrumentation creates most spans for you.
129. What is AsyncLocalStorage used for?
AsyncLocalStorage from node:async_hooks keeps request-scoped data — a request ID, the current user, a transaction — available through every await and callback in that request without passing it through every function. It's how loggers attach request IDs automatically and how tracing libraries keep context.
import { AsyncLocalStorage } from "node:async_hooks";import { randomUUID } from "node:crypto"; export const requestContext = new AsyncLocalStorage(); app.use((req, res, next) => { const id = req.get("x-request-id") ?? randomUUID(); res.set("x-request-id", id); requestContext.run({ requestId: id }, next);}); export const currentRequestId = () => requestContext.getStore()?.requestId;130. Which metrics would you alert on for a Node API?
Focus on symptoms users feel: error rate (5xx), latency percentiles (p95, p99) and traffic, per route. Add saturation signals: CPU, memory and heap, event loop lag, database pool usage, queue depth and dependency latency. Alert on SLO burn rate rather than single spikes, and link every alert to a dashboard and runbook.
131. What are health checks and readiness probes?
A liveness check tells the orchestrator the process is alive; if it fails, the process is restarted. A readiness check tells the load balancer whether the instance should receive traffic — for example, failing while it starts up, drains for shutdown or loses its database. Keep liveness simple and cheap; let readiness check critical dependencies.
132. How do you run zero-downtime deployments for a Node API?
Use rolling or blue-green deployments behind a load balancer, with readiness checks so new instances only get traffic once ready, and graceful shutdown so old ones finish in-flight requests. Make database migrations backwards-compatible (expand, migrate, contract) so old and new versions can run side by side, and keep a fast rollback.
133. How do you run database migrations safely?
Version migrations in the repository and run them automatically in the pipeline, once per deploy, not from every instance at startup. Prefer additive changes; split breaking ones into expand-and-contract steps across releases; avoid long table locks on big tables (create indexes concurrently, backfill in batches); and test migrations against production-sized data.
134. How do you choose and use indexes for API queries?
Index the columns used in frequent WHERE, JOIN and ORDER BY clauses, with compound indexes in the order the queries filter and sort. Check plans with EXPLAIN, watch slow-query logs, and avoid indexing everything, because indexes slow down writes and use memory. Cursor pagination works best on an indexed, unique sort key.
135. Read replicas, caching or sharding — how do you scale the database?
First optimise queries and indexes and add caching for hot reads. Then add read replicas for read-heavy workloads, accepting slight replication lag. Partition or shard only when a single primary can't handle the writes or data size, because sharding complicates queries, transactions and operations. Connection pooling in front (e.g. PgBouncer) helps when many Node instances connect.
136. How do you handle the cache stampede problem?
When a popular cache key expires, many requests miss at once and all hit the database. Prevent it with request coalescing (only one request recomputes while others wait for it), early or probabilistic refresh before expiry, stale-while-revalidate serving, and jitter on expiry times so keys don't expire together.
137. How do you design an API rate limiter across many instances?
Keep counters in a shared store like Redis with atomic operations, using a sliding-window or token-bucket algorithm per API key, user or IP. Return 429 with rate-limit headers, apply different tiers to different routes, and consider doing coarse limiting at the gateway or CDN. Make the limiter fail open or closed deliberately when Redis is unavailable.
138. What are the trade-offs of serverless for Node APIs?
Serverless functions scale automatically and cost nothing when idle, which suits spiky traffic and event-driven work. The trade-offs are cold starts, execution time limits, limited long-lived connections (WebSockets need a separate service), and many short-lived instances overwhelming databases unless you use a pooler or HTTP-based driver. Long-running, steady workloads are often cheaper in containers.
139. How do you handle real-time features at scale with Node?
WebSocket connections are stateful, so with several instances a message for a user may arrive at the wrong server. Use a pub/sub layer — Redis, NATS, or Socket.IO's Redis adapter — to broadcast between instances, enable sticky sessions where needed, limit connections per instance, and handle reconnection and missed messages with sequence numbers or a resume token.
140. What testing strategy would you use for a Node backend?
Fast unit tests for business logic, many integration tests that hit routes with a real database in a container (Testcontainers), contract tests for APIs other teams consume or that you depend on, and a few end-to-end tests of critical flows against a deployed environment. Add load tests (k6, Artillery) for performance-sensitive endpoints before big launches.
141. How do you load test a Node API, and what do you look for?
Write realistic scenarios with a tool like k6 or Artillery, ramp traffic up gradually against a production-like environment, and watch latency percentiles, error rate, CPU, memory, event loop lag and database metrics. Find the point where latency rises sharply, identify the bottleneck — often the database or a blocking operation — and fix it before testing again.
142. How do you design APIs for backward compatibility?
Treat the API as a contract. Add optional fields and new endpoints instead of renaming or removing; never change the meaning or type of an existing field; make clients ignore unknown fields; and version only for truly breaking changes. Track usage of deprecated fields, announce timelines, and remove them only when traffic has gone.
143. How do you secure file uploads and user-generated content?
Enforce size limits early, check the real content type from the file's bytes, store uploads outside the web root (ideally object storage with private access and signed URLs), generate new file names, scan for malware where needed, and process images in a sandboxed worker. Serve user content from a separate domain to limit damage from malicious files.
144. What is the permission model in Node.js?
Modern Node has a built-in permission model: run with --permission and the process can no longer read or write files, spawn child processes or create worker threads unless you grant it, for example with --allow-fs-read=./data. It adds defence in depth against compromised dependencies, alongside running as a non-root user in a minimal container.
145. How do you handle time zones and dates in a backend?
Store and transmit timestamps in UTC (ISO 8601 strings or database timestamp-with-time-zone types), and convert to the user's time zone only for display or for business rules that depend on local time, like "end of day". Use Intl or a solid date library, store the user's IANA time zone, and test around daylight-saving changes.
146. How do you handle money and precise numbers in Node?
JavaScript numbers are binary floating point, so 0.1 + 0.2 isn't exactly 0.3. Store money as integers in the smallest unit (cents), or use a decimal type in the database and a decimal library in code. Keep the currency with every amount, round only at defined points, and use BigInt for integers beyond 2^53.
147. How would you design error classes so errors map cleanly to HTTP responses?
Create a small hierarchy of operational errors — NotFoundError, ValidationError, ConflictError, ForbiddenError — that carry an HTTP status and a stable code. Services throw them without knowing about Express; one error middleware turns them into responses and treats anything else as an unexpected 500 that is logged and alerted on. Use the cause option to keep the original error for debugging.
export class AppError extends Error { constructor(message, { status = 500, code = "INTERNAL", cause } = {}) { super(message, { cause }); this.status = status; this.code = code; }}export class NotFoundError extends AppError { constructor(message = "Not found") { super(message, { status: 404, code: "NOT_FOUND" }); }}148. How would you migrate an Express 4 application to Express 5?
Read the migration guide and upgrade in a branch. Update route paths to the new syntax (named wildcards like /*splat, braces for optional parts), replace removed methods such as app.del and the old res.send(status) forms, stop writing to req.query, and remove async error wrappers since Express 5 handles rejected promises. Run the official codemods, then your test suite and a canary deploy.
149. How do you profile and reduce startup time?
Measure with --cpu-prof on startup, and look for heavy synchronous work at import time — large config parsing, eager database connections, big dependency trees. Lazy-load rarely used modules, cache compiled code where supported, avoid huge barrel files and trim dependencies. Fast startup matters for autoscaling, serverless cold starts and quick rollbacks.
150. Walk through how you would design a URL shortener API in Node.
Endpoints: POST /links to create, GET /:code to redirect. Generate short codes from a counter encoded in base62 or a random ID with a uniqueness check; store code → url, owner, createdAt with an index on the code. Serve redirects from Redis with the database as fallback, count clicks asynchronously through a queue, rate-limit creation, validate URLs to block abuse, and scale reads with caching and replicas.
Tech Lead — Leading Node.js Backend Teams
At tech lead level, questions move from code to systems and people: choosing the platform and architecture, keeping services reliable and secure, running releases and incidents, managing technical debt and growing a backend team. Interviewers look for clear reasoning, honest trade-offs and examples of you raising the whole team's output.
151. How do you choose the backend stack for a new Node.js product?
Start from requirements: traffic shape, latency needs, data model, team skills, hosting and compliance. Then pick a framework (Express, Fastify or NestJS), a database that fits the data, and the minimum of infrastructure — usually one service, one database, a cache and a queue. Prototype the riskiest part, write the decision and the rejected alternatives in an ADR, and avoid adopting technology just because it's new.
152. How do you decide when to split a monolith into services?
Only when a concrete problem justifies it: a part needs to scale independently, a team needs to deploy on its own schedule, or a component has very different reliability or technology needs. First strengthen module boundaries inside the monolith; then extract the module with the clearest boundary and the most pain, using the strangler pattern, with its own data and a well-defined API.
153. What architecture guidelines would you set for a Node.js team?
A short, written set of defaults: modules by business domain with explicit public interfaces; HTTP, business logic and data access kept separate; every input validated with schemas; one error-handling and logging approach; config validated at startup; no blocking work on the request path; and every service observable with logs, metrics and traces. Back it with templates, lint rules and review checklists.
154. How would you standardise new services across many teams?
Provide a service template or generator that already includes the agreed framework setup, config validation, structured logging, OpenTelemetry tracing, health checks, graceful shutdown, Dockerfile, CI pipeline and test setup. Teams start from the paved road and only deviate with a reason. Keep the template maintained and publish shared libraries for cross-cutting concerns.
155. How do you define API design standards for the organisation?
Write a concise API style guide: resource naming, HTTP methods and status codes, a single error format, pagination, filtering and sorting conventions, versioning and deprecation rules, authentication and idempotency for unsafe operations. Require an OpenAPI spec for every API, lint specs automatically in CI and review new APIs early in design rather than after they ship.
156. How do you plan a major Node.js or framework upgrade across many services?
Track the runtime versions in use against the Node release schedule, and upgrade to each new LTS within its first months. Test the upgrade on a pilot service first, run codemods and fix deprecations, upgrade shared libraries and the service template, then roll out service by service with a dashboard showing progress. Small, regular upgrades beat rare, painful ones.
157. How do you manage technical debt in a backend codebase?
Make it visible and tie it to cost — incidents, slow delivery, security risk, scaling limits. Keep a prioritised debt list, reserve a steady share of capacity for it, and pay it down where code changes most. Explain it to the business in terms of risk and speed, and prevent new debt with standards, reviews and automated checks.
158. What would you put in a backend code review checklist?
A short checklist keeps reviews consistent and focused.
- Input validated and authorisation checked for every endpoint
- Errors handled, logged with context, and safe responses returned
- No blocking work on the request path; timeouts on external calls
- Database changes indexed, migrated safely and backwards compatible
- Tests for the behaviour, and no secrets or personal data in logs
159. How do you enforce quality automatically in a Node.js codebase?
TypeScript in strict mode, ESLint with security and promise rules, Prettier, dependency boundary checks and commit hooks for fast feedback. In CI, gate merges on type checks, tests, coverage of critical modules, dependency audits, secret scanning and container image scanning. Automate everything objective so human review can focus on design.
160. How do you set SLOs for a backend service?
Pick indicators that reflect user experience — availability (successful requests) and latency (for example p95 under 300 ms) for key endpoints — and set targets slightly below what you can reliably deliver, such as 99.9%. The gap is the error budget: when it's being burned quickly, slow down feature work and invest in reliability. Alert on burn rate, not on every blip.
161. How do you run an incident as a tech lead?
Assign roles quickly — an incident commander, someone investigating, someone communicating. Focus first on mitigation: roll back, disable a feature flag, scale up or fail over. Communicate impact and next update times regularly in one channel. Afterwards, run a blameless post-mortem with a timeline, root causes and owned actions, and follow up until the actions are done.
162. How do you design the on-call process for a backend team?
Make alerts actionable and few: each links to a dashboard and a runbook. Rotate fairly with a primary and a backup, train people with shadow shifts before they're on call, compensate it, and review every page afterwards to remove noise or fix the cause. If on-call is painful, treat reliability work as top priority.
163. How do you decide what to build versus buy for backend capabilities?
Build what differentiates the product; buy or adopt managed services for commodities like authentication, payments, email delivery, search, queues and observability. Compare total cost of ownership — engineering time, on-call, security patches — against vendor cost, and weigh lock-in, data residency and the exit path if you need to switch.
164. How do you choose between managed cloud services and self-hosting?
Managed services (databases, queues, caches) cost more per unit but remove operational work, backups, patching and scaling — usually the right default for small and medium teams. Self-host when you have the operational expertise and a strong reason: cost at large scale, specific configuration, compliance or portability. Revisit the decision as scale changes.
165. How do you keep cloud costs under control?
Make costs visible per service and team with tagging and dashboards, set budgets and alerts, right-size instances and database tiers from real usage, autoscale stateless services, use reserved or spot capacity where safe, add caching to cut expensive queries, and set retention policies for logs and backups. Review costs regularly like any other metric.
166. How do you plan capacity for a growing backend?
Measure current load and the resources each unit of traffic uses, find the first bottleneck with load tests (often the database), and project growth from business forecasts. Keep headroom for peaks, design stateless services that scale horizontally, and plan the next step for each bottleneck — read replicas, caching, partitioning — before you reach it.
167. What is your approach to data and database ownership across services?
Each service owns its data and is the only one that writes to its database; others access it through APIs or events. Shared databases create hidden coupling that makes changes risky. For reporting and analytics, stream changes into a separate warehouse rather than querying service databases directly.
168. How do you introduce event-driven architecture to a team?
Start with one clear use case where async communication helps — sending notifications after an order, syncing search indexes. Choose a managed broker, define event schemas and versioning rules, use the outbox pattern for reliable publishing, and require idempotent consumers. Add tracing across events and dead-letter handling before adding more producers.
169. How do you make sure security is built into backend development?
Make it part of the normal workflow: threat-model new features, keep secure defaults in the service template, automate dependency, secret and image scanning in CI, require authorisation checks in reviews, run periodic penetration tests, and train engineers on the OWASP API risks. Assign a security champion per team and treat security findings like production bugs.
170. How do you handle a critical vulnerability in a dependency?
Assess quickly whether you're affected — the vulnerable function, version and exposure. If you are, patch or upgrade immediately across all services using an inventory of dependencies, deploy, and verify. If no fix exists, mitigate (disable the feature, add input filtering or a WAF rule). Communicate status to stakeholders and review how detection could be faster next time.
171. How do you handle compliance requirements like GDPR in a backend?
Know what personal data you store, where and why; minimise it; encrypt it in transit and at rest; restrict access by role and log access to sensitive data. Support data subject rights — export and deletion — across all stores, including backups and logs, set retention periods, choose hosting regions that meet data-residency rules, and keep personal data out of logs and analytics.
172. What testing strategy would you set for a Node.js backend team?
Unit tests for business logic, integration tests on routes with real databases in containers as the main layer, contract tests between services, and a small set of end-to-end tests on critical journeys. Add load tests before big launches and run security scans continuously. Agree on what must be tested before merge and keep the suite fast and reliable.
173. How do you keep CI/CD fast and safe as the team grows?
Cache dependencies and builds, run only the tests affected by a change, parallelise suites and fix flaky tests immediately. Deploy small changes often, behind feature flags, with automatic canary analysis and one-click rollback. Keep the main branch always deployable and track build time and deployment frequency as team metrics.
174. How do you roll out risky backend changes safely?
Hide them behind feature flags, release to a small percentage of traffic or internal users first, and compare error rates and latency with the baseline. Use dark launches or shadow traffic for new code paths, make database changes backwards compatible, and have a clear rollback plan before you start. Increase exposure gradually.
175. How do you document backend systems so they stay useful?
Keep documentation close to the code: OpenAPI specs generated from schemas, ADRs for decisions, READMEs with setup and run instructions, and runbooks for operations. Add a high-level architecture diagram showing services, data stores and flows. Give each document an owner and update docs as part of the definition of done.
176. How do you onboard engineers onto a complex backend?
One-command local setup with Docker Compose and seed data, an architecture overview of services and data flows, a glossary of domain terms, and a first task that touches a real endpoint end to end. Pair them with a buddy, give them time on the on-call shadow rotation, and ask them to fix the onboarding gaps they find.
177. How do you mentor engineers towards senior-level backend skills?
Give them ownership of a meaningful piece — a service, a migration, an incident follow-up — with support, not step-by-step instructions. Review their designs as well as their code, ask questions about trade-offs, failure modes and observability, involve them in incident reviews and capacity planning, and give regular, specific feedback tied to a growth plan.
178. How do you run backend technical interviews?
Use a structured process with a shared rubric: a practical exercise such as building or debugging a small API, a system design discussion scaled to the level, and a conversation about past work and decisions. Look for reasoning about failure, data and trade-offs, not memorised trivia, and calibrate interviewers regularly to keep it fair.
179. How do you estimate a large backend project?
Break it into deliverable milestones, estimate each as a range, and call out unknowns — third-party integrations, data migrations, performance targets. Spike the riskiest parts first, deliver a thin end-to-end slice early, and re-forecast regularly from actual progress. Communicate confidence levels, not just dates.
180. How do you balance feature work with reliability and platform work?
Agree on a standing capacity split with product, for example 70% features and 30% reliability, debt and platform, and adjust it using the error budget: when reliability slips, shift more capacity there. Tie platform work to outcomes product cares about — faster delivery, fewer incidents, lower cost — and show the results.
181. How do you work with front-end and mobile teams on APIs?
Design APIs together from the screens and use cases, agree the contract first in OpenAPI or GraphQL schema form, and generate types and mocks so teams can work in parallel. Add contract tests, give clients a sandbox environment, and communicate changes and deprecations early with clear timelines.
182. How do you explain technical risks to non-technical stakeholders?
Translate them into business terms: impact (customers affected, revenue, reputation), likelihood and cost to fix now versus later. Offer options with trade-offs and a recommendation, use concrete examples or incident history, and confirm the decision in writing. Avoid jargon and don't exaggerate — credibility matters for the next conversation.
183. Two engineers disagree strongly about a design. What do you do?
Listen to each separately, then bring them together to agree on the goals and the criteria for deciding. If evidence can settle it, run a short spike or benchmark. If it's still balanced, make the decision, explain why, record it in an ADR and ask both to commit. Check afterwards that the disagreement didn't damage the working relationship.
184. How do you handle an engineer who repeatedly ships bugs to production?
Look for the system problem first: missing tests, unclear requirements, a risky area of code or rushed timelines. Talk privately with specific examples and listen. Agree on concrete improvements — more tests, smaller changes, pairing on risky parts, reviews from a senior — and check in regularly. Escalate with your manager only if there's no progress over an agreed period.
185. How do you prevent knowledge silos in a backend team?
Rotate ownership and on-call across services, pair on complex work, require more than one reviewer for critical code, and keep runbooks and architecture docs current. Make sure at least two people can deploy, debug and recover each service, and notice when one person has become the only expert — including yourself.
186. What metrics do you use to understand your team's health and delivery?
Delivery metrics like deployment frequency, lead time for changes, change failure rate and time to restore; reliability metrics like SLO attainment and incident count; and developer experience signals like CI time and survey results. Use them to find bottlenecks and improve the system, never to rank individuals.
187. How do you improve developer experience for a backend team?
Measure where time goes, then remove friction: fast local environments with Docker Compose, quick and reliable CI, generators for new services and endpoints, preview environments, typed configuration, good error messages and clear docs. Every minute saved repeats for every engineer every day.
188. How do you choose between Node.js and another language for a new service?
Node is excellent for I/O-heavy APIs, real-time features, BFF layers and teams that share TypeScript with the front end. For CPU-heavy workloads such as data processing or machine learning, or where a library ecosystem is far stronger elsewhere, Go, Java, Rust or Python may fit better. Consider team skills, hiring and operational consistency, not only raw performance.
189. How do you plan for disaster recovery?
Define recovery time and recovery point objectives for each system with the business. Take automated, encrypted backups, store them in another region or account, and test restores regularly — an untested backup isn't a backup. Use infrastructure as code so environments can be recreated, and practise failover with game days.
190. How do you approach multi-region deployment?
Only when the business needs it — lower latency for global users, regulatory data residency or resilience to a whole region failing. Start with active-passive (a warm standby region) before active-active, because writing data in several regions brings consistency and conflict problems. Route users with global load balancing and keep stateless services region-independent.
191. How do you decide on an API gateway or service mesh?
An API gateway centralises cross-cutting concerns at the edge: routing, authentication, rate limiting, request transformation and analytics — useful once you have several public services. A service mesh handles service-to-service traffic: mutual TLS, retries, traffic splitting and telemetry — valuable for many microservices, but it adds operational complexity. Adopt each only when the problems they solve are real.
192. How do you run a technical design review?
Ask authors for a short design document — problem, goals and non-goals, proposed design, alternatives, data model, API, failure modes, security, observability and rollout. Share it ahead of the meeting, invite people from affected teams, focus discussion on risks and trade-offs, and record the decision and open questions.
193. How do you introduce TypeScript into an existing JavaScript Node codebase?
Incrementally: add a tsconfig with allowJs and checkJs off at first, convert shared utilities and new code to TypeScript, add types at module boundaries, and raise strictness step by step. Type the external inputs with schemas so runtime validation and types agree. Run type checks in CI from day one so progress isn't lost.
194. How do you keep a backend team aligned with the product roadmap?
Join planning early so technical constraints and enabling work are visible, translate roadmap items into technical milestones with clear owners, and maintain a technical roadmap that supports the product one — platform improvements, scaling steps, debt to pay. Review progress regularly with product and adjust both when priorities change.
195. How do you create a culture of ownership in a backend team?
Teams own services end to end — design, build, deploy, operate and support — with the authority to make decisions within agreed standards. Make outcomes visible with dashboards, celebrate improvements in reliability and speed, run blameless reviews, and give people the context about why their work matters to customers.
196. How do you keep your own technical skills sharp as a lead?
Stay hands-on in focused ways: review designs and code, write prototypes and spikes, take part in incident investigations and occasionally pick up non-critical tickets. Read release notes and post-mortems from other companies, experiment with new tools in side projects, and learn from the engineers on your team.
197. Tell me about a difficult production problem you led the team through.
Use the STAR structure: the situation and its impact, how you organised the response, the technical investigation and the fix, and the outcome with numbers if possible. Spend most of the time on what you learned and changed afterwards — monitoring, process or architecture. Interviewers look for calm leadership, clear communication and lasting improvements.
198. How do you build trust with a team you have just joined?
Listen before changing anything: one-to-ones with everyone, reading the code, incidents and past decisions, and asking what slows people down. Deliver a few small improvements the team asks for, keep your commitments, give credit generously and admit your mistakes. Trust comes from consistency over time.
199. Where do you see Node.js heading, and how do you prepare your team?
Node keeps adopting web standards (fetch, Web Streams, WebSocket), adding built-in tools (test runner, watch mode, .env loading, type stripping, a permission model) and competing with newer runtimes like Deno and Bun that push performance and developer experience. Prepare the team by favouring standard APIs, keeping dependencies lean, upgrading LTS versions regularly and evaluating new runtimes with real benchmarks.
200. What would you do in your first 90 days leading a Node.js backend team?
First month: meet everyone, learn the product and the architecture, read recent incidents and map the delivery pipeline and pain points. Second month: deliver a few visible quick wins — better alerts, a faster CI, a fixed recurring incident. Third month: share a written technical strategy and roadmap, agreed with the team and stakeholders, covering reliability, architecture, security and people growth.
Intern — Node.js နဲ့ Express အခြေခံ
Intern backend ဒါမှမဟုတ် full-stack role အတွက် interviewer တွေက Node.js ဆိုတာ ဘာလဲ၊ module နဲ့ npm ဘယ်လိုအလုပ်လုပ်လဲ၊ HTTP နဲ့ REST အခြေခံတွေ၊ route၊ middleware နဲ့ JSON ပါတဲ့ Express API အသေးလေးတစ်ခုကို ဘယ်လို တည်ဆောက်လဲ ဆိုတာကို သိလား စစ်ပါတယ်။ Feature တိုင်းကို ဖုံးတာထက် ကိုယ်တည်ဆောက်ခဲ့တာနဲ့ ဘာကြောင့်လဲ ဆိုတာကို ရှင်းရှင်းလင်းလင်း ပြောနိုင်တာက ပိုအရေးကြီးပါတယ်။
1. Node.js ဆိုတာ ဘာလဲ?
Node.js ဆိုတာ Chrome ရဲ့ V8 engine ပေါ်မှာ တည်ဆောက်ထားပြီး JavaScript ကို browser ပြင်ပမှာ run ပေးတဲ့ JavaScript runtime ပါ။ Server၊ API၊ command-line tool နဲ့ build tool တွေအတွက် အဓိကသုံးပါတယ်။ သူ့အားသာချက်က thread တစ်ခုတည်းပေါ်မှာ non-blocking၊ asynchronous I/O နဲ့ network connection အများကြီးကို တစ်ပြိုင်နက် ကိုင်တွယ်နိုင်တာပါ။
2. Node.js က browser ထဲက JavaScript နဲ့ ဘယ်လိုကွာလဲ?
နှစ်ခုစလုံး language အတူတူ run ပေမဲ့ environment ကွာပါတယ်။ Browser က DOM၊ window နဲ့ web API တွေကို ပေးပြီး code ကို sandbox ထဲမှာ run ပါတယ်။ Node ကတော့ fs၊ path၊ http လို module တွေကနေ file system၊ process၊ network socket နဲ့ environment variable တွေကို access ပေးပေမဲ့ DOM မရှိပါဘူး။ အခုဆို နှစ်ခုစလုံး fetch၊ URL၊ AbortController လို standard API တွေကို မျှသုံးပါတယ်။
3. V8 engine ဆိုတာ ဘာလဲ?
V8 ဆိုတာ C++ နဲ့ရေးထားပြီး Chrome နဲ့ Node.js သုံးတဲ့ Google ရဲ့ open-source JavaScript engine ပါ။ JavaScript ကို just-in-time compilation နဲ့ မြန်တဲ့ machine code အဖြစ် compile လုပ်ပြီး garbage collector နဲ့ memory ကို manage လုပ်ပါတယ်။ Node က V8 ရဲ့ အပေါ်မှာ system API တွေနဲ့ event loop ကို ထပ်ထည့်ပေးပါတယ်။
4. Node.js က single-threaded နဲ့ non-blocking ဖြစ်တယ်ဆိုတာ ဘာကိုဆိုလိုလဲ?
ကိုယ့် JavaScript က main thread တစ်ခုပေါ်မှာ run တာမို့ တစ်ကြိမ်မှာ code တစ်ပိုင်းပဲ execute ဖြစ်ပါတယ်။ ဒါပေမဲ့ file ဖတ်တာ ဒါမှမဟုတ် database ခေါ်တာလို နှေးတဲ့ operation တွေက အဲ့ thread ကို မပိတ်ဆို့ပါဘူး — Node က သူတို့ကို စလိုက်ပြီး တခြား request တွေကို ဆက်ကိုင်တွယ်ကာ ရလဒ်ရတဲ့အခါ callback ကို run တာ ဒါမှမဟုတ် await ကို ဆက်တာ လုပ်ပါတယ်။ Node process တစ်ခုက တစ်ပြိုင်နက် connection ထောင်ချီကို serve လုပ်နိုင်တာ ဒါကြောင့်ပါ။
5. npm ဆိုတာ ဘာလဲ၊ package.json က ဘာအတွက်လဲ?
npm ဆိုတာ Node ရဲ့ package manager နဲ့ library တွေရဲ့ public registry ပါ။ package.json က project ကို ဖော်ပြပါတယ် — နာမည်နဲ့ version၊ လိုအပ်တဲ့ dependency နဲ့ dev dependency တွေ၊ start၊ dev၊ test လို script တွေ။ npm install ကို run လိုက်ရင် အဲ့ဒါကို ဖတ်ပြီး အားလုံးကို node_modules ထဲ download လုပ်ပါတယ်။
6. dependencies နဲ့ devDependencies ဘာကွာလဲ?
dependencies က app ကို production မှာ run တဲ့အခါ လိုတာတွေပါ — Express၊ database driver၊ validation library။ devDependencies က develop လုပ်နေစဉ် ဒါမှမဟုတ် build လုပ်နေစဉ်မှာပဲ လိုတာတွေပါ — test runner၊ linter၊ TypeScript၊ nodemon။ Production မှာ npm ci --omit=dev နဲ့ runtime ဟာတွေကိုပဲ install လုပ်လို့ရတာမို့ deployment ကို ပိုသေးပြီး ပိုလုံခြုံစေပါတယ်။
7. package-lock.json file က ဘာအတွက်လဲ?
Lock file က dependency တွေရဲ့ dependency တွေ အပါအဝင် install လုပ်ထားတဲ့ package တိုင်းရဲ့ version အတိအကျကို မှတ်တမ်းတင်ပါတယ်။ Commit လုပ်ထားရင် developer တိုင်း၊ CI run တိုင်းနဲ့ server တိုင်းက tree အတူတူကို install လုပ်လို့ "ကျွန်တော့်စက်မှာတော့ အလုပ်လုပ်တယ်" ပြဿနာတွေ ပျောက်သွားပါတယ်။ CI မှာ lock file ကနေ တင်းတင်းကျပ်ကျပ် install လုပ်ဖို့ npm ci ကို သုံးပါ။
8. ^1.2.3 နဲ့ ~1.2.3 version နံပါတ်တွေက ဘာကိုဆိုလိုလဲ?
Package တွေက semantic versioning ကို သုံးပါတယ် — MAJOR.MINOR.PATCH။ Caret ^1.2.3 က backwards compatible ဖြစ်သင့်တဲ့ minor နဲ့ patch update တွေ (1.x.x၊ 2.0.0 အောက်) ကို ခွင့်ပြုပါတယ်။ Tilde ~1.2.3 က patch update (1.2.x) တွေကိုပဲ ခွင့်ပြုပါတယ်။ အတိအကျ 1.2.3 က version ကို လုံးဝ pin လုပ်ပါတယ်။
9. Node မှာ CommonJS နဲ့ ES modules ဘာကွာလဲ?
CommonJS က require() နဲ့ module.exports ကို သုံးပြီး Node ရဲ့ မူလ module system ပါ။ ES modules က JavaScript standard ဖြစ်တဲ့ import နဲ့ export ကို သုံးပါတယ်။ Node က .mjs file တွေ ဒါမှမဟုတ် package.json မှာ "type": "module" ပါရင် .js file တွေကို ES modules အဖြစ် ဆက်ဆံပါတယ်။ Project အသစ်တွေက များသောအားဖြင့် ES modules ကို သုံးပါတယ်။
// CommonJSconst path = require("node:path");module.exports = { greet }; // ES modulesimport path from "node:path";export function greet(name) { return `Hello, ${name}`;}10. Node.js ထဲမှာ ပါပြီးသား core module တချို့ ပြောပြပါ။
Node က ဘာမှ install မလုပ်ဘဲ သုံးလို့ရတဲ့ module တွေနဲ့အတူ ပါလာပါတယ်၊ ရှင်းအောင် node: prefix ထည့်ပါ။
node:fs— file တွေ ဖတ်တာ၊ ရေးတာnode:path— file path တွေကို လုံလုံခြုံခြုံ တည်ဆောက်တာ၊ ခွဲခြမ်းတာnode:http— HTTP server နဲ့ client တွေ ဖန်တီးတာnode:events— EventEmitter patternnode:crypto— hashing၊ random value နဲ့ encryption
11. Node.js မှာ file တစ်ခုကို ဘယ်လို ဖတ်မလဲ?
File ဖတ်နေစဉ် server မပိတ်ဆို့အောင် promise-based fs/promises API ကို await နဲ့ သုံးပါ။ Synchronous readFileSync က startup script မှာ အဆင်ပြေပေမဲ့ request handler ထဲမှာဆိုရင် တခြား request အားလုံးကို ပိတ်ဆို့ပါတယ်။
import { readFile } from "node:fs/promises"; try { const text = await readFile("./data/users.json", "utf8"); const users = JSON.parse(text); console.log(users.length, "users");} catch (err) { console.error("Could not read users:", err.message);}12. String တွေ ဆက်မယ့်အစား path module ကို ဘာကြောင့် သုံးသင့်လဲ?
Operating system အလိုက် file path ကွာပါတယ် — Windows က backslash သုံးပြီး macOS နဲ့ Linux က slash သုံးပါတယ်။ path.join နဲ့ path.resolve က လက်ရှိ system အတွက် မှန်ကန်တဲ့ path ကို တည်ဆောက်ပေးပြီး separator အပို ဒါမှမဟုတ် ကျန်နေတာတွေကို ကိုင်တွယ်ပေးပါတယ်။ ES modules အတွက် import.meta.dirname က လက်ရှိ file ရဲ့ folder ကို ပေးပါတယ်။
13. process object ဆိုတာ ဘာလဲ?
process ဆိုတာ run နေတဲ့ Node program ကို ဖော်ပြတဲ့ global object ပါ။ Environment variable (process.env)၊ command-line argument (process.argv)၊ working directory (process.cwd())၊ memory usage နဲ့ exit၊ SIGTERM လို event တွေကို ပေးပါတယ်။ process.exit(code) က program ကို status code နဲ့ အဆုံးသတ်ပါတယ်။
14. Node app မှာ environment variable တွေကို ဘယ်လို သုံးမလဲ?
Configuration — port၊ database URL၊ API key — တွေကို hard-code မလုပ်ဘဲ process.env ကနေ ဖတ်ပါ။ Local မှာ .env file ထဲ ထားပြီး node --env-file=.env app.js (modern Node မှာ ပါပြီးသား) ဒါမှမဟုတ် dotenv package နဲ့ load လုပ်လို့ရပါတယ်။ Secret အစစ်ပါတဲ့ .env file တွေကို Git ထဲ ဘယ်တော့မှ commit မလုပ်ပါနဲ့။
15. Callback ဆိုတာ ဘာလဲ၊ callback hell ဆိုတာ ဘာလဲ?
Callback ဆိုတာ asynchronous operation ကို ပေးလိုက်ပြီး ပြီးတဲ့အခါ ခေါ်ခံရတဲ့ function ပါ။ Node ရဲ့ API ဟောင်းတွေက error-first callback တွေကို သုံးပါတယ် — (err, result) => {}။ Async အဆင့်အများကြီးက တစ်ခုနဲ့တစ်ခု မှီခိုတဲ့အခါ callback တွေ နက်သထက်နက်လာပြီး — "callback hell" — code ဖတ်ရခက်ကာ error တွေ လွတ်သွားလွယ်ပါတယ်။ Promise နဲ့ async/await က ဒါကို ဖြေရှင်းပေးပါတယ်။
16. Promise နဲ့ async/await က Node မှာ ဘယ်လို ကူညီလဲ?
Promise က နောက်မှရမယ့် ရလဒ်ကို ကိုယ်စားပြုပြီး async/await က asynchronous code ကို error အတွက် ပုံမှန် try/catch နဲ့ အပေါ်ကနေ အောက် ဖတ်သလို ရေးခွင့်ပေးပါတယ်။ Node API အများစုမှာ promise version (fs/promises၊ timers/promises) ရှိပြီး callback function ဟောင်းတွေကို util.promisify နဲ့ ထုပ်လို့ရပါတယ်။
17. Event loop ကို ရိုးရိုးရှင်းရှင်း ပြောပြပါ။
Event loop ဆိုတာ single-threaded Node ကို task အများကြီး ကိုင်တွယ်နိုင်စေတဲ့ mechanism ပါ။ Database query လို async operation တစ်ခု ပြီးတဲ့အခါ သူ့ callback ကို queue ထဲ ထည့်ပါတယ်။ Main thread အားတိုင်း event loop က queue တွေထဲက callback တွေကို ယူပြီး run ပါတယ်။ ကိုယ့် code က synchronous loop အရှည်ကြီး run နေရင် ပြီးတဲ့အထိ event loop က ဘာမှ run လို့မရပါဘူး။
18. EventEmitter ဆိုတာ ဘာလဲ?
node:events က EventEmitter က object တွေကို နာမည်ပေးထားတဲ့ event တွေ emit လုပ်ခွင့်ပေးပြီး တခြား code တွေကို on နဲ့ နားထောင်ခွင့်ပေးပါတယ်။ Node object အများကြီး — HTTP server၊ stream၊ process — က emitter တွေပါ။ Code ကို ခွဲထုတ်ဖို့ ရိုးရှင်းတဲ့ နည်းလမ်းပါ — အပိုင်းတစ်ခုက တစ်ခုခုဖြစ်ကြောင်း ကြေညာပြီး တခြားအပိုင်းတွေက တုံ့ပြန်ပါတယ်။
import { EventEmitter } from "node:events"; const orders = new EventEmitter();orders.on("created", (order) => { console.log("Send email for order", order.id);});orders.emit("created", { id: 42 });19. Express မပါဘဲ basic HTTP server ကို ဘယ်လို ဖန်တီးမလဲ?
Request နဲ့ response ကို လက်ခံတဲ့ function နဲ့ http.createServer ကို သုံးပါ။ အလုပ်လုပ်ပေမဲ့ URL၊ body နဲ့ route တွေကို ကိုယ်တိုင် parse လုပ်ရပါတယ် — Express လို framework တွေ ရှိရတဲ့ အကြောင်းရင်းပါ။
import http from "node:http"; const server = http.createServer((req, res) => { res.writeHead(200, { "Content-Type": "application/json" }); res.end(JSON.stringify({ message: "Hello from Node" }));}); server.listen(3000, () => console.log("Listening on :3000"));20. Express.js ဆိုတာ ဘာလဲ၊ ဘာကြောင့် သုံးလဲ?
Express ဆိုတာ Node အတွက် minimal web framework ပါ။ Method နဲ့ path အလိုက် routing၊ middleware system၊ request ဖတ်ဖို့နဲ့ response ပို့ဖို့ helper (res.json၊ res.status) တွေနဲ့ CORS၊ session၊ security header လိုအရာတွေအတွက် middleware ecosystem ကြီးကို ထပ်ထည့်ပေးပါတယ်။ သေးငယ်နေပြီး ကိုယ့် stack ရဲ့ ကျန်အပိုင်းတွေကို ကိုယ်တိုင်ရွေးခွင့် ပေးပါတယ်။
21. Basic Express app ကို ဘယ်လို ဖန်တီးမလဲ?
express ကို install လုပ်၊ app ဖန်တီး၊ middleware နဲ့ route တွေထည့်ပြီး port တစ်ခုမှာ listen လုပ်ပါ။ express.json() က JSON request body တွေကို req.body ပေါ်မှာ ပေါ်အောင် parse လုပ်ပေးပါတယ်။
import express from "express"; const app = express();app.use(express.json()); app.get("/", (req, res) => { res.json({ status: "ok" });}); const port = process.env.PORT ?? 3000;app.listen(port, () => console.log(`API on port ${port}`));22. Express မှာ routing ဆိုတာ ဘာလဲ?
Routing က HTTP method နဲ့ path ကို ကိုင်တွယ်မယ့် function နဲ့ တွဲပေးပါတယ် — app.get("/users", ...)၊ app.post("/users", ...)၊ app.delete("/users/:id", ...)။ Express က route တွေကို ထည့်ခဲ့တဲ့ order အတိုင်း စစ်ပြီး ပထမဆုံး ကိုက်ညီတဲ့ဟာကို run ပါတယ်။ ဘာနဲ့မှ မကိုက်တဲ့ route တွေက 404 handler ဆီ ကျသွားပါတယ်။
23. Route parameter နဲ့ query string ဆိုတာ ဘာလဲ?
Route parameter တွေက /users/:id ထဲက :id လို path ရဲ့ နာမည်ပေးထားတဲ့ အစိတ်အပိုင်းတွေဖြစ်ပြီး req.params မှာ ရနိုင်ပါတယ်။ Query string တွေက /users?page=2&limit=20 လို ? နောက်က optional key-value အတွဲတွေဖြစ်ပြီး req.query မှာ ရနိုင်ပါတယ်။ နှစ်ခုစလုံး string အဖြစ် ရောက်လာတာမို့ မသုံးခင် ပြောင်းပြီး validate လုပ်ပါ။
// GET /users/42?include=postsapp.get("/users/:id", (req, res) => { const id = Number(req.params.id); // 42 const include = req.query.include; // "posts" res.json({ id, include });});24. req နဲ့ res ဘာကွာလဲ?
req (request) က client ပို့လိုက်တာအားလုံးကို ကိုင်ထားပါတယ် — method၊ URL၊ params၊ query၊ header၊ cookie နဲ့ body။ res (response) က ကိုယ်ပြန်ဖြေပုံပါ — res.status(201)၊ res.json(data)၊ res.send(text)၊ res.redirect(url) နဲ့ header သတ်မှတ်တာ။ Request တိုင်းက response တစ်ခုတည်းနဲ့ အတိအကျ အဆုံးသတ်ရပါမယ်။
25. Express မှာ middleware ဆိုတာ ဘာလဲ?
Middleware ဆိုတာ request လုပ်နေစဉ် နောက်ဆုံး route handler မတိုင်ခင် run တဲ့ (req, res, next) function ပါ။ Request ကို ဖတ်တာ ဒါမှမဟုတ် ပြောင်းတာ၊ response ကို အဆုံးသတ်တာ ဒါမှမဟုတ် ထိန်းချုပ်မှုကို ဆက်ပေးဖို့ next() ကို ခေါ်တာ လုပ်နိုင်ပါတယ်။ Logging၊ JSON parse လုပ်တာ၊ authentication၊ CORS နဲ့ rate limiting တွေအားလုံး middleware တွေပါ။
function logger(req, res, next) { const start = Date.now(); res.on("finish", () => { console.log(req.method, req.url, res.statusCode, `${Date.now() - start}ms`); }); next();} app.use(logger);26. next() က ဘာလုပ်ပေးလဲ?
next() က Express ကို နောက်ထပ် ကိုက်ညီတဲ့ middleware ဒါမှမဟုတ် route handler ဆီ ရွှေ့ခိုင်းပါတယ်။ Middleware က response လည်းမပို့၊ next() လည်း မခေါ်ရင် request က timeout ဖြစ်တဲ့အထိ ဆွဲထားခံရပါတယ်။ Error နဲ့ next(err) ကို ခေါ်ရင် ပုံမှန် handler တွေကို ကျော်ပြီး error-handling middleware ဆီ ခုန်သွားပါတယ်။
27. JSON request body ကို ဘယ်လို parse လုပ်မလဲ?
Route တွေ မတိုင်ခင် built-in express.json() middleware ကို ထည့်ပါ။ Content-Type: application/json header ပါတဲ့ request တွေကို ဖတ်ပြီး body ကို parse လုပ်ကာ req.body ပေါ် တင်ပေးပါတယ်။ HTML form post တွေအတွက် express.urlencoded() ကို သုံးပါ။ Server ကို ကာကွယ်ဖို့ express.json({ limit: "100kb" }) လို size limit သတ်မှတ်လို့ရပါတယ်။
28. Status code နဲ့ JSON ကို ဘယ်လို ပို့မလဲ?
res.status(code) ကို res.json(data) နဲ့ chain လုပ်ပါ။ ရလဒ်နဲ့ ကိုက်တဲ့ status ကို ရွေးပါ — အောင်မြင်ရင် 200၊ တစ်ခုခု ဖန်တီးလိုက်ရင် 201၊ body မပါတဲ့ အောင်မြင်မှုအတွက် 204၊ input မှားရင် 400၊ login မဝင်ရသေးရင် 401၊ ခွင့်မပြုရင် 403၊ မတွေ့ရင် 404 နဲ့ မမျှော်လင့်ထားတဲ့ server error အတွက် 500။
app.post("/users", async (req, res) => { if (!req.body.email) { return res.status(400).json({ error: "Email is required" }); } const user = await createUser(req.body); res.status(201).json(user);});29. Express နဲ့ static file တွေကို ဘယ်လို serve လုပ်မလဲ?
Folder တစ်ခုနဲ့ express.static ကို သုံးပါ — app.use(express.static("public")) က public/logo.png ကို /logo.png မှာ serve လုပ်ပါတယ်။ Caching header နဲ့ content type တွေကို ကိုင်တွယ်ပေးပါတယ်။ Production မှာ static file တွေကို များသောအားဖြင့် ပိုမြန်တဲ့ CDN ဒါမှမဟုတ် Nginx လို reverse proxy က serve လုပ်ပါတယ်။
30. REST ဆိုတာ ဘာလဲ?
REST ဆိုတာ URL တွေနဲ့ ခွဲခြားသတ်မှတ်ထားတဲ့ resource တွေကို အခြေခံပြီး action တွေအတွက် HTTP method တွေကို သုံးကာ API design လုပ်တဲ့ ပုံစံပါ — GET /users က user စာရင်း၊ POST /users က အသစ်ဖန်တီး၊ GET /users/42 က တစ်ယောက်ကို ဖတ်၊ PATCH /users/42 က တစ်စိတ်တစ်ပိုင်း update၊ DELETE /users/42 က ဖျက်ပါတယ်။ Response တွေက standard status code တွေကို သုံးပြီး stateless ဖြစ်ပါတယ် — request တိုင်းမှာ server လိုတာအားလုံး ပါပါတယ်။
31. HTTP method GET၊ POST၊ PUT၊ PATCH နဲ့ DELETE က ဘာကိုဆိုလိုလဲ?
Method တစ်ခုချင်းက request ရဲ့ ရည်ရွယ်ချက်ကို ဖော်ပြပါတယ်။
- GET — data ဖတ်တာ၊ ဘာမှ မပြောင်းရဘူး
- POST — resource ဖန်တီးတာ ဒါမှမဟုတ် action တစ်ခု trigger လုပ်တာ
- PUT — resource ကို အပြည့် အစားထိုးတာ
- PATCH — resource ရဲ့ တစ်စိတ်တစ်ပိုင်းကို update လုပ်တာ
- DELETE — resource ကို ဖျက်တာ
32. JSON ဆိုတာ ဘာလဲ၊ API တွေမှာ ဘာကြောင့် သုံးလဲ?
JSON (JavaScript Object Notation) ဆိုတာ structured data — object၊ array၊ string၊ number၊ boolean နဲ့ null — အတွက် ပေါ့ပါးတဲ့ text format ပါ။ လူဖတ်ရလွယ်ပြီး language တိုင်း parse လုပ်နိုင်တာမို့ web API တွေရဲ့ default format ပါ။ Node မှာ JSON.stringify နဲ့ JSON.parse က JSON text နဲ့ JavaScript value တွေကြား ပြောင်းပေးပါတယ်။
33. CORS ဆိုတာ ဘာလဲ၊ Express မှာ ဘယ်လို ဖွင့်မလဲ?
CORS ဆိုတာ browser security rule ပါ — web page က တခြား origin ကနေ response တွေကို ဖတ်ခွင့်ရဖို့ အဲ့ server က Access-Control-Allow-Origin လို header တွေနဲ့ ခွင့်ပြုရပါမယ်။ Express မှာ cors middleware က ဒီ header တွေကို သတ်မှတ်ပေးပါတယ်။ Cookie သုံးတဲ့ API တွေအတွက် * မဟုတ်ဘဲ ကိုယ့် front-end URL လို ယုံကြည်ရတဲ့ origin တွေကိုပဲ ခွင့်ပြုပါ။
import cors from "cors"; app.use( cors({ origin: ["https://myapp.com"], credentials: true, }),);34. Express မှာ မသိတဲ့ route တွေအတွက် 404 ကို ဘယ်လို ကိုင်တွယ်မလဲ?
Route အားလုံးရဲ့ နောက်မှာ middleware တစ်ခု ထည့်ပါ။ Request က အဲ့ဒီကို ရောက်လာရင် ဘယ် route နဲ့မှ မကိုက်ခဲ့လို့ 404 နဲ့ တုံ့ပြန်ပါတယ်။ Error-handling middleware ရဲ့ ရှေ့မှာ ထားပါ။
// after all routesapp.use((req, res) => { res.status(404).json({ error: `Not found: ${req.method} ${req.path}` });});35. Express မှာ error-handling middleware ဆိုတာ ဘာလဲ?
Argument လေးခုပါတဲ့ middleware ပါ — (err, req, res, next)။ Route က next(err) ကို ခေါ်တဲ့အခါ ဒါမှမဟုတ် throw လုပ်တဲ့အခါ Express က ခေါ်ပါတယ် — Express 5 မှာ async handler ရဲ့ promise reject ဖြစ်တဲ့အခါလည်း ခေါ်ပါတယ်။ နောက်ဆုံးမှာ ထားပါ၊ error ကို log လုပ်ပြီး client တွေဆီ stack trace မပေါက်ကြားဘဲ လုံခြုံတဲ့ message ပို့ပါ။
app.use((err, req, res, next) => { console.error(err); const status = err.status ?? 500; res.status(status).json({ error: status === 500 ? "Something went wrong" : err.message, });});36. express.Router ဆိုတာ ဘာလဲ၊ ဘာကြောင့် သုံးလဲ?
express.Router() က ကိုယ်ပိုင် route နဲ့ middleware ပါတဲ့ app အသေးလေးတစ်ခု ဖန်တီးပေးပါတယ်။ ဆက်စပ်တဲ့ route တွေကို file သီးခြား — user၊ order၊ auth — အုပ်စုဖွဲ့ပြီး app.use("/api/users", usersRouter) လို prefix နဲ့ mount လုပ်ပါတယ်။ ကြီးလာတဲ့ API ကို စနစ်တကျ ထိန်းထားပေးပါတယ်။
// routes/users.jsimport { Router } from "express";export const usersRouter = Router(); usersRouter.get("/", listUsers);usersRouter.get("/:id", getUser);usersRouter.post("/", createUser); // app.jsapp.use("/api/users", usersRouter);37. nodemon ဆိုတာ ဘာလဲ၊ modern Node မှာ လိုသေးလား?
nodemon က file save လုပ်တိုင်း Node app ကို အလိုအလျောက် restart လုပ်ပေးလို့ development ကို မြန်စေပါတယ်။ Modern Node မှာ ဒါ ပါပြီးသားပါ — node --watch app.js က file ပြောင်းတိုင်း restart လုပ်ပါတယ်။ နှစ်ခုစလုံးကို production မှာ မသုံးသင့်ပါဘူး။
38. Express app ကို database နဲ့ ဘယ်လို ချိတ်မလဲ?
ကိုယ့် database အတွက် driver ဒါမှမဟုတ် library ကို install လုပ်ပါ — PostgreSQL အတွက် pg၊ MongoDB အတွက် mongodb ဒါမှမဟုတ် Mongoose၊ ဒါမှမဟုတ် Prisma၊ Drizzle လို ORM။ App စတင်တဲ့အခါ connection ဒါမှမဟုတ် connection pool တစ်ခု ဖန်တီးပြီး request တိုင်းမှာ ပြန်သုံးကာ connection string ကို environment variable ကနေ ဖတ်ပါ။ Connection error တွေကို ကိုင်တွယ်ပြီး shutdown မှာ pool ကို ပိတ်ပါ။
39. SQL နဲ့ NoSQL database တွေ ဘာကွာလဲ?
SQL database (PostgreSQL၊ MySQL) တွေက data ကို fixed schema နဲ့ relationship တွေပါတဲ့ table တွေထဲမှာ သိမ်းပြီး အားကောင်းတဲ့ query နဲ့ transaction တွေအတွက် SQL ကို သုံးပါတယ်။ NoSQL database (MongoDB၊ Redis၊ DynamoDB) တွေက document၊ key-value လို တခြား model တွေကို ပိုပြောင်းလွယ်တဲ့ schema နဲ့ horizontal scaling လွယ်ကူမှုနဲ့ သုံးပါတယ်။ ကိုယ့် data ပုံစံနဲ့ လိုအပ်တဲ့ query တွေပေါ်မူတည်ပြီး ရွေးပါ။
40. Mongoose ဆိုတာ ဘာလဲ?
Mongoose ဆိုတာ Node မှာ MongoDB အတွက် ODM (object-document mapper) ပါ။ Type နဲ့ validation ပါတဲ့ schema တွေ သတ်မှတ်၊ အဲ့ဒါတွေကနေ model တွေ ဖန်တီးပြီး find၊ create၊ updateOne လို method တွေကို သုံးပါတယ်။ Plain MongoDB driver ရဲ့ အပေါ်မှာ structure၊ validation နဲ့ population လို helper တွေကို ထပ်ထည့်ပေးပါတယ်။
41. Password တွေကို plain text အနေနဲ့ ဘာကြောင့် ဘယ်တော့မှ မသိမ်းရတာလဲ?
Database ပေါက်ကြားရင် user တိုင်းရဲ့ password — များသောအားဖြင့် တခြား site တွေမှာလည်း ပြန်သုံးထားတဲ့ — ပေါ်သွားပါတယ်။ bcrypt ဒါမှမဟုတ် argon2 လို password-hashing algorithm နဲ့ ဖန်တီးထားတဲ့ နှေးပြီး salt ပါတဲ့ hash ကိုပဲ သိမ်းပါ။ Login ဝင်တဲ့အခါ ကြိုးစားတဲ့ password ကို hash လုပ်ပြီး နှိုင်းယှဉ်ပါ။ Password တွေအတွက် MD5 ဒါမှမဟုတ် SHA-256 လို မြန်တဲ့ hash တွေကို တစ်ခုတည်း ဘယ်တော့မှ မသုံးပါနဲ့။
42. Express API မှာ input ကို ဘယ်လို validate လုပ်မလဲ?
req.body၊ req.params ဒါမှမဟုတ် req.query ကို ဘယ်တော့မှ မယုံပါနဲ့။ မသုံးခင် လိုအပ်တဲ့ field တွေ ရှိလား၊ type နဲ့ format မှန်လား စစ်ပြီး မမှန်ရင် ရှင်းလင်းတဲ့ message နဲ့ 400 ပြန်ပေးပါ။ Zod ဒါမှမဟုတ် Joi လို library တွေက မျှော်လင့်ထားတဲ့ ပုံစံကို တစ်ကြိမ်ဖော်ပြပြီး line တစ်ကြောင်းနဲ့ validate လုပ်ခွင့်ပေးပါတယ်။
43. Status code 500 ဆိုတာ ဘာလဲ၊ user အမှားတွေအတွက် မပို့မိအောင် ဘယ်လို ရှောင်မလဲ?
500 ဆိုတာ server ပေါ်က မမျှော်လင့်ထားတဲ့ error ကို ဆိုလိုပါတယ်။ ရှားရှားပါးပါးပဲ ဖြစ်သင့်ပြီး အမြဲ စုံစမ်းရပါမယ်။ Client က တစ်ခုခု မှားလုပ်တဲ့အခါ — field ကျန်တာ၊ ID မှားတာ၊ မသိတဲ့ resource — 4xx code နဲ့ အသုံးဝင်တဲ့ message နဲ့ တုံ့ပြန်ပါ၊ ဒါဆို client က request ကို ဘယ်လိုပြင်ရမလဲ သိပြီး ကိုယ့် monitoring လည်း မလျှံသွားပါဘူး။
44. API endpoint ကို manual ဘယ်လို test လုပ်မလဲ?
HTTP request ပို့တဲ့ tool ကို သုံးပါ — terminal ထဲက curl၊ Postman၊ Insomnia၊ Bruno ဒါမှမဟုတ် editor ထဲက REST client။ Method၊ URL၊ Content-Type: application/json လို header တွေနဲ့ body ကို သတ်မှတ်ပြီး status code နဲ့ response ကို စစ်ပါ။ Teammate တွေ ပြန်သုံးနိုင်အောင် request တွေကို collection ထဲ သိမ်းပါ။
45. Node app အတွက် logging အခြေခံတွေက ဘာတွေလဲ?
အသုံးဝင်တဲ့ event တွေကို log လုပ်ပါ — server စတင်တာ၊ request တိုင်းကို method၊ path၊ status နဲ့ ကြာချိန်နဲ့၊ error တိုင်းကို သူ့ stack နဲ့။ Filter လုပ်နိုင်အောင် level (info၊ warn၊ error) တွေ သုံးပါ။ သင်ယူဖို့ console.log က အဆင်ပြေပေမဲ့ app အစစ်တွေက pino လို structured logger ကို သုံးပါတယ်။ Password၊ token ဒါမှမဟုတ် ကိုယ်ရေးကိုယ်တာ data တွေကို ဘယ်တော့မှ log မလုပ်ပါနဲ့။
46. npm script တွေနဲ့ Node app ကို ဘယ်လို run မလဲ?
package.json ရဲ့ scripts section ထဲမှာ "dev": "node --watch --env-file=.env src/server.js" နဲ့ "start": "node src/server.js" လို command တွေ သတ်မှတ်ပြီး npm run dev ဒါမှမဟုတ် npm start ကို run ပါ။ Script တွေက team ထဲက လူတိုင်းကို command အတူတူ ပေးပြီး test နဲ့ linting လို tool တွေကို chain လုပ်နိုင်ပါတယ်။
47. setTimeout၊ setImmediate နဲ့ process.nextTick ဘာကွာလဲ?
process.nextTick က callback ကို လက်ရှိ operation ပြီးချင်း၊ I/O ဒါမှမဟုတ် timer မတိုင်ခင် run ပါတယ်။ setImmediate က I/O callback တွေပြီးနောက် event loop ရဲ့ "check" phase မှာ run ပါတယ်။ setTimeout(fn, 0) က timers phase မှာ ပေးထားတဲ့ delay အနည်းဆုံး ကုန်ပြီးမှ run ပါတယ်။ nextTick ကို အလွန်အကျွံသုံးရင် I/O ကို ငတ်စေနိုင်တာမို့ promise ဒါမှမဟုတ် setImmediate ကို ဦးစားပေးပါ။
48. Node.js က TypeScript ကို run နိုင်လား?
ရပါတယ်။ Modern Node version တွေက erasable TypeScript syntax ကိုပဲ သုံးထားသရွေ့ type annotation တွေကို ဖယ်ရှားပြီး .ts file တွေကို တိုက်ရိုက် run နိုင်ပါတယ်။ Node ကိုယ်တိုင် type မစစ်တာမို့ project အများစုက tsc နဲ့ compile လုပ်ဆဲ ဒါမှမဟုတ် tsx လို runner တွေ သုံးဆဲဖြစ်ပြီး type checking အတွက် CI မှာ tsc --noEmit ကို run ပါတယ်။
49. ရိုးရှင်းတဲ့ Node နဲ့ Express API ကို ဘယ်လို deploy လုပ်မလဲ?
Railway၊ Render၊ Fly.io ဒါမှမဟုတ် VPS လို platform တစ်ခု ရွေးပါ။ Environment variable တွေကို အဲ့မှာ သတ်မှတ်ပါ၊ app က process.env.PORT မှာ listen လုပ်တာ သေချာပါစေ၊ npm ci --omit=dev နဲ့ install လုပ်ပြီး (nodemon မဟုတ်ဘဲ) node နဲ့ စတင်ပါ။ Health-check route ထည့်ပါ၊ ရှေ့မှာ HTTPS ထားပြီး secret တွေကို repository ထဲ မထည့်ပါနဲ့။
50. ကိုယ်တိုင်တည်ဆောက်ခဲ့တဲ့ Node ဒါမှမဟုတ် Express project အသေးလေးအကြောင်း ပြောပြပါ။
Project အစစ်တစ်ခုကို ရွေးပြီး အတိုချုပ် ရှင်းပြပါ — API က ဘာလုပ်လဲ၊ အဓိက route တွေနဲ့ data model၊ validation နဲ့ error တွေကို ဘယ်လို ကိုင်တွယ်ခဲ့လဲ၊ database နဲ့ ဘယ်လို ချိတ်လဲ၊ ဖြေရှင်းခဲ့တဲ့ ပြဿနာတစ်ခုနဲ့ ဘာကို တိုးတက်အောင် လုပ်ချင်လဲ။ Repository ဒါမှမဟုတ် deploy လုပ်ထားတဲ့ URL ကို အသင့်ထားပါ — ရှင်းပြနိုင်တဲ့ သန့်ရှင်းပြီး အလုပ်လုပ်တဲ့ API အသေးလေးက မပြီးသေးတဲ့ ကြီးကြီးမားမားထက် သာပါတယ်။
Mid-Level — Production API တွေ တည်ဆောက်ခြင်း
Mid-level interview တွေမှာ API အစစ်တစ်ခုကို ကိုယ်တိုင် တည်ဆောက်ပြီး run နိုင်ဖို့ မျှော်လင့်ပါတယ် — event loop နဲ့ stream တွေ၊ Express codebase ကို structure လုပ်တာ၊ authentication၊ validation၊ database၊ testing နဲ့ error handling။ Interviewer တွေက လက်တွေ့ကျတဲ့ ဆုံးဖြတ်ချက်ကို ရှာပါတယ် — နည်းလမ်းတစ်ခုကို ဘာကြောင့် ရွေးခဲ့လဲ၊ အဲ့ဒါနဲ့ ဘာတွေ မှားနိုင်လဲ။
51. Node.js event loop ရဲ့ phase တွေကို ဖော်ပြပါ။
Event loop ရဲ့ အလှည့်တိုင်းက phase တွေကို အစဉ်လိုက် ဖြတ်သွားပါတယ်။
- timers — အချိန်ရောက်ပြီဖြစ်တဲ့
setTimeoutနဲ့setIntervalက callback တွေ - pending callbacks — ရွှေ့ဆိုင်းထားတဲ့ system I/O callback တချို့
- poll — I/O callback တွေကို စောင့်ပြီး run တယ် (ကိုယ့်အလုပ်အများစု ဒီမှာ ဖြစ်တယ်)
- check —
setImmediatecallback တွေ - close callbacks — ဥပမာ socket ရဲ့
closeevent၊ callback တိုင်းကြားမှာprocess.nextTickနဲ့ promise microtask တွေ run တယ်
52. libuv ဆိုတာ ဘာလဲ၊ thread pool ကို ဘာအတွက် သုံးလဲ?
libuv ဆိုတာ event loop နဲ့ asynchronous I/O ကို implement လုပ်ထားတဲ့ Node ရဲ့ အောက်က C library ပါ။ Network I/O က operating system ရဲ့ non-blocking mechanism တွေကို သုံးပေမဲ့ အလုပ်တချို့ — file system call၊ dns.lookup နဲ့ DNS lookup၊ crypto နဲ့ zlib function တချို့ — ကို အဲ့လိုမလုပ်နိုင်တာမို့ libuv က thread pool သေးသေးလေး (default 4 thread၊ UV_THREADPOOL_SIZE နဲ့ သတ်မှတ်) ပေါ်မှာ run ပါတယ်။
53. Microtask တွေနဲ့ process.nextTick က event loop ထဲမှာ ဘယ်လို နေရာယူလဲ?
Callback တစ်ခုပြီးတိုင်း Node က ရှေ့ဆက်မသွားခင် process.nextTick queue ကို အရင်ရှင်းပြီးမှ promise microtask queue ကို ရှင်းပါတယ်။ ဒါကြောင့် nextTick callback တွေက resolve ဖြစ်ပြီးသား promise တွေထက် အရင် run ပြီး နှစ်ခုစလုံး timer ဒါမှမဟုတ် I/O ထက် အရင် run ပါတယ်။ Recursive nextTick ဒါမှမဟုတ် microtask chain အဆုံးမဲ့က event loop ကို ငတ်စေနိုင်ပါတယ်။
setTimeout(() => console.log("timeout"), 0);setImmediate(() => console.log("immediate"));Promise.resolve().then(() => console.log("promise"));process.nextTick(() => console.log("nextTick"));console.log("sync");// sync, nextTick, promise, then timeout/immediate54. Event loop ကို block လုပ်တယ်ဆိုတာ ဘာကိုဆိုလိုလဲ၊ ဘယ်လို ရှောင်မလဲ?
Block လုပ်တယ်ဆိုတာ synchronous အလုပ်ရှည်ကြီး — loop ကြီး၊ JSON.parse အကြီးကြီး၊ synchronous crypto ဒါမှမဟုတ် file call၊ catastrophic regular expression — run လို့ thread တစ်ခုတည်းက တခြား request တွေကို serve မလုပ်နိုင်တော့တာပါ။ Request handler တွေကို asynchronous ထားပါ၊ data ကြီးတွေကို paginate နဲ့ stream လုပ်ပါ၊ API တွေရဲ့ async version ကို သုံးပြီး CPU လေးတဲ့ အလုပ်ကို worker thread ဒါမှမဟုတ် background job ဆီ ရွှေ့ပါ။
55. Node.js မှာ stream တွေဆိုတာ ဘာလဲ?
Stream တွေက data အားလုံးကို memory ထဲ load မလုပ်ဘဲ တစ်ပိုင်းချင်း process လုပ်ပါတယ်။ အမျိုးအစား လေးမျိုး ရှိပါတယ် — Readable (ဖတ်နေတဲ့ file၊ HTTP request)၊ Writable (ရေးနေတဲ့ file၊ HTTP response)၊ Duplex (TCP socket) နဲ့ Transform (gzip compression)။ ဘယ်လောက်ကြီးတဲ့ file နဲ့ response တွေကိုမဆို memory တည်ငြိမ်စွာနဲ့ ကိုင်တွယ်ခွင့်ပေးပါတယ်။
56. Backpressure ဆိုတာ ဘာလဲ၊ pipeline က ဘယ်လို ကိုင်တွယ်လဲ?
Backpressure ဆိုတာ destination က ရေးနိုင်တာထက် data က ပိုမြန်မြန် ရောက်လာတာပါ၊ မကိုင်တွယ်ရင် memory ပြည့်သွားပါတယ်။ Writable stream တွေက write() ကနေ false ပြန်ပေးပြီး ဒါကို signal ပေးပါတယ်။ stream.pipeline က stream တွေကို ချိတ်ပြီး destination ပြည့်နေရင် source ကို ခဏရပ်ကာ တစ်ခုခု fail ဖြစ်ရင် error တွေကို ဆက်ပို့ပြီး stream တိုင်းကို ရှင်းလင်းပေးပါတယ်။
import { pipeline } from "node:stream/promises";import { createReadStream, createWriteStream } from "node:fs";import { createGzip } from "node:zlib"; await pipeline( createReadStream("access.log"), createGzip(), createWriteStream("access.log.gz"),);57. Buffer ဆိုတာ ဘာလဲ?
Buffer ဆိုတာ raw binary data အတွက် Node ရဲ့ type ပါ — V8 heap ပြင်ပက size သတ်မှတ်ထားတဲ့ byte အစုအဝေး။ Encoding မပါဘဲ file ဖတ်တဲ့အခါ၊ network socket တွေနဲ့ crypto function တွေကနေ Buffer တွေ ရပါတယ်။ buf.toString("utf8") ဒါမှမဟုတ် Buffer.from(text, "utf8") နဲ့ ပြောင်းပြီး chunk နယ်နိမိတ်တွေမှာ multi-byte text ကို မှန်မှန်ကန်ကန် decode လုပ်ဖို့ သတိထားပါ။
58. File ကြီးတစ်ခုကို client ဆီ efficient ဖြစ်အောင် ဘယ်လို ပို့မလဲ?
Memory ထဲ ဖတ်ထည့်မယ့်အစား stream လုပ်ပါ — read stream ကို response ထဲ pipe လုပ်ပါ၊ ဒါမှမဟုတ် stream လုပ်ပြီး header တွေ သတ်မှတ်ပေးတဲ့ res.sendFile / res.download ကို သုံးပါ။ Content-Type နဲ့ Content-Disposition ကို သတ်မှတ်ပါ၊ media အတွက် range request တွေကို support လုပ်ပြီး public file ကြီးတွေအတွက် S3 လို object storage ပေါ်က signed URL ဆီ redirect လုပ်ဖို့ စဉ်းစားပါ။
59. Express မှာ middleware order က ဘာကြောင့် အရေးကြီးလဲ?
Express က middleware နဲ့ route တွေကို register လုပ်ခဲ့တဲ့ order အတိုင်း run တာမို့ order က behaviour ပါပဲ။ Body parser တွေက req.body ကို ဖတ်တဲ့ route တွေ ရှေ့မှာ၊ authentication က သူကာကွယ်တဲ့ route တွေ ရှေ့မှာ၊ CORS နဲ့ security header တွေက အစောပိုင်းမှာ၊ 404 handler က route အားလုံးနောက်မှာ၊ error handler က နောက်ဆုံးမှာ ရှိရပါမယ်။ နေရာမှားနေတဲ့ app.use က bug တွေရဲ့ အဖြစ်များတဲ့ အရင်းအမြစ်ပါ။
60. Async code အတွက် error handling က Express 5 နဲ့ Express 4 မှာ ဘယ်လို ကွာလဲ?
Express 4 မှာ async handler ထဲက rejected promise ကို မဖမ်းပေးပါဘူး — handler တွေကို ထုပ်ရတယ် ဒါမှမဟုတ် next(err) ကို ကိုယ်တိုင်ခေါ်ရတယ်၊ မဟုတ်ရင် request က ဆွဲထားခံရပါတယ်။ Express 5 က async handler နဲ့ middleware ထဲက rejected promise နဲ့ throw လုပ်တဲ့ error တွေကို အလိုအလျောက် ဖမ်းပြီး ကိုယ့် error handler ဆီ ပို့ပေးတာမို့ ရိုးရိုးလေး throw လုပ်လို့ ဒါမှမဟုတ် await ကို reject ဖြစ်ခွင့်ပေးလို့ ရပါတယ်။
// Express 5: no wrapper neededapp.get("/users/:id", async (req, res) => { const user = await db.users.findById(req.params.id); if (!user) throw new NotFoundError("User not found"); res.json(user);});61. Express 5 မှာ route path syntax ဘာတွေ ပြောင်းသွားလဲ?
Express 5 က path-to-regexp အသစ်ကို သုံးတာမို့ pattern တချို့ ပြောင်းသွားပါတယ်။ Wildcard တွေကို နာမည်ပေးရပါမယ် — /* အစား /*splat — ပြီး segment တွေကို array အဖြစ် ဖမ်းယူပါတယ်။ Optional အပိုင်းတွေက ? အစား /:file{.:ext} လို brace တွေ သုံးပါတယ်။ Path string ထဲက regular-expression character တွေကို support မလုပ်တော့ဘဲ req.query က read-only ဖြစ်သွားပါပြီ။
62. အလယ်အလတ်အရွယ် Express project ကို ဘယ်လို structure လုပ်မလဲ?
Layer တစ်ခုချင်း အလုပ်တစ်ခုပဲ လုပ်အောင် ခွဲပါ — route တွေက endpoint တွေကို ကြေညာတယ်၊ controller တွေက HTTP ကို function call အဖြစ် ဘာသာပြန်တယ်၊ service တွေက business logic ကို ကိုင်တယ်၊ repository ဒါမှမဟုတ် data-access module တွေက database နဲ့ ဆက်သွယ်တယ်။ Code ကို feature (users/၊ orders/) အလိုက် အုပ်စုဖွဲ့ပြီး test တွေက server မစဘဲ app ကို import လုပ်နိုင်အောင် config နဲ့ app setup ကို server.js နဲ့ သီးခြားထားပါ။
63. Authentication နဲ့ authorisation ဘာကွာလဲ?
Authentication က "မင်းဘယ်သူလဲ?" ကို ဖြေပါတယ် — password၊ token ဒါမှမဟုတ် OAuth login နဲ့ identity ကို အတည်ပြုတာ။ Authorisation က "မင်းဘာလုပ်ခွင့်ရှိလဲ?" ကို ဖြေပါတယ် — role ဒါမှမဟုတ် resource ပိုင်ဆိုင်မှုလို permission တွေ စစ်တာ။ Request က authenticate ဖြစ်ပေမဲ့ ခွင့်မပြုနိုင်ပါတယ် — ဒါက 403 ဖြစ်ပြီး credential မရှိတာ ဒါမှမဟုတ် မမှန်တာက 401 ပါ။
64. JWT authentication ဘယ်လိုအလုပ်လုပ်လဲ?
Login ပြီးနောက် server က user ID နဲ့ expiry လို claim တွေပါတဲ့ JSON Web Token ကို sign လုပ်ပြီး client ကို ပေးပါတယ်။ Client က နောက်ပိုင်း request တွေမှာ များသောအားဖြင့် Authorization: Bearer header ဒါမှမဟုတ် cookie နဲ့ ပို့ပြီး server က session ရှာမယ့်အစား signature ကို verify လုပ်ပါတယ်။ Token တွေကို သက်တမ်းတိုတိုထားပါ၊ payload ထဲ secret တွေ ဘယ်တော့မှ မထည့်ပါနဲ့ (encode လုပ်ထားရုံသာ ဖြစ်ပြီး encrypt မလုပ်ထားပါဘူး)၊ refresh နဲ့ revocation အတွက် ကြိုစီစဉ်ပါ။
65. Session နဲ့ JWT — ဘယ်လို ရွေးမလဲ?
Server-side session တွေက state ကို Redis လို store ထဲမှာ သိမ်းပြီး browser ကို opaque ID cookie ပေးပါတယ်၊ revoke လုပ်ရလွယ်ပြီး web app တွေအတွက် ရိုးရှင်းပါတယ်။ JWT တွေက ကိုယ့်ဘာသာ ပြည့်စုံတာမို့ service တွေက shared store မလိုဘဲ verify လုပ်နိုင်လို့ API နဲ့ microservice တွေနဲ့ သင့်တော်ပေမဲ့ သက်တမ်းမကုန်ခင် revoke လုပ်ရခက်ပါတယ်။ Web app အများစုက session သုံးပြီး API အများစုက သက်တမ်းတို JWT နဲ့ refresh token တွေ သုံးပါတယ်။
66. Web app က authentication token တွေကို ဘယ်လို သိမ်းသင့်လဲ?
Browser app တွေအတွက် server က သတ်မှတ်ပေးတဲ့ HttpOnly၊ Secure၊ SameSite cookie ကို ဦးစားပေးပါ — JavaScript က ဖတ်လို့မရလို့ XSS bug တစ်ခုက ခိုးလို့မရပါဘူး။ localStorage ထဲက token တွေကို inject လုပ်ခံရတဲ့ script မှန်သမျှ ဖတ်နိုင်ပါတယ်။ Cookie သုံးရင် state ပြောင်းတဲ့ request တွေကို SameSite နဲ့၊ လိုအပ်ရင် CSRF token တွေနဲ့ CSRF ကနေ ကာကွယ်ပါ။
67. Node မှာ password တွေကို ဘယ်လို မှန်မှန်ကန်ကန် hash လုပ်မလဲ?
Hash လုပ်တာ မီလီစက္ကန့် ဆယ်ချီ ကြာအောင် ချိန်ညှိထားတဲ့ cost factor နဲ့ နှေးပြီး salt ပါတဲ့ password-hashing function — bcrypt ဒါမှမဟုတ် argon2 — ကို သုံးပါ။ Event loop မပိတ်ဆို့အောင် library ရဲ့ async function နဲ့ hash လုပ်ပြီး timing attack ကနေ လုံခြုံတဲ့ သူ့ verify function နဲ့ နှိုင်းယှဉ်ပါ။ Cost factor ကို မြှင့်တဲ့အခါ ပြန် hash လုပ်ပါ။
import bcrypt from "bcrypt"; export async function hashPassword(plain) { return bcrypt.hash(plain, 12);} export async function checkPassword(plain, hash) { return bcrypt.compare(plain, hash);}68. Express မှာ schema နဲ့ request တွေကို ဘယ်လို validate လုပ်မလဲ?
မျှော်လင့်ထားတဲ့ body၊ params နဲ့ query ကို Zod လို schema library နဲ့ ဖော်ပြပြီး controller မ run ခင် middleware သေးသေးလေး တစ်ခုထဲမှာ validate လုပ်ပါ။ Fail ဖြစ်ရင် ပြဿနာစာရင်းနဲ့ 400 ပြန်ပေးပါ။ အောင်မြင်ရင် controller က သန့်ရှင်းတဲ့ data ကိုပဲ မြင်ရအောင် raw input ကို parse လုပ်ပြီး type ပါတဲ့ value နဲ့ အစားထိုးပါ။
import { z } from "zod"; const CreateUser = z.object({ email: z.string().email(), name: z.string().min(1).max(80),}); const validate = (schema) => (req, res, next) => { const result = schema.safeParse(req.body); if (!result.success) { return res.status(400).json({ errors: result.error.issues }); } req.body = result.data; next();}; app.post("/users", validate(CreateUser), createUser);69. တသမတ်တည်းရှိတဲ့ error response format ကို ဘယ်လို design လုပ်မလဲ?
ပုံစံတစ်ခုကို ရွေးပြီး နေရာတိုင်းမှာ သုံးပါ — ဥပမာ { error: { code, message, details } } ဒါမှမဟုတ် RFC 9457 Problem Details format။ လူဖတ်ဖို့ message တွေနဲ့အတူ VALIDATION_FAILED လို machine ဖတ်လို့ရတဲ့ တည်ငြိမ်တဲ့ code တွေ သုံးပါ၊ support အတွက် request ID ထည့်ပြီး production response တွေမှာ stack trace ဒါမှမဟုတ် internal detail တွေ ဘယ်တော့မှ မထည့်ပါနဲ့။
70. API မှာ pagination ကို ဘယ်လို implement လုပ်မလဲ?
Offset pagination (?page=3&limit=20) က ရိုးရှင်းပြီး user တွေကို page တစ်ခုဆီ ခုန်ခွင့်ပေးပေမဲ့ table ကြီးတွေမှာ နှေးလာပြီး data ပြောင်းတဲ့အခါ row တွေ ကျော်သွားတာ ဒါမှမဟုတ် ထပ်နေတာ ဖြစ်နိုင်ပါတယ်။ Cursor pagination (?after=<lastId>&limit=20) က index ပါတဲ့ column ကို သုံးလို့ မြန်နေပြီး feed နဲ့ infinite scroll အတွက် တည်ငြိမ်ပါတယ်။ Limit ကို အမြဲ ကန့်သတ်ပြီး နောက် cursor ဒါမှမဟုတ် စုစုပေါင်းကို metadata အဖြစ် ပြန်ပေးပါ။
71. N+1 query ပြဿနာ ဆိုတာ ဘာလဲ?
Code က list ယူဖို့ query တစ်ခု run ပြီး item တစ်ခုချင်းအတွက် query တစ်ခုစီ ထပ် run တာပါ — post 50 ခုအတွက် query 1 ခုနဲ့ သူတို့ author တွေအတွက် query 50 ခု။ နှေးပြီး database ကို ဝန်ပိစေပါတယ်။ Join၊ IN (...) batch query၊ ORM ရဲ့ eager loading (include၊ populate) ဒါမှမဟုတ် lookup တွေကို batch လုပ်ပေးတဲ့ DataLoader နဲ့ ပြင်ပါ။
72. Database connection pool ကို ဘာကြောင့် သုံးလဲ?
Database connection ဖွင့်တာ နှေးပြီး database တွေက connection အရေအတွက် ကန့်သတ်ချက် ရှိပါတယ်။ Pool က ဖွင့်ထားတဲ့ connection အစုကို ထိန်းထားပြီး request တွေကို ငှားပေးကာ query ပြီးတာနဲ့ ပြန်ယူပါတယ်။ Startup မှာ process တစ်ခုချင်းအတွက် pool တစ်ခု ဖန်တီးပါ၊ instance အားလုံးကို ပေါင်းပြီး database ခံနိုင်သလောက် size ထားပါ၊ error ဖြစ်ရင်တောင် connection တွေကို အမြဲ ပြန်လွှတ်ပါ။
73. Database transaction ဆိုတာ ဘာလဲ၊ ဘယ်အချိန် လိုလဲ?
Transaction က write အများအပြားကို အုပ်စုဖွဲ့လို့ အားလုံးအောင်မြင်တာ ဒါမှမဟုတ် အားလုံး rollback ဖြစ်တာ ဖြစ်ပါတယ် — ဥပမာ stock နုတ်တာနဲ့ order ဖန်တီးတာကို အတူလုပ်တာ။ Business operation တစ်ခုက တသမတ်တည်း ရှိနေရမယ့် row ဒါမှမဟုတ် table အများကြီးကို ထိတိုင်း သုံးပါ။ Transaction တွေကို တိုတိုထားပြီး conflict ဒါမှမဟုတ် deadlock တွေကို retry နဲ့ ကိုင်တွယ်ပါ။
74. SQL နဲ့ NoSQL injection ကို ဘယ်လို ကာကွယ်မလဲ?
User input ကို ဆက်ပေါင်းပြီး query တွေ ဘယ်တော့မှ မတည်ဆောက်ပါနဲ့။ Parameterised query တွေ ဒါမှမဟုတ် ကိုယ့်အတွက် parameterise လုပ်ပေးတဲ့ ORM/query builder ကို သုံးပါ။ MongoDB အတွက် string ကို မျှော်လင့်တဲ့နေရာမှာ attacker က { "$gt": "" } လို object ပို့မရအောင် input type တွေကို validate လုပ်ပြီး raw request object တွေကို query ထဲ တိုက်ရိုက် မထည့်ပါနဲ့။
// unsafe: string concatenation// db.query(`SELECT * FROM users WHERE email = '${email}'`) // safe: parameterisedconst { rows } = await pool.query( "SELECT id, email FROM users WHERE email = $1", [email],);75. Express app ကို ဘယ် security middleware တွေ ထည့်မလဲ?
လူသိများတဲ့ package အနည်းငယ်က အခြေခံတွေကို ဖုံးပေးပါတယ်။
helmet— လုံခြုံတဲ့ HTTP header တွေ သတ်မှတ်တယ်cors— ယုံကြည်ရတဲ့ origin တွေကိုပဲ ခွင့်ပြုတယ်express-rate-limit— brute force နဲ့ အလွဲသုံးစားကို နှေးစေဖို့ client တစ်ခုချင်းရဲ့ request ကို ကန့်သတ်တယ်- Payload အကြီးကြီးတွေကို ပိတ်ဖို့
express.json()ပေါ်က body size limit - Input တိုင်းအတွက် validation layer (Zod၊ Joi)
76. Rate limiting ကို ဘယ်လို ထည့်မလဲ?
Time window တစ်ခုအတွင်း IP ဒါမှမဟုတ် user တစ်ခုချင်းရဲ့ request ကို ကန့်သတ်ဖို့ express-rate-limit လို middleware ကို သုံးပြီး ကျော်သွားရင် Retry-After header နဲ့ 429 Too Many Requests ပြန်ပေးပါ။ Login နဲ့ password reset လို sensitive route တွေမှာ ပိုတင်းကျပ်တဲ့ limit တွေ apply လုပ်ပါ။ Server instance အများကြီးရှိရင် limit မျှသုံးနိုင်အောင် counter တွေကို Redis ထဲမှာ သိမ်းပါ။
77. API ကို မြန်စေဖို့ caching ကို ဘယ်လို သုံးမလဲ?
မှန်ကန်တဲ့ layer မှာ cache လုပ်ပါ — public response တွေအတွက် HTTP caching header (Cache-Control၊ ETag)၊ စျေးကြီးတဲ့ query တွေအတွက် in-memory ဒါမှမဟုတ် Redis cache နဲ့ public endpoint တွေရဲ့ ရှေ့မှာ CDN။ Data ပြောင်းတဲ့အခါ entry တွေ ဘယ်လို expire ဖြစ်ပြီး invalidate လုပ်မလဲ သတ်မှတ်ပါ — ဟောင်းနေတဲ့ cache တွေက bug တွေရဲ့ အဖြစ်များတဲ့ အရင်းအမြစ်ပါ။
78. Cache-aside pattern ဆိုတာ ဘာလဲ?
Application က cache ကို အရင်စစ်ပါတယ်၊ miss ဖြစ်ရင် database ကနေ ဖတ်ပြီး ရလဒ်ကို expiry နဲ့ cache ထဲ သိမ်းကာ ပြန်ပေးပါတယ်။ Write လုပ်တဲ့အခါ database ကို update လုပ်ပြီး cache entry ကို ဖျက်တာ ဒါမှမဟုတ် update လုပ်တာ လုပ်ပါတယ်။ ရိုးရှင်းပြီး Redis နဲ့ အသုံးအများဆုံး pattern ပါ။
async function getProduct(id) { const key = `product:${id}`; const cached = await redis.get(key); if (cached) return JSON.parse(cached); const product = await db.products.findById(id); await redis.set(key, JSON.stringify(product), { EX: 300 }); return product;}79. Express မှာ file upload တွေကို ဘယ်လို ကိုင်တွယ်မလဲ?
multipart/form-data ကို parse လုပ်ဖို့ multer (ဒါမှမဟုတ် busboy) လို middleware ကို သုံးပါ။ File size နဲ့ အရေအတွက်ကို ကန့်သတ်ပါ၊ extension ကို မယုံဘဲ file type အစစ်ကို စစ်ပါ၊ ကိုယ်ပိုင် file နာမည်တွေ ထုတ်ပြီး server ရဲ့ disk အစား object storage (S3၊ GCS) ပေါ်မှာ သိမ်းပါ။ File ကြီးတွေအတွက် client ကို pre-signed URL နဲ့ storage ဆီ တိုက်ရိုက် upload လုပ်ခွင့်ပေးပါ။
80. API အတွက် unit၊ integration နဲ့ end-to-end test တွေ ဘာကွာလဲ?
Unit test တွေက function တစ်ခုကို သီးခြား စစ်ပါတယ် — dependency တွေကို mock လုပ်ထားတဲ့ service လိုမျိုး။ Integration test တွေက အစိတ်အပိုင်းတွေကို အတူစစ်ပါတယ် — test container ထဲက database အစစ်နဲ့ route တစ်ခု။ End-to-end test တွေက deploy လုပ်ထားတဲ့ system ကို လက်တွေ့ကျတဲ့ flow တွေနဲ့ run ပါတယ်။ API တွေအတွက် route တွေပေါ်က integration test တွေက test တစ်ခုချင်းအလိုက် ယုံကြည်မှု အများဆုံး ပေးပါတယ်။
81. Express route တွေကို ဘယ်လို test လုပ်မလဲ?
listen မခေါ်ဘဲ app ကို export လုပ်ပြီး ကိုယ့် test runner (Vitest၊ Jest ဒါမှမဟုတ် Node ရဲ့ built-in node:test) ထဲမှာ Supertest နဲ့ request တွေ ပို့ပါ။ Test database အစစ်ကို သုံးပြီး test တွေကြား reset လုပ်ကာ status code နဲ့ response body တွေကို assert လုပ်ပါ။
import request from "supertest";import { test } from "node:test";import assert from "node:assert/strict";import { app } from "../src/app.js"; test("POST /users rejects a missing email", async () => { const res = await request(app).post("/users").send({ name: "Aye" }); assert.equal(res.status, 400);});82. Node ရဲ့ built-in test runner ဆိုတာ ဘာလဲ?
Modern Node မှာ node:test နဲ့ node:assert ပါလို့ dependency အပိုမလိုဘဲ node --test နဲ့ test တွေ ရေးပြီး run လို့ရပါတယ်။ describe/it၊ hook တွေ၊ mocking၊ subtest တွေ၊ watch mode နဲ့ coverage ကို support လုပ်ပါတယ်။ Team အများစုက ecosystem အတွက် Vitest ဒါမှမဟုတ် Jest ကို သုံးဆဲဖြစ်ပေမဲ့ built-in runner က library နဲ့ service အသေးတွေအတွက် ကောင်းပါတယ်။
83. Environment အမျိုးမျိုးမှာ configuration ကို ဘယ်လို manage လုပ်မလဲ?
Config အားလုံးကို environment variable ကနေ ဖတ်ပြီး startup မှာ schema နဲ့ တစ်ကြိမ် validate လုပ်ကာ တစ်ခုခု ကျန်ရင် ဒါမှမဟုတ် မမှန်ရင် အမြန် fail ဖြစ်ပါစေ။ Code တစ်ခုလုံးမှာ process.env ကို ဖတ်မယ့်အစား type ပါတဲ့ config object ကို export လုပ်ပါ။ Environment တစ်ခုချင်း (development၊ staging၊ production) အတွက် value သီးခြားတွေကို repository ထဲမှာ မဟုတ်ဘဲ platform ရဲ့ secret manager ထဲမှာ ထားပါ။
84. Structured logging ဆိုတာ ဘာလဲ၊ ဘာကြောင့် သုံးလဲ?
Structured logging က log line တစ်ခုချင်းကို free text အစား field — level၊ time၊ message၊ request ID၊ user ID၊ duration — တွေပါတဲ့ JSON အဖြစ် ရေးပါတယ်။ ဒါဆို log tool တွေက search၊ filter နဲ့ aggregate လုပ်နိုင်ပါတယ်။ pino လို library တွေက မြန်ပြီး request logging middleware ထည့်ပေးပါတယ်၊ request တစ်ခုရဲ့ log line တိုင်းမှာ correlation ID ထည့်ပါ။
85. cluster module ကို ဘာတွေအတွက် သုံးလဲ?
Node process တစ်ခုက JavaScript အတွက် CPU core တစ်ခုကိုပဲ သုံးပါတယ်။ cluster module က server port တစ်ခုတည်းကို မျှသုံးတဲ့ worker process အများကြီးကို fork လုပ်တာမို့ core 8 ခုပါတဲ့ စက်က worker 8 ခု run နိုင်ပါတယ်။ ယနေ့ process manager (PM2) တွေ ဒါမှမဟုတ် replica အများကြီးပါတဲ့ container တွေက များသောအားဖြင့် ဒီအလုပ်ကို လုပ်ပေမဲ့ idea က အတူတူပါပဲ — core တစ်ခုချင်းအတွက် process တစ်ခု run တာ။
86. Worker thread တွေဆိုတာ ဘာလဲ၊ ဘယ်အချိန် သုံးမလဲ?
worker_threads တွေက process တစ်ခုတည်းထဲမှာ JavaScript ကို parallel thread တွေနဲ့ run ပြီး တစ်ခုချင်းမှာ ကိုယ်ပိုင် event loop ရှိကာ message ဒါမှမဟုတ် shared memory နဲ့ ဆက်သွယ်ပါတယ်။ မဟုတ်ရင် event loop ကို ပိတ်ဆို့မယ့် CPU လေးတဲ့ task — image processing၊ parsing၊ data ကြီးတွေ hash လုပ်တာ — တွေအတွက် သုံးပါ။ I/O-bound အလုပ်တွေအတွက်တော့ မကူညီပါဘူး၊ async I/O က efficient ဖြစ်ပြီးသားပါ။
87. Uncaught exception နဲ့ unhandled promise rejection တွေကို ဘယ်လို ကိုင်တွယ်မလဲ?
သူတို့ကို bug တွေအဖြစ် ဆက်ဆံပါ — error တွေကို ဖြစ်တဲ့နေရာမှာ ဖမ်းပါ။ နောက်ဆုံးကာကွယ်ရေးအဖြစ် uncaughtException နဲ့ unhandledRejection ကို နားထောင်ပြီး error ကို အသေးစိတ်အပြည့်နဲ့ log လုပ်ကာ process ကို သေသေသပ်သပ် shutdown လုပ်ပါ — app က မသိတဲ့ state ထဲမှာ ရှိနေနိုင်ပါတယ်။ Process manager ဒါမှမဟုတ် orchestrator ကို restart လုပ်ခိုင်းပါ။
88. Graceful shutdown ဆိုတာ ဘာလဲ၊ ဘယ်လို implement လုပ်မလဲ?
SIGTERM (container ဒါမှမဟုတ် deploy က app ကို ရပ်တဲ့အခါ ပို့တာ) ရရင် connection အသစ်တွေ လက်မခံတော့ဘဲ လုပ်နေဆဲ request တွေကို ပြီးခွင့်ပေးပါ၊ database pool နဲ့ queue တွေကို ပိတ်ပြီးမှ exit လုပ်ပါ။ Request တစ်ခု ပိတ်မိနေရင် shutdown ကို ထာဝရ မပိတ်ဆို့အောင် timeout ထည့်ပါ။ Deploy လုပ်နေစဉ် request တွေ ကျမသွားအောင် ကာကွယ်ပေးပါတယ်။
const server = app.listen(port); process.on("SIGTERM", () => { server.close(async () => { await db.end(); process.exit(0); }); setTimeout(() => process.exit(1), 10_000).unref();});89. API ကို ဘယ်လို version ထားမလဲ?
အဖြစ်အများဆုံး နည်းက URL path ထဲမှာ version ထည့်တာပါ (/v1/users)၊ ရှင်းလင်းပြီး route လုပ်ရလွယ်ပါတယ်။ Alternative တွေက header ဒါမှမဟုတ် media type ပါ။ ဘယ်ဟာရွေးရွေး version တစ်ခုအတွင်း breaking change တွေ ရှောင်ပါ — နာမည်ပြောင်းတာ ဒါမှမဟုတ် ဖယ်တာထက် field တွေ ထပ်ထည့်ပါ၊ warning နဲ့ ရက်စွဲတွေနဲ့ deprecate လုပ်ပြီး client တွေ ပြောင်းနိုင်လောက်အောင် version ဟောင်းကို support လုပ်ပါ။
90. WebSocket ဆိုတာ ဘာလဲ၊ HTTP နဲ့ ဘယ်လို ကွာလဲ?
HTTP က request–response ပါ — client မေးပြီး server ဖြေပါတယ်။ WebSocket ကတော့ ဘယ်ဘက်ကမဆို ဘယ်အချိန်မဆို message ပို့နိုင်တဲ့ ကြာကြာရှိပြီး နှစ်လမ်းသွား connection ဖြစ်လို့ chat၊ live dashboard နဲ့ multiplayer feature တွေအတွက် အကောင်းဆုံးပါ။ Node မှာ ws ဒါမှမဟုတ် room၊ reconnection နဲ့ fallback တွေ ထပ်ထည့်ပေးတဲ့ Socket.IO ကို သုံးလို့ရပါတယ်။
91. WebSocket အစား Server-Sent Events ကို ဘယ်အချိန် ရွေးမလဲ?
Server-Sent Events က ပုံမှန် HTTP ပေါ်ကနေ server ကနေ client ဆီ တစ်လမ်းသွား event stream ကို ပို့ပါတယ်။ WebSocket ထက် ရိုးရှင်းတယ်၊ အလိုအလျောက် reconnect လုပ်ပြီး proxy တွေနဲ့ ကောင်းကောင်း အလုပ်လုပ်တာမို့ notification၊ progress update နဲ့ AI ပုံစံ token streaming တွေအတွက် ကောင်းပါတယ်။ Client ကလည်း message တွေ မကြာခဏ ပို့ဖို့လိုရင် WebSocket ကို သုံးပါ။
92. Background job နဲ့ queue တွေကို ဘာကြောင့် သုံးလဲ?
အလုပ်တချို့က request အတွင်းမှာ မဖြစ်သင့်ပါဘူး — email ပို့တာ၊ PDF ထုတ်တာ၊ image resize လုပ်တာ၊ နှေးတဲ့ third-party API ခေါ်တာ။ Job ကို queue (Redis နဲ့ BullMQ၊ SQS၊ RabbitMQ) ပေါ် တင်ပြီး retry နဲ့ backoff ပါတဲ့ သီးခြား worker မှာ process လုပ်ပါ။ API က မြန်မြန်တုံ့ပြန်ပြီး failure တွေကို user မစောင့်ရဘဲ retry လုပ်လို့ရပါတယ်။
93. Node မှာ ထပ်ခါထပ်ခါ run ရမယ့် task တွေကို ဘယ်လို schedule လုပ်မလဲ?
ရိုးရှင်းတဲ့ case တွေအတွက် node-cron လို library တွေက process ထဲမှာ function တွေကို cron schedule နဲ့ run ပါတယ် — ဒါပေမဲ့ instance အများကြီးရှိရင် instance တိုင်းက task ကို run ပါတယ်။ Repeatable job ပါတဲ့ job queue (BullMQ)၊ platform ရဲ့ scheduled job တွေ ဒါမှမဟုတ် distributed lock ကို ဦးစားပေးပါ၊ ဒါဆို task က schedule တစ်ခုချင်းအတွက် တစ်ကြိမ်ပဲ run ပါတယ်။
94. PUT နဲ့ PATCH ဘာကွာလဲ၊ idempotency ဆိုတာ ဘာလဲ?
PUT က resource တစ်ခုလုံးကို ကိုယ်ပို့တာနဲ့ အစားထိုးပါတယ်၊ PATCH က ကိုယ်ပို့တဲ့ field တွေကိုပဲ ပြောင်းပါတယ်။ Idempotent ဆိုတာ request ကို ထပ်လုပ်ရင် တစ်ကြိမ်လုပ်တာနဲ့ အကျိုးသက်ရောက်မှု အတူတူ ဖြစ်တာပါ — GET၊ PUT နဲ့ DELETE က idempotent ဖြစ်ပြီး POST က မဟုတ်ပါဘူး။ Payment လို POST operation တွေအတွက် retry တွေက ထပ်နေတာတွေ မဖန်တီးအောင် idempotency key header ကို လက်ခံပါ။
95. Node ကနေ outgoing HTTP call တွေကို ဘယ်လို လုပ်မလဲ?
Modern Node မှာ undici ပေါ်မှာ တည်ဆောက်ထားတဲ့ global fetch ပါလို့ axios ကို ရှားရှားပါးပါးပဲ လိုပါတော့တယ်။ AbortSignal.timeout(ms) နဲ့ timeout ကို အမြဲ သတ်မှတ်ပါ၊ res.ok ကို စစ်ပါ၊ error တွေကို ကိုင်တွယ်ပြီး idempotent request တွေကိုပဲ backoff နဲ့ retry လုပ်ပါ။ Performance အတွက် connection တွေကို ပြန်သုံးပါ (undici မှာ keep-alive က default ဖွင့်ထားပါတယ်)။
const res = await fetch("https://api.example.com/rates", { signal: AbortSignal.timeout(3000), headers: { Accept: "application/json" },});if (!res.ok) throw new Error(`Rates API failed: ${res.status}`);const rates = await res.json();96. API ကို ဘယ်လို document လုပ်မလဲ?
API ကို OpenAPI specification နဲ့ ဖော်ပြပါ — endpoint၊ parameter၊ request နဲ့ response schema၊ error တွေနဲ့ authentication — ပြီး Swagger UI၊ Redoc ဒါမှမဟုတ် Scalar နဲ့ interactive docs ကို serve လုပ်ပါ။ Spec ကို ကိုယ့် validation schema (ဥပမာ Zod) တွေကနေ generate လုပ်တာက docs နဲ့ code ကို ညီနေစေပါတယ်။ Endpoint တိုင်းအတွက် ဥပမာတွေ ထည့်ပါ။
97. Node နဲ့ Express project မှာ TypeScript ကို ဘယ်လို သုံးမလဲ?
Request body၊ params နဲ့ response တွေ၊ service နဲ့ config တွေကို type ပေးပါ။ @types/express ကို install လုပ်ပါ၊ strict mode ကို ဖွင့်ပြီး runtime check နဲ့ type တွေ ညီအောင် type တွေကို validation schema တွေကနေ ထုတ်ယူပါ။ Development မှာ compiler ဒါမှမဟုတ် type-stripping runtime နဲ့ run ပါ၊ CI မှာ tsc --noEmit ကို run ပြီး production မှာ JavaScript အဖြစ် build လုပ်တာ ဒါမှမဟုတ် type-stripped code ကို run တာ လုပ်ပါ။
98. Node app ကို Docker နဲ့ ဘယ်လို containerise လုပ်မလဲ?
Official slim Node image ကို သုံးပါ၊ dependency layer တွေ cache ဖြစ်အောင် package.json နဲ့ lock file ကို အရင် copy ကူးပြီး npm ci --omit=dev ကို run ကာ ပြီးမှ source ကို copy ကူးပါ။ TypeScript compile လုပ်တဲ့အခါ multi-stage build ကို သုံးပါ၊ non-root node user အဖြစ် run ပါ၊ NODE_ENV=production သတ်မှတ်ပြီး shutdown signal တွေ ရအောင် node နဲ့ တိုက်ရိုက် စတင်ပါ။
99. Node project ရဲ့ dependency တွေကို ခေတ်မီပြီး လုံခြုံအောင် ဘယ်လို ထိန်းမလဲ?
Dependency စာရင်းကို တိုတိုထားပါ၊ lock file ကို commit လုပ်ပြီး npm ci နဲ့ install လုပ်ပါ။ CI မှာ npm audit (ဒါမှမဟုတ် Snyk လို tool) ကို run ပါ၊ ကိုယ့် test တွေက စစ်ဆေးမယ့် update pull request အသေးလေးတွေကို Renovate ဒါမှမဟုတ် Dependabot ကို ဖွင့်ခိုင်းပါ။ Supply-chain risk လျှော့ဖို့ package အသစ်တွေ မထည့်ခင် review လုပ်ပါ — maintenance လှုပ်ရှားမှု၊ download၊ install script တွေ — ပြီး support လုပ်ဆဲ Node LTS version မှာ ထားပါ။
100. Node.js application ကို ဘယ်လို debug လုပ်မလဲ?
ကောင်းတဲ့ log တွေနဲ့ စပြီး ပြဿနာကို ပြန်ဖြစ်အောင်လုပ်ပါ။ တစ်ဆင့်ချင်း debug လုပ်ဖို့ node --inspect ကို run ပြီး Chrome DevTools ဒါမှမဟုတ် editor ရဲ့ debugger ကို ချိတ်ကာ breakpoint တွေ ထားပြီး variable တွေကို စစ်ဆေးပါ။ Performance အတွက် --cpu-prof ဒါမှမဟုတ် DevTools profiler ကို၊ memory အတွက် heap snapshot တွေယူပြီး နှိုင်းယှဉ်ပါ။
Senior — Performance၊ Reliability နဲ့ Architecture
Senior Node.js interview တွေက load အောက်မှာ runtime ဘယ်လို ပြုမူလဲ၊ production မှာ မြန်ဆန်၊ လုံခြုံပြီး observable ဖြစ်နေမယ့် service တွေကို ဘယ်လို design လုပ်မလဲ ဆိုတာကို နက်နက်နဲနဲ မေးပါတယ် — profiling နဲ့ memory၊ scaling နဲ့ concurrency၊ data consistency၊ security၊ architecture boundary တွေနဲ့ operations။ အဖြေကောင်းတွေက mechanism၊ trade-off နဲ့ ရလဒ်ကို ဘယ်လို တိုင်းတာမလဲ ဆိုတာကို ရှင်းပြပါတယ်။
101. Node service မှာ CPU bottleneck ကို ဘယ်လို ရှာပြီး ပြင်မလဲ?
Load ကို ပြန်ဖြစ်အောင်လုပ်ပြီး profile လုပ်ပါ — --cpu-prof နဲ့ run ပါ ဒါမှမဟုတ် DevTools profiler ကို ချိတ်ပြီး ဘယ် function တွေ အချိန်အများဆုံး ယူလဲ ကြည့်ဖို့ flame graph ကို ဖတ်ပါ။ အဖြစ်များတဲ့ တရားခံတွေက payload ကြီးတွေပေါ်က synchronous JSON အလုပ်၊ လေးတဲ့ regular expression၊ main thread ပေါ်က crypto ဒါမှမဟုတ် compression နဲ့ efficient မဖြစ်တဲ့ loop တွေပါ။ Hot path ကို ပြင်ပါ၊ CPU လေးတဲ့ အလုပ်ကို worker thread ဒါမှမဟုတ် job ဆီ ရွှေ့ပြီး ပြန်တိုင်းပါ။
102. Node.js မှာ memory leak ကို ဘယ်လို စစ်ဆေးမလဲ?
Monitoring မှာ heap usage ကို အချိန်နဲ့အမျှ ကြည့်ပါ — leak ဆိုရင် garbage collection ပြီးနောက် ဘယ်တော့မှ ပြန်မကျဘဲ ဆက်တက်နေတဲ့ memory ကို ပြပါတယ်။ Load အောက်မှာ မိနစ်အနည်းငယ်ခြား heap snapshot တွေယူပြီး နှိုင်းယှဉ်ကာ ဆက်ကြီးလာနေတဲ့ object type တွေကို ရှာပြီး သူတို့ retainer တွေကို လိုက်ပါ။ ပုံမှန်အကြောင်းရင်းတွေက အကန့်အသတ်မဲ့ cache ဒါမှမဟုတ် map တွေ၊ ဘယ်တော့မှ မဖယ်တဲ့ listener တွေ၊ object ကြီးတွေကို ကိုင်ထားတဲ့ closure တွေ၊ ဘယ်တော့မှ clear မလုပ်တဲ့ timer တွေနဲ့ request တွေရဲ့ global array တွေပါ။
103. V8 မှာ garbage collection ဘယ်လိုအလုပ်လုပ်လဲ?
V8 က generational garbage collection ကို သုံးပါတယ်။ Object အသစ်တွေက young generation သေးသေးလေးထဲ ရောက်ပြီး ရှင်သန်ကျန်တာတွေကို copy ကူးတဲ့ နည်းနဲ့ မကြာခဏ မြန်မြန် collect လုပ်ပါတယ်။ Collection အများအပြားကနေ ရှင်သန်ကျန်တဲ့ object တွေကို old generation ဆီ ရာထူးတိုးပြီး mark-sweep-compact နဲ့ ပိုရှားရှားပါးပါး၊ အများစု concurrent အနေနဲ့ collect လုပ်ပါတယ်။ သက်တမ်းတို object အများကြီး allocate လုပ်တာ စျေးပေါပေမဲ့ reference တွေကို လိုတာထက် ကြာကြာ ကိုင်ထားရင် memory က ရှင်သန်နေပါတယ်။
104. Container တွေထဲမှာ Node ရဲ့ memory limit တွေကို ဘယ်လို သတ်မှတ်မလဲ?
V8 က ရနိုင်တဲ့ memory ကနေ heap size ကို သတ်မှတ်ပေမဲ့ container limit နဲ့ heap limit ကို ညှိထားသင့်ပါတယ် — kernel က process ကို မသတ်ခင် garbage-collect လုပ်နိုင်အောင် --max-old-space-size ကို container memory ရဲ့ 70–80% လောက် သတ်မှတ်ပါ။ Heap ပြင်ပက memory — Buffer၊ native module၊ thread stack — ကို မှတ်ထားပြီး heap size တစ်ခုတည်း မဟုတ်ဘဲ resident memory ကို monitor လုပ်ပါ။
105. Event loop lag ဆိုတာ ဘာလဲ၊ ဘယ်လို တိုင်းတာမလဲ?
Event loop lag ဆိုတာ thread အလုပ်များနေလို့ callback တွေ run ခွင့်ရဖို့ ဘယ်လောက်ကြာကြာ စောင့်ရလဲ ဆိုတာပါ။ Lag မြင့်ရင် request တိုင်း နှေးလာပါတယ်။ perf_hooks.monitorEventLoopDelay() ဒါမှမဟုတ် APM နဲ့ တိုင်းပြီး percentile တွေနဲ့ metric အဖြစ် export လုပ်ကာ p99 တက်လာရင် alert လုပ်ပါ။ Blocking code ဒါမှမဟုတ် CPU ပြည့်နေတာရဲ့ ပထမဆုံး လက္ခဏာ ဖြစ်တတ်ပါတယ်။
import { monitorEventLoopDelay } from "node:perf_hooks"; const histogram = monitorEventLoopDelay({ resolution: 20 });histogram.enable(); setInterval(() => { const p99 = histogram.percentile(99) / 1e6; // ns → ms metrics.gauge("event_loop_lag_p99_ms", p99); histogram.reset();}, 10_000).unref();106. Node.js API ကို horizontal ဘယ်လို scale လုပ်မလဲ?
Instance တွေကို stateless ထားပါ — process တစ်ခုထဲမှာ ရှိနေရမယ့် session၊ upload ဒါမှမဟုတ် cache မရှိစေနဲ့ — ပြီး shared state ကို Redis၊ database ဒါမှမဟုတ် object storage ထဲ ထည့်ပါ။ Load balancer နောက်မှာ instance အများကြီး run ပါ၊ CPU core တစ်ခုချင်းအတွက် process တစ်ခု ထားပြီး replica အရေအတွက်ကို CPU၊ latency ဒါမှမဟုတ် queue depth အပေါ် scale လုပ်ပါ။ Database နဲ့ တခြား dependency တွေက connection အပိုတွေကို ခံနိုင်ကြောင်း သေချာလုပ်ပါ။
107. Node မှာ concurrency နဲ့ parallelism ဘာကွာလဲ?
Concurrency ဆိုတာ task အများကြီး တစ်ပြိုင်နက် လုပ်ဆောင်နေဆဲ ဖြစ်တာပါ — Node က I/O စောင့်နေစဉ် အလုပ်တွေကို ကြားညှပ်ပြီး thread တစ်ခုပေါ်မှာ ဒါကို လုပ်ပါတယ်။ Parallelism ဆိုတာ task တွေက core အများကြီးပေါ်မှာ တကယ် တစ်ချိန်တည်း run တာဖြစ်ပြီး Node မှာ process အများကြီး (cluster၊ replica) ဒါမှမဟုတ် worker thread တွေ လိုပါတယ်။ I/O-bound service တွေက concurrency နဲ့ scale ဖြစ်ပြီး CPU-bound အလုပ်က parallelism လိုပါတယ်။
108. ပြင်ပ service တွေကို ခေါ်တဲ့အခါ concurrency ကို ဘယ်လို ကန့်သတ်မလဲ?
Promise.all နဲ့ request ထောင်ချီကို တစ်ပြိုင်နက် ပစ်လိုက်ရင် socket၊ memory ဒါမှမဟုတ် တခြား service ရဲ့ rate limit ကို ကုန်စေနိုင်ပါတယ်။ Item တွေကို batch လိုက် ဒါမှမဟုတ် concurrency limiter (p-limit လို) နဲ့ process လုပ်ပါ၊ remote rate limit ကို လေးစားပြီး timeout တွေ ထည့်ပါ။ ကြီးမားတဲ့ ဒါမှမဟုတ် ဆက်လက်ဖြစ်နေတဲ့ workload တွေအတွက် item တွေကို worker အရေအတွက် သတ်မှတ်ထားတဲ့ queue ပေါ် တင်ပါ။
import pLimit from "p-limit"; const limit = pLimit(10); // at most 10 requests at a timeconst results = await Promise.all( userIds.map((id) => limit(() => fetchProfile(id))),);109. တခြား service တွေကို ခေါ်တဲ့အခါ failure အတွက် ဘယ်လို design လုပ်မလဲ?
Dependency တိုင်း နှေးနိုင်တယ် ဒါမှမဟုတ် ကျနိုင်တယ်လို့ ယူဆပါ။ Call တိုင်းမှာ timeout သတ်မှတ်ပါ၊ idempotent operation တွေကိုပဲ exponential backoff နဲ့ jitter နဲ့ retry လုပ်ပါ၊ fail ဖြစ်နေတဲ့ service ကို ဆက်မထုလေအောင် circuit breaker ကို သုံးပါ။ သေသေသပ်သပ် degrade လုပ်ပါ — cache လုပ်ထားတဲ့ data ဒါမှမဟုတ် response တစ်စိတ်တစ်ပိုင်းကို serve လုပ်ပါ — ပြီး နှေးတဲ့ dependency တစ်ခုက ကိုယ့် connection အားလုံးကို မစားသွားအောင် bulkhead တွေ သုံးပါ။
110. Circuit breaker ဆိုတာ ဘာလဲ?
Circuit breaker က dependency တစ်ခုဆီ call တွေကို ထုပ်ပြီး failure တွေကို ခြေရာခံပါတယ်။ Failure တွေ threshold ကျော်သွားရင် "ပွင့်" ပြီး timeout တွေ စောင့်မယ့်အစား ခဏ အမြန် fail ဖြစ်စေပါတယ်၊ ပြီးမှ စမ်းသပ် request အနည်းငယ်ကို ဖြတ်ခွင့်ပေး ("half-open") ပြီး အောင်မြင်ရင် ပြန်ပိတ်ပါတယ်။ ကိုယ့် service ရဲ့ resource တွေကို ကာကွယ်ပြီး fail ဖြစ်နေတဲ့ service ကို ပြန်ကောင်းဖို့ အချိန်ပေးပါတယ်။ opossum လို library တွေက implement လုပ်ထားပါတယ်။
111. API endpoint ကို idempotent ဖြစ်အောင် ဘယ်လို လုပ်မလဲ?
Payment ဒါမှမဟုတ် order ဖန်တီးတာလို operation တွေမှာ Idempotency-Key header ကို လက်ခံပါ။ ပထမအကြိမ်မှာ key ကို ရလဒ်နဲ့အတူ သိမ်းပါ၊ key အတူတူ ထပ်ရောက်လာရင် အလုပ်ကို ထပ်မလုပ်ဘဲ သိမ်းထားတဲ့ ရလဒ်ကို ပြန်ပေးပါ။ Key အတူတူပါတဲ့ concurrent request နှစ်ခုစလုံး အောင်မြင်မသွားအောင် unique constraint ဒါမှမဟုတ် atomic insert ကို သုံးပါ။
112. Database write နဲ့ message publish ကြားမှာ data ကို ဘယ်လို တသမတ်တည်း ထိန်းမလဲ?
Database ကို ရေးပြီးမှ event publish လုပ်တာ တစ်ဝက်တစ်ပျက် fail ဖြစ်ပြီး နှစ်ခု မညီတော့နိုင်ပါတယ်။ Transactional outbox pattern က ဒါကို ဖြေရှင်းပါတယ် — business ပြောင်းလဲမှုနဲ့ outbox row ကို transaction တစ်ခုတည်းမှာ ရေးပြီး သီးခြား process က outbox ကို ဖတ်ကာ event တွေကို publish လုပ်ပြီး ပို့ပြီးကြောင်း မှတ်ပါတယ်။ Event တွေ တစ်ကြိမ်ထက်ပို ရောက်နိုင်တာမို့ consumer တွေက idempotent ဖြစ်ရပါမယ်။
113. Message queue တွေက ဘယ်လို delivery guarantee တွေ ပေးလဲ၊ ထပ်နေတာတွေကို ဘယ်လို ကိုင်တွယ်မလဲ?
Queue အများစုက at-least-once delivery ကို ပေးပါတယ် — consumer က acknowledge မလုပ်ခင် crash ဖြစ်ရင် message ကို ပြန်ပို့တာမို့ ထပ်နေတာတွေ ဖြစ်ပါတယ်။ Exactly-once ကို အစအဆုံး ရှားရှားပါးပါးပဲ ရနိုင်ပါတယ်။ Consumer တွေကို idempotent ဖြစ်အောင်လုပ်ပါ — process လုပ်ပြီးသား message ID တွေကို ခြေရာခံပါ ဒါမှမဟုတ် natural unique key တွေ သုံးပါ — အလုပ် commit ဖြစ်ပြီးမှ acknowledge လုပ်ပြီး ထပ်ခါထပ်ခါ fail ဖြစ်တဲ့ message တွေကို dead-letter queue ဆီ ပို့ပါ။
114. Node မှာ ယုံကြည်ရတဲ့ background job system ကို ဘယ်လို design လုပ်မလဲ?
Durable queue (Redis နဲ့ BullMQ၊ SQS၊ RabbitMQ) နဲ့ သီးခြား worker process တွေကို သုံးပါ။ Job တွေကို ID၊ backoff နဲ့ retry၊ timeout နဲ့ dead-letter destination ပေးပါ၊ handler တွေကို idempotent ဖြစ်အောင်လုပ်ပါ၊ worker တစ်ခုချင်းရဲ့ concurrency ကို ကန့်သတ်ပြီး queue depth၊ failure နဲ့ processing time ပေါ်က metric တွေကို ထုတ်ပြပါ။ Job လေးတွေက API ကို မနှေးစေအောင် worker တွေကို သီးခြား deploy လုပ်ပါ။
115. Node.js codebase ကြီးတစ်ခုကို ဘယ်လို structure လုပ်မလဲ?
Technical layer အလိုက် မဟုတ်ဘဲ business domain (billing၊ catalog၊ identity လို module) အလိုက် စီစဉ်ပြီး module တွေကြား ရှင်းလင်းတဲ့ public interface တွေ ထားပါ။ တစ်ခုချင်းထဲမှာ HTTP ကိုင်တွယ်တာ၊ business logic နဲ့ data access ကို ခွဲထားပြီး business rule တွေက Express ဒါမှမဟုတ် database ပေါ် မမှီခိုအောင် dependency တွေကို အတွင်းဘက် ညွှန်ပါစေ။ Lint rule တွေနဲ့ module boundary တွေကို အကောင်အထည်ဖော်ပြီး test တွေအတွက် app ကို ပေါင်းစပ်လို့ရအောင် ထားပါ။
116. Dependency injection ဆိုတာ ဘာလဲ၊ Node မှာ ကူညီလား?
Dependency injection ဆိုတာ module ကို သူ့ dependency — database client၊ logger၊ တခြား service — တွေကို တိုက်ရိုက် import မလုပ်ဘဲ ထည့်ပေးတာပါ။ Code ကို test လုပ်ရ (fake တွေ ထည့်ပေး)၊ configure လုပ်ရ၊ အစားထိုးရ ပိုလွယ်စေပါတယ်။ Node မှာ plain factory function ဒါမှမဟုတ် constructor parameter တွေက များသောအားဖြင့် လုံလောက်ပါတယ်၊ Awilix ဒါမှမဟုတ် NestJS ထဲက container တွေက codebase ကြီးတွေမှာ ကူညီပါတယ်။
117. Node backend အတွက် monolith လား microservices လား?
Structure ကောင်းတဲ့ modular monolith နဲ့ စပါ — အတွင်းပိုင်း boundary ခိုင်မာတဲ့ deployable တစ်ခုက develop၊ test၊ deploy နဲ့ debug လုပ်ရ ပိုရိုးရှင်းပါတယ်။ ရှင်းလင်းတဲ့ အကြောင်းပြချက် — သီးခြား scaling၊ သီးခြား team ပိုင်ဆိုင်မှု၊ မတူတဲ့ reliability ဒါမှမဟုတ် technology လိုအပ်ချက် — ရှိမှပဲ service တွေကို ခွဲထုတ်ပါ။ Microservice တွေက network failure၊ data consistency စိန်ခေါ်မှုနဲ့ operational cost တွေကို ထပ်ယူလာပါတယ်။
118. Express၊ Fastify နဲ့ NestJS ကြား ဘယ်လို ရွေးမလဲ?
Express က minimal၊ တည်ငြိမ်ပြီး ecosystem အကြီးဆုံး ရှိပါတယ်၊ Express 5 က async error handling ကို ပြင်ခဲ့ပါတယ်။ Fastify က ပိုမြန်ပြီး schema-based validation နဲ့ serialisation ပါပြီးသားဖြစ်ကာ plugin system အားကောင်းပါတယ်။ NestJS က module၊ dependency injection နဲ့ decorator တွေပါတဲ့ opinionated architecture ကို ထည့်ပေးလို့ team ကြီးတွေအတွက် အသုံးဝင်ပါတယ်။ Team အတွေ့အကြုံ၊ performance လိုအပ်ချက်နဲ့ ဘယ်လောက် structure ကို အတင်းသတ်မှတ်စေချင်လဲ ပေါ်မူတည်ပြီး ရွေးပါ။
119. REST၊ GraphQL ဒါမှမဟုတ် gRPC — တစ်ခုချင်းကို ဘယ်အချိန် သုံးမလဲ?
REST က ရိုးရှင်းတယ်၊ HTTP ပေါ်မှာ cache လုပ်လို့ရပြီး public နဲ့ web API အများစုနဲ့ သင့်တော်ပါတယ်။ GraphQL က client တွေကို ဆက်စပ်တဲ့ data တွေကြား လိုတဲ့ field အတိအကျကိုပဲ တောင်းခွင့်ပေးလို့ ရှုပ်ထွေးတဲ့ front end တွေအတွက် ကောင်းပေမဲ့ N+1 query၊ query cost limit နဲ့ caching ကို ဂရုစိုက်ရပါတယ်။ gRPC က HTTP/2 ပေါ်မှာ Protocol Buffers ကို သုံးပြီး မြန်ဆန်ကာ type တင်းကျပ်တဲ့ service-to-service call နဲ့ streaming အတွက်ဖြစ်ပေမဲ့ browser မှာ native မဟုတ်ပါဘူး။
120. Node ပေါ်မှာ တည်ဆောက်ထားတဲ့ GraphQL API ကို ဘယ်လို လုံခြုံအောင် လုပ်မလဲ?
Request တွေကို authenticate လုပ်ပြီး edge မှာတင် မဟုတ်ဘဲ resolver ဒါမှမဟုတ် data-access level မှာ authorise လုပ်ပါ။ Query depth နဲ့ complexity ကို ကန့်သတ်ပါ၊ timeout နဲ့ pagination limit တွေ သတ်မှတ်ပါ၊ schema က private ဆိုရင် production မှာ introspection ကို ပိတ်ပါ၊ public client တွေအတွက် persisted query တွေ သုံးပြီး N+1 query ရှောင်ဖို့ DataLoader နဲ့ database access ကို batch လုပ်ပါ။
121. Node service အတွက် ဘယ် OWASP API risk တွေ အရေးအကြီးဆုံးလဲ?
Incident အစစ်အများစုက API risk အနည်းငယ်ကနေ လာပါတယ်။
- Broken object-level authorisation — ID ပြောင်းပြီး တခြား user တွေရဲ့ record တွေကို access လုပ်တာ
- Broken authentication — အားနည်းတဲ့ token၊ login မှာ rate limit မရှိတာ၊ ပေါက်ကြားတဲ့ secret
- Excessive data exposure — ရှင်းလင်းတဲ့ field တွေ မဟုတ်ဘဲ database object တစ်ခုလုံးကို ပြန်ပေးတာ
- Rate limiting နဲ့ resource limit မရှိတာ — အလွဲသုံးစားနဲ့ denial of service
- Injection နဲ့ third-party API တွေကို မလုံခြုံစွာ သုံးတာ — input ဒါမှမဟုတ် response တွေကို validation မလုပ်ဘဲ ယုံတာ
122. Prototype pollution ဆိုတာ ဘာလဲ၊ ဘယ်လို ကာကွယ်မလဲ?
Prototype pollution ဆိုတာ attacker ထိန်းချုပ်တဲ့ __proto__ ဒါမှမဟုတ် constructor.prototype လို key တွေကို object တွေထဲ merge လုပ်ပြီး process ထဲက object တိုင်းကို property တွေ ထပ်ထည့်ကာ တခါတလေ privilege escalation ဒါမှမဟုတ် remote code execution အထိ ဖြစ်စေတာပါ။ Input ကို strict schema တွေနဲ့ validate လုပ်ပါ၊ မလုံခြုံတဲ့ deep-merge utility တွေ ရှောင်ပါ၊ map တွေကို Object.create(null) ဒါမှမဟုတ် Map နဲ့ ဖန်တီးပြီး dependency တွေကို patch လုပ်ထားပါ။
123. Node service ကို ReDoS ကနေ ဘယ်လို ကာကွယ်မလဲ?
Nested quantifier ပါတဲ့ regular expression တချို့က ဖန်တီးထားတဲ့ input ပေါ်မှာ exponential time ယူပြီး event loop ကို ပိတ်ဆို့ပါတယ် — regular-expression denial of service။ (a+)+ လို ambiguous pattern တွေကို ရှောင်ပါ၊ match မလုပ်ခင် input length ကို ကန့်သတ်ပါ၊ မလုံခြုံတဲ့ regex တွေ ရှာဖို့ lint rule ဒါမှမဟုတ် tool တွေ သုံးပြီး email နဲ့ URL လို format တွေအတွက် ကောင်းကောင်း test လုပ်ထားတဲ့ validation library တွေကို ဦးစားပေးပါ။
124. Production မှာ secret တွေကို ဘယ်လို manage လုပ်မလဲ?
Secret တွေကို code၊ image နဲ့ log တွေထဲ မထည့်ပါနဲ့။ Secret manager (AWS Secrets Manager၊ Vault၊ platform ရဲ့ encrypt လုပ်ထားတဲ့ variable တွေ) ထဲမှာ သိမ်းပြီး runtime မှာ inject လုပ်ပါ၊ service တစ်ခုချင်းကို လိုတဲ့ secret တွေကိုပဲ ပေးပြီး ပုံမှန် rotate လုပ်ပါ။ Startup မှာ လိုအပ်တဲ့ secret တွေ ရှိကြောင်း validate လုပ်ပြီး log နဲ့ error report တွေကနေ redact လုပ်ပါ။
125. Service-to-service communication ကို ဘယ်လို လုံခြုံအောင် လုပ်မလဲ?
Network အတွင်းပိုင်း အပါအဝင် နေရာတိုင်းမှာ TLS နဲ့ traffic ကို encrypt လုပ်ပါ။ Service တွေကို တစ်ခုနဲ့တစ်ခု mutual TLS၊ sign လုပ်ထားတဲ့ သက်တမ်းတို token (ဥပမာ OAuth client credentials) ဒါမှမဟုတ် service mesh နဲ့ authenticate လုပ်ပြီး service တစ်ခုချင်း ဘာကို ခေါ်ခွင့်ရှိလဲ authorise လုပ်ပါ။ Private network ထဲမှာ ရှိနေတာ တစ်ခုတည်းကို ဘယ်တော့မှ အားမကိုးပါနဲ့။
126. OAuth 2.0 / OpenID Connect login ကို ဘယ်လို implement လုပ်မလဲ?
Protocol ကို ကိုယ်တိုင်ရေးမယ့်အစား maintain ကောင်းတဲ့ library ဒါမှမဟုတ် identity provider ကို သုံးပါ။ Web app တွေအတွက် PKCE ပါတဲ့ Authorization Code flow ကို သုံးပါ၊ state နဲ့ nonce ကို validate လုပ်ပါ၊ ID token signature၊ audience နဲ့ expiry ကို verify လုပ်ပြီး ရလာတဲ့ session ကို လုံခြုံတဲ့ HttpOnly cookie ထဲ သိမ်းပါ။ Client secret တွေကို server ပေါ်မှာ ထားပြီး refresh token တွေကို server-side မှာပဲ ထားပါ။
127. Node service အတွက် observability ဆိုတာ ဘာကိုဆိုလိုလဲ?
Observability ဆိုတာ system ရဲ့ output တွေကနေ ဘာလုပ်နေလဲ နားလည်နိုင်တာပါ — request ID ပါတဲ့ structured log တွေ၊ metric တွေ (request rate၊ error၊ latency percentile၊ event loop lag၊ memory) နဲ့ service တွေကြား request တစ်ခုကို လိုက်တဲ့ distributed trace တွေ။ OpenTelemetry က Node၊ Express၊ HTTP client နဲ့ database တွေအတွက် vendor-neutral instrumentation ပေးပါတယ်။
128. Distributed tracing ဘယ်လိုအလုပ်လုပ်လဲ?
ဝင်လာတဲ့ request တိုင်း trace ID ရပါတယ်၊ အထဲက operation တိုင်း — handler၊ database query၊ တခြား service ကို ခေါ်တာ — က timing ပါတဲ့ span တစ်ခု ဖြစ်လာပါတယ်။ Trace context ကို downstream service တွေဆီ header (W3C traceparent) တွေထဲမှာ ပို့တာမို့ request လမ်းကြောင်းတစ်ခုလုံးကို မြင်ပြီး အချိန် ဘယ်မှာ ကုန်လဲ ရှာနိုင်ပါတယ်။ Node မှာ OpenTelemetry auto-instrumentation က span အများစုကို ဖန်တီးပေးပါတယ်။
129. AsyncLocalStorage ကို ဘာအတွက် သုံးလဲ?
node:async_hooks က AsyncLocalStorage က request-scoped data — request ID၊ လက်ရှိ user၊ transaction — ကို function တိုင်းကို ဖြတ်ပို့စရာမလိုဘဲ အဲ့ request ထဲက await နဲ့ callback တိုင်းမှာ ရနိုင်အောင် ထိန်းထားပေးပါတယ်။ Logger တွေက request ID ကို အလိုအလျောက် ထည့်ပုံနဲ့ tracing library တွေက context ကို ထိန်းပုံ ဒါပါပဲ။
import { AsyncLocalStorage } from "node:async_hooks";import { randomUUID } from "node:crypto"; export const requestContext = new AsyncLocalStorage(); app.use((req, res, next) => { const id = req.get("x-request-id") ?? randomUUID(); res.set("x-request-id", id); requestContext.run({ requestId: id }, next);}); export const currentRequestId = () => requestContext.getStore()?.requestId;130. Node API အတွက် ဘယ် metric တွေအပေါ် alert လုပ်မလဲ?
User တွေ ခံစားရတဲ့ လက္ခဏာတွေကို အာရုံစိုက်ပါ — route အလိုက် error rate (5xx)၊ latency percentile (p95၊ p99) နဲ့ traffic။ Saturation signal တွေ ထည့်ပါ — CPU၊ memory နဲ့ heap၊ event loop lag၊ database pool usage၊ queue depth နဲ့ dependency latency။ တစ်ကြိမ်တည်း spike တွေထက် SLO burn rate အပေါ် alert လုပ်ပြီး alert တိုင်းကို dashboard နဲ့ runbook နဲ့ ချိတ်ပါ။
131. Health check နဲ့ readiness probe တွေဆိုတာ ဘာလဲ?
Liveness check က orchestrator ကို process အသက်ရှင်နေကြောင်း ပြောပါတယ်၊ fail ဖြစ်ရင် process ကို restart လုပ်ပါတယ်။ Readiness check က load balancer ကို instance က traffic လက်ခံသင့်လား ပြောပါတယ် — ဥပမာ စတင်နေစဉ်၊ shutdown အတွက် drain လုပ်နေစဉ် ဒါမှမဟုတ် database ပျောက်နေစဉ် fail ဖြစ်တာ။ Liveness ကို ရိုးရှင်းပြီး စျေးပေါအောင်ထားပါ၊ readiness ကို critical dependency တွေ စစ်ခွင့်ပေးပါ။
132. Node API အတွက် zero-downtime deployment ကို ဘယ်လို run မလဲ?
Load balancer နောက်မှာ rolling ဒါမှမဟုတ် blue-green deployment ကို သုံးပါ၊ instance အသစ်တွေ အဆင်သင့်ဖြစ်မှ traffic ရအောင် readiness check တွေ ထားပြီး ဟောင်းတွေ လုပ်နေဆဲ request တွေကို ပြီးအောင် graceful shutdown လုပ်ပါ။ Version ဟောင်းနဲ့ အသစ် ဘေးချင်းယှဉ် run နိုင်အောင် database migration တွေကို backwards-compatible (expand၊ migrate၊ contract) ဖြစ်အောင်လုပ်ပြီး မြန်တဲ့ rollback ကို ထားပါ။
133. Database migration တွေကို ဘယ်လို လုံလုံခြုံခြုံ run မလဲ?
Migration တွေကို repository ထဲမှာ version ထားပြီး instance တိုင်း startup မှာ မဟုတ်ဘဲ pipeline ထဲမှာ deploy တစ်ခုလျှင် တစ်ကြိမ် အလိုအလျောက် run ပါ။ Additive ပြောင်းလဲမှုတွေကို ဦးစားပေးပါ၊ breaking ဖြစ်တာတွေကို release တွေကြား expand-and-contract အဆင့်တွေ ခွဲပါ၊ table ကြီးတွေမှာ lock ကြာကြာ ရှောင်ပါ (index တွေကို concurrent ဖန်တီး၊ batch လိုက် backfill) ပြီး production အရွယ် data နဲ့ migration တွေကို test လုပ်ပါ။
134. API query တွေအတွက် index တွေကို ဘယ်လို ရွေးပြီး သုံးမလဲ?
မကြာခဏသုံးတဲ့ WHERE၊ JOIN နဲ့ ORDER BY clause တွေမှာ သုံးတဲ့ column တွေကို index လုပ်ပါ၊ compound index တွေကို query တွေ filter နဲ့ sort လုပ်တဲ့ order အတိုင်း ထားပါ။ EXPLAIN နဲ့ plan တွေ စစ်ပါ၊ slow-query log တွေကို ကြည့်ပြီး index တွေက write ကို နှေးစေကာ memory သုံးတာမို့ အရာအားလုံးကို index မလုပ်ပါနဲ့။ Cursor pagination က index ပါပြီး unique ဖြစ်တဲ့ sort key ပေါ်မှာ အကောင်းဆုံး အလုပ်လုပ်ပါတယ်။
135. Read replica၊ caching ဒါမှမဟုတ် sharding — database ကို ဘယ်လို scale လုပ်မလဲ?
အရင်ဆုံး query နဲ့ index တွေကို optimise လုပ်ပြီး hot read တွေအတွက် caching ထည့်ပါ။ ပြီးမှ read များတဲ့ workload တွေအတွက် replication lag နည်းနည်းကို လက်ခံပြီး read replica တွေ ထည့်ပါ။ Primary တစ်ခုတည်းက write ဒါမှမဟုတ် data size ကို မခံနိုင်တော့မှပဲ partition ဒါမှမဟုတ် shard လုပ်ပါ၊ sharding က query၊ transaction နဲ့ operations တွေကို ရှုပ်ထွေးစေလို့ပါ။ Node instance အများကြီး ချိတ်တဲ့အခါ ရှေ့မှာ connection pooling (ဥပမာ PgBouncer) က ကူညီပါတယ်။
136. Cache stampede ပြဿနာကို ဘယ်လို ကိုင်တွယ်မလဲ?
လူကြိုက်များတဲ့ cache key တစ်ခု expire ဖြစ်တဲ့အခါ request အများကြီး တစ်ပြိုင်နက် miss ဖြစ်ပြီး database ကို ထုပါတယ်။ Request coalescing (request တစ်ခုပဲ ပြန်တွက်ပြီး ကျန်တာတွေ စောင့်တာ)၊ expiry မတိုင်ခင် စောစော ဒါမှမဟုတ် probabilistic refresh၊ stale-while-revalidate serve လုပ်တာနဲ့ key တွေ အတူ expire မဖြစ်အောင် expiry time တွေမှာ jitter ထည့်တာနဲ့ ကာကွယ်ပါ။
137. Instance အများကြီးကြား API rate limiter ကို ဘယ်လို design လုပ်မလဲ?
Counter တွေကို Redis လို shared store ထဲမှာ atomic operation တွေနဲ့ ထားပြီး API key၊ user ဒါမှမဟုတ် IP တစ်ခုချင်းအတွက် sliding-window ဒါမှမဟုတ် token-bucket algorithm ကို သုံးပါ။ Rate-limit header တွေနဲ့ 429 ပြန်ပေးပါ၊ route အမျိုးမျိုးကို tier မတူအောင် apply လုပ်ပြီး gateway ဒါမှမဟုတ် CDN မှာ ကြမ်းကြမ်း limit လုပ်ဖို့ စဉ်းစားပါ။ Redis မရနိုင်တဲ့အခါ limiter ကို ရည်ရွယ်ချက်ရှိရှိ fail open ဒါမှမဟုတ် closed ဖြစ်အောင် လုပ်ပါ။
138. Node API တွေအတွက် serverless ရဲ့ trade-off တွေက ဘာလဲ?
Serverless function တွေက အလိုအလျောက် scale ဖြစ်ပြီး idle ဖြစ်နေရင် ဘာမှ မကုန်တာမို့ ရုတ်တရက်တက်တဲ့ traffic နဲ့ event-driven အလုပ်တွေနဲ့ သင့်တော်ပါတယ်။ Trade-off တွေက cold start၊ execution time limit၊ ကြာကြာရှိတဲ့ connection ကန့်သတ်ချက် (WebSocket တွေက သီးခြား service လိုတယ်) နဲ့ pooler ဒါမှမဟုတ် HTTP-based driver မသုံးရင် သက်တမ်းတို instance အများကြီးက database တွေကို လွှမ်းမိုးတာပါ။ ကြာကြာ run ပြီး တည်ငြိမ်တဲ့ workload တွေက container တွေမှာ များသောအားဖြင့် ပိုစျေးပေါပါတယ်။
139. Node နဲ့ scale ကြီးတဲ့ real-time feature တွေကို ဘယ်လို ကိုင်တွယ်မလဲ?
WebSocket connection တွေက stateful ဖြစ်တာမို့ instance အများကြီးရှိရင် user တစ်ယောက်အတွက် message က server မှားဆီ ရောက်နိုင်ပါတယ်။ Instance တွေကြား broadcast လုပ်ဖို့ pub/sub layer — Redis၊ NATS ဒါမှမဟုတ် Socket.IO ရဲ့ Redis adapter — ကို သုံးပါ၊ လိုရင် sticky session ဖွင့်ပါ၊ instance တစ်ခုချင်းရဲ့ connection ကို ကန့်သတ်ပြီး reconnection နဲ့ လွတ်သွားတဲ့ message တွေကို sequence number ဒါမှမဟုတ် resume token နဲ့ ကိုင်တွယ်ပါ။
140. Node backend အတွက် ဘယ် testing strategy ကို သုံးမလဲ?
Business logic အတွက် မြန်တဲ့ unit test တွေ၊ container (Testcontainers) ထဲက database အစစ်နဲ့ route တွေကို ထုတဲ့ integration test အများကြီး၊ တခြား team တွေ သုံးတဲ့ ဒါမှမဟုတ် ကိုယ်မှီခိုတဲ့ API တွေအတွက် contract test တွေနဲ့ deploy လုပ်ထားတဲ့ environment ပေါ်မှာ အရေးကြီးတဲ့ flow တွေရဲ့ end-to-end test အနည်းငယ်။ Launch ကြီးတွေ မတိုင်ခင် performance-sensitive endpoint တွေအတွက် load test (k6၊ Artillery) တွေ ထည့်ပါ။
141. Node API ကို ဘယ်လို load test လုပ်မလဲ၊ ဘာကို ရှာမလဲ?
k6 ဒါမှမဟုတ် Artillery လို tool နဲ့ လက်တွေ့ကျတဲ့ scenario တွေရေးပါ၊ production နဲ့ဆင်တဲ့ environment ပေါ်မှာ traffic ကို တဖြည်းဖြည်း မြှင့်ပြီး latency percentile၊ error rate၊ CPU၊ memory၊ event loop lag နဲ့ database metric တွေကို ကြည့်ပါ။ Latency ရုတ်တရက် တက်သွားတဲ့ အမှတ်ကို ရှာပါ၊ bottleneck ကို ခွဲခြားပါ — များသောအားဖြင့် database ဒါမှမဟုတ် blocking operation — ပြီး ပြန် test မလုပ်ခင် ပြင်ပါ။
142. Backward compatibility အတွက် API တွေကို ဘယ်လို design လုပ်မလဲ?
API ကို contract တစ်ခုအဖြစ် ဆက်ဆံပါ။ နာမည်ပြောင်းတာ ဒါမှမဟုတ် ဖယ်တာ မဟုတ်ဘဲ optional field နဲ့ endpoint အသစ်တွေ ထပ်ထည့်ပါ၊ ရှိပြီးသား field ရဲ့ အဓိပ္ပာယ် ဒါမှမဟုတ် type ကို ဘယ်တော့မှ မပြောင်းပါနဲ့၊ client တွေကို မသိတဲ့ field တွေကို လျစ်လျူရှုခိုင်းပြီး တကယ့် breaking change တွေအတွက်ပဲ version တင်ပါ။ Deprecate လုပ်ထားတဲ့ field တွေရဲ့ အသုံးပြုမှုကို ခြေရာခံပါ၊ timeline တွေ ကြေညာပြီး traffic မရှိတော့မှ ဖယ်ပါ။
143. File upload နဲ့ user ဖန်တီးတဲ့ content တွေကို ဘယ်လို လုံခြုံအောင် လုပ်မလဲ?
Size limit တွေကို စောစော အကောင်အထည်ဖော်ပါ၊ file ရဲ့ byte တွေကနေ content type အစစ်ကို စစ်ပါ၊ upload တွေကို web root ပြင်ပ (အကောင်းဆုံးက private access နဲ့ signed URL ပါတဲ့ object storage) မှာ သိမ်းပါ၊ file နာမည်အသစ်တွေ ထုတ်ပါ၊ လိုအပ်ရင် malware scan လုပ်ပြီး image တွေကို sandbox လုပ်ထားတဲ့ worker ထဲမှာ process လုပ်ပါ။ Malicious file တွေကြောင့် ပျက်စီးမှု ကန့်သတ်ဖို့ user content ကို domain သီးခြားကနေ serve လုပ်ပါ။
144. Node.js မှာ permission model ဆိုတာ ဘာလဲ?
Modern Node မှာ built-in permission model ပါပါတယ် — --permission နဲ့ run ရင် process က ခွင့်မပြုမချင်း file ဖတ်တာ၊ ရေးတာ၊ child process spawn လုပ်တာ ဒါမှမဟုတ် worker thread ဖန်တီးတာ မလုပ်နိုင်တော့ပါဘူး၊ ဥပမာ --allow-fs-read=./data နဲ့ ခွင့်ပြုပါတယ်။ Minimal container ထဲမှာ non-root user အဖြစ် run တာနဲ့အတူ compromise ဖြစ်တဲ့ dependency တွေကနေ အထပ်ထပ် ကာကွယ်ပေးပါတယ်။
145. Backend မှာ time zone နဲ့ date တွေကို ဘယ်လို ကိုင်တွယ်မလဲ?
Timestamp တွေကို UTC (ISO 8601 string ဒါမှမဟုတ် database ရဲ့ timestamp-with-time-zone type) နဲ့ သိမ်းပြီး ပို့ပါ၊ user ရဲ့ time zone ကို display ဒါမှမဟုတ် "တစ်နေ့ရဲ့အဆုံး" လို local time ပေါ်မူတည်တဲ့ business rule တွေအတွက်ပဲ ပြောင်းပါ။ Intl ဒါမှမဟုတ် ခိုင်မာတဲ့ date library ကို သုံးပါ၊ user ရဲ့ IANA time zone ကို သိမ်းပြီး daylight-saving ပြောင်းချိန်တွေ ဝန်းကျင်မှာ test လုပ်ပါ။
146. Node မှာ ငွေနဲ့ တိကျတဲ့ number တွေကို ဘယ်လို ကိုင်တွယ်မလဲ?
JavaScript number တွေက binary floating point ဖြစ်တာမို့ 0.1 + 0.2 က 0.3 အတိအကျ မဟုတ်ပါဘူး။ ငွေကို အသေးဆုံးယူနစ် (cent) နဲ့ integer အဖြစ် သိမ်းပါ၊ ဒါမှမဟုတ် database မှာ decimal type နဲ့ code မှာ decimal library ကို သုံးပါ။ Amount တိုင်းနဲ့အတူ currency ကို ထားပါ၊ သတ်မှတ်ထားတဲ့ အမှတ်တွေမှာပဲ round လုပ်ပြီး 2^53 ကျော်တဲ့ integer တွေအတွက် BigInt ကို သုံးပါ။
147. Error တွေက HTTP response တွေနဲ့ သန့်သန့်ရှင်းရှင်း ကိုက်ညီအောင် error class တွေကို ဘယ်လို design လုပ်မလဲ?
HTTP status နဲ့ တည်ငြိမ်တဲ့ code ပါတဲ့ operational error တွေရဲ့ hierarchy သေးသေးလေး — NotFoundError၊ ValidationError၊ ConflictError၊ ForbiddenError — ဖန်တီးပါ။ Service တွေက Express အကြောင်း မသိဘဲ သူတို့ကို throw လုပ်ပါတယ်၊ error middleware တစ်ခုက သူတို့ကို response တွေအဖြစ် ပြောင်းပြီး ကျန်တာမှန်သမျှကို log လုပ်ကာ alert ပေးမယ့် မမျှော်လင့်ထားတဲ့ 500 အဖြစ် ဆက်ဆံပါတယ်။ Debug အတွက် မူလ error ကို ထိန်းထားဖို့ cause option ကို သုံးပါ။
export class AppError extends Error { constructor(message, { status = 500, code = "INTERNAL", cause } = {}) { super(message, { cause }); this.status = status; this.code = code; }}export class NotFoundError extends AppError { constructor(message = "Not found") { super(message, { status: 404, code: "NOT_FOUND" }); }}148. Express 4 application ကို Express 5 ဆီ ဘယ်လို migrate လုပ်မလဲ?
Migration guide ကို ဖတ်ပြီး branch တစ်ခုမှာ upgrade လုပ်ပါ။ Route path တွေကို syntax အသစ်ဆီ update လုပ်ပါ (/*splat လို နာမည်ပေးထားတဲ့ wildcard၊ optional အပိုင်းတွေအတွက် brace)၊ app.del နဲ့ res.send(status) ပုံစံဟောင်းလို ဖယ်ရှားခံရတဲ့ method တွေကို အစားထိုးပါ၊ req.query ကို ရေးတာ ရပ်ပြီး Express 5 က rejected promise တွေကို ကိုင်တွယ်ပေးတာမို့ async error wrapper တွေကို ဖယ်ပါ။ Official codemod တွေ run ပြီးမှ test suite နဲ့ canary deploy ကို run ပါ။
149. Startup time ကို ဘယ်လို profile လုပ်ပြီး လျှော့ချမလဲ?
Startup မှာ --cpu-prof နဲ့ တိုင်းပြီး import time မှာ လေးတဲ့ synchronous အလုပ်တွေ — config ကြီး parse လုပ်တာ၊ database connection ကို အလျင်အမြန် ဖွင့်တာ၊ dependency tree ကြီးတွေ — ကို ရှာပါ။ ရှားရှားပါးပါးသုံးတဲ့ module တွေကို lazy-load လုပ်ပါ၊ support လုပ်ရင် compile လုပ်ထားတဲ့ code ကို cache လုပ်ပါ၊ barrel file ကြီးတွေ ရှောင်ပြီး dependency တွေကို လျှော့ပါ။ မြန်တဲ့ startup က autoscaling၊ serverless cold start နဲ့ မြန်တဲ့ rollback တွေအတွက် အရေးကြီးပါတယ်။
150. Node နဲ့ URL shortener API ကို ဘယ်လို design လုပ်မလဲ တစ်ဆင့်ချင်း ရှင်းပြပါ။
Endpoint တွေ — ဖန်တီးဖို့ POST /links၊ redirect လုပ်ဖို့ GET /:code။ Short code တွေကို base62 နဲ့ encode လုပ်ထားတဲ့ counter ကနေ ဒါမှမဟုတ် uniqueness check ပါတဲ့ random ID ကနေ ထုတ်ပါ၊ code → url, owner, createdAt ကို code ပေါ်မှာ index နဲ့ သိမ်းပါ။ Redirect တွေကို database ကို fallback ထားပြီး Redis ကနေ serve လုပ်ပါ၊ click တွေကို queue ကနေ asynchronous ရေတွက်ပါ၊ ဖန်တီးတာကို rate-limit လုပ်ပါ၊ အလွဲသုံးစား ပိတ်ဖို့ URL တွေကို validate လုပ်ပြီး caching နဲ့ replica တွေနဲ့ read ကို scale လုပ်ပါ။
Tech Lead — Node.js Backend Team တွေကို ဦးဆောင်ခြင်း
Tech lead အဆင့်မှာ မေးခွန်းတွေက code ကနေ system နဲ့ လူတွေဆီ ရွှေ့သွားပါတယ် — platform နဲ့ architecture ရွေးချယ်တာ၊ service တွေကို ယုံကြည်ရပြီး လုံခြုံအောင် ထိန်းတာ၊ release နဲ့ incident တွေကို run တာ၊ technical debt ကို manage လုပ်တာနဲ့ backend team ကို ကြီးထွားစေတာ။ Interviewer တွေက ရှင်းလင်းတဲ့ ကျိုးကြောင်းဆင်ခြင်မှု၊ ရိုးသားတဲ့ trade-off တွေနဲ့ team တစ်ခုလုံးရဲ့ output ကို မြှင့်တင်ခဲ့တဲ့ ဥပမာတွေကို ရှာပါတယ်။
151. Node.js product အသစ်အတွက် backend stack ကို ဘယ်လို ရွေးမလဲ?
လိုအပ်ချက်ကနေ စပါ — traffic ပုံစံ၊ latency လိုအပ်ချက်၊ data model၊ team skill၊ hosting နဲ့ compliance။ ပြီးမှ framework (Express၊ Fastify ဒါမှမဟုတ် NestJS)၊ data နဲ့ ကိုက်တဲ့ database နဲ့ infrastructure အနည်းဆုံး — များသောအားဖြင့် service တစ်ခု၊ database တစ်ခု၊ cache နဲ့ queue — ကို ရွေးပါ။ အန္တရာယ်အများဆုံး အပိုင်းကို prototype လုပ်ပါ၊ ဆုံးဖြတ်ချက်နဲ့ ငြင်းပယ်ခဲ့တဲ့ alternative တွေကို ADR မှာ ရေးပြီး အသစ်ဖြစ်လို့သက်သက် technology ကို မကျင့်သုံးပါနဲ့။
152. Monolith ကို service တွေအဖြစ် ဘယ်အချိန် ခွဲမလဲ ဘယ်လို ဆုံးဖြတ်မလဲ?
တိကျတဲ့ ပြဿနာက ဒါကို တရားမျှတစေမှပဲ — အစိတ်အပိုင်းတစ်ခုက သီးခြား scale လုပ်ဖို့လိုတာ၊ team တစ်ခုက ကိုယ်ပိုင် schedule နဲ့ deploy လုပ်ဖို့လိုတာ ဒါမှမဟုတ် component တစ်ခုမှာ reliability ဒါမှမဟုတ် technology လိုအပ်ချက် အလွန်ကွာတာ။ အရင်ဆုံး monolith အတွင်းက module boundary တွေကို ခိုင်မာအောင်လုပ်ပါ၊ ပြီးမှ boundary အရှင်းဆုံးနဲ့ ဝေဒနာအများဆုံး module ကို strangler pattern နဲ့၊ ကိုယ်ပိုင် data နဲ့ ကောင်းကောင်း သတ်မှတ်ထားတဲ့ API နဲ့ ခွဲထုတ်ပါ။
153. Node.js team အတွက် ဘယ် architecture guideline တွေကို သတ်မှတ်မလဲ?
တိုတိုနဲ့ ရေးထားတဲ့ default အစု — ရှင်းလင်းတဲ့ public interface ပါတဲ့ business domain အလိုက် module တွေ၊ HTTP၊ business logic နဲ့ data access ကို ခွဲထားတာ၊ input တိုင်းကို schema နဲ့ validate လုပ်တာ၊ error-handling နဲ့ logging နည်းလမ်း တစ်ခုတည်း၊ startup မှာ validate လုပ်ထားတဲ့ config၊ request path ပေါ်မှာ blocking အလုပ် မရှိတာနဲ့ service တိုင်းက log၊ metric နဲ့ trace တွေနဲ့ observable ဖြစ်တာ။ Template တွေ၊ lint rule တွေနဲ့ review checklist တွေနဲ့ ထောက်ခံပါ။
154. Team အများကြီးကြား service အသစ်တွေကို ဘယ်လို standardise လုပ်မလဲ?
သဘောတူထားတဲ့ framework setup၊ config validation၊ structured logging၊ OpenTelemetry tracing၊ health check၊ graceful shutdown၊ Dockerfile၊ CI pipeline နဲ့ test setup တွေ ပါပြီးသား service template ဒါမှမဟုတ် generator ကို ပေးပါ။ Team တွေက ခင်းထားတဲ့ လမ်းကနေ စပြီး အကြောင်းပြချက်ရှိမှပဲ သွေဖည်ပါတယ်။ Template ကို maintain လုပ်ထားပြီး ဖြတ်ကျော်တဲ့ ကိစ္စတွေအတွက် shared library တွေ publish လုပ်ပါ။
155. Organisation အတွက် API design standard တွေကို ဘယ်လို သတ်မှတ်မလဲ?
တိုတောင်းတဲ့ API style guide တစ်ခု ရေးပါ — resource နာမည်ပေးပုံ၊ HTTP method နဲ့ status code တွေ၊ error format တစ်ခုတည်း၊ pagination၊ filtering နဲ့ sorting convention တွေ၊ versioning နဲ့ deprecation rule တွေ၊ မလုံခြုံတဲ့ operation တွေအတွက် authentication နဲ့ idempotency။ API တိုင်းအတွက် OpenAPI spec လိုအပ်ပါစေ၊ CI မှာ spec တွေကို အလိုအလျောက် lint လုပ်ပြီး API အသစ်တွေကို ship ပြီးမှ မဟုတ်ဘဲ design အစောပိုင်းမှာ review လုပ်ပါ။
156. Service အများကြီးမှာ Node.js ဒါမှမဟုတ် framework major upgrade ကို ဘယ်လို plan ချမလဲ?
သုံးနေတဲ့ runtime version တွေကို Node release schedule နဲ့ ခြေရာခံပြီး LTS အသစ်တိုင်းကို ပထမလ အနည်းငယ်အတွင်း upgrade လုပ်ပါ။ Pilot service တစ်ခုမှာ upgrade ကို အရင် test လုပ်ပါ၊ codemod တွေ run ပြီး deprecation တွေကို ပြင်ပါ၊ shared library နဲ့ service template ကို upgrade လုပ်ပြီးမှ တိုးတက်မှုပြတဲ့ dashboard နဲ့ service တစ်ခုချင်း rollout လုပ်ပါ။ သေးငယ်ပြီး ပုံမှန် upgrade တွေက ရှားရှားပါးပါး ခက်ခဲတဲ့ upgrade တွေထက် သာပါတယ်။
157. Backend codebase မှာ technical debt ကို ဘယ်လို manage လုပ်မလဲ?
မြင်သာအောင်လုပ်ပြီး ကုန်ကျစရိတ် — incident၊ နှေးတဲ့ delivery၊ security risk၊ scaling ကန့်သတ်ချက် — နဲ့ ချိတ်ပါ။ ဦးစားပေးထားတဲ့ debt စာရင်း ထားပါ၊ capacity ရဲ့ တည်ငြိမ်တဲ့ ရာခိုင်နှုန်းကို ချန်ထားပြီး code အပြောင်းအလဲ အများဆုံးနေရာမှာ ဆပ်ပါ။ Business ကို risk နဲ့ speed အရ ရှင်းပြပါ၊ standard၊ review နဲ့ automated check တွေနဲ့ debt အသစ်ကို ကာကွယ်ပါ။
158. Backend code review checklist ထဲမှာ ဘာတွေ ထည့်မလဲ?
Checklist တိုလေးက review တွေကို တသမတ်တည်းဖြစ်ပြီး အာရုံစိုက်စေပါတယ်။
- Endpoint တိုင်းအတွက် input ကို validate လုပ်ပြီး authorisation ကို စစ်ထားလား
- Error တွေကို ကိုင်တွယ်၊ context နဲ့ log လုပ်ပြီး လုံခြုံတဲ့ response ပြန်ပေးထားလား
- Request path ပေါ်မှာ blocking အလုပ် မရှိဘူး၊ external call တွေမှာ timeout ပါတယ်
- Database ပြောင်းလဲမှုတွေ index လုပ်ထား၊ လုံလုံခြုံခြုံ migrate လုပ်ထားပြီး backwards compatible ဖြစ်လား
- Behaviour အတွက် test တွေ၊ log ထဲမှာ secret ဒါမှမဟုတ် ကိုယ်ရေးကိုယ်တာ data မရှိတာ
159. Node.js codebase မှာ quality ကို အလိုအလျောက် ဘယ်လို အကောင်အထည်ဖော်မလဲ?
Strict mode နဲ့ TypeScript၊ security နဲ့ promise rule တွေပါတဲ့ ESLint၊ Prettier၊ dependency boundary check တွေနဲ့ မြန်တဲ့ feedback အတွက် commit hook တွေ။ CI မှာ type check၊ test၊ critical module တွေရဲ့ coverage၊ dependency audit၊ secret scanning နဲ့ container image scanning တွေပေါ်မှာ merge ကို gate လုပ်ပါ။ Objective ဖြစ်တာမှန်သမျှကို automate လုပ်ပြီး လူ review ကို design အပေါ် အာရုံစိုက်ခွင့်ပေးပါ။
160. Backend service အတွက် SLO တွေကို ဘယ်လို သတ်မှတ်မလဲ?
User experience ကို ထင်ဟပ်တဲ့ indicator တွေကို ရွေးပါ — အဓိက endpoint တွေအတွက် availability (အောင်မြင်တဲ့ request) နဲ့ latency (ဥပမာ p95 300 ms အောက်) — ပြီး target ကို ယုံကြည်စွာ ပေးနိုင်တာထက် နည်းနည်းနိမ့်အောင် သတ်မှတ်ပါ၊ ဥပမာ 99.9%။ ကွာဟချက်က error budget ပါ — မြန်မြန် ကုန်နေရင် feature အလုပ်ကို နှေးစေပြီး reliability မှာ ရင်းနှီးပါ။ Blip တိုင်းအပေါ် မဟုတ်ဘဲ burn rate အပေါ် alert လုပ်ပါ။
161. Tech lead အနေနဲ့ incident ကို ဘယ်လို run မလဲ?
Role တွေကို မြန်မြန် ခွဲပေးပါ — incident commander တစ်ယောက်၊ စုံစမ်းမယ့်သူ၊ ဆက်သွယ်မယ့်သူ။ အရင်ဆုံး mitigation ကို အာရုံစိုက်ပါ — rollback လုပ်၊ feature flag ကို ပိတ်၊ scale up ဒါမှမဟုတ် fail over လုပ်ပါ။ သက်ရောက်မှုနဲ့ နောက် update အချိန်တွေကို channel တစ်ခုတည်းမှာ ပုံမှန် ဆက်သွယ်ပါ။ ပြီးနောက် timeline၊ root cause တွေနဲ့ ပိုင်ရှင်ပါတဲ့ action တွေပါတဲ့ blameless post-mortem ကို run ပြီး action တွေ ပြီးတဲ့အထိ လိုက်ပါ။
162. Backend team အတွက် on-call process ကို ဘယ်လို design လုပ်မလဲ?
Alert တွေကို လုပ်ဆောင်လို့ရပြီး နည်းနည်းပဲ ဖြစ်အောင်လုပ်ပါ — တစ်ခုချင်းက dashboard နဲ့ runbook ကို ချိတ်ပါတယ်။ Primary နဲ့ backup နဲ့ တရားမျှတစွာ လှည့်ပါ၊ on-call မဝင်ခင် shadow shift တွေနဲ့ လေ့ကျင့်ပေးပါ၊ အခကြေးငွေ ပေးပြီး page တိုင်းကို နောက်မှ review လုပ်ကာ noise ကို ဖယ်ပါ ဒါမှမဟုတ် အကြောင်းရင်းကို ပြင်ပါ။ On-call က ခက်ခဲနေရင် reliability အလုပ်ကို ထိပ်ဆုံး ဦးစားပေးအဖြစ် ဆက်ဆံပါ။
163. Backend စွမ်းရည်တွေအတွက် ကိုယ်တိုင်တည်ဆောက်မလား ဝယ်မလား ဘယ်လို ဆုံးဖြတ်မလဲ?
Product ကို ထူးခြားစေတာကို တည်ဆောက်ပါ၊ authentication၊ payment၊ email ပို့တာ၊ search၊ queue နဲ့ observability လို commodity တွေအတွက် managed service တွေကို ဝယ်ပါ ဒါမှမဟုတ် ကျင့်သုံးပါ။ ပိုင်ဆိုင်မှု စုစုပေါင်းကုန်ကျစရိတ် — engineering time၊ on-call၊ security patch — ကို vendor cost နဲ့ နှိုင်းယှဉ်ပြီး lock-in၊ data residency နဲ့ ပြောင်းဖို့လိုရင် ထွက်ပေါက်ကို ချိန်ဆပါ။
164. Managed cloud service နဲ့ self-hosting ကြား ဘယ်လို ရွေးမလဲ?
Managed service (database၊ queue၊ cache) တွေက ယူနစ်တစ်ခုချင်း ပိုစျေးကြီးပေမဲ့ operational အလုပ်၊ backup၊ patching နဲ့ scaling ကို ဖယ်ရှားပေးတာမို့ team အသေးနဲ့ အလတ်တွေအတွက် များသောအားဖြင့် မှန်ကန်တဲ့ default ပါ။ Operational ကျွမ်းကျင်မှုနဲ့ ခိုင်မာတဲ့ အကြောင်းပြချက် — scale ကြီးမှာ cost၊ သီးသန့် configuration၊ compliance ဒါမှမဟုတ် portability — ရှိမှ self-host လုပ်ပါ။ Scale ပြောင်းတာနဲ့အမျှ ဆုံးဖြတ်ချက်ကို ပြန်သုံးသပ်ပါ။
165. Cloud cost တွေကို ဘယ်လို ထိန်းချုပ်မလဲ?
Tagging နဲ့ dashboard တွေနဲ့ service နဲ့ team အလိုက် cost တွေကို မြင်သာအောင်လုပ်ပါ၊ budget နဲ့ alert တွေ သတ်မှတ်ပါ၊ instance နဲ့ database tier တွေကို အသုံးပြုမှု အစစ်ကနေ right-size လုပ်ပါ၊ stateless service တွေကို autoscale လုပ်ပါ၊ လုံခြုံရင် reserved ဒါမှမဟုတ် spot capacity သုံးပါ၊ စျေးကြီးတဲ့ query တွေ လျှော့ဖို့ caching ထည့်ပြီး log နဲ့ backup တွေအတွက် retention policy တွေ သတ်မှတ်ပါ။ Cost တွေကို တခြား metric တွေလိုပဲ ပုံမှန် review လုပ်ပါ။
166. ကြီးထွားလာတဲ့ backend အတွက် capacity ကို ဘယ်လို plan ချမလဲ?
လက်ရှိ load နဲ့ traffic ယူနစ်တစ်ခုချင်း သုံးတဲ့ resource တွေကို တိုင်းပါ၊ load test တွေနဲ့ ပထမဆုံး bottleneck ကို ရှာပြီး (များသောအားဖြင့် database) business ခန့်မှန်းချက်တွေကနေ ကြီးထွားမှုကို project လုပ်ပါ။ Peak တွေအတွက် headroom ထားပါ၊ horizontal scale ဖြစ်တဲ့ stateless service တွေ design လုပ်ပြီး bottleneck တစ်ခုချင်းအတွက် နောက်ခြေလှမ်း — read replica၊ caching၊ partitioning — ကို မရောက်ခင် ကြိုစီစဉ်ပါ။
167. Service တွေကြား data နဲ့ database ownership အတွက် ကိုယ့်နည်းလမ်းက ဘာလဲ?
Service တစ်ခုချင်းက ကိုယ့် data ကို ပိုင်ပြီး ကိုယ့် database ကို ရေးတဲ့ တစ်ခုတည်းသော သူ ဖြစ်ပါတယ်၊ တခြားသူတွေက API ဒါမှမဟုတ် event တွေကနေ access လုပ်ပါတယ်။ Shared database တွေက ပြောင်းလဲမှုတွေကို risk ရှိစေတဲ့ ဖုံးကွယ်ထားတဲ့ coupling ကို ဖန်တီးပါတယ်။ Reporting နဲ့ analytics အတွက် service database တွေကို တိုက်ရိုက် query လုပ်မယ့်အစား ပြောင်းလဲမှုတွေကို warehouse သီးခြားဆီ stream လုပ်ပါ။
168. Team ကို event-driven architecture ဘယ်လို မိတ်ဆက်မလဲ?
Async communication က ကူညီတဲ့ ရှင်းလင်းတဲ့ use case တစ်ခုနဲ့ စပါ — order ပြီးနောက် notification ပို့တာ၊ search index တွေ sync လုပ်တာ။ Managed broker ကို ရွေးပါ၊ event schema နဲ့ versioning rule တွေ သတ်မှတ်ပါ၊ ယုံကြည်ရတဲ့ publishing အတွက် outbox pattern ကို သုံးပြီး consumer တွေ idempotent ဖြစ်ရပါမယ်။ Producer အသစ်တွေ မထည့်ခင် event တွေကြား tracing နဲ့ dead-letter ကိုင်တွယ်မှုကို ထည့်ပါ။
169. Backend development ထဲမှာ security ကို ဘယ်လို ထည့်သွင်းတည်ဆောက်မလဲ?
ပုံမှန် workflow ရဲ့ အစိတ်အပိုင်း ဖြစ်စေပါ — feature အသစ်တွေကို threat-model လုပ်ပါ၊ service template ထဲမှာ လုံခြုံတဲ့ default တွေ ထားပါ၊ CI မှာ dependency၊ secret နဲ့ image scanning ကို automate လုပ်ပါ၊ review တွေမှာ authorisation check လိုအပ်ပါစေ၊ penetration test တွေကို အခါအားလျော်စွာ run ပြီး engineer တွေကို OWASP API risk တွေ လေ့ကျင့်ပေးပါ။ Team တစ်ခုချင်းမှာ security champion ခန့်ပြီး security finding တွေကို production bug တွေလို ဆက်ဆံပါ။
170. Dependency တစ်ခုမှာ critical vulnerability တွေ့ရင် ဘယ်လို ကိုင်တွယ်မလဲ?
ကိုယ်ထိခိုက်လား အမြန် အကဲဖြတ်ပါ — vulnerable function၊ version နဲ့ exposure။ ထိခိုက်ရင် dependency inventory ကို သုံးပြီး service အားလုံးမှာ ချက်ချင်း patch ဒါမှမဟုတ် upgrade လုပ်ပါ၊ deploy လုပ်ပြီး စစ်ဆေးအတည်ပြုပါ။ Fix မရှိရင် mitigate လုပ်ပါ (feature ကို ပိတ်တာ၊ input filtering ဒါမှမဟုတ် WAF rule ထည့်တာ)။ Stakeholder တွေကို status ဆက်သွယ်ပြီး နောက်တစ်ကြိမ် detection ကို ဘယ်လို ပိုမြန်စေမလဲ review လုပ်ပါ။
171. Backend မှာ GDPR လို compliance လိုအပ်ချက်တွေကို ဘယ်လို ကိုင်တွယ်မလဲ?
ဘယ်ကိုယ်ရေးကိုယ်တာ data ကို ဘယ်မှာ ဘာကြောင့် သိမ်းလဲ သိပါ၊ လျှော့ချပါ၊ ပို့နေစဉ်နဲ့ သိမ်းထားစဉ် encrypt လုပ်ပါ၊ role အလိုက် access ကို ကန့်သတ်ပြီး sensitive data ကို access လုပ်တာကို log လုပ်ပါ။ Data subject ရဲ့ အခွင့်အရေးတွေ — export နဲ့ deletion — ကို backup နဲ့ log တွေ အပါအဝင် store အားလုံးမှာ support လုပ်ပါ၊ retention period တွေ သတ်မှတ်ပါ၊ data-residency rule တွေနဲ့ ကိုက်တဲ့ hosting region တွေကို ရွေးပြီး ကိုယ်ရေးကိုယ်တာ data ကို log နဲ့ analytics တွေထဲ မထည့်ပါနဲ့။
172. Node.js backend team အတွက် ဘယ် testing strategy ကို သတ်မှတ်မလဲ?
Business logic အတွက် unit test တွေ၊ အဓိက layer အဖြစ် container ထဲက database အစစ်နဲ့ route တွေပေါ်က integration test တွေ၊ service တွေကြား contract test တွေနဲ့ အရေးကြီးတဲ့ ခရီးစဉ်တွေပေါ်က end-to-end test အစုသေးသေးလေး။ Launch ကြီးတွေ မတိုင်ခင် load test တွေ ထည့်ပြီး security scan တွေကို အဆက်မပြတ် run ပါ။ Merge မလုပ်ခင် ဘာကို test လုပ်ရမလဲ သဘောတူပြီး suite ကို မြန်ဆန်ကာ ယုံကြည်ရအောင် ထားပါ။
173. Team ကြီးထွားလာတာနဲ့အမျှ CI/CD ကို မြန်ပြီး လုံခြုံအောင် ဘယ်လို ထိန်းမလဲ?
Dependency နဲ့ build တွေကို cache လုပ်ပါ၊ ပြောင်းလဲမှုက ထိခိုက်တဲ့ test တွေကိုပဲ run ပါ၊ suite တွေကို parallel လုပ်ပြီး flaky test တွေကို ချက်ချင်း ပြင်ပါ။ ပြောင်းလဲမှု သေးသေးလေးတွေကို feature flag နောက်ကွယ်မှာ အလိုအလျောက် canary analysis နဲ့ click တစ်ချက် rollback နဲ့ မကြာခဏ deploy လုပ်ပါ။ Main branch ကို အမြဲ deploy လုပ်လို့ရအောင် ထားပြီး build time နဲ့ deployment frequency ကို team metric အဖြစ် ခြေရာခံပါ။
174. Risk ရှိတဲ့ backend ပြောင်းလဲမှုတွေကို ဘယ်လို လုံလုံခြုံခြုံ rollout လုပ်မလဲ?
Feature flag တွေနောက်မှာ ဖုံးထားပြီး traffic ရာခိုင်နှုန်းအနည်းငယ် ဒါမှမဟုတ် internal user တွေဆီ အရင် release လုပ်ကာ error rate နဲ့ latency ကို baseline နဲ့ နှိုင်းယှဉ်ပါ။ Code path အသစ်တွေအတွက် dark launch ဒါမှမဟုတ် shadow traffic ကို သုံးပါ၊ database ပြောင်းလဲမှုတွေကို backwards compatible ဖြစ်အောင်လုပ်ပြီး မစခင် ရှင်းလင်းတဲ့ rollback plan ထားပါ။ Exposure ကို တဖြည်းဖြည်း တိုးပါ။
175. Backend system တွေကို အသုံးဝင်နေအောင် ဘယ်လို document လုပ်မလဲ?
Documentation ကို code နားမှာ ထားပါ — schema တွေကနေ generate လုပ်တဲ့ OpenAPI spec တွေ၊ ဆုံးဖြတ်ချက်တွေအတွက် ADR တွေ၊ setup နဲ့ run ညွှန်ကြားချက်ပါတဲ့ README တွေနဲ့ operations အတွက် runbook တွေ။ Service တွေ၊ data store တွေနဲ့ flow တွေကို ပြတဲ့ high-level architecture diagram ထည့်ပါ။ Document တစ်ခုချင်းကို owner ပေးပြီး docs update ကို definition of done ရဲ့ အစိတ်အပိုင်း ဖြစ်စေပါ။
176. ရှုပ်ထွေးတဲ့ backend ပေါ်ကို engineer တွေကို ဘယ်လို onboard လုပ်မလဲ?
Docker Compose နဲ့ seed data ပါတဲ့ command တစ်ခုတည်း local setup၊ service တွေနဲ့ data flow တွေရဲ့ architecture overview၊ domain term တွေရဲ့ glossary နဲ့ endpoint အစစ်တစ်ခုကို အစအဆုံး ထိတဲ့ ပထမ task။ Buddy တစ်ယောက်နဲ့ တွဲပေးပါ၊ on-call shadow rotation မှာ အချိန်ပေးပြီး တွေ့တဲ့ onboarding ကွက်လပ်တွေကို ပြင်ခိုင်းပါ။
177. Engineer တွေကို senior-level backend skill တွေဆီ ဘယ်လို mentor လုပ်မလဲ?
အဓိပ္ပာယ်ရှိတဲ့ အစိတ်အပိုင်းတစ်ခု — service၊ migration၊ incident follow-up — ကို တစ်ဆင့်ချင်း ညွှန်ကြားချက် မဟုတ်ဘဲ အကူအညီနဲ့ ပိုင်ဆိုင်ခွင့် ပေးပါ။ သူတို့ code အပြင် design တွေကိုပါ review လုပ်ပါ၊ trade-off၊ failure mode နဲ့ observability အကြောင်း မေးခွန်းတွေ မေးပါ၊ incident review နဲ့ capacity planning မှာ ပါဝင်စေပြီး growth plan နဲ့ ချိတ်ထားတဲ့ ပုံမှန်၊ တိကျတဲ့ feedback ပေးပါ။
178. Backend technical interview တွေကို ဘယ်လို run မလဲ?
Shared rubric ပါတဲ့ structured process ကို သုံးပါ — API အသေးလေး တည်ဆောက်တာ ဒါမှမဟုတ် debug လုပ်တာလို လက်တွေ့ exercise၊ level နဲ့ ကိုက်တဲ့ system design ဆွေးနွေးမှုနဲ့ အရင်အလုပ်နဲ့ ဆုံးဖြတ်ချက်တွေအကြောင်း စကားပြောခြင်း။ အလွတ်ကျက်ထားတဲ့ trivia မဟုတ်ဘဲ failure၊ data နဲ့ trade-off တွေအကြောင်း ကျိုးကြောင်းဆင်ခြင်မှုကို ရှာပါ၊ တရားမျှတအောင် interviewer တွေကို ပုံမှန် calibrate လုပ်ပါ။
179. Backend project ကြီးတစ်ခုကို ဘယ်လို estimate လုပ်မလဲ?
Deliver လုပ်လို့ရတဲ့ milestone တွေ ခွဲပါ၊ တစ်ခုချင်းကို range နဲ့ estimate လုပ်ပြီး မသိတာတွေ — third-party integration၊ data migration၊ performance target — ကို ဖော်ပြပါ။ အန္တရာယ်အများဆုံး အပိုင်းတွေကို အရင် spike လုပ်ပါ၊ ပါးပါးလေး end-to-end slice ကို စောစော deliver လုပ်ပြီး အမှန်တကယ် တိုးတက်မှုကနေ ပုံမှန် ပြန်ခန့်မှန်းပါ။ ရက်စွဲတွေတင်မဟုတ်ဘဲ ယုံကြည်မှု level တွေကိုပါ ဆက်သွယ်ပါ။
180. Feature အလုပ်ကို reliability နဲ့ platform အလုပ်တွေနဲ့ ဘယ်လို ချိန်ခွင်လျှာညှိမလဲ?
Product နဲ့ capacity ခွဲပုံတစ်ခုကို သဘောတူပါ၊ ဥပမာ feature 70% နဲ့ reliability၊ debt နဲ့ platform 30%၊ ပြီး error budget ကို သုံးပြီး ချိန်ညှိပါ — reliability ကျလာရင် capacity ပိုပြောင်းပေးပါ။ Platform အလုပ်ကို product ဂရုစိုက်တဲ့ ရလဒ်တွေ — ပိုမြန်တဲ့ delivery၊ incident နည်းတာ၊ cost နည်းတာ — နဲ့ ချိတ်ပြီး ရလဒ်တွေကို ပြပါ။
181. API တွေပေါ်မှာ front-end နဲ့ mobile team တွေနဲ့ ဘယ်လို အလုပ်လုပ်မလဲ?
Screen နဲ့ use case တွေကနေ API တွေကို အတူ design လုပ်ပါ၊ contract ကို OpenAPI ဒါမှမဟုတ် GraphQL schema ပုံစံနဲ့ အရင်သဘောတူပြီး team တွေ parallel အလုပ်လုပ်နိုင်အောင် type နဲ့ mock တွေ generate လုပ်ပါ။ Contract test တွေ ထည့်ပါ၊ client တွေကို sandbox environment ပေးပြီး ပြောင်းလဲမှုနဲ့ deprecation တွေကို ရှင်းလင်းတဲ့ timeline တွေနဲ့ စောစော ဆက်သွယ်ပါ။
182. Technical မဟုတ်တဲ့ stakeholder တွေကို technical risk တွေကို ဘယ်လို ရှင်းပြမလဲ?
Business term တွေအဖြစ် ဘာသာပြန်ပါ — သက်ရောက်မှု (ထိခိုက်တဲ့ customer၊ ဝင်ငွေ၊ ဂုဏ်သိက္ခာ)၊ ဖြစ်နိုင်ခြေနဲ့ အခုပြင်တာ နဲ့ နောက်မှပြင်တာရဲ့ ကုန်ကျစရိတ်။ Trade-off တွေနဲ့ အကြံပြုချက်ပါတဲ့ option တွေ ပေးပါ၊ တိကျတဲ့ ဥပမာ ဒါမှမဟုတ် incident history ကို သုံးပြီး ဆုံးဖြတ်ချက်ကို စာနဲ့ အတည်ပြုပါ။ Jargon ကို ရှောင်ပြီး ချဲ့ကားမပြောပါနဲ့ — နောက်ဆွေးနွေးမှုအတွက် ယုံကြည်ရမှု အရေးကြီးပါတယ်။
183. Engineer နှစ်ယောက် design တစ်ခုအပေါ် ပြင်းပြင်းထန်ထန် သဘောထားကွဲနေတယ်။ ဘာလုပ်မလဲ?
တစ်ယောက်ချင်း သီးခြား နားထောင်ပါ၊ ပြီးမှ goal နဲ့ ဆုံးဖြတ်ဖို့ စံနှုန်းတွေ သဘောတူဖို့ အတူခေါ်ပါ။ သက်သေနဲ့ ဖြေရှင်းလို့ရရင် spike တိုလေး ဒါမှမဟုတ် benchmark run ပါ။ ချိန်ခွင်လျှာညီနေဆဲဆိုရင် ဆုံးဖြတ်ချက်ချ၊ ဘာကြောင့်လဲ ရှင်းပြ၊ ADR မှာ မှတ်တမ်းတင်ပြီး နှစ်ယောက်စလုံးကို commit လုပ်ခိုင်းပါ။ သဘောထားကွဲလွဲမှုက အလုပ်ဆက်ဆံရေးကို မထိခိုက်ကြောင်း နောက်မှ စစ်ပါ။
184. Production ဆီ bug တွေ ထပ်ခါထပ်ခါ ship လုပ်တဲ့ engineer ကို ဘယ်လို ကိုင်တွယ်မလဲ?
System ပြဿနာကို အရင်ရှာပါ — test မရှိတာ၊ လိုအပ်ချက် မရှင်းတာ၊ risk ရှိတဲ့ code area ဒါမှမဟုတ် အလျင်စလို timeline။ တိကျတဲ့ ဥပမာတွေနဲ့ သီးသန့် စကားပြောပြီး နားထောင်ပါ။ တိကျတဲ့ တိုးတက်မှုတွေ — test ပိုများတာ၊ ပြောင်းလဲမှု ပိုသေးတာ၊ risk ရှိတဲ့ အပိုင်းတွေမှာ pair လုပ်တာ၊ senior ဆီက review — ကို သဘောတူပြီး ပုံမှန် check in လုပ်ပါ။ သဘောတူထားတဲ့ ကာလအတွင်း တိုးတက်မှု မရှိမှပဲ manager နဲ့ escalate လုပ်ပါ။
185. Backend team မှာ knowledge silo တွေကို ဘယ်လို ကာကွယ်မလဲ?
Service တွေကြား ownership နဲ့ on-call ကို လှည့်ပါ၊ ရှုပ်ထွေးတဲ့ အလုပ်မှာ pair လုပ်ပါ၊ critical code အတွက် reviewer တစ်ယောက်ထက်ပို လိုအပ်ပါစေ၊ runbook နဲ့ architecture docs တွေကို ခေတ်မီအောင် ထားပါ။ Service တစ်ခုချင်းကို အနည်းဆုံး နှစ်ယောက်က deploy၊ debug နဲ့ recover လုပ်နိုင်ကြောင်း သေချာလုပ်ပြီး တစ်ယောက်တည်းက တစ်ဦးတည်းသော ကျွမ်းကျင်သူ ဖြစ်လာတာကို သတိထားပါ — ကိုယ်တိုင် အပါအဝင်ပေါ့။
186. Team ရဲ့ ကျန်းမာရေးနဲ့ delivery ကို နားလည်ဖို့ ဘယ် metric တွေ သုံးမလဲ?
Deployment frequency၊ change တွေရဲ့ lead time၊ change failure rate နဲ့ ပြန်ကောင်းဖို့ကြာချိန် လို delivery metric တွေ၊ SLO ရရှိမှုနဲ့ incident အရေအတွက် လို reliability metric တွေနဲ့ CI time နဲ့ survey ရလဒ်လို developer experience signal တွေ။ Bottleneck ရှာပြီး system ကို တိုးတက်စေဖို့ သုံးပါ၊ တစ်ဦးချင်းကို အဆင့်သတ်မှတ်ဖို့ ဘယ်တော့မှ မသုံးပါနဲ့။
187. Backend team အတွက် developer experience ကို ဘယ်လို တိုးတက်အောင် လုပ်မလဲ?
အချိန် ဘယ်ကို ကုန်လဲ တိုင်းပြီး အတားအဆီးတွေကို ဖယ်ပါ — Docker Compose နဲ့ မြန်တဲ့ local environment၊ မြန်ပြီး ယုံကြည်ရတဲ့ CI၊ service နဲ့ endpoint အသစ်တွေအတွက် generator၊ preview environment၊ type ပါတဲ့ configuration၊ ကောင်းတဲ့ error message နဲ့ ရှင်းလင်းတဲ့ docs။ သက်သာသွားတဲ့ မိနစ်တိုင်းက engineer တိုင်း နေ့တိုင်း ထပ်ခါထပ်ခါ ဖြစ်ပါတယ်။
188. Service အသစ်အတွက် Node.js နဲ့ တခြား language ကြား ဘယ်လို ရွေးမလဲ?
Node က I/O များတဲ့ API၊ real-time feature၊ BFF layer နဲ့ front end နဲ့ TypeScript မျှသုံးတဲ့ team တွေအတွက် အကောင်းဆုံးပါ။ Data processing ဒါမှမဟုတ် machine learning လို CPU လေးတဲ့ workload တွေ ဒါမှမဟုတ် library ecosystem က တခြားနေရာမှာ အများကြီး ပိုအားကောင်းတဲ့အခါ Go၊ Java၊ Rust ဒါမှမဟုတ် Python က ပိုကိုက်ညီနိုင်ပါတယ်။ Raw performance တစ်ခုတည်း မဟုတ်ဘဲ team skill၊ hiring နဲ့ operational consistency ကို စဉ်းစားပါ။
189. Disaster recovery ကို ဘယ်လို plan ချမလဲ?
System တစ်ခုချင်းအတွက် recovery time နဲ့ recovery point objective တွေကို business နဲ့ သတ်မှတ်ပါ။ အလိုအလျောက်၊ encrypt လုပ်ထားတဲ့ backup တွေယူပြီး region ဒါမှမဟုတ် account တခြားမှာ သိမ်းကာ restore ကို ပုံမှန် test လုပ်ပါ — test မလုပ်ထားတဲ့ backup က backup မဟုတ်ပါဘူး။ Environment တွေ ပြန်ဖန်တီးနိုင်အောင် infrastructure as code ကို သုံးပြီး game day တွေနဲ့ failover ကို လေ့ကျင့်ပါ။
190. Multi-region deployment ကို ဘယ်လို ချဉ်းကပ်မလဲ?
Business က လိုအပ်မှပဲ — global user တွေအတွက် latency နည်းဖို့၊ regulatory data residency ဒါမှမဟုတ် region တစ်ခုလုံး ကျတာကို ခံနိုင်ဖို့။ Region အများကြီးမှာ data ရေးတာက consistency နဲ့ conflict ပြဿနာတွေ ယူလာတာမို့ active-active မတိုင်ခင် active-passive (warm standby region) နဲ့ စပါ။ Global load balancing နဲ့ user တွေကို route လုပ်ပြီး stateless service တွေကို region မမှီခိုအောင် ထားပါ။
191. API gateway ဒါမှမဟုတ် service mesh ကို ဘယ်လို ဆုံးဖြတ်မလဲ?
API gateway က edge မှာ ဖြတ်ကျော်တဲ့ ကိစ္စတွေကို စုစည်းပေးပါတယ် — routing၊ authentication၊ rate limiting၊ request transformation နဲ့ analytics — public service အများအပြား ရှိလာရင် အသုံးဝင်ပါတယ်။ Service mesh က service-to-service traffic ကို ကိုင်တွယ်ပါတယ် — mutual TLS၊ retry၊ traffic splitting နဲ့ telemetry — microservice အများကြီးအတွက် တန်ဖိုးရှိပေမဲ့ operational ရှုပ်ထွေးမှု ထပ်ယူလာပါတယ်။ သူတို့ ဖြေရှင်းတဲ့ ပြဿနာတွေ တကယ်ရှိမှ တစ်ခုချင်းကို ကျင့်သုံးပါ။
192. Technical design review ကို ဘယ်လို run မလဲ?
Author တွေကို design document တိုလေး တောင်းပါ — ပြဿနာ၊ goal နဲ့ non-goal၊ အဆိုပြု design၊ alternative တွေ၊ data model၊ API၊ failure mode၊ security၊ observability နဲ့ rollout။ Meeting မတိုင်ခင် မျှဝေပါ၊ သက်ရောက်တဲ့ team တွေက လူတွေကို ဖိတ်ပါ၊ ဆွေးနွေးမှုကို risk နဲ့ trade-off တွေအပေါ် အာရုံစိုက်ပြီး ဆုံးဖြတ်ချက်နဲ့ ဖွင့်ထားဆဲ မေးခွန်းတွေကို မှတ်တမ်းတင်ပါ။
193. ရှိပြီးသား JavaScript Node codebase ထဲကို TypeScript ကို ဘယ်လို မိတ်ဆက်မလဲ?
တဖြည်းဖြည်းပါ — အစပိုင်းမှာ allowJs ပါပြီး checkJs ပိတ်ထားတဲ့ tsconfig ထည့်ပါ၊ shared utility တွေနဲ့ code အသစ်တွေကို TypeScript ဆီ ပြောင်းပါ၊ module boundary တွေမှာ type ထည့်ပြီး strictness ကို တစ်ဆင့်ချင်း မြှင့်ပါ။ Runtime validation နဲ့ type တွေ ညီအောင် ပြင်ပ input တွေကို schema တွေနဲ့ type ပေးပါ။ တိုးတက်မှု မပျောက်အောင် ပထမနေ့ကတည်းက CI မှာ type check ကို run ပါ။
194. Backend team ကို product roadmap နဲ့ ဘယ်လို ညှိထားမလဲ?
Technical ကန့်သတ်ချက်နဲ့ ဖြစ်နိုင်စေတဲ့ အလုပ်တွေ မြင်သာအောင် planning ကို စောစော ပါဝင်ပါ၊ roadmap item တွေကို ရှင်းလင်းတဲ့ owner တွေပါတဲ့ technical milestone တွေအဖြစ် ဘာသာပြန်ပြီး product ကို ထောက်ပံ့တဲ့ technical roadmap — platform တိုးတက်မှု၊ scaling ခြေလှမ်း၊ ဆပ်ရမယ့် debt — ကို ထိန်းထားပါ။ Product နဲ့ တိုးတက်မှုကို ပုံမှန် review လုပ်ပြီး ဦးစားပေးတွေ ပြောင်းရင် နှစ်ခုစလုံးကို ချိန်ညှိပါ။
195. Backend team မှာ ownership culture ကို ဘယ်လို ဖန်တီးမလဲ?
Team တွေက service တွေကို အစအဆုံး ပိုင်ပါတယ် — design၊ build၊ deploy၊ operate နဲ့ support — သဘောတူထားတဲ့ standard အတွင်းမှာ ဆုံးဖြတ်ခွင့်နဲ့အတူ။ ရလဒ်တွေကို dashboard တွေနဲ့ မြင်သာအောင်လုပ်ပါ၊ reliability နဲ့ speed တိုးတက်မှုတွေကို ဂုဏ်ပြုပါ၊ blameless review တွေ run ပြီး သူတို့အလုပ်က customer တွေအတွက် ဘာကြောင့် အရေးကြီးလဲ ဆိုတဲ့ context ကို ပေးပါ။
196. Lead အနေနဲ့ ကိုယ့် technical skill တွေကို ဘယ်လို ထက်မြက်နေအောင် ထိန်းမလဲ?
အာရုံစိုက်တဲ့ ပုံစံတွေနဲ့ hands-on ဆက်ဖြစ်နေပါ — design နဲ့ code တွေ review လုပ်တာ၊ prototype နဲ့ spike တွေ ရေးတာ၊ incident စုံစမ်းမှုတွေမှာ ပါဝင်တာနဲ့ critical မဟုတ်တဲ့ ticket တွေကို ရံဖန်ရံခါ ယူတာ။ Release note တွေနဲ့ တခြားကုမ္ပဏီတွေရဲ့ post-mortem တွေကို ဖတ်ပါ၊ side project တွေမှာ tool အသစ်တွေ စမ်းသပ်ပြီး ကိုယ့် team ထဲက engineer တွေဆီကလည်း သင်ယူပါ။
197. Team ကို ဦးဆောင်ပြီး ဖြတ်ကျော်ခဲ့တဲ့ ခက်ခဲတဲ့ production ပြဿနာတစ်ခုအကြောင်း ပြောပြပါ။
STAR structure ကို သုံးပါ — အခြေအနေနဲ့ သူ့သက်ရောက်မှု၊ တုံ့ပြန်မှုကို ဘယ်လို စီစဉ်ခဲ့လဲ၊ technical စုံစမ်းမှုနဲ့ fix၊ ဖြစ်နိုင်ရင် နံပါတ်တွေနဲ့ ရလဒ်။ အချိန်အများစုကို နောက်မှ ဘာသင်ယူပြီး ဘာပြောင်းခဲ့လဲ — monitoring၊ process ဒါမှမဟုတ် architecture — မှာ သုံးပါ။ Interviewer တွေက တည်ငြိမ်တဲ့ ခေါင်းဆောင်မှု၊ ရှင်းလင်းတဲ့ ဆက်သွယ်ပြောဆိုမှုနဲ့ ရေရှည်တည်တံ့တဲ့ တိုးတက်မှုတွေကို ရှာပါတယ်။
198. အခုမှ ဝင်ရောက်လာတဲ့ team နဲ့ ယုံကြည်မှုကို ဘယ်လို တည်ဆောက်မလဲ?
ဘာမှ မပြောင်းခင် နားထောင်ပါ — လူတိုင်းနဲ့ one-to-one၊ code၊ incident တွေနဲ့ အရင်ဆုံးဖြတ်ချက်တွေကို ဖတ်ပြီး ဘာက လူတွေကို နှေးစေလဲ မေးပါ။ Team တောင်းဆိုတဲ့ တိုးတက်မှု အသေးလေး အနည်းငယ်ကို deliver လုပ်ပါ၊ ကတိတွေ တည်ပါ၊ credit ကို ရက်ရက်ရောရော ပေးပြီး ကိုယ့်အမှားတွေကို ဝန်ခံပါ။ ယုံကြည်မှုက အချိန်ကြာလာတာနဲ့အမျှ တသမတ်တည်းရှိမှုကနေ လာပါတယ်။
199. Node.js က ဘယ်ကို ဦးတည်နေလဲ၊ team ကို ဘယ်လို ပြင်ဆင်ပေးမလဲ?
Node က web standard တွေ (fetch၊ Web Streams၊ WebSocket) ကို ဆက်ကျင့်သုံးနေတယ်၊ built-in tool တွေ (test runner၊ watch mode၊ .env loading၊ type stripping၊ permission model) ထည့်နေပြီး performance နဲ့ developer experience ကို တွန်းအားပေးနေတဲ့ Deno နဲ့ Bun လို runtime အသစ်တွေနဲ့ ယှဉ်ပြိုင်နေပါတယ်။ Standard API တွေကို ဦးစားပေးတာ၊ dependency တွေကို ပါးပါးထားတာ၊ LTS version တွေကို ပုံမှန် upgrade လုပ်တာနဲ့ runtime အသစ်တွေကို benchmark အစစ်တွေနဲ့ အကဲဖြတ်တာနဲ့ team ကို ပြင်ဆင်ပေးပါ။
200. Node.js backend team ကို ဦးဆောင်တဲ့ ပထမ ရက် 90 မှာ ဘာလုပ်မလဲ?
ပထမလ — လူတိုင်းနဲ့ တွေ့ပါ၊ product နဲ့ architecture ကို လေ့လာပါ၊ မကြာသေးခင်က incident တွေကို ဖတ်ပြီး delivery pipeline နဲ့ ဝေဒနာတွေကို map လုပ်ပါ။ ဒုတိယလ — မြင်သာတဲ့ quick win အနည်းငယ် deliver လုပ်ပါ — ပိုကောင်းတဲ့ alert၊ ပိုမြန်တဲ့ CI၊ ပြင်ပြီးသား ထပ်ခါထပ်ခါ incident။ တတိယလ — reliability၊ architecture၊ security နဲ့ လူတွေရဲ့ ကြီးထွားမှုကို ဖုံးတဲ့ team နဲ့ stakeholder တွေ သဘောတူထားတဲ့ technical strategy နဲ့ roadmap ကို စာနဲ့ရေးပြီး မျှဝေပါ။

