JavaRush /Blog Java /Random-PL /13 najważniejszych pytań na temat serializacji w wywiadac...
Dmitry Vasilyev
Poziom 26
Саратов

13 najważniejszych pytań na temat serializacji w wywiadach

Opublikowano w grupie Random-PL
Tłumaczenie artykułu https://javarevisited.blogspot.com/2011/04/top-10-java-serialization-interview.html Co to jest serializacja w Javie? Serializacja to jedna z ważnych koncepcji, która jest dość rzadko stosowana jako rozwiązanie umożliwiające zapisanie stanu programów i dlatego to API jest często pomijane przez programistów. Jednak z mojego doświadczenia wynika, że ​​serializacja jest dość ważnym tematem w każdej podstawowej rozmowie kwalifikacyjnej w języku Java. Prawie w każdej rozmowie kwalifikacyjnej, z którą się spotkałem, pojawiało się jedno lub dwa pytania dotyczące serializacji i widziałem, jak kandydaci czuli się nieswojo z powodu braku doświadczenia w tej dziedzinie po kilku pytaniach na ten temat. Nie wiedzą, jak serializować obiekt w Javie, nie znają żadnych przykładów serializacji i nie potrafią wyjaśnić mechaniki jej działania, różnicy między zmienną przejściową a zmienną, nie wiedzą, ile metod ma interfejs Serializable ma. Co to jest interfejs znacznika? Jaki jest jego cel? Jaka jest różnica między implementacją zewnętrzną i serializowalną w Javie? Dlaczego Java nie zastąpiła Serializable przez @Serializable po wprowadzeniu adnotacji? W tym artykule omówimy pytania zarówno dla początkujących, jak i zaawansowanych programistów, które mogą być równie przydatne dla każdego: od juniorów po starszych programistów. Większość projektów komercyjnych wykorzystuje bazy danych, pliki mapowane w pamięci lub po prostu zwykłe pliki płaskie, aby zapewnić większą niezawodność, ale niewiele opiera się na procesie serializacji Java. W każdym razie ten post nie jest tutorialem - raczej porusza pytania, które warto sobie wyjaśnić przed pójściem na jakąkolwiek rozmowę w języku Java i dać się zaskoczyć nieznanym sobie terminom. Dla tych, którzy w ogóle nie są zaznajomieni z serializacją w Javie: „Serializacja w Javie to proces, który służy do serializacji obiektu w Javie poprzez zapisanie stanu obiektu w pliku z rozszerzeniem .ser i odtworzenie stanu obiektu z tego pliku. Ten proces odwrotny nazywa się deserializacją. sepulka Interfejs API Serializacji Java zapewnia programistom standardowy mechanizm serializacji obiektów przy użyciu interfejsów Serializable i Externalizable. Nawiasem mówiąc, ten artykuł jest kontynuacją moich ( nie moich, tłumacza, ale autora angielskiego oryginału) poprzednich artykułów: 20 pytań do wywiadu na temat wzorców projektowych i 10 pytań do wywiadu na temat wzorca Singleton w Javie . Więc chodźmy! Co to jest serializacja w Javie? Serializacja obiektów w Javie to proces używany do konwersji obiektu do formatu binarnego, który można zapisać na dysku lub przesłać przez sieć do dowolnej innej uruchomionej wirtualnej maszyny Java. odwrotny proces tworzenia obiektu ze strumienia binarnego nazywa się deserializacją. Java udostępnia interfejs API obejmujący java.io.Serializable, java.io.Externalizable, ObjectInputStream i ObjectOutputStream itp. Programiści mogą swobodnie używać domyślnego mechanizmu serializacji, którego używa Java w oparciu o strukturę klasy, ale mogą również używać własnego, niestandardowego formatu binarnego, który jest często zalecany jako najlepsza praktyka serializacji, ponieważ serializowany format binarny staje się częścią eksportowanego interfejsu API klasy i może potencjalnie przerwać enkapsulację w Javie zapewnianą przez pola prywatne i prywatne pakietu . Ogólnie rzecz biorąc, te informacje wystarczą na początek. Jak sprawić, by klasa Java mogła być serializowana? To bardzo łatwe. Twoja klasa musi po prostu zaimplementować interfejs java.io.Serializable, a JVM zajmie się serializacją obiektu w domyślnym formacie. Decyzję o utworzeniu klasy nadającej się do serializacji należy podjąć krótko, ponieważ chociaż krótkoterminowe koszty utworzenia klasy nadającej się do serializacji są niskie, koszty długoterminowe są znaczące i mogą potencjalnie ograniczyć możliwość wprowadzania dalszych modyfikacji w implementacji. Dzieje się tak, ponieważ podobnie jak w przypadku każdego publicznego interfejsu API, serializowana forma obiektu staje się częścią publicznego interfejsu API, a gdy zmieniasz strukturę klasy poprzez implementację interfejsu dodawania, dodanie lub usunięcie dowolnego pola może potencjalnie przerwać domyślną serializację. Można to jednak zminimalizować, stosując niestandardowy format binarny, ale nadal wymaga to wiele wysiłku, aby zapewnić kompatybilność wsteczną. Jednym z przykładów tego, jak serializacja może ograniczyć możliwość modyfikowania klasy, jest pole SerialVersionUID. Jeśli nie zadeklarujesz jawnie SerialVersionUID, maszyna wirtualna wygeneruje go w oparciu o strukturę klasy, która zależy od interfejsów zaimplementowanych przez klasę i kilku innych czynników, które można zmienić. Załóżmy, że implementujesz inny interfejs niż JVM, który wygeneruje inny SerialVersionUID dla nowej wersji plików klas, a gdy spróbujesz załadować stary obiekt serializowany przez starą wersję programu, otrzymasz komunikat Nieprawidłowy wyjątek klasy. Pytanie 1) Jaka jest różnica między interfejsem serializowalnym i zewnętrznym w Javie? To najczęściej zadawane pytanie podczas rozmowy kwalifikacyjnej dotyczącej serializacji Java. Interfejs Outsideizable udostępnia metody writeExternal() i readExternal(), które dają nam elastyczność kontrolowania serializacji zamiast polegania na domyślnym mechanizmie. Właściwa implementacja interfejsu Externalizable może znacznie poprawić wydajność aplikacji. Pytanie 2) Ile metod ma Serializable? Jeśli nie ma metody, to jaki jest cel interfejsu Serializable? Interfejs umożliwiający serializację znajduje się w pakiecie java.io i stanowi rdzeń mechanizmu serializacji Java. Nie posiada żadnych metod i w Javie nazywany jest także interfejsem znacznikowym . Kiedy Twoja klasa implementuje interfejs java.io.Serializable, staje się on możliwy do serializacji. To proste. Pytanie 3) Co to jest serialVersionUID? Co się stanie, jeśli tego nie zdefiniujesz? Jedno z moich ulubionych pytań podczas wywiadu dotyczącego serializacji Java. SerialVersionUID to identyfikator umieszczany na obiekcie podczas jego serializacji. Zwykle jest to kod skrótu obiektu. Możesz użyć narzędzia serialver, aby uzyskać serialVersionUID serializowanego obiektu. SerialVersionUID służy do kontroli wersji obiektu. Możesz także ręcznie określić serialVersionUID w pliku klasy. Konsekwencją nieokreślenia serialVersionUID jest to, że jeśli dodasz lub zmienisz dowolne pole w klasie, już serializowanej klasy nie będzie można odzyskać, ponieważ serialVersionUID wygenerowany dla nowej klasy będzie inny niż to samo pole starego serializowanego obiektu. Proces serializacji Java opiera się na poprawnym identyfikatorze serialVersionUID w celu przywrócenia stanu serializowanego obiektu i zgłasza wyjątek java.io.InvalidClassException w przypadku niezgodności. Aby dowiedzieć się więcej o serialversionuid, zobacz tutaj . Pytanie 4) Czy podczas serializacji chcesz, aby niektórzy członkowie nie byli serializowani? Jak to osiągnąć? Kolejne często zadawane pytanie podczas rozmowy kwalifikacyjnej w sprawie serializacji. Czasami ludzie pytają również, w jaki sposób używana jest zmienna przejściowa, czy zmienna przejściowa i statyczna jest serializowana, czy nie itp., więc jeśli nie chcesz, aby jakiekolwiek pole było częścią stanu obiektu, zadeklaruj je jako statyczne lub przejściowe w zależności na Twoje potrzeby i nie będzie uwzględniany w procesie serializacji Java. Pytanie 5) Co się stanie, jeśli jeden z członków klasy nie zaimplementuje interfejsu Serializable? Jedno z prostych pytań dotyczących procesu serializacji w Javie. Jeśli spróbujesz serializować obiekt klasy, która implementuje Serializable, ale obiekt zawiera odwołanie do klasy, która nie jest serializowalna, wówczas w czasie wykonywania zostanie zgłoszony wyjątek NotSerializableException i dlatego zawsze umieszczam SerializableAlert (sekcja komentarzy w moim kod), jedną z najlepszych technik komentowania kodu jest poinstruowanie programisty, aby pamiętał o tym fakcie podczas dodawania nowego pola do klasy Serializable. Pytanie 6) Jeśli klasę można serializować, ale jej nadklasa nie, jaki będzie stan zmiennych instancji odziedziczonych z nadklasy po deserializacji? Proces serializacji w Javie trwa jedynie w hierarchii obiektów tak długo, jak klasa implementuje interfejs Serializable, a wartości zmiennych odziedziczonych z nadklasy zostaną zainicjowane poprzez wywołanie konstruktora nadklasy nie serializowalnej w trakcie procesu deserializacji. Gdy łańcuch konstruktorów zostanie uruchomiony, nie ma możliwości jego zatrzymania, więc nawet jeśli klasy znajdujące się wyżej w hierarchii (nie) implementują interfejs Serializable , konstruktor zostanie wykonany. To pytanie do wywiadu serializacyjnego może wydawać się bardzo trudne, ale jeśli znasz kluczowe pojęcia, nie będzie to trudne. Pytanie 7) Czy możesz dostosować proces serializacji lub zastąpić domyślny proces serializacji w Javie? Odpowiedź brzmi: tak, możesz. Wszyscy wiemy, że w celu serializacji obiektu wywoływana jest metoda ObjectOutputStream.writeObject(saveThisObject), a w celu odczytania obiektu wywoływana jest metoda ObjectInputStream.readObject(), ale jest jeszcze jedna rzecz, którą zapewnia wirtualna maszyna Java - zdefiniowanie tych dwóch metod w Twojej klasie. Jeśli zdefiniujesz je w swojej klasie, JVM wywoła te dwie metody zamiast korzystać z domyślnego mechanizmu serializacji. Tutaj możesz skonfigurować zachowanie serializacji i deserializacji obiektu, wykonując dowolne zadanie przetwarzania wstępnego lub końcowego. Należy zauważyć, że metody te muszą być prywatne, aby uniknąć dziedziczenia, przesłaniania lub przeciążenia. Ponieważ tylko wirtualna maszyna Java może wywołać metodę prywatną, integralność klasy zostanie zachowana, a serializacja będzie działać normalnie. Moim zdaniem jest to jedno z najlepszych pytań, jakie można zadać podczas dowolnej rozmowy kwalifikacyjnej dotyczącej serializacji Java. Dobre pytanie uzupełniające brzmi: dlaczego miałbyś udostępnić niestandardowy serializowany formularz dla swojego obiektu? Pytanie 8) Załóżmy, że nadklasa nowej klasy implementuje interfejs Serializable. Jak możemy uniknąć serializacji nowej klasy? Jedno z trudnych pytań na rozmowie kwalifikacyjnej na temat serializacji w Javie. Jeśli nadklasa klasy implementuje już interfejs Serializable w Javie, wówczas klasa potomna również podlega serializacji, ponieważ nie można nie zaimplementować interfejsu rodzica i nie jest naprawdę możliwe uczynienie z niej klasy Non Serializable. Istnieje jednak sposób na uniknięcie serializacji dla tej nowej klasy. Aby to zrobić, musisz zaimplementować metody writeObject() i readObject() oraz zgłosić wyjątek NotSerializableException z tych metod. To pytanie jest zwykle zadawane jako pytanie dodatkowe w trakcie rozmowy kwalifikacyjnej. Pytanie 9) Jakie są metody stosowane w procesie serializacji i deserializacji w Javie? Jest to bardzo częste pytanie przy serializacji. Czego w tej sytuacji stara się dowiedzieć osoba przeprowadzająca rozmowę kwalifikacyjną? Niezależnie od tego, czy znasz użycie funkcji readObject(), writeObject(), readExternal() i writeExternal(), czy nie. Serializacja Java jest wykonywana przez klasę java.io.ObjectOutputStream. Ta klasa to filtrowany strumień owinięty wokół strumienia bajtów niższego poziomu w celu obsługi mechanizmu serializacji. Aby zapisać dowolny obiekt za pomocą mechanizmu serializacji, wywołujemy metodę ObjectOutputStream.writeObject(saveThisObject), a w celu deserializacji obiektu wywołujemy metodę ObjectInputStream.readObject(). Wywołanie metody writeObject() rozpoczyna proces serializacji. Ważną rzeczą, o której należy pamiętać w przypadku metody readObject() jest to, że służy ona do odczytywania bajtów oraz do tworzenia i zwracania obiektu z tych bajtów, który z kolei musi zostać rzutowany na właściwy typ. Pytanie 10) Załóżmy, że masz klasę, którą serializujesz i zapisałeś, a następnie modyfikujesz tę klasę, dodając nowe pole. Co się stanie, jeśli deserializujesz już serializowany obiekt? Zależy to od tego, czy klasa ma własny serialVersionUID, czy nie. Jak wiemy z powyższych pytań, jeśli w naszym kodzie nie podamy serialVersionUID, kompilator Java wygeneruje go sam i zwykle będzie on równy kodowi skrótu tego obiektu. Po dodaniu nowego pola istnieje ryzyko, że nowy serialVersionUID wygenerowany dla tej wersji klasy nie będzie zgodny z już serializowanym obiektem, w takim przypadku API zgłosi wyjątek java.io.InvalidClassException. Z tego powodu zaleca się posiadanie w kodzie własnego serialVersionUID, który jest zawsze taki sam dla tej samej klasy. Pytanie 11) Jakie są kompatybilne i niezgodne zmiany w mechanizmie serializacji Java? Prawdziwym problemem jest zmiana struktury klas poprzez dodanie dowolnego pola, metody lub usunięcie dowolnego pola lub metody z już zserializowanym obiektem. Zgodnie ze specyfikacją Java Serialization, dodanie dowolnego pola lub metody podlega zgodnym zmianom i zmianom, hierarchii klas lub interfejsom Serializable implementującym ONZ, niektóre w ramach niezgodnych zmian). Aby uzyskać pełną listę zgodnych i niekompatybilnych zmian, sugeruję przeczytanie specyfikacji serializacji Java. Pytanie 12) Czy możemy przesłać serializowany obiekt przez sieć? Tak, można przekazać serializowany obiekt przez sieć, ponieważ serializowany obiekt Java to zbiór bajtów, które można przekazywać w dowolny sposób. Można również przechowywać serializowany obiekt na dysku lub w bazie danych jako obiekt BLOB. Pytanie 13) Jakie typy zmiennych nie są serializowane podczas serializacji Java? To pytanie było czasami zadawane inaczej, ale cel był ten sam: sprawdzenie, czy programista Java zna specyfikę serializacji zmiennych statycznych i przejściowych. Ponieważ zmienne statyczne należą do klasy, a nie obiektu, nie są częścią stanu obiektu, więc nie są utrwalane podczas procesu serializacji Java. Ponieważ serializacja Java przechowuje tylko stan obiektu, a nie sam obiekt, zmienne przejściowe również nie są uwzględniane w procesie serializacji i nie są częścią serializowanego stanu obiektu. Po tym pytaniu być może ankieter zapyta: Jeśli nie przechowujesz wartości tych zmiennych, to jaka będzie wartość tych zmiennych po deserializacji i odtworzeniu tego obiektu? A to, koledzy, pomyślcie sami :) Oryginalny artykuł jest tutaj .
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION