Maison  >  Article  >  Java  >  Partagez quelques questions d'entretien de base sur Java

Partagez quelques questions d'entretien de base sur Java

零下一度
零下一度original
2017-06-23 09:30:431372parcourir

1.Où enregistrer les données

Registre, pile, tas, stockage statique, stockage constant (pool constant String a = "abc" a est sur la pile, "abc" est dans le pool constant), non-RAM stockage

2.Le type de données de base

est automatiquement initialisé en tant que membre de la classe à la valeur par défaut

booléen 1bit Par défautfaux

octet 8bits un octetu0000

caractère 16 bits Un caractère 0

court 16bits 0

int 32bits 0

flotteur 32bits 0.0f

long 64bits 0L

double 64bits 0.0d

3.Classe numérique de haute précision

BigInteger, Bigdecimal Haute précision, vitesse lente

4.javaTraitement des déchets

Java dispose d'un "garbage collector" spécial qui recherche tous les objets créés avec new et identifie lesquels d'entre eux sont ne soit plus cité. Il libère ensuite automatiquement la mémoire occupée par ces objets inactifs afin qu'elle puisse être utilisée par de nouveaux objets.

5.statiqueOrdre d'exécution

Classe parent variables membres statiques et instruction statique

variables membres statiques de la sous-classe et instruction statique

variable membre non statique de la classe parent et ne sont pas statiques bloc d'instructions

Méthode constructeur de la classe parent

variables

membres statiques des 🎜> sous-classes et des blocs d'instructions non statiques

Méthode constructeur de sous-classe

(statique n'est exécutée qu'une seule fois. La première fois nouveau )

6.Classe de collecte

Vector est un tableau qui se développera automatiquement. Il a une efficacité de requête élevée, une faible efficacité d'ajout et de suppression, une sécurité des threads, une vitesse lente et double la taille d'origine.

ArrayList agrandira automatiquement le tableau, avec une efficacité de requête élevée, une faible efficacité d'ajout et de suppression, un thread dangereux, une vitesse rapide et la croissance sera l'original 0,5 fois.

LinkedList Liste chaînée circulaire bidirectionnelle, faible efficacité des requêtes, efficacité élevée d'ajout et de suppression, thread dangereux.

HashMap est un hachage de liste chaînée, qui est une combinaison d'un tableau et d'une liste chaînée. Il autorise les valeurs nulles, ce qui est. thread-safe et très efficace.

TreeMap est implémenté comme un arbre trié binaire, en utilisant Key pour le tri.

LinkedHashMap est implémenté pour les tables de hachage et les listes liées. C'est une sous-classe de HashMap. si nécessaire. L'ordre est le même que l'entrée, puis utilisez LinkedHashMap.

Hashtable est thread-safe, inefficace et n'autorise pas les valeurs null.

Set n'est pas répétable :

TreeSet est implémenté sur la base de TreeMap et est commandé Oui, thread-dangereux.

HashSet est implémenté sur la base de HashMap, HashMap clé .

LinkedHashSet est implémenté sur la base de LinkedHashMap et est ordonné.

7. Traversée de la carte

Utilisez EntrySet pour parcourir Mapper la collection de classes KV au lieu de la méthode keySet pour la traversée.
Explication : keySet traverse en fait 2 fois, une fois converti en Itérateur objet, l'autre fois est de retirer la valeur correspondant à la
clé du hashMap >. Et entrySet n'a traversé qu'une seule fois et a mis les deux clé et valeur l'entrée a une efficacité supérieure
. S'il s'agit de JDK8, utilisez la méthode Map.foreach .
Exemple positif : values() renvoie l'ensemble de valeurs V , qui est une liste set object ; keySet() renvoie l'ensemble de valeurs K , qui est
Un objet de collection Set  ; entrySet() renvoie une collection de combinaisons de valeurs K-V .

1, entrySet implémente l'interface Set, qui stocke les paires clé-valeur. Un K correspond à un V.
2, une méthode utilisée pour parcourir la carte.
Set> .println(entry.getKey()+","+entry.getValue());
}

Obtenir
KgetKey() >, getValue obtient V. 3, et l'autre est

keySet. Set set = map.keySet(); for (String s:set) { System.out.println(s+","+map.get(s)) ;
>


2.

IOSystème

Flux de pont :

InputStreamReader

Convertir le flux d'octets en flux de caractères. (Lire tel que converti en flux de caractères)

OutputStreamWriterConvertir le flux de caractères en flux d'octets (Écrire tel que converti en flux d'octets)

Classification des fluxNode StreamFileInputStreamFileOutStreamFileReaderFileWriterValeur d'accèsByteArrayInputStreamByteArrayOutStreamCharArrayReaderCharArrayWriterPipepedInputStreamFlux tamponné

Classification des utilisations

Flux d'entrée d'octets

Flux de sortie d'octets

Flux d'entrée de caractères

Flux de sortie de personnages

Classe de base abstraite

InputStream

OutputStream

Lecteur

Écrivain

Fichier d'accès

PipedOutStream

PipedReader

PipedWriter

Chaîne d'accès

StringReader

StringWriter

Flux de traitement

BufferedInputStream

BufferedOutputStream

BufferedReader

BufferedWriter

Convertir le flux

InputStreamReader

OutputStreamWriter

Flux d'objets

ObjectInputStream

ObjectOutputStream

Classe de base abstraite (filtrage)

FilterInputStream

FilterOutputStream

FilterReader

FilterWriter

PrintStream

PrintStream

PrintWriter

Pushback InputStream

PushbackInputStream

PushbackReader

Flux spécial

DataInputStream

DataOutputStream

1. Java IO adopte le mode de décoration, qui utilise des flux de traitement pour envelopper les flux de nœuds afin d'obtenir la polyvalence du code.

2.Comment distinguer le flux de traitement et le flux de nœuds. Le flux de nœuds nécessite une source de données (fichier, réseau) comme paramètre lors de la création d'une nouvelle, tandis que le flux de traitement nécessite un flux de nœuds. comme paramètre.

3.La fonction du flux de traitement est d'améliorer la polyvalence du code, la commodité d'écrire du code et d'améliorer les performances.

4.Les flux de nœuds sont toutes des classes d'implémentation correspondant à la classe de base abstraite, et ils implémentent tous les méthodes de lecture et d'écriture de base de la classe de base abstraite. Parmi eux, si la méthode read() renvoie -1, cela signifie que la fin de la source de données a été lue.

1. Diagramme de trame du flux d'entrée en octets

Ce qui suit est un diagramme de trame du flux d'entrée en octets.

De là, nous pouvons le voir.
(01) InputStream est une superclasse pour les flux d'entrée en octets. InputStream fournit l'interface read() pour lire les données d'octets du flux d'entrée.
(02) ByteArrayInputStream est un flux d'entrée de tableau d'octets. Il contient un tampon interne qui contient les octets lus à partir du flux ; en termes simples, son tampon interne est un tableau d'octets, et l'essence de ByteArrayInputStream Ceci est réalisé grâce à des tableaux d'octets.
(03) PipedInputStream est un flux d'entrée de pipeline. Il est utilisé avec PipedOutputStream pour réaliser une communication pipeline entre plusieurs threads.
(04) FilterInputStream est un flux d'entrée de filtre. C'est la superclasse de DataInputStream et BufferedInputStream.
(05) DataInputStream est un flux d'entrée de données. Il est utilisé pour décorer d'autres flux d'entrée, ce qui "permet aux applications de lire les types de données de base Java à partir du flux d'entrée sous-jacent d'une manière indépendante de la machine".
(06) BufferedInputStream est un flux d'entrée mis en mémoire tampon. Ce qu'il fait, c'est ajouter une fonctionnalité de mise en mémoire tampon à un autre flux d'entrée.
(07) Fichier est une représentation abstraite de "fichier" et de "chemin d'accès au répertoire". Concernant Fichier, veuillez noter deux points :
a), Fichier représente non seulement un fichier, il peut aussi représenter un répertoire !
b), File est défini dans io, mais sa super classe est Object , à la place de InputStream.
(08) FileDescriptor est un "descripteur de fichier". Il peut être utilisé pour représenter des fichiers ouverts, des sockets ouverts, etc.
(09) FileInputStream est un flux d'entrée de fichier. Il est généralement utilisé pour les opérations de lecture sur les fichiers.
(10) ObjectInputStream est un flux d'entrée d'objet. Il est utilisé avec ObjectOutputStream pour fournir un stockage persistant de « données ou objets de base ».


