F Core 批量寫與“軟實時”一致性:ExecuteUpdate / COPY / SqlBulkCopy 的取舍與事務權衡

EF Core 批量寫與“軟實時”一致性:ExecuteUpdate / COPY / SqlBulkCopy 的取舍與事務權衡 ?


📚 目錄

  • EF Core 批量寫與“軟實時”一致性:ExecuteUpdate / COPY / SqlBulkCopy 的取舍與事務權衡 ?
    • 1. 術語與目標 🧭
    • 2. 技術選型總覽 🧰
    • 3. 建模與熱點隔離 🌋
    • 4. 寫通道:背壓 + 微批 🛣?
    • 5. 三類批量寫法與工程細節 🔧
      • 5.1 集合級更新/刪除:`ExecuteUpdate / ExecuteDelete` ??
      • 5.2 PostgreSQL:`COPY BINARY`(Npgsql) 🐘🚀
      • 5.3 SQL Server:`SqlBulkCopy`(常規 + 流式)🧱??
    • 6. 事務與隔離級別 🧪
    • 7. 一致性策略(面向業務的選擇)??
    • 8. 讀寫一致性與緩存 🧩
    • 9. 可觀測性與告警(最低集)📈🔔
    • 10. 實驗與基準 🧪🧪
      • 10.1 微基準(BenchmarkDotNet)
      • 10.2 壓測(k6):**uuidv4()** ?
    • 11. 失敗與回滾策略 🛡?
    • 12. 代碼與配置清單 🧱
      • 12.1 模型
      • 12.2 DbContext(PG/SQL Server 通用)
      • 12.3 批量實現(核心方法)
      • 12.4 Web API 入隊口(限流/限包/校驗)
      • 12.5 appsettings(關鍵參數)
    • 13. 選型決策樹 🌳


TL;DR

  • 插入為主:PostgreSQL 選 COPY(Binary);SQL Server 選 SqlBulkCopy

  • 更新/刪除為主:優先 ExecuteUpdate/ExecuteDelete(集合級 DML,無需加載實體)。

  • Upsert:PG 用 INSERT ... ON CONFLICT DO UPDATE;SQL Server 用 MERGE(小批量+唯一約束,謹慎)。

  • 一致性:高吞吐優先 有界通道 + 微批,以時間窗 + 條數雙門限觸發;讀側承諾軟實時 SLO并可回補。

  • 要點

    • COPY FROM 會觸發表觸發器/檢查約束(不觸發 rules);timestamptz 只接受 UTC
    • SqlBulkCopy 默認觸發觸發器/檢查約束;可用選項顯式開啟;超大批量改流式

1. 術語與目標 🧭

  • 批量寫:一次提交多行 DML,追求吞吐、降低往返/日志/WAL 開銷。
  • 軟實時一致性:允許讀模型滯后幾十毫秒~數秒,但有可觀測上限(SLO)與回補(冪等補償/重放)。
  • 目標:最大化寫吞吐(不拖垮庫)、讀延遲可控、失敗可回收、全鏈路可觀測。

2. 技術選型總覽 🧰

場景首選備選關鍵點
批量插入(PG)COPY (Binary)多值 INSERT/ON CONFLICTCOPY 吞吐最佳;COPY FROM 觸發表觸發器、檢查約束(不觸發 rules)。
批量插入(SQL Server)SqlBulkCopy多值 INSERT/MERGE默認不觸發觸發器/不檢查約束,需 `FireTriggersCheckConstraints;可用 TableLock`。
批量更新/刪除ExecuteUpdate/ExecuteDeleteMERGE/手寫 SQL集合級 DML,不載入實體,單語句更新/刪除。
UpsertPG ON CONFLICT DO UPDATESQL Server MERGE有唯一約束/冪等鍵;MERGE 歷史缺陷多,生產務必小批+足量測試。
讀你所寫小批同步提交+版本水位——吞吐受限,適合強一致界面。
軟實時(推薦)有界通道+微批刷寫Outbox/事件→讀庫給定追平上限(SLO);提供刷新/通知與水位線。

數據通路(分層 + 批觸發條件)

Database Layer 💿
App Layer
Validate & Throttle
PG
SQL Server
批量條件更新
DB
Bounded Channel 📦
API Ingest 📨
BulkWriter 👷
Copy Binary 🚀
SqlBulkCopy ??
ExecuteUpdate ??
Note
Read/Cache 🔎

3. 建模與熱點隔離 🌋

  • 冪等鍵:如 (tenant_id, business_id) 唯一約束,支撐 Upsert 與重放;Upsert 日志需記錄影響行數沖突鍵用于審計。
  • 分區/分片:分散寫熱點到不同分區/索引;SQL Server 可使用分區表與合適 FILLFACTOR,PG 可用聲明式分區。
  • 索引策略:大批量導入前可暫時禁用或移除次要非聚集索引,導入后再重建;或設置較低 FILLFACTOR 減少頁分裂。
  • 任務/隊列表(PG):FOR UPDATE SKIP LOCKED 支持多消費者不阻塞拉取,適合軟實時流水線。

4. 寫通道:背壓 + 微批 🛣?

關鍵:有界通道(滿→等待/丟棄/降級)、事件驅動消費WaitToReadAsync)、雙門限(條數/時間)、錯誤防護/死信冪等重放

// Program.cs
builder.Services.AddHostedService<BulkWriter>();
builder.Services.AddSingleton(Channel.CreateBounded<WriteItem>(new BoundedChannelOptions(50_000) {FullMode = BoundedChannelFullMode.Wait, // DropOldest/DropNewest/DropWrite 按需選擇SingleReader = true, SingleWriter = false}));// (可選)DbContext 池化,降低分配開銷
builder.Services.AddDbContextPool<AppDbContext>(o => /* options */);
public sealed class BulkWriter : BackgroundService
{private readonly Channel<WriteItem> _ch;private readonly IServiceProvider _sp;private const int MaxBatch = 5000;private static readonly TimeSpan MaxWait = TimeSpan.FromMilliseconds(100);public BulkWriter(Channel<WriteItem> ch, IServiceProvider sp) { _ch = ch; _sp = sp; }protected override async Task ExecuteAsync(CancellationToken ct){var buffer = new List<WriteItem>(MaxBatch);var lastFlush = System.Diagnostics.Stopwatch.StartNew();while (await _ch.Reader.WaitToReadAsync(ct)){while (_ch.Reader.TryRead(out var item)){buffer.Add(item);if (buffer.Count >= MaxBatch) break;}if (buffer.Count >= MaxBatch || lastFlush.Elapsed >= MaxWait){await FlushSafeAsync(buffer, ct);buffer.Clear();lastFlush.Restart();}}// drainif (buffer.Count > 0) await FlushSafeAsync(buffer, ct);}private async Task FlushSafeAsync(List<WriteItem> batch, CancellationToken ct){if (batch.Count == 0) return;try { await FlushAsync(batch, ct); }catch (Exception ex){// TODO: 打點/日志await DeadLetterSink.WriteAsync(batch, ex, ct); // -> 死信}}private async Task FlushAsync(List<WriteItem> batch, CancellationToken ct){using var scope = _sp.CreateScope();var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();if (db.Database.IsNpgsql()) await BulkImpl.PostgresCopyAsync(db, batch, ct);else if (db.Database.IsSqlServer()){if (batch.Count >= 100_000)await BulkImpl.SqlServerBulkCopyStreamAsync(db, batch, ct); // 超大批:流式elseawait BulkImpl.SqlServerBulkCopyAsync(db, batch, ct);      // 常規:DataTable}}
}

時序(背壓/Accepted/批刷寫)

Client 🌐API Ingest 🚪Bounded Channel 📦BulkWriter 👷Database 💿POST /api/ingestTryWrite / WaitToWrite429 Too Many Requests ?202 Accepted ?WaitToReadAsync()items (<= MaxBatch or timeout MaxWait)COPY / SqlBulkCopy / ExecuteUpdateCommit/Resultalt[Channel Full][Accept]Client 🌐API Ingest 🚪Bounded Channel 📦BulkWriter 👷Database 💿

5. 三類批量寫法與工程細節 🔧

5.1 集合級更新/刪除:ExecuteUpdate / ExecuteDelete ??

var cutoff = DateTimeOffset.UtcNow.AddHours(-1);
var affected = await db.Orders.Where(o => o.TenantId == tenant && o.Status == OrderStatus.Pending && o.UpdatedAt < cutoff).ExecuteUpdateAsync(s => s.SetProperty(o => o.Status, _ => OrderStatus.Closed).SetProperty(o => o.UpdatedAt, _ => DateTimeOffset.UtcNow), ct);
// 記錄 affected 便于審計;注意:該路徑繞開樂觀并發標記/行版本

5.2 PostgreSQL:COPY BINARY(Npgsql) 🐘🚀

await using var conn = (NpgsqlConnection)db.Database.GetDbConnection();
if (conn.State != ConnectionState.Open) await conn.OpenAsync(ct);await using var wr = conn.BeginBinaryImport("COPY public.metrics (tenant_id, id, ts, value) FROM STDIN (FORMAT BINARY)");foreach (var r in rows)
{wr.StartRow();wr.Write(r.TenantId, NpgsqlDbType.Text);wr.Write(r.Id, NpgsqlDbType.Uuid);// ? timestamptz 只接受 UTC(Offset=0)wr.Write(r.Ts.ToUniversalTime(), NpgsqlDbType.TimestampTz);wr.Write(r.Value, NpgsqlDbType.Double);
}
await wr.CompleteAsync(ct); // 未 Complete/Dispose 即取消并回滾

多次 COPY 納入同一事務:外層 BeginTransaction(),多次 COPY 后統一 Commit()

5.3 SQL Server:SqlBulkCopy(常規 + 流式)🧱??

常規(DataTable) —— 便于快速復現:

await using var conn = (SqlConnection)db.Database.GetDbConnection();
if (conn.State != ConnectionState.Open) await conn.OpenAsync(ct);
await using var tx = await conn.BeginTransactionAsync(ct);using var bulk = new SqlBulkCopy(conn,SqlBulkCopyOptions.CheckConstraints | SqlBulkCopyOptions.FireTriggers | SqlBulkCopyOptions.TableLock,(SqlTransaction)tx)
{DestinationTableName = "[dbo].[metrics]",BatchSize = 5000,BulkCopyTimeout = 120
};var table = new DataTable();
table.Columns.Add("tenant_id", typeof(string));
table.Columns.Add("id", typeof(Guid));
table.Columns.Add("ts", typeof(DateTimeOffset));  // -> datetimeoffset
table.Columns.Add("value", typeof(double));
foreach (var r in rows) table.Rows.Add(r.TenantId, r.Id, r.Ts, r.Value);bulk.ColumnMappings.Add("tenant_id", "tenant_id");
bulk.ColumnMappings.Add("id", "id");
bulk.ColumnMappings.Add("ts", "ts");
bulk.ColumnMappings.Add("value", "value");bulk.NotifyAfter = 5000;
bulk.SqlRowsCopied += (_, e) => Console.WriteLine($"Copied: {e.RowsCopied}");await bulk.WriteToServerAsync(table, ct);
await tx.CommitAsync(ct);

超大批(流式:低內存) —— 切換閾值示例 >= 100_000

public static async Task SqlServerBulkCopyStreamAsync(AppDbContext db, List<WriteItem> rows, CancellationToken ct)
{var conn = (SqlConnection)db.Database.GetDbConnection();if (conn.State != ConnectionState.Open) await conn.OpenAsync(ct);var meta = new[]{new SqlMetaData("tenant_id", SqlDbType.NVarChar, 128),new SqlMetaData("id", SqlDbType.UniqueIdentifier),new SqlMetaData("ts", SqlDbType.DateTimeOffset),new SqlMetaData("value", SqlDbType.Float)};IEnumerable<SqlDataRecord> Stream(){foreach (var r in rows){var rec = new SqlDataRecord(meta);rec.SetString(0, r.TenantId);rec.SetGuid(1, r.Id);rec.SetDateTimeOffset(2, r.Ts);rec.SetDouble(3, r.Value);yield return rec;}}using var bulk = new SqlBulkCopy(conn){DestinationTableName = "[dbo].[metrics]",BatchSize = 5000,BulkCopyTimeout = 120};await bulk.WriteToServerAsync(Stream().GetEnumerator(), ct);
}

說明:SqlBulkCopyOptions 默認不觸發觸發器/不檢查約束;如需等效常規 DML,請顯式開啟。若有標識列并需保留源值,使用 KeepIdentity


6. 事務與隔離級別 🧪

  • 小批多提 vs 大批一提:小批降低鎖持有和回滾代價;大批吞吐更高但失敗成本大。

  • 隔離級別

    • SQL Server:啟用 RCSIREAD_COMMITTED_SNAPSHOT ON)在讀已提交下讀取版本,減少讀寫沖突。
    • PostgreSQL:任務/隊列使用 FOR UPDATE SKIP LOCKED 避免“搶同一行”。
  • 冪等:唯一鍵 + Upsert,保證“效果一次”。


7. 一致性策略(面向業務的選擇)??

策略描述讀你所寫吞吐實施
強同步API 等到落庫小批同步提交
軟實時(推薦)API 快速 ACK,后臺批寫,承諾追平上限(SLO)可配有界通道+微批+“水位線”
最終一致讀庫異步構建最高Outbox/Event→讀庫

一致性戰略圖(含 p99 SLA)

軟實時
最終一致
業務寫請求
一致性需求?
同步落庫 ??
有界通道 + 微批 ??
事件/Outbox → 讀庫 🔁
水位線/通知 🔔
讀你所寫 ?
追平 SLA 📏
p99 ≤ 2s
最大吞吐 ?

8. 讀寫一致性與緩存 🧩

  • 寫后短期寫側緩存(30–120s TTL),鍵含 (tenant,key,version)
  • 批更新后發布失效事件或寫水位線(如 last_applied_offset),供前端判斷“是否追平”。

9. 可觀測性與告警(最低集)📈🔔

  • 寫通道:入隊速率、隊列深度、高/低水位、批大小、批耗時 p95/p99、失敗/重試率。
  • 數據庫:鎖等待、WAL/日志增長、檢查點時間、索引膨脹。
  • SLO:入隊→可讀 p99 ≤ 2s,連續 5 分鐘越界告警。
  • 實現建議:統一封裝 Prometheus/OpenTelemetry 指標(把 SqlRowsCopied、EF LogTo、隊列深度等采集起來)。

10. 實驗與基準 🧪🧪

10.1 微基準(BenchmarkDotNet)

[MemoryDiagnoser]
public class BulkBench
{private readonly List<WriteItem> _batch = DataGen.Generate(5000);private AppDbContext _db = default!;[GlobalSetup]public void Setup() => _db = DbFactory.Create();[Benchmark] public Task PG_Copy() => BulkImpl.PostgresCopyAsync(_db, _batch, CancellationToken.None);[Benchmark] public Task SQL_BulkCopy() => BulkImpl.SqlServerBulkCopyAsync(_db, _batch, CancellationToken.None);[Benchmark] public Task EF_ExecuteUpdate() => BulkImpl.ExecuteUpdateAsync(_db, CancellationToken.None);
}

10.2 壓測(k6):uuidv4() ?

import http from 'k6/http';
import { sleep } from 'k6';
import { uuidv4 } from 'https://jslib.k6.io/k6-utils/1.4.0/index.js';export const options = { vus: 50, duration: '2m' };function genItems(n) {const items = [];for (let i = 0; i < n; i++) {items.push({tenantId: 't1',id: uuidv4(), // ?ts: new Date().toISOString(),value: Math.random()});}return items;
}export default function () {const payload = JSON.stringify({ tenantId: 't1', items: genItems(100) });http.post('http://localhost:5000/api/ingest', payload, { headers: { 'Content-Type': 'application/json' } });sleep(0.1);
}

11. 失敗與回滾策略 🛡?

  • 批失敗二分:將失敗批二分定位壞記錄(或壞子集),異常數據入死信并記錄原因/哈希。
  • 重試:指數退避,超限轉死信;日終冪等補償腳本按唯一鍵重放。
  • 審計:批次表記錄 batch_idcountfailuresdur_ms、時間戳。

建議準備 dead_letters 表(含批次 ID、異常摘要、payload hash、首次/末次時間、重試次數)。


12. 代碼與配置清單 🧱

12.1 模型

public record WriteItem(string TenantId, Guid Id, DateTimeOffset Ts, double Value);public class Metric
{public string TenantId { get; set; } = default!;public Guid Id { get; set; }public DateTimeOffset Ts { get; set; }public double Value { get; set; }
}

12.2 DbContext(PG/SQL Server 通用)

public class AppDbContext : DbContext
{public DbSet<Metric> Metrics => Set<Metric>();public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }protected override void OnModelCreating(ModelBuilder b){b.Entity<Metric>(e =>{e.ToTable("metrics");e.HasKey(x => new { x.TenantId, x.Id }); // 冪等鍵e.Property(x => x.Ts).HasColumnName("ts");e.HasIndex(x => x.Ts);});}
}

12.3 批量實現(核心方法)

public static class BulkImpl
{public static async Task PostgresCopyAsync(AppDbContext db, List<WriteItem> rows, CancellationToken ct){var conn = (NpgsqlConnection)db.Database.GetDbConnection();if (conn.State != ConnectionState.Open) await conn.OpenAsync(ct);await using var wr = conn.BeginBinaryImport("COPY public.metrics (tenant_id, id, ts, value) FROM STDIN (FORMAT BINARY)");foreach (var r in rows){wr.StartRow();wr.Write(r.TenantId, NpgsqlDbType.Text);wr.Write(r.Id, NpgsqlDbType.Uuid);wr.Write(r.Ts.ToUniversalTime(), NpgsqlDbType.TimestampTz); // ? UTCwr.Write(r.Value, NpgsqlDbType.Double);}await wr.CompleteAsync(ct); // 未 Complete 則回滾}// 常規模式:DataTablepublic static async Task SqlServerBulkCopyAsync(AppDbContext db, List<WriteItem> rows, CancellationToken ct){var table = new DataTable();table.Columns.Add("tenant_id", typeof(string));table.Columns.Add("id", typeof(Guid));table.Columns.Add("ts", typeof(DateTimeOffset));table.Columns.Add("value", typeof(double));foreach (var r in rows) table.Rows.Add(r.TenantId, r.Id, r.Ts, r.Value);var conn = (SqlConnection)db.Database.GetDbConnection();if (conn.State != ConnectionState.Open) await conn.OpenAsync(ct);using var bulk = new SqlBulkCopy(conn,SqlBulkCopyOptions.CheckConstraints | SqlBulkCopyOptions.FireTriggers | SqlBulkCopyOptions.TableLock,null){DestinationTableName = "[dbo].[metrics]",BatchSize = 5000,BulkCopyTimeout = 120};bulk.ColumnMappings.Add("tenant_id", "tenant_id");bulk.ColumnMappings.Add("id", "id");bulk.ColumnMappings.Add("ts", "ts");bulk.ColumnMappings.Add("value", "value");bulk.NotifyAfter = 5000;bulk.SqlRowsCopied += (_, e) => Console.WriteLine($"Copied: {e.RowsCopied}");await bulk.WriteToServerAsync(table, ct);}// 流式模式:IEnumerable<SqlDataRecord>(低內存)public static async Task SqlServerBulkCopyStreamAsync(AppDbContext db, List<WriteItem> rows, CancellationToken ct){var conn = (SqlConnection)db.Database.GetDbConnection();if (conn.State != ConnectionState.Open) await conn.OpenAsync(ct);var meta = new[]{new SqlMetaData("tenant_id", SqlDbType.NVarChar, 128),new SqlMetaData("id", SqlDbType.UniqueIdentifier),new SqlMetaData("ts", SqlDbType.DateTimeOffset),new SqlMetaData("value", SqlDbType.Float)};IEnumerable<SqlDataRecord> Stream(){foreach (var r in rows){var rec = new SqlDataRecord(meta);rec.SetString(0, r.TenantId);rec.SetGuid(1, r.Id);rec.SetDateTimeOffset(2, r.Ts);rec.SetDouble(3, r.Value);yield return rec;}}using var bulk = new SqlBulkCopy(conn){DestinationTableName = "[dbo].[metrics]",BatchSize = 5000,BulkCopyTimeout = 120};await bulk.WriteToServerAsync(Stream().GetEnumerator(), ct);}public static async Task ExecuteUpdateAsync(AppDbContext db, CancellationToken ct){var cutoff = DateTimeOffset.UtcNow.AddHours(-1);var rows = await db.Metrics.Where(m => m.Ts < cutoff).ExecuteUpdateAsync(s => s.SetProperty(m => m.Value, m => m.Value * 0.99), ct);// rows -> 審計}
}

12.4 Web API 入隊口(限流/限包/校驗)

[ApiController, Route("api/ingest")]
public class IngestController : ControllerBase
{private readonly Channel<WriteItem> _ch;public IngestController(Channel<WriteItem> ch) => _ch = ch;[HttpPost][RequestSizeLimit(5 * 1024 * 1024)] // 5MB:防大包;按需上調public async Task<IActionResult> Post([FromBody] IngestRequest req, CancellationToken ct){if (req.Items is null || req.Items.Count == 0 || req.Items.Count > 10_000)return BadRequest("Items count out of range");foreach (var it in req.Items){var ok = await _ch.Writer.WaitToWriteAsync(ct) && _ch.Writer.TryWrite(it);if (!ok) return StatusCode(StatusCodes.Status429TooManyRequests); // 背壓}return Accepted(); // 軟實時快速 ACK}
}public record IngestRequest(string TenantId, List<WriteItem> Items);

12.5 appsettings(關鍵參數)

{"Bulk": {"MaxBatchSize": 5000,"MaxBatchIntervalMs": 100,"ChannelCapacity": 50000,"Retry": { "MaxAttempts": 3, "BaseDelayMs": 100 }},"ConnectionStrings": {"Pg": "Host=localhost;Username=postgres;Password=postgres;Database=app;","Sql": "Server=localhost,1433;User Id=sa;Password=Pass@word1;Encrypt=False;TrustServerCertificate=True"}
}

13. 選型決策樹 🌳

批量插入 PG
批量插入 SQL
批量更新/刪除
你的寫入主要類型?
PG: COPY Binary ?
SQL: SqlBulkCopy ?
EF ExecuteUpdate/Delete ?
需要 Upsert?
需要 Upsert?
PG ON CONFLICT 🔁
Done
SQL MERGE 謹慎 🔁
Done
Done

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

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

相關文章

基于PSO粒子群多目標優化的微電網調度算法matlab仿真

目錄 1.課題概述 2.系統仿真結果 3.核心程序 4.系統原理簡介 4.1 改進粒子群算法 4.2 分布式電源與儲能模型公式 4.3 多目標函數 5.參考文獻 6.完整工程文件 1.課題概述 微電網優化調度的核心是在滿足系統約束&#xff08;如功率平衡、設備出力限制等&#xff09;的前…

Spring AI ChatClient集成Deepseek

Spring AI ChatClient集成Deepseek 下文將簡述如何通過spring ai集成deepseek實現智能對話。在開始之前你需要在deepseek官網申請一個apikey,并設置到系統變量中&#xff0c;保障安全性。 ChatModel 在集成deepseek前&#xff0c;我們先要了解一個chat model&#xff0c;chat m…

Azure微軟云內網接入問題

1. 域名解析失敗 azure需要給ClientSecretCredentialBuilder和AzureResourceManager都配置HTTP 代理,但還是會域名解析失敗,netty會調用InetAddress.getByName解析域名.最終只能在hosts文件寫死host和ip映射關系 2. netty版本不匹配,導致報錯netty某個方法找不到 azure只用引入…

【IDEA】設置Debug調試時調試器不進入特定類(Spring框架、Mybatis框架)

問題 以Ruoyi-Vue項目為例&#xff0c;以Debug方式啟動項目&#xff0c;在com.ruoyi.web.controller.system.SysUserController#list()方法中的userService.selectUserList(user)處打上斷點&#xff0c;訪問[系統管理–用戶管理]頁面&#xff0c;程序就會執行到該斷點處此時按下…

OpenCV 視頻處理全解析

OpenCV 視頻處理全解析&#xff1a;從基礎操作到高級應用?在計算機視覺領域&#xff0c;視頻處理是一個核心且廣泛應用的技術方向。無論是安防監控、自動駕駛還是短視頻特效&#xff0c;都離不開對動態視頻流的智能分析與處理。OpenCV 作為最流行的開源計算機視覺庫&#xff0…

java如何使用正則提取字符串中的內容

在Java中使用正則表達式提取字符串內容&#xff0c;主要通過java.util.regex包中的Pattern和Matcher類實現。以下是詳細步驟和示例&#xff1a;1. 基礎流程 import java.util.regex.Matcher; import java.util.regex.Pattern;public class RegexExample {public static void ma…

Baumer高防護相機如何通過YoloV8深度學習模型實現行人跌倒的檢測識別(C#代碼UI界面版)

《------往期經典推薦------》 AI應用軟件開發實戰專欄【鏈接】 序號項目名稱項目名稱11.工業相機 YOLOv8 實現人物檢測識別&#xff1a;&#xff08;C#代碼&#xff0c;UI界面版&#xff09;2.工業相機 YOLOv8 實現PCB的缺陷檢測&#xff1a;&#xff08;C#代碼&#xff0…

jetson orin nx(8G)燒錄super系統實錄

1. 說明 2. 下載新版發布包&#xff08;在PC上下載&#xff09; Jetson Linux Archive | NVIDIA Developer 安裝的jetpack版本為6.2.1&#xff08;rev.2)對應的Jetson Linux 36.4.4 點擊綠色區域的36.4.4>&#xff0c;進入下載頁面&#xff0c;如下 點擊Driver Package(B…

LeetCode算法日記 - Day 11: 尋找峰值、山脈數組的峰頂索引

目錄 1. 尋找峰值 1.1 題目解析 1.2 解法 1.3 代碼實現 2. 山脈數組 2.1 題目解析 2.2 解法 2.3 代碼實現 1. 尋找峰值 162. 尋找峰值 - 力扣&#xff08;LeetCode&#xff09; 峰值元素是指其值嚴格大于左右相鄰值的元素。 給你一個整數數組 nums&#xff0c;找到峰…

Cherryusb UAC例程對接STM32 SAI播放音樂和錄音(下)=>USB+SAI+TX+RX+DMA控制WM8978播放和錄音實驗

1. 程序基本框架 整個程序框架, 與之前的一篇文章《Cherryusb UAC例程對接STM32內置ADC和DAC播放音樂和錄音(中)>UACSTM32 ADCDAC實現錄音和播放》基本一致, 只是這次將ADC和DAC替換成了SAI TX/RX。因此這里不再贅述了。2. sai_dma_wm8978_usb.c主程序的實現說明 在menuconf…

Docker運行python項目:使用Docker成功啟動FastAPI應用

根據昨天成功使用阿里云鏡像加速后&#xff0c;我是根據windows本地的python項目&#xff0c;直接傳到了centos&#xff0c;然后再導入到docker里面&#xff0c;然后進行運行&#xff0c;主要是發現運行的時候&#xff0c;老是提示一些庫的問題&#xff0c;還有就是一些python老…

PowerShell來關閉 Windows 安全中心

你可以使用 PowerShell 來關閉 Windows 安全中心的盾牌圖標&#xff08;通知&#xff09;。以下是幾種方法&#xff0c;包括禁用通知、關閉 Windows Defender&#xff08;不推薦&#xff09;或調整注冊表。方法 1&#xff1a;禁用 Windows 安全中心通知&#xff08;推薦&#x…

基于深度學習的老照片修復系統

背景隨著時間的推移&#xff0c;老照片可能會因褪色、損壞或曝光不當而影響其視覺質量。這些珍貴的影像承載著歷史和回憶&#xff0c;但由于物理損耗&#xff0c;它們的觀賞價值和可讀性逐漸下降。為了恢復這些照片的清晰度和色彩&#xff0c;本項目采用深度學習與先進的圖像處…

深入解析Tomcat目錄結構

Apache Tomcat 是一個強大的 Servlet 容器,它不僅支持 Java Servlet 和 JSP 技術,還提供了豐富的功能來幫助開發者構建和部署動態的 Web 應用。為了更好地理解和使用 Tomcat,了解其文件結構和組成部分是至關重要的。本文將深入探討 Tomcat 的目錄結構及其各個組件的作用。 …

專題:2025抖音電商與微短劇行業研究報告|附150+份報告PDF匯總下載

原文鏈接&#xff1a;https://tecdat.cn/?p43595 當618大促的硝煙散去&#xff0c;抖音電商的生態分化愈發刺眼&#xff1a;服飾內衣以27.5%的份額穩坐頭把交椅&#xff0c;而無數中小商家卻在“流量荒”中掙扎。這場看似繁榮的盛宴里&#xff0c;平臺規則如同無形的手&#x…

3.Ansible自動化之-編寫和運行playbook

3.Ansible編寫和運行 Playbook Playbook 介紹 如果把 Ansible 的ad-hoc命令比作 “一次性腳本”&#xff08;適合臨時執行單個簡單任務&#xff09;&#xff0c;那么Playbook就是 “可重復執行的程序”&#xff08;適合復雜、多步驟的管理流程&#xff09;。 舉個例子&#…

Vue實時刷新,比如我提交審核,審核頁面還需要點查詢才能看到最新數據

refreshTimer: null,lastRefreshTime: null}; }, created() {console.log(組件創建&#xff0c;初始化數據...);this.loadLatestData();this.setupAutoRefresh(); }, activated() {// 當使用keep-alive時&#xff0c;組件激活時刷新數據console.log(組件激活&#xff0c;刷新數…

Docker入門:容器化技術的第一堂課

Docker入門&#xff1a;容器化技術的第一堂課 &#x1f31f; 你好&#xff0c;我是 勵志成為糕手 &#xff01; &#x1f30c; 在代碼的宇宙中&#xff0c;我是那個追逐優雅與性能的星際旅人。 ? 每一行代碼都是我種下的星光&#xff0c;在邏輯的土壤里生長成璀璨的銀河&#…

【SLAM】不同相機模型及其常見的鏈式求導推導

【SLAM】不同相機模型及其常見的鏈式求導推導1. 魚眼相機模型鏈式求導1. 魚眼相機畸變模型2. 雅可比矩陣的推導畸變坐標相對于歸一化坐標的雅可比矩陣 Hdz/dznH_{dz/dzn}Hdz/dzn?畸變坐標相對于相機內參的雅可比矩陣 Hdz/dzetaH_{dz/dzeta}Hdz/dzeta?3. 注意4. 輸入輸出含義5…

【人工智能】本地部署 KTransformers并加載大模型筆記

博主未授權任何人或組織機構轉載博主任何原創文章&#xff0c;感謝各位對原創的支持&#xff01; 博主鏈接 本人就職于國際知名終端廠商&#xff0c;負責modem芯片研發。 在5G早期負責終端數據業務層、核心網相關的開發工作&#xff0c;目前牽頭6G技術研究。 博客內容主要圍繞…