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技术研究。 博客内容主要围绕…