当前位置: 首页 > news >正文

前端实战中的单例模式:以医疗药敏管理为例

目录

    • 一、什么是单例模式?
      • 1. 状态共享性 —— 数据唯一,任意访问,任意修改
      • 2. 生命周期控制性 —— 自己掌控何时创建、何时销毁
    • 二、实战分析:医疗药敏管理系统中的单例应用
    • 三、其他场景示例
      • 单例实现:ConfigManager.ts
    • 四、单例 VS Pinia

在大型项目中,尤其是业务数据复杂、组件之间需要共享状态的场景里,我们会遇到这样的问题:

某个模块的数据需要在多个地方访问和更新,但我们不希望它被重复实例化,避免状态混乱,如何实现?

这个时候单例模式就要出场了。在本文中,我会结合一个医疗行业中抗生素药敏信息管理的实际案例,剖析单例模式的核心价值、使用场景、代码实践。


一、什么是单例模式?

单例模式的基本结构:

class Singleton {private static instance: Singleton;private constructor() {} // 构造器私有化,禁止外部 newpublic static getInstance(): Singleton {if (!Singleton.instance) {Singleton.instance = new Singleton();}return Singleton.instance;}
}

单例模式的本质是:状态共享 + 生命周期控制

这里有两个关键点:

1. 状态共享性 —— 数据唯一,任意访问,任意修改

单例其实就是一个全局变量 + 封装行为的对象。你创建了一个类,它被实例化一次后,这个实例会在整个项目生命周期中被共享使用,不管你在哪里引用,拿到的都是同一个对象。这就意味着你可以在任意组件中:

  • 读取状态;
  • 修改状态;
  • 保证数据一致。
const instance = useMySingleton(); // 不管在哪里调用,拿到的是同一个实例
instance.setValue(123);

如果你熟悉vue开发,会发现 Pinia 中定义的 store 很相似,比如:

const userStore = useUserStore();
userStore.name = 'zhen';

无论在哪个组件里调用 useUserStore(),拿到的都是同一个 store 实例,状态是同步的。

文章的末尾我们会仔细对比下二者的区别。


2. 生命周期控制性 —— 自己掌控何时创建、何时销毁

单例模式的好处在于:你可以完全控制这个对象的生命周期

  • 什么时候创建(第一次调用才创建);
  • 什么时候重置(提供 reset 方法);
  • 什么时候释放资源(如关闭 socket,清除定时器等)。

这点和 Pinia 有点区别,因为 Pinia 的 store 是响应式的、受 Vue 生命周期自动管理的,你不能完全控制 store 的创建和销毁。

举个例子:

// 单例
const socket = useSocket(); // 第一次调用才创建连接
socket.close(); // 可以手动关闭连接// Pinia
const socketStore = useSocketStore();
socketStore.socket = new WebSocket(...) // 你无法很方便地从外部控制它的初始化时机和销毁逻辑

二、实战分析:医疗药敏管理系统中的单例应用

在 LIS 系统中,医院的微生物实验室都需要进行药敏测试管理。

简单来说,就是当医生从病人身上采集标本后,实验室需要:

  • 分离出可能导致感染的细菌
  • 测试这些细菌对不同抗生素的敏感程度
  • 生成报告帮助医生选择有效的抗生素治疗

在这样的场景下,前端数据管理就需要考虑如下问题:

  1. 状态的集中管理:一个样本可能检出多种细菌,每种细菌又对应多种抗生素的测试结果。这些数据结构复杂且相互关联。如果分散管理,极易导致状态混乱和数据不一致。
  2. 数据共享与同步:用户可能在检出菌列表和药敏结果表格之间频繁切换、编辑。例如,在药敏结果表格中修改了某个抗生素的结果,这个状态需要被准确记录,并且如果后续有保存操作,需要将最新的完整数据提交给后端。
  3. 组件间通信:业务主页面可能包含多个子组件(例如,选择检出菌的组件、编辑药敏结果的组件、引用历史结果的弹窗等)。这些组件可能都需要访问或修改这份核心的药敏数据。
  4. 操作的原子性与数据一致性:当用户选择一个新的检出菌时,可能需要从后端加载默认的药敏模板;当用户修改检出菌名称时,可能需要判断是否要清除已有的药敏结果。这些操作都需要确保数据在不同步骤间保持一致。
  5. 提升可维护性:将数据管理逻辑从视图组件中抽离出来,形成独立的模块,可以使组件代码更专注于视图渲染和用户交互,降低耦合度,提高代码的可读性和可维护性。

那么这种情况下,使用 单例模式 就再合适不过了,我们通过一个类来提供集中的、可控的数据存储和操作接口,所有关于药敏数据的状态变更都通过这个管家来进行,确保了数据的统一和有序。

来看看核心代码逻辑演示:

// 定义数据结构
interface AntibioticResult {// resId: string; // 示例:代表具体字段// ... 更多药敏结果相关字段
}interface BacterialInfo {// bacId: string | number; // 示例:代表具体字段// ... 更多检出菌信息相关字段
}interface DSTestMap {bactRes: BacterialInfo; // 检出菌信息antiResList: AntibioticResult[]; // 相关的药敏结果列表
}/*** AntibioticResistanceMap 类 (核心数据管理类)* 储存和管理检出菌及其对应的药敏测试结果。* 此类采用单例模式,确保全局只有一个实例。*/
class AntibioticResistanceMap {// 使用 Map 结构来存储数据,键为细菌ID,值为检出菌信息和药敏结果列表private tableMap = new Map<string | number, DSTestMap>();/*** 清空映射表中的所有数据。*/public clearTableMap(): void {// 业务逻辑:清空 this.tableMap 实例。// 例如: this.tableMap.clear();}/*** 根据细菌ID删除映射表中的条目。* @param bacId 检出菌ID*/public deleteTableMap(bacId: string | number): void {// 业务逻辑:从 this.tableMap 中删除指定 bacId 的条目。// 例如: if (this.tableMap.has(bacId)) { this.tableMap.delete(bacId); }}/*** 设置或更新指定细菌ID的映射数据。* @param bacId 检出菌ID* @param options 包含检出菌和药敏结果的数据*/public setTableMap(bacId: string | number, options: DSTestMap): void {// 业务逻辑:// 1. (可选) 验证传入的 options 数据是否符合规范 (调用 this.validateData)。// 2. (可选) 对 options 数据进行深拷贝 (调用 this.cloneData) 以避免外部修改影响内部状态。// 3. 将处理后的数据存入 this.tableMap。// 例如: this.tableMap.set(bacId, processedOptions);}/*** 更新已存在的细菌ID的映射数据。* 通常用于部分更新检出菌信息或药敏结果列表。* @param bacId 检出菌ID* @param options 需要部分更新的数据*/public updateTableMap(bacId: string | number, options: Partial<DSTestMap>): void {// 业务逻辑:// 1. 获取 bacId 对应的现有数据。// 2. 将传入的 options 与现有数据合并。// 3. (可选) 验证合并后的数据。// 4. (可选) 对合并后的数据进行深拷贝。// 5. 将更新后的数据存回 this.tableMap。// 例如: const currentData = this.tableMap.get(bacId); /* ...合并与处理... */ this.tableMap.set(bacId, updatedData);}/*** 根据细菌ID获取映射数据。* @param bacId 检出菌ID* @returns 检出菌和药敏结果数据,如果不存在则返回 undefined*/public getTableMap(bacId: string | number): DSTestMap | undefined {// 业务逻辑:// 1. 从 this.tableMap 获取 bacId 对应的数据。// 2. (可选) 对获取的数据进行深拷贝后返回,以防止外部修改。// 例如: const data = this.tableMap.get(bacId); return data ? this.cloneData(data) : undefined;return undefined; // 仅为骨架示例}/*** 检查是否存在指定细菌ID的映射。* @param bacId 检出菌ID* @returns 如果存在则返回 true,否则返回 false*/public hasTableMap(bacId: string | number): boolean {// 业务逻辑:检查 this.tableMap 是否包含 bacId。// 例如: return this.tableMap.has(bacId);return false; // 仅为骨架示例}/*** 获取映射表中所有的数据。* @returns 包含所有检出菌和药敏结果数据的 Map 对象*/public getAllTableMap(): Map<string | number, DSTestMap> {// 业务逻辑:// 1. 创建一个新的 Map。// 2. 遍历 this.tableMap,将每个条目 (可选地进行深拷贝后) 存入新的 Map。// 3. 返回新的 Map。// 例如: const allData = new Map(); this.tableMap.forEach(...); return allData;return new Map(); }/*** 数据验证 (私有辅助方法)。* 用于验证将要存入映射表的数据的结构和内容的正确性。* @param data 需要验证的数据*/private validateData(data: DSTestMap): void {// 内部具体的数据验证逻辑。// 例如: 检查 bactRes 和 antiResList 是否存在,字段是否符合要求等。}/*** 深拷贝数据 (私有辅助方法)。* 用于创建数据的深拷贝副本,以防止原始数据被意外修改。* @param data 需要拷贝的数据* @returns 深拷贝后的数据副本*/private cloneData<T>(data: T): T {// 内部具体的深拷贝实现逻辑。// 例如: return JSON.parse(JSON.stringify(data));return data; // 仅为示例,实际应为深拷贝实现}
}// --- 单例模式实现的核心 ---
// instance 变量用于存储 AntibioticResistanceMap 的唯一实例。
// 初始化为 null,表示尚未创建实例。
let instance: AntibioticResistanceMap | null = null;/*** useDSTestMap Hook (工厂函数)* 这是获取 AntibioticResistanceMap 单例实例的唯一入口。* 如果实例不存在,则创建一个新实例;否则,返回现有实例。* @returns AntibioticResistanceMap 的单例实例*/
export const useDSTestMap = () => {if (!instance) {// 如果 instance 为 null (即第一次调用),则创建 AntibioticResistanceMap 的新实例。instance = new AntibioticResistanceMap();}// 返回(新创建的或已存在的)实例。return instance;
};

以上仅仅是我对这个特定业务场景下的逻辑抽象,来让大家通过代码实例感受单例模式的应用,替换到其他的业务场景也都是类似的。


三、其他场景示例

上面的业务对于没接触过 LIS 业务的人来说,看起来可能有点不直观,接下来举个简单的例子体会下单例模式。

场景:全局配置管理器(ConfigManager)

在中大型前端项目中,经常会有一些全局配置项,比如:

  • 接口基础地址(baseURL)
  • 环境标识(dev/test/prod)
  • 默认请求头
  • 开关配置项(如是否启用 mock、调试日志等)

这些配置需要:

  • 全局唯一且共享
  • 在应用初始化时设定一次
  • 在后续任意模块或组件中都可以访问
  • 可在测试环境或某些场景下动态修改配置(比如切换 API 地址)。

这非常适合用单例模式封装。

单例实现:ConfigManager.ts

// ConfigManager.tstype ConfigOptions = {baseURL: string;env: 'dev' | 'test' | 'prod';enableMock: boolean;
};class ConfigManager {private static instance: ConfigManager;private config: ConfigOptions;private constructor() {// 默认配置this.config = {baseURL: '',env: 'dev',enableMock: false,};}public static getInstance(): ConfigManager {if (!ConfigManager.instance) {ConfigManager.instance = new ConfigManager();}return ConfigManager.instance;}public setConfig(newConfig: Partial<ConfigOptions>) {this.config = { ...this.config, ...newConfig };}public getConfig(): ConfigOptions {return this.config;}public reset() {this.config = {baseURL: '',env: 'dev',enableMock: false,};}
}export default ConfigManager;

✅ 使用示例 1:初始化时配置

// main.tsimport ConfigManager from './ConfigManager';const config = ConfigManager.getInstance();config.setConfig({baseURL: 'https://api.example.com',env: 'prod',enableMock: false,
});

✅ 使用示例 2:任意模块中读取配置

// services/userService.tsimport ConfigManager from '../ConfigManager';export async function fetchUserData() {const { baseURL, enableMock } = ConfigManager.getInstance().getConfig();const url = enableMock? '/mock/user': `${baseURL}/user`;const res = await fetch(url);return res.json();
}

✅ 使用示例 3:切换环境或调试时修改配置

// devtools/configPanel.tsx(假设你有一个设置面板)import ConfigManager from '../ConfigManager';function switchToMockMode() {const config = ConfigManager.getInstance();config.setConfig({enableMock: true,});
}

四、单例 VS Pinia

我们以 vue 开发为背景,看完上面的例子,你可能会想,我用 Pinia 不也一样吗?

其实它们的本质区别就是 状态模型 vs 响应式状态容器

我们来用一张表格来对比下

维度单例模式(如 ConfigManagerPinia
核心目的管理和共享一个全局类实例响应式地管理组件状态
数据结构普通 JS 对象(不可响应)Vue 响应式对象
使用语义传统 OOP(面向对象)Vue 组合式 API(函数式风格)
调用方式ConfigManager.getInstance()useXxxStore()
响应性❌ 无自动响应式,改了数据不会自动更新视图✅ 自动驱动视图更新
依赖框架❌ 完全独立于 Vue,可用于任何项目✅ 必须依赖于 Vue(Pinia)
场景适配配置项、工具类、非 UI 逻辑、模块缓存组件状态、表单数据、视图交互相关状态

所以,对于实际场景的选择:

场景使用单例模式使用 Pinia
全局 API 配置管理✅ 非常合适❌ 太重,没必要响应式
用户登录信息缓存✅ 可行(如 JWT、用户 ID)✅ 更适合响应式场景(比如头像变化自动刷新)
控制 debug 模式、mock 模式✅ 合理、集中式管理❌ 用 Pinia 会显得臃肿
页面内表单状态❌ 不适合,改了没反应✅ 响应式,推荐
多组件共享列表数据❌ 实现复杂、无响应性✅ 很方便,推荐

综上可以看出

  • 是否需要响应式 是选择单例或 Pinia 的核心判断标准;
  • 单例模式适合做“全局共享、非 UI 驱动”的状态管理,比如配置信息、工具类、日志器等;
  • Pinia 是“响应式状态容器”,适合组件状态、UI 状态、交互驱动的逻辑;

相关文章:

前端实战中的单例模式:以医疗药敏管理为例

目录 一、什么是单例模式&#xff1f;1. 状态共享性 —— 数据唯一&#xff0c;任意访问&#xff0c;任意修改2. 生命周期控制性 —— 自己掌控何时创建、何时销毁 二、实战分析&#xff1a;医疗药敏管理系统中的单例应用三、其他场景示例单例实现&#xff1a;ConfigManager.ts…...

如何在 Logback 日志框架中加入链路 ID

在 Logback 日志框架中加入链路 ID&#xff0c;能有效将同一条链路的日志串联起来&#xff0c;便于追踪和排查问题。 1. 生成和管理链路 ID 要保证在整个请求链路里都能获取到链路 ID&#xff0c;可借助 ThreadLocal 来实现。以下是一个简单的工具类示例&#xff1a; import…...

晶振:智能设备的“心跳”如何支撑5G与航天

在现代科技飞速发展的时代&#xff0c;智能设备已深度融入我们生活的方方面面&#xff0c;而晶振&#xff0c;作为智能设备的“心跳”&#xff0c;正默默发挥着不可替代的关键作用。无论是翱翔太空的神舟飞船&#xff0c;还是人们手中须臾不离的智能手机&#xff0c;亦或是推动…...

【HarmonyOS 5】App Linking 应用间跳转详解

目录 什么是 App Linking 使用场景 工作原理 如何开发 1.开通 App Linking 2.确定域名 3.服务端部署 applinking.json 文件 4.AGC绑定域名 5.项目配置 6.组装聚合链接 7.解析聚合链接中的参数 其他 如何获取应用ID 什么是 App Linking App Linking 是一款创建跨…...

neo4j官方示例

目录 一、准备数据 1.执行查看结果 二、操作 1.find 单个节点 2.同上&#xff0c;已某个属性去查询 3. 指定查询个数 4.条件查询 5.查询某个人出演的电影汇总 6.查询tom出演的电影中&#xff0c;还有其他演员的信息。 7.查询跟电影(Cloud Atlas)有关的演员&#xff0…...

基于vueflow可拖拽元素的示例(基于官网示例的单文件示例)

效果图 代码 <template><div style"width: 100%;height: calc(100vh - 84px)"><VueFlow :nodes"nodes" :edges"edges" drop"onDrop" dragover"onDragOver" dragleave"onDragLeave"><div cl…...

minio单点登录与集成(免密)

需求&#xff1a;系统A里&#xff0c;需要实现与MINIO单点登录集成&#xff0c;也就是说&#xff0c;登录了系统A&#xff0c;在访问MINIO时不需要再输入用户密码就可以直接访问。 具体场景如下&#xff1a; 在系统A的一个页面里&#xff0c;配置一个按钮链接&#xff0c;点击…...

深入理解 Docker 网络原理:构建高效、灵活的容器网络

在现代软件开发中&#xff0c;Docker 已经成为了容器化技术的代名词&#xff0c;广泛应用于开发、测试和生产环境。Docker 使得开发者能够将应用及其依赖打包成一个轻量级的容器&#xff0c;并通过 Docker 容器化技术来实现高效的部署与管理。 然而&#xff0c;在日常使用 Dock…...

Hutool中的Pair类详解

1. Pair类概述 Hutool工具库中的Pair类是一个简单的键值对数据结构&#xff0c;用于存储两个相关联的对象。它类似于Map的Entry&#xff0c;但更加轻量级&#xff0c;适用于需要临时存储两个相关联数据的场景。 2. Pair类的主要特点 简单轻量&#xff1a;不依赖复杂的数据结…...

没有Mac,我是怎么上传IPA到App Store的?

没有Mac&#xff0c;我是怎么上传IPA到App Store的&#xff1f; 最近赶一个小项目上线&#xff0c;写的是一个Flutter做的App。安卓版本一晚上搞定&#xff0c;iOS上架却差点把人整崩。 不是我技术菜&#xff0c;是实在太麻烦了。最关键的&#xff0c;是我这台Windows笔电根本…...

RISC-V hardfault分析工具,RTTHREAD-RVBACKTRACE

RV BACKTRACE 简介 本文主要讲述RV BACKTRACE 的内部主要原理 没有接触过rvbacktrace可以看下面两篇文章&#xff0c;理解一下如何使用RVBACKTRACE RVBacktrace RISC-V极简栈回溯组件&#xff1a;https://club.rt-thread.org/ask/article/64bfe06feb7b3e29.html RVBacktra…...

c语言if else语句格式(非常详细)

在C语言中&#xff0c;if else 语句是一种常用的条件控制结构&#xff0c;用于根据不同条件执行不同的代码块。 if-else 语句的基本格式 if-else 语句的基本格式如下&#xff1a; if (条件) { // 如果条件为真&#xff0c;执行这里的代码 } else { // 如果条件为假&a…...

Logback官方文档翻译章节目录

Logback官方文档翻译章节目录 第一章 Logback简介 第二章 Logback的架构&#xff08;一&#xff09; Logback的架构&#xff08;二&#xff09; Logback的架构&#xff08;三&#xff09; 持续更新中…...

按摩椅的机芯类型和材质

按摩椅的机芯类型和材质是影响其按摩效果、使用寿命以及舒适度的重要因素。下面我将从这两个方面详细为你解析&#xff1a; 一、按摩椅机芯类型 按摩椅的“机芯”相当于它的“心脏”&#xff0c;决定了按摩手法、力度、覆盖范围等关键性能。 常见机芯类型&#xff08;按技术发…...

HarmonyOS-hdc远程网络方式连接设备

hdc工具使用手册 1 hdc简介 hdc&#xff08;OpenHarmony Device Connector&#xff09;是为开发人员提供的用于设备连接调试的命令行工具&#xff0c;pc端开发机使用命令行工具hdc&#xff0c;该工具需支持部署在Windows/Linux/Mac等系统上与OpenHarmony设备&#xff08;或模…...

秋招准备——2.跨时钟相关

格雷码异步FIFO跨时钟域处理 格雷码 一、格雷码规律 相邻性&#xff1a;相邻两个数的格雷码只有一位不同&#xff0c;例如&#xff1a; 0000 → 0001&#xff08;仅最低位变化&#xff09;0001 → 0011&#xff08;仅次低位变化&#xff09;0011 → 0010&#xff08;仅最低位…...

【开源版】likeshop上门家政系统PHP版全开源+uniapp前端

一.系统介绍 likeshop_上门家政系统&#xff0c;PHP版本更新至2.1.1最新版&#xff0c;全开源&#xff0c;适用于上门家政场景&#xff0c;系统拥有用户端、师傅端、无论运营还是二开都是性价比极高的100%开源家政系统。 二.搭建环境-教程 系统环境&#xff1a;CentOS、 运行…...

Memgraph 的安装教程

目录 Memgraph 安装步骤1. 使用 Docker 安装 Memgraph2. 使用 Memgraph Lab3. 使用 Python 客户端连接 Memgraph Memgraph 安装步骤 1. 使用 Docker 安装 Memgraph Memgraph 可以通过 Docker 快速安装和运行。以下是使用 Docker 安装 Memgraph 的步骤&#xff1a; 安装 Docke…...

华为网路设备学习-21 路由过滤(filter-policy)

一、路由过滤&#xff08;filter-policy&#xff09; 1、用于控制路由更新、接收的一个工具 2、只能过滤路由信息&#xff0c;无法过滤LSA 二、路由过滤&#xff08;filter-policy&#xff09;与动态路由协议 1、距离矢量路由协议 RIP动态路由协议 交换的是路由表&#xff0…...

Mac 平台 字体Unicode范围分析器

字体Unicode范围分析器 #include <CoreText/CoreText.h> // CoreText框架头文件&#xff0c;用于字体处理 #include <CoreFoundation/CoreFoundation.h> // CoreFoundation框架头文件 #include <stdio.h> // 标准输入输出 #include…...

Android不能下载Gradle,解决方法Could not install Gradle distribution from.......

外网下载速度太慢导致失败&#xff0c;换成国内镜像&#xff0c;可加速下载&#xff1a; 官网地址&#xff1a;https://services.gradle.org/distributions/ 腾讯云镜像 Gradle下载地址&#xff1a;https://mirrors.cloud.tencent.com/gradle/ 阿里云镜像 Gradle下载地址&…...

树状数组的操作问题--Python

树状数组的操作问题 一、问题引入二、解题步骤1.思维导图2.解题步骤 三、代码实现1.代码2.复杂度分析 四、个人总结 一、问题引入 请编写程序&#xff0c;实现树状数组区间求前缀和、单点修改的操作。 输入格式&#xff1a; 输入首先给出一个正整数 n&#xff08;2≤n<10^…...

FEKO许可限制

随着科技的飞速发展&#xff0c;电磁仿真软件在多个领域发挥着越来越重要的作用。FEKO作为一款业界领先的电磁仿真软件&#xff0c;广泛应用于通信、雷达、航空航天、电子对抗等领域。然而&#xff0c;为了确保软件使用的合规性与高效性&#xff0c;FEKO设定了相应的许可限制。…...

第5章 深度学习和卷积神经网络

深度学习是人工智能的一种实现方法。本章我们将考察作为深度学习的代表的卷积神经网络的数学结构。 5-1小恶魔来讲解卷积神经网络的结构 深度学习是重叠了很多层的隐藏层&#xff08;中间层&#xff09;的神经网络。这样的神经网络使隐藏层具有一定的结构&#xff0c;从而更加…...

window 显示驱动开发-处理内存段(一)

视频内存管理器 (VidMm) 负责管理 GPU 的地址空间。 在此之前&#xff0c;内核模式显示微型端口驱动程序 (KMD) 必须通过使用内存段将 GPU 的地址空间描述为 VidMm。 KMD 创建内存段以概括和虚拟化视频内存资源。 它可以根据硬件支持的存储器类型&#xff08;例如&#xff0c;…...

QT实现曲线图缩放、拖拽以及框选放大

.h文件 protected: void saveAxisRange();void wheelEvent(QWheelEvent *event) override;void mousePressEvent(QMouseEvent *event) override;void mouseMoveEvent(QMouseEvent *event) override;void mouseReleaseEvent(QMouseEvent *event) override;private:QPoint m_…...

龙虎榜——20250508

上证假阴包阳的走势&#xff0c;量能较昨天有萎缩&#xff0c;在前期压力附近~ 深证这两天假阴包阳的走势&#xff0c;60分钟未突破昨天的高点&#xff0c;缺口也未补等待明天的选择~ 2025年5月8日龙虎榜行业方向分析 一、核心行业方向 军工航天&#xff08;政策催化地缘驱动…...

SEMI E40-0200 STANDARD FOR PROCESSING MANAGEMENT(加工管理标准)-(三)完结

10 消息服务详情 10.1 本章定义实现加工管理概念所需的消息服务。这些消息已在第8.1节中初步介绍。 协议无关性&#xff1a;这些服务独立于所使用的消息协议&#xff0c;可映射至SECS-II&#xff08;SEMI E5&#xff09;或其他类似协议。 10.1.1 消息服务定义内容包括&#…...

算法竞赛进阶指南.次小生成树

目录 题目算法标签: K r u s k a l Kruskal Kruskal, M S T MST MST, 倍增优化, l c a lca lca思路代码*警示后人 题目 356. 次小生成树 算法标签: K r u s k a l Kruskal Kruskal, M S T MST MST, 倍增优化, l c a lca lca 思路 因为要求的是严格次小生成树, 假设最…...

ElasticSearch基本概念

为什么要使用ElasticSearch Elasticsearch 主要为系统提供搜索功能&#xff0c; MySQL 这类传统关系型数据库主要为系统提供数据存储功能 Elasticsearch 的优势 &#xff1a; 支持多种数据类型&#xff0c;非结构化&#xff0c;数值&#xff0c;地理信息。简单的 RESTful AP…...

普通IT的股票交易成长史--20250508晚复盘

声明&#xff1a;本文章的内容只是自己学习的总结&#xff0c;不构成投资建议。价格行为理论学习可参考简介中的几位&#xff0c;感谢他们的无私奉献。 送给自己的话&#xff1a; 仓位就是生命&#xff0c;绝对不能满仓&#xff01;&#xff01;&#xff01;&#xff01;&…...

SAP 交货单行项目含税金额计算报cx_sy_zerodivide处理

业务背景&#xff1a;SAP交货单只有数量&#xff0c;没有金额&#xff0c;所以开发报表从订单的价格按数量计算交货单的金额。 用户反馈近期报表出现异常&#xff1a; ****2012/12/12 清风雅雨 规格变更 Chg 修改开始 ** 修改原因:由于余数为0时&#xff0c;可能会报错溢出。…...

基于译码器和锁存器的运行逻辑的简易算法

74HC138 def decoder_74hc138(E1, E2, E3, A0, A1, A2):output [1] * 8 # 默认全高电平# 检查使能条件&#xff1a;E1和E2低电平&#xff0c;E3高电平if E1 0 and E2 0 and E3 1:# 计算地址索引&#xff08;A2为高位&#xff0c;A0为低位&#xff09;index (A2 <<…...

用电信息采集中的天线种类

一、4G/3G/2G 频率范围“698-960/1710-2700MHz 输入阻抗&#xff1a;50Ω 电压驻波比&#xff1a;<3.0 增益&#xff1a;5dBi/7dBi/9dBi&#xff1b; 824MHz&#xff5e;960MHz频段本体增益≥3.0dBi 1710MHz&#xff5e;2700MHz频段本体增益≥5.0dBi 天线长度225*30mm…...

2025年4月AI算力领域热点事件全景报告

目录 一、政策要闻 01欧洲央行召开会议讨论AI影响 02中国生成式AI备案制落地 03多国政府公布AI基础设施投资计划 04香港发布生成式AI技术及应用指引 05美国出口管制政策影响 06欧盟《人工智能法案》落地 07中国 “东数西算” 工程深化 08美国CHIPS法案争议 09中国发…...

数据结构-非线性结构-二叉树

概述 /** * 术语 * 根节点&#xff08;root node&#xff09;&#xff1a;位于二叉树顶层的节点&#xff0c;没有父节点。 * 叶节点&#xff08;leaf node&#xff09;&#xff1a;没有子节点的节点&#xff0c;其两个指针均指向 None 。 * 边&#xff08;edge&#xff09;&…...

Android开发补充内容

Android开发补充内容 fragment通信生命周期 Okhttp基本使用websocket Retrofit基本使用 RxJava基本使用定时任务 Hilt基本使用进阶使用例子 组件库Material ComponentsJetpack Compose fragment 通信 fragment于activity通信的一种原生方法是使用Bundle&#xff1a; Bundle …...

Go主要里程碑版本及其新增特性

Go 语言自 2009 年诞生以来&#xff0c;经历了多个里程碑版本的迭代&#xff0c;每个版本都引入了重要特性和改进。以下是 Go 语言的主要版本及其关键特性&#xff1a; Go 1.0 (2012-03-28) 首个稳定版&#xff0c;承诺向后兼容&#xff08;Go 1 兼容性保证&#xff09;。核心…...

Cut video with ffmpeg

To cut a snippet from a video based on timestamps like 02:52 to 04:20, the best tool is FFmpeg, which is fast, free, and doesn’t re-encode the video (so it keeps original quality if you don’t want re-encoding). Here’s the command you can run in a termi…...

无刷电机控制算法策略

目录 一、基础控制算法 二、高性能算法 三、无感算法 四、智能算法 五、特殊场景算法 无刷电机的核心控制算法主要包括以下类型&#xff1a; 一、基础控制算法 六步换向法&#xff08;梯形控制&#xff09; 通过霍尔传感器检测转子位置&#xff0c;按固定顺序切换…...

LeetCode算法题(Go语言实现)_61

题目 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一晚上被小偷闯入&#xff0c;系统会自动报警。 给定一个代表每个房屋存放金…...

Kafka消息不丢失处理

kafka作为消息中间件&#xff0c;吞吐量大&#xff08;至于为啥吞吐量大&#xff0c;本文不做介绍&#xff09;&#xff0c;所以大家用的多。涉及到异构数据库更换&#xff0c;以及数据预处理后的迁移&#xff0c;基本想到的都是通过kafka。 概览图 我先画个图 生产者到kafka…...

Python+ffmpeg 实现给视频添加字幕

创作灵感 孩子学校经常留作业&#xff0c;需要提交一段录制的视频&#xff0c;视频上要求添加学校、班级、姓名等信息的字幕&#xff0c;手机自带的相机软件字幕添加位置要么只能添加在视频正中&#xff0c;要么无法添加多行文本&#xff0c;要么只能添加在片头或者片尾&#…...

QMK键盘固件自定义指南 - 打造你的专属键盘体验

QMK键盘固件自定义指南 - 打造你的专属键盘体验 &#x1f680; 前言 在机械键盘的世界里&#xff0c;QMK固件让你的键盘不再只是简单的输入设备&#xff0c;而是可以按照你的意愿定制的强大工具。本文将深入浅出地介绍如何自定义QMK键盘的行为&#xff0c;从基础概念到高级应…...

Linux-openeuler更换yum镜像源

将 openEuler 系统镜像源更换为华为镜像 以openEuler 24.03 LTS SP1 为例。操作前建议备份原配置文件&#xff0c;并确保系统已联网。 一、确认系统版本与架构 查看系统版本&#xff1a; [rooteulerzy yum.repos.d]# cat /etc/os-releaseNAME"openEuler"VERSION&qu…...

手势、鼠标滑动实现界面切换

手势&#xff1a; #include <QApplication> #include "mainwindow.h"int main(int argc, char *argv[]) {QApplication app(argc, argv);MainWindow window;window.show();return app.exec(); }#ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainW…...

什么是变量提升?(形象的比喻)

当然&#xff01;可以用几个生活中的比喻来形象地解释变量提升&#xff1a; ​​1. 书架的占位符​​ 想象你有一个书架&#xff0c;但还没放书。 • 变量提升&#xff08;var&#xff09;&#xff1a; 你先在书架上贴了一个标签&#xff08;比如写“我的书”&#xff09;&…...

趣味编程:答案之书

概述&#xff1a;该篇博客主要介绍的是曾经一度风靡全网的答案之书小程序。 目录 1. 效果展示 2. 源码展示 3. 代码逻辑详解 3.1 头文件与全局变量 3.2 main函数 3.3 主循环 3. 4 绘制界面 4. 运行问题 5.小结 1. 效果展示 该小程序是动态的效果&#xff0c; 因此实…...

用kompose将docker-compose文件转换为K8S资源清单

一、什么是kompose Kompose 是什么&#xff1f;它是一个转换工具&#xff0c;可将 Compose &#xff08;即 Docker Compose&#xff09;所组装的所有内容转换成容器编排器&#xff08;Kubernetes 或 OpenShift&#xff09;可识别的形式。 更多信息请参考 Kompose 官网 Kompos…...

Linux中的防火墙

概述 防火墙通过一系列规则来过滤网络数据包&#xff0c;决定哪些数据包可以进入或离开系统&#xff0c;哪些数据包将被阻止&#xff0c;以此来保护系统免受未经授权的访问、恶意攻击和潜在的安全威胁。 常见的防火墙软件 iptables&#xff1a;是 Linux 系统中常用的防火墙工…...