天天看點

JAVA常用面試題總結

JAVA常用面試題總結

一、SpringMVC運作原理

SpringMVC運作原理

1. 用戶端請求送出到DispatcherServlet

2. 由DispatcherServlet控制器查詢一個或多個HandlerMapping,找到處理請求的Controller

3. DispatcherServlet将請求送出到Controller

4. Controller調用業務邏輯處理後,傳回ModelAndView

5. DispatcherServlet查詢一個或多個ViewResoler視圖解析器,找到ModelAndView指定的視圖

6. 視圖負責将結果顯示到用戶端

相關接口解釋

DispatcherServlet接口:

Spring提供的前端控制器,所有的請求都有經過它來統一分發。在DispatcherServlet将請求分發給Spring Controller之前,需要借助于Spring提供的HandlerMapping定位到具體的Controller。

HandlerMapping接口:

能夠完成客戶請求到Controller映射。

Controller接口:

需要為并發使用者處理上述請求,是以實作Controller接口時,必須保證線程安全并且可重用。

Controller将處理使用者請求,這和Struts Action扮演的角色是一緻的。一旦Controller處理完使用者請求,則傳回ModelAndView對象給DispatcherServlet前端控制器,ModelAndView中包含了模型(Model)和視圖(View)。

從宏觀角度考慮,DispatcherServlet是整個Web應用的控制器;從微觀考慮,Controller是單個Http請求處理過程中的控制器,而ModelAndView是Http請求過程中傳回的模型(Model)和視圖(View)。

ViewResolver接口:

Spring提供的視圖解析器(ViewResolver)在Web應用中查找View對象,進而将相應結果渲染給客戶。

DispatcherServlet是整個Spring MVC的核心。它負責接收HTTP請求組織協調Spring MVC的各個組成部分。其主要工作有以下三項:

1. 截獲符合特定格式的URL請求。

2. 初始化DispatcherServlet上下文對應的WebApplicationContext,并将其與業務層、持久化層的WebApplicationContext建立關聯。

3. 初始化Spring MVC的各個組成元件,并裝配到DispatcherServlet中。

二、spring架構

spring是J2EE應用程式架構,是輕量級的IoC和AOP的容器架構,主要是針對javaBean的生命周期進行管理的輕量級容器,可以單獨使用,也可以和Struts架構,ibatis架構等組合使用。

1)IoC(Inversion of Control)控制反轉,對象建立責任的反轉,在spring中BeanFacotory是IoC容器的核心接口,負責執行個體化,定位,配置應用程式中的對象及建立這些對象間的依賴。XmlBeanFacotory實作BeanFactory接口,通過擷取xml配置檔案資料,組成應用對象及對象間的依賴關系。

spring中有三種注入方式,一種是set注入,一種是接口注入,另一種是構造方法注入。 

2)AOP面向切面程式設計

aop就是縱向的程式設計,如下圖所示,業務1和業務2都需要一個共同的操作,與其往每個業務中都添加同樣的代碼,不如寫一遍代碼,讓兩個業務共同使用這段代碼。

 spring中面向切面變成的實作有兩種方式,一種是動态代理,一種是CGLIB,動态代理必須要提供接口,而CGLIB實作是有繼承。

架構優點

輕量級的容器架構沒有侵入性

使用IoC容器更加容易組合對象直接間關系,面向接口程式設計,降低耦合

Aop可以更加容易的進行功能擴充,遵循ocp開發原則

建立對象預設是單例的,不需要再使用單例模式進行處理 

5,缺點:業務功能依賴spring特有的功能,依賴與spring環境。

三、常用的設計模式

       1.單例模式(有的書上說叫單态模式其實都一樣)

該模式主要目的是使記憶體中保持1個對象。

       2.工廠模式

該模式主要功能是統一提供執行個體對象的引用。

       3.門面模式

這個模式個人感覺像是Service層的一個翻版。比如Dao我們定義了很多持久化方法,我們通過Service層将Dao的原子方法組成業務邏輯,再通過方法向上層提供服務。門面模式道理其實是一樣的。

       4.政策模式

這個模式是将行為的抽象,即當有幾個類有相似的方法,将其中通用的部分都提取出來,進而使擴充更容易。

四、Hibernate與MyBatis的對比總結

兩者相同點

Hibernate與MyBatis都可以是通過SessionFactoryBuider由XML配置檔案生成SessionFactory,然後由SessionFactory 生成Session,最後由Session來開啟執行事務和SQL語句。其中SessionFactoryBuider,SessionFactory,Session的生命周期都是差不多的。

Hibernate和MyBatis都支援JDBC和JTA事務處理。

Mybatis優勢

MyBatis可以進行更為細緻的SQL優化,可以減少查詢字段。

MyBatis容易掌握,而Hibernate門檻較高。

Hibernate優勢

Hibernate的DAO層開發比MyBatis簡單,Mybatis需要維護SQL和結果映射。

Hibernate對對象的維護和緩存要比MyBatis好,對增删改查的對象的維護要友善。

Hibernate資料庫移植性很好,MyBatis的資料庫移植性不好,不同的資料庫需要寫不同SQL。

Hibernate有更好的二級緩存機制,可以使用第三方緩存。MyBatis本身提供的緩存機制不佳。

以下為詳細介紹:

       Hibernate是目前最流行的O/R mapping架構,它出身于sf.net,現在已經成為Jboss的一部分。 Mybatis 是另外一種優秀的O/R mapping架構。目前屬于apache的一個子項目。

   1.Hibernate對資料庫結構提供了較為完整的封裝,Hibernate的O/R Mapping實作了POJO 和資料庫表之間的映射,以及SQL 的自動生成和執行。程式員往往隻需定義好了POJO 到資料庫表的映射關系,即可通過Hibernate 提供的方法完成持久層操作。程式員甚至不需要對SQL 的熟練掌握, Hibernate/OJB 會根據制定的存儲邏輯,自動生成對應的SQL 并調用JDBC 接口加以執行。

       2.iBATIS的着力點,則在于POJO 與SQL之間的映射關系。然後通過映射配置檔案,将SQL所需的參數,以及傳回的結果字段映射到指定POJO。 相對Hibernate“O/R”而言,iBATIS 是一種“Sql Mapping”的ORM實作。

       4.開發速度

Hibernate的真正掌握要比Mybatis來得難些。Mybatis架構相對簡單很容易上手,但也相對簡陋些。個人覺得要用好Mybatis還是首先要先了解好Hibernate。

       5.開發社群

Hibernate 與Mybatis都是流行的持久層開發架構,但Hibernate開發社群相對多熱鬧些,支援的工具也多,更新也快,目前最高版本4.1.8。而Mybatis相對平靜,工具較少,目前最高版本3.2。

       6.開發工作量

Hibernate和MyBatis都有相應的代碼生成工具。可以生成簡單基本的DAO層方法。

針對進階查詢,Mybatis需要手動編寫SQL語句,以及ResultMap。而Hibernate有良好的映射機制,開發者無需關心SQL的生成與結果映射,可以更專注于業務流程。

       7.系統調優對比

Hibernate的調優方案

制定合理的緩存政策;

盡量使用延遲加載特性;

采用合理的Session管理機制;

使用批量抓取,設定合理的批處理參數(batch_size);

進行合理的O/R映射設計

Mybatis調優方案

MyBatis在Session方面和Hibernate的Session生命周期是一緻的,同樣需要合理的Session管理機制。MyBatis同樣具有二級緩存機制。 MyBatis可以進行詳細的SQL優化設計。

       8.SQL優化方面

Hibernate的查詢會将表中的所有字段查詢出來,這一點會有性能消耗。Hibernate也可以自己寫SQL來指定需要查詢的字段,但這樣就破壞了Hibernate開發的簡潔性。而Mybatis的SQL是手動編寫的,是以可以按需求指定查詢的字段。

Hibernate HQL語句的調優需要将SQL列印出來,而Hibernate的SQL被很多人嫌棄因為太醜了。MyBatis的SQL是自己手動寫的是以調整友善。但Hibernate具有自己的日志統計。Mybatis本身不帶日志統計,使用Log4j進行日志記錄。

       9.擴充性方面

Hibernate與具體資料庫的關聯隻需在XML檔案中配置即可,所有的HQL語句與具體使用的資料庫無關,移植性很好。MyBatis項目中所有的SQL語句都是依賴所用的資料庫的,是以不同資料庫類型的支援不好。

       10.對象管理與抓取政策

Hibernate 是完整的對象/關系映射解決方案,它提供了對象狀态管理(state management)的功能,使開發者不再需要理會底層資料庫系統的細節。也就是說,相對于常見的 JDBC/SQL 持久層方案中需要管理 SQL 語句,Hibernate采用了更自然的面向對象的視角來持久化 Java 應用中的資料。換句話說,使用 Hibernate 的開發者應該總是關注對象的狀态(state),不必考慮 SQL 語句的執行。這部分細節已經由 Hibernate 掌管妥當,隻有開發者在進行系統性能調優的時候才需要進行了解。

而MyBatis在這一塊沒有文檔說明,使用者需要對對象自己進行詳細的管理。

抓取政策

Hibernate對實體關聯對象的抓取有着良好的機制。對于每一個關聯關系都可以詳細地設定是否延遲加載,并且提供關聯抓取、查詢抓取、子查詢抓取、批量抓取四種模式。它是詳細配置和處理的。

而Mybatis的延遲加載是全局配置的。

       10緩存機制對比

Hibernate緩存

Hibernate一級緩存是Session緩存,利用好一級緩存就需要對Session的生命周期進行管理好。建議在一個Action操作中使用一個Session。一級緩存需要對Session進行嚴格管理。

Hibernate二級緩存是SessionFactory級的緩存。 SessionFactory的緩存分為内置緩存和外置緩存。内置緩存中存放的是SessionFactory對象的一些集合屬性包含的資料(映射元素據及預定SQL語句等),對于應用程式來說,它是隻讀的。外置緩存中存放的是資料庫資料的副本,其作用和一級緩存類似.二級緩存除了以記憶體作為存儲媒體外,還可以選用硬碟等外部儲存設備。二級緩存稱為程序級緩存或SessionFactory級緩存,它可以被所有session共享,它的生命周期伴随着SessionFactory的生命周期存在和消亡。

MyBatis緩存

MyBatis 包含一個非常強大的查詢緩存特性,它可以非常友善地配置和定制。MyBatis 3 中的緩存實作的很多改進都已經實作了,使得它更加強大而且易于配置。

預設情況下是沒有開啟緩存的,除了局部的session 緩存,可以增強變現而且處理循環 依賴也是必須的。要開啟二級緩存,你需要在你的 SQL 映射檔案中添加一行:  <cache/>

相同點

Hibernate和Mybatis的二級緩存除了采用系統預設的緩存機制外,都可以通過實作你自己的緩存或為其他第三方緩存方案,建立擴充卡來完全覆寫緩存行為。

不同點

Hibernate的二級緩存配置在SessionFactory生成的配置檔案中進行詳細配置,然後再在具體的表-對象映射中配置是哪種緩存。

MyBatis的二級緩存配置都是在每個具體的表-對象映射中進行詳細配置,這樣針對不同的表可以自定義不同的緩存機制。并且Mybatis可以在命名空間中共享相同的緩存配置和執行個體,通過Cache-ref來實作。

兩者比較

因為Hibernate對查詢對象有着良好的管理機制,使用者無需關心SQL。是以在使用二級緩存時如果出現髒資料,系統會報出錯誤并提示。

而MyBatis在這一方面,使用二級緩存時需要特别小心。如果不能完全确定資料更新操作的波及範圍,避免Cache的盲目使用。否則,髒資料的出現會給系統的正常運作帶來很大的隐患。

五、EJB的幾種類型

會話(Session)Bean ,實體(Entity)Bean 消息驅動的(MessageDriven)Bean

  會話Bean又可分為有狀态(Stateful)和無狀态(Stateless)兩種

  實體Bean可分為Bean管理的持續性(BMP)和容器管理的持續性(CMP)兩種

       一 Ejb的組成 

             标準的Ejb至少由三個部分組成:Local接口,Remote接口以及Ejb Instance。 

       二 Local接口 

             1.Local接口,稱為Home接口,繼.承接基類javax.ejb.Local.從Ejb2.0開始出現的新的接口,本質上是JavaRMI接口. 

              2. 對于Local接口的使用,隻能在本地使用。它列出了所有定位/建立/删除Ejb執行個體的方法。 

             3. 定義local接口的方法: 

                     1) 在Ejb檔案中定義: 

                            @Local(value={Interface1,interface2,..}) 

                     2) 在Ejb檔案中定義: 

                            @Local(Interface1,Interface2,..) 

                     3) 在Interface檔案中定義 

                           @Local 

       三 Remote接口 

             1.Remote接口列出Ejb類的業務邏輯方法。內建基類javax.ejb.Remote.本質上是Java RMI接口. 

             2.定義local接口的方法: 

                     1) 在Ejb檔案中定義: 

                            @Remote(value={Interface1,interface2,..}) 

                     2) 在Ejb檔案中定義: 

                            @Remote(Interface1,Interface2,..) 

                     3) 在Interface檔案中定義 

                           @Remote 

六、java線程有幾種狀态

在java中,線程通常有五種狀态,建立,就緒,運作、阻塞和死亡狀态。

  第一是建立狀态。在生成線程對象,并沒有調用該對象的start方法,這是線程處于建立狀态。

  第二是就緒狀态。當調用了線程對象的start方法之後,該線程就進入了就緒狀态,但是此時線程排程程式還沒有把該線程設定為目前線程,此時處于就緒狀态。線上程運作之後,從等待或者睡眠中回來之後,也會處于就緒狀态。

  第三是運作狀态。線程排程程式将處于就緒狀态的線程設定為目前線程,此時線程就進入了運作狀态,開始運作run函數當中的代碼。

  第四是阻塞狀态。線程正在運作的時候,被暫停,通常是為了等待某個時間的發生(比如說某項資源就緒)之後再繼續運作。sleep,suspend,wait等方法都可以導緻線程阻塞。

  第五是死亡狀态。如果一個線程的run方法執行結束或者調用stop方法後,該線程就會死亡。對于已經死亡的線程,無法再使用start方法令其進入就緒。

七、程序和線程的差別

定義

1、程序是什麼?

是具有一定獨立功能的程式、它是系統進行資源配置設定和排程的一個獨立機關,重點在系統排程和單獨的機關,也就是說程序是可以獨 立運作的一段程式。

2、線程又是什麼?

線程程序的一個實體,是CPU排程和分派的基本機關,他是比程序更小的能獨立運作的基本機關,線程自己基本上不擁有系統資源。

在運作時,隻是暫用一些計數器、寄存器和棧 。

關系

1、一個線程隻能屬于一個程序,而一個程序可以有多個線程,但至少有一個線程(通常說的主線程)。

2、資源配置設定給程序,同一程序的所有線程共享該程序的所有資源。

3、線程在執行過程中,需要協作同步。不同程序的線程間要利用消息通信的辦法實作同步。

4、處理機分給線程,即真正在處理機上運作的是線程。

5、線程是指程序内的一個執行單元,也是程序内的可排程實體。 

差別

1、排程:線程作為排程和配置設定的基本機關,程序作為擁有資源的基本機關。

2、并發性:不僅程序之間可以并發執行,同一個程序的多個線程之間也可以并發執行。

3、擁有資源:程序是擁有資源的一個獨立機關,線程不擁有系統資源,但可以通路隸屬于程序的資源。

八、Hibernate事物隔離級别

       1.原子性(atomic),事務必須是原子工作單元;對于其資料修改,要麼全都執行,要麼全都不執行

  2. 一緻性(consistent),事務在完成時,必須使所有的資料都保持一緻狀态。

  3. 隔離性(insulation),由并發事務所作的修改必須與任何其它并發事務所作的修改隔離。

  4. 持久性(Duration),事務完成之後,它對于系統的影響是永久性的。

資料庫事務隔離級别

為了解決資料庫事務并發運作時的各種問題資料庫系統提供四種事務隔離級别:

1. Serializable 串行化

2. Repeatable Read 可重複讀

3. Read Commited 可讀已送出

4. Read Uncommited 可讀未送出

九、資料庫樹查詢SQL

select distinct t.child_team_id team_idfrom org_team_r t

startwith t.parent_team_id in teamIds

connectby prior t.child_team_id=t.parent_team_id

分組排序查詢第一條記錄

select product_id product_id,costcost_price from (

selectic.org_id,ic.product_id,ic.cost,ic.start_time,ic.end_time,ic.purchase_time

,row_number() over(partition by ic.org_id,ic.product_id order by ic.start_time desc, ic.purchase_time desc) rn

from inventory_cost ic

) where rn = 1

十、SpringMVC常用關鍵字

事務

@Transactional(propagation =Propagation.NESTED, rollbackFor = Exception.class)

Controller

//@RestController

@Controller

@RequestMapping(value ="/service/bpmControl")

public class BpmContorl extendsBpmBaseControl {

   @RequestMapping(value = "/myTaskDetail/{instanceId}")

       [email protected] String myTaskDetail(@PathVariable String instanceId,

                                   RedirectAttributesredirectAttributes){

              returnnull;

       }

   @RequestMapping(value={"/addPurchaseData.htm"},method={RequestMethod.POST})

       [email protected] Object dataSaveApply(@ModelAttribute Purchase purchase){

              returnnull;

       }

}

十一、JSP的7個動作指令

forward、include、useBean、setProperty、getProperty、plugin、param

十二、JSP腳本中的9個内置對象

Application、Config、Exception、Out、page、pageContext、Request、response、session

十三、html中post和get差別

1. get是從伺服器上擷取資料,post是向伺服器傳送資料。

2. get是把參數資料隊列加到送出表單的ACTION屬性所指的URL中,值和表單内各個字段一一對應,在URL中可以看到。post是通過HTTPpost機制,将表單内各個字段與其内容放置在HTML HEADER内一起傳送到ACTION屬性所指的URL位址。使用者看不到這個過程。

3. 對于get方式,伺服器端用Request.QueryString擷取變量的值,對于post方式,伺服器端用Request.Form擷取送出的資料。

4. get傳送的資料量較小,不能大于2KB。post傳送的資料量較大,一般被預設為不受限制。但理論上,IIS4中最大量為80KB,IIS5中為100KB。

5. get安全性非常低,post安全性較高。但是執行效率卻比Post方法好。

建議:

1、get方式的安全性較Post方式要差些,包含機密資訊的話,建議用Post資料送出方式;

2、在做資料查詢時,建議用Get方式;而在做資料添加、修改或删除時,建議用Post方式;

十四、Servlet生命周期

Servlet生命周期分為三個階段:

  1.初始化階段 調用init()方法

  2.響應客戶請求階段 調用service()方法

  3.終止階段 調用destroy()方法

Servlet工作原理:

1、首先簡單解釋一下Servlet接收和響應客戶請求的過程,首先客戶發送一個請求,Servlet是調用service()方法對請求進行響應的,通過源代碼可見,service()方法中對請求的方式進行了比對,選擇調用doGet,doPost等這些方法,然後再進入對應的方法中調用邏輯層的方法,實作對客戶的響應。在Servlet接口和GenericServlet中是沒有doGet()、doPost()等等這些方法的,HttpServlet中定義了這些方法,但是都是傳回error資訊,是以,我們每次定義一個Servlet的時候,都必須實作doGet或doPost等這些方法。

2、每一個自定義的Servlet都必須實作Servlet的接口,Servlet接口中定義了五個方法,其中比較重要的三個方法涉及到Servlet的生命周期,分别是上文提到的init(),service(),destroy()方法。GenericServlet是一個通用的,不特定于任何協定的Servlet,它實作了Servlet接口。而HttpServlet繼承于GenericServlet,是以HttpServlet也實作了Servlet接口。是以我們定義Servlet的時候隻需要繼承HttpServlet即可。

3、Servlet接口和GenericServlet是不特定于任何協定的,而HttpServlet是特定于HTTP協定的類,是以HttpServlet中實作了service()方法,并将請求ServletRequest、ServletResponse 強轉為HttpRequest 和 HttpResponse。

十五、Linux常用指令