摘要:我自己總結(jié)的學(xué)習(xí)的系統(tǒng)知識點以及面試問題,已經(jīng)開源,目前已經(jīng)。目前最新的版本中模塊的組件已經(jīng)被廢棄掉,同時增加了用于異步響應(yīng)式處理的組件。每一次請求都會產(chǎn)生一個新的,該僅在當(dāng)前內(nèi)有效。顯而易見,這種模式存在很多問題。
我自己總結(jié)的Java學(xué)習(xí)的系統(tǒng)知識點以及面試問題,已經(jīng)開源,目前已經(jīng) 41k+ Star。會一直完善下去,歡迎建議和指導(dǎo),同時也歡迎Star: https://github.com/Snailclimb...
這篇文章主要是想通過一些問題,加深大家對于 Spring 的理解,所以不會涉及太多的代碼!這篇文章整理了挺長時間,下面的很多問題我自己在使用 Spring 的過程中也并沒有注意,自己也是臨時查閱了很多資料和書籍補上的。網(wǎng)上也有一些很多關(guān)于 Spring 常見問題/面試題整理的文章,我感覺大部分都是互相 copy,而且很多問題也不是很汗,有些回答也存在問題。所以,自己花了一周的業(yè)余時間整理了一下,希望對大家有幫助。
什么是 Spring 框架?Spring 是一種輕量級開發(fā)框架,旨在提高開發(fā)人員的開發(fā)效率以及系統(tǒng)的可維護性。Spring 官網(wǎng):https://spring.io/。
我們一般說 Spring 框架指的都是 Spring Framework,它是很多模塊的集合,使用這些模塊可以很方便地協(xié)助我們進行開發(fā)。這些模塊是:核心容器、數(shù)據(jù)訪問/集成,、Web、AOP(面向切面編程)、工具、消息和測試模塊。比如:Core Container 中的 Core 組件是Spring 所有組件的核心,Beans 組件和 Context 組件是實現(xiàn)IOC和依賴注入的基礎(chǔ),AOP組件用來實現(xiàn)面向切面編程。
Spring 官網(wǎng)列出的 Spring 的 6 個特征:
核心技術(shù) :依賴注入(DI),AOP,事件(events),資源,i18n,驗證,數(shù)據(jù)綁定,類型轉(zhuǎn)換,SpEL。
測試 :模擬對象,TestContext框架,Spring MVC 測試,WebTestClient。
數(shù)據(jù)訪問 :事務(wù),DAO支持,JDBC,ORM,編組XML。
Web支持 : Spring MVC和Spring WebFlux Web框架。
集成 :遠程處理,JMS,JCA,JMX,電子郵件,任務(wù),調(diào)度,緩存。
語言 :Kotlin,Groovy,動態(tài)語言。
列舉一些重要的Spring模塊?下圖對應(yīng)的是 Spring4.x 版本。目前最新的5.x版本中 Web 模塊的 Portlet 組件已經(jīng)被廢棄掉,同時增加了用于異步響應(yīng)式處理的 WebFlux 組件。
Spring Core: 基礎(chǔ),可以說 Spring 其他所有的功能都需要依賴于該類庫。主要提供 IOC 依賴注入功能。
Spring Aspects : 該模塊為與AspectJ的集成提供支持。
Spring AOP :提供了面向方面的編程實現(xiàn)。
Spring JDBC : Java數(shù)據(jù)庫連接。
Spring JMS :Java消息服務(wù)。
Spring ORM : 用于支持Hibernate等ORM工具。
Spring Web : 為創(chuàng)建Web應(yīng)用程序提供支持。
Spring Test : 提供了對 JUnit 和 TestNG 測試的支持。
談?wù)勛约簩τ?Spring IoC 和 AOP 的理解 IoCIoC(Inverse of Control:控制反轉(zhuǎn))是一種設(shè)計思想,就是 將原本在程序中手動創(chuàng)建對象的控制權(quán),交由Spring框架來管理。 IoC 在其他語言中也有應(yīng)用,并非 Spirng 特有。 IoC 容器是 Spring 用來實現(xiàn) IoC 的載體, IoC 容器實際上就是個Map(key,value),Map 中存放的是各種對象。
將對象之間的相互依賴關(guān)系交給 IOC 容器來管理,并由 IOC 容器完成對象的注入。這樣可以很大程度上簡化應(yīng)用的開發(fā),把應(yīng)用從復(fù)雜的依賴關(guān)系中解放出來。 IOC 容器就像是一個工廠一樣,當(dāng)我們需要創(chuàng)建一個對象的時候,只需要配置好配置文件/注解即可,完全不用考慮對象是如何被創(chuàng)建出來的。 在實際項目中一個 Service 類可能有幾百甚至上千個類作為它的底層,假如我們需要實例化這個 Service,你可能要每次都要搞清這個 Service 所有底層類的構(gòu)造函數(shù),這可能會把人逼瘋。如果利用 IOC 的話,你只需要配置好,然后在需要的地方引用就行了,這大大增加了項目的可維護性且降低了開發(fā)難度。
Spring 時代我們一般通過 XML 文件來配置 Bean,后來開發(fā)人員覺得 XML 文件來配置不太好,于是 SpringBoot 注解配置就慢慢開始流行起來。
推薦閱讀:https://www.zhihu.com/questio...
Spring IOC的初始化過程:
IOC源碼閱讀
https://javadoop.com/post/spr...
AOPAOP(Aspect-Oriented Programming:面向切面編程)能夠?qū)⒛切┡c業(yè)務(wù)無關(guān),卻為業(yè)務(wù)模塊所共同調(diào)用的邏輯或責(zé)任(例如事務(wù)處理、日志管理、權(quán)限控制等)封裝起來,便于減少系統(tǒng)的重復(fù)代碼,降低模塊間的耦合度,并有利于未來的可拓展性和可維護性。
Spring AOP就是基于動態(tài)代理的,如果要代理的對象,實現(xiàn)了某個接口,那么Spring AOP會使用JDK Proxy,去創(chuàng)建代理對象,而對于沒有實現(xiàn)接口的對象,就無法使用 JDK Proxy 去進行代理了,這時候Spring AOP會使用Cglib ,這時候Spring AOP會使用 Cglib 生成一個被代理對象的子類來作為代理,如下圖所示:
當(dāng)然你也可以使用 AspectJ ,Spring AOP 已經(jīng)集成了AspectJ ,AspectJ 應(yīng)該算的上是 Java 生態(tài)系統(tǒng)中最完整的 AOP 框架了。
使用 AOP 之后我們可以把一些通用功能抽象出來,在需要用到的地方直接使用即可,這樣大大簡化了代碼量。我們需要增加新功能時也方便,這樣也提高了系統(tǒng)擴展性。日志功能、事務(wù)管理等等場景都用到了 AOP 。
Spring AOP 和 AspectJ AOP 有什么區(qū)別?Spring AOP 屬于運行時增強,而 AspectJ 是編譯時增強。 Spring AOP 基于代理(Proxying),而 AspectJ 基于字節(jié)碼操作(Bytecode Manipulation)。
Spring AOP 已經(jīng)集成了 AspectJ ,AspectJ 應(yīng)該算的上是 Java 生態(tài)系統(tǒng)中最完整的 AOP 框架了。AspectJ 相比于 Spring AOP 功能更加強大,但是 Spring AOP 相對來說更簡單,
如果我們的切面比較少,那么兩者性能差異不大。但是,當(dāng)切面太多的話,最好選擇 AspectJ ,它比Spring AOP 快很多。
Spring 中的 bean 的作用域有哪些?singleton : 唯一 bean 實例,Spring 中的 bean 默認(rèn)都是單例的。
prototype : 每次請求都會創(chuàng)建一個新的 bean 實例。
request : 每一次HTTP請求都會產(chǎn)生一個新的bean,該bean僅在當(dāng)前HTTP request內(nèi)有效。
session : 每一次HTTP請求都會產(chǎn)生一個新的 bean,該bean僅在當(dāng)前 HTTP session 內(nèi)有效。
global-session: 全局session作用域,僅僅在基于portlet的web應(yīng)用中才有意義,Spring5已經(jīng)沒有了。Portlet是能夠生成語義代碼(例如:HTML)片段的小型Java Web插件。它們基于portlet容器,可以像servlet一樣處理HTTP請求。但是,與 servlet 不同,每個 portlet 都有不同的會話
Spring 中的單例 bean 的線程安全問題了解嗎?大部分時候我們并沒有在系統(tǒng)中使用多線程,所以很少有人會關(guān)注這個問題。單例 bean 存在線程問題,主要是因為當(dāng)多個線程操作同一個對象的時候,對這個對象的非靜態(tài)成員變量的寫操作會存在線程安全問題。
常見的有兩種解決辦法:
在Bean對象中盡量避免定義可變的成員變量(不太現(xiàn)實)。
在類中定義一個ThreadLocal成員變量,將需要的可變成員變量保存在 ThreadLocal 中(推薦的一種方式)。
Spring 中的 bean 生命周期?這部分網(wǎng)上有很多文章都講到了,下面的內(nèi)容整理自:https://yemengying.com/2016/0... 。
Bean 容器找到配置文件中 Spring Bean 的定義。
Bean 容器利用 Java Reflection API 創(chuàng)建一個Bean的實例。
如果涉及到一些屬性值 利用 set()方法設(shè)置一些屬性值。
如果 Bean 實現(xiàn)了 BeanNameAware 接口,調(diào)用 setBeanName()方法,傳入Bean的名字。
如果 Bean 實現(xiàn)了 BeanClassLoaderAware 接口,調(diào)用 setBeanClassLoader()方法,傳入 ClassLoader對象的實例。
如果Bean實現(xiàn)了 BeanFactoryAware 接口,調(diào)用 setBeanClassLoader()方法,傳入 ClassLoade r對象的實例。
與上面的類似,如果實現(xiàn)了其他 *.Aware接口,就調(diào)用相應(yīng)的方法。
如果有和加載這個 Bean 的 Spring 容器相關(guān)的 BeanPostProcessor 對象,執(zhí)行postProcessBeforeInitialization() 方法
如果Bean實現(xiàn)了InitializingBean接口,執(zhí)行afterPropertiesSet()方法。
如果 Bean 在配置文件中的定義包含 init-method 屬性,執(zhí)行指定的方法。
如果有和加載這個 Bean的 Spring 容器相關(guān)的 BeanPostProcessor 對象,執(zhí)行postProcessAfterInitialization() 方法
當(dāng)要銷毀 Bean 的時候,如果 Bean 實現(xiàn)了 DisposableBean 接口,執(zhí)行 destroy() 方法。
當(dāng)要銷毀 Bean 的時候,如果 Bean 在配置文件中的定義包含 destroy-method 屬性,執(zhí)行指定的方法。
圖示:
與之比較類似的中文版本:
說說自己對于 Spring MVC 了解?談到這個問題,我們不得不提提之前 Model1 和 Model2 這兩個沒有 Spring MVC 的時代。
Model1 時代 : 很多學(xué) Java 后端比較晚的朋友可能并沒有接觸過 Model1 模式下的 JavaWeb 應(yīng)用開發(fā)。在 Model1 模式下,整個 Web 應(yīng)用幾乎全部用 JSP 頁面組成,只用少量的 JavaBean 來處理數(shù)據(jù)庫連接、訪問等操作。這個模式下 JSP 即是控制層又是表現(xiàn)層。顯而易見,這種模式存在很多問題。比如①將控制邏輯和表現(xiàn)邏輯混雜在一起,導(dǎo)致代碼重用率極低;②前端和后端相互依賴,難以進行測試并且開發(fā)效率極低;
Model2 時代 :學(xué)過 Servlet 并做過相關(guān) Demo 的朋友應(yīng)該了解“Java Bean(Model)+ JSP(View,)+Servlet(Controller) ”這種開發(fā)模式,這就是早期的 JavaWeb MVC 開發(fā)模式。Model:系統(tǒng)涉及的數(shù)據(jù),也就是 dao 和 bean。View:展示模型中的數(shù)據(jù),只是用來展示。Controller:處理用戶請求都發(fā)送給 ,返回數(shù)據(jù)給 JSP 并展示給用戶。
Model2 模式下還存在很多問題,Model2的抽象和封裝程度還遠遠不夠,使用Model2進行開發(fā)時不可避免地會重復(fù)造輪子,這就大大降低了程序的可維護性和復(fù)用性。于是很多JavaWeb開發(fā)相關(guān)的 MVC 框架營運而生比如Struts2,但是 Struts2 比較笨重。隨著 Spring 輕量級開發(fā)框架的流行,Spring 生態(tài)圈出現(xiàn)了 Spring MVC 框架, Spring MVC 是當(dāng)前最優(yōu)秀的 MVC 框架。相比于 Struts2 , Spring MVC 使用更加簡單和方便,開發(fā)效率更高,并且 Spring MVC 運行速度更快。
MVC 是一種設(shè)計模式,Spring MVC 是一款很優(yōu)秀的 MVC 框架。Spring MVC 可以幫助我們進行更簡潔的Web層的開發(fā),并且它天生與 Spring 框架集成。Spring MVC 下我們一般把后端項目分為 Service層(處理業(yè)務(wù))、Dao層(數(shù)據(jù)庫操作)、Entity層(實體類)、Controller層(控制層,返回數(shù)據(jù)給前臺頁面)。
Spring MVC 的簡單原理圖如下:
SpringMVC 工作原理了解嗎?原理如下圖所示:
上圖的一個筆誤的小問題:Spring MVC 的入口函數(shù)也就是前端控制器 DispatcherServlet 的作用是接收請求,響應(yīng)結(jié)果。
流程說明(重要):
客戶端(瀏覽器)發(fā)送請求,直接請求到 DispatcherServlet。
DispatcherServlet 根據(jù)請求信息調(diào)用 HandlerMapping,解析請求對應(yīng)的 Handler。
解析到對應(yīng)的 Handler(也就是我們平常說的 Controller 控制器)后,開始由 HandlerAdapter 適配器處理。
HandlerAdapter 會根據(jù) Handler 來調(diào)用真正的處理器開處理請求,并處理相應(yīng)的業(yè)務(wù)邏輯。
處理器處理完業(yè)務(wù)后,會返回一個 ModelAndView 對象,Model 是返回的數(shù)據(jù)對象,View 是個邏輯上的 View。
ViewResolver 會根據(jù)邏輯 View 查找實際的 View。
DispaterServlet 把返回的 Model 傳給 View(視圖渲染)。
把 View 返回給請求者(瀏覽器)
Spring 框架中用到了哪些設(shè)計模式?關(guān)于下面一些設(shè)計模式的詳細介紹,可以看筆主前段時間的原創(chuàng)文章《面試官:“談?wù)凷pring中都用到了那些設(shè)計模式?”?!?。
工廠設(shè)計模式 : Spring使用工廠模式通過 BeanFactory、ApplicationContext 創(chuàng)建 bean 對象。
代理設(shè)計模式 : Spring AOP 功能的實現(xiàn)。
單例設(shè)計模式 : Spring 中的 Bean 默認(rèn)都是單例的。
模板方法模式 : Spring 中 jdbcTemplate、hibernateTemplate 等以 Template 結(jié)尾的對數(shù)據(jù)庫操作的類,它們就使用到了模板模式。
包裝器設(shè)計模式 : 我們的項目需要連接多個數(shù)據(jù)庫,而且不同的客戶在每次訪問中根據(jù)需要會去訪問不同的數(shù)據(jù)庫。這種模式讓我們可以根據(jù)客戶的需求能夠動態(tài)切換不同的數(shù)據(jù)源。
觀察者模式: Spring 事件驅(qū)動模型就是觀察者模式很經(jīng)典的一個應(yīng)用。
適配器模式 :Spring AOP 的增強或通知(Advice)使用到了適配器模式、spring MVC 中也是用到了適配器模式適配Controller。
......
@Component 和 @Bean 的區(qū)別是什么?作用對象不同: @Component 注解作用于類,而@Bean注解作用于方法。
@Component通常是通過類路徑掃描來自動偵測以及自動裝配到Spring容器中(我們可以使用 @ComponentScan 注解定義要掃描的路徑從中找出標(biāo)識了需要裝配的類自動裝配到 Spring 的 bean 容器中)。@Bean 注解通常是我們在標(biāo)有該注解的方法中定義產(chǎn)生這個 bean,@Bean告訴了Spring這是某個類的示例,當(dāng)我需要用它的時候還給我。
@Bean 注解比 Component 注解的自定義性更強,而且很多地方我們只能通過 @Bean 注解來注冊bean。比如當(dāng)我們引用第三方庫中的類需要裝配到 Spring容器時,則只能通過 @Bean來實現(xiàn)。
@Bean注解使用示例:
@Configuration public class AppConfig { @Bean public TransferService transferService() { return new TransferServiceImpl(); } }
上面的代碼相當(dāng)于下面的 xml 配置
下面這個例子是通過 @Component 無法實現(xiàn)的。
@Bean public OneService getService(status) { case (status) { when 1: return new serviceImpl1(); when 2: return new serviceImpl2(); when 3: return new serviceImpl3(); } }將一個類聲明為Spring的 bean 的注解有哪些?
我們一般使用 @Autowired 注解自動裝配 bean,要想把類標(biāo)識成可用于 @Autowired 注解自動裝配的 bean 的類,采用以下注解可實現(xiàn):
@Component :通用的注解,可標(biāo)注任意類為 Spring 組件。如果一個Bean不知道屬于拿個層,可以使用@Component 注解標(biāo)注。
@Repository : 對應(yīng)持久層即 Dao 層,主要用于數(shù)據(jù)庫相關(guān)操作。
@Service : 對應(yīng)服務(wù)層,主要涉及一些復(fù)雜的邏輯,需要用到 Dao層。
@Controller : 對應(yīng) Spring MVC 控制層,主要用戶接受用戶請求并調(diào)用 Service 層返回數(shù)據(jù)給前端頁面。
Spring 管理事務(wù)的方式有幾種?編程式事務(wù),在代碼中硬編碼。(不推薦使用)
聲明式事務(wù),在配置文件中配置(推薦使用)
聲明式事務(wù)又分為兩種:
基于XML的聲明式事務(wù)
基于注解的聲明式事務(wù)
Spring 事務(wù)中的隔離級別有哪幾種?TransactionDefinition 接口中定義了五個表示隔離級別的常量:
TransactionDefinition.ISOLATION_DEFAULT: 使用后端數(shù)據(jù)庫默認(rèn)的隔離級別,Mysql 默認(rèn)采用的 REPEATABLE_READ隔離級別 Oracle 默認(rèn)采用的 READ_COMMITTED隔離級別.
TransactionDefinition.ISOLATION_READ_UNCOMMITTED: 最低的隔離級別,允許讀取尚未提交的數(shù)據(jù)變更,可能會導(dǎo)致臟讀、幻讀或不可重復(fù)讀
TransactionDefinition.ISOLATION_READ_COMMITTED: 允許讀取并發(fā)事務(wù)已經(jīng)提交的數(shù)據(jù),可以阻止臟讀,但是幻讀或不可重復(fù)讀仍有可能發(fā)生
TransactionDefinition.ISOLATION_REPEATABLE_READ: 對同一字段的多次讀取結(jié)果都是一致的,除非數(shù)據(jù)是被本身事務(wù)自己所修改,可以阻止臟讀和不可重復(fù)讀,但幻讀仍有可能發(fā)生。
TransactionDefinition.ISOLATION_SERIALIZABLE: 最高的隔離級別,完全服從ACID的隔離級別。所有的事務(wù)依次逐個執(zhí)行,這樣事務(wù)之間就完全不可能產(chǎn)生干擾,也就是說,該級別可以防止臟讀、不可重復(fù)讀以及幻讀。但是這將嚴(yán)重影響程序的性能。通常情況下也不會用到該級別。
Spring 事務(wù)中哪幾種事務(wù)傳播行為?支持當(dāng)前事務(wù)的情況:
TransactionDefinition.PROPAGATION_REQUIRED: 如果當(dāng)前存在事務(wù),則加入該事務(wù);如果當(dāng)前沒有事務(wù),則創(chuàng)建一個新的事務(wù)。
TransactionDefinition.PROPAGATION_SUPPORTS: 如果當(dāng)前存在事務(wù),則加入該事務(wù);如果當(dāng)前沒有事務(wù),則以非事務(wù)的方式繼續(xù)運行。
TransactionDefinition.PROPAGATION_MANDATORY: 如果當(dāng)前存在事務(wù),則加入該事務(wù);如果當(dāng)前沒有事務(wù),則拋出異常。(mandatory:強制性)
不支持當(dāng)前事務(wù)的情況:
TransactionDefinition.PROPAGATION_REQUIRES_NEW: 創(chuàng)建一個新的事務(wù),如果當(dāng)前存在事務(wù),則把當(dāng)前事務(wù)掛起。
TransactionDefinition.PROPAGATION_NOT_SUPPORTED: 以非事務(wù)方式運行,如果當(dāng)前存在事務(wù),則把當(dāng)前事務(wù)掛起。
TransactionDefinition.PROPAGATION_NEVER: 以非事務(wù)方式運行,如果當(dāng)前存在事務(wù),則拋出異常。
其他情況:
TransactionDefinition.PROPAGATION_NESTED: 如果當(dāng)前存在事務(wù),則創(chuàng)建一個事務(wù)作為當(dāng)前事務(wù)的嵌套事務(wù)來運行;如果當(dāng)前沒有事務(wù),則該取值等價于TransactionDefinition.PROPAGATION_REQUIRED。
參考《Spring 技術(shù)內(nèi)幕》
http://www.cnblogs.com/wmyskx...
https://www.journaldev.com/26...
https://www.edureka.co/blog/i...
https://howtodoinjava.com/int...
http://www.tomaszezula.com/20...
https://stackoverflow.com/que...
公眾號如果大家想要實時關(guān)注我更新的文章以及分享的干貨的話,可以關(guān)注我的公眾號。
《Java面試突擊》: 由本文檔衍生的專為面試而生的《Java面試突擊》V2.0 PDF 版本公眾號后臺回復(fù) "Java面試突擊" 即可免費領(lǐng)?。?/p>
Java工程師必備學(xué)習(xí)資源: 一些Java工程師常用學(xué)習(xí)資源公眾號后臺回復(fù)關(guān)鍵字 “1” 即可免費無套路獲取。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/74828.html
摘要:哪吒社區(qū)技能樹打卡打卡貼函數(shù)式接口簡介領(lǐng)域優(yōu)質(zhì)創(chuàng)作者哪吒公眾號作者架構(gòu)師奮斗者掃描主頁左側(cè)二維碼,加入群聊,一起學(xué)習(xí)一起進步歡迎點贊收藏留言前情提要無意間聽到領(lǐng)導(dǎo)們的談話,現(xiàn)在公司的現(xiàn)狀是碼農(nóng)太多,但能獨立帶隊的人太少,簡而言之,不缺干 ? 哪吒社區(qū)Java技能樹打卡?【打卡貼 day2...
摘要:作為面試官,我是如何甄別應(yīng)聘者的包裝程度語言和等其他語言的對比分析和主從復(fù)制的原理詳解和持久化的原理是什么面試中經(jīng)常被問到的持久化與恢復(fù)實現(xiàn)故障恢復(fù)自動化詳解哨兵技術(shù)查漏補缺最易錯過的技術(shù)要點大掃盲意外宕機不難解決,但你真的懂?dāng)?shù)據(jù)恢復(fù)嗎每秒 作為面試官,我是如何甄別應(yīng)聘者的包裝程度Go語言和Java、python等其他語言的對比分析 Redis和MySQL Redis:主從復(fù)制的原理詳...
摘要:作為面試官,我是如何甄別應(yīng)聘者的包裝程度語言和等其他語言的對比分析和主從復(fù)制的原理詳解和持久化的原理是什么面試中經(jīng)常被問到的持久化與恢復(fù)實現(xiàn)故障恢復(fù)自動化詳解哨兵技術(shù)查漏補缺最易錯過的技術(shù)要點大掃盲意外宕機不難解決,但你真的懂?dāng)?shù)據(jù)恢復(fù)嗎每秒 作為面試官,我是如何甄別應(yīng)聘者的包裝程度Go語言和Java、python等其他語言的對比分析 Redis和MySQL Redis:主從復(fù)制的原理詳...
摘要:請注意,我們在聊聊單元測試遇到問題多思考多查閱多驗證,方能有所得,再勤快點樂于分享,才能寫出好文章。單元測試是指對軟件中的最小可測試單元進行檢查和驗證。 JAVA容器-自問自答學(xué)HashMap 這次我和大家一起學(xué)習(xí)HashMap,HashMap我們在工作中經(jīng)常會使用,而且面試中也很頻繁會問到,因為它里面蘊含著很多知識點,可以很好的考察個人基礎(chǔ)。但一個這么重要的東西,我為什么沒有在一開始...
閱讀 1045·2023-04-26 01:47
閱讀 1709·2021-11-18 13:19
閱讀 2074·2019-08-30 15:44
閱讀 682·2019-08-30 15:44
閱讀 2339·2019-08-30 15:44
閱讀 1265·2019-08-30 14:06
閱讀 1444·2019-08-30 12:59
閱讀 1919·2019-08-29 12:49