dicembre 21, 2025
19 min di lettura

Domande per il Colloquio di Junior Backend Developer (Node.js): Guida Completa

interview
career-advice
job-search
entry-level
Domande per il Colloquio di Junior Backend Developer (Node.js): Guida Completa
MB

Milad Bonakdar

Autore

Padroneggia lo sviluppo backend con Node.js grazie a 35 domande essenziali per il colloquio, che coprono i fondamenti di JavaScript, la programmazione asincrona, Express.js, i database, le API, la sicurezza e altro ancora. Preparazione perfetta per i colloqui da junior backend developer.


Introduzione

Questa guida completa contiene 35 domande per il colloquio, accuratamente selezionate, che coprono i fondamenti dello sviluppo backend con Node.js. Queste sono le domande che gli sviluppatori backend junior incontrano effettivamente nei colloqui. Ogni domanda include una risposta approfondita, una valutazione della rarità e un livello di difficoltà basato sull'analisi di centinaia di colloqui reali di importanti aziende tecnologiche e startup.

Che tu ti stia preparando per il tuo primo ruolo backend o che tu stia passando dallo sviluppo frontend, questa guida copre tutto, dai fondamenti di JavaScript alla progettazione di API, alla gestione di database, alle migliori pratiche di sicurezza e alle strategie di deployment.


Fondamenti di JavaScript (8 domande)

1. Spiega la differenza tra var, let e const in JavaScript

Risposta:

  • var: Scope a livello di funzione, sollevata (hoisted) e inizializzata con undefined, può essere ri-dichiarata nello stesso scope, ampiamente deprecata nel codice moderno
  • let: Scope a livello di blocco, sollevata ma rimane nella Temporal Dead Zone (TDZ) fino alla dichiarazione, non può essere ri-dichiarata nello stesso scope, può essere riassegnata
  • const: Scope a livello di blocco, sollevata ma in TDZ, deve essere inizializzata al momento della dichiarazione, non può essere riassegnata (ma il contenuto di oggetti/array può essere modificato)

Esempio:

// var - scope a livello di funzione
function example() {
  if (true) {
    var x = 1;
  }
  console.log(x); // 1 (accessibile al di fuori del blocco)
}

// let - scope a livello di blocco
if (true) {
  let y = 2;
}
console.log(y); // ReferenceError

// const - non può essere riassegnata
const z = 3;
z = 4; // TypeError

const obj = { name: 'John' };
obj.name = 'Jane'; // OK - modifica della proprietà
obj = {}; // TypeError - non può essere riassegnata

Best practice: Usa const di default, let quando devi riassegnare, non usare mai var nel JavaScript moderno.

Rarità: Comune Difficoltà: Facile


2. Cosa sono le closure e fornisci un esempio pratico in Node.js?

Risposta: Una closure si verifica quando una funzione interna ha accesso alle variabili dello scope della sua funzione esterna (contenitore), anche dopo che la funzione esterna è stata restituita. La funzione interna "si chiude" su queste variabili.

Esempio pratico in Node.js:

// Pattern di fabbrica per middleware
function createAuthMiddleware(secretKey) {
  // secretKey è "chiusa" dalla funzione restituita
  return function(req, res, next) {
    const token = req.headers.authorization;
    if (validateToken(token, secretKey)) {
      next();
    } else {
      res.status(401).json({ error: 'Unauthorized' });
    }
  };
}

// Utilizzo
const authMiddleware = createAuthMiddleware(process.env.JWT_SECRET);
app.use('/api/protected', authMiddleware);

Vantaggi:

  • Privacy dei dati (secretKey non può essere accessibile direttamente)
  • Fabbriche di funzioni
  • Implementazione del pattern modulo
  • Mantenimento dello stato nelle operazioni asincrone

Rarità: Comune Difficoltà: Media


3. Spiega la keyword this e come differisce nelle arrow function

Risposta: this si riferisce al contesto di esecuzione. Il suo valore dipende da COME viene chiamata la funzione.

Funzioni regolari:

