更多技術分享,請點擊右上角紅色的"關注",感謝你的支持!
本文接上篇, ,只是給大家一個提醒引入,將40道題目題幹羅列供大家先自學,接下來的後續文章將把前文的題目一一解答,答案其實也都來自於網上,這裡只是進行一些歸納整理和總結。40道題目都是比較高頻的基礎面試題,並不能囊括所有的面試重點,其他的更多面試題目要靠小夥伴們自己努力去搜集,並將之攻克了。
1.Java的基本數據類型幾個,都是什麼以及大小,以及他們的封裝類有哪些?
8種基本數據類型:int、short、float、double、long、boolean、byte、char。
封裝類型對應為:Integer、Short、Float、Double、Long、Boolean、Byte、Character。
2.什麼是引用數據類型?
引用數據類型,是由類的編譯器定義的,用於訪問對象。這些變量被定義為不可更改的特定類型。
當一個變量值為引用類型的時候,直接賦值其他變量傳遞的是引用。
同樣的,引用的數據在某個地方改變了值會影響所有調用這個變量的地方。
例如:Employee, Puppy 等等
類對象和數組變量就是這種引用數據類型。
任何引用數據類型的默認值都為null。
一個引用數據類型可以被用於任何聲明類型和兼容類型的對象。
3.條件語句中switch句柄,能否用string做為參數?
在jdk1.7之前,switch 只能支持 byte、short、char、int 這幾個基本數據類型和其對應的封裝類型。
switch後面的括號裡面只能放int類型的值,但由於byte,short,char類型,它們會自動轉換為int類型(精度小的向大的轉化),所以這些現在都支持了。
例如,
jdk1.7後,
整型(int),枚舉類,字符串(string)都可以支持有個疑問,jdk1.7後又可以用string類型作為switch參數呢?
本質上是,jdk1.7並沒有新的指令來處理switch string,而是通過調用switch中string.hashCode,將string轉換為int從而進行判斷。
4.equals與==的區別是什麼?
使用==比較基本數據類型如:boolean、int、char等等,equals()用來比較對象是否為同一個。
1、==是判斷兩個變量或實例是不是指向同一個內存空間;
equals是判斷兩個變量或實例所指向的內存空間的值是不是相同。
2、==是指對內存地址進行比較;equals()是對字符串的內容進行比較。
3、==指引用是否相同; equals()指的是值是否相同。
直接看代碼更清晰:
5.什麼是自動裝箱?常量池又是什麼?
自動裝箱 在jdk1.5之前,如果你想要定義一個value為100的Integer對象,則需要如下定義:
上面的代碼中,intNum2為一個Integer類型的實例,intNum1為Java中的基礎數據類型,將intNum1賦值給intNum2的過程就是自動裝箱;而將intNum2賦值給intNum3得過程則是自動拆箱。這是一個相反的過程。
8種基本數據類型: boolean byte char shrot int long float double ,所生成的變量相當於常量。
對應的基本類型包裝類:Boolean Byte Character Short Integer Long Float Double。
自動拆箱和自動裝箱定義:
自動裝箱是將一個java定義的基本數據類型賦值給相應封裝類的變量。拆箱與裝箱是相反的操作,自動拆箱則是將一個封裝類的變量賦值給相應基本數據類型的變量。
6.Object都有什麼公用的方法?
Object是所有類的父類,任何類都默認繼承Object
clone方法,實現對象的淺複製,當實現了Cloneable接口才可以調用該方法,否則會拋出異常,類型為CloneNotSupportedException。
equals在Object中與==是一樣的,子類一般需要重寫該方法。
hashCode該方法用於哈希查找,重寫了equals方法一般都要重寫hashCode方法。這個方法在一些具有哈希功能的Collection中用到。
getClassfinal方法,獲得運行時類型
wait使當前線程等待該對象的鎖,當前線程必須是該對象的擁有者,也就是具有該對象的鎖。wait() 方法一直等待,直到獲得鎖或者被中斷。wait(long timeout) 設定一個超時間隔,如果在規定時間內沒有獲得鎖就返回。
調用該方法後當前線程進入睡眠狀態,直到以下事件發生
1、其他線程調用了該對象的notify方法。
2、其他線程調用了該對象的notifyAll方法。
3、其他線程調用了interrupt中斷該線程。
4、時間間隔到了。
5、此時該線程就可以被調度了,如果是被中斷的話就拋出一個InterruptedException異常。
notify喚醒在該對象上等待的某個線程。
notifyAll喚醒在該對象上等待的所有線程。
toString轉換成字符串,一般子類都有重寫,否則打印句柄。
7.Java的四種級別的引用都有什麼?以及對應的引用場景在哪裡?
從JDK1.2版本開始,把對象的引用分為四種級別,從而使程序能更加靈活的控制對象的生命週期。這四種級別由高到低依次為:強引用、軟引用、弱引用和虛引用。
1、強引用
最普遍的一種引用方式,如String s = "abc",變量s就是字符串“abc”的強引用,只要強引用存在,則垃圾回收器就不會回收這個對象。
2、軟引用(SoftReference)
用於描述還有用但非必須的對象,如果內存足夠,不回收,如果內存不足,則回收。一般用於實現內存敏感的高速緩存,軟引用可以和引用隊列ReferenceQueue聯合使用,如果軟引用的對象被垃圾回收,JVM就會把這個軟引用加入到與之關聯的引用隊列中。
3、弱引用(WeakReference)
弱引用和軟引用大致相同,弱引用與軟引用的區別在於:只具有弱引用的對象擁有更短暫的生命週期。在垃圾回收器線程掃描它所管轄的內存區域的過程中,一旦發現了只具有弱引用的對象,不管當前內存空間足夠與否,都會回收它的內存。
4、虛引用(PhantomReference)
就是形同虛設,與其他幾種引用都不同,虛引用並不會決定對象的生命週期。如果一個對象僅持有虛引用,那麼它就和沒有任何引用一樣,在任何時候都可能被垃圾回收器回收。 虛引用主要用來跟蹤對象被垃圾回收器回收的活動。
虛引用與軟引用和弱引用的一個區別在於:
虛引用必須和引用隊列 (ReferenceQueue)聯合使用。當垃圾回收器準備回收一個對象時,如果發現它還有虛引,就會在回收對象的內存之前,把這個虛引用加入到與之關聯的引用隊列中。
8.Java中Hashcode的作用是什麼?
1、HashCode的特性
(1)HashCode的存在主要是用於查找的快捷性,如Hashtable,HashMap等,HashCode經常用於確定對象的存儲地址。
(2)如果兩個對象相同,equals方法一定返回true,並且這兩個對象的HashCode一定相同。
(3)兩個對象的HashCode相同,並不一定表示兩個對象就相同,即equals()不一定為true,只能夠說明這兩個對象在一個散列存儲結構中。
(4)如果對象的equals方法被重寫,那麼對象的HashCode也應該重寫。
2、HashCode作用
Java中的集合有兩類,一類是List ,再有一類是Set。前者集合內的元素是有序的,元素可以重複;後者元素無序,但元素不可重複。
equals方法可用於保證元素不重複,但如果每增加一個元素就檢查一次,若集合中現在已經有1000個元素,那麼第1001個元素加入集合時,就要調用1000次equals方法。這顯然會大大降低效率。?於是,Java採用了哈希表的原理。
哈希算法也稱為散列算法,是將數據依特定算法直接指定到一個地址上。
這樣一來,當集合要添加新的元素時,先調用這個元素的HashCode方法,就一下子能定位到它應該放置的物理位置上。
(1)如果這個位置上沒有元素,它就可以直接存儲在這個位置上,不用再進行任何比較了。
(2)如果這個位置上已經有元素了,就調用它的equals方法與新元素進行比較,相同的話就不存了。
(3)不相同的話,也就是發生了Hash key相同導致衝突的情況,那麼就在這個Hash key的地方產生一個鏈表,將所有產生相同HashCode的對象放到這個單鏈表上去,串在一起(很少出現)。
這樣一來實際調用equals方法的次數就大大降低了,幾乎只需要一兩次。
如何理解HashCode的作用:
從Object角度看,JVM每new一個Object,它都會將這個Object丟到一個Hash表中去,這樣的話,下次做Object的比較或者取這個對象的時候(讀取過程),它會根據對象的HashCode再從Hash表中取這個對象。這樣做的目的是提高取對象的效率。若HashCode相同再去調用equal。
3、HashCode實踐(如何用來查找)
HashCode是用於查找使用的,而equals是用於比較兩個對象是否相等的。
(1)例如內存中有這樣的位置
0 1 2 3 4 5 6 7
而我有個類,這個類有個字段叫ID,我要把這個類存放在以上8個位置之一,如果不用HashCode而任意存放,那麼當查找時就需要到這八個位置裡挨個去找,或者用二分法一類的算法。
但以上問題如果用HashCode就會使效率提高很多定義我們的HashCode為ID%8,比如我們的ID為9,9除8的餘數為1,那麼我們就把該類存在1這個位置,如果ID是13,求得的餘數是5,那麼我們就把該類放在5這個位置。依此類推。
(2)但是如果兩個類有相同的HashCode,例如9除以8和17除以8的餘數都是1,也就是說,我們先通過?HashCode來判斷兩個類是否存放某個桶裡,但這個桶裡可能有很多類,那麼我們就需要再通過equals在這個桶裡找到我們要的類。
看一下下邊的代碼:
輸出是:
true
false
[HashTest@1, HashTest@1]
以上這個示例,我們只是重寫了HashCode方法,從上面的結果可以看出,雖然兩個對象的HashCode相等,但是實際上兩個對象並不是相等,因為我們沒有重寫equals方法,那麼就會調用Object默認的equals方法,顯示這是兩個不同的對象。
這裡我們將生成的對象放到了HashSet中,而HashSet中只能夠存放唯一的對象,也就是相同的(適用於equals方法)的對象只會存放一個,但是這裡實際上是兩個對象ab都被放到了HashSet中,這樣HashSet就失去了他本身的意義了。
把equals方法重寫如下:
輸出如下:
true
true
[HashTest@1]
可以看到,兩個對象已經完全相等了,在HashSet中也只存放了一份對象。
注意:hashCode()只是簡單舉例,實際的生產環境中一般不這樣做
閱讀更多 程序碼上說 的文章