1. 程式人生 > >Java面試題集(116-135)

Java面試題集(116-135)

分享一下我的偶像大神的人工智慧教程!http://blog.csdn.net/jiangjunshow

Java程式設計師面試題集(116-135)

摘要:這一部分講解基於Java的Web開發相關面試題,即便在Java走向沒落的當下,基於Java的Web開發因為擁有非常成熟的解決方案,仍然被廣泛應用。不管你的Web開發中是否使用框架,JSP和Servlet都是一個必備的基礎,在面試的時候被問到的概率還是很高的。


116、說出Servlet的生命週期,並說出Servlet和CGI的區別?

答:Web容器載入Servlet並將其例項化後,Servlet生命週期開始,容器執行其init()方法進行Servlet的初始化;請求到達時呼叫Servlet的service方法,service方法會呼叫與請求對應的doGet或doPost等方法;當伺服器關閉會專案被解除安裝時伺服器會將Servlet例項銷燬,此時會呼叫Servlet的destroy方法。Servlet與CGI的區別在於Servlet處於伺服器程序中,它通過多執行緒方式執行其service方法,一個例項可以服務於多個請求,並且其例項一般不會銷燬,而CGI 對每個請求都產生新的程序,服務完成後就銷燬,所以效率上低於Servlet。

【補充1】SUN公司在1996年釋出Servlet技術就是為了和CGI進行競爭,Servlet是一個特殊的Java程式,一個基於Java的Web應用通常包含一個或多個Servlet類。   Servlet不能夠自行建立並執行,它是在Servlet容器中執行的,容器將使用者的請求傳遞給Servlet程式,此外將Servlet的響應回傳給使用者。通常一個Servlet會關聯一個或多個JSP頁面。以前CGI經常因為效能開銷上的問題被詬病,然而Fast CGI早就已經解決了CGI效率上的問題,所以面試的時候大可不必詬病CGI,騰訊的網站就使用了CGI技術,相信你也沒感覺它哪裡不好。

【補充2】Servlet介面定義了5個方法,其中前三個方法與Servlet生命週期相關:

  1. void init(ServletConfig config) throws ServletException
  2. void service(ServletRequest req, ServletResponse resp) throws ServletException, java.io.IOException
  3. void destory()
  4. java.lang.String getServletInfo()
  5. ServletConfig getServletConfig()

117、轉發(forward)和重定向(redirect)的區別?

答:forward是容器中控制權的轉向,是伺服器請求資源,伺服器直接訪問目標地址的URL,把那個URL 的響應內容讀取過來,然後把這些內容再發給瀏覽器,瀏覽器根本不知道伺服器傳送的內容是從哪兒來的,所以它的位址列中還是原來的地址。redirect就是伺服器端根據邏輯,傳送一個狀態碼,告訴瀏覽器重新去請求那個地址,因此從瀏覽器的位址列中可以看到跳轉後的連結地址。前者更加高效,在前者可以滿足需要時,儘量使用轉發(通過RequestDispatcher物件的forward方法,RequestDispatcher物件可以通過ServletRequest物件的getRequestDispatcher方法獲得),並且,這樣也有助於隱藏實際的連結;在有些情況下,比如,需要跳轉到一個其它伺服器上的資源,則必須使用重定向(通過HttpServletResponse物件呼叫其sendRedirect方法)。

 

118、JSP有哪些內建物件?作用分別是什麼?

答:JSP有9個內建物件:

  1. request:封裝客戶端的請求,其中包含來自GET或POST請求的引數;
  2. response:封裝伺服器對客戶端的響應;
  3. pageContext:通過該物件可以獲取其他物件;
  4. session:封裝使用者會話的物件;
  5. application:封裝伺服器執行環境的物件;
  6. out:輸出伺服器響應的輸出流物件;
  7. config:Web應用的配置物件;
  8. page:JSP頁面本身(相當於Java程式中的this);
  9. exception:封裝頁面丟擲異常的物件。

【補充】如果用Servlet來生成網頁中的動態內容無疑是非常繁瑣的工作,另一方面,所有的文字和HTML標籤都是硬編碼,即使做出微小的修改,都需要進行重新編譯。JSP解決了Servlet的這些問題,它是Servlet很好的補充,可以專門用作呈現給使用者的檢視(View),而Servlet作為控制器(Controller)專門負責處理使用者請求並轉發或重定向到某個頁面。基於Java的Web開發很多都同時使用了Servlet和JSP。JSP頁面其實是一個Servlet,能夠執行Servlet的伺服器(Servlet容器)通常也是JSP容器,可以提供JSP頁面的執行環境,Tomcat就是一個Servlet/JSP容器。第一次請求一個JSP頁面時,Servlet/JSP容器首先將JSP頁面轉換成一個JSP頁面的實現類,這是一個實現了JspPage介面或其子介面HttpJspPage的Java類。JspPage介面是Servlet的子介面,因此每個JSP頁面都是一個Servlet。轉換成功後,容器會編譯Servlet類,之後容器載入和例項化Java位元組碼,並執行它通常對Servlet所做的生命週期操作。對同一個JSP頁面的後續請求,容器會檢視這個JSP頁面是否被修改過,如果修改過就會重新轉換並重新編譯並執行。如果沒有則執行記憶體中已經存在的Servlet例項。我們可以看一段JSP程式碼對應的Java程式就知道一切了,而且9個內建物件的神祕面紗也會被揭開。

JSP頁面:


  
  1. <%@ page pageEncoding="UTF-8"%>
  2. <%
  3. String path = request.getContextPath();
  4. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
  5. %>
  6. <!DOCTYPE html>
  7. <html>
  8. <head>
  9. <base href="<%=basePath%>">
  10. <title>首頁 </title>
  11. <style type="text/css">
  12. * { font-family: "Arial"; }
  13. </style>
  14. </head>
  15. <body>
  16. <h1>Hello, World! </h1>
  17. <hr/>
  18. <h2>Current time is: <%= new java.util.Date().toString() %> </h2>
  19. </body>
  20. </html>

對應的Java程式碼:


  
  1. /*
  2. * Generated by the Jasper component of Apache Tomcat
  3. * Version: Apache Tomcat/7.0.52
  4. * Generated at: 2014-10-13 13:28:38 UTC
  5. * Note: The last modified time of this file was set to
  6. * the last modified time of the source file after
  7. * generation to assist with modification tracking.
  8. */
  9. package org.apache.jsp;
  10. import javax.servlet.*;
  11. import javax.servlet.http.*;
  12. import javax.servlet.jsp.*;
  13. public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
  14. implements org. apache. jasper. runtime. JspSourceDependent {
  15. private static final javax.servlet.jsp.JspFactory _jspxFactory = javax.servlet.jsp.JspFactory
  16. .getDefaultFactory();
  17. private static java.util.Map<java.lang.String, java.lang.Long> _jspx_dependants;
  18. private javax.el.ExpressionFactory _el_expressionfactory;
  19. private org.apache.tomcat.InstanceManager _jsp_instancemanager;
  20. public java.util.Map<java.lang.String, java.lang.Long> getDependants() {
  21. return _jspx_dependants;
  22. }
  23. public void _jspInit() {
  24. _el_expressionfactory = _jspxFactory.getJspApplicationContext(
  25. getServletConfig().getServletContext()).getExpressionFactory();
  26. _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory
  27. .getInstanceManager(getServletConfig());
  28. }
  29. public void _jspDestroy() {
  30. }
  31. public void _jspService(
  32. final javax.servlet.http.HttpServletRequest request,
  33. final javax.servlet.http.HttpServletResponse response)
  34. throws java.io.IOException, javax.servlet.ServletException {
  35. // 9個內建物件就是在這裡定義的
  36. final javax.servlet.jsp.PageContext pageContext;
  37. javax.servlet.http.HttpSession session = null;
  38. final javax.servlet.ServletContext application;
  39. final javax.servlet.ServletConfig config;
  40. javax.servlet.jsp.JspWriter out = null;
  41. final java.lang.Object page = this;
  42. javax.servlet.jsp.JspWriter _jspx_out = null;
  43. javax.servlet.jsp.PageContext _jspx_page_context = null;
  44. try {
  45. response.setContentType( "text/html;charset=UTF-8");
  46. pageContext = _jspxFactory.getPageContext( this, request, response,
  47. null, true, 8192, true);
  48. _jspx_page_context = pageContext;
  49. application = pageContext.getServletContext();
  50. config = pageContext.getServletConfig();
  51. session = pageContext.getSession();
  52. out = pageContext.getOut();
  53. _jspx_out = out;
  54. out.write( '\r');
  55. out.write( '\n');
  56. String path = request.getContextPath();
  57. String basePath = request.getScheme() + "://"
  58. + request.getServerName() + ":" + request.getServerPort()
  59. + path + "/";
  60. // 以下程式碼通過輸出流將HTML標籤輸出到瀏覽器中
  61. out.write( "\r\n");
  62. out.write( "\r\n");
  63. out.write( "<!DOCTYPE html>\r\n");
  64. out.write( "<html>\r\n");
  65. out.write( " <head>\r\n");
  66. out.write( " <base href=\"");
  67. out.print(basePath);
  68. out.write( "\">\r\n");
  69. out.write( " <title>首頁</title>\r\n");
  70. out.write( " <style type=\"text/css\">\r\n");
  71. out.write( " \t* { font-family: \"Arial\"; }\r\n");
  72. out.write( " </style>\r\n");
  73. out.write( " </head>\r\n");
  74. out.write( " \r\n");
  75. out.write( " <body>\r\n");
  76. out.write( " <h1>Hello, World!</h1>\r\n");
  77. out.write( " <hr/>\r\n");
  78. out.write( " <h2>Current time is: ");
  79. out.print( new java.util.Date().toString());
  80. out.write( "</h2>\r\n");
  81. out.write( " </body>\r\n");
  82. out.write( "</html>\r\n");
  83. } catch (java.lang.Throwable t) {
  84. if (!(t instanceof javax.servlet.jsp.SkipPageException)) {
  85. out = _jspx_out;
  86. if (out != null && out.getBufferSize() != 0)
  87. try {
  88. out.clearBuffer();
  89. } catch (java.io.IOException e) {
  90. }
  91. if (_jspx_page_context != null)
  92. _jspx_page_context.handlePageException(t);
  93. else
  94. throw new ServletException(t);
  95. }
  96. } finally {
  97. _jspxFactory.releasePageContext(_jspx_page_context);
  98. }
  99. }
  100. }


119、get和post請求的區別?

答:

①get請求用來從伺服器上獲得資源,而post是用來向伺服器提交資料;

②get將表單中資料按照name=value的形式,新增到action 所指向的URL 後面,並且兩者使用“?”連線,而各個變數之間使用“&”連線;post是將表單中的資料放在HTML頭部(header),傳遞到action所指向URL;

③get傳輸的資料要受到URL長度限制(1024位元組);而post可以傳輸大量的資料,上傳檔案只能使用post方式;

④使用get時引數會顯示在位址列上,如果這些資料不是敏感資料,那麼可以使用get;對於敏感資料還是應用使用post;

⑤get使用MIME型別application/x-www-form-urlencoded的URL 編碼(URL encoding,也叫百分號編碼)文字的格式傳遞引數,保證被傳送的引數由遵循規範的文字組成,例如一個空格的編碼是"%20"。

 

120、常用的Web容器

答:Unix和Linux平臺下使用最廣泛的免費HTTP伺服器是Apache伺服器,而Windows平臺的伺服器通常使用IIS作為Web伺服器。選擇Web伺服器應考慮的因素有:效能、安全性、日誌和統計、虛擬主機代理伺服器、緩衝服務和整合應用程式等。下面是對常用伺服器的簡介:

  • IIS:Microsoft的Web伺服器產品為Internet Information Services。IIS 是允許在公共Intranet或Internet上釋出資訊的Web伺服器。IIS是目前最流行的Web伺服器產品之一,很多著名的網站都是建立在IIS的平臺上。IIS提供了一個圖形介面的管理工具,稱為Internet服務管理器,可用於監視配置和控制Internet服務。IIS是一種Web服務元件,其中包括Web伺服器、FTP伺服器、NNTP伺服器和SMTP伺服器,分別用於網頁瀏覽、檔案傳輸、新聞服務和郵件傳送等方面,它使得在網路(包括網際網路和區域網)上釋出資訊成了一件很容易的事。它提供ISAPI(Intranet Server API)作為擴充套件Web伺服器功能的程式設計介面;同時,它還提供一個Internet資料庫聯結器,可以實現對資料庫的查詢和更新。
  • Kangle:Kangle Web伺服器是一款跨平臺、功能強大、安全穩定、易操作的高效能Web伺服器和反向代理伺服器軟體。此外,Kangle也是一款專為做虛擬主機研發的Web伺服器。實現虛擬主機獨立程序、獨立身份執行。使用者之間安全隔離,一個使用者出問題不影響其他使用者。支援PHP、ASP、ASP.NET、Java、Ruby等多種動態開發語言。
  • WebSphere:WebSphere Application Server是功能完善、開放的Web應用程式伺服器,是IBM電子商務計劃的核心部分,它是基於Java的應用環境,用於建立、部署和管理Internet和Intranet Web應用程式,適應各種Web應用程式伺服器的需要,範圍從簡單到高階直到企業級。
  • WebLogic:BEA WebLogic Server是一種多功能、基於標準的Web應用伺服器,為企業構建自己的應用提供了堅實的基礎。各種應用開發、部署所有關鍵性的任務,無論是整合各種系統和資料庫,還是提交服務、跨Internet協作,Weblogic都提供了相應的支援。由於它具有全面的功能、對開放標準的遵從性、多層架構、支援基於元件的開發,基於Internet的企業都選擇它來開發、部署最佳的應用。BEA WebLogic Server在使應用伺服器成為企業應用架構的基礎方面一直處於領先地位,為構建整合化的企業級應用提供了穩固的基礎,它們以 Internet的容量和速度,在連網的企業之間共享資訊、提交服務,實現協作自動化。
  • Apache:目前Apache仍然是世界上用得最多的Web伺服器,市場佔有率約為60%左右。世界上很多著名的網站都是Apache的產物,它的成功之處主要在於它的原始碼開放、有一支強大的開發團隊、支援跨平臺的應用(可以執行在幾乎所有的Unix、Windows、Linux系統平臺上)以及它的可移植性等方面。
  • Tomcat:Tomcat是一個開放原始碼、執行Servlet和JSP的容器。TomcatServer實現了Servlet和JSP規範。此外,Tomcat還實現了Apache-Jakarta規範而且比絕大多數商業應用軟體伺服器要好,因此目前也有不少的Web伺服器都選擇了Tomcat。
  • Nginx:讀作"engine x",是一個高效能的HTTP和反向代理伺服器,也是一個IMAP/POP3/SMTP代理伺服器。 Nginx是由Igor Sysoev為俄羅斯訪問量第二的 Rambler.ru站點開發的,第一個公開版本0.1.0釋出於2004年10月4日。其將原始碼以類BSD許可證的形式釋出,因它的穩定性、豐富的功能集、示例配置檔案和低系統資源的消耗而聞名。

 

121、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)。

 

122、JSP中的四種作用域?

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

①page 代表與一個頁面相關的物件和屬性。

②request 代表與Web客戶機發出的一個請求相關的物件和屬性。一個請求可能跨越多個頁面,涉及多個Web 元件;需要在頁面顯示的臨時資料可以置於此作用域

③session代表與某個使用者與伺服器建立的一次會話相關的物件和屬性。跟某個使用者相關的資料應該放在使用者自己的session中

④application代表與整個Web應用程式相關的物件和屬性,它實質上是跨越整個Web應用程式,包括多個頁面、請求和會話的一個全域性作用域。

 

123、如何實現JSP或Servlet的單執行緒模式?

答:

<%@page isThreadSafe=”false”%>
  

【補充】Servlet預設的工作模式是單例項多執行緒,如果Servlet實現了標識介面SingleThreadModel又或是JSP頁面通過page指令設定isThreadSafe屬性為false,那麼它們生成的Java程式碼會以單執行緒多例項方式工作。顯然,這樣做會導致每個請求建立一個Servlet例項,這種實踐將導致嚴重的效能問題。

 

124、實現會話跟蹤的技術有哪些?

答:由於HTTP協議本身是無狀態的,伺服器為了區分不同的使用者,就需要對使用者會話進行跟蹤,簡單的說就是為使用者進行登記,為使用者分配唯一的ID,下一次使用者在請求中包含此ID,伺服器據此判斷到底是哪一個使用者。

①URL 重寫:在URL中新增使用者會話的資訊作為請求的引數,或者將唯一的會話ID新增到URL結尾以標識一個會話。

②設定表單隱藏域:將和會話跟蹤相關的欄位新增到隱式表單域中,這些資訊不會在瀏覽器中顯示但是提交表單時會提交給伺服器。

這兩種方式很難處理跨越多個頁面的資訊傳遞,因為如果每次都要修改URL或在頁面中新增隱式表單域來儲存使用者會話相關資訊,事情將變得非常麻煩。

③cookie:cookie有兩種,一種是基於視窗的,瀏覽器視窗關閉後,cookie就沒有了;另一種是將資訊儲存在一個臨時檔案中,並設定存在的時間。當用戶通過瀏覽器和伺服器建立一次會話後,會話ID就會隨響應資訊返回儲存在基於視窗的cookie中,那就意味著只要瀏覽器沒有關閉,會話沒有超時,下一次請求時這個會話ID又會提交給伺服器讓伺服器識別使用者身份。會話中可以為使用者儲存資訊。會話物件是在伺服器記憶體中的,而基於視窗的cookie是在客戶端記憶體中的。如果瀏覽器禁用了cookie,那麼就需要通過下面兩種方式進行會話跟蹤。當然,在使用cookie時要注意幾點:首先不要在cookie中存放敏感資訊;其次cookie儲存的資料量有限(4k),不能將過多的內容儲存cookie中;再者瀏覽器通常只允許一個站點最多存放20個cookie。當然,和使用者會話相關的其他資訊(除了會話ID)也可以存在cookie方便進行會話跟蹤。

④HttpSession:在所有會話跟蹤技術中,HttpSession物件是最強大也是功能最多的。當一個使用者第一次訪問某個網站時會自動建立HttpSession,每個使用者可以訪問他自己的HttpSession。可以通過HttpServletRequest物件的getSession方法獲得HttpSession,通過HttpSession的setAttribute方法可以將一個值放在HttpSession中,通過呼叫HttpSession物件的getAttribute方法,同時傳入屬性名就可以獲取儲存在HttpSession中的物件。與上面三種方式不同的是,HttpSession放在伺服器的記憶體中,因此不要將過大的物件放在裡面,即使目前的Servlet容器可以在記憶體將滿時將HttpSession中的物件移到其他儲存裝置中,但是這樣勢必影響效能。新增到HttpSession中的值可以是任意Java物件,這個物件最好實現了Serializable介面,這樣Servlet容器在必要的時候可以將其序列化到檔案中,否則在序列化時就會出現異常。

 

126、過濾器有哪些作用和用法?

答: Java Web開發中的過濾器(filter)是從Servlet 2.3規範開始增加的功能,並在Servlet 2.4規範中得到增強。對Web應用來說,過濾器是一個駐留在伺服器端的Web元件,它可以擷取客戶端和伺服器之間的請求與響應資訊,並對這些資訊進行過濾。當Web容器接受到一個對資源的請求時,它將判斷是否有過濾器與這個資源相關聯。如果有,那麼容器將把請求交給過濾器進行處理。在過濾器中,你可以改變請求的內容,或者重新設定請求的報頭資訊,然後再將請求傳送給目標資源。當目標資源對請求作出響應時候,容器同樣會將響應先轉發給過濾器,再過濾器中,你可以對響應的內容進行轉換,然後再將響應傳送到客戶端。

常見的過濾器用途主要包括:對使用者請求進行統一認證、對使用者的訪問請求進行記錄和稽核、對使用者傳送的資料進行過濾或替換、轉換圖象格式、對響應內容進行壓縮以減少傳輸量、對請求或響應進行加解密處理、觸發資源訪問事件、對XML的輸出應用XSLT等。

和過濾器相關的介面主要有:Filter、FilterConfig、FilterChain

編碼過濾器的例子:


  
  1. package com.lovo.filter;
  2. import java.io.IOException;
  3. import javax.servlet.Filter;
  4. import javax.servlet.FilterChain;
  5. import javax.servlet.FilterConfig;
  6. import javax.servlet.ServletException;
  7. import javax.servlet.ServletRequest;
  8. import javax.servlet.ServletResponse;
  9. import javax.servlet.annotation.WebFilter;
  10. import javax.servlet.annotation.WebInitParam;
  11. @WebFilter(urlPatterns = { "*" },
  12. initParams = { @WebInitParam(name= "encoding", value= "utf-8")})
  13. public class CodingFilter implements Filter {
  14. private String defaultEncoding = "utf-8";
  15. @Override
  16. public void destroy() {
  17. }
  18. @Override
  19. public void doFilter(ServletRequest req, ServletResponse resp,
  20. FilterChain chain)