HiTakeJobHiTakeJob

שאלות ראיון Node.js — 35 שאלות ותשובות

זמן קריאה: 8 דקות

שאלות ראיון Node.js מתמקדות ב-event loop ובמודל האסינכרוני החד-תהליכי, ב-streams ובניהול זיכרון, ב-Express וב-APIs, ובאבטחה וביצועים. במדריך זה ריכזנו 35 שאלות ותשובות אמיתיות מקובצות לפי נושא, כפי שנשאלות בישראל. נכון להיום פתוחות אצלנו 52 משרות Node.js ו-44 משרות JavaScript.

מודל הריצה ו-Event Loop

איך פועל ה-event loop ב-Node.js?

Node רץ ב-thread יחיד עם event loop שמעבד callbacks בשלבים (timers, I/O callbacks, poll, check, close). פעולות I/O מועברות ל-libuv הרץ ב-thread pool, וה-callback חוזר לתור כשהן מסתיימות. כך Node לא-חוסם למרות ה-thread היחיד.

מה ההבדל בין microtasks ל-macrotasks?

microtasks (Promises, process.nextTick) רצים אחרי כל פעולה ולפני ה-macrotask הבא. macrotasks כוללים setTimeout ו-I/O callbacks. process.nextTick קודם אפילו ל-Promises, ולכן שימוש מופרז בו עלול להרעיב את ה-event loop.

אם Node חד-תהליכי, איך הוא מטפל בעומס?

ה-I/O לא-חוסם מאפשר לטפל באלפי חיבורים בו-זמנית בעזרת ה-event loop. למקבול עבודה כבדת CPU משתמשים במודול cluster או ב-worker_threads, ובסקיילינג אופקי מול load balancer. Node מצטיין במשימות I/O-bound, ופחות במשימות CPU-bound כבדות.

מה זה worker_threads ומתי משתמשים בו?

worker_threads מריץ קוד JavaScript ב-threads מקבילים אמיתיים עם זיכרון משלהם. משתמשים בו לעבודה כבדת CPU (עיבוד תמונה, הצפנה) כדי לא לחסום את ה-event loop הראשי.

מה ההבדל בין blocking ל-non-blocking code?

קוד חוסם (למשל fs.readFileSync) עוצר את ה-event loop עד לסיום. קוד לא-חוסם (fs.readFile עם callback/Promise) מחזיר שליטה מיד. חסימת ה-event loop פוגעת בכל הבקשות במקביל — טעות קריטית ב-Node.

אסינכרוניות

המודל האסינכרוני הוא ליבת Node. הטבלה מסכמת את התפתחות הגישות:

גישהיתרוןחיסרון
callbackפשוט, ישןcallback hell, טיפול שגיאות מסורבל
Promiseשרשור, then/catchעדיין פחות קריא ברצפים
async/awaitקריא, try/catchקל לשכוח await

מה ההבדל בין callback, Promise ו-async/await?

callback הוא הגישה הישנה שמובילה ל-"callback hell". Promise מייצג ערך עתידי עם then/catch. async/await הוא סוכר תחבירי מעל Promises שמאפשר לכתוב קוד אסינכרוני בסגנון סינכרוני וקריא, עם try/catch לשגיאות.

מה זה callback hell ואיך נמנעים ממנו?

callback hell הוא קינון עמוק של callbacks שמקשה על קריאה וטיפול בשגיאות. נמנעים על ידי Promises, async/await, ופיצול לפונקציות בעלות שם. הקוד הופך שטוח וקל לתחזוקה.

מה ההבדל בין Promise.all ל-Promise.allSettled?

Promise.all נכשל מיד אם אחד ה-Promises נדחה (fail-fast). Promise.allSettled ממתין לכולם ומחזיר את התוצאה של כל אחד (fulfilled/rejected). בוחרים לפי האם כישלון אחד צריך להפיל את הכל.

איך מטפלים בשגיאות בקוד אסינכרוני?

ב-async/await עוטפים ב-try/catch. ב-Promises משתמשים ב-catch. חובה לטפל בכל rejection — unhandled rejection עלול להפיל את התהליך בגרסאות מודרניות. גם EventEmitter דורש טיפול ב-'error'.

מה קורה אם שוכחים await?

הפונקציה מחזירה Promise שלא ממתינים לו — הערך אינו זמין, שגיאות אינן נתפסות, וייתכן race condition. זו טעות נפוצה מאוד; linters מסייעים לזהות אותה.

מה זה race condition ב-Node אם הוא חד-תהליכי?

למרות שהקוד רץ ב-thread יחיד, פעולות אסינכרוניות עלולות להשתלב בסדר לא-צפוי בין await-ים. למשל, שתי בקשות שקוראות ומעדכנות אותו שדה ב-DB עלולות לדרוס זו את זו. הפתרון: אטומיות ברמת ה-DB, נעילות, או תורים.

מה ההבדל בין require ל-import מבחינת טעינה?

require (CommonJS) נטען סינכרונית בזמן ריצה ומאפשר טעינה מותנית. import (ESM) נפתר סטטית לפני ההרצה, מה שמאפשר tree-shaking וניתוח סטטי, אך פחות גמיש בטעינה דינמית (יש import() אסינכרוני לכך).

Streams וקבצים

Streams מונעים התפוצצות זיכרון בהעברות גדולות. ארבעת סוגי ה-stream:

סוגתפקידדוגמה
Readableקריאת נתוניםfs.createReadStream
Writableכתיבת נתוניםfs.createWriteStream
Duplexקריאה וכתיבהTCP socket
Transformעיבוד תוך כדיzlib (דחיסה)

מה זה Stream ולמה הוא חשוב?

Stream מעבד נתונים בחלקים (chunks) במקום לטעון הכל לזיכרון. ארבעה סוגים: Readable, Writable, Duplex, Transform. קריטי לקבצים גדולים ולהעברת נתונים — מונע התפוצצות זיכרון.

מה עושה pipe ולמה משתמשים בו?

pipe מחבר Readable ל-Writable ומעביר נתונים ביניהם עם backpressure אוטומטי — כלומר האטת המקור אם היעד לא מדביק. זה מונע הצטברות נתונים בזיכרון בהעברות גדולות.

מה זה backpressure?

Backpressure הוא מנגנון שמאזן בין קצב הייצור לקצב הצריכה של נתונים. כאשר הצרכן איטי, ה-buffer מתמלא וה-stream מאותת למקור להאט. התעלמות מ-backpressure גורמת לצריכת זיכרון בלתי-מבוקרת.

Express ו-APIs

מה זה middleware ב-Express?

middleware היא פונקציה עם גישה ל-req, res ו-next, שרצה בשרשרת. משתמשים בה ל-logging, אימות, parsing וטיפול בשגיאות. הסדר קובע — middleware של error מוגדר עם ארבעה פרמטרים ומופיע אחרון.

איך מטפלים בשגיאות ב-Express?

עם error-handling middleware בעל ארבעה פרמטרים (err, req, res, next). בקוד אסינכרוני מעבירים שגיאות ל-next(err) או משתמשים ב-wrapper. טיפול מרוכז עדיף על try/catch מפוזר בכל route.

מה ההבדל בין REST ל-GraphQL?

REST חושף משאבים דרך endpoints מרובים; GraphQL חושף schema יחיד שבו הלקוח מבקש בדיוק את השדות שהוא צריך. GraphQL מצמצם over-fetching אך מוסיף מורכבות ב-caching. בוחרים לפי הצורך.

איך מאבטחים REST API ב-Node?

אימות עם JWT או session, הרשאות (authorization), ולידציה של קלט, rate limiting, HTTPS, ו-helmet לכותרות אבטחה. לעולם לא סומכים על קלט הלקוח, ולא מחזירים פרטי שגיאה פנימיים.

מה זה JWT ואיך הוא עובד?

JWT הוא token חתום המכיל claims (למשל מזהה משתמש). השרת מאמת את החתימה ללא צורך במצב בצד השרת. חשוב: לא לשמור מידע רגיש ב-payload (הוא רק מקודד base64), ולהגדיר תפוגה.

אבטחה, ביצועים וכלים

איך מזהים memory leak ב-Node?

מנטרים גידול ב-heap לאורך זמן, לוקחים heap snapshots ב-Chrome DevTools ומשווים. סיבות נפוצות: closures שמחזיקים הפניות, listeners שלא הוסרו, ו-caches שגדלים ללא הגבלה.

איך משפרים ביצועים באפליקציית Node?

הימנעות מחסימת ה-event loop, caching (Redis), pooling של חיבורי DB, דחיסה, streaming לתגובות גדולות, ו-clustering לניצול ליבות. מודדים לפני שמאופטמים — pprof/clinic.js מסייעים.

מה ההבדל בין dependencies ל-devDependencies?

dependencies נדרשות בזמן ריצה בפרודקשן. devDependencies נדרשות רק בפיתוח (טסטים, linters, bundlers). הפרדה נכונה מקטינה את גודל ההתקנה בפרודקשן ואת שטח התקיפה.

מהן נקודות אבטחה נפוצות ב-Node?

הזרקת SQL/NoSQL, XSS, חבילות npm פגיעות, חשיפת סודות בקוד, ו-prototype pollution. מגנים עם ולידציה, ORM/queries מפורמטים, npm audit, ומשתני סביבה לסודות.

מה ההבדל בין CommonJS ל-ES Modules?

CommonJS (require/module.exports) סינכרוני והיסטורי ב-Node. ES Modules (import/export) הם הסטנדרט המודרני, תומכים ב-tree-shaking ו-static analysis. פרויקטים חדשים נוטים ל-ESM, אך יש שיקולי תאימות.

מה זה process.env ולמה חשוב?

process.env נותן גישה למשתני סביבה, שם מאחסנים קונפיגורציה וסודות (מפתחות API, מחרוזות חיבור) מחוץ לקוד. לעולם לא מכניסים סודות ל-repo; משתמשים ב-.env מקומי ובניהול סודות בפרודקשן.

מעשי ומערכתי

איך היית מתכנן שירות Node שמקבל עומס גבוה?

clustering/worker per core מאחורי load balancer, caching, connection pooling, תורים (queue) לעבודה כבדה, ו-graceful shutdown. מנטרים event loop lag כדי לזהות חסימות מוקדם.

איך מבצעים graceful shutdown?

מאזינים ל-SIGTERM, מפסיקים לקבל חיבורים חדשים, מסיימים בקשות פעילות, סוגרים חיבורי DB, ואז יוצאים. חשוב בפריסות container כדי לא לקטוע בקשות באמצע.

איך בודקים קוד Node?

unit tests (Jest/Vitest) ללוגיקה, integration tests ל-APIs (supertest), ומוקים לתלויות חיצוניות. שואפים לבדיקות מהירות ואמינות ולכיסוי הנתיבים הקריטיים, לא לאחוז כיסוי לשמו.

מתי לבחור Node על פני שפה אחרת?

Node מצוין לשירותי I/O-bound, real-time (WebSockets), ו-full-stack JavaScript עם שיתוף קוד בין client ל-server. פחות מתאים ל-CPU-bound כבד. הבחירה נובעת מ-ecosystem, מהירות פיתוח ואחידות שפה.

מה ההבדל בין exec, spawn ו-fork?

ב-child_process: spawn מריץ תהליך עם stream של פלט (מתאים לפלט גדול), exec מריץ פקודה ומחזיר את כל הפלט ל-buffer (מתאים לפלט קטן), ו-fork יוצר תהליך Node חדש עם ערוץ תקשורת IPC. בחירה שגויה עלולה למלא זיכרון.

מה זה EventEmitter?

EventEmitter הוא הבסיס למודל האירועים ב-Node — אובייקטים פולטים אירועים בשם (emit) ומאזינים מגיבים (on). streams ו-HTTP servers בנויים עליו. חובה לטפל באירוע 'error', אחרת התהליך עלול לקרוס.

