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

015行为型-职责链模式

定义

责链模式是一种设计模式,其目的是使多个对象能够处理同一请求,但是并不知道下一个处理请求的对象是谁。它能够解耦请求的发送者和接收者之间的直接耦合关系。
举个例子,假设你的公司有一个报销流程,需要依次提交给主管、经理和财务部门审核,如果一个人无法审核,那么就需要向下一个人提交审核请求。在这种情况下,职责链模式非常适用。
在职责链模式中,每个处理请求的对象都可以尝试处理请求,如果自己无法处理,则将请求传递给下一个对象,直到有一个对象能够处理请求为止。
职责链模式由以下几个部分组成:

  1. 抽象处理者(Handler):定义一个处理请求的接口,并将请求传递给下一个处理者。
  2. 具体处理者(ConcreteHandler):实现处理请求的接口,并负责处理请求或者将请求传递给下一个处理者。
  3. 客户端(Client):创建处理者对象,并将请求发送给处理者。

通过这种方式,我们可以将处理请求的对象连接成一条链,让每个对象都有机会处理请求,同时又不会知道下一个对象是谁。

标准模式实现:

如果处理器链上的某个处理器能够处理这个请求,那就不会继续往下传递请求。

这段代码是一个使用职责链模式的示例,主要包含以下几个类:

  1. 抽象处理器类 Handler :定义了一个处理器对象的公共接口,并且持有下一个处理器的引用。具体的处理器需要继承自该类并实现其 doHandle() 方法,用于实现处理逻辑。
  2. 具体处理器类 HandlerAHandlerB :继承自 Handler 类,实现了 doHandle() 方法,并且在该方法中输出自己的类名。
  3. 处理器链类 HandlerChain :用于维护处理器链,实现了 addHandler() 方法用于添加处理器,实现了 handle() 方法用于处理请求。
  4. 测试类 HandlerTest :创建了一个处理器链并添加了两个处理器,然后调用 handle() 方法处理请求。

具体的实现过程如下:

  1. 在抽象处理器类 Handler 中定义了一个 handle() 方法,其中先调用 doHandle() 方法来执行实际的处理逻辑,如果返回值为 false,则表示当前处理器不能处理该请求,需要将请求传递给下一个处理器。这里使用了模板方法设计模式。
  2. 在具体处理器类 HandlerAHandlerB 中分别实现了 doHandle() 方法,输出自己的类名,并且将返回值设置为 false
  3. 在处理器链类 HandlerChain 中,定义了一个头部处理器和尾部处理器,以及 addHandler() 方法用于添加处理器。当添加第一个处理器时,同时将头部和尾部处理器设置为该处理器;当添加多个处理器时,将新的处理器设置为尾部处理器的下一个处理器,并将尾部处理器设置为新的处理器。在 handle() 方法中,调用头部处理器的 handle() 方法,从而开始处理请求。
  4. 在测试类 HandlerTest 中,创建了一个处理器链,并添加了 HandlerAHandlerB 处理器。然后调用 handle() 方法处理请求,从而开始执行处理逻辑。在执行过程中,处理器链会将请求传递给每个处理器,直到找到能够处理该请求的处理器为止。在本例中,由于处理器只输出自己的类名,因此实际上并没有进行实际的处理逻辑。
public abstract class Handler {protected Handler successor = null;public void setSuccessor(Handler successor) {this.successor = successor;}/**
* 利用模版方法,抽离公共的逻辑
*/public final void handle() {boolean handled = doHandle();if (successor != null && !handled) {successor.handle();}}/**
* 此处子类实现,填充需要处理的逻辑
* 如果处理器链上的某个处理器能够处理这个请求,那就不会继续往下传递请求
*
* @return
*/protected abstract boolean doHandle();
}public class HandlerA extends Handler {@Overrideprotected boolean doHandle() {boolean handled = false;System.out.println("我是" + this.getClass().getSimpleName());return handled;}
}public class HandlerB extends Handler {@Overrideprotected boolean doHandle() {boolean handled = false;System.out.println("我是" + this.getClass().getSimpleName());return handled;}
}public class HandlerChain {private Handler head = null;private Handler tail = null;public void addHandler(Handler handler) {//将传入的节点下一步设置为nullhandler.setSuccessor(null);if (head == null) {head = handler;tail = handler;return;}//尾部增加节点tail.setSuccessor(handler);tail = handler;}public void handle(){if (head != null) {head.handle();}}
}public class HandlerTest {public static void main(String[] args) {HandlerChain chain = new HandlerChain();chain.addHandler(new HandlerA());chain.addHandler(new HandlerB());chain.handle();}
}

职责链变体

请求会被所有的处理器都处理一遍,不存在中途终止的情况。这种变体也有两种实现方式:用链表存储处理器和用数组存储处理器

使用链表实现


public abstract class Handler {protected Handler successor = null;public void setSuccessor(Handler successor) {this.successor = successor;}public final void handle() {doHandle();if (successor != null) {successor.handle();}}protected abstract void doHandle();
}public class HandlerA extends Handler {@Overrideprotected void doHandle() {System.out.println("我是" + this.getClass().getSimpleName());}
}public class HandlerB extends Handler {@Overrideprotected void doHandle() {System.out.println("我是" + this.getClass().getSimpleName());}
}public class HandlerChain {private Handler head = null;private Handler tail = null;public void addHandler(Handler handler) {handler.setSuccessor(null);if (head == null) {head = handler;tail = handler;return;}tail.setSuccessor(handler);tail = handler;}public void handle() {if (head != null) {head.handle();}}
}// 使用举例
public class Application {public static void main(String[] args) {HandlerChain chain = new HandlerChain();chain.addHandler(new HandlerA());chain.addHandler(new HandlerB());chain.handle();}
}

这段代码和上面的代码实现的是相同的职责链模式,只是实现的方式略有不同。具体区别如下:

  1. 上面的代码中,抽象处理器 Handler 类的 doHandle() 方法返回 boolean 类型,表示是否处理了请求,而这里的代码中,抽象处理器 Handler 类的 doHandle() 方法返回 void 类型,表示无论是否处理请求,都会执行该方法。
  2. 在上面的代码中,处理器链中的处理器如果处理了请求,则不会继续往后传递请求;而在这里的代码中,处理器链中的处理器不管是否处理了请求,都会把请求继续传递给下一个处理器。

总的来说,这两段代码的区别并不大,都是实现职责链模式的有效方式,具体的实现方式可以根据实际情况进行选择。

使用数组实现

public class HandlerChain {private final List<Handler> handlers = new ArrayList<>();public void addHandler(Handler handler) {handlers.add(handler);}public void handle() {for (Handler handler : handlers) {handler.handle();}}
}

这个改进方案的主要变化如下:

  1. 将处理器链的存储方式从链表改为了数组,这样可以更加高效地遍历所有处理器。
  2. 去掉了 tail 指针,因为数组可以直接按照添加的顺序来遍历,不需要链表的指针。
  3. handle() 方法中,直接使用 for 循环来遍历所有处理器,不需要链表中的递归调用。

这种改进方案的优点是代码更加简洁易懂,效率也更高。但是需要注意的是,这种方式只适用于处理器数量不太多的情况,如果处理器数量很大,那么这种方式的效率可能会受到影响,因为数组的大小是固定的,如果处理器数量很大,可能会导致数组空间的浪费。

应用场景

日志输出

当然,这里是一个类似于日志记录框架的职责链模式的例子。假设我们有一个需求,需要在应用程序中使用多个记录器,例如控制台记录器、文件记录器和电子邮件记录器,将日志信息记录在不同的位置,那么我们可以使用职责链模式来实现这个功能。

// Interface for all loggers in the chain
public interface Logger {void log(String message);
}// Logger implementation that writes to console
public class ConsoleLogger implements Logger {@Overridepublic void log(String message) {System.out.println("Console Logger: " + message);}
}// Logger implementation that writes to a file
public class FileLogger implements Logger {@Overridepublic void log(String message) {System.out.println("File Logger: " + message);}
}// Logger implementation that sends an email
public class EmailLogger implements Logger {@Overridepublic void log(String message) {System.out.println("Email Logger: " + message);}
}// The chain that contains all loggers
public class LoggerChain {private List<Logger> loggers = new ArrayList<>();public void addLogger(Logger logger) {this.loggers.add(logger);}public void log(String message) {for (Logger logger : loggers) {logger.log(message);}}
}// Usage example
public class ApplicationDemo {public static void main(String[] args) {LoggerChain loggerChain = new LoggerChain();loggerChain.addLogger(new ConsoleLogger());loggerChain.addLogger(new FileLogger());loggerChain.addLogger(new EmailLogger());loggerChain.log("This is a log message.");}
}

spring过滤器

Spring Boot Servlet 过滤器(Filter):在 Web 应用程序中,可以使用过滤器来对请求进行处理。Spring Boot Servlet 过滤器使用职责链模式来实现多个过滤器的链式调用。在请求处理过程中,过滤器链中的每个过滤器都可以对请求进行处理和修改,过滤器链主要用于拦截 HTTP 请求,并在请求到达处理器之前对其进行预处理,以实现一些共性的处理逻辑,例如权限校验、日志记录、字符编码转换等。

public class CharacterEncodingFilter implements Filter {private String encoding;@Overridepublic void init(FilterConfig filterConfig) throws ServletException {encoding = filterConfig.getInitParameter("encoding");}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {request.setCharacterEncoding(encoding);chain.doFilter(request, response);}@Overridepublic void destroy() {// do nothing}
}

该过滤器的作用是将 HTTP 请求的字符编码设置为指定的编码。它实现了 Filter 接口,并重写了initdoFilterdestroy方法。在doFilter方法中,该过滤器首先将请求的字符编码设置为指定的编码,然后调用 FilterChain 的 doFilter 方法,将请求转发给下一个过滤器。

@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}@Beanpublic FilterRegistrationBean<CharacterEncodingFilter> characterEncodingFilterRegistrationBean() {FilterRegistrationBean<CharacterEncodingFilter> registrationBean = new FilterRegistrationBean<>();registrationBean.setFilter(new CharacterEncodingFilter());registrationBean.addUrlPatterns("/*");registrationBean.addInitParameter("encoding", "UTF-8");registrationBean.setName("characterEncodingFilter");registrationBean.setOrder(1);return registrationBean;}
}

在上面的代码中,我们使用了**@Bean注解来声明一个名为characterEncodingFilterRegistrationBean的 Bean。这个 Bean 是一个FilterRegistrationBean**类型的对象,它用于将 CharacterEncodingFilter 过滤器注册到应用程序中。

characterEncodingFilterRegistrationBean方法中,

  • 我们首先创建一个FilterRegistrationBean对象,并将 CharacterEncodingFilter 过滤器实例作为参数传入。
  • 然后,我们使用addUrlPatterns方法来指定该过滤器所拦截的 URL 模式。在本例中,我们将其设置为拦截所有请求。
  • 接下来,我们使用addInitParameter方法来设置过滤器的初始化参数。
  • 最后,我们使用setName方法来指定该过滤器的名称,使用setOrder方法来指定该过滤器在过滤器链中的顺序。

通过以上的配置,我们就成功地将 CharacterEncodingFilter 过滤器注册到了应用程序中,并将其加入到了过滤器链中。当 HTTP 请求到达应用程序时,Spring Boot 将会按照过滤器链的顺序,依次将请求转发给下一个过滤器,直到请求到达处理器。

spirng 拦截器

Spring MVC 拦截器(HandlerInterceptor):在 Spring MVC 中,可以使用拦截器来拦截请求并在处理请求之前或之后执行一些操作。Spring MVC 拦截器使用职责链模式来实现多个拦截器的链式调用。在请求处理过程中,拦截器链中的每个拦截器都可以对请求进行处理和修改。

public class SecurityInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 检查用户的权限if (!hasPermission(request)) {// 如果没有权限,返回错误信息response.sendError(HttpServletResponse.SC_FORBIDDEN, "Forbidden");return false;}return true;}private boolean hasPermission(HttpServletRequest request) {// 检查用户是否具有执行该请求的权限// ...return true;}
}public class LogInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 记录请求日志logRequest(request);return true;}private void logRequest(HttpServletRequest request) {// 记录请求日志// ...}
}public class InterceptorChainConfigurer implements WebMvcConfigurer {@Autowiredprivate SecurityInterceptor securityInterceptor;@Autowiredprivate LogInterceptor logInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(securityInterceptor);registry.addInterceptor(logInterceptor);}
}

拦截器和过滤器的实现机制中都使用了职责链模式。
在 Spring MVC 中,拦截器是通过 HandlerInterceptor 接口实现的,它的实现类可以在 Spring MVC 的配置文件中配置,并按照顺序组成一个拦截器链。在请求处理过程中,拦截器链中的每个拦截器都可以对请求进行处理和修改,形成一个职责链。
同样,在 Servlet 中,过滤器也是使用职责链模式实现的。在 web.xml 中配置的过滤器会按照顺序形成一个过滤器链,每个过滤器都可以对请求进行处理和修改,形成一个职责链。
因此,拦截器和过滤器的实现机制都借鉴了职责链模式的思想,通过将多个拦截器或过滤器组合成一个链条,实现对请求进行处理和拦截的目的。

在 Spring MVC 中,拦截器和过滤器都是用于对请求进行处理和拦截的组件,但是它们有一些区别:

  1. 拦截器是 Spring MVC 框架提供的组件,而过滤器是 Servlet 规范提供的组件。因此,使用拦截器需要在 Spring MVC 的配置文件中配置拦截器,而使用过滤器需要在 web.xml 中配置过滤器。
  2. 拦截器只能拦截请求,并且只能在请求被分派到具体的处理器(Controller)之前或之后进行处理,它不能修改请求的内容。而过滤器可以拦截请求和响应,它能够修改请求和响应的内容。
  3. 拦截器可以访问 Spring MVC 的上下文(如请求和响应对象、处理器对象等),并可以调用处理器方法。而过滤器只能访问 Servlet 的上下文(如请求和响应对象),它不能调用处理器方法。
  4. 拦截器是基于 AOP 实现的,可以使用 AOP 的特性(如切面、通知等),因此它具有更高的灵活性和可扩展性。而过滤器只能使用 Servlet 规范中定义的特性,它的灵活性和可扩展性相对较低。

mybatis动态sql

MyBatis 使用 SQLNode 接口来表示 SQL 语句的不同部分,例如 WHERE 子句、SET 子句等等。每个 SQLNode 对象都包含一个 SQLNode 的集合,这些集合可以被视为一个责任链。在处理 SQL 语句时,MyBatis 会按照一定的顺序遍历这个责任链,让每个 SQLNode 对象对 SQL 语句进行处理。这样,MyBatis 就能够灵活地生成各种不同的 SQL 语句,而不需要编写大量的重复代码。
例如,当我们执行一个带有条件查询的 SQL 语句时,MyBatis 会生成一个带有 WHERE 子句的 SQL 语句。在生成这个 SQL 语句的过程中,MyBatis 会依次遍历责任链中的每个 SQLNode 对象,并将它们的结果拼接成最终的 SQL 语句。如果某个 SQLNode 对象无法处理当前的 SQL 语句部分,它会将处理权交给下一个 SQLNode 对象,直到整个责任链被遍历完为止。

public interface SQLNode {String process(String sql);
}public class WhereNode implements SQLNode {private SQLNode next;public WhereNode(SQLNode next) {this.next = next;}@Overridepublic String process(String sql) {String where = "WHERE ";if (next != null) {where += next.process(sql);}return where;}
}public class OrderByNode implements SQLNode {private SQLNode next;public OrderByNode(SQLNode next) {this.next = next;}@Overridepublic String process(String sql) {String orderBy = "ORDER BY id";if (next != null) {orderBy += next.process(sql);}return orderBy;}
}public class SelectNode implements SQLNode {private SQLNode next;public SelectNode(SQLNode next) {this.next = next;}@Overridepublic String process(String sql) {String select = "SELECT * FROM table";if (next != null) {select += next.process(sql);}return select;}
}// 构建责任链
SQLNode whereNode = new WhereNode(null);
SQLNode orderByNode = new OrderByNode(whereNode);
SQLNode selectNode = new SelectNode(orderByNode);// 生成 SQL 语句
String sql = selectNode.process(null);
System.out.println(sql);

在这个示例中,我们定义了三个 SQLNode 类,分别对应 SQL 语句中的 WHERE 子句、ORDER BY 子句和 SELECT 语句。每个 SQLNode 对象都包含一个 next 属性,用于指向责任链中的下一个 SQLNode 对象。
我们首先创建了 WhereNode 对象,然后创建了 OrderByNode 和 SelectNode 对象,并将它们与 WhereNode 对象连接起来,形成了一个责任链。最后,我们通过调用 selectNode.process(null) 方法来生成 SQL 语句,这样 MyBatis 就会按照责任链的顺序遍历各个 SQLNode 对象,并将它们的处理结果拼接成最终的 SQL 语句。

相关文章:

015行为型-职责链模式

目录定义标准模式实现&#xff1a;职责链变体使用链表实现使用数组实现应用场景日志输出spring过滤器spirng 拦截器mybatis动态sql定义 责链模式是一种设计模式&#xff0c;其目的是使多个对象能够处理同一请求&#xff0c;但是并不知道下一个处理请求的对象是谁。它能够解耦请…...

python例程:五子棋(控制台版)程序

目录《五子棋&#xff08;控制台版&#xff09;》程序使用说明程序示例代码可执行程序及源码下载路径《五子棋&#xff08;控制台版&#xff09;》程序使用说明 在PyCharm中运行《五子棋&#xff08;控制台版&#xff09;》即可进入如图1所示的系统主界面。 图1 游戏主界面 具…...

leveldb的Compaction线程

个人随笔 (Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu) 1. leveldb的Compaction全局线程 在leveldb中&#xff0c;有一个全局的后台线程BGThread&#xff0c;用于数据库的MinorCompact与MajorCompact。 重点关注“全局线程”&#xff1a; 这个标识着无论一个进程打开…...

邪恶的想法冒出,立马启动python实现美女通通下

前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! 完整源码、python资料: 点击此处跳转文末名片获取 当我在首页刷到这些的时候~ 我的心里逐渐浮现一个邪念&#xff1a;我把这些小姐姐全都采集&#xff0c;可以嘛&#xff1f; 答案当然是可以的~毕竟就我这技术&#xff0c…...

蓝桥杯刷题冲刺 | 倒计时18天

作者&#xff1a;指针不指南吗 专栏&#xff1a;蓝桥杯倒计时冲刺 &#x1f43e;马上就要蓝桥杯了&#xff0c;最后的这几天尤为重要&#xff0c;不可懈怠哦&#x1f43e; 文章目录0.知识点1.乳草的入侵今天写 搜索题 0.知识点 DFS 设计步骤 确定该题目的状态&#xff08;包括边…...

经典算法面试题——Java篇-附带赠书活动,评论区随机选取一人赠书

目录 一.图书推荐 二.说一下什么是二分法&#xff1f;使用二分法时需要注意什么&#xff1f;如何用代码实现&#xff1f; 三.什么是插入排序&#xff1f;用代码如何实现&#xff1f; 四.什么是冒泡排序&#xff1f;用代码如何实现&#xff1f; 五.什么是斐波那契数列&#…...

支持RT-Thread最新版本的瑞萨RA2E1开发板终于要大展身手了

支持RT-Thread最新版本的瑞萨RA2E1开发板终于要大展身手了 熟悉RT-Thread和瑞萨MCU的朋友都知道&#xff0c;当前RT-Thread仓库的主线代码是不支持RA2E1这个BSP的。刚好&#xff0c;最近我在联合瑞萨推广一个叫《致敬未来的攻城狮计划》&#xff0c;使用的就是RA2E1开发板&…...

【C语言进阶】 12. 假期测评①

day01 1. 转义字符的判断 以下不正确的定义语句是&#xff08; &#xff09; A: double x[5] {2.0, 4.0, 6.0, 8.0, 10.0}; B: char c2[] {‘\x10’, ‘\xa’, ‘\8’}; C: char c1[] {‘1’,‘2’,‘3’,‘4’,‘5’}; D: int y[53]{0, 1, 3, 5, 7, 9}; 【答案解析】 B 本…...

给程序加个进度条吧,1行Python代码,快速添加~

大家好&#xff0c;这里是程序员晚枫。 你在写代码的过程中&#xff0c;有没有遇到过以下问题&#xff1f; 已经写好的程序&#xff0c;想看看程序执行的进度&#xff1f; 在写代码批量处理文件的时候&#xff0c;如何显示现在处理到第几个文件了&#xff1f; &#x1f446…...

常见的Keil5编译报错及其原因和解决方法

以下是几种常见的Keil5编译报错及其原因和解决方法&#xff1a; "Error: L6218E: Undefined symbol"&#xff08;未定义符号错误&#xff09; 这通常是由于缺少对应的库文件或者代码中有未声明的变量或函数引起的。解决方法是检查相应的库文件是否已正确添加到工程中…...

Django 实现瀑布流

需求分析 现在是 "图片为王"的时代&#xff0c;在浏览一些网站时&#xff0c;经常会看到类似于这种满屏都是图片。图片大小不一&#xff0c;却按空间排列&#xff0c;就这是瀑布流布局。 以瀑布流形式布局&#xff0c;从数据库中取出图片每次取出等量&#xff08;7 …...

传输层协议----UDP/TCP

文章目录前言一、再谈端口号端口号的划分认识知名端口号(Well-Know Port Number)两个问题nestatpidof二、UDP协议UDP协议端格式UDP的特点面向数据报UDP的缓冲区UDP使用注意事项基于UDP的应用层协议二、TCP协议TCP协议段格式可靠性问题确认应答(ACK)机制流量控制六个标志位PSHUG…...

教你如何快速在Linux中找到某个目录中最大的文件

工作中经常会有查看某个目录下最大的文件的需求&#xff0c;比如在运维工作中&#xff0c;发现某个系统或功能不工作了&#xff0c;经排查发现是服务器空间满了…那么接下来就需要清理一下临时文件或者日志文件&#xff0c;或者其他不需要的文件&#xff0c;那么就会想要查看一…...

Java二叉树面试题讲解

Java二叉树面试题讲解&#x1f697;1.检查两颗树是否相同&#x1f695;2.另一颗树的子树&#x1f699;3.二叉树最大深度&#x1f68c;4.判断一颗二叉树是否是平衡二叉树&#x1f68e;5.对称二叉树&#x1f693;6.获取树中结点个数&#x1f691;7.判断一个树是不是完全二叉树&am…...

rancher2.6进阶之nfs动态创建pv配置

添加NFS client provisioner 动态提供K8s后端存储卷 1.1.前提说明 1.1.1.说明 NFS client provisioner 利用 NFS Server 给 Kubernetes 作为持久存储的后端,并且动态提供PV。 默认 rancher 2 的存储类中的提供者不包含NFS,需要手动添加;添加方式有两种: 1)从应用商店直接安…...

快速上手vue elementUI好看的登录界面

这是一个非常非常适合新手的vue登录界面&#xff0c;总体来说美观大气&#xff0c;axios那部分没有发&#xff0c;有需要的大家可以自己进行二次开发&#xff0c;继续编写。 用到了技术栈有 vue/cli 5.07 element-ui 2.15.9 适合入门级新手&#xff0c;展示下页面 emmm验证码…...

