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 3

Publié dans le groupe Random-FR
Bonjour! Tout comme il est impossible d’apprendre à piloter un avion sans formation particulière, il est également impossible de devenir développeur Java sans passer de longues heures à étudier les bases théoriques nécessaires. Aujourd'hui, nous allons travailler exactement sur cela : nous continuerons à analyser plus de 250 questions d'entretien pour les développeurs Java et, par conséquent, les réponses à celles-ci. Voici la première et la deuxième parties de l’analyse. Oui, bien sûr, vous pouvez devenir un bon développeur Java sans toutes ces questions. Cependant, si vous maîtrisez bien les tenants et les aboutissants du langage Java, cela vous donnera un avantage, faisant de vous un candidat plus recherché aux yeux de votre futur employeur.Analyse des questions et réponses des entretiens pour développeur Java.  Partie 3 - 1

20. Quels éléments du langage sont responsables de l'encapsulation ?

Comme nous nous en souvenons, l'encapsulation masque les détails d'implémentation d'une classe. Autrement dit, lorsque notre classe est utilisée en externe, le contenu et la logique internes ne sont pas évidents. Et quels éléments du langage en sont responsables ? Naturellement, accédez aux modificateurs ! Nous marquons ce que nous devons cacher avec le modificateur private . Par exemple, les champs privés d'une classe ou certaines méthodes internes permettant d'implémenter certaines fonctionnalités internes. Et à ce à quoi nous souhaitons fournir un accès externe, nous ajoutons le modificateur d'accès public . Par exemple, une méthode chargée de fournir certaines fonctionnalités (au sein desquelles de nombreuses méthodes privées peuvent être utilisées) ou les mêmes getters et setters pour accéder aux champs privés d'une classe. Oh, et nous avons également les modificateurs default et protected , qui peuvent être utilisés pour une configuration plus flexible et spécifique de l'accès aux parties sélectionnées de la classe.

21. Quels éléments du langage sont responsables de l'héritage ?

L'héritage est un mécanisme qui vous permet de créer des classes basées sur une autre classe. En Java, le mot clé extends est utilisé à cet effet . Par exemple, nous avons une certaine classe Cat et nous voulons créer son successeur - Lion . Dans le code, cela ressemblera à ceci :
public class Lion extends Cat
Et cela signifie que la classe Lion hérite de toutes les méthodes et variables de la classe Cat , à l'exception des méthodes statiques. De plus, les éléments de langage responsables de l'héritage incluent super . Il s'agit d'une référence similaire à this , mais bien que this fasse référence à l'objet sur lequel elle a été appelée, super fait référence à l'objet parent actuel. Généralement, super est utilisé :
  1. Pour appeler un constructeur de superclasse : par exemple, la classe Cat a un nom de variable interne qui doit être initialisé dans le constructeur. Dans le constructeur de la classe Lion , cela ressemblerait à ceci :

    public Lion(final String name) {
       super(name);
    }
  2. Pour accéder aux champs et méthodes parents : par exemple, dans la classe Cat nous avons un champ age initialisé :

    public class Cat {
       int age = 10;
En même temps, nous avons le même champ initialisé dans Lion :
public class Lion extends Cat {
   int age = 15;
Et si nous voulons accéder à la variable age de l'objet parent à partir de l'objet Lion , nous devons le faire via super :
super.name

22. Quels éléments du langage sont responsables du polymorphisme ?

Le polymorphisme est la capacité d'un objet d'une même signature à prendre plusieurs formes (implémentations multiples). Nous pouvons affirmer avec certitude qu'en Java, les mots-clés Implements et ExtendsAnalyse des questions et réponses des entretiens pour développeur Java.  Partie 3 - 2 sont responsables du polymorphisme . implémente - lorsque nous créons notre interface, nous implémentons l'une de ses formes possibles dans une classe, mais ce n'est pas la seule, n'est-ce pas ? Rappelons à quoi ressemble l'implémentation des implémentations :
public class Cat implements Animal
Et dans la classe Cat nous devons implémenter toutes les méthodes abstraites présentées dans l' interface Animal . Il en va de même pour l'héritage : dans une classe descendante, nous pouvons remplacer une implémentation déjà existante d'une méthode. Par exemple : plusieurs descendants -> plusieurs remplacements différents d'une même méthode. Eh bien, soit la superclasse était abstraite et elle possède une certaine méthode qui doit être implémentée d'une manière spéciale pour chacun de ses descendants. Autrement dit, nous pouvons dire que la méthode prendra plusieurs formes. De plus, l'annotation @Override peut nous aider , qui est placée au-dessus des méthodes implémentées et indique que nous voulons implémenter ou remplacer (si l'implémentation existe déjà dans la superclasse) l'une ou l'autre méthode de la superclasse ou de l'interface. Il est facultatif et sert à faciliter la détection des erreurs. Avec cette annotation, vous indiquez au compilateur que vous souhaitez remplacer/implémenter une méthode de superclasse/interface, et cela garantira que vous ne commettez pas d'erreurs dans la signature de la méthode.

23. Qu'est-ce que SOLIDE ? Donne des exemples

SOLID est l'acronyme des cinq principes de conception de base pour la POO, inventés par Robert Martin. S - Principe de responsabilité unique - le principe de responsabilité unique, qui stipule qu'une classe ne doit avoir qu'un seul but et un seul objectif. Autrement dit, vous ne devriez pas créer des classes qui font tout. Dans ce cas, vous pouvez reproduire l’anti-motif « Objet Divin ». Si vous disposez d'un objet Cat , il doit contenir des méthodes qui interagissent uniquement avec ses fonctionnalités internes, et non avec une logique métier qui n'est pas pertinente pour cette instance. Par exemple, une sorte de sauvegarde d'objets de ce type quelque part. Cette fonctionnalité externe (par rapport à Cat ) doit être transférée vers d'autres classes, certains services dont la tâche est de fournir une logique métier pour les objets de ce type. O - Principe ouvert-fermé - principe d'ouverture/fermeture. Cela signifie que les entités logicielles (classes, interfaces) doivent être ouvertes à l'extension, mais fermées à la modification. Par exemple, nous avions besoin de fonctionnalités similaires aux fonctionnalités de la classe Cat déjà existante , mais légèrement différentes. Au lieu de modifier la fonctionnalité de la classe Cat , en cassant les endroits où elle est déjà utilisée, nous utilisons l'héritage ou la composition . En conséquence, nous avons atteint notre objectif avec la fonctionnalité modifiée de la classe Cat , mais en même temps, nous ne l'avons pas modifié ni cassé quoi que ce soit. L - Principe de substitution de Liskov - Principe de substitution de Barbara Liskov. Le principe stipule qu'une fonction qui utilise un type de base doit pouvoir utiliser des sous-types du type de base sans le savoir. Par exemple, notre classe Cat devrait être interchangeable avec n'importe lequel de ses descendants, disons Lion , sans changer fondamentalement le comportement. La logique générale (comportement) reste la même, mais les détails de mise en œuvre de telle ou telle fonctionnalité changent. I - Principe de séparation des interfaces - le principe de séparation des interfaces. Ce principe stipule qu’il est préférable d’avoir de nombreuses interfaces spécialisées (étroitement ciblées) plutôt qu’une seule universelle. Par exemple, un utilisateur implémente une interface dont il n'a besoin que de cette méthode, mais cette interface comporte neuf méthodes supplémentaires qui n'ont rien à voir avec la logique de la méthode souhaitée. Dans ce cas, l'utilisateur devra implémenter dix méthodes d'interface, dont neuf lui sont inutiles ! Au lieu de cela, il est préférable de créer dix interfaces différentes qui peuvent être implémentées si nécessaire. Eh bien, ou pas dix, mais plusieurs, qui auront des méthodes étroitement liées à l'objectif commun de l'interface. D - Principe d'inversion de dépendance— le principe d'inversion de dépendance. Le principe stipule que les modules des niveaux supérieurs ne doivent pas dépendre des modules des niveaux inférieurs. Ce principe est également décrit comme suit : « l’abstraction ne devrait pas dépendre des détails, les détails devraient dépendre de l’abstraction ». Autrement dit, nous devons construire notre logique en nous référant aux interfaces, et ensuite seulement transmettre des objets spécifiques à cette fonctionnalité, dont les classes implémentent l'interface requise. Par exemple, si nous avons une interface Cat et certaines de ses implémentations, par exemple Lion et HomeCat , nous construisons notre logique d'interaction spécifiquement avec le type d'interface Cat , et ensuite seulement substituons une implémentation spécifique de Lion ou HomeCat , mais pas l'inverse.

24. Qu'est-ce qu'une classe, un objet, une interface ?

On le rappelle, Java est un langage POO. Autrement dit, les programmes Java sont construits sur l'interaction entre les objets. Il s'avère que le programme est comme une fourmilière, où chaque fourmi est un objet. Analyse des questions et réponses des entretiens pour développeur Java.  Partie 3 - 3Les objets sont des données groupées qui contiennent diverses méthodes (fonctions) pour interagir avec ces données internes. Et les classes sont des instructions, des modèles pour créer des objets. Autrement dit, il peut y avoir de nombreux objets construits selon la même instruction, remplis de valeurs de données différentes ou identiques. Pour donner un exemple tiré de la vie, nous pouvons dire qu'une classe est un dessin d'un bâtiment et qu'un objet est un bâtiment spécifiquement créé sur la base de ce dessin. Les interfaces sont analogues aux classes, à la différence que les objets ne peuvent pas être créés à l'aide d'elles. Leur objectif est d'ajouter un élément d'abstraction à Java. Plus précisément, pour ajouter de la flexibilité dans les relations entre classes et objets. Par flexibilité, nous entendons le polymorphisme et l'abstraction décrits précédemment, qui à leur tour ouvrent de nombreuses opportunités pour construire l'architecture interne de l'application.

25. Qu'est-ce qu'un cours POJO ? Donnez un exemple d'une telle classe

Analyse des questions et réponses des entretiens pour développeur Java.  Partie 3 - 4POJO - Plain Old Java Object - un bon vieil objet Java : un simple objet d'une classe qui n'est hérité d'aucune classe spécifique et n'implémente aucune interface de service au-delà de celles nécessaires au modèle économique. En d’autres termes , un cours POJO n’est qu’un cours sans exigences particulières. La seule exigence est l’absence de cloches et de sifflets liés à un cadre spécifique. En règle générale, ces classes n'héritent pas d'autres classes (à l'exception des classes POJO du même package), n'implémentent pas d'interfaces - parfois une exception est faite pour les interfaces de marqueurs de la bibliothèque standard telles que Serialisable ou Cloneable - n'utilisent pas d'annotations et ne dépendent pas de bibliothèques tierces. Mais je note que les POJO peuvent avoir des méthodes avec une logique métier et des constructeurs de toute sorte. Si vous autorisez les annotations qui n'apportent pas de modifications à la sémantique de la classe (sans lesquelles le but de l'objet et la logique de son fonctionnement ne changeront pas), les POJO peuvent également inclure des entités JPA Entity et des objets DTO désérialisés à partir de XML ou JSON , dont les règles sont précisées dans les annotations. Il est également conseillé de remplacer equals et hashCode pour les classes POJO , car cela peut les aider à mieux remplir leur rôle. Exemple de classe POJO :
public class User {
   private Long id;
   private String firstName;
   private String lastName;
   private Long age;

   public User(final Long id, final String firstName, final String lastName, final long age) {
       this.id = id;
       this.firstName = firstName;
       this.lastName = lastName;
       this.age = age;
   }

   public Long getId() {
       return this.id;
   }

   public String getFirstName() {
       return this.firstName;
   }

   public String getLastName() {
       return this.lastName;
   }

   public Long getAge() {
       return this.age;
   }

   @Override
   public boolean equals(final Object o) {
       if (this == o) return true;
       if (o == null || this.getClass() != o.getClass()) return false;
       final User user = (User) o;
       return Objects.equals(this.id, user.id) &&
               Objects.equals(this.firstName, user.firstName) &&
               Objects.equals(this.lastName, user.lastName) &&
               Objects.equals(this.age, user.age);
   }

   @Override
   public int hashCode() {
       return Objects.hash(this.id, this.firstName, this.lastName, this.age);
   }
}

26. Quels éléments une classe peut-elle contenir ?

La classe peut contenir les éléments suivants :
  • champs de classe ;
  • champs de classe statiques ;
  • bloc d'initialisation ;
  • bloc d'initialisation statique ;
  • constructeurs (vide est toujours défini par défaut) ;
  • méthodes;
  • méthodes statiques ;
  • diverses annotations (qui peuvent être accrochées au-dessus de la classe elle-même ou de ses composants) ;
  • génériques ;
  • héritage d'autres classes ( extends ) ou implémentation d'interfaces ( Implements ).

27. Expliquez l'héritage en Java. Quels sont les avantages de l’utilisation du super mot-clé ?

Ci-dessus, j'ai déjà parlé de l'héritage et du mot-clé super en Java. Permettez-moi de mentionner quelques points plus importants :
  1. Il est possible d'hériter d'une seule classe : il n'y a pas d'héritage multiple en Java (mais avec l'avènement des méthodes par défaut dans Java 8, cette affirmation deviendra très controversée).
  2. Les méthodes et les champs privés sont également hérités, ils n'y auront tout simplement pas accès de la part de l'héritier (mais si, par exemple, nous avons un champ privé et qu'il y a des getters et setters publics ou protégés pour celui-ci, le champ peut être utilisé avec à travers eux).
  3. les classes finales ne sont pas héritées.
  4. Les méthodes final ne sont pas remplacées (mais elles peuvent être héritées et surchargées).
  5. les méthodes et variables statiques ne sont pas héritées (puisqu'elles ne sont pas liées aux objets, mais aux classes).
  6. Lors de l'héritage de classes abstraites, l'implémentation de leurs méthodes abstraites est requise, ou la classe actuelle doit également être déclarée abstraite.
  7. S'il existe des constructeurs autres que ceux par défaut dans le parent, ils doivent être remplacés dans la classe enfant (mais @Override n'est pas écrit dessus).
  8. Les méthodes remplacées dans le descendant peuvent être étendues avec un modificateur d'accès : private -> default -> protected -> public .
  9. Les méthodes remplacées dans le descendant peuvent restreindre les exceptions écrites, par exemple : Exception -> IOException -> FileNotFoundException.
Analyse des questions et réponses des entretiens pour développeur Java.  Partie 3 à 5

28. Qu'est-ce qu'une signature de méthode ? Donnez des exemples de signatures correctes et incorrectes

La signature d'une méthode est le nom de la méthode plus les types des paramètres entrants (et l'ordre des paramètres compte). La signature de la méthode n'inclut pas la valeur de retour ni les exceptions qu'elle génère. Exemple de signature correcte :
doSomething(int, double, double)
Un exemple de signature incorrecte :
void doSomething(int firstArg, int secondArg) throws Exception
La signature de la méthode, combinée au type de retour et à la liste des exceptions levées, est appelée contrat de méthode . C'est tout pour aujourd'hui. À plus tard!Analyse des questions et réponses des entretiens pour développeur Java.  Partie 3 à 6
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION