JavaRush /Blog Java /Random-FR /Analyse des questions et réponses des entretiens pour dév...

Analyse des questions et réponses des entretiens pour développeur Java. Partie 2

Publié dans le groupe Random-FR
Re-bonjour à tous ! Nous continuons à chercher des réponses à plus de 250 questions pour les développeurs juniors, intermédiaires et seniors. Les questions sont assez intéressantes, et j'aime moi-même les analyser : à de tels moments, on peut découvrir des lacunes dans les connaissances théoriques, et dans les endroits les plus inattendus. Analyse des questions et réponses d'entretien.  Partie 2 - 1La partie précédente se trouve dans cet article . Mais avant de commencer, je tiens à vous rappeler que :
  1. Questions qui recoupent cette série d'articles afin de ne pas dupliquer à nouveau les informations. Je recommande de lire ces documents, car ils contiennent les questions d'entretien Java Core les plus courantes (populaires).
  2. Les questions sur DOU sont présentées en ukrainien, mais j'aurai tout ici en russe.
  3. Les réponses pourraient être décrites plus en détail, mais je ne le ferai pas, car la réponse à chaque question pourrait alors prendre un article entier. Et ils ne vous poseront pas de questions aussi détaillées lors d’un entretien.
Si nécessaire, je laisserai des liens pour une étude plus approfondie. Volons!

11. Nommez toutes les méthodes de la classe Object

