<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          面試必問(wèn)的 Spring,你懂了嗎?

          共 8186字,需瀏覽 17分鐘

           ·

          2020-11-24 10:22


          前言


          之前在?4 年 Java 經(jīng)驗(yàn)面試總結(jié)、心得體會(huì)?中列出了一些高頻面試題,這些題目大部分是我自己在面試中碰到過(guò)的、小部分是我覺(jué)得比較重要的,但是當(dāng)時(shí)并沒(méi)有給出答案,后面收到有不少同學(xué)留言說(shuō)希望給出答案。之前一直比較忙,所以沒(méi)時(shí)間出。

          最近換了工作后,沒(méi)之前壓力那么大了,所以想把這個(gè)之前留下的坑給填上。之后會(huì)針對(duì)這些題目按專題來(lái)給出對(duì)應(yīng)的解析,同時(shí)結(jié)合當(dāng)前的面試環(huán)境,適當(dāng)補(bǔ)充點(diǎn)當(dāng)前熱門題目。



          另外,針對(duì)這些面試題的重要程度/出現(xiàn)頻率,我會(huì)給出一個(gè)評(píng)分(1~10),分值越高代表出現(xiàn)的概率越大,其中8分及以上的可以認(rèn)為是高頻面試題,評(píng)分僅供參考。


          針對(duì) Spring 這個(gè)知識(shí)點(diǎn),面試中的重要程度綜合評(píng)分為8分。



          正文


          Spring IoC 的容器構(gòu)建流程(8分)


          核心的構(gòu)建流程如下,也就是 refresh 方法的核心內(nèi)容:




          Spring bean 的生命周期(10分)


          bean 的生命周期主要有以下幾個(gè)階段,深色底的5個(gè)是比較重要的階段。




          BeanFactory?和?FactoryBean 的區(qū)別(6分)


          BeanFactory:Spring 容器最核心也是最基礎(chǔ)的接口,本質(zhì)是個(gè)工廠類,用于管理 bean 的工廠,最核心的功能是加載 bean,也就是 getBean 方法,通常我們不會(huì)直接使用該接口,而是使用其子接口。


          FactoryBean:該接口以 bean 樣式定義,但是它不是一種普通的 bean,它是個(gè)工廠 bean,實(shí)現(xiàn)該接口的類可以自己定義要?jiǎng)?chuàng)建的 bean 實(shí)例,只需要實(shí)現(xiàn)它的 getObject 方法即可。


          FactoryBean 被廣泛應(yīng)用于 Java 相關(guān)的中間件中,如果你看過(guò)一些中間件的源碼,一定會(huì)看到 FactoryBean 的身影。


          一般來(lái)說(shuō),都是通過(guò)?FactoryBean#getObject?來(lái)返回一個(gè)代理類,當(dāng)我們觸發(fā)調(diào)用時(shí),會(huì)走到代理類中,從而可以在代理類中實(shí)現(xiàn)中間件的自定義邏輯,比如:RPC 最核心的幾個(gè)功能,選址、建立連接、遠(yuǎn)程調(diào)用,還有一些自定義的監(jiān)控、限流等等。



          BeanFactory?和?ApplicationContext 的區(qū)別(6分)


          BeanFactory:基礎(chǔ) IoC 容器,提供完整的 IoC 服務(wù)支持。


          ApplicationContext:高級(jí) IoC 容器,BeanFactory 的子接口,在 BeanFactory 的基礎(chǔ)上進(jìn)行擴(kuò)展。包含 BeanFactory 的所有功能,還提供了其他高級(jí)的特性,比如:事件發(fā)布、國(guó)際化信息支持、統(tǒng)一資源加載策略等。正常情況下,我們都是使用的 ApplicationContext。


          ?

          這邊以電話來(lái)舉個(gè)簡(jiǎn)單的例子:


          我們家里使用的 “座機(jī)”?就類似于 BeanFactory,可以進(jìn)行電話通訊,滿足了最基本的需求。


          而現(xiàn)在非常普及的智能手機(jī),iPhone、小米等,就類似于 ApplicationContext,除了能進(jìn)行電話通訊,還有其他很多功能:拍照、地圖導(dǎo)航、聽(tīng)歌等。



          Spring 的 AOP 是怎么實(shí)現(xiàn)的(5分)


          本質(zhì)是通過(guò)動(dòng)態(tài)代理來(lái)實(shí)現(xiàn)的,主要有以下幾個(gè)步驟。


          1、獲取增強(qiáng)器,例如被 Aspect 注解修飾的類。


          2、在創(chuàng)建每一個(gè) bean 時(shí),會(huì)檢查是否有增強(qiáng)器能應(yīng)用于這個(gè) bean,簡(jiǎn)單理解就是該 bean 是否在該增強(qiáng)器指定的?execution 表達(dá)式中。如果是,則將增強(qiáng)器作為攔截器參數(shù),使用動(dòng)態(tài)代理創(chuàng)建 bean 的代理對(duì)象實(shí)例。


          3、當(dāng)我們調(diào)用被增強(qiáng)過(guò)的 bean?時(shí),就會(huì)走到代理類中,從而可以觸發(fā)增強(qiáng)器,本質(zhì)跟攔截器類似。



          多個(gè)AOP的順序怎么定(6分)


          通過(guò) Ordered 和 PriorityOrdered 接口進(jìn)行排序。PriorityOrdered?接口的優(yōu)先級(jí)比 Ordered?更高,如果同時(shí)實(shí)現(xiàn)?PriorityOrdered?或?Ordered?接口,則再按 order 值排序,值越小的優(yōu)先級(jí)越高。



          Spring?的?AOP 有哪幾種創(chuàng)建代理的方式(9分)


          Spring 中的 AOP 目前支持?JDK 動(dòng)態(tài)代理和 Cglib 代理。


          通常來(lái)說(shuō):如果被代理對(duì)象實(shí)現(xiàn)了接口,則使用 JDK 動(dòng)態(tài)代理,否則使用 Cglib 代理。另外,也可以通過(guò)指定 proxyTargetClass=true 來(lái)實(shí)現(xiàn)強(qiáng)制走 Cglib 代理。



          JDK 動(dòng)態(tài)代理和 Cglib 代理的區(qū)別(9分)


          1、JDK 動(dòng)態(tài)代理本質(zhì)上是實(shí)現(xiàn)了被代理對(duì)象的接口,而 Cglib 本質(zhì)上是繼承了被代理對(duì)象,覆蓋其中的方法。


          2、JDK 動(dòng)態(tài)代理只能對(duì)實(shí)現(xiàn)了接口的類生成代理,Cglib 則沒(méi)有這個(gè)限制。但是 Cglib 因?yàn)槭褂美^承實(shí)現(xiàn),所以 Cglib 無(wú)法代理被 final 修飾的方法或類。


          3、在調(diào)用代理方法上,JDK 是通過(guò)反射機(jī)制調(diào)用,Cglib是通過(guò)FastClass 機(jī)制直接調(diào)用。FastClass 簡(jiǎn)單的理解,就是使用 index 作為入?yún)?,可以直接定位到要調(diào)用的方法直接進(jìn)行調(diào)用。


          4、在性能上,JDK1.7 之前,由于使用了 FastClass 機(jī)制,Cglib 在執(zhí)行效率上比 JDK 快,但是隨著 JDK 動(dòng)態(tài)代理的不斷優(yōu)化,從 JDK 1.7 開(kāi)始,JDK 動(dòng)態(tài)代理已經(jīng)明顯比 Cglib 更快了。



          JDK 動(dòng)態(tài)代理為什么只能對(duì)實(shí)現(xiàn)了接口的類生成代理(7分)


          根本原因是通過(guò) JDK 動(dòng)態(tài)代理生成的類已經(jīng)繼承了 Proxy 類,所以無(wú)法再使用繼承的方式去對(duì)類實(shí)現(xiàn)代理。



          Spring?的事務(wù)傳播行為有哪些(6分)


          1、REQUIRED:Spring 默認(rèn)的事務(wù)傳播級(jí)別,如果上下文中已經(jīng)存在事務(wù),那么就加入到事務(wù)中執(zhí)行,如果當(dāng)前上下文中不存在事務(wù),則新建事務(wù)執(zhí)行。


          2)REQUIRES_NEW:每次都會(huì)新建一個(gè)事務(wù),如果上下文中有事務(wù),則將上下文的事務(wù)掛起,當(dāng)新建事務(wù)執(zhí)行完成以后,上下文事務(wù)再恢復(fù)執(zhí)行。


          3)SUPPORTS:如果上下文存在事務(wù),則加入到事務(wù)執(zhí)行,如果沒(méi)有事務(wù),則使用非事務(wù)的方式執(zhí)行。


          4)MANDATORY:上下文中必須要存在事務(wù),否則就會(huì)拋出異常。


          5)NOT_SUPPORTED :如果上下文中存在事務(wù),則掛起事務(wù),執(zhí)行當(dāng)前邏輯,結(jié)束后恢復(fù)上下文的事務(wù)。


          6)NEVER:上下文中不能存在事務(wù),否則就會(huì)拋出異常。


          7)NESTED:嵌套事務(wù)。如果上下文中存在事務(wù),則嵌套事務(wù)執(zhí)行,如果不存在事務(wù),則新建事務(wù)。



          Spring 的事務(wù)隔離級(jí)別(6分)

          Spring 的事務(wù)隔離級(jí)別底層其實(shí)是基于數(shù)據(jù)庫(kù)的,Spring 并沒(méi)有自己的一套隔離級(jí)別。


          DEFAULT:使用數(shù)據(jù)庫(kù)的默認(rèn)隔離級(jí)別。


          READ_UNCOMMITTED:讀未提交,最低的隔離級(jí)別,會(huì)讀取到其他事務(wù)還未提交的內(nèi)容,存在臟讀。

          READ_COMMITTED:讀已提交,讀取到的內(nèi)容都是已經(jīng)提交的,可以解決臟讀,但是存在不可重復(fù)讀。

          REPEATABLE_READ:可重復(fù)讀,在一個(gè)事務(wù)中多次讀取時(shí)看到相同的內(nèi)容,可以解決不可重復(fù)讀,但是存在幻讀。

          SERIALIZABLE:串行化,最高的隔離級(jí)別,對(duì)于同一行記錄,寫(xiě)會(huì)加寫(xiě)鎖,讀會(huì)加讀鎖。在這種情況下,只有讀讀能并發(fā)執(zhí)行,其他并行的讀寫(xiě)、寫(xiě)讀、寫(xiě)寫(xiě)操作都是沖突的,需要串行執(zhí)行??梢苑乐古K讀、不可重復(fù)度、幻讀,沒(méi)有并發(fā)事務(wù)問(wèn)題。



          Spring 的事務(wù)隔離級(jí)別是如何做到和數(shù)據(jù)庫(kù)不一致的?(5分)


          比如數(shù)據(jù)庫(kù)是可重復(fù)讀,Spring 是讀已提交,這是怎么實(shí)現(xiàn)的?


          Spring 的事務(wù)隔離級(jí)別本質(zhì)上還是通過(guò)數(shù)據(jù)庫(kù)來(lái)控制的,具體是在執(zhí)行事務(wù)前先執(zhí)行命令修改數(shù)據(jù)庫(kù)隔離級(jí)別,命令格式如下:

          SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED



          Spring 事務(wù)的實(shí)現(xiàn)原理(8分)


          Spring 事務(wù)的底層實(shí)現(xiàn)主要使用的技術(shù):AOP(動(dòng)態(tài)代理) + ThreadLocal + try/catch。


          動(dòng)態(tài)代理:基本所有要進(jìn)行邏輯增強(qiáng)的地方都會(huì)用到動(dòng)態(tài)代理,AOP 底層也是通過(guò)動(dòng)態(tài)代理實(shí)現(xiàn)。


          ThreadLocal:主要用于線程間的資源隔離,以此實(shí)現(xiàn)不同線程可以使用不同的數(shù)據(jù)源、隔離級(jí)別等等。


          try/catch:最終是執(zhí)行 commit 還是 rollback,是根據(jù)業(yè)務(wù)邏輯處理是否拋出異常來(lái)決定。


          Spring 事務(wù)的核心邏輯偽代碼如下:

          public void invokeWithinTransaction() {    // 1.事務(wù)資源準(zhǔn)備    try {        // 2.業(yè)務(wù)邏輯處理,也就是調(diào)用被代理的方法    } catch (Exception e) {        // 3.出現(xiàn)異常,進(jìn)行回滾并將異常拋出    } finally {????????//?現(xiàn)場(chǎng)還原:還原舊的事務(wù)信息    }    // 4.正常執(zhí)行,進(jìn)行事務(wù)的提交    // 返回業(yè)務(wù)邏輯處理結(jié)果}


          詳細(xì)流程如下圖所示:




          Spring 怎么解決循環(huán)依賴的問(wèn)題(9分)


          Spring 是通過(guò)提前暴露 bean 的引用來(lái)解決的,具體如下。


          Spring 首先使用構(gòu)造函數(shù)創(chuàng)建一個(gè) “不完整”?的 bean 實(shí)例(之所以說(shuō)不完整,是因?yàn)榇藭r(shí)該 bean 實(shí)例還未初始化),并且提前曝光該 bean 實(shí)例的 ObjectFactory(提前曝光就是將 ObjectFactory 放到 singletonFactories 緩存).


          通過(guò) ObjectFactory 我們可以拿到該 bean 實(shí)例的引用,如果出現(xiàn)循環(huán)引用,我們可以通過(guò)緩存中的 ObjectFactory 來(lái)拿到 bean 實(shí)例,從而避免出現(xiàn)循環(huán)引用導(dǎo)致的死循環(huán)。


          舉個(gè)例子:A 依賴了 B,B 也依賴了 A,那么依賴注入過(guò)程如下。

          • 檢查 A 是否在緩存中,發(fā)現(xiàn)不存在,進(jìn)行實(shí)例化

          • 通過(guò)構(gòu)造函數(shù)創(chuàng)建 bean A,并通過(guò) ObjectFactory 提前曝光?bean A

          • A 走到屬性填充階段,發(fā)現(xiàn)依賴了 B,所以開(kāi)始實(shí)例化 B。

          • 首先檢查 B 是否在緩存中,發(fā)現(xiàn)不存在,進(jìn)行實(shí)例化

          • 通過(guò)構(gòu)造函數(shù)創(chuàng)建 bean B,并通過(guò) ObjectFactory 曝光創(chuàng)建的 bean B

          • B 走到屬性填充階段,發(fā)現(xiàn)依賴了 A,所以開(kāi)始實(shí)例化 A。

          • 檢查?A?是否在緩存中,發(fā)現(xiàn)存在,拿到?A 對(duì)應(yīng)的?ObjectFactory?來(lái)獲得 bean A,并返回。

          • B 繼續(xù)接下來(lái)的流程,直至創(chuàng)建完畢,然后返回 A 的創(chuàng)建流程,A 同樣繼續(xù)接下來(lái)的流程,直至創(chuàng)建完畢。


          這邊通過(guò)緩存中的 ObjectFactory 拿到的 bean 實(shí)例雖然拿到的是 “不完整”?的 bean 實(shí)例,但是由于是單例,所以后續(xù)初始化完成后,該 bean 實(shí)例的引用地址并不會(huì)變,所以最終我們看到的還是完整 bean 實(shí)例。



          Spring 能解決構(gòu)造函數(shù)循環(huán)依賴嗎(6分)


          答案是不行的,對(duì)于使用構(gòu)造函數(shù)注入產(chǎn)生的循環(huán)依賴,Spring 會(huì)直接拋異常。


          為什么無(wú)法解決構(gòu)造函數(shù)循環(huán)依賴?


          上面解決邏輯的第一句話:“首先使用構(gòu)造函數(shù)創(chuàng)建一個(gè) “不完整”?的 bean 實(shí)例”,從這句話可以看出,構(gòu)造函數(shù)循環(huán)依賴是無(wú)法解決的,因?yàn)楫?dāng)構(gòu)造函數(shù)出現(xiàn)循環(huán)依賴,我們連 “不完整”?的 bean 實(shí)例都構(gòu)建不出來(lái)。



          Spring 三級(jí)緩存(6分)


          Spring 的三級(jí)緩存其實(shí)就是解決循環(huán)依賴時(shí)所用到的三個(gè)緩存。


          singletonObjects:正常情況下的 bean 被創(chuàng)建完畢后會(huì)被放到該緩存,key:beanName,value:bean 實(shí)例。


          singletonFactories:上面說(shuō)的提前曝光的?ObjectFactory 就會(huì)被放到該緩存中,key:beanName,value:ObjectFactory。


          earlySingletonObjects:該緩存用于存放?ObjectFactory 返回的 bean,也就是說(shuō)對(duì)于一個(gè) bean,ObjectFactory 只會(huì)被用一次,之后就通過(guò)?
          earlySingletonObjects 來(lái)獲取,key:beanName,早期 bean 實(shí)例。



          @Resource 和 @Autowire 的區(qū)別(7分)


          1、@Resource 和 @Autowired 都可以用來(lái)裝配?bean


          2、@Autowired 默認(rèn)按類型裝配,默認(rèn)情況下必須要求依賴對(duì)象必須存在,如果要允許null值,可以設(shè)置它的required屬性為false。


          3、@Resource?如果指定了 name 或 type,則按指定的進(jìn)行裝配;如果都不指定,則優(yōu)先按名稱裝配,當(dāng)找不到與名稱匹配的 bean 時(shí)才按照類型進(jìn)行裝配。



          @Autowire 怎么使用名稱來(lái)注入(6分)


          配合 @Qualifier 使用,如下所示:


          @Componentpublic class Test {    @Autowired    @Qualifier("userService")    private UserService userService;}


          @PostConstruct 修飾的方法里用到了其他 bean 實(shí)例,會(huì)有問(wèn)題嗎(5分)


          該題可以拆解成下面3個(gè)問(wèn)題:


          1、@PostConstruct 修飾的方法被調(diào)用的時(shí)間


          2、bean 實(shí)例依賴的其他 bean?被注入的時(shí)間,也可理解為屬性的依賴注入時(shí)間


          3、步驟2的時(shí)間是否早于步驟1:如果是,則沒(méi)有問(wèn)題,如果不是,則有問(wèn)題



          解析:


          1、PostConstruct 注解被封裝在 CommonAnnotationBeanPostProcessor中,具體觸發(fā)時(shí)間是在 postProcessBeforeInitialization 方法,從 doCreateBean?維度看,則是在?initializeBean 方法里,屬于初始化?bean?階段


          2、屬性的依賴注入是在 populateBean 方法里,屬于屬性填充階段。


          3、屬性填充階段位于初始化之前,所以本題答案為沒(méi)有問(wèn)題。



          bean?的 init-method?屬性指定的方法里用到了其他?bean?實(shí)例,會(huì)有問(wèn)題嗎(5分)


          該題同上面這題類似,只是將 @PostConstruct?換成了 init-method 屬性。


          答案是不會(huì)有問(wèn)題。同上面一樣,init-method 屬性指定的方法也是在 initializeBean 方法里被觸發(fā),屬于初始化?bean?階段。



          要在 Spring?IoC 容器構(gòu)建完畢之后執(zhí)行一些邏輯,怎么實(shí)現(xiàn)(6分)


          1、比較常見(jiàn)的方法是使用事件監(jiān)聽(tīng)器,實(shí)現(xiàn) ApplicationListener 接口,監(jiān)聽(tīng) ContextRefreshedEvent 事件。


          2、還有一種比較少見(jiàn)的方法是實(shí)現(xiàn) SmartLifecycle 接口,并且 isAutoStartup 方法返回 true,則會(huì)在 finishRefresh() 方法中被觸發(fā)。


          兩種方式都是在 finishRefresh 中被觸發(fā),SmartLifecycle在ApplicationListener之前。



          Spring?中的常見(jiàn)擴(kuò)展點(diǎn)有哪些(5分)


          1、ApplicationContextInitializer

          initialize 方法,在 Spring 容器刷新前觸發(fā),也就是 refresh 方法前被觸發(fā)。


          2、BeanFactoryPostProcessor

          postProcessBeanFactory 方法,在加載完 Bean 定義之后,創(chuàng)建 Bean 實(shí)例之前被觸發(fā),通常使用該擴(kuò)展點(diǎn)來(lái)加載一些自己的 bean 定義。


          3、BeanPostProcessor

          postProcessBeforeInitialization 方法,執(zhí)行 bean 的初始化方法前被觸發(fā);postProcessAfterInitialization 方法,執(zhí)行 bean 的初始化方法后被觸發(fā)。


          4、@PostConstruct

          該注解被封裝在 CommonAnnotationBeanPostProcessor 中,具體觸發(fā)時(shí)間是在 postProcessBeforeInitialization 方法。


          5、InitializingBean

          afterPropertiesSet 方法,在 bean 的屬性填充之后,初始化方法(init-method)之前被觸發(fā),該方法的作用基本等同于 init-method,主要用于執(zhí)行初始化相關(guān)操作。


          6、ApplicationListener,事件監(jiān)聽(tīng)器

          onApplicationEvent 方法,根據(jù)事件類型觸發(fā)時(shí)間不同,通常使用的 ContextRefreshedEvent 觸發(fā)時(shí)間為上下文刷新完畢,通常用于 IoC 容器構(gòu)建結(jié)束后處理一些自定義邏輯。


          7、@PreDestroy

          該注解被封裝在 DestructionAwareBeanPostProcessor 中,具體觸發(fā)時(shí)間是在 postProcessBeforeDestruction 方法,也就是在銷毀對(duì)象之前觸發(fā)。


          8、DisposableBean

          destroy 方法,在 bean 的銷毀階段被觸發(fā),該方法的作用基本等同于
          destroy-method,主用用于執(zhí)行銷毀相關(guān)操作。


          Spring中如何讓兩個(gè)bean按順序加載?(8分)


          1、使用 @DependsOn、depends-on


          2、讓后加載的類依賴先加載的類

          @Componentpublic class A {    @Autowire    private B b;}


          3、使用擴(kuò)展點(diǎn)提前加載,例如:BeanFactoryPostProcessor

          @Componentpublic class TestBean implements BeanFactoryPostProcessor {  @Override  public void postProcessBeanFactory(ConfigurableListableBeanFactory           configurableListableBeanFactory) throws BeansException {      // 加載bean      beanFactory.getBean("a");  }



          使用 Mybatis 時(shí),調(diào)用 DAO接口時(shí)是怎么調(diào)用到 SQL 的(7分)


          詳細(xì)的解析見(jiàn):《面試題:mybatis 中的 DAO 接口和 XML 文件里的 SQL 是如何建立關(guān)系的?


          簡(jiǎn)單點(diǎn)說(shuō),當(dāng)我們使用 Spring+MyBatis 時(shí):


          1、DAO接口會(huì)被加載到 Spring 容器中,通過(guò)動(dòng)態(tài)代理來(lái)創(chuàng)建


          2、XML中的SQL會(huì)被解析并保存到本地緩存中,key是SQL 的 namespace + id,value 是SQL的封裝


          3、當(dāng)我們調(diào)用DAO接口時(shí),會(huì)走到代理類中,通過(guò)接口的全路徑名,從步驟2的緩存中找到對(duì)應(yīng)的SQL,然后執(zhí)行并返回結(jié)果



          最后


          現(xiàn)在的 Java 服務(wù)基本都是基于 Spring 來(lái)開(kāi)發(fā),Spring 的重要性不言而喻。


          想比于應(yīng)付面試,Spring 對(duì)于工作中的幫助會(huì)大的多。學(xué)習(xí) Spring 有助于解決工作中遇到的問(wèn)題、閱讀其他 Java 框架的源碼、學(xué)習(xí)優(yōu)秀的設(shè)計(jì)思想等等。


          原創(chuàng)不易,如果你覺(jué)得本文寫(xiě)的還不錯(cuò),對(duì)你有幫助,請(qǐng)通過(guò)點(diǎn)贊】【在看】【分享】【留言】讓我知道,支持我寫(xiě)出更好的文章,這對(duì)我很重要。



          推薦閱讀


          如何寫(xiě)一份讓 HR 眼前一亮的簡(jiǎn)歷(附模板)

          字節(jié)、美團(tuán)、快手核心部門面試總結(jié)(真題解析)

          面試阿里,HashMap 這一篇就夠了

          面試必問(wèn)的線程池,你懂了嗎?

          BATJTMD 面試必問(wèn)的 MySQL,你懂了嗎?

          如何準(zhǔn)備好一場(chǎng)大廠面試

          跳槽,如何選擇一家公司

          MySQL 8.0 MVCC 核心源碼解析

          4 年 Java 經(jīng)驗(yàn)面試總結(jié)、心得體會(huì)




          瀏覽 68
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  黄色电影视频网址 | 大香蕉伊在 | 男人的天堂青青草视频 | 精品传媒一区二区 | 草榴VA在线观看 |