ホームページ  >  記事  >  Java  >  Java 面接でよくある質問 (回答付き)

Java 面接でよくある質問 (回答付き)

(*-*)浩
(*-*)浩オリジナル
2019-11-26 15:02:512480ブラウズ

Java 面接でよくある質問 (回答付き)

#配列を使用してキューを実装するにはどうすればよいですか?

配列を使用してキューを実装する場合、オーバーフロー現象に注意する必要がありますが、この場合は配列をループする、つまり両端を接続する方法を使用して解決できます。配列の。フロント ポインタを使用してキューの最初の位置を指し、テール ポインタを使用してキューの最後の位置を指します。 (推奨される学習:

java の一般的な面接の質問 )

内部クラスがローカル変数にアクセスするとき、変数を Final で変更する必要があるのはなぜですか?

ライフサイクルが違うからです。ローカル変数はメソッド終了後に破棄されますが、内部クラスのオブジェクトは必ずしも破棄されるわけではなく、内部クラスが存在しない変数を参照することになります。

したがって、コンパイラは内部クラスにローカル変数のコピーを生成しますが、このコピーのライフサイクルは内部クラスのオブジェクトと同じであるため、上記の問題は発生しません。

しかし、これにより、変数の 1 つが変更され、2 つの変数の値が異なる可能性があるという問題が発生します。この問題を解決するために、コンパイラは、2 つの変数が同じ値を持つようにローカル変数を最終的に変更する必要があることを要求します。

JDK8 以降、コンパイラは、内部クラスによってアクセスされるローカル変数を最終的に変更する必要はありませんが、ローカル変数の値は (メソッド内でも内部クラス内でも) 変更できません。変更しないとコンパイルが失敗します。エラーが報告されます。 javap を使用してコンパイルされたバイトコードを表示すると、コンパイラーが Final を追加していることがわかります。

long s = 499999999 * 499999999 上記のコードでは、s の値は何ですか?

コードの計算結果によれば、s の値は -1371654655 となるはずですが、これは Java の右辺の値の計算がデフォルトで int 型になっているためです。

非静的内部クラスは静的メソッドを定義できますか?

public class OuterClass{
    private static float f = 1.0f;

    class InnerClass{
        public static float func(){return f;}
    }
}

静的メソッドを定義できるのは静的内部クラスのみであるため、上記のコードはコンパイル エラーを引き起こします。

ロックと同期の違いは何ですか?

1. 使用方法的区别
- **Synchronized**:在需要同步的对象中加入此控制,`synchronized`可以加在方法上,也可以加在特定代码块中,括号中表示需要锁的对象。
- **Lock**:需要显示指定起始位置和终止位置。一般使用`ReentrantLock`类做为锁,多个线程中必须要使用一个`ReentrantLock`类做为对象才能保证锁的生效。且在加锁和解锁处需要通过`lock()`和`unlock()`显示指出。所以一般会在`finally`块中写`unlock()`以防死锁。
2. 性能的区别
`synchronized`是托管给JVM执行的,而`lock`是java写的控制锁的代码。在Java1.5中,`synchronize`是性能低效的。因为这是一个重量级操作,需要调用操作接口,导致有可能加锁消耗的系统时间比加锁以外的操作还多。相比之下使用Java提供的Lock对象,性能更高一些。但是到了Java1.6,发生了变化。`synchronize`在语义上很清晰,可以进行很多优化,有适应自旋,锁消除,锁粗化,轻量级锁,偏向锁等等。导致在Java1.6上`synchronize`的性能并不比Lock差。
  - **Synchronized**:采用的是CPU悲观锁机制,即线程获得的是独占锁。独占锁意味着 **其他线程只能依靠阻塞来等待线程释放锁**。而在CPU转换线程阻塞时会引起线程上下文切换,当有很多线程竞争锁的时候,会引起CPU频繁的上下文切换导致效率很低。
  - **Lock**:用的是乐观锁方式。所谓乐观锁就是,**每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止**。乐观锁实现的机制就是`CAS`操作。我们可以进一步研究`ReentrantLock`的源代码,会发现其中比较重要的获得锁的一个方法是`compareAndSetState`。这里其实就是调用的CPU提供的特殊指令。
3. `ReentrantLock`:具有更好的可伸缩性:比如时间锁等候、可中断锁等候、无块结构锁、多个条件变量或者锁投票。

float 変数は 0 とどのように比較されるのでしょうか?

folat 型と double 型があり、これら 10 進数型は 0 に近づくと直接 0 になる可能性は非常に低く、一般的には限りなく 0 に近づくため、= で判定することはできません。 |x-0|
//用程序表示就是

fabs(x) < 0.00001f
新しい非静的内部クラスを作成するにはどうすればよいですか?

内部クラスは、 int a と同様に、宣言されるときは、Outer.Inner a である必要があります。静的内部クラスと非静的内部クラス new に関しては、違いがあります:

Outer .Inner a = new inner().new Inner() (非静的、新しい内部クラスを作成する前に、Outer オブジェクトが存在する必要があります)

Outer.Inner a = new inner.Inner() (静的内部クラス)

Java 識別子の命名規則

次の文字、数字、$、_ (アンダースコア) を含めることができます。数字で始めることはできません。 Java のキーワードまたは予約語。

JDK で使用されているデザイン パターンを知っていますか?

デコレーション モード: java.io

シングル ケース モード: ランタイム クラス

シンプル ファクトリ モード: Integer.valueOf メソッド

フライウェイト モード :文字列定数プール、Integer.valueOf(int i)、Character.valueOf(char c)

イテレータ モード: Iterator

責任連鎖モード: ClassLoader の親委任モデル

インタプリタ モード: 正規表現 java.util.regex.Pattern

ConcurrentHashMap がスレッド セーフを確保する方法

JDK 1.7 以前:

ConcurrentHashMap では複数の変更が可能鍵となるのは、ロック分離テクノロジーの使用です。複数のロックを使用して、ハッシュ テーブルのさまざまな部分への変更を制御します。 ConcurrentHashMap は、これらのさまざまな部分を表すために内部的にセグメントを使用します。各セグメントは実際には小さなハッシュ テーブルであり、独自のロックを持っています。複数の変更操作は、異なるセグメントで実行される限り、同時に実行できます。

JDK 1.8:

セグメントは保持されますが、その属性は古いバージョンとの互換性を保つために簡素化されています。

挿入時に CAS アルゴリズムを使用します: unsafe.compareAndSwapInt(this, valueOffset, Expect, update)。 CAS (Compare And Swap) は、valueOffset 位置に含まれる値が期待値と同じである場合、valueOffset 位置の値を更新して true を返し、それ以外の場合は更新せずに false を返すことを意味します。挿入するときにキーまたは値を null にすることはできません。

これは Java8 の HashMap に似ています。最下層は引き続き「配列」リンク リストの赤黒ツリーで構成されます。

最下位構造体には TreeBin オブジェクトが格納されますが、TreeNode オブジェクトではありません。

CAS はよく知られたロックフリー アルゴリズムなので、ConcurrentHashMap にはロックがありませんか?もちろんそうではありません。ハッシュ値がリンク リストのヘッド ノードと同じである場合でも、同期されてロックされ、リンク リストはロックされます。

Thread.sleep() と Thread.yield()&Thread.wait() の違い

sleep() と yield() はどちらも CPU を解放します。

sleep() は、優先順位の低いスレッドに実行の機会を与えることができます。もちろん、同じ優先順位と高い優先順位のスレッドに実行の機会を与えることもできます。yield() は、同じ優先度の場合、実行の可能性があります。 実行の可能性があります。

Thread.sleep と Thread.yield() はロックの動作を変更しません。現在のスレッドがロックを所有している場合、Thread.sleep はスレッドにロックを解放させません。覚えておくと役立つと思いますが、ロック関連のメソッドは Object クラスで定義されているため、Thread.sleep を呼び出してもロック関連の動作には影響しないと考えてください。

Thread.sleep と Object.wait は現在のスレッドを一時停止します。CPU リソースに関しては、どのスレッドが一時停止されても、CPU 実行時間が不要になることを意味します。 OS は実行時間を他のスレッドに割り当てます。違いは、wait を呼び出した後、他のスレッドが CPU 実行時間を取り戻すために、notify/notifyAll を実行する必要があることです。

配列リストとリンクリストの違いは何ですか?

ArrayList と LinkedList は両方とも List インターフェイスを実装していますが、それらの間にはいくつかの違いがあります。

(1) ArrayList は Array でサポートされるインデックスに基づくデータ構造であるため、要素へのランダム アクセスを提供します

(2) ArrayList と比較して、要素の挿入、追加、削除は、より高速になります

(3) LinkedList の各ノードには前後のノードの参照が格納されるため、LinkedList は ArrayList よりも多くのメモリを消費します。

以上がJava 面接でよくある質問 (回答付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。