Redis宕機數據丟失解決方案,不吃透都對不起自己

前言

昨天,有個女孩子問我提高數據庫查詢性能有什么立竿見影的好方法?

這簡直是一道送分題,我自豪且略帶鄙夷的說,當然是加「索引」了。

她又不緊不慢的問,索引為什么就能提高查詢性能。

這還用問,索引就像一本書的目錄,用目錄查當然很快。

她失望地搖了搖頭,你說的只是一個類比,可為什么通過目錄就能提高查詢速度呢。

唉,對啊,通過書目可以快速查詢,這只是一個現象,真正原因到底是什么呢。

那女孩看著詫異且表情僵硬的我,滿意而又意味深長的笑笑:原來你這個男程序員也不會,看來我還得靠自己研究了。

哎,熬夜又要憔悴了我這該死的美貌。

來自同行的羞辱,是可忍孰不可忍?!

于是,我踏上了數據庫索引學習的不歸路,原來數據庫索引使用了一種叫 B+ 樹的古老數據結構,當然也有 Hash 等類型,暫且不說,可 B+ 樹 這是個什么妖魔鬼怪呢?

下面就來淺嘗輒止的扒一扒樹的前世今生。

二、Spring生命周期的大膽猜測

這里分享一個閱讀源碼的小技巧:捉大放小,連蒙帶猜!8字真言,我們在閱讀源碼過程中,因為你要知道,每一個被開源出來的優秀框架,其源碼的體系都是極其龐大復雜的,我們不能面面俱到,所以在看源碼過程中一定不能被細枝末節纏住,一定要先理清楚整個框架的一個大致思想和大致的框架體系,再去搞那些細枝末節,其效率會好很多,其次在看源碼過程中,我們一定要大膽的去想,去猜測,如果這個功能讓你自己去寫,你會怎么實現!

我們今天學習SpringBean的生命周期也是按照這個8字真言去學習,通過我們之前所學,Spring大致有以下的功能:

  1. 他會幫我們自動的創建對象然后保存起來!
  2. 他會幫我們完成屬性的填充!
  3. 如果我們設置了Aop的功能,他會幫我們自動的代理,實現切面功能!

我們從平常的使用中,至少可以得知以上的三點,如果讓你自己去實現,必會如何實現呢?

  • 首先他既然能夠幫我們自己創建對象,那么他肯定是通過反射來創建的,通過反射來創建,就必定繞不過去要使用Class對象創建,那么我們如何獲取Class對象呢? 去掃描項目,將指定的包下的加了注解的類文件切割獲取Class名稱,通過反射加載Class名稱,反射創建java對象!
  • 我們要完成屬性的填充,為了方便和性能方面,我肯定會把這些創建好的對象保存起來,無疑Map容器是最合適的!
  • 我們在創建一個對象完成之后,反射拿到里面的屬性,如果需要填充,我們先去我們之前保存的容器里面去取,取不出來在反射吧這個依賴的屬性創建出來,然后填充進對象再保存在容器里面,從而完成了屬性的注入!
  • 填充完成屬性之后,我們那當前對象,取與Aop邏輯進行對比,判斷是否需要代理,不需要則創建完成,保存進Map容器,需要代理則對當前這個類進行jdk或者cglib的代理然后再保存進容器里面!

于是乎,我們自己實現了一個Spring管理一個Bean的所有過程,畫個圖,他大概長這樣!

自己實現看起來,整個流程就很清晰,掃描、創建、注入、代理、保存一應俱全,但是Spring的實現方式遠比我們自己實現的要復雜的多得多!

三、Spring的生命周期流程

Spring作者希望,Spring再著手管理一個Bean的時候,它希望能夠讓Spring的使用者能夠插手,Spring把一個類對象變成一個Java Object的每一步,怎么理解呢?

