深入理解 Java 代理模式:从基础到实战
在软件开发的世界里,设计模式是程序员智慧的结晶,它们为解决常见问题提供了经过验证的最佳实践。代理模式作为一种常用的结构型设计模式,在 Java 开发中有着广泛的应用。本文将深入探讨 Java 代理模式,从基本概念、分类、实现原理到实际应用,带您全面理解这一重要的设计模式。
一、代理模式基本概念
代理模式(Proxy Pattern)的核心思想是通过引入一个代理对象来控制对真实对象的访问。代理对象在客户端和真实对象之间起到中介作用,它可以在不修改真实对象代码的情况下,为真实对象添加额外的功能或控制访问行为。
举个生活中的例子,比如你想租房子,可能会通过房产中介来寻找合适的房源。这里的房产中介就是一个代理,它代表你与房东进行沟通,处理租房过程中的各种事务。你不需要直接与所有房东打交道,只需通过中介即可,中介可以在这个过程中提供
筛选房源安排看房等额外服务。在软件开发中,代理模式的作用类似,它可以帮助我们更好地管理对真实对象的访问,实现功能的扩展和优化。
代理模式涉及三个主要角色:
- 抽象主题(Subject):定义了真实主题和代理主题的共同接口,客户端通过该接口访问真实主题和代理主题。
- 真实主题(Real Subject):实际处理业务逻辑的对象,是代理主题所代表的真实对象。、
- 代理主题(Proxy):实现了抽象主题接口,持有对真实主题的引用,负责控制对真实主题的访问,并可以在访问前后添加额外的操作。
二、代理模式的分类
在 Java 中,代理模式主要分为静态代理和动态代理两种类型,其中动态代理又包括 JDK 动态代理和 CGLIB 动态代理。
(一)静态代理
静态代理是指在编译时就已经确定了代理类的代码,代理类和真实类在编译时是一一对应的。下面通过一个简单的例子来演示静态代理的实现。
假设我们有一个接口Subject,定义了一个请求方法request():
public interface Subject {
void request();
}
真实主题类RealSubject实现了该接口,实现具体的请求逻辑:
public class RealSubject implements Subject {
@Override
public void request() {
System.out.println("RealSubject handling request");
}
}
代理类ProxySubject也实现了Subject接口,并且持有一个RealSubject对象的引用。在代理类的request()方法中,首先可以执行一些前置处理,然后调用真实主题的request()方法,最后执行一些后置处理:
public class ProxySubject implements Subject {
private RealSubject realSubject;
public ProxySubject(RealSubject realSubject) {
this.realSubject = realSubject;
}
@Override
public void request() {
System.out.println("Proxy before request");
realSubject.request();
System.out.println("Proxy after request");
}
}
客户端使用代理类来访问真实主题:
public class Client {
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
ProxySubject proxySubject = new ProxySubject(realSubject);
proxySubject.request();
}
}
运行结果为:
Proxy before request
RealSubject handling request
Proxy after request
静态代理的优点是实现简单,容易理解,在编译时就可以确定代理关系。但它的缺点也很明显,当需要代理多个不同的真实主题时,需要为每个真实主题创建对应的代理类,这会导致代码量增加,灵活性较差。
(二)动态代理
动态代理是在运行时动态生成代理类的一种方式,它不需要在编译时就确定代理类的代码,而是通过反射机制在运行时生成代理类。动态代理可以分为 JDK 动态代理和 CGLIB 动态代理。
1. JDK 动态代理
JDK 动态代理是 Java 自带的动态代理实现,它基于接口实现代理。JDK 动态代理需要使用java.lang.reflect.Proxy类和InvocationHandler接口。
InvocationHandler接口定义了一个invoke方法,当调用代理对象的方法时,会调用该invoke方法。我们需要实现InvocationHandler接口,在invoke方法中处理对真实主题的调用和额外的逻辑。
下面以之前的Subject接口和RealSubject类为例,演示 JDK 动态代理的实现。
首先,创建一个InvocationHandler实现类SubjectInvocationHandler:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class SubjectInvocationHandler implements InvocationHandler {
private Object target;
public SubjectInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("JDK Proxy before method");
Object result = method.invoke(target, args);
System.out.println("JDK Proxy after method");
return result;
}
}
然后,在客户端中使用Proxy.newProxyInstance方法生成代理对象:
import java.lang.reflect.Proxy;
public class Client {
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
SubjectInvocationHandler handler = new SubjectInvocationHandler(realSubject);
Subject proxy = (Subject) Proxy.newProxyInstance(
realSubject.getClass().getClassLoader(),
realSubject.getClass().getInterfaces(),
handler
);
proxy.request();
}
}
运行结果与静态代理类似:
JDK Proxy before method
RealSubject handling request
JDK Proxy after method
JDK 动态代理的优点是无需引入第三方库,基于接口实现,符合面向接口编程的思想。但它的缺点是只能代理实现了接口的类,对于没有接口的类无法使用。
2. CGLIB 动态代理
CGLIB(Code Generation Library)是一个强大的高性能代码生成库,它可以在运行时动态生成子类来实现代理。CGLIB 动态代理不需要依赖接口,它通过继承真实类来生成代理类,因此可以代理没有接口的类。
使用 CGLIB 动态代理需要引入 CGLIB 的依赖,在 Maven 项目中可以添加以下依赖:
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
假设我们有一个没有实现接口的真实类RealSubjectNoInterface:
public class RealSubjectNoInterface {
public void request() {
System.out.println("RealSubjectNoInterface handling request");
}
}
创建一个 CGLIB 的代理类,需要实现MethodInterceptor接口,该接口的intercept方法会在调用代理对象的方法时被触发:
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CglibProxy implements MethodInterceptor {
private Object target;
public CglibProxy(Object target) {
this.target = target;
}
public Object getProxy() {
net.sf.cglib.proxy.Enhancer enhancer = new net.sf.cglib.proxy.Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("CGLIB Proxy before method");
Object result = method.invoke(target, args);
System.out.println("CGLIB Proxy after method");
return result;
}
}
客户端使用 CGLIB 代理:
public class Client {
public static void main(String[] args) {
RealSubjectNoInterface realSubject = new RealSubjectNoInterface();
CglibProxy cglibProxy = new CglibProxy(realSubject);
RealSubjectNoInterface proxy = (RealSubjectNoInterface) cglibProxy.getProxy();
proxy.request();
}
}
运行结果为:
CGLIB Proxy before method
RealSubjectNoInterface handling request
CGLIB Proxy after method
CGLIB 动态代理的优点是无需接口,代理类是真实类的子类,可以代理任何类(除了 final 类)。但由于是通过继承实现的,所以不能代理 final 类,并且性能上可能会有一定的开销。
(三)JDK 动态代理与 CGLIB 动态代理的对比
特性 | JDK 动态代理 | CGLIB 动态代理 |
依赖 | 无需第三方库,Java 自带 | 需要引入 CGLIB 库 |
代理方式 | 基于接口 | 基于子类(继承) |
适用场景 | 代理实现了接口的类 | 代理没有接口的类,或者希望更灵活的代理方式 |
性能 | 反射调用,性能稍低 | 生成子类,性能相对较高 |
三、代理模式的应用场景
代理模式在 Java 开发中有很多实际应用场景,以下是一些常见的例子:
(一)远程代理
远程代理用于代理访问远程服务器上的对象。例如,在分布式系统中,客户端需要访问远程服务器上的服务,远程代理可以隐藏网络通信的细节,让客户端像调用本地对象一样调用远程对象的方法。RMI(Remote Method Invocation)就是一种典型的远程代理应用。
(二)虚拟代理
虚拟代理用于延迟加载真实对象,只有在需要使用真实对象时才创建它。例如,当处理大对象或需要复杂初始化的对象时,虚拟代理可以在对象被使用前先返回一个简单的代理对象,当真正需要使用时再加载真实对象,从而提高系统的性能和响应速度。
(三)保护代理
保护代理用于控制对真实对象的访问权限,确保只有符合条件的客户端才能访问真实对象。例如,在系统中,不同的用户角色可能具有不同的访问权限,保护代理可以在代理对象中检查客户端的权限,决定是否允许访问真实对象。
(四)日志记录与性能监控
代理模式可以用于在方法调用前后添加日志记录和性能监控代码,而无需修改真实对象的代码。通过代理对象,我们可以统一在代理类中实现日志记录和性能统计功能,实现代码的复用和解耦。
四、代理模式的优缺点
(一)优点
- 解耦:代理模式将客户端与真实对象解耦,客户端通过代理对象访问真实对象,不需要知道真实对象的具体实现细节。
- 扩展性:可以在不修改真实对象代码的情况下,通过代理对象添加额外的功能,符合开闭原则。
- 控制访问:代理对象可以控制对真实对象的访问,实现访问权限控制、延迟加载等功能。
- 集中处理公共逻辑:像日志记录、事务处理、性能监控等公共逻辑可以集中在代理类中实现,避免在真实对象中重复编写代码。
(二)缺点
- 增加复杂度:引入代理模式会增加系统的类数量和复杂度,特别是在使用动态代理时,需要理解反射机制和相关的 API。
- 性能开销:动态代理通过反射机制调用方法,会带来一定的性能开销;静态代理则需要为每个真实对象创建代理类,增加了代码量。
- 学习成本:对于初学者来说,理解代理模式的原理和实现需要一定的学习成本,特别是动态代理涉及到反射等高级特性。
五、总结
代理模式是一种非常实用的设计模式,它通过引入代理对象来控制对真实对象的访问,实现了功能的扩展和优化。在 Java 中,静态代理实现简单,但灵活性较差;动态代理包括 JDK 动态代理和 CGLIB 动态代理,分别适用于不同的场景。JDK 动态代理基于接口,CGLIB 动态代理基于子类,开发者可以根据具体需求选择合适的代理方式。
代理模式在实际开发中有广泛的应用,如远程代理、虚拟代理、保护代理等,它能够帮助我们更好地管理对象的访问,实现代码的解耦和复用。虽然代理模式存在一定的缺点,但在合适的场景下使用,可以显著提高系统的可维护性和扩展性。
作为 Java 开发者,掌握代理模式的原理和应用是非常重要的。通过不断地实践和学习,我们可以更好地运用代理模式来解决实际开发中的问题,写出更加优雅、高效的代码。
相关文章:
深入理解 Java 代理模式:从基础到实战
在软件开发的世界里,设计模式是程序员智慧的结晶,它们为解决常见问题提供了经过验证的最佳实践。代理模式作为一种常用的结构型设计模式,在 Java 开发中有着广泛的应用。本文将深入探讨 Java 代理模式,从基本概念、分类、实现原理…...
Python毕业设计219—基于python+Django+vue的房屋租赁系统(源代码+数据库+万字论文)
毕设所有选题: https://blog.csdn.net/2303_76227485/article/details/131104075 基于pythonDjangovue的房屋租赁系统(源代码数据库万字论文)219 一、系统介绍 本项目前后端分离,分为租客、房东、管理员三种角色 1、租客: 注册、登录、公…...
Spring Boot 框架概述
1. 简介 Spring Boot 是由 Pivotal 团队开发的一个用于简化 Spring 应用开发的框架。它通过提供默认配置、嵌入式服务器和自动配置等特性,让开发者能够更快速地构建独立的、生产级别的 Spring 应用。 Spring Boot 的主要特点包括: 快速创建独立的 Spri…...
MySQL 8.0(主从复制)
MySQL 8.0 的 主从复制(Master-Slave Replication) 是一种数据库高可用和数据备份的核心技术,下面用 一、什么是主从复制? 就像公司的「领导-秘书」分工: 主库(Master):负责处理所…...
探索大型语言模型的 LLM 安全风险和 OWASP 十大漏洞
大型语言模型 (LLM) 引领着技术进步,推动着包括医疗保健在内的各个领域的自动化进程。在 Halodoc,我们通过 AI 驱动技术的运用直接见证了这一变化。然而,强大的功能伴随着同样重大的责任——保障这些系统的安全对于保护敏感信息和维护信任至关重要。本博客探讨了与 LLM 相关…...
算法与数据结构 - 二叉树结构入门
目录 1. 普通二叉树结构 1.1. 常见术语 1.2. 完全二叉树 (Complete Binary Tree) 1.3. 满二叉树 (Full Binary Tree) 2. 特殊二叉树结构 2.1. 二叉搜索树 (BST) 2.1.1. BST 基本操作 - 查找 2.1.2. BST 基本操作 - 插入 2.1.3. BST 基本操作 - 删除 2.2. 平衡二叉树…...
基于AQS实现Reentrantlcok
好久没有更新了 这次来补充上一次AQS还没有实现的可重入锁部分! 我们知道ReentrantLock是可重入的锁,主要的核心是state,他是一个原子性的整数,我们只需要将获取锁的代码boolean由false到true变成0->1即可完成。在完成删除逻辑…...
TiDB预研-分页查询、连接查询、执行计划
目录 分页查询原理连接查询原理查询计划分析 https://docs.pingcap.com/zh/tidb/stable/dev-guide-join-tables/ https://cn.pingcap.com/blog/tidb-query-optimization-and-tuning-1/ https://github.com/pingcap/blog-cn/blob/master/how-to-use-tidb.md 分页查询 深分…...
五、【LLaMA-Factory实战】模型部署与监控:从实验室到生产的全链路实践
【LLaMA-Factory实战】模型部署与监控:从实验室到生产的全链路实践 一、引言 在大模型应用落地过程中,从实验室研究到生产环境部署存在巨大挑战。本文基于LLaMA-Factory框架,详细介绍大模型部署与监控的完整流程,包含推理优化、…...
Unity 点击按钮,打开 Windows 文件选择框,并加载图片
代码如下: using System; using System.Collections; using System.Runtime.InteropServices; using UnityEngine; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.UI;/// <summary> /// 文件日志类 /// </summary> // […...
深入解析磁盘 I/O 与零拷贝技术:从传统读取到高效传输
深入解析磁盘 I/O 与零拷贝技术:从传统读取到高效传输 在现代计算机系统中,磁盘 I/O 操作是数据处理的核心环节之一。无论是读取文件、写入数据,还是进行网络传输,磁盘 I/O 的效率直接影响到系统的整体性能。本文将深入探讨磁盘 I…...
第十六章,网络型攻击防范技术
网络攻击介绍 网络攻击 --- 指的是入侵或破坏网络上的服务器 ( 主机 ) ,盗取服务器的敏感数据或占用网络带宽。 网络攻击分类: 流量型攻击 网络层攻击 应用层攻击 单包攻击 畸形报文攻击 --- 向目标主机发送有缺陷的IP报文,使得目标在…...
线程的生命周期·
知识点详细说明 Java线程的生命周期由Thread.State枚举明确定义,包含以下6种状态: 1. 新建状态(NEW) 定义:线程对象被创建后,但未调用start()方法。特点: 未分配系统资源(如CPU时间片)。可通过Thread.getState()获取状态为NEW。示例:Thread t = new Thread(); // 状…...
kafka 面试总结
Kafka的幂等性是一种机制,确保生产者发送的每条消息在Broker端只被持久化一次,即使生产者因网络问题等原因重试发送,也不会导致消息重复。 实现原理 生产者ID(PID) 每个生产者实例在初始化时,会被分配一个…...
Webpack基本用法学习总结
Webpack 基本使用核心概念处理样式资源步骤: 处理图片资源修改图片输出文件目录 自动清空上次打包的内容EslintBabel处理HTML资源搭建开发服务器生产模式提取css文件为单独文件问题: Css压缩HTML压缩 小结1高级SourceMap开发模式生产模式 HMROneOfInclud…...
5月9日复盘-混合注意力机制
5月9日复盘 四、混合注意力 混合注意力机制(Hybrid Attention Mechanism)是一种结合空间和通道注意力的策略,旨在提高神经网络的特征提取能力。 1. CBAM Convolution Block Attention Module ,卷积块注意力模块 论文地址&…...
YOLOv8 优化:基于 Damo-YOLO 与 DyHead 检测头融合的创新研究
文章目录 YOLOv8 的背景与发展Damo-YOLO 的优势与特点DyHead 检测头的创新之处融合 Damo-YOLO 与 DyHead 检测头的思路融合后的模型架构融合模型的代码实现导入必要的库定义 Damo-YOLO 的主干网络定义特征金字塔网络(FPN)定义 DyHead 检测头定义融合后的…...
【网安播报】Meta 推出 LlamaFirewall开源框架以阻止 AI 越狱、注入和不安全代码
1、Meta 推出 LlamaFirewall 框架以阻止 AI 越狱、注入和不安全代码 Meta 宣布推出 LlamaFirewall,这是一个开源框架,旨在保护人工智能 (AI) 系统免受新出现的网络风险,例如提示词注入、越狱和不安全代码等。除了 Llam…...
QT 解决msvc fatal error C1060: 编译器的堆空间不足
一.物理内存太小,代码又比较复杂,递归嵌套之类的。 1.修改虚拟内存的大小,一般设置为物理内存的1.5倍。 二.msvc工程的编译默认开启的是多线程编译,所以电脑内存确实不够,采用如下设置。 QMAKE_CXXFLAGS -j1 三.ms…...
PX4开始之旅(一)自动调参
核心知识点:无人机震动与滤波参数 1. 通俗易懂的解释 想象一下,你的无人机就像一个非常敏感的“听众”,它的“耳朵”就是陀螺仪和加速度计这些传感器,用来感知自己是如何移动和旋转的。理想情况下,它应该只“听”到你…...
C++ 中 lower_bound 与 upper_bound 函数详解
C 中 lower_bound 与 upper_bound 函数详解 文章目录 C 中 lower_bound 与 upper_bound 函数详解**一、核心定义与区别****二、使用条件与时间复杂度****三、实际应用场景****四、注意事项与常见误区****五、代码示例****六、总结** 一、核心定义与区别 lower_bound 作用&#…...
minio数据迁移(两台服务器没法相互通信)
场景描述: A服务器 无法访问 B服务器,B服务器 也无法访问 A(即双方都不能通过公网或内网直连对方) MinIO 官方提供了 mc(MinIO Client)命令行工具,可以直接实现 Bucket 之间的数据迁移: 安装 …...
O2OA(翱途)开发平台系统安全-用户登录IP限制
O2OA(翱途)开发平台[下称O2OA开发平台或者O2OA]支持对指定的用户设置可以连接的客户端计算机的IP地址,以避免用户在不安全的环境下访问系统。本篇主要介绍如何开启O2OA用户登录IP限制。 一、先决条件: 以拥有管理员权限的用户账号登录O2OA(翱途)开发平…...
CSS flex:1
在 CSS 中,flex: 1 是一个用于弹性布局(Flexbox)的简写属性,主要用于控制 flex 项目(子元素)如何分配父容器的剩余空间。以下是其核心作用和用法: 核心作用 等分剩余空间:让 flex …...
OpenHarmony平台驱动开发(十一),PIN
OpenHarmony平台驱动开发(十一) PIN 概述 功能简介 PIN即管脚控制器,用于统一管理各SoC的管脚资源,对外提供管脚复用功能。 基本概念 PIN是一个软件层面的概念,目的是为了统一对各SoC的PIN管脚进行管理࿰…...
.NET高频技术点(持续更新中)
1. .NET 框架概述 .NET 框架的发展历程.NET Core 与 .NET Framework 的区别.NET 5 及后续版本的统一平台 2. C# 语言特性 异步编程(async/await)LINQ(Language Integrated Query)泛型与集合委托与事件属性与索引器 3. ASP.NET…...
Spring Cloud - 2( 12000 字详解 Spring Cloud)
一:服务注册和服务发现 - Eureka 1.1 背景 在上一章节的例子中,我们可以看到远程调用时 URL 被硬编码,这导致在更换机器或新增机器时,相关的 URL 需要进行相应的变更。这就需要让所有相关服务去修改 URL,随之而来的就…...
解决Win11下MySQL服务无法开机自启动问题
问题描述 在win11系统中,明明将MySQL服务设置成了自动启动,但在重启电脑后MySQL服务还是无法自动启动,每次都要重新到计算机管理的服务中找到服务再手动启动。 解决方式 首先确保mysql服务的启动类型为自动。 设置方法:找到此电…...
RGB矩阵照明系统详解及WS2812配置指南
RGB矩阵照明系统详解及WS2812配置指南 一、RGB矩阵照明简介 RGB矩阵照明是一种强大的功能,允许使用外部驱动器驱动的RGB LED矩阵为键盘增添绚丽的灯光效果。该系统与RGBLIGHT功能无缝集成,因此您可以使用与RGBLIGHT相同的键码来控制它,操作…...
全球首款无限时长电影生成模型SkyReels-V2本地部署教程:视频时长无限制!
一、简介 SkyReels-V2 模型集成了多模态大语言模型(MLLM)、多阶段预训练、强化学习以及创新的扩散强迫(Diffusion-forcing)框架,实现了在提示词遵循、视觉质量、运动动态以及视频时长等方面的全面突破。通过扩散强迫框…...
代理ARP与传统ARP在网络通信中的应用及区别研究
一些问题 路由器隔离广播域,每个接口/网段都是独立的广播域ARP请求是二层广播包,广播包没法通过路由器ARP请求没法穿越互联网到达目标主服务器 一些思考 电脑访问互联网服务器的时候,ARP询问的内容,真的是访问服务器么…...
理解 Envoy 的架构
理解 Envoy 的架构对于深入理解 Istio 至关重要,因为 Envoy 是 Istio 数据平面的核心。Envoy 是一个高性能的 C 分布式代理,设计为云原生应用和大规模微服务架构的网络基础。 以下是 Envoy 架构的关键组成部分和核心理念: 核心设计理念&…...
使用Kotlin Flow实现Android应用的响应式编程
在Android应用中使用Kotlin Flow实现响应式编程可以分为以下步骤,结合最佳实践和生命周期管理: 1. 添加依赖 在build.gradle中确保包含协程和生命周期相关依赖: dependencies {implementation("org.jetbrains.kotlinx:kotlinx-corouti…...
【AI提示词】蝴蝶效应专家
提示说明 一位专注于分析和优化蝴蝶效应现象的专业人士,擅长将微小变化转化为系统级影响的研究者。 提示词 # Role: 蝴蝶效应专家## Profile - language: 中文 - description: 一位专注于分析和优化蝴蝶效应现象的专业人士,擅长将微小变化转化为系统级…...
StreamRL:弹性、可扩展、异构的RLHF架构
StreamRL:弹性、可扩展、异构的RLHF架构 大语言模型(LLMs)的强化学习(RL)训练正处于快速发展阶段,但现有架构存在诸多问题。本文介绍的StreamRL框架为解决这些难题而来,它通过独特设计提升了训…...
架构进阶:大型制造业企业数据架构顶层设计总体规划方案【附全文阅读】
本文概述了一个大型企业数据架构设计的总体规划方案,针对当前数据架构与管理中存在的诸多问题,如缺乏统一数据模型、数据分析应用体系不健全、主数据管理体系不完善、数据治理体系缺失等,提出了明确的改进目标与实施路径。 数据架构设计思路聚焦于明确数据分布和流向…...
前端指南——项目代码结构解析(React为例)
文件结构 文件项目 ├── doc │ ├── technology.md ├── node_modules ├── public ├── shell ├── src │ ├── auto-generated │ │ ├── apis │ │ ├── models │ ├── components │ │ ├── 组件A │ │ ├── 组件B …...
Redis-数据一致性问题与解决方案
Redis-数据一致性问题与解决方案 引言 Redis 是一个高性能的内存数据库,广泛应用于缓存、会话存储、实时分析等场景。作为一个 NoSQL 数据库,它的高性能和丰富的数据结构使其成为现代微服务架构中不可或缺的组件。然而,在高并发的环境下&am…...
【数据结构】算法的复杂度
前言:经过了C语言的学习,紧接着就步入到数据结构的学习了。在C语言阶段我们在写大多数的oj题的时候会遇到一些问题,就是算法的效率低使用的时间较多,占用的空间也多,数据结构就是来优化算法的。 文章目录 一ÿ…...
Leetcode刷题 由浅入深之字符串——541. 反转字符串Ⅱ
目录 (一)反转字符串Ⅱ的C实现 写法一(s.begin()遍历字符) (二)复杂度分析 时间复杂度 空间复杂度 (三)总结 【题目链接】541. 反转字符串Ⅱ - 力扣&am…...
制造单元智能化改造与集成技术平台成套实训设备
制造单元智能化改造与集成技术平台成套实训设备 一、概述: 本设备以汽车行业的轮毂为产品对象,实现了仓库取料、制造加工、打磨抛光、检测识别、分拣入位等生产工艺环节,以未来智能制造工厂的定位和需求为参考,通过工业以太网完成…...
Vscode 顶部Menu(菜单)栏消失如何恢复
Vscode 顶部Menu(菜单)栏消失如何恢复 https://blog.csdn.net/m0_62964247/article/details/135759655 Vscode 顶部Menu(菜单)栏消失如何恢复? 首先按一下 Alt按键,看一下是否恢复了菜单栏 如果恢复了想了解更进一步的设置,或是没能恢复菜单…...
苍穹外卖--公共字段自动填充
1.问题分析 业务表中的公共字段: 问题:代码冗余、不便于后期维护 2.实现思路 自定义注解AutoFill,用于标识需要进行公共字段填充的方法 自定义切面类AutoFillAspect,统一拦截加入了AutoFill注解的方法,通过反射为公…...
行业 |四大痛点待破:“拆解”DeepSeek一体机
繁荣DeepSeek一体机市场。 2025年开年,DeepSeek大模型掀起的一体机热潮席卷中国AI市场。这款一体机凭借其“开箱即用”的便利性和极低的门槛,吸引了大量企业关注,尤其是在中小企业和行业创新者中,更是成为了新晋“顶流”。 无论…...
革新锅炉厂智能控制——Ethernet IP转CANopen协议网关的工业互联新方案
锅炉厂智能化转型的必经之路 在工业4.0时代,锅炉厂作为能源供应的核心环节,正面临智能化升级的迫切需求。传统锅炉控制系统往往因协议不兼容、数据孤岛问题导致效率低下、维护成本高昂。如何实现设备间高效协同?如何让老旧设备融入智能网络&…...
基于卷积神经网络和Pyqt5的猫狗识别小程序
任务描述 猫狗分类任务(Dogs vs Cats)是Kaggle平台在2013年举办的一个经典计算机视觉竞赛。官方给出的Kaggle Dogs vs Cats 数据集中包括由12500张猫咪图片和12500张狗狗图片组成的训练集,12500张未标记照片组成的测试集。选手需要在规定时间…...
Baklib知识中台引领服务智能跃迁
智能架构重构服务范式 Baklib 知识中台通过全量数据融合与多模态处理能力,重塑企业服务底层逻辑。基于分布式架构设计,平台将分散在业务系统、文档库及外部渠道的非结构化数据进行智能清洗与语义解析,形成标准化的知识元数据池。通过四库体系…...
【Python】超全常用 conda 命令整理
Conda命令整理文档,结合官方指南与高频使用场景分类说明,每个命令都有对应的解释 一、环境管理 1. 创建环境 基本创建conda create --name my_env # 创建名为my_env的空环境 conda create -n my_env python3.11 # 指定Python版本 conda creat…...
FreeRTOS菜鸟入门(十四)·事件
目录 1. 基本概念 2. 应用场景 3. 运作机制 4. 控制块 5. 事件函数接口 5.1 事件创建函数 xEventGroupCreate() 5.2 事件删除函数 vEventGroupDelete() 5.3 事件组置位函数 xEventGroupSetBits()(非中断) 5.4 事件组置位函数 xEventGr…...
setData执行后操作方法-微信小程序
在微信小程序中,setData 是异步执行的,如果你需要在 setData 执行完毕后执行某些操作,可以通过以下几种方式实现: 1. 使用 setData 的回调函数 从基础库 2.2.3 开始,setData 支持传入回调函数,回调会在数据…...