Questions d’entretien d’embauche Java

Questions d'entrevue Java

1. introduction

Cet article contient des réponses à certaines des plus importantes questions de l'entretien d'embauche sur le noyau Java. Les réponses à certaines d'entre elles peuvent ne pas être évidentes, alors cet article aidera à clarifier les choses.

2. Questions sur le langage Core-Java pour les débutants

Q1. Les données sont-elles passées par référence ou par valeur en Java?

Bien que la réponse à cette question soit assez simple, cette question peut être déroutante pour les débutants. Tout d'abord, clarifions le sujet de la question:

  1. Passing by value – cela signifie que nous passonsa copy of an object comme paramètre dans une méthode.

  2. Passing by reference – cela signifie que nous passonsa reference to an object comme paramètre dans une méthode.

Pour répondre à la question, nous devons analyser deux cas. Ils représentent deux types de données que nous pouvons transmettre à une méthode: une primitive et un objet.

Lorsque nous transmettons des primitives à une méthode, sa valeur est copiée dans une nouvelle variable. En ce qui concerne les objets, la valeur de la référence est copiée dans une nouvelle variable. So we can say that Java is a strictly pass-by-value language.

Nous pouvons en apprendre plus à ce sujet dans l'un de nos articles:Pass-By-Value as a Parameter Passing Mechanism in Java.

Q2. Quelle est la différence entre les importations importées et statiques?

Nous pouvons utiliser des importations régulières pour importer une classe spécifique ou toutes les classes définies dans un package différent:

import java.util.ArrayList; //specific class
import java.util.*; //all classes in util package

Nous pouvons également les utiliser pour importer des classes imbriquées publiques d'une classe englobante:

import com.example.A.*

Cependant, nous devons être conscients que l’importation ci-dessus n’importe pas la classeA elle-même.

Il existe également des importations statiques qui nous permettent d'importer des membres statiques ou des classes imbriquées:

import static java.util.Collections.EMPTY_LIST;

L’effet est que nous pouvons utiliser la variable statique EMPTY_LIST sans ajouter de préfixe au nom complet de la classe, c.-à-d. comme s'il était déclaré dans la classe actuelle.

Q3. Quels modificateurs d'accès sont disponibles en Java et quel est leur objectif?

Il existe quatre modificateurs d'accès dansJava:

  1. privé

  2. default (package)

  3. protégé

  4. Publique

The private modifier assures that class members won’t be accessible outside the class. Il peut être appliqué aux méthodes, propriétés, constructeurs, classes imbriquées, mais pas aux classes de niveau supérieur elles-mêmes.

Contrairement au modificateurprivate, nous pouvons appliquer le modificateurdefault à tous les types de membres de classe et à la classe elle-même. Nous pouvons appliquer la visibilité dedefaulten n'ajoutant aucun modificateur d'accès. If we use default visibility our class or its members will be accessible only inside the package of our class. Nous devons garder à l'esprit que le modificateur d'accès par défaut n'a rien de commun avec le mot-clédefault.

Comme pour le modificateurdefault, toutes les classes d'un même package peuvent accéder aux membres deprotected. What’s more, the protected modifier allows subclasses to access the protected members of a superclass, even if they are not within the same package. Nous ne pouvons pas appliquer ce modificateur d'accès aux classes, uniquement aux membres de la classe.

Le modificateurpublic peut être utilisé avec le mot-clé de classe et tous les membres de la classe. It makes classes and class members accessible in all packages and by all classes.

Nous pouvons en savoir plus dans l'article deJava Access Modifiers.

Q4. Quels autres modificateurs sont disponibles en Java et quel est leur but?

Il existe cinq autres modificateurs disponibles en Java:

  • statique

  • final

  • abstrait

  • synchronisé

  • volatil

Ceux-ci ne contrôlent pas la visibilité.

Tout d'abord, nous pouvons appliquer le mot-cléstatic aux champs et aux méthodes. Static fields or methods are class members, whereas non-static ones are object members. Les membres du cours n'ont besoin d'aucune instance pour être invoqués. Ils sont appelés avec le nom de la classe au lieu du nom de référence de l'objet. This article donne plus de détails sur le mot cléstatic.

Ensuite, nous avons le mot-cléfinal. Nous pouvons l'utiliser avec des champs, des méthodes et des classes. When final is used on a field, it means that the field reference cannot be changed. Il ne peut donc pas être réaffecté à un autre objet. When final is applied to a class or a method, it assures us that that class or method cannot be extended or overridden. Le mot cléfinal est expliqué plus en détail dansthis article.

Le mot clé suivant estabstract. Celui-ci peut décrire des classes et des méthodes. When classes are abstract, they can’t be instantiated. Au lieu de cela, ils sont censés être sous-classés. Lorsque les méthodes sontabstract, elles sont laissées sans implémentation et peuvent être remplacées dans les sous-classes.

Le mot clésynchronized peut être le plus avancé. Nous pouvons l'utiliser avec l'instance ainsi qu'avec des méthodes statiques et des blocs de code. When we use this keyword, we make Java use a monitor lock to provide synchronization on a given code fragment. Pour plus d'informations sursynchronized, consultezthis article.

Le dernier mot-clé dont nous allons discuter estvolatile. Nous ne pouvons l'utiliser qu'avec des champs d'instance. It declares that the field value must be read from and written to main memory – bypassing the CPU cache. Toutes les lectures et écritures pour une variable volatile sont atomiques. Le mot clé volatile est expliqué en détail enthis article.

Q5. Quelle est la différence entre JDK, JRE et JVM?

JDK signifieJava Development Kit, qui est un ensemble d'outils nécessaires aux développeurs pour écrire des applications en Java. Il existe trois types d’environnements JDK:

  • Standard Edition - kit de développement pour la création d'applications de bureau ou de serveur portables

  • Enterprise Edition - une extension de la Standard Edition avec prise en charge de l'informatique distribuée ou des services Web

  • Micro Edition - plate-forme de développement pour applications embarquées et mobiles

Il existe de nombreux outils inclus dans le JDK quihelp programmers with writing, debugging or maintaining applications. Les plus populaires sont un compilateur (javac), un interpréteur (java), un archiveur (jar) et un générateur de documentation (javadoc).

JRE est unJava Runtime Environment. Il fait partie du JDK, maisit contains the minimum functionality to run Java applications. Il se compose d'unJava Virtual Machine, de classes principales et de fichiers de prise en charge. Par exemple, il n’a pas de compilateur.

JVM est l'acronyme deJava Virtual Machine, qui est une machine virtuelle capable d'exécuter des programmes compilés en bytecode. Il est décrit par la spécification JVM, car il est important d’assurer l’interopérabilité entre les différentes implémentations. The most important function of a JVM is to enable users to deploy the same Java application into different operating systems and environments without worrying about what lies underneath.

Pour plus d’informations, consultez l’articleDifference Between JVM, JRE, and JDK.

Q6. Quelle est la différence entre Stack et Heap?

Il existe deux parties de la mémoire où toutes les variables et tous les objets sont stockés par la machine virtuelle Java. Le premier est lestack et le second est leheap.

Lesstack is a place where the JVM reserves blocks for local variables and additional data. La pile est une structureLIFO (dernier entré premier sorti). Cela signifie que chaque fois qu'une méthode est appelée, un nouveau bloc est réservé aux variables locales et aux références d'objet. Chaque nouvelle invocation de méthode réserve le bloc suivant. Lorsque les méthodes terminent leur exécution, les blocs sont libérés de manière inverse.

Chaque nouveau thread a sa propre pile.

Nous devons être conscients que la pile a beaucoup moins d’espace mémoire que le tas. Et quand une pile est pleine, la JVM lancera unStackOverflowError. Il est probable que cela se produise lors d'un mauvais appel récursif et que la récursion est trop profonde.

Every new object is created on the Java heap which is used for a dynamic allocation. Il y a ungarbage collector qui est responsable de l'effacement des objets inutilisés qui sont divisés en espaces jeunes (crèche) et anciens. L'accès mémoire au tas est plus lent que l'accès à la pile. La JVM renvoie unOutOfMemoryError lorsque le tas est plein.

Nous pouvons trouver plus de détails dans l'article deStack Memory and Heap Space in Java.

Q7. Quelle est la différence entre les interfacesComparable andComparator?

Parfois, lorsque nous écrivons une nouvelle classe, nous aimerions pouvoir comparer les objets de cette classe. Cela est particulièrement utile lorsque nous voulons utiliser des collections triées. Il y a deux façons de faire cela: avec l'interfaceComparable ou avec l'interfaceComparator.

Examinons d'abord l'interfaceComparable:

public interface Comparable {
    int compareTo(T var1);
}

Nous devrions implémenter cette interface par la classe dont nous voulons trier les objets.

Il a la méthodecompareTo() et renvoie un entier. Il peut renvoyer trois valeurs: -1, 0 et 1, ce qui signifie que cet objet est inférieur, égal ou supérieur à l'objet comparé.

Il convient de mentionner que la méthodecompareT0() remplacée doit être cohérente avec la méthodeequals().

D'autre part, nous pouvons utiliser l'interfaceComparator. Il peut être passé aux méthodessort() de l'interfaceCollection ou lors de l'instanciation de collections triées. C’est pourquoi il est principalement utilisé pour créer une stratégie de tri unique.

De plus, il est également utile lorsque nous utilisons une classe tierce qui n’implémente pas l’interface Comparable.

Comme la méthodecompareTo(), les méthodescompare() surchargées doivent être cohérentes avec la méthodeequals(), mais elles peuvent éventuellement permettre une comparaison avec des valeurs nulles.

Consultez l'article deComparator and Comparable in Java pour plus d'informations.

Q8. Quel est le type devoid et quand l'utilisons-nous?

Chaque fois que nous écrivons une méthode en Java, elle doit avoir un type de retour. Si nous voulons que la méthode ne renvoie aucune valeur, nous pouvons utiliser le mot clévoid.

Nous devons également savoir qu'il existe une classeVoid. C'est une classe d'espace réservé qui peut être utilisée, par exemple, lorsque vous travaillez avec des génériques. La classeVoid ne peut être ni instanciée ni étendue.

Q9. Quelles sont les méthodes de la classe d'objets et que font-elles?

Il est important de savoir quelles méthodes la classeObject contient et comment elles fonctionnent. C'est également très utile lorsque nous souhaitons remplacer ces méthodes:

  • clone() - renvoie une copie de cet objet

  • equals() - renvoietrue lorsque cet objet est égal à l'objet passé en paramètre

  • finalize() - le garbage collector appelle cette méthode pendant qu'il nettoie la mémoire

  • getClass() - renvoie la classe d'exécution de cet objet

  • hashCode() - renvoie un code de hachage de cet objet. We should be aware that it should be consistent with the equals() method

  • notify() - envoie une notification à un seul thread en attente du moniteur de l'objet

  • notifyAll() - envoie une notification à tous les threads en attente du moniteur de l'objet

  • toString() - renvoie une représentation sous forme de chaîne de cet objet

  • wait() - il existe trois versions surchargées de cette méthode. Cela force le thread actuel à attendre le laps de temps spécifié jusqu'à ce qu'un autre thread appellenotify() ounotifyAll() sur cet objet.

Q10. Qu'est-ce qu'un énum et comment l'utiliser?

Enum est un type de classe qui permet aux développeurs de spécifier un ensemble de valeurs constantes prédéfinies. Pour créer une telle classe, nous devons utiliser le mot-cléenum. Imaginons une énumération des jours de la semaine:

public enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
}

