Javaインタビューの質問-ArrayListの一般的な知識ポイント

前に書かれた

インターネット上のArrayListに関するインタビューの質問はたくさんありますが、それらのほとんどは、検索や変更などの効率の問題の分析など、ArrayListのデータ構造から始まります。この記事では、並行性の観点から始めて、その方法を説明します。 ArrayListの同時実行の問題に答えるために。

面接レビュー

一般的に、コンテナなどの問題は、一般的に片側で調査されるため、より基本的であり、これは、両側に入るかどうかを決定する際の重要な要素にもなっています。

インタビュアー:履歴書でJavaの基本をマスターできると思いますが、どのコンテナーを使用しましたか?

私:こんにちは、インタビュアー。ArrayList、LinkedList、HashSet、hashMapなどは一般的な作業で一般的に使用されます。

インタビュアー:それらはすべてスレッドセーフですか?

私:スレッドセーフではありません。同時実行性の高い状況ではスレッドセーフの問題が発生します。

インタビュアー:ArrayListの問題について簡単に説明するプログラムを作成できますか?

もちろん、このとき、普段蓄積しているプログラムを考え出す必要があります。

私:

次のように:20スレッドを開くと、各スレッドは乱数を生成し、リストコンテナに乱数を追加します

public class ArrayListUnsafe {
    public static void main(String[] args) {
        List<String> lists = new ArrayList <>();
        for (int i = 0; i < 20; i++) {
            new Thread(()->{
                lists.add(UUID.randomUUID().toString().substring(0,5));
                System.out.println(lists);
            },String.valueOf(i)).start();
        }
    }
}

通常の状況では、このプログラムはjava.util.ConcurrentModificationExceptionを報告します。これは、同時実行性の高い状況でも一般的なエラーであり、同時変更の例外です。

インタビュアー:なぜこの問題が発生するのですか?

私:マルチスレッドでは、コンテナにデータを書き込むたびに順序が保証されません。コンテナをプリエンプトする人がデータの書き込みを開始するため、上書き状況が発生し、毎回一貫性のない結果になる可能性があります。

インタビュアー:この問題を回避する方法はありますか?

私:jdkは、Listのスレッドセーフを確保するためのさまざまな方法を提供します。

従来のVectorコレクションクラスを使用します。ただし、このクラスは、スレッドセーフを確保するためにSynchronizeキーワードをメソッドに追加します。ただし、ヘビーウェイトロック方式が使用されて実行効率が低下するため、jdKは推奨されなくなりました。
ツール、Collections.synchronizedListを使用して、スレッドセーフを確保します。たとえば、
リストリスト= Collections.synchronizedList(new ArrayList <>());
コピーオンライトコレクションクラスを使用します。CopyOnWriteArrayList
は、ボーナスアイテムであるコピーオンライトと言うことができます。

インタビュアー:CopyOnWriteArrayListとは何かについて簡単に話していただけますか?

私:コピーオンライトは、データの読み取りと書き込みのプロセスを分離することに似ています。といった

スレッドとBスレッドの両方がデータの書き込みを開始します。AとBがデータを書き込むたびに、ライセンスを取得する必要があります(ロックと同様)。メインメモリ内のデータは作業メモリにコピーされてから変更されます。変更が完了しましたコンテナ参照を新しいデータセットにポイントし、他のスレッドがそれを変更できるようにします。

ソースコード

たとえば、コピーオンライトのadd()メソッドの場合、jdkソースコードは次のようになります。

public boolean add(E e) {
    // 先获取锁,也就是前文说的许可证
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
        Object[] elements = getArray();
        int len = elements.length;
        // 将原数组复制一份
        Object[] newElements = Arrays.copyOf(elements, len + 1);
        // 添加新值
        newElements[len] = e;
        // 将数组索引指向新数组
        setArray(newElements);
        return true;
    } finally {
        // 最后释放锁
        lock.unlock();
    }
}

要素が追加されるたびに、最初にロック(つまり、アクセス許可)が取得され、次に要素が更新されます。

このレベルに答えると、ArrayListの質問がより良い答えであると考えられます。一方の質問に、その理由と方法でそれぞれの質問に答えることができれば、当然のことながら、もう一方の質問に答えることができます。

インタビュアー:さて、今日のインタビューは以上です。次のインタビューの時間はいつですか?手配させていただきます。

ははは、おめでとうございます、面接はここで無事に勝ちました。双方の準備をしてください。

私:あなたの取り決めにもよりますが、最近は時間があります。

総括する

コンテナの問題について説明しているブログはたくさんあります。ArrayListの基礎となるデータ構造に興味がある場合は、自分で検索できます。この記事では、主にスレッドセーフの観点からArrayListのインタビューの質問と、それらに一般的に答える方法を分析します。

最後に、長年のインタビュー経験を共有します。面接では、トータルスコアの論理に従って質問に答えることができます。最初に結論を直接破棄し、次に例を使用して結論を​​示します。面接官の心を初めて把握するようにしてください。そうしないと、鍵や限界を把握できないという印象を人々に与えやすくなります。

おすすめ

転載: blog.csdn.net/doubututou/article/details/112315548