国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

橘子學(xué)Mybatis07之Mybatis關(guān)于緩存的設(shè)計

這篇具有很好參考價值的文章主要介紹了橘子學(xué)Mybatis07之Mybatis關(guān)于緩存的設(shè)計。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

很逆天的一件事是,我上一次發(fā)mybatis是在2022年10月15號,然后直到今天才開始總結(jié)下一篇Mybatis的東西。一年里面忙成那啥了,而且重心都投入在了Elasticsearch的學(xué)習(xí)上面,基本一年下來都在搞ES,并且考下了ECE認(rèn)證,后續(xù)如果有時間,一直想寫一些es學(xué)習(xí)的總結(jié),分享一下。
現(xiàn)在貌似又要開始往管理崗位上面湊熱鬧了,以后可能會有多的時間來總結(jié)之前的一些學(xué)習(xí)了,這個不知道是好事還是壞事,這里就當(dāng)抱怨抱怨。哈哈。

一、緩存的意義

話不多說,我們來看Mybatis中的緩存,我們之前說過緩存,那還是在2022年的時候,我們知道m(xù)ybatis作為ORM框架,他的核心任務(wù)就是和數(shù)據(jù)庫打交道。
我們又知道你和數(shù)據(jù)庫打交道我們不說各家數(shù)據(jù)庫對于文件系統(tǒng)的實現(xiàn)是不是自身自帶緩存,他總歸是要和磁盤打交道的,涉及到很重的磁盤IO操作(別抬杠,別和我說硬件的進化,我說的是相對很重)。
而我們面對這種一般就是在業(yè)務(wù)設(shè)計的時候都會想到緩存,是的常見的就是Redis緩存,我們會把數(shù)據(jù)庫(磁盤中)的一部分?jǐn)?shù)據(jù)預(yù)先加載在緩存中,而緩存是內(nèi)存角度的操作,在內(nèi)存中操作數(shù)據(jù)是很輕量級的。以后我們每次讀數(shù)據(jù)庫的時候就在緩存里面放一份,下次再讀的時候就直接走緩存了,那么是不是就能提高請求的響應(yīng),提高業(yè)務(wù)的吞吐。
緩存中的數(shù)據(jù)在修改的時候也不需要直接就刷回磁盤,我們可以在一定時間頻率內(nèi)進行數(shù)據(jù)的寫磁盤,這樣對于你系統(tǒng)的吞吐也是很有提升的,當(dāng)然前提是你能容忍一定的數(shù)據(jù)丟失問題。這些大概就是緩存的意義,但是實現(xiàn)起來卻并不容易,數(shù)據(jù)的一致性,數(shù)據(jù)的持久化,緩存的大小導(dǎo)致的數(shù)據(jù)換出,內(nèi)存中存儲的大小,這都是我們在設(shè)計的時候需要考慮的,如果你想知道一些擴展的東西,可以去看redis的實現(xiàn)。這里不多展開說了。

既然知道了緩存的大致意義,他可以做到減少和磁盤IO的交互,轉(zhuǎn)為和內(nèi)存的交互,這樣就能減少我們的性能開支。那么mybatis是和數(shù)據(jù)庫打交道的,那么他是不是可以加入關(guān)于緩存的設(shè)計呢,答案是可以,他確實這么設(shè)計了一套接口API,并且以接口的形式暴露出來,方面我們自己進行擴展,你可以很方便的就擴展為你們自己的redis架構(gòu)。

二、Mybatis中緩存的設(shè)計

mybatis中緩存是設(shè)計為接口的形式,方便后面的擴展和實現(xiàn)?,F(xiàn)在我們就來看一下這個擴展接口。
這個接口的位置是org.apache.ibatis.cache.Cache類,我們可以看到他是ibatis包中的一個接口。
這個接口有諸多的方法,我們可以借助idea的ctrl+F12組合鍵來看一下。
如何查找應(yīng)用文件緩存位置,SSM,# Mybatis,JAVA,mybatis,java
我們看到他作為緩存的頂層接口,實際上就約定了緩存操作的一些基礎(chǔ)操作,看了一下也其實就那么回事吧。無外乎就是怎么把數(shù)據(jù)放入緩存(putObject),怎么把數(shù)據(jù)從緩存里面取出來(getObject),怎么把數(shù)據(jù)從緩存中移除出去(removeObject),怎么清除緩存(clear),其他的基本也是圍繞這幾個操作展開的一些更加細(xì)化的操作,我們說其實不用看他這個代碼也能想到他就是這么些個功能。
原諒我這里再次吐槽一下,mybatis的源碼注釋,真的少。我的建議是要不干脆別加了。

這里需要額外說一件事就是那個getReadWriteLock這個方法,看著意思是獲取讀寫鎖,但是我們看一下源碼:

/**
   * 從3.2.6開始,mybatis已經(jīng)移除了這個方法,所以其實他不重要。
   * Optional. As of 3.2.6 this method is no longer called by the core.
   * 
   * 以后的鎖需要由提供緩存的人來維護這個并發(fā)安全,所以如果你怕麻煩,那我推薦你使用redis,服務(wù)端寫入單線程,沒有這個苦惱,我們一直都用它。
   * Any locking needed by the cache must be provided internally by the cache provider.
   *
   * @return A ReadWriteLock
   */
  default ReadWriteLock getReadWriteLock() {
    return null;
  }

那按照我們對于緩存的理解,自然你往緩存里面放數(shù)據(jù)的時候,就要指定數(shù)據(jù)的key,方便我們后面去根據(jù)這個key去取,自然putObject的參數(shù)就有兩個,一個是標(biāo)識key,一個是緩存的數(shù)據(jù)。
那我們?nèi)?shù)據(jù)的時候自然就是根據(jù)這個標(biāo)識去取,自然getObject的參數(shù)就是那個key.
移除數(shù)據(jù)和獲取數(shù)據(jù)其實是一樣的,都是找到這個數(shù)據(jù)。這個其實就類似于map,而緩存實際上也就是map的那個意思,可以一起理解一下。
clear不說了,屬于AOE大招,直接全刪,自然也不需要區(qū)分什么誰是誰,不要參數(shù),直接全干掉。
至此我們是對于這個緩存有個大概的理解了。下面我們就來實際操作一下,我們看看咋用。親愛的。

三、先讓你來設(shè)計一下緩存

既然mybatis這么貼心為我們設(shè)計了緩存接口,我們只需要實現(xiàn)一下就能實現(xiàn)緩存功能。那你不試一把,實在是對不起遠(yuǎn)在大洋彼岸的那些大佬們(或者你用plus,那就稍微對得起他們了)。
來吧,我們來試試。試試就逝逝。

3.1、實現(xiàn)接口

第一步、我們先定義一個org.apache.ibatis.cache.Cache接口的接口實現(xiàn)類,就叫他IkunCache吧。

public class IkunCache implements Cache {
  @Override
  public String getId() {
    return null;
  }

  @Override
  public void putObject(Object key, Object value) {

  }

  @Override
  public Object getObject(Object key) {
    return null;
  }

  @Override
  public Object removeObject(Object key) {
    return null;
  }

  @Override
  public void clear() {

  }

  @Override
  public int getSize() {
    return 0;
  }

  @Override
  public ReadWriteLock getReadWriteLock() {
    return null;
  }
}

好了,我們現(xiàn)在已經(jīng)完成了接口實現(xiàn)類的工作了,下一步我們要考慮一下既然是緩存,那么數(shù)據(jù)到底緩存到哪呢,redis?一上來就開大,不太好吧(實際上我本地沒有redis環(huán)境)。我們先放在我們的本地內(nèi)存試試。

3.2、制定存儲結(jié)構(gòu)

既然要在本地存,那作為java boy,本地其實就那么幾種結(jié)構(gòu),存那么多緩存數(shù)據(jù)你高低得是個集合吧,那無外乎就是List,Set,Map這種,list和set不行,我直接否了,因為他們獲取數(shù)據(jù)需要遍歷。移除數(shù)據(jù)也要遍歷。我用緩存是為了快,你給我來個遍歷,你腦子和我腦子到底誰有問題。
所以我們就把目標(biāo)定在了Map上,簡單點,哥們,直接用HashMap,能通過key直接獲取刪除,等會你說key,你剛才說了key。還記不記得我們說緩存redis這種的時候,就是Key,我們又說Cache接口里面那些方法的時候也說的是key。好了,HashMap,我宣布,你就是今天的天命之子。
于是我們就要聲明一個本地變量,就是HashMap,然后我們不管是寫緩存,還是讀緩存,還是清空緩存都用這個map就好了,那么代碼就進化成為這樣。

public class IkunCache implements Cache {
  

  // 緩存內(nèi)容的容器
  private static Map<Object,Object> ikunCache = new HashMap<>();
  
  /**
    因為整個應(yīng)用中可能存在多個緩存,比如緩存的redis,本地的,或者按照業(yè)務(wù)劃分緩存的訂單的,用戶的等等
    這里可以為你的緩存指定一個名字來區(qū)分
   **/
  @Override
  public String getId() {
    // 我們用緩存類的類名來區(qū)分開每個緩存實例,每個緩存類都維護自己的一個map即可,這樣就區(qū)分開了,簡單設(shè)計一下,別太糾結(jié)
    return getClass().getName();
  }

  @Override
  public void putObject(Object key, Object value) {
    // 把數(shù)據(jù)放入緩存
    ikunCache.put(key,value);
  }

  @Override
  public Object getObject(Object key) {
    // 從緩存中獲取數(shù)據(jù)
    return ikunCache.get(key);
  }

  @Override
  public Object removeObject(Object key) {
    // 從緩存中移除數(shù)據(jù)
    return ikunCache.remove(key);
  }

  @Override
  public void clear() {
    // 開大招,清空緩存
    ikunCache.clear();
  }

  @Override
  public int getSize() {
    // 獲取緩存的長度
    return ikunCache.size();
  }

  @Override
  public ReadWriteLock getReadWriteLock() {
    // 移除了
    return null;
  }
}

那現(xiàn)在是不是你就實現(xiàn)了這個緩存接口了,你就能用了。至于你是不是還有其他的實現(xiàn)類,那可以制定多個實現(xiàn)類。你自己多實現(xiàn)幾個試試,你可以給你的map整個過期時間等等,或者換成別的容器,到時候用那個看你指定哪個就好?;蛘吣阒苯訐Q成redis,全部放redis里面,把你的k-v序列化好就行。
原則就是能用就行,畢竟我們的路線是,完成,完善,完美,完蛋。
這是我們的簡單實現(xiàn),那么mybatis實際上提供了很多內(nèi)置的實現(xiàn)方式,也就是他自己有很多實現(xiàn)類,我們就來看一下。

四、Mybatis內(nèi)置緩存實現(xiàn)

我們看一下Mybatis自己內(nèi)置的實現(xiàn)類。
如何查找應(yīng)用文件緩存位置,SSM,# Mybatis,JAVA,mybatis,java
這個圖好像被壓縮了,我來用文字列出這幾個類。

Cache (org.apache.ibatis.cache):這是那個緩存接口
	SoftCache (org.apache.ibatis.cache.decorators)
	PerpetualCache (org.apache.ibatis.cache.impl)
	LoggingCache (org.apache.ibatis.cache.decorators)
	SynchronizedCache (org.apache.ibatis.cache.decorators)
	ScheduledCache (org.apache.ibatis.cache.decorators)
	LruCache (org.apache.ibatis.cache.decorators)
	IkunCache (com.yx.cache) :這是我們剛才自己實現(xiàn)的,就不說了。
	WeakCache (org.apache.ibatis.cache.decorators)
	FifoCache (org.apache.ibatis.cache.decorators)
	SerializedCache (org.apache.ibatis.cache.decorators)
	BlockingCache (org.apache.ibatis.cache.decorators)
	TransactionalCache (org.apache.ibatis.cache.decorators)

我們看到除了我們自己實現(xiàn)的,mybatis自己內(nèi)置的幾個類貌似分為兩種。

一種是屬于org.apache.ibatis.cache.decorators包下面的,我們說decorators其實翻譯一下就是裝飾器
裝飾器這三個字有沒有喚醒你內(nèi)心的設(shè)計模式之魂,所以我們知道這些類都是裝飾器門面,
真正工作的其實不在他這里,其核心實際在下面這個PerpetualCache。
那我們說裝飾器模式的作用是裝飾器為了給你的目標(biāo)類增強功能。

第二種是屬于org.apache.ibatis.cache.impl包下面的,其實這個包下面就一個PerpetualCache。

根據(jù)我們對于裝飾器的理解,所以其實他的目標(biāo)類是在PerpetualCache,其余的都是給他增強功能用的,所以我們直接看PerpetualCache就可以了。

4.1、干活的其實是我,目標(biāo)PerpetualCache登場

我們來看一下PerpetualCache的源碼。

public class PerpetualCache implements Cache {

  private final String id;

  private final Map<Object, Object> cache = new HashMap<>();

  public PerpetualCache(String id) {
    this.id = id;
  }

  @Override
  public String getId() {
    return id;
  }

  @Override
  public int getSize() {
    return cache.size();
  }

  @Override
  public void putObject(Object key, Object value) {
    cache.put(key, value);
  }

  @Override
  public Object getObject(Object key) {
    return cache.get(key);
  }

  @Override
  public Object removeObject(Object key) {
    return cache.remove(key);
  }

  @Override
  public void clear() {
    cache.clear();
  }

  @Override
  public boolean equals(Object o) {
    if (getId() == null) {
      throw new CacheException("Cache instances require an ID.");
    }
    if (this == o) {
      return true;
    }
    if (!(o instanceof Cache)) {
      return false;
    }

    Cache otherCache = (Cache) o;
    return getId().equals(otherCache.getId());
  }

  @Override
  public int hashCode() {
    if (getId() == null) {
      throw new CacheException("Cache instances require an ID.");
    }
    return getId().hashCode();
  }

}

再吐槽一次,你們是真不寫注釋啊哥,我們看到他除了傳入一個id來指定緩存的名字來區(qū)分以外,其余的實現(xiàn)也是用了一個HashMap作為緩存容器,除了他重寫了equal和hashcode方法,其余的和我們剛才的實現(xiàn)一毛一樣。你看看,其實你也是大佬。
但是大佬肯定不能這么粗糙,于是就有了那么多的裝飾器,來增強你這個無比粗糙的緩存。

4.2、我來給你加點buff吧,緩存裝飾器登場

我們看到了那個緩存干活的類,PerpetualCache,主打一個粗糙,那mybats絕對不會這么low,于是他借助裝飾器模式來實現(xiàn)了一組增強功能的裝飾器。來看一下。

	LruCache (org.apache.ibatis.cache.decorators)
	FifoCache (org.apache.ibatis.cache.decorators)
	
    SoftCache (org.apache.ibatis.cache.decorators)
	LoggingCache (org.apache.ibatis.cache.decorators)
	SynchronizedCache (org.apache.ibatis.cache.decorators)
	ScheduledCache (org.apache.ibatis.cache.decorators)
	WeakCache (org.apache.ibatis.cache.decorators)
	SerializedCache (org.apache.ibatis.cache.decorators)
	BlockingCache (org.apache.ibatis.cache.decorators)
	TransactionalCache (org.apache.ibatis.cache.decorators)

你看到了,我把LruCache和FifoCache單獨列在了一起,和我一樣聰明的你一眼就看懂了,Lru和Fifo其實是一種淘汰機制,在內(nèi)存頁置換的時候?qū)W習(xí)的時候,你是知道的,我不多說了。算了簡單說一下。
LRU:Least Recently Used,最近最少使用,換言之就是最近用的最少的數(shù)據(jù),就先淘汰。
FIFO:First In First Out,先進先出,我不管你誰用的多,那么花里花哨沒用,誰先進來誰先滾,呆那么長時間干嘛。
以上都是在緩存中的數(shù)據(jù)超過了限制的時候,再有新的數(shù)據(jù)進來的時候,需要淘汰掉老的緩存數(shù)據(jù)的時候設(shè)計的策略。可見mybatis是實現(xiàn)了這兩種的。
LoggingCache (org.apache.ibatis.cache.decorators):增強日志打印的功能
BlockingCache (org.apache.ibatis.cache.decorators):阻塞增強,保證一時間只有一個線程讀寫緩存,線程安全得以保證。
ScheduledCache (org.apache.ibatis.cache.decorators):能夠定時自動刷新緩存,按照一定的時間定時去清空緩存。你可以在代碼設(shè)置這個時間間隔。
SerializedCache (org.apache.ibatis.cache.decorators):可以自動幫我們完成k-v的序列化和反序列化,序列化方式就是jdk的Serializedble序列化方式。
TransactionalCache (org.apache.ibatis.cache.decorators):這個裝飾器只有在事務(wù)操作成功的時候才會寫入緩存,你是不是發(fā)現(xiàn)這個保證了寫入DB和緩存的一致性,不至于事務(wù)失敗了,緩存寫進去了,挺好的是不是。
其余的不常用就不說了。其實主要是加裝飾器是為了擴展功能,但是實際上我們一般也不咋用,默認(rèn)就可以了,如果你需要設(shè)計的更加精細(xì)可以考慮使用。我們一般還是借助redis去實現(xiàn)分布式緩存。這里的學(xué)習(xí)是為了學(xué)習(xí)他的設(shè)計。

至于這個裝飾器,你說你不會用,你知道的,我會。

4.2.1、緩存裝飾器簡單操作

我們來寫個簡單的實現(xiàn)看看裝飾器模式怎么用。

@Test
public void testMyCache() throws IOException {
  // 我們先聲明一個PerpetualCache 被增強的目標(biāo)緩存對象
  PerpetualCache perpetualCache = new PerpetualCache("levi");
  // 然后創(chuàng)建加buff的裝飾器緩存類,把我們要增強的傳入,此時的cache 就是一個有了FIFO的能力緩存了
  FifoCache cache = new FifoCache(perpetualCache);
  // 我們設(shè)計緩存大小為5來模擬緩存換出,你看看,增強之后都有設(shè)置大小的能力了,
  cache.setSize(5);
  // 放入五個對象,此時已經(jīng)滿了
  for (int i = 0; i < 5; i++) {
    cache.putObject(i, i);
  }
  // 輸出一下第一個放入的key就是0的對象
  System.out.println(cache.getObject(0));
  // 再放一個進去,發(fā)生換出
  cache.putObject(5, 5);
  // 再取一下第一個放進去的,不出意外的話,他已經(jīng)沒了,因為他第一個放進去,
  // 按照FIFO的邏輯,他被淘汰換出了
  System.out.println(cache.getObject(0));
}

不出意外的話,果然沒有意外,輸出符合預(yù)期。
0
null

4.2.2、緩存裝飾器連環(huán)設(shè)置

我們上面就設(shè)置了一個增強,其實他可以多個增強,增強一組能力。寫法如下。

@Test
public void testMyCache2() throws IOException {
  PerpetualCache perpetualCache = new PerpetualCache("levi");
  FifoCache fifoCache = new FifoCache(perpetualCache);
  LoggingCache loggingCache = new LoggingCache(perpetualCache);
}

這樣他就增強了換出和日志打出的功能,你也可以再加。
或者是鏈?zhǔn)降膶懛ā?/p>

@Test
public void testMyCache3() throws IOException {
  PerpetualCache perpetualCache = new PerpetualCache("levi");
  FifoCache fifoCache = new FifoCache(perpetualCache);
  LoggingCache cache = new LoggingCache(fifoCache);
}

這樣都可以。至于什么是裝飾器的設(shè)計,我會在設(shè)計模式寫出來。

4.3、貼心的源碼

你肯定會問我為啥知道這個裝飾器怎么用,首先我告訴你我學(xué)過設(shè)計模式,那么沒學(xué)過的兄弟們就不配用嗎,mybatis此時從天而降,大喊一聲,放開那個姑娘,讓我來。
我們看一下mybatis源碼有一個test包。這里都有,你照著看就行了,哥們,不難吧。
如何查找應(yīng)用文件緩存位置,SSM,# Mybatis,JAVA,mybatis,java

五、裝飾器模式和代理模式的區(qū)別

5.1、核心區(qū)別

為啥要提到這兩個模式呢,因為我們前面說代理模式的時候,提到過。
代理設(shè)計模式:為邏輯添加功能。增強功能。
裝飾器模式:現(xiàn)在我們又說裝飾器模式也是增強功能。
而且二者的URL設(shè)計類圖都大差不差,那有啥區(qū)別的,用的時候有啥分別呢?
代理模式是為了增強的核心邏輯的額外功能。附加功能。
裝飾器模式是為了增強核心邏輯的核心功能。
舉個例子,我們的service的事務(wù)就是代理模式做的,那你service可能是去查用戶,或者登錄等等,肯定不是做的事務(wù),事務(wù)是額外加的功能,增強的功能不是你要做的事,你本來是登錄,他給你增強了事務(wù)功能,是兩件事。這就是代理模式。
而我們上面的緩存裝飾器增強的是緩存的換出和日志,這就是核心功能的增強,增強的是自己的功能,是一件事。這就是他們的區(qū)別。

可能你又要問了,既然都差不多,我為啥要聽他呢,我用裝飾器模式增強額外功能不行嗎?
答案是行,就你行,誰能難得到你啊,數(shù)你能了。
那么大哥,你的代碼以后還有人維護呢,你自己不按規(guī)矩來,后面的兄弟是不是會不理解,這樣混雜一起,代碼只會越來越爛,屎上雕花。

5.2、語法區(qū)別

裝飾器代碼我們剛才看到了,我們能套娃式的鏈?zhǔn)皆鰪姟?br> 但是代理模式好像沒這么寫。
實際這個理由不充分,因為代理一般就增強一層,實際上他也能多個套,看你寫不寫了。

// 動態(tài)代理的InvocationHandler接口實現(xiàn)
InvocationHandler invocationHandler = new InvocationHandler(){
  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    // 這里你可以繼續(xù)對prox這個代理進行增強套娃,再增強一次,只不過不這么做而已
    Object result = method.invoke(userService, args);
    return result;
  }
};

5.3、無中生有

動態(tài)代理能無中生有,產(chǎn)生新對象。就像mybatis中生成DAO的實現(xiàn)類。
裝飾器模式不行。

實際上那23種模式,你也用不全,有的甚至不能在javaweb中硬套進去。所以多思考設(shè)計,多用設(shè)計,多踩坑,踩坑了再改,才能理解的更深刻,設(shè)計模式就這樣,看是看不會的,親。文章來源地址http://www.zghlxwxcb.cn/news/detail-801956.html

到了這里,關(guān)于橘子學(xué)Mybatis07之Mybatis關(guān)于緩存的設(shè)計的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 說說你對二分查找的理解?如何實現(xiàn)?應(yīng)用場景?

    說說你對二分查找的理解?如何實現(xiàn)?應(yīng)用場景?

    ? 在計算機科學(xué)中,二分查找算法,也稱折半搜索算法,是一種在有序數(shù)組中查找某一特定元素的搜索算法 想要應(yīng)用二分查找法,則這一堆數(shù)應(yīng)有如下特性: 存儲在數(shù)組中 有序排序 搜索過程從數(shù)組的中間元素開始,如果中間元素正好是要查找的元素,則搜索過程結(jié)束 如果

    2024年04月25日
    瀏覽(20)
  • JavaScript如何實現(xiàn)函數(shù)緩存?函數(shù)緩存有哪些應(yīng)用場景?

    在JavaScript中,可以通過函數(shù)緩存來提高函數(shù)的執(zhí)行效率。函數(shù)緩存指的是將函數(shù)的計算結(jié)果緩存起來,當(dāng)下次使用相同的參數(shù)調(diào)用該函數(shù)時,直接返回緩存中的結(jié)果,避免重復(fù)計算。 以下是一種常見的函數(shù)緩存實現(xiàn)方式: 上述代碼中, memoize 函數(shù)接受一個函數(shù)作為參數(shù),并

    2024年01月19日
    瀏覽(20)
  • 數(shù)據(jù)結(jié)構(gòu)07:查找[C++][B樹Btree]

    數(shù)據(jù)結(jié)構(gòu)07:查找[C++][B樹Btree]

    ?圖源:文心一言 考研對于B樹的要求重點在推理手算的部分,只參考王道論壇咸魚老師的視頻就可以了;若時間非常充裕的小伙伴,也可以往下滑了解一下代碼 ~???? 備注: 這次的代碼是從這里復(fù)制的: B-tree (programiz.com)。因為代碼比較復(fù)雜,我與AI修改的代碼沒有通過刪

    2024年02月16日
    瀏覽(16)
  • DAY07_Maven高級——分模塊開發(fā)與設(shè)計&依賴管理&聚合與繼承&屬性管理&多環(huán)境配置與應(yīng)用&私服

    DAY07_Maven高級——分模塊開發(fā)與設(shè)計&依賴管理&聚合與繼承&屬性管理&多環(huán)境配置與應(yīng)用&私服

    問題導(dǎo)入 分模塊開發(fā)對工程有什么好處? 模塊拆分原則 目的:項目的擴展性變強了,方便其他項目引用相同的功能。 將原始模塊按照功能拆分成若干個子模塊,方便模塊間的相互調(diào)用,接口共享 問題導(dǎo)入 一個完整的工程依據(jù)什么來進行模塊的拆分? 2.1 創(chuàng)建Maven模塊 2.2 書

    2024年02月09日
    瀏覽(49)
  • 橘子學(xué)ES16之分詞三大組件以及如何自己實現(xiàn)自己的分詞器

    橘子學(xué)ES16之分詞三大組件以及如何自己實現(xiàn)自己的分詞器

    本文來看一下ES的多字段特性,以及如何配置一個自定義的分詞器。 精確值和全文檢索值。精確值的意思就是不分詞,不全文檢索。當(dāng)成mysql中的那種等值查詢。全文文本值意思就是查詢的時候走的是分詞的路子,全文文本的匹配。 1.1、Exact Values 包括數(shù)字類型,日期類型,具

    2024年02月12日
    瀏覽(16)
  • 緩存解析:從架構(gòu)設(shè)計到Redis應(yīng)用及最佳實踐

    在現(xiàn)代軟件架構(gòu)中,緩存是優(yōu)化數(shù)據(jù)檢索、提高應(yīng)用性能的關(guān)鍵組件。緩存的存儲位置多種多樣,每個位置針對特定的優(yōu)化目標(biāo)和需求。理解這些層級對于設(shè)計高效的系統(tǒng)至關(guān)重要。 瀏覽器緩存 :這是最接近用戶端的緩存層。瀏覽器緩存存儲了用戶經(jīng)常訪問的靜態(tài)資源,如

    2024年01月22日
    瀏覽(21)
  • 【微服務(wù)】07-緩存

    1. 緩存是什么 緩存是計算結(jié)果的“臨時”存儲和重復(fù)使用 緩存本質(zhì)是用“空間”換取“時間” 2. 緩存的場景 計算結(jié)果,如:反射對象緩存 請求結(jié)果,如:DNS緩存 臨時共享數(shù)據(jù),如:會話存儲 熱點訪問內(nèi)容頁,如:商品詳情 熱點變更邏輯數(shù)據(jù),如:秒殺的庫存數(shù) 3. 緩存的

    2024年02月11日
    瀏覽(18)
  • 微服務(wù)07-分布式緩存

    微服務(wù)07-分布式緩存

    前提: 單機的Redis存在四大問題: 解決辦法:基于Redis集群解決單機Redis存在的問題 Redis 具有持久化功能,其會按照設(shè)置以 快照 或 操作日志 的形式將數(shù)據(jù)持久化到磁盤。 Redis有兩種持久化方案: RDB持久化 AOF持久化 注意: RDB 是默認(rèn)持久化方式,但 Redis 允許 RDB 與 AOF 兩種

    2024年02月12日
    瀏覽(22)
  • JAVA07_Stream流中FindFirst方法查找元素第一個

    ①. Stream的findFirst方法在此流中查找第一個元素作為Optional,如果流中沒有元素,findFirst返回空的Optional,如果findFirst選擇的元素為null,它將拋出NullPointerException Optional findFirst() ②. findAny():返回流中的任意一個元素;如果流是空的,則返回空 對于串行流,輸出的都是查找第一個元素 對于

    2024年02月12日
    瀏覽(23)
  • 數(shù)據(jù)結(jié)構(gòu)07:查找[C++][樸素二叉排序樹BST]

    數(shù)據(jù)結(jié)構(gòu)07:查找[C++][樸素二叉排序樹BST]

    圖源:文心一言 考研筆記整理 8k+ 字,小白友好、代碼可跑,請小伙伴放心食用~~???? 第1版:查資料、寫B(tài)UG、畫導(dǎo)圖、畫配圖~???? 參考用書: 王道考研《2024年 數(shù)據(jù)結(jié)構(gòu)考研復(fù)習(xí)指導(dǎo)》 參考用書配套視頻: 7.3_1 二叉排序樹_嗶哩嗶哩_bilibili 特別感謝: ?Chat GPT老師、文心

    2024年02月10日
    瀏覽(16)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包