Java Road to God:Javaインタビューの準備(8)

記事のディレクトリ

4.16の次の構造の中で、最高の挿入パフォーマンスは

4.17次の構造のどれがスタックとしての使用に最も適していますか

ここに画像の説明を挿入

4.18 Mapの実装クラスのうち、順序付けられているものと無秩序なものの中で、順序性のパフォーマンスが高いと思う順序性の順序性をどのように確保するか、より良いまたはより効率的な実装がありますか?

  1. Mapの実装クラスは、HashMap、LinkedHashMap、TreeMapです。

  2. HashMapは無秩序であり、LinkedHashMapとTreeMapは両方とも順序付けられています(LinkedHashMapはデータを追加する順序を記録し、TreeMapはデフォルトで自然な昇順になります)

  3. LinkedHashMapの基礎となるストレージ構造は、ハッシュテーブル+リンクリストであり、リンクリストはデータの追加順序を記録します

  4. TreeMapの基礎となるストレージ構造はバイナリツリーであり、バイナリツリーを順番にトラバースすることで、データの順序が保証されます。

  5. LinkedHashMapは、基になるデータストレージ構造で使用されるハッシュテーブルにより、より高い順序付けパフォーマンスを備えています。

4.19以下のコードはほとんどの場合正常に実行されますが、どのような状況で問題が発生しますか?根本的な原因はどこにありますか

import java.util.LinkedList;
public class Stack {
    
    
    LinkedList list = new LinkedList();
    public synchronized void push(Object x) {
    
    
        synchronized (list) {
    
    
            list.addLast(x);
            notify();
        }
    }
    public  synchronized Object pop() throws  Exception{
    
    
        synchronized(list){
    
    
            if(list.size()<=0){
    
    
                wait();
            }
            return list.removeLast( );
        }
    }
}

将if(list.size())改是while(list.size())

4.20 TreeMapとTreeSetは、並べ替え時に要素をどのように比較しますか?コレクションツールクラスのsort()メソッドが要素を比較する方法

TreeSetでは、格納されたオブジェクトが属するクラスにComparableインターフェイスを実装する必要があります。このインターフェイスは、要素を比較するためのcompareTo()メソッドを提供します。要素が挿入されると、このメソッドが呼び出されて要素のサイズが比較されます。TreeMapでは、キーと値のペアのマッピングに格納されているキーが、キーに従って要素を並べ替えるためにComparableインターフェイスを実装する必要があります。Collectionsユーティリティクラスのsortメソッドには、2つのオーバーロードされた形式があります。1つ目は、受信コンテナに格納されているオブジェクトの比較を並べ替える必要があり、要素の比較を実現するためにComparableインターフェイスを実装します。2つ目は、コンテナ内の要素を並べ替える必要はありません。必須。比較可能である必要がありますが、2番目のパラメーターを渡す必要があります。パラメーターはComparatorインターフェースのサブタイプです(要素の比較を行うにはcompareメソッドを書き直す必要があります)。これは一時的に定義された並べ替えルールと同等です。実際、比較要素のサイズはインターフェースを介して注入されます。アルゴリズムはコールバックモードのアプリケーションでもあります。

4.21リストから同じオブジェクトを削除する方法

public class Test {
    
    
    public static void main(String[] args) {
    
    
        List<String> li1 = new ArrayList<String>();
        li1.add("8");
        li1.add("8");
        li1.add("9");
        li1.add("9");
        li1.add("0");
        System.out.println(li1);
        //方法:将List中数据取出来来存到Set中
        HashSet<String> set = new HashSet<String>();
        for(int i=0;i<li1.size();i++){
    
    
            set.add(li1.get(i));
        }
        System.out.println(set);
    }
   
}

4.22Java.util.Mapの実装クラスは次のとおりです。

1、HashMap

2、ハッシュテーブル

3、LinkedHashMap

4、TreeMap

4.23次の説明のうち正しいものはどれですか

4.24 Javaコンテナとは何ですか?同期コンテナはどれですか?同時コンテナはどれですか

同期コンテナ:スレッドセーフを指します。データの整合性は保証されますが、同時実行性は非常に低く、通常はsynchronizedキーワードを使用します。

  • バクター
  • ハッシュ表
  • スタック
  • Collections.synchronized()

並行コンテナ:マルチスレッド環境でも効率が高く、ロックの使用が削減されます

  • CopyOnWrieArrayList
  • CopyOnWriteArraySet
  • ConcurrentHashMap
  • ArrayBlockingQueue
  • LinkedBlockingQueue

4.25ArrayListとLinkedListの挿入とアクセスの時間計算量

ArrayListルックアップの時間計算量はO(1)であり、挿入の時間計算量はO(n)です。

LinkedList検索の時間計算量はO(n)であり、挿入の時間計算量はO(1)です。

4.26 HashMapはどのような状況で拡張されますか?どのアクションが拡張をトリガーしますか

JDK1.7でのHashMap拡張は、2つの条件を満たす必要があります

1.新しい値を格納する場合、将来の要素数がしきい値以上になる

2.新しい値を格納する場合、現在の配列に既存の値があります

JDK1.8拡張条件

新しい値が保存された後、要素の数がしきい値を超えると、容量が拡張されます

どのアクションが拡張をトリガーしますか

1、put()

2、merge()

4.27HashMapでのputメソッドの実行プロセス

HashMapputメソッドは、 HashMapのコア関数と見なすことできます。HashMapのデータ構造は、配列+リンクリストです。値は、キーと値の形式で保存されます。値は、を呼び出すことによって保存および取得されます。 putメソッドとgetメソッド。
Entry配列を内部的に維持し、キーのhashCode値を取得し、ビット単位のAND演算でシフトしてから、配列の長さ-1で論理AND演算を実行してインデックス値を取得し、格納されているデータの位置を決定します。リンクされたリストを介してハッシュの競合の問題を解決します。衝突が発生すると、オブジェクトはリンクリストの次のノードに保存されます。

4.28 HashMapがハッシュの競合を検出した後、要素はリンクリストの最後または最初に挿入されますか?

4.29 jdk1.8は赤黒木を使用し、赤黒木の特徴について話します。なぜ人々はAVLの代わりに赤黒木を使用しなければならないのですか。

CurrentHashMapでロックされていますが、実際には読み取り/書き込みロックです。書き込みの競合がある場合は、待機します。

挿入時間が長すぎると待ち時間が長くなり、赤黒木の挿入がAVL木よりも速くなります!

4.30 HashMapとHashTableの基本的な実装の違いは何ですか?HashTbleとConcurrentHashMap

ハッシュ表

  • 最下位の配列+リンクリストが実装され、キーも値もnullすることはでき、スレッドセーフですスレッドセーフを実現する方法は、データを変更するときにHashTable全体をロックすることです。これは非効率的であり、ConcurrentHashMap最適化されています。
  • 初期サイズは11、拡張:newsize = olesize * 2 + 1
  • インデックスの計算方法:index =(hash&0x7FFFFFFF)%tab.length

HashMap

  • +基になる配列のリンクリストの実装、nullキーとnull値格納されている可能性があり、スレッドセーフではありません
  • 初期サイズは16、拡張:newsize = oldsize * 2、サイズは2のn乗である必要があります
  • 展開はマップ全体を対象としています。展開が実行されるたびに、元の配列の要素が再計算され、再挿入されます。
  • 要素を挿入した後、展開するかどうかを判断し、無効な展開となる場合があります(挿入後に展開した場合、再度挿入しないと無効な展開になります)
  • マップ内の要素の総数がエントリ配列の75%を超えると、展開操作がトリガーされます。リンクリストの長さを短縮するために、要素の分布はより均一になります。
  • インデックスメソッドの計算:index = hash&(tab.length – 1)

ConcurrentHashMap

  • 最下層は、スレッドセーフセグメント化された配列+リンクリストで実装されます
  • マップ全体をNセグメントに分割することで、同じスレッドセーフを提供できますが、効率はN倍になり、デフォルトは16倍になります。(読み取り操作はロックされていません。HashEntryの値変数は揮発性であるため、最新の値も確実に読み取られます。)
  • Hashtableの同期は、ハッシュテーブル全体に対して行われます。つまり、スレッドが独占できるようにテーブル全体がロックされるたびに、ConcurrentHashMapを使用すると、複数の変更操作を同時に実行できます。重要なのは、ロック分離テクノロジの使用です。
  • size()やcontainsValue()など、一部のメソッドはセグメントにまたがる必要があり、セグメントだけでなくテーブル全体をロックする必要がある場合があります。これには、すべてのセグメントを順番にロックする必要があり、操作の完了後にすべてのセグメントをロックする必要があります。ロックは順番に解放されます
  • 拡張:セグメント内の拡張(セグメント内の要素がセグメントの対応するエントリ配列の長さの75%を超えて拡張をトリガーし、マップ全体が拡張されない)、挿入前の検出は拡張を必要としないため、効果的に回避されます無効な展開

4.31高速障害と安全障害の違いは何ですか

Iteratorの安全上の失敗は、基になるコレクションのコピーに基づいているため、ソースコレクションの変更による影響を受けません。

java.utilパッケージのすべてのコレクションクラスはすぐに失敗します

java.util.concurrentパッケージのすべてのクラスは安全に失敗します

高速失敗イテレータはConcurrentModificationExceptionをスローします

安全障害イテレータがそのような例外をスローすることはありません

おすすめ

転載: blog.csdn.net/weixin_54707168/article/details/113975161