第一篇:java開發面試題
1、編寫程序
題目:古典問題:有一對公母豬,從出生后第3個月起每個月都生一對豬,小豬長到第三個月后每個月又生一對豬,假如豬都不死,問每個月的豬總數為多少?
答案:
public class lianxi01 {
public static void main(String[] args){
System.out.println(“第1個月的兔子對數: 1”);
System.out.println(“第2個月的兔子對數: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 +“個月的兔子對數: ”+f2);
}
}
}
2、是非題
2.1 Java程序中的起始類名稱必須與存放該類的文件名相同。()
答案:正確
2.2 原生類中的數據類型均可任意轉換。()
答案:錯誤
3、問答題
3.1 try {}里有一個return語句,那么緊跟在這個try后的finally {}里的code會不會被執行,什么時候被執行,在return前還是后?
答案:
會執行,在return前執行。
3.2 sleep()和 wait()有什么區別:
答案:
sleep是線程類(Thread)的方法,導致此線程暫停執行指定時間,給執行機會給其他線程,但是監控狀態依然保持,到時后會自動恢復。調用sleep不會 釋放對象鎖。wait是Object類的方法,對此對象調用wait方法導致本線程放棄對象鎖,進入等待此對象的等待鎖定池,只有針對此對象發出notify方法(或notifyAll)后本線程才進入對象鎖定池準備獲得對象鎖進入運行狀態。
4、數據庫題
聚集函數的應用
編寫一條sql語句,希望從藝術家表artist_tab中,看到只有一個專長specialty的是哪些專長
答案:seelctspecialty from artist_tab group by specialty having count(*)=1’;
第二篇:JAVA網站開發工程師面試題
JAVA_WEB開發人員面試題及答案
面試人:面試時間:
一.選擇題(每題1分,共20分)
1.jsp 有幾個內置對象?(c)(單選)
A 5個B6個C9個D8個
2.在JAVA中,如何跳出當前的多重嵌套循環?(ab)(多選)
A breakBreturnCforwardDfinally
3.四種會話跟蹤技術,哪個范圍最大?(d)(單選)
A pageBrequestCsessionDapplication
4.java中有幾種方法可以實現一個線程?(b)(單選)
A1種B2種C3種D 4種
5.同步有幾種實現方法(b)(單選)
A 4種B2種C3種D 1種
6.xml有哪些解析技術?(abcd)(多選)
A DOMBSAXCSTAXD JDOM
7.下列說法正確的是(bd)(多選)
A 構造器Constructor可被繼承
BString類不可以繼承
C 判斷兩個對象值相同用“==”
D char型變量中能不能存貯一個中文漢字
8.下列關于線程說法正確的是(abc)(多選)
A調用sleep不會釋放對象鎖。
B調用wait方法導致本線程放棄對象鎖
C當一個線程進入一個對象的一個synchronized方法后,其它線程不可進入此對象的其它方法
Dnotify():喚醒全部處于等待狀態的線程。
9.給定JSP程序源碼如下,該JSP運行后輸出的結果是(b)。(單選)
<%int Count=1;%>
Count:<%= Count%>
ACount:1BCount:2C1:2 DCount:
10.在J2EE中的一個JSP文件中,有表達式<%=2 3%>,它將輸出(b)(單選)
a)2 3b)5c)23d)不會輸出,因為表達式是錯誤的11.在J2EE中,編寫Servlet過濾器時,(c)接口用于調用過濾器鏈中的下一個過濾器。(單選)
a)Filterb)FilterConfigc)FilterChaind)Servlet
12)關于視圖的描述正確的是(c)(單選)
a)視圖是一種特殊的表,它存儲了用戶定制的數據。
b)視圖僅用于用戶進行查詢,不可以通過視圖對數據進行修改。
c)在sql server中可以通過用T-sql語句來創建,也可以通過企業管理器。
d)創建視圖只能操作本機器上的數據庫表。
13)STRUTS框架中,(c)類在視圖層和控制層之間傳遞HTML表單數據。(單選)a)Actionb)ActionForward c)ActionFormd)ActionServlet
18)Struts控制器的主要任務是接受用戶請求、根據用戶請求調用對應的模型組件、獲取業務邏輯執行結果的根據處理結果選擇適合的視圖組件返回給用戶,實現Struts控制器的類中不包括(c)。(單選)
a)ActionServletb)Actionc)ActionFormd)ActionForward
14)以下關于SessionFactory的說法哪些正確?(bc)(多選)
A)對于每個數據庫事務,應該創建一個SessionFactory對象
B)一個SessionFactory對象對應一個數據庫存儲源。
C)SessionFactory是重量級的對象,不應該隨意創建。如果系統中只有一個數據庫存儲源只需要創建一個。
D)SessionFactory的load()方法用于加載持久化對象
15)下面那些是Hibernate的查詢方式(abc)(多選)
A)sqlB)hqlC)Criteria
18)以下數據結構不屬于線性結構的是(c)(單選)
A)隊列B)線性表C)二叉樹D)棧
16)下列是文件讀寫的類是(ac)(多選)
A)File ReaderB)FileC)FileWriterD)InputStream
17)數據庫技術中的“臟數據',是指(c)的數據。(單選)
A)錯誤B 回返C 未提交D 未提交的隨后又被撤消
18)在計算機中,—個字節是由多少個二進制位組成的(b)(單選)
A).4B).8C).16D).24
19.下列不屬于面向對象的方法是(d)(單選)
A).對象B).類C).繼承D).過程調用
29.設正x、y均為整型變量,且x=10 y=3,則以下語句printf(“%d,%dn”,x--,--y);的輸出結果是(d)(單選)
A).10,3B).9,3C).9,2D).10,2二.填空(每空1分,共10分)
1.String s = new String(“xyz”);創建了__2__個String 對象?
2.Math.round(9.5)等於__10___Math.round(-9.5)等於__-9____
3.try {}里有一個return語句,那么緊跟在這個try后的finally {}里的code會被執行,什么時候被執行,在return____前_____(前還是后?)
4.如何現實servlet的單線程模式 ______<%@ page isThreadSafe=“false”%> _________
5.類變量必須帶的修飾符是 ______ static _________
6.final類可以修飾在屬性 , 方法和___類___前面
7.Java默認的包是______ java.lang.*_________
8.Hibernate里面怎樣實現類與類之間的關系__________表映射_______________
9.Socket 編程服務器端用____ serverSocket ____類來創建socket對象。
三. 判斷題(每題2分,共10分)
1.依賴注入即是“面向接口”的編程。錯
2.Overload和Override都是java多態的不同體現形式。對
3.String是最基本的數據類型。錯
4.啟動一個線程是用start。對
5.接口可以繼承接口。對
四.簡答題(每題5分,共30分)
1、網頁設計采用div css有什么好處?
答:布局實現了表現與內容的分離,大大縮減頁面代碼,符合W3C的標準,兼容性更好;易于后期網站的更新、維護;SEO的優化:對搜索引擎更加友好,更容易被搜索引擎收錄。
2、前端頁面有哪三層構成,分別是什么?作用是什么?
答:網頁分成三個層次,即:結構層、表示層、行為層。
網頁的結構層(structural layer)由HTML或 XHTML之類的標記語言負責創建。標簽,也就是那些出現在尖括號里的單詞,對網頁內容的語義含義做出了描述,但這些標簽不包含任何關于如何顯示有關內容的信息。例如,P 標簽表達了這樣一種語義:“這是一個文本段。”
網頁的表示層(presentation layer)由CSS負責創建。CSS 對“如何顯示有關內容”的問題做出了回答。
網頁的行為層(behavior layer)負責回答“內容應該如何對事件做出反應”這一問題。這是 Javascript 語言和 DOM 主宰的領域。
3、如何區別display:none與visibility:hidden?
答:相同的是display:none與visibility:hidden都可以用來隱藏某個元素;
不同的是display:none在隱藏元素的時候,將其占位空間也去掉;而visibility:hidden只是隱藏了內容而已,其占位空間仍然保留。
4.購物網站的主色調應該是什么樣色?交友網站?體育網站?軟件網站?年輕的互聯網? 答:購物:暖色;交友:粉紅之類的;體育:酷一點;軟件公司:無所謂;年輕互聯網:有朝氣的顏色,比如綠色。
5. 一個網站最多有幾種色彩
答:一到兩各種主色彩。
6.如果背景是黑色,那么字體用什么顏色能突出字體,且不顯得刺眼?
答:紅色。
五.編程操作題(每題6分,30分)
注:有上機機會上機操作,沒有就手動把代碼寫出來;
1.一個表td中的部分Id有多個記錄,把所有有多個記錄的id查出來,并顯示共有多少條 記錄數。
2.寫出冒泡排序的實現
答:代碼如下:
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; } } } }編程:編寫一個截取字符串的函數,輸入為一個字符串和字節數,輸出為按字節截取的字符串。但是要保證漢字不被截半個,如“我ABC”4,應該截為“我AB”,輸入“我ABC漢DEF”,應該輸出為“我ABC”而不是“我ABC 漢的半個”。 答:代碼如下: 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中國43中國人 0ewldfls=103”,4); ss.SplitIt(); } } 注:另外關于美工操作,如果有photoshop等軟件可以任選擇兩題考下: 1.手寫 html 能力 描述一個不規則表格,一定要有跨列和跨行的,讓他把 html 代碼寫出來; 2.讓他用 Photoshop 或 Fireworks 設計一個頁面布局,或者指定一個效果(比如半透明的按鈕),讓他畫出來,在或者,提供一幅人物照片,要求他摳掉背景,這是平面軟件能力的一種體現方式; 3.如果要涉及 Flash,讓他做一個兩種形狀(方形、圓圈)的漸變,要求過渡平滑、美觀,新手都直接用 shapemotion,很難看,高手知道加過渡。 1、面向對象的四個特征:封裝、繼承、多態、抽象 封裝: 繼承:子類繼承父類,除private修飾以外的所以方法和屬性 多態:一個對象多種狀態,可以把子類對象當作父類對象來看,一旦這樣做了,就只能 去調用父類中原有定義的屬性和方法,也就是子類中擴展的方法或屬性就不能調用了。 抽象: 2、abstractclass 和interface的區別 聲明方法的存在而不去實現它的類被叫做抽象類(abstract class),它用于要創建一個體現某些基本行為的類,并為該類聲明方法,但不能在該類中實現該類的情況。不能創建abstract 類的實例。然而可以創建一個變量,其類型是一個抽象類,并讓它指向具體子類的一個實例。不能有抽象構造函數或抽象靜態方法。Abstract 類的子類為它們父類中的所有抽象方法提供實現,否則它們也是抽象類為。取而代之,在子類中實現該方法。知道其行為的其它類可以在類中實現這些方法。 接口(interface)是抽象類的變體。在接口中,所有方法都是抽象的。多繼承性可通過實現這樣的接口而獲得。接口中的所有方法都是抽象的,沒有一個有程序體。接口只可以定義static final成員變量。接口的實現與子類相似,除了該實現類不能從接口定義中繼承行為。當類實現特殊接口時,它定義(即將程序體給予)所有這種接口的方法。然后,它可以在實現了該接口的類的任何對象上調用接口的方法。由于有抽象類,它允許使用接口名作為引用變量的類型。通常的動態聯編將生效。引用可以轉換到接口類型或從接口類型轉換,instanceof 運算符可以用來決定某對象的類是否實現了接口。 3、final、finally、finalize的區別 final 用于聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。finally是異常處理語句結構的一部分,表示總是執行。 finalize是Object類的一個方法,在垃圾收集器執行的時候會調用被回收對象的此方法,可以覆蓋此方法提供垃圾收集時的其他資源回收,例如關閉文件等。 4、匿名內部類是否可以作為父類被其他類繼承,或做為接口被實現? 匿名內部類不被繼承也不能被實現,因為它沒有名字,而一個內部類只要有名字就可以作為父類被繼承,也可以作為借口被實現。 5、多線程有幾種實現方法,同步有幾種實現方法,都是什么? 多線程有兩種實現方法,分別繼承繼承Thread類與實現runnable借口。 同步的實現方法有兩種,分別是synchronized,wait與notify。 6、string 與 stringbuffer的區別? String的長度是不可變的,而stringbuffer的長度是可變的。如果你對字符中的內容經常進行操作,特別是內容修改時,那么就要使用stringbuffer,如果最后需要使用string,那么使用stringbuffer的tostring()方法。 7、解析XML文件的幾種方式和區別 DOM:處理大型文件時其性能下降的非常厲害 SAX:SAX是事件驅動型的XML解析方式,它是順序讀取XML文件,不需要一次性全部裝載整個文件。 8、sleep()和wait()有什么區別? sleep是線程類(Thread)的方法,導致此線程暫停執行指定時間,給執行機會給其他線程,但是監控狀態依然保持,到時后會自動恢復。調用sleep不會釋放對象鎖。 wait是Object類的方法,對此對象調用wait方法導致本線程放棄對象鎖,進入等待此對象的等待鎖定池,只有針對此對象發出notify方法(或notifyAll)后本線程才進入對象鎖定池準備獲得對象鎖進入運行狀態。 9、數組有沒有length這個方法?string有沒有length這個方法? 數組沒有length()這個方法,有length這個屬性 String有length()這個方法 10、LinkedList、ArrayList和Vector的區別? ArrayList和Vector是采用數組方式存儲數據,此數組元素總數大于實際存儲的數據個數以便增加和插入元素,二者都允許直接序號索引元素,但是插入數據要移動數組元素等內存操作,所以它們索引數據快、插入數據慢。 Vector由于使用了synchronized同步方法(如add、insert、remove、set、equals、hashcode等操作),因此是線程安全,性能上比ArrayList要差。 LinkedList使用雙向鏈表實現存儲,按序號索引數據需要進行向前或向后遍歷,但是插入數據時只需要記錄本項的前后項即可,所以插入數度較快!LinkedList雙向鏈表,是指可以從first依次遍歷至last(從頭到尾),也可以從last遍歷至first(從尾到頭),但首尾沒有構成環,不同于雙向循環鏈表(注意區分): 11、hashmap與hashtable的區別? 都屬于Map接口的類,實現了將惟一鍵映射到特定的值上。 HashMap類沒有分類或者排序。它允許一個null鍵和多個null值。 Hashtable類似于HashMap,但是不允許null鍵和null值。它也比HashMap慢,因為它是同步的。 12、Jsp有哪些內置對象,作用分別是什么?(至少能說出五個) 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實例 13、Javaservletapi中forward()與redirect()的區別? 前者僅是容器中控制權的轉向,在客戶端瀏覽器地址欄中不會顯示出轉向后的地址;后者則是完全的跳轉,瀏覽器將會得到跳轉的地址,并重新發送請求鏈接。這樣,從瀏覽器的地址欄中可以看到跳轉后的鏈接地址。所以,前者更加高效,在前者可以滿足需要時,盡量使用forward()方法,并且,這樣也有助于隱藏實際的鏈接。在有些情況下,比如,需要跳轉到一個其它服務器上的資源,則必須使用sendRedirect()方法。 14、重載(overload)與重寫(override)的區別? Overload:方法名相同,參數不同,與返回值無關 Override:方法名相同,參數相同,相同的返回值,建立在繼承的基礎之上 15、什么是單例模式,在程序中如何使用? 單例模式確保一個類只有一個實例 餓漢式單例類 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生命周期? 加載和實例化 初始化init() 請求處理service() 服務終止destroy() 17、spring中IOC與AOP的含義? IOC:控制反轉,是一種設計模式,一層含義控制權的轉移,由傳統的在程序中控制依賴轉移到由容器來控制,第二層是依賴注入將互相依賴的對象分離,在spring配置文件中描述它們的依賴關心,它們的依賴關系只是在使用的時候才建立 AOP:面向切面,是一種編程思想,oop的延續,將系統中非核心的業務提取出來,進行單獨的處理,比如事務、日志和安全等 Spring的AOP和IOC都是為了解決系統代碼耦合度過高的問題,使用代碼重用性高,易于維護,不過AOP和IOC并不是spring中特有的,只是spring把它們應用的更靈活方便。 18、hibernate與JDBC的區別? 相同點: 1>兩者都是JAVA的數據庫操作中間件。 2>兩者對于數據庫進行直接操作的對象都不是線程安全的,都需要及時關閉。 3>兩者都可以對數據庫的更新操作進行顯式的事務處理。 不同點: 1>使用的SQL語言不同:JDBC使用的是基于關系型數據庫的標準SQL語言,Hibernate使用的是HQL(Hibernate query language)語言 2>操作的對象不同:JDBC操作的是數據,將數據通過SQL語句直接傳送到數據庫中執行,Hibernate操作的是持久化對象,由底層持久化對象的數據更新到數據庫中。3>數據狀態不同:JDBC操作的數據是“瞬時”的,變量的值無法與數據庫中的值保持一致,而Hibernate操作的數據是可持久的,即持久化對象的數據屬性的值是可以跟數據庫中的值保持一致的。 19、struts中的標簽庫有幾種,分別是? 有5種標簽,分別是:bean標簽庫、html標簽庫、logic標簽庫、tiles標簽庫nested標簽庫 20、Error與Exception有什么區別? Error表示系統級的錯誤和程序不必處理的異常,Exception表示需要捕捉或者需要程序進行處理的異常。 21、Collection和Collections的區別。 Collection是集合類的上級接口,繼承與他的接口主要有Set 和List.Collections是針對集合類的一個幫助類,他提供一系列靜態方法實現對各種集合的搜索、排序、線程安全化等操作 22、GC是什么?為什么要有GC?(基礎)。 GC是垃圾收集器。Java程序員不用擔心內存管理,因為垃圾收集器會自動進行管理。 要請求垃圾收集,可以調用下面的方法之一: System.gc() Runtime.getRuntime().gc() 23、啟動一個線程是用run()還是start()? 啟動一個線程是調用start()方法,使線程所代表的虛擬處理機處于可運行狀態,這意味著它可以由JVM調度并執行。這并不意味著線程就會立即運行。run()方法可以產生必須退出的標志來停止一個線程。 24、&和&&的區別。 &是位運算符,表示按位與運算,&&是邏輯運算符,表示邏輯與(and)。 25、heap和stack有什么區別。 棧是一種線形集合,其添加和刪除元素的操作應在同一段完成。棧按照后進先出的方 式進行處理。 堆是棧的一個組成元素 26、List, Set, Map是否繼承自Collection接口? List,Set是,Map不是 27、MVC的各個部分都有那些技術來實現?如何實現? MVC 是Model-View-Controller的簡寫。“Model” 代表的是應用的業務邏輯(通過JavaBean,EJB組件實現),“View” 是應用的表示面(由JSP頁面產生),“Controller” 是提供應用的處理過程控制(一般是一個Servlet),通過這種設計模型把應用邏輯,處理過程和顯示邏輯分成不同的組件實現。這些組件可以進行交互和重用。 28、Static Nested Class 和 Inner Class的不同。 Static Nested Class是被聲明為靜態(static)的內部類,它可以不依賴于外部類實例被實例化。而通常的內部類需要在外部類實例化后才能實例化。 29、接口是否可繼承接口? 抽象類是否可實現(implements)接口? 抽象類是否可繼承實體類 (concrete class)? 接口可以繼承接口。抽象類可以實現(implements)接口,抽象類是否可繼承實體類,但前提是實體類必須有明確的構造函數 30、JSP和Servlet有哪些相同點和不同點,他們之間的聯系是什么? JSP 是Servlet技術的擴展,本質上是Servlet的簡易方式,更強調應用的外表表達。JSP編譯后是“類servlet”。Servlet和JSP最主要的不同點在于,Servlet的應用邏輯是在Java文件中,并且完全從表示層中的HTML里分離開來。而JSP的情況是Java和HTML可以組合成一個擴展名為.jsp的文件。JSP側重于視圖,Servlet主要用于控制邏輯 31、當一個線程進入一個對象的一個synchronized方法后,其它線程是否可進入此對象的其它方法? 不能,一個對象的一個synchronized方法只能由一個線程訪問。 32、運行時異常與一般異常有何異同? 異常表示程序運行過程中可能出現的非正常狀態,運行時異常表示虛擬機的通常操作中可能遇到的異常,是一種常見運行錯誤。java編譯器要求方法必須聲明拋出可能發生的非運行時異常,但是并不要求必須聲明拋出未被捕獲的運行時異常。 33、JSP中動態INCLUDE與靜態INCLUDE的區別? 動態INCLUDE用jsp:include動作實現 靜態INCLUDE用include偽碼實現,定不會檢查所含文件的變化,適用于包含靜態頁面<%@ include file=“included.htm” %> 1、你怎樣理解Struts,又那些配置文件,以及作用? 理解:http://ruixin.iteye.com/blog/899289 配置文件:struts.xml 作用:struts 框架mvc 實現低耦合,便于程序的維護~ 配置文件控制流程的轉向 很清晰~ 主要負責具體業務的實現和頁面的轉向~ 2、怎么樣來捕獲數據庫中的異常? 3、如何處理網頁中的驗證信息,如何友好的進行處理? 4、用javaScript實現java中的監聽器功能? 5、你對對日外包的看法? 6、數據庫連接方式由哪幾種? Jdbc、連接池、hibernate 7、你清楚哪幾種設計模式,談談各種設計模式的類結構。 8、談談jsp和sevlet的區別,以及它們性能上的區別。 jsp是servlet的一種簡化,jsp編譯后是“類servlet”。servlet 主要是用來處理業務層; jsp 則是主要負責 表現層。 servlet完全是java程序代碼構成,擅長于流程控制和事務處理,而通過servlet來生成動態網頁很不直觀; 對于靜態的html標簽,servlet都必須使用頁面輸出流逐行輸出。Servlet中沒有內置對象。Jsp由html代碼和jsp標簽構成可以方便地編寫動態網頁,在struts框架中,jsp位于MVC設計模式的視圖層,而servlet位于控制層。 總之,使用jsp只需要完成程序員需要輸出到客戶端的內容,至于jsp中的java腳本如果鑲嵌到一個類中,由jsp容器完成,而servlet則是個完整的java類,這個類的service方法用于生成對客戶端的響應 9、如何來編寫存儲過程,如何優化存儲過程,以及存儲過程和TSQL的區別。 10、提供的培訓,CMM-5軟件開發流程培訓、代碼編寫規范和業務流程培訓、對日語的培訓。 1、為什么要選擇這個行業,和計算機專業的相比有什么優勢? 2、Servlet是什么,以及生命周期? Servlet被服務器實例化后,容器運行其init方法,請求到達時運行其service方法,service方法自動派遣運行與請求對應的doXXX方法(doGet,doPost)等,當服務器決定將實例銷毀的時候調用其destroy方法。 與cgi的區別在于servlet處于服務器進程中,它通過多線程方式運行其service方法,一個實例可以服務于多個請求,并且其實例一般不會銷毀,而CGI對每個請求都產生新的進程,服務完成后就銷毀,所以效率上低于servlet。 3、怎么理解事務? 4、怎么理解MVC? 自己做自己的事情,主要強調分層,5、同時插入大量數據,使用何種方法優化?Batch 6、多個有關系得怎么樣操作? 7、你認為你還有什么優點在前面沒有提到? 8、對加班的看法? 9、與上級意見不一致時怎么樣處理?10、11、12、13、14、15、16、17、18、19、20、21、22、23、你如何理解團隊精神? 你怎樣處理學習新技術和項目開發之間的矛盾? 怎樣去學習新技術? 作為一個初級程序員怎么樣彌補與有經驗程序員之間的差距? 你對索引的理解,索引有幾種,什么時候用索引? 對Oracle理解? 怎樣優化復雜的查詢語句? 你對Jdbc理解? 對Finally塊的理解和應用? 游標的理解? ResultSet 重載,重寫? 簽名 EJB的事務,Hibernate的事務? Struts的標簽? 重定向和跳轉? A、 a.地址欄不改變跳轉——服務器端跳轉,服務器之間內部轉,相同的request,可傳參; b.執行到跳轉語句后無條件立刻跳轉——之后的代碼不再被執行; 注意:如果使用forward跳轉,則一定要在跳轉之前釋放掉全部的資源; c.使用forward時,request設置的屬性依然能保留在下一個頁面(setAttribute);d.通過 e.地址中的”/”代表是:http://localhost:8080/Test B、response.sendRedirect(“地址”):效率低,速度慢 a.地址欄改變跳轉——客戶端跳轉(其中地址可以是任意的) b.所有代碼執行完畢之后再跳轉,跳轉語句后面的代碼還是會執行,除非在其后面加上return(return)需復雜一些。 <% Response.sendRedirect(“aa.jsp”);boolean b = true; if(b){ Return;} System.out.println(“aaaaaaaaaa”);%> c.不能保存request屬性——地址改變了,客戶端跳轉,不同的request d.通過對URL地址的重寫傳遞參數: response.sendRedirect(“responseDemo04.jsp?id=mldn”); e.地址中的”/”代表是:http://localhost:8080/ 下面是兩種比較重要的跳轉,我還是與上次的一次,把我做的筆記貼出來:24、25、Hibernate的左聯結和右連接,緩存,數據加載? 面向對象如何理解? 26、EJB中CMP和BMP,SessionBean的機制?27、28、29、對日外包是否有抵觸情緒? 如何減少Servlet的請求? 對設計模式了解多少?作過的項目中用過那些設計模式? 30、31、32、33、34、35、36、37、38、39、40、41、42、43、44、45、怎樣看待團隊合作,在團隊合作中你扮演什么樣的角色,遇到技術難題時怎么解決? Exception的層次結構? EJB對數據庫的訪問機制? Struts中是否有事務處理? Hibernate的其它功能(除了ORM)? 如何提高數據庫中的數據查詢效率? 作為項目經理如何對組內成員分工? 描述一下你做過項目的流程。 加班到12點,突然有人來問你技術上的難題,你會如何處理? Oracle的冷備份、熱備份 Strurs中怎樣實現 Hibernate怎樣實現ORM Spring 的事務處理機制 Strurs的驗證方式,Javascript的驗證的方式 一個是服務器端驗證,一個是客戶端驗證 Struts的工作機制 Delete/trancate的區別 trancate與delete都是刪除數據,不同的是trancate是將表的所有數據都刪除,而delete可以有選擇地刪除數據; delete刪除數據是記錄在日志中的,可以通過其將數據恢復,而trancate則是將整個表截斷,其操作是不記錄在日志里的。46、47、48、作為項目組長,你遇到的最大問題是什么?如何解決? Ajax/內嵌框架實現局部刷新,有什么差別? Exception/Error的區別,在什么情況下可以拋出RuntimeException 父類不同 知道異常和錯誤最本質的區別就是異常能被開發人員處理而錯誤時系統本來自帶的,一般無法處理也不需要我們程序員來處理。 在程序運行時候出錯而又不是系統原因差生的,一般是由于程序原因產生,比如程序寫的不夠嚴謹、完善 典型的RuntimeException 有 ArithmeticException、ClassCastException、IndexOutOfBoundsException、NullPointerException、UnsupportedOperationException 等.49、50、51、52、53、54、55、56、57、58、59、Orcale 物化視圖(MV) 業務處理模塊中,是如何處理事務? Sql語句如何優化 數據庫右連接 JDBC的連接關閉在哪? Finally語句塊內 錯誤處理模塊是放在哪個層的。接口能否繼承接口。 接口可以繼承接口..但是要使用extends~而不是用implements 抽象類能否繼承實體類。 抽象類是可以繼承實體類,但前提是實體類必須有明確的構造函數 答案很明確,可以繼承。 項目中查詢時怎么樣實現的? 作為項目負責人你是管理這個團隊的? 在你做項目過程中遇到些什么問題,是怎么樣解決的? Jquery中的幾種選擇器: Javascript如何進行數字和字符串之間的轉換? 數字類型轉換成String類型用 對象=對象.toString()方法,字符串轉換成數字類型則是對象=Number(對象); 1、一個“.java”源文件中是否可以包括多個類(不是內部類)?有什么限制? 可以有多個類,但只能有一個public的類,并且public的類名必須與文件名相一致。 3、說說&和&&的區別。 &和&&都可以用作邏輯與的運算符,表示邏輯與(and),當運算符兩邊的表達式的結果都為true時,整個運算結果才為true,否則,只要有一方為false,則結果為false。 &&還具有短路的功能,即如果 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。 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方法究竟有什么區別? ==操作符專門用來比較兩個變量的值是否相等,也就是用于比較變量所對應的內存中所存儲的數值是否相同,要比較兩個基本類型的數據或兩個引用變量是否相等,只能用==操作符。 equals方法是用于比較兩個獨立對象的內容是否相同,就好比去比較兩個人的長相是否相同,它比較的兩個對象是獨立的。例如,對于下面的代碼: 12、靜態變量和實例變量的區別? 在語法定義上的區別:靜態變量前要加static關鍵字,而實例變量前則不加。在程序運行時的區別:實例變量屬于某個對象的屬性,必須創建了實例對象,其中的實例變量才會被分配空間,才能使用這個實例變量。靜態變量不屬于某個實例對象,而是屬于類,所以也稱為類變量,只要程序加載了類的字節碼,不用創建任何實例對象,靜態變量就會被分配空間,靜態變量就可以被使用了。總之,實例變量必須創建對象后才可以通過這個對象來使用,靜態變量則可以直接使用類名來引用。 13、是否可以從一個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層的表單數據的類型。 在Hibernate中,如果將OID定義為Integer類型,那么Hibernate就可以根據其值是否為null而判斷一個對象是否是臨時的,如果將OID定義為了int類型,還需要在hbm映射文件中設置其unsaved-value屬性為0。 另外,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.floor(11.6)的結果為11,Math.floor(-11.6)的結果是-12;round方法,它表示“四舍五入”,算法為Math.floor(x+0.5),即將原來的數字加上0.5后再向下取整,所以,Math.round(11.5)的結果為12,Math.round(-11.5)的結果為-11。 15、下面的代碼有什么不妥之處? 1.if(username.equals(“zxx”){} 如果username=null;會報異常,而且少個括號結束。 2.int x = 1;return x==1?true:false;X==1返回的本來就是boolean類型 后面的true:false是多余的.16、請說出作用域public,private,protected,以及不寫時的區別 這四個作用域的可見范圍如下表所示。 說明:如果在修飾的元素上面沒有寫任何訪問修飾符,則表示friendly。 作用域 當前類 同一package 子孫類 其他package public √ √ √ √ protected √ √ √ × friendly √ √ × × private √ × × × 備注:只要記住了有4種訪問權限,4個訪問范圍,然后將全選和范圍在水平和垂直方向上分別按排從小到大或從大到小的順序排列,就很容易畫出上面的圖了。 17、Overload和Override的區別(觀察者和被觀察者模式)。Overloaded的方法是否可以改變返回值的類型? Overload是重載的意思,Override是覆蓋的意思,也就是重寫。 重載Overload表示同一個類中可以有多個名稱相同的方法,但這些方法的參數列表各不相同(即參數個數或類型不同)。 重寫Override表示子類中的方法可以與父類中的某個方法的名稱和參數完全相同,通過子類創建的實例對象調用這個方法時,將調用子類中的定義方法,這相當于把父類中定義的那個完全相同的方法給覆蓋了,這也是面向對象編程的多態性的一種表現。子類覆蓋父類的方法時,只能比父類拋出更少的異常,或者是拋出父類拋出的異常的子異常,因為子類可以解決父類的一些問題,不能比父類有更多的問題。子類方法的訪問權限只能比父類的更大,不能更小。如果父類的方法是private類型,那么,子類則不存在覆蓋的限制,相當于子類中增加了一個全新的方法。 至于Overloaded的方法是否可以改變返回值的類型這個問題,要看你倒底想問什么呢?這個題目很模糊。如果幾個Overloaded的方法的參數列表不一樣,它們的返回者類型當然也可以不一樣。但我估計你想問的問題是:如果兩個方法的參數列表完全一樣,是否可以讓它們的返回值不同來實現重載Overload。這是不行的,我們可以用反證法來說明這個問題,因為我們有時候調用一個方法時也可以不定義返回結果變量,即不要關心其返回結果,例如,我們調用map.remove(key)方法時,雖然remove方法有返回值,但是我們通常都不會定義接收返回結果的變量,這時候假設該類中有兩個名稱和參數列表完全相同的方法,僅僅是返回類型不同,java就無法確定編程者倒底是想調用哪個方法了,因為它無法通過返回結果類型來判斷。 override可以翻譯為覆蓋,從字面就可以知道,它是覆蓋了一個方法并且對其重寫,以求達到不同的作用。對我們來說最熟悉的覆蓋就是對接口方法的實現,在接口中一般只是對方法進行了聲明,而我們在實現時,就需要實現接口聲明的所有方法。除了這個典型的用法以外,我們在繼承中也可能會在子類覆蓋父類中的方法。在覆蓋要注意以下的幾點: 1、覆蓋的方法的標志必須要和被覆蓋的方法的標志完全匹配,才能達到覆蓋的效果; 2、覆蓋的方法的返回值必須和被覆蓋的方法的返回一致; 3、覆蓋的方法所拋出的異常必須和被覆蓋方法的所拋出的異常一致,或者是其子類; 4、被覆蓋的方法不能為private,否則在其子類中只是新定義了一個方法,并沒有對其進行覆蓋。 overload對我們來說可能比較熟悉,可以翻譯為重載,它是指我們可以定義一些名稱相同的方法,通過定義不同的輸入參數來區分這些方法,然后再調用時,VM就會根據不同的參數樣式,來選擇合適的方法執行。在使用重載要注意以下的幾點: 1、在使用重載時只能通過不同的參數樣式。例如,不同的參數類型,不同的參數個數,不同的參數順序(當然,同一方法內的幾個參數類型必須不一樣,例如可以是fun(int,float),但是不能為fun(int,int)); 2、不能通過訪問權限、返回類型、拋出的異常進行重載; 3、方法的異常類型和數目不會對重載造成影響; 4、對于繼承來說,如果某一方法在父類中是訪問權限是priavte,那么就不能在子類對其進行重載,如果定義的話,也只是定義了一個新方法,而不會達到重載的效果。 18、說說對javaee中的session的理解,你是怎么用session的? 在Java Servlet API中引入session機制來跟蹤客戶的狀態。session指的是在一段時間內,單個客戶與Web服務器的一連串相關的交互過程。在一個session中,客戶可能會多次請求同一個網頁,也有可能請求訪問各種不同的服務器資源。例如在電子郵件應用中,從一個客戶登錄到電子郵件系統開始,經過收信,寫信,和發信等,直至退出郵件系統,整個過程為一個session。再比如,在網上書店應用中,從一個客戶開始購物,到最后結賬,整個過程為一個session。 會話的創建:HttpSession session = request.getSession(boolean value);HttpSession session = request.getSession();會話的使用:javax.servlet.http.HttpSession接口中定義的方法,我們常用的是有關進行數據存取的方法。 session.setAttribute(String name , Object value);session.getAttribute(String name); 19、說說has a與is a的區別。 is-a表示的是屬于得關系。比如兔子屬于一種動物(繼承關系)。has-a表示組合,包含關系。比如兔子包含有腿,頭等組件; 20、線程如何同步和通訊。 只有多個synchronized代碼塊使用的是同一個監視器對象,這些synchronized代碼塊之間才具有線程互斥的效果,假如a代碼塊用obj1作為監視器對象,假如b代碼塊用obj2作為監視器對象,那么,兩個并發的線程可以同時分別進入這兩個代碼塊中。對于同步方法的分析,所用的同步監視器對象是this 接著對于靜態同步方法的分析,所用的同步監視器對象是該類的Class對象 接著對如何實現代碼塊與方法的同步進行分析。2.ClassLoader如何加載class。 jvm里有多個類加載,每個類加載可以負責加載特定位置的類,例如,bootstrap類加載負責加載jre/lib/rt.jar中的類,我們平時用的jdk中的類都位于rt.jar中。 extclassloader負責加載jar/lib/ext/*.jar中的類,appclassloader負責classpath指定的目錄或jar中的類。除了bootstrap之外,其他的類加載器本身也都是java類,它們的父類是ClassLoader。3.Servlet的生命周期 ? 通常情況下,服務器只會創建一個Servlet實例對象,也就是說Servlet實例對象一旦創建,它就會駐留在內存中,為后續的其它請求服務,直至web容器退出,servlet實例對象才會銷毀。 Web容器退出,調用destory方法,結束servlet; 4.抽象類的作用 5.ArrayList如何實現插入的數據按自定義的方式有序存放 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.分層設計的好處;把各個功能按調用流程進行了模塊化,模塊化帶來的好處就是可以隨意組合,舉例說明:如果要注冊一個用戶,流程為顯示界面并通過界面接收用戶的輸入,接著進行業務邏輯處理,在處理業務邏輯又訪問數據庫,如果我們將這些步驟全部按流水帳的方式放在一個方法中編寫,這也是可以的,但這其中的壞處就是,當界面要修改時,由于代碼全在一個方法內,可能會碰壞業務邏輯和數據庫訪問的碼,同樣,當修改業務邏輯或數據庫訪問的代碼時,也會碰壞其他部分的代碼。分層就是要把界面部分、業務邏輯部分、數據庫訪問部分的代碼放在各自獨立的方法或類中編寫,這樣就不會出現牽一發而動全身的問題了。這樣分層后,還可以方便切換各層,譬如原來的界面是Swing,現在要改成 BS界面,如果最初是按分層設計的,這時候不需要涉及業務和數據訪問的代碼,只需編寫一條web界面就可以了。 下面的僅供參考,不建議照搬照套,一定要改成自己的語言,發現內心的感受: 分層的好處: 1,實現了軟件之間的解耦; 2.便于進行分工 3.便于維護 4,提高軟件組件的重用 5.便于替換某種產品,比如持久層用的是hibernate,需要更換產品用toplink,就不用該其他業務代碼,直接把配置一改。6.便于產品功能的擴展。 7。便于適用用戶需求的不斷變化 7.序列化接口的id有什么用? 對象經常要通過IO進行傳送,讓你寫程序傳遞對象,你會怎么做?把對象的狀態數據用某種格式寫入到硬盤,Person->“zxx,male,28,30000”?Person,既然大家都要這么干,并且沒有個統一的干法,于是,sun公司就提出一種統一的解決方案,它會把對象變成某個格式進行輸入和輸出,這種格式對程序員來說是透明(transparent)的,但是,我們的某個類要想能被sun的這種方案處理,必須實現Serializable接口。 ObjectOutputStream.writeObject(obj);Object obj = ObjectInputStream.readObject();假設兩年前我保存了某個類的一個對象,這兩年來,我修改該類,刪除了某個屬性和增加了另外一個屬性,兩年后,我又去讀取那個保存的對象,或有什么結果?未知!sun的jdk就會蒙了。為此,一個解決辦法就是在類中增加版本后,每一次類的屬性修改,都應該把版本號升級一下,這樣,在讀取時,比較存儲對象時的版本號與當前類的版本號,如果不一致,則直接報版本號不同的錯! 9.hashCode方法的作用?說(網友提供的一段,待改進:hashcode這個方法是用來鑒定2個對象是否相等的。 那你會說,不是還有equals這個方法嗎? 不錯,這2個方法都是用來判斷2個對象是否相等的。但是他們是有區別的。一般來講,equals這個方法是給用戶調用的,如果你想判斷2個對象是否相等,你可以重寫equals方法,然后在代碼中調用,就可以判斷他們是否相等了。簡單來講,equals方法主要是用來判斷從表面上看或者從內容上看,2個對象是不是相等。舉個例子,有個學生類,屬性只有姓名和性別,那么我們可以認為只要姓名和性別相等,那么就說這2個對象是相等的。 hashcode方法一般用戶不會去調用,比如在hashmap中,由于key是不可以重復的,他在判斷key是不是重復的時候就判斷了hashcode這個方法,而且也用到了equals方法。這里不可以重復是說equals和hashcode只要有一個不等就可以了!所以簡單來講,hashcode相當于是一個對象的編碼,就好像文件中的md5,他和equals不同就在于他返回的是int型的,比較起來不直觀。我們一般在覆蓋equals的同時也要覆蓋hashcode,讓他們的邏輯一致。舉個 例子,還是剛剛的例子,如果姓名和性別相等就算2個對象相等的話,那么hashcode的方法也要返回姓名的hashcode值加上性別的hashcode值,這樣從邏輯上,他們就一致了。 要從物理上判斷2個對象是否相等,用==就可以了。) 10.webservice問得很多 11.設計出計算任意正整數的階層。 4.在oracle數據庫中需要查詢出前8條記錄的sql語句怎么寫? Select * from(select *,rownum r from test where r<8) 5.什么是SOA,談談你的SOA的理解。service orientied architecture 面向服務的體系結構(Service-Oriented Architecture,SOA)是一個組件模型,它將應用程序的不同功能單元(稱為服務)通過這些服務之間定義良好的接口和契約聯系起來。接口是采用中立的方式進行定義的,它應該獨立于實現服務的硬件平臺、操作系統和編程語言。這使得構建在各種這樣的系統中的服務可以一種統一和通用的方式進行交互。松耦合的 6.如何實現線程間的通訊。 新題目:編程:1.編寫一個函數將一個十六進制數的字符串參數轉換成整數返回。String str = “13abf”;int len = str.length;int sum = 0;for(int i=0;i 其實,也可以用Integer.parseInt(str,16),但面試官很可能是想考我們的編碼基本功。 編程2 :銀行貸款的還款方式中最常用的是一種叫“等額本息”,還款法,即借款人在約定還款期限內的每一期(月)歸還的金額(產生的利息+部分本金)都是相等的,現有一筆總額為T元的N年期住房貸款,年利率為R,要求算出每一期的還款的本金和利息總額,請寫出解決思路和任意一種編程語言實現的主要代碼。思路:既然是按月還款,那我就要將N年按月來計算,即要還N*12個月,這樣就可以求出每月要還的本金。由于每月要還的那部分本金所欠的時間不同,所以, 它們所產生的利息是不同的,該部分本金的利息為:部分本金額*所欠月數*月利率。應該是這么個算法,如果利息還計利息,如果月還款不按年利率來算,老百姓算不明白的。 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是什么(學員注:除了IOC,AOP這些概念,還不太清楚DI的概念) 什么是DI機制? 依賴注入(Dependecy Injection)和控制反轉(Inversion of Control)是同一個概念,具體的講:當某個角色 需要另外一個角色協助的時候,在傳統的程序設計過程中,通常由調用者來創建被調用者的實例。但在spring中 創建被調用者的工作不再由調用者來完成,因此稱為控制反轉。創建被調用者的工作由spring來完成,然后注入調用者 因此也稱為依賴注入。 spring以動態靈活的方式來管理對象,注入的兩種方式,設置注入和構造注入。 設置注入的優點:直觀,自然 構造注入的優點:可以在構造器中決定依賴關系的順序。 2.*任意數字序列“123456”之類,輸出它們所有的排列組合 2題的答案: String str = “xafdvs”;char[] arr1 = str.toCharArray();char[] arr2 = Arrays.copyOf(arr1,arr1.length);for(int i=0;i 3.*****什么是AOP(學員注:會用,但感覺說不清楚)什么是AOP? 面向切面編程(AOP)完善spring的依賴注入(DI),面向切面編程在spring中主要表現為兩個方面 1.面向切面編程提供聲明式事務管理 2.spring支持用戶自定義的切面 面向切面編程(aop)是對面向對象編程(oop)的補充,面向對象編程將程序分解成各個層次的對象,面向切面編程將程序運行過程分解成各個切面。 AOP從程序運行角度考慮程序的結構,提取業務處理過程的切面,oop是靜態的抽象,aop是動態的抽象,是對應用執行過程中的步驟進行抽象,從而獲得步驟之間的邏輯劃分。 aop框架具有的兩個特征: 1.各個步驟之間的良好隔離性 2.源代碼無關性 spring 的優點? 1.降低了組件之間的耦合性,實現了軟件各層之間的解耦 2.可以使用容易提供的眾多服務,如事務管理,消息服務等 3.容器提供單例模式支持 4.容器提供了AOP技術,利用它很容易實現如權限攔截,運行期監控等功能 5.容器提供了眾多的輔助類,能加快應用的開發 6.spring對于主流的應用框架提供了集成支持,如hibernate,JPA,Struts等 7.spring屬于低侵入式設計,代碼的污染極低 8.獨立于各種應用服務器 9.spring的DI機制降低了業務對象替換的復雜性 10.Spring的高度開放性,并不強制應用完全依賴于Spring,開發者可以自由選擇spring的部分或全部 3題的答案: 1.概念介紹:所謂AOP,即Aspect orientied program,就是面向方面的編程,2.解釋什么是方面:貫穿到系統的各個模塊中的系統一個功能就是一個方面,比如,記錄日志,統一異常處理,事務處理,全限檢查,這些功能都是軟件系統 的一個面,而不是一點,在各個模塊中都要出現。 3.什么是面向方面編程:把系統的一個方面的功能封裝成對象的形式來處理 4.怎么進行面向方面編程:把功能模塊對應的對象作為切面嵌入到原來的各個系統模塊中,采用代理技術,代理會調用目標,同時把切面功能的代碼(對象)加入進來,所以,用spring配置代理對象時只要要配兩個屬性,分別表示目標和切面對象(Advisor)。 3、構造器Constructor是否可被override? 構造器Constructor不能被繼承,因此不能重寫Override,但可以被重載Overload。 4、接口是否可繼承接口? 抽象類是否可實現(implements)接口? 抽象類是否可繼承具體類(concrete class)? 抽象類中是否可以有靜態的main方法? 接口可以繼承接口。抽象類可以實現(implements)接口,抽象類可繼承具體類。抽象類中可以有靜態的main方法。 備注:只要明白了接口和抽象類的本質和作用,這些問題都很好回答,你想想,如果你是java語言的設計者,你是否會提供這樣的支持,如果不提供的話,有什么理由嗎?如果你沒有道理不提供,那答案就是肯定的了。 只有記住抽象類與普通類的唯一區別就是不能創建實例對象和允許有abstract方法。 5、寫clone()方法時,通常都有一行代碼,是什么? clone 有缺省行為,super.clone();因為首先要把父類中的成員復制到位,然后才是復制自己的成員。 6、面向對象的特征有哪些方面 計算機軟件系統是現實生活中的業務在計算機中的映射,而現實生活中的業務其實就是一個個對象協作的過程。面向對象編程就是按現實業務一樣的方式將程序代碼按一個個對象進行組織和編寫,讓計算機系統能夠識別和理解用對象方式組織和編寫的程序代碼,這樣就可以把現實生活中的業務對象映射到計算機系統中。 面向對象的編程語言有封裝、繼承、抽象、多態等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); 比喻:人吃飯,你看到的是左手,還是右手? 7、java中實現多態的機制是什么? 靠的是父類或接口定義的引用變量可以指向子類或具體實現類的實例對象,而程序調用的方法在運行期才動態綁定,就是引用變量所指向的具體實例對象的方法,也就是內存里正在運行的那個對象的方法,而不是引用變量的類型中定義的方法。 8、abstract class和interface有什么區別? 含有abstract修飾符的class即為抽象類,abstract 類不能創建的實例對象。含有abstract方法的類必須定義為abstract class,abstract class類中的方法不必是抽象的。abstract class類中定義抽象方法必須在具體(Concrete)子類中實現,所以,不能有抽象構造方法或抽象靜態方法。如果的子類沒有實現抽象父類中的所有抽象方法,那么子類也必須定義為abstract類型。 接口(interface)可以說成是抽象類的一種特例,接口中的所有方法都必須是抽象的。接口中的方法定義默認為public abstract類型,接口中的成員變量類型默認為public static final。 下面比較一下兩者的語法區別: 1.抽象類可以有構造方法,接口中不能有構造方法。 2.抽象類中可以有普通成員變量,接口中沒有普通成員變量 3.抽象類中可以包含非抽象的普通方法,接口中的所有方法必須都是抽象的,不能有非抽象的普通方法。 4.抽象類中的抽象方法的訪問類型可以是public,protected和(默認類型,雖然 eclipse下不報錯,但應該也不行),但接口中的抽象方法只能是public類型的,并且默認即為public abstract類型。 5.抽象類中可以包含靜態方法,接口中不能包含靜態方法 6.抽象類和接口中都可以包含靜態成員變量,抽象類中的靜態成員變量的訪問類型可以任意,但接口中定義的變量只能是public static final類型,并且默認即為public static final類型。 7.一個類可以實現多個接口,但只能繼承一個抽象類。下面接著再說說兩者在應用上的區別: 接口更多的是在系統架構設計方法發揮作用,主要用于定義模塊之間的通信契約。而抽象類在代碼實現方面發揮作用,可以實現代碼的重用,例如,模板方法設計模式是抽象類的一個典型應用,假設某個項目的所有Servlet類都要用相 同的方式進行權限判斷、記錄訪問日志和處理異常,那么就可以定義一個抽象的基類,讓所有的Servlet都繼承這個抽象基類,在抽象基類的service方法中完成權限判斷、記錄訪問日志和處理異常的代碼,在各個子類中只是完成各自的業務邏輯代碼,偽代碼如下: public abstract class BaseServlet extends HttpServlet { public final 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個方面逐一去比較回答,接著從 9、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應該是作用在一個具體的方法上才有意義。而且,方法上的synchronized同步所使用的同步鎖對象是this,而抽象方法上無法確定this是什么。 10、什么是內部類?Static Nested Class 和 Inner Class的不同。 內部類就是在一個類的內部定義的類,內部類中不能定義靜態成員(靜態成員不是對象的特性,只是為了找一個容身之處,所以需要放到一個類中而已,這么一點小事,你還要把它放到類內部的一個類中,過分了啊!提供內部類,不是為讓你干這種事情,無聊,不讓你干。我想可能是既然靜態成員類似c語言的全局變量,而內部類通常是用于創建內部對象用的,所以,把“全局變量”放在內部類中就是毫無意義的事情,既然是毫無意義的事情,就應該被禁止),內部類可以直接訪問外部類中的成員變量,內部類可以定義在外部類的方法外面,也可以定義在外部類的方法體中,如下所示: public class Outer { int out_x = 0;public void method() { Inner1 inner1 = new Inner1();public 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寫代碼試試,根據開發工具提示的各類錯誤信息就可以馬上了解到。 在方法體內部還可以采用如下語法來創建一種匿名內部類,即定義某一接口或類的子類的同時,還創建了該子類的實例對象,無需為該子類定義名稱: public class Outer { public void start(){ new Thread(new Runable(){ public void run(){};}).start();} } 最后,在方法外部定義的內部類前面可以加上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的成員變量,不需要加上外部類的名字。 在靜態方法中定義的內部類也是Static Nested Class,這時候不能在類前面加static關鍵字,靜態方法中的Static Nested Class與普通方法中的內部類的應用方式很相似,它除了可以直接訪問外部類中的static的成員變量,還可以訪問靜態方法中的局部變量,但是,該局部變量前必須加final修飾符。 備注:首先根據你的印象說出你對內部類的總體方面的特點:例如,在兩個地方可以定義,可以訪問外部類的成員變量,不能定義靜態成員,這是大的特點。然后再說一些細節方面的知識,例如,幾種定義方式的語法區別,靜態內部類,以及匿名內部類。 11、內部類可以引用它的包含類的成員嗎?有沒有什么限制? 完全可以。如果不是靜態內部類,那沒有什么限制! 如果你把靜態嵌套類當作內部類的一種特例,那在這種情況下不可以訪問外部類的普通成員變量,而只能訪問外部類中的靜態成員,例如,下面的代碼: class Outer { static int x;static class Inner { void test(){ syso(x);} } } 答題時,也要能察言觀色,揣摩提問者的心思,顯然人家希望你說的是靜態內部類不能訪問外部類的成員,但你一上來就頂牛,這不好,要先順著人家,讓人家滿意,然后再說特殊情況,讓人家吃驚。 12、Anonymous Inner Class(匿名內部類)是否可以extends(繼承)其它類,是否可以implements(實現)interface(接口)? 可以繼承其他類或實現其他接口。不僅是可以,而是必須! 13、super.getClass()方法調用 下面程序的輸出結果是多少? 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());} } 很奇怪,結果是Test 這屬于腦筋急轉彎的題目,在一個qq群有個網友正好問過這個問題,我覺得挺有趣,就研究了一下,沒想到今天還被你面到了,哈哈。 在test方法中,直接調用getClass().getName()方法,返回的是Test類名 由于getClass()在Object類中定義成了final,子類不能覆蓋該方法,所以,在 test方法中調用getClass().getName()方法,其實就是在調用從父類繼承的getClass()方法,等效于調用super.getClass().getName()方法,所以,super.getClass().getName()方法返回的也應該是Test。如果想得到父類的名稱,應該用如下代碼: getClass().getSuperClass().getName(); 14.jdk中哪些類是不能繼承的? 不能繼承的是類是那些用final關鍵字修飾的類。一般比較基本的類型或防止擴展類無意間破壞原來方法的實現的類型都應該是final的,在jdk中System,String,StringBuffer等都是基本類型。 2、String是最基本的數據類型嗎? 基本數據類型包括byte、int、char、long、float、double、boolean和short。java.lang.String類是final類型的,因此不可以繼承這個類、不能修改這個類。為了提高效率節省空間,我們應該用StringBuffer類 111、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。 41、是否可以繼承String類? String類是final類故不可以繼承。 27、String s = new String(”xyz“);創建了幾個String Object? 二者之間有什么區別? 兩個或一個,”xyz”對應一個對象,這個對象放在字符串常量緩沖區,常量”xyz”不管出現多少遍,都是緩沖區中的那一個。New String每寫一遍,就創建一個新的對象,它一句那個常量”xyz”對象的內容來創建出一個新String對象。如果以前就用過’xyz’,這句代表就不會創建”xyz”自己了,直接從緩沖區拿。 5、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;} 在講兩者區別時,應把循環的次數搞成10000,然后用endTime-beginTime來比較兩者執行的時間差異,最后還要講講StringBuilder與StringBuffer的區別。 String覆蓋了equals方法和hashCode方法,而StringBuffer沒有覆蓋equals方法和hashCode方法,所以,將StringBuffer對象存儲進Java集合類中時會出現問題。 8.StringBuffer與StringBuilder的區別 StringBuffer和StringBuilder類都表示內容可以被修改的字符串,StringBuilder是線程不安全的,運行效率高,如果一個字符串變量是在方法里面定義,這種情況只可能有一個線程訪問它,不存在不安全的因素了,則用StringBuilder。如果要在類里面定義成員變量,并且這個類的實例對象會在多線程環境下使用,那么最好用StringBuffer。 3、如何把一段逗號分割的字符串轉換成一個數組? 如果不查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();} 38、數組有沒有length()這個方法? String有沒有length()這個方法? 數組沒有length()這個方法,有length的屬性。String有有length()這個方法。 39、下面這條語句一共創建了多少個對象:String s=”a“+”b“+”c“+”d“;答:對于如下代碼: String s1 = ”a“;String s2 = s1 + ”b“;String s3 = ”a“ + ”b“;System.out.println(s2 == ”ab“);System.out.println(s3 == ”ab“); } finally { ++x;} } } ---------執行結果---------1 運行結果是1,為什么呢?主函數調用子函數并得到結果的過程,好比主函數準備一個空罐子,當子函數要返回結果時,先把結果放在罐子里,然后再將程序邏輯返回到主函數。所謂返回,就是子函數說,我不運行了,你主函數繼續運行吧,這沒什么結果可言,結果是在說這話之前放進罐子里的。 7、下面的程序代碼輸出的結果是多少? 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語句后執行 12、final, finally, finalize的區別。 final 用于聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。 內部類要訪問局部變量,局部變量必須定義成final類型,例如,一段代碼…… finally是異常處理語句結構的一部分,表示總是執行。 finalize是Object類的一個方法,在垃圾收集器執行的時候會調用被回收對象的此方法,可以覆蓋此方法提供垃圾收集時的其他資源回收,例如關閉文件等。JVM不保證此方法總被調用 5、運行時異常與一般異常有何異同? 異常表示程序運行過程中可能出現的非正常狀態,運行時異常表示虛擬機的通常操作中可能遇到的異常,是一種常見運行錯誤。java編譯器要求方法必須聲明拋出可能發生的非運行時異常,但是并不要求必須聲明拋出未被捕獲的運行時異常。 15、error和exception有什么區別? error 表示恢復不是不可能但很困難的情況下的一種嚴重問題。比如說內存溢出。不可能指望程序能處理這樣的情況。exception 表示一種設計或實現問題。也就是說,它表示如果程序運行正常,從不會發生的情況。 50、Java中的異常處理機制的簡單原理和應用。 異常是指java程序運行時(非編譯)所發生的非正常情況或錯誤,與現實生活中的事件很相似,現實生活中的事件可以包含事件發生的時間、地點、人物、情節等信息,可以用一個對象來表示,Java使用面向對象的方式來處理異常,它把程序中發生的每個異常也都分別封裝到一個對象來表示的,該對象中包含有異常的信息。 Java對異常進行了分類,不同類型的異常分別用不同的Java類表示,所有異常的根類為java.lang.Throwable,Throwable下面又派生了兩個子類:Error和Exception,Error 表示應用程序本身無法克服和恢復的一種嚴重問題,程序只有死的份了,例如,說內存溢出和線程死鎖等系統問題。Exception表示程序還能 夠克服和恢復的問題,其中又分為系統異常和普通異常,系統異常是軟件本身缺陷所導致的問題,也就是軟件開發人員考慮不周所導致的問題,軟件使用者無法克服和恢復這種問題,但在這種問題下還可以讓軟件系統繼續運行或者讓軟件死掉,例如,數組腳本越界(ArrayIndexOutOfBoundsException),空指針異常(NullPointerException)、類轉換異常(ClassCastException);普通異常是運行環境的變化或異常所導致的問題,是用戶能夠克服的問題,例如,網絡斷線,硬盤空間不夠,發生這樣的異常后,程序不應該死掉。 java為系統異常和普通異常提供了不同的解決方案,編譯器強制普通異常必須try..catch處理或用throws聲明繼續拋給上層調用方法處理,所以普通異常也稱為checked異常,而系統異常可以處理也可以不處理,所以,編譯器不強制用try..catch處理或用throws聲明,所以系統異常也稱為unchecked異常。 提示答題者:就按照三個級別去思考:虛擬機必須宕機的錯誤,程序可以死掉也可以不死掉的錯誤,程序不應該死掉的錯誤; 33、請寫出你最常見到的5個runtime exception。 這道題主要考你的代碼量到底多大,如果你長期寫代碼的,應該經常都看到過一些系統方面的異常,你不一定真要回答出5個具體的系統異常,但你要能夠說出什么是系統異常,以及幾個系統異常就可以了,當然,這些異常完全用其英文名稱來寫是最好的,如果實在寫不出,那就用中文吧,有總比沒有強! 所謂系統異常,就是…..,它們都是RuntimeException的子類,在jdk doc中查RuntimeException類,就可以看到其所有的子類列表,也就是看到了所有的系統異常。我比較有印象的系統異常有:NullPointerException、ArrayIndexOutOfBoundsException、ClassCastException。unknowntypeException illegalArgumentException 96、JAVA語言如何進行異常處理,關鍵字:throws,throw,try,catch,finally分別代表什么意義?在try塊中可以拋出異常嗎? 99、java中有幾種方法可以實現一個線程?用什么關鍵字修飾同步方法? stop()和suspend()方法為何不推薦使用? java5以前,有如下兩種: 表示一個Thread的匿名子類的實例對象,子類加上run方法后的代碼如下: new Thread(){ public void run(){ } }.start(); notify()重新啟動線程。 13、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 { //釋放鎖有兩種方式,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 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、同步和異步有何異同,在什么情況下分別使用他們?舉例說明。 如果數據將在線程間共享。例如正在寫的數據以后可能被另一個線程讀到,或者正在讀的數據可能已經被另一個線程寫過了,那么這些數據就是共享數據,必須進行同步存取。 當應用程序在對象上調用了一個需要花費很長時間來執行的方法,并且不希望讓程序等待方法的返回時,就應該使用異步編程,在很多情況下采用異步途徑往往更有效率。 ten 17.下面兩個方法同步嗎?(自己發明) class Test { synchronized static void sayHello3(){ } synchronized void getX(){} } 56、多線程有幾種實現方法?同步有幾種實現方法? 多線程有兩種實現方法,分別是繼承Thread類與實現Runnable接口 同步的實現方面有兩種,分別是synchronized,wait與notify wait():使一個線程處于等待狀態,并且釋放所持有的對象的lock。 sleep():使一個正在運行的線程處于睡眠狀態,是一個靜態方法,調用此方法要捕捉InterruptedException異常。 notify():喚醒一個處于等待狀態的線程,注意的是在調用此方法的時候,并不能確切的喚醒某一個等待狀態的線程,而是由JVM確定喚醒哪個線程,而且不是按優先級。 Allnotity():喚醒所有處入等待狀態的線程,注意并不是給所有喚醒線程一個對象的鎖,而是讓它們競爭。 30、啟動一個線程是用run()還是start()?.啟動一個線程是調用start()方法,使線程就緒狀態,以后可以被調度為運行狀態,一個線程必須關聯一些具體的執行代碼,run()方法是該線程所關聯的執行代碼。 47、當一個線程進入一個對象的一個synchronized方法后,其它線程是否可進入此對象的其它方法? 分幾種情況: 1.其他方法前是否加了synchronized關鍵字,如果沒加,則能。 2.如果這個方法內部調用了wait,則可以進入其他synchronized方法。 3.如果其他個方法都加了synchronized關鍵字,并且內部沒有調用wait,則不能。 4.如果其他方法是static,它用的同步鎖是當前類的字節碼,與非靜態的方法不能同步,因為非靜態的方法用的是this。 58、線程的基本概念、線程的基本狀態以及狀態之間的關系 一個程序中可以有多條執行線索同時執行,一個線程就是程序中的一條執行線索,每個線程上都關聯有要執行的代碼,即可以有多段程序代碼同時運行,每個程序至少都有一個線程,即main方法執行的那個線程。如果只是一個cpu,它怎么能夠同時執行多段程序呢?這是從宏觀上來看的,cpu一會執行a線索,一會執行b線索,切換時間很快,給人的感覺是a,b在同時執行,好比大家在同一個辦公室上網,只有一條鏈接到外部網線,其實,這條網線一會為a傳數據,一會為b傳數據,由于切換時間很短暫,所以,大家感覺都在同時上網。 狀態:就緒,運行,synchronize阻塞,wait和sleep掛起,結束。wait必須在synchronized內部調用。 調用線程的start方法后線程進入就緒狀態,線程調度系統將就緒狀態的線程轉為運行狀態,遇到synchronized語句時,由運行狀態轉為阻塞,當synchronized獲得鎖后,由阻塞轉為運行,在這種情況可以調用wait方法轉為掛起狀態,當線程關聯的代碼執行完后,線程變為結束狀態。 71、簡述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();} } } } } 28、設計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();} } } } ----------隨手再寫的一個-------------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、子線程循環10次,接著主線程循環100,接著又回到子線程循環10次,接著再回到主線程又循環100,如此循環50次,請寫出程序。 最終的程序代碼如下: 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;//這里相當于定義了控制該誰執行的一個信號燈 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();} } } 備注:不可能一上來就寫出上面的完整代碼,最初寫出來的代碼如下,問題在于兩個線程的代碼要參照同一個變量,即這兩個線程的代碼要共享數據,所以,把這兩個線程的執行代碼搬到同一個類中去: 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中的并發庫來實現的: 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框架的結構 答:隨意發揮題,天南海北誰便談,只要讓別覺得你知識淵博,理解透徹即可。 3、Collection框架中實現比較要實現什么接口 comparable/comparator 3、ArrayList和Vector的區別 答: 這兩個類都實現了List接口(List接口繼承了Collection接口),他們都是有序集合,即存儲在這兩個集合中的元素的位置都是有順序的,相當于一種動態的數組,我們以后可以按位置索引號取出某個元素,并且其中的數據是允許重復的,這是HashSet之類的集合的最大不同處,HashSet之類的集合不可以按索引號去檢索其中的元素,也不允許有重復的元素(本來題目問的與hashset沒有任何關系,但為了說清楚ArrayList與Vector的功能,我們使用對比方式,更有利于說明問題)。 接著才說ArrayList與Vector的區別,這主要包括兩個方面:.(1)同步性: Vector是線程安全的,也就是說是它的方法之間是線程同步的,而ArrayList是線程序不安全的,它的方法之間是線程不同步的。如果只有一個線程會訪問到集合,那最好是使用ArrayList,因為它不考慮線程安全,效率會高些;如果有多個線程會訪問到集合,那最好是使用Vector,因為不需要我們自己再去考慮和編寫線程安全的代碼。 備注:對于Vector&ArrayList、Hashtable&HashMap,要記住線程安全的問題,記住Vector與Hashtable是舊的,是java一誕生就提供了的,它們是線程安全的,ArrayList與HashMap是java2時才提供的,它們是線程不安全的。所以,我們講課時先講老的。(2)數據增長: ArrayList與Vector都有一個初始的容量大小,當存儲進它們里面的元素的個數超過了容量時,就需要增加ArrayList與Vector的存儲空間,每次要增加存儲空間時,不是只增加一個存儲單元,而是增加多個存儲單元,每次增加的存儲單元的個數在內存空間利用與程序效率之間要取得一定的平衡。Vector默認增長為原來兩倍,而ArrayList的增長策略在文檔中沒有明確規定(從源代碼看到的是增長為原來的1.5倍)。ArrayList與Vector都可以設置初始的空間大小,Vector還可以設置增長的空間大小,而ArrayList沒有提供設置增長空間的方法。總結:即Vector增長原來的一倍,ArrayList增加原來的0.5倍。 4、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 5、List 和 Map 區別? 一個是存儲單列數據的集合,另一個是存儲鍵和值這樣的雙列數據的集合,List中存儲的數據是有順序,并且允許重復;Map中存儲的數據是沒有順序的,其鍵是不能重復的,它的值是可以有重復的。 35、List, Set, Map是否繼承自Collection接口? List,Set是,Map不是 109、List、Map、Set三個接口,存取元素時,各有什么特點? 這樣的題屬于隨意發揮題:這樣的題比較考水平,兩個方面的水平:一是要真正明白這些內容,二是要有較強的總結和表述能力。如果你明白,但表述不清楚,在別人那里則等同于不明白。 首先,List與Set具有相似性,它們都是單列元素的集合,所以,它們有一個功共同的父接口,叫Collection。Set里面不允許有重復的元素,所謂重復,即不能有兩個相等(注意,不是僅僅是相同)的對象,即假設Set集合中有了一個A對象,現在我要向Set集合再存入一個B對象,但B對象與A對象equals相等,則B對象存儲不進去,所以,Set集合的add方法有一個boolean的返回值,當集合中沒有某個元素,此時add方法可成功加入該元素時,則返回true,當集合含有與某個元素equals相等的元素時,此時add方法無法加入該元素,返回結果為false。Set取元素時,沒法說取 index,Obj e)方法,就可以指定當前對象在集合中的存放位置。一個對象可以被反復存儲進List中,每調用一次add方法,這個對象就被插入進集合中一次,其實,并不是把這個對象本身存儲進了集合中,而是在集合中用一個索引變量指向這個對象,當這個對象被add多次時,即相當于集合中有多個索引指向了這個對象,如圖x所示。List除了可以以Iterator接口取得所有的元素,再逐一遍歷各個元素之外,還可以調用get(index i)來明確說明取 4、去掉一個Vector集合中重復的元素 Vector newVector = new Vector();For(int i=0;i 9、Collection 和 Collections的區別。 Collection是集合類的上級接口,繼承與他的接口主要有Set 和List.Collections是針對集合類的一個幫助類,他提供一系列靜態方法實現對各種集合的搜索、排序、線程安全化等操作。 39、Set里的元素是不能重復的,那么用什么方法來區分重復與否呢? 是用==還是equals()? 它們有何區別? Set里的元素是不能重復的,元素重復與否是使用equals()方法進行判斷的。equals()和==方法決定引用值是否指向同一對象equals()在類中被覆蓋,為的是當兩個分離的對象的內容和類型相配的話,返回真值。 53、你所知道的集合類都有哪些?主要方法? 最常用的集合類是 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。 45、兩個對象值相同(x.equals(y)== true),但卻可有不同的hash code,這句話對不對? 對。 如果對象要保存在HashSet或HashMap中,它們的equals相等,那么,它們的hashcode值就必須相等。 如果不是要保存在HashSet或HashMap,則與hashcode沒有什么關系了,這時候hashcode不等是可以的,例如arrayList存儲的對象就不用實現hashcode,當然,我們沒有理由不實現,通常都會去實現的。 46、TreeSet里面放對象,如果同時放入了父類和子類的實例對象,那比較時使用的是父類的compareTo方法,還是使用的子類的compareTo方法,還是拋異常! (應該是沒有針對問題的確切的答案,當前的add方法放入的是哪個對象,就調用哪個對象的compareTo方法,至于這個compareTo方法怎么做,就看當前這個對象的類中是如何編寫這個方法的)實驗代碼: 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、說出一些常用的類,包,接口,請各舉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 100、java中有幾種類型的流?JDK為每種類型的流提供了一些抽象類以供繼承,請說出他們分別是哪些類? 字節流,字符流。字節流繼承于InputStream OutputStream,字符流繼承于InputStreamReader OutputStreamWriter。在java.io包中還有許多其他的流,主要是為了提高性能和使用方便。102、字節流與字符流的區別 要把一片二進制數據數據逐一輸出到某個設備中,或者從某個設備中逐一讀取一片二進制數據,不管輸入輸出設備是什么,我們要用統一的方式來完成這些操作,用一種抽象的方式進行描述,這個抽象描述方式起名為IO流,對應的抽象類為OutputStream和InputStream,不同的實現類就代表不同的輸入和輸出設備,它們都是針對字節進行操作的。 在應用中,經常要完全是字符的一段文本輸出去或讀進來,用字節流可以嗎?計算機中的一切最終都是二進制的字節形式存在。對于“中國”這些字符,首先要得到其對應的字節,然后將字節寫入到輸出流。讀取時,首先讀到的是字節,可是我們要把它顯示為字符,我們需要將字節轉換成字符。由于這樣的需求很廣泛,人家專門提供了字符流的包裝類。 底層設備永遠只接受字節數據,有時候要寫字符串到底層設備,需要將字符串轉成字節再進行寫入。字符流是字節流的包裝,字符流則是直接接受字符串,它內部將串轉成字節,再寫入底層設備,這為我們向IO設別寫入或讀取字符串提供了一點點方便。 字符向字節轉換時,要注意編碼的問題,因為字符串轉成字節數組,其實是轉成該字符的某種編碼的字節形式,讀取也是反之的道理。 講解字節流與字符流關系的代碼案例: 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 = ”中國人“;/*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序列化,如何實現java序列化?或者請解釋Serializable接口的作用。第三篇:JAVA面試題
第四篇:java程序員面試題
第五篇:Java就業面試題