const obj = {
  name: "Server",
  greet: function() {
    console.log(this.name); // "Server"
  }
};
obj.greet(); // this = obj

const greet = obj.greet;
greet(); // this = undefined (strict mode) o globale

Arrow function:

const obj = {
  name: "Server",
  greet: () => {
    console.log(this.name); // undefined (scope lessicale)
  }
};
obj.greet(); // this = scope lessicale (scope del modulo in Node.js)

Differenza chiave: Le arrow function non hanno il proprio this - lo ereditano dallo scope contenitore.

Rarità: Comune Difficoltà: Media


4. Cosa sono le Promise e come differiscono dalle callback?

Risposta: Una Promise rappresenta il completamento (o il fallimento) eventuale di un'operazione asincrona.

Pattern callback (callback hell):

getUser(userId, (err, user) => {
  if (err) return handleError(err);
  getPosts(user.id, (err, posts) => {
    if (err) return handleError(err);
    getComments(posts[0].id, (err, comments) => {
      if (err) return handleError(err);
      // Callback annidate - difficili da leggere
    });
  });
});

Pattern Promise:

getUser(userId)
  .then(user => getPosts(user.id))
  .then(posts => getComments(posts[0].id))
  .then(comments => console.log(comments))
  .catch(err => handleError(err));

Vantaggi:

  • Evita la callback hell
  • Migliore gestione degli errori con .catch()
  • Operazioni concatenabili
  • Possibilità di utilizzare Promise.all() per operazioni parallele

Rarità: Comune Difficoltà: Facile-Media


5. Cosa sono async/await e come migliorano la leggibilità del codice?

Risposta: async/await è zucchero sintattico costruito sulle Promise che fa sembrare e comportare il codice asincrono in modo più simile al codice sincrono.

Esempio:

// Con le Promise
function fetchUserData(userId) {
  return fetchUser(userId)
    .then(user => {
      return fetchPosts(user.id)
        .then(posts => {
          return { user, posts };
        });
    })
    .catch(error => console.error(error));
}

// Con async/await (più pulito)
async function fetchUserData(userId) {
  try {
    const user = await fetchUser(userId);
    const posts = await fetchPosts(user.id);
    return { user, posts };
  } catch (error) {
    console.error(error);
  }
}

Punti chiave:

  • La funzione async restituisce sempre una Promise
  • await mette in pausa l'esecuzione finché la Promise non si risolve
  • Usa try/catch per la gestione degli errori
  • Rende più chiare le operazioni sequenziali

Rarità: Comune Difficoltà: Media


6. Spiega il destructuring per oggetti e array

Risposta: Il destructuring estrae valori da array o proprietà da oggetti in variabili distinte.

Destructuring di array:

const [first, second, ...rest] = [1, 2, 3, 4, 5];
// first = 1, second = 2, rest = [3, 4, 5]

// Salta elementi
const [primary, , tertiary] = ['red', 'green', 'blue'];
// primary = 'red', tertiary = 'blue'

Destructuring di oggetti:

const user = { name: 'Alice', age: 25, email: '[email protected]' };

const { name, age, city = 'NYC' } = user;
// name = 'Alice', age = 25, city = 'NYC' (valore predefinito)

// Rinomina le variabili
const { name: userName, age: userAge } = user;

// Destructuring annidato
const { address: { street, zip } } = person;

Parametri di funzione:

function createUser({ name, email, role = 'user' }) {
  // Usa parametri destrutturati
}

Rarità: Comune Difficoltà: Facile-Media


7. Cosa sono lo spread operator e i rest parameters?

Risposta:

Spread operator (...) - Espande gli iterabili:

// Array
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5]; // [1, 2, 3, 4, 5]

// Oggetti (copia superficiale)
const user = { name: 'Alice', age: 25 };
const updatedUser = { ...user, age: 26 }; // Aggiornamento immutabile

// Argomenti di funzione
const numbers = [1, 2, 3];
Math.max(...numbers); // 3

Rest parameters (...) - Raccoglie più elementi:

// Parametri di funzione
function sum(...numbers) {
  return numbers.reduce((a, b) => a + b, 0);
}
sum(1, 2, 3, 4); // 10

// Destructuring di array
const [first, ...remaining] = [1, 2, 3, 4];
// first = 1, remaining = [2, 3, 4]

Differenza chiave: Spread espande, rest raccoglie.

Rarità: Comune Difficoltà: Facile-Media


8. Spiega i metodi comuni degli array: map, filter, reduce, forEach

Risposta:

map - Trasforma ogni elemento, restituisce un nuovo array:

const doubled = [1, 2, 3].map(x => x * 2); // [2, 4, 6]

filter - Mantiene gli elementi che corrispondono alla condizione:

const evens = [1, 2, 3, 4].filter(x => x % 2 === 0); // [2, 4]

reduce - Riduce a un singolo valore:

const sum = [1, 2, 3].reduce((acc, val) => acc + val, 0); // 6
const grouped = users.reduce((acc, user) => {
  acc[user.role] = acc[user.role] || [];
  acc[user.role].push(user);
  return acc;
}, {});

forEach - Itera senza restituire un nuovo array:

[1, 2, 3].forEach(item => console.log(item));

Rarità: Comune Difficoltà: Facile


Fondamenti di Node.js (7 domande)

9. Cos'è Node.js e come differisce dai linguaggi server-side tradizionali?

Risposta: Node.js è un runtime JavaScript costruito sul motore JavaScript V8 di Chrome che consente a JavaScript di essere eseguito sul server-side.

Differenze chiave:

  • Event loop single-threaded: Utilizza un modello I/O non bloccante vs. I/O bloccante multi-threaded
  • Asincrono di default: Le operazioni non bloccano il thread principale
  • JavaScript ovunque: Stesso linguaggio per frontend e backend
  • Ecosistema NPM: Il più grande registro di pacchetti al mondo
  • Esecuzione veloce: Il motore V8 compila JavaScript in codice macchina nativo

Quando usare Node.js:

  • Applicazioni real-time (chat, gaming)
  • Server API
  • Microservizi
  • Applicazioni di streaming di dati
  • Applicazioni I/O-intensive

Quando NON usare:

  • Task CPU-intensive (elaborazione di immagini, codifica video)
  • Applicazioni che richiedono calcoli complessi

Rarità: Comune Difficoltà: Facile-Media


10. Spiega l'Event Loop in Node.js

Risposta: L'Event Loop è il meccanismo che consente a Node.js di eseguire operazioni I/O non bloccanti pur essendo single-threaded.

Come funziona:

  1. Call Stack: Esegue codice sincrono (LIFO)
  2. Node APIs: Gestisce operazioni asincrone (fs, http, timers)
  3. Callback Queue (Macrotasks): Contiene le callback delle Node APIs
  4. Microtask Queue: Contiene le callback delle Promise (priorità più alta)
  5. Event Loop: Sposta i task dalle code alla call stack quando la stack è vuota

Ordine di esecuzione:

console.log('1');

setTimeout(() => console.log('2'), 0);

Promise.resolve().then(() => console.log('3'));

console.log('4');

// Output: 1, 4, 3, 2
// Spiegazione:
// - Il codice sincrono (1, 4) viene eseguito per primo
// - I microtask (Promise) vengono eseguiti prima dei macrotask
// - I macrotask (setTimeout) vengono eseguiti per ultimi

Fasi dell'Event Loop:

  1. Timers (setTimeout, setInterval)
  2. Pending callbacks
  3. Idle, prepare
  4. Poll (recupera nuovi eventi I/O)
  5. Check (callback di setImmediate)
  6. Close callbacks

Rarità: Comune Difficoltà: Difficile


11. Qual è la differenza tra codice bloccante e non bloccante?

Risposta:

Codice bloccante - Interrompe l'esecuzione finché l'operazione non è completata:

// Lettura sincrona del file (blocca)
const fs = require('fs');
const data = fs.readFileSync('file.txt', 'utf8');
console.log(data); // Attende la lettura del file
console.log('Done'); // Esegue dopo la lettura del file

Codice non bloccante - Continua l'esecuzione, gestisce il risultato tramite callback:

// Lettura asincrona del file (non bloccante)
const fs = require('fs');
fs.readFile('file.txt', 'utf8', (err, data) => {
  if (err) throw err;
  console.log(data);
});
console.log('Done'); // Esegue immediatamente, prima che la lettura del file sia completata

Perché il non bloccante è importante:

  • Il server può gestire più richieste contemporaneamente
  • Migliore utilizzo delle risorse
  • Prestazioni migliorate per le operazioni I/O
  • Scalabilità

Rarità: Comune Difficoltà: Facile-Media


12. Cosa sono i moduli di Node.js e come funziona il sistema dei moduli?

Risposta: Node.js utilizza il sistema dei moduli CommonJS (anche se i moduli ES sono supportati).

CommonJS (require/module.exports):

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

module.exports = { add };
// oppure
exports.add = add;

// app.js
const { add } = require('./math');
const result = add(2, 3);

Moduli ES (import/export):

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

// app.js
import { add } from './math.js';

Tipi di modulo:

  • Moduli core: Built-in (fs, http, path)
  • Moduli locali: I tuoi file
  • Moduli di terze parti: Installati tramite npm

Caching dei moduli: I moduli vengono memorizzati nella cache dopo il primo require, quindi i successivi require restituiscono la stessa istanza.

Rarità: Comune Difficoltà: Facile


13. Spiega la differenza tra process.nextTick() e setImmediate()

Risposta:

process.nextTick() - Esegue la callback nella fase corrente, prima di qualsiasi altra operazione asincrona:

console.log('1');

process.nextTick(() => {
  console.log('2');
});

Promise.resolve().then(() => {
  console.log('3');
});

console.log('4');

// Output: 1, 4, 2, 3
// nextTick ha la priorità più alta, anche sopra le Promise

setImmediate() - Esegue la callback nella prossima iterazione dell'event loop:

console.log('1');

setImmediate(() => {
  console.log('2');
});

setTimeout(() => {
  console.log('3');
}, 0);

console.log('4');

// Output: 1, 4, 3, 2 (o 1, 4, 2, 3 a seconda del contesto)

Ordine di priorità:

  1. Codice sincrono
  2. Callback di process.nextTick()
  3. Callback di Promise (microtask)
  4. setTimeout(0) / setImmediate() (macrotask)

Casi d'uso:

  • nextTick: Assicura che la callback venga eseguita prima di altre operazioni asincrone
  • setImmediate: Rimanda l'esecuzione alla prossima iterazione dell'event loop

Rarità: Non comune Difficoltà: Media-Difficile


14. Cos'è l'oggetto Global in Node.js?

Risposta: L'oggetto global in Node.js è simile all'oggetto window nei browser, ma si chiama global.

Proprietà globali:

// Disponibili ovunque senza require
console.log(__dirname); // Percorso della directory corrente
console.log(__filename); // Percorso del file corrente
console.log(process); // Oggetto processo
console.log(global); // Oggetto global stesso

Global comuni:

  • process - Informazioni e controllo del processo
  • Buffer - Gestisce i dati binari
  • setTimeout, setInterval, clearTimeout, clearInterval
  • setImmediate, clearImmediate
  • console - Output della console

Nota: Nei moduli ES, __dirname e __filename non sono disponibili di default. Utilizza invece import.meta.url.

Rarità: Comune Difficoltà: Facile


15. Come gestisci gli errori nelle applicazioni Node.js?

Risposta: La gestione degli errori in Node.js può essere gestita attraverso diversi approcci:

1. Try-catch per codice sincrono:

try {
  const data = fs.readFileSync('file.txt', 'utf8');
} catch (error) {
  console.error('Errore durante la lettura del file:', error.message);
}

2. Pattern di errore callback:

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

