一、數據類型
- 基本數據類型
- String
三、運算符
- 算術運算符(+、-、*、/)
- 關系運算符(==、!=、>、<、>=、<=)
- 邏輯運算符(&&、||、!)
- 位運算符(&、|、~、^)
- 移位運算符(<<、>>、>>>)
- 條件運算符/三目運算符(表達式 1 ? 表達式2 : 表達式3)
四、邏輯控制
- 順序結構
- 分支結構(if,switch)
- 循環結構(while、for、foreach、do while)
五、重載與重寫

六、抽象類和接口
- super 和 this

- 抽象類和接口的異同
相同
- 抽象類和接口都不能實例化
不同
- 構造方法:抽象類可以有構造方法;接口沒有
- 成員方法:抽象類可以是抽象的,也可以是非抽象的;(jdk1.8 之后)接口成員方法可以是 default 或者 static 開頭
- 成員變量:抽象類可以是變量也可以是常量;接口只能是常量,默認修飾符是 public static final
七、進程與線程
- 并行與并發
并行: 例如一臺電腦有 8 個 cpu,可以同時執行 8 個程序
并發: 從微觀角度看,并發是串行的,執行完當前進程,再執行下一個進程;從宏觀角度看,并發是并行的,因為每個進程執行的時間都很快,可以理解為并行。
雖然并行與并發概念并不一樣,但是一般都用并發代指并行+并發
-
用戶態和內核態
內核態:操作系統內核執行任務,一旦某個任務進入內核態執行,就變得不可控,往往意味著比較低效;
用戶態:應用程序執行任務 -
進程與線程的區別
a. 進程包含線程,一個進程可以有多個線程
b. 進程是資源分配的基本單位,線程是系統調度的基本單位。也就是說,進程得到一部分資源后,一個或者多個線程共享這部分資源
c. 進程與進程之間是相互獨立的,一個進程掛掉之后不會影響另外一個進程;但是線程不一樣,線程共享進程申請的資源,如果一個線程掛了,可能影響另外一個線程,以至于危害到整個進程
d. 進程是資源分配的最小單位,線程是調度執行的最小單位。 -
創建線程的方式
a. 繼承 Thread 類重寫 run 方法
b. 實現 Runnable 接口重寫 run 方法,實例化實現接口的類,然后將引用傳遞給 Thread 實例化對象
Runnable r2 = new Create2();
Thread c2 = new Thread(r2);
c2.start();
c. 匿名內部類,實際上還是繼承 Thread 類
Thread c3 = new Thread() {
@Override
public void run() {
System.out.println("匿名內部類創建");
}
};
c3.start();
d. lambda 表達式創建
Thread c4 = new Thread(() ->
System.out.println("lambda 表達式創建"));
c4.start();
e. Callable 接口創建
class Create5 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// Callable 泛型參數與下面返回值的類型相同
Callable<Object> callable = new Callable<Object>() {
@Override
public Integer call() throws Exception {
// doSomething
System.out.println("Callable 創建線程");
return null;
}
};
// 使用 FutureTask 把 Callable 包裹起來, 傳 task 對象給 Thread
// FutureTask 起到的作用就是 "未來能獲取到一個結果"
// 也就是 Callable 重寫方法中執行的結果
FutureTask<Object> task = new FutureTask<>(callable);
Thread thread = new Thread(task);
thread.start();
// 通過 FutureTask 的 get 方法獲取到結果
// 如果線程阻塞, 對應的線程沒有執行完, get 就等待阻塞
Integer res = (Integer) task.get();
}
}
-
Runnable 和 Callable 的區別
a. Runnable 和 Callable 中都只有一個重寫方法,Runnable 是 run 方法,Callable 是 call 方法
b. run 方法沒有返回值,不拋異常;call 方法有返回值,拋異常
c. 使用 Callable 創建線程需要使用 FutureTask 類來接受返回結果,Runnable 不用 -
Thread 和 Runnable 的區別
本質上沒有區別
a.Runnable 和 Thread 創建線程的方式不一樣
b.Runnable 是接口,Thread 是實體類,Thread 實現了 Runnable 接口
c. 如果是復雜的工作,使用 Thread,簡單的使用 Runnable -
wait 和 sleep 的區別
a. wait 使用之前需要請求鎖,也就是等待鎖釋放;sleep 無視鎖的狀態
b. wait 是 Object 的方法;sleep 是 Thread 的靜態方法 -
線程安全
首先我們要了解線程不安全的根本原因是線程的搶占式執行
保證線程安全的方法
- 保證原子性
- 內存可見性
- 禁止指令重排序
synchronized 能保證線程安全
而 volatile 不能保證原子性
- 鎖的設計
- 樂觀鎖和悲觀鎖
- 讀寫鎖
- 輕量級鎖(自旋鎖)和重量級鎖
- 公平鎖與非公平鎖
- 可重入鎖和不可重入鎖
synchronized :非公平鎖、可重入鎖、即是悲觀鎖也是樂觀鎖
- 死鎖
產生死鎖的原因
- 互斥條件:一個資源每次只能被一個進程使用
- 請求與保存條件:一個進程因請求支援而阻塞時,對已得到的資源不釋放
- 不剝奪條件:進程已獲得的資源,在使用完之前,不能強行剝奪
- 循環等待條件:若干個進程之間形成一種頭尾相接的循環等待資源關系
解決的辦法
- 不要再加鎖的代碼中嘗試獲取其他鎖
- 約定順序加鎖
-
CAS 與自旋鎖
-
JUC (Java.util.concurrent)
九、JVM
- 什么是 JVM
- JDK、JRE、JVM
- JVM 內存劃分
- JVM 的作用
- 雙親委派模型
- 垃圾回收
- 回收算法
浙公網安備 33010602011771號