インターネット Java 面接でよくある 14 の質問

(*-*)浩
リリース: 2019-11-15 16:31:28
オリジナル
2427 人が閲覧しました

インターネット Java 面接でよくある 14 の質問

#1.同期ロックとリエントラントロックの類似点と相違点

#同じ点

どちらもマルチスレッド同期とメモリ可視性セマンティクスを実装しており、すべてリエントラント ロックです

相違点

実装メカニズムが異なります。Java オブジェクト ヘッド ロック マークを通じて同期されます。オブジェクトは再入ロックを実装し、CAS、ASQ (AbstractQueuedSynchronizer)、およびロックサポート (ブロックおよびブロック解除用) を介して同期を実装します。これは、共有変数を含むマルチスレッド メモリの可視性を確保するために jvm メモリ モデルに依存します。再入ロックはマルチスレッドを保証します。 ASQ の揮発性状態による共有変数を含むメモリ。可視性

さまざまな方法で使用され、同期によりインスタンス メソッド (ロック インスタンス オブジェクト)、静的メソッド (ロック クラス オブジェクト)、コード ブロック (指定されたロック オブジェクトの表示) を変更できます。リエントラント ロック表示trylock()/lock() メソッドを呼び出すと、finally ブロックでロックを解放する必要があります。関数の豊富さが異なります。reentrantlock

は、ロックの待機時間を制限する (設定有効期限)、割り込み可能なロック (lockInterruptibly)、条件 (await、signal、およびその他のメソッドを提供) reentrantlock は、待機時間を設定できず、中断できない同期を実装するために公平なロックと不公平なロックを提供します。 ##2. なぜ concurrenthashmap はロックせずに読み取るのですか?

jdk1.7 1) HashEntry のキー、ハッシュ、次はすべて最終型であり、ヘッダーのみが最終型です。

2) HashEntry クラスの値フィールドは volatile として宣言されています

3) キーおよび値として null を使用することはできません。読み取りスレッドが読み取るときHashEntry の値フィールドの値が null であることは、競合が発生したことを認識しています。並べ替え現象が発生しています (put は新しい値オブジェクトを設定します。バイトコード命令の並べ替え)。ロック後にこの値を再読み取る必要があります

4) 揮発性変数カウントは、読み取りスレッドと書き込みスレッド間のメモリの可視性を調整します。カウントは書き込み操作の後に変更され、読み取り操作の最初の読み取りカウントは、前発生推移原則に従って変更されます。書き込み操作の操作を確認できます。

#jdk1.8

1) ノードの val と next は両方とも volatile

2) tabAt と casTabAt に対応する安全でない操作は volatile を実装しますセマンティクス

3. ContextClassLoader の役割 (スレッド コンテキスト クラス ローダー)

クラス ローダーの親をオーバーライドして、クラスをロードするための委任メカニズム (サービスローダー実装など) を使用します。スレッド コンテキスト クラス ローダーを使用してクラスをロードします。異なるクラス ローダーによって引き起こされる型変換例外 (ClassCastException) を防ぐために、通信する必要がある複数のスレッド間のクラス ローダーが同じであることを確認するように注意してください。)

4. Tomcat クラス ローディング メカニズム

異なるアプリケーションは、アプリケーション分離の効果を達成するために異なる Web アプリ クラス ローダーを使用します。Web アプリ クラス ローダーの下には JSP クラス ローディング サーバーがあり、異なるアプリケーションで共有される jar パッケージは、共有クラスローダー/共有ディレクトリに配置されます

5. osgi クラスローディングメカニズム

osgi クラスローディングモデルはメッシュです はい、モジュール間で相互に委任できます ( Bundle)

osgi モジュラー ホット デプロイメントを実現するための鍵は、カスタム クラス ローダー メカニズムの実装です。各バンドルには独自のクラス ローダーがあり、置き換える必要があるときに置き換えることができます。 、コードのホット置換を実現するために、バンドルとクラス ローダーが一緒に置き換えられます。

クラス ロード リクエストを受信すると、osgi は次の順序でクラス検索を実行します。

1) デリゲートjava.* で始まるクラスをロード用の親クラスローダーに転送

#2) それ以外の場合は、委任リスト (構成ファイル org.osgi.framework.bootdelegation で定義) 内のクラスを親クラスローダーのロード# に委任します。

##3) それ以外の場合は、Import-Package で宣言されているかどうかを確認します。そうであれば、このクラスのエクスポートに委任されたバンドルのクラス ローダーがロードされます

4) それ以外の場合は、宣言されているかどうかを確認してくださいRequire-Bundle で宣言されている場合は、クラスのロード要求を必要なバンドルのクラス ローダーに委任します。

5) それ以外の場合は、現在のバンドルのクラスパスを見つけて、独自のクラス ローダーを使用してロードします

6) それ以外の場合は、クラスが独自のフラグメント バンドル内にあるかどうかを確認します。そうであれば、それをフラグメント バンドルのクラス ローダーに委任してロードします。

7) それ以外の場合は、動的インポートを探します-Package (動的インポートは、このパッケージが実際に使用される場合にのみバンドルがロードされる場合にのみ使用可能です)、ロードのために対応するバンドルのクラスローダーに委任されます

8) それ以外の場合、クラス検索は失敗します

6. 常に実行中のスレッドを終了する方法

終了フラグを使用します。このフラグ変数は複数のスレッドから見える必要があります

割り込みを使用します。 isInterrupted()

7. threadlocal の使用シナリオと問題

threadlocal では、マルチスレッド共有変数の問題を解決できません。同じ threadlocal に含まれるオブジェクトは異なります。相互に干渉することなく、異なるスレッドにコピーします

トランザクションやデータベース接続など、同じスレッドによる複数の変数の読み取りを容易にするために、スレッド コンテキスト変数を保存するために使用されます。 Web プログラミング: スレッド プールのシナリオでは threadlocal を使用することに注意してください。実際の変数値はスレッドの threadlocalmap 型変数に格納されるため、最初に値を削除または設定しないと古い値が取得される可能性があります

質問: スレッド プールのシナリオにおけるメモリ リークに注意してください。スレッドローカルの get/set はキーを使用してエントリをクリアしますが (キーはスレッドローカルの弱参照ですが、値は強参照であるため、値は消去されません)

8. スレッドプールの起動から動作までのプロセス

最初に作成されたときは、スレッドプールはありません。タスクを追加するとき:

1 ) 実行中のスレッドの数がコア パラメーター corePoolSize 未満の場合は、このタスクを実行するためのスレッドの作成を続行します

2) それ以外の場合、実行中のスレッドの数が corePoolSize 以上の場合、タスクをブロッキング キューに追加します

3) それ以外の場合、キューがいっぱいで、同時に実行中のスレッドの数が増加する場合コアパラメータのmaximumPoolSizeより小さい場合は、このタスクを実行するためのスレッドの作成を続行します。

4) それ以外の場合、キューがいっぱいで、同時に実行されているスレッドの数がmaximumPoolSize以上の場合、処理されます。設定された拒否ポリシーに従って

5) タスクを完了し、次のタスクの処理を継続します

6) 処理を継続するタスクがない場合、スレッドが中断されるか、スレッド プールが停止されます。 Closed の場合、スレッドは実行を終了します。スレッド プールが閉じている場合、スレッドは終了します。

7) それ以外の場合は、スレッド プール内で実行されているスレッドの数がコア スレッドの数より大きいかどうかを確認します。スレッドが終了するか、それ以外の場合はスレッドがブロックされます。したがって、すべてのスレッド プール タスクが実行された後に残り続けるスレッド プールのサイズは corePoolSize

9 になります。 #poll(time): take BlockingQueue の最初のオブジェクトを取得します。すぐに取り出せない場合は、time パラメーターで指定された時間待つことができます。取得できない場合は、null## が返されます。 #take(): BlockingQueue の最初のオブジェクトを取得します。BlockingQueue が空の場合、新しいオブジェクトが BlockingQueue に追加されるまでブロックします

#10. ブロックせずに FutureTask から結果を取得する方法

get(long timeout,TimeUnit Unit), timeout 次に、

ポーリングに戻り、最初に isDone() を使用して終了したかどうかを判断し、次に get()

# を呼び出します。 ##11.blockingqueue 重要なデータが保存されている場合にシステムがクラッシュした場合の対処方法 処理

キューを永続化するのは面倒です。運用データはディスクに永続化する必要があります。データは後でのみ返されます。永続化は成功しました。コンシューマ スレッドは、ディスクからデータをメモリ ブロッキング キューにロードし、消費オフセットを維持します。起動時に、データがディスクからロードされ、消費オフセットに従ってメッセージ キューに追加され、メッセージが消去されないようにします。失われ、シーケンス番号が生成され、消費はべき等であり、システム再起動後の生産ステータスは消費プロセスに基づいて決定されます

#12. NIO と従来の I/O ## の違い# スレッドの保存、NIO は、各スレッドが複数のチャネル登録 (レジスタ) の処理を​​担当する単一のスレッド (つまりセレクター) への読み取りと書き込みをブロックするという本来の必要性から変更されます (最下層は依存します)。オペレーティング システムによって提供される epoll() 上)、netty Bossgroup は接続の受け入れを処理し、workergroup は特定のビジネス プロセスとデータの読み取りと書き込みを処理し、NIO はノンブロッキング操作を提供し、従来の I/O はストリーミング方式でデータを処理し、NIO はデータを処理しますNIO は、ヒープ内バッファとオフヒープ バッファに分割されたバイトバッファを提供します。読み取りと書き込みの場合は、まずこのバッファに置かれ、次にカーネルがチャネルを通じて反対側に送信します。ヒープ バッファは削除されません。カーネル、パフォーマンスが向上しました。

13. 繰り返し可能な文字列がリストに格納され、特定の文字列を削除する方法

イテレータ関連のメソッドを呼び出して削除します。逆方向の削除と正の順序の防止 削除による配列の再配置、配列要素のインデックススキップの問題

#14. GC ROOTS とは何ですか (日常の開発に関連するのは、これに関連するメモリ リークです)

すべての Java スレッドの現在アクティブなスタック フレームは、GC ヒープ内のオブジェクトへの参照をポイントしているため、メモリのリサイクル効率を向上させるために、未使用のオブジェクトは時間内に null に設定されます。

静的変数によって参照されるオブジェクト。そのため、静的変数が削減されます。特に静的コレクション変数のサイズが大きくなります。コレクションに格納されたオブジェクトは、継続的な増加を防ぐために euqls() と hashcode() を上書きします。

ローカル メソッドによって参照されるオブジェクト JNI

Constantこれにより、長い文字列に対して String.intern() を呼び出す必要性が減ります。

クラス オブジェクトがクラスローダーによってロードされるため、カスタム クラスローダーが無効な場合は、適切なタイミングで null を設定し、 jvm のクラスローダーによってロードされたオブジェクト間の分離 一部の静的データ構造は、GC ヒープ内のオブジェクトへの参照を指します

以上がインターネット Java 面接でよくある 14 の質問の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート