1. Java のプリミティブ データ型、そのサイズ、および対応するカプセル化クラスとは何ですか?
(1) boolean
ブールデータ型は true または false のいずれかです。このデータ型は 1 ビットの情報を表しますが、そのサイズは正確に定義されていません。
「Java 仮想マシン仕様」には次のように記載されています: 「ブール データ型は定義されていますが、非常に限定されたサポートのみを提供します。Java 仮想マシンにはブール値専用のバイトコード命令はありません。ブール値Java 言語で操作される式は、コンパイル後に Java 仮想マシンの int データ型に置き換えられ、ブール配列は Java 仮想マシンのバイト配列にエンコードされ、各ブール要素は 8 ビットを占めます。このようにして、ブール型は単独で使用される場合は 4 バイト、配列では 1 バイトであると結論付けることができます。では、なぜ仮想マシンはブール値ではなく int を使用するのでしょうか? byte または short を使用しないのは、メモリ領域をさらに節約できないでしょうか?実際、int を使用する理由は、現在の 32 ビット CPU では、一度に 32 ビット データを交換する方が効率的であるためです。
要約すると、次のことがわかります: 公式ドキュメントではブール型の正確な定義は示されていません。「Java 仮想マシン仕様」では、「単独の場合は 4 バイト、ブール配列の場合は 1 バイトを使用する」という定義が示されています。仮想マシンの実装が仕様に従っているかどうかに依存するため、1 バイトまたは 4 バイトが可能です。これは実際には時間と空間のトレードオフです。
ブール型のカプセル化クラスは Boolean です。
(2)byte——1バイト——Byte
(3)short——2バイト——Short
(4)int——4バイト——Integer
(5)long——8バイト— — —Long
(6)float——4バイト——Float
(7)double——8バイト——Double
(8)char——2バイト——Character
2. 「==」と「equals()」の違い。
「Java で考える」には、「関係演算子はブール値の結果を生成し、オペランドの値間の関係を計算します。」と書かれています。
「==」は、2 つのオブジェクトのメモリ アドレスが同じかどうかを判断します。これは、プリミティブ データ型と列挙型に適しています (それらの変数は値自体を格納しますが、参照型変数は参照を格納します)。オブジェクトの実装はメモリ アドレスを比較することです。このメソッドをオーバーライドして、「等しい」の概念をカスタマイズできます。たとえば、クラス ライブラリ内の String、Date、およびその他のクラスは、このメソッドを書き直しました。
要約すると、列挙型とプリミティブ データ型の間の等価比較には「==」を使用する必要があり、参照型間の等価比較には、equals メソッドを使用する必要があります。
3. Java の 4 種類の参照とその適用シナリオとは何ですか?
強参照: 通常、 new 演算子を使用してオブジェクトを作成するときに返される参照は、強参照です。
ソフト参照: ソフト参照を通じてのみオブジェクトに到達できる場合、オブジェクトは存在するときにリサイクルされます。メモリが不足しています。使用できます。画像キャッシュでは、メモリが不足している場合、システムは使用されなくなったビットマップを自動的にリサイクルします
弱い参照: オブジェクトが弱い参照を通じてのみアクセスできる場合、そのオブジェクトはリサイクルされます。 (十分なメモリがある場合でも)、画像キャッシュでも使用できますが、現時点では、ビットマップが使用されなくなった限りリサイクルされます
仮想参照: 仮想参照は「最も弱い」ですJava では参照先のオブジェクトを取得することさえできません。存在する唯一の役割は、それが指すオブジェクトを処理することです。そのため、それが指すオブジェクトがいつなのかを知ることができます。が破壊されます。
4. オブジェクトにはどのようなメソッドが定義されていますか?
clone()、equals()、hashCode()、toString()、notify()、notifyAll()、wait()、finalize()、getClass()
5. hashCodeの機能は何ですか?
ハッシュテーブルの基本原理と実装を参照してください
6. ArrayList、LinkedList、Vector の違いは何ですか?
ArrayList: 内部的に配列を使用して要素を格納し、効率的なランダムアクセスをサポートし、動的なサイズ変更をサポートします
LinkedList: 内部的にリンクされたリストを使用して要素を格納し、要素の高速な挿入/削除をサポートしますが、効率的なランダムアクセスはサポートしません
Vector : ArrayList のスレッドセーフ バージョンを作成する
7 を参照してください。String、StringBuilder、StringBuffer の違いは何ですか?
String: 不変の文字シーケンス。新しい文字を追加するには、新しい String オブジェクトを作成する必要があります。
StringBuilder: 新しい文字の追加をサポートする、変更可能な文字シーケンス (新しいオブジェクトを作成する必要はありません)。
StringBuffer: はい、StringBuilder
8 の特性と使用法です。
Map
Set
List
Queue
Stack
詳細な手順については、公式ドキュメントを参照してください。関連するデータ構造に精通していない学生は、「アルゴリズム入門」またはその他の関連書籍を参照してください。
9. HashMap と HashTable の違い
HashTable はスレッドセーフですが、HashMap はスレッドセーフではありません
HashMap では Null キーと Null 値が許可されますが、HashTable では許可されません
さらに詳しい分析については、 HashMap 、HashTable
の詳細な分析を参照してください
10. HashMapの実装原理
簡単に言えば、HashMapの基礎となる実装は「ジッパーメソッドに基づくハッシュテーブル」です。詳細な分析については、HashMapとHashTableの詳細な分析を参照してください
ConcurrentHashMapの実装原理
ConcurrentHashMapは、読み取り時にロックが必要ないのが特徴です。データを書き込むときのロック粒度は可能な限り小さいことが保証されます。内部的には「セグメントストレージ」を使用しているため、書き込むデータが配置されている「セグメント」をロックするだけで済みます。 ConcurrentHashMap の基礎となる実装の詳細な分析については、「Java Concurrent Programming: Concurrent Concurrent HashMap
12」を参照してください。 TreeMap、LinkedHashMap、および HashMap の違いは何ですか?
HashMap の基礎となる実装はハッシュ テーブルであるため、その中に格納される要素は順序付けされていません。
TreeMap の基礎となる実装は赤黒ツリーであるため、その中に格納される要素は順序付けされます。並べ替えは、自然順序、または TreeMap の作成時に指定された Comparator オブジェクトに基づいて行われます。
LinkedHashMap は要素が挿入される順序を記憶できます。
さらに詳しい説明については、HashMap、LinkedMap、TreeMap の違いを参照してください
13 Collection と Collections の違いは何ですか?
Collection
Java コレクション フレームワークに詳しくない方は、Java コア技術ポイントのコレクション フレームワークを参照してください。ステートメント、finally ステートメント ブロックは実行されますか?
答えは「はい」です。 finally ブロック内のステートメントが実行されない状況は 2 つだけです:
System.exit() メソッドが呼び出された場合、
JVM が「クラッシュ」した場合。
15. Java の例外階層
Java の例外階層は以下のとおりです:
Throwable クラスが例外階層の基本クラスであることがわかります。 Error クラスは制御できない内部エラーを表し、Exception は例外を表します。RuntimeException とそのサブクラスには、ArrayIndexOutOfBoundsException や NullPointerException などが含まれます。発生した条件判断やその他のステートメントによって、未チェックの例外を回避する必要があります。 IOException とそのサブクラスはチェック例外です。コンパイラは、スローされる可能性のあるすべてのチェック例外に対して例外ハンドラが提供されているかどうかをチェックします。そうでない場合は、エラーが報告されます。チェックされていない例外については、それをキャッチする必要はありません (もちろん Java でも例外をキャッチできますが、すべきなのは、チェックされていない例外の発生を避けることです)。
16. Java オブジェクト指向の 3 つの特徴と意味
3 つの主要な特徴: カプセル化、継承、ポリモーフィズム。詳しい紹介については、Java オブジェクト指向の 3 つの主要な機能をクリックしてください
17 オーバーライドとオーバーロードの意味と違い
オーバーライドとは、親内の同じメソッドを再定義する「上書き」を意味します。サブクラスによるクラス
Overloadは「多重定義」「Contain」、つまり、定義されたメソッドと同じ名前で異なるシグネチャを持つ新しいメソッドを定義することを意味します
18 インターフェースと抽象クラスの違い
。インターフェイスは規則であり、インターフェイスを実装するクラスはこの規則に従う必要があります。抽象クラスは本質的にクラスであり、抽象クラスを使用するコストはインターフェイスのコストよりも高くなります。インターフェースと抽象クラスの比較は次のとおりです。
抽象クラスには属性、メソッド (抽象メソッドと特定の実装を持つメソッドを含む)、および定数を含めることができます。インターフェースには定数とメソッド宣言のみを含めることができます。
抽象クラスのメソッドとメンバー変数は可視性 (パブリック、プライベートなど) を定義できますが、インターフェイスのメソッドはパブリックのみにできます (デフォルトはパブリックです)。
サブクラスは親クラス (具体クラスまたは抽象クラス) を 1 つだけ持つことができますが、インターフェイスは複数のインターフェイスを継承でき、クラスは複数のインターフェイスを実装することもできます。
サブクラスが親クラスの抽象メソッドを実装する場合、可視性は親クラスの可視性以上にすることができますが、インターフェイス実装クラスのインターフェイス メソッドの可視性は、親クラスの可視性と同じにすることしかできません。インターフェース(パブリック)。
19. 静的内部クラスと非静的内部クラスの違い
静的内部クラスは外部クラスへの参照を保持しませんが、非静的内部クラスは外部クラスへの参照を暗黙的に保持します。
内部クラスの詳細については、Java コア テクノロジの内部クラスをクリックしてください
20. Java におけるポリモーフィズムの実装原理
いわゆるポリモーフィズムは、サブクラス オブジェクトを指す親クラス参照を指します。メソッドを呼び出すと、親クラスの実装ではなく、サブクラスの実装が呼び出されます。ポリモーフィズム実装の鍵は「動的バインディング」にあります。詳細については、Java 動的バインディングの内部実装メカニズムをクリックしてください
21。Java で新しいスレッドを作成する 2 つの方法を簡単に説明します
Thread クラスを継承し (サブクラスが MyThread であると仮定します)、オーバーライドします。 run() メソッド。次に、新しい MyThread オブジェクトを作成し、それに対して start() を呼び出して新しいスレッドを開始します。
Runnable インターフェースを実装し (実装クラスが MyRunnable であると仮定)、MyRunnable オブジェクトをパラメーターとして Thread コンストラクターに渡し、取得した Thread オブジェクトで start() メソッドを呼び出します。
22. Java でのスレッド同期の方法を簡単に説明します。
volatile: Java メモリ モデルは、同じ volatile 変数への書き込みが読み取り前に行われるようにします。
synchronized: コード ブロックを同期するために使用できます。メソッドがロックされている場合、「ロックされた」場所はクリティカル セクションと呼ばれます。クリティカル セクションに入るスレッドはオブジェクトのモニターを取得します。そのため、クリティカル セクションに入ろうとする他のスレッドはモニターを取得できないためブロックされます。別のスレッドがモニターを解放するのを待ってブロックされているスレッドは中断できません。
ReentrantLock: ロックを取得しようとしているスレッドを中断し、タイムアウト パラメーターを設定できます。
より詳細な紹介については、Java のコア技術ポイントであるマルチスレッドをクリックしてください
23. Java の詳細なロックの種類を簡単に説明します
Java では、クラス、オブジェクト、メソッド、またはコード ブロックをロックできます。 。より詳細な紹介については、「Java コア テクノロジー ポイント マルチスレッド
」をクリックしてください。 24. 「プロデューサーとコンシューマー」問題の解決策を提供します
ブロッキング キューを使用します:
public class BlockingQueueTest { private int size = 20; private ArrayBlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<>(size); public static void main(String[] args) { BlockingQueueTest test = new BlockingQueueTest(); Producer producer = test.new Producer(); Consumer consumer = test.new Consumer(); producer.start(); consumer.start(); } class Consumer extends Thread{ @Override public void run() { while(true){ try { //从阻塞队列中取出一个元素 queue.take(); System.out.println("队列剩余" + queue.size() + "个元素"); } catch (InterruptedException e) { } } } } class Producer extends Thread{ @Override public void run() { while (true) { try { //向阻塞队列中插入一个元素 queue.put(1); System.out.println("队列剩余空间:" + (size - queue.size())); } catch (InterruptedException e) { } } } } }
25. ThreadLocal の設計概念と役割
ThreadLocal の役割は、スレッド内でローカル変数を提供することです。これにより、マルチスレッド環境でアクセスされたときに各スレッドの ThreadLocal 変数が独立していることが保証されます。つまり、各スレッドの ThreadLocal 変数はそれ自体専用であり、他のスレッドからアクセスすることはできません。 ThreadLocal は、次のシナリオで最も一般的に使用されます。マルチスレッド環境で非スレッドセーフ オブジェクトに同時アクセスがあり、オブジェクトをスレッド間で共有する必要はないが、この場合はロックしたくない。この場合、ThreadLocal を使用して、各スレッドがこのオブジェクトのコピーを維持できるようにすることができます。
ThreadLocal の実装原理の分析については、クリックして ThreadLocal を詳細に分析してください
27 ArrayBlockingQueue、CountDownLatch クラスの役割
CountDownLatch。カウンタが 0 になるまで待機するスレッドのセット。該当するシナリオ: 1 つ以上のスレッドが実行を続行する前に、指定された数のイベントが発生するまで待機する必要がある場合。
ArrayBlockingQueue: 配列実装に基づくブロッキング キュー。構築時に容量を指定する必要があります。満杯のキューに要素を追加しようとしたり、空のキューから要素を削除しようとすると、現在のスレッドはブロックされます。ブロッキング キューを使用すると、次のモードで作業できます。ワーカー スレッドは中間結果を定期的にブロッキング キューに入れ、他のスレッドは中間結果を取り出してさらなる操作を実行できます。ワーカー スレッドの実行が遅い場合 (キューに要素を挿入する時間がない場合)、ワーカー スレッドが高速に実行される場合、キューから要素を取得する他のスレッドはそれを待ちます (空のキューから要素を取得してブロックしようとします)。 (満杯のキューに要素を挿入しようとすると)、続行する前に他のスレッドが要素を削除するのを待ちます。
28. wait() と sleep() の違い
wait(): Object クラスで定義されたインスタンス メソッド。指定されたオブジェクトで wait メソッドを呼び出すと、現在のスレッドが待機状態になります (現在のスレッドがオブジェクトのモニターを保持している場合)。このとき、現在のスレッドは対応するオブジェクトのモニターを解放します。スレッドはオブジェクト モニターを取得する機会があります。他のスレッドがこのオブジェクトのモニターを取得して必要な操作を実行すると、通知メソッドを呼び出して、以前に待機状態に入ったスレッドをウェイクアップできます。
sleep(): Thread クラスの静的メソッド。現在のスレッドをスリープ状態にして、他のスレッドが実行できるようにするために使用されます。スリープ状態になったスレッドは、保持しているロックを解放しません。
29. スレッド プールの使用法と利点
利点: スレッドの再利用を実現し、スレッド プールを使用してスレッドを均一に管理することで、同時実行スレッドの数を削減できます。スレッドの数が多すぎると、スレッドのコンテキストの切り替えとスレッドの同期に時間がかかりすぎる傾向があります。
使用法: ThreadPoolExecutor のコンストラクター メソッドを呼び出して、スレッド プールを自分で作成できます。ただし、通常は、Executors クラスによって提供される静的ファクトリ メソッドを使用して、スレッド プール オブジェクトをより簡単に作成できます。スレッド プール オブジェクトを作成した後、submit メソッドを呼び出してタスクをスレッド プールに送信して実行できます。スレッド プールを使用した後は、shutdown メソッドを呼び出してスレッド プールを閉じる必要があります。
スレッド プールの詳細な紹介と実装原理の分析については、Java のスレッド プールの詳細な理解
30 の for-each ループと従来の for ループの効率の比較
をクリックしてください。この問題については、「Effective Java」を直接読みます。 答え:
for-each能够让代码更加清晰,并且减少了出错的机会。下面的惯用代码适用于集合与数组类型: for (Element e : elements) { doSomething(e); }使用for-each循环与常规的for循环相比,并不存在性能损失,即使对数组进行迭代也是如此。实际上,在有些场合下它还能带来微小的性能提升,因为它只计算一次数组索引的上限。
31. Java IO と NIO の違いを簡単に説明します
Java IO はストリーム指向です。つまり、データから 1 バイト以上を読み取る必要があります。すべてのバイトが読み取られるまで一度にストリームします。NIO はバッファ指向です。つまり、データがバッファに読み込まれ、バッファ内のデータがそれに応じて処理されます。
Java IO はブロッキング IO ですが、NIO はノンブロッキング IO です。
Java NIO にはセレクターと呼ばれるものがあり、複数のチャネルをセレクターに登録し、スレッドを使用してこれらのチャネルを監視できます。これらのチャネルに特定の準備がある場合、これで読み取りまたは書き込み操作を開始できます。 、対応するチャネルの読み取りと書き込みを開始します。チャネルが読み取り/書き込み可能になるのを待機している間、チャネル上で読み取りおよび書き込み操作を要求しているスレッドは他のことを行うことができます。
詳しい説明については、Java NIO と IO
をクリックしてください。 リフレクションの役割と原理
リフレクションの役割は、どの属性やメソッドが定義されているかなど、実行時にクラスのさまざまな定義情報を取得することです。 。原理は、クラスオブジェクトを通じてクラスに関するさまざまな情報を取得することです。
詳細については、Java のコア技術点であるリフレクション
を参照してください。
33 Java の汎用メカニズム
汎用メカニズムの詳細については、Java のコア技術点であるジェネリック
をクリックしてください。
34. Java 7 と Java 8 の新機能
以下に 2 つの非常に優れた要約を示します: Java 7 の新機能 Java 8 の新機能
35. 一般的なデザイン パターン
いわゆる「デザイン」パターン」はオブジェクト指向に他なりません。プログラミングで一般的に使用されるソフトウェア設計手法のいくつかがあり、実際のテストを経て、これらの設計手法はそれぞれのシナリオでのニーズを解決できるため、現在広く流通している「デザインパターン」となっています。言い換えれば、正式には、特定のシナリオで厄介な問題が発生したために、対応するデザイン パターンが生まれたということです。これを明確にした上で、特定のデザインパターンを学ぶときは、その作成の背景とそれが解決する主な矛盾を完全に理解する必要があります。
一般的に使用されるデザイン パターンは、次の 3 つのカテゴリに分類できます:
クリエイティブ パターン: ファクトリ パターン (さらに単純なファクトリ パターン、ファクトリ メソッド パターン、および抽象ファクトリ パターンに分類できます)、ビルダー パターン、およびシングルトン パターンを含む。
構造モード: アダプター モード、ブリッジ モード、デコレーション モード、外観モード、フライウェイト モード、プロキシ モードを含みます。
行動パターン: コマンドモード、メディエーターモード、オブザーバーモード、ステートモード、戦略モードを含みます。
各モードの詳細については、図解された設計パターン
36 を参照してください。 JNI の基本的な使用法
JNI については、次の優れた記事を参照してください: Android の JNI
37。動的プロキシのシナリオと原則
動的プロキシに関しては、Java コア技術の動的プロキシ
を直接参照してください
アノテーションの基本概念と使用方法
アノテーションは「アノテーションの拡張版」と見なすことができます。コンパイラに情報を提供することができ、仮想マシンはいくつかのことを説明します。
アノテーションは Java コードを記述するコードであり、コンパイラーによって解析でき、アノテーション処理ツールは実行時にアノテーションを解析することもできます。注釈自体は「受動的」情報であり、能動的に解析される場合にのみ意味を持ちます。
コンパイラー/仮想マシンに情報を渡すことに加えて、アノテーションを使用して「テンプレート化された」コードを生成することもできます。
これで十分ですか?もちろん十分ではありません。上記は、面接での Java に関するよくある質問のリストです。それらのほとんどは、Java テクノロジー システムの中核となる技術的なポイントでもあり、これらの質問によって提起される一連の質問は、私たちが行うべき知識体系を改善する方法を示しています。最善のことは、この道に沿って進み続けることです:)
Java インタビューの知識ポイントの概要と関連記事の詳細については、PHP 中国語 Web サイトに注目してください。