深入浅出JavaScript常见设计模式:从原理到实战(2)
深入浅出JavaScript常见设计模式:从原理到实战(2)
本文是深入浅出JavaScript常见设计模式:从原理到实战(1)的续集
设计模式是一种在特定情境下解决软件设计中常见问题的通用方案或模板。在特定的开发场景中使用特定的设计模式,可以提升代码质量,增强代码可读性和可维护性,提高团队开发效率,降低软件设计的复杂度。本文将介绍前端开发中常用的设计模式,讲解他们的含义,核心特性,使用场景及注意事项
一、设计模式核心认知
1.1 什么是设计模式
- 定义:经过验证的代码组织最佳实践方案
- 黄金三角:
- 场景:特定问题的解决方案
- 结构:类/对象的关系拓扑
- 效果:可维护性/扩展性提升
1.2 为什么需要设计模式
- 代码腐化防控:减少面条式代码
- 架构清晰度:提高模块化程度(示例:React Hooks vs Class组件)
- 团队协作:统一代码交流语言
二、三大高频设计模式详解
2.1 代理模式(Proxy)
代理模式(Proxy Pattern)是结构型设计模式的核心实现之一,其核心目标是通过代理对象控制对原始对象的访问,在不修改原始对象的前提下增强其功能。以下是其关键要点:
核心特性
特性 | 说明 |
---|---|
访问控制 | 代理对象控制对原始对象的访问权限 |
功能增强 | 添加缓存、验证、日志等附加功能 |
延迟初始化 | 按需创建高开销对象(虚拟代理) |
接口一致性 | 代理与原始对象实现相同接口,客户端无感知 |
应用场景
-
虚拟代理
- 图片懒加载(延迟加载大图)
- 按需加载模块(Webpack动态导入)
-
保护代理
- API请求权限校验(JWT Token验证)
- 敏感操作审计(删除操作日志记录)
-
缓存代理
- 接口响应缓存(减少重复请求)
- 复杂计算缓存(斐波那契数列记忆化)
-
远程代理
- RPC调用封装(像调用本地方法一样调用远程服务)
- WebSocket通信代理
代码实现(综合缓存+权限校验代理)
class DatabaseService { constructor() { this.data = new Map(); } // 原始方法 query(sql) { console.log(`执行SQL: ${sql}`); return Math.random() * 100; // 模拟查询结果 } // 敏感操作 deleteTable(name) { console.log(`删除表: ${name}`); return true; }
} // 代理类
class DatabaseProxy { constructor(role = 'guest') { this.db = new DatabaseService(); this.cache = new Map(); this.role = role; } // 代理查询方法(添加缓存) query(sql) { if (this.cache.has(sql)) { console.log('返回缓存结果'); return this.cache.get(sql); } const result = this.db.query(sql); this.cache.set(sql, result); return result; } // 代理删除方法(添加权限校验) deleteTable(name) { if (this.role !== 'admin') { throw new Error('权限不足'); } return this.db.deleteTable(name); } // 扩展代理功能(添加日志) auditLog(action) { console.log(`[审计日志] ${new Date().toISOString()} 执行了 ${action}`); }
} // 使用示例
const adminProxy = new DatabaseProxy('admin');
console.log(adminProxy.query('SELECT * FROM users')); // 执行真实查询
console.log(adminProxy.query('SELECT * FROM users')); // 返回缓存结果
adminProxy.deleteTable('logs'); // 成功执行 const guestProxy = new DatabaseProxy();
guestProxy.deleteTable('users'); // 抛出权限错误
实现流程图解
注意事项
-
性能损耗
- 代理链过长会导致调用延迟,解决方案:
// 使用组合代理替代继承链 const proxy = compose(logProxy, cacheProxy, authProxy)(realObject);
-
过度代理
- 避免无意义的代理层,遵循YAGNI原则
// 仅在需要时创建代理 function createProxy(target, needs) { return needs.reduce((obj, feature) => { return feature === 'cache' ? new CacheProxy(obj) : obj; }, target); }
-
与装饰器模式区别
- 代理控制访问,装饰器增强功能
现代框架中的演进
-
Vue3响应式代理
const raw = { count: 0 }; const proxy = new Proxy(raw, { get(target, key) { track(target, key); // 依赖收集 return Reflect.get(...arguments); }, set(target, key, value) { trigger(target, key); // 触发更新 return Reflect.set(...arguments); } });
-
React高阶组件(HOC)
function withLoading(WrappedComponent) { return function Enhanced(props) { const [loading, setLoading] = useState(true); useEffect(() => { setLoading(false); }, []); return loading ? <Spinner /> : <WrappedComponent {...props} />; }; }
-
Node.js HTTP中间件
const proxyMiddleware = (req, res, next) => { const targetUrl = determineTarget(req.url); httpProxy.web(req, res, { target: targetUrl }, next); }; app.use('/api', proxyMiddleware);
模式延伸
-
动态代理
function createDynamicProxy(handler) { return new Proxy({}, { get(target, prop) { return (...args) => handler(prop, args); } }); } const apiProxy = createDynamicProxy((method, params) => { return fetch(`/api/${method}`, { body: JSON.stringify(params) }); }); apiProxy.getUsers({ page: 1 }); // 实际调用 /api/getUsers
-
虚拟化代理
class HeavyResourceProxy { constructor() { this.resource = null; } load() { if (!this.resource) { this.resource = new HeavyResource(); // 按需初始化 } return this.resource; } }
-
代理模式组合
最佳实践示例:实现智能API客户端
class SmartAPIClient { constructor(baseURL) { return new Proxy(this, { get(target, endpoint) { return params => fetch(`${baseURL}/${endpoint}`, { method: 'POST', body: JSON.stringify(params) }) .then(res => res.json()) .catch(err => ({ error: err.message })); } }); }
} // 使用示例
const api = new SmartAPIClient('https://api.example.com');
api.users({ id: 1 }).then(console.log);
api.products({ category: 'books' }).then(console.log);
2.2 工厂模式(Factory)
工厂模式(Factory Pattern)是创建型设计模式的核心实现之一,其核心目标是封装对象创建过程,通过统一接口动态创建不同类型的对象,实现客户端与具体类的解耦。以下是其关键要点:
核心特性
特性 | 说明 |
---|---|
创建封装 | 隐藏对象实例化逻辑,客户端仅关注接口 |
类型扩展 | 新增产品类型无需修改客户端代码 |
多态支持 | 工厂方法返回抽象类型的具体实现 |
条件创建 | 根据输入参数动态创建不同对象 |
应用场景
-
UI组件库
- 根据配置生成不同风格的按钮/表单
- 跨平台组件渲染(Web/Mobile)
-
支付系统
- 根据用户选择创建支付处理器(支付宝/微信/银联)
- 国际化货币处理器
-
游戏开发
- 动态生成NPC角色(敌人/盟友)
- 武器/装备生成系统
-
数据解析
- 根据文件类型选择解析器(JSON/XML/CSV)
- 不同数据源的适配器创建
代码实现(支持抽象工厂的增强版)
// 抽象产品接口
class Button { render() { throw new Error("必须实现render方法"); }
} // 具体产品
class PrimaryButton extends Button { render() { return "<button class='primary'>Submit</button>"; }
} class DangerButton extends Button { render() { return "<button class='danger'>Delete</button>"; }
} // 抽象工厂
class UIFactory { createButton() { throw new Error("必须实现createButton方法"); } createInput() { throw new Error("必须实现createInput方法"); }
} // 具体工厂
class WebUIFactory extends UIFactory { createButton() { return new PrimaryButton(); } createInput() { return "<input type='text'>"; }
} class MobileUIFactory extends UIFactory { createButton() { return new DangerButton(); } createInput() { return "<input type='number'>"; }
} // 客户端代码
function renderUI(platform) { const factory = platform === 'mobile' ? new MobileUIFactory() : new WebUIFactory(); const button = factory.createButton(); const input = factory.createInput(); document.body.innerHTML = `${button.render()} ${input}`;
} // 使用示例
renderUI('web'); // 生成Web风格UI
renderUI('mobile'); // 生成Mobile风格UI
实现流程图解
注意事项
-
避免过度设计
- 简单场景直接使用构造函数
// 只有当需要处理多种类型时使用工厂 class SimpleButton { constructor(type) { this.type = type; } }
-
工厂膨胀问题
- 使用参数化工厂替代多子类
class DynamicUIFactory { constructor(config) { this.config = config; } createButton() { return new this.config.buttonClass(); } }
-
与构造函数对比
工厂模式 构造函数 返回任意对象 必须返回当前类实例 可缓存/复用实例 每次调用创建新实例 支持更复杂的创建逻辑 适合简单初始化场景
现代框架中的演进
-
React组件工厂
function createComponent(type, props) { const components = { Button: <button {...props} />, Input: <input {...props} /> }; return components[type]; } // 使用 <div>{createComponent('Button', { onClick })}</div>
-
Vue插件工厂
const pluginFactory = (options) => ({ install(app) { app.component(options.name, options.component); } }); Vue.use(pluginFactory({ name: 'CustomButton', component: ButtonComponent }));
-
Node.js模块缓存
// Node.js的require机制本质是工厂模式 const express = require('express'); const app = express();
模式延伸
-
工厂方法 vs 抽象工厂
-
与原型模式结合
class PrototypeFactory { constructor(prototypes) { this.prototypes = prototypes; } create(type) { return this.prototypes[type].clone(); } }
-
依赖注入实现
class Container { constructor() { this.factories = new Map(); } register(type, factory) { this.factories.set(type, factory); } resolve(type) { return this.factories.get(type)(); } }
2.3 模块化模式(Module)
模块化模式(Module Pattern)是JavaScript中最基础的组织代码模式,通过闭包和立即执行函数实现作用域隔离,核心目标是封装私有状态,暴露公共接口。以下是其关键要点:
核心特性
特性 | 说明 |
---|---|
命名空间 | 避免全局变量污染 |
私有封装 | 通过闭包保护内部状态 |
接口暴露 | 选择性公开方法与属性 |
依赖管理 | 显式声明模块依赖关系 |
应用场景
-
工具库开发
- Lodash/Underscore等工具函数封装
- 日期处理/数学计算专用模块
-
第三方SDK
- 支付SDK(支付宝/微信支付接口封装)
- 地图SDK(Google Maps API包装)
-
业务模块
- 用户认证模块(登录/注册/权限)
- 购物车管理模块
-
旧代码重构
- 将全局函数重构为模块
- jQuery插件开发
代码实现(支持依赖注入的增强版)
const UserModule = (($, _) => { // 私有变量 let users = []; const API_URL = '/api/users'; // 私有方法 function fetchUsers() { return $.get(API_URL).then(data => { users = _.sortBy(data, 'name'); }); } // 暴露公共接口 return { init() { fetchUsers().then(() => { console.log('用户数据加载完成'); }); }, getUsers() { return [...users]; }, addUser(user) { users.push(user); return $.post(API_URL, user); } };
})(jQuery, _); // 使用示例
UserModule.init();
setTimeout(() => { console.log(UserModule.getUsers());
}, 1000);
实现流程图解
注意事项
-
内存泄漏
- 避免在闭包中保留DOM引用
function createModule() { const element = document.getElementById('app'); // 危险! return { update() { /*...*/ } }; }
-
单元测试困难
- 通过依赖注入解决
const TestableModule = (deps = { fetch: fetch }) => ({ getData() { return deps.fetch('/data'); } });
-
模块通信
通信方式 优点 缺点 全局事件总线 松耦合 难以追踪数据流 直接引用 简单直接 增加耦合度 依赖注入 可测试性好 增加配置复杂度
现代框架中的演进
-
ES6 Modules
// math.js export function add(a, b) { return a + b; } // app.js import { add } from './math.js';
-
Webpack模块联邦
// app1 暴露模块 new ModuleFederationPlugin({ name: "app1", exposes: { "./Button": "./src/Button.js" } }); // app2 使用远程模块 import("app1/Button").then(Button => { ReactDOM.render(<Button />, root); });
-
Node.js CommonJS
// 模块导出 module.exports = { method: () => { /*...*/ } }; // 模块导入 const lib = require('./lib');
模式延伸
-
增强模块模式
const EnhancedModule = (original => ({ ...original, newMethod() { // 扩展功能 } }))(UserModule);
-
沙箱模式
function Sandbox(...deps) { const modules = {}; return { register(name, impl) { modules[name] = impl; }, require(name) { return modules[name]; } }; }
-
动态加载
const DynamicModule = { load(name) { return import(`./modules/${name}.js`); } };
模块化演进史:
最佳实践组合:
// 现代模块化方案
import { factory } from './factory.js';
import { logger } from '@monorepo/utils'; export default (config) => { const module = factory.create(config); logger.debug('Module initialized'); return Object.freeze(module);
};
四、下期预告
总共有23种经典的设计模式,本篇文章介绍了3种前端开发中常用的设计模式,其他设计模式将在下篇文章中继续分享哦,敬请期待~
相关文章:
深入浅出JavaScript常见设计模式:从原理到实战(2)
深入浅出JavaScript常见设计模式:从原理到实战(2) 本文是深入浅出JavaScript常见设计模式:从原理到实战(1)的续集 设计模式是一种在特定情境下解决软件设计中常见问题的通用方案或模板。在特定的开发场景中使用特定的设计模式,可以提升代码质…...
MySQL 主从复制
数据的高可用性、读写分离以及数据备份是至关重要的需求。MySQL 作为一款广泛使用的开源关系型数据库,其主从复制功能为解决这些问题提供了有效的方案。本文将详细介绍 MySQL 主从复制的原理、搭建步骤以及实际应用。 一、MySQL 主从复制原理 1.1 基本概念 MySQL…...
小目标检测的集成融合论文阅读
摘要 小目标检测常因图像模糊和分辨率低而受到阻碍,这给小目标的精确检测和定位带来了重大挑战。此外,传统的特征提取方法往往难以捕捉到这些目标的有效表征,因为下采样和卷积操作会导致小目标细节的模糊化。为了解决这些问题,本研究提出了一种基于集成融合的方法,通过利…...
IP SSL证书常见问题:快速实现HTTPS加密
SSL证书作为实现HTTPS加密和身份验证的关键工具,不仅适用于域名,还能直接绑定IP地址,为IP通信提供安全保障。 一、什么是IP SSL证书? IP SSL证书(IP HTTPS证书)是一种专为IP地址设计的SSL/TLS证书…...
Scratch——第20课 辗转相除法/绳子算法
辗转相除法是用于求取最大公约数时需要用到的方法,它还有个名字称为绳子算法,这类题目只要理解辗转相处的原理即可拿下。 一、辗转相除法的基本原理 两个整数的最大公约数不变,当较大数减去较小数后,得到的差值与较小数的最大公…...
MYOJ_1349:(洛谷P3951)[NOIP 2017 提高组] 小凯的疑惑(数学公式套用,两步搞定代码)
提示 本题代码纯属数学的结晶,因此肥肠简单,但需要一定理解。 题目描述 小凯手中有两种面值的金币,两种面值均为正整数且彼此互素。每种金币小凯都有无数个。在不找零的情况下,仅凭这两种金币,有些物品他是无法准确支付…...
如何免费把PPT的页面输出为透明的图片-快速制作图新说汇报内容
0.序 经常有朋友问想把PPT中的内容输出为图片,但是PPT里面的officePlus还得付费才可以。不付费就带水印还不高清,关键是还不透明,如果需要透明就设置纯底色去PS里面抠图(可自动化),或者手动右键挨个输出。…...
操作系统——第四章(文件管理与文件的逻辑结构)
一、文件系统基础 1.文件的属性 文件名:由创建文件的用户决定文件名,主要是为了方便用户找到文件,同一目录下不允许有重名文件标识符:一个系统内的各文件标识符唯一,对用户来说毫无可读性。因此标识符只是操作系统用…...
剑指offer经典题目(七)
目录 动态规划 字符串相关 排序思想相关 链表相关 动态规划 题目1:输入一个长度为n的整型数组array,数组中的一个或连续多个整数组成一个子数组,子数组最小长度为1。求所有子数组的和的最大值。OJ地址 图示如下。 题目解析:…...
[RoarCTF 2019]Easy Calc 详解
[RoarCTF 2019]Easy Calc 1 ajax 是进行前后端交互的 但是我们发现一个waf 就是他提示的"calc.php?num"encodeURIComponent($("#content").val()) ?num 的值必须是数字审计一下 foreach 发现了num的限制但是eval是rce的标志所以我们首选的就是使用命令…...
AI日报 - 2025年04月29日
🌟 今日概览(60秒速览) ▎🤖 AGI突破 | 巨头CEO预测AGI时间线,5年内或达人类认知水平;Yann LeCun强调多模态训练重要性。 关于AGI定义和实现时间的讨论升温,对超越纯文本训练的需求成为共识。 ▎💼 商业动向…...
Kubernetes的错误信息处理
报错信息 E0428 13:18:25.531614 3193818 memcache.go:287] couldn’t get resource list for metrics.k8s.io/v1beta1: the server is currently unable to handle the request 以下是处理该 Kubernetes 指标服务报错的系统化解决方案: 错误诊断流程 # 1. 检查 …...
杰理-安卓通过map获取时间的时候,部分手机切换sbc和aac时候单耳无声音
杰理-安卓通过map获取时间的时候,部分手机切换sbc和aac时候单耳无声音 #if USER_SUPPORT_PROFILE_MAPif(tws_api_get_role()0){ //主机才获取,否则切换sbc 和 aac 的时候影响单耳无声音user_send_cmd_prepare(USER_CTRL_MAP_READ_TIME,0,NULL);} #endif…...
基于 Python 的实现:居民用电量数据分析与可视化
基于 Python 的实现:居民用电量数据分析与可视化 本文将介绍如何利用 Python 技术栈(包括 pymysql、pandas、matplotlib 等库)对居民用电量数据进行分析和可视化,以帮助我们更好地理解用电行为模式。 数据准备 在MySQL数据库中创建数据,,数据库表结构如下: date:记录…...
el-transfer穿梭框数据量过大的解决方案
一:背景 我们这个穿梭框获取的是项目的全量数据,在左边大概有5000条,自己测试了一下5000条数据的效果,发现异常的卡顿,本来打算像el-select一样去解决的(只显示一部分,在搜索的时候去全量搜索&a…...
【3D基础】深入解析OBJ与MTL文件格式:Blender导出模型示例及3D开发应用
引言 在3D模型开发和3D引擎加载过程中,OBJ格式是最基础、最常见的标准之一。即便在今天流行的GLTF、USDZ格式出现后,OBJ依然是建模软件和渲染引擎普遍支持的基本格式。 本文以Blender导出的立方体模型为例,详细讲解OBJ与MTL文件每一部分的含…...
Fiddler+Yakit实现手机流量抓包和小程序抓包
文章目录 一、小程序抓包1、配置Fiddler2、配置Yakit 二、手机流量抓包1、配置Fiddler2、手机连接电脑热点并配置代理服务器3、手机安装证书4、配置Yakit 三、总结 操作工具:Yakit Fiddler 一、小程序抓包 1、配置Fiddler 点击Tools—>Options进入如下配置页面…...
C++实时统计数据均值、方差和标准差
文章目录 1. 算法原理2. 类设计3. 完整代码实现4. 总结 本文采用了一种递推计算方法(Welford 算法)实时更新数据的均值、方差和标准差,其算法原理及实现如下。 1. 算法原理 Welford算法是由B.P.Welford于1962年提出的,用于计…...
【广州华锐视点】AR 远程协同:突破时空限制的利器
AR 远程协同,简单来说,就是利用增强现实(AR)技术,打破地理空间的束缚,让身处不同地方的人们能够在同一虚拟空间中进行实时协作。它就像是为人们搭建了一座无形的桥梁,将现实与虚拟紧密相连,让沟通和协作变得…...
【Docker】——在Docker工具上安装创建容器并完成项目部署
🎼个人主页:【Y小夜】 😎作者简介:一位双非学校的大三学生,编程爱好者, 专注于基础和实战分享,欢迎私信咨询! 🎆入门专栏:🎇【MySQL࿰…...
9. 使用Gazebo和Rviz显示机器人(包括运动控制,雷达,摄像头仿真以及显示)
概述:通过Gazebo和Rviz集成机器人,机器人的组件包括底盘,雷达,摄像头,可以在Gazebo中仿真和显示。并且能够订阅运动控制话题,雷达话题,摄像头话题在Rviz中仿真和显示。 1.新建功能包和导入依赖 …...
跨语言哈希一致性:C# 与 Java 的 MD5 之战?
在跨平台或异构系统集成的场景中,我们经常需要在不同的编程语言之间交换数据或验证数据一致性。MD5 作为一种广泛使用的哈希算法,就常常扮演着生成唯一标识或校验数据完整性的角色。然而,不少开发者可能会遇到这样一个令人困惑的问题…...
赋能航天教育:高校卫星仿真教学实验平台解决方案
随着全球航天事业的飞速发展,对高素质航天人才的需求日益增长。如何在高校阶段提前锻炼学生的航天工程实践能力,成为教育界的重要命题。作为领先的通信与网络技术供应商,IPLOOK基于自身在5G核心网、卫星通信及仿真平台领域的深…...
H指数(中等)
可以先对数组从小到大排序,然后数组后面往前遍历,计算h的值。 如果从后往前遍历,当前位置的数,如果大于h,就说明又找到了一个引用次数大于h的文献,h指数可以加一了。 class Solution {public int hIndex(…...
推荐 1 款 9.3k stars 的全景式开源数据分析与可视化工具
Orama 是一个开源的数据分析与可视化项目,由askorama团队开发和维护。该项目旨在为用户提供一套强大而易用的工具集,帮助用户轻松处理和理解大规模数据,通过创建交互式且引人入胜的数据可视化图表,揭示隐藏在数据背后的深层次洞察…...
无人船 | 图解基于LQR控制的路径跟踪算法(以全驱动无人艇WAMV为例)
目录 1 最优控制线性二次型问题2 LQR的价值迭代推导3 基于全驱动无人船动力学的LQR4 跟踪效果分析 1 最优控制线性二次型问题 最优控制理论是一种数学和工程领域的理论,旨在寻找如何使系统在给定约束条件下达到最佳性能的方法。它的基本思想是通过选择合适的控制输…...
检查IBM MQ SSL配置是否成功
使用 DISPLAY 命令检查任务是否已成功完成。 如果任务成功,那么生成的输出类似于以下示例中显示的输出。 从队列管理器 QM1,输入以下命令: DISPLAY CHS(QM1.TO.QM2) SSLPEER SSLCERTI 生成的输出类似于以下示例: DISPLAY CHSTATUS(QM1.TO.QM2) SSLPE…...
EasyRTC嵌入式音视频通信SDK智能安防与监控系统的全方位升级解决方案
一、方案背景 随着安全防范意识的提升以及物联网、人工智能技术的发展,智能安防与监控系统在各领域的应用愈发广泛。传统监控系统多以单向视频传输为主,缺乏实时交互能力。EasyRTC凭借其低延迟、高可靠的实时音视频通信技术,能为智能安防与…...
Meta 推出 WebSSL 模型:探索 AI 无语言视觉学习,纯图训练媲美 OpenAI CLIP
Web-SSL 探索了视觉自监督学习(SSL)在网络规模数据上的扩展潜力。通过调整模型大小和训练数据,我们证明了纯视觉模型可以与 CLIP 等语言监督方法相媲美,甚至超越它们,从而对 "语言监督是学习多模态建模所需的强大…...
node.js puppeteer 实践
puppeteer 介绍 Puppeteer 是 Google 推出的一个 Node.js 库,它通过 Chromium 提供了一个高效、简洁的 API,用于操作无头浏览器或具有 UI 的完整浏览器。它广泛应用于 自动化测试、数据抓取、页面性能分析和 UI 测试等领域。 Puppeteer 是一个 Node 库&…...
【现代深度学习技术】循环神经网络07:通过时间反向传播
【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈PyTorch深度学习 ⌋ ⌋ ⌋ 深度学习 (DL, Deep Learning) 特指基于深层神经网络模型和方法的机器学习。它是在统计机器学习、人工神经网络等算法模型基础上,结合当代大数据和大算力的发展而发展出来的。深度学习最重…...
如何在idea中写spark程序
一、环境准备 1. 安装 IntelliJ IDEA: 下载并安装 IntelliJ IDEA(推荐使用 Community 版本,它已经支持 Scala 和 Spark 开发)。 官方下载地址:[JetBrains IntelliJ IDEA](https://www.jetbrains.com/idea/downlo…...
硬件加密+本地部署,大模型一体机如何打造AI安全护城河?
2025年,大模型技术加速渗透千行百业,但随之而来的安全风险也引发广泛关注。数据显示,近九成企业部署的大模型服务器存在“裸奔”隐患,数据泄露、模型篡改、算力劫持等问题频发。 在此背景下,大模型一体机凭借“开箱即…...
在另外一台可以科学下载的电脑用ollama下载模型后,怎么导入到另外一台服务器的ollama使用
环境: Win10专业版 Ubuntu20.04 问题描述: 在另外一台可以科学下载的电脑用ollama下载模型后,怎么导入到另外一台服务器的ollama使用,原电脑win10上的ollama下载的模型,复制到ubuntu20.04的ollama上推理 解决方案:…...
鼠标滚动字体缩放
在VsCode中编辑文件时,有时候发现Ctrl鼠标滚轮并不能缩放字体,下面是启用这个功能的方法。 第一步: 进入设置,可以从左下角按钮菜单进入,也可以使用【Ctrl,】。 第二步: 启用鼠标滚轮缩放功能 第三步&…...
什么是VR相机?VR相机的发展历史
VR相机:沉浸式体验的未来科技 VR相机,全称为虚拟现实相机,是专门用于捕捉和记录三维空间和场景的设备,能够拍摄360度全景照片和视频。通过模拟人的双眼视觉差异,利用多个镜头和传感器同时捕捉周围环境的图像ÿ…...
Java面试:Spring及Spring Cloud技术深度剖析
Spring及Spring Cloud技术深度剖析 前言 在Java开发领域,Spring框架一直是企业级应用开发的中流砥柱,而Spring Boot的出现更是极大地简化了Spring应用的开发过程。同时,Spring Cloud为构建分布式系统提供了强大的支持。本文将围绕Spring及S…...
论文阅读_Search-R1_大模型+搜索引擎
英文名称:Search-R1: Training LLMs to Reason and Leverage Search Engines with Reinforcement Learning 中文名称:Search-R1:训练大型语言模型进行推理并利用搜索引擎的强化学习 链接: http://arxiv.org/pdf/2503.09516v2 代码: https://g…...
零成本AI抠图终极指南:蓝耘元生代AIDC OS+ComfyUI实现商业级效果
引言:AI抠图革命已经到来 在数字内容创作爆炸式增长的今天,高质量的图像处理已成为刚需。无论是电商平台的商品展示、自媒体博主的封面设计,还是摄影爱好者的后期处理,抠图都是最基础也是最繁琐的工作之一。 传统抠图方式面临三…...
深入理解CSS3:Flex/Grid布局、动画与媒体查询实战指南
引言 在现代Web开发中,CSS3已经成为构建响应式、美观且高性能网站的核心技术。它不仅提供了更强大的布局系统(Flexbox和Grid),还引入了令人惊艳的动画效果和精准的媒体查询能力。本文将深入探讨这些关键技术,帮助您提…...
VLM-E2E:通过多模态驾驶员注意融合增强端到端自动驾驶——论文阅读
《VLM-E2E Enhancing End-to-End Autonomous Driving with Multimodal Driver Attention Fusion》2025年2月发表,来自香港科大广州分校、理想汽车和厦门大学的论文。 一、核心问题与动机 现有端到端(E2E)自动驾驶系统直接从传感器输入映射到…...
蓝牙BLE
1、简介 蓝牙BR/EDR和BLE是蓝牙技术的两个重要分支,它们各自具有独特的特点和应用场景。 1.1、蓝牙BR/EDR 蓝牙BR(Basic Rate) 定义:蓝牙技术的首个开发版本,采用高斯频移键控(GFSK)调制技术…...
在VS2022中使用Lua与c交互(二)
一、核心交互机制:Lua 虚拟栈 Lua 与 C 的交互通过一个 虚拟栈(Stack) 完成,所有数据传递、函数调用均通过此栈实现。栈的每个元素可以是任意 Lua 类型(如数字、字符串、表、函数等)。 栈的结构与…...
论文阅读_Citrus_在医学语言模型中利用专家认知路径以支持高级医疗决策
英文名称:Citrus: Leveraging Expert Cognitive Pathways in a Medical Language Model for Advanced Medical Decision Support 中文名称:Citrus:在医学语言模型中利用专家认知路径以支持高级医疗决策 链接: http://arxiv.org/pdf/2502.18…...
浅谈PCB传输线(一)
前言:浅谈传输线的类型,以及传输线的一些行为特性。 1.传输线的种类 2.互连线被视为传输线的场景 3.传输线的行为特性*** 1.传输线的种类 PCB 中的信号传输线通常有两种基本类型: 微带线和带状线。此外,还有第三种类型–共面线(没有参考平面…...
Spring-全面详解(学习总结)
一:概述 1.1 为什么学 解决了两个主要问题 1. 2 学什么 1.3 怎么学 二:系统架构 作用:web开发、微服务开发、分布式系统开发 容器:用于管理对象 AOP:面向切面编程(不惊动原始程序下对其进行加强) 事…...
突破JVM边界:类加载三重门与栈帧的生存法则
类加载子系统 文件验证阶段 类加载子系统在加载Class文件时,首先会验证文件格式规范,检查文件开头的魔数标识,确保这是一个合法的JVM字节码文件。 职责边界 该子系统仅负责将Class文件加载到内存中,并不关心后续能否成功执行—…...
VSCode 查看文件的本地修改历史
1. 使用时间线视图(Timeline) 新版 VSCode 内置了一个叫 Timeline(时间线) 的功能,可以查看: 本地文件修改记录(包括保存历史)Git 提交历史(如果仓库是 Git 管理的&…...
在QGraphicsView中精确地以鼠标为锚缩放图片
在pyqt中以鼠标所在位置为锚点缩放图片-CSDN博客中的第一个示例中,通过简单设置: self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse) 使得QGraphicsView具有了以鼠标为锚进行缩放的功能。但是,其内部应当是利用了滚动条的移动来…...
【Python数据驱动决策】数据分析与可视化全流程实战指南
目录 前言技术背景与价值当前技术痛点解决方案概述目标读者说明一、技术原理剖析核心概念图解核心作用讲解关键技术模块说明技术选型对比二、实战演示环境配置要求核心代码实现案例1:销售数据清洗案例2:月度销售趋势分析案例3:产品关联分析(热力图)运行结果验证三、性能对…...