(一)Java部分
1涣雕、列舉出JAVA中6個(gè)比較常用的包【天威誠(chéng)信面試題】
【參考答案】
java.lang;java.util;java.io;java.sql;java.awt;java.net;javax.swing
2、JDK中哪些類(lèi)是不能繼承的?【信雅達(dá)面試題】
【參考答案】
不能繼承的是類(lèi)是那些用final關(guān)鍵字修飾的類(lèi)娩怎。一般比較基本的類(lèi)型或防止擴(kuò)展類(lèi)無(wú)意間破壞原來(lái)方法的實(shí)現(xiàn)的類(lèi)型都應(yīng)該是final的。
3、String是最基本的數(shù)據(jù)類(lèi)型嗎?【天能智健面試題】
【參考答案】
基本數(shù)據(jù)類(lèi)型包括byte、int耳贬、char、long猎唁、float咒劲、double、boolean和short诫隅。
所以String不屬于基本數(shù)據(jù)類(lèi)型范疇內(nèi)腐魂,但String屬于最常見(jiàn)一種引用類(lèi)型。
4阎肝、short s1 = 1; s1 = s1 + 1;有什么錯(cuò)? short s1 = 1; s1 += 1;有什么錯(cuò)?【博炎科技面試題】
【參考答案】
對(duì)于short s1 = 1; s1 = s1 + 1;由于s1+1運(yùn)算時(shí)會(huì)自動(dòng)提升表達(dá)式的類(lèi)型挤渔,所以結(jié)果是int型,再賦值給short類(lèi)型s1時(shí)风题,編譯器會(huì)提示錯(cuò)誤,需要強(qiáng)制轉(zhuǎn)換類(lèi)型嫉父。
對(duì)于short s1 = 1; s1 += 1;由于+=是java語(yǔ)言規(guī)定的運(yùn)算符沛硅,Java編譯器會(huì)對(duì)它進(jìn)行特殊處理,因此可以正確編譯绕辖。
【分析】
主要考查幾種基本數(shù)據(jù)類(lèi)型在運(yùn)算時(shí)的摇肌,由低到高會(huì)自動(dòng)轉(zhuǎn)換,而由高到低時(shí)會(huì)強(qiáng)制轉(zhuǎn)換仪际。
5围小、Java對(duì)象初始化順序?【騰鵬科技面試題】
【參考答案】
分為兩種树碱,一種是本類(lèi)的初始化肯适,一種是含有父類(lèi)的初始化順序。這里分開(kāi)來(lái)說(shuō)成榜,
本類(lèi)的初始化順序是:靜態(tài)變量框舔、靜態(tài)初始化塊、變量、初始化塊刘绣、構(gòu)造函數(shù)
繼承類(lèi)的初始化順序是:父類(lèi)靜態(tài)變量樱溉、父類(lèi)靜態(tài)初始化塊、子類(lèi)靜態(tài)變量纬凤、子類(lèi)靜態(tài)初始?jí)K福贞、父類(lèi)變量、父類(lèi)初始化塊停士、父類(lèi)構(gòu)造函數(shù)肚医、子類(lèi)變量、子類(lèi)初始化塊向瓷、子類(lèi)構(gòu)造函數(shù)肠套。
【分析】
static{
System.out.println("靜態(tài)塊");
}
{
System.out.println("初始化模塊"); }
public ClassName() {
System.out.println("構(gòu)造方法");
}
說(shuō)明:
原則上回答全面的話(huà),應(yīng)該是完整的說(shuō)出帶有繼承的這種類(lèi)的初始化過(guò)程猖任,下面有個(gè)步驟可以參考:
1.裝載程序的時(shí)候首先找到的是它的基(父)類(lèi),如果有多層基(父)類(lèi)則會(huì)一級(jí)一級(jí)的往上找最后找到根基(父)類(lèi)你稚。
2.執(zhí)行根基礎(chǔ)(父)類(lèi)中的static初始化,再執(zhí)行下一個(gè)衍生類(lèi)中的static,依此類(lèi)推,一直保持這個(gè)順序。
3.此時(shí)類(lèi)已經(jīng)裝載完畢,開(kāi)始創(chuàng)建對(duì)象,所有的基本數(shù)據(jù)類(lèi)型都會(huì)設(shè)成它們的默認(rèn)值,對(duì)象句柄設(shè)為null
4.調(diào)用基礎(chǔ)(父)類(lèi)的構(gòu)造方法,基礎(chǔ)(父)類(lèi)的構(gòu)建采用與衍生類(lèi)構(gòu)造方法完全相同的處理過(guò)程朱躺。
5.構(gòu)造方法初始完之后,進(jìn)行變量的初始化刁赖。
6.執(zhí)行構(gòu)造方法中剩余的部分。
6长搀、寫(xiě)幾個(gè)線程安全類(lèi)宇弛,不安全的,支持排序的類(lèi)名源请?【軟通動(dòng)力面試題】
【參考答案】
?線程安全類(lèi):Vector枪芒、Hashtable、Stack谁尸。
?線程不安全的類(lèi):ArrayList舅踪、Linkedlist、HashSet良蛮、TreeSet抽碌、HashMap、TreeMap等决瞳。
?支持排序的類(lèi)有HashSet货徙、LinkedHashSet、TreeSet等(Set接口下的實(shí)現(xiàn)都支持排序)
【分析】
此題主要考查集合框架的知識(shí)皮胡。在集合框架中Collection接口為集合的根類(lèi)型痴颊,提供集合操作的常用API方法,該接口下派生出兩個(gè)子接口胸囱,一個(gè)是不支持排序的List接口祷舀,一個(gè)是有自身排序的Set接口,所以回答排序與不排序分別從兩接口的實(shí)現(xiàn)中在作答。線程安全上來(lái)說(shuō)裳扯,Vector類(lèi)比同屬于List接口的ArrayList要早抛丽,是一個(gè)線程安全的類(lèi),在JDK1.2以后才推出一個(gè)異步的ArrayList類(lèi)饰豺,比Vector類(lèi)效率高亿鲜。同理Stack繼承自Vector也線程安全的類(lèi),另外在在Map接口的實(shí)現(xiàn)在Hashtable也是個(gè)線程安全的類(lèi)冤吨。
7蒿柳、哪幾個(gè)方法可以實(shí)現(xiàn)一個(gè)線程?【上海華信面試題】
【參考答案】
一是繼承Thread漩蟆,重寫(xiě)Thread類(lèi)的方法run方法垒探;另種是實(shí)現(xiàn)runnable接口并實(shí)現(xiàn)run方法。
【分析】
考查線程的基本實(shí)現(xiàn)怠李,很多公司喜歡考查這方面知識(shí)圾叼,另外補(bǔ)充一下關(guān)于線程的run方法,在多線程API中啟動(dòng)一個(gè)線程是調(diào)用start()方法捺癞,線程進(jìn)入就緒狀態(tài)滚澜。
8申窘、STOP()和SUSPEND()不推薦使用的原因耽装?
【參考答案】
stop()是因?yàn)樗话踩渌丁K鼤?huì)解除由線程獲取的所有鎖定,當(dāng)在一個(gè)線程對(duì)象上調(diào)用stop()方法時(shí)唐础,這個(gè)線程對(duì)象所運(yùn)行的線程就會(huì)立即停止箱歧,假如一個(gè)線程正在執(zhí)行:synchronized void { x = 3; y = 4;}由于方法是同步的,多個(gè)線程訪問(wèn)時(shí)總能保證x,y被同時(shí)賦值彻犁,而如果一個(gè)線程正在執(zhí)行到x = 3;時(shí)叫胁,被調(diào)用了stop()方法,即使在同步塊中汞幢,它也干脆地stop了,這樣就產(chǎn)生了不完整的殘廢數(shù)據(jù)微谓。而多線程編程中最最基礎(chǔ)的條件要保證數(shù)據(jù)的完整性森篷,所以請(qǐng)忘記線程的stop方法,以后我們?cè)僖膊灰f(shuō)“停止線程”了豺型。而且如果對(duì)象處于一種不連貫狀態(tài)仲智,那么其他線程能在那種狀態(tài)下檢查和修改它們。
suspend()方法容易發(fā)生死鎖姻氨。調(diào)用suspend()的時(shí)候钓辆,目標(biāo)線程會(huì)停下來(lái),但卻仍然持有在這之前獲得的鎖定。此時(shí)前联,其他任何線程都不能訪問(wèn)鎖定的資源功戚,除非被"掛起"的線程恢復(fù)運(yùn)行。對(duì)任何線程來(lái)說(shuō)似嗤,如果它們想恢復(fù)目標(biāo)線程啸臀,同時(shí)又試圖使用任何一個(gè)鎖定的資源,就會(huì)造成死鎖烁落。所以不應(yīng)該使用suspend()乘粒,而應(yīng)在自己的Thread類(lèi)中置入一個(gè)標(biāo)志,指出線程應(yīng)該活動(dòng)還是掛起伤塌。若標(biāo)志指出線程應(yīng)該掛起灯萍,便用wait()命其進(jìn)入等待狀態(tài)。若標(biāo)志指出線程應(yīng)當(dāng)恢復(fù)每聪,則用一個(gè)notify()重新啟動(dòng)線程旦棉。
【分析】
9、"=="和equals方法有什么區(qū)別熊痴?【中科軟】
【參考答案】
==操作符專(zhuān)門(mén)用來(lái)比較兩個(gè)變量的值是否相等他爸,也就是用于比較變量所對(duì)應(yīng)的內(nèi)存中所存儲(chǔ)的數(shù)值是否相同,要比較兩個(gè)基本類(lèi)型的數(shù)據(jù)或兩個(gè)引用變量是否相等果善,只能用==操作符诊笤。
如果一個(gè)變量指向的數(shù)據(jù)是對(duì)象類(lèi)型的,那么巾陕,這時(shí)候涉及了兩塊內(nèi)存讨跟,對(duì)象本身占用一塊內(nèi)存(堆內(nèi)存),變量也占用一塊內(nèi)存鄙煤,例如Objet obj = new Object();變量obj是一個(gè)內(nèi)存晾匠,new Object()是另一個(gè)內(nèi)存,此時(shí)梯刚,變量obj所對(duì)應(yīng)的內(nèi)存中存儲(chǔ)的數(shù)值就是對(duì)象占用的那塊內(nèi)存的首地址凉馆。對(duì)于指向?qū)ο箢?lèi)型的變量,如果要比較兩個(gè)變量是否指向同一個(gè)對(duì)象亡资,即要看這兩個(gè)變量所對(duì)應(yīng)的內(nèi)存中的數(shù)值是否相等澜共,這時(shí)候就需要用==操作符進(jìn)行比較。
equals方法是用于比較兩個(gè)獨(dú)立對(duì)象的內(nèi)容是否相同锥腻,就好比去比較兩個(gè)人的長(zhǎng)相是否相同嗦董,它比較的兩個(gè)對(duì)象是獨(dú)立的。例如瘦黑,對(duì)于下面的代碼:
String?a=new?String("foo");
String?b=new?String("foo");
兩條new語(yǔ)句創(chuàng)建了兩個(gè)對(duì)象京革,然后用a,b這兩個(gè)變量分別指向了其中一個(gè)對(duì)象奇唤,這是兩個(gè)不同的對(duì)象,它們的首地址是不同的匹摇,即a和b中存儲(chǔ)的數(shù)值是不相同的咬扇,所以,表達(dá)式a==b將返回false来惧,而這兩個(gè)對(duì)象中的內(nèi)容是相同的冗栗,所以,表達(dá)式a.equals(b)將返回true供搀。
在實(shí)際開(kāi)發(fā)中隅居,我們經(jīng)常要比較傳遞進(jìn)行來(lái)的字符串內(nèi)容是否等,例如葛虐,String input =…;input.equals(“quit”)胎源,如果一個(gè)類(lèi)沒(méi)有自己定義equals方法,那么它將繼承Object類(lèi)的equals方法屿脐,Object類(lèi)的equals方法的實(shí)現(xiàn)代碼如下:
boolean?equals(Object?o){
return?this==o;
}
這說(shuō)明涕蚤,如果一個(gè)類(lèi)沒(méi)有自己定義equals方法,它默認(rèn)的equals方法(從Object類(lèi)繼承的)就是使用==操作符的诵,也是在比較兩個(gè)變量指向的對(duì)象是否是同一對(duì)象万栅,這時(shí)候使用equals和使用==會(huì)得到同樣的結(jié)果,如果比較的是兩個(gè)獨(dú)立的對(duì)象則總返回false西疤。如果你編寫(xiě)的類(lèi)希望能夠比較該類(lèi)創(chuàng)建的兩個(gè)實(shí)例對(duì)象的內(nèi)容是否相同烦粒,那么你必須覆蓋equals方法,由你自己寫(xiě)代碼來(lái)決定在什么情況即可認(rèn)為兩個(gè)對(duì)象的內(nèi)容是相同的代赁。
10扰她、靜態(tài)變量和實(shí)例變量的區(qū)別?
【參考答案】
在語(yǔ)法定義上的區(qū)別:靜態(tài)變量前要加static關(guān)鍵字芭碍,而實(shí)例變量前則不加徒役。
在程序運(yùn)行時(shí)的區(qū)別:實(shí)例變量屬于某個(gè)對(duì)象的屬性,必須創(chuàng)建了實(shí)例對(duì)象窖壕,其中的實(shí)例變量才會(huì)被分配空間忧勿,才能使用這個(gè)實(shí)例變量。靜態(tài)變量不屬于某個(gè)實(shí)例對(duì)象瞻讽,而是屬于類(lèi)狐蜕,所以也稱(chēng)為類(lèi)變量,只要程序加載了類(lèi)的字節(jié)碼卸夕,不用創(chuàng)建任何實(shí)例對(duì)象,靜態(tài)變量就會(huì)被分配空間婆瓜,靜態(tài)變量就可以被使用了快集」备幔總之,實(shí)例變量必須創(chuàng)建對(duì)象后才可以通過(guò)這個(gè)對(duì)象來(lái)使用个初,靜態(tài)變量則可以直接使用類(lèi)名來(lái)引用乖寒。
例如,對(duì)于下面的程序院溺,無(wú)論創(chuàng)建多少個(gè)實(shí)例對(duì)象楣嘁,永遠(yuǎn)都只分配了一個(gè)staticVar變量珍逸,并且每創(chuàng)建一個(gè)實(shí)例對(duì)象,這個(gè)staticVar就會(huì)加1叭爱;但是著觉,每創(chuàng)建一個(gè)實(shí)例對(duì)象古掏,就會(huì)分配一個(gè)instanceVar,即可能分配多個(gè)instanceVar,并且每個(gè)instanceVar的值都只自加了1次皆愉。
public class VariantTest
{
public static int staticVar = 0;
public int instanceVar = 0;
public VariantTest()
{
staticVar++;
instanceVar++;
System.out.println(“staticVar=”+ staticVar +”,instanceVar=”+ instanceVar);
}
}
備注:這個(gè)解答除了說(shuō)清楚兩者的區(qū)別外,最后還用一個(gè)具體的應(yīng)用例子來(lái)說(shuō)明兩者的差異辣吃,體現(xiàn)了自己有很好的解說(shuō)問(wèn)題和設(shè)計(jì)案例的能力硬猫,思維敏捷,超過(guò)一般程序員改执,有寫(xiě)作能力啸蜜!
11、構(gòu)造器的名能不能和類(lèi)的名字相同辈挂?
【參考答案】
構(gòu)造器的名稱(chēng)必須與類(lèi)名相同衬横。
【分析】
構(gòu)造器或構(gòu)造函數(shù)(有些書(shū)這樣叫)主要用來(lái)對(duì)類(lèi)的成員變量進(jìn)行初始化,當(dāng)類(lèi)創(chuàng)建實(shí)例時(shí)調(diào)用呢岗。
12冕香、在一個(gè)主方法類(lèi)可不可以調(diào)用一個(gè)非靜態(tài)的方法?
【參考答案】
可以調(diào)用后豫。因?yàn)镴ava的主方法(main)方法本身也是static類(lèi)型方法悉尾,一個(gè)static類(lèi)型方法,發(fā)起對(duì)另一個(gè)static方法的調(diào)用沒(méi)有問(wèn)題挫酿。
【分析】
靜態(tài)方法可以調(diào)用其它的靜態(tài)方法构眯,但是不能調(diào)用非靜態(tài)方法,這個(gè)好比Java中的類(lèi)變量與實(shí)例變量的關(guān)系早龟。類(lèi)變量是被所有類(lèi)成員共享惫霸,而實(shí)例變量只被該實(shí)例共享猫缭,
13、一個(gè)類(lèi)中可不可以有2個(gè)公共的方法壹店?
【參考答案】
可以猜丹。Java中對(duì)公共方法的個(gè)數(shù)沒(méi)有約束,但是對(duì)公共的類(lèi)有約束硅卢,一個(gè)Java源文件中只能定義一個(gè)public類(lèi)型的類(lèi)射窒。
14、GC是什么将塑,為什么要使用它脉顿?【阿斯拓】
【參考答案】
GC是垃圾收集的意思(Gabage Collection),內(nèi)存處理是編程人員容易出現(xiàn)問(wèn)題的地方,忘記或者錯(cuò)誤的內(nèi)存回收會(huì)導(dǎo)致程序或系統(tǒng)的不穩(wěn)定甚至崩潰点寥,Java提供的GC功能可以自動(dòng)監(jiān)測(cè)對(duì)象是否超過(guò)作用域艾疟,從而達(dá)到自動(dòng)回收內(nèi)存的目的,Java語(yǔ)言沒(méi)有提供釋放已分配內(nèi)存的顯示操作方法敢辩。
【分析】
15蔽莱、說(shuō)一下垃圾回收的原理,可以直接從內(nèi)存中回收嗎?
【參考答案】
Java語(yǔ)言中一個(gè)顯著的特點(diǎn)就是引入了垃圾回收機(jī)制责鳍,使c++程序員最頭疼的內(nèi)存管理的問(wèn)題迎刃而解碾褂,它使得Java程序員在編寫(xiě)程序的時(shí)候不再需要考慮內(nèi)存管理。垃圾回收可以有效的防止內(nèi)存泄露历葛,有效的使用可以使用的內(nèi)存正塌。垃圾回收器通常是作為一個(gè)單獨(dú)的低級(jí)別的線程運(yùn)行,不可預(yù)知的情況下對(duì)內(nèi)存堆中已經(jīng)死亡的或者長(zhǎng)時(shí)間沒(méi)有使用的對(duì)象進(jìn)行清除和回收恤溶,程序員不能實(shí)時(shí)的調(diào)用垃圾回收器對(duì)某個(gè)對(duì)象或所有對(duì)象進(jìn)行垃圾回收,因?yàn)镴ava語(yǔ)言規(guī)范并不保證GC一定會(huì)執(zhí)行乓诽。回收機(jī)制有分代復(fù)制垃圾回收和標(biāo)記垃圾回收咒程,增量垃圾回收鸠天。
【分析】
16、Java的異常有哪幾種帐姻,有什么區(qū)別稠集?
【參考答案】
兩大類(lèi),一般異常和運(yùn)行時(shí)異常饥瓷。一般異常剥纷,這些異常是在定義方法時(shí)聲明拋出的,這些異常必需用try catch拋出呢铆,或throws處理晦鞋,如果不處理,程序?qū)⒕幾g失敗。比如:IOException悠垛、FileNotFoundException线定、SQLException等。
運(yùn)行時(shí)異常是程序運(yùn)行時(shí)可能報(bào)出的異常确买〗锛ィ可以用try catch抓取,也可以不做任何處理拇惋。例如:NullPointerException異常就是一種比較常見(jiàn)的運(yùn)行時(shí)異常周偎。
【分析】
17、switch語(yǔ)句能否作用在byte上撑帖,能否作用在long上,能否作用在String上?
【參考答案】
在switch(表達(dá)式)中澳眷,括號(hào)表達(dá)式只能是一個(gè)整數(shù)表達(dá)式或者枚舉常量(更大字體)胡嘿,整數(shù)表達(dá)式可以是int基本類(lèi)型或Integer包裝類(lèi)型,由于钳踊,byte,short,char都可以隱含轉(zhuǎn)換為int衷敌,所以,這些類(lèi)型以及這些類(lèi)型的包裝類(lèi)型也是可以的拓瞪。顯然缴罗,long和String類(lèi)型都不符合switch的語(yǔ)法規(guī)定,并且不能被隱式轉(zhuǎn)換成int類(lèi)型祭埂,所以面氓,它們不能作用于swtich語(yǔ)句中。
18蛆橡、Integer與int的區(qū)別舌界?
【參考答案】
int是java提供的8種原始數(shù)據(jù)類(lèi)型之一,另外Java為每個(gè)原始類(lèi)型提供了封裝類(lèi)泰演,Integer是java為int提供的封裝類(lèi)呻拌。int的默認(rèn)值為0,而Integer的默認(rèn)值為null睦焕,即Integer可以區(qū)分出未賦值和值為0的區(qū)別藐握,int則無(wú)法表達(dá)出未賦值的情況。
19垃喊、Java Reflection是什么猾普?【】
【參考答案】
JAVA反射,Reflection是Java程序開(kāi)發(fā)語(yǔ)言的特征之一缔御,它允許運(yùn)行中的Java程序?qū)ψ陨磉M(jìn)行檢查抬闷,或者說(shuō)"自審",并能直接操作程序的內(nèi)部屬性。
【分析】
20笤成、寫(xiě)幾個(gè)java.lang.Object類(lèi)中的方法名稱(chēng)评架。
【參考答案】
主要有equals()、toString()炕泳、getClass()纵诞、hashCode()、clone()培遵、notify()浙芙、wait()诽里、notify()方法亡鼠。
【分析】
這種題能記多少個(gè)就說(shuō)多少個(gè),不一定要求你所有的都記住反浓,但是要理解其中部分重要方法的含義和作用皇耗。
21南窗、&和&&的區(qū)別?
【參考答案】
&和&&都可以用作邏輯與的運(yùn)算符郎楼,表示邏輯與(and)万伤,當(dāng)運(yùn)算符兩邊的表達(dá)式的結(jié)果都為true時(shí),整個(gè)運(yùn)算結(jié)果才為true呜袁,否則敌买,只要有一方為false,則結(jié)果為false阶界。
&&還具有短路的功能虹钮,即如果第一個(gè)表達(dá)式為false,則不再計(jì)算第二個(gè)表達(dá)式荐操。
&還可以用作位運(yùn)算符芜抒,當(dāng)&操作符兩邊的表達(dá)式不是boolean類(lèi)型時(shí),&表示按位與操作托启,我們通常使用0x0f來(lái)與一個(gè)整數(shù)進(jìn)行&運(yùn)算宅倒,來(lái)獲取該整數(shù)的最低4個(gè)bit位。
【分析】
先說(shuō)分別說(shuō)兩者的作用屯耸,再說(shuō)出&&和&各自的不同之處拐迁。
22、數(shù)組有沒(méi)有length()這個(gè)方法疗绣,String有沒(méi)有length()這個(gè)方法线召。
【參考答案】
數(shù)組沒(méi)有l(wèi)ength()方法,但有l(wèi)ength屬性
String有l(wèi)ength()方法多矮。
【分析】
考查平時(shí)使用數(shù)組和字符串的一些細(xì)節(jié)缓淹,一般在使用
23哈打、String s=new String(“xyz”)創(chuàng)建了幾個(gè)對(duì)象
【參考答案】
2個(gè)string對(duì)象,一個(gè)是=null的s,一個(gè)是=“xyz”的string
兩個(gè)或一個(gè)”xyz”對(duì)應(yīng)一個(gè)對(duì)象讯壶,這個(gè)對(duì)象放在字符串常量緩沖區(qū)料仗,常量”xyz”不管出現(xiàn)多少遍,都是緩沖區(qū)中的那一個(gè)伏蚊。New String每寫(xiě)一遍立轧,就創(chuàng)建一個(gè)新的對(duì)象,它一句那個(gè)常量”xyz”對(duì)象的內(nèi)容來(lái)創(chuàng)建出一個(gè)新String對(duì)象躏吊。如果以前就用過(guò)’xyz’氛改,這句代表就不會(huì)創(chuàng)建”xyz”自己了,直接從緩沖區(qū)拿比伏。
【分析】
24胜卤、能不能自己寫(xiě)個(gè)類(lèi),也叫java.lang.String赁项?
可以瑰艘,但在應(yīng)用的時(shí)候,需要用自己的類(lèi)加載器去加載肤舞,否則,系統(tǒng)的類(lèi)加載器永遠(yuǎn)只是去加載jre.jar包中的那個(gè)java.lang.String均蜜。由于在tomcat的web應(yīng)用程序中李剖,都是由webapp自己的類(lèi)加載器先自己加載WEB-INF/classess目錄中的類(lèi),然后才委托上級(jí)的類(lèi)加載器加載囤耳,如果我們?cè)趖omcat的web應(yīng)用程序中寫(xiě)一個(gè)java.lang.String篙顺,這時(shí)候Servlet程序加載的就是我們自己寫(xiě)的java.lang.String,但是這么干就會(huì)出很多潛在的問(wèn)題充择,原來(lái)所有用了java.lang.String類(lèi)的都將出現(xiàn)問(wèn)題德玫。
雖然java提供了endorsed技術(shù),可以覆蓋jdk中的某些類(lèi)椎麦,具體做法是….宰僧。但是,能夠被覆蓋的類(lèi)是有限制范圍观挎,反正不包括java.lang這樣的包中的類(lèi)琴儿。
例如,運(yùn)行下面的程序:
package java.lang;
public class String {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("string");
}
}
報(bào)告的錯(cuò)誤如下:
java.lang.NoSuchMethodError: main
Exception in thread "main"
這是因?yàn)榧虞d了jre自帶的java.lang.String嘁捷,而該類(lèi)中沒(méi)有main方法造成。
25、你對(duì)面向?qū)ο笏枷氲睦斫猓?/b>
【參考答案】
面向?qū)ο缶幊蹋∣bject-Oriented Programming)簡(jiǎn)稱(chēng)OOP技術(shù)雄嚣,是開(kāi)發(fā)計(jì)算機(jī)應(yīng)用程序的一種新方法晒屎、新思想。過(guò)去的面向過(guò)程編程中常常會(huì)導(dǎo)致所有的代碼都包含在幾個(gè)模塊中,使程序難以閱讀和維護(hù)鼓鲁,在做一些修改時(shí)常常牽一動(dòng)百蕴轨,使以后的開(kāi)發(fā)和維護(hù)難以為繼。而使用OOP技術(shù)坐桩,使用許多代碼模塊尺棋,每個(gè)模塊都只提供特定的功能,它們是彼此獨(dú)立的绵跷,可以增加代碼重用的幾率膘螟,更加有利于軟件的開(kāi)發(fā)、維護(hù)和升級(jí)碾局。另外OOP的三大核心特性:繼承荆残、封裝、多態(tài)的特性净当,使得在面對(duì)象編上能夠設(shè)計(jì)出高內(nèi)聚内斯、低耦合的系統(tǒng)結(jié)構(gòu),使得系統(tǒng)更靈活像啼、更容易擴(kuò)展俘闯,而且成本較低,所以這一編程思想是目前一種應(yīng)用最為普遍的軟件設(shè)計(jì)思想忽冻。
【分析】
26真朗、最常見(jiàn)的runtime exception運(yùn)行時(shí)異常?
【參考答案】
ClassCastException(類(lèi)型轉(zhuǎn)換異常)僧诚、NumberFormatException(格式化異常)遮婶、
ArrayIndexOutOfBoundsException(數(shù)組越界異常)、ArithmeticException(算術(shù)異常)湖笨、NullPointerException(空指針異常)等等
【分析】
這道題主要考查大家平時(shí)在項(xiàng)目開(kāi)發(fā)過(guò)程中經(jīng)常遇到的一些異常類(lèi)型信息旗扑,通過(guò)這些異常來(lái)考查大家的項(xiàng)目經(jīng)驗(yàn)與項(xiàng)目排錯(cuò)能力。
27慈省、用JDBC來(lái)實(shí)現(xiàn)訪問(wèn)數(shù)據(jù)庫(kù)記錄可以采用下面的幾個(gè)步驟:
【參考答案】
1臀防、通過(guò)驅(qū)動(dòng)器管理器獲取連接接口(Connection)。
2辫呻、獲得Statement或它的子類(lèi)清钥。
3、指定Statement中的參數(shù)放闺。
4祟昭、通過(guò)Statement發(fā)送SQL語(yǔ)句。
5怖侦、檢查并處理返回的結(jié)果篡悟。
6谜叹、關(guān)閉Statement。
7搬葬、關(guān)閉連接接
【分析】
28荷腊、Error和exception的區(qū)別與聯(lián)系?
【參考答案】
error表示恢復(fù)不是不可能,但很困難的情況下的一種嚴(yán)重問(wèn)題急凰。比如說(shuō)內(nèi)存溢,網(wǎng)絡(luò)故障等女仰,不可能指望程序能處理的一類(lèi)錯(cuò)誤。
Exception表示一種由程序設(shè)計(jì)或?qū)崿F(xiàn)問(wèn)題抡锈,像我們常說(shuō)的異常處理疾忍,就是屬于這類(lèi),一般程序可以捕獲和處理這些異常床三。
【分析】
這道題的難點(diǎn)在Error很多時(shí)候由于我們無(wú)法重現(xiàn)這種Error導(dǎo)致很多同學(xué)甚至不知道Error到底是什么一罩,所以很容易把題目中的兩種錯(cuò)誤劃上等號(hào)。
29撇簿、String?s?=?"Hello";s?=?s?+?"?world!";這兩行代碼執(zhí)行后聂渊,原始的String對(duì)象中的內(nèi)容到底變了沒(méi)有?
【參考答案】
沒(méi)有四瘫。因?yàn)镾tring被設(shè)計(jì)成不可變(immutable)類(lèi)汉嗽,所以它的所有對(duì)象都是不可變對(duì)象吱涉。在這段代碼中等舔,s原先指向一個(gè)String對(duì)象,內(nèi)容是"Hello"睦授,然后我們對(duì)s進(jìn)行了+操作锹杈,那么s所指向的那個(gè)對(duì)象是否發(fā)生了改變呢?答案是沒(méi)有迈着。這時(shí)竭望,s不指向原來(lái)那個(gè)對(duì)象了,而指向了另一個(gè)String對(duì)象裕菠,內(nèi)容為"Hello?world!"咬清,原來(lái)那個(gè)對(duì)象還存在于內(nèi)存之中,只是s這個(gè)引用變量不再指向它了奴潘。
通過(guò)上面的說(shuō)明旧烧,我們很容易導(dǎo)出另一個(gè)結(jié)論,如果經(jīng)常對(duì)字符串進(jìn)行各種各樣的修改画髓,或者說(shuō)掘剪,不可預(yù)見(jiàn)的修改,那么使用String來(lái)代表字符串的話(huà)會(huì)引起很大的內(nèi)存開(kāi)銷(xiāo)奈虾。因?yàn)镾tring對(duì)象建立之后不能再改變夺谁,所以對(duì)于每一個(gè)不同的字符串廉赔,都需要一個(gè)String對(duì)象來(lái)表示。這時(shí)匾鸥,應(yīng)該考慮使用StringBuffer類(lèi)蜡塌,它允許修改,而不是每個(gè)不同的字符串都要生成一個(gè)新的對(duì)象勿负。并且馏艾,這兩種類(lèi)的對(duì)象轉(zhuǎn)換十分容易。
同時(shí)奴愉,我們還可以知道琅摩,如果要使用內(nèi)容相同的字符串,不必每次都new一個(gè)String躁劣。例如我們要在構(gòu)造器中對(duì)一個(gè)名叫s的String引用變量進(jìn)行初始化迫吐,把它設(shè)置為初始值,應(yīng)當(dāng)這樣做:
public?class?Demo?{
private?String?s;
...
public?Demo?{
s?=?"Initial?Value";
}
...
}
而非
s?=?new?String("Initial?Value");
后者每次都會(huì)調(diào)用構(gòu)造器账忘,生成新對(duì)象志膀,性能低下且內(nèi)存開(kāi)銷(xiāo)大,并且沒(méi)有意義鳖擒,因?yàn)镾tring對(duì)象不可改變溉浙,所以對(duì)于內(nèi)容相同的字符串,只要一個(gè)String對(duì)象來(lái)表示就可以了蒋荚。也就說(shuō)戳稽,多次調(diào)用上面的構(gòu)造器創(chuàng)建多個(gè)對(duì)象,他們的String類(lèi)型屬性s都指向同一個(gè)對(duì)象期升。
上面的結(jié)論還基于這樣一個(gè)事實(shí):對(duì)于字符串常量惊奇,如果內(nèi)容相同,Java認(rèn)為它們代表同一個(gè)String對(duì)象播赁。而用關(guān)鍵字new調(diào)用構(gòu)造器颂郎,總是會(huì)創(chuàng)建一個(gè)新的對(duì)象,無(wú)論內(nèi)容是否相同容为。
至于為什么要把String類(lèi)設(shè)計(jì)成不可變類(lèi)乓序,是它的用途決定的。其實(shí)不只String坎背,很多Java標(biāo)準(zhǔn)類(lèi)庫(kù)中的類(lèi)都是不可變的替劈。在開(kāi)發(fā)一個(gè)系統(tǒng)的時(shí)候,我們有時(shí)候也需要設(shè)計(jì)不可變類(lèi)得滤,來(lái)傳遞一組相關(guān)的值陨献,這也是面向?qū)ο笏枷氲捏w現(xiàn)。不可變類(lèi)有一些優(yōu)點(diǎn)懂更,比如因?yàn)樗膶?duì)象是只讀的湿故,所以多線程并發(fā)訪問(wèn)也不會(huì)有任何問(wèn)題阿趁。當(dāng)然也有一些缺點(diǎn),比如每個(gè)不同的狀態(tài)都要一個(gè)對(duì)象來(lái)代表坛猪,可能會(huì)造成性能上的問(wèn)題脖阵。所以Java標(biāo)準(zhǔn)類(lèi)庫(kù)還提供了一個(gè)可變版本,即StringBuffer墅茉。
30命黔、Jdk1.5的新特性?
【參考答案】
JDK1.5的一個(gè)重要主題就是通過(guò)新增一些特性來(lái)簡(jiǎn)化開(kāi)發(fā)就斤,這些特性主要包括:泛型悍募、ForEach循環(huán)、自動(dòng)裝包/拆包洋机、枚舉坠宴、可變參數(shù)、靜態(tài)導(dǎo)入這些绷旗。
【分析】
31喜鼓、面向?qū)ο蟮奶卣饔心男┓矫妫?/b>
【參考答案】
面向?qū)ο蟮木幊陶Z(yǔ)言有封裝、繼承衔肢、多態(tài)等3個(gè)主要的特征庄岖。
u封裝
封裝是保證軟件部件具有優(yōu)良的模塊性的基礎(chǔ),封裝的目標(biāo)就是要實(shí)現(xiàn)軟件部件的“高內(nèi)聚角骤、低耦合”隅忿,防止程序相互依賴(lài)性而帶來(lái)的變動(dòng)影響。面向?qū)ο蟮姆庋b就是把描述一個(gè)對(duì)象的屬性和行為的代碼封裝在一個(gè)“模塊”中邦尊,也就是一個(gè)類(lèi)中背桐,屬性用變量定義,行為用方法進(jìn)行定義蝉揍,方法可以直接訪問(wèn)同一個(gè)對(duì)象中的屬性牢撼。
u繼承
在定義和實(shí)現(xiàn)一個(gè)類(lèi)的時(shí)候,可以在一個(gè)已經(jīng)存在的類(lèi)的基礎(chǔ)之上來(lái)進(jìn)行疑苫,把這個(gè)已經(jīng)存在的類(lèi)所定義的內(nèi)容作為自己的內(nèi)容,并可以加入若干新的內(nèi)容纷责,或修改原來(lái)的方法使之更適合特殊的需要捍掺,這就是繼承。繼承是子類(lèi)自動(dòng)共享父類(lèi)數(shù)據(jù)和方法的機(jī)制再膳,這是類(lèi)之間的一種關(guān)系挺勿,提高了軟件的可重用性和可擴(kuò)展性。
u多態(tài)
多態(tài)是指程序中定義的引用變量所指向的具體類(lèi)型和通過(guò)該引用變量發(fā)出的方法調(diào)用在編程時(shí)并不確定喂柒,而是在程序運(yùn)行期間才確定不瓶,即一個(gè)引用變量倒底會(huì)指向哪個(gè)類(lèi)的實(shí)例對(duì)象禾嫉,該引用變量發(fā)出的方法調(diào)用到底是哪個(gè)類(lèi)中實(shí)現(xiàn)的方法,必須在由程序運(yùn)行期間才能決定蚊丐。因?yàn)樵诔绦蜻\(yùn)行時(shí)才確定具體的類(lèi)熙参,這樣,不用修改源程序代碼麦备,就可以讓引用變量綁定到各種不同的類(lèi)實(shí)現(xiàn)上孽椰,從而導(dǎo)致該引用調(diào)用的具體方法隨之改變,即不修改程序代碼就可以改變程序運(yùn)行時(shí)所綁定的具體代碼凛篙,讓程序可以選擇多個(gè)運(yùn)行狀態(tài)黍匾,這就是多態(tài)性。多態(tài)性增強(qiáng)了軟件的靈活性和擴(kuò)展性呛梆。
32锐涯、JVM工作原理?
運(yùn)行jvm字符碼的工作是由解釋器來(lái)完成的填物。解釋執(zhí)行過(guò)程分三步進(jìn)行:
代碼的裝入纹腌、代碼的校驗(yàn)、和代碼的執(zhí)行融痛。
裝入代碼的工作由“類(lèi)裝載器class loader”完成壶笼。類(lèi)裝載器負(fù)責(zé)裝入運(yùn)行一個(gè)程序需要的所有代碼,這也包括程序代碼中的類(lèi)所繼承的類(lèi)和被調(diào)用的類(lèi)雁刷。當(dāng)類(lèi)裝載器裝入一個(gè)類(lèi)時(shí)覆劈,該類(lèi)被放在自己的名字空間中。除了通過(guò)符號(hào)引用自己名字空間以外的類(lèi)沛励,類(lèi)之間沒(méi)有其他辦法可以影響其他類(lèi)责语。在本臺(tái)計(jì)算機(jī)的所有類(lèi)都在同一地址空間中,而所有從外部引進(jìn)的類(lèi)目派,都有一個(gè)自己獨(dú)立的名字空間坤候。這使得本地類(lèi)通過(guò)共享相同的名字空間獲得較高的運(yùn)行效率,同時(shí)又保證它們與從外部引進(jìn)的類(lèi)不會(huì)相互影響企蹭。當(dāng)裝入了運(yùn)行程序需要的所有類(lèi)后白筹,解釋器便可確定整個(gè)可執(zhí)行程序的內(nèi)存布局。解釋器為符號(hào)引用與特定的地址空間建立對(duì)應(yīng)關(guān)系及查詢(xún)表谅摄。通過(guò)在這一階段確定代碼的內(nèi)布局徒河,java很好地解決了由超類(lèi)改變而使子類(lèi)
崩潰的問(wèn)題照卦,同時(shí)也防止了代碼的非法訪問(wèn)割以。隨后惕耕,被裝入的代碼由字節(jié)碼校驗(yàn)器進(jìn)行檢查蝶糯。校驗(yàn)器可以發(fā)現(xiàn)操作數(shù)棧益處察绷、非法數(shù)據(jù)類(lèi)型轉(zhuǎn)化等多種錯(cuò)誤志群。通過(guò)校驗(yàn)后浑彰,代碼便開(kāi)始執(zhí)行了拾积。
Java字節(jié)碼的執(zhí)行有兩種方式:
1)即時(shí)編譯方式:解釋器先將字節(jié)編譯成機(jī)器碼,然后再執(zhí)行該機(jī)器碼植影。
2)解釋執(zhí)行方式:解釋器通過(guò)每次解釋并執(zhí)行一小段代碼來(lái)完成java字節(jié)裳擎。
碼程序的所有操作。
33何乎、說(shuō)說(shuō)Java中的內(nèi)存分配?
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)存的主要原因听隐。但是在寫(xiě)程序的時(shí)候,可以人為的控制哄啄。
34雅任、final, finally, finalize的區(qū)別风范。
【參考答案】
final用于聲明屬性,方法和類(lèi)沪么,分別表示屬性不可變硼婿,方法不可覆蓋,類(lèi)不可繼承禽车。
內(nèi)部類(lèi)要訪問(wèn)局部變量寇漫,局部變量必須定義成final類(lèi)型,例如殉摔,一段代碼……
finally是異常處理語(yǔ)句結(jié)構(gòu)的一部分州胳,表示總是執(zhí)行。
finalize是Object類(lèi)的一個(gè)方法逸月,在垃圾收集器執(zhí)行的時(shí)候會(huì)調(diào)用被回收對(duì)象的此方法栓撞,可以覆蓋此方法提供垃圾收集時(shí)的其他資源回收,例如關(guān)閉文件等碗硬。JVM不保證此方法總被調(diào)用
35瓤湘、Extends和Implement的不同?
【參考答案】
extends是繼承父類(lèi)恩尾,只要那個(gè)類(lèi)不是聲明為final或者那個(gè)類(lèi)定義為abstract的就能繼承弛说,JAVA中不支持多重繼承,但是可以用接口來(lái)實(shí)現(xiàn)翰意,這樣就要用到implements木人,繼承只能繼承一個(gè)類(lèi),但implements可以實(shí)現(xiàn)多個(gè)接口猎物,用逗號(hào)分開(kāi)就行了
比如class A extends B implements C,D,E
36虎囚、抽象類(lèi)是否可以沒(méi)有抽象方法?為什么蔫磨?
【參考答案】
可以在java中用abstract關(guān)鍵字來(lái)修飾一個(gè)類(lèi)時(shí)淘讥,這個(gè)類(lèi)叫做抽象類(lèi)。
抽象類(lèi)中不一定要包含abstract方法堤如,但一個(gè)類(lèi)中包含了abstract方法蒲列,則這個(gè)類(lèi)必須聲明為abstract類(lèi)。
37搀罢、靜態(tài)的多態(tài)和動(dòng)態(tài)的多態(tài)的區(qū)別蝗岖?
【參考答案】
靜態(tài)的多態(tài):即為重載;方法名相同榔至,參數(shù)個(gè)數(shù)或類(lèi)型不相同抵赢。(overloading)
動(dòng)態(tài)的多態(tài):即為重寫(xiě);子類(lèi)覆蓋父類(lèi)的方法,將子類(lèi)的實(shí)例傳與父類(lèi)的引用調(diào)用的是子類(lèi)的方法實(shí)現(xiàn)接口的實(shí)例傳與接口的引用調(diào)用的實(shí)現(xiàn)類(lèi)的方法铅鲤。
38划提、說(shuō)出一些常用的類(lèi),包邢享,接口鹏往,請(qǐng)各舉5個(gè)?
【參考答案】
常用的類(lèi):String、StringBuffer骇塘、Integer伊履、Vector、ArrayList款违、Hashtable等
常用的包:java.lang ??java.io ?java.util唐瀑、java.sql。
常用的接口:集合中的List奠货、Set介褥、Map接口;與Servlet API相關(guān)的Servlet接口递惋、HttpServletRequest,HttpServletResponse,HttpSession接口等柔滔。
39、Collections和Collection的區(qū)別【天晟科技】
【參考答案】
Collection是個(gè)java.util下的接口萍虽,它是各種集合結(jié)構(gòu)的父接口睛廊,定義了集合對(duì)象的基本操作方法。Collections是個(gè)java.util下的工具類(lèi)杉编,它包含有各種有關(guān)集合操作的靜態(tài)方法超全,主要是針對(duì)集合類(lèi)的一個(gè)幫助類(lèi)或者叫包裝類(lèi),它提供一系列對(duì)各種集合的搜索邓馒,排序嘶朱,線程安全化等操作方法。
40光酣、Class.forName的作用?為什么要用?
【參考答案】
按參數(shù)中指定的字符串形式的類(lèi)名去搜索并加載相應(yīng)的類(lèi)疏遏,如果該類(lèi)字節(jié)碼已經(jīng)被加載過(guò),則返回代表該字節(jié)碼的Class實(shí)例對(duì)象救军,否則财异,按類(lèi)加載器的委托機(jī)制去搜索和加載該類(lèi),如果所有的類(lèi)加載器都無(wú)法加載到該類(lèi)唱遭,則拋出ClassNotFoundException戳寸。加載完這個(gè)Class字節(jié)碼后,接著就可以使用Class字節(jié)碼的newInstance方法去創(chuàng)建該類(lèi)的實(shí)例對(duì)象了拷泽。有時(shí)候疫鹊,我們程序中所有使用的具體類(lèi)名在設(shè)計(jì)時(shí)(即開(kāi)發(fā)時(shí))無(wú)法確定袖瞻,只有程序運(yùn)行時(shí)才能確定,這時(shí)候就需要使用Class.forName去動(dòng)態(tài)加載該類(lèi)拆吆,這個(gè)類(lèi)名通常是在配置文件中配置的虏辫,例如,spring的ioc中每次依賴(lài)注入的具體類(lèi)就是這樣配置的锈拨,jdbc的驅(qū)動(dòng)類(lèi)名通常也是通過(guò)配置文件來(lái)配置的,以便在產(chǎn)品交付使用后不用修改源程序就可以更換驅(qū)動(dòng)類(lèi)名羹唠。
41奕枢、Socket如何獲取本地ip地址?
【參考答案】
InetAddress類(lèi)提供的API來(lái)訪問(wèn)佩微。InetAddress.getLocalAddress()
【分析】
42缝彬、接口是否可繼承接口?抽象類(lèi)是否可實(shí)現(xiàn)(implements)接口?抽象類(lèi)是否可繼承具體類(lèi)【天威誠(chéng)信面試題】
【參考答案】
接口可以繼承接口。抽象類(lèi)可以實(shí)現(xiàn)(implements)接口哺眯,抽象類(lèi)是否可繼承具體類(lèi)谷浅。抽象類(lèi)中可以有靜態(tài)的main方法。
備注:只要明白了接口和抽象類(lèi)的本質(zhì)和作用奶卓,這些問(wèn)題都很好回答一疯,你想想,如果你是java語(yǔ)言的設(shè)計(jì)者夺姑,你是否會(huì)提供這樣的支持墩邀,如果不提供的話(huà),有什么理由嗎盏浙?如果你沒(méi)有道理不提供眉睹,那答案就是肯定的了。
只有記住抽象類(lèi)與普通類(lèi)的唯一區(qū)別就是不能創(chuàng)建實(shí)例對(duì)象和允許有abstract方法废膘。
43、用最有效率的方法算出2乘以8等於幾?
【參考答案】
2 << 3
【分析】
因?yàn)閷⒁粋€(gè)數(shù)左移n位,就相當(dāng)于乘以了2的n次方余爆,那么茴迁,一個(gè)數(shù)乘以8只要將其左移3位即可,而位運(yùn)算cpu直接支持的孵稽,效率最高许起,所以2乘以8等於幾的最效率的方法是2 << 3。
44菩鲜、char型變量中能不能存貯一個(gè)中文漢字?為什么?
【參考答案】
char型變量是用來(lái)存儲(chǔ)Unicode編碼的字符的园细,unicode編碼字符集中包含了漢字,所以接校,char型變量中當(dāng)然可以存儲(chǔ)漢字啦猛频。不過(guò)狮崩,如果某個(gè)特殊的漢字沒(méi)有被包含在unicode編碼字符集中,那么鹿寻,這個(gè)char型變量中就不能存儲(chǔ)這個(gè)特殊漢字睦柴。補(bǔ)充說(shuō)明:unicode編碼占用兩個(gè)字節(jié),所以毡熏,char類(lèi)型的變量也是占用兩個(gè)字節(jié)坦敌。
45、寫(xiě)clone()方法時(shí)痢法,通常都有一行代碼狱窘,是什么?
【參考答案】
clone有缺省行為财搁,super.clone();因?yàn)槭紫纫迅割?lèi)中的成員復(fù)制到位蘸炸,然后才是復(fù)制自己的成員。
46尖奔、說(shuō)說(shuō)常用集合類(lèi)有哪些搭儒?有哪些方法?
【參考答案】
通常我們使用的集合類(lèi)都大多是由List提茁、Set淹禾、Map這三類(lèi)接口派生出來(lái)的類(lèi),例如:
ArrayList茴扁、Vector稀拐、LinkedList、Stack丹弱、TreeSet德撬、Hashtable、HashMap等
集合類(lèi)的大部分方法都是由Collection接口定義的躲胳,主要包括有:
add(Ee)蜓洪、remove(Object e)、addAll(),remove()坯苹、contains(Object obj)隆檀、clear()等
47、請(qǐng)說(shuō)出作用域public粹湃,private恐仑,protected,以及不寫(xiě)時(shí)的區(qū)別?【天威誠(chéng)信面試題】
【參考答案】
這四個(gè)作用域的可見(jiàn)范圍如下表所示为鳄。
說(shuō)明:如果在修飾的元素上面沒(méi)有寫(xiě)任何訪問(wèn)修飾符裳仆,則表示friendly。
作用域同一類(lèi)同一package子孫類(lèi)其他package
public√√√√
protected√√√×
friendly√√××
private√×××
備注:只要記住了有4種訪問(wèn)權(quán)限孤钦,4個(gè)訪問(wèn)范圍歧斟,然后將全選和范圍在水平和垂直方向上分別按排從小到大或從大到小的順序排列纯丸,就很容易畫(huà)出上面的圖了。
48静袖、構(gòu)造器Constructor是否可被override?【億陽(yáng)通訊面試題】
【參考答案】
構(gòu)造器Constructor不能被繼承觉鼻,因此不能重寫(xiě)Override,但可以被重載Overload队橙。
49坠陈、是否可以從一個(gè)static方法內(nèi)部發(fā)出對(duì)非static方法的調(diào)用?【世承軟件面試題】
【參考答案】
不可以捐康。因?yàn)榉莝tatic方法是要與對(duì)象關(guān)聯(lián)在一起的畅姊,必須創(chuàng)建一個(gè)對(duì)象后,才可以在該對(duì)象上進(jìn)行方法調(diào)用吹由,而static方法調(diào)用時(shí)不需要?jiǎng)?chuàng)建對(duì)象,可以直接調(diào)用朱嘴。
50倾鲫、Math.round(11.5)等於多少? Math.round(-11.5)等於多少?【霧隱美地傳媒】
【參考答案】
Math類(lèi)中提供了三個(gè)與取整有關(guān)的方法:ceil、floor萍嬉、round乌昔,這些方法的作用與它們的英文名稱(chēng)的含義相對(duì)應(yīng),例如壤追,ceil的英文意義是天花板磕道,該方法就表示向上取整,所以行冰,Math.ceil(11.3)的結(jié)果為12,Math.ceil(-11.3)的結(jié)果是-11溺蕉;floor的英文意義是地板,該方法就表示向下取整悼做,所以疯特,Math.floor(11.6)的結(jié)果為11,Math.floor(-11.6)的結(jié)果是-12;最難掌握的是round方法肛走,它表示“四舍五入”漓雅,算法為Math.floor(x+0.5),即將原來(lái)的數(shù)字加上0.5后再向下取整朽色,所以邻吞,Math.round(11.5)的結(jié)果為12,Math.round(-11.5)的結(jié)果為-11葫男。
51抱冷、abstract class(抽象類(lèi))和interface(接口)有什么區(qū)別?【百度應(yīng)用中心面試題】
【參考答案】
含有abstract修飾符的class即為抽象類(lèi),abstract類(lèi)不能創(chuàng)建的實(shí)例對(duì)象梢褐。含有abstract方法的類(lèi)必須定義為abstract class徘层,abstract class類(lèi)中的方法不必是抽象的峻呕。abstract class類(lèi)中定義抽象方法必須在具體(Concrete)子類(lèi)中實(shí)現(xiàn),所以趣效,不能有抽象構(gòu)造方法或抽象靜態(tài)方法瘦癌。如果的子類(lèi)沒(méi)有實(shí)現(xiàn)抽象父類(lèi)中的所有抽象方法,那么子類(lèi)也必須定義為abstract類(lèi)型跷敬。
接口(interface)可以說(shuō)成是抽象類(lèi)的一種特例讯私,接口中的所有方法都必須是抽象的。接口中的方法定義默認(rèn)為public abstract類(lèi)型西傀,接口中的成員變量類(lèi)型默認(rèn)為public static final斤寇。
下面比較一下兩者的語(yǔ)法區(qū)別:
1.抽象類(lèi)可以有構(gòu)造方法,接口中不能有構(gòu)造方法拥褂。
2.抽象類(lèi)中可以有普通成員變量娘锁,接口中沒(méi)有普通成員變量
3.抽象類(lèi)中可以包含非抽象的普通方法,接口中的所有方法必須都是抽象的饺鹃,不能有非抽象的普通方法莫秆。
4.抽象類(lèi)中的抽象方法的訪問(wèn)類(lèi)型可以是public,protected和(默認(rèn)類(lèi)型,雖然
eclipse下不報(bào)錯(cuò)悔详,但應(yīng)該也不行)镊屎,但接口中的抽象方法只能是public類(lèi)型的,并且默認(rèn)即為public abstract類(lèi)型茄螃。
5.抽象類(lèi)中可以包含靜態(tài)方法缝驳,接口中不能包含靜態(tài)方法
6.抽象類(lèi)和接口中都可以包含靜態(tài)成員變量,抽象類(lèi)中的靜態(tài)成員變量的訪問(wèn)類(lèi)型可以任意归苍,但接口中定義的變量只能是public static final類(lèi)型用狱,并且默認(rèn)即為public static final類(lèi)型。
7.一個(gè)類(lèi)可以實(shí)現(xiàn)多個(gè)接口拼弃,但只能繼承一個(gè)抽象類(lèi)齿拂。
下面接著再說(shuō)說(shuō)兩者在應(yīng)用上的區(qū)別:
【分析】
這道題的思路是先從總體解釋抽象類(lèi)和接口的基本概念,然后再比較兩者的語(yǔ)法細(xì)節(jié)肴敛,最后再說(shuō)兩者的應(yīng)用區(qū)別署海。比較兩者語(yǔ)法細(xì)節(jié)區(qū)別的條理是:先從一個(gè)類(lèi)中的構(gòu)造方法、普通成員變量和方法(包括抽象方法)医男,靜態(tài)變量和方法砸狞,繼承性等方面來(lái)回答。
52镀梭、Collection框架中實(shí)現(xiàn)比較要實(shí)現(xiàn)什么接口?
【參考答案】
Comparable刀森、Comparator接口
53、是否可以繼承String類(lèi)?
【參考答案】
String類(lèi)是final類(lèi)故不可以繼承报账。
54研底、String和StringBuffer的區(qū)別
【參考答案】
JAVA平臺(tái)提供了兩個(gè)類(lèi):String和StringBuffer埠偿,它們可以?xún)?chǔ)存和操作字符串,即包含多個(gè)字符的字符數(shù)據(jù)榜晦。String類(lèi)表示內(nèi)容不可改變的字符串冠蒋。而StringBuffer類(lèi)表示內(nèi)容可以被修改的字符串。當(dāng)你知道字符數(shù)據(jù)要改變的時(shí)候你就可以使用StringBuffer乾胶。典型地抖剿,你可以使用StringBuffers來(lái)動(dòng)態(tài)構(gòu)造字符數(shù)據(jù)。另外识窿,String實(shí)現(xiàn)了equals方法斩郎,new String(“abc”).equals(new String(“abc”)的結(jié)果為true,而StringBuffer沒(méi)有實(shí)現(xiàn)equals方法,所以喻频,new StringBuffer(“abc”).equals(new StringBuffer(“abc”)的結(jié)果為false缩宜。
String覆蓋了equals方法和hashCode方法,而StringBuffer沒(méi)有覆蓋equals方法和hashCode方法甥温,所以锻煌,將StringBuffer對(duì)象存儲(chǔ)進(jìn)Java集合類(lèi)中時(shí)會(huì)出現(xiàn)問(wèn)題。
55窿侈、StringBuffer與StringBuilder的區(qū)別
【參考答案】
StringBuffer和StringBuilder類(lèi)都表示內(nèi)容可以被修改的字符串,StringBuilder是線程不安全的秋茫,運(yùn)行效率高史简,如果一個(gè)字符串變量是在方法里面定義,這種情況只可能有一個(gè)線程訪問(wèn)它逸吵,不存在不安全的因素了窑睁,則用StringBuilder史侣。如果要在類(lèi)里面定義成員變量,并且這個(gè)類(lèi)的實(shí)例對(duì)象會(huì)在多線程環(huán)境下使用殉农,那么最好用StringBuffer。
56局荚、try {}里有一個(gè)return語(yǔ)句超凳,那么緊跟在這個(gè)try后的finally {}里的code會(huì)不會(huì)被執(zhí)行,什么時(shí)候被執(zhí)行耀态,在return前還是后?【杭州天眼科技】
【參考答案】
答案是在return之前轮傍。
【分析】
程序代碼的運(yùn)行結(jié)果:
public ?class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(new Test().test());;
}
static int test()
{
int x = 1;
try
{
return x;
}
finally
{
++x;
}
}
}
---------執(zhí)行結(jié)果---------
1
運(yùn)行結(jié)果是1,為什么呢首装?主函數(shù)調(diào)用子函數(shù)并得到結(jié)果的過(guò)程创夜,好比主函數(shù)準(zhǔn)備一個(gè)空罐子,當(dāng)子函數(shù)要返回結(jié)果時(shí)仙逻,先把結(jié)果放在罐子里驰吓,然后再將程序邏輯返回到主函數(shù)涧尿。所謂返回,就是子函數(shù)說(shuō)檬贰,我不運(yùn)行了姑廉,你主函數(shù)繼續(xù)運(yùn)行吧,這沒(méi)什么結(jié)果可言偎蘸,結(jié)果是在說(shuō)這話(huà)之前放進(jìn)罐子里的庄蹋。
下面的程序代碼輸出的結(jié)果是多少?
public class ?smallT
{
public static void ?main(String args[])
{
smallT t ?= new ?smallT();
int ?b ?= ?t.get();
System.out.println(b);
}
public int ?get()
{
try
{
return 1 ;
}
finally
{
return 2 ;
}
}
}
返回的結(jié)果是2迷雪。
我可以通過(guò)下面一個(gè)例子程序來(lái)幫助我解釋這個(gè)答案限书,從下面例子的運(yùn)行結(jié)果中可以發(fā)現(xiàn),try中的return語(yǔ)句調(diào)用的函數(shù)先于finally中調(diào)用的函數(shù)執(zhí)行章咧,也就是說(shuō)return語(yǔ)句先執(zhí)行倦西,finally語(yǔ)句后執(zhí)行,所以赁严,返回的結(jié)果是2扰柠。Return并不是讓函數(shù)馬上返回,而是return語(yǔ)句執(zhí)行后疼约,將把返回結(jié)果放置進(jìn)函數(shù)棧中卤档,此時(shí)函數(shù)并不是馬上返回,它要執(zhí)行finally語(yǔ)句后才真正開(kāi)始返回程剥。
在講解答案時(shí)可以用下面的程序來(lái)幫助分析:
public ?class Test {
/**
* @param args add by zxx ,Dec 9, 2008
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(new Test().test());;
}
int test()
{
try
{
return func1();
}
finally
{
return func2();
}
}
int func1()
{
System.out.println("func1");
return 1;
}
int func2()
{
System.out.println("func2");
return 2;
}
}
-----------執(zhí)行結(jié)果-----------------
func1
func2
2
結(jié)論:finally中的代碼比return和break語(yǔ)句后執(zhí)行劝枣。
57、Java中的異常處理機(jī)制的簡(jiǎn)單原理和應(yīng)用织鲸。
【參考答案】
異常是指java程序運(yùn)行時(shí)(非編譯)所發(fā)生的非正常情況或錯(cuò)誤舔腾,與現(xiàn)實(shí)生活中的事件很相似,現(xiàn)實(shí)生活中的事件可以包含事件發(fā)生的時(shí)間搂擦、地點(diǎn)稳诚、人物、情節(jié)等信息瀑踢,可以用一個(gè)對(duì)象來(lái)表示扳还,Java使用面向?qū)ο蟮姆绞絹?lái)處理異常,它把程序中發(fā)生的每個(gè)異常也都分別封裝到一個(gè)對(duì)象來(lái)表示的橱夭,該對(duì)象中包含有異常的信息普办。
Java對(duì)異常進(jìn)行了分類(lèi),不同類(lèi)型的異常分別用不同的Java類(lèi)表示徘钥,所有異常的根類(lèi)為java.lang.Throwable衔蹲,Throwable下面又派生了兩個(gè)子類(lèi):Error和Exception,Error表示應(yīng)用程序本身無(wú)法克服和恢復(fù)的一種嚴(yán)重問(wèn)題,程序只有死的份了舆驶,例如橱健,說(shuō)內(nèi)存溢出和線程死鎖等系統(tǒng)問(wèn)題。Exception表示程序還能夠克服和恢復(fù)的問(wèn)題沙廉,其中又分為系統(tǒng)異常和普通異常拘荡,系統(tǒng)異常是軟件本身缺陷所導(dǎo)致的問(wèn)題,也就是軟件開(kāi)發(fā)人員考慮不周所導(dǎo)致的問(wèn)題撬陵,軟件使用者無(wú)法克服和恢復(fù)這種問(wèn)題珊皿,但在這種問(wèn)題下還可以讓軟件系統(tǒng)繼續(xù)運(yùn)行或者讓軟件死掉,例如巨税,數(shù)組腳本越界(ArrayIndexOutOfBoundsException)蟋定,空指針異常(NullPointerException)、類(lèi)轉(zhuǎn)換異常(ClassCastException)草添;普通異常是運(yùn)行環(huán)境的變化或異常所導(dǎo)致的問(wèn)題驶兜,是用戶(hù)能夠克服的問(wèn)題,例如远寸,網(wǎng)絡(luò)斷線抄淑,硬盤(pán)空間不夠,發(fā)生這樣的異常后驰后,程序不應(yīng)該死掉肆资。
java為系統(tǒng)異常和普通異常提供了不同的解決方案,編譯器強(qiáng)制普通異常必須try..catch處理或用throws聲明繼續(xù)拋給上層調(diào)用方法處理灶芝,所以普通異常也稱(chēng)為checked異常郑原,而系統(tǒng)異常可以處理也可以不處理监署,所以颤专,編譯器不強(qiáng)制用try..catch處理或用throws聲明纽哥,所以系統(tǒng)異常也稱(chēng)為unchecked異常钠乏。
58、多線程有幾種實(shí)現(xiàn)方法?同步有幾種實(shí)現(xiàn)方法?
【參考答案】
多線程有兩種實(shí)現(xiàn)方法春塌,分別是繼承Thread類(lèi)與實(shí)現(xiàn)Runnable接口晓避。
同步的實(shí)現(xiàn)方面有兩種,分別是synchronized,wait與notify只壳。
a.wait():使一個(gè)線程處于等待狀態(tài)俏拱,并且釋放所持有的對(duì)象的lock。
b.sleep():使一個(gè)正在運(yùn)行的線程處于睡眠狀態(tài)吼句,是一個(gè)靜態(tài)方法锅必,調(diào)用此方法要捕捉InterruptedException異常。
c.notify():喚醒一個(gè)處于等待狀態(tài)的線程,注意的是在調(diào)用此方法的時(shí)候搞隐,并不能確切的喚醒某一個(gè)等待狀態(tài)的線程驹愚,而是由JVM確定喚醒哪個(gè)線程,而且不是按優(yōu)先級(jí)劣纲。
d.allnotity():喚醒所有處入等待狀態(tài)的線程逢捺,注意并不是給所有喚醒線程一個(gè)對(duì)象的鎖,而是讓它們競(jìng)爭(zhēng)癞季。
59劫瞳、啟動(dòng)一個(gè)線程是用run()還是start()?
【參考答案】
啟動(dòng)一個(gè)線程是調(diào)用start()方法,使線程就緒狀態(tài)绷柒,以后可以被調(diào)度為運(yùn)行狀態(tài)志于,一個(gè)線程必須關(guān)聯(lián)一些具體的執(zhí)行代碼,run()方法是該線程所關(guān)聯(lián)的執(zhí)行代碼辉巡。
60恨憎、內(nèi)部類(lèi)可以引用外部類(lèi)的成員嗎?有沒(méi)有什么限制郊楣?
【參考答案】
完全可以憔恳。如果不是靜態(tài)內(nèi)部類(lèi),那沒(méi)有什么限制净蚤!
如果你把靜態(tài)嵌套類(lèi)當(dāng)作內(nèi)部類(lèi)的一種特例钥组,那在這種情況下不可以訪問(wèn)外部類(lèi)的普通成員變量,而只能訪問(wèn)外部類(lèi)中的靜態(tài)成員今瀑。
61程梦、List和Map區(qū)別?【軟通動(dòng)力】
【參考答案】
一個(gè)是存儲(chǔ)單列數(shù)據(jù)的集合,另一個(gè)是存儲(chǔ)鍵和值這樣的雙列數(shù)據(jù)的集合橘荠,List中存儲(chǔ)的數(shù)據(jù)是有順序屿附,并且允許重復(fù);Map中存儲(chǔ)的數(shù)據(jù)是沒(méi)有順序的哥童,其鍵是不能重復(fù)的挺份,它的值是可以有重復(fù)的。
62贮懈、ArrayList和Vector的區(qū)別【博炎科技】
【參考答案】
這兩個(gè)類(lèi)都實(shí)現(xiàn)了List接口(List接口繼承了Collection接口)匀泊,他們都是有序集合,即存儲(chǔ)在這兩個(gè)集合中的元素的位置都是有順序的朵你,相當(dāng)于一種動(dòng)態(tài)的數(shù)組各聘,我們以后可以按位置索引號(hào)取出某個(gè)元素,并且其中的數(shù)據(jù)是允許重復(fù)的抡医。
接著說(shuō)ArrayList與Vector的區(qū)別躲因,這主要包括兩個(gè)方面:
1、同步性:
Vector是線程安全的,也就是說(shuō)是它的方法之間是線程同步的大脉,而ArrayList是線程序不安全的搁嗓,它的方法之間是線程不同步的。如果只有一個(gè)線程會(huì)訪問(wèn)到集合箱靴,那最好是使用ArrayList腺逛,因?yàn)樗豢紤]線程安全,效率會(huì)高些衡怀;如果有多個(gè)線程會(huì)訪問(wèn)到集合棍矛,那最好是使用Vector,因?yàn)椴恍枰覀冏约涸偃タ紤]和編寫(xiě)線程安全的代碼抛杨。
備注:對(duì)于Vector&ArrayList够委、Hashtable&HashMap,要記住線程安全的問(wèn)題怖现,記住Vector與Hashtable是舊的茁帽,是java一誕生就提供了的,它們是線程安全的屈嗤,ArrayList與HashMap是java2時(shí)才提供的潘拨,它們是線程不安全的。
2饶号、數(shù)據(jù)增長(zhǎng):
ArrayList與Vector都有一個(gè)初始的容量大小铁追,當(dāng)存儲(chǔ)進(jìn)它們里面的元素的個(gè)數(shù)超過(guò)了容量時(shí),就需要增加ArrayList與Vector的存儲(chǔ)空間茫船,每次要增加存儲(chǔ)空間時(shí)琅束,不是只增加一個(gè)存儲(chǔ)單元,而是增加多個(gè)存儲(chǔ)單元算谈,每次增加的存儲(chǔ)單元的個(gè)數(shù)在內(nèi)存空間利用與程序效率之間要取得一定的平衡角雷。Vector默認(rèn)增長(zhǎng)為原來(lái)兩倍栽惶,而ArrayList的增長(zhǎng)為原來(lái)的1.5倍惨奕。ArrayList與Vector都可以設(shè)置初始的空間大小惹悄,Vector還可以設(shè)置增長(zhǎng)的空間大小车份,而ArrayList沒(méi)有提供設(shè)置增長(zhǎng)空間的方法匙铡。
63鹃答、heap和stack有什么區(qū)別蜕衡。
【參考答案】
Java的內(nèi)存分為兩類(lèi)礁蔗,一類(lèi)是棧內(nèi)存觉义,一類(lèi)是堆內(nèi)存。棧內(nèi)存是指程序進(jìn)入一個(gè)方法時(shí)浴井,會(huì)為這個(gè)方法單獨(dú)分配一塊私屬存儲(chǔ)空間晒骇,用于存儲(chǔ)這個(gè)方法內(nèi)部的局部變量,當(dāng)這個(gè)方法結(jié)束時(shí),分配給這個(gè)方法的棧會(huì)釋放洪囤,這個(gè)棧中的變量也將隨之釋放徒坡。
堆是與棧作用不同的內(nèi)存,一般用于存放不放在當(dāng)前方法棧中的那些數(shù)據(jù)瘤缩,例如喇完,使用
new創(chuàng)建的對(duì)象都放在堆里,所以剥啤,它不會(huì)隨方法的結(jié)束而消失锦溪。方法中的局部變量使
用final修飾后,放在堆中府怯,而不是棧中刻诊。
64、Java類(lèi)實(shí)現(xiàn)序列化的方法(二種)牺丙?如在collection框架中實(shí)現(xiàn)排序则涯,要實(shí)現(xiàn)什么樣的接口
【參考答案】
java.io.Serializable接口或?qū)崿F(xiàn)Externalizable接口。
Collection框架中實(shí)現(xiàn)比較要實(shí)現(xiàn)Comparable接口或Comparator接口冲簿,并實(shí)現(xiàn)比較方法
65粟判、JAVA實(shí)現(xiàn)向數(shù)據(jù)庫(kù)添加一列。
【參考答案】
Connection con = null;
ResultSet rs = null;
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
String url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=db_name";
Connection con = DriverManager.getConnection(url,"","");
StateManager ?sm =con.createStateMent();
String sql = " alter table student ?add ?age ?int; ";
rs = sm.excute(sql);
66峦剔、什么是Java序列化浮入,如何實(shí)現(xiàn)java序列化?或者請(qǐng)解釋Serializable接口的作用羊异。【東軟國(guó)際】
【參考答案】
序列化就是一種用來(lái)處理對(duì)象流的機(jī)制事秀,所謂對(duì)象流也就是將對(duì)象的內(nèi)容進(jìn)行流化∫安埃可以對(duì)流化后的對(duì)象進(jìn)行讀寫(xiě)操作易迹,也可將流化后的對(duì)象傳輸于網(wǎng)絡(luò)之間。序列化是為了解決在對(duì)對(duì)象流進(jìn)行讀寫(xiě)操作時(shí)所引發(fā)的問(wèn)題平道。
序列化的實(shí)現(xiàn):將需要被序列化的類(lèi)實(shí)現(xiàn)Serializable接口睹欲,該接口沒(méi)有需要實(shí)現(xiàn)的方法,implements Serializable只是為了標(biāo)注該對(duì)象是可被序列化的一屋,然后使用一個(gè)輸出流(如:FileOutputStream)來(lái)構(gòu)造一個(gè)ObjectOutputStream(對(duì)象流)對(duì)象窘疮,使用ObjectOutputStream對(duì)象的writeObject(Object obj)方法就可以將參數(shù)為obj的對(duì)象寫(xiě)出,那么在另一端,通過(guò)ObjectInputStream對(duì)象的readObject(Object obj)獲取到字節(jié)流數(shù)據(jù)后冀墨,要將字節(jié)流轉(zhuǎn)換成原對(duì)象闸衫,這叫反序列化,以便將數(shù)據(jù)存儲(chǔ)在文件中或在網(wǎng)絡(luò)傳輸。
Serializable接口描述啟用其序列化功能诽嘉,未實(shí)現(xiàn)此接口的類(lèi)將無(wú)法使其任何狀態(tài)序列化或反序列化蔚出。Serializable接口沒(méi)有方法或字段弟翘,僅用于標(biāo)識(shí)可序列化的語(yǔ)義,標(biāo)識(shí)實(shí)現(xiàn)了該接口的對(duì)象屬性可被序列化骄酗。
67稀余、Java中有幾種類(lèi)型的流?JDK為每種類(lèi)型的流提供了一些抽象類(lèi)以供繼承趋翻,請(qǐng)說(shuō)出他們分別是哪些類(lèi)睛琳?
【參考答案】
字節(jié)流,字符流兩種類(lèi)型流踏烙。字節(jié)流繼承于InputStream掸掏、OutputStream;字符流繼承于Reader宙帝、Writer丧凤。其它與IO操作相關(guān)的類(lèi)都是派生至上述4個(gè)抽象類(lèi),如字節(jié)相關(guān)的:FileInputStream步脓、FileOutputStream類(lèi)愿待;字符相關(guān)的:BufferedReader、BufferedWriter類(lèi)
68靴患、用JDBC如何調(diào)用存儲(chǔ)過(guò)程
【參考答案】
通過(guò)JDBC組件中的CallableStatement接口實(shí)現(xiàn)調(diào)用存儲(chǔ)過(guò)程仍侥。
核心代碼如下:
Class.forName("com.mysql.jdbc.Driver");
Connection conn=
DriverManager.getConnection("jdbc:mysql:///test","root","root");
CallableStatement cstmt = cn.prepareCall("{call insert_Student(?,?,?)}");
cstmt.registerOutParameter(3,Types.INTEGER);
cstmt.setString(1, "wangwu");
cstmt.setInt(2, 25);
cstmt.execute();
69、JAVA事件有哪些模式鸳君?
【參考答案】
1农渊、事件直接驅(qū)動(dòng)模式。它的特點(diǎn)是直接而且快或颊,是必須經(jīng)常使用的砸紊,主要適合于迅速處理前臺(tái)的命令,通常就是我們說(shuō)的command(命令)模式囱挑。醉顽。2.監(jiān)控式事件模式。主要借助第三者來(lái)監(jiān)控和觸發(fā)事件平挑,就是通常我們說(shuō)的觀察者模式游添。特點(diǎn)是:有一個(gè)觀察者置身事外在定期獨(dú)立運(yùn)行著,我們將我們要監(jiān)聽(tīng)的事件向這個(gè)觀察者注冊(cè)通熄,這樣觀察者就代替我們來(lái)監(jiān)聽(tīng)這個(gè)事件唆涝,應(yīng)用客戶(hù)端通過(guò)觀察者來(lái)獲得事件狀況。
【分析】
70唇辨、JVM加載class文件原理廊酣?
【參考答案】
所謂裝載就是尋找一個(gè)類(lèi)或是一個(gè)接口的二進(jìn)制形式并用該二進(jìn)制形式來(lái)構(gòu)造代表這個(gè)類(lèi)或是這個(gè)接口的class對(duì)象的過(guò)程.
在Java中,類(lèi)裝載器把一個(gè)類(lèi)裝入Java虛擬機(jī)中助泽,要經(jīng)過(guò)三個(gè)步驟來(lái)完成:裝載啰扛、鏈接和初始化,其中鏈接又可以分成校驗(yàn)、準(zhǔn)備嗡贺、解析
裝載:查找和導(dǎo)入類(lèi)或接口的二進(jìn)制數(shù)據(jù)隐解;
鏈接:執(zhí)行下面的校驗(yàn)、準(zhǔn)備和解析步驟诫睬,其中解析步驟是可以選擇的煞茫;
校驗(yàn):檢查導(dǎo)入類(lèi)或接口的二進(jìn)制數(shù)據(jù)的正確性;
準(zhǔn)備:給類(lèi)的靜態(tài)變量分配并初始化存儲(chǔ)空間摄凡;
解析:將符號(hào)引用轉(zhuǎn)成直接引用续徽;
初始化:激活類(lèi)的靜態(tài)變量的初始化Java代碼和靜態(tài)Java代碼塊
JVM中類(lèi)的裝載是由ClassLoader和它的子類(lèi)來(lái)實(shí)現(xiàn)的,Java?ClassLoader是一個(gè)重要的Java運(yùn)行時(shí)系統(tǒng)組件。它負(fù)責(zé)在運(yùn)行時(shí)查找和裝入類(lèi)文件的類(lèi)
一個(gè)Java應(yīng)用程序使用兩種類(lèi)型的類(lèi)裝載器:根裝載器(bootstrap)和用戶(hù)定義的裝載器(user-defined)亲澡。
根裝載器以某種默認(rèn)的方式將類(lèi)裝入钦扭,包括那些Java?API的類(lèi)。在運(yùn)行期間一個(gè)Java程序能安裝用戶(hù)自己定義的類(lèi)裝載器床绪。根裝載器是虛擬機(jī)固有的一部分客情,而用戶(hù)定義的類(lèi)裝載器則不是,它是用Java語(yǔ)言寫(xiě)的癞己,被編譯成class文件之后然后再被裝入到虛擬機(jī)膀斋,并像其它的任何對(duì)象一樣可以被實(shí)例化。Java類(lèi)裝載器的體系結(jié)構(gòu)如下所示:
Bootstrap(根裝載器)
|
Extension?(擴(kuò)展裝載器)
|
System
|
UserDefine1
/???????????\
UserDefine2??UserDefine3
|
UserDefine4
Java的類(lèi)裝載模型是一種代理(delegation)模型痹雅。當(dāng)JVM要求類(lèi)裝載器CL(ClassLoader)裝載一個(gè)類(lèi)時(shí),CL首先將這個(gè)類(lèi)裝載請(qǐng)求轉(zhuǎn)發(fā)給他的父裝載器仰担。只有當(dāng)父裝載器沒(méi)有裝載并無(wú)法裝載這個(gè)類(lèi)時(shí),CL才獲得裝載這個(gè)類(lèi)的機(jī)會(huì)。這樣,所有類(lèi)裝載器的代理關(guān)系構(gòu)成了一種樹(shù)狀的關(guān)系绩社。樹(shù)的根是類(lèi)的根裝載器(bootstrap?ClassLoader)?,在JVM中它以"null"表示摔蓝。除根裝載器以外的類(lèi)裝載器有且僅有一個(gè)父裝載器。在創(chuàng)建一個(gè)裝載器時(shí),如果沒(méi)有顯式地給出父裝載器,那么JVM將默認(rèn)系統(tǒng)裝載器為其父裝載器
下面針對(duì)各種類(lèi)裝載器分別進(jìn)行詳細(xì)的說(shuō)明:
根(Bootstrap)裝載器:該裝載器沒(méi)有父裝載器愉耙,它是JVM實(shí)現(xiàn)的一部分项鬼,從sun.boot.class.path裝載運(yùn)行時(shí)庫(kù)的核心代碼。
擴(kuò)展(Extension)裝載器:繼承的父裝載器為根裝載器劲阎,不像根裝載器可能與運(yùn)行時(shí)的操作系統(tǒng)有關(guān)绘盟,這個(gè)類(lèi)裝載器是用純Java代碼實(shí)現(xiàn)的,它從java.ext.dirs?(擴(kuò)展目錄)中裝載代碼悯仙。
系統(tǒng)(System?or?Application)裝載器:裝載器為擴(kuò)展裝載器龄毡,我們都知道在安裝JDK的時(shí)候要設(shè)置環(huán)境變量(CLASSPATH?),這個(gè)類(lèi)裝載器就是從java.class.path(CLASSPATH環(huán)境變量)中裝載代碼的锡垄,它也是用純Java代碼實(shí)現(xiàn)的沦零,同時(shí)還是用戶(hù)自定義類(lèi)裝載器的缺省父裝載器。
小應(yīng)用程序(Applet)裝載器:裝載器為系統(tǒng)裝載器货岭,它從用戶(hù)指定的網(wǎng)絡(luò)上的特定目錄裝載小應(yīng)用程序代碼路操。
71疾渴、SOCKET中有幾中連接方式,各有什么區(qū)別屯仗?
【參考答案】
Sockets有兩種主要的操作方式:面向連接(TCP/IP)的和無(wú)連接(UDP)的搞坝。無(wú)連接的操作使用數(shù)據(jù)報(bào)協(xié)議,無(wú)連接的操作是快速的和高效的,但是數(shù)據(jù)安全性不佳.面向連接的操作使用TCP協(xié)議.面向連接的操作比無(wú)連接的操作效率更低,但是數(shù)據(jù)的安全性更高
【分析】
72魁袜、抽象類(lèi)能否被實(shí)例化桩撮?抽象類(lèi)的作用是什么?
【參考答案】
抽象類(lèi)一般不能被實(shí)例化峰弹;抽象類(lèi)通常不是由程序員定義的店量,而是由項(xiàng)目經(jīng)理或模塊設(shè)計(jì)人設(shè)計(jì)抽象類(lèi)的原因通常是為了規(guī)范方法名抽象類(lèi)必須要繼承,不然沒(méi)法用鞠呈,作為模塊設(shè)計(jì)者融师,可以把讓底層程序員直接用得方法直接調(diào)用,而一些需要讓程序員覆蓋后自己做得方法則定義稱(chēng)抽象方法
【分析】
73蚁吝、Linkedlist诬滩、Arraylist內(nèi)部是如何實(shí)現(xiàn)的(更深入的問(wèn)了LinkedList與ArrayList的區(qū)別)【天威誠(chéng)信面試題】
【參考答案】
ArrayList的內(nèi)部實(shí)現(xiàn)是基于內(nèi)部數(shù)組Object[],它更像是對(duì)數(shù)組實(shí)現(xiàn)的一種封裝灭将,所以在向ArrayList的前面或中間插入數(shù)據(jù)時(shí)疼鸟,必須將其后的所有數(shù)據(jù)相應(yīng)的后移,這樣必然要花費(fèi)較多時(shí)間庙曙。
而LinkedList的內(nèi)部實(shí)現(xiàn)是基于一組雙向鏈表實(shí)現(xiàn)的存儲(chǔ)特性空镜,所以提供了鏈表一樣訪問(wèn)的API接口,它們?cè)谛阅苌嫌泻艽蟮牟顒e捌朴。當(dāng)你訪問(wèn)Linkedlist鏈表中的某個(gè)元素時(shí)吴攒,就必須從鏈表的一端開(kāi)始沿著連接方向一個(gè)一個(gè)元素地去查找,直到找到所需的元素為止砂蔽,所以洼怔,當(dāng)你的操作是在一列數(shù)據(jù)的前面或中間添加或刪除數(shù)據(jù),并且按照順序訪問(wèn)其中的元素時(shí)左驾,就應(yīng)該使用LinkedList了镣隶。
而當(dāng)你的操作是在一列數(shù)據(jù)的后面添加數(shù)據(jù)而不是在前面或中間,并且需要隨機(jī)地訪問(wèn)其中的元素時(shí)诡右,使用ArrayList會(huì)提供比較好的性能汁蝶。
【分析】
74摸屠、Hashtable的原理【北辰網(wǎng)絡(luò)】
【參考答案】
通過(guò)節(jié)點(diǎn)的關(guān)鍵碼確定節(jié)點(diǎn)的存儲(chǔ)位置,即給定節(jié)點(diǎn)的關(guān)鍵碼k,通過(guò)一定的函數(shù)關(guān)系H(散列函數(shù)),得到函數(shù)值H(k),將此值解釋為該節(jié)點(diǎn)的存儲(chǔ)地址
75瘸爽、JDBC中的PreparedStatement相比Statement的好處播掷?
【參考答案】
預(yù)編譯語(yǔ)句java.sql.PreparedStatement ,擴(kuò)展自Statement,不但具有Statement的所有能力而且具有更強(qiáng)大的功能。不同的是猜煮,PreparedStatement是在創(chuàng)建語(yǔ)句對(duì)象的同時(shí)給出要執(zhí)行的sql語(yǔ)句次员。這樣败许,sql語(yǔ)句就會(huì)被系統(tǒng)進(jìn)行預(yù)編譯,執(zhí)行的速度會(huì)有所增加淑蔚,尤其是在執(zhí)行大語(yǔ)句的時(shí)候市殷,效果更加理想
76、sleep()和wait()區(qū)別
【參考答案】
sleep()方法:線程主動(dòng)放棄CPU束倍,使得線程在指定的時(shí)間內(nèi)進(jìn)入阻塞狀態(tài)被丧,不能得到CPU時(shí)間盟戏,指定的時(shí)間一過(guò)绪妹,線程重新進(jìn)入可執(zhí)行狀態(tài)。典型地柿究,sleep()被用在等待某個(gè)資源就緒的情形:測(cè)試發(fā)現(xiàn)條件不滿(mǎn)足后邮旷,讓線程阻塞一段時(shí)間后重新測(cè)試,直到條件滿(mǎn)足為止蝇摸。
wait( ):與notify()配套使用婶肩,wait()使得線程進(jìn)入阻塞狀態(tài),它有兩種形式貌夕,一種允許指定以毫秒為單位的一段時(shí)間作為參數(shù)律歼,另一種沒(méi)有參數(shù),當(dāng)指定時(shí)間參數(shù)時(shí)對(duì)應(yīng)的notify()被調(diào)用或者超出指定時(shí)間時(shí)線程重新進(jìn)入可執(zhí)行狀態(tài)啡专,后者則必須對(duì)應(yīng)的notify()被調(diào)用
(網(wǎng)上的答案:sleep是線程類(lèi)(Thread)的方法险毁,導(dǎo)致此線程暫停執(zhí)行指定時(shí)間,給執(zhí)行機(jī)會(huì)給其他線程们童,但是監(jiān)控狀態(tài)依然保持畔况,到時(shí)后會(huì)自動(dòng)恢復(fù)。調(diào)用sleep不會(huì)釋放對(duì)象鎖慧库。wait是Object類(lèi)的方法跷跪,對(duì)此對(duì)象調(diào)用wait方法導(dǎo)致本線程放棄對(duì)象鎖,進(jìn)入等待此對(duì)象的等待鎖定池齐板,只有針對(duì)此對(duì)象發(fā)出notify方法(或notifyAll)后本線程才進(jìn)入對(duì)象鎖定池準(zhǔn)備獲得對(duì)象鎖進(jìn)入運(yùn)行狀態(tài)吵瞻。)
sleep就是正在執(zhí)行的線程主動(dòng)讓出cpu,cpu去執(zhí)行其他線程甘磨,在sleep指定的時(shí)間過(guò)后听皿,cpu才會(huì)回到這個(gè)線程上繼續(xù)往下執(zhí)行,如果當(dāng)前線程進(jìn)入了同步鎖宽档,sleep方法并不會(huì)釋放鎖尉姨,即使當(dāng)前線程使用sleep方法讓出了cpu,但其他被同步鎖擋住了的線程也無(wú)法得到執(zhí)行吗冤。wait是指在一個(gè)已經(jīng)進(jìn)入了同步鎖的線程內(nèi)又厉,讓自己暫時(shí)讓出同步鎖九府,以便其他正在等待此鎖的線程可以得到同步鎖并運(yùn)行,只有其他線程調(diào)用了notify方法(notify并不釋放鎖覆致,只是告訴調(diào)用過(guò)wait方法的線程可以去參與獲得鎖的競(jìng)爭(zhēng)了侄旬,但不是馬上得到鎖,因?yàn)殒i還在別人手里煌妈,別人還沒(méi)釋放儡羔。如果notify方法后面的代碼還有很多,需要這些代碼執(zhí)行完后才會(huì)釋放鎖璧诵,可以在notfiy方法后增加一個(gè)等待和一些代碼汰蜘,看看效果),調(diào)用wait方法的線程就會(huì)解除wait狀態(tài)和程序可以再次得到鎖后繼續(xù)向下運(yùn)行之宿。對(duì)于wait的講解一定要配合例子代碼來(lái)說(shuō)明族操,才顯得自己真明白。
package com.huawei.interview;
public class MultiThread {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new Thread(new Thread1()).start();
try {
Thread.sleep(10);
}catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
new Thread(new Thread2()).start();
}
private static class Thread1 implements Runnable
{
@Override
public void run() {
// TODO Auto-generated method stub
//由于這里的Thread1和下面的Thread2內(nèi)部run方法要用同一對(duì)象作為監(jiān)視器比被,我們這里不能用this色难,因?yàn)樵赥hread2里面的this和這個(gè)Thread1的this不是同一個(gè)對(duì)象。我們用MultiThread.class這個(gè)字節(jié)碼對(duì)象等缀,當(dāng)前虛擬機(jī)里引用這個(gè)變量時(shí)枷莉,指向的都是同一個(gè)對(duì)象。
synchronized (MultiThread.class) {
System.out.println("enter thread1...");
System.out.println("thread1 is waiting");
try {
//釋放鎖有兩種方式尺迂,第一種方式是程序自然離開(kāi)監(jiān)視器的范圍笤妙,也就是離開(kāi)了synchronized關(guān)鍵字管轄的代碼范圍,另一種方式就是在synchronized關(guān)鍵字管轄的代碼內(nèi)部調(diào)用監(jiān)視器對(duì)象的wait方法枪狂。這里危喉,使用wait方法釋放鎖。
MultiThread.class.wait();
}catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("thread1 is going on...");
System.out.println("thread1 is being over!");
}
}
}
private static class Thread2 implements Runnable
{
@Override
public void run() {
// TODO Auto-generated method stub
synchronized (MultiThread.class) {
System.out.println("enter thread2...");
System.out.println("thread2 notify other thread can release wait status..");
//由于notify方法并不釋放鎖州疾,即使thread2調(diào)用下面的sleep方法休息了10毫秒辜限,但thread1仍然不會(huì)執(zhí)行,因?yàn)閠hread2沒(méi)有釋放鎖严蓖,所以Thread1無(wú)法得不到鎖薄嫡。
MultiThread.class.notify();
System.out.println("thread2 is sleeping ten millisecond...");
try {
Thread.sleep(10);
}catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("thread2 is going on...");
System.out.println("thread2 is being over!");
}
}
}
})
77、概述反射和序列化
【參考答案】
Reflection:是Java被視為動(dòng)態(tài)語(yǔ)言的一個(gè)關(guān)鍵性質(zhì)颗胡。這個(gè)機(jī)制允許程序在運(yùn)行時(shí)透過(guò)Reflection?APIs取得任何一個(gè)已知名稱(chēng)的class的內(nèi)部信息毫深,包括其modifiers(諸如public,?static等等)、superclass(例如Object)毒姨、實(shí)現(xiàn)之interfaces(例如Cloneable)哑蔫,也包括fields和methods的所有信息,并可于運(yùn)行時(shí)改變fields內(nèi)容或喚起methods。
序列化:就是一種用來(lái)處理對(duì)象流的機(jī)制闸迷,所謂對(duì)象流也就是將對(duì)象的內(nèi)容進(jìn)行流化嵌纲。可以對(duì)流化后的對(duì)象進(jìn)行讀寫(xiě)操作腥沽,也可將流化后的對(duì)象傳輸于網(wǎng)絡(luò)之間逮走。序列化是為了解決在對(duì)對(duì)象流進(jìn)行讀寫(xiě)操作時(shí)的問(wèn)題。
78今阳、Java中實(shí)現(xiàn)多態(tài)的機(jī)制是什么?
【參考答案】
重寫(xiě)师溅,重載
方法的重寫(xiě)Overriding和重載Overloading是Java多態(tài)性的不同表現(xiàn)。
重寫(xiě)Overriding是父類(lèi)與子類(lèi)之間多態(tài)性的一種表現(xiàn)盾舌,重載Overloading是一個(gè)類(lèi)中多態(tài)性的一種表現(xiàn)墓臭。如果在子類(lèi)中定義某方法與其父類(lèi)有相同的名稱(chēng)和參數(shù),我們說(shuō)該方法被重寫(xiě)(Overriding)矿筝。子類(lèi)的對(duì)象使用這個(gè)方法時(shí)起便,將調(diào)用子類(lèi)中的定義棚贾,對(duì)它而言窖维,父類(lèi)中的定義如同被“屏蔽”了。
果在一個(gè)類(lèi)中定義了多個(gè)同名的方法妙痹,它們或有不同的參數(shù)個(gè)數(shù)或有不同的參數(shù)類(lèi)型铸史,則稱(chēng)為方法的重載(Overloading)。Overloaded的方法是可以改變返回值的類(lèi)型怯伊。
79琳轿、Overload和Override的區(qū)別?Overloaded的方法是否可以改變返回值的類(lèi)型?【軟通動(dòng)力】
【參考答案】
Overload是重載的意思耿芹,Override是覆蓋的意思崭篡,也就是重寫(xiě)。
重載Overload表示同一個(gè)類(lèi)中可以有多個(gè)名稱(chēng)相同的方法吧秕,但這些方法的參數(shù)列表各不相同(即參數(shù)個(gè)數(shù)或類(lèi)型不同)琉闪。
重寫(xiě)Override表示子類(lèi)中的方法可以與父類(lèi)中的某個(gè)方法的名稱(chēng)和參數(shù)完全相同,通過(guò)子類(lèi)創(chuàng)建的實(shí)例對(duì)象調(diào)用這個(gè)方法時(shí)砸彬,將調(diào)用子類(lèi)中的定義方法颠毙,這相當(dāng)于把父類(lèi)中定義的那個(gè)完全相同的方法給覆蓋了,這也是面向?qū)ο缶幊痰亩鄳B(tài)性的一種表現(xiàn)砂碉。子類(lèi)覆蓋父類(lèi)的方法時(shí)蛀蜜,只能比父類(lèi)拋出更少的異常,或者是拋出父類(lèi)拋出的異常的子異常增蹭,因?yàn)樽宇?lèi)可以解決父類(lèi)的一些問(wèn)題滴某,不能比父類(lèi)有更多的問(wèn)題。子類(lèi)方法的訪問(wèn)權(quán)限只能比父類(lèi)的更大,不能更小霎奢。如果父類(lèi)的方法是private類(lèi)型偏瓤,那么,子類(lèi)則不存在覆蓋的限制椰憋,相當(dāng)于子類(lèi)中增加了一個(gè)全新的方法厅克。
是否可以改變返回值類(lèi)型,在重載的定義中橙依,與方法是什么類(lèi)型返回值無(wú)關(guān)证舟。
【分析】
override可以翻譯為覆蓋,從字面就可以知道窗骑,它是覆蓋了一個(gè)方法并且對(duì)其重寫(xiě)女责,以求達(dá)到不同的作用。對(duì)我們來(lái)說(shuō)最熟悉的覆蓋就是對(duì)接口方法的實(shí)現(xiàn)创译,在接口中一般只是對(duì)方法進(jìn)行了聲明抵知,而我們?cè)趯?shí)現(xiàn)時(shí),就需要實(shí)現(xiàn)接口聲明的所有方法软族。除了這個(gè)典型的用法以外刷喜,我們?cè)诶^承中也可能會(huì)在子類(lèi)覆蓋父類(lèi)中的方法。在覆蓋要注意以下的幾點(diǎn):
1立砸、覆蓋的方法的標(biāo)志必須要和被覆蓋的方法的標(biāo)志完全匹配掖疮,才能達(dá)到覆蓋的效果;
2颗祝、覆蓋的方法的返回值必須和被覆蓋的方法的返回一致浊闪;
3、覆蓋的方法所拋出的異常必須和被覆蓋方法的所拋出的異常一致螺戳,或者是其子類(lèi)搁宾;
4、被覆蓋的方法不能為private倔幼,否則在其子類(lèi)中只是新定義了一個(gè)方法盖腿,并沒(méi)有對(duì)其進(jìn)行覆蓋。
overload對(duì)我們來(lái)說(shuō)可能比較熟悉凤藏,可以翻譯為重載奸忽,它是指我們可以定義一些名稱(chēng)相同的方法,通過(guò)定義不同的輸入?yún)?shù)來(lái)區(qū)分這些方法揖庄,然后再調(diào)用時(shí)栗菜,VM就會(huì)根據(jù)不同的參數(shù)樣式,來(lái)選擇合適的方法執(zhí)行蹄梢。在使用重載要注意以下的幾點(diǎn):
1疙筹、在使用重載時(shí)只能通過(guò)不同的參數(shù)樣式富俄。例如,不同的參數(shù)類(lèi)型而咆,不同的參數(shù)個(gè)數(shù)霍比,不同的參數(shù)順序(當(dāng)然,同一方法內(nèi)的幾個(gè)參數(shù)類(lèi)型必須不一樣暴备,例如可以是fun(int,float)悠瞬,但是不能為fun(int,int));
2涯捻、不能通過(guò)訪問(wèn)權(quán)限浅妆、返回類(lèi)型、拋出的異常進(jìn)行重載障癌;
3督赤、方法的異常類(lèi)型和數(shù)目不會(huì)對(duì)重載造成影響稽犁;
4、對(duì)于繼承來(lái)說(shuō)如迟,如果某一方法在父類(lèi)中是訪問(wèn)權(quán)限是priavte诀拭,那么就不能在子類(lèi)對(duì)其進(jìn)行重載摸吠,如果定義的話(huà)纬凤,也只是定義了一個(gè)新方法姿搜,而不會(huì)達(dá)到重載的效果。
80哀托、ClassLoader如何加載class惦辛。
【參考答案】
jvm里有多個(gè)類(lèi)加載劳秋,每個(gè)類(lèi)加載可以負(fù)責(zé)加載特定位置的類(lèi)仓手,例如,bootstrap類(lèi)加載負(fù)責(zé)加載jre/lib/rt.jar中的類(lèi)玻淑,我們平時(shí)用的jdk中的類(lèi)都位于rt.jar中嗽冒。extclassloader負(fù)責(zé)加載jar/lib/ext/*.jar中的類(lèi),appclassloader負(fù)責(zé)classpath指定的目錄或jar中的類(lèi)补履。除了bootstrap之外添坊,其他的類(lèi)加載器本身也都是java類(lèi),它們的父類(lèi)是ClassLoader箫锤。
81贬蛙、ArrayList如何實(shí)現(xiàn)插入的數(shù)據(jù)按自定義的方式有序存放
【參考答案】
實(shí)現(xiàn)Comparable比較接口,并實(shí)現(xiàn)compareTo方法谚攒。排序的方法阳准,取決于compareTo方法中的比較定義的返回值,一般有3個(gè)返回值:1、-1馏臭、0表示不同的比較結(jié)果野蝇。
程序示例:
class MyBean implementsComparable{
public intcompareTo(Object obj){
if(! obj instanceof MyBean)
throw new ClassCastException();
MyBean other = (MyBean) obj;
return age > other.age?1:age== other.age?0:-1;
}
}
class MyTreeSet {
private ArrayList ?datas = new ArrayList();
public void add(Object obj){
for(int i=0;i
if(obj.compareTo(datas.get(i) != 1){
datas.add(i,obj);
}
}
}
}
82、hashCode方法的作用?
【參考答案】
hashcode這個(gè)方法是用來(lái)鑒定2個(gè)對(duì)象是否相等的绕沈。hashcode方法一般用戶(hù)不會(huì)去調(diào)用锐想,比如在hashmap中,由于key是不可以重復(fù)的乍狐,他在判斷key是不是重復(fù)的時(shí)候就判斷了hashcode這個(gè)方法赠摇,而且也用到了equals方法。這里不可以重復(fù)是說(shuō)equals和hashcode只要有一個(gè)不等就可以了浅蚪!所以簡(jiǎn)單來(lái)講蝉稳,hashcode相當(dāng)于是一個(gè)對(duì)象的編碼。我們一般在覆蓋equals的同時(shí)也要覆蓋hashcode掘鄙,讓他們的邏輯一致耘戚。
83、abstract的method是否可同時(shí)是static,是否可同時(shí)是native操漠,是否可同時(shí)是synchronized?
【參考答案】
abstract的method不可以是static的收津,因?yàn)槌橄蟮姆椒ㄊ且蛔宇?lèi)實(shí)現(xiàn)的,而static與子類(lèi)扯不上關(guān)系浊伙!
native方法表示該方法要用另外一種依賴(lài)平臺(tái)的編程語(yǔ)言實(shí)現(xiàn)的撞秋,不存在著被子類(lèi)實(shí)現(xiàn)的問(wèn)題,所以嚣鄙,它也不能是抽象的吻贿,不能與abstract混用。例如哑子,F(xiàn)ileOutputSteam類(lèi)要硬件打交道舅列,底層的實(shí)現(xiàn)用的是操作系統(tǒng)相關(guān)的api實(shí)現(xiàn),例如卧蜓,在windows用c語(yǔ)言實(shí)現(xiàn)的帐要,所以,查看jdk的源代碼弥奸,可以發(fā)現(xiàn)FileOutputStream的open方法的定義如下:
private native void open(String name) throws FileNotFoundException;
如果我們要用java調(diào)用別人寫(xiě)的c語(yǔ)言函數(shù)榨惠,我們是無(wú)法直接調(diào)用的,我們需要按照java的要求寫(xiě)一個(gè)c語(yǔ)言的函數(shù)盛霎,又我們的這個(gè)c語(yǔ)言函數(shù)去調(diào)用別人的c語(yǔ)言函數(shù)赠橙。由于我們的c語(yǔ)言函數(shù)是按java的要求來(lái)寫(xiě)的,我們這個(gè)c語(yǔ)言函數(shù)就可以與java對(duì)接上愤炸,java那邊的對(duì)接方式就是定義出與我們這個(gè)c函數(shù)相對(duì)應(yīng)的方法期揪,java中對(duì)應(yīng)的方法不需要寫(xiě)具體的代碼,但需要在前面聲明native摇幻。
關(guān)于synchronized與abstract合用的問(wèn)題横侦,我覺(jué)得也不行挥萌,因?yàn)樵谖規(guī)啄甑膶W(xué)習(xí)和開(kāi)發(fā)中,從來(lái)沒(méi)見(jiàn)到過(guò)這種情況枉侧,并且我覺(jué)得synchronized應(yīng)該是作用在一個(gè)具體的方法上才有意義引瀑。而且,方法上的synchronized同步所使用的同步鎖對(duì)象是this榨馁,而抽象方法上無(wú)法確定this是什么憨栽。
84、Anonymous Inner Class (匿名內(nèi)部類(lèi))是否可以extends(繼承)其它類(lèi)翼虫,是否可以implements(實(shí)現(xiàn))interface(接口)?
【參考答案】
可以繼承其他類(lèi)或?qū)崿F(xiàn)其他接口屑柔。不僅是可以,而是必須!
85珍剑、JAVA語(yǔ)言如何進(jìn)行異常處理掸宛,關(guān)鍵字:throws,throw,try,catch,finally分別代表什么意義?在try塊中可以?huà)伋霎惓幔?/b>
【參考答案】
Java使用面向?qū)ο蟮姆绞絹?lái)處理異常招拙,它把程序中發(fā)生的每個(gè)異常也都分別封裝到一個(gè)對(duì)象來(lái)表示的唧瘾,該對(duì)象中包含有異常的信息。而throws\throw\try别凤、catch饰序、finally就是Java中用來(lái)對(duì)異常進(jìn)行處理的幾個(gè)關(guān)鍵字,在Java編程中規(guī)容Java編譯器強(qiáng)制普通異常必須try..catch處理或用throws聲明繼續(xù)拋給上層調(diào)用方法處理规哪,一般異常必須要求被捕獲和處理求豫,而系統(tǒng)異常可以處理也可以不處理诉稍,所以編譯器不強(qiáng)制用try..catch處理或用throws蝠嘉、throw聲明異常。而finally一般與try或try\catch一起使用做為異常的最后處理出口均唉。
86是晨、同步和異步有何異同,在什么情況下分別使用他們舔箭?舉例說(shuō)明。
【參考答案】
如果數(shù)據(jù)將在線程間共享蚊逢。例如正在寫(xiě)的數(shù)據(jù)以后可能被另一個(gè)線程讀到层扶,或者正在讀的數(shù)據(jù)可能已經(jīng)被另一個(gè)線程寫(xiě)過(guò)了,那么這些數(shù)據(jù)就是共享數(shù)據(jù)烙荷,必須進(jìn)行同步存取镜会。
當(dāng)應(yīng)用程序在對(duì)象上調(diào)用了一個(gè)需要花費(fèi)很長(zhǎng)時(shí)間來(lái)執(zhí)行的方法,并且不希望讓程序等待方法的返回時(shí)终抽,就應(yīng)該使用異步編程戳表,在很多情況下采用異步途徑往往更有效率桶至。
87、當(dāng)一個(gè)線程進(jìn)入一個(gè)對(duì)象的一個(gè)synchronized方法后匾旭,其它線程是否可進(jìn)入此對(duì)象的其它方法?
【參考答案】
分幾種情況:
1.其他方法前是否加了synchronized關(guān)鍵字镣屹,如果沒(méi)加,則能价涝。
2.如果這個(gè)方法內(nèi)部調(diào)用了wait女蜈,則可以進(jìn)入其他synchronized方法。
3.如果其他個(gè)方法都加了synchronized關(guān)鍵字色瘩,并且內(nèi)部沒(méi)有調(diào)用wait伪窖,則不能。
4.如果其他方法是static居兆,它用的同步鎖是當(dāng)前類(lèi)的字節(jié)碼覆山,與非靜態(tài)的方法不能同步,因?yàn)榉庆o態(tài)的方法用的是this泥栖。
88汹买、線程的基本概念、線程的基本狀態(tài)以及狀態(tài)之間的關(guān)系
【參考答案】
一個(gè)程序中可以有多條執(zhí)行線索同時(shí)執(zhí)行聊倔,一個(gè)線程就是程序中的一條執(zhí)行線索晦毙,每個(gè)線程上都關(guān)聯(lián)有要執(zhí)行的代碼,即可以有多段程序代碼同時(shí)運(yùn)行耙蔑,每個(gè)程序至少都有一個(gè)線程见妒,即main方法執(zhí)行的那個(gè)線程。如果只是一個(gè)cpu甸陌,它怎么能夠同時(shí)執(zhí)行多段程序呢须揣?這是從宏觀上來(lái)看的,cpu一會(huì)執(zhí)行a線索钱豁,一會(huì)執(zhí)行b線索耻卡,切換時(shí)間很快,給人的感覺(jué)是a,b在同時(shí)執(zhí)行牲尺,好比大家在同一個(gè)辦公室上網(wǎng)卵酪,只有一條鏈接到外部網(wǎng)線,其實(shí)谤碳,這條網(wǎng)線一會(huì)為a傳數(shù)據(jù)溃卡,一會(huì)為b傳數(shù)據(jù),由于切換時(shí)間很短暫蜒简,所以瘸羡,大家感覺(jué)都在同時(shí)上網(wǎng)。
狀態(tài):就緒搓茬,運(yùn)行犹赖,synchronize阻塞队他,wait和sleep掛起,結(jié)束峻村。wait必須在synchronized內(nèi)部調(diào)用麸折。
調(diào)用線程的start方法后線程進(jìn)入就緒狀態(tài),線程調(diào)度系統(tǒng)將就緒狀態(tài)的線程轉(zhuǎn)為運(yùn)行狀態(tài)雀哨,遇到synchronized語(yǔ)句時(shí)磕谅,由運(yùn)行狀態(tài)轉(zhuǎn)為阻塞,當(dāng)synchronized獲得鎖后雾棺,由阻塞轉(zhuǎn)為運(yùn)行膊夹,在這種情況可以調(diào)用wait方法轉(zhuǎn)為掛起狀態(tài),當(dāng)線程關(guān)聯(lián)的代碼執(zhí)行完后捌浩,線程變?yōu)榻Y(jié)束狀態(tài)放刨。
89、簡(jiǎn)述synchronized和java.util.concurrent.locks.Lock的異同尸饺?
【參考答案】
主要相同點(diǎn):Lock能完成synchronized所實(shí)現(xiàn)的所有功能
主要不同點(diǎn):Lock有比synchronized更精確的線程語(yǔ)義和更好的性能进统。synchronized會(huì)自動(dòng)釋放鎖,而Lock一定要求程序員手工釋放浪听,并且必須在finally從句中釋放螟碎。Lock還有更強(qiáng)大的功能,例如迹栓,它的tryLock方法可以非阻塞方式去拿鎖掉分。
90、HashMap和Hashtable的區(qū)別克伊?【北通網(wǎng)科】
【參考答案】
HashMap是Hashtable的輕量級(jí)實(shí)現(xiàn)(非線程安全的實(shí)現(xiàn))酥郭,他們都實(shí)現(xiàn)Map接口,主要區(qū)別在于HashMap允許空(null)鍵值(key),由于非線程安全愿吹,在只有一個(gè)線程訪問(wèn)的情況下不从,效率要高于Hashtable。
HashMap允許將null作為一個(gè)entry的key或者value犁跪,而Hashtable不允許椿息。
HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey耘拇。因?yàn)閏ontains方法容易讓人引起誤解撵颊。
Hashtable繼承自Dictionary類(lèi),而HashMap是Java1.2引進(jìn)的Map interface的一個(gè)實(shí)現(xiàn)惫叛。
最大的不同是段直,Hashtable的方法是synchronized的烘挫,而HashMap不是冰木,在多個(gè)線程訪問(wèn)Hashtable時(shí)饼丘,不需要自己為它的方法實(shí)現(xiàn)同步,而HashMap就必須為之提供外同步仑最。
Hashtable和HashMap采用的hash/rehash算法都大概一樣扔役,所以性能不會(huì)有很大的差異。
91警医、List亿胸、Set、Map是否繼承自Collection接口?
【參考答案】
List预皇、Set是侈玄,Map不是;Map接口定義的是Key-Value存儲(chǔ)的特性吟温,與List和Set不同序仙,Map在存儲(chǔ)對(duì)象時(shí),先要定義這個(gè)對(duì)象的key的值鲁豪,再存入與這個(gè)key相對(duì)應(yīng)的Object潘悼,Map集合的取值時(shí)根據(jù)存入的key(關(guān)鍵字)來(lái)獲取與這個(gè)關(guān)鍵字對(duì)應(yīng)的對(duì)象。
92爬橡、List治唤、Map、Set三個(gè)接口糙申,存取元素時(shí)宾添,各有什么特點(diǎn)?
【參考答案】
首先郭宝,List與Set具有相似性辞槐,它們都是單列元素的集合,所以粘室,它們有一個(gè)功共同的父接口Collection接口榄檬。Set里面不允許有重復(fù)的元素,即不能有兩個(gè)相等的對(duì)象衔统。
List表示有先后順序的集合鹿榜,當(dāng)我們多次調(diào)用add(Obj e)方法時(shí),每次加入的對(duì)象就像火車(chē)站買(mǎi)票有排隊(duì)順序一樣锦爵,按先來(lái)后到的順序排序舱殿。
Map與List和Set不同,它是雙列的集合每次存儲(chǔ)時(shí)险掀,要存儲(chǔ)一對(duì)key/value沪袭,不能存儲(chǔ)重復(fù)的key,這個(gè)重復(fù)的規(guī)則也是按equals比較相等樟氢。取則可以根據(jù)key獲得相應(yīng)的value冈绊,即get(Object key)返回值為key所對(duì)應(yīng)的value侠鳄。另外,也可以獲得所有的key的結(jié)合死宣。
【分析】
總結(jié):List以特定次序來(lái)持有元素伟恶,可有重復(fù)元素。Set無(wú)法擁有重復(fù)元素,內(nèi)部排序毅该。Map保存key-value值博秫,value可多值。上面是大致不同眶掌,另外上述3個(gè)只是接口挡育,而具體實(shí)現(xiàn)類(lèi)中,用法大同小異畏线,只是實(shí)現(xiàn)的數(shù)據(jù)結(jié)構(gòu)不同静盅,例如List接口下的LinkedList主要實(shí)現(xiàn)了雙鏈表的存儲(chǔ)特點(diǎn),Vector是線程安全的集合類(lèi)寝殴。
93蒿叠、說(shuō)出ArrayList,Vector, LinkedList的存儲(chǔ)性能和特性◎汲#【大唐動(dòng)力面試題】
【參考答案】
ArrayList和Vector都是使用數(shù)組方式存儲(chǔ)數(shù)據(jù)市咽,此數(shù)組元素?cái)?shù)大于實(shí)際存儲(chǔ)的數(shù)據(jù)以便增加和插入元素,它們都允許直接按序號(hào)索引元素抵蚊,但是插入元素要涉及數(shù)組元素移動(dòng)等內(nèi)存操作施绎,所以索引數(shù)據(jù)快而插入數(shù)據(jù)慢,Vector由于使用了synchronized方法(線程安全)贞绳,通常性能上較ArrayList差谷醉,而LinkedList使用雙向鏈表實(shí)現(xiàn)存儲(chǔ),按序號(hào)索引數(shù)據(jù)需要進(jìn)行前向或后向遍歷冈闭,但是插入數(shù)據(jù)時(shí)只需要記錄本項(xiàng)的前后項(xiàng)即可俱尼,所以插入速度較快。
LinkedList也是線程不安全的萎攒,LinkedList提供了一些方法遇八,使得LinkedList可以被當(dāng)作堆棧和隊(duì)列來(lái)使用。
94耍休、如何去掉一個(gè)Vector集合中重復(fù)的元素
【參考答案】
Vector newVector = new Vector();
for (int i=0;i
{
Object obj = vector.get(i);
if(!newVector.contains(obj);
newVector.add(obj);
}
還有一種簡(jiǎn)單的方式刃永,HashSet set = new HashSet(vector);
95、Set里的元素是不能重復(fù)的羊精,那么用什么方法來(lái)區(qū)分重復(fù)與否呢?是用==還是equals()?它們有何區(qū)別?
【參考答案】
Set里的元素是不能重復(fù)的斯够,元素重復(fù)與否是使用equals()方法進(jìn)行判斷的。
96、兩個(gè)對(duì)象值相同(x.equals(y) == true)雳刺,但卻可有不同的hash code劫灶,這句話(huà)對(duì)不對(duì)?
【參考答案】
對(duì)裸违。
如果對(duì)象要保存在HashSet或HashMap中掖桦,它們的equals相等,那么供汛,它們的hashcode值就必須相等枪汪。
如果不是要保存在HashSet或HashMap,則與hashcode沒(méi)有什么關(guān)系了怔昨,這時(shí)候hashcode不等是可以的雀久,例如arrayList存儲(chǔ)的對(duì)象就不用實(shí)現(xiàn)hashcode方法。
97趁舀、字節(jié)流與字符流的區(qū)別
【參考答案】
要把一片二進(jìn)制數(shù)據(jù)數(shù)據(jù)逐一輸出到某個(gè)設(shè)備中赖捌,或者從某個(gè)設(shè)備中逐一讀取一片二進(jìn)制數(shù)據(jù),不管輸入輸出設(shè)備是什么矮烹,我們要用統(tǒng)一的方式來(lái)完成這些操作越庇,用一種抽象的方式進(jìn)行描述,這個(gè)抽象描述方式起名為IO流奉狈,對(duì)應(yīng)的抽象類(lèi)為OutputStream和InputStream卤唉,不同的實(shí)現(xiàn)類(lèi)就代表不同的輸入和輸出設(shè)備,它們都是針對(duì)字節(jié)進(jìn)行操作的仁期。
在應(yīng)用中桑驱,經(jīng)常要完全是字符的一段文本輸出去或讀進(jìn)來(lái),用字節(jié)流可以嗎跛蛋?計(jì)算機(jī)中的一切最終都是二進(jìn)制的字節(jié)形式存在熬的。對(duì)于“中國(guó)”這些字符,首先要得到其對(duì)應(yīng)的字節(jié)赊级,然后將字節(jié)寫(xiě)入到輸出流押框。讀取時(shí),首先讀到的是字節(jié)此衅,可是我們要把它顯示為字符强戴,我們需要將字節(jié)轉(zhuǎn)換成字符。由于這樣的需求很廣泛挡鞍,人家專(zhuān)門(mén)提供了字符流的包裝類(lèi)骑歹。
底層設(shè)備永遠(yuǎn)只接受字節(jié)數(shù)據(jù),有時(shí)候要寫(xiě)字符串到底層設(shè)備墨微,需要將字符串轉(zhuǎn)成字節(jié)再進(jìn)行寫(xiě)入道媚。字符流是字節(jié)流的包裝,字符流則是直接接受字符串,它內(nèi)部將串轉(zhuǎn)成字節(jié)最域,再寫(xiě)入底層設(shè)備谴分,這為我們向IO設(shè)別寫(xiě)入或讀取字符串提供了一點(diǎn)點(diǎn)方便。
字符向字節(jié)轉(zhuǎn)換時(shí)镀脂,要注意編碼的問(wèn)題牺蹄,因?yàn)樽址D(zhuǎn)成字節(jié)數(shù)組,
其實(shí)是轉(zhuǎn)成該字符的某種編碼的字節(jié)形式薄翅,讀取也是反之的道理沙兰。
講解字節(jié)流與字符流關(guān)系的代碼案例:
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.PrintWriter;
public class IOTest {
public static void main(String[] args) throws Exception {
String str = "中國(guó)人";
/*FileOutputStream fos ?= new FileOutputStream("1.txt");
fos.write(str.getBytes("UTF-8"));
fos.close();*/
/*FileWriter fw = new FileWriter("1.txt");
fw.write(str);
fw.close();*/
PrintWriter pw = new PrintWriter("1.txt","utf-8");
pw.write(str);
pw.close();
/*FileReader fr = new FileReader("1.txt");
char[] buf = new char[1024];
int len = fr.read(buf);
String myStr = new String(buf,0,len);
System.out.println(myStr);*/
/*FileInputStream fr = new FileInputStream("1.txt");
byte[] buf = new byte[1024];
int len = fr.read(buf);
String myStr = new String(buf,0,len,"UTF-8");
System.out.println(myStr);*/
BufferedReader br = new BufferedReader(
new InputStreamReader(
new FileInputStream("1.txt"),"UTF-8"
)
);
String myStr = br.readLine();
br.close();
System.out.println(myStr);
}
}
98、java里面的io跟nio有什么區(qū)別
【參考答案】
1翘魄、Java NIO和IO之間第一個(gè)最大的區(qū)別是鼎天,IO是面向流的,NIO是面向緩沖區(qū)的暑竟。
2斋射、Java IO的各種流是阻塞的。而Java NIO的非阻塞模式但荤,使一個(gè)線程從某通道發(fā)送請(qǐng)求讀取數(shù)據(jù)罗岖,但是它僅能得到目前可用的數(shù)據(jù),如果目前沒(méi)有數(shù)據(jù)可用時(shí)纱兑,就什么都不會(huì)獲取呀闻。而不是保持線程阻塞,所以直至數(shù)據(jù)變的可以讀取之前潜慎,該線程可以繼續(xù)做其他的事情捡多。
3、選擇器上铐炫,Java IO無(wú)選擇器垒手,而NIO有選擇器,Java NIO的選擇器允許一個(gè)單獨(dú)的線程來(lái)監(jiān)視多個(gè)輸入通道倒信,你可以注冊(cè)多個(gè)通道使用一個(gè)選擇器科贬,然后使用一個(gè)單獨(dú)的線程來(lái)“選擇”通道:這些通道里已經(jīng)有可以處理的輸入,或者選擇已準(zhǔn)備寫(xiě)入的通道鳖悠。
99榜掌、Java中會(huì)存在內(nèi)存泄漏嗎,請(qǐng)簡(jiǎn)單描述乘综。
【參考答案】
所謂內(nèi)存泄露就是指一個(gè)不再被程序使用的對(duì)象或變量一直被占據(jù)在內(nèi)存中憎账。java中有垃圾回收機(jī)制,它可以保證一對(duì)象不再被引用的時(shí)候卡辰,即對(duì)象變成了孤兒的時(shí)候胞皱,對(duì)象將自動(dòng)被垃圾回收器從內(nèi)存中清除掉邪意。由于Java使用有向圖的方式進(jìn)行垃圾回收管理,可以消除引用循環(huán)的問(wèn)題反砌,例如有兩個(gè)對(duì)象雾鬼,相互引用,只要它們和根進(jìn)程不可達(dá)的宴树,那么GC也是可以回收它們的策菜,例如下面的代碼可以看到這種情況的內(nèi)存回收:
package com.huawei.interview;
import java.io.IOException;
public class GarbageTest {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
try {
gcTest();
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("has exited gcTest!");
System.in.read();
System.in.read();
System.out.println("out begin gc!");
for(int i=0;i<100;i++)
{
System.gc();
System.in.read();
System.in.read();
}
}
private static void gcTest() throws IOException {
System.in.read();
System.in.read();
Person p1 = new Person();
System.in.read();
System.in.read();
Person p2 = new Person();
p1.setMate(p2);
p2.setMate(p1);
System.out.println("before exit gctest!");
System.in.read();
System.in.read();
System.gc();
System.out.println("exit gctest!");
}
private static class Person
{
byte[] data = new byte[20000000];
Person mate = null;
public void setMate(Person other)
{
mate = other;
}
}
}
java中的內(nèi)存泄露的情況:長(zhǎng)生命周期的對(duì)象持有短生命周期對(duì)象的引用就很可能發(fā)生內(nèi)存泄露,盡管短生命周期對(duì)象已經(jīng)不再需要森渐,但是因?yàn)殚L(zhǎng)生命周期對(duì)象持有它的引用而導(dǎo)致不能被回收做入,這就是java中內(nèi)存泄露的發(fā)生場(chǎng)景,通俗地說(shuō)同衣,就是程序員可能創(chuàng)建了一個(gè)對(duì)象,以后一直不再使用這個(gè)對(duì)象壶运,這個(gè)對(duì)象卻一直被引用耐齐,即這個(gè)對(duì)象無(wú)用但是卻無(wú)法被垃圾回收器回收的,這就是java中可能出現(xiàn)內(nèi)存泄露的情況蒋情,例如埠况,緩存系統(tǒng),我們加載了一個(gè)對(duì)象放在緩存中(例如放在一個(gè)全局map對(duì)象中)棵癣,然后一直不再使用它辕翰,這個(gè)對(duì)象一直被緩存引用,但卻不再被使用狈谊。
檢查java中的內(nèi)存泄露喜命,一定要讓程序?qū)⒏鞣N分支情況都完整執(zhí)行到程序結(jié)束,然后看某個(gè)對(duì)象是否被使用過(guò)河劝,如果沒(méi)有壁榕,則才能判定這個(gè)對(duì)象屬于內(nèi)存泄露。
如果一個(gè)外部類(lèi)的實(shí)例對(duì)象的方法返回了一個(gè)內(nèi)部類(lèi)的實(shí)例對(duì)象赎瞎,這個(gè)內(nèi)部類(lèi)對(duì)象被長(zhǎng)期引用了牌里,即使那個(gè)外部類(lèi)實(shí)例對(duì)象不再被使用,但由于內(nèi)部類(lèi)持久外部類(lèi)的實(shí)例對(duì)象务甥,這個(gè)外部類(lèi)對(duì)象將不會(huì)被垃圾回收牡辽,這也會(huì)造成內(nèi)存泄露。
[]是對(duì)象已不可到達(dá)敞临,而內(nèi)存又沒(méi)有回收态辛,真正的內(nèi)存黑洞。
而Java的泄漏哟绊,則是因?yàn)楦鞣N原因因妙,對(duì)象對(duì)應(yīng)用已經(jīng)無(wú)用痰憎,但一直被持有,一直可到達(dá)攀涵。
總結(jié)原因無(wú)外乎幾方面:
1.被生命周期極長(zhǎng)的集合類(lèi)不當(dāng)持有铣耘,號(hào)稱(chēng)是Java內(nèi)存泄漏的首因。
這些集合類(lèi)的生命周期通常極長(zhǎng)以故,而且是一個(gè)輔助管理性質(zhì)的對(duì)象蜗细,在一個(gè)業(yè)務(wù)事務(wù)運(yùn)行完后,如果沒(méi)有將某個(gè)業(yè)務(wù)對(duì)象主動(dòng)的從中清除的話(huà)怒详,這個(gè)集合就會(huì)吃越來(lái)越多內(nèi)存炉媒,可以用WeakReference,如WeakHashMap昆烁,使得它持有的對(duì)象不增加對(duì)象的引用數(shù)吊骤。
2.Scope定義不對(duì),這個(gè)很簡(jiǎn)單了静尼,方法的局部變量定義成類(lèi)的變量白粉,類(lèi)的靜態(tài)變量等。
3.異常時(shí)沒(méi)有加finally{}來(lái)釋放某些資源鼠渺,JDBC時(shí)代也是很普遍的事情鸭巴。
4.另外一些我了解不深的原因,如:Swing里的Listener沒(méi)有顯式remove拦盹;內(nèi)部類(lèi)持有外部對(duì)象的隱式引用鹃祖;Finalizers造成關(guān)聯(lián)對(duì)象沒(méi)有被及時(shí)清空等。
內(nèi)存泄漏的檢測(cè)
有不少工具輔助做這個(gè)事情的普舆,如果手上一個(gè)工具也沒(méi)有吨瞎,可以用JDK自帶的小工具:
·看看誰(shuí)占滿(mǎn)了Heap寺晌?
用JDK6的jmap可以顯示運(yùn)行程序中對(duì)象的類(lèi)型掉丽,個(gè)數(shù)與所占的大小
先用jps找到進(jìn)程號(hào)签孔,然后jmap -histo pid顯示或jmap -dump:file=heap_file_name pid導(dǎo)出heap文件
·為什么這些對(duì)象仍然可以到達(dá)?
用jhat(Java Heap Analysis Tool)分析剛才導(dǎo)出的heap文件华临。
先jhat heap_file_name芯杀,然后打開(kāi)瀏覽器http://localhost:7000/瀏覽。
100雅潭、Hashcode和Equals的聯(lián)系
【參考答案】
首先equals()和hashcode()這兩個(gè)方法都是從object類(lèi)中繼承過(guò)來(lái)的揭厚,主要用來(lái)比較對(duì)象時(shí)進(jìn)行調(diào)用。在object類(lèi)中定義如下:
a)扶供、如果兩個(gè)對(duì)象相同筛圆,那么它們的hashCode值一定要相同;
b)椿浓、如果兩個(gè)對(duì)象的hashCode相同太援,它們并不一定相同上面說(shuō)的對(duì)象相同指的是用eqauls方法比較闽晦。
101、Tread和Threadlocal的作用及區(qū)別提岔?
【參考答案】
答:threadlocal是線程局部變量(thread local variable)仙蛉,為每一個(gè)使用該線程的線程都提供一個(gè)變量值的副本,使每一個(gè)線程都可以獨(dú)立地改變自己的副本碱蒙,而不會(huì)和其他線程的副本產(chǎn)生沖突荠瘪。
102、TCP和UDP的區(qū)別赛惩?
【參考答案】
TCP/IP的運(yùn)輸層有兩個(gè)不同的協(xié)議:①用戶(hù)數(shù)據(jù)報(bào)協(xié)議UDP②傳輸控制協(xié)議TCP
二者最大區(qū)別:TCP是面向連接的,而UDP是無(wú)連接的.區(qū)別大致如下:
1)UDP傳送的數(shù)據(jù)單位協(xié)議是UDP報(bào)文或用戶(hù)數(shù)據(jù)報(bào),TCP傳送的數(shù)據(jù)單位協(xié)議是TCP報(bào)文段哀墓。
2)UDP發(fā)送數(shù)據(jù)之前不需要建立連接,因此減少了開(kāi)銷(xiāo)和發(fā)送之前的時(shí)延。TCP提供面向連接的服務(wù),不提供廣播或多播服務(wù)喷兼。
3)對(duì)方的運(yùn)輸層在收到UDP報(bào)文后,不需要給出任何確認(rèn)篮绰。TCP則需要確認(rèn)。
4)UDP沒(méi)有擁塞控制,因此網(wǎng)絡(luò)出現(xiàn)的擁塞不會(huì)使源主機(jī)的發(fā)送速率降低,也不保證可靠交付,因此主機(jī)不需要維持具有許多參數(shù)的褒搔、復(fù)雜的連接狀態(tài)表阶牍。TCP要提供可靠的、面向連接的運(yùn)輸服務(wù),因此不可避免地增加了許多的開(kāi)銷(xiāo),這不僅使協(xié)議數(shù)據(jù)單元的首部增大很多,還要占用許多的處理機(jī)資源星瘾。
5)UDP用戶(hù)數(shù)據(jù)報(bào)只有8個(gè)字節(jié)的首部開(kāi)銷(xiāo),比TCP的20個(gè)字節(jié)的首部要短。
103惧辈、啟動(dòng)一個(gè)線程用什么方法琳状?【北京永中軟件面試題】
【參考】
使用Thread類(lèi)的start()方法來(lái)啟動(dòng)一個(gè)線程,使線程進(jìn)入就緒狀態(tài)盒齿。如果自定義的類(lèi)是Thread類(lèi)的子類(lèi)的話(huà)念逞,可以直接使用Start()來(lái)啟,如果是實(shí)現(xiàn)的Runnable接口的話(huà)边翁,還要將該類(lèi)的實(shí)例作為參數(shù)傳入到Thread對(duì)象中來(lái)啟動(dòng)翎承。
104、作用域public等寫(xiě)不寫(xiě)的區(qū)別符匾?【北京永中軟件面試題】
【參考】
作用域不寫(xiě)將采用默認(rèn)的作用域,默認(rèn)作用域的訪問(wèn)權(quán)限是包的權(quán)限叨咖,也就是除本包中的所有類(lèi)能訪問(wèn),不同包只有子類(lèi)能訪問(wèn)啊胶。
105甸各、同步和異步有何異同
【參考答案】
同步(synchronized)和異步(asynchronized)是對(duì)于多線程(multi-threading)而言的
同步可防止并發(fā)主要出于數(shù)據(jù)安全的考慮
如果數(shù)據(jù)將在線程間共享。例如正在寫(xiě)的數(shù)據(jù)以后可能被另一個(gè)線程讀到焰坪,或者正在讀的數(shù)據(jù)可能已經(jīng)被另一個(gè)線程寫(xiě)過(guò)了趣倾,那么這些數(shù)據(jù)就是共享數(shù)據(jù),必須進(jìn)行同步存取某饰。
異步允許并發(fā)
ajax技術(shù)通常都是異步實(shí)現(xiàn)的儒恋,異步主要使用在當(dāng)應(yīng)用程序在對(duì)象上調(diào)用了一個(gè)需要花費(fèi)很長(zhǎng)時(shí)間來(lái)執(zhí)行的方法善绎,并且不希望讓程序等待方法的返回時(shí),就應(yīng)該使用異步編程诫尽,在很多情況下采用異步途徑往往更有效率禀酱。
106、Static方法和static字段有什么用處箱锐?可以被重載嗎比勉?
【參考答案】
用static修飾的方法叫類(lèi)方法,被所有實(shí)例共享驹止;static修飾的字段為類(lèi)變量浩聋,被所有實(shí)例共享,在使用類(lèi)變量時(shí)臊恋,一般會(huì)結(jié)合final一起使用定義類(lèi)常量衣洁,不允許被其它的類(lèi)實(shí)例修改。
可以被重載抖仅,重載只是參數(shù)類(lèi)型坊夫、順序和個(gè)數(shù)不同。
http://blog.duywl.com/java/java%E9%9D%A2%E8%AF%95%E9%A2%98-java%E9%83%A8%E5%88%86/