3. Gestione degli errori di Promise:

fetchData()
  .then(data => processData(data))
  .catch(error => console.error('Errore:', error));

4. Async/await con try-catch:

async function handleRequest() {
  try {
    const data = await fetchData();
    return data;
  } catch (error) {
    console.error('Errore:', error);
    throw error; // Rilancia se necessario
  }
}

5. Gestori di errori globali:

// Eccezioni non gestite
process.on('uncaughtException', (error) => {
  console.error('Eccezione non gestita:', error);
  process.exit(1);
});

// Rifiuti di promise non gestiti
process.on('unhandledRejection', (reason, promise) => {
  console.error('Rifiuto non gestito:', reason);
});

6. Middleware per la gestione degli errori in Express:

app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).json({ error: 'Qualcosa è andato storto!' });
});

Rarità: Comune Difficoltà: Media


Express.js e Web Frameworks (6 domande)

16. Cos'è Express.js e quali sono le sue caratteristiche principali?

Risposta: Express.js è un framework per applicazioni web Node.js minimale e flessibile che fornisce un robusto set di funzionalità per la creazione di applicazioni web e mobile.

Caratteristiche principali:

  • Routing: Definisci endpoint e metodi HTTP
  • Middleware: Funzioni che vengono eseguite durante il ciclo richiesta-risposta
  • Template engines: Renderizza HTML dinamico (EJS, Pug, Handlebars)
  • Gestione degli errori: Middleware centralizzato per la gestione degli errori
  • File statici: Serve asset statici
  • Parsing JSON: Parsing del body integrato per dati JSON e URL-encoded

Esempio base:

const express = require('express');
const app = express();

app.use(express.json());

app.get('/', (req, res) => {
  res.json({ message: 'Ciao Mondo' });
});

app.listen(3000, () => {
  console.log('Server in esecuzione sulla porta 3000');
});

Perché Express:

  • Minimo e non vincolante
  • Ampio ecosistema
  • Facile da imparare
  • Sistema di middleware flessibile

Rarità: Comune Difficoltà: Facile


17. Cosa sono i middleware in Express.js? Fornisci esempi.

Risposta: Le funzioni middleware sono funzioni che hanno accesso all'oggetto request (req), all'oggetto response (res) e alla funzione next nel ciclo richiesta-risposta dell'applicazione.

Tipi di middleware:

1. Middleware a livello di applicazione:

app.use((req, res, next) => {
  console.log('Richiesta ricevuta:', req.method, req.path);
  next(); // Passa il controllo al middleware successivo
});

2. Middleware a livello di route:

app.get('/users', authenticateUser, (req, res) => {
  res.json({ users: [] });
});

3. Middleware per la gestione degli errori:

app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).json({ error: err.message });
});

4. Middleware integrati:

app.use(express.json()); // Parse i body JSON
app.use(express.urlencoded({ extended: true })); // Parse URL-encoded
app.use(express.static('public')); // Serve i file statici

5. Middleware di terze parti:

const cors = require('cors');
const helmet = require('helmet');

app.use(cors());
app.use(helmet());

Esempio di middleware di autenticazione personalizzato:

function authenticateUser(req, res, next) {
  const token = req.headers.authorization;
  if (!token) {
    return res.status(401).json({ error: 'Nessun token fornito' });
  }
  // Verifica il token
  req.user = decodedToken;
  next();
}

Rarità: Comune Difficoltà: Media


18. Spiega il routing di Express e come organizzare le rotte

Risposta: Il routing si riferisce a come gli endpoint (URI) di un'applicazione rispondono alle richieste del client.

Routing di base:

app.get('/users', (req, res) => {
  res.json({ users: [] });
});

app.post('/users', (req, res) => {
  const newUser = req.body;
  res.status(201).json(newUser);
});

app.get('/users/:id', (req, res) => {
  const userId = req.params.id;
  res.json({ user: { id: userId } });
});

app.put('/users/:id', (req, res) => {
  // Aggiorna l'utente
});

app.delete('/users/:id', (req, res) => {
  // Elimina l'utente
});

Parametri di route:

app.get('/users/:userId/posts/:postId', (req, res) => {
  const { userId, postId } = req.params;
  // Accedi ai parametri di route
});

Parametri di query:

app.get('/search', (req, res) => {
  const { q, page, limit } = req.query;
  // ?q=nodejs&page=1&limit=10
});

Organizzare le rotte con Express Router:

// routes/users.js
const express = require('express');
const router = express.Router();

router.get('/', (req, res) => {
  res.json({ users: [] });
});

router.get('/:id', (req, res) => {
  res.json({ user: { id: req.params.id } });
});

module.exports = router;

// app.js
const userRoutes = require('./routes/users');
app.use('/api/users', userRoutes);

Rarità: Comune Difficoltà: Facile-Media


19. Come gestisci l'upload di file in Express?

Risposta: L'upload di file può essere gestito utilizzando middleware come multer.

Upload di file di base:

const multer = require('multer');
const upload = multer({ dest: 'uploads/' });

app.post('/upload', upload.single('file'), (req, res) => {
  // req.file contiene le informazioni sul file
  res.json({
    filename: req.file.filename,
    originalname: req.file.originalname,
    size: req.file.size
  });
});

File multipli:

app.post('/upload-multiple', upload.array('files', 10), (req, res) => {
  // req.files è un array di file
  res.json({ uploaded: req.files.length });
});

Configurazione personalizzata dello storage:

const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, 'uploads/');
  },
  filename: (req, file, cb) => {
    const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
    cb(null, file.fieldname + '-' + uniqueSuffix);
  }
});

const upload = multer({
  storage: storage,
  limits: { fileSize: 5 * 1024 * 1024 }, // Limite di 5MB
  fileFilter: (req, file, cb) => {
    if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') {
      cb(null, true);
    } else {
      cb(new Error('Sono ammessi solo JPEG e PNG'));
    }
  }
});

Rarità: Comune Difficoltà: Media


20. Cos'è CORS e come lo gestisci in Express?

Risposta: CORS (Cross-Origin Resource Sharing) è una funzionalità di sicurezza che consente o limita le pagine web dall'effettuare richieste a un dominio diverso da quello che serve la pagina web.

Problema: I browser bloccano le richieste da http://localhost:3000 a http://localhost:4000 di default (origini diverse).

Soluzione con il middleware cors:

const cors = require('cors');

// Consenti tutte le origini (solo sviluppo)
app.use(cors());

// Configura origini specifiche
app.use(cors({
  origin: 'https://example.com',
  methods: ['GET', 'POST', 'PUT', 'DELETE'],
  allowedHeaders: ['Content-Type', 'Authorization']
}));

// Origini multiple
app.use(cors({
  origin: ['https://example.com', 'https://app.example.com']
}));

Header CORS manuali:

app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', 'https://example.com');
  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
  res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');

  if (req.method === 'OPTIONS') {
    return res.sendStatus(200);
  }
  next();
});

Rarità: Comune Difficoltà: Facile-Media


21. Come strutturi un'applicazione Express.js di grandi dimensioni?

Risposta: Organizza il codice in moduli e cartelle logiche per la manutenibilità.

Struttura raccomandata:

project/
├── src/
│   ├── controllers/
│   │   └── userController.js
│   ├── models/
│   │   └── User.js
│   ├── routes/
│   │   └── userRoutes.js
│   ├── middleware/
│   │   └── auth.js
│   ├── services/
│   │   └── userService.js
│   ├── utils/
│   │   └── helpers.js
│   ├── config/
│   │   └── database.js
│   └── app.js
├── tests/
├── .env
└── package.json

Esempio di separazione delle preoccupazioni:

Controller (gestisce HTTP):

// controllers/userController.js
const userService = require('../services/userService');

exports.getUsers = async (req, res, next) => {
  try {
    const users = await userService.getAllUsers();
    res.json(users);
  } catch (error) {
    next(error);
  }
};

Service (logica di business):

// services/userService.js
const User = require('../models/User');

exports.getAllUsers = async () => {
  return await User.find();
};

Route:

// routes/userRoutes.js
const express = require('express');
const router = express.Router();
const userController = require('../controllers/userController');

router.get('/', userController.getUsers);
router.post('/', userController.createUser);

module.exports = router;

Setup dell'app:

// app.js
const express = require('express');
const userRoutes = require('./routes/userRoutes');

const app = express();
app.use(express.json());
app.use('/api/users', userRoutes);

Rarità: Comune Difficoltà: Media


Concetti di Database (5 domande)

22. Qual è la differenza tra database SQL e NoSQL?

Risposta:

Database SQL (Relazionali):

  • Dati strutturati con tabelle, righe, colonne
  • Lo schema deve essere definito prima dell'uso
  • Conformità ACID (Atomicità, Coerenza, Isolamento, Durabilità)
  • Esempi: PostgreSQL, MySQL, SQLite
  • Ottimo per: Query complesse, transazioni, dati strutturati

Database NoSQL:

  • Schema flessibile o schema-less
  • Vari modelli di dati (documento, chiave-valore, grafo, colonna)
  • Scalabilità orizzontale
  • Esempi: MongoDB, Redis, Cassandra
  • Ottimo per: Applicazioni su larga scala, schemi flessibili, sviluppo rapido

Comparazione:

CaratteristicaSQLNoSQL
SchemaFissoFlessibile
ScalabilitàVerticaleOrizzontale
ACIDVaria
Linguaggio di querySQLVaria
RelazioniJoinIncorporato/Riferimenti

Quando usare SQL:

  • Query e relazioni complesse
  • Conformità ACID richiesta
  • Dati strutturati
  • Transazioni finanziarie

Quando usare NoSQL:

  • Sviluppo rapido
  • Dati su larga scala
  • Necessità di schema flessibile
  • Query semplici

Rarità: Comune Difficoltà: Facile-Media


23. Come ti connetti a un database in Node.js? (Esempio MongoDB)

Risposta: Utilizzando MongoDB con Mongoose come esempio:

Connessione di base:

const mongoose = require('mongoose');

// Stringa di connessione
const mongoURI = 'mongodb://localhost:27017/mydb';

// Connetti
mongoose.connect(mongoURI, {
  useNewUrlParser: true,
  useUnifiedTopology: true
})
.then(() => console.log('MongoDB connesso'))
.catch(err => console.error('Errore di connessione:', err));

Con variabili d'ambiente:

require('dotenv').config();

mongoose.connect(process.env.MONGODB_URI, {
  useNewUrlParser: true,
  useUnifiedTopology: true
});

Eventi di connessione:

mongoose.connection.on('connected', () => {
  console.log('Mongoose connesso a MongoDB');
});

mongoose.connection.on('error', (err) => {
  console.error('Errore di connessione Mongoose:', err);
});

mongoose.connection.on('disconnected', () => {
  console.log('Mongoose disconnesso');
});

Definizione di un modello:

const userSchema = new mongoose.Schema({
  name: { type: String, required: true },
  email: { type: String, required: true, unique: true },
  age: { type: Number, min: 0 }
}, { timestamps: true });

const User = mongoose
Newsletter subscription

Consigli di carriera settimanali che funzionano davvero

Ricevi le ultime idee direttamente nella tua casella di posta

Decorative doodle

Distinguiti dai Reclutatori e Ottieni il Lavoro dei Tuoi Sogni

Unisciti a migliaia di persone che hanno trasformato la loro carriera con curriculum potenziati dall'IA che superano l'ATS e impressionano i responsabili delle assunzioni.

Inizia a creare ora

Condividi questo post

Riduci il Tempo di Scrittura del Curriculum del 90%

La persona in cerca di lavoro media impiega più di 3 ore per formattare un curriculum. La nostra IA lo fa in meno di 15 minuti, portandoti alla fase di candidatura 12 volte più velocemente.