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

【设计模式——学习笔记】23种设计模式——适配器模式Adapter(原理讲解+应用场景介绍+案例介绍+Java代码实现)

文章目录

  • 介绍
    • 生活中的案例
    • 基础介绍
    • 工作原理
    • 分类
    • 应用场景
  • 案例
    • 类适配器模式
      • 例1
        • 介绍
        • 类图
        • 代码实现
        • 优缺点分析
      • 例2
        • 类图
        • 代码实现
    • 对象适配器模式(常用方式)
      • 例1
        • 介绍
        • 类图
        • 代码实现
        • 优缺点分析
      • 例2
        • 代码实现
    • 接口适配器模式
      • 介绍
      • 类图
      • 代码实现
  • 登场角色
  • 类图
    • 类适配器模式
    • 对象适配器模式
  • 适配器模式在SpringMvc中的应用
    • 类图
    • 模拟实现
    • 分析
  • 总结
  • 文章说明

介绍

生活中的案例

不同国家的插座不同,出国旅游充电器不能直接使用,可以通过使用多功能转换插头来辅助使用

基础介绍

  • 适配器模式将某个类的接口转换成客户端期望的另一个接口表示,主的目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作。其别名为包装器(Wrapper)

    适配器模式属于结构型模式(没有产生什么新对象,只是结构的一些调整,让类与类之间可以协调工作)

工作原理

  • 将一个类的接口转换成另一种接口,目的是让原本接口不兼容的类可以兼容
  • 从用户的角度看不到被适配者(A调用B,中间有个adpater,B属于被适配者),是解耦的
  • 用户调用适配器转化出来的目标接口方法,适配器再调用被适配者的相关接口方法
  • 用户收到反馈结果,感觉只是和目标接口交互

在这里插入图片描述

分类

  • 类适配器模式
  • 对象适配器模式
  • 接口适配器模式

应用场景

很多时候,我们加入项目组的时候,项目已经有一定的代码量了,或者部分代码已经在生产环境上面使用了,这些方法已经经过测试,在我们开发新的项目时,可以将这些类作为组件重复利用,但是可能没办法直接调用,需要我们使用适配器模式来让这些方法适配我们的现有项目。

疑问:直接修改之前的类不就可以了吗,为啥要使用适配器模式?答:之前的类都比较完善了,如果在上面改乱了,出了bug不好调试,但是如果使用了适配器模式,那出了bug就知道是适配器的问题。此外,在Adapter模式中,并非一定需要现成的代码。只要知道现有类的功能,就可以编写出新的类。

适配器模式还能用于做新旧版本的兼容,可以让新版本扮演Adaptee 角色,旧版本扮演Target角色。接着编写一个扮演Adapter 角色的类,让它使用新版本的类来实现旧版本的类中的方法。如下图

在这里插入图片描述

案例

类适配器模式

例1

介绍

  • Adapter类,通过继承src类,实现 dst 类接口,完成src->dst的适配
  • 如生活中的小例子:充电器本身相当于Adapter,220V交流电相当于src(即被适配者),我们的dst(即目标)是5V直流电

类图

在这里插入图片描述

代码实现

【被适配的类】

package com.atguigu.adapter.classadapter;/*** 被适配的类*/
public class Voltage220V {/*** 输出220V的电压* @return*/public int output220V() {int src = 220;System.out.println("电压=" + src + "伏");return src;}
}

适配接口

package com.atguigu.adapter.classadapter;/*** 适配接口*/
public interface IVoltage5V {public int output5V();
}

【适配器】

package com.atguigu.adapter.classadapter;/*** 适配器类 将220V转化为5V*/
public class VoltageAdapter extends Voltage220V implements IVoltage5V {@Overridepublic int output5V() {//获取到220V电压int srcV = output220V();//转成 5v(降压)int dstV = srcV / 44 ;return dstV;}}

【手机类】

package com.atguigu.adapter.classadapter;public class Phone {/*** 手机充电方法* @param iVoltage5V*/public void charging(IVoltage5V iVoltage5V) {if(iVoltage5V.output5V() == 5) {System.out.println("电压为5V, 可以充电~~");} else if (iVoltage5V.output5V() > 5) {System.out.println("电压过高, 不能充电~~");}}
}

【客户端:用户给手机充电】

package com.atguigu.adapter.classadapter;public class Client {public static void main(String[] args) {System.out.println(" === 类适配器模式 ====");Phone phone = new Phone();phone.charging(new VoltageAdapter());}}

【运行】

 === 类适配器模式 ====
电压=220伏
电压为5V, 可以充电~~Process finished with exit code 0

优缺点分析

【优点】

  • 由于其继承了src类,所以它可以根据需求重写src类的方法,使得Adapter的灵活性增强了

【缺点】

  • Java是单继承机制,所以类适配器需要继承src类这一点算是一个缺点(之前的七大原则分析过,使用继承不好),因为这要求dst必须是接口,有一定局限性
  • src类的方法在Adapter中都会暴露出来,也增加了使用的成本(如果方法很多,调用起来就麻烦了)

例2

类图

在这里插入图片描述

代码实现

【src】

package com.atguigu.adapter.Sample1;public class Banner {private String string;public Banner(String string) {this.string = string;}public void showWithParen() {System.out.println("(" + string + ")");}public void showWithAster() {System.out.println("*" + string + "*");}
}

【dst】

package com.atguigu.adapter.Sample1;public interface Print {public abstract void printWeak();public abstract void printStrong();
}

【适配器】

package com.atguigu.adapter.Sample1;public class PrintBanner extends Banner implements Print {public PrintBanner(String string) {super(string);}public void printWeak() {showWithParen();}public void printStrong() {showWithAster();}
}

【客户端】

package com.atguigu.adapter.Sample1;public class Main {public static void main(String[] args) {Print p = new PrintBanner("Hello");p.printWeak();p.printStrong();}
}

【运行】

(Hello)
*Hello*Process finished with exit code 0

【分析】

对Main类的代码而言,Banner类、showWithParen方法和showWithAster 方法被完全隐藏起来了。这就好像笔记本电脑只要在直流12伏特电压下就能正常工作,但它并不知道这12伏特的电压是由适配器将100伏特交流电压转换而成的。Main类并不知道PrintBanner类是如何实现的,这样就可以在不用对Main类进行修改的情况下改变PrintBanner类的具体实现。

对象适配器模式(常用方式)

例1

介绍

  • 基本思路和类的适配器模式相同,只是将Adapter类作修改,不是继承src类,而是持有src类的实例(聚合src类),以解决兼容性的问题。 即:持有 src类,实现 dst 类接口,完成src->dst的适配
  • 根据“合成复用原则”,在系统中尽量使用关联关系来替代继承关系
  • 对象适配器模式是适配器模式常用的一种

类图

在这里插入图片描述

代码实现

【适配器类】

package com.atguigu.adapter.objectadapter;/*** 适配器类*/
public class VoltageAdapter implements IVoltage5V {/*** 关联关系-聚合*/private Voltage220V voltage220V;/*** 通过构造器,传入一个 Voltage220V 实例** @param voltage220v*/public VoltageAdapter(Voltage220V voltage220v) {this.voltage220V = voltage220v;}@Overridepublic int output5V() {int dst = 0;if (null != voltage220V) {//获取220V 电压int src = voltage220V.output220V();System.out.println("使用对象适配器,进行适配~~");dst = src / 44;System.out.println("适配完成,输出的电压为=" + dst);}return dst;}}

【客户端:用户给手机充电】

package com.atguigu.adapter.objectadapter;public class Client {public static void main(String[] args) {// TODO Auto-generated method stubSystem.out.println(" === 对象适配器模式 ====");Phone phone = new Phone();phone.charging(new VoltageAdapter(new Voltage220V()));}}

其他类和类适配器模式的一致

优缺点分析

【优点】

  • 对象适配器和类适配器其实算是同一种思想,只不过实现方式不同。根据合成复用原则,使用组合替代继承,所以它解决了类适配器必须继承src的局限性问题,也不再要求dst必须是接口
  • 使用成本更低,更灵活

例2

代码实现

【dst】

package com.atguigu.adapter.Sample2;public abstract class Print {public abstract void printWeak();public abstract void printStrong();
}

【适配器】

package com.atguigu.adapter.Sample2;public class PrintBanner extends Print {private Banner banner;public PrintBanner(String string) {this.banner = new Banner(string);}public void printWeak() {banner.showWithParen();}public void printStrong() {banner.showWithAster();}
}

其他两个类的和类适配器模式的例2的代码一致

接口适配器模式

介绍

  • 一些书籍称为:适配器模式(Default Adapter Pattern)或缺省适配器模式
  • 当不需要全部实现接口提供的方法时,可先设计一个抽象类实现接口,并为该接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求
  • 适用于不想使用一个接口所有的方法的情况

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

类图

在这里插入图片描述

代码实现

【接口】

package com.atguigu.adapter.interfaceadapter;public interface Interface4 {public void m1();public void m2();public void m3();public void m4();
}

【抽象类:适配器】

package com.atguigu.adapter.interfaceadapter;/*** 在AbsAdapter 我们将 Interface4 的方法进行默认实现(空实现)*/
public abstract class AbsAdapter implements Interface4 {@Overridepublic void m1() {}@Overridepublic void m2() {}@Overridepublic void m3() {}@Overridepublic void m4() {}
}

【客户端:重写抽象类的方法】

package com.atguigu.adapter.interfaceadapter;public class Client {public static void main(String[] args) {AbsAdapter absAdapter = new AbsAdapter() {/*** 只需要去覆盖我们 需要使用 接口方法*/@Overridepublic void m1() {System.out.println("使用了m1的方法");}};absAdapter.m1();}
}

登场角色

  • Target(对象):负责定义所需的方法,如需要能提供5v电压的方法
  • Adaptee(被适配):该角色持有既定方法,如有一个方法可以提供220v电压
  • Adapter(适配):使用Adaptee角色的方法来满足Target角色的需求
  • Client(请求者):负责使用 Target 角色所定义的方法来做事,如使用5V电压给手机充电

类图

类适配器模式

在这里插入图片描述

对象适配器模式

在这里插入图片描述

适配器模式在SpringMvc中的应用

  • SpringMvc中的HandlerAdapter使用了适配器模式

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

类图

在这里插入图片描述

模拟实现

【Controller】

package com.atguigu.spring.springmvc;/*** 多种Controller实现*/
public interface Controller {}//-----------------针对不同的请求,有多种不同的controller------------------------
class HttpController implements Controller {public void doHttpHandler() {System.out.println("http...");}
}class SimpleController implements Controller {public void doSimplerHandler() {System.out.println("simple...");}
}class AnnotationController implements Controller {public void doAnnotationHandler() {System.out.println("annotation...");}
}

【适配器】

package com.atguigu.spring.springmvc;/*** 定义一个Adapter接口*/
public interface HandlerAdapter {public boolean supports(Object handler);public void handle(Object handler);
}//-------------------多种适配器类-------------------------class SimpleHandlerAdapter implements HandlerAdapter {public void handle(Object handler) {((SimpleController) handler).doSimplerHandler();}/*** 判断是否支持该handler* @param handler* @return*/public boolean supports(Object handler) {return (handler instanceof SimpleController);}}class HttpHandlerAdapter implements HandlerAdapter {public void handle(Object handler) {((HttpController) handler).doHttpHandler();}public boolean supports(Object handler) {return (handler instanceof HttpController);}}class AnnotationHandlerAdapter implements HandlerAdapter {public void handle(Object handler) {((AnnotationController) handler).doAnnotationHandler();}public boolean supports(Object handler) {return (handler instanceof AnnotationController);}}

【servlet】

package com.atguigu.spring.springmvc;import java.util.ArrayList;
import java.util.List;public class DispatchServlet {/*** 组合所有适配器*/public static List<HandlerAdapter> handlerAdapters = new ArrayList<HandlerAdapter>();public DispatchServlet() {handlerAdapters.add(new AnnotationHandlerAdapter());handlerAdapters.add(new HttpHandlerAdapter());handlerAdapters.add(new SimpleHandlerAdapter());}public void doDispatch() {// 此处模拟SpringMVC从request取handler的对象,// 适配器可以获取到希望的ControllerHttpController controller = new HttpController();// AnnotationController controller = new AnnotationController();//SimpleController controller = new SimpleController();// 得到对应适配器HandlerAdapter adapter = getHandler(controller);// 通过适配器执行对应的controller对应方法adapter.handle(controller);}/*** 根据controller返回对应的适配器* @param controller* @return*/public HandlerAdapter getHandler(Controller controller) {//遍历:根据得到的controller(handler), 返回对应适配器for (HandlerAdapter adapter : this.handlerAdapters) {if (adapter.supports(controller)) {return adapter;}}return null;}public static void main(String[] args) {new DispatchServlet().doDispatch(); // http...}}

分析

  • 适配器的价值:controller变化了,适配器也会跟着变化,最终调用的方法也不同
  • 扩展Controller 时,只需要增加一个适配器类就完成了SpringMVC的扩展了
  • 如果不使用适配器:可以看到处理器的类型不同,有多重实现方式,那么调用方式就不是确定的,如果需要直接调用Controller方法,需要调用的时候就得不断是使用if else来进行判断是哪一种子类然后执行。那么如果后面要扩展Controller,就得修改原来的代码,这样违背了OCP原则

在这里插入图片描述

总结

  • 类适配器:以类给到,在Adapter里,就是将src当做类,继承
  • 对象适配器: 以对象给到,在Adapter里,将src作为一个对象,持有(聚合)
  • 接口适配器: 以接口给到,在Adapter里,将src作为一个接口,实现
  • Adapter模式最大的作用是将原本不兼容的接口融合在一起工作
  • 实际开发中,实现起来不拘泥于上述三种经典形式

文章说明

  • 本文章为本人学习尚硅谷的学习笔记,文章中大部分内容来源于尚硅谷视频(点击学习尚硅谷相关课程),也有部分内容来自于自己的思考,发布文章是想帮助其他学习的人更方便地整理自己的笔记或者直接通过文章学习相关知识,如有侵权请联系删除,最后对尚硅谷的优质课程表示感谢。
  • 本人还同步阅读《图解设计模式》书籍(图解设计模式/(日)结城浩著;杨文轩译–北京:人民邮电出版社,2017.1),进而综合两者的内容,让知识点更加全面

相关文章:

【设计模式——学习笔记】23种设计模式——适配器模式Adapter(原理讲解+应用场景介绍+案例介绍+Java代码实现)

文章目录 介绍生活中的案例基础介绍工作原理分类应用场景 案例类适配器模式例1介绍类图代码实现优缺点分析 例2类图代码实现 对象适配器模式&#xff08;常用方式&#xff09;例1介绍类图代码实现优缺点分析 例2代码实现 接口适配器模式介绍类图代码实现 登场角色类图类适配器模…...

Android Unit Test

一、测试基础知识 1.1 测试级别 测试金字塔&#xff08;如图 2 所示&#xff09;说明了应用应如何包含三类测试&#xff08;即小型、中型和大型测试&#xff09;&#xff1a; 小型测试是指单元测试&#xff0c;用于验证应用的行为&#xff0c;一次验证一个类。 中型测试是指…...

docker更新jenkins

下载文件 1、jenkins提示下载 2、官网下载jenkins官网 文件放服务器内 通过工具把jenkins.war放进服务器例如tmp 文件复制到docker的jenkins容器 docker cp 路径文件 容器id:/{后面不接内容为根路径} docker cp /tmp/jenkins.war 53dc1c71058a:/进入容器内 docker exec …...

一种新的基于区域的在线活动轮廓模型研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

【Docker】基于Dockerfile搭建LNMP架构

一、项目环境 公司在实际的生产环境中,需要使用Docker 技术在一台主机上创建LNMP服务并运行Wordpress网站平台。然后对此服务进行相关的性能调优和管理工作。 1. 环境配置 主机操作系统IP地址主要软件DockerCentOS 7.3 x86_64192.168.145.15Docker 19.03容器ip地址规划 ngin…...

爬虫003_pycharm的安装以及使用_以及python脚本模版设置---python工作笔记021

这里我们用ide,pycharm来编码,看一看如何下载 这里我们下载这个社区办,这个是免费的,个人版是收费的 然后勾选以后 安装以后我们来创建一个项目 这里可以选择python的解释器,选择右边的... 这里我们找到我们自己安装的python解释器...

远程xml读取解析,将image url下载到本地,延时队列定时删除文件,图片访问路径保存在数据库中

远程xml部分内容 <imagelist name"FY4A AGRI IMG REGI MTCC GLL" tag"FY4A AGRI IMG REGI MTCC GLL"><image time"2023-07-25 22:30 (UTC)" desc"FY4A AGRI IMG REGI MTCC GLL" url"http://img.nsmc.org.cn/PORTAL/FY4…...

firefox笔记-Centos7离线安装firefox

目前&#xff08;2023-03-22 16:41:35&#xff09;Centos7自带的firefox已经很新了是2020年的。主要原因是有个web项目&#xff0c;用2020年的firefox打不开。 发到互联网上是2023-07-24。 报错是js有问题&#xff0c;估计是搞前端的只做了chrome适应&#xff0c;没做firefox…...

Flutter:滑动面板

前言 无意中发现了这个库&#xff0c;发现现在很多app中都有类似的功能。以手机b站为例&#xff0c;当你在看视频时&#xff0c;点击评论&#xff0c;视频会向上偏移&#xff0c;下方划出评论界面。 sliding_up_panel SlidingUpPanel是一个Flutter插件&#xff0c;用于创建滑…...

RocketMQ概论

目录 前言&#xff1a; 1.概述 2.下载安装、集群搭建 3.消息模型 4.如何保证吞吐量 4.1.消息存储 4.1.1顺序读写 4.1.2.异步刷盘 4.1.3.零拷贝 4.2.网络传输 前言&#xff1a; RocketMQ的代码示例在安装目录下有全套详细demo&#xff0c;所以本文不侧重于讲API这种死…...

任务的创建与删除

Q: 什么是任务&#xff1f; A: 任务可以理解为进程/线程&#xff0c;创建一个任务&#xff0c;就会在内存开辟一个空间。 比如&#xff1a; 玩游戏&#xff0c;打篮球&#xff0c;开车&#xff0c;都可以视为任务。 Windows 系统中的 MarkText 、谷歌浏览器、记事本&#xff0…...

致敬图灵!HashData拥抱数据智能新时代!

图1&#xff1a;2023ACM中国图灵大会现场 生于1912年的艾伦图灵被称为“计算机科学之父”、“人工智能之父”。1966年&#xff0c;国际计算机协会&#xff08;ACM&#xff09;为了纪念这位卓越的科学家&#xff0c;设立了以其名字命名的ACM图灵奖&#xff0c;以表彰在计算机领…...

AD21原理图的高级应用(二)层次原理图设计

&#xff08;二&#xff09;层次原理图设计 1.层次原理图概述2.层次化原理图的应用2.1 自上而下的层次化原理图2.2 自下而上的层次化原理图 3.生成层次设计表 对于大规模的电路系统,需要将其按功能分解为若干个电路模块,用户可以单独绘制好各个功能模块,再将它们组合起来继续处…...

ROS中使用RealSense-D435

文章目录 D435简介RealSense的SDK2.0安装方法1&#xff1a;直接利用安装源安装注册服务器公匙将服务器添加到存储库列表安装库 方法2&#xff1a;利用源码安装GitHub下载librealsense安装编译依赖运行脚本cmake编译 软件显示 ROS接口安装启动节点查看话题rviz显示点云 Python接…...

nlp系列(6)文本实体识别(Bi-LSTM+CRF)pytorch

模型介绍 LSTM&#xff1a;长短期记忆网络&#xff08;Long-short-term-memory&#xff09;,能够记住长句子的前后信息&#xff0c;解决了RNN的问题&#xff08;时间间隔较大时&#xff0c;网络对前面的信息会遗忘&#xff0c;从而出现梯度消失问题&#xff0c;会形成长期依赖…...

zookeeper-3.7.1集群

1.下载&解压安装包apache-zookeeper-3.7.1-bin.tar.gz 解压到/app/ &改名zookeeper-3.7.1 [rootnode1 app]# tar -zxvf apache-zookeeper-3.7.1-bin.tar.gz -C /app/ [rootnode1 app]# mv apache-zookeeper-3.7.1-bin zookeeper-3.7.1 ---- 删除docs [rootnode1…...

ubuntu上安装firefox geckodriver 实现爬虫

缘由&#xff1a;当时在windows 上运行chrom 的时候 发现要找到 浏览器和 webdirver 相匹配的 版本比较麻烦&#xff0c;当时搞了大半天才找到并安装好。 这次在ubuntu上尝试用firefox 实现爬虫 文章分为三个部分&#xff1a; 环境搭建浏览器弹窗输入用户名&#xff0c;密码的…...

【Matlab】基于长短期记忆网络的时间序列预测(Excel可直接替换数据)

【Matlab】基于长短期记忆网络的时间序列预测(Excel可直接替换数据) 1.模型原理2.数学公式3.文件结构4.Excel数据5.分块代码6.完整代码7.运行结果1.模型原理 "基于长短期记忆网络(Long Short-Term Memory, LSTM)的时间序列预测"是一种使用LSTM神经网络来预测时间…...

[NLP]LLM高效微调(PEFT)--LoRA

LoRA 背景 神经网络包含很多全连接层&#xff0c;其借助于矩阵乘法得以实现&#xff0c;然而&#xff0c;很多全连接层的权重矩阵都是满秩的。当针对特定任务进行微调后&#xff0c;模型中权重矩阵其实具有很低的本征秩&#xff08;intrinsic rank&#xff09;&#xff0c;因…...

vue3 vant上传图片

在 Vue 3 中使用 Vant 组件库进行图片上传&#xff0c;您可以使用 Vant 的 ImageUploader 组件。ImageUploader 是 Vant 提供的图片上传组件&#xff0c;可以方便地实现图片上传功能。 以下是一个简单的示例&#xff0c;演示如何在 Vue 3 中使用 Vant 的 ImageUploader 组件进行…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验

系列回顾&#xff1a; 在上一篇中&#xff0c;我们成功地为应用集成了数据库&#xff0c;并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了&#xff01;但是&#xff0c;如果你仔细审视那些 API&#xff0c;会发现它们还很“粗糙”&#xff1a;有…...

Mac下Android Studio扫描根目录卡死问题记录

环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中&#xff0c;提示一个依赖外部头文件的cpp源文件需要同步&#xff0c;点…...

均衡后的SNRSINR

本文主要摘自参考文献中的前两篇&#xff0c;相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程&#xff0c;其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt​ 根发送天线&#xff0c; n r n_r nr​ 根接收天线的 MIMO 系…...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)

RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发&#xff0c;后来由Pivotal Software Inc.&#xff08;现为VMware子公司&#xff09;接管。RabbitMQ 是一个开源的消息代理和队列服务器&#xff0c;用 Erlang 语言编写。广泛应用于各种分布…...

【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制

使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下&#xff0c;限制某个 IP 的访问频率是非常重要的&#xff0c;可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案&#xff0c;使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

并发编程 - go版

1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程&#xff0c;系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

【网络安全】开源系统getshell漏洞挖掘

审计过程&#xff1a; 在入口文件admin/index.php中&#xff1a; 用户可以通过m,c,a等参数控制加载的文件和方法&#xff0c;在app/system/entrance.php中存在重点代码&#xff1a; 当M_TYPE system并且M_MODULE include时&#xff0c;会设置常量PATH_OWN_FILE为PATH_APP.M_T…...

【Veristand】Veristand环境安装教程-Linux RT / Windows

首先声明&#xff0c;此教程是针对Simulink编译模型并导入Veristand中编写的&#xff0c;同时需要注意的是老用户编译可能用的是Veristand Model Framework&#xff0c;那个是历史版本&#xff0c;且NI不会再维护&#xff0c;新版本编译支持为VeriStand Model Generation Suppo…...