JavaRush /Blog Java /Random-FR /Les 13 principales questions sur la sérialisation lors de...
Dmitry Vasilyev
Niveau 26
Саратов

Les 13 principales questions sur la sérialisation lors des entretiens

Publié dans le groupe Random-FR
Traduction de l'article https://javarevisited.blogspot.com/2011/04/top-10-java-serialization-interview.html Qu'est-ce que la sérialisation en Java ? La sérialisation est l'un des concepts importants qui est assez rarement utilisé comme solution pour sauvegarder l'état des programmes et cette API est donc souvent négligée par les développeurs. Cependant, d'après mon expérience, la sérialisation est un sujet assez important dans toute interview Java de base. Presque tous les entretiens que j'ai rencontrés comportaient une ou deux questions sur la sérialisation, et j'ai vu des candidats se sentir mal à l'aise face à leur manque d'expérience dans ce domaine après quelques questions sur ce sujet. Ils ne savent pas comment sérialiser un objet en Java, ils ne connaissent aucun exemple de sérialisation et ne peuvent pas expliquer les mécanismes de son travail, la différence entre une variable transitoire et une variable volatile, ils ne savent pas combien de méthodes l'interface sérialisable a. Qu'est-ce qu'une interface de marqueur ? Quel est son but? Quelle est la différence entre l’implémentation externalisable et sérialisable en Java ? Pourquoi Java n'a-t-il pas remplacé Seriallessly par @Seriallessly après avoir introduit l'annotation ? Dans cet article, nous aborderons des questions destinées aux développeurs débutants et avancés, qui peuvent être également utiles à tout le monde : des développeurs juniors aux développeurs seniors. La plupart des projets commerciaux utilisent soit des bases de données, des fichiers mappés en mémoire ou simplement des fichiers plats pour offrir une plus grande robustesse, mais peu d'entre eux s'appuient sur le processus de sérialisation de Java. Dans tous les cas, cet article n'est pas un tutoriel - il s'agit plutôt de questions qui méritent d'être clarifiées par vous-même avant de vous rendre à un entretien Java et d'être surpris par des termes inconnus de vous-même. Pour ceux qui ne sont pas du tout familiers avec la sérialisation Java : « La sérialisation en Java est un processus utilisé pour sérialiser un objet en Java en stockant l'état de l'objet dans un fichier avec une extension .ser et en recréant l'état de l'objet. à partir de ce fichier. Ce processus inverse est appelé désérialisation. sépulka L'API Java Serialization fournit aux développeurs un mécanisme standard pour sérialiser des objets à l'aide des interfaces Serialisable et Externalisable. D'ailleurs, cet article est une continuation de mes articles précédents ( pas le mien, le traducteur, mais l'auteur de l'original anglais) : 20 questions d'entretien sur les modèles de conception et 10 questions d'entretien sur le modèle Singleton en Java . Alors allons-y! Qu’est-ce que la sérialisation en Java ? La sérialisation d'objets en Java est un processus utilisé pour convertir un objet dans un format binaire qui peut être enregistré sur le disque ou envoyé sur le réseau à toute autre machine virtuelle Java en cours d'exécution. le processus inverse de création d'un objet à partir d'un flux binaire est appelé désérialisation. Java fournit une API qui inclut java.io.Serializing, java.io.Externalizing, ObjectInputStream et ObjectOutputStream, etc. Les programmeurs sont libres d'utiliser le mécanisme de sérialisation par défaut utilisé par Java en fonction de la structure de classe, mais ils peuvent également utiliser leur propre format binaire personnalisé, qui est souvent recommandé comme meilleure pratique de sérialisation car le format binaire sérialisé devient partie intégrante de l'API exportée de la classe. et peut potentiellement rompre l'encapsulation en Java fournie par les champs privés et privés du package . En général, ces informations seront largement suffisantes pour commencer. Comment rendre une classe Java sérialisable ? C'est très facile. Votre classe doit simplement implémenter l'interface java.io.Seriallessly et la JVM se chargera de sérialiser l'objet dans un format par défaut. La décision de créer une classe sérialisable doit être prise brièvement car, bien que les coûts à court terme liés à la création d'une classe sérialisable soient faibles, les coûts à long terme sont importants et peuvent potentiellement limiter votre capacité à apporter d'autres modifications à l'implémentation. Cela se produit parce que, comme toute API publique, la forme sérialisée d'un objet devient une partie de l'API publique, et lorsque vous modifiez la structure de votre classe en implémentant une interface d'ajout, l'ajout ou la suppression d'un champ peut potentiellement rompre la sérialisation par défaut. Cependant, cela peut être minimisé en utilisant un format binaire personnalisé, mais cela nécessite encore beaucoup d'efforts pour garantir la compatibilité ascendante. Le champ SerialVersionUID est un exemple de la manière dont la sérialisation peut limiter votre capacité à modifier une classe. Si vous ne déclarez pas explicitement le SerialVersionUID, la machine virtuelle le génère en fonction de la structure de la classe, qui dépend des interfaces implémentées par la classe et de plusieurs autres facteurs qui peuvent être modifiés. Disons que vous implémentez une interface différente par opposition à la JVM, qui générera un SerialVersionUID différent pour la nouvelle version des fichiers de classe, et lorsque vous essayez de charger un ancien objet sérialisé par l'ancienne version de votre programme, vous obtiendrez un InvalidClassException. Question 1) Quelle est la différence entre les interfaces sérialisable et externalisable en Java ? Il s'agit de la question d'entretien sur la sérialisation Java la plus fréquemment posée. L'interface Externalisable nous fournit les méthodes writeExternal() et readExternal(), qui nous donnent la flexibilité de contrôler la sérialisation au lieu de nous fier au mécanisme par défaut. Une bonne implémentation de l’interface externalisable peut améliorer considérablement les performances des applications. Question 2) Combien de méthodes Serialisable possède-t-il ? S’il n’y a pas de méthode, quel est le but de l’interface Serialisable ? L'interface sérialisable existe dans le package java.io et constitue le cœur du moteur de sérialisation de Java. Il n'a aucune méthode et est également appelé interface de marqueur en Java. Lorsque votre classe implémente l'interface java.io.Serializing, elle devient sérialisable. C'est simple. Question 3) Qu'est-ce que SerialVersionUID ? Que se passe-t-il si vous ne le définissez pas ? Une de mes questions d'entretien de sérialisation Java préférées. SerialVersionUID est un identifiant placé sur un objet lors de sa sérialisation, généralement un code de hachage de l'objet. Vous pouvez utiliser l'outil Serialver pour obtenir le SerialVersionUID de l'objet sérialisé. SerialVersionUID est utilisé pour le contrôle de version des objets. Vous pouvez également spécifier manuellement SerialVersionUID dans votre fichier de classe. La conséquence de ne pas spécifier SerialVersionUID est que si vous ajoutez ou modifiez un champ dans une classe, la classe déjà sérialisée ne pourra pas être récupérée car le SerialVersionUID généré pour la nouvelle classe sera différent du même champ de l'ancien objet sérialisé. Le processus de sérialisation Java s'appuie sur le SerialVersionUID correct pour restaurer l'état de l'objet sérialisé et renvoie une java.io.InvalidClassException en cas de non-concordance. Pour en savoir plus sur Serialversionuid, voir ici . Question 4) Lors de la sérialisation, souhaitez-vous que certains membres ne soient pas sérialisés ? Comment y parvenir ? Une autre question d’entretien de sérialisation fréquemment posée. Parfois, les gens demandent également comment une variable transitoire est utilisée, si une variable transitoire et statique est sérialisée ou non, etc., donc si vous ne voulez pas qu'un champ fasse partie de l'état de l'objet, déclarez-le comme statique ou transitoire selon selon vos besoins, et il ne sera pas inclus dans le processus de sérialisation Java. Question 5) Que se passe-t-il si l'un des membres de la classe n'implémente pas l'interface Serialisable ? Une des questions simples sur le processus de sérialisation en Java. Si vous essayez de sérialiser un objet d'une classe qui implémente Serialisable, mais que l'objet inclut une référence à une classe qui n'est pas Serialisable, alors une exception NotSerializingException sera levée au moment de l'exécution, et c'est pourquoi je mets toujours une Alerte Serialisable (section commentaires dans mon code), l'une des meilleures techniques de commentaire de code consiste à demander au développeur de se souvenir de ce fait lors de l'ajout d'un nouveau champ à la classe Serialisable. Question 6) Si une classe est sérialisable mais que sa superclasse ne l'est pas, quel sera l'état des variables d'instance héritées de la superclasse après désérialisation ? Le processus de sérialisation Java se poursuit uniquement dans la hiérarchie des objets tant que la classe implémente l'interface Serialisable et que les valeurs des variables héritées de la superclasse seront initialisées en appelant le constructeur de la superclasse non sérialisable pendant le processus de désérialisation. Une fois que la chaîne de constructeurs a démarré, il n'y a aucun moyen de l'arrêter, donc même si les classes supérieures dans la hiérarchie implémentent (n'implémentent pas) l'interface Serialisable , le constructeur sera exécuté. Cette question d'entretien de sérialisation peut sembler très difficile, mais si vous connaissez les concepts clés, elle ne sera pas difficile. Question 7) Pouvez-vous personnaliser le processus de sérialisation ou remplacer le processus de sérialisation par défaut en Java ? La réponse est oui, vous le pouvez. Nous savons tous que pour sérialiser un objet, ObjectOutputStream.writeObject(saveThisObject) est appelé et pour lire un objet, ObjectInputStream.readObject() est appelé, mais la machine virtuelle Java vous offre encore une chose : définir ces deux méthodes. Dans votre classe. Si vous les définissez dans votre classe, la JVM appellera ces deux méthodes au lieu d'utiliser le mécanisme de sérialisation par défaut. Ici, vous pouvez configurer le comportement de sérialisation et de désérialisation de l'objet en effectuant n'importe quelle tâche de prétraitement ou de post-traitement. Il est important de noter que ces méthodes doivent être privées pour éviter l’héritage, le remplacement ou la surcharge. Puisque seule la machine virtuelle Java peut appeler une méthode privée, l'intégrité de votre classe sera préservée et la sérialisation fonctionnera comme d'habitude. À mon avis, c'est l'une des meilleures questions que l'on puisse poser lors de tout entretien sur la sérialisation Java. Une bonne question de suivi est la suivante : pourquoi auriez-vous besoin de fournir un formulaire sérialisé personnalisé pour votre objet ? Question 8) Supposons que la superclasse d'une nouvelle classe implémente l'interface Serialisable, comment pouvons-nous éviter de sérialiser la nouvelle classe ? L'une des questions d'entretien difficiles sur la sérialisation en Java. Si la superclasse d'une classe implémente déjà l'interface Serialisable en Java, alors la classe descendante est également sérialisable, car vous ne pouvez pas implémenter l'interface parent et il n'est pas vraiment possible d'en faire une classe non sérialisable. Il existe cependant un moyen d’éviter la sérialisation pour cette nouvelle classe. Pour ce faire, vous devez implémenter les méthodes writeObject() et readObject() et lancer NotSerializingException à partir de ces méthodes. Cette question est généralement posée comme question supplémentaire au fur et à mesure de la progression de l'entretien. Question 9) Quelles sont les méthodes utilisées dans le processus de sérialisation et de désérialisation en Java ? C'est une question très courante en matière de sérialisation. Qu’est-ce que l’intervieweur essaie de découvrir dans ce cas ? Que vous soyez familier avec l'utilisation de readObject(), writeObject(), readExternal() et writeExternal() ou non. La sérialisation Java est effectuée par la classe java.io.ObjectOutputStream. Cette classe est un flux filtré enroulé autour d'un flux d'octets de niveau inférieur pour gérer le moteur de sérialisation. Pour enregistrer n'importe quel objet à l'aide du mécanisme de sérialisation, nous appelons ObjectOutputStream.writeObject(saveThisObject) et pour désérialiser cet objet, nous appelons la méthode ObjectInputStream.readObject(). L'appel de la méthode writeObject() démarre le processus de sérialisation. Une chose importante à noter à propos de la méthode readObject() est qu'elle est utilisée pour lire des octets et pour créer et renvoyer un objet à partir de ces octets, qui à son tour doit être converti dans le type correct. Question 10) Supposons que vous ayez une classe que vous avez sérialisée et enregistrée, puis que vous modifiez cette classe pour ajouter un nouveau champ. Que se passe-t-il si vous désérialisez un objet déjà sérialisé ? Cela dépend si la classe possède ou non son propre SerialVersionUID. Comme nous le savons grâce aux questions ci-dessus, si nous ne fournissons pas serialVersionUID dans notre code, le compilateur Java le générera lui-même et il sera généralement égal au code de hachage de cet objet. Après avoir ajouté un nouveau champ, il est possible que le nouveau SerialVersionUID généré pour cette version de la classe ne corresponde pas à l'objet déjà sérialisé, auquel cas l'API lancera une java.io.InvalidClassException. Pour cette raison, il est recommandé d’avoir votre propre SerialVersionUID dans votre code, qui est toujours le même pour la même classe. Question 11) Quels sont les changements compatibles et incompatibles dans le mécanisme de sérialisation Java ? Le vrai problème consiste à modifier la structure des classes en ajoutant n'importe quel champ, méthode ou en supprimant n'importe quel champ ou méthode avec un objet déjà sérialisé. Selon la spécification de sérialisation Java, l'ajout d'un champ ou d'une méthode relève des changements compatibles et de la modification de la hiérarchie des classes ou des interfaces sérialisables implémentant l'ONU, certaines sous des changements non compatibles). Pour une liste complète des modifications compatibles et incompatibles, je suggère de lire la spécification de sérialisation Java. Question 12) Peut-on transférer un objet sérialisé sur le réseau ? Oui, vous pouvez transmettre un objet sérialisé sur le réseau, car un objet sérialisé Java est une collection d'octets qui peuvent être transmis de n'importe quelle manière. Vous pouvez également stocker l'objet sérialisé sur disque ou dans une base de données en tant que Blob. Question 13) Quels types de variables ne sont pas sérialisés lors de la sérialisation Java ? Cette question a parfois été posée différemment, mais le but est le même : savoir si un développeur Java connaît les spécificités de la sérialisation des variables statiques et transitoires. Étant donné que les variables statiques appartiennent à une classe et non à un objet, elles ne font pas partie de l'état de l'objet et ne sont donc pas conservées pendant le processus de sérialisation Java. Étant donné que la sérialisation Java stocke uniquement l'état d'un objet et non l'objet lui-même, les variables transitoires ne sont pas non plus incluses dans le processus de sérialisation et ne font pas partie de l'état sérialisé de l'objet. Après cette question, peut-être que l'intervieweur demandera : si vous ne stockez pas les valeurs de ces variables, alors quelle sera la valeur de ces variables après désérialisation et recréation de cet objet ? Et cela, chers collègues, pensez par vous-mêmes :) L'article original est ici .
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION