📚 Fiches de Révision
87 questions organisées par thème
Domain Driven Design(20 questions)
Quelles affirmations sont vraies concernant l'Ubiquitous Language (Langage Ubiquitaire) ?
Explication :
L'Ubiquitous Language est un langage commun structuré autour du modèle de domaine, utilisé par les développeurs ET les experts métier. Il doit se refléter dans le code (noms de classes, méthodes, etc.).
Quelles sont les caractéristiques d'une Entity en DDD ?
Explication :
Une Entity est définie par son identité unique (ex: un ID) qui persiste dans le temps, pas par ses attributs. Elle n'est PAS immuable contrairement aux Value Objects.
Quelles sont les caractéristiques d'un Value Object ?
Explication :
Les Value Objects sont définis par leur valeur (attributs), doivent être immuables, et sont préférés aux Entities car ils simplifient le code. Ils n'ont PAS d'identité propre.
Concernant les Aggregates en DDD, quelles affirmations sont correctes ?
Explication :
Un Aggregate est un cluster d'objets associés avec une 'Root Entity' (Aggregate Root) qui contrôle l'accès. Il garantit la cohérence mais toutes les Entities ne sont PAS des Aggregate Roots.
Qu'est-ce qu'un Bounded Context ?
Explication :
Un Bounded Context est une frontière dans laquelle un modèle de domaine spécifique est défini. Le même mot peut avoir des significations différentes dans différents contextes.
Quels sont les rôles des Repositories en DDD ?
Explication :
Les Repositories encapsulent la persistance et la récupération des objets du domaine. La logique métier appartient aux Services ou aux Entities, pas aux Repositories.
À quoi sert l'Anti-corruption Layer (ACL) ?
Explication :
L'ACL est une couche de traduction qui protège le modèle interne des influences externes (modèles legacy, APIs tierces). Elle utilise des DTOs et mappers, mais n'est pas liée aux performances.
Concernant le Core Domain et les Generic Subdomains, quelles affirmations sont vraies ?
Explication :
Le Core Domain est le cœur de la valeur métier et doit recevoir le plus d'attention. Les Generic Subdomains (technique, support) sont nécessaires mais n'apportent pas de valeur unique.
Quelles sont les caractéristiques des Services en DDD ?
Explication :
Les Services sont stateless et contiennent une logique qui ne s'intègre pas dans une Entity ou un Value Object. Ils ne remplacent PAS les Entities mais complètent l'architecture.
Qu'est-ce que le Context Map en DDD ?
Explication :
Le Context Map est une visualisation des relations entre Bounded Contexts et des patterns d'intégration utilisés (ACL, Shared Kernel, etc.). Ce n'est pas lié au déploiement.
Concernant les Factories en DDD, quelles affirmations sont correctes ?
Explication :
Les Factories créent des objets complexes ou des Aggregates. Elles ne remplacent PAS tous les constructeurs, seulement quand la logique de création est complexe.
Qu'est-ce que le 'Refactoring toward deeper insight' en DDD ?
Explication :
À mesure que la compréhension du domaine s'améliore, le design doit être refactoré pour refléter ces insights, même si cela nécessite des changements majeurs. Ce n'est pas limité aux performances.
Concernant les 'Intention-revealing interfaces', quelles sont les bonnes pratiques ?
Explication :
Les interfaces doivent révéler l'intention métier, pas les détails techniques. Des noms business explicites (PayrollService, Employee) sont préférés aux noms techniques (ErpService, sapId).
Dans l'exemple d'un siège d'avion, quand doit-on utiliser une Entity vs un Value Object ?
Explication :
Si chaque siège a une identité (réservation spécifique) → Entity. Si n'importe quel siège équivalent convient → Value Object. Les sièges ne sont pas nécessairement immuables.
Pourquoi le DDD encourage-t-il les échanges fréquents avec les experts métier ?
Explication :
Les échanges fréquents alignent le code avec le business, construisent le langage commun et améliorent la compréhension. Le but n'est pas uniquement de réduire les coûts.
En DDD, qu'est-ce qui distingue une Entity d'un Value Object ?
Explication :
L'Entity a une identité, le Value Object est défini par ses attributs. Mais l'Entity n'est pas TOUJOURS mutable (elle peut avoir des champs finaux).
Dans le TP Feature Flipping, la classe Feature est-elle une Entity ou un Value Object ?
Explication :
Feature est une Entity : elle a un champ 'name' qui sert d'identité, et equals() compare uniquement le 'name'. L'annotation @Entity n'est pas requise au niveau domain.
Dans le TP, l'expression 'dev & admin | guest' est parsée dans quel ordre ?
Explication :
L'opérateur & (AND) a priorité sur | (OR), comme en mathématiques et en programmation. Donc (dev & admin) | guest.
Que retourne RoleExpression.toPredicate() ?
Explication :
toPredicate() retourne un Predicate<UserRoles> qui peut être testé avec .test(userRoles). stringify() retourne le String.
Dans le TP, comment la classe Feature valide-t-elle son nom ?
Explication :
La validation est dans le constructeur : 'if (name == null || name.isBlank()) throw new IllegalArgumentException()'. C'est le pattern DDD recommandé.
Test Driven Development(18 questions)
Quelles sont les étapes du cycle TDD (Red-Green-Refactor) ?
Explication :
Le cycle TDD est : Red (test échoue) → Green (code minimal pour passer) → Refactor (améliorer sans casser). L'optimisation des performances n'est PAS une étape du cycle.
Pourquoi écrire un test qui échoue d'abord (étape Red) ?
Explication :
L'étape Red confirme que le test fonctionne et détecte vraiment l'absence de fonctionnalité. Cela évite les tests qui passent toujours (faux positifs).
Quels outils sont utilisés pour le TDD en Java ?
Explication :
JUnit est le framework de test, AssertJ pour les assertions lisibles, Mockito pour les mocks. Maven est un outil de build, pas spécifiquement pour la couverture (c'est JaCoCo par exemple).
Quels sont les anti-patterns à éviter en TDD ?
Explication :
Tous sont des anti-patterns : les tests doivent être indépendants, tester le comportement public, ne pas tester le code tiers, et être rapides à exécuter.
Quelles sont les caractéristiques d'un bon test unitaire ?
Explication :
Les tests doivent être indépendants (ordre invariant), tester le comportement public, et être rapides. Un test ne doit JAMAIS dépendre de l'ordre d'exécution.
Quels sont les différents niveaux de tests ?
Explication :
Tous ces niveaux existent : unitaires (isolation), social/intégration (collaborateurs), E2E (flux complets), performance (charge).
Concernant Mockito, quelles affirmations sont vraies ?
Explication :
Mockito permet de créer des mocks (mock()), définir leur comportement (when()) et vérifier les appels (verify()). Les mocks ne remplacent PAS toujours les vraies classes, seulement pour isoler le code testé.
Qu'est-ce que l'ATDD (Acceptance Test Driven Development) ?
Explication :
ATDD écrit des tests basés sur les critères d'acceptation du client avant le développement. Il est souvent combiné avec BDD. Ce n'est pas lié aux performances.
Concernant la couverture de code, quelles affirmations sont vraies ?
Explication :
La couverture mesure le code exécuté par les tests et aide à identifier les lacunes. Mais 100% de couverture ne garantit PAS l'absence de bugs, car elle ne teste pas tous les cas.
Pourquoi les méthodes privées ne doivent-elles pas être testées directement ?
Explication :
Les méthodes privées sont des détails d'implémentation. Les tester directement rend les tests fragiles au refactoring. Elles sont testées via le comportement public.
Concernant les tests avec des parsers TDD, quels cas doivent être testés ?
Explication :
Tous ces cas doivent être testés : nulls/blanks, termes invalides, espaces parasites, et les cas complexes d'opérateurs imbriqués.
Concernant la hiérarchie des exceptions en Java, quelles affirmations sont vraies ?
Explication :
Error = problèmes système. Exception = checked (à déclarer ou capturer). RuntimeException = unchecked (pas obligé de déclarer). Seules les checked doivent être déclarées.
Quelles syntaxes Mockito permettent de vérifier qu'une méthode n'a JAMAIS été appelée ?
Explication :
times(0) et never() sont équivalents en Mockito pour vérifier qu'une méthode n'a pas été appelée.
Quelles annotations sont OBLIGATOIRES pour un test unitaire avec Mockito (JUnit 5) ?
Explication :
@ExtendWith et @Mock sont essentiels. @SpringBootTest est pour les tests d'intégration, pas les tests unitaires. @InjectMocks est utile mais pas toujours obligatoire.
Concernant ArgumentCaptor en Mockito, quelles affirmations sont vraies ?
Explication :
ArgumentCaptor capture les arguments pour les vérifier ensuite. Il complète AssertJ, ne le remplace pas.
Pourquoi les tests dans le TP utilisent-ils @Nested ?
Explication :
@Nested permet de grouper les tests et améliore la lisibilité. Ce n'est pas obligatoire et ne permet pas de partager le setup automatiquement.
Dans le test du contrôleur : 'verify(service, times(0)).saveFeature(any())' signifie ?
Explication :
times(0) vérifie que la méthode n'a PAS été appelée. C'est utilisé pour s'assurer qu'en cas d'erreur, on ne sauvegarde pas.
Dans AssertJ, quelle assertion vérifie qu'une collection contient exactement les éléments attendus, dans n'importe quel ordre ?
Explication :
containsExactlyInAnyOrder() vérifie les mêmes éléments sans ordre. containsExactly() impose l'ordre. contains() n'est pas exact.
Inversion of Control(17 questions)
Qu'est-ce que l'Inversion of Control (IoC) ?
Explication :
L'IoC consiste à déléguer la gestion des objets au conteneur (Spring, CDI). Le framework crée, injecte et détruit les composants. Ce n'est pas un pattern de performance.
Quelles sont les caractéristiques de la Dependency Injection (DI) ?
Explication :
La DI permet au conteneur de créer et injecter les dépendances (parfois via proxies). Elle favorise la composition over inheritance et facilite aussi les tests via les mocks.
À quoi sert l'annotation @Autowired (ou @Inject) ?
Explication :
@Autowired/@Inject indique au conteneur où injecter une dépendance. Elle ne crée PAS une nouvelle instance à chaque appel (dépend du scope).
Concernant l'annotation @Scope, quelles affirmations sont vraies ?
Explication :
Le scope par défaut est singleton (une instance). Prototype crée une nouvelle instance à chaque fois. Request est lié à une requête HTTP. Session n'est PAS le défaut.
Pourquoi faut-il éviter d'utiliser 'new' pour les composants injectables ?
Explication :
Utiliser 'new' bypasse le conteneur : l'objet n'a pas ses dépendances injectées et les proxies (pour les transactions, etc.) ne sont pas appliqués. Ce n'est pas une question de performance.
À quoi sert l'annotation @Bean (ou @Produces) ?
Explication :
@Bean/@Produces définit comment créer un bean quand la construction est complexe. Elle ne remplace pas automatiquement les dépendances.
Quels sont les avantages de l'IoC avec les Repositories automatiques ?
Explication :
Avec Spring Data, les Repositories génèrent automatiquement le CRUD et déduisent les requêtes du nom des méthodes (findByFirstname). Pas besoin de SQL manuel pour les cas simples.
Concernant les erreurs courantes en IoC, quelles affirmations sont vraies ?
Explication :
Erreurs courantes : oublier le singleton par défaut, ThreadLocal avec parallel streams (request scope), et tenter d'injecter des composants inconnus. On ne peut PAS injecter dans des objets créés manuellement.
Que permettent les annotations @Service et @Repository ?
Explication :
@Service et @Repository déclarent des composants gérés. @Repository offre le CRUD, @Service indique la logique métier. Elles ne sont PAS totalement interchangeables (sémantique différente).
Concernant @RestController en Spring, quelles affirmations sont vraies ?
Explication :
@RestController combine @Controller + @ResponseBody. Les méthodes retournent des objets JSON/XML, pas des vues HTML. On peut injecter des dépendances via @Autowired.
Quel est le scope par DÉFAUT d'un bean Spring ?
Explication :
Le scope par défaut est 'singleton' : une seule instance par conteneur Spring.
Comment Spring génère-t-il automatiquement les requêtes dans un Repository ?
Explication :
Spring Data déduit la requête à partir du nom de la méthode (ex: findByFirstname génère SELECT * WHERE firstname = ?).
Quel Repository Spring Data est correctement défini ?
Explication :
Un Repository Spring Data DOIT être une interface qui EXTENDS CrudRepository (ou JpaRepository). Une classe ne peut pas hériter d'une interface.
Quelle(s) annotation(s) peuvent être utilisées pour injecter une dépendance ?
Explication :
@Autowired (Spring), @Inject (JSR-330), et @Resource (JSR-250) permettent l'injection. @Dependency n'existe pas.
Quelles annotations marquent une classe comme composant géré par Spring ?
Explication :
@Component, @Service (logique métier), et @Repository (accès données) sont des stéréotypes. @Bean est pour les méthodes, pas les classes.
Quelle est la différence entre @Service et @Repository ?
Explication :
@Service = logique métier, @Repository = accès données avec traduction des exceptions. Ils ne sont PAS interchangeables, ils ont une sémantique différente.
Pourquoi l'injection par constructeur est-elle préférée à @Autowired sur un champ ?
Explication :
L'injection par constructeur permet les champs final, facilite les tests, et rend les dépendances explicites. Ce n'est pas obligatoire en Spring 6.
REST API(27 questions)
Quelles sont les caractéristiques de REST (Representational State Transfer) ?
Explication :
REST est une architecture (pas un protocole comme SOAP), avec identification unique des ressources, utilisant HTTP. REST est plus SIMPLE que SOAP, pas plus complexe.
Quelles sont les différences entre REST et SOAP ?
Explication :
REST = architecture avec identification des ressources. SOAP = protocole avec contrat WSDL. REST est plus LÉGER que SOAP, pas plus lourd.
Concernant le niveau 0 du modèle de Richardson, quelles affirmations sont vraies ?
Explication :
Le niveau 0 (Swamp of POX) utilise HTTP comme simple tunnel, souvent avec un seul endpoint POST. Les ressources ne sont PAS encore identifiées, c'est le niveau 1.
Concernant le niveau 1 du modèle de Richardson (Resources), quelles affirmations sont vraies ?
Explication :
Le niveau 1 introduit les ressources avec des URIs distinctes (/doctors/martin). Les verbes HTTP corrects sont le niveau 2, pas le niveau 1.
Concernant le niveau 2 du modèle de Richardson (HTTP Verbs), quelles affirmations sont vraies ?
Explication :
Le niveau 2 utilise correctement les verbes et les codes de statut HTTP. HATEOAS est le niveau 3, pas le niveau 2.
Concernant le niveau 3 du modèle de Richardson (HATEOAS), quelles affirmations sont vraies ?
Explication :
HATEOAS ajoute des liens dans les réponses pour guider le client. Peu d'APIs atteignent réellement ce niveau dans la pratique.
Quels verbes HTTP correspondent aux opérations CRUD ?
Explication :
POST=Create, GET=Read, PUT=Update complet, PATCH=Update partiel, DELETE=Delete. PATCH n'est pas pour la suppression.
À quoi servent les query strings en REST ?
Explication :
Les query strings servent au filtrage, pagination et tri. L'implémentation n'est PAS standardisée (chaque API peut utiliser différents noms de paramètres).
Concernant la négociation de contenu HTTP, quelles affirmations sont vraies ?
Explication :
La négociation de contenu via Accept permet de demander format, langue, encodage. Elle n'est pas limitée à la langue.
Quels codes de statut HTTP indiquent un succès ?
Explication :
Les codes 2XX indiquent un succès : 200 (OK), 201 (Created), 202 (Accepted). 400 est une erreur client (4XX).
Quels codes de statut HTTP indiquent une erreur client ?
Explication :
Les codes 4XX sont des erreurs client : 400 (Bad Request), 401 (Unauthorized), 403 (Forbidden). 500 est une erreur serveur (5XX).
Quels codes de statut HTTP indiquent une erreur serveur ?
Explication :
Les codes 5XX sont des erreurs serveur : 500, 501, 503. 404 est une erreur client (ressource non trouvée).
Quelle est la différence entre PUT et PATCH ?
Explication :
PUT remplace la ressource entière, PATCH ne modifie que certains champs. Ils ne sont PAS interchangeables.
Pourquoi le cache HTTP est-il important en REST ?
Explication :
GET est cacheable, POST non. Le cache améliore les performances. Tous les verbes ne sont PAS cacheables (POST, PUT, DELETE ne le sont pas par défaut).
Pourquoi le code 418 'I'm a teapot' existe-t-il ?
Explication :
418 'I'm a teapot' est un easter egg de la RFC 2324 (HTCPCP - protocole de cafetière). Ce n'est PAS un code sérieux pour la production.
Que signifie l'acronyme REST ?
Explication :
REST = Representational State Transfer, une architecture pour les APIs web utilisant HTTP.
Quel code HTTP DOIT être retourné après une création réussie avec POST ?
Explication :
201 Created est le code approprié pour une création réussie. 200 OK indique un succès général, 204 est pour un succès sans body.
Quel code HTTP retourner pour un DELETE réussi sur une ressource existante (sans body de retour) ?
Explication :
204 No Content est le code approprié pour un DELETE réussi sans contenu de retour. 200 OK implique un body dans la réponse.
Quel code retourner si on essaie de modifier une ressource qui n'existe pas avec PUT ?
Explication :
404 Not Found car la ressource ciblée n'existe pas. 400 serait pour une requête mal formée.
Dans un @RestController, comment retourner un code 201 avec l'URL de la ressource créée ?
Explication :
ResponseEntity.created(uri).build() retourne 201 avec le header Location. La méthode ok() retourne 200, pas 201.
Quelles méthodes HTTP sont idempotentes ?
Explication :
GET, PUT et DELETE sont idempotents (même résultat si répétés). POST n'est PAS idempotent (crée une nouvelle ressource à chaque appel).
Quels codes HTTP indiquent un succès SANS body dans la réponse ?
Explication :
SEUL 204 No Content indique explicitement l'absence de body. 200, 201 et 202 peuvent tous avoir un body.
Différence entre 401 Unauthorized et 403 Forbidden ?
Explication :
401 = pas authentifié (ou token invalide). 403 = authentifié mais pas les droits. C'est une distinction importante !
Pourquoi le contrôleur utilise StringUtils.hasText() plutôt que != null ?
Explication :
hasText() vérifie que le string n'est pas null, pas vide, et pas composé uniquement d'espaces. Cela évite aussi les NPE.
Dans le TP, que retourne POST /features si le nom est vide ?
Explication :
Le contrôleur retourne 400 Bad Request pour les données invalides (nom vide, expression invalide).
PUT /features/{name} avec un body contenant un nom différent retourne ?
Explication :
Le contrôleur vérifie que id.equals(featureBean.name), sinon 400 Bad Request. Le nom dans l'URL et le body doivent correspondre.
Le contrôleur du TP retourne ResponseEntity.noContent().build() pour DELETE. Quel code HTTP cela génère ?
Explication :
noContent() génère un 204 No Content, approprié pour un DELETE réussi sans body de retour.
Spring Cloud(5 questions)
Qu'est-ce que Spring Cloud ?
Explication :
Spring Cloud est une suite d'outils intégrés à Spring Boot pour créer des applications distribuées résilientes et stateless. Ce n'est pas un langage.
Qu'est-ce que le Service Registry (Annuaire de services) ?
Explication :
Le Service Registry permet aux services de s'enregistrer et d'être découverts dynamiquement (Eureka). Il ne remplace pas complètement les URLs, mais facilite le routing.
Qu'est-ce que le Service Discovery ?
Explication :
Le Service Discovery permet de découvrir les services par nom sans connaître les IPs/ports à l'avance. Il facilite le load balancing côté client.
Concernant l'architecture client/serveur HTTP dans Spring Cloud, quelles sont les caractéristiques ?
Explication :
L'architecture repose sur HTTP avec cache, statelessness, verbes et codes de statut. Les sessions côté serveur ne sont PAS obligatoires (stateless).
Dans Spring Cloud, pourquoi appeler les services par leur nom plutôt que par URL ?
Explication :
Appeler par nom permet le découplage, le load balancing et la résilience. Ce n'est pas juste pour la lisibilité mais pour des raisons techniques importantes.