Que sont les cours d'emballage ? Donnez des exemples de deux d'entre elles et des primitives correspondantes. Quel est le rapport entre chacune d'elles et un objet ?
Justification
Les classes d’emballage sont fondamentales en programmation Java. En fait, leur existence implique que java n’est pas 100% orienté objet (bonus au candidat qui le signale !). C’est le cas parce que Java contient 8 types de données primitives qui ne sont pas, par définition, des objets.
Bonne réponse
Une classe d’emballage est une classe qui contient une variable qui est un type de données primitives, et qui enveloppe la primitive pour fournir une fonctionnalité d’interaction avec elle. En fait, on peut dire qu’il transforme le primitif en objet. Ce qui est utile, par exemple, lorsqu’une méthode vise au transfert d’un objet. Le candidat doit être capable de nommer au moins deux des paires suivantes :
Primitive
Classe d'emballage
boolean
Boolean
byte
Byte
char
Char
double
Double
float
Float
int
Int
long
Long
short
Short
Mauvaise réponse
Les classes d’emballage sont définies en java.lang, et requises car il existe de nombreuses classes qui supportent uniquement les objets. Le fait de ne pas connaître ces classes d’emballage, ou de ne pas savoir pourquoi elles seraient utilisées, apparaît comme une grave lacune de la part du candidat interrogé.
Définissez les termes suivants qui sont courants dans la programmation java
Classe abstraite
Ramasse-miettes (aussi appelé récupérateur de mémoire, glaneur de cellules ou garbage collector)
Autoboxing
Sérialisation
Justification
Cette liste inclut des termes qui sont communément utilisés en Java, ainsi que dans d’autres langages de programmation. Les questions d’entretien pour les programmeurs expérimentés incluent de telles définitions parce qu’elles permettent de tester leurs connaissances de manière approfondie, ainsi que leur capacité à distinguer des langages comportant des concepts proches sans être parfaitement identiques.
Bonne réponse
Une classe abstraite est utilisée comme classe de base pour les sous-classes qui vont étendre ou écraser ses méthodes. Prenons l’exemple d’une classe « Forme ». Une forme peut contenir un certain nombre de côtés, de faces ou même de dimensions. Prise isolément, savoir que cette classe est une « Forme » est peu utile. D’autre part, si cette classe abstraite sera utilisée comme classe de base pour un « Carré », un « Triangle », ou un autre type de polygone, elle deviendra utile quand placée au sommet de la hiérarchie des classes. - Il n'est pas possible d'instancier une classe abstraite. – Elle peut contenir des méthodes abstraites, mais ce n’est pas obligatoire. - Les sous-classes de la classe d'abstraction doivent mettre en œuvre toutes les méthodes d'abstraction, à moins qu'il ne s'agisse également d'une classe d'abstraction. Il n'est pas possible d'instancier une classe abstraite.
Ne pas être parfaitement calé à propos classes abstraites n’est pas éliminatoire, bien que ces dernières seront très probablement rencontrées par le programmeur Java lorsqu’il devra effectuer des actions de maintenance ou du débogage d’une base de code existante.
La "garbage collection" (effectuée par le "garbage collector" ou ramasse-miettes) est le processus de détection et de suppression des objets en mémoire qui ne sont plus utilisés ou référencés. En java, le ramassage des miettes est automatique, mais il peut aussi être demandé.
Les commandes System.gc() et Runtime.gc() indiqueront au ramasse-miettes qu’il doit s’exécuter, bien que cela ne soit pas garanti.
Les fils d’exécution sont mis en pause pendant le ramassage des ordures. Cela ralentit nécessairement l’exécution, ce qui signifie que dans les applications réactives, le ramassage des miettes doit être réduit au minimum. La connaissance du ramasseur de miettes n’est pas indispensable, surtout pour un programmeur débutant. Il est à noter, cependant, que lorsqu’on vient d’un langage comme C, où toute la mémoire est gérée manuellement, le développeur doit être au courant de l’existence de cette fonctionnalité.
L’Autoboxing est l’emballage automatique d’un type primitif (voir la question #4 relative aux types primitifs et classes d’emballages). Par exemple, l’autoboxing convertira automatiquement un nombre de type float (type primitif) en Float (classe d’emballage). Le contraire de cela est le déballage, lors duquel type primitif est extrait de la classe d’emballage. Cette notion est habituellement familière aux bons développeurs Java.
La sérialisation fait référence à l’encodage d’objets en mémoire dans un flux d’octets qui pouvant être facilement stockés ou transmis. Le contraire est la désérialisation, qui reconstruit les objets à partir d’un flux d’octets. Il existe différentes approches pour réaliser la sérialisation. Deux méthodes courantes sont la conversion de l’objet en XML (eXtensible Markup Language), ou JSON (JavaScript Object Notation). Ce sont des types de fichiers bien connus, chacun d’entre eux étant largement pris en charge. Java supporte également la sérialisation comme partie intégrante du langage. Le langage inclut l’interface sérialisable, qui peut être utilisée à la fois pour la sérialisation et la désérialisation. La méthode writeObject() est utilisée pour encoder les données, tandis que la méthode readObject() est utilisée pour reconstruire les objets.
Java définit une classe String pour représenter des tableaux de caractères. Répondez aux questions suivantes :
Un constructeur initialise un objet lors de sa création. Cependant, les constructeurs n'ont pas de type de retour explicite.
En général, vous utiliserez un constructeur pour donner des valeurs initiales aux variables d'instance définies par la classe, ou pour effectuer toute autre procédure de démarrage nécessaire pour créer un objet entièrement formé.
Toutes les classes ont des constructeurs, que vous en définissiez un ou non, car Java fournit automatiquement un constructeur par défaut qui initialise toutes les variables membres à zéro. Cependant, une fois que vous avez défini votre propre constructeur, le constructeur par défaut n'est plus utilisé.
Pourriez-vous citer quelques cadres de travail Java ?
Cette question d'entretien est une question de base : tout développeur Java compétent est en mesure de nommer quelques frameworks écrits en langage Java. Au cours de l'entretien, le candidat interrogé doit mentionner au moins trois frameworks Java parmi cette liste :
JSF (Java Server Faces), un cadre web Java qui facilite la construction d'interfaces utilisateur pour les applications basées sur des serveurs
GWT (Google Web Toolkit), un ensemble d'outils open-source qui aide les programmeurs à créer et à maintenir des applications JavaScript dans Java Spring, un framework Java qui n'impose aucun modèle de programmation spécifique
Struts
Hiberner
Grails
Jouez !
Vaadin
Maven
Questions d'entretien sur la programmation mixte
Java définit une classe String pour représenter des tableaux de caractères. Répondez aux questions suivantes :
- Par quoi faut-il remplacer le "XXX" pour pouvoir comparer les deux principaux arcs de cordes ? Si les arguments sont : "Sun Microsystems" et "Sun microsystems", quel sera le résultat de l'exécution ? Y a-t-il un moyen de garantir qu'il les déclarera comme étant identiques ? - Si les arguments sont plutôt : "Sun Microsystems" et "Sun Microsystems", quel sera le résultat de l'exécution ? "Sun Microsystem" et "Sun Microsystems", quel sera le résultat de l'exécution ?
1/ Après la création d'une chaîne, est-il possible de la modifier ? Considérez ce qui suit :
public static void main(String[] args) { String name = "James gosling"; // I want to change the 'g' to a 'G'. // Will this work at compile time? name.charAt(6) = 'G'; // Print with the standard system println to see “James Gosling” System.out.println(name); }
Cela va-t-il fonctionner ? Si ce n'est pas le cas, quelles modifications faudrait-il apporter pour obtenir la chaîne souhaitée ?
2/ La classe String a plus d'un Comparateur. Considérez le code suivant :
public static void main(String[] args) { // This program received 2 arguments. We want to // determine if those two strings are equal. // Compare the first argument to the second argument boolean compareResult = (XXX); if (compareResult) { System.out.println("The Strings are the same."); } else { System.out.println("The Strings are not the same."); } // Print the main string args System.out.println(args[0]); System.out.println(args[1]); }
- Par quoi faut-il remplacer le "XXX" pour pouvoir comparer les deux principaux arcs de cordes ? Si les arguments sont : "Sun Microsystems" et "Sun microsystems", quel sera le résultat de l'exécution ? Y a-t-il un moyen de garantir qu'il les déclarera comme étant identiques ? - Si les arguments sont plutôt : "Sun Microsystems" et "Sun Microsystems", quel sera le résultat de l'exécution ? "Sun Microsystem" et "Sun Microsystems", quel sera le résultat de l'exécution ?
3/ Qu'est-ce que le pool de constantes de la chaîne Java ? (ou pool de chaînes de caractères Java) ? Il réside dans la mémoire de la pile ?
Justification
L'utilisation de représentations de chaînes de caractères est courante dans de nombreux langages, et Java ne fait pas exception. Il est important de comprendre comment les chaînes de caractères sont créées, analysées, imprimées et manipulées. C'est un sujet important qui constitue une question d'entretien importante pour les développeurs Java.
Bonne réponse
Non, cela échouera au moment de la compilation car il n'est pas possible de modifier une chaîne une fois qu'elle a été initialisée. Cette propriété est dite immuable. Pour que cela fonctionne, il faudrait recréer la chaîne contenant "James gosling". Une approche consiste à utiliser un tableau de caractères intermédiaires (en appelant la méthode toCharArray() sur le "nom"), à remplacer le "g" par la lettre majuscule, puis à recréer la chaîne avant de l'imprimer. Un bonus pour le candidat qui souligne que la fonction string replace(...) existe pour remplacer les caractères, mais ne peut pas être utilisée car toutes les instances de "g" minuscules seraient remplacées.
Le comparateur exact dans cet exemple est soit égal(...) soit égalIgnoreCase(...). Le type de retour de ces deux méthodes est une valeur booléenne. Si la personne interrogée répond compareTo(...) ou compareToIgnoreCase(...), alors le crédit devrait être accordé, bien que le type de retour de ces méthodes soit un int, donc techniquement incorrect. Il n'en reste pas moins qu'elle démontre une connaissance de la langue.
Dans le premier exemple, les chaînes sont identiques sous equalsIgnoreCase(...), mais différentes sous equals(...). Dans le deuxième exemple, il y a un "s" à la fin, ce qui fait que les chaînes sont différentes dans tous les cas.
Le Java Constant String Pool est une zone de la mémoire du Heap (donc, pas de la mémoire de la pile) où sont stockées les chaînes de caractères. Cette approche est à l'origine de la raison pour laquelle les chaînes sont immuables en java.
Par exemple :
chaîne x = "chaîne principale" ;
chaîne de caractères y = "machine virtuelle" ;
chaîne z = "chaîne principale" ;
Les trois cordes ci-dessus sont stockées dans le pool de cordes, mais la partie intéressante est l'efficacité. x et y pointent tous deux vers la même zone dans la réserve de cordes, ce qui ne nécessite pas de duplication de l'espace. Sachant cela, il doit être clair que la modification de la valeur de x n'est pas autorisée car elle aurait l'effet secondaire non voulu de modifier z.
Quelles sont les différences entre la mémoire Stack et l'espace Heap ?
Justification
Afin d'améliorer l'efficacité, la JVM organise la mémoire pour que les applications puissent s'exécuter. Elle crée de l'espace de pile et de l'espace de tas, chacun étant utilisé par des opérations différentes. Comprendre l'allocation de la mémoire à ce niveau peut conduire à un ramassage des déchets plus prévisible et, en fin de compte, à une efficacité accrue.
Bonne réponse
La mémoire en pile est utilisée pour l'allocation de mémoire statique, comme les valeurs primitives à l'intérieur d'une méthode. Elle est toujours utilisée pour l'exécution d'un thread. La pile s'agrandit lorsque les méthodes sont appelées, et se réduit lorsqu'elles reviennent. Si la mémoire allouée pour la pile est dépassée, l'exception java.lang.StackOverFlowError est lancée.
La mémoire de tas est utilisée pour l'allocation de mémoire dynamique, comme les objets java. Plus précisément, l'objet est stocké dans le tas, tandis que la référence à l'objet est stockée dans la pile. Les classes JRE sont également stockées dans le tas au moment de l'exécution. L'accès aux données dans le tas est plus lent que dans la mémoire de la pile. Le tas requiert l'action du collecteur de déchets afin de libérer les objets inutilisés. Si la mémoire allouée au tas est dépassée, l'exception java.lang.OutOfMemoryError est lancée.
Mauvaise réponse
Le fait de n'avoir jamais entendu parler de la pile ou du tas indiquerait une connaissance superficielle du langage de programmation java. De plus, la terminologie est typique d'une culture générale de programmation. Le diagnostic des erreurs liées à la mémoire, telles qu'un débordement de pile causé par un comportement incorrect d'une fonction récursive, serait plus facile avec cette compréhension.
Deux termes liés à la classe utilisés dans la programmation java sont "subclass" et "nested class". Expliquez les différences entre ces deux termes. Pourquoi choisir l'une plutôt que l'autre ? Laquelle est parfois appelée "classe intérieure" ?
Justification
Dans la conception orientée objet, il y a souvent une confusion sur le placement des classes dans la hiérarchie. Les classes imbriquées sont relativement rares par rapport aux sous-classes, mais leur utilisation est bénéfique dans de nombreuses situations. La connaissance de leur existence et de leur mode d'utilisation doit être considérée comme un atout.
Bonne réponse
Une sous-classe est une extension d'une autre classe, et est souvent une spécialisation de l'original. Les sous-classes héritent des membres publics et protégés de leur super-classe. Les sous-classes peuvent être instanciées indépendamment de la superclasse, et en fait, c'est toujours le cas lorsque la superclasse est une classe abstraite.
Une classe imbriquée est une classe à l'intérieur d'une classe, qui dans certains cas est une classe intérieure. Le champ d'application de la classe intérieure comprend tous les membres de sa classe extérieure, ce qui lui donne accès à ces variables et méthodes. Comme le corps existe entièrement au sein de la classe englobante, il ne peut pas être instancié indépendamment, sans elle.
L'utilisation d'une classe interne peut améliorer la conception orientée objet en organisant davantage le code. L'objectif est limité dans la mesure où il existe pour servir sa classe englobante. Si la classe interne offre des fonctionnalités utiles à une plus grande échelle, il serait plus logique de l'avoir comme classe de haut niveau. Les classes internes sont couramment utilisées comme fonctions de rappel pour les composants de l'interface graphique.
Bonus
Il existe deux types de classes imbriquées. Plus précisément, il existe une classe imbriquée statique, qui n'a pas directement accès aux autres membres de la classe englobante. Celles-ci ne sont pas souvent utilisées, c'est pourquoi le fait de les connaître est un bonus par opposition à l'ignorance qui peut entraîner une pénalité. L'autre type est une classe imbriquée non statique, qui est la version que l'on appelle une classe intérieure. Ceux-ci ont en effet accès à tous les membres de la classe englobante, y compris aux méthodes privées.
Mauvaise réponse
Le candidat doit être pardonné de n'avoir jamais utilisé une classe imbriquée. Bien qu'utile, et susceptible d'être vu si l'on maintient une base de code existante, le concept est simple. Les classes imbriquées rendent souvent le code plus élégant et plus facile à maintenir, mais certains concepteurs considèrent que c'est une question de style. Les sous-classes, d'autre part, sont un élément fondamental de la programmation orientée objet que tout développeur java devrait connaître. Ne pas pouvoir discuter facilement des sous-classes au sein d'une hiérarchie de classes est un sérieux signal d'alarme.
Deux classes de collection sont disponibles en programmation java : Array et List. En quoi les méthodes diffèrent-elles entre ces deux objets conteneurs, et dans quelles circonstances choisiriez-vous l'une plutôt que l'autre ?
Justification
L'utilisation de conteneurs est courante en Java et dans d'autres langages de programmation. La liste est une structure de données dynamique, tandis que le tableau est statique. Il est important de reconnaître que chacun d'entre eux est mieux adapté à certaines applications, et à ce titre, le candidat doit les connaître. Avoir une connaissance approfondie des types de données et des classes de conteneurs disponibles permettra en fin de compte de gagner du temps de développement.
Bonne réponse
Array
Les tableaux sont de taille statique, ils ne peuvent donc ni croître ni diminuer en termes de nombre d'éléments. Cela signifie qu'il existe des méthodes pour accéder aux éléments et les modifier, mais pas pour les insérer ou les supprimer.
Java fournit des méthodes pour effectuer une recherche binaire ou un tri sur un tableau. De plus, un tableau peut être initialisé en utilisant la méthode fill(), ou comparé en utilisant le comparateur equals().
La taille d'un tableau est fixée lors de sa création.
L'accès aléatoire d'un élément dans un tableau est très efficace.
Les tableaux sont plus adaptés à des collections d'éléments de longueur fixe.
Tous les éléments sont du même type, par exemple :
int[] interviewArray = new int[5];
or
int[] arrayForInterview = {3, 1, 4, 1, 5};
Ces deux tableaux contiennent cinq entiers.
Vecteur
Les candidats doivent savoir quand il est approprié et possible d'utiliser ces mots clés. En particulier, ils doivent savoir que l'asynchronisation ne peut être placée avant le mot-clé de fonction sur une définition de fonction. La fonction est alors considérée comme un retour de promesse. Le mot-clé "await" ne peut être utilisé qu'à l'intérieur d'une telle fonction asynchrone et doit être placé avant un appel à une fonction qui rendra une Promesse.
Les éléments d'une liste peuvent être ajoutés ou supprimés, ce qui signifie que la taille de la liste peut changer. Les méthodes permettent de nombreux types de manipulations, y compris l'insertion ou la suppression dans un index spécifique. Les plages peuvent également être manipulées.
La Liste est une interface, donc quand on manipule une Liste, une vraie classe, généralement ArrayList, est utilisée en coulisse
Une liste repose sur les méthodes de tri de Collections, telles que Collections.sort().
Les méthodes de recherche contain(), indexOf(), et lastIndexOf() sont des exemples qui peuvent être utilisés pour rechercher les éléments. Cependant, pour effectuer une recherche binaire, il faut appeler la méthode plus générale : Collections.binarySearch(...)
Les listes peuvent contenir des objets de type mixte, par exemple :
List interviewList = new ArrayList();
interviewList.add(3);
interviewList.add(1415);
interviewList.add(“Pi”);
Bonus
Les tableaux peuvent stocker des objets, il existe donc une solution de rechange pour ceux qui sont enclins à mélanger les types dans un tableau. De plus, le candidat doit être crédité de savoir que les Listes remplacent les Vecteurs qui ne sont plus couramment utilisés en Java. La raison est liée à la simultanéité et à la synchronisation des opérations. Il est clair qu'une explication plus détaillée dépasse la portée de cette question - cependant, la mention de ce point est digne d'intérêt.
Mauvaise réponse
Les tableaux et les listes, parmi d'autres classes et interfaces intégrées, y compris les collections, sont très courants dans la programmation Java et le développement d'applications. Un candidat qui n'est pas à l'aise avec ces fonctionnalités manque presque certainement d'expérience avec le langage.
Contrairement au C++, Java ne prend pas en charge l'héritage multiple. Comment la programmation avec une interface apportera-t-elle une réponse à ce problème ? Une interface fait-elle partie de la hiérarchie des classes ?
Justification
S'il existe des points communs entre les langues que de nombreux programmeurs connaissent bien, il existe aussi des distinctions qui permettent de les définir. Dans un entretien en Java, il y aura des questions de base en Java qui aideront à évaluer dans quelle mesure le candidat connaît les spécificités du langage de programmation Java. Étant donné la question du problème du diamant en C++, il est intéressant de tester les connaissances du candidat dans une perspective java.
Bonne réponse
Une interface est similaire à une classe en ce sens qu'elle peut contenir différents types de méthodes, mais différente parce qu'elle ne détient pas l'état. Les interfaces sont intrinsèquement abstraites, et leurs méthodes doivent être implémentées par une classe. L'interface n'est pas instanciée, elle est implémentée. Contrairement au C++, une classe ne peut étendre qu'un seul parent (c'est-à-dire qu'elle ne peut avoir qu'une seule superclasse). Une interface, en revanche, est capable d'étendre plus d'une interface parent. Par exemple :
public interface CheckerBoard {
public void setSize(int rowCount, int columnCount);
}
public interface Game {
public void setNumberOfPlayers();
public void play();
}
public interface ChessGame extends CheckerBoard, Game {}
Dans cet exemple, l'interface ChessGame hérite à la fois de CheckerBoard et de Game.
Mauvaise réponse
Si la personne interrogée ne sait pas ce qu'est l'héritage multiple, cela suggère un manque d'expérience en matière de conception orientée objet. Cela n'est pas essentiel pour toutes les applications, bien qu'il soit important de reconnaître que java est intrinsèquement OO.
Qu'est-ce que la machine virtuelle Java ? Quel en est l'objectif principal et avec quel type de code fonctionne-t-elle ?
Justification
Aucune interview en Java ne serait complète sans une question sur le thème de la machine virtuelle. La JVM est un élément clé de Java, et les programmeurs java l'apprennent très tôt. Si la JVM est capable d'exécuter du bytecode généré par d'autres langages, tels que JRuby et Jython, cela n'enlève rien au fait qu'elle est essentielle à la java elle-même.
Bonne réponse
La JVM est une machine virtuelle qui permet à l'ordinateur d'exécuter des programmes Java qui ont été compilés en bytecode. Le bytecode est indépendant de la plateforme, et s'exécute sur tout ordinateur qui héberge une JVM. Il comprend un compilateur juste à temps (JIT) qui convertit le bytecode en instructions en langage machine, permettant aux applications de s'exécuter aussi rapidement qu'un exécutable natif.
Mauvaise réponse
La JVM est l'un des principaux composants qui font de Java ce qu'il est. Le fait de ne pas connaître la JVM indique probablement un manque d'expérience avec le langage.
Quelles sont les méthodes et les classes finales ? Une classe abstraite supportera-t-elle les méthodes finales ?
Justification
Le dernier mot-clé est commun et doit être bien compris par les programmeurs java. Au cours de la phase de conception OO, il est normalement décidé si les classes doivent être extensibles. Si ce n'est pas le cas, elles sont marquées comme finales afin de limiter les effets secondaires potentiels de sous-classes qui n'ont pas été envisagées. Il s'agit d'une caractéristique importante qui devrait être utilisée pour un code plus robuste et plus facile à maintenir.
Bonne réponse
Une méthode qui est déclarée avec le mot-clé final ne peut pas être annulée dans les sous-classes. Cette méthode est utilisée dans les hiérarchies où la mise en œuvre de la méthode doit être cohérente dans l'ensemble. La déclaration finale d'une classe interdit totalement le sous-classement. Oui, il est possible d'inclure des méthodes finales dans une classe abstraite. Cela permet de s'assurer que les sous-classes ne peuvent pas passer outre la méthode.
Mauvaise réponse
Si le candidat n'est pas familier avec le mot-clé final, qu'il soit utilisé au niveau de la classe ou de la méthode, alors cela suggère une relative inexpérience de la langue. Même pour les programmeurs inexpérimentés qui ont participé à la conception orientée objet, le concept de classe finale devrait être familier.
La programmation Java permet de créer un fil de discussion de différentes manières. Quelles sont-elles et quelle est la méthode préférée ? Expliquez.
Justification
Contrairement au C++, java contient un support intégré pour le multithreading. C'est une fonctionnalité riche et puissante qui est à la fois pertinente et utile dans de nombreuses applications. En tant que tel, le candidat doit être familier avec les bases.
Bonne réponse
Que se passe-t-il dans le cas où la réduction est appelée sur un tableau vide sans fournir la valeur initiale facultative de l'accumulateur ?
public class JavaInterviewClass implements Runnable {
public void run() {
System.out.println(“My example public class prints this line from a thread.”);
}
}
Pour exécuter la méthode run(), passez une instance de la classe dans un Thread, comme suit :
Thread interviewThread = new Thread(new JavaInterviewClass ());
interviewThread.start();
La deuxième façon de créer un fil de discussion est d'étendre la classe de fil de discussion. La sous-classe remplacera la méthode run(). Après cela, il suffit de créer une instance de la classe.
public class JavaInterviewClass extends Thread {
public void run() {
System.out.println(“My example public class extends the Thread class.”);
}
}
Pour exécuter le fil de discussion, il suffit d'instancier la classe et d'appeler start(), comme suit :
JavaInterviewClass myInterview = new JavaInterviewClass (); myInterview.start();
Bonus
Bien que l'implémentation de l'interface exécutable et l'extension de la classe Thread soient deux moyens populaires de créer un thread, il est également possible d'utiliser le framework Executor. Celui-ci permet de travailler directement avec les threads, mais il est moins connu. Il comprend des méthodes telles que newSingleThreadExecutor(), newFixedThreadPool() et submit() pour créer des tâches d'exécution. La connaissance de l'utilisation du framework Executor implique que le candidat soit très à l'aise avec la création et l'utilisation de threads en java.
Mauvaise réponse
Si le candidat n'est pas à l'aise avec l'utilisation des fils de discussion, il passe à côté d'une caractéristique puissante et importante de la langue. C'est important car comprendre le multithreading ne se limite pas à rechercher la syntaxe de quelques commandes. Il s'agit plutôt d'une approche qui doit être envisagée lors de la conception et du développement d'une application.
Le code Java a un support intégré pour la concurrence dans sa classe Thread. La simultanéité a son propre ensemble de problèmes tels que l'impasse et les conditions de course. Décrivez brièvement les variables Atomic en Java et leur utilisation. Ensuite, il est indiqué que la méthode start() est utilisée pour créer une pile d'appels séparée avant que la méthode run() ne soit utilisée pour exécuter un thread. Que font les méthodes yield(), sleep() et join() ?
Justification
La prise en charge du multithreading par Java peut entraîner des problèmes liés à la concurrence. Les connaissances du candidat concernant ces problèmes doivent être évaluées et prises en compte.
Bonne réponse
Une variable atomique est une variable "mise à jour atomique", ce qui signifie que l'intégrité des données est assurée par l'utilisation d'algorithmes non bloquants. Cette fonctionnalité est généralement mise en œuvre au niveau du code machine. Java prend en charge plusieurs variables atomiques, le plus souvent AtomicBoolean, AtomicInteger, AtomicLong et AtomicReference. Il existe également plusieurs méthodes qui permettent de récupérer et de modifier ces variables, notamment get(), set(), lazySet(), compareAndSet() et weakCompareAndSet(). Utilisées correctement, les variables atomiques peuvent être utilisées pour mettre en œuvre des méthodes "thread safe" (multithreading safe) qui traitent efficacement certains problèmes liés à la concurrence.
rendement() : Cette méthode informe l'environnement que le fil de discussion actuel n'est pas en train d'achever une tâche de haute priorité, et est prêt à en interrompre l'exécution. À condition que l'environnement sous-jacent supporte l'ordonnancement préventif, elle suspendra le fil s'il y en a un autre qui doit s'exécuter. S'il n'y a pas de deuxième fil, ou si le deuxième fil se termine, le fil en cours reprendra le contrôle et continuera à s'exécuter.
sommeil() : Cette méthode fait dormir le fil courant, ou met en pause son exécution, pendant un nombre de millisecondes déterminé. Il est également possible de combiner un certain nombre de millisecondes et de nanosecondes. Pendant que le fil courant est en sommeil, un autre fil sera exécuté, ou sinon le CPU restera inactif. Sous réserve de la précision de l'horloge du système et des minuteurs, le fil de discussion reprendra le contrôle une fois le compte à rebours terminé.
join() : Cette méthode est utilisée pour joindre deux l'exécution de deux fils ensemble. Pour clarifier, si le fil A appelle join() sur le fil B, alors A commencera à attendre. Une fois que B a terminé, ou qu'un délai prédéfini a expiré, A reprendra le contrôle et continuera l'exécution.
Mauvaise réponse
Le fait de connaître les fils de discussion Java, mais de ne pas être conscient des problèmes liés à la concurrence peut entraîner de graves erreurs. La majorité des appareils, des ordinateurs de bureau aux appareils mobiles en passant par les ordinateurs à carte unique, prennent désormais généralement en charge le multithreading et la concurrence. Il est important de comprendre la bonne utilisation des threads, et d'être conscient des méthodes fournies par java pour les prendre en charge.
Conclusion
Les questions de cet article sont utiles pour évaluer les compétences d'un futur programmeur Java. En ce qui concerne les questions d'entretien à préparer pour un développeur Java, il est important de se rappeler que les spécificités du langage peuvent être facilement référencées en utilisant l'aide et la documentation en ligne. Les points subtils d'un langage ne sont pas aussi importants que la façon dont on applique la logique. Cela dit, les candidats à ce poste sont censés connaître le langage et ne pas avoir besoin d'une formation approfondie avant que le travail réel ne commence. Les compétences requises seront dictées par le travail à effectuer, et la variation des questions données ci-dessus aidera à faire cette évaluation. N'oubliez pas que l'une des meilleures façons d'évaluer les compétences du candidat pour votre projet est d'effectuer une évaluation pratique de la programmation, ce qui est bien plus efficace que des questions d'entretien orales pour engager un programmeur Java hautement qualifié.
Qu'est-ce qu'une exception ? Décrivez brièvement les deux types d'exception utilisés dans le code java.
Justification
Les exceptions sont des événements inattendus qui surviennent au moment de l’exécution et qui diffèrent des erreurs dans la mesure où il est généralement aisé de les « rattraper ». Les erreurs, par contre, indiquent généralement un problème plus grave. La gestion des exceptions est très courante et doit être comprise, au moins à un niveau de base, par n’importe quel programmeur Java.
Bonne réponse
Les deux types d’exceptions dans Java sont les exceptions vérifiées et les exceptions non-vérifiées.
Une exception vérifiée est une exception qui est vérifiée au moment de la compilation. Lorsqu’il y a du code dans une méthode qui lève une exception vérifiée, la méthode est nécessaire pour l’acquitter. Ceci peut être accompli soit en gérant l’exception avec un bloc try/catch, soit en la spécifiant à l’aide du mot-clé throws. Une exception non-vérifiée est une exception qui n’est pas vérifiée au moment de la compilation. C’est au programmeur de spécifier ce type d’exception. En revanche, il faut noter que toutes les exceptions en C++ sont non-vérifiées.
Bonus
En Java, toutes les exceptions des classes Error et RuntimeException sont décochées. Tout le reste sous Throwable est vérifié. Si la personne interrogée soulève ce point particulier, elle démontre une compréhension profonde de la question qui lui a été posée.
Mauvaise réponse
Si le candidat n’est pas au courant des exceptions, il lui manque une partie essentielle du langage qui est responsable du contrôle de l’exécution. Cette fonctionnalité représente un véritable bond en avant par rapport à des langages tels que C (qui ne supporte pas la gestion des exceptions). Bien qu’elles ne soient pas absolument indispensables, les exceptions sont extrêmement utiles au quotidien du fait de leurs nombreux avantages, tout développeur Java efficace les utilise.
Que sont les cours d'emballage ? Donnez des exemples de deux d'entre elles et des primitives correspondantes. Quel est le rapport entre chacune d'elles et un objet ?
Justification
Les classes d’emballage sont fondamentales en programmation Java. En fait, leur existence implique que java n’est pas 100% orienté objet (bonus au candidat qui le signale !). C’est le cas parce que Java contient 8 types de données primitives qui ne sont pas, par définition, des objets.
Bonne réponse
Une classe d’emballage est une classe qui contient une variable qui est un type de données primitives, et qui enveloppe la primitive pour fournir une fonctionnalité d’interaction avec elle. En fait, on peut dire qu’il transforme le primitif en objet. Ce qui est utile, par exemple, lorsqu’une méthode vise au transfert d’un objet. Le candidat doit être capable de nommer au moins deux des paires suivantes :
Primitive
Classe d'emballage
boolean
Boolean
byte
Byte
char
Char
double
Double
float
Float
int
Int
long
Long
short
Short
Mauvaise réponse
Les classes d’emballage sont définies en java.lang, et requises car il existe de nombreuses classes qui supportent uniquement les objets. Le fait de ne pas connaître ces classes d’emballage, ou de ne pas savoir pourquoi elles seraient utilisées, apparaît comme une grave lacune de la part du candidat interrogé.
Définissez les termes suivants qui sont courants dans la programmation java
Classe abstraite
Ramasse-miettes (aussi appelé récupérateur de mémoire, glaneur de cellules ou garbage collector)
Autoboxing
Sérialisation
Justification
Cette liste inclut des termes qui sont communément utilisés en Java, ainsi que dans d’autres langages de programmation. Les questions d’entretien pour les programmeurs expérimentés incluent de telles définitions parce qu’elles permettent de tester leurs connaissances de manière approfondie, ainsi que leur capacité à distinguer des langages comportant des concepts proches sans être parfaitement identiques.
Bonne réponse
Une classe abstraite est utilisée comme classe de base pour les sous-classes qui vont étendre ou écraser ses méthodes. Prenons l’exemple d’une classe « Forme ». Une forme peut contenir un certain nombre de côtés, de faces ou même de dimensions. Prise isolément, savoir que cette classe est une « Forme » est peu utile. D’autre part, si cette classe abstraite sera utilisée comme classe de base pour un « Carré », un « Triangle », ou un autre type de polygone, elle deviendra utile quand placée au sommet de la hiérarchie des classes. - Il n'est pas possible d'instancier une classe abstraite. – Elle peut contenir des méthodes abstraites, mais ce n’est pas obligatoire. - Les sous-classes de la classe d'abstraction doivent mettre en œuvre toutes les méthodes d'abstraction, à moins qu'il ne s'agisse également d'une classe d'abstraction. Il n'est pas possible d'instancier une classe abstraite.
Ne pas être parfaitement calé à propos classes abstraites n’est pas éliminatoire, bien que ces dernières seront très probablement rencontrées par le programmeur Java lorsqu’il devra effectuer des actions de maintenance ou du débogage d’une base de code existante.
La "garbage collection" (effectuée par le "garbage collector" ou ramasse-miettes) est le processus de détection et de suppression des objets en mémoire qui ne sont plus utilisés ou référencés. En java, le ramassage des miettes est automatique, mais il peut aussi être demandé.
Les commandes System.gc() et Runtime.gc() indiqueront au ramasse-miettes qu’il doit s’exécuter, bien que cela ne soit pas garanti.
Les fils d’exécution sont mis en pause pendant le ramassage des ordures. Cela ralentit nécessairement l’exécution, ce qui signifie que dans les applications réactives, le ramassage des miettes doit être réduit au minimum. La connaissance du ramasseur de miettes n’est pas indispensable, surtout pour un programmeur débutant. Il est à noter, cependant, que lorsqu’on vient d’un langage comme C, où toute la mémoire est gérée manuellement, le développeur doit être au courant de l’existence de cette fonctionnalité.
L’Autoboxing est l’emballage automatique d’un type primitif (voir la question #4 relative aux types primitifs et classes d’emballages). Par exemple, l’autoboxing convertira automatiquement un nombre de type float (type primitif) en Float (classe d’emballage). Le contraire de cela est le déballage, lors duquel type primitif est extrait de la classe d’emballage. Cette notion est habituellement familière aux bons développeurs Java.
La sérialisation fait référence à l’encodage d’objets en mémoire dans un flux d’octets qui pouvant être facilement stockés ou transmis. Le contraire est la désérialisation, qui reconstruit les objets à partir d’un flux d’octets. Il existe différentes approches pour réaliser la sérialisation. Deux méthodes courantes sont la conversion de l’objet en XML (eXtensible Markup Language), ou JSON (JavaScript Object Notation). Ce sont des types de fichiers bien connus, chacun d’entre eux étant largement pris en charge. Java supporte également la sérialisation comme partie intégrante du langage. Le langage inclut l’interface sérialisable, qui peut être utilisée à la fois pour la sérialisation et la désérialisation. La méthode writeObject() est utilisée pour encoder les données, tandis que la méthode readObject() est utilisée pour reconstruire les objets.
Java définit une classe String pour représenter des tableaux de caractères. Répondez aux questions suivantes :
Un constructeur initialise un objet lors de sa création. Cependant, les constructeurs n'ont pas de type de retour explicite.
En général, vous utiliserez un constructeur pour donner des valeurs initiales aux variables d'instance définies par la classe, ou pour effectuer toute autre procédure de démarrage nécessaire pour créer un objet entièrement formé.
Toutes les classes ont des constructeurs, que vous en définissiez un ou non, car Java fournit automatiquement un constructeur par défaut qui initialise toutes les variables membres à zéro. Cependant, une fois que vous avez défini votre propre constructeur, le constructeur par défaut n'est plus utilisé.
Pourriez-vous citer quelques cadres de travail Java ?
Cette question d'entretien est une question de base : tout développeur Java compétent est en mesure de nommer quelques frameworks écrits en langage Java. Au cours de l'entretien, le candidat interrogé doit mentionner au moins trois frameworks Java parmi cette liste :
JSF (Java Server Faces), un cadre web Java qui facilite la construction d'interfaces utilisateur pour les applications basées sur des serveurs
GWT (Google Web Toolkit), un ensemble d'outils open-source qui aide les programmeurs à créer et à maintenir des applications JavaScript dans Java Spring, un framework Java qui n'impose aucun modèle de programmation spécifique
Struts
Hiberner
Grails
Jouez !
Vaadin
Maven
Questions d'entretien sur la programmation mixte
Java définit une classe String pour représenter des tableaux de caractères. Répondez aux questions suivantes :
- Par quoi faut-il remplacer le "XXX" pour pouvoir comparer les deux principaux arcs de cordes ? Si les arguments sont : "Sun Microsystems" et "Sun microsystems", quel sera le résultat de l'exécution ? Y a-t-il un moyen de garantir qu'il les déclarera comme étant identiques ? - Si les arguments sont plutôt : "Sun Microsystems" et "Sun Microsystems", quel sera le résultat de l'exécution ? "Sun Microsystem" et "Sun Microsystems", quel sera le résultat de l'exécution ?
1/ Après la création d'une chaîne, est-il possible de la modifier ? Considérez ce qui suit :
public static void main(String[] args) { String name = "James gosling"; // I want to change the 'g' to a 'G'. // Will this work at compile time? name.charAt(6) = 'G'; // Print with the standard system println to see “James Gosling” System.out.println(name); }
Cela va-t-il fonctionner ? Si ce n'est pas le cas, quelles modifications faudrait-il apporter pour obtenir la chaîne souhaitée ?
2/ La classe String a plus d'un Comparateur. Considérez le code suivant :
public static void main(String[] args) { // This program received 2 arguments. We want to // determine if those two strings are equal. // Compare the first argument to the second argument boolean compareResult = (XXX); if (compareResult) { System.out.println("The Strings are the same."); } else { System.out.println("The Strings are not the same."); } // Print the main string args System.out.println(args[0]); System.out.println(args[1]); }
- Par quoi faut-il remplacer le "XXX" pour pouvoir comparer les deux principaux arcs de cordes ? Si les arguments sont : "Sun Microsystems" et "Sun microsystems", quel sera le résultat de l'exécution ? Y a-t-il un moyen de garantir qu'il les déclarera comme étant identiques ? - Si les arguments sont plutôt : "Sun Microsystems" et "Sun Microsystems", quel sera le résultat de l'exécution ? "Sun Microsystem" et "Sun Microsystems", quel sera le résultat de l'exécution ?
3/ Qu'est-ce que le pool de constantes de la chaîne Java ? (ou pool de chaînes de caractères Java) ? Il réside dans la mémoire de la pile ?
Justification
L'utilisation de représentations de chaînes de caractères est courante dans de nombreux langages, et Java ne fait pas exception. Il est important de comprendre comment les chaînes de caractères sont créées, analysées, imprimées et manipulées. C'est un sujet important qui constitue une question d'entretien importante pour les développeurs Java.
Bonne réponse
Non, cela échouera au moment de la compilation car il n'est pas possible de modifier une chaîne une fois qu'elle a été initialisée. Cette propriété est dite immuable. Pour que cela fonctionne, il faudrait recréer la chaîne contenant "James gosling". Une approche consiste à utiliser un tableau de caractères intermédiaires (en appelant la méthode toCharArray() sur le "nom"), à remplacer le "g" par la lettre majuscule, puis à recréer la chaîne avant de l'imprimer. Un bonus pour le candidat qui souligne que la fonction string replace(...) existe pour remplacer les caractères, mais ne peut pas être utilisée car toutes les instances de "g" minuscules seraient remplacées.
Le comparateur exact dans cet exemple est soit égal(...) soit égalIgnoreCase(...). Le type de retour de ces deux méthodes est une valeur booléenne. Si la personne interrogée répond compareTo(...) ou compareToIgnoreCase(...), alors le crédit devrait être accordé, bien que le type de retour de ces méthodes soit un int, donc techniquement incorrect. Il n'en reste pas moins qu'elle démontre une connaissance de la langue.
Dans le premier exemple, les chaînes sont identiques sous equalsIgnoreCase(...), mais différentes sous equals(...). Dans le deuxième exemple, il y a un "s" à la fin, ce qui fait que les chaînes sont différentes dans tous les cas.
Le Java Constant String Pool est une zone de la mémoire du Heap (donc, pas de la mémoire de la pile) où sont stockées les chaînes de caractères. Cette approche est à l'origine de la raison pour laquelle les chaînes sont immuables en java.
Par exemple :
chaîne x = "chaîne principale" ;
chaîne de caractères y = "machine virtuelle" ;
chaîne z = "chaîne principale" ;
Les trois cordes ci-dessus sont stockées dans le pool de cordes, mais la partie intéressante est l'efficacité. x et y pointent tous deux vers la même zone dans la réserve de cordes, ce qui ne nécessite pas de duplication de l'espace. Sachant cela, il doit être clair que la modification de la valeur de x n'est pas autorisée car elle aurait l'effet secondaire non voulu de modifier z.
Quelles sont les différences entre la mémoire Stack et l'espace Heap ?
Justification
Afin d'améliorer l'efficacité, la JVM organise la mémoire pour que les applications puissent s'exécuter. Elle crée de l'espace de pile et de l'espace de tas, chacun étant utilisé par des opérations différentes. Comprendre l'allocation de la mémoire à ce niveau peut conduire à un ramassage des déchets plus prévisible et, en fin de compte, à une efficacité accrue.
Bonne réponse
La mémoire en pile est utilisée pour l'allocation de mémoire statique, comme les valeurs primitives à l'intérieur d'une méthode. Elle est toujours utilisée pour l'exécution d'un thread. La pile s'agrandit lorsque les méthodes sont appelées, et se réduit lorsqu'elles reviennent. Si la mémoire allouée pour la pile est dépassée, l'exception java.lang.StackOverFlowError est lancée.
La mémoire de tas est utilisée pour l'allocation de mémoire dynamique, comme les objets java. Plus précisément, l'objet est stocké dans le tas, tandis que la référence à l'objet est stockée dans la pile. Les classes JRE sont également stockées dans le tas au moment de l'exécution. L'accès aux données dans le tas est plus lent que dans la mémoire de la pile. Le tas requiert l'action du collecteur de déchets afin de libérer les objets inutilisés. Si la mémoire allouée au tas est dépassée, l'exception java.lang.OutOfMemoryError est lancée.
Mauvaise réponse
Le fait de n'avoir jamais entendu parler de la pile ou du tas indiquerait une connaissance superficielle du langage de programmation java. De plus, la terminologie est typique d'une culture générale de programmation. Le diagnostic des erreurs liées à la mémoire, telles qu'un débordement de pile causé par un comportement incorrect d'une fonction récursive, serait plus facile avec cette compréhension.
Deux termes liés à la classe utilisés dans la programmation java sont "subclass" et "nested class". Expliquez les différences entre ces deux termes. Pourquoi choisir l'une plutôt que l'autre ? Laquelle est parfois appelée "classe intérieure" ?
Justification
Dans la conception orientée objet, il y a souvent une confusion sur le placement des classes dans la hiérarchie. Les classes imbriquées sont relativement rares par rapport aux sous-classes, mais leur utilisation est bénéfique dans de nombreuses situations. La connaissance de leur existence et de leur mode d'utilisation doit être considérée comme un atout.
Bonne réponse
Une sous-classe est une extension d'une autre classe, et est souvent une spécialisation de l'original. Les sous-classes héritent des membres publics et protégés de leur super-classe. Les sous-classes peuvent être instanciées indépendamment de la superclasse, et en fait, c'est toujours le cas lorsque la superclasse est une classe abstraite.
Une classe imbriquée est une classe à l'intérieur d'une classe, qui dans certains cas est une classe intérieure. Le champ d'application de la classe intérieure comprend tous les membres de sa classe extérieure, ce qui lui donne accès à ces variables et méthodes. Comme le corps existe entièrement au sein de la classe englobante, il ne peut pas être instancié indépendamment, sans elle.
L'utilisation d'une classe interne peut améliorer la conception orientée objet en organisant davantage le code. L'objectif est limité dans la mesure où il existe pour servir sa classe englobante. Si la classe interne offre des fonctionnalités utiles à une plus grande échelle, il serait plus logique de l'avoir comme classe de haut niveau. Les classes internes sont couramment utilisées comme fonctions de rappel pour les composants de l'interface graphique.
Bonus
Il existe deux types de classes imbriquées. Plus précisément, il existe une classe imbriquée statique, qui n'a pas directement accès aux autres membres de la classe englobante. Celles-ci ne sont pas souvent utilisées, c'est pourquoi le fait de les connaître est un bonus par opposition à l'ignorance qui peut entraîner une pénalité. L'autre type est une classe imbriquée non statique, qui est la version que l'on appelle une classe intérieure. Ceux-ci ont en effet accès à tous les membres de la classe englobante, y compris aux méthodes privées.
Mauvaise réponse
Le candidat doit être pardonné de n'avoir jamais utilisé une classe imbriquée. Bien qu'utile, et susceptible d'être vu si l'on maintient une base de code existante, le concept est simple. Les classes imbriquées rendent souvent le code plus élégant et plus facile à maintenir, mais certains concepteurs considèrent que c'est une question de style. Les sous-classes, d'autre part, sont un élément fondamental de la programmation orientée objet que tout développeur java devrait connaître. Ne pas pouvoir discuter facilement des sous-classes au sein d'une hiérarchie de classes est un sérieux signal d'alarme.
Deux classes de collection sont disponibles en programmation java : Array et List. En quoi les méthodes diffèrent-elles entre ces deux objets conteneurs, et dans quelles circonstances choisiriez-vous l'une plutôt que l'autre ?
Justification
L'utilisation de conteneurs est courante en Java et dans d'autres langages de programmation. La liste est une structure de données dynamique, tandis que le tableau est statique. Il est important de reconnaître que chacun d'entre eux est mieux adapté à certaines applications, et à ce titre, le candidat doit les connaître. Avoir une connaissance approfondie des types de données et des classes de conteneurs disponibles permettra en fin de compte de gagner du temps de développement.
Bonne réponse
Array
Les tableaux sont de taille statique, ils ne peuvent donc ni croître ni diminuer en termes de nombre d'éléments. Cela signifie qu'il existe des méthodes pour accéder aux éléments et les modifier, mais pas pour les insérer ou les supprimer.
Java fournit des méthodes pour effectuer une recherche binaire ou un tri sur un tableau. De plus, un tableau peut être initialisé en utilisant la méthode fill(), ou comparé en utilisant le comparateur equals().
La taille d'un tableau est fixée lors de sa création.
L'accès aléatoire d'un élément dans un tableau est très efficace.
Les tableaux sont plus adaptés à des collections d'éléments de longueur fixe.
Tous les éléments sont du même type, par exemple :
int[] interviewArray = new int[5];
or
int[] arrayForInterview = {3, 1, 4, 1, 5};
Ces deux tableaux contiennent cinq entiers.
Vecteur
Les candidats doivent savoir quand il est approprié et possible d'utiliser ces mots clés. En particulier, ils doivent savoir que l'asynchronisation ne peut être placée avant le mot-clé de fonction sur une définition de fonction. La fonction est alors considérée comme un retour de promesse. Le mot-clé "await" ne peut être utilisé qu'à l'intérieur d'une telle fonction asynchrone et doit être placé avant un appel à une fonction qui rendra une Promesse.
Les éléments d'une liste peuvent être ajoutés ou supprimés, ce qui signifie que la taille de la liste peut changer. Les méthodes permettent de nombreux types de manipulations, y compris l'insertion ou la suppression dans un index spécifique. Les plages peuvent également être manipulées.
La Liste est une interface, donc quand on manipule une Liste, une vraie classe, généralement ArrayList, est utilisée en coulisse
Une liste repose sur les méthodes de tri de Collections, telles que Collections.sort().
Les méthodes de recherche contain(), indexOf(), et lastIndexOf() sont des exemples qui peuvent être utilisés pour rechercher les éléments. Cependant, pour effectuer une recherche binaire, il faut appeler la méthode plus générale : Collections.binarySearch(...)
Les listes peuvent contenir des objets de type mixte, par exemple :
List interviewList = new ArrayList();
interviewList.add(3);
interviewList.add(1415);
interviewList.add(“Pi”);
Bonus
Les tableaux peuvent stocker des objets, il existe donc une solution de rechange pour ceux qui sont enclins à mélanger les types dans un tableau. De plus, le candidat doit être crédité de savoir que les Listes remplacent les Vecteurs qui ne sont plus couramment utilisés en Java. La raison est liée à la simultanéité et à la synchronisation des opérations. Il est clair qu'une explication plus détaillée dépasse la portée de cette question - cependant, la mention de ce point est digne d'intérêt.
Mauvaise réponse
Les tableaux et les listes, parmi d'autres classes et interfaces intégrées, y compris les collections, sont très courants dans la programmation Java et le développement d'applications. Un candidat qui n'est pas à l'aise avec ces fonctionnalités manque presque certainement d'expérience avec le langage.
Contrairement au C++, Java ne prend pas en charge l'héritage multiple. Comment la programmation avec une interface apportera-t-elle une réponse à ce problème ? Une interface fait-elle partie de la hiérarchie des classes ?
Justification
S'il existe des points communs entre les langues que de nombreux programmeurs connaissent bien, il existe aussi des distinctions qui permettent de les définir. Dans un entretien en Java, il y aura des questions de base en Java qui aideront à évaluer dans quelle mesure le candidat connaît les spécificités du langage de programmation Java. Étant donné la question du problème du diamant en C++, il est intéressant de tester les connaissances du candidat dans une perspective java.
Bonne réponse
Une interface est similaire à une classe en ce sens qu'elle peut contenir différents types de méthodes, mais différente parce qu'elle ne détient pas l'état. Les interfaces sont intrinsèquement abstraites, et leurs méthodes doivent être implémentées par une classe. L'interface n'est pas instanciée, elle est implémentée. Contrairement au C++, une classe ne peut étendre qu'un seul parent (c'est-à-dire qu'elle ne peut avoir qu'une seule superclasse). Une interface, en revanche, est capable d'étendre plus d'une interface parent. Par exemple :
public interface CheckerBoard {
public void setSize(int rowCount, int columnCount);
}
public interface Game {
public void setNumberOfPlayers();
public void play();
}
public interface ChessGame extends CheckerBoard, Game {}
Dans cet exemple, l'interface ChessGame hérite à la fois de CheckerBoard et de Game.
Mauvaise réponse
Si la personne interrogée ne sait pas ce qu'est l'héritage multiple, cela suggère un manque d'expérience en matière de conception orientée objet. Cela n'est pas essentiel pour toutes les applications, bien qu'il soit important de reconnaître que java est intrinsèquement OO.
Qu'est-ce que la machine virtuelle Java ? Quel en est l'objectif principal et avec quel type de code fonctionne-t-elle ?
Justification
Aucune interview en Java ne serait complète sans une question sur le thème de la machine virtuelle. La JVM est un élément clé de Java, et les programmeurs java l'apprennent très tôt. Si la JVM est capable d'exécuter du bytecode généré par d'autres langages, tels que JRuby et Jython, cela n'enlève rien au fait qu'elle est essentielle à la java elle-même.
Bonne réponse
La JVM est une machine virtuelle qui permet à l'ordinateur d'exécuter des programmes Java qui ont été compilés en bytecode. Le bytecode est indépendant de la plateforme, et s'exécute sur tout ordinateur qui héberge une JVM. Il comprend un compilateur juste à temps (JIT) qui convertit le bytecode en instructions en langage machine, permettant aux applications de s'exécuter aussi rapidement qu'un exécutable natif.
Mauvaise réponse
La JVM est l'un des principaux composants qui font de Java ce qu'il est. Le fait de ne pas connaître la JVM indique probablement un manque d'expérience avec le langage.
Quelles sont les méthodes et les classes finales ? Une classe abstraite supportera-t-elle les méthodes finales ?
Justification
Le dernier mot-clé est commun et doit être bien compris par les programmeurs java. Au cours de la phase de conception OO, il est normalement décidé si les classes doivent être extensibles. Si ce n'est pas le cas, elles sont marquées comme finales afin de limiter les effets secondaires potentiels de sous-classes qui n'ont pas été envisagées. Il s'agit d'une caractéristique importante qui devrait être utilisée pour un code plus robuste et plus facile à maintenir.
Bonne réponse
Une méthode qui est déclarée avec le mot-clé final ne peut pas être annulée dans les sous-classes. Cette méthode est utilisée dans les hiérarchies où la mise en œuvre de la méthode doit être cohérente dans l'ensemble. La déclaration finale d'une classe interdit totalement le sous-classement. Oui, il est possible d'inclure des méthodes finales dans une classe abstraite. Cela permet de s'assurer que les sous-classes ne peuvent pas passer outre la méthode.
Mauvaise réponse
Si le candidat n'est pas familier avec le mot-clé final, qu'il soit utilisé au niveau de la classe ou de la méthode, alors cela suggère une relative inexpérience de la langue. Même pour les programmeurs inexpérimentés qui ont participé à la conception orientée objet, le concept de classe finale devrait être familier.
La programmation Java permet de créer un fil de discussion de différentes manières. Quelles sont-elles et quelle est la méthode préférée ? Expliquez.
Justification
Contrairement au C++, java contient un support intégré pour le multithreading. C'est une fonctionnalité riche et puissante qui est à la fois pertinente et utile dans de nombreuses applications. En tant que tel, le candidat doit être familier avec les bases.
Bonne réponse
Que se passe-t-il dans le cas où la réduction est appelée sur un tableau vide sans fournir la valeur initiale facultative de l'accumulateur ?
public class JavaInterviewClass implements Runnable {
public void run() {
System.out.println(“My example public class prints this line from a thread.”);
}
}
Pour exécuter la méthode run(), passez une instance de la classe dans un Thread, comme suit :
Thread interviewThread = new Thread(new JavaInterviewClass ());
interviewThread.start();
La deuxième façon de créer un fil de discussion est d'étendre la classe de fil de discussion. La sous-classe remplacera la méthode run(). Après cela, il suffit de créer une instance de la classe.
public class JavaInterviewClass extends Thread {
public void run() {
System.out.println(“My example public class extends the Thread class.”);
}
}
Pour exécuter le fil de discussion, il suffit d'instancier la classe et d'appeler start(), comme suit :
JavaInterviewClass myInterview = new JavaInterviewClass (); myInterview.start();
Bonus
Bien que l'implémentation de l'interface exécutable et l'extension de la classe Thread soient deux moyens populaires de créer un thread, il est également possible d'utiliser le framework Executor. Celui-ci permet de travailler directement avec les threads, mais il est moins connu. Il comprend des méthodes telles que newSingleThreadExecutor(), newFixedThreadPool() et submit() pour créer des tâches d'exécution. La connaissance de l'utilisation du framework Executor implique que le candidat soit très à l'aise avec la création et l'utilisation de threads en java.
Mauvaise réponse
Si le candidat n'est pas à l'aise avec l'utilisation des fils de discussion, il passe à côté d'une caractéristique puissante et importante de la langue. C'est important car comprendre le multithreading ne se limite pas à rechercher la syntaxe de quelques commandes. Il s'agit plutôt d'une approche qui doit être envisagée lors de la conception et du développement d'une application.
Le code Java a un support intégré pour la concurrence dans sa classe Thread. La simultanéité a son propre ensemble de problèmes tels que l'impasse et les conditions de course. Décrivez brièvement les variables Atomic en Java et leur utilisation. Ensuite, il est indiqué que la méthode start() est utilisée pour créer une pile d'appels séparée avant que la méthode run() ne soit utilisée pour exécuter un thread. Que font les méthodes yield(), sleep() et join() ?
Justification
La prise en charge du multithreading par Java peut entraîner des problèmes liés à la concurrence. Les connaissances du candidat concernant ces problèmes doivent être évaluées et prises en compte.
Bonne réponse
Une variable atomique est une variable "mise à jour atomique", ce qui signifie que l'intégrité des données est assurée par l'utilisation d'algorithmes non bloquants. Cette fonctionnalité est généralement mise en œuvre au niveau du code machine. Java prend en charge plusieurs variables atomiques, le plus souvent AtomicBoolean, AtomicInteger, AtomicLong et AtomicReference. Il existe également plusieurs méthodes qui permettent de récupérer et de modifier ces variables, notamment get(), set(), lazySet(), compareAndSet() et weakCompareAndSet(). Utilisées correctement, les variables atomiques peuvent être utilisées pour mettre en œuvre des méthodes "thread safe" (multithreading safe) qui traitent efficacement certains problèmes liés à la concurrence.
rendement() : Cette méthode informe l'environnement que le fil de discussion actuel n'est pas en train d'achever une tâche de haute priorité, et est prêt à en interrompre l'exécution. À condition que l'environnement sous-jacent supporte l'ordonnancement préventif, elle suspendra le fil s'il y en a un autre qui doit s'exécuter. S'il n'y a pas de deuxième fil, ou si le deuxième fil se termine, le fil en cours reprendra le contrôle et continuera à s'exécuter.
sommeil() : Cette méthode fait dormir le fil courant, ou met en pause son exécution, pendant un nombre de millisecondes déterminé. Il est également possible de combiner un certain nombre de millisecondes et de nanosecondes. Pendant que le fil courant est en sommeil, un autre fil sera exécuté, ou sinon le CPU restera inactif. Sous réserve de la précision de l'horloge du système et des minuteurs, le fil de discussion reprendra le contrôle une fois le compte à rebours terminé.
join() : Cette méthode est utilisée pour joindre deux l'exécution de deux fils ensemble. Pour clarifier, si le fil A appelle join() sur le fil B, alors A commencera à attendre. Une fois que B a terminé, ou qu'un délai prédéfini a expiré, A reprendra le contrôle et continuera l'exécution.
Mauvaise réponse
Le fait de connaître les fils de discussion Java, mais de ne pas être conscient des problèmes liés à la concurrence peut entraîner de graves erreurs. La majorité des appareils, des ordinateurs de bureau aux appareils mobiles en passant par les ordinateurs à carte unique, prennent désormais généralement en charge le multithreading et la concurrence. Il est important de comprendre la bonne utilisation des threads, et d'être conscient des méthodes fournies par java pour les prendre en charge.
Conclusion
Les questions de cet article sont utiles pour évaluer les compétences d'un futur programmeur Java. En ce qui concerne les questions d'entretien à préparer pour un développeur Java, il est important de se rappeler que les spécificités du langage peuvent être facilement référencées en utilisant l'aide et la documentation en ligne. Les points subtils d'un langage ne sont pas aussi importants que la façon dont on applique la logique. Cela dit, les candidats à ce poste sont censés connaître le langage et ne pas avoir besoin d'une formation approfondie avant que le travail réel ne commence. Les compétences requises seront dictées par le travail à effectuer, et la variation des questions données ci-dessus aidera à faire cette évaluation. N'oubliez pas que l'une des meilleures façons d'évaluer les compétences du candidat pour votre projet est d'effectuer une évaluation pratique de la programmation, ce qui est bien plus efficace que des questions d'entretien orales pour engager un programmeur Java hautement qualifié.
Justification
Les variables statiques sont une caractéristique de Java régulièrement utilisée par les développeurs. Comme c’est le cas pour les variables globales, il est important pour les programmeurs de comprendre la portée de ces objets afin d’éviter un quelconque effet collatéral. Note à propos de la non-déclaration d’une variable : cela permet d’éviter de mal taper le nom d’une variable, car la variable mal orthographiée apparaîtra comme une nouvelle variable non déclarée.
Bonne réponse
La classe Apple partage la variable statique, bites, entre toutes ses instances. Par conséquent, lorsque la méthode takeBite() est appelée sur chacune des instances, la variable commune est mise à jour. Le résultat final se présente ainsi :
The Macintosh apple has 2 bite(s) out of it.
The Granny Smith apple has 2 bite(s) out of it.
Mauvaise réponse
Si le candidat répond que chacune des deux instances s’est vue retirée une seule bouchée (bite), cela indique un manque d’expérience avec les variables statiques. Ce sujet est trivial, mais un développeur Java le rencontrera fréquemment. Le fait de ne pas en avoir connaissance indique que le candidat manque probablement d’expérience pratique du langage.
Qu'est-ce qu'une exception ? Décrivez brièvement les deux types d'exception utilisés dans le code java.
Justification
Les exceptions sont des événements inattendus qui surviennent au moment de l’exécution et qui diffèrent des erreurs dans la mesure où il est généralement aisé de les « rattraper ». Les erreurs, par contre, indiquent généralement un problème plus grave. La gestion des exceptions est très courante et doit être comprise, au moins à un niveau de base, par n’importe quel programmeur Java.
Bonne réponse
Les deux types d’exceptions dans Java sont les exceptions vérifiées et les exceptions non-vérifiées.
Une exception vérifiée est une exception qui est vérifiée au moment de la compilation. Lorsqu’il y a du code dans une méthode qui lève une exception vérifiée, la méthode est nécessaire pour l’acquitter. Ceci peut être accompli soit en gérant l’exception avec un bloc try/catch, soit en la spécifiant à l’aide du mot-clé throws. Une exception non-vérifiée est une exception qui n’est pas vérifiée au moment de la compilation. C’est au programmeur de spécifier ce type d’exception. En revanche, il faut noter que toutes les exceptions en C++ sont non-vérifiées.
Bonus
En Java, toutes les exceptions des classes Error et RuntimeException sont décochées. Tout le reste sous Throwable est vérifié. Si la personne interrogée soulève ce point particulier, elle démontre une compréhension profonde de la question qui lui a été posée.
Mauvaise réponse
Si le candidat n’est pas au courant des exceptions, il lui manque une partie essentielle du langage qui est responsable du contrôle de l’exécution. Cette fonctionnalité représente un véritable bond en avant par rapport à des langages tels que C (qui ne supporte pas la gestion des exceptions). Bien qu’elles ne soient pas absolument indispensables, les exceptions sont extrêmement utiles au quotidien du fait de leurs nombreux avantages, tout développeur Java efficace les utilise.
Que sont les cours d'emballage ? Donnez des exemples de deux d'entre elles et des primitives correspondantes. Quel est le rapport entre chacune d'elles et un objet ?
Justification
Les classes d’emballage sont fondamentales en programmation Java. En fait, leur existence implique que java n’est pas 100% orienté objet (bonus au candidat qui le signale !). C’est le cas parce que Java contient 8 types de données primitives qui ne sont pas, par définition, des objets.
Bonne réponse
Une classe d’emballage est une classe qui contient une variable qui est un type de données primitives, et qui enveloppe la primitive pour fournir une fonctionnalité d’interaction avec elle. En fait, on peut dire qu’il transforme le primitif en objet. Ce qui est utile, par exemple, lorsqu’une méthode vise au transfert d’un objet. Le candidat doit être capable de nommer au moins deux des paires suivantes :
Primitive
Classe d'emballage
boolean
Boolean
byte
Byte
char
Char
double
Double
float
Float
int
Int
long
Long
short
Short
Mauvaise réponse
Les classes d’emballage sont définies en java.lang, et requises car il existe de nombreuses classes qui supportent uniquement les objets. Le fait de ne pas connaître ces classes d’emballage, ou de ne pas savoir pourquoi elles seraient utilisées, apparaît comme une grave lacune de la part du candidat interrogé.
Définissez les termes suivants qui sont courants dans la programmation java
Classe abstraite
Ramasse-miettes (aussi appelé récupérateur de mémoire, glaneur de cellules ou garbage collector)
Autoboxing
Sérialisation
Justification
Cette liste inclut des termes qui sont communément utilisés en Java, ainsi que dans d’autres langages de programmation. Les questions d’entretien pour les programmeurs expérimentés incluent de telles définitions parce qu’elles permettent de tester leurs connaissances de manière approfondie, ainsi que leur capacité à distinguer des langages comportant des concepts proches sans être parfaitement identiques.
Bonne réponse
Une classe abstraite est utilisée comme classe de base pour les sous-classes qui vont étendre ou écraser ses méthodes. Prenons l’exemple d’une classe « Forme ». Une forme peut contenir un certain nombre de côtés, de faces ou même de dimensions. Prise isolément, savoir que cette classe est une « Forme » est peu utile. D’autre part, si cette classe abstraite sera utilisée comme classe de base pour un « Carré », un « Triangle », ou un autre type de polygone, elle deviendra utile quand placée au sommet de la hiérarchie des classes. - Il n'est pas possible d'instancier une classe abstraite. – Elle peut contenir des méthodes abstraites, mais ce n’est pas obligatoire. - Les sous-classes de la classe d'abstraction doivent mettre en œuvre toutes les méthodes d'abstraction, à moins qu'il ne s'agisse également d'une classe d'abstraction. Il n'est pas possible d'instancier une classe abstraite.
Ne pas être parfaitement calé à propos classes abstraites n’est pas éliminatoire, bien que ces dernières seront très probablement rencontrées par le programmeur Java lorsqu’il devra effectuer des actions de maintenance ou du débogage d’une base de code existante.
La "garbage collection" (effectuée par le "garbage collector" ou ramasse-miettes) est le processus de détection et de suppression des objets en mémoire qui ne sont plus utilisés ou référencés. En java, le ramassage des miettes est automatique, mais il peut aussi être demandé.
Les commandes System.gc() et Runtime.gc() indiqueront au ramasse-miettes qu’il doit s’exécuter, bien que cela ne soit pas garanti.
Les fils d’exécution sont mis en pause pendant le ramassage des ordures. Cela ralentit nécessairement l’exécution, ce qui signifie que dans les applications réactives, le ramassage des miettes doit être réduit au minimum. La connaissance du ramasseur de miettes n’est pas indispensable, surtout pour un programmeur débutant. Il est à noter, cependant, que lorsqu’on vient d’un langage comme C, où toute la mémoire est gérée manuellement, le développeur doit être au courant de l’existence de cette fonctionnalité.
L’Autoboxing est l’emballage automatique d’un type primitif (voir la question #4 relative aux types primitifs et classes d’emballages). Par exemple, l’autoboxing convertira automatiquement un nombre de type float (type primitif) en Float (classe d’emballage). Le contraire de cela est le déballage, lors duquel type primitif est extrait de la classe d’emballage. Cette notion est habituellement familière aux bons développeurs Java.
La sérialisation fait référence à l’encodage d’objets en mémoire dans un flux d’octets qui pouvant être facilement stockés ou transmis. Le contraire est la désérialisation, qui reconstruit les objets à partir d’un flux d’octets. Il existe différentes approches pour réaliser la sérialisation. Deux méthodes courantes sont la conversion de l’objet en XML (eXtensible Markup Language), ou JSON (JavaScript Object Notation). Ce sont des types de fichiers bien connus, chacun d’entre eux étant largement pris en charge. Java supporte également la sérialisation comme partie intégrante du langage. Le langage inclut l’interface sérialisable, qui peut être utilisée à la fois pour la sérialisation et la désérialisation. La méthode writeObject() est utilisée pour encoder les données, tandis que la méthode readObject() est utilisée pour reconstruire les objets.
Java définit une classe String pour représenter des tableaux de caractères. Répondez aux questions suivantes :
Un constructeur initialise un objet lors de sa création. Cependant, les constructeurs n'ont pas de type de retour explicite.
En général, vous utiliserez un constructeur pour donner des valeurs initiales aux variables d'instance définies par la classe, ou pour effectuer toute autre procédure de démarrage nécessaire pour créer un objet entièrement formé.
Toutes les classes ont des constructeurs, que vous en définissiez un ou non, car Java fournit automatiquement un constructeur par défaut qui initialise toutes les variables membres à zéro. Cependant, une fois que vous avez défini votre propre constructeur, le constructeur par défaut n'est plus utilisé.
Pourriez-vous citer quelques cadres de travail Java ?
Cette question d'entretien est une question de base : tout développeur Java compétent est en mesure de nommer quelques frameworks écrits en langage Java. Au cours de l'entretien, le candidat interrogé doit mentionner au moins trois frameworks Java parmi cette liste :
JSF (Java Server Faces), un cadre web Java qui facilite la construction d'interfaces utilisateur pour les applications basées sur des serveurs
GWT (Google Web Toolkit), un ensemble d'outils open-source qui aide les programmeurs à créer et à maintenir des applications JavaScript dans Java Spring, un framework Java qui n'impose aucun modèle de programmation spécifique
Struts
Hiberner
Grails
Jouez !
Vaadin
Maven
Questions d'entretien sur la programmation mixte
Java définit une classe String pour représenter des tableaux de caractères. Répondez aux questions suivantes :
- Par quoi faut-il remplacer le "XXX" pour pouvoir comparer les deux principaux arcs de cordes ? Si les arguments sont : "Sun Microsystems" et "Sun microsystems", quel sera le résultat de l'exécution ? Y a-t-il un moyen de garantir qu'il les déclarera comme étant identiques ? - Si les arguments sont plutôt : "Sun Microsystems" et "Sun Microsystems", quel sera le résultat de l'exécution ? "Sun Microsystem" et "Sun Microsystems", quel sera le résultat de l'exécution ?
1/ Après la création d'une chaîne, est-il possible de la modifier ? Considérez ce qui suit :
public static void main(String[] args) { String name = "James gosling"; // I want to change the 'g' to a 'G'. // Will this work at compile time? name.charAt(6) = 'G'; // Print with the standard system println to see “James Gosling” System.out.println(name); }
Cela va-t-il fonctionner ? Si ce n'est pas le cas, quelles modifications faudrait-il apporter pour obtenir la chaîne souhaitée ?
2/ La classe String a plus d'un Comparateur. Considérez le code suivant :
public static void main(String[] args) { // This program received 2 arguments. We want to // determine if those two strings are equal. // Compare the first argument to the second argument boolean compareResult = (XXX); if (compareResult) { System.out.println("The Strings are the same."); } else { System.out.println("The Strings are not the same."); } // Print the main string args System.out.println(args[0]); System.out.println(args[1]); }
- Par quoi faut-il remplacer le "XXX" pour pouvoir comparer les deux principaux arcs de cordes ? Si les arguments sont : "Sun Microsystems" et "Sun microsystems", quel sera le résultat de l'exécution ? Y a-t-il un moyen de garantir qu'il les déclarera comme étant identiques ? - Si les arguments sont plutôt : "Sun Microsystems" et "Sun Microsystems", quel sera le résultat de l'exécution ? "Sun Microsystem" et "Sun Microsystems", quel sera le résultat de l'exécution ?
3/ Qu'est-ce que le pool de constantes de la chaîne Java ? (ou pool de chaînes de caractères Java) ? Il réside dans la mémoire de la pile ?
Justification
L'utilisation de représentations de chaînes de caractères est courante dans de nombreux langages, et Java ne fait pas exception. Il est important de comprendre comment les chaînes de caractères sont créées, analysées, imprimées et manipulées. C'est un sujet important qui constitue une question d'entretien importante pour les développeurs Java.
Bonne réponse
Non, cela échouera au moment de la compilation car il n'est pas possible de modifier une chaîne une fois qu'elle a été initialisée. Cette propriété est dite immuable. Pour que cela fonctionne, il faudrait recréer la chaîne contenant "James gosling". Une approche consiste à utiliser un tableau de caractères intermédiaires (en appelant la méthode toCharArray() sur le "nom"), à remplacer le "g" par la lettre majuscule, puis à recréer la chaîne avant de l'imprimer. Un bonus pour le candidat qui souligne que la fonction string replace(...) existe pour remplacer les caractères, mais ne peut pas être utilisée car toutes les instances de "g" minuscules seraient remplacées.
Le comparateur exact dans cet exemple est soit égal(...) soit égalIgnoreCase(...). Le type de retour de ces deux méthodes est une valeur booléenne. Si la personne interrogée répond compareTo(...) ou compareToIgnoreCase(...), alors le crédit devrait être accordé, bien que le type de retour de ces méthodes soit un int, donc techniquement incorrect. Il n'en reste pas moins qu'elle démontre une connaissance de la langue.
Dans le premier exemple, les chaînes sont identiques sous equalsIgnoreCase(...), mais différentes sous equals(...). Dans le deuxième exemple, il y a un "s" à la fin, ce qui fait que les chaînes sont différentes dans tous les cas.
Le Java Constant String Pool est une zone de la mémoire du Heap (donc, pas de la mémoire de la pile) où sont stockées les chaînes de caractères. Cette approche est à l'origine de la raison pour laquelle les chaînes sont immuables en java.
Par exemple :
chaîne x = "chaîne principale" ;
chaîne de caractères y = "machine virtuelle" ;
chaîne z = "chaîne principale" ;
Les trois cordes ci-dessus sont stockées dans le pool de cordes, mais la partie intéressante est l'efficacité. x et y pointent tous deux vers la même zone dans la réserve de cordes, ce qui ne nécessite pas de duplication de l'espace. Sachant cela, il doit être clair que la modification de la valeur de x n'est pas autorisée car elle aurait l'effet secondaire non voulu de modifier z.
Quelles sont les différences entre la mémoire Stack et l'espace Heap ?
Justification
Afin d'améliorer l'efficacité, la JVM organise la mémoire pour que les applications puissent s'exécuter. Elle crée de l'espace de pile et de l'espace de tas, chacun étant utilisé par des opérations différentes. Comprendre l'allocation de la mémoire à ce niveau peut conduire à un ramassage des déchets plus prévisible et, en fin de compte, à une efficacité accrue.
Bonne réponse
La mémoire en pile est utilisée pour l'allocation de mémoire statique, comme les valeurs primitives à l'intérieur d'une méthode. Elle est toujours utilisée pour l'exécution d'un thread. La pile s'agrandit lorsque les méthodes sont appelées, et se réduit lorsqu'elles reviennent. Si la mémoire allouée pour la pile est dépassée, l'exception java.lang.StackOverFlowError est lancée.
La mémoire de tas est utilisée pour l'allocation de mémoire dynamique, comme les objets java. Plus précisément, l'objet est stocké dans le tas, tandis que la référence à l'objet est stockée dans la pile. Les classes JRE sont également stockées dans le tas au moment de l'exécution. L'accès aux données dans le tas est plus lent que dans la mémoire de la pile. Le tas requiert l'action du collecteur de déchets afin de libérer les objets inutilisés. Si la mémoire allouée au tas est dépassée, l'exception java.lang.OutOfMemoryError est lancée.
Mauvaise réponse
Le fait de n'avoir jamais entendu parler de la pile ou du tas indiquerait une connaissance superficielle du langage de programmation java. De plus, la terminologie est typique d'une culture générale de programmation. Le diagnostic des erreurs liées à la mémoire, telles qu'un débordement de pile causé par un comportement incorrect d'une fonction récursive, serait plus facile avec cette compréhension.
Deux termes liés à la classe utilisés dans la programmation java sont "subclass" et "nested class". Expliquez les différences entre ces deux termes. Pourquoi choisir l'une plutôt que l'autre ? Laquelle est parfois appelée "classe intérieure" ?
Justification
Dans la conception orientée objet, il y a souvent une confusion sur le placement des classes dans la hiérarchie. Les classes imbriquées sont relativement rares par rapport aux sous-classes, mais leur utilisation est bénéfique dans de nombreuses situations. La connaissance de leur existence et de leur mode d'utilisation doit être considérée comme un atout.
Bonne réponse
Une sous-classe est une extension d'une autre classe, et est souvent une spécialisation de l'original. Les sous-classes héritent des membres publics et protégés de leur super-classe. Les sous-classes peuvent être instanciées indépendamment de la superclasse, et en fait, c'est toujours le cas lorsque la superclasse est une classe abstraite.
Une classe imbriquée est une classe à l'intérieur d'une classe, qui dans certains cas est une classe intérieure. Le champ d'application de la classe intérieure comprend tous les membres de sa classe extérieure, ce qui lui donne accès à ces variables et méthodes. Comme le corps existe entièrement au sein de la classe englobante, il ne peut pas être instancié indépendamment, sans elle.
L'utilisation d'une classe interne peut améliorer la conception orientée objet en organisant davantage le code. L'objectif est limité dans la mesure où il existe pour servir sa classe englobante. Si la classe interne offre des fonctionnalités utiles à une plus grande échelle, il serait plus logique de l'avoir comme classe de haut niveau. Les classes internes sont couramment utilisées comme fonctions de rappel pour les composants de l'interface graphique.
Bonus
Il existe deux types de classes imbriquées. Plus précisément, il existe une classe imbriquée statique, qui n'a pas directement accès aux autres membres de la classe englobante. Celles-ci ne sont pas souvent utilisées, c'est pourquoi le fait de les connaître est un bonus par opposition à l'ignorance qui peut entraîner une pénalité. L'autre type est une classe imbriquée non statique, qui est la version que l'on appelle une classe intérieure. Ceux-ci ont en effet accès à tous les membres de la classe englobante, y compris aux méthodes privées.
Mauvaise réponse
Le candidat doit être pardonné de n'avoir jamais utilisé une classe imbriquée. Bien qu'utile, et susceptible d'être vu si l'on maintient une base de code existante, le concept est simple. Les classes imbriquées rendent souvent le code plus élégant et plus facile à maintenir, mais certains concepteurs considèrent que c'est une question de style. Les sous-classes, d'autre part, sont un élément fondamental de la programmation orientée objet que tout développeur java devrait connaître. Ne pas pouvoir discuter facilement des sous-classes au sein d'une hiérarchie de classes est un sérieux signal d'alarme.
Deux classes de collection sont disponibles en programmation java : Array et List. En quoi les méthodes diffèrent-elles entre ces deux objets conteneurs, et dans quelles circonstances choisiriez-vous l'une plutôt que l'autre ?
Justification
L'utilisation de conteneurs est courante en Java et dans d'autres langages de programmation. La liste est une structure de données dynamique, tandis que le tableau est statique. Il est important de reconnaître que chacun d'entre eux est mieux adapté à certaines applications, et à ce titre, le candidat doit les connaître. Avoir une connaissance approfondie des types de données et des classes de conteneurs disponibles permettra en fin de compte de gagner du temps de développement.
Bonne réponse
Array
Les tableaux sont de taille statique, ils ne peuvent donc ni croître ni diminuer en termes de nombre d'éléments. Cela signifie qu'il existe des méthodes pour accéder aux éléments et les modifier, mais pas pour les insérer ou les supprimer.
Java fournit des méthodes pour effectuer une recherche binaire ou un tri sur un tableau. De plus, un tableau peut être initialisé en utilisant la méthode fill(), ou comparé en utilisant le comparateur equals().
La taille d'un tableau est fixée lors de sa création.
L'accès aléatoire d'un élément dans un tableau est très efficace.
Les tableaux sont plus adaptés à des collections d'éléments de longueur fixe.
Tous les éléments sont du même type, par exemple :
int[] interviewArray = new int[5];
or
int[] arrayForInterview = {3, 1, 4, 1, 5};
Ces deux tableaux contiennent cinq entiers.
Vecteur
Les candidats doivent savoir quand il est approprié et possible d'utiliser ces mots clés. En particulier, ils doivent savoir que l'asynchronisation ne peut être placée avant le mot-clé de fonction sur une définition de fonction. La fonction est alors considérée comme un retour de promesse. Le mot-clé "await" ne peut être utilisé qu'à l'intérieur d'une telle fonction asynchrone et doit être placé avant un appel à une fonction qui rendra une Promesse.
Les éléments d'une liste peuvent être ajoutés ou supprimés, ce qui signifie que la taille de la liste peut changer. Les méthodes permettent de nombreux types de manipulations, y compris l'insertion ou la suppression dans un index spécifique. Les plages peuvent également être manipulées.
La Liste est une interface, donc quand on manipule une Liste, une vraie classe, généralement ArrayList, est utilisée en coulisse
Une liste repose sur les méthodes de tri de Collections, telles que Collections.sort().
Les méthodes de recherche contain(), indexOf(), et lastIndexOf() sont des exemples qui peuvent être utilisés pour rechercher les éléments. Cependant, pour effectuer une recherche binaire, il faut appeler la méthode plus générale : Collections.binarySearch(...)
Les listes peuvent contenir des objets de type mixte, par exemple :
List interviewList = new ArrayList();
interviewList.add(3);
interviewList.add(1415);
interviewList.add(“Pi”);
Bonus
Les tableaux peuvent stocker des objets, il existe donc une solution de rechange pour ceux qui sont enclins à mélanger les types dans un tableau. De plus, le candidat doit être crédité de savoir que les Listes remplacent les Vecteurs qui ne sont plus couramment utilisés en Java. La raison est liée à la simultanéité et à la synchronisation des opérations. Il est clair qu'une explication plus détaillée dépasse la portée de cette question - cependant, la mention de ce point est digne d'intérêt.
Mauvaise réponse
Les tableaux et les listes, parmi d'autres classes et interfaces intégrées, y compris les collections, sont très courants dans la programmation Java et le développement d'applications. Un candidat qui n'est pas à l'aise avec ces fonctionnalités manque presque certainement d'expérience avec le langage.
Contrairement au C++, Java ne prend pas en charge l'héritage multiple. Comment la programmation avec une interface apportera-t-elle une réponse à ce problème ? Une interface fait-elle partie de la hiérarchie des classes ?
Justification
S'il existe des points communs entre les langues que de nombreux programmeurs connaissent bien, il existe aussi des distinctions qui permettent de les définir. Dans un entretien en Java, il y aura des questions de base en Java qui aideront à évaluer dans quelle mesure le candidat connaît les spécificités du langage de programmation Java. Étant donné la question du problème du diamant en C++, il est intéressant de tester les connaissances du candidat dans une perspective java.
Bonne réponse
Une interface est similaire à une classe en ce sens qu'elle peut contenir différents types de méthodes, mais différente parce qu'elle ne détient pas l'état. Les interfaces sont intrinsèquement abstraites, et leurs méthodes doivent être implémentées par une classe. L'interface n'est pas instanciée, elle est implémentée. Contrairement au C++, une classe ne peut étendre qu'un seul parent (c'est-à-dire qu'elle ne peut avoir qu'une seule superclasse). Une interface, en revanche, est capable d'étendre plus d'une interface parent. Par exemple :
public interface CheckerBoard {
public void setSize(int rowCount, int columnCount);
}
public interface Game {
public void setNumberOfPlayers();
public void play();
}
public interface ChessGame extends CheckerBoard, Game {}
Dans cet exemple, l'interface ChessGame hérite à la fois de CheckerBoard et de Game.
Mauvaise réponse
Si la personne interrogée ne sait pas ce qu'est l'héritage multiple, cela suggère un manque d'expérience en matière de conception orientée objet. Cela n'est pas essentiel pour toutes les applications, bien qu'il soit important de reconnaître que java est intrinsèquement OO.
Qu'est-ce que la machine virtuelle Java ? Quel en est l'objectif principal et avec quel type de code fonctionne-t-elle ?
Justification
Aucune interview en Java ne serait complète sans une question sur le thème de la machine virtuelle. La JVM est un élément clé de Java, et les programmeurs java l'apprennent très tôt. Si la JVM est capable d'exécuter du bytecode généré par d'autres langages, tels que JRuby et Jython, cela n'enlève rien au fait qu'elle est essentielle à la java elle-même.
Bonne réponse
La JVM est une machine virtuelle qui permet à l'ordinateur d'exécuter des programmes Java qui ont été compilés en bytecode. Le bytecode est indépendant de la plateforme, et s'exécute sur tout ordinateur qui héberge une JVM. Il comprend un compilateur juste à temps (JIT) qui convertit le bytecode en instructions en langage machine, permettant aux applications de s'exécuter aussi rapidement qu'un exécutable natif.
Mauvaise réponse
La JVM est l'un des principaux composants qui font de Java ce qu'il est. Le fait de ne pas connaître la JVM indique probablement un manque d'expérience avec le langage.
Quelles sont les méthodes et les classes finales ? Une classe abstraite supportera-t-elle les méthodes finales ?
Justification
Le dernier mot-clé est commun et doit être bien compris par les programmeurs java. Au cours de la phase de conception OO, il est normalement décidé si les classes doivent être extensibles. Si ce n'est pas le cas, elles sont marquées comme finales afin de limiter les effets secondaires potentiels de sous-classes qui n'ont pas été envisagées. Il s'agit d'une caractéristique importante qui devrait être utilisée pour un code plus robuste et plus facile à maintenir.
Bonne réponse
Une méthode qui est déclarée avec le mot-clé final ne peut pas être annulée dans les sous-classes. Cette méthode est utilisée dans les hiérarchies où la mise en œuvre de la méthode doit être cohérente dans l'ensemble. La déclaration finale d'une classe interdit totalement le sous-classement. Oui, il est possible d'inclure des méthodes finales dans une classe abstraite. Cela permet de s'assurer que les sous-classes ne peuvent pas passer outre la méthode.
Mauvaise réponse
Si le candidat n'est pas familier avec le mot-clé final, qu'il soit utilisé au niveau de la classe ou de la méthode, alors cela suggère une relative inexpérience de la langue. Même pour les programmeurs inexpérimentés qui ont participé à la conception orientée objet, le concept de classe finale devrait être familier.
La programmation Java permet de créer un fil de discussion de différentes manières. Quelles sont-elles et quelle est la méthode préférée ? Expliquez.
Justification
Contrairement au C++, java contient un support intégré pour le multithreading. C'est une fonctionnalité riche et puissante qui est à la fois pertinente et utile dans de nombreuses applications. En tant que tel, le candidat doit être familier avec les bases.
Bonne réponse
Que se passe-t-il dans le cas où la réduction est appelée sur un tableau vide sans fournir la valeur initiale facultative de l'accumulateur ?
public class JavaInterviewClass implements Runnable {
public void run() {
System.out.println(“My example public class prints this line from a thread.”);
}
}
Pour exécuter la méthode run(), passez une instance de la classe dans un Thread, comme suit :
Thread interviewThread = new Thread(new JavaInterviewClass ());
interviewThread.start();
La deuxième façon de créer un fil de discussion est d'étendre la classe de fil de discussion. La sous-classe remplacera la méthode run(). Après cela, il suffit de créer une instance de la classe.
public class JavaInterviewClass extends Thread {
public void run() {
System.out.println(“My example public class extends the Thread class.”);
}
}
Pour exécuter le fil de discussion, il suffit d'instancier la classe et d'appeler start(), comme suit :
JavaInterviewClass myInterview = new JavaInterviewClass (); myInterview.start();
Bonus
Bien que l'implémentation de l'interface exécutable et l'extension de la classe Thread soient deux moyens populaires de créer un thread, il est également possible d'utiliser le framework Executor. Celui-ci permet de travailler directement avec les threads, mais il est moins connu. Il comprend des méthodes telles que newSingleThreadExecutor(), newFixedThreadPool() et submit() pour créer des tâches d'exécution. La connaissance de l'utilisation du framework Executor implique que le candidat soit très à l'aise avec la création et l'utilisation de threads en java.
Mauvaise réponse
Si le candidat n'est pas à l'aise avec l'utilisation des fils de discussion, il passe à côté d'une caractéristique puissante et importante de la langue. C'est important car comprendre le multithreading ne se limite pas à rechercher la syntaxe de quelques commandes. Il s'agit plutôt d'une approche qui doit être envisagée lors de la conception et du développement d'une application.
Le code Java a un support intégré pour la concurrence dans sa classe Thread. La simultanéité a son propre ensemble de problèmes tels que l'impasse et les conditions de course. Décrivez brièvement les variables Atomic en Java et leur utilisation. Ensuite, il est indiqué que la méthode start() est utilisée pour créer une pile d'appels séparée avant que la méthode run() ne soit utilisée pour exécuter un thread. Que font les méthodes yield(), sleep() et join() ?
Justification
La prise en charge du multithreading par Java peut entraîner des problèmes liés à la concurrence. Les connaissances du candidat concernant ces problèmes doivent être évaluées et prises en compte.
Bonne réponse
Une variable atomique est une variable "mise à jour atomique", ce qui signifie que l'intégrité des données est assurée par l'utilisation d'algorithmes non bloquants. Cette fonctionnalité est généralement mise en œuvre au niveau du code machine. Java prend en charge plusieurs variables atomiques, le plus souvent AtomicBoolean, AtomicInteger, AtomicLong et AtomicReference. Il existe également plusieurs méthodes qui permettent de récupérer et de modifier ces variables, notamment get(), set(), lazySet(), compareAndSet() et weakCompareAndSet(). Utilisées correctement, les variables atomiques peuvent être utilisées pour mettre en œuvre des méthodes "thread safe" (multithreading safe) qui traitent efficacement certains problèmes liés à la concurrence.
rendement() : Cette méthode informe l'environnement que le fil de discussion actuel n'est pas en train d'achever une tâche de haute priorité, et est prêt à en interrompre l'exécution. À condition que l'environnement sous-jacent supporte l'ordonnancement préventif, elle suspendra le fil s'il y en a un autre qui doit s'exécuter. S'il n'y a pas de deuxième fil, ou si le deuxième fil se termine, le fil en cours reprendra le contrôle et continuera à s'exécuter.
sommeil() : Cette méthode fait dormir le fil courant, ou met en pause son exécution, pendant un nombre de millisecondes déterminé. Il est également possible de combiner un certain nombre de millisecondes et de nanosecondes. Pendant que le fil courant est en sommeil, un autre fil sera exécuté, ou sinon le CPU restera inactif. Sous réserve de la précision de l'horloge du système et des minuteurs, le fil de discussion reprendra le contrôle une fois le compte à rebours terminé.
join() : Cette méthode est utilisée pour joindre deux l'exécution de deux fils ensemble. Pour clarifier, si le fil A appelle join() sur le fil B, alors A commencera à attendre. Une fois que B a terminé, ou qu'un délai prédéfini a expiré, A reprendra le contrôle et continuera l'exécution.
Mauvaise réponse
Le fait de connaître les fils de discussion Java, mais de ne pas être conscient des problèmes liés à la concurrence peut entraîner de graves erreurs. La majorité des appareils, des ordinateurs de bureau aux appareils mobiles en passant par les ordinateurs à carte unique, prennent désormais généralement en charge le multithreading et la concurrence. Il est important de comprendre la bonne utilisation des threads, et d'être conscient des méthodes fournies par java pour les prendre en charge.
Conclusion
Les questions de cet article sont utiles pour évaluer les compétences d'un futur programmeur Java. En ce qui concerne les questions d'entretien à préparer pour un développeur Java, il est important de se rappeler que les spécificités du langage peuvent être facilement référencées en utilisant l'aide et la documentation en ligne. Les points subtils d'un langage ne sont pas aussi importants que la façon dont on applique la logique. Cela dit, les candidats à ce poste sont censés connaître le langage et ne pas avoir besoin d'une formation approfondie avant que le travail réel ne commence. Les compétences requises seront dictées par le travail à effectuer, et la variation des questions données ci-dessus aidera à faire cette évaluation. N'oubliez pas que l'une des meilleures façons d'évaluer les compétences du candidat pour votre projet est d'effectuer une évaluation pratique de la programmation, ce qui est bien plus efficace que des questions d'entretien orales pour engager un programmeur Java hautement qualifié.
1 - Le code Java prévoit des méthodes de classe avec des spécificateurs d'accès public et privé. Quelle est la différence entre ces deux modificateurs ?
Justification
Dans la programmation orientée objet, il est courant de limiter la portée des variables et des fonctions à des classes spécifiques dans une hiérarchie de classes. Ceci est réalisé à l’aide de différents spécificateurs d’accès, et connaître la différence entre ces composants fondamentaux est une question d’entretien Java très pertinente.
En Java, les classes peuvent être uniquement déclarées publiques, ou bien pas du tout – alors que les fonctions membres ont quatre modificateurs différents – c’est donc un sujet qui peut s’avérer épineux pour les grands débutants.
Bonne réponse
Un spécificateur d’accès public ordonne que la méthode soit accessible à la fois à l’intérieur et à l’extérieur de la classe. Ceci est vrai tant que la classe elle-même est déclarée publique, ou que la classe appelante est dans le même package. Si la classe ne spécifie pas de modificateur, elle est supposée avoir un accès par défaut (package), et les déclarations de ses méthodes ne l’écrasent pas.
Un spécificateur d’accès privé indique que la méthode doit être accessible uniquement à l’intérieur de la classe.
Bonus
Si le candidat sait qu'il existe également des spécifications pour les produits protégés et les emballages (par défaut), il démontre alors une bonne compréhension de ce sujet.
Mauvaise réponse
Si le candidat ne connaît pas la différence entre public et private, cela indique un manque d’expérience à propos de Java et probablement dans d’autres langages orientés objet tels que C++. Si la réponse est correcte, mais qu’il n’est pas fait mention du fait que le modificateur de classe l’emporte sur les méthodes, le candidat devrait être pénalisé.
Considérons le code suivant qui contient une classe, une variable statique et une méthode publique. Combien de bouchées ont été prises pour chaque pomme ?
public class Apple {
static int bites = 0;
public void takeBite() {
bites++;
}
public static void main(String[] args) {
// Instantiate red and green apples for our example public class
Apple macintosh = new Apple();
Apple grannySmith = new Apple();
// Take a bite out of each of the two apples
macintosh.takeBite();
grannySmith.takeBite();
// Display the contents of each class
System.out.println("The Macintosh apple has " + macintosh.bites + " bite(s) out of it.");
System.out.println("The Granny Smith apple has " + grannySmith.bites + " bite(s) out of it.");
}
}
Justification
Les variables statiques sont une caractéristique de Java régulièrement utilisée par les développeurs. Comme c’est le cas pour les variables globales, il est important pour les programmeurs de comprendre la portée de ces objets afin d’éviter un quelconque effet collatéral. Note à propos de la non-déclaration d’une variable : cela permet d’éviter de mal taper le nom d’une variable, car la variable mal orthographiée apparaîtra comme une nouvelle variable non déclarée.
Bonne réponse
La classe Apple partage la variable statique, bites, entre toutes ses instances. Par conséquent, lorsque la méthode takeBite() est appelée sur chacune des instances, la variable commune est mise à jour. Le résultat final se présente ainsi :
The Macintosh apple has 2 bite(s) out of it.
The Granny Smith apple has 2 bite(s) out of it.
Mauvaise réponse
Si le candidat répond que chacune des deux instances s’est vue retirée une seule bouchée (bite), cela indique un manque d’expérience avec les variables statiques. Ce sujet est trivial, mais un développeur Java le rencontrera fréquemment. Le fait de ne pas en avoir connaissance indique que le candidat manque probablement d’expérience pratique du langage.
Qu'est-ce qu'une exception ? Décrivez brièvement les deux types d'exception utilisés dans le code java.
Justification
Les exceptions sont des événements inattendus qui surviennent au moment de l’exécution et qui diffèrent des erreurs dans la mesure où il est généralement aisé de les « rattraper ». Les erreurs, par contre, indiquent généralement un problème plus grave. La gestion des exceptions est très courante et doit être comprise, au moins à un niveau de base, par n’importe quel programmeur Java.
Bonne réponse
Les deux types d’exceptions dans Java sont les exceptions vérifiées et les exceptions non-vérifiées.
Une exception vérifiée est une exception qui est vérifiée au moment de la compilation. Lorsqu’il y a du code dans une méthode qui lève une exception vérifiée, la méthode est nécessaire pour l’acquitter. Ceci peut être accompli soit en gérant l’exception avec un bloc try/catch, soit en la spécifiant à l’aide du mot-clé throws. Une exception non-vérifiée est une exception qui n’est pas vérifiée au moment de la compilation. C’est au programmeur de spécifier ce type d’exception. En revanche, il faut noter que toutes les exceptions en C++ sont non-vérifiées.
Bonus
En Java, toutes les exceptions des classes Error et RuntimeException sont décochées. Tout le reste sous Throwable est vérifié. Si la personne interrogée soulève ce point particulier, elle démontre une compréhension profonde de la question qui lui a été posée.
Mauvaise réponse
Si le candidat n’est pas au courant des exceptions, il lui manque une partie essentielle du langage qui est responsable du contrôle de l’exécution. Cette fonctionnalité représente un véritable bond en avant par rapport à des langages tels que C (qui ne supporte pas la gestion des exceptions). Bien qu’elles ne soient pas absolument indispensables, les exceptions sont extrêmement utiles au quotidien du fait de leurs nombreux avantages, tout développeur Java efficace les utilise.
Que sont les cours d'emballage ? Donnez des exemples de deux d'entre elles et des primitives correspondantes. Quel est le rapport entre chacune d'elles et un objet ?
Justification
Les classes d’emballage sont fondamentales en programmation Java. En fait, leur existence implique que java n’est pas 100% orienté objet (bonus au candidat qui le signale !). C’est le cas parce que Java contient 8 types de données primitives qui ne sont pas, par définition, des objets.
Bonne réponse
Une classe d’emballage est une classe qui contient une variable qui est un type de données primitives, et qui enveloppe la primitive pour fournir une fonctionnalité d’interaction avec elle. En fait, on peut dire qu’il transforme le primitif en objet. Ce qui est utile, par exemple, lorsqu’une méthode vise au transfert d’un objet. Le candidat doit être capable de nommer au moins deux des paires suivantes :
Primitive
Classe d'emballage
boolean
Boolean
byte
Byte
char
Char
double
Double
float
Float
int
Int
long
Long
short
Short
Mauvaise réponse
Les classes d’emballage sont définies en java.lang, et requises car il existe de nombreuses classes qui supportent uniquement les objets. Le fait de ne pas connaître ces classes d’emballage, ou de ne pas savoir pourquoi elles seraient utilisées, apparaît comme une grave lacune de la part du candidat interrogé.
Définissez les termes suivants qui sont courants dans la programmation java
Classe abstraite
Ramasse-miettes (aussi appelé récupérateur de mémoire, glaneur de cellules ou garbage collector)
Autoboxing
Sérialisation
Justification
Cette liste inclut des termes qui sont communément utilisés en Java, ainsi que dans d’autres langages de programmation. Les questions d’entretien pour les programmeurs expérimentés incluent de telles définitions parce qu’elles permettent de tester leurs connaissances de manière approfondie, ainsi que leur capacité à distinguer des langages comportant des concepts proches sans être parfaitement identiques.
Bonne réponse
Une classe abstraite est utilisée comme classe de base pour les sous-classes qui vont étendre ou écraser ses méthodes. Prenons l’exemple d’une classe « Forme ». Une forme peut contenir un certain nombre de côtés, de faces ou même de dimensions. Prise isolément, savoir que cette classe est une « Forme » est peu utile. D’autre part, si cette classe abstraite sera utilisée comme classe de base pour un « Carré », un « Triangle », ou un autre type de polygone, elle deviendra utile quand placée au sommet de la hiérarchie des classes. - Il n'est pas possible d'instancier une classe abstraite. – Elle peut contenir des méthodes abstraites, mais ce n’est pas obligatoire. - Les sous-classes de la classe d'abstraction doivent mettre en œuvre toutes les méthodes d'abstraction, à moins qu'il ne s'agisse également d'une classe d'abstraction. Il n'est pas possible d'instancier une classe abstraite.
Ne pas être parfaitement calé à propos classes abstraites n’est pas éliminatoire, bien que ces dernières seront très probablement rencontrées par le programmeur Java lorsqu’il devra effectuer des actions de maintenance ou du débogage d’une base de code existante.
La "garbage collection" (effectuée par le "garbage collector" ou ramasse-miettes) est le processus de détection et de suppression des objets en mémoire qui ne sont plus utilisés ou référencés. En java, le ramassage des miettes est automatique, mais il peut aussi être demandé.
Les commandes System.gc() et Runtime.gc() indiqueront au ramasse-miettes qu’il doit s’exécuter, bien que cela ne soit pas garanti.
Les fils d’exécution sont mis en pause pendant le ramassage des ordures. Cela ralentit nécessairement l’exécution, ce qui signifie que dans les applications réactives, le ramassage des miettes doit être réduit au minimum. La connaissance du ramasseur de miettes n’est pas indispensable, surtout pour un programmeur débutant. Il est à noter, cependant, que lorsqu’on vient d’un langage comme C, où toute la mémoire est gérée manuellement, le développeur doit être au courant de l’existence de cette fonctionnalité.
L’Autoboxing est l’emballage automatique d’un type primitif (voir la question #4 relative aux types primitifs et classes d’emballages). Par exemple, l’autoboxing convertira automatiquement un nombre de type float (type primitif) en Float (classe d’emballage). Le contraire de cela est le déballage, lors duquel type primitif est extrait de la classe d’emballage. Cette notion est habituellement familière aux bons développeurs Java.
La sérialisation fait référence à l’encodage d’objets en mémoire dans un flux d’octets qui pouvant être facilement stockés ou transmis. Le contraire est la désérialisation, qui reconstruit les objets à partir d’un flux d’octets. Il existe différentes approches pour réaliser la sérialisation. Deux méthodes courantes sont la conversion de l’objet en XML (eXtensible Markup Language), ou JSON (JavaScript Object Notation). Ce sont des types de fichiers bien connus, chacun d’entre eux étant largement pris en charge. Java supporte également la sérialisation comme partie intégrante du langage. Le langage inclut l’interface sérialisable, qui peut être utilisée à la fois pour la sérialisation et la désérialisation. La méthode writeObject() est utilisée pour encoder les données, tandis que la méthode readObject() est utilisée pour reconstruire les objets.
Java définit une classe String pour représenter des tableaux de caractères. Répondez aux questions suivantes :
Un constructeur initialise un objet lors de sa création. Cependant, les constructeurs n'ont pas de type de retour explicite.
En général, vous utiliserez un constructeur pour donner des valeurs initiales aux variables d'instance définies par la classe, ou pour effectuer toute autre procédure de démarrage nécessaire pour créer un objet entièrement formé.
Toutes les classes ont des constructeurs, que vous en définissiez un ou non, car Java fournit automatiquement un constructeur par défaut qui initialise toutes les variables membres à zéro. Cependant, une fois que vous avez défini votre propre constructeur, le constructeur par défaut n'est plus utilisé.
Pourriez-vous citer quelques cadres de travail Java ?
Cette question d'entretien est une question de base : tout développeur Java compétent est en mesure de nommer quelques frameworks écrits en langage Java. Au cours de l'entretien, le candidat interrogé doit mentionner au moins trois frameworks Java parmi cette liste :
JSF (Java Server Faces), un cadre web Java qui facilite la construction d'interfaces utilisateur pour les applications basées sur des serveurs
GWT (Google Web Toolkit), un ensemble d'outils open-source qui aide les programmeurs à créer et à maintenir des applications JavaScript dans Java Spring, un framework Java qui n'impose aucun modèle de programmation spécifique
Struts
Hiberner
Grails
Jouez !
Vaadin
Maven
Questions d'entretien sur la programmation mixte
Java définit une classe String pour représenter des tableaux de caractères. Répondez aux questions suivantes :
- Par quoi faut-il remplacer le "XXX" pour pouvoir comparer les deux principaux arcs de cordes ? Si les arguments sont : "Sun Microsystems" et "Sun microsystems", quel sera le résultat de l'exécution ? Y a-t-il un moyen de garantir qu'il les déclarera comme étant identiques ? - Si les arguments sont plutôt : "Sun Microsystems" et "Sun Microsystems", quel sera le résultat de l'exécution ? "Sun Microsystem" et "Sun Microsystems", quel sera le résultat de l'exécution ?
1/ Après la création d'une chaîne, est-il possible de la modifier ? Considérez ce qui suit :
public static void main(String[] args) { String name = "James gosling"; // I want to change the 'g' to a 'G'. // Will this work at compile time? name.charAt(6) = 'G'; // Print with the standard system println to see “James Gosling” System.out.println(name); }
Cela va-t-il fonctionner ? Si ce n'est pas le cas, quelles modifications faudrait-il apporter pour obtenir la chaîne souhaitée ?
2/ La classe String a plus d'un Comparateur. Considérez le code suivant :
public static void main(String[] args) { // This program received 2 arguments. We want to // determine if those two strings are equal. // Compare the first argument to the second argument boolean compareResult = (XXX); if (compareResult) { System.out.println("The Strings are the same."); } else { System.out.println("The Strings are not the same."); } // Print the main string args System.out.println(args[0]); System.out.println(args[1]); }
- Par quoi faut-il remplacer le "XXX" pour pouvoir comparer les deux principaux arcs de cordes ? Si les arguments sont : "Sun Microsystems" et "Sun microsystems", quel sera le résultat de l'exécution ? Y a-t-il un moyen de garantir qu'il les déclarera comme étant identiques ? - Si les arguments sont plutôt : "Sun Microsystems" et "Sun Microsystems", quel sera le résultat de l'exécution ? "Sun Microsystem" et "Sun Microsystems", quel sera le résultat de l'exécution ?
3/ Qu'est-ce que le pool de constantes de la chaîne Java ? (ou pool de chaînes de caractères Java) ? Il réside dans la mémoire de la pile ?
Justification
L'utilisation de représentations de chaînes de caractères est courante dans de nombreux langages, et Java ne fait pas exception. Il est important de comprendre comment les chaînes de caractères sont créées, analysées, imprimées et manipulées. C'est un sujet important qui constitue une question d'entretien importante pour les développeurs Java.
Bonne réponse
Non, cela échouera au moment de la compilation car il n'est pas possible de modifier une chaîne une fois qu'elle a été initialisée. Cette propriété est dite immuable. Pour que cela fonctionne, il faudrait recréer la chaîne contenant "James gosling". Une approche consiste à utiliser un tableau de caractères intermédiaires (en appelant la méthode toCharArray() sur le "nom"), à remplacer le "g" par la lettre majuscule, puis à recréer la chaîne avant de l'imprimer. Un bonus pour le candidat qui souligne que la fonction string replace(...) existe pour remplacer les caractères, mais ne peut pas être utilisée car toutes les instances de "g" minuscules seraient remplacées.
Le comparateur exact dans cet exemple est soit égal(...) soit égalIgnoreCase(...). Le type de retour de ces deux méthodes est une valeur booléenne. Si la personne interrogée répond compareTo(...) ou compareToIgnoreCase(...), alors le crédit devrait être accordé, bien que le type de retour de ces méthodes soit un int, donc techniquement incorrect. Il n'en reste pas moins qu'elle démontre une connaissance de la langue.
Dans le premier exemple, les chaînes sont identiques sous equalsIgnoreCase(...), mais différentes sous equals(...). Dans le deuxième exemple, il y a un "s" à la fin, ce qui fait que les chaînes sont différentes dans tous les cas.
Le Java Constant String Pool est une zone de la mémoire du Heap (donc, pas de la mémoire de la pile) où sont stockées les chaînes de caractères. Cette approche est à l'origine de la raison pour laquelle les chaînes sont immuables en java.
Par exemple :
chaîne x = "chaîne principale" ;
chaîne de caractères y = "machine virtuelle" ;
chaîne z = "chaîne principale" ;
Les trois cordes ci-dessus sont stockées dans le pool de cordes, mais la partie intéressante est l'efficacité. x et y pointent tous deux vers la même zone dans la réserve de cordes, ce qui ne nécessite pas de duplication de l'espace. Sachant cela, il doit être clair que la modification de la valeur de x n'est pas autorisée car elle aurait l'effet secondaire non voulu de modifier z.
Quelles sont les différences entre la mémoire Stack et l'espace Heap ?
Justification
Afin d'améliorer l'efficacité, la JVM organise la mémoire pour que les applications puissent s'exécuter. Elle crée de l'espace de pile et de l'espace de tas, chacun étant utilisé par des opérations différentes. Comprendre l'allocation de la mémoire à ce niveau peut conduire à un ramassage des déchets plus prévisible et, en fin de compte, à une efficacité accrue.
Bonne réponse
La mémoire en pile est utilisée pour l'allocation de mémoire statique, comme les valeurs primitives à l'intérieur d'une méthode. Elle est toujours utilisée pour l'exécution d'un thread. La pile s'agrandit lorsque les méthodes sont appelées, et se réduit lorsqu'elles reviennent. Si la mémoire allouée pour la pile est dépassée, l'exception java.lang.StackOverFlowError est lancée.
La mémoire de tas est utilisée pour l'allocation de mémoire dynamique, comme les objets java. Plus précisément, l'objet est stocké dans le tas, tandis que la référence à l'objet est stockée dans la pile. Les classes JRE sont également stockées dans le tas au moment de l'exécution. L'accès aux données dans le tas est plus lent que dans la mémoire de la pile. Le tas requiert l'action du collecteur de déchets afin de libérer les objets inutilisés. Si la mémoire allouée au tas est dépassée, l'exception java.lang.OutOfMemoryError est lancée.
Mauvaise réponse
Le fait de n'avoir jamais entendu parler de la pile ou du tas indiquerait une connaissance superficielle du langage de programmation java. De plus, la terminologie est typique d'une culture générale de programmation. Le diagnostic des erreurs liées à la mémoire, telles qu'un débordement de pile causé par un comportement incorrect d'une fonction récursive, serait plus facile avec cette compréhension.
Deux termes liés à la classe utilisés dans la programmation java sont "subclass" et "nested class". Expliquez les différences entre ces deux termes. Pourquoi choisir l'une plutôt que l'autre ? Laquelle est parfois appelée "classe intérieure" ?
Justification
Dans la conception orientée objet, il y a souvent une confusion sur le placement des classes dans la hiérarchie. Les classes imbriquées sont relativement rares par rapport aux sous-classes, mais leur utilisation est bénéfique dans de nombreuses situations. La connaissance de leur existence et de leur mode d'utilisation doit être considérée comme un atout.
Bonne réponse
Une sous-classe est une extension d'une autre classe, et est souvent une spécialisation de l'original. Les sous-classes héritent des membres publics et protégés de leur super-classe. Les sous-classes peuvent être instanciées indépendamment de la superclasse, et en fait, c'est toujours le cas lorsque la superclasse est une classe abstraite.
Une classe imbriquée est une classe à l'intérieur d'une classe, qui dans certains cas est une classe intérieure. Le champ d'application de la classe intérieure comprend tous les membres de sa classe extérieure, ce qui lui donne accès à ces variables et méthodes. Comme le corps existe entièrement au sein de la classe englobante, il ne peut pas être instancié indépendamment, sans elle.
L'utilisation d'une classe interne peut améliorer la conception orientée objet en organisant davantage le code. L'objectif est limité dans la mesure où il existe pour servir sa classe englobante. Si la classe interne offre des fonctionnalités utiles à une plus grande échelle, il serait plus logique de l'avoir comme classe de haut niveau. Les classes internes sont couramment utilisées comme fonctions de rappel pour les composants de l'interface graphique.
Bonus
Il existe deux types de classes imbriquées. Plus précisément, il existe une classe imbriquée statique, qui n'a pas directement accès aux autres membres de la classe englobante. Celles-ci ne sont pas souvent utilisées, c'est pourquoi le fait de les connaître est un bonus par opposition à l'ignorance qui peut entraîner une pénalité. L'autre type est une classe imbriquée non statique, qui est la version que l'on appelle une classe intérieure. Ceux-ci ont en effet accès à tous les membres de la classe englobante, y compris aux méthodes privées.
Mauvaise réponse
Le candidat doit être pardonné de n'avoir jamais utilisé une classe imbriquée. Bien qu'utile, et susceptible d'être vu si l'on maintient une base de code existante, le concept est simple. Les classes imbriquées rendent souvent le code plus élégant et plus facile à maintenir, mais certains concepteurs considèrent que c'est une question de style. Les sous-classes, d'autre part, sont un élément fondamental de la programmation orientée objet que tout développeur java devrait connaître. Ne pas pouvoir discuter facilement des sous-classes au sein d'une hiérarchie de classes est un sérieux signal d'alarme.
Deux classes de collection sont disponibles en programmation java : Array et List. En quoi les méthodes diffèrent-elles entre ces deux objets conteneurs, et dans quelles circonstances choisiriez-vous l'une plutôt que l'autre ?
Justification
L'utilisation de conteneurs est courante en Java et dans d'autres langages de programmation. La liste est une structure de données dynamique, tandis que le tableau est statique. Il est important de reconnaître que chacun d'entre eux est mieux adapté à certaines applications, et à ce titre, le candidat doit les connaître. Avoir une connaissance approfondie des types de données et des classes de conteneurs disponibles permettra en fin de compte de gagner du temps de développement.
Bonne réponse
Array
Les tableaux sont de taille statique, ils ne peuvent donc ni croître ni diminuer en termes de nombre d'éléments. Cela signifie qu'il existe des méthodes pour accéder aux éléments et les modifier, mais pas pour les insérer ou les supprimer.
Java fournit des méthodes pour effectuer une recherche binaire ou un tri sur un tableau. De plus, un tableau peut être initialisé en utilisant la méthode fill(), ou comparé en utilisant le comparateur equals().
La taille d'un tableau est fixée lors de sa création.
L'accès aléatoire d'un élément dans un tableau est très efficace.
Les tableaux sont plus adaptés à des collections d'éléments de longueur fixe.
Tous les éléments sont du même type, par exemple :
int[] interviewArray = new int[5];
or
int[] arrayForInterview = {3, 1, 4, 1, 5};
Ces deux tableaux contiennent cinq entiers.
Vecteur
Les candidats doivent savoir quand il est approprié et possible d'utiliser ces mots clés. En particulier, ils doivent savoir que l'asynchronisation ne peut être placée avant le mot-clé de fonction sur une définition de fonction. La fonction est alors considérée comme un retour de promesse. Le mot-clé "await" ne peut être utilisé qu'à l'intérieur d'une telle fonction asynchrone et doit être placé avant un appel à une fonction qui rendra une Promesse.
Les éléments d'une liste peuvent être ajoutés ou supprimés, ce qui signifie que la taille de la liste peut changer. Les méthodes permettent de nombreux types de manipulations, y compris l'insertion ou la suppression dans un index spécifique. Les plages peuvent également être manipulées.
La Liste est une interface, donc quand on manipule une Liste, une vraie classe, généralement ArrayList, est utilisée en coulisse
Une liste repose sur les méthodes de tri de Collections, telles que Collections.sort().
Les méthodes de recherche contain(), indexOf(), et lastIndexOf() sont des exemples qui peuvent être utilisés pour rechercher les éléments. Cependant, pour effectuer une recherche binaire, il faut appeler la méthode plus générale : Collections.binarySearch(...)
Les listes peuvent contenir des objets de type mixte, par exemple :
List interviewList = new ArrayList();
interviewList.add(3);
interviewList.add(1415);
interviewList.add(“Pi”);
Bonus
Les tableaux peuvent stocker des objets, il existe donc une solution de rechange pour ceux qui sont enclins à mélanger les types dans un tableau. De plus, le candidat doit être crédité de savoir que les Listes remplacent les Vecteurs qui ne sont plus couramment utilisés en Java. La raison est liée à la simultanéité et à la synchronisation des opérations. Il est clair qu'une explication plus détaillée dépasse la portée de cette question - cependant, la mention de ce point est digne d'intérêt.
Mauvaise réponse
Les tableaux et les listes, parmi d'autres classes et interfaces intégrées, y compris les collections, sont très courants dans la programmation Java et le développement d'applications. Un candidat qui n'est pas à l'aise avec ces fonctionnalités manque presque certainement d'expérience avec le langage.
Contrairement au C++, Java ne prend pas en charge l'héritage multiple. Comment la programmation avec une interface apportera-t-elle une réponse à ce problème ? Une interface fait-elle partie de la hiérarchie des classes ?
Justification
S'il existe des points communs entre les langues que de nombreux programmeurs connaissent bien, il existe aussi des distinctions qui permettent de les définir. Dans un entretien en Java, il y aura des questions de base en Java qui aideront à évaluer dans quelle mesure le candidat connaît les spécificités du langage de programmation Java. Étant donné la question du problème du diamant en C++, il est intéressant de tester les connaissances du candidat dans une perspective java.
Bonne réponse
Une interface est similaire à une classe en ce sens qu'elle peut contenir différents types de méthodes, mais différente parce qu'elle ne détient pas l'état. Les interfaces sont intrinsèquement abstraites, et leurs méthodes doivent être implémentées par une classe. L'interface n'est pas instanciée, elle est implémentée. Contrairement au C++, une classe ne peut étendre qu'un seul parent (c'est-à-dire qu'elle ne peut avoir qu'une seule superclasse). Une interface, en revanche, est capable d'étendre plus d'une interface parent. Par exemple :
public interface CheckerBoard {
public void setSize(int rowCount, int columnCount);
}
public interface Game {
public void setNumberOfPlayers();
public void play();
}
public interface ChessGame extends CheckerBoard, Game {}
Dans cet exemple, l'interface ChessGame hérite à la fois de CheckerBoard et de Game.
Mauvaise réponse
Si la personne interrogée ne sait pas ce qu'est l'héritage multiple, cela suggère un manque d'expérience en matière de conception orientée objet. Cela n'est pas essentiel pour toutes les applications, bien qu'il soit important de reconnaître que java est intrinsèquement OO.
Qu'est-ce que la machine virtuelle Java ? Quel en est l'objectif principal et avec quel type de code fonctionne-t-elle ?
Justification
Aucune interview en Java ne serait complète sans une question sur le thème de la machine virtuelle. La JVM est un élément clé de Java, et les programmeurs java l'apprennent très tôt. Si la JVM est capable d'exécuter du bytecode généré par d'autres langages, tels que JRuby et Jython, cela n'enlève rien au fait qu'elle est essentielle à la java elle-même.
Bonne réponse
La JVM est une machine virtuelle qui permet à l'ordinateur d'exécuter des programmes Java qui ont été compilés en bytecode. Le bytecode est indépendant de la plateforme, et s'exécute sur tout ordinateur qui héberge une JVM. Il comprend un compilateur juste à temps (JIT) qui convertit le bytecode en instructions en langage machine, permettant aux applications de s'exécuter aussi rapidement qu'un exécutable natif.
Mauvaise réponse
La JVM est l'un des principaux composants qui font de Java ce qu'il est. Le fait de ne pas connaître la JVM indique probablement un manque d'expérience avec le langage.
Quelles sont les méthodes et les classes finales ? Une classe abstraite supportera-t-elle les méthodes finales ?
Justification
Le dernier mot-clé est commun et doit être bien compris par les programmeurs java. Au cours de la phase de conception OO, il est normalement décidé si les classes doivent être extensibles. Si ce n'est pas le cas, elles sont marquées comme finales afin de limiter les effets secondaires potentiels de sous-classes qui n'ont pas été envisagées. Il s'agit d'une caractéristique importante qui devrait être utilisée pour un code plus robuste et plus facile à maintenir.
Bonne réponse
Une méthode qui est déclarée avec le mot-clé final ne peut pas être annulée dans les sous-classes. Cette méthode est utilisée dans les hiérarchies où la mise en œuvre de la méthode doit être cohérente dans l'ensemble. La déclaration finale d'une classe interdit totalement le sous-classement. Oui, il est possible d'inclure des méthodes finales dans une classe abstraite. Cela permet de s'assurer que les sous-classes ne peuvent pas passer outre la méthode.
Mauvaise réponse
Si le candidat n'est pas familier avec le mot-clé final, qu'il soit utilisé au niveau de la classe ou de la méthode, alors cela suggère une relative inexpérience de la langue. Même pour les programmeurs inexpérimentés qui ont participé à la conception orientée objet, le concept de classe finale devrait être familier.
La programmation Java permet de créer un fil de discussion de différentes manières. Quelles sont-elles et quelle est la méthode préférée ? Expliquez.
Justification
Contrairement au C++, java contient un support intégré pour le multithreading. C'est une fonctionnalité riche et puissante qui est à la fois pertinente et utile dans de nombreuses applications. En tant que tel, le candidat doit être familier avec les bases.
Bonne réponse
Que se passe-t-il dans le cas où la réduction est appelée sur un tableau vide sans fournir la valeur initiale facultative de l'accumulateur ?
public class JavaInterviewClass implements Runnable {
public void run() {
System.out.println(“My example public class prints this line from a thread.”);
}
}
Pour exécuter la méthode run(), passez une instance de la classe dans un Thread, comme suit :
Thread interviewThread = new Thread(new JavaInterviewClass ());
interviewThread.start();
La deuxième façon de créer un fil de discussion est d'étendre la classe de fil de discussion. La sous-classe remplacera la méthode run(). Après cela, il suffit de créer une instance de la classe.
public class JavaInterviewClass extends Thread {
public void run() {
System.out.println(“My example public class extends the Thread class.”);
}
}
Pour exécuter le fil de discussion, il suffit d'instancier la classe et d'appeler start(), comme suit :
JavaInterviewClass myInterview = new JavaInterviewClass (); myInterview.start();
Bonus
Bien que l'implémentation de l'interface exécutable et l'extension de la classe Thread soient deux moyens populaires de créer un thread, il est également possible d'utiliser le framework Executor. Celui-ci permet de travailler directement avec les threads, mais il est moins connu. Il comprend des méthodes telles que newSingleThreadExecutor(), newFixedThreadPool() et submit() pour créer des tâches d'exécution. La connaissance de l'utilisation du framework Executor implique que le candidat soit très à l'aise avec la création et l'utilisation de threads en java.
Mauvaise réponse
Si le candidat n'est pas à l'aise avec l'utilisation des fils de discussion, il passe à côté d'une caractéristique puissante et importante de la langue. C'est important car comprendre le multithreading ne se limite pas à rechercher la syntaxe de quelques commandes. Il s'agit plutôt d'une approche qui doit être envisagée lors de la conception et du développement d'une application.
Le code Java a un support intégré pour la concurrence dans sa classe Thread. La simultanéité a son propre ensemble de problèmes tels que l'impasse et les conditions de course. Décrivez brièvement les variables Atomic en Java et leur utilisation. Ensuite, il est indiqué que la méthode start() est utilisée pour créer une pile d'appels séparée avant que la méthode run() ne soit utilisée pour exécuter un thread. Que font les méthodes yield(), sleep() et join() ?
Justification
La prise en charge du multithreading par Java peut entraîner des problèmes liés à la concurrence. Les connaissances du candidat concernant ces problèmes doivent être évaluées et prises en compte.
Bonne réponse
Une variable atomique est une variable "mise à jour atomique", ce qui signifie que l'intégrité des données est assurée par l'utilisation d'algorithmes non bloquants. Cette fonctionnalité est généralement mise en œuvre au niveau du code machine. Java prend en charge plusieurs variables atomiques, le plus souvent AtomicBoolean, AtomicInteger, AtomicLong et AtomicReference. Il existe également plusieurs méthodes qui permettent de récupérer et de modifier ces variables, notamment get(), set(), lazySet(), compareAndSet() et weakCompareAndSet(). Utilisées correctement, les variables atomiques peuvent être utilisées pour mettre en œuvre des méthodes "thread safe" (multithreading safe) qui traitent efficacement certains problèmes liés à la concurrence.
rendement() : Cette méthode informe l'environnement que le fil de discussion actuel n'est pas en train d'achever une tâche de haute priorité, et est prêt à en interrompre l'exécution. À condition que l'environnement sous-jacent supporte l'ordonnancement préventif, elle suspendra le fil s'il y en a un autre qui doit s'exécuter. S'il n'y a pas de deuxième fil, ou si le deuxième fil se termine, le fil en cours reprendra le contrôle et continuera à s'exécuter.
sommeil() : Cette méthode fait dormir le fil courant, ou met en pause son exécution, pendant un nombre de millisecondes déterminé. Il est également possible de combiner un certain nombre de millisecondes et de nanosecondes. Pendant que le fil courant est en sommeil, un autre fil sera exécuté, ou sinon le CPU restera inactif. Sous réserve de la précision de l'horloge du système et des minuteurs, le fil de discussion reprendra le contrôle une fois le compte à rebours terminé.
join() : Cette méthode est utilisée pour joindre deux l'exécution de deux fils ensemble. Pour clarifier, si le fil A appelle join() sur le fil B, alors A commencera à attendre. Une fois que B a terminé, ou qu'un délai prédéfini a expiré, A reprendra le contrôle et continuera l'exécution.
Mauvaise réponse
Le fait de connaître les fils de discussion Java, mais de ne pas être conscient des problèmes liés à la concurrence peut entraîner de graves erreurs. La majorité des appareils, des ordinateurs de bureau aux appareils mobiles en passant par les ordinateurs à carte unique, prennent désormais généralement en charge le multithreading et la concurrence. Il est important de comprendre la bonne utilisation des threads, et d'être conscient des méthodes fournies par java pour les prendre en charge.
Conclusion
Les questions de cet article sont utiles pour évaluer les compétences d'un futur programmeur Java. En ce qui concerne les questions d'entretien à préparer pour un développeur Java, il est important de se rappeler que les spécificités du langage peuvent être facilement référencées en utilisant l'aide et la documentation en ligne. Les points subtils d'un langage ne sont pas aussi importants que la façon dont on applique la logique. Cela dit, les candidats à ce poste sont censés connaître le langage et ne pas avoir besoin d'une formation approfondie avant que le travail réel ne commence. Les compétences requises seront dictées par le travail à effectuer, et la variation des questions données ci-dessus aidera à faire cette évaluation. N'oubliez pas que l'une des meilleures façons d'évaluer les compétences du candidat pour votre projet est d'effectuer une évaluation pratique de la programmation, ce qui est bien plus efficace que des questions d'entretien orales pour engager un programmeur Java hautement qualifié.
Le but de cet article est d’aider à préparer le recruteur, quelle que soit son expérience avec Java. Déterminer quel candidat parmi tant d’autres a offert la meilleure performance lors d’un entretien sur Java n’est pas une tâche facile lorsque l’on ne dispose pas de compétences avancées en programmation. Dans le même temps, il faut savoir que ce candidat parfait ne sera pas trouvé à l’aide de questions d’entretien purement liées au code. La programmation est souvent une question de logique, par opposition à la syntaxe, et ce serait une grave erreur de pénaliser trop lourdement les candidats parce qu’ils ne sont pas familiers avec une problématique pouvant être aisément solutionnée à l’aide de Google.
Cela dit, il est important de se rappeler que l’entretien doit aboutir à un poste de développeur Java. Le candidat doit connaître l’environnement d’exécution Java (JRE), la machine virtuelle Java (JVM) et le kit de développement Java (JDK), etc. Les bibliothèques couramment utilisées telles que java lang, java util ne devrait pas être un mystère pour eux. De même, alors qu’elle n’est plus utilisée, la bibliothèque Swingdevrait au moins leur être familière (alors qu’il est acceptable de ne pas connaître la bibliothèque Awt, qui est totalement obsolète. Enfin, les candidats doivent au moins être au courant de l’existence de frameworks et d’autres technologies tels que Spring framework, JavaServer Pages (JSP), et Java Database Connectivity (JDBC).
Les questions d'entretien Java doivent être spécifiques à certains égards, mais générales à d'autres. Par exemple, est-il nécessaire d'inclure des questions d'entretien JDBC spécifiques ? Peu probable. Cependant, un candidat doit absolument savoir ce qu'est une interface de la Liste.
Avec autant d'objectifs concurrents, comment trouver le candidat idéal ? La réponse réside dans un large éventail de questions d'entretien qui couvrent le sujet sous plus d'un angle. Cet article vise à répondre à ces préoccupations en fournissant la question d'entretien de Java, la ou les réponses correctes, et la raison pour laquelle chaque question est posée.
Consultez la question Java ci-dessous. Il existe plusieurs façons de la résoudre, de sorte que les choix du candidat peuvent révéler sa façon de coder. Comment la résoudriez-vous ? Cliquez sur l'onglet "Instructions" et essayez :
Questions de programmation de différents niveaux et leurs réponses
Cet article contient 14 questions d’entretien et leurs réponses. Les 5 premières sont niveau débutant, tandis que les autres varient à la fois en termes de sujet et de niveau de difficulté. Un score parfait ne sera pas nécessairement obtenu en répondant à chaque question parfaitement. Au contraire, la discussion sur les solutions donnera le meilleur indicateur à la fois de la capacité de réflexion du candidat et de l’expérience qu’il a accumulée.
Questions de programmation Java niveau débutant
1 - Le code Java prévoit des méthodes de classe avec des spécificateurs d'accès public et privé. Quelle est la différence entre ces deux modificateurs ?
Justification
Dans la programmation orientée objet, il est courant de limiter la portée des variables et des fonctions à des classes spécifiques dans une hiérarchie de classes. Ceci est réalisé à l’aide de différents spécificateurs d’accès, et connaître la différence entre ces composants fondamentaux est une question d’entretien Java très pertinente.
En Java, les classes peuvent être uniquement déclarées publiques, ou bien pas du tout – alors que les fonctions membres ont quatre modificateurs différents – c’est donc un sujet qui peut s’avérer épineux pour les grands débutants.
Bonne réponse
Un spécificateur d’accès public ordonne que la méthode soit accessible à la fois à l’intérieur et à l’extérieur de la classe. Ceci est vrai tant que la classe elle-même est déclarée publique, ou que la classe appelante est dans le même package. Si la classe ne spécifie pas de modificateur, elle est supposée avoir un accès par défaut (package), et les déclarations de ses méthodes ne l’écrasent pas.
Un spécificateur d’accès privé indique que la méthode doit être accessible uniquement à l’intérieur de la classe.
Bonus
Si le candidat sait qu'il existe également des spécifications pour les produits protégés et les emballages (par défaut), il démontre alors une bonne compréhension de ce sujet.
Mauvaise réponse
Si le candidat ne connaît pas la différence entre public et private, cela indique un manque d’expérience à propos de Java et probablement dans d’autres langages orientés objet tels que C++. Si la réponse est correcte, mais qu’il n’est pas fait mention du fait que le modificateur de classe l’emporte sur les méthodes, le candidat devrait être pénalisé.
Considérons le code suivant qui contient une classe, une variable statique et une méthode publique. Combien de bouchées ont été prises pour chaque pomme ?
public class Apple {
static int bites = 0;
public void takeBite() {
bites++;
}
public static void main(String[] args) {
// Instantiate red and green apples for our example public class
Apple macintosh = new Apple();
Apple grannySmith = new Apple();
// Take a bite out of each of the two apples
macintosh.takeBite();
grannySmith.takeBite();
// Display the contents of each class
System.out.println("The Macintosh apple has " + macintosh.bites + " bite(s) out of it.");
System.out.println("The Granny Smith apple has " + grannySmith.bites + " bite(s) out of it.");
}
}
Justification
Les variables statiques sont une caractéristique de Java régulièrement utilisée par les développeurs. Comme c’est le cas pour les variables globales, il est important pour les programmeurs de comprendre la portée de ces objets afin d’éviter un quelconque effet collatéral. Note à propos de la non-déclaration d’une variable : cela permet d’éviter de mal taper le nom d’une variable, car la variable mal orthographiée apparaîtra comme une nouvelle variable non déclarée.
Bonne réponse
La classe Apple partage la variable statique, bites, entre toutes ses instances. Par conséquent, lorsque la méthode takeBite() est appelée sur chacune des instances, la variable commune est mise à jour. Le résultat final se présente ainsi :
The Macintosh apple has 2 bite(s) out of it.
The Granny Smith apple has 2 bite(s) out of it.
Mauvaise réponse
Si le candidat répond que chacune des deux instances s’est vue retirée une seule bouchée (bite), cela indique un manque d’expérience avec les variables statiques. Ce sujet est trivial, mais un développeur Java le rencontrera fréquemment. Le fait de ne pas en avoir connaissance indique que le candidat manque probablement d’expérience pratique du langage.
Qu'est-ce qu'une exception ? Décrivez brièvement les deux types d'exception utilisés dans le code java.
Justification
Les exceptions sont des événements inattendus qui surviennent au moment de l’exécution et qui diffèrent des erreurs dans la mesure où il est généralement aisé de les « rattraper ». Les erreurs, par contre, indiquent généralement un problème plus grave. La gestion des exceptions est très courante et doit être comprise, au moins à un niveau de base, par n’importe quel programmeur Java.
Bonne réponse
Les deux types d’exceptions dans Java sont les exceptions vérifiées et les exceptions non-vérifiées.
Une exception vérifiée est une exception qui est vérifiée au moment de la compilation. Lorsqu’il y a du code dans une méthode qui lève une exception vérifiée, la méthode est nécessaire pour l’acquitter. Ceci peut être accompli soit en gérant l’exception avec un bloc try/catch, soit en la spécifiant à l’aide du mot-clé throws. Une exception non-vérifiée est une exception qui n’est pas vérifiée au moment de la compilation. C’est au programmeur de spécifier ce type d’exception. En revanche, il faut noter que toutes les exceptions en C++ sont non-vérifiées.
Bonus
En Java, toutes les exceptions des classes Error et RuntimeException sont décochées. Tout le reste sous Throwable est vérifié. Si la personne interrogée soulève ce point particulier, elle démontre une compréhension profonde de la question qui lui a été posée.
Mauvaise réponse
Si le candidat n’est pas au courant des exceptions, il lui manque une partie essentielle du langage qui est responsable du contrôle de l’exécution. Cette fonctionnalité représente un véritable bond en avant par rapport à des langages tels que C (qui ne supporte pas la gestion des exceptions). Bien qu’elles ne soient pas absolument indispensables, les exceptions sont extrêmement utiles au quotidien du fait de leurs nombreux avantages, tout développeur Java efficace les utilise.
Que sont les cours d'emballage ? Donnez des exemples de deux d'entre elles et des primitives correspondantes. Quel est le rapport entre chacune d'elles et un objet ?
Justification
Les classes d’emballage sont fondamentales en programmation Java. En fait, leur existence implique que java n’est pas 100% orienté objet (bonus au candidat qui le signale !). C’est le cas parce que Java contient 8 types de données primitives qui ne sont pas, par définition, des objets.
Bonne réponse
Une classe d’emballage est une classe qui contient une variable qui est un type de données primitives, et qui enveloppe la primitive pour fournir une fonctionnalité d’interaction avec elle. En fait, on peut dire qu’il transforme le primitif en objet. Ce qui est utile, par exemple, lorsqu’une méthode vise au transfert d’un objet. Le candidat doit être capable de nommer au moins deux des paires suivantes :
Primitive
Classe d'emballage
boolean
Boolean
byte
Byte
char
Char
double
Double
float
Float
int
Int
long
Long
short
Short
Mauvaise réponse
Les classes d’emballage sont définies en java.lang, et requises car il existe de nombreuses classes qui supportent uniquement les objets. Le fait de ne pas connaître ces classes d’emballage, ou de ne pas savoir pourquoi elles seraient utilisées, apparaît comme une grave lacune de la part du candidat interrogé.
Définissez les termes suivants qui sont courants dans la programmation java
Classe abstraite
Ramasse-miettes (aussi appelé récupérateur de mémoire, glaneur de cellules ou garbage collector)
Autoboxing
Sérialisation
Justification
Cette liste inclut des termes qui sont communément utilisés en Java, ainsi que dans d’autres langages de programmation. Les questions d’entretien pour les programmeurs expérimentés incluent de telles définitions parce qu’elles permettent de tester leurs connaissances de manière approfondie, ainsi que leur capacité à distinguer des langages comportant des concepts proches sans être parfaitement identiques.
Bonne réponse
Une classe abstraite est utilisée comme classe de base pour les sous-classes qui vont étendre ou écraser ses méthodes. Prenons l’exemple d’une classe « Forme ». Une forme peut contenir un certain nombre de côtés, de faces ou même de dimensions. Prise isolément, savoir que cette classe est une « Forme » est peu utile. D’autre part, si cette classe abstraite sera utilisée comme classe de base pour un « Carré », un « Triangle », ou un autre type de polygone, elle deviendra utile quand placée au sommet de la hiérarchie des classes. - Il n'est pas possible d'instancier une classe abstraite. – Elle peut contenir des méthodes abstraites, mais ce n’est pas obligatoire. - Les sous-classes de la classe d'abstraction doivent mettre en œuvre toutes les méthodes d'abstraction, à moins qu'il ne s'agisse également d'une classe d'abstraction. Il n'est pas possible d'instancier une classe abstraite.
Ne pas être parfaitement calé à propos classes abstraites n’est pas éliminatoire, bien que ces dernières seront très probablement rencontrées par le programmeur Java lorsqu’il devra effectuer des actions de maintenance ou du débogage d’une base de code existante.
La "garbage collection" (effectuée par le "garbage collector" ou ramasse-miettes) est le processus de détection et de suppression des objets en mémoire qui ne sont plus utilisés ou référencés. En java, le ramassage des miettes est automatique, mais il peut aussi être demandé.
Les commandes System.gc() et Runtime.gc() indiqueront au ramasse-miettes qu’il doit s’exécuter, bien que cela ne soit pas garanti.
Les fils d’exécution sont mis en pause pendant le ramassage des ordures. Cela ralentit nécessairement l’exécution, ce qui signifie que dans les applications réactives, le ramassage des miettes doit être réduit au minimum. La connaissance du ramasseur de miettes n’est pas indispensable, surtout pour un programmeur débutant. Il est à noter, cependant, que lorsqu’on vient d’un langage comme C, où toute la mémoire est gérée manuellement, le développeur doit être au courant de l’existence de cette fonctionnalité.
L’Autoboxing est l’emballage automatique d’un type primitif (voir la question #4 relative aux types primitifs et classes d’emballages). Par exemple, l’autoboxing convertira automatiquement un nombre de type float (type primitif) en Float (classe d’emballage). Le contraire de cela est le déballage, lors duquel type primitif est extrait de la classe d’emballage. Cette notion est habituellement familière aux bons développeurs Java.
La sérialisation fait référence à l’encodage d’objets en mémoire dans un flux d’octets qui pouvant être facilement stockés ou transmis. Le contraire est la désérialisation, qui reconstruit les objets à partir d’un flux d’octets. Il existe différentes approches pour réaliser la sérialisation. Deux méthodes courantes sont la conversion de l’objet en XML (eXtensible Markup Language), ou JSON (JavaScript Object Notation). Ce sont des types de fichiers bien connus, chacun d’entre eux étant largement pris en charge. Java supporte également la sérialisation comme partie intégrante du langage. Le langage inclut l’interface sérialisable, qui peut être utilisée à la fois pour la sérialisation et la désérialisation. La méthode writeObject() est utilisée pour encoder les données, tandis que la méthode readObject() est utilisée pour reconstruire les objets.
Java définit une classe String pour représenter des tableaux de caractères. Répondez aux questions suivantes :
Un constructeur initialise un objet lors de sa création. Cependant, les constructeurs n'ont pas de type de retour explicite.
En général, vous utiliserez un constructeur pour donner des valeurs initiales aux variables d'instance définies par la classe, ou pour effectuer toute autre procédure de démarrage nécessaire pour créer un objet entièrement formé.
Toutes les classes ont des constructeurs, que vous en définissiez un ou non, car Java fournit automatiquement un constructeur par défaut qui initialise toutes les variables membres à zéro. Cependant, une fois que vous avez défini votre propre constructeur, le constructeur par défaut n'est plus utilisé.
Pourriez-vous citer quelques cadres de travail Java ?
Cette question d'entretien est une question de base : tout développeur Java compétent est en mesure de nommer quelques frameworks écrits en langage Java. Au cours de l'entretien, le candidat interrogé doit mentionner au moins trois frameworks Java parmi cette liste :
JSF (Java Server Faces), un cadre web Java qui facilite la construction d'interfaces utilisateur pour les applications basées sur des serveurs
GWT (Google Web Toolkit), un ensemble d'outils open-source qui aide les programmeurs à créer et à maintenir des applications JavaScript dans Java Spring, un framework Java qui n'impose aucun modèle de programmation spécifique
Struts
Hiberner
Grails
Jouez !
Vaadin
Maven
Questions d'entretien sur la programmation mixte
Java définit une classe String pour représenter des tableaux de caractères. Répondez aux questions suivantes :
- Par quoi faut-il remplacer le "XXX" pour pouvoir comparer les deux principaux arcs de cordes ? Si les arguments sont : "Sun Microsystems" et "Sun microsystems", quel sera le résultat de l'exécution ? Y a-t-il un moyen de garantir qu'il les déclarera comme étant identiques ? - Si les arguments sont plutôt : "Sun Microsystems" et "Sun Microsystems", quel sera le résultat de l'exécution ? "Sun Microsystem" et "Sun Microsystems", quel sera le résultat de l'exécution ?
1/ Après la création d'une chaîne, est-il possible de la modifier ? Considérez ce qui suit :
public static void main(String[] args) { String name = "James gosling"; // I want to change the 'g' to a 'G'. // Will this work at compile time? name.charAt(6) = 'G'; // Print with the standard system println to see “James Gosling” System.out.println(name); }
Cela va-t-il fonctionner ? Si ce n'est pas le cas, quelles modifications faudrait-il apporter pour obtenir la chaîne souhaitée ?
2/ La classe String a plus d'un Comparateur. Considérez le code suivant :
public static void main(String[] args) { // This program received 2 arguments. We want to // determine if those two strings are equal. // Compare the first argument to the second argument boolean compareResult = (XXX); if (compareResult) { System.out.println("The Strings are the same."); } else { System.out.println("The Strings are not the same."); } // Print the main string args System.out.println(args[0]); System.out.println(args[1]); }
- Par quoi faut-il remplacer le "XXX" pour pouvoir comparer les deux principaux arcs de cordes ? Si les arguments sont : "Sun Microsystems" et "Sun microsystems", quel sera le résultat de l'exécution ? Y a-t-il un moyen de garantir qu'il les déclarera comme étant identiques ? - Si les arguments sont plutôt : "Sun Microsystems" et "Sun Microsystems", quel sera le résultat de l'exécution ? "Sun Microsystem" et "Sun Microsystems", quel sera le résultat de l'exécution ?
3/ Qu'est-ce que le pool de constantes de la chaîne Java ? (ou pool de chaînes de caractères Java) ? Il réside dans la mémoire de la pile ?
Justification
L'utilisation de représentations de chaînes de caractères est courante dans de nombreux langages, et Java ne fait pas exception. Il est important de comprendre comment les chaînes de caractères sont créées, analysées, imprimées et manipulées. C'est un sujet important qui constitue une question d'entretien importante pour les développeurs Java.
Bonne réponse
Non, cela échouera au moment de la compilation car il n'est pas possible de modifier une chaîne une fois qu'elle a été initialisée. Cette propriété est dite immuable. Pour que cela fonctionne, il faudrait recréer la chaîne contenant "James gosling". Une approche consiste à utiliser un tableau de caractères intermédiaires (en appelant la méthode toCharArray() sur le "nom"), à remplacer le "g" par la lettre majuscule, puis à recréer la chaîne avant de l'imprimer. Un bonus pour le candidat qui souligne que la fonction string replace(...) existe pour remplacer les caractères, mais ne peut pas être utilisée car toutes les instances de "g" minuscules seraient remplacées.
Le comparateur exact dans cet exemple est soit égal(...) soit égalIgnoreCase(...). Le type de retour de ces deux méthodes est une valeur booléenne. Si la personne interrogée répond compareTo(...) ou compareToIgnoreCase(...), alors le crédit devrait être accordé, bien que le type de retour de ces méthodes soit un int, donc techniquement incorrect. Il n'en reste pas moins qu'elle démontre une connaissance de la langue.
Dans le premier exemple, les chaînes sont identiques sous equalsIgnoreCase(...), mais différentes sous equals(...). Dans le deuxième exemple, il y a un "s" à la fin, ce qui fait que les chaînes sont différentes dans tous les cas.
Le Java Constant String Pool est une zone de la mémoire du Heap (donc, pas de la mémoire de la pile) où sont stockées les chaînes de caractères. Cette approche est à l'origine de la raison pour laquelle les chaînes sont immuables en java.
Par exemple :
chaîne x = "chaîne principale" ;
chaîne de caractères y = "machine virtuelle" ;
chaîne z = "chaîne principale" ;
Les trois cordes ci-dessus sont stockées dans le pool de cordes, mais la partie intéressante est l'efficacité. x et y pointent tous deux vers la même zone dans la réserve de cordes, ce qui ne nécessite pas de duplication de l'espace. Sachant cela, il doit être clair que la modification de la valeur de x n'est pas autorisée car elle aurait l'effet secondaire non voulu de modifier z.
Quelles sont les différences entre la mémoire Stack et l'espace Heap ?
Justification
Afin d'améliorer l'efficacité, la JVM organise la mémoire pour que les applications puissent s'exécuter. Elle crée de l'espace de pile et de l'espace de tas, chacun étant utilisé par des opérations différentes. Comprendre l'allocation de la mémoire à ce niveau peut conduire à un ramassage des déchets plus prévisible et, en fin de compte, à une efficacité accrue.
Bonne réponse
La mémoire en pile est utilisée pour l'allocation de mémoire statique, comme les valeurs primitives à l'intérieur d'une méthode. Elle est toujours utilisée pour l'exécution d'un thread. La pile s'agrandit lorsque les méthodes sont appelées, et se réduit lorsqu'elles reviennent. Si la mémoire allouée pour la pile est dépassée, l'exception java.lang.StackOverFlowError est lancée.
La mémoire de tas est utilisée pour l'allocation de mémoire dynamique, comme les objets java. Plus précisément, l'objet est stocké dans le tas, tandis que la référence à l'objet est stockée dans la pile. Les classes JRE sont également stockées dans le tas au moment de l'exécution. L'accès aux données dans le tas est plus lent que dans la mémoire de la pile. Le tas requiert l'action du collecteur de déchets afin de libérer les objets inutilisés. Si la mémoire allouée au tas est dépassée, l'exception java.lang.OutOfMemoryError est lancée.
Mauvaise réponse
Le fait de n'avoir jamais entendu parler de la pile ou du tas indiquerait une connaissance superficielle du langage de programmation java. De plus, la terminologie est typique d'une culture générale de programmation. Le diagnostic des erreurs liées à la mémoire, telles qu'un débordement de pile causé par un comportement incorrect d'une fonction récursive, serait plus facile avec cette compréhension.
Deux termes liés à la classe utilisés dans la programmation java sont "subclass" et "nested class". Expliquez les différences entre ces deux termes. Pourquoi choisir l'une plutôt que l'autre ? Laquelle est parfois appelée "classe intérieure" ?
Justification
Dans la conception orientée objet, il y a souvent une confusion sur le placement des classes dans la hiérarchie. Les classes imbriquées sont relativement rares par rapport aux sous-classes, mais leur utilisation est bénéfique dans de nombreuses situations. La connaissance de leur existence et de leur mode d'utilisation doit être considérée comme un atout.
Bonne réponse
Une sous-classe est une extension d'une autre classe, et est souvent une spécialisation de l'original. Les sous-classes héritent des membres publics et protégés de leur super-classe. Les sous-classes peuvent être instanciées indépendamment de la superclasse, et en fait, c'est toujours le cas lorsque la superclasse est une classe abstraite.
Une classe imbriquée est une classe à l'intérieur d'une classe, qui dans certains cas est une classe intérieure. Le champ d'application de la classe intérieure comprend tous les membres de sa classe extérieure, ce qui lui donne accès à ces variables et méthodes. Comme le corps existe entièrement au sein de la classe englobante, il ne peut pas être instancié indépendamment, sans elle.
L'utilisation d'une classe interne peut améliorer la conception orientée objet en organisant davantage le code. L'objectif est limité dans la mesure où il existe pour servir sa classe englobante. Si la classe interne offre des fonctionnalités utiles à une plus grande échelle, il serait plus logique de l'avoir comme classe de haut niveau. Les classes internes sont couramment utilisées comme fonctions de rappel pour les composants de l'interface graphique.
Bonus
Il existe deux types de classes imbriquées. Plus précisément, il existe une classe imbriquée statique, qui n'a pas directement accès aux autres membres de la classe englobante. Celles-ci ne sont pas souvent utilisées, c'est pourquoi le fait de les connaître est un bonus par opposition à l'ignorance qui peut entraîner une pénalité. L'autre type est une classe imbriquée non statique, qui est la version que l'on appelle une classe intérieure. Ceux-ci ont en effet accès à tous les membres de la classe englobante, y compris aux méthodes privées.
Mauvaise réponse
Le candidat doit être pardonné de n'avoir jamais utilisé une classe imbriquée. Bien qu'utile, et susceptible d'être vu si l'on maintient une base de code existante, le concept est simple. Les classes imbriquées rendent souvent le code plus élégant et plus facile à maintenir, mais certains concepteurs considèrent que c'est une question de style. Les sous-classes, d'autre part, sont un élément fondamental de la programmation orientée objet que tout développeur java devrait connaître. Ne pas pouvoir discuter facilement des sous-classes au sein d'une hiérarchie de classes est un sérieux signal d'alarme.
Deux classes de collection sont disponibles en programmation java : Array et List. En quoi les méthodes diffèrent-elles entre ces deux objets conteneurs, et dans quelles circonstances choisiriez-vous l'une plutôt que l'autre ?
Justification
L'utilisation de conteneurs est courante en Java et dans d'autres langages de programmation. La liste est une structure de données dynamique, tandis que le tableau est statique. Il est important de reconnaître que chacun d'entre eux est mieux adapté à certaines applications, et à ce titre, le candidat doit les connaître. Avoir une connaissance approfondie des types de données et des classes de conteneurs disponibles permettra en fin de compte de gagner du temps de développement.
Bonne réponse
Array
Les tableaux sont de taille statique, ils ne peuvent donc ni croître ni diminuer en termes de nombre d'éléments. Cela signifie qu'il existe des méthodes pour accéder aux éléments et les modifier, mais pas pour les insérer ou les supprimer.
Java fournit des méthodes pour effectuer une recherche binaire ou un tri sur un tableau. De plus, un tableau peut être initialisé en utilisant la méthode fill(), ou comparé en utilisant le comparateur equals().
La taille d'un tableau est fixée lors de sa création.
L'accès aléatoire d'un élément dans un tableau est très efficace.
Les tableaux sont plus adaptés à des collections d'éléments de longueur fixe.
Tous les éléments sont du même type, par exemple :
int[] interviewArray = new int[5];
or
int[] arrayForInterview = {3, 1, 4, 1, 5};
Ces deux tableaux contiennent cinq entiers.
Vecteur
Les candidats doivent savoir quand il est approprié et possible d'utiliser ces mots clés. En particulier, ils doivent savoir que l'asynchronisation ne peut être placée avant le mot-clé de fonction sur une définition de fonction. La fonction est alors considérée comme un retour de promesse. Le mot-clé "await" ne peut être utilisé qu'à l'intérieur d'une telle fonction asynchrone et doit être placé avant un appel à une fonction qui rendra une Promesse.
Les éléments d'une liste peuvent être ajoutés ou supprimés, ce qui signifie que la taille de la liste peut changer. Les méthodes permettent de nombreux types de manipulations, y compris l'insertion ou la suppression dans un index spécifique. Les plages peuvent également être manipulées.
La Liste est une interface, donc quand on manipule une Liste, une vraie classe, généralement ArrayList, est utilisée en coulisse
Une liste repose sur les méthodes de tri de Collections, telles que Collections.sort().
Les méthodes de recherche contain(), indexOf(), et lastIndexOf() sont des exemples qui peuvent être utilisés pour rechercher les éléments. Cependant, pour effectuer une recherche binaire, il faut appeler la méthode plus générale : Collections.binarySearch(...)
Les listes peuvent contenir des objets de type mixte, par exemple :
List interviewList = new ArrayList();
interviewList.add(3);
interviewList.add(1415);
interviewList.add(“Pi”);
Bonus
Les tableaux peuvent stocker des objets, il existe donc une solution de rechange pour ceux qui sont enclins à mélanger les types dans un tableau. De plus, le candidat doit être crédité de savoir que les Listes remplacent les Vecteurs qui ne sont plus couramment utilisés en Java. La raison est liée à la simultanéité et à la synchronisation des opérations. Il est clair qu'une explication plus détaillée dépasse la portée de cette question - cependant, la mention de ce point est digne d'intérêt.
Mauvaise réponse
Les tableaux et les listes, parmi d'autres classes et interfaces intégrées, y compris les collections, sont très courants dans la programmation Java et le développement d'applications. Un candidat qui n'est pas à l'aise avec ces fonctionnalités manque presque certainement d'expérience avec le langage.
Contrairement au C++, Java ne prend pas en charge l'héritage multiple. Comment la programmation avec une interface apportera-t-elle une réponse à ce problème ? Une interface fait-elle partie de la hiérarchie des classes ?
Justification
S'il existe des points communs entre les langues que de nombreux programmeurs connaissent bien, il existe aussi des distinctions qui permettent de les définir. Dans un entretien en Java, il y aura des questions de base en Java qui aideront à évaluer dans quelle mesure le candidat connaît les spécificités du langage de programmation Java. Étant donné la question du problème du diamant en C++, il est intéressant de tester les connaissances du candidat dans une perspective java.
Bonne réponse
Une interface est similaire à une classe en ce sens qu'elle peut contenir différents types de méthodes, mais différente parce qu'elle ne détient pas l'état. Les interfaces sont intrinsèquement abstraites, et leurs méthodes doivent être implémentées par une classe. L'interface n'est pas instanciée, elle est implémentée. Contrairement au C++, une classe ne peut étendre qu'un seul parent (c'est-à-dire qu'elle ne peut avoir qu'une seule superclasse). Une interface, en revanche, est capable d'étendre plus d'une interface parent. Par exemple :
public interface CheckerBoard {
public void setSize(int rowCount, int columnCount);
}
public interface Game {
public void setNumberOfPlayers();
public void play();
}
public interface ChessGame extends CheckerBoard, Game {}
Dans cet exemple, l'interface ChessGame hérite à la fois de CheckerBoard et de Game.
Mauvaise réponse
Si la personne interrogée ne sait pas ce qu'est l'héritage multiple, cela suggère un manque d'expérience en matière de conception orientée objet. Cela n'est pas essentiel pour toutes les applications, bien qu'il soit important de reconnaître que java est intrinsèquement OO.
Qu'est-ce que la machine virtuelle Java ? Quel en est l'objectif principal et avec quel type de code fonctionne-t-elle ?
Justification
Aucune interview en Java ne serait complète sans une question sur le thème de la machine virtuelle. La JVM est un élément clé de Java, et les programmeurs java l'apprennent très tôt. Si la JVM est capable d'exécuter du bytecode généré par d'autres langages, tels que JRuby et Jython, cela n'enlève rien au fait qu'elle est essentielle à la java elle-même.
Bonne réponse
La JVM est une machine virtuelle qui permet à l'ordinateur d'exécuter des programmes Java qui ont été compilés en bytecode. Le bytecode est indépendant de la plateforme, et s'exécute sur tout ordinateur qui héberge une JVM. Il comprend un compilateur juste à temps (JIT) qui convertit le bytecode en instructions en langage machine, permettant aux applications de s'exécuter aussi rapidement qu'un exécutable natif.
Mauvaise réponse
La JVM est l'un des principaux composants qui font de Java ce qu'il est. Le fait de ne pas connaître la JVM indique probablement un manque d'expérience avec le langage.
Quelles sont les méthodes et les classes finales ? Une classe abstraite supportera-t-elle les méthodes finales ?
Justification
Le dernier mot-clé est commun et doit être bien compris par les programmeurs java. Au cours de la phase de conception OO, il est normalement décidé si les classes doivent être extensibles. Si ce n'est pas le cas, elles sont marquées comme finales afin de limiter les effets secondaires potentiels de sous-classes qui n'ont pas été envisagées. Il s'agit d'une caractéristique importante qui devrait être utilisée pour un code plus robuste et plus facile à maintenir.
Bonne réponse
Une méthode qui est déclarée avec le mot-clé final ne peut pas être annulée dans les sous-classes. Cette méthode est utilisée dans les hiérarchies où la mise en œuvre de la méthode doit être cohérente dans l'ensemble. La déclaration finale d'une classe interdit totalement le sous-classement. Oui, il est possible d'inclure des méthodes finales dans une classe abstraite. Cela permet de s'assurer que les sous-classes ne peuvent pas passer outre la méthode.
Mauvaise réponse
Si le candidat n'est pas familier avec le mot-clé final, qu'il soit utilisé au niveau de la classe ou de la méthode, alors cela suggère une relative inexpérience de la langue. Même pour les programmeurs inexpérimentés qui ont participé à la conception orientée objet, le concept de classe finale devrait être familier.
La programmation Java permet de créer un fil de discussion de différentes manières. Quelles sont-elles et quelle est la méthode préférée ? Expliquez.
Justification
Contrairement au C++, java contient un support intégré pour le multithreading. C'est une fonctionnalité riche et puissante qui est à la fois pertinente et utile dans de nombreuses applications. En tant que tel, le candidat doit être familier avec les bases.
Bonne réponse
Que se passe-t-il dans le cas où la réduction est appelée sur un tableau vide sans fournir la valeur initiale facultative de l'accumulateur ?
public class JavaInterviewClass implements Runnable {
public void run() {
System.out.println(“My example public class prints this line from a thread.”);
}
}
Pour exécuter la méthode run(), passez une instance de la classe dans un Thread, comme suit :
Thread interviewThread = new Thread(new JavaInterviewClass ());
interviewThread.start();
La deuxième façon de créer un fil de discussion est d'étendre la classe de fil de discussion. La sous-classe remplacera la méthode run(). Après cela, il suffit de créer une instance de la classe.
public class JavaInterviewClass extends Thread {
public void run() {
System.out.println(“My example public class extends the Thread class.”);
}
}
Pour exécuter le fil de discussion, il suffit d'instancier la classe et d'appeler start(), comme suit :
JavaInterviewClass myInterview = new JavaInterviewClass (); myInterview.start();
Bonus
Bien que l'implémentation de l'interface exécutable et l'extension de la classe Thread soient deux moyens populaires de créer un thread, il est également possible d'utiliser le framework Executor. Celui-ci permet de travailler directement avec les threads, mais il est moins connu. Il comprend des méthodes telles que newSingleThreadExecutor(), newFixedThreadPool() et submit() pour créer des tâches d'exécution. La connaissance de l'utilisation du framework Executor implique que le candidat soit très à l'aise avec la création et l'utilisation de threads en java.
Mauvaise réponse
Si le candidat n'est pas à l'aise avec l'utilisation des fils de discussion, il passe à côté d'une caractéristique puissante et importante de la langue. C'est important car comprendre le multithreading ne se limite pas à rechercher la syntaxe de quelques commandes. Il s'agit plutôt d'une approche qui doit être envisagée lors de la conception et du développement d'une application.
Le code Java a un support intégré pour la concurrence dans sa classe Thread. La simultanéité a son propre ensemble de problèmes tels que l'impasse et les conditions de course. Décrivez brièvement les variables Atomic en Java et leur utilisation. Ensuite, il est indiqué que la méthode start() est utilisée pour créer une pile d'appels séparée avant que la méthode run() ne soit utilisée pour exécuter un thread. Que font les méthodes yield(), sleep() et join() ?
Justification
La prise en charge du multithreading par Java peut entraîner des problèmes liés à la concurrence. Les connaissances du candidat concernant ces problèmes doivent être évaluées et prises en compte.
Bonne réponse
Une variable atomique est une variable "mise à jour atomique", ce qui signifie que l'intégrité des données est assurée par l'utilisation d'algorithmes non bloquants. Cette fonctionnalité est généralement mise en œuvre au niveau du code machine. Java prend en charge plusieurs variables atomiques, le plus souvent AtomicBoolean, AtomicInteger, AtomicLong et AtomicReference. Il existe également plusieurs méthodes qui permettent de récupérer et de modifier ces variables, notamment get(), set(), lazySet(), compareAndSet() et weakCompareAndSet(). Utilisées correctement, les variables atomiques peuvent être utilisées pour mettre en œuvre des méthodes "thread safe" (multithreading safe) qui traitent efficacement certains problèmes liés à la concurrence.
rendement() : Cette méthode informe l'environnement que le fil de discussion actuel n'est pas en train d'achever une tâche de haute priorité, et est prêt à en interrompre l'exécution. À condition que l'environnement sous-jacent supporte l'ordonnancement préventif, elle suspendra le fil s'il y en a un autre qui doit s'exécuter. S'il n'y a pas de deuxième fil, ou si le deuxième fil se termine, le fil en cours reprendra le contrôle et continuera à s'exécuter.
sommeil() : Cette méthode fait dormir le fil courant, ou met en pause son exécution, pendant un nombre de millisecondes déterminé. Il est également possible de combiner un certain nombre de millisecondes et de nanosecondes. Pendant que le fil courant est en sommeil, un autre fil sera exécuté, ou sinon le CPU restera inactif. Sous réserve de la précision de l'horloge du système et des minuteurs, le fil de discussion reprendra le contrôle une fois le compte à rebours terminé.
join() : Cette méthode est utilisée pour joindre deux l'exécution de deux fils ensemble. Pour clarifier, si le fil A appelle join() sur le fil B, alors A commencera à attendre. Une fois que B a terminé, ou qu'un délai prédéfini a expiré, A reprendra le contrôle et continuera l'exécution.
Mauvaise réponse
Le fait de connaître les fils de discussion Java, mais de ne pas être conscient des problèmes liés à la concurrence peut entraîner de graves erreurs. La majorité des appareils, des ordinateurs de bureau aux appareils mobiles en passant par les ordinateurs à carte unique, prennent désormais généralement en charge le multithreading et la concurrence. Il est important de comprendre la bonne utilisation des threads, et d'être conscient des méthodes fournies par java pour les prendre en charge.
Conclusion
Les questions de cet article sont utiles pour évaluer les compétences d'un futur programmeur Java. En ce qui concerne les questions d'entretien à préparer pour un développeur Java, il est important de se rappeler que les spécificités du langage peuvent être facilement référencées en utilisant l'aide et la documentation en ligne. Les points subtils d'un langage ne sont pas aussi importants que la façon dont on applique la logique. Cela dit, les candidats à ce poste sont censés connaître le langage et ne pas avoir besoin d'une formation approfondie avant que le travail réel ne commence. Les compétences requises seront dictées par le travail à effectuer, et la variation des questions données ci-dessus aidera à faire cette évaluation. N'oubliez pas que l'une des meilleures façons d'évaluer les compétences du candidat pour votre projet est d'effectuer une évaluation pratique de la programmation, ce qui est bien plus efficace que des questions d'entretien orales pour engager un programmeur Java hautement qualifié.
Questions d’entretien pour recruter un développeur Java
Généralement, lorsque l’on parle de préparation pour l’entretien d’embauche d’un développeur Java, l’accent est mis sur le point de vue de la personne recrutée. Les candidats veulent savoir à quels types de questions ils doivent s’attendre afin de se préparer au mieux. Pourtant, en prenant un angle différent, on peut se demander : quelles questions un recruteur à la recherche d’un développeur Java doit-il poser aux candidats afin d’évaluer au mieux leurs compétences techniques ?
Dans une entreprise développant des logiciels, que le langage de programmation Java ou la programmation orientée objet en général soit un standard ou non, il est facile de trouver des questions de programmation et leurs réponses. Il est chose aisée d’utiliser Google pour rechercher la syntaxe du langage en question afin de faciliter la rédaction d’un entretien d’embauche sur Java.
Avant de commencer, voici une définition rapide du terme Java qui devrait vous aider si ce langage ne vous est pas entièrement familier :
Java is a high-level programming language developed by Sun Microsystems. It was originally designed for developing programs for set-top boxes and handheld devices, but later became a popular choice for creating web applications.
The Java syntax is similar to C++, but is strictly an object-oriented programming language. For example, most Java programs contain classes, which are used to define objects, and methods, which are assigned to individual classes. Java is also known for being more strict than C++, meaning variables and functions must be explicitly defined. This means Java source code may produce errors or “exceptions” more easily than other languages, but it also limits other types of errors that may be caused by undefined variables or unassigned types.
Christensson, P., Définition Java, techterms.com
Le but de cet article est d’aider à préparer le recruteur, quelle que soit son expérience avec Java. Déterminer quel candidat parmi tant d’autres a offert la meilleure performance lors d’un entretien sur Java n’est pas une tâche facile lorsque l’on ne dispose pas de compétences avancées en programmation. Dans le même temps, il faut savoir que ce candidat parfait ne sera pas trouvé à l’aide de questions d’entretien purement liées au code. La programmation est souvent une question de logique, par opposition à la syntaxe, et ce serait une grave erreur de pénaliser trop lourdement les candidats parce qu’ils ne sont pas familiers avec une problématique pouvant être aisément solutionnée à l’aide de Google.
Cela dit, il est important de se rappeler que l’entretien doit aboutir à un poste de développeur Java. Le candidat doit connaître l’environnement d’exécution Java (JRE), la machine virtuelle Java (JVM) et le kit de développement Java (JDK), etc. Les bibliothèques couramment utilisées telles que java lang, java util ne devrait pas être un mystère pour eux. De même, alors qu’elle n’est plus utilisée, la bibliothèque Swingdevrait au moins leur être familière (alors qu’il est acceptable de ne pas connaître la bibliothèque Awt, qui est totalement obsolète. Enfin, les candidats doivent au moins être au courant de l’existence de frameworks et d’autres technologies tels que Spring framework, JavaServer Pages (JSP), et Java Database Connectivity (JDBC).
Les questions d'entretien Java doivent être spécifiques à certains égards, mais générales à d'autres. Par exemple, est-il nécessaire d'inclure des questions d'entretien JDBC spécifiques ? Peu probable. Cependant, un candidat doit absolument savoir ce qu'est une interface de la Liste.
Avec autant d'objectifs concurrents, comment trouver le candidat idéal ? La réponse réside dans un large éventail de questions d'entretien qui couvrent le sujet sous plus d'un angle. Cet article vise à répondre à ces préoccupations en fournissant la question d'entretien de Java, la ou les réponses correctes, et la raison pour laquelle chaque question est posée.
Consultez la question Java ci-dessous. Il existe plusieurs façons de la résoudre, de sorte que les choix du candidat peuvent révéler sa façon de coder. Comment la résoudriez-vous ? Cliquez sur l'onglet "Instructions" et essayez :
Questions de programmation de différents niveaux et leurs réponses
Cet article contient 14 questions d’entretien et leurs réponses. Les 5 premières sont niveau débutant, tandis que les autres varient à la fois en termes de sujet et de niveau de difficulté. Un score parfait ne sera pas nécessairement obtenu en répondant à chaque question parfaitement. Au contraire, la discussion sur les solutions donnera le meilleur indicateur à la fois de la capacité de réflexion du candidat et de l’expérience qu’il a accumulée.
Questions de programmation Java niveau débutant
1 - Le code Java prévoit des méthodes de classe avec des spécificateurs d'accès public et privé. Quelle est la différence entre ces deux modificateurs ?
Justification
Dans la programmation orientée objet, il est courant de limiter la portée des variables et des fonctions à des classes spécifiques dans une hiérarchie de classes. Ceci est réalisé à l’aide de différents spécificateurs d’accès, et connaître la différence entre ces composants fondamentaux est une question d’entretien Java très pertinente.
En Java, les classes peuvent être uniquement déclarées publiques, ou bien pas du tout – alors que les fonctions membres ont quatre modificateurs différents – c’est donc un sujet qui peut s’avérer épineux pour les grands débutants.
Bonne réponse
Un spécificateur d’accès public ordonne que la méthode soit accessible à la fois à l’intérieur et à l’extérieur de la classe. Ceci est vrai tant que la classe elle-même est déclarée publique, ou que la classe appelante est dans le même package. Si la classe ne spécifie pas de modificateur, elle est supposée avoir un accès par défaut (package), et les déclarations de ses méthodes ne l’écrasent pas.
Un spécificateur d’accès privé indique que la méthode doit être accessible uniquement à l’intérieur de la classe.
Bonus
Si le candidat sait qu'il existe également des spécifications pour les produits protégés et les emballages (par défaut), il démontre alors une bonne compréhension de ce sujet.
Mauvaise réponse
Si le candidat ne connaît pas la différence entre public et private, cela indique un manque d’expérience à propos de Java et probablement dans d’autres langages orientés objet tels que C++. Si la réponse est correcte, mais qu’il n’est pas fait mention du fait que le modificateur de classe l’emporte sur les méthodes, le candidat devrait être pénalisé.
Considérons le code suivant qui contient une classe, une variable statique et une méthode publique. Combien de bouchées ont été prises pour chaque pomme ?
public class Apple {
static int bites = 0;
public void takeBite() {
bites++;
}
public static void main(String[] args) {
// Instantiate red and green apples for our example public class
Apple macintosh = new Apple();
Apple grannySmith = new Apple();
// Take a bite out of each of the two apples
macintosh.takeBite();
grannySmith.takeBite();
// Display the contents of each class
System.out.println("The Macintosh apple has " + macintosh.bites + " bite(s) out of it.");
System.out.println("The Granny Smith apple has " + grannySmith.bites + " bite(s) out of it.");
}
}
Justification
Les variables statiques sont une caractéristique de Java régulièrement utilisée par les développeurs. Comme c’est le cas pour les variables globales, il est important pour les programmeurs de comprendre la portée de ces objets afin d’éviter un quelconque effet collatéral. Note à propos de la non-déclaration d’une variable : cela permet d’éviter de mal taper le nom d’une variable, car la variable mal orthographiée apparaîtra comme une nouvelle variable non déclarée.
Bonne réponse
La classe Apple partage la variable statique, bites, entre toutes ses instances. Par conséquent, lorsque la méthode takeBite() est appelée sur chacune des instances, la variable commune est mise à jour. Le résultat final se présente ainsi :
The Macintosh apple has 2 bite(s) out of it.
The Granny Smith apple has 2 bite(s) out of it.
Mauvaise réponse
Si le candidat répond que chacune des deux instances s’est vue retirée une seule bouchée (bite), cela indique un manque d’expérience avec les variables statiques. Ce sujet est trivial, mais un développeur Java le rencontrera fréquemment. Le fait de ne pas en avoir connaissance indique que le candidat manque probablement d’expérience pratique du langage.
Qu'est-ce qu'une exception ? Décrivez brièvement les deux types d'exception utilisés dans le code java.
Justification
Les exceptions sont des événements inattendus qui surviennent au moment de l’exécution et qui diffèrent des erreurs dans la mesure où il est généralement aisé de les « rattraper ». Les erreurs, par contre, indiquent généralement un problème plus grave. La gestion des exceptions est très courante et doit être comprise, au moins à un niveau de base, par n’importe quel programmeur Java.
Bonne réponse
Les deux types d’exceptions dans Java sont les exceptions vérifiées et les exceptions non-vérifiées.
Une exception vérifiée est une exception qui est vérifiée au moment de la compilation. Lorsqu’il y a du code dans une méthode qui lève une exception vérifiée, la méthode est nécessaire pour l’acquitter. Ceci peut être accompli soit en gérant l’exception avec un bloc try/catch, soit en la spécifiant à l’aide du mot-clé throws. Une exception non-vérifiée est une exception qui n’est pas vérifiée au moment de la compilation. C’est au programmeur de spécifier ce type d’exception. En revanche, il faut noter que toutes les exceptions en C++ sont non-vérifiées.
Bonus
En Java, toutes les exceptions des classes Error et RuntimeException sont décochées. Tout le reste sous Throwable est vérifié. Si la personne interrogée soulève ce point particulier, elle démontre une compréhension profonde de la question qui lui a été posée.
Mauvaise réponse
Si le candidat n’est pas au courant des exceptions, il lui manque une partie essentielle du langage qui est responsable du contrôle de l’exécution. Cette fonctionnalité représente un véritable bond en avant par rapport à des langages tels que C (qui ne supporte pas la gestion des exceptions). Bien qu’elles ne soient pas absolument indispensables, les exceptions sont extrêmement utiles au quotidien du fait de leurs nombreux avantages, tout développeur Java efficace les utilise.
Que sont les cours d'emballage ? Donnez des exemples de deux d'entre elles et des primitives correspondantes. Quel est le rapport entre chacune d'elles et un objet ?
Justification
Les classes d’emballage sont fondamentales en programmation Java. En fait, leur existence implique que java n’est pas 100% orienté objet (bonus au candidat qui le signale !). C’est le cas parce que Java contient 8 types de données primitives qui ne sont pas, par définition, des objets.
Bonne réponse
Une classe d’emballage est une classe qui contient une variable qui est un type de données primitives, et qui enveloppe la primitive pour fournir une fonctionnalité d’interaction avec elle. En fait, on peut dire qu’il transforme le primitif en objet. Ce qui est utile, par exemple, lorsqu’une méthode vise au transfert d’un objet. Le candidat doit être capable de nommer au moins deux des paires suivantes :
Primitive
Classe d'emballage
boolean
Boolean
byte
Byte
char
Char
double
Double
float
Float
int
Int
long
Long
short
Short
Mauvaise réponse
Les classes d’emballage sont définies en java.lang, et requises car il existe de nombreuses classes qui supportent uniquement les objets. Le fait de ne pas connaître ces classes d’emballage, ou de ne pas savoir pourquoi elles seraient utilisées, apparaît comme une grave lacune de la part du candidat interrogé.
Définissez les termes suivants qui sont courants dans la programmation java
Classe abstraite
Ramasse-miettes (aussi appelé récupérateur de mémoire, glaneur de cellules ou garbage collector)
Autoboxing
Sérialisation
Justification
Cette liste inclut des termes qui sont communément utilisés en Java, ainsi que dans d’autres langages de programmation. Les questions d’entretien pour les programmeurs expérimentés incluent de telles définitions parce qu’elles permettent de tester leurs connaissances de manière approfondie, ainsi que leur capacité à distinguer des langages comportant des concepts proches sans être parfaitement identiques.
Bonne réponse
Une classe abstraite est utilisée comme classe de base pour les sous-classes qui vont étendre ou écraser ses méthodes. Prenons l’exemple d’une classe « Forme ». Une forme peut contenir un certain nombre de côtés, de faces ou même de dimensions. Prise isolément, savoir que cette classe est une « Forme » est peu utile. D’autre part, si cette classe abstraite sera utilisée comme classe de base pour un « Carré », un « Triangle », ou un autre type de polygone, elle deviendra utile quand placée au sommet de la hiérarchie des classes. - Il n'est pas possible d'instancier une classe abstraite. – Elle peut contenir des méthodes abstraites, mais ce n’est pas obligatoire. - Les sous-classes de la classe d'abstraction doivent mettre en œuvre toutes les méthodes d'abstraction, à moins qu'il ne s'agisse également d'une classe d'abstraction. Il n'est pas possible d'instancier une classe abstraite.
Ne pas être parfaitement calé à propos classes abstraites n’est pas éliminatoire, bien que ces dernières seront très probablement rencontrées par le programmeur Java lorsqu’il devra effectuer des actions de maintenance ou du débogage d’une base de code existante.
La "garbage collection" (effectuée par le "garbage collector" ou ramasse-miettes) est le processus de détection et de suppression des objets en mémoire qui ne sont plus utilisés ou référencés. En java, le ramassage des miettes est automatique, mais il peut aussi être demandé.
Les commandes System.gc() et Runtime.gc() indiqueront au ramasse-miettes qu’il doit s’exécuter, bien que cela ne soit pas garanti.
Les fils d’exécution sont mis en pause pendant le ramassage des ordures. Cela ralentit nécessairement l’exécution, ce qui signifie que dans les applications réactives, le ramassage des miettes doit être réduit au minimum. La connaissance du ramasseur de miettes n’est pas indispensable, surtout pour un programmeur débutant. Il est à noter, cependant, que lorsqu’on vient d’un langage comme C, où toute la mémoire est gérée manuellement, le développeur doit être au courant de l’existence de cette fonctionnalité.
L’Autoboxing est l’emballage automatique d’un type primitif (voir la question #4 relative aux types primitifs et classes d’emballages). Par exemple, l’autoboxing convertira automatiquement un nombre de type float (type primitif) en Float (classe d’emballage). Le contraire de cela est le déballage, lors duquel type primitif est extrait de la classe d’emballage. Cette notion est habituellement familière aux bons développeurs Java.
La sérialisation fait référence à l’encodage d’objets en mémoire dans un flux d’octets qui pouvant être facilement stockés ou transmis. Le contraire est la désérialisation, qui reconstruit les objets à partir d’un flux d’octets. Il existe différentes approches pour réaliser la sérialisation. Deux méthodes courantes sont la conversion de l’objet en XML (eXtensible Markup Language), ou JSON (JavaScript Object Notation). Ce sont des types de fichiers bien connus, chacun d’entre eux étant largement pris en charge. Java supporte également la sérialisation comme partie intégrante du langage. Le langage inclut l’interface sérialisable, qui peut être utilisée à la fois pour la sérialisation et la désérialisation. La méthode writeObject() est utilisée pour encoder les données, tandis que la méthode readObject() est utilisée pour reconstruire les objets.
Java définit une classe String pour représenter des tableaux de caractères. Répondez aux questions suivantes :
Un constructeur initialise un objet lors de sa création. Cependant, les constructeurs n'ont pas de type de retour explicite.
En général, vous utiliserez un constructeur pour donner des valeurs initiales aux variables d'instance définies par la classe, ou pour effectuer toute autre procédure de démarrage nécessaire pour créer un objet entièrement formé.
Toutes les classes ont des constructeurs, que vous en définissiez un ou non, car Java fournit automatiquement un constructeur par défaut qui initialise toutes les variables membres à zéro. Cependant, une fois que vous avez défini votre propre constructeur, le constructeur par défaut n'est plus utilisé.
Pourriez-vous citer quelques cadres de travail Java ?
Cette question d'entretien est une question de base : tout développeur Java compétent est en mesure de nommer quelques frameworks écrits en langage Java. Au cours de l'entretien, le candidat interrogé doit mentionner au moins trois frameworks Java parmi cette liste :
JSF (Java Server Faces), un cadre web Java qui facilite la construction d'interfaces utilisateur pour les applications basées sur des serveurs
GWT (Google Web Toolkit), un ensemble d'outils open-source qui aide les programmeurs à créer et à maintenir des applications JavaScript dans Java Spring, un framework Java qui n'impose aucun modèle de programmation spécifique
Struts
Hiberner
Grails
Jouez !
Vaadin
Maven
Questions d'entretien sur la programmation mixte
Java définit une classe String pour représenter des tableaux de caractères. Répondez aux questions suivantes :
- Par quoi faut-il remplacer le "XXX" pour pouvoir comparer les deux principaux arcs de cordes ? Si les arguments sont : "Sun Microsystems" et "Sun microsystems", quel sera le résultat de l'exécution ? Y a-t-il un moyen de garantir qu'il les déclarera comme étant identiques ? - Si les arguments sont plutôt : "Sun Microsystems" et "Sun Microsystems", quel sera le résultat de l'exécution ? "Sun Microsystem" et "Sun Microsystems", quel sera le résultat de l'exécution ?
1/ Après la création d'une chaîne, est-il possible de la modifier ? Considérez ce qui suit :
public static void main(String[] args) { String name = "James gosling"; // I want to change the 'g' to a 'G'. // Will this work at compile time? name.charAt(6) = 'G'; // Print with the standard system println to see “James Gosling” System.out.println(name); }
Cela va-t-il fonctionner ? Si ce n'est pas le cas, quelles modifications faudrait-il apporter pour obtenir la chaîne souhaitée ?
2/ La classe String a plus d'un Comparateur. Considérez le code suivant :
public static void main(String[] args) { // This program received 2 arguments. We want to // determine if those two strings are equal. // Compare the first argument to the second argument boolean compareResult = (XXX); if (compareResult) { System.out.println("The Strings are the same."); } else { System.out.println("The Strings are not the same."); } // Print the main string args System.out.println(args[0]); System.out.println(args[1]); }
- Par quoi faut-il remplacer le "XXX" pour pouvoir comparer les deux principaux arcs de cordes ? Si les arguments sont : "Sun Microsystems" et "Sun microsystems", quel sera le résultat de l'exécution ? Y a-t-il un moyen de garantir qu'il les déclarera comme étant identiques ? - Si les arguments sont plutôt : "Sun Microsystems" et "Sun Microsystems", quel sera le résultat de l'exécution ? "Sun Microsystem" et "Sun Microsystems", quel sera le résultat de l'exécution ?
3/ Qu'est-ce que le pool de constantes de la chaîne Java ? (ou pool de chaînes de caractères Java) ? Il réside dans la mémoire de la pile ?
Justification
L'utilisation de représentations de chaînes de caractères est courante dans de nombreux langages, et Java ne fait pas exception. Il est important de comprendre comment les chaînes de caractères sont créées, analysées, imprimées et manipulées. C'est un sujet important qui constitue une question d'entretien importante pour les développeurs Java.
Bonne réponse
Non, cela échouera au moment de la compilation car il n'est pas possible de modifier une chaîne une fois qu'elle a été initialisée. Cette propriété est dite immuable. Pour que cela fonctionne, il faudrait recréer la chaîne contenant "James gosling". Une approche consiste à utiliser un tableau de caractères intermédiaires (en appelant la méthode toCharArray() sur le "nom"), à remplacer le "g" par la lettre majuscule, puis à recréer la chaîne avant de l'imprimer. Un bonus pour le candidat qui souligne que la fonction string replace(...) existe pour remplacer les caractères, mais ne peut pas être utilisée car toutes les instances de "g" minuscules seraient remplacées.
Le comparateur exact dans cet exemple est soit égal(...) soit égalIgnoreCase(...). Le type de retour de ces deux méthodes est une valeur booléenne. Si la personne interrogée répond compareTo(...) ou compareToIgnoreCase(...), alors le crédit devrait être accordé, bien que le type de retour de ces méthodes soit un int, donc techniquement incorrect. Il n'en reste pas moins qu'elle démontre une connaissance de la langue.
Dans le premier exemple, les chaînes sont identiques sous equalsIgnoreCase(...), mais différentes sous equals(...). Dans le deuxième exemple, il y a un "s" à la fin, ce qui fait que les chaînes sont différentes dans tous les cas.
Le Java Constant String Pool est une zone de la mémoire du Heap (donc, pas de la mémoire de la pile) où sont stockées les chaînes de caractères. Cette approche est à l'origine de la raison pour laquelle les chaînes sont immuables en java.
Par exemple :
chaîne x = "chaîne principale" ;
chaîne de caractères y = "machine virtuelle" ;
chaîne z = "chaîne principale" ;
Les trois cordes ci-dessus sont stockées dans le pool de cordes, mais la partie intéressante est l'efficacité. x et y pointent tous deux vers la même zone dans la réserve de cordes, ce qui ne nécessite pas de duplication de l'espace. Sachant cela, il doit être clair que la modification de la valeur de x n'est pas autorisée car elle aurait l'effet secondaire non voulu de modifier z.
Quelles sont les différences entre la mémoire Stack et l'espace Heap ?
Justification
Afin d'améliorer l'efficacité, la JVM organise la mémoire pour que les applications puissent s'exécuter. Elle crée de l'espace de pile et de l'espace de tas, chacun étant utilisé par des opérations différentes. Comprendre l'allocation de la mémoire à ce niveau peut conduire à un ramassage des déchets plus prévisible et, en fin de compte, à une efficacité accrue.
Bonne réponse
La mémoire en pile est utilisée pour l'allocation de mémoire statique, comme les valeurs primitives à l'intérieur d'une méthode. Elle est toujours utilisée pour l'exécution d'un thread. La pile s'agrandit lorsque les méthodes sont appelées, et se réduit lorsqu'elles reviennent. Si la mémoire allouée pour la pile est dépassée, l'exception java.lang.StackOverFlowError est lancée.
La mémoire de tas est utilisée pour l'allocation de mémoire dynamique, comme les objets java. Plus précisément, l'objet est stocké dans le tas, tandis que la référence à l'objet est stockée dans la pile. Les classes JRE sont également stockées dans le tas au moment de l'exécution. L'accès aux données dans le tas est plus lent que dans la mémoire de la pile. Le tas requiert l'action du collecteur de déchets afin de libérer les objets inutilisés. Si la mémoire allouée au tas est dépassée, l'exception java.lang.OutOfMemoryError est lancée.
Mauvaise réponse
Le fait de n'avoir jamais entendu parler de la pile ou du tas indiquerait une connaissance superficielle du langage de programmation java. De plus, la terminologie est typique d'une culture générale de programmation. Le diagnostic des erreurs liées à la mémoire, telles qu'un débordement de pile causé par un comportement incorrect d'une fonction récursive, serait plus facile avec cette compréhension.
Deux termes liés à la classe utilisés dans la programmation java sont "subclass" et "nested class". Expliquez les différences entre ces deux termes. Pourquoi choisir l'une plutôt que l'autre ? Laquelle est parfois appelée "classe intérieure" ?
Justification
Dans la conception orientée objet, il y a souvent une confusion sur le placement des classes dans la hiérarchie. Les classes imbriquées sont relativement rares par rapport aux sous-classes, mais leur utilisation est bénéfique dans de nombreuses situations. La connaissance de leur existence et de leur mode d'utilisation doit être considérée comme un atout.
Bonne réponse
Une sous-classe est une extension d'une autre classe, et est souvent une spécialisation de l'original. Les sous-classes héritent des membres publics et protégés de leur super-classe. Les sous-classes peuvent être instanciées indépendamment de la superclasse, et en fait, c'est toujours le cas lorsque la superclasse est une classe abstraite.
Une classe imbriquée est une classe à l'intérieur d'une classe, qui dans certains cas est une classe intérieure. Le champ d'application de la classe intérieure comprend tous les membres de sa classe extérieure, ce qui lui donne accès à ces variables et méthodes. Comme le corps existe entièrement au sein de la classe englobante, il ne peut pas être instancié indépendamment, sans elle.
L'utilisation d'une classe interne peut améliorer la conception orientée objet en organisant davantage le code. L'objectif est limité dans la mesure où il existe pour servir sa classe englobante. Si la classe interne offre des fonctionnalités utiles à une plus grande échelle, il serait plus logique de l'avoir comme classe de haut niveau. Les classes internes sont couramment utilisées comme fonctions de rappel pour les composants de l'interface graphique.
Bonus
Il existe deux types de classes imbriquées. Plus précisément, il existe une classe imbriquée statique, qui n'a pas directement accès aux autres membres de la classe englobante. Celles-ci ne sont pas souvent utilisées, c'est pourquoi le fait de les connaître est un bonus par opposition à l'ignorance qui peut entraîner une pénalité. L'autre type est une classe imbriquée non statique, qui est la version que l'on appelle une classe intérieure. Ceux-ci ont en effet accès à tous les membres de la classe englobante, y compris aux méthodes privées.
Mauvaise réponse
Le candidat doit être pardonné de n'avoir jamais utilisé une classe imbriquée. Bien qu'utile, et susceptible d'être vu si l'on maintient une base de code existante, le concept est simple. Les classes imbriquées rendent souvent le code plus élégant et plus facile à maintenir, mais certains concepteurs considèrent que c'est une question de style. Les sous-classes, d'autre part, sont un élément fondamental de la programmation orientée objet que tout développeur java devrait connaître. Ne pas pouvoir discuter facilement des sous-classes au sein d'une hiérarchie de classes est un sérieux signal d'alarme.
Deux classes de collection sont disponibles en programmation java : Array et List. En quoi les méthodes diffèrent-elles entre ces deux objets conteneurs, et dans quelles circonstances choisiriez-vous l'une plutôt que l'autre ?
Justification
L'utilisation de conteneurs est courante en Java et dans d'autres langages de programmation. La liste est une structure de données dynamique, tandis que le tableau est statique. Il est important de reconnaître que chacun d'entre eux est mieux adapté à certaines applications, et à ce titre, le candidat doit les connaître. Avoir une connaissance approfondie des types de données et des classes de conteneurs disponibles permettra en fin de compte de gagner du temps de développement.
Bonne réponse
Array
Les tableaux sont de taille statique, ils ne peuvent donc ni croître ni diminuer en termes de nombre d'éléments. Cela signifie qu'il existe des méthodes pour accéder aux éléments et les modifier, mais pas pour les insérer ou les supprimer.
Java fournit des méthodes pour effectuer une recherche binaire ou un tri sur un tableau. De plus, un tableau peut être initialisé en utilisant la méthode fill(), ou comparé en utilisant le comparateur equals().
La taille d'un tableau est fixée lors de sa création.
L'accès aléatoire d'un élément dans un tableau est très efficace.
Les tableaux sont plus adaptés à des collections d'éléments de longueur fixe.
Tous les éléments sont du même type, par exemple :
int[] interviewArray = new int[5];
or
int[] arrayForInterview = {3, 1, 4, 1, 5};
Ces deux tableaux contiennent cinq entiers.
Vecteur
Les candidats doivent savoir quand il est approprié et possible d'utiliser ces mots clés. En particulier, ils doivent savoir que l'asynchronisation ne peut être placée avant le mot-clé de fonction sur une définition de fonction. La fonction est alors considérée comme un retour de promesse. Le mot-clé "await" ne peut être utilisé qu'à l'intérieur d'une telle fonction asynchrone et doit être placé avant un appel à une fonction qui rendra une Promesse.
Les éléments d'une liste peuvent être ajoutés ou supprimés, ce qui signifie que la taille de la liste peut changer. Les méthodes permettent de nombreux types de manipulations, y compris l'insertion ou la suppression dans un index spécifique. Les plages peuvent également être manipulées.
La Liste est une interface, donc quand on manipule une Liste, une vraie classe, généralement ArrayList, est utilisée en coulisse
Une liste repose sur les méthodes de tri de Collections, telles que Collections.sort().
Les méthodes de recherche contain(), indexOf(), et lastIndexOf() sont des exemples qui peuvent être utilisés pour rechercher les éléments. Cependant, pour effectuer une recherche binaire, il faut appeler la méthode plus générale : Collections.binarySearch(...)
Les listes peuvent contenir des objets de type mixte, par exemple :
List interviewList = new ArrayList();
interviewList.add(3);
interviewList.add(1415);
interviewList.add(“Pi”);
Bonus
Les tableaux peuvent stocker des objets, il existe donc une solution de rechange pour ceux qui sont enclins à mélanger les types dans un tableau. De plus, le candidat doit être crédité de savoir que les Listes remplacent les Vecteurs qui ne sont plus couramment utilisés en Java. La raison est liée à la simultanéité et à la synchronisation des opérations. Il est clair qu'une explication plus détaillée dépasse la portée de cette question - cependant, la mention de ce point est digne d'intérêt.
Mauvaise réponse
Les tableaux et les listes, parmi d'autres classes et interfaces intégrées, y compris les collections, sont très courants dans la programmation Java et le développement d'applications. Un candidat qui n'est pas à l'aise avec ces fonctionnalités manque presque certainement d'expérience avec le langage.
Contrairement au C++, Java ne prend pas en charge l'héritage multiple. Comment la programmation avec une interface apportera-t-elle une réponse à ce problème ? Une interface fait-elle partie de la hiérarchie des classes ?
Justification
S'il existe des points communs entre les langues que de nombreux programmeurs connaissent bien, il existe aussi des distinctions qui permettent de les définir. Dans un entretien en Java, il y aura des questions de base en Java qui aideront à évaluer dans quelle mesure le candidat connaît les spécificités du langage de programmation Java. Étant donné la question du problème du diamant en C++, il est intéressant de tester les connaissances du candidat dans une perspective java.
Bonne réponse
Une interface est similaire à une classe en ce sens qu'elle peut contenir différents types de méthodes, mais différente parce qu'elle ne détient pas l'état. Les interfaces sont intrinsèquement abstraites, et leurs méthodes doivent être implémentées par une classe. L'interface n'est pas instanciée, elle est implémentée. Contrairement au C++, une classe ne peut étendre qu'un seul parent (c'est-à-dire qu'elle ne peut avoir qu'une seule superclasse). Une interface, en revanche, est capable d'étendre plus d'une interface parent. Par exemple :
public interface CheckerBoard {
public void setSize(int rowCount, int columnCount);
}
public interface Game {
public void setNumberOfPlayers();
public void play();
}
public interface ChessGame extends CheckerBoard, Game {}
Dans cet exemple, l'interface ChessGame hérite à la fois de CheckerBoard et de Game.
Mauvaise réponse
Si la personne interrogée ne sait pas ce qu'est l'héritage multiple, cela suggère un manque d'expérience en matière de conception orientée objet. Cela n'est pas essentiel pour toutes les applications, bien qu'il soit important de reconnaître que java est intrinsèquement OO.
Qu'est-ce que la machine virtuelle Java ? Quel en est l'objectif principal et avec quel type de code fonctionne-t-elle ?
Justification
Aucune interview en Java ne serait complète sans une question sur le thème de la machine virtuelle. La JVM est un élément clé de Java, et les programmeurs java l'apprennent très tôt. Si la JVM est capable d'exécuter du bytecode généré par d'autres langages, tels que JRuby et Jython, cela n'enlève rien au fait qu'elle est essentielle à la java elle-même.
Bonne réponse
La JVM est une machine virtuelle qui permet à l'ordinateur d'exécuter des programmes Java qui ont été compilés en bytecode. Le bytecode est indépendant de la plateforme, et s'exécute sur tout ordinateur qui héberge une JVM. Il comprend un compilateur juste à temps (JIT) qui convertit le bytecode en instructions en langage machine, permettant aux applications de s'exécuter aussi rapidement qu'un exécutable natif.
Mauvaise réponse
La JVM est l'un des principaux composants qui font de Java ce qu'il est. Le fait de ne pas connaître la JVM indique probablement un manque d'expérience avec le langage.
Quelles sont les méthodes et les classes finales ? Une classe abstraite supportera-t-elle les méthodes finales ?
Justification
Le dernier mot-clé est commun et doit être bien compris par les programmeurs java. Au cours de la phase de conception OO, il est normalement décidé si les classes doivent être extensibles. Si ce n'est pas le cas, elles sont marquées comme finales afin de limiter les effets secondaires potentiels de sous-classes qui n'ont pas été envisagées. Il s'agit d'une caractéristique importante qui devrait être utilisée pour un code plus robuste et plus facile à maintenir.
Bonne réponse
Une méthode qui est déclarée avec le mot-clé final ne peut pas être annulée dans les sous-classes. Cette méthode est utilisée dans les hiérarchies où la mise en œuvre de la méthode doit être cohérente dans l'ensemble. La déclaration finale d'une classe interdit totalement le sous-classement. Oui, il est possible d'inclure des méthodes finales dans une classe abstraite. Cela permet de s'assurer que les sous-classes ne peuvent pas passer outre la méthode.
Mauvaise réponse
Si le candidat n'est pas familier avec le mot-clé final, qu'il soit utilisé au niveau de la classe ou de la méthode, alors cela suggère une relative inexpérience de la langue. Même pour les programmeurs inexpérimentés qui ont participé à la conception orientée objet, le concept de classe finale devrait être familier.
La programmation Java permet de créer un fil de discussion de différentes manières. Quelles sont-elles et quelle est la méthode préférée ? Expliquez.
Justification
Contrairement au C++, java contient un support intégré pour le multithreading. C'est une fonctionnalité riche et puissante qui est à la fois pertinente et utile dans de nombreuses applications. En tant que tel, le candidat doit être familier avec les bases.
Bonne réponse
Que se passe-t-il dans le cas où la réduction est appelée sur un tableau vide sans fournir la valeur initiale facultative de l'accumulateur ?
public class JavaInterviewClass implements Runnable {
public void run() {
System.out.println(“My example public class prints this line from a thread.”);
}
}
Pour exécuter la méthode run(), passez une instance de la classe dans un Thread, comme suit :
Thread interviewThread = new Thread(new JavaInterviewClass ());
interviewThread.start();
La deuxième façon de créer un fil de discussion est d'étendre la classe de fil de discussion. La sous-classe remplacera la méthode run(). Après cela, il suffit de créer une instance de la classe.
public class JavaInterviewClass extends Thread {
public void run() {
System.out.println(“My example public class extends the Thread class.”);
}
}
Pour exécuter le fil de discussion, il suffit d'instancier la classe et d'appeler start(), comme suit :
JavaInterviewClass myInterview = new JavaInterviewClass (); myInterview.start();
Bonus
Bien que l'implémentation de l'interface exécutable et l'extension de la classe Thread soient deux moyens populaires de créer un thread, il est également possible d'utiliser le framework Executor. Celui-ci permet de travailler directement avec les threads, mais il est moins connu. Il comprend des méthodes telles que newSingleThreadExecutor(), newFixedThreadPool() et submit() pour créer des tâches d'exécution. La connaissance de l'utilisation du framework Executor implique que le candidat soit très à l'aise avec la création et l'utilisation de threads en java.
Mauvaise réponse
Si le candidat n'est pas à l'aise avec l'utilisation des fils de discussion, il passe à côté d'une caractéristique puissante et importante de la langue. C'est important car comprendre le multithreading ne se limite pas à rechercher la syntaxe de quelques commandes. Il s'agit plutôt d'une approche qui doit être envisagée lors de la conception et du développement d'une application.
Le code Java a un support intégré pour la concurrence dans sa classe Thread. La simultanéité a son propre ensemble de problèmes tels que l'impasse et les conditions de course. Décrivez brièvement les variables Atomic en Java et leur utilisation. Ensuite, il est indiqué que la méthode start() est utilisée pour créer une pile d'appels séparée avant que la méthode run() ne soit utilisée pour exécuter un thread. Que font les méthodes yield(), sleep() et join() ?
Justification
La prise en charge du multithreading par Java peut entraîner des problèmes liés à la concurrence. Les connaissances du candidat concernant ces problèmes doivent être évaluées et prises en compte.
Bonne réponse
Une variable atomique est une variable "mise à jour atomique", ce qui signifie que l'intégrité des données est assurée par l'utilisation d'algorithmes non bloquants. Cette fonctionnalité est généralement mise en œuvre au niveau du code machine. Java prend en charge plusieurs variables atomiques, le plus souvent AtomicBoolean, AtomicInteger, AtomicLong et AtomicReference. Il existe également plusieurs méthodes qui permettent de récupérer et de modifier ces variables, notamment get(), set(), lazySet(), compareAndSet() et weakCompareAndSet(). Utilisées correctement, les variables atomiques peuvent être utilisées pour mettre en œuvre des méthodes "thread safe" (multithreading safe) qui traitent efficacement certains problèmes liés à la concurrence.
rendement() : Cette méthode informe l'environnement que le fil de discussion actuel n'est pas en train d'achever une tâche de haute priorité, et est prêt à en interrompre l'exécution. À condition que l'environnement sous-jacent supporte l'ordonnancement préventif, elle suspendra le fil s'il y en a un autre qui doit s'exécuter. S'il n'y a pas de deuxième fil, ou si le deuxième fil se termine, le fil en cours reprendra le contrôle et continuera à s'exécuter.
sommeil() : Cette méthode fait dormir le fil courant, ou met en pause son exécution, pendant un nombre de millisecondes déterminé. Il est également possible de combiner un certain nombre de millisecondes et de nanosecondes. Pendant que le fil courant est en sommeil, un autre fil sera exécuté, ou sinon le CPU restera inactif. Sous réserve de la précision de l'horloge du système et des minuteurs, le fil de discussion reprendra le contrôle une fois le compte à rebours terminé.
join() : Cette méthode est utilisée pour joindre deux l'exécution de deux fils ensemble. Pour clarifier, si le fil A appelle join() sur le fil B, alors A commencera à attendre. Une fois que B a terminé, ou qu'un délai prédéfini a expiré, A reprendra le contrôle et continuera l'exécution.
Mauvaise réponse
Le fait de connaître les fils de discussion Java, mais de ne pas être conscient des problèmes liés à la concurrence peut entraîner de graves erreurs. La majorité des appareils, des ordinateurs de bureau aux appareils mobiles en passant par les ordinateurs à carte unique, prennent désormais généralement en charge le multithreading et la concurrence. Il est important de comprendre la bonne utilisation des threads, et d'être conscient des méthodes fournies par java pour les prendre en charge.
Conclusion
Les questions de cet article sont utiles pour évaluer les compétences d'un futur programmeur Java. En ce qui concerne les questions d'entretien à préparer pour un développeur Java, il est important de se rappeler que les spécificités du langage peuvent être facilement référencées en utilisant l'aide et la documentation en ligne. Les points subtils d'un langage ne sont pas aussi importants que la façon dont on applique la logique. Cela dit, les candidats à ce poste sont censés connaître le langage et ne pas avoir besoin d'une formation approfondie avant que le travail réel ne commence. Les compétences requises seront dictées par le travail à effectuer, et la variation des questions données ci-dessus aidera à faire cette évaluation. N'oubliez pas que l'une des meilleures façons d'évaluer les compétences du candidat pour votre projet est d'effectuer une évaluation pratique de la programmation, ce qui est bien plus efficace que des questions d'entretien orales pour engager un programmeur Java hautement qualifié.
Questions d’entretien pour recruter un développeur Java
Généralement, lorsque l’on parle de préparation pour l’entretien d’embauche d’un développeur Java, l’accent est mis sur le point de vue de la personne recrutée. Les candidats veulent savoir à quels types de questions ils doivent s’attendre afin de se préparer au mieux. Pourtant, en prenant un angle différent, on peut se demander : quelles questions un recruteur à la recherche d’un développeur Java doit-il poser aux candidats afin d’évaluer au mieux leurs compétences techniques ?
Dans une entreprise développant des logiciels, que le langage de programmation Java ou la programmation orientée objet en général soit un standard ou non, il est facile de trouver des questions de programmation et leurs réponses. Il est chose aisée d’utiliser Google pour rechercher la syntaxe du langage en question afin de faciliter la rédaction d’un entretien d’embauche sur Java.
Avant de commencer, voici une définition rapide du terme Java qui devrait vous aider si ce langage ne vous est pas entièrement familier :
Java is a high-level programming language developed by Sun Microsystems. It was originally designed for developing programs for set-top boxes and handheld devices, but later became a popular choice for creating web applications.
The Java syntax is similar to C++, but is strictly an object-oriented programming language. For example, most Java programs contain classes, which are used to define objects, and methods, which are assigned to individual classes. Java is also known for being more strict than C++, meaning variables and functions must be explicitly defined. This means Java source code may produce errors or “exceptions” more easily than other languages, but it also limits other types of errors that may be caused by undefined variables or unassigned types.
Christensson, P., Définition Java, techterms.com
Le but de cet article est d’aider à préparer le recruteur, quelle que soit son expérience avec Java. Déterminer quel candidat parmi tant d’autres a offert la meilleure performance lors d’un entretien sur Java n’est pas une tâche facile lorsque l’on ne dispose pas de compétences avancées en programmation. Dans le même temps, il faut savoir que ce candidat parfait ne sera pas trouvé à l’aide de questions d’entretien purement liées au code. La programmation est souvent une question de logique, par opposition à la syntaxe, et ce serait une grave erreur de pénaliser trop lourdement les candidats parce qu’ils ne sont pas familiers avec une problématique pouvant être aisément solutionnée à l’aide de Google.
Cela dit, il est important de se rappeler que l’entretien doit aboutir à un poste de développeur Java. Le candidat doit connaître l’environnement d’exécution Java (JRE), la machine virtuelle Java (JVM) et le kit de développement Java (JDK), etc. Les bibliothèques couramment utilisées telles que java lang, java util ne devrait pas être un mystère pour eux. De même, alors qu’elle n’est plus utilisée, la bibliothèque Swingdevrait au moins leur être familière (alors qu’il est acceptable de ne pas connaître la bibliothèque Awt, qui est totalement obsolète. Enfin, les candidats doivent au moins être au courant de l’existence de frameworks et d’autres technologies tels que Spring framework, JavaServer Pages (JSP), et Java Database Connectivity (JDBC).
Les questions d'entretien Java doivent être spécifiques à certains égards, mais générales à d'autres. Par exemple, est-il nécessaire d'inclure des questions d'entretien JDBC spécifiques ? Peu probable. Cependant, un candidat doit absolument savoir ce qu'est une interface de la Liste.
Avec autant d'objectifs concurrents, comment trouver le candidat idéal ? La réponse réside dans un large éventail de questions d'entretien qui couvrent le sujet sous plus d'un angle. Cet article vise à répondre à ces préoccupations en fournissant la question d'entretien de Java, la ou les réponses correctes, et la raison pour laquelle chaque question est posée.
Consultez la question Java ci-dessous. Il existe plusieurs façons de la résoudre, de sorte que les choix du candidat peuvent révéler sa façon de coder. Comment la résoudriez-vous ? Cliquez sur l'onglet "Instructions" et essayez :
Questions de programmation de différents niveaux et leurs réponses
Cet article contient 14 questions d’entretien et leurs réponses. Les 5 premières sont niveau débutant, tandis que les autres varient à la fois en termes de sujet et de niveau de difficulté. Un score parfait ne sera pas nécessairement obtenu en répondant à chaque question parfaitement. Au contraire, la discussion sur les solutions donnera le meilleur indicateur à la fois de la capacité de réflexion du candidat et de l’expérience qu’il a accumulée.
Questions de programmation Java niveau débutant
1 - Le code Java prévoit des méthodes de classe avec des spécificateurs d'accès public et privé. Quelle est la différence entre ces deux modificateurs ?
Justification
Dans la programmation orientée objet, il est courant de limiter la portée des variables et des fonctions à des classes spécifiques dans une hiérarchie de classes. Ceci est réalisé à l’aide de différents spécificateurs d’accès, et connaître la différence entre ces composants fondamentaux est une question d’entretien Java très pertinente.
En Java, les classes peuvent être uniquement déclarées publiques, ou bien pas du tout – alors que les fonctions membres ont quatre modificateurs différents – c’est donc un sujet qui peut s’avérer épineux pour les grands débutants.
Bonne réponse
Un spécificateur d’accès public ordonne que la méthode soit accessible à la fois à l’intérieur et à l’extérieur de la classe. Ceci est vrai tant que la classe elle-même est déclarée publique, ou que la classe appelante est dans le même package. Si la classe ne spécifie pas de modificateur, elle est supposée avoir un accès par défaut (package), et les déclarations de ses méthodes ne l’écrasent pas.
Un spécificateur d’accès privé indique que la méthode doit être accessible uniquement à l’intérieur de la classe.
Bonus
Si le candidat sait qu'il existe également des spécifications pour les produits protégés et les emballages (par défaut), il démontre alors une bonne compréhension de ce sujet.
Mauvaise réponse
Si le candidat ne connaît pas la différence entre public et private, cela indique un manque d’expérience à propos de Java et probablement dans d’autres langages orientés objet tels que C++. Si la réponse est correcte, mais qu’il n’est pas fait mention du fait que le modificateur de classe l’emporte sur les méthodes, le candidat devrait être pénalisé.
Considérons le code suivant qui contient une classe, une variable statique et une méthode publique. Combien de bouchées ont été prises pour chaque pomme ?
public class Apple {
static int bites = 0;
public void takeBite() {
bites++;
}
public static void main(String[] args) {
// Instantiate red and green apples for our example public class
Apple macintosh = new Apple();
Apple grannySmith = new Apple();
// Take a bite out of each of the two apples
macintosh.takeBite();
grannySmith.takeBite();
// Display the contents of each class
System.out.println("The Macintosh apple has " + macintosh.bites + " bite(s) out of it.");
System.out.println("The Granny Smith apple has " + grannySmith.bites + " bite(s) out of it.");
}
}
Justification
Les variables statiques sont une caractéristique de Java régulièrement utilisée par les développeurs. Comme c’est le cas pour les variables globales, il est important pour les programmeurs de comprendre la portée de ces objets afin d’éviter un quelconque effet collatéral. Note à propos de la non-déclaration d’une variable : cela permet d’éviter de mal taper le nom d’une variable, car la variable mal orthographiée apparaîtra comme une nouvelle variable non déclarée.
Bonne réponse
La classe Apple partage la variable statique, bites, entre toutes ses instances. Par conséquent, lorsque la méthode takeBite() est appelée sur chacune des instances, la variable commune est mise à jour. Le résultat final se présente ainsi :
The Macintosh apple has 2 bite(s) out of it.
The Granny Smith apple has 2 bite(s) out of it.
Mauvaise réponse
Si le candidat répond que chacune des deux instances s’est vue retirée une seule bouchée (bite), cela indique un manque d’expérience avec les variables statiques. Ce sujet est trivial, mais un développeur Java le rencontrera fréquemment. Le fait de ne pas en avoir connaissance indique que le candidat manque probablement d’expérience pratique du langage.
Qu'est-ce qu'une exception ? Décrivez brièvement les deux types d'exception utilisés dans le code java.
Justification
Les exceptions sont des événements inattendus qui surviennent au moment de l’exécution et qui diffèrent des erreurs dans la mesure où il est généralement aisé de les « rattraper ». Les erreurs, par contre, indiquent généralement un problème plus grave. La gestion des exceptions est très courante et doit être comprise, au moins à un niveau de base, par n’importe quel programmeur Java.
Bonne réponse
Les deux types d’exceptions dans Java sont les exceptions vérifiées et les exceptions non-vérifiées.
Une exception vérifiée est une exception qui est vérifiée au moment de la compilation. Lorsqu’il y a du code dans une méthode qui lève une exception vérifiée, la méthode est nécessaire pour l’acquitter. Ceci peut être accompli soit en gérant l’exception avec un bloc try/catch, soit en la spécifiant à l’aide du mot-clé throws. Une exception non-vérifiée est une exception qui n’est pas vérifiée au moment de la compilation. C’est au programmeur de spécifier ce type d’exception. En revanche, il faut noter que toutes les exceptions en C++ sont non-vérifiées.
Bonus
En Java, toutes les exceptions des classes Error et RuntimeException sont décochées. Tout le reste sous Throwable est vérifié. Si la personne interrogée soulève ce point particulier, elle démontre une compréhension profonde de la question qui lui a été posée.
Mauvaise réponse
Si le candidat n’est pas au courant des exceptions, il lui manque une partie essentielle du langage qui est responsable du contrôle de l’exécution. Cette fonctionnalité représente un véritable bond en avant par rapport à des langages tels que C (qui ne supporte pas la gestion des exceptions). Bien qu’elles ne soient pas absolument indispensables, les exceptions sont extrêmement utiles au quotidien du fait de leurs nombreux avantages, tout développeur Java efficace les utilise.
Que sont les cours d'emballage ? Donnez des exemples de deux d'entre elles et des primitives correspondantes. Quel est le rapport entre chacune d'elles et un objet ?
Justification
Les classes d’emballage sont fondamentales en programmation Java. En fait, leur existence implique que java n’est pas 100% orienté objet (bonus au candidat qui le signale !). C’est le cas parce que Java contient 8 types de données primitives qui ne sont pas, par définition, des objets.
Bonne réponse
Une classe d’emballage est une classe qui contient une variable qui est un type de données primitives, et qui enveloppe la primitive pour fournir une fonctionnalité d’interaction avec elle. En fait, on peut dire qu’il transforme le primitif en objet. Ce qui est utile, par exemple, lorsqu’une méthode vise au transfert d’un objet. Le candidat doit être capable de nommer au moins deux des paires suivantes :
Primitive
Classe d'emballage
boolean
Boolean
byte
Byte
char
Char
double
Double
float
Float
int
Int
long
Long
short
Short
Mauvaise réponse
Les classes d’emballage sont définies en java.lang, et requises car il existe de nombreuses classes qui supportent uniquement les objets. Le fait de ne pas connaître ces classes d’emballage, ou de ne pas savoir pourquoi elles seraient utilisées, apparaît comme une grave lacune de la part du candidat interrogé.
Définissez les termes suivants qui sont courants dans la programmation java
Classe abstraite
Ramasse-miettes (aussi appelé récupérateur de mémoire, glaneur de cellules ou garbage collector)
Autoboxing
Sérialisation
Justification
Cette liste inclut des termes qui sont communément utilisés en Java, ainsi que dans d’autres langages de programmation. Les questions d’entretien pour les programmeurs expérimentés incluent de telles définitions parce qu’elles permettent de tester leurs connaissances de manière approfondie, ainsi que leur capacité à distinguer des langages comportant des concepts proches sans être parfaitement identiques.
Bonne réponse
Une classe abstraite est utilisée comme classe de base pour les sous-classes qui vont étendre ou écraser ses méthodes. Prenons l’exemple d’une classe « Forme ». Une forme peut contenir un certain nombre de côtés, de faces ou même de dimensions. Prise isolément, savoir que cette classe est une « Forme » est peu utile. D’autre part, si cette classe abstraite sera utilisée comme classe de base pour un « Carré », un « Triangle », ou un autre type de polygone, elle deviendra utile quand placée au sommet de la hiérarchie des classes. - Il n'est pas possible d'instancier une classe abstraite. – Elle peut contenir des méthodes abstraites, mais ce n’est pas obligatoire. - Les sous-classes de la classe d'abstraction doivent mettre en œuvre toutes les méthodes d'abstraction, à moins qu'il ne s'agisse également d'une classe d'abstraction. Il n'est pas possible d'instancier une classe abstraite.
Ne pas être parfaitement calé à propos classes abstraites n’est pas éliminatoire, bien que ces dernières seront très probablement rencontrées par le programmeur Java lorsqu’il devra effectuer des actions de maintenance ou du débogage d’une base de code existante.
La "garbage collection" (effectuée par le "garbage collector" ou ramasse-miettes) est le processus de détection et de suppression des objets en mémoire qui ne sont plus utilisés ou référencés. En java, le ramassage des miettes est automatique, mais il peut aussi être demandé.
Les commandes System.gc() et Runtime.gc() indiqueront au ramasse-miettes qu’il doit s’exécuter, bien que cela ne soit pas garanti.
Les fils d’exécution sont mis en pause pendant le ramassage des ordures. Cela ralentit nécessairement l’exécution, ce qui signifie que dans les applications réactives, le ramassage des miettes doit être réduit au minimum. La connaissance du ramasseur de miettes n’est pas indispensable, surtout pour un programmeur débutant. Il est à noter, cependant, que lorsqu’on vient d’un langage comme C, où toute la mémoire est gérée manuellement, le développeur doit être au courant de l’existence de cette fonctionnalité.
L’Autoboxing est l’emballage automatique d’un type primitif (voir la question #4 relative aux types primitifs et classes d’emballages). Par exemple, l’autoboxing convertira automatiquement un nombre de type float (type primitif) en Float (classe d’emballage). Le contraire de cela est le déballage, lors duquel type primitif est extrait de la classe d’emballage. Cette notion est habituellement familière aux bons développeurs Java.
La sérialisation fait référence à l’encodage d’objets en mémoire dans un flux d’octets qui pouvant être facilement stockés ou transmis. Le contraire est la désérialisation, qui reconstruit les objets à partir d’un flux d’octets. Il existe différentes approches pour réaliser la sérialisation. Deux méthodes courantes sont la conversion de l’objet en XML (eXtensible Markup Language), ou JSON (JavaScript Object Notation). Ce sont des types de fichiers bien connus, chacun d’entre eux étant largement pris en charge. Java supporte également la sérialisation comme partie intégrante du langage. Le langage inclut l’interface sérialisable, qui peut être utilisée à la fois pour la sérialisation et la désérialisation. La méthode writeObject() est utilisée pour encoder les données, tandis que la méthode readObject() est utilisée pour reconstruire les objets.
Java définit une classe String pour représenter des tableaux de caractères. Répondez aux questions suivantes :
Un constructeur initialise un objet lors de sa création. Cependant, les constructeurs n'ont pas de type de retour explicite.
En général, vous utiliserez un constructeur pour donner des valeurs initiales aux variables d'instance définies par la classe, ou pour effectuer toute autre procédure de démarrage nécessaire pour créer un objet entièrement formé.
Toutes les classes ont des constructeurs, que vous en définissiez un ou non, car Java fournit automatiquement un constructeur par défaut qui initialise toutes les variables membres à zéro. Cependant, une fois que vous avez défini votre propre constructeur, le constructeur par défaut n'est plus utilisé.
Pourriez-vous citer quelques cadres de travail Java ?
Cette question d'entretien est une question de base : tout développeur Java compétent est en mesure de nommer quelques frameworks écrits en langage Java. Au cours de l'entretien, le candidat interrogé doit mentionner au moins trois frameworks Java parmi cette liste :
JSF (Java Server Faces), un cadre web Java qui facilite la construction d'interfaces utilisateur pour les applications basées sur des serveurs
GWT (Google Web Toolkit), un ensemble d'outils open-source qui aide les programmeurs à créer et à maintenir des applications JavaScript dans Java Spring, un framework Java qui n'impose aucun modèle de programmation spécifique
Struts
Hiberner
Grails
Jouez !
Vaadin
Maven
Questions d'entretien sur la programmation mixte
Java définit une classe String pour représenter des tableaux de caractères. Répondez aux questions suivantes :
- Par quoi faut-il remplacer le "XXX" pour pouvoir comparer les deux principaux arcs de cordes ? Si les arguments sont : "Sun Microsystems" et "Sun microsystems", quel sera le résultat de l'exécution ? Y a-t-il un moyen de garantir qu'il les déclarera comme étant identiques ? - Si les arguments sont plutôt : "Sun Microsystems" et "Sun Microsystems", quel sera le résultat de l'exécution ? "Sun Microsystem" et "Sun Microsystems", quel sera le résultat de l'exécution ?
1/ Après la création d'une chaîne, est-il possible de la modifier ? Considérez ce qui suit :
public static void main(String[] args) { String name = "James gosling"; // I want to change the 'g' to a 'G'. // Will this work at compile time? name.charAt(6) = 'G'; // Print with the standard system println to see “James Gosling” System.out.println(name); }
Cela va-t-il fonctionner ? Si ce n'est pas le cas, quelles modifications faudrait-il apporter pour obtenir la chaîne souhaitée ?
2/ La classe String a plus d'un Comparateur. Considérez le code suivant :
public static void main(String[] args) { // This program received 2 arguments. We want to // determine if those two strings are equal. // Compare the first argument to the second argument boolean compareResult = (XXX); if (compareResult) { System.out.println("The Strings are the same."); } else { System.out.println("The Strings are not the same."); } // Print the main string args System.out.println(args[0]); System.out.println(args[1]); }
- Par quoi faut-il remplacer le "XXX" pour pouvoir comparer les deux principaux arcs de cordes ? Si les arguments sont : "Sun Microsystems" et "Sun microsystems", quel sera le résultat de l'exécution ? Y a-t-il un moyen de garantir qu'il les déclarera comme étant identiques ? - Si les arguments sont plutôt : "Sun Microsystems" et "Sun Microsystems", quel sera le résultat de l'exécution ? "Sun Microsystem" et "Sun Microsystems", quel sera le résultat de l'exécution ?
3/ Qu'est-ce que le pool de constantes de la chaîne Java ? (ou pool de chaînes de caractères Java) ? Il réside dans la mémoire de la pile ?
Justification
L'utilisation de représentations de chaînes de caractères est courante dans de nombreux langages, et Java ne fait pas exception. Il est important de comprendre comment les chaînes de caractères sont créées, analysées, imprimées et manipulées. C'est un sujet important qui constitue une question d'entretien importante pour les développeurs Java.
Bonne réponse
Non, cela échouera au moment de la compilation car il n'est pas possible de modifier une chaîne une fois qu'elle a été initialisée. Cette propriété est dite immuable. Pour que cela fonctionne, il faudrait recréer la chaîne contenant "James gosling". Une approche consiste à utiliser un tableau de caractères intermédiaires (en appelant la méthode toCharArray() sur le "nom"), à remplacer le "g" par la lettre majuscule, puis à recréer la chaîne avant de l'imprimer. Un bonus pour le candidat qui souligne que la fonction string replace(...) existe pour remplacer les caractères, mais ne peut pas être utilisée car toutes les instances de "g" minuscules seraient remplacées.
Le comparateur exact dans cet exemple est soit égal(...) soit égalIgnoreCase(...). Le type de retour de ces deux méthodes est une valeur booléenne. Si la personne interrogée répond compareTo(...) ou compareToIgnoreCase(...), alors le crédit devrait être accordé, bien que le type de retour de ces méthodes soit un int, donc techniquement incorrect. Il n'en reste pas moins qu'elle démontre une connaissance de la langue.
Dans le premier exemple, les chaînes sont identiques sous equalsIgnoreCase(...), mais différentes sous equals(...). Dans le deuxième exemple, il y a un "s" à la fin, ce qui fait que les chaînes sont différentes dans tous les cas.
Le Java Constant String Pool est une zone de la mémoire du Heap (donc, pas de la mémoire de la pile) où sont stockées les chaînes de caractères. Cette approche est à l'origine de la raison pour laquelle les chaînes sont immuables en java.
Par exemple :
chaîne x = "chaîne principale" ;
chaîne de caractères y = "machine virtuelle" ;
chaîne z = "chaîne principale" ;
Les trois cordes ci-dessus sont stockées dans le pool de cordes, mais la partie intéressante est l'efficacité. x et y pointent tous deux vers la même zone dans la réserve de cordes, ce qui ne nécessite pas de duplication de l'espace. Sachant cela, il doit être clair que la modification de la valeur de x n'est pas autorisée car elle aurait l'effet secondaire non voulu de modifier z.
Quelles sont les différences entre la mémoire Stack et l'espace Heap ?
Justification
Afin d'améliorer l'efficacité, la JVM organise la mémoire pour que les applications puissent s'exécuter. Elle crée de l'espace de pile et de l'espace de tas, chacun étant utilisé par des opérations différentes. Comprendre l'allocation de la mémoire à ce niveau peut conduire à un ramassage des déchets plus prévisible et, en fin de compte, à une efficacité accrue.
Bonne réponse
La mémoire en pile est utilisée pour l'allocation de mémoire statique, comme les valeurs primitives à l'intérieur d'une méthode. Elle est toujours utilisée pour l'exécution d'un thread. La pile s'agrandit lorsque les méthodes sont appelées, et se réduit lorsqu'elles reviennent. Si la mémoire allouée pour la pile est dépassée, l'exception java.lang.StackOverFlowError est lancée.
La mémoire de tas est utilisée pour l'allocation de mémoire dynamique, comme les objets java. Plus précisément, l'objet est stocké dans le tas, tandis que la référence à l'objet est stockée dans la pile. Les classes JRE sont également stockées dans le tas au moment de l'exécution. L'accès aux données dans le tas est plus lent que dans la mémoire de la pile. Le tas requiert l'action du collecteur de déchets afin de libérer les objets inutilisés. Si la mémoire allouée au tas est dépassée, l'exception java.lang.OutOfMemoryError est lancée.
Mauvaise réponse
Le fait de n'avoir jamais entendu parler de la pile ou du tas indiquerait une connaissance superficielle du langage de programmation java. De plus, la terminologie est typique d'une culture générale de programmation. Le diagnostic des erreurs liées à la mémoire, telles qu'un débordement de pile causé par un comportement incorrect d'une fonction récursive, serait plus facile avec cette compréhension.
Deux termes liés à la classe utilisés dans la programmation java sont "subclass" et "nested class". Expliquez les différences entre ces deux termes. Pourquoi choisir l'une plutôt que l'autre ? Laquelle est parfois appelée "classe intérieure" ?
Justification
Dans la conception orientée objet, il y a souvent une confusion sur le placement des classes dans la hiérarchie. Les classes imbriquées sont relativement rares par rapport aux sous-classes, mais leur utilisation est bénéfique dans de nombreuses situations. La connaissance de leur existence et de leur mode d'utilisation doit être considérée comme un atout.
Bonne réponse
Une sous-classe est une extension d'une autre classe, et est souvent une spécialisation de l'original. Les sous-classes héritent des membres publics et protégés de leur super-classe. Les sous-classes peuvent être instanciées indépendamment de la superclasse, et en fait, c'est toujours le cas lorsque la superclasse est une classe abstraite.
Une classe imbriquée est une classe à l'intérieur d'une classe, qui dans certains cas est une classe intérieure. Le champ d'application de la classe intérieure comprend tous les membres de sa classe extérieure, ce qui lui donne accès à ces variables et méthodes. Comme le corps existe entièrement au sein de la classe englobante, il ne peut pas être instancié indépendamment, sans elle.
L'utilisation d'une classe interne peut améliorer la conception orientée objet en organisant davantage le code. L'objectif est limité dans la mesure où il existe pour servir sa classe englobante. Si la classe interne offre des fonctionnalités utiles à une plus grande échelle, il serait plus logique de l'avoir comme classe de haut niveau. Les classes internes sont couramment utilisées comme fonctions de rappel pour les composants de l'interface graphique.
Bonus
Il existe deux types de classes imbriquées. Plus précisément, il existe une classe imbriquée statique, qui n'a pas directement accès aux autres membres de la classe englobante. Celles-ci ne sont pas souvent utilisées, c'est pourquoi le fait de les connaître est un bonus par opposition à l'ignorance qui peut entraîner une pénalité. L'autre type est une classe imbriquée non statique, qui est la version que l'on appelle une classe intérieure. Ceux-ci ont en effet accès à tous les membres de la classe englobante, y compris aux méthodes privées.
Mauvaise réponse
Le candidat doit être pardonné de n'avoir jamais utilisé une classe imbriquée. Bien qu'utile, et susceptible d'être vu si l'on maintient une base de code existante, le concept est simple. Les classes imbriquées rendent souvent le code plus élégant et plus facile à maintenir, mais certains concepteurs considèrent que c'est une question de style. Les sous-classes, d'autre part, sont un élément fondamental de la programmation orientée objet que tout développeur java devrait connaître. Ne pas pouvoir discuter facilement des sous-classes au sein d'une hiérarchie de classes est un sérieux signal d'alarme.
Deux classes de collection sont disponibles en programmation java : Array et List. En quoi les méthodes diffèrent-elles entre ces deux objets conteneurs, et dans quelles circonstances choisiriez-vous l'une plutôt que l'autre ?
Justification
L'utilisation de conteneurs est courante en Java et dans d'autres langages de programmation. La liste est une structure de données dynamique, tandis que le tableau est statique. Il est important de reconnaître que chacun d'entre eux est mieux adapté à certaines applications, et à ce titre, le candidat doit les connaître. Avoir une connaissance approfondie des types de données et des classes de conteneurs disponibles permettra en fin de compte de gagner du temps de développement.
Bonne réponse
Array
Les tableaux sont de taille statique, ils ne peuvent donc ni croître ni diminuer en termes de nombre d'éléments. Cela signifie qu'il existe des méthodes pour accéder aux éléments et les modifier, mais pas pour les insérer ou les supprimer.
Java fournit des méthodes pour effectuer une recherche binaire ou un tri sur un tableau. De plus, un tableau peut être initialisé en utilisant la méthode fill(), ou comparé en utilisant le comparateur equals().
La taille d'un tableau est fixée lors de sa création.
L'accès aléatoire d'un élément dans un tableau est très efficace.
Les tableaux sont plus adaptés à des collections d'éléments de longueur fixe.
Tous les éléments sont du même type, par exemple :
int[] interviewArray = new int[5];
or
int[] arrayForInterview = {3, 1, 4, 1, 5};
Ces deux tableaux contiennent cinq entiers.
Vecteur
Les candidats doivent savoir quand il est approprié et possible d'utiliser ces mots clés. En particulier, ils doivent savoir que l'asynchronisation ne peut être placée avant le mot-clé de fonction sur une définition de fonction. La fonction est alors considérée comme un retour de promesse. Le mot-clé "await" ne peut être utilisé qu'à l'intérieur d'une telle fonction asynchrone et doit être placé avant un appel à une fonction qui rendra une Promesse.
Les éléments d'une liste peuvent être ajoutés ou supprimés, ce qui signifie que la taille de la liste peut changer. Les méthodes permettent de nombreux types de manipulations, y compris l'insertion ou la suppression dans un index spécifique. Les plages peuvent également être manipulées.
La Liste est une interface, donc quand on manipule une Liste, une vraie classe, généralement ArrayList, est utilisée en coulisse
Une liste repose sur les méthodes de tri de Collections, telles que Collections.sort().
Les méthodes de recherche contain(), indexOf(), et lastIndexOf() sont des exemples qui peuvent être utilisés pour rechercher les éléments. Cependant, pour effectuer une recherche binaire, il faut appeler la méthode plus générale : Collections.binarySearch(...)
Les listes peuvent contenir des objets de type mixte, par exemple :
List interviewList = new ArrayList();
interviewList.add(3);
interviewList.add(1415);
interviewList.add(“Pi”);
Bonus
Les tableaux peuvent stocker des objets, il existe donc une solution de rechange pour ceux qui sont enclins à mélanger les types dans un tableau. De plus, le candidat doit être crédité de savoir que les Listes remplacent les Vecteurs qui ne sont plus couramment utilisés en Java. La raison est liée à la simultanéité et à la synchronisation des opérations. Il est clair qu'une explication plus détaillée dépasse la portée de cette question - cependant, la mention de ce point est digne d'intérêt.
Mauvaise réponse
Les tableaux et les listes, parmi d'autres classes et interfaces intégrées, y compris les collections, sont très courants dans la programmation Java et le développement d'applications. Un candidat qui n'est pas à l'aise avec ces fonctionnalités manque presque certainement d'expérience avec le langage.
Contrairement au C++, Java ne prend pas en charge l'héritage multiple. Comment la programmation avec une interface apportera-t-elle une réponse à ce problème ? Une interface fait-elle partie de la hiérarchie des classes ?
Justification
S'il existe des points communs entre les langues que de nombreux programmeurs connaissent bien, il existe aussi des distinctions qui permettent de les définir. Dans un entretien en Java, il y aura des questions de base en Java qui aideront à évaluer dans quelle mesure le candidat connaît les spécificités du langage de programmation Java. Étant donné la question du problème du diamant en C++, il est intéressant de tester les connaissances du candidat dans une perspective java.
Bonne réponse
Une interface est similaire à une classe en ce sens qu'elle peut contenir différents types de méthodes, mais différente parce qu'elle ne détient pas l'état. Les interfaces sont intrinsèquement abstraites, et leurs méthodes doivent être implémentées par une classe. L'interface n'est pas instanciée, elle est implémentée. Contrairement au C++, une classe ne peut étendre qu'un seul parent (c'est-à-dire qu'elle ne peut avoir qu'une seule superclasse). Une interface, en revanche, est capable d'étendre plus d'une interface parent. Par exemple :
public interface CheckerBoard {
public void setSize(int rowCount, int columnCount);
}
public interface Game {
public void setNumberOfPlayers();
public void play();
}
public interface ChessGame extends CheckerBoard, Game {}
Dans cet exemple, l'interface ChessGame hérite à la fois de CheckerBoard et de Game.
Mauvaise réponse
Si la personne interrogée ne sait pas ce qu'est l'héritage multiple, cela suggère un manque d'expérience en matière de conception orientée objet. Cela n'est pas essentiel pour toutes les applications, bien qu'il soit important de reconnaître que java est intrinsèquement OO.
Qu'est-ce que la machine virtuelle Java ? Quel en est l'objectif principal et avec quel type de code fonctionne-t-elle ?
Justification
Aucune interview en Java ne serait complète sans une question sur le thème de la machine virtuelle. La JVM est un élément clé de Java, et les programmeurs java l'apprennent très tôt. Si la JVM est capable d'exécuter du bytecode généré par d'autres langages, tels que JRuby et Jython, cela n'enlève rien au fait qu'elle est essentielle à la java elle-même.
Bonne réponse
La JVM est une machine virtuelle qui permet à l'ordinateur d'exécuter des programmes Java qui ont été compilés en bytecode. Le bytecode est indépendant de la plateforme, et s'exécute sur tout ordinateur qui héberge une JVM. Il comprend un compilateur juste à temps (JIT) qui convertit le bytecode en instructions en langage machine, permettant aux applications de s'exécuter aussi rapidement qu'un exécutable natif.
Mauvaise réponse
La JVM est l'un des principaux composants qui font de Java ce qu'il est. Le fait de ne pas connaître la JVM indique probablement un manque d'expérience avec le langage.
Quelles sont les méthodes et les classes finales ? Une classe abstraite supportera-t-elle les méthodes finales ?
Justification
Le dernier mot-clé est commun et doit être bien compris par les programmeurs java. Au cours de la phase de conception OO, il est normalement décidé si les classes doivent être extensibles. Si ce n'est pas le cas, elles sont marquées comme finales afin de limiter les effets secondaires potentiels de sous-classes qui n'ont pas été envisagées. Il s'agit d'une caractéristique importante qui devrait être utilisée pour un code plus robuste et plus facile à maintenir.
Bonne réponse
Une méthode qui est déclarée avec le mot-clé final ne peut pas être annulée dans les sous-classes. Cette méthode est utilisée dans les hiérarchies où la mise en œuvre de la méthode doit être cohérente dans l'ensemble. La déclaration finale d'une classe interdit totalement le sous-classement. Oui, il est possible d'inclure des méthodes finales dans une classe abstraite. Cela permet de s'assurer que les sous-classes ne peuvent pas passer outre la méthode.
Mauvaise réponse
Si le candidat n'est pas familier avec le mot-clé final, qu'il soit utilisé au niveau de la classe ou de la méthode, alors cela suggère une relative inexpérience de la langue. Même pour les programmeurs inexpérimentés qui ont participé à la conception orientée objet, le concept de classe finale devrait être familier.
La programmation Java permet de créer un fil de discussion de différentes manières. Quelles sont-elles et quelle est la méthode préférée ? Expliquez.
Justification
Contrairement au C++, java contient un support intégré pour le multithreading. C'est une fonctionnalité riche et puissante qui est à la fois pertinente et utile dans de nombreuses applications. En tant que tel, le candidat doit être familier avec les bases.
Bonne réponse
Que se passe-t-il dans le cas où la réduction est appelée sur un tableau vide sans fournir la valeur initiale facultative de l'accumulateur ?
public class JavaInterviewClass implements Runnable {
public void run() {
System.out.println(“My example public class prints this line from a thread.”);
}
}
Pour exécuter la méthode run(), passez une instance de la classe dans un Thread, comme suit :
Thread interviewThread = new Thread(new JavaInterviewClass ());
interviewThread.start();
La deuxième façon de créer un fil de discussion est d'étendre la classe de fil de discussion. La sous-classe remplacera la méthode run(). Après cela, il suffit de créer une instance de la classe.
public class JavaInterviewClass extends Thread {
public void run() {
System.out.println(“My example public class extends the Thread class.”);
}
}
Pour exécuter le fil de discussion, il suffit d'instancier la classe et d'appeler start(), comme suit :
JavaInterviewClass myInterview = new JavaInterviewClass (); myInterview.start();
Bonus
Bien que l'implémentation de l'interface exécutable et l'extension de la classe Thread soient deux moyens populaires de créer un thread, il est également possible d'utiliser le framework Executor. Celui-ci permet de travailler directement avec les threads, mais il est moins connu. Il comprend des méthodes telles que newSingleThreadExecutor(), newFixedThreadPool() et submit() pour créer des tâches d'exécution. La connaissance de l'utilisation du framework Executor implique que le candidat soit très à l'aise avec la création et l'utilisation de threads en java.
Mauvaise réponse
Si le candidat n'est pas à l'aise avec l'utilisation des fils de discussion, il passe à côté d'une caractéristique puissante et importante de la langue. C'est important car comprendre le multithreading ne se limite pas à rechercher la syntaxe de quelques commandes. Il s'agit plutôt d'une approche qui doit être envisagée lors de la conception et du développement d'une application.
Le code Java a un support intégré pour la concurrence dans sa classe Thread. La simultanéité a son propre ensemble de problèmes tels que l'impasse et les conditions de course. Décrivez brièvement les variables Atomic en Java et leur utilisation. Ensuite, il est indiqué que la méthode start() est utilisée pour créer une pile d'appels séparée avant que la méthode run() ne soit utilisée pour exécuter un thread. Que font les méthodes yield(), sleep() et join() ?
Justification
La prise en charge du multithreading par Java peut entraîner des problèmes liés à la concurrence. Les connaissances du candidat concernant ces problèmes doivent être évaluées et prises en compte.
Bonne réponse
Une variable atomique est une variable "mise à jour atomique", ce qui signifie que l'intégrité des données est assurée par l'utilisation d'algorithmes non bloquants. Cette fonctionnalité est généralement mise en œuvre au niveau du code machine. Java prend en charge plusieurs variables atomiques, le plus souvent AtomicBoolean, AtomicInteger, AtomicLong et AtomicReference. Il existe également plusieurs méthodes qui permettent de récupérer et de modifier ces variables, notamment get(), set(), lazySet(), compareAndSet() et weakCompareAndSet(). Utilisées correctement, les variables atomiques peuvent être utilisées pour mettre en œuvre des méthodes "thread safe" (multithreading safe) qui traitent efficacement certains problèmes liés à la concurrence.
rendement() : Cette méthode informe l'environnement que le fil de discussion actuel n'est pas en train d'achever une tâche de haute priorité, et est prêt à en interrompre l'exécution. À condition que l'environnement sous-jacent supporte l'ordonnancement préventif, elle suspendra le fil s'il y en a un autre qui doit s'exécuter. S'il n'y a pas de deuxième fil, ou si le deuxième fil se termine, le fil en cours reprendra le contrôle et continuera à s'exécuter.
sommeil() : Cette méthode fait dormir le fil courant, ou met en pause son exécution, pendant un nombre de millisecondes déterminé. Il est également possible de combiner un certain nombre de millisecondes et de nanosecondes. Pendant que le fil courant est en sommeil, un autre fil sera exécuté, ou sinon le CPU restera inactif. Sous réserve de la précision de l'horloge du système et des minuteurs, le fil de discussion reprendra le contrôle une fois le compte à rebours terminé.
join() : Cette méthode est utilisée pour joindre deux l'exécution de deux fils ensemble. Pour clarifier, si le fil A appelle join() sur le fil B, alors A commencera à attendre. Une fois que B a terminé, ou qu'un délai prédéfini a expiré, A reprendra le contrôle et continuera l'exécution.
Mauvaise réponse
Le fait de connaître les fils de discussion Java, mais de ne pas être conscient des problèmes liés à la concurrence peut entraîner de graves erreurs. La majorité des appareils, des ordinateurs de bureau aux appareils mobiles en passant par les ordinateurs à carte unique, prennent désormais généralement en charge le multithreading et la concurrence. Il est important de comprendre la bonne utilisation des threads, et d'être conscient des méthodes fournies par java pour les prendre en charge.
Conclusion
Les questions de cet article sont utiles pour évaluer les compétences d'un futur programmeur Java. En ce qui concerne les questions d'entretien à préparer pour un développeur Java, il est important de se rappeler que les spécificités du langage peuvent être facilement référencées en utilisant l'aide et la documentation en ligne. Les points subtils d'un langage ne sont pas aussi importants que la façon dont on applique la logique. Cela dit, les candidats à ce poste sont censés connaître le langage et ne pas avoir besoin d'une formation approfondie avant que le travail réel ne commence. Les compétences requises seront dictées par le travail à effectuer, et la variation des questions données ci-dessus aidera à faire cette évaluation. N'oubliez pas que l'une des meilleures façons d'évaluer les compétences du candidat pour votre projet est d'effectuer une évaluation pratique de la programmation, ce qui est bien plus efficace que des questions d'entretien orales pour engager un programmeur Java hautement qualifié.
Questions d’entretien pour recruter un développeur Java
Généralement, lorsque l’on parle de préparation pour l’entretien d’embauche d’un développeur Java, l’accent est mis sur le point de vue de la personne recrutée. Les candidats veulent savoir à quels types de questions ils doivent s’attendre afin de se préparer au mieux. Pourtant, en prenant un angle différent, on peut se demander : quelles questions un recruteur à la recherche d’un développeur Java doit-il poser aux candidats afin d’évaluer au mieux leurs compétences techniques ?
Dans une entreprise développant des logiciels, que le langage de programmation Java ou la programmation orientée objet en général soit un standard ou non, il est facile de trouver des questions de programmation et leurs réponses. Il est chose aisée d’utiliser Google pour rechercher la syntaxe du langage en question afin de faciliter la rédaction d’un entretien d’embauche sur Java.
Avant de commencer, voici une définition rapide du terme Java qui devrait vous aider si ce langage ne vous est pas entièrement familier :
Java is a high-level programming language developed by Sun Microsystems. It was originally designed for developing programs for set-top boxes and handheld devices, but later became a popular choice for creating web applications.
The Java syntax is similar to C++, but is strictly an object-oriented programming language. For example, most Java programs contain classes, which are used to define objects, and methods, which are assigned to individual classes. Java is also known for being more strict than C++, meaning variables and functions must be explicitly defined. This means Java source code may produce errors or “exceptions” more easily than other languages, but it also limits other types of errors that may be caused by undefined variables or unassigned types.
Christensson, P., Définition Java, techterms.com
Le but de cet article est d’aider à préparer le recruteur, quelle que soit son expérience avec Java. Déterminer quel candidat parmi tant d’autres a offert la meilleure performance lors d’un entretien sur Java n’est pas une tâche facile lorsque l’on ne dispose pas de compétences avancées en programmation. Dans le même temps, il faut savoir que ce candidat parfait ne sera pas trouvé à l’aide de questions d’entretien purement liées au code. La programmation est souvent une question de logique, par opposition à la syntaxe, et ce serait une grave erreur de pénaliser trop lourdement les candidats parce qu’ils ne sont pas familiers avec une problématique pouvant être aisément solutionnée à l’aide de Google.
Cela dit, il est important de se rappeler que l’entretien doit aboutir à un poste de développeur Java. Le candidat doit connaître l’environnement d’exécution Java (JRE), la machine virtuelle Java (JVM) et le kit de développement Java (JDK), etc. Les bibliothèques couramment utilisées telles que java lang, java util ne devrait pas être un mystère pour eux. De même, alors qu’elle n’est plus utilisée, la bibliothèque Swingdevrait au moins leur être familière (alors qu’il est acceptable de ne pas connaître la bibliothèque Awt, qui est totalement obsolète. Enfin, les candidats doivent au moins être au courant de l’existence de frameworks et d’autres technologies tels que Spring framework, JavaServer Pages (JSP), et Java Database Connectivity (JDBC).
Les questions d'entretien Java doivent être spécifiques à certains égards, mais générales à d'autres. Par exemple, est-il nécessaire d'inclure des questions d'entretien JDBC spécifiques ? Peu probable. Cependant, un candidat doit absolument savoir ce qu'est une interface de la Liste.
Avec autant d'objectifs concurrents, comment trouver le candidat idéal ? La réponse réside dans un large éventail de questions d'entretien qui couvrent le sujet sous plus d'un angle. Cet article vise à répondre à ces préoccupations en fournissant la question d'entretien de Java, la ou les réponses correctes, et la raison pour laquelle chaque question est posée.
Consultez la question Java ci-dessous. Il existe plusieurs façons de la résoudre, de sorte que les choix du candidat peuvent révéler sa façon de coder. Comment la résoudriez-vous ? Cliquez sur l'onglet "Instructions" et essayez :
Questions de programmation de différents niveaux et leurs réponses
Cet article contient 14 questions d’entretien et leurs réponses. Les 5 premières sont niveau débutant, tandis que les autres varient à la fois en termes de sujet et de niveau de difficulté. Un score parfait ne sera pas nécessairement obtenu en répondant à chaque question parfaitement. Au contraire, la discussion sur les solutions donnera le meilleur indicateur à la fois de la capacité de réflexion du candidat et de l’expérience qu’il a accumulée.
Questions de programmation Java niveau débutant
1 - Le code Java prévoit des méthodes de classe avec des spécificateurs d'accès public et privé. Quelle est la différence entre ces deux modificateurs ?
Justification
Dans la programmation orientée objet, il est courant de limiter la portée des variables et des fonctions à des classes spécifiques dans une hiérarchie de classes. Ceci est réalisé à l’aide de différents spécificateurs d’accès, et connaître la différence entre ces composants fondamentaux est une question d’entretien Java très pertinente.
En Java, les classes peuvent être uniquement déclarées publiques, ou bien pas du tout – alors que les fonctions membres ont quatre modificateurs différents – c’est donc un sujet qui peut s’avérer épineux pour les grands débutants.
Bonne réponse
Un spécificateur d’accès public ordonne que la méthode soit accessible à la fois à l’intérieur et à l’extérieur de la classe. Ceci est vrai tant que la classe elle-même est déclarée publique, ou que la classe appelante est dans le même package. Si la classe ne spécifie pas de modificateur, elle est supposée avoir un accès par défaut (package), et les déclarations de ses méthodes ne l’écrasent pas.
Un spécificateur d’accès privé indique que la méthode doit être accessible uniquement à l’intérieur de la classe.
Bonus
Si le candidat sait qu'il existe également des spécifications pour les produits protégés et les emballages (par défaut), il démontre alors une bonne compréhension de ce sujet.
Mauvaise réponse
Si le candidat ne connaît pas la différence entre public et private, cela indique un manque d’expérience à propos de Java et probablement dans d’autres langages orientés objet tels que C++. Si la réponse est correcte, mais qu’il n’est pas fait mention du fait que le modificateur de classe l’emporte sur les méthodes, le candidat devrait être pénalisé.
Considérons le code suivant qui contient une classe, une variable statique et une méthode publique. Combien de bouchées ont été prises pour chaque pomme ?
public class Apple {
static int bites = 0;
public void takeBite() {
bites++;
}
public static void main(String[] args) {
// Instantiate red and green apples for our example public class
Apple macintosh = new Apple();
Apple grannySmith = new Apple();
// Take a bite out of each of the two apples
macintosh.takeBite();
grannySmith.takeBite();
// Display the contents of each class
System.out.println("The Macintosh apple has " + macintosh.bites + " bite(s) out of it.");
System.out.println("The Granny Smith apple has " + grannySmith.bites + " bite(s) out of it.");
}
}
Justification
Les variables statiques sont une caractéristique de Java régulièrement utilisée par les développeurs. Comme c’est le cas pour les variables globales, il est important pour les programmeurs de comprendre la portée de ces objets afin d’éviter un quelconque effet collatéral. Note à propos de la non-déclaration d’une variable : cela permet d’éviter de mal taper le nom d’une variable, car la variable mal orthographiée apparaîtra comme une nouvelle variable non déclarée.
Bonne réponse
La classe Apple partage la variable statique, bites, entre toutes ses instances. Par conséquent, lorsque la méthode takeBite() est appelée sur chacune des instances, la variable commune est mise à jour. Le résultat final se présente ainsi :
The Macintosh apple has 2 bite(s) out of it.
The Granny Smith apple has 2 bite(s) out of it.
Mauvaise réponse
Si le candidat répond que chacune des deux instances s’est vue retirée une seule bouchée (bite), cela indique un manque d’expérience avec les variables statiques. Ce sujet est trivial, mais un développeur Java le rencontrera fréquemment. Le fait de ne pas en avoir connaissance indique que le candidat manque probablement d’expérience pratique du langage.
Qu'est-ce qu'une exception ? Décrivez brièvement les deux types d'exception utilisés dans le code java.
Justification
Les exceptions sont des événements inattendus qui surviennent au moment de l’exécution et qui diffèrent des erreurs dans la mesure où il est généralement aisé de les « rattraper ». Les erreurs, par contre, indiquent généralement un problème plus grave. La gestion des exceptions est très courante et doit être comprise, au moins à un niveau de base, par n’importe quel programmeur Java.
Bonne réponse
Les deux types d’exceptions dans Java sont les exceptions vérifiées et les exceptions non-vérifiées.
Une exception vérifiée est une exception qui est vérifiée au moment de la compilation. Lorsqu’il y a du code dans une méthode qui lève une exception vérifiée, la méthode est nécessaire pour l’acquitter. Ceci peut être accompli soit en gérant l’exception avec un bloc try/catch, soit en la spécifiant à l’aide du mot-clé throws. Une exception non-vérifiée est une exception qui n’est pas vérifiée au moment de la compilation. C’est au programmeur de spécifier ce type d’exception. En revanche, il faut noter que toutes les exceptions en C++ sont non-vérifiées.
Bonus
En Java, toutes les exceptions des classes Error et RuntimeException sont décochées. Tout le reste sous Throwable est vérifié. Si la personne interrogée soulève ce point particulier, elle démontre une compréhension profonde de la question qui lui a été posée.
Mauvaise réponse
Si le candidat n’est pas au courant des exceptions, il lui manque une partie essentielle du langage qui est responsable du contrôle de l’exécution. Cette fonctionnalité représente un véritable bond en avant par rapport à des langages tels que C (qui ne supporte pas la gestion des exceptions). Bien qu’elles ne soient pas absolument indispensables, les exceptions sont extrêmement utiles au quotidien du fait de leurs nombreux avantages, tout développeur Java efficace les utilise.
Que sont les cours d'emballage ? Donnez des exemples de deux d'entre elles et des primitives correspondantes. Quel est le rapport entre chacune d'elles et un objet ?
Justification
Les classes d’emballage sont fondamentales en programmation Java. En fait, leur existence implique que java n’est pas 100% orienté objet (bonus au candidat qui le signale !). C’est le cas parce que Java contient 8 types de données primitives qui ne sont pas, par définition, des objets.
Bonne réponse
Une classe d’emballage est une classe qui contient une variable qui est un type de données primitives, et qui enveloppe la primitive pour fournir une fonctionnalité d’interaction avec elle. En fait, on peut dire qu’il transforme le primitif en objet. Ce qui est utile, par exemple, lorsqu’une méthode vise au transfert d’un objet. Le candidat doit être capable de nommer au moins deux des paires suivantes :
Primitive
Classe d'emballage
boolean
Boolean
byte
Byte
char
Char
double
Double
float
Float
int
Int
long
Long
short
Short
Mauvaise réponse
Les classes d’emballage sont définies en java.lang, et requises car il existe de nombreuses classes qui supportent uniquement les objets. Le fait de ne pas connaître ces classes d’emballage, ou de ne pas savoir pourquoi elles seraient utilisées, apparaît comme une grave lacune de la part du candidat interrogé.
Définissez les termes suivants qui sont courants dans la programmation java
Classe abstraite
Ramasse-miettes (aussi appelé récupérateur de mémoire, glaneur de cellules ou garbage collector)
Autoboxing
Sérialisation
Justification
Cette liste inclut des termes qui sont communément utilisés en Java, ainsi que dans d’autres langages de programmation. Les questions d’entretien pour les programmeurs expérimentés incluent de telles définitions parce qu’elles permettent de tester leurs connaissances de manière approfondie, ainsi que leur capacité à distinguer des langages comportant des concepts proches sans être parfaitement identiques.
Bonne réponse
Une classe abstraite est utilisée comme classe de base pour les sous-classes qui vont étendre ou écraser ses méthodes. Prenons l’exemple d’une classe « Forme ». Une forme peut contenir un certain nombre de côtés, de faces ou même de dimensions. Prise isolément, savoir que cette classe est une « Forme » est peu utile. D’autre part, si cette classe abstraite sera utilisée comme classe de base pour un « Carré », un « Triangle », ou un autre type de polygone, elle deviendra utile quand placée au sommet de la hiérarchie des classes. - Il n'est pas possible d'instancier une classe abstraite. – Elle peut contenir des méthodes abstraites, mais ce n’est pas obligatoire. - Les sous-classes de la classe d'abstraction doivent mettre en œuvre toutes les méthodes d'abstraction, à moins qu'il ne s'agisse également d'une classe d'abstraction. Il n'est pas possible d'instancier une classe abstraite.
Ne pas être parfaitement calé à propos classes abstraites n’est pas éliminatoire, bien que ces dernières seront très probablement rencontrées par le programmeur Java lorsqu’il devra effectuer des actions de maintenance ou du débogage d’une base de code existante.
La "garbage collection" (effectuée par le "garbage collector" ou ramasse-miettes) est le processus de détection et de suppression des objets en mémoire qui ne sont plus utilisés ou référencés. En java, le ramassage des miettes est automatique, mais il peut aussi être demandé.
Les commandes System.gc() et Runtime.gc() indiqueront au ramasse-miettes qu’il doit s’exécuter, bien que cela ne soit pas garanti.
Les fils d’exécution sont mis en pause pendant le ramassage des ordures. Cela ralentit nécessairement l’exécution, ce qui signifie que dans les applications réactives, le ramassage des miettes doit être réduit au minimum. La connaissance du ramasseur de miettes n’est pas indispensable, surtout pour un programmeur débutant. Il est à noter, cependant, que lorsqu’on vient d’un langage comme C, où toute la mémoire est gérée manuellement, le développeur doit être au courant de l’existence de cette fonctionnalité.
L’Autoboxing est l’emballage automatique d’un type primitif (voir la question #4 relative aux types primitifs et classes d’emballages). Par exemple, l’autoboxing convertira automatiquement un nombre de type float (type primitif) en Float (classe d’emballage). Le contraire de cela est le déballage, lors duquel type primitif est extrait de la classe d’emballage. Cette notion est habituellement familière aux bons développeurs Java.
La sérialisation fait référence à l’encodage d’objets en mémoire dans un flux d’octets qui pouvant être facilement stockés ou transmis. Le contraire est la désérialisation, qui reconstruit les objets à partir d’un flux d’octets. Il existe différentes approches pour réaliser la sérialisation. Deux méthodes courantes sont la conversion de l’objet en XML (eXtensible Markup Language), ou JSON (JavaScript Object Notation). Ce sont des types de fichiers bien connus, chacun d’entre eux étant largement pris en charge. Java supporte également la sérialisation comme partie intégrante du langage. Le langage inclut l’interface sérialisable, qui peut être utilisée à la fois pour la sérialisation et la désérialisation. La méthode writeObject() est utilisée pour encoder les données, tandis que la méthode readObject() est utilisée pour reconstruire les objets.
Java définit une classe String pour représenter des tableaux de caractères. Répondez aux questions suivantes :
Un constructeur initialise un objet lors de sa création. Cependant, les constructeurs n'ont pas de type de retour explicite.
En général, vous utiliserez un constructeur pour donner des valeurs initiales aux variables d'instance définies par la classe, ou pour effectuer toute autre procédure de démarrage nécessaire pour créer un objet entièrement formé.
Toutes les classes ont des constructeurs, que vous en définissiez un ou non, car Java fournit automatiquement un constructeur par défaut qui initialise toutes les variables membres à zéro. Cependant, une fois que vous avez défini votre propre constructeur, le constructeur par défaut n'est plus utilisé.
Pourriez-vous citer quelques cadres de travail Java ?
Cette question d'entretien est une question de base : tout développeur Java compétent est en mesure de nommer quelques frameworks écrits en langage Java. Au cours de l'entretien, le candidat interrogé doit mentionner au moins trois frameworks Java parmi cette liste :
JSF (Java Server Faces), un cadre web Java qui facilite la construction d'interfaces utilisateur pour les applications basées sur des serveurs
GWT (Google Web Toolkit), un ensemble d'outils open-source qui aide les programmeurs à créer et à maintenir des applications JavaScript dans Java Spring, un framework Java qui n'impose aucun modèle de programmation spécifique
Struts
Hiberner
Grails
Jouez !
Vaadin
Maven
Questions d'entretien sur la programmation mixte
Java définit une classe String pour représenter des tableaux de caractères. Répondez aux questions suivantes :
- Par quoi faut-il remplacer le "XXX" pour pouvoir comparer les deux principaux arcs de cordes ? Si les arguments sont : "Sun Microsystems" et "Sun microsystems", quel sera le résultat de l'exécution ? Y a-t-il un moyen de garantir qu'il les déclarera comme étant identiques ? - Si les arguments sont plutôt : "Sun Microsystems" et "Sun Microsystems", quel sera le résultat de l'exécution ? "Sun Microsystem" et "Sun Microsystems", quel sera le résultat de l'exécution ?
1/ Après la création d'une chaîne, est-il possible de la modifier ? Considérez ce qui suit :
public static void main(String[] args) { String name = "James gosling"; // I want to change the 'g' to a 'G'. // Will this work at compile time? name.charAt(6) = 'G'; // Print with the standard system println to see “James Gosling” System.out.println(name); }
Cela va-t-il fonctionner ? Si ce n'est pas le cas, quelles modifications faudrait-il apporter pour obtenir la chaîne souhaitée ?
2/ La classe String a plus d'un Comparateur. Considérez le code suivant :
public static void main(String[] args) { // This program received 2 arguments. We want to // determine if those two strings are equal. // Compare the first argument to the second argument boolean compareResult = (XXX); if (compareResult) { System.out.println("The Strings are the same."); } else { System.out.println("The Strings are not the same."); } // Print the main string args System.out.println(args[0]); System.out.println(args[1]); }
- Par quoi faut-il remplacer le "XXX" pour pouvoir comparer les deux principaux arcs de cordes ? Si les arguments sont : "Sun Microsystems" et "Sun microsystems", quel sera le résultat de l'exécution ? Y a-t-il un moyen de garantir qu'il les déclarera comme étant identiques ? - Si les arguments sont plutôt : "Sun Microsystems" et "Sun Microsystems", quel sera le résultat de l'exécution ? "Sun Microsystem" et "Sun Microsystems", quel sera le résultat de l'exécution ?
3/ Qu'est-ce que le pool de constantes de la chaîne Java ? (ou pool de chaînes de caractères Java) ? Il réside dans la mémoire de la pile ?
Justification
L'utilisation de représentations de chaînes de caractères est courante dans de nombreux langages, et Java ne fait pas exception. Il est important de comprendre comment les chaînes de caractères sont créées, analysées, imprimées et manipulées. C'est un sujet important qui constitue une question d'entretien importante pour les développeurs Java.
Bonne réponse
Non, cela échouera au moment de la compilation car il n'est pas possible de modifier une chaîne une fois qu'elle a été initialisée. Cette propriété est dite immuable. Pour que cela fonctionne, il faudrait recréer la chaîne contenant "James gosling". Une approche consiste à utiliser un tableau de caractères intermédiaires (en appelant la méthode toCharArray() sur le "nom"), à remplacer le "g" par la lettre majuscule, puis à recréer la chaîne avant de l'imprimer. Un bonus pour le candidat qui souligne que la fonction string replace(...) existe pour remplacer les caractères, mais ne peut pas être utilisée car toutes les instances de "g" minuscules seraient remplacées.
Le comparateur exact dans cet exemple est soit égal(...) soit égalIgnoreCase(...). Le type de retour de ces deux méthodes est une valeur booléenne. Si la personne interrogée répond compareTo(...) ou compareToIgnoreCase(...), alors le crédit devrait être accordé, bien que le type de retour de ces méthodes soit un int, donc techniquement incorrect. Il n'en reste pas moins qu'elle démontre une connaissance de la langue.
Dans le premier exemple, les chaînes sont identiques sous equalsIgnoreCase(...), mais différentes sous equals(...). Dans le deuxième exemple, il y a un "s" à la fin, ce qui fait que les chaînes sont différentes dans tous les cas.
Le Java Constant String Pool est une zone de la mémoire du Heap (donc, pas de la mémoire de la pile) où sont stockées les chaînes de caractères. Cette approche est à l'origine de la raison pour laquelle les chaînes sont immuables en java.
Par exemple :
chaîne x = "chaîne principale" ;
chaîne de caractères y = "machine virtuelle" ;
chaîne z = "chaîne principale" ;
Les trois cordes ci-dessus sont stockées dans le pool de cordes, mais la partie intéressante est l'efficacité. x et y pointent tous deux vers la même zone dans la réserve de cordes, ce qui ne nécessite pas de duplication de l'espace. Sachant cela, il doit être clair que la modification de la valeur de x n'est pas autorisée car elle aurait l'effet secondaire non voulu de modifier z.
Quelles sont les différences entre la mémoire Stack et l'espace Heap ?
Justification
Afin d'améliorer l'efficacité, la JVM organise la mémoire pour que les applications puissent s'exécuter. Elle crée de l'espace de pile et de l'espace de tas, chacun étant utilisé par des opérations différentes. Comprendre l'allocation de la mémoire à ce niveau peut conduire à un ramassage des déchets plus prévisible et, en fin de compte, à une efficacité accrue.
Bonne réponse
La mémoire en pile est utilisée pour l'allocation de mémoire statique, comme les valeurs primitives à l'intérieur d'une méthode. Elle est toujours utilisée pour l'exécution d'un thread. La pile s'agrandit lorsque les méthodes sont appelées, et se réduit lorsqu'elles reviennent. Si la mémoire allouée pour la pile est dépassée, l'exception java.lang.StackOverFlowError est lancée.
La mémoire de tas est utilisée pour l'allocation de mémoire dynamique, comme les objets java. Plus précisément, l'objet est stocké dans le tas, tandis que la référence à l'objet est stockée dans la pile. Les classes JRE sont également stockées dans le tas au moment de l'exécution. L'accès aux données dans le tas est plus lent que dans la mémoire de la pile. Le tas requiert l'action du collecteur de déchets afin de libérer les objets inutilisés. Si la mémoire allouée au tas est dépassée, l'exception java.lang.OutOfMemoryError est lancée.
Mauvaise réponse
Le fait de n'avoir jamais entendu parler de la pile ou du tas indiquerait une connaissance superficielle du langage de programmation java. De plus, la terminologie est typique d'une culture générale de programmation. Le diagnostic des erreurs liées à la mémoire, telles qu'un débordement de pile causé par un comportement incorrect d'une fonction récursive, serait plus facile avec cette compréhension.
Deux termes liés à la classe utilisés dans la programmation java sont "subclass" et "nested class". Expliquez les différences entre ces deux termes. Pourquoi choisir l'une plutôt que l'autre ? Laquelle est parfois appelée "classe intérieure" ?
Justification
Dans la conception orientée objet, il y a souvent une confusion sur le placement des classes dans la hiérarchie. Les classes imbriquées sont relativement rares par rapport aux sous-classes, mais leur utilisation est bénéfique dans de nombreuses situations. La connaissance de leur existence et de leur mode d'utilisation doit être considérée comme un atout.
Bonne réponse
Une sous-classe est une extension d'une autre classe, et est souvent une spécialisation de l'original. Les sous-classes héritent des membres publics et protégés de leur super-classe. Les sous-classes peuvent être instanciées indépendamment de la superclasse, et en fait, c'est toujours le cas lorsque la superclasse est une classe abstraite.
Une classe imbriquée est une classe à l'intérieur d'une classe, qui dans certains cas est une classe intérieure. Le champ d'application de la classe intérieure comprend tous les membres de sa classe extérieure, ce qui lui donne accès à ces variables et méthodes. Comme le corps existe entièrement au sein de la classe englobante, il ne peut pas être instancié indépendamment, sans elle.
L'utilisation d'une classe interne peut améliorer la conception orientée objet en organisant davantage le code. L'objectif est limité dans la mesure où il existe pour servir sa classe englobante. Si la classe interne offre des fonctionnalités utiles à une plus grande échelle, il serait plus logique de l'avoir comme classe de haut niveau. Les classes internes sont couramment utilisées comme fonctions de rappel pour les composants de l'interface graphique.
Bonus
Il existe deux types de classes imbriquées. Plus précisément, il existe une classe imbriquée statique, qui n'a pas directement accès aux autres membres de la classe englobante. Celles-ci ne sont pas souvent utilisées, c'est pourquoi le fait de les connaître est un bonus par opposition à l'ignorance qui peut entraîner une pénalité. L'autre type est une classe imbriquée non statique, qui est la version que l'on appelle une classe intérieure. Ceux-ci ont en effet accès à tous les membres de la classe englobante, y compris aux méthodes privées.
Mauvaise réponse
Le candidat doit être pardonné de n'avoir jamais utilisé une classe imbriquée. Bien qu'utile, et susceptible d'être vu si l'on maintient une base de code existante, le concept est simple. Les classes imbriquées rendent souvent le code plus élégant et plus facile à maintenir, mais certains concepteurs considèrent que c'est une question de style. Les sous-classes, d'autre part, sont un élément fondamental de la programmation orientée objet que tout développeur java devrait connaître. Ne pas pouvoir discuter facilement des sous-classes au sein d'une hiérarchie de classes est un sérieux signal d'alarme.
Deux classes de collection sont disponibles en programmation java : Array et List. En quoi les méthodes diffèrent-elles entre ces deux objets conteneurs, et dans quelles circonstances choisiriez-vous l'une plutôt que l'autre ?
Justification
L'utilisation de conteneurs est courante en Java et dans d'autres langages de programmation. La liste est une structure de données dynamique, tandis que le tableau est statique. Il est important de reconnaître que chacun d'entre eux est mieux adapté à certaines applications, et à ce titre, le candidat doit les connaître. Avoir une connaissance approfondie des types de données et des classes de conteneurs disponibles permettra en fin de compte de gagner du temps de développement.
Bonne réponse
Array
Les tableaux sont de taille statique, ils ne peuvent donc ni croître ni diminuer en termes de nombre d'éléments. Cela signifie qu'il existe des méthodes pour accéder aux éléments et les modifier, mais pas pour les insérer ou les supprimer.
Java fournit des méthodes pour effectuer une recherche binaire ou un tri sur un tableau. De plus, un tableau peut être initialisé en utilisant la méthode fill(), ou comparé en utilisant le comparateur equals().
La taille d'un tableau est fixée lors de sa création.
L'accès aléatoire d'un élément dans un tableau est très efficace.
Les tableaux sont plus adaptés à des collections d'éléments de longueur fixe.
Tous les éléments sont du même type, par exemple :
int[] interviewArray = new int[5];
or
int[] arrayForInterview = {3, 1, 4, 1, 5};
Ces deux tableaux contiennent cinq entiers.
Vecteur
Les candidats doivent savoir quand il est approprié et possible d'utiliser ces mots clés. En particulier, ils doivent savoir que l'asynchronisation ne peut être placée avant le mot-clé de fonction sur une définition de fonction. La fonction est alors considérée comme un retour de promesse. Le mot-clé "await" ne peut être utilisé qu'à l'intérieur d'une telle fonction asynchrone et doit être placé avant un appel à une fonction qui rendra une Promesse.
Les éléments d'une liste peuvent être ajoutés ou supprimés, ce qui signifie que la taille de la liste peut changer. Les méthodes permettent de nombreux types de manipulations, y compris l'insertion ou la suppression dans un index spécifique. Les plages peuvent également être manipulées.
La Liste est une interface, donc quand on manipule une Liste, une vraie classe, généralement ArrayList, est utilisée en coulisse
Une liste repose sur les méthodes de tri de Collections, telles que Collections.sort().
Les méthodes de recherche contain(), indexOf(), et lastIndexOf() sont des exemples qui peuvent être utilisés pour rechercher les éléments. Cependant, pour effectuer une recherche binaire, il faut appeler la méthode plus générale : Collections.binarySearch(...)
Les listes peuvent contenir des objets de type mixte, par exemple :
List interviewList = new ArrayList();
interviewList.add(3);
interviewList.add(1415);
interviewList.add(“Pi”);
Bonus
Les tableaux peuvent stocker des objets, il existe donc une solution de rechange pour ceux qui sont enclins à mélanger les types dans un tableau. De plus, le candidat doit être crédité de savoir que les Listes remplacent les Vecteurs qui ne sont plus couramment utilisés en Java. La raison est liée à la simultanéité et à la synchronisation des opérations. Il est clair qu'une explication plus détaillée dépasse la portée de cette question - cependant, la mention de ce point est digne d'intérêt.
Mauvaise réponse
Les tableaux et les listes, parmi d'autres classes et interfaces intégrées, y compris les collections, sont très courants dans la programmation Java et le développement d'applications. Un candidat qui n'est pas à l'aise avec ces fonctionnalités manque presque certainement d'expérience avec le langage.
Contrairement au C++, Java ne prend pas en charge l'héritage multiple. Comment la programmation avec une interface apportera-t-elle une réponse à ce problème ? Une interface fait-elle partie de la hiérarchie des classes ?
Justification
S'il existe des points communs entre les langues que de nombreux programmeurs connaissent bien, il existe aussi des distinctions qui permettent de les définir. Dans un entretien en Java, il y aura des questions de base en Java qui aideront à évaluer dans quelle mesure le candidat connaît les spécificités du langage de programmation Java. Étant donné la question du problème du diamant en C++, il est intéressant de tester les connaissances du candidat dans une perspective java.
Bonne réponse
Une interface est similaire à une classe en ce sens qu'elle peut contenir différents types de méthodes, mais différente parce qu'elle ne détient pas l'état. Les interfaces sont intrinsèquement abstraites, et leurs méthodes doivent être implémentées par une classe. L'interface n'est pas instanciée, elle est implémentée. Contrairement au C++, une classe ne peut étendre qu'un seul parent (c'est-à-dire qu'elle ne peut avoir qu'une seule superclasse). Une interface, en revanche, est capable d'étendre plus d'une interface parent. Par exemple :
public interface CheckerBoard {
public void setSize(int rowCount, int columnCount);
}
public interface Game {
public void setNumberOfPlayers();
public void play();
}
public interface ChessGame extends CheckerBoard, Game {}
Dans cet exemple, l'interface ChessGame hérite à la fois de CheckerBoard et de Game.
Mauvaise réponse
Si la personne interrogée ne sait pas ce qu'est l'héritage multiple, cela suggère un manque d'expérience en matière de conception orientée objet. Cela n'est pas essentiel pour toutes les applications, bien qu'il soit important de reconnaître que java est intrinsèquement OO.
Qu'est-ce que la machine virtuelle Java ? Quel en est l'objectif principal et avec quel type de code fonctionne-t-elle ?
Justification
Aucune interview en Java ne serait complète sans une question sur le thème de la machine virtuelle. La JVM est un élément clé de Java, et les programmeurs java l'apprennent très tôt. Si la JVM est capable d'exécuter du bytecode généré par d'autres langages, tels que JRuby et Jython, cela n'enlève rien au fait qu'elle est essentielle à la java elle-même.
Bonne réponse
La JVM est une machine virtuelle qui permet à l'ordinateur d'exécuter des programmes Java qui ont été compilés en bytecode. Le bytecode est indépendant de la plateforme, et s'exécute sur tout ordinateur qui héberge une JVM. Il comprend un compilateur juste à temps (JIT) qui convertit le bytecode en instructions en langage machine, permettant aux applications de s'exécuter aussi rapidement qu'un exécutable natif.
Mauvaise réponse
La JVM est l'un des principaux composants qui font de Java ce qu'il est. Le fait de ne pas connaître la JVM indique probablement un manque d'expérience avec le langage.
Quelles sont les méthodes et les classes finales ? Une classe abstraite supportera-t-elle les méthodes finales ?
Justification
Le dernier mot-clé est commun et doit être bien compris par les programmeurs java. Au cours de la phase de conception OO, il est normalement décidé si les classes doivent être extensibles. Si ce n'est pas le cas, elles sont marquées comme finales afin de limiter les effets secondaires potentiels de sous-classes qui n'ont pas été envisagées. Il s'agit d'une caractéristique importante qui devrait être utilisée pour un code plus robuste et plus facile à maintenir.
Bonne réponse
Une méthode qui est déclarée avec le mot-clé final ne peut pas être annulée dans les sous-classes. Cette méthode est utilisée dans les hiérarchies où la mise en œuvre de la méthode doit être cohérente dans l'ensemble. La déclaration finale d'une classe interdit totalement le sous-classement. Oui, il est possible d'inclure des méthodes finales dans une classe abstraite. Cela permet de s'assurer que les sous-classes ne peuvent pas passer outre la méthode.
Mauvaise réponse
Si le candidat n'est pas familier avec le mot-clé final, qu'il soit utilisé au niveau de la classe ou de la méthode, alors cela suggère une relative inexpérience de la langue. Même pour les programmeurs inexpérimentés qui ont participé à la conception orientée objet, le concept de classe finale devrait être familier.
La programmation Java permet de créer un fil de discussion de différentes manières. Quelles sont-elles et quelle est la méthode préférée ? Expliquez.
Justification
Contrairement au C++, java contient un support intégré pour le multithreading. C'est une fonctionnalité riche et puissante qui est à la fois pertinente et utile dans de nombreuses applications. En tant que tel, le candidat doit être familier avec les bases.
Bonne réponse
Que se passe-t-il dans le cas où la réduction est appelée sur un tableau vide sans fournir la valeur initiale facultative de l'accumulateur ?
public class JavaInterviewClass implements Runnable {
public void run() {
System.out.println(“My example public class prints this line from a thread.”);
}
}
Pour exécuter la méthode run(), passez une instance de la classe dans un Thread, comme suit :
Thread interviewThread = new Thread(new JavaInterviewClass ());
interviewThread.start();
La deuxième façon de créer un fil de discussion est d'étendre la classe de fil de discussion. La sous-classe remplacera la méthode run(). Après cela, il suffit de créer une instance de la classe.
public class JavaInterviewClass extends Thread {
public void run() {
System.out.println(“My example public class extends the Thread class.”);
}
}
Pour exécuter le fil de discussion, il suffit d'instancier la classe et d'appeler start(), comme suit :
JavaInterviewClass myInterview = new JavaInterviewClass (); myInterview.start();
Bonus
Bien que l'implémentation de l'interface exécutable et l'extension de la classe Thread soient deux moyens populaires de créer un thread, il est également possible d'utiliser le framework Executor. Celui-ci permet de travailler directement avec les threads, mais il est moins connu. Il comprend des méthodes telles que newSingleThreadExecutor(), newFixedThreadPool() et submit() pour créer des tâches d'exécution. La connaissance de l'utilisation du framework Executor implique que le candidat soit très à l'aise avec la création et l'utilisation de threads en java.
Mauvaise réponse
Si le candidat n'est pas à l'aise avec l'utilisation des fils de discussion, il passe à côté d'une caractéristique puissante et importante de la langue. C'est important car comprendre le multithreading ne se limite pas à rechercher la syntaxe de quelques commandes. Il s'agit plutôt d'une approche qui doit être envisagée lors de la conception et du développement d'une application.
Le code Java a un support intégré pour la concurrence dans sa classe Thread. La simultanéité a son propre ensemble de problèmes tels que l'impasse et les conditions de course. Décrivez brièvement les variables Atomic en Java et leur utilisation. Ensuite, il est indiqué que la méthode start() est utilisée pour créer une pile d'appels séparée avant que la méthode run() ne soit utilisée pour exécuter un thread. Que font les méthodes yield(), sleep() et join() ?
Justification
La prise en charge du multithreading par Java peut entraîner des problèmes liés à la concurrence. Les connaissances du candidat concernant ces problèmes doivent être évaluées et prises en compte.
Bonne réponse
Une variable atomique est une variable "mise à jour atomique", ce qui signifie que l'intégrité des données est assurée par l'utilisation d'algorithmes non bloquants. Cette fonctionnalité est généralement mise en œuvre au niveau du code machine. Java prend en charge plusieurs variables atomiques, le plus souvent AtomicBoolean, AtomicInteger, AtomicLong et AtomicReference. Il existe également plusieurs méthodes qui permettent de récupérer et de modifier ces variables, notamment get(), set(), lazySet(), compareAndSet() et weakCompareAndSet(). Utilisées correctement, les variables atomiques peuvent être utilisées pour mettre en œuvre des méthodes "thread safe" (multithreading safe) qui traitent efficacement certains problèmes liés à la concurrence.
rendement() : Cette méthode informe l'environnement que le fil de discussion actuel n'est pas en train d'achever une tâche de haute priorité, et est prêt à en interrompre l'exécution. À condition que l'environnement sous-jacent supporte l'ordonnancement préventif, elle suspendra le fil s'il y en a un autre qui doit s'exécuter. S'il n'y a pas de deuxième fil, ou si le deuxième fil se termine, le fil en cours reprendra le contrôle et continuera à s'exécuter.
sommeil() : Cette méthode fait dormir le fil courant, ou met en pause son exécution, pendant un nombre de millisecondes déterminé. Il est également possible de combiner un certain nombre de millisecondes et de nanosecondes. Pendant que le fil courant est en sommeil, un autre fil sera exécuté, ou sinon le CPU restera inactif. Sous réserve de la précision de l'horloge du système et des minuteurs, le fil de discussion reprendra le contrôle une fois le compte à rebours terminé.
join() : Cette méthode est utilisée pour joindre deux l'exécution de deux fils ensemble. Pour clarifier, si le fil A appelle join() sur le fil B, alors A commencera à attendre. Une fois que B a terminé, ou qu'un délai prédéfini a expiré, A reprendra le contrôle et continuera l'exécution.
Mauvaise réponse
Le fait de connaître les fils de discussion Java, mais de ne pas être conscient des problèmes liés à la concurrence peut entraîner de graves erreurs. La majorité des appareils, des ordinateurs de bureau aux appareils mobiles en passant par les ordinateurs à carte unique, prennent désormais généralement en charge le multithreading et la concurrence. Il est important de comprendre la bonne utilisation des threads, et d'être conscient des méthodes fournies par java pour les prendre en charge.
Conclusion
Les questions de cet article sont utiles pour évaluer les compétences d'un futur programmeur Java. En ce qui concerne les questions d'entretien à préparer pour un développeur Java, il est important de se rappeler que les spécificités du langage peuvent être facilement référencées en utilisant l'aide et la documentation en ligne. Les points subtils d'un langage ne sont pas aussi importants que la façon dont on applique la logique. Cela dit, les candidats à ce poste sont censés connaître le langage et ne pas avoir besoin d'une formation approfondie avant que le travail réel ne commence. Les compétences requises seront dictées par le travail à effectuer, et la variation des questions données ci-dessus aidera à faire cette évaluation. N'oubliez pas que l'une des meilleures façons d'évaluer les compétences du candidat pour votre projet est d'effectuer une évaluation pratique de la programmation, ce qui est bien plus efficace que des questions d'entretien orales pour engager un programmeur Java hautement qualifié.
Questions d’entretien pour recruter un développeur Java
Généralement, lorsque l’on parle de préparation pour l’entretien d’embauche d’un développeur Java, l’accent est mis sur le point de vue de la personne recrutée. Les candidats veulent savoir à quels types de questions ils doivent s’attendre afin de se préparer au mieux. Pourtant, en prenant un angle différent, on peut se demander : quelles questions un recruteur à la recherche d’un développeur Java doit-il poser aux candidats afin d’évaluer au mieux leurs compétences techniques ?
Dans une entreprise développant des logiciels, que le langage de programmation Java ou la programmation orientée objet en général soit un standard ou non, il est facile de trouver des questions de programmation et leurs réponses. Il est chose aisée d’utiliser Google pour rechercher la syntaxe du langage en question afin de faciliter la rédaction d’un entretien d’embauche sur Java.
Avant de commencer, voici une définition rapide du terme Java qui devrait vous aider si ce langage ne vous est pas entièrement familier :
Java is a high-level programming language developed by Sun Microsystems. It was originally designed for developing programs for set-top boxes and handheld devices, but later became a popular choice for creating web applications.
The Java syntax is similar to C++, but is strictly an object-oriented programming language. For example, most Java programs contain classes, which are used to define objects, and methods, which are assigned to individual classes. Java is also known for being more strict than C++, meaning variables and functions must be explicitly defined. This means Java source code may produce errors or “exceptions” more easily than other languages, but it also limits other types of errors that may be caused by undefined variables or unassigned types.
Christensson, P., Définition Java, techterms.com
Le but de cet article est d’aider à préparer le recruteur, quelle que soit son expérience avec Java. Déterminer quel candidat parmi tant d’autres a offert la meilleure performance lors d’un entretien sur Java n’est pas une tâche facile lorsque l’on ne dispose pas de compétences avancées en programmation. Dans le même temps, il faut savoir que ce candidat parfait ne sera pas trouvé à l’aide de questions d’entretien purement liées au code. La programmation est souvent une question de logique, par opposition à la syntaxe, et ce serait une grave erreur de pénaliser trop lourdement les candidats parce qu’ils ne sont pas familiers avec une problématique pouvant être aisément solutionnée à l’aide de Google.
Cela dit, il est important de se rappeler que l’entretien doit aboutir à un poste de développeur Java. Le candidat doit connaître l’environnement d’exécution Java (JRE), la machine virtuelle Java (JVM) et le kit de développement Java (JDK), etc. Les bibliothèques couramment utilisées telles que java lang, java util ne devrait pas être un mystère pour eux. De même, alors qu’elle n’est plus utilisée, la bibliothèque Swingdevrait au moins leur être familière (alors qu’il est acceptable de ne pas connaître la bibliothèque Awt, qui est totalement obsolète. Enfin, les candidats doivent au moins être au courant de l’existence de frameworks et d’autres technologies tels que Spring framework, JavaServer Pages (JSP), et Java Database Connectivity (JDBC).
Les questions d'entretien Java doivent être spécifiques à certains égards, mais générales à d'autres. Par exemple, est-il nécessaire d'inclure des questions d'entretien JDBC spécifiques ? Peu probable. Cependant, un candidat doit absolument savoir ce qu'est une interface de la Liste.
Avec autant d'objectifs concurrents, comment trouver le candidat idéal ? La réponse réside dans un large éventail de questions d'entretien qui couvrent le sujet sous plus d'un angle. Cet article vise à répondre à ces préoccupations en fournissant la question d'entretien de Java, la ou les réponses correctes, et la raison pour laquelle chaque question est posée.
Consultez la question Java ci-dessous. Il existe plusieurs façons de la résoudre, de sorte que les choix du candidat peuvent révéler sa façon de coder. Comment la résoudriez-vous ? Cliquez sur l'onglet "Instructions" et essayez :
Questions de programmation de différents niveaux et leurs réponses
Cet article contient 14 questions d’entretien et leurs réponses. Les 5 premières sont niveau débutant, tandis que les autres varient à la fois en termes de sujet et de niveau de difficulté. Un score parfait ne sera pas nécessairement obtenu en répondant à chaque question parfaitement. Au contraire, la discussion sur les solutions donnera le meilleur indicateur à la fois de la capacité de réflexion du candidat et de l’expérience qu’il a accumulée.
Questions de programmation Java niveau débutant
1 - Le code Java prévoit des méthodes de classe avec des spécificateurs d'accès public et privé. Quelle est la différence entre ces deux modificateurs ?
Justification
Dans la programmation orientée objet, il est courant de limiter la portée des variables et des fonctions à des classes spécifiques dans une hiérarchie de classes. Ceci est réalisé à l’aide de différents spécificateurs d’accès, et connaître la différence entre ces composants fondamentaux est une question d’entretien Java très pertinente.
En Java, les classes peuvent être uniquement déclarées publiques, ou bien pas du tout – alors que les fonctions membres ont quatre modificateurs différents – c’est donc un sujet qui peut s’avérer épineux pour les grands débutants.
Bonne réponse
Un spécificateur d’accès public ordonne que la méthode soit accessible à la fois à l’intérieur et à l’extérieur de la classe. Ceci est vrai tant que la classe elle-même est déclarée publique, ou que la classe appelante est dans le même package. Si la classe ne spécifie pas de modificateur, elle est supposée avoir un accès par défaut (package), et les déclarations de ses méthodes ne l’écrasent pas.
Un spécificateur d’accès privé indique que la méthode doit être accessible uniquement à l’intérieur de la classe.
Bonus
Si le candidat sait qu'il existe également des spécifications pour les produits protégés et les emballages (par défaut), il démontre alors une bonne compréhension de ce sujet.
Mauvaise réponse
Si le candidat ne connaît pas la différence entre public et private, cela indique un manque d’expérience à propos de Java et probablement dans d’autres langages orientés objet tels que C++. Si la réponse est correcte, mais qu’il n’est pas fait mention du fait que le modificateur de classe l’emporte sur les méthodes, le candidat devrait être pénalisé.
Considérons le code suivant qui contient une classe, une variable statique et une méthode publique. Combien de bouchées ont été prises pour chaque pomme ?
public class Apple {
static int bites = 0;
public void takeBite() {
bites++;
}
public static void main(String[] args) {
// Instantiate red and green apples for our example public class
Apple macintosh = new Apple();
Apple grannySmith = new Apple();
// Take a bite out of each of the two apples
macintosh.takeBite();
grannySmith.takeBite();
// Display the contents of each class
System.out.println("The Macintosh apple has " + macintosh.bites + " bite(s) out of it.");
System.out.println("The Granny Smith apple has " + grannySmith.bites + " bite(s) out of it.");
}
}
Justification
Les variables statiques sont une caractéristique de Java régulièrement utilisée par les développeurs. Comme c’est le cas pour les variables globales, il est important pour les programmeurs de comprendre la portée de ces objets afin d’éviter un quelconque effet collatéral. Note à propos de la non-déclaration d’une variable : cela permet d’éviter de mal taper le nom d’une variable, car la variable mal orthographiée apparaîtra comme une nouvelle variable non déclarée.
Bonne réponse
La classe Apple partage la variable statique, bites, entre toutes ses instances. Par conséquent, lorsque la méthode takeBite() est appelée sur chacune des instances, la variable commune est mise à jour. Le résultat final se présente ainsi :
The Macintosh apple has 2 bite(s) out of it.
The Granny Smith apple has 2 bite(s) out of it.
Mauvaise réponse
Si le candidat répond que chacune des deux instances s’est vue retirée une seule bouchée (bite), cela indique un manque d’expérience avec les variables statiques. Ce sujet est trivial, mais un développeur Java le rencontrera fréquemment. Le fait de ne pas en avoir connaissance indique que le candidat manque probablement d’expérience pratique du langage.
Qu'est-ce qu'une exception ? Décrivez brièvement les deux types d'exception utilisés dans le code java.
Justification
Les exceptions sont des événements inattendus qui surviennent au moment de l’exécution et qui diffèrent des erreurs dans la mesure où il est généralement aisé de les « rattraper ». Les erreurs, par contre, indiquent généralement un problème plus grave. La gestion des exceptions est très courante et doit être comprise, au moins à un niveau de base, par n’importe quel programmeur Java.
Bonne réponse
Les deux types d’exceptions dans Java sont les exceptions vérifiées et les exceptions non-vérifiées.
Une exception vérifiée est une exception qui est vérifiée au moment de la compilation. Lorsqu’il y a du code dans une méthode qui lève une exception vérifiée, la méthode est nécessaire pour l’acquitter. Ceci peut être accompli soit en gérant l’exception avec un bloc try/catch, soit en la spécifiant à l’aide du mot-clé throws. Une exception non-vérifiée est une exception qui n’est pas vérifiée au moment de la compilation. C’est au programmeur de spécifier ce type d’exception. En revanche, il faut noter que toutes les exceptions en C++ sont non-vérifiées.
Bonus
En Java, toutes les exceptions des classes Error et RuntimeException sont décochées. Tout le reste sous Throwable est vérifié. Si la personne interrogée soulève ce point particulier, elle démontre une compréhension profonde de la question qui lui a été posée.
Mauvaise réponse
Si le candidat n’est pas au courant des exceptions, il lui manque une partie essentielle du langage qui est responsable du contrôle de l’exécution. Cette fonctionnalité représente un véritable bond en avant par rapport à des langages tels que C (qui ne supporte pas la gestion des exceptions). Bien qu’elles ne soient pas absolument indispensables, les exceptions sont extrêmement utiles au quotidien du fait de leurs nombreux avantages, tout développeur Java efficace les utilise.
Que sont les cours d'emballage ? Donnez des exemples de deux d'entre elles et des primitives correspondantes. Quel est le rapport entre chacune d'elles et un objet ?
Justification
Les classes d’emballage sont fondamentales en programmation Java. En fait, leur existence implique que java n’est pas 100% orienté objet (bonus au candidat qui le signale !). C’est le cas parce que Java contient 8 types de données primitives qui ne sont pas, par définition, des objets.
Bonne réponse
Une classe d’emballage est une classe qui contient une variable qui est un type de données primitives, et qui enveloppe la primitive pour fournir une fonctionnalité d’interaction avec elle. En fait, on peut dire qu’il transforme le primitif en objet. Ce qui est utile, par exemple, lorsqu’une méthode vise au transfert d’un objet. Le candidat doit être capable de nommer au moins deux des paires suivantes :
Primitive
Classe d'emballage
boolean
Boolean
byte
Byte
char
Char
double
Double
float
Float
int
Int
long
Long
short
Short
Mauvaise réponse
Les classes d’emballage sont définies en java.lang, et requises car il existe de nombreuses classes qui supportent uniquement les objets. Le fait de ne pas connaître ces classes d’emballage, ou de ne pas savoir pourquoi elles seraient utilisées, apparaît comme une grave lacune de la part du candidat interrogé.
Définissez les termes suivants qui sont courants dans la programmation java
Classe abstraite
Ramasse-miettes (aussi appelé récupérateur de mémoire, glaneur de cellules ou garbage collector)
Autoboxing
Sérialisation
Justification
Cette liste inclut des termes qui sont communément utilisés en Java, ainsi que dans d’autres langages de programmation. Les questions d’entretien pour les programmeurs expérimentés incluent de telles définitions parce qu’elles permettent de tester leurs connaissances de manière approfondie, ainsi que leur capacité à distinguer des langages comportant des concepts proches sans être parfaitement identiques.
Bonne réponse
Une classe abstraite est utilisée comme classe de base pour les sous-classes qui vont étendre ou écraser ses méthodes. Prenons l’exemple d’une classe « Forme ». Une forme peut contenir un certain nombre de côtés, de faces ou même de dimensions. Prise isolément, savoir que cette classe est une « Forme » est peu utile. D’autre part, si cette classe abstraite sera utilisée comme classe de base pour un « Carré », un « Triangle », ou un autre type de polygone, elle deviendra utile quand placée au sommet de la hiérarchie des classes. - Il n'est pas possible d'instancier une classe abstraite. – Elle peut contenir des méthodes abstraites, mais ce n’est pas obligatoire. - Les sous-classes de la classe d'abstraction doivent mettre en œuvre toutes les méthodes d'abstraction, à moins qu'il ne s'agisse également d'une classe d'abstraction. Il n'est pas possible d'instancier une classe abstraite.
Ne pas être parfaitement calé à propos classes abstraites n’est pas éliminatoire, bien que ces dernières seront très probablement rencontrées par le programmeur Java lorsqu’il devra effectuer des actions de maintenance ou du débogage d’une base de code existante.
La "garbage collection" (effectuée par le "garbage collector" ou ramasse-miettes) est le processus de détection et de suppression des objets en mémoire qui ne sont plus utilisés ou référencés. En java, le ramassage des miettes est automatique, mais il peut aussi être demandé.
Les commandes System.gc() et Runtime.gc() indiqueront au ramasse-miettes qu’il doit s’exécuter, bien que cela ne soit pas garanti.
Les fils d’exécution sont mis en pause pendant le ramassage des ordures. Cela ralentit nécessairement l’exécution, ce qui signifie que dans les applications réactives, le ramassage des miettes doit être réduit au minimum. La connaissance du ramasseur de miettes n’est pas indispensable, surtout pour un programmeur débutant. Il est à noter, cependant, que lorsqu’on vient d’un langage comme C, où toute la mémoire est gérée manuellement, le développeur doit être au courant de l’existence de cette fonctionnalité.
L’Autoboxing est l’emballage automatique d’un type primitif (voir la question #4 relative aux types primitifs et classes d’emballages). Par exemple, l’autoboxing convertira automatiquement un nombre de type float (type primitif) en Float (classe d’emballage). Le contraire de cela est le déballage, lors duquel type primitif est extrait de la classe d’emballage. Cette notion est habituellement familière aux bons développeurs Java.
La sérialisation fait référence à l’encodage d’objets en mémoire dans un flux d’octets qui pouvant être facilement stockés ou transmis. Le contraire est la désérialisation, qui reconstruit les objets à partir d’un flux d’octets. Il existe différentes approches pour réaliser la sérialisation. Deux méthodes courantes sont la conversion de l’objet en XML (eXtensible Markup Language), ou JSON (JavaScript Object Notation). Ce sont des types de fichiers bien connus, chacun d’entre eux étant largement pris en charge. Java supporte également la sérialisation comme partie intégrante du langage. Le langage inclut l’interface sérialisable, qui peut être utilisée à la fois pour la sérialisation et la désérialisation. La méthode writeObject() est utilisée pour encoder les données, tandis que la méthode readObject() est utilisée pour reconstruire les objets.
Java définit une classe String pour représenter des tableaux de caractères. Répondez aux questions suivantes :
Un constructeur initialise un objet lors de sa création. Cependant, les constructeurs n'ont pas de type de retour explicite.
En général, vous utiliserez un constructeur pour donner des valeurs initiales aux variables d'instance définies par la classe, ou pour effectuer toute autre procédure de démarrage nécessaire pour créer un objet entièrement formé.
Toutes les classes ont des constructeurs, que vous en définissiez un ou non, car Java fournit automatiquement un constructeur par défaut qui initialise toutes les variables membres à zéro. Cependant, une fois que vous avez défini votre propre constructeur, le constructeur par défaut n'est plus utilisé.
Pourriez-vous citer quelques cadres de travail Java ?
Cette question d'entretien est une question de base : tout développeur Java compétent est en mesure de nommer quelques frameworks écrits en langage Java. Au cours de l'entretien, le candidat interrogé doit mentionner au moins trois frameworks Java parmi cette liste :
JSF (Java Server Faces), un cadre web Java qui facilite la construction d'interfaces utilisateur pour les applications basées sur des serveurs
GWT (Google Web Toolkit), un ensemble d'outils open-source qui aide les programmeurs à créer et à maintenir des applications JavaScript dans Java Spring, un framework Java qui n'impose aucun modèle de programmation spécifique
Struts
Hiberner
Grails
Jouez !
Vaadin
Maven
Questions d'entretien sur la programmation mixte
Java définit une classe String pour représenter des tableaux de caractères. Répondez aux questions suivantes :
- Par quoi faut-il remplacer le "XXX" pour pouvoir comparer les deux principaux arcs de cordes ? Si les arguments sont : "Sun Microsystems" et "Sun microsystems", quel sera le résultat de l'exécution ? Y a-t-il un moyen de garantir qu'il les déclarera comme étant identiques ? - Si les arguments sont plutôt : "Sun Microsystems" et "Sun Microsystems", quel sera le résultat de l'exécution ? "Sun Microsystem" et "Sun Microsystems", quel sera le résultat de l'exécution ?
1/ Après la création d'une chaîne, est-il possible de la modifier ? Considérez ce qui suit :
public static void main(String[] args) { String name = "James gosling"; // I want to change the 'g' to a 'G'. // Will this work at compile time? name.charAt(6) = 'G'; // Print with the standard system println to see “James Gosling” System.out.println(name); }
Cela va-t-il fonctionner ? Si ce n'est pas le cas, quelles modifications faudrait-il apporter pour obtenir la chaîne souhaitée ?
2/ La classe String a plus d'un Comparateur. Considérez le code suivant :
public static void main(String[] args) { // This program received 2 arguments. We want to // determine if those two strings are equal. // Compare the first argument to the second argument boolean compareResult = (XXX); if (compareResult) { System.out.println("The Strings are the same."); } else { System.out.println("The Strings are not the same."); } // Print the main string args System.out.println(args[0]); System.out.println(args[1]); }
- Par quoi faut-il remplacer le "XXX" pour pouvoir comparer les deux principaux arcs de cordes ? Si les arguments sont : "Sun Microsystems" et "Sun microsystems", quel sera le résultat de l'exécution ? Y a-t-il un moyen de garantir qu'il les déclarera comme étant identiques ? - Si les arguments sont plutôt : "Sun Microsystems" et "Sun Microsystems", quel sera le résultat de l'exécution ? "Sun Microsystem" et "Sun Microsystems", quel sera le résultat de l'exécution ?
3/ Qu'est-ce que le pool de constantes de la chaîne Java ? (ou pool de chaînes de caractères Java) ? Il réside dans la mémoire de la pile ?
Justification
L'utilisation de représentations de chaînes de caractères est courante dans de nombreux langages, et Java ne fait pas exception. Il est important de comprendre comment les chaînes de caractères sont créées, analysées, imprimées et manipulées. C'est un sujet important qui constitue une question d'entretien importante pour les développeurs Java.
Bonne réponse
Non, cela échouera au moment de la compilation car il n'est pas possible de modifier une chaîne une fois qu'elle a été initialisée. Cette propriété est dite immuable. Pour que cela fonctionne, il faudrait recréer la chaîne contenant "James gosling". Une approche consiste à utiliser un tableau de caractères intermédiaires (en appelant la méthode toCharArray() sur le "nom"), à remplacer le "g" par la lettre majuscule, puis à recréer la chaîne avant de l'imprimer. Un bonus pour le candidat qui souligne que la fonction string replace(...) existe pour remplacer les caractères, mais ne peut pas être utilisée car toutes les instances de "g" minuscules seraient remplacées.
Le comparateur exact dans cet exemple est soit égal(...) soit égalIgnoreCase(...). Le type de retour de ces deux méthodes est une valeur booléenne. Si la personne interrogée répond compareTo(...) ou compareToIgnoreCase(...), alors le crédit devrait être accordé, bien que le type de retour de ces méthodes soit un int, donc techniquement incorrect. Il n'en reste pas moins qu'elle démontre une connaissance de la langue.
Dans le premier exemple, les chaînes sont identiques sous equalsIgnoreCase(...), mais différentes sous equals(...). Dans le deuxième exemple, il y a un "s" à la fin, ce qui fait que les chaînes sont différentes dans tous les cas.
Le Java Constant String Pool est une zone de la mémoire du Heap (donc, pas de la mémoire de la pile) où sont stockées les chaînes de caractères. Cette approche est à l'origine de la raison pour laquelle les chaînes sont immuables en java.
Par exemple :
chaîne x = "chaîne principale" ;
chaîne de caractères y = "machine virtuelle" ;
chaîne z = "chaîne principale" ;
Les trois cordes ci-dessus sont stockées dans le pool de cordes, mais la partie intéressante est l'efficacité. x et y pointent tous deux vers la même zone dans la réserve de cordes, ce qui ne nécessite pas de duplication de l'espace. Sachant cela, il doit être clair que la modification de la valeur de x n'est pas autorisée car elle aurait l'effet secondaire non voulu de modifier z.
Quelles sont les différences entre la mémoire Stack et l'espace Heap ?
Justification
Afin d'améliorer l'efficacité, la JVM organise la mémoire pour que les applications puissent s'exécuter. Elle crée de l'espace de pile et de l'espace de tas, chacun étant utilisé par des opérations différentes. Comprendre l'allocation de la mémoire à ce niveau peut conduire à un ramassage des déchets plus prévisible et, en fin de compte, à une efficacité accrue.
Bonne réponse
La mémoire en pile est utilisée pour l'allocation de mémoire statique, comme les valeurs primitives à l'intérieur d'une méthode. Elle est toujours utilisée pour l'exécution d'un thread. La pile s'agrandit lorsque les méthodes sont appelées, et se réduit lorsqu'elles reviennent. Si la mémoire allouée pour la pile est dépassée, l'exception java.lang.StackOverFlowError est lancée.
La mémoire de tas est utilisée pour l'allocation de mémoire dynamique, comme les objets java. Plus précisément, l'objet est stocké dans le tas, tandis que la référence à l'objet est stockée dans la pile. Les classes JRE sont également stockées dans le tas au moment de l'exécution. L'accès aux données dans le tas est plus lent que dans la mémoire de la pile. Le tas requiert l'action du collecteur de déchets afin de libérer les objets inutilisés. Si la mémoire allouée au tas est dépassée, l'exception java.lang.OutOfMemoryError est lancée.
Mauvaise réponse
Le fait de n'avoir jamais entendu parler de la pile ou du tas indiquerait une connaissance superficielle du langage de programmation java. De plus, la terminologie est typique d'une culture générale de programmation. Le diagnostic des erreurs liées à la mémoire, telles qu'un débordement de pile causé par un comportement incorrect d'une fonction récursive, serait plus facile avec cette compréhension.
Deux termes liés à la classe utilisés dans la programmation java sont "subclass" et "nested class". Expliquez les différences entre ces deux termes. Pourquoi choisir l'une plutôt que l'autre ? Laquelle est parfois appelée "classe intérieure" ?
Justification
Dans la conception orientée objet, il y a souvent une confusion sur le placement des classes dans la hiérarchie. Les classes imbriquées sont relativement rares par rapport aux sous-classes, mais leur utilisation est bénéfique dans de nombreuses situations. La connaissance de leur existence et de leur mode d'utilisation doit être considérée comme un atout.
Bonne réponse
Une sous-classe est une extension d'une autre classe, et est souvent une spécialisation de l'original. Les sous-classes héritent des membres publics et protégés de leur super-classe. Les sous-classes peuvent être instanciées indépendamment de la superclasse, et en fait, c'est toujours le cas lorsque la superclasse est une classe abstraite.
Une classe imbriquée est une classe à l'intérieur d'une classe, qui dans certains cas est une classe intérieure. Le champ d'application de la classe intérieure comprend tous les membres de sa classe extérieure, ce qui lui donne accès à ces variables et méthodes. Comme le corps existe entièrement au sein de la classe englobante, il ne peut pas être instancié indépendamment, sans elle.
L'utilisation d'une classe interne peut améliorer la conception orientée objet en organisant davantage le code. L'objectif est limité dans la mesure où il existe pour servir sa classe englobante. Si la classe interne offre des fonctionnalités utiles à une plus grande échelle, il serait plus logique de l'avoir comme classe de haut niveau. Les classes internes sont couramment utilisées comme fonctions de rappel pour les composants de l'interface graphique.
Bonus
Il existe deux types de classes imbriquées. Plus précisément, il existe une classe imbriquée statique, qui n'a pas directement accès aux autres membres de la classe englobante. Celles-ci ne sont pas souvent utilisées, c'est pourquoi le fait de les connaître est un bonus par opposition à l'ignorance qui peut entraîner une pénalité. L'autre type est une classe imbriquée non statique, qui est la version que l'on appelle une classe intérieure. Ceux-ci ont en effet accès à tous les membres de la classe englobante, y compris aux méthodes privées.
Mauvaise réponse
Le candidat doit être pardonné de n'avoir jamais utilisé une classe imbriquée. Bien qu'utile, et susceptible d'être vu si l'on maintient une base de code existante, le concept est simple. Les classes imbriquées rendent souvent le code plus élégant et plus facile à maintenir, mais certains concepteurs considèrent que c'est une question de style. Les sous-classes, d'autre part, sont un élément fondamental de la programmation orientée objet que tout développeur java devrait connaître. Ne pas pouvoir discuter facilement des sous-classes au sein d'une hiérarchie de classes est un sérieux signal d'alarme.
Deux classes de collection sont disponibles en programmation java : Array et List. En quoi les méthodes diffèrent-elles entre ces deux objets conteneurs, et dans quelles circonstances choisiriez-vous l'une plutôt que l'autre ?
Justification
L'utilisation de conteneurs est courante en Java et dans d'autres langages de programmation. La liste est une structure de données dynamique, tandis que le tableau est statique. Il est important de reconnaître que chacun d'entre eux est mieux adapté à certaines applications, et à ce titre, le candidat doit les connaître. Avoir une connaissance approfondie des types de données et des classes de conteneurs disponibles permettra en fin de compte de gagner du temps de développement.
Bonne réponse
Array
Les tableaux sont de taille statique, ils ne peuvent donc ni croître ni diminuer en termes de nombre d'éléments. Cela signifie qu'il existe des méthodes pour accéder aux éléments et les modifier, mais pas pour les insérer ou les supprimer.
Java fournit des méthodes pour effectuer une recherche binaire ou un tri sur un tableau. De plus, un tableau peut être initialisé en utilisant la méthode fill(), ou comparé en utilisant le comparateur equals().
La taille d'un tableau est fixée lors de sa création.
L'accès aléatoire d'un élément dans un tableau est très efficace.
Les tableaux sont plus adaptés à des collections d'éléments de longueur fixe.
Tous les éléments sont du même type, par exemple :
int[] interviewArray = new int[5];
or
int[] arrayForInterview = {3, 1, 4, 1, 5};
Ces deux tableaux contiennent cinq entiers.
Vecteur
Les candidats doivent savoir quand il est approprié et possible d'utiliser ces mots clés. En particulier, ils doivent savoir que l'asynchronisation ne peut être placée avant le mot-clé de fonction sur une définition de fonction. La fonction est alors considérée comme un retour de promesse. Le mot-clé "await" ne peut être utilisé qu'à l'intérieur d'une telle fonction asynchrone et doit être placé avant un appel à une fonction qui rendra une Promesse.
Les éléments d'une liste peuvent être ajoutés ou supprimés, ce qui signifie que la taille de la liste peut changer. Les méthodes permettent de nombreux types de manipulations, y compris l'insertion ou la suppression dans un index spécifique. Les plages peuvent également être manipulées.
La Liste est une interface, donc quand on manipule une Liste, une vraie classe, généralement ArrayList, est utilisée en coulisse
Une liste repose sur les méthodes de tri de Collections, telles que Collections.sort().
Les méthodes de recherche contain(), indexOf(), et lastIndexOf() sont des exemples qui peuvent être utilisés pour rechercher les éléments. Cependant, pour effectuer une recherche binaire, il faut appeler la méthode plus générale : Collections.binarySearch(...)
Les listes peuvent contenir des objets de type mixte, par exemple :
List interviewList = new ArrayList();
interviewList.add(3);
interviewList.add(1415);
interviewList.add(“Pi”);
Bonus
Les tableaux peuvent stocker des objets, il existe donc une solution de rechange pour ceux qui sont enclins à mélanger les types dans un tableau. De plus, le candidat doit être crédité de savoir que les Listes remplacent les Vecteurs qui ne sont plus couramment utilisés en Java. La raison est liée à la simultanéité et à la synchronisation des opérations. Il est clair qu'une explication plus détaillée dépasse la portée de cette question - cependant, la mention de ce point est digne d'intérêt.
Mauvaise réponse
Les tableaux et les listes, parmi d'autres classes et interfaces intégrées, y compris les collections, sont très courants dans la programmation Java et le développement d'applications. Un candidat qui n'est pas à l'aise avec ces fonctionnalités manque presque certainement d'expérience avec le langage.
Contrairement au C++, Java ne prend pas en charge l'héritage multiple. Comment la programmation avec une interface apportera-t-elle une réponse à ce problème ? Une interface fait-elle partie de la hiérarchie des classes ?
Justification
S'il existe des points communs entre les langues que de nombreux programmeurs connaissent bien, il existe aussi des distinctions qui permettent de les définir. Dans un entretien en Java, il y aura des questions de base en Java qui aideront à évaluer dans quelle mesure le candidat connaît les spécificités du langage de programmation Java. Étant donné la question du problème du diamant en C++, il est intéressant de tester les connaissances du candidat dans une perspective java.
Bonne réponse
Une interface est similaire à une classe en ce sens qu'elle peut contenir différents types de méthodes, mais différente parce qu'elle ne détient pas l'état. Les interfaces sont intrinsèquement abstraites, et leurs méthodes doivent être implémentées par une classe. L'interface n'est pas instanciée, elle est implémentée. Contrairement au C++, une classe ne peut étendre qu'un seul parent (c'est-à-dire qu'elle ne peut avoir qu'une seule superclasse). Une interface, en revanche, est capable d'étendre plus d'une interface parent. Par exemple :
public interface CheckerBoard {
public void setSize(int rowCount, int columnCount);
}
public interface Game {
public void setNumberOfPlayers();
public void play();
}
public interface ChessGame extends CheckerBoard, Game {}
Dans cet exemple, l'interface ChessGame hérite à la fois de CheckerBoard et de Game.
Mauvaise réponse
Si la personne interrogée ne sait pas ce qu'est l'héritage multiple, cela suggère un manque d'expérience en matière de conception orientée objet. Cela n'est pas essentiel pour toutes les applications, bien qu'il soit important de reconnaître que java est intrinsèquement OO.
Qu'est-ce que la machine virtuelle Java ? Quel en est l'objectif principal et avec quel type de code fonctionne-t-elle ?
Justification
Aucune interview en Java ne serait complète sans une question sur le thème de la machine virtuelle. La JVM est un élément clé de Java, et les programmeurs java l'apprennent très tôt. Si la JVM est capable d'exécuter du bytecode généré par d'autres langages, tels que JRuby et Jython, cela n'enlève rien au fait qu'elle est essentielle à la java elle-même.
Bonne réponse
La JVM est une machine virtuelle qui permet à l'ordinateur d'exécuter des programmes Java qui ont été compilés en bytecode. Le bytecode est indépendant de la plateforme, et s'exécute sur tout ordinateur qui héberge une JVM. Il comprend un compilateur juste à temps (JIT) qui convertit le bytecode en instructions en langage machine, permettant aux applications de s'exécuter aussi rapidement qu'un exécutable natif.
Mauvaise réponse
La JVM est l'un des principaux composants qui font de Java ce qu'il est. Le fait de ne pas connaître la JVM indique probablement un manque d'expérience avec le langage.
Quelles sont les méthodes et les classes finales ? Une classe abstraite supportera-t-elle les méthodes finales ?
Justification
Le dernier mot-clé est commun et doit être bien compris par les programmeurs java. Au cours de la phase de conception OO, il est normalement décidé si les classes doivent être extensibles. Si ce n'est pas le cas, elles sont marquées comme finales afin de limiter les effets secondaires potentiels de sous-classes qui n'ont pas été envisagées. Il s'agit d'une caractéristique importante qui devrait être utilisée pour un code plus robuste et plus facile à maintenir.
Bonne réponse
Une méthode qui est déclarée avec le mot-clé final ne peut pas être annulée dans les sous-classes. Cette méthode est utilisée dans les hiérarchies où la mise en œuvre de la méthode doit être cohérente dans l'ensemble. La déclaration finale d'une classe interdit totalement le sous-classement. Oui, il est possible d'inclure des méthodes finales dans une classe abstraite. Cela permet de s'assurer que les sous-classes ne peuvent pas passer outre la méthode.
Mauvaise réponse
Si le candidat n'est pas familier avec le mot-clé final, qu'il soit utilisé au niveau de la classe ou de la méthode, alors cela suggère une relative inexpérience de la langue. Même pour les programmeurs inexpérimentés qui ont participé à la conception orientée objet, le concept de classe finale devrait être familier.
La programmation Java permet de créer un fil de discussion de différentes manières. Quelles sont-elles et quelle est la méthode préférée ? Expliquez.
Justification
Contrairement au C++, java contient un support intégré pour le multithreading. C'est une fonctionnalité riche et puissante qui est à la fois pertinente et utile dans de nombreuses applications. En tant que tel, le candidat doit être familier avec les bases.
Bonne réponse
Que se passe-t-il dans le cas où la réduction est appelée sur un tableau vide sans fournir la valeur initiale facultative de l'accumulateur ?
public class JavaInterviewClass implements Runnable {
public void run() {
System.out.println(“My example public class prints this line from a thread.”);
}
}
Pour exécuter la méthode run(), passez une instance de la classe dans un Thread, comme suit :
Thread interviewThread = new Thread(new JavaInterviewClass ());
interviewThread.start();
La deuxième façon de créer un fil de discussion est d'étendre la classe de fil de discussion. La sous-classe remplacera la méthode run(). Après cela, il suffit de créer une instance de la classe.
public class JavaInterviewClass extends Thread {
public void run() {
System.out.println(“My example public class extends the Thread class.”);
}
}
Pour exécuter le fil de discussion, il suffit d'instancier la classe et d'appeler start(), comme suit :
JavaInterviewClass myInterview = new JavaInterviewClass (); myInterview.start();
Bonus
Bien que l'implémentation de l'interface exécutable et l'extension de la classe Thread soient deux moyens populaires de créer un thread, il est également possible d'utiliser le framework Executor. Celui-ci permet de travailler directement avec les threads, mais il est moins connu. Il comprend des méthodes telles que newSingleThreadExecutor(), newFixedThreadPool() et submit() pour créer des tâches d'exécution. La connaissance de l'utilisation du framework Executor implique que le candidat soit très à l'aise avec la création et l'utilisation de threads en java.
Mauvaise réponse
Si le candidat n'est pas à l'aise avec l'utilisation des fils de discussion, il passe à côté d'une caractéristique puissante et importante de la langue. C'est important car comprendre le multithreading ne se limite pas à rechercher la syntaxe de quelques commandes. Il s'agit plutôt d'une approche qui doit être envisagée lors de la conception et du développement d'une application.
Le code Java a un support intégré pour la concurrence dans sa classe Thread. La simultanéité a son propre ensemble de problèmes tels que l'impasse et les conditions de course. Décrivez brièvement les variables Atomic en Java et leur utilisation. Ensuite, il est indiqué que la méthode start() est utilisée pour créer une pile d'appels séparée avant que la méthode run() ne soit utilisée pour exécuter un thread. Que font les méthodes yield(), sleep() et join() ?
Justification
La prise en charge du multithreading par Java peut entraîner des problèmes liés à la concurrence. Les connaissances du candidat concernant ces problèmes doivent être évaluées et prises en compte.
Bonne réponse
Une variable atomique est une variable "mise à jour atomique", ce qui signifie que l'intégrité des données est assurée par l'utilisation d'algorithmes non bloquants. Cette fonctionnalité est généralement mise en œuvre au niveau du code machine. Java prend en charge plusieurs variables atomiques, le plus souvent AtomicBoolean, AtomicInteger, AtomicLong et AtomicReference. Il existe également plusieurs méthodes qui permettent de récupérer et de modifier ces variables, notamment get(), set(), lazySet(), compareAndSet() et weakCompareAndSet(). Utilisées correctement, les variables atomiques peuvent être utilisées pour mettre en œuvre des méthodes "thread safe" (multithreading safe) qui traitent efficacement certains problèmes liés à la concurrence.
rendement() : Cette méthode informe l'environnement que le fil de discussion actuel n'est pas en train d'achever une tâche de haute priorité, et est prêt à en interrompre l'exécution. À condition que l'environnement sous-jacent supporte l'ordonnancement préventif, elle suspendra le fil s'il y en a un autre qui doit s'exécuter. S'il n'y a pas de deuxième fil, ou si le deuxième fil se termine, le fil en cours reprendra le contrôle et continuera à s'exécuter.
sommeil() : Cette méthode fait dormir le fil courant, ou met en pause son exécution, pendant un nombre de millisecondes déterminé. Il est également possible de combiner un certain nombre de millisecondes et de nanosecondes. Pendant que le fil courant est en sommeil, un autre fil sera exécuté, ou sinon le CPU restera inactif. Sous réserve de la précision de l'horloge du système et des minuteurs, le fil de discussion reprendra le contrôle une fois le compte à rebours terminé.
join() : Cette méthode est utilisée pour joindre deux l'exécution de deux fils ensemble. Pour clarifier, si le fil A appelle join() sur le fil B, alors A commencera à attendre. Une fois que B a terminé, ou qu'un délai prédéfini a expiré, A reprendra le contrôle et continuera l'exécution.
Mauvaise réponse
Le fait de connaître les fils de discussion Java, mais de ne pas être conscient des problèmes liés à la concurrence peut entraîner de graves erreurs. La majorité des appareils, des ordinateurs de bureau aux appareils mobiles en passant par les ordinateurs à carte unique, prennent désormais généralement en charge le multithreading et la concurrence. Il est important de comprendre la bonne utilisation des threads, et d'être conscient des méthodes fournies par java pour les prendre en charge.
Conclusion
Les questions de cet article sont utiles pour évaluer les compétences d'un futur programmeur Java. En ce qui concerne les questions d'entretien à préparer pour un développeur Java, il est important de se rappeler que les spécificités du langage peuvent être facilement référencées en utilisant l'aide et la documentation en ligne. Les points subtils d'un langage ne sont pas aussi importants que la façon dont on applique la logique. Cela dit, les candidats à ce poste sont censés connaître le langage et ne pas avoir besoin d'une formation approfondie avant que le travail réel ne commence. Les compétences requises seront dictées par le travail à effectuer, et la variation des questions données ci-dessus aidera à faire cette évaluation. N'oubliez pas que l'une des meilleures façons d'évaluer les compétences du candidat pour votre projet est d'effectuer une évaluation pratique de la programmation, ce qui est bien plus efficace que des questions d'entretien orales pour engager un programmeur Java hautement qualifié.