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 6

Publié dans le groupe Random-FR
Bonjour le monde! Continuer à se développer est très important pour tout développeur. Après tout, si vous vous arrêtez, vous risquez de ne plus être réclamé et de disparaître complètement du marché : le monde informatique se développe et avance constamment, et vous devez évoluer avec lui. Mais même en même temps, on ne peut pas se concentrer uniquement sur les technologies nouvelles et fraîches, pour ne pas oublier, pour ainsi dire, les classiques (sujets classiques). Aujourd’hui je souhaite poursuivre mon analyse de questions sur des sujets « classiques » pour un développeur Java. Analyse des questions et réponses des entretiens pour développeur Java.  Partie 6 - 1Je note que mes réponses ne constituent pas l'autorité finale - c'est simplement ainsi que je vois les bonnes réponses à ces questions, et vous n'êtes peut-être pas d'accord avec certaines d'entre elles. Ce sera tout à fait normal, alors n'hésitez pas à partager votre avis dans les commentaires. Les liens vers des parties de l’analyse se trouvent à la fin de l’article.Analyse des questions et réponses des entretiens pour développeur Java.  Partie 6 - 2

Bibliothèques et normes

52. Qu'est-ce que la mise en veille prolongée ? Quelle est la différence entre JPA et Hibernate ?

Je pense que pour répondre à cette question, nous devons d'abord comprendre ce qu'est JPA . JPA est une spécification qui décrit le mappage objet-relationnel d'objets Java simples et fournit une API pour stocker, récupérer et manipuler ces objets. Autrement dit, on s'en souvient, les bases de données relationnelles (DB) se présentent sous la forme de nombreuses tables interconnectées. Et JPA est une norme largement acceptée qui décrit comment les objets peuvent interagir avec les bases de données relationnelles. Comme vous pouvez le constater, JPA est quelque chose d’abstrait et d’intangible. C’est comme l’idée elle-même, la démarche. Analyse des questions et réponses des entretiens pour développeur Java.  Partie 6 - 3En même temps, Hibernate est une bibliothèque spécifique qui implémente les paradigmes JPA . Autrement dit, avec l'aide de cette bibliothèque, vous pouvez travailler avec une base de données relationnelle via des objets qui représentent les données de la base de données (Entité). Comme on dit, cette bibliothèque est très proche des idéaux de JPA et c'est peut-être pour cela qu'elle est devenue populaire. Et comme vous le comprenez, la popularité de l'utilisation est un bon argument en faveur d'un développement et d'améliorations ultérieurs. De plus, derrière son utilisation fréquente se cache une énorme communauté qui a déjà résolu toutes les questions possibles et impossibles liées à cet outil. Voici un exemple de livre qui examine en détail tous les coins sombres de cette technologie. Autrement dit, Hibernate a été étudié autant que possible et s'avère fiable. En fait, ce n'est pas pour rien que même l'implémentation idéale de JPA côté Spring utilise généralement Hibernate sous le capot.

53. Qu'est-ce que la cascade ? Comment est-il utilisé dans Hibernate ?

Comme je l'ai dit plus tôt, dans Hibernate, la communication s'effectue via des objets de données appelés entités . Ces entités représentent certaines tables spécifiques de la base de données et, comme vous vous en souvenez, en Java, les classes peuvent contenir des références à d'autres classes. Ces relations sont reflétées dans la base de données. Dans une base de données, en règle générale, il s'agit soit de clés étrangères (pour OneToOne, OneToMany, ManyToOne), soit de tables intermédiaires (pour ManyToMany). Vous pouvez en savoir plus sur la relation entre les entités dans cet article . Lorsque votre entité possède des liens vers d'autres entités liées, des annotations sont placées au dessus de ces liens pour indiquer le type de connexion : @OneToOne, @OneToMany, @ManyToOne, @ManyToMane, dans les paramètres desquels vous pouvez préciser la valeur de la propriété - cascade - la type de cascade pour cette connexion. JPA dispose de méthodes spécifiques pour interagir avec les entités (persister, sauvegarder, fusionner...) . Les types en cascade sont précisément utilisés pour montrer comment les données associées doivent se comporter lorsque ces méthodes sont utilisées sur l'entité cible. Alors, quelles sont les stratégies en cascade (types de cascade) ? La norme JPA implique l'utilisation de six types de mise en cascade :
  • PERSIST - les opérations de sauvegarde se produiront en cascade (pour les méthodes save() et persist() ). Autrement dit, si nous enregistrons une entité associée à d'autres entités, elles sont également enregistrées dans la base de données (si elles n'y sont pas déjà)

  • MERGE - les opérations de mise à jour se produiront en cascade (pour la méthode merge() )

  • REMOVE - les opérations de suppression se produisent en cascade ( méthode Remove() )

  • ALL - contient trois opérations en cascade à la fois - PERSIST - MERGE - REMOVE