La classe Object dispose de 11 méthodes :
  • Class<?> getClass() — obtient la classe de l'objet actuel ;
  • int hashCode() — obtenir le code de hachage de l'objet actuel ;
  • booléen égal​(Object obj) - comparaison de l'objet actuel avec un autre ;
  • Object clone() - crée et renvoie une copie de l'objet actuel ;
  • String toString() — obtenir une représentation sous forme de chaîne d'un objet ;
  • void notify() - réveil d'un thread en attente sur le moniteur de cet objet (la sélection du thread est aléatoire) ;
  • void notifyAll() - réveille tous les threads en attente sur le moniteur de cet objet ;
  • void wait() - fait passer le thread actuel en mode veille (le gèle) sur le moniteur actuel, fonctionne uniquement dans un bloc synchronisé jusqu'à ce qu'une notification ou un notifyAll réveille le thread ;
  • void wait(long timeout) - gèle également le thread actuel sur le moniteur actuel (sur celui actuellement synchronisé), mais avec une minuterie pour quitter cet état (ou encore : jusqu'à ce que notify ou notifyAll se réveille) ;
  • void wait(long timeout, int nanos) - une méthode similaire à celle décrite ci-dessus, mais avec des minuteries plus précises pour sortir du gel ;
  • void finalize() - avant de supprimer cet objet, le garbage collector appelle cette méthode (enfin). Il est utilisé pour nettoyer les ressources occupées.
Pour une utilisation correcte des méthodes hashCode , equals​ , clone , toString et finalize , elles doivent être redéfinies, en tenant compte de la tâche et des circonstances actuelles.

12. Quelle est la différence entre try-with-resources et try-catch-finally lorsqu'il s'agit de ressources ?

Généralement, lors de l'utilisation de try-catch-finally, le bloc final était utilisé pour fermer les ressources. Java 7 a introduit un nouveau type d'opérateur try-with-resources , un analogue de try-catch-finally pour libérer des ressources, mais plus compact et lisible. Rappelons à quoi ressemble try-catch-finally :
String text = "some text......";
BufferedWriter bufferedWriter = null;
try {
   bufferedWriter = new BufferedWriter(new FileWriter("someFileName"));
   bufferedWriter.write(text);
} catch (IOException e) {
   e.printStackTrace();
} finally {
   try {
       bufferedWriter.close();
   } catch (IOException e) {
       e.printStackTrace();
   }
}
Réécrivons maintenant ce code, mais en utilisant try-with-resources :
String text = "some text......";
try(BufferedWriter bufferedWriter =new BufferedWriter(new FileWriter("someFileName"))) {
   bufferedWriter.write(text);
} catch (IOException e) {
   e.printStackTrace();
}
C’est en quelque sorte devenu plus facile, tu ne trouves pas ? En plus de la simplification, il y a quelques points :
  1. Dans try-with-resources , les ressources déclarées entre parenthèses (qui seront fermées) doivent implémenter l'interface AutoCloseable et sa seule méthode, close() .

    La méthode close est exécutée dans un bloc final implicite , sinon comment le programme comprendra-t-il exactement comment fermer une ressource donnée ?

    Mais, très probablement, vous écrirez rarement vos propres implémentations de ressources et leur méthode de fermeture.

  2. Séquence d'exécution du bloc :

    1. essayez de bloquer .
    2. Implicite finalement .
    3. Un bloc catch qui intercepte les exceptions des étapes précédentes.
    4. Explicite enfin .

    En règle générale, les exceptions qui apparaissent plus bas dans la liste interrompent celles qui apparaissent plus haut.

Imaginez une situation dans laquelle, lors de l'utilisation de try-catch-finally, une exception se produit dans votre try . En conséquence, un bloc catch spécifique commence immédiatement à s'exécuter , dans lequel vous écrivez une autre exception (par exemple, avec un message décrivant l'erreur plus en détail), et vous souhaitez que la méthode lève davantage cette exception. Vient ensuite l'exécution du bloc final , et une exception y est également levée. Mais c'est différent. Laquelle de ces deux exceptions cette méthode va-t-elle finalement générer ? Exception levée par le bloc enfin ! Mais il y a aussi un point avec try-with-resources . Examinons maintenant le comportement de try-with-resources dans la même situation. Nous obtenons une exception dans le bloc try lorsque nous essayons de fermer des ressources dans la méthode close() , c'est-à-dire dans l' implicite final . Laquelle de ces exceptions sera interceptée ? Celui qui a été lancé par le bloc try ! Une exception à un final implicite (de la méthode close() ) sera ignorée. Cette ignorance est également appelée suppression d'exception.

13. Que sont les opérations au niveau du bit ?

Les opérations au niveau du bit sont des opérations sur des chaînes de bits qui incluent des opérations logiques et des décalages au niveau du bit. Opérations logiques :
  • ET au niveau du bit - compare les valeurs des bits et, dans le processus, tout bit défini sur 0 (faux) définit le bit correspondant dans le résultat sur 0. Autrement dit, si dans les deux valeurs comparées, le bit était 1 (vrai), le le résultat sera également 1.

    Noté - ET , &

    Exemple : 10111101 & 01100111 = 00100101

  • OU au niveau du bit est l’opération inverse de la précédente. Tout bit défini sur 1 définit un bit similaire dans le résultat à 1. Et par conséquent, si le bit était 0 dans les deux valeurs comparées, le bit résultant sera également 0.

    Noté - OU , |

    Exemple : 10100101 | 01100011 = 11100111

  • NOT au niveau du bit - appliqué à une valeur, inverse (inverse) les bits. Autrement dit, les bits qui étaient 1 deviendront 0 ; et ceux qui étaient 0 deviendront 1.

    Noté - PAS , ~

    Exemple : ~10100101 = 01011010

  • OU exclusif au niveau du bit - compare les valeurs des bits, et si dans les deux valeurs le bit est égal à 1, alors le résultat sera 0, et si dans les deux valeurs le bit est 0, le résultat sera 0. Autrement dit, pour que le résultat soit égal à 1, il faut qu'un seul des bits soit égal à 1, et le second soit égal à 0.

    Noté - XOR , ^

    Exemple : 10100101 ^ 01100011 = 11000110

Décalages au niveau des bits - >> ou << décale les bits d'une valeur dans la direction spécifiée, du nombre spécifié. Les postes vacants sont remplis de zéros. Par exemple:
  1. 01100011 >> 4 = 00000110
  2. 01100011 << 3 = 00011000
Il existe également une exception lors du déplacement vers la droite d'un nombre négatif. Comme vous vous en souvenez, le premier bit est responsable du signe, et si ce bit est égal à 1, alors le nombre est négatif. Si vous déplacez un nombre négatif, les positions libérées ne seront plus remplies de zéros, mais de uns, puisqu'il faut conserver le bit de signe. Par exemple : 10100010 >> 2 = 11101000 Dans le même temps, en Java, il existe un opérateur de décalage à droite non signé supplémentaire >>> Cet opérateur est un analogue de >>, lors du décalage, les positions libérées sont remplies par 0, que ce soit le nombre est négatif ou positif. Par exemple : 10100010 >>> 2 = 00101000 En savoir plus sur les opérations au niveau du bit ici . Analyse des questions et réponses d'entretien.  Partie 2 - 2Comme exemples d'utilisation des décalages de bits en Java, vous pouvez citer la méthode hash() d'un HashMap, qui est utilisée pour déterminer un code de hachage interne spécial pour une clé : Analyse des questions et réponses d'entretien.  Partie 2 - 3Cette méthode vous permet de répartir uniformément les données dans un HashMap pour minimiser le nombre de collisions.

14. Quelles classes immuables standard sont des objets en Java ?

Immuable est un objet qui ne permet pas de modifier ses paramètres d'origine. Il peut contenir des méthodes qui renvoient de nouveaux objets d'un type donné, avec des paramètres que vous souhaitez modifier. Quelques objets immuables standards :
  • L’objet immuable de loin le plus célèbre en Java est String ;
  • instances de classes wrapper qui encapsulent les types standard : Boolean, Character, Byte, Short, Integer, Long, Double, Float ;
  • objets qui sont généralement utilisés pour des nombres particulièrement GRANDS - BigInteger et BigDecimal ;
  • un objet qui est une unité dans les traces de pile (par exemple, dans une trace de pile d'exception) StackTraceElement ;
  • un objet de la classe File - peut modifier des fichiers, mais en même temps il est lui-même immuable ;
  • UUID - qui est souvent utilisé comme identifiant unique pour les éléments ;
  • tous les objets de classe du package java.time ;
  • Locale - utilisé pour définir une région géographique, politique ou culturelle.

15. Quels sont les avantages d'un objet immuable par rapport aux objets ordinaires ?

  1. De tels objets sont sûrs lorsqu'ils sont utilisés dans un environnement multithread . En les utilisant, vous n'avez pas à craindre de perdre des données en raison de conditions de course aux threads. Contrairement au travail avec des objets ordinaires : dans ce cas, vous devrez réfléchir très attentivement et élaborer les mécanismes d'utilisation de l'objet dans un environnement parallèle.
  2. Les objets immuables sont de bonnes clés dans une carte, car si vous utilisez un objet mutable et que l'objet change ensuite d'état, cela peut devenir déroutant lors de l'utilisation d'un HashMap : l'objet sera toujours présent, et si vous utilisez containKey(), il se peut qu'il ne le soit pas. être trouvé.
  3. Les objets immuables sont parfaits pour stocker des données immuables (constantes) qui ne doivent jamais être modifiées pendant l'exécution du programme.
  4. "Atomicité jusqu'à l'échec" - si un objet immuable lève une exception, il ne restera toujours pas dans un état indésirable (cassé).
  5. Ces cours sont faciles à tester.
  6. Des mécanismes supplémentaires tels qu'un constructeur de copie et une implémentation de clone ne sont pas nécessaires.

Questions sur la POO

Analyse des questions et réponses d'entretien.  Partie 2 - 4

16. Quels sont les avantages de la POO en général et par rapport à la programmation procédurale ?

Alors, les avantages de la POO :
  1. Les applications complexes sont plus faciles à écrire que la programmation procédurale, puisque tout est décomposé en petits modules - des objets qui interagissent les uns avec les autres - et par conséquent, la programmation se résume à des relations entre objets.
  2. Les applications écrites en POO sont beaucoup plus faciles à modifier (à condition que les concepts de conception soient suivis).
  3. Étant donné que les données et les opérations qu'elles contiennent forment une seule entité, elles ne sont pas réparties dans toute l'application (ce qui arrive souvent avec la programmation procédurale).
  4. L'encapsulation des informations protège les données les plus critiques de l'utilisateur.
  5. Il est possible de réutiliser le même code avec des données différentes, car les classes permettent de créer de nombreux objets, chacun ayant ses propres valeurs d'attribut.
  6. L'héritage et le polymorphisme vous permettent également de réutiliser et d'étendre le code existant (au lieu de dupliquer des fonctionnalités similaires).
  7. Extensibilité de l'application plus facile qu'avec une approche procédurale.
  8. L'approche POO permet de faire abstraction des détails de mise en œuvre.

17. Dites-nous quelles sont les lacunes de la POO

Malheureusement, ils sont également présents :
  1. La POO nécessite beaucoup de connaissances théoriques qui doivent être maîtrisées avant de pouvoir écrire quoi que ce soit.Analyse des questions et réponses d'entretien.  Partie 2 à 5
  2. Les idées de la POO ne sont pas si faciles à comprendre et à appliquer dans la pratique (il faut être un peu philosophe dans l'âme).
  3. Lors de l'utilisation de la POO, les performances du logiciel sont légèrement réduites en raison de l'organisation plus complexe du système.
  4. L'approche POO nécessite plus de mémoire, puisque tout est constitué de classes, d'interfaces, de méthodes, qui occupent beaucoup plus de mémoire que les variables ordinaires.
  5. Le temps requis pour l’analyse initiale est plus long que pour l’analyse procédurale.

18. Qu'est-ce que le polymorphisme statique et dynamique

Le polymorphisme permet aux objets de se comporter différemment pour la même classe ou interface. Il existe deux types de polymorphisme, également appelés liaisons précoces et tardives . Polymorphisme statique, ou liaison antérieure :
  • se produit au moment de la compilation (au début du cycle de vie du programme) ;
  • décide quelle méthode exécuter au moment de la compilation ;
  • La surcharge de méthodes est un exemple de polymorphisme statique ;
  • la liaison anticipée inclut les méthodes privées, statiques et terminales ;
  • l'héritage n'est pas impliqué dans la liaison précoce ;
  • Le polymorphisme statique n'implique pas d'objets spécifiques, mais des informations sur la classe dont le type est représenté à gauche du nom de la variable.
Polymorphisme dynamique, ou liaison tardive :
  • se produit au moment de l'exécution (pendant que le programme est en cours d'exécution) ;
  • le polymorphisme dynamique décide quelle implémentation spécifique une méthode aura au moment de l'exécution ;
  • le remplacement de méthode est un exemple de polymorphisme dynamique ;
  • la liaison tardive est l'affectation d'un objet spécifique, d'une référence de son type ou de sa superclasse ;
  • l'héritage est associé au polymorphisme dynamique.
Vous pouvez en savoir plus sur les différences entre la liaison anticipée et tardive dans cet article .

19. Définir le principe de l'abstraction en POO

L'abstraction en POO est un moyen de mettre en évidence un ensemble de caractéristiques significatives d'un objet, en excluant les détails sans importance. Autrement dit, lors de la conception d'un programme avec une approche POO, vous vous concentrez sur les modèles en général, sans entrer dans les détails de leur mise en œuvre. En Java, les interfaces sont responsables de l'abstraction . Par exemple, vous avez une machine, et ce sera l'interface. Et diverses interactions avec celui-ci - par exemple, démarrer le moteur, utiliser la boîte de vitesses - ce sont des fonctions que nous utilisons sans entrer dans les détails de mise en œuvre. Après tout, au moment où vous conduisez une voiture, vous ne pensez pas à la manière exacte dont la boîte de vitesses remplit sa fonction, ni à la manière dont la clé démarre le moteur, ni à la manière exacte dont le volant fait tourner les roues. Et même si la mise en œuvre de l'une de ces fonctionnalités est remplacée (par exemple, le moteur), vous ne le remarquerez peut-être pas. Cela n'a pas d'importance pour vous : vous n'entrez pas dans les détails de la mise en œuvre. Il est important pour vous que l'action soit réalisée. En fait, il s’agit d’une abstraction des détails d’implémentation. C'est là que nous nous arrêterons aujourd'hui : à suivre !Analyse des questions et réponses d'entretien.  Partie 2 à 6
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION