JAVA基礎面試

1.保存數據的地方

香港彩票透码 www.kptln.icu 寄存器、棧、堆、靜態存儲、常量存儲(常量池 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實現,HashMap的key。

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

1,entrySet實現了Set接口,里面存放的是鍵值對。一個K對應一個V。
2,用來遍歷map的一種方法。
 Set<Map.Entry<String, String>> entryseSet=map.entrySet();  
  for (Map.Entry<String, String> entry:entryseSet) {  
   System.out.println(entry.getKey()+","+entry.getValue());  
  }  
通過getKey()得到K,getValue得到V。

3,還有一種是keySet。
Set<String> set = map.keySet();   
  for (String s:set) {  
   System.out.println(s+","+map.get(s));  
  }

 

二、   IO系統  

橋梁流:

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

 

 

抽象基類(過濾)

FilterInputStream

FilterOutputStream

FilterReader

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 是過濾輸入流。它是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()方法,該線程結束生命周期。

2.start() 和 run()的區別說明

//繼承Thread

class MyThread extends Thread{  

    public void run(){

        ...

    }

};

MyThread mythread = new MyThread();

 

//實現Runnable

class MyThread implements Runnable{  

public void run(){

        ...

    }

};

 MyThread 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();

        s.start();

        s.join();

        ...

    }

}// 子線程public class Son extends Thread {

    public void run() {

        ...

    }

}

它的源碼就是當子線程是活的(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;

}

 

@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會自動退出。

 來源:itnose

上一篇: Android開發中遇到的問題--Android中WARNING: Application does not specify an API level requirement!的解決方法

下一篇: String、StringBuffer、StringBulider

分享到: 更多
北京pk10全天计划专业 和值大小单双算法技巧 pk10平刷软件手机版 快三彩票大小单双有规律嘛 女篮亚洲杯2019分组 机选双色球号码 金7乐彩票今日开奖结果 七星彩选号超准方法 七乐彩综合走势图表图 快3计划软件手机版苹果 飞艇助赢计划软件那个好 旺旺时时采彩分析计划软件 手机版五星计划软件破解版 双式投注 七乐彩票购彩大厅 今天三肖包中