Pour itérer sur toutes les constantes, nous pouvons utiliser la méthode statiquevalues(). De plus, les énumérations nous permettent de définir des membres tels que des propriétés et des méthodes comme des classes régulières.

Although it’s a special type of class, we can’t subclass it. Une énumération peut cependant implémenter une interface.

Un autre avantage intéressant desEnums est qu'ils sont thread-safe et sont donc couramment utilisés comme singletons.

Nous pouvons en savoir plus sur les Enums dansone of our guides.

Q11. Qu'est-ce que le fichier JAR dea?

JAR  est un raccourci pourJava archive. Il s’agit d’un fichier d’archive au format ZIP. Nous pouvons l'utiliser pour inclure les fichiers de classe et les ressources auxiliaires nécessaires aux applications. Il a beaucoup de fonctionnalités:

  • Security – nous pouvons signer numériquement les fichiers JAR

  • Compression – tout en utilisant un JAR, nous pouvons compresser les fichiers pour un stockage efficace

  • Portability – nous pouvons utiliser le même fichier JAR sur plusieurs plates-formes

  • Les fichiers JAR deVersioning – peuvent contenir des métadonnées sur les fichiers qu'ils contiennent

  • Sealing – nous pouvons sceller un package dans un fichier JAR. Cela signifie que toutes les classes d'un package doivent être incluses dans le même fichier JAR.

  • Extensions – nous pouvons utiliser le format de fichier JAR pour empaqueter des modules ou des extensions pour les logiciels existants

Q12. Qu'est-ce queaNullPointerException?

LeNullPointerException est probablement l'exception la plus courante dans le monde Java. C’est une exception non vérifiée et étend ainsiRuntimeException. Nous ne devrions pas essayer de gérer cela.

Cette exception est levée lorsque nous essayons d’accéder à une variable ou d’appeler une méthode de référence null, comme lorsque:

  • invoquer une méthode de référence nulle

  • définir ou obtenir un champ d'une référence nulle

  • vérifier la longueur d'une référence de tableau null

  • définir ou obtenir un élément d'une référence de tableau null

  • lancernull

Q13. Quels sont les deux types de casting en Java? Quelle exception peut être levée lors du casting? Comment pouvons-nous l'éviter?

On peut distinguer deux types de casting en Java. We can do upcasting which is casting an object to a supertype or downcasting which is casting an object to a subtype.

Upcasting est très simple, car nous pouvons toujours le faire. Par exemple, nous pouvons convertir une instanceString vers le typeObject:

Object str = "string";

Alternativement, nous pouvonsdowncast une variable. Ce n’est pas aussi sûr que le upcasting car il implique une vérification de type. Si nous convertissons un objet de manière incorrecte, la JVM lèvera unClassCastExcpetion à l'exécution. Fortunately, we can use the instanceof keyword to prevent invalid casting:

Object o = "string";
String str = (String) o; // it's ok

Object o2 = new Object();
String str2 = (String) o2; // ClassCastException will be thrown

if (o2 instanceof String) { // returns false
    String str3 = (String) o2;
}

Nous pouvons en savoir plus sur le type castingin this article.

3. Questions sur le langage Core-Java pour les programmeurs avancés

Q1. Pourquoi String est-il une classe immuable?

Il faut savoir que les objetsString sont traités différemment des autres objets par lesJVM. Une différence est que les objetsString sont immuables. It means that we can’t change them once we have created them. Il y a plusieurs raisons pour lesquelles ils se comportent de cette façon:

  1. Ils sont stockés dans lestring pool qui est une partie spéciale de la mémoire du tas. Il est responsable d’économiser beaucoup d’espace.

  2. L'immuabilité de la classeString garantit que son code de hachage ne changera pas. Due to that fact, Strings can be effectively used as keys in hashing collections. Nous pouvons être sûrs que nous n'écraserons aucune donnée en raison d'une modification des codes de hachage.

  3. Ils peuvent être utilisés en toute sécurité sur plusieurs threads. No thread can change the value of a String object, so we get thread safety for free.

  4. Les chaînes sont immuables pour éviter de graves problèmes de sécurité. Les données sensibles telles que les mots de passe peuvent être modifiées par une source peu fiable ou un autre thread.

Nous pouvons en savoir plus sur l'immuabilité des chaînesin this article.

Q2. Quelle est la différence entre la liaison dynamique et la liaison statique?

La liaison en Java consiste à associer un appel de méthode au corps de méthode approprié. On peut distinguer deux types de liaison en Java: statique et dynamique.

La principale différence entre la liaison statique et la liaison dynamique est que la liaison statique se produit au moment de la compilation et la liaison dynamique au moment de l'exécution.

Static binding utilise les informations de classe pour la liaison. Il est responsable de la résolution des membres de classe qui sont des méthodes et des variablesprivate oustatic etfinal. En outre, la liaison statique lie les méthodes surchargées.

Dynamic binding, d'autre part, utilise les informations d'objet pour résoudre les liaisons. C’est pourquoi il est responsable de la résolution des méthodes virtuelles et remplacées.

Q3. Qu'est-ce que JIT?

JIT signifie «juste à temps». Il s’agit d’un composant du JRE qui s’exécute au moment de l’exécution et augmente les performances de l’application. Specifically, it’s a compiler which runs just after the program’s start.

Cela diffère du compilateur Java habituel qui compile le code bien avant le démarrage de l'application. JIT peut accélérer l'application de différentes manières.

Par exemple, le compilateur JIT est chargé de compiler à la volée le bytecode en instructions natives pour améliorer les performances. En outre, il peut optimiser le code pour le processeur et le système d'exploitation ciblés.

De plus, il a accès à de nombreuses statistiques d'exécution pouvant être utilisées pour la recompilation afin d'optimiser les performances. Cela permet également d’optimiser le code global ou de réorganiser le code pour une meilleure utilisation du cache.

Q4. Qu'est-ce que la réflexion en Java?

La réflexion est un mécanisme très puissant en Java. Reflection est un mécanisme du langage Java qui permet aux programmeurs d'examiner ou de modifier l'état interne du programme (propriétés, méthodes, classes, etc.) au moment de l'exécution. Le package java.lang.reflect fournit tous les composants nécessaires à l’utilisation de la réflexion.

Lorsque vous utilisez cette fonctionnalité, vous pouvez accéder à tous les champs, méthodes et constructeurs possibles inclus dans une définition de classe. Nous pouvons y accéder quel que soit leur modificateur d'accès. Cela signifie par exemple que nous pouvons accéder à des membres privés. Pour ce faire, nous n'avons pas besoin de connaître leurs noms. Tout ce que nous avons à faire est d'utiliser des méthodes statiques deClass.

Il est utile de savoir qu’il est possible de restreindre l’accès par réflexion. Pour ce faire, nous pouvons utiliser le gestionnaire de sécurité Java et le fichier de règles de sécurité Java. Ils nous permettent d'accorder des autorisations aux classes.

Lorsque vous travaillez avec des modules depuis Java 9, nous devons savoir que par défaut, nous ne pouvons pas utiliser la réflexion sur les classes importées depuis un autre module. Pour autoriser d'autres classes à utiliser la réflexion pour accéder aux membres privés d'un package, nous devons accorder l'autorisation «Réflexion».

This article donne plus de détails sur Java Reflection.

Q5. Qu'est-ce que le chargeur de classea?

Leclassloader est l'un des composants les plus importants de Java. Cela fait partie du JRE.

En termes simples, le classloader est responsable du chargement des classes dans la JVM. On peut distinguer trois types de chargeurs de classe:

  • Bootstrap classloader – il charge les classes Java de base. Ils se trouvent dans le répertoire<JAVA_HOME>/jre/lib

  • Extension classloader – il charge les classes situées dans<JAVA_HOME>/jre/lib/ext ou dans le chemin défini par la propriétéjava.ext.dirs

  • System classloader – il charge les classes sur le chemin de classe de notre application

Un chargeur de classe charge les classes «à la demande». Cela signifie que les classes sont chargées après leur appel par le programme. De plus, un chargeur de classe ne peut charger qu’une seule fois une classe avec un nom donné. Toutefois, si la même classe est chargée par deux chargeurs de classes différents, ces classes échouent lors d'un contrôle d'égalité.

Il y a plus d'informations sur les chargeurs de classes dans l'articleClass Loaders in Java.

Q6. Quelle est la différence entre le chargement de classes statiques et dynamiques?

Le chargement des classes statiques a lieu lorsque nous avons des classes sources disponibles au moment de la compilation. Nous pouvons l'utiliser en créant des instances d'objet avec le mot clénew.

Le chargement dynamique de classe fait référence à une situation dans laquelle nous ne pouvons pas fournir de définition de classe au moment de la compilation. Pourtant, nous pouvons le faire au moment de l'exécution. Pour créer une instance d'une classe, nous devons utiliser la méthodeClass.forName():

Class.forName("oracle.jdbc.driver.OracleDriver")

Q7. Quel est le but de l'interfaceSerializable?

We can use the Serializable interface to enable serializability of a class, using Java’s Serialization API. La sérialisation est un mécanisme permettant de sauvegarder l'état d'un objet sous la forme d'une séquence d'octets tandis que la désérialisation est un mécanisme de restauration de l'état d'un objet à partir d'une séquence d'octets. La sortie sérialisée contient l'état de l'objet et certaines métadonnées sur le type de l'objet et les types de ses champs.

Nous devons savoir que les sous-types de classes sérialisables le sont également. Cependant, si nous voulons rendre une classe sérialisable, mais que son sur-type n'est pas sérialisable, nous devons faire deux choses:

  • implémenter l'interfaceSerializable

  • assurer qu'un constructeur sans argument est présent dans la superclasse

Nous pouvons en savoir plus sur la sérialisation enone of our articles.

Q8. Y a-t-il un destructeur en Java?

En Java, le ramasse-miettes supprime automatiquement les objets inutilisés pour libérer de la mémoire. Les développeurs n'ont pas besoin de marquer les objets pour suppression, ce qui est sujet aux erreurs. So it’s sensible Java has no destructors available.

Si les objets contiennent des sockets ouverts, des fichiers ouverts ou des connexions à la base de données,the garbage collector is not able to reclaim those resources. Nous pouvons libérer les ressources dansclose method et utilisertry-finally syntax pour appeler la méthode par la suite avant Java 7, comme les classes d'E / SFileInputStreamandFileOutputStream. As of Java 7, we can implement interface AutoCloseable and use try-with-resources statement to write shorter and cleaner code. Mais il est possible que les utilisateurs de l'API oublient d'appeler la méthodeclose , de sorte que la méthodefinalize et la classeCleaner ont créées pour servir de filet de sécurité. But please be cautioned they are not equivalent to the destructor.

It’s not assured both the finalize method and Cleaner class will run promptly. Ils n'ont même aucune chance de s'exécuter avant la fermeture de la JVM. Bien que nous puissions appelerSystem.runFinalization pour suggérer que la JVM exécute les méthodesfinalize m de tous les objets en attente de finalisation, cela reste non déterministe.

De plus, la méthodefinalize peut entraîner des problèmes de performances, des blocages, etc. Nous pouvons trouver plus d'informations en consultant l'un de nos articles:A Guide to the finalize Method in Java.

As of Java 9,Cleaner class is added to replace the finalize method en raison de ses inconvénients. En conséquence, nous avons un meilleur contrôle sur le fil qui effectue les actions de nettoyage.

Mais la spécification Java indique le comportement des nettoyeurs lors de l'implémentation deSystem.exit is spécifique et Java ne fournit aucune garantie si les actions de nettoyage seront appelées ou non.