What Node.js is
TipV8 also runs garbage collection. libuv does the I/O.
process.nextTick() queue, then the promise microtask queue.TipV8 also runs garbage collection. libuv does the I/O.
dns.lookup(), crypto, zlib. Not sockets.UV_THREADPOOL_SIZE=8 TrapThe pool has four threads by default, so a fifth slow pbkdf2() call waits.
TrapnextTick and promise callbacks have no phase.
Asked in interviews
AskedExplain the Node.js Event Loop and how it works.process.nextTick(fn) queueMicrotask(fn) TipInside an I/O callback, setImmediate() always runs before a 0 ms timer.
TrapRecursive nextTick calls can starve the loop and stop I/O.
fn((err, data) => {})async/awaitawait failuretry { await p; } catch (e) {}TrapA throw inside an async callback reaches no catch, so the process crashes.
p.then(f).catch(h) const x = await p;Pauses this function, not the threadawait Promise.all(ps)Rejects on the first failureawait Promise.allSettled(ps) Never rejectsTipAwaiting one by one runs calls in sequence. Use Promise.all().
TrapNeither all nor allSettled cancels the other promises.
e.on('done', fn)e.off('done', fn)e.emit('done', data)Calls listeners synchronouslyTipOver 10 listeners on one event triggers a leak warning.
TrapAn 'error' event with no listener throws and crashes the process.
Asked in interviews
AskedWhat is the EventEmitter class and how do you use it?exports.add = add;module.exports = fn;Trapexports = {} breaks the link, and require() returns module.exports.
Asked in interviews
AskedWhat is the difference between module.exports and exports?require('./x')Synchronousimport x from './x.js'No __dirname, use import.meta.dirname .mjs is ESM, .cjs is CommonJS, .js follows "type"awaitTipESM imports are live bindings. require() gives you a copy.
TrapA relative import must include the file extension.
Asked in interviews
AskedWhat is the difference between CommonJS and ES6 modules in Node.js?require('node:fs')Beats a same-named file.js, .json, .node, then a directorynode_modules in each folder, up to the rootTipResults are cached by full path, so a file runs only once.
Asked in interviews
AskedHow does Node.js resolve modules?package.jsonnpm run devprestart runs before startpackage.json holds ranges. The lock file holds exact versions.npm ciTipCommit package-lock.. Its hashes catch a tampered download.
TrapScripts run in sh or cmd.exe, so Unix commands fail on Windows.
.env filenode --env-file=.env app.jsrequire('dotenv').config() process.env.PORT TipCheck required variables at startup. Keep .env out of Git.
TrapA default JWT_SECRET lets anyone sign valid tokens.
Asked in interviews
AskedHow do you handle environment configuration in Node.js?module.exports = new Pool()TipEventEmitter is the observer. Middleware is a chain of responsibility.
Asked in interviews
AskedWhat are design patterns commonly used in Node.js?Buffer.alloc(10) Buffer.from('Hi') buf.toString('base64') Buffer.concat([a, b])TipA Buffer never changes size, so joining copies the bytes.
TrapallocUnsafe() is faster but may expose old data.
Asked in interviews
AskedWhat is the Buffer class in Node.js?await readFile(p, 'utf8')await writeFile(p, s)From fs/promisesfs.readFile(p, cb)fs.createReadStream(p) Memory stays flat. readFile loads it all.pipeline(a, b, cb)TipSync calls such as readFileSync() block the event loop.
Trappipe() doesn't close the writable when the readable fails.
http.createServer(fn) server.listen(3000) req.method, req.url, req.headersres.writeHead(404) res.end('done')The first write sends the headershttps.createServer() Needs a key and a certificateTipTLS often ends at a proxy, and the app listens with plain http.
TrapFinish every response with res.end(), or the client waits.
await fetch(url)Stable since Node.js 21http.request(opts, cb)TipLibraries such as axios add timeouts and interceptors.
Trapfetch() doesn't reject on a 404 or 500. Check response.ok.
Asked in interviews
AskedHow do you make HTTP requests in Node.js?res.json() on top of httpreq.params.idreq.query.qapp.use('/api', router)'/files/*filepath' Express 5 needs the namereq.bodyexpress.json()express.urlencoded({ extended: true })extended defaults to false in Express 5TipFile uploads are multipart/, which needs a library such as multer.
TrapIn Express 5, req.body is undefined if no parser matched.
(req, res, next) => next()app.use('/api', fn)app.get('/users', fn)TipBoth run in the order you register them.
TrapA middleware that neither responds nor calls next() hangs the request.
app.use((err, req, res, next) => {})fn(req, res, next).catch(next) Express 5 does this for youapp.use() before the error handlerTipIf res.headersSent is true, call next(err). Send stack traces only in development.
Asked in interviews
AskedHow do you handle errors in Express.js?skip = (page - 1) * limitCap limit{ _id: { $lt: cursor } }Can't jump to any pageTipSort a cursor on a unique key. Fetch limit + 1 to see if a next page exists.
TrapOffsets slow down as they grow, and an insert can show an item twice.
Asked in interviews
AskedHow do you implement pagination in Node.js APIs?exec().SameSite cookiesObject.prototype TipRun npm audit to find insecure dependencies.
Asked in interviews
AskedWhat are common security vulnerabilities in Node.js applications?bcrypt.hash(pw, 10)bcrypt.compare(pw, hash)jwt.sign(claims, key, opts)jwt.verify(token, key)TipAuthentication proves who you are. Authorization decides what you may do.
TrapA JWT stays valid until it expires. Sessions are easier to revoke.
Asked in interviews
AskedHow do you implement authentication and authorization?app.use(helmet()) cors({ origin })authorize(['admin'])Your own middleware, answers 403TipLayer HTTPS, auth, validation and limits. Cap bodies with express.json({ limit }).
Trapcors() is not access control. Non-browser clients ignore it.
Asked in interviews
AskedHow do you secure API endpoints?body('email').isEmail() validationResult(req) body('name').escape() Encodes HTML to prevent XSSTipPrefer an allow list. Joi or Zod put the same checks in one object.
TrapValidate on the server too. Any client can send any request.
Asked in interviews
AskedWhat is input validation and how do you implement it?rateLimit({ windowMs, max })Answers 429TipBehind a proxy, set trust proxy so req.ip is the real client.
TrapThe default store is per process. Across instances, count in Redis.
Asked in interviews
AskedHow do you handle rate limiting in Node.js applications?mongoose.connect(url) Mongoose for MongoDB, Prisma or Sequelize for SQLsequelize.sync() TipReuse one pool. One connection per request can exhaust the database.
TrapNever join strings into SQL. Use parameterized queries.
Asked in interviews
AskedHow do you implement database connections and ORM in Node.js?new NodeCache()Fastest, lost on restartsetEx(key, ttl, value)Redis adds a network tripTrapAn unbounded in-process cache becomes a memory leak.
Asked in interviews
AskedHow do you implement caching in Node.js?new WebSocketServer() The ws packagesocket.to(room).emit() Everyone except the senderdata: hi\n\nOne-way, over text/event-stream new EventSource(url) Reconnects on its ownTipOver HTTP/1.1, browsers allow six SSE connections per domain.
TrapSocket.IO has its own protocol, so plain WebSocket clients can't connect.
cluster.fork()Own event loop and memorycluster.on('exit', fn)new Worker(file)Own V8 and event loop, same processparentPort.postMessage(x) Copies, unless you transfer itTipReuse worker threads in a pool. They add little for I/O-heavy work.
TrapCluster workers share no memory, so keep sessions in Redis.
spawn('ls', ['-lh'])No shell by defaultexec('ls | wc -l', cb)Buffers, up to maxBufferfork('./child.js') Adds an IPC channelTrapNever pass user input to exec(). That allows command injection.
monitorEventLoopDelay() Subtract the resolutionSync APIs, huge JSON, ReDoSsetImmediate()TipAlso add indexes, avoid N+1 queries, select only the columns you need.
TrapClustering doesn't fix this. A heavy task still blocks its process.
node --max-old-space-size=4096 v8.writeHeapSnapshot() Compare two, minutes apartTipUsual leaks are growing maps, listeners and uncleared timers.
TrapA snapshot blocks the loop and needs about twice the heap in memory.
Tipnode-addon-api is the C++ binding. Build with node-gyp.
Asked in interviews
AskedWhat is Node-API and how does it help with native addons?node --testjest.mock('./db') request(app).get('/x').expect(200) node --inspect app.jsnode --inspect-brk app.js-brk pauses on the first linenode --cpu-prof app.jsDEBUG=app:*TrapKeep listen() out of the file that exports app, so tests can import it.
pm2 start ecosystem.config.js pm2 reload allnpm ci --omit=devTipIn containers, run one process each, and expose /health.
Trappm2 reload needs each process to shut down gracefully.
Asked in interviews
AskedHow do you deploy Node.js applications?process.on('SIGTERM', stop)server.close(cb) Then close the databaseSIGKILLsetTimeout(() => process.exit(1), 10000)process.on('uncaughtException', fn)process.on('unhandledRejection', fn)Fatal since Node.js 15TipFail the readiness check first, so traffic stops.
TrapDon't resume after an uncaught exception. Log and exit.
stdoutwinston.format.json() Or pino. Add a request id.register.metrics() Alert on errors, p99 latency, loop delayTipLogs explain a failure, metrics show trends, traces show delays.
TrapStart tracing agents first, because they patch modules on load.
als.run({ requestId }, next)It follows await and timersals.getStore()undefined outside a contextTrapA rare callback-based library loses it. util. fixes that.
Asked in interviews
AskedWhat is AsyncLocalStorage, and what problem does it solve?Nothing matches. Try a shorter word, or clear the search.
With Pro, you can:
Already have Pro? Sign in