比如我們買了一棟新房子,這個房子需要取裝修,你自己去裝修誠然不夠專業,不能夠面面俱到,所以是我們就找了一個裝修公司幫助我們裝修新房,于是裝修公司就開始預先畫好的圖紙進行裝修,但是在裝修的過程中,你為了讓自己的新家更加溫馨,你想掛一些壁畫在墻上,但是圖紙上卻沒有!于是你就找裝修公司,要求裝修公司在新家的墻上掛上一些壁畫!裝修公司在接受到你的請求之后,就吩咐裝修的工人在圖紙之外去給你在墻上掛上壁畫之后,然后再接著裝修!

上面這個小故事有 這樣幾個角色,我們把它和Spring對照起來!

  • 你:代表框架的使用者!
  • 新房:代表一個Class文件,你自己也能夠裝修,但是不夠專業,所以交給裝修公司! 那么你自己創建對象可能某些使用用起來很麻煩,所以我們交給了Spring容器!
  • 裝修公司:代表著Spring容器!
  • 圖紙:代表預設步驟,Spring原本就存在的步驟!
  • 工人:Spring提供的各種接口!我們可以通過Spring工廠提供的接口做各種自定義的配置!

上面的小故事,大致可以描述Spring生命周期的核心思想!Spring再對一個Class文件實例化成具體的Spring Bean的時候,它提供了各種接口,由我們自己實現!然后再實例化過程中,不同的時機,去調用不同的接口!從而完成Spring的整個生命周期的創建!

Spring的生命周期大致分為以下部分!

  1. 掃描項目,將項目指定目錄下的Class文件轉換為Class對象!

  2. 讀取Class對象屬性包裝為BeanDefinition,然后保存再一個Map中!(不難理解,他是為了后續創建或者讀取這個類的信息更加方便取而創立的)

  3. 將全部的類轉化為 BeanDefinition 并保存之后,開始調用第一個回調接口BeanFactoryPostProcessor#postProcessBeanFactory()!

    • 它的調用時機是將掃描到的Class文件轉換為 BeanDefinition 之后調用的,我們可以通過回調的方法獲取所有的BeanDefinition ,而后續的所有對Class的操作都是基于BeanDefinition 操作的,所以,我們可以通過修改它,來改變后續的流程!
  4. 先從當前的容器對象取當前要創建的對象,當取出來的對象為null時開始著手創建對象!

  5. 做一系列的驗證,比如驗證這個類是否被排除、是否正在創建中、是否有依賴Bean【@DependsOn】注解、是否時單例等等!

  6. 驗證通過之后,開始通過反射創建這個對象!

  7. 合并BeanDefinition ,這里涉及到Spring之前版本使用的父子容器的概念,屬于另外一個知識點不做講解!

  8. 判斷當前對象是不是單例、是不是支持循環引用、是不是正在創建等!

  9. 執行第二個接口回調InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation()方法!

    • 它的執行時機時實例化完成之后,屬性填充之前,它的返回值是一個布爾值,當返回false時,不做自動屬性填充!
  10. 執行第三個接口回調InstantiationAwareBeanPostProcessor#postProcessProperties()方法!

    • 他的執行時機是,實例化之后,屬性填充檢查之后,屬性填充之前!它會返回一個屬性,后續的屬性填充會使用這個方法返回的值!我們可以在這個方法里面修改對應Bean的注入的值!
  11. 填充屬性到對象!

  12. 調用第四個回調接口BeanNameAware#setBeanName()方法!

    • 調用時機:屬性填充給完畢后,調用初始化方法之前;它的功能是能獲取bean的Name!
  13. 調用第五個回調接口BeanClassLoaderAware#setBeanClassLoader()

    • 調用時機:BeanNameAware之后,他的功能是傳入bean的類加載器;
  14. 調用第六個回調接口BeanFactoryAware#setBeanFactory()!

    • 調用時機:BeanClassLoaderAware之后,用于設置beanFactory!
  15. 調用第七個回調接口BeanPostProcessor#postProcessBeforeInitialization()方法

    • 調用時機是部分Aware之后,初始化方法之前!傳入當前實例化好的對象和beanName,再初始化前做修改!
  16. 回調第八個比較重要的生命周期的初始化方法,它可以是一個InitializingBean接口的bean,也可以是xml中配置的類,也可以是被加了@PostConstruct注解的方法!

    • 該方法內部邏輯可以用戶自己編寫,調用時機為:實例化完成之后調用!
  17. 回調第九個回調接口 BeanPostProcessor#postProcessAfterInitialization()方法!

    • 該方法的調用時機為初始化方法執行之后,這里也是Bean實例化后的最后一步,也是SpringAop實現的重要的一步!
  18. 注冊銷毀方法,以便Spring容器銷毀的時候進行方法的銷毀!

整體的方法流程示例圖如下:

四、對應源碼結構圖

最近我根據上述的技術體系圖搜集了幾十套騰訊、頭條、阿里、美團等公司21年的面試題,把技術點整理成了視頻(實際上比預期多花了不少精力),包含知識脈絡 + 諸多細節,由于篇幅有限,這里以圖片的形式給大家展示一部分

戳這里免費領取下面所有資料

由于篇幅有限,這里以圖片的形式給大家展示一部分

戳這里免費領取下面所有資料

[外鏈圖片轉存中…(img-2mwnR2T2-1624600758368)]

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/385896.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/385896.shtml
英文地址,請注明出處:http://en.pswp.cn/news/385896.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

c 加密 java解密錯誤_java解密出錯

展開全部你那個代碼少得東西太多,我左試右試,都是錯,也不知道你的初始32313133353236313431303231363533e78988e69d8331333332613762值都是什么。給你寫了一個加密解密的,希望對你有幫助。import java.security.NoSuchAlgorithmEx…

Redis成神之路電子版教程已問世,面試題+筆記+項目實戰

前言 我想對所有程序員說:除了看視頻、做項目來提高自身的技術之外,還有一種提升自己的專業技能就是:多!看!書!(本文內提到的書單筆者整理出了一份電子檔作為分享,文末有免費獲取方式…

java 中的event_Java中this與event有什么不同

Java中this與event有什么不同發布時間:2021-02-11 10:37:25來源:億速云閱讀:61作者:LeahJava中this與event有什么不同?相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法&#xff…

Redis有幾種數據類型?文末領取面試資料

前言 其實前幾篇文章已經寫了好多有關于Spring源碼的文章,事實上,很多同學雖然一直在跟著閱讀、學習這些Spring的源碼教程,但是一直都很迷茫,這些Spring的源碼學習,似乎只是為了面試吹逼用,我大概問過一些…

java 多重屬性_最全面的44個Java 性能調優細節

我認為,代碼優化的最重要的作用應該是:避免未知的錯誤。在代碼上線運行的過程中,往往會出現很多我們意想不到的錯誤,因為線上環境和開發環境是非常不同的,錯誤定位到最后往往是一個非常小的原因。然而為了解決這個錯誤…

Redis靈魂14問?真香

前言 今日博主聽聞,現在很多培訓出來的應屆生薪資都趕上了摸爬滾打兩三年的朋友,講道理,這說不過去啊 作為同行來說,這個行業發展很快,技術更新很快,淘汰也很快,千萬不要再找借口了&#xff0…

java主流微服務框架_Spring Boot作為當下最流行的微服務開發框架,一名合格的Java開發者一定有所了解,...

Spring Boot作為當下最流行的微服務開發框架,一名合格的Java開發者一定有所了解,Spring Boot相對于傳統的SSM框架來說:springboot使用了特定的配置方式,開發人員不需要再定義樣板化的配置,簡化項目的初始構建springboo…

Redis面試復習大綱在手面試不慌,內含福利

前言 這幾年在Java工程師招聘時,會看到很多人的簡歷都寫著使用了Spring Cloud做微服務實現,使用Docker做自動化部署,并且也會把這些做為自己的亮點。而比較有趣的這其中以小公司出來的人為絕大多數,大的公司出來的人簡歷上倒是很…

java注解編程_Java注解編程原理

一、先了解以下4個元注解Documented具體來說是生成說明文檔時把類的解釋添加進去。Inherited 允許子類繼承父類中的注解Target 表示該注解用于什么地方,可能的值在枚舉類 ElemenetType 中public enum ElementType {TYPE, //給類(型)注解FIELD, //給字段注解&#x…

Redis面試復習大綱在手面試不慌,講的明明白白!

前言 面試時間將近兩個小時(期間等待二面面試官來面我的時候等了半個多小時)面試官問的東西很多,還挖了好幾個坑,一個技術點套著一個技術點的問,一定要做好萬全的準備。問了一些基本層面上的技術點都答出來了&#xf…

python sendline_python Pexpect模塊的使用

Pexpect簡介在講解Pexpect之前,我們需要先了解一下Expect這個腳本語言,它是由TCL語言實現的,主要用于人機交互式對話的自動化控制,可以用來完成ssh、ftp、telnet等命令行程序的自動化交互。Pexpect其實就是一個用Python語言實現的…

RocketMQ消息丟失場景及解決辦法,已拿offer入職

前言 當前我們都會說SpringBoot是Spring框架對“約定優先于配置理念的最佳實踐的產物,一個典型的SpringBoot應用本質上其實就是一個基于Spring框架的應用,而如果大家對Spring框架已經了如指掌,那么,在我們一步步揭開SpringBoot微…

java抓rtp包_Wireshark抓取RTP包,還原語音

最近在做基于SIP的VoIP通信研究,使用Wireshark軟件可以對網絡流量進行抓包。VoIP使用RTP協議對語音數據進行傳輸,語音載荷都封裝在RTP包里面。要對傳輸中的語音進行截獲和還原,需要通過Wireshark對RTP包進行分析和解碼。該過程如下&#xff1…

RocketMQ消費者是如何獲取消息的?轉瘋了!

前言 前兩天,我收到了螞蟻金服的offer,從朋友的內推開始面試到拿到最后offer經歷了4面技術、一面交叉面和一面HR面。經過了漫長的等待和幾次幾乎折磨的面試之后,終于拿到了offer。 第1章:Dubbo的簡史、后續的規劃和整體架構大圖 …

java if在內存中_java如何將對象暫存到內存中?

展開全部form表單提交文件,建議用62616964757a686964616fe59b9ee7ad9431333264623862smartupload上傳,暫存在web服務器目錄下,然后稍微一下下面的代碼,ftp上傳后,刪除暫存文件,okimport java.io.File;impor…

K8S+Docker理論與實踐深度集成

前言: 這篇文章主要介紹了26道Spring經典面試題總結(附帶答案)的相關資料,小編在網上看到的覺得挺不錯的,現在分享給大家,希望對你們有所幫助。 另外本人整理收藏了多家公司面試知識點整理 ,以及各種Java核心知識點免費分享給大…

java 注解 方法 參數_java在注解中綁定方法參數的解決方案

我們有這樣子的需求,需要記錄用戶操作某個方法的信息并記錄到日志里面,例如,用戶在保存和更新任務的時候,我們需要記錄下用戶的ip,具體是保存還是更新,調用的是哪個方法,保存和更新的任務名稱以…

Kafka的精髓全寫這本“限量筆記”里了

前言 大廠面試真題向來是求職者的最佳練兵場,華為在Java開發工程師招聘中有哪些技術性考察和傾向?那今天咱就給大家分享一下近期的華為5面面經! 注:以下所分享的華為面試問題,相關的答案我也整理出來了,且…

gcc是java的什么意思_為什么gcc支持Java而不是C#

我已經seen this question了,我想知道是否有任何技術理由可以證明gcc支持Java但不支持C#.如果我理解,Java也是一種解釋性語言.如果Mono提供C#編譯器和CIL的實現,為什么不能創建一個將C#轉換為IL然后靜態編譯的gcc c#編譯器?解決方法:如果編譯器工具鏈不支持特定語言…

MongoDB數據分布不均的解決方案

前言 算法血拼:Google百度Alibaba字節Tencent網易360拼夕夕美團 不知不覺雙11就來了,轟轟烈烈的秋招也完美結束了,不知算法與數據結構成為了多少小伙伴進擊大廠的絆腳石? 恰好,我這兩天花了點時間,整理了些各大廠(G…