【JAVA秒會技術之秒殺面試官】JavaEE常見面試題(一)
阿新 • • 發佈:2018-08-21
parameter 和數 程序 配置 except 查詢 解析 list 就會 1.Struts2中,Action通過什麽方式獲取用戶從頁面輸入的數據,又是通過什麽方法把數據傳給視圖層顯示的?
/WEB-INF/pages/error.jsp
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語句。
答:(1)Action從頁面獲取數據的方式有三種:
①通過Action屬性接收參數;(例:${pageContext.request.contextPath}/***.action? id=xxxx) ②通過域模型獲取參數;(例:ServletActionContext.getRequest().getParameter(arg0)) ③通過模型驅動獲取參數(例:extends ModelDriven<T>) (2)Action將數據存入值棧(Value Stack)中,視圖可以通過表達式語言(EL)從值棧中獲取;
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提供了聲明式的異常處理機制,可以在配置文件中加入如下代碼:
【JAVA秒會技術之秒殺面試官】JavaEE常見面試題(一)