Maison  >  Article  >  Java  >  14 questions courantes d'entretien Java sur Internet

14 questions courantes d'entretien Java sur Internet

(*-*)浩
(*-*)浩original
2019-11-15 16:31:282254parcourir

14 questions courantes d'entretien Java sur Internet

1. Similitudes et différences synchronisées et réentrantes

Mêmeness

Les deux implémentent la synchronisation multi-thread et la sémantique de visibilité de la mémoire, et les deux sont des verrous réentrants

Différences

Le mécanisme d'implémentation est différent, synchronisé via la balise de verrouillage de tête d'objet Java et Monitor L'objet implémente reentrantlock et implémente la synchronisation via CAS, ASQ (AbstractQueuedSynchronizer) et locksupport (pour le blocage et le déblocage). Il s'appuie sur le modèle de mémoire jvm pour garantir la visibilité de la mémoire multithread contenant des variables partagées. variables partagées via l'état volatile d'ASQ. La visibilité

est utilisée de différentes manières. synchronisée peut modifier les méthodes d'instance (objets d'instance de verrouillage), les méthodes statiques (objets de classe de verrouillage), les blocs de code (afficher les objets de verrouillage spécifiés), le verrouillage réentrant, et display appelle la méthode trylock()/lock(), le verrou doit être libéré dans le bloc final. La richesse des fonctions varie. reentrantlock

fournit une sémantique riche telle qu'un temps d'attente limité pour le verrou (. définition du délai d'expiration), verrouillage interrompu (lockInterruptably), condition (fournissant l'attente, le signal et d'autres méthodes, fournit des verrous équitables et des verrous injustes à implémenter de manière synchronisée, qui ne peut pas définir le temps d'attente et ne peut pas être interrompu (interrompu)

2. Pourquoi concurrenthashmap lit-il sans verrouillage

jdk1.7

1) La clé, le hachage et le suivant dans HashEntry sont tous finaux, et seuls les l'en-tête peut être inséré ou supprimé.

2) Le champ de valeur de la classe HashEntry est déclaré comme volatile

3) Il n'est pas autorisé d'utiliser null comme clé et valeur lors de la lecture. le fil lit que le champ de valeur d'un HashEntry est nul, il sait qu'un conflit s'est produit - un phénomène de réorganisation s'est produit (put définit un nouvel objet de valeur Réorganisation des instructions de bytecode), vous devez verrouiller et relire cette valeur

4) Le nombre de variables volatiles coordonne la visibilité de la mémoire entre les threads de lecture et d'écriture après les opérations d'écriture et les opérations de lecture en premier. Compte de lecture, l'opération de lecture modifiée de l'opération d'écriture selon le principe de transitivité qui s'est produit avant. être vu

jdk1.8

1) Les valeurs val et next du nœud sont toutes deux volatiles

2) Les opérations non sécurisées correspondant à tabAt et casTabAt implémentent une sémantique volatile

3. Le rôle de ContextClassLoader (chargeur de classe de contexte de thread)

remplace les parents du mécanisme de délégation du chargeur de classe pour charger les classes, telles que l'implémentation du chargeur de service, utilise le chargeur de classe de contexte de thread pour charger classes. Faites attention à ce que le chargeur de classe entre plusieurs threads qui doivent communiquer soit le même pour éviter les exceptions de conversion de type (ClassCastException) causées par différents chargeurs de classe)

4. mécanisme

Différentes applications utilisent différents chargeurs de classe webapp pour obtenir l'effet d'isolation des applications. Sous le chargeur de classe webapp se trouve le serveur de chargement de classe jsp partagé par différentes applications qui peut être placé dans la classe Shared. chargeur/répertoire partagé

5. mécanisme de chargement de classe osgi

le modèle de chargement de classe osgi est maillé Oui, vous pouvez vous déléguer entre les modules (Bundle)

osgi La clé pour réaliser un déploiement modulaire à chaud est l'implémentation du mécanisme de chargement de classe personnalisé. Chaque Bundle a son propre chargeur de classe, qui peut être remplacé lorsqu'il doit être remplacé. Lorsqu'un Bundle est chargé, remplacez le Bundle avec. le chargeur de classe pour réaliser le remplacement à chaud du code

Lors de la réception d'une demande de chargement de classe, osgi effectuera une recherche de classe dans l'ordre suivant :

1) Déléguez les classes commençant par java.* à le chargeur de classe parent pour le chargement

2) Sinon, déléguez les classes de la liste de délégation (définie dans le fichier de configuration org.osgi.framework.bootdelegation) au chargement du chargeur de classe parent

3) Sinon, vérifiez s'il est déclaré dans l'Import-Package. Si c'est le cas, le chargeur de classe du Bundle délégué à l'exportation de cette classe est chargé.

4) Sinon, vérifiez s'il est déclaré dans Require-Bundle, si. donc, déléguez la demande de chargement de classe au chargeur de classe du bundle requis

5) Sinon, trouvez le ClassPath du Bundle actuel et utilisez votre propre chargeur de classe pour le charger

6) Sinon , recherchez si la classe est dans son propre Fragment Bundle. Si c'est le cas, déléguez-la au chargeur de classe du Fragment Bundle pour qu'il charge

7) Sinon, recherchez le Dynamic Import-Package (L'importation dynamique est uniquement disponible dans The Bundle est chargé uniquement lorsque ce Package est réellement utilisé) et est délégué au chargeur de classe du Bundle correspondant pour le chargement

8) Sinon, la recherche de classe échoue

6. Comment mettre fin à un Le thread en cours d'exécution

utilise l'indicateur de sortie. Cette variable d'indicateur doit être visible par plusieurs threads

utilise une interruption, combinée avec isInterrupted(). utiliser

7. threadlocal Scénarios et problèmes d'utilisation

Threadlocal ne peut pas résoudre le problème des variables partagées multi-thread. Les objets contenus dans le même threadlocal ont des copies différentes dans différents. threads sans interférer les uns avec les autres

Utilisé pour stocker les variables de contexte de thread afin de faciliter les lectures multiples de variables par le même thread, telles que les transactions et les connexions de connexion à la base de données. Il est plus utilisé dans la programmation Web

. Question : Notez que le thread local est utilisé dans les scénarios de pool de threads. Étant donné que la valeur réelle de la variable est stockée dans la variable de type threadlocalmap du thread, si la valeur n'est pas supprimée ou définie en premier, l'ancienne valeur précédente peut être obtenue

.

Problème : faites attention à la fuite de mémoire dans le scénario du pool de threads. Bien que le get/set de threadlocal efface l'entrée avec la clé (la clé est une référence faible de threadlocal, la valeur est une référence forte, ce qui empêche la valeur de le faire. être publié), mais il est préférable de le supprimer

8. Le processus du pool de threads du démarrage au travail

Lors de sa première création, il n'y a pas. thread dedans pour appeler execute(). Lors de l'ajout d'une tâche :

1 ) Si le nombre de threads en cours d'exécution est inférieur au paramètre principal corePoolSize, continuez à créer des threads pour exécuter cette tâche

2) Sinon, si le nombre de threads en cours d'exécution est supérieur ou égal à corePoolSize, ajoutez la tâche à la file d'attente de blocage

3) Sinon, si la file d'attente est pleine et le nombre de threads s'exécutant en même temps est inférieur au paramètre principal maximumPoolSize, continuez à créer des threads pour exécuter cette tâche

4) Sinon, si la file d'attente est pleine et que le nombre de threads exécutés en même temps est supérieur ou égal à maximumPoolSize, traité selon la politique de rejet définie

5) Terminer une tâche et continuer à traiter la tâche suivante

6) Lorsqu'il n'y a aucune tâche à poursuivre le traitement, le thread est interrompu ou le pool de threads est fermé , le thread quitte l'exécution. Si le pool de threads est fermé, le thread se termine

7) Sinon, déterminez si le nombre de threads exécutés dans le pool de threads est supérieur au nombre de threads principaux. le fil se termine, sinon le fil se bloque. Par conséquent, une fois toutes les tâches du pool de threads exécutées, la taille restante du pool de threads est corePoolSize

9 La différence entre la file d'attente de blocage BlockingQueue take et poll

poll(time) : take Prenez l'objet classé en premier dans BlockingQueue S'il ne peut pas être retiré immédiatement, vous pouvez attendre le temps spécifié par le paramètre time. S'il ne peut pas être obtenu, null sera renvoyé

take(). : Prenez l'objet classé en premier dans BlockingQueue. Si BlockingQueue est vide, bloquez jusqu'à ce que de nouveaux objets soient ajoutés à BlockingQueue

10 Comment obtenir les résultats de FutureTask sans bloquer

get(long timeout, TimeUnit unit), timeout Revenez ensuite au sondage

, jugez d'abord s'il est terminé via isDone(), puis appelez get()

11. blockingqueue Si des données critiques sont stockées, que doit-il se passer si le système tombe en panne ? Le traitement

pour conserver la file d'attente est plus gênant. Les données de production doivent être conservées sur le disque. une fois la persistance réussie, le thread consommateur charge les données du disque dans la file d'attente de blocage de mémoire et maintient le décalage de consommation. Au démarrage, les données sont chargées à partir du disque et ajoutées à la file d'attente des messages en fonction du décalage de consommation pour garantir que les messages sont bien reçus. pas perdu, des numéros de série sont générés, la consommation est idempotente et l'état de production après le redémarrage du système est déterminé en fonction du processus de consommation

12. NIO et la différence entre les E/S traditionnelles

Enregistrez les threads, les modifications NIO de chaque thread doivent bloquer la lecture et l'écriture dans un seul thread (c'est-à-dire le sélecteur) responsable du traitement des enregistrements de plusieurs canaux (register) Collection d'événements d'intérêt (SelectionKey) (la couche inférieure repose sur epoll () fourni par le système d'exploitation), netty bossgroup gère les connexions acceptées, le groupe de travail gère les processus métier spécifiques ainsi que la lecture et l'écriture des données, NIO fournit des opérations non bloquantes, les E/S traditionnelles traitent les données en continu et NIO traite les données en blocs. .NIO fournit un bytebuffer, qui est divisé en tampons dans le tas et hors tas. Lors de la lecture et de l'écriture, ils sont d'abord placés dans ce tampon, puis le noyau le transmet à l'extrémité opposée via le canal. n'est pas supprimé. Noyau, performances améliorées

13. Les chaînes répétables sont stockées dans la liste, comment supprimer une chaîne

Appelez les méthodes liées à l'itérateur pour supprimer la suppression et empêcher la suppression. Séquence positive Réarrangement du tableau causé par la suppression, problème d'éléments de tableau sautant d'index

14 Quelles sont les RACINES GC (les fuites de mémoire liées à cela sont plus pertinentes pour le développement quotidien)Tous les cadres de pile actuellement actifs des threads Java pointent vers des références à des objets dans le tas GC, de sorte que les objets inutilisés sont définis sur null à temps pour améliorer l'efficacité du recyclage de la mémoire

Objets référencés par des variables statiques, de sorte que les variables statiques sont réduites Surtout la taille des variables de collection statiques, les objets stockés dans la collection écrasent euqls() et hashcode() pour empêcher une croissance continue

Objets référencés par la méthode locale JNI

Références constantes dans la zone de méthode Objet, réduisant ainsi le besoin d'appeler String.intern() sur des chaînes longues

objets de classe chargés par le chargeur de classe, donc lorsque le chargeur de classe personnalisé n'est pas valide, définissez null à temps et faites attention à l'isolement entre les objets chargés par le chargeur de classe dans jvm Certaines structures de données statiques pointent vers des références à des objets dans le tas GC

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn