面試多線程八股文十問十答第二期

面試多線程八股文十問十答第二期

作者:程序員小白條,個人博客

相信看了本文后,對你的面試是有一定幫助的!

?點贊?收藏?不迷路!?

1.進程和線程的區別

  1. 概念不同:進程是操作系統中的一個獨立執行單元,擁有獨立的內存空間,可以包含多個線程;而線程是進程中的一個執行單元,與同一進程中的其他線程共享內存空間。
  2. 調度方式不同:進程是由操作系統進行調度的,操作系統負責分配進程所需的資源,如內存、CPU時間等;線程則是由進程內的調度器進行調度的,同一進程中的多個線程共享進程的資源,如內存、文件句柄等。
  3. 資源占用不同:進程獨占系統資源,包括內存空間、文件句柄、網絡端口等,而線程與同一進程中的其他線程共享這些資源,因此在資源占用上,線程比進程更輕量級。
  4. 上下文切換成本不同:進程間的切換需要進行上下文切換,涉及到內存狀態的保存和恢復,因此成本較高;而線程間的切換成本相對較低,只需要保存和恢復少量的寄存器狀態。
  5. 通信方式不同:進程之間通信一般需要使用操作系統提供的進程間通信機制,如管道、消息隊列、共享內存等;而線程之間通信一般可以通過共享內存、管道、消息隊列等方式,但更常用的是使用Java提供的高級線程間通信機制,如wait()/notify()、Lock、Condition等。

進程:程序是靜止的,進程實體的運行過程就是進程,是系統進行資源分配的基本單位

進程的特征:并發性、異步性、動態性(最基本)、獨立性、(結構性)

線程:線程是屬于進程的,是一個基本的 CPU 執行單元,是程序執行流的最小單元。線程是進程中的一個實體,是系統獨立調度的基本單位,線程本身不擁有系統資源,只擁有一點在運行中必不可少的資源,與同屬一個進程的其他線程共享進程所擁有的全部資源

2.進程的通信方式

重要的進程間通信方式:**管道、消息隊列、**共享內存、信號量、信號、Socket。

$ ps auxf | grep mysql

上面命令行里的「|」豎線就是一個管道,它的功能是將前一個命令(ps auxf)的輸出,作為后一個命令(grep mysql)的輸入,從這功能描述,可以看出管道傳輸數據是單向的,如果想相互通信,我們需要創建兩個管道才行。

同時,我們得知上面這種管道是沒有名字,所以「|」表示的管道稱為匿名管道,用完了就銷毀。

管道還有另外一個類型是命名管道,也被叫做 FIFO,因為數據是先進先出的傳輸方式。

在使用命名管道前,先需要通過 mkfifo 命令來創建,并且指定管道名字:

$ mkfifo myPipe

$ echo "hello" > myPipe  // 將數據寫進管道// 停住了 ...
$ cat < myPipe  // 讀取管道里的數據
hello

管道這種通信方式效率低,不適合進程間頻繁地交換數據。當然,它的好處,自然就是簡單,同時也我們很容易得知管道里的數據已經被另一個進程讀取了。

消息隊列

前面說到管道的通信方式是效率低的,因此管道不適合進程間頻繁地交換數據。

對于這個問題,消息隊列的通信模式就可以解決。比如,A 進程要給 B 進程發送消息,A 進程把數據放在對應的消息隊列后就可以正常返回了,B 進程需要的時候再去讀取數據就可以了。同理,B 進程要給 A 進程發送消息也是如此。

再來,消息隊列是保存在內核中的消息鏈表,在發送數據時,會分成一個一個獨立的數據單元,也就是消息體(數據塊),消息體是用戶自定義的數據類型,消息的發送方和接收方要約定好消息體的數據類型,所以每個消息體都是固定大小的存儲塊,不像管道是無格式的字節流數據。如果進程從消息隊列中讀取了消息體,內核就會把這個消息體刪除。

