標籤:同步方法 檢測 java io 構造方法 float private hashcode 緩衝 pac
九種基礎資料型別 (Elementary Data Type)的大小,以及他們的封裝類。
| 基本類型 |
大小(位) |
位元組 |
最小值 |
最大值 |
封裝類 |
| boolean |
- |
1 |
- |
- |
Boolean |
| byte |
8 |
1 |
-128 |
127 |
Byte |
| char |
16 |
2 |
Unicode 0 |
Unicode 2^16-1 |
Character |
| short |
16 |
2 |
-2^15 |
2^15-1 |
Short |
| int |
32 |
4 |
-2^31 |
2^31-1 |
Integer |
| float |
32 |
4 |
|
|
Float |
| double |
64 |
8 |
|
|
Double |
| long |
64 |
8 |
-2^63 |
2^63-1 |
Long |
| void |
- |
|
- |
- |
Void |
Switch能否用string做參數?
JDK1.7之前是只支援int 或char
JDK1.7開始支援String
JDK1.5 開始支援 Enum 類
equals與==的區別
“==” 用於基礎資料型別 (Elementary Data Type)的比較,判斷引用是否指向堆記憶體的同一快地址。
equals 用於判斷兩個變數是否是對同一個對象的引用,即堆中的內容是否相同,傳回值為布爾類型。
可以用equals方法檢測兩個字串是否相等。
一定不能使用 == 運算子檢測兩個字串是否相等!== 用來確定兩個字串是否放置在同一個位置上。
如果虛擬機器始終將相同的字串共用,就可以使用 == 運算子檢測是否相等。但是實際上只有字串常量是共用的,而+或者substring等操作產生的結果並不是共用的。
Object有哪些公用方法?
- equals方法
Object類中的equals方法用於檢測一個對象是否等於另外一個對象。
- hashCode方法
該方法用於雜湊尋找,可以減少在尋找中使用equals的次數,重寫了equals方法一般都要重寫hashCode方法。這個方法在一些具有雜湊功能的Collection中用到。
- toString方法
用於返回表示對象值的字串。
Java的四種引用,強弱軟虛,用到的情境
- 強引用
強引用是使用最普遍的引用。如果一個對象具有強引用,那記憶體回收期絕不會回收它。
- 軟引用
如果一個對象只具有軟引用,則記憶體空間足夠,記憶體回收行程就不會回收它;如果記憶體空間不足了,就會回收這些 對象的記憶體。只要記憶體回收行程沒有回收它,該對象就可以被程式使用。軟引用可以用來實現記憶體敏感的快取。
- 弱引用
弱引用與軟引用的區別在於:只具有弱引用的對象具有更短暫的生命週期。
在記憶體回收行程線程掃描它所管轄的記憶體地區過程中,一旦發現了只具有弱引用的對象,不管當前記憶體空間足夠與否,都會回收它的記憶體。
不過,由於記憶體回收行程是一個優先順序很低的線程,因此不一樣很快發現那些只有弱引用的對象。
如果你想引用一個對象,但這個對象具有自己的生命週期,你不想介入這個對象的生命週期,這時候你就是用弱引用。
- 虛引用
虛引用不會決定對象的生命週期,如果一個對象僅持有虛引用,那麼他就和沒有任何引用一樣,在任何適合都可能被記憶體回收行程回收。
總結:
Java 4種引用的層級由高到低依次為:
強》軟》弱》虛
Hashcode的作用
hashCode的存在主要是用於尋找的快捷性,如Hashtable,HashMap等,hashCode是用來在散列儲存結構中確定對象的儲存地址的
ArrayList、LinkedList、Vector的區別
ArrayList本質上是一個數組,當更多的元素添加到ArrayList中時,其大小會動態增長,內部元素通過get和set方式進行訪問。不是安全執行緒的。
LinkedList是一個雙鏈表,因此在刪除和添加元素的時候優於數組形式的ArrayList,但是在get和set方面弱於ArrayList;
Vector幾乎和ArrayList一樣,但是Vector是安全執行緒的,在更多元素進來時,Vector每次請求雙倍的空間,而ArrayList每次對size增長50%。
String、StringBuffer與StringBuilder的區別
String是不可變類
StringBuffer是可變類
StringBuilder不是安全執行緒的
在執行效率方面,StringBuilder最高,StringBuffer次之,String最低
如果要操作的資料量比較小,應優先用String類
如果是在單線程下操作大量資料,應優先用StringBuilder類
如果在多線程下操作大量資料,應優先考慮StringBuffer類。
Map、Set、List、Queue、Stack的特點與用法
鍵映射到值的對象。 一個映射不能包含重複的鍵,每個鍵最多隻能映射到一個值。
某些映射實現可明確保證其順序,如TreeMap類;另一些映射實現不保證順序,如HashMap類。
Map中元素,可以將key序列,value序列單獨抽取出來。
使用keySet()抽取key序列,將map中所有keys產生一個Set。
使用 values() 抽取value序列,將map中的所有values產生一個Collection。
為什麼一個是Set,一個是Collection。因為key是獨一無二的,value允許重複。
一個不包含重複元素的Collection。
不可隨機訪問包含的元素
只能用lterator實現單向遍曆
Set沒有同步方法
可隨機訪問包含的元素
元素是有序的
可在任意位置增刪元素
不管訪問多少次,元素位置不變
允許重複元素
用Iterator實現單向遍曆,也可用ListIterator實現雙向遍曆
先進先出
用offer()來加入元素
用poll()來擷取並移出元素
peek()方法查看或使用前端元素
Queue實現通常不允許插入null元素
後進先出
Stack繼承自Vector,是同步的
提供了push、pop、peek、empty方法
如果涉及到堆棧,隊列等操作,應該考慮用List
對於需要快速插入,刪除元素,應該用LinkedList
如果需要快速隨機訪問元素,應該用ArrayList
如果單線程環境,考慮非同步的類,效率較高。
HashMap和HashTable的區別
主要區別:安全執行緒,同步,速度
HashMap幾乎等價於HashTable,除了HashMap是非同步的,並可以接受null
HashMap和ConcurrentHashMap的區別,HashMap的底層源碼
HashMap的本質是數組加鏈表。根據key取得hash值,然後計算出數組下標,如果多個key對應到同一個下標,就用鏈表串起來,新插入的在前面。
ConcurrentHashMap在HashMap的基礎上,將資料分為多個segment,預設16個,然後每次操作對一個segment加鎖,避免多線程鎖的幾率,提高並發效率。
HashMap就是一個Entry數組,Entry數組中包含了鍵和值,其中next也是一個Entry對象,當hash衝突時,形成一個鏈表。
static class Entry<K,V> implements Map.Entry<K,V> { final K key; V value; Entry<K,V> next; final int hash; /** * Creates new entry. */ Entry(int h, K k, V v, Entry<K,V> n) { value = v; next = n; //hash值衝突後存放在鏈表的下一個 key = k; hash = h; } ......... }
HashMap儲存資料的put方法
public V put(K key, V value) { if (key == null) //如果鍵為null的話,調用putForNullKey(value) return putForNullKey(value); int hash = hash(key.hashCode());//根據鍵的hashCode計算hash碼 int i = indexFor(hash, table.length); for (Entry<K,V> e = table[i]; e != null; e = e.next) { //處理衝突的,如果hash值相同,則在該位置用鏈表格儲存體 Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { //如果key相同則覆蓋並返回舊值 V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } modCount++; addEntry(hash, key, value, i); return null; }
當我們往HashMap中put元素時,先根據key的hash值得到這個元素在數組中的位置(即下標),然後就可以把這個元素放到對應的位置中了,如果這個元素的位置上已經存在其他元素了,那麼在同一個位子上的元素將會以鏈表的形式存放,新加入的放鏈表頭,之前加入的放後面。
從HashMap中get元素時,首先計算key的hash值,找到數組中對應位置的某一元素,然後通過key的equals方法在對應位置的鏈表中找到需要的元素。
如果沒有與key相同的鍵,則調用addEntry方法建立一個Entry對象:
void addEntry(int hash, K key, V value, int bucketIndex) { Entry<K,V> e = table[bucketIndex]; //如果要加入的位置有值,將該位置原先的值設定為新entry的next,也就是新entry鏈表的下一個節點 table[bucketIndex] = new Entry<>(hash, key, value, e); if (size++ >= threshold) //如果大於臨界值就擴容 resize(2 * table.length); //以2的倍數擴容 }
擴容資料
void resize(int newCapacity) { Entry[] oldTable = table; int oldCapacity = oldTable.length; if (oldCapacity == MAXIMUM_CAPACITY) { threshold = Integer.MAX_VALUE; return; } Entry[] newTable = new Entry[newCapacity]; transfer(newTable);//用來將原先table的元素全部移到newTable裡面 table = newTable; //再將newTable賦值給table threshold = (int)(newCapacity * loadFactor);//重新計算臨界值 }
TreeMap、HashMap、LindedHashMap的區別。Collection包結構,與Collections的區別。try catch finally,try裡有return,finally還執行嗎?
- try中沒有異常且try中有return
try---finally---return
- try中有異常,try中有return
try---catch---finally---return
總之finally永遠執行
- Excption與Error包結構。OOM你遇到過哪些情況,SOF你遇到過哪些情況。
- Java物件導向的三個特徵與含義。
Override和Overload的含義與區別
重寫是子類對父類的允許訪問的方法的實現過程進行重新編寫。
傳回值和形參都不能改變。即外殼不變,重寫內在實現。
重寫的好處在於子類可以根據需要,定義特定於自己的行為。
public class LiftOff { public static void main(String args []){ Animal a= new Animal(); Animal b = new pig(); a.eat(); b.eat(); } } class Animal{ public void eat(){ System.out.println("Animal eat xx "); } } class pig extends Animal{ public void eat(){ System.out.println("pig eat siliao"); } }
Animal eat xx pig eat siliao
重寫規則:
參數列表必須完全與被重寫方法相同(也就是說重寫,不能添加寫方法,不能添加參數。)
傳回型別必須完全與被重寫方法的傳回型別相同
父類的成員方法只能被他的子類重寫
聲明為final的方法不能被重寫
聲明為static的方法不能被重寫,但是能再次聲明。
構造方法不能被重寫
重載是在同一個類裡,方法名字相同,參數不同,傳回型別可相同也可不同的多個方法。
每個重載的方法都必須有一個獨一無二的參數類型列表。
被重載的方法必須改變參數列表,被重載的方法可以改變傳回型別,被重載的方法可以改變存取修飾詞,方法能在同一個類中或在一個子類中被重載。
public class LiftOff { public int test(){ System.out.println("Overload1"); return 1; } public void test(int a){ System.out.println("Overload1"+ a); } public String test(String a1 , String a2){ System.out.println("Overload1"+ a1+a2); return a1; } public static void main(String args []){ LiftOff t=new LiftOff(); System.out.println(t.test()); t.test(2); System.out.println(t.test("asd","erf")); } }
Overload11Overload12Overload1asderfasd
重載和重寫區別:
|
重載方法(Overload) |
重寫方法(Override) |
| 參數列表 |
必須修改 |
不能改 |
| 傳回型別 |
可以修改 |
不能改 |
| 異常 |
可以修改 |
可以減少或刪除,不能拋出新的 |
| 存取修飾詞 |
可以修改 |
只能降低限制,不能變高限制 |
限制又低到高: public、protected、private
Interface與abstract類的區別
如果一個類中包含抽象方法,那麼這個類就是抽象類別。類或方法聲明為abstract
介面就是指一個方法的集合,介面中所有方法都沒有方法體,介面通過關鍵字interface實現。
介面和抽象類別的相同點:
- 都不能被執行個體化
- 介面的實作類別或抽象類別的子類都只有實現了介面或抽象類別中的方法後才才能被執行個體化。
不同點:
- 介面只有定義,其方法不能在介面中實現,只有實現介面的類才能實現介面中定義的方法;而抽象類別可以有定義和實現,即其方法可以在抽象類別中被實現。
- 介面需要實現(用implement),但抽象類別只能被繼承(用extends),一個類可以實現多個介面,但是一個類只可以繼承一個抽象類別,因此使用介面可以間接達到多重繼承的目的。
- 介面強調特定功能的實現,"has - a" ;抽象類別強調所屬關係,"is - a "
- 介面中定義的成員變數預設為 public static final , 只能夠有靜態不能被修改的資料成員,而且,必須給其賦值,其所以的成員方法都是public,abstract的,而且只能被這兩個關鍵字修飾。而抽象類別可以有自己的資料成員變數,也可以有非抽象的成員方法,而且,抽象類別中的成員變數預設為default,當然也可以定義為private,protected,public。所以,當功能需要累積時,用抽象類別,不需要累積時,用介面。
- 介面被運用於實現比較常用的功能,便於以後的維護;抽象類別更傾向於充當公用類的角色,不適用於日後重新修改內部代碼。
Static class 與non static class的區別java多態的實現原理實現多線程的兩種方法:Thread與Runable線程同步的方法:sychronized、lock、reentrantLock等鎖的等級:方法鎖、對象鎖、類鎖
synchronized 在修飾代碼塊的時候需要一個reference對象作為鎖的對象。
在修飾方法的時候預設是當前對象作為鎖的對象。
在修飾類的時候預設是當前的Class對象作為鎖的對象。
線程同步的方法: sychronized、lock、reentrantLock分析
通過在方法聲明中加入synchronized關鍵字來聲明synchronized方法。
- 對象鎖(synchronized修飾方法或代碼塊)
當一個對象中有synchronized method 或 synchronized block 的時候調用此對象的同步方法或進入其同步地區時,就必須先獲得對象鎖,如何此對象的對象鎖已被其他調用者佔用,則需要等待此鎖被釋放。(方法鎖也是對象鎖)
寫出生產者消費者模式。ThreadLocal的設計理念與作用。ThreadPool用法與優勢。Concurrent包裡的其他東西:ArrayBlockingQueue、CountDownLatch等等。wait()和sleep()的區別
他們都是一種使線程暫停執行的方法
區別:
- 原理不同。sleep()是Thread類的靜態方法;wait()方法是Object類的方法。
- 對鎖的處理機制不同。sleep不放,wait釋放。
- 使用地區不同
- sleep()必須捕獲異常,wait()不需要
foreach與正常for迴圈效率對比Java IO與NIO。反射的作用與原理
反射機制能夠實現在運行時對類進行裝在,因此能增加程式的靈活性。
功能:
- 得到一個對象所屬的類;
- 擷取一個類所有的成員變數和方法;
- 在運行時建立對象
- 在運行時調用對象的方法
Java建立對象的方式有幾種
- 通過new執行個體化一個對象
- 通過反射機制建立對象
- clone()
- 還原序列化的方式
泛型常用特點,List
Java基礎-2