暫存器、堆疊、堆疊、靜態儲存、常數儲存(常數池 String a = 「abc」 a在堆疊中、「abc」在常數池裡)、非RAM儲存
作為類別的成員自動初始化為預設值
boolean 1#位元 預設false
byte 8位元 一個位元組 \u0000
char 16位元 一個字元0
short 16位元 0
int 32位元# 0
float 32位元 0.0f
long 64位元 0L
double 64位元 0.0d
精確度高、速度慢
創建的所有對象,並辨別其中哪些不再被引用。隨後,它會自動釋放那些閒置物件佔據的內存,以便能由新物件使用。
5.static執行順序
父類別的 static 成員變數和 static 語句
子類別的static 成員變數和 static 語句
#父類別的
非 static 成員變量
與非
static語句區塊 父類別的建構方法##
子類別的非static 成員變數與非
static 語句區塊#子類別的建構方法
(
#6.集合類別
##Vector會自動成長的數組,查詢效率高,增刪效率低,執行緒安全,速度較慢,成長為原來的一倍。
ArrayList會自動成長的數組,查詢效率高,增刪效率低,執行緒不安全的,速度快,成長為原來的
0.5#倍。 LinkedList雙向迴圈鍊錶,查詢效率低,增刪效率高,執行緒不安全。
HashMap 為鍊錶散列即數組與鍊錶的結合體 允許null值,線程不安全,效率高。
TreeMap為二元排序樹實現,利用Key排序。 LinkedHashMap 為雜湊表和鍊錶實現,是
###HashMap######的子類,它保留插入的順序,如果需要輸出的順序和輸入時的相同,那就選用######LinkedHashMap######。 ######Hashtable執行緒安全,效率低,不允許null值值。
Set 為不可重複的:
TreeSet基於TreeMap#實現,為有序的,線程不安全的。
HashSet 基於HashMap實現,HashMap的key 。
LinkedHashSet基於LinkedHashMap實作 ,是有序的。
#使用 entrySet 遍歷 Map 類別集合KV#,而不是keySet 方式進行遍歷。
說明: keySet 其實是遍歷了#2 次,一次是轉為Iterator 對象,另一次是從hashMap
#key 所對應的value。而entrySet 只是遍歷了一次就把key 和value 都放到了entry 中,效
率更高。如果是 JDK8,使用 Map.foreach 方法。
正例: values()傳回的是V #值集合,是一個list 集合物件; keySet()#傳回的是#K 值集合,是
#一個 Set 集合物件; entrySet() 傳回的是K-V #值組合集合。
1,entrySet實作了Set接口,裡面存放的是鍵值對。一個K對應一個V。
2,用來遍歷map的一種方法。
Set
for (Map.Entry
}
透過getKey()得到K,getValue得到V。
3
,還有一種是keySet。 Set
for (String s:set) {
System.out.println(s+","+map.get(s)) ;
}
橋樑流: | InputStreamReader 將位元組流轉換成字元流。 (讀為轉換成字元流) |
OutputStreamWriter 將字元流轉換成位元組流(寫為轉換為位元組流) |
||||
# | #串流分類 使用分類 |
位元組輸入流 | 位元組輸出流#字元輸入流 |
|||
##字元輸入流 | #字元輸出流 | #抽象基底類別 |
InputStream |
|||
OutputStream |
||||||
#Reader |
||||||
#Writer |
節點流 |
存取檔案 |
#FileInputStream
|
|||
##FileOutStream | #########FileReader##################FileWriter###### ################存取數值################ByteArrayInputStream################################################################################## ##ByteArrayOutStream##################CharArrayReader#################CharArrayWriter######### ############存取管道(線程交互)################PipedInputStream############################################################################################################################################################################################################################################################### # ##PipedOutStream##################PipedReader##################PipedWriter########## ############存取字串############ ############# ########### ####StringReader##################StringWriter#####################處理流程### #########緩衝流############BufferedInputStream############BufferedOutputStream################################################################################# | BufferedReader |
BufferedWriter |
|||
#InputStreamReader | OutputStreamWriter | |||||
ObjectInputStream | #ObjectOutputStream |
|
#抽象基底類別(過濾) |
##抽象基底類別(過濾) |
||
#FilterOutputStream | ||||||
#FilterReader |
1.Java IO是採用的是裝飾模式,也就是採用處理流程來包裝節點流的方式,來達到程式碼通用性。
2.處理流和節點流的區分方法,節點流在新建時需要一個資料來源(檔案、網路)作為參數,而處理流需要一個節點流作為參數。
3.處理流程的作用是提高程式碼通用性,寫程式碼的便利性,提高效能。
4.節點流都是對應抽象基底類別的實作類,它們都實作了抽象基底類別的基礎讀寫方法。其中read()方法如果傳回-1#,代表已經讀到資料來源結尾。
1. 以位元組為單位的輸入流的框架圖
下面,是以位元組為單位的輸入流的框架圖。
從中,我們可以看出。
(01) InputStream 是以位元組為單位的輸入流的超類別。 InputStream提供了read()#介面從輸入流讀取位元組資料。
(02) ByteArrayInputStream 是位元組陣列輸入流。它包含一個內部緩衝區,該緩衝區包含從流中讀取的位元組;通俗點說,它的內部緩衝區就是一個位元組數組,而ByteArrayInputStream#本質就是透過位元組數組來實現的。
(03) PipedInputStream 是管道輸入流,它和PipedOutputStream一起使用,可以實作多執行緒間的管道通訊。
(04) FilterInputStream 是過濾輸入流。它是DataInputStream和BufferedInputStream的超類別。
(05) DataInputStream 是資料輸入流。它是用來裝飾其它輸入流,它「允許應用程式以與機器無關方式從底層輸入流中讀取基本 Java #資料類型」。
(06) BufferedInputStream 是緩衝輸入流。它的作用是為另一個輸入流添加緩衝功能。
(07) File 是「檔案」和「目錄路徑名」的抽象表示形式。關於File,注意兩點:
a), File不只表示文件,它也可以表示目錄!
b), File雖然在io保重定義,但是它的超類別是Object# ,而不是InputStream。
(08) FileDescriptor 是「檔案描述子」。它可以被用來表示開放文件、開放套接字等。
(09) FileInputStream 是檔案輸入流。它通常用於對文件進行讀取操作。
(10) ObjectInputStream 是物件輸入流。它和ObjectOutputStream一起,用來提供對「基本資料或物件」的持久儲存。
2. 以位元組為單位的輸出流的框架圖
#下面,是一個以位元組為單位的輸出流的框架圖。
從中,我們可以看出。以位元組為單位的輸出流的公共父類別是OutputStream。
(01) OutputStream 是以位元組為單位的輸出流的超類別。 OutputStream提供了write()介面從輸出流讀取位元組資料。
(02) ByteArrayOutputStream 是位元組陣列輸出流。寫入ByteArrayOutputStream的資料被寫入一個 byte 陣列。緩衝區會隨著資料的不斷寫入而自動增長。可使用 toByteArray() 和 toString() 來取得資料。
(03) PipedOutputStream 是管道輸出流,它和PipedInputStream一起使用,可以實作多執行緒間的管道通訊。
(04) FilterOutputStream 是過濾輸出流。它是DataOutputStream,BufferedOutputStream和##PrintStream的超類別。 (05) DataOutputStream
是資料輸出流。它是用來裝飾其它輸出流,它「允許應用程式以與機器無關方式向底層寫入基本 Java 資料類型」。 (06) BufferedOutputStream
是緩衝輸出流。它的作用是為另一個輸出流添加緩衝功能。 (07) PrintStream
是列印輸出流。它是用來裝飾其它輸出流,能為其他輸出流添加了功能,使它們能夠方便地列印各種資料值表示形式。 (08) FileOutputStream
是檔案輸出流。它通常用於向文件進行寫入操作。 (09) ObjectOutputStream
是物件輸出流。它和ObjectInputStream一起,用來提供對「基本資料或物件」的持久儲存。
執行緒共包含以下5種狀態。
1. 新狀態(New) : 執行緒物件建立後,就進入了新建狀態。例如,Thread thread = new Thread()。
2. 就緒狀態(Runnable): 也稱為「可執行狀態」。執行緒物件被建立後,其它執行緒呼叫了該物件的start()方法,從而來啟動該執行緒。例如,thread.start()。處於就緒狀態的線程,隨時可能被CPU#調度執行。
3. 運行狀態(Running) : #執行緒取得CPU#權限進行執行。需要注意的是,執行緒只能從就緒狀態進入到運行狀態。
4. 阻塞狀態(Blocked) : 阻塞狀態是執行緒因為某些原因放棄CPU #使用權,暫時停止運轉。直到執行緒進入就緒狀態,才有機會轉到運行狀態。阻塞的情況分為三種:
(01) 等待阻塞-- 透過呼叫執行緒的wait()方法,讓執行緒等待某工作的完成。
(02) 同步阻塞-- #執行緒在取得synchronized同步鎖定失敗 (因為鎖定被其它執行緒所佔用),它會進入同步阻塞狀態。
(03) 其他阻塞-- #透過呼叫執行緒的sleep()或join()或發出了I/O#請求時,執行緒會進入到阻塞狀態。當sleep()狀態逾時、join()等待執行緒終止或逾時、或I/O 處理完畢時,執行緒重新轉入就緒狀態。
5. 死亡狀態(Dead) : 執行緒執行了或因異常退出了run()方法,該執行緒結束生命週期。
繼承Thread
class MyThread extends Thread{ public void run(){};
MyThread mythread = new MyThread();
//
實作Runnable
#class MyThread implements Runnable{ public void run(){
...
}
#};
## ##Thread mt=new MyThread( ); Thread t1=new Thread(mt);mythread.start()會啟動一個新線程,並在新線程中執行run()方法。
而mythread.run()則會直接在目前執行緒中執行run()方法,並不會啟動一個新執行緒來運行run()。
#我們將synchronized的基本規則總結為下面3條,並透過實例對它們進行說明。
第一條: 當一個執行緒存取「某物件」 #的“synchronized方法”或“synchronized程式碼區塊 」時,其他執行緒對「該物件」的該 #“synchronized方法”或“synchronized程式碼區塊” 的存取將被阻塞。
第二條: 當一個執行緒存取「某物件」 #的“synchronized方法”或“synchronized程式碼區塊 ”時,其他執行緒仍可存取「該物件」的非同步程式碼區塊。
第三條: 當一個執行緒存取「某物件」 #的“synchronized方法”或“synchronized程式碼區塊 」時,其他執行緒對「該物件」的其他的“synchronized方法”或“synchronized程式碼區塊#”的存取將被阻塞。
notify()-- 喚醒在此物件監視器上等待的單一線程。
notifyAll()-- 喚醒在此物件監視器上等待的所有執行緒。
wait()-- 讓目前執行緒處於「#等待(##阻塞)狀態」,「直到其他執行緒呼叫此物件的# notify() 方法或notifyAll() 方法」,目前執行緒被喚醒(進入“就緒狀態”)。 wait(long timeout)--
讓目前執行緒處於「等待()狀態」,「直到其他執行緒呼叫此物件的notify() 方法或notifyAll() #方法,或超過指定的時間量”,當前執行緒被喚醒(
進入“#就緒狀態”)#。 wait(long timeout, int nanos)-- 讓目前執行緒處於「#等待(阻塞)狀態」,「直到其他執行緒呼叫此物件的notify() 方法或notifyAll() 方法,或其他某個執行緒中斷目前執行緒,或已超過某個實際時間量」,目前執行緒被喚醒(
。 5.yield()介紹#yield()的作用是讓步。它能讓目前執行緒由“運行狀態”#進入到「#就緒狀態」,從而讓它具有相同優先權的等待執行緒取得執行權;但是,並不能保證在目前執行緒呼叫yield()
之後,其它具有相同優先權的執行緒就一定能獲得執行權;也有可能是目前執行緒又進入######「######運行狀態######」# #####繼續運行! ######sleep() 定義在Thread.java中。
sleep() 的作用是讓目前執行緒休眠,也就是目前執行緒會從「運行狀態」進入到「休眠(阻塞)狀態」。 sleep()會指定休眠時間,執行緒休眠的時間會大於/等於該休眠時間;當執行緒重新被喚醒時,它會由“阻塞狀態”變成“#就緒狀態” ,從而等待cpu的調度執行。
我們知道,wait()的作用是讓目前執行緒由「運行狀態”進入「等待() #狀態」的同時,也會釋放同步鎖定。而sleep()的作用是也是讓目前執行緒由「運行狀態##」進入到“休眠(#)##狀態 ##”
。 但是,wait()會釋放物件的同步鎖定,而sleep()
則不會釋放鎖定。 下面透過範例示範
我們知道,wait()的作用是讓目前執行緒由「運行狀態」進入“等待(#)狀態” 的同時,也會釋放同步鎖定。而yield()的作用是讓步,它也會讓目前執行緒離開“運行狀態” 。它們的差異是:
(01) wait()是讓執行緒由「執行狀態」進入到「等待(#)##狀態 ##”,而yield()是讓執行緒由“執行狀態”進入到「就緒狀態」
。 (02) wait()是會執行緒釋放它所持有物件的同步鎖定,而yield()
#join() 定義在Thread.java
中。 join() 的作用:讓「主執行緒」等待「子執行緒」
// 主執行緒
public class Father extends Thread {public void run() {
Son s = new Son();
# ...
}
}//
子執行緒public class Son extends Thread {## oid publicoid v. ) {
...# }}它的原始碼就是當子執行緒是活的(isAlive())主執行緒就不行停的等待( wait(0))8.interrupt()
interrupt()#方法時,會透過checkAccess()檢查權限。這有可能拋出SecurityException異常。
如果本執行緒是處於阻塞狀態:呼叫執行緒的wait(), wait(long)或wait(long, int)會讓它進入等待(阻塞)#狀態,或是呼叫執行緒的join(), join( long), join(long, int), sleep(long), sleep(long, int)也會讓它進入阻塞狀態。若執行緒在阻塞狀態時,呼叫了它的interrupt()方法,那麼它的「##中斷狀態”會被清除並且會收到一個InterruptedException異常。例如,執行緒透過wait()進入阻塞狀態,此時透過interrupt()中斷該執行緒;呼叫interrupt()會立即將執行緒的中斷標記設為「true」,但由於執行緒處於阻塞狀態,所以該“中斷標記”會立即被清除為“false”,同時,會產生一個InterruptedException的例外。
如果執行緒被阻塞在一個Selector選擇器中,那麼透過interrupt()#中斷它時;執行緒的中斷標記會被設定為true,並且它會立即從選擇操作中傳回。
如果不屬於前面所說的情況,那麼透過interrupt()中斷執行緒時,它的中斷標記會被設定為 “true”。
中斷一個「已終止的執行緒」不會產生任何動作。
「中斷」方式終止處於「#阻塞狀態」的執行緒。 當執行緒因為被呼叫了 #通常,我們透過「標記 ”方式終止處於「運行狀態」的執行緒。其中,包括“中斷標記”#額外新增標記”。 @Overridepublic void run() { while (!isInterrupted()) { 執行任務... } } 說明:isInterrupted()是判斷執行緒的中斷標記是不是為true。當執行緒處於運行狀態,並且我們需要終止它時;可以呼叫執行緒的interrupt()方法,使用執行緒的中斷標記為#true ,即isInterrupted()會傳回true。此時,就會退出while迴圈。 透過「額外新增標記」。 ## flag = false; # } @Overridepublic void run() { while (flag) { // 執行任務 }說明:在執行緒中有一個flag標記,它的預設值是true ;並且我們提供stopTask()來設定flag標記。當我們需要終止該執行緒時,呼叫該執行緒的stopTask()方法就可以讓執行緒退出while 最後談談 interrupted() 和 isInterrupted()。 #每個執行緒都有一個優先權。 「高優先權執行緒」會優先於「低優先權執行緒# ”執行。每個線程都可以被標記為一個守護程序或非守護程序。在一些運行的主執行緒中建立新的子執行緒時,子執行緒的優先權被設定為等於「建立它的主執行緒的優先權# ”,當且僅當“創建它的主線程是守護線程”時 「子執行緒才會是守護執行緒」。 當Java虛擬機啟動時,通常會有一個單一的非守護執行緒(該執行緒透過是透過main()方法啟動)。 JVM會一直運作直到下面的任何條件發生,JVM就會終止執行: #(01) 呼叫了exit()方法,並且exit()有權限被正常執行。 (02) 所有的「非守護執行緒」都死了(即JVM中僅只有「守護執行緒# ”) 每一個執行緒都被標記為「守護執行緒」#或「使用者執行緒」。當只有守護執行緒執行時,JVM
sleep(), wait(), join()等方法而進入阻塞狀態;若此時呼叫執行緒的interrupt()將執行緒的中斷標記設為true#。由於處於阻塞狀態,中斷標記會被清除,同時產生一個InterruptedException#異常。將InterruptedException放在適當的為止就能終止執行緒
8.2 終止處於「運行狀態」的執行緒
(01) 透過「中斷標記」終止執行緒。
形式如下:
注意:interrupt()並不會終止處於「運行狀態##」 的線程!它會將線程的中斷標記設為true。
形式如下:
迴圈。 注意:將flag定義為volatile類型,是為了保證flag的可見性。即其它執行緒經由stopTask()修改了flag之後,本執行緒能看到修改後的 flag
interrupted() 和isInterrupted()#都能夠用來偵測物件的「中斷標記」。
區別是,interrupted()除了返回中斷標記之外,它還會清除中斷標記(即將中斷標記設定為false);而isInterrupted()只回傳中斷標記
#9.執行緒優先權和守護執行緒
以上是分享java的一些基礎面試題的詳細內容。更多資訊請關注PHP中文網其他相關文章!