1. 程式人生 > >Java面試--容易忽略的知識點

Java面試--容易忽略的知識點

容易忽略的知識點

平行計算【詳解】

步驟:

1.將資料拆分到每個節點上【如何拆分:要保證每個節點都能獨立計算;1.將大的資料根據尺寸進行拆分 2.根據使用者首字母進行拆分】

2.每個幾點並行的計算出結果【每個節點算出什麼樣的結果,這時得到中間結果】

3.將結果彙總

例【外部排序】  如何排序10G個元素

使用擴充套件的歸併排序

歸併排序:將資料分為左右兩半,分別歸併排序,再把兩個有序資料歸併【穩定排序】

排序過程:

如何排序10G個元素

思路:

將資料進行切分,分為很多段,每一段都送到一個節點進行排序,每一段的資料量要控制到可以在記憶體中放下,每一個節點進行排序即可,這時每一個節點都會是一個有序的序列,如下圖所示:

每一個有序的序列同時送給一個歸併節點,這個歸併節點使用演算法進行歸併(不斷選各個節點最小的數),歸併完成 即可完成操作,難點在於如何進行歸併;

歸併節點實現過程:

1.使用 堆 的資料結構, 堆 :根是最小的元素

2.完成 堆 的構建

3.建立緩衝區 (歸併節點記憶體中只需要放每個資料來源中最小的元素即可,但存在問題,如將 1 拿掉之後,再將 2 讀進來需要讀一次外部儲存,這個讀取操作會很慢,效率很低,通常做法是建立緩衝區:讀取一批資料放在緩衝區,減小讀取次數)

歸併:使用  Iterable<T> 介面:

1.可以不斷獲取下一個元素

2.元素儲存/獲取方式被抽象,與歸併節點無關

3.Iterable<T> merge(List<Iterable<T>> sortedData)

歸併資料來源來自 Iterable<T> .next()

1.如果緩衝區空,讀取下一批元素放入緩衝區

2.給出緩衝區第一個元素

3.可配置項:緩衝區大小,如何讀取下一批元素

多執行緒【詳解】

典型的兩種死鎖情形:【詳解】 (一)執行緒自己將自己鎖住 一般情況下,如果同一個執行緒先後兩次呼叫lock,在第二次調⽤用時,由於鎖已經被佔用,該執行緒會掛起等待佔用鎖的執行緒釋放鎖,然而鎖正是被自己佔用著的,該執行緒又被掛起而沒有機會釋放鎖,因此 就永遠處於掛起等待狀態了,於是就形成了死鎖(Deadlock)。 (二)多執行緒搶佔鎖資源被困 又如執行緒A獲 得了鎖1,執行緒B獲得了鎖2,這時執行緒A呼叫lock試圖獲得鎖2,結果是需要掛起等待執行緒B釋放 鎖2,而這時執行緒B也呼叫lock試圖獲得鎖1,結果是需要掛起等待執行緒A釋放鎖1,於是執行緒A和B都 永遠處於掛起狀態了,死鎖再次形成。 

新增死鎖:

死鎖分析:1.在任何地方都可以執行緒切換,甚至在一句語句中間 

2.要盡力設想對自己最 不利 的情況

死鎖條件,必須同時滿足:

1.互斥等待

2.hold and wait

3.迴圈等待

4.無法剝奪的等待

死鎖防止:  

1.破除互斥等待      ---一般無法破除

2.破除hold and wait       ---一次性獲取所有資源

3.破除迴圈等待          ---按順序獲取資源

4.破除無法剝奪的等待     ---加入超時【不得已的辦法】

執行緒池【詳解】

執行緒的生命週期,執行緒的生命週期可以利用以下的圖解來更好的理解:

第一步,是用new Thread()的方法新建一個執行緒,線上程建立完成之後,執行緒就進入了就緒(Runnable)狀態,此時創建出來的執行緒進入搶佔CPU資源的狀態,當執行緒搶到了CPU的執行權之後,執行緒就進入了執行狀態(Running),當該執行緒的任務執行完成之後或者是非常態的呼叫的stop()方法之後,執行緒就進入了死亡狀態。而我們在圖解中可以看出,執行緒還具有一個則色的過程,這是怎麼回事呢?當面對以下幾種情況的時候,容易造成執行緒阻塞,第一種,當執行緒主動呼叫了sleep()方法時,執行緒會進入則阻塞狀態,除此之外,當執行緒中主動呼叫了阻塞時的IO方法時,這個方法有一個返回引數,當引數返回之前,執行緒也會進入阻塞狀態,還有一種情況,當執行緒進入正在等待某個通知時,會進入阻塞狀態。那麼,為什麼會有阻塞狀態出現呢?我們都知道,CPU的資源是十分寶貴的,所以,當執行緒正在進行某種不確定時長的任務時,Java就會收回CPU的執行權,從而合理應用CPU的資源。我們根據圖可以看出,執行緒在阻塞過程結束之後,會重新進入就緒狀態,重新搶奪CPU資源。這時候,我們可能會產生一個疑問,如何跳出阻塞過程呢?又以上幾種可能造成執行緒阻塞的情況來看,都是存在一個時間限制的,當sleep()方法的睡眠時長過去後,執行緒就自動跳出了阻塞狀態,第二種則是在返回了一個引數之後,在獲取到了等待的通知時,就自動跳出了執行緒的阻塞過程。

在一個應用程式中,我們需要多次使用執行緒,也就意味著,我們需要多次建立並銷燬執行緒。而建立並銷燬執行緒的過程勢必會消耗記憶體。而在Java中,記憶體資源是及其寶貴的,所以,我們就提出了執行緒池的概念,執行緒池的好處,就是可以方便的管理執行緒,也可以減少記憶體的消耗。

定義:預先建立好執行緒,等待任務派發

執行緒池內部:

執行緒池引數:

1.corePoolSize:執行緒池中初始執行緒數量,可能處於等待狀態

2.maximumPoolSize:執行緒池中最大允許執行緒數量

3.keepAliveTime:超出 corePoolSize 部分執行緒如果等待這些時間將被回收

執行緒池_Java Excutor Framework演示

1.執行緒池建立

2.任務派發

3.利用 Future 檢查任務結果

程式碼實現:

ExecutorTester.java

package interview.adv;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import interview.designpattern.task.CodingTask;

public class ExecutorTester {

  public static void main(String[] args)
      throws InterruptedException, ExecutionException {
    ExecutorService executor = Executors.newFixedThreadPool(3); 	//建立執行緒池

    List<Future<?>> taskResults = new LinkedList<>();
    for (int i = 0; i < 10; i++) {		//建立 10 個任務
      taskResults.add(executor.submit(new CodingTask(i)));
    }
    System.out.println("10 tasks dispatched successfully.");

    for (Future<?> taskResult : taskResults) {
      taskResult.get();
    }

    System.out.println("All tasks finished.");
    executor.shutdown();
  }
}

輸出:

資源管理

1.不被引用的物件會被回收

2.垃圾回收包括 Minor GC 和 Full GC

3.垃圾回收時所有執行暫停

Java 資源管理

1.記憶體會被回收,資源不會被釋放

2. databaseConnection 需要 databaseConnection.close() 來釋放

Java 1.7

C++ 資源管理

1.沒有 finally ,沒有 try with resourcce

2.有解構函式