JPA a le concept d' entité persistante - une entité associée à ses données dans la base de données, qui est contrôlée par la session en cours (connexion) . Si vous le modifiez, mais n'enregistrez pas les modifications dans la base de données, ses données dans la base de données seront quand même modifiées.
  • Les entités liées à DETACH ne seront pas gérées par la session ( méthode detach() ). Autrement dit, lorsqu'ils changent, il n'y aura pas de changement automatique de leurs données dans la base de données - ils sont transférés de l'état de persistance à détaché (une entité non gérée par JPA)

  • REFRESH - chaque fois qu'une entité est mise à jour avec les données de la base de données ( refresh() - met à jour les objets détachés), les entités associées sont mises à jour de la même manière. Par exemple, vous avez modifié d'une manière ou d'une autre les données extraites de la base de données et souhaitez renvoyer leurs valeurs d'origine. Dans ce cas, cette opération vous sera utile.

Analyse des questions et réponses des entretiens pour développeur Java.  Partie 6 - 4Hibernate prend en charge toutes ces opérations en cascade standard, mais en introduit également trois :
  • REPLICATE - Utilisé lorsque nous avons plus d'une source de données et que nous souhaitons que les données soient synchronisées (méthode Hibernate - répliquer). Toutes les entités doivent avoir des identifiants (id) pour qu'il n'y ait pas de problèmes avec leur génération (afin qu'une même entité n'ait pas d'identifiants différents pour différentes bases de données)

  • SAVE_UPDATE - sauvegarde/suppression en cascade (pour la méthode Hibernate - saveOrUpdate )

  • LOCK est l'opération inverse de DETACHED : elle transfère l' entité détachée à l' état de persistance , c'est-à-dire l'entité sera à nouveau suivie par la session en cours

Si le type cascade n'est pas sélectionné, aucune opération sur une entité n'aura d'effet sur les autres entités qui lui sont associées.

54. Une classe Entity peut-elle être abstraite ?

Dans la spécification JPA , au paragraphe 2.1 The Entity Class, il y a une ligne : « Les classes abstraites et concrètes peuvent être des entités . La réponse est donc oui, une classe abstraite peut être une entité et peut être annotée avec @Entity.

55. Qu'est-ce qu'un gestionnaire d'entité ? De quoi est-il responsable ?