2. Diagramme de trame du flux de sortie en octets

Ce qui suit est la trame du flux de sortie en octets.

De là, nous pouvons le voir. La classe parent commune pour les flux de sortie en octets est OutputStream.
(01) OutputStream est une superclasse pour les flux de sortie en octets. OutputStream fournit l'interface write() pour lire les données d'octets du flux de sortie.
(02) ByteArrayOutputStream est un flux de sortie de tableau d'octets. Les données écrites dans ByteArrayOutputStream sont écrites dans un tableau octet . Le tampon augmentera automatiquement à mesure que les données sont écrites en continu. Les données peuvent être obtenues en utilisant toByteArray() et toString() .
(03) PipedOutputStream est un flux de sortie de pipeline. Il est utilisé avec PipedInputStream pour réaliser une communication pipeline entre plusieurs threads.
(04) FilterOutputStream est le flux de sortie du filtre. C'est la superclasse de DataOutputStream, BufferedOutputStream et PrintStream.
(05) DataOutputStream est le flux de sortie de données. Il est utilisé pour décorer d'autres flux de sortie, ce qui "permet aux applications d'écrire dans les types de données Java sous-jacents d'une manière indépendante de la machine".
(06) BufferedOutputStream est un flux de sortie mis en mémoire tampon. Ce qu'il fait, c'est ajouter une fonctionnalité de mise en mémoire tampon à un autre flux de sortie.
(07) PrintStream est le flux de sortie d'impression. Il est utilisé pour décorer d'autres flux de sortie et ajouter des fonctionnalités à d'autres flux de sortie afin qu'ils puissent facilement imprimer diverses représentations de valeurs de données.
(08) FileOutputStream est un flux de sortie de fichier. Il est généralement utilisé pour écrire dans des fichiers.
(09) ObjectOutputStream est un flux de sortie d'objet. Il est utilisé avec ObjectInputStream pour fournir un stockage persistant de « données ou objets de base ».

3. Multi-threading

Cycle de vie

Les threads incluent les 5 états suivants.
1. Nouvel état(Nouveau) : Une fois l'objet thread créé, il entre dans le nouvel état. Par exemple, Thread thread = new Thread().
2. État prêt (Runnable) : est également appelé "état exécutable". Une fois l'objet thread créé, d'autres threads appellent la méthode start() de l'objet pour démarrer le thread. Par exemple, thread.start(). Les threads à l'état prêt peuvent être programmés pour être exécutés par le CPU à tout moment.
3. État d'exécution(En cours d'exécution) : Le thread obtient les autorisations CPU pour s'exécuter. Il convient de noter qu’un thread ne peut entrer dans l’état d’exécution qu’à partir de l’état prêt.
4. État bloqué(Bloqué) : L'état bloqué est lorsque le thread abandonne pour une raison quelconque CPUDroit d'utilisation, temporairement suspendu. Jusqu'à ce que le thread entre dans l'état prêt, il a une chance de passer à l'état en cours d'exécution. Il existe trois situations de blocage :
(01) En attente de blocage-- En appelant le wait()Méthode pour laisser le fil attendre la fin d'un certain travail.
(02) Blocage de la synchronisation-- Le thread n'a pas réussi à acquérir synchroniséverrouillage de synchronisation (Parce que le verrou est occupé par d'autres threads ), il entrera dans l'état de blocage synchrone.
(03) Autre blocage-- en appelant le sleep() ou join() ou lorsqu'une requête E/S est émise, le thread entrera dans l'état de blocage. Lorsque le statut sleep() expire, join() attend que le thread se termine ou expire, ou E/S Lorsque le traitement est terminé, le thread revient à l'état prêt.
5. État de mort(Dead) : Le thread a terminé son exécution ou s'est arrêté en raison d'une exceptionrun() méthode, le fil termine son cycle de vie .

2. Explication de la différence entre start() et run()

// HériteThread

class MyThread étend le fil{

public void run(){

...

}

};

MyThread mythread = new MyThread();

//implémentationRunnable

classe MyThread implémente Runnable{

public void run(){

...

}

};

MyThread mt=new MonThread( );

Sujet t1=nouveau Sujet(mt);

mythread.start() démarrera un nouveau fil et exécutera la méthode run() dans le nouveau fil.
et mythread.run() exécuteront directement la méthode run() dans le fil de discussion actuel et ne le démarreront pas . Un nouveau fil de discussion pour exécuter run().

3.synchronisé

Nous résumons les règles de base de synchronisé comme ci-dessous3 éléments et illustrez-les avec des exemples.
Article 1 : Quand un fil de discussion accède à "un certain objet""méthodesynchronisée" ou "synchroniséebloc de code " " >"méthodesynchronisée" ou "synchroniséebloc de code " L'accès à sera bloqué. Article 2 : Quand un fil de discussion accède à "un certain objet"
"méthodesynchronisée" ou "synchroniséebloc de code ", d'autres threads peuvent toujours accéder au bloc de code asynchrone de l'objet " " . Article 3 : Quand un fil de discussion accède à "un certain objet"
"méthodesynchronisée" ou "synchroniséebloc de code ", d'autres fils de discussion ont d'autres "méthode synchronisée" ou " synchronisébloc de code"L'accès à sera bloqué.

4.wait(), notify(), notifyAll()

notify()-- Réveillez-vous et attendez sur ce moniteur d'objet d'un seul fil.
notifyAll()-- Réveillez tous les threads en attente sur ce moniteur d'objets.
wait()-- Laisser le fil de discussion actuel en "En attente(Blocage)Statut", " jusqu'à ce qu'un autre fil appelle le méthode notify() ou notifyAll() méthode , le fil de discussion actuel est réveillé (Entrez "État prêt"). attendre (long délai d'attente)--
Laisser le fil de discussion actuel être en "attendre(blocage )Statut ", " jusqu'à ce que d'autres threads appellent le de cet objet notify() méthode ou notifyAll() , ou dépasse la durée spécifiée , Le fil de discussion actuel est réveillé ( et entre "État Prêt "). attendre (long timeout, int nanos)--
Laisser le fil de discussion actuel dans "En attente( Bloque ) statut ", " jusqu'à ce qu'un autre fil appelle cet objet notify() méthode ou notifyAll() , ou un autre thread interrompt le thread en cours, ou un certain temps s'est écoulé écoulé ", le fil de discussion en cours est réveillé(entre "état prêt ”).

5.

yield()Introduction

yield()

La fonction de est une concession. Il permet au fil de discussion actuel d'entrer de "État en cours d'exécution" à " Statut prêt , permettant ainsi à d'autres threads en attente avec la même priorité d'obtenir les droits d'exécution, cependant, il n'y a aucune garantie que yield() soit appelé sur le thread actuel. Après , d'autres threads avec la même priorité pourront certainement obtenir les droits d'exécution ; il est également possible que le thread actuel soit entré dans le " ; État de fonctionnement"Continuez à courir !

6.sleep()Introduction

sleep() est défini dans Thread.java milieu.
sleep() est utilisé pour mettre le thread actuel en veille, c'est-à-dire que le thread actuel entrera à partir de "État d'exécution " à "Hibernation(Blocage)Statut". sleep() spécifiera le temps de sommeil, et le temps de sommeil du fil sera supérieur à / égal au temps de sommeil quand ; le fil est à nouveau réveillé, il passera de "État bloqué" à "État prêt" , attendant ainsi l'exécution programmée de cpu.

Nous savons que la fonction de wait() est de faire exécuter le thread actuel par "état d'exécution "Entrer"Attendez(Blocage)Status libérera également le verrou de synchronisation. La fonction de sleep() est également de faire passer le fil de discussion actuel de «état d'exécution»Entrez "Veille prolongée(Bloqué)État.
Cependant, wait() libérera le verrou de synchronisation de l'objet, tandis que sleep() ne libérera pas le verrou .
L'exemple suivant démontre que sleep() ne libérera pas le verrou.

Nous savons que la fonction de wait() est de faire entrer le fil de discussion actuel "État d'exécution" >"En attente(Blocage)Statut" en même temps, le verrou de synchronisation sera également libéré. La fonction de yield() est une concession, elle fera également quitter le fil de discussion actuel "Statut d'exécution " . La différence entre eux est la suivante : (01) wait()
permet au thread d'être exécuté par "running status" Entrez "En attente(Bloqué)Statut", et yield() consiste à laisser le fil s'exécuter par ""Entrez "État prêt". (02) wait()
amènera le thread à libérer le verrou de synchronisation de l'objet qu'il détient, tandis que la méthode yield() ne le fera pas relâchez le verrou.

7.

join()Introduction

join()

est défini dans Thread. java dans. join() Le rôle de
 : laisser " fil principal " attendre "Sous-thread " peut continuer à s'exécuter après sa fin. Cette phrase est peut-être un peu obscure, mais on la comprend quand même à travers des exemples :

//

Main Threadclass public Father extends Thread {

public void run() {

Son s = new Son();

s.start();

s.join();

...

}

}//

Fils filsclasse publique Le fils étend le fil {

public void run( ) {

...

}

}

Son code source est celui lorsque le thread enfant est vivant (isAlive()), le thread principal arrêtera d'attendre (wait(0))

8.

interrupt() et la manière de terminer le thread

interruption( )

La fonction est d'interrompre ce fil. Ce fil est autorisé à s'interrompre ; lorsque d'autres threads appellent la méthode interrupt() de ce fil, ils transmettent checkAccess() Check autorisations. Cela peut générer une exception SecurityException.

Si ce fil est dans un état bloqué : appelez le wait(), wait(long) ou wait(long, int) Il entrera dans l'état d'attente (blocage), ou appellera l'état join() du fil, rejoignez ( long), join(long, int), sleep(long), sleep(long, int) le mettra également dans un état de blocage. Si le thread appelle sa méthode interrupt() lorsqu'il est dans l'état bloqué, alors son « état d'interruption sera effacé et une exception InterruptedException sera reçue. Par exemple, un thread entre dans l'état bloqué via wait(), puis interrompt le thread via interrupt(); 🎜>interrupt() définira immédiatement l'indicateur d'interruption du fil sur "true", mais comme le fil est bloqué, le >"Drapeau d'interruption " sera immédiatement effacé à "faux" , et en même temps fois, une exception InterruptedException.

Si un fil de discussion est bloqué dans un sélecteur Selector, alors lorsqu'il est interrompu par interrupt(); L'indicateur d'interruption du fil sera défini sur true et il reviendra immédiatement de l'opération de sélection.

S'il ne tombe pas dans la situation mentionnée ci-dessus, alors lorsque le fil est interrompu via interrupt(), sa marque d'interruption sera définie sur "vrai".

Interrompre un " fil de discussion terminé " ne fait rien.

8.1 Terminer le fil de discussion dans "l'état bloqué"

Habituellement, on passe " Interrompre manière de terminer le fil de discussion en État bloqué.
Lorsque le thread entre dans l'état de blocage en raison de son appel sleep(), wait(), join() et d'autres méthodes si le interrupt()Définissez l'indicateur d'interruption du thread sur true. En raison de l'état de blocage, la marque d'interruption sera effacée et une exception InterruptedException sera générée. Placez InterruptedException de manière appropriée pour terminer le fil de discussion

8.2 Terminer le fil de discussion en "état d'exécution"

Habituellement, nous passons " marque La méthode " termine un thread dans l'"état d'exécution ". Parmi eux, dont "Break Mark" et "Extra Add Mark.
(01) Terminez le fil de discussion via "Drapeau d'interruption " .
a la forme suivante :

@Overridepublic void run() {

while (!isInterrupted()) {

// Exécuter la tâche... }

}

Explication : isInterrupted() est de déterminer l'interruption du fil Est-ce que le tag vrai. Lorsqu'un thread est en cours d'exécution et que nous devons le terminer ; nous pouvons appeler la méthode interrupt() du thread, en utilisant l'indicateur d'interruption du thread comme true , c'est-à-dire isInterrupted() renverra true. À ce moment-là, la boucle while se terminera.
Remarque : interrupt() ne met pas fin à l'état d'exécution de "" Le fil de  ! Cela définira l'indicateur d'interruption du fil sur true.

(02) Ajouter des balises supplémentaires " via "". a la forme suivante :
private volatile boolean flag= true;protected void stopTask() {

flag = false;

}

@Overridepublic void run() {

while (drapeau) {

//

Exécuter la tâche

... }}

Explication : Il y a une balise

flag dans le fil de discussion, et sa valeur par défaut est true  ; et nous fournissons stopTask() pour définir la balise flag. Lorsque nous devons terminer le thread, appeler la méthode stopTask() du thread permettra au thread de quitter la boucle while. Remarque : Définir
drapeau comme volatile consiste à garantir que drapeau visibilité. Autrement dit, après que d'autres threads ont modifié le flag via stopTask(), ce fil peut voir le modifié. valeur du drapeau.

Parlez enfin de interrompu() et isInterrupted().
interrupted() et isInterrupted() peuvent tous deux être utilisés pour détecter l'interruption " de l'objet drapeau .
La différence est que, interrupted() en plus de renvoyer la marque d'interruption, il effacera également la marque d'interruption (La marque d'interruption à venir définie sur false) et isInterrupted() renvoie uniquement l'indicateur d'interruption

9.Priorité des threads et threads démons

Chaque thread a une priorité. "Les fils de discussion à haute priorité" auront la priorité sur les "Les fils de discussion à faible prioritéExécuter. Chaque thread peut être marqué comme démon ou non-démon. Lorsqu'un nouveau thread enfant est créé dans un thread principal en cours d'exécution, la priorité du thread enfant est définie comme étant égale à la priorité du thread principal qui l'a créé ", si et seulement si ". Le thread principal qui l'a créé est le thread démon " "Le thread enfant est le thread démon". Lorsque la machine virtuelle Java

démarre, il y a généralement un seul thread non-démon (le thread passe par

main()

démarrage de la méthode). JVM continuera à s'exécuter jusqu'à ce que l'une des conditions suivantes se produise, JVM se terminera : (01) a appelé la méthode exit()

, et

exit() a la permission d'être exécutée normalement. (02) Tous les "

les fils de discussion non-démons

"sont morts(C'est-à-dire que JVM n'a que "thread démon »). Chaque fil de discussion est marqué comme "

Fil démon

"

ou "Fil utilisateur". Lorsque seul le thread démon est en cours d'exécution, JVM se fermera automatiquement.

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