Nouveau : Datasets open source gratuits disponibles !Decouvrir →
💼
entretiens 28 entrees

Entretien technique Node.js

Découvrez notre cheatsheet complète sur l'entretien technique Node.js : des conseils pratiques pour réussir votre interview !

Voici la cheatsheet d'entretien technique Node.js en français :

Questions théoriques fréquentes

Q: Qu'est-ce que Node.js ?

Node.js est un environnement d'exécution JavaScript côté serveur construit sur le moteur V8 de Chrome. Il permet d'écrire des applications asynchrones et événementielles, ce qui lui donne une performance élevée.

const http = require('http');

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World\n');
});

server.listen(3000, () => {
  console.log('Server running at http://localhost:3000/');
});

Q: Différences entre callback et promesse en Node.js ?

  • Callback : Fonction passée en paramètre d'une autre fonction pour être exécutée à un moment donné.
  • Promesse : Objet représentant une valeur qui peut être disponible maintenant, dans le futur ou jamais.
// Callback
fs.readFile('file.txt', 'utf8', (err, data) => {
  if (err) throw err;
  console.log(data);
});

// Promesse
const readFilePromise = new Promise((resolve, reject) => {
  fs.readFile('file.txt', 'utf8', (err, data) => {
    if (err) reject(err);
    resolve(data);
  });
});

readFilePromise.then(data => console.log(data)).catch(err => console.error(err));

Q: Que sont les modules en Node.js ?

Les modules sont des fichiers contenant du code JavaScript. Ils permettent de structurer le code et de réutiliser du code entre différents fichiers.

// math.js
module.exports = {
  add: (a, b) => a + b,
  subtract: (a, b) => a - b
};

// app.js
const math = require('./math');
console.log(math.add(5, 3)); // Output : 8

Q: Explication de la fonction setTimeout et setInterval en Node.js ?

  • setTimeout : Exécute une fonction après un certain délai.
  • setInterval : Exécute une fonction à intervalles réguliers.
setTimeout(() => {
  console.log('Exécuté une fois');
}, 2000);

setInterval(() => {
  console.log('Exécuté toutes les secondes');
}, 1000);

Q: Qu'est-ce que process en Node.js ?

Le module process fournit des informations et des outils sur le processus courant node.js. Il est accessible de n'importe où dans le code.

console.log(process.argv); // Affiche les arguments de la ligne de commande

Q: Explication de require et import en Node.js ?

  • require : Importe des modules CommonJS.
  • import : Importe des modules ES6 (nécessite un fichier package.json avec "type": "module").
// CommonJS
const math = require('./math');

// ES6
import math from './math.js';

Q: Qu'est-ce que les middlewares en Express ?

Les middlewares sont des fonctions qui ont accès à l'objet de requête (req), à l'objet de réponse (res) et à la chaîne de middlewares suivante dans le cycle de traitement de la requête. Ils peuvent exécuter du code, modifier les objets req et res, terminer le cycle de requête-réponse, ou appeler le middleware suivant.

app.use((req, res, next) => {
  console.log('Middleware');
  next();
});

Q: Que sont les streams en Node.js ?

Les streams représentent la transmission continue de données. Ils permettent d'optimiser l'utilisation des ressources en traitant les données de manière incrémentielle.

const fs = require('fs');

const readStream = fs.createReadStream('file.txt');
const writeStream = fs.createWriteStream('output.txt');

readStream.pipe(writeStream);

Q: Qu'est-ce que le système d'exploitation abstrait en Node.js ?

Le système d'exploitation abstrait (OS) est une couche qui fournit des interfaces unifiées pour interagir avec le système d'exploitation sous-jacent. Il permet à Node.js de fonctionner sur différents systèmes d'exploitation.

Q: Que sont les événements en Node.js ?

Les événements sont des objets qui représentent diverses actions qui peuvent être déclenchées dans l'environnement Node.js. Ils sont utilisés pour gérer la communication entre différentes parties du code.

const EventEmitter = require('events');

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter();
myEmitter.on('event', () => {
  console.log('un événement a été déclenché');
});
myEmitter.emit('event');

Exercices de code classiques

Exercice 1 : Compteur asynchrone

Ecrire une fonction qui prend un nombre en argument et affiche le comptage des nombres de 0 à ce nombre avec un délai de 1 seconde entre chaque affichage.

function countNumbers(num) {
  for (let i = 0; i <= num; i++) {
    setTimeout(() => {
      console.log(i);
    }, i * 1000);
  }
}

countNumbers(5);

Exercice 2 : Promesse de lecture de fichier

Ecrire une fonction qui retourne une promesse qui résout le contenu d'un fichier texte.

const fs = require('fs').promises;

function readFileContent(filePath) {
  return new Promise((resolve, reject) => {
    fs.readFile(filePath, 'utf8')
      .then(data => resolve(data))
      .catch(err => reject(err));
  });
}

readFileContent('file.txt')
  .then(content => console.log(content))
  .catch(err => console.error(err));

Exercice 3 : Middleware d'authentification

Ecrire un middleware Express qui vérifie si une clé d'API est présente dans les en-têtes de la requête.

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

function authMiddleware(req, res, next) {
  const apiKey = req.headers['x-api-key'];
  if (apiKey === 'my-secret-key') {
    next();
  } else {
    res.status(401).send('Unauthorized');
  }
}

app.use(authMiddleware);

app.get('/protected', (req, res) => {
  res.send('Accès protégé');
});

app.listen(3000, () => {
  console.log('Server running at http://localhost:3000/');
});

Exercice 4 : Gestion des erreurs avec try...catch

Ecrire une fonction qui divise deux nombres et gère les erreurs potentielles.

function divide(a, b) {
  try {
    if (b === 0) throw new Error('Division par zéro');
    return a / b;
  } catch (err) {
    console.error(err.message);
    return null;
  }
}

console.log(divide(10, 2)); // Output : 5
console.log(divide(10, 0)); // Output : Division par zéro

Exercice 5 : Streams de données

Ecrire un programme qui lit un fichier texte et écrit son contenu dans un autre fichier en utilisant des streams.

const fs = require('fs');

const readStream = fs.createReadStream('file.txt');
const writeStream = fs.createWriteStream('output.txt');

readStream.pipe(writeStream);

Pieges courants en entretien

Piege 1 : Confusion entre Node.js et JavaScript

Node.js utilise JavaScript, mais il s'exécute côté serveur. Il existe une différence importante entre le code exécuté dans un navigateur et celui exécuté avec Node.js.

Piege 2 : Ignorer les erreurs asynchrones

Les erreurs asynchrones ne sont pas traitées automatiquement. Il est important de gérer les erreurs en utilisant des callbacks, des promesses ou des try...catch.

fs.readFile('non-existent-file.txt', 'utf8', (err, data) => {
  if (err) throw err; // Erreur non traitée
  console.log(data);
});

Piege 3 : Non-compréhension des événements et de la non-blocage

Node.js est conçu pour être asynchrone et événementiel. Il ne bloque pas l'exécution du code même lorsqu'il attend une opération longue.

const fs = require('fs');

console.log('Début');
fs.readFile('file.txt', 'utf8', (err, data) => {
  console.log(data);
});
console.log('Fin'); // Exécuté avant la lecture du fichier

Piege 4 : Utilisation de let et const dans les boucles for

Dans certains cas, l'utilisation de let et const peut causer des problèmes en raison de la portée des variables.

for (let i = 0; i < 5; i++) {
  setTimeout(() => {
    console.log(i); // Affiche 5, 5, 5, 5, 5
  }, 100);
}

Piege 5 : Compréhension faible des streams

Les streams sont souvent sous-estimés. Ils permettent de gérer les données en morceaux plutôt que tout en une fois.

Complexité algorithmique

Q: Complexité O(1) : Opération constante, le temps d'exécution ne change pas avec la taille de l'entrée.

const arr = [1, 2, 3];
console.log(arr[0]); // Accès constant

Q: Complexité O(n) : Opération linéaire, le temps d'exécution augmente proportionnellement à la taille de l'entrée.

const arr = [1, 2, 3];
arr.forEach(item => {
  console.log(item); // Temps linéaire
});

Q: Complexité O(n²) : Opération quadratique, le temps d'exécution augmente en fonction du carré de la taille de l'entrée.

const arr = [1, 2, 3];
for (let i = 0; i < arr.length; i++) {
  for (let j = 0; j < arr.length; j++) {
    console.log(arr[i], arr[j]); // Temps quadratique
  }
}

Q: Complexité O(log n) : Opération logarithmique, le temps d'exécution augmente logarithmiquement avec la taille de l'entrée.

function binarySearch(arr, target) {
  let left = 0;
  let right = arr.length - 1;
  while (left <= right) {
    const mid = Math.floor((left + right) / 2);
    if (arr[mid] === target) {
      return mid; // Temps logarithmique
    } else if (arr[mid] < target) {
      left = mid + 1;
    } else {
      right = mid - 1;
    }
  }
  return -1;
}

Q: Complexité O(n log n) : Opération linéaireithme, le temps d'exécution augmente en fonction de la taille de l'entrée multiplié par le logarithme de cette taille.

