前に書かれた
インターネット上の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のインタビューの質問と、それらに一般的に答える方法を分析します。
最後に、長年のインタビュー経験を共有します。面接では、トータルスコアの論理に従って質問に答えることができます。最初に結論を直接破棄し、次に例を使用して結論を示します。面接官の心を初めて把握するようにしてください。そうしないと、鍵や限界を把握できないという印象を人々に与えやすくなります。