Vue趣味【Vue3+Element Plus+Canvas实现一个简易画板;支持导出为图片】

目录&#x1f31f;前言&#x1f31f;粉丝先看&#x1f31f;创建Vue3项目&#x1f31f;引入Element Plus&#x1f31f;实现代码&#xff08;详细注释&#xff09;&#x1f31f;写在最后&#x1f31f;JSON包里写函数&#xff0c;关注博主不迷路&#x1f31f;前言 哈喽小伙伴们&a…...

【Spring Cloud Alibaba】2.服务注册与发现(Nacos安装)

文章目录环境要求简介安装Nacos源码安装Docker安装数据库配置访问服务我们要搭建一个Spring Cloud Alibaba项目就绕不开Nacos&#xff0c;阿里巴巴提供的Nacos组件&#xff0c;可以提供服务注册与发现和分布式配置服务&#xff0c;拥有着淘宝双十一十几年的流量经验&#xff0c…...

深度学习 Day28——利用Pytorch实现好莱坞明星识别

深度学习 Day28——利用Pytorch实现好莱坞明星识别 文章目录深度学习 Day28——利用Pytorch实现好莱坞明星识别一、前言二、我的环境三、前期工作1、导入依赖项设置GPU2、导入数据集3、划分数据集四、调用官方的VGG16模型五、训练模型1、编写训练函数2、编写测试函数3、设置动态…...

Android中使用FCM进行消息推送

Firebase Cloud Message 的介绍 Firebase Cloud Message(FCM)是由Google推出的一种云端消息推送服务,它是由Google推出的Google Cloud Messaging(GCM)服务的升级版。在2016年5月,Google宣布将Google Cloud Messaging重命名为Firebase Cloud Message,作为Firebase的一部…...

从 X 入门Pytorch——BN、LN、IN、GN 四种归一化层的代码使用和原理

Pytorch中四种归一化层的原理和代码使用前言1 Batch Normalization&#xff08;2015年提出&#xff09;Pytorch官网解释原理Pytorch代码示例2 Layer Normalization&#xff08;2016年提出&#xff09;Pytorch官网解释原理Pytorch代码示例3 Instance Normalization&#xff08;2…...

Windows环境下实施域名访问的一些小知识

文章目录 前言一、windows域名访问流程二、网络域名访问配置设置DNS未正确设置DNS的结果三、本地hosts设置本地hosts本地hosts的优先机制本地hosts的内部访问次序示例一示例二总结前言 作为一种常见的操作系统,windows系统具有其特殊的域名访问管理机制。了解其访问机制,将有…...

78.qt QCustomPlot介绍

参考https://www.qcustomplot.com/index.php/tutorials/settingup 下载地址: https://www.qcustomplot.com/index.php/download 1.添加帮助文档 在QtCreator ——>工具——>选项——>帮助——>文档——>添加,选择qcustomplot.qch文件,确定,以后按F1就能跳转到…...

win32api之文件系统管理(七)

什么是文件系统 文件系统是一种用于管理计算机存储设备上文件和目录的机制。文件系统为文件和目录分配磁盘空间&#xff0c;管理文件和目录的存储和检索&#xff0c;以及提供对它们的访问和共享&#xff0c;以下是常见的两种文件系统&#xff1a; NTFSFAT32磁盘分区容量2T32G…...

点云规则格网化,且保存原始的点云索引

点云规则格网化&#xff0c;且保存原始的点云索引 点云深度学习Voxelize规则&#xff0c;参考PTV2&#xff1a;https://github.com/Gofinge/PointTransformerV2 1总执行文件 import numpy as np import torch from pcr.utils.registry import Registry TRANSFORMS Registry…...

入职第一天就被迫离职,找工作多月已读不回,面试拿不到offer我该怎么办?

大多数情况下&#xff0c;测试员的个人技能成长速度&#xff0c;远远大于公司规模或业务的成长速度。所以&#xff0c;跳槽成为了这个行业里最常见的一个词汇。 前言 前几天&#xff0c;我们一个粉丝跟我说&#xff0c;正常入职一家外包&#xff0c;什么都准备好了&#xff0…...

走进Vue【三】vue-router详解

目录&#x1f31f;前言&#x1f31f;路由&#x1f31f;什么是前端路由&#xff1f;&#x1f31f;前端路由优点缺点&#x1f31f;vue-router&#x1f31f;安装&#x1f31f;路由初体验1.路由组件router-linkrouter-view2.步骤1. 定义路由组件2. 定义路由3. 创建 router 实例4. 挂…...

html+css制作

<!DOCTYPE html> <html><head><meta charset"utf-8"><title>校园官网</title><style type"text/css">*{padding: 0;margin: 0;}#logo{width:30%;float: left;}.nav{width: 100%;height: 100px;background-color…...

Python实现rar、zip和7z文件的压缩和解压

一、7z压缩文件的压缩和解压 1、安装py7zr 我们要先安装py7zr第三方库&#xff1a; pip install py7zr如果python环境有问题&#xff0c;执行上面那一条安装语句老是安装在默认的python环境的话&#xff0c;我们可以执行下面这条语句&#xff0c;将第三方库安装在项目的虚拟…...

从Hive源码解读大数据开发为什么可以脱离SQL、Java、Scala

从Hive源码解读大数据开发为什么可以脱离SQL、Java、Scala 前言 【本文适合有一定计算机基础/半年工作经验的读者食用。立个Flg&#xff0c;愿天下不再有肤浅的SQL Boy】 谈到大数据开发&#xff0c;占据绝大多数人口的就是SQL Boy&#xff0c;不接受反驳&#xff0c;毕竟大…...

找人做任务网站有哪些/seo优化博客

clear; clc; A rand(4) cond(A)     %求矩阵A的条件数 Det(A)     %求方阵A的行列式 Dot(A,B)     %矩阵A与B的点积 Eig(A)     %方阵A的特征值和特征向量 Norm(A,1)   %矩阵A的1-范式 Norm(A)     %矩阵A的2-范式 norm(A,2) Trace(A)     %矩阵A的…...

重庆市网站建设/搜索引擎营销案例分析

作为普通的网民来说&#xff0c;一般不需要知道也不用关心什么是盗链&#xff0c;不过如果你是网站的开发者或维护者&#xff0c;就不得不重视盗链的问题了。如果你刚刚开发完一个没有防盗链的带有文件下载功能的网站&#xff0c;挂上internet&#xff0c;然后上传几个时下非常…...

建筑工程承包网址大全/免费seo关键词优化方案

1、微型计算机系统中的中央处理器通常是指( )A.内存储器和控制器B.内存储器和运算器C.运算器和控制器D.内存储器、控制器和运算器2、存储器可分为哪两类( )A.硬盘和软盘B.ROM和EPROMC.RAM和ROMD.内存储器和外存储器3、最早的计算机的用途是用于( )A.科学计算B.自动控制C.辅助设…...

国外的电商网站有哪些/搜seo

一般来说&#xff0c;STM32的型号是这样表示的 STM32F103XYxxx 这XY是什么意思呢&#xff1f;其实啊&#xff0c;这个X表示引脚数量&#xff0c;具体的值有如下形式&#xff1a; R64PIN V100PIN Z144PIN Y表示FLASH容量大小&#xff0c;具体有如下取值&#xff1a; 4 16K…...

如何做网站页面赚钱/最新中央人事任免

#1 连接数据库import pymysqldef run():try:# 打开数据库连接&#xff0c;设置charset为utf8&#xff0c;否则存入数据库时在workbench显示为乱码db pymysql.connect("localhost", "root", , "test_DB", charsetutf8)except pymysql.Error, e:p…...

wordpress 站群系统/营销手段有哪些

参考&#xff1a;https://blog.csdn.net/qq_34329508/article/details/78141011...