تختبر أسئلة مقابلة Node.js مدى فهمك لحلقة الأحداث والأنماط غير المتزامنة والتدفقات والأداء ونشر الإنتاج. يغطي هذا الدليل أسئلة Node.js الأكثر شيوعًا لمقابلات مطوري الواجهة الخلفية في عام 2026.
أسئلة Node.js الأساسية
1. اشرح حلقة أحداث Node.js
Node.js Event Loop Phases (in order):
1. timers — setTimeout, setInterval callbacks
2. pending I/O — I/O errors from previous iteration
3. idle/prepare — internal use
4. poll — retrieve new I/O events (MAIN PHASE)
5. check — setImmediate callbacks
6. close — close event callbacks (socket.destroy, etc.)
Microtask queue (runs BETWEEN each phase):
- process.nextTick() — higher priority than Promises
- Promise callbacks (.then/.catch)
Order of execution:
1. Synchronous code
2. process.nextTick() queue
3. Promise callbacks
4. setImmediate (check phase)
5. setTimeout (timers phase, even setTimeout(fn, 0))
// Demonstrate event loop order
console.log('1 - sync');
setTimeout(() => console.log('2 - setTimeout'), 0);
setImmediate(() => console.log('3 - setImmediate'));
Promise.resolve().then(() => console.log('4 - Promise'));
process.nextTick(() => console.log('5 - nextTick'));
console.log('6 - sync');
// Output: 1, 6, 5, 4, 3, 2
// sync → nextTick → Promise → setImmediate → setTimeout
2. ما هو الليبوف وماذا يفعل؟
libuv هي مكتبة C التي تشغل حلقة أحداث Node.js وعمليات الإدخال/الإخراج:
- تجمع الموضوع: يعالج عمليات الحظر (إدخال/إخراج الملفات، التشفير، DNS) على سلاسل العمليات الخلفية
- حلقة الحدث: يدير عمليات الاسترجاعات غير المتزامنة
- تجريد المنصة: يعمل على Linux (epoll)، macOS (kqueue)، Windows (IOCP)
حجم تجمع الخيوط الافتراضي: 4 عمال. يمكن أن تزيد معUV_THREADPOOL_SIZE=8.
3. ما هي تدفقات Node.js ومتى تستخدمها؟
const fs = require('fs');
const zlib = require('zlib');
const { pipeline } = require('stream/promises');
// Streams: process data piece by piece, not all at once
// Memory efficient for large files
// Four types:
// Readable: fs.createReadStream, http.IncomingMessage
// Writable: fs.createWriteStream, http.ServerResponse
// Duplex: net.Socket (both read and write)
// Transform: zlib.gzip (modifies data as it passes through)
// Good: streams don't load entire file into memory
async function compressFile(input, output) {
await pipeline(
fs.createReadStream(input),
zlib.createGzip(),
fs.createWriteStream(output)
);
}
// BAD: loads entire file into memory
// const data = fs.readFileSync('huge-file.csv'); // could be 10GB!
// Streams for HTTP
const http = require('http');
http.createServer((req, res) => {
const stream = fs.createReadStream('large-file.mp4');
stream.pipe(res); // efficient streaming to browser
}).listen(3000);
4. كيف تتعامل مع الأخطاء في كود Node.js غير المتزامن؟
// 1. async/await with try/catch (most common in 2026)
async function getUser(id) {
try {
const user = await db.findUser(id);
if (!user) throw new Error('User not found');
return user;
} catch (error) {
logger.error({ error, id }, 'Failed to get user');
throw error; // re-throw or return error response
}
}
// 2. Express error handling middleware
app.get('/users/:id', async (req, res, next) => {
try {
const user = await getUser(req.params.id);
res.json(user);
} catch (error) {
next(error); // pass to error handler
}
});
app.use((error, req, res, next) => {
logger.error(error);
res.status(error.status || 500).json({ error: error.message });
});
// 3. Uncaught exceptions (last resort)
process.on('uncaughtException', (error) => {
logger.error('Uncaught exception:', error);
process.exit(1); // restart via PM2/supervisor
});
process.on('unhandledRejection', (reason, promise) => {
logger.error('Unhandled rejection:', reason);
// In Node.js 16+, this terminates the process
});
5. شرح سلاسل العمليات العاملة في Node.js
const { Worker, isMainThread, parentPort, workerData } = require('worker_threads');
// Main thread
if (isMainThread) {
// CPU-intensive work → offload to worker thread
const worker = new Worker(__filename, {
workerData: { data: largeDataArray }
});
worker.on('message', (result) => {
console.log('Result:', result);
});
worker.on('error', (error) => {
console.error('Worker error:', error);
});
} else {
// Worker thread
const { data } = workerData;
const result = expensiveComputation(data); // doesn't block main thread!
parentPort.postMessage(result);
}
// Use worker threads for:
// - CPU-intensive computation (image processing, crypto, compression)
// - Parallel data processing
// NOT needed for I/O operations (event loop handles those efficiently)
6. كيف يمكنك توسيع نطاق تطبيق Node.js؟
// 1. Cluster module (use all CPU cores)
const cluster = require('cluster');
const os = require('os');
if (cluster.isPrimary) {
const numCPUs = os.cpus().length;
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker) => {
console.log(`Worker ${worker.id} died. Restarting...`);
cluster.fork(); // auto-restart
});
} else {
require('./server'); // each worker runs the server
}
// 2. PM2 (recommended for production)
// pm2 start app.js -i max # cluster mode, max workers
// pm2 start app.js -i 4 # 4 workers
// pm2 monit # monitoring
// 3. Horizontal scaling
// Run multiple Node.js instances
// Load balance with nginx or AWS ALB
نجاح مقابلة Node.js: فهم حلقة الحدث بعمق (المراحل، المهام الدقيقة مقابل المهام الكبيرة)، ومعرفة متى يتم استخدام التدفقات لتحسين كفاءة الذاكرة، وشرح سلاسل العمليات العاملة مقابل المجموعة للقياس، وإظهار معالجة الأخطاء غير المتزامنة. تغطي الأسئلة المتقدمة ملفات تعريف الأداء (–prof,clinic.js) واكتشاف تسرب الذاكرة وأنماط الإنتاج.
🔗 Share this article
✍️ Leave a Comment