java面試題大全2

這是一套我自己在網上查找的一份內容很龐大的面試題精選,說實話想要自己看完也是需要很多的時間,我也是爲了能夠長時間的保存下來以便以後可能會用到。

目錄

1. Java 基礎部分 ................................................................................................................... 10

  1. 一個".java"源文件中是否可以包括多個類(不是內部類)?有什麼限制? ........ 10
  2. Java 有沒有 goto? ...................................................................................................... 10
  3. 說說&和&&的區別。 ................................................................................................... 10
  4. 在 JAVA 中如何跳出當前的多重嵌套循環? ........................................................... 11
  5. switch 語句能否作用在 byte 上,能否作用在 long 上,能否作用在 String 上? . 11
  6. short s1 = 1; s1 = s1 + 1;有什麼錯? short s1 = 1; s1 += 1;有什麼錯? ................ 12
  7. char 型變量中能不能存貯一箇中文漢字?爲什麼? .................................................. 12
  8. 用最有效率的方法算出 2 乘以 8 等於幾? ................................................................ 12
  9. 請設計一個一百億的計算器 ....................................................................................... 12
  10. 使用 final 關鍵字修飾一個變量時,是引用不能變,還是引用的對象不能變? 14
  11. "=="和 equals 方法究竟有什麼區別? ................................................................... 14
  12. 靜態變量和實例變量的區別? ................................................................................. 15
  13. 是否可以從一個 static 方法內部發出對非 static 方法的調用? .......................... 16
  14. Integer 與 int 的區別 ................................................................................................. 16
  15. Math.round(11.5)等於多少? Math.round(-11.5)等於多少? ................................. 17
  16. 下面的代碼有什麼不妥之處? .................................................................................. 17
  17. 請說出作用域 public,private,protected,以及不寫時的區別 ......................... 17
  18. Overload 和 Override 的區別。Overloaded 的方法是否可以改變返回值的類型?

 ............................................................................................................................................. 18

  1. 構造器 Constructor 是否可被 override? ................................................................ 19
  2. 接口是否可繼承接口?抽象類是否可實現(implements)接口?抽象類是否可繼承具體類(concrete class)?抽象類中是否可以有靜態的 main 方法? ................................ 19 21、寫 clone()方法時,通常都有一行代碼,是什麼? ................................................ 19
  1. 面向對象的特徵有哪些方面 ..................................................................................... 19
  2. java 中實現多態的機制是什麼? ............................................................................ 21
  3. abstract class 和 interface 有什麼區別? ................................................................ 21
  4. abstract 的 method 是否可同時是 static,是否可同時是 native,是否可同時是

synchronized? ................................................................................................................... 23

  1. 什麼是內部類?Static Nested Class 和 Inner Class 的不同。 ........................... 24 27、內部類可以引用它的包含類的成員嗎?有沒有什麼限制? ................................. 26

28、Anonymous Inner Class (匿名內部類)是否可以 extends(繼承)其它類,是否可以

implements(實現)interface(接口)? .................................................................................. 27 29、super.getClass()方法調用 ....................................................................................... 27

  1. String 是最基本的數據類型嗎? ............................................................................... 28
  2. String s = "Hello";s = s + " world!";這兩行代碼執行後,原始的 String 對象中的內

容到底變了沒有? ............................................................................................................. 28 32、是否可以繼承 String 類? .......................................................................................... 29

  1. String s = new String("xyz");創建了幾個 String Object?二者之間有什麼區別?

 ............................................................................................................................................. 29

  1. String 和 StringBuffer 的區別 .................................................................................. 30
  2. 如何把一段逗號分割的字符串轉換成一個數組? ................................................... 30
  3. 數組有沒有 length()這個方法? String 有沒有 length()這個方法? ..................... 31
  4. 下面這條語句一共創建了多少個對象:String s="a"+"b"+"c"+"d"; ..................... 31
  5. try {}裏有一個 return 語句,那麼緊跟在這個 try 後的 finally {}裏的 code 會不會

被執行,什麼時候被執行,在 return 前還是後? ........................................................... 31 39、下面的程序代碼輸出的結果是多少? ..................................................................... 32

  1. final, finally, finalize 的區別。 ................................................................................. 35
  2. 運行時異常與一般異常有何異同? ......................................................................... 35
  3. error 和 exception 有什麼區別? .............................................................................. 35
  4. Java 中的異常處理機制的簡單原理和應用。 ....................................................... 35
  5. 請寫出你最常見到的 5 個 runtime exception。 .................................................... 36
  6. JAVA 語言如何進行異常處理,關鍵字:throws,throw,try,catch,finally 分別代表

什麼意義?在 try 塊中可以拋出異常嗎? ....................................................................... 36

  1. java 中有幾種方法可以實現一個線程?用什麼關鍵字修飾同步方法? stop()和

suspend()方法爲何不推薦使用? ................................................................................... 36 47、sleep()和 wait()有什麼區別? .................................................................................. 38

48、同步和異步有何異同,在什麼情況下分別使用他們?舉例說明。 ..................... 41

49. 下面兩個方法同步嗎?(自己發明) ...................................................................... 41

  1. 多線程有幾種實現方法?同步有幾種實現方法? .................................................... 42
  2. 啓動一個線程是用 run()還是 start()? . ................................................................... 42
  3. 當一個線程進入一個對象的一個 synchronized 方法後,其它線程是否可進入此

對象的其它方法? ............................................................................................................... 42 53、線程的基本概念、線程的基本狀態以及狀態之間的關係 ..................................... 43

  1. 簡述 synchronized 和 java.util.concurrent.locks.Lock 的異同? ........................ 43
  2. 設計 4 個線程,其中兩個線程每次對 j 增加 1,另外兩個線程對 j 每次減少 1。寫

出程序。 ............................................................................................................................. 46

  1. 子線程循環 10 次,接着主線程循環 100,接着又回到子線程循環 10 次,接着

再回到主線程又循環 100,如此循環 50 次,請寫出程序。 ....................................... 48

  1. 介紹 Collection 框架的結構 ..................................................................................... 56
  2. Collection 框架中實現比較要實現什麼接口 .......................................................... 56
  3. ArrayList 和 Vector 的區別 ...................................................................................... 56
  4. HashMap 和 Hashtable 的區別 ............................................................................... 57
  5. List 和 Map 區別? .................................................................................................... 57
  6. List, Set, Map 是否繼承自 Collection 接口?.......................................................... 58
  7. List、Map、Set 三個接口,存取元素時,各有什麼特點? ................................ 58
  8. 說出 ArrayList,Vector, LinkedList 的存儲性能和特性 .......................................... 59
  9. 去掉一個 Vector 集合中重複的元素 ....................................................................... 59
  10. Collection 和 Collections 的區別。 ........................................................................ 59
  11. Set 裏的元素是不能重複的,那麼用什麼方法來區分重複與否呢?是用==還是

equals()?它們有何區別? .................................................................................................. 60

  1. 你所知道的集合類都有哪些?主要方法? ............................................................. 60
  2. 兩個對象值相同(x.equals(y) == true),但卻可有不同的 hash code,這句話對不

對? ....................................................................................................................................... 61

  1. TreeSet 裏面放對象,如果同時放入了父類和子類的實例對象,那比較時使用的是父類的 compareTo 方法,還是使用的子類的 compareTo 方法,還是拋異常! . 61
  2. 說出一些常用的類,包,接口,請各舉 5 個......................................................... 63
  3. java 中有幾種類型的流?JDK 爲每種類型的流提供了一些抽象類以供繼承,請

說出他們分別是哪些類? ................................................................................................. 63 73、字節流與字符流的區別 ............................................................................................. 63

  1. 什麼是 java 序列化,如何實現 java 序列化?或者請解釋 Serializable 接口的作

用。 ..................................................................................................................................... 65

  1. 描述一下 JVM 加載 class 文件的原理機制? ......................................................... 66
  2. heap 和 stack 有什麼區別。 ................................................................................... 66
  3. GC 是什麼?爲什麼要有 GC? .................................................................................. 66
  4. 垃圾回收的優點和原理。並考慮 2 種回收機制。................................................. 66 79、垃圾回收器的基本原理是什麼?垃圾回收器可以馬上回收內存嗎?有什麼辦法主

動通知虛擬機進行垃圾回收? ......................................................................................... 66 80、什麼時候用 assert。 ................................................................................................. 67

    1. java 中會存在內存泄漏嗎,請簡單描述。 ............................................................ 68
    2. 能不能自己寫個類,也叫 java.lang.String? ........................................................ 72
    3. Java 代碼查錯 ............................................................................................................. 73

二.算法與編程 ........................................................................................................................ 77

    1. 編寫一個程序,將 a.txt 文件中的單詞與 b.txt 文件中的單詞交替合併到 c.txt 文件中,a.txt 文件中的單詞用回車符分隔,b.txt 文件中用回車或空格進行分隔。 ........ 77
    2. 編寫一個程序,將 d:\java 目錄下的所有.java 文件複製到 d:\jad 目錄下,並將原

來文件的擴展名從.java 改爲.jad。 ................................................................................. 79

    1. 編寫一個截取字符串的函數,輸入爲一個字符串和字節數,輸出爲按字節截取的字符串,但要保證漢字不被截取半個,如“我 ABC”,4,應該截取“我 AB”,輸入“我

ABC 漢 DEF”,6,應該輸出“我 ABC”,而不是“我 ABC+漢的半個”。 .................... 82

    1. 有一個字符串,其中包含中文字符、英文字符和數字字符,請統計和打印出各個

字符的個數。 ..................................................................................................................... 83

    1. 說明生活中遇到的二叉樹,用 java 實現二叉樹 ...................................................... 84
    2. 從類似如下的文本文件中讀取出所有的姓名,並打印出重複的姓名和重複的次數,

並按重複次數排序: ......................................................................................................... 91 7、寫一個 Singleton 出來。 ............................................................................................ 96

    1. 遞歸算法題 1 ................................................................................................................ 99
    2. 遞歸算法題 2 .............................................................................................................. 100
    3. 排序都有哪幾種方法?請列舉。用 JAVA 實現一個快速排序。 ....................... 100
    4. 有數組 a[n],用 java 代碼將數組元素順序顛倒 .................................................. 102

12.金額轉換,阿拉伯數字的金額轉換成中國傳統的形式如:(¥1011)->(一千

零一拾一元整)輸出。 ................................................................................................... 103 三. html&JavaScript&ajax 部分 ......................................................................................... 104

    1. 判斷第二個日期比第一個日期大 .............................................................................. 104
    2. 用 table 顯示 n 條記錄,每 3 行換一次顏色,即 1,2,3 用紅色字體,4,5,6

用綠色字體,7,8,9 用紅顏色字體。 ....................................................................... 106

    1. HTML 的 form 提交之前如何驗證數值文本框的內容全部爲數字?否則的話提示用

戶並終止提交? ................................................................................................................. 107

    1. 請寫出用於校驗 HTML 文本框中輸入的內容全部爲數字的 javascript 代碼 ..... 107
    2. 說說你用過那些 ajax 技術和框架,說說它們的區別 ............................................ 108

四. Java web 部分 ............................................................................................................... 108 1、Tomcat 的優化經驗 .................................................................................................. 108

    1. HTTP 請求的 GET 與 POST 方式的區別 .............................................................. 108
    2. 解釋一下什麼是 servlet; ........................................................................................... 108
    3. 說一說 Servlet 的生命週期? .................................................................................... 109
    4. Servlet 的基本架構 ................................................................................................... 109
    5. SERVLET API 中 forward()與 redirect()的區別? ................................................ 109
    6. 什麼情況下調用 doGet()和 doPost()? .................................................................. 109
    7. Request 對象的主要方法: ..................................................................................... 110
    8. forward 和 redirect 的區別 ....................................................................................... 110
    9. request.getAttribute()和 request.getParameter()有何區別? ............................ 111
    1. jsp 有哪些內置對象?作用分別是什麼?分別有什麼方法? .................................. 111
    2. jsp 有哪些動作?作用分別是什麼? .......................................................................... 112

13、JSP 的常用指令 ...................................................................................................... 112

14. JSP 中動態 INCLUDE 與靜態 INCLUDE 的區別? ............................................. 112

    1. 兩種跳轉方式分別是什麼?有什麼區別? .............................................................. 113
    2. 頁面間對象傳遞的方法 ........................................................................................... 113
    3. JSP 和 Servlet 有哪些相同點和不同點,他們之間的聯繫是什麼? ................ 113
    4. MVC 的各個部分都有那些技術來實現?如何實現? ............................................ 113
    5. 我們在 web 應用開發過程中經常遇到輸出某種編碼的字符,如 iso8859-1 等,

如何輸出一個某種編碼的字符串? ............................................................................... 113

    1. 現在輸入 n 個數字,以逗號,分開;然後可選擇升或者降序排序;按提交鍵就在另一頁面顯示按什麼排序,結果爲,提供 reset ......................................................... 114 五.數據庫部分 ...................................................................................................................... 114
    1. 用兩種方式根據部門號從高到低,工資從低到高列出每個員工的信息。 ......... 114
    2. 列出各個部門中工資高於本部門的平均工資的員工數和部門號,並按部門號排序

 ........................................................................................................................................... 114

    1. 存儲過程與觸發器必須講,經常被面試到? ........................................................... 116
    2. 數據庫三範式是什麼? ............................................................................................... 118
    3. 說出一些數據庫優化方面的經驗? ........................................................................... 119
    4. union 和 union all 有什麼不同? ............................................................................... 121

7.分頁語句 ........................................................................................................................ 122

8.用一條 SQL 語句查詢出每門課都大於 80 分的學生姓名 ....................................... 126

9.所有部門之間的比賽組合 ............................................................................................ 127

10.每個月份的發生額都比 101 科目多的科目 ............................................................. 127

11.統計每年每月的信息 ................................................................................................. 129

12.顯示文章標題,發帖人、最後回覆時間 .................................................................. 131

13.刪除除了 id 號不同,其他都相同的學生冗餘信息 ................................................... 131

14.航空網的幾個航班查詢題:...................................................................................... 132

15.查出比經理薪水還高的員工信息: .......................................................................... 134

16、求出小於 45 歲的各個老師所帶的大於 12 歲的學生人數 .................................. 135

17.求出發帖最多的人: ................................................................................................. 136

    1. 一個用戶表中有一個積分字段,假如數據庫中有 100 多萬個用戶,若要在每年

第一天凌晨將積分清零,你將考慮什麼,你將想什麼辦法解決? ............................. 136

    1. 一個用戶具有多個角色,請查詢出該表中具有該用戶的所有角色的其他用戶。

 ........................................................................................................................................... 137

20. xxx 公司的 sql 面試 .................................................................................................. 138

    1. 註冊 Jdbc 驅動程序的三種方式 ............................................................................ 139
    2. 用 JDBC 如何調用存儲過程 .................................................................................. 139 23、JDBC 中的 PreparedStatement 相比 Statement 的好處................................... 141

24. 寫一個用 jdbc 連接並訪問 oracle 數據的程序代碼 ............................................. 141

    1. Class.forName 的作用?爲什麼要用? ................................................................... 141
    2. 大數據量下的分頁解決方法。 ............................................................................... 141
    3. 用 JDBC 查詢學生成績單,把主要代碼寫出來(考試概率極大). ................... 142
    4. 這段代碼有什麼不足之處? .................................................................................... 143
    5. 說出數據連接池的工作機制是什麼? .................................................................... 143
    6. 爲什麼要用 ORM? 和 JDBC 有何不一樣?........................................................ 144 六. XML 部分 ........................................................................................................................ 144
    1. xml 有哪些解析技術?區別是什麼? ......................................................................... 144
    2. 你在項目中用到了 xml 技術的哪些方面?如何實現的? ........................................ 144
    3. 用 jdom 解析 xml 文件時如何解決中文問題?如何解析? ...................................... 144
    4. 編程用 JAVA 解析 XML 的方式. .............................................................................. 145
    5. XML 文檔定義有幾種形式?它們之間有何本質區別?解析 XML 文檔有哪幾種方

式? ................................................................................................................................... 148

七.流行的框架與新技術 ...................................................................................................... 148 1、談談你對 Struts 的理解。 ........................................................................................ 149

2、談談你對 Hibernate 的理解。.................................................................................. 149 3、AOP 的作用。 ........................................................................................................... 150 4、你對 Spring 的理解。 ............................................................................................... 150

    1. 談談 Struts 中的 Action servlet。 ........................................................................... 151
    2. Struts 優缺點 優點:  1. 實現 MVC 模式,結構清晰,使開發者只關注業務邏輯的

實現. .................................................................................................................................. 151

    1. STRUTS 的應用(如 STRUTS 架構) ....................................................................... 153
    2. 說說 struts1 與 struts2 的區別。 ............................................................................. 153
    3. hibernate 中的 update()和 saveOrUpdate()的區別,session 的 load()和 get()的區

別。 ................................................................................................................................... 154

    1. 簡述 Hibernate 和 JDBC 的優缺點?如何書寫一個 one to many 配置文件. . 154
    2. iBatis 與 Hibernate 有什麼不同? .......................................................................... 154
    3. 寫 Hibernate 的一對多和多對一雙向關聯的 orm 配置? .................................... 154

12.1、hibernate 的 inverse 屬性的作用? ..................................................................... 154

    1. 在 DAO 中如何體現 DAO 設計模式? ................................................................... 155
    2. spring+Hibernate 中委託方案怎麼配置? ............................................................. 155
    3. spring+Hibernate 中委託方案怎麼配置? ............................................................. 155

16. hibernate 進行多表查詢每個表中各取幾個字段,也就是說查詢出來的結果集沒有

一個實體類與之對應如何解決; ................................................................................... 155 17.介紹一下 Hibernate 的二級緩存 .............................................................................. 155

    1. Spring 的依賴注入是什麼意思?給一個 Bean 的 message 屬性,字符串類型,注

入值爲"Hello"的 XML 配置文件該怎麼寫? .................................................................. 158

    1. Jdo 是什麼? ............................................................................................................. 158
    2. 什麼是 spring 的 IOC AOP .................................................................................... 158
    3. STRUTS 的工作流程! .......................................................................................... 158
    4. spring 與 EJB 的區別!! ..................................................................................... 158 八.軟件工程與設計模式 ...................................................................................................... 158 1、UML 方面 ................................................................................................................... 158
    1. j2ee 常用的設計模式?說明工廠模式。 ................................................................ 158
    2. 開發中都用到了那些設計模式?用在什麼場合?..................................................... 159 九. j2ee 部分 ........................................................................................................................ 159 1、BS 與 CS 的聯繫與區別。 ....................................................................................... 159 1.硬件環境不同: ...................................................................................................... 159 2.對安全要求不同 ................................................................................................... 160

3.對程序架構不同 ................................................................................................... 160 4.軟件重用不同 ....................................................................................................... 160

5.系統維護不同 ....................................................................................................... 160

6.處理問題不同 ....................................................................................................... 160

7.用戶接口不同 ....................................................................................................... 160

    1. 應用服務器與 WEB SERVER 的區別? ................................................................ 161
    2. 應用服務器有那些? ................................................................................................. 161
    3. J2EE 是什麼? .......................................................................................................... 161
    4. J2EE 是技術還是平臺還是框架?什麼是 J2EE .................................................... 161
    5. 請對以下在 J2EE 中常用的名詞進行解釋(或簡單描述) ....................................... 161
    6. 如何給 weblogic 指定大小的內存? ......................................................................... 162
    7. 如何設定的 weblogic 的熱啓動模式(開發模式)與產品發佈模式? ....................... 162
    8. 如何啓動時不需輸入用戶名與密碼? ....................................................................... 162
    9. 在 weblogic 管理制臺中對一個應用域(或者說是一個網站,Domain)進行 jms及 ejb 或連接池等相關信息進行配置後,實際保存在什麼文件中? ........................................ 162
    10. 說說 weblogic 中一個 Domain 的缺省目錄結構?比如要將一個簡單的 helloWorld.jsp 放入何目錄下,然的在瀏覽器上就可打入 http://主機:端口號

//helloword.jsp 就可以看到運行結果了?又比如這其中用到了一個自己寫的 javaBean

該如何辦? ......................................................................................................................... 162

    1. 在 weblogic 中發佈 ejb 需涉及到哪些配置文件 .................................................. 163
    2. 如何在 weblogic 中進行 ssl 配置與客戶端的認證配置或說說 j2ee(標準)進行 ssl

的配置? ............................................................................................................................. 163

    1. 如何查看在 weblogic 中已經發布的 EJB? ........................................................... 163
  • EJB 部分 ........................................................................................................................ 163
    1. EJB 是基於哪些技術實現的?並說出 SessionBean 和 EntityBean 的區別,

StatefulBean 和 StatelessBean 的區別。 ................................................................... 163

    1. 簡要講一下 EJB 的 7 個 Transaction Level? ...................................................... 164
    2. EJB 與 JAVA BEAN 的區別?................................................................................. 164
    3. EJB 包括(SessionBean,EntityBean)說出他們的生命週期,及如何管理事務的?

 ........................................................................................................................................... 164 5、EJB 容器提供的服務................................................................................................. 164

    1. EJB 的激活機制 ........................................................................................................ 164
    2. EJB 的幾種類型 ........................................................................................................ 165
    3. 客服端調用 EJB 對象的幾個基本步驟 .................................................................... 165
  • webservice 部分 ........................................................................................................ 165
    1. WEB SERVICE 名詞解釋。JSWDL 開發包的介紹。JAXP、JAXM 的解釋。SOAP、

UDDI,WSDL 解釋。 ........................................................................................................ 165

    1. CORBA 是什麼?用途是什麼? ................................................................................. 165
    2. Linux ............................................................................................................................. 166
    3. LINUX 下線程,GDI 類的解釋。 ............................................................................ 166
    4. 問得稀裏糊塗的題 ...................................................................................................... 166
    5. 四種會話跟蹤技術 ..................................................................................................... 166
    6. 簡述邏輯操作(&,|,^)與條件操作(&&,||)的區別。 ................................................... 166

十二.其他 .............................................................................................................................. 166 1、請用英文簡單介紹一下自己. .................................................................................... 166

    1. 請把 http://tomcat.apache.org/ 首頁的這一段話用中文翻譯一下? .................... 166
    2. 美資軟件公司 JAVA 工程師電話面試題目 ............................................................. 167

這套面試題主要目的是幫助那些還沒有 java 軟件開發實際工作經驗,而正在努力尋找 java 軟件開發工作的朋友在筆試時更好地贏得筆試和麪試。由於這套面試題涉及的範圍很泛,很廣,很雜,大家不可能一天兩天就看完和學完這套面試寶典,即使你已經學過了有關的技術,那麼至少也需要一個月的時間才能消化和掌握這套面試寶典,所以,大家應該早作準備,從拿到這套面試寶典之日起,就要堅持在每天閒暇之餘學習其中幾道題目,日積月累,等到出去面試時,一切都水到渠成,面試時就自然會遊刃有餘了。

答題時,先答是什麼,再答有什麼作用和要注意什麼(這部分最重要,展現自己的心得)

答案的段落分別,層次分明,條理清晰都非常重要,從這些表面的東西也可以看出一個人的習慣、辦事風格、條理等。

要講你做出答案的思路過程,或者說你記住答案的思想都寫下來。把答題想着是辯論賽。答題就是給別人講道理、擺事實。答題不侷限於什麼格式和形式,就是要將自己的學識展現出來!

別因爲人家題目本來就模棱兩可,你就心裏膽怯和沒底氣了,不敢回答了。你要大膽地指出對方題目很模糊和你的觀點,不要把面試官想得有多高,其實他和你就是差不多的,你想想,如果他把你招進去了,你們以後就是同事了,可不是差不多的嗎?

關於就業薪水,如果你是應屆生,那不能要高工資,好比大餅的故事,沒有文憑還想拿高工資,就去中關村缺什麼補什麼吧!少數人基礎確實很好,在校期間確實又做過一些項目,那仍然是可以要到相對高的工資的。

1. Java 基礎部分

基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語法,集合的語法,io 的語法,虛擬機方面的語法。

  1. 一個".java"源文件中是否可以包括多個類(不是內部類)?有什麼限制?

可以有多個類,但只能有一個 public 的類,並且 public 的類名必須與文件名相一致

  1. Java 有沒有 goto?

java 中的保留字,現在沒有在 java 中使用。

  1. 說說&&&的區別。

&&&都可以用作邏輯與的運算符,表示邏輯與(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。

備註:這道題先說兩者的共同點,再說出&&和&的特殊之處,並列舉一些經典的例子來表明自己理解透徹深入、實際經驗豐富。 

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;

        }

}

另外,我個人通常並不使用標號這種方式,而是讓外層的循環條件表達式的結果可以受到裏層循環體代碼的控制,例如,要在二維數組中查找到某個數字。

int arr[][] ={{1,2,3},{4,5,6,7},{9}}; boolean found = false; for(int i=0;i<arr.length&& !found;i++)       {         for(int j=0;j<arr[i].length;j++){

               System.out.println(“i=” + i + “,j=” + j);                if(arr[i][j]  ==5) {                       found = true;                       break;

               }

        }

}

  1. switch 語句能否作用在 byte 上,能否作用在 long 上,能否作用在 String ?

在 switch(expr1)中,expr1只能是一個整數表達式或者枚舉常量(更大字體),整數表達式可以是 int 基本類型或 Integer 包裝類型,由於,byte,short,char 都可以隱含轉換爲 int,所以,這些類型以及這些類型的包裝類型也是可以的。顯然,long 和 String 類型都不符合

switch 的語法規定,並且不能被隱式轉換成 int 類型,所以,它們不能作用於 swtich 語句中。

  1. 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 編譯器會對它進行特殊處理,因此可以正確編譯

  1. char 型變量中能不能存貯一箇中文漢字?爲什麼?

char 型變量是用來存儲 Unicode 編碼的字符的,unicode 編碼字符集中包含了漢字,所以, char 型變量中當然可以存儲漢字啦。不過,如果某個特殊的漢字沒有被包含在 unicode 編碼字符集中,那麼,這個 char 型變量中就不能存儲這個特殊漢字。補充說明:unicode 編碼佔用兩個字節,所以,char 類型的變量也是佔用兩個字節。

備註:後面一部分回答雖然不是在正面回答題目,但是,爲了展現自己的學識和表現自己對問題理解的透徹深入,可以回答一些相關的知識,做到知無不言,言無不盡。

  1. 用最有效率的方法算出 2 乘以 8 等於幾?

2 << 3,

因爲將一個數左移 n 位,就相當於乘以了2n 次方,那麼,一個數乘以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億的大小,所以,要實現一個一百億的計算器,我們得自己設計一個類可以用於表示很大的整數,並且提供了與另外一個整數進行加減乘除的功能,大概功能如下:

  1. 這個類內部有兩個成員變量,一個表示符號,另一個用字節數組表示數值的二進制數
  2. 有一個構造方法,把一個包含有多位數值的字符串轉換到內部的符號和字節數組中
  3. 提供加減乘除的功能

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);

        }

}

備註:這個解答除了說清楚兩者的區別外,最後還用一個具體的應用例子來說明兩者的差異,體現了自己有很好的解說問題和設計案例的能力,思維敏捷,超過一般程序員,有寫作能力!

  1. 是否可以從一個 static 方法內部發出對非 static 方法的調用?

不可以。因爲static 方法是要與對象關聯在一起的,必須創建一個對象後,纔可以在該對象上進行方法調用,而 static 方法調用時不需要創建對象,可以直接調用。也就是說,當一個 static 方法被調用時,可能還沒有創建任何實例對象,如果從一個 static 方法中發出對非 static 方法的調用,那個非 static 方法是關聯到哪個對象上的呢?這個邏輯無法成立,所以,一個 static 方法內部發出對非 static 方法的調用。

  1. 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 中還定義了表示整數的最大值和最小值的常量。

  1. 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。

  1. 下面的代碼有什麼不妥之處?
    1. if(username.equals(“zxx”){}

  username 可能爲 NULL,會報空指針錯誤;改爲"zxx".equals(username)

    1. int  x = 1;

      return x==1?true:false;  這個改成 return x==1;就可以!

  1. 請說出作用域 publicprivateprotected,以及不寫時的區別

這四個作用域的可見範圍如下表所示。

說明:如果在修飾的元素上面沒有寫任何訪問修飾符,則表示 friendly。

作用域

當前類

同一包(package)

子孫類

其他包(package)

public

protected

×

friendly

×

×

private

×

×

×

 

備註:只要記住了有4種訪問權限,4個訪問範圍,然後將全選和範圍在水平和垂直方向上分別按排從小到大或從大到小的順序排列,就很容易畫出上面的圖了。

  1. 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,那麼就不能在子類對其進行重載,如果定義的話,也只是定義了一個新方法,而不會達到重載的效果。
  1. 構造器 Constructor 是否可被 override?

構造器Constructor 不能被繼承,因此不能重寫Override,但可以被重載Overload

  1. 接口是否可繼承接口?抽象類是否可實現(implements)接口?抽象類是否可繼承具體類(concrete class)?抽象類中是否可以有靜態的 main 方法?

接口可以繼承接口。抽象類可以實現(implements)接口,抽象類可以繼承具體類。抽象類中可以有靜態的 main 方法。

備註:只要明白了接口和抽象類的本質和作用,這些問題都很好回答,你想想,如果你是 java 語言的設計者,你是否會提供這樣的支持,如果不提供的話,有什麼理由嗎?如果你沒有道理不提供,那答案就是肯定的了。

 只有記住抽象類與普通類的唯一區別:就是不能創建實例對象和允許有 abstract 方法。

  1. clone()方法時,通常都有一行代碼,是什麼?

clone 有缺省行爲,

super.clone();

因爲首先要把父類中的成員複製到位,然後纔是複製自己的成員。

  1. 面向對象的特徵有哪些方面

計算機軟件系統是現實生活中的業務在計算機中的映射,而現實生活中的業務其實就是一個個對象協作的過程。面向對象編程就是按現實業務一樣的方式將程序代碼按一個個對象進行組織和編寫,讓計算機系統能夠識別和理解用對象方式組織和編寫的程序代碼,這樣就可以把現實生活中的業務對象映射到計算機系統中。面向對象的編程語言有,嗎等4個主要的特徵。

封裝:封裝是保證軟件部件具有優良的模塊性的基礎,封裝的目標就是要實現軟件部件的“高內聚、低耦合”,防止程序相互依賴性而帶來的變動影響。在面向對象的編程語言中,對象是封裝的最基本單位,面向對象的封裝比傳統語言的封裝更爲清晰、更爲有力。面向對象的封裝就是把描述一個對象的屬性和行爲的代碼封裝在一個“模塊”中,也就是一個類中,屬性用變量定義,行爲用方法進行定義,方法可以直接訪問同一個對象中的屬性。通常情況下,只要記住讓變量和訪問這個變量的方法放在一起,將一個類中的成員變量全部定義成私有的,只有這個類自己的方法纔可以訪問到這些成員變量,這就基本上實現對象的封裝,就很容易找出要分配到這個類上的方法了,就基本上算是會面向對象的編程了。把握一個原則:把對同一事物進行操作的方法和相關的方法放在同一個類中,把方法和它操作的數據放在同一個類中。

例如,人要在黑板上畫圓,這一共涉及三個對象:人、黑板、圓,畫圓的方法要分配給哪個對象呢?由於畫圓需要使用到圓心和半徑,圓心和半徑顯然是圓的屬性,如果將它們在類中定義成了私有的成員變量,那麼,畫圓的方法必須分配給圓,它才能訪問到圓心和半徑這兩個屬性,人以後只是調用圓的畫圓方法、表示給圓發給消息而已,畫圓這個方法不應該分配在人這個對象上,這就是面向對象的封裝性,即將對象封裝成一個高度自治和相對封閉的個體,對象狀態(屬性)由這個對象自己的行爲(方法)來讀取和改變。一個更便於理解的例子就是,司機將火車剎住了,剎車的動作是分配給司機,還是分配給火車,顯然,應該分配給火車,因爲司機自身是不可能有那麼大的力氣將一個火車給停下來的,只有火車自己才能完成這一動作,火車需要調用內部的離合器和剎車片等多個器件協作才能完成剎車這個動作,司機剎車的過程只是給火車發了一個消息,通知火車要執行剎車動作而已。

 

抽象:

抽象就是找出一些事物的相似和共性之處,然後將這些事物歸爲一個類,這個類只考慮這些事物的相似和共性之處,並且會忽略與當前主題和目標無關的那些方面,將注意力集中在與當前目標有關的方面。例如,看到一隻螞蟻和大象,你能夠想象出它們的相同之處,那就是抽象。抽象包括行爲抽象和狀態抽象兩個方面。例如,定義一個 Person 類,如下:

classPerson{

        String name;

        int age;

}

人本來是很複雜的事物,有很多方面,但因爲當前系統只需要瞭解人的姓名和年齡,所以上面定義的類中只包含姓名和年齡這兩個屬性,這就是一種抽像,使用抽象可以避免考慮一些與目標無關的細節。我對抽象的理解就是不要用顯微鏡去看一個事物的所有方面,這樣涉及的內容就太多了,而是要善於劃分問題的邊界,當前系統需要什麼,就只考慮什麼。

 

繼承:

在定義和實現一個類的時候,可以在一個已經存在的類的基礎之上來進行,把這個已經存在的類所定義的內容作爲自己的內容,並可以加入若干新的內容,或修改原來的方法使之更適合特殊的需要,這就是繼承。繼承是子類自動共享父類數據和方法的機制,這是類之間的一種關係,提高了軟件的可重用性和可擴展性。

 

多態:

多態是指程序中定義的引用變量所指向的具體類型和通過該引用變量發出的方法調用在編程時並不確定,而是在程序運行期間才確定,即一個引用變量倒底會指向哪個類的實例對象,該引用變量發出的方法調用到底是哪個類中實現的方法,必須在由程序運行期間才能決定。因爲在程序運行時才確定具體的類,這樣,不用修改源程序代碼,就可以讓引用變量綁定到各種不同的類實現上,從而導致該引用調用的具體方法隨之改變,即不修改程序代碼就可以改變程序運行時所綁定的具體代碼,讓程序可以選擇多個運行狀態,這就是多態性。多態性增強了軟件的靈活性和擴展性。例如,下面代碼中的 UserDao 是一個接口,它定義引用變量 userDao 指向的實例對象由 daofactory.getDao()在執行的時候返回,有時候指向的是

UserJdbcDao 這個實現,有時候指向的是 UserHibernateDao 這個實現,這樣,不用修改源代碼,就可以改變 userDao 指向的具體類實現,從而導致 userDao.insertUser()方法調用的具體代碼也隨之改變,即有時候調用的是 UserJdbcDao 的 insertUser 方法,有時候調用的是 UserHibernateDao 的 insertUser 方法:

UserDao userDao =daofactory.getDao();  userDao.insertUser(user);

 

比喻:人吃飯,你看到的是左手,還是右手?

  1. java 中實現多態的機制是什麼?

靠的是父類或接口定義的引用變量可以指向子類或具體實現類的實例對象,而程序調用的方法在運行期才動態綁定,就是引用變量所指向的具體實例對象的方法,也就是內存里正在運行的那個對象的方法,而不是引用變量的類型中定義的方法。

  1. abstract class interface 有什麼區別?

含有 abstract 修飾符的 class 即爲抽象類,abstract 類不能創建的實例對象。含有 abstract 方法的類必須定義爲abstract class,abstract class類中的方法不必是抽象的。abstract class 類中定義抽象方法必須在具體(Concrete)子類中實現,所以,不能有抽象構造方法或抽象靜態方法。如果的子類沒有實現抽象父類中的所有抽象方法,那麼子類也必須定義爲 abstract 類型。

接口(interface)可以說成是抽象類的一種特例,接口中的所有方法都必須是抽象的。接口

中的方法定義默認爲 public abstract 類型,接口中的成員變量類型默認爲 public static final

下面比較一下兩者的語法區別:

1.抽象類可以有構造方法,接口中不能有構造方法。

2.抽象類中可以有普通成員變量,接口中沒有普通成員變量

3.抽象類中可以包含非抽象的普通方法,接口中的所有方法必須都是抽象的,不能有非抽象的普通方法。

  1. 抽象類中的抽象方法的訪問類型可以是 public,protected 和(默認類型,雖然

eclipse 下不報錯,但應該也不行),但接口中的抽象方法只能是 public 類型的,並且默認即爲 public abstract 型。

  1. 抽象類中可以包含靜態方法,接口中不能包含靜態方法
  2. 抽象類和接口中都可以包含靜態成員變量,抽象類中的靜態成員變量的訪問類型可以任意,但接口中定義的變量只能是 public static final 類型,並且默認即爲 public static final 類型。
  3. 一個類可以實現多個接口,但只能繼承一個抽象類。

       下面接着再說說兩者在應用上的區別:

接口更多的是在系統架構設計方法發揮作用,主要用於定義模塊之間的通信契約。而抽象類在代碼實現方面發揮作用,可以實現代碼的重用,例如,模板方法設計模式是抽象類的一個典型應用,假設某個項目的所有 Servlet 類都要用相同的方式進行權限判斷、記錄訪問日誌和處理異常,那麼就可以定義一個抽象的基類,讓所有的 Servlet 都繼承這個抽象基類,在抽象基類的 service 方法中完成權限判斷、記錄訪問日誌和處理異常的代碼,在各個子類中只是完成各自的業務邏輯代碼,僞代碼如下:

public abstract classBaseServlet 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 extendsBaseServlet

{

protected voiddoService(HttpServletRequest request, HttpServletResponse response) throwsIOExcetion,ServletException

        {

               本 Servlet 只處理的具體業務邏輯代碼

        }

 

}

父類方法中間的某段代碼不確定,留給子類幹,就用模板方法設計模式。

備註:這道題的思路是先從總體解釋抽象類和接口的基本概念,然後再比較兩者的語法細節,最後再說兩者的應用區別。比較兩者語法細節區別的條理是:先從一個類中的構造方法、普通成員變量和方法(包括抽象方法),靜態變量和方法,繼承性等6個方面逐一去比較回答,接着從第三者繼承的角度的回答,特別是最後用了一個典型的例子來展現自己深厚的技術功底。

25abstract method 是否可同時是 static,是否可同時是 native,是否可同時是 synchronized?

abstract method 不可以是 static 的,因爲抽象的方法是要被子類實現的,而 static 與子類扯不上關係!

native 方法表示該方法要用另外一種依賴平臺的編程語言實現的,不存在着被子類實現的問題,所以,它也不能是抽象的,不能與 abstract 混用。例如,FileOutputSteam 類要硬件打交道,底層的實現用的是操作系統相關的 api 實現,例如,在 windows 用 c 語言實現的,所以,查看 jdk 的源代碼,可以發現 FileOutputStream 的 open 方法的定義如下:

private native void open(Stringname) throws FileNotFoundException;

如果我們要用 java 調用別人寫的 c 語言函數,我們是無法直接調用的,我們需要按照 java 的要求寫一個 c 語言的函數,又我們的這個 c 語言函數去調用別人的 c 語言函數。由於我們的 c 語言函數是按 java 的要求來寫的,我們這個 c 語言函數就可以與 java 對接上,java 那邊的對接方式就是定義出與我們這個 c 函數相對應的方法,java 中對應的方法不需要寫具體的代碼,但需要在前面聲明 native。

關於 synchronized 與 abstract 合用的問題,我覺得也不行,因爲在我幾年的學習和開發中,從來沒見到過這種情況,並且我覺得 synchronized 應該是作用在一個具體的方法上纔有意義。而且,方法上的 synchronized 同步所使用的同步鎖對象是 this,而抽象方法上無法確定 this 是什麼。

26、什麼是內部類?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 = newOuter.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 修飾符。

 

備註:首先根據你的印象說出你對內部類的總體方面的特點:例如,在兩個地方可以定義,可以訪問外部類的成員變量,不能定義靜態成員,這是大的特點。然後再說一些細節方面的知識,例如,幾種定義方式的語法區別,靜態內部類,以及匿名內部類。

27、內部類可以引用它的包含類的成員嗎?有沒有什麼限制?

完全可以。如果不是靜態內部類,那沒有什麼限制!如果你把靜態嵌套類當作內部類的一種特例,那在這種情況下不可以訪問外部類的普通成員變量,而只能訪問外部類中的靜態成員,例如,下面的代碼:

class Outer

{ static int x; static class Inner

{

        void test()         {                syso(x);

        }

}

}

 

答題時,也要能察言觀色,揣摩提問者的心思,顯然人家希望你說的是靜態內部類不能訪問外部類的成員,但你一上來就頂牛,這不好,要先順着人家,讓人家滿意,然後再說特殊情況,讓人家吃驚。

 

  1. Anonymous Inner Class (匿名內部類)是否可以 extends(繼承)其它類,是否可以 implements(實現)interface(接口)?

可以繼承其他類或實現其他接口。不僅是可以,而是必須!

  1. super.getClass()方法調用

下面程序的輸出結果是多少?

importjava.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();

  1. String 是最基本的數據類型嗎?

基本數據類型包括 byte、int、char、long、float、double、boolean 和 short。

java.lang.String 類是 final 類型的,因此不可以繼承這個類、不能修改這個類。爲了提高效率節省空間,我們應該用 StringBuffer 類

  1. 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。

 

 

  1. 是否可以繼承 String ?

String 類是 final 類故不可以繼承。

  1. String s = new String("xyz");創建了幾個 String Object?二者之間有什麼區別?

兩個或一個,”xyz”對應一個對象,這個對象放在字符串常量緩衝區,常量”xyz”不管出現多少遍,都是緩衝區中的那一個。New String 每寫一遍,就創建一個新的對象,它一句那個常量”xyz”對象的內容來創建出一個新 String 對象。如果以前就用過’xyz’,這句代表就不會創建”xyz”自己了,直接從緩衝區拿。

  1. String StringBuffer 的區別

JAVA 平臺提供了兩個類:String 和 StringBuffer,它們可以儲存和操作字符串,即包含多個字符的字符數據。這個 String 類提供了數值不可改變的字符串。而這個 StringBuffer 類提供的字符串進行修改。當你知道字符數據要改變的時候你就可以使用 StringBuffer。典型地,你可以使用 StringBuffers 來動態構造字符數據。另外,String 實現了 equals 方法,new

String(“abc”).equals(newString(“abc”)的結果爲 true,而 StringBuffer 沒有實現equals 方法,所以,new StringBuffer(“abc”).equals(newStringBuffer(“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 集合類中時會出現問題。

  1. 如何把一段逗號分割的字符串轉換成一個數組?

如果不查 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();}

  1. 數組有沒有 length()這個方法? String 有沒有 length()這個方法?數組沒有 length()這個方法,有 length 的屬性。String 有有 length()這個方法。
  2. 下面這條語句一共創建了多少個對象: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");

第一條語句打印的結果爲 false,第二條語句打印的結果爲 true,這說明 javac 編譯可以對字符串常量直接相加的表達式進行優化,不必要等到運行期去進行加法運算處理,而是在編譯時去掉其中的加號,直接將其編譯成一個這些常量相連的結果。題目中的第一行代碼被編譯器在編譯時優化後,相當於直接定義了一個”abcd”的字符串,所以,上面的代碼應該只創建了一個 String 對象。寫如下兩行代碼,

           String s ="a" + "b" + "c" + "d";

           System.out.println(s== "abcd");

最終打印的結果應該爲 true。

38try {}裏有一個 return 語句,那麼緊跟在這個 try 後的 finally {}裏的 code 會不會被執行,什麼時候被執行,在 return 前還是後?

也許你的答案是在 return 之前,但往更細地說,我的答案是在 return 中間執行,請看下面程序代碼的運行結果:

public classTest {

 

    /**

     * @paramargs 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

 

運行結果是1,爲什麼呢?主函數調用子函數並得到結果的過程,好比主函數準備一個空罐子,當子函數要返回結果時,先把結果放在罐子裏,然後再將程序邏輯返回到主函數。所謂返回,就是子函數說,我不運行了,你主函數繼續運行吧,這沒什麼結果可言,結果是在說這話之前放進罐子裏的。

39、下面的程序代碼輸出的結果是多少?

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 classTest {

 

    /**

     * @paramargs add by zxx ,Dec 9, 2008

     */     public static voidmain(String[] args) {        // TODO Auto-generated method stub

       System.out.println(newTest().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 語句後執行

 

  1. final, finally, finalize 的區別。

final 用於聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。

內部類要訪問局部變量,局部變量必須定義成 final 類型,例如,一段代碼…… finally 是異常處理語句結構的一部分,表示總是執行。

finalize 是 Object 類的一個方法,在垃圾收集器執行的時候會調用被回收對象的此方法,可以覆蓋此方法提供垃圾收集時的其他資源回收,例如關閉文件等。JVM 不保證此方法總被調用

 

  1. 運行時異常與一般異常有何異同?

異常表示程序運行過程中可能出現的非正常狀態,運行時異常表示虛擬機的通常操作中可能遇到的異常,是一種常見運行錯誤。java 編譯器要求方法必須聲明拋出可能發生的非運行時異常,但是並不要求必須聲明拋出未被捕獲的運行時異常。

  1. error exception 有什麼區別?

error 表示恢復不是不可能但很困難的情況下的一種嚴重問題。比如說內存溢出。不可能指望程序能處理這樣的情況。 exception 表示一種設計或實現問題。也就是說,它表示如果程序運行正常,從不會發生的情況。

 

  1. 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 異常。

 

提示答題者:就按照三個級別去思考:虛擬機必須宕機的錯誤,程序可以死掉也可以不死掉的錯誤,程序不應該死掉的錯誤;

  1. 請寫出你最常見到的 5 runtime exception

這道題主要考你的代碼量到底多大,如果你長期寫代碼的,應該經常都看到過一些系統方面的異常,你不一定真要回答出5個具體的系統異常,但你要能夠說出什麼是系統異常,以及幾個系統異常就可以了,當然,這些異常完全用其英文名稱來寫是最好的,如果實在寫不出,那就用中文吧,有總比沒有強!

所謂系統異常,就是…..,它們都是 RuntimeException 的子類,在 jdk doc 中查

RuntimeException 類,就可以看到其所有的子類列表,也就是看到了所有的系統異常。我比較有印象的系統異常有:NullPointerException、ArrayIndexOutOfBoundsException、

ClassCastException。

  1. JAVA 語言如何進行異常處理,關鍵字:throws,throw,try,catch,finally 分別代表什麼意義?在 try 塊中可以拋出異常嗎?

throws 捕獲並向外拋出異常 throw 拋出異常

try catch 是內部捕獲異常並做自定義處理

finally 是無論是否有異常都會被處理的語句,除非在 finally 前存在被執行的

System.exit(int i)時除外

  1. java 中有幾種方法可以實現一個線程?用什麼關鍵字修飾同步方法? stop() suspend()方法爲何不推薦使用?

 

java5以前,有如下兩種:第一種:

new Thread(){}.start();這表示調用 Thread 子類對象的 run 方法,new Thread(){}表示一個

Thread 的匿名子類的實例對象,子類加上 run 方法後的代碼如下:

new Thread(){    public void run(){

   }

}.start();

 

第二種:

new Thread(new Runnable(){}).start();這表示調用Thread對象接受的Runnable對象的run 方法,new Runnable(){}表示一個 Runnable 的匿名子類的實例對象,runnable 的子類加上 run 方法後的代碼如下:

new Thread(new Runnable(){                public voidrun(){

               }    

        }

   ).start();

  

  

從 java5開始,還有如下一些線程池創建多線程的方式:

ExecutorService pool = Executors.newFixedThreadPool(3)

for(int i=0;i<10;i++)

{

 pool.execute(newRunable(){public void run(){}});

}

Executors.newCachedThreadPool().execute(new Runable(){publicvoid run(){}});

Executors.newSingleThreadExecutor().execute(new Runable(){publicvoid run(){}});

 

 

 

有兩種實現方法,分別使用 new Thread()和 new Thread(runnable)形式,第一種直接調用 thread 的 run 方法,所以,我們往往使用 Thread 子類,即 new SubThread()。第二種調用 runnable 的 run 方法。

 

有兩種實現方法,分別是繼承 Thread 類與實現 Runnable 接口synchronized 關鍵字修飾同步方法

反對使用 stop(),是因爲它不安全。它會解除由線程獲取的所有鎖定,而且如果對象處於一種不連貫狀態,那麼其他線程能在那種狀態下檢查和修改它們。結果很難檢查出真正的問題所在。suspend()方法容易發生死鎖。調用 suspend()的時候,目標線程會停下來,但卻仍然持有在這之前獲得的鎖定。此時,其他任何線程都不能訪問鎖定的資源,除非被"掛起"的線程恢復運行。對任何線程來說,如果它們想恢復目標線程,同時又試圖使用任何一個鎖定的資源,就會造成死鎖。所以不應該使用 suspend(),而應在自己的 Thread 類中置入一個標誌,指出線程應該活動還是掛起。若標誌指出線程應該掛起,便用 wait()命其進入等待狀態。若標誌指出線程應當恢復,則用一個 notify()重新啓動線程。

47sleep() 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;

 

publicclass MultiThread {

 

    /**

     * @paramargs

     */     public static voidmain(String[] args) {        // TODO Auto-generated method stub        new Thread(newThread1()).start();        try {

           Thread.sleep(10);

       } catch (InterruptedException e) {            // TODO Auto-generated catchblock

           e.printStackTrace();        }        new Thread(newThread2()).start();    

    }

            private static classThread1implements Runnable

    {

 

       @Override        public void run() {

           // TODO Auto-generated methodstub

//由於這裏的 Thread1和下面的 Thread2內部 run 方法要用同一對象作爲監視器,我們這裏不能用 this,因爲在 Thread2裏面的 this 和這個 Thread1的 this 不是同一個對象。我們用 MultiThread.class 這個字節碼對象,當前虛擬機裏引用這個變量時,指向的都是同一個對象。

           synchronized (MultiThread.class){

 

              System.out.println("enterthread1...");

             

              System.out.println("thread1is waiting");

              try {

           //釋放鎖有兩種方式,第一種方式是程序自然離開監視器的範圍,也就是離開了 synchronized 關鍵字管轄的代碼範圍,另一種方式就是在 synchronized 關鍵字管轄的代碼內部調用監視器對象的 wait 方法。這裏,使用 wait 方法釋放鎖。

                  MultiThread.class.wait();

              } catch(InterruptedException e) {                   // TODO Auto-generatedcatch block

                  e.printStackTrace();

              }

             

              System.out.println("thread1is going on...");

              System.out.println("thread1is being over!");       

           }

       }

      

    }         private static classThread2implements Runnable

    {

 

       @Override        public void run() {

           // TODO Auto-generated methodstub            synchronized (MultiThread.class){

          

              System.out.println("enterthread2...");

             

              System.out.println("thread2notify other thread can release wait status..");

//由於 notify 方法並不釋放鎖,即使 thread2調用下面的 sleep 方法休息了10毫秒,但 thread1 仍然不會執行,因爲 thread2沒有釋放鎖,所以 Thread1無法得不到鎖。

 

              MultiThread.class.notify();

             

              System.out.println("thread2is sleeping ten millisecond...");               try {

                  Thread.sleep(10);

              } catch (InterruptedExceptione) {                   // TODO Auto-generatedcatch block

                  e.printStackTrace();

              }

             

              System.out.println("thread2is going on...");

              System.out.println("thread2is being over!");

             

           }

       }

      

    }  

 

}

 

 

48、同步和異步有何異同,在什麼情況下分別使用他們?舉例說明。

 

如果數據將在線程間共享。例如正在寫的數據以後可能被另一個線程讀到,或者正在讀的數據可能已經被另一個線程寫過了,那麼這些數據就是共享數據,必須進行同步存取。當應用程序在對象上調用了一個需要花費很長時間來執行的方法,並且不希望讓程序等待方法的返回時,就應該使用異步編程,在很多情況下采用異步途徑往往更有效率。

 

49. 下面兩個方法同步嗎?(自己發明)

    class Test

{

synchronizedstatic  void say Hello3()

        {

      

        }  

   

        synchronizedvoid  getX(){}

}

  1. 多線程有幾種實現方法?同步有幾種實現方法?

多線程有兩種實現方法,分別是繼承 Thread 類與實現 Runnable 接口同步的實現方面有兩種,分別是 synchronized,wait notify wait():使一個線程處於等待狀態,並且釋放所持有的對象的 lock。

sleep():使一個正在運行的線程處於睡眠狀態,是一個靜態方法,調用此方法要捕捉

InterruptedException(中斷異常)異常。

notify():喚醒一個處於等待狀態的線程,注意的是在調用此方法的時候,並不能確切的喚醒某一個等待狀態的線程,而是由 JVM 確定喚醒哪個線程,而且不是按優先級。

Allnotity():喚醒所有處入等待狀態的線程,注意並不是給所有喚醒線程一個對象的鎖,而是讓它們競爭。

 

 

  1. 啓動一個線程是用 run()還是 start()? .

啓動一個線程是調用 start()方法,使線程就緒狀態,以後可以被調度爲運行狀態,一個線程必須關聯一些具體的執行代碼,run()方法是該線程所關聯的執行代碼。

 

  1. 當一個線程進入一個對象的一個 synchronized 方法後,其它線程是否可進入此對象的其它方法?

分幾種情況:

    1. 其他方法前是否加了 synchronized 關鍵字,如果沒加,則能。
    2. 如果這個方法內部調用了 wait,則可以進入其他 synchronized 方法。
    3. 如果其他個方法都加了 synchronized 關鍵字,並且內部沒有調用 wait,則不能。
    4. 如果其他方法是 static,它用的同步鎖是當前類的字節碼,與非靜態的方法不能同步,因爲非靜態的方法用的是 this。

 

  1. 線程的基本概念、線程的基本狀態以及狀態之間的關係

 

一個程序中可以有多條執行線索同時執行,一個線程就是程序中的一條執行線索,每個線程上都關聯有要執行的代碼,即可以有多段程序代碼同時運行,每個程序至少都有一個線程,即 main 方法執行的那個線程。如果只是一個 cpu,它怎麼能夠同時執行多段程序呢?這是從宏觀上來看的,cpu 一會執行 a 線索,一會執行 b 線索,切換時間很快,給人的感覺是 a,b 在同時執行,好比大家在同一個辦公室上網,只有一條鏈接到外部網線,其實,這條網線一會爲 a 傳數據,一會爲 b 傳數據,由於切換時間很短暫,所以,大家感覺都在同時上網。

 

  狀態:就緒,運行,synchronize 阻塞,wait 和 sleep 掛起,結束。wait 必須在 synchronized 內部調用。

  調用線程的 start 方法後線程進入就緒狀態,線程調度系統將就緒狀態的線程轉爲運行狀態,遇到 synchronized 語句時,由運行狀態轉爲阻塞,當 synchronized 獲得鎖後,由阻塞轉爲運行,在這種情況可以調用 wait 方法轉爲掛起狀態,當線程關聯的代碼執行完後,線程變爲結束狀態。

 

  1. 簡述 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;

  publicclass ThreadTest {     /**

     * @paramargs

     */         private int j;     private Lock lock =newReentrantLock();     public static voidmain(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 SubtractorimplementsRunnable

    {

 

       @Override        public void run() {

           // TODO Auto-generated methodstub            while(true)

           {

              /*synchronized (ThreadTest.this) {       

                  System.out.println("j--="+ j--);

                  //這裏拋異常了,鎖能釋放嗎?

              }*/               lock.lock();               try

              {

                  System.out.println("j--="+ j--);

              }finally               {                   lock.unlock();

              }

           }

       }

      

    }         private class AdderimplementsRunnable

    {

 

       @Override        public void run() {

           // TODO Auto-generated methodstub            while(true)

           {

              /*synchronized (ThreadTest.this) {

              System.out.println("j++="+ j++); 

              }*/               lock.lock();                try

              {

                  System.out.println("j++="+ j++);

              }finally               {                   lock.unlock();

              }            

           }         

       }

      

    }

}

55、設計 4 個線程,其中兩個線程每次對 j 增加 1,另外兩個線程對 j 每次減少 1。寫出程序。以下程序使用內部類實現線程,對 j 增減的時候沒有考慮順序問題。

public class ThreadTest1

{ private int j; public static void main(String args[]){

   ThreadTest1 tt=newThreadTest1();

   Inc inc=tt.new Inc();    Dec dec=tt.new Dec();    for(inti=0;i<2;i++){

       Thread t=newThread(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(inti=0;i<100;i++){        inc();

       }

   }

}

class Dec implements Runnable{    public void run(){        for(inti=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(                newRunnable(){ public void run(){while(true){j.accumulate()}}}

        ).start();

        new Thread(newRunnable(){ public void run(){while(true){j.sub()}}}).start();    }

}

}   class JManager

{

   private j = 0;

      public synchronized voidsubtract()

   {         j--

   }       public synchronized voidaccumulate()

   {         j++;

   }

  

}

 

56、子線程循環 10 次,接着主線程循環 100,接着又回到子線程循環 10 次,接着再回到主線程又循環 100,如此循環 50 次,請寫出程序。

 

最終的程序代碼如下:

public class ThreadTest {

 

    /**

     * @paramargs

     */

    public static voidmain(String[] args) {        // TODO Auto-generated method stub        new ThreadTest().init();

 

    }       public void init()     {        final Business business =newBusiness();        new Thread(               new Runnable()

              {

                    public voidrun() {                      for(inti=0;i<50;i++)                      {                          business.SubThread(i);

                     }                   

                  }

                 

              }

      

       ).start();               for(int i=0;i<50;i++)        {            business.MainThread(i);

       }     

    }         private class Business     {

       booleanbShouldSub =true;//這裏相當於定義了控制該誰執行的一個信號燈

       public synchronized voidMainThread(int i)

       {            if(bShouldSub)               try {                   this.wait();

              } catch(InterruptedException e) {                   // TODO Auto-generatedcatch 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 voidSubThread(int i)

       {            if(!bShouldSub)               try {                   this.wait();

              } catch (InterruptedExceptione) {                   // TODO Auto-generatedcatch block

                  e.printStackTrace();

              }  

                         for(intj=0;j<10;j++)

           {

              System.out.println(Thread.currentThread().getName()+ ":i=" + i +",j=" + j);

           }            bShouldSub =false;                        this.notify();          

       }

    }

}

 

備註:不可能一上來就寫出上面的完整代碼,最初寫出來的代碼如下,問題在於兩個線程的代碼要參照同一個變量,即這兩個線程的代碼要共享數據,所以,把這兩個線程的執行代碼搬到同一個類中去:

  package com.huawei.interview.lym;

  publicclass ThreadTest {

        private static booleanbShouldMain=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 = newString("");

 

       new Thread(               new Runnable()

              {                   public voidrun()

                  {                      for(inti=0;i<50;i++)

                     {                          synchronized(ThreadTest.class) {                             if(bShouldMain)

                            {                                 try {

                                   ThreadTest.class.wait();}                                 catch(InterruptedException e) {

                                   e.printStackTrace();

                                }                             }                             for(intj=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(intj=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 Locklock = new ReentrantLock();        private staticCondition subThreadCondition = lock.newCondition();        private staticboolean bBhouldSubThread = false;        public static voidmain(String [] args)

       {

              ExecutorServicethreadPool = Executors.newFixedThreadPool(3);               threadPool.execute(newRunnable(){                      publicvoid run()

                     {                             for(inti=0;i<50;i++)

                            {                                    lock.lock();                                                                    try

                                   {                                                                           if(!bBhouldSubThread)                                                  subThreadCondition.await();                                           for(intj=0;j<10;j++)

                                          {

                                                

System.out.println(Thread.currentThread().getName()+ ",j=" + j);

                                          }

                                          bBhouldSubThread= false;                                           subThreadCondition.signal();

                                   }catch(Exceptione)

                                   {                                       

                                   }                                    finally                                    {                                           lock.unlock();

                                   }

                            }                  

                     }

                                   });               threadPool.shutdown();               for(inti=0;i<50;i++)

              {                             lock.lock();                                                             try                             {                                        if(bBhouldSubThread)                                                  subThreadCondition.await();                                                          for(intj=0;j<10;j++)

                                   {

                                         

System.out.println(Thread.currentThread().getName()+ ",j=" + j);

                                   }                                    bBhouldSubThread= true;                                    subThreadCondition.signal();                            

                            }catch(Exceptione)

                            {                                        

                            }

                            finally

                            {                                    lock.unlock();

                            }                                

              }

       }

}

  1. 介紹 Collection 框架的結構

答:隨意發揮題,天南海北誰便談,只要讓別覺得你知識淵博,理解透徹即可。

 

  1. Collection 框架中實現比較要實現什麼接口

comparable/comparator

  1. 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倍。

60HashMap 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

  1. List Map 區別?

一個是存儲單列數據的集合,另一個是存儲鍵和值這樣的雙列數據的集合,List 中存儲的數據是有順序,並且允許重複;Map 中存儲的數據是沒有順序的,其鍵是不能重複的,它的值是可以有重複的。

  1. List, Set, Map 是否繼承自 Collection 接口?

   List,Set 是,Map 不是

  1. ListMapSet 三個接口,存取元素時,各有什麼特點?

這樣的題屬於隨意發揮題:這樣的題比較考水平,兩個方面的水平:一是要真正明白這些內容,二是要有較強的總結和表述能力。如果你明白,但表述不清楚,在別人那裏則等同於不明白。

 

首先,List 與 Set 具有相似性,它們都是單列元素的集合,所以,它們有一個功共同的父接口,叫 Collection。Set 裏面不允許有重複的元素,所謂重複,即不能有兩個相等(注意,不是僅僅是相同)的對象,即假設 Set 集合中有了一個 A 對象,現在我要向 Set 集合再存入一個 B 對象,但 B 對象與 A 對象 equals 相等,則 B 對象存儲不進去,所以,Set 集合的 add 方法有一個 boolean 的返回值,當集合中沒有某個元素,此時 add 方法可成功加入該元素時,則返回 true,當集合含有與某個元素 equals 相等的元素時,此時 add 方法無法加入該元素,返回結果爲 false。Set 取元素時,沒法說取第幾個,只能以 Iterator 接口取得所有的元素,再逐一遍歷各個元素。

       List 表示有先後順序的集合,注意,不是那種按年齡、按大小、按價格之類的排序。當我們多次調用 add(Obj e)方法時,每次加入的對象就像火車站買票有排隊順序一樣,按先來後到的順序排序。有時候,也可以插隊,即調用 add(int index,Obj e)方法,就可以指定當前對象在集合中的存放位置。一個對象可以被反覆存儲進 List 中,每調用一次 add 方法,這個對象就被插入進集合中一次,其實,並不是把這個對象本身存儲進了集合中,而是在集合中用一個索引變量指向這個對象,當這個對象被 add 多次時,即相當於集合中有多個索引指向了這個對象,如圖 x 所示。List 除了可以以 Iterator 接口取得所有的元素,再逐一遍歷各個元素之外,還可以調用 get(index i)來明確說明取第幾個。

       Map 與 List 和 Set 不同,它是雙列的集合,其中有 put 方法,定義如下:put(obj key,objvalue),每次存儲時,要存儲一對 key/value,不能存儲重複的 key,這個重複的規則也是按 equals 比較相等。取則可以根據 key 獲得相應的 value,即 get(Object key)返回值爲 key 所對應的 value。另外,也可以獲得所有的 key 的結合,還可以獲得所有的 value 的結合,還可以獲得 key 和 value 組合成的 Map.Entry 對象的集合。

 

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 中卻加不了多次的。

 

  1. 說出 ArrayList,Vector, LinkedList 的存儲性能和特性

ArrayList 和 Vector 都是使用數組方式存儲數據,此數組元素數大於實際存儲的數據以便增加和插入元素,它們都允許直接按序號索引元素,但是插入元素要涉及數組元素移動等內存

操作,所以索引數據快而插入數據慢,Vector 由於使用了 synchronized 方法(線程安全),通常性能上較 ArrayList 差,而 LinkedList 使用雙向鏈表實現存儲,按序號索引數據需要進行前向或後向遍歷,但是插入數據時只需要記錄本項的前後項即可,所以插入速度較快。

 

LinkedList 也是線程不安全的,LinkedList 提供了一些方法,使得 LinkedList 可以被當作堆棧和隊列來使用。

  1. 去掉一個 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); 66Collection Collections 的區別。

Collection 是集合類的上級接口,繼承與他的接口主要有 Set 和 List.

Collections 是針對集合類的一個幫助類,他提供一系列靜態方法實現對各種集合的搜索、排序、線程安全化等操作。

  1. Set 裏的元素是不能重複的,那麼用什麼方法來區分重複與否呢?是用==還是 equals()?它們有何區別?

Set 裏的元素是不能重複的,元素重複與否是使用 equals()方法進行判斷的。

   equals()和==方法決定引用值是否指向同一對象 equals()在類中被覆蓋,爲的是當兩個分離的對象的內容和類型相配的話,返回真值。

  1. 你所知道的集合類都有哪些?主要方法?

最常用的集合類是 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。

 

  1. 兩個對象值相同(x.equals(y) == true),但卻可有不同的 hash code,這句話對不對?

對。

如果對象要保存在 HashSet 或 HashMap 中,它們的 equals 相等,那麼,它們的 hashcode 值就必須相等。

如果不是要保存在HashSet或HashMap,則與hashcode沒有什麼關係了,這時候hashcode 不等是可以的,例如 arrayList 存儲的對象就不用實現 hashcode,當然,我們沒有理由不實現,通常都會去實現的。

  1. TreeSet 裏面放對象,如果同時放入了父類和子類的實例對象,那比較時使用的是父類的 compareTo 方法,還是使用的子類的 compareTo 方法,還是拋異常!

(應該是沒有針對問題的確切的答案,當前的 add 方法放入的是哪個對象,就調用哪個對象的 compareTo 方法,至於這個 compareTo 方法怎麼做,就看當前這個對象的類中是如何編寫這個方法的)實驗代碼:

public class ParentimplementsComparable {     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 ofparent");        Parent o1 = (Parent)o;        return age>o1.age?1:age<o1.age?-1:0;

    }

 

}   public class Childextends Parent {     public Child(){        super(3);     }     public int compareTo(Object o){

 

           // TODO Auto-generated methodstub

           System.out.println("methodof child"); //         Child o1 = (Child)o;            return 1;

 

    }

}   public class TreeSetTest {

 

    /**

     * @paramargs

     */     public static voidmain(String[] args) {

       // TODO Auto-generated method stub        TreeSet set = new TreeSet();        set.add(newParent(3));        set.add(new Child());        set.add(newParent(4));

       System.out.println(set.size());

    }

 

}

 

  1. 說出一些常用的類,包,接口,請各舉 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

  1. java 中有幾種類型的流?JDK 爲每種類型的流提供了一些抽象類以供繼承,請說出他們分別是哪些類?

字節流,字符流。字節流繼承於 InputStream OutputStream,字符流繼承於

InputStreamReaderOutputStreamWriter。在 java.io 包中還有許多其他的流,主要是爲了提高性能和使用方便。

  1. 字節流與字符流的區別

       要把一片二進制數據數據逐一輸出到某個設備中,或者從某個設備中逐一讀取一片二進制數據,不管輸入輸出設備是什麼,我們要用統一的方式來完成這些操作,用一種抽象的方式進行描述,這個抽象描述方式起名爲 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 = "中國人";

        /*FileOutputStreamfos  = newFileOutputStream("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 = newchar[1024];         int len =fr.read(buf);

        String myStr = newString(buf,0,len);

        System.out.println(myStr);*/

        /*FileInputStreamfr = new FileInputStream("1.txt");         byte[] buf = newbyte[1024];

        int len =fr.read(buf);

        String myStr = newString(buf,0,len,"UTF-8");

        System.out.println(myStr);*/

        BufferedReader br =new BufferedReader(                       newInputStreamReader(                              newFileInputStream("1.txt"),"UTF-8"

                             )

                      );

        String myStr =br.readLine();         br.close();

        System.out.println(myStr);

   }

 

}

  1. 什麼是 java 序列化,如何實現 java 序列化?或者請解釋 Serializable 接口的作用。

 

我們有時候將一個 java 對象變成字節流的形式傳出去或者從一個字節流中恢復成一個 java 對象,例如,要將 java 對象存儲到硬盤或者傳送給網絡上的其他計算機,這個過程我們可以自己寫代碼去把一個 java 對象變成某個格式的字節流再傳輸,但是,jre 本身就提供了這種支持,我們可以調用 OutputStream 的 writeObject 方法來做,如果要讓 java 幫我們做,要被傳輸的對象必須實現 serializable 接口,這樣,javac 編譯時就會進行特殊處理,編譯的類纔可以被 writeObject 方法操作,這就是所謂的序列化。需要被序列化的類必須實現 Serializable 接口,該接口是一個 mini 接口,其中沒有需要實現的方法, implementsSerializable 只是爲了標註該對象是可被序列化的。

 

 

例如,在 web 開發中,如果對象被保存在了 Session 中,tomcat 在重啓時要把 Session 對象序列化到硬盤,這個對象就必須實現 Serializable 接口。如果對象要經過分佈式系統進行網絡傳輸或通過 rmi 等遠程調用,這就需要在網絡上傳輸對象,被傳輸的對象就必須實現

Serializable 接口。

  1. 描述一下 JVM 加載 class 文件的原理機制?

JVM 中類的裝載是由 ClassLoader 和它的子類來實現的,Java ClassLoader 是一個重要的

Java 運行時系統組件。它負責在運行時查找和裝入類文件的類。

 

  1. heap stack 有什麼區別。

java 的內存分爲兩類,一類是棧內存,一類是堆內存。棧內存是指程序進入一個方法時,會爲這個方法單獨分配一塊私屬存儲空間,用於存儲這個方法內部的局部變量,當這個方法結束時,分配給這個方法的棧會釋放,這個棧中的變量也將隨之釋放。

堆是與棧作用不同的內存,一般用於存放不放在當前方法棧中的那些數據,例如,使用 new 創建的對象都放在堆裏,所以,它不會隨方法的結束而消失。方法中的局部變量使用 final 修飾後,放在堆中,而不是棧中。

 

  1. GC 是什麼?爲什麼要有 GC?

GC 是垃圾收集的意思(Gabage Collection),內存處理是編程人員容易出現問題的地方,忘記或者錯誤的內存回收會導致程序或系統的不穩定甚至崩潰,Java 提供的 GC 功能可以自動監測對象是否超過作用域從而達到自動回收內存的目的,Java 語言沒有提供釋放已分配內存的顯示操作方法。

 

  1. 垃圾回收的優點和原理。並考慮 2 種回收機制。

Java 語言中一個顯著的特點就是引入了垃圾回收機制,使 c++程序員最頭疼的內存管理的問題迎刃而解,它使得 Java 程序員在編寫程序的時候不再需要考慮內存管理。由於有個垃圾回收機制,Java 中的對象不再有"作用域"的概念,只有對象的引用纔有"作用域"。垃圾回收可以有效的防止內存泄露,有效的使用可以使用的內存。垃圾回收器通常是作爲一個單獨的低級別的線程運行,不可預知的情況下對內存堆中已經死亡的或者長時間沒有使用的對象進行清楚和回收,程序員不能實時的調用垃圾回收器對某個對象或所有對象進行垃圾回收。

回收機制有分代複製垃圾回收和標記垃圾回收,增量垃圾回收。

 

  1. 垃圾回收器的基本原理是什麼?垃圾回收器可以馬上回收內存嗎?有什麼辦法主動通知虛擬機進行垃圾回收?

對於 GC 來說,當程序員創建對象時,GC 就開始監控這個對象的地址、大小以及使用情況。通常,GC 採用有向圖的方式記錄和管理堆(heap)中的所有對象。通過這種方式確定哪些對象是"可達的",哪些對象是"不可達的"。當 GC 確定一些對象爲"不可達"時,GC 就有責任回收這些內存空間。可以。程序員可以手動執行 System.gc(),通知 GC 運行,但是 Java 語言規範並不保證 GC 一定會執行。

 

 

  1. 什麼時候用 assert

assertion(斷言)在軟件開發中是一種常用的調試方式,很多開發語言中都支持這種機制。在實現中,assertion 就是在程序中的一條語句,它對一個 boolean 表達式進行檢查,一個正確程序必須保證這個 boolean 表達式的值爲 true;如果該值爲 false,說明程序已經處於不正確的狀態下,assert 將給出警告或退出。一般來說,assertion 用於保證程序最基本、關鍵的正確性。assertion 檢查通常在開發和測試時開啓。爲了提高性能,在軟件發佈後,

assertion 檢查通常是關閉的。

package com.huawei.interview;

  publicclass AssertTest {

 

    /**

     * @paramargs

     */     public static voidmain(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;     

    }

 

}

 

81java 中會存在內存泄漏嗎,請簡單描述。

所謂內存泄露就是指一個不再被程序使用的對象或變量一直被佔據在內存中。java 中有垃圾回收機制,它可以保證一對象不再被引用的時候,即對象編程了孤兒的時候,對象將自動被垃圾回收器從內存中清除掉。由於 Java 使用有向圖的方式進行垃圾回收管理,可以消除引用循環的問題,例如有兩個對象,相互引用,只要它們和根進程不可達的,那麼 GC 也是可以回收它們的,例如下面的代碼可以看到這種情況的內存回收:

package com.huawei.interview;

  import java.io.IOException;

  publicclass GarbageTest {

 

    /**

  • @paramargs
  • @throwsIOException

     */     public static voidmain(String[] args)throws IOException {

       // TODO Auto-generated method stub        try {            gcTest();

       } catch (IOException e) {

           // TODO Auto-generated catch block

           e.printStackTrace();

       }

       System.out.println("hasexited gcTest!");

       System.in.read();

       System.in.read();   

       System.out.println("out begingc!");             for(int i=0;i<100;i++)

       {

           System.gc();

           System.in.read();

           System.in.read();

       }

    }       private static voidgcTest()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("beforeexit gctest!");

       System.in.read();

       System.in.read();   

       System.gc();

       System.out.println("exitgctest!");

    }       private static classPerson

    {        byte[] data =new byte[20000000];        Person mate = null;        public void setMate(Personother)

       {            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個引用,最壞的情況就是他們都是無用的,因爲我們一旦放新的進取,以前的引用自然消失!

 

內存泄露的另外一種情況:當一個對象被存儲進 HashSet 集合中以後,就不能修改這個對象中的那些參與計算哈希值的字段了,否則,對象修改後的哈希值與最初存儲進 HashSet 集合中時的哈希值就不同了,在這種情況下,即使在 contains 方法使用該對象的當前引用作爲的參數去 HashSet 集合中檢索對象,也將返回找不到對象的結果,這也會導致無法從

HashSet 集合中單獨刪除當前對象,造成內存泄露。

 

 

 

82、能不能自己寫個類,也叫 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;

  publicclass String {

 

    /**

     * @paramargs

     */     public static voidmain(String[] args) {

       // TODO Auto-generated method stub

       System.out.println("string");

    }

 

}

報告的錯誤如下:

java.lang.NoSuchMethodError:main

Exception inthread "main"

這是因爲加載了 jre 自帶的 java.lang.String,而該類中沒有 main 方法。

 

83. 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-staticmethods。可改成"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("Dosomething ...");

    }

}

 這個好像很明顯。

答案: 正確。從來沒有人說過 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 staticfinal.

所以可以通過 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 = newBall("Football");

        System.out.println(ball.getName());

    }

}

這個錯誤不容易發現。

答案: 錯。"interfaceRollable extends Playable, Bounceable"沒有問題。interface 可繼承多個 interfaces,所以這裏沒錯。問題出在 interface Rollable 裏的"Ball ball =new Ball("PingPang");"。任何在 interface 裏聲明的 interface variable (接口變量,也可稱成員變

量),默認爲 public static final。也就是說"Ball ball = new Ball("PingPang");"實際上是"public staticfinal Ball ball = new Ball("PingPang");"。在 Ball 類的 Play()方法中,"ball = newBall("Football");"改變了ball的reference,而這裏的ball來自Rollable interface,Rollable interface 裏的 ball 是 public static final 的,final 的 object 是不能被改變 reference 的。因此編譯器將在"ball = newBall("Football");"這裏顯示有錯。

.算法與編程

1、編寫一個程序,將 a.txt 文件中的單詞與 b.txt 文件中的單詞交替合併到 c.txt 文件中,a.txt 文件中的單詞用回車符分隔,b.txt 文件中用回車或空格進行分隔。

答:

packagecn.itcast;

  import java.io.File; import java.io.FileReader; import java.io.FileWriter;

  public class MainClass{        public static voidmain(String[] args) throws Exception{

              FileManager a= new FileManager("a.txt",new char[]{'\n'});

              FileManager b= new FileManager("b.txt",new char[]{'\n',' '});         

              FileWriter c= new FileWriter("c.txt");

              String aWord= null;

              String bWord= null;               while((aWord= a.nextWord()) !=null ){

                     c.write(aWord+ "\n");                      bWord= b.nextWord();                      if(bWord!= null)

                            c.write(bWord+ "\n");

              }                             while((bWord= b.nextWord()) != null){

                     c.write(bWord+ "\n");

              }    

              c.close();

       }

      

}

 

  class FileManager{

 

       String[] words =null;        int pos = 0;        publicFileManager(String filename,char[] seperators) throws Exception{

              File f = newFile(filename);

              FileReaderreader = new FileReader(f);               char[] buf =new char[(int)f.length()];               int len =reader.read(buf);

              Stringresults = new String(buf,0,len);               String regex= null;               if(seperators.length>1 ){                      regex= "" + seperators[0] + "|" + seperators[1];

              }else{

                     regex= "" + seperators[0];

              }               words =results.split(regex);

       }               public StringnextWord(){               if(pos ==words.length)                      returnnull;               returnwords[pos++];

       }

 

}

 

2、編寫一個程序,將 d:\java 目錄下的所有.java 文件複製到 d:\jad 目錄下,並將原來文件的擴展名從.java 改爲.jad

(大家正在做上面這道題,網上遲到的朋友也請做做這道題,找工作必須能編寫這些簡單問題的代碼!)答:listFiles 方法接受一個 FileFilter 對象,這個 FileFilter 對象就是過慮的策略對象,不同的人提供不同的 FileFilter 實現,即提供了不同的過濾策略。

import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream;

  public class Jad2Java {

         public static voidmain(String[] args) throws Exception {

              File srcDir =new File("java");

              if(!(srcDir.exists()&& srcDir.isDirectory()))                             thrownew Exception("目錄不存在");

              File[] files= srcDir.listFiles(                      newFilenameFilter(){

                                     publicboolean accept(File dir, String name) {                                           returnname.endsWith(".java");

                                   }

                                   

                            }

              );

             

              System.out.println(files.length);               File destDir= new File("jad");               if(!destDir.exists())destDir.mkdir();               for(File f:files){

                     FileInputStream  fis = new FileInputStream(f);

                     StringdestFileName = f.getName().replaceAll("\\.java$", ".jad");

                     FileOutputStreamfos = new FileOutputStream(new File(destDir,destFileName));                      copy(fis,fos);                      fis.close();                      fos.close();

              }

       }               private static voidcopy(InputStream ips,OutputStream ops) throws Exception{               int len = 0;               byte[] buf =new byte[1024];               while((len =ips.read(buf)) != -1){                      ops.write(buf,0,len);

              }

 

       }

}

 

由本題總結的思想及策略模式的解析:

1.

class jad2java{

  1. 得到某個目錄下的所有的 java 文件集合
    1. 得到目錄 File srcDir = newFile("d:\\java");
    2. 得到目錄下的所有 java 文件:File[] files =srcDir.listFiles(new

MyFileFilter());

    1. 只想得到.java 的文件: class MyFileFilterimplememyts FileFilter{                      publicboolean accept(File pathname){                             returnpathname.getName().endsWith(".java")

                     }

              }

             

       2.將每個文件複製到另外一個目錄,並改擴展名

    1. 得到目標目錄,如果目標目錄不存在,則創建之
    2. 根據源文件名得到目標文件名,注意要用正則表達式,注意.的轉義。
    3. 根據表示目錄的File和目標文件名的字符串,得到表示目標文件的File。

                     //要在硬盤中準確地創建出一個文件,需要知道文件名和文件的目錄。

    1. 將源文件的流拷貝成目標文件流,拷貝方法獨立成爲一個方法,方法的參數採用抽象流的形式。

                     //方法接受的參數類型儘量面向父類,越抽象越好,這樣適應面更寬廣。 

}

 

分析 listFiles 方法內部的策略模式實現原理

File[] listFiles(FileFilter filter){

       File[] files =listFiles();

       //ArraylistacceptedFilesList = new ArrayList();        File[] acceptedFiles= new File[files.length];        int pos = 0;        for(File file:files){               booleanaccepted = filter.accept(file);               if(accepted){

                     //acceptedFilesList.add(file);                      acceptedFiles[pos++]= file;

              }           

       }

      

       Arrays.copyOf(acceptedFiles,pos);

       //return(File[])accpetedFilesList.toArray();

      

}

3、編寫一個截取字符串的函數,輸入爲一個字符串和字節數,輸出爲按字節截取的字符串,但要保證漢字不被截取半個,如“我 ABC”,4,應該截取“我 AB”,輸入“我 ABC DEF”,6,應該輸出“我 ABC”,而不是“我 ABC+漢的半個”。

答:        首先要了解中文字符有多種編碼及各種編碼的特徵。     假設 n 爲要截取的字節數。

       public static voidmain(String[] args) throws Exception{

              String str ="我 a 愛中華 abc 我愛傳智 def';               String str ="我 ABC 漢";               int num =trimGBK(str.getBytes("GBK"),5);

              System.out.println(str.substring(0,num));

       }

      

       public staticint  trimGBK(byte[] buf,int n){               int num = 0;               booleanbChineseFirstHalf = false;               for(inti=0;i<n;i++)

              {                      if(buf[i]<0&& !bChineseFirstHalf){                             bChineseFirstHalf= true;

                     }else{                             num++;                             bChineseFirstHalf= false;                         

                     }               }               return num;

       }

4、有一個字符串,其中包含中文字符、英文字符和數字字符,請統計和打印出各個字符的個數。

答:哈哈,其實包含中文字符、英文字符、數字字符原來是出題者放的煙霧彈。

String content = “中國 aadf 的111薩 bbb 菲的 zz 薩菲”;

HashMap map = new HashMap();

for(int i=0;i<content.length;i++)

{

       char c =content.charAt(i);        Integer num =map.get(c);        if(num == null)               num = 1;        else               num = num +1;        map.put(c,num);

}

for(Map.EntrySet entry : map)

{

       system.out.println(entry.getkey()+ “:” + entry.getValue());

}

估計是當初面試的那個學員表述不清楚,問題很可能是:如果一串字符如"aaaabbc 中國1512"要分別統計英文字符的數量,中文字符的數量,和數字字符的數量,假設字符中沒有中文字符、英文字符、數字字符之外的其他特殊字符。

int engishCount; int chineseCount; int digitCount; for(int i=0;i<str.length;i++)

{

    charch = str.charAt(i);     if(ch>=’0’&& ch<=’9’)

    {         digitCount++

    }     elseif((ch>=’a’&& ch<=’z’) || (ch>=’A’ && ch<=’Z’))

    {         engishCount++;

    }     else     {         chineseCount++;

    }

}

System.out.println(……………);

 

5、說明生活中遇到的二叉樹,用 java 實現二叉樹這是組合設計模式。

我有很多個(假設10萬個)數據要保存起來,以後還需要從保存的這些數據中檢索是否存在某個數據,(我想說出二叉樹的好處,該怎麼說呢?那就是說別人的缺點),假如存在數組中,那麼,碰巧要找的數字位於99999那個地方,那查找的速度將很慢,因爲要從第1個依次往後取,取出來後進行比較。平衡二叉樹(構建平衡二叉樹需要先排序,我們這裏就不作考慮了)可以很好地解決這個問題,但二叉樹的遍歷(前序,中序,後序)效率要比數組低很多,原理如下圖:代碼如下:

package com.huawei.interview;

  publicclass Node {     public int value;     public Node left;     public Node right;

        public void store(intvalue)

    {        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(intvalue)

    {  

       System.out.println("happen" +this.value);        if(value ==this.value)

       {            return true;        }        else if(value>this.value)

       {            if(right ==null)returnfalse;            return right.find(value);

       }else        {            if(left ==null)returnfalse;            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 voidmain(String [] args)

    {        int [] data =new int[20];        for(inti=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(inti=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();

    }

}

-----------------又一次臨場寫的代碼--------------------------- importjava.util.Arrays; importjava.util.Iterator;

  public class Node{     private Node left;     private Node right;     private int value;

    //private int num;         public Node(int value){        this.value = value;

    }     public void add(int value){

              if(value > this.value)

       {            if(right != null)               right.add(value);            else

           {

              Node node = new Node(value);                            right = node;

           }        }        else{            if(left != null)               left.add(value);            else

           {

              Node node = new Node(value);                            left = node;

           }         

       }

    }         public boolean find(int value){        if(value == this.value) return true;        else if(value > this.value){            if(right == null) return false;            else return right.find(value);

       }else{            if(left == null) return false;            else return left.find(value);         

       }

 

    }         public void display(){        System.out.println(value);        if(left != null) left.display();        if(right != null) right.display();

      

    }

   

    /*public Iterator iterator(){

      

    }*/         public static void main(String[] args){        int[] values = new int[8];        for(int i=0;i<8;i++){            int num = (int)(Math.random() * 15);

           //System.out.println(num);            //if(Arrays.binarySearch(values,num)<0)            if(!contains(values,num))               values[i] = num;            else               i--;

       }

      

       System.out.println(Arrays.toString(values));

      

       Node root = new Node(values[0]);        for(int i=1;i<values.length;i++){            root.add(values[i]);

       }

      

       System.out.println(root.find(13));

              root.display();     }         public static boolean contains(int [] arr,int value){        int i = 0;        for(;i<arr.length;i++){            if(arr[i] == value) return true;

                  }        return false;

    }

   

}

6、從類似如下的文本文件中讀取出所有的姓名,並打印出重複的姓名和重複的次數,並按重複次數排序:

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;

 

  publicclass GetNameTest {

 

    /**

     * @paramargs

     */     public static voidmain(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 = newBufferedReader(new InputStreamReader(ips));        String line = null;        try {            while((line=in.readLine())!=null)

           {               dealLine(line,results);

           }            sortResults(results);

       } catch (IOException e) {

           // TODO Auto-generated catchblock

           e.printStackTrace();

       }

    }         static class User

    {        public  String name;        public Integer value;        public User(String name,Integervalue)

       {            this.name = name;            this.value = value;

       }

 

       @Override        public booleanequals(Object obj) {

           // TODO Auto-generated methodstub

             

           //下面的代碼沒有執行,說明往 treeset 中增加數據時,不會使用到 equals 方法。

           boolean result =super.equals(obj);            System.out.println(result);            return result;

       }

    }         private static voidsortResults(Map results) {        // TODO Auto-generated method stub        TreeSet sortedResults =newTreeSet(               new Comparator(){

                  public intcompare(Object o1, Object o2) {

                     // TODOAuto-generated method stub

                     User user1 = (User)o1;

                     User user2 = (User)o2;

                     /*如果 compareTo 返回結果0,則認爲兩個對象相等,新的對象不會增加到集合中去

  • 所以,不能直接用下面的代碼,否則,那些個數相同的其他姓名就打印不出來。
  • */

                    

                     //returnuser1.value-user2.value;

                    

//returnuser1.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                      {                          returnuser1.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(newUser(name,value));            

           }

       }               printResults(sortedResults);

    }     private static voidprintResults(TreeSet sortedResults)

    {

       Iterator iterator  = sortedResults.iterator();        while(iterator.hasNext())

       {

           User user = (User)iterator.next();

           System.out.println(user.name +":" + user.value);

       }       }     public static voiddealLine(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);

           }

       }

    }

 

}

7、寫一個 Singleton 出來。第一種:飽漢模式

public classSingleTon {     private SingleTon(){

       }

 

    //實例化放在靜態代碼塊裏可提高程序的執行效率,但也可能更佔用空間  

    private final static SingleTon instance =new SingleTon();     public static SingleTon getInstance(){        return instance;

    }

}

 

第二種:飢漢模式

public classSingleTon {     private SingleTon(){}

        private static instance = null;//newSingleTon();

        public static synchronized SingleTongetInstance(){        if(instance == null)            instance = new SingleTon();        return instance;

    }

}

 

第三種:用枚舉

    public enum SingleTon{

       ONE;

   

    }

 

第三:更實際的應用(在什麼情況用單例)

public classSequenceGenerator{

    //下面是該類自身的業務功能代碼

    private int count = 0;

      public synchronized int getSequence(){

       ++count;

    }

   

    //下面是把該類變成單例的代碼

    private SequenceGenerator(){}     private final static instance = newSequenceGenerator();     public static SingleTon getInstance(){        return instance;

    }  

   

}

 

第四:

    public class MemoryDao

    {     private HashMap map = new HashMap();

       publicvoid add(Student stu1){             map.put(SequenceGenerator.getInstance().getSequence(),stu1);

    }

  

   //把 MemoryDao 變成單例

  }

 

 

 

 

 

 

Singleton 模式主要作用是保證在 Java 應用程序中,一個類 Class 只有一個實例存在。一般 Singleton 模式通常有幾種種形式:

第一種形式: 定義一個類,它的構造函數爲 private 的,它有一個 static 的 private 的該類變量,在類初始化時實例話,通過一個 public 的 getInstance 方法獲取對它的引用,繼而調用其中的方法。

public class Singleton { private Singleton(){}

    //在自己內部定義自己一個實例,是不是很奇怪?

    //注意這是 private 只供內部調用

    private staticSingleton instance = new Singleton();

    //這裏提供了一個供外部訪問本 class 的靜態方法,可以直接訪問   

    public staticSingleton 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 的。

一般認爲第一種形式要更加安全些 8、遞歸算法題 1

一個整數,大於0,不用循環和本地變量,按照 n,2n,4n,8n 的順序遞增,當值大於5000 時,把值按照指定順序輸出來。

例:n=1237 則輸出爲:

1237,

2474,

4948,

9896,

9896,

4948,

2474,

1237,

提示:寫程序時,先致謝按遞增方式的代碼,寫好遞增的以後,再增加考慮遞減部分。

    public static void doubleNum(int n)

    {

       System.out.println(n);        if(n<=5000)            doubleNum(n*2);

       System.out.println(n);     

    }

 

Gaibaota(N) = Gaibaota(N-1) + n

 

 

 

  

9、遞歸算法題 2 第1個人10,第2個比第1個人大2歲,依次遞推,請用遞歸方式計算出第8個人多大?

package cn.itcast;

  import java.util.Date;

  publicclass A1 {

      public static voidmain(String [] args)

    {

       System.out.println(computeAge(8));

    }         public static int computeAge(intn)

    {        if(n==1)return 10;        returncomputeAge(n-1) + 2;

    }

}       public static voidtoBinary(int n,StringBuffer result)

    {          if(n/2 != 0)            toBinary(n/2,result);        result.append(n%2);     

    }

10、排序都有哪幾種方法?請列舉。用 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=newString[]{"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]+" ");

}

}

 

 

}

11、有數組 a[n],用 java 代碼將數組元素順序顛倒

//用下面的也可以

//for(inti=0,int j=a.length-1;i<j;i++,j--)是否等效於 for(int i=0;i<a.length/2;i++)呢?

  importjava.util.Arrays;

 

public classSwapDemo{

      public static void main(String[] args){        int [] a = new int[]{

                     (int)(Math.random() *1000),

                     (int)(Math.random() * 1000),

                     (int)(Math.random() *1000),

                     (int)(Math.random() *1000),                    

                     (int)(Math.random() * 1000)                                                   

       }; 

      

       System.out.println(a);

       System.out.println(Arrays.toString(a));        swap(a);        System.out.println(Arrays.toString(a));      

    }         public static void swap(int a[]){        int len = a.length;        for(int i=0;i<len/2;i++){            int tmp = a[i];            a[i] = a[len-1-i];            a[len-1-i] = tmp;

       }

    }

}

12.金額轉換,阿拉伯數字的金額轉換成中國傳統的形式如:(¥1011)->(一千零一拾一元整)輸出。

去零的代碼:

    returnsb.reverse().toString().replaceAll("零[拾佰仟]","零").replaceAll("零+萬","萬 ").replaceAll("零+元","元").replaceAll("零+","零");

  public class RenMingBi {

 

       /**

        * @param args add by zxx ,Nov 29, 2008

        */        private static finalchar[] data = new char[]{

                     '零','壹','貳','叄','肆','伍','陸','柒','捌','玖'

              };        private static finalchar[] units = new char[]{

              '元','拾','佰','仟','萬','拾','佰','仟','億'

       };        public static voidmain(String[] args) {               // TODOAuto-generated method stub               System.out.println(                             convert(135689123));

       }          public static Stringconvert(int money)

       {

              StringBuffersbf = new StringBuffer();               int unit = 0;               while(money!=0)

              {                      sbf.insert(0,units[unit++]);                      intnumber = money%10;                      sbf.insert(0,data[number]);                      money/= 10;

              }

                returnsbf.toString();

       }

}

. html&JavaScript&ajax 部分

1. 判斷第二個日期比第一個日期大

       如何用腳本判斷用戶輸入的的字符串是下面的時間格式2004-11-21必須要保證用戶的輸入是此格式,並且是時間,比如說月份不大於12等等,另外我需要用戶輸入兩個,並且後一個要比前一個晚,只允許用 JAVASCRIPT,請詳細幫助作答,,

//這裏可用正則表達式判斷提前判斷一下格式,然後按下提取各時間字段內容

<script type="text/javascript">    window.onload =function()

   {

        //這麼寫是爲了實現 js 代碼與 html 代碼的分離,當我修改 js 時,不能影響 html 代碼。

        document.getElementById("frm1").onsubmit=                function(){                       vard1 = this.d1.value;                       vard2 = this.d2.value;                       if(!verifyDate(d1)) {alert("第一個日期格式不對");return false;}                       if(!verifyDate(d2)) {alert("第二個日期格式不對");return false;}                       if(!compareDate(d1,d2)){alert("第二個日期比第一日期小");return false;}                 

               };

        }                 functioncompareDate(d1,d2)

        {                var arrayD1= d1.split("-");                var date1 =new Date(arrayD1[0],arrayD1[1],arrayD1[2]);                var arrayD2= d2.split("-");                var date2 =new Date(arrayD2[0],arrayD2[1],arrayD2[2]);                if(date1> date2) return false;                             return true;

        }                 functionverifyDate(d)

        {                vardatePattern = /^\d{4}-(0?[1-9]|1[0-2])-(0?[1-9]|[1-2]\d|3[0-1])$/;                returndatePattern.test(d);

        }

</script>

 

<form id="frm1" action="xxx.html">

<input type="text" name="d1" />

<input type="text" name="d2" />

<input type="submit"/>

</form>

2. table 顯示 n 條記錄,每 3 行換一次顏色,即 123 用紅色字體,456 用綠色字體,789 用紅顏色字體。

<body>

<table id="tbl">

   <tr><td>1</td></tr>

   <tr><td>2</td></tr>

   <tr><td>3</td></tr>

   <tr><td>4</td></tr>

   <tr><td>5</td></tr>

   <tr><td>6</td></tr>

   <tr><td>7</td></tr>

   <tr><td>8</td></tr>

   <tr><td>9</td></tr>

   <tr><td>10</td></tr>

</table>

</body>

<script type="text/javascript">    window.onload=function()

        {                var tbl =document.getElementById("tbl");                rows =tbl.getElementsByTagName("tr");                for(i=0;i<rows.length;i++)

               {                       var j= parseInt(i/3);                       if(j%2==0)rows[i].style.backgroundColor="#f00";                       else  rows[i].style.backgroundColor="#0f0";

               }

        }

</script>

3HTML form 提交之前如何驗證數值文本框的內容全部爲數字?否則的話提示用戶並終止提交?

<form onsubmit=’return chkForm(this)’>

<input type="text" name="d1"/>

<input type="submit"/>

</form>

<script type=”text/javascript” />    function chkForm(this)

       {               var value = thist.d1.value;               var len =value.length;               for(vari=0;i<len;i++)

              {                      if(value.charAt(i)>"9"|| value.charAt(i)<"0")

                     {                             alert("含有非數字字符");                             returnfalse;

                     }               }               return true;

       }

</script>

 

4、請寫出用於校驗 HTML 文本框中輸入的內容全部爲數字的 javascript 代碼

<input type="text" id="d1" onblur=" chkNumber(this)"/>

<script type=”text/javascript” />    function chkNumber(eleText)

 

       {

              var value =eleText.value;               var len =value.length;               for(vari=0;i<len;i++)

              {                      if(value.charAt(i)>"9"|| value.charAt(i)<"0")

                     {                             alert("含有非數字字符");                             eleText.focus();                             break;

                     }

              }

       }

</script>

除了寫完代碼,還應該在網頁上寫出實驗步驟和在代碼中加入實現思路,讓面試官一看就明白你的意圖和檢查你的結果。

 

5、說說你用過那些 ajax 技術和框架,說說它們的區別

. Java web 部分 1Tomcat 的優化經驗答:去掉對 web.xml 的監視,把 jsp 提前編輯成 Servlet。有富餘物理內存的情況,加大 tomcat 使用的 jvm 的內存

 

 

  1. HTTP 請求的 GET POST 方式的區別

答:servlet 有良好的生存期的定義,包括加載和實例化、初始化、處理請求以及服務結束。

這個生存期由 javax.servlet.Servlet 接口的 init,service 和 destroy 方法表達。

  1. 解釋一下什麼是 servlet;

答:servlet 有良好的生存期的定義,包括加載和實例化、初始化、處理請求以及服務結束。

這個生存期由 javax.servlet.Servlet 接口的 init,service 和 destroy 方法表達。

  1. 說一說 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()方法。

 

  1. 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 {

}

}

  1. SERVLET API forward()redirect()的區別?

答:前者僅是容器中控制權的轉向,在客戶端瀏覽器地址欄中不會顯示出轉向後的地址;後者則是完全的跳轉,瀏覽器將會得到跳轉的地址,並重新發送請求鏈接。這樣,從瀏覽器的地址欄中可以看到跳轉後的鏈接地址。所以,前者更加高效,在前者可以滿足需要時,儘量使用 forward()方法,並且,這樣也有助於隱藏實際的鏈接。在有些情況下,比如,需要跳轉到一個其它服務器上的資源,則必須使用

sendRedirect()方法。

 

  1. 什麼情況下調用 doGet()doPost()

Jsp 頁面中的 FORM標籤裏的method屬性爲get 時調用 doGet(),爲 post 時調用 doPost()。

 

  1. 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):刪除請求中的一個屬性

  1. forward redirect 的區別

forward 是服務器請求資源,服務器直接訪問目標地址的 URL,把那個 URL 的響應內容讀取過來,然後把這些內容再發給瀏覽器,瀏覽器根本不知道服務器發送的內容是從哪兒來的,所以它的地址欄中還是原來的地址。

   redirect 就是服務端根據邏輯,發送一個狀態碼,告訴瀏覽器重新去請求那個地址,一般來說瀏覽器會用剛纔請求的所有參數重新請求,所以 session,request 參數都可以獲取。

  1. request.getAttribute() request.getParameter()有何區別?

getParameter 得到的都是 String 類型的。或者是 http://a.jsp?id=123 中的 123,或者是某個表單提交過去的數據。 getAttribute 則可以是對象。 getParameter()是獲取 POST/GET 傳遞的參數值;

getAttribute()是獲取對象容器中的數據值;

getParameter:用於客戶端重定向時,即點擊了鏈接或提交按扭時傳值用,即用於在用表單或 url 重定向傳值時接收數據用。

getAttribute:用於服務器端重定向時,即在 sevlet 中使用了 forward 函數,或 struts 中使用了 mapping.findForward。getAttribute 只能收到程序用 setAttribute 傳過來的值。

getParameter()是獲取 POST/GET 傳遞的參數值; getAttribute()是獲取 SESSION 的值;另外,可以用 setAttribute,getAttribute 發送接收對象.而 getParameter 顯然只能傳字符串。 setAttribute 是應用服務器把這個對象放在該頁面所對應的一塊內存中去,當你的頁面服務器重定向到另一個頁面時,應用服務器會把這塊內存拷貝另一個頁面所對應的內存中。這樣 getAttribute 就能取得你所設下的值,當然這種方法可以傳對象。session 也一樣,只是對象在內存中的生命週期不一樣而已。getParameter 只是應用服務器在分析你送上來的 request 頁面的文本時,取得你設在表單或 url 重定向時的值。

getParameter 返回的是 String, 用於讀取提交的表單中的值; getAttribute 返回的是 Object,需進行轉換,可用 setAttribute 設置成任意對象,使用很靈活,可隨時用;

11. 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 實例

12. jsp 有哪些動作?作用分別是什麼?

(這個問題似乎不重要,不明白爲何有此題)答:JSP 共有以下6種基本動作 jsp:include:在頁面被請求的時候引入一個文件。 jsp:useBean:尋找或者實例化一個 JavaBean。 jsp:setProperty:設置 JavaBean 的屬性。 jsp:getProperty:輸出某個 JavaBean 的屬性。 jsp:forward:把請求轉到一個新的頁面。

jsp:plugin:根據瀏覽器類型爲 Java 插件生成 OBJECT 或 EMBED 標記

13JSP 的常用指令

isErrorPage(是否能使用 Exception 對象),isELIgnored(是否忽略表達式)

 

14. JSP 中動態 INCLUDE 與靜態 INCLUDE 的區別?

答:動態 INCLUDE 用 jsp:include 動作實現

<jsp:include page=included.jsp flush=true />它總是會檢查所含文件中的變化,適合用於包含動態頁面,並且可以帶參數 靜態 INCLUDE 用 include 僞碼實現,定不會檢查所含文件的

變化,適用於包含靜態頁面 <%@include file=included.htm %>

 

15、兩種跳轉方式分別是什麼?有什麼區別?

(下面的回答嚴重錯誤,應該是想問 forward 和 sendRedirect 的區別,畢竟出題的人不是專業搞文字藝術的人,可能表達能力並不見得很強,用詞不一定精準,加之其自身的技術面也可能存在一些問題,不一定真正將他的意思表達清楚了,嚴格意思上來講,一些題目可能根本就無人能答,所以,答題時要掌握主動,只要把自己知道的表達清楚就夠了,而不要去推敲原始題目的具體含義是什麼,不要一味想着是在答題)答:有兩種,分別爲:

<jsp:include page=included.jsp flush=true>

<jsp:forward page= nextpage.jsp/>

前者頁面不會轉向 include 所指的頁面,只是顯示該頁的結果,主頁面還是原來的頁面。執行完後還會回來,相當於函數調用。並且可以帶參數.後者完全轉向新頁面,不會再回來。

相當於 go to 語句。

 

  1. 頁面間對象傳遞的方法

request,session,application,cookie 等

  1. JSP Servlet 有哪些相同點和不同點,他們之間的聯繫是什麼?

JSP 是 Servlet 技術的擴展,本質上是 Servlet 的簡易方式,更強調應用的外表表達。JSP 編譯後是"類 servlet"。Servlet 和 JSP 最主要的不同點在於,Servlet 的應用邏輯是在 Java 文件中,並且完全從表示層中的 HTML 裏分離開來。而 JSP 的情況是 Java 和 HTML 可以組合成一個擴展名爲.jsp 的文件。JSP 側重於視圖,Servlet 主要用於控制邏輯。

 

  1. MVC 的各個部分都有那些技術來實現?如何實現?

答:MVC 是 Model-View-Controller 的簡寫。Model 代表的是應用的業務邏輯(通過

JavaBean,EJB 組件實現),View 是應用的表示面(由 JSP 頁面產生),Controller 是提供應用的處理過程控制(一般是一個 Servlet),通過這種設計模型把應用邏輯,處理過程和顯示邏輯分成不同的組件實現。這些組件可以進行交互和重用。

 

  1. 我們在 web 應用開發過程中經常遇到輸出某種編碼的字符,如 iso8859-1 等,如何輸出一個某種編碼的字符串?

 Public String translate(String str) {

   String tempStr ="";

   try {      tempStr = newString(str.getBytes("ISO-8859-1"), "GBK");      tempStr =tempStr.trim();

   }    catch (Exception e) {

    System.err.println(e.getMessage());

   }    return tempStr;

 }

20、現在輸入 n 個數字,以逗號,分開;然後可選擇升或者降序排序;按提交鍵就在另一頁面顯示按什麼排序,結果爲,提供 reset

 

 

 

.數據庫部分

  1. 用兩種方式根據部門號從高到低,工資從低到高列出每個員工的信息。

employee:

    eid,ename,salary,deptid;  select * from employeeorder by deptid desc,salary

 

 

  1. 列出各個部門中工資高於本部門的平均工資的員工數和部門號,並按部門號

排序創建表:

       mysql> createtable employee921(id int primary key auto_increment,name varchar(5

0),salary bigint,deptid int);

 

插入實驗數據:

mysql> insert into employee921values(null,'zs',1000,1),(null,'ls',1100,1),(null ,'ww',1100,1),(null,'zl',900,1) ,(null,'zl',1000,2), (null,'zl',900,2),(null,'z l',1000,2) , (null,'zl',1100,2);

 

編寫 sql 語句:

 

()select avg(salary) from employee921 group by deptid;

()mysql>

selectemployee921.id,employee921.name,employee921.salary,employee921.dep tid tid from  employee921where salary > (select avg(salary) from employee921 where 

deptid = tid);

   效率低的一個語句,僅供學習參考使用(在 group by 之後不能使用 where,只能使用 having,在 group by 之前可以使用 where,即表示對過濾後的結果分組):

mysql> selectemployee921.id,employee921.name,employee921.salary,employee921.dep tid tid from  employee921where salary > (select avg(salary) from employee921 group by deptid havingdeptid = tid); ()select count(*) ,tid        from (

              selectemployee921.id,employee921.name,employee921.salary,employee921.deptid tid               from      employee921               where salary>

                    (selectavg(salary) from employee921 where deptid = tid)

       ) as t        group by tid ;

 

另外一種方式:關聯查詢

select a.ename,a.salary,a.deptid  from emp a,

    (selectdeptd,avg(salary) avgsal from emp group by deptid ) b  where a.deptid=b.deptidand a.salary>b.avgsal;

3、存儲過程與觸發器必須講,經常被面試到?

create procedure insert_Student (_name varchar(50),_age int ,out_id int) begin        insert into studentvalue(null,_name,_age);        select max(stuId)into _id from student; end;   call insert_Student('wfz',23,@id); select @id;

 

mysql> create trigger update_Student BEFORE update on studentFOR EACH ROW

-> select * from student;

觸發器不允許返回結果

 

create trigger update_StudentBEFORE update on student FOR EACH ROW 

insert into  student value(null,'zxx',28);

mysql 的觸發器目前不能對當前表進行操作

 

create trigger update_StudentBEFORE update on student FOR EACH ROW  delete from articles  where id=8;

這個例子不是很好,最好是用刪除一個用戶時,順帶刪除該用戶的所有帖子

這裏要注意使用 OLD.id

 

觸發器用處還是很多的,比如校內網、開心網、Facebook,你發一個日誌,自動通知好友,其實就是在增加日誌時做一個後觸發,再向通知表中寫入條目。因爲觸發器效率高。而 UCH 沒有用觸發器,效率和數據處理能力都很低。

存儲過程的實驗步驟:

mysql> delimiter | mysql> create procedure insertArticle_Procedure (pTitle varchar(50),pBid int,out  pId int)

    -> begin

    -> insert into article1value(null,pTitle,pBid);

    -> select max(id) into pId fromarticle1;

    -> end;

    -> |

Query OK, 0 rows affected (0.05sec)

  mysql> callinsertArticle_Procedure('傳智播客',1,@pid);

    -> |

Query OK, 0 rows affected (0.00sec)

  mysql> delimiter ; mysql> select @pid;

+------+

| @pid |

+------+

| 3    |

+------+

1 row in set (0.00 sec)

  mysql> select * fromarticle1;

+----+--------------+------+

| id | title        | bid |

+----+--------------+------+

| 1  | test        | 1    |

| 2  | chuanzhiboke | 1    |

| 3  | 傳智播客    | 1    |

+----+--------------+------+

3 rows in set (0.00 sec)

 

觸發器的實驗步驟:

create table board1(id intprimary key auto_increment,name varchar(50),ar ticleCount int);

  create table article1(id intprimary key auto_increment,title varchar(50)

,bid int referencesboard1(id));

  delimiter |   create triggerinsertArticle_Trigger after insert on article1 for each ro w begin

    -> update board1 setarticleCount=articleCount+1 where id= NEW.bid;

    -> end;

    -> |   delimiter ;   insert into board1 value(null,'test',0);

  insert into article1value(null,'test',1);

還有,每插入一個帖子,都希望將版面表中的最後發帖時間,帖子總數字段進行同步更新,用觸發器做效率就很高。下次課設計這樣一個案例,寫觸發器時,對於最後發帖時間可能需要用 declare 方式聲明一個變量,或者是用 NEW.posttime 來生成。

 

4、數據庫三範式是什麼?

第一範式(1NF):字段具有原子性,不可再分。所有關係型數據庫系統都滿足第一範式)        數據庫表中的字段都是單一屬性的,不可再分。例如,姓名字段,其中的姓和名必須作爲一個整體,無法區分哪部分是姓,哪部分是名,如果要區分出姓和名,必須設計成兩個獨立的字段。

 

  第二範式(2NF):第二範式(2NF)是在第一範式(1NF)的基礎上建立起來的,即滿足第二範式(2NF)必須先滿足第一範式(1NF)。要求數據庫表中的每個實例或行必須可以被惟一地區分。通常需要爲表加上一個列,以存儲各個實例的惟一標識。這個惟一屬性列被稱爲主關鍵字或主鍵。

 

第二範式(2NF)要求實體的屬性完全依賴於主關鍵字。所謂完全依賴是指不能存在僅依賴主關鍵字一部分的屬性,如果存在,那麼這個屬性和主關鍵字的這一部分應該分離出來形成一個新的實體,新實體與原實體之間是一對多的關係。爲實現區分通常需要爲表加上一個列,以存儲各個實例的惟一標識。簡而言之,第二範式就是非主屬性非部分依賴於主關鍵字。

  

 第三範式的要求如下:

滿足第三範式(3NF)必須先滿足第二範式(2NF)。簡而言之,第三範式(3NF)要求一個數據庫表中不包含已在其它表中已包含的非主關鍵字信息。

所以第三範式具有如下特徵:

         1,每一列只有一個值

         2,每一行都能區分。

         3,每一個表都不包含其他表已經包含的非主關鍵字信息。

例如,帖子表中只能出現發帖人的 id,而不能出現發帖人的 id,還同時出現發帖人姓名,否則,只要出現同一發帖人 id 的所有記錄,它們中的姓名部分都必須嚴格保持一致,這就是數據冗餘。

 

5、說出一些數據庫優化方面的經驗?

用 PreparedStatement 一般來說比 Statement 性能高:一個 sql 發給服務器去執行,涉及步驟:語法檢查、語義分析,編譯,緩存

“inert into user values(1,1,1)”-à 二進制

“inert into user values(2,2,2)”-à 二進制

“inert into user values(?,?,?)”-à 二進制

 

 

 

有外鍵約束會影響插入和刪除性能,如果程序能夠保證數據的完整性,那在設計數據庫時就去掉外鍵。(比喻:就好比免檢產品,就是爲了提高效率,充分相信產品的製造商)

(對於 hibernate 來說,就應該有一個變化:empleyee->Deptment 對象,現在設計時就成了 employeeàdeptid)

 

看 mysql 幫助文檔子查詢章節的最後部分,例如,根據掃描的原理,下面的子查詢語句要比第二條關聯查詢的效率高:

  1. select e.name,e.salarywhere e.managerid=(select id from employee where name='zxx');

 

  1. select e.name,e.salary,m.name,m.salary fromemployees e,employees m where

 e.managerid = m.id andm.name='zxx';

 

表中允許適當冗餘,譬如,主題帖的回覆數量和最後回覆時間等將姓名和密碼單獨從用戶表中獨立出來。這可以是非常好的一對一的案例喲!

 

sql 語句全部大寫,特別是列名和表名都大寫。特別是 sql 命令的緩存功能,更加需要統一大小寫,sql 語句 à 發給 oracle 服務器 à 語法檢查和編譯成爲內部指令 à 緩存和執行指令。根據緩存的特點,不要拼湊條件,而是用?和 PreparedStatment

 

還有索引對查詢性能的改進也是值得關注的。

 

備註:下面是關於性能的討論舉例

 

4航班 3個城市

 

m*n

  select * from flight,city where flight.startcityid=city.cityidand city.name='beijing';

  m + n

    select * from flight where startcityid = (select cityid fromcity where cityname='beijing');   select flight.id,'beijing',flight.flightTime from flight wherestartcityid = (select cityid from city where cityname='beijing')

6union union all 有什麼不同?

假設我們有一個表 Student,包括以下字段與數據:

drop table student; create table student

(

id int primary key, name nvarchar2(50) not null, score number not null

);

insert into student values(1,'Aaron',78); insert into student values(2,'Bill',76); insert into student values(3,'Cindy',89); insert into student values(4,'Damon',90); insert into student values(5,'Ella',73); insert into student values(6,'Frado',61); insert into student values(7,'Gill',99); insert into student values(8,'Hellen',56); insert into student values(9,'Ivan',93); insert into student values(10,'Jay',90); commit;

Union 和 Union All 的區別。

select * from student where id < 4 union select * from student where id > 2 and id < 6

結果將是

  1. Aaron    78
  2. Bill    76
  3. Cindy    89
  4. Damon    90
  5. Ella    73

如果換成 Union All 連接兩個結果集,則返回結果是:

  1. Aaron    78
  2. Bill    76
  3. Cindy    89
  1. Cindy    89
  2. Damon    90
  3. Ella    73

可以看到,Union 和 Union All 的區別之一在於對重複結果的處理。

 

UNION 在進行錶鏈接後會篩選掉重複的記錄,所以在錶鏈接後會對所產生的結果集進行排序運算,刪除重複的記錄再返回結果。實際大部分應用中是不會產生重複的記錄,最常見的是過程表與歷史表 UNION。如:

select * from gc_dfys union select * from ls_jg_dfys

  這個 SQL 在運行時先取出兩個表的結果,再用排序空間進行排序刪除重複的記錄,最後返回結果集,如果表數據量大的話可能會導致用磁盤進行排序。

 而 UNION ALL 只是簡單的將兩個結果合併後就返回。這樣,如果返回的兩個結果集中有重複的數據,那麼返回的結果集就會包含重複的數據了。  從效率上說,UNION ALL 要比 UNION 快很多,所以,如果可以確認合併的兩個結果集中不包含重複的數據的話,那麼就使用 UNION ALL,

7.分頁語句取出 sql 表中第3140的記錄(以自動增長 ID 爲主鍵)

sql server 方案1:

    selecttop 10 * from t where id not in (select top 30 id from t order by id ) orde byid

sql server 方案2:

    selecttop 10 * from t where id in (select top 40 id from t order by id) order by iddesc

  mysql 方案:select * from t order by idlimit 30,10 oracle 方案:select * from (select rownum r,* from t where r<=40) wherer>30

 

--------------------待整理進去的內容------------------------------------- pageSize=20; pageNo = 5;

 

1.分頁技術1(直接利用 sql 語句進行分頁,效率最高和最推薦的)

  mysql:sql = "select * from articles limit " +(pageNo-1)*pageSize + "," + pageSize; oracle: sql = "select * from " +

                                                       "(selectrownum r,* from " +

                                                              "(select* from articles order by postime desc)" +

                                                       "whererownum<= " + pageNo*pageSize +") tmp " +

                                                 "wherer>" +

(pageNo-1)*pageSize;

註釋:第7行保證 rownum 的順序是確定的,因爲 oracle 的索引會造成 rownum 返回不同的值簡洋提示:沒有 order by 時,rownum 按順序輸出,一旦有了 order by,rownum 不按順序輸出了,這說明 rownum 是排序前的編號。如果對 order by 從句中的字段建立了索引,那麼,rownum 也是按順序輸出的,因爲這時候生成原始的查詢結果集時會參照索引表的順序來構建。

  sqlserver:sql = "select top 10 * from id not id(select top" + (pageNo-1)*pageSize + "id from

articles)"

 

DataSource ds = new InitialContext().lookup(jndiurl);

Connection cn = ds.getConnection();

//"select * from user where id=?"  --->binary directive

PreparedStatement pstmt = cn.prepareSatement(sql);

ResultSet rs = pstmt.executeQuery()

while(rs.next())

{

       out.println(rs.getString(1));

}

 

2.不可滾動的遊標

pageSize=20; pageNo = 5; cn = null stmt = null; rs = null; try

{

sqlserver:sql = "select * from articles";

 

DataSource ds = new InitialContext().lookup(jndiurl);

Connection cn = ds.getConnection();

//"select * from user where id=?"  --->binary directive

PreparedStatement pstmt = cn.prepareSatement(sql); ResultSet rs = pstmt.executeQuery() for(int j=0;j<(pageNo-1)*pageSize;j++)

{

       rs.next();

}   int i=0;   while(rs.next() && i<10)

{

       i++;        out.println(rs.getString(1)); }

}

cacth(){} finnaly

{

       if(rs!=null)try{rs.close();}catch(Exceptione){}        if(stm.........        if(cn............

}

 

3.可滾動的遊標

pageSize=20; pageNo = 5; cn = null stmt = null; rs = null; try

{

sqlserver:sql = "select * from articles";

 

DataSource ds = new InitialContext().lookup(jndiurl);

Connection cn = ds.getConnection();

//"select * from user where id=?"  --->binary directive

PreparedStatement pstmt = cn.prepareSatement(sql,ResultSet.TYPE_SCROLL_INSENSITIVE,...);

//根據上面這行代碼的異常 SQLFeatureNotSupportedException,就可判斷驅動是否支持可滾動遊標

 

ResultSet rs = pstmt.executeQuery() rs.absolute((pageNo-1)*pageSize)

int i=0;

while(rs.next() && i<10)

{

       i++;        out.println(rs.getString(1));

}

}

cacth(){} finnaly

{

       if(rs!=null)try{rs.close();}catch(Exceptione){}        if(stm.........        if(cn............

}

8.用一條 SQL 語句查詢出每門課都大於 80 分的學生姓名 

name   kecheng   fenshu  張三    語文      81 張三    數學      75 李四    語文      76 李四    數學      90 王五    語文      81 王五    數學      100 王五    英語      90

準備數據的 sql 代碼:

create table score(id int primary key auto_increment,namevarchar(20),subject varchar(20),score int); insert into score values (null,'張三','語文',81),

(null,'張三','數學',75),

(null,'李四','語文',76),

(null,'李四','數學',90),

(null,'王五','語文',81),

(null,'王五','數學',100),

(null,'王五 ','英語',90);

 

提示:當百思不得其解時,請理想思維,把小變成大做,把大變成小做,

 

答案:

A: select distinct name from score  where  name not in (selectdistinct name from score where score<=80)

 

B:select distince name t1 from score where 80< all (selectscore from score where name=t1);

9.所有部門之間的比賽組合

一個叫 department 的表,裏面只有一個字段 name,一共有4條紀錄,分別是 a,b,c,d,對應四個球對,現在四個球對進行比賽,用一條 sql 語句顯示所有可能的比賽組合.

 

 

答:select a.name,b.name  from team a, team b  where a.name < b.name

 

10.每個月份的發生額都比 101 科目多的科目

請用 SQL 語句實現:從 TestDB 數據表中查詢出所有月份的發生額都比101科目相應月份的發生額高的科目。請注意:TestDB 中有很多科目,都有1-12月份的發生額。

AccID:科目代碼,Occmonth:發生額月份,DebitOccur:發生額。數據庫名:JcyAudit,數據集:Select * from TestDB

準備數據的 sql 代碼:

drop table if exists TestDB; create table TestDB(id int primary key auto_increment,AccIDvarchar(20), Occmonth date, DebitOccur bigint); insert into TestDB values

(null,'101','1988-1-1',100),

(null,'101','1988-2-1',110),

(null,'101','1988-3-1',120),

(null,'101','1988-4-1',100),

(null,'101','1988-5-1',100),

(null,'101','1988-6-1',100),

(null,'101','1988-7-1',100),

(null,'101','1988-8-1',100);

--複製上面的數據,故意把第一個月份的發生額數字改小一點

insert into TestDB values

(null,'102','1988-1-1',90),

(null,'102','1988-2-1',110),

(null,'102','1988-3-1',120),

(null,'102','1988-4-1',100),

(null,'102','1988-5-1',100),

(null,'102','1988-6-1',100),

(null,'102','1988-7-1',100),

(null,'102','1988-8-1',100);

--複製最上面的數據,故意把所有發生額數字改大一點

insert into TestDB values

(null,'103','1988-1-1',150),

(null,'103','1988-2-1',160),

(null,'103','1988-3-1',180),

(null,'103','1988-4-1',120),

(null,'103','1988-5-1',120),

(null,'103','1988-6-1',120),

(null,'103','1988-7-1',120),

(null,'103','1988-8-1',120);

--複製最上面的數據,故意把所有發生額數字改大一點

insert into TestDB values

(null,'104','1988-1-1',130),

(null,'104','1988-2-1',130),

(null,'104','1988-3-1',140),

(null,'104','1988-4-1',150),

(null,'104','1988-5-1',160),

(null,'104','1988-6-1',170),

(null,'104','1988-7-1',180),

(null,'104','1988-8-1',140);

--複製最上面的數據,故意把第二個月份的發生額數字改小一點

insert into TestDB values

(null,'105','1988-1-1',100),

(null,'105','1988-2-1',80),

(null,'105','1988-3-1',120),

(null,'105','1988-4-1',100),

(null,'105','1988-5-1',100),

(null,'105','1988-6-1',100),

(null,'105','1988-7-1',100),

(null,'105','1988-8-1',100);

答案:

select distinct AccID from TestDB where AccID not in

       (selectTestDB.AccIDfrom TestDB,

               (select * from TestDB where AccID='101') asdb101        whereTestDB.Occmonth=db101.Occmonth and

TestDB.DebitOccur<=db101.DebitOccur

       );

 

11.統計每年每月的信息

year  monthamount 1991   1     1.1

1991   2     1.2

1991   3     1.3

  1. 4     1.4
  2. 1     2.1

1992   2     2.2

1992   3     2.3

1992   4     2.4 查成這樣一個結果

year m1  m2  m3  m4

  1. 1.1 1.2 1.3 1.4
  2. 2.1 2.2 2.3 2.4 

 

 

提示:這個與工資條非常類似,與學生的科目成績也很相似。

 

準備 sql 語句:

drop table if existssales; create table sales(idint auto_increment primary key,year varchar(10), month varchar(10), amountfloat(2,1)); insert into salesvalues

(null,'1991','1',1.1),

(null,'1991','2',1.2),

(null,'1991','3',1.3),

(null,'1991','4',1.4),

(null,'1992','1',2.1),

(null,'1992','2',2.2),

(null,'1992','3',2.3), (null,'1992','4',2.4);

 

答案一、

select sales.year ,

(select t.amount fromsales t where t.month='1' and t.year= sales.year) '1',

(select t.amount fromsales t where t.month='1' and t.year= sales.year) '2',

(select t.amount fromsales t where t.month='1' and t.year= sales.year) '3', (select t.amount fromsales t where t.month='1' and t.year= sales.year) as '4' from sales  group by year;

 

12.顯示文章標題,發帖人、最後回覆時間

表:id,title,postuser,postdate,parentid

準備 sql 語句:

drop table if exists articles; create table articles(id int auto_increment primary key,titlevarchar(50), postuser varchar(10), postdate datetime,parentid int referencesarticles(id)); insert into articles values

(null,'第一條','張三','1998-10-10 12:32:32',null),

(null,'第二條','張三','1998-10-10 12:34:32',null),

(null,'第一條回覆1','李四','1998-10-10 12:35:32',1),

(null,'第二條回覆1','李四','1998-10-10 12:36:32',2),

(null,'第一條回覆2','王五','1998-10-10 12:37:32',1),

(null,'第一條回覆3','李四','1998-10-10 12:38:32',1),

(null,'第二條回覆2','李四','1998-10-10 12:39:32',2), (null,'第一條回覆4','王五','1998-10-10 12:39:40',1);

 

答案:

select a.title,a.postuser,

       (selectmax(postdate) from articles where parentid=a.id) reply from articles a where a.parentid is null;

 

註釋:子查詢可以用在選擇列中,也可用於 where 的比較條件中,還可以用於 from 從句中。

13.刪除除了 id 號不同,其他都相同的學生冗餘信息

2.學生表如下:

id 號   學號   姓名課程編號課程名稱分數

  1. 2005001  張三 0001     數學    69
  2. 2005002  李四 0001     數學    89
  3. 2005001  張三 0001     數學    69

A: delete from tablename where id 號 not in(select min(id 號) from tablename group by 學

號,姓名,課程編號,課程名稱,分數)

實驗:

create table student2(id int auto_increment primary key,codevarchar(20),name varchar(20)); insert into student2 values(null,'2005001','張三'),(null,'2005002','李四'),(null,'2005001','張三');

 

//如下語句,mysql 報告錯誤,可能刪除依賴後面統計語句,而刪除又導致統計語句結果不一致。

  delete from student2 where id not in(select min(id) fromstudent2 group by name);

//但是,如下語句沒有問題:

select *  from student2where id not in(select min(id) from student2 group by name);

//於是,我想先把分組的結果做成虛表,然後從虛表中選出結果,最後再將結果作爲刪除的條件數據。

delete from student2 where id not in(select mid from (selectmin(id) mid from student2 group by name) as t);

或者:

delete from student2 where id not in(select min(id) from (select* from s tudent2) as t group by t.name);

14.航空網的幾個航班查詢題:表結構如下:

flight{flightID,StartCityID ,endCityID,StartTime} city{cityID, CityName)

實驗環境:

create table city(cityID int auto_increment primary key,cityNamevarchar(20)); create table flight (flightID int auto_increment primary key,        StartCityID intreferences city(cityID),        endCityID  int references city(cityID),

       StartTimetimestamp);

//航班本來應該沒有日期部分纔好,但是下面的題目當中涉及到了日期

insert into city values(null,'北京'),(null,'上海'),(null,'廣州');

insert into flight values

       (null,1,2,'9:37:23'),(null,1,3,'9:37:23'),(null,1,2,'10:37:23'),(null,2,3,'10:37:23');

 

 

1、查詢起飛城市是北京的所有航班,按到達城市的名字排序

 

 

參與運算的列是我起碼能夠顯示出來的那些列,但最終我不一定把它們顯示出來。各個表組合出來的中間結果字段中必須包含所有運算的字段。

    select  * from flight f,city c        where f.endcityid =c.cityid and startcityid =

       (select c1.cityidfrom city c1 where c1.cityname = "北京")        order by c.citynameasc;

  mysql> select flight.flightid,'北京' startcity, e.cityname from flight,city e wh ere flight.endcityid=e.cityid and flight.startcityid=(selectcityid from city wh ere cityname='北京');

  mysql> select flight.flightid,s.cityname,e.cityname fromflight,city s,city e wh ere flight.startcityid=s.cityid and s.cityname='北京' andflight.endCityId=e.cit yID order by e.cityName desc;

 

 

2、查詢北京到上海的所有航班紀錄(起飛城市,到達城市,起飛時間,航班號)

select c1.CityName,c2.CityName,f.StartTime,f.flightID from city c1,city c2,flight f where f.StartCityID=c1.cityID and f.endCityID=c2.cityID and c1.cityName='北京' and c2.cityName='上海' 3、查詢具體某一天(2005-5-8)的北京到上海的的航班次數

select count(*) from

(select c1.CityName,c2.CityName,f.StartTime,f.flightID from city c1,city c2,flight f where f.StartCityID=c1.cityID and f.endCityID=c2.cityID and c1.cityName='北京' and c2.cityName='上海' and 查幫助獲得的某個日期處理函數(startTime) like '2005-5-8%'

 

mysql 中提取日期部分進行比較的示例代碼如下:

select * from flight wheredate_format(starttime,'%Y-%m-%d')='1998-01-02'

15.查出比經理薪水還高的員工信息:

Drop table if not exists employees; create table employees(id int primary key auto_increment,namevarchar(50)

,salary int,managerid intreferences employees(id)); insert into employees values (null,' lhm',10000,null), (null,'zxx',15000,1 ),(null,'flx',9000,1),(null,'tg',10000,2),(null,'wzg',10000,3);

 

Wzg 大於 flx,lhm 大於 zxx

 

解題思路:      根據 sql 語句的查詢特點,是逐行進行運算,不可能兩行同時參與運算。

涉及了員工薪水和經理薪水,所有,一行記錄要同時包含兩個薪水,所有想到要把這個表自關聯組合一下。

     首先要組合出一個包含有各個員工及該員工的經理信息的長記錄,譬如,左半部分是員工,右半部分是經理。而迪卡爾積會組合出很多垃圾信息,先去除這些垃圾信息。

  select e.* from employees e,employees m where e.managerid=m.idand e.sala ry>m.salary;

16、求出小於 45 歲的各個老師所帶的大於 12 歲的學生人數

數據庫中有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 primarykey,name varchar(50),age int);       create table student(stuID int primarykey,name varchar(50),age int);       create table tea_stu(teaID int referencesteacher(teaID),stuID int references student(stuID)); insertinto teacher values(1,'zxx',45), (2,'lhm',25) , (3,'wzg',26) , (4,'tg',27); insertinto student values(1,'wy',11), (2,'dh',25) , (3,'ysq',26) , (4,'mxc',27); insertinto tea_stu values(1,1), (1,2), (1,3); insertinto tea_stu values(2,2), (2,3), (2,4);  insert into tea_stu values(3,3), (3,4), (3,1); insertinto tea_stu values(4,4), (4,1), (4,2) , (4,3);

 

結果:2à3,3à2,4à3

 

解題思路:(真實面試答題時,也要寫出每個分析步驟,如果紙張不夠,就找別人要)

1要會統計分組信息,統計信息放在中間表中:

selectteaid,count(*) from tea_stu group by teaid;

 

2接着其實應該是篩除掉小於12歲的學生,然後再進行統計,中間表必須與 student 關聯才能得到12歲以下學生和把該學生記錄從中間表中剔除,代碼是:

selecttea_stu.teaid,count(*) total from student,tea_stu

wherestudent.stuid=tea_stu.stuid and student.age>12 group by tea_stu.teaid

 

3.接着把上面的結果做成虛表與 teacher 進行關聯,並篩除大於45的老師 selectteacher.teaid,teacher.name,total from teacher ,(select tea_stu.tea id,count(*)total from student,tea_stu where student.stuid=tea_stu.stuid and stu dent.age>12group by tea_stu.teaid) as tea_stu2where teacher.teaid=tea_stu2.tea idand teacher.age<45;

  

 

17.求出發帖最多的人:

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)也不行。

 

18、一個用戶表中有一個積分字段,假如數據庫中有 100 多萬個用戶,若要在每年第一天凌晨將積分清零,你將考慮什麼,你將想什麼辦法解決?

alter table drop column score;

alter table add colunm score int;

可能會很快,但是需要試驗,試驗不能拿真實的環境來操刀,並且要注意,

這樣的操作時無法回滾的,在我的印象中,只有 inert update delete 等 DML 語句才能回滾,

對於 create table,drop table ,alter table 等 DDL 語句是不能回滾。

 

 

解決方案一,update user set score=0;

解決方案二,假設上面的代碼要執行好長時間,超出我們的容忍範圍,那我就 alter table user

drop columnscore;alter table user add column score int。

 

下面代碼實現每年的那個凌晨時刻進行清零。

Runnable runnable =        new Runnable(){               public voidrun(){                      clearDb();                      schedule(this,newDate(new Date().getYear()+1,0,0));

                     }           

                     };

  schedule(runnable,        new Date(newDate().getYear()+1,0,1));

 

19、一個用戶具有多個角色,請查詢出該表中具有該用戶的所有角色的其他用

戶。

select count(*) as num,tb.id from  tb,

 (select role from tbwhere id=xxx) as t1 where

 tb.role = t1.role andtb.id != t1.id

group by tb.id having        num = select count(role)from tb where id=xxx;

20. xxx 公司的 sql 面試

Table EMPLOYEES Structure:

EMPLOYEE_ID      NUMBER        Primary Key,

FIRST_NAME       VARCHAR2(25),

LAST_NAME       VARCHAR2(25),

Salary number(8,2),

HiredDate DATE, Departmentid number(2)

TableDepartments Structure:

Departmentid number(2)        Primary Key,

DepartmentName  VARCHAR2(25).

  

 (2)基於上述 EMPLOYEES 表寫出查詢:寫出僱用日期在今年的,或者工資在[1000,2000] 之間的,或者員工姓名(last_name)以’Obama’打頭的所有員工,列出這些員工的全部個人信息。(4分)

select* from employees whereYear(hiredDate) = Year(date())        or (salary between 1000 and 200)        or left(last_name,3)='abc';

 

  1. 基於上述 EMPLOYEES 表寫出查詢:查出部門平均工資大於1800元的部門的所有員工,列出這些員工的全部個人信息。(4分)

mysql>select id,name,salary,deptid did from employee1 where (select avg(salary)  from employee1 where deptid = did) > 1800;

 

  1. 基於上述 EMPLOYEES 表寫出查詢:查出個人工資高於其所在部門平均工資的員工,列出這些員工的全部個人信息及該員工工資高出部門平均工資百分比。(5分)

selectemployee1.*,(employee1.salary-t.avgSalary)*100/employee1.salary

fromemployee1,

       (select deptid,avg(salary) avgSalary fromemployee1 group by deptid) as t whereemployee1.deptid = t.deptid and employee1.salary>t.avgSalary;

 

  1. 註冊 Jdbc 驅動程序的三種方式

 

  1. JDBC 如何調用存儲過程代碼如下:

package com.huawei.interview.lym;

  import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Types;

  publicclass JdbcTest {

 

    /**

     * @paramargs

     */     public static voidmain(String[] args) {

       // TODO Auto-generated method stub

       Connection cn = null;

       CallableStatement cstmt =null;           try {

           //這裏最好不要這麼幹,因爲驅動名寫死在程序中了

           Class.forName("com.mysql.jdbc.Driver");

           //實際項目中,這裏應用 DataSource 數據,如果用框架,

           //這個數據源不需要我們編碼創建,我們只需 Datasource ds =context.lookup()            //cn = ds.getConnection();                    cn = DriverManager.getConnection("jdbc:mysql:///test","root","root");            cstmt = cn.prepareCall("{callinsert_Student(?,?,?)}");            cstmt.registerOutParameter(3,Types.INTEGER);            cstmt.setString(1,"wangwu");            cstmt.setInt(2, 25);            cstmt.execute();

           //get 第幾個,不同的數據庫不一樣,建議不寫

           System.out.println(cstmt.getString(3));

       } catch (Exception e) {

           // TODO Auto-generated catchblock

           e.printStackTrace();        }        finally

       {

 

           /*try{cstmt.close();}catch(Exceptione){}            try{cn.close();}catch(Exceptione){}*/            try {               if(cstmt !=null)                   cstmt.close();               if(cn !=null)                                cn.close();

           } catch (SQLException e) {               // TODO Auto-generatedcatch block

              e.printStackTrace();

           }

       }

    }

23JDBC 中的 PreparedStatement 相比 Statement 的好處

答:一個 sql 命令發給服務器去執行的步驟爲:語法檢查,語義分析,編譯成內部指令,緩存指令,執行指令等過程。

select * from student where id =3----緩存--àxxxxx 二進制命令 select * from student where id =3----直接取-àxxxxx 二進制命令 select * from student where id =4--- -à 會怎麼幹?

如果當初是 select * from student where id =?--- -à 又會怎麼幹?  上面說的是性能提高可以防止 sql 注入。

24. 寫一個用 jdbc 連接並訪問 oracle 數據的程序代碼

  1. Class.forName 的作用?爲什麼要用?

答:按參數中指定的字符串形式的類名去搜索並加載相應的類,如果該類字節碼已經被加載過,則返回代表該字節碼的 Class 實例對象,否則,按類加載器的委託機制去搜索和加載該類,如果所有的類加載器都無法加載到該類,則拋出 ClassNotFoundException。加載完這個 Class 字節碼後,接着就可以使用 Class 字節碼的 newInstance 方法去創建該類的實例對象了。

有時候,我們程序中所有使用的具體類名在設計時(即開發時)無法確定,只有程序運行時才能確定,這時候就需要使用 Class.forName 去動態加載該類,這個類名通常是在配置文件中配置的,例如,spring 的 ioc 中每次依賴注入的具體類就是這樣配置的,jdbc 的驅動類名通常也是通過配置文件來配置的,以便在產品交付使用後不用修改源程序就可以更換驅動類名。

  1. 大數據量下的分頁解決方法。

答:最好的辦法是利用 sql 語句進行分頁,這樣每次查詢出的結果集中就只包含某頁的數據內容。再 sql 語句無法實現分頁的情況下,可以考慮對大的結果集通過遊標定位方式來獲取某頁的數據。

sql 語句分頁,不同的數據庫下的分頁方案各不一樣,下面是主流的三種數據庫的分頁 sql:

sql server:

       String sql =

       "select top" + pageSize + " * from students where id not in" +

 

 "(select top "+ pageSize * (pageNumber-1) + " id from students order by id)" +

 

 "order by id";

  mysql:

 

       String sql =

       "select * fromstudents order by id limit " + pageSize*(pageNumber-1) + ","

+pageSize;        oracle:

 

       String sql =

        "select * from " + 

        (select *,rownum rid from (select * fromstudents order by postime desc) where rid<=" + pagesize*pagenumber +") as t" +

        "where t>" +pageSize*(pageNumber-1);

27、用 JDBC 查詢學生成績單,把主要代碼寫出來(考試概率極大).

Connection cn = null;

PreparedStatement pstmt =null; Resultset rs = null; try

{

       Class.forname(driveClassName);        cn =  DriverManager.getConnection(url,username,password);        pstmt =cn.prepareStatement(“select  score.* fromscore ,student “ +               “wherescore.stuId = student.id and student.name = ?”);        pstmt.setString(1,studentName);        Resultset rs =pstmt.executeQuery();        while(rs.next())

       {               system.out.println(rs.getInt(“subject”)  +  “    ” + rs.getFloat(“score”) );

       }

}catch(Exception e){e.printStackTrace();}

finally

{

       if(rs != null) try{rs.close() }catch(exception e){}        if(pstmt != null)try{pstmt.close()}catch(exception e){}        if(cn != null) try{cn.close() }catch(exception e){}

}

 

 

  1. 這段代碼有什麼不足之處?

try {

Connection conn = ...;

Statement stmt = ...;

ResultSet rs =stmt.executeQuery("select * from table1"); while(rs.next()) {

}

} catch(Exception ex) {

}

答:沒有 finally 語句來關閉各個對象,另外,使用 finally 之後,要把變量的定義放在 try 語句塊的外面,以便在 try 語句塊之外的 finally 塊中仍可以訪問這些變量。

 

  1. 說出數據連接池的工作機制是什麼?

J2EE 服務器啓動時會建立一定數量的池連接,並一直維持不少於此數目的池連接。客戶端程序需要連接時,池驅動程序會返回一個未使用的池連接並將其表記爲忙。如果當前沒有空閒連接,池驅動程序就新建一定數量的連接,新建連接的數量有配置參數決定。當使用的池連接調用完成後,池驅動程序將此連接表記爲空閒,其他調用就可以使用這個連接。

實現方式,返回的 Connection 是原始 Connection 的代理,代理 Connection 的 close 方法不是真正關連接,而是把它代理的 Connection 對象還回到連接池中。

 

  1. 爲什麼要用 ORM? JDBC 有何不一樣?

orm 是一種思想,就是把 object 轉變成數據庫中的記錄,或者把數據庫中的記錄轉變成

objecdt,我們可以用 jdbc 來實現這種思想,其實,如果我們的項目是嚴格按照 oop 方式編寫的話,我們的 jdbc 程序不管是有意還是無意,就已經在實現 orm 的工作了。

現在有許多 orm 工具,它們底層調用 jdbc 來實現了 orm 工作,我們直接使用這些工具,就省去了直接使用 jdbc 的繁瑣細節,提高了開發效率,現在用的較多的 orm 工具是 hibernate。

也聽說一些其他 orm 工具,如 toplink,ojb 等。

. XML 部分

  1. xml 有哪些解析技術?區別是什麼?

答:有 DOM,SAX,STAX 等

DOM:處理大型文件時其性能下降的非常厲害。這個問題是由 DOM 的樹結構所造成的,這種結構佔用的內存較多,而且 DOM 必須在解析文件之前把整個文檔裝入內存,適合對 XML 的隨機訪問 SAX:不現於 DOM,SAX 是事件驅動型的 XML 解析方式。它順序讀取 XML 文件,不需要一次全部裝載整個文件。當遇到像文件開頭,文檔結束,或者標籤開頭與標籤結束時,它會觸發一個事件,用戶通過在其回調事件中寫入處理代碼來處理 XML 文件,適合對 XML 的順序訪問

STAX:Streaming API for XML (StAX)

講解這些區別是不需要特別去比較,就像說傳智播客與其他培訓機構的區別時,我們只需說清楚傳智播客有什麼特點和優點就行了,這就已經間接回答了彼此的區別。

 

  1. 你在項目中用到了 xml 技術的哪些方面?如何實現的?

答:用到了數據存貯,信息配置兩方面。在做數據交換平臺時,將不能數據源的數據組裝成 XML 文件,然後將 XML 文件壓縮打包加密後通過網絡傳送給接收者,接收解密與解壓縮後再同 XML 文件中還原相關信息進行處理。在做軟件配置時,利用 XML 可以很方便的進行,軟件的各種配置參數都存貯在 XML 文件中。

  1. 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(newjavax.xml.transform.dom.DOMSource(doc), new javax.xml.transform.stream.StreamResult(outFile));

catch (Exception e) 

System.out.println (e.getMessage()); 

}

4、編程用 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(newString(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>

5XML 文檔定義有幾種形式?它們之間有何本質區別?解析 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 forXML (StAX)

 

.流行的框架與新技術

 

1、談談你對 Struts 的理解。

答:

1. struts 是一個按 MVC 模式設計的 Web 層框架,其實它就是一個大大的 servlet,這個

Servlet 名爲 ActionServlet,或是 ActionServlet 的子類。我們可以在 web.xml 文件中將符合某種特徵的所有請求交給這個 Servlet 處理,這個 Servlet 再參照一個配置文件(通常爲

/WEB-INF/struts-config.xml)將各個請求分別分配給不同的 action 去處理。

一個擴展知識點:struts 的配置文件可以有多個,可以按模塊配置各自的配置文件,這樣可以防止配置文件的過度膨脹;

2.ActionServlet把請求交給action去處理之前,會將請求參數封裝成一個formbean對象(就是一個 java 類,這個類中的每個屬性對應一個請求參數),封裝成一個什麼樣的 formbean 對象呢?看配置文件。

3.要說明的是, ActionServlet 把 formbean 對象傳遞給 action 的 execute 方法之前,可能會調用 formbean 的 validate 方法進行校驗,只有校驗通過後纔將這個 formbean 對象傳遞給 action 的 execute 方法,否則,它將返回一個錯誤頁面,這個錯誤頁面由 input 屬性指定,

(看配置文件)作者爲什麼將這裏命名爲 input 屬性,而不是 error 屬性,我們後面結合實際的運行效果進行分析。

4.action 執行完後要返回顯示的結果視圖,這個結果視圖是用一個 ActionForward 對象來表示的,actionforward 對象通過 struts-config.xml 配置文件中的配置關聯到某個 jsp 頁面,因爲程序中使用的是在 struts-config.xml 配置文件爲 jsp 頁面設置的邏輯名,這樣可以實現 action 程序代碼與返回的 jsp 頁面名稱的解耦。

 

你對 struts 可能還有自己的應用方面的經驗,那也要一併說出來。

2、談談你對 Hibernate 的理解。

答:

1. 面向對象設計的軟件內部運行過程可以理解成就是在不斷創建各種新對象、建立對象之間的關係,調用對象的方法來改變各個對象的狀態和對象消亡的過程,不管程序運行的過程和操作怎麼樣,本質上都是要得到一個結果,程序上一個時刻和下一個時刻的運行結果的差異就表現在內存中的對象狀態發生了變化。

2.爲了在關機和內存空間不夠的狀況下,保持程序的運行狀態,需要將內存中的對象狀態保存到持久化設備和從持久化設備中恢復出對象的狀態,通常都是保存到關係數據庫來保存大量對象信息。從 Java 程序的運行功能上來講,保存對象狀態的功能相比系統運行的其他功能來說,應該是一個很不起眼的附屬功能,java 採用 jdbc 來實現這個功能,這個不起眼的功能卻要編寫大量的代碼,而做的事情僅僅是保存對象和恢復對象,並且那些大量的 jdbc 代碼並沒有什麼技術含量,基本上是採用一套例行公事的標準代碼模板來編寫,是一種苦活和重複性的工作。

3.通過數據庫保存 java 程序運行時產生的對象和恢復對象,其實就是實現了 java 對象與關係數據庫記錄的映射關係,稱爲 ORM(即 Object RelationMapping),人們可以通過封裝 JDBC 代碼來實現了這種功能,封裝出來的產品稱之爲 ORM 框架,Hibernate 就是其中的一種流行 ORM 框架。使用 Hibernate 框架,不用寫 JDBC 代碼,僅僅是調用一個 save 方法,就可以將對象保存到關係數據庫中,僅僅是調用一個 get 方法,就可以從數據庫中加載出一個對象。

4.使用 Hibernate 的基本流程是:配置 Configuration 對象、產生 SessionFactory、創建

session 對象,啓動事務,完成 CRUD 操作,提交事務,關閉 session。

5.使用 Hibernate 時,先要配置 hibernate.cfg.xml 文件,其中配置數據庫連接信息和方言等,還要爲每個實體配置相應的 hbm.xml 文件,hibernate.cfg.xml 文件中需要登記每個 hbm.xml 文件。

6.在應用 Hibernate 時,重點要了解 Session 的緩存原理,級聯,延遲加載和 hql 查詢。

  1. AOP 的作用。
  2. 你對 Spring 的理解。

1.Spring 實現了工廠模式的工廠類(在這裏有必要解釋清楚什麼是工廠模式),這個類名爲

BeanFactory(實際上是一個接口),在程序中通常 BeanFactory 的子類 ApplicationContext。

Spring 相當於一個大的工廠類,在其配置文件中通過<bean>元素配置用於創建實例對象的類名和實例對象的屬性。

2. Spring 提供了對 IOC 良好支持,IOC 是一種編程思想,是一種架構藝術,利用這種思想可以很好地實現模塊之間的解耦。IOC 也稱爲 DI(Depency Injection),什麼叫依賴注入呢?

譬如,Class Programmer

{

       Computer computer =null;        public void code()

       {

              //Computercomputer = new IBMComputer();               //Computercomputer = beanfacotry.getComputer();               computer.write();

       }        public voidsetComputer(Computer computer)        {               this.computer= computer;

       }

}

另外兩種方式都由依賴,第一個直接依賴於目標類,第二個把依賴轉移到工廠上,第三個徹底與目標和工廠解耦了。在 spring 的配置文件中配置片段如下:

<bean id=”computer” class=”cn.itcast.interview.Computer”>

</bean>  

<bean id=”programmer” class=”cn.itcast.interview.Programmer”>

       <property name=”computer”  ref=”computer”></property>

</bean>

3. Spring 提供了對 AOP 技術的良好封裝, AOP 稱爲面向切面編程,就是系統中有很多各不相干的類的方法,在這些衆多方法中要加入某種系統功能的代碼,例如,加入日誌,加入權限判斷,加入異常處理,這種應用稱爲 AOP。實現 AOP 功能採用的是代理技術,客戶端程序不再調用目標,而調用代理類,代理類與目標類對外具有相同的方法聲明,有兩種方式可以實現相同的方法聲明,一是實現相同的接口,二是作爲目標的子類在,JDK 中採用 Proxy 類產生動態代理的方式爲某個接口生成實現類,如果要爲某個類生成子類,則可以用 CGLI B。在生成的代理類的方法中加入系統功能和調用目標類的相應方法,系統功能的代理以 Advice 對象進行提供,顯然要創建出代理對象,至少需要目標類和 Advice 類。spring 提供了這種支持,只需要在 spring 配置文件中配置這兩個元素即可實現代理和 aop 功能,例如,

<bean id=”proxy” type=”org.spring.framework.aop.ProxyBeanFactory”>

       <property name=”target”ref=””></property>

       <property name=”advisor”ref=””></property>

 

</bean>

 

  1. 談談 Struts 中的 Action servlet
  2. Struts 優缺點優點:

 1. 實現 MVC 模式,結構清晰,使開發者只關注業務邏輯的實現.

2.有豐富的 tag 可以用 ,Struts 的標記庫(Taglib),如能靈活動用,則能大大提高開發效率

  1. 頁面導航

       使系統的脈絡更加清晰。通過一個配置文件,即可把握整個系統各部分之間的聯繫,這對於後期的維護有着莫大的好處。尤其是當另一批開發者接手這個項目時,這種優勢體現得更加明顯。

  1. 提供 Exception 處理機制 .
  2. 數據庫鏈接池管理
  3. 支持 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 相比是一種粗粒度的事件

 

 

  1. 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 屬性、國際化的提示和消息。

 

  1. 說說 struts1 struts2 的區別。

1.都是 MVC 的 WEB 框架,

2 struts1的老牌框架,應用很廣泛,有很好的羣衆基礎,使用它開發風險很小,成本更低! struts2雖然基於這個框架,但是應用羣衆並多,相對不成熟,未知的風險和變化很多,開發人員相對不好招,使用它開發項目的風險係數更大,用人成本更高!

3.struts2畢竟是站在前輩的基礎設計出來,它會改善和完善 struts1中的一些缺陷,struts1 中一些懸而未決問題在 struts2得到了解決。

4.struts1的前端控制器是一個 Servlet,名稱爲 ActionServlet,struts2的前端控制器是一個

filter,在 struts2.0中叫 FilterDispatcher,在 struts2.1中叫 StrutsPrepareAndExecuteFilter。

5.struts1的 action 需要繼承 Action 類,struts2的 action 可以不繼承任何類;struts1對同一個路徑的所有請求共享一個 Action 實例,struts2對同一個路徑的每個請求分別使用一個獨立 Action 實例對象,所有對於 struts2的 Action 不用考慮線程安全問題。

6.在 struts1中使用 formbean 封裝請求參數,在 struts2中直接使用 action 的屬性來封裝請求參數。

7.struts1中的多個業務方法放在一個 Action 中時(即繼承 DispatchAction 時),要麼都校驗,

要麼都不校驗;對於 struts2,可以指定只對某個方法進行校驗,當一個 Action 繼承了

ActionSupport 且在這個類中只編寫了 validateXxx()方法,那麼則只對 Xxx()方法進行校驗。  

(一個請求來了的執行流程進行分析,struts2是自動支持分模塊開發,並可以不同模塊設置不同的 url 前綴,這是通過 package 的 namespace 來實現的;struts2是支持多種類型的視圖;struts2的視圖地址可以是動態的,即視圖的名稱是支持變量方式的,舉例,論壇發帖失敗後回來還要傳遞 boardid。視圖內容顯示方面:它的標籤用 ognl,要 el 強大很多,在國際化方面支持分模塊管理,兩個模塊用到同樣的 key,對應不同的消息;)         

與 Struts1不同,Struts2對用戶的每一次請求都會創建一個 Action,所以 Struts2中的 Action 是線程安全的。  

給我印象最深刻的是:struts 配置文件中的 redirect 視圖的 url 不能接受參數,而 struts2配置文件中的 redirect 視圖可以接受參數。

  1. hibernate 中的 update()saveOrUpdate()的區別,session load()get()的區別。
  2. 簡述 Hibernate JDBC 的優缺點?如何書寫一個 one to many 配置文

.

  1. iBatis Hibernate 有什麼不同?

相同點:屏蔽 jdbc api 的底層訪問細節,使用我們不用與 jdbc api 打交道,就可以訪問數據。

jdbc api 編程流程固定,還將 sql 語句與 java 代碼混雜在了一起,經常需要拼湊 sql 語句,細節很繁瑣。

ibatis 的好處:屏蔽 jdbc api 的底層訪問細節;將 sql 語句與 java 代碼進行分離;提供了將結果集自動封裝稱爲實體對象和對象的集合的功能,queryForList 返回對象集合,用

queryForObject 返回單個對象;提供了自動將實體對象的屬性傳遞給 sql 語句的參數。

 

Hibernate 是一個全自動的 orm 映射工具,它可以自動生成 sql 語句,ibatis 需要我們自己在 xml 配置文件中寫 sql 語句,hibernate 要比 ibatis 功能負責和強大很多。因爲 hibernate 自動生成 sql 語句,我們無法控制該語句,我們就無法去寫特定的高效率的 sql。對於一些不太複雜的 sql 查詢,hibernate 可以很好幫我們完成,但是,對於特別複雜的查詢,hibernate 就很難適應了,這時候用 ibatis 就是不錯的選擇,因爲 ibatis 還是由我們自己寫 sql 語句。

 

 

  1. Hibernate 的一對多和多對一雙向關聯的 orm 配置?

12.1hibernate inverse 屬性的作用?

解決方案一,按照 Object[]數據取出數據,然後自己組 bean

解決方案二,對每個表的 bean 寫構造函數,比如表一要查出 field1,field2兩個字段,那麼有一個構造函數就是 Bean(type1filed1,type2

field2) ,然後在 hql 裏面就可以直接生成這個 bean 了。

 

  1. DAO 中如何體現 DAO 設計模式?

解決方案一,按照 Object[]數據取出數據,然後自己組 bean

解決方案二,對每個表的 bean 寫構造函數,比如表一要查出 field1,field2兩個字段,那麼有一個構造函數就是 Bean(type1filed1,type2

field2) ,然後在 hql 裏面就可以直接生成這個 bean 了。

 

  1. spring+Hibernate 中委託方案怎麼配置?

解決方案一,按照 Object[]數據取出數據,然後自己組 bean

解決方案二,對每個表的 bean 寫構造函數,比如表一要查出 field1,field2兩個字段,那麼有一個構造函數就是 Bean(type1filed1,type2

field2) ,然後在 hql 裏面就可以直接生成這個 bean 了。

 

  1. spring+Hibernate 中委託方案怎麼配置?

解決方案一,按照 Object[]數據取出數據,然後自己組 bean

解決方案二,對每個表的 bean 寫構造函數,比如表一要查出 field1,field2兩個字段,那麼有一個構造函數就是 Bean(type1filed1,type2

field2) ,然後在 hql 裏面就可以直接生成這個 bean 了。

 

16. hibernate 進行多表查詢每個表中各取幾個字段,也就是說查詢出來的結果集沒有一個實體類與之對應如何解決;

 

解決方案一,按照 Object[]數據取出數據,然後自己組 bean

解決方案二,對每個表的 bean 寫構造函數,比如表一要查出 field1,field2兩個字段,那麼有一個構造函數就是 Bean(type1filed1,type2

field2) ,然後在 hql 裏面就可以直接生成這個 bean 了。

17.介紹一下 Hibernate 的二級緩存

按照以下思路來回答:(1)首先說清楚什麼是緩存,(2)再說有了 hibernate 的 Session 就是一級緩存,即有了一級緩存,爲什麼還要有二級緩存,(3)最後再說如何配置 Hibernate 的二級緩存。

(1)緩存就是把以前從數據庫中查詢出來和使用過的對象保存在內存中(一個數據結構中),這個數據結構通常是或類似 Hashmap,當以後要使用某個對象時,先查詢緩存中是否有這個對象,如果有則使用緩存中的對象,如果沒有則去查詢數據庫,並將查詢出來的對象保存在緩存中,以便下次使用。下面是緩存的僞代碼:引出 hibernate 的第二級緩存,用下面的僞代碼分析了 Cache 的實現原理

Dao

{

       hashmap map = newmap();

       User getUser(integerid)

       {

              User user =map.get(id)               if(user ==null)

              {                      user =session.get(id);                      map.put(id,user);

              }               return user;

       }

}

 

Dao

{

       Cache cache = null        setCache(Cachecache)

       {               this.cache =cache

       }

      

       User getUser(int id)

       {

              if(cache!=null)

              {

                     Useruser = cache.get(id);                      if(user==null)

                     {                             user= session.get(id);                             cache.put(id,user);

                     }                      returnuser;

              }                             returnsession.get(id);

       }

}

  1. Hibernate 的 Session 就是一種緩存,我們通常將之稱爲 Hibernate 的一級緩存,當想使用 session 從數據庫中查詢出一個對象時,Session 也是先從自己內部查看是否存在這個對象,存在則直接返回,不存在纔去訪問數據庫,並將查詢的結果保存在自己內部。由於 Session 代表一次會話過程,一個 Session 與一個數據庫連接相關連,所以 Session 最好不要長時間保持打開,通常僅用於一個事務當中,在事務結束時就應關閉。並且 Session 是線程不安全的,被多個線程共享時容易出現問題。通常只有那種全局意義上的緩存纔是真正的緩存應用,纔有較大的緩存價值,因此,Hibernate 的 Session 這一級緩存的緩存作用並不明顯,應用價值不大。Hibernate 的二級緩存就是要爲 Hibernate 配置一種全局緩存,讓多個線程和多個事務都可以共享這個緩存。我們希望的是一個人使用過,其他人也可以使用,

session 沒有這種效果。

  1. 二級緩存是獨立於 Hibernate 的軟件部件,屬於第三方的產品,多個廠商和組織都提供有緩存產品,例如,EHCache 和 OSCache 等等。在 Hibernate 中使用二級緩存,首先就要在 hibernate.cfg.xml 配置文件中配置使用哪個廠家的緩存產品,接着需要配置該緩存產品自己的配置文件,最後要配置 Hibernate 中的哪些實體對象要納入到二級緩存的管理中。明白了二級緩存原理和有了這個思路後,很容易配置起 Hibernate 的二級緩存。擴展知識:一個 SessionFactory 可以關聯一個二級緩存,也即一個二級緩存只能負責緩存一個數據庫中的數據,當使用 Hibernate 的二級緩存後,注意不要有其他的應用或 SessionFactory 來更改當前數據庫中的數據,這樣緩存的數據就會與數據庫中的實際數據不一致。

 

  1. Spring 的依賴注入是什麼意思?給一個 Bean message 屬性,字符串類型,注入值爲"Hello" XML 配置文件該怎麼寫?

 

  1. Jdo 是什麼?

JDO 是 Java 對象持久化的新的規範,爲 java data object 的簡稱,也是一個用於存取某種數據倉庫中的對象的標準化 API。JDO 提供了透明的對象存儲,因此對開發人員來說,存儲數據對象完全不需要額外的代碼(如 JDBC API 的使用)。這些繁瑣的例行工作已經轉移到 JDO 產品提供商身上,使開發人員解脫出來,從而集中時間和精力在業務邏輯上。另外,

JDO 很靈活,因爲它可以在任何數據底層上運行。JDBC 只是面向關係數據庫(RDBMS) JDO 更通用,提供到任何數據底層的存儲功能,比如關係數據庫、文件、XML 以及對象數據庫(ODBMS)等等,使得應用可移植性更強。

 

  1. 什麼是 spring IOC AOP
  2. STRUTS 的工作流程!
  3. spring EJB 的區別!!

.軟件工程與設計模式

  1. UML 方面

標準建模語言 UML。用例圖,靜態圖(包括類圖、對象圖和包圖),行爲圖,交互圖(順序圖,合作圖),實現圖。

  1. 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(責任鏈模式)

工廠模式:工廠模式是一種經常被使用到的模式,根據工廠模式實現的類可以根據提供的數據生成一組類中某一個類的實例,通常這一組類有一個公共的抽象父類並且實現了相同的方法,但是這些方法針對不同的數據進行了不同的操作。首先需要定義一個基類,該類的子類通過不同的方法實現了基類中的方法。然後需要定義一個工廠類,工廠類可以根據條件生成不同的子類實例。當得到子類的實例後,開發人員可以調用基類中的方法而不必考慮到底返回的是哪一個子類的實例。

3、開發中都用到了那些設計模式?用在什麼場合?

每個模式都描述了一個在我們的環境中不斷出現的問題,然後描述了該問題的解決方案的核心。通過這種方式,你可以無數次地使用那些已有的解決方案,無需在重複相同的工作。主要用到了 MVC 的設計模式。用來開發 JSP/Servlet 或者 J2EE 的相關應用。簡單工廠模式等。

. j2ee 部分

1BS 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 2000Exchange 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 等信息、流向的變化,更像交易中心。

  1. 應用服務器與 WEB SERVER 的區別?

應用服務器:Weblogic、Tomcat、Jboss

WEB SERVER:IIS、 Apache

  1. 應用服務器有那些?

BEA WebLogic Server,IBM WebSphere Application Server,Oracle9i ApplicationServer, jBoss,Tomcat

 

  1. J2EE 是什麼?

答:Je22是 Sun 公司提出的多層(multi-diered),分佈式(distributed),基於組件

(component-base)的企業級應用模型(enterpriese applicationmodel).在這樣的一個應用系統中,可按照功能劃分爲不同的組件,這些組件又可在不同計算機上,並且處於相應的層次 (tier)中。所屬層次包括客戶層(clietn tier)組件,web 層和組件,Business 層和組件,企業信息系統(EIS)層。

 

一個另類的回答:j2ee 就是增刪改查。

  1. J2EE 是技術還是平臺還是框架?什麼是 J2EE

   J2EE 本身是一個標準,一個爲企業分佈式應用的開發提供的標準平臺。

   J2EE 也是一個框架,包括 JDBC、JNDI、RMI、JMS、EJB、JTA 等技術。

  1. 請對以下在 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 特有的。

  1. 如何給 weblogic 指定大小的內存?

(這個問題不作具體回答,列出來只是告訴讀者可能會遇到什麼問題,你不需要面面俱到,什麼都精通。)

 

在啓動 Weblogic 的腳本中(位於所在 Domian 對應服務器目錄下的 startServerName),增加 set MEM_ARGS=-Xms32m-Xmx200m,可以調整最小內存爲32M,最大200M

  1. 如何設定的 weblogic 的熱啓動模式(開發模式)與產品發佈模式?

可以在管理控制檯中修改對應服務器的啓動模式爲開發或產品模式之一。或者修改服務的啓動文件或者 commenv 文件,增加 setPRODUCTION_MODE=true。

  1. 如何啓動時不需輸入用戶名與密碼?

修改服務啓動文件,增加 WLS_USER 和 WLS_PW 項。也可以在 boot.properties 文件中增加加密過的用戶名和密碼.

  1. weblogic 管理制臺中對一個應用域(或者說是一個網站,Domain)進行 jms ejb 或連接池等相關信息進行配置後,實際保存在什麼文件中?

保存在此 Domain 的 config.xml 文件中,它是服務器的核心配置文件。

  1. 說說 weblogic 中一個 Domain 的缺省目錄結構?比如要將一個簡單的 helloWorld.jsp 放入何目錄下,然的在瀏覽器上就可打入 http://主機:端口號 //helloword.jsp 就可以看到運行結果了?又比如這其中用到了一個自己寫的 javaBean 該如何辦?

Domain 目錄服務器目錄 applications,將應用目錄放在此目錄下將可以作爲應用訪問,如果是 Web 應用,應用目錄需要滿足 Web 應用目錄要求,jsp 文件可以直接放在應用目錄中, Javabean 需要放在應用目錄的 WEB-INF 目錄的 classes 目錄中,設置服務器的缺省應用將可以實現在瀏覽器上無需輸入應用名。 12、在 weblogic 中發佈 ejb 需涉及到哪些配置文件

不同類型的 EJB 涉及的配置文件不同,都涉及到的配置文件包括

ejb-jar.xml,weblogic-ejb-jar.xmlCMP 實體 Bean 一般還需要 weblogic-cmp-rdbms-jar.xml

  1. 如何在 weblogic 中進行 ssl 配置與客戶端的認證配置或說說 j2ee(標準)進行 ssl 的配置?

缺省安裝中使用 DemoIdentity.jks 和 DemoTrust.jks KeyStore 實現 SSL,需要配置服務器使用 Enable SSL,配置其端口,在產品模式下需要從 CA 獲取私有密鑰和數字證書,創建 identity 和 trust keystore,裝載獲得的密鑰和數字證書。可以配置此 SSL 連接是單向還是雙向的。

  1. 如何查看在 weblogic 中已經發布的 EJB?

可以使用管理控制檯,在它的 Deployment 中可以查看所有已發佈的 EJB

. EJB 部分

1EJB 是基於哪些技術實現的?並說出 SessionBean EntityBean 的區別,

StatefulBean StatelessBean 的區別。

   EJB 包括 Session Bean、Entity Bean、Message Driven Bean,基於 JNDI、RMI、JAT 等技術實現。

SessionBean 在 J2EE 應用程序中被用來完成一些服務器端的業務操作,例如訪問數據庫、調用其他 EJB 組件。EntityBean 被用來代表應用系統中用到的數據。對於客戶機,SessionBean 是一種非持久性對象,它實現某些在服務器上運行的業務邏輯。對於客戶機,EntityBean 是一種持久性對象,它代表一個存儲在持久性存儲器中的實體的對象視圖,或是一個由現有企業應用程序實現的實體。

Session Bean 還可以再細分爲 Stateful Session Bean 與 Stateless SessionBean,這兩種的 Session Bean 都可以將系統邏輯放在 method 之中執行,不同的是 Stateful

SessionBean 可以記錄呼叫者的狀態,因此通常來說,一個使用者會有一個相對應的

Stateful SessionBean 的實體。Stateless SessionBean 雖然也是邏輯組件,但是他卻不負責記錄使用者狀態,也就是說當使用者呼叫 Stateless SessionBean 的時候,EJB Container 並不會找尋特定的 Stateless SessionBean 的實體來執行這個 method。換言之,很可能數個使用者在執行某個 Stateless SessionBean 的 methods 時,會是同一個 Bean 的

Instance 在執行。從內存方面來看, Stateful SessionBean 與 Stateless SessionBean 比較,

Stateful SessionBean 會消耗 J2EE Server 較多的內存,然而 Stateful SessionBean 的優勢卻在於他可以維持使用者的狀態。

 

  1. 簡要講一下 EJB 7 Transaction Level?
  2. 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 組件。

  1. EJB 包括(SessionBean,EntityBean)說出他們的生命週期,及如何管理事務的?

SessionBean:Stateless Session Bean 的生命週期是由容器決定的,當客戶機發出請求要建立一個 Bean 的實例時,EJB 容器不一定要創建一個新的 Bean 的實例供客戶機調用,而是隨便找一個現有的實例提供給客戶機。當客戶機第一次調用一個 Stateful SessionBean 時,容器必須立即在服務器中創建一個新的 Bean 實例,並關聯到客戶機上,以後此客戶機調用 Stateful SessionBean 的方法時容器會把調用分派到與此客戶機相關聯的 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 接口。

  1. EJB 容器提供的服務

主要提供聲明週期管理、代碼產生、持續性管理、安全、事務管理、鎖和併發行管理等服務。

 

  1. EJB 的激活機制

以 Stateful Session Bean 爲例:其 Cache 大小決定了內存中可以同時存在的 Bean 實例的數量,根據 MRU 或 NRU 算法,實例在激活和去激活狀態之間遷移,激活機制是當客戶端調用某個 EJB 實例業務方法時,如果對應 EJB Object 發現自己沒有綁定對應的 Bean 實例則從其去激活 Bean 存儲中(通過序列化機制存儲實例)回覆(激活)此實例。狀態變遷前會調用對應的 ejbActive 和 ejbPassivate 方法。

  1. EJB 的幾種類型

會話(Session)Bean,實體(Entity)Bean 消息驅動的(Message Driven)Bean 會話 Bean 又可分爲有狀態(Stateful)和無狀態(Stateless)兩種

實體 Bean 可分爲 Bean 管理的持續性(BMP)和容器管理的持續性(CMP)兩種

  1. 客服端調用 EJB 對象的幾個基本步驟

設置 JNDI 服務工廠以及 JNDI 服務地址系統屬性,查找 Home 接口,從 Home 接口調用

Create 方法創建 Remote 接口,通過 Remote 接口調用其業務方法。

十一. webservice 部分

1WEB SERVICE 名詞解釋。JSWDL 開發包的介紹。JAXPJAXM 的解釋。

SOAPUDDI,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 註冊,以使別的企業能夠發現的訪問協議的實現標準。

2CORBA 是什麼?用途是什麼?

CORBA 標準是公共對象請求代理結構(Common Object Request Broker Architecture),由對象管理組織 (Object ManagementGroup,縮寫爲 OMG)標準化。它的組成是接口定義語言(IDL),語言綁定(binding:也譯爲聯編)和允許應用程序間互操作的協議。其目的爲:用不同的程序設計語言書寫在不同的進程中運行,爲不同的操作系統開發。

3. Linux

4LINUX 下線程,GDI 類的解釋。

LINUX 實現的就是基於核心輕量級進程的"一對一"線程模型,一個線程實體對應一個核心輕量級進程,而線程之間的管理在覈外函數庫中實現。

GDI 類爲圖像設備編程接口類庫。

5. 問得稀裏糊塗的題

  1. 四種會話跟蹤技術

會話作用域 ServletsJSP 頁面描述

page 否是代表與一個頁面相關的對象和屬性。一個頁面由一個編譯好的 Java servlet 類(可以帶有任何的 include 指令,但是沒有 include 動作)表示。這既包括 servlet 又包括被編譯成 servlet 的 JSP 頁面

request 是是代表與 Web 客戶機發出的一個請求相關的對象和屬性。一個請求可能跨越多個頁面,涉及多個 Web 組件(由於 forward 指令和 include 動作的關係)

session 是是代表與用於某個 Web 客戶機的一個用戶體驗相關的對象和屬性。一個 Web 會話可以也經常會跨越多個客戶機請求

application 是是代表與整個 Web 應用程序相關的對象和屬性。這實質上是跨越整個 Web 應用程序,包括多個頁面、請求和會話的一個全局作用域

  1. 簡述邏輯操作(&,|,^)與條件操作(&&,||)的區別。

區別主要答兩點:a.條件操作只能操作布爾型的,而邏輯操作不僅可以操作布爾型,而且可以操作數值型

b.邏輯操作不會產生短路

 

十二.其他

1、請用英文簡單介紹一下自己.

4、WEB SERVICE 名詞解釋。JSWDL 開發包的介紹。JAXP、JAXM 的解釋。SOAP、

UDDI,WSDL 解釋。

2、請把 http://tomcat.apache.org/ 首頁的這一段話用中文翻譯一下?

Apache Tomcat is the servlet container that is used in the officialReference

Implementation for theJava ServletandJavaServerPages technologies. The Java Servlet and JavaServer Pagesspecifications are developed by Sun under theJavaCommunity Process.

Apache Tomcat is developed in an open andparticipatory environment and released under theApacheSoftware License. Apache Tomcat is intended to be a collaboration ofthe best-of-breed developers from around the world. We invite you toparticipate in this open development project. To learn more about gettinginvolved,click here.

ApacheTomcat powers numerous large-scale, mission-critical web applications across adiverse range of industries and organizations. Some of these users and theirstories are listed on thePoweredBy wiki page.

3美資軟件公司 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?
  1. Why we use StringBuffer when concatenating strings?
  2. Try to explain Singleton to us? Is it thread safe? If no, how to make itthread safe?
  3. Try to explain Ioc?
  4. How to set many-to-many relationship in Hibernate?
  5. Talk about the difference between INNER JOIN and LFET JOIN.
  6. Why we use index in database? How many indexes is the maximum in one tableas your suggestion?
  7. When ‘Final’ is used in class, method and property, what dose it mean?
  8. Do you have any experience on XML? Talk about any XML tool youused ,e.g. JAXB,

JAXG.

  1. Do you have any experience on Linux?
  2. In OOD what is the reason when you create a Sequence diagram?

Administrator 10:34:20

1,堆和棧的區別,有一個64k 的字符串,是放到堆上,還是放到棧上,爲什麼?

2,什麼時候用到接口,什麼時候用到抽象類,二者區別

3,有一個100萬的數組,裏邊有兩個市重複的,如何設計算法找到。

4,設計數據庫時,n 維,如何設計。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章