Java工程師面試題,整理自網絡與博主各類筆試面試,持續更新

一、面向對象的特徵有哪些方面?html

封裝:一般認爲封裝是把數據和操做數據的方法綁定起來,對數據的訪問只能經過已定義的接口。前端

多態性:多態性是指容許不一樣子類型的對象對同一消息做出不一樣的響應。簡單的說就是用一樣的對象引用調用一樣的方法可是作了不一樣的事情。多態性分爲編譯時的多態性和運行時的多態性。方法重載(overload)實現的是編譯時的多態性(也稱爲前綁定),而方法重寫(override)實現的是運行時的多態性(也稱爲後綁定)。java

二、訪問修飾符public,private,protected,以及不寫(默認)時的區別?mysql

做用域    當前類  同包 子類 其餘程序員

public        √        √       √      √web

protected  √        √       √      ×面試

default       √       √       ×      ×正則表達式

private       √        ×      ×      ×spring

類的成員不寫訪問修飾時默認爲default。默認對於同一個包中的其餘類至關於公開(public),對於不是同一個包中的其餘類至關於私有(private)。受保護(protected)對子類至關於公開,對不是同一包中的沒有父子關係的類至關於私有。sql

三、構造器(constructor)是否可被重寫(override)?

答:構造器不能被繼承,所以不能被重寫,但能夠被重載。

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

答:不對,若是兩個對象x和y知足x.equals(y) == true,它們的哈希碼(hash code)應當相同。Java對於eqauls方法和hashCode方法是這樣規定的:(1)若是兩個對象相同(equals方法返回true),那麼它們的hashCode值必定要相同;(2)若是兩個對象的hashCode相同,它們並不必定相同。

五、抽象類(abstract class)和接口(interface)有什麼異同?

答:抽象類和接口都不可以實例化,但能夠定義抽象類和接口類型的引用。一個類若是繼承了某個抽象類或者實現了某個接口都須要對其中的抽象方法所有進 行實現,不然該類仍然須要被聲明爲抽象類。接口比抽象類更加抽象,由於抽象類中能夠定義構造器,能夠有抽象方法和具體方法,而接口中不能定義構造器並且其 中的方法所有都是抽象方法。抽象類中的成員能夠是private、默認、protected、public的,而接口中的成員全都是public的。抽象 類中能夠定義成員變量,而接口中定義的成員變量實際上都是常量。有抽象方法的類必須被聲明爲抽象類,而抽象類未必要有抽象方法。抽象類和接口中均可以包含靜態成員變量。

六、抽象的(abstract)方法是否可同時是靜態的(static),是否可同時是本地方法(native),是否可同時被synchronized修飾?

答:都不能。抽象方法須要子類重寫,而靜態的方法是沒法被重寫的,所以兩者是矛盾的。本地方法是由本地代碼(如C代碼)實現的方法,而抽象方法是沒有實現的,也是矛盾的。synchronized和方法的實現細節有關,抽象方法不涉及實現細節,所以也是相互矛盾的。

七、接口是否可繼承(extends)接口? 抽象類是否可實現(implements)接口? 抽象類是否可繼承具體類(concrete class)?

答:接口能夠繼承接口。抽象類能夠實現(implements)接口,抽象類可繼承具體類,但前提是具體類必須有明確的構造函數。

八、Anonymous Inner Class(匿名內部類)是否能夠繼承其它類?是否能夠實現接口?

答:能夠繼承其餘類或實現其餘接口,在Swing編程中經常使用此方式來實現事件監聽和回調。

九、數據類型之間的轉換:

1)如何將字符串轉換爲基本數據類型?

2)如何將基本數據類型轉換爲字符串?

1)調用基本數據類型對應的包裝類中的方法parseXXX(String)或valueOf(String)便可返回相應基本類型; Integer.parseInt(a)   Integer.valueOf(a)

2)一種方法是將基本數據類型與空字符串(」」)鏈接(+)便可得到其所對應的字符串;另外一種方法是調用String 類中的valueOf(…)方法返回相應字符串 String.valueOf(int)   Integer.toString 

十、如何實現字符串的反轉及替換? 

答:這裏博主寫了幾個常見的方式,代碼以下所示:

 

 1 public class Reverse {
 2     // 經過遞歸實現字符串反轉
 3     public String reverse1(String str) {
 4         if (str.length() <= 1) {
 5             return str;
 6         } else {
 7             return reverse1(str.substring(1)) + str.charAt(0);
 8         }
 9     }
10     // 經過一個新的字符串循環接收每一個字符
11     public String reverse2(String str) {
12         String reStr = "";
13         for (int i = 0; i < str.length(); i++) {
14             reStr = str.charAt(i) + reStr;// 後面的加在前面
15         }
16         return reStr;
17     }
18     // 轉換成數組來循環接收每一個元素
19     public String reverse3(String str) {
20         char[] charArr = str.toCharArray();
21         String reStr = "";
22         for (int i = 0; i < charArr.length; i++) {
23             reStr = charArr[i] + reStr;
24         }
25         return reStr;
26     }
27     // 轉換成StringBuffer來調用他的反轉方法
28     public String reverse4(String str) {
29         return new StringBuffer(str).reverse().toString();
30     }
31     public static void main(String[] args) {
32         Reverse re = new Reverse();
33         String str = "ABCDE";
34         System.out.println(re.reverse4(str));
35     }
36 }
View Code

 

十一、列出一些你常見的運行時異常? 

答:

ArithmeticException(算術異常)

ClassCastException (類轉換異常)

IllegalArgumentException (非法參數異常)

IndexOutOfBoundsException (下標越界異常)

NullPointerException (空指針異常)

SecurityException (安全異常)

十二、List、Map、Set三個接口存取元素時,各有什麼特色? 
答:List以特定索引來存取元素,能夠有重複元素。Set不能存放重複元素(用對象的equals()方法來區分元素是否重複)。Map保存鍵值對 (key-value pair)映射,映射關係能夠是一對一或多對一。Set和Map容器都有基於哈希存儲和排序樹的兩種實現版本,基於哈希存儲的版本理論存取時間複雜度爲 O(1),而基於排序樹版本的實如今插入或刪除元素時會按照元素或元素的鍵(key)構成排序樹從而達到排序和去重的效果。

1三、什麼是進程,什麼是線程?爲何須要多線程編程?

進程是具備必定獨立功能的程序關於某個數據集合上的一次運行活動,是操做系統進行資源分配和調度的一個獨立單位;

線程是進程的一個實體,是CPU調度和分 派的基本單位,是比進程更小的能獨立運行的基本單位。

線程的劃分尺度小於進程,這使得多線程程序的併發性高;進程在執行時一般擁有獨立的內存單元,而線程之間能夠共享內存。使用多線程的編程一般可以帶來更好的性能和用戶體驗,可是多線程的程序對於其餘程序是不友好的,由於它佔用了更多的CPU資源。

14.闡述JDBC操做數據庫的步驟 
答:下面的代碼以鏈接本機的Mysql數據庫爲例,演示JDBC操做數據庫的步驟。

1. 加載驅動。

 

[java]  view plain  copy
 
  1. Class.forName("com.mysql.jdbc.Driver"); 

 

 

2. 建立鏈接。

 

[java]  view plain  copy
 
  1. Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/xxx");  //xxx:數據庫的名稱

 

 

3. 建立語句。 

 

[java]  view plain  copy
 
  1. PreparedStatement pstmt = con.prepareStatement("select * from t_user where id=?");     
  2.  pstmt.setInt(1, 1);    

 

 

4. 執行語句。

 

[java]  view plain  copy
 
  1. ResultSet rs = pstmt.executeQuery();  

 

 

5. 處理結果。

 

[java]  view plain  copy
 
  1. while(rs.next()) {     
  2.     System.out.println(rs.getInt(1) + " - " + rs.getString(2));    }  

 

 

6. 關閉資源。

 

[java]  view plain  copy
 
  1. finally {      
  2.     if(con != null) {        
  3.       try {               
  4.    con.close();            
  5.   } catch (SQLException e) {                e.printStackTrace();            
  6.   }        
  7.   }     
  8.  }  

總體代碼:

 1 public class JDBCDemo {
 2     private static final String DRIVER = "com.mysql.jdbc.Driver";
 3     private static final String URL = "jdbc:mysql://localhost:3306/db_jsp";
 4     private static final String USER = "root";
 5     private static final String PASSWORD = "123456";
 6     
 7 
 8     public static void main(String[] args) {
 9         PreparedStatement pstmt = null;
10         Connection con = null;
11         try {
12             Class.forName(DRIVER);
13             System.out.println("加載驅動成功");
14             con = DriverManager.getConnection(URL, USER, PASSWORD);
15             System.out.println("獲取鏈接成功");
16             pstmt = con
17                     .prepareStatement("select * from t_user where id=?");
18             pstmt.setInt(1, 1);
19             ResultSet rs = pstmt.executeQuery();
20             while (rs.next()) {
21                 System.out.println(rs.getInt(1)+"\t"+rs.getString(2)+"\t"+rs.getString(3));
22             }
23         } catch (Exception e) {
24             System.out.println("加載驅動失敗");
25             e.printStackTrace();
26         }finally{
27             if (pstmt != null) {
28                 try {
29                     pstmt.close();
30                 } catch (SQLException e) {
31                     e.printStackTrace();
32                 }
33                 if (con != null) {
34                     try {
35                         con.close();
36                     } catch (SQLException e) {
37                         e.printStackTrace();
38                     }
39                 }
40             }
41         }
42     }
43 
44 }
View Code

 

 

 

15.Statement和PreparedStatement有什麼區別?哪一個性能更好? 
與Statement相比

①PreparedStatement接口表明預編譯的語句,它主要的優點在於能夠減小SQL的編譯錯誤並增長SQL的安全性(減小SQL注射攻擊的可能性)

②PreparedStatement中的SQL語句是能夠帶參數的,避免了用字符串鏈接拼接SQL語句的麻煩和不安全;

③當批量處理SQL或頻繁執行相同的查詢時,PreparedStatement有明顯的性能上的優點,因爲數據庫能夠將編譯優化後的SQL語句緩存起來,下次執行相同結構的語句時就會很快(不用再次編譯和生成執行計劃)。

1六、在進行數據庫編程時,鏈接池有什麼做用? 
    因爲建立鏈接和釋放鏈接都有很大的開銷(尤爲是數據庫服務器不在本地時,每次創建鏈接都須要進行TCP的三次握手,釋放鏈接須要進行TCP四次握手,形成的開銷是不可忽視的),爲了提高系統訪問數據庫的性能,能夠事先建立若干鏈接置於鏈接池中,須要時直接從鏈接池獲取,使用結束時歸還鏈接池而沒必要關閉鏈接,從而避免頻繁建立和釋放鏈接所形成的開銷,這是典型的用空間換取時間的策略(浪費了空間存儲鏈接,但節省了建立和釋放鏈接的時間)。池化技術在Java開發中是很常見的,在使用線程時建立線程池的道理與此相同。

1七、Java中是如何支持正則表達式操做的? 
答:Java中的String類提供了支持正則表達式操做的方法,包括:matches()、replaceAll()、replaceFirst()、split()。此外,Java中能夠用Pattern類表示正則表達式對象,它提供了豐富的API進行各類正則表達式操做,請參考下面面試題的代碼。

面試題: - 若是要從字符串中截取第一個英文左括號以前的字符串,例如:北京市(朝陽區)(西城區)(海淀區),截取結果爲:北京市,那麼正則表達式怎麼寫?

 

[java]  view plain  copy
 
  1. import java.util.regex.Matcher;  
  2. import java.util.regex.Pattern;  
  3. class RegExpTest {     
  4.  public static void main(String[] args){  
  5. String str = "北京市(朝陽區)(西城區)(海淀區)";       
  6.    Pattern p = Pattern.compile(".*?(?=\\()");        
  7.   Matcher m = p.matcher(str);        
  8.   if(m.find()) {          
  9.     System.out.println(m.group());        }    
  10.   }  
  11. }  

 

1八、得到一個類的類對象有哪些方式? 
答: 
- 方法1:類型.class,例如:String.class 
- 方法2:對象.getClass(),例如:"hello".getClass() 
- 方法3:Class.forName(),例如:Class.forName("java.lang.String")

1九、如何經過反射建立對象? 
答: 
- 方法1:經過類對象調用newInstance()方法,例如:String.class.newInstance() 
- 方法2:經過類對象的getConstructor()或getDeclaredConstructor()方法得到構造器(Constructor)對象並調用其newInstance()方法建立對象,例如:String.class.getConstructor(String.class).newInstance("Hello");

20、如何經過反射調用對象的方法? 
答:請看下面的代碼:

 

[java]  view plain  copy
 
  1. import java.lang.reflect.Method;  
  2. class MethodInvokeTest {     
  3.  public static void main(String[] args) throws Exception {      
  4.     String str = "hello";         
  5.  Method m = str.getClass().getMethod("toUpperCase");       
  6.    System.out.println(m.invoke(str));  
  7.   // HELLO     
  8.  }  
  9. }  

 

2一、簡述一下面向對象的"六原則一法則"。 
答: 
1)單一職責原則:一個類只作它該作的事情。(單一職責原則想表達的就是"高內聚",寫代碼最終極的原則只有六個字"高內聚、低耦合")
2)開閉原則:軟件實體應當對擴展開放,對修改關閉。(在理想的狀態下,當咱們須要爲一個軟件系統增長新功能時,只須要從原來的系統派生出一些新類就能夠,不須要修改原來的任何一行代碼。要作到開閉有兩個要點:①抽象是關鍵,一個系統中若是沒有抽象類或接口系統就沒有擴展點;②封裝可變性,將系統中的各類可變因素封裝到一個繼承結構中,若是多個可變因素混雜在一塊兒,系統將變得複雜而換亂) 
3)依賴倒轉原則:面向接口編程。(該原則說得直白和具體一些就是聲明方法的參數類型、方法的返回類型、變量的引用類型時,儘量使用抽象類型而不用具體類型,由於抽象類型能夠被它的任何一個子類型所替代) 
4)里氏替換原則:任什麼時候候均可以用子類型替換掉父類型。(子類必定是增長父類的能力而不是減小父類的能力,由於子類比父類的能力更多,把能力多的對象當成能力少的對象來用固然沒有任何問題。) 
5)接口隔離原則:接口要小而專,毫不能大而全。(臃腫的接口是對接口的污染,既然接口表示能力,那麼一個接口只應該描述一種能力,接口也應該是高度內聚的。Java中的接口表明能力、表明約定、表明角色,可否正確的使用接口必定是編程水平高低的重要標識。) 
6)合成聚合複用原則:優先使用聚合或合成關係複用代碼。(經過繼承來複用代碼是面向對象程序設計中被濫用得最多的東西,記住:任什麼時候候都不要繼承工具類,工具是能夠擁有並可使用的,而不是拿來繼承的。) 
迪米特法則:迪米特法則又叫最少知識原則,一個對象應當對其餘對象有儘量少的瞭解。(迪米特法則簡單的說就是如何作到"低耦合",門面模式和調停者模式就是對迪米特法則的踐行。Java Web開發中做爲前端控制器的Servlet或Filter不就是一個門面嗎,瀏覽器對服務器的運做方式一無所知,可是經過前端控制器就可以根據你的請求獲得相應的服務。調停者模式也能夠舉一個簡單的例子來講明,例如一臺計算機,CPU、內存、硬盤、顯卡、聲卡各類設備須要相互配合才能很好的工做。迪米特法則用通俗的話來將就是不要和陌生人打交道,若是真的須要,找一個本身的朋友,讓他替你和陌生人打交道。)

22.簡述一下你瞭解的設計模式

-工廠模式:工廠類能夠根據條件生成不一樣的子類實例,這些子類有一個公共的抽象父類而且實現了相同的方法,可是這些方法針對不一樣的數據進行了不一樣的操做(多態方法)。當獲得子類的實例後,開發人員能夠調用基類中的方法而沒必要考慮到底返回的是哪個子類的實例。 
- 代理模式:給一個對象提供一個代理對象,並由代理對象控制原對象的引用。實際開發中,按照使用目的的不一樣,代理能夠分爲:遠程代理、虛擬代理、保護代理、Cache代理、防火牆代理、同步化代理、智能引用代理。 
- 適配器模式:把一個類的接口變換成客戶端所期待的另外一種接口,從而使本來因接口不匹配而沒法在一塊兒使用的類可以一塊兒工做。 
- 模板方法模式:提供一個抽象類,將部分邏輯以具體方法或構造器的形式實現,而後聲明一些抽象方法來迫使子類實現剩餘的邏輯。不一樣的子類能夠以不一樣的方式實現這些抽象方法(多態實現),從而實現不一樣的業務邏輯。 

2三、用Java寫一個單例類。 

餓漢式單例

 

[java]  view plain  copy
 
  1. public class Singleton {  
  2.     private Singleton(){}     
  3.  private static Singleton instance = new Singleton();     
  4.  public static Singleton getInstance(){        return instance;     
  5.  }  
  6. }  

 

 

懶漢式單例

 

[java]  view plain  copy
 
  1. public class Singleton {  
  2. private Singleton() {}    
  3.   private static Singleton instance = null;      
  4.     public static synchronized Singleton getInstance(){      
  5.     if (instance == null)  
  6.  instance = new Singleton();        
  7.   return instance;     
  8.  }  
  9. }  

 

 

注意:實現一個單例有兩點注意事項,①將構造器私有,不容許外界經過構造器建立對象;②經過公開的靜態方法向外界返回類的惟一實例。這裏有一個問題能夠思考:spring的IoC容器能夠爲普通的類建立單例,它是怎麼作到的呢?

24.什麼是DAO模式?

答:DAO(DataAccess Object)顧名思義是一個爲數據庫或其餘持久化機制提供了抽象接口的對象,在不暴露數據庫實現細節的前提下提供了各類數據操做。將全部對數據源的訪問操做進行抽象化後封裝在一個公共API中。在這個應用程序中,當須要和數據源進行交互的時候則使用這個接口,而且編寫一個單獨的類來實現這個接口,在邏輯上該類對應一個特定的數據存儲。DAO模式實際上包含了兩個模式,一是Data Accessor(數據訪問器),二是Data Object(數據對象),前者要解決如何訪問數據的問題,然後者要解決的是如何用對象封裝數據。

 

25.Servlet的生命週期

Web容器加載Servlet並將其實例化後,Servlet生命週期開始,容器運行其init()方法進行Servlet的初始化;請求到達時調用Servlet的service方法,service方法會調用與請求對應的doGet或doPost等方法;當服務器關閉會項目被卸載時服務器會將Servlet實例銷燬,此時會調用Servlet的destroy方法。

26.轉發(forward)和重定向(redirect)的區別?

1)forward是容器中控制權的轉向,是服務器請求資源,服務器直接訪問目標地址的URL,把那個URL 的響應內容讀取過來,而後把這些內容再發給瀏覽器,瀏覽器根本不知道服務器發送的內容是從哪兒來的,因此它的地址欄中仍是原來的地址。

2)redirect就是服務器端根據邏輯,發送一個狀態碼,告訴瀏覽器從新去請求那個地址,所以從瀏覽器的地址欄中能夠看到跳轉後的連接地址。

3)前者更加高效,在前者能夠知足須要時,儘可能使用轉發(經過RequestDispatcher對象的forward方法,RequestDispatcher對象能夠經過ServletRequest對象的getRequestDispatcher方法得到),而且,這樣也有助於隱藏實際的連接;在有些狀況下,好比,須要跳轉到一個其它服務器上的資源,則必須使用重定向(經過HttpServletResponse對象調用其sendRedirect方法)。

27.get和post請求的區別?

①get請求用來從服務器上得到資源,而post是用來向服務器提交數據;

②get將表單中數據按照name=value的形式,添加到action 所指向的URL 後面,而且二者使用「?」鏈接,而各個變量之間使用「&」鏈接;post是將表單中的數據放在HTML頭部(header),傳遞到action所指向URL;

③get傳輸的數據要受到URL長度限制(1024字節);而post能夠傳輸大量的數據,上傳文件只能使用post方式;

④使用get時參數會顯示在地址欄上,若是這些數據不是敏感數據,那麼可使用get;對於敏感數據仍是應用使用post;

2八、JSP 和Servlet 有有什麼關係?

答:其實這個問題在上面已經闡述過了,Servlet是一個特殊的Java程序,它運行於服務器的JVM中,可以依靠服務器的支持向瀏覽器提供顯示內容。  

JSP本質上是Servlet的一種簡易形式, JSP會被服務器處理成一個相似於Servlet的Java程序,能夠簡化頁面內容的生成。

Servlet和JSP最主要的不一樣點在於,Servlet 的應用邏輯是在Java 文件中,而且徹底從表示層中的HTML分離開來。而JSP的狀況是Java和HTML能夠組合成一個擴展名爲.jsp 的文件(有人說,Servlet就是在Java中寫HTML,而JSP就是在HTML中寫Java代碼,固然,這個說法仍是很片面的)。

JSP側重於視圖,Servlet更側重於控制邏輯,在MVC架構模式中,JSP適合充當視圖(view)而Servlet適合充當控制器(controller)。

2九、JSP中的四種做用域?

答:page、request、session和application,具體以下:

①page 表明與一個頁面相關的對象和屬性。

②request 表明與Web客戶機發出的一個請求相關的對象和屬性。一個請求可能跨越多個頁面,涉及多個Web 組件;須要在頁面顯示的臨時數據能夠置於此做用域

③session表明與某個用戶與服務器創建的一次會話相關的對象和屬性。跟某個用戶相關的數據應該放在用戶本身的session中

④application表明與整個Web應用程序相關的對象和屬性,它實質上是跨越整個Web應用程序,包括多個頁面、請求和會話的一個全局做用域。

30.實現會話跟蹤的技術有哪些?

答:因爲HTTP協議自己是無狀態的,服務器爲了區分不一樣的用戶,就須要對用戶會話進行跟蹤,簡單的說就是爲用戶進行登記,爲用戶分配惟一的ID,下一次用戶在請求中包含此ID,服務器據此判斷究竟是哪個用戶。

①URL 重寫:在URL中添加用戶會話的信息做爲請求的參數,或者將惟一的會話ID添加到URL結尾以標識一個會話。

②設置表單隱藏域:將和會話跟蹤相關的字段添加到隱式表單域中,這些信息不會在瀏覽器中顯示可是提交表單時會提交給服務器。

③cookie:cookie當用戶經過瀏覽器和服務器創建一次會話後,會話ID就會隨響應信息返回存儲在基於窗口的cookie中,那就意味着只要瀏覽器沒有關閉,會話沒有超時,下一次請求時這個會話ID又會提交給服務器讓服務器識別用戶身份。會話中能夠爲用戶保存信息。會話對象是在服務器內存中的,而基於窗口的cookie是在客戶端內存中的。

④HttpSession:在全部會話跟蹤技術中,HttpSession對象是最強大也是功能最多的。當一個用戶第一次訪問某個網站時會自動建立HttpSession,每一個用戶能夠訪問他本身的HttpSession。與上面三種方式不一樣的是,HttpSession放在服務器的內存中

31.JSP中的靜態包含和動態包含有什麼區別? 
答:靜態包含是經過JSP的include指令包含頁面,動態包含是經過JSP標準動做<jsp:forward>包含頁面。靜態包含是編譯時包含,若是包含的頁面不存在則會產生編譯錯誤,並且兩個頁面的"contentType"屬性應保持一致,由於兩個頁面會合二爲一,只產生一個class文件,所以被包含頁面發生的變更再包含它的頁面更新前不會獲得更新。動態包含是運行時包含,能夠向被包含的頁面傳遞參數,包含頁面和被包含頁面是獨立的,會編譯出兩個class文件,若是被包含的頁面不存在,不會產生編譯錯誤,也不影響頁面其餘部分的執行。代碼以下所示:

<%-- 靜態包含 --%><%@ include file="..." %> <%-- 動態包含 --%><jsp:include page="...">    <jsp:param name="..." value="..." /></jsp:include>

3二、什麼是Web Service(Web服務)? 
答:從表面上看,Web Service就是一個應用程序,它向外界暴露出一個可以經過Web進行調用的API。例如能夠建立一個提供天氣預報的Web Service,那麼不管你用哪一種編程語言開發的應用均可以經過調用它的API並傳入城市信息來得到該城市的天氣預報。

補充:這裏必需要說起的一個概念是SOA(Service-Oriented Architecture,面向服務的架構)顯然,Web Service是SOA的一種較好的解決方案,它更多的是一種標準,而不是一種具體的技術。

3三、hashmap和hashtable區別

   1.hashMap去掉了HashTable 的contains方法,可是加上了containsValue()和containsKey()方法。
   2.hashTable同步的,而HashMap是非同步的,效率上逼hashTable要高。
   3.hashMap容許空鍵值,而hashTable不容許。

 

3四、Socket的通訊機制?

套接字(socket)是通訊的基石,是支持TCP/IP協議的網絡通訊的基本操做單元。它是網絡通訊過程當中端點的抽象表示,包含進行網絡通訊必須的五種信息:鏈接使用的協議,本地主機的IP地址,本地進程的協議端口,遠地主機的IP地址,遠地進程的協議端口。

應用層經過傳輸層進行數據通訊時,TCP會遇到同時爲多個應用程序進程提供併發服務的問題。多個TCP鏈接或多個應用程序進程可能須要經過同一個 
TCP協議端口傳輸數據。爲了區別不一樣的應用程序進程和鏈接,許多計算機操做系統爲應用程序與TCP/IP協議交互提供了套接字(Socket)接口。應用層能夠和傳輸層經過Socket接口,區分來自不一樣應用程序進程或網絡鏈接的通訊,實現數據傳輸的併發服務。
創建Socket鏈接至少須要一對套接字,其中一個運行於客戶端,稱爲ClientSocket ,另外一個運行於服務器端,稱爲ServerSocket 。
套接字之間的鏈接過程分爲三個步驟:服務器監聽,客戶端請求,鏈接確認。

服務器監聽:服務器端套接字並不定位具體的客戶端套接字,而是處於等待鏈接的狀態,實時監控網絡狀態,等待客戶端的鏈接請求。

客戶端請求:指客戶端的套接字提出鏈接請求,要鏈接的目標是服務器端的套接字。爲此,客戶端的套接字必須首先描述它要鏈接的服務器的套接字,指出服務器端套接字的地址和端口號,而後就向服務器端套接字提出鏈接請求。

鏈接確認:當服務器端套接字監聽到或者說接收到客戶端套接字的鏈接請求時,就響應客戶端套接字的請求,創建一個新的線程,把服務器端套接字的描述發給客戶端,一旦客戶端確認了此描述,雙方就正式創建鏈接。而服務器端套接字繼續處於監聽狀態,繼續接收其餘客戶端套接字的鏈接請求。

3五、Http的通訊機制?
HTTP協議即超文本傳送協議(Hypertext Transfer Protocol 
),是Web聯網的基礎,也是手機聯網經常使用的協議之一,HTTP協議是創建在TCP協議之上的一種應用。

HTTP鏈接最顯著的特色是客戶端發送的每次請求都須要服務器回送響應,在請求結束後,會主動釋放鏈接。從創建鏈接到關閉鏈接的過程稱爲「一次鏈接」。

1)在HTTP 1.0中,客戶端的每次請求都要求創建一次單獨的鏈接,在處理完本次請求後,就自動釋放鏈接。

2)在HTTP 
1.1中則能夠在一次鏈接中處理多個請求,而且多個請求能夠重疊進行,不須要等待一個請求結束後再發送下一個請求。

因爲HTTP在每次請求結束後都會主動釋放鏈接,所以HTTP鏈接是一種「短鏈接」,要保持客戶端程序的在線狀態,須要不斷地向服務器發起鏈接請求。一般的作法是即時不須要得到任何數據,客戶端也保持每隔一段固定的時間向服務器發送一次「保持鏈接」的請求,服務器在收到該請求後對客戶端進行回覆,代表知道客戶端「在線」。若服務器長時間沒法收到客戶端的請求,則認爲客戶端「下線」,若客戶端長時間沒法收到服務器的回覆,則認爲網絡已經斷開。
因爲一般狀況下Socket鏈接就是TCP鏈接,所以Socket鏈接一旦創建,通訊雙方便可開始相互發送數據內容,直到雙方鏈接斷開。但在實際網絡應用中,客戶端到服務器之間的通訊每每須要穿越多箇中間節點,例如路由器、網關、防火牆等,大部分防火牆默認會關閉長時間處於非活躍狀態的鏈接而致使 
Socket 鏈接斷連,所以須要經過輪詢告訴網絡,該鏈接處於活躍狀態。

而HTTP鏈接使用的是「請求—響應」的方式,不只在請求時須要先創建鏈接,並且須要客戶端向服務器發出請求後,服務器端才能回覆數據。

不少狀況下,須要服務器端主動向客戶端推送數據,保持客戶端與服務器數據的實時與同步。此時若雙方創建的是Socket鏈接,服務器就能夠直接將數據傳送給客戶端;若雙方創建的是HTTP鏈接,則服務器須要等到客戶端發送一次請求後才能將數據傳回給客戶端,所以,客戶端定時向服務器端發送鏈接請求,不只能夠保持在線,同時也是在「詢問」服務器是否有新的數據,若是有就將數據傳給客戶端。

 

3六、HttpServlet容器響應Web客戶請求流程?

1)Web客戶向Servlet容器發出Http請求;

2)Servlet容器解析Web客戶的Http請求;

3)Servlet容器建立一個HttpRequest對象,在這個對象中封裝Http請求信息;

4)Servlet容器建立一個HttpResponse對象;

5)Servlet容器調用HttpServlet的service方法,這個方法中會根據request的Method來判斷具體是執行doGet仍是doPost,把HttpRequest和HttpResponse對象做爲service方法的參數傳給HttpServlet對象;

6)HttpServlet調用HttpRequest的有關方法,獲取HTTP請求信息;

7)HttpServlet調用HttpResponse的有關方法,生成響應數據;

8)Servlet容器把HttpServlet的響應結果傳給Web客戶

 

3七、hibernate中Session的load和get方法的區別是什麼? 
答:主要有如下三項區別: 
① 若是沒有找到符合條件的記錄,get方法返回null,load方法拋出異常。 
② get方法直接返回實體類對象,load方法返回實體類對象的代理。 
③ 在Hibernate 3以前,get方法只在一級緩存中進行數據查找,若是沒有找到對應的數據則越過二級緩存,直接發出SQL語句完成數據讀取;load方法則能夠從二級緩存中獲取數據;從Hibernate 3開始,get方法再也不是對二級緩存只寫不讀,它也是能夠訪問二級緩存的。

說明:對於load()方法Hibernate認爲該數據在數據庫中必定存在能夠放心的使用代理來實現延遲加載,若是沒有數據就拋出異常,而經過get()方法獲取的數據能夠不存在。

3八、如何理解Hibernate的延遲加載機制

答:延遲加載就是並非在讀取的時候就把數據加載進來,而是等到使用時再加載。Hibernate使用了虛擬代理機制實現延遲加載。返回給用戶的並非實體自己,而是實體對象的代理。代理對象在用戶調用getter方法時就會去數據庫加載數據。

3九、簡述Hibernate常見優化策略。

①制定合理的緩存策略

② 採用合理的Session管理機制

③ 儘可能使用延遲加載特性

④若是能夠, 選用基於version的樂觀鎖替代悲觀鎖

⑤在開發過程當中, 開啓hibernate.show_sql選項查看生成的SQL, 從而瞭解底層的情況;開發完成後關閉此選項

40、什麼是IoC和DI?DI是如何實現的? 
答:IoC叫控制反轉,是Inversion of Control的縮寫,控制反轉是把傳統上由程序代碼直接操控的對象的調用權交給容器,經過容器來實現對象組件的裝配和管理。所謂的"控制反轉"就是對組件對象控制權的轉移,從程序代碼自己轉移到了外部容器,由容器來建立對象並管理對象之間的依賴關係。

控制反轉——Spring經過一種稱做控制反轉(IoC)的技術促進了鬆耦合。當應用了IoC,一個對象依賴的其它對象會經過被動的方式傳遞進來,而不是這個對象本身建立或者查找依賴對象,是容器在對象初始化時不等對象請求就主動將依賴傳遞給它。經過IOC反轉控制DI依賴注入完成各個層之間的注入,使得層與層之間實現徹底脫耦,增長運行效率利於維護。

 

4一、解釋一下什麼叫AOP(面向切面編程)? 
答:
    spring的AOP面向切面編程,實如今不改變代碼的狀況下完成對方法的加強。比較經常使用的就是spring的聲明式事務管理,底層經過AOP實現,避免了咱們每次都要手動開啓事物,提交事務的重複性代碼,使得開發邏輯更加清晰。

   簡單點解釋,比方說你想在你的service層全部類中都加上一個打印‘你好’的功能這你經能夠用aop思想來作,你先寫個類寫個方法,方法經實現打印‘你好’而後你Ioc這個類 ref=「service.*」讓每一個類都注入。

   aop就是面向切面的編程。好比說你每作一次對數據庫操做,都要生成一句日誌。若是,你對數據庫的操做有不少類,那你每一類中都要寫關於日誌的方法。可是若是你用aop,那麼你能夠寫一個方法,在這個方法中有關於數據庫操做的方法,每一次調用這個方法的時候,就加上生成日誌的操做。

 

4二、選擇使用Spring框架的緣由(Spring框架爲企業級開發帶來的好處)?

答:能夠從如下幾個方面做答:

1. IoC容器:IoC容器幫助應用程序管理對象以及對象之間的依賴關係,對象之間的依賴關係若是發生了改變只須要修改配置文件而不是修改代碼,由於代碼的修改可能意味着項目的從新構建和完整的迴歸測試。有了IoC容器,程序員不再須要本身編寫工廠、單例,這一點特別符合Spring的精神「不要重複的發明輪子」。

2. AOP:面向切面編程,將全部的橫切關注功能封裝到切面(aspect)中,經過配置的方式將橫切關注功能動態添加到目標代碼上,進一步實現了業務邏輯和系統服務之間的分離。另外一方面,有了AOP程序員能夠省去不少本身寫代理類的工做。

3. MVC:Spring的MVC框架是很是優秀的,從各個方面均可以甩Struts 2幾條街,爲Web表示層提供了更好的解決方案。

4. 事務管理:Spring以寬廣的胸懷接納多種持久層技術,而且爲其提供了聲明式的事務管理,在不須要任何一行代碼的狀況下就可以完成事務管理。

 4三、 簡述攔截器的工做原理以及你在項目中使用過哪些自定義攔截器

答:Struts 2中定義了攔截器的接口以及默認實現,實現了Interceptor接口或繼承了AbstractInterceptor的類能夠做爲攔截器。接口中的init()方法在攔截器被建立後當即被調用,它在攔截器的生命週期內只被調用一次,能夠在該方法中對相關資源進行必要的初始化。每攔截一個請求,intercept()方法就會被調用一次。destory()方法將在攔截器被銷燬以前被調用, 它在攔截器的生命週期內也只被調用一次。

項目中使用過的有權限攔截器、執行時間攔截器、令牌攔截器等。

4四、談一下攔截器和過濾器的區別

答:攔截器和過濾器均可以用來實現橫切關注功能,其區別主要在於:

一、攔截器是基於java反射機制的,而過濾器是基於函數回調的。
二、過濾器依賴於servlet容器,而攔截器不依賴於servlet容器。
三、攔截器只能對Action請求起做用,而過濾器則能夠對幾乎全部請求起做用。
四、攔截器能夠訪問Action上下文、值棧裏的對象,而過濾器不能。
五、在Action的生命週期中,攔截器能夠屢次調用,而過濾器只能在容器初始化時被調用一次。

 過濾器,是在java web中,你傳入的request,response提早過濾掉一些信息,或者提早設置一些參數,而後再傳入servlet或者struts的 action進行業務邏輯,好比過濾掉非法url(不是login.do的地址請求,若是用戶沒有登錄都過濾掉),或者在傳入servlet或者struts的action前統一設置字符集,或者去除掉一些非法字符.

  攔截器,是在面向切面編程的就是在你的service或者一個方法,前調用一個方法,或者在方法後調用一個方法好比動態代理就是攔截器的簡單實現,在你調用方法前打印出字符串(或者作其它業務邏輯的操做),也能夠在你調用方法後打印出字符串,甚至在你拋出異常的時候作業務邏輯的操做。

執行順序:過濾前 - 攔截前 - Action處理 - 攔截後 - 過濾後。

我的認爲過濾是一個橫向的過程,首先把客戶端提交的內容進行過濾(例如未登陸用戶不能訪問內部頁面的處理);過濾經過後,攔截器將檢查用戶提交數據的驗證,作一些前期的數據處理,接着把處理後的數據發給對應的Action;Action處理完成返回後,攔截器還能夠作其餘過程(還沒想到要作啥),再向上返回到過濾器的後續操做。

 

4五、struts1.2和struts2.0的區別?

   struts1.2和struts2.0的對比

   a、Action類:

      struts1.2要求Action類繼承一個基類。struts2.0 Action要求繼承ActionSupport基類

   b、線程模式

      struts1.2 Action是單例模式的而且必須是線程安全的,由於僅有一個Action的實例來處理全部的請求。 struts2.0 Action爲每個請求產生一個實例,所以沒有線程安全問題。

   c、Servlet依賴

      struts1.2 Action依賴於Servlet API,由於當一個Action被調用時HttpServletRequest和HttpServletResponse被傳遞給execut方法。 struts2.0 Action不依賴於容器,容許Action脫離容器單獨測試。

 

4六、常見的網絡協議有哪些?

    1.IP協議:互聯網協議

主要用於負責IP尋址、路由選擇和IP數據包的分割和組裝。一般咱們所說的IP地址能夠理解爲符合IP協議的地址。

    2.TCP協議:傳輸控制協議

    該協議主要用於在主機間創建一個虛擬鏈接,以實現高可靠性的數據包交換。IP協議能夠進行IP數據包的分割和組裝,可是經過IP協議並不能清楚地瞭解到數據包是否順利地發送給目標計算機。而使用TCP協議就不一樣了,在該協議傳輸模式中在將數據包成功發送給目標計算機後,TCP會要求發送一個確認;若是在某個時限內沒有收到確認,那麼TCP將從新發送數據包。另外,在傳輸的過程當中,若是接收到無序、丟失以及被破壞的數據包,TCP還能夠負責恢復。

    3.FTP(File Transfer Protocol):遠程文件傳輸協議,容許用戶將遠程主機上的文件拷貝到本身的計算機上。

    4.HTTP:超文本傳輸協議(HTTP,HyperText Transfer Protocol)是互聯網上應用最爲普遍的一種網絡協議。全部的WWW文件都必須遵照這個標準。設計HTTP最初的目的是爲了提供一種發佈和接收HTML頁面的方法。

    5.ARP協議:AddressResolutionProtocol地址解析協議

簡單地說,ARP協議主要負責將局域網中的32爲IP地址轉換爲對應的48位物理地址,即網卡的MAC地址。

 

4七、計算機網絡分層,每層所用協議,協議所佔端口

(1)應用層:與其餘計算機進行通信的一個應用,它是對應應用程序的通訊服務的。示例:telnet,HTTP,FTP,WWW,NFS,SMTP等。 
    (2)表示層:這一層的主要功能是定義數據格式及加密。示例:加密,ASII等。 
    (3)會話層:他定義瞭如何開始、控制和結束一個會話,包括對多個雙向小時的控制和管理,以便在只完成連續消息的一部分時能夠通知應用,從而使表示層看到的數據是連續的。示例:RPC,SQL等。 
   (4)傳輸層:這層的功能包括是否選擇差錯恢復協議仍是無差錯恢復協議,及在同一主機上對不一樣應用的數據流的輸入進行復用,還包括對收到的順序不對的數據包的從新排序功能。示例:TCP,UDP,SPX。 
   (5)網絡層:這層對端到端的包傳輸進行定義,他定義了可以標識全部結點的邏輯地址,還定義了路由實現的方式和學習的方式。。示例:IP,IPX等。 
   (6)數據鏈路層:他定義了在單個鏈路上如何傳輸數據。

   (7)物理層:OSI的物理層規範是有關傳輸介質的特性標準,這些規範一般也參考了其餘組織制定的標準。

 

4八、html訪問全過程

A)解析Web頁面的URL,獲得Web服務器的域名
    B)經過DNS服務器得到Web服務器的IP地址

I)與Web服務器創建TCP鏈接
    E)與Web服務器創建HTTP鏈接

C)從Web服務器得到URL指定的文檔
    G)瀏覽器解釋頁面文檔,並顯示在屏幕

 

4九、classloader原理

    1.classLoader的介紹及加載過程

與普通程序不一樣的是,Java程序(class文件)並非本地的可執行程序。當運行Java程序時,首先運行JVM(Java虛擬機),而後再把Java class加載到JVM裏頭運行,負責加載Java class的這部分就叫作Class Loader。因此classLoader的目的在於把class文件裝入到jvm中。

那麼classLoader又在那裏的啦?又由誰調用呢?其實classLoader只是jvm的一個實現的一部分。Jvm提供的一個頂級的classLoader(bootStrap classLoader),bootStrap classLoader負責加載java核心的API以知足java程序最基本的需求。Jvm還提供的兩個classLoader,其中Extension ClassLoader負責加載擴展的Java class,Application ClassLoader負責加載應用程序自身的類。而Extension ClassLoader和Application ClassLoader則由bootStrap classLoader加載。

2.classLoader加載的基本流程

   當運行一個程序的時候,JVM啓動,運行bootstrap classloader,該ClassLoader加載java核心API(ExtClassLoader和AppClassLoader也在此時被加載),而後調用ExtClassLoader加載擴展API,最後AppClassLoader加載CLASSPATH目錄下定義的Class,這就是一個程序最基本的加載流程。

3.classLoader加載的方式

   其實classLoader在加載class文件的時候就採用的雙親委託模式。每個自定義ClassLoader都必須繼承ClassLoader這個抽象類,而每一個ClassLoader都會有一個parent ClassLoader,咱們能夠看一下ClassLoader這個抽象類中有一個getParent()方法,這個方法用來返回當前ClassLoader的parent。

 

50、快速排序原理

 原理:

    快速排序也是分治法思想的一種實現,他的思路是使數組中的每一個元素與基準值(Pivot,一般是數組的首個值,A[0])比較,數組中比基準值小的放在基準值的左邊,造成左部;大的放在右邊,造成右部;接下來將左部和右部分別遞歸地執行上面的過程:選基準值,小的放在左邊,大的放在右邊。。。直到排序結束。

 步驟:

1.找基準值,設Pivot = a[0] 

2.分區(Partition):比基準值小的放左邊,大的放右邊,基準值(Pivot)放左部與右部的之間。

3.進行左部(a[0] - a[pivot-1])的遞歸,以及右部(a[pivot+1] - a[n-1])的遞歸,重複上述步驟。

 

[java]  view plain  copy
 
  1. 1.//快速排序    
  2. 2.void quick_sort(int s[], int l, int r)    
  3. 3.{    
  4. 4.    if (l < r)    
  5. 5.    {    
  6. 6.        //Swap(s[l], s[(l + r) / 2]); //將中間的這個數和第一個數交換 參見注1    
  7. 7.       int i = l, j = r, x = s[l];    
  8. 8.       while (i < j)    
  9. 9.       {    
  10. 10.        while(i < j && s[j] >= x) // 從右向左找第一個小於x的數    
  11. 11.                j--;      
  12. 12.          if(i < j)     
  13. 13.          s[i++] = s[j];    
  14. 14.                
  15. 15.       while(i < j && s[i] < x) // 從左向右找第一個大於等於x的數    
  16. 16.            i++;      
  17. 17.         if(i < j)     
  18. 18.          s[j--] = s[i];    
  19. 19.        }    
  20. 20.        s[i] = x;    
  21. 21.        quick_sort(s, l, i - 1); // 遞歸調用     
  22. 22.        quick_sort(s, i + 1, r);    
  23. 23.    }    
  24. 24.}    

 

5一、各類集合類之間的區別

 1.ArrayList: 元素單個,效率高,多用於查詢

2.Vector:  元素單個,線程安全,多用於查詢

3.LinkedList:元素單個,多用於插入和刪除

4.HashMap:  元素成對,元素可爲空

5.HashTable: 元素成對,線程安全,元素不可爲空

 

5二、內存溢出和內存泄漏

    內存溢出是指已有的數據超過了其得到到的內存所能存儲的範圍,好比用一個字節存放1000這個數字就屬於內存溢出。好比說你申請了一個integer,但給它存了long才能存下的數,那就是內存溢出。

    Java內存泄漏就是沒有及時清理內存垃圾,致使系統沒法再給你提供內存資源(內存資源耗盡)。Java內存泄露是說程序邏輯問題,形成申請的內存沒法釋放.這樣的話不管多少內存,遲早都會被佔用光的.最簡單的例子就是死循環了.因爲程序判斷錯誤導常常發生此事。

 

5三、jvm佈局

    如下是JVM的一個基本架構圖,在這個基本架構圖中,棧有兩部份,Java線程棧以及本地方法棧

在JVM中堆空間劃分以下圖所示

上圖中,刻畫了Java程序運行時的堆空間,能夠簡述成以下2條

1.JVM中堆空間能夠分紅三個大區,新生代、老年代、永久代

2.新生代能夠劃分爲三個區,Eden區,兩個倖存區

Jvm主要包括下面兩面方面:

· Java代碼編譯和執行的整個過程

· JVM內存管理及垃圾回收機制

5四、在瀏覽器中輸入www.baidu.com後執行的所有過程

一、客戶端瀏覽器經過DNS解析到www.baidu.com的IP地址220.181.27.48,經過這個IP地址找到客戶端到服務器的路徑。客戶端瀏覽器發起一個HTTP會話到220.161.27.48,而後經過TCP進行封裝數據包,輸入到網絡層。

二、在客戶端的傳輸層,把HTTP會話請求分紅報文段,添加源和目的端口,如服務器使用80端口監聽客戶端的請求,客戶端由系統隨機選擇一個端口如5000,與服務器進行交換,服務器把相應的請求返回給客戶端的5000端口。而後使用IP層的IP地址查找目的端。

三、客戶端的網絡層不用關係應用層或者傳輸層的東西,主要作的是經過查找路由表肯定如何到達服務器,期間可能通過多個路由器,這些都是由路由器來完成的工做,我不做過多的描述,無非就是經過查找路由表決定經過那個路徑到達服務器。

四、客戶端的鏈路層,包經過鏈路層發送到路由器,經過鄰居協議查找給定IP地址的MAC地址,而後發送ARP請求查找目的地址,若是獲得迴應後就可使用ARP的請求應答交換的IP數據包如今就能夠傳輸了,而後發送IP數據包到達服務器的地址。

5五、IO流類

相關文章
相關標籤/搜索