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 consommation12. 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ées13. 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'index14 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!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

Video Face Swap
Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Sujets chauds

Guide du nombre de Smith en Java. Nous discutons ici de la définition, comment vérifier le numéro Smith en Java ? exemple avec implémentation de code.

Dans cet article, nous avons conservé les questions d'entretien Java Spring les plus posées avec leurs réponses détaillées. Pour que vous puissiez réussir l'interview.

Java 8 présente l'API Stream, fournissant un moyen puissant et expressif de traiter les collections de données. Cependant, une question courante lors de l'utilisation du flux est: comment se casser ou revenir d'une opération FOREAK? Les boucles traditionnelles permettent une interruption ou un retour précoce, mais la méthode Foreach de Stream ne prend pas directement en charge cette méthode. Cet article expliquera les raisons et explorera des méthodes alternatives pour la mise en œuvre de terminaison prématurée dans les systèmes de traitement de flux. Lire plus approfondie: Améliorations de l'API Java Stream Comprendre le flux Forach La méthode foreach est une opération terminale qui effectue une opération sur chaque élément du flux. Son intention de conception est

Guide de TimeStamp to Date en Java. Ici, nous discutons également de l'introduction et de la façon de convertir l'horodatage en date en Java avec des exemples.

Les capsules sont des figures géométriques tridimensionnelles, composées d'un cylindre et d'un hémisphère aux deux extrémités. Le volume de la capsule peut être calculé en ajoutant le volume du cylindre et le volume de l'hémisphère aux deux extrémités. Ce tutoriel discutera de la façon de calculer le volume d'une capsule donnée en Java en utilisant différentes méthodes. Formule de volume de capsule La formule du volume de la capsule est la suivante: Volume de capsule = volume cylindrique volume de deux hémisphères volume dans, R: Le rayon de l'hémisphère. H: La hauteur du cylindre (à l'exclusion de l'hémisphère). Exemple 1 entrer Rayon = 5 unités Hauteur = 10 unités Sortir Volume = 1570,8 unités cubes expliquer Calculer le volume à l'aide de la formule: Volume = π × r2 × h (4

PHP et Python ont chacun leurs propres avantages, et le choix doit être basé sur les exigences du projet. 1.Php convient au développement Web, avec une syntaxe simple et une efficacité d'exécution élevée. 2. Python convient à la science des données et à l'apprentissage automatique, avec une syntaxe concise et des bibliothèques riches.

PHP est un langage de script largement utilisé du côté du serveur, particulièrement adapté au développement Web. 1.Php peut intégrer HTML, traiter les demandes et réponses HTTP et prend en charge une variété de bases de données. 2.PHP est utilisé pour générer du contenu Web dynamique, des données de formulaire de traitement, des bases de données d'accès, etc., avec un support communautaire solide et des ressources open source. 3. PHP est une langue interprétée, et le processus d'exécution comprend l'analyse lexicale, l'analyse grammaticale, la compilation et l'exécution. 4.PHP peut être combiné avec MySQL pour les applications avancées telles que les systèmes d'enregistrement des utilisateurs. 5. Lors du débogage de PHP, vous pouvez utiliser des fonctions telles que error_reportting () et var_dump (). 6. Optimiser le code PHP pour utiliser les mécanismes de mise en cache, optimiser les requêtes de base de données et utiliser des fonctions intégrées. 7

Java est un langage de programmation populaire qui peut être appris aussi bien par les développeurs débutants que par les développeurs expérimentés. Ce didacticiel commence par les concepts de base et progresse vers des sujets avancés. Après avoir installé le kit de développement Java, vous pouvez vous entraîner à la programmation en créant un simple programme « Hello, World ! ». Une fois que vous avez compris le code, utilisez l'invite de commande pour compiler et exécuter le programme, et « Hello, World ! » s'affichera sur la console. L'apprentissage de Java commence votre parcours de programmation et, à mesure que votre maîtrise s'approfondit, vous pouvez créer des applications plus complexes.
