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

代理模式的优缺点是什么?

什么是代理模式?

代理模式(Proxy Pattern)是一种结构型设计模式,它通过创建代理对象来控制对原始对象的访问。

这种模式在前端开发中广泛应用,特别是在需要控制对象访问、添加额外逻辑或优化性能的场景中。

​核心思想​​:在客户端代码和真实对象之间添加中间层,这个中间层(代理)可以:

  1. 控制对原始对象的访问权限
  2. 添加预处理/后处理逻辑
  3. 实现延迟加载
  4. 缓存昂贵操作的结果
  5. 记录日志或监控行为

代理模式实现方式

1. 虚拟代理(延迟加载)

// 原始图片加载器
class ImageLoader {constructor(url) {this.url = url;}load() {console.log(`Loading image from ${this.url}`);return `<img src="${this.url}" />`;}
}// 虚拟代理 - 延迟加载
class ImageProxy {constructor(url) {this.url = url;this.imageLoader = null; // 延迟初始化}load() {if (!this.imageLoader) {this.imageLoader = new ImageLoader(this.url);// 添加占位逻辑const placeholder = document.createElement('div');placeholder.style.width = '300px';placeholder.style.height = '200px';placeholder.style.background = '#eee';document.body.appendChild(placeholder);// 延迟实际加载setTimeout(() => {document.body.removeChild(placeholder);document.body.innerHTML += this.imageLoader.load();}, 2000);}return 'Image loading initiated...';}
}// 使用代理
const image = new ImageProxy('https://example.com/large-image.jpg');
console.log(image.load()); // 立即返回占位符,2秒后加载真实图片

2. 缓存代理(记忆函数)

// 原始计算函数
function fibonacci(n) {if (n <= 1) return n;return fibonacci(n - 1) + fibonacci(n - 2);
}// 缓存代理
function createCachedProxy(fn) {const cache = new Map();return function(n) {if (cache.has(n)) {console.log(`Cache hit for n=${n}`);return cache.get(n);}const result = fn(n);cache.set(n, result);console.log(`Calculated for n=${n}`);return result;};
}// 使用代理
const cachedFib = createCachedProxy(fibonacci);console.log(cachedFib(35)); // 长时间计算
console.log(cachedFib(35)); // 立即返回缓存结果

3. 保护代理(访问控制)

// 原始用户服务
class UserService {constructor() {this.users = new Map([[1, { id: 1, name: 'Admin', role: 'admin' }]]);}deleteUser(id) {this.users.delete(id);return `User ${id} deleted`;}
}// 保护代理
class UserServiceProxy {constructor(user) {this.userService = new UserService();this.currentUser = user;}deleteUser(id) {if (this.currentUser.role !== 'admin') {throw new Error('Permission denied');}return this.userService.deleteUser(id);}
}// 使用代理
const adminProxy = new UserServiceProxy({ role: 'admin' });
console.log(adminProxy.deleteUser(1)); // 成功const userProxy = new UserServiceProxy({ role: 'user' });
userProxy.deleteUser(1); // 抛出权限错误

4. ES6 Proxy实现

// 原始对象
const database = {users: {1: { name: 'Alice', email: 'alice@example.com' }},getEmail: function(userId) {return this.users[userId]?.email;}
};// 创建代理
const protectedDatabase = new Proxy(database, {get(target, prop) {// 权限验证if (prop === 'users') {throw new Error('Direct access to users denied');}return target[prop];},set(target, prop, value) {// 写操作限制if (prop === 'users') {throw new Error('User modification requires admin privileges');}target[prop] = value;return true;}
});console.log(protectedDatabase.getEmail(1)); // 正常访问
protectedDatabase.users = {}; // 抛出错误
console.log(protectedDatabase.users); // 抛出错误

代理模式优缺点分析

优点:

  1. ​访问控制​​:实现精细的权限管理
// API请求代理示例
class ApiProxy {constructor(api) {this.api = api;}async request(endpoint) {if (isRateLimited(endpoint)) {throw new Error('API rate limit exceeded');}trackRequest(endpoint);return this.api.request(endpoint);}
}
  1. ​性能优化​​:通过缓存和延迟加载提升性能
// 图片懒加载代理
const lazyImage = new Proxy(new Image(), {set(target, prop, value) {if (prop === 'src') {// 延迟到元素可见时加载const observer = new IntersectionObserver((entries) => {entries.forEach(entry => {if (entry.isIntersecting) {target.src = value;observer.unobserve(target);}});});observer.observe(target);return true;}return Reflect.set(...arguments);}
});document.body.appendChild(lazyImage);
lazyImage.src = 'https://example.com/large-image.jpg'; // 实际加载延迟到图片可见时
  1. ​职责分离​​:保持核心逻辑的纯净性
// 原始表单验证
class FormValidator {validateEmail(email) {return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);}
}// 验证代理添加日志
class LoggingValidatorProxy {constructor(validator) {this.validator = validator;}validateEmail(email) {const result = this.validator.validateEmail(email);console.log(`Email validation result for ${email}: ${result}`);return result;}
}

缺点:

  1. ​复杂性增加​​:可能引入额外抽象层
// 过度设计的代理示例(不推荐)
class OverEngineeredProxy {constructor(service) {this.service = service;this.logger = new Logger();this.cache = new Cache();this.validator = new Validator();}async getData() {this.logger.logStart();if (!this.validator.validate()) {throw new Error('Validation failed');}const data = await this.cache.get('data') || this.service.getData();this.logger.logEnd();return data;}
}
  1. ​性能损耗​​:额外的代理调用开销
// 性能敏感的原始类
class Vector {constructor(x, y) {this.x = x;this.y = y;}add(other) {return new Vector(this.x + other.x, this.y + other.y);}
}// 添加日志代理可能影响性能
const loggedVector = new Proxy(new Vector(1,2), {get(target, prop) {if (typeof target[prop] === 'function') {return function(...args) {console.log(`Calling ${prop} with`, args);return target[prop].apply(target, args);};}return target[prop];}
});// 在需要高性能计算的场景中,这种代理会产生明显开销
  1. ​调试困难​​:调用堆栈变深
// 多层代理导致的调试问题
const original = { method() { console.log('Original method'); } 
};const proxy1 = new Proxy(original, {get(target, prop) {console.log('Proxy1 handler');return target[prop];}
});const proxy2 = new Proxy(proxy1, {get(target, prop) {console.log('Proxy2 handler');return target[prop];}
});proxy2.method(); // 调用链:proxy2 -> proxy1 -> original

工程实践建议

1. 表单验证代理

// 原始表单对象
const form = {values: {},errors: {},submit() {console.log('Submitting:', this.values);}
};// 验证代理
const validatedForm = new Proxy(form, {set(target, prop, value) {if (prop === 'values') {// 自动触发验证target.errors = validateForm(value);if (Object.keys(target.errors).length === 0) {target.submit();}}return Reflect.set(...arguments);}
});function validateForm(values) {const errors = {};if (!values.email?.includes('@')) errors.email = 'Invalid email';if (values.password?.length < 6) errors.password = 'Password too short';return errors;
}// 使用
validatedForm.values = { email: 'user@example.com', password: '12345' 
}; // 自动触发验证并显示错误

2. API请求代理

// 请求代理工厂
function createApiProxy(api, config = {}) {return new Proxy(api, {get(target, prop) {const originalMethod = target[prop];if (typeof originalMethod !== 'function') return originalMethod;return async function(...args) {// 请求拦截if (config.beforeRequest) {args = config.beforeRequest(...args) || args;}try {const response = await originalMethod.apply(target, args);// 响应拦截return config.afterResponse ? config.afterResponse(response) : response;} catch (error) {// 错误处理if (config.errorHandler) {return config.errorHandler(error);}throw error;}};}});
}// 使用示例
const rawApi = {async getUser(id) {const res = await fetch(`/api/users/${id}`);return res.json();}
};const enhancedApi = createApiProxy(rawApi, {beforeRequest: (id) => {console.log(`Requesting user ${id}`);return [id]; // 可以修改参数},afterResponse: (data) => {console.log('Received response');return { ...data, fullName: `${data.firstName} ${data.lastName}` };},errorHandler: (error) => {console.error('API Error:', error);return { error: true, message: error.message };}
});// 调用方式保持一致
enhancedApi.getUser(123).then(console.log);

注意事项

  1. ​接口一致性​​:代理必须保持与原对象相同的接口
// 错误的代理实现(接口不一致)
class BadProxy {constructor(file) {this.file = file;}// 遗漏了原始对象的save方法read() {return this.file.read();}
}
  1. ​避免深层代理嵌套​
// 不推荐的深层嵌套
const proxy1 = new Proxy(obj, handler1);
const proxy2 = new Proxy(proxy1, handler2);
const proxy3 = new Proxy(proxy2, handler3);
// 应尽量保持代理层级扁平
  1. ​注意内存管理​
// 代理导致的闭包内存泄漏
function createLeakyProxy() {const hugeData = new Array(1000000).fill('data');return new Proxy({}, {get(target, prop) {// 无意中持有hugeData的引用return hugeData[prop];}});
}
  1. ​性能关键路径慎用​
// 在动画循环中避免使用复杂代理
function animate() {// 直接访问对象属性element.x += velocity.x;element.y += velocity.y;// 而不是:// proxiedElement.x += velocity.x;requestAnimationFrame(animate);
}
  1. ​与装饰器模式区分​
// 装饰器模式(增强功能)
function withLogging(fn) {return function(...args) {console.log('Calling function');return fn(...args);};
}// 代理模式(控制访问)
const proxiedFn = new Proxy(fn, {apply(target, thisArg, args) {if (!validate(args)) throw new Error('Invalid arguments');return Reflect.apply(target, thisArg, args);}
});

代理模式是前端架构中的重要模式,适用于:

  • 需要访问控制的场景(权限验证、流量控制)
  • 性能优化需求(缓存、延迟加载)
  • 增强监控能力(日志记录、性能跟踪)
  • 实现智能引用(自动清理、加载)

在实际工程中建议:

  1. 优先使用ES6 Proxy实现简单代理逻辑
  2. 对性能敏感模块谨慎使用
  3. 保持代理接口与原始对象一致
  4. 使用TypeScript增强类型安全
  5. 配合工厂模式创建复杂代理

正确使用代理模式可以提升代码的可维护性和扩展性,但需要警惕模式滥用带来的复杂性。

建议结合具体需求场景,在代码清晰度和功能需求之间找到平衡点。

相关文章:

代理模式的优缺点是什么?

什么是代理模式&#xff1f; 代理模式&#xff08;Proxy Pattern&#xff09;是一种结构型设计模式&#xff0c;它通过创建代理对象来控制对原始对象的访问。 这种模式在前端开发中广泛应用&#xff0c;特别是在需要控制对象访问、添加额外逻辑或优化性能的场景中。 ​​核心…...

十分钟上手:Distilling the Knowledge in a Neural Network

概述&#xff1a;知识蒸馏是一种模型压缩技术&#xff0c;通过让轻量化的学生模型模仿复杂教师模型的输出概率分布&#xff0c;结合软目标和硬目标进行训练&#xff0c;从而将教师模型的泛化能力迁移至学生模型&#xff0c;实现小模型的高效部署而不显著降低性能。 硬目标&…...

百度的deepseek与硅基模型的差距。

问题&#xff1a; 已经下载速度8兆每秒&#xff0c;请问下载30G的文件需要多长时间&#xff1f; 关于这个问题。百度的回答如下&#xff1a; ‌30GB文件下载时间计算‌ ‌理论计算‌&#xff08;基于十进制单位&#xff09;&#xff1a; ‌单位换算‌ 文件大小&#xff1a;3…...

OpenCV 图形API(18)用于执行两个矩阵(或数组)的逐元素减法操作函数sub()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 描述 计算两个矩阵之间的逐元素差值。 sub 函数计算两个矩阵之间的差值&#xff0c;要求这两个矩阵具有相同的尺寸和通道数&#xff1a; dst ( I ) src…...

布谷一对一直播源码android版环境配置流程及功能明细

一&#xff1a;举例布谷交友&#xff08;一对一直播源码&#xff09;搭建部署的基本环境说明 1. 首先安装Center OS 7.9系统&#xff0c;硬盘最低 40G 2. 安装宝塔环境 https://bt.cn&#xff08;强烈推荐使用&#xff09; 3. 安装环境 ● PHP 7.3&#xff08;安装redis扩展…...

#MongoDB 快速上手

docker pull mongo docker run -d --name my-mongo -p 27017:27017 mongo docker exec -it my-mongo mongo &#x1f6aa;进入 Mongo Shell 后的第一步 你进入后会看到类似提示符&#xff1a; >说明已经进入 Mongo Shell&#xff0c;现在就可以操作数据库了。 &#x1…...

docker相关命令

常用命令 #创建并启动 docker-compose up -d # 启动之后就可以通过浏览器访问了 #停止并删除 docker-compose down #重启 docker-compose restart #停止 docker-compose stop #启动 docker-compose startdocker search #搜索镜像(只搜索官方仓库的&#xff0c;官方仓库地址&am…...

浅谈进程与程序的区别

如大家所了解的&#xff0c;进程与程序是有区别的。 下面做了一个总结&#xff0c;供大家参考、学习&#xff1a; 1. 程序是指令的有序集合&#xff0c;是一个静态的概念&#xff0c;其本身没有任何运行的含义。进程是程序在 CPU 上的一次执行过程&#xff0c;是一个动态的概…...

redis 和 MongoDB都可以存储键值对,并且值可以是复杂json,用完整例子分别展示说明两者在存储json键值对上的使用对比

Redis 存储 JSON 键值对示例 存储操作&#xff1a; // 存储用户信息&#xff08;键&#xff1a;user:1001&#xff0c;值&#xff1a;JSON对象&#xff09; SET user:1001 {"name":"Alice", "age":30, "address":"New York&quo…...

基于chatgpt得到的生活成本计算

意大利的生活成本因城市而异&#xff0c;比如米兰和罗马相对较贵&#xff0c;而南部城市如那不勒斯或巴勒莫则便宜一些。下面是意大利大致的基本生活成本和费用明细&#xff08;以欧元€为单位&#xff0c;2025年初数据为基础&#xff0c;具体数值可能随时间和汇率略有变化&…...

C和C++有什么区别?

C和C是两种不同的编程语言&#xff0c;虽然它们有许多相似之处&#xff0c;但也存在一些关键的区别。 C是一种过程化编程语言&#xff0c;专注于函数和流程控制&#xff0c;非常适合系统级编程。而 C是一种面向对象编程语言&#xff0c;支持类、对象和封装、继承、多态等特性。…...

力扣1338 === 贪心算法解决数组减半问题

目录 问题分析 方法思路&#xff1a;贪心算法 步骤分解 代码解释 复杂度分析 正确性证明 示例验证 边界情况 总结 要解决这个问题&#xff0c;我们需要找到最少需要删除的不同整数集合&#xff0c;使得剩余的元素个数不超过原数组的一半。以下是对该问题的详细分析和解…...

企业知识库如何搭建?应对高频咨询的AI自助问答系统

在客户服务和内部沟通中&#xff0c;“同样的问题被反复问”、“信息找不到”、“新员工上手慢”等现象屡见不鲜。为了提升企业运营效率&#xff0c;越来越多企业开始重视知识库建设&#xff0c;而“企业知识库如何搭建”也成为热门话题。 尤其在AI技术快速发展的今天&#xf…...

UE5学习笔记 FPS游戏制作44 统一UI大小 sizeBox

如果我们希望多个类似的UI大小一样&#xff0c;例如不同菜单的标题&#xff0c;可以使用sizeBox组件 我们在标题控件上&#xff0c;用sizeBox包裹所有子物体 然后指定他的最小宽高&#xff0c;或最大宽高 如果指定的是最小宽高&#xff0c;当子元素&#xff08;如图片&#xf…...

SpringAOP新链浅析

前言 在复现CCSSSC软件攻防赛的时候发现需要打SpringAOP链子&#xff0c;于是跟着前人的文章自己动手调试了一下 参考了大佬的文章 https://gsbp0.github.io/post/springaop/#%E6%B5%81%E7%A8%8B https://mp.weixin.qq.com/s/oQ1mFohc332v8U1yA7RaMQ 正文 依赖于Spring-AO…...

高效网页截图利器:支持长截图、异步加载内容截图、API调用、Docker一键部署!

一、简介 利用playwright自动化工具&#xff0c;模拟浏览器打开网页&#xff0c;实现完整网页截图功能支持长截图&#xff0c;支持异步加载动态渲染内容截图支持docker一键部署支持API调用项目地址&#xff1a;https://github.com/luler/hello_screenshot 二、安装 提前安装好d…...

处理语言模型返回的响应

completion.choices[0].message.content 是在处理语言模型&#xff08;如 OpenAI 的 GPT 系列&#xff09;返回的响应时&#xff0c;用于 访问模型生成的文本内容的代码路径。为了更好地理解它&#xff0c;我们需要先了解语言模型响应的结构。 1. 响应的结构 当使用语言模型&…...

Go语言类型捕获及内存大小判断

代码如下&#xff1a; 类型捕获可使用&#xff1a;reflect.TypeOf()&#xff0c;fmt.Printf在的%T。 内存大小判断&#xff1a;len()&#xff0c;unsafe.Sizeof。 package mainimport ("fmt""unsafe""reflect" )func main(){var i , j 1, 2f…...

Java 大视界 -- Java 大数据机器学习模型在智能客服多轮对话系统中的优化策略(179)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…...

CAS号:288574-78-7,Zinpyr-1可用作PET传感器

试剂描述&#xff1a; Zinpyr-1&#xff08;ZP-1&#xff09;是一种具细胞膜渗透性的荧光探针&#xff0c;选择性检测锌离子&#xff08;Zn2&#xff09;&#xff08;Kd 0.7 0.1 nM&#xff09;。一旦与金属离子复合&#xff0c;诱发荧光信号产生。活细胞内&#xff0c;Zinpyr…...

【JVM调优实战指南:从案例分析到性能优化】

一、JVM 调优核心原则 JVM 调优旨在平衡系统的吞吐量、延迟和内存使用。在进行 JVM 调优时&#xff0c;我们可以遵循以下原则&#xff1a; 先优化代码&#xff1a;优先排查业务逻辑中的内存泄漏、对象滥用等问题。优化代码不仅能从根本上解决性能问题&#xff0c;还能减少对 J…...

交换机转发原理 和 DNS服务

1. 收到报文后&#xff0c;将其转换为二进制&#xff0c;并记录在缓存当中 2. 根据二进制中的源 MAC 地址&#xff0c;与接收报文的接口&#xff0c;记录对应关系&#xff0c;在 MAC 地址表中&#xff0c;每个动态表项 300S 老化时间。 3. 判断 如果目的 MAC 是组播或广…...

强化学习Q-Learning:DQN

强化学习Q-Learning/DQN 本文是一篇学习笔记&#xff0c;主要参考李宏毅老师的强化学习课程。 目前主流的强化学习方法大致可以分为 policy-based 和 value-based 两大类。之前我们介绍的 policy gradient 策略梯度&#xff0c;就是 policy-based 的方法。本文要介绍的 Q-learn…...

OpenCv(七)——模板匹配、打包、图像的旋转

目录 一、模板匹配 模板匹配原理 1、单模板之间的匹配 &#xff08;1&#xff09;读取并显示待匹配的图片和模板图片 &#xff08;2&#xff09;模板匹配并绘制匹配位置的外接矩形 &#xff08;3&#xff09;显示最终的效果 2、模板与多个对象匹配&#xff0c;仅匹配当前…...

汽车售后诊断 ODX 和 OTX 对比分析报告

一、引言 在汽车行业不断发展的当下&#xff0c;汽车售后诊断技术对于保障车辆性能、维护车主权益以及提升汽车品牌服务质量起着至关重要的作用。随着汽车电子化程度的不断提高&#xff0c;售后诊断所涉及的数据和流程愈发复杂&#xff0c;这就促使行业需要更加标准化、高效化…...

关于图卷积

深入理解神经网络中的图卷积 一、为什么需要图卷积&#xff08;动机&#xff09; 在图结构中&#xff0c;比如&#xff1a; 社交网络&#xff08;节点是人&#xff0c;边是朋友关系&#xff09;分子结构&#xff08;节点是原子&#xff0c;边是化学键&#xff09;知识图谱&a…...

Meta LLaMA 4:对抗 GPT-4o 与 Claude 的开源王牌

2025 年 4 月&#xff0c;Meta 正式发布了 LLaMA 4 系列的首批两款模型。 这两款模型模型分别是&#xff1a;LLaMA 4 Scout 与 LLaMA 4 Maverick&#xff0c;均采用了 专家混合架构&#xff08;Mixture-of-Experts, MoE&#xff09;。 据 Meta 表示&#xff0c;这是首次有 …...

如何进行SQL调优

如何进行SQL调优 SQL 调优是优化数据库查询性能的过程&#xff0c;目的是减少查询的执行时间&#xff0c;提高数据库系统的整体效率。SQL 调优的技巧和方法可以针对不同的数据库管理系统&#xff08;DBMS&#xff09;有所不同&#xff0c;但基本的原则和步骤是相似的。以下是一…...

WAF防护规则配置技巧与企业级安全实践指南

面对日益复杂的Web应用攻击&#xff0c;WAF规则配置直接决定防护体系的有效性。本文深度解析规则优先级编排、误报消减策略、智能学习机制等17项关键技术&#xff0c;结合金融行业API攻击案例与Gartner最新防御框架&#xff0c;为企业提供可落地的WAF优化路径。 WAF规则引擎的…...

第16届蓝桥杯单片机模拟试题Ⅱ

试题 代码 sys.h #ifndef __SYS_H__ #define __SYS_H__#include <STC15F2K60S2.H> //ds1302.c extern unsigned char time[3]; void w_ds1302(); void r_ds1302(); //iic.c float v_adc(unsigned char addr); //sys.c extern float light_v; extern float rb2_v; exte…...

机器学习——ROC曲线、PR曲线

一、ROC曲线简介 1.1 ROC曲线的构成 1.横轴&#xff08;假正率&#xff0c;FPR&#xff09;&#xff1a; 表示负样本被错误分类为正的比例&#xff08;越小越好&#xff09; 2.纵轴&#xff08;真正率&#xff0c;TPR&#xff0c;即召回率&#xff09;&#xff1a; 表示正样…...

Flutter之交互事件

目录&#xff1a; 1、点击事件标准案例1.1、效果图2.1、代码实现 1、点击事件标准案例 1.1、效果图 2.1、代码实现 class FavoriteWidget extends StatefulWidget {const FavoriteWidget({super.key});overrideState<FavoriteWidget> createState() > _FavoriteWidge…...

深入解析Spring Boot自动装配:原理、设计与最佳实践

引言 Spring Boot作为现代Java开发中的一股清流&#xff0c;凭借其简洁、快速和高效的特性&#xff0c;迅速赢得了广大开发者的青睐。而在Spring Boot的众多特性中&#xff0c;自动装载&#xff08;Auto-configuration&#xff09;无疑是最为耀眼的明珠之一。本文将深入剖析Sp…...

【责任链】模式解决流程中多个接口的流程问题

业务需求 整体流程有5步骤&#xff0c;每个步骤调用一个接口&#xff0c;每个接口成功才能进行下一步。如a->b->c->d->e&#xff0c; 比如入学报到 a&#xff1a;报班&#xff0c;根据名字生成学号uid b&#xff1a;根据学号分配班级获取班级编号cid c&#xff1a…...

excel常见错误包括(#N/A、#VALUE!、#REF!、#DIV/0!、#NUM!、#NAME?、#NULL! )

目录 1. #N/A2. #VALUE!3. #REF!4. #DIV/0!5. #NUM!6. #NAME?7. #NULL!8.图表总结 在 Excel 中&#xff0c;可能会遇到以下常见的错误值&#xff0c;每个都有特定的含义和成因&#xff1a; 1. #N/A 含义&#xff1a; 表示“Not Available”&#xff08;不可用&#xff09;。…...

【湖南大学】2025我们该如何看待DeepSeek

大家好&#xff0c;我是樱木。 DeepSeek 官方网站&#xff1a;https://www.deepseek.com/ 一、DeepSeek 到底是什么&#xff1f; TA 到底厉害在哪里&#xff1f; 故事从 ChatGPT 说起 去年我们看到 Open AI 发布ChatGPT 后&#xff0c;全球的注意力到了 AI 身上。 我们来拆…...

RAG中构建个人知识库

1. 添加本地模型 1.1 查看本地模型 ollama list1.2 ragflow添加本地模型 1.3 系统模型配置 2. 构建知识库 2.1 准备知识库素材 2.2 配置知识库 2.3 知识库绑定素材文件 上传文件素材 - 解析文件 3. 构建交互系统 3.1 配置助理 3.2 完善提示词 3.3 设置模型参数 4. 体验效…...

在 Kubernetes (k8s) 中,apiserver 的 IIP和 VIP的区别

在 Kubernetes (k8s) 中&#xff0c;apiserver 的 IIP&#xff08;Internal IP&#xff09; 和 VIP&#xff08;Virtual IP&#xff09; 是与集群网络通信和高可用性设计相关的两个重要概念。 IIP&#xff08;Internal IP&#xff09; 定义&#xff1a; IIP 是 apiserver 所在…...

OpenCV--图像形态学

在图像处理领域&#xff0c;图像形态学是一种基于形状进行图像分析的有力工具&#xff0c;广泛应用于图像分割、特征提取、边缘检测、图像降噪等多个方面。借助 OpenCV 这个强大的计算机视觉库&#xff0c;我们可以轻松实现各种图像形态学操作。本文将深入探讨图像形态学的基本…...

智慧医疗数据集

WiNGPT2 更新时间&#xff1a;2024-11-29 访问地址: GitHub 描述&#xff1a; WiNGPT是一个基于GPT的医疗垂直领域大模型&#xff0c;旨在将专业的医学知识、医疗信息、数据融会贯通&#xff0c;为医疗行业提供智能化的医疗问答、诊断支持和医学知识等信息服务&#xff0c;…...

3D激光轮廓仪知识整理(待补充)

文章目录 1.原理和应用场景1.1 相机原理1.1.1 测量原理1.1.2 相机激光器1.1.3 沙姆镜头1.1.4 相机标定1.1.5 中心线提取 1.2 应用场景1.2.1 测量相关应用1.2.2 缺陷检测相关易用 2.相机参数介绍及选型介绍2.1 成像原理2.2 原始图成像2.3 生成轮廓图2.4 相机规格参数2.4.1 单轮廓…...

算法思想之双指针

文章目录 双指针字符串序列判定字符串所有整数最小和服务交换接口失败率分析分披萨最多团队 双指针 双指针是指在解决问题时使用两个指针&#xff0c;通常分别指向数组或字符串中的不同位置&#xff0c;通过移动这两个指针来解决问题的一种技巧。双指针技巧常用于解决数组、链…...

Windows环境下PyCharm 配置miniforge

问题描述. 目前Anconda python 环境管理软件&#xff0c;已非常臃肿。为了替代该软件&#xff0c;可以使用miniforge软件来代替。 1. 安装windows miniforge软件 (1) 下载网站&#xff1a;https://github.com/conda-forge/miniforge?tabreadme-ov-file 从网址下载&#xff…...

C语言基础18

内容提要 构造类型 结构体 共用体/联合体 枚举 typedef 构造类型 数据类型 基本类型/基础类型 整型 短整型&#xff1a;short [int] -- 2字节 基本整型&#xff1a;int -- 4字节 长整型&#xff1a;long [int] -- 32位4字节/64位8字节 长长整型&#xff1a;long long…...

Docker部署Jenkins服务

文章目录 1.下载Jenkins服务2.部署Java21&#xff08;可选&#xff09;2.1 安装Java21 3.Maven3.9.9安装4.启动Jenkins5.初始化Jenkins5.1 入门5.2 安装推荐的插件5.3 创建第一个管理员用户5.4 实例配置5.5 Jenkins已就绪5.6 开始使用Jenkins5.7 重启Jenkins 6.配置Jenkins6.1 …...

【题解-Acwing】798. 差分矩阵

题目&#xff1a;798. 差分矩阵 题目描述 输入一个n行m列的整数矩阵&#xff0c;再输入q个操作&#xff0c;每个操作包含五个整数 x1,y1,x2,y2,c&#xff0c;其中 (x1,y1)和 (x2,y2)表示一个子矩阵的左上角坐标和右下角坐标。 每个操作都要将选中的子矩阵中的每个元素的值加…...

linux环境下的硬盘分区格式化工具介绍 fdisk,gdisk,parted,cfdisk,cgdisk,sfdisk,gparted 笔记250407

linux环境下的硬盘分区格式化工具介绍 fdisk,gdisk,parted,cfdisk,cgdisk,sfdisk,gparted 笔记250407 以下是 Linux 系统中常用的 硬盘分区与格式化工具&#xff0c;涵盖命令行和图形界面工具&#xff0c;按功能分类整理&#xff1a; 一、分区管理工具 1. 命令行工具 工具功能…...

Ubuntu 24.04 LTS系统安装RTX 4090显卡驱动和cuda并部署ollama下载DeepSeek模型【自用详细版】

自己捣鼓玩玩哈&#xff0c;正好有机子 1. 安装驱动前的系统配置工作 卸载原有驱动并禁用nouveau sudo apt remove --purge nvidia*sudo cp /etc/modprobe.d/blacklist.conf /etc/modprobe.d/blacklist.conf.backup //备份文件sudo vim /etc/modprobe.d/blacklist.conf //修…...

FogFL: Fog-Assisted Federated Learning for Resource-Constrained IoT Devices

摘要 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 -在本文中&#xff0c;我们提出了一个支持雾的联邦学习框架–FogFL–来促进资源受限的物联网环境中延迟敏感应用的分布式学习。联邦学习&#xff08;FL&#xff09;是一种流行的分…...

音视频入门基础:RTCP专题(2)——RTCP协议简介(上)

一、引言 本文对RTCP协议进行简介。在简介之前&#xff0c;请各位先下载RTCP的官方文档《RFC 3550》。《RFC 3550》总共有89页。本文下面所说的“页数”是指在pdf阅读器中显示的页数&#xff1a; 二、RTCP协议简介 本段内容对应《RFC 3550》的第6节。根据《RFC 3550》第17页&…...