java宝典
說明,為了減輕大家的負擔和節省大家的時間,一些過時知識點和被筆試概率極低的題目不再被收錄和分析。
回答問題的思路:先正面敘述一些基本的核心知識,然后描述一些特殊的東西,最后再來一些錦上添花的東西。要注意有些不是錦上添花,而是畫蛇添足的東西,不要隨便寫上。把答題像寫書一樣寫。我要回答一個新技術的問題大概思路和步驟是:我們想干什么,干這個遇到了什么問題,現在用什么方式來解決。其實我們講課也是這樣一個思路。
例如,將ajax時,我們希望不改變原來的整個網頁,而知識改變網頁中的局部內容,例如,用戶名校驗,級聯下拉列表,下來樹狀菜單。用傳統方式,就是瀏覽器自己直接向服務器發請求,服務器返回新頁面回蓋掉老頁面,這樣就不流暢了。
?
對于這個系列里的問題,每個學Java的人都應該搞懂。當然,如果只是學Java玩玩就無所謂了。如果你認為自己已經超越初學者了,卻不很懂這些問題,請將你自己重歸初學者行列。
答題時,先答是什么,再答有什么作用和要注意什么(這部分最重要,展現自己的心得)
?
答案的段落分別,層次分明,條理清楚都非常重要,從這些表面的東西也可以看出一個人的習慣、辦事風格、條理等。
要將你做出答案的思路過程,或者說你記住答案的思想都寫下來。把答題想著是辯論賽。答題就是給別人講道理、擺事實。答題不局限于什么格式和形式,就是要將自己的學識展現出來!
別因為人家題目本來就模棱兩可,你就心里膽怯和沒底氣了,不敢回答了。你要大膽地指出對方題目很模糊和你的觀點,不要把面試官想得有多高,其實他和你就是差不多的,你想想,如果他把你招進去了,你們以后就是同事了,可不是差不多的嗎?
關于就業薪水,如果你是應屆生,那不能要高工資,好比大餅的故事,要拿高工資,就去中關村!少數人基礎確實很好,在校期間確實又做過一些項目,那仍然是可以要到相對高的工資的。基礎好的冷桂華的故事。
初級程序員薪水:2000-4500
中級程序員薪水:4000-7000
高級程序員薪水:7000以上
?
公司招聘程序員更看重的要用到的編碼技術、而不是那些業務不太相關的所謂項目經歷:
1.公司想招什么樣的人2.公司面試會問什么,.3.簡歷怎么寫4怎樣達到簡歷上的標準(培訓中心教項目的目的)
?
對于一些公司接到了一些項目,想招聘一些初中級的程序員過來幫助寫代碼,完成這個項目,你更看重的是他的專業技術功底,還是以前做過幾個項目的經歷呢?我們先排除掉那些編碼技術功底好,又正好做過相似項目的情況,實際上,這種魚和熊掌兼得的情況并不常見。其實公司很清楚,只要招聘進來的人技術真的很明白,那他什么項目都可以做出來,公司招人不是讓你去重復做你以前的項目,而是做一個新項目,業務方面,你只要進了項目團隊,自然就能掌握。所以,大多數招聘單位在招聘那些編碼級別的程序員時也沒指望能招聘到做過類似項目的人,也不會刻意去找做過類似項目的人,用人單位也不是想把你招進,然后把你以前做過的項目重做一遍,所以,用人單位更看重招進來的人對要用到的編碼技術的功底到底怎樣,技術扎實不扎實,項目則只要跟著開發團隊走,自然就沒問題。除非是一些非常專業的行業,要招聘特別高級的開發人員和系統分析師,招聘單位才特別注重他的項目經驗和行業經驗,要去找到行業高手,公司才關心項目和與你聊項目的細節,這樣的人通常都不是通過常規招聘渠道去招聘進來的,而是通過各種手段挖過來的,這情況不再我今天要討論的范圍中。
技術學得明白不明白,人家幾個問題就把你的深淺問出來了,只要問一些具體的技術點,就很容易看出你是真懂還是假懂,很容看出你的技術深度和實力,所以,技術是來不得半點虛假的,必須扎扎實實。
由于項目的種類繁多,涉及到現實生活中的各行各業,什么五花八門的業務都有,例如,酒店房間預定管理,公司車輛調度管理,學校課程教室管理,超市進銷存管理,知識內容管理,等等……成千上萬等等,但是,不管是什么項目,采用的無非都是我們學習的那些目前流行和常用的技術。技術好、經驗豐富,則項目做出來的效率高些,程序更穩定和更容易維護些;技術差點,碰碰磕磕最后也能把項目做出來,無非是做的周期長點、返工的次數多點,程序代碼寫得差些,用的技術笨拙點。如果一個人不是完完全全做過某個項目,他是不太關心該項目的業務的,對其中的一些具體細節更是一竅不知,(如果我招你來做圖書管理,你項目經歷說你做過汽車調度,那我能問你汽車調度具體怎么回事嗎?不會,所以,你很容易蒙混過去的)而一個程序員的整個職業生涯中能實實在在和完完整整做出來的項目沒幾個,更別說在多個不同行業的項目了,有的程序員更是一輩子都只是在做某一個行業的項目,結果他就成了這個行業的專家(專門干一件事的家伙)。所以,技術面試官通常沒正好親身經歷過你簡歷寫的那些項目,他不可能去問你寫的那些項目的具體細節,而是只能泛泛地問你這個項目是多少人做的,做了多長時間,開發的過程,你在做項目的過程中有什么心得和收獲,用的什么技術等面上的問題,所以,簡歷上的項目經歷可以含有很多水分,很容易作假,技術面試官也無法在項目上甄別你的真偽。
簡歷該怎么寫:精通那些技術,有一些什么項目經歷
教項目是為了鞏固和靈活整合運用技術,增強學習的趣味性,熟悉做項目的流程,或得一些專業課程中無法獲得的特有項目經驗,增強自己面試的信心。講的項目應該真實可靠才有價值,否則,表面上是項目,實際上還是知識點的整合,對鞏固技術點和增強學習的趣味性,但無法獲得實際的項目經驗。(項目主要是增加你經驗的可信度,獲得更多面試機會,真正能不能找到工作,找到好工作,主要看你鍵盤上的功夫了)
建議大家盡量開自己的blog,堅持每天寫技術blog。在簡歷上寫上自己的blog地址,可以多轉載一些技術文章。
Java就業培訓教程就是小沈陽
1.?Java基礎部分
基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語法,集合的語法,io?的語法,虛擬機方面的語法,其他
1、一個".java"源文件中是否可以包括多個類(不是內部類)?有什么限制??
可以有多個類,但只能有一個public的類,并且public的類名必須與文件名相一致。
2、&和&&的區別。?
&和&&都可以用作邏輯與的運算符,表示邏輯與(and),當運算符兩邊的表達式的結果都為true時,整個運算結果才為true,否則,只要有一方為false,則結果為false。
&&還具有短路的功能,即如果第一個表達式為false,則不再計算第二個表達式,例如,對于if(str?!=?null?&&?!str.equals(“”))表達式,當str為null時,后面的表達式不會執行,所以不會出現NullPointerException如果將&&改為&,則會拋出NullPointerException異常。If(x==33?&?++y>0)?y會增長,If(x==33?&&?++y>0)不會增長
&還可以用作位運算符,當&操作符兩邊的表達式不是boolean類型時,&表示按位與操作,我們通常使用0x0f來與一個整數進行&運算,來獲取該整數的最低4個bit位,例如,0x31?&?0x0f的結果為0x01。?
?
備注:這道題先說兩者的共同點,再說出&&和&的特殊之處,并列舉一些經典的例子來表明自己理解透徹深入、實際經驗豐富。?
3、Java有沒有goto??
java中的保留字,現在沒有在java中使用。
?
4、在JAVA中,如何跳出當前的多重嵌套循環??
在Java中,要想跳出多重循環,可以在外面的循環語句前定義一個標號,然后在里層循環體的代碼中使用帶有標號的break?語句,即可跳出外層循環。例如,
ok:
for(int?i=0;i<10;i++)
{
for(int?j=0;j<10;j++)
{
System.out.println(“i=”?+?i?+?“,j=”?+?j);
if(j?==?5)?break?ok;
}
}?
另外,我個人通常并不使用標號這種方式,而是讓外層的循環條件表達式的結果可以受到里層循環體代碼的控制,例如,要在二維數組中查找到某個數字。
boolean?found?=?false;
for(int?i=0;i<10?&&?!found;i++)
{
for(int?j=0;j<10;j++)
{
System.out.println(“i=”?+?i?+?“,j=”?+?j);
if(j?==?5)?
{
found?=?true;
break;
}
}
}?
?
?
5、switch是否能作用在byte上,是否能作用在long上,是否能作用在String上??
在switch(expr1)中,expr1只能是一個整數表達式或者枚舉常量(更大字體),整數表達式可以是int基本類型或Integer包裝類型,由于,byte,short,char都可以隱含轉換為int,所以,這些類型以及這些類型的包裝類型也是可以的。顯然,long和String類型都不符合sitch的語法規定,并且不能被隱式轉換成int類型,所以,它們不能作用于swtich語句中。?
6、short?s1?=?1;?s1?=?s1?+?1;有什么錯??short?s1?=?1;?s1?+=?1;有什么錯??
對于short?s1?=?1;?s1?=?s1?+?1;?由于s1+1運算時會自動提升表達式的類型,所以結果是int型,再賦值給short類型s1時,編譯器將報告需要強制轉換類型的錯誤。
對于short?s1?=?1;?s1?+=?1;由于?+=?是java語言規定的運算符,java編譯器會對它進行特殊處理,因此可以正確編譯。?
7、char型變量中能不能存貯一個中文漢字?為什么??
char型變量是用來存儲Unicode編碼的字符的,unicode編碼字符集中包含了漢字,所以,char型變量中當然可以存儲漢字啦。不過,如果某個特殊的漢字沒有被包含在unicode編碼字符集中,那么,這個char型變量中就不能存儲這個特殊漢字。補充說明:unicode編碼占用兩個字節,所以,char類型的變量也是占用兩個字節。
備注:后面一部分回答雖然不是在正面回答題目,但是,為了展現自己的學識和表現自己對問題理解的透徹深入,可以回答一些相關的知識,做到知無不言,言無不盡。?
8、編程題:?用最有效率的方法算出2乘以8等於幾??
2?<<?3,
因為將一個數左移n位,就相當于乘以了2的n次方,那么,一個數乘以8只要將其左移3位即可,而位運算cpu直接支持的,效率最高,所以,2乘以8等於幾的最效率的方法是2?<<?3。
9、請設計一個一百億的計算器
首先要明白這道題目的考查點是什么,一是大家首先要對計算機原理的底層細節要清楚、要知道加減法的位運算原理和知道計算機中的算術運算會發生越界的情況,二是要具備一定的面向對象的設計思想。
首先,計算機中用固定數量的幾個字節來存儲的數值,所以計算機中能夠表示的數值是有一定的范圍的,為了便于講解和理解,我們先以byte?類型的整數為例,它用1個字節進行存儲,表示的最大數值范圍為-128到+127。-1在內存中對應的二進制數據為11111111,如果兩個-1相加,不考慮Java運算時的類型提升,運算后會產生進位,二進制結果為1,11111110,由于進位后超過了byte類型的存儲空間,所以進位部分被舍棄,即最終的結果為11111110,也就是-2,這正好利用溢位的方式實現了負數的運算。-128在內存中對應的二進制數據為10000000,如果兩個-128相加,不考慮Java運算時的類型提升,運算后會產生進位,二進制結果為1,00000000,由于進位后超過了byte類型的存儲空間,所以進位部分被舍棄,即最終的結果為00000000,也就是0,這樣的結果顯然不是我們期望的,這說明計算機中的算術運算是會發生越界情況的,兩個數值的運算結果不能超過計算機中的該類型的數值范圍。由于Java中涉及表達式運算時的類型自動提升,我們無法用byte類型來做演示這種問題和現象的實驗,大家可以用下面一個使用整數做實驗的例子程序體驗一下:
int?a?=?Integer.MAX_VALUE;
int?b?=?Integer.MAX_VALUE;
int?sum?=?a?+?b;
System.out.println(“a=”+a+”,b=”+b+”,sum=”+sum);
?
先不考慮long類型,由于int的正數范圍為2的31次方,表示的最大數值約等于2*1000*1000*1000,也就是20億的大小,所以,要實現一個一百億的計算器,我們得自己設計一個類可以用于表示很大的整數,并且提供了與另外一個整數進行加減乘除的功能,大概功能如下:
()這個類內部有兩個成員變量,一個表示符號,另一個用字節數組表示數值的二進制數
()有一個構造方法,把一個包含有多位數值的字符串轉換到內部的符號和字節數組中
()提供加減乘除的功能
public?class?BigInteger
{
int?sign;
byte[]?val;
public?Biginteger(String?val)
{
sign?=?;
val?=?;
}
public?BigInteger?add(BigInteger?other)
{
?
}
public?BigInteger?subtract(BigInteger?other)
{
?
}
public?BigInteger?multiply(BigInteger?other)
{
?
}
public?BigInteger?divide(BigInteger?other)
{
?
}
?
}
備注:要想寫出這個類的完整代碼,是非常復雜的,如果有興趣的話,可以參看jdk中自帶的java.math.BigInteger類的源碼。面試的人也知道誰都不可能在短時間內寫出這個類的完整代碼的,他要的是你是否有這方面的概念和意識,他最重要的還是考查你的能力,所以,你不要因為自己無法寫出完整的最終結果就放棄答這道題,你要做的就是你比別人寫得多,證明你比別人強,你有這方面的思想意識就可以了,畢竟別人可能連題目的意思都看不懂,什么都沒寫,你要敢于答這道題,即使只答了一部分,那也與那些什么都不懂的人區別出來,拉開了距離,算是矮子中的高個,機會當然就屬于你了。另外,答案中的框架代碼也很重要,體現了一些面向對象設計的功底,特別是其中的方法命名很專業,用的英文單詞很精準,這也是能力、經驗、專業性、英語水平等多個方面的體現,會給人留下很好的印象,在編程能力和其他方面條件差不多的情況下,英語好除了可以使你獲得更多機會外,薪水可以高出一千元。?
?
10、使用final關鍵字修飾一個變量時,是引用不能變,還是引用的對象不能變??
使用final關鍵字修飾一個變量時,是指引用變量不能變,引用變量所指向的對象中的內容還是可以改變的。例如,對于如下語句:
?final?StringBuffer?a=new?StringBuffer("immutable");
執行如下語句將報告編譯期錯誤:
a=new?StringBuffer("");
但是,執行如下語句則可以通過編譯:
a.append("?broken!");?
?
有人在定義方法的參數時,可能想采用如下形式來阻止方法內部修改傳進來的參數對象:
public?void?method(final??StringBuffer??param)
{
}?
實際上,這是辦不到的,在該方法內部仍然可以增加如下代碼來修改參數對象:
param.append("a");
11、"=="和equals方法究竟有什么區別?
(單獨把一個東西說清楚,然后再說清楚另一個,這樣,它們的區別自然就出來了,混在一起說,則很難說清楚)
==操作符專門用來比較兩個變量的值是否相等,也就是用于比較變量所對應的內存中所存儲的數值是否相同,要比較兩個基本類型的數據或兩個引用變量是否相等,只能用==操作符。
如果一個變量指向的數據是對象類型的,那么,這時候涉及了兩塊內存,對象本身占用一塊內存(堆內存),變量也占用一塊內存,例如Objet?obj?=?new?Object();變量obj是一個內存,new?Object()是另一個內存,此時,變量obj所對應的內存中存儲的數值就是對象占用的那塊內存的首地址。對于指向對象類型的變量,如果要比較兩個變量是否指向同一個對象,即要看這兩個變量所對應的內存中的數值是否相等,這時候就需要用==操作符進行比較。
equals方法是用于比較兩個獨立對象的內容是否相同,就好比去比較兩個人的長相是否相同,它比較的兩個對象是獨立的。例如,對于下面的代碼:
String?a=new?String("foo");
String?b=new?String("foo");
兩條new語句創建了兩個對象,然后用a,b這兩個變量分別指向了其中一個對象,這是兩個不同的對象,它們的首地址是不同的,即a和b中存儲的數值是不相同的,所以,表達式a==b將返回false,而這兩個對象中的內容是相同的,所以,表達式a.equals(b)將返回true。
在實際開發中,我們經常要比較傳遞進來的字符串內容是否等,例如,String?input?=?…;input.equals(“quit”),許多人稍不注意就使用==進行比較了,這是錯誤的,隨便從網上找幾個項目實戰的教學視頻看看,里面就有大量這樣的錯誤。記住,字符串的比較基本上都是使用equals方法。
如果一個類沒有自己定義equals方法,那么它將繼承Object類的equals方法,Object類的equals方法的實現代碼如下:
boolean?equals(Object?o){
return?this==o;
}
這說明,如果一個類沒有自己定義equals方法,它默認的equals方法(從Object?類繼承的)就是使用==操作符,也是在比較兩個變量指向的對象是否是同一對象,這時候使用equals和使用==會得到同樣的結果,如果比較的是兩個獨立的對象則總返回false。如果你編寫的類希望能夠比較該類創建的兩個實例對象的內容是否相同,那么你必須覆蓋equals方法,由你自己寫代碼來決定在什么情況即可認為兩個對象的內容是相同的。
12、靜態變量和實例變量的區別??
在語法定義上的區別:靜態變量前要加static關鍵字,而實例變量前則不加。
在程序運行時的區別:實例變量屬于某個對象的屬性,必須創建了實例對象,其中的實例變量才會被分配空間,才能使用這個實例變量。靜態變量不屬于某個實例對象,而是屬于類,所以也稱為類變量,只要程序加載了類的字節碼,不用創建任何實例對象,靜態變量就會被分配空間,靜態變量就可以被使用了。總之,實例變量必須創建對象后才可以通過這個對象來使用,靜態變量則可以直接使用類名來引用。
例如,對于下面的程序,無論創建多少個實例對象,永遠都只分配了一個staticVar變量,并且每創建一個實例對象,這個staticVar就會加1;但是,每創建一個實例對象,就會分配一個instanceVar,即可能分配多個instanceVar,并且每個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);
}
}
備注:這個解答除了說清楚兩者的區別外,最后還用一個具體的應用例子來說明兩者的差異,體現了自己有很好的解說問題和設計案例的能力,思維敏捷,超過一般程序員,有寫作能力!
13、是否可以從一個static方法內部發出對非static方法的調用??
不可以。因為非static方法是要與對象關聯在一起的,必須創建一個對象后,才可以在該對象上進行方法調用,而static方法調用時不需要創建對象,可以直接調用。也就是說,當一個static方法被調用時,可能還沒有創建任何實例對象,如果從一個static方法中發出對非static方法的調用,那個非static方法是關聯到哪個對象上的呢?這個邏輯無法成立,所以,一個static方法內部發出對非static方法的調用。
14、Integer與int的區別
int是java提供的8種原始數據類型之一。Java為每個原始類型提供了封裝類,Integer是java為int提供的封裝類。int的默認值為0,而Integer的默認值為null,即Integer可以區分出未賦值和值為0的區別,int則無法表達出未賦值的情況,例如,要想表達出沒有參加考試和考試成績為0的區別,則只能使用Integer。在JSP開發中,Integer的默認為null,所以用el表達式在文本框中顯示時,值為空白字符串,而int默認的默認值為0,所以用el表達式在文本框中顯示時,結果為0,所以,int不適合作為web層的表單數據的類型。
Integer提供了多個與整數相關的操作方法,例如,將一個字符串轉換成整數,Integer中還定義了表示整數的最大值和最小值的常量。
?
15、Math.round(11.5)等於多少??Math.round(-11.5)等於多少?
Math類中提供了三個與取整有關的方法:ceil、floor、round,這些方法的作用與它們的英文名稱的含義相對應,例如,ceil的英文意義是天花板,該方法就表示向上取整,Math.ceil(11.3)的結果為12,Math.ceil(-11.3)的結果是-11;floor的英文意義是地板,該方法就表示向下取整,Math.ceil(11.6)的結果為11,Math.ceil(-11.6)的結果是-12;最難掌握的是round方法,它表示“四舍五入”,算法為Math.floor(x+0.5),即將原來的數字加上0.5后再向下取整,所以,Math.round(11.5)的結果為12,Math.round(-11.5)的結果為-11。
16、作用域public,private,protected,以及不寫時的區別
這四個作用域的可見范圍如下表所示。
說明:如果在修飾的元素上面沒有寫任何訪問修飾符,則表示friendly。
?
作用域????當前類?同一package?子孫類?其他package?
public????√?????√??????????√???????√?
protected??√?????√??????????√??????×?
friendly???√?????√??????????×??????×?
private????√?????×??????????×??????×?
備注:只要記住了有4種訪問權限,4個訪問范圍,然后將全選和范圍在水平和垂直方向上分別按排從小到大或從大到小的順序排列,就很容易畫出上面的圖了。
17、Overload和Override的區別。Overloaded的方法是否可以改變返回值的類型??
Overload是重載的意思,Override是覆蓋的意思,也就是重寫。
重載Overload表示同一個類中可以有多個名稱相同的方法,但這些方法的參數列表各不相同(即參數個數或類型不同)。
重寫Override表示子類中的方法可以與父類中的某個方法的名稱和參數完全相同,通過子類創建的實例對象調用這個方法時,將調用子類中的定義方法,這相當于把父類中定義的那個完全相同的方法給覆蓋了,這也是面向對象編程的多態性的一種表現。子類覆蓋父類的方法時,只能比父類拋出更少的異常,或者是拋出父類拋出的異常的子異常,因為子類可以解決父類的一些問題,不能比父類有更多的問題。子類方法的訪問權限只能比父類的更大,不能更小。
至于Overloaded的方法是否可以改變返回值的類型這個問題,要看你倒底想問什么呢?這個題目很模糊。如果幾個Overloaded的方法的參數列表不一樣,它們的返回者類型當然也可以不一樣。但我估計你想問的問題是:如果兩個方法的參數列表完全一樣,是否可以讓它們的返回值不同來實現重載Override。這是不行的,我們可以用反證法來說明這個問題,因為我們有時候調用一個方法時也可以不定義返回結果變量,即不要關心其返回結果,例如,我們調用map.remove(key)方法時,雖然remove方法有返回值,但是我們通常都不會定義接收返回結果的變量,這時候假設該類中有兩個名稱和參數列表完全相同的方法,僅僅是返回類型不同,java就無法確定編程者倒底是想調用哪個方法了,因為它無法通過返回結果類型來判斷。?
?
18、構造器Constructor是否可被override??
構造器Constructor不能被繼承,因此不能重寫Override,但可以被重載Overload。?
19、接口是否可繼承接口??抽象類是否可實現(implements)接口??抽象類是否可繼承具體類(concrete?class)??抽象類中是否可以有靜態的main方法?
接口可以繼承接口。抽象類可以實現(implements)接口,抽象類是否可繼承實體類,但前提是實體類必須有明確的構造函數。抽象類中可以有靜態的main方法。
備注:只要明白了接口和抽象類的本質和作用,這些問題都很好回答,你想想,如果你是java語言的設計者,你是否會提供這樣的支持,如果不提供的話,有什么理由嗎?如果你沒有道理不提供,那答案就是肯定的了。
?
20、寫clone()方法時,通常都有一行代碼,是什么??
clone?有缺省行為,super.clone();因為首先要把父類中的成員復制到位,然后才是復制自己的成員。?
21、面向對象的特征有哪些方面
計算機軟件系統是現實生活中的業務在計算機中的映射,而現實生活中的業務其實就是一個個對象協作的過程。面向對象編程就是按現實業務一樣的方式將程序代碼按一個個對象進行組織和編寫,讓計算機系統能夠識別和理解用對象方式組織和編寫的程序代碼,這樣就可以把現實生活中的業務對象映射到計算機系統中。
面向對象的編程語言有封裝、繼承?、抽象、多態等4個主要的特征。
1封裝:
封裝是保證軟件部件具有優良的模塊性的基礎,封裝的目標就是要實現軟件部件的“高內聚、低耦合”,防止程序相互依賴性而帶來的變動影響。在面向對象的編程語言中,對象是封裝的最基本單位,面向對象的封裝比傳統語言的封裝更為清晰、更為有力。面向對象的封裝就是把描述一個對象的屬性和行為的代碼封裝在一個“模塊”中,也就是一個類中,屬性用變量定義,行為用方法進行定義,方法可以直接訪問同一個對象中的屬性。通常情況下,只要記住讓變量和訪問這個變量的方法放在一起,將一個類中的成員變量全部定義成私有的,只有這個類自己的方法才可以訪問到這些成員變量,這就基本上實現對象的封裝,就很容易找出要分配到這個類上的方法了,就基本上算是會面向對象的編程了。
例如,人要在黑板上畫圓,這一共涉及三個對象:人、黑板、圓,畫圓的方法要分配給哪個對象呢?由于畫圓需要使用到圓心和半徑,圓心和半徑顯然是圓的屬性,如果將它們在類中定義成了私有的成員變量,那么,畫圓的方法必須分配給圓,它才能訪問到圓心和半徑這兩個屬性,人以后只是調用圓的畫圓方法、表示給圓發給消息而已,畫圓這個方法不應該分配在人這個對象上,這就是面向對象的封裝性,即將對象封裝成一個高度自治和相對封閉的個體,對象狀態(屬性)由這個對象自己的行為(方法)來讀取和改變。一個更便于理解的例子就是,司機將火車剎住了,剎車的動作是分配給司機,還是分配給火車,顯然,應該分配給火車,因為司機自身是不可能有那么大的力氣將一個火車給停下來的,只有火車自己才能完成這一動作,火車需要調用內部的離合器和剎車片等多個器件協作才能完成剎車這個動作,司機剎車的過程只是給火車發了一個消息,通知火車要執行剎車動作而已。
?
抽象:
抽象就是找出一些事物的相似和共性之處,然后將這些事物歸為一個類,這個類只考慮這些事物的相似和共性之處,并且會忽略與當前主題和目標無關的那些方面,將注意力集中在與當前目標有關的方面。抽象包括行為抽象和狀態抽象兩個方面。例如,定義一個Person類,如下:
class?Person
{
String?name;
int?age;
}
人本來是很復雜的事物,有很多方面,但因為當前系統只需要了解人的姓名和年齡,所以上面定義的類中只包含姓名和年齡這兩個屬性,這就是一種抽像,使用抽象可以避免考慮一些與目標無關的細節。我對抽象的理解就是不要用顯微鏡去看一個事物的所有方面,這樣涉及的內容就太多了,而是要善于劃分問題的邊界,當前系統需要什么,就只考慮什么。
?
繼承:
在定義和實現一個類的時候,可以在一個已經存在的類的基礎之上來進行,把這個已經存在的類所定義的內容作為自己的內容,并可以加入若干新的內容,或修改原來的方法使之更適合特殊的需要,這就是繼承。繼承是子類自動共享父類數據和方法的機制,這是類之間的一種關系,提高了軟件的可重用性和可擴展性。
?
多態:
多態是指程序中定義的引用變量所指向的具體類型和通過該引用變量發出的方法調用在編程時并不確定,而是在程序運行期間才確定,即一個引用變量倒底會指向哪個類的實例對象,該引用變量發出的方法調用到底是哪個類中實現的方法,必須在由程序運行期間才能決定。因為在程序運行時才確定具體的類,這樣,不用修改源程序代碼,就可以讓引用變量綁定到各種不同的類實現上,從而導致該引用調用的具體方法隨之改變,即不修改程序代碼就可以改變程序運行時所綁定的具體代碼,讓程序可以選擇多個運行狀態,這就是多態性。多態性增強了軟件的靈活性和擴展性。例如,下面代碼中的UserDao是一個接口,它定義引用變量userDao指向的實例對象由daofactory.getDao()在執行的時候返回,有時候指向的是UserJdbcDao這個實現,有時候指向的是UserHibernateDao這個實現,這樣,不用修改源代碼,就可以改變userDao指向的具體類實現,從而導致userDao.insertUser()方法調用的具體代碼也隨之改變,即有時候調用的是UserJdbcDao的insertUser方法,有時候調用的是UserHibernateDao的insertUser方法:
UserDao?userDao?=?daofactory.getDao();??
userDao.insertUser(user);
?
比喻:人吃飯,你看到的是左手,還是右手?
22、java中實現多態的機制是什么??
靠的是父類或接口定義的引用變量可以指向子類或具體實現類的實例對象,而程序調用的方法就是引用所指向的具體實例對象的方法,也就是內存里正在運行的那個對象的方法,而不是引用變量的類型中定義的方法。?
23、abstract?class和interface有什么區別??
含有abstract修飾符的class即為抽象類,abstract?類不能創建的實例對象。含有abstract方法的類必須定義為abstract?class,abstract?class類中的方法不必是抽象的。abstract?class類中定義抽象方法必須在具體子類中實現,所以,不能有抽象構造方法或抽象靜態方法。如果的子類沒有實現抽象父類中的所有抽象方法,那么子類也必須定義為abstract類型。
接口(interface)可以說成是抽象類的一種特例,接口中的所有方法都必須是抽象的。接口?中的方法定義默認為public?abstract類型,接口中的成員變量類型默認為public?static?final。
下面比較一下兩者的語法區別:
1.抽象類可以有構造方法,接口中不能有構造方法。
2.抽象類中可以有普通成員變量,接口中沒有普通成員變量
3.抽象類中可以包含非抽象的普通方法,接口中的所有方法必須都是抽象的,不能有非抽象的普通方法。
4.?抽象類中的抽象方法的訪問類型可以是public,protected和默認類型,但接口中的抽象方法只能是public類型的,并且默認即為public?abstract類型。
5.?抽象類中可以包含靜態方法,接口中不能包含靜態方法
6.?抽象類和接口中都可以包含靜態成員變量,抽象類中的靜態成員變量的訪問類型可以任意,但接口中定義的變量只能是public?static類型,并且默認即為public?static類型。
7.?一個類可以實現多個接口,但只能繼承一個抽象類。
下面接著再說說兩者在應用上的區別:
接口更多的是在系統架構設計方法發揮作用,主要用于定義模塊之間的通信契約。而抽象類在代碼實現方面發揮作用,可以實現代碼的重用,例如,模板方法設計模式是抽象類的一個典型應用,假設某個項目的所有Servlet類都要用相同的方式進行權限判斷、記錄訪問日志和處理異常,那么就可以定義一個抽象的基類,讓所有的Servlet都繼承這個抽象基類,在抽象基類的service方法中完成權限判斷、記錄訪問日志和處理異常的代碼,在各個子類中只是完成各自的業務邏輯代碼,偽代碼如下:
public?abstract?class?BaseServlet?extends?HttpServlet
{
public?void?service(HttpServletRequest?request,?HttpServletResponse?response)?throws?IOExcetion,ServletException
{
記錄訪問日志
進行權限判斷
if(具有權限)
{
try
{
doService(request,response);
}
catch(Excetpion?e)
{
記錄異常信息
}
}
}?
protected?abstract?void?doService(HttpServletRequest?request,?HttpServletResponse?response)?throws?IOExcetion,ServletException;??
//注意訪問權限定義成protected,顯得既專業,又嚴謹,因為它是專門給子類用的
}
?
public?class?MyServlet1?extends?BaseServlet
{
protected?void?doService(HttpServletRequest?request,?HttpServletResponse?response)?throws?IOExcetion,ServletException
{
本Servlet只處理的具體業務邏輯代碼
}?
?
}
父類方法中間的某段代碼不確定,留給子類干,就用模板方法設計模式。
備注:這道題的思路是先從總體解釋抽象類和接口的基本概念,然后再比較兩者的語法細節,最后再說兩者的應用區別。比較兩者語法細節區別的條理是:先從一個類中的構造方法、普通成員變量和方法(包括抽象方法),靜態變量和方法,繼承性等6個方面逐一去比較回答,接著從第三者繼承的角度的回答,特別是最后用了一個典型的例子來展現自己深厚的技術功底。
24、abstract的method是否可同時是static,是否可同時是native,是否可同時是synchronized??
abstract的method?不可以是static的,因為抽象的方法是要被子類實現的,而static與子類扯不上關系!
native方法表示該方法要用另外一種依賴平臺的編程語言實現的,不存在著被子類實現的問題,所以,它也不能是抽象的,不能與abstract混用。例如,FileOutputSteam類要硬件打交道,底層的實現用的是操作系統相關的api實現,例如,在windows用c語言實現的,所以,查看jdk?的源代碼,可以發現FileOutputStream的open方法的定義如下:
private?native?void?open(String?name)?throws?FileNotFoundException;
如果我們要用java調用別人寫的c語言函數,我們是無法直接調用的,我們需要按照java的要求寫一個c語言的函數,又我們的這個c語言函數去調用別人的c語言函數。由于我們的c語言函數是按java的要求來寫的,我們這個c語言函數就可以與java對接上,java那邊的對接方式就是定義出與我們這個c函數相對應的方法,java中對應的方法不需要寫具體的代碼,但需要在前面聲明native。
關于synchronized與abstract合用的問題,我覺得也不行,因為在我幾年的學習和開發中,從來沒見到過這種情況,并且我覺得synchronized應該是作用在一個具體的方法上才有意義。?
25、什么是內部類?
內部類就是在一個類的內部定義的類,內部類中不能定義靜態成員(我想可能是既然靜態成員類似c語言的全局變量,而內部類通常是用于創建內部對象用的,所以,把“全局變量”放在內部類中就是毫無意義的事情,既然是毫無意義的事情,就應該被禁止),內部類可以直接訪問外部類中的成員變量,內部類可以定義在外部類的方法外面,也可以定義在外部類的方法體中,如下所示:
public?class?Outer
{
int?out_x??=?0;
public?void?method()
{
Inner1?inner1?=?new?Inner1();
class?Inner2???//在方法體內部定義的內部類
{
public?method()
{
out_x?=?3;
}
}
Inner2?inner2?=?new?Inner2();
}
?
public?class?Inner1???//在方法體外面定義的內部類
{
}
}
在方法體外面定義的內部類的訪問類型可以是public,protecte,默認的,private等4種類型,這就好像類中定義的成員變量有4種訪問類型一樣,它們決定這個內部類的定義對其他類是否可見;對于這種情況,我們也可以在外面創建內部類的實例對象,創建內部類的實例對象時,一定要先創建外部類的實例對象,然后用這個外部類的實例對象去創建內部類的實例對象,代碼如下:
Outer?outer?=?new?Outer();
Outer.Inner1?inner1?=?outer.new?Innner1();
?
在方法內部定義的內部類前面不能有訪問類型修飾符,就好像方法中定義的局部變量一樣,但這種內部類的前面可以使用final或abstract修飾符。這種內部類對其他類是不可見的其他類無法引用這種內部類,但是這種內部類創建的實例對象可以傳遞給其他類訪問。這種內部類必須是先定義,后使用,即內部類的定義代碼必須出現在使用該類之前,這與方法中的局部變量必須先定義后使用的道理也是一樣的。這種內部類可以訪問方法體中的局部變量,但是,該局部變量前必須加final修飾符。
對于這些細節,只要在eclipse寫代碼試試,根據開發工具提示的各類錯誤信息就可以馬上了解到。
在方法外部定義的內部類前面可以加上static關鍵字,從而成為靜態內部類,或者叫Static?Nested?Class。Static?Nested?Class與普通類在運行時的行為和功能上沒有什么區別,只是在編程引用時的語法上有一些差別,它可以定義成public、protected、默認的、private等多種類型,而普通類只能定義成public和默認的這兩種類型。在外面引用Static?Nested?Class類的名稱為“外部類名.內部類名”。在外面不需要創建外部類的實例對象,就可以直接創建Static?Nested?Class,例如,假設Inner是定義在Outer類中的Static?Nested?Class,那么可以使用如下語句創建Inner類:
Outer.Inner?inner?=?new?Outer.Inner();
由于static?Nested?Class不依賴于外部類的實例對象,所以,static?Nested?Class能訪問外部類的非static成員變量。當在外部類中訪問Static?Nested?Class時,可以直接使用Static?Nested?Class的名字,而不需要加上外部類的名字了,在Static?Nested?Class中也可以直接引用外部類的static的成員變量,不需要加上外部類的名字。
?
最后,在方法體內部還可以采用如下語法來創建一種匿名內部類,即定義某一接口或類的子類的同時,還創建了該子類的實例對象,無需為該子類定義名稱:
public?class?Outer
{
public?void?start()
{
new?Thread(
new?Runable(){
public?void?run(){};
}
).start();
}
}
?
備注:首先根據你的印象說出你對內部類的總體方面的特點:例如,在兩個地方可以定義,可以訪問外部類的成員變量,不能定義靜態成員,這是大的特點。然后再說一些細節方面的知識,例如,幾種定義方式的語法區別,靜態內部類,以及匿名內部類。
26、內部類可以引用他包含類的成員嗎?有沒有什么限制??
完全可以。如果不是靜態內部類,那沒有什么限制!?
如果你把靜態嵌套類當作內部類的一種特例,那在這種情況下不可以訪問外部類的普通成員變量,而只能訪問外部類中的靜態成員,例如,下面的代碼:
class?Outer
{
static?int?x;
static?class?Inner
{
void?test()
{
syso(x);
}
}
}
如果問靜態內部類能否訪問外部類的成員這個問題,該如何回答:
答題時,也要能察言觀色,揣摩提問者的心思,顯然人家希望你說的是靜態內部類不能訪問外部類的成員,但你一上來就頂牛,這不好,要先順著人家,讓人家滿意,然后再說特殊情況,讓人家吃驚。
?
27、Static?Nested?Class?和?Inner?Class的不同。?
參見前面的什么是內部類的那道題
?
28、Anonymous?Inner?Class?(匿名內部類)?是否可以extends(繼承)其它類,是否可以implements(實現)interface(接口)??
可以繼承其他類或實現其他接口。
?
29、String是最基本的數據類型嗎??
基本數據類型包括byte、int、char、long、float、double、boolean和short。?
java.lang.String類是final類型的,因此不可以繼承這個類、不能修改這個類。為了提高效率節省空間,我們應該用StringBuffer類?
?
30、String?s?=?"Hello";s?=?s?+?"?world!";這兩行代碼執行后,原始的String對象中的內容到底變了沒有?
沒有。因為String被設計成不可變(immutable)類,所以它的所有對象都是不可變對象。在這段代碼中,s原先指向一個String對象,內容是?"Hello",然后我們對s進行了+操作,那么s所指向的那個對象是否發生了改變呢?答案是沒有。這時,s不指向原來那個對象了,而指向了另一個?String對象,內容為"Hello?world!",原來那個對象還存在于內存之中,只是s這個引用變量不再指向它了。
通過上面的說明,我們很容易導出另一個結論,如果經常對字符串進行各種各樣的修改,或者說,不可預見的修改,那么使用String來代表字符串的話會引起很大的內存開銷。因為?String對象建立之后不能再改變,所以對于每一個不同的字符串,都需要一個String對象來表示。這時,應該考慮使用StringBuffer類,它允許修改,而不是每個不同的字符串都要生成一個新的對象。并且,這兩種類的對象轉換十分容易。
同時,我們還可以知道,如果要使用內容相同的字符串,不必每次都new一個String。例如我們要在構造器中對一個名叫s的String引用變量進行初始化,把它設置為初始值,應當這樣做:
public?class?Demo?{
private?String?s;
...
public?Demo?{
s?=?"Initial?Value";
}
...
}
而非
s?=?new?String("Initial?Value");
后者每次都會調用構造器,生成新對象,性能低下且內存開銷大,并且沒有意義,因為String對象不可改變,所以對于內容相同的字符串,只要一個String對象來表示就可以了。也就說,多次調用上面的構造器創建多個對象,他們的String類型屬性s都指向同一個對象。
上面的結論還基于這樣一個事實:對于字符串常量,如果內容相同,Java認為它們代表同一個String對象。而用關鍵字new調用構造器,總是會創建一個新的對象,無論內容是否相同。
至于為什么要把String類設計成不可變類,是它的用途決定的。其實不只String,很多Java標準類庫中的類都是不可變的。在開發一個系統的時候,我們有時候也需要設計不可變類,來傳遞一組相關的值,這也是面向對象思想的體現。不可變類有一些優點,比如因為它的對象是只讀的,所以多線程并發訪問也不會有任何問題。當然也有一些缺點,比如每個不同的狀態都要一個對象來代表,可能會造成性能上的問題。所以Java標準類庫還提供了一個可變版本,即?StringBuffer。
31、是否可以繼承String類??
String類是final類故不可以繼承。?
?
32、String?s?=?new?String("xyz");創建了幾個String?Object??二者之間有什么區別?
兩個,一個放在常量區,不管寫多少遍,都是同一個。New?String每寫一遍,就創建一個新。
33、String?和StringBuffer的區別
JAVA平臺提供了兩個類:String和StringBuffer,它們可以儲存和操作字符串,即包含多個字符的字符數據。這個String類提供了數值不可改變的字符串。而這個StringBuffer類提供的字符串進行修改。當你知道字符數據要改變的時候你就可以使用StringBuffer。典型地,你可以使用StringBuffers來動態構造字符數據。另外,String實現了equals方法,new?String(“abc”).equals(new?String(“abc”)的結果為true,而StringBuffer沒有實現equals方法,所以,new?StringBuffer(“abc”).equals(new?StringBuffer(“abc”)的結果為false。
?
接著要舉一個具體的例子來說明,我們要把1到100的所有數字拼起來,組成一個串。
StringBuffer?sbf?=?new?StringBuffer();??
for(int?i=0;i<100;i++)
{
sbf.append(i);
}
上面的代碼效率很高,因為只創建了一個StringBuffer對象,而下面的代碼效率很低,因為創建了101個對象。
String?str?=?new?String();??
for(int?i=0;i<100;i++)
{
str?=?str?+?i;
}
34、如何把一段逗號分割的字符串轉換成一個數組?
如果不查jdk?api,我很難寫出來!我可以說說我的思路:
1.?用正則表達式,代碼大概為: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();}
?
35、數組有沒有length()這個方法??String有沒有length()這個方法??
數組沒有length()這個方法,有length的屬性。String有有length()這個方法。
?
36、try?{}里有一個return語句,那么緊跟在這個try后的finally?{}里的code會不會被執行,什么時候被執行,在return前還是后??
會執行,在return前執行。?
?
我的答案是在return中間執行,參看下一題的講解。
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());;
}
?
static?int?test()
{
int?x?=?1;
try
{
return?x;
}
finally
{
++x;
}
}
?
}
?
---------執行結果?---------
1
37、下面的程序代碼輸出的結果是多少?
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?;
}
}
}
?
返回的結果是2。
我可以通過下面一個例子程序來幫助我解釋這個答案,從下面例子的運行結果中可以發現,try中的return語句調用的函數先于finally中調用的函數執行,也就是說return語句先執行,finally語句后執行,所以,返回的結果是2。Return并不是讓函數馬上返回,而是return語句執行后,將把返回結果放置進函數棧中,此時函數并不是馬上返回,它要執行finally語句后才真正開始返回。
在講解答案時可以用下面的程序來幫助分析:
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;
}
}
-----------執行結果-----------------
?
func1
func2
2
?
結論:finally中的代碼比return?和break語句后執行
?
38、final,?finally,?finalize的區別。?
final?用于聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。?
內部類要訪問局部變量,局部變量必須定義成final類型,例如,一段代碼……
?
finally是異常處理語句結構的一部分,表示總是執行。
?
?
finalize是Object類的一個方法,在垃圾收集器執行的時候會調用被回收對象的此方法,可以覆蓋此方法提供垃圾收集時的其他資源回收,例如關閉文件等。JVM不保證此方法總被調用
?
39、運行時異常與一般異常有何異同??
異常表示程序運行過程中可能出現的非正常狀態,運行時異常表示虛擬機的通常操作中可能遇到的異常,是一種常見運行錯誤。java編譯器要求方法必須聲明拋出可能發生的非運行時異常,但是并不要求必須聲明拋出未被捕獲的運行時異常。
40、error和exception有什么區別??
error?表示恢復不是不可能但很困難的情況下的一種嚴重問題。比如說內存溢出。不可能指望程序能處理這樣的情況。?exception?表示一種設計或實現問題。也就是說,它表示如果程序運行正常,從不會發生的情況。?
?
41、Java中的異常處理機制的簡單原理和應用。?
當JAVA程序違反了JAVA的語義規則時,JAVA虛擬機就會將發生的錯誤表示為一個異常。違反語義規則包括2種情況。一種是JAVA類庫內置的語義檢查。例如數組下標越界,會引發IndexOutOfBoundsException;訪問null的對象時會引發NullPointerException。另一種情況就是JAVA允許程序員擴展這種語義檢查,程序員可以創建自己的異常,并自由選擇在何時用throw關鍵字引發異常。所有的異常都是java.lang.Thowable的子類。?
?
?
42、給我一個你最常見到的runtime?exception。?
ArithmeticException,?ArrayStoreException,?BufferOverflowException,?BufferUnderflowException,?CannotRedoException,?CannotUndoException,?ClassCastException,?CMMException,?ConcurrentModificationException,?DOMException,?EmptyStackException,?IllegalArgumentException,?IllegalMonitorStateException,?IllegalPathStateException,?IllegalStateException,?ImagingOpException,?IndexOutOfBoundsException,?MissingResourceException,?NegativeArraySizeException,?NoSuchElementException,?NullPointerException,?ProfileDataException,?ProviderException,?RasterFORMatException,?SecurityException,?SystemException,?UndeclaredThrowableException,?UnmodifiableSetException,?UnsupportedOperationException?
43、JAVA語言如何進行異常處理,關鍵字:throws,throw,try,catch,finally分別代表什么意義?在try塊中可以拋出異常嗎??
Java通過面向對象的方法進行異常處理,把各種不同的異常進行分類,并提供了良好的接口。在Java中,每個異常都是一個對象,它是Throwable類或其它子類的實例。當一個方法出現異常后便拋出一個異常對象,該對象中包含有異常信息,調用這個對象的方法可以捕獲到這個異常并進行處理。Java的異常處理是通過5個關鍵詞來實現的:try、catch、throw、throws和finally。一般情況下是用try來執行一段程序,如果出現異常,系統會拋出(throws)一個異常,這時候你可以通過它的類型來捕捉(catch)它,或最后(finally)由缺省處理器來處理。?
用try來指定一塊預防所有"異常"的程序。緊跟在try程序后面,應包含一個catch子句來指定你想要捕捉的"異常"的類型。?
throw語句用來明確地拋出一個"異常"。?
throws用來標明一個成員函數可能拋出的各種"異常"。?
Finally為確保一段代碼不管發生什么"異常"都被執行一段代碼。?
可以在一個成員函數調用的外面寫一個try語句,在這個成員函數內部寫另一個try語句保護其他代碼。每當遇到一個try語句,"異常"的框架就放到堆棧上面,直到所有的try語句都完成。如果下一級的try語句沒有對某種"異常"進行處理,堆棧就會展開,直到遇到有處理這種"異常"的try語句。
?
44、java中有幾種方法可以實現一個線程?用什么關鍵字修飾同步方法??stop()和suspend()方法為何不推薦使用??
有兩種實現方法,分別使用new?Thread()和new?Thread(runnable)形式,第一種直接調用thread的run方法,所以,我們往往使用Thread子類,即new?SubThread()。第二種調用runnable的run方法。
?
有兩種實現方法,分別是繼承Thread類與實現Runnable接口?
用synchronized關鍵字修飾同步方法?
反對使用stop(),是因為它不安全。它會解除由線程獲取的所有鎖定,而且如果對象處于一種不連貫狀態,那么其他線程能在那種狀態下檢查和修改它們。結果很難檢查出真正的問題所在。suspend()方法容易發生死鎖。調用suspend()的時候,目標線程會停下來,但卻仍然持有在這之前獲得的鎖定。此時,其他任何線程都不能訪問鎖定的資源,除非被"掛起"的線程恢復運行。對任何線程來說,如果它們想恢復目標線程,同時又試圖使用任何一個鎖定的資源,就會造成死鎖。所以不應該使用suspend(),而應在自己的Thread類中置入一個標志,指出線程應該活動還是掛起。若標志指出線程應該掛起,便用wait()命其進入等待狀態。若標志指出線程應當恢復,則用一個notify()重新啟動線程。?
45、sleep()?和?wait()?有什么區別??
?????(網上的答案:sleep是線程類(Thread)的方法,導致此線程暫停執行指定時間,給執行機會給其他線程,但是監控狀態依然保持,到時后會自動恢復。調用sleep不會釋放對象鎖。?wait是Object類的方法,對此對象調用wait方法導致本線程放棄對象鎖,進入等待此對象的等待鎖定池,只有針對此對象發出notify方法(或notifyAll)后本線程才進入對象鎖定池準備獲得對象鎖進入運行狀態。)?
?
sleep就是正在執行的線程主動讓出cpu,cpu去執行其他線程,在sleep指定的時間過后,cpu才會回到這個線程上繼續往下執行,如果當前線程進入了同步鎖,sleep方法并不會釋放鎖,即使當前線程使用sleep方法讓出了cpu,但其他被同步鎖擋住了的線程也無法得到執行。wait是指在一個已經進入了同步鎖的線程內,讓自己暫時讓出同步鎖,以便其他正在等待此鎖的線程可以得到同步鎖并運行,只有其他線程調用了notify方法(notify并不釋放鎖,只是告訴調用過wait方法的線程可以去參與獲得鎖的競爭了,但不是馬上得到鎖,因為鎖還在別人手里,別人還沒釋放。如果notify方法后面的代碼還有很多,需要這些代碼執行完后才會釋放鎖,可以在notfiy方法后增加一個等待和一些代碼,看看效果),調用wait方法的線程就會解除wait狀態和程序可以再次得到鎖后繼續向下運行。對于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內部run方法要用同一對象作為監視器,我們這里不能用this,因為在Thread2里面的this和這個Thread1的this不是同一個對象。我們用MultiThread.class這個字節碼對象,當前虛擬機里引用這個變量時,指向的都是同一個對象。
synchronized?(MultiThread.class)?{
?
System.out.println("enter?thread1...");
?
System.out.println("thread1?is?waiting");
try?{
//釋放鎖有兩種方式,第一種方式是程序自然離開監視器的范圍,也就是離開了synchronized關鍵字管轄的代碼范圍,另一種方式就是在synchronized關鍵字管轄的代碼內部調用監視器對象的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調用下面的sleep方法休息了10毫秒,但thread1仍然不會執行,因為thread2沒有釋放鎖,所以Thread1無法得不到鎖。
?
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!");
?
}
}
?
}
?
}
?
?
46、同步和異步有何異同,在什么情況下分別使用他們?舉例說明。?
如果數據將在線程間共享。例如正在寫的數據以后可能被另一個線程讀到,或者正在讀的數據可能已經被另一個線程寫過了,那么這些數據就是共享數據,必須進行同步存取。?
當應用程序在對象上調用了一個需要花費很長時間來執行的方法,并且不希望讓程序等待方法的返回時,就應該使用異步編程,在很多情況下采用異步途徑往往更有效率。?
?
47.?下面兩個方法同步嗎?(自己發明)
class?Test
{
synchronized?static?void?sayHello3()
{
?
}
?
synchronized?void?getX(){}
}
48、多線程有幾種實現方法?同步有幾種實現方法??
多線程有兩種實現方法,分別是繼承Thread類與實現Runnable接口?
同步的實現方面有兩種,分別是synchronized,wait與notify?
wait():使一個線程處于等待狀態,并且釋放所持有的對象的lock。?
sleep():使一個正在運行的線程處于睡眠狀態,是一個靜態方法,調用此方法要捕捉InterruptedException異常。?
notify():喚醒一個處于等待狀態的線程,注意的是在調用此方法的時候,并不能確切的喚醒某一個等待狀態的線程,而是由JVM確定喚醒哪個線程,而且不是按優先級。?
Allnotity():喚醒所有處入等待狀態的線程,注意并不是給所有喚醒線程一個對象的鎖,而是讓它們競爭。
?
?
49、啟動一個線程是用run()還是start()??.?
啟動一個線程是調用start()方法,使線程就緒狀態,以后可以被調度為運行狀態,一個線程必須關聯一些具體的執行代碼,run()方法是該線程所關聯的執行代碼。?
?
47、當一個線程進入一個對象的一個synchronized方法后,其它線程是否可進入此對象的其它方法??
分幾種情況:
?????1.其他方法前是否加了synchronized關鍵字,如果沒加,則能。
??????2.如果這個方法內部調用了wait,則可以進入其他synchronized方法。
????3.如果其他個方法都加了synchronized關鍵字,并且內部沒有調用wait,則不能。
?
50、線程的基本概念、線程的基本狀態以及狀態之間的關系?
?
一個程序中可以有多條執行線索同時執行,一個線程就是程序中的一條執行線索,每個線程上都關聯有要執行的代碼,即可以有多段程序代碼同時運行,每個程序至少都有一個線程,即main方法執行的那個線程。如果只是一個cpu,它怎么能夠同時執行多段程序呢?這是從宏觀上來看的,cpu一會執行a線索,一會執行b線索,切換時間很快,給人的感覺是a,b在同時執行,好比大家在同一個辦公室上網,只有一條鏈接到外部網線,其實,這條網線一會為a傳數據,一會為b傳數據,由于切換時間很短暫,所以,大家感覺都在同時上網。?
?
??狀態:就緒,運行,synchronize阻塞,wait和sleep掛起,結束。wait必須在synchronized內部調用。
??調用線程的start方法后線程進入就緒狀態,線程調度系統將就緒狀態的線程轉為運行狀態,遇到synchronized語句時,由運行狀態轉為阻塞,當synchronized獲得鎖后,由阻塞轉為運行,在這種情況可以調用wait方法轉為掛起狀態,當線程關聯的代碼執行完后,線程變為結束狀態。?
?
51、簡述synchronized和java.util.concurrent.locks.Lock的異同???
主要相同點:Lock能完成synchronized所實現的所有功能?
主要不同點:Lock有比synchronized更精確的線程語義和更好的性能。synchronized會自動釋放鎖,而Lock一定要求程序員手工釋放,并且必須在finally從句中釋放。Lock還有更強大的功能,例如,它的tryLock方法可以非阻塞方式去拿鎖。?
舉例說明(對下面的題用lock進行了改寫):
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();
}
}
}
?
}
}
52、設計4個線程,其中兩個線程每次對j增加1,另外兩個線程對j每次減少1。寫出程序。?
以下程序使用內部類實現線程,對j增減的時候沒有考慮順序問題。?
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();?
???????}?
???}?
}?
}?
?
?
53、ArrayList和Vector的區別
答:
這兩個類都實現了List接口(List接口繼承了Collection接口),他們都是有序集合,即存儲在這兩個集合中的元素的位置都是有順序的,相當于一種動態的數組,我們以后可以按位置索引號取出某個元素,,并且其中的數據是允許重復的,這是HashSet之類的集合的最大不同處,HashSet之類的集合不可以按索引號去檢索其中的元素,也不允許有重復的元素(本來題目問的與hashset沒有任何關系,但為了說清楚ArrayList與Vector的功能,我們使用對比方式,更有利于說明問題)。
?
接著才說ArrayList與Vector的區別,這主要包括兩個方面:.?
(1)同步性:
Vector是線程安全的,也就是說是它的方法之間是線程同步的,而ArrayList是線程序不安全的,它的方法之間是線程不同步的。如果只有一個線程會訪問到集合,那最好是使用ArrayList,因為它不考慮線程安全,效率會高些;如果有多個線程會訪問到集合,那最好是使用Vector,因為不需要我們自己再去考慮和編寫線程安全的代碼。
(2)數據增長:
ArrayList與Vector都有一個初始的容量大小,當存儲進它們里面的元素的個數超過了容量時,就需要增加ArrayList與Vector的存儲空間,每次要增加存儲空間時,不是只增加一個存儲單元,而是增加多個存儲單元,每次增加的存儲單元的個數在內存空間利用與程序效率之間要取得一定的平衡。Vector默認增長為原來兩倍,而ArrayList的增長策略在文檔中沒有明確規定(從源代碼看到的是增長為原來的1.5倍)。ArrayList與Vector都可以設置初始的空間大小,Vector還可以設置增長的空間大小,而ArrayList沒有提供設置增長空間的方法。
54、HashMap和Hashtable的區別
(條理上還需要整理,也是先說相同點,再說不同點)
HashMap是Hashtable的輕量級實現(非線程安全的實現),他們都完成了Map接口,主要區別在于HashMap允許空(null)鍵值(key),由于非線程安全,在只有一個線程訪問的情況下,效率要高于Hashtable。?
HashMap允許將null作為一個entry的key或者value,而Hashtable不允許。?
HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因為contains方法容易讓人引起誤解。?
Hashtable繼承自Dictionary類,而HashMap是Java1.2引進的Map?interface的一個實現。?
最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多個線程訪問Hashtable時,不需要自己為它的方法實現同步,而HashMap?就必須為之提供外同步。?
Hashtable和HashMap采用的hash/rehash算法都大概一樣,所以性能不會有很大的差異。
?
就HashMap與HashTable主要從三方面來說。?
一.歷史原因:Hashtable是基于陳舊的Dictionary類的,HashMap是Java?1.2引進的Map接口的一個實現?
二.同步性:Hashtable是線程安全的,也就是說是同步的,而HashMap是線程序不安全的,不是同步的?
三.值:只有HashMap可以讓你將空值作為一個表的條目的key或value?
55、List?和?Map?區別?
一個是存儲單列數據的集合,另一個是存儲鍵和值這樣的雙列數據的集合,List中存儲的數據是有順序,并且允許重復;Map中存儲的數據是沒有順序的,其鍵是不能重復的,它的值是可以有重復的。
56、List,?Set,?Map是否繼承自Collection接口??
???List,Set是,Map不是?
?
57、List、Map、Set三個接口,存取元素時,各有什么特點??
List?以特定次序來持有元素,可有重復元素。Set?無法擁有重復元素,內部排序。Map?保存key-value值,value可多值。
?
?
HashSet按照hashcode值的某種運算方式進行存儲,而不是直接按hashCode值的大小進行存儲。例如,"abc"?--->?78,"def"?--->?62,"xyz"?--->?65在hashSet中的存儲順序不是62,65,78,這些問題感謝以前一個叫崔健的學員提出,最后通過查看源代碼給他解釋清楚,看本次培訓學員當中有多少能看懂源碼。LinkedHashSet按插入的順序存儲,那被存儲對象的hashcode方法還有什么作用呢?學員想想!hashset集合比較兩個對象是否相等,首先看hashcode方法是否相等,然后看equals方法是否相等。new?兩個Student插入到HashSet中,看HashSet的size,實現hashcode和equals方法后再看size。
?
同一個對象可以在Vector中加入多次。往集合里面加元素,相當于集合里用一根繩子連接到了目標對象。往HashSet中卻加不了多次的。?
?
58、說出ArrayList,Vector,?LinkedList的存儲性能和特性?
ArrayList和Vector都是使用數組方式存儲數據,此數組元素數大于實際存儲的數據以便增加和插入元素,它們都允許直接按序號索引元素,但是插入元素要涉及數組元素移動等內存操作,所以索引數據快而插入數據慢,Vector由于使用了synchronized方法(線程安全),通常性能上較ArrayList差,而LinkedList使用雙向鏈表實現存儲,按序號索引數據需要進行前向或后向遍歷,但是插入數據時只需要記錄本項的前后項即可,所以插入速度較快。
?
LinkedList也是線程不安全的,LinkedList提供了一些方法,使得LinkedList可以被當作堆棧和隊列來使用。
59、去掉一個Vector集合中重復的元素?
Vector?newVector?=?new?Vector();
For?(int?i=0;i<vector.size();i++)
{
Object?obj?=?vector.get(i);
if(!newVector.contains(obj);
newVector.add(obj);
}
還有一種簡單的方式,HashSet?set?=?new?HashSet(vector);?
60、Collection?和?Collections的區別。?
Collection是集合類的上級接口,繼承與他的接口主要有Set?和List.?
Collections是針對集合類的一個幫助類,他提供一系列靜態方法實現對各種集合的搜索、排序、線程安全化等操作。?
61、Set里的元素是不能重復的,那么用什么方法來區分重復與否呢??是用==還是equals()??它們有何區別??
Set里的元素是不能重復的,元素重復與否是使用equals()方法進行判斷的。?
???equals()和==方法決定引用值是否指向同一對象equals()在類中被覆蓋,為的是當兩個分離的對象的內容和類型相配的話,返回真值。
?
62、你所知道的集合類都有哪些?主要方法??
最常用的集合類是?List?和?Map。?List?的具體實現包括?ArrayList?和?Vector,它們是可變大小的列表,比較適合構建、存儲和操作任何類型對象的元素列表。?List?適用于按數值索引訪問元素的情形。?
Map?提供了一個更通用的元素存儲方法。?Map?集合類用于存儲元素對(稱作"鍵"和"值"),其中每個鍵映射到一個值。?
?
ArrayList/VectoràList
????????????????????àCollection
HashSet/TreeSetàSet
?
PropetiesàHashTable
àMap
Treemap/HashMap
?
我記的不是方法名,而是思想,我知道它們都有增刪改查的方法,但這些方法的具體名稱,我記得不是很清楚,對于set,大概的方法是add,remove,?contains;對于map,大概的方法就是put,remove,contains等,因為,我只要在eclispe下按點操作符,很自然的這些方法就出來了。我記住的一些思想就是List類會有get(int?index)這樣的方法,因為它可以按順序取元素,而set類中沒有get(int?index)這樣的方法。List和set都可以迭代出所有元素,迭代時先要得到一個iterator對象,所以,set和list類都有一個iterator方法,用于返回那個iterator對象。map可以返回三個集合,一個是返回所有的key的集合,另外一個返回的是所有value的集合,再一個返回的key和value組合成的EntrySet對象的集合,map也有get方法,參數是key,返回值是key對應的value。?
?
63、兩個對象值相同(x.equals(y)?==?true),但卻可有不同的hash?code,這句話對不對??
對。
如果對象要保存在HashSet或HashMap中,它們的equals相等,那么,它們的hashcode值就必須相等。
如果不是要保存在HashSet或HashMap,則與hashcode沒有什么關系了,這時候hashcode不等是可以的,例如arrayList存儲的對象就不用實現hashcode,當然,我們沒有理由不實現,通常都會去實現的。
?
64、java中有幾種類型的流?JDK為每種類型的流提供了一些抽象類以供繼承,請說出他們分別是哪些類??
字節流,字符流。字節流繼承于InputStream?OutputStream,字符流繼承于InputStreamReader?OutputStreamWriter。在java.io包中還有許多其他的流,主要是為了提高性能和使用方便。?
?
65、什么是java序列化,如何實現java序列化??
?
我們有時候將一個java對象變成字節流的形式傳出去或者從一個字節流中恢復成一個java對象,例如,要將java對象存儲到硬盤或者傳送給網絡上的其他計算機,這個過程我們可以自己寫代碼去把一個java對象變成某個格式的字節流再傳輸,但是,jre本身就提供了這種支持,我們可以調用OutputStream的writeObject方法來做,如果要讓java?幫我們做,要被傳輸的對象必須實現serializable接口,這樣,javac編譯時就會進行特殊處理,編譯的類才可以被writeObject方法操作,這就是所謂的序列化。需要被序列化的類必須實現Serializable接口,該接口是一個mini接口,其中沒有需要實現的方法,implements?Serializable只是為了標注該對象是可被序列化的。?
?
?
例如,在web開發中,如果對象被保存在了Session中,tomcat在重啟時要把Session對象序列化到硬盤,這個對象就必須實現Serializable接口。如果對象要經過分布式系統進行網絡傳輸或通過rmi等遠程調用,這就需要在網絡上傳輸對象,被傳輸的對象就必須實現Serializable接口。
?
66、描述一下JVM加載class文件的原理機制??
JVM中類的裝載是由ClassLoader和它的子類來實現的,Java?ClassLoader?是一個重要的Java運行時系統組件。它負責在運行時查找和裝入類文件的類。?
?
67、heap和stack有什么區別。?
java的內存分為兩類,一類是棧內存,一類是堆內存。棧內存是指程序進入一個方法時,會為這個方法單獨分配一塊私屬存儲空間,用于存儲這個方法內部的局部變量,當這個方法結束時,分配給這個方法的棧會釋放,這個棧中的變量也將隨之釋放。
堆是與棧作用不同的內存,一般用于存放不放在當前方法棧中的那些數據,例如,使用new創建的對象都放在堆里,所以,它不會隨方法的結束而消失。方法中的局部變量使用final修飾后,放在堆中,而不是棧中。?
?
68、GC是什么??為什么要有GC?? ?
GC是垃圾收集的意思(Gabage?Collection),內存處理是編程人員容易出現問題的地方,忘記或者錯誤的內存回收會導致程序或系統的不穩定甚至崩潰,Java提供的GC功能可以自動監測對象是否超過作用域從而達到自動回收內存的目的,Java語言沒有提供釋放已分配內存的顯示操作方法。
?
69、垃圾回收的優點和原理。并考慮2種回收機制。?
Java語言中一個顯著的特點就是引入了垃圾回收機制,使c++程序員最頭疼的內存管理的問題迎刃而解,它使得Java程序員在編寫程序的時候不再需要考慮內存管理。由于有個垃圾回收機制,Java中的對象不再有"作用域"的概念,只有對象的引用才有"作用域"。垃圾回收可以有效的防止內存泄露,有效的使用可以使用的內存。垃圾回收器通常是作為一個單獨的低級別的線程運行,不可預知的情況下對內存堆中已經死亡的或者長時間沒有使用的對象進行清楚和回收,程序員不能實時的調用垃圾回收器對某個對象或所有對象進行垃圾回收。回收機制有分代復制垃圾回收和標記垃圾回收,增量垃圾回收。
?
70、垃圾回收器的基本原理是什么?垃圾回收器可以馬上回收內存嗎?有什么辦法主動通知虛擬機進行垃圾回收??
對于GC來說,當程序員創建對象時,GC就開始監控這個對象的地址、大小以及使用情況。通常,GC采用有向圖的方式記錄和管理堆(heap)中的所有對象。通過這種方式確定哪些對象是"可達的",哪些對象是"不可達的"。當GC確定一些對象為"不可達"時,GC就有責任回收這些內存空間。可以。程序員可以手動執行System.gc(),通知GC運行,但是Java語言規范并不保證GC一定會執行。?
?
?
71、什么時候用assert。?
assertion(斷言)在軟件開發中是一種常用的調試方式,很多開發語言中都支持這種機制。在實現中,assertion就是在程序中的一條語句,它對一個boolean表達式進行檢查,一個正確程序必須保證這個boolean表達式的值為true;如果該值為false,說明程序已經處于不正確的狀態下,assert將給出警告或退出。一般來說,assertion用于保證程序最基本、關鍵的正確性。assertion檢查通常在開發和測試時開啟。為了提高性能,在軟件發布后,assertion檢查通常是關閉的。?
package?com.huawei.interview;
?
public?class?AssertTest?{
?
/**
?*?@param?args
?*/
public?static?void?main(String[]?args)?{
//?TODO?Auto-generated?method?stub
int?i?=?0;
for(i=0;i<5;i++)
{
System.out.println(i);
}
//假設程序不小心多了一句--i;
--i;
assert?i==5;
}
?
}
?
72、java中會存在內存泄漏嗎,請簡單描述。?
所謂內存泄露就是指一個不再被程序使用的對象或變量一直被占據在內存中。java中有垃圾回收機制,它可以保證一對象不再被引用的時候,即對象編程了孤兒的時候,對象將自動被垃圾回收器從內存中清除掉。由于Java?使用有向圖的方式進行垃圾回收管理,可以消除引用循環的問題,例如有兩個對象,相互引用,只要它們和根進程不可達的,那么GC也是可以回收它們的,例如下面的代碼可以看到這種情況的內存回收:
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中的內存泄露的情況:長生命周期的對象持有短生命周期對象的引用就很可能發生內存泄露,盡管短生命周期對象已經不再需要,但是因為長生命周期對象持有它的引用而導致不能被回收,這就是java中內存泄露的發生場景,通俗地說,就是程序員可能創建了一個對象,以后一直不再使用這個對象,這個對象卻一直被引用,即這個對象無用但是卻無法被垃圾回收器回收的,這就是java中可能出現內存泄露的情況,例如,緩存系統,我們加載了一個對象放在緩存中(例如放在一個全局map對象中),然后一直不再使用它,這個對象一直被緩存引用,但卻不再被使用。
檢查java中的內存泄露,一定要讓程序將各種分支情況都完整執行到程序結束,然后看某個對象是否被使用過,如果沒有,則才能判定這個對象屬于內存泄露。
?
下面內容來自于網上(主要特點就是清空堆棧中的某個元素,并不是徹底把它從數組中拿掉,而是把存儲的總數減少,本人寫得可以比這個好,在拿掉某個元素時,順便也讓它從數組中消失,將那個元素所在的位置的值設置為null即可):
我實在想不到比那個堆棧更經典的例子了,以致于我還要引用別人的例子,下面的例子不是我想到的,是書上看到的,當然如果沒有在書上看到,可能過一段時間我自己也想的到,可是那時我說是我自己想到的也沒有人相信的。
????public?class?Stack?{
????private?Object[]?elements=new?Object[10];
????private?int?size?=?0;
????public?void?push(Object?e){
????ensureCapacity();
????elements[size++]?=?e;
????}
????public?Object?pop(){
????if(?size?==?0)
????throw?new?EmptyStackException();
????return?elements[--size];
????}
????private?void?ensureCapacity(){
????if(elements.length?==?size){
????Object[]?oldElements?=?elements;
????elements?=?new?Object[2?*?elements.length+1];
????System.arraycopy(oldElements,0,?elements,?0,?size);
????}
????}
????}
????上面的原理應該很簡單,假如堆棧加了10個元素,然后全部彈出來,雖然堆棧是空的,沒有我們要的東西,但是這是個對象是無法回收的,這個才符合了內存泄露的兩個條件:無用,無法回收。
????但是就是存在這樣的東西也不一定會導致什么樣的后果,如果這個堆棧用的比較少,也就浪費了幾個K內存而已,反正我們的內存都上G了,哪里會有什么影響,再說這個東西很快就會被回收的,有什么關系。下面看兩個例子。
????例子1
????public?class?Bad{
????public?static?Stack?s=Stack();
????static{
????s.push(new?Object());
????s.pop();?//這里有一個對象發生內存泄露
????s.push(new?Object());?//上面的對象可以被回收了,等于是自愈了
????}
????}
????因為是static,就一直存在到程序退出,但是我們也可以看到它有自愈功能,就是說如果你的Stack最多有100個對象,那么最多也就只有100個對象無法被回收其實這個應該很容易理解,Stack內部持有100個引用,最壞的情況就是他們都是無用的,因為我們一旦放新的進取,以前的引用自然消失!
?
?
73、下面程序的輸出結果是多少?
?
import?java.util.Date;
public??class?Test?extends?Date{
?
/**
?*?@param?args?add?by?zxx?,Dec?9,?2008
?*/
public?static?void?main(String[]?args)?{
new?Test().test();
?
}
?
public?void?test()
{
System.out.println(super.getClass().getName());
}
}
Public?class?Test1?extends?Test{
Public?static?void?main(String[]?agrs){
New?Test1().test();
}
Public?void?test(){
System.out.println(getClass().getSuperClass().getName());
}
}
?
很奇怪,結果是Test
這屬于腦筋急轉彎的題目,在一個qq群有個網友正好問過這個問題,我覺得挺有趣,就研究了一下,沒想到今天還被你面到了,哈哈。
在test方法中,直接調用getClass().getName()方法,返回的是Test類名
由于getClass()在Object類中定義成了final,子類不能覆蓋該方法,所以,在
test方法中調用getClass().getName()方法,其實就是在調用從父類繼承的getClass()方法,等效于調用super.getClass().getName()方法,所以,super.getClass().getName()方法返回的也應該是Test。
如果想得到父類的名稱,應該用如下代碼:
getClass().getSuperClass().getName();
74、說出一些常用的類,包,接口,請各舉5個?
要讓人家感覺你對java?ee開發很熟,所以,不能僅僅只列core?java中的那些東西,要多列你在做ssh項目中涉及的那些東西。就寫你最近寫的那些程序中涉及的那些類。
?
常用的類: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
?
?
2.?特高深的Java問題
75、能不能自己寫個類,也叫java.lang.String?
?
可以,但在應用的時候,需要用自己的類加載器去加載,否則,系統的類加載器永遠只是去加載jre.jar包中的那個java.lang.String。由于在tomcat的web應用程序中,都是由webapp自己的類加載器先自己加載WEB-INF/classess目錄中的類,然后才委托上級的類加載器加載,如果我們在tomcat的web應用程序中寫一個java.lang.String,這時候Servlet程序加載的就是我們自己寫的java.lang.String,但是這么干就會出很多潛在的問題,原來所有用了java.lang.String類的都將出現問題。
?
雖然java提供了endorsed技術,可以覆蓋jdk中的某些類,具體做法是….。但是,能夠被覆蓋的類是有限制范圍,反正不包括java.lang這樣的包中的類。
?
(下面的例如主要是便于大家學習理解只用,不要作為答案的一部分,否則,人家懷疑是題目泄露了)例如,運行下面的程序:
package?java.lang;
?
public?class?String?{
?
/**
?*?@param?args
?*/
public?static?void?main(String[]?args)?{
//?TODO?Auto-generated?method?stub
System.out.println("string");
}
?
}
報告的錯誤如下:
java.lang.NoSuchMethodError:?main
Exception?in?thread?"main"
這是因為加載了jre自帶的java.lang.String,而該類中沒有main方法。
?
76.?Java代碼查錯
1.
abstract?class?Name?{
???private?String?name;
???public?abstract?boolean?isStupidName(String?name)?{}
}
大俠們,這有何錯誤?
答案:?錯。abstract?method必須以分號結尾,且不帶花括號。
2.
public?class?Something?{
???void?doSomething?()?{
???????private?String?s?=?"";
???????int?l?=?s.length();
???}
}
有錯嗎?
答案:?錯。局部變量前不能放置任何訪問修飾符?(private,public,和protected)。final可以用來修飾局部變量
(final如同abstract和strictfp,都是非訪問修飾符,strictfp只能修飾class和method而非variable)。
3.
abstract?class?Something?{
???private?abstract?String?doSomething?();
}
這好像沒什么錯吧?
答案:?錯。abstract的methods不能以private修飾。abstract的methods就是讓子類implement(實現)具體細節的,怎么可以用private把abstract
method封鎖起來呢??(同理,abstract?method前不能加final)。
4.
public?class?Something?{
???public?int?addOne(final?int?x)?{
???????return?++x;
???}
}
這個比較明顯。
答案:?錯。int?x被修飾成final,意味著x不能在addOne?method中被修改。
5.
public?class?Something?{
???public?static?void?main(String[]?args)?{
???????Other?o?=?new?Other();
???????new?Something().addOne(o);
???}
???public?void?addOne(final?Other?o)?{
???????o.i++;
???}
}
class?Other?{
???public?int?i;
}
和上面的很相似,都是關于final的問題,這有錯嗎?
答案:?正確。在addOne?method中,參數o被修飾成final。如果在addOne?method里我們修改了o的reference
(比如:?o?=?new?Other();),那么如同上例這題也是錯的。但這里修改的是o的member?vairable
(成員變量),而o的reference并沒有改變。
6.
class?Something?{
????int?i;
????public?void?doSomething()?{
????????System.out.println("i?=?"?+?i);
????}
}?
有什么錯呢??看不出來啊。
答案:?正確。輸出的是"i?=?0"。int?i屬於instant?variable?(實例變量,或叫成員變量)。instant?variable有default?value。int的default?value是0。
7.
class?Something?{
????final?int?i;
????public?void?doSomething()?{
????????System.out.println("i?=?"?+?i);
????}
}
和上面一題只有一個地方不同,就是多了一個final。這難道就錯了嗎?
答案:?錯。final?int?i是個final的instant?variable?(實例變量,或叫成員變量)。final的instant?variable沒有default?value,必須在constructor?(構造器)結束之前被賦予一個明確的值。可以修改為"final?int?i?=?0;"。
8.
public?class?Something?{
?????public?static?void?main(String[]?args)?{
????????Something?s?=?new?Something();
????????System.out.println("s.doSomething()?returns?"?+?doSomething());
????}
????public?String?doSomething()?{
????????return?"Do?something?...";
????}
}
?看上去很完美。
答案:?錯。看上去在main里call?doSomething沒有什么問題,畢竟兩個methods都在同一個class里。但仔細看,main是static的。static?method不能直接call?non-static?methods。可改成"System.out.println("s.doSomething()?returns?"?+?s.doSomething());"。同理,static?method不能訪問non-static?instant?variable。
9.
此處,Something類的文件名叫OtherThing.java
class?Something?{
????private?static?void?main(String[]?something_to_do)?{????????
????????System.out.println("Do?something?...");
????}
}
?這個好像很明顯。
答案:?正確。從來沒有人說過Java的Class名字必須和其文件名相同。但public?class的名字必須和文件名相同。
10.
interface??A{
???int?x?=?0;
}
class?B{
???int?x?=1;
}
class?C?extends?B?implements?A?{
???public?void?pX(){
??????System.out.println(x);
???}
???public?static?void?main(String[]?args)?{
??????new?C().pX();
???}
}
答案:錯誤。在編譯時會發生錯誤(錯誤描述不同的JVM有不同的信息,意思就是未明確的x調用,兩個x都匹配(就象在同時import?java.util和java.sql兩個包時直接聲明Date一樣)。對于父類的變量,可以用super.x來明確,而接口的屬性默認隱含為?public?static?final.所以可以通過A.x來明確。
11.
interface?Playable?{
????void?play();
}
interface?Bounceable?{
????void?play();
}
interface?Rollable?extends?Playable,?Bounceable?{
????Ball?ball?=?new?Ball("PingPang");
}
class?Ball?implements?Rollable?{
????private?String?name;
????public?String?getName()?{
????????return?name;
????}
????public?Ball(String?name)?{
????????this.name?=?name;????????
????}
???public?void?play()?{
????????ball?=?new?Ball("Football");
????????System.out.println(ball.getName());
????}
}
這個錯誤不容易發現。
答案:?錯。"interface?Rollable?extends?Playable,?Bounceable"沒有問題。interface可繼承多個interfaces,所以這里沒錯。問題出在interface?Rollable里的"Ball?ball?=?new?Ball("PingPang");"。任何在interface里聲明的interface?variable?(接口變量,也可稱成員變量),默認為public?static?final。也就是說"Ball?ball?=?new?Ball("PingPang");"實際上是"public?static?final?Ball?ball?=?new?Ball("PingPang");"。在Ball類的Play()方法中,"ball?=?new?Ball("Football");"改變了ball的reference,而這里的ball來自Rollable?interface,Rollable?interface里的ball是public?static?final的,final的object是不能被改變reference的。因此編譯器將在"ball?=?new?Ball("Football");"這里顯示有錯。
2.?算法與編程
77、說明生活中遇到的二叉樹,用java實現二叉樹
我有很多個(假設10萬個)數據要保存起來,以后還需要從保存的這些數據中檢索是否存在某個數據,(我想說出二叉樹的好處,該怎么說呢?那就是說別人的缺點),假如存在數組中,那么,碰巧要找的數字位于99999那個地方,那查找的速度將很慢,因為要從第1個依次往后取,取出來后進行比較。平衡二叉樹(構建平衡二叉樹需要先排序,我們這里就不作考慮了)可以很好地解決這個問題,但二叉樹的遍歷(前序,中序,后序)效率要比數組低很多,原理如下圖:
?
代碼如下:
package?com.huawei.interview;
?
public?class?Node?{
public?int?value;
public?Node?left;
public?Node?right;
?
public?void?store(int?value)
{
if(value<this.value)
{
if(left?==?null)
{
left?=?new?Node();
left.value=value;
}
else
{
left.store(value);
}
}
else?if(value>this.value)
{
if(right?==?null)
{
right?=?new?Node();
right.value=value;
}
else
{
right.store(value);
}
}
}
?
public?boolean?find(int?value)
{
System.out.println("happen?"?+?this.value);
if(value?==?this.value)
{
return?true;
}
else?if(value>this.value)
{
if(right?==?null)?return?false;
return?right.find(value);
}else
{
if(left?==?null)?return?false;
return?left.find(value);
}
?
}
?
public??void?preList()
{
System.out.print(this.value?+?",");
if(left!=null)?left.preList();
if(right!=null)?right.preList();
}
?
public?void?middleList()
{
if(left!=null)?left.preList();
System.out.print(this.value?+?",");
if(right!=null)?right.preList();
}
public?void?afterList()
{
if(left!=null)?left.preList();
if(right!=null)?right.preList();
System.out.print(this.value?+?",");
}
public?static?void?main(String?[]?args)
{
int?[]?data?=?new?int[20];
for(int?i=0;i<data.length;i++)
{
data[i]?=?(int)(Math.random()*100)?+?1;
System.out.print(data[i]?+?",");
}
System.out.println();
?
Node?root?=?new?Node();
root.value?=?data[0];
for(int?i=1;i<data.length;i++)
{
root.store(data[i]);
}
?
root.find(data[19]);
?
root.preList();
System.out.println();
root.middleList();
System.out.println();
root.afterList();
}
}
?
78、從類似如下的文本文件中讀取出所有的姓名,并打印出重復的姓名和重復的次數,并按重復次數排序:
1,張三,28
2,李四,35
3,張三,28
4,王五,35
5,張三,28
6,李四,35
7,趙六,28
8,田七,35
?
程序代碼如下(答題要博得用人單位的喜歡,包名用該公司,面試前就提前查好該公司的網址,如果查不到,現場問也是可以的。還要加上實現思路的注釋):
package?com.huawei.interview;
?
import?java.io.BufferedReader;
import?java.io.IOException;
import?java.io.InputStream;
import?java.io.InputStreamReader;
import?java.util.Comparator;
import?java.util.HashMap;
import?java.util.Iterator;
import?java.util.Map;
import?java.util.TreeSet;
?
?
public?class?GetNameTest?{
?
/**
?*?@param?args
?*/
public?static?void?main(String[]?args)?{
//?TODO?Auto-generated?method?stub
//InputStream?ips?=?GetNameTest.class.getResourceAsStream("/com/huawei/interview/info.txt");
//用上一行注釋的代碼和下一行的代碼都可以,因為info.txt與GetNameTest類在同一包下面,所以,可以用下面的相對路徑形式
?
Map?results?=?new?HashMap();
InputStream?ips?=?GetNameTest.class.getResourceAsStream("info.txt");
BufferedReader?in?=?new?BufferedReader(new?InputStreamReader(ips));
String?line?=?null;
try?{
while((line=in.readLine())!=null)
{
dealLine(line,results);
}
sortResults(results);
}?catch?(IOException?e)?{
//?TODO?Auto-generated?catch?block
e.printStackTrace();
}
}
?
static?class?User
{
public??String?name;
public?Integer?value;
public?User(String?name,Integer?value)
{
this.name?=?name;
this.value?=?value;
}
?
@Override
public?boolean?equals(Object?obj)?{
//?TODO?Auto-generated?method?stub
?
//下面的代碼沒有執行,說明往treeset中增加數據時,不會使用到equals方法。
boolean?result?=?super.equals(obj);
System.out.println(result);
return?result;
}
}
?
private?static?void?sortResults(Map?results)?{
//?TODO?Auto-generated?method?stub
TreeSet?sortedResults?=?new?TreeSet(
new?Comparator(){
public?int?compare(Object?o1,?Object?o2)?{
//?TODO?Auto-generated?method?stub
User?user1?=?(User)o1;
User?user2?=?(User)o2;
/*如果compareTo返回結果0,則認為兩個對象相等,新的對象不會增加到集合中去
?*?所以,不能直接用下面的代碼,否則,那些個數相同的其他姓名就打印不出來。
?*?*/
?
//return?user1.value-user2.value;
//return?user1.value<user2.value?-1:user1.value==user2.value?0:1;
if(user1.value<user2.value)
{
return?-1;
}else?if(user1.value>user2.value)
{
return?1;
}else
{
return?user1.name.compareTo(user2.name);
}
}
?
}
);
Iterator?iterator?=?results.keySet().iterator();
while(iterator.hasNext())
{
String?name?=?(String)iterator.next();
Integer?value?=?(Integer)results.get(name);
if(value?>?1)
{
sortedResults.add(new?User(name,value));
}
}
?
printResults(sortedResults);
}
private?static?void?printResults(TreeSet?sortedResults)?
{
Iterator?iterator??=?sortedResults.iterator();
while(iterator.hasNext())
{
User?user?=?(User)iterator.next();
System.out.println(user.name?+?":"?+?user.value);
}
}
public?static?void?dealLine(String?line,Map?map)
{
if(!"".equals(line.trim()))
{
String?[]?results?=?line.split(",");
if(results.length?==?3)
{
String?name?=?results[1];
Integer?value?=?(Integer)map.get(name);
if(value?==?null)?value?=?0;
map.put(name,value?+?1);
}
}
}
?
}
79、寫一個Singleton出來。
Singleton模式主要作用是保證在Java應用程序中,一個類Class只有一個實例存在。?
一般Singleton模式通常有幾種種形式:?
第一種形式:?定義一個類,它的構造函數為private的,它有一個static的private的該類變量,在類初始化時實例話,通過一個public的getInstance方法獲取對它的引用,繼而調用其中的方法。?
public?class?Singleton?{?
private?Singleton(){}?
????//在自己內部定義自己一個實例,是不是很奇怪??
????//注意這是private?只供內部調用?
????private?static?Singleton?instance?=?new?Singleton();?
????//這里提供了一個供外部訪問本class的靜態方法,可以直接訪問 ?
????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;?
}?
}?
其他形式:?
定義一個類,它的構造函數為private的,所有方法為static的。?
一般認為第一種形式要更加安全些?
80、遞歸算法題1
一個整數,大于0,不用循環和本地變量,按照n,2n,4n,8n的順序遞增,當值大于5000時,把值按照指定順序輸出來。
例:n=1237
則輸出為:
1237,
2474,
4948,
9896,
9896,
4948,
2474,
1237,
?
public?static?void?multiply(int?n)
{
if(n>5000)?return;
System.out.println(n);
multiply(n*2);
System.out.println(n);
}
?
?
?
81、遞歸算法題2
第1個人10,第2個比第1個人大2歲,依次遞推,第8個人多大?
package?cn.itcast;
?
import?java.util.Date;
?
public?class?A1?{
?
public?static?void?main(String?[]?args)
{
System.out.println(computeAge(8));
}
?
public?static?int?computeAge(int?n)
{
if(n==1)?return?10;
return?computeAge(n-1)?+?2;
}
}
?
public?static?void?toBinary(int?n,StringBuffer?result)
{
?
if(n/2?!=?0)
toBinary(n/2,result);
result.append(n%2);
}
82、排序都有哪幾種方法?請列舉。用JAVA實現一個快速排序。?
?本人只研究過冒泡排序、選擇排序和快速排序,下面是快速排序的代碼:
public?class?QuickSort?{
/**
*?快速排序
*?@param?strDate
*?@param?left
*?@param?right
*/
public?void?quickSort(String[]?strDate,int?left,int?right){
String?middle,tempDate;
int?i,j;
i=left;
j=right;
middle=strDate[(i+j)/2];
do{
while(strDate[i].compareTo(middle)<0&&?i<right)
i++;?//找出左邊比中間值大的數
while(strDate[j].compareTo(middle)>0&&?j>left)
j--;?//找出右邊比中間值小的數
if(i<=j){?//將左邊大的數和右邊小的數進行替換?
tempDate=strDate[i];
strDate[i]=strDate[j];
strDate[j]=tempDate;
i++;
j--;
}
}while(i<=j);?//當兩者交錯時停止
if(i<right){
quickSort(strDate,i,right);//從
}
if(j>left){
quickSort(strDate,left,j);
}
}
/**
??*?@param?args
??*/
public?static?void?main(String[]?args){
String[]?strVoid=new?String[]{"11","66","22","0","55","22","0","32"};
QuickSort?sort=new?QuickSort();
sort.quickSort(strVoid,0,strVoid.length-1);
for(int?i=0;i<strVoid.length;i++){
System.out.println(strVoid[i]+"?");
}
}
}
83、有數組a[n],用java代碼將數組元素順序顛倒
?
package?cn.itcast.lecture2;
?
import?java.util.Arrays;
import?java.util.Collections;
?
public?class?ReverseTest?{
public?static?void?main(String?[]?args)
{
//產生若干0到1000的隨機數,作為數組的初始值
int?data[]?=?new?int[]{
(int)(Math.random()?*?1000),
(int)(Math.random()?*?1000),
(int)(Math.random()?*?1000),
(int)(Math.random()?*?1000),
(int)(Math.random()?*?1000),
(int)(Math.random()?*?1000),
(int)(Math.random()?*?100),
};
System.out.println(Math.random());
System.out.print("交換前的數據:");
System.out.println(
Arrays.toString(data));
reverse(data);
System.out.print("交換后的數據:");
System.out.println(Arrays.toString(data));
}
?
//方法執行完后,參數data中的數據順序即被顛倒
//實現思路是第1個和第n個交換,第2個和第n-1個交換,依次類推...
public?static?void?reverse(int[]?data)
{
?
int?len?=?data.length;
for(int?i=0;i<len/2;i++)
{
int?temp?=?data[i];
data[i]?=?data[len-1-i];
data[len-1-i]?=?temp;
}
}
}
?
84.金額轉換,阿拉伯數字的金額轉換成中國傳統的形式如:(¥1011)->(一千零一拾一元整)輸出。
public?class?RenMingBi?{
?
/**
?*?@param?args?add?by?zxx?,Nov?29,?2008
?*/
private?static?final?char[]?data?=?new?char[]{
'零','壹','貳','叁','肆','伍','陸','柒','捌','玖'
};?
private?static?final?char[]?units?=?new?char[]{
'元','拾','佰','仟','萬','拾','佰','仟','億'
};
public?static?void?main(String[]?args)?{
//?TODO?Auto-generated?method?stub
System.out.println(
convert(135689123));
}
?
public?static?String?convert(int?money)
{
StringBuffer?sbf?=?new?StringBuffer();
int?unit?=?0;
while(money!=0)
{
sbf.insert(0,units[unit++]);
int?number?=?money%10;
sbf.insert(0,?data[number]);
money?/=?10;
}
?
return?sbf.toString();
}
}
2.?html&JavaScript部分
85.?判斷第二個日期比第一個日期大
如何用腳本判斷用戶輸入的的字符串是下面的時間格式2004-11-21?必須要保證用戶的輸入是此格式,并且是時間,比如說月份不大于12等等,另外我需要用戶輸入兩個,并且后一個要比前一個晚,只允許用JAVASCRIPT,請詳細幫助作答,,?
//這里可用正則表達式判斷提前判斷一下格式,然后按下提取各時間字段內容
<input?type="text"?id="d1"/>
<input?type="text"?id="d2"?οnblur="compare()"/>
<script>
function?compare()
{
var?d1?=?document.getElementById("d1").value;
var?d2?=?document.getElementById("d2").value;
arr1?=?d1.split("-");
arr2?=?d2.split("-");
date1?=?new?Date(arr1[0],arr1[1],arr1[2]);
date2?=?new?Date(arr2[0],arr2[1],arr2[2]);
if(date2.getTime()<date1.getTime())
{
alert("不能比第一個日期小");
return?false;
}
}
</script>
86.?用table顯示n條記錄,每3行換一次顏色,即1,2,3用紅色字體,4,5,6用綠色字體,7,8,9用紅顏色字體。
87、HTML?的?form?提交之前如何驗證數值不為空??為空的話提示用戶并終止提交??
88、請寫出用于校驗HTML文本框中輸入的內容全部為數字的javascript代碼
var?re=/^\d{1,8}$|\.\d{1,2}$/;?
var?str=document.form1.all(i).value;?
var?r=str.match(re);?
if?(r==null)?
{?
sign=-4;?
break;?
}?
else{?
document.form1.all(i).value=parseFloat(str);?
}?
?
3.?Java?web部分
89、HTTP請求的GET與POST方式的區別
答:servlet有良好的生存期的定義,包括加載和實例化、初始化、處理請求以及服務結束。這個生存期由javax.servlet.Servlet接口的init,service和destroy方法表達。
90、解釋一下什么是servlet;
答:servlet有良好的生存期的定義,包括加載和實例化、初始化、處理請求以及服務結束。這個生存期由javax.servlet.Servlet接口的init,service和destroy方法表達。
91、說一說Servlet的生命周期??
答:servlet有良好的生存期的定義,包括加載和實例化、初始化、處理請求以及服務結束。這個生存期由javax.servlet.Servlet接口的init,service和destroy方法表達。
?
Servlet被服務器實例化后,容器運行其init方法,請求到達時運行其service方法,service方法自動派遣運行與請求對應的doXXX方法(doGet,doPost)等,當服務器決定將實例銷毀的時候調用其destroy方法。
web容器加載servlet,生命周期開始。通過調用servlet的init()方法進行servlet的初始化。通過調用service()方法實現,根據請求的不同調用不同的do***()方法。結束服務,web容器調用servlet的destroy()方法。?
?
92、Servlet的基本架構?
public?class?ServletName?extends?HttpServlet?{?
public?void?doPost(HttpServletRequest?request,?HttpServletResponse?response)?throws?
ServletException,?IOException?{?
}?
public?void?doGet(HttpServletRequest?request,?HttpServletResponse?response)?throws?
ServletException,?IOException?{?
}?
}?
93、SERVLET?API中forward()?與redirect()的區別??
答:前者僅是容器中控制權的轉向,在客戶端瀏覽器地址欄中不會顯示出轉向后的地址;后者則是完全的跳轉,瀏覽器將會得到跳轉的地址,并重新發送請求鏈接。這樣,從瀏覽器的地址欄中可以看到跳轉后的鏈接地址。所以,前者更加高效,在前者可以滿足需要時,盡量使用forward()方法,并且,這樣也有助于隱藏實際的鏈接。在有些情況下,比如,需要跳轉到一個其它服務器上的資源,則必須使用
sendRedirect()方法。?
?
94、什么情況下調用doGet()和doPost()??
Jsp頁面中的FORM標簽里的method屬性為get時調用doGet(),為post時調用doPost()。?
?
95、Request對象的主要方法:?
setAttribute(String?name,Object):設置名字為name的request的參數值?
getAttribute(String?name):返回由name指定的屬性值?
getAttributeNames():返回request對象所有屬性的名字集合,結果是一個枚舉的實例?
getCookies():返回客戶端的所有Cookie對象,結果是一個Cookie數組?
getCharacterEncoding():返回請求中的字符編碼方式?
getContentLength():返回請求的Body的長度?
getHeader(String?name):獲得HTTP協議定義的文件頭信息?
getHeaders(String?name):返回指定名字的request?Header的所有值,結果是一個枚舉的實例?
getHeaderNames():返回所以request?Header的名字,結果是一個枚舉的實例?
getInputStream():返回請求的輸入流,用于獲得請求中的數據?
getMethod():獲得客戶端向服務器端傳送數據的方法?
getParameter(String?name):獲得客戶端傳送給服務器端的有name指定的參數值?
getParameterNames():獲得客戶端傳送給服務器端的所有參數的名字,結果是一個枚舉的實例?
getParametervalues(String?name):獲得有name指定的參數的所有值?
getProtocol():獲取客戶端向服務器端傳送數據所依據的協議名稱?
getQueryString():獲得查詢字符串?
getRequestURI():獲取發出請求字符串的客戶端地址?
getRemoteAddr():獲取客戶端的IP地址?
getRemoteHost():獲取客戶端的名字?
getSession([Boolean?create]):返回和請求相關Session?
getServerName():獲取服務器的名字?
getServletPath():獲取客戶端所請求的腳本文件的路徑?
getServerPort():獲取服務器的端口號?
removeAttribute(String?name):刪除請求中的一個屬性?
?
?
?
96、forward?和redirect的區別?
forward是服務器請求資源,服務器直接訪問目標地址的URL,把那個URL的響應內容讀取過來,然后把這些內容再發給瀏覽器,瀏覽器根本不知道服務器發送的內容是從哪兒來的,所以它的地址欄中還是原來的地址。?
???redirect就是服務端根據邏輯,發送一個狀態碼,告訴瀏覽器重新去請求那個地址,一般來說瀏覽器會用剛才請求的所有參數重新請求,所以session,request參數都可以獲取。
97、request.getAttribute()?和?request.getParameter()?有何區別?
98.?jsp有哪些內置對象?作用分別是什么??分別有什么方法??
答:JSP共有以下9個內置的對象:?
request?用戶端請求,此請求會包含來自GET/POST請求的參數?
response?網頁傳回用戶端的回應?
pageContext?網頁的屬性是在這里管理?
session?與請求有關的會話期?
application?servlet?正在執行的內容?
out?用來傳送回應的輸出?
config?servlet的構架部件?
page?JSP網頁本身?
exception?針對錯誤網頁,未捕捉的例外?
?
request表示HttpServletRequest對象。它包含了有關瀏覽器請求的信息,并且提供了幾個用于獲取cookie,?header,?和session數據的有用的方法。?
???response表示HttpServletResponse對象,并提供了幾個用于設置送回?瀏覽器的響應的方法(如cookies,頭信息等)?
???out對象是javax.jsp.JspWriter的一個實例,并提供了幾個方法使你能用于向瀏覽器回送輸出結果。?
???pageContext表示一個javax.servlet.jsp.PageContext對象。它是用于方便存取各種范圍的名字空間、servlet相關的對象的API,并且包裝了通用的servlet相關功能的方法。?
???session表示一個請求的javax.servlet.http.HttpSession對象。Session可以存貯用戶的狀態信息?
???applicaton?表示一個javax.servle.ServletContext對象。這有助于查找有關servlet引擎和servlet環境的信息?
???config表示一個javax.servlet.ServletConfig對象。該對象用于存取servlet實例的初始化參數。?
???page表示從該頁面產生的一個servlet實例?
?
99.?jsp有哪些動作?作用分別是什么??
(這個問題似乎不重要,不明白為何有此題)
答:JSP共有以下6種基本動作?
jsp:include:在頁面被請求的時候引入一個文件。?
jsp:useBean:尋找或者實例化一個JavaBean。?
jsp:setProperty:設置JavaBean的屬性。?
jsp:getProperty:輸出某個JavaBean的屬性。?
jsp:forward:把請求轉到一個新的頁面。?
jsp:plugin:根據瀏覽器類型為Java插件生成OBJECT或EMBED標記
100、JSP的常用指令?
isErrorPage(是否能使用Exception對象),isELIgnored(是否忽略表達式)?
?
101.?JSP中動態INCLUDE與靜態INCLUDE的區別??
答:動態INCLUDE用jsp:include動作實現?
<jsp:include?page=included.jsp?flush=true?/>它總是會檢查所含文件中的變化,適合用于包含動態頁面,并且可以帶參數?靜態INCLUDE用include偽碼實現,定不會檢查所含文件的變化,適用于包含靜態頁面?<%@?include?file=included.htm?%>?
?
102、兩種跳轉方式分別是什么?有什么區別??
(下面的回答嚴重錯誤,應該是想問forward和sendRedirect?的區別,畢竟出題的人不是專業搞文字藝術的人,可能表達能力并不見得很強,用詞不一定精準,加之其自身的技術面也可能存在一些問題,不一定真正將他的意思表達清楚了,嚴格意思上來講,一些題目可能根本就無人能答,所以,答題時要掌握主動,只要把自己知道的表達清楚就夠了,而不要去推敲原始題目的具體含義是什么,不要一味想著是在答題)
答:有兩種,分別為:?
<jsp:include?page=included.jsp?flush=true>?
<jsp:forward?page=?nextpage.jsp/>?
前者頁面不會轉向include所指的頁面,只是顯示該頁的結果,主頁面還是原來的頁面。執行完后還會回來,相當于函數調用。并且可以帶參數.后者完全轉向新頁面,不會再回來。相當于go?to?語句。
?
103、頁面間對象傳遞的方法?
request,session,application,cookie等?
104、JSP和Servlet有哪些相同點和不同點,他們之間的聯系是什么??
JSP是Servlet技術的擴展,本質上是Servlet的簡易方式,更強調應用的外表表達。JSP編譯后是"類servlet"。Servlet和JSP最主要的不同點在于,Servlet的應用邏輯是在Java文件中,并且完全從表示層中的HTML里分離開來。而JSP的情況是Java和HTML可以組合成一個擴展名為.jsp的文件。JSP側重于視圖,Servlet主要用于控制邏輯。?
?
105、MVC的各個部分都有那些技術來實現?如何實現??
答:MVC是Model-View-Controller的簡寫。Model?代表的是應用的業務邏輯(通過JavaBean,EJB組件實現),?View?是應用的表示面(由JSP頁面產生),Controller?是提供應用的處理過程控制(一般是一個Servlet),通過這種設計模型把應用邏輯,處理過程和顯示邏輯分成不同的組件實現。這些組件可以進行交互和重用。?
?
106、我們在web應用開發過程中經常遇到輸出某種編碼的字符,如iso8859-1等,如何輸出一個某種編碼的字符串??
?Public?String?translate?(String?str)?{?
???String?tempStr?=?"";?
???try?{?
?????tempStr?=?new?String(str.getBytes("ISO-8859-1"),?"GBK");?
?????tempStr?=?tempStr.trim();?
???}?
???catch?(Exception?e)?{?
?????System.err.println(e.getMessage());?
???}?
???return?tempStr;?
?}?
107.現在輸入n個數字,以逗號,分開;然后可選擇升或者降序排序;按提交鍵就在另一頁面顯示按什么排序,結果為,提供reset
108.?數據庫部分
109、數據庫三范式是什么?
第一范式:1NF是對屬性的原子性約束,要求屬性具有原子性,不可再分解
第二范式:2NF是對記錄的唯一約束,要求記錄有唯一標識,即實體的唯一性
第三范式:3NF是對字段行的約束,即任何字段不能由其他字段派生出來,要求字段沒有余,,(是直接相關而不是間接相關)
110、說出一些數據庫優化方面的經驗?
111、union和union?all有什么不同?
Union會自動壓縮多個結果集合中的重復結果,而union?all則將所有的結果全部顯示出來,不管是不是重復,?union:對兩個結果集驚醒并集操作,不包括重復行,同時進行默認規則的排序,union?all;對兩個結果集進行并集操作包括重復行,不進行排序;
112查出比經理薪水還高的員工信息:
Drop?table?if?not?exists?employees;
create?table?employees(id?int?primary?key?auto_increment,name?varchar(50)
,salary?int,managerid?int?references?employees(id));
insert?into?employees?values?(null,'zxx',10000,null),?(null,'lhm',15000,1
),(null,'flx',9000,1),(null,'tg',10000,2),(null,'wzg',10000,3);
?
Wzg大于flx,lhm大于zxx
?
select?e.*?from?employees?e,employees?m?where?e.managerid=m.id?and?e.sala
ry>m.salary;
113、oracle關聯查詢題目1
數據庫中有3個表?teacher?表,student表,tea_stu關系表。?
teacher?表?teaID?name?age?
student?表?stuID?name?age?
teacher_student表?teaID?stuID?
要求用一條sql查詢出這樣的結果?
??1.顯示的字段要有老師name,?age?每個老師所帶的學生人數?
2?只列出老師age為40以下學生age為12以上的記錄
預備知識:
??????1.sql語句是對每一條記錄依次處理,條件為真則執行動作(select,insert,delete,update)
???????2.只要是迪卡爾積,就會產生“垃圾”信息,所以,只要迪卡爾積了,我們首先就要想到清除“垃圾”信息
實驗準備:
drop?table?if?exists?tea_stu;
drop?table?if?exists?teacher;
drop?table?if?exists?student;
??????create?table?teacher(teaID?int?primary?key,name?varchar(50),age?int);
??????create?table?student(stuID?int?primary?key,name?varchar(50),age?int);
??????create?table?tea_stu(teaID?int?references?teacher(teaID),stuID?int?references?student(stuID));
insert?into?teacher?values(1,'zxx',45),?(2,'lhm',25)?,?(3,'wzg',26)?,?(4,'tg',27);
insert?into?student?values(1,'wy',11),?(2,'dh',25)?,?(3,'ysq',26)?,?(4,'mxc',27);
insert?into?tea_stu?values(1,1),?(1,2),?(1,3);
insert?into?tea_stu?values(2,2),?(2,3),?(2,4);
?insert?into?tea_stu?values(3,3),?(3,4),?(3,1);
insert?into?tea_stu?values(4,4),?(4,1),?(4,2)?,?(4,3);
?
結果:2à3,3à2,4à3
?
解題思路:(真實面試答題時,也要寫出每個分析步驟,如果紙張不夠,就找別人要)
1要會統計分組信息:
select?teaid,count(*)?from?tea_stu?group?by?teaid;
2.要會篩選大于40的老師
??先講給1號學生帶課的所有老師的名字,要知道1號學生的老師,要從哪個表獲得?從tea_stu里才可以,從這個表里獲得的是老師的什么?是老師的teaID,如果要得到老師的名稱,則必須拿著teaID去teacher里找。所以,這兩個表要進行關聯,關聯就引出迪卡爾既的問題。假設我們好獲得teaID為1的老師的名稱,我們要關聯的是哪條記錄?是1那一條,但是,迪卡爾既的結果有幾條啊?4條,顯然,我接著要做的就是把其他垃圾的3條去掉。
select?*?from?tea_stu,teacher?where?tea_stu.teaID=teacher.teaID;
再接著去掉大于40的老師:
select?*?from?tea_stu,teacher?where?tea_stu.teaID=teacher.teaID?and?teacher.age<=40;
3.再對上面的結果去掉小于12的學生
select?*?from?
(select?tea_stu.*?from?tea_stu,teacher?where?tea_stu.teaID=
teacher.teaID?and?teacher.age<40)?as?t,
student?
where?t.stuid=student.stuid?and?student.age>12;
4.再對上面的結果進行統計,顯示的是老師的id和組信息
select?t.teaID,count(*)?from?
(select?tea_stu.*?from?tea_stu,teacher?where?tea_stu.teaID=
teacher.teaID?and?teacher.age<40)?as?t,
student?
where?t.stuid=student.stuid?and?student.age>12
group?by?t.teaID;
?
5.然后對上面的東西進行改寫,改寫成顯示老師的名字
select?teacher.name,t2.c?from
(select?t.teaID,count(*)?c?from?
(select?tea_stu.*?from?tea_stu,teacher?where?tea_stu.teaID=
teacher.teaID?and?teacher.age<40)?as?t,
student?
where?t.stuid=student.stuid?and?student.age>12
group?by?t.teaID)?as?t2,
teacher
where?teacher.teaID=t2.teaID;
?
第二種寫法:
select?teacher.teaID,?teacher.name,?t1.total?from?teacher,
(select?teaID,count(tea_stu.stuID)?total?from?tea_stu,?student?
where?tea_stu.stuID?=?student.stuID?and?student.age>12
group?by?teaID?)?as?t1
where?teacher.teaID?=?t1.teaID?and?teacher.age<40?;
?
求出發帖最多的人:
select?authorid,count(*)?total?from?articles?
group?by?authorid?
having?total=
(select?max(total2)?from?(select?count(*)?total2?from?articles?group?by?authorid)?as?t);
?
select?t.authorid,max(t.total)?from
(select?authorid,count(*)?total?from?articles?)as?t
這條語句不行,因為max只有一列,不能與其他列混淆。
?
select?authorid,count(*)?total?from?articles?
group?by?authorid?having?total=max(total)也不行。
114、什么是存儲過程和如何編寫
存儲過程是一組為了完成特定功能的sql語句集,
create?or?replace
procedure?test
as
begin
??過程
end;
--調用
begin
??test;
end;
115、注冊Jdbc驅動程序的三種方式
1,Class.forName(“com.oracle.jdbc.Driver”);
2,DriverManger.registerDriver(new?com.oracle.jdbc.Driver());
3,System.setProperty(“jdbc.drivers”,”com.oracle.jdbc.Driver”);
116、用JDBC如何調用存儲過程
{call過程名[(?,?,,,,)]}返回結果參數的過程的語法為
{?=call過程名[(?,?,,,,)]}
不帶參的:{call過程名}
117、JDBC中的PreparedStatement相比Statement的好處
1,相對比較安全,可以防止sql注入
2,有裕編譯功能,相同的操作批量數據效率較高
118.?寫一個用jdbc連接并訪問oracle數據的程序代碼
?
private?static?final?String?DRIVER?=?"?com.oracle.jdbc.driver.OracleDriver?";
private?static?final?String?URL?=?"jdbc:oracle:thin:@localhost:1521?=orcl";
private?static?final?String?UNAME?=?"sa";
private?static?final?String?PASS?=?"123";
Class.forName(DRIVER);
conn?=?DriverManager.getConnection(URL,UNAME,PASS);
?
119、Class.forName的作用?為什么要用??
Class.forName(“”)返回的是以個類,任何Class都要裝載虛擬機上才能運行,class.forName();就是裝載類用的,(和NEW不一樣,)
用:比如說給你以個字符串(代表以類的包名和類名),要你把他的類加載到虛擬機上的時候就要用到了,
答:調用該訪問返回一個以字符串指定類名的類的對象。
120、大數據量下的分頁解決方法。
121、用?JDBC?查詢學生成績單,?把主要代碼寫出來.?
Connection?getConnection()
{
private?static?final?String?DRIVER?=?"?com.orcl.jdbc.Driver?";
private?static?final?String?URL?=?"jdbc:orcl?://localhost:1433;databasename=test";
private?static?final?String?UNAME?=?"sa";
private?static?final?String?PASS?=?"123";
Class.forName("com.orcl.jdbc.Driver");
return?java.sql.DriverManager.getConnention(dbURL,dbUser,dbPwd);
}
public?Employee?getEmployee()?throws?SQLException?{
STUDENT?employee?=?null;
String?sql?=?"SELECT?*?FROM?STUDENT";
Connection?conn?=?null;
PreparedStatement?ps?=?null;
ResultSet?rs?=?null;
try?{
conn?=?dataSource.getConnection();
ps?=?conn.prepareStatement(sql);
rs?=?ps.executeQuery();
employee?=?null;
while?(rs.next())?{
employee?=?new?STUDENT?();
employee.stuid?(rs.getInt("ID"));
?
}
}?finally?{
try?{
if?(rs?!=?null)
rs.close();
}?finally?{
try?{
if?(ps?!=?null)
ps.close();
}?finally?{
if?(conn?!=?null)
conn.close();
}
}
}
return?employee;
}
122、這段代碼有什么不足之處??
try?{
Connection?conn?=?...;
Statement?stmt?=?...;
ResultSet?rs?=?stmt.executeQuery("select?*?from?table1");
while(rs.next())?{
}
}?catch(Exception?ex)?{
}?
需要異常處理
123、說出數據連接池的工作機制是什么??
J2EE服務器啟動時會建立一定數量的池連接,并一直維持不少于此數目的池連接。客戶端程序需要連接時,池驅動程序會返回一個未使用的池連接并將其表記為忙。如果當前沒有空閑連接,池驅動程序就新建一定數量的連接,新建連接的數量有配置參數決定。當使用的池連接調用完成后,池驅動程序將此連接表記為空閑,其他調用就可以使用這個連接。?
?
124、為什么要用?ORM???和?JDBC?有何不一樣??
Orm建立java對象與數據庫對象之間的映射關系,程序員不需要編寫復雜的sql語句,直接操作java對象即可,從而大大降低了代碼量,也是程序員更加專注于業務邏輯的實現,
1.?代碼繁瑣問題,用jdbc訪問數據庫代碼量大繁瑣,容易出錯,
2.?數據庫連接問題,,關系數據對象之間,存在各種關系,,如果程序員用jdbc編程的話,就必須十分小心的處理這些關系,而這個過程是個很痛苦的過程,
3.?Orm建立java對象與數據庫對象關系映射,也自動根據數據庫對象之間的關系創建java對象的關系,并且提供了維持這些關系的完整有效機制
4.?系統架構問題,現在的應用系統一般由展示層,業務層,數據訪問層,數據層,各層次功能劃分非常清楚,jdbc屬于數據訪問層,使用jdbc編程時就必須知道后臺使用的是什么數據庫,有哪些表,哪些字段,表與表之間有什么關系,索引,等等,,使用orm可以完全的屏蔽數據庫,給程序員的只有java對象,程序員只需要根據業務邏輯的需要調用java對象,就可以實現對后臺的數據庫操作
5.?性能問題,jdbc很多時候存在效率地下的問題,orm框架講根據具體數據庫操作需要,會自動的延遲向后臺數據庫發送sql請求,盡量減少不必要的數據操作請求操作,
?
5.?XML部分
125、xml有哪些解析技術?區別是什么??
答:有DOM,SAX,STAX等?
DOM:處理大型文件時其性能下降的非常厲害。這個問題是由DOM的樹結構所造成的,這種結構占用的內存較多,而且DOM必須在解析文件之前把整個文檔裝入內存,適合對XML的隨機訪問SAX:不現于DOM,SAX是事件驅動型的XML解析方式。它順序讀取XML文件,不需要一次全部裝載整個文件。當遇到像文件開頭,文檔結束,或者標簽開頭與標簽結束時,它會觸發一個事件,用戶通過在其回調事件中寫入處理代碼來處理XML文件,適合對XML的順序訪問?
STAX:Streaming?API?for?XML?(StAX)?
講解這些區別是不需要特別去比較,就像說傳智播客與其他培訓機構的區別時,我們只需說清楚傳智播客有什么特點和優點就行了,這就已經間接回答了彼此的區別。
?
126、你在項目中用到了xml技術的哪些方面?如何實現的??
答:用到了數據存貯,信息配置兩方面。在做數據交換平臺時,將不能數據源的數據組裝成XML文件,然后將XML文件壓縮打包加密后通過網絡傳送給接收者,接收解密與解壓縮后再同XML文件中還原相關信息進行處理。在做軟件配置時,利用XML可以很方便的進行,軟件的各種配置參數都存貯在XML文件中。?
127、用jdom解析xml文件時如何解決中文問題?如何解析??
答:看如下代碼,用編碼方式加以解決?
package?test;?
import?java.io.*;?
public?class?DOMTest?
{?
private?String?inFile?=?"c:\\people.xml"?
private?String?outFile?=?"c:\\people.xml"?
public?static?void?main(String?args[])?
{?
new?DOMTest();?
}?
public?DOMTest()?
{?
try?
{?
javax.xml.parsers.DocumentBuilder?builder?=?
javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocumentBuilder();?
org.w3c.dom.Document?doc?=?builder.newDocument();?
org.w3c.dom.Element?root?=?doc.createElement("老師");?
org.w3c.dom.Element?wang?=?doc.createElement("王");?
org.w3c.dom.Element?liu?=?doc.createElement("劉");?
wang.appendChild(doc.createTextNode("我是王老師"));?
root.appendChild(wang);?
doc.appendChild(root);?
javax.xml.transform.Transformer?transformer?=?
javax.xml.transform.TransformerFactory.newInstance().newTransformer();?
transformer.setOutputProperty(javax.xml.transform.OutputKeys.ENCODING,?"gb2312");?
transformer.setOutputProperty(javax.xml.transform.OutputKeys.INDENT,?"yes");?
transformer.transform(new?javax.xml.transform.dom.DOMSource(doc),?
new?
javax.xml.transform.stream.StreamResult(outFile));?
}?
catch?(Exception?e)?
{?
System.out.println?(e.getMessage());?
}?
}?
}?
128、編程用JAVA解析XML的方式.?
答:用SAX方式解析XML,XML文件如下:?
<?xml?version=1.0?encoding=gb2312?>?
<person>?
<name>王小明</name>?
<college>信息學院</college>?
<telephone>6258113</telephone>?
<notes>男,1955年生,博士,95年調入海南大學</notes>?
</person>?
事件回調類SAXHandler.java?
import?java.io.*;?
import?java.util.Hashtable;?
import?org.xml.sax.*;?
public?class?SAXHandler?extends?HandlerBase?
{?
private?Hashtable?table?=?new?Hashtable();?
private?String?currentElement?=?null;?
private?String?currentValue?=?null;?
public?void?setTable(Hashtable?table)?
{?
this.table?=?table;?
}?
public?Hashtable?getTable()?
{?
return?table;?
}?
public?void?startElement(String?tag,?AttributeList?attrs)?
throws?SAXException?
{?
currentElement?=?tag;?
}?
public?void?characters(char[]?ch,?int?start,?int?length)?
throws?SAXException?
{?
currentValue?=?new?String(ch,?start,?length);?
}?
public?void?endElement(String?name)?throws?SAXException?
{?
if?(currentElement.equals(name))?
table.put(currentElement,?currentValue);?
}?
?
}?
JSP內容顯示源碼,SaxXml.jsp:?
<HTML>?
<HEAD>?
<TITLE>剖析XML文件people.xml</TITLE>?
</HEAD>?
<BODY>?
<%@?page?errorPage=ErrPage.jsp?
contentType=text/html;charset=GB2312?%>?
<%@?page?import=java.io.*?%>?
<%@?page?import=java.util.Hashtable?%>?
<%@?page?import=org.w3c.dom.*?%>?
<%@?page?import=org.xml.sax.*?%>?
<%@?page?import=javax.xml.parsers.SAXParserFactory?%>?
<%@?page?import=javax.xml.parsers.SAXParser?%>?
<%@?page?import=SAXHandler?%>?
<%?
File?file?=?new?File(c:\people.xml);?
FileReader?reader?=?new?FileReader(file);?
Parser?parser;?
SAXParserFactory?spf?=?SAXParserFactory.newInstance();?
SAXParser?sp?=?spf.newSAXParser();?
SAXHandler?handler?=?new?SAXHandler();?
sp.parse(new?InputSource(reader),?handler);?
Hashtable?hashTable?=?handler.getTable();?
out.println(<TABLE?BORDER=2><CAPTION>教師信息表</CAPTION>);?
out.println(<TR><TD>姓名</TD>?+?<TD>?+?
(String)hashTable.get(new?String(name))?+?</TD></TR>);?
out.println(<TR><TD>學院</TD>?+?<TD>?+?
(String)hashTable.get(new?String(college))+</TD></TR>);?
out.println(<TR><TD>電話</TD>?+?<TD>?+?
(String)hashTable.get(new?String(telephone))?+?</TD></TR>);?
out.println(<TR><TD>備注</TD>?+?<TD>?+?
(String)hashTable.get(new?String(notes))?+?</TD></TR>);?
out.println(</TABLE>);?
%>?
</BODY>?
</HTML>?
129、XML文檔定義有幾種形式?它們之間有何本質區別?解析XML文檔有哪幾種方式??
a:?兩種形式?dtd??schema,b:?本質區別:schema本身是xml的,可以被XML解析器解析(這也是從DTD上發展schema的根本目的),c:有DOM,SAX,STAX等?
???DOM:處理大型文件時其性能下降的非常厲害。這個問題是由DOM的樹結構所造成的,這種結構占用的內存較多,而且DOM必須在解析文件之前把整個文檔裝入內存,適合對XML的隨機訪問?
SAX:不現于DOM,SAX是事件驅動型的XML解析方式。它順序讀取XML文件,不需要一次全部裝載整個文件。當遇到像文件開頭,文檔結束,或者標簽開頭與標簽結束時,它會觸發一個事件,用戶通過在其回調事件中寫入處理代碼來處理XML文件,適合對XML的順序訪問?
???STAX:Streaming?API?for?XML?(StAX)?
?
6.?j2ee部分
130、BS與CS的聯系與區別。?
C/S是Client/Server的縮寫。服務器通常采用高性能的PC、工作站或小型機,并采用大型數據庫系統,如Oracle、Sybase、InFORMix或?SQL?Server。客戶端需要安裝專用的客戶端軟件。?
B/S是Brower/Server的縮寫,客戶機上只要安裝一個瀏覽器(Browser),如Netscape?Navigator或Internet?Explorer,服務器安裝Oracle、Sybase、InFORMix或?SQL?Server等數據庫。在這種結構下,用戶界面完全通過WWW瀏覽器實現,一部分事務邏輯在前端實現,但是主要事務邏輯在服務器端實現。瀏覽器通過Web?Server?同數據庫進行數據交互。?
C/S?與?B/S?區別:?
1.硬件環境不同:?
C/S?一般建立在專用的網絡上,?小范圍里的網絡環境,?局域網之間再通過專門服務器提供連接和數據交換服務.?
B/S?建立在廣域網之上的,?不必是專門的網絡硬件環境,例與電話上網,?租用設備.?信息自己管理.?有比C/S更強的適應范圍,?一般只要有操作系統和瀏覽器就行?
2.對安全要求不同?
C/S?一般面向相對固定的用戶群,?對信息安全的控制能力很強.?一般高度機密的信息系統采用C/S?結構適宜.?可以通過B/S發布部分可公開信息.?
B/S?建立在廣域網之上,?對安全的控制能力相對弱,?可能面向不可知的用戶。?
3.對程序架構不同?
C/S?程序可以更加注重流程,?可以對權限多層次校驗,?對系統運行速度可以較少考慮.?
B/S?對安全以及訪問速度的多重的考慮,?建立在需要更加優化的基礎之上.?比C/S有更高的要求?B/S結構的程序架構是發展的趨勢,?從MS的.Net系列的BizTalk?2000?Exchange?2000等,?全面支持網絡的構件搭建的系統.?SUN?和IBM推的JavaBean?構件技術等,使?B/S更加成熟.?
4.軟件重用不同?
C/S?程序可以不可避免的整體性考慮,?構件的重用性不如在B/S要求下的構件的重用性好.?
B/S?對的多重結構,要求構件相對獨立的功能.?能夠相對較好的重用.就入買來的餐桌可以再利用,而不是做在墻上的石頭桌子?
5.系統維護不同???
C/S?程序由于整體性,?必須整體考察,?處理出現的問題以及系統升級.?升級難.?可能是再做一個全新的系統?
B/S?構件組成,方面構件個別的更換,實現系統的無縫升級.?系統維護開銷減到最小.用戶從網上自己下載安裝就可以實現升級.?
6.處理問題不同?
C/S?程序可以處理用戶面固定,?并且在相同區域,?安全要求高需求,?與操作系統相關.?應該都是相同的系統?
B/S?建立在廣域網上,?面向不同的用戶群,?分散地域,?這是C/S無法作到的.?與操作系統平臺關系最小.?
7.用戶接口不同?
C/S?多是建立的Window平臺上,表現方法有限,對程序員普遍要求較高?
B/S?建立在瀏覽器上,?有更加豐富和生動的表現方式與用戶交流.?并且大部分難度減低,減低開發成本.?
8.信息流不同?
C/S?程序一般是典型的中央集權的機械式處理,?交互性相對低?
B/S?信息流向可變化,?B-B?B-C?B-G等信息、流向的變化,?更像交易中心。?
131、應用服務器與WEB?SERVER的區別?
應用服務器:Weblogic、Tomcat、Jboss?
WEB?SERVER:IIS、?Apache?
132、應用服務器有那些??
BEA?WebLogic?Server,IBM?WebSphere?Application?Server,Oracle9i?Application?Server,jBoss,Tomcat?
?
133、J2EE是什么??
答:Je22是Sun公司提出的多層(multi-diered),分布式(distributed),基于組件(component-base)的企業級應用模型(enterpriese?application?model).在這樣的一個應用系統中,可按照功能劃分為不同的組件,這些組件又可在不同計算機上,并且處于相應的層次(tier)中。所屬層次包括客戶層(clietn?tier)組件,web層和組件,Business層和組件,企業信息系統(EIS)層。
?
一個另類的回答:j2ee就是增刪改查。?
134、J2EE是技術還是平臺還是框架??什么是J2EE
???J2EE本身是一個標準,一個為企業分布式應用的開發提供的標準平臺。?
???J2EE也是一個框架,包括JDBC、JNDI、RMI、JMS、EJB、JTA等技術。
135、請對以下在J2EE中常用的名詞進行解釋(或簡單描述)?
web容器:給處于其中的應用程序組件(JSP,SERVLET)提供一個環境,使JSP,SERVLET直接更容器中的環境變量接口交互,不必關注其它系統問題。主要有WEB服務器來實現。例如:TOMCAT,WEBLOGIC,WEBSPHERE等。該容器提供的接口嚴格遵守J2EE規范中的WEB?APPLICATION?標準。我們把遵守以上標準的WEB服務器就叫做J2EE中的WEB容器。?
EJB容器:Enterprise?java?bean?容器。更具有行業領域特色。他提供給運行在其中的組件EJB各種管理功能。只要滿足J2EE規范的EJB放入該容器,馬上就會被容器進行高效率的管理。并且可以通過現成的接口來獲得系統級別的服務。例如郵件服務、事務管理。?
JNDI:(Java?Naming?&?Directory?Interface)JAVA命名目錄服務。主要提供的功能是:提供一個目錄系統,讓其它各地的應用程序在其上面留下自己的索引,從而滿足快速查找和定位分布式應用程序的功能。?(在連接池里面用到了)
JMS:(Java?Message?Service)JAVA消息服務。主要實現各個應用程序之間的通訊。包括點對點和廣播。?
JTA:(Java?Transaction?API)JAVA事務服務。提供各種分布式事務服務。應用程序只需調用其提供的接口即可。?
JAF:(Java?Action?FrameWork)JAVA安全認證框架。提供一些安全控制方面的框架。讓開發者通過各種部署和自定義實現自己的個性安全控制策略。?
RMI/IIOP:(Remote?Method?Invocation?/internet對象請求中介協議)他們主要用于通過遠程調用服務。例如,遠程有一臺計算機上運行一個程序,它提供股票分析服務,我們可以在本地計算機上實現對其直接調用。當然這是要通過一定的規范才能在異構的系統之間進行通信。RMI是JAVA特有的。
136、如何給weblogic指定大小的內存??
(這個問題不作具體回答,列出來只是告訴讀者可能會遇到什么問題,你不需要面面俱到,什么都精通。)(weblogic是BA公司的)
?
在啟動Weblogic的腳本中(位于所在Domian對應服務器目錄下的startServerName),增加set?MEM_ARGS=-Xms32m?-Xmx200m,可以調整最小內存為32M,最大200M?
137、如何設定的weblogic的熱啟動模式(開發模式)與產品發布模式??
可以在管理控制臺中修改對應服務器的啟動模式為開發或產品模式之一。或者修改服務的啟動文件或者commenv文件,增加set?PRODUCTION_MODE=true。?
138、如何啟動時不需輸入用戶名與密碼??
修改服務啟動文件,增加?WLS_USER和WLS_PW項。也可以在boot.properties文件中增加加密過的用戶名和密碼.?
139、在weblogic管理制臺中對一個應用域(或者說是一個網站,Domain)進行jms及ejb或連接池等相關信息進行配置后,實際保存在什么文件中??
保存在此Domain的config.xml文件中,它是服務器的核心配置文件。?
140、說說weblogic中一個Domain的缺省目錄結構?比如要將一個簡單的helloWorld.jsp放入何目錄下,然的在瀏覽器上就可打入http://主機:端口號//helloword.jsp就可以看到運行結果了??又比如這其中用到了一個自己寫的javaBean該如何辦??
Domain目錄服務器目錄applications,將應用目錄放在此目錄下將可以作為應用訪問,如果是Web應用,應用目錄需要滿足Web應用目錄要求,jsp文件可以直接放在應用目錄中,Javabean需要放在應用目錄的WEB-INF目錄的classes目錄中,設置服務器的缺省應用將可以實現在瀏覽器上無需輸入應用名。?
145、在weblogic中發布ejb需涉及到哪些配置文件?
不同類型的EJB涉及的配置文件不同,都涉及到的配置文件包括ejb-jar.xml,weblogic-ejb-jar.xmlCMP實體Bean一般還需要weblogic-cmp-rdbms-jar.xml?
146、如何在weblogic中進行ssl配置與客戶端的認證配置或說說j2ee(標準)進行ssl的配置?
缺省安裝中使用DemoIdentity.jks和DemoTrust.jks??KeyStore實現SSL,需要配置服務器使用Enable?SSL,配置其端口,在產品模式下需要從CA獲取私有密鑰和數字證書,創建identity和trust?keystore,裝載獲得的密鑰和數字證書。可以配置此SSL連接是單向還是雙向的。?
147、如何查看在weblogic中已經發布的EJB??
可以使用管理控制臺,在它的Deployment中可以查看所有已發布的EJB?
7.?ejb部分
148、EJB是基于哪些技術實現的?并說出SessionBean和EntityBean的區別,StatefulBean和StatelessBean的區別。?
???EJB包括Session?Bean、Entity?Bean、Message?Driven?Bean,基于JNDI、RMI、JAT等技術實現。?
SessionBean在J2EE應用程序中被用來完成一些服務器端的業務操作,例如訪問數據庫、調用其他EJB組件。EntityBean被用來代表應用系統中用到的數據。?
對于客戶機,SessionBean是一種非持久性對象,它實現某些在服務器上運行的業務邏輯。?
對于客戶機,EntityBean是一種持久性對象,它代表一個存儲在持久性存儲器中的實體的對象視圖,或是一個由現有企業應用程序實現的實體。?
Session?Bean?還可以再細分為?Tasteful?Session?Bean?與?Stateless?Session?Bean?,這兩種的?Session?Bean都可以將系統邏輯放在?method之中執行,不同的是?Stateful?Session?Bean?可以記錄呼叫者的狀態,因此通常來說,一個使用者會有一個相對應的?Stateful?Session?Bean?的實體。Stateless?Session?Bean?雖然也是邏輯組件,但是他卻不負責記錄使用者狀態,也就是說當使用者呼叫?Stateless?Session?Bean?的時候,EJB?Container?并不會找尋特定的?Stateless?Session?Bean?的實體來執行這個?method。換言之,很可能數個使用者在執行某個?Stateless?Session?Bean?的?methods?時,會是同一個?Bean?的?Instance?在執行。從內存方面來看,?Stateful?Session?Bean?與?Stateless?Session?Bean?比較,?Stateful?Session?Bean?會消耗?J2EE?Server?較多的內存,然而?Stateful?Session?Bean?的優勢卻在于他可以維持使用者的狀態。?
?
149、簡要講一下?EJB?的?7?個?Transaction?Level??
150、EJB與JAVA?BEAN的區別??
Java?Bean?是可復用的組件,對Java?Bean并沒有嚴格的規范,理論上講,任何一個Java類都可以是一個Bean。但通常情況下,由于Java?Bean是被容器所創建(如Tomcat)的,所以Java?Bean應具有一個無參的構造器,另外,通常Java?Bean還要實現Serializable接口用于實現Bean的持久性。Java?Bean實際上相當于微軟COM模型中的本地進程內COM組件,它是不能被跨進程訪問的。Enterprise?Java?Bean?相當于DCOM,即分布式組件。它是基于Java的遠程方法調用(RMI)技術的,所以EJB可以被遠程訪問(跨進程、跨計算機)。但EJB必須被布署在諸如Webspere、WebLogic這樣的容器中,EJB客戶從不直接訪問真正的EJB組件,而是通過其容器訪問。EJB容器是EJB組件的代理,EJB組件由容器所創建和管理。客戶通過容器來訪問真正的EJB組件。?
151、EJB包括(SessionBean,EntityBean)說出他們的生命周期,及如何管理事務的??
SessionBean:Stateless?Session?Bean?的生命周期是由容器決定的,當客戶機發出請求要建立一個Bean的實例時,EJB容器不一定要創建一個新的Bean的實例供客戶機調用,而是隨便找一個現有的實例提供給客戶機。當客戶機第一次調用一個Stateful?Session?Bean?時,容器必須立即在服務器中創建一個新的Bean實例,并關聯到客戶機上,以后此客戶機調用Stateful?Session?Bean?的方法時容器會把調用分派到與此客戶機相關聯的Bean實例。?
EntityBean:Entity?Beans能存活相對較長的時間,并且狀態是持續的。只要數據庫中的數據存在,Entity?beans就一直存活。而不是按照應用程序或者服務進程來說的。即使EJB容器崩潰了,Entity?beans也是存活的。Entity?Beans生命周期能夠被容器或者?Beans自己管理。?
EJB通過以下技術管理實務:對象管理組織(OMG)的對象實務服務(OTS),Sun?Microsystems的Transaction?Service(JTS)、Java?Transaction?API(JTA),開發組(X/Open)的XA接口。?
152、EJB容器提供的服務?
主要提供聲明周期管理、代碼產生、持續性管理、安全、事務管理、鎖和并發行管理等服務。
?
153、EJB的激活機制?
以Stateful?Session?Bean?為例:其Cache大小決定了內存中可以同時存在的Bean實例的數量,根據MRU或NRU算法,實例在激活和去激活狀態之間遷移,激活機制是當客戶端調用某個EJB實例業務方法時,如果對應EJB?Object發現自己沒有綁定對應的Bean實例則從其去激活Bean存儲中(通過序列化機制存儲實例)回復(激活)此實例。狀態變遷前會調用對應的ejbActive和ejbPassivate方法。?
154、EJB的幾種類型?
會話(Session)Bean?,實體(Entity)Bean?消息驅動的(Message?Driven)Bean?
會話Bean又可分為有狀態(Stateful)和無狀態(Stateless)兩種?
實體Bean可分為Bean管理的持續性(BMP)和容器管理的持續性(CMP)兩種?
155、客服端調用EJB對象的幾個基本步驟?
設置JNDI服務工廠以及JNDI服務地址系統屬性,查找Home接口,從Home接口調用Create方法創建Remote接口,通過Remote接口調用其業務方法。
156.?webservice部分
157、WEB?SERVICE名詞解釋。JSWDL開發包的介紹。JAXP、JAXM的解釋。SOAP、UDDI,WSDL解釋。
Web?ServiceWeb?Service是基于網絡的、分布式的模塊化組件,它執行特定的任務,遵守具體的技術規范,這些規范使得Web?Service能與其他兼容的組件進行互操作。?
JAXP(Java?API?for?XML?Parsing)?定義了在Java中使用DOM,?SAX,?XSLT的通用的接口。這樣在你的程序中你只要使用這些通用的接口,當你需要改變具體的實現時候也不需要修改代碼。?
JAXM(Java?API?for?XML?Messaging)?是為SOAP通信提供訪問方法和傳輸機制的API。?
WSDL是一種?XML?格式,用于將網絡服務描述為一組端點,這些端點對包含面向文檔信息或面向過程信息的消息進行操作。這種格式首先對操作和消息進行抽象描述,然后將其綁定到具體的網絡協議和消息格式上以定義端點。相關的具體端點即組合成為抽象端點(服務)。?
SOAP即簡單對象訪問協議(Simple?Object?Access?Protocol),它是用于交換XML編碼信息的輕量級協議。?
UDDI?的目的是為電子商務建立標準;UDDI是一套基于Web的、分布式的、為Web?Service提供的、信息注冊中心的實現標準規范,同時也包含一組使企業能將自身提供的Web?Service注冊,以使別的企業能夠發現的訪問協議的實現標準。
158、CORBA是什么?用途是什么??
CORBA?標準是公共對象請求代理結構(Common?Object?Request?Broker?Architecture),由對象管理組織?(Object?Management?Group,縮寫為?OMG)標準化。它的組成是接口定義語言(IDL),?語言綁定(binding:也譯為聯編)和允許應用程序間互操作的協議。?其目的為:用不同的程序設計語言書寫在不同的進程中運行,為不同的操作系統開發。
?
5.?流行的框架與新技術
?
159、談談Struts中的Action?servlet。
屬于是中央控制器,所有的請求都由Action?servlet解析,當是他也不是每一個都自己取解析,
而是交給他的手下
160、Struts優缺點?
優點:?
?1.?實現MVC模式,結構清晰,使開發者只關注業務邏輯的實現.
2.有豐富的tag可以用?,Struts的標記庫(Taglib),如能靈活動用,則能大大提高開發效率
3.?頁面導航
使系統的脈絡更加清晰。通過一個配置文件,即可把握整個系統各部分之間的聯系,這對于后期的維護有著莫大的好處。尤其是當另一批開發者接手這個項目時,這種優勢體現得更加明顯。
4.?提供Exception處理機制?.?
5.?數據庫鏈接池管理?
6.?支持I18N?
缺點
一、?轉到展示層時,需要配置forward,如果有十個展示層的jsp,需要配置十次struts,而且還不包括有時候目錄、文件變更,需要重新修改forward,注意,每次修改配置之后,要求重新部署整個項目,而tomcate這樣的服務器,還必須重新啟動服務器
二、?二、?Struts?的Action必需是thread-safe方式,它僅僅允許一個實例去處理所有的請求。所以action用到的所有的資源都必需統一同步,這個就引起了線程安全的問題。
三、??測試不方便.?Struts的每個Action都同Web層耦合在一起,這樣它的測試依賴于Web容器,單元測試也很難實現。不過有一個Junit的擴展工具Struts?TestCase可以實現它的單元測試。?
四、??類型的轉換.?Struts的FormBean把所有的數據都作為String類型,它可以使用工具Commons-Beanutils進行類型轉化。但它的轉化都是在Class級別,而且轉化的類型是不可配置的。類型轉化時的錯誤信息返回給用戶也是非常困難的。
五、?對Servlet的依賴性過強.?Struts處理Action時必需要依賴ServletRequest?和ServletResponse,所有它擺脫不了Servlet容器。?
六、??前端表達式語言方面.Struts集成了JSTL,所以它主要使用JSTL的表達式語言來獲取數據。可是JSTL的表達式語言在Collection和索引屬性方面處理顯得很弱。?
七、??對Action執行的控制困難.?Struts創建一個Action,如果想控制它的執行順序將會非常困難。甚至你要重新去寫Servlet來實現你的這個功能需求。?
八、??對Action?執行前和后的處理.?Struts處理Action的時候是基于class的hierarchies,很難在action處理前和后進行操作。?
九、??對事件支持不夠.?在struts中,實際是一個表單Form對應一個Action類(或DispatchAction),換一句話說:在Struts中實際是一個表單只能?對應一個事件,struts這種事件方式稱為application?event,application?event和component?event相比是一種粗粒度的事件
?
?
161、STRUTS的應用(如STRUTS架構)?
Struts是采用Java?Servlet/JavaServer?Pages技術,開發Web應用程序的開放源碼的framework。?采用Struts能開發出基于MVC(Model-View-Controller)設計模式的應用構架。?Struts有如下的主要功能:?一.包含一個controller?servlet,能將用戶的請求發送到相應的Action對象。?二.JSP自由tag庫,并且在controller?servlet中提供關聯支持,幫助開發員創建交互式表單應用。?三.提供了一系列實用對象:XML處理、通過Java?reflection?APIs自動處理JavaBeans屬性、國際化的提示和消息。
?
162、hibernate中的update()和saveOrUpdate()的區別,session的load()和get()的區別。
?
163、簡述?Hibernate?和?JDBC?的優缺點??如何書寫一個?one?to?many?配置文件.
164、iBatis與Hibernate有什么不同?
相同點:屏蔽jdbc?api的底層訪問細節,使用我們不用與jdbc?api?打交道,就可以訪問數據,jdbc?api編程流程固定,
165.?hibernate進行多表查詢每個表中各取幾個字段,也就是說查詢出來的結果集沒有一個實體類與之對應如何解決;?
?
解決方案一,按照Object[]數據取出數據,然后自己組bean
解決方案二,對每個表的bean寫構造函數,比如表一要查出field1,field2兩個字段,那么有一個構造函數就是Bean(type1?filed1,type2?
field2)?,然后在hql里面就可以直接生成這個bean了。
166.介紹一下Hibernate的二級緩存
按照以下思路來回答:(1)首先說清楚什么是緩存,(2)再說有了hibernate的Session就是一級緩存,即有了一級緩存,為什么還要有二級緩存,(3)最后再說如何配置Hibernate的二級緩存。
(1)緩存就是把以前從數據庫中查詢出來和使用過的對象保存在內存中(一個數據結構中),這個數據結構通常是或類似Hashmap,當以后要使用某個對象時,先查詢緩存中是否有這個對象,如果有則使用緩存中的對象,如果沒有則去查詢數據庫,并將查詢出來的對象保存在緩存中,以便下次使用。下面是緩存的偽代碼:
引出hibernate的第二級緩存,用下面的偽代碼分析了Cache的實現原理
Dao
{
hashmap?map?=?new?map();
User?getUser(integer?id)
{
User?user?=?map.get(id)
if(user?==?null)
{
user?=?session.get(id);
map.put(id,user);
}
return?user;
}
}
?
Dao
{
Cache?cache?=?null
setCache(Cache?cache)
{
this.cache?=?cache
}
?
User?getUser(int?id)
{
if(cache!=null)
{
User?user?=?cache.get(id);
if(user?==null)
{
user?=?session.get(id);
cache.put(id,user);
}
return?user;
}
?
return?session.get(id);
}
}
(2)Hibernate的Session就是一種緩存,我們通常將之稱為Hibernate的一級緩存,當想使用session從數據庫中查詢出一個對象時,Session也是先從自己內部查看是否存在這個對象,存在則直接返回,不存在才去訪問數據庫,并將查詢的結果保存在自己內部。由于Session代表一次會話過程,一個Session與一個數據庫連接相關連,所以Session最好不要長時間保持打開,通常僅用于一個事務當中,在事務結束時就應關閉。并且Session是線程不安全的,被多個線程共享時容易出現問題。通常只有那種全局意義上的緩存才是真正的緩存應用,才有較大的緩存價值,因此,Hibernate的Session這一級緩存的緩存作用并不明顯,應用價值不大。Hibernate的二級緩存就是要為Hibernate配置一種全局緩存,讓多個線程和多個事務都可以共享這個緩存。我們希望的是一個人使用過,其他人也可以使用,session沒有這種效果。
(3)二級緩存是獨立于Hibernate的軟件部件,屬于第三方的產品,多個廠商和組織都提供有緩存產品,例如,EHCache和OSCache等等。在Hibernate中使用二級緩存,首先就要在hibernate.cfg.xml配置文件中配置使用哪個廠家的緩存產品,接著需要配置該緩存產品自己的配置文件,最后要配置Hibernate中的哪些實體對象要納入到二級緩存的管理中。明白了二級緩存原理和有了這個思路后,很容易配置起Hibernate的二級緩存。擴展知識:一個SessionFactory可以關聯一個二級緩存,也即一個二級緩存只能負責緩存一個數據庫中的數據,當使用Hibernate?的二級緩存后,注意不要有其他的應用或SessionFactory來更改當前數據庫中的數據,這樣緩存的數據就會與數據庫中的實際數據不一致。?
?
167、Spring?的依賴注入是什么意思??給一個?Bean?的?message?屬性,?字符串類型,?注入值為?"Hello"?的?XML?配置文件該怎么寫?
?
168、Jdo是什么??
JDO是Java對象持久化的新的規范,為java?data?object的簡稱,也是一個用于存取某種數據倉庫中的對象的標準化API。JDO提供了透明的對象存儲,因此對開發人員來說,存儲數據對象完全不需要額外的代碼(如JDBC?API的使用)。這些繁瑣的例行工作已經轉移到JDO產品提供商身上,使開發人員解脫出來,從而集中時間和精力在業務邏輯上。另外,JDO很靈活,因為它可以在任何數據底層上運行。JDBC只是面向關系數據庫(RDBMS)JDO更通用,提供到任何數據底層的存儲功能,比如關系數據庫、文件、XML以及對象數據庫(ODBMS)等等,使得應用可移植性更強。?
?
169、什么是spring的IOC??AOP
Spring要掌握的:
一個就是IOC(依賴注入(耦合程度可以降低)或者控制反轉)一個就是AOP
?
170、STRUTS的工作流程!
171、spring?與EJB的區別!!
9.?軟件工程與設計模式
172、UML方面?
標準建模語言UML。用例圖,靜態圖(包括類圖、對象圖和包圖),行為圖,交互圖(順序圖,合作圖),實現圖。?
173.?軟件開發的
174、j2ee常用的設計模式?說明工廠模式。?
總共23種,分為三大類:創建型,結構型,行為型
我只記得其中常用的6、7種,分別是:
創建型(工廠、工廠方法、抽象工廠、單例)
結構型(包裝、適配器,組合,代理)
行為(觀察者,模版,策略)
然后再針對你熟悉的模式談談你的理解即可。???
?
Java中的23種設計模式:?
Factory(工廠模式),??????Builder(建造模式),???????Factory?Method(工廠方法模式),?
Prototype(原始模型模式),Singleton(單例模式),????Facade(門面模式),?
Adapter(適配器模式),????Bridge(橋梁模式),????????Composite(合成模式),?
Decorator(裝飾模式),????Flyweight(享元模式),?????Proxy(代理模式),?
Command(命令模式),??????Interpreter(解釋器模式),?Visitor(訪問者模式),?
Iterator(迭代子模式),???Mediator(調停者模式),????Memento(備忘錄模式),?
Observer(觀察者模式),???State(狀態模式),?????????Strategy(策略模式),?
Template?Method(模板方法模式),?Chain?Of?Responsibleity(責任鏈模式)?
工廠模式:工廠模式是一種經常被使用到的模式,根據工廠模式實現的類可以根據提供的數據生成一組類中某一個類的實例,通常這一組類有一個公共的抽象父類并且實現了相同的方法,但是這些方法針對不同的數據進行了不同的操作。首先需要定義一個基類,該類的子類通過不同的方法實現了基類中的方法。然后需要定義一個工廠類,工廠類可以根據條件生成不同的子類實例。當得到子類的實例后,開發人員可以調用基類中的方法而不必考慮到底返回的是哪一個子類的實例。?
175、開發中都用到了那些設計模式?用在什么場合??
每個模式都描述了一個在我們的環境中不斷出現的問題,然后描述了該問題的解決方案的核心。通過這種方式,你可以無數次地使用那些已有的解決方案,無需在重復相同的工作。主要用到了MVC的設計模式。用來開發JSP/Servlet或者J2EE的相關應用。簡單工廠模式等。?
?
10.?Linux
176、LINUX下線程,GDI類的解釋。?
LINUX實現的就是基于核心輕量級進程的"一對一"線程模型,一個線程實體對應一個核心輕量級進程,而線程之間的管理在核外函數庫中實現。?
GDI類為圖像設備編程接口類庫。?
?
10.?問得稀里糊涂的題
177、四種會話跟蹤技術?
會話作用域ServletsJSP?頁面描述?
page否是代表與一個頁面相關的對象和屬性。一個頁面由一個編譯好的?Java?servlet?類(可以帶有任何的?include?指令,但是沒有?include?動作)表示。這既包括?servlet?又包括被編譯成?servlet?的?JSP?頁面?
request是是代表與?Web?客戶機發出的一個請求相關的對象和屬性。一個請求可能跨越多個頁面,涉及多個?Web?組件(由于?forward?指令和?include?動作的關系)?
session是是代表與用于某個?Web?客戶機的一個用戶體驗相關的對象和屬性。一個?Web?會話可以也經常會跨越多個客戶機請求?
application是是代表與整個?Web?應用程序相關的對象和屬性。這實質上是跨越整個?Web?應用程序,包括多個頁面、請求和會話的一個全局作用域?
178、簡述邏輯操作(&,|,^)與條件操作(&&,||)的區別。?
區別主要答兩點:a.條件操作只能操作布爾型的,而邏輯操作不僅可以操作布爾型,而且可以操作數值型?
b.邏輯操作不會產生短路?
?
10.?其他
179、請用英文簡單介紹一下自己.
4、WEB?SERVICE名詞解釋。JSWDL開發包的介紹。JAXP、JAXM的解釋。SOAP、UDDI,WSDL解釋。
180、請把?http://tomcat.apache.org/?首頁的這一段話用中文翻譯一下?
Apache?Tomcat?is?the?servlet?container?that?is?used?in?the?official?Reference?Implementation?for?the?Java?Servlet?and?JavaServer?Pages?technologies.?The?Java?Servlet?and?JavaServer?Pages?specifications?are?developed?by?Sun?under?the?Java?Community?Process.?
Apache?Tomcat?is?developed?in?an?open?and?participatory?environment?and?released?under?the?Apache?Software?License.?Apache?Tomcat?is?intended?to?be?a?collaboration?of?the?best-of-breed?developers?from?around?the?world.?We?invite?you?to?participate?in?this?open?development?project.?To?learn?more?about?getting?involved,?click?here.?
Apache?Tomcat?powers?numerous?large-scale,?mission-critical?web?applications?across?a?diverse?range?of?industries?and?organizations.?Some?of?these?users?and?their?stories?are?listed?on?the?PoweredBy?wiki?page.
180、美資軟件公司JAVA工程師電話面試題目?
1.?Talk?about?overriding,?overloading.
2.?Talk?about?JAVA?design?patterns?you?known.
3.?Talk?about?the?difference?between?LinkList,?ArrayList?and?Victor.
4.?Talk?about?the?difference?between?an?Abstract?class?and?an?Interface.
5.?Class?a?=?new?Class();?Class?b?=?new?Class();
?if(a?==?b)?returns?true?or?false,?why?
6.?Why?we?use?StringBuffer?when?concatenating?strings?
7.?Try?to?explain?Singleton?to?us??Is?it?thread?safe??If?no,?how?to?make?it?thread?safe?
8.?Try?to?explain?Ioc?
9.?How?to?set?many-to-many?relationship?in?Hibernate?
10.?Talk?about?the?difference?between?INNER?JOIN?and?LFET?JOIN.
11.?Why?we?use?index?in?database??How?many?indexes?is?the?maximum?in?one?table?as?your?suggestion?
12.?When?‘Final’?is?used?in?class,?method?and?property,?what?dose?it?mean?
13.?Do?you?have?any?experience?on?XML??Talk?about?any?XML?tool?you?used?,e.g.?JAXB,?JAXG.
14.?Do?you?have?any?experience?on?Linux?
15.?In?OOD?what?is?the?reason?when?you?create?a?Sequence?diagram??
?
?
總結
- 上一篇: java笔试面试经典问题
- 下一篇: ajax常见错误和使用总结