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.有解構函式