ジャワの50点の分析は、面接の質問と回答をスレッド

次はあなたが面接の準備をするために使用することができ、一般的なJavaスレッド関連の面接の質問です。

1)スレッドとは何ですか?
スレッド、プロセス、単位工程の実際の動作に含まれる動作スケジュール、可能なオペレーティングシステムの最小単位です。プログラマは、あなたは、計算集約型の作業を加速するために、複数のスレッドを使用することができ、マルチプロセッサのプログラミングのためにそれを使用することができます。たとえば、スレッドが10個のスレッドでタスクを完了するために100ミリ秒、その後、わずか10ミリ秒とするタスクを完了する場合。Java言語レベルでは、それはまた、良好なセールスポイントである、複数のスレッドのための優れたサポートを提供します。

2)スレッドとプロセスの違いは何ですか?
スレッドは、プロセスが異なるタスクを実行するために、並行して各スレッドをスレッドの多くを有することができ、プロセスのサブセットです。異なる別のメモリ空間を使用するプロセス、およびすべてのスレッドが同じメモリ空間を共有しています。各スレッドは、ローカルデータを格納するために使用される別のスタックメモリを持って、それを混同してメモリを積み重ねないでください。

3)どのようにJavaでスレッドを達成するには?
3.1スレッドの作成にThreadクラスを継承
3.2は、スレッドを作成するために、Runnableインタフェースを実装
3.3は、スレッドラッパーFutureTaskでスレッドを作成するために、呼び出し可能インターフェースを実装して
今後はそのリターン結果スレッドを達成するため、3.4 ExecutorServiceの、呼び出し可能

4)Runnableをまたはスレッドに?
問題のフォローアップの質問ですが、私たちはすべて我々がThreadクラスや、Runnableインタフェースを継承することができることを知っているが、スレッドを実装するために呼び出して、問題は方法が優れていること、ありますか?どのような状況下でそれを使用するには?あなたはJavaは多重継承クラスをサポートしていない知っていれば、この質問は答えるのは簡単ですが、複数のインタフェースを呼び出すことができます。あなたが他のクラスから継承したいのであれば、当然のことながら、より良い、Runnableインタフェースを呼び出すことです。

Runnableを簡単に共有するためのリソースは、リソースが複数のスレッドを同時に処理することができます。

5)Threadクラス開始()とrun()メソッドの違いは何ですか?
この質問はよく聞かが、それでもJavaのスレッドモデルの面接の理解から区別することができます。start()メソッドは、新しいスレッドが作成されて開始するために使用され、スタートは()内部でrun()メソッドを呼び出し、この効果は直接実行()メソッドの呼び出しが同じではありません。あなたはrun()メソッドは、のみ元のスレッドで実行するために呼び出されるコールすると、新しいスレッドが新しいスレッドを開始します()メソッドを起動し、開始されません。

6)JavaはRunnableを、呼び出し可能に違いは何ですか?
実行可能と異なるスレッドで実行されるこれらのタスクの代わりに呼び出し可能。当初からのRunnableがJDK1.0、JDK1.5で呼び出し可能に増加しました。主な違いは、Callableを呼び出し()メソッドは値を返し、例外をスローしますが、Runnableをrun()メソッドは、これらの機能を持っていないです。呼び出し可能な未来のオブジェクトは、計算結果をロードし戻してもよいです。

7)どのように強制するためには、スレッドを開始しますか?
この問題は、Javaのガベージコレクションを強制的にどのように、そこにあなたがにSystem.gc()を使用することができますが、ガベージコレクションを実行するそのような方法ではありませんが、成功を保証するものではありませんのようなものです。Javaではスレッドを開始することを強制する方法はありません、それはスレッドスケジューラのコントロールであるとJavaは、関連するAPIを開示することはありませんでした。

8)CyclicBarrierをしてたCountDownLatchにおけるJavaの違いは何ですか?
CyclicBarrierをしてたCountDownLatchは、他のスレッドを待っているスレッドのセットを作るために使用することができます。違いはCyclicBarrierをして、されたCountDownLatchを再利用することができないということです。

何9)は、Javaメモリモデル?

10)Javaの中の揮発性の変数は何ですか?
揮発性は、特別な修飾子、それを使用するための唯一のメンバ変数です。同期クラスが欠落していたJava並行プログラムの場合は、マルチスレッド操作部材の変数は、他のスレッドに対して透過的です。volatile変数の下で、前の書き込み操作がvolatile変数の問いに支配した後に読み出し動作が行われます保証することができます。より揮発性の内容を表示するにはここをクリックしてください。

https://www.cnblogs.com/linjiqin/p/3212737.html

11)スレッドセーフとは何ですか?ベクターは、スレッドセーフなクラスが行うのですか?
プロセスが同時に実行されている複数のスレッドを持っており、これらのスレッドが同時にこのコードを実行することができ、あなたのコードの場合。それぞれの結果はシングルスレッド業績と同じ、また、他の変数の値を実行し、期待が同じである場合、それは、スレッドセーフです。スレッドセーフなカウンタオブジェクトクラスの同じインスタンスしません複数のスレッドを使用する場合に計算間違い。もちろん、あなたは二つのグループ、スレッドセーフと非スレッドセーフにコレクションクラスをすることができます。ベクターは、スレッドセーフ達成するための方法を同期しているが、これと同様のArrayListのはスレッドセーフではありません。

12)Javaは競合状態とは何ですか?例を説明します。
競合状態は並行処理のプログラムでいくつかのバグを引き起こす可能性があります。いくつかのリソースをマルチスレッド化プログラムは、後で実行排出される最初の大会の実行に失敗した場合、そこ全体のプログラムはバグいくつかの不確実になり、競争とき競合状態を持っています。これはバグを見つけるのは困難で、スレッド間のランダムな競争ので、繰り返されます。

13)どのようにJavaでスレッドを停止するには?
Java APIは、非常に豊富に提供していますが、スレッドを停止するためのAPIを提供していませんでした。JDK 1.0は、停止()、(一時停止)と)(コントロールの方法を再開しますが、ためのJava APIの設計後の潜在的な脅威、したがって、彼らが放棄されているJDKの後続バージョンでデッドロックの提供しないようなものだっただろうスレッドを停止するために互換性があり、スレッドセーフな方法。スレッドの実行、実行()または()メソッドの呼び出しが自動的に終了します場合は、手動でスレッドを終了させたい場合、あなたはリサイクルのrun()メソッドを終了するか、スレッドを中断するタスクをキャンセルする揮発性のブール変数を使用することができます。

14)の実行時にスレッド例外が発生しますか?
例外は、スレッドが実行を停止しますキャッチされていない場合、これは、簡単に言えば、私が遭遇した就職の面接では非常にトリッキーなJavaのインタビューの質問、です。スレッドラインインターフェイスの突然の中断によって引き起こさキャッチされない例外を処理するためのThread.UncaughtExceptionHandler。ときにキャッチされない例外は、破壊JVMスレッドはスレッドとスレッド処理のためのuncaughtExceptionハンドラ()メソッドにパラメータとして渡されたuncaughtExceptionHandler異常を照会するThread.getUncaughtExceptionHandler()を使用する原因となります。

15) 如何在两个线程间共享数据?
实现Runnable接口创建线程,如:
public static void main(String[] args) {
Runnable runnable = new MyRunnable();
new Thread(runnable).start();
new Thread(runnable).start();
new Thread(runnable).start();
new Thread(runnable).start();
}

16) Java中notify 和 notifyAll有什么区别?
这又是一个刁钻的问题,因为多线程可以等待单监控锁,Java API 的设计人员提供了一些方法当等待条件改变的时候通知它们,但是这些方法没有完全实现。notify()方法不能唤醒某个具体的线程,所以只有一个线程在等待的时候它才有用武之地。而notifyAll()唤醒所有线程并允许他们争夺锁确保了至少有一个线程能继续运行。

18) 什么是ThreadLocal变量?
线程范围内的共享变量,每个线程只能访问他自己的,不能访问别的线程。

19) 什么是FutureTask?
在Java并发程序中FutureTask表示一个可以取消的异步运算。它有启动和取消运算、查询运算是否完成和取回运算结果等方法。只有当运算完成的时候结果才能取回,如果运算尚未完成get方法将会阻塞。一个FutureTask对象可以对调用了Callable和Runnable的对象进行包装,由于FutureTask也是调用了Runnable接口所以它可以提交给Executor来执行。

20) Java中interrupted 和 isInterruptedd方法的区别?
interrupted() 和 isInterrupted()的主要区别是前者会将中断状态清除而后者不会。Java多线程的中断机制是用内部标识来实现的,调用Thread.interrupt()来中断一个线程就会设置中断标识为true。当中断线程调用静态方法Thread.interrupted()来检查中断状态时,中断状态会被清零。而非静态方法isInterrupted()用来查询其它线程的中断状态且不会改变中断状态标识。简单的说就是任何抛出InterruptedException异常的方法都会将中断状态清零。无论如何,一个线程的中断状态有有可能被其它线程调用中断来改变。

21) 为什么wait和notify方法要在同步块中调用?
主要是因为Java API强制要求这样做,如果你不这么做,你的代码会抛出IllegalMonitorStateException异常。还有一个原因是为了避免wait和notify之间产生竞态条件。

23) Java中的同步集合与并发集合有什么区别?

同步集合与并发集合都为多线程和并发提供了合适的线程安全的集合,不过并发集合的可扩展性更高。在Java1.5之前程序员们只有同步集合来用且在多线程并发的时候会导致争用,阻碍了系统的扩展性。Java5介绍了并发集合像HashMap,不仅提供线程安全还用锁分离和内部分区等现代技术提高了可扩展性。

24) Java中堆和栈有什么不同?
为什么把这个问题归类在多线程和并发面试题里?因为栈是一块和线程紧密相关的内存区域。每个线程都有自己的栈内存,用于存储本地变量,方法参数和栈调用,一个线程中存储的变量对其它线程是不可见的。而堆是所有线程共享的一片公用内存区域。对象都在堆里创建,为了提升效率线程会从堆中弄一个缓存到自己的栈,如果多个线程使用该变量就可能引发问题,这时volatile 变量就可以发挥作用了,它要求线程从主存中读取变量的值。

(1)存放内容不同:
栈内存:用来存放基本数据类型变量和引用类型变量。
堆内存:用来存放运行时通过new关键字创建的对象。

(2)生命周期不同:
栈的生命周期与线程相同,随线程而生,随线程而亡,是线程私有的。
堆的生命周期与JVM相同,JVM启动时创建,JVM停止时销毁,是线程共享的。

25)什么是线程池? 为什么要使用它?
创建线程要花费昂贵的资源和时间,如果任务来了才创建线程那么响应时间会变长,而且一个进程能创建的线程数有限。为了避免这些问题,在程序启动的时候就创建若干线程来响应处理,它们被称为线程池,里面的线程叫工作线程。

缓存线程池(可变尺寸的线程池)、固定大小的线程池、调度线程池、单例线程池、自定义线程池

26)如何写代码来解决生产者消费者问题?
在现实中你解决的许多线程问题都属于生产者消费者模型,就是一个线程生产任务供其它线程进行消费,你必须知道怎么进行线程间通信来解决这个问题。比较低级的办法是用wait和notify来解决这个问题,比较赞的办法是用Semaphore 或者 BlockingQueue来实现生产者消费者模型,这篇教程有实现它。

用wait和notify实现
用Semaphore信号量实现
BlockingQueue/ConcurrentLinkedQueue

29) 怎么检测一个线程是否拥有锁?
我一直不知道我们竟然可以检测一个线程是否拥有锁,直到我参加了一次电话面试。在java.lang.Thread中有一个方法叫holdsLock(),它返回true如果当且仅当当前线程拥有某个具体对象的锁。

30) 你如何在Java中获取线程堆栈?
对于不同的操作系统,有多种方法来获得Java进程的线程堆栈。当你获取线程堆栈时,JVM会把所有线程的状态存到日志文件或者输出到控制台。在Windows你可以使用Ctrl + Break组合键来获取线程堆栈,Linux下用kill -3命令。你也可以用jstack这个工具来获取,它对线程id进行操作,你可以用jps这个工具找到id。

31) JVM中哪个参数是用来控制线程的栈堆栈小的
这个问题很简单, -Xss参数用来控制线程的堆栈大小。你可以查看JVM配置列表来了解这个参数的更多信息。

32) Java中synchronized 和 ReentrantLock 有什么不同?
Java在过去很长一段时间只能通过synchronized关键字来实现互斥,它有一些缺点。比如你不能扩展锁之外的方法或者块边界,尝试获取锁时不能中途取消等。
Java 5 通过Lock接口提供了更复杂的控制来解决这些问题。 ReentrantLock 类实现了 Lock,它拥有与 synchronized 相同的并发性和内存语义且它还具有可扩展性。

33) 有三个线程T1,T2,T3,怎么确保它们按顺序执行?
在多线程中有多种方法让线程按特定顺序执行,你可以用线程类的join()方法在一个线程中启动另一个线程,另外一个线程完成该线程继续执行。为了确保三个线程的顺序你应该先启动最后一个(T3调用T2,T2调用T1),这样T1就会先完成而T3最后完成。

35) Java中ConcurrentHashMap的并发度是什么?
ConcurrentHashMap把实际map划分成若干部分来实现它的可扩展性和线程安全。这种划分是使用并发度获得的,它是ConcurrentHashMap类构造函数的一个可选参数,默认值为16,这样在多线程情况下就能避免争用。

36) Java中Semaphore是什么?
Java中的Semaphore是一种新的同步类,它是一个计数信号。从概念上讲,从概念上讲,信号量维护了一个许可集合。如有必要,在许可可用前会阻塞每一个 acquire(),然后再获取该许可。每个 release()添加一个许可,从而可能释放一个正在阻塞的获取者。但是,不使用实际的许可对象,Semaphore只对可用许可的号码进行计数,并采取相应的行动。


37)如果你提交任务时,线程池队列已满。会时发会生什么?

这个问题问得很狡猾,许多程序员会认为该任务会阻塞直到线程池队列有空位。事实上如果一个任务不能被调度执行那么ThreadPoolExecutor’s submit()方法将会抛出一个RejectedExecutionException异常。

38) Java线程池中submit() 和 execute()方法有什么区别?

两个方法都可以向线程池提交任务,execute()方法的返回类型是void,它定义在Executor接口中, 而submit()方法可以返回持有计算结果的Future对象,它定义在ExecutorService接口中,它扩展了Executor接口,其它线程池类像ThreadPoolExecutor和ScheduledThreadPoolExecutor都有这些方法。

39) 什么是阻塞式方法?

阻塞式方法是指程序会一直等待该方法完成期间不做其他事情,ServerSocket的accept()方法就是一直等待客户端连接。这里的阻塞是指调用结果返回之前,当前线程会被挂起,直到得到结果之后才会返回。此外,还有异步和非阻塞式方法在任务完成前就返回。

44) Java中的ReadWriteLock是什么?
一般而言,读写锁是用来提升并发程序性能的锁分离技术的成果。Java中的ReadWriteLock是Java 5 中新增的一个接口,一个ReadWriteLock维护一对关联的锁,一个用于只读操作一个用于写。在没有写线程的情况下一个读锁可能会同时被多个读线程持有。写锁是独占的,你可以使用JDK中的ReentrantReadWriteLock来实现这个规则,它最多支持65535个写锁和65535个读锁。

46)volatile 变量和 atomic 变量有什么不同?
这是个有趣的问题。首先,volatile 变量和 atomic 变量看起来很像,但功能却不一样。Volatile变量可以确保先行关系,即写操作会发生在后续的读操作之前, 但它并不能保证原子性。例如用volatile修饰count变量那么 count++ 操作就不是原子性的。而AtomicInteger类提供的atomic方法可以让这种操作具有原子性如getAndIncrement()方法会原子性的进行增量操作把当前值加一,其它数据类型和引用变量也可以进行相似操作。

47) 如果同步块内的线程抛出异常会发生什么?

这个问题坑了很多Java程序员,若你能想到锁是否释放这条线索来回答还有点希望答对。无论你的同步块是正常还是异常退出的,里面的线程都会释放锁,所以对比锁接口我更喜欢同步块,因为它不用我花费精力去释放锁,该功能可以在finally block里释放锁实现。

おすすめ

転載: www.cnblogs.com/linjiqin/p/11315694.html