第一篇:java開發(fā)面試題
1、編寫程序
題目:古典問題:有一對(duì)公母豬,從出生后第3個(gè)月起每個(gè)月都生一對(duì)豬,小豬長(zhǎng)到第三個(gè)月后每個(gè)月又生一對(duì)豬,假如豬都不死,問每個(gè)月的豬總數(shù)為多少?
答案:
public class lianxi01 {
public static void main(String[] args){
System.out.println(“第1個(gè)月的兔子對(duì)數(shù): 1”);
System.out.println(“第2個(gè)月的兔子對(duì)數(shù):1”);
int f1 = 1, f2 = 1, f, M=24;
for(int i=3;i<=M;i++){
f = f2;
f2 = f1 + f2;
f1 = f;
System.out.println(“第” + i +“個(gè)月的兔子對(duì)數(shù): ”+f2);
}
}
}
2、是非題
2.1 Java程序中的起始類名稱必須與存放該類的文件名相同。()
答案:正確
2.2 原生類中的數(shù)據(jù)類型均可任意轉(zhuǎn)換。()
答案:錯(cuò)誤
3、問答題
3.1 try {}里有一個(gè)return語(yǔ)句,那么緊跟在這個(gè)try后的finally {}里的code會(huì)不會(huì)被執(zhí)行,什么時(shí)候被執(zhí)行,在return前還是后?
答案:
會(huì)執(zhí)行,在return前執(zhí)行。
3.2 sleep()和 wait()有什么區(qū)別:
答案:
sleep是線程類(Thread)的方法,導(dǎo)致此線程暫停執(zhí)行指定時(shí)間,給執(zhí)行機(jī)會(huì)給其他線程,但是監(jiān)控狀態(tài)依然保持,到時(shí)后會(huì)自動(dòng)恢復(fù)。調(diào)用sleep不會(huì) 釋放對(duì)象鎖。wait是Object類的方法,對(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)。
4、數(shù)據(jù)庫(kù)題
聚集函數(shù)的應(yīng)用
編寫一條sql語(yǔ)句,希望從藝術(shù)家表artist_tab中,看到只有一個(gè)專長(zhǎng)specialty的是哪些專長(zhǎng)
答案:seelctspecialty from artist_tab group by specialty having count(*)=1’;
第二篇:JAVA網(wǎng)站開發(fā)工程師面試題
JAVA_WEB開發(fā)人員面試題及答案
面試人:面試時(shí)間:
一.選擇題(每題1分,共20分)
1.jsp 有幾個(gè)內(nèi)置對(duì)象?(c)(單選)
A 5個(gè)B6個(gè)C9個(gè)D8個(gè)
2.在JAVA中,如何跳出當(dāng)前的多重嵌套循環(huán)?(ab)(多選)
A breakBreturnCforwardDfinally
3.四種會(huì)話跟蹤技術(shù),哪個(gè)范圍最大?(d)(單選)
A pageBrequestCsessionDapplication
4.java中有幾種方法可以實(shí)現(xiàn)一個(gè)線程?(b)(單選)
A1種B2種C3種D 4種
5.同步有幾種實(shí)現(xiàn)方法(b)(單選)
A 4種B2種C3種D 1種
6.xml有哪些解析技術(shù)?(abcd)(多選)
A DOMBSAXCSTAXD JDOM
7.下列說法正確的是(bd)(多選)
A 構(gòu)造器Constructor可被繼承
BString類不可以繼承
C 判斷兩個(gè)對(duì)象值相同用“==”
D char型變量中能不能存貯一個(gè)中文漢字
8.下列關(guān)于線程說法正確的是(abc)(多選)
A調(diào)用sleep不會(huì)釋放對(duì)象鎖。
B調(diào)用wait方法導(dǎo)致本線程放棄對(duì)象鎖
C當(dāng)一個(gè)線程進(jìn)入一個(gè)對(duì)象的一個(gè)synchronized方法后,其它線程不可進(jìn)入此對(duì)象的其它方法
Dnotify():喚醒全部處于等待狀態(tài)的線程。
9.給定JSP程序源碼如下,該JSP運(yùn)行后輸出的結(jié)果是(b)。(單選)
<%int Count=1;%>
Count:<%= Count%>
ACount:1BCount:2C1:2 DCount:
10.在J2EE中的一個(gè)JSP文件中,有表達(dá)式<%=2 3%>,它將輸出(b)(單選)
a)2 3b)5c)23d)不會(huì)輸出,因?yàn)楸磉_(dá)式是錯(cuò)誤的11.在J2EE中,編寫Servlet過濾器時(shí),(c)接口用于調(diào)用過濾器鏈中的下一個(gè)過濾器。(單選)
a)Filterb)FilterConfigc)FilterChaind)Servlet
12)關(guān)于視圖的描述正確的是(c)(單選)
a)視圖是一種特殊的表,它存儲(chǔ)了用戶定制的數(shù)據(jù)。
b)視圖僅用于用戶進(jìn)行查詢,不可以通過視圖對(duì)數(shù)據(jù)進(jìn)行修改。
c)在sql server中可以通過用T-sql語(yǔ)句來創(chuàng)建,也可以通過企業(yè)管理器。
d)創(chuàng)建視圖只能操作本機(jī)器上的數(shù)據(jù)庫(kù)表。
13)STRUTS框架中,(c)類在視圖層和控制層之間傳遞HTML表單數(shù)據(jù)。(單選)a)Actionb)ActionForward c)ActionFormd)ActionServlet
18)Struts控制器的主要任務(wù)是接受用戶請(qǐng)求、根據(jù)用戶請(qǐng)求調(diào)用對(duì)應(yīng)的模型組件、獲取業(yè)務(wù)邏輯執(zhí)行結(jié)果的根據(jù)處理結(jié)果選擇適合的視圖組件返回給用戶,實(shí)現(xiàn)Struts控制器的類中不包括(c)。(單選)
a)ActionServletb)Actionc)ActionFormd)ActionForward
14)以下關(guān)于SessionFactory的說法哪些正確?(bc)(多選)
A)對(duì)于每個(gè)數(shù)據(jù)庫(kù)事務(wù),應(yīng)該創(chuàng)建一個(gè)SessionFactory對(duì)象
B)一個(gè)SessionFactory對(duì)象對(duì)應(yīng)一個(gè)數(shù)據(jù)庫(kù)存儲(chǔ)源。
C)SessionFactory是重量級(jí)的對(duì)象,不應(yīng)該隨意創(chuàng)建。如果系統(tǒng)中只有一個(gè)數(shù)據(jù)庫(kù)存儲(chǔ)源只需要?jiǎng)?chuàng)建一個(gè)。
D)SessionFactory的load()方法用于加載持久化對(duì)象
15)下面那些是Hibernate的查詢方式(abc)(多選)
A)sqlB)hqlC)Criteria
18)以下數(shù)據(jù)結(jié)構(gòu)不屬于線性結(jié)構(gòu)的是(c)(單選)
A)隊(duì)列B)線性表C)二叉樹D)棧
16)下列是文件讀寫的類是(ac)(多選)
A)File ReaderB)FileC)FileWriterD)InputStream
17)數(shù)據(jù)庫(kù)技術(shù)中的“臟數(shù)據(jù)',是指(c)的數(shù)據(jù)。(單選)
A)錯(cuò)誤B 回返C 未提交D 未提交的隨后又被撤消
18)在計(jì)算機(jī)中,—個(gè)字節(jié)是由多少個(gè)二進(jìn)制位組成的(b)(單選)
A).4B).8C).16D).24
19.下列不屬于面向?qū)ο蟮姆椒ㄊ牵╠)(單選)
A).對(duì)象B).類C).繼承D).過程調(diào)用
29.設(shè)正x、y均為整型變量,且x=10 y=3,則以下語(yǔ)句printf(“%d,%dn”,x--,--y);的輸出結(jié)果是(d)(單選)
A).10,3B).9,3C).9,2D).10,2二.填空(每空1分,共10分)
1.String s = new String(“xyz”);創(chuàng)建了__2__個(gè)String 對(duì)象?
2.Math.round(9.5)等於__10___Math.round(-9.5)等於__-9____
3.try {}里有一個(gè)return語(yǔ)句,那么緊跟在這個(gè)try后的finally {}里的code會(huì)被執(zhí)行,什么時(shí)候被執(zhí)行,在return____前_____(前還是后?)
4.如何現(xiàn)實(shí)servlet的單線程模式 ______<%@ page isThreadSafe=“false”%> _________
5.類變量必須帶的修飾符是 ______ static _________
6.final類可以修飾在屬性 , 方法和___類___前面
7.Java默認(rèn)的包是______ java.lang.*_________
8.Hibernate里面怎樣實(shí)現(xiàn)類與類之間的關(guān)系__________表映射_______________
9.Socket 編程服務(wù)器端用____ serverSocket ____類來創(chuàng)建socket對(duì)象。
三. 判斷題(每題2分,共10分)
1.依賴注入即是“面向接口”的編程。錯(cuò)
2.Overload和Override都是java多態(tài)的不同體現(xiàn)形式。對(duì)
3.String是最基本的數(shù)據(jù)類型。錯(cuò)
4.啟動(dòng)一個(gè)線程是用start。對(duì)
5.接口可以繼承接口。對(duì)
四.簡(jiǎn)答題(每題5分,共30分)
1、網(wǎng)頁(yè)設(shè)計(jì)采用div css有什么好處?
答:布局實(shí)現(xiàn)了表現(xiàn)與內(nèi)容的分離,大大縮減頁(yè)面代碼,符合W3C的標(biāo)準(zhǔn),兼容性更好;易于后期網(wǎng)站的更新、維護(hù);SEO的優(yōu)化:對(duì)搜索引擎更加友好,更容易被搜索引擎收錄。
2、前端頁(yè)面有哪三層構(gòu)成,分別是什么?作用是什么?
答:網(wǎng)頁(yè)分成三個(gè)層次,即:結(jié)構(gòu)層、表示層、行為層。
網(wǎng)頁(yè)的結(jié)構(gòu)層(structural layer)由HTML或 XHTML之類的標(biāo)記語(yǔ)言負(fù)責(zé)創(chuàng)建。標(biāo)簽,也就是那些出現(xiàn)在尖括號(hào)里的單詞,對(duì)網(wǎng)頁(yè)內(nèi)容的語(yǔ)義含義做出了描述,但這些標(biāo)簽不包含任何關(guān)于如何顯示有關(guān)內(nèi)容的信息。例如,P 標(biāo)簽表達(dá)了這樣一種語(yǔ)義:“這是一個(gè)文本段?!?/p>
網(wǎng)頁(yè)的表示層(presentation layer)由CSS負(fù)責(zé)創(chuàng)建。CSS 對(duì)“如何顯示有關(guān)內(nèi)容”的問題做出了回答。
網(wǎng)頁(yè)的行為層(behavior layer)負(fù)責(zé)回答“內(nèi)容應(yīng)該如何對(duì)事件做出反應(yīng)”這一問題。這是 Javascript 語(yǔ)言和 DOM 主宰的領(lǐng)域。
3、如何區(qū)別display:none與visibility:hidden?
答:相同的是display:none與visibility:hidden都可以用來隱藏某個(gè)元素;
不同的是display:none在隱藏元素的時(shí)候,將其占位空間也去掉;而visibility:hidden只是隱藏了內(nèi)容而已,其占位空間仍然保留。
4.購(gòu)物網(wǎng)站的主色調(diào)應(yīng)該是什么樣色?交友網(wǎng)站?體育網(wǎng)站?軟件網(wǎng)站?年輕的互聯(lián)網(wǎng)? 答:購(gòu)物:暖色;交友:粉紅之類的;體育:酷一點(diǎn);軟件公司:無(wú)所謂;年輕互聯(lián)網(wǎng):有朝氣的顏色,比如綠色。
5. 一個(gè)網(wǎng)站最多有幾種色彩
答:一到兩各種主色彩。
6.如果背景是黑色,那么字體用什么顏色能突出字體,且不顯得刺眼?
答:紅色。
五.編程操作題(每題6分,30分)
注:有上機(jī)機(jī)會(huì)上機(jī)操作,沒有就手動(dòng)把代碼寫出來;
1.一個(gè)表td中的部分Id有多個(gè)記錄,把所有有多個(gè)記錄的id查出來,并顯示共有多少條 記錄數(shù)。
2.寫出冒泡排序的實(shí)現(xiàn)
答:代碼如下:
public void fun9(){
int[] a = {1,3,5,61,2,123,12,}
Conica.print(a);
for(int i=0;i for(int j=0;j { if(a[j]>a[j 1]){ int temp = a[j]; a[j] = a[j 1]; a[j 1] = temp; } } } }編程:編寫一個(gè)截取字符串的函數(shù),輸入為一個(gè)字符串和字節(jié)數(shù),輸出為按字節(jié)截取的字符串。但是要保證漢字不被截半個(gè),如“我ABC”4,應(yīng)該截為“我AB”,輸入“我ABC漢DEF”,應(yīng)該輸出為“我ABC”而不是“我ABC 漢的半個(gè)”。 答:代碼如下: package test; class SplitString { String SplitStr; int SplitByte; public SplitString(String str,intbytes){ SplitStr=str; SplitByte=bytes; System.out.println(“TheString is:′” SplitStr “′;SplitBytes=” SplitByte); } public void SplitIt(){ int loopCount; loopCount=(SplitStr.length()%SplitByte==0)?(SplitStr.length()/SplitByte):(SplitStr.length()/SplitByte 1); System.out.println(“WillSplit into ” loopCount); for(int i=1;i<=loopCount;i){ if(i==loopCount){ System.out.println(SplitStr.substring((i-1)*SplitByte,SplitStr.length())); } else { System.out.println(SplitStr.substring((i-1)*SplitByte,(i*SplitByte))); } } } public static void main(String[]args){ SplitString ss = newSplitString(“test中dd文dsaf中男大3443n中國(guó)43中國(guó)人 0ewldfls=103”,4); ss.SplitIt(); } } 注:另外關(guān)于美工操作,如果有photoshop等軟件可以任選擇兩題考下: 1.手寫 html 能力 描述一個(gè)不規(guī)則表格,一定要有跨列和跨行的,讓他把 html 代碼寫出來; 2.讓他用 Photoshop 或 Fireworks 設(shè)計(jì)一個(gè)頁(yè)面布局,或者指定一個(gè)效果(比如半透明的按鈕),讓他畫出來,在或者,提供一幅人物照片,要求他摳掉背景,這是平面軟件能力的一種體現(xiàn)方式; 3.如果要涉及 Flash,讓他做一個(gè)兩種形狀(方形、圓圈)的漸變,要求過渡平滑、美觀,新手都直接用 shapemotion,很難看,高手知道加過渡。 1、面向?qū)ο蟮乃膫€(gè)特征:封裝、繼承、多態(tài)、抽象 封裝: 繼承:子類繼承父類,除private修飾以外的所以方法和屬性 多態(tài):一個(gè)對(duì)象多種狀態(tài),可以把子類對(duì)象當(dāng)作父類對(duì)象來看,一旦這樣做了,就只能 去調(diào)用父類中原有定義的屬性和方法,也就是子類中擴(kuò)展的方法或?qū)傩跃筒荒苷{(diào)用了。 抽象: 2、abstractclass 和interface的區(qū)別 聲明方法的存在而不去實(shí)現(xiàn)它的類被叫做抽象類(abstract class),它用于要?jiǎng)?chuàng)建一個(gè)體現(xiàn)某些基本行為的類,并為該類聲明方法,但不能在該類中實(shí)現(xiàn)該類的情況。不能創(chuàng)建abstract 類的實(shí)例。然而可以創(chuàng)建一個(gè)變量,其類型是一個(gè)抽象類,并讓它指向具體子類的一個(gè)實(shí)例。不能有抽象構(gòu)造函數(shù)或抽象靜態(tài)方法。Abstract 類的子類為它們父類中的所有抽象方法提供實(shí)現(xiàn),否則它們也是抽象類為。取而代之,在子類中實(shí)現(xiàn)該方法。知道其行為的其它類可以在類中實(shí)現(xiàn)這些方法。 接口(interface)是抽象類的變體。在接口中,所有方法都是抽象的。多繼承性可通過實(shí)現(xiàn)這樣的接口而獲得。接口中的所有方法都是抽象的,沒有一個(gè)有程序體。接口只可以定義static final成員變量。接口的實(shí)現(xiàn)與子類相似,除了該實(shí)現(xiàn)類不能從接口定義中繼承行為。當(dāng)類實(shí)現(xiàn)特殊接口時(shí),它定義(即將程序體給予)所有這種接口的方法。然后,它可以在實(shí)現(xiàn)了該接口的類的任何對(duì)象上調(diào)用接口的方法。由于有抽象類,它允許使用接口名作為引用變量的類型。通常的動(dòng)態(tài)聯(lián)編將生效。引用可以轉(zhuǎn)換到接口類型或從接口類型轉(zhuǎn)換,instanceof 運(yùn)算符可以用來決定某對(duì)象的類是否實(shí)現(xiàn)了接口。 3、final、finally、finalize的區(qū)別 final 用于聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。finally是異常處理語(yǔ)句結(jié)構(gòu)的一部分,表示總是執(zhí)行。 finalize是Object類的一個(gè)方法,在垃圾收集器執(zhí)行的時(shí)候會(huì)調(diào)用被回收對(duì)象的此方法,可以覆蓋此方法提供垃圾收集時(shí)的其他資源回收,例如關(guān)閉文件等。 4、匿名內(nèi)部類是否可以作為父類被其他類繼承,或做為接口被實(shí)現(xiàn)? 匿名內(nèi)部類不被繼承也不能被實(shí)現(xiàn),因?yàn)樗鼪]有名字,而一個(gè)內(nèi)部類只要有名字就可以作為父類被繼承,也可以作為借口被實(shí)現(xiàn)。 5、多線程有幾種實(shí)現(xiàn)方法,同步有幾種實(shí)現(xiàn)方法,都是什么? 多線程有兩種實(shí)現(xiàn)方法,分別繼承繼承Thread類與實(shí)現(xiàn)runnable借口。 同步的實(shí)現(xiàn)方法有兩種,分別是synchronized,wait與notify。 6、string 與 stringbuffer的區(qū)別? String的長(zhǎng)度是不可變的,而stringbuffer的長(zhǎng)度是可變的。如果你對(duì)字符中的內(nèi)容經(jīng)常進(jìn)行操作,特別是內(nèi)容修改時(shí),那么就要使用stringbuffer,如果最后需要使用string,那么使用stringbuffer的tostring()方法。 7、解析XML文件的幾種方式和區(qū)別 DOM:處理大型文件時(shí)其性能下降的非常厲害 SAX:SAX是事件驅(qū)動(dòng)型的XML解析方式,它是順序讀取XML文件,不需要一次性全部裝載整個(gè)文件。 8、sleep()和wait()有什么區(qū)別? sleep是線程類(Thread)的方法,導(dǎo)致此線程暫停執(zhí)行指定時(shí)間,給執(zhí)行機(jī)會(huì)給其他線程,但是監(jiān)控狀態(tài)依然保持,到時(shí)后會(huì)自動(dòng)恢復(fù)。調(diào)用sleep不會(huì)釋放對(duì)象鎖。 wait是Object類的方法,對(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)。 9、數(shù)組有沒有l(wèi)ength這個(gè)方法?string有沒有l(wèi)ength這個(gè)方法? 數(shù)組沒有l(wèi)ength()這個(gè)方法,有l(wèi)ength這個(gè)屬性 String有l(wèi)ength()這個(gè)方法 10、LinkedList、ArrayList和Vector的區(qū)別? ArrayList和Vector是采用數(shù)組方式存儲(chǔ)數(shù)據(jù),此數(shù)組元素總數(shù)大于實(shí)際存儲(chǔ)的數(shù)據(jù)個(gè)數(shù)以便增加和插入元素,二者都允許直接序號(hào)索引元素,但是插入數(shù)據(jù)要移動(dòng)數(shù)組元素等內(nèi)存操作,所以它們索引數(shù)據(jù)快、插入數(shù)據(jù)慢。 Vector由于使用了synchronized同步方法(如add、insert、remove、set、equals、hashcode等操作),因此是線程安全,性能上比ArrayList要差。 LinkedList使用雙向鏈表實(shí)現(xiàn)存儲(chǔ),按序號(hào)索引數(shù)據(jù)需要進(jìn)行向前或向后遍歷,但是插入數(shù)據(jù)時(shí)只需要記錄本項(xiàng)的前后項(xiàng)即可,所以插入數(shù)度較快!LinkedList雙向鏈表,是指可以從first依次遍歷至last(從頭到尾),也可以從last遍歷至first(從尾到頭),但首尾沒有構(gòu)成環(huán),不同于雙向循環(huán)鏈表(注意區(qū)分): 11、hashmap與hashtable的區(qū)別? 都屬于Map接口的類,實(shí)現(xiàn)了將惟一鍵映射到特定的值上。 HashMap類沒有分類或者排序。它允許一個(gè)null鍵和多個(gè)null值。 Hashtable類似于HashMap,但是不允許null鍵和null值。它也比HashMap慢,因?yàn)樗峭降摹?/p> 12、Jsp有哪些內(nèi)置對(duì)象,作用分別是什么?(至少能說出五個(gè)) request表示HttpServletRequest對(duì)象。它包含了有關(guān)瀏覽器請(qǐng)求的信息,并且提供了幾個(gè)用于獲取cookie, header, 和session數(shù)據(jù)的有用的方法。 response表示HttpServletResponse對(duì)象,并提供了幾個(gè)用于設(shè)置送回 瀏覽器的響應(yīng)的方法(如cookies,頭信息等) out對(duì)象是javax.jsp.JspWriter的一個(gè)實(shí)例,并提供了幾個(gè)方法使你能用于向?yàn)g覽器回送輸出結(jié)果。 pageContext表示一個(gè)javax.servlet.jsp.PageContext對(duì)象。它是用于方便存取各種范圍的名字空間、servlet相關(guān)的對(duì)象的API,并且包裝了通用的servlet相關(guān)功能的方法。 session表示一個(gè)請(qǐng)求的javax.servlet.http.HttpSession對(duì)象。Session可以存貯用戶的狀態(tài)信息 applicaton 表示一個(gè)javax.servle.ServletContext對(duì)象。這有助于查找有關(guān)servlet引擎和servlet環(huán)境的信息 config表示一個(gè)javax.servlet.ServletConfig對(duì)象。該對(duì)象用于存取servlet實(shí)例的初始化參數(shù)。 page表示從該頁(yè)面產(chǎn)生的一個(gè)servlet實(shí)例 13、Javaservletapi中forward()與redirect()的區(qū)別? 前者僅是容器中控制權(quán)的轉(zhuǎn)向,在客戶端瀏覽器地址欄中不會(huì)顯示出轉(zhuǎn)向后的地址;后者則是完全的跳轉(zhuǎn),瀏覽器將會(huì)得到跳轉(zhuǎn)的地址,并重新發(fā)送請(qǐng)求鏈接。這樣,從瀏覽器的地址欄中可以看到跳轉(zhuǎn)后的鏈接地址。所以,前者更加高效,在前者可以滿足需要時(shí),盡量使用forward()方法,并且,這樣也有助于隱藏實(shí)際的鏈接。在有些情況下,比如,需要跳轉(zhuǎn)到一個(gè)其它服務(wù)器上的資源,則必須使用sendRedirect()方法。 14、重載(overload)與重寫(override)的區(qū)別? Overload:方法名相同,參數(shù)不同,與返回值無(wú)關(guān) Override:方法名相同,參數(shù)相同,相同的返回值,建立在繼承的基礎(chǔ)之上 15、什么是單例模式,在程序中如何使用? 單例模式確保一個(gè)類只有一個(gè)實(shí)例 餓漢式單例類 public class Singleton { private Singleton(){} private static Singleton instance = new Singleton(); public static Singleton getInstance(){ return instance; } } 懶漢式單例類 public class Singleton { private static Singleton instance = null; public static synchronized Singleton getInstance(){ if(instance==null) instance=new Singleton(); return instance; } } 16、Servlet生命周期? 加載和實(shí)例化 初始化init() 請(qǐng)求處理service() 服務(wù)終止destroy() 17、spring中IOC與AOP的含義? IOC:控制反轉(zhuǎn),是一種設(shè)計(jì)模式,一層含義控制權(quán)的轉(zhuǎn)移,由傳統(tǒng)的在程序中控制依賴轉(zhuǎn)移到由容器來控制,第二層是依賴注入將互相依賴的對(duì)象分離,在spring配置文件中描述它們的依賴關(guān)心,它們的依賴關(guān)系只是在使用的時(shí)候才建立 AOP:面向切面,是一種編程思想,oop的延續(xù),將系統(tǒng)中非核心的業(yè)務(wù)提取出來,進(jìn)行單獨(dú)的處理,比如事務(wù)、日志和安全等 Spring的AOP和IOC都是為了解決系統(tǒng)代碼耦合度過高的問題,使用代碼重用性高,易于維護(hù),不過AOP和IOC并不是spring中特有的,只是spring把它們應(yīng)用的更靈活方便。 18、hibernate與JDBC的區(qū)別? 相同點(diǎn): 1>兩者都是JAVA的數(shù)據(jù)庫(kù)操作中間件。 2>兩者對(duì)于數(shù)據(jù)庫(kù)進(jìn)行直接操作的對(duì)象都不是線程安全的,都需要及時(shí)關(guān)閉。 3>兩者都可以對(duì)數(shù)據(jù)庫(kù)的更新操作進(jìn)行顯式的事務(wù)處理。 不同點(diǎn): 1>使用的SQL語(yǔ)言不同:JDBC使用的是基于關(guān)系型數(shù)據(jù)庫(kù)的標(biāo)準(zhǔn)SQL語(yǔ)言,Hibernate使用的是HQL(Hibernate query language)語(yǔ)言 2>操作的對(duì)象不同:JDBC操作的是數(shù)據(jù),將數(shù)據(jù)通過SQL語(yǔ)句直接傳送到數(shù)據(jù)庫(kù)中執(zhí)行,Hibernate操作的是持久化對(duì)象,由底層持久化對(duì)象的數(shù)據(jù)更新到數(shù)據(jù)庫(kù)中。3>數(shù)據(jù)狀態(tài)不同:JDBC操作的數(shù)據(jù)是“瞬時(shí)”的,變量的值無(wú)法與數(shù)據(jù)庫(kù)中的值保持一致,而Hibernate操作的數(shù)據(jù)是可持久的,即持久化對(duì)象的數(shù)據(jù)屬性的值是可以跟數(shù)據(jù)庫(kù)中的值保持一致的。 19、struts中的標(biāo)簽庫(kù)有幾種,分別是? 有5種標(biāo)簽,分別是:bean標(biāo)簽庫(kù)、html標(biāo)簽庫(kù)、logic標(biāo)簽庫(kù)、tiles標(biāo)簽庫(kù)nested標(biāo)簽庫(kù) 20、Error與Exception有什么區(qū)別? Error表示系統(tǒng)級(jí)的錯(cuò)誤和程序不必處理的異常,Exception表示需要捕捉或者需要程序進(jìn)行處理的異常。 21、Collection和Collections的區(qū)別。 Collection是集合類的上級(jí)接口,繼承與他的接口主要有Set 和List.Collections是針對(duì)集合類的一個(gè)幫助類,他提供一系列靜態(tài)方法實(shí)現(xiàn)對(duì)各種集合的搜索、排序、線程安全化等操作 22、GC是什么?為什么要有GC?(基礎(chǔ))。 GC是垃圾收集器。Java程序員不用擔(dān)心內(nèi)存管理,因?yàn)槔占鲿?huì)自動(dòng)進(jìn)行管理。 要請(qǐng)求垃圾收集,可以調(diào)用下面的方法之一: System.gc() Runtime.getRuntime().gc() 23、啟動(dòng)一個(gè)線程是用run()還是start()? 啟動(dòng)一個(gè)線程是調(diào)用start()方法,使線程所代表的虛擬處理機(jī)處于可運(yùn)行狀態(tài),這意味著它可以由JVM調(diào)度并執(zhí)行。這并不意味著線程就會(huì)立即運(yùn)行。run()方法可以產(chǎn)生必須退出的標(biāo)志來停止一個(gè)線程。 24、&和&&的區(qū)別。 &是位運(yùn)算符,表示按位與運(yùn)算,&&是邏輯運(yùn)算符,表示邏輯與(and)。 25、heap和stack有什么區(qū)別。 棧是一種線形集合,其添加和刪除元素的操作應(yīng)在同一段完成。棧按照后進(jìn)先出的方 式進(jìn)行處理。 堆是棧的一個(gè)組成元素 26、List, Set, Map是否繼承自Collection接口? List,Set是,Map不是 27、MVC的各個(gè)部分都有那些技術(shù)來實(shí)現(xiàn)?如何實(shí)現(xiàn)? MVC 是Model-View-Controller的簡(jiǎn)寫?!癕odel” 代表的是應(yīng)用的業(yè)務(wù)邏輯(通過JavaBean,EJB組件實(shí)現(xiàn)),“View” 是應(yīng)用的表示面(由JSP頁(yè)面產(chǎn)生),“Controller” 是提供應(yīng)用的處理過程控制(一般是一個(gè)Servlet),通過這種設(shè)計(jì)模型把應(yīng)用邏輯,處理過程和顯示邏輯分成不同的組件實(shí)現(xiàn)。這些組件可以進(jìn)行交互和重用。 28、Static Nested Class 和 Inner Class的不同。 Static Nested Class是被聲明為靜態(tài)(static)的內(nèi)部類,它可以不依賴于外部類實(shí)例被實(shí)例化。而通常的內(nèi)部類需要在外部類實(shí)例化后才能實(shí)例化。 29、接口是否可繼承接口? 抽象類是否可實(shí)現(xiàn)(implements)接口? 抽象類是否可繼承實(shí)體類 (concrete class)? 接口可以繼承接口。抽象類可以實(shí)現(xiàn)(implements)接口,抽象類是否可繼承實(shí)體類,但前提是實(shí)體類必須有明確的構(gòu)造函數(shù) 30、JSP和Servlet有哪些相同點(diǎn)和不同點(diǎn),他們之間的聯(lián)系是什么? JSP 是Servlet技術(shù)的擴(kuò)展,本質(zhì)上是Servlet的簡(jiǎn)易方式,更強(qiáng)調(diào)應(yīng)用的外表表達(dá)。JSP編譯后是“類servlet”。Servlet和JSP最主要的不同點(diǎn)在于,Servlet的應(yīng)用邏輯是在Java文件中,并且完全從表示層中的HTML里分離開來。而JSP的情況是Java和HTML可以組合成一個(gè)擴(kuò)展名為.jsp的文件。JSP側(cè)重于視圖,Servlet主要用于控制邏輯 31、當(dāng)一個(gè)線程進(jìn)入一個(gè)對(duì)象的一個(gè)synchronized方法后,其它線程是否可進(jìn)入此對(duì)象的其它方法? 不能,一個(gè)對(duì)象的一個(gè)synchronized方法只能由一個(gè)線程訪問。 32、運(yùn)行時(shí)異常與一般異常有何異同? 異常表示程序運(yùn)行過程中可能出現(xiàn)的非正常狀態(tài),運(yùn)行時(shí)異常表示虛擬機(jī)的通常操作中可能遇到的異常,是一種常見運(yùn)行錯(cuò)誤。java編譯器要求方法必須聲明拋出可能發(fā)生的非運(yùn)行時(shí)異常,但是并不要求必須聲明拋出未被捕獲的運(yùn)行時(shí)異常。 33、JSP中動(dòng)態(tài)INCLUDE與靜態(tài)INCLUDE的區(qū)別? 動(dòng)態(tài)INCLUDE用jsp:include動(dòng)作實(shí)現(xiàn) 靜態(tài)INCLUDE用include偽碼實(shí)現(xiàn),定不會(huì)檢查所含文件的變化,適用于包含靜態(tài)頁(yè)面<%@ include file=“included.htm” %> 1、你怎樣理解Struts,又那些配置文件,以及作用? 理解:http://ruixin.iteye.com/blog/899289 配置文件:struts.xml 作用:struts 框架mvc 實(shí)現(xiàn)低耦合,便于程序的維護(hù)~ 配置文件控制流程的轉(zhuǎn)向 很清晰~ 主要負(fù)責(zé)具體業(yè)務(wù)的實(shí)現(xiàn)和頁(yè)面的轉(zhuǎn)向~ 2、怎么樣來捕獲數(shù)據(jù)庫(kù)中的異常? 3、如何處理網(wǎng)頁(yè)中的驗(yàn)證信息,如何友好的進(jìn)行處理? 4、用javaScript實(shí)現(xiàn)java中的監(jiān)聽器功能? 5、你對(duì)對(duì)日外包的看法? 6、數(shù)據(jù)庫(kù)連接方式由哪幾種? Jdbc、連接池、hibernate 7、你清楚哪幾種設(shè)計(jì)模式,談?wù)劯鞣N設(shè)計(jì)模式的類結(jié)構(gòu)。 8、談?wù)刯sp和sevlet的區(qū)別,以及它們性能上的區(qū)別。 jsp是servlet的一種簡(jiǎn)化,jsp編譯后是“類servlet”。servlet 主要是用來處理業(yè)務(wù)層; jsp 則是主要負(fù)責(zé) 表現(xiàn)層。 servlet完全是java程序代碼構(gòu)成,擅長(zhǎng)于流程控制和事務(wù)處理,而通過servlet來生成動(dòng)態(tài)網(wǎng)頁(yè)很不直觀; 對(duì)于靜態(tài)的html標(biāo)簽,servlet都必須使用頁(yè)面輸出流逐行輸出。Servlet中沒有內(nèi)置對(duì)象。Jsp由html代碼和jsp標(biāo)簽構(gòu)成可以方便地編寫動(dòng)態(tài)網(wǎng)頁(yè),在struts框架中,jsp位于MVC設(shè)計(jì)模式的視圖層,而servlet位于控制層。 總之,使用jsp只需要完成程序員需要輸出到客戶端的內(nèi)容,至于jsp中的java腳本如果鑲嵌到一個(gè)類中,由jsp容器完成,而servlet則是個(gè)完整的java類,這個(gè)類的service方法用于生成對(duì)客戶端的響應(yīng) 9、如何來編寫存儲(chǔ)過程,如何優(yōu)化存儲(chǔ)過程,以及存儲(chǔ)過程和TSQL的區(qū)別。 10、提供的培訓(xùn),CMM-5軟件開發(fā)流程培訓(xùn)、代碼編寫規(guī)范和業(yè)務(wù)流程培訓(xùn)、對(duì)日語(yǔ)的培訓(xùn)。 1、為什么要選擇這個(gè)行業(yè),和計(jì)算機(jī)專業(yè)的相比有什么優(yōu)勢(shì)? 2、Servlet是什么,以及生命周期? Servlet被服務(wù)器實(shí)例化后,容器運(yùn)行其init方法,請(qǐng)求到達(dá)時(shí)運(yùn)行其service方法,service方法自動(dòng)派遣運(yùn)行與請(qǐng)求對(duì)應(yīng)的doXXX方法(doGet,doPost)等,當(dāng)服務(wù)器決定將實(shí)例銷毀的時(shí)候調(diào)用其destroy方法。 與cgi的區(qū)別在于servlet處于服務(wù)器進(jìn)程中,它通過多線程方式運(yùn)行其service方法,一個(gè)實(shí)例可以服務(wù)于多個(gè)請(qǐng)求,并且其實(shí)例一般不會(huì)銷毀,而CGI對(duì)每個(gè)請(qǐng)求都產(chǎn)生新的進(jìn)程,服務(wù)完成后就銷毀,所以效率上低于servlet。 3、怎么理解事務(wù)? 4、怎么理解MVC? 自己做自己的事情,主要強(qiáng)調(diào)分層,5、同時(shí)插入大量數(shù)據(jù),使用何種方法優(yōu)化?Batch 6、多個(gè)有關(guān)系得怎么樣操作? 7、你認(rèn)為你還有什么優(yōu)點(diǎn)在前面沒有提到? 8、對(duì)加班的看法? 9、與上級(jí)意見不一致時(shí)怎么樣處理?10、11、12、13、14、15、16、17、18、19、20、21、22、23、你如何理解團(tuán)隊(duì)精神? 你怎樣處理學(xué)習(xí)新技術(shù)和項(xiàng)目開發(fā)之間的矛盾? 怎樣去學(xué)習(xí)新技術(shù)? 作為一個(gè)初級(jí)程序員怎么樣彌補(bǔ)與有經(jīng)驗(yàn)程序員之間的差距? 你對(duì)索引的理解,索引有幾種,什么時(shí)候用索引? 對(duì)Oracle理解? 怎樣優(yōu)化復(fù)雜的查詢語(yǔ)句? 你對(duì)Jdbc理解? 對(duì)Finally塊的理解和應(yīng)用? 游標(biāo)的理解? ResultSet 重載,重寫? 簽名 EJB的事務(wù),Hibernate的事務(wù)? Struts的標(biāo)簽? 重定向和跳轉(zhuǎn)? A、 a.地址欄不改變跳轉(zhuǎn)——服務(wù)器端跳轉(zhuǎn),服務(wù)器之間內(nèi)部轉(zhuǎn),相同的request,可傳參; b.執(zhí)行到跳轉(zhuǎn)語(yǔ)句后無(wú)條件立刻跳轉(zhuǎn)——之后的代碼不再被執(zhí)行; 注意:如果使用forward跳轉(zhuǎn),則一定要在跳轉(zhuǎn)之前釋放掉全部的資源; c.使用forward時(shí),request設(shè)置的屬性依然能保留在下一個(gè)頁(yè)面(setAttribute);d.通過 e.地址中的”/”代表是:http://localhost:8080/Test B、response.sendRedirect(“地址”):效率低,速度慢 a.地址欄改變跳轉(zhuǎn)——客戶端跳轉(zhuǎn)(其中地址可以是任意的) b.所有代碼執(zhí)行完畢之后再跳轉(zhuǎn),跳轉(zhuǎn)語(yǔ)句后面的代碼還是會(huì)執(zhí)行,除非在其后面加上return(return)需復(fù)雜一些。 <% Response.sendRedirect(“aa.jsp”);boolean b = true; if(b){ Return;} System.out.println(“aaaaaaaaaa”);%> c.不能保存request屬性——地址改變了,客戶端跳轉(zhuǎn),不同的request d.通過對(duì)URL地址的重寫傳遞參數(shù): response.sendRedirect(“responseDemo04.jsp?id=mldn”); e.地址中的”/”代表是:http://localhost:8080/ 下面是兩種比較重要的跳轉(zhuǎn),我還是與上次的一次,把我做的筆記貼出來:24、25、Hibernate的左聯(lián)結(jié)和右連接,緩存,數(shù)據(jù)加載? 面向?qū)ο笕绾卫斫? 26、EJB中CMP和BMP,SessionBean的機(jī)制?27、28、29、對(duì)日外包是否有抵觸情緒? 如何減少Servlet的請(qǐng)求? 對(duì)設(shè)計(jì)模式了解多少?作過的項(xiàng)目中用過那些設(shè)計(jì)模式? 30、31、32、33、34、35、36、37、38、39、40、41、42、43、44、45、怎樣看待團(tuán)隊(duì)合作,在團(tuán)隊(duì)合作中你扮演什么樣的角色,遇到技術(shù)難題時(shí)怎么解決? Exception的層次結(jié)構(gòu)? EJB對(duì)數(shù)據(jù)庫(kù)的訪問機(jī)制? Struts中是否有事務(wù)處理? Hibernate的其它功能(除了ORM)? 如何提高數(shù)據(jù)庫(kù)中的數(shù)據(jù)查詢效率? 作為項(xiàng)目經(jīng)理如何對(duì)組內(nèi)成員分工? 描述一下你做過項(xiàng)目的流程。 加班到12點(diǎn),突然有人來問你技術(shù)上的難題,你會(huì)如何處理? Oracle的冷備份、熱備份 Strurs中怎樣實(shí)現(xiàn) Hibernate怎樣實(shí)現(xiàn)ORM Spring 的事務(wù)處理機(jī)制 Strurs的驗(yàn)證方式,Javascript的驗(yàn)證的方式 一個(gè)是服務(wù)器端驗(yàn)證,一個(gè)是客戶端驗(yàn)證 Struts的工作機(jī)制 Delete/trancate的區(qū)別 trancate與delete都是刪除數(shù)據(jù),不同的是trancate是將表的所有數(shù)據(jù)都刪除,而delete可以有選擇地刪除數(shù)據(jù); delete刪除數(shù)據(jù)是記錄在日志中的,可以通過其將數(shù)據(jù)恢復(fù),而trancate則是將整個(gè)表截?cái)?,其操作是不記錄在日志里的?6、47、48、作為項(xiàng)目組長(zhǎng),你遇到的最大問題是什么?如何解決? Ajax/內(nèi)嵌框架實(shí)現(xiàn)局部刷新,有什么差別? Exception/Error的區(qū)別,在什么情況下可以拋出RuntimeException 父類不同 知道異常和錯(cuò)誤最本質(zhì)的區(qū)別就是異常能被開發(fā)人員處理而錯(cuò)誤時(shí)系統(tǒng)本來自帶的,一般無(wú)法處理也不需要我們程序員來處理。 在程序運(yùn)行時(shí)候出錯(cuò)而又不是系統(tǒng)原因差生的,一般是由于程序原因產(chǎn)生,比如程序?qū)懙牟粔驀?yán)謹(jǐn)、完善 典型的RuntimeException 有 ArithmeticException、ClassCastException、IndexOutOfBoundsException、NullPointerException、UnsupportedOperationException 等.49、50、51、52、53、54、55、56、57、58、59、Orcale 物化視圖(MV) 業(yè)務(wù)處理模塊中,是如何處理事務(wù)? Sql語(yǔ)句如何優(yōu)化 數(shù)據(jù)庫(kù)右連接 JDBC的連接關(guān)閉在哪? Finally語(yǔ)句塊內(nèi) 錯(cuò)誤處理模塊是放在哪個(gè)層的。接口能否繼承接口。 接口可以繼承接口..但是要使用extends~而不是用implements 抽象類能否繼承實(shí)體類。 抽象類是可以繼承實(shí)體類,但前提是實(shí)體類必須有明確的構(gòu)造函數(shù) 答案很明確,可以繼承。 項(xiàng)目中查詢時(shí)怎么樣實(shí)現(xiàn)的? 作為項(xiàng)目負(fù)責(zé)人你是管理這個(gè)團(tuán)隊(duì)的? 在你做項(xiàng)目過程中遇到些什么問題,是怎么樣解決的? Jquery中的幾種選擇器: Javascript如何進(jìn)行數(shù)字和字符串之間的轉(zhuǎn)換? 數(shù)字類型轉(zhuǎn)換成String類型用 對(duì)象=對(duì)象.toString()方法,字符串轉(zhuǎn)換成數(shù)字類型則是對(duì)象=Number(對(duì)象); 1、一個(gè)“.java”源文件中是否可以包括多個(gè)類(不是內(nèi)部類)?有什么限制? 可以有多個(gè)類,但只能有一個(gè)public的類,并且public的類名必須與文件名相一致。 3、說說&和&&的區(qū)別。 &和&&都可以用作邏輯與的運(yùn)算符,表示邏輯與(and),當(dāng)運(yùn)算符兩邊的表達(dá)式的結(jié)果都為true時(shí),整個(gè)運(yùn)算結(jié)果才為true,否則,只要有一方為false,則結(jié)果為false。 &&還具有短路的功能,即如果 6、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á)式的類型,所以結(jié)果是int型,再賦值給short類型s1時(shí),編譯器將報(bào)告需要強(qiáng)制轉(zhuǎn)換類型的錯(cuò)誤。 對(duì)于short s1 = 1;s1 += 1;由于 += 是java語(yǔ)言規(guī)定的運(yùn)算符,java編譯器會(huì)對(duì)它進(jìn)行特殊處理,因此可以正確編譯。 7、char型變量中能不能存貯一個(gè)中文漢字?為什么? char型變量是用來存儲(chǔ)Unicode編碼的字符的,unicode編碼字符集中包含了漢字,所以,char型變量中當(dāng)然可以存儲(chǔ)漢字啦。不過,如果某個(gè)特殊的漢字沒有被包含在unicode編碼字符集中,那么,這個(gè)char型變量中就不能存儲(chǔ)這個(gè)特殊漢字。補(bǔ)充說明:unicode編碼占用兩個(gè)字節(jié),所以,char類型的變量也是占用兩個(gè)字節(jié)。 備注:后面一部分回答雖然不是在正面回答題目,但是,為了展現(xiàn)自己的學(xué)識(shí)和表現(xiàn)自己對(duì)問題理解的透徹深入,可以回答一些相關(guān)的知識(shí),做到知無(wú)不言,言無(wú)不盡。 8、用最有效率的方法算出2乘以8等於幾? 2 << 3,將一個(gè)數(shù)左移n位,就相當(dāng)于乘以了2的n次方,那么,一個(gè)數(shù)乘以8只要將其左移3位即可,而位運(yùn)算cpu直接支持的,效率最高,所以,2乘以8等於幾的最效率的方法是2 << 3。 10、使用final關(guān)鍵字修飾一個(gè)變量時(shí),是引用變量不能變,還是引用的對(duì)象不能變? 使用final關(guān)鍵字修飾一個(gè)變量時(shí),是指引用變量不能變,引用變量所指向的對(duì)象中的內(nèi)容還是可以改變的。例如,對(duì)于如下語(yǔ)句: final StringBuffer a=new StringBuffer(“immutable”);執(zhí)行如下語(yǔ)句將報(bào)告編譯期錯(cuò)誤: a=new StringBuffer(“");但是,執(zhí)行如下語(yǔ)句則可以通過編譯: a.append(” broken!“); 有人在定義方法的參數(shù)時(shí),可能想采用如下形式來阻止方法內(nèi)部修改傳進(jìn)來的參數(shù)對(duì)象: public void method(final StringBuffer param){ } 實(shí)際上,這是辦不到的,在該方法內(nèi)部仍然可以增加如下代碼來修改參數(shù)對(duì)象: param.append(”a“); 11、”==“和equals方法究竟有什么區(qū)別? ==操作符專門用來比較兩個(gè)變量的值是否相等,也就是用于比較變量所對(duì)應(yīng)的內(nèi)存中所存儲(chǔ)的數(shù)值是否相同,要比較兩個(gè)基本類型的數(shù)據(jù)或兩個(gè)引用變量是否相等,只能用==操作符。 equals方法是用于比較兩個(gè)獨(dú)立對(duì)象的內(nèi)容是否相同,就好比去比較兩個(gè)人的長(zhǎng)相是否相同,它比較的兩個(gè)對(duì)象是獨(dú)立的。例如,對(duì)于下面的代碼: 12、靜態(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ì)象,而是屬于類,所以也稱為類變量,只要程序加載了類的字節(jié)碼,不用創(chuàng)建任何實(shí)例對(duì)象,靜態(tài)變量就會(huì)被分配空間,靜態(tài)變量就可以被使用了??傊?,實(shí)例變量必須創(chuàng)建對(duì)象后才可以通過這個(gè)對(duì)象來使用,靜態(tài)變量則可以直接使用類名來引用。 13、是否可以從一個(gè)static方法內(nèi)部發(fā)出對(duì)非static方法的調(diào)用? 不可以。非static方法是要與對(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)用。一個(gè)static方法內(nèi)部發(fā)出對(duì)非static方法的調(diào)用。 14、Integer與int的區(qū)別 int是java提供的8種原始數(shù)據(jù)類型之一。Java為每個(gè)原始類型提供了封裝類,Integer是java為int提供的封裝類。int的默認(rèn)值為0,而Integer的默認(rèn)值為null,即Integer可以區(qū)分出未賦值和值為0的區(qū)別,int則無(wú)法表達(dá)出未賦值的情況,例如,要想表達(dá)出沒有參加考試和考試成績(jī)?yōu)?的區(qū)別,則只能使用Integer。在JSP開發(fā)中,Integer的默認(rèn)為null,所以用el表達(dá)式在文本框中顯示時(shí),值為空白字符串,而int默認(rèn)的默認(rèn)值為0,所以用el表達(dá)式在文本框中顯示時(shí),結(jié)果為0,所以,int不適合作為web層的表單數(shù)據(jù)的類型。 在Hibernate中,如果將OID定義為Integer類型,那么Hibernate就可以根據(jù)其值是否為null而判斷一個(gè)對(duì)象是否是臨時(shí)的,如果將OID定義為了int類型,還需要在hbm映射文件中設(shè)置其unsaved-value屬性為0。 另外,Integer提供了多個(gè)與整數(shù)相關(guān)的操作方法,例如,將一個(gè)字符串轉(zhuǎn)換 成整數(shù),Integer中還定義了表示整數(shù)的最大值和最小值的常量。 15、Math.round(11.5)等於多少? Math.round(-11.5)等於多少? Math類中提供了三個(gè)與取整有關(guān)的方法:ceil、floor、round,這些方法的作用與它們的英文名稱的含義相對(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),即將原來的數(shù)字加上0.5后再向下取整,所以,Math.round(11.5)的結(jié)果為12,Math.round(-11.5)的結(jié)果為-11。 15、下面的代碼有什么不妥之處? 1.if(username.equals(“zxx”){} 如果username=null;會(huì)報(bào)異常,而且少個(gè)括號(hào)結(jié)束。 2.int x = 1;return x==1?true:false;X==1返回的本來就是boolean類型 后面的true:false是多余的.16、請(qǐng)說出作用域public,private,protected,以及不寫時(shí)的區(qū)別 這四個(gè)作用域的可見范圍如下表所示。 說明:如果在修飾的元素上面沒有寫任何訪問修飾符,則表示friendly。 作用域 當(dāng)前類 同一package 子孫類 其他package public √ √ √ √ protected √ √ √ × friendly √ √ × × private √ × × × 備注:只要記住了有4種訪問權(quán)限,4個(gè)訪問范圍,然后將全選和范圍在水平和垂直方向上分別按排從小到大或從大到小的順序排列,就很容易畫出上面的圖了。 17、Overload和Override的區(qū)別(觀察者和被觀察者模式)。Overloaded的方法是否可以改變返回值的類型? Overload是重載的意思,Override是覆蓋的意思,也就是重寫。 重載Overload表示同一個(gè)類中可以有多個(gè)名稱相同的方法,但這些方法的參數(shù)列表各不相同(即參數(shù)個(gè)數(shù)或類型不同)。 重寫Override表示子類中的方法可以與父類中的某個(gè)方法的名稱和參數(shù)完全相同,通過子類創(chuàng)建的實(shí)例對(duì)象調(diào)用這個(gè)方法時(shí),將調(diào)用子類中的定義方法,這相當(dāng)于把父類中定義的那個(gè)完全相同的方法給覆蓋了,這也是面向?qū)ο缶幊痰亩鄳B(tài)性的一種表現(xiàn)。子類覆蓋父類的方法時(shí),只能比父類拋出更少的異常,或者是拋出父類拋出的異常的子異常,因?yàn)樽宇惪梢越鉀Q父類的一些問題,不能比父類有更多的問題。子類方法的訪問權(quán)限只能比父類的更大,不能更小。如果父類的方法是private類型,那么,子類則不存在覆蓋的限制,相當(dāng)于子類中增加了一個(gè)全新的方法。 至于Overloaded的方法是否可以改變返回值的類型這個(gè)問題,要看你倒底想問什么呢?這個(gè)題目很模糊。如果幾個(gè)Overloaded的方法的參數(shù)列表不一樣,它們的返回者類型當(dāng)然也可以不一樣。但我估計(jì)你想問的問題是:如果兩個(gè)方法的參數(shù)列表完全一樣,是否可以讓它們的返回值不同來實(shí)現(xiàn)重載Overload。這是不行的,我們可以用反證法來說明這個(gè)問題,因?yàn)槲覀冇袝r(shí)候調(diào)用一個(gè)方法時(shí)也可以不定義返回結(jié)果變量,即不要關(guān)心其返回結(jié)果,例如,我們調(diào)用map.remove(key)方法時(shí),雖然remove方法有返回值,但是我們通常都不會(huì)定義接收返回結(jié)果的變量,這時(shí)候假設(shè)該類中有兩個(gè)名稱和參數(shù)列表完全相同的方法,僅僅是返回類型不同,java就無(wú)法確定編程者倒底是想調(diào)用哪個(gè)方法了,因?yàn)樗鼰o(wú)法通過返回結(jié)果類型來判斷。 override可以翻譯為覆蓋,從字面就可以知道,它是覆蓋了一個(gè)方法并且對(duì)其重寫,以求達(dá)到不同的作用。對(duì)我們來說最熟悉的覆蓋就是對(duì)接口方法的實(shí)現(xiàn),在接口中一般只是對(duì)方法進(jìn)行了聲明,而我們?cè)趯?shí)現(xiàn)時(shí),就需要實(shí)現(xiàn)接口聲明的所有方法。除了這個(gè)典型的用法以外,我們?cè)诶^承中也可能會(huì)在子類覆蓋父類中的方法。在覆蓋要注意以下的幾點(diǎn): 1、覆蓋的方法的標(biāo)志必須要和被覆蓋的方法的標(biāo)志完全匹配,才能達(dá)到覆蓋的效果; 2、覆蓋的方法的返回值必須和被覆蓋的方法的返回一致; 3、覆蓋的方法所拋出的異常必須和被覆蓋方法的所拋出的異常一致,或者是其子類; 4、被覆蓋的方法不能為private,否則在其子類中只是新定義了一個(gè)方法,并沒有對(duì)其進(jìn)行覆蓋。 overload對(duì)我們來說可能比較熟悉,可以翻譯為重載,它是指我們可以定義一些名稱相同的方法,通過定義不同的輸入?yún)?shù)來區(qū)分這些方法,然后再調(diào)用時(shí),VM就會(huì)根據(jù)不同的參數(shù)樣式,來選擇合適的方法執(zhí)行。在使用重載要注意以下的幾點(diǎn): 1、在使用重載時(shí)只能通過不同的參數(shù)樣式。例如,不同的參數(shù)類型,不同的參數(shù)個(gè)數(shù),不同的參數(shù)順序(當(dāng)然,同一方法內(nèi)的幾個(gè)參數(shù)類型必須不一樣,例如可以是fun(int,float),但是不能為fun(int,int)); 2、不能通過訪問權(quán)限、返回類型、拋出的異常進(jìn)行重載; 3、方法的異常類型和數(shù)目不會(huì)對(duì)重載造成影響; 4、對(duì)于繼承來說,如果某一方法在父類中是訪問權(quán)限是priavte,那么就不能在子類對(duì)其進(jìn)行重載,如果定義的話,也只是定義了一個(gè)新方法,而不會(huì)達(dá)到重載的效果。 18、說說對(duì)javaee中的session的理解,你是怎么用session的? 在Java Servlet API中引入session機(jī)制來跟蹤客戶的狀態(tài)。session指的是在一段時(shí)間內(nèi),單個(gè)客戶與Web服務(wù)器的一連串相關(guān)的交互過程。在一個(gè)session中,客戶可能會(huì)多次請(qǐng)求同一個(gè)網(wǎng)頁(yè),也有可能請(qǐng)求訪問各種不同的服務(wù)器資源。例如在電子郵件應(yīng)用中,從一個(gè)客戶登錄到電子郵件系統(tǒng)開始,經(jīng)過收信,寫信,和發(fā)信等,直至退出郵件系統(tǒng),整個(gè)過程為一個(gè)session。再比如,在網(wǎng)上書店應(yīng)用中,從一個(gè)客戶開始購(gòu)物,到最后結(jié)賬,整個(gè)過程為一個(gè)session。 會(huì)話的創(chuàng)建:HttpSession session = request.getSession(boolean value);HttpSession session = request.getSession();會(huì)話的使用:javax.servlet.http.HttpSession接口中定義的方法,我們常用的是有關(guān)進(jìn)行數(shù)據(jù)存取的方法。 session.setAttribute(String name , Object value);session.getAttribute(String name); 19、說說has a與is a的區(qū)別。 is-a表示的是屬于得關(guān)系。比如兔子屬于一種動(dòng)物(繼承關(guān)系)。has-a表示組合,包含關(guān)系。比如兔子包含有腿,頭等組件; 20、線程如何同步和通訊。 只有多個(gè)synchronized代碼塊使用的是同一個(gè)監(jiān)視器對(duì)象,這些synchronized代碼塊之間才具有線程互斥的效果,假如a代碼塊用obj1作為監(jiān)視器對(duì)象,假如b代碼塊用obj2作為監(jiān)視器對(duì)象,那么,兩個(gè)并發(fā)的線程可以同時(shí)分別進(jìn)入這兩個(gè)代碼塊中。對(duì)于同步方法的分析,所用的同步監(jiān)視器對(duì)象是this 接著對(duì)于靜態(tài)同步方法的分析,所用的同步監(jiān)視器對(duì)象是該類的Class對(duì)象 接著對(duì)如何實(shí)現(xiàn)代碼塊與方法的同步進(jìn)行分析。2.ClassLoader如何加載class。 jvm里有多個(gè)類加載,每個(gè)類加載可以負(fù)責(zé)加載特定位置的類,例如,bootstrap類加載負(fù)責(zé)加載jre/lib/rt.jar中的類,我們平時(shí)用的jdk中的類都位于rt.jar中。 extclassloader負(fù)責(zé)加載jar/lib/ext/*.jar中的類,appclassloader負(fù)責(zé)classpath指定的目錄或jar中的類。除了bootstrap之外,其他的類加載器本身也都是java類,它們的父類是ClassLoader。3.Servlet的生命周期 ? 通常情況下,服務(wù)器只會(huì)創(chuàng)建一個(gè)Servlet實(shí)例對(duì)象,也就是說Servlet實(shí)例對(duì)象一旦創(chuàng)建,它就會(huì)駐留在內(nèi)存中,為后續(xù)的其它請(qǐng)求服務(wù),直至web容器退出,servlet實(shí)例對(duì)象才會(huì)銷毀。 Web容器退出,調(diào)用destory方法,結(jié)束servlet; 4.抽象類的作用 5.ArrayList如何實(shí)現(xiàn)插入的數(shù)據(jù)按自定義的方式有序存放 class MyBean implements Comparable{ public int compareTo(Object obj){ if(!obj instanceof MyBean)throw new ClassCastException()//具體異常的名稱,我要查jdk文檔。 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 6.分層設(shè)計(jì)的好處;把各個(gè)功能按調(diào)用流程進(jìn)行了模塊化,模塊化帶來的好處就是可以隨意組合,舉例說明:如果要注冊(cè)一個(gè)用戶,流程為顯示界面并通過界面接收用戶的輸入,接著進(jìn)行業(yè)務(wù)邏輯處理,在處理業(yè)務(wù)邏輯又訪問數(shù)據(jù)庫(kù),如果我們將這些步驟全部按流水帳的方式放在一個(gè)方法中編寫,這也是可以的,但這其中的壞處就是,當(dāng)界面要修改時(shí),由于代碼全在一個(gè)方法內(nèi),可能會(huì)碰壞業(yè)務(wù)邏輯和數(shù)據(jù)庫(kù)訪問的碼,同樣,當(dāng)修改業(yè)務(wù)邏輯或數(shù)據(jù)庫(kù)訪問的代碼時(shí),也會(huì)碰壞其他部分的代碼。分層就是要把界面部分、業(yè)務(wù)邏輯部分、數(shù)據(jù)庫(kù)訪問部分的代碼放在各自獨(dú)立的方法或類中編寫,這樣就不會(huì)出現(xiàn)牽一發(fā)而動(dòng)全身的問題了。這樣分層后,還可以方便切換各層,譬如原來的界面是Swing,現(xiàn)在要改成 BS界面,如果最初是按分層設(shè)計(jì)的,這時(shí)候不需要涉及業(yè)務(wù)和數(shù)據(jù)訪問的代碼,只需編寫一條web界面就可以了。 下面的僅供參考,不建議照搬照套,一定要改成自己的語(yǔ)言,發(fā)現(xiàn)內(nèi)心的感受: 分層的好處: 1,實(shí)現(xiàn)了軟件之間的解耦; 2.便于進(jìn)行分工 3.便于維護(hù) 4,提高軟件組件的重用 5.便于替換某種產(chǎn)品,比如持久層用的是hibernate,需要更換產(chǎn)品用toplink,就不用該其他業(yè)務(wù)代碼,直接把配置一改。6.便于產(chǎn)品功能的擴(kuò)展。 7。便于適用用戶需求的不斷變化 7.序列化接口的id有什么用? 對(duì)象經(jīng)常要通過IO進(jìn)行傳送,讓你寫程序傳遞對(duì)象,你會(huì)怎么做?把對(duì)象的狀態(tài)數(shù)據(jù)用某種格式寫入到硬盤,Person->“zxx,male,28,30000”?Person,既然大家都要這么干,并且沒有個(gè)統(tǒng)一的干法,于是,sun公司就提出一種統(tǒng)一的解決方案,它會(huì)把對(duì)象變成某個(gè)格式進(jìn)行輸入和輸出,這種格式對(duì)程序員來說是透明(transparent)的,但是,我們的某個(gè)類要想能被sun的這種方案處理,必須實(shí)現(xiàn)Serializable接口。 ObjectOutputStream.writeObject(obj);Object obj = ObjectInputStream.readObject();假設(shè)兩年前我保存了某個(gè)類的一個(gè)對(duì)象,這兩年來,我修改該類,刪除了某個(gè)屬性和增加了另外一個(gè)屬性,兩年后,我又去讀取那個(gè)保存的對(duì)象,或有什么結(jié)果?未知!sun的jdk就會(huì)蒙了。為此,一個(gè)解決辦法就是在類中增加版本后,每一次類的屬性修改,都應(yīng)該把版本號(hào)升級(jí)一下,這樣,在讀取時(shí),比較存儲(chǔ)對(duì)象時(shí)的版本號(hào)與當(dāng)前類的版本號(hào),如果不一致,則直接報(bào)版本號(hào)不同的錯(cuò)! 9.hashCode方法的作用?說(網(wǎng)友提供的一段,待改進(jìn):hashcode這個(gè)方法是用來鑒定2個(gè)對(duì)象是否相等的。 那你會(huì)說,不是還有equals這個(gè)方法嗎? 不錯(cuò),這2個(gè)方法都是用來判斷2個(gè)對(duì)象是否相等的。但是他們是有區(qū)別的。一般來講,equals這個(gè)方法是給用戶調(diào)用的,如果你想判斷2個(gè)對(duì)象是否相等,你可以重寫equals方法,然后在代碼中調(diào)用,就可以判斷他們是否相等了。簡(jiǎn)單來講,equals方法主要是用來判斷從表面上看或者從內(nèi)容上看,2個(gè)對(duì)象是不是相等。舉個(gè)例子,有個(gè)學(xué)生類,屬性只有姓名和性別,那么我們可以認(rèn)為只要姓名和性別相等,那么就說這2個(gè)對(duì)象是相等的。 hashcode方法一般用戶不會(huì)去調(diào)用,比如在hashmap中,由于key是不可以重復(fù)的,他在判斷key是不是重復(fù)的時(shí)候就判斷了hashcode這個(gè)方法,而且也用到了equals方法。這里不可以重復(fù)是說equals和hashcode只要有一個(gè)不等就可以了!所以簡(jiǎn)單來講,hashcode相當(dāng)于是一個(gè)對(duì)象的編碼,就好像文件中的md5,他和equals不同就在于他返回的是int型的,比較起來不直觀。我們一般在覆蓋equals的同時(shí)也要覆蓋hashcode,讓他們的邏輯一致。舉個(gè) 例子,還是剛剛的例子,如果姓名和性別相等就算2個(gè)對(duì)象相等的話,那么hashcode的方法也要返回姓名的hashcode值加上性別的hashcode值,這樣從邏輯上,他們就一致了。 要從物理上判斷2個(gè)對(duì)象是否相等,用==就可以了。) 10.webservice問得很多 11.設(shè)計(jì)出計(jì)算任意正整數(shù)的階層。 4.在oracle數(shù)據(jù)庫(kù)中需要查詢出前8條記錄的sql語(yǔ)句怎么寫? Select * from(select *,rownum r from test where r<8) 5.什么是SOA,談?wù)勀愕腟OA的理解。service orientied architecture 面向服務(wù)的體系結(jié)構(gòu)(Service-Oriented Architecture,SOA)是一個(gè)組件模型,它將應(yīng)用程序的不同功能單元(稱為服務(wù))通過這些服務(wù)之間定義良好的接口和契約聯(lián)系起來。接口是采用中立的方式進(jìn)行定義的,它應(yīng)該獨(dú)立于實(shí)現(xiàn)服務(wù)的硬件平臺(tái)、操作系統(tǒng)和編程語(yǔ)言。這使得構(gòu)建在各種這樣的系統(tǒng)中的服務(wù)可以一種統(tǒng)一和通用的方式進(jìn)行交互。松耦合的 6.如何實(shí)現(xiàn)線程間的通訊。 新題目:編程:1.編寫一個(gè)函數(shù)將一個(gè)十六進(jìn)制數(shù)的字符串參數(shù)轉(zhuǎn)換成整數(shù)返回。String str = “13abf”;int len = str.length;int sum = 0;for(int i=0;i 其實(shí),也可以用Integer.parseInt(str,16),但面試官很可能是想考我們的編碼基本功。 編程2 :銀行貸款的還款方式中最常用的是一種叫“等額本息”,還款法,即借款人在約定還款期限內(nèi)的每一期(月)歸還的金額(產(chǎn)生的利息+部分本金)都是相等的,現(xiàn)有一筆總額為T元的N年期住房貸款,年利率為R,要求算出每一期的還款的本金和利息總額,請(qǐng)寫出解決思路和任意一種編程語(yǔ)言實(shí)現(xiàn)的主要代碼。思路:既然是按月還款,那我就要將N年按月來計(jì)算,即要還N*12個(gè)月,這樣就可以求出每月要還的本金。由于每月要還的那部分本金所欠的時(shí)間不同,所以, 它們所產(chǎn)生的利息是不同的,該部分本金的利息為:部分本金額*所欠月數(shù)*月利率。應(yīng)該是這么個(gè)算法,如果利息還計(jì)利息,如果月還款不按年利率來算,老百姓算不明白的。 int monthMoney = T/N/12;float monthRate = R/12;int totalMonth = N * 12;float totalRate = 0;for(int i=1;i<=totalMonth;i++){ totalRate += monthMoney * monthRate * i;} int result = monthMoney + totalRate/N/12; 幾道題: 1.****Spring的DI是什么(學(xué)員注:除了IOC,AOP這些概念,還不太清楚DI的概念) 什么是DI機(jī)制? 依賴注入(Dependecy Injection)和控制反轉(zhuǎn)(Inversion of Control)是同一個(gè)概念,具體的講:當(dāng)某個(gè)角色 需要另外一個(gè)角色協(xié)助的時(shí)候,在傳統(tǒng)的程序設(shè)計(jì)過程中,通常由調(diào)用者來創(chuàng)建被調(diào)用者的實(shí)例。但在spring中 創(chuàng)建被調(diào)用者的工作不再由調(diào)用者來完成,因此稱為控制反轉(zhuǎn)。創(chuàng)建被調(diào)用者的工作由spring來完成,然后注入調(diào)用者 因此也稱為依賴注入。 spring以動(dòng)態(tài)靈活的方式來管理對(duì)象,注入的兩種方式,設(shè)置注入和構(gòu)造注入。 設(shè)置注入的優(yōu)點(diǎn):直觀,自然 構(gòu)造注入的優(yōu)點(diǎn):可以在構(gòu)造器中決定依賴關(guān)系的順序。 2.*任意數(shù)字序列“123456”之類,輸出它們所有的排列組合 2題的答案: String str = “xafdvs”;char[] arr1 = str.toCharArray();char[] arr2 = Arrays.copyOf(arr1,arr1.length);for(int i=0;i 3.*****什么是AOP(學(xué)員注:會(huì)用,但感覺說不清楚)什么是AOP? 面向切面編程(AOP)完善spring的依賴注入(DI),面向切面編程在spring中主要表現(xiàn)為兩個(gè)方面 1.面向切面編程提供聲明式事務(wù)管理 2.spring支持用戶自定義的切面 面向切面編程(aop)是對(duì)面向?qū)ο缶幊蹋╫op)的補(bǔ)充,面向?qū)ο缶幊虒⒊绦蚍纸獬筛鱾€(gè)層次的對(duì)象,面向切面編程將程序運(yùn)行過程分解成各個(gè)切面。 AOP從程序運(yùn)行角度考慮程序的結(jié)構(gòu),提取業(yè)務(wù)處理過程的切面,oop是靜態(tài)的抽象,aop是動(dòng)態(tài)的抽象,是對(duì)應(yīng)用執(zhí)行過程中的步驟進(jìn)行抽象,從而獲得步驟之間的邏輯劃分。 aop框架具有的兩個(gè)特征: 1.各個(gè)步驟之間的良好隔離性 2.源代碼無(wú)關(guān)性 spring 的優(yōu)點(diǎn)? 1.降低了組件之間的耦合性,實(shí)現(xiàn)了軟件各層之間的解耦 2.可以使用容易提供的眾多服務(wù),如事務(wù)管理,消息服務(wù)等 3.容器提供單例模式支持 4.容器提供了AOP技術(shù),利用它很容易實(shí)現(xiàn)如權(quán)限攔截,運(yùn)行期監(jiān)控等功能 5.容器提供了眾多的輔助類,能加快應(yīng)用的開發(fā) 6.spring對(duì)于主流的應(yīng)用框架提供了集成支持,如hibernate,JPA,Struts等 7.spring屬于低侵入式設(shè)計(jì),代碼的污染極低 8.獨(dú)立于各種應(yīng)用服務(wù)器 9.spring的DI機(jī)制降低了業(yè)務(wù)對(duì)象替換的復(fù)雜性 10.Spring的高度開放性,并不強(qiáng)制應(yīng)用完全依賴于Spring,開發(fā)者可以自由選擇spring的部分或全部 3題的答案: 1.概念介紹:所謂AOP,即Aspect orientied program,就是面向方面的編程,2.解釋什么是方面:貫穿到系統(tǒng)的各個(gè)模塊中的系統(tǒng)一個(gè)功能就是一個(gè)方面,比如,記錄日志,統(tǒng)一異常處理,事務(wù)處理,全限檢查,這些功能都是軟件系統(tǒng) 的一個(gè)面,而不是一點(diǎn),在各個(gè)模塊中都要出現(xiàn)。 3.什么是面向方面編程:把系統(tǒng)的一個(gè)方面的功能封裝成對(duì)象的形式來處理 4.怎么進(jìn)行面向方面編程:把功能模塊對(duì)應(yīng)的對(duì)象作為切面嵌入到原來的各個(gè)系統(tǒng)模塊中,采用代理技術(shù),代理會(huì)調(diào)用目標(biāo),同時(shí)把切面功能的代碼(對(duì)象)加入進(jìn)來,所以,用spring配置代理對(duì)象時(shí)只要要配兩個(gè)屬性,分別表示目標(biāo)和切面對(duì)象(Advisor)。 3、構(gòu)造器Constructor是否可被override? 構(gòu)造器Constructor不能被繼承,因此不能重寫Override,但可以被重載Overload。 4、接口是否可繼承接口? 抽象類是否可實(shí)現(xiàn)(implements)接口? 抽象類是否可繼承具體類(concrete class)? 抽象類中是否可以有靜態(tài)的main方法? 接口可以繼承接口。抽象類可以實(shí)現(xiàn)(implements)接口,抽象類可繼承具體類。抽象類中可以有靜態(tài)的main方法。 備注:只要明白了接口和抽象類的本質(zhì)和作用,這些問題都很好回答,你想想,如果你是java語(yǔ)言的設(shè)計(jì)者,你是否會(huì)提供這樣的支持,如果不提供的話,有什么理由嗎?如果你沒有道理不提供,那答案就是肯定的了。 只有記住抽象類與普通類的唯一區(qū)別就是不能創(chuàng)建實(shí)例對(duì)象和允許有abstract方法。 5、寫clone()方法時(shí),通常都有一行代碼,是什么? clone 有缺省行為,super.clone();因?yàn)槭紫纫迅割愔械某蓡T復(fù)制到位,然后才是復(fù)制自己的成員。 6、面向?qū)ο蟮奶卣饔心男┓矫?/p> 計(jì)算機(jī)軟件系統(tǒng)是現(xiàn)實(shí)生活中的業(yè)務(wù)在計(jì)算機(jī)中的映射,而現(xiàn)實(shí)生活中的業(yè)務(wù)其實(shí)就是一個(gè)個(gè)對(duì)象協(xié)作的過程。面向?qū)ο缶幊叹褪前船F(xiàn)實(shí)業(yè)務(wù)一樣的方式將程序代碼按一個(gè)個(gè)對(duì)象進(jìn)行組織和編寫,讓計(jì)算機(jī)系統(tǒng)能夠識(shí)別和理解用對(duì)象方式組織和編寫的程序代碼,這樣就可以把現(xiàn)實(shí)生活中的業(yè)務(wù)對(duì)象映射到計(jì)算機(jī)系統(tǒng)中。 面向?qū)ο蟮木幊陶Z(yǔ)言有封裝、繼承、抽象、多態(tài)等4個(gè)主要的特征。1封裝: 封裝是保證軟件部件具有優(yōu)良的模塊性的基礎(chǔ),封裝的目標(biāo)就是要實(shí)現(xiàn)軟件部件的“高內(nèi)聚、低耦合”,防止程序相互依賴性而帶來的變動(dòng)影響。在面向?qū)ο蟮木幊陶Z(yǔ)言中,對(duì)象是封裝的最基本單位,面向?qū)ο蟮姆庋b比傳統(tǒng)語(yǔ)言的封裝更為清晰、更為有力。面向?qū)ο蟮姆庋b就是把描述一個(gè)對(duì)象的屬性和行為的代碼封裝在一個(gè)“模塊”中,也就是一個(gè)類中,屬性用變量定義,行為用方法進(jìn)行定義,方法可以直接訪問同一個(gè)對(duì)象中的屬性。通常情況下,只要記住讓變量和訪問這個(gè)變量的方法放在一起,將一個(gè)類中的成員變量全部定義成私有的,只有這個(gè)類自己的方法才可以訪問到這些成員變量,這就基本上實(shí)現(xiàn)對(duì)象的封裝,就很容易找出要分配到這個(gè)類上的方法了,就基本上算是會(huì)面向?qū)ο蟮木幊塘?。把握一個(gè)原則:把對(duì)同一事物進(jìn)行操作的方法和相關(guān)的方法放在同一個(gè)類中,把方法和它操作的數(shù)據(jù)放在同一個(gè)類中。 例如,人要在黑板上畫圓,這一共涉及三個(gè)對(duì)象:人、黑板、圓,畫圓的方法要分配給哪個(gè)對(duì)象呢?由于畫圓需要使用到圓心和半徑,圓心和半徑顯然是圓的屬性,如果將它們?cè)陬愔卸x成了私有的成員變量,那么,畫圓的方法必須分配給圓,它才能訪問到圓心和半徑這兩個(gè)屬性,人以后只是調(diào)用圓的畫圓方法、表示給圓發(fā)給消息而已,畫圓這個(gè)方法不應(yīng)該分配在人這個(gè)對(duì)象上,這就是面向 對(duì)象的封裝性,即將對(duì)象封裝成一個(gè)高度自治和相對(duì)封閉的個(gè)體,對(duì)象狀態(tài)(屬性)由這個(gè)對(duì)象自己的行為(方法)來讀取和改變。一個(gè)更便于理解的例子就是,司機(jī)將火車剎住了,剎車的動(dòng)作是分配給司機(jī),還是分配給火車,顯然,應(yīng)該分配給火車,因?yàn)樗緳C(jī)自身是不可能有那么大的力氣將一個(gè)火車給停下來的,只有火車自己才能完成這一動(dòng)作,火車需要調(diào)用內(nèi)部的離合器和剎車片等多個(gè)器件協(xié)作才能完成剎車這個(gè)動(dòng)作,司機(jī)剎車的過程只是給火車發(fā)了一個(gè)消息,通知火車要執(zhí)行剎車動(dòng)作而已。 抽象: 抽象就是找出一些事物的相似和共性之處,然后將這些事物歸為一個(gè)類,這個(gè)類只考慮這些事物的相似和共性之處,并且會(huì)忽略與當(dāng)前主題和目標(biāo)無(wú)關(guān)的那些方面,將注意力集中在與當(dāng)前目標(biāo)有關(guān)的方面。例如,看到一只螞蟻和大象,你能夠想象出它們的相同之處,那就是抽象。抽象包括行為抽象和狀態(tài)抽象兩個(gè)方面。例如,定義一個(gè)Person類,如下: class Person { String name;int age;} 人本來是很復(fù)雜的事物,有很多方面,但因?yàn)楫?dāng)前系統(tǒng)只需要了解人的姓名和年齡,所以上面定義的類中只包含姓名和年齡這兩個(gè)屬性,這就是一種抽像,使用抽象可以避免考慮一些與目標(biāo)無(wú)關(guān)的細(xì)節(jié)。我對(duì)抽象的理解就是不要用顯微鏡去看一個(gè)事物的所有方面,這樣涉及的內(nèi)容就太多了,而是要善于劃分問題的邊界,當(dāng)前系統(tǒng)需要什么,就只考慮什么。 繼承: 在定義和實(shí)現(xiàn)一個(gè)類的時(shí)候,可以在一個(gè)已經(jīng)存在的類的基礎(chǔ)之上來進(jìn)行,把這個(gè)已經(jīng)存在的類所定義的內(nèi)容作為自己的內(nèi)容,并可以加入若干新的內(nèi)容,或修改原來的方法使之更適合特殊的需要,這就是繼承。繼承是子類自動(dòng)共享父類數(shù)據(jù)和方法的機(jī)制,這是類之間的一種關(guān)系,提高了軟件的可重用性和可擴(kuò)展性。 多態(tài): 多態(tài)是指程序中定義的引用變量所指向的具體類型和通過該引用變量發(fā)出的方法調(diào)用在編程時(shí)并不確定,而是在程序運(yùn)行期間才確定,即一個(gè)引用變量倒底會(huì)指向哪個(gè)類的實(shí)例對(duì)象,該引用變量發(fā)出的方法調(diào)用到底是哪個(gè)類中實(shí)現(xiàn)的方法,必須在由程序運(yùn)行期間才能決定。因?yàn)樵诔绦蜻\(yùn)行時(shí)才確定具體的類,這樣,不用修改源程序代碼,就可以讓引用變量綁定到各種不同的類實(shí)現(xiàn)上,從而導(dǎo)致該引用調(diào)用的具體方法隨之改變,即不修改程序代碼就可以改變程序運(yùn)行時(shí)所綁定的具體代碼,讓程序可以選擇多個(gè)運(yùn)行狀態(tài),這就是多態(tài)性。多態(tài)性增強(qiáng)了軟件的靈活性和擴(kuò)展性。例如,下面代碼中的UserDao是一個(gè)接口,它定義引用變量userDao指向的實(shí)例對(duì)象由daofactory.getDao()在執(zhí)行的時(shí)候返回,有時(shí)候指向的是UserJdbcDao這個(gè)實(shí)現(xiàn),有時(shí)候指向的是UserHibernateDao這個(gè)實(shí)現(xiàn),這樣,不用修改源代碼,就可以改變userDao指向的具體類實(shí)現(xiàn),從而導(dǎo)致 userDao.insertUser()方法調(diào)用的具體代碼也隨之改變,即有時(shí)候調(diào)用的是UserJdbcDao的insertUser方法,有時(shí)候調(diào)用的是UserHibernateDao的insertUser方法: UserDao userDao = daofactory.getDao();userDao.insertUser(user); 比喻:人吃飯,你看到的是左手,還是右手? 7、java中實(shí)現(xiàn)多態(tài)的機(jī)制是什么? 靠的是父類或接口定義的引用變量可以指向子類或具體實(shí)現(xiàn)類的實(shí)例對(duì)象,而程序調(diào)用的方法在運(yùn)行期才動(dòng)態(tài)綁定,就是引用變量所指向的具體實(shí)例對(duì)象的方法,也就是內(nèi)存里正在運(yùn)行的那個(gè)對(duì)象的方法,而不是引用變量的類型中定義的方法。 8、abstract class和interface有什么區(qū)別? 含有abstract修飾符的class即為抽象類,abstract 類不能創(chuàng)建的實(shí)例對(duì)象。含有abstract方法的類必須定義為abstract class,abstract class類中的方法不必是抽象的。abstract class類中定義抽象方法必須在具體(Concrete)子類中實(shí)現(xiàn),所以,不能有抽象構(gòu)造方法或抽象靜態(tài)方法。如果的子類沒有實(shí)現(xiàn)抽象父類中的所有抽象方法,那么子類也必須定義為abstract類型。 接口(interface)可以說成是抽象類的一種特例,接口中的所有方法都必須是抽象的。接口中的方法定義默認(rèn)為public abstract類型,接口中的成員變量類型默認(rèn)為public static final。 下面比較一下兩者的語(yǔ)法區(qū)別: 1.抽象類可以有構(gòu)造方法,接口中不能有構(gòu)造方法。 2.抽象類中可以有普通成員變量,接口中沒有普通成員變量 3.抽象類中可以包含非抽象的普通方法,接口中的所有方法必須都是抽象的,不能有非抽象的普通方法。 4.抽象類中的抽象方法的訪問類型可以是public,protected和(默認(rèn)類型,雖然 eclipse下不報(bào)錯(cuò),但應(yīng)該也不行),但接口中的抽象方法只能是public類型的,并且默認(rèn)即為public abstract類型。 5.抽象類中可以包含靜態(tài)方法,接口中不能包含靜態(tài)方法 6.抽象類和接口中都可以包含靜態(tài)成員變量,抽象類中的靜態(tài)成員變量的訪問類型可以任意,但接口中定義的變量只能是public static final類型,并且默認(rèn)即為public static final類型。 7.一個(gè)類可以實(shí)現(xiàn)多個(gè)接口,但只能繼承一個(gè)抽象類。下面接著再說說兩者在應(yīng)用上的區(qū)別: 接口更多的是在系統(tǒng)架構(gòu)設(shè)計(jì)方法發(fā)揮作用,主要用于定義模塊之間的通信契約。而抽象類在代碼實(shí)現(xiàn)方面發(fā)揮作用,可以實(shí)現(xiàn)代碼的重用,例如,模板方法設(shè)計(jì)模式是抽象類的一個(gè)典型應(yīng)用,假設(shè)某個(gè)項(xiàng)目的所有Servlet類都要用相 同的方式進(jìn)行權(quán)限判斷、記錄訪問日志和處理異常,那么就可以定義一個(gè)抽象的基類,讓所有的Servlet都繼承這個(gè)抽象基類,在抽象基類的service方法中完成權(quán)限判斷、記錄訪問日志和處理異常的代碼,在各個(gè)子類中只是完成各自的業(yè)務(wù)邏輯代碼,偽代碼如下: public abstract class BaseServlet extends HttpServlet { public final void service(HttpServletRequest request, HttpServletResponse response)throws IOExcetion,ServletException { 記錄訪問日志 進(jìn)行權(quán)限判斷 if(具有權(quán)限){ try { doService(request,response);} catch(Excetpion e){ 記錄異常信息 } } } protected abstract void doService(HttpServletRequest request, HttpServletResponse response)throws IOExcetion,ServletException;//注意訪問權(quán)限定義成protected,顯得既專業(yè),又嚴(yán)謹(jǐn),因?yàn)樗菍iT給子類用的 } public class MyServlet1 extends BaseServlet { protected void doService(HttpServletRequest request, HttpServletResponse response)throws IOExcetion,ServletException { 本Servlet只處理的具體業(yè)務(wù)邏輯代碼 } } 父類方法中間的某段代碼不確定,留給子類干,就用模板方法設(shè)計(jì)模式。備注:這道題的思路是先從總體解釋抽象類和接口的基本概念,然后再比較兩者的語(yǔ)法細(xì)節(jié),最后再說兩者的應(yīng)用區(qū)別。比較兩者語(yǔ)法細(xì)節(jié)區(qū)別的條理是:先從一個(gè)類中的構(gòu)造方法、普通成員變量和方法(包括抽象方法),靜態(tài)變量和方法,繼承性等6個(gè)方面逐一去比較回答,接著從 9、abstract的method是否可同時(shí)是static,是否可同時(shí)是native,是否可同時(shí)是synchronized? abstract的method 不可以是static的,因?yàn)槌橄蟮姆椒ㄊ且蛔宇悓?shí)現(xiàn)的,而static與子類扯不上關(guān)系! native方法表示該方法要用另外一種依賴平臺(tái)的編程語(yǔ)言實(shí)現(xiàn)的,不存在著被子類實(shí)現(xiàn)的問題,所以,它也不能是抽象的,不能與abstract混用。例如,F(xiàn)ileOutputSteam類要硬件打交道,底層的實(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)用別人寫的c語(yǔ)言函數(shù),我們是無(wú)法直接調(diào)用的,我們需要按照java的要求寫一個(gè)c語(yǔ)言的函數(shù),又我們的這個(gè)c語(yǔ)言函數(shù)去調(diào)用別人的c語(yǔ)言函數(shù)。由于我們的c語(yǔ)言函數(shù)是按java的要求來寫的,我們這個(gè)c語(yǔ)言函數(shù)就可以與java對(duì)接上,java那邊的對(duì)接方式就是定義出與我們這個(gè)c函數(shù)相對(duì)應(yīng)的方法,java中對(duì)應(yīng)的方法不需要寫具體的代碼,但需要在前面聲明native。關(guān)于synchronized與abstract合用的問題,我覺得也不行,因?yàn)樵谖規(guī)啄甑膶W(xué)習(xí)和開發(fā)中,從來沒見到過這種情況,并且我覺得synchronized應(yīng)該是作用在一個(gè)具體的方法上才有意義。而且,方法上的synchronized同步所使用的同步鎖對(duì)象是this,而抽象方法上無(wú)法確定this是什么。 10、什么是內(nèi)部類?Static Nested Class 和 Inner Class的不同。 內(nèi)部類就是在一個(gè)類的內(nèi)部定義的類,內(nèi)部類中不能定義靜態(tài)成員(靜態(tài)成員不是對(duì)象的特性,只是為了找一個(gè)容身之處,所以需要放到一個(gè)類中而已,這么一點(diǎn)小事,你還要把它放到類內(nèi)部的一個(gè)類中,過分了??!提供內(nèi)部類,不是為讓你干這種事情,無(wú)聊,不讓你干。我想可能是既然靜態(tài)成員類似c語(yǔ)言的全局變量,而內(nèi)部類通常是用于創(chuàng)建內(nèi)部對(duì)象用的,所以,把“全局變量”放在內(nèi)部類中就是毫無(wú)意義的事情,既然是毫無(wú)意義的事情,就應(yīng)該被禁止),內(nèi)部類可以直接訪問外部類中的成員變量,內(nèi)部類可以定義在外部類的方法外面,也可以定義在外部類的方法體中,如下所示: public class Outer { int out_x = 0;public void method() { Inner1 inner1 = new Inner1();public class Inner2 //在方法體內(nèi)部定義的內(nèi)部類 { public method(){ out_x = 3;} } Inner2 inner2 = new Inner2();} public class Inner1 //在方法體外面定義的內(nèi)部類 { } } 在方法體外面定義的內(nèi)部類的訪問類型可以是public,protecte,默認(rèn)的,private等4種類型,這就好像類中定義的成員變量有4種訪問類型一樣,它們決定這個(gè)內(nèi)部類的定義對(duì)其他類是否可見;對(duì)于這種情況,我們也可以在外面創(chuàng)建內(nèi)部類的實(shí)例對(duì)象,創(chuàng)建內(nèi)部類的實(shí)例對(duì)象時(shí),一定要先創(chuàng)建外部類的實(shí)例對(duì)象,然后用這個(gè)外部類的實(shí)例對(duì)象去創(chuàng)建內(nèi)部類的實(shí)例對(duì)象,代碼如下: Outer outer = new Outer();Outer.Inner1 inner1 = outer.new Innner1(); 在方法內(nèi)部定義的內(nèi)部類前面不能有訪問類型修飾符,就好像方法中定義的局部變量一樣,但這種內(nèi)部類的前面可以使用final或abstract修飾符。這種內(nèi)部類對(duì)其他類是不可見的其他類無(wú)法引用這種內(nèi)部類,但是這種內(nèi)部類創(chuàng)建的實(shí)例對(duì)象可以傳遞給其他類訪問。這種內(nèi)部類必須是先定義,后使用,即內(nèi)部類的定義代碼必須出現(xiàn)在使用該類之前,這與方法中的局部變量必須先定義后使用的道理也是一樣的。這種內(nèi)部類可以訪問方法體中的局部變量,但是,該局部變量前必須加final修飾符。 對(duì)于這些細(xì)節(jié),只要在eclipse寫代碼試試,根據(jù)開發(fā)工具提示的各類錯(cuò)誤信息就可以馬上了解到。 在方法體內(nèi)部還可以采用如下語(yǔ)法來創(chuàng)建一種匿名內(nèi)部類,即定義某一接口或類的子類的同時(shí),還創(chuàng)建了該子類的實(shí)例對(duì)象,無(wú)需為該子類定義名稱: public class Outer { public void start(){ new Thread(new Runable(){ public void run(){};}).start();} } 最后,在方法外部定義的內(nèi)部類前面可以加上static關(guān)鍵字,從而成為Static Nested Class,它不再具有內(nèi)部類的特性,所有,從狹義上講,它不是內(nèi)部類。Static Nested Class與普通類在運(yùn)行時(shí)的行為和功能上沒有什么區(qū)別,只是在編程 引用時(shí)的語(yǔ)法上有一些差別,它可以定義成public、protected、默認(rèn)的、private等多種類型,而普通類只能定義成public和默認(rèn)的這兩種類型。在外面引用Static Nested Class類的名稱為“外部類名.內(nèi)部類名”。在外面不需要?jiǎng)?chuàng)建外部類的實(shí)例對(duì)象,就可以直接創(chuàng)建Static Nested Class,例如,假設(shè)Inner是定義在Outer類中的Static Nested Class,那么可以使用如下語(yǔ)句創(chuàng)建Inner類: Outer.Inner inner = new Outer.Inner();由于static Nested Class不依賴于外部類的實(shí)例對(duì)象,所以,static Nested Class能訪問外部類的非static成員變量。當(dāng)在外部類中訪問Static Nested Class時(shí),可以直接使用Static Nested Class的名字,而不需要加上外部類的名字了,在Static Nested Class中也可以直接引用外部類的static的成員變量,不需要加上外部類的名字。 在靜態(tài)方法中定義的內(nèi)部類也是Static Nested Class,這時(shí)候不能在類前面加static關(guān)鍵字,靜態(tài)方法中的Static Nested Class與普通方法中的內(nèi)部類的應(yīng)用方式很相似,它除了可以直接訪問外部類中的static的成員變量,還可以訪問靜態(tài)方法中的局部變量,但是,該局部變量前必須加final修飾符。 備注:首先根據(jù)你的印象說出你對(duì)內(nèi)部類的總體方面的特點(diǎn):例如,在兩個(gè)地方可以定義,可以訪問外部類的成員變量,不能定義靜態(tài)成員,這是大的特點(diǎn)。然后再說一些細(xì)節(jié)方面的知識(shí),例如,幾種定義方式的語(yǔ)法區(qū)別,靜態(tài)內(nèi)部類,以及匿名內(nèi)部類。 11、內(nèi)部類可以引用它的包含類的成員嗎?有沒有什么限制? 完全可以。如果不是靜態(tài)內(nèi)部類,那沒有什么限制! 如果你把靜態(tài)嵌套類當(dāng)作內(nèi)部類的一種特例,那在這種情況下不可以訪問外部類的普通成員變量,而只能訪問外部類中的靜態(tài)成員,例如,下面的代碼: class Outer { static int x;static class Inner { void test(){ syso(x);} } } 答題時(shí),也要能察言觀色,揣摩提問者的心思,顯然人家希望你說的是靜態(tài)內(nèi)部類不能訪問外部類的成員,但你一上來就頂牛,這不好,要先順著人家,讓人家滿意,然后再說特殊情況,讓人家吃驚。 12、Anonymous Inner Class(匿名內(nèi)部類)是否可以extends(繼承)其它類,是否可以implements(實(shí)現(xiàn))interface(接口)? 可以繼承其他類或?qū)崿F(xiàn)其他接口。不僅是可以,而是必須! 13、super.getClass()方法調(diào)用 下面程序的輸出結(jié)果是多少? import java.util.Date;public class Test extends Date{ public static void main(String[] args){ new Test().test();} public void test(){ System.out.println(super.getClass().getName());} } 很奇怪,結(jié)果是Test 這屬于腦筋急轉(zhuǎn)彎的題目,在一個(gè)qq群有個(gè)網(wǎng)友正好問過這個(gè)問題,我覺得挺有趣,就研究了一下,沒想到今天還被你面到了,哈哈。 在test方法中,直接調(diào)用getClass().getName()方法,返回的是Test類名 由于getClass()在Object類中定義成了final,子類不能覆蓋該方法,所以,在 test方法中調(diào)用getClass().getName()方法,其實(shí)就是在調(diào)用從父類繼承的getClass()方法,等效于調(diào)用super.getClass().getName()方法,所以,super.getClass().getName()方法返回的也應(yīng)該是Test。如果想得到父類的名稱,應(yīng)該用如下代碼: getClass().getSuperClass().getName(); 14.jdk中哪些類是不能繼承的? 不能繼承的是類是那些用final關(guān)鍵字修飾的類。一般比較基本的類型或防止擴(kuò)展類無(wú)意間破壞原來方法的實(shí)現(xiàn)的類型都應(yīng)該是final的,在jdk中System,String,StringBuffer等都是基本類型。 2、String是最基本的數(shù)據(jù)類型嗎? 基本數(shù)據(jù)類型包括byte、int、char、long、float、double、boolean和short。java.lang.String類是final類型的,因此不可以繼承這個(gè)類、不能修改這個(gè)類。為了提高效率節(jié)省空間,我們應(yīng)該用StringBuffer類 111、String s = ”Hello“;s = s + ” world!“;這兩行代碼執(zhí)行后,原始的String對(duì)象中的內(nèi)容到底變了沒有? 沒有。因?yàn)镾tring被設(shè)計(jì)成不可變(immutable)類,所以它的所有對(duì)象都是不可變對(duì)象。在這段代碼中,s原先指向一個(gè)String對(duì)象,內(nèi)容是 ”Hello“,然后我們對(duì)s進(jìn)行了+操作,那么s所指向的那個(gè)對(duì)象是否發(fā)生了改變呢?答案是沒有。這時(shí),s不指向原來那個(gè)對(duì)象了,而指向了另一個(gè) String對(duì)象,內(nèi)容為”Hello world!“,原來那個(gè)對(duì)象還存在于內(nèi)存之中,只是s這個(gè)引用變量不再指向它了。 通過上面的說明,我們很容易導(dǎo)出另一個(gè)結(jié)論,如果經(jīng)常對(duì)字符串進(jìn)行各種各樣的修改,或者說,不可預(yù)見的修改,那么使用String來代表字符串的話會(huì)引起很大的內(nèi)存開銷。因?yàn)?String對(duì)象建立之后不能再改變,所以對(duì)于每一個(gè)不同的字符串,都需要一個(gè)String對(duì)象來表示。這時(shí),應(yīng)該考慮使用StringBuffer類,它允許修改,而不是每個(gè)不同的字符串都要生成一個(gè)新的對(duì)象。并且,這兩種類的對(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)存開銷大,并且沒有意義,因?yàn)镾tring對(duì)象不可改變,所以對(duì)于內(nèi)容相同的字符串,只要一個(gè)String對(duì)象來表示就可以了。也就說,多次調(diào)用上面的構(gòu)造器創(chuàng)建多個(gè)對(duì)象,他們的String類型屬性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類設(shè)計(jì)成不可變類,是它的用途決定的。其實(shí)不只String,很多Java標(biāo)準(zhǔn)類庫(kù)中的類都是不可變的。在開發(fā)一個(gè)系統(tǒng)的時(shí)候,我們有時(shí)候也需要設(shè)計(jì)不可變類,來傳遞一組相關(guān)的值,這也是面向?qū)ο笏枷氲捏w現(xiàn)。不可變類有一些優(yōu)點(diǎn),比如因?yàn)樗膶?duì)象是只讀的,所以多線程并發(fā)訪問也不會(huì)有任何問題。當(dāng)然也有一些缺點(diǎn),比如每個(gè)不同的狀態(tài)都要一個(gè)對(duì)象來代表,可能會(huì)造成性能上的問題。所以Java標(biāo)準(zhǔn)類庫(kù)還提供了一個(gè)可變版本,即 StringBuffer。 41、是否可以繼承String類? String類是final類故不可以繼承。 27、String s = new String(”xyz“);創(chuàng)建了幾個(gè)String Object? 二者之間有什么區(qū)別? 兩個(gè)或一個(gè),”xyz”對(duì)應(yīng)一個(gè)對(duì)象,這個(gè)對(duì)象放在字符串常量緩沖區(qū),常量”xyz”不管出現(xiàn)多少遍,都是緩沖區(qū)中的那一個(gè)。New String每寫一遍,就創(chuàng)建一個(gè)新的對(duì)象,它一句那個(gè)常量”xyz”對(duì)象的內(nèi)容來創(chuàng)建出一個(gè)新String對(duì)象。如果以前就用過’xyz’,這句代表就不會(huì)創(chuàng)建”xyz”自己了,直接從緩沖區(qū)拿。 5、String 和StringBuffer的區(qū)別 JAVA平臺(tái)提供了兩個(gè)類:String和StringBuffer,它們可以儲(chǔ)存和操作字符串,即包含多個(gè)字符的字符數(shù)據(jù)。String類表示內(nèi)容不可改變的字符串。而StringBuffer類表示內(nèi)容可以被修改的字符串。當(dāng)你知道字符數(shù)據(jù)要改變的時(shí)候你就可以使用StringBuffer。典型地,你可以使用StringBuffers來動(dòng)態(tài)構(gòu)造字符數(shù)據(jù)。另外,String實(shí)現(xiàn)了equals方法,new String(“abc”).equals(new String(“abc”)的結(jié)果為true,而StringBuffer沒有實(shí)現(xiàn)equals方法,所以,new StringBuffer(“abc”).equals(new StringBuffer(“abc”)的結(jié)果為false。 接著要舉一個(gè)具體的例子來說明,我們要把1到100的所有數(shù)字拼起來,組成一個(gè)串。 StringBuffer sbf = new StringBuffer(); for(int i=0;i<100;i++){ sbf.append(i);} 上面的代碼效率很高,因?yàn)橹粍?chuàng)建了一個(gè)StringBuffer對(duì)象,而下面的代碼效率很低,因?yàn)閯?chuàng)建了101個(gè)對(duì)象。String str = new String();for(int i=0;i<100;i++){ str = str + i;} 在講兩者區(qū)別時(shí),應(yīng)把循環(huán)的次數(shù)搞成10000,然后用endTime-beginTime來比較兩者執(zhí)行的時(shí)間差異,最后還要講講StringBuilder與StringBuffer的區(qū)別。 String覆蓋了equals方法和hashCode方法,而StringBuffer沒有覆蓋equals方法和hashCode方法,所以,將StringBuffer對(duì)象存儲(chǔ)進(jìn)Java集合類中時(shí)會(huì)出現(xiàn)問題。 8.StringBuffer與StringBuilder的區(qū)別 StringBuffer和StringBuilder類都表示內(nèi)容可以被修改的字符串,StringBuilder是線程不安全的,運(yùn)行效率高,如果一個(gè)字符串變量是在方法里面定義,這種情況只可能有一個(gè)線程訪問它,不存在不安全的因素了,則用StringBuilder。如果要在類里面定義成員變量,并且這個(gè)類的實(shí)例對(duì)象會(huì)在多線程環(huán)境下使用,那么最好用StringBuffer。 3、如何把一段逗號(hào)分割的字符串轉(zhuǎn)換成一個(gè)數(shù)組? 如果不查jdk api,我很難寫出來!我可以說說我的思路: 1.用正則表達(dá)式,代碼大概為:String [] result = orgStr.split(“,”);2.用 StingTokenizer ,代碼為:StringTokenizer tokener = StringTokenizer(orgStr,”,”);String [] result = new String[tokener.countTokens()];Int i=0;while(tokener.hasNext(){result[i++]=toker.nextToken();} 38、數(shù)組有沒有l(wèi)ength()這個(gè)方法? String有沒有l(wèi)ength()這個(gè)方法? 數(shù)組沒有l(wèi)ength()這個(gè)方法,有l(wèi)ength的屬性。String有有l(wèi)ength()這個(gè)方法。 39、下面這條語(yǔ)句一共創(chuàng)建了多少個(gè)對(duì)象:String s=”a“+”b“+”c“+”d“;答:對(duì)于如下代碼: String s1 = ”a“;String s2 = s1 + ”b“;String s3 = ”a“ + ”b“;System.out.println(s2 == ”ab“);System.out.println(s3 == ”ab“); } finally { ++x;} } } ---------執(zhí)行結(jié)果---------1 運(yùn)行結(jié)果是1,為什么呢?主函數(shù)調(diào)用子函數(shù)并得到結(jié)果的過程,好比主函數(shù)準(zhǔn)備一個(gè)空罐子,當(dāng)子函數(shù)要返回結(jié)果時(shí),先把結(jié)果放在罐子里,然后再將程序邏輯返回到主函數(shù)。所謂返回,就是子函數(shù)說,我不運(yùn)行了,你主函數(shù)繼續(xù)運(yùn)行吧,這沒什么結(jié)果可言,結(jié)果是在說這話之前放進(jìn)罐子里的。 7、下面的程序代碼輸出的結(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。 我可以通過下面一個(gè)例子程序來幫助我解釋這個(gè)答案,從下面例子的運(yùn)行結(jié)果中可以發(fā)現(xiàn),try中的return語(yǔ)句調(diào)用的函數(shù)先于finally中調(diào)用的函數(shù)執(zhí)行,也就是說return語(yǔ)句先執(zhí)行,finally語(yǔ)句后執(zhí)行,所以,返回的結(jié)果是2。Return并不是讓函數(shù)馬上返回,而是return語(yǔ)句執(zhí)行后,將把返回結(jié)果放置進(jìn)函數(shù)棧中,此時(shí)函數(shù)并不是馬上返回,它要執(zhí)行finally語(yǔ)句后才真正開始返回。在講解答案時(shí)可以用下面的程序來幫助分析: 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í)行 12、final, finally, finalize的區(qū)別。 final 用于聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。 內(nèi)部類要訪問局部變量,局部變量必須定義成final類型,例如,一段代碼…… finally是異常處理語(yǔ)句結(jié)構(gòu)的一部分,表示總是執(zhí)行。 finalize是Object類的一個(gè)方法,在垃圾收集器執(zhí)行的時(shí)候會(huì)調(diào)用被回收對(duì)象的此方法,可以覆蓋此方法提供垃圾收集時(shí)的其他資源回收,例如關(guān)閉文件等。JVM不保證此方法總被調(diào)用 5、運(yùn)行時(shí)異常與一般異常有何異同? 異常表示程序運(yùn)行過程中可能出現(xiàn)的非正常狀態(tài),運(yùn)行時(shí)異常表示虛擬機(jī)的通常操作中可能遇到的異常,是一種常見運(yùn)行錯(cuò)誤。java編譯器要求方法必須聲明拋出可能發(fā)生的非運(yùn)行時(shí)異常,但是并不要求必須聲明拋出未被捕獲的運(yùn)行時(shí)異常。 15、error和exception有什么區(qū)別? error 表示恢復(fù)不是不可能但很困難的情況下的一種嚴(yán)重問題。比如說內(nèi)存溢出。不可能指望程序能處理這樣的情況。exception 表示一種設(shè)計(jì)或?qū)崿F(xiàn)問題。也就是說,它表示如果程序運(yùn)行正常,從不會(huì)發(fā)生的情況。 50、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ì)象來表示,Java使用面向?qū)ο蟮姆绞絹硖幚懋惓?,它把程序中發(fā)生的每個(gè)異常也都分別封裝到一個(gè)對(duì)象來表示的,該對(duì)象中包含有異常的信息。 Java對(duì)異常進(jìn)行了分類,不同類型的異常分別用不同的Java類表示,所有異常的根類為java.lang.Throwable,Throwable下面又派生了兩個(gè)子類:Error和Exception,Error 表示應(yīng)用程序本身無(wú)法克服和恢復(fù)的一種嚴(yán)重問題,程序只有死的份了,例如,說內(nèi)存溢出和線程死鎖等系統(tǒng)問題。Exception表示程序還能 夠克服和恢復(fù)的問題,其中又分為系統(tǒng)異常和普通異常,系統(tǒng)異常是軟件本身缺陷所導(dǎo)致的問題,也就是軟件開發(fā)人員考慮不周所導(dǎo)致的問題,軟件使用者無(wú)法克服和恢復(fù)這種問題,但在這種問題下還可以讓軟件系統(tǒng)繼續(xù)運(yùn)行或者讓軟件死掉,例如,數(shù)組腳本越界(ArrayIndexOutOfBoundsException),空指針異常(NullPointerException)、類轉(zhuǎn)換異常(ClassCastException);普通異常是運(yùn)行環(huán)境的變化或異常所導(dǎo)致的問題,是用戶能夠克服的問題,例如,網(wǎng)絡(luò)斷線,硬盤空間不夠,發(fā)生這樣的異常后,程序不應(yīng)該死掉。 java為系統(tǒng)異常和普通異常提供了不同的解決方案,編譯器強(qiáng)制普通異常必須try..catch處理或用throws聲明繼續(xù)拋給上層調(diào)用方法處理,所以普通異常也稱為checked異常,而系統(tǒng)異??梢蕴幚硪部梢圆惶幚?,所以,編譯器不強(qiáng)制用try..catch處理或用throws聲明,所以系統(tǒng)異常也稱為unchecked異常。 提示答題者:就按照三個(gè)級(jí)別去思考:虛擬機(jī)必須宕機(jī)的錯(cuò)誤,程序可以死掉也可以不死掉的錯(cuò)誤,程序不應(yīng)該死掉的錯(cuò)誤; 33、請(qǐng)寫出你最常見到的5個(gè)runtime exception。 這道題主要考你的代碼量到底多大,如果你長(zhǎng)期寫代碼的,應(yīng)該經(jīng)常都看到過一些系統(tǒng)方面的異常,你不一定真要回答出5個(gè)具體的系統(tǒng)異常,但你要能夠說出什么是系統(tǒng)異常,以及幾個(gè)系統(tǒng)異常就可以了,當(dāng)然,這些異常完全用其英文名稱來寫是最好的,如果實(shí)在寫不出,那就用中文吧,有總比沒有強(qiáng)! 所謂系統(tǒng)異常,就是…..,它們都是RuntimeException的子類,在jdk doc中查RuntimeException類,就可以看到其所有的子類列表,也就是看到了所有的系統(tǒng)異常。我比較有印象的系統(tǒng)異常有:NullPointerException、ArrayIndexOutOfBoundsException、ClassCastException。unknowntypeException illegalArgumentException 96、JAVA語(yǔ)言如何進(jìn)行異常處理,關(guān)鍵字:throws,throw,try,catch,finally分別代表什么意義?在try塊中可以拋出異常嗎? 99、java中有幾種方法可以實(shí)現(xiàn)一個(gè)線程?用什么關(guān)鍵字修飾同步方法? stop()和suspend()方法為何不推薦使用? java5以前,有如下兩種: 表示一個(gè)Thread的匿名子類的實(shí)例對(duì)象,子類加上run方法后的代碼如下: new Thread(){ public void run(){ } }.start(); notify()重新啟動(dòng)線程。 13、sleep()和 wait()有什么區(qū)別?(網(wǎng)上的答案:sleep是線程類(Thread)的方法,導(dǎo)致此線程暫停執(zhí)行指定時(shí)間,給執(zhí)行機(jī)會(huì)給其他線程,但是監(jiān)控狀態(tài)依然保持,到時(shí)后會(huì)自動(dòng)恢復(fù)。調(diào)用sleep不會(huì)釋放對(duì)象鎖。wait是Object類的方法,對(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í)間過后,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)用過wait方法的線程可以去參與獲得鎖的競(jìng)爭(zhēng)了,但不是馬上得到鎖,因?yàn)殒i還在別人手里,別人還沒釋放。如果notify方法后面的代碼還有很多,需要這些代碼執(zhí)行完后才會(huì)釋放鎖,可以在notfiy方法后增加一個(gè)等待和一些代碼,看看效果),調(diào)用wait方法的線程就會(huì)解除wait狀態(tài)和程序可以再次得到鎖后繼續(xù)向下運(yùn)行。對(duì)于wait的講解一定要配合例子代碼來說明,才顯得自己真明白。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 { //釋放鎖有兩種方式,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沒有釋放鎖,所以Thread1無(wú)法得不到鎖。 MultiThread.class.notify(); System.out.println(”thread2 is sleeping 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!“);} } } } 16、同步和異步有何異同,在什么情況下分別使用他們?舉例說明。 如果數(shù)據(jù)將在線程間共享。例如正在寫的數(shù)據(jù)以后可能被另一個(gè)線程讀到,或者正在讀的數(shù)據(jù)可能已經(jīng)被另一個(gè)線程寫過了,那么這些數(shù)據(jù)就是共享數(shù)據(jù),必須進(jìn)行同步存取。 當(dāng)應(yīng)用程序在對(duì)象上調(diào)用了一個(gè)需要花費(fèi)很長(zhǎng)時(shí)間來執(zhí)行的方法,并且不希望讓程序等待方法的返回時(shí),就應(yīng)該使用異步編程,在很多情況下采用異步途徑往往更有效率。 ten 17.下面兩個(gè)方法同步嗎?(自己發(fā)明) class Test { synchronized static void sayHello3(){ } synchronized void getX(){} } 56、多線程有幾種實(shí)現(xiàn)方法?同步有幾種實(shí)現(xiàn)方法? 多線程有兩種實(shí)現(xiàn)方法,分別是繼承Thread類與實(shí)現(xiàn)Runnable接口 同步的實(shí)現(xiàn)方面有兩種,分別是synchronized,wait與notify wait():使一個(gè)線程處于等待狀態(tài),并且釋放所持有的對(duì)象的lock。 sleep():使一個(gè)正在運(yùn)行的線程處于睡眠狀態(tài),是一個(gè)靜態(tài)方法,調(diào)用此方法要捕捉InterruptedException異常。 notify():喚醒一個(gè)處于等待狀態(tài)的線程,注意的是在調(diào)用此方法的時(shí)候,并不能確切的喚醒某一個(gè)等待狀態(tài)的線程,而是由JVM確定喚醒哪個(gè)線程,而且不是按優(yōu)先級(jí)。 Allnotity():喚醒所有處入等待狀態(tài)的線程,注意并不是給所有喚醒線程一個(gè)對(duì)象的鎖,而是讓它們競(jìng)爭(zhēng)。 30、啟動(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í)行代碼。 47、當(dāng)一個(gè)線程進(jìn)入一個(gè)對(duì)象的一個(gè)synchronized方法后,其它線程是否可進(jìn)入此對(duì)象的其它方法? 分幾種情況: 1.其他方法前是否加了synchronized關(guān)鍵字,如果沒加,則能。 2.如果這個(gè)方法內(nèi)部調(diào)用了wait,則可以進(jìn)入其他synchronized方法。 3.如果其他個(gè)方法都加了synchronized關(guān)鍵字,并且內(nèi)部沒有調(diào)用wait,則不能。 4.如果其他方法是static,它用的同步鎖是當(dāng)前類的字節(jié)碼,與非靜態(tài)的方法不能同步,因?yàn)榉庆o態(tài)的方法用的是this。 58、線程的基本概念、線程的基本狀態(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í)行多段程序呢?這是從宏觀上來看的,cpu一會(huì)執(zhí)行a線索,一會(huì)執(zhí)行b線索,切換時(shí)間很快,給人的感覺是a,b在同時(shí)執(zhí)行,好比大家在同一個(gè)辦公室上網(wǎng),只有一條鏈接到外部網(wǎng)線,其實(shí),這條網(wǎng)線一會(huì)為a傳數(shù)據(jù),一會(huì)為b傳數(shù)據(jù),由于切換時(shí)間很短暫,所以,大家感覺都在同時(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)。 71、簡(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方法可以非阻塞方式去拿鎖。 舉例說明(對(duì)下面的題用lock進(jìn)行了改寫): package com.huawei.interview; import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock; public class ThreadTest { /** * @param args */ private int j; private Lock lock = new ReentrantLock();public static void main(String[] args){ // TODO Auto-generated method stub ThreadTest tt = new ThreadTest();for(int i=0;i<2;i++){ new Thread(tt.new Adder()).start();new Thread(tt.new Subtractor()).start();} } private class Subtractor implements Runnable { @Override public void run(){ // TODO Auto-generated method stub while(true){ /*synchronized(ThreadTest.this){ System.out.println(”j--=“ + j--);//這里拋異常了,鎖能釋放嗎? }*/ lock.lock();try { System.out.println(”j--=“ + j--);}finally { lock.unlock();} } } } private class Adder implements Runnable { @Override public void run(){ // TODO Auto-generated method stub while(true) { /*synchronized(ThreadTest.this){ System.out.println(”j++=“ + j++);}*/ lock.lock();try { System.out.println(”j++=“ + j++);}finally { lock.unlock();} } } } } 28、設(shè)計(jì)4個(gè)線程,其中兩個(gè)線程每次對(duì)j增加1,另外兩個(gè)線程對(duì)j每次減少1。寫出程序。 以下程序使用內(nèi)部類實(shí)現(xiàn)線程,對(duì)j增減的時(shí)候沒有考慮順序問題。public class ThreadTest1 { private int j;public static void main(String args[]){ ThreadTest1 tt=new ThreadTest1();Inc inc=tt.new Inc();Dec dec=tt.new Dec();for(int i=0;i<2;i++){ Thread t=new Thread(inc);t.start();t=new Thread(dec);t.start();} } private synchronized void inc(){ j++;System.out.println(Thread.currentThread().getName()+”-inc:“+j);} private synchronized void dec(){ j--;System.out.println(Thread.currentThread().getName()+”-dec:“+j); } class Inc implements Runnable{ public void run(){ for(int i=0;i<100;i++){ inc();} } } class Dec implements Runnable{ public void run(){ for(int i=0;i<100;i++){ dec();} } } } ----------隨手再寫的一個(gè)-------------class A { JManger j =new JManager();main(){ new A().call();} void call { for(int i=0;i<2;i++){ new Thread(new Runnable(){ public void run(){while(true){j.accumulate()}}}).start();new Thread(new Runnable(){ public void run(){while(true){j.sub()}}}).start();} } } class JManager { private j = 0; public synchronized void subtract(){ j--} public synchronized void accumulate(){ j++;} } 28、子線程循環(huán)10次,接著主線程循環(huán)100,接著又回到子線程循環(huán)10次,接著再回到主線程又循環(huán)100,如此循環(huán)50次,請(qǐng)寫出程序。 最終的程序代碼如下: public class ThreadTest { /** * @param args */ public static void main(String[] args){ // TODO Auto-generated method stub new ThreadTest().init();} public void init(){ final Business business = new Business();new Thread(new Runnable(){ public void run(){ for(int i=0;i<50;i++){ business.SubThread(i);} } } ).start(); for(int i=0;i<50;i++){ business.MainThread(i);} } private class Business { boolean bShouldSub = true;//這里相當(dāng)于定義了控制該誰(shuí)執(zhí)行的一個(gè)信號(hào)燈 public synchronized void MainThread(int i){ if(bShouldSub)try { this.wait();} catch(InterruptedException e){ // TODO Auto-generated catch block e.printStackTrace();} for(int j=0;j<5;j++){ System.out.println(Thread.currentThread().getName()”:i=“ + i +”,j=“ + j);} bShouldSub = true;this.notify();} public synchronized void SubThread(int i){ if(!bShouldSub)try { this.wait();} catch(InterruptedException e){ // TODO Auto-generated catch block e.printStackTrace();} + for(int j=0;j<10;j++){ System.out.println(Thread.currentThread().getName()+ ”:i=“ + i +”,j=“ + j);} bShouldSub = false;this.notify();} } } 備注:不可能一上來就寫出上面的完整代碼,最初寫出來的代碼如下,問題在于兩個(gè)線程的代碼要參照同一個(gè)變量,即這兩個(gè)線程的代碼要共享數(shù)據(jù),所以,把這兩個(gè)線程的執(zhí)行代碼搬到同一個(gè)類中去: package com.huawei.interview.lym; public class ThreadTest { private static boolean bShouldMain = false; public static void main(String[] args){ // TODO Auto-generated method stub /*new Thread(){ public void run(){ for(int i=0;i<50;i++){ for(int j=0;j<10;j++){ System.out.println(”i=“ + i + ”,j=“ + j);} } } }.start();*/ //final String str = new String(”“); new Thread(new Runnable(){ public void run() { for(int i=0;i<50;i++){ synchronized(ThreadTest.class){ if(bShouldMain){ try { ThreadTest.class.wait();} catch(InterruptedException e){ e.printStackTrace();} } for(int j=0;j<10;j++){ System.out.println(Thread.currentThread().getName()+ ”i=“ + i + ”,j=“ + j);} bShouldMain = true;ThreadTest.class.notify();} } } }).start(); for(int i=0;i<50;i++){ synchronized(ThreadTest.class){ if(!bShouldMain){ try { ThreadTest.class.wait();} catch(InterruptedException e){ e.printStackTrace();} } for(int j=0;j<5;j++){ System.out.println(Thread.currentThread().getName()+ ”i=“ + i + ”,j=“ + j);} bShouldMain = false; ThreadTest.class.notify();} } } } 下面使用jdk5中的并發(fā)庫(kù)來實(shí)現(xiàn)的: import java.util.concurrent.Executors;import java.util.concurrent.ExecutorService;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;import java.util.concurrent.locks.Condition; public class ThreadTest { private static Lock lock = new ReentrantLock();private static Condition subThreadCondition = lock.newCondition();private static boolean bBhouldSubThread = false;public static void main(String [] args){ ExecutorService threadPool = Executors.newFixedThreadPool(3);threadPool.execute(new Runnable(){ public void run(){ for(int i=0;i<50;i++){ lock.lock();try { if(!bBhouldSubThread)subThreadCondition.await();for(int j=0;j<10;j++){ System.out.println(Thread.currentThread().getName()+ ”,j=“ + j);} bBhouldSubThread = false;subThreadCondition.signal();}catch(Exception e){ } finally { lock.unlock();} } } });threadPool.shutdown();for(int i=0;i<50;i++){ lock.lock();try { if(bBhouldSubThread)subThreadCondition.await();for(int j=0;j<10;j++){ System.out.println(Thread.currentThread().getName()+ ”,j=“ + j);} bBhouldSubThread = true;subThreadCondition.signal();}catch(Exception e){ } finally { lock.unlock();} } } } 3、介紹Collection框架的結(jié)構(gòu) 答:隨意發(fā)揮題,天南海北誰(shuí)便談,只要讓別覺得你知識(shí)淵博,理解透徹即可。 3、Collection框架中實(shí)現(xiàn)比較要實(shí)現(xiàn)什么接口 comparable/comparator 3、ArrayList和Vector的區(qū)別 答: 這兩個(gè)類都實(shí)現(xiàn)了List接口(List接口繼承了Collection接口),他們都是有序集合,即存儲(chǔ)在這兩個(gè)集合中的元素的位置都是有順序的,相當(dāng)于一種動(dòng)態(tài)的數(shù)組,我們以后可以按位置索引號(hào)取出某個(gè)元素,并且其中的數(shù)據(jù)是允許重復(fù)的,這是HashSet之類的集合的最大不同處,HashSet之類的集合不可以按索引號(hào)去檢索其中的元素,也不允許有重復(fù)的元素(本來題目問的與hashset沒有任何關(guān)系,但為了說清楚ArrayList與Vector的功能,我們使用對(duì)比方式,更有利于說明問題)。 接著才說ArrayList與Vector的區(qū)別,這主要包括兩個(gè)方面:.(1)同步性: Vector是線程安全的,也就是說是它的方法之間是線程同步的,而ArrayList是線程序不安全的,它的方法之間是線程不同步的。如果只有一個(gè)線程會(huì)訪問到集合,那最好是使用ArrayList,因?yàn)樗豢紤]線程安全,效率會(huì)高些;如果有多個(gè)線程會(huì)訪問到集合,那最好是使用Vector,因?yàn)椴恍枰覀冏约涸偃タ紤]和編寫線程安全的代碼。 備注:對(duì)于Vector&ArrayList、Hashtable&HashMap,要記住線程安全的問題,記住Vector與Hashtable是舊的,是java一誕生就提供了的,它們是線程安全的,ArrayList與HashMap是java2時(shí)才提供的,它們是線程不安全的。所以,我們講課時(shí)先講老的。(2)數(shù)據(jù)增長(zhǎng): ArrayList與Vector都有一個(gè)初始的容量大小,當(dāng)存儲(chǔ)進(jìn)它們里面的元素的個(gè)數(shù)超過了容量時(shí),就需要增加ArrayList與Vector的存儲(chǔ)空間,每次要增加存儲(chǔ)空間時(shí),不是只增加一個(gè)存儲(chǔ)單元,而是增加多個(gè)存儲(chǔ)單元,每次增加的存儲(chǔ)單元的個(gè)數(shù)在內(nèi)存空間利用與程序效率之間要取得一定的平衡。Vector默認(rèn)增長(zhǎng)為原來兩倍,而ArrayList的增長(zhǎng)策略在文檔中沒有明確規(guī)定(從源代碼看到的是增長(zhǎng)為原來的1.5倍)。ArrayList與Vector都可以設(shè)置初始的空間大小,Vector還可以設(shè)置增長(zhǎng)的空間大小,而ArrayList沒有提供設(shè)置增長(zhǎng)空間的方法??偨Y(jié):即Vector增長(zhǎng)原來的一倍,ArrayList增加原來的0.5倍。 4、HashMap和Hashtable的區(qū)別 (條理上還需要整理,也是先說相同點(diǎn),再說不同點(diǎn))HashMap是Hashtable的輕量級(jí)實(shí)現(xiàn)(非線程安全的實(shí)現(xiàn)),他們都完成了Map接口,主要區(qū)別在于HashMap允許空(null)鍵值(key),由于非線程安全,在只有一個(gè)線程訪問的情況下,效率要高于Hashtable。 HashMap允許將null作為一個(gè)entry的key或者value,而Hashtable不允許。HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因?yàn)閏ontains方法容易讓人引起誤解。Hashtable繼承自Dictionary類,而HashMap是Java1.2引進(jìn)的Map interface的一 個(gè)實(shí)現(xiàn)。 最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多個(gè)線程訪問Hashtable時(shí),不需要自己為它的方法實(shí)現(xiàn)同步,而HashMap 就必須為之提供外同步。 Hashtable和HashMap采用的hash/rehash算法都大概一樣,所以性能不會(huì)有很大的差異。 就HashMap與HashTable主要從三方面來說。 一.歷史原因:Hashtable是基于陳舊的Dictionary類的,HashMap是Java 1.2引進(jìn)的Map接口的一個(gè)實(shí)現(xiàn) 二.同步性:Hashtable是線程安全的,也就是說是同步的,而HashMap是線程序不安全的,不是同步的 三.值:只有HashMap可以讓你將空值作為一個(gè)表的條目的key或value 5、List 和 Map 區(qū)別? 一個(gè)是存儲(chǔ)單列數(shù)據(jù)的集合,另一個(gè)是存儲(chǔ)鍵和值這樣的雙列數(shù)據(jù)的集合,List中存儲(chǔ)的數(shù)據(jù)是有順序,并且允許重復(fù);Map中存儲(chǔ)的數(shù)據(jù)是沒有順序的,其鍵是不能重復(fù)的,它的值是可以有重復(fù)的。 35、List, Set, Map是否繼承自Collection接口? List,Set是,Map不是 109、List、Map、Set三個(gè)接口,存取元素時(shí),各有什么特點(diǎn)? 這樣的題屬于隨意發(fā)揮題:這樣的題比較考水平,兩個(gè)方面的水平:一是要真正明白這些內(nèi)容,二是要有較強(qiáng)的總結(jié)和表述能力。如果你明白,但表述不清楚,在別人那里則等同于不明白。 首先,List與Set具有相似性,它們都是單列元素的集合,所以,它們有一個(gè)功共同的父接口,叫Collection。Set里面不允許有重復(fù)的元素,所謂重復(fù),即不能有兩個(gè)相等(注意,不是僅僅是相同)的對(duì)象,即假設(shè)Set集合中有了一個(gè)A對(duì)象,現(xiàn)在我要向Set集合再存入一個(gè)B對(duì)象,但B對(duì)象與A對(duì)象equals相等,則B對(duì)象存儲(chǔ)不進(jìn)去,所以,Set集合的add方法有一個(gè)boolean的返回值,當(dāng)集合中沒有某個(gè)元素,此時(shí)add方法可成功加入該元素時(shí),則返回true,當(dāng)集合含有與某個(gè)元素equals相等的元素時(shí),此時(shí)add方法無(wú)法加入該元素,返回結(jié)果為false。Set取元素時(shí),沒法說取 index,Obj e)方法,就可以指定當(dāng)前對(duì)象在集合中的存放位置。一個(gè)對(duì)象可以被反復(fù)存儲(chǔ)進(jìn)List中,每調(diào)用一次add方法,這個(gè)對(duì)象就被插入進(jìn)集合中一次,其實(shí),并不是把這個(gè)對(duì)象本身存儲(chǔ)進(jìn)了集合中,而是在集合中用一個(gè)索引變量指向這個(gè)對(duì)象,當(dāng)這個(gè)對(duì)象被add多次時(shí),即相當(dāng)于集合中有多個(gè)索引指向了這個(gè)對(duì)象,如圖x所示。List除了可以以Iterator接口取得所有的元素,再逐一遍歷各個(gè)元素之外,還可以調(diào)用get(index i)來明確說明取 4、去掉一個(gè)Vector集合中重復(fù)的元素 Vector newVector = new Vector();For(int i=0;i 9、Collection 和 Collections的區(qū)別。 Collection是集合類的上級(jí)接口,繼承與他的接口主要有Set 和List.Collections是針對(duì)集合類的一個(gè)幫助類,他提供一系列靜態(tài)方法實(shí)現(xiàn)對(duì)各種集合的搜索、排序、線程安全化等操作。 39、Set里的元素是不能重復(fù)的,那么用什么方法來區(qū)分重復(fù)與否呢? 是用==還是equals()? 它們有何區(qū)別? Set里的元素是不能重復(fù)的,元素重復(fù)與否是使用equals()方法進(jìn)行判斷的。equals()和==方法決定引用值是否指向同一對(duì)象equals()在類中被覆蓋,為的是當(dāng)兩個(gè)分離的對(duì)象的內(nèi)容和類型相配的話,返回真值。 53、你所知道的集合類都有哪些?主要方法? 最常用的集合類是 List 和 Map。List 的具體實(shí)現(xiàn)包括 ArrayList 和 Vector,它們是可變大小的列表,比較適合構(gòu)建、存儲(chǔ)和操作任何類型對(duì)象的元素列表。List 適用于按數(shù)值索引訪問元素的情形。 Map 提供了一個(gè)更通用的元素存儲(chǔ)方法。Map 集合類用于存儲(chǔ)元素對(duì)(稱作”鍵“和”值“),其中每個(gè)鍵映射到一個(gè)值。 ArrayList/Vector?List ?Collection HashSet/TreeSet?Set Propeties?HashTable ?Map Treemap/HashMap 我記的不是方法名,而是思想,我知道它們都有增刪改查的方法,但這些方法的 具體名稱,我記得不是很清楚,對(duì)于set,大概的方法是add,remove, contains;對(duì)于map,大概的方法就是put,remove,contains等,因?yàn)椋抑灰趀clispe下按點(diǎn)操作符,很自然的這些方法就出來了。我記住的一些思想就是List類會(huì)有g(shù)et(int index)這樣的方法,因?yàn)樗梢园错樞蛉≡?,而set類中沒有g(shù)et(int index)這樣的方法。List和set都可以迭代出所有元素,迭代時(shí)先要得到一個(gè)iterator對(duì)象,所以,set和list類都有一個(gè)iterator方法,用于返回那個(gè)iterator對(duì)象。map可以返回三個(gè)集合,一個(gè)是返回所有的key的集合,另外一個(gè)返回的是所有value的集合,再一個(gè)返回的key和value組合成的EntrySet對(duì)象的集合,map也有g(shù)et方法,參數(shù)是key,返回值是key對(duì)應(yīng)的value。 45、兩個(gè)對(duì)象值相同(x.equals(y)== true),但卻可有不同的hash code,這句話對(duì)不對(duì)? 對(duì)。 如果對(duì)象要保存在HashSet或HashMap中,它們的equals相等,那么,它們的hashcode值就必須相等。 如果不是要保存在HashSet或HashMap,則與hashcode沒有什么關(guān)系了,這時(shí)候hashcode不等是可以的,例如arrayList存儲(chǔ)的對(duì)象就不用實(shí)現(xiàn)hashcode,當(dāng)然,我們沒有理由不實(shí)現(xiàn),通常都會(huì)去實(shí)現(xiàn)的。 46、TreeSet里面放對(duì)象,如果同時(shí)放入了父類和子類的實(shí)例對(duì)象,那比較時(shí)使用的是父類的compareTo方法,還是使用的子類的compareTo方法,還是拋異常! (應(yīng)該是沒有針對(duì)問題的確切的答案,當(dāng)前的add方法放入的是哪個(gè)對(duì)象,就調(diào)用哪個(gè)對(duì)象的compareTo方法,至于這個(gè)compareTo方法怎么做,就看當(dāng)前這個(gè)對(duì)象的類中是如何編寫這個(gè)方法的)實(shí)驗(yàn)代碼: public class Parent implements Comparable { private int age = 0;public Parent(int age){ this.age = age;} public int compareTo(Object o){ // TODO Auto-generated method stub System.out.println(”method of parent“);Parent o1 =(Parent)o;return age>o1.age?1:age } public class Child extends Parent { public Child(){ super(3);} public int compareTo(Object o){ // TODO Auto-generated method stub System.out.println(”method of child“);// Child o1 =(Child)o;return 1;} } public class TreeSetTest { /** * @param args */ public static void main(String[] args){ // TODO Auto-generated method stub TreeSet set = new TreeSet();set.add(new Parent(3));set.add(new Child());set.add(new Parent(4));System.out.println(set.size());} } 112、說出一些常用的類,包,接口,請(qǐng)各舉5個(gè) 要讓人家感覺你對(duì)java ee開發(fā)很熟,所以,不能僅僅只列core java中的那些東西,要多列你在做ssh項(xiàng)目中涉及的那些東西。就寫你最近寫的那些程序中涉及的那些類。 常用的類:BufferedReader BufferedWriter FileReader FileWirter String Integer java.util.Date,System,Class,List,HashMap 常用的包:java.lang java.io java.util java.sql ,javax.servlet,org.apache.strtuts.action,org.hibernate 常用的接口:Remote List Map Document NodeList ,Servlet,HttpServletRequest,HttpServletResponse,Transaction(Hibernate)、Session(Hibernate),HttpSession 100、java中有幾種類型的流?JDK為每種類型的流提供了一些抽象類以供繼承,請(qǐng)說出他們分別是哪些類? 字節(jié)流,字符流。字節(jié)流繼承于InputStream OutputStream,字符流繼承于InputStreamReader OutputStreamWriter。在java.io包中還有許多其他的流,主要是為了提高性能和使用方便。102、字節(jié)流與字符流的區(qū)別 要把一片二進(jìn)制數(shù)據(jù)數(shù)據(jù)逐一輸出到某個(gè)設(shè)備中,或者從某個(gè)設(shè)備中逐一讀取一片二進(jìn)制數(shù)據(jù),不管輸入輸出設(shè)備是什么,我們要用統(tǒng)一的方式來完成這些操作,用一種抽象的方式進(jìn)行描述,這個(gè)抽象描述方式起名為IO流,對(duì)應(yīng)的抽象類為OutputStream和InputStream,不同的實(shí)現(xiàn)類就代表不同的輸入和輸出設(shè)備,它們都是針對(duì)字節(jié)進(jìn)行操作的。 在應(yīng)用中,經(jīng)常要完全是字符的一段文本輸出去或讀進(jìn)來,用字節(jié)流可以嗎?計(jì)算機(jī)中的一切最終都是二進(jìn)制的字節(jié)形式存在。對(duì)于“中國(guó)”這些字符,首先要得到其對(duì)應(yīng)的字節(jié),然后將字節(jié)寫入到輸出流。讀取時(shí),首先讀到的是字節(jié),可是我們要把它顯示為字符,我們需要將字節(jié)轉(zhuǎn)換成字符。由于這樣的需求很廣泛,人家專門提供了字符流的包裝類。 底層設(shè)備永遠(yuǎn)只接受字節(jié)數(shù)據(jù),有時(shí)候要寫字符串到底層設(shè)備,需要將字符串轉(zhuǎn)成字節(jié)再進(jìn)行寫入。字符流是字節(jié)流的包裝,字符流則是直接接受字符串,它內(nèi)部將串轉(zhuǎn)成字節(jié),再寫入底層設(shè)備,這為我們向IO設(shè)別寫入或讀取字符串提供了一點(diǎn)點(diǎn)方便。 字符向字節(jié)轉(zhuǎn)換時(shí),要注意編碼的問題,因?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);} } 105、什么是java序列化,如何實(shí)現(xiàn)java序列化?或者請(qǐng)解釋Serializable接口的作用。第三篇:JAVA面試題
第四篇:java程序員面試題
第五篇:Java就業(yè)面試題