SSM面试题及相关答案
本文由公眾號【碼說TM】收錄
目錄
Spring
SpringMVC
Mybatis
Spring
1. Spring的概念
輕量級的IOC和AOP容器框架,能夠為Java應用程序提供基礎性服務,目的是簡化企業應用程序的開發,讓開發者專注于業務需求。有三種常見的配置方式,分別是基于XML、注解、Java的配置。
Spring擁有七大主要模塊:
Spring Core:核心庫,Spring所有功能都依賴于該庫。Core主要實現IOC功能,Spring所有的功能都是通過IOC實現的。
AOP:AOP=Aspect Oriented Programming,是OOP的延續,提供攔截器機制,用戶能夠自定義和配置攔截器。應用場景:日志記錄、性能統計、安全控制、事務處理、異常處理等等。
ORM:該模塊提供對ORM框架的管理和輔助支持。Spring本身并不對ORM進行實現,僅對常用的ORM框架(Hibernate、ibatis)進行封裝和管理。
DAO:Spring 提供對JDBC的支持,對JDBC進行封裝,允許JDBC使用Spring資源,并能統一管理JDBC事物,并不對JDBC進行實現。
WEB模塊:管理常見的WEB框架(Struts1,WEBWORK,JSF),將Spring的資源注入給框架,也可以在框架前后插入攔截器。
Context模塊:提供框架式的Bean訪問方式,其他程序可以通過Context訪問Spring的Bean資源,相當于資源注入。?
MVC模塊:該模塊為Spring提供了一套輕量級的MVC實現,相對于Struts,Spring自己的MVC框架更加簡潔和方便。
2. Spring的優點
? (1)低侵入式設計,代碼的污染極低;
(2)spring的DI機制將對象之間的依賴關系交由框架處理,減低組件的耦合性;
(3)提供了AOP技術,支持將一些通用任務,如安全、事務、日志、權限等進行集中式管理,從而提供更好的復用。
(4)spring對于主流的應用框架提供了集成支持。
3. BeanFactory和ApplicationContext有什么區別
BeanFactory和ApplicationContext是Spring的兩大核心接口,它們都可以當做Spring的容器。其中ApplicationContext是BeanFactory的子接口。
ApplicationContext接口作為BeanFactory的派生,除了提供BeanFactory所具有的功能外,還提供了更完整的框架功能:
(1)繼承MessageSource,因此支持國際化。
(2)統一的資源文件訪問方式。
(3)提供在監聽器中注冊bean的事件。
(4)同時加載多個配置文件。
(5)載入多個(有繼承關系)上下文 ,使得每一個上下文都專注于一個特定的層次,比如應用的web層。
BeanFactroy采用的是延遲加載形式來注入Bean的,即只有在使用到某個Bean時(調用getBean()),才對該Bean進行加載實例化。這樣,我們就不能發現一些存在的Spring的配置問題。如果Bean的某一個屬性沒有注入,BeanFacotry加載后,直至第一次使用調用getBean方法才會拋出異常;但是ApplicationContext在容器啟動時,一次性創建了所有的Bean。這樣,在容器啟動時,我們就可以發現Spring中存在的配置錯誤,這樣有利于檢查所依賴屬性是否注入。?ApplicationContext啟動后預載入所有的單實例Bean,通過預載入單實例bean ,確保當你需要的時候,你就不用等待,因為它們已經創建好了。
????????ApplicationContext 比BeanFactory占用更多的內存空間。當應用程序配置Bean較多時,程序啟動較慢。
BeanFactory通常以編程的方式被創建,ApplicationContext還能以聲明的方式創建,如使用ContextLoader。
BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的使用,但兩者之間的區別是:BeanFactory需要手動注冊,而ApplicationContext則是自動注冊。
4. 簡述Spring Bean的生命周期
(1)實例化Bean:當有客戶端請求一個未被初始化的bean時或者初始化bean的時候需要注入另一個尚未初始化的依賴時,BeanFactory會調用createBean進行初始化。ApplicationContext容器會在當容器啟動結束后,通過獲取BeanDefinition對象中的信息,實例化所有的bean。
(2)依賴注入:實例化之后的對象會被封裝在BeanWrapper中,然后Spring會根據BeanDefinition中的信息和BeanWrapper提供的設置屬性的接口完成依賴注入。
(3)處理Aware接口:Spring會檢測該對象是否實現了xxxAware接口,并將相關的xxxAware實例注入給Bean:
①如果這個Bean已經實現了BeanNameAware接口,會調用它實現的setBeanName(String beanId)方法,此處傳遞的就是Spring配置文件中Bean的id值;
②如果這個Bean已經實現了BeanFactoryAware接口,會調用它實現的setBeanFactory()方法,傳遞的是Spring工廠自身。
③如果這個Bean已經實現了ApplicationContextAware接口,會調用setApplicationContext(ApplicationContext)方法,傳入Spring上下文;
(4)BeanPostProcessor:該接口能夠通過postProcessBeforeInitialization(Object obj, String s)方法讓用戶能夠自定義處理Bean。由于這個方法是在Bean初始化結束時調用的,所以可以被應用于內存或緩存技術;
(5)InitializingBean?與?init-method:如果Bean在Spring配置文件中配置了init-method屬性,就會自動調用預先配置的初始化方法。至此,Bean完成了創建的所有步驟,之后就可以使用這個Bean了。
(6)DisposableBean:當Bean不再需要時,就會清洗這個Bean,如果Bean實現了DisposableBean這個接口,會調用其實現的destroy()方法;
(7)destroy-method:如果這個Bean的Spring配置中配置了destroy-method屬性,會自動調用其配置的銷毀方法。
5. 簡述Spring中bean的作用域
Spring容器中的bean可以分為5個范圍:
(1)singleton:默認,每個容器中只有一個bean的實例,單例的模式由BeanFactory自身來維護。
(2)prototype:為每一個bean請求提供一個實例。
(3)request:為每一個網絡請求創建一個實例,在請求完成以后,bean會失效并被垃圾回收器回收。
(4)session:與request范圍類似,確保每個session中有一個bean的實例,在session過期后,bean會隨之失效。
(5)global-session:全局作用域,global-session和Portlet應用相關。當你的應用部署在Portlet容器中工作時,它包含很多portlet。如果你想要聲明讓所有的portlet共用全局的存儲變量的話,那么這全局變量需要存儲在global-session中。全局作用域與Servlet中的session作用域效果相同。
6. Spring框架中的單例Beans是線程安全的嗎
Spring框架并沒有對單例bean進行任何多線程的封裝處理。大部分的Spring bean并沒有可變的狀態(比如Serview類和DAO類),所以在某種程度上說Spring的單例bean是線程安全的。如果你的bean有多種狀態的話,就需要自行保證線程安全。最淺顯的解決辦法就是將多態bean的作用域由“singleton”變更為“prototype”。
7. Spring如何處理線程并發問題
在一般情況下,只有無狀態的Bean才可以在多線程環境下共享,在Spring中,絕大部分Bean都可以聲明為singleton作用域,因為Spring對一些Bean中非線程安全狀態采用ThreadLocal進行處理,解決線程安全問題。
ThreadLocal和線程同步機制都是為了解決多線程中相同變量的訪問沖突問題。同步機制采用了“時間換空間”的方式,僅提供一份變量,不同的線程在訪問前需要獲取鎖,沒獲得鎖的線程則需要排隊。而ThreadLocal采用了“空間換時間”的方式。
ThreadLocal會為每一個線程提供一個獨立的變量副本,從而隔離了多個線程對數據的訪問沖突。因為每一個線程都擁有自己的變量副本,從而也就沒有必要對該變量進行同步了。ThreadLocal提供了線程安全的共享對象,在編寫多線程代碼時,可以把不安全的變量封裝進ThreadLocal。
8. Spring基于xml注入bean的幾種方式
(1)Set方法注入;
(2)構造器注入:①通過index設置參數的位置;②通過type設置參數類型;
(3)靜態工廠注入;
(4)實例工廠;
9. Spring的自動裝配
在spring中,對象無需自己查找或創建與其關聯的其他對象,由容器負責把需要相互協作的對象引用賦予各個對象,使用autowire來配置自動裝載模式。
在Spring框架xml配置中共有5種自動裝配:
(1)no:默認的方式是不進行自動裝配的,通過手工設置ref屬性來進行裝配bean。
(2)byName:通過bean的名稱進行自動裝配,如果一個bean的 property 與另一bean 的name 相同,就進行自動裝配。?
(3)byType:通過參數的數據類型進行自動裝配。
(4)constructor:利用構造函數進行裝配,并且構造函數的參數通過byType進行裝配。
(5)autodetect:自動探測,如果有構造方法,通過 construct的方式自動裝配,否則使用 byType的方式自動裝配。
10. Spring框架中用到了哪些設計模式
(1)工廠模式:BeanFactory就是簡單工廠模式的體現,用來創建對象的實例;
(2)單例模式:Bean默認為單例模式。
(3)代理模式:Spring的AOP功能用到了JDK的動態代理和CGLIB字節碼生成技術;
(4)模板方法:用來解決代碼重復的問題。比如.?RestTemplate,?JmsTemplate,?JpaTemplate。
(5)觀察者模式:定義對象鍵一種一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴于它的對象都會得到通知被制動更新,如Spring中listener的實現--ApplicationListener。
11. Spring 事務的實現方式和實現原理
Spring事務的本質其實就是數據庫對事務的支持,沒有數據庫的事務支持,spring是無法提供事務功能的。真正的數據庫層的事務提交和回滾是通過binlog或者redo log實現的。
(1)Spring事務的種類:
Spring支持編程式事務管理和聲明式事務管理兩種方式:
①編程式事務管理使用TransactionTemplate。
②聲明式事務管理建立在AOP之上的。其本質是通過AOP功能,對方法前后進行攔截,將事務處理的功能編織到攔截的方法中,也就是在目標方法開始之前加入一個事務,在執行完目標方法之后根據執行情況提交或者回滾事務。
(2)Spring的事務傳播行為:
Spring事務的傳播行為說的是,當多個事務同時存在的時候,Spring如何處理這些事務的行為。
① PROPAGATION_REQUIRED:如果當前沒有事務,就創建一個新事務,如果當前存在事務,就加入該事務,該設置是最常用的設置。
② PROPAGATION_SUPPORTS:支持當前事務,如果當前存在事務,就加入該事務,如果當前不存在事務,就以非事務執行。‘
③ PROPAGATION_MANDATORY:支持當前事務,如果當前存在事務,就加入該事務,如果當前不存在事務,就拋出異常。
④ PROPAGATION_REQUIRES_NEW:創建新事務,無論當前存不存在事務,都創建新事務。
⑤ PROPAGATION_NOT_SUPPORTED:以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。
⑥ PROPAGATION_NEVER:以非事務方式執行,如果當前存在事務,則拋出異常。
⑦ PROPAGATION_NESTED:如果當前存在事務,則在嵌套事務內執行。如果當前沒有事務,則按REQUIRED屬性執行。
(3)Spring中的隔離級別:
①?ISOLATION_DEFAULT:這是個?PlatfromTransactionManager?默認的隔離級別,使用數據庫默認的事務隔離級別。
②?ISOLATION_READ_UNCOMMITTED:讀未提交,允許另外一個事務可以看到這個事務未提交的數據。
③?ISOLATION_READ_COMMITTED:讀已提交,保證一個事務修改的數據提交后才能被另一事務讀取,而且能看到該事務對已有記錄的更新。
④?ISOLATION_REPEATABLE_READ:可重復讀,保證一個事務修改的數據提交后才能被另一事務讀取,但是不能看到該事務對已有記錄的更新。
⑤?ISOLATION_SERIALIZABLE:一個事務在執行的過程中完全看不到其他事務對數據庫所做的更新。
12. Spring在SSM中起什么作用
作用:Bean工廠,用來管理Bean的生命周期和框架集成。
兩大核心:(1)IOC/DI(控制反轉/依賴注入),Spring頂層容器為BeanFactory(2)AOP(面向切面編程)
13. IOC在項目中的作用
IOC解決對象之間的依賴問題,把所有Bean的依賴關系通過配置文件或注解關聯起來,降低耦合度。
14. Spring常用注解
注冊:@Controller @Service @Component
注入:@Autowired @Resource
請求地址:@RequestMapping
返回具體數據類型而非跳轉:@ResponseBody
15. Spring DI的三種方式
(1) 構造器注入:通過構造方法初始化
(2) setter方法注入:通過setter方法初始化
(3) 接口注入
SpringMVC
1. SpringMvc 的控制器是不是單例模式,如果是,有什么問題,怎么解決?
是單例模式,在多線程訪問時會有線程安全問題。解決這種問題,不能夠使用同步,并且不能再控制器中寫字段。
2. SpringMVC控制器注解
@Controller:該注解表明被注解類扮演控制器的角色。
3. @RequestMapping 注解用在類上的作用?
用來映射一個URL到一個類或者一個特定的處理方法上
4.?前臺多個參數,這些參數都是一個對象,快速得到對象?
直接在方法中聲明這個對象,SpringMVC就自動把屬性賦值到這個對象里面
5.?SpringMVC中如何轉發和重定向
(1)轉發:在返回值前面加"forward:"
(2)重定向:在返回值前面加"redirect:"
6.?SpringMVC和Ajax之間如何相互調用
通過JackSon框架把java里面對象直接轉換成js可識別的json對象,具體步驟如下:
(1) 加入JackSon.jar
(2) 在配置文件中配置json的映射
(3) 在接受Ajax方法里面直接返回Object,list等,方法前面需要加上注解@ResponseBody
7.?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. Struts2和SpringMVC的區別有哪些
| Filter過濾器 | 一個Servlet(前端控制器) |
| 基于類開發,通過類的屬性傳遞參數,只能設置為多例 | 基于方法開發(一個url對應一個方法),請求參數傳遞到方法形參,可以為單例也可以為多例(建議單例) |
| 值棧存儲請求和響應的數據,通過OGNL存取數據 | 通過參數解析器將request請求內容解析,給方法形參賦值,將數據和視圖封裝成ModelAndView對象,最后又將ModelAndView中的模型數據通過request域傳輸到頁面,jsp視圖解析器默認使用的是jstl。 |
9. 如何配置攔截器攔截get方法
在@RequestMapping注解里面加上method=RequestMethod.GET。
10.?怎樣在方法里面得到Request或Session
直接在方法的形參中聲明request,SpringMvc就自動把request對象傳入。
11.?SpringMVC使用什么對象從后臺向前臺傳遞數據
通過ModelMap對象,可以在這個對象里面調用put方法向其中添加對象,前臺可以通過el表達式拿到。
12. 注解的原理是什么
注解本質是一個繼承了Annotation的特殊接口,其具體實現類是Java運行時生成的動態代理類。通過反射獲取注解時,返回的是Java運行時生成的動態代理對象。通過代理對象調用自定義注解的方法,會最終調用AnnotationInvocationHandler的invoke方法。該方法會從memberValues這個Map中索引出對應的值。而memberValues的來源是Java常量池。
Mybatis
1.Mybatis優缺點
優點:
(1)基于SQL語句編程,相當靈活,不會對應用程序或者數據庫的現有設計造成任何影響,SQL寫在XML里,解除sql與程序代碼的耦合,便于統一管理;提供XML標簽,支持編寫動態SQL語句,并可重用。
(2)與JDBC相比,減少了50%以上的代碼量,消除了JDBC大量冗余的代碼,不需要手動開關連接;
(3)很好的與各種數據庫兼容(因為MyBatis使用JDBC來連接數據庫,所以只要JDBC支持的數據庫MyBatis都支持)。
(4)能夠與Spring很好的集成;
(5)提供映射標簽,支持對象與數據庫的ORM字段關系映射;提供對象關系映射標簽,支持對象關系組件維護。
缺點:
(1)SQL語句的編寫工作量較大,尤其當字段多、關聯表多時,對開發人員編寫SQL語句的功底有一定要求。
(2)SQL語句依賴于數據庫,導致數據庫移植性差,不能隨意更換數據庫。
2. Mybatis框架適用場合
對性能的要求很高,或者需求變化較多的項目
3.?MyBatis與Hibernate有哪些不同
(1)Mybatis和hibernate不同,它不完全是一個ORM框架,因為MyBatis需要程序員自己編寫Sql語句。
(2)Mybatis直接編寫原生態sql,可以嚴格控制sql執行性能,靈活度高,非常適合對關系數據模型要求不高的軟件開發,因為這類軟件需求變化頻繁,一但需求變化要求迅速輸出成果。但是靈活的前提是mybatis無法做到數據庫無關性,如果需要實現支持多種數據庫的軟件,則需要自定義多套sql映射文件,工作量大。?
(3)Hibernate對象/關系映射能力強,數據庫無關性好,對于關系模型要求高的軟件,如果用hibernate開發可以節省很多代碼,提高效率。?
4.?#{}和${}的區別是什么?
#{}是預編譯處理,${}是字符串替換。
Mybatis在處理#{}時,會將sql中的#{}替換為?號,調用PreparedStatement的set方法來賦值;
Mybatis在處理${}時,就是把${}替換成變量的值。
使用#{}可以有效的防止SQL注入,提高系統安全性。
5.?當實體類中的屬性名和表中的字段名不一樣時應當如何處理
兩種解決方案:
(1)通過在查詢的sql語句中定義字段名的別名,讓字段名的別名和實體類的屬性名一致。
(2)通過<resultMap>來映射字段名和實體類屬性名的一一對應的關系。
6.?Mybatis如何進行分頁
Mybatis使用RowBounds對象進行分頁,它是針對ResultSet結果集執行的內存分頁,而非物理分頁。可以在sql內直接書寫帶有物理分頁的參數來完成物理分頁功能,也可以使用分頁插件來完成物理分頁
7. 分頁插件的原理是什么
分頁插件的基本原理是使用Mybatis提供的插件接口,實現自定義插件,在插件的攔截方法內攔截待執行的sql,然后重寫sql,根據dialect方言,添加對應的物理分頁語句和物理分頁參數。
8.?Mybatis是如何將sql執行結果封裝為目標對象并返回的,都有哪些映射形式
第一種是使用<resultMap>標簽,逐一定義數據庫列名和對象屬性名之間的映射關系。
第二種是使用sql列的別名功能,將列的別名書寫為對象屬性名。
有了列名與屬性名的映射關系后,Mybatis通過反射創建對象,同時使用反射給對象的屬性逐一賦值并返回,那些找不到映射關系的屬性,是無法完成賦值的。
9.?Mybatis動態sql有什么用,執行原理是什么,總共有哪些動態sql
Mybatis動態sql可以在Xml映射文件內,以標簽的形式編寫動態sql,執行原理是根據表達式的值 完成邏輯判斷并動態拼接sql的功能。
Mybatis提供了9種動態sql標簽:trim 、where 、set 、foreach 、if ?choose 、when 、otherwise 、bind。
10.?Mybatis是否支持延遲加載
Mybatis僅支持association關聯對象和collection關聯集合對象的延遲加載,association指的就是一對一,collection指的就是一對多查詢。在Mybatis配置文件中,可以配置是否啟用延遲加載lazyLoadingEnabled=true|false。
它的原理是,使用CGLIB創建目標對象的代理對象,當調用目標方法時,進入攔截器方法,比如調用a.getB().getName(),攔截器invoke()方法發現a.getB()是null值,那么就會單獨發送事先保存好的查詢關聯B對象的sql,把B查詢上來,然后調用a.setB(b),于是a的對象b屬性就有值了,接著完成a.getB().getName()方法的調用。這就是延遲加載的基本原理。
11. Mybatis的一級、二級緩存
(1)一級緩存: 基于 PerpetualCache 的 HashMap 本地緩存,其存儲作用域為 Session,當 Session flush 或 close 之后,該 Session 中的所有 Cache 就將清空,默認打開一級緩存。
(2)二級緩存與一級緩存其機制相同,默認也是采用 PerpetualCache,HashMap 存儲,不同在于其存儲作用域為 Mapper(Namespace),并且可自定義存儲源,如 Ehcache。默認不打開二級緩存,要開啟二級緩存,使用二級緩存屬性類需要實現Serializable序列化接口(可用來保存對象的狀態),可在它的映射文件中配置<cache/> ;
(3)對于緩存數據更新機制,當某一個作用域(一級緩存 Session/二級緩存Namespaces)的進行了C/U/D 操作后,默認該作用域下所有 select 中的緩存將被 clear 掉并重新更新,如果開啟了二級緩存,則只根據配置判斷是否刷新。
12.?什么是MyBatis的接口綁定?有哪些實現方式
接口綁定,就是在MyBatis中任意定義接口,然后把接口里面的方法和SQL語句綁定,?我們直接調用接口方法就可以,這樣比起原來了SqlSession提供的方法我們可以有更加靈活的選擇和設置。
接口綁定有兩種實現方式,一種是通過注解綁定,就是在接口的方法上面加上?@Select、@Update等注解,里面包含Sql語句來綁定;另外一種就是通過xml里面寫SQL來綁定,?在這種情況下,要指定xml映射文件里面的namespace必須為接口的全路徑名。當Sql語句比較簡單時候,用注解綁定,?當SQL語句比較復雜時候,用xml綁定,一般用xml綁定的比較多。
13.使用MyBatis的mapper接口調用時有哪些要求
(1)Mapper接口方法名和mapper.xml中定義的每個sql的id相同;
(2)Mapper接口方法的輸入參數類型和mapper.xml中定義的每個sql 的parameterType的類型相同;
(3)Mapper接口方法的輸出參數類型和mapper.xml中定義的每個sql的resultType的類型相同;
(4)Mapper.xml文件中的namespace即是mapper接口的類路徑。
總結
以上是生活随笔為你收集整理的SSM面试题及相关答案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: azure linux 磁盘,在Azur
- 下一篇: D. Solve The Maze Co