JavaRush /Blog Java /Random-FR /Traduction : Top 50 des questions d'entretien par fil de ...
KapChook
Niveau 19
Volga

Traduction : Top 50 des questions d'entretien par fil de discussion. Partie 2.

Publié dans le groupe Random-FR
La deuxième partie de la traduction de l'article original Top 50 des questions d'entrevue sur les fils Java, réponses pour les programmeurs débutants et expérimentés. Première partie.
  1. Comment vérifier si un thread détient un verrou ?

  2. Je ne savais pas qu'il était possible de vérifier si un fil de discussion était actuellement verrouillé jusqu'à ce que je tombe sur cette question lors d'un entretien téléphonique. java.lang.Thread a une méthode holdLock(), elle renvoie true si et seulement si le thread actuel maintient le moniteur sur un objet spécifique.
  3. Comment obtenir un thread dump ?

  4. Un thread dump vous permet de savoir ce que fait actuellement un thread. Il existe plusieurs façons d'obtenir un thread dump, selon le système d'exploitation. Sous Windows, vous pouvez utiliser la combinaison ctrl + Break, sous Linux, vous pouvez utiliser la commande kill -3. Vous pouvez également utiliser l'utilitaire jstack ; il fonctionne sur l'identifiant du processus, que vous pouvez découvrir à l'aide d'un autre utilitaire jps.
  5. Quel paramètre JVM est utilisé pour contrôler la taille de la pile du thread ?

  6. Il s'agit de l'un des paramètres simples -Xss utilisés pour contrôler la taille de la pile d'un thread en Java.
  7. Différences entre synchronisé et ReentrantLock ?

  8. Il y avait des moments où le seul moyen d'obtenir une exclusion mutuelle était d'utiliser le mot-clé synchronisé, mais il présente plusieurs inconvénients, comme l'impossibilité d'étendre le verrouillage au-delà d'une méthode ou d'un bloc de code, etc. Java 5 résout ce problème en fournissant un contrôle plus granulaire via l'interface Lock. ReentrantLock est une implémentation de verrouillage courante qui fournit à un verrou le même comportement de base et la même sémantique qu'un moniteur implicite, obtenu à l'aide de méthodes synchronisées, mais avec des fonctionnalités améliorées.
  9. Étant donné 3 threads T1, T2 et T3 ? Comment mettre en œuvre la séquence T1, T2, T3 ?

  10. La cohérence peut être obtenue de plusieurs manières, mais vous pouvez simplement utiliser la méthode join() pour démarrer un thread lorsqu'un autre a terminé son exécution. Pour implémenter la séquence donnée, vous devez d'abord démarrer le dernier thread, puis appeler la méthode join() dans l'ordre inverse, c'est-à-dire que T3 appelle T2.join et T2 appelle T1.join, donc T1 terminera en premier et T3 en dernier. .
  11. À quoi sert la méthode du rendement ?

  12. La méthode rendement est une façon de demander à un thread d’abandonner le processeur afin qu’un autre thread puisse s’exécuter. Il s'agit d'une méthode statique qui garantit uniquement que le thread actuel abandonnera le processeur, mais ne décide pas à quel thread l'exécution ira.
  13. Quel est le niveau de concurrence de ConcurrentHashMap ?

  14. ConcurrentHashMap atteint son évolutivité et sa sécurité des threads en divisant la carte réelle en sections. Cette séparation est obtenue en utilisant un niveau de parallélisme. Il s'agit d'un paramètre facultatif du constructeur ConcurrentHashMap et sa valeur par défaut est 16.
  15. Qu’est-ce que le Sémaphore ?

  16. Le sémaphore est un nouveau type de synchroniseur. Il s'agit d'un sémaphore avec un compteur. Conceptuellement, un sémaphore contrôle un ensemble d'autorisations. Chaque acquire() bloque, si nécessaire, avant que l'autorisation ne soit disponible, puis l'acquiert. Chaque release() ajoute une autorisation, libérant potentiellement l'acquéreur bloquant. Cependant, cela n'utilise pas d'objets d'autorisation réels ; Le sémaphore stocke simplement le nombre de disponibles et agit en conséquence. Le sémaphore est utilisé pour protéger des ressources coûteuses et disponibles en quantités limitées, comme une connexion à une base de données mutualisée.
  17. Que se passe-t-il si la file d'attente du pool de threads est déjà pleine et que vous soumettez une tâche ?

  18. Si la file d'attente du pool de threads est pleine, la tâche soumise sera "rejetée". La méthode submit() de ThreadPoolExecutor lève une RejectedExecutionException, après quoi le RejectedExecutionHandler est appelé.
  19. Différences entre les méthodes submit() etexecute() sur un pool de threads ?

  20. Les deux méthodes permettent de soumettre une tâche à un pool de threads, mais il existe une légère différence entre elles. Execute (commande Runnable) est défini dans l'interface Executor et exécute la tâche donnée dans le futur, mais plus important encore, ne renvoie rien. D'un autre côté, submit() est une méthode surchargée, elle peut accepter des tâches Runnable et Callable et peut renvoyer un objet Future qui peut être utilisé pour annuler l'exécution et/ou attendre le résultat d'un calcul. Cette méthode est définie dans l'interface ExecutorService, qui hérite de l'interface Executor, et chaque classe de pool de threads, telle que ThreadPoolExecutor ou ScheduledThreadPoolExecutor, hérite de ces méthodes.
  21. Qu'est-ce qu'une méthode de blocage ?

  22. Une méthode de blocage est une méthode qui bloque jusqu'à ce que la tâche soit terminée, par exemple, la méthode ServerSocket accept() se bloque en attendant que le client se connecte. Ici, le blocage signifie que le contrôle ne reviendra pas à la méthode appelante tant que le travail n'est pas terminé. D'un autre côté, il existe des méthodes asynchrones ou non bloquantes qui se terminent avant que la tâche ne soit terminée.
  23. Le thread Swing est-il sûr ?

  24. En termes simples, non, Swing n'est pas thread-safe, mais vous devez expliquer ce que vous entendez par là, même si l'intervieweur ne le demande pas. Lorsque nous disons que Swing n'est pas thread-safe, nous faisons généralement référence au fait qu'il s'agit d'un composant qui ne peut pas être modifié par plusieurs threads. Toutes les modifications apportées aux composants de l'interface graphique doivent être effectuées dans le thread AWT et Swing fournit des méthodes synchrones et asynchrones pour planifier ces modifications.
  25. Différences entre InvoquerAndWait et InvoquerLater ?

  26. Il s'agit de deux méthodes de l'API Swing qui permettent aux développeurs de mettre à jour les composants de l'interface graphique à partir des threads plutôt qu'à partir du thread Event Manager. InvokeAndWait() met à jour de manière synchrone un composant de l'interface graphique tel qu'une barre de progression ; chaque fois qu'une progression est effectuée, la barre doit être mise à jour pour refléter les modifications. Si la progression est suivie dans un autre thread, il doit appeler EnsureAndWait() pour affecter le thread Event Dispatcher à la mise à jour de ce composant. Et InvoqueLater() est un appel asynchrone pour mettre à jour les composants.
  27. Quelles méthodes de l'API Swing sont thread-safe ?

  28. Cette question concerne à nouveau Swing et la sécurité des threads, bien que les composants Swing ne soient pas thread-safe, il existe des méthodes qui peuvent être appelées en toute sécurité à partir de plusieurs threads. Je sais que repaint() et revalidate() sont thread-safe, mais il existe d'autres méthodes sur différents composants Swing, telles que les méthodes setText() de JTextComponent et insert() et append() de JTextArea.
  29. Comment créer des objets immuables ?

  30. Cette question peut sembler n’avoir rien à voir avec le multithreading et la concurrence, mais c’est le cas. L'immuabilité permet de simplifier un code parallèle déjà complexe. Un objet immuable coûte très cher aux développeurs car il peut être propagé sans aucune synchronisation. Malheureusement, Java n'a pas l'annotation @Immutable, qui rendra votre objet immuable, car les développeurs doivent travailler dur. Pour créer un objet immuable, vous devez suivre les bases : initialisation dans le constructeur, pas de setters, pas de fuite de référence, stockage de copies séparées des objets mutables.
  31. Qu’est-ce que ReadWriteLock ?

  32. En général, ReadWriteLock est le résultat d'une technique d'analyse des verrous visant à améliorer les performances des applications parallèles. Il s'agit d'une interface qui a été ajoutée dans Java 5. Elle fonctionne sur une paire de verrous associés, un pour les opérations de lecture, un pour les opérations d'écriture. Un verrou de lecteur peut être maintenu simultanément par plusieurs threads de lecture jusqu'à ce qu'il n'y ait plus d'écrivains. Le verrou d'écriture est exclusif. Si vous le souhaitez, vous pouvez implémenter une interface avec votre ensemble de règles ou utiliser ReentrantReadWriteLock, qui prend en charge un maximum de 65 535 verrous en écriture récursifs et 65 535 verrous en lecture.
  33. Qu’est-ce que la rotation occupée ?

  34. Busy Spin est une technique utilisée par les programmeurs pour forcer un thread à attendre dans une certaine condition. Contrairement aux méthodes traditionnelles, wait(), sleep() ou rendement(), qui impliquent de céder le contrôle du processeur, cette méthode ne cède pas le processeur ; au lieu de cela, elle exécute simplement une boucle vide. Pourquoi quelqu'un ferait-il ça ? Pour sauvegarder le cache du processeur. Sur les systèmes multicœurs, il est possible qu'un thread suspendu continue de s'exécuter sur un autre cœur, ce qui implique une reconstruction du cache. Pour éviter des reconstructions coûteuses, le programmeur préfère attendre moins en utilisant le spin occupé.
  35. Différences entre les variables volatiles et atomiques ?

  36. C'est une question assez intéressante, au début les variables volatiles et atomiques se ressemblent beaucoup, mais elles sont quand même différentes. Une variable volatile fournit une garantie préalable qu'une écriture aura lieu avant toute écriture ultérieure ; elle ne garantit pas l'atomicité. Par exemple, l’opération count++ ne deviendra pas atomique simplement parce que count est déclaré volatile. D'un autre côté, la classe AtomicInteger fournit une méthode atomique pour effectuer de telles opérations complexes de manière atomique, par exemple getAndIncrement() est un remplacement atomique de l'opérateur d'incrémentation, il peut être utilisé pour incrémenter atomiquement la valeur actuelle de un. Il existe également des versions atomiques pour d'autres types de données.
  37. Que se passe-t-il si un thread lève une exception dans un bloc synchronisé ?

  38. C'est une autre question piège pour les programmeurs Java réguliers. Quelle que soit la façon dont vous quittez un bloc synchronisé, soit normalement en terminant l'exécution, soit soudainement en lançant une exception, le thread libère le verrou acquis lorsqu'il entre dans le bloc synchronisé. C'est l'une des raisons pour lesquelles je préfère un bloc de verrouillage synchronisé à une interface qui nécessite un soin particulier lors du déverrouillage du verrou, généralement obtenu en libérant le verrou dans un bloc final.
  39. Qu'est-ce que le verrouillage à double vérification de Singleton ?

  40. C’est l’une des questions d’entretien les plus populaires et pourtant, malgré sa popularité, les chances qu’un candidat y réponde sont au mieux de 50 %. La moitié du temps, ils ne parviennent pas à écrire le code et l'autre moitié à expliquer comment il a été cassé et corrigé dans Java 1.5. Il s'agit d'une ancienne façon de créer un singleton thread-safe qui tente d'optimiser les performances en bloquant uniquement lorsque l'instance singleton est instanciée pour la première fois, mais en raison de la complexité et du fait qu'il a été cassé dans le JDK 1.4, je n'aime personnellement pas il. Néanmoins, même si vous ne préférez pas cette approche, il est utile de la connaître du point de vue de l'entretien.
  41. Comment créer un Singleton thread-safe ?

  42. Cette question complète la précédente. Si vous dites que vous n'aimez pas le verrouillage à double vérification, l'intervieweur sera alors obligé de vous poser des questions sur d'autres moyens de créer un Singleton thread-safe. Et ils le sont, vous pouvez profiter des fonctionnalités de chargement de classe et d’initialisation de variables statiques pour instancier Singleton, ou vous pouvez profiter du puissant type enum.
  43. Énumérez 3 coutumes que vous suivez en programmation parallèle ?

  44. C'est ma question préférée car je pense que certaines règles doivent être suivies lors de l'écriture de code parallèle, ce qui améliore les performances, le débogage et la prise en charge. Vous trouverez ci-dessous les 3 meilleures règles que tout programmeur Java devrait suivre :
    • Donnez toujours des noms significatifs à vos fils de discussion
    • Trouver un bug ou traquer une exception dans le code parallèle est une tâche assez difficile. OrderProcessor, QuoteProcessor ou TradeProcessor est bien meilleur que Thread-1. Fil-2 et fil-3. Le nom doit refléter la tâche effectuée par le thread. Tous les principaux frameworks et même JDK suivent cette règle.
    • Évitez de bloquer ou de réduire la portée de synchronisation
    • Le blocage coûte cher, et le changement de contexte est encore plus coûteux. Essayez d'éviter autant que possible la synchronisation et le blocage, et vous réduirez la section critique au minimum requis. C'est pourquoi je préfère un blocage chronométré à une méthode chronométrée, car il vous donne un contrôle absolu sur l'étendue du blocage.
    • Entre synchroniseurs et attendre et notifier, choisissez les synchroniseurs
    • Premièrement, les synchroniseurs tels que CountDownLatch, Semaphore, CyclicBarrier ou Exchanger simplifient le codage. Il est très difficile de mettre en œuvre un flux de contrôle complexe à l'aide de l'attente et de la notification. Deuxièmement, ces classes sont écrites et maintenues par les meilleurs du secteur et il y a de fortes chances qu'elles soient optimisées ou remplacées par un meilleur code dans les futures versions du JDK. En utilisant des utilitaires de synchronisation de haut niveau, vous bénéficiez automatiquement de tous ces avantages.
    • Entre Collecte simultanée et Collecte synchronisée, choisissez Collecte simultanée
    • Il s’agit d’une autre règle simple qui est facile à suivre et à en récolter les bénéfices. Les collections simultanées sont plus évolutives que leurs homologues synchronisées, il est donc préférable de les utiliser lors de l'écriture de code parallèle. Alors la prochaine fois que vous aurez besoin d'une carte, pensez à ConcurrentHashMap avant de penser à Hashtable.
  45. Comment forcer le démarrage d'un fil de discussion ?

  46. C'est une question à la manière de forcer l'exécution du garbage collection. Bref, pas question, vous pouvez bien sûr faire une requête en utilisant System.gc(), mais cela ne garantit rien. Il n'y a absolument aucun moyen de forcer le démarrage d'un thread en Java, cela est contrôlé par le planificateur de threads et Java ne fournit aucune API pour le contrôler. Cette partie de Java est encore aléatoire.
  47. Qu'est-ce que le framework Fork/Join ?

  48. Le framework Fork/Join introduit dans JDK 7 est un utilitaire puissant qui permet au développeur de profiter des multiples processeurs des serveurs modernes. Il est conçu pour des travaux qui peuvent être décomposés de manière récursive en petites particules. L’objectif est d’utiliser toute la puissance de calcul disponible pour augmenter les performances de votre application. Un avantage important de ce cadre est qu'il utilise un algorithme de vol de travail (du travail - travailler et voler - voler). Les threads de travail qui n'ont plus de tâches peuvent voler des tâches à d'autres threads qui sont encore occupés.
  49. Quelle est la différence entre les appels à wait() et sleep() ?

  50. Bien que l'attente et le sommeil représentent une sorte de pause dans une application Java, ce sont des dispositifs répondant à des besoins différents. Wait est utilisé pour la communication du thread interne, il se verrouille si la condition d'attente est vraie et attend une notification si les actions d'un autre thread rendent la condition d'attente fausse. D'un autre côté, la méthode sleep() abandonne simplement le processeur ou arrête l'exécution du thread en cours pendant une durée spécifiée. L’appel de sleep() ne libère pas le verrou détenu par le thread actuel.
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION