Javaインタビューの質問の全集(7)

Javaインタビューの質問の全集(7)

BaiyuITハハ

61.マルチスレッドプログラムを作成する方法はいくつありますか?

回答:Java 5より前にマルチスレッドを実装する方法は2つあります。1つはThreadクラスを継承する方法、もう1つはRunnableインターフェイスを実装する方法です。スレッドの動作を定義するには、両方のメソッドでrun()メソッドをオーバーライドする必要があります。Javaでの継承は単一の継承であるため、後者をお勧めします。クラスには親クラスがあります。Threadクラスを継承する場合、他のクラスを継承することはできません。明らかに、Runnableインターフェイスの使用はより柔軟です。

追加:Java 5の後、スレッドを作成する3番目の方法があります。Callableインターフェイスを実装します。このインターフェイスのcallメソッドは、スレッドの実行が終了したときに戻り値を生成できます。コードは次のとおりです。


import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
class MyTask implements Callable<Integer> {
    private int upperBounds;
    public MyTask(int upperBounds) {
        this.upperBounds = upperBounds;
    }
    @Override
    public Integer call() throws Exception {
        int sum = 0; 
        for(int i = 1; i <= upperBounds; i++) {
            sum += i;
        }
        return sum;
    }
}
class Test {
    public static void main(String[] args) throws Exception {
        List<Future<Integer>> list = new ArrayList<>();
        ExecutorService service = Executors.newFixedThreadPool(10);
        for(int i = 0; i < 10; i++) {
            list.add(service.submit(new MyTask((int) (Math.random() * 100))));
        }
        int sum = 0;
        for(Future<Integer> future : list) {
            // while(!future.isDone()) ;
            sum += future.get();
        }
        System.out.println(sum);
    }
}

62.同期キーワードの使用方法は?

回答:synchronizedキーワードは、オブジェクトまたはメソッドを同期済みとしてマークして、オブジェクトおよびメソッドへの相互排他アクセスを実現できます。synchronized(object){…}を使用して同期コードブロックを定義するか、メソッドを宣言するときにメソッド変更として同期を使用できますシンボル。同期キーワードの使用法は、質問60の例で示されています。

63.同期および非同期の例を挙げてください。

回答:システムに重要なリソースがある場合(リソースの数がリソースを競合するスレッドの数より少ない場合)、たとえば、書き込まれるデータが将来別のスレッドによって読み取られるか、読み取られるデータが別のスレッドによって書き込まれる可能性があります。 、次に、これらのデータに同期的にアクセスする必要があります(データベース操作の排他的ロックが最良の例です)。アプリケーションが実行に時間がかかるオブジェクトのメソッドを呼び出し、プログラムがメソッドの戻りを待たないようにする場合は、非同期プログラミングを使用する必要があります。多くの場合、非同期メソッドを使用する方が効率的です。実際、いわゆる同期とはブロッキング操作を指し、非同期とは非ブロッキング操作を指します。

64.スレッドを開始するには、run()またはstart()メソッドを呼び出しますか?

回答:スレッドを開始するには、start()メソッドを呼び出して、スレッドによって表される仮想プロセッサを実行可能な状態にします。これは、JVMによってスケジュールおよび実行できることを意味します。これは、スレッドがすぐに実行されることを意味するわけではありません。run()メソッドは、スレッドの開始後のコールバックメソッドです。

65.スレッドプールとは何ですか?

回答:オブジェクト指向のプログラミングでは、オブジェクトの作成にはメモリリソースまたはそれ以上のリソースへのアクセスが必要なため、オブジェクトの作成と破棄には時間がかかります。これは特にJavaに当てはまり、仮想マシンはすべてのオブジェクトを追跡して、オブジェクトが破棄された後にガベージを収集できるようにします。したがって、サービスプログラムの効率を向上させる1つの方法は、オブジェクトの作成と破棄の数、特にリソースを大量に消費するオブジェクトの作成と破棄の数をできるだけ減らすことです。これが「プールされたリソース」テクノロジの理由です。スレッドプールは、その名前が示すように、事前に複数の実行可能なスレッドを作成してプール(コンテナ)に配置することです。プールからスレッドを取得する必要がある場合は、作成する必要はありません。スレッドを破棄する必要はありませんが、必要なときにプールに戻す必要があります。スレッドオブジェクトを破棄するコスト。
Java 5+のExecutorインターフェースは、スレッドを実行するためのツールを定義します。そのサブタイプであるスレッドプールインターフェイスはExecutorServiceです。特にスレッドプールの原理があまり明確でない場合は、スレッドプールの構成がより複雑になります。したがって、以下に示すように、ツールクラスのExecutors側にいくつかの静的ファクトリメソッドが提供され、一般的に使用されるスレッドプールが生成されます。

  • newSingleThreadExecutor:シングルスレッドスレッドプールを作成します。このスレッドプールには1つのスレッドしか機能していません。これは、1つのスレッドがすべてのタスクを連続して実行するのと同じです。唯一のスレッドが異常終了した場合、それを置き換える新しいスレッドがあります。このスレッドプールは、すべてのタスクの実行順序がタスク送信の順序で実行されることを保証します。
  • newFixedThreadPool:固定サイズのスレッドプールを作成します。タスクが送信されるたびに、スレッドがスレッドプールの最大サイズに達するまでスレッドが作成されます。スレッドプールのサイズが最大値に達すると、サイズは変更されません。異常な実行によってスレッドが終了した場合、スレッドプールは新しいスレッドで補完されます。
  • newCachedThreadPool:キャッシュ可能なスレッドプールを作成します。スレッドプールのサイズがタスクの処理に必要なスレッドを超えると、一部のアイドルスレッド(60秒間タスクを実行しない)がリサイクルされます。タスクの数が増えると、スレッドプールは新しいスレッドをインテリジェントにプロセスタスクに追加できます。このスレッドプールは、スレッドプールのサイズを制限しません。スレッドプールのサイズは、オペレーティングシステム(またはJVM)が作成できる最大スレッドサイズに完全に依存します。
  • newScheduledThreadPool:無制限のサイズのスレッドプールを作成します。このスレッドプールは、タスクの時限的かつ定期的な実行のニーズをサポートします。
  • newSingleThreadExecutor:シングルスレッドスレッドプールを作成します。このスレッドプールは、タスクの時限的かつ定期的な実行のニーズをサポートします。
    問題60の例は、Executorsツールクラスを介してスレッドプールを作成し、スレッドプールを使用してスレッドを実行するコードを示しています。サーバーでスレッドプールを使用する場合は、パフォーマンスを向上させるために、newFixedThreadPoolメソッドを使用してスレッドプールを作成することを強くお勧めします。

    66.スレッドの基本的な状態と状態間の関係は?

    回答:
    Javaインタビューの質問の全集(7)

注:実行中は実行中の状態を意味し、実行可能は準備完了状態(すべての準備ができており、CPUのみを負っている)を意味します。ブロックはブロック状態を意味します。ブロック状態には多くの状況があります。これは、wait()メソッドが呼び出されて待機プールに入るためである可能性があります。同期メソッドまたは同期コードブロックの実行が待機ロックプールに入るか、sleep()メソッドまたはjoin()メソッドが呼び出されて、スリープまたは他のスレッドの終了を待機するか、I / O中断が発生します。

67.同期とjava.util.concurrent.locks.Lockの類似点と相違点を簡単に説明してください。

回答:ロックはJava 5の後に導入された新しいAPIです。キーワードsyncedと比較すると、主な類似点は次のとおりです。ロックは同期によって実現されるすべての機能を完了できます。主な違い:ロックは同期よりも正確なスレッドセマンティクスを備えています。パフォーマンス、およびロックの取得は必須ではありません。Synchronizedは自動的にロックを解放し、Lockはプログラマーに手動で解放するように要求する必要があり、finallyブロックで解放するのが最善です(これは外部リソースを解放するのに最適な場所です)。

68. Javaでシリアル化を実現する方法とその重要性は何ですか?

回答:シリアル化は、オブジェクトストリームを処理するためのメカニズムです。いわゆるオブジェクトストリームは、オブジェクトのコンテンツをストリーミングすることです。ストリーミングされたオブジェクトの読み取りと書き込みができます。また、ストリーミングされたオブジェクトをネットワーク間で転送することもできます。シリアル化は、オブジェクトストリームの読み取りおよび書き込み操作中に発生する可能性のある問題を解決するためのものです(シリアル化されていない場合、データの順序が乱れる可能性があります)。
シリアル化を実現するには、識別インターフェイスであるSerializableインターフェイスをクラスに実装させ、このクラスのオブジェクトをシリアル化できることをマークしてから、出力ストリームを使用してオブジェクト出力ストリームを構築し、writeObject(Object)メソッドを渡す必要があります。実装オブジェクトを書き出す(つまり、その状態を保存する)ことができます。逆シリアル化する必要がある場合は、入力ストリームを使用してオブジェクト入力ストリームを作成し、readObjectメソッドを使用してストリームからオブジェクトを読み取ることができます。オブジェクトの永続性を実現することに加えて、シリアル化はオブジェクトのディープクローニングにも使用できます(質問29を参照)。

69. Javaには何種類のストリームがありますか?

回答:バイトストリームと文字ストリーム。バイトストリームはInputStreamとOutputStreamから継承され、文字ストリームはReaderとWriterから継承されます。java.ioパッケージには、主にパフォーマンスと使いやすさを向上させるために、他にも多くのストリームがあります。Java I / Oについて注意すべき点が2つあります。1つは2つの対称性(入力と出力の対称性、バイトと文字の対称性)、もう1つは2つの設計モード(アダプターモードと装飾モード)です。さらに、JavaのフローはC#とは異なり、1つの次元と1つの方向しかありません。

インタビューの質問-ファイルコピーを実現するためのプログラミング。(このトピックは、筆記テスト中によく表示されます。次のコードは、2つの実装スキームを示しています)


import java.io.FileInputStream;
import java.io.FileOutputStream;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public final class MyUtil {
    private MyUtil() {
        throw new AssertionError();
    }
    public static void fileCopy(String source, String target) throws IOException {
        try (InputStream in = new FileInputStream(source)) {
            try (OutputStream out = new FileOutputStream(target)) {
                byte[] buffer = new byte[4096];
                int bytesToRead;
                while((bytesToRead = in.read(buffer)) != -1) {
                    out.write(buffer, 0, bytesToRead);
                }
            }
        }
    }
    public static void fileCopyNIO(String source, String target) throws IOException {
        try (FileInputStream in = new FileInputStream(source)) {
            try (FileOutputStream out = new FileOutputStream(target)) {
                FileChannel inChannel = in.getChannel();
                FileChannel outChannel = out.getChannel();
                ByteBuffer buffer = ByteBuffer.allocate(4096);
                while(inChannel.read(buffer) != -1) {
                    buffer.flip();
                    outChannel.write(buffer);
                    buffer.clear();
                }
            }
        }
    }
}

:上記ではJava 7 TWRを使用しています。TWRを使用した後、最終的に外部リソースを解放する必要がないため、コードがよりエレガントになります。

70.メソッドを記述し、ファイル名と文字列を入力して、この文字列がファイルに表示される回数を数えます。

回答:コードは次のとおりです。


import java.io.BufferedReader;
import java.io.FileReader;
public final class MyUtil {
    // 工具类中的方法都是静态方式访问的因此将构造器私有不允许创建对象(绝对好习惯)
    private MyUtil() {
        throw new AssertionError();
    }

    /**     * 统计给定文件中给定字符串的出现次数     *     * @param filename  文件名     * @param word 字符串     * @return 字符串在文件中出现的次数     */
    public static int countWordInFile(String filename, String word) {
        int counter = 0;
        try (FileReader fr = new FileReader(filename)) {
            try (BufferedReader br = new BufferedReader(fr)) {
                String line = null;
                while ((line = br.readLine()) != null) {
                    int index = -1;
                    while (line.length() >= word.length() && (index = line.indexOf(word)) >= 0) {
                        counter++;
                        line = line.substring(index + word.length());
                    }
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return counter;
    }
}

おすすめ

転載: blog.51cto.com/15061944/2593694
おすすめ