Priprema za Node.js backend intervju

Node.js pitanja i odgovori za intervju 2026

Fokusirana kolekcija Node.js pitanja za backend intervjue. Koristite svaki odgovor kao strukturu za usmenu vežbu: koncept, primer i trade-offs.

Započni Node.js mock intervjuKreditna kartica nije potrebna. Dostupna je 1 besplatna sesija.
Vežba tehničkog intervjua na engleskomRežim u kome kandidati kojima engleski nije maternji mogu da vežbaju tehničke intervjue.

Architecture and Event Loop

1Šta je Node.js i za šta se koristi?

Node.js je JavaScript izvršno okruženje van veb pregledača, izgrađeno na V8 endžinu i prošireno API-jima za rad sa mrežom, fajlovima, procesima, tokovima podataka (streams) i operativnim sistemom. Najčešće se koristi za REST API (Application Programming Interface) servise, GraphQL servise, WebSocket servere u realnom vremenu, mikroservise, CLI alate, proksije i API mrežne prolaze (API gateways). Njegova glavna prednost je neblokirajući I/O: jedan proces može efikasno da opslužuje veliki broj mrežnih konekcija. Kompromis je u tome što dugotrajna, računarski zahtevna izračunavanja mogu blokirati petlju događaja ukoliko se ne prebace na radne niti (workers), zasebne procese ili drugi servis.

Pokušajte da odgovorite na ovo pitanje sa AI trenerom

2Kako Node.js funkcioniše interno?

JavaScript se izvršava u V8 motoru, dok Node.js API-ji delegiraju asinhroni rad operativnom sistemu ili libuv skupu niti. Glavna JavaScript nit ne čeka završetak I/O operacije; ona nastavlja sa izvršavanjem drugog koda. Kada se operacija završi, njen povratni poziv ili nastavak Promise objekta postaje spreman za petlju događaja. Na taj način Node.js postiže visoku konkurentnost iako se korisnički JavaScript obično izvršava na jednoj glavnoj niti.

Pokušajte da odgovorite na ovo pitanje sa AI trenerom

3Šta su V8, libuv i petlja događaja?

V8 kompajlira i izvršava JavaScript i upravlja JavaScript objektima i memorijom. `libuv` obezbeđuje međuplatformsku petlju događaja, integraciju asinhronog U/I (I/O) i skup radnih niti za operacije kao što su pojedini poslovi sa fajl sistemom, DNS i kriptografija. Petlja događaja odlučuje kada treba da se izvrše povratni pozivi završenih operacija. Sam Node.js povezuje JavaScript API-je sa izvornim mogućnostima sistema; V8 sam po sebi ne obezbeđuje HTTP server, pristup fajl sistemu niti procesne API-je.

Pokušajte da odgovorite na ovo pitanje sa AI trenerom

4Zašto se za Node.js često kaže da je jedno-nitni (single-threaded)?

Jedan Node.js proces obično izvršava korisnički JavaScript na jednoj glavnoj niti, tako da dve uobičajene funkcije za obradu zahteva ne izvršavaju JavaScript u potpuno isto vreme na toj niti. Međutim, platforma se doslovno ne sastoji od samo jedne niti: libuv ima skup niti, operativni sistem obavlja asinhroni I/O (Input/Output), V8 ima zadatke sakupljanja smeća, a Node.js takođe podržava `worker_threads` i potprocese. Ova fraza uglavnom opisuje podrazumevani model izvršavanja JavaScript-a.

Pokušajte da odgovorite na ovo pitanje sa AI trenerom

5Kako Node.js može konkurentno da obrađuje veliki broj zahteva?

Node.js pokreće U/I operacije i zatim se vraća u petlju događaja umesto da blokira po jednu nit za svaki zahtev. Na primer, 1.000 poziva ka bazi podataka može biti u toku dok glavna nit nastavlja da prihvata nove konekcije i obrađuje prispele povratne pozive. Ovo odlično funkcioniše za poslove ograničene U/I operacijama kao što su HTTP pozivi, upiti ka bazi podataka, rad sa datotekama i soketima. Međutim, funkcioniše loše kada funkcije za obradu zahteva obavljaju težak sinhroni rad na procesoru, jer to blokira petlju događaja i odlaže obradu svih ostalih zahteva.

Pokušajte da odgovorite na ovo pitanje sa AI trenerom

6Koje su glavne faze Node.js petlje događaja?

libuv petlja događaja obuhvata faze kao što su timers, pending callbacks, idle/prepare, poll, check i close callbacks. Faza timers izvršava setTimeout i setInterval povratne pozive; poll obrađuje mnoge I/O događaje; check pokreće setImmediate povratne pozive; close obrađuje događaje zatvaranja kao što je zatvaranje soketa. Node.js takođe ima redove mikrozadataka, uključujući process.nextTick i Promise mikrozadatke, koji se izvršavaju između povratnih poziva. Preveliki broj mikrozadataka može uskratiti resurse I/O operacijama i učiniti da servis deluje blokirano.

Pokušajte da odgovorite na ovo pitanje sa AI trenerom

7Kako se razlikuju sinhrone, asinhrone i neblokirajuće operacije?

Sinhrona operacija se završava pre nego što se izvrši sledeća linija koda i blokira glavnu nit, kao što je fs.readFileSync u funkciji za obradu zahteva. Asinhrona operacija vraća svoj rezultat kasnije putem povratnog poziva (callback) ili Promise objekta. Neblokirajuće znači da nit može nastaviti sa obavljanjem drugog posla dok je operacija na čekanju. Ovi pojmovi su povezani, ali nisu identični: asinhrono opisuje kako se rezultat isporučuje, dok neblokirajuće opisuje da li nit čeka. Funkcije za obradu zahteva na backend-u bi uglavnom trebalo da preferiraju asinhrone neblokirajuće API-je.

import fs from 'node:fs';

const syncData = fs.readFileSync('file.txt', 'utf8');

const asyncData = await fs.promises.readFile(
  'file.txt',
  'utf8'
);
Pokušajte da odgovorite na ovo pitanje sa AI trenerom

8Šta je izgladnjivanje petlje događaja (event loop starvation)?

Izgladnjivanje petlje događaja nastaje kada JavaScript zadaci ili mikrozadaci drže petlju događaja zauzetom, tako da ona ne može blagovremeno da obradi ulazno/izlazne operacije, tajmere ili nove zahteve. Uobičajeni uzroci uključuju teška sinhrona izračunavanja, obradu ogromnih JSON struktura, neograničene lance Promise objekata i prekomernu upotrebu process.nextTick. Rešenja uključuju podelu posla na manje delove, ograničavanje veličine ulaznih podataka, profajlisanje procesora, prebacivanje poslova zahtevnih za procesor na worker_threads ili drugi servis, kao i izbegavanje sinhronih API-ja u delovima koda kritičnim za obradu zahteva.

app.get('/report', (req, res) => {
  const result = performVeryHeavyCalculation();
  res.json(result);
});
Pokušajte da odgovorite na ovo pitanje sa AI trenerom

Async Programming and Errors

9Šta je povratni poziv (callback) i šta je callback hell?

Povratni poziv (callback) je funkcija koja se prosleđuje kako bi se izvršila kasnije, najčešće nakon što se asinhrona operacija završi. Klasični Node.js povratni pozivi obično prate stil u kom je greška prvi argument: `callback(error, result)`. Callback hell nastaje kada su zavisne operacije duboko ugnježdene, što otežava obradu grešaka i praćenje toka izvršavanja. Rešenje je dekompozicija koda na imenovane funkcije, korišćenje `Promise` objekata ili `async/await` sintakse, kao i pokretanje nezavisnih operacija pomoću `Promise.all` umesto njihovog ugnježđivanja.

import fs from 'node:fs';

fs.readFile('file.txt', 'utf8', (err, data) => {
  if (err) {
    console.error(err);
    return;
  }

  console.log(data);
});
Pokušajte da odgovorite na ovo pitanje sa AI trenerom

10Šta je Promise i kako funkcioniše async/await?

Promise predstavlja budući rezultat asinhrone operacije i može biti u stanju čekanja (pending), ispunjen (fulfilled) ili odbijen (rejected). `async` funkcija uvek vraća Promise. `await` pauzira samo trenutnu `async` funkciju dok se Promise ne razreši; on ne blokira ceo Node.js proces. Dobar odgovor treba da obuhvati obradu grešaka pomoću `try/catch`, izbegavanje neobrađenih (floating) Promise objekata i korišćenje `Promise.all` za nezavisne zadatke kako se operacije ne bi izvršavale nepotrebno sekvencijalno.

async function loadUser(id) {
  try {
    const user = await repository.findById(id);
    return user;
  } catch (error) {
    console.error(error);
    throw error;
  }
}

const [user, settings] = await Promise.all([
  getUser(),
  getSettings()
]);
Pokušajte da odgovorite na ovo pitanje sa AI trenerom

11Kako se razlikuju process.nextTick, queueMicrotask, setImmediate i setTimeout?

`process.nextTick` se izvršava nakon trenutne operacije i pre nego što petlja događaja pređe na sledeći korak. `queueMicrotask` raspoređuje standardni JavaScript mikrozadatak, slično nastavcima za `Promise`. `setImmediate` se izvršava u fazi `check`. `setTimeout(fn, 0)` se izvršava u fazi `timers` nakon minimalnog kašnjenja. Obično se `nextTick` izvršava pre `Promise` mikrozadataka, a redosled između `setTimeout(0)` i `setImmediate` zavisi od konteksta; nakon I/O (Input/Output) povratnih poziva, `setImmediate` se često izvršava prvi.

setTimeout(() => console.log('timeout'), 0);
setImmediate(() => console.log('immediate'));
Promise.resolve().then(() => console.log('promise'));
process.nextTick(() => console.log('nextTick'));
Pokušajte da odgovorite na ovo pitanje sa AI trenerom

12Kako treba obrađivati greške u Node.js-u?

Sinhroni kod koristi `try/catch`. Kod zasnovan na `Promise` objektima treba da koristi `await` unutar `try/catch` bloka ili da veže `.catch`. Povratni pozivi koji primaju grešku kao prvi argument (error-first callbacks) treba da provere argument greške pre korišćenja rezultata. U serverskim aplikacijama važni su centralni posrednički softver za obradu grešaka (error middleware), logovanje sa kontekstom zahteva, bezbedne poruke za klijente i kontrolisano gašenje aplikacije. Događaj `uncaughtException` ne treba koristiti da bi se oštećeni proces održao u radu; to je obično signal za evidentiranje u log, oslobađanje resursa i ponovno pokretanje.

try {
  JSON.parse(input);
} catch (error) {
  handleError(error);
}

try {
  await operation();
} catch (error) {
  handleError(error);
}

operation((error, result) => {
  if (error) return handleError(error);
  return result;
});
Pokušajte da odgovorite na ovo pitanje sa AI trenerom

Modules and Project Management

13Šta su moduli u Node.js-u?

Modul je izolovana jedinica koda sa eksplicitnim izvezenim interfejsom. Node.js podržava ugrađene module kao što su node:fs i node:http, lokalne projektne module, npm pakete, CommonJS module i ECMAScript module. Moduli čine granice odgovornosti jasnijim i omogućavaju ponovno korišćenje koda. Kompromis u produkciji jeste međusobna zavisnost: ako moduli previše duboko uvoze jedan drugog ili skrivaju propratne efekte u trenutku uvoza, ponašanje pri pokretanju i testiranje postaju znatno teži za razumevanje.

// math.js
export function add(a, b) {
  return a + b;
}

// app.js
import { add } from './math.js';
Pokušajte da odgovorite na ovo pitanje sa AI trenerom

14Kako se razlikuju CommonJS require i ES Modules (ECMAScript Modules) import?

CommonJS koristi require i module.exports, dok ES Modules koriste import i export. ES Modules podržavaju statičku analizu i top-level await, a biraju se kroz type: module u package.json datoteci ili putem datoteka sa .mjs ekstenzijom. CommonJS se često učitava sinhrono i može se označiti pomoću .cjs. U savremenim Node.js projektima postoje oba sistema, pa dobar odgovor izbegava preterano pojednostavljivanje i objašnjava da ekstenzija datoteke, package.json i kontekst projekta određuju režim rada modula.

// CommonJS
const fs = require('node:fs');
module.exports = { calculate };

// ES Modules
import fs from 'node:fs';
export { calculate };
Pokušajte da odgovorite na ovo pitanje sa AI trenerom

15Šta su npm, package.json i package-lock.json?

npm je menadžer paketa i CLI (Command Line Interface) alat. package.json opisuje skripte, metapodatke, zavisnosti (dependencies) i razvojne zavisnosti (devDependencies). package-lock.json beleži tačno stablo zavisnosti kako bi instalacije bile ponovljive. U CI (Continuous Integration) okruženju obično se preferira npm ci jer vrši instalaciju striktno iz lock datoteke i prekida rad ako se package.json i lock datoteka ne poklapaju. Ovo štiti proces izgradnje od neočekivanih promena u verzijama zavisnosti.

{
  "name": "api",
  "type": "module",
  "scripts": {
    "start": "node src/server.js",
    "test": "node --test"
  },
  "dependencies": {},
  "devDependencies": {}
}
Pokušajte da odgovorite na ovo pitanje sa AI trenerom

16Kako treba upravljati konfiguracijom i promenljivama okruženja?

Node.js čita promenljive okruženja kroz process.env, ali su te vrednosti tekstualne (stringovi) i treba ih validirati i konvertovati prilikom pokretanja. Tajne ne treba čuvati u repozitorijumu, .env fajl treba ignorisati, a produkcione tajne treba da dolaze sa platforme ili iz servisa za upravljanje tajnama. Dobri servisi rano prijavljuju grešku i prekidaju rad kada nedostaje obavezna konfiguracija. NODE_ENV je konvencija, a ne bezbednosna granica, pa se kôd ne sme oslanjati na nju kao na zaštićeni mehanizam.

const port = Number(process.env.PORT ?? 3000);
const databaseUrl = process.env.DATABASE_URL;

if (!databaseUrl) {
  throw new Error('DATABASE_URL is required');
}
Pokušajte da odgovorite na ovo pitanje sa AI trenerom

Events, Buffers and Streams

17Šta je EventEmitter?

EventEmitter implementira obrazac objavljivanja i pretplate (publish-subscribe) unutar Node.js procesa. Metoda on registruje osluškivač, once registruje osluškivač za jedan događaj, off uklanja osluškivač, a emit sinhrono poziva osluškivače po redosledu registracije. Sinhrona priroda je važna: spor osluškivač blokira emiter. Događaj error je poseban jer neobrađeni error događaj može srušiti proces. Dugotrajni sistemi takođe treba da uklanjaju nekorišćene osluškivače kako bi se izbeglo curenje memorije.

import { EventEmitter } from 'node:events';

const emitter = new EventEmitter();

emitter.on('orderCreated', order => {
  console.log(`Order ${order.id} created`);
});

emitter.emit('orderCreated', { id: 42 });
Pokušajte da odgovorite na ovo pitanje sa AI trenerom

18Za šta se koristi Buffer u Node.js-u?

Buffer predstavlja sekvencu bajtova fiksne veličine. Koristi se za rad sa fajlovima, TCP soketima, telima HTTP zahteva i odgovora, slikama, kriptografijom i binarnim protokolima. Buffer.from kreira bafer iz postojećih podataka, Buffer.alloc stvara memoriju popunjenu nulama, a Buffer.allocUnsafe je brži, ali može sadržati stare memorijske podatke dok se ne prepiše. To čini allocUnsafe pogodnim samo kada kod odmah popunjava bafer i ne izlaže zaostale podatke.

const buffer = Buffer.from('Hello', 'utf8');

console.log(buffer);
console.log(buffer.toString('utf8'));

const safe = Buffer.alloc(1024);
const fast = Buffer.allocUnsafe(1024);
Pokušajte da odgovorite na ovo pitanje sa AI trenerom

19Šta su tokovi podataka (streams) i koje vrste postoje?

Tokovi podataka obrađuju podatke u delovima umesto učitavanja celokupnog sadržaja u memoriju. Glavni tipovi su `Readable`, `Writable`, `Duplex` i `Transform`. Datoteke, objekti HTTP zahteva i odgovora, TCP utičnice i gzip tokovi su česti primeri. Tokovi su dragoceni za velike datoteke i mrežni saobraćaj jer smanjuju upotrebu memorije i kašnjenje. Odgovor na nivou produkcije treba da napomene da greške u tokovima moraju biti ispravno obrađene duž celog lanca.

import fs from 'node:fs';

const input = fs.createReadStream('large.log');
const output = fs.createWriteStream('copy.log');

input.pipe(output);
Pokušajte da odgovorite na ovo pitanje sa AI trenerom

20Šta je povratni pritisak (backpressure) i zašto je pipeline koristan?

Povratni pritisak nastaje kada izvor podataka proizvodi delove brže nego što odredište može da ih obradi. Bez kontrole povratnog pritiska, potrošnja memorije može nekontrolisano rasti sve dok proces ne uspori ili se ne sruši. Tokovi podataka (streams) i funkcija `pipe` mogu koordinisati protok, ali je funkcija `pipeline` iz modula `node:stream/promises` bezbednija za višestepene lance jer propagira greške, zatvara povezane tokove i vraća `Promise`. Ona predstavlja odličan podrazumevani izbor za kompresiju datoteka, otpremanje, preuzimanje i transformacije tokova podataka.

import fs from 'node:fs';
import zlib from 'node:zlib';
import { pipeline } from 'node:stream/promises';

await pipeline(
  fs.createReadStream('input.txt'),
  zlib.createGzip(),
  fs.createWriteStream('input.txt.gz')
);
Pokušajte da odgovorite na ovo pitanje sa AI trenerom