JavaRush /Blog Java /Random-ES /Las 13 preguntas principales sobre la serialización en la...
Dmitry Vasilyev
Nivel 26
Саратов

Las 13 preguntas principales sobre la serialización en las entrevistas

Publicado en el grupo Random-ES
Traducción del artículo https://javarevisited.blogspot.com/2011/04/top-10-java-serialization-interview.html ¿Qué es la serialización en Java? La serialización es uno de los conceptos importantes que rara vez se utiliza como solución para guardar el estado de los programas y, por lo tanto, los desarrolladores suelen pasar por alto esta API. Sin embargo, en mi experiencia, la serialización es un tema bastante importante en cualquier entrevista básica sobre Java. Casi todas las entrevistas con las que me he encontrado tienen una o dos preguntas sobre la serialización y he visto candidatos sentirse incómodos por su falta de experiencia en esta área después de algunas preguntas sobre este tema. No saben cómo serializar un objeto en Java, no están familiarizados con ningún ejemplo de serialización y no pueden explicar la mecánica de su trabajo, la diferencia entre una variable transitoria y volátil, no saben cuántos métodos utiliza la interfaz serializable. tiene. ¿Qué es una interfaz de marcador? ¿Cual es su propósito? ¿Cuál es la diferencia entre la implementación externalizable y serializable en Java? ¿Por qué Java no reemplazó Serializable con @Serializable después de introducir la anotación? En este artículo, cubriremos preguntas tanto para desarrolladores principiantes como avanzados, que pueden ser igualmente útiles para todos: desde desarrolladores junior hasta desarrolladores senior. La mayoría de los proyectos comerciales utilizan bases de datos, archivos mapeados en memoria o simplemente archivos planos para proporcionar mayor solidez, pero pocos dependen del proceso de serialización de Java. En cualquier caso, esta publicación no es un tutorial, se trata más bien de preguntas que vale la pena aclarar antes de acudir a cualquier entrevista sobre Java y sorprenderse con términos desconocidos para usted. Para aquellos que no están familiarizados con la serialización de Java: “La serialización en Java es un proceso que se utiliza para serializar un objeto en Java almacenando el estado del objeto en un archivo con una extensión .ser y recreando el estado del objeto. de este archivo. Este proceso inverso se llama deserialización. sepulca La API de serialización de Java proporciona a los desarrolladores un mecanismo estándar para serializar objetos utilizando las interfaces serializable y externalizable. Por cierto, este artículo es una continuación de mis artículos anteriores ( no míos, del traductor, sino del autor del original en inglés) : 20 preguntas de entrevista sobre patrones de diseño y 10 preguntas de entrevista sobre el patrón Singleton en Java . ¡Entonces vamos! ¿Qué es la serialización en Java? La serialización de objetos en Java es un proceso utilizado para convertir un objeto a un formato binario que puede guardarse en el disco o enviarse a través de la red a cualquier otra máquina virtual Java en ejecución; El proceso inverso de crear un objeto a partir de un flujo binario se llama deserialización. Java proporciona una API que incluye java.io.Serializable, java.io.Externalizable, ObjectInputStream y ObjectOutputStream, etc. Los programadores son libres de usar el mecanismo de serialización predeterminado que usa Java según la estructura de clases, pero también pueden usar su propio formato binario personalizado, que a menudo se recomienda como una mejor práctica de serialización porque el formato binario serializado se convierte en parte de la API exportada de la clase. y potencialmente puede romper la encapsulación en Java proporcionada por campos privados y privados de paquetes . En general, esta información será suficiente para empezar. ¿Cómo hacer que una clase Java sea serializable? Es muy fácil. Su clase simplemente necesita implementar la interfaz java.io.Serializable y la JVM se encargará de serializar el objeto en un formato predeterminado. La decisión de crear una clase serializable se debe tomar brevemente porque, aunque los costos a corto plazo de crear una clase serializable son bajos, los costos a largo plazo son significativos y potencialmente pueden limitar su capacidad para realizar modificaciones adicionales en la implementación. Esto sucede porque, como cualquier API pública, la forma serializada de un objeto se convierte en parte de la API pública y cuando cambia la estructura de su clase implementando una interfaz de adición, agregar o eliminar cualquier campo puede potencialmente romper la serialización predeterminada. Sin embargo, esto se puede minimizar utilizando un formato binario personalizado, pero aún requiere mucho esfuerzo para garantizar la compatibilidad con versiones anteriores. Un ejemplo de cómo la serialización puede limitar su capacidad para modificar una clase es el campo SerialVersionUID. Si no declara explícitamente el SerialVersionUID, entonces la máquina virtual lo genera en función de la estructura de la clase, que depende de las interfaces implementadas por la clase y de varios otros factores que se pueden cambiar. Digamos que implementas una interfaz diferente a la JVM, lo que generará un SerialVersionUID diferente para la nueva versión de los archivos de clase, y cuando intentas cargar un objeto antiguo serializado por la versión anterior de tu programa, obtendrás un Excepción de clase no válida. Pregunta 1) ¿Cuál es la diferencia entre una interfaz serializable y externalizable en Java? Esta es la pregunta más frecuente en las entrevistas sobre serialización de Java. La interfaz externalizable nos proporciona los métodos writeExternal() y readExternal(), que nos brindan la flexibilidad de controlar la serialización en lugar de depender del mecanismo predeterminado. La implementación adecuada de la interfaz externalizable puede mejorar significativamente el rendimiento de la aplicación. Pregunta 2) ¿Cuántos métodos tiene Serializable? Si no existe un método, ¿cuál es el propósito de la interfaz serializable? La interfaz serializable existe en el paquete java.io y forma el núcleo del motor de serialización de Java. No tiene ningún método y también se llama interfaz de marcador en Java. Cuando su clase implementa la interfaz java.io.Serializable, se vuelve serializable. Es sencillo. Pregunta 3) ¿Qué es serialVersionUID? ¿Qué pasa si no lo defines? Una de mis preguntas favoritas de la entrevista sobre serialización de Java. SerialVersionUID es un identificador que se coloca en un objeto cuando se serializa, generalmente un código hash del objeto. Puede utilizar la herramienta serialver para obtener el serialVersionUID del objeto serializado. SerialVersionUID se utiliza para el control de versiones de objetos. También puede especificar serialVersionUID en su archivo de clase manualmente. La consecuencia de no especificar serialVersionUID es que si agrega o cambia cualquier campo en una clase, la clase ya serializada no podrá recuperarse porque el serialVersionUID generado para la nueva clase será diferente del mismo campo del antiguo objeto serializado. El proceso de serialización de Java se basa en el serialVersionUID correcto para restaurar el estado del objeto serializado y genera una java.io.InvalidClassException si hay una discrepancia. Para obtener más información sobre serialversionuid, consulte aquí . Pregunta 4) Al realizar la serialización, ¿desea que algunos miembros no se serialicen? ¿Cómo lograr esto? Otra pregunta frecuente en las entrevistas sobre serialización. A veces la gente también pregunta cómo se usa una variable transitoria, si una variable transitoria y una estática están serializadas o no, etc., por lo que si no desea que ningún campo forme parte del estado del objeto, declarelo como estático o transitorio dependiendo según sus necesidades y no se incluirá en el proceso de serialización de Java. Pregunta 5) ¿Qué sucede si uno de los miembros de la clase no implementa la interfaz Serializable? Una de las preguntas sencillas sobre el proceso de serialización en Java. Si intenta serializar un objeto de una clase que implementa Serializable, pero el objeto incluye una referencia a una clase que no es Serializable, entonces se generará una NotSerializableException en tiempo de ejecución, y es por eso que siempre pongo una SerializableAlert (sección de comentarios en mi código), una de las mejores técnicas para comentar código es indicarle al desarrollador que recuerde este hecho al agregar un nuevo campo a la clase Serializable. Pregunta 6) Si una clase es serializable pero su superclase no, ¿cuál será el estado de las variables de instancia heredadas de la superclase después de la deserialización? El proceso de serialización de Java continúa solo en la jerarquía de objetos siempre que la clase implemente la interfaz Serializable y los valores de las variables heredadas de la superclase se inicializarán llamando al constructor de la superclase no serializable durante el proceso de deserialización. Una vez que la cadena de constructores ha comenzado, no hay forma de detenerla, por lo que incluso si las clases superiores en la jerarquía (no) implementan la interfaz Serializable , el constructor se ejecutará. Esta pregunta de la entrevista de serialización puede parecer muy difícil, pero si está familiarizado con los conceptos clave, no lo será. Pregunta 7) ¿Se puede personalizar el proceso de serialización o anular el proceso de serialización predeterminado en Java? La respuesta es sí, puedes. Todos sabemos que para serializar un objeto, se llama a ObjectOutputStream.writeObject(saveThisObject) y para leer un objeto, se llama a ObjectInputStream.readObject(), pero hay una cosa más que la máquina virtual Java le proporciona: definir estos dos métodos. en tu clase. Si los define en su clase, la JVM llamará a estos dos métodos en lugar de utilizar el mecanismo de serialización predeterminado. Aquí puede configurar el comportamiento de serialización y deserialización del objeto realizando cualquier tarea de preprocesamiento o posprocesamiento. Es importante tener en cuenta que estos métodos deben ser privados para evitar herencia, anulación o sobrecarga. Dado que solo la máquina virtual Java puede llamar a un método privado, se preservará la integridad de su clase y la serialización funcionará como de costumbre. En mi opinión, esta es una de las mejores preguntas que se pueden hacer en cualquier entrevista sobre serialización de Java. Una buena pregunta de seguimiento es: ¿por qué necesitaría proporcionar un formulario serializado personalizado para su objeto? Pregunta 8) Supongamos que la superclase de una nueva clase implementa la interfaz Serializable, ¿cómo podemos evitar serializar la nueva clase? Una de las preguntas difíciles de la entrevista sobre serialización en Java. Si la superclase de una clase ya implementa la interfaz Serializable en Java, entonces la clase descendiente también es Serializable, ya que no se puede no implementar la interfaz principal y realmente no es posible convertirla en una clase No Serializable. Sin embargo, existe una manera de evitar la serialización de esta nueva clase. Para hacer esto, necesita implementar los métodos writeObject() y readObject() y lanzar NotSerializableException desde estos métodos. Esta pregunta generalmente se hace como una pregunta adicional a medida que avanza la entrevista. Pregunta 9) ¿Cuáles son los métodos utilizados en el proceso de serialización y deserialización en Java? Esta es una pregunta muy común en la serialización. ¿Qué intenta averiguar el entrevistador en este caso? Si está familiarizado con el uso de readObject(), writeObject(), readExternal() y writeExternal() o no. La serialización de Java la realiza la clase java.io.ObjectOutputStream. Esta clase es una secuencia filtrada que se envuelve alrededor de una secuencia de bytes de nivel inferior para manejar el motor de serialización. Para guardar cualquier objeto usando el mecanismo de serialización, llamamos a ObjectOutputStream.writeObject(saveThisObject) y para deserializar ese objeto, llamamos al método ObjectInputStream.readObject(). Llamar al método writeObject() inicia el proceso de serialización. Una cosa importante a tener en cuenta sobre el método readObject() es que se utiliza para leer bytes y para crear y devolver un objeto a partir de esos bytes, que a su vez debe convertirse al tipo correcto. Pregunta 10) Supongamos que tiene una clase que ha serializado y guardado, y luego modifica esa clase para agregar un nuevo campo. ¿Qué sucede si deserializas un objeto ya serializado? Depende de si la clase tiene su propio serialVersionUID o no. Como sabemos por las preguntas anteriores, si no proporcionamos serialVersionUID en nuestro código, el compilador de Java lo generará él mismo y, por lo general, será igual al código hash de ese objeto. Después de agregar cualquier campo nuevo, existe la posibilidad de que el nuevo serialVersionUID generado para esa versión de la clase no coincida con el objeto ya serializado, en cuyo caso la API generará una java.io.InvalidClassException. Por este motivo, se recomienda tener su propio serialVersionUID en su código, que siempre es el mismo para la misma clase. Pregunta 11) ¿Cuáles son los cambios compatibles e incompatibles en el mecanismo de serialización de Java? El verdadero problema es cambiar la estructura de las clases agregando cualquier campo, método o eliminando cualquier campo o método con un objeto ya serializado. De acuerdo con la especificación de serialización de Java, agregar cualquier campo o método se incluye en cambios compatibles y cambiar la jerarquía de clases o las interfaces serializables que implementan la ONU (algunas en cambios no compatibles). Para obtener una lista completa de cambios compatibles e incompatibles, sugeriría leer la Especificación de serialización de Java. Pregunta 12) ¿Podemos transferir un objeto serializado a través de la red? Sí, puede pasar un objeto serializado a través de la red porque un objeto serializado Java es una colección de bytes que se puede pasar de cualquier forma. También puede almacenar el objeto serializado en el disco o en una base de datos como un Blob. Pregunta 13) ¿Qué tipos de variables no se serializan durante la serialización de Java? Esta pregunta a veces se ha formulado de manera diferente, pero el objetivo es el mismo: descubrir si un desarrollador de Java conoce los detalles de la serialización de variables estáticas y transitorias. Dado que las variables estáticas pertenecen a una clase y no a un objeto, no forman parte del estado del objeto, por lo que no persisten durante el proceso de serialización de Java. Debido a que la serialización de Java solo almacena el estado de un objeto y no el objeto en sí, las variables transitorias tampoco se incluyen en el proceso de serialización y no forman parte del estado serializado del objeto. Después de esta pregunta, tal vez el entrevistador pregunte: Si no almacena los valores de estas variables, ¿cuál será el valor de estas variables después de deserializar y recrear este objeto? Y esto, compañeros, pensad por vosotros mismos :) El artículo original está aquí .
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION