JavaRush /Blogue Java /Random-PT /As 13 principais perguntas sobre serialização em entrevis...
Dmitry Vasilyev
Nível 26
Саратов

As 13 principais perguntas sobre serialização em entrevistas

Publicado no grupo Random-PT
Tradução do artigo https://javarevisited.blogspot.com/2011/04/top-10-java-serialization-interview.html O que é serialização em Java? A serialização é um dos conceitos importantes que raramente é usado como solução para salvar o estado dos programas e, portanto, esta API é frequentemente ignorada pelos desenvolvedores. No entanto, na minha experiência, a serialização é um tópico muito importante em qualquer entrevista básica sobre Java. Quase todas as entrevistas que encontrei tinham uma ou duas perguntas sobre serialização, e vi candidatos se sentirem desconfortáveis ​​com sua falta de experiência nessa área depois de algumas perguntas sobre esse assunto. Eles não sabem serializar um objeto em Java, não estão familiarizados com nenhum exemplo de serialização e não conseguem explicar a mecânica de seu trabalho, a diferença entre uma variável transitória e uma variável volátil, não sabem quantos métodos a interface serializável tem. O que é uma interface de marcador? Qual é seu propósito? Qual é a diferença entre implementação externalizável e serializável em Java? Por que java não substituiu Serializable por @Serializable após introduzir a anotação? Neste artigo, abordaremos questões tanto para desenvolvedores iniciantes quanto avançados, que podem ser igualmente úteis para todos: de desenvolvedores juniores a desenvolvedores seniores. A maioria dos projetos comerciais usa bancos de dados, arquivos mapeados em memória ou simplesmente arquivos simples para fornecer maior robustez, mas poucos dependem do processo de serialização do Java. De qualquer forma, este post não é um tutorial - trata-se antes de questões que vale a pena esclarecer antes de ir para qualquer entrevista sobre Java e ser surpreendido por termos desconhecidos para você. Para aqueles que não estão familiarizados com a serialização Java: “Serialização em Java é um processo usado para serializar um objeto em Java, armazenando o estado do objeto em um arquivo com extensão .ser e recriando o estado do objeto deste arquivo. Esse processo reverso é chamado de desserialização. sepulca A API Java Serialization fornece aos desenvolvedores um mecanismo padrão para serializar objetos usando as interfaces Serializable e Externalizable. A propósito, este artigo é uma continuação dos meus artigos anteriores ( não meus, o tradutor, mas o autor do original em inglês) : 20 perguntas de entrevista sobre padrões de design e 10 perguntas de entrevista sobre o padrão Singleton em Java . Então vamos! O que é serialização em Java? A serialização de objetos em Java é um processo usado para converter um objeto em um formato binário que pode ser salvo em disco ou enviado pela rede para qualquer outra máquina virtual Java em execução; o processo inverso de criação de um objeto a partir de um fluxo binário é chamado de desserialização. Java fornece uma API que inclui java.io.Serializable, java.io.Externalizable, ObjectInputStream e ObjectOutputStream etc. Os programadores são livres para usar o mecanismo de serialização padrão que Java usa com base na estrutura da classe, mas também podem usar seu próprio formato binário personalizado, que geralmente é recomendado como uma prática recomendada de serialização porque o formato binário serializado se torna parte da API exportada da classe e pode potencialmente quebrar o encapsulamento em Java fornecido por campos privados e privados de pacote . Em geral, essas informações serão suficientes para começar. Como tornar uma classe Java serializável? Isso é muito fácil. Sua classe simplesmente precisa implementar a interface java.io.Serializable e a JVM se encarregará de serializar o objeto em um formato padrão. A decisão de criar uma classe serializável deve ser tomada brevemente porque, embora os custos de curto prazo da criação de uma classe serializável sejam baixos, os custos de longo prazo são significativos e podem potencialmente limitar a sua capacidade de fazer modificações adicionais na implementação. Isso acontece porque, como qualquer API pública, a forma serializada de um objeto torna-se parte da API pública, e quando você altera a estrutura da sua classe implementando uma interface add, adicionar ou remover qualquer campo pode potencialmente quebrar a serialização padrão. No entanto, isso pode ser minimizado usando um formato binário personalizado, mas ainda requer muito esforço para garantir a compatibilidade com versões anteriores. Um exemplo de como a serialização pode limitar sua capacidade de modificar uma classe é o campo SerialVersionUID. Se você não declarar explicitamente o SerialVersionUID, a máquina virtual o gerará com base na estrutura da classe, que depende das interfaces implementadas pela classe e de vários outros fatores que podem ser alterados. Digamos que você implemente uma interface diferente em oposição à JVM, que irá gerar um SerialVersionUID diferente para a nova versão dos arquivos de classe, e quando você tentar carregar um objeto antigo serializado pela versão antiga do seu programa, você obterá um InvalidClassException. Questão 1) Qual é a diferença entre interface serializável e externalizável em Java? Esta é a pergunta mais frequente da entrevista sobre serialização Java. A interface Externalizable nos fornece os métodos writeExternal() e readExternal(), que nos dão flexibilidade para controlar a serialização em vez de depender do mecanismo padrão. A implementação adequada da interface externalizável pode melhorar significativamente o desempenho do aplicativo. Questão 2) Quantos métodos o Serializable possui? Se não houver método, qual é o propósito da interface Serializable? A interface serializável existe no pacote java.io e forma o núcleo do mecanismo de serialização Java. Ele não possui nenhum método e também é chamado de interface de marcador em Java. Quando sua classe implementa a interface java.io.Serializable, ela se torna serializável. É simples. Pergunta 3) O que é serialVersionUID? O que acontece se você não definir isso? Uma das minhas perguntas favoritas da entrevista sobre serialização Java. SerialVersionUID é um identificador colocado em um objeto quando ele é serializado, geralmente um código hash do objeto. Você pode usar a ferramenta serialver para obter o serialVersionUID do objeto serializado. SerialVersionUID é usado para controle de versão do objeto. Você também pode especificar serialVersionUID em seu arquivo de classe manualmente. A consequência de não especificar serialVersionUID é que se você adicionar ou alterar qualquer campo em uma classe, a classe já serializada não poderá se recuperar porque o serialVersionUID gerado para a nova classe será diferente do mesmo campo do antigo objeto serializado. O processo de serialização Java depende do serialVersionUID correto para restaurar o estado do objeto serializado e gera uma java.io.InvalidClassException se houver uma incompatibilidade. Para saber mais sobre serialversionuid, veja aqui . Questão 4) Ao serializar, você deseja que alguns membros não sejam serializados? Como conseguir isso? Outra pergunta frequente da entrevista de serialização. Às vezes as pessoas também perguntam como uma variável transitória é usada, se uma variável transitória e uma variável estática são serializadas ou não, etc., então se você não quiser que nenhum campo faça parte do estado do objeto, declare-o como estático ou transitório dependendo de acordo com suas necessidades e não será incluído no processo de serialização Java. Questão 5) O que acontece se um dos membros da classe não implementar a interface Serializable? Uma das questões simples sobre o processo de serialização em Java. Se você tentar serializar um objeto de uma classe que implementa Serializable, mas o objeto inclui uma referência a uma classe que não é Serializable, então uma NotSerializableException será lançada em tempo de execução, e é por isso que eu sempre coloco um SerializableAlert (seção de comentários no meu código), uma das melhores técnicas de comentários de código é instruir o desenvolvedor a lembrar desse fato ao adicionar um novo campo à classe Serializable. Questão 6) Se uma classe é serializável, mas sua superclasse não, qual será o estado das variáveis ​​de instância herdadas da superclasse após a desserialização? O processo de serialização Java continua apenas na hierarquia de objetos enquanto a classe implementa a interface Serializable e os valores das variáveis ​​​​herdadas da superclasse serão inicializados chamando o construtor da superclasse não serializável durante o processo de desserialização. Uma vez iniciada a cadeia de construtores, não há como interrompê-la, portanto, mesmo que as classes superiores na hierarquia (não) implementem a interface Serializable , o construtor será executado. Esta pergunta da entrevista de serialização pode parecer muito difícil, mas se você estiver familiarizado com os conceitos-chave, não será difícil. Pergunta 7) Você pode personalizar o processo de serialização ou substituir o processo de serialização padrão em Java? A resposta é sim você pode. Todos nós sabemos que para serializar um objeto, ObjectOutputStream.writeObject(saveThisObject) é chamado e para ler um objeto, ObjectInputStream.readObject() é chamado, mas há mais uma coisa que a Java Virtual Machine fornece - definir esses dois métodos em sua classe. Se você defini-los em sua classe, a JVM chamará esses dois métodos em vez de usar o mecanismo de serialização padrão. Aqui você pode configurar o comportamento de serialização e desserialização do objeto executando qualquer tarefa de pré-processamento ou pós-processamento. É importante observar que esses métodos devem ser privados para evitar herança, substituição ou sobrecarga. Como apenas a Java Virtual Machine pode chamar um método privado, a integridade da sua classe será preservada e a serialização funcionará normalmente. Na minha opinião, esta é uma das melhores perguntas que podem ser feitas em qualquer entrevista sobre serialização Java. Uma boa pergunta complementar é: por que você precisaria fornecer um formulário serializado personalizado para seu objeto? Questão 8) Suponha que a superclasse de uma nova classe implemente a interface Serializable, como podemos evitar a serialização da nova classe? Uma das perguntas difíceis da entrevista sobre serialização em Java. Se a superclasse de uma classe já implementa a interface Serializable em Java, então a classe descendente também é Serializable, já que você não pode deixar de implementar a interface pai, e não é realmente possível torná-la uma classe Non Serializable. No entanto, existe uma maneira de evitar a serialização para esta nova classe. Para fazer isso, você precisa implementar os métodos writeObject() e readObject() e lançar NotSerializableException desses métodos. Esta pergunta geralmente é feita como uma pergunta adicional à medida que a entrevista avança. Questão 9) Quais são os métodos utilizados no processo de serialização e desserialização em Java? Esta é uma pergunta muito comum na serialização. O que o entrevistador está tentando descobrir neste caso? Quer você esteja familiarizado com o uso de readObject(), writeObject(), readExternal() e writeExternal() ou não. A serialização Java é feita pela classe java.io.ObjectOutputStream. Esta classe é um fluxo filtrado que envolve um fluxo de bytes de nível inferior para manipular o mecanismo de serialização. Para salvar qualquer objeto usando o mecanismo de serialização, chamamos ObjectOutputStream.writeObject(saveThisObject) e para desserializar esse objeto, chamamos o método ObjectInputStream.readObject(). Chamar o método writeObject() inicia o processo de serialização. Uma coisa importante a ser observada sobre o método readObject() é que ele é usado para ler bytes e para criar e retornar um objeto desses bytes, que por sua vez deve ser convertido para o tipo correto. Pergunta 10) Suponha que você tenha uma classe que serializou e salvou e, em seguida, modificou essa classe para adicionar um novo campo. O que acontece se você desserializar um objeto já serializado? Depende se a classe possui seu próprio serialVersionUID ou não. Como sabemos pelas perguntas acima, se não fornecermos serialVersionUID em nosso código, o compilador java irá gerá-lo sozinho e geralmente será igual ao código hash desse objeto. Após adicionar qualquer novo campo, há uma chance de que o novo serialVersionUID gerado para aquela versão da classe não corresponda ao objeto já serializado, caso em que a API lançará uma java.io.InvalidClassException. Por esse motivo, é recomendável ter seu próprio serialVersionUID em seu código, que é sempre o mesmo para a mesma classe. Questão 11) Quais são as alterações compatíveis e incompatíveis no mecanismo de serialização Java? O verdadeiro problema é mudar a estrutura das classes adicionando qualquer campo, método ou removendo qualquer campo ou método com um objeto já serializado. De acordo com a especificação de serialização Java, a adição de qualquer campo ou método está sujeita a alterações e alterações compatíveis, hierarquia de classes ou interfaces serializáveis ​​​​implementadas pela ONU (algumas sob alterações não compatíveis). Para obter uma lista completa de alterações compatíveis e incompatíveis, sugiro a leitura da Especificação de serialização Java. Questão 12) Podemos transferir um objeto serializado pela rede? Sim, você pode passar um objeto serializado pela rede porque um objeto serializado Java é uma coleção de bytes que pode ser passado de qualquer maneira. Você também pode armazenar o objeto serializado em disco ou em um banco de dados como um Blob. Questão 13) Que tipos de variáveis ​​não são serializadas durante a serialização Java? Esta pergunta às vezes foi feita de forma diferente, mas o objetivo é o mesmo: descobrir se um desenvolvedor Java conhece os detalhes da serialização de variáveis ​​estáticas e transitórias. Como as variáveis ​​estáticas pertencem a uma classe e não a um objeto, elas não fazem parte do estado do objeto e, portanto, não persistem durante o processo de serialização Java. Como a serialização Java armazena apenas o estado de um objeto e não o próprio objeto, as variáveis ​​transitórias também não são incluídas no processo de serialização e não fazem parte do estado serializado do objeto. Após essa pergunta, talvez o entrevistador pergunte: Se você não armazena os valores dessas variáveis, então qual será o valor dessas variáveis ​​após desserializar e recriar esse objeto? E isso, colegas, pensem por si mesmos :) O artigo original está aqui .
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION