1. 程式人生 > >Java面試題集(五)

Java面試題集(五)

足夠 advice 面試題 有一個 了解 framework ons switch 多個

三、開源框架

什麽是mybaties?

Mybaties是支持普通sql查詢,存儲過程和高級映射的優秀持久層框架。Mybaties消除了幾乎所有的jdbc代碼和參數的手工設置以及結果集的檢索。Mybaties使用簡單的xml或註解用於配置和原始映射,將接口和Java的pojos(Plan Old Java Objects 普通的Java對象)映射成數據庫中的記錄。

Mybaties的動態sql語句是基於ognl表達式的,可以方便的在sql語句中實現某些邏輯,總體來說mybaties動態sql語句主要有以下幾類:

1:if語句(簡單的條件判斷)

2:choose(when otherwise),相當於Java語言中的switch與jstl中的choose很類似。

3:trim(where,set,對包含的內容加上prexif或者suffix等,前綴後綴)

4:where(主要是用來簡化sql語句中where條件判斷,能只能的處理and ,or,不必擔心多余導致語法報錯)

5:set(主要用於更新操作)

6:foreach 主要用在構建in條件中,它可以在sql語句中進行叠代一個集合。Foreach元素的屬性主要有item,index,collector,open,separator,close.

Item表示集合中每一個元素進行叠代時的別名;

Index指定一個名字,用於表示在叠代過程中,每次叠代到的位置;

Open表示該語句以什麽開始;

Separator表示在每次進行叠代之間以什麽符號作為分隔符;

Close表示該語句以什麽結束。

註意:collector 若是list則為list,若為數組則為array,默認為map

Mybaties與hibernate的區別?

相對於hibernate的O/R而言,mybaties是一種“sql mapping”的ORM實現。

Hibernate對數據庫結構提供了較為完整的封裝,hibernate的o/r mapping實現了pojo和數據庫之間的映射,以及sql的自動生成和執行。程序員往往只需定義好pojo到數據庫表的映射關系,即可通過hibernate提供的辦法完成持久層操作。程序員甚至不需要對sql熟練掌握,hibernate會根據制定的存儲邏輯,自動生成對應的sql並調用jdbc接口加以執行。

而mybaties著力點則在於pojo與sql之間的映射關系。也就是說mybaties並不會為程序員在運行期間自動執行生成sql執行,具體的sql語句需要程序員自己寫,然後通過映射配置文件,將sql所需的參數以及返回的結果字段映射到指定pojo。

Hibernate是一個全自動的orm映射工具,它可以自動生成sql語句,而mybatis 需要我們自己在xml配置文件中寫sql語句,hibernate要比ibatis功能負責和強大很多。因為hibernate自動生成sql語句,我們 無法控制該語句,我們就無法去寫特定的高效率的sql。對於一些不太復雜的sql查詢,hibernate可以很好幫我們完成,但是對於特別復雜的查 詢,hibernate就很難適應了,這時候用mybatis就是不錯的選擇,因為mybatis還是由我們自己寫sql語句。

springMVC工作原理(重點)

在整個springMVC框架中,dispatcherServlet處於核心位置,負責協調和組織不同組件以完成請求處理並返回響應工作

1.客戶端發送一個請求匹配dispatcherServlet的請求映射路徑(web.xml),web容器將該請求轉交給dispatcherServlet處理。

2.dispatcherServlet接收到請求後,將請求信息(包括url,http,請求頭,請求參數,cook等)以及HandlerMapping的配置找到處理請求的處理器Handler

3.dispatcherServlet根據HandlerMapping得到對應請求的Handler後,通過HandlerAdapter對Handler進行封裝,再以統一的適配器接口調用Handler。

4.處理器完成業務邏輯的處理後將返回一個ModelAndView給dispatcherServlet,ModelAndView包含視圖邏輯名和模型數據信息。

5.dispatcherServlet借助ViewResoler完成邏輯視圖名到真實視圖對象的解析。

6.得到真實視圖對象後,dispatcherServlet使用這個view對ModelAndView中的模型數據進行視圖渲染。

SpringMVC註解

[email protected](value="url請求地址")寫在類的上面,表示該類的url請求地址

[email protected](value="請求路徑",method={RequestMethod.GET})寫在方法的上面,方法的路徑。

[email protected] 綁定單個請求數據,可以是url中的數據,表單提交的數據或者上傳的文件。

[email protected] 用來返回數據給客戶端。例如:

@ResponseBody

@RequestMapping(value = "/getGoodsByType", method = RequestMethod.POST)

public ResultModel<Goods> getGoodsByType(@RequestParam int typeId) {

return “modelresult”

}

[email protected] 用來處理Content-type不是application/x-www-form-urlencoded編碼的內容,例如application/json ,application/xml等。

[email protected] 綁定url模板變量值,@PathVariable(value="id")Integer id這裏value值必須和請求參數一致。

[email protected] 綁定數據到Model

[email protected] 綁定數據到session

[email protected] 綁定multipart/data數據,並可以根據類型進行對象轉換。

[email protected] 綁定請求頭數據

[email protected] 綁定Cookie數據

Springmvc常用標簽?

首先在jsp頁面引入springmvc標簽標識符

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

form標簽:<form:form modelAttribute=”contentModel” method=”post”>

input標簽:<form:input path=”username”>

password標簽:<form:password path=”password”>

checkbox標簽:

<form:checkbox path=”selectArray” value=${contentModel.testArray}>

SpringMVC與Struts2比較(重點)

1.springmvc是方法級別的攔截,攔截到方法後根據參數上的註解,把request數據註入進去,一個方法對應一個request上下文,而方法同時又跟一個url對應,而struts2是類級別的攔截,每次來了請求就創建一個Action,然後調用setter getter方法把request中的數據註入,struts2中一個Action對象對應一個request上下文,struts2中action一個方法對應一個url,但是其類的屬性被所有方法所共享。

2.springmvc的方法之間基本上獨立的,獨享request response數據,請求數據通過參數獲取,方法之間不共享變量。而struts2雖然方法之間也是獨立的,但其所有Action變量是共享的,這不會影響程序運行,卻給我們編碼讀程序時帶來麻煩。

3.springmvc的驗證也是一個亮點,支持JSR303,處理ajax的請求更是方便只需一個註解@ResponseBody然後直接返回響應文本即可,如下:

@RequestMapping(value=“/whitelists”)  
public String index(ModelMap map) {  
  Account account = accountManager.getByDigitId(SecurityContextHolder.get().getDigitId());  
  List groupList = groupManager.findAllGroup(account.getId());  
  map.put(“account”, account);  
  map.put(“groupList”, groupList);  
  return “/group/group-index”;  
}  
 

// @ResponseBody ajax響應,處理Ajax請求也很方便

Spring最核心的2點:IOC和AOP(重點)

Spring是一個輕量級的控制反轉和面向切面的容器框架。

IOC(控制反轉也稱為 DI依賴註入):一個對象依賴的其對象通過被動的方式傳遞進來,而不是這個對象自己創建或者查找依賴對象,spring容器初始化時就將依賴傳遞給對象。

IOC(控制反轉):獲得依賴對象被反轉,即獲得依賴對象的過程由自身管理變為由IOC容器主動註入。依賴註入就是由IOC容器在運行期間,動態地將某種依賴關系註入到對象中。

一個對象依賴的其他對象通過被動的方式傳遞過來,而不是這個對象自己創建或者查找依賴對象,容器在對象初始化時不等對象請求就主動將依賴傳遞給它。

AOP:面向方面編程。能夠將那些與業務無關,卻為業務模塊所共同調用的邏輯或責任,例持久化管理,事務管理、日誌管理、權限控制,調試管理等封裝起來,便於減少系統的重復代碼,降低模塊間的耦合度,提高開發和調試效率

Spring的目的就是讓對象與對象之間的關系沒有通過代碼來關聯,都是通過配置類說明管理的(spring根據配置,內部通過反射去動態組裝對象)。

項目中如何體現spring的AOP和IOC的?

項目中體現AOP:

主要是橫切一個關註點,將一個關註點模塊化成一個切面,在切面上聲明一個通知(Advice)和切入點。通知中定義了要插入的方法,切入點內容是一個表達式,以描述需要在哪些對象的哪些方法上插入通知定義的方法。

項目中用到的spring中的切面編程最多的地方是聲明式事務管理。

1.定義一個事務管理

2.配置事務特性(相當於聲明通知,一般在業務層的類的一些方法上定義事務)

3.配置哪些類的哪些方法需要配置事務(相當於切入點,一般在業務類的方法上)

例如:

1.註解方式配置事務

@AspectJ風格的切面可以通過@Compenent註解標識其為Spring管理Bean,而@Aspect註解不能被Spring自動識別並註冊為Bean,

必須通過@Component註解來完成,如下:

@Component    
@Aspect    
public class TestAspect {    
    @Pointcut(value="execution(* *(..))")    
    private void pointcut() {}    
    @Before(value="pointcut()")    
    public void before() {    
        System.out.println("=======before");    
    }    
}   

2.攔截方式配置事務(在spring-hibernate.xml中配置)

Spring的聲明式事務配置:

首先配置sessionfactory

<bean id=”sessionFactory” class=”org.springframework.orm.hibernate4.LocalSessionFactoryBean”>  
   <property name=”configLocation”>  
     <value>/WEB/INF/classes/hibernate.cfg.xml</value>  
   </property>  
</bean>  
 

然後配置事務管理器

<bean id=”transactionManager” class=”org.springframework.orm.hibernate4.HibernateTransactionManager”>  
   <property name="sessionFactory" ref="sessionFactory"></property>  
</bean>  

配置事務特征

  1. <tx:advice id=”txAdvice” transaction-manager=”transactionManager”>  
       <tx:attributes>  
          <tx:method:nametx:method:name=”add.*” progagation=”REQUIRED”>  
          <tx:method:nametx:method:name=”update.*” progagation=”SUPPORTS”>  
          <tx:method name="delete*" rollback-for="Exception" />  
       </tx:attributes>  
    </tx:advice>  

配置哪些類的哪些方法配置事務

<aop:config>  
  <aop:pointcut id=”transactionPoitcut”expression=”execution(*.com.ftsc.service.impl.*.*(..))”/>  
   <aop:advisor advice-ref=”txAdvice”pointcut-ref=”transactiomPointcut”>  
</aop:config>  

Spring的傳播機制:progagation定義了7個事務傳播機制。

REQUIRED:如果存在一個事務,則支持當前事務。如果沒有事務則開啟一個新的事務

SUPPORTS:如果存在一個事務,支持當前事務。如果沒有事務,則非事務的執行,但是對於事務同步的事務管理器,supports與不使用有少許不同。

REQUIRES_NEW:總是開啟一個新的事務如果一個事務已經存在,則將當前事務掛起

NOT_SUPPORTED:總是非事務執行,並掛起任務存在的事務

NEVER:總是非事務的執行,如果存在一個活動事務,則拋出異常

NESTED:如果一個活動的事務存在,則運行在一個嵌套的事務中,如果沒有活動事務,則按

TransactionDefinition.PROPAGATION_REQUIRED屬性執行

註:嵌套事務一個非常的概念及時內層事務依賴於外層事務。外層事務失敗時,會回滾內層事務所做的動作。而內層事務操作失敗並不會引起外層事務的回滾。

項目中體現IOC:

例如spring整合struts,讓spring的IOC容器管理struts2的action

首先在web.xml中引入struts配置文件如struts的過濾器,spring的配置文件如:

<context-parm>  
  <param-name>contextConfigLocation</param-name>  
  <param-name>classpath:applicationContext.xml</param-name>  
</context-parm>  

啟動IOC容器的listener:

<listener>  
  <listener-class>  
     org.springframework.web.context.ContextLoaderListener  
  </listener-class>  
</listener>  

spring整合struts的插件struts-spring-plugin,該插件包的作用是:覆蓋struts的objectFactory來增強核心框架對象的創建,當創建一個對象的時候,它會用struts配置文件的class屬性去和spring配置文件中的id屬性進行關聯,如果能找到,則由spring創建,否則由struts框架自身創建,然後由spring來裝配

接著在spring的配置文件中配置struts的action實例,(註意需要配置scope屬性為prototype,因為struts的action是單例,這是為了解決線程安全問題。)在struts配置文件中配置action,但其class屬性不再指向該action的實現類,而是指向spring容器中action實例的ID

Spring依賴註入方式?

spring註入有3中方法:屬性名稱,setter方法,構造方法

開發中主要使用spring的什麽技術?

1.IOC容器管理各層組件

2.使用aop配置事務

3.整合其他框架

Spring註解?

@Component:通用註解,可用於任何bean

@Repository:通常用於註解dao類,即持久層

@Service:通常用於註解service類,即服務層。

@Controller:通常用於controller類,即控制層(MVC)

在聲明action時,需要指定為多例,解決線程安全問題。

Spring過濾器和攔截器區別?

Spring的攔截器與servlet的filter有相似之處,比如二者都是AOP編程思想的體現,都能實現權限檢查,日誌記錄等。

區別:

1.使用範圍不同:filter是servlet規範規定的,只能用於web程序中,而攔截器既可以用於web程序,也可以用於application,swing程序中;

2.規範不同:filter是在servlet規範中定義的,是servlet容器支持的,而攔截器是在spring容器內的,是spring框架支持的;

3.使用資源不同:同其他的代碼塊一樣,攔截器也是一個spring的組件,歸spring管理,配置在spring文件中,因此能使用spring裏的任何資源,對象。例如service對象,數據源,事務管理等,通過ioc註入到攔截器即可,而過濾器則不能;

4.深度不同:filter只在servlet前後起作用,而攔截器能夠深入到方法前後,異常拋出前後等,因此攔截器的使用具有更大的彈性,所以在spring框架的程序中,要優先使用攔截器。

案例:在web.xml中使用filter如字符集編碼

Struts2工作原理?

1.客戶端發送一個請求給strtusPrepareAndExecueFilter(在web.xml中),

2.strutsPrepareAndExecuteFilter詢問ActionMapper:該請求是否是一個strtus2的請求,

3.若actionMapper認為該請求是一個strtus請求,則strutsPrepareAndExecuteFilter把請求的處理交給actionProxy,

4.ActionProxy通過ConfigurationManager詢問框架的配置文件,確定需要調用action類及action方法,

5.actionProxy創建一個actionInvocation的實例,並進行初始化,

6.actionInvocation實例在調用action過程前後,涉及到相關攔截器(Intercepter)的調用,

7.Action執行完畢,actionInvocation負責根據strtus.xml找到對應的返回結果。調用結果的execute方法,渲染結果,在渲染的過程中可以使用strtus2框架的標簽,

8.執行各個攔截器invocation.invoke()之後的代碼

9.把結果發送給客戶端

Struts2:註意在頁面中展示的數據,都一視同仁的成為字符串在頁面上展現出來。

Struts2常用標簽?

首先在jsp頁面中引入strtus2標簽庫<%@taglib prefix=”s”uri=”/struts-tags”>

1.往action傳值:<input name=”userName” type=”text” >

2.顯示標簽property用於輸出指定值:<s:property value=”userName”>

3.用於從頁面往action中(user)的對象傳值:

<s:text name=”user.userName”id=”userName”>

4.叠代<s:iterator>用於將list,Map,ArrayList等集合數據循環遍歷

<s:iterator id=”user”status=”u”value=”userList”>

<s:property value=”userName”>

</s:iterator>

5.Set標簽用於將某個值放入指定範圍內如application,session

<s:set name=”user”value=”userName” scope=”request”>

El表達式:如

<s:set name=”name” value=”<%=request.getParamter(“name”)%>”/>

攔截器和過濾器的區別?

1.過濾器依賴於servlet容器,而攔截器不依賴於servlet容器。

2.Struts2攔截器只能對action請求起作用,而過濾器則對所有請求起作用。

3.攔截器可以訪問action的上下文,值棧裏的對象,而過濾器不能。

4.在action的生命周期中,攔截器可以調用多次,而過濾器只能在容器初始化時被調用一次。

談談你對MVC的理解?

MVC即Model-View-Controller的縮寫

Model:表示業務數據和業務處理,相當於Javabean,一個模型為多個視圖提供數據

View:用戶看到並與之交互的頁面,向用戶顯示相關數據,並接受用戶的輸入,如jsp

Controller:接受用戶請求並調用相應模型去處理請求,然後根據處理的結果調用相應的視圖來顯示處理的結果如servlet,struts2

MVC處理過程:首先控制器接受用戶的請求,並決定應該調用哪個模型來進行處理;然後根據用戶請求進行相應的業務邏輯處理,並返回數據;最後控制器調用相應的視圖格式化返回的數據,並通過視圖呈現給用戶。

Action 是單例還是多例?為什麽?

Action是單例,當多個用戶訪問一個請求時候,服務器內存中只有一個與之對應的 action類對象。因為當服務器第一次加載struts的配置文件時,創建一個action後,每發送一個請求,服務器都會去檢索相應的範圍是否存在這 樣一個action實例,如果存在,則使用這個實例,否則創建一個action實例。

Hibernate的緩存機制:一級緩存session緩存和二級緩存sessionfactory緩存?

hibernate:一個基於元數據的輕量級(占用資源少,沒有浸入性)orm(對象關系數據庫映射)框架。

Session是一級緩存,它是屬於事務範圍的緩存,由Hibernate管理,無需進行幹預。

SessionFactory是二級緩存,它是屬於進程範圍或群集範圍的緩存,可以進行配置和更改.

一級緩存又叫session緩存,輕量級的,創建和銷毀不需要消耗太多資源,但是它是線程不安全的,要避免多個線程共享一個session實例。我們框架使用的get,load,save,update,delete等都支持一級緩存的。

二級緩存又叫sessionfactory緩存,重量級的,創建和銷毀需要消耗太多資源,它是線程安全的,一個實例可以被應用的多個線程共享。

需要在配置文件中啟用二級緩存

<!--啟用二級緩存 -->

<property name="hibernate.cache.use_second_level_cache">true</property>

緩存的操作數據原理:

查詢數據時,會首先從一級緩存中取數據,如果取上,則直接使用,否則到二級緩存中取,如果取到則直接使用,否則,就會發送語句查詢數據庫。這樣利用一級和二級緩存會提高訪問效率。

lazy(Hibernate的延遲加載功能):表示查詢當前對象或關聯對象數據時,不真正訪問數據庫,當使用對象非主鍵屬性時,才真正發送查詢語句,訪問數據庫。

Hibernate工作原理?

1.讀取並解析配置文件

2.讀取並解析映射信息,創建sessionfantory

3.打開session

4.創建事務transaction

5.持久化操作

6.提交事務

7.關閉session

8.關閉sessionfactory

Hibernate的核心接口有5個:session,sessionFactory,transaction,query,configuration?

Session接口:負責進行被持久化對象的crud操作。Session是一級緩存,輕量級的,線程不安全的。

SessionFactory接口:負責初始化Hibernate,它充當數據存儲源的代理,並負責創建session對象,這裏用到工廠模式,sessionFactory是二級緩存,重量級的。

Configuration接口:負責配置並啟動Hibernate,創建sessionFactory對象。在Hibernate啟動過程中,configuration類的實例首先定義映射文件位置,讀取配置,然後創建sessionFactory對象。

Transact接口:負責相關事務相關的操作。

Query和criteria接口:負責各種數據庫查詢,用sql或者hql語句表達方式。

Hibernate中Java對象的狀態有哪些?

1.臨時態(transient)不處於session緩存中。Oid為null或等於id的unsaved-value屬性值

2.持久態(persistent)加入session緩存中

3.遊離態(detached)已經被持久化,但不再處於session的緩存中

Session的清理和清空有什麽區別?

清理緩存調用的是session.flush()方法,而清空調用的是session.clean()方法。

Session清理緩存是指按照緩存中對象的狀態變化來同步更新數據庫,但不清空緩存。而清空則是把session的緩存置空,不同步更新到數據庫。

Hibernate的load()方法與get()方法的區別?

Get加載數據不支持延遲加載,若沒有oid對象則返回的是null,而load加載數據支持延遲加載,返回的是一個代理對象

Hibernate優缺點?

優點:

1.對JDBC訪問數據庫的代碼做了封裝,簡化了數據訪問層繁瑣的重復性代碼

2.映射的靈活性, 它支持各種關系數據庫,從一對一到多對多的各種復雜關系.

3.非侵入性、移植性會好

4.緩存機制: 提供一級緩存和二級緩存。

缺點:

1.無法對 SQL 進行優化

2.框架中使用 ORM 原則, 導致配置過於復雜

3.執行效率和原生的JDBC相比偏差: 特別是在批量數據處理的時候

4.不支持批量修改、刪除

Hibernate的openSessionView問題?

用於解決懶加載異常問題,主要功能就是把hibernate session和一個請求的線程綁定在一起,直到頁面完整輸出,這樣就可以保證頁面讀取數據的時候session一直處於開啟狀態,如果去獲取延遲加載對象也不會報錯。

註意配置filter要放在strtus2過濾器的前面,因為它要頁面顯示完後再退出。

Hibernate的getCurrentSession()和openSession()的區別?

1.getCurrentSession()它會先檢查當前線程中是否綁定了session如果有則直接返回,沒有再創建,而openSession()則是直接new一個新的session並返回。

2.使用ThreadLocal來實現線程session的隔離。

3.getCurrentSession()在事務提交的時候會自動關閉session,而openSession()要手動關閉。


項目中為什麽使用SSH?

1.使用struts2是因為struts2是基於MVC設計模式,很好的將應用程序進行分層,使開發者更關註業務邏輯實現,其次struts有豐富的taglib,靈活運用,大大提高開發效率。

2.使用hibernate是因為它是基於orm模式的輕量級框架。

3.使用spring是因為基於IOC和AOP架構多層j2ee框架,采用IOC使得很容易實現bean的裝配,采用AOP實現事務管理。

Hibernate的update()和saveOrUpdate()的區別?

Update()和saveOrUpdate()是用來對跨session的po進行狀態管理的。

Update()方法操作的對象必須是持久化的對象,如果此對象在數據庫中不存在的話,就不能使用update()方法。

saveOrUpdate()方法操作的對象即可以是持久化的,也可以是未持久化的對象,如果該對象是已經持久化的則調用該方法會更新數據庫對象,如果該對象是未持久化的則調用該方法會save到數據庫。

什麽是hibernate的並發機制?怎麽去處理並發問題?

Hibernate的並發機制:1.hibernate的session對象是非線程安全的,對於單個請求,單個會話,單個工作單元,它通常只使用一次然後就丟棄。如果一個session實例會話允許共享的話,那些支持並發運行的,例如http request,session bean將會導致出現資源爭用。如果在http session中hibernate的session話,就可能出現同步訪問http session,只要用戶足夠快點擊瀏覽器的“刷新”。2.多個事務並發訪問同一塊資源,可能會引發第一類丟失更新,臟讀,幻讀,不可重復讀,第二類丟失更新一系列的問題。

解決方案:

1.設置事務隔離級別

Serializable串行化。隔離級別最高

Repeatable read:可重復讀

Read committed:已提交數據讀

Read uncommitted:未提交數據讀。隔離級別最差

設置鎖:樂觀鎖和悲觀鎖。

樂觀鎖:使用版本號或者時間戳檢測更新丟失,在<class>映射中設置optimistic-lock=“all”可以在沒有版本或者時間戳屬性映射的情況下實現版本檢查,此時hibernate將比較一行記錄的每個字段的狀態行。

悲觀鎖:hibernate總是使用數據庫的鎖定機制,從不在內存中鎖定對象,只要為jdbc連接指定一下隔離級別,然後讓數據庫去搞定一切就夠了。類LockMode定義了hibernate所需的不同的鎖定級別:

LockMode.UPGRADE,LockMode.UPGRADE_NOWAIT,LockMode.READ

Java面試題集(五)