Questions d'entretien Java Senior
1. Comment fonctionne le Garbage Collector de la JVM ?
Le GC libere automatiquement la memoire des objets non references. La heap est divisee en Young Generation (Eden + Survivor spaces) et Old Generation. Les objets sont crees dans Eden. Les collections "minor" (Young GC) sont rapides et frequentes. Les objets survivant a plusieurs cycles sont promus en Old Gen. Les collections "major" (Full GC) sont plus lentes. Collecteurs modernes : G1 (defaut depuis Java 9, bon equilibre pause/throughput), ZGC (pauses < 1ms, ideal pour les grandes heaps), Shenandoah (pauses faibles, RedHat).
2. Expliquez les Virtual Threads (Project Loom) de Java 21.
Les Virtual Threads sont des threads legers geres par la JVM plutot que par l'OS. Ils permettent de creer des millions de threads concurrents (contre quelques milliers de threads OS). L'API est identique aux threads classiques (Thread.ofVirtual().start()). Chaque virtual thread est monte sur un carrier thread (thread OS) et peut etre demonte pendant les operations bloquantes (I/O). C'est revolutionnaire pour les serveurs qui gagnent en throughput sans recourir aux callbacks asynchrones complexes.
3. Qu'est-ce que le pattern Reactor et la programmation reactive en Java ?
La programmation reactive gere des flux de donnees asynchrones avec backpressure (le consommateur controle le rythme). En Java : Project Reactor (Mono et Flux, utilise par Spring WebFlux), RxJava (Observable, Single, Completable). Operateurs : map, flatMap, filter, zip, retry, buffer, window. La programmation reactive est ideale pour les applications I/O-bound avec beaucoup de connexions simultanees. Cependant, avec les Virtual Threads de Java 21, la programmation imperative classique redevient competitiv.
4. Expliquez les Records, Sealed Classes et Pattern Matching de Java moderne.
Les Records (Java 16) sont des classes de donnees immutables avec equals/hashCode/toString generes : record Point(int x, int y) {}. Les Sealed Classes (Java 17) restreignent la hierarchie : sealed interface Shape permits Circle, Rectangle {}. Le Pattern Matching pour instanceof (Java 16) : if (shape instanceof Circle c) { c.radius(); }. Le Pattern Matching pour switch (Java 21) combine tout : switch (shape) { case Circle c -> ...; case Rectangle r -> ...; }. Ces features permettent la modelisation de domaine avec des types algebriques.
5. Comment concevoir une application thread-safe en Java ?
Strategies : immutabilite (records, objets immutables — aucune synchronisation necessaire), confinement au thread (ThreadLocal), classes thread-safe du JDK (ConcurrentHashMap, AtomicInteger, CopyOnWriteArrayList), synchronized (moniteur intrinseque, granularite objet), ReentrantLock (plus flexible, tryLock, fairness), StampedLock (optimiste, pour les cas read-heavy). Evitez les synchronized sur des methodes entieres. Preferez les structures immutables et les classes concurrent du JDK.
6. Expliquez les design patterns les plus utiles en Java.
Strategy : encapsuler des algorithmes interchangeables (Comparator en Java). Builder : construction d'objets complexes etape par etape (Pattern Lombok @Builder). Factory : delegation de la creation d'objets. Observer : notification d'evenements (PropertyChangeListener, reactive streams). Decorator : ajouter des comportements dynamiquement (I/O streams : BufferedInputStream(new FileInputStream(...))). Proxy : controle d'acces (Spring AOP, Hibernate lazy loading). Template Method : definir le squelette d'un algorithme (AbstractList).
7. Comment diagnostiquer un probleme de performance en Java ?
Outils : JVisualVM ou JConsole (monitoring en temps reel, heap, threads), JFR (Java Flight Recorder, profiling faible overhead), JMC (Java Mission Control, analyse des enregistrements JFR), async-profiler (profiling CPU et allocation, flame graphs), jmap (heap dump), jstack (thread dump pour les deadlocks). Metriques cles : CPU usage, heap usage, GC pause time, thread count, contention des locks. Prenez un thread dump si l'application semble "bloquee".
8. Qu'est-ce que le classloading en Java et comment fonctionne-t-il ?
Le ClassLoader charge les classes bytecode en memoire. Hierarchie : Bootstrap ClassLoader (classes core Java), Platform ClassLoader (modules Java), Application ClassLoader (classpath de l'application). Le mecanisme de delegation parente : un ClassLoader demande d'abord a son parent de charger la classe avant de le faire lui-meme. Cela evite les conflits. Les serveurs d'applications (Tomcat) et les frameworks de modules (OSGi) utilisent des ClassLoaders personnalises pour l'isolation des applications.
9. Expliquez le systeme de modules Java (JPMS).
Le Java Platform Module System (Project Jigsaw, Java 9) decoupe la plateforme et les applications en modules. Un module est defini par module-info.java : requires (dependances), exports (packages publics), opens (packages ouverts a la reflexion), provides/uses (services). Avantages : encapsulation forte (seuls les packages exportes sont accessibles), dependances explicites, images runtime minimales (jlink). En pratique, beaucoup de projets n'utilisent pas encore les modules, mais le JDK lui-meme est modularise.
10. Comment optimiser une application Spring Boot en production ?
Configuration : activez la compilation native (GraalVM Native Image pour des demarrages ultra-rapides), Spring AOT (compilation ahead-of-time), Virtual Threads (spring.threads.virtual.enabled=true en Java 21+). Performance : connection pooling (HikariCP configure correctement), cache (Spring Cache avec Caffeine ou Redis), compression gzip des reponses, profils adaptes (logging minimal en prod). Monitoring : Spring Boot Actuator + Prometheus + Grafana pour les metriques, Micrometer tracing pour le tracing distribue.