构建优雅对象的艺术:Java 建造者模式的架构解析与工程实践
一、建造者模式的本质与核心价值
在面向对象的软件设计中,创建复杂对象一直是一个需要精心处理的问题。当一个对象的构建需要多个步骤,并且这些步骤具有不同的组合方式时,传统的构造函数方式会显得力不从心。建造者模式(Builder Pattern)应运而生,它通过将对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。这种模式特别适用于需要分步骤构建复杂对象,且对象的构建步骤稳定但具体参数变化较多的场景。
从本质上讲,建造者模式是一种将对象构建过程封装的设计模式。它允许我们通过链式调用的方式逐步设置对象的属性,最终生成一个完整的对象。这种方式不仅提高了代码的可读性和可维护性,还使得对象的构建过程更加灵活和可控。例如,当我们需要构建一个包含多个可选参数的复杂对象时,建造者模式可以让我们避免编写大量的构造函数,同时确保对象在构建过程中始终处于一致的状态。
二、建造者模式的核心结构与角色分工
建造者模式主要由四个核心角色组成:抽象建造者(Builder)、具体建造者(Concrete Builder)、产品(Product)和指挥者(Director)。
(一)产品(Product)
产品是我们最终要构建的复杂对象,它包含了多个属性,这些属性可能有不同的类型和组合方式。例如,一个汽车对象可能包含发动机、轮胎、座椅、颜色等属性,这些属性的不同组合会形成不同类型的汽车。
(二)抽象建造者(Builder)
抽象建造者定义了构建产品各个部件的抽象方法,以及返回最终产品的方法。它是一个接口或抽象类,为具体建造者提供了统一的构建接口。例如,抽象汽车建造者可能定义了构建发动机、构建轮胎、构建座椅等方法,以及获取最终汽车对象的方法。
(三)具体建造者(Concrete Builder)
具体建造者实现了抽象建造者定义的方法,具体负责构建产品的各个部件。每个具体建造者可以根据不同的需求,实现不同的构建逻辑,从而生成不同的产品表示。例如,豪华汽车建造者和普通汽车建造者可以分别实现抽象汽车建造者的方法,构建出不同配置的汽车。
(四)指挥者(Director)
指挥者负责统筹整个构建过程,它知道如何使用建造者来构建产品。指挥者可以有不同的构建策略,根据不同的策略调用建造者的方法,从而构建出不同的产品。在一些简单的场景中,指挥者角色可能会被省略,直接由客户端代码来控制构建过程。
这四个角色相互协作,形成了一个完整的建造者模式结构。客户端通过使用具体建造者和指挥者,可以灵活地构建出各种复杂的对象,而无需关心具体的构建细节。
三、Java 中建造者模式的经典实现
(一)简单产品的建造者实现
我们以一个简单的用户对象为例,用户对象包含姓名、年龄、性别、地址等属性,其中地址又包含省份、城市、街道等子属性。使用建造者模式来构建这个用户对象,可以让我们通过链式调用的方式方便地设置各个属性。
首先定义用户类(Product):
java
public class User {private String name;private int age;private String gender;private Address address;// 省略getter和setter方法,以及构造函数
}public class Address {private String province;private String city;private String street;// 省略getter和setter方法,以及构造函数
}
然后定义抽象建造者接口(Builder):
java
public abstract class UserBuilder {protected User user = new User();public abstract UserBuilder setName(String name);public abstract UserBuilder setAge(int age);public abstract UserBuilder setGender(String gender);public abstract UserBuilder setAddress(Address address);public abstract User build();
}
接着实现具体建造者(Concrete Builder):
java
public class ConcreteUserBuilder extends UserBuilder {@Overridepublic UserBuilder setName(String name) {user.setName(name);return this;}@Overridepublic UserBuilder setAge(int age) {user.setAge(age);return this;}@Overridepublic UserBuilder setGender(String gender) {user.setGender(gender);return this;}@Overridepublic UserBuilder setAddress(Address address) {user.setAddress(address);return this;}@Overridepublic User build() {return user;}
}
客户端使用建造者构建用户对象:
java
public class Client {public static void main(String[] args) {Address address = new Address("广东省", "广州市", "天河区");User user = new ConcreteUserBuilder().setName("张三").setAge(25).setGender("男").setAddress(address).build();}
}
(二)复杂场景下的扩展实现
在实际开发中,可能会遇到更复杂的场景,例如产品的构建步骤需要有一定的顺序,或者某些属性是必须设置的,而其他属性是可选的。这时我们可以在建造者中添加一些校验逻辑,确保对象在构建过程中满足一定的条件。
例如,我们可以要求用户对象的姓名和年龄是必须设置的属性,在 build 方法中进行校验:
java
public class ConcreteUserBuilder extends UserBuilder {// 省略其他方法@Overridepublic User build() {if (user.getName() == null || user.getAge() == 0) {throw new IllegalArgumentException("姓名和年龄是必须设置的属性");}return user;}
}
另外,当产品的构建步骤比较复杂时,我们可以使用指挥者(Director)来管理构建过程。例如,定义一个用户构建指挥者,根据不同的需求构建不同类型的用户对象:
java
public class UserDirector {public User buildBasicUser(UserBuilder builder, String name, int age) {return builder.setName(name).setAge(age).build();}public User buildFullUser(UserBuilder builder, String name, int age, String gender, Address address) {return builder.setName(name).setAge(age).setGender(gender).setAddress(address).build();}
}
客户端使用指挥者来构建用户对象:
java
public class Client {public static void main(String[] args) {UserDirector director = new UserDirector();User basicUser = director.buildBasicUser(new ConcreteUserBuilder(), "李四", 30);// 省略其他构建逻辑}
}
四、建造者模式与其他设计模式的对比分析
(一)与工厂模式的区别
工厂模式(Factory Pattern)也是一种创建型设计模式,它主要用于创建对象,将对象的创建逻辑封装在工厂类中。工厂模式适用于创建一系列相关或依赖的对象,而建造者模式则更适用于构建复杂对象,特别是当对象的构建需要多个步骤,并且这些步骤可以有不同的组合方式时。
工厂模式通常返回的是一个简单的对象,而建造者模式返回的是一个复杂的对象,该对象可能由多个部件组成。工厂模式的重点在于对象的创建,而建造者模式的重点在于对象的构建过程,它允许我们逐步构建对象,并在构建过程中进行更多的控制和处理。
(二)与抽象工厂模式的区别
抽象工厂模式(Abstract Factory Pattern)用于创建一系列相关或相互依赖的对象家族,它提供了一个创建对象家族的接口。抽象工厂模式与建造者模式的区别在于,抽象工厂模式关注的是对象家族的创建,而建造者模式关注的是单个复杂对象的构建过程。
抽象工厂模式中的每个工厂可以创建多个相关的对象,而建造者模式中的每个建造者只能创建一个特定的产品。此外,抽象工厂模式通常用于解决对象家族的创建问题,而建造者模式用于解决单个复杂对象的构建问题,特别是当对象的构建步骤较多且需要灵活组合时。
(三)与原型模式的区别
原型模式(Prototype Pattern)通过复制现有对象来创建新对象,它适用于创建与现有对象相似的对象,避免重新初始化对象的繁琐过程。原型模式与建造者模式的区别在于,原型模式是通过复制来创建对象,而建造者模式是通过逐步构建来创建对象。
原型模式适用于对象之间差异较小,且复制对象的成本较低的场景,而建造者模式适用于对象构建过程复杂,需要分步骤设置多个属性的场景。
五、建造者模式的适用场景与最佳实践
(一)适用场景分析
- 复杂对象构建:当需要构建的对象包含多个属性,且这些属性的设置顺序和组合方式较为复杂时,使用建造者模式可以将构建过程封装,使代码更加清晰和易于维护。
- 可选参数较多:当对象的属性中有很多可选参数,而我们希望通过链式调用的方式方便地设置这些参数时,建造者模式是一个很好的选择。例如,Java 中的 StringBuilder 就是一个典型的建造者模式应用,它允许我们通过链式调用 append 方法来构建字符串。
- 分步构建与复杂校验:当对象的构建过程需要分步骤进行,并且在构建过程中需要进行一些复杂的校验或处理时,建造者模式可以将这些步骤和处理逻辑封装在建造者类中,保持产品类的简洁。
(二)最佳实践
- 合理设计建造者接口:抽象建造者接口应该定义构建产品所需的基本方法,这些方法应该具有明确的语义,方便客户端使用。具体建造者应该实现这些方法,并确保在构建过程中正确设置产品的属性。
- 处理必需属性和可选属性:对于必需的属性,应该在建造者的 build 方法中进行校验,确保对象在构建完成后处于有效状态。对于可选属性,可以提供默认值,或者在建造者中提供相应的设置方法。
- 考虑线程安全:如果建造者模式在多线程环境下使用,需要考虑线程安全问题。例如,当多个线程同时使用同一个建造者对象构建产品时,可能会导致数据不一致,这时可以通过同步方法或使用线程局部变量来解决。
- 结合 Lombok 简化代码:在 Java 开发中,我们可以使用 Lombok 的 @Builder 注解来自动生成建造者类,从而减少样板代码的编写。例如,给 User 类添加 @Builder 注解后,Lombok 会自动生成一个建造者类,客户端可以直接使用该建造者来构建 User 对象。
六、Java 标准库中的建造者模式应用
(一)StringBuilder 和 StringBuffer
Java 中的 StringBuilder 和 StringBuffer 是建造者模式的典型应用。它们用于构建可变的字符串对象,通过 append 方法可以逐步添加字符或字符串,最后通过 toString 方法得到最终的字符串对象。
例如,使用 StringBuilder 构建一个字符串:
java
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("Hello, ").append("World!");
String result = stringBuilder.toString();
(二)JavaFX 中的 UI 构建
在 JavaFX 中,构建复杂的用户界面时,也可以使用建造者模式。例如,构建一个按钮对象,可以通过链式调用设置按钮的文本、样式、事件处理等属性。
(三)ombok 的 @Builder 注解
Lombok 的 @Builder 注解是建造者模式在 Java 开发中的一个便捷应用。它可以自动为类生成建造者类,使得我们无需手动编写大量的建造者代码。使用 @Builder 注解后,类会拥有一个内部的 Builder 类,该类提供了链式调用的方法来设置类的属性,最后通过 build 方法生成对象。
例如,给 User 类添加 @Builder 注解:
java
@Builder
public class User {private String name;private int age;private String gender;private Address address;
}
客户端可以直接使用 User.builder () 来获取建造者对象,然后设置属性并构建用户对象:
java
User user = User.builder().name("王五").age(35).gender("女").address(address).build();
七、建造者模式的优缺点分析
(一)优点
- 分离构建过程与产品表示:建造者模式将对象的构建过程与产品的表示分离,使得我们可以在不改变产品内部表示的情况下,灵活地改变构建过程,从而生成不同的产品表示。
- 提高代码可读性和可维护性:通过链式调用的方式设置对象的属性,使得代码更加清晰易懂,易于维护。同时,建造者类封装了复杂的构建逻辑,保持了产品类的简洁。
- 支持复杂对象的构建:对于包含多个属性和复杂构建步骤的对象,建造者模式提供了一种有效的构建方式,确保对象在构建过程中始终处于一致的状态。
- 方便添加新的构建步骤:如果需要添加新的构建步骤或修改现有构建步骤,只需修改具体建造者类,而不会影响到其他代码,符合开闭原则。
(二)缺点
- 增加类的数量:建造者模式需要定义抽象建造者、具体建造者等类,这会增加系统中的类的数量,可能会使系统变得更加复杂,特别是对于简单对象的构建,使用建造者模式可能会显得过于繁琐。
- 指挥者角色的复杂性:在复杂的场景中,指挥者角色可能会变得比较复杂,需要管理多个构建步骤和不同的构建策略,这可能会增加开发和维护的难度。
- 对不变对象的支持有限:建造者模式通常用于构建可变对象,对于不可变对象(即对象在创建后属性不能被修改),使用建造者模式时需要确保在 build 方法之后对象的属性不再被修改,这需要在设计时进行特别处理。
八、总结与拓展思考
建造者模式是一种非常实用的创建型设计模式,它在处理复杂对象的构建问题时表现出色。通过将构建过程封装,它为我们提供了灵活、可控的对象创建方式,使得代码更加清晰、易于维护。在 Java 开发中,无论是标准库中的 StringBuilder,还是 Lombok 的 @Builder 注解,都体现了建造者模式的广泛应用。
然而,任何设计模式都有其适用场景和局限性,建造者模式也不例外。在使用建造者模式时,我们需要根据具体的需求来判断是否合适,避免过度设计。对于简单对象的构建,使用传统的构造函数可能更加简洁;而对于复杂对象,特别是需要分步骤设置多个可选参数的情况,建造者模式则是首选。
随着软件系统的不断复杂,设计模式的合理应用将成为提高代码质量和开发效率的关键。建造者模式教会我们如何将复杂的问题分解,通过封装和抽象来简化实现。希望通过本文的解析,读者能够深入理解建造者模式的核心思想,并在实际开发中灵活运用,写出更加优雅、可维护的代码。
在未来的技术发展中,随着 Java 语言的不断演进和新的开发框架的出现,建造者模式可能会有更多的应用形式和拓展场景。例如,在响应式编程、函数式编程等领域,建造者模式可能会与其他设计模式相结合,形成更加强大的解决方案。保持对设计模式的学习和实践,将有助于我们更好地应对不断变化的开发需求,提升自己的技术水平。
相关文章:
构建优雅对象的艺术:Java 建造者模式的架构解析与工程实践
一、建造者模式的本质与核心价值 在面向对象的软件设计中,创建复杂对象一直是一个需要精心处理的问题。当一个对象的构建需要多个步骤,并且这些步骤具有不同的组合方式时,传统的构造函数方式会显得力不从心。建造者模式(Builder …...
vim启动的时候,执行gg
在 Vim 编辑器中,gg 命令是一个非常有用的命令,它可以将光标快速移动到当前窗口的顶部(即第一行)。如果你想在 Vim 启动时自动执行 gg 命令,有几种方法可以实现这一点: 方法 1:使用 Vim 的启动…...
【SSL部署与优化】HTTP/2与HTTPS的协同效应
HTTP/2与HTTPS的协同效应:为何HTTP/2强制要求TLS 1.2? HTTP/2是HTTP协议的现代升级版,旨在通过多路复用、头部压缩等技术提升性能。然而,HTTP/2的设计与部署与HTTPS(TLS加密)紧密相关,甚至强制…...
JavaScript篇:揭秘函数式与命令式编程的思维碰撞
大家好,我是江城开朗的豌豆,一名拥有6年以上前端开发经验的工程师。我精通HTML、CSS、JavaScript等基础前端技术,并深入掌握Vue、React、Uniapp、Flutter等主流框架,能够高效解决各类前端开发问题。在我的技术栈中,除了…...
ubuntu24.04上安装NVIDIA driver+CUDA+cuDNN+Anaconda+Pytorch
一、NVIDIA driver 使用Ubuntu系统的:软件和更新——>附加驱动,安装NVIDIA驱动。 二、CUDA 安装命令:sudo apt install nvidia-cuda-toolkit 三、cuDNN cuDNN 9.10.0 Downloads | NVIDIA Developer 四、Anaconda Download Anaconda Di…...
vue3基础学习(上) [简单标签] (vscode)
目录 1. Vue简介 2. 创建Vue应用 2.1 下载JS文件 2.2 引用JS文件 2.3 调用Vue方法编辑 2.4 运行一下试试: 2.5 代码如下 3.模块化开发模式 3.1 Live Server插件 3.2 运行 4. 常用的标签 4.1 reactive 4.1.1 运行结果 4.1.2 代码: 4.2 ref 4.2.1 运行结果 4.2.2…...
.Net HttpClient 使用代理功能
HttpClient 使用代理功能 实际开发中,HttpClient 通过代理访问目标服务器是常见的需求。 本文将全面介绍如何在 .NET 中配置 HttpClient 使用代理(Proxy)功能,包括基础使用方式、代码示例、以及与依赖注入结合的最佳实践。 注意…...
深入理解Java适配器模式:从接口兼容到设计哲学
引言:接口不兼容的困局 在软件开发中,我们经常遇到这样的场景: 旧系统有一个「RS232串口设备」(仅支持sendByRS232(String data)方法),新系统需要通过「USB接口」(要求sendByUSB(String data)…...
非异步信号安全函数
这个程序演示了如何使用sigaction来捕获和处理信号(特别是SIGINT,即CtrlC)。以下是关键点和潜在问题的分析: 程序功能 信号捕获:注册自定义处理函数handler来捕获信号2(SIGINT,通常由CtrlC触发…...
PHP黑白胶卷底片图转彩图功能 V2025.05.15
关于底片转彩图 传统照片底片是摄影过程中生成的反色图像,为了欣赏照片,需要通过冲印过程将底片转化为正像。而随着数字技术的发展,我们现在可以使用数字工具不仅将底片转为正像,还可以添加色彩,重现照片原本的色彩效…...
【C++ / STL】封装红黑树实现map和set
文章目录 一. 源码及框架分析1.决定搜索类型的传参思考:为什么要传第一个参数 2.KeyOfValue的作用 二. 模拟实现map和set1. 实现出复用红黑树框架,并支持insert2. 支持iterator的实现iterator实现思路分析【iterator操作实现详解】 3.支持map的[ ]操作4.map和set代码…...
记录: Windows下远程Liunx 系统xrdp 用到的一些小问题(免费踩坑 记录)
采用liunx Ubuntu22.04版本以下,需要安装 xrdp 或者VNC 具体过程就是下载 在linux命令行里 首先更新软件包:sudo apt update 安装xrdp服务:sudo apt install xrdp 启动XRDP:sudo systemctl start xrdp(如果在启动的…...
WordPress 文章和页面:它们的区别是什么?
很多刚接触WordPress的用户,在创建网站内容时往往会遇到这样一个问题:“我应该用‘文章’还是‘页面’?”虽然两者都能发布内容,但它们之间到底有什么区别呢?这篇文章将从易于理解的角度,帮助大家厘清WordP…...
【工具变量】各省市场化指数-杨兴权版共三个方法(1997-2023年)
市场化指数是衡量中国各地区市场化改革进程的重要指标。本次数据基于杨兴全、马连福和夏立军三位学者的研究成果,系统整理并更新了我国1997-2023年间31个省、自治区、直辖市的市场化指数,便于研究者进行横向和纵向比较分析。 一、数据介绍 数据名称&…...
Android App View——团结引擎车机版实现安卓应用原生嵌入 3D 开发场景
团结引擎 1.5.0 版本已于 4 月 14 日正式发布,从 1.5.0 版本开始,团结引擎车机版带来了一个激动人心的新能力 —— Android App View。现在,开发者可以将任意第三方安卓应用以 2D 组件或 3D 组件的形式,原生嵌入到 Tuanjie 开发的…...
完整的 CentOS 6.10 虚拟机安装启动脚本
好的!下面是一个 完整的 CentOS 6.10 虚拟机安装启动脚本,专为你在 macOS(M 系芯片) QEMU(x86_64 软件模拟) 环境设计,确保你能顺利启动并安装一个接近 Red Hat 6.4 的开发环境。 ⸻ ✅ 前提准…...
如何远程执行脚本不留痕迹
通常我们在做远程维护的时候,会有这么一个需求,就是我想在远程主机执行一个脚本,但是这个脚本我又不想保留在远程主机上,那么有人就说了,那就复制过去再登录远程执行不就行了吗?嗯嗯,但是这还不…...
观测云:从云时代走向AI时代
过去十年,云计算让企业的数据处理能力实现了指数级增长,而观测云作为全栈监控观测平台,见证并参与了这一进程。通过强大的数据采集、处理与展示能力,观测云帮助数百家企业实现了对 IT 基础设施、应用服务、业务链路的全面掌控。 …...
解密企业级大模型智能体Agentic AI 关键技术:MCP、A2A、Reasoning LLMs- consistency is the key
解密企业级大模型智能体Agentic AI 关键技术:MCP、A2A、Reasoning LLMs- consistency is the key DeepSeek v3的时候,它模型已经足够强大到能带来consistency稳定性。所以当这个DeepSeek R1 Zero或者DeepSeek R1使用GRPO进行训练的时候,它能够…...
鸿蒙OSUniApp 实现图片上传与压缩功能#三方框架 #Uniapp
UniApp 实现图片上传与压缩功能 前言 在移动应用开发中,图片上传是一个非常常见的需求。无论是用户头像、朋友圈图片还是商品图片,都需要上传到服务器。但移动设备拍摄的图片往往尺寸较大,直接上传会导致流量消耗过大、上传时间过长&#x…...
SymPy | 如何提取指定项的系数
SymPy 是 Python 中一个强大的符号计算库,广泛应用于数学、物理和工程领域的符号运算。在代数表达式的处理中,提取特定项的系数是一项常见且重要的操作。本文将详细介绍 SymPy 中提取指定项系数的多种方法,并通过丰富的示例帮助读者掌握这些技…...
MUSE Pi Pro 更换kernel内核及module模块
视频讲解: MUSE Pi Pro 更换kernel内核及module模块 脚本仓库: https://github.com/LitchiCheng/MUSE-Pi-Pro-Learning 结合上期编译内核,编译成功后的输出如下: 输入 uname -a 可以看到如下信息,未修改的内核时间在 …...
java每日精进 5.14【参数校验】
参数校验 1.1概述 本文使用 Hibernate Validator 框架对 RESTful API 接口的参数进行校验,确保数据入库的正确性。 例如,在用户注册时,校验手机号格式、密码强度等。如果校验失败,抛出 ConstraintViolationException 或相关异…...
CPS联盟+小程序聚合平台分销返利系统开发|小红书番茄网盘CPA拉新推广全解析
导语: 在私域流量与社交电商爆发的时代,CPS联盟分销返利系统与小红书CPA拉新推广成为企业增长的核心引擎。本文深度解析如何通过小程序聚合平台开发、多层级返利机制搭建及精准CPA推广策略,快速占领市场,实现用户裂变与收益倍增。…...
基于EFISH-SCB-RK3576/SAIL-RK3576的光伏逆变器控制器技术方案
(国产化替代J1900的能源物联网解决方案) 一、硬件架构设计 电力转换与控制模块 高精度功率控制: Cortex-M0硬实时核驱动多相PWM(频率>200kHz),动态调节DC-AC转换误差<0.5%FPGA实现MPPT算法…...
HarmonyOS NEXT 适配高德地图FlutterSDK实现地图展示,添加覆盖物和移动Camera
HarmonyOS NEXT 适配高德地图 Flutter SDK 实现地图展示,添加覆盖物和移动 Camera 在现代移动应用开发中,地图功能是许多应用的核心组成部分之一。HarmonyOS NEXT 提供了强大的跨平台开发能力,而高德地图 Flutter SDK 则为开发者提供了丰富的…...
计算机网络:手机和基站之间是通过什么传递信息的?怎么保证的防衰减,抗干扰和私密安全的?
手机与基站之间的通信依赖无线电磁波信号,其传输介质、频率选择、抗衰减/抗干扰技术及隐私保护机制共同构成了现代移动通信的核心。以下从技术原理到实际应用逐一解析: 一、信号本质与传输介质 1. 信号类型 电磁波:手机与基站通过射频(RF)电磁波传递信息,采用数字调制技…...
C#调用C++dll 过程记录
C#调用Cdll 过程记录 问题:1、设置修改记录2 修改对应问题3 继续出问题4 许久之后的转机5 最后的成功 如题,过程记录 问题: 提示:main 已经在 dllmain.obj 中定义,针对该问题作进一步的处理 1、设置修改记录 &…...
Vue百日学习计划Day4-8——Gemini版
番茄时钟: 每个番茄钟为25分钟学习,之后休息5分钟。每完成4个番茄钟,进行一次15-30分钟的长休息。灵活性: 这仍然是一个建议性计划。某些主题(尤其是 Flexbox 和 Grid)可能需要比预期更多的时间来练习和理解…...
DHCP协议
DHCP协议 1、掌握DHCP的工作原理 2、会在Windows server上去部署DHCP服务 3、抓流量 正常收到攻击后 一、DHCP 1、DHCP基本概念 dhcp(动态主机配置协议):主要就是给客户机提供TCP/IP参数(IP地址、子网掩码、网关、DNS等) 2、好处 减少管理员工作…...
级联与端到端对话系统架构解析:以Moshi为例
一、对话系统架构对比 1.1 级联对话系统(Cascaded Dialogue Systems) 传统级联系统采用多阶段处理流程: 语音识别(ASR):将24kHz音频信号通过卷积神经网络(CNN)和Transformer转换为…...
3、ubantu系统docker常用命令
1、自助查看docker命令 1.1、查看所有命令 docker 客户端非常简单,可以直接输入 docker 命令来查看到 Docker 客户端的所有命令选项。 angqiangwangqiang:~$ dockerUsage: docker [OPTIONS] COMMANDA self-sufficient runtime for containersCommon Commands:ru…...
【leetcode】349. 两个数组的交集
文章目录 代码1.set()2. 哈希表3. 数组 给定两个数组 nums1 和 nums2 ,返回 它们的 交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。 示例 1: 输入:nums1 [1,2,2,1], nums2 [2,2] 输…...
BGP联邦和发射试验
一、要求 二、需求分析 1. **拓扑与地址规划** - **AS1**:环回16.1.1.0/24需宣告,192.168.1.0/24不宣告。 - **AS3**:环回11.1.1.0/24需宣告,192.168.2.0/24不宣告。 - **AS2**:使用172.16.0.0/16划分子…...
LeetCode Hot100 (1/100)
目录 一、有关数组和动态数组的排序(sort函数) 1.普通数组的排序 基本用法 降序排序 2.vector的排序 基本用法 降序排序 二、数组长度和一些vector的基本语法 1. 静态数组长度计算 2. 安全获取数组长度(C17 起) 3.vecto…...
LeetCode热题100--234.回文链表--简单
1. 题目 给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。 示例 1: 输入:head [1,2,2,1] 输出:true 示例 2: 输入…...
Java—接口和抽象类
一、接口 Java 接口(Interface) 是面向对象编程中用于定义行为规范的核心机制。接口通过抽象方法约定“能做什么”,而不关心“如何做”,从而实现多态和代码解耦。 1.1 接口的特点 接口用interface定义接口中全为抽象方法默认用p…...
CycleISP: Real Image Restoration via Improved Data Synthesis通过改进数据合成实现真实图像恢复
摘要 大规模数据集的可用性极大释放了深度卷积神经网络(CNN)的潜力。然而,针对单图像去噪问题,获取真实数据集成本高昂且流程繁琐。因此,图像去噪算法主要基于合成数据开发与评估,这些数据通常通过广泛假设…...
算法题(146):最大子段和
、 审题: 本题需要我们找到给定数组中子段之和和最大的sum值 思路: 方法一:暴力解法 我们可以使用双层for循环,第一层循环负责遍历每一个数组元素,然后分别以他们为子段起点,第二层循环从第一层循环的索引开…...
centos6.10在Macbook m芯片上使用
非常好!用 CentOS 6.10 替代 6.4 是一个明智的选择 ✅,原因如下: ⸻ ✅ 为什么选 CentOS 6.10 更好 对比项 CentOS 6.4 CentOS 6.10 发布年份 2013 年 2018 年(CentOS 6 系列最终版) 内核版本 2.6.32-358 2.6.32-75…...
OA 系统办公自动化包含哪些内容,关键功能模块与操作要点说明
在企业数字化转型浪潮中,OA 系统常被片面认知为请假审批、文件收发的工具,未能发挥其核心价值。部分企业引入 OA 后,出现员工抵触、流程卡顿、系统闲置等问题,根源在于对其功能定位模糊、应用模式僵化,导致无法实现预期…...
AI智能体的现状和应用前景
AI智能体的现状 AI智能体(AI Agents)是指能够感知环境、做出决策并执行任务的智能系统。它们通常结合了机器学习、自然语言处理、计算机视觉等技术,能够在复杂环境中自主运行。目前,AI智能体已经在多个领域取得了显著进展。 在工业领域,AI智能体被用于自动化生产线、质量…...
操作系统实验 实验3 存储器分配与回收
1.实验目的 了解动态分区分配方式中使用的数据结构和分配算法,并进一步加深动态分区存储管理方式及其实现过程的理解。 2.实验要求 用C语言实现首次适应算法的动态分区分配过程alloc()和回收过程free()。 一、实验内容: 1.实验内容 用C语言实…...
408考研逐题详解:2009年第13题
2009年第13题 浮点数加、减运算过程一般包括对阶、尾数运算、规格化、舍入和判溢出等步骤。设浮点数的阶码和尾数均采用补码表示,且位数分别为 5 位和 7 位(均含 2 位符号位)。若有两个数 X 2 7 29 / 32 X2^7\times29/32 X2729/32, Y 2 …...
什么是虚拟同步发电机
虚拟同步发电机(Virtual Synchronous Generator, VSG) 是一种基于电力电子技术的先进控制策略,通过模拟传统同步发电机的机电特性和动态行为,使逆变器或储能系统能够像传统发电机一样为电网提供惯性支撑、频率调节和电压稳定性支持…...
性能比拼: Linkerd vs. Istio
本内容是对知名性能评测博主 Anton Putra Linkerd vs. Istio (Rust vs. C) performance benchmark 内容的翻译与整理, 有适当删减, 相关指标和结论以原作为准 在本内容中,我们将对比 Kubernetes 服务网格中的 Istio 和 Linkerd。 相关代码详见 github 我们将运行…...
FPGA: Xilinx Kintex 7实现PCIe接口
在Xilinx Kintex-7系列FPGA上实现PCIe(Peripheral Component Interconnect Express)接口,通常使用Xilinx提供的7 Series Integrated Block for PCIe IP核,结合Vivado设计流程。以下是实现PCIe接口的详细步骤和关键点,适…...
《Effective Python》第2章 字符串和切片操作——Python 字符串格式化的现代选择f-strings
引言 本篇博客基于学习《Effective Python》第三版 Chapter 2: Strings and Slicing 的 Item 11 “Prefer Interpolated F-Strings Over C-style Format Strings and str.format” 的总结与延伸。 字符串格式化是 Python 编程中的常见操作,用于动态生成可读性高的…...
vue 去掉右边table的下拉条与下面的白色边框并补充满
::v-deep table {width: 100% !important; } ::v-deep .el-table::after, .el-table::before {display: none !important; }/* 隐藏滚动条但保留滚动功能 */ ::v-deep .el-table__body-wrapper::-webkit-scrollbar {width: 0 !important;height: 0 !important; }::v-deep .el-t…...
RabbitMq消息阻塞,立即解决方案
如果目前你的 RabbitMQ 消费者 被卡住不再消费消息,且消息已经到达消费者绑定队列,但Spring Cloud Stream 没有继续触发 StreamListener 的方法执行。这类问题一般是因为消费者线程阻塞或消息被 RabbitMQ 拒绝投递。我们可以按照下面的步骤紧急处理&…...