HttpMessageConveter: 將請求消息(如Json、xml等數據)轉換成一個對象,將對象轉換爲指定的響應信息。 數據轉換:對請求消息進行數據轉換。如String轉換成Integer、Double等。 數據根式化:對請求消息進行數據格式化。 如將字符串轉換成格式化數字或格式化日期等。 數據驗證: 驗證數據的有效性(長度、格式等),驗證結果存儲到BindingResult或Error中。
晚上八點多本身在看視頻的時候忽然接到杭州來的一個電話,當時以爲很奇怪,突兀,接通以後被告知是杭州網易打來的,沒有簡單的自我介紹,沒有多餘的廢話,直接入主題,嚇得我內心怪緊張的,徹底沒有準備,可是也沒有辦法,仍是得硬上!前端
一、項目結構。java
沒有緩和的時間,面試官直接問我簡歷上某個項目的狀況,簡要的說了下算是緩解心情,問了下使用的相關的技術,好比用了spring mvc框架沒 數據庫是用的什麼 這些可能就是面試官給的緩和時間吧,可是,我是這樣越緩和越緊張了,悲催。。。面試
二、用過mybatis沒?由於沒怎麼用過,因此面試官就沒怎麼問了。。。spring
三、集合框架hashtable、hashmap、list、list初始化大小、hashmap自動增加sql
答:一開始是直接問了解經常使用的集合框架麼,這個一聽到確定說了解咯,因而就讓說說hashtable、hashmap、list的區別,因此就大體展開說了下:數據庫
ArrayList和Vector的區別: 編程
共同點:這兩個類都實現了List接口(List接口繼承了Collection接口),他們都是有序集合,即存儲在這兩個集合中的元素的位置都是有順序的,至關於一種動態的數組,咱們之後能夠按位置索引號取出某個元素,而且其中的數據是容許重複的,這是與HashSet之類的集合的最大不一樣處,HashSet之類的集合不能夠按索引號去檢索其中的元素,也不容許有重複的元素。
接着說ArrayList與Vector的區別,這主要包括兩個方面:.
同步性:Vector是線程安全的,也就是說是它的方法之間是線程同步的,而ArrayList是線程序不安全的,它的方法之間是線程不一樣步的。若是隻有一個線程會訪問到集合,那最好是使用ArrayList,由於它不考慮線程安全,效率會高些;若是有多個線程會訪問到集合,那最好是使用Vector,由於不須要咱們本身再去考慮和編寫線程安全的代碼。
注意:這裏談到線程安全,同步問題,面試官少不了會多嘴說一句,讓你講講線程安全是咋回事,若是不考慮,你聽到這個問題估計會是一臉懵逼,我當初就是這樣子的!因此這裏我補充下線程安全的問題: java中的線程安全就是線程同步的意思,就是當一個程序對一個線程安全的方法或者變量進行訪問的時候,其餘的程序不能再對他進行操做了,必須等到此次訪問結束之後才能對這個線程安全的方法進行訪問,不然將會形成錯誤發生;線程安全就是說,若是你的代碼所在的進程中有多個線程在同時運行,而這些線程可能會同時運行這段代碼。若是每次運行結果和單線程運行的結果是同樣的,並且其餘的變量的值也和預期的是同樣的,就是線程安全的。 線程安全問題都是由全局變量及靜態變量引發的,定義在方法內部的局部私有變量是沒有線程安全與否一說的。
備註:對於Vector&ArrayList、Hashtable&HashMap,要記住線程安全的問題,記住Vector與Hashtable是舊的,是java一誕生就提供了的,它們是線程安全的,ArrayList與HashMap是java2時才提供的,它們是線程不安全的。因此,咱們講課時先講老的。
數據增加:ArrayList與Vector都有一個初始的容量大小,當存儲進它們裏面的元素的個數超過了容量時,就須要增長ArrayList與Vector的存儲空間,每次要增長存儲空間時,不是隻增長一個存儲單元,而是增長多個存儲單元,每次增長的存儲單元的個數在內存空間利用與程序效率之間要取得必定的平衡。Vector默認增加爲原來兩倍,而ArrayList的增加策略在文檔中沒有明確規定(從源代碼看到的是增加爲原來的1.5倍)。ArrayList與Vector均可以設置初始的空間大小,Vector還能夠設置增加的空間大小,而ArrayList沒有提供設置增加空間的方法。
總結:即Vector增加原來的一倍,ArrayList增長原來的0.5倍。 PS:由於在上面講區別的時候提到了自動增加的問題,因此面試官順帶問了句,hashmap自動增加爲多少,這個問題說實話,本身沒有關注過,平時也沒注意過,因此只能老實的說不知道咯,面後網上查了下,不肯定是否正確,有說1.6版本的是增加2倍!數組
ArrayList,Vector, LinkedList的存儲性能和特性:
ArrayList和Vector都是使用數組方式存儲數據,此數組元素數大於實際存儲的數據以便增長和插入元素,它們都容許直接按序號索引元素,可是插入元素要涉及數組元素移動等內存操做,因此索引數據快而插入數據慢,Vector因爲使用了synchronized方法(線程安全),一般性能上較ArrayList差,而LinkedList使用雙向鏈表實現存儲,按序號索引數據須要進行前向或後向遍歷,可是插入數據時只須要記錄本項的先後項便可,因此插入速度較快。LinkedList也是線程不安全的,LinkedList提供了一些方法,使得LinkedList能夠被看成堆棧和隊列來使用。
List和Map的區別:
一個是存儲單列數據的集合,另外一個是存儲鍵和值這樣的雙列數據的集合,List中存儲的數據是有順序,而且容許重複;Map中存儲的數據是沒有順序的,其鍵(key)是不能重複的,它的值(value)是能夠有重複的,存值採用 put(key,value)。Map中取值:value=m.get(key)(這個面試官常問,雖然不難,但也得注意)
HashMap和Hashtable的區別:
HashMap把Hashtable的contains方法去掉了,改爲containsvalue和containsKey。由於contains方法容易讓人引發誤解。
一.歷史緣由:Hashtable是基於陳舊的Dictionary類的,HashMap是Java 1.2引進的Map接口的一個實現
二.同步性:Hashtable是線程安全的,也就是說是同步的,而HashMap是線程序不安全的,不是同步的
三.值:只有HashMap可讓你將空值做爲一個表的條目的key或value,即HashMap容許將null做爲一個entry的key或者value,而Hashtable不容許。安全
PS:最後面試官有問到list初始化大小爲多少,也就是說默認是多少,這個其實問的是 List list = new ArrayList() 這裏初始化 數組的大小是多少,根據源碼咱們知道,默認大小爲10.服務器
四、多線程 wait()sleep()
答:聊到多線程,大體先問了多線程的實現方式,這個問題不用多說,很簡單,java提供了兩種方式,一個是繼承Thread類,另外一個是實現Runnable接口,因爲java不支持多繼承,因此在多繼承的時候,咱們得優先選用 實現 Runnable接口,由於咱們能夠經過實現接口的辦法,間接的實現多繼承!【問了實現方式以後面試官又問了這兩種方法的使用】,其次問到了wait()和sleep()的區別,這兩個方法區別在於:sleep()是Thread類的,而wait()是Object類的,sleep是睡眠,指定時間後線程會繼續執行,不放棄對cpu資源的佔用(即不放棄對象鎖),至關於暫停指定t,wait()是等待,須要喚醒,它會釋放對cpu資源的佔用(即會放棄對象鎖),調用notify()和notifyAll()喚醒。
五、spring mvc框架結構 spring過濾器、登陸過濾 spring mvc分層 spring註解
答:首先問到的是spring mvc框架,讓我講下其組成及功能,因爲當時思路有點凌亂,我主動提出這個問題留到最後講!接下來面試官問了,spring過濾器,就簡單問了下我通常用過濾器作什麼,我回答通常處理字符以及編碼,顯然這不是面試官要的結果,因而面試官提示,加入你在作一個登錄註冊系統,怎麼用過濾器來驗證是否匹配,我直接脫口而出查數據庫啦,說完後本身都笑了,至於最後要問的是什麼這裏我好想也忘了,好想提到什麼controller 我說是的,而後應該沒答錯了,接下來就問到了spring的註解問題,說本身經常使用的註解有哪些,這裏我大體講了一些,總結摘錄以下:
Spring自帶依賴注入註解
1 @Required:依賴檢查;
2 @Autowired:自動裝配2 自動裝配,用於替代基於XML配置的自動裝配 基於@Autowired的自動裝配,默認是根據類型注入,能夠用於構造器、字段、方法注入
3 @Value:注入SpEL表達式 用於注入SpEL表達式,能夠放置在字段方法或參數上
@Value(value = "SpEL表達式")
@Value(value = "#{message}")
4 @Qualifier:限定描述符,用於細粒度選擇候選者
@Qualifier限定描述符除了能根據名字進行注入,但能進行更細粒度的控制如何選擇候選者
@Qualifier(value = "限定標識符")
JSR-250註解
1 @Resource:自動裝配,默認根據類型裝配,若是指定name屬性將根據名字裝配,可使用以下方式來指定
@Resource(name = "標識符")
字段或setter方法
2 @PostConstruct和PreDestroy:經過註解指定初始化和銷燬方法定義
JSR-330註解
1 @Inject:等價於默認的@Autowired,只是沒有required屬性
2 @Named:指定Bean名字,對應於Spring自帶@Qualifier中的缺省的根據Bean名字注入狀況
3 @Qualifier:只對應於Spring自帶@Qualifier中的擴展@Qualifier限定描述符註解,即只能擴展使用,沒有value屬性
JPA註解
@PersistenceContext
@PersistenceUnit用於注入EntityManagerFactory和EntityManager
具體這裏不詳細展開,你們能夠參考一些專門針對註解的文章!
好了,接下來就提到spring mvc的分層了,總結以下:
使用Java spring進行MVC模式開發時,每每將數據模型分爲兩部分,即DAO(Data Access Object,數據訪問對象)和Service(業務邏輯模型)。在第2步中,控制器向模型請求數據時,並非直接向DAO請求數據,而是經過Service向DAO請求數據。這樣作的好處是,能夠將業務邏輯與數據庫訪問獨立開,爲未來系統更換數據保存介質(如目前系統使用文件系統存儲數據,未來能夠更換爲使用數據庫存儲,又或者是如今使用了MSSQL存儲數據,未來更換爲MySQL等)提供了很大的靈活性。控制器只須要調用Service接口中的方法獲取或是處理數據,Service層對控制器傳入的數據進行業務邏輯處理封裝後,傳給DAO層,由DAO層負責將處理後的數據寫入數據庫中。在Service層使用了抽象工廠模式來實現Service層與DAO層的低耦合,Service層並不知道DAO層是如何實現的,實際上也不須要知道系統使用了哪一種數據庫或是文件系統。
action(控制器)、Dao(數據訪問層)、Service(業務邏輯)!view層(視圖 jsp之類的)!
最後就得言歸正傳了,回到spring mvc框架的結構上來,大概是照着下面總結的:
核心容器 核心容器提供 Spring 框架的基本功能。核心容器的主要組件是 BeanFactory,它是工廠模式的實現。BeanFactory 使用控制反轉 (IOC) 模式將應用程序的配置和依賴性規範與實際的應用程序代碼分開。
Spring 上下文 Spring 上下文是一個配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企業服務,例如 JNDI、EJB、電子郵件、國際化、校驗和調度功能。
Spring AOP 經過配置管理特性,Spring AOP 模塊直接將面向方面的編程功能集成到了Spring 框架中。因此,能夠很容易地使 Spring 框架管理的任何對象支持 AOP。Spring AOP 模塊爲基於 Spring 的應用程序中的對象提供了事務管理服務。經過使用 Spring AOP,不用依賴 EJB 組件,就能夠將聲明性事務管理集成到應用程序中。
Spring DAO JDBC DAO 抽象層提供了有意義的異常層次結構,可用該結構來管理異常處理和不一樣數據庫供應商拋出的錯誤消息。異常層次結構簡化了錯誤處理,而且極大地下降了須要編寫的異常代碼數量(例如打開和關閉鏈接)。Spring DAO 的面向 JDBC 的異常聽從通用的 DAO 異常層次結構。
Spring ORM Spring 框架插入了若干個 ORM 框架,從而提供了 ORM 的對象關係工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。全部這些都聽從 Spring 的通用事務和 DAO 異常層次結構。
Spring Web 模塊 Web 上下文模塊創建在應用程序上下文模塊之上,爲基於 Web 的應用程序提供了上下文。因此,Spring 框架支持與 Jakarta Struts 的集成。Web 模塊還簡化了處理多部分請求以及將請求參數綁定到域對象的工做。
Spring MVC 框架 MVC 框架是一個全功能的構建 Web 應用程序的 MVC 實現。經過策略接口,MVC 框架變成爲高度可配置的,MVC 容納了大量視圖技術,其中包括 JSP、Velocity、Tiles、iText 和 POI。
Spring 框架的功能能夠用在任何 J2EE 服務器中,大多數功能也適用於不受管理的環境。Spring 的核心要點是:支持不綁定到特定 J2EE 服務的可重用業務和數據訪問對象。毫無疑問,這樣的對象能夠在不一樣 J2EE 環境 (Web 或 EJB)、獨立應用程序、測試環境之間重用。
向服務器發送HTTP請求,請求被前端控制器 DispatcherServlet 捕獲。
DispatcherServlet 根據 <servlet-name>-servlet.xml 中的配置對請求的URL進行解析,獲得請求資源標識符(URI)。 而後根據該URI,調用 HandlerMapping 得到該Handler配置的全部相關的對象(包括Handler對象以及Handler對象對應的攔截器),最後以 HandlerExecutionChain 對象的形式返回。
DispatcherServlet 根據得到的Handler,選擇一個合適的 HandlerAdapter。(附註:若是成功得到HandlerAdapter後,此時將開始執行攔截器的preHandler(…)方法)。
提取Request中的模型數據,填充Handler入參,開始執行Handler(Controller)。 在填充Handler的入參過程當中,根據你的配置,Spring將幫你作一些額外的工做:
HttpMessageConveter: 將請求消息(如Json、xml等數據)轉換成一個對象,將對象轉換爲指定的響應信息。 數據轉換:對請求消息進行數據轉換。如String轉換成Integer、Double等。 數據根式化:對請求消息進行數據格式化。 如將字符串轉換成格式化數字或格式化日期等。 數據驗證: 驗證數據的有效性(長度、格式等),驗證結果存儲到BindingResult或Error中。
Handler(Controller)執行完成後,向 DispatcherServlet 返回一個 ModelAndView 對象;
根據返回的ModelAndView,選擇一個適合的 ViewResolver(必須是已經註冊到Spring容器中的ViewResolver)返回給DispatcherServlet。
ViewResolver 結合Model和View,來渲染視圖。
視圖負責將渲染結果返回給客戶端。
六、連表查詢方法、笛卡爾積經過什麼鏈接獲得 sql對‘a’,‘b’,‘c’,‘d’排序,排成本身指定的順序
答:連表查詢方法,我大體說了三個,引入以前的答案:說句實在話,自從辭職讀研以來好久沒有用過sql語句了,關於這幾個鏈接光靠記憶的話,徹底會是懵逼,幸好本身還不算蠢,很天然的根據字面理解,我很好的回答了出來,left join就是返回包括左表中全部記錄和右表中聯結字段相等的記錄,好了面試官會問你,那麼若是A表中,有甲丙丁3條記錄,B表中有甲乙丙丁4條記錄,那麼若是條件都知足的狀況,A left join B 丙記錄是否會被查出,答案是否認的!好了,right join就是和left join 相反的,inner join等值聯結 只返回2表中聯結字段相等的行!講到這裏我就戛然而止,多是面試官以爲我回答的還不夠全面,因此又提醒我那麼笛卡爾積怎麼實現的,我想了想,忽然腦子中冒出了個Cross join,因而脫口而出,交叉鏈接,而後面試官嗯了下,因而接着往下走問我通常用什麼排序,我就回答,order by啦,而後就是提了下 desc 和ASC的含義,一個降序一個升序沒什麼好說的,最後話鋒一轉,問我,給我 a b c d 四個字符讓我按照自定義的方式排序怎麼實現,好比排序成 b a c d 我實話實說不知道。。。
七、分佈式
最後一個問題是問我瞭解分佈式不,我說稍微看了下,不怎麼了解,這段時間正打算看看。。。
PS:spring mvc模塊及功能是最後回答的,因此回答完這些,面試官讓我本身提了些問題,隨便問了些,就是後悔沒用問我那幾個沒答出來的題目,原本是要問的,最後居然忘了!。。。。
2017年2月22日22:44:18總結 by小仇哥