TypeScript 泛型讲解
如果说 TypeScript 是一门对类型进行编程的语言,那么泛型就是这门语言里的(函数)参数。本章,我将会从多角度讲解 TypeScript 中无处不在的泛型,以及它在类型别名、对象类型、函数与 Class 中的使用方式。
一、泛型的核心概念
1.基本定义
泛型(Generics)是 TypeScript 中允许在定义函数、接口或类时不预先指定具体类型,而是在使用时动态指定类型的机制。其核心目标是实现代码的可重用性与类型安全。
- 示例:
function identity<T>(arg: T): T { return arg; }
此处
<T>
为类型参数,T
在调用时被具体类型替换,如identity<string>("hello")
。 -
不过上述例子中直接
identity("hello") 也是可以的,
省略不写类型参数的值,让 TypeScript 自己推断。但有些复杂的使用场景,TypeScript 可能推断不出类型参数的值,这时就必须显式给出了。function comb<T>(arr1:T[], arr2:T[]):T[] {return arr1.concat(arr2); }comb([1, 2], ['a', 'b']) // 报错comb<number|string>([1, 2], ['a', 'b']) // 正确
上面示例中,两个参数
arr1
、arr2
和返回值都是同一个类型。如果不给出类型参数的值,调用会报错。如果类型参数是一个联合类型,就不会报错。
2. 泛型 vs any
any
的缺陷:放弃类型检查,失去 TypeScript 的类型安全优势。- 泛型的优势:保留类型信息,编译器可进行静态检查,如类型推断与错误提示 。
二、泛型的主要应用场景
泛型主要用在四个场合:函数、接口、类和别名。
1. 函数的泛型写法
通过泛型定义可处理多种类型的函数,避免重复代码:
function reverse<T>(items: T[]): T[] {return items.reverse();
}
const numbers = reverse([1, 2, 3]); // 推断为 number[]
const strings = reverse(["a", "b"]); // 推断为 string[]
此例中,T
自动匹配输入数组类型,返回值类型与输入一致。
2. 接口的泛型写法
定义灵活的类型契约,适用于容器类场景:
interface KeyValuePair<K, V> {key: K;value: V;
}
const pair: KeyValuePair<number, string> = { key: 1, value: "one" };
接口通过类型参数 K
和 V
支持多种键值组合。
3. 类的泛型写法
创建可复用的数据结构(如集合、栈、队列):
class Stack<T> {private items: T[] = [];push(item: T) { this.items.push(item); }pop(): T | undefined { return this.items.pop(); }
}
const numberStack = new Stack<number>();
numberStack.push(42); // 仅允许 number 类型
此类实现保证了栈内元素的类型一致性。
4. 类型别名的泛型写法
type 命令定义的类型别名,也可以使用泛型。
type Nullable<T> = T | undefined | null;
上面示例中,Nullable<T>
是一个泛型,只要传入一个类型,就可以得到这个类型与undefined
和null
的一个联合类型。
三、高级泛型技巧
1. 泛型约束
通过 extends
限制类型参数的范围:
interface HasLength { length: number; }
function logLength<T extends HasLength>(arg: T): void {console.log(arg.length);
}
logLength("hello"); // 合法(length=5)
logLength(42); // 错误:缺少 length 属性
此约束确保类型参数必须包含指定属性。
2. 多类型参数与默认值
多类型参数:
function swap<T, U>(tuple: [T, U]): [U, T] {return [tuple[1], tuple[0]];
}
swap([7, "seven"]); // 返回 ["seven", 7]
但是类型参数越少越好,下面我会讲到
默认类型:
class Generic<T = string> {list:T[] = []add(t:T) {this.list.push(t)}
}const g = new Generic();
g.add(4) // 报错
g.add('hello') // 正确-------------------------------------------const g = new Generic<number>();
g.add(4) // 正确
g.add('hello') // 报错
上面示例中,类Generic
有一个类型参数T
,默认值为string
。这意味着,属性list
默认是一个字符串数组,方法add()
的默认参数是一个字符串。所以,向add()
方法传入一个数值会报错,传入字符串就不会。反之,传入字符串会报错。
3. 索引类型与 keyof
确保对象属性访问的安全性:
function getValue<T, K extends keyof T>(obj: T, key: K): T[K] {return obj[key];
}
const person = { name: "Alice", age: 30 };
getValue(person, "name"); // 合法
getValue(person, "gender"); // 错误:属性不存在。
4. 条件类型与映射类型
条件类型:根据条件选择类型:
type Check<T> = T extends string ? "string" : "not string";
type A = Check<"hello">; // "string"
映射类型:基于已有类型生成新类型:
type Readonly<T> = { readonly [P in keyof T]: T[P] };
type ReadonlyPerson = Readonly<Person>; // 所有属性变为只读。
四、泛型的正确使用场景与注意点
1.正确使用场景
- 当需要在多个位置(参数、返回值、成员变量)之间建立类型约束时。
- 避免重复编写相似逻辑的类型特定代码(如不同数据类型的队列实现)。
2.注意点
1、尽量少用泛型。
泛型虽然灵活,但是会加大代码的复杂性,使其变得难读难写。一般来说,只要使用了泛型,类型声明通常都不太易读,容易写得很复杂。因此,可以不用泛型就不要用。
2、类型参数越少越好。
多一个类型参数,多一道替换步骤,加大复杂性。因此,类型参数越少越好。
function filter<T,Fn extends (arg:T) => boolean
>(arr:T[],func:Fn
): T[] {return arr.filter(func);
}
上面示例有两个类型参数,但是第二个类型参数 Fn
是不必要的,完全可以直接写在函数参数的类型声明里面。
function filter<T>(arr:T[],func:(arg:T) => boolean
): T[] {return arr.filter(func);
}
上面示例中,类型参数简化成了一个,效果与前一个示例是一样的。
3、类型参数需要出现两次。
如果类型参数在定义后只出现一次,那么很可能是不必要的。
function greet<Str extends string>(s:Str
) {console.log('Hello, ' + s);
}
上面示例中,类型参数Str
只在函数声明中出现一次(除了它的定义部分),这往往表明这个类型参数是不必要。
function greet(s:string) {console.log('Hello, ' + s);
}
上面示例把前面的类型参数省略了,效果与前一个示例是一样的。
也就是说,只有当类型参数用到两次或两次以上,才是泛型的适用场合。
4、泛型可以嵌套。
类型参数可以是另一个泛型。
type OrNull<Type> = Type|null;
type OneOrMany<Type> = Type|Type[];
type OneOrManyOrNull<Type> = OrNull<OneOrMany<Type>>;
上面示例中,最后一行的泛型OrNull
的类型参数,就是另一个泛型OneOrMany
。
五、实战应用案例
1. React 组件泛型
定义可接收多种 props 类型的组件:
interface ListProps<T> {items: T[];renderItem: (item: T) => React.ReactNode;
}
function List<T>({ items, renderItem }: ListProps<T>) {return <div>{items.map(renderItem)}</div>;
}
// 使用
<List<number> items={[1, 2]} renderItem={(n) => <div>{n}</div>} />。
2. API 请求封装
利用泛型约束返回数据类型:
async function fetchData<T>(url: string): Promise<T> {const response = await fetch(url);return response.json() as T;
}
interface User { id: number; name: string; }
const users = await fetchData<User[]>("/api/users");。
相关文章:
TypeScript 泛型讲解
如果说 TypeScript 是一门对类型进行编程的语言,那么泛型就是这门语言里的(函数)参数。本章,我将会从多角度讲解 TypeScript 中无处不在的泛型,以及它在类型别名、对象类型、函数与 Class 中的使用方式。 一、泛型的核…...
BERT、GPT-3与超越:NLP模型演进全解析
自然语言处理(NLP)领域近年来经历了前所未有的变革,从早期的统计方法到如今的深度学习大模型,技术的进步推动了机器理解、生成和交互能力的飞跃。其中,BERT和GPT-3作为两个里程碑式的模型,分别代表了不同的…...
RISC-V IDE MRS2 开发笔记一:volatile关键字的使用
RISC-V IDE MRS2 开发笔记一:volatile关键字的使用 一、volatile是什么 二、GCC 中 volatile 的行为 2.1禁止编译器优化 2.2 不等于内存屏障 2.3 GCC扩展行为 三、什么时候需要 volatile 3.1防止编译器优化掉“有效代码” 3.2 访问硬件寄存器 3.3 中断服务…...
25、工业防火墙 - 工控网络保护 (模拟) - /安全与维护组件/industrial-firewall-dcs-protection
76个工业组件库示例汇总 工业防火墙 - 工控网络保护 (模拟) 概述 这是一个交互式的 Web 组件,旨在模拟工业防火墙在保护关键工控网络(特别是 DCS - 分布式控制系统)免受网络攻击(如勒索软件传播)方面的核心功能。组件通过可视化简化的网络拓扑、模拟网络流量、应用防火…...
LAN(局域网)和WAN(广域网)
你的问题非常清晰!我来用一个直观的比喻实际拓扑图帮你彻底理解LAN(局域网)和WAN(广域网)如何协同工作,以及路由器在其中的位置。你可以把整个网络想象成一座城市: 1. 比喻:城市交通…...
ArcGIS Pro 3.4 二次开发 - Arcade
环境:ArcGIS Pro SDK 3.4 .NET 8 文章目录 Arcade1 基本查询1.1 基本查询1.2 使用要素进行基本查询1.3 使用 FeatureSetByName 检索要素1.4 使用过滤器检索要素1.5 使用数学函数计算基本统计量1.6 使用 FeatureSet 函数的 Filter 和 Intersects 2 评估表达式2.1 评…...
PCB智能报价系统——————仙盟创梦IDE
软件署名 代码贡献: 紫金电子科技有限公司 文案正路:cybersnow 正文 对企业的竞争力有着深远影响。传统的 PCB 报价方式往往依赖人工核算,不仅耗时较长,还容易出现误差。随着科技的发展,PCB 自动报价系统应运而生&a…...
灾备认证助力构建数据资产安全防线
信息安全保障人员(CISAW)-灾难备份与恢复认证 1.权威认证体系:技术护城河 在数字化进程加速的背景下,数据资产已成为政府与企业的核心资源,容灾备份能力成为保障业务连续性的关键。特别是近年来,因灾备缺…...
[特殊字符] 遇见Flask
一、初识Flask:像风一样自由 想象一下,你手里有一盒乐高积木——没有说明书,但每一块都精致小巧,任你组合成城堡、飞船,甚至整个宇宙。Flask就是这样一个存在。它不像Django那样“手把手教你搭房子”,而是…...
Axure高级交互设计:中继器嵌套动态面板实现超强体验感台账
亲爱的小伙伴,在您浏览之前,烦请关注一下,在此深表感谢!如有帮助请订阅专栏! Axure产品经理精品视频课已登录CSDN可点击学习https://edu.csdn.net/course/detail/40420 课程主题:中继器嵌套动态面板 主要内容:中继器内部嵌套动态面板,实现可移动式台账,增强数据表现…...
告别手动绘图!2分钟用 AI 生成波士顿矩阵
波士顿矩阵作为经典工具,始终是企业定位产品组合、制定竞争策略的核心方法论。然而,传统手动绘制矩阵的方式,往往面临数据处理繁琐、图表调整耗时、团队协作低效等痛点。 随着AI技术的发展,这一现状正在被彻底改变。boardmix博思白…...
iframe加载或者切换时候,短暂的白屏频闪问题解决
问题描述 iframe加载或者是切换iframe链接的时候,会有短暂的白屏,这个时候是在加载,目前没有想到避免的问题,应该是浏览器层面的,所以解决方法之一就是,用页面的主题背景色来遮盖一下,当他加载…...
Python数据可视化高级实战之一——绘制GE矩阵图
目录 一、课程概述 二、GE矩阵? 三、GE 矩阵图的适用范围 五、GE 矩阵的评估方法 (一)市场吸引力的评估要素 二、企业竞争实力的评估要素 三、评估方法与实践应用 1. 定量与定性结合法 2. 数据来源 六、GE矩阵的图形化实现 七、总结:GE 矩阵与 BCG 矩阵的对比分析 (一)GE…...
量子计算与云计算的融合:技术前沿与应用前景
目录 引言 量子计算基础 量子计算的基本原理 量子计算的优势与挑战 量子计算的发展阶段 云计算基础 云计算的基本概念 云计算的应用领域 云计算面临的挑战 量子计算与云计算的结合 量子云计算的概念与架构 量子云计算的服务模式 量子云计算的优势 量子云计算的发展…...
QMK固件RGB矩阵照明功能详解 - 打造你的专属炫彩键盘
QMK固件RGB矩阵照明功能详解 - 打造你的专属炫彩键盘 🌈 大家好!今天我要详细讲解QMK固件中的RGB矩阵照明功能,让你轻松打造一个真正炫彩的机械键盘!本文从基础原理到实战配置,手把手教你如何配置各种绚丽的灯光效果,即使你是小白也能轻松上手!文中所有代码都配有详细的…...
Rust 学习笔记:关于泛型的练习题
Rust 学习笔记:关于泛型的练习题 Rust 学习笔记:关于泛型的练习题问题 1下面代码能否通过编译?若能,输出是?下面代码能否通过编译?若能,输出是? Rust 学习笔记:关于泛型的…...
Panasonic松下焊接机器人节气
Panasonic松下焊接机器人节气装置 一、工作原理 松下焊接机器人节气装置的工作原理主要是通过智能控制技术,实现对焊接过程中气体流量的精确调节。例如,在焊接的不同阶段,根据焊接电流的大小自动调整气体的供给量。当焊接电流较强时&#x…...
2023 睿抗机器人开发者大赛CAIP-编程技能赛-本科组(国赛) 解题报告 | 珂学家
前言 题解 2023 睿抗机器人开发者大赛CAIP-编程技能赛-本科组(国赛)。 vp了下,题目挺好的,难度也适中,但是彻底红温了。 第二题,题意不是那么清晰, M i n ( K 1 , K 2 ) Min(K_1, K_2) Min(K1,K2)容易求&#x…...
LeetCode 3355.零数组变换 I:差分数组
【LetMeFly】3355.零数组变换 I:差分数组 力扣题目链接:https://leetcode.cn/problems/zero-array-transformation-i/ 给定一个长度为 n 的整数数组 nums 和一个二维数组 queries,其中 queries[i] [li, ri]。 对于每个查询 queries[i]&am…...
java21
1.数据结构之二叉树,二叉查找树,平衡二叉树 原理:和节点比较大小然后选左边还是右边 注意:中序遍历最常见,因为遍历的结果是从小到大 注意是任意节点,上面的二叉查找树的节点10的左子树高度是0,…...
ES的倒排索引和正排索引的区别及适用场景?为什么倒排索引适合全文搜索?
正排索引解析 1.存储机制 Elasticsearch 的文档存储机制比简单的固定字节分配更复杂,其核心原理如下: 1. 数值类型存储机制 对于 long/float/double 等数值类型: 文档ID2 → 偏移量 2 * sizeof(type) 例如:long 类型…...
ElasticSearch各种查询语法示例
1. 每种查询语法的区别与优缺点 Query DSL 区别: JSON 格式的结构化查询,功能强大,支持复杂查询逻辑,适用于 Elasticsearch 的核心查询场景。优点: 灵活,功能全面,支持全文搜索、精确匹配、聚合等;可组合…...
Ubuntu20.04部署KVM
文章目录 一. 环境准备关闭防火墙(UFW)禁用 SELinux更换镜像源检查 CPU 虚拟化支持 二. 安装KVM安装 KVM 及相关组件启动 libvirtd 服务验证安装创建虚拟机 一. 环境准备 4C8G,50G硬盘——VMware Workstation需要给虚拟机开启虚拟化引擎 roo…...
Android车载应用开发:Kotlin与Automotive OS深度实践
一、Android Automotive OS简介 Android Automotive OS(AAOS)是Google为车辆定制的操作系统,直接运行于车机硬件,提供完整的车载信息娱乐系统(IVI)。与Android Auto(手机投影方案)不…...
提示词工程(Prompt Engineering)是智能Agent交互中不可或缺的一环
Prompt Engineering 提示词,参考OpenAI提示词建议 2.5.1 概述 提示词工程(Prompt Engineering)是智能Agent交互中不可或缺的一环,它们指导智能体如何理解和回应用户的需求。这一节将探讨如何设计有效的提示词,以及如何通过精确的语言引导智能…...
九天画芯CEO张锦:AR 与 AI 融合重构智能终端生态,消费级市场迎来关键拐点
一、AR设备逆势突围:从技术验证到规模商用的跨越 根据洛图科技显示,2025 年 Q1 中国 XR(ARVR) 设备市场数据显示,AR 设备以 9.1 万台销量、116% 的同比增速远超 VR/MR 设备,这标志着消费级 AR 市场正式从 “…...
Python爬虫(32)Python爬虫高阶:动态页面处理与Scrapy+Selenium+BeautifulSoup分布式架构深度解析实战
目录 引言一、动态页面爬取的技术背景1.1 动态页面的核心特征1.2 传统爬虫的局限性 二、技术选型与架构设计2.1 核心组件分析2.2 架构设计思路1. 分层处理2. 数据流 三、代码实现与关键技术3.1 Selenium与Scrapy的中间件集成3.2 BeautifulSoup与Scrapy Item的整合3.3 分布式爬取…...
[案例七] NX二次开发标识特征的导入与布尔运算
本来做的是案例六NX二次开发减重块。但是当时在处理导入指定面时发现坐标转化存在很大问题,开了我很长时间,太难受了,决定放一放,昨天做了第六个案例采取了一种补救方法(实在不会的一种解决思路),个人认为NX这么优秀的软件应该有更好的方法,坐标转化真让人头大。刚开始…...
Canvas进阶篇:鼠标交互动画
Canvas进阶篇:鼠标交互动画 前言获取鼠标坐标鼠标事件点击事件监听代码示例效果预览 拖动事件监听代码示例效果预览 结语 前言 在上一篇文章Canvas进阶篇:基本动画详解 中,我们讲述了在Canvas中实现动画的基本步骤和动画的绘制方法。本文将进…...
Axure项目实战:智慧运输平台后台管理端-订单管理2(多级交互)
亲爱的小伙伴,在您浏览之前,烦请关注一下,在此深表感谢!如有帮助请订阅专栏! Axure产品经理精品视频课已登录CSDN可点击学习https://edu.csdn.net/course/detail/40420 课程主题:订单管理2 主要内容:中继器筛选、表单跟随菜单拖动、审批数据互通等 应用场景:订单管理…...
AG-UI:重构AI代理与前端交互的下一代协议标准
目录 技术演进背景与核心价值协议架构与技术原理深度解析核心功能与标准化事件体系典型应用场景与实战案例开发者生态与集成指南行业影响与未来展望1. 技术演进背景与核心价值 1.1 AI交互的三大痛点 当前AI应用生态面临三大核心挑战: 交互碎片化:LangGraph、CrewAI等框架各…...
鸿蒙版Flutter库torch_light手电筒功能深度适配
鸿蒙版Flutter库torch_light手电筒功能深度适配:跨平台开发者的光明之路 本项目作者:kirk/坚果 适配仓库地址 作者仓库:https://github.com/svprdga/torch_light# 在数字化浪潮的推动下,跨平台开发框架如 Flutter 凭借其高效、…...
【JAVA】中文我该怎么排序?
📘 Java 中文排序教学文档(基于 Collator) 🧠 目录 概述Java 中字符串排序的默认行为为什么需要 Collator使用 Collator 进行中文排序升序 vs 降序排序自定义对象字段排序多字段排序示例总结对比表附录:完整代码示例 …...
WPF MVVM Community Toolkit. Mvvm 社区框架
Community Toolkit. Mvvm 社区框架 微软官方文档 主要内容:CommunityToolkit.Mvvm 框架 概念,安装,使用(重要API:ObservableObject,RelayCommand)源生成器([ObservableProperty]&…...
云原生安全之PaaS:从基础到实践的技术指南
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 云原生安全之PaaS:从基础到实践的技术指南 一、基础概念 PaaS(Platform as a Service)平台 PaaS是一种云计算服务模型,为开发者提供应用程序的开发、部署和运行环境,涵…...
软件设计师考试需背诵知识点
1. 网络技术标准与协议 2. OSI/RM七层模型 3. 对称加密算法 4. 常见的非对称加密算法 5. 排序算法比较 6. 海明码公式 设数据位是n位,校验位是k位,则n与k必须满足以下关系: 7. McCabe度量法 McCabe度量法的核心公式为: V(G)E−…...
智慧社区新防线:华奥系AI技术如何让夏季安防“零隐患”
夏季社区安防隐患频发 随着夏季高温、暴雨、台风等极端天气增多,社区安全风险显著上升。高空建筑外墙材料因暴晒脱落、地下管道锈蚀堵塞导致积水、电动车充电自燃等事件频发,传统“人防物防”模式响应滞后、管理粗放,难以满足精细化防控需求…...
pinia的简单使用
yarn add pinia // 用来存储token,用户信息,等需要多地方使用的信息 src目录下新建store文件夹->新建index.ts import { createPinia } from "pinia";const store createPinia()export default storemain.ts 引用store import { createApp } from v…...
【Linux笔记】——线程池项目与线程安全单例模式
🔥个人主页🔥:孤寂大仙V 🌈收录专栏🌈:Linux 🌹往期回顾🌹: 【Linux笔记】——简单实习一个日志项目 🔖流水不争,争的是滔滔不息 一、线程池设计二…...
用户有一个Django模型没有设置主键,现在需要设置主键。
用户有一个Django模型没有设置主键,现在需要设置主键。 from django.db import modelsclass CategoryAssistentModel(models.Model):second_level_category models.CharField(max_length100, nullTrue, blankTrue)third_level_category models.CharField(max_len…...
SkyWalking 报错:sw_profile_task 索引缺失问题分析与解决
文章目录 SkyWalking 报错:sw_profile_task 索引缺失问题分析与解决问题背景SkyWalking 是否会自动创建 sw_profile_task 索引?答案:不会在初始化时创建相关索引包括: 问题原因分析解决方案✅ 解决思路:手动创建 sw_pr…...
多模态学习笔记
在模态对齐任务中,同一时刻不同类型的数据(模态)需要做好对齐,才能更好的感知内容,下面对其常见的多模态对齐任务进行如下总结: (1)文本图像 图像和文本特征提取后的对齐方法主要分为两类:基于对比学习的方法和基于跨模态注意力的方法。以下是它们的细化说明及具体实…...
【 Redis | 实战篇 扩展 】
目录 前言: 1.达人探店功能 1.1.点赞功能 1.2.排行榜 2.关注 2.1.共同关注 2.2.关注推送 3.附近商铺 3.1.GEO基本用法 3.2.获取附近商铺 4.签到 4.1.BitMap 4.2.实现签到 4.3.统计连续签到 5.UV统计 前言: 实现达人探店,好友…...
【HarmonyOS Next之旅】DevEco Studio使用指南(二十五) -> 端云一体化开发 -> 业务介绍(二)
目录 1 -> 工作原理 2 -> 约束与限制 2.1 -> 支持的设备 2.2 -> 支持的国家/地区 2.3 -> 支持的签名方式 3 -> 总结 3.1 -> 关键功能与工具 3.2 -> 开发流程 3.3 -> 典型场景与优化 3.4 -> 常见问题与解决 3.5 -> 总结 1 -> 工…...
空调系统虚拟标定技术:新能源汽车能效优化的革命性突破
title: 空调系统虚拟标定技术:新能源汽车能效优化的革命性突破 date: 2025-05-15 categories: 新能源汽车技术 tags: [空调系统, 虚拟标定, PID控制, 数字孪生, 能效优化] description: 本文深度解析空调系统虚拟标定技术在新能源汽车中的应用,揭秘如何…...
MCP Server开发并使用自定义天气查询工具查询城市天气
1.本地安装node.js环境 2.本地创建mcp文件夹,搭建mcp环境 在文件夹下cmd执行npm init -y初始化npm项目 3.创建weather-server.js文件,代码如下 // weather-server.js import { McpServer } from "modelcontextprotocol/sdk/server/mcp.js"…...
virtualbox选项“启用套嵌vt-x/amd-v“不可用
“启用套嵌vt-x/amd-v”选项不可用。 解决方法: 切换到virtualbox安装目录,执行如下命令查看虚拟机名称: .\VBoxManage.exe list vms比如返回: winxp 执行如下命令开启64位,注意把"winxp"换成你的虚拟机名字&#x…...
windows powershell 判断 进程号是否存在
在 Windows PowerShell 中,你可以使用多种方法来检查一个特定的进程号(PID)是否存在。以下是几种常用的方法: 方法1:使用 Get-Process 命令 你可以尝试获取具有特定 PID 的进程。如果该进程存在,Get-Proce…...
JAVA SE 多线程(下)
文章目录 📕1. 常见的锁策略✏️1.1 乐观锁VS悲观锁✏️1.2 轻量级锁VS重量级锁✏️1.3 自旋锁✏️1.4 公平锁VS非公平锁✏️1.5 可重入锁和不可重入锁✏️1.6 读写锁 📕2. 死锁✏️2.1 哲学家就餐问题✏️2.2 形成死锁的必要条件✏️2.3 如何避免死锁 &…...
DeepSeek+Dify之九多模态大模型识别图片
Dify之八添加各种在线大模型 文章目录 背景整体流程测试数据用到的节点开始列表操作LLM结束实现步骤1、新建工作流2、开始节点3、列表操作4、LLM节点(多模态大模型检索)5、结束节点测试发布导出背景 有了上一篇文章的基础,现在可以了解下多模态大模型识别图片的工作流 整体…...