-
Il existe un excellent article avec les principales questions et réponses pour eux. Certaines questions chevauchent la liste présentée ci-dessus (250+), ces questions seront donc ignorées afin de ne pas dupliquer les informations une fois de plus.
-
Les questions sont présentées en ukrainien, mais comme la majorité des participants à JavaRush sont russophones (et dans une plus large mesure moi aussi), les réponses seront en russe.
-
Les réponses seront brèves, car si vous écrivez de manière très détaillée, les réponses à certaines questions peuvent nécessiter un article séparé. Et lors des entretiens, des réponses aussi détaillées et volumineuses ne sont pas nécessaires, car votre interlocuteur ne dispose que d'une heure pour vous interviewer sur les sujets nécessaires (et, comme vous vous en souvenez, cela suffit). Pour ceux qui aiment approfondir, je laisserai des liens.
Questions et réponses pour le niveau junior
Questions générales
1. Quels modèles de conception connaissez-vous ? Parlez-nous des deux modèles que vous avez utilisés dans votre travail.
Il existe une grande variété de modèles : vous pouvez commencer à vous familiariser à partir de cet article et de cet article. Eh bien, pour ceux d'entre vous qui souhaitent se familiariser avec eux en détail, je recommande de lire le livre « Head First. Modèles de conception" . Avec son aide, vous pouvez étudier les modèles de conception les plus élémentaires en détail et de manière simple. Lorsqu'il s'agit de modèles de conception que vous pouvez utiliser comme exemples dans une interview, certains qui vous viennent à l'esprit sont :- Builder est un modèle fréquemment utilisé, une alternative à la création d'objets classique ;
- Modèle de stratégie , qui représente intrinsèquement le polymorphisme. Autrement dit, nous avons une interface, mais le comportement du programme changera en fonction de l'implémentation spécifique de cette interface qui a été transférée à la fonctionnalité (maintenant, la stratégie est pratiquement utilisée partout dans les applications Java).
- Factory - dans ApplicationContext (ou dans BeanFactory) ;
- Singleton - tous les beans sont des singletons par défaut ;
- Proxy - essentiellement tout ce qui se trouve dans Spring utilise ce modèle d'une manière ou d'une autre, par exemple AOP ;
- La chaîne de responsabilité est un modèle basé sur le concept sur lequel fonctionne Spring Security ;
- Modèle - utilisé dans Spring Jdbc.
Noyau Java
2. Quels types de données existe-t-il en Java ?
Java a des types de données primitifs :- octet — nombres entiers compris entre -128 et 127, pèse 1 octet ;
- short — entiers compris entre -32 768 et 32 767, pèse 2 octets ;
- int — entiers -2147483648 à 2147483647, pèse 4 octets ;
- long — nombres entiers compris entre 9223372036854775808 et 9223372036854775807, pèse 8 octets ;
- float — nombres à virgule flottante compris entre -3,4E+38 et 3,4E+38, pèse 4 octets ;
- double — nombres à virgule flottante compris entre -1,7E+308 et 1,7E+308, pèse 8 octets ;
- char — caractères uniques en UTF-16, pèsent 2 octets ;
- les valeurs booléennes vrai/faux pèsent 1 octet.
3. En quoi un objet diffère-t-il des types de données primitifs ?
Première différence : la quantité de mémoire occupée : les primitives en occupent très peu, car elles ne contiennent que leur propre valeur, alors que les objets peuvent contenir de très, très nombreuses valeurs différentes : à la fois des primitives et des références à d'autres objets. Deuxième différence : Java est un langage orienté objet, donc tout ce qu'il contient fonctionne grâce à l'interaction entre les objets, et les primitives ne s'intègrent pas très bien (en fait, c'est pourquoi Java n'est pas un langage 100 % orienté objet). Troisièmement, dans la continuité du deuxième : puisque Java se concentre sur l’interaction entre les objets, ces objets disposent de nombreux mécanismes différents pour les gérer. Par exemple, les constructeurs, les méthodes, les exceptions (qui opèrent principalement sur les objets), etc. En fait, pour que les primitives puissent s'impliquer (fonctionner) d'une manière ou d'une autre dans cet environnement orienté objet, des wrappers ont été inventés pour les types primitifs ( Integer , Character , Double , Boolean ...)4. Quelle est la différence entre passer des paramètres par référence et par valeur ?
Les champs primitifs stockent leur valeur : par exemple, si nous définissons int i = 9 ; le champ i stocke la valeur 9 . Lorsque nous avons une référence à un objet, cela signifie que nous avons un champ avec une référence à l'objet, ou en d'autres termes, avec la valeur de l'adresse de l'objet en mémoire.Cat cat = new Cat();
Il s'avère que les champs faisant référence à un objet stockent également des valeurs , des valeurs d'adresse mémoire. Autrement dit, cat stocke la valeur d'adresse du nouvel objet Cat() en mémoire. Lorsque nous passons un paramètre à une méthode, sa valeur est copiée. Dans le cas d'une primitive, la valeur de la primitive sera copiée. En conséquence, la méthode fonctionnera avec une copie, dont la modification n'affectera pas l'original. Dans le cas d'un type référence, la valeur de l'adresse mémoire sera copiée, respectivement, l'adresse sera la même que l'objet vers lequel elle pointe. Et si nous modifions l'objet en utilisant ce nouveau lien, il sera remplacé par l'ancien (après tout, ils pointent tous les deux vers le même objet).
5. Qu'est-ce que JVM, JDK, JRE ?
JVM - Java Virtual Machine est une machine virtuelle qui exécute le bytecode Java pré-généré par le compilateur. JRE - Java Runtime Environment - est essentiellement un environnement pour exécuter des applications Java, qui contient la JVM , des bibliothèques standard et d'autres composants pour exécuter des applets et des applications écrites dans le langage de programmation Java. En d'autres termes , le JRE est un package contenant tout ce qui est nécessaire pour exécuter un programme Java compilé, mais ne contient pas d'outils ni d'utilitaires tels que des compilateurs ou des débogueurs pour le développement d'applications. JDK - Java Development Kit - un ensemble étendu de JRE , c'est-à-dire un environnement non seulement pour le lancement, mais également pour le développement d'applications Java. Le JDK contient tout ce qui se trouve dans le JRE, ainsi que divers outils supplémentaires - des compilateurs et des débogueurs nécessaires pour créer des applications en Java (contient également de la documentation Java).6. Pourquoi utiliser JVM ?
Comme mentionné ci-dessus, Java Virtual Machine est une machine virtuelle qui exécute le bytecode Java pré-généré par le compilateur. Autrement dit, la JVM ne comprend pas le code source Java. Par conséquent, d'abord, les fichiers .java sont compilés , qui après compilation ont déjà une extension .class et qui sont présentés sous la forme du même code d'octet que celui compris par la JVM. Chaque système d'exploitation a sa propre JVM, donc après avoir reçu les fichiers de bytecode, la JVM l'exécute en l'adaptant au système d'exploitation sur lequel cela se produit. En fait, en raison des différentes JVM, les versions du JDK (ou JRE) diffèrent selon les systèmes d'exploitation (chacun d'eux nécessite sa propre JVM). Rappelons comment fonctionne le développement dans d'autres langages de programmation. Vous développez un programme, puis son code est compilé en code machine pour un système d'exploitation spécifique, puis vous pouvez l'exécuter. En d’autres termes, vous devez écrire différentes versions du programme pour chaque système. Alors qu'en Java, grâce au double traitement de code (compilation et traitement des octets de code JVM), vous pouvez bénéficier des avantages du multiplateforme. Nous avons une fois créé le code, l'avons recompilé en bytecode, l'avons transféré sur n'importe quel système d'exploitation et la JVM locale exécute le code. C'est la propriété légendaire de Java : écrire une fois, exécuter n'importe où . Pour en savoir plus, consultez l'article « Compilation et exécution d'applications Java sous le capot ».7. Qu'est-ce que le bytecode ?
Comme je l'ai dit plus haut, le compilateur convertit le code Java en bytecode intermédiaire (fichiers avec l'extension .java en fichiers avec l'extension .class). Le bytecode est à bien des égards similaire au code machine, sauf qu'il utilise un ensemble d'instructions provenant non pas d'un processeur réel, mais d'un processeur virtuel. De plus, il peut inclure des sections axées sur l'utilisation d'un compilateur JIT, qui optimise l'exécution des commandes pour le processeur réel sur lequel le programme s'exécute. La compilation JIT, également appelée compilation à la volée, est une technologie qui augmente les performances d'un programme utilisant le bytecode en compilant le bytecode sur une machine ou dans un autre format pendant l'exécution du programme. Comme vous l'avez peut-être deviné, la JVM utilise un compilateur JIT lorsqu'elle exécute le bytecode. Jetons un coup d'œil à un exemple de bytecode : pas trop lisible, n'est-ce pas ? Eh bien, ce n'est pas une instruction pour nous, mais pour la JVM. Voici un article qui vous aidera à mieux comprendre ce problème.8. Quelles sont les caractéristiques d'un JavaBean ?
JavaBeans est une classe Java avec certaines règles. Voici quelques règles pour écrire un JavaBean :-
La classe doit contenir un constructeur d'accès public vide (sans paramètres) avec le modificateur d'accès public . Ce constructeur permet de créer un objet de cette classe sans problèmes inutiles (afin qu'il n'y ait pas de problèmes inutiles avec les paramètres).
-
Les champs internes d'une classe sont accessibles via les méthodes get et set , qui devraient être standard. Par exemple, si le champ est name , alors getName et setName, etc. Ceci, à son tour, permet à divers outils (frameworks) de déterminer et de mettre à jour automatiquement le contenu des beans sans complications.
-
La classe doit contenir des versions remplacées des méthodes equals() hashCode() et toString() .
-
La classe doit être sérialisable, c'est-à-dire qu'elle doit avoir une interface de marqueur - Serialisable ou implémenter l' interface Externalisable . Cela est nécessaire pour que l'état du bean puisse être sauvegardé, stocké et restauré de manière fiable.
9. Qu'est-ce qu'OutOfMemoryError ?
OutOfMemoryError est l'une des erreurs d'exécution critiques associées au fonctionnement de la machine virtuelle Java (JVM). Appelé lorsque la JVM ne peut pas allouer un objet car il n'y a pas assez de mémoire disponible pour lui et le garbage collector ne peut pas allouer plus de mémoire. Certains types d'OutOfMemoryError :-
OutOfMemoryError : espace du tas Java : l'objet ne peut pas être alloué sur le tas Java en raison d'une mémoire insuffisante. L'erreur peut être provoquée par une fuite de mémoire ou par le fait que la taille du tas par défaut n'est pas suffisamment grande pour l'application actuelle.
-
OutOfMemoryError : limite de surcharge GC dépassée - en raison du fait que la quantité de données tient à peine dans le tas, le garbage collector s'exécute tout le temps et le programme Java s'exécute très lentement et, par conséquent, la limite de surcharge du garbage collector est dépassé et l'application plante avec cette erreur.
-
OutOfMemoryError : La taille du tableau demandé dépasse la limite de la VM - indique que l'application a tenté d'allouer de la mémoire à un tableau qui est plus grande que la taille du tas, ce qui peut encore une fois être dû à une allocation de mémoire par défaut insuffisante.
-
OutOfMemoryError: Metaspace : le tas n'a plus d'espace alloué aux métadonnées (les métadonnées sont des instructions pour les classes et les méthodes).
-
OutOfMemoryError : demande de taille en octets pour une raison. Espace d'échange insuffisant : un échec s'est produit lors de la tentative d'allocation de mémoire à partir du tas et, par conséquent, il y avait un manque de mémoire dans le tas.
10. Qu'est-ce qu'une trace de pile ? Comment l'obtenir?
Une Stack Trace est une liste de classes et de méthodes qui ont été appelées jusqu'à présent dans l'application. Vous pouvez appeler une trace de pile à un point spécifique de l'application comme ceci :StackTraceElement[] stackTraceElements =Thread.currentThread().getStackTrace();
De cette façon, nous obtiendrons un tableau d'éléments de trace de pile disposés dans l'ordre LIFO - Last In First Out . En Java, en règle générale, lorsqu'ils parlent de trace de pile, ils désignent la trace de pile qui s'affiche dans la console lorsqu'une erreur (ou une exception) se produit. Vous pouvez obtenir la trace de pile des exceptions comme ceci :
StackTraceElement[] stackTraceElements;
try{
...
} catch (Exception e) {
stackTraceElements = e.getStackTrace();
}
Eh bien, si nous parlons de générer la trace de la pile d'exceptions dans la console :
try{
...
} catch (Exception e) {
e.printStackTrace();
}
De plus, si nous avons une erreur, une exception non vérifiée ou une exception vérifiée , que nous ne traiterons pas, mais que nous transmettrons seulement, alors lorsque l'application plante, nous recevrons automatiquement une trace de pile des exceptions dans la console. Un petit exemple d'exception de trace de pile dans la console : vous pouvez en savoir plus sur Stack Trace ici . Nous allons nous concentrer sur cette question aujourd'hui...
GO TO FULL VERSION