Java中常見面試題二(簡單)
HashMap和Hashtable的區(qū)別筋蓖?
- 線程是否安全: HashMap 是非線程安全的卸耘,Hashtable 是線程安全的,因為 Hashtable 內部的方法基本都經過synchronized 修飾。(如果你要保證線程安全的話就使用 ConcurrentHashMap 吧U晨А)
- 效率:因為Hashtable加了synchronized鎖蚣抗。所以HashMap 要比 Hashtable 效率高一點。另外瓮下,Hashtable 基本被淘汰翰铡,不要在代碼中使用它
- 對 Null key 和 Null value 的支持: HashMap 可以存儲 null 的 key 和 value,但 null 作為鍵只能有一個讽坏,null 作為值可以有多個锭魔;Hashtable 不允許有 null 鍵和 null 值,否則會拋出 NullPointerException路呜。
- 初始容量大小和每次擴充容量大小的不同 :① 創(chuàng)建時如果不指定容量初始值迷捧,Hashtable 默認的初始大小為 11,之后每次擴充胀葱,容量變?yōu)樵瓉淼?2n+1党涕。HashMap 默認的初始化大小為 16。之后每次擴充巡社,容量變?yōu)樵瓉淼?2 倍膛堤。② 創(chuàng)建時如果給定了容量初始值,那么 Hashtable 會直接使用你給定的大小晌该,而 HashMap 會將其擴充為 2 的冪次方大小肥荔。也就是說 HashMap 總是使用 2 的冪作為哈希表的大小绿渣。
- 底層數(shù)據(jù)結構: JDK1.8 以后的 HashMap 在解決哈希沖突時有了較大的變化,當鏈表長度大于閾值(默認為 8)(將鏈表轉換成紅黑樹前會判斷燕耿,如果當前數(shù)組的長度小于 64中符,那么會選擇先進行數(shù)組擴容,而不是轉換為紅黑樹)時誉帅,將鏈表轉化為紅黑樹淀散,以減少搜索時間。Hashtable 沒有這樣的機制蚜锨。
Spring事務的理解档插?
Spring支持編程式事務管理以及聲明式事務管理兩種方式
編程式事務管理
編程式事務管理是侵入性事務管理,使用TransactionTemplate或者直接使用PlatformTransactionManager亚再,對于編程式事務管理郭膛,Spring推薦使用TransactionTemplate。聲明式事務管理
聲明式事務管理建立在AOP之上氛悬,其本質是對方法前后進行攔截则剃,然后在目標方法開始之前創(chuàng)建或者加入一個事務,執(zhí)行完目標方法之后根據(jù)執(zhí)行的情況提交或者回滾如捅。
Java中會存在內存泄漏嗎棍现,請簡單描述
所謂內存泄露就是指一個不再被程序使用的對象或變量一直被占據(jù)在內存中。Java中有垃圾回收機制镜遣,它可以保證一對象不再被引用的時候轴咱,即對象變成了孤兒的時候,對象將自動被垃圾回收器從內存中清除掉烈涮。由于Java使用有向圖的方式進行垃圾回收管理,可 以消除引用循環(huán)的問題,
例如有兩個對象窖剑,相互引用坚洽,只要它們和根進程不可達的,那么GC也是可以回收它們的西土,例如下面的代碼可以看到這種情況的內存回收讶舰。
Java中的內存泄露的情況:長生命周期的對象持有短生命周期對象的引用就很可能發(fā)生內存泄露,盡管短生命周期對象已經不再需要需了,但是因為長生命周期對象持有它的引用而導致不能被回收跳昼,這就是Java中內存泄露的發(fā)生場景,通俗地說肋乍,就是程序員可能創(chuàng)建了一個對象鹅颊,以后一直不再使用這個對象,這個對象卻一直被引用墓造,即這個對象無用但是卻無法被垃圾回收器回收的堪伍,這就是java中可能出現(xiàn)內存泄露的情況锚烦,例如,緩存系統(tǒng)帝雇,我們加載了一個對象放在緩存中(例如放在一個全局map對象中),然后一直不再使用它涮俄,這個對象一直被緩存引用,但卻不再被使用尸闸。
檢查Java中的內存泄露彻亲,一定要讓程序將各種分支情況都完整執(zhí)行到程序結束,然后看某個對象是否被使用過吮廉,如果沒有苞尝,則才能判定這個對象屬于內存泄露。
如果一個外部類的實例對象的方法返回了一個內部類的實例對象茧痕,這個內部類對象被長期引用了野来,即使那個外部類實例對象不再被使用,但由于內部類持久外部類的實例對象踪旷,這個外部類對象將不會被垃圾回收曼氛,這也會造成內存泄露。
GC是什么?為什么要有GC?
GC是垃圾收集的意思(GabageCollection)令野,內存處理是編程人員容易出現(xiàn)問題的地方舀患,忘記或者錯誤的內存回收會導致程序或系統(tǒng)的不穩(wěn)定甚至崩潰,Java提供的GC功能可以自動監(jiān)測對象是否超過作用域從而達到自動回收內存的目的气破,Java 語言沒有提供釋放已分配內存的顯示操作方法聊浅。
簡述Java垃圾回收機制
在Java中,程序員是不需要顯示的去釋放一個對象的內存的现使,而是由虛擬機自行執(zhí)行低匙。在JVM中,有一個垃圾回收線程碳锈,它是低優(yōu)先級的顽冶,在正常情況下是不會執(zhí)行的,只有在虛擬機空閑或者當前堆內存不足時售碳,才會觸發(fā)執(zhí)行强重,掃面那些沒有被任何引用的對象,并將它們添加到要回收的集合中贸人,進行回收间景。
垃圾回收的優(yōu)點和原理。并考慮2種回收機制
Java語言中一個顯著的特點就是引入了垃圾回收機制艺智,使C++程序員最頭疼的內存管理的問題迎刃而解倘要,它使得Java程序員在編寫程序的時候不再需要考慮內存管理。
由于有個垃圾回收機制十拣,Java 中的對象不再有“作用域”的概念碗誉,只有對象的引用才有"作用域"召嘶。垃圾回收可以有效的防止內存泄露,有效的使用可以使用的內存哮缺。
垃圾回收器通常是作為一個單獨的低級別的線程運行弄跌,不可預知的情況下對內存堆中已經死亡的或者長時間沒有使用的對象進行清楚和回收,程序員不能實時的調用垃圾回收器對某個對象或所有對象進行垃圾回收尝苇。
回收機制有分代復制垃圾回收铛只、標記垃圾回收、增量垃圾回收糠溜。
深拷貝和淺拷貝是什么淳玩?
簡單來講就是復制、克隆非竿。
淺拷貝就是對對象中的數(shù)據(jù)成員進行簡單賦值蜕着,如果存在動態(tài)成員或者指針就會報錯。而且红柱,如果有引用類型的變量承匣,新生成的對象和被拷貝的對象的這個屬性會指向同一個地方,沒有解耦锤悄,會影響對方韧骗,兩個對象會擁有一樣的值(穿一條褲子)。對基本數(shù)據(jù)類型來說零聚,兩邊是獨立的袍暴。
深拷貝就是對對象中存在的動態(tài)成員或指針重新開辟內存空間。而且隶症,如果有引用類型的變量政模,新生成的對象和被拷貝的對象的這個屬性會指向兩個地方,解耦了蚂会,不會影響對方淋样,兩個對象分別做修改的話,不會影響到對方颂龙。
什么是分布式垃圾回收(DGC)?它是如何工作的?
DGC叫做分布式垃圾回收。
RMI使用DGC來做自動垃圾回收纽什。因為 RMI包含了跨虛擬機的遠程對象的引用措嵌,垃圾回收是很困難的。DGC使用引用計數(shù)算法來給遠程對象提供自動內存管理芦缰。
簡述Java內存分配與回收策率以及Minor GC和Major GC
- 對象優(yōu)先在堆的Eden區(qū)分配
- 大對象直接進入老年代
- 長期存活的對象將直接進入老年代
- 當Eden區(qū)沒有足夠的空間進行分配時企巢,虛擬機會執(zhí)行一次Minor GC。
- Minor GC通常發(fā)生在新生代的Eden區(qū)让蕾,在這個區(qū)的對象生存期短浪规,往往發(fā)生Gc的頻率較高或听,回收速度比較快;
- Full GC/Major GC發(fā)生在老年代,一般情況下笋婿,觸發(fā)老年代GC的時候不會觸發(fā)Minor GC,但是通過配置誉裆,可以在Full GC之前進行一次Minor GC這樣可以加快老年代的回收速度。