1. Qu'est-ce qu'une machine virtuelle Java ? Pourquoi Java est-il appelé « langage de programmation indépendant de la plate-forme » ?
(Recommandations pour des questions d'entretien plus connexes : questions et réponses d'entretien Java)
La machine virtuelle Java est un processus de machine virtuelle qui exécute des fichiers de bytecode (.class). . Le programme source Java (.java) est compilé dans un fichier de bytecode (.class) par le compilateur. Ensuite, le fichier bytecode sera interprété en code machine par la machine virtuelle Java (le code machine des différentes plateformes est différent). Utilisez le code machine pour faire fonctionner le matériel et les systèmes d'exploitation. Étant donné que différentes plates-formes sont équipées de différentes JVM, elles peuvent interpréter le même fichier .class dans le code machine requis par différentes plates-formes. C'est précisément en raison de l'existence de JVM que Java est appelé langage de programmation indépendant de la plate-forme.
2. Quelle est la différence entre JDK et JRE ?
Java Development Kit (JDK) est un package complet de développement de logiciels Java, comprenant JRE, un compilateur et d'autres outils (tels que JavaDoc, le débogueur Java), qui permet aux développeurs de développer, de compiler et d'exécuter des applications Java. Environnement d'exécution Java (JRE). Il comprend une machine virtuelle Java, une bibliothèque de classes de base Java et des fichiers de support. Il n'inclut pas les outils de développement (JDK), les compilateurs, les débogueurs et autres outils.
3. Que signifie le mot-clé « statique » ? Est-il possible de remplacer une méthode privée ou statique en Java ?
Le mot-clé "static" indique qu'une variable membre ou une méthode membre est accessible sans variable d'instance de la classe à laquelle elle appartient.
Les méthodes statiques en Java ne peuvent pas être remplacées car les remplacements de méthodes sont basés sur une liaison dynamique au moment de l'exécution, tandis que les méthodes statiques sont liées statiquement au moment de la compilation. Les méthodes statiques ne sont liées à aucune instance de la classe, elles ne s’appliquent donc pas conceptuellement. Les méthodes privées ne peuvent pas être remplacées en Java, car les variables et méthodes privées ne peuvent être utilisées que dans la classe actuelle. Si d'autres classes héritent de la classe actuelle, elles ne peuvent pas accéder aux variables ou méthodes privées et, bien sûr, elles ne peuvent pas être remplacées.
4. Est-il possible d'accéder à des variables non statiques dans un environnement statique ?
Les variables statiques appartiennent à des classes en Java et leurs valeurs sont les mêmes dans toutes les instances. Lorsqu'une classe est chargée par la machine virtuelle Java, les variables statiques sont initialisées. Si votre code tente d'accéder à des variables non statiques sans utiliser d'instance, le compilateur signalera une erreur car ces variables n'ont pas encore été créées et ne sont associées à aucune instance.
5. Quels sont les types de données pris en charge par Java ? Qu'est-ce qu'un carton de déballage automatique ?
Java prend en charge deux types de données : l'un est le type de données de base, notamment byte, char, short, boolean, int, long, float, double ; l'autre est le type de référence : tel que String, etc. En fait, il s'agit d'une référence à un objet. Ce qui est stocké dans la pile virtuelle de la JVM est l'adresse de l'objet créé. Le processus de recherche de l'objet dans le tas est effectué via l'adresse. un type de référence. L'autoboxing est la conversion du compilateur Java entre les types de données de base et les types d'empaquetage d'objets correspondants, c'est-à-dire que int est converti en Integer. Le déballage automatique est le processus de conversion d'Integer en int en appelant sa méthode.
6. Que signifient le remplacement et la surcharge de méthodes en Java ?
La surcharge de méthodes en Java se produit lorsque deux méthodes ou plus dans la même classe ont le même nom de méthode mais des paramètres différents. La substitution est une manifestation du polymorphisme dans une classe. Le remplacement de méthode signifie que la sous-classe redéfinit la méthode de la classe parent. Les remplacements de méthode doivent avoir le même nom de méthode, la même liste de paramètres et le même type de retour. Un remplacement ne peut pas restreindre l'accès aux méthodes qu'il remplace. En Java, les sous-classes peuvent hériter des méthodes de la classe parent et il n'est pas nécessaire de réécrire les mêmes méthodes. Mais parfois, la sous-classe ne veut pas hériter des méthodes de la classe parent inchangées, mais souhaite apporter certaines modifications, c'est pourquoi la réécriture des méthodes est utilisée. Le remplacement de méthode est également appelé remplacement de méthode.
7.Qu'est-ce qu'une méthode constructeur en Java ? Qu’est-ce que la surcharge du constructeur ? Qu’est-ce qu’un constructeur de copie ?
Lorsqu'un nouvel objet est créé, le constructeur sera appelé. Chaque classe possède des méthodes constructeur. Dans le cas où le programmeur ne fournit pas de constructeur pour la classe, le compilateur Java créera un constructeur par défaut pour la classe. La surcharge de constructeur et la surcharge de méthode en Java sont très similaires. Vous pouvez créer plusieurs constructeurs pour une classe. Chaque constructeur doit avoir sa propre liste de paramètres unique. Java ne prend pas en charge les constructeurs de copie. Si vous n'écrivez pas le constructeur vous-même, Java ne créera pas de constructeur de copie par défaut.
8. Java prend-il en charge l'héritage multiple ?
Les classes en Java ne prennent pas en charge l'héritage multiple, mais uniquement l'héritage unique (c'est-à-dire qu'une classe n'a qu'une seule classe parent). Cependant, les interfaces Java prennent en charge l'héritage multiple, c'est-à-dire qu'une sous-interface peut avoir plusieurs interfaces parents. (La fonction d'une interface est d'étendre les fonctions d'un objet. Une sous-interface hérite de plusieurs interfaces parents, indiquant que la sous-interface étend plusieurs fonctions. Lorsqu'une classe implémente l'interface, la classe étend les fonctions correspondantes).
9. Quelle est la différence entre une interface et une classe abstraite ?
Au niveau de la conception, l'abstraction est l'abstraction des classes et la conception d'un modèle. Les interfaces sont l'abstraction du comportement et une spécification du comportement.
Java fournit et prend en charge la création de classes et d'interfaces abstraites. Leurs implémentations ont quelque chose en commun, mais les différences sont :
Toutes les méthodes de l'interface sont implicitement abstraites. Une classe abstraite peut contenir à la fois des méthodes abstraites et non abstraites ; une classe peut implémenter de nombreuses interfaces, mais ne peut hériter que d'une seule classe abstraite ; une classe n'a pas besoin d'implémenter toutes les méthodes déclarées par les classes abstraites et les interfaces. Dans ce cas, les classes doivent également être déclarées abstraites ; les classes abstraites peuvent implémenter des interfaces sans fournir d'implémentations de méthodes d'interface ; les variables déclarées dans les interfaces Java sont finales par défaut. Les classes abstraites peuvent contenir des variables non finales ; les fonctions membres dans les interfaces Java sont publiques par défaut. Les fonctions membres des classes abstraites peuvent être privées, protégées ou publiques ; les interfaces sont absolument abstraites et ne peuvent pas être instanciées. Une classe abstraite ne peut pas être instanciée, mais elle peut être appelée si elle contient une méthode principale.
Vous pouvez également vous référer à la différence entre les classes abstraites et les interfaces dans JDK8.
10. Que sont le passage par valeur et le passage par référence ?
On pense généralement que le transfert en Java se fait par valeur. Le transfert d'objets d'instance en Java se fait par référence.
Le transfert de valeur concerne les variables de base, et une copie de la variable est transférée. La modification de la copie n'affecte pas la variable d'origine ; le transfert de référence concerne généralement les variables d'objet, et l'objet est transféré. adresse, pas l’objet original lui-même.
11. Quelle est la différence entre un processus et un fil ?
Un processus est une application en cours d'exécution, une forme dynamique du programme et l'unité de base qui occupe des ressources telles que le processeur et la mémoire. De plus, les processus sont indépendants les uns des autres et la communication est difficile lors de l'exécution. un processus, contient des entrées, des séquences d'exécution et des sorties relativement fixes ; un thread est une séquence d'exécution au sein d'un processus et appartient à un certain processus. Un processus peut avoir plusieurs threads qui ne peuvent pas occuper des ressources telles que le processeur et la mémoire, et les threads se partagent. un morceau de mémoire, la communication est plus pratique et la séquence d'exécution des entrées de thread et ces processus sont contrôlés par le programme d'application.
12. Combien y a-t-il de façons différentes de créer un fil de discussion ? Lequel préfères-tu ? Pourquoi?
Il existe quatre façons de créer des fils de discussion.
Héritez la classe Thread ; implémentez l'interface Runnable ; les applications peuvent utiliser le framework Executor pour créer un pool de threads ; implémentez l'interface Callable.
L'implémentation de l'interface Runnable est plus populaire car elle ne nécessite pas d'hériter de la classe Thread. Dans le cas où d'autres objets ont été hérités dans la conception de l'application, cela nécessite un héritage multiple (et Java ne prend pas en charge l'héritage multiple), et seules des interfaces peuvent être implémentées. Dans le même temps, le pool de threads est également très efficace et facile à mettre en œuvre et à utiliser.
13. Expliquez brièvement les différents états disponibles des threads.
Nouveau (nouveau) : Un nouvel objet thread est créé. Exécutable : une fois l'objet thread créé, d'autres threads (tels que le thread principal) appellent la méthode start () de l'objet. Le thread dans cet état se trouve dans le pool de threads exécutables, en attente d'être sélectionné par la planification des threads pour obtenir le droit d'utiliser le processeur. En cours d'exécution : le thread à l'état exécutable obtient la tranche de temps CPU (timeslice) et exécute le code du programme. Blocage (blocage) : l'état de blocage signifie que le thread abandonne le droit d'utiliser le processeur pour une raison quelconque, c'est-à-dire qu'il abandonne la tranche de temps du processeur et arrête temporairement de fonctionner. Jusqu'à ce que le thread entre dans l'état exécutable, il a la possibilité d'obtenir à nouveau la tranche de temps du processeur et de passer à l'état d'exécution. Il existe trois situations de blocage :
(1) En attente de blocage : le thread en cours d'exécution exécute la méthode o.wait () et la JVM placera le thread dans la file d'attente.
(2). Blocage synchrone : lorsqu'un thread en cours d'exécution acquiert le verrou de synchronisation d'un objet, si le verrou de synchronisation est occupé par un autre thread, la JVM placera le thread dans le pool de verrouillage) au milieu.
(3). Autre blocage : lorsqu'un thread en cours d'exécution exécute la méthode Thread.sleep (long ms) ou t.join (), ou qu'une requête d'E/S est émise, la JVM définit le thread sur est en état de blocage. Lorsque l'état sleep () expire, join () attend que le thread se termine ou expire, ou que le traitement des E/S est terminé, le thread revient à l'état exécutable.
Mort (mort) : lorsque l'exécution des méthodes run() et main() du thread se termine, ou que la méthode run() se termine en raison d'une exception, le thread termine son cycle de vie. Les fils morts ne peuvent pas être ressuscités.
14. Quelle est la différence entre les méthodes synchronisées et les blocs de code synchronisés ?
Pourquoi utiliser la synchronisation ?
Java permet le contrôle de la concurrence multithread. Lorsque plusieurs threads exploitent une variable de ressource partageable en même temps (ajouter, supprimer, modifier, vérifier), cela entraînera des données inexactes et des conflits les uns avec les autres. ajouté pour éviter Ce thread est appelé par d'autres threads avant de terminer l'opération, garantissant ainsi l'unicité et l'exactitude de la variable.
Différence
La méthode de synchronisation utilise cet objet de classe ou l'objet de classe actuel comme verrou par défaut ; le bloc de code de synchronisation peut choisir ce qu'il faut verrouiller, ce qui est plus précis que la méthode de synchronisation. Nous pouvons choisir uniquement La synchronisation provoquera des problèmes de synchronisation dans une partie du code plutôt que dans l'ensemble de la méthode ; la méthode de synchronisation utilise le mot-clé synchronisé pour modifier la méthode, et le bloc de code de synchronisation modifie principalement le code qui doit être synchronisé et utilise synchronisé. (objet) {contenu du code} à modifier ;
15. Comment se fait la synchronisation des threads à l'intérieur du moniteur ? Quel niveau de synchronisation le programme doit-il effectuer ?
Les moniteurs et les verrous sont utilisés ensemble dans la machine virtuelle Java. Le moniteur surveille un bloc de code synchronisé pour garantir qu'un seul thread exécute le bloc de code synchronisé à la fois. Chaque moniteur est associé à une référence d'objet. Le thread n'est pas autorisé à exécuter du code synchronisé avant d'acquérir le verrou.
16. Qu’est-ce qu’une impasse ?
La soi-disant impasse fait référence à une impasse (s'attendant les uns les autres) causée par plusieurs processus en compétition pour les ressources. Sans force externe, ces processus ne pourront pas avancer. Quatre conditions nécessaires en cas de blocage :
Condition d'exclusion mutuelle : le processus nécessite un contrôle exclusif des ressources allouées (telles que les imprimantes), c'est-à-dire qu'une certaine ressource n'est occupée que par un seul processus sur une période donnée. À ce stade, si d’autres processus demandent la ressource, le processus demandeur ne peut qu’attendre. Condition de non-privation : les ressources obtenues par un processus ne peuvent pas être retirées de force par d'autres processus avant d'être complètement utilisées, c'est-à-dire qu'elles ne peuvent être libérées que par le processus qui a obtenu les ressources (il ne peut être libéré qu'activement). Conditions de demande et de maintien : Le processus a détenu au moins une ressource, mais a fait une nouvelle demande de ressource et la ressource a été occupée par un autre processus. À ce stade, le processus demandeur est bloqué, mais il conservera les ressources dont il dispose. obtenu. Condition d'attente circulaire : il existe une ==chaîne d'attente cyclique== pour les ressources du processus. Les ressources obtenues par chaque processus de la chaîne sont simultanément demandées par le processus suivant de la chaîne.
17. Comment s'assurer que N threads peuvent accéder à N ressources sans provoquer de blocage ?
Lors de l'utilisation du multi-threading, un moyen très simple d'éviter les blocages est de : ==Spécifier l'ordre dans lequel les verrous sont acquis== et forcer les threads à acquérir les verrous dans l'ordre spécifié. Par conséquent, si tous les threads se verrouillent et libèrent les verrous dans le même ordre, il n’y aura pas de blocage.
18. Quelles sont les interfaces de base du framework de classes de collection Java ?
L'interface de classe de collection spécifie un ensemble d'objets appelés éléments. Chaque classe d'implémentation concrète de l'interface de la classe collection peut choisir de sauvegarder et de trier les éléments à sa manière. Certaines classes de collection autorisent les clés en double, d'autres non.
Les classes de collection Java fournissent un ensemble d'interfaces et de classes bien conçues qui prennent en charge les opérations sur un ensemble d'objets. Les interfaces les plus basiques des classes de collection Java sont :
Collection : représente un groupe d'objets, chaque objet est son élément enfant. Ensemble : collection qui ne contient pas d'éléments en double. Liste : une collection ordonnée pouvant contenir des éléments répétés. Map : un objet qui peut mapper des clés à des valeurs ne peut pas être répété.
19. Pourquoi la classe collection n'implémente-t-elle pas les interfaces Cloneable et Serialisable ?
La sémantique et la signification du clonage ou de la sérialisation sont liées à l'implémentation spécifique. Par conséquent, il appartient à l’implémentation spécifique de la classe de collection de déterminer comment elle est clonée ou sérialisée.
20. Qu'est-ce qu'un itérateur ?
L'interface Iterator fournit de nombreuses méthodes pour itérer sur les éléments de la collection. Chaque classe de collection contient
méthodes d'itération qui renvoient des instances d'itérateur. L'itérateur peut supprimer des éléments de la collection sous-jacente pendant le processus d'itération, mais elle ne peut pas être supprimée directement en appelant
remove(Object Obj) de la collection. Elle peut être supprimée via la méthode remove() de l'itérateur.
21. Quelle est la différence entre Iterator et ListIterator ?
Leurs différences sont répertoriées ci-dessous :
Iterator peut être utilisé pour parcourir les collections Set et List, mais ListIterator ne peut être utilisé que pour parcourir List. Iterator ne peut parcourir une collection que vers l'avant, tandis que ListIterator peut parcourir à la fois vers l'avant et vers l'arrière. ListIterator implémente l'interface Iterator et inclut d'autres fonctions, telles que l'ajout d'éléments, le remplacement d'éléments, l'obtention de l'index des éléments précédents et suivants, etc.
22. Quelle est la différence entre fail-fast et fail-safe ?
La sécurité intégrée de l'Iterator est basée sur la création d'une copie de la collection sous-jacente, elle n'est donc pas affectée par les modifications apportées à la collection source. Toutes les classes de collection du package java.util sont à sécurité intégrée et toutes les classes du package java.util.concurrent sont à sécurité intégrée. Un itérateur à sécurité intégrée lancera une exception ConcurrentModificationException, tandis qu'un itérateur à sécurité intégrée ne lancera jamais une telle exception.
33. Comment fonctionne HashMap en Java ?
HashMap en Java stocke les éléments sous forme de paires clé-valeur. HashMap nécessite une fonction de hachage, qui utilise les méthodes hashCode() et equals() pour ajouter et récupérer des éléments vers/depuis la collection. Lorsque la méthode put() est appelée, HashMap calcule la valeur de hachage de la clé, puis stocke la paire clé-valeur à l'index approprié dans la collection. Si la clé existe déjà, la valeur sera mise à jour avec la nouvelle valeur. Certaines caractéristiques importantes de HashMap sont sa capacité, son facteur de charge et son redimensionnement de seuil.
34. Quelle est l'importance des méthodes hashCode() et equals() ?
HashMap en Java utilise les méthodes hashCode() et equals() pour déterminer l'index de la paire clé-valeur. Ces deux méthodes sont également utilisées pour obtenir la valeur basée sur la clé. Si ces deux méthodes ne sont pas implémentées correctement, deux clés différentes peuvent avoir la même valeur de hachage et peuvent donc être considérées comme égales par la collection. De plus, ces deux méthodes sont également utilisées pour rechercher des éléments en double. Par conséquent, la mise en œuvre de ces deux méthodes est cruciale pour l’exactitude et l’exactitude de HashMap.
35. Quelle est la différence entre HashMap et Hashtable ?
HashMap et Hashtable implémentent tous deux l'interface Map, donc de nombreuses fonctionnalités sont très similaires. Cependant, ils présentent les différences suivantes :
HashMap permet aux clés et aux valeurs d'être nulles, tandis que Hashtable ne permet pas aux clés ou aux valeurs d'être nulles. Hashtable est synchrone, HashMap ne l'est pas. Par conséquent, HashMap est plus adapté aux environnements monothread, tandis que Hashtable convient aux environnements multithread. HashMap fournit une collection de clés sur lesquelles une application peut parcourir, par conséquent, HashMap est rapide. D'un autre côté, Hashtable fournit une énumération de clés. On pense généralement que Hashtable est une classe héritée.
36. Quelle est la différence entre un tableau (Array) et une liste (ArrayList) ? Quand devez-vous utiliser Array au lieu d’ArrayList ?
Array peut contenir des types de base et des types d'objets, et ArrayList ne peut contenir que des types d'objets. La taille de Array est fixe et la taille de ArrayList change dynamiquement. ArrayList fournit plus de méthodes et de fonctionnalités, telles que : addAll(), removeAll(), iterator(), etc. Pour les types de données de base, les collections utilisent le boxing automatique pour réduire les efforts de codage. Cependant, cette approche est relativement lente lorsqu’il s’agit de types de données primitifs de taille fixe.
37. Quelle est la différence entre ArrayList et LinkedList ?
ArrayList et LinkedList implémentent l'interface List. Ils présentent les différences suivantes :
ArrayList est une interface de données basée sur un index et sa couche inférieure est un tableau. Il peut effectuer un accès aléatoire à des éléments avec une complexité temporelle O(1). En conséquence, LinkedList stocke ses données sous la forme == element list ==. Chaque élément est lié à ses éléments précédent et suivant. Dans ce cas, le temps pour trouver un élément est compliqué.
Par rapport à ArrayList, les opérations d'insertion, d'ajout et de suppression de LinkedList sont plus rapides car lorsqu'un élément est ajouté à n'importe quelle position de la collection, il n'est pas nécessaire de recalculer la taille ou de mettre à jour l'index comme un tableau. LinkedList occupe plus de mémoire que ArrayList car LinkedList stocke deux références pour chaque nœud, une pointant vers l'élément précédent et une pointant vers l'élément suivant.
38. À quoi servent les interfaces Comparable et Comparateur ? Énumérez leurs différences.
Java fournit une interface Comparable qui ne contient qu'une seule méthode compareTo(). Cette méthode peut trier deux objets. Plus précisément, il renvoie des nombres négatifs, 0 et positifs pour indiquer que l'objet existant est inférieur, égal ou supérieur à l'objet d'entrée.
Java fournit l'interface Comparator contenant deux méthodes : compare() et equals(). La méthode compare() est utilisée pour trier deux paramètres d'entrée et renvoie un nombre négatif, 0. Un nombre positif indique que le premier paramètre est inférieur, égal ou supérieur au deuxième paramètre. La méthode equals() nécessite un objet comme paramètre, qui est utilisé pour déterminer si le paramètre d'entrée est égal au comparateur. Cette méthode renvoie vrai uniquement si le paramètre d’entrée est également un comparateur et que le résultat du tri du paramètre d’entrée et du comparateur actuel est le même.
Comparable et Comparator sont tous deux utilisés pour réaliser la comparaison et le tri des éléments dans une collection. Cependant, Comparable est un tri implémenté par une méthode définie à l'intérieur de la collection, et Comparator est un tri implémenté en dehors de la collection. si vous souhaitez implémenter le tri, vous devez définir les méthodes de l'interface Comparator en dehors de la collection ou implémenter les méthodes de l'interface Comparable au sein de la collection. Comparator se trouve sous le package java.util et Comparable se trouve sous le package java.lang. Comparable est une interface qui doit être implémentée par un objet lui-même qui prend déjà en charge l'auto-comparaison (comme String et Integer. Il peut compléter). l'opération de comparaison par elle-même et a implémenté l'interface Comparable) Pour trier une classe personnalisée après l'avoir ajoutée au conteneur de liste, vous pouvez implémenter l'interface Comparable lors du tri à l'aide de la méthode de tri de la classe Collections, si vous ne spécifiez pas de Comparator. , alors il sera trié dans l'ordre naturel. L'ordre naturel ici est d'implémenter le paramètre d'interface Comparable certaine méthode de tri.
Le Comparateur est un comparateur dédié. Lorsque l'objet ne prend pas en charge l'auto-comparaison ou que la fonction d'auto-comparaison ne peut pas répondre à vos besoins, vous pouvez écrire un comparateur pour compléter la comparaison de taille entre les deux objets. On peut dire que la différence entre l'un est que la comparaison est effectuée par soi-même et l'autre est que le programme externe implémente la comparaison. L'utilisation de Comparator est un modèle de conception de stratégie, ce qui signifie ne pas modifier l'objet lui-même, mais utiliser un objet de stratégie pour modifier son comportement. Par exemple : si vous souhaitez trier des entiers par taille absolue, Integer ne répond pas aux exigences. Vous n'avez pas besoin de modifier la classe Integer (en fait, vous ne pouvez pas le faire) pour modifier son comportement de tri. Interface Comparator qui implémente l'interface Comparator. Utilisez simplement l'objet pour contrôler son tri.
39. Qu'est-ce que la file d'attente prioritaire Java (file d'attente prioritaire) ?
PriorityQueue est une file d'attente illimitée basée sur un tas prioritaire, et ses éléments sont triés dans l'ordre naturel. Lors de sa création, on peut lui fournir un comparateur chargé de trier les éléments. PriorityQueue n'autorise pas les valeurs nulles car elles n'ont pas d'ordre naturel ou n'ont aucun comparateur associé. Enfin, PriorityQueue n'est pas thread-safe et la complexité temporelle de la mise en file d'attente et du retrait de la file d'attente est O(log(n)).
40. Comprenez-vous la notation grand O ? Pouvez-vous donner des exemples de différentes structures de données ?
La notation Big O décrit la taille de l'algorithme ou une limite supérieure asymptotique lorsque les éléments de la structure de données augmentent.
La notation Big O peut également être utilisée pour décrire d'autres comportements, tels que la consommation de mémoire. Étant donné que les classes de collection sont en réalité des structures de données, nous utilisons généralement la notation Big O pour choisir la meilleure implémentation en fonction du temps, de la mémoire et des performances. La notation Big O peut donner une bonne idée des performances sur de grandes quantités de données.
41.Quelles sont les différences entre l'interface Enumeration et l'interface Iterator ?
L'énumération est 2 fois plus rapide qu'Iterator et prend moins de mémoire. Cependant, Iterator est beaucoup plus sûr que Enumeration car les autres threads ne peuvent pas modifier les objets de la collection parcourus par l'itérateur. Dans le même temps, Iterator permet à l'appelant de supprimer des éléments de la collection sous-jacente, ce qui n'est pas possible avec Enumeration.
42. Quelle est la différence entre HashSet et TreeSet ?
HashSet est implémenté par une table de hachage, ses éléments ne sont donc pas ordonnés. La complexité temporelle des méthodes add(), remove() et contain() est O(1). D'un autre côté, TreeSet est implémenté par une structure arborescente et les éléments qu'elle contient sont ordonnés. Par conséquent, la complexité temporelle des méthodes add(), remove() et contain() est O(logn).
43.Quel est le but du garbage collection en Java ? Quand a lieu la collecte des déchets ?
Le garbage collection est effectué lorsqu'il y a des objets non référencés ou des objets qui dépassent la portée dans la mémoire.
Le but du garbage collection est d'identifier et de supprimer les objets qui ne sont plus utilisés par l'application afin de libérer et de réutiliser les ressources.
44.Que feront System.gc() et Runtime.gc() ?
Ces deux méthodes sont utilisées pour inviter la JVM à effectuer un garbage collection. Cependant, le fait que le garbage collection démarre immédiatement ou soit retardé dépend de la JVM.
45. Quand la méthode finalize() est-elle appelée ? Quel est le but du destructeur (finalisation) ?
Lorsque le garbage collector décide de recycler un objet, il exécutera la méthode finalize() de l'objet. Mais malheureusement en Java, si la mémoire est toujours suffisante, alors le garbage collection peut ne jamais se produire. c'est-à-dire que filalize() peut ne jamais être exécuté. Évidemment, il n'est pas fiable de s'attendre à ce qu'il fasse le travail de finition. Alors, que fait exactement finalize() ? Son objectif principal est de récupérer la mémoire allouée par des canaux spéciaux. Les programmes Java ont des garbage collectors, donc dans des circonstances normales, les programmeurs n'ont pas à se soucier des problèmes de mémoire. Mais il existe un JNI (Java Native Interface) qui appelle un programme non Java (C ou C++), et le travail de finalize() consiste à récupérer cette partie de la mémoire.
Minutage d'appel : lorsque le garbage collector veut déclarer un objet mort, il doit passer par au moins deux processus de marquage : s'il s'avère que l'objet n'a aucune chaîne de référence connectée aux racines GC après une analyse d'accessibilité, il will est marqué pour la première fois et détermine s'il faut exécuter la méthode finalizer(). Si l'objet remplace la méthode finalizer() et n'a pas été appelé par la machine virtuelle, alors l'objet sera placé dans la file d'attente F-Queue. et sera ensuite utilisé par une machine virtuelle. L'exécution de la zone de thread Finalizer de faible priorité créée automatiquement par la machine déclenche la méthode finalizer(), mais ne promet pas d'attendre la fin de son opération.
(Tutoriel recommandé : cours java )
Le but de la finalisation : la dernière chance de l'objet d'échapper à la mort. (Il suffit de le réassocier à n'importe quel objet de la chaîne de référence.) Cependant, son exécution est coûteuse, très incertaine et l'ordre d'appel de chaque objet ne peut pas être garanti. Utilisez try-finally ou d'autres alternatives.
46. Si la référence d'un objet est définie sur null, le garbage collector libérera-t-il immédiatement la mémoire occupée par l'objet ?
Non, cet objet sera recyclable lors du prochain cycle de collecte des déchets.
La mémoire occupée par l'objet ne sera pas libérée immédiatement. Si la référence de l'objet est définie sur null, cela déconnecte uniquement la référence à l'objet dans le cadre de pile de threads actuel, et le garbage collector est un thread exécuté en arrière-plan. Il ne peut être utilisé que lorsque le thread utilisateur s'exécute sur un. point sûr (point sûr) ou coffre-fort La relation de référence d'objet sera analysée uniquement dans la zone. Si l'objet n'est pas référencé, l'objet sera marqué à ce moment, la mémoire de l'objet ne sera pas libérée immédiatement car certains objets sont récupérables. (les références sont restaurées dans la méthode finalize). La mémoire de l'objet ne sera effacée que lorsqu'il sera déterminé que la référence à l'objet ne peut pas être restaurée.
47. Quelle est la structure du tas Java ? Quel est l'espace Perm Gen dans le tas ?
Le tas de la JVM est la zone de données d'exécution, et toutes les instances de classe et tous les tableaux allouent de la mémoire sur le tas. Il est créé au démarrage de la JVM. La mémoire tas occupée par l'objet est récupérée par le système de gestion automatique de la mémoire, c'est-à-dire le garbage collector.
La mémoire tas est composée d'objets vivants et morts. Les objets survivants sont accessibles à l’application et ne seront pas récupérés. Les objets morts sont des objets inaccessibles à l'application et qui n'ont pas encore été récupérés par le garbage collector. Jusqu'à ce que le ramasse-miettes récupère ces objets, ils continueront à occuper de l'espace mémoire tas.
La génération permanente est utilisée pour stocker des fichiers statiques, tels que des classes Java, des méthodes, etc. La génération persistante n'a pas d'impact significatif sur le garbage collection, mais certaines applications peuvent générer ou appeler dynamiquement certaines classes, comme Hibernate, etc. Dans ce cas, un espace de génération persistante relativement grand doit être configuré pour stocker ces classes nouvellement ajoutées pendant opération, en permanence. Le code contient généralement :
Méthodes de la classe (bytecode...)
Nom de la classe (objet Sring)
Informations constantes lues dans le fichier .class
Liste d'objets et liste de types. lié à l'objet de classe (par exemple, un tableau d'objets de méthode).
Objets internes créés par JVM
Informations pour l'optimisation du compilateur JIT
48. Collecteur série et collecteur de débit Quelle est la différence ?
Le collecteur de débit utilise une version parallèle du garbage collector de jeune génération, qui est utilisé pour les applications avec des données de taille moyenne et à grande échelle. Le collecteur série est suffisant pour la plupart des petites applications (qui nécessitent environ 100 Mo de mémoire sur les processeurs modernes).
49. En Java, quand les objets peuvent-ils être récupérés ?
Lorsqu'un objet est inaccessible depuis GC Roots, il essaiera de recycler l'objet lors du prochain cycle de récupération de place si l'objet remplace la méthode finalize() et s'enregistre avec succès dans cette méthode (en s'attribuant à quelqu'un). référence), alors l’objet ne sera pas recyclé. Mais si l'objet ne remplace pas la méthode finalize() ou a déjà exécuté cette méthode et ne parvient pas à se sauvegarder, l'objet sera recyclé.
50. Le garbage collection aura-t-il lieu dans la génération permanente de la JVM ?
Le garbage collection n'aura pas lieu dans la génération permanente. Si la génération permanente est pleine ou dépasse la valeur critique, un garbage collection complet (Full GC) sera déclenché. Si vous regardez attentivement la sortie du garbage collector, vous verrez que la génération permanente est également collectée. C'est pourquoi la taille correcte de la génération permanente est très importante pour éviter le Full GC. Veuillez vous référer à Java8 : De la génération permanente à la zone de métadonnées
(Remarque : la génération permanente a été supprimée dans Java8 et une nouvelle zone de mémoire native appelée zone de métadonnées a été ajoutée)
51. Java Que sont les deux types d'exceptions de ? Quelle est la différence entre eux ?
Il existe deux types d'exceptions en Java : les exceptions vérifiées et les exceptions non vérifiées. Les exceptions non contrôlées n'ont pas besoin d'être déclarées sur une méthode ou un constructeur, même si l'exécution de la méthode ou du constructeur peut lever une telle exception, et les exceptions non contrôlées peuvent se propager en dehors de la méthode ou du constructeur. Au lieu de cela, les exceptions vérifiées doivent être déclarées sur la méthode ou le constructeur à l'aide de l'instruction throws. Voici quelques conseils pour la gestion des exceptions Java.
Throwable inclut les erreurs (Error) et les exceptions (Excetion)
Exception inclut également les exceptions d'exécution (RuntimeException, également appelées exceptions non vérifiées) et les exceptions non-exécutables (également appelées exceptions vérifiées)
(1) L'erreur signifie que le programme ne peut pas la gérer. Si OutOfMemoryError, etc., lorsque ces exceptions se produisent, la machine virtuelle Java mettra généralement fin au thread
(2) Les exceptions d'exécution sont toutes les classes RuntimeException et leurs sous-classes, telles que NullPointerException. , IndexOutOfBoundsException, etc. Ces exceptions sont des exceptions non vérifiées qui peuvent se produire lorsque le programme est en cours d'exécution, de sorte que le programme peut ou non les détecter. Ces erreurs sont généralement causées par des erreurs logiques dans le programme, et le programme doit démarrer d'un point de vue logique. . Essayez de l'éviter autant que possible.
(3) Les exceptions vérifiées sont des exceptions autres que les exceptions d'exécution, et sont également des exceptions et ses sous-classes. Du point de vue du programme, ces exceptions doivent être interceptées et vérifiées, sinon elles ne peuvent pas passer. compilation. Tels que IOException, SQLException, etc.
52. Quelle est la différence entre une exception et une erreur en Java ?
Exception et Error sont toutes deux des sous-classes de Throwable. L'exception est utilisée pour les exceptions qui peuvent être interceptées par les programmes utilisateur. Erreur définit les exceptions qui ne devraient pas être interceptées par les programmes utilisateur.
53. Quelle est la différence entre lancer et lancer ?
Le mot-clé throw est utilisé pour lancer explicitement des exceptions dans le programme. Au contraire, l'instruction throws est utilisée pour indiquer les exceptions que la méthode ne peut pas gérer. Chaque méthode doit spécifier quelles exceptions ne peuvent pas être gérées, afin que l'appelant de la méthode puisse garantir que les exceptions possibles sont gérées. Plusieurs exceptions sont séparées par des virgules.
1. Throw est utilisé à l'intérieur de la méthode, et Throws est utilisé dans la déclaration de la méthode ;
2. Throw est suivi de l'objet d'exception et Throws est suivi du type d'exception ; .Throw ne peut être suivi que d'un seul objet d'exception. Plusieurs types d'exception peuvent être déclarés à la fois après Throws.
Init : Elle sera initialisée à chaque chargement.
Démarrer : démarrez l'exécution de l'applet.
Stop : Terminer l'exécution de l'applet.
Détruire : effectuez le nettoyage final avant de désinstaller l'applet.
58. Que se passe-t-il lorsque l'applet est chargée ?
Tout d'abord, créez une instance de la classe de contrôle d'applet, puis initialisez l'applet et enfin commencez à l'exécuter.
59. Quelle est la différence entre les applets et les applications Java ordinaires ?
L'applet s'exécute dans un navigateur compatible Java. Les applications Java sont des programmes Java indépendants qui peuvent s'exécuter en dehors du navigateur. Cependant, ils nécessitent tous une machine virtuelle Java.
De plus, une application Java nécessite une fonction principale avec une signature de méthode spécifique pour démarrer l'exécution. Les applets Java ne nécessitent pas une telle fonction pour démarrer l'exécution.
Enfin, les applets Java utilisent généralement des politiques de sécurité très strictes, et les applications Java utilisent généralement des politiques de sécurité plus souples.
60. Quelles sont les restrictions sur les applets Java ?
Principalement pour des raisons de sécurité, les restrictions suivantes sont imposées à l'applet :
l'applet ne peut pas charger des bibliothèques de classes ou définir des méthodes locales ; ne peut pas lire et écrire des fichiers sur l'hôte ; ne peut pas lire des propriétés système spécifiques ; connexions réseau sauf avec l'hôte ; ne peut démarrer aucun autre programme sur l'hôte.
61. Qu'est-ce qu'une applet non fiable ?
Les applets non fiables sont des applets Java qui ne peuvent pas accéder ou exécuter les fichiers du système local. Par défaut, toutes les applets téléchargées ne sont pas fiables.
62. Quelle est la différence entre une applet chargée depuis le réseau et une applet chargée depuis le système de fichiers local ?
Lorsqu'une applet est chargée depuis le réseau, l'applet est chargée par le chargeur de classe d'applet, qui est restreint par le gestionnaire de sécurité de l'applet.
Lorsque l'applet est chargée depuis le disque local du client, l'applet est chargée par le chargeur du système de fichiers.
L'applet chargée à partir du système de fichiers permet de lire des fichiers, d'écrire des fichiers, de charger des bibliothèques de classes sur le client, et permet également d'exécuter d'autres programmes, mais elle ne peut pas passer la vérification du bytecode.
63. Qu'est-ce qu'un chargeur de classe d'applet ? Que fera-t-il ?
Lorsqu'une applet est chargée depuis le réseau, elle est chargée par le chargeur de classe d'applet. Les chargeurs de classes ont leur propre hiérarchie d'espaces de noms Java. Le chargeur de classes garantira que les classes du système de fichiers ont un espace de noms unique et que les classes des ressources réseau ont un espace de noms unique.
Lorsqu'un navigateur charge une applet sur le réseau, la classe de l'applet est placée dans un espace de noms privé associé à la source de l'applet. Ensuite, les classes chargées par le chargeur de classes sont vérifiées par le validateur. Le validateur vérifie si le format de fichier de classe est conforme à la spécification du langage Java pour garantir qu'aucun débordement ou sous-débordement de pile ne se produit et que les paramètres transmis aux instructions de bytecode sont corrects.
64. Qu'est-ce que le gestionnaire de sécurité de l'applet ? Que fera-t-il ?
Le gestionnaire de sécurité des applets est un mécanisme permettant d'imposer des restrictions sur les applets. Un navigateur ne peut avoir qu'un seul gestionnaire de sécurité. Le gestionnaire de sécurité est créé au démarrage et ne peut pas être remplacé ou étendu ultérieurement.
65. Quelle est la différence entre le menu de sélection contextuel (Choice) et la liste (List) ?
Le choix est affiché sous une forme compacte et vous devez faire défiler vers le bas pour voir toutes les options. Une seule option peut être sélectionnée à la fois dans Choice. La liste peut avoir plusieurs éléments visibles en même temps et prend en charge la sélection d'un ou plusieurs éléments.
66. Qu'est-ce qu'un gestionnaire de mise en page ?
Les gestionnaires de mise en page sont utilisés pour organiser les composants dans des conteneurs.
67. Quelle est la différence entre une barre de défilement (Scrollbar) et un panneau de défilement (JScrollPane) ?
La barre de défilement est un composant, pas un conteneur. Et ScrollPane est un conteneur. ScrollPane gère lui-même les événements de défilement.
68. Quelles méthodes Swing sont thread-safe ?
Il n'existe que 3 méthodes thread-safe : repaint(), revalidate() et invalidate().
69. Nommez trois composants qui permettent de repeindre.
Canvas, Frame, Panel et Applet prennent en charge le redessin.
70. Qu'est-ce que JDBC ?
JDBC est une couche d'abstraction qui permet aux utilisateurs de choisir entre différentes bases de données. JDBC permet aux développeurs d'écrire des applications de base de données en JAVA sans avoir à se soucier des détails de la base de données spécifique sous-jacente.
JDBC (Java DataBase Connectivity) est un ensemble d'interfaces de programmation d'applications (API) orientées objet. Il formule une interface standard unifiée pour accéder à diverses bases de données relationnelles et fournit des implémentations standard pour divers fabricants de bases de données. Grâce à la technologie JDBC, les développeurs peuvent écrire des applications de base de données complètes en utilisant un langage Java pur et des instructions SQL standard, et pleinement prendre conscience de la nature multiplateforme du logiciel.
Habituellement, JDBC est utilisé pour effectuer les opérations suivantes :
1. Établir une connexion avec la base de données ;
2. Envoyer les instructions SQL à la base de données ;
3.
JDBC présente les avantages suivants :
1. JDBC est très similaire à ODBC (Open Database Connectivity, c'est-à-dire une interconnexion de base de données ouverte), ce qui est facile à comprendre pour les développeurs de logiciels
2. JDBC libère les logiciels ; les développeurs de l'écriture complexe des pilotes peuvent se concentrer entièrement sur le développement de la logique métier ;
3. JDBC prend en charge une variété de bases de données relationnelles, ce qui augmente considérablement la portabilité du logiciel.
4. et les développeurs de logiciels peuvent utiliser la méthode couramment utilisée pour améliorer la réutilisabilité du code
71. Que signifie le pool de connexions à la base de données ?
Les interactions avec la base de données telles que l'ouverture et la fermeture des connexions à la base de données peuvent prendre du temps, surtout lorsque le nombre de clients augmente, cela consommera beaucoup de ressources et le coût est très élevé. De nombreuses connexions à la base de données peuvent être établies et maintenues dans un pool au démarrage du serveur d'applications. Les demandes de connexion sont servies à partir des connexions du pool. Une fois la connexion épuisée, elle est renvoyée au pool pour être utilisée pour satisfaire davantage de demandes à l'avenir.
72. Quelles sont les étapes pour que le programme RMI fonctionne correctement ?
Pour que le programme RMI fonctionne correctement, les étapes suivantes doivent être incluses :
Compilez tous les fichiers sources.
Utilisez rmic pour générer un stub.
Démarrez rmiregistry.
Démarrez le serveur RMI.
Exécutez le programme client.
73. Expliquez le marshalling et le démarshalling.
Lorsqu'une application souhaite transférer un objet mémoire à travers le réseau vers un autre hôte ou le conserver dans le stockage, elle doit convertir la représentation de l'objet en mémoire dans un format approprié. Ce processus s'appelle Marshalling, et l'inverse est démarshalling.
74. Expliquez la sérialisation et la désérialisation.
Java fournit un mécanisme appelé sérialisation d'objet, qui représente l'objet sous la forme d'une série d'octets, qui contient les données de l'objet, les informations de type de l'objet, les informations de type des données à l'intérieur de l'objet, etc. La sérialisation peut donc être considérée comme un moyen d’aplatir des objets afin de les stocker sur disque ou de les lire depuis le disque et de les reconstruire. La désérialisation est l'étape inverse de la conversion d'un objet d'un état plat en un objet actif.
75. Qu'est-ce que le Servlet ?
Servlet est une classe Java utilisée pour gérer les requêtes des clients et générer du contenu Web dynamique. Le servlet est principalement utilisé pour traiter ou stocker les données soumises par les formulaires HTML, générer du contenu dynamique et gérer les informations d'état sous le protocole HTTP sans état.
76. Parlons de l’architecture de Servlet.
L'interface principale que tous les servlets doivent implémenter est javax.servlet.Servlet. Chaque servlet doit implémenter directement ou indirectement cette interface, ou hériter de javax.servlet.GenericServlet ou javax.servlet.http.HTTPServlet. Enfin, les servlets utilisent plusieurs threads pour répondre à plusieurs requêtes en parallèle.
77. Qu'est-ce qu'une application web ?
Les applications Web sont des extensions dynamiques du Web ou des serveurs d'applications. Il existe deux types d'applications Web : orientées présentation et orientées services. Les applications Web orientées présentation génèrent des pages Web interactives contenant une variété de langages de balisage et de contenu dynamique en réponse aux demandes. Les applications Web orientées services implémentent les points de terminaison des services Web. De manière générale, une application Web peut être considérée comme un ensemble de servlets installés sous un sous-ensemble spécifique de l'espace de noms URL du serveur.
78. Comment savoir quelle machine client demande votre Servlet ?
La classe ServletRequest peut connaître l'adresse IP ou le nom d'hôte de la machine client. La méthode getRemoteAddr() obtient l'adresse IP de l'hôte client et getRemoteHost() obtient le nom d'hôte.
79. Quelle est la structure de la réponse HTTP ?
La réponse HTTP se compose de trois parties :
Code d'état : décrit l'état de la réponse. Peut être utilisé pour vérifier si la demande a été complétée avec succès. En cas d'échec d'une demande, le code d'état peut être utilisé pour connaître la raison de l'échec. Si le servlet ne renvoie pas de code d'état, le code d'état réussi HttpServletResponse.SC_OK sera renvoyé par défaut.
En-tête HTTP : ils contiennent plus d’informations sur la réponse. Par exemple, l'en-tête peut spécifier une date d'expiration à laquelle la réponse est considérée comme expirée, ou il peut spécifier un format de codage utilisé pour transmettre en toute sécurité le contenu de l'entité à l'utilisateur. Comment récupérer les en-têtes HTTP dans Serlet, voir ici.
Corps : Il contient le contenu de la réponse. Il peut contenir du code HTML, des images, etc. Le corps est constitué des octets de données transmis dans le message HTTP immédiatement après l'en-tête.
80. Que sont les cookies ? Quelle est la différence entre session et cookie ?
Un cookie est une information envoyée par le serveur web au navigateur. Le navigateur stocke les cookies dans des fichiers locaux pour chaque serveur Web. À l'avenir, lorsque le navigateur enverra une requête à un serveur Web spécifique, il enverra également tous les cookies stockés pour ce serveur. La différence entre session et cookie est répertoriée ci-dessous :
Quels que soient les paramètres définis par le navigateur client, la session devrait fonctionner normalement. Le client peut choisir de désactiver les cookies, mais la session fonctionnera toujours car le client ne peut pas désactiver la session côté serveur.
La session et les cookies sont également différents en termes de quantité de données stockées. La session peut stocker n'importe quel objet Java et le cookie ne peut stocker que des objets de type String.
81. Comment les requêtes JSP sont-elles traitées ?
Le navigateur demande d'abord une page se terminant par l'extension .jsp et initie une requête JSP. Ensuite, le serveur Web lit la requête et utilise un compilateur JSP pour convertir la page JSP en classe Servlet. Il convient de noter que le fichier JSP ne sera compilé que lorsque la page est demandée pour la première fois ou lorsque le fichier JSP change, puis que le serveur appelle la classe servlet pour gérer la requête du navigateur. Une fois l'exécution de la requête terminée, la servlet enverra la réponse au client.
82. Quels sont les définitions et les avantages de l’encapsulation ?
L'encapsulation offre aux objets la possibilité de masquer des caractéristiques et des comportements internes. Un objet fournit des méthodes accessibles par d'autres objets pour modifier ses données internes. En Java, il existe trois modificateurs : public, privé et protégé. Chaque modificateur donne des droits d'accès différents à d'autres objets situés dans le même package ou dans des packages différents.
Vous trouverez ci-dessous quelques-uns des avantages de l'utilisation de l'encapsulation :
Protégez l'état à l'intérieur d'un objet en masquant ses propriétés.
Améliore la convivialité et la maintenabilité du code car le comportement des objets peut être modifié ou étendu individuellement.
Interdire les interactions indésirables entre les objets améliore la modularité.
Référez-vous à ce document pour plus de détails et d'exemples sur l'encapsulation.
ou :
Tout d'abord, utilisez private pour isoler les détails de la classe du monde extérieur, masquant ainsi les éléments de données et les méthodes. Le seul moyen d'accéder à ces éléments de données et méthodes est via. la classe À elle seule, une classe est éligible pour appeler les ressources qu'elle possède (méthodes, attributs de données, etc.). Le premier avantage est donc que la sécurité des données est améliorée.
La seconde consiste à utiliser une isolation cachée, qui permet uniquement un accès externe limité à la classe. Les développeurs peuvent librement modifier l'implémentation interne de la classe sans modifier les programmes qui utilisent la classe. Tant que les méthodes qui peuvent être appelées en dehors de la classe conservent leurs caractéristiques externes inchangées, le code interne peut être modifié librement pour répondre à leurs besoins, ce qui facilite la division du travail.
La troisième consiste à améliorer la réutilisabilité du code. Après avoir été encapsulé dans des classes d'outils, de nombreuses étapes fastidieuses peuvent être réduites.
83. Quelle est la définition de l’abstraction ? Quelle est la différence entre l'abstraction et l'encapsulation ?
L'abstraction est l'étape qui consiste à séparer les idées des instances concrètes, créant ainsi des classes basées sur leur fonctionnalité plutôt que sur les détails de mise en œuvre. Java prend en charge la création de classes abstraites qui exposent uniquement les interfaces mais ne contiennent pas d'implémentations de méthodes. L’objectif principal de cette technique d’abstraction est de séparer le comportement de la classe des détails d’implémentation. L'abstraction et l'encapsulation sont des concepts complémentaires. D'une part, l'abstraction se concentre sur le comportement des objets. L'encapsulation, quant à elle, se concentre sur les détails du comportement d'un objet. L'encapsulation est généralement réalisée en masquant les informations d'état interne de l'objet. Par conséquent, l'encapsulation peut être considérée comme une stratégie utilisée pour fournir une abstraction.
Recommandations associées : Démarrez avec Java
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!