1. 程式人生 > >java面試題答案

java面試題答案

前言 這個是我自己看的面試題,如果解答有問題,請指教

就是這個部落格提到面試題

面試題

  1. 作業系統中 heap 和 stack 的區別
堆的特點是類似於排隊:先進先出,後進後出,類似於商場排隊,使用於java的資料的儲存階段,用於儲存java 建立的變數
棧的特點是:先進後出,後進先出,類似像箱子裡面放書,拿出來的過程,棧使用於java程式的執行階段
  1. 什麼是基於註解的切面實現
切面的實現實際上說的aop的思想,這裡我介紹spring aspactJ aop實現方式:

aop用於記錄事件方法 前置方法(before),後置方法(aftert),異常方法(afterThrows),返回方法(afterReturn),環繞方法(around)
aop 有些概念 切面,切點(一般指要記錄的方法)之類的東西

  1. 什麼是 Java 的反射機制
java 特有的在程式執行期間獲取 類的欄位,方法,執行類的方法,新增類的屬性的特性稱為 java類的反射機制
  1. 什麼是 ACID
acid值得事物的特性:
A:原子性: 一個事物要麼發生,要不發生發生回滾,事物是一個整體,不可分離
C:一致性: 存在事物的2個或者多個事件,必須同時改變事物發生之前的狀態或者是改變到事物發生之後的狀態
B:隔離性:
2. spring七個事務傳播屬性:
1.PROPAGATION_REQUIRED – 支援當前事務,如果當前沒有事務,就新建一個事務。這是最常見的選擇。

2.PROPAGATION_SUPPORTS – 支援當前事務,如果當前沒有事務,就以非事務方式執行。

3.PROPAGATION_MANDATORY – 支援當前事務,如果當前沒有事務,就丟擲異常。

4.PROPAGATION_REQUIRES_NEW – 新建事務,如果當前存在事務,把當前事務掛起。

5.PROPAGATION_NOT_SUPPORTED – 以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。

6.PROPAGATION_NEVER – 以非事務方式執行,如果當前存在事務,則丟擲異常。

7.PROPAGATION_NESTED – 如果當前存在事務,則在巢狀事務內執行。如果當前沒有事務,則進行與PROPAGATION_REQUIRED類似的操作。

備註:常用的兩個事務傳播屬性是1和4,即PROPAGATION_REQUIRED,PROPAGATION_REQUIRES_NEW

3. 五個隔離級別:
ISOLATION_DEFAULT 
這是一個PlatfromTransactionManager預設的隔離級別,使用資料庫預設的事務隔離級別.

另外四個與JDBC的隔離級別相對應;

ISOLATION_READ_UNCOMMITTED 
這是事務最低的隔離級別,它充許別外一個事務可以看到這個事務未提交的資料。 
這種隔離級別會產生髒讀,不可重複讀和幻像讀。

ISOLATION_READ_COMMITTED 
保證一個事務修改的資料提交後才能被另外一個事務讀取。另外一個事務不能讀取該事務未提交的資料。 
這種事務隔離級別可以避免髒讀出現,但是可能會出現不可重複讀和幻像讀。

ISOLATION_REPEATABLE_READ 
這種事務隔離級別可以防止髒讀,不可重複讀。但是可能出現幻像讀。 
它除了保證一個事務不能讀取另一個事務未提交的資料外,還保證了避免下面的情況產生(不可重複讀)。

ISOLATION_SERIALIZABLE 
這是花費最高代價但是最可靠的事務隔離級別。事務被處理為順序執行。 
除了防止髒讀,不可重複讀外,還避免了幻像讀。

關鍵詞: 
Ø  髒讀:一個事務讀取了另一個未提交的並行事務寫的資料。

Ø  不可重複讀:一個事務重新讀取前面讀取過的資料, 發現該資料已經被另一個已提交的事務修改過。

Ø  幻讀:一個事務重新執行一個查詢,返回一套符合查詢條件的行, 發現這些行因為其他最近提交的事務而發生了改變。

髒讀:指一個事務讀取了一個未提交事務的資料

不可重複讀:在一個事務內讀取表中的某一行資料,多次讀取結果不同.一個事務讀取到了另一個事務提交後的資料.

虛讀(幻讀):在一個事務內讀取了別的事務插入的資料,導致前後讀取不一致(insert)

D:永續性:事物提交以後,資料的改變應該是永續性

7、Cookie 和 Session 的區別

Cookie 指的是對系統的一次請求將請求的內容快取在瀏覽器,在瀏覽器為關閉之前都可以在任意頁面都可以訪問到這個物件
Session 是瀏覽器和伺服器之間的互動,系統將資料快取在伺服器端的物件

8、get 和 post請求的區別

傳輸的資料量:get傳輸的資料量是有限的,post傳輸的資料量是無限的
安全性:get傳遞的引數是明文傳輸不安全,post可以傳遞http包中所以安全性高一些
功能上:post 執行的請求一般為跟新操作,get執行的請求型別一般為獲取資料的操作

9、 finalize() 方法的使用

在這裡插入程式碼片

1、final關鍵字有哪些用法

  • 使用在欄位上面 fina static Stirng name 說明name這個變數不可以改變了,屬於常量
  • 使用在方法上說明這個方法不能被其他類繼承
  • 使用在類上說明這個類不能被繼承

2、final 與 static 關鍵字可以用於哪裡?它們的作用是什麼

1.static 可以用在類的成員變數上面,也可以用在方法上面,static修飾的成員變數和方法可以通過類直接訪問,而不是建立物件才能訪問,static修飾的變數建立所有物件都能訪問得到
2.static修飾的方法裡面不可以訪問非static修飾的變數
3.單類中有些資料只需載入一次那麼可以放在static{}裡面
例如:
class Person{
    private Date birthDate;
    private static Date startDate,endDate;
    static{
        startDate = Date.valueOf("1946");
        endDate = Date.valueOf("1964");
	     Date startDate = Date.valueOf("1946");//對比與這樣建立的方式
        Date endDate = Date.valueOf("1964");//
    }
     
    public Person(Date birthDate) {
        this.birthDate = birthDate;
    }
     
    boolean isBornBoomer() {
        return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0;
    }
}

這樣建立的效率更高一些
4. static 和 構造方法執行先後的問題
   執行的時候 static{} 程式碼塊是在類載入的時候就執行,所以先執行類的static{},然後再執行構造方法
   執行方法的時候 先執行父類的static和構造方法再執行子類的static模組和構造方法
   public class Test {
    Person person = new Person("Test");
    static{
        System.out.println("test static");
    }
     
    public Test() {
        System.out.println("test constructor");
    }
     
    public static void main(String[] args) {
        new MyClass();
    }
}
 
class Person{
    static{
        System.out.println("person static");
    }
    public Person(String str) {
        System.out.println("person "+str);
    }
}
 
 
class MyClass extends Test {
    Person person = new Person("MyClass");
    static{
        System.out.println("myclass static");
    }
     
    public MyClass() {
        System.out.println("myclass constructor");
    }
}

執行次序:
test static
myclass static
person static
person Test
test constructor
person MyClass
myclass constructor

3、final, finally, finalize的區別

finally 一般用在 try{}catch(Exception e){}finally{} 這裡面的finally指的是無論是否捕獲到異常我們都執行finally裡面的內容

4、final、finalize 和 finally 的不同之處?

5、能否在執行時向 static final 型別的賦值

不能

6、使用final關鍵字修飾一個變數時,是引用不能變,還是引用的物件不能變

7、一個類被宣告為final型別,表示了什麼意思

8、throws, throw, try, catch, finally分別代表什麼意義

throws 使用在方法的頭中用於丟擲各種異常 public void test() throws Exception{}

throws 使用在方法的程式碼之中例如
if(money<1000){
 throw new Exception("貨幣金額不足");
}

try{
// 可能出現異常的程式碼
}catch(Exception e){
// 捕獲到的異常資訊
}finally{
// 最終要執行的程式碼無論有無捕獲到異常資訊
}

1、switch 語句中的表示式可以是什麼型別資料

byte ,short ,int char,String (必須是jdk1.7),列舉型別

2、switch 是否能作用在byte 上,是否能作用在long 上,是否能作用在String上

不能 long的範圍大於int了,switch原則上只能使用int 

3、while 迴圈和 do 迴圈有什麼不同

while 滿足條件的時候迴圈體執行,do先執行迴圈體,再判斷條件

1、&操作符和&&操作符有什麼區別?

& 表示且  表示式1&表示式2  當表示式滿足條件時 就不判斷了,&& 都會判斷

2、a = a + b 與 a += b 的區別?

如果限制了 a和b為同一種資料型別 例如 byte,int限制無區別,java 中的5 預設為int型別,如果a型別byte型別則會報錯 a+=b卻不會

3、邏輯操作符 (&,|,^)與條件操作符(&&,||)的區別

4、3*0.1 == 0.3 將會返回什麼?true 還是 false?

false

5、float f=3.4; 是否正確?

不正確 3.4 為double 型別

6、short s1 = 1; s1 = s1 + 1;有什麼錯?

跟2一個錯誤

1、基礎型別(Primitives)與封裝型別(Wrappers)的區別在哪裡

2、簡述九種基本資料型別的大小,以及他們的封裝類

型別   大小       分裝類 預設值

byte -128 ~127 Integer 0 
short 2^-16 ~ 2^16-1 Short 0
int 2^-32 ~ 2^32-1 Integer 0 
Long 2^-64~ 2^64-1 Ingeter

浮點型 :
float 2^-32 ~ 2^32 -1 Float 0.0
double 2^-64 ~ 2^64-1 Double 0.0

布林型別:
boolean  2^-8 ~ 128 Boolean false

字元型別:
char 2^-64 ~ 2^64-1 Character 空

3、int 和 Integer 哪個會佔用更多的記憶體? int 和 Integer 有什麼區別?parseInt()函式在什麼時候使用到

4、float和double的預設值是多少
0.0,0.0

5、如何去小數四捨五入保留小數點後兩位

6、char 型變數中能不能存貯一箇中文漢字,為什麼

能,一個漢字佔2個位元組,char的範圍大於位元組儲存數所以可以儲存漢字

1、怎樣將 bytes 轉換為 long 型別

直接轉就可以了,
byte a =4;

long b =(long)a

2、怎麼將 byte 轉換為 String

byte num = 3;
String.valueOf(num)

3、如何將數值型字元轉換為數字

String a = "123";

int b = Integer.Intparse(a);

4、我們能將 int 強制轉換為 byte 型別的變數嗎?如果該值大於 byte 型別的範圍,將會出現什麼現象

可以,byte只能儲存到127 ,當int 數值大於127時,那麼就會丟失精度,存進去的最大值為127

5、能在不進行強制轉換的情況下將一個 double 值賦值給 long 型別的變數嗎

不行,有小數,只能通過強制型別轉換,並且丟失精度

1、如何權衡是使用無序的陣列還是有序的陣列

在這裡插入程式碼片

2、怎麼判斷陣列是 null 還是為空

3、怎麼列印陣列? 怎樣列印陣列中的重複元素

Arrays.asList(陣列)
遍歷陣列當元素出現2次以上打印出來
程式碼:
/**  

* <p>Title: ArrayTest.java</p>  

* <p>Description: </p>  

* <p>Copyright: Copyright (c) 2017</p>  

* <p>Company:kehui</p>  

* @author jiangcl 

* @date 2018年10月13日  

* @version 1.0  

*/  
package com.mvc.test;

import java.util.HashMap;
import java.util.Map;

/**  

 * <p>Title: ArrayTest</p>  

 * <p>Description: </p>  

 * @author jiangcl 

 * @date 2018年10月13日  

 */
public class ArrayTest {
	
	
	public static void main(String[] args) {
		
		
		String[] arr = new String[]{"jiang","jiang","test","ooo","test","pppp"};
		
		Map<String,Integer> map = new HashMap<String,Integer>();
		
		for(int i = 0 ;i<arr.length;i++){
			
			int appNum = 0;
			for(int j = 0;j<arr.length;j++){
				
				if(arr[i].equals(arr[j])){
					appNum++;
				}
				
			}
			
			if(appNum>=2){
				map.put(arr[i], appNum);
			}
			
		}
		System.out.println(map.toString());
		
		
	}

}

4、Array 和 ArrayList有什麼區別?什麼時候應該使用Array而不是ArrayList

5、陣列和連結串列資料結構描述,各自的時間複雜度

陣列:按照順序進行資料的儲存,在記憶體中是連續排列的,當查詢的時候根據陣列的下標,進行查詢,刪除或者插入的時候需要重新移動下標,將資料重新儲存一遍,所以陣列的查詢速度快而刪除和插入較慢
連結串列:連結串列的儲存是不連續的,一個節點上儲存著本節點的資料和下一個節點的記憶體地址,在查詢時需要將每個節點都查詢一遍以獲取下一個節點的資料,所以查詢資料慢,刪除和插入的時候,將節點刪除不影響節點資料結構所以刪除和插入較快,但是查詢較慢

陣列利用下標定位,時間複雜度為O(1),連結串列定位元素時間複雜度O(n); 
陣列插入或刪除元素的時間複雜度O(n),連結串列的時間複雜度O(1)

6、陣列有沒有length()這個方法? String有沒有length()這個方法

沒有,有

1、佇列和棧是什麼,列出它們的區別

2、BlockingQueue是什麼

3、簡述 ConcurrentLinkedQueue LinkedBlockingQueue 的用處和不同之處。

4、ArrayList、Vector、LinkedList 的儲存效能和特性?

ArrayList 查詢資料快,刪除,插入速度慢,底層基於陣列的方式
Vector 查詢速度較ArrayList 慢一些,vector裡面大量方法使用了,同步程式碼塊欄位,所以執行緒安全
LinkedList 插入和刪除的速度較快,查詢速度較慢,底層基於連結串列的結構

5、String 和 StringBuffer,StringBuilder 的區別?

StringBuffer 是執行緒安全的,但是字串的拼接效率低於StringBuilder ,
StringBuffer 的執行緒安全是通過synchronized  實現的

6、ByteBuffer 與 StringBuffer 有什麼區別?

1、HashMap的工作原理是什麼

https://www.cnblogs.com/chengxiao/p/6059914.html

2、HashMap內部的資料結構是什麼

HashMap 底層是由陣列和連結串列實現的,hashMap的主幹實際上是一個entry陣列,裡面存放key-value的資料

3、HashMap 的 table的容量如何確定?loadFactor 是什麼? 該容量如何變化?這種變化會帶來什麼問題?

4、HashMap 實現的資料結構是什麼?如何實現

5、HashMap 和 HashTable、ConcurrentHashMap 的區別

HashMap 執行緒不安全,但是查詢,刪除,插入的效率較HashTable較高,
HashTable執行緒安全,
ConcurrentHashMap

6、HashMap的遍歷方式及效率

	for(Map.Entry<String, String> entry:map.entrySet()){
			
			System.out.println(entry.getKey()+entry.getValue());
			
		}
		

7、HashMap、LinkedMap、TreeMap的區別

linkedMap 會保持資料插入的順序,但是查詢速度較慢
TreeMap 會給資料自動排序

8、如何決定選用HashMap還是TreeMap

9、如果HashMap的大小超過了負載因子(load factor)定義的容量,怎麼辦

增加2倍的容量

10、HashMap 是執行緒安全的嗎?併發下使用的 Map 是什麼,它們內部原理分別是什麼,比如儲存方式、 hashcode、擴容、 預設容量等

1、HashSet和TreeSet有什麼區別

2、HashSet 內部是如何工作的

3、WeakHashMap 是怎麼工作的?

1、Set 裡的元素是不能重複的,那麼用什麼方法來區分重複與否呢?是用 == 還是 equals()? 它們有何區別?

當資料為基本資料型別的時候,我們比較內容 使用的equal方法的方式進行比較
當資料為引用型別時候,我們比較記憶體地址

2、TreeMap:TreeMap 是採用什麼樹實現的?TreeMap、HashMap、LindedHashMap的區別。TreeMap和TreeSet在排序時如何比較元素?Collections工具類中的sort()方法如何比較元素?

3、TreeSet:一個已經構建好的 TreeSet,怎麼完成倒排序。

4、EnumSet 是什麼

1、Hashcode 的作用

hashcode是記憶體地址

2、簡述一致性 Hash 演算法

3、有沒有可能 兩個不相等的物件有相同的 hashcode?當兩個物件 hashcode 相同怎麼辦?如何獲取值物件

4、為什麼在重寫 equals 方法的時候需要重寫 hashCode 方法?equals與 hashCode 的異同點在哪裡

5、a.hashCode() 有什麼用?與 a.equals(b) 有什麼關係

6、hashCode() 和 equals() 方法的重要性體現在什麼地方

7、Object:Object有哪些公用方法?Object類hashcode,equals 設計原則? sun為什麼這麼設計?Object類的概述

8、如何在父類中為子類自動完成所有的 hashcode 和 equals 實現?這麼做有何優劣。

9、可以在 hashcode() 中使用隨機數字嗎?

1、什麼是執行緒

執行緒指的是cpu完成一系列程序的操作

2、多執行緒的優點

合理的利用cpu資源,提高工作效率

3、多執行緒的幾種實現方式

java的多執行緒主要有繼承Thread類和實現runnable介面的方式實現的

4、用 Runnable 還是 Thread

都是可以的,要根據實際的場景

5、什麼是執行緒安全

當一個方法正在被訪問那麼其他的執行緒就不能再訪問這個方法了,必須等到這個方法被執行完,其他執行緒才能訪問,這樣的模式就叫執行緒安全

6、Vector, SimpleDateFormat 是執行緒安全類嗎

Vector是執行緒安全的集合,SimpleDateFormat並非執行緒安全的類

7、什麼 Java 原型不是執行緒安全的

8、哪些集合類是執行緒安全的

Vector,HashTable,CurrentHashMap等

9、多執行緒中的忙迴圈是什麼

  忙迴圈就是程式設計師用迴圈讓一個執行緒等待,不像傳統方法wait(), sleep() 或 yield() 它們都放棄了CPU控制,而忙迴圈不會放棄CPU,它就是在執行一個空迴圈。這麼做的目的是為了保留CPU快取,在多核系統中,一個等待執行緒醒來的時候可能會在另一個核心執行,這樣會重建快取。為了避免重建快取和減少等待重建的時間就可以使用它了。

10、如何建立一個執行緒

/**  

* <p>Title: Thread.java</p>  

* <p>Description: </p>  

* <p>Copyright: Copyright (c) 2017</p>  

* <p>Company:kehui</p>  

* @author jiangcl 

* @date 2018年10月10日  

* @version 1.0  

*/  
package com.mvc.test.thread;

/**  

 * <p>Title: Thread</p>  

 * <p>Description: </p>  

 * @author jiangcl 

 * @date 2018年10月10日  

 */
public class ThreadTest {
	
	
	//執行緒的建立主要由繼承Thread方法和實現runnable介面的方式
	
	public static void main(String[] args) {
		
		// 使用 繼承Thread方式建立
		
		Thread1 th1 = new Thread1();
		// 使用介面方式建立
		
		Thread2 th2 = new Thread2();
		
		Thread th3 = new Thread(th2,"執行緒2");
		
		// 直接建立
		new Thread(){
			
			public void run(){
				
				System.out.println("直接使用thread方式建立執行緒");
				
			}
		}.start();
		
		
		// start() 是執行緒的啟動方法
		
		th1.start();
		
		th3.start();
		
		
		
		
	}
}



11、編寫多執行緒程式有幾種實現方式


12、什麼是執行緒區域性變數

共享單個變數:

/**  

* <p>Title: ShareParam.java</p>  

* <p>Description: </p>  

* <p>Copyright: Copyright (c) 2017</p>  

* <p>Company:kehui</p>  

* @author jiangcl 

* @date 2018年10月14日  

* @version 1.0  

*/  
package com.mvc.test.thread;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**  

 * <p>Title: ShareParam</p>  

 * <p>Description: </p>  

 * @author jiangcl 

 * @date 2018年10月14日  

 */
public class ShareParam extends Thread{
	
	
	List<Integer> list = new ArrayList<Integer>();
	
	int printTimes = 0;
	
	boolean stopFlag = true;
	
	long startTime = System.currentTimeMillis();
	
	public void run(){
		
		while(stopFlag){
			
			printTimes++;
			
			list.add(printTimes);
			
			System.out.println(Thread.currentThread().getName()+"列印的次數為:"+printTimes);
			if(printTimes ==90){
				stopFlag = false;
				
				System.out.println(list.toString());
				long endTime = System.currentTimeMillis();
				
				System.out.println("花費的時間為:"+(endTime-startTime));
			}
			
		}
		
		
		
		
		
		
	}
}

/**  

* <p>Title: ShareTest.java</p>  

* <p>Description: </p>  

* <p>Copyright: Copyright (c) 2017</p>  

* <p>Company:kehui</p>  

* @author jiangcl 

* @date 2018年10月14日  

* @version 1.0  

*/  
package com.mvc.test.thread;

/**  

 * <p>Title: ShareTest</p>  

 * <p>Description: </p>  

 * @author jiangcl 

 * @date 2018年10月14日  

 */
public class ShareTest {
	
	public static void main(String[] args) {
		
		
		ShareParam p = new ShareParam();
		
		Thread th1 = new Thread(p);
		
		Thread th2 = new Thread(p);
		
		th1.setName("執行緒1");
		th2.setName("執行緒2");
		
		th1.start();
		th2.start();
		
		
	}

}

在這裡插入圖片描述

13、執行緒和程序有什麼區別?程序間如何通訊,執行緒間如何通訊

程序:具有一定獨立功能的程式關於某個資料集合上的一次執行活動,程序是系統進行資源分配和排程的一個獨立單位.

執行緒:程序的一個實體,是CPU排程和分派的基本單位,它是比程序更小的能獨立執行的基本單位.執行緒自己基本上不擁有系統資源,只擁有一點在執行中必不可少的資源(如程式計數器,一組暫存器和棧),但是它可與同屬一個程序的其他的執行緒共享程序所擁有的全部資源.

14、什麼是多執行緒環境下的偽共享(false sharing)

15、同步和非同步有何異同,在什麼情況下分別使用他們?舉例說明

1、啟動一個執行緒是呼叫 run() 還是 start() 方法?start() 和 run() 方法有什麼區別

start() 是呼叫執行緒啟動的方法,start() 方法是從底層啟動了,執行緒啟動方法,run是執行緒的執行體,也是執行緒裡面的普通,方法,有start()呼叫,使用執行緒直接run()達不到併發執行任務的目的

2、呼叫start()方法時會執行run()方法,為什麼不能直接呼叫run()方法

3、sleep() 方法和物件的 wait() 方法都可以讓執行緒暫停執行,它們有什麼區別

sleep()方法(休眠)是執行緒類(Thread)的靜態方法,呼叫此方法會讓當前執行緒暫停執行指定的時間,
將執行機會(CPU)讓給其他執行緒,但是物件的鎖依然保持,因此休眠時間結束後會自動恢復(執行緒回到就緒狀態,請參考第66題中的執行緒狀態轉換圖)。

wait()是Object類的方法,呼叫物件的wait()方法導致當前執行緒放棄物件的鎖(執行緒暫停執行),進入物件的等待池(wait pool),只有呼叫物件的notify()方法(或notifyAll()方法)時才能喚醒等待池中的執行緒進入等鎖池(lockpool),如果執行緒重新獲得物件的鎖就可以進入就緒狀態

4、yield方法有什麼作用?sleep() 方法和 yield() 方法有什麼區別

yield()是執行緒執行完釋放出資源,供其他執行緒使用

5、Java 中如何停止一個執行緒


一般使用while迴圈使用一個boolean變數控制while迴圈,如果這個boolean值改變就退出迴圈退出執行緒

6、stop() 和 suspend() 方法為何不推薦使用

7、如何在兩個執行緒間共享資料

不能夠線上程內使用區域性變數,使用成員變數並且使用static修飾

8、如何強制啟動一個執行緒

9、如何讓正在執行的執行緒暫停一段時間

使用sleep()方法或者使用wait()方法,2個方法的區別是sleep()在休眠執行緒以後,會獲取執行緒的鎖,這個其他執行緒處於阻塞狀態,而wait()在停止執行緒以後會釋放鎖,讓其他執行緒有機會去競爭這個鎖,不會阻塞執行緒的執行

10、什麼是執行緒組,為什麼在Java中不推薦使用

11、你是如何呼叫 wait(方法的)?使用 if 塊還是迴圈?為什麼

1、有哪些不同的執行緒生命週期

1.執行緒的建立(2種方式)
2.執行緒的就緒狀態
3.執行緒的開啟
4.執行緒執行
   執行緒的掛起
   執行緒的休眠
5.執行緒的結束	

2、執行緒狀態,BLOCKED 和 WAITING 有什麼區別

3、畫一個執行緒的生命週期狀態圖

4、ThreadLocal 用途是什麼,原理是什麼,用的時候要注意什麼

1、請說出你所知的執行緒同步的方法

多執行緒在同時操作同一個變數的時候,會出現錯誤,所以我們需要同步操作同一個變數,這個就是執行緒同步,使用執行緒同步一般使用synchronized關鍵字的方法或者程式碼塊

2、synchronized 的原理是什麼

就是給synchronized修飾的方法加鎖,使執行緒必須執行完以後,其他執行緒才能執行這個方法

3、synchronized 和 ReentrantLock 有什麼不同

4、什麼場景下可以使用 volatile 替換 synchronized

5、有T1,T2,T3三個執行緒,怎麼確保它們按順序執行?怎樣保證T2在T1執行完後執行,T3在T2執行完後執行

/**  

* <p>Title: RR.java</p>  

* <p>Description: </p>  

* <p>Copyright: Copyright (c) 2017</p>  

* <p>Company:kehui</p>  

* @author jiangcl 

* @date 2018年10月18日  

* @version 1.0  

*/  
package com.mvc.test.thread;

/**  

 * <p>Title: RR</p>  

 * <p>Description: </p>  

 * @author jiangcl 

 * @date 2018年10月18日  

 */
public class JoinTest {
    public static void main(String [] args) throws InterruptedException {
        ThreadJoinTest t1 = new ThreadJoinTest("執行緒1");
        ThreadJoinTest t2 = new ThreadJoinTest("執行緒2");
        ThreadJoinTest t3 = new ThreadJoinTest("執行緒3");
        t1.start();
        /**join的意思是使得放棄當前執行緒的執行,並返回對應的執行緒,例如下面程式碼的意思就是:
         程式在main執行緒中呼叫t1執行緒的join方法,則main執行緒放棄cpu控制權,並返回t1執行緒繼續執行直到執行緒t1執行完畢
         所以結果是t1執行緒執行完後,才到主執行緒執行,相當於在main執行緒中同步t1執行緒,t1執行完了,main執行緒才有執行的機會
         */
        t1.join();
        
        t3.start();
        t3.join();
        t2.start();
        
    }

}
class ThreadJoinTest extends Thread{
    public ThreadJoinTest(String name){
        super(name);
    }
    @Override
    public void run(){
        System.out.println(Thread.currentThread().getName()+"執行了");
    }
}

6、同步塊內的執行緒丟擲異常會發生什麼

7、當一個執行緒進入一個物件的 synchronized 方法A 之後,其它執行緒是否可進入此物件的 synchronized 方法B

不能。其它執行緒只能訪問該物件的非同步方法,同步方法則不能進入。因為非靜態方法上的synchronized修飾符要求執行方法時要獲得物件的鎖,如果已經進入A方法說明物件鎖已經被取走,那麼試圖進入B方法的執行緒就只能在等鎖池(注意不是等待池哦)中等待物件的鎖

8、使用 synchronized 修飾靜態方法和非靜態方法有什麼區別

9、如何從給定集合那裡建立一個 synchronized 的集合