消息隊列生命周期隨內核,如果沒有釋放消息隊列或者沒有關閉操作系統,消息隊列會一直存在,而前面提到的匿名管道的生命周期,是隨進程的創建而建立,隨進程的結束而銷毀。

消息這種模型,兩個進程之間的通信就像平時發郵件一樣,你來一封,我回一封,可以頻繁溝通了。

但郵件的通信方式存在不足的地方有兩點,一是通信不及時,二是附件也有大小限制,這同樣也是消息隊列通信不足的點。

消息隊列不適合比較大數據的傳輸,因為在內核中每個消息體都有一個最大長度的限制,同時所有隊列所包含的全部消息體的總長度也是有上限。在 Linux 內核中,會有兩個宏定義 MSGMAX 和 MSGMNB,它們以字節為單位,分別定義了一條消息的最大長度和一個隊列的最大長度。

消息隊列通信過程中,存在用戶態與內核態之間的數據拷貝開銷,因為進程寫入數據到內核中的消息隊列時,會發生從用戶態拷貝數據到內核態的過程,同理另一進程讀取內核中的消息數據時,會發生從內核態拷貝數據到用戶態的過程。共享內存

消息隊列的讀取和寫入的過程,都會有發生用戶態與內核態之間的消息拷貝過程。那共享內存的方式,就很好的解決了這一問題。

現代操作系統,對于內存管理,采用的是虛擬內存技術,也就是每個進程都有自己獨立的虛擬內存空間,不同進程的虛擬內存映射到不同的物理內存中。所以,即使進程 A 和 進程 B 的虛擬地址是一樣的,其實訪問的是不同的物理內存地址,對于數據的增刪查改互不影響。

共享內存的機制,就是拿出一塊虛擬地址空間來,映射到相同的物理內存中。這樣這個進程寫入的東西,另外一個進程馬上就能看到了,都不需要拷貝來拷貝去,傳來傳去,大大提高了進程間通信的速度。

信號量用了共享內存通信方式,帶來新的問題,那就是如果多個進程同時修改同一個共享內存,很有可能就沖突了。例如兩個進程都同時寫一個地址,那先寫的那個進程會發現內容被別人覆蓋了。

為了防止多進程競爭共享資源,而造成的數據錯亂,所以需要保護機制,使得共享的資源,在任意時刻只能被一個進程訪問。正好,信號量就實現了這一保護機制。

信號量其實是一個整型的計數器,主要用于實現進程間的互斥與同步,而不是用于緩存進程間通信的數據。

信號量表示資源的數量,控制信號量的方式有兩種原子操作:

一個是 P 操作,這個操作會把信號量減去 -1,相減后如果信號量 < 0,則表明資源已被占用,進程需阻塞等待;相減后如果信號量 >= 0,則表明還有資源可使用,進程可正常繼續執行。另一個是 V 操作,這個操作會把信號量加上 1,相加后如果信號量 <= 0,則表明當前有阻塞中的進程,于是會將該進程喚醒運行;相加后如果信號量 > 0,則表明當前沒有阻塞中的進程;P 操作是用在進入共享資源之前,V 操作是用在離開共享資源之后,這兩個操作是必須成對出現的。

信號上面說的進程間通信,都是常規狀態下的工作模式。對于異常情況下的工作模式,就需要用「信號」的方式來通知進程。

信號跟信號量雖然名字相似度 66.66%,但兩者用途完全不一樣,就好像 Java 和 JavaScript 的區別。

在 Linux 操作系統中, 為了響應各種各樣的事件,提供了幾十種信號,分別代表不同的意義。我們可以通過 kill -l 命令,查看所有的信號:

$ kill -l1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

信號是進程間通信機制中唯一的異步通信機制,因為可以在任何時候發送信號給某一進程,一旦有信號產生,我們就有下面這幾種,用戶進程對信號的處理方式。

1.執行默認操作。Linux 對每種信號都規定了默認操作,例如,上面列表中的 SIGTERM 信號,就是終止進程的意思。Core 的意思是 Core Dump,也即終止進程后,通過 Core Dump 將當前進程的運行狀態保存在文件里面,方便程序員事后進行分析問題在哪里。

2.捕捉信號。我們可以為信號定義一個信號處理函數。當信號發生時,我們就執行相應的信號處理函數。

3.忽略信號。當我們不希望處理某些信號的時候,就可以忽略該信號,不做任何處理。有兩個信號是應用進程無法捕捉和忽略的,即 SIGKILL 和 SEGSTOP,它們用于在任何時候中斷或結束某一進程。

Socket前面提到的管道、消息隊列、共享內存、信號量和信號都是在同一臺主機上進行進程間通信,那要想跨網絡與不同主機上的進程之間通信,就需要 Socket 通信了。

實際上,Socket 通信不僅可以跨網絡與不同主機的進程間通信,還可以在同主機上進程間通信。

我們來看看創建 socket 的系統調用:

int socket(int domain, int type, int protocal)

三個參數分別代表:

domain 參數用來指定協議族,比如 AF_INET 用于 IPV4、AF_INET6 用于 IPV6、AF_LOCAL/AF_UNIX 用于本機;type 參數用來指定通信特性,比如 SOCK_STREAM 表示的是字節流,對應 TCP、SOCK_DGRAM 表示的是數據報,對應 UDP、SOCK_RAW 表示的是原始套接字;protocal 參數原本是用來指定通信協議的,但現在基本廢棄。因為協議已經通過前面兩個參數指定完成,protocol 目前一般寫成 0 即可;根據創建 socket 類型的不同,通信的方式也就不同:

實現 TCP 字節流通信: socket 類型是 AF_INET 和 SOCK_STREAM;實現 UDP 數據報通信:socket 類型是 AF_INET 和 SOCK_DGRAM;實現本地進程間通信: 「本地字節流 socket 」類型是 AF_LOCAL 和 SOCK_STREAM,「本地數據報 socket 」類型是 AF_LOCAL 和 SOCK_DGRAM。另外,AF_UNIX 和 AF_LOCAL 是等價的,所以 AF_UNIX 也屬于本地 socket;

3.JUC用過哪些?

  • JUC的atomic包下運用了CAS的AtomicBoolean、AtomicInteger、AtomicReference等原子變量類
  • JUC的locks包下的AbstractQueuedSynchronizer(AQS)以及使用AQS的ReentantLock(顯式鎖)、ReentrantReadWriteLock
  • JUC下的一些同步工具類:CountDownLatch(閉鎖)、Semaphore(信號量)、CyclicBarrier(柵欄)、FutureTask
  • JUC下的一些并發容器類:ConcurrentHashMap、CopyOnWriteArrayList
  • JUC下的一些Executor框架的相關類: 線程池的工廠類->Executors 線程池的實現類->ThreadPoolExecutor/ForkJoinPoolJUC下的一些阻塞隊列實現類:ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue

4.synchronized和Lock的區別

不同點:

  • synchronized是關鍵字,Lock是接口;
  • synchronized是隱式的加鎖,lock是顯式的加鎖;
  • synchronized底層采用的是objectMonitor,lock采用的AQS;
  • synchronized是阻塞式加鎖,lock是非阻塞式加鎖支持可中斷式加鎖,支持超時時間的加鎖;
  • synchronized在進行加鎖解鎖時,只有一個同步隊列和一個等待隊列, lock有一個同步隊列,可以有多個等待隊列;
  • synchronized只支持非公平鎖,lock支持非公平鎖和公平鎖;
  • synchronized使用了object類的wait和notify進行等待和喚醒, lock使用了condition接口進行等待和喚醒(await和signal);
  • synchronized采用悲觀鎖,lock采用樂觀鎖
  • synchronized無法判斷鎖的狀態,而Lock可以采用tryLock(),嘗試獲取鎖,可以判斷鎖的狀態。
  • synchronized在獲取鎖的線程執行完代碼或者發生異常后線程釋放鎖,而Lock不會釋放鎖,所以一般在finally中必須釋放鎖,否則容易造成線程死鎖。

相同點:

  • 都是可重入鎖
  • 都可以實現線程同步
  • 都用于保護臨界區
  • 其他線程在獲取鎖之前都會被阻塞,等待鎖的釋放。

5.synchronized關鍵字是一個什么鎖?

悲觀鎖、非公平鎖

6.synchronized是否可重入,你對可重入鎖的理解?

synchronized可以重入。

當一個線程已經獲得了 synchronized 鎖,并且在同步代碼塊中執行時,如果它再次嘗試進入同一個鎖的同步代碼塊,不會被阻塞。這是因為 Java 中的 synchronized 機制是基于線程的,而不是基于調用的方法。線程獲得鎖后,會記錄持有鎖的線程信息,如果同一個線程再次嘗試獲得相同的鎖,它會被允許,而不會阻塞。

在 Java 中,可重入鎖(ReentrantLock)通常是使用一個計數器來追蹤鎖的重入次數的,這個計數器的初始值是0。每當同一個線程成功獲取鎖時,計數器會增加1,而每當線程成功釋放鎖時,計數器會減少1。當計數器的值達到0時,鎖被完全釋放,其他線程可以爭奪鎖。

7.線程重入會發生鎖升級嗎?鎖升級的過程?

在 Java 中,鎖重入不會導致鎖升級。鎖升級是指鎖從低級別升級到高級別的過程,而鎖重入是一種鎖的特性,允許同一個線程多次獲取同一個鎖,而不會引發升級。鎖升級通常與鎖的性能和競爭有關,而鎖重入是為了解決同一個線程在多次調用同步方法時的便利性。

8.介紹一下偏向鎖

偏向鎖的思想是偏向于讓第一個獲取鎖對象的線程,這個線程之后重新獲取該鎖不再需要同步操作:

  • 當鎖對象第一次被線程獲得的時候進入偏向狀態,標記為 101,同時使用 CAS 操作將線程 ID 記錄到 Mark Word。如果 CAS 操作成功,這個線程以后進入這個鎖相關的同步塊,查看這個線程 ID 是自己的就表示沒有競爭,就不需要再進行任何同步操作
  • 當有另外一個線程去嘗試獲取這個鎖對象時,偏向狀態就宣告結束,此時撤銷偏向(Revoke Bias)后恢復到未鎖定或輕量級鎖狀態

一個對象創建時:

  • 如果開啟了偏向鎖(默認開啟),那么對象創建后,MarkWord 值為 0x05 即最后 3 位為 101,thread、epoch、age 都為 0
  • 偏向鎖是默認是延遲的,不會在程序啟動時立即生效,如果想避免延遲,可以加 VM 參數 -XX:BiasedLockingStartupDelay=0 來禁用延遲。JDK 8 延遲 4s 開啟偏向鎖原因:在剛開始執行代碼時,會有好多線程來搶鎖,如果開偏向鎖效率反而降低
  • 當一個對象已經計算過 hashCode,就再也無法進入偏向狀態了
  • 如果一個已經處于偏向鎖狀態,然后計算hashCode,將會進行鎖膨脹升級成重量級鎖。
  • 添加 VM 參數 -XX:-UseBiasedLocking 禁用偏向鎖

撤銷偏向鎖的狀態:

  • 調用對象的 hashCode:偏向鎖的對象 MarkWord 中存儲的是線程 id,調用 hashCode 導致偏向鎖被撤銷
  • 當有其它線程使用偏向鎖對象時,會將偏向鎖升級為輕量級鎖
  • 調用 wait/notify,需要申請 Monitor,進入 WaitSet

批量撤銷:如果對象被多個線程訪問,但沒有競爭,這時偏向了線程 T1 的對象仍有機會重新偏向 T2,重偏向會重置對象的 Thread ID

  • 批量重偏向:當撤銷偏向鎖閾值超過 20 次后,JVM 會覺得是不是偏向錯了,于是在給這些對象加鎖時重新偏向至加鎖線程
  • 批量撤銷:當撤銷偏向鎖閾值超過 40 次后,JVM 會覺得自己確實偏向錯了,根本就不該偏向,于是整個類的所有對象都會變為不可偏向的,新建的對象也是不可偏向的

9.介紹一下輕量級鎖

一個對象有多個線程要加鎖,但加鎖的時間是錯開的(沒有競爭),可以使用輕量級鎖來優化,輕量級鎖對使用者是透明的(不可見)

可重入鎖:線程可以進入任何一個它已經擁有的鎖所同步著的代碼塊,可重入鎖最大的作用是避免死鎖

輕量級鎖在沒有競爭時(鎖重入時),每次重入仍然需要執行 CAS 操作,Java 6 才引入的偏向鎖來優化

鎖重入實例:

static final Object obj = new Object();
public static void method1() {synchronized( obj ) {// 同步塊 Amethod2();}
}
public static void method2() {synchronized( obj ) {// 同步塊 B}
}
  • 創建鎖記錄(Lock Record)對象,每個線程的棧幀都會包含一個鎖記錄的結構,存儲鎖定對象的 Mark Word

  • 讓鎖記錄中 Object reference 指向鎖住的對象,并嘗試用 CAS 替換 Object 的 Mark Word,將 Mark Word 的值存入鎖記錄

  • 如果 CAS 替換成功,對象頭中存儲了鎖記錄地址和狀態 00(輕量級鎖) ,表示由該線程給對象加鎖

  • 如果 CAS 失敗,有兩種情況:

    • 如果是其它線程已經持有了該 Object 的輕量級鎖,這時表明有競爭,進入鎖膨脹過程
    • 如果是線程自己執行了 synchronized 鎖重入,就添加一條 Lock Record 作為重入的計數
  • 當退出 synchronized 代碼塊(解鎖時)

    • 如果有取值為 null 的鎖記錄,表示有重入,這時重置鎖記錄,表示重入計數減 1
    • 如果鎖記錄的值不為 null,這時使用 CAS 將 Mark Word 的值恢復給對象頭
      • 成功,則解鎖成功
      • 失敗,說明輕量級鎖進行了鎖膨脹或已經升級為重量級鎖,進入重量級鎖解鎖流程

10.了解鎖膨脹嗎?

在嘗試加輕量級鎖的過程中,CAS 操作無法成功,可能是其它線程為此對象加上了輕量級鎖(有競爭),這時需要進行鎖膨脹,將輕量級鎖變為重量級鎖

  • 當 Thread-1 進行輕量級加鎖時,Thread-0 已經對該對象加了輕量級鎖
  • Thread-1 加輕量級鎖失敗,進入鎖膨脹流程:為 Object 對象申請 Monitor 鎖,通過 Object 對象頭獲取到持鎖線程,將 Monitor 的 Owner 置為 Thread-0,將 Object 的對象頭指向重量級鎖地址,然后自己進入 Monitor 的 EntryList BLOCKED
  • 當 Thread-0 退出同步塊解鎖時,使用 CAS 將 Mark Word 的值恢復給對象頭失敗,這時進入重量級解鎖流程,即按照 Monitor 地址找到 Monitor 對象,設置 Owner 為 null,喚醒 EntryList 中 BLOCKED 線程

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

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

相關文章

LeetCode56. Merge Intervals

文章目錄 一、題目二、題解 一、題目 Given an array of intervals where intervals[i] [starti, endi], merge all overlapping intervals, and return an array of the non-overlapping intervals that cover all the intervals in the input. Example 1: Input: interva…

目標檢測mAP計算以及coco評價標準

這篇是我對嗶哩嗶哩up主 霹靂吧啦Wz 的視頻的文字版學習筆記 感謝他對知識的分享 講一下目標檢測中的一些常見的指標 在我們使用目標檢測網絡訓練時 最后在驗證集上會得到一個coco的評價列表 就像我們圖中給的這一系列參數列表一樣 我們再進一步引入兩個概念 第一個叫做precisi…

P1 Qt的認識及環境配置

目錄 前言 01 下載Qt Creator windows下載安裝包拷貝到Linux Linux直接下載 02 Linux 安裝Qt 前言 &#x1f3ac; 個人主頁&#xff1a;ChenPi &#x1f43b;推薦專欄1: 《C_ChenPi的博客-CSDN博客》??? &#x1f525; 推薦專欄2: 《Linux C應用編程&#xff08;概念類…

地址欄不安全提示

在使用瀏覽器時訪問網站的時候&#xff0c;我們可能會遇到地址欄提示不安全的情況。這種情況通常都是是由于未安裝有效SSL證書或者網站SSL證書過期等原因導致的。本文將介紹如何處理地址欄提示不安全的問題&#xff0c;以確保我們的上網安全。 1&#xff0c;缺少SSL證書&#x…

golang游戲服務器 - tgf系列課程01

TGF框架的特點和功能 課程介紹了TGF框架的特點和功能在第一節課程中我們并不會介紹框架的使用。我們希望在這節課程中,能讓你了解到tgf是一個什么樣的框架 概要 本節課程介紹了TGF框架的特點和功能。TGF是一個開箱即用的服務器框架, 適合中小型團隊和獨立開發者進行游戲開發。…

基于單片機音樂盒仿真仿真系統設計

**單片機設計介紹&#xff0c;基于單片機音樂盒仿真仿真系統設計 文章目錄 一 概要二、功能設計設計思路 三、 軟件設計原理圖 五、 程序六、 文章目錄 一 概要 基于單片機的音樂盒仿真仿真系統是一種基于嵌入式系統技術的設計方案&#xff0c;用于模擬傳統的音樂盒功能。它通…

002 self-attention自注意力

目錄 一、環境 二、self-attention原理 三、完整代碼 一、環境 本文使用環境為&#xff1a; Windows10Python 3.9.17torch 1.13.1cu117torchvision 0.14.1cu117 二、self-attention原理 自注意力&#xff08;Self-Attention&#xff09;操作是基于 Transformer 的機器翻…

【XILINX】記錄ISE/Vivado使用過程中遇到的一些warning及解決方案

前言 XILINX/AMD是大家常用的FPGA&#xff0c;但是在使用其開發工具ISE/Vivado時免不了會遇到很多warning&#xff0c;(大家是不是發現程序越大warning越多&#xff1f;)&#xff0c;并且還有很多warning根據消除不了&#xff0c;看著特心煩&#xff1f; 我這里匯總一些我遇到的…

http和https區別

http和https區別 HTTP&#xff08;Hypertext Transfer Protocol&#xff09;和HTTPS&#xff08;Hypertext Transfer Protocol Secure&#xff09;是用于在網絡上傳輸數據的兩種協議。它們之間的主要區別在于安全性和數據傳輸方式&#xff1a; 安全性&#xff1a;HTTP是明文傳…

華清遠見嵌入式學習——QT——作業2

作業要求&#xff1a; 代碼運行效果圖&#xff1a; 登錄失敗 和 最小化 和 取消登錄 登錄成功 和 X號退出 代碼&#xff1a; ①&#xff1a;頭文件 #ifndef LOGIN_H #define LOGIN_H#include <QMainWindow> #include <QLineEdit> //行編輯器類 #include…

如何在centos8上配置一個ca證書頒發機構并且頒發一個自簽名證書【超詳細!!!】

在CentOS 8上配置CA證書頒發機構并頒發自簽名證書的步驟如下&#xff1a; 1. 安裝OpenSSL sudo dnf install openssl 2. 創建CA證書目錄 sudo mkdir /etc/pki/CA/ sudo chmod 0700 /etc/pki/CA/ 3. 創建CA證書數據庫 sudo touch /etc/pki/CA/index.txt sudo echo 1000 >…

Java Spring + SpringMVC + MyBatis(SSM)期末作業項目

本系統是一個圖書管理系統&#xff0c;比較適合當作期末作業主要技術棧如下&#xff1a; - 數據庫&#xff1a;MySQL - 開發工具&#xff1a;IDEA - 數據連接池&#xff1a;Druid - Web容器&#xff1a;Apache Tomcat - 項目管理工具&#xff1a;Maven - 版本控制工具&#xf…

探索人工智能領域——每日20個名詞詳解【day12】

目錄 前言 正文 總結 &#x1f308;嗨&#xff01;我是Filotimo__&#x1f308;。很高興與大家相識&#xff0c;希望我的博客能對你有所幫助。 &#x1f4a1;本文由Filotimo__??原創&#xff0c;首發于CSDN&#x1f4da;。 &#x1f4e3;如需轉載&#xff0c;請事先與我聯系以…

學習JVM

java虛擬機 流程&#xff1a;helloworld.java----(javac編譯)----helloworld.class-------(java運行)——JVM——機器碼JVM功能 *解釋和運行 *內存管理 *即時編譯&#xff08;跨平臺-慢一點&#xff09;jit &#xff08;反復用到的代碼 解釋保存再內存里面&#xff09;…

進程、線程、線程池狀態

線程幾種狀態和狀態轉換 進程主要寫明三種基本狀態&#xff1a; 線程池的幾種狀態&#xff1a;

STM32的BKP與RTC簡介

芯片的供電引腳 引腳表橙色的是芯片的供電引腳&#xff0c;其中VSS/VDD是芯片內部數字部分的供電&#xff0c;VSSA/VDDA是芯片內部模擬部分的供電&#xff0c;這4組以VDD開頭的供電都是系統的主電源&#xff0c;正常使用時&#xff0c;全部都要接3.3V的電源上&#xff0c;VBAT是…

Leetcode2477. 到達首都的最少油耗

Every day a Leetcode 題目來源&#xff1a;2477. 到達首都的最少油耗 解法1&#xff1a;貪心 深度優先搜索 題目等價于給出了一棵以節點 0 為根結點的樹&#xff0c;并且初始樹上的每一個節點上都有一個人&#xff0c;現在所有人都需要通過「車子」向結點 0 移動。 對于…

從阻抗匹配看擁塞控制

先來理解阻抗匹配&#xff0c;但我不按傳統方式解釋&#xff0c;因為傳統方案你要先理解如何定義阻抗&#xff0c;然后再學習什么是輸入阻抗和輸出阻抗&#xff0c;最后再看如何讓它們匹配&#xff0c;而讓它們匹配的目標僅僅是信號不反射&#xff0c;以最大能效被負載接收。 …

面試寶典之自我介紹

聽人勸、吃飽飯,奉勸各位小伙伴,不要訂閱該文所屬專欄。 如需要項目實戰或者是體系化資源,文末名片加V! 作者:哈哥撩編程,工作十余年, 從事過全棧研發、產品經理等工作,目前在公司擔任研發部門CTO。榮譽:2022年度博客之星Top4、2023年度超級個體得主、谷歌與亞馬遜開發…

Amazon CodeWhisperer 開箱初體驗

文章作者&#xff1a;Coder9527 科技的進步日新月異&#xff0c;正當人工智能發展如火如荼的時候&#xff0c;各大廠商在“解放”碼農的道路上不斷創造出各種 Coding 利器&#xff0c;今天在下就帶大家開箱體驗一個 Coding 利器&#xff1a; Amazon CodeWhisperer。 亞馬遜云科…