摘要:系列文章請查看超詳細的面試題總結一之基礎知識篇超詳細的面試題總結二之基礎知識篇超詳細的面試題總結三之集合篇常見問題下面的都是自己之前在學習的時候總結的,對于鞏固的基礎知識應該有很大幫助。注意多線程的并發的讀寫類屬性會導致數據不同步。
系列文章請查看:
超詳細的Java面試題總結(一)之Java基礎知識篇
超詳細的Java面試題總結(二)之Java基礎知識篇
超詳細的Java面試題總結(三)之Java集合篇常見問題
下面的都是自己之前在學習JavaWeb的時候總結的,對于鞏固JavaWeb的基礎知識應該有很大幫助。后面還會把框架的面試題總結一下。
Servlet總結:在Java Web程序中,Servlet主要負責接收用戶請求HttpServletRequest,在doGet(),doPost()中做相應的處理,并將回應HttpServletResponse反饋給用戶。Servlet可以設置初始化參數,供Servlet內部使用。一個Servlet類只會有一個實例,在它初始化時調用init()方法,銷毀時調用destroy()方法。Servlet需要在web.xml中配置(MyEclipse中創建Servlet會自動配置),一個Servlet可以設置多個URL訪問。Servlet不是線程安全,因此要謹慎使用類變量。
闡述Servlet和CGI的區別?CGI的不足之處:
1,需要為每個請求啟動一個操作CGI程序的系統進程。如果請求頻繁,這將會帶來很大的開銷。
2,需要為每個請求加載和運行一個CGI程序,這將帶來很大的開銷
3,需要重復編寫處理網絡協議的代碼以及編碼,這些工作都是非常耗時的。
Servlet的優點:
1,只需要啟動一個操作系統進程以及加載一個JVM,大大降低了系統的開銷
2,如果多個請求需要做同樣處理的時候,這時候只需要加載一個類,這也大大降低了開銷
3,所有動態加載的類可以實現對網絡協議以及請求解碼的共享,大大降低了工作量。
4,Servlet能直接和Web服務器交互,而普通的CGI程序不能。Servlet還能在各個程序之間共享數據,使數據庫連接池之類的功能很容易實現。
補充:Sun Microsystems公司在1996年發布Servlet技術就是為了和CGI進行競爭,Servlet是一個特殊的Java程序,一個基于Java的Web應用通常包含一個或多個Servlet類。Servlet不能夠自行創建并執行,它是在Servlet容器中運行的,容器將用戶的請求傳遞給Servlet程序,并將Servlet的響應回傳給用戶。通常一個Servlet會關聯一個或多個JSP頁面。以前CGI經常因為性能開銷上的問題被詬病,然而Fast CGI早就已經解決了CGI效率上的問題,所以面試的時候大可不必信口開河的詬病CGI,事實上有很多你熟悉的網站都使用了CGI技術。
參考:《javaweb整合開發王者歸來》P7
Servlet接口中有哪些方法及Servlet生命周期探秘Servlet接口定義了5個方法,其中前三個方法與Servlet生命周期相關:
void init(ServletConfig config) throws ServletException
void service(ServletRequest req, ServletResponse resp) throws ServletException, java.io.IOException
void destory()
java.lang.String getServletInfo()
ServletConfig getServletConfig()
生命周期: Web容器加載Servlet并將其實例化后,Servlet生命周期開始,容器運行其init()方法進行Servlet的初始化;請求到達時調用Servlet的service()方法,service()方法會根據需要調用與請求對應的doGet或doPost等方法;當服務器關閉或項目被卸載時服務器會將Servlet實例銷毀,此時會調用Servlet的destroy()方法。init方法和destory方法只會執行一次,service方法客戶端每次請求Servlet都會執行。Servlet中有時會用到一些需要初始化與銷毀的資源,因此可以把初始化資源的代碼放入init方法中,銷毀資源的代碼放入destroy方法中,這樣就不需要每次處理客戶端的請求都要初始化與銷毀資源。
參考:《javaweb整合開發王者歸來》P81
get和post請求的區別?①get請求用來從服務器上獲得資源,而post是用來向服務器提交數據;
②get將表單中數據按照name=value的形式,添加到action 所指向的URL 后面,并且兩者使用"?"連接,而各個變量之間使用"&"連接;post是將表單中的數據放在HTTP協議的請求頭或消息體中,傳遞到action所指向URL;
③get傳輸的數據要受到URL長度限制(1024字節即256個字符);而post可以傳輸大量的數據,上傳文件通常要使用post方式;
④使用get時參數會顯示在地址欄上,如果這些數據不是敏感數據,那么可以使用get;對于敏感數據還是應用使用post;
⑤get使用MIME類型application/x-www-form-urlencoded的URL編碼(也叫百分號編碼)文本的格式傳遞參數,保證被傳送的參數由遵循規范的文本組成,例如一個空格的編碼是"%20"。
補充:GET方式提交表單的典型應用是搜索引擎。GET方式就是被設計為查詢用的。
什么情況下調用doGet()和doPost()?Form標簽里的method的屬性為get時調用doGet(),為post時調用doPost()。
轉發(Forward)和重定向(Redirect)的區別?轉發是服務器行為,重定向是客戶端行為。
轉發(Forword)
通過RequestDispatcher對象的forward(HttpServletRequest request,HttpServletResponse response)方法實現的。RequestDispatcher可以通過HttpServletRequest 的getRequestDispatcher()方法獲得。例如下面的代碼就是跳轉到login_success.jsp頁面。
request.getRequestDispatcher("login_success.jsp").forward(request, response);
重定向(Redirect) 是利用服務器返回的狀態嗎來實現的。客戶端瀏覽器請求服務器的時候,服務器會返回一個狀態碼。服務器通過HttpServletRequestResponse的setStatus(int status)方法設置狀態碼。如果服務器返回301或者302,則瀏覽器會到新的網址重新請求該資源。
從地址欄顯示來說
forward是服務器請求資源,服務器直接訪問目標地址的URL,把那個URL的響應內容讀取過來,然后把這些內容再發給瀏覽器.瀏覽器根本不知道服務器發送的內容從哪里來的,所以它的地址欄還是原來的地址.
redirect是服務端根據邏輯,發送一個狀態碼,告訴瀏覽器重新去請求那個地址.所以地址欄顯示的是新的URL.
從數據共享來說
forward:轉發頁面和轉發到的頁面可以共享request里面的數據.
redirect:不能共享數據.
從運用地方來說
forward:一般用于用戶登陸的時候,根據角色轉發到相應的模塊.
redirect:一般用于用戶注銷登陸時返回主頁面和跳轉到其它的網站等
從效率來說
forward:高.
redirect:低.
自動刷新不僅可以實現一段時間之后自動跳轉到另一個頁面,還可以實現一段時間之后自動刷新本頁面。Servlet中通過HttpServletResponse對象設置Header屬性實現自動刷新例如:
Response.setHeader("Refresh","1000;URL=http://localhost:8080/servlet/example.htm");
其中1000為時間,單位為毫秒。URL指定就是要跳轉的頁面(如果設置自己的路徑,就會實現沒過一秒自動刷新本頁面一次)
Servlet與線程安全Servlet不是線程安全的,多線程并發的讀寫會導致數據不同步的問題。 解決的辦法是盡量不要定義name屬性,而是要把name變量分別定義在doGet()和doPost()方法內。雖然使用synchronized(name){}語句塊可以解決問題,但是會造成線程的等待,不是很科學的辦法。
注意:多線程的并發的讀寫Servlet類屬性會導致數據不同步。但是如果只是并發地讀取屬性而不寫入,則不存在數據不同步的問題。因此Servlet里的只讀屬性最好定義為final類型的。
參考:《javaweb整合開發王者歸來》P92
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)。
JSP工作原理:JSP是一種Servlet,但是與HttpServlet的工作方式不太一樣。HttpServlet是先由源代碼編譯為class文件后部署到服務器下,為先編譯后部署。而JSP則是先部署后編譯。JSP會在客戶端第一次請求JSP文件時被編譯為HttpJspPage類(接口Servlet的一個子類)。該類會被服務器臨時存放在服務器工作目錄里面。下面通過實例給大家介紹。
工程JspLoginDemo下有一個名為login.jsp的Jsp文件,把工程第一次部署到服務器上后訪問這個Jsp文件,我們發現這個目錄下多了下圖這兩個東東。
.class文件便是JSP對應的Servlet。編譯完畢后再運行class文件來響應客戶端請求。以后客戶端訪問login.jsp的時候,Tomcat將不再重新編譯JSP文件,而是直接調用class文件來響應客戶端請求。
由于JSP只會在客戶端第一次請求的時候被編譯 ,因此第一次請求JSP時會感覺比較慢,之后就會感覺快很多。如果把服務器保存的class文件刪除,服務器也會重新編譯JSP。
開發Web程序時經常需要修改JSP。Tomcat能夠自動檢測到JSP程序的改動。如果檢測到JSP源代碼發生了改動。Tomcat會在下次客戶端請求JSP時重新編譯JSP,而不需要重啟Tomcat。這種自動檢測功能是默認開啟的,檢測改動會消耗少量的時間,在部署Web應用的時候可以在web.xml中將它關掉。
參考:《javaweb整合開發王者歸來》P97
JSP有哪些內置對象?作用分別是什么?JSP內置對象 - CSDN博客
JSP有9個內置對象:
request:封裝客戶端的請求,其中包含來自GET或POST請求的參數;
response:封裝服務器對客戶端的響應;
pageContext:通過該對象可以獲取其他對象;
session:封裝用戶會話的對象;
application:封裝服務器運行環境的對象;
out:輸出服務器響應的輸出流對象;
config:Web應用的配置對象;
page:JSP頁面本身(相當于Java程序中的this);
exception:封裝頁面拋出異常的對象。
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):刪除請求中的一個屬性
request.getAttribute()和 request.getParameter()有何區別?從獲取方向來看:
getParameter()是獲取 POST/GET 傳遞的參數值;
getAttribute()是獲取對象容器中的數據值;
從用途來看:
getParameter用于客戶端重定向時,即點擊了鏈接或提交按扭時傳值用,即用于在用表單或url重定向傳值時接收數據用。
getAttribute用于服務器端重定向時,即在 sevlet 中使用了 forward 函數,或 struts 中使用了
mapping.findForward。 getAttribute 只能收到程序用 setAttribute 傳過來的值。
另外,可以用 setAttribute,getAttribute 發送接收對象.而 getParameter 顯然只能傳字符串。
setAttribute 是應用服務器把這個對象放在該頁面所對應的一塊內存中去,當你的頁面服務器重定向到另一個頁面時,應用服務器會把這塊內存拷貝另一個頁面所對應的內存中。這樣getAttribute就能取得你所設下的值,當然這種方法可以傳對象。session也一樣,只是對象在內存中的生命周期不一樣而已。getParameter只是應用服務器在分析你送上來的 request頁面的文本時,取得你設在表單或 url 重定向時的值。
總結:
getParameter 返回的是String,用于讀取提交的表單中的值;(獲取之后會根據實際需要轉換為自己需要的相應類型,比如整型,日期類型啊等等)
getAttribute 返回的是Object,需進行轉換,可用setAttribute 設置成任意對象,使用很靈活,可隨時用
include指令include的行為的區別include指令: JSP可以通過include指令來包含其他文件。被包含的文件可以是JSP文件、HTML文件或文本文件。包含的文件就好像是該JSP文件的一部分,會被同時編譯執行。 語法格式如下:
<%@ include file="文件相對 url 地址" %>
include動作:
JSP九大內置對象,七大動作,三大指令總結
講解JSP中的四種作用域JSP中的四種作用域包括page、request、session和application,具體來說:
page代表與一個頁面相關的對象和屬性。
request代表與Web客戶機發出的一個請求相關的對象和屬性。一個請求可能跨越多個頁面,涉及多個Web組件;需要在頁面顯示的臨時數據可以置于此作用域。
session代表與某個用戶與服務器建立的一次會話相關的對象和屬性。跟某個用戶相關的數據應該放在用戶自己的session中。
application代表與整個Web應用程序相關的對象和屬性,它實質上是跨越整個Web應用程序,包括多個頁面、請求和會話的一個全局作用域。
如何實現JSP或Servlet的單線程模式?對于JSP頁面,可以通過page指令進行設置。
<%@page isThreadSafe=”false”%>
對于Servlet,可以讓自定義的Servlet實現SingleThreadModel標識接口。
說明:如果將JSP或Servlet設置成單線程工作模式,會導致每個請求創建一個Servlet實例,這種實踐將導致嚴重的性能問題(服務器的內存壓力很大,還會導致頻繁的垃圾回收),所以通常情況下并不會這么做。
實現會話跟蹤的技術有哪些?使用Cookie
向客戶端發送Cookie
Cookie c =new Cookie("name","value"); //創建Cookie c.setMaxAge(60*60*24); //設置最大時效,此處設置的最大時效為一天 response.addCookie(c); //把Cookie放入到HTTP響應中
從客戶端讀取Cookie
String name ="name"; Cookie[]cookies =request.getCookies(); if(cookies !=null){ for(int i= 0;i優點: 數據可以持久保存,不需要服務器資源,簡單,基于文本的Key-Value
缺點: 大小受到限制,用戶可以禁用Cookie功能,由于保存在本地,有一定的安全風險。
URL 重寫
在URL中添加用戶會話的信息作為請求的參數,或者將唯一的會話ID添加到URL結尾以標識一個會話。
優點: 在Cookie被禁用的時候依然可以使用
缺點: 必須對網站的URL進行編碼,所有頁面必須動態生成,不能用預先記錄下來的URL進行訪問。
3.隱藏的表單域
優點: Cookie被禁時可以使用
缺點: 所有頁面必須是表單提交之后的結果。
HttpSession
在所有會話跟蹤技術中,HttpSession對象是最強大也是功能最多的。當一個用戶第一次訪問某個網站時會自動創建 HttpSession,每個用戶可以訪問他自己的HttpSession。可以通過HttpServletRequest對象的getSession方 法獲得HttpSession,通過HttpSession的setAttribute方法可以將一個值放在HttpSession中,通過調用 HttpSession對象的getAttribute方法,同時傳入屬性名就可以獲取保存在HttpSession中的對象。與上面三種方式不同的 是,HttpSession放在服務器的內存中,因此不要將過大的對象放在里面,即使目前的Servlet容器可以在內存將滿時將HttpSession 中的對象移到其他存儲設備中,但是這樣勢必影響性能。添加到HttpSession中的值可以是任意Java對象,這個對象最好實現了 Serializable接口,這樣Servlet容器在必要的時候可以將其序列化到文件中,否則在序列化時就會出現異常。
Cookie和Session的的區別?由于HTTP協議是無狀態的協議,所以服務端需要記錄用戶的狀態時,就需要用某種機制來識具體的用戶,這個機制就是Session.典型的場景比如購物車,當你點擊下單按鈕時,由于HTTP協議無狀態,所以并不知道是哪個用戶操作的,所以服務端要為特定的用戶創建了特定的Session,用用于標識這個用戶,并且跟蹤用戶,這樣才知道購物車里面有幾本書。這個Session是保存在服務端的,有一個唯一標識。在服務端保存Session的方法很多,內存、數據庫、文件都有。集群的時候也要考慮Session的轉移,在大型的網站,一般會有專門的Session服務器集群,用來保存用戶會話,這個時候 Session 信息都是放在內存的,使用一些緩存服務比如Memcached之類的來放 Session。
思考一下服務端如何識別特定的客戶?這個時候Cookie就登場了。每次HTTP請求的時候,客戶端都會發送相應的Cookie信息到服務端。實際上大多數的應用都是用 Cookie 來實現Session跟蹤的,第一次創建Session的時候,服務端會在HTTP協議中告訴客戶端,需要在 Cookie 里面記錄一個Session ID,以后每次請求把這個會話ID發送到服務器,我就知道你是誰了。有人問,如果客戶端的瀏覽器禁用了 Cookie 怎么辦?一般這種情況下,會使用一種叫做URL重寫的技術來進行會話跟蹤,即每次HTTP交互,URL后面都會被附加上一個諸如 sid=xxxxx 這樣的參數,服務端據此來識別用戶。
Cookie其實還可以用在一些方便用戶的場景下,設想你某次登陸過一個網站,下次登錄的時候不想再次輸入賬號了,怎么辦?這個信息可以寫到Cookie里面,訪問網站的時候,網站頁面的腳本可以讀取這個信息,就自動幫你把用戶名給填了,能夠方便一下用戶。這也是Cookie名稱的由來,給用戶的一點甜頭。所以,總結一下:Session是在服務端保存的一個數據結構,用來跟蹤用戶的狀態,這個數據可以保存在集群、數據庫、文件中;Cookie是客戶端保存用戶信息的一種機制,用來記錄用戶的一些信息,也是實現Session的一種方式。
參考:
https://www.zhihu.com/questio...
《javaweb整合開發王者歸來》P158 Cookie和Session的比較
歡迎關注我的微信公眾號:"Java面試通關手冊"(堅持原創,分享各種Java學習資源,面試題,優質文章,以及企業級Java實戰項目回復關鍵字免費領取)::
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/68957.html
摘要:編程思想第版這本書要常讀,初學者可以快速概覽,中等程序員可以深入看看,老鳥還可以用之回顧的體系。以下視頻整理自慕課網工程師路徑相關免費課程。 我自己總結的Java學習的系統知識點以及面試問題,目前已經開源,會一直完善下去,歡迎建議和指導歡迎Star: https://github.com/Snailclimb/Java-Guide 筆者建議初學者學習Java的方式:看書+視頻+實踐(初...
摘要:哪吒社區技能樹打卡打卡貼函數式接口簡介領域優質創作者哪吒公眾號作者架構師奮斗者掃描主頁左側二維碼,加入群聊,一起學習一起進步歡迎點贊收藏留言前情提要無意間聽到領導們的談話,現在公司的現狀是碼農太多,但能獨立帶隊的人太少,簡而言之,不缺干 ? 哪吒社區Java技能樹打卡?【打卡貼 day2...
摘要:超詳細的面試題總結一之基本知識多線程和虛擬機創建線程有幾種不同的方式你喜歡哪一種為什么繼承類實現接口應用程序可以使用框架來創建線程池實現接口。死亡線程方法執行結束,或者因異常退出了方法,則該線程結束生命周期。死亡的線程不可再次復生。 超詳細的Java面試題總結(一)之Java基本知識 多線程和Java虛擬機 創建線程有幾種不同的方式?你喜歡哪一種?為什么? 繼承Thread類 實現R...
摘要:前言由于寫的文章已經是有點多了,為了自己和大家的檢索方便,于是我就做了這么一個博客導航。 前言 由于寫的文章已經是有點多了,為了自己和大家的檢索方便,于是我就做了這么一個博客導航。 由于更新比較頻繁,因此隔一段時間才會更新目錄導航哦~想要獲取最新原創的技術文章歡迎關注我的公眾號:Java3y Java3y文章目錄導航 Java基礎 泛型就這么簡單 注解就這么簡單 Druid數據庫連接池...
摘要:最近在備戰面試的過程中,整理一下面試題。成員變量如果沒有被賦初值,則會自動以類型的默認值而賦值一種情況例外被修飾但沒有被修飾的成員變量必須顯示地賦值而局部變量則不會自動賦值。 最近在備戰面試的過程中,整理一下面試題。大多數題目都是自己手敲的,網上也有很多這樣的總結。自己感覺總是很亂,所以花了很久把自己覺得重要的東西總結了一下。 面向對象和面向過程的區別 面向過程: 優點:性能比面...
閱讀 3018·2021-10-27 14:15
閱讀 3011·2021-09-07 10:18
閱讀 1328·2019-08-30 15:53
閱讀 1581·2019-08-26 18:18
閱讀 3382·2019-08-26 12:15
閱讀 3467·2019-08-26 10:43
閱讀 659·2019-08-23 16:43
閱讀 2216·2019-08-23 15:27