Tout d'abord, je voudrais noter qu'EntityManager est l'un des composants clés de JPA , qui est utilisé pour interagir avec les entités avec la base de données. En général, il appelle les méthodes d'interaction entre l'entité et la base de données (persister, fusionner, supprimer, détacher)... Mais je noterais aussi que ce composant, en règle générale, n'en est pas un pour l'ensemble de l'application : le plus souvent il est léger et est souvent supprimé et un nouveau est créé à l'aide de EntityManagerFactory . Si nous faisons un parallèle avec JDBC , où EntityManagerFactory sera un analogue de DataSource , alors EntityManager, à son tour, sera un analogue de Connection . Plus tôt, j'ai mentionné une entité de persistance , en tant qu'entité contrôlée par la connexion actuelle. Donc : cette entité est gérée précisément par le EntityManager , qui est étroitement lié à la connexion actuelle et le TransactionManager , qui est responsable de l'ouverture/fermeture des transactions. Plus loin dans la figure ci-dessous, vous pouvez voir le cycle de vie d'une entité : Analyse des questions et réponses des entretiens pour développeur Java.  Partie 6 à 5EntityManager gère l'entité lorsqu'elle est au stade Géré (à ce stade, elle est persistante, car elle a une connexion avec EntityManager). C'est-à-dire qu'il n'est plus nouveau et n'a pas encore été supprimé. On peut dire que lorsqu'une entité est nouvelle ou supprimée, elle est également détachée, car il n'est pas géré par EntityManager. Il existe différentes stratégies pour EntityManager. Autrement dit, il peut y avoir un seul EntityManager pour l'ensemble de l'application, ou un nouveau peut être créé à chaque fois, pour chaque connexion. Si vous utilisez Spring, alors la création/suppression d'EntityManager est contrôlée automatiquement sous le capot (mais cela ne veut pas dire que vous ne pouvez pas le personnaliser ^^). Il vaut la peine de dire qu'un ou plusieurs EntityManagers forment le contexte de persistance . Le contexte de persistance est un environnement dans lequel les instances d'entités sont synchronisées avec des entités similaires dans la base de données (comme je l'ai dit, cela ne fonctionne que pour les entités persistantes). Si vous approfondissez JPA (ce que je recommande vivement), vous rencontrerez très, très souvent ces concepts.

56. Qu'est-ce que la classe Assert ? Pourquoi l'utiliser ?

Je n'ai pas entendu parler d'une telle classe dans JPA , je suppose donc que cela fait référence à la classe JUnit de la bibliothèque, qui est utilisée pour les tests unitaires du code. La classe de cette bibliothèque, Assert , est utilisée pour vérifier les résultats de l'exécution du code ( assert est une déclaration selon laquelle vous avez un certain état/données à un certain endroit). Par exemple, vous testez une méthode qui devrait créer un chat. Vous exécutez une méthode et obtenez un résultat :
Cat resultOfTest = createCat();
Mais vous devez vous assurer qu’il a été créé correctement, n’est-ce pas ? Par conséquent, vous avez précédemment créé manuellement un certain chat - attenduCat - avec exactement les paramètres que vous attendez du chat obtenu à partir de la méthode createCat() . Ensuite, vous utilisez la classe Assert pour vérifier les résultats :
Assert.assertEquals(resultOfTest, expectedCat);
Si les chats sont différents, une exception AssertionError sera levée , ce qui nous indique que les résultats attendus ne convergent pas. La classe Assert dispose de nombreuses méthodes différentes qui couvrent de nombreuses tâches de vérification des résultats attendus. En voici quelques uns:
  • assertTrue(<boolean>) - la valeur attendue reçue en argument doit être vraie

  • assertFalse(<boolean>) - la valeur attendue reçue en argument doit être fausse

  • assertNotEquals(<object1>, <object2>) - les objets reçus comme arguments doivent être différents lorsqu'ils sont comparés à l'aide de equals ( false )

  • assertThrows(<ClassNameOfException>.class, <exceptionObject>) - le deuxième argument est censé être une exception de la classe spécifiée par le premier argument (c'est-à-dire qu'en règle générale, à la place du deuxième argument, une méthode est appelée qui devrait lancer une exception du type requis)

Chaîne

57. Caractériser la chaîne en Java

String est une classe standard en Java, responsable du stockage et de la manipulation des valeurs de chaîne (séquences de caractères), est une classe immuable ( j'ai parlé d' immuable plus tôt ), c'est-à-dire Les données des objets de cette classe ne peuvent pas être modifiées après la création. Je voudrais immédiatement noter que les classes StringBuilder et StringBuffer sont deux classes pratiquement identiques, la seule différence étant que l'une d'elles est destinée à être utilisée dans un environnement multithread (StringBuffer). Ces classes sont analogues à String , mais contrairement à elle, elles sont mutables . Autrement dit, les objets, une fois créés, permettent de modifier la chaîne qu'ils représentent sans créer de nouvel objet. En fait, les méthodes diffèrent des méthodes String standard et visent à répondre aux besoins de modification de la chaîne (ce n'est pas pour rien qu'on les appelle constructeur). En savoir plus sur String , StringBuffer et StringBuilder dans cet article .

58. Quelles sont les différentes manières de créer un objet String ? Où est-il créé ?

La manière la plus courante de créer une chaîne consiste simplement à spécifier la valeur dont nous avons besoin entre doubles parenthèses :
String str = "Hello World!";
Vous pouvez également le faire directement via new :
String str = new String("Hello World!");
Vous pouvez créer une chaîne à partir d'un tableau de caractères :
char[] charArr = {'H','e','l','l','o',' ', 'W','o','r','l','d','!'};
String str = new String(charArr);
En raison de l'exécution de la méthode toString sur un objet :
String str = someObject.toString();
Comme le résultat de toute autre méthode, elle renvoie une représentation sous forme de chaîne. Par exemple:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String str =  reader.readLine();
Comme vous le comprenez, il peut y avoir de très nombreuses façons de créer une chaîne. Lorsqu'un objet String est créé, il est stocké dans le pool de chaînes , dont nous parlerons plus en détail dans l'une des questions ci-dessous.

59. Comment comparer deux chaînes en Java et comment les trier ?

Java utilise le double signe égal == pour comparer les valeurs . Si nous avions besoin de comparer des valeurs simples comme int , nous l'utiliserions. Mais cette méthode n'est pas applicable pour comparer des objets à part entière. Dans ce cas, il s’agira uniquement d’une comparaison de références – qu’elles pointent ou non vers le même objet. Autrement dit, lors de la comparaison de deux objets avec exactement les mêmes valeurs de champs internes, la comparaison via == donnera le résultat faux : malgré les champs identiques des objets, les objets eux-mêmes occupent des cellules mémoire différentes. Et les objets de la classe String , malgré leur simplicité trompeuse, sont toujours des objets. Et la comparaison via == ne leur est pas non plus applicable (même malgré la présence d'un pool de chaînes). Ici, la méthode standard de la classe Object entre en jeu - equals , qui doit être remplacée dans la classe pour qu'elle fonctionne correctement (sinon, par défaut, elle compare en utilisant == ). Il est remplacé dans la classe String , nous le prenons donc et l'utilisons :
String firstStr = "Hello World!";
String secondStr = "Hello World!";
boolean isEquals = firstStr.equals(secondStr);
Analyse des questions et réponses des entretiens pour développeur Java.  Partie 6 - 6Nous avons parlé des comparaisons d'appariement, regardons maintenant les comparaisons de tri. Après tout, pour trier quelque chose, nous devons savoir selon quel principe trier. Pour ce faire, vous pouvez utiliser un ensemble trié standard - TreeSet . Vous pouvez en savoir plus sur les différentes collections en Java dans cet article . Cette liste fonctionne sur la base de l'algorithme de l'arbre rouge-noir et trie l'ensemble conformément au principe de tri spécifié. Comme je l'ai dit plus tôt, vous devez comprendre comment trier les objets d'un certain type. Les comparateurs sont utilisés pour définir la méthode de comparaison pour le tri . Généralement, ceux-ci doivent être implémentés pour les classes que vous souhaitez trier, mais dans le cas de String , ils sont déjà implémentés. Par conséquent, nous ajoutons simplement les lignes dont nous avons besoin au TreeSet , et il les triera :
TreeSet<String> sortedSet = new TreeSet<>();
sortedSet.add("B");
sortedSet.add("C");
sortedSet.add("A");
sortedSet.forEach(System.out::println);
Sortie de la console :
ABC

60. Donnez un algorithme pour convertir une chaîne en caractère. Écrivez le code approprié

Comme je l'ai dit plus tôt, les objets de la classe String ont de nombreuses méthodes utiles différentes. L'un d'eux est toCharArray . Cette méthode convertit une chaîne en tableau de caractères :
String str = "Hello world";
char[] charArr = str.toCharArray();
Nous avons ensuite un tableau de caractères que nous pouvons appeler par index :
char firstChar = charArr[0]; // H

61. Comment convertir une chaîne en un tableau d'octets et inversement ? Écrivez le code approprié

Semblable à la méthode toCharArray , la classe String possède une méthode getBytes qui renvoie un tableau d'octets de la chaîne :
String str = "Hello world";
byte[] byteArr = str.getBytes();
byte firstChar = byteArr[6]; // 119
La partie de l’analyse d’aujourd’hui a atteint sa fin logique. Merci pour votre attention!Analyse des questions et réponses des entretiens pour développeur Java.  Partie 6 - 7
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION