第一部分 Java基礎
第二部分 Java進階

高級java面試題及答案(MyBatis專題 )

 

6.MyBatis專題


6.1談一談你對ORM的理解?
對象關系映射(Object Relational Mapping,簡稱ORM)是一種為了解決面向對象與關系數據庫存在的互不匹配的現象的技術。 簡單的說,ORM是通過使用描述對象和數據庫之間映射的元數據,將java程序中的對象自動持久化到關系數據庫中。當然反過來也是可以的,例如將數據庫表當中的記錄查詢出來,然后映射為Java程序中的Java對象。


6.2在MyBatis中$和#的區別?
$進行sql語句的拼接,#是專門給sql語句傳值的。$就是JDBC當中的Statement,#就是JDBC當中的PreparedStatement。$的這種方式使用時需要特別注意sql注入問題。


6.3你對MyBatis的一級緩存和二級緩存有了解嗎,說一下?
Mybatis對緩存提供支持,但是在沒有配置的默認情況下,它只開啟一級緩存,一級緩存只是相對于同一個SqlSession而言。所以在參數SQL完全一樣的情況下,我們使用同一個SqlSession對象調用一個Mapper方法,往往只執行一次SQL,因為使用SqlSession第一次查詢后,MyBatis會將其放在緩存中,以后再查詢的時候,如果沒有聲明需要刷新,并且緩存沒有超時的情況下,SqlSession都會取出當前緩存的數據,而不會再次發送SQL到數據庫。


MyBatis的二級緩存是Application級別的緩存,它可以提高對數據庫查詢的效率,以提高應用的性能。SqlSessionFactory層面上的二級緩存默認是不開啟的,二級緩存的開啟需要進行配置,實現二級緩存的時候,MyBatis要求返回的POJO必須是可序列化的。 也就是要求實現Serializable接口,配置方法很簡單,只需要在映射XML文件配置就可以開啟緩存了。


由于我們在實際的開發中目前都會使用第三方的緩存技術,例如Redis,所以MyBatis這塊的二級緩存沒有太多的了解。


6.4MyBatis一對多你是怎么實現的?
有聯合查詢和嵌套查詢。聯合查詢是幾個表聯合查詢,只查詢一次,通過在resultMap里面配 置collection節點配置一對多的類就可以完成; 嵌套查詢是先查一個表,根據這個表里面的結果的外鍵id再去另外一個表里面查詢數據,也是通過配置collection,但另外一個表的查詢通過select節點配置。

 

6.5MyBatis的parameterType怎么理解的?
parameterType屬性用來指定參數類型,parameterType屬性是專門用來給sql語句占位符#{}傳值的,底層原理使用了反射機制,#{}的大括號當中需要提供實體類的屬性名,底層使用屬性名拼接get方法來獲取屬性值,將屬性值傳遞給sql語句。


6.6MyBatis的resultType是怎么理解的?
resultType用來指定結果集封裝的數據類型,當一個select語句查詢之后得到結果集,結果集的列名需要和java實體類的屬性名一致,不一致的可以使用as關鍵字給列起別名,拿著列名拼接set方法,通過反射機制調用set方法給結果集對象的屬性賦值。


6.7MyBatis中resultMap用過嗎,它是干什么的?
在MyBatis當中,查詢結果集被封裝為Java對象,可以通過resultType,也可以通過resultMap,在resultMap當中描述了數據庫表的列與Java對象的屬性之間的對應關系。在映射關系中,還可以通過resultMap的typeHandler設置實現查詢結果值的類型轉換。另外,最重要的是通過resultMap的子標簽比如、等,可以實現一對一、一對多等的映射。


6.8MyBatis底層實現原理?
MyBatis是一個持久層框架,實現了ORM思想,可以將查詢的結果集自動轉換成Java對象,也可以將Java對象轉換成一條數據插入到數據庫表當中。
那么,查詢結果集是如何自動轉換成Java對象的呢?實際上這里使用了反射機制,在配置文件中假設編寫了一條select語句,查詢之后,列名與屬性名要一一對應(不對應的可以采用給列起別名),然后每個列名前添加“set”,通過反射機制獲取set方法,然后再通過反射機制的method.invoke()來調用這個set方法,給Java對象的屬性賦值。這樣就完成了對象的封裝。


另外,Java對象是如何轉換成一條記錄插入到數據庫的呢?假設在配置文件中編寫了一條insert語句,那么這條語句需要的值從哪里來呢,在mybatis的mapper配置中有parameterType屬性,該屬性是專門給sql語句占位符傳值的,其實這里也是使用了反射機制,其中sql語句的占位符采用#{},其中大括號當中需要提供java對象的屬性名,該屬性名和get進行拼接得到get方法名,然后通過反射機制獲取該get方法,再通過method.invoke()來調用這個get方法,這樣就可以獲取到對應的屬性值,然后傳入了。


其實MyBatis設計最牛的地方當然是采用JDK動態代理的方式生成DAO接口的實現類了。其中DAO接口中的每一個方法名對應sql語句的id。DAO接口中的方法不允許重載,因為id是不允許重復的。以上大概就是我了解的MyBatis實現原理。


6.9談談MyBatis和Hibernate的區別?
Hibernate屬于全自動ORM映射框架,使用Hibernate查詢關聯對象或者關聯集合對象時,可以根據對象關系模型直接獲取,所以它是全自動的。而Mybatis在查詢關聯對象或關聯集合對象時,需要手動編寫sql來完成,所以,稱之為半自動ORM映射工具。


也正因為MyBatis的sql語句由程序員自己編寫,所以sql更容易優化,這也是目前互聯網公司使用MyBatis較多的重要原因。


6.10MyBatis中除了之外你還用過哪些標簽?

還有很多其他的標簽,、、、、,加上動態sql的9個標簽,trim|where|set|foreach|if|choose|when|otherwise|bind等,其中為sql片段標簽,通過標簽引入sql片段,為不支持自增的主鍵生成策略標簽。

 

6.11在MyBatis當中,通常一個Mapper映射文件,都會寫一個Dao接口與之對應,請問,這個Dao接口的工作原理是什么?

Dao接口的工作原理是JDK動態代理,Mybatis運行時會使用JDK動態代理為Dao接口生成代理proxy對象,代理對象proxy會攔截接口方法,轉而執行MappedStatement所代表的sql,然后將sql執行結果返回。

 

6.12MyBatis注解用過嗎,都有哪些?

到目前為止,我們在項目中還沒有使用過MyBatis的注解,因為MyBatis最主要是編寫sql語句,sql語句涉及到后期優化,可能會頻繁修改,所以我們一直都在使用配置文件的形式。

 

6.13Mybatis動態sql是做什么的?都有哪些動態sql?能簡述一下動態sql的執行原理嗎?

Mybatis動態sql可以讓我們在Xml映射文件內以標簽的形式編寫動態sql,完成邏輯判斷和動態拼接sql的功能,Mybatis提供了9種動態sql標簽trim|where|set|foreach|if|choose|when|otherwise|bind。其執行原理為,使用OGNL從sql參數對象中計算表達式的值,根據表達式的值動態拼接sql,以此來完成動態sql的功能。

 

6.14Mybatis是如何將sql執行結果封裝為目標對象并返回的?

第一種是使用resultMap,逐一定義列名和對象屬性名之間的映射關系。 第二種是使用resultType,使用sql列的別名功能,將列別名書寫為對象屬性名,比如T_NAME AS NAME,對象屬性名一般是name,小寫,但是列名不區分大小寫,Mybatis會忽略列名大小寫,智能找到與之對應對象屬性名,你甚至可以寫成T_NAME AS NaMe,Mybatis一樣可以正常工作。 有了列名與屬性名的映射關系后,Mybatis通過反射創建對象,同時使用反射給對象的屬性逐一賦值并返回,那些找不到映射關系的屬性,是無法完成賦值的。

 

6.15MyBatis接口Mapper中的方法能夠重載嗎?

不能。MyBatis使用package+Mapper+method全限名作為key,去xml內尋找唯一sql來執行的。類似:key=x.y.UserMapper.getUserById,那么,重載方法時將導致矛盾。對于Mapper接口,Mybatis禁止方法重載(overload)。

 

6.16在MyBatis當中,給sql語句傳值,你知道哪幾種方式?

通過POJO(Javabean)可以傳值,但要求#{}的大括號當中提供POJO的屬性名。如果沒有合適的POJO,可以使用Map集合進行傳值,但要求#{}的大括號當中提供Map集合的key。如果DAO接口的方法參數有多個,并且數量不多,而且每個都是簡單類型,也可以通過#{arg0}、#{arg1}的方式傳參。    

 

7.Spring專題

 

7.1談談你對Spring框架的理解?

 

7.2Spring IoC的理解以及實現原理?

 

7.3Spring AOP的理解以及實現原理?

 

7.4Spring是如何進行事務管理的?

事務就是對一系列的數據庫操作(比如插入多條數據)進行統一的提交或回滾操作,如果插入成功,那么一起成功,如果中間有一條出現異常,那么回滾之前的所有操作。這樣可以防止出現臟數據,防止數據庫數據出現問題。開發中為了避免這種情況一般都會進行事務管理。 Spring的聲明式事務通常是指在配置文件中對事務進行配置聲明,其中包括了很多聲明屬性,它是通過Spring Proxy幫你做代理,自己不用額外的寫代碼,只要在Spring配置文件中聲明即可;通常用在數據庫的操作里面; 編程式事務就是指通過硬編碼的方式做事務處理,這種處理方式需要寫代碼,事務中的邏輯可以自己定制;可以是數據庫的東東,也可以是其他的操作。 Spring中也有自己的事務管理機制,一般是使用TransactionMananger進行管理,可以通過Spring的注入來使用此功能。

 

7.5Spring事務的傳播特性有了解嗎?

 

7.6Spring常用注解說幾個?

 

[email protected] 與@Resource的區別?

 

7.8IoC和DI的關系?

 

7.9解釋Spring支持的幾種bean的作用域,怎么配置?

 

7.10依賴注入的實現方式包括哪些?

 

7.11說一下Spring Bean的生命周期?

 

7.12什么是Spring的自動裝配機制,包括哪些?

 

7.13在Spring中怎么啟用注解? 使用 配置。

 

7.14Spring支持的事務管理類型有哪些?

 

7.15Spring AOP中什么是切面?

 

7.16Spring AOP中什么是關注點?

 

7.17Spring AOP中什么是通知,包括哪些?

 

7.18Spring AOP中什么是切入點?

 

7.19Spring AOP中什么是連接點?

 

7.20Spring AOP中什么是目標對象?

 

7.21Spring AOP中什么是代理對象?

 

7.22Spring AOP中什么是織入?

 

7.23你在實際開發中使用Spring AOP干什么了?

 

7.24Spring框架中的單例bean是否是線程安全的?

 

7.25Spring框架中BeanFactory和ApplicationContext有什么區別?  

 

8.SpringMVC專題

 

8.1說一下SpringMVC的執行流程?

(1)用戶發送請求至前端控制器DispatcherServlet;

(2) DispatcherServlet收到請求后,調用HandlerMapping處理器映射器,請求獲取Handle;

(3)處理器映射器根據請求url找到具體的處理器,生成處理器對象及處理器攔截器(如果有則生成)一并返回給DispatcherServlet;

(4)DispatcherServlet 調用 HandlerAdapter處理器適配器;

(5)HandlerAdapter 經過適配調用 具體處理器(Handler,也叫后端控制器);

(6)Handler執行完成返回ModelAndView;

(7)HandlerAdapter將Handler執行結果ModelAndView返回給DispatcherServlet;

(8)DispatcherServlet將ModelAndView傳給ViewResolver視圖解析器進行解析;

(9)ViewResolver解析后返回具體View;

(10)DispatcherServlet對View進行渲染視圖(即將模型數據填充至視圖中)

(11)DispatcherServlet響應用戶。  

 

8.2說一下SpringMVC框架的理解?

Spring MVC是一個基于Java實現了MVC架構模式的請求驅動類型的輕量級Web框架,通過把Model,View,Controller分離,將web層職能分工(解耦合),把復雜的web應用分成邏輯清晰的幾部分,簡化開發,減少出錯,方便組內開發人員之間的配合。

 

8.3SpringMVC常用注解?

@RequestMapping:用于處理請求地址映射,可以作用于類和方法上。 @RequestParam:用于獲取傳入參數的值 @RequestBody:將客戶端請求過來的json轉成java對象 @RestController:@Controller+ @ResponseBody @[email protected]@[email protected] @PathViriable:用于定義路徑參數值 @ResponseBody:作用于方法上,可以將整個返回結果以某種格式返回,如json或xml格式。 @ModelAttribute:用于把參數保存到model中,可以注解方法或參數,注解在方法上的時候,該方法將在處理器方法執行之前執行,然后把返回的對象存放在 session(前提時要有@SessionAttributes注解) 或模型屬性中,@ModelAttribute(“attributeName”) 在標記方法的時候指定,若未指定,則使用返回類型的類名稱(首字母小寫)作為屬性名稱。

 

8.4SpringMVC的控制器是不是單例,如果是,有什么問題,怎么解決?

是單例,所以在多線程訪問的時候有線程安全問題,不要用同步,會影響性能的,解決方案是在控制器里面不能寫字段。

 

8.5談談你對RESTful的理解?

一種軟件架構風格、設計風格,而不是標準,只是提供了一組設計原則和約束條件。它主要用于客戶端和服務器交互類的軟件。基于這個風格設計的軟件可以更簡潔,更有層次,更易于實現緩存等機制。 REST 指的是一組架構約束條件和原則。滿足這些約束條件和原則的應用程序或設計就是 RESTful。 REST被翻譯為“表現層狀態轉換”,具體來說,就是HTTP協議里面,四個表示操作方式的動詞:GET、POST、PUT、DELETE。它們分別對應四種基本操作:GET用來獲取資源,POST用來新建資源(也可以用于更新資源),PUT用來更新資源,DELETE用來刪除資源。使用REST編程風格要求URL中不允許出現動詞。

 

8.6如何解決POST請求中文亂碼問題,GET的又如何處理呢?

POST亂碼:web.xml文件中添加以下配置 CharacterEncodingFilter org.springframework.web.filter.CharacterEncodingFilter encoding utf-8 CharacterEncodingFilter /* GET亂碼,修改Tomcat服務器server.xml文件:    

 

9.并發編程專題

 

9.1你進行過壓測嗎,怎么進行的?  

 

 

10.Redis專題

 

10.1Redis你在項目中哪里使用了,用來解決什么問題?

 

10.2Redis支持哪些數據類型?

 

10.3什么是Redis持久化?Redis有哪幾種持久化方式?優缺點是什么?

 

10.4什么是緩存穿透,如何避免?什么是緩存雪崩,如何避免?

 

10.5數據庫和Redis緩存數據一致性問題,你是怎么解決的?

 

10.6Redis有哪幾種數據淘汰策略?

 

10.7Redis有哪些適合的場景?

(1)會話緩存(Session Cache)最常用的一種使用Redis的情景是會話緩存(session cache)。 用Redis緩存會話比其他存儲(如Memcached)的優勢在于:Redis提供持久化。當維護一個不是嚴格要求一致性的緩存時,如果用戶的購物車信息全部丟失,大部分人都會不高興的,現在,他們還會這樣嗎?幸運的是,隨著 Redis 這些年的改進,很容易找到怎么恰當的使用Redis來緩存會話的文檔。甚至廣為人知的商業平臺Magento也提供Redis的插件。

 

(2)全頁緩存(FPC)除基本的會話token之外,Redis還提供很簡便的FPC平臺。 回到一致性問題,即使重啟了Redis實例,因為有磁盤的持久化,用戶也不會看到頁面加載速度的下降,這是一個極大改進,類似PHP本地FPC。再次以Magento為例,Magento提供一個插件來使用Redis作為全頁緩存后端。此外,對WordPress的用戶來說,Pantheon有一個非常好的插件 wp-redis,這個插件能幫助你以最快速度加載你曾瀏覽過的頁面。

 

(3)隊列Reids在內存存儲引擎領域的一大優點是提供 list 和 set 操作,這使得Redis能作為一個很好的消息隊列平臺來使用。 Redis作為隊列使用的操作,就類似于本地程序語言(如Python)對 list 的 push/pop 操作。如果你快速的在Google中搜索“Redis queues”,你馬上就能找到大量的開源項目,這些項目的目的就是利用Redis創建非常好的后端工具,以滿足各種隊列需求。例如,Celery有一個后臺就是使用Redis作為broker,你可以從這里去查看。

 

(4)排行榜/計數器Redis在內存中對數字進行遞增或遞減的操作實現的非常好。 集合(Set)和有序集合(Sorted Set)也使得我們在執行這些操作的時候變的非常簡單,Redis只是正好提供了這兩種數據結構。所以,我們要從排序集合中獲取到排名最靠前的10個用戶–我們稱之為“user_scores”,我們只需要像下面一樣執行即可:當然,這是假定你是根據你用戶的分數做遞增的排序。如果你想返回用戶及用戶的分數,你需要這樣執行:ZRANGE user_scores 0 10 WITHSCORESAgora Games就是一個很好的例子,用Ruby實現的,它的排行榜就是使用Redis來存儲數據的,你可以在這里看到。

 

(5)發布/訂閱最后(但肯定不是最不重要的)是Redis的發布/訂閱功能。 發布/訂閱的使用場景確實非常多。我已看見人們在社交網絡連接中使用,還可作為基于發布/訂閱的腳本觸發器,甚至用Redis的發布/訂閱功能來建立聊天系統!    

 

11.Dubbo專題

 

11.1可以說一下你對Dubbo的理解嗎,什么是Dubbo?

Dubbo是阿里巴巴開源的基于 Java 的高性能 RPC 分布式服務框架,現已成為 Apache 基金會孵化項目。 因為是阿里開源項目,國內很多互聯網公司都在用,已經經過很多線上考驗。內部使用了 Netty、Zookeeper,保證了高性能高可用性。 使用 Dubbo 可以將核心業務抽取出來,作為獨立的服務,逐漸形成穩定的服務中心,可用于提高業務復用靈活擴展,使前端應用能更快速的響應多變的市場需求。 最重要的一點是,分布式架構可以承受更大規模的并發流量。比如某個服務并發量很大的話,可以針對此服務部署多臺服務器提高性能。

 

11.2Dubbo的實現原理?

 

11.3你對zookeeper是怎么理解的,為什么要用它?

 

11.4據你了解,zookeeper都能干什么?

 

11.5Dubbo支持負載均衡嗎,有哪些策略?

 

11.6Dubbo超時重試之后導致的數據重復怎么解決?

對于核心的服務中心,去除dubbo超時重試機制,并重新評估設置超時時間。業務處理代碼必須放在服務端,客戶端只做參數驗證和服務調用,不涉及業務流程處理。

 

11.7RPC是什么,你知道哪些RPC框架?

全部教程
广东36选7开奖公告