JavaRush /Java Blog /Random-IT /Le 13 domande principali sulla serializzazione nelle inte...
Dmitry Vasilyev
Livello 26
Саратов

Le 13 domande principali sulla serializzazione nelle interviste

Pubblicato nel gruppo Random-IT
Traduzione dell'articolo https://javarevisited.blogspot.com/2011/04/top-10-java-serialization-interview.html Cos'è la serializzazione in Java? La serializzazione è uno dei concetti importanti che viene utilizzato abbastanza raramente come soluzione per salvare lo stato dei programmi e pertanto questa API viene spesso trascurata dagli sviluppatori. Tuttavia, secondo la mia esperienza, la serializzazione è un argomento piuttosto importante in qualsiasi intervista di base su Java. Quasi ogni colloquio che ho incontrato prevedeva una o due domande sulla serializzazione e ho visto i candidati sentirsi a disagio per la loro mancanza di esperienza in questo settore dopo alcune domande su questo argomento. Non sanno come serializzare un oggetto in Java, non hanno familiarità con alcun esempio di serializzazione e non sanno spiegare i meccanismi del suo lavoro, la differenza tra una variabile transitoria e una variabile volatile, non sanno quanti metodi l'interfaccia Serializable ha. Cos'è un'interfaccia marcatore? Qual è il suo scopo? Qual è la differenza tra l'implementazione externalizable e serializable in Java? Perché Java non ha sostituito Serializable con @Serializable dopo aver introdotto l'annotazione? In questo articolo tratteremo le domande sia per principianti che per sviluppatori avanzati, che possono essere ugualmente utili per tutti: dagli sviluppatori junior agli sviluppatori senior. La maggior parte dei progetti commerciali utilizza database, file mappati in memoria o semplici file flat per fornire maggiore robustezza, ma pochi si affidano al processo di serializzazione di Java. In ogni caso, questo post non è un tutorial, ma riguarda piuttosto domande che vale la pena chiarire da soli prima di andare a qualsiasi colloquio su Java e lasciarsi sorprendere da termini a te sconosciuti. Per coloro che non hanno affatto familiarità con la serializzazione Java: “La serializzazione in Java è un processo utilizzato per serializzare un oggetto in Java memorizzando lo stato dell'oggetto in un file con estensione .ser e ricreando lo stato dell'oggetto da questo file. Questo processo inverso è chiamato deserializzazione. sepolka L'API Java Serialization fornisce agli sviluppatori un meccanismo standard per la serializzazione di oggetti utilizzando le interfacce Serializable ed Externalizable. A proposito, questo articolo è una continuazione dei miei articoli precedenti ( non miei, del traduttore, ma dell'autore dell'originale inglese) : 20 domande di intervista sui design pattern e 10 domande di intervista sul pattern Singleton in Java . Quindi andiamo! Cos'è la serializzazione in Java? La serializzazione degli oggetti in Java è un processo utilizzato per convertire un oggetto in un formato binario che può essere salvato su disco o inviato in rete a qualsiasi altra macchina virtuale Java in esecuzione; il processo inverso di creazione di un oggetto da un flusso binario è chiamato deserializzazione. Java fornisce un'API che include java.io.Serializable, java.io.Externalizable, ObjectInputStream e ObjectOutputStream ecc. I programmatori sono liberi di utilizzare il meccanismo di serializzazione predefinito utilizzato da Java in base alla struttura della classe, ma possono anche utilizzare il proprio formato binario personalizzato, che è spesso consigliato come best practice di serializzazione perché il formato binario serializzato diventa parte dell'API esportata della classe e può potenzialmente interrompere l'incapsulamento in Java fornito dai campi privati ​​e privati ​​del pacchetto . In generale, queste informazioni saranno sufficienti per iniziare. Come rendere serializzabile una classe Java? È molto facile. La tua classe deve semplicemente implementare l'interfaccia java.io.Serializable e la JVM si occuperà di serializzare l'oggetto in un formato predefinito. La decisione di creare una classe serializzabile dovrebbe essere presa brevemente perché, sebbene i costi a breve termine per la creazione di una classe serializzabile siano bassi, i costi a lungo termine sono significativi e possono potenzialmente limitare la capacità di apportare ulteriori modifiche all'implementazione. Ciò accade perché, come qualsiasi API pubblica, la forma serializzata di un oggetto diventa parte dell'API pubblica e quando modifichi la struttura della tua classe implementando un'interfaccia di aggiunta, l'aggiunta o la rimozione di qualsiasi campo può potenzialmente interrompere la serializzazione predefinita. Tuttavia, questo problema può essere ridotto al minimo utilizzando un formato binario personalizzato, ma richiede comunque molto impegno per garantire la compatibilità con le versioni precedenti. Un esempio di come la serializzazione può limitare la capacità di modificare una classe è il campo SerialVersionUID. Se non dichiari esplicitamente SerialVersionUID, la macchina virtuale lo genera in base alla struttura della classe, che dipende dalle interfacce implementate dalla classe e da molti altri fattori che possono essere modificati. Supponiamo che tu implementi un'interfaccia diversa rispetto alla JVM, che genererà un SerialVersionUID diverso per la nuova versione dei file di classe e quando provi a caricare un vecchio oggetto serializzato dalla vecchia versione del tuo programma, otterrai un InvalidClassException. Domanda 1) Qual è la differenza tra l'interfaccia Serializable e externalizable in Java? Questa è la domanda più frequente nell'intervista sulla serializzazione Java. L'interfaccia Externalizable ci fornisce i metodi writeExternal() e readExternal(), che ci danno la flessibilità di controllare la serializzazione invece di fare affidamento sul meccanismo predefinito. La corretta implementazione dell'interfaccia Externalizable può migliorare significativamente le prestazioni dell'applicazione. Domanda 2) Quanti metodi ha Serializable? Se non esiste un metodo, qual è lo scopo dell'interfaccia Serializable? L'interfaccia serializzabile esiste nel pacchetto java.io e costituisce il nucleo del motore di serializzazione di Java. Non ha metodi ed è anche chiamata interfaccia marker in Java. Quando la tua classe implementa l'interfaccia java.io.Serializable, diventa serializzabile. È semplice. Domanda 3) Cos'è serialVersionUID? Cosa succede se non lo definisci? Una delle mie domande preferite per l'intervista sulla serializzazione Java. SerialVersionUID è un identificatore che viene inserito su un oggetto quando viene serializzato, solitamente un codice hash dell'oggetto. È possibile utilizzare lo strumento serialver per ottenere il serialVersionUID dell'oggetto serializzato. SerialVersionUID viene utilizzato per il controllo della versione dell'oggetto. Puoi anche specificare serialVersionUID nel file di classe manualmente. La conseguenza di non specificare serialVersionUID è che se aggiungi o modifichi qualsiasi campo in una classe, la classe già serializzata non potrà essere ripristinata perché il serialVersionUID generato per la nuova classe sarà diverso dallo stesso campo del vecchio oggetto serializzato. Il processo di serializzazione Java si basa sul serialVersionUID corretto per ripristinare lo stato dell'oggetto serializzato e genera un'eccezione java.io.InvalidClassException in caso di mancata corrispondenza. Per ulteriori informazioni su serialversionuid, vedere qui . Domanda 4) Durante la serializzazione, vuoi che alcuni membri non vengano serializzati? Come raggiungere questo obiettivo? Un'altra domanda frequente nell'intervista sulla serializzazione. A volte le persone chiedono anche come viene utilizzata una variabile transitoria, se una variabile transitoria e una statica sono serializzate o meno, ecc., Quindi se non vuoi che alcun campo faccia parte dello stato dell'oggetto, dichiaralo come statico o transitorio dipendente in base alle tue esigenze e non sarà incluso nel processo di serializzazione Java. Domanda 5) Cosa succede se uno dei membri della classe non implementa l'interfaccia Serializable? Una delle semplici domande sul processo di serializzazione in Java. Se provi a serializzare un oggetto di una classe che implementa Serializable, ma l'oggetto include un riferimento a una classe che non è Serializable, verrà lanciata un'eccezione NotSerializableException in fase di runtime, ed è per questo che inserisco sempre un SerializableAlert (sezione commenti nel mio codice), una delle migliori tecniche di commento del codice consiste nel chiedere allo sviluppatore di ricordare questo fatto quando aggiunge un nuovo campo alla classe Serializable. Domanda 6) Se una classe è serializzabile ma la sua superclasse no, quale sarà lo stato delle variabili di istanza ereditate dalla superclasse dopo la deserializzazione? Il processo di serializzazione Java continua solo nella gerarchia degli oggetti fintanto che la classe implementa l'interfaccia Serializable e i valori delle variabili ereditate dalla superclasse verranno inizializzati chiamando il costruttore della superclasse non serializzabile durante il processo di deserializzazione. Una volta avviata la catena del costruttore, non c'è modo di fermarla, quindi anche se le classi più alte nella gerarchia (non) implementano l'interfaccia Serializable , il costruttore verrà eseguito. Questa domanda per l'intervista sulla serializzazione può sembrare molto difficile, ma se hai familiarità con i concetti chiave, non sarà difficile. Domanda 7) È possibile personalizzare il processo di serializzazione o sovrascrivere il processo di serializzazione predefinito in Java? La risposta è sì, puoi. Sappiamo tutti che per serializzare un oggetto viene chiamato ObjectOutputStream.writeObject(saveThisObject) e per leggere un oggetto viene chiamato ObjectInputStream.readObject(), ma c'è un'altra cosa che Java Virtual Machine ti fornisce: definire questi due metodi nella tua classe. Se li definisci nella tua classe, la JVM chiamerà questi due metodi invece di utilizzare il meccanismo di serializzazione predefinito. Qui puoi configurare il comportamento di serializzazione e deserializzazione dell'oggetto eseguendo qualsiasi attività di pre-elaborazione o post-elaborazione. È importante notare che questi metodi devono essere privati ​​per evitare ereditarietà, sovrascrittura o sovraccarico. Poiché solo la Java Virtual Machine può chiamare un metodo privato, l'integrità della classe verrà preservata e la serializzazione funzionerà normalmente. Secondo me, questa è una delle migliori domande che possono essere poste in qualsiasi intervista sulla serializzazione Java. Una buona domanda successiva è: perché dovresti fornire un modulo serializzato personalizzato per il tuo oggetto? Domanda 8) Supponiamo che la superclasse di una nuova classe implementi l'interfaccia Serializable, come possiamo evitare di serializzare la nuova classe? Una delle domande difficili dell'intervista sulla serializzazione in Java. Se la superclasse di una classe implementa già l'interfaccia Serializable in Java, anche la classe discendente è Serializable, poiché non è possibile non implementare l'interfaccia genitore e non è realmente possibile renderla una classe Non Serializable. Tuttavia, esiste un modo per evitare la serializzazione per questa nuova classe. Per fare ciò, è necessario implementare i metodi writeObject() e readObject() e lanciare NotSerializableException da questi metodi. Questa domanda viene solitamente posta come domanda aggiuntiva man mano che l'intervista procede. Domanda 9) Quali sono i metodi utilizzati nel processo di serializzazione e deserializzazione in Java? Questa è una domanda molto comune nella serializzazione. Cosa sta cercando di scoprire l’intervistatore in questo caso? Che tu abbia familiarità con l'uso di readObject(), writeObject(), readExternal() e writeExternal() o meno. La serializzazione Java viene eseguita dalla classe java.io.ObjectOutputStream. Questa classe è un flusso filtrato racchiuso attorno a un flusso di byte di livello inferiore per gestire il motore di serializzazione. Per salvare qualsiasi oggetto utilizzando il meccanismo di serializzazione, chiamiamo ObjectOutputStream.writeObject(saveThisObject) e per deserializzare quell'oggetto, chiamiamo il metodo ObjectInputStream.readObject(). La chiamata al metodo writeObject() avvia il processo di serializzazione. Una cosa importante da notare sul metodo readObject() è che viene utilizzato per leggere byte e per creare e restituire un oggetto da quei byte, che a sua volta deve essere convertito nel tipo corretto. Domanda 10) Supponiamo di avere una classe che è stata serializzata e salvata e quindi di modificare quella classe per aggiungere un nuovo campo. Cosa succede se deserializzi un oggetto già serializzato? Dipende dal fatto che la classe abbia o meno il proprio serialVersionUID. Come sappiamo dalle domande precedenti, se non forniamo serialVersionUID nel nostro codice, il compilatore Java lo genererà da solo e solitamente sarà uguale al codice hash di quell'oggetto. Dopo aver aggiunto qualsiasi nuovo campo, è possibile che il nuovo serialVersionUID generato per quella versione della classe non corrisponda all'oggetto già serializzato, nel qual caso l'API lancerà una java.io.InvalidClassException. Per questo motivo è consigliabile avere nel codice un proprio serialVersionUID, che è sempre lo stesso per la stessa classe. Domanda 11) Quali sono le modifiche compatibili e incompatibili nel meccanismo di serializzazione Java? Il vero problema è cambiare la struttura delle classi aggiungendo qualsiasi campo, metodo o rimuovendo qualsiasi campo o metodo con un oggetto già serializzato. Secondo la specifica Java Serialization, l'aggiunta di qualsiasi campo o metodo rientra in modifiche compatibili e la modifica (gerarchia di classi o interfacce serializzabili di implementazione delle Nazioni Unite) (alcune in modifiche non compatibili). Per un elenco completo delle modifiche compatibili e incompatibili, suggerirei di leggere la specifica di serializzazione Java. Domanda 12) Possiamo trasferire un oggetto serializzato sulla rete? Sì, puoi passare un oggetto serializzato sulla rete perché un oggetto serializzato Java è una raccolta di byte che può essere passato in qualsiasi modo. È inoltre possibile archiviare l'oggetto serializzato su disco o in un database come BLOB. Domanda 13) Quali tipi di variabili non vengono serializzate durante la serializzazione Java? Questa domanda a volte è stata posta in modo diverso, ma l'obiettivo è lo stesso: scoprire se uno sviluppatore Java conosce le specifiche della serializzazione di variabili statiche e transitorie. Poiché le variabili statiche appartengono a una classe e non a un oggetto, non fanno parte dello stato dell'oggetto, quindi non vengono mantenute durante il processo di serializzazione Java. Poiché la serializzazione Java memorizza solo lo stato di un oggetto e non l'oggetto stesso, anche le variabili temporanee non sono incluse nel processo di serializzazione e non fanno parte dello stato serializzato dell'oggetto. Dopo questa domanda, forse l'intervistatore chiederà: se non memorizzi i valori di queste variabili, quale sarà il valore di queste variabili dopo aver deserializzato e ricreato questo oggetto? E questo, colleghi, pensate voi stessi :) L'articolo originale è qui .
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION