更新時間:2022-12-29 11:22:48 來源:動力節點 瀏覽1253次
說道Java高級程序員面試題,網上肯定是有不少資料,但是大家找一找不難發現出問題,就是很多高級程序員面試題中都沒有答案,只有題目,所以我們還需要花費大量的時間去搜集一些帶有題目和答案的面試匯總,為了大家的方便,小編今天就匯總了一些大廠的高級面試題,大家可以進行參考:
1. Java如何開啟線程?怎么保證線程安全?
答:線程與進程的區別:進程是操作系統進行資源分配的最小單元。線程是操作系統進行任務分配的最小單元,線程隸屬于進程。
如何開啟線程?1. 繼承Thread類,重寫run方法。2. 實現Runable接口,實現run方法。3. 實現Callable接口,實現call方法。通過FutureTask創建一個線程,獲取到線程執行的返回值。4. 通過線程池來開啟線程。
怎么保證線程安全?核心思想就是加鎖:1. JVM提供的鎖,也就是Synchronized關鍵字。 2. JDK提供的各種鎖Lock.
2. Volatile和Synchronized有什么區別?Volatile能不能保證線程安全?DCL(Double Check Lock)單例為什么要加Volatile
答:1. Synchronize關鍵字,用來加鎖,Volatile只是保持亦是的線程可見性。通常適用于一個線程寫,多個線程讀的場景。
2. Volatile關鍵字不能保證線程安全,只能保證線程可見性,不能保證原子性。
3.Volatile防止指令重排,在DCL中,防上高并發情況下,指令重排造成的線程安全問題。
3.Java線程鎖機制是怎么樣的?偏向鎖、輕量級鎖、重量級鎖有什么區別?鎖機制是如何升級的?
答:1.Java的鎖就是在對象的Markword中記錄一個鎖狀態,無鎖、偏向鎖、輕量級鎖、重量級鎖對應不同的鎖狀態。
2. Java的鎖機制就是根據資源竟爭的激烈程度不斷進行鎖升級的過程。
4.談談你對AQS的理解。AQS如何實現可重入鎖?
答:1. AQS是一個Java線程同步的框架,是JDK中很多鎖工具的核心實現框架。
2. 在AQS中,維護了一個信號量state和一個線程組成的雙向鏈表隊列,其中,這個線程隊列就是用來給線程排隊的,而state就像是一個紅綠燈,用來控制線程排隊或才放行的,在不同的場景下,有不同的意義。
3.在可重入鎖這個場景下,state就用來表示加鎖的次數,0表示無鎖,每加一次鎖state就加1,釋放鎖state就減1.
5.有A、B、C三個線程,如何保證三個線程同時執行?如何在并發情況下保證三個線程依次執行?如何保證三個線程有序交錯進行?
答:CountDownLatch,CylicBarrier,Semaphore
public class ThreadSafeDemo {
public int count = 0;
public void add(){
count++;
}
public static void main(String[] args) throws InterruptedException{
int size = 3;
ThreadSafeDemo threadSafeDemo = new ThreadSafeDemo();
CountDownLatch countDownLatch = new CountDownLatch(1);
for(int i=0;i<size;i++){
new Thread(()->{
try{
countDownLatch.await();
System.out.println(System.currentTimeMillis());
Thread.sleep(100);
}catch (Exception ex){
ex.printStackTrace();
}
}).start();
}
Thread.sleep(5000);
countDownLatch.countDown();
}
}
public class OldThread2 {
static volatile int tickts = 1;
public static void main(String[] args){
Thread t1 = new Thread(()->{
while (true){
if(tickts==1){
try {
Thread.sleep(100);
for(int i=0;i<10;i++){
System.out.println("a"+i);
}
}catch (InterruptedException ie){
ie.printStackTrace();
}
tickts=2;
return;
}
}
});
Thread t2 = new Thread(()->{
while (true){
if(tickts==2){
try {
Thread.sleep(100);
for(int i=0;i<10;i++){
System.out.println("b"+i);
}
}catch (InterruptedException ie){
ie.printStackTrace();
}
tickts=3;
return;
}
}
});
Thread t3 = new Thread(()->{
while (true){
if(tickts==3){
try {
Thread.sleep(100);
for(int i=0;i<10;i++){
System.out.println("c"+i);
}
}catch (InterruptedException ie){
ie.printStackTrace();
}
tickts=1;
return;
}
}
});
t1.start();
t2.start();
t3.start();
}
}
public class OldThread {
private static Semaphore s1 = new Semaphore(1);
private static Semaphore s2 = new Semaphore(1);
private static Semaphore s3 = new Semaphore(1);
public static void main(String[] args){
try {
s1.acquire();
s2.acquire();
}catch (InterruptedException ex){
ex.printStackTrace();
}
new Thread(()->{
while (true){
try {
s1.acquire();
}catch (InterruptedException iex){
iex.printStackTrace();
}
try {
Thread.sleep(500);
}catch (InterruptedException ex2){
ex2.printStackTrace();
}
System.out.println("A");
s2.release();
}
}).start();
new Thread(()->{
while (true){
try {
s2.acquire();
}catch (InterruptedException iex){
iex.printStackTrace();
}
try {
Thread.sleep(500);
}catch (InterruptedException ex2){
ex2.printStackTrace();
}
System.out.println("B");
s3.release();
}
}).start();
new Thread(()->{
while (true){
try {
s3.acquire();
}catch (InterruptedException iex){
iex.printStackTrace();
}
try {
Thread.sleep(500);
}catch (InterruptedException ex2){
ex2.printStackTrace();
}
System.out.println("C");
s1.release();
}
}).start();
}
}
6. 如何對一個字符串快速進行排序?
答:Fork/Join框架
public class MargeTest {
private static int MAX = 100;
private static int inits[] = new int[MAX];
//隨機隊列初始化
static {
Random r = new Random();
for(int index = 0; index<MAX;index++){
inits[index-1] = r.nextInt(1000);
}
}
public static void main(String[] args) throws Exception{
long beginTime = System.currentTimeMillis();
ForkJoinPool pool = new ForkJoinPool();
MyTask task = new MyTask(inits);
ForkJoinTask<int[]> taskResult = pool.submit(task);
try {
int[] ints = taskResult.get();
System.out.println(Arrays.toString(ints));
}catch (InterruptedException ex){
ex.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println("耗時:"+(endTime-beginTime));
}
static class MyTask extends RecursiveTask<int[]>{
private int source[];
public MyTask(int source[]){
this.source = source;
}
@Override
protected int[] compute() {
int sourcelen = source.length;
if(sourcelen>2){
int midIndex = sourcelen/2;
MyTask task1 = new MyTask(Arrays.copyOf(source,midIndex));
task1.fork();
MyTask task2 = new MyTask(Arrays.copyOfRange(source,midIndex,sourcelen));
task2.fork();
int result1[] = task1.join();
int result2[] = task2.join();
int mer[] = joinInts(result1,result2);
return mer;
}else{
if(sourcelen==1 || source[0]<source[1]){
return source;
}else{
int targetTp[] = new int[sourcelen];
targetTp[0] = source[1];
targetTp[1] = source[0];
return targetTp;
}
}
}
}
}
7. TCP和UDP有什么區別?TCP為什么是三次握手,而不是兩次?
答:TCP Transfer Control Protocol 是一種面向連接的,可靠的,傳輸層通信協議。
特點:好比打電話,面向連接的,點對點的通信,高可靠的,效率比較低,占用的系統資源比較多。
UDP User Datagram Protocol 是一種無連接的,不可靠的,傳輸層通信協議。
特點:好比廣播,不需要連接,發送方不管接收方有沒有準備好,直接發消息;可以進行廣播發送。傳輸不可靠,有可能丟失消息;效率比較高,協議比較簡單,占用的系統資源比較少。
TCP建立連接三次握手,斷開連接四次揮手。如果是兩次握手,可能造成連接資源浪費的情況。
8. Java有哪幾種IO模型?有什么區別?
答:
BIO 同步阻塞IO。可靠性差,吞吐量低,適用于連接比較少且比較固定的場景。JDK1.4之前唯一的選擇。編程模型最簡單。
NIO 同步非阻塞IO。可靠性比較好,吞吐量比較高,適用于連接比較多,并且連接比較短(輕操作),例如聊天室,編程模型最復雜。
AIO 異步非阻塞IO。可靠性是最好的,吞吐量也是非常高的,適用于連接比較多,并且連接比較長(重操作)。例如相冊服務器。視頻流點播等,JDK1.7版本之后提供的。編程模型比較簡單,需要操作系統來支持。
同步、異步【針對請求】和阻塞、非阻塞【針對客戶端】
在一個網絡請求中,客戶端會發一個請求到服務端。
1. 客戶端發了請求后,就一直等著服務端響應。客戶端: 阻塞。 請求:同步
2. 客戶端發了請求后,就去干別的事情了,時不時過來檢查服務端是否給出了相應。客戶端:非阻塞。請求:同步。
3. 換成異步請求。 客戶端發了請求后,就坐在椅子上,等著服務端返回響應。客戶端:阻塞。 請求:異步。
4. 客戶端發了請求后,就去干別的事情了。等到服務端給出響應后,再過來處理業務邏輯。 客戶端: 非阻塞。請求:異步。
以上就是“Java高級程序員面試題,內含解析答案”,你能回答上來嗎?如果想要了解更多的Java面試題相關內容,可以關注動力節點Java官網。
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習