首頁  >  文章  >  Java  >  分享java的一些基礎面試題

分享java的一些基礎面試題

零下一度
零下一度原創
2017-06-23 09:30:431372瀏覽

1.儲存資料的地方

暫存器、堆疊、堆疊、靜態儲存、常數儲存(常數池 String a = 「abc」 a在堆疊中、「abc」在常數池裡)、非RAM儲存 

2.基本數據類型

 

 作為類別的成員自動初始化為預設值

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

 

3.高精確度數字的類別

## 

BigInteger 、Bigdecimal

精確度高、速度慢

 

4.java垃圾處理

##Java 有一個特別的“垃圾收集器”,它會尋找用new

創建的所有對象,並辨別其中哪些不再被引用。隨後,它會自動釋放那些閒置物件佔據的內存,以便能由新物件使用。

 5.static執行順序

 

父類別的 static 成員變數和 static 語句 

 

子類別的static 成員變數和 static 語句 

#父類別的

static 成員變量

static

語句區塊 父類別的建構方法## 

子類別的非

static 成員變數與非

static

語句區塊

 #子類別的建構方法 

static只執行一次。第一次 new

的時候執行)

 

#6.集合類別

##Vector會自動成長的數組,查詢效率高,增刪效率低,執行緒安全,速度較慢,成長為原來的一倍。

ArrayList會自動成長的數組,查詢效率高,增刪效率低,執行緒不安全的,速度快,成長為原來的

0.5#倍。 LinkedList雙向迴圈鍊錶,查詢效率低,增刪效率高,執行緒不安全。

HashMap 為鍊錶散列即數組與鍊錶的結合體 允許null值,線程不安全,效率高。

TreeMap為二元排序樹實現,利用Key排序。 LinkedHashMap 為雜湊表和鍊錶實現,是

###HashMap######的子類,它保留插入的順序,如果需要輸出的順序和輸入時的相同,那就選用######LinkedHashMap######。 ######

Hashtable執行緒安全,效率低,不允許null值值。

Set 為不可重複的:

TreeSet基於TreeMap#實現,為有序的,線程不安全的。

HashSet 基於HashMap實現,HashMapkey

LinkedHashSet基於LinkedHashMap實作 ,是有序的。

7.Map的遍歷

#使用 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 #值組合集合。

1entrySet實作了Set接口,裡面存放的是鍵值對。一個K對應一個V
2,用來遍歷map的一種方法。
 Set> entryseSet=map.entrySet();  
  for (Map.Entry entry:  . .println(entry.getKey()+","+entry.getValue());  
  }  

透過getKey()得到KgetValue得到V
3
,還有一種是keySetSet set = map.keySet();   
  for (String s:set) {  
   System.out.println(s+","+map.get(s)) ;  
  }

 

二、IO系統

 位元組輸出流#字元輸出流# #OutputStream#Writer##FileOutStream  #InputStreamReaderOutputStreamWriter#物件流ObjectInputStream FilterInputStream#FilterReader

橋樑流:
InputStreamReader

將位元組流轉換成字元流。 (讀為轉換成字元流)

OutputStreamWriter

將字元流轉換成位元組流(寫為轉換為位元組流)

 

#串流分類

使用分類

位元組輸入流

#字元輸入流

##字元輸入流

#抽象基底類別

InputStream

OutputStream

#Reader

#Writer

節點流

存取檔案

#FileInputStream

#########FileReader##################FileWriter###### ################存取數值################ByteArrayInputStream################################################################################## ##ByteArrayOutStream##################CharArrayReader#################CharArrayWriter######### ############存取管道(線程交互)################PipedInputStream############################################################################################################################################################################################################################################################### # ##PipedOutStream##################PipedReader##################PipedWriter########## ############存取字串############ ############# ########### ####StringReader##################StringWriter#####################處理流程### #########緩衝流############BufferedInputStream############BufferedOutputStream#################################################################################

BufferedReader

BufferedWriter

#ObjectOutputStream

 

#抽象基底類別(過濾)

##抽象基底類別(過濾)

#FilterOutputStream

####FilterWriter################### #####列印流程############ #############PrintStream############ ###################################################################### ######PrintWriter##################推回輸入流############PushbackInputStream########################################################### #### ############PushbackReader############# #################特殊流# ###########DataInputStream############DataOutputStream############ ############ # ##############

