明航凱亞面試題

 


1. 下列代碼的執行結果是什麼:java

public class Test { public static void main(String[] args) { (new ThreadTest()).start(); } } class ThreadTest extends Thread{ @Override public void run() { System.out.println("In run"); yield(); System.out.println("leaving run."); } }

答案:In run 在leaving run以前被打印出來。設計模式

分析:Thread類的yield()方法的做用爲線程讓步,嘗試釋放當前線程對CPU資源的佔用,並從新進入就緒狀態。當其再次獲取到CPU資源後會繼續執行。數組

 


 

2. <jsp:forward>和HttpServletResponse的sendredirect()方法的主要區別描述正確的是:瀏覽器

答案爲:forward執行在服務器端,而sendredirect在客戶端服務器

分析:<jsp:forward> 的原理是HttpServletRequest的getRequestDispatcher的forward方法,爲請求的轉發,而sendredirect爲頁面的重定向。兩者的完整區別爲:  oracle

a.     重定向app

response.sendRedirect(你要跳轉的路徑)jsp

服務器告知給客戶端,讓客戶端去請求你要跳轉的路徑。ide

一、          跳轉前和跳轉後的request對象不是同一個對象了;意味着跳轉後不能從request中獲取到跳轉前的用戶請求數據;post

二、          在客戶端的瀏覽器地址欄上看到的地址是跳轉的地址。

三、          能夠跳轉到項目外的地址;

四、          若是跳轉的路徑採用根路徑的話,須要攜帶項目的上下文路徑。

根路徑:   /應用上下文/資源目錄/文件名

問題:如何動態的獲取到應用上下文路徑?

            request.getContextPath()
五、          跳轉後,若是客戶端刷新頁面,它只會刷新跳轉後的頁面

 b.     請求的轉發

request.getRequestDispatcher(你要跳轉的路徑)

                .forward(request,response);

       服務器本身去請求跳轉後的資源並執行,執行後將執行結果響應給客戶端。

一、          跳轉前和跳轉後的request對象是同一個對象;意味着跳轉後能夠從request中獲取到跳轉前的用戶請求數據;

二、          在客戶端的瀏覽器地址欄上看到的地址是跳轉的地址。

三、          不能夠跳轉到項目外的地址;

四、          若是跳轉的路徑採用根路徑的話,不須要攜帶項目的上下文路徑。

根路徑:  /資源目錄/文件名

五、   跳轉後,若是客戶端刷新頁面,它會將跳轉前和跳轉後的頁面都再執行一次。
六、   請求的轉發,他能夠跳轉到WEB-INF下的頁面。

3. 如下語句建立了幾個對象
String a,b,c; a = "a"; b = "b"; a = a+b; StringBuffer d = new StringBuffer("abc"); d = d.append("567");

 



答案:這個題,說實話很誅心,很是的噁心,下面是分析

首先, 明確一下 建立對象 的具體含義. 按個人理解, 若是字符串是 字符常量, 那麼這個字符串對象是在編譯時候肯定好的, 它是存放在常量池中的, 所以就不算是建立了一個字符串對象, 而若是有 String b = new String("abc") 之類的操做, 那麼能夠認爲是建立了字符串對象, 並與變量 b 關聯.

根據上面的定義, 那麼有: "a", "b", "abc", "567" 都是常量, 放在常量池中的, 所以就不算是建立對象了。

那麼來看一下代碼:
源碼:

1: String a,b,c; 2: a = "a"; 3: b = "b"; 4: a = a+b; 5: StringBuffer d = new StringBuffer("abc"); 6: d = d.append("567");

爲了方便起見, 我手動給每一行編號了.
再來看一下對應的字節碼:

Code: stack=3, locals=5, args_size=1
     0: ldc           #2                  // String a
     2: astore_1 3: ldc           #3                  // String b
     5: astore_2 6: new           #4                  // class java/lang/StringBuilder
     9: dup 10: invokespecial #5                  // Method java/lang/StringBuilder."<init>":()V
    13: aload_1 14: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
    17: aload_2 18: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
    21: invokevirtual #7                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
    24: astore_1 25: new           #8                  // class java/lang/StringBuffer
    28: dup 29: ldc           #9                  // String abc
    31: invokespecial #10                 // Method java/lang/StringBuffer."<init>":(Ljava/lang/String;)V
    34: astore        4
    36: aload         4
    38: ldc           #11                 // String 567
    40: invokevirtual #12                 // Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
    43: astore        4
    45: return

由字節碼能夠看出, 源碼的第四行 a = a+b 翻譯爲以下代碼:

StringBuilder builder = new StringBuilder(); builder.append(a); builder.append(b); a = builder.toString();

那麼這裏就新建了一個對象 new StringBuilder(), 接着調用 builder.toString() 方法, 它源碼以下:

@Override public String toString() { // Create a copy, don't share the array
    return new String(value, 0, count); }

因而 builder.toString() 方法建立了一個 String 對象, 所以目前咱們已經建立了 兩個對象 了.

接着第五行 StringBuffer d = new StringBuffer("abc") 毫無疑問是 建立了對象 StringBuffer, 因而咱們就有 三個對象 了. 有一點須要注意的是 StringBuffer d 從始至終都沒有調用 toString 方法, 所以就不會有多餘的 String 建立出來.

總結:

  • "a": 字符串常量, 不算建立對象

  • "b": 字符串常量, 不算建立對象

  • builder 對象: 在執行 a = a+b 時建立.

  • "ab": 由 StringBuilder.toString() 建立.

  • "abc": 字符串常量, 不算建立對象

  • "567": 字符串常量, 不算建立對象

  • d: 經過 new StringBuffer("abc") 建立.

所以最終有三個對象建立了.

固然有的學者也將字符串常量理解爲對象,這樣的話總共就是七個對象被建立了

 


4. 在實現DAO設計模式時,下面哪一種模式常常被採用?
答案:Factory模式

5. 有以下的Servlet類
import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; public class MyServlet extends HttpServlet { @Override public void init() throws ServletException { } @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter out = resp.getWriter(); out.print("hello"); } }

 

加入編譯SErvlet要具有的環境都已經齊全,用徹底正確的命令編譯此文件,描述正確的是:
答案:編譯後,將MyServlet.class放在正確的位置,在瀏覽器中查看該servlet,會看到輸出文字「hello」
分析:此servlet雖然沒有doget和dopost,可是咱們分析HttpServlet中的doget方法源碼可見:
 protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String method = req.getMethod(); long lastModified; if (method.equals("GET")) { lastModified = this.getLastModified(req); if (lastModified == -1L) { this.doGet(req, resp); } else { long ifModifiedSince; try { ifModifiedSince = req.getDateHeader("If-Modified-Since"); } catch (IllegalArgumentException var9) { ifModifiedSince = -1L; } if (ifModifiedSince < lastModified / 1000L * 1000L) { this.maybeSetLastModified(resp, lastModified); this.doGet(req, resp); } else { resp.setStatus(304); } } } else if (method.equals("HEAD")) { lastModified = this.getLastModified(req); this.maybeSetLastModified(resp, lastModified); this.doHead(req, resp); } else if (method.equals("POST")) { this.doPost(req, resp); } else if (method.equals("PUT")) { this.doPut(req, resp); } else if (method.equals("DELETE")) { this.doDelete(req, resp); } else if (method.equals("OPTIONS")) { this.doOptions(req, resp); } else if (method.equals("TRACE")) { this.doTrace(req, resp); } else { String errMsg = lStrings.getString("http.method_not_implemented"); Object[] errArgs = new Object[]{method}; errMsg = MessageFormat.format(errMsg, errArgs); resp.sendError(501, errMsg); } }

 

因而可知:servlet處理客戶端的請求默認是經過service方法攔擊全部的請求,並根據具體的客戶端請求方式,調用對應的doXxx方法,而此題中service方法被重寫,則客戶端無論以何種method請求該servelt,均是執行重寫後的service方法,而不會執行doXxx方法


6. 評估下面一組SQL語句:
CREATE TABLE DEPT (DEPTNO NUMBER(2),DNAME VARCHAR2(14),1oc VARCHAR2(13));
ROLLBACK; DESCRIBE DEPT
下面關於該組語句的描述哪一個是正確的?()

答案:A

分析: CREATE TABLE時不須要commit

describe 命令用於查看特定表的詳細信息(oracle中)

 

7. 一個輸入項的合法範圍是0-100的整數,則其邊界值爲   -1,0,100,101

 

答案:D    

分析: 其實我以爲B也有錯,一個類實現了接口其實不必定非要實現接口的全部方法,只要該類爲抽象類便可,讓其子類再去實現方法;

         在java的重寫中,遵循訪問權限  重寫前  <= 重寫後的規則,而接口中全部的方法的訪問修飾符都已是public最大了,因此實現接口不能夠修改其訪問權限;

  接口中定義變量,其實是定義的常量,在編譯器編譯時會自動追加: public static final 

 


答案:  有錯

分析: 抽象方法不能有{}方法的實現體。


 

答案: 0次
分析:查看ArrayList的源碼中的構造方法,在構造方法初始化的時候就已經建立大小爲20的對象數組了。
 public ArrayList(int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { this.elementData = EMPTY_ELEMENTDATA; } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } }

可見,ArrayList在指定initialCapacity時是直接分配對象的數組空間爲initialCapacity;

 

若是是 List list  = new ArrayList();

經過add方法插入20條記錄的話,則遵循下面的法則:

ArrayList在沒指定initialCapacity時會使用延遲分配對象數組空間,當第一次插入元素時才分配10(默認)個對象空間。
若是有20個數據須要添加,那麼會分別在第一次的時候,將ArrayList的容量變爲10;以後擴容會按照1.5倍增加。
也就是當添加第11個數據的時候,Arraylist繼續擴容變爲10*1.5=15;當添加第16個數據時,繼續擴容變爲15 * 1.5 =22個。
相關文章
相關標籤/搜索