MFormations
Modern Design Patterns

Chapitre 23

23. Interviews - Design Patterns

23. Interviews - Design Patterns

60 Questions d'Interview - Design Patterns


Partie 1 : Questions Comportementales (30)

Expérience générale

Q1 : Parle-moi d'un projet où tu as utilisé des Design Patterns. Quel pattern as-tu choisi et pourquoi ?

Q2 : Décris une situation où l'absence de Design Patterns a causé des problèmes dans un projet.

Q3 : Comment as-tu introduit les Design Patterns dans une équipe qui ne les utilisait pas ?

Q4 : Quel est le plus grand échec technique que tu aies rencontré avec un pattern ?

Q5 : Décris un refactoring important que tu as mené. Quels patterns as-tu appliqués ?

Prise de décision

Q6 : Comment choisis-tu entre plusieurs patterns pour résoudre un problème ?

Q7 : Décris une situation où tu as délibérément choisi de ne pas utiliser un pattern.

Q8 : Comment évalues-tu si un pattern est sur-engineering pour un problème donné ?

Q9 : Quelle est ton approche pour équilibrer flexibilité et simplicité dans une architecture ?

Q10 : Comment décides-tu quand refactorer du code legacy ?

Collaboration

Q11 : Comment expliques-tu un pattern complexe à un développeur junior ?

Q12 : Décris une revue de code où tu as suggéré l'utilisation d'un pattern.

Q13 : Comment gères-tu les désaccords sur le choix d'un pattern dans l'équipe ?

Q14 : As-tu déjà dû convaincre ton manager de l'importance d'investir dans l'architecture ?

Q15 : Comment documentes-tu les décisions architecturales dans ton équipe ?

Apprentissage

Q16 : Comment as-tu appris les Design Patterns ? Quelle ressource a été la plus utile ?

Q17 : Quel pattern as-tu découvert récemment et dans quel contexte ?

Q18 : Comment te tiens-tu à jour sur les nouveaux patterns et pratiques ?

Q19 : Quel livre sur les patterns recommanderais-tu à un développeur intermédiaire ?

Q20 : Quelle conférence ou vidéo sur les patterns t'a le plus marqué ?

Problèmes concrets

Q21 : Décris un système complexe que tu as conçu. Quels patterns architecturaux as-tu utilisés ?

Q22 : Comment as-tu géré une migration de monolithe vers microservices ?

Q23 : Décris un bug causé par une mauvaise utilisation de pattern et comment tu l'as corrigé.

Q24 : Comment gères-tu la dette technique liée aux patterns mal implémentés ?

Q25 : Décris comment tu as utilisé les tests pour valider une architecture de patterns.

Leadership

Q26 : Comment établis-tu des standards de code autour des patterns dans une équipe ?

Q27 : As-tu déjà créé un ADR (Architecture Decision Record) ? Décris le processus.

Q28 : Comment onboardes-tu un nouveau développeur sur une codebase riche en patterns ?

Q29 : Quels sont les anti-patterns les plus courants que tu vois en entreprise ?

Q30 : Quelle serait ton approche pour auditer l'architecture d'une application existante ?


Partie 2 : Questions Techniques (30)

Identification de patterns

Q31 : Donne un exemple concret où tu utiliserais le pattern Stratégie plutôt qu'un switch/if.

Q32 : Quelle est la différence entre Factory Method et Abstract Factory ? Donne un exemple pour chacun.

Q33 : Dans quels cas le pattern Singleton est-il approprié ? Dans quels cas est-ce un anti-pattern ?

Q34 : Quelle est la différence entre un Proxy et un Decorator ?

Q35 : Quand utiliser Composite plutôt qu'une simple collection ?

Implémentation

Q36 : Implémente un Observateur thread-safe en TypeScript.

Q37 : Code un Builder fluent pour une classe QueryBuilder SQL.

Q38 : Écris un Proxy de cache pour un service d'API avec TTL configurable.

Q39 : Implémente une Chaîne de Responsabilité pour un middleware HTTP.

Q40 : Code un Circuit Breaker simple avec les 3 états.

Architecture

Q41 : Conçois l'architecture d'un système de notifications supportant Email, SMS, Push, avec ajout facile d'un nouveau canal.

Q42 : Comment structurerais-tu un système de plugins en utilisant les patterns ?

Q43 : Conçois un système de validation de données avec composition de validateurs.

Q44 : Comment implémenterais-tu un undo/redo dans un éditeur ?

Q45 : Propose une architecture pour un système e-commerce avec les patterns appropriés.

SOLID et principes

Q46 : Explique le Dependency Inversion Principle. Donne un exemple avant/après.

Q47 : Comment le pattern Observateur viole-t-il potentiellement le LSP ? Comment l'éviter ?

Q48 : Quelle est la relation entre OCP (Open/Closed) et les patterns Strategy/Decorator ?

Q49 : Comment appliquer l'ISP (Interface Segregation) au React Context API ?

Q50 : Décris comment le pattern Adapter respecte le SRP.

Design Patterns avancés

Q51 : Explique le pattern Saga. Dans quel contexte l'utiliser ?

Q52 : Quelle est la différence entre CQRS et Event Sourcing ? Comment les combine-t-on ?

Q53 : Décris l'Anti-Corruption Layer. Quand est-il nécessaire ?

Q54 : Explique le pattern Strangler Fig pour la migration de systèmes legacy.

Q55 : Comment le pattern Outbox garantit-il la livraison fiable des événements ?

Systèmes distribués

Q56 : Comment gères-tu les transactions distribuées dans une architecture microservices ?

Q57 : Conçois un système de réservation avec Saga et compensation.

Q58 : Comment implémenter un API Gateway avec agrégation ?

Q59 : Explique le pattern BFF (Backend for Frontend). Donne un exemple.

Q60 : Comment assurer la résilience dans un système distribué ? Quels patterns utiliser ?


Réponses résumées (Techniques)

Q31 - Strategy vs switch

// Au lieu de :
function getDiscount(type: string) { 
  if (type === 'VIP') return 0.2;
  if (type === 'LOYAL') return 0.15;
  // ...
}

// Utiliser Strategy :
interface DiscountStrategy { calculate(amount: number): number; }
class VIPDiscount implements DiscountStrategy { calculate(a: number) { return a * 0.2; } }
class LoyalDiscount implements DiscountStrategy { calculate(a: number) { return a * 0.15; } }

Q36 - Observer thread-safe

class ThreadSafeObserver {
  private observers = new Set<Function>();
  private mutex = new Mutex();

  async subscribe(fn: Function): Promise<void> {
    await this.mutex.acquire();
    try { this.observers.add(fn); }
    finally { this.mutex.release(); }
  }

  async notify(data: any): Promise<void> {
    const tasks = [...this.observers].map(fn => fn(data));
    await Promise.all(tasks);
  }
}

Q40 - Circuit Breaker

class CircuitBreaker {
  state: 'CLOSED' | 'OPEN' | 'HALF_OPEN' = 'CLOSED';
  failures = 0;
  threshold = 5;
  timeout = 30000;
  lastFailure = 0;

  async call<T>(fn: () => Promise<T>): Promise<T> {
    if (this.state === 'OPEN') {
      if (Date.now() - this.lastFailure > this.timeout) this.state = 'HALF_OPEN';
      else throw new Error('Circuit open');
    }
    try {
      const result = await fn();
      this.failures = 0;
      this.state = 'CLOSED';
      return result;
    } catch (error) {
      this.failures++;
      this.lastFailure = Date.now();
      if (this.failures >= this.threshold) this.state = 'OPEN';
      throw error;
    }
  }
}

Q41 - Notification system

interface Notifier { send(message: string): void; }

class EmailNotifier implements Notifier { /* ... */ }
class SMSNotifier implements Notifier { /* ... */ }
class PushNotifier implements Notifier { /* ... */ }

class NotificationService {
  constructor(private notifiers: Notifier[]) {}
  send(message: string) { this.notifiers.forEach(n => n.send(message)); }
}

Q44 - Undo/Redo

Combinaison Command + Memento : chaque commande est stockée dans une pile. L'undo restaure le memento précédent.

Q51 - Saga

Transaction distribuée composée d'étapes locales avec compensation. Choreography (événements) ou Orchestration (coordinateur).

Q55 - Outbox

Sauvegarde l'événement dans la même transaction que l'opération métier. Un poller lit la table outbox et publie au broker. Garantie "at least once".