1.Java IO是採用的是裝飾模式,也就是採用處理流程來包裝節點流的方式,來達到程式碼通用性。

2.處理流和節點流的區分方法,節點流在新建時需要一個資料來源(檔案、網路)作為參數,而處理流需要一個節點流作為參數。

3.處理流程的作用是提高程式碼通用性,寫程式碼的便利性,提高效能。

4.節點流都是對應抽象基底類別的實作類,它們都實作了抽象基底類別的基礎讀寫方法。其中read()方法如果傳回-1#,代表已經讀到資料來源結尾。

1. 以位元組為單位的輸入流的框架圖

下面,是以位元組為單位的輸入流的框架圖。

從中,我們可以看出。
(01) InputStream 是以位元組為單位的輸入流的超類別。 InputStream提供了read()#介面從輸入流讀取位元組資料。
(02) ByteArrayInputStream 是位元組陣列輸入流。它包含一個內部緩衝區,該緩衝區包含從流中讀取的位元組;通俗點說,它的內部緩衝區就是一個位元組數組,而ByteArrayInputStream#本質就是透過位元組數組來實現的。
(03) PipedInputStream 是管道輸入流,它和PipedOutputStream一起使用,可以實作多執行緒間的管道通訊。
(04) FilterInputStream 是過濾輸入流。它是DataInputStreamBufferedInputStream的超類別。
(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 是過濾輸出流。它是DataOutputStreamBufferedOutputStream##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()方法,該執行緒結束生命週期

2.start() 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()

3.synchronized

#我們將synchronized的基本規則總結為下面3條,並透過實例對它們進行說明。
第一條: 當一個執行緒存取某物件 #的“synchronized方法“synchronized程式碼區塊 時,其他執行緒對該物件的該 #“synchronized方法“synchronized程式碼區塊 的存取將被阻塞。
第二條: 當一個執行緒存取某物件 #的“synchronized方法“synchronized程式碼區塊 時,其他執行緒仍可存取該物件的非同步程式碼區塊。
第三條: 當一個執行緒存取某物件 #的“synchronized方法“synchronized程式碼區塊 時,其他執行緒對該物件的其他的“synchronized方法“synchronized程式碼區塊#”的存取將被阻塞。

4.wait(), notify(), notifyAll()

notify()-- 喚醒在此物件監視器上等待的單一線程。
notifyAll()-- 喚醒在此物件監視器上等待的所有執行緒。
wait()-- 讓目前執行緒處於#等待(##阻塞)狀態直到其他執行緒呼叫此物件的# notify() 方法或notifyAll() 方法,目前執行緒被喚醒(進入就緒狀態”) wait(long timeout)--
讓目前執行緒處於等待()狀態直到其他執行緒呼叫此物件的notify() 方法或notifyAll() #方法,或超過指定的時間量,當前執行緒被喚醒(
進入#就緒狀態”)#。 wait(long timeout, int nanos)-- 讓目前執行緒處於#等待(阻塞)狀態直到其他執行緒呼叫此物件的notify() 方法或notifyAll() 方法,或其他某個執行緒中斷目前執行緒,或已超過某個實際時間量,目前執行緒被喚醒(

#進入##就緒狀態

”)

5.yield()介紹#yield()的作用是讓步。它能讓目前執行緒由運行狀態#進入到#就緒狀態,從而讓它具有相同優先權的等待執行緒取得執行權;但是,並不能保證在目前執行緒呼叫yield()

之後,其它具有相同優先權的執行緒就一定能獲得執行權;也有可能是目前執行緒又進入######「######運行狀態######」# #####繼續運行! ######

6.sleep()介紹

sleep() 定義在Thread.java中。
sleep() 的作用是讓目前執行緒休眠,也就是目前執行緒會從運行狀態進入到休眠(阻塞)狀態sleep()會指定休眠時間,執行緒休眠的時間會大於/等於該休眠時間;當執行緒重新被喚醒時,它會由阻塞狀態變成#就緒狀態 ,從而等待cpu的調度執行。

我們知道,wait()的作用是讓目前執行緒由運行狀態進入等待() #狀態的同時,也會釋放同步鎖定。而sleep()的作用是也是讓目前執行緒由運行狀態##」進入到休眠(#)##狀態 ##”
但是,wait()會釋放物件的同步鎖定,而sleep()
則不會釋放鎖定。 下面透過範例示範

sleep()###是不會釋放鎖定的。 ######

我們知道,wait()的作用是讓目前執行緒由運行狀態進入等待(#)狀態 的同時,也會釋放同步鎖定。而yield()的作用是讓步,它也會讓目前執行緒離開運行狀態。它們的差異是:
(01) wait()是讓執行緒由執行狀態進入到等待(#)##狀態 ##”,而yield()是讓執行緒由執行狀態進入到就緒狀態
(02) wait()是會執行緒釋放它所持有物件的同步鎖定,而yield()

方法不會釋放鎖定。

7.join()介紹

#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()的作用是中斷本線程。當本執行緒中斷自己是被允許的;其它執行緒呼叫本線程的

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”

中斷一個已終止的執行緒不會產生任何動作。

8.1 終止處於「阻塞狀態」的執行緒

##通常,我們透過

中斷方式終止處於#阻塞狀態的執行緒。 當執行緒因為被呼叫了
sleep(), wait(), join()等方法而進入阻塞狀態;若此時呼叫執行緒的interrupt()將執行緒的中斷標記設為true#。由於處於阻塞狀態,中斷標記會被清除,同時產生一個InterruptedException#異常。將InterruptedException放在適當的為止就能終止執行緒

8.2 終止處於「運行狀態」的執行緒

#通常,我們透過標記 方式終止處於運行狀態的執行緒。其中,包括中斷標記#額外新增標記
(01) 透過中斷標記終止執行緒。
形式如下:

@Overridepublic void run() {

    while (!isInterrupted()) {

      執行任務...    }

}

說明:isInterrupted()是判斷執行緒的中斷標記是不是為true。當執行緒處於運行狀態,並且我們需要終止它時;可以呼叫執行緒的interrupt()方法,使用執行緒的中斷標記為#true ,即isInterrupted()會傳回true。此時,就會退出while迴圈。
注意:interrupt()並不會終止處於運行狀態##」 的線程!它會將線程的中斷標記設為true

(02)

透過額外新增標記
形式如下:

private volatile boolean flag= true;protected void stopTask() {

    flag = false;

##    flag = false;

# }

 

@Overridepublic void run() {

    while (flag) {        // 執行任務

...    }

}說明:在執行緒中有一個flag標記,它的預設值是true ;並且我們提供stopTask()來設定flag標記。當我們需要終止該執行緒時,呼叫該執行緒的stopTask()方法就可以讓執行緒退出while
迴圈。 注意:將flag定義為volatile類型,是為了保證flag的可見性。即其它執行緒經由stopTask()修改了flag之後,本執行緒能看到修改後的 flag

的值。 ######

最後談談 interrupted() isInterrupted()
interrupted() isInterrupted()#都能夠用來偵測物件的中斷標記
區別是,interrupted()除了返回中斷標記之外,它還會清除中斷標記(即將中斷標記設定為false);而isInterrupted()只回傳中斷標記

 

#9.執行緒優先權和守護執行緒

#每個執行緒都有一個優先權。 高優先權執行緒會優先於低優先權執行緒# ”執行。每個線程都可以被標記為一個守護程序或非守護程序。在一些運行的主執行緒中建立新的子執行緒時,子執行緒的優先權被設定為等於建立它的主執行緒的優先權# ”,當且僅當創建它的主線程是守護線程 子執行緒才會是守護執行緒

 

Java虛擬機啟動時,通常會有一個單一的非守護執行緒(該執行緒透過是透過main()方法啟動)。 JVM會一直運作直到下面的任何條件發生,JVM就會終止執行:

#(01) 呼叫了exit()方法,並且exit()有權限被正常執行。

(02) 所有的非守護執行緒都死了(JVM中僅只有守護執行緒# ”)

 每一個執行緒都被標記為守護執行緒#或使用者執行緒。當只有守護執行緒執行時,JVM

會自動退出。

### ###

以上是分享java的一些基礎面試題的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn