JavaRush /Java Blog /Random-JA /インタビューでの連載に関する質問トップ 13
Dmitry Vasilyev
レベル 26
Саратов

インタビューでの連載に関する質問トップ 13

Random-JA グループに公開済み
記事の翻訳https://javarevisited.blogspot.com/2011/04/top-10-java-serialization-interview.html Java のシリアル化とは何ですか? シリアル化は重要な概念の 1 つですが、プログラムの状態を保存するソリューションとしてはほとんど使用されないため、この API は開発者によって見落とされがちです。ただし、私の経験では、Java の基本的な面接ではシリアル化は非常に重要なトピックです。私がこれまで遭遇したほぼすべての面接には、連載に関する質問が 1 つまたは 2 つあり、候補者がこのテーマに関する質問をいくつか受けた後、この分野での経験が不足していることに不快感を感じているのを見てきました。Java でオブジェクトをシリアル化する方法が分からず、シリアル化の例に詳しくなく、その仕組みや一時変数と揮発性変数の違いを説明できず、シリアル化可能なインターフェイスにメソッドがいくつあるかも知りません。もっている。マーカーインターフェイスとは何ですか? その目的は何ですか? Java における Externalizable 実装と Serializable 実装の違いは何ですか? Java はアノテーションを導入した後、なぜ Serializable を @Serializable に置き換えなかったのでしょうか? この記事では、初心者から上級開発者まで、誰にとっても同様に役立つ、初心者と上級開発者の両方に対する質問を取り上げます。ほとんどの商用プロジェクトは、堅牢性を高めるためにデータベース、メモリ マップ ファイル、または単なるフラット ファイルのいずれかを使用していますが、Java のシリアル化プロセスに依存するプロジェクトはほとんどありません。いずれにせよ、この投稿はチュートリアルではありません。むしろ、Java の面接に行って未知の用語に驚かれる前に、自分自身で明確にする価値のある質問に関するものです。Java のシリアル化にまったく慣れていない人向け: 「Java のシリアル化は、オブジェクトの状態を .ser 拡張子の付いたファイルに保存し、オブジェクトの状態を再作成することによって、Java でオブジェクトをシリアル化するために使用されるプロセスです。このファイルから。この逆のプロセスはデシリアライズと呼ばれます。 セプルカ Java Serialization API は、Serializable および Externalizable インターフェイスを使用してオブジェクトをシリアル化するための標準メカニズムを開発者に提供します。ちなみに、この記事は、私 (翻訳者の私ではなく、英語の原文の著者) の以前の記事「デザインパターンに関するインタビューの質問 20 件」「Java のシングルトンパターンに関するインタビューの質問 10 件」の続きです。じゃ、行こう! Java におけるシリアル化とは何ですか? Java におけるオブジェクトのシリアル化は、オブジェクトをバイナリ形式に変換するために使用されるプロセスであり、バイナリ形式はディスクに保存したり、ネットワーク経由で他の実行中の Java 仮想マシンに送信したりできます。バイナリ ストリームからオブジェクトを作成する逆のプロセスは、逆シリアル化と呼ばれます。Java は、java.io.Serializable、java.io.Externalizable、ObjectInputStream、ObjectOutputStream などを含む API を提供します。プログラマは、クラス構造に基づいて Java が使用するデフォルトのシリアル化メカニズムを自由に使用できますが、独自のカスタム バイナリ形式も使用できます。シリアル化されたバイナリ形式はクラスのエクスポートされた API の一部になるため、これがシリアル化のベスト プラクティスとして推奨されることがよくあります。また、プライベート フィールドおよびパッケージ プライベートフィールドによって提供される Java のカプセル化が壊れる可能性があります。一般に、開始するにはこの情報で十分です。 Java クラスをシリアル化可能にするにはどうすればよいですか? これはとても簡単だ。クラスは java.io.Serializable インターフェイスを実装するだけでよく、JVM がオブジェクトをデフォルト形式でシリアル化します。シリアル化可能クラスの作成の短期的なコストは低いですが、長期的なコストは大きく、実装をさらに変更する能力が制限される可能性があるため、シリアル化可能クラスを作成する決定は短時間で行う必要があります。これは、他のパブリック API と同様に、オブジェクトのシリアル化された形式がパブリック API の一部となり、追加インターフェイスを実装してクラスの構造を変更する場合、フィールドを追加または削除すると、デフォルトのシリアル化が破壊される可能性があるために発生します。ただし、カスタム バイナリ形式を使用することでこれを最小限に抑えることができますが、それでも下位互換性を確保するには多大な労力が必要です。シリアル化によってクラスの変更機能がどのように制限されるかの一例は、SerialVersionUID フィールドです。SerialVersionUID を明示的に宣言しない場合、仮想マシンはクラス構造に基づいて SerialVersionUID を生成します。この構造は、クラスによって実装されたインターフェイスや、その他の変更可能ないくつかの要素に依存します。JVM ではなく別のインターフェイスを実装するとします。これにより、新しいバージョンのクラス ファイルに対して異なる SerialVersionUID が生成され、古いバージョンのプログラムによってシリアル化された古いオブジェクトをロードしようとすると、無効なクラス例外。 質問 1) Java の Serializable インターフェイスと Externalizable インターフェイスの違いは何ですか? これは、Java シリアル化の面接で最もよく聞かれる質問です。Externalizable インターフェイスには、writeExternal() メソッドと readExternal() メソッドが用意されており、これにより、デフォルトのメカニズムに依存する代わりにシリアル化を柔軟に制御できるようになります。Externalizable インターフェイスを適切に実装すると、アプリケーションのパフォーマンスが大幅に向上します。 質問 2) Serializable にはメソッドがいくつありますか? メソッドがない場合、Serializable インターフェイスの目的は何でしょうか? シリアル化可能なインターフェイスは java.io パッケージに存在し、Java のシリアル化エンジンの中核を形成します。メソッドを持たず、Java ではマーカー インターフェイスとも呼ばれます。クラスが java.io.Serializable インターフェイスを実装すると、クラスはシリアル化可能になります。それは簡単です。 質問 3) SerialVersionUID とは何ですか? 定義しないとどうなるでしょうか? 私のお気に入りの Java シリアル化インタビューの質問の 1 つです。SerialVersionUID は、オブジェクトがシリアル化されるときにそのオブジェクトに付けられる識別子で、通常はオブジェクトのハッシュ コードです。Serialver ツールを使用して、シリアル化されたオブジェクトの SerialVersionUID を取得できます。SerialVersionUID はオブジェクトのバージョン管理に使用されます。クラスファイルでserialVersionUIDを手動で指定することもできます。SerialVersionUID を指定しないと、クラス内のフィールドを追加または変更すると、新しいクラス用に生成された SerialVersionUID が古いシリアル化されたオブジェクトの同じフィールドと異なるため、既にシリアル化されたクラスを回復できなくなります。Java シリアル化プロセスは、正しい SerialVersionUID に基づいてシリアル化されたオブジェクトの状態を復元し、不一致がある場合は java.io.InvalidClassException をスローします。serialversionuid の詳細については、ここを参照してください。 質問4)連載する場合、一部のメンバーは連載しないでほしいですか?これを達成するにはどうすればよいでしょうか? もうひとつの連載インタビューでよくある質問。時々、一時変数がどのように使用されるか、一時変数と静的変数がシリアル化されているかどうかなどについて質問されることがあります。そのため、どのフィールドもオブジェクトの状態の一部にしたくない場合は、それに応じて静的または一時的として宣言します。 Java シリアル化プロセスには含まれません。 質問 5) クラス メンバーの 1 つが Serializable インターフェイスを実装していない場合はどうなりますか? Java のシリアル化プロセスに関する単純な質問の 1 つ。Serializable を実装するクラスのオブジェクトをシリアル化しようとしたが、そのオブジェクトに Serializable ではないクラスへの参照が含まれている場合、実行時に NotSerializableException がスローされます。そのため、私は常に SerializableAlert (コメント セクション) を設定しています。コード)、最良のコード コメント テクニックの 1 つは、Serializable クラスに新しいフィールドを追加するときにこの事実を覚えておくように開発者に指示することです。 質問 6) クラスはシリアル化可能だが、そのスーパークラスはシリアル化できない場合、逆シリアル化後にスーパークラスから継承されたインスタンス変数の状態はどうなりますか? Java シリアル化プロセスは、クラスが Serializable インターフェイスを実装している限り、オブジェクト階層内でのみ続行され、スーパークラスから継承された変数の値は、逆シリアル化プロセス中にシリアル化不可能なスーパークラスのコンストラクターを呼び出すことによって初期化されます。コンストラクター チェーンが開始されると、それを停止する方法はないため、階層内の上位のクラスが Serializable インターフェイスを実装している (実装していない) 場合でも、コンストラクターは実行されます。この連載インタビューの質問は非常に難しいように思えるかもしれませんが、重要な概念を理解していれば、難しくはありません。 質問 7) Java でシリアル化プロセスをカスタマイズしたり、デフォルトのシリアル化プロセスをオーバーライドしたりできますか? 答えは「はい、できます」です。オブジェクトをシリアル化するには ObjectOutputStream.writeObject(saveThisObject) が呼び出され、オブジェクトを読み取るために ObjectInputStream.readObject() が呼び出されることは誰もが知っていますが、Java 仮想マシンが提供する機能がもう 1 つあります。それは、これら 2 つのメソッドを定義することです。あなたのクラスで。これらをクラス内で定義すると、JVM はデフォルトのシリアル化メカニズムを使用する代わりに、これら 2 つのメソッドを呼び出します。ここでは、前処理タスクまたは後処理タスクを実行することで、オブジェクトのシリアル化および逆シリアル化の動作を構成できます。継承、オーバーライド、またはオーバーロードを避けるために、これらのメソッドはプライベートである必要があることに注意することが重要です。Java 仮想マシンのみがプライベート メソッドを呼び出すことができるため、クラスの整合性は維持され、シリアル化は通常どおり機能します。私の意見では、これは Java シリアル化の面接で尋ねられる最高の質問の 1 つです。フォローアップの良い質問は、「オブジェクトにカスタムのシリアル化フォームを提供する必要があるのはなぜですか?」です。 質問 8) 新しいクラスのスーパークラスが Serializable インターフェイスを実装すると仮定します。新しいクラスのシリアル化を回避するにはどうすればよいですか? Java でのシリアル化に関する面接での難しい質問の 1 つ。クラスのスーパークラスが既に Java の Serializable インターフェイスを実装している場合、親のインターフェイスを実装できないため、子孫クラスも Serializable になります。また、それを非 Serializable クラスにすることも実際には不可能です。ただし、この新しいクラスのシリアル化を回避する方法があります。これを行うには、writeObject() メソッドと readObject() メソッドを実装し、これらのメソッドから NotSerializableException をスローする必要があります。この質問は通常、面接が進むにつれて追加の質問として尋ねられます。 質問 9) Java のシリアル化および逆シリアル化プロセスで使用されるメソッドは何ですか? これは連載でよくある質問です。この場合、面接官は何を知ろうとしているのでしょうか?readObject()、writeObject()、readExternal()、writeExternal() の使用に慣れているかどうかは関係ありません。Java のシリアル化は、java.io.ObjectOutputStream クラスによって行われます。このクラスは、シリアル化エンジンを処理するために下位レベルのバイト ストリームにラップされるフィルター処理されたストリームです。シリアル化メカニズムを使用してオブジェクトを保存するには、ObjectOutputStream.writeObject(saveThisObject) を呼び出し、そのオブジェクトを逆シリアル化するには、ObjectInputStream.readObject() メソッドを呼び出します。writeObject() メソッドを呼び出すと、シリアル化プロセスが開始されます。readObject() メソッドについて注意すべき重要な点の 1 つは、このメソッドはバイトを読み取り、それらのバイトからオブジェクトを作成して返すために使用され、そのオブジェクトを正しい型にキャストする必要があるということです。 質問 10) シリアル化して保存したクラスがあり、そのクラスを変更して新しいフィールドを追加するとします。すでにシリアル化されているオブジェクトを逆シリアル化するとどうなりますか? それは、クラスが独自のserialVersionUIDを持っているかどうかによって異なります。上記の質問からわかるように、コード内で SerialVersionUID を指定しない場合、Java コンパイラーがそれを自動的に生成し、通常はそのオブジェクトのハッシュ コードと等しくなります。新しいフィールドを追加した後、そのバージョンのクラスに対して生成された新しい SerialVersionUID が、すでにシリアル化されたオブジェクトと一致しない可能性があります。その場合、API は java.io.InvalidClassException をスローします。このため、コード内に独自のserialVersionUIDを設定し、同じクラスでは常に同じにすることをお勧めします。 質問 11) Java シリアル化メカニズムにおける互換性のある変更と互換性のない変更は何ですか? 本当の問題は、フィールドやメソッドを追加したり、既にシリアル化されたオブジェクトを含むフィールドやメソッドを削除したりして、クラスの構造を変更することです。Java シリアル化仕様によれば、フィールドやメソッドの追加は互換性のある変更に該当し、クラス階層や UN 実装のシリアル化可能インターフェイスの変更には互換性のない変更が適用されます)。互換性のある変更と互換性のない変更の完全なリストについては、Java シリアル化仕様を読むことをお勧めします。 質問 12) シリアル化されたオブジェクトをネットワーク経由で転送できますか? はい、Java のシリアル化オブジェクトは任意の方法で受け渡すことができるバイトのコレクションであるため、シリアル化されたオブジェクトをネットワーク経由で渡すことができます。シリアル化されたオブジェクトをディスクまたはデータベースに BLOB として保存することもできます。 質問 13) Java シリアル化中にシリアル化されない変数のタイプは何ですか? この質問は別の方法で尋ねられることもありますが、目的は同じです。Java 開発者が静的変数と一時変数のシリアル化の詳細を理解しているかどうかを確認することです。静的変数はオブジェクトではなくクラスに属し、オブジェクトの状態の一部ではないため、Java シリアル化プロセス中には保持されません。Java シリアル化ではオブジェクトの状態のみが保存され、オブジェクト自体は保存されないため、一時変数もシリアル化プロセスには含まれず、オブジェクトのシリアル化状態の一部ではありません。この質問の後、おそらく面接官は次のように尋ねます。これらの変数の値を保存しない場合、このオブジェクトを逆シリアル化して再作成した後のこれらの変数の値はどうなりますか? そしてこれは、同僚の皆さん、自分で考えてください:) 元の記事はここにあります
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION