Java并發鎖相關

鎖相關

?1. 什么是可重入鎖?Java 中如何實現???
?答?:
可重入鎖允許一個線程多次獲取同一把鎖(即遞歸調用時無需重新競爭鎖)。

  • ?關鍵點?:防止死鎖,避免線程因重復請求已持有的鎖而阻塞。
  • ?Java 實現?:
  • synchronized:隱式支持可重入。
    public synchronized void methodA() {
    methodB(); // 可重入
    }
    public synchronized void methodB() {}
  • ReentrantLock:顯式鎖,通過計數器實現可重入。
    ReentrantLock lock = new ReentrantLock();
    public void method() {
    lock.lock();
    try {
    // 遞歸調用或其他同步代碼
    } finally {
    lock.unlock();
    }
    }
    ?2. ReentrantLock 與 synchronized 的區別???
    ?特性??synchronized??ReentrantLock??實現方式?JVM 關鍵字,自動管理鎖JDK 類,需手動加鎖/解鎖?鎖獲取靈活性?不支持中斷或超時支持tryLock()、lockInterruptibly()?公平性?非公平鎖可選公平/非公平模式(構造函數指定)?條件變量?僅通過wait()/notify()關聯一個條件支持多個Condition對象?鎖釋放?自動釋放(退出同步塊或異常)必須在finally中手動釋放

?3. 什么是讀寫鎖(ReadWriteLock)???
?答?:
讀寫鎖分離讀操作(共享)和寫操作(獨占),提升并發性能。

  • ?規則?:
  • 讀鎖:允許多線程同時讀,但排斥寫鎖。
  • 寫鎖:獨占鎖,排斥其他所有讀寫鎖。
  • ?適用場景?:讀多寫少(如緩存)。
  • ?Java 實現?:ReentrantReadWriteLock
    ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
    public void readData() {
    rwLock.readLock().lock();
    try {
    // 讀操作
    } finally {
    rwLock.readLock().unlock();
    }
    }
    public void writeData() {
    rwLock.writeLock().lock();
    try {
    // 寫操作
    } finally {
    rwLock.writeLock().unlock();
    }
    }
    ?4. 死鎖產生的條件?如何避免???
    ?死鎖條件?:
    1.?互斥?:資源獨占。
    2.?持有且等待?:線程持有資源并等待其他資源。
    3.?不可搶占?:資源只能由持有線程釋放。
    4.?循環等待?:多個線程形成資源請求閉環。
    ?避免方法?:
  • ?破壞循環等待?:按固定順序獲取鎖(如按鎖對象的哈希值排序)。
    public void transfer(Account a, Account b, int amount) {
    Object firstLock = a.hashCode() < b.hashCode() ? a : b;
    Object secondLock = firstLock == a ? b : a;
    synchronized (firstLock) {
    synchronized (secondLock) {
    // 轉賬操作
    }
    }
    }
  • ?超時機制?:使用 tryLock() 設置超時時間。
    if (lock1.tryLock(1, TimeUnit.SECONDS)) {
    try {
    if (lock2.tryLock(1, TimeUnit.SECONDS)) {
    try { /* … */ } finally { lock2.unlock(); }
    }
    } finally { lock1.unlock(); }
    }
  • ?銀行家算法?:動態檢查資源分配是否安全(實際開發較少用)。
    ?5. 樂觀鎖與悲觀鎖的區別???
    ?類型??原理??實現??適用場景??悲觀鎖?假設會發生沖突,先加鎖再操作synchronized、ReentrantLock寫多讀少?樂觀鎖?假設無沖突,更新時檢查版本號CAS 操作(如AtomicInteger)、StampedLock讀多寫少

?CAS 示例?:
AtomicInteger count = new AtomicInteger(0);
public void increment() {
int oldVal, newVal;
do {
oldVal = count.get();
newVal = oldVal + 1;
} while (!count.compareAndSet(oldVal, newVal)); // CAS 更新
}
?6. synchronized 鎖升級過程???
1.?無鎖?:初始狀態。
2.?偏向鎖?:鎖被同一線程多次訪問時,記錄線程 ID(避免 CAS 操作)。
3.?輕量級鎖?:當多線程競爭時,通過 CAS 自旋嘗試獲取鎖(減少阻塞)。
4.?重量級鎖?:自旋超過閾值后,轉為操作系統級互斥鎖(線程阻塞)。

  • ?目的?:平衡性能與開銷,減少直接使用重量級鎖的成本。
    ?7. volatile 能否替代鎖???
    ?答?:?不能完全替代。

  • ?volatile 特性?:

  • 保證可見性:修改后立即刷新到主內存。

  • 禁止指令重排序(內存屏障)。

  • ?不足?:

  • 不保證原子性(如 i++ 需配合鎖或原子類)。

  • 無法實現互斥訪問(如臨界區保護)。
    ?適用場景?:

  • 狀態標記(如 boolean flag = true)。

  • 單次讀寫操作(如 long、double 的 64 位寫入)。
    ?8. 什么是自旋鎖???
    ?答?:線程在獲取鎖失敗時,不立即阻塞而是循環(自旋)重試,避免上下文切換開銷。

  • ?實現?:
    public class SpinLock {
    private AtomicReference owner = new AtomicReference<>();

    public void lock() {
    Thread t = Thread.currentThread();
    while (!owner.compareAndSet(null, t)) {
    // 自旋等待
    }
    }
    public void unlock() {
    owner.set(null);
    }
    }

  • ?適用場景?:鎖持有時間短、線程數少。

  • ?缺點?:長時間自旋浪費 CPU(JDK 的自旋鎖有自適應策略)。
    ?9. StampedLock 是什么???
    ?答?:Java 8 引入的高性能讀寫鎖,支持三種模式:
    1.?寫鎖?:獨占鎖(類似 ReentrantReadWriteLock 的寫鎖)。
    2.?悲觀讀鎖?:共享鎖(類似讀鎖)。
    3.?樂觀讀?:無鎖操作,需驗證是否有寫發生。
    StampedLock sl = new StampedLock();

// 樂觀讀
long stamp = sl.tryOptimisticRead();
if (!sl.validate(stamp)) { // 檢查期間是否有寫操作
stamp = sl.readLock(); // 轉為悲觀讀
try { /* … */ } finally { sl.unlockRead(stamp); }
}

  • ?優勢?:樂觀讀避免鎖開銷,提升讀性能。
    ?10. Condition 接口的作用???
    ?答?:配合 ReentrantLock 實現線程等待/喚醒機制,可替代 Object.wait()/notify()。
  • ?優勢?:支持多個等待隊列(如生產者-消費者模型)。
    java運行復制ReentrantLock lock = new ReentrantLock();
    Condition notFull = lock.newCondition(); // 隊列未滿條件
    Condition notEmpty = lock.newCondition(); // 隊列非空條件

// 生產者
public void put(Object item) {
lock.lock();
try {
while (queue.isFull()) notFull.await(); // 等待未滿
queue.add(item);
notEmpty.signal(); // 喚醒消費者
} finally { lock.unlock(); }
}

// 消費者
public Object take() {
lock.lock();
try {
while (queue.isEmpty()) notEmpty.await(); // 等待非空
notFull.signal(); // 喚醒生產者
return queue.remove();
} finally { lock.unlock(); }
}
?11. 鎖消除(Lock Elision)和鎖粗化(Lock Coarsening)是什么???

  • ?鎖消除?:JIT 編譯器移除不必要的鎖(如局部變量鎖)。
    public String concat(String s1, String s2) {
    StringBuffer sb = new StringBuffer(); // 局部變量,線程安全
    sb.append(s1).append(s2);
    return sb.toString();
    }
    // JIT 可能移除 StringBuffer 的同步操作
  • ?鎖粗化?:合并多次加鎖/解鎖操作為一次(減少開銷)。
    synchronized (obj) { /* 操作1 / }
    synchronized (obj) { /
    操作2 / }
    // 優化后 =>
    synchronized (obj) { /
    操作1+操作2 */ }
    ?12. 如何檢測死鎖???
    1.?命令行工具?:
  • jstack :查看線程堆棧,標記死鎖信息。
  • jconsole:圖形化檢測死鎖。
    2.?代碼檢測?:
    ThreadMXBean bean = ManagementFactory.getThreadMXBean();
    long[] threadIds = bean.findDeadlockedThreads();
    if (threadIds != null) {
    // 處理死鎖
    }
    總結
  • ?基礎鎖?:synchronized(隱式)、ReentrantLock(顯式)。
  • ?高級鎖?:ReadWriteLock、StampedLock、Condition。
  • ?鎖優化?:鎖升級、消除、粗化。
  • ?避免死鎖?:順序加鎖、超時機制。
  • ?工具?:樂觀鎖(CAS)、原子類、并發工具包(java.util.concurrent)。

synchronized和lock
synchronized vs Lock(以ReentrantLock為例)詳解
?1. 實現機制?
?特性??synchronized??Lock(ReentrantLock)???實現級別?JVM 內置關鍵字(字節碼指令monitorenter/monitorexit)JDK API(Java 類實現)?鎖狀態保存?鎖狀態存儲在對象頭中(Mark Word)AQS(AbstractQueuedSynchronizer)維護鎖狀態

?2. 使用方式?
// ========== synchronized ==========
// 1. 方法級鎖
public synchronized void syncMethod() { // }

// 2. 代碼塊鎖
public void method() {
synchronized(this) { // 鎖對象可以是任意對象
// 臨界區代碼
}
}

// ========== Lock ==========
private final Lock lock = new ReentrantLock();

public void lockMethod() {
lock.lock(); // 必須手動加鎖
try {
// 臨界區代碼
} finally {
lock.unlock(); // 必須放在finally中保證釋放
}
}
?3. 核心功能對比?
?功能??synchronized??Lock??可中斷鎖?? 不可中斷?lockInterruptibly()?嘗試獲取鎖?? 不支持?tryLock()/tryLock(timeout)?公平鎖?? 只有非公平鎖? 可構造公平鎖(new ReentrantLock(true))?多條件變量?? 單條件(wait()/notify())? 多個Condition對象?鎖綁定多條件?? 不能?lock.newCondition()?鎖釋放?自動釋放(代碼塊結束/異常)必須手動調用unlock()

?4. 性能差異?

  • ?Java 5 之前?:synchronized 性能遠低于 Lock(線程阻塞涉及內核態切換)
  • ?Java 6 及以后?:
  • synchronized 引入鎖升級機制?(偏向鎖→輕量級鎖→重量級鎖)
  • 兩者性能差距大幅縮小
  • 建議:
  • ?簡單場景? → 優先用 synchronized(簡潔安全)
  • ?復雜場景? → 用 Lock(利用高級功能)
    ?5. 鎖升級過程(synchronized優化)??
    圖片代碼首次獲取鎖其他線程競爭自旋超過閾值無鎖狀態偏向鎖輕量級鎖:自旋適應重量級鎖:線程阻塞
    ?6. 條件變量對比?
    // ===== synchronized 單條件 =====
    synchronized(lockObj) {
    while(!condition) lockObj.wait(); // 只能使用一個條件
    // 業務代碼
    lockObj.notifyAll();
    }

// ===== Lock 多條件 =====
private final Condition notEmpty = lock.newCondition();
private final Condition notFull = lock.newCondition();

// 生產者
lock.lock();
try {
while(queue.isFull()) notFull.await(); // 特定條件等待
// 生產操作
notEmpty.signal(); // 喚醒特定條件
} finally { lock.unlock(); }

// 消費者
lock.lock();
try {
while(queue.isEmpty()) notEmpty.await();
// 消費操作
notFull.signal();
} finally { lock.unlock(); }
?7. 適用場景總結?
?場景??推薦方案??原因?簡單同步(如單方法加鎖)? synchronized代碼簡潔,自動釋放需要等待超時/中斷響應? LocktryLock(timeout)/lockInterruptibly()分組喚醒線程? Lock + Condition精確控制不同等待隊列公平鎖需求? ReentrantLock(true)synchronized 只能是非公平鎖需要鎖統計信息? ReentrantLock可獲取等待線程數等狀態簡單讀寫分離? synchronized如果寫操作簡單,可用同步方法代替讀寫鎖

?8. 關鍵差異總結?
?維度??synchronized??Lock??本質?JVM 原生特性Java API 接口?死鎖恢復?需外部干預(重啟/JDKTools)可用tryLock防止死鎖?代碼控制?自動管理需要顯式聲明lock()和unlock()?靈活性?基礎同步功能提供細粒度控制能力?監控?JConsole可查看Monitor狀態可編程獲取鎖狀態(如getQueueLength())?分布式擴展?不支持可通過Redisson等實現分布式鎖

💡 ?最終建議?:

  • 優先用 ?synchronized?(簡潔安全,JVM持續優化)
  • 遇到以下需求時改用 ?Lock?:
    ? 需要等待超時/中斷響應
    ? 分組喚醒線程
    ? 公平鎖需求
    ? 需要獲取鎖的詳細信息

鎖升級過程中什么是偏向鎖→輕量級鎖→重量級鎖?什么是自旋?

鎖升級過程詳解(從偏向鎖→輕量級鎖→重量級鎖)
?1. 偏向鎖(Biased Locking)??

  • ?目的?:消除無競爭情況下的同步開銷
  • ?適用場景?:單線程多次訪問同步塊
  • ?實現原理?:
    // 對象頭存儲結構
    |-------------------------------------------------------|
    | Mark Word (64 bits) |
    |-------------------------------------------------------|
    | unused:25 | identity_hashcode:31 | unused:1 | age:4 | biased_lock:1 | lock:2 |
    |-------------------------------------------------------|
  • 首次獲取鎖時,JVM將線程ID寫入對象頭(biased_lock=1, lock=01)
  • 后續進入同步塊時直接比對線程ID,無需CAS操作
  • ?特點?:
  • 只需一次CAS開銷(首次)
  • 單線程重復訪問無同步成本
  • ?示例?:
    synchronized(lock) { /* 第1次進入:CAS設置偏向鎖 / }
    synchronized(lock) { /
    第2次進入:直接檢查線程ID */ }
    ?2. 輕量級鎖(Lightweight Locking)??
  • ?觸發條件?:第二個線程嘗試獲取鎖(偏向鎖撤銷)
  • ?實現原理?:
    a.JVM在線程棧幀中創建Lock Record
    b.復制對象頭到Lock Record(Displaced Mark Word)
    c.CAS嘗試將對象頭替換為指向Lock Record的指針
    d.成功獲取鎖(lock狀態置為00)
  • ?鎖競爭處理?:
    while (true) {
    if (嘗試CAS成功) { break; }
    else if (自旋超過閾值) { 升級為重量級鎖 }
    else { continue; } // 繼續自旋
    }
  • ?特點?:
  • 通過自旋避免線程阻塞
  • 適合短時間持有鎖的場景
  • 自旋消耗CPU但減少線程切換
    ?3. 重量級鎖(Heavyweight Locking)??
  • ?觸發條件?:自旋失敗或等待線程數過多
  • ?實現原理?:
    圖片代碼Object Header指向Monitor對象Owner:持有鎖的線程EntryList:競爭隊列WaitSet:等待隊列
  • 依賴操作系統的互斥量(mutex)
  • 未獲鎖線程直接阻塞(用戶態→內核態切換)
  • ?特點?:
  • 開銷大(涉及上下文切換)
  • 防止CPU空轉
  • 支持更復雜的同步機制

?自旋(Spinning)詳解?
?1. 核心思想?

  • ?不阻塞線程,而是在循環中重試獲取鎖

  • 示例自旋鎖實現:
    public class SpinLock {
    private AtomicReference owner = new AtomicReference<>();

    public void lock() {
    Thread t = Thread.currentThread();
    while (!owner.compareAndSet(null, t)) {
    // 空循環重試(自旋)
    }
    }

    public void unlock() {
    owner.set(null);
    }
    }
    ?2. 自旋策略?
    ?策略類型??描述??實現??固定次數自旋?設置固定重試次數for (int i=0; i<MAX_SPIN; i++)?自適應自旋?JVM根據歷史成功率動態調整自旋時間HotSpot默認策略?條件自旋?結合條件變量避免無限自旋while (!condition && spins>0)

?3. 開銷分析?
?場景??CPU開銷??延遲??適用性?自旋成功低極低? 理想情況自旋失敗高中?? 浪費CPU資源阻塞/喚醒低高?? 上下文切換開銷大

?4. 最佳實踐?
1.?短任務優先自旋?
if (!lock.tryLock()) {
for (int i=0; i<MAX_SPIN; i++) { // 限制自旋次數
if (lock.tryLock()) return;
}
lock.lock(); // 自旋失敗后阻塞
}
2.?結合條件檢查?
while (true) {
if (tryAcquireLock()) break;
if (needToBlock()) {
parkThread(); // 放棄自旋
break;
}
}
3.?JVM自適應優化?

  • 歷史數據:統計鎖持有時間
  • 動態調整:自旋時間 ≈ 上次持有時間 * 系數
  • 平臺相關:單核CPU直接禁用自旋

?
?關鍵點總結?
1.?鎖升級?

  • 目標:最小化同步開銷
  • 路徑:無鎖 → 偏向鎖 → 輕量級鎖 → 重量級鎖
  • 不可逆:重量級鎖無法降級(部分JVM支持降級但成本高)
    2.?自旋優化?
  • 目的:避免用戶態→內核態切換
  • 權衡:CPU時間 vs 上下文切換開銷
  • 臨界點:鎖持有時間 ≈ 線程切換時間 * 2
    💡 ?實戰建議?:
    undefined.減少競爭:縮小同步塊范圍
    undefined.分離熱點:讀寫鎖分離(如ConcurrentHashMap)
    undefined.避免升級:控制鎖持有時間短于自旋閾值
    undefined.監控工具:jstack -l 檢查鎖狀態

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

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

相關文章

Pie Menu Editor V1.18.7.exe 怎么安裝?詳細安裝教程(附安裝包)?

??Pie Menu Editor V1.18.7.exe? 是一款用于創建和編輯 ?餅圖菜單&#xff08;Pie Menu&#xff09;?? 的工具軟件&#xff0c;通常用于游戲開發、UI設計、3D建模&#xff08;如 Blender 等&#xff09;、或自定義軟件操作界面。 一、準備工作 ?下載文件? 下載了 ?Pi…

基于Spark的中文文本情感分析系統研究

引言 1.1 研究背景與意義 隨著互聯網的普及和社交媒體的興起、特別是自媒體時代的來臨&#xff0c;網絡文本數據呈現爆炸式增長。這些文本數據蘊含著豐富的用戶情感信息&#xff0c;如何有效地挖掘和利用這些信息&#xff0c;對于了解輿情動態、改進客戶服務、輔助決策分析具…

Simulink子系統、變體子系統及封裝知識

1.引言 文章三相新能源并網系統序阻抗模型——序阻抗分析器IMAnalyzer介紹了一種用于分析和掃描序阻抗的軟件。其中&#xff0c;在序阻抗掃頻操作過程中&#xff0c;用到了一個擾動注入、測量和運算工具【IMtool】&#xff0c;它外表長這樣&#xff1a; 內部長這樣&#xff1a…

高階組件介紹

高階組件約定俗成以with開頭 import React, { useEffect } from react; import { TouchableOpacity, Image, StyleSheet } from react-native;type IReactComponent React.ClassicComponentClass| React.ComponentClass| React.FunctionComponent| React.ForwardRefExoticComp…

C++ STL系列-02.泛型入門

C STL系列-02.泛型入門C中的泛型編程主要通過模板&#xff08;template&#xff09;實現。模板允許我們編寫與類型無關的代碼&#xff0c;是一種將類型作為參數進行編程的方式。在C中&#xff0c;模板分為函數模板和類模板。 1. 函數模板函數模板允許我們定義一個函數&#xff…

高效管理網絡段和端口集合的工具之ipset

目錄 1. 核心命令速查 2. 集合類型 3. 實戰案例&#xff1a;使用 ipset 封禁 IP 案例 1&#xff1a;基礎黑名單封禁&#xff08;手動添加&#xff09; 案例 2&#xff1a;自動過期和解封 案例 3&#xff1a;封禁 IP 和端口組合 案例 4&#xff1a;白名單模式 案例 5&am…

實例和對象的區別

對象&#xff08;Object&#xff09;是一個概念&#xff0c;它表示“某個類的一個成員”&#xff0c;是“邏輯上的個體”。實例&#xff08;Instance&#xff09;是一個現實&#xff0c;指的是在內存中真正分配了空間的對象。實例一定是對象&#xff0c;但對象不一定是實例。例…

Win10 Chrome認不出新Emoji?兩個擴展搞定顯示與輸入

前言 用Win10電腦在Chrome里發消息、刷網頁時&#xff0c;你是否遇到過這樣的尷尬&#xff1a;別人發的、或者頁面顯示的 Emoji&#xff0c;在你屏幕上變成了空白方框&#xff0c;像“文字里缺了一塊拼圖”&#xff1f;其實這不是Chrome的錯&#xff0c;也不用換電腦&#xff0…

Golang中逃逸現象, 變量“何時棧?何時堆?”

目錄 什么是棧 什么是堆 棧 vs 堆&#xff08;核心區別&#xff09; GO編譯器的逃逸分析 什么是逃逸分析&#xff1f; 怎么看逃逸分析結果&#xff1f; 典型“會逃逸”的場景 閉包捕獲局部變量 返回或保存帶有“底層存儲”的容器 經由接口/反射/fmt 等導致裝箱或被長…

MySQL入門指南:從安裝到工作原理

什么是MySQL MySQL是一個開源的關系型數據庫管理系統&#xff0c;由瑞典MySQL AB公司開發&#xff08;目前屬于Oracle公司&#xff09;&#xff0c;被廣泛地應用在大中小型網站中 MySQL是一個小型的開源的關系型數據庫管理系統&#xff0c;與其他大型數據庫管理系統例如&…

dask.dataframe.shuffle.set_index中獲取 divisions 的步驟分析

dask.dataframe.shuffle.set_index 中獲取 divisions 的步驟分析 主要流程概述 在 set_index 函數中&#xff0c;當 divisionsNone 時&#xff0c;系統需要通過分析數據來動態計算分區邊界。這個過程分為以下幾個關鍵步驟&#xff1a; 1. 初始檢查和準備 if divisions is None:…

ai生成ppt工具有哪些?10款主流AI生成PPT工具盤點

隨著人工智能技術的飛速發展&#xff0c;AI生成PPT工具逐漸成為職場人士、學生和創作者提升效率的得力助手。這類工具通過智能算法&#xff0c;能夠快速將文本、數據或創意轉化為結構化、視覺化的演示文稿&#xff0c;大幅節省設計時間。1、AiPPT星級評分&#xff1a;★★★★★…

Qt多線程編程學習

Qt多線程編程學習 1. 項目概述 本項目展示了Qt中多線程編程的基本用法&#xff0c;通過繼承QThread類創建自定義線程&#xff0c;并演示了線程的啟動、執行和銷毀過程。項目包含一個簡單的用戶界面&#xff0c;用戶可以通過按鈕控制線程的啟動和結束。 1.1 項目結構 項目包含以…

加密貨幣武器化:惡意npm包利用以太坊智能合約實現隱蔽通信

ReversingLabs研究人員發現兩個惡意npm包利用以太坊&#xff08;Ethereum&#xff09;智能合約隱藏并傳播惡意軟件。這兩個名為colortoolsv2和mimelib2的軟件包于2025年7月被識別&#xff0c;展現了開源安全攻防戰中的新戰術。惡意軟件包偽裝成實用工具攻擊活動始于7月7日發布的…

Spring Boot 全局字段處理最佳實踐

在日常開發中&#xff0c;我們總會遇到一些瑣碎但又無處不在的字段處理需求&#xff1a;? 請求處理: 用戶提交的表單&#xff0c;字符串前后帶了多余的空格&#xff0c;需要手動 trim()。? 響應處理: 返回給前端的 BigDecimal 金額&#xff0c;因為精度問題導致JS處理出錯&am…

三坐標測量機在汽車制造行業中的應用

在汽車制造業中&#xff0c;零部件精度決定著整車性能。從發動機活塞的微米級公差&#xff0c;到車身焊接的毫米級間隙&#xff0c;汽車制造“差之毫厘&#xff0c;謬以千里” &#xff0c;任何細微偏差都可能引發連鎖反應&#xff1a;發動機抖動、異響、油耗飆升&#xff0c;車…

機床夾具設計 +選型

機床夾具設計—第2組&#xff08;鉆床夾具&#xff09;仿真組裝視頻_嗶哩嗶哩_bilibili 夾具-商品搜索-怡合達一站式采購平臺 米思米FA標準品電子目錄new 可能要吧這些定位塊單獨用yolo訓練一邊才能搞識別分析 3長條一短銷定位&#xff0c;黃色的用來夾緊 一個面加一短軸一棱…

表格識別技術:通過計算機視覺和OCR,實現非結構化表格向結構化數據的轉換,推動數字化轉型。

在日常工作和生活中&#xff0c;我們無處不在與表格打交道。從財務報表、發票收據&#xff0c;到科研論文中的數據表、醫療報告&#xff0c;表格以其清晰、結構化的方式&#xff0c;承載著大量關鍵信息。然而&#xff0c;當這些表格以紙質或圖片等非結構化形式存在時&#xff0…

Go基礎(②Viper)

Viper 讀取配置創建一個配置文件 config.yamlserver:port: 8080timeout: 30 # 超時時間&#xff08;秒&#xff09; database:host: "localhost"user: "root"password: "123456"name: "mydb"然后用 Viper 讀取這個配置&#xff0c;代…

kafka Partition(分區)詳解

一、什么是 PartitionPartition&#xff08;分區&#xff09; 是 Kafka Topic&#xff08;主題&#xff09; 的最小并行單位。一個 Topic 可以包含多個 Partition&#xff0c;每個 Partition 底層對應一個有序、不可變的消息隊列&#xff0c;消息只會順序追加。Partition 內部消…