Java - Mybatis的緩存機制、集成SpringBoot后緩存相關問題

mybaits提供一級緩存,和二級緩存


一級緩存(默認開啟)

?

一級緩存是SqlSession級別的緩存。在操作數據庫時需要構造 sqlSession對象,在對象中有一個(內存區域)數據結構(HashMap)用于存儲緩存數據。不同的sqlSession之間的緩存數據區域(HashMap)是互相不影響的。

一級緩存的作用域是同一個SqlSession,在同一個sqlSession中兩次執行相同的sql語句,第一次執行完畢會將數據庫中查詢的數據寫到緩存(內存),第二次會從緩存中獲取數據將不再從數據庫查詢,從而提高查詢效率。當一個sqlSession結束后該sqlSession中的一級緩存也就不存在了。Mybatis默認開啟一級緩存。

一級緩存只是相對于同一個SqlSession而言。所以在參數和SQL完全一樣的情況下,我們使用同一個SqlSession對象調用一個Mapper方法,往往只執行一次SQL,因為使用SelSession第一次查詢后,MyBatis會將其放在緩存中,以后再查詢的時候,如果沒有聲明需要刷新,并且緩存沒有超時的情況下,SqlSession都會取出當前緩存的數據,而不會再次發送SQL到數據庫。

一級緩存的生命周期有多長?
  a、MyBatis在開啟一個數據庫會話時,會 創建一個新的SqlSession對象,SqlSession對象中會有一個新的Executor對象。Executor對象中持有一個新的PerpetualCache對象;當會話結束時,SqlSession對象及其內部的Executor對象還有PerpetualCache對象也一并釋放掉。

  b、如果SqlSession調用了close()方法,會釋放掉一級緩存PerpetualCache對象,一級緩存將不可用。

  c、如果SqlSession調用了clearCache(),會清空PerpetualCache對象中的數據,但是該對象仍可使用。

  d、SqlSession中執行了任何一個update操作(update()、delete()、insert()) ,都會清空PerpetualCache對象的數據,但是該對象可以繼續使用

怎么判斷某兩次查詢是完全相同的查詢?
  mybatis認為,對于兩次查詢,如果以下條件都完全一樣,那么就認為它們是完全相同的兩次查詢。

  2.1 傳入的statementId

  2.2 查詢時要求的結果集中的結果范圍

  2.3. 這次查詢所產生的最終要傳遞給JDBC java.sql.Preparedstatement的Sql語句字符串(boundSql.getSql() )

  2.4 傳遞給java.sql.Statement要設置的參數值

?

 
@Testpublic void testCache1() throws Exception{SqlSessionsqlSession = sqlSessionFactory.openSession();//創建代理對象UserMapperuserMapper = sqlSession.getMapper(UserMapper.class);//下邊查詢使用一個SqlSession//第一次發起請求,查詢id為1的用戶Useruser1 = userMapper.findUserById(1);System.out.println(user1);//    如果sqlSession去執行commit操作(執行插入、更新、刪除),清空SqlSession中的一級緩存,這樣做的目的為了讓緩存中存儲的是最新的信息,避免臟讀。//更新user1的信息user1.setUsername("測試用戶22");userMapper.updateUser(user1);//執行commit操作去清空緩存sqlSession.commit();//第二次發起請求,查詢id為1的用戶Useruser2 = userMapper.findUserById(1);System.out.println(user2);sqlSession.close();}

mybatis和spring進行整合開發,事務控制在service中。

一個service方法中包括很多mapper方法調用。

如果是執行兩次service調用查詢相同的用戶信息,不走一級緩存,因為Service方法結束,sqlSession就關閉,一級緩存就清空。

service{//開始執行時,開啟事務,創建SqlSession對象//第一次調用mapper的方法findUserById(1)//第二次調用mapper的方法findUserById(1),從一級緩存中取數據//aop控制 只要方法結束,sqlSession關閉 sqlsession關閉后就銷毀數據結構,清空緩存Service結束sqlsession關閉}


二級緩存

MyBatis的二級緩存是Application級別的緩存

二級緩存是mapper級別的緩存,多個SqlSession去操作同一個Mapper的sql語句,多個SqlSession去操作數據庫得到數據會存在二級緩存區域,多個SqlSession可以共用二級緩存,二級緩存是跨SqlSession的。

? ? 二級緩存是多個SqlSession共享的,其作用域是mapper的同一個namespace,不同的sqlSession兩次執行相同namespace下的sql語句且向sql中傳遞參數也相同即最終執行相同的sql語句,第一次執行完畢會將數據庫中查詢的數據寫到緩存(內存),第二次會從緩存中獲取數據將不再從數據庫查詢,從而提高查詢效率。Mybatis默認沒有開啟二級緩存需要在setting全局參數中配置開啟二級緩存。

二級緩存與一級緩存區別,二級緩存的范圍更大,多個sqlSession可以共享一個UserMapper的二級緩存區域。數據類型仍然為HashMap

UserMapper有一個二級緩存區域(按namespace分,如果namespace相同則使用同一個相同的二級緩存區),其它mapper也有自己的二級緩存區域(按namespace分)。

每一個namespace的mapper都有一個二緩存區域,兩個mapper的namespace如果相同,這兩個mapper執行sql查詢到數據將存在相同的二級緩存區域中。

?

sqlSessionFactory層面上的二級緩存默認是不開啟的,二級緩存的開啟需要進行配置,實現二級緩存的時候,MyBatis要求返回的POJO必須是可序列化的。 也就是要求實現Serializable接口,配置方法很簡單,只需要在映射XML文件配置就可以開啟緩存了<cache/>,如果我們配置了二級緩存就意味著:

映射語句文件中的所有select語句將會被緩存。
映射語句文件中的所欲insert、update和delete語句會刷新緩存。
緩存會使用默認的Least Recently Used(LRU,最近最少使用的)算法來收回。
根據時間表,比如No Flush Interval,(CNFI沒有刷新間隔),緩存不會以任何時間順序來刷新。
緩存會存儲列表集合或對象(無論查詢方法返回什么)的1024個引用
緩存會被視為是read/write(可讀/可寫)的緩存,意味著對象檢索不是共享的,而且可以安全的被調用者修改,不干擾其他調用者或線程所做的潛在修改。


開啟二級緩存

mybaits的二級緩存是mapper范圍級別,除了在SqlMapConfig.xml設置二級緩存的總開關,還要在具體的mapper.xml中開啟二級緩存。

在核心配置文件SqlMapConfig.xml中加入

<setting name="cacheEnabled"value="true"/><!-- 全局配置參數,需要時再設置 --><settings><!-- 開啟二級緩存  默認值為true --><setting name="cacheEnabled" value="true"/></settings>

在UserMapper.xml中開啟二緩存,UserMapper.xml下的sql執行完成會存儲到它的緩存區域(HashMap)

<mapper namespace="cn.hpu.mybatis.mapper.UserMapper"><!-- 開啟本mapper namespace下的二級緩存 --><cache></cache>

調用pojo類實現序列化接口

public class Userimplements Serializable {//Serializable實現序列化,為了將來反序列化

二級緩存需要查詢結果映射的pojo對象實現java.io.Serializable接口實現序列化和反序列化操作,注意如果存在父類、成員pojo都需要實現序列化接口。

pojo類實現序列化接口是為了將緩存數據取出執行反序列化操作,因為二級緩存數據存儲介質多種多樣,不一定在內存有可能是硬盤或者遠程服務器。
?

// 二級緩存測試@Testpublic void testCache2() throws Exception {SqlSessionsqlSession1 = sqlSessionFactory.openSession();SqlSessionsqlSession2 = sqlSessionFactory.openSession();SqlSessionsqlSession3 = sqlSessionFactory.openSession();// 創建代理對象UserMapperuserMapper1 = sqlSession1.getMapper(UserMapper.class);// 第一次發起請求,查詢id為1的用戶Useruser1 = userMapper1.findUserById(1);System.out.println(user1);//這里執行關閉操作,將sqlsession中的數據寫到二級緩存區域sqlSession1.close();//使用sqlSession3執行commit()操作UserMapperuserMapper3 = sqlSession3.getMapper(UserMapper.class);Useruser  = userMapper3.findUserById(1);user.setUsername("張明明");userMapper3.updateUser(user);//執行提交,清空UserMapper下邊的二級緩存sqlSession3.commit();sqlSession3.close();UserMapperuserMapper2 = sqlSession2.getMapper(UserMapper.class);// 第二次發起請求,查詢id為1的用戶Useruser2 = userMapper2.findUserById(1);System.out.println(user2);sqlSession2.close();}

?useCache配置禁用二級緩存
在statement中設置useCache=false可以禁用當前select語句的二級緩存,即每次查詢都會發出sql去查詢,默認情況是true,即該sql使用二級緩存。

<selectid="findOrderListResultMap" resultMap="ordersUserMap" useCache="false">
總結:針對每次查詢都需要最新的數據sql,要設置成useCache=false,禁用二級緩存。

mybatis刷新緩存(就是清空緩存)


在mapper的同一個namespace中,如果有其它insert、update、delete操作數據后需要刷新緩存,如果不執行刷新緩存會出現臟讀。

?設置statement配置中的flushCache="true" 屬性,默認情況下為true即刷新緩存,如果改成false則不會刷新。使用緩存時如果手動修改數據庫表中的查詢數據會出現臟讀。

如下:

<insertid="insertUser" parameterType="cn.itcast.mybatis.po.User" flushCache="true">
?

總結:一般下執行完commit操作都需要刷新緩存,flushCache=true表示刷新緩存默認情況下為true,我們不用去設置它,這樣可以避免數據庫臟讀。

Mybatis Cache參數


flushInterval(刷新間隔)可以被設置為任意的正整數,而且它們代表一個合理的毫秒形式的時間段。默認情況是不設置,也就是沒有刷新間隔,緩存僅僅調用語句時刷新。

size(引用數目)可以被設置為任意正整數,要記住你緩存的對象數目和你運行環境的可用內存資源數目。默認值是1024。

readOnly(只讀)屬性可以被設置為true或false。只讀的緩存會給所有調用者返回緩存對象的相同實例。因此這些對象不能被修改。這提供了很重要的性能優勢。可讀寫的緩存會返回緩存對象的拷貝(通過序列化)。這會慢一些,但是安全,因此默認是false。

如下例子:

<cache ?eviction="FIFO" flushInterval="60000" ?size="512" readOnly="true"/>
這個更高級的配置創建了一個 FIFO 緩存,并每隔 60 秒刷新,存數結果對象或列表的 512 個引用,而且返回的對象被認為是只讀的,因此在不同線程中的調用者之間修改它們會導致沖突。可用的收回策略有, 默認的是 LRU:

1. ? ? ?LRU – 最近最少使用的:移除最長時間不被使用的對象。

2. ? ? ?FIFO – 先進先出:按對象進入緩存的順序來移除它們。

3. ? ? ?SOFT – 軟引用:移除基于垃圾回收器狀態和軟引用規則的對象。

4. ? ? ?WEAK – 弱引用:更積極地移除基于垃圾收集器狀態和弱引用規則的對象。


mybatis整合ehcache

ehcache是一個分布式緩存框架。

EhCache 是一個純Java的進程內緩存框架,是一種廣泛使用的開源Java分布式緩存,具有快速、精干等特點,是Hibernate中默認的CacheProvider。

不使用分布緩存,緩存的數據在各各服務單獨存儲,不方便系統開發。所以要使用分布式緩存對緩存數據進行集中管理。

mybatis無法實現分布式緩存,需要和其它分布式緩存框架進行整合。

整合方法(掌握無論整合誰,首先想到改type接口)

mybatis提供了一個cache接口,如果要實現自己的緩存邏輯,實現cache接口開發即可。

mybatis和ehcache整合,mybatis和ehcache整合包中提供了一個cache接口的實現類。

加入ehcache包

整合ehcache

配置mapper中cache中的type為ehcache對cache接口的實現類型。

<mapper namespace="cn.hpu.mybatis.mapper.UserMapper"><!-- 開啟本mapper namespace下的二級緩存type:指定cache接口實現類,mybatis默認使用PerpetualCache要和eache整合,需要配置type為ehcahe實現cache接口的類型--><cache type="org.mybatis.caches.ehcache.EhcacheCache"></cache>

可以根據需求調整緩存參數:

<cache type="org.mybatis.caches.ehcache.EhcacheCache"><property name="timeToIdleSeconds" value="3600"/><property name="timeToLiveSeconds" value="3600"/><!-- 同ehcache參數maxElementsInMemory--><property name="maxEntriesLocalHeap"value="1000"/><!-- 同ehcache參數maxElementsOnDisk --><property name="maxEntriesLocalDisk" value="10000000"/><property name="memoryStoreEvictionPolicy" value="LRU"/></cache>

加入ehcache的配置文件

在classpath下配置ehcache.xml

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="../config/ehcache.xsd"><diskStore path="F:\develop\ehcache"/><defaultCachemaxElementsInMemory="1000"maxElementsOnDisk="10000000"eternal="false"overflowToDisk="false"timeToIdleSeconds="120"timeToLiveSeconds="120"diskExpiryThreadIntervalSeconds="120"memoryStoreEvictionPolicy="LRU"></defaultCache></ehcache>

屬性說明:

? diskStore:指定數據在磁盤中的存儲位置。

? defaultCache:當借助CacheManager.add("demoCache")創建Cache時,EhCache便會采用<defalutCache/>指定的的管理策略

以下屬性是必須的:

?maxElementsInMemory - 在內存中緩存的element的最大數目

?maxElementsOnDisk - 在磁盤上緩存的element的最大數目,若是0表示無窮大

? eternal - 設定緩存的elements是否永遠不過期。如果為true,則緩存的數據始終有效,如果為false那么還要根據timeToIdleSeconds,timeToLiveSeconds判斷

? overflowToDisk- 設定當內存緩存溢出的時候是否將過期的element緩存到磁盤上

以下屬性是可選的:

?timeToIdleSeconds - 當緩存在EhCache中的數據前后兩次訪問的時間超過timeToIdleSeconds的屬性取值時,這些數據便會刪除,默認值是0,也就是可閑置時間無窮大

?timeToLiveSeconds - 緩存element的有效生命期,默認是0.,也就是element存活時間無窮大

? ? ? ?diskSpoolBufferSizeMB 這個參數設置DiskStore(磁盤緩存)的緩存區大小.默認是30MB.每個Cache都應該有自己的一個緩沖區.

?diskPersistent在VM重啟的時候是否啟用磁盤保存EhCache中的數據,默認是false。

?diskExpiryThreadIntervalSeconds - 磁盤緩存的清理線程運行間隔,默認是120秒。每個120s,相應的線程會進行一次EhCache中數據的清理工作

?memoryStoreEvictionPolicy - 當內存緩存達到最大,有新的element加入的時候,移除緩存中element的策略。默認是LRU(最近最少使用),可選的有LFU(最不常使用)和FIFO(先進先出)


集成SpringBoot緩存相關問題

1.一級緩存只有在開啟了數據庫事物【@EnableTransactionManagement】并且處于一個被事物標注的方法下【直接或間接】才會生效。

2.禁用一級緩存:mybatis沒有提供一級緩存的啟用、禁用開關,但在Mapper文件對應的語句中增加flushCache="true"可以達到實際禁用一級緩存的效果,一般同時還會加上useCache="false",以便關閉二級緩存;下面討論使用springboot配置的方式控制一級緩存。

MyBatis 一級緩存(MyBaits 稱其為 Local Cache)無法關閉,但是有兩種級別可選:

A.session

在同一個 sqlSession 內,對同樣的查詢將不再查詢數據庫,直接從緩存中獲取。

mybatis:configuration:cache-enabled: false  #禁用二級緩存local-cache-scope: session  #一級緩存指定為session級別

B.statement

每次查詢結束都會清掉一級緩存,實際效果就是禁用了一級緩存;

mybatis:configuration:cache-enabled: false #禁用二級緩存local-cache-scope: statement #一級緩存指定為statement級別

@Transactional(propagation = Propagation.REQUIRED)
public List<Users> getUsers() {List<Users> usersList = usersMapper.selectByExample(new UsersExample());  #1usersList = usersMapper.selectByExample(new UsersExample());  #2return usersList;
}

A.一級緩存級別設置為session

在代碼中1處,通過日志觀察,打印出sql語句,未走緩存【此時緩存數據還不存在】;

在執行2處語句之前,通過數據庫工具修改數據庫記錄并提交,繼續執行程序后,通過日志觀察,未打印出sql語句,獲取的數據未體現出通過工具修改數據的變化,說明使用的是緩存中的數據;

B.一級緩存級別設置為statement

在代碼中1處,通過日志觀察,打印出sql語句,未走緩存【此時緩存數據還不存在】;

在執行2處語句之前,通過數據庫工具修改數據庫記錄并提交,繼續執行程序后,通過日志觀察,打印出sql語句,且獲取的數據也體現出通過工具修改數據的變化,說明未使用緩存中的數據;

結論:通過將一級緩存級別設置為statement,可以達到禁用一級緩存的效果。

@Transactional(propagation = Propagation.REQUIRED)
public List<Users> getUsers() {List<Users> usersList = usersMapper.selectByExample(new UsersExample());  #1usersList = usersServer.getUsersList();return usersList;
}

?#下面的代碼屬于usersServer

@Transactional(propagation = Propagation.NESTED)  #3
public List<Users> getUsersList() {return usersMapper.selectByExample(new UsersExample());  #2
}

觀察到的結果與上面的一致。

結論:同上,同時證明了嵌套事物NESTED本質上與上層事物處于一個相同的事物中。
將代碼3處事物配置調整成REQUIRES_NEW,重做之前的實驗;

觀察到的結果:在一級緩存級別為session與statement時,現象一致,帶執行代碼2處,均打印SQL語句,并且體現出了手動修改數據庫記錄的效果;

結論:REQUIRES_NEW確實重新起了一個新的事物,與上層事物沒有關系。

結論:
1.將mybatis一級緩存級別設置為statement可以事實上達到禁用一級緩存的效果;
2.啟用mybatis一級緩存,將級別設置為session【或不做任何設置,mybaits默認就是這個級別】

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

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

相關文章

STM32F407-14.3.1-01 時基單元

時基單元 可編程高級控制定時器的主要模塊是一個 16 位計數器及其相關的自動重載寄存器。計數器可遞增計數、遞減計數或交替進行遞增和遞減計數。計數器的時鐘可通過預分頻器進行分頻。 計數器、自動重載寄存器和預分頻器寄存器可通過軟件進行讀寫。即使在計數器運行時也可執行…

Linux ln命令教程:如何創建符號鏈接(附案例詳解和注意事項)

Linux ln命令介紹 Linux ln命令&#xff08;全稱&#xff1a;link files&#xff09;是一個非常重要的命令&#xff0c;它的功能是為某一個文件在另外一個位置建立一個同步的鏈接。當我們需要在不同的目錄&#xff0c;用到相同的文件時&#xff0c;我們不需要在每一個需要的目…

Python:核心知識點整理大全14-筆記

目錄 ?編輯 7.2.2 讓用戶選擇何時退出 parrot.py 7.2.3 使用標志 7.2.4 使用 break 退出循環 cities.py 7.2.5 在循環中使用 continue counting.py 7.2.6 避免無限循環 counting.py 7.3 使用 while 循環來處理列表和字典 7.3.1 在列表之間移動元素 confirmed_user…

數字圖像處理(實踐篇)二十二 使用opencv進行人臉、眼睛、嘴的檢測

目錄 1 xml文件 2 涉及的函數 3 實踐 使用opencv進行人臉、眼睛、嘴的檢測。 1 xml文件 方法① 下載 地址&#xff1a;https://github.com/opencv/opencv/tree/master/data/haarcascades 點擊haarcascade_frontalface_default.xml文件 對著Raw右鍵&#xff0c;選擇“鏈接…

【JVM從入門到實戰】(二)字節碼文件的組成

一、Java虛擬機的組成 二、字節碼文件的組成 字節碼文件的組成 – 應用場景 字節碼文件的組成部分-Magic魔數 什么是魔數&#xff1f; Java字節碼文件中的魔數 文件是無法通過文件擴展名來確定文件類型的&#xff0c;文件擴展名可以隨意修改&#xff0c;不影響文件的內容。…

機器學習筆記 - 隨機樣本共識(RANSAC) 算法

一、什么是 RANSAC? RANSAC(隨機樣本共識)是一種用于機器學習和計算機視覺的算法,隨機樣本共識(RANSAC)是一種迭代方法,用于根據包含異常值的數據集估計數學模型。RANSAC 算法的工作原理是識別數據集中的異常值,并使用不包含異常值的數據來估計所需的模型。 …

在Go中定義結構體

引言 圍繞具體細節構建抽象是編程語言可以提供給開發人員的最好工具。結構體允許Go開發人員描述Go程序運行的世界。結構體允許我們討論Address,而不是描述Street、 City或PostalCode的字符串。它們是我們努力告訴未來開發人員(包括我們自己)哪些數據對我們的Go程序是重要的,…

UE引擎 LandscapeGrass 實現機制分析(UE5.2)

前言 隨著電腦和手機硬件性能越來越高&#xff0c;游戲越來越追求大世界&#xff0c;而大世界非常核心的一環是植被&#xff0c;目前UE5引擎提供給植被生成的主流兩種方式為 手刷植被和LandscapeGrass(WeightMap程序化植被)。當然UE5.3推出新一代PCGFramework 節點程序化生成框…

MyBatis:緩存

MyBatis 緩存一級緩存二級緩存注 緩存 緩存&#xff0c;是數據交換的緩沖區&#xff08;臨時保存數據的地方&#xff09;。即將數據&#xff08;數據一般為頻繁查詢且不易改變&#xff09;保存在計算機內存中&#xff0c;下次讀取數據時直接從內存中獲取&#xff0c;以避免頻繁…

OpenAI接口調用示例

最近為公司做了一個ChatGPT工具&#xff0c;這里展示一下OpenAI接口的調用 前提條件 訪問OpenAI官網&#xff08;國內需要翻墻&#xff09;的賬號&#xff0c;需要sk 地址&#xff1a;https://platform.openai.com 依賴 使用開源工具調用OpenAI接口&#xff0c;依賴如下&am…

js中箭頭函數簡單介紹

1.箭頭函數是 ES6 中新增的一種函數定義方式&#xff0c; 簡單舉例為 var nameA function(a){return a} 可以用箭頭函數簡化為 var nameA a >a; 返回的是你輸入的值 比如 nameA(5) 返回的就是5 nameA(2) 返回的就是2 以上兩個表達的含義是一樣的。nameA為名字 2.…

Vue3封裝一個輪播圖組件

先看效果 編寫組件代碼 CarouselChart.vue <template><div classimg-box><el-button clickpreviousImages v-ifprops.showBtn>←</el-button><div classimg><div styledisplay: flex;gap: 20px idmove><imgclassimg-item v-for(item…

centos7部署docker

文章目錄 &#xff08;1&#xff09;安裝前準備&#xff08;2&#xff09;卸載舊版Docker&#xff08;3&#xff09;安裝docker&#xff08;4&#xff09;配置鏡像加速 &#xff08;1&#xff09;安裝前準備 在開始安裝之前&#xff0c;首先需要檢查內核版本。使用 uname -r 命…

nodejs微信小程序+python+PHP個性化服裝搭配系統APP-計算機畢業設計推薦 android

目 錄 摘 要 I ABSTRACT II 目 錄 II 第1章 緒論 1 1.1背景及意義 1 1.2 國內外研究概況 1 1.3 研究的內容 1 第2章 相關技術 3 2.1 nodejs簡介 4 2.2 express框架介紹 6 2.4 MySQL數據庫 4 第3章 系統分析 5 3.1 需求分析 5 3.2 系統可行性分析 5 3.2.1技術可行性&#xff1a;…

redis(設置密碼)配置文件詳細

1.設置賬號密碼端口 config set requirepass 123456 設置密碼為123456 config get requirepass 查看賬號密碼 auth 123456 登入的時候輸入這個確定賬號密碼 1. 首先連接到Redis服務器: redis-cli 2. 然后使用CONFIG SET命令設置requirepass參數并指定密碼: CONFIG SET requi…

【PyTorch】現代卷積神經網絡

文章目錄 1. 理論介紹1.1. 深度卷積神經網絡&#xff08;AlexNet&#xff09;1.1.1. 概述1.1.2. 模型設計 1.2. 使用塊的網絡&#xff08;VGG&#xff09;1.3. 網絡中的網絡&#xff08;NiN&#xff09;1.4. 含并行連結的網絡&#xff08;GoogLeNet&#xff09; 2. 實例解析2.1…

家具制造ERP軟件包含哪些功能?家具制造業ERP系統哪個好

不同的家具有不同的用料、品質、制造工時、營銷渠道等&#xff0c;而有些家具制造企業采用傳統的管理方式在處理物料BOM、生產實際成本核算、庫存盤點、供應商選擇、班組計件核對、生產領用以及物料追溯等方面存在不少提升空間。 與此同時也有很多的皮具制造企業借助ERP軟件優…

Linux16 ftp文件服務區、vsftpd文件系統服務安裝、lftp客戶端安裝、NFS遠程共享存儲

目錄 一、FTP基礎ftp主動模式ftp被動模式 二、vsftpd配置共享目錄編輯配置文件使用windows 訪問 三、客戶端安裝 &#xff08;lftp&#xff09;匿名用戶的一些操作&#xff08;lftp {ip}&#xff09;ftp配置本地用戶登錄配置本地用戶ftp配置文件 lftp操作 NFS遠程共享存儲安裝n…

新的側通道攻擊可泄露處理器的 Root 密碼

阿姆斯特丹自由大學的一組科學家開發了一種名為 SLAM&#xff08;Spectre Linear Address Masking&#xff09;的側信道攻擊。 該攻擊利用旨在提高新型Intel、AMD 和 Arm 處理器安全性的硬件功能&#xff0c;從內核內存中提取根密碼哈希。 重現 SLAM 攻擊所需的代碼和所有數據…

dockerfile:創建鏡像的方式,船艦自定義的鏡像

dockerfile&#xff1a;創建鏡像的方式&#xff0c;船艦自定義的鏡像 包括配置文件&#xff0c;掛載點&#xff0c;對外暴露的端口&#xff0c;設置環境變量 docker創建鏡像的方式 1、基于已有鏡像進行創建。 根據官方提供的鏡像源&#xff0c;創建鏡像&#xff0c;然后拉起…