Java程式員應該常思考的問題

來源:互聯網
上載者:User

Java Serial1. Java基礎問答
2. Java Generic
3. Latch VS Barrier
4. AtomicInteger, BlockingQueue and Fork/Join
5. ConcurrentHashMap, Executor, ThreadPool

Java基礎問答

1. 進程vs線程

2. JVM同步互動機制介紹

3. Synchornized死結樣本

4. 線程狀態轉換圖

5. static

a. 為什麼要有靜態變數?為什麼要有靜態方法?普通的成員變數/方法和靜態成員變數/方法含義上有什麼區別?

b. 靜態變數存在在什麼地區?靜態方法存放於什麼地區?

c. 私人靜態方法有什麼用?多線程對靜態變數有什麼影響?

d. 為什麼不推薦把對靜態變數的訪問放於synchronized 塊內?

e. 為什麼thread的sleep方法是static的?

6. final

a. final關鍵字的作用是什嗎?final關鍵字對於多線程有什麼協助,會造成什麼不良的後果?

b. 為什麼在多線程中,對final變數的取值要取兩次?

c. 利用final static組合關鍵字來代替一些枚舉類型有什麼好處?為什麼在很多項目裡面,String類型的常量或者模板被統一聲明為final static?

7. volatile

a. 為什麼 private volatile Integer i = new Integer(2); public int fun() {return i * i;} 是錯的?

b. final, volatile一起使用可以嗎?

c. happens-before法則是什嗎?它跟volatile有什麼關係

d. volatile是用來修飾變數,而不是方法, 為什麼?

e. 為什麼volatile無法代替鎖?

f. synchronized和volatile的區別是什嗎?在什麼時候可以使用volatile變數?

g. 應用volatile的一般情境可以有哪些?

8. Threadsafe

a. 一句話概括出安全執行緒的含義

b. 為了保證安全執行緒,我們需要注意什麼事情?

c. 我們可以利用哪些手段來保證安全執行緒?

d. 利用synchronized直接鎖住所有訪問,有些時候太重了,有什麼簡單的辦法可以即使用synchronized(因為它簡單),有可以大幅提高讀寫效能?

9. synchronized

a. synchronized鎖加在什麼地方?對哪些部分的訪問會被鎖住?JVM如何保證只有一個線程在訪問?鎖的資訊存放在哪裡?

b. synchronized是否可以用到變數上?

c. synchronized太重了,有什麼其他的鎖來替換?偏向鎖

d. 什麼是死結, 什麼是活鎖,如何避免死結?出現線程死結如何補救?

e. 為什麼建構函式上不能用synchronized?

10. Threadlocal

a. 為什麼多線程中使用Threadlocal生命對象可以保證安全執行緒?

b. Threadlocal如何保證key是唯一的?

c. 線程run方法裡面聲明的變數為什麼不需要使用Threadlocal來保證安全執行緒?

d. 什麼時候需要使用Threadlocal以保證安全執行緒?

11. fail-fast和fail-safe

a. 為什麼不能對java collection一邊遍曆一邊刪除?

b. 為什麼能對juc可以一邊遍曆一邊刪除?

Java generic

1. 泛型是什麼

2. 泛型的作用

3. 泛型實現原理:編譯器擦除

a. 泛型是編譯器中的概念,JVM沒有泛型這樣的概念,編譯器用擦除法實現泛型。

b. 擦除示範

c. 擦除引起的問題及解決方案(參考http://blog.csdn.net/lonelyroamer/article/details/7868820)

i. 類型擦除所帶來的多態麻煩

ii. 泛型型別變數不能是基礎資料型別 (Elementary Data Type)

iii. 異常中使用泛型的問題

iv. 不能聲明參數化型別的數組

v. 泛型型別的執行個體化

vi. 類型擦除後的衝突(比如equals方法)

d. 其它常見問題

i. 泛型中 參數化型別不考慮繼承關係

ii. 參數化型別與原始類型的相容

4. 存取原則和PECS(Producer Extends, Consumer Super)法則

a. 泛型中的”?”萬用字元

b. 泛型中的”?”萬用字元的擴充

c. PECS法則

i. 如果你想從一個資料類型裡擷取資料,使用 ? extends 萬用字元

ii. 如果你想把對象寫入一個資料結構裡,使用 ? super 萬用字元

iii. 如果你既想存,又想取,那就別用萬用字元。

5. 為什麼Java的泛型偽泛型

Latch and Barrier

1. Latch

a. latch就像一把大鎖,所有調用它的await方法的線程都會被阻塞在那裡,直到有足夠的線程調用它的countDown方法,那些被阻塞的線程才會繼續運行。

b. latch最主要的方法有兩個,一個是await,另一個是countDown。

i. 當一個線程調用await方法時,該線程會被阻塞起來。

ii. 當一個線程調用countDown方法時,該線程不會被阻塞,會繼續運行下去。

iii. latch在執行個體化的時候,需要屬於一個參數用於指明在阻塞線程被喚起之前,需要調用countDown方法的次數。

iv. latch的await還提供了一種方法await(long timeout, TimeUnit unit)用來設定線程的最大阻塞時間。如果線程阻塞時間超過這個時間設定,但countDown方法的調用次數依然沒有達到被喚醒的條件,該線程會放棄阻塞,被喚醒。

c. LatchSample.java是一個簡單的使用CountDownLatch的例子。

d. latch的執行個體化對象不可以被反覆使用,去掉上面例子中main方法中的倒數第二第三行的登出,執行代碼,可以看到當第二次使用時,列印"All end."這一句的方法並沒有在其它線程執行完了以後才被執行。

2. barrier

a. barrier類似一個同步所有線程的柵欄,它讓所有執行到特定行的線程同時等待,直到等待的線程數目達到一定的數目,所有線程再又同時開始執行。

b. 和latch不同的是,barrier是可以被反覆使用的。

c. barrier最主要的就是一個方法await。

i. 當一個線程調用await方法時,該線程會被阻塞起來。

ii. barrier執行個體化的時候,需要屬於一個參數用於指明在阻塞線程被喚起之前,需要調用await方法的次數。當await方法被調用次數達到該次數時,所有被阻塞的線程被喚醒開始運行,此時barrier對await方法調用次數的計數將重新開始。

iii. barrier在執行個體化的時候,傳入一個實現Runnable介面的對象作為喚醒所有線程前被執行的回呼函數。這個回呼函數是通過run()方法執行的,而不是start()方法,所以它不是一個和其他線程並存執行的線程,這個回呼函數的執行會阻塞其他所有被await阻塞的線程,直到這個回呼函數被執行完了之後,其他被阻塞線程才能開始執行。所以盡量不要在這個回呼函數中去執行計算時間比較長的方法。

d. BarrierSample.java是一個簡單的使用CyclicBarrier的例子。在這個例子中,CyclicBarrier的一個執行個體化對象被連續使用了三次。

e. BarrierSample2.java是一個類比三個運動員參加跑步比賽的例子。其中包含三個運動員和一個裁判。運動員從熱身開始起到最後發完獎品離開,中間有幾個特定的時間點需要等到所有的人都達到特定的狀態,例如,只有當裁判檢查完所有運動員以後才開始跑步,所有人跑完以後再進行統計成績,統計統計完畢統一發獎等。

3. Practise:有一個很大的整數list, 需要求這個list裡面的所有整數的和,實現一段充分利用多線程的代碼,要求如下:

a. 自行初始化list

b. 求和計算要利用JAVA多線程實現,要求根據一開始輸入的線程個數不同可自行調控線程個數

c. 要能輸出最後的計算結果,無論是作為返回值,或者直接輸出在console上都可以

d. 該list無法一次性load到記憶體中

AtomicIntergrer, BlockingQueue and Fork/Join

1. for(;;) {} 和 while(true) {} 的相同點和不同點在哪裡?

a. 相同點: 兩者都是在做死迴圈

b. 不同點: 前者只對應一條迴圈語句,後則需要對一個局部變數進行判斷,前者執行效率更高

2. Atomic Integer

a. 當沒有原子整數的時候,用什麼方式可以使得對同一個整型引用的多線程加減修改是安全執行緒的?--- 加鎖

b. 該做法有什麼不好的地方? ----- 容易造成死結

c. Atomic Integer 比 加鎖 要快嗎? ----- 加鎖會快很多,數值計算比較多的地方最好不要使用Atomic Integer,會影響執行效率

d. Atomic Integer適合用在類似分配唯一ID號的地方

3. BlockingQueue

a. Blocking的好處是什嗎?

可以讓線程阻塞,不佔用CPU時間,利用阻塞線程等待訊息,減少代碼複雜度,提高執行效率

b. array, linked的特點分別是什麼?

i. array內部是用固定大小的數組實現的,初始化時必須給定數組固定大小並初始化話這麼大一個數組,效率更高

ii. linked內部用鏈表實現,初始化時可不給定大小,預設大小為MAX_INT,記憶體使用量上更靈活

c. ReentrantLock, Condition, Atomic Integer (capacity)

i. ReentrantLock 通過lock和unlock方法實現加鎖解鎖

ii. Condition 類似於Object的wait和notify

iii. Atomic Integer 用於記錄隊列中元素個數,capacity 隊列最大容納元素個數

d. BlockingQueue最主要的介面

i. Take

ii. put

e. BlockingQueue的應用情境可以有哪些?

f. 謹慎封裝BlockingQueue

防止死結,儘可能通過隊列來實現訊號的傳遞

g. queue, deque, priority queue

4. Fork & Join

a. RecursiveTask -> ForkJoinTask -> Future

RecursiveAction -> ForkJoinTask -> Future

ForkJoinPool -> AbstractExecutorService

b. RecursiveTask, RecursiveAction : computer, fork, join

ForkJoinPool : submit

c. 調用

forkJoinPool = new ForkJoinPool();

Future<Object> result = forkJoinPool.submit(new RecursiveTask(...)/RecursiveAction(...));

result.get();

d. ForkJoinPool如何?自適應線程數?

通過調用 System.Runtime中的方法直接擷取核心數

ConcurrentHashmap, Executor, ThreadPool

1. ConcurrentHashMap

a. 情境

高並發讀寫,即時性要求很高,IO量大。

b. HashMap為什麼不行

寫入更新操作涉及到的步驟太多

c. 讓步

可以允許讀到稍微早一點的到期資料,但是不能讀到太久以前的到期資料

還有什麼問題不能解決的?

d. 兩級結構

Segment, HashEntry

e. 基本操作

i. get, put, remove

ii. size

2. ThreadPool

a. Executor -> ExecutorService -> AbstractExecutorService -> ThreadPoolExecutor

void execute(Runnable command);

b. Executors?

c. ThreadPoolExecutor

public ThreadPoolExecutor(int corePoolSize,

int maximumPoolSize,

long keepAliveTime,

TimeUnit unit,

BlockingQueue<Runnable> workQueue,

ThreadFactory threadFactory,

RejectedExecutionHandler handler)

corePoolSize: 線程池維護線程的最少數量

maximumPoolSize:線程池維護線程的最大數量

keepAliveTime: 線程池維護線程所允許的空閑時間

unit: 線程池維護線程所允許的空閑時間的單位

workQueue: 線程池所使用的緩衝隊列

handler: 線程池對拒絕任務的處理策略

threadFactory: ?

d. 停止線程池ThreadPoolExecutor

shutdown()

shutdownNow()

e. 執行

Worker

3. Future and FutureTask

V get() throws InterruptedException, ExecutionException;

V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;

運行逾時設定取得結果

4. 該線程池使用哪些範圍

5. 哪些地方使用該線程池不合適,使用什麼樣的方式比較合適

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.