【前言】別人都在你看不到的地方暗自努力,在你看獲得的地方,他們也和你同樣顯得不務正業,和你同樣會抱怨,而只有你本身相信這些都是真的,最後,也只有你一我的繼續不思進取 …… java
【下載】我的結合諸多資料,總結的一些JavaEE常見面試題,主要針對初/中級程序員。想要word完整版下載的,評論裏留言留下你的郵箱!程序員
1.Struts2中,Action經過什麼方式獲取用戶從頁面輸入的數據,又是經過什麼方法把數據傳給視圖層顯示的?面試
答:(1)Action從頁面獲取數據的方式有三種:sql
①經過Action屬性接收參數;(例:${pageContext.request.contextPath}/***.action? id=xxxx)數據庫
②經過域模型獲取參數;(例:ServletActionContext.getRequest().getParameter(arg0))緩存
③經過模型驅動獲取參數(例:extends ModelDriven<T>)安全
(2)Action將數據存入值棧(Value Stack)中,視圖能夠經過表達式語言(EL)從值棧中獲取;session
2.闡述Struts2中的Action如何編寫,是否採用單例?多線程
答:(1)Struts2的Action有三種寫法:併發
①POJO類——無繼承無實現;
②實現Action接口,重寫execute()方法;
③繼承ActionSupport(經常使用);
(2)Action沒有像Servlet同樣,使用單實例多線程的工做方式,很明顯,每個Action要接收不一樣用戶的請求參數,這就意味着Action是有狀態的,所以在設計上使用了,每個請求對應一個Action的處理方式,因此是多例的。
3.Struts2中,Action並無直接收到用戶的請求,那它爲何能夠處理用戶的請求?又憑什麼知道一個請求到底交給哪個Action來處理?
答:(1)Struts2的核心過濾器收到用戶的請求後,會對用戶的請求進行簡單的預處理(如解析、封裝參數),而後經過反射來建立Action實例,並調用Action中指定的方法來處理用戶請求。
(2)通知具體調用哪一個Action來處理請求的方式,有兩種:
①利用配置文件,Struts.xml中配置的<action>標籤來肯定;
②利用約定,Struts2中可使用約定(convention)插件。例如:約定xxx老是對應XxxAction,這是對約定優於配置理念的踐行;
4.簡述Struts2異常處理機制?
答:Struts2提供了聲明式的異常處理機制,能夠在配置文件中加入以下代碼:
<!-- 配置全局結果視圖 -->
<global-results>
<result name="error">/WEB-INF/pages/error.jsp</result>
</global-results>
<!-- struts2自帶異常處理配置-->
<global-exception-mappings>
<exception-mapping result="error" exception="com.itheima.exception.SysException"></exception-mapping>
<exception-mapping result="error" exception="java.lang.Exception"></exception-mapping>
</global-exception-mappings>
5.簡述攔截器的工做原理?
答:在Struts2中,能夠實現Interceptor接口或繼承AbstractInterceptor類,來自定義攔截器。
①接口中的init()方法,在攔截器被建立後當即被調用,它在攔截器的生命週期內只被調用一次,能夠在該方法中對相關資源進行必要的初始化;
②每攔截一個請求,intercept()方法就會被調用一次;
③destory()方法將在攔截器銷燬以前被調用。
6.談一下攔截器和過濾器的區別?
答:攔截器和過濾器均可以用來實現橫切關注功能,其區別主要在於:
①攔截器是基於JAVA反射機制的,而過濾器是基於函數回調的
②過濾器依賴於Servlet容器,而攔截器不依賴於Servlet容器
③攔截器只能對Action請求起做用(Action中的方法),而過濾器能夠對幾乎全部的請求起做用(CSS JSP JS)
7.談一下你的項目選擇Struts2的理由?
答:①Action是POJO類,沒有依賴Servlet API,具備良好的可測試性;
②強大的攔截器,簡化了開發的複雜度;
③支持多種表現層技術:JSP、Freemarker等;
④靈活的驗證方式;
⑤國際化(I18N)支持
⑥聲明式異常管理;
⑦經過JSON插件簡化Ajax;
⑧經過Spring插件跟Spring整合;
8.Struts2中如何訪問HttpServletRequest、HttpSession和ServletContext三個域對象?
答:有兩種方式:
①經過ServletActionContext的方法得到;
②經過ServletRequestAware、SessionAware和ServletContextAware接口注入。
9.Struts2中的默認包struts-default有什麼做用?
答:它定義了Struts2內部的衆多攔截器和Result類型,而Struts2不少核心的功能是經過這些內置的攔截器實現,如:從請求中把參數封裝到action、文件上傳和數據校驗等等,都是經過攔截器實現的。在Struts2的配置文件中,自定義的包,繼承了struts-default包,就可使用Struts2爲咱們提供這些功能。
10.簡述值棧的原理和生命週期?
答:Value-Stack貫穿整個Action的生命週期,保存在request做用域中,因此它和request的生命週期同樣。當Struts2接受一個請求時,會建立ActionContext、Value-Stack和Action對象,而後把Action存放進Value-Stack,因此Action的實例變量能夠經過OGNL訪問。因爲Action是多實例的,和使用單例的Servlet不一樣,每一個Action都有一個對應的Value-Stack,Value-Stack存放的數據類型是該Action的實例,以及該Action中的實例變量,Action對象默認保存在棧頂。
11.SessionFactory是線程安全的嗎?Session是線程安全的嗎?兩個線程能共享一個Session嗎?
答:(1)SessionFactory對應Hibernate的一個數據存儲的概念,它是線程安全的,能夠被多個線程併發訪問。SessionFactory通常只會在啓動的時候構建。對於應用程序,最好將SessionFactory經過單例的模式進行封裝以便於訪問。
(2)Session是一個輕量級非線程安全的對象(線程間不能共享Session),它表示與數據庫進行交互的一個工做單元。Session是由SessionFactory建立的,在任務完成以後會被關閉。Session是持久層服務對外提供的主要接口。Session會延遲獲取數據庫鏈接(也就是在須要的時候纔會獲取)。爲了不建立太多的session,可使用TreadLocal來獲取當前的session,不管你調用多少次getCurrentSession()方法,返回的都是同一個session。
12.Session的load和get方法區別是什麼?
答:①若是沒有找到符合條件的記錄,get方法返回null值,而load方法會拋出異常;
②get方法直接返回實體類對象,load方法返回實體類對象的代理;
③在Hibernate3以前,get方法只在一級緩存(內部緩存)中進行數據查找,若是沒有找到對應的數據則越過二級緩存,直接發出SQL語句完成數據的讀取;load方法則能夠充分利用二級緩存中現有數據,進行延遲加載。固然從Hibernate3開始,get方法再也不是對二級緩存只寫不讀,它也是能夠訪問二級緩存的;
簡單的是,對於load()方法,hibernate認爲該數據在數據庫中必定存在,能夠放心的使用代理來實現延遲加載,若是沒有數據,就會拋出異常,而經過get()方法去取數據,是能夠不存在的。
13.闡述Session加載實體對象的過程?
答:①Session在調用數據查詢功能以前,首先會在緩存中進行查詢,在一級緩存中,經過實體類型和主鍵進行查詢,若是一級緩存查找命中且數據狀態合法,則直接返回;
②若是一級緩存沒有命中,接下來Session會在當前NonExists記錄(至關於一個查詢黑名單,若是出現重複的無效查詢能夠迅速判斷,從而提高性能)中進行查詢,若是NonExists中存在一樣的查詢條件,則返回null;
③對於load方法,若是一級緩存查詢失敗,則查詢二級緩存,若是二級緩存命中則直接返回;
④若是以前的查詢都未命中,則發出sql語句,若是查詢未發現對應的記錄,則這次查詢添加到Session的NonExists中加以記錄,並返回null;
⑤根據映射配置和sql語句,獲得ResultSet,並建立對應的實體對象;
⑥將對象歸入Session(一級緩存)管理;
⑦執行攔截器的onload方法(若是有對應的攔截器);
⑧將數據對象歸入二級緩存;
⑨返回數據對象。
14.Query接口的list方法和iterate方法有什麼區別?
答:①list()方法返回的每一個對象都是完整的(對象中的每一個屬性都被表中的字段填充上了),list方法沒法利用緩存,它對一級緩存只寫不讀;
②iterate方法能夠充分利用一級緩存,它所返回的對象中僅包含了主鍵值(標識符),只有當你對iterator中的對象進行操做時,Hibernate纔會向數據庫再次發送SQL語句來獲取該對象的屬性值;
②list方法不會引發N+1查詢問題,而iterate方法會引發N+1查詢問題。
15.Hibernate如何實現分頁查詢?
答:經過Hibernate實現分頁查詢,開發人員只須要提供HQL語句、查詢起始行數(setFirstResult()方法)和最大查詢行數(setMaxResult()方法),並調用Query接口的list()方法,Hibernate會自動生成分頁查詢的SQL語句。