设计模式浅析
一、设计模式的使用场景
设计模式(Design Patterns)是在软件开发中经过验证的最佳实践,用于解决常见的设计问题。它们提供了一种可复用的解决方案,可以帮助开发人员提高代码质量、可维护性和可重用性。设计模式的采用通常在以下情况下被考虑:
1.代码重用性:当您发现多个地方有相似的代码结构或逻辑时,可以考虑使用设计模式来提取这些共通的部分,以提高代码的重用性。
2.扩展性:当系统需要支持未来的扩展或修改时,设计模式可以帮助您构建灵活和可扩展的架构。
3.可维护性:设计模式通常使代码结构更清晰、易于理解,这有助于提高代码的可维护性。通过遵循设计模式的最佳实践,可以使代码更易于阅读、调试和修改。
4.解决复杂问题:当面对复杂的设计问题时,如对象间通信、资源管理、并发控制等,设计模式提供了一种经过验证的解决方案。
5.团队协作:在团队开发环境中,使用设计模式可以提高代码的一致性和可维护性,促进团队成员之间的沟通和协作。
6.适应变化:当软件需求经常发生变化时,设计模式可以帮助您构建更加灵活和适应变化的系统。
需要注意的是,虽然设计模式在软件开发中很有用,但过度使用或不当地使用它们也可能导致代码过度复杂化和难以理解。那怎样定义过度使用呢,遵循事不过三的原则即可,只有没有重复的代码或者方法有三个的时候就不用优化。
二、使用介绍
在之前的工作经历中我有过多次使用设计模式的经历,一次是使用工厂和策略两种设计模式统一接口完成多端多业务类型多类型页面资源,减少了接口数量和开发成本,完成了查询广告页面的组件化,当时面临的问题是有多种类型的app,app上有不同的页面,不同页面根据不同的业务或者标识去数据库里面查询配置的不同的页面,但是我们页面的数据逻辑又在其他系统,我们只能在自己系统内完成这样的筛选逻辑,在当时要么根据不同的客户端开放不同的接口,要么根据不同的业务类型开放不同的接口,那这样肯定会随着端的增多或者业务类型的增多会产生接口爆炸的情况,要么就是在一个接口内完成大量的判断来完成这样的逻辑,那有没有可能借助设计模式来解决呢?当时我就在寻找相关的案例,最后觉得工厂模式和策略模式的结合是很好的方式,简单工厂模式的作用是提供专门的工厂类用于创建对象,实现了对象创建和使用的职责分离,客户端不需知道所创建的具体产品类的类名以及创建过程,只需要知道具体产品类所对应的参数即可。
这样不正是拟合了根据上送和客户端参数创建多端工厂的场景吗?而策略模式是把具体的算法实现从业务逻辑中剥离出来,成为一系列独立算法类,使得它们可以相互替换。那也正好拟合了我们根据上送的业务类型和页面类型寻找不同处理类的场景
*
(一)策略和工厂模式
下面我来展示一个简化版本根据的demo,方便大家理解的。
客户端
@SpringBootTest
public class ApplicationTest {
@Autowired
ClientFactory clientFactory;@Test
public void test() {String result1 = clientFactory.getClient("wechat").getResult();System.out.println("-----------------");System.out.println(result1);String result2 = clientFactory.getClient("alipay").getResult();System.out.println("-----------------");System.out.println(result2);
}
}
创建工厂
@Service
public class ClientFactory {
private final Map<String, ClientService> clientServiceMap = new ConcurrentHashMap<>();public ClientService getClient(String appType) {ClientService clientService = clientServiceMap.get(appType);if (clientService == null) {throw new RuntimeException("未找到客户端");}return clientService;
}
}
客户端接口
public interface ClientService {
String getResult();
}
支付宝实现
@Component(value = “alipay”)
public class AlipayServiceImpl implements ClientService {
@Override
public String getResult() {return "我是支付宝";
}
}
微信实现
@Component(value = “wechat”)
public class WechatServiceImpl implements ClientService {
@Override
public String getResult() {return "我是微信";
}
}
从上面可以看出,调用者仍然只需要传入自己的参数,在寻找具体处理类和方法的路径都被包装在工厂方法和springbean和具体类的映射关系处理中。以后增加了新的客户端百度,只需要新增一个BaiduService处理类即可。
(二)模版方法
还有一次经历是是使用模版方法完成业务逻辑的组件化,之前一个业务逻辑有很多个版本,我还需要再增加2个版本,全部流程大致有15步流程,在不同的版本可能会有缺少不同的步骤,所以之前的逻辑就有在不同步骤中有各自版本的判断导致很难清晰的看出每个版本自己的逻辑是什么,导致我很难加自己的逻辑,也很不利于排查问题。
那怎样解决这样一个问题呢?最后结合模版方法的模式来重构了一遍代码,我们先看下模版方法模式的定义,模板方法模式定义了一个算法
的步骤,并允许子类别为一个或多个步骤提供其实践方式。让子类别在不改变算法架构的情况下,重新定义算法中的某些步骤。它主要优点包括:
- 封装不变部分:将算法的核心结构和不变部分封装在基本方法中,使得子类可以根据需求对可变部分进行扩展,而不影响不变部分。
- 代码复用:抽象类中包含的基本方法可以避免子类重复实现相同的代码逻辑,提高了代码的复用性。
- 更好的扩展性:由于具体实现由子类来完成,可以方便地扩展新的功能或变更实现方式,同时不影响模板方法本身。
这样的不正好拟合我这样场景吗。我将业务逻辑中的步骤梳理出来,放到一个抽象类中,公共部分在抽象类中实现,不同版本的内容定义成抽象方法,由各个版本的子类完成实现,由传入的参数来和子类形成一个映射关系。这样我增加自己的两个版本,只需要增加两个子类即可,每个版本的逻辑也清晰可见,减少了排查的难度。下面我也来展示一个简化版本根据的demo,方便大家理解的。
客户端
public class Client {
public static void main(String[] args) {
AbstractClass instance1 = new ConcreteClass1();
instance1.templateMethod();
AbstractClass instance2 = new ConcreteClass2();instance2.templateMethod();
}
}
// 定义抽象类
abstract class AbstractClass {
// 声明为final,避免子类重写模板方法
public final void templateMethod() {
// 调用基本方法
operation1();
abstractMethod1();
operation2();
abstractMethod2();
}
// 基本方法
public void operation1() {
System.out.println(“执行操作1”);
}
public void operation2() {System.out.println("执行操作2");
}// 抽象方法,需要子类实现
public abstract void abstractMethod1();public abstract void abstractMethod2();
}
// 定义具体实现类1
class ConcreteClass1 extends AbstractClass {
@Override
public void abstractMethod1() {
System.out.println(“实现类1,重写抽象方法1”);
}
@Override
public void abstractMethod2() {System.out.println("实现类1,重写抽象方法2");
}
}
// 定义具体实现类2
class ConcreteClass2 extends AbstractClass {
@Override
public void abstractMethod1() {
System.out.println(“实现类2,重写抽象方法1”);
}
@Override
public void abstractMethod2() {System.out.println("实现类2,重写抽象方法2");
}
}
(三)注意事项
以上就是我用设计模式解决的两个工作问题,那么在在工作中,如何有效利用设计模式帮我们解决问题呢?我觉得主要有以下几点:
1.理解业务需求:在开始编码之前,深入了解业务需求是非常重要的。这将帮助我们确定哪些设计模式最适合当前的问题。
2.识别问题:在开发过程中,时刻关注代码中可能出现的重复、冗余或难以维护的部分。这些问题通常是需要应用设计模式的候选者。
3.选择适当的设计模式:根据识别到的问题,拟合设计模式的解决方式,在脑子中模拟改写后的业务代码,大致逻辑通顺后就可以尝试改写了。有的一直设计模式可能还不好解决,那就要先拆解一部分,分批解决,因为工程是有时间、成本要求的,不可能一直等我们苦思冥想和尝试。而且也不要试图一次性将所有代码都改造成使用设计模式。相反,应该逐步改进代码,逐步引入设计模式。这样可以确保代码始终保持在一个稳定且可维护的状态。
4.学习和研究:不断学习新的设计模式,研究它们是如何解决特定问题的。这可以通过阅读书籍、在线教程、博客文章和开源代码库来实现。这样可以让我们脑子里有个设计模式的概念,尽快的能拟合业务场景找到合适的设计模式,这样才保证能在工作中用起来。
5.注意事项:设计模式并不是银弹,我们应该根据具体情况和需求进行选择和调整。不要盲目追求使用设计模式,而是要在理解它们的优缺点的基础上做出决策。
下面我附一下常用设计模式的定义,方便根据定义来映射场景:
设计模式主要分为三类:创建型模式、结构型模式和行为型模式。
1.创建型模式(Creational Patterns)
- 单例模式(Singleton Pattern):确保一个类只有一个实例,并提供一个全局访问点。
- 工厂模式(Factory Pattern):定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
- 抽象工厂模式(Abstract Factory Pattern):提供一个接口,用于创建相关或依赖对象的家族,而不需要指定它们具体的类。
- 建造者模式(Builder Pattern):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
- 原型模式(Prototype Pattern):用原型实例指定创建对象的种类,并且通过拷贝这个原型来创建新的对象。
2.结构型模式(Structural Patterns) - 适配器模式(Adapter Pattern):将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
- 桥接模式(Bridge Pattern):将抽象部分与它的实现部分分离,使它们都可以独立地变化。
- 组合模式(Composite Pattern):将对象组合成树形结构以表示“部分整体”的层次结构。组合模式使得用户对单个对象和复合对象的使用具有一致性。
- 装饰器模式(Decorator Pattern):动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。
- 外观模式(Facade Pattern):为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
- 享元模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度的对象。
3.行为型模式(Behavioral Patterns) - 模板方法模式(Template Method Pattern):定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
- 策略模式(Strategy Pattern):定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。策略模式使得算法可独立于使用它的客户。
- 观察者模式(Observer Pattern):定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,它的所有依赖者都会自动收到通知并更新。
- 迭代器模式(Iterator Pattern):提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。
- 责任链模式(Chain of Responsibility Pattern):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
- 命令模式(Command Pattern):将一个请求封装为一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,以及支持可撤销的操作。
- 备忘录模式(Memento Pattern):在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。以后可将该对象恢复到原先保存的状态。
- 状态模式(State Pattern):允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
- 访问者模式(Visitor Pattern):表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各类的结构的情况下定义新的操作。
- 中介者模式(Mediator Pattern):用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
- 解释器模式(Interpreter Pattern):给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
三、扩展阅读
上述的主要是在代码层面的设计模式,还有一些分类标准有一些设计模式也可以了解下,例如架构模式中的以下设计模式:
- 分层模式
- 客户端-服务器模式
- 主从模式
- 管道-过滤器模式
- 代理模式
- 对等模式
- 事件总线模式
- 模型-视图-控制器模式
- 黑板模式
- 解释器模式
- 事件驱动架构
- 微内核架构
- 微服务架构
- 基于空间的架构
并发编程领域的Thread-Per-Message模式、Future模式、MapReduce模式、任务并行模式、数据并行模式、Reactor模式、Proactor模式、Actor模型、生产者-消费者模式等,并行编程中的设计模式主要是为了解决在并行计算环境中遇到的各种问题和挑战。由于并行编程涉及多个处理器或线程同时执行代码,因此需要特别关注线程间的同步、通信、数据共享和冲突避免等问题。需要注意的是,不同的模式在不同的场景下可能具有不同的优势和适用性,因此需要根据实际情况进行选择。
相关资料:
Mark Richards 写的《软件架构:架构模式、特征及实践指南》
《软件系统架构师教程》
《Java异步编程实战》
《微服务设计模式和最佳实践》
相关文章:
设计模式浅析
一、设计模式的使用场景 设计模式(Design Patterns)是在软件开发中经过验证的最佳实践,用于解决常见的设计问题。它们提供了一种可复用的解决方案,可以帮助开发人员提高代码质量、可维护性和可重用性。设计模式的采用通常在以下情…...
Linux环境中的git
目录 1.要使用git,首先要安装git 2.首次使用git需要做的操作 3.git操作 1.要使用git,首先要安装git 指令:sudo yum install -y git 2.首次使用git需要做的操作 在gitee网页,在你的仓库中找到: 先将下面两行代码分别…...
单测的思路
文章目录 单测的定义方法的单测几种生成工具的对比生成步骤 接口的单测场景的单测总结参考 单测的定义 单元测试(Unit Testing)是一种软件开发中的测试方法,它的主要目的是确保软件中的最小可测试单元(通常是函数、方法或类&…...
Linux内核与驱动面试经典“小”问题集锦(6)
接前一篇文章:Linux内核与驱动面试经典“小”问题集锦(5) 问题8 问:如何判断一个数是否是2的幂次(假设最多32位)? 备注:此问题是笔者年前参加小米面试时遇到的一个问题,…...
【zabbix】(四)-钉钉告警企业微信配置
前提条件: 已经安装了Python3环境(脚本需要requests模块)。Centos7.x自带Python2(不含requests模块) 钉钉告警配置 一 安装Python3 参考该优秀文档部署 查看Python的模块:pip list / pip3 list 报错 …...
python-自动化篇-办公-一键将word中的表格提取到excel文件中
文章目录 代码 工作中,经常需要将Word文档中的表格粘贴到Excel文件中,以便汇总及分析。一个一个复制粘贴,非常不方便,还是Python自动化操作,省心省力。要求如下图所示,即将word中的所有表格,转存…...
C#,数值计算,矩阵的行列式(Determinant)、伴随矩阵(Adjoint)与逆矩阵(Inverse)的算法与源代码
本文发布矩阵(Matrix)的一些初级算法。 一、矩阵的行列式(Determinant) 矩阵行列式是指矩阵的全部元素构成的行列式,设A(a)是数域P上的一个n阶矩阵,则所有A(a)中的元素组成的行列式称为矩阵A的行列式&…...
人工智能|推荐系统——基于tensorflow的个性化电影推荐系统实战(有前端)
代码下载: 基于tensorflow的个性化电影推荐系统实战(有前端).zip资源-CSDN文库 项目简介: dl_re_web : Web 项目的文件夹re_sys: Web app model:百度云下载之后,把model放到该文件夹下recommend: 网络模型相…...
Hive SQL编译成MapReduce任务的过程
目录 一、架构及组件介绍 1.1 Hive底层架构 1.2 Hive组件 1.3 Hive与Hadoop交互过程 二、Hive SQL 编译成MR任务的流程 2.1 HQL转换为MR源码整体流程介绍 2.2 程序入口—CliDriver 2.3 HQL编译成MR任务的详细过程—Driver 2.3.1 将HQL语句转换成AST抽象语法树 词法、语…...
【C++】快速上手map、multimap、set、multiset
文章目录 一、前言二、set / multiset1. 常见应用2. 核心操作 三、map / multimap1. 常见应用2. 核心操作 一、前言 S T L STL STL 中的关联式容器分为树型结构和哈希结构,树型结构主要有四种: s e t set set、 m u l t i s e t multiset multiset、 m a…...
【分享】图解ADS+JLINK调试ARM
文章是对LPC2148而写的,但是对三星的44B0芯片同样适用,只需要在选择时将相应的CPU选择的S3C44B0就可以了。 JLINK在ADS下调试心得 前两天一个客户用jlink在ADS下调试LPC2148总报错,这个错误我之前在调试LPC2200的时候也碰到过,后…...
反无人机系统技术分析,无人机反制技术理论基础,无人机技术详解
近年来,经过大疆、parrot、3d robotics等公司不断的努力,具有强大功能的消费级无人机价格不断降低,操作简便性不断提高,无人机正快速地从尖端的军用设备转入大众市场,成为普通民众手中的玩具。 然而,随着消…...
Kotlin和Java 单例模式
Java 和Kotlin的单例模式其实很像,只是Kotlin一部分单例可以用对象类和委托lazy来实现 Java /*** 懒汉式,线程不安全*/ class Singleton {private static Singleton instance;private Singleton() {}public static Singleton getInstance() {if (insta…...
软考 系统分析师系列知识点之信息系统战略规划方法(9)
接前一篇文章:软考 系统分析师系列知识点之信息系统战略规划方法(8) 所属章节: 第7章. 企业信息化战略与实施 第4节. 信息系统战略规划方法 7.4.5 信息工程方法 信息工程(Information Engineering,IE&…...
政安晨:示例演绎TensorFlow的官方指南(一){基础知识}
为什么要示例演绎? 既然有了官方指南,咱们在官方指南上看看就可以了,为什么还要写示例演绎的文章呢? 其实对于初步了解TensorFlow的小伙伴们而言,示例演绎才是最重要的。 官方文档已经假定了您已经具备了相当合适的…...
node - 与数据库交互
在Web开发中,与数据库交互是常见的需求,用于持久化存储、检索和操作数据。不同的后端技术和数据库类型(如关系型数据库和非关系型数据库)有着不同的交互方式。下面介绍几种常见的数据库交互方法。 关系型数据库 关系型数据库(如MySQL、PostgreSQL、SQLite)使用结构化查…...
速盾:2024年cdn在5g时代重要吗
在2024年,随着5G技术的普及与应用,内容分发网络(Content Delivery Network,CDN)在数字化时代中的重要性将进一步巩固和扩大。CDN是一种用于快速、高效地分发网络内容的基础设施,它通过将内容部署在全球各地…...
微信小程序(四十一)wechat-http的使用
注释很详细,直接上代码 上一篇 新增内容: 1.模块下载 2.模块的使用 在终端输入npm install wechat-http 没有安装成功vue的先看之前的一篇 微信小程序(二十)Vant组件库的配置- 如果按以上的成功配置出现如下报错先输入以下语句 …...
所有设计模式大全及学习链接
文章目录 创建型设计模式结构型设计模式行为型设计模式 创建型设计模式 一种创建对象的设计模式,它们提供了一种灵活的方式来创建对象,同时隐藏了对象的创建细节。以下是常见的创建型设计模式: 工厂方法模式(Factory Method Patte…...
【Java程序设计】【C00264】基于Springboot的原创歌曲分享平台(有论文)
基于Springboot的原创歌曲分享平台(有论文) 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的原创歌曲分享平台 本系统分为平台功能模块、管理员功能模块以及用户功能模块。 平台功能模块:在平台首页可以查看首…...
2024年,要特别注意这两个方位
家居风水对每个家庭都非常重要,可在无形中影响到人们的事业、财富以及健康运势。俗话说:“风水轮流转”,2024年为甲辰龙年,斗转星移、九宫飞星将改变宫位,新一年的磁场即将启动,方位的吉凶也会重新变动&…...
【Chrono Engine学习总结】5-sensor-5.1-sensor基础并创建一个lidar
由于Chrono的官方教程在一些细节方面解释的并不清楚,自己做了一些尝试,做学习总结。 1、Sensor模块 Sensor模块是附加模块,需要单独安装。参考:【Chrono Engine学习总结】1-安装配置与程序运行 Sensor Module Tutorial Sensor …...
springboot/ssm学生信息管理系统Java学生在线选课考试管理系统
springboot/ssm学生信息管理系统Java学生在线选课考试管理系统 开发语言:Java 框架:springboot(可改ssm) vue JDK版本:JDK1.8(或11) 服务器:tomcat 数据库:mysql 5.…...
three.js 箭头ArrowHelper的实践应用
效果: 代码: <template><div><el-container><el-main><div class"box-card-left"><div id"threejs" style"border: 1px solid red"></div></div></el-main></…...
力扣hot2--哈希
推荐博客: for(auto i : v)遍历容器元素_for auto 遍历-CSDN博客 字母异位词都有一个特点:也就是对这个词排序之后结果会相同。所以将排序之后的string作为key,将排序之后能变成key的单词组vector<string>作为value。 class Solution …...
【正在更新】从零开始认识语音识别:DNN-HMM混合系统语音识别(ASR)原理
摘要 | Abstract 这是一篇对语音识别中的一种热门技术——DNN-HMM混合系统原理的透彻介绍。本文自2月10日开始撰写,计划一星期内写完。 1.前言 | Introduction 近期想深入了解语音识别(ASR)中隐马尔可夫模型(HMM)和深度神经网络-隐马尔可夫(DNN-HMM)混合模型&#…...
thinkphp+vue企业产品展示网站f7enu
本文首先介绍了企业产品展示网站管理技术的发展背景与发展现状,然后遵循软件常规开发流程,首先针对系统选取适用的语言和开发平台,根据需求分析制定模块并设计数据库结构,再根据系统总体功能模块的设计绘制系统的功能模块图&#…...
在Ubuntu22.04上部署ComfyUI
ComfyUI 是 一个基于节点流程的 Stable Diffusion 操作界面,可以通过流程,实现了更加精准的工作流定制和完善的可复现性。每一个模块都有特定的的功能,我们可以通过调整模块连接达到不同的出图效果,特点如下: 1.对显存…...
Springboot+vue的社区养老服务平台(有报告)。Javaee项目,springboot vue前后端分离项目
演示视频: Springbootvue的社区养老服务平台(有报告)。Javaee项目,springboot vue前后端分离项目 项目介绍: 本文设计了一个基于Springbootvue的前后端分离的社区养老服务平台,采用M(model&…...
计算机设计大赛 深度学习+opencv+python实现车道线检测 - 自动驾驶
文章目录 0 前言1 课题背景2 实现效果3 卷积神经网络3.1卷积层3.2 池化层3.3 激活函数:3.4 全连接层3.5 使用tensorflow中keras模块实现卷积神经网络 4 YOLOV56 数据集处理7 模型训练8 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 &am…...
机器学习2---逻辑回归(基础准备)
逻辑回归是基于线性回归是直线分的也可以做多分类 ## 数学基础 import numpy as np np.pi # 三角函数 np.sin() np.cos() np.tan() # 指数 y3**x # 对数 np.log10(10) np.log2(2) np.e np.log(np.e) #ln(e)# 对数运算 # log(AB) log(A) logB np.log(3*4)np.log(3)np.log(4) #…...
JVM体系
JVM是一种虚拟的计算机,它模拟了一个完整的硬件系统,并运行在一个完全隔离的环境中。这意味着JVM可以看作是一个在操作系统之上的计算机系统,与VMware、Virtual Box等虚拟机类似。JVM的设计目标是提供一个安全、可靠、高效且跨平台的运行环境…...
.NET命令行(CLI)常用命令
本文用于记录了.NET软件开发全生命周期各阶段常用的一些CLI命令,用于开发速查。 .NET命令行(CLI)常用命令 项目创建(1)查看本机SDK(2)查看本机可以使用的.NET版本(3)生成…...
六、Redis之数据持久化及高频面试题
6.1 数据持久化 官网文档地址:https://redis.io/docs/manual/persistence/ Redis提供了主要提供了 2 种不同形式的持久化方式: RDB(Redis数据库):RDB 持久性以指定的时间间隔执行数据集的时间点快照。AOF࿰…...
爬虫——ajax和selenuim总结
为什么要写这个博客呢,这个代码前面其实都有,就是结束了。明天搞个qq登录,这个就结束了。 当然也会更新小说爬取,和百度翻译,百度小姐姐的爬取,的对比爬取。总结嘛!!!加…...
【Python】单元测试unittest框架
note 使用unittest框架进行单元测试是Python标准库的一部分,提供了编写测试用例、测试套件以及运行测试的能力。测试用例是继承自unittest.TestCase的类。在这个类中,你可以定义一系列的方法来测试不同的行为。每个测试方法都应该以test开头。 文章目录…...
(三十七)大数据实战——Solr服务的部署安装
前言 Solr是一个基于Apache Lucene的开源搜索平台,它提供了强大的全文搜索、分布式搜索和数据分析功能。Solr 可以用于构建高性能的搜索应用程序,支持从海量数据中快速检索和分析信息。Solr 使用倒排索引和先进的搜索算法,可实现快速而准确的…...
在Ubuntu22.04上部署FoooCUS2.1
Fooocus 是一款基于 Gradio的图像生成软件,Fooocus 是对 Stable Diffusion 和 Midjourney 设计的重新思考: 1、从 Stable Diffusion 学习,该软件是离线的、开源的和免费的。 2、从 Midjourney 中学到,不需要手动调整,…...
详解C语言中的野指针和assert断言
目录 1.野指针1.1 野指针成因1.1.1 指针未初始化1.1.2 指针越界访问1.1.3 指针指向的空间释放 1.2 如何规避野指针1.2.1 指针初始化1.2.2 小心指针越界1.2.3 指针变量不再使用时,及时置为NULL,指针使用之前检查1.2.4 避免返回局部变量的地址 2.assert断言…...
Vue源码系列讲解——模板编译篇【四】(文本解析器)
1. 前言 在上篇文章中我们说了,当HTML解析器解析到文本内容时会调用4个钩子函数中的chars函数来创建文本型的AST节点,并且也说了在chars函数中会根据文本内容是否包含变量再细分为创建含有变量的AST节点和不包含变量的AST节点,如下ÿ…...
微信小程序开发学习笔记《17》uni-app框架-tabBar
微信小程序开发学习笔记《17》uni-app框架-tabBar 博主正在学习微信小程序开发,希望记录自己学习过程同时与广大网友共同学习讨论。建议仔细阅读uni-app对应官方文档 一、创建tabBar分支 运行如下的命令,基于master分支在本地创建tabBar子分支&#x…...
《区块链公链数据分析简易速速上手小册》第5章:高级数据分析技术(2024 最新版)
文章目录 5.1 跨链交易分析5.1.1 基础知识5.1.2 重点案例:分析以太坊到 BSC 的跨链交易理论步骤和工具准备Python 代码示例构思步骤1: 设置环境和获取合约信息步骤2: 分析以太坊上的锁定交易步骤3: 跟踪BSC上的铸币交易 结论 5.1.3 拓展案例 1:使用 Pyth…...
【芯片设计- RTL 数字逻辑设计入门 15 -- 函数实现数据大小端转换】
文章目录 函数实现数据大小端转换函数语法函数使用的规则Verilog and Testbench综合图VCS 仿真波形 函数实现数据大小端转换 在数字芯片设计中,经常把实现特定功能的模块编写成函数,在需要的时候再在主模块中调用,以提高代码的复用性和提高设…...
Codeforces Round 925 (Div. 3) D. Divisible Pairs (Java)
Codeforces Round 925 (Div. 3) D. Divisible Pairs (Java) 比赛链接:Codeforces Round 925 (Div. 3) D题传送门:D.Divisible Pairs 题目:D.Divisible Pairs 题目描述 输出格式 For each test case, output a single integer — the num…...
【C语言】实现单链表
目录 (一)头文件 (二)功能实现 (1)打印单链表 (2)头插与头删 (3)尾插与尾删 (4) 删除指定位置节点 和 删除指定位置之后的节点 …...
Hive调优——合并小文件
目录 一、小文件产生的原因 二、小文件的危害 三、小文件的解决方案 3.1 小文件的预防 3.1.1 减少Map数量 3.1.2 减少Reduce的数量 3.2 已存在的小文件合并 3.2.1 方式一:insert overwrite (推荐) 3.2.2 方式二:concatenate 3.2.3 方式三ÿ…...
设计模式(行为型模式)责任链模式
目录 一、简介二、责任链模式2.1、处理器接口2.2、具体处理器类2.3、使用 三、优点与缺点 一、简介 责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,允许你将请求沿着处理者链进行传递,直到有一个处理者能够处理…...
HTTP和HTTPS区别!
http 是我们几乎天天都要打交道的东西,相关知识点有点多,所以也有不少面试必问的点,这里做了一些整理,帮且大家树立完整的 http 知识体系,对面试官说 so easy HTTP 的特点和缺点 特点:无连接、无状态、灵…...
麻将普通胡牌算法(带混)
最近在玩腾讯的麻将游戏,但是经常需要充值,于是就想自己实现一个简单的单机麻将游戏.第一个难点就是实现胡牌的判断.这里写一下心得. 术语 本文的胡牌是指手牌构成了3N2的牌型,即一对做将,剩下的牌均为刻子(3张一样的牌)或者顺子(3张连续的牌比如234饼). 下面就是一个14张牌…...
Rust结构体详解:定义、使用及方法
Rust 是一门强调安全性和性能的系统级编程语言,它引入了结构体(struct)作为一种自定义的数据类型,允许程序员以更加灵活的方式组织和操作数据。在本篇博客中,我们将深入探讨 Rust 结构体的定义、使用以及相关概念。 什…...