function mergeSort(arr) {
  if (arr.length <= 1) return arr;
  const mid = Math.floor(arr.length / 2);
  const left = mergeSort(arr.slice(0, mid));
  const right = mergeSort(arr.slice(mid));
  return merge(left, right);
}

function merge(left, right) {
  let result = [];
  let i = 0;
  let j = 0;
  while (i < left.length && j < right.length) {
    if (left[i] < right[j]) {
      result.push(left[i]);
      i++;
    } else {
      result.push(right[j]);
      j++;
    }
  }
  return [...result, ...left.slice(i), ...right.slice(j)]; // Temps linéaireithme
}

Concepts avancés à connaitre

Q: Middleware Express

Les middlewares sont des fonctions qui ont accès à l'objet de requête (req), à l'objet de réponse (res) et à la chaîne de middlewares suivante dans le cycle de traitement de la requête. Ils peuvent exécuter du code, modifier les objets req et res, terminer le cycle de requête-réponse, ou appeler le middleware suivant.

Q: Gestion des erreurs avec try...catch

Les erreurs asynchrones ne sont pas traitées automatiquement. Il est important de gérer les erreurs en utilisant des callbacks, des promesses ou des try...catch.

async function fetchData() {
  try {
    const response = await fetch('https://api.example.com/data');
    const data = await response.json();
    console.log(data);
  } catch (err) {
    console.error(err.message);
  }
}

Q: Gestion des erreurs avec process.on('uncaughtException')

Les erreurs non traitées peuvent causer le crash de l'application. Il est important de gérer ces erreurs en utilisant process.on('uncaughtException').

process.on('uncaughtException', (err) => {
  console.error(`Uncaught Exception: ${err.message}`);
  process.exit(1);
});

Q: Utilisation des streams avec les fichiers

Les streams sont souvent sous-estimés. Ils permettent de gérer les données en morceaux plutôt que tout en une fois.

const fs = require('fs');

const readStream = fs.createReadStream('file.txt');
const writeStream = fs.createWriteStream('output.txt');

readStream.pipe(writeStream);

Q: Utilisation des streams avec les requêtes HTTP

Les streams peuvent également être utilisés pour traiter les données en flux continu lors de la gestion des requêtes HTTP.

const http = require('http');
const fs = require('fs');

const server = http.createServer((req, res) => {
  const readStream = fs.createReadStream('file.txt');
  readStream.pipe(res);
});

server.listen(3000, () => {
  console.log('Server running at http://localhost:3000/');
});

Conseils pratiques

Conseil 1 : Comprendre les principes de base

Avant tout autre chose, assurez-vous de comprendre les principes de base de Node.js, comme la programmation asynchrone et le non-blocage.

Conseil 2 : Utiliser des outils de débogage

L'utilisation d'outils de débogage peut aider à identifier les erreurs et à comprendre le comportement du code.

node inspect app.js

Conseil 3 : Écrire des tests

La rédaction de tests unitaires aide à vérifier la qualité du code et à prévenir les bugs futurs.

Conseil 4 : Utiliser un linter

Un linter peut aider à détecter des erreurs de syntaxe et à promouvoir une meilleure pratique de codage.

npm install --save-dev eslint

Conseil 5 : Connaître les meilleures pratiques

Apprendre les meilleures pratiques en matière de développement Node.js peut améliorer la performance et la sécurité de l'application.

Projet Node.js a lancer ?

Besoin d'aide sur un projet ? Decrivez-le pour des conseils personnalises.

Recevoir des conseils

Questions frequentes

A quoi sert cette cheatsheet Node.js ?
Cette cheatsheet Node.js regroupe la syntaxe, les commandes et les astuces essentielles pour Node.js. Elle est concue pour servir d'aide-memoire rapide, que vous soyez debutant ou developpeur confirme cherchant une reference rapide.
Comment utiliser cette cheatsheet Node.js ?
Parcourez les sections pour trouver la syntaxe ou la commande dont vous avez besoin. Vous pouvez la garder ouverte dans un onglet pendant que vous codez, ou la copier dans vos notes pour un acces hors ligne.
Cette cheatsheet est-elle a jour ?
Oui, nos cheatsheets sont regulierement mises a jour pour refleter les dernieres versions et bonnes pratiques de Node.js. Si vous remarquez une information obsolete, n'hesitez pas a nous contacter.

Pages liees

Chaque semaine, le meilleur de la tech francaise

Tendances, salaires, outils et opportunites — directement dans votre boite mail.

Gratuit. Desabonnement en un clic. Pas de spam.