<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                [TOC] ## JVM GC機制 **JVM GC 算法講解** **1、根搜索算法** 根搜索算法是從離散數學中的圖論引入的,程序把所有引用關系看作一張圖,從一個節點GC ROOT 開始,尋找對應的引用節點,找到這個節點后,繼續尋找這個節點的引用節點。當所有的引用節點尋找完畢后,剩余的節點則被認為是沒有被引用到的節點,即無用的節點。 ![](https://pic1.zhimg.com/80/v2-de35903caa0764079dc5980c21610cbc_720w.png) 上圖紅色為無用的節點,可以被回收。 目前Java中可以作為GC ROOT的對象有: 1、虛擬機棧中引用的對象(本地變量表) 2、方法區中靜態屬性引用的對象 3、方法區中常亮引用的對象 4、本地方法棧中引用的對象(Native對象) 基本所有GC算法都引用根搜索算法這種概念。 **2、標記 - 清除算法** ![](https://pic1.zhimg.com/80/v2-1e4e744442d9dc1adefd6805a1bfdea0_720w.png) 標記-清除算法采用從根集合進行掃描,**對存活的對象進行標記**,標記完畢后,再掃描整個空間中未被標記的對象進行直接回收,如上圖。 標記-清除算法不需要進行對象的移動,并且僅對不存活的對象進行處理,在存活的對象比較多的情況下極為高效,但由于標記-清除算法直接回收不存活的對象,并沒有對還存活的對象進行整理,因此會導致內存碎片。 **3、復制算法** ![](https://pic2.zhimg.com/80/v2-b95db02b09702215228e2dc5575f499d_720w.png) 復制算法將內存劃分為兩個區間,使用此算法時,所有動態分配的對象都只能分配在其中一個區間(活動區間),而另外一個區間(空間區間)則是空閑的。 復制算法采用從根集合掃描,將存活的對象復制到空閑區間,當掃描完畢活動區間后,會的將活動區間一次性全部回收。**此時原本的空閑區間變成了活動區間**。下次GC時候又會重復剛才的操作,以此循環。 復制算法在存活對象比較少的時候,極為高效,但是帶來的成本是犧牲一半的內存空間用于進行對象的移動。**所以復制算法的使用場景,必須是對象的存活率非常低才行**,而且最重要的是,我們需要克服50%內存的浪費。 **4、標記 - 整理算法** ![](https://pic1.zhimg.com/80/v2-c5ac27ceecebacef2d56cdcbc839cf2c_720w.png) 標記-整理算法采用 標記-清除 算法一樣的方式進行對象的標記、清除,但在回收不存活的對象占用的空間后,會將所有存活的對象往左端空閑空間移動,并更新對應的指針。標記-整理 算法是在標記-清除 算法之上,又進行了對象的移動排序整理,因此成本更高,但卻解決了內存碎片的問題。 JVM為了優化內存的回收,使用了分代回收的方式,對于新生代內存的回收(Minor GC)主要采用**復制算法**。而對于老年代的回收(Major GC),大多采用**標記-整理算法**。 ## redis刪除策略 可以設置內存最大使用量,當內存使用量超出時,會施行數據淘汰策略。 Redis 具體有 6 種淘汰策略: | 策略 | 描述 | | --- | --- | | volatile-lru | 從已設置過期時間的數據集中挑選最近最少使用的數據淘汰 | | volatile-ttl | 從已設置過期時間的數據集中挑選將要過期的數據淘汰 | | volatile-random | 從已設置過期時間的數據集中任意選擇數據淘汰 | | allkeys-lru | 從所有數據集中挑選最近最少使用的數據淘汰 | | allkeys-random | 從所有數據集中任意選擇數據進行淘汰 | | noeviction | 禁止驅逐數據 | 作為內存數據庫,出于對性能和內存消耗的考慮,Redis 的淘汰算法實際實現上并非針對所有 key,而是抽樣一小部分并且從中選出被淘汰的 key。 使用 Redis 緩存數據時,為了提高緩存命中率,需要保證緩存數據都是熱點數據。可以將內存最大使用量設置為熱點數據占用的內存量,然后啟用 allkeys-lru 淘汰策略,將最近最少使用的數據淘汰。 ## 限流令牌桶 令牌桶算法: 1,令牌按固定速率發放,生成的令牌放入令牌桶中。2,令牌桶有容量限制,當桶滿時,新生成的令牌會被丟棄。 3,請求到來時,先從令牌桶中獲取令牌,如果取得,則執行請求;如果令牌桶為空,則丟棄該請求。 令牌桶算法可以把請求平均分散在時間段內,是使用較為廣發的限流算法。 ## Java中的對象和引用 [https://www.zhihu.com/question/31203609/answer/50992895](https://www.zhihu.com/question/31203609/answer/50992895) ## kafka亂序解決 Kafka分布式的單位是partition,同一個partition用一個write ahead log組織,所以可以保證FIFO的順序。不同partition之間不能保證順序。 但是絕大多數用戶都可以通過message key來定義,因為同一個key的message可以保證只發送到同一個partition,比如說key是user id,table row id等等,所以同一個user或者同一個record的消息永遠只會發送到同一個partition上,保證了同一個user或record的順序。 [https://www.taosdata.com/blog/2019/10/08/922.html](https://www.taosdata.com/blog/2019/10/08/922.html) [https://blog.csdn.net/u012386386/article/details/79033040](https://blog.csdn.net/u012386386/article/details/79033040) ## rabbitMq如何保證均勻分發 使用 basicQos 方法,并將傳遞參數為 prefetchCount = 1。 這樣告訴 RabbitMQ 不要一次給一個工作線程多個消息。換句話說,在處理并確認前一個消息之前,不要向工作線程發送新消息。相反,它將發送到下一個還不忙的工作線程 ## 阻塞隊列實現原理 [https://zhuanlan.zhihu.com/p/56579882](https://zhuanlan.zhihu.com/p/56579882) [https://my.oschina.net/u/3464538/blog/4491417](https://my.oschina.net/u/3464538/blog/4491417)更好的理解 出入都要加鎖,所以是一把鎖兩個condition,用AtomicInteger 統計容量 可查看LinkedBlockingDeque類的代碼 ## 簡述下IOC加載過程 ### Ioc容器的加載過程簡單概括: 1.刷新預處理 2.將配置信息解析,注冊到BeanFactory 3.設置bean的類加載器 4.如果有第三方想再bean加載注冊完成后,初始化前做點什么(例如修改屬性的值,修改bean的scope為單例或者多例。),提供了相應的模板方法,后面還調用了這個方法的實現,并且把這些個實現類注冊到對應的容器中 5.初始化當前的事件廣播器 6.初始化所有的bean。(懶加載不執行這一步) 7.廣播applicationcontext初始化完成。 ### ps:BeanFactory 與 ApplicationContext區別 BeanFactory 看下去可以去做IOC當中的大部分事情,為什么還要去定義一個ApplicationContext 呢? ApplicationContext 它由BeanFactory接口派生而來,因而提供了BeanFactory所有的功能。除此之外context包還提供了以下的功能: 1.MessageSource, 提供國際化的消息訪問 2.資源訪問,如URL和文件 3.事件傳播,實現了ApplicationListener接口的bean 4.載入多個(有繼承關系)上下文 ,使得每一個上下文都專注于一個特定的層次,比如應用的web層 ##一條sql執行原理 ## 執行alter修改表結構,如何實現不鎖表? 概述 在 mysql 5.5 版本以前,修改表結構如添加索引、修改列,需要鎖表,期間不能寫入,對于大表這簡直是災難。從5.5特別是5.6里,情況有了好轉,支持Online DDL,pt-online-schema-change是Percona-toolkit一員,通過改進原生ddl的方式,達到不鎖表在線修改表結構。 1、pt-osc工作過程 1)創建一個和要執行 alter 操作的表一樣的新的空表結構(是alter之前的結構) 2)在新表執行alter table 語句(速度應該很快) 3)在原表中創建觸發器3個觸發器分別對應insert,update,delete操作 4)以一定塊大小從原表拷貝數據到臨時表,拷貝過程中通過原表上的觸發器在原表進行的寫操作都會更新到新建的臨時表 5)Rename 原表到old表中,在把臨時表Rename為原表 6)如果有參考該表的外鍵,根據alter-foreign-keys-method參數的值,檢測外鍵相關的表,做相應設置的處理 7)默認最后將舊原表刪除 4、使用 pt-osc原生 5.6 online ddl相比,如何選擇 online ddl在必須copy table時成本較高,不宜采用 pt-osc工具在存在觸發器時,不適用 修改索引、外鍵、列名時,優先采用online ddl,并指定 ALGORITHM=INPLACE 其它情況使用pt-?>,l;kh-osc,雖然存在copy data pt-osc比online ddl要慢一倍左右,因為它是根據負載調整的 無論哪種方式都選擇的業務低峰期執行 特殊情況需要利用主從特性,先alter從庫,主備切換,再改原主庫 ———————————————— ## HashMap為什么線程不安全? 擴容的時候,因為獲取數組桶下標時候 需要先1.獲取hash,2hash桶數取模或者(hash&(n-1) n為同數量),多線程的情況下不同線程可能會有擴容需求,而桶數量可能是不同的,這樣導致取到的數組桶下標不一樣,破壞了原子性 ## Thread.join的實現原理 https://www.cnblogs.com/barrywxx/p/10153776.html 1.join()方法是有`synchronized`修飾,**我們需要知道的是,調用wait方法必須要獲取鎖**,所以join方法是被synchronized修飾的 2.isAlive為true時說明沒有執行完,需要調用Object中的wait方法實現線程的阻塞 3.喚醒是在JVM hotspot中調用notify **總結**,Thread.join其實底層是通過wait/notifyall來實現線程的通信達到線程阻塞的目的;當線程執行結束以后,會觸發兩個事情,第一個是設置native線程對象為null、第二個是通過notifyall方法,讓等待在previousThread對象鎖上的wait方法被喚醒。 ## redis的hash結構是怎么擴容和rehash的 當hash內部的元素比較擁擠時(hash碰撞比較頻繁),就需要進行擴容。**擴容需要申請新的兩倍大小的數組,然后將所有的鍵值對重新分配到新的數組下標對應的鏈表中(rehash)**。如果hash結構很大,比如有上百萬個鍵值對,那么一次完整rehash的過程就會耗時很長。這對于單線程的Redis里來說有點壓力山大。所以**Redis采用了漸進式rehash的方案。它會同時保留兩個新舊hash結構,在后續的定時任務以及hash結構的讀寫指令中將舊結構的元素逐漸遷移到新的結構中。這樣就可以避免因擴容導致的線程卡頓現象**。 ## 分布式事務解決方案 ## 無界隊列和有界隊列區別 ## rabbitMq怎么保證高可用? 鏡像集群模式: 這種模式才是高可用模式. 與普通集群模式的主要區別在于. 無論queue的元數據還是queue中的消息都會同時存在與多個實例上. 設計集群的目的: 1. 允許消費者和生產者在RabbitMQ節點崩潰的情況下繼續運行 2. 通過增加更多的節點來擴展消息通信的吞吐量 要開啟鏡像集群模式,需要在后臺新增鏡像集群模式策略. 即要求數據同步到所有的節點.也可以指定同步到指定數量的節點. 這種方式的好處就在于, 任何一個服務宕機了,都不會影響整個集群數據的完整性, 因為其他服務中都有queue的完整數據, 當進行消息消費的時候,連接其他的服務器節點一樣也能獲取到數據. 缺點: 1: 性能開銷大: 因為需要進行整個集群內部所有實例的數據同步 2:無法線性擴容: 因為每一個服務器中都包含整個集群服務節點中的所有數據, 這樣如果一旦單個服務器節點的容量無法容納了怎么辦?. ## kafka中的CAP機制 CAP是不可能同時滿足的,所以在Kafka中也是一樣,也只能盡量滿足。Kafka只實現了CA,Partition tolerance是通過一定的機制盡量盡量滿足。 kafka首先將數據寫入到不同的分區里面去,每個分區又可能有好多個副本,數據首先寫入到leader分區里面去,讀寫的操作都是與leader分區進行通信,保證了數據的一致性原則,也就是滿足了Consistency原則。然后kafka通過分區副本機制,來保證了kafka當中數據的可用性。但是也存在另外一個問題,就是副本分區當中的數據與leader當中的數據存在差別的問題如何解決,這個就是Partition tolerance的問題。 kafka為了解決Partition tolerance的問題,使用了ISR的同步策略,來盡最大可能減少 Partition tolerance的問題。在leader分區中會維護一個ISR(a set of in-sync replicas,基本同步)列表,ISR列表主要的作用就是決定哪些副本分區是可用的,也就是說可以將leader分區里面的數據同步到副本分區里面去,決定一個副本分區是否可用的條件有兩個 ? replica.lag.time.max.ms=10000 副本分區與主分區心跳時間延遲 ? replica.lag.max.messages=4000 副本分區與主分區消息同步最大差 1 2 這里的意思就是說如果某個follower分區超過最大延遲時間還沒和leader進行心跳感知或者和leader分區的消息同步差值超過4000條,ISR就認為這個分區不可用了,就會把該分區從ISR中移除。 ## kafka文件存機制 https://blog.csdn.net/qq_41893274/article/details/112746898 ## Spring 中攔截器(Interceptor)與過濾器(Filter)的區別 ## mysql死鎖形成原因和解決方案 ## 熔斷機制,熔斷什么實現? ## 灰度如何實現。A/B testing、分流等設計方案了解嗎?
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看