CodeGym /Blog Java /Random-FR /Explorer les questions et réponses d'un entretien d'embau...
John Squirrels
Niveau 41
San Francisco

Explorer les questions et réponses d'un entretien d'embauche pour un poste de développeur Java. Partie 11

Publié dans le groupe Random-FR
Salut! Même le navire le plus rapide dérivera simplement sur les vagues s'il n'a pas de cap. Si vous lisez cet article en ce moment, vous avez définitivement un objectif. L’essentiel est de ne pas s’écarter du cap et de se lancer à fond pour devenir développeur Java. Aujourd'hui, je souhaite poursuivre mon examen des questions destinées aux développeurs Java afin de vous aider à combler certaines de vos lacunes théoriques. Explorer les questions et réponses d'un entretien d'embauche pour un poste de développeur Java.  Partie 11 - 1

97. Des règles s'appliquent-elles lors du remplacement de equals() ?

Lors du remplacement de la méthode equals(), vous devez respecter les règles suivantes :
  • réflexivité — pour toute valeur x , x.equals(x) doit toujours renvoyer true (où x != null ).

  • symétrie — pour toutes les valeurs x et y , x.equals(y) doit renvoyer true uniquement si y.equals(x) renvoie true .

  • transitivité - pour toutes les valeurs x , y et z , si x.equals(y) renvoie true et y.equals(z) renvoie également true , alors x.equals(z) doit renvoyer true .

  • cohérence - pour toutes les valeurs x et y , l'appel répété de x.equals(y) renverra toujours la même valeur tant que les champs utilisés pour comparer les deux objets n'ont pas changé entre chaque appel.

  • comparaison nulle — pour toute valeur x , l'appel de x.equals(null) doit renvoyer false .

98. Que se passe-t-il si vous ne remplacez pas equals() et hashCode() ?

Dans ce cas, hashCode() renverra un nombre généré en fonction de l'adresse de la cellule mémoire où l'objet est stocké. En d’autres termes, lorsque la méthode hashCode() d’origine est appelée sur deux objets avec exactement les mêmes champs, le résultat sera différent (car ils sont stockés dans des emplacements mémoire différents). La méthode originale equals() compare les références, c'est-à-dire qu'elle indique si les références pointent vers le même objet. En d’autres termes, la comparaison utilise l’ opérateur == et renverra toujours false pour différents objets, même lorsque leurs champs sont identiques. true n'est renvoyé que lors de la comparaison des références au même objet. Parfois, il est judicieux de ne pas remplacer ces méthodes. Par exemple, vous souhaitez que tous les objets d'une certaine classe soient uniques : remplacer ces méthodes ne pourrait que gâcher la garantie existante des codes de hachage uniques. L’important est de comprendre les nuances de ces méthodes, qu’elles soient contournées ou non, et d’utiliser l’approche qu’exige la situation.

99. Pourquoi l'exigence de symétrie est-elle satisfaite uniquement si x.equals(y) renvoie vrai ?

Cette question est un peu étrange. Si l’objet A est égal à l’objet B, alors l’objet B est égal à l’objet A. Si B n’est pas égal à l’objet A, alors comment l’inverse pourrait-il être possible ? C'est du bon sens.

100. Qu'est-ce qu'une collision HashCode ? Comment gères-tu cela?

Une collision HashCode se produit lorsque deux objets différents ont le même HashCode . Comment est-ce possible? Eh bien, le code de hachage est mappé sur un entier, dont la plage va de -2147483648 à 2147483647. Autrement dit, il peut s'agir de l'un des 4 milliards d'entiers différents. Cette gamme est énorme mais pas infinie. Cela signifie qu'il existe des situations dans lesquelles deux objets complètement différents peuvent avoir le même code de hachage. C’est très peu probable, mais c’est possible. Une fonction de hachage mal implémentée peut rendre les codes de hachage identiques plus fréquents en renvoyant des nombres dans une petite plage, augmentant ainsi le risque de collisions. Pour réduire les collisions, vous devez disposer d'une bonne implémentation de la méthode HashCode qui répartit uniformément les valeurs et minimise le risque de valeurs répétées.

101. Que se passe-t-il si la valeur d'un élément participant au contrat hashCode change ?

Si un élément impliqué dans le calcul d'un code de hachage change, alors le code de hachage de l'objet doit changer (si la fonction de hachage est bonne). C'est pourquoi vous devez utiliser des objets immuables comme clés dans un HashMap , puisque leur état interne (champs) ne peut pas être modifié après la création. Et il s’ensuit que leur code de hachage change après la création. Si vous utilisez un objet mutable comme clé, lorsque les champs de l'objet changent, son code de hachage change et vous risquez de perdre la paire clé-valeur correspondante dans le HashMap . Après tout, il sera stocké dans le compartiment associé au code de hachage d'origine, mais une fois l'objet modifié, vous le rechercherez dans un autre compartiment.

102. Écrivez les méthodes equals() et hashCode() pour une classe Student qui a un nom de chaîne et des champs d'âge int.

public class Student {
int age;
String name;

 @Override
 public boolean equals(final Object o) {
   if (this == o) {
     return true;
   }
   if (o == null || this.getClass() != o.getClass()) {
     return false;
   }

   final Student student = (Student) o;

   if (this.age != student.age) {
     return false;
   }
   return this.name != null ? this.name.equals(student.name) : student.name == null;
 }

 @Override
 public int hashCode() {
   int result = this.age;
   result = 31 * result + (this.name != null ? this.name.hashCode() : 0);
   return result;
 }
}
équivaut à():
  • Tout d’abord, nous comparons directement les références, car si les références pointent vers le même objet, à quoi bon continuer à vérifier l’égalité ? Nous savons déjà que le résultat sera vrai .

  • Nous vérifions null et si les types de classe sont les mêmes, car si le paramètre est null ou d'un autre type, alors les objets ne peuvent pas être égaux et le résultat doit être false .

  • Nous convertissons le paramètre dans le même type (après tout, que se passe-t-il s'il s'agit d'un objet du type parent).

  • On compare les champs primitifs (une comparaison utilisant =! suffira). S'ils ne sont pas égaux, nous renvoyons false .

  • Nous vérifions le champ non primitif pour voir s'il est nul et en utilisant la méthode égale (la classe String remplace la méthode, elle effectuera donc la comparaison correctement). Si les deux champs sont nuls ou si égal renvoie true , nous arrêtons la vérification et la méthode renvoie true .

hashCode() :
  • Nous définissons la valeur initiale du code de hachage égale à la valeur du champ d'âge de l'objet .

  • Nous multiplions le code de hachage actuel par 31 (pour une plus grande répartition des valeurs), puis ajoutons le code de hachage du champ String non primitif (s'il n'est pas nul).

  • Nous renvoyons le résultat.

  • Remplacer la méthode de cette manière signifie que les objets portant le même nom et les mêmes valeurs int renverront toujours le même code de hachage.

103. Quelle est la différence entre l'utilisation de « if (obj instanceof Student) » et « if (getClass() == obj.getClass()) » ?

Jetons un coup d'œil à ce que fait chaque expression :
  • instanceof vérifie si la référence d'objet sur le côté gauche est une instance du type sur le côté droit ou l'un de ses sous-types.

  • "getClass() == ..." vérifie si les types sont identiques.

En d'autres termes, getClass() renvoie l'identité spécifique de la classe, mais instanceof renvoie true même si l'objet n'est qu'un sous-type, ce qui peut nous donner plus de flexibilité lors de l'utilisation du polymorphisme. Les deux approches sont prometteuses si vous comprenez précisément leur fonctionnement et si vous les appliquez aux bons endroits.

104. Donnez une brève description de la méthode clone().

La méthode clone() appartient à la classe Object . Son but est de créer et de renvoyer un clone (copie) de l'objet actuel. Explorer les questions et réponses d'un entretien d'embauche pour un poste de développeur Java.  Partie 11 - 2Pour utiliser cette méthode, vous devez implémenter l' interface du marqueur Cloneable :
Student implements Cloneable
Et remplacez la méthode clone() elle-même :
@Override
protected Object clone() throws CloneNotSupportedException {
 return super.clone();
}
Après tout, il est protégé dans la classe Object , c'est-à-dire qu'il ne sera visible que dans la classe Student et non visible par les classes externes.

105. Quelles considérations particulières devez-vous garder à l'esprit concernant la méthode clone() et les variables de référence dans un objet ?

Lorsque des objets sont clonés, seules les valeurs primitives et la valeur des références d'objet sont copiées. Cela signifie que si un objet possède un champ qui fait référence à un autre objet, alors seule la référence sera clonée — cet autre objet référencé ne sera pas cloné. C'est ce qu'on appelle une copie superficielle. Alors, que se passe-t-il si vous avez besoin d'une copie à part entière, où chaque objet imbriqué est cloné ? Comment s'assurer qu'il ne s'agit pas de simples copies de références, mais plutôt de copies complètes d'objets distincts occupant des adresses mémoire distinctes dans le tas ? En fait, tout est assez simple : pour chaque classe référencée en interne, vous devez remplacer la méthode clone() et ajouter l' interface de marqueur Cloneable . Une fois cela fait, l'opération de clonage ne copiera pas les références aux objets existants, mais copiera à la place les objets référencés, car ils ont désormais également la possibilité de se copier eux-mêmes.

Des exceptions

106. Quelle est la différence entre une erreur et une exception ?

Les exceptions, ainsi que les erreurs, sont des sous-classes de Throwable . Cependant, ils ont leurs différences. L'erreur indique un problème qui se produit principalement en raison d'un manque de ressources système. Et notre application ne devrait pas voir ce type de problèmes. Des exemples de ces erreurs incluent une panne du système et une erreur de mémoire insuffisante. Les erreurs se produisent principalement au moment de l’exécution, car elles ne sont pas vérifiées. Explorer les questions et réponses d'un entretien d'embauche pour un poste de développeur Java.  Partie 11 - 3Les exceptions sont des problèmes qui peuvent survenir au moment de l'exécution et au moment de la compilation. Ces problèmes surviennent généralement dans le code que nous écrivons en tant que développeurs. Cela signifie que ces exceptions sont plus prévisibles et dépendent davantage de nous. En revanche, les erreurs sont plus aléatoires et plus indépendantes de nous. Au lieu de cela, ils dépendent de problèmes dans le système sur lequel notre application s'exécute.

107. Quelle est la différence entre coché, non coché, exception, lancer et lancer ?

Comme je l'ai dit plus tôt, une exception est une erreur d'exécution ou de compilation qui se produit dans le code écrit par le développeur (en raison d'une situation anormale). Coché est ce que nous appelons les exceptions qu'une méthode doit toujours gérer en utilisant le mécanisme try-catch ou en renvoyant à la méthode appelante. Le mot-clé throws est utilisé dans un en-tête de méthode pour indiquer les exceptions que la méthode peut lever. En d’autres termes, cela nous fournit un mécanisme pour lever des exceptions à la méthode appelante. Les exceptions non vérifiées n'ont pas besoin d'être gérées. Ils ont tendance à être moins prévisibles et moins probables. Cela dit, vous pouvez les gérer si vous le souhaitez. Nous utilisons throw lors du lancement manuel d'une exception, par exemple :
throw new Exception();

108. Quelle est la hiérarchie des exceptions ?

La hiérarchie des exceptions est très étendue. Il y a trop de choses à décrire de manière adéquate ici. Nous ne considérerons donc que ses branches clés : Explorer les questions et réponses d'un entretien d'embauche pour un poste de développeur Java.  Partie 11 - 4 ici, tout en haut de la hiérarchie, nous voyons la classe Throwable , qui est l'ancêtre général de la hiérarchie des exceptions et se divise à son tour en :
  • Erreurs – problèmes critiques et non résolus.
  • Exceptions — exceptions qui peuvent être vérifiées.
Les exceptions sont divisées en diverses exceptions d'exécution non vérifiées et en diverses exceptions vérifiées.

109. Que sont les exceptions cochées et non cochées ?

Comme je le disais avant:
  • Les exceptions cochées sont des exceptions que vous devez gérer d'une manière ou d'une autre. Autrement dit, vous devez soit les gérer dans un bloc try-catch , soit les lancer vers la méthode ci-dessus. Pour ce faire, après avoir répertorié les arguments de la méthode dans la signature de la méthode, utilisez throws <exception type> pour indiquer que la méthode peut lever cette exception. C'est un peu comme un avertissement, avertissant la méthode appelante qu'elle doit assumer la responsabilité de la gestion de cette exception.

  • Les exceptions non vérifiées n'ont pas besoin d'être gérées, car elles ne sont pas vérifiées au moment de la compilation et sont généralement plus imprévisibles. Leur principale différence avec les exceptions vérifiées est que leur gestion à l'aide d'un bloc try-catch ou en les relançant est facultative plutôt qu'obligatoire.

101. Écrivez un exemple dans lequel vous utilisez un bloc try-catch pour intercepter et gérer une exception.

try{                                                 // Start of the try-catch block
 throw new Exception();                             // Manually throw an exception
} catch (Exception e) {                              // Exceptions of this type and its subtypes will be caught
 System.out.println("Oops! Something went wrong =("); // Display the exception
}

102. Écrivez un exemple dans lequel vous interceptez et gérez vos propres exceptions personnalisées.

Tout d'abord, écrivons notre propre classe d'exception qui hérite d'Exception et remplaçons son constructeur qui prend un message d'erreur comme argument :
public class CustomException extends Exception {

 public CustomException(final String message) {
   super(message);
 }
}
Ensuite, nous allons en lancer un manuellement et l'attraper comme nous l'avons fait dans l'exemple de la question précédente :
try{
 throw new CustomException("Oops! Something went wrong =(");
} catch (CustomException e) {
 System.out.println(e.getMessage());
}
Encore une fois, lorsque nous exécutons notre code, nous obtenons le résultat suivant :
Oops! Quelque chose s'est mal passé =(
Explorer les questions et réponses d'un entretien d'embauche pour un poste de développeur Java.  Partie 11 - 5Eh bien, c'est tout pour aujourd'hui ! Rendez-vous dans la prochaine partie !
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION