工作3年去大廠面試Java開(kāi)發(fā),被Spring問(wèn)自閉了...

前言:

又到了金九銀十的日子,前幾天好朋友發(fā)來(lái)喜訊,跳槽一個(gè)月了,面試了有二十家公司,在面試官的狂轟濫炸下終于拿到了不錯(cuò)的offer。但是比較可惜的是朋友內(nèi)推的大廠面試失敗了,而且還是在Spring上,就令人挺無(wú)語(yǔ)的。他說(shuō)本來(lái)以為大廠的面試會(huì)問(wèn)一下高并發(fā)線程組件方面的知識(shí),所以就著重看了一下這些,沒(méi)想到栽倒了Spring上,真是太慘了!

所以今天我就總結(jié)一下幾個(gè)關(guān)于Spring的高頻面試題,比如:SpringAOP和aspectJ AOP有什么區(qū)別?springbean的生命周期?事務(wù)控制等,希望對(duì)大家有所幫助。

image

京東集團(tuán)

另外本人整理收藏了20年多家公司面試知識(shí)點(diǎn)整理 ,以及各種Java核心知識(shí)點(diǎn)免費(fèi)分享給大家,想要資料的話請(qǐng)私聊。

IOC

IOC(Inversion Of Controll,控制反轉(zhuǎn))是一種設(shè)計(jì)思想,將原本在程序中手動(dòng)創(chuàng)建對(duì)象的控制權(quán),交由給Spring框架來(lái)管理。IOC容器是Spring用來(lái)實(shí)現(xiàn)IOC的載體,IOC容器實(shí)際上就是一個(gè)Map(key, value),Map中存放的是各種對(duì)象。

這樣可以很大程度上簡(jiǎn)化應(yīng)用的開(kāi)發(fā),把應(yīng)用從復(fù)雜的依賴關(guān)系中解放出來(lái)。IOC容器就像是一個(gè)工廠,當(dāng)需要?jiǎng)?chuàng)建一個(gè)對(duì)象,只需要配置好配置文件/注解即可,不用考慮對(duì)象是如何被創(chuàng)建出來(lái)的,大大增加了項(xiàng)目的可維護(hù)性且降低了開(kāi)發(fā)難度。

AOP

AOP(Aspect-Oriented Programming,面向切面編程)能夠?qū)⒛切┡c業(yè)務(wù)無(wú)關(guān),卻為業(yè)務(wù)模塊所共同調(diào)用的邏輯或責(zé)任(例如事務(wù)處理、日志管理、權(quán)限控制等)封裝起來(lái),便于減少系統(tǒng)的重復(fù)代碼,降低模塊間的耦合度,并有利于未來(lái)的可擴(kuò)展性和可維護(hù)性。使用AOP之后我們可以把一些通用功能抽象出來(lái),在需要用到的地方直接使用即可,這樣可以大大簡(jiǎn)化代碼量,提高了系統(tǒng)的擴(kuò)展性。

Spring AOP是基于動(dòng)態(tài)代理的,如果要代理的對(duì)象實(shí)現(xiàn)了某個(gè)接口,那么Spring AOP就會(huì)使用JDK動(dòng)態(tài)代理去創(chuàng)建代理對(duì)象;而對(duì)于沒(méi)有實(shí)現(xiàn)接口的對(duì)象,就無(wú)法使用JDK動(dòng)態(tài)代理,轉(zhuǎn)而使用CGlib動(dòng)態(tài)代理生成一個(gè)被代理對(duì)象的子類(lèi)來(lái)作為代理。

image

<figcaption class="caption" contenteditable="false" style="outline: none; border-bottom: 1px solid rgb(228, 230, 232); max-width: 90%; min-width: 300px; margin: 0px auto; color: rgb(153, 153, 153); font-size: 14px; min-height: 22px; line-height: 1.5; padding: 10px 5px; cursor: text; display: inline-block;"></figcaption>

Spring AOP / AspectJ AOP 的區(qū)別?

Spring AOP屬于運(yùn)行時(shí)增強(qiáng),而AspectJ是編譯時(shí)增強(qiáng)。

Spring AOP基于代理(Proxying),而AspectJ基于字節(jié)碼操作(Bytecode Manipulation)。

AspectJ相比于Spring AOP功能更加強(qiáng)大,但是Spring AOP相對(duì)來(lái)說(shuō)更簡(jiǎn)單。如果切面比較少,那么兩者性能差異不大。但是,當(dāng)切面太多的話,最好選擇AspectJ,它比SpringAOP快很多。

Spring框架中都用到了哪些設(shè)計(jì)模式?

  1. 代理模式:在AOP和remoting中被用的比較多。

  2. 單例模式:在spring配置文件中定義的bean默認(rèn)為單例模式。

  3. 模板方法模式:用來(lái)解決代碼重復(fù)的問(wèn)題。

  4. 前端控制器模式:Spring提供了DispatcherServlet來(lái)對(duì)請(qǐng)求進(jìn)行分發(fā)。

  5. 依賴注入模式:貫穿于BeanFactory / ApplicationContext接口的核心理念。

  6. 工廠模式:BeanFactory用來(lái)創(chuàng)建對(duì)象的實(shí)例。

springmvc的核心是什么,請(qǐng)求的流程是怎么處理的,控制反轉(zhuǎn)怎么實(shí)現(xiàn)的

image

核心:控制反轉(zhuǎn)和面向切面

請(qǐng)求處理流程:

首先用戶發(fā)送請(qǐng)求到前端控制器,前端控制器根據(jù)請(qǐng)求信息(如URL)來(lái)決定選擇哪一個(gè)頁(yè)面控制器進(jìn)行處理并把請(qǐng)求委托給它,即以前的控制器的控制邏輯部分;
頁(yè)面控制器接收到請(qǐng)求后,進(jìn)行功能處理,首先需要收集和綁定請(qǐng)求參數(shù)到一個(gè)對(duì)象,并進(jìn)行驗(yàn)證,然后將命令對(duì)象委托給業(yè)務(wù)對(duì)象進(jìn)行處理;處理完畢后返回一個(gè)ModelAndView(模型數(shù)據(jù)和邏輯視圖名);
前端控制器收回控制權(quán),然后根據(jù)返回的邏輯視圖名,選擇相應(yīng)的視圖進(jìn)行渲染,并把模型數(shù)據(jù)傳入以便視圖渲染;
前端控制器再次收回控制權(quán),將響應(yīng)返回給用戶。
控制反轉(zhuǎn)如何實(shí)現(xiàn):

我們每次使用spring框架都要配置xml文件,這個(gè)xml配置了bean的id和class。
spring中默認(rèn)的bean為單實(shí)例模式,通過(guò)bean的class引用反射機(jī)制可以創(chuàng)建這個(gè)實(shí)例。
因此,spring框架通過(guò)反射替我們創(chuàng)建好了實(shí)例并且替我們維護(hù)他們。
A需要引用B類(lèi),spring框架就會(huì)通過(guò)xml把B實(shí)例的引用傳給了A的成員變量。

你用過(guò)哪些重要的 Spring 注解?

@Controller - 用于 Spring MVC 項(xiàng)目中的控制器類(lèi)。
@Service - 用于服務(wù)類(lèi)。
@RequestMapping - 用于在控制器處理程序方法中配置 URI 映射。
@ResponseBody - 用于發(fā)送 Object 作為響應(yīng),通常用于發(fā)送 XML 或 JSON 數(shù)據(jù)作為響應(yīng)。
@PathVariable - 用于將動(dòng)態(tài)值從 URI 映射到處理程序方法參數(shù)。
@Autowired - 用于在 spring bean 中自動(dòng)裝配依賴項(xiàng)。
@Qualifier - 使用 @Autowired 注解,以避免在存在多個(gè) bean 類(lèi)型實(shí)例時(shí)出現(xiàn)混淆。
@Scope - 用于配置 spring bean 的范圍。
@Configuration,@ComponentScan 和 @Bean - 用于基于 java 的配置。
@Aspect,@Before,@After,@Around,@Pointcut - 用于切面編程(AOP)。

@Component, @Controller, @Repository, @Service 有何區(qū)別?

  • @Component:這將 java 類(lèi)標(biāo)記為 bean。它是任何 Spring 管理組件的通用構(gòu)造型。spring
    的組件掃描機(jī)制現(xiàn)在可以將其拾取并將其拉入應(yīng)用程序環(huán)境中。

  • @Controller:這將一個(gè)類(lèi)標(biāo)記為 Spring Web MVC 控制器。標(biāo)有它的 Bean 會(huì)自動(dòng)導(dǎo)入到 IoC 容器中。

  • @Service:此注解是組件注解的特化。它不會(huì)對(duì) @Component 注解提供任何其他行為。您可以在服務(wù)層類(lèi)中使用

  • @Service 而不是 @Component,因?yàn)樗愿玫姆绞街付艘鈭D。

  • @Repository:這個(gè)注解是具有類(lèi)似用途和功能的 @Component 注解的特化。它為 DAO 提供了額外的好處。它將 DAO導(dǎo)入 IoC 容器,并使未經(jīng)檢查的異常有資格轉(zhuǎn)換為 Spring DataAccessException。

SpringMVC 流程?

1)用戶發(fā)送請(qǐng)求至前端控制器 DispatcherServlet。
2)DispatcherServlet 收到請(qǐng)求調(diào)用 HandlerMapping 處理器映射器。
3)處理器映射器找到具體的處理器(可以根據(jù) xml 配置、注解進(jìn)行查找),生成處理器及處理器攔截器(如果有則生成)一并返回給 DispatcherServlet。
4)DispatcherServlet 調(diào)用 HandlerAdapter 處理器適配器。
5)HandlerAdapter 經(jīng)過(guò)適配調(diào)用具體的處理器(Controller,也叫后端控制器)
6)Controller 執(zhí)行完成返回 ModelAndView。
7)HandlerAdapter 將 controller 執(zhí)行結(jié)果 ModelAndView 返回給 DispatcherServlet。8)DispatcherServlet 將 ModelAndView 傳給 ViewReslover 視圖解析器。
9)ViewReslover 解析后返回具體 View。
10)DispatcherServlet 根據(jù) View 進(jìn)行渲染視圖(即將模型數(shù)據(jù)填充至視圖中)。
11)DispatcherServlet 響應(yīng)用戶。

SpringMvc 怎么和 AJAX 相互調(diào)用的?

通過(guò) Jackson 框架就可以把 Java 里面的對(duì)象直接轉(zhuǎn)化成 Js 可以識(shí)別的 Json 對(duì)象具體步驟如下
1)加入 Jackson.jar
2)在配置文件中配置 json 的映射
3)在接受 Ajax 方法里面可以直接返回 Object,List 等,但方法前面要加上@ResponseB注解

有哪些不同類(lèi)型的依賴注入實(shí)現(xiàn)方式?

依賴注入是時(shí)下最流行的IoC實(shí)現(xiàn)方式,依賴注入分為接口注入(Interface Injection),Setter方法注入(Setter Injection)和構(gòu)造器注入(Constructor Injection)三種方式。其中接口注入由于在靈活性和易用性比較差,現(xiàn)在從Spring4開(kāi)始已被廢棄。

構(gòu)造器依賴注入:構(gòu)造器依賴注入通過(guò)容器觸發(fā)一個(gè)類(lèi)的構(gòu)造器來(lái)實(shí)現(xiàn)的,該類(lèi)有一系列參數(shù),每個(gè)參數(shù)代表一個(gè)對(duì)其他類(lèi)的依賴。

Setter方法注入:Setter方法注入是容器通過(guò)調(diào)用無(wú)參構(gòu)造器或無(wú)參static工廠 方法實(shí)例化bean之后,調(diào)用該bean的setter方法,即實(shí)現(xiàn)了基于setter的依賴注入。

Spring Beans

什么是Spring beans?

Spring beans 是那些形成Spring應(yīng)用的主干的java對(duì)象。它們被Spring IOC容器初始化,裝配,和管理。這些beans通過(guò)容器中配置的元數(shù)據(jù)創(chuàng)建。比如,以XML文件中 的形式定義。

一個(gè) Spring Bean 定義 包含什么?

一個(gè)Spring Bean 的定義包含容器必知的所有配置元數(shù)據(jù),包括如何創(chuàng)建一個(gè)bean,它的生命周期詳情及它的依賴。

如何給Spring 容器提供配置元數(shù)據(jù)?Spring有幾種配置方式

這里有三種重要的方法給Spring 容器提供配置元數(shù)據(jù)。

XML配置文件。
基于注解的配置。
基于java的配置。

Spring配置文件包含了哪些信息

Spring配置文件是個(gè)XML 文件,這個(gè)文件包含了類(lèi)信息,描述了如何配置它們,以及如何相互調(diào)用。

Spring基于xml注入bean的幾種方式

Set方法注入;
構(gòu)造器注入:①通過(guò)index設(shè)置參數(shù)的位置;②通過(guò)type設(shè)置參數(shù)類(lèi)型;
靜態(tài)工廠注入;
實(shí)例工廠;

關(guān)于事務(wù)控制

事務(wù)是一系列的動(dòng)作,它們綜合在一起才是一個(gè)完整的工作單元,這些動(dòng)作必須全部完成,如果有一個(gè)失敗的話,那么事務(wù)就會(huì)回滾到最開(kāi)始的狀態(tài),仿佛什么都沒(méi)發(fā)生過(guò)一樣。

1.1 spring中事務(wù)控制API
PlatformTransactionManager 接口提供事務(wù)操作的方法,包含三個(gè)具體的操作

public interface PlatformTransactionManager extends TransactionManager { // 獲取事務(wù)狀態(tài)信息 TransactionStatus getTransaction(@Nullable TransactionDefinition var1) throws TransactionException; // 提交事務(wù) void commit(TransactionStatus var1) throws TransactionException; // 回滾事務(wù) void rollback(TransactionStatus var1) throws TransactionException; }

開(kāi)發(fā)中常用的實(shí)現(xiàn)類(lèi):

org.springframework.jdbc.datasource.DataSourceTransactionManager :使用Spring JDBC或iBatis進(jìn)行持久化數(shù)據(jù)時(shí)使用

spring中事務(wù)控制接口的結(jié)構(gòu)

image

<figcaption class="caption" contenteditable="false" style="outline: none; border-bottom: 1px solid rgb(228, 230, 232); max-width: 90%; min-width: 300px; margin: 0px auto; color: rgb(153, 153, 153); font-size: 14px; min-height: 22px; line-height: 1.5; padding: 10px 5px; cursor: text; display: inline-block;"></figcaption>

1.1.2 TransactionDefinition

事務(wù)的定義信息對(duì)象,包含如下方法:

獲取事務(wù)對(duì)象名稱:String getName()

獲取事務(wù)隔離級(jí)別:int getIsolationLevel()

獲取事務(wù)傳播行為:int getPropagationBehavior()

獲取事務(wù)超時(shí)時(shí)間:int getTimeout()

獲取事務(wù)是否只讀:boolean isReadOnly()

1.1.3 TransactionStatus

描述了某個(gè)時(shí)間點(diǎn)上事務(wù)對(duì)象的狀態(tài)信息,包含6個(gè)具體的操作:

刷新事務(wù):void flush()

獲取是否存在儲(chǔ)存點(diǎn):boolean hasSavepoint()

獲取事務(wù)是否完成:boolean isCompleted()

獲取事務(wù)是否為新的事物:boolean isNewTransaction()

獲取事務(wù)是否回滾:boolean isRollbackOnly()

設(shè)置事務(wù)回滾:void set RollbackOnly()

1.2 事務(wù)的隔離級(jí)別

事務(wù)的隔離界別反映事務(wù)提交并發(fā)訪問(wèn)時(shí)的處理態(tài)度

1.2.1 事務(wù)隔離的級(jí)別

  • ISOLATION_DEFAULT 默認(rèn)級(jí)別,由 DBA 默認(rèn)的設(shè)置來(lái)決定隔離級(jí)別,歸屬下列某一種

  • ISOLATION_READ_UNCOMMITTED 就是一個(gè)事務(wù)可以讀取另一個(gè)未提交事務(wù)的數(shù)據(jù)。會(huì)出現(xiàn)臟讀、不可重復(fù)讀、幻讀(隔離級(jí)別最低,但并發(fā)性高)

  • ISOLATION_READ_COMMITTED 就是一個(gè)事務(wù)要等另一個(gè)事務(wù)提交后才能讀取數(shù)據(jù),解決臟讀問(wèn)題。會(huì)出現(xiàn)不可重復(fù)讀、幻讀問(wèn)題(鎖定正在讀取的行,適用于大多數(shù)系統(tǒng),Oracle默認(rèn)級(jí)別)

  • ISOLATION_REPEATABLE_READ 就是在開(kāi)始讀取數(shù)據(jù)(事務(wù)開(kāi)啟)時(shí),不再允許修改操作,解決不可重復(fù)讀問(wèn)題。會(huì)出現(xiàn)幻讀問(wèn)題(鎖定所讀的所有行,MYSQL默認(rèn)級(jí)別)

  • ISOLATION_SERALZABLE 是最高的事務(wù)隔離級(jí)別,在該級(jí)別下,事務(wù)串行化順序執(zhí)行,可以避免臟讀、不可重復(fù)讀與幻讀。但是這種事務(wù)隔離級(jí)別效率低下,比較耗數(shù)據(jù)庫(kù)性能,一般不使用。

事務(wù)隔離級(jí)別由上到下依次提升,隔離級(jí)別越高,越能保證數(shù)據(jù)的完整性和一致性。但對(duì)數(shù)據(jù)庫(kù)性能的消耗依次增加,并發(fā)執(zhí)行效率依次下降。

大多數(shù)的數(shù)據(jù)庫(kù)默認(rèn)隔離級(jí)別為 Read Commited,比如 SqlServer、Oracle

少數(shù)數(shù)據(jù)庫(kù)默認(rèn)隔離級(jí)別為:Repeatable Read 比如:MySQL InnoDB

1.2.2 數(shù)據(jù)庫(kù)讀取時(shí)會(huì)出現(xiàn)的三種問(wèn)題

① Dirty reads:讀臟數(shù)據(jù)。

也就是說(shuō),比如事務(wù)A的未提交(還依然緩存)的數(shù)據(jù)被事務(wù)B讀走,如果事務(wù)A失敗回滾,會(huì)導(dǎo)致事務(wù)B所讀取的的數(shù)據(jù)是錯(cuò)誤的。

② non-repeatable reads:數(shù)據(jù)不可重復(fù)讀。

比如事務(wù)A中兩處讀取數(shù)據(jù)price的值。在第一讀的時(shí)候,price是100,然后事務(wù)B就把price的值改成 200;事務(wù)A再讀一次,結(jié)果就發(fā)現(xiàn),price竟然就變成200了,造成事務(wù)A數(shù)據(jù)混亂。

③ phantom reads:幻象讀數(shù)據(jù)。

這個(gè)和non-repeatable reads相似,也是同一個(gè)事務(wù)中多次讀不一致的問(wèn)題。但是 non-repeatable reads 的不一致是因?yàn)樗〉臄?shù)據(jù)值被改變了(比如price)而 phantom reads 所要讀的數(shù)據(jù)的不一致卻是他的條件數(shù)據(jù)集發(fā)生變化了。

比如:執(zhí)行 Select account.id where account.name=“Bruce*”,第一次讀去了6個(gè)符合條件的id;第二次讀取的時(shí)候,由于事務(wù)B把一個(gè)帳號(hào)的名字由"dd"改成"Bruce1",結(jié)果取出來(lái)了7個(gè)數(shù)據(jù)。

不可重復(fù)讀的重點(diǎn)是修改:同樣的條件,兩次讀發(fā)現(xiàn)值不一樣;

幻讀的重點(diǎn)在于新增或者刪除:同樣的條件,兩次讀發(fā)現(xiàn)得到的記錄數(shù)不一樣

1.2.3 數(shù)據(jù)隔離級(jí)別和出現(xiàn)的問(wèn)題之間的關(guān)聯(lián)

image

1.3 事務(wù)的傳播行為

  • REQUIRED:如果當(dāng)前沒(méi)有事務(wù),就新建一個(gè)事務(wù),如果已經(jīng)存在一個(gè)事務(wù)中,加入到這個(gè)事務(wù)中。一般的選 擇(默認(rèn)值)

  • SUPPORTS:支持當(dāng)前事務(wù),如果當(dāng)前沒(méi)有事務(wù),就以非事務(wù)方式執(zhí)行(沒(méi)有事務(wù))

  • MANDATORY:使用當(dāng)前的事務(wù),如果當(dāng)前沒(méi)有事務(wù),就拋出異常。

  • REQUERS_NEW:新建事務(wù),如果當(dāng)前在事務(wù)中,把當(dāng)前事務(wù)掛起。

  • NOT_SUPPORTED:以非事務(wù)方式執(zhí)行操作,如果當(dāng)前存在事務(wù),就把當(dāng)前事務(wù)掛起。

  • NEVER:以非事務(wù)方式運(yùn)行,如果當(dāng)前存在事務(wù),拋出異常。

  • NESTED:如果當(dāng)前存在事務(wù),則在嵌套事務(wù)內(nèi)執(zhí)行。如果當(dāng)前沒(méi)有事務(wù),則執(zhí)行REQUIRED類(lèi)似的操作。

1.4 超時(shí)時(shí)間

指事務(wù)提交后最長(zhǎng)可以等待的時(shí)間,超出時(shí)間則會(huì)自動(dòng)失敗。默認(rèn)值是-1,沒(méi)有時(shí)間限制。如果有,則以秒為單位進(jìn)行設(shè)置。

1.5 是否為只讀事務(wù)

讀寫(xiě)型事務(wù):增加、刪除、修改時(shí)開(kāi)啟事務(wù)

只讀型事務(wù):執(zhí)行查詢時(shí),也會(huì)開(kāi)啟事務(wù)

面試總結(jié):

無(wú)論是哪家公司,都很重視Spring框架技術(shù),重視基礎(chǔ),所以千萬(wàn)別小看任何知識(shí)。面試是一個(gè)雙向選擇的過(guò)程,不要抱著畏懼的心態(tài)去面試,不利于自己的發(fā)揮。同時(shí)看中的應(yīng)該不止薪資,還要看你是不是真的喜歡這家公司,是不是能真的得到鍛煉。其實(shí)我寫(xiě)了這么多,只是我自己的總結(jié),并不一定適用于所有人,相信經(jīng)過(guò)一些面試,大家都會(huì)有這些感觸。

另外本人整理收藏了20年多家公司面試知識(shí)點(diǎn)整理 ,以及各種Java核心知識(shí)點(diǎn)免費(fèi)分享給大家,下方只是部分截圖 想要資料的話也可以私聊領(lǐng)取 暗號(hào)spring。

image
image
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容