מה ההבדל בין setImmediate ל-setTimeout(fn, 0)?

setImmediate מריץ callback בשלב ה-check של ה-event loop, מיד אחרי שלב ה-poll. setTimeout(fn,0) מריץ בשלב ה-timers עם עיכוב מינימלי. בתוך I/O callback, setImmediate ירוץ תמיד לפני setTimeout(0).

מתי לבחור במה — טבלת החלטות ל-Node.js

שיקול דעת מערכתי נבדק בראיוני Node לתפקידי backend:

הצורךבחירה מומלצתהסיבה
העברת קובץ גדולStream + pipebackpressure, זיכרון קבוע
עבודה כבדת CPUworker_threadsלא חוסם event loop
כמה קריאות במקבילPromise.allמקבול, קיצור latency
קריאות עצמאיות שאסור להפיל זו את זוPromise.allSettledעמידות לכשל חלקי
סקיילינג לכל הליבותclusterניצול מלא של המעבד

טעויות נפוצות בראיון Node.js

  • לחסום את ה-event loop: קוד סינכרוני כבד או לולאה כבדה פוגעים בכל הבקשות.
  • לשכוח await או לא לטפל ב-rejection: באגים שקטים ו-crashes.
  • לטעון קובץ גדול לזיכרון במקום stream: מוביל למחסור בזיכרון.
  • לחשוב ש-Node מקבילי אמיתי: הוא חד-תהליכי; מקבול דורש workers/cluster.
  • לשמור סודות בקוד: חשיפת מפתחות ב-repo.

מיני-צ'קליסט להכנה לראיון Node.js

  • להסביר event loop, microtasks מול macrotasks.
  • לתרגל async/await, Promise.all/allSettled וטיפול בשגיאות.
  • להבין streams, pipe ו-backpressure.
  • לדעת Express middleware ואבטחת API (JWT, ולידציה).
  • להכיר clustering/worker_threads ופרופיילינג ביצועים.
  • להכין תכנון שירות עומס-גבוה מקצה לקצה.

אם התפקיד גם frontend, ראו את שאלות ראיון Frontend/React, ולרוחב backend את שאלות ראיון Backend. מוכנים? עיינו במשרות Node.js ובכלל המשרות הפתוחות.

שאלות נפוצות

כמה משרות Node.js יש בישראל כרגע?

נכון להיום פתוחות אצלנו ב-HiTakeJob 52 משרות Node.js ו-44 משרות JavaScript. Node נפוץ מאוד בשירותי backend, ב-full-stack עם React, ובמערכות real-time, ולכן הביקוש יציב.

על מה הכי שמים דגש בראיון Node.js?

על הבנת ה-event loop והמודל האסינכרוני, טיפול נכון ב-Promises/async, streams ו-backpressure, ואבטחת API. מראיינים בודקים אם המועמד מבין למה חסימת ה-event loop הרסנית.

האם צריך לדעת Express או framework אחר?

Express הוא הסטנדרט הנפוץ ביותר ולרוב נבדק — middleware, routing וטיפול בשגיאות. היכרות עם NestJS או Fastify יכולה לעזור בחלק מהתפקידים, אך הבנת היסודות של Node חשובה יותר.

האם Node.js מתאים למערכות בעומס גבוה?

כן, למשימות I/O-bound, כשמשלבים clustering, caching ו-connection pooling. למשימות CPU-bound משתמשים ב-worker_threads או בשירות נפרד. Node אינו "איטי" מטבעו — התלות היא בסוג העומס.

מה ההבדל בין ראיון Node לג'וניור לסניור?

לג'וניור: תחביר אסינכרוני, Express בסיסי וטיפול בשגיאות. לסניור: תכנון מערכות בעומס, event loop lag, memory leaks, graceful shutdown, ובחירות ארכיטקטורה מול תורים ו-caching.

מאמרים נוספים

המשרות באתר