アリババ:2021年春に中級および上級のJava面接の質問、50の詳細な説明、ちょうどいい

アリババ:Autumnは、中級および上級のJavaインタビューの質問、50の詳細な説明、ちょうどいいものを募集しています

 

最近、たくさんの子供靴から面接の質問がありましたが、本日はプログラマーの面接でよくある質問をまとめましたので、子供靴のお役に立てば幸いです![記事の最後に完全なインタビューの質問収集方法があります]

質問1マルチスレッドの使用は何ですか?

多くの人にとってナンセンスに思えるかもしれませんが、マルチスレッドを使用します。その用途は何ですか。私の意見では、この答えはさらにナンセンスです。いわゆる「理由を知る、理由を知る」、「使える」、「理由を知る」、「なぜ使うのか」は「理由を知る」、「理由を知り、理由を知る」程度の場合のみ「と言えば知識ポイントは自由に使えます。OK、この問題に関する私の見解について話させてください。

(1)マルチコアCPUの利点を最大限に活用する

業界の進歩に伴い、現在のノートブック、デスクトップ、さらには商用アプリケーションサーバーも少なくともデュアルコアであり、4コア、8コア、さらには16コアも珍しくありません。シングルスレッドプログラムの場合は、デュアルコアCPUは50%が無駄になり、75%は4コアCPUで無駄になりました。シングルコアCPUでのいわゆる「マルチスレッド」は、偽のマルチスレッドです。プロセッサは同時にロジックの一部しか処理できませんが、スレッドの切り替えが速く、複数のスレッドが「同時に」実行されているように見えます。マルチコアCPUでのマルチスレッドは、本当のマルチスレッドです。これにより、マルチセグメントロジックを同時に機能させることができます。マルチスレッドは、マルチコアCPUを真に活用し、完全なものにするという目的を達成できます。 CPUの使用。

(2)ブロッキングを防ぐ

プログラム効率の観点から、シングルコアCPUは、マルチスレッドの利点を活用するだけでなく、シングルコアCPUで実行されるマルチスレッドにより、スレッドコンテキストを切り替えます。これにより、プログラムの全体的な効率。ただし、シングルコアCPUの場合は、ブロッキングを防ぐために、マルチスレッドを適用する必要があります。シングルコアCPUがシングルスレッドを使用する場合、たとえば特定のデータをリモートで読み取るなど、スレッドがブロックされている限り、ピアは返されず、タイムアウト期間が設定されていない場合、プログラム全体がデータが返される前に実行を停止しました。マルチスレッドはこの問題を防ぐことができます。複数のスレッドが同時に実行されています。1つのスレッドのコード実行がデータの読み取りのためにブロックされている場合でも、他のタスクの実行には影響しません。

(3)モデル化が容易

これは、それほど明白ではないもう1つの利点です。大きなタスクA、シングルスレッドプログラミングがあるとすると、多くの考慮事項があり、プログラムモデル全体を構築するのは面倒です。ただし、この大きなタスクAをいくつかの小さなタスク(タスクB、タスクC、およびタスクD)に分解し、プログラムモデルを個別に構築し、マルチスレッドを介してこれらのタスクを個別に実行すると、はるかに簡単になります。

質問2Javaでスレッドダンプファイルを取得する方法

無限ループ、デッドロック、ブロッキング、ページを開くのが遅いなどの問題の場合、スレッドダンプをヒットすることが問題を解決するための最良の方法です。いわゆるスレッドダンプはスレッドスタックです。スレッドスタックを取得するには、次の2つの手順があります。

(1)スレッドのpidを取得するには、jpsコマンドを使用するか、Linux環境ではps -ef | grepjavaを使用します。

(2)スレッドスタックを出力するには、jstack pidコマンドを使用できます。また、Linux環境ではkill -3pidを使用することもできます。

さらに、Threadクラスは、スレッドスタックを取得するためにも使用できるgetStackTrace()メソッドを提供します。これはインスタンスメソッドであるため、このメソッドは特定のスレッドインスタンスにバインドされ、特定のスレッドが現在実行されているスタックを取得するたびに、

質問3生産者/消費者モデルの役割は何ですか

この質問は非常に理論的ですが、非常に重要です。

(1)生産者の生産能力と消費者の消費能力のバランスをとることにより、システム全体の運用効率を向上せる。これが生産者/消費者モデルの最も重要な機能である。

(2)デカップリング生産者-消費者モデルの付随効果である。生産者と消費者との間のより少ない接続があることを意味するデカップリング。少数の接続は、もっと彼らは相互の制約を受けることなく独立して開発することができます。

質問4:短いs1 = 1; s1 = s1 + 1;何が問題なのですか?短いs1 = 1; s1 + = 1;何が問題なのですか?

分析:

面接の質問は非常に異常なので、虐待に備えてください。

s1 = s1 + 1はエラーを引き起こし、s1 + 1はint型であり、intをs1に割り当てることはできません。変換を表示する必要があり、s1 =(int)(s1 + 1)、s1 + = 1は失敗しません。理由としては、コンパイラのメカニズムに関係していると言う人もいます。コンパイルの原則コンパイルの原則が最も厄介ですこれはどうですか

アリババ:Autumnは、中級および上級のJavaインタビューの質問、50の詳細な説明、ちょうどいいものを募集しています

 

質問5スレッドがオブジェクトモニターを保持しているかどうかを検出する方法

また、インターネットでマルチスレッドのインタビューの質問を見て、スレッドがオブジェクトモニターを保持しているかどうかを判断する方法があることを知りました。スレッドクラスは、オブジェクトobjのモニターが存在する場合に限り、holdsLock(Object obj)メソッドを提供します。スレッドが保持されている場合にのみtrueを返します。これは静的メソッドであることに注意してください。つまり、「スレッド」は現在のスレッドを指します。

質問6:最も頻繁に発生する実行時例外の1つを教えてください。

分析

この質問も非常に一般的です。答えられない場合、インタビュアーはプログラミングの経験がないと思います。

NullPointerException、null参照例外。正直なところ、ChinaSoftの筆記試験の質問にはこれがあります。多くの人が質問の意味を誤解していました。彼らは、ランタイム例外がランタイム例外を指すことを認識していませんでした。

質問7同期とReentrantLockの違い

Synchronizedは、if、else、for、whileと同じキーワードであり、ReentrantLockはクラスであり、これが2つの本質的な違いです。ReentrantLockはクラスであるため、同期よりも柔軟な機能を提供します。継承、メソッド、さまざまなクラス変数を使用できます。ReentrantLockは、いくつかの点で同期よりも拡張性があります。

(1)ReentrantLockは、デッドロックを回避するために、ロックを取得するための待機時間を設定できます。

(2)ReentrantLockは、さまざまなロックに関する情報を取得できます

(3)ReentrantLockは、複数の通知を柔軟に実装できます

質問8volatileキーワードの役割

非常に重要な問題は、マルチスレッドを学習して適用するすべてのJavaプログラマーがそれを習得しなければならないということです。volatileキーワードの役割を理解するための前提条件は、Javaメモリモデルを理解することです。Javaメモリモデルについてはここでは説明しません。ポイント31を参照してください。volatileキーワードには2つの主要な機能があります。

(1)マルチスレッドは、主に可視性と原子性の2つの特性を中心に開発されています。volatileキーワードで変更された変数は、複数のスレッド間の可視性を保証します。つまり、揮発性変数が読み取られるたびに、最新のデータである必要があります。

(2)基礎となるコードの実行は、これまで見てきた高水準言語であるJavaプログラムほど単純ではありません。その実行はJavaコード->バイトコード->バイトコードに従って対応するC / C ++コードを実行します-> C / C ++コードはアセンブリ言語にコンパイルされ、ハードウェア回路と対話します。実際には、パフォーマンスを向上させるために、JVMが命令を並べ替えたり、マルチスレッドで予期しない問題が発生したりする場合があります。もちろん、volatileを使用すると、禁止されているセマンティクスが並べ替えられます。これにより、コードの実行効率もある程度低下します。

実用的な観点から、volatileの重要な役割は、CASと組み合わせて原子性を確保することです。詳細については、AtomicIntegerなどのjava.util.concurrent.atomicパッケージの下のクラスを参照してください。

質問9:楽観的ロックと悲観的ロックとは何ですか

(1)楽観的ロック:その名前と同じように、同時操作によって引き起こされるスレッドセーフの問題について楽観的です。楽観的ロックは、競合が常に発生するとは限らないため、ロックを保持する必要はないと考えています。比較します。 twoこのアクションは、メモリ内の変数を変更しようとするアトミック操作として使用されます。失敗した場合は、競合があることを意味するため、対応する再試行ロジックが必要です。

(2)ペシミスティックロック:その名前と同じように、並行操作によって引き起こされるスレッドセーフの問題についてペシミスティックです。ペシミスティックロックは、常に競合が発生すると考えているため、リソースが操作されるたびに、排他的なロックが保持されます。同期され、それが3または7 21であるかどうかに関係なく、リソースをロックすると、リソースを直接操作できます。

質問10デッドロックを引き起こすプログラムを書くためのJavaプログラミング

このトピックを初めて見たとき、とても良い質問だと思いました。多くの人がデッドロックとは何かを知っています。スレッドAとスレッドBは互いのロックを待機し、プログラムを無期限にループさせます。もちろん、これに限定されます。デッドロックプログラムの書き方がわかりません。この場合、デッドロックとは何かわかりません。理論を理解すれば終わりです。でデッドロックの問題が発生しました。基本的には見えません。

デッドロックとは何かを真に理解するために、この問題は難しくありません。ほんの数ステップです。

(1)2つのスレッドは、lock1とlock2の2つのオブジェクトオブジェクトを保持します。これらの2つのロックは、同期コードブロックのロックとして使用されます。

(2)スレッド1のrun()メソッドの同期コードブロックは、最初にlock1、Thread.sleep(xxx)のオブジェクトロックを取得します。時間はかからず、50ミリ秒はほぼ同じで、次にオブジェクトを取得します。 lock2のロック。これの主な目的は、スレッド1がlock1オブジェクトとlock2オブジェクトのオブジェクトロックを一度に取得するのを防ぐことです。

(3)スレッド2の実行)(メソッドの同期コードブロックは、最初にlock2のオブジェクトロックを取得し、次にlock1のオブジェクトロックを取得します。もちろん、lock1のオブジェクトロックはスレッド1のロックによって保持されています。スレッド2はスレッドを待機している必要があります。1lock1のオブジェクトロックを解除します。

このように、スレッド1はスリープ後に「スリープ」し、スレッド2はlock2のオブジェクトロックを取得し、スレッド1はこの時点でlock2のオブジェクトロックを取得しようとしてブロックされます。このとき、デッドロックが発生します。 。コードは記述されておらず、多くのスペースを占有します。Javaマルチスレッド7:デッドロックこの記事には、上記の手順のコード実装が含まれています。

アリババ:Autumnは、中級および上級のJavaインタビューの質問、50の詳細な説明、ちょうどいいものを募集しています

 

質問11タスクを送信するときにスレッドプールキューがいっぱいになるとどうなりますか

制限のないキューであるLinkedBlockingQueueを使用する場合は、問題ではありません。LinkedBlockingQueueは、タスクを無期限に格納できる無限のキューと見なすことができるため、実行のためにブロックキューにタスクを追加し続けます。制限のあるキューを使用する場合は、たとえば、ArrayBlockingQueueの場合、タスクは最初にArrayBlockingQueueに追加されます。ArrayBlockingQueueがいっぱいになると、拒否ポリシーRejectedExecutionHandlerを使用して完全なタスクが処理されます。デフォルトはAbortPolicyです。

質問12:ハッシュマップとハッシュテーブルの違い。

分析:

これはもっと遭遇しました。

アリババ:Autumnは、中級および上級のJavaインタビューの質問、50の詳細な説明、ちょうどいいものを募集しています

 

質問13スピンとは

同期されたコードの多くは単純なコードであり、実行時間は非常に高速です。現時点では、待機中のスレッドはすべてロックされています。スレッドのブロックにはユーザーモードとカーネルモードの切り替えの問題が伴うため、操作に値しない場合があります。 。同期されたコードは非常に高速に実行されるため、ロックを待機しているスレッドはブロックされませんが、同期の境界でビジーループを実行します。これはスピンです。複数のビジーループを実行し、ロックが取得されていないことがわかった場合は、再度ブロックします。これは、より適切な戦略である可能性があります。

質問14:Javaメモリモデルとは何ですか

Javaメモリモデルは、Javaメモリへのマルチスレッドアクセスの仕様を定義します。Javaメモリモデルの完全な説明は、これらの数文で明確に言えることではありません。Javaメモリモデルのいくつかの部分を簡単に要約します。

(1)Javaメモリモデルは、メモリをメインメモリとワーキングメモリに分割します。クラスの状態、つまりクラス間で共有される変数はメインメモリに格納されます。Javaスレッドがメインメモリでこれらの変数を使用するたびに、メインメモリ内の変数を1回読み取り、これらのメモリを存在させます。作業メモリにコピーがあります。独自のスレッドコードを実行するときは、これらの変数を使用して、作業メモリ内のコピーを操作します。スレッドコードが実行された後、最新の値がメインメモリに更新されます

(2)メインメモリとワーキングメモリの変数を操作するために、いくつかのアトミック操作が定義されています

(3)揮発性変数の使用規則を定義する

(4)発生前、つまり、操作Aが操作Bの前に発生する必要があるといういくつかのルールを定義する最初の発生の原則。たとえば、同じスレッドの制御フローの前のコードは、コードの後ろのコードの前に発生する必要があります。制御フロー、および解放ロックロック解除アクションは、同じロックのロックロックアクションなどの前に実行する必要があります。これらのルールが満たされている限り、追加の同期手段は必要ありません。コードの一部がすべてを満たさない場合は、 -ルールの前に、このコードはスレッドセーフでなければなりません

質問15:スレッドがオブジェクトの同期メソッドに入った後、他のスレッドはこのオブジェクトの他のメソッドに入ることができますか?

分析:

アリババ:Autumnは、中級および上級のJavaインタビューの質問、50の詳細な説明、ちょうどいいものを募集しています

 

アリババ:Autumnは、中級および上級のJavaインタビューの質問、50の詳細な説明、ちょうどいいものを募集しています

 

質問16:try {}にreturnステートメントがあり、tryが実行された直後のfinally {}のコードは、returnの前後にいつ実行されますか?

分析

プログラムによって証明されるように、それは戻る前に実行されます:

アリババ:Autumnは、中級および上級のJavaインタビューの質問、50の詳細な説明、ちょうどいいものを募集しています

 

結果は次のとおりです。

retrun

最後に

リターン1

質問17シングルトンモードのスレッドセーフ

これは昔ながらの質問です。最初に言うことは、シングルトンモードのスレッドセーフは、特定のクラスのインスタンスがマルチスレッド環境で1回だけ作成されることを意味するということです。シングルトンモードを作成する方法はたくさんあります。要約すると、次のようになります。

(1)空腹の中国のシングルトンパターンの記述:スレッドセーフ

(2)レイジーシングルトンモードの書き込み方法:非スレッドセーフ

(3)ダブルチェックロックシングルトンモードの文言:スレッドセーフ

質問18Hashtableのsize()メソッドには明らかに「returncount」というステートメントが1つしかないのに、なぜ同期する必要があるのですか?

これは私の以前の混乱です。あなたがこの問題について考えたかどうかはわかりません。メソッドに複数のステートメントがあり、それらがすべて同じクラス変数で動作している場合、マルチスレッド環境でロックしないと、必然的にスレッドセーフの問題が発生します。これは理解しやすいですが、size()メソッドには明らかに1つのステートメント、なぜそれをロックする必要があるのですか?

ゆっくりと働き、勉強することでこの問題を理解する主な理由は2つあります。

(1)同時に、固定クラスの同期メソッドを実行できるスレッドは1つだけですが、クラスの非同期メソッドの場合、複数のスレッドが同時にアクセスできます。したがって、問題があります。スレッドAがHashtableのputメソッドを実行してデータを追加している場合、スレッドBは通常size()メソッドを呼び出してハッシュテーブル内の現在の要素の数を読み取ることができ、読み取られた値は最新のスレッドAはデータの追加を終了した可能性がありますが、スレッドBはすでにsize ++と一致せずにサイズを読み取っているため、スレッドBによって読み取られたサイズは不正確である必要があります。size()メソッドに同期を追加した後、スレッドAがputメソッドを呼び出した後にのみ、スレッドBがsize()メソッドを呼び出すことを意味します。これにより、スレッドの安全性が確保されます。

(2)CPUはコードを実行しますが、Javaコードではありません。これは非常に重要であり、覚えておく必要があります。Javaコードは最終的に実行用のアセンブリコードに変換されます。アセンブリコードは、ハードウェア回路と実際に対話できるコードです。Javaコードが1行しかない場合や、Javaコードのコンパイル後に生成されるバイトコードが1行しかない場合でも、最下層の操作が1つしかないという意味ではありません。この文の。「リターンカウント」の1文を3つのアセンブリ文に変換して実行することを想定しています。最初の文を実行した後、スレッドを切り替えることは可能です。

質問19:swtichはバイト、ロング、文字列に作用できますか?

分析:

switchステートメントの式は整数型のみにすることができます。つまり、int、char、または列挙型のデータである必要があります。ブールまたは浮動小数点、あるいは他のタイプの整数データ(バイト、ショート、ロング)にすることはできません。

質問20同時実行性が高く、タスクの実行時間が短い企業は、スレッドプールをどのように使用しますか?同時実行性が低く、タスクの実行時間が長い企業は、スレッドプールをどのように使用しますか?同時実行性が高く、ビジネスの実行時間が長いビジネスでは、スレッドプールをどのように使用しますか?

これは並行プログラミングのウェブサイトで見た質問です。最後の質問にこの質問を置きました。この質問は非常に優れており、非常に実用的で、非常に専門的であるため、皆さんに見て考えていただきたいと思います。この問題に関して、私の個人的な意見は次のとおりです。

(1)同時実行性が高く、タスク実行時間が短いサービスの場合、スレッドプール内のスレッド数をCPUコア数+1に設定できるため、スレッドコンテキストの切り替えが少なくなります。

(2)同時実行性が低く、タスクの実行時間が長いビジネスは区別する必要があります。

  • IO操作はCPUを占有しないため、ビジネス時間がIO操作、つまりIO集約型タスクに長時間集中している場合は、すべてのCPUをアイドル状態にしないでください。これにより、スレッドプール内のスレッド数を次のように増やすことができます。 CPU処理をより多くのビジネスにする
  • 営業時間が長く、計算操作、つまり計算量の多いタスクに集中している場合、これは方法ではありません。(1)と同様に、スレッドプール内のスレッド数を少なく設定して、スレッドコンテキストの切り替えを減らします。

(3)高い同時実行性と長いビジネス実行時間このタイプのタスクを解決するための鍵は、スレッドプールではなく、全体的なアーキテクチャ設計です。これらのビジネスの特定のデータをキャッシュできるかどうかを確認することが最初のステップであり、サーバーを追加することが最初のステップです。第1ステップ第2ステップスレッドプールの設定については、(2)を参照してください。最後に、ミドルウェアを使用してタスクを分割および分離できるかどうかを確認するために、ビジネスの実行時間が長いという問題も分析する必要があります。

読者のメリット:

スペースの関係で、すべての問題を一覧表示することはできません。これらの問題をドキュメントにまとめてネットワークディスクに転送しました。必要な友達は、[下の写真を参照して小さなアシスタントを追加する]だけで無料で受け取ることができます。

アリババ:Autumnは、中級および上級のJavaインタビューの質問、50の詳細な説明、ちょうどいいものを募集しています

 

アリババ:Autumnは、中級および上級のJavaインタビューの質問、50の詳細な説明、ちょうどいいものを募集しています

 

アリババ:Autumnは、中級および上級のJavaインタビューの質問、50の詳細な説明、ちょうどいいものを募集しています

 

アリババ:Autumnは、中級および上級のJavaインタビューの質問、50の詳細な説明、ちょうどいいものを募集しています

 

おすすめ

転載: blog.csdn.net/m0_50180963/article/details/114174903