更新時(shí)間:2023-01-14 14:23:21 來(lái)源:動(dòng)力節(jié)點(diǎn) 瀏覽1595次
1、Java與C++的區(qū)別?
Java源碼會(huì)先經(jīng)過(guò)編譯器編譯成字節(jié)碼(class文件),然后由JVM中內(nèi)置的解釋器解釋成機(jī)器碼。而C++源碼直徑過(guò)一次編譯,直接在編譯的過(guò)程中鏈接了,形成機(jī)器碼
C++比Java執(zhí)行效率快,但是Java可以利用JVM跨平臺(tái)
Java是純面向?qū)ο蟮恼Z(yǔ)言,所有代碼都必須在勒種定義。而C++中還有面向過(guò)程的東西,比如全局變量和全局函數(shù)
C++中有指針,Java中沒(méi)有,但是有引用
C++支持多繼承,Java類(lèi)都是單繼承。但是繼承都有傳遞性,同時(shí)Java中的接口是多繼承,接口可以多實(shí)現(xiàn)
Java 中內(nèi)存的分配和回收由Java虛擬機(jī)實(shí)現(xiàn)。Java 中有垃圾自動(dòng)回收機(jī)制,會(huì)自動(dòng)清理引用數(shù)為0的對(duì)象。而在 C++ 編程時(shí),則需要花精力考慮如何避免內(nèi)存泄漏。
C++運(yùn)算符可以重載,但是Java中不可以。同時(shí)C++中支持強(qiáng)制自動(dòng)轉(zhuǎn)型,Java中不行,會(huì)出現(xiàn)ClassCastException(類(lèi)型不匹配)。
2、Java堆內(nèi)存和棧內(nèi)存的區(qū)別
Java把內(nèi)存分成兩種,一種叫做棧內(nèi)存,一種叫做堆內(nèi)存。
在函數(shù)中定義的一些基本類(lèi)型的變量和對(duì)象的引用變量都是在函數(shù)的棧內(nèi)存中分配。當(dāng)在一段代碼塊中定義一個(gè)變量時(shí),java就在棧中為這個(gè)變量分配內(nèi)存空間,當(dāng)超過(guò)變量的作用域后,java會(huì)自動(dòng)釋放掉為該變量分配的內(nèi)存空間,該內(nèi)存空間可以立刻被另作他用。
堆內(nèi)存用于存放由new創(chuàng)建的對(duì)象和數(shù)組。在堆中分配的內(nèi)存,由java虛擬機(jī)自動(dòng)垃圾回收器來(lái)管理。在堆中產(chǎn)生了一個(gè)數(shù)組或者對(duì)象后,還可以在棧中定義一個(gè)特殊的變量,這個(gè)變量的取值等于數(shù)組或者對(duì)象在堆內(nèi)存中的首地址,在棧中的這個(gè)特殊的變量就變成了數(shù)組或者對(duì)象的引用變量,以后就可以在程序中使用棧內(nèi)存中的引用變量來(lái)訪問(wèn)堆中的數(shù)組或者對(duì)象,引用變量相當(dāng)于為數(shù)組或者對(duì)象起的一個(gè)別名,或者代號(hào)。
引用變量是普通變量,定義時(shí)在棧中分配內(nèi)存,引用變量在程序運(yùn)行到作用域外釋放。而數(shù)組&對(duì)象本身在堆中分配,即使程序運(yùn)行到使用new產(chǎn)生數(shù)組和對(duì)象的語(yǔ)句所在地代碼塊之外,數(shù)組和對(duì)象本身占用的堆內(nèi)存也不會(huì)被釋放,數(shù)組和對(duì)象在沒(méi)有引用變量指向它的時(shí)候,才變成垃圾,不能再被使用,但是仍然占著內(nèi)存,在隨后的一個(gè)不確定的時(shí)間被垃圾回收器釋放掉。這個(gè)也是java比較占內(nèi)存的主要原因,實(shí)際上,棧中的變量指向堆內(nèi)存中的變量,這就是 Java 中的指針!
3、Java的垃圾回收機(jī)制,什么時(shí)候會(huì)出現(xiàn)Full GC
由于Java有垃圾回收機(jī)制,Java中的對(duì)象不再有“作用域”的概念,只有對(duì)象的引用才有“作用域”。垃圾回收可以有效的防止內(nèi)存泄露,有效的使用空閑的內(nèi)存。
ps:內(nèi)存泄露是指該內(nèi)存空間使用完畢之后未回收
什么情況下回導(dǎo)致內(nèi)存泄漏?
1.靜態(tài)集合類(lèi)像HashMap、Vector等的使用最容易出現(xiàn)內(nèi)存泄露,這些靜態(tài)變量的生命周期和應(yīng)用程序一致,所有的對(duì)象Object也不能被釋放,因?yàn)樗麄円矊⒁恢北籚ector等應(yīng)用著。
2.各種連接,數(shù)據(jù)庫(kù)連接,網(wǎng)絡(luò)連接,IO連接等沒(méi)有顯示調(diào)用close關(guān)閉,不被GC回收導(dǎo)致內(nèi)存泄露。
3.監(jiān)聽(tīng)器的使用,在釋放對(duì)象的同時(shí)沒(méi)有相應(yīng)刪除監(jiān)聽(tīng)器的時(shí)候也可能導(dǎo)致內(nèi)存泄露。
Java分代的垃圾回收策略,是基于這樣一個(gè)事實(shí):不同的對(duì)象的生命周期是不一樣的。因此,不同生命周期的對(duì)象可以采取不同的回收算法,以便提高回收效率。
分為三代:
①年輕代。
1.所有新生成的對(duì)象首先都是放在年輕代的。年輕代的目標(biāo)就是盡可能快速的收集掉那些生命周期短的對(duì)象。
2.新生代內(nèi)存按照8:1:1的比例分為一個(gè)eden區(qū)和兩個(gè)survivor(survivor0,survivor1)區(qū)。一個(gè)Eden區(qū),兩個(gè) Survivor區(qū)(一般而言)。大部分對(duì)象在Eden區(qū)中生成。回收時(shí)先將eden區(qū)存活對(duì)象復(fù)制到一個(gè)survivor0區(qū),然后清空eden區(qū),當(dāng)這個(gè)survivor0區(qū)也存放滿(mǎn)了時(shí),則將eden區(qū)和survivor0區(qū)存活對(duì)象復(fù)制到另一個(gè)survivor1區(qū),然后清空eden和這個(gè)survivor0區(qū),此時(shí)survivor0區(qū)是空的,然后將survivor0區(qū)和survivor1區(qū)交換,即保持survivor1區(qū)為空, 如此往復(fù)。
3.當(dāng)survivor1區(qū)不足以存放 eden和survivor0的存活對(duì)象時(shí),就將存活對(duì)象直接存放到老年代。若是老年代也滿(mǎn)了就會(huì)觸發(fā)一次Full GC,也就是新生代、老年代都進(jìn)行回收
4.新生代發(fā)生的GC也叫做Minor GC,MinorGC發(fā)生頻率比較高(不一定等Eden區(qū)滿(mǎn)了才觸發(fā))
②年老代。
1.在年輕代中經(jīng)歷了N次垃圾回收后仍然存活的對(duì)象,就會(huì)被放到年老代中。因此,可以認(rèn)為年老代中存放的都是一些生命周期較長(zhǎng)的對(duì)象。
2.內(nèi)存比新生代也大很多(大概比例是1:2),當(dāng)老年代內(nèi)存滿(mǎn)時(shí)觸發(fā)Major GC即Full GC,F(xiàn)ull GC發(fā)生頻率比較低,老年代對(duì)象存活時(shí)間比較長(zhǎng),存活率標(biāo)記高。
③持久代
用于存放靜態(tài)文件,如Java類(lèi)、方法等。持久代對(duì)垃圾回收沒(méi)有顯著影響,但是有些應(yīng)用可能動(dòng)態(tài)生成或者調(diào)用一些class,例如Hibernate 等,在這種時(shí)候需要設(shè)置一個(gè)比較大的持久代空間來(lái)存放這些運(yùn)行過(guò)程中新增的類(lèi)。
不同的收集器采用的算法不一樣,如復(fù)制算法,標(biāo)記-整理算法,標(biāo)記-復(fù)制算法,停止-復(fù)制算法。
新生代收集器使用的收集器:Serial(復(fù)制算法)、PraNew(停止-復(fù)制算法)、Parallel Scavenge(停止-復(fù)制算法)
老年代收集器使用的收集器:Serial Old(標(biāo)記-整理算法)、Parallel Old(停止-復(fù)制算法)、CMS(標(biāo)記-清理算法)。
由于對(duì)象進(jìn)行了分代處理,因此垃圾回收區(qū)域、時(shí)間也不一樣。
GC有兩種類(lèi)型:Scavenge GC和Full GC。
Scavenge GC
一般情況下,當(dāng)新對(duì)象生成,并且在Eden申請(qǐng)空間失敗時(shí),就會(huì)觸發(fā)Scavenge GC,對(duì)Eden區(qū)域進(jìn)行GC,清除非存活對(duì)象,并且把尚且存活的對(duì)象移動(dòng)到Survivor區(qū)。然后整理Survivor的兩個(gè)區(qū)。這種方式的GC是對(duì)年輕代的Eden區(qū)進(jìn)行,不會(huì)影響到年老代。因?yàn)榇蟛糠謱?duì)象都是從Eden區(qū)開(kāi)始的,同時(shí)Eden區(qū)不會(huì)分配的很大,所以Eden區(qū)的GC會(huì)頻繁進(jìn)行。因而,一般在這里需要使用速度快、效率高的算法,使Eden去能盡快空閑出來(lái)。
Full GC
對(duì)整個(gè)堆進(jìn)行整理,包括Young、Tenured和Perm。Full GC因?yàn)樾枰獙?duì)整個(gè)堆進(jìn)行回收,所以比Scavenge GC要慢,因此應(yīng)該盡可能減少Full GC的次數(shù)。在對(duì)JVM調(diào)優(yōu)的過(guò)程中,很大一部分工作就是對(duì)于FullGC的調(diào)節(jié)。
有如下原因可能導(dǎo)致Full GC:
1.年老代(Tenured)被寫(xiě)滿(mǎn)
2.持久代(Perm)被寫(xiě)滿(mǎn)
3.System.gc()被顯示調(diào)用
4.上一次GC之后Heap的各域分配策略動(dòng)態(tài)變化
以上就是“2023年精選出來(lái)的Java后端面試題”,你能回答上來(lái)嗎?如果想要了解更多的Java面試題相關(guān)內(nèi)容,可以關(guān)注動(dòng)力節(jié)點(diǎn)Java官網(wǎng)。
相關(guān)閱讀
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
有基礎(chǔ) 直達(dá)就業(yè)
業(yè)余時(shí)間 高薪轉(zhuǎn)行
工作1~3年,加薪神器
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問(wèn)老師會(huì)電話(huà)與您溝通安排學(xué)習(xí)