前端学习:HTTP协议、请求响应、分层解耦

HTTP协议

HTTP-概述

  HTTP:Hyper Text Transfer Protocol(超文本传输协议),规定了浏览器与服务器之间数据传输的规则。如果想知道http协议的数据传输格式有哪些,可以打开浏览器,点击 F12 打开开发者工具,点击Network 来查看。

  浏览器和服务器是按照HTTP协议进行数据通信的。

	HTTP协议又分为:请求协议和响应协议
		请求协议:浏览器将数据以请求格式发送到服务器
			包括:请求行、请求头 、请求体
		响应协议:服务器将数据以响应格式返回给浏览器
			包括:响应行 、响应头 、响应体

  浏览器向服务器进行请求时,服务器按照固定的格式进行解析:
在这里插入图片描述

  服务器向浏览器进行响应时,浏览器按照固定的格式进行解析:
在这里插入图片描述
学习HTTP主要是学习请求和响应数据的具体格式内容。

HTTP的特点:
	1、基于TCP协议:面向连接,安全
	2、基于请求-响应模型: 一次请求对应一次响应(先请求后响应)
	3、HTTP协议是无状态协议: 对于数据没有记忆能力。每次请求-响应都是独立的

HTTP-请求协议

  在实际应用中常用的有 :GET、POST

请求方式请求说明
GET获取资源向特定的资源发出请求。
POST传输实体主体,向指定资源提交数据进行处理请求(例:上传文件),数据被包含在请求体中。

GET方式的请求协议

在这里插入图片描述

请求行 :HTTP请求中的第一行数据。由: 请求方式 、 资源路径 、 协议/版本 组成(之间使用空格分隔)
	请求方式:GET
	资源路径:/brand/findAll?name=OPPO&status=1
	请求路径:/brand/findAll
	请求参数:name=OPPO&status=1
		请求参数是以key=value形式出现
		多个请求参数之间使用 & 连接
		请求路径和请求参数之间使用 ? 连接
	协议/版本:HTTP/1.1

.
  http是个无状态的协议,所以需要在请求头设置浏览器的一些自身信息和想要响应的形式。这样服务器在收到信息后,就可以知道是谁,想干什么了。

请求头 :第二行开始,上图黄色部分内容就是请求头。格式为key: value形式
常见的HTTP请求头有:
	Host: 表示请求的主机名
	User-Agent: 浏览器版本。
	Accept:表示浏览器能接收的资源类型,如text/*,image/*或者*/*表示所有;
	Accept-Language:表示浏览器偏好的语言,服务器可以据此返回不同语言的网页;
	Accept-Encoding:表示浏览器可以支持的压缩类型,例如gzip, deflate等
	Content-Type:请求主体的数据类型
	Content-Length:数据主体的大小(单位:字节)

.

请求体 :存储请求参数
	GET请求的请求参数在请求行中,故不需要设置请求体

POST方式的请求协议

在这里插入图片描述

请求行(以上图中红色部分):包含请求方式、资源路径、协议/版本
	请求方式:POST
	资源路径:/brand
	协议/版本:HTTP/1.1
请求头(以上图中黄色部分)
请求体(以上图中绿色部分) :存储请求参数
请求体和请求头之间是有一个空行隔开(作用:用于标记请求头结束)

GET请求和POST请求的区别

区别方式GET请求POST请求
请求参数请求参数在请求行中。例:/brand/findAll?name=OPPO&status=1请求参数在请求体中
请求参数长度请求参数长度有限制(浏览器不同限制也不同)请求参数长度没有限制
安全性安全性低。原因:请求参数暴露在浏览器地址栏中。安全性相对高

HTTP-响应协议

  http是个无状态的协议,所以可以在请求头和响应头中设置一些信息和想要执行的动作,这样,对方在收到信息后,就可以知道你是谁,你想干什么。
在这里插入图片描述

响应行(以上图中红色部分):响应数据的第一行。响应行由 协议及版本 、 响应状态码 、 状态码描述 组成
	协议/版本:HTTP/1.1
	响应状态码:200
	状态码描述:OK
	
响应头(以上图中黄色部分):响应数据的第二行开始。格式为key:value形式
常见的HTTP响应头有:
	Content-Type:表示该响应内容的类型,例如text/html,image/jpeg ;
	Content-Length:表示该响应内容的长度(字节数);
	Content-Encoding:表示该响应压缩算法,例如gzip ;
	Cache-Control:指示客户端应如何缓存,例如max-age=300表示可以最多缓存300秒 ;
	Set-Cookie: 告诉浏览器为当前页面所在的域设置cookie ;
	
响应体(以上图中绿色部分): 响应数据的最后一部分。存储响应的数据
响应体和响应头之间有一个空行隔开(作用:用于标记响应头结束)

响应状态码

状态码分类说明
1xx响应中 ----> 临时状态码。表示请求已经接受,告诉客户端应该继续请求或者如果已经完成则忽略
2xx成功 ----> 表示请求已经被成功接收,处理已完成
3xx重定向 ----> 重定向到其它地方,让客户端再发起一个请求以完成整个处理
4xx客户端错误 ----> 处理发生错误,责任在客户端,如:客户端的请求一个不存在的资源,客户端未被授权,禁止访问等
5xx服务器端错误 ----> 处理发生错误,责任在服务端,如:服务端抛出异常,路由出错,HTTP版本不支持等

  关于响应状态码,先主要认识三个状态码,其余的等后期用到了再去掌握:

200    ok  ---->  客户端请求成功
404  Not Found  ---->  请求资源不存在
500  Internal Server Error  ----> 服务端发生不可预期的错误

请求响应简介

请求响应:
	请求(HttpServletRequest):获取请求数据
	响应(HttpServletResponse):设置响应数据

常用的架构有BS架构和CS架构。
  BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。常用的架构,网页访问。
  CS架构:Client/Server,客户端/服务器架构模式。需要下载APP

请求

postman

  当前最为主流的开发模式:前后端分离。其中,GET请求适合用于获取资源、查询数据,而POST请求适合用于提交表单、上传文件等操作。  浏览器通过网址发起的请求全部都是GET请求;而POST请求的数据对用户来说是不可见的,如果想要测试POST请求就会很不方便,Postman应运而生。Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件,常用于进行接口测试。

简单参数

   简单参数是指向服务器发起请求时,向服务器传递的是一些普通的请求数据。在 http://localhost:8080/simpleParam?name=Tom&age=10 中 name 和 age 就是简单参数。
   在后端程序中,通常使用SpringBoot方式接收传递过来的普通参数数据。在Springboot的环境中,对原始的API进行了封装,接收参数的形式更加简单。简单参数,参数名与形参变量名相同,定义同名的形参即可接收参数。

@RestController
public class RequestController {
// http://localhost:8080/simpleParam?name=Tom&age=10
// 第1个请求参数: name=Tom  参数名:name,参数值:Tom
// 第2个请求参数: age=10  参数名:age , 参数值:10

//springboot方式
@RequestMapping("/simpleParam")
	public String simpleParam(String name , Integer age ){ //形参名和请求参数名保持一致
		System.out.println(name+"  :  "+age);
		return "OK";
	}
}

  不论是GET请求还是POST请求,对于简单参数来讲,只要保证请求参数名和Controller
方法中的形参名保持一致 ,就可以获取到请求参数中的数据值。
  如果在开发中,遇到请求参数名和controller方法中的形参名不相同时,可以使用Spring提供的 @RequestParam 注解完成映射。在方法形参前面加上 @RequestParam 然后通过value属性执行请求参数名,从而完成映射。注意:@RequestParam中的required属性默认为true,代表该请求参数必须传递,如果不传递将报错。

@RequestMapping("/simpleParam")
   public String simpleParam(@RequestParam(name = "name", required =
           false) String username, Integer age){
       System.out.println(username+ ":" + age);
       return "OK";
   }

实体参数

  在使用简单参数做为数据传递方式时,前端传递了多少个请求参数,后端controller方法中的形参就要书写多少个。如果请求参数比较多,则需要一个参数一个参数的接收,比较繁琐。此时,可以将请求参数封装到一个实体类对象中。
  要想完成数据封装,需要遵守规则:请求参数名与实体类的属性名相同
在这里插入图片描述

简单实体对象

  1、定义POJO实体类

package com.sprintbot1example.pojo;

public class User {
    private String name;
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

  2、Controller方法:

@RequestMapping("/simplePojo")
    public String simplePojo(Userzzz sur){
        System.out.println(sur);
        return "ok";
    }
复杂实体对象

  复杂实体对象指的是,在实体类中有一个或多个属性,也是实体对象类型的。如:User类中有一个Address类型的属性(Address是一个实体类,有两个province和city属性)
  复杂实体对象的封装,需要遵守如下规则:请求参数名与形参对象属性名相同,按照对象层次结构关系即可接收嵌套实体类属性参数。
在这里插入图片描述
  1、定义POJO实体类:
Address实体类

package com.sprintbot1example.pojo;

public class Adress {
    private String province;
    private String city;

    public String getProvince() {
        return province;
    }

    public void setProvince(String province) {
        this.province = province;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    @Override
    public String toString() {
        return "Adress{" +
                "province='" + province + '\'' +
                ", city='" + city + '\'' +
                '}';
    }
}

User实体类

package com.sprintbot1example.pojo;

public class Userzzz {
    private String name;
    private Integer age;
    private Address address;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Userzzz{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", address=" + address +
                '}';
    }
}

  2、Controller方法:

@RequestMapping("/simplePojo")
    public String simplePojo(Userzzz sur){
        System.out.println(sur);
        return "ok";
    }

数组集合参数

  数组集合参数的使用场景:在HTML的表单中,有一个表单项是支持多选的(复选框),可以提交选择的多个值。多个值是怎么提交的呢?其实多个值也是一个一个的提交。
在这里插入图片描述

后端程序接收上述多个值的方式有两种:数组集合

数组

  数组参数:请求参数名与形参数组名称相同且请求参数为多个,定义数组类型形参即可接收参数。
在这里插入图片描述

@RequestMapping("/arrayParam")
    public String arrayParam(String[] hobby){
        System.out.println(Arrays.toString(hobby));
        return "ok";
    }
在前端请求时,有两种传递形式:
	1、xxxxxxxxxx?hobby=game&hobby=java
	2、xxxxxxxxxxxxx?hobby=game,java
集合

  集合参数:请求参数名与形参集合对象名相同且请求参数为多个,@RequestParam 绑定参数关系默认情况下,请求中参数名相同的多个值,是封装到数组。如果要封装到集合,要使用@RequestParam绑定参数关系
在这里插入图片描述

@RequestMapping("/listParam")
    public String listParam(@RequestParam List<String> hobby){
        System.out.println(hobby);
        return "ok";
    }

日期参数

  在一些特殊的需求中,可能会涉及到日期类型数据的封装。因为日期的格式多种多样(如:2022-12-12 10:05:45 、2022/12/12 10:05:45),那么对于日期类型的参数在进行封装的时候,需要通过@DateTimeFormat注解,以及其pattern属性来设置日期的格式。
在这里插入图片描述

Json参数

  JSON是开发中最常用的前后端数据交互方式。

学习JSON格式参数,主要从以下两个方面着手:
	1. Postman在发送请求时,如何传递json格式的请求参数
	2. 在服务端的controller方法中,如何接收json格式的请求参数
Postman发送JSON格式数据

在这里插入图片描述

服务端Controller方法接收JSON格式数据

  传递json格式的参数,在Controller中会使用实体类进行封装。
  封装规则:JSON数据键名与形参对象属性名相同,定义POJO类型形参即可接收参数。需要使用@RequestBody标识。
在这里插入图片描述

//josn 参数
    @RequestMapping("/JSONParam")
    public String JSONParam(@RequestBody Userzzz userzzz){
        System.out.println(userzzz);
        return "OK";
    }

路径参数

  传统的开发中请求参数是放在请求体(POST请求)传递或跟在URL后面通过?key=value的形式传递(GET请求)。而在现在开发中,经常会直接在请求的URL中传递参数。
  学习路径参数,主要掌握在后端的controller方法中,如何接收路径参数。

路径参数:
	前端:通过请求URL直接传递参数
	后端:使用{…}来标识该路径参数,需要使用@PathVariable获取路径参数
传递单个路径参数

在这里插入图片描述

// 路径
    @RequestMapping("/path/{id}")
    public String pathParam(@PathVariable Integer id){
        System.out.println(id);
        return "OK";
    }
传递多个路径参数
// 路径
    @RequestMapping("/path/{id}/{name}")
    public String pathParam2(@PathVariable Integer id,
                             @PathVariable String name){
        System.out.println(id+":"+name);
        return "OK";
    }

响应

  Controller程序,除了接收请求外,还可以进行响应。controller方法中的return的结果,使用@ResponseBody注解就可以响应给浏览器。

@ResponseBody注解:
	类型:方法注解、类注解
	位置:书写在Controller方法上或类上
	作用:将方法返回值直接响应给浏览器
	如果返回值类型是实体对象/集合,将会转换为JSON格式后在响应给浏览器

  但是,在所书写的Controller中,只在类上添加了RestController注解、方法添加了@RequestMapping注解,并没有使用@ResponseBody注解,怎么给浏览器响应呢?原因是:在类上添加的@RestController注解,是一个组合注解。@RestController = @Controller + @ResponseBody

在这里插入图片描述

  在上述所编写的Controller方法中,返回值各种各样,没有任何的规范。在实际开发中,controller方法将成千上万,若controller返回值没有规范将造成整个项目难以维护。在实际项目开发中,无论是哪种方法,都会定义一个统一的返回结果。方案如下:
在这里插入图片描述

统一的返回结果使用类来描述,在这个结果中包含:
	响应状态码:当前请求是成功,还是失败
	状态码信息:给页面的提示信息
	返回的数据:给前端响应的数据(字符串、对象、集合)

.
  定义在一个实体类Result来包含以上信息。代码如下:

/**
 * 统一响应结果封装类
 */
public class Result {
    private Integer code ;//1 成功 , 0 失败
    private String msg; //提示信息
    private Object data; //数据 data

    public Result() {
    }
    public Result(Integer code, String msg, Object data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }
    public Integer getCode() {
        return code;
    }
    public void setCode(Integer code) {
        this.code = code;
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
    public Object getData() {
        return data;
    }
    public void setData(Object data) {
        this.data = data;
    }

    public static Result success(Object data){
        return new Result(1, "success", data);
    }
    public static Result success(){
        return new Result(1, "success", null);
    }
    public static Result error(String msg){
        return new Result(0, msg, null);
    }

    @Override
    public String toString() {
        return "Result{" +
                "code=" + code +
                ", msg='" + msg + '\'' +
                ", data=" + data +
                '}';
    }
}
@RequestMapping("/listParam")
    public Result listParam(@RequestParam List<String> hobby){
        System.out.println(hobby);
        return Result.success(hobby);
    }

Springboot项目的静态资源(html,css,js等前端资源)默认存放目录为:classpath:/static
、 classpath:/public、 classpath:/resources

分层解耦

  在进行程序设计以及程序开发时,应尽可能遵循单一职责原则,即一个类或一个方法,就只做一件事情,只管一块功能。这样可以让类、接口、方法的复杂度更低,可读性更强,扩展性更好,也更利用后期的维护。

三层架构

在项目开发中按处理逻辑,从组成上看可以分为三个部分:
	数据访问:负责业务数据的维护操作,包括增、删、改、查等操作。
	逻辑处理:负责业务逻辑处理的代码。
	请求处理、响应数据:负责,接收页面的请求,给页面响应数据。

按照上述对应的三个组成部分,如下:
	Controller:控制层。接收前端发送的请求,对请求进行处理,并响应数据。
	Service:业务逻辑层。处理具体的业务逻辑。
	Dao:数据访问层(Data Access Object),也称为持久层。负责数据访问操作,包括数据的增、删、改、查。

基于三层架构的程序执行流程:
	1、前端发起的请求,由Controller层接收(Controller响应数据给前端)
	2、Controller层调用Service层来进行逻辑处理(Service层处理完后,把处理结果返回给Controller层)
	3、Serivce层调用Dao层(逻辑处理过程中需要用到的一些数据要从Dao层获取)
	4、Dao层操作文件中的数据(Dao拿到的数据会返回给Service层)

在这里插入图片描述

用三层架构改写如下:

在这里插入图片描述

解耦

  解耦:即解除耦合。软件开发涉及到的两个概念:内聚和耦合。内聚:指软件中各个功能模块内部的功能联系。耦合:指衡量软件中各个层/模块之间的依赖、关联的程度。
  软件设计原则:高内聚低耦合。
  高内聚指的是:一个模块中各个元素之间的联系的紧密程度,如果各个元素(语句、程序段)之间的联系程度越高,则内聚性越高,即 “高内聚”。
  低耦合指的是:软件中各个层、模块之间的依赖关联程序越低越好。

  解耦思路是提供一个容器,容器中存储一些对象,controller程序从容器中获取EmpService类型的对象。要实现上述解耦操作,就涉及到Spring中的两个核心概念:
  控制反转: Inversion Of Control,简称IOC。对象的创建控制权由程序自身转移到外部(容器),这种思想称为控制反转。对象的创建权由程序员主动创建转移到容器(由容器创建、管理对象)。这个容器称为:IOC容器或Spring容器。OC容器中创建、管理的对象,称之为:bean对象
  依赖注入: Dependency Injection,简称DI。容器为应用程序提供运行时,所依赖的资源,称之为依赖注入。程序运行时需要某个资源,此时容器就为其提供这个资源。

步骤:			
	1.将Service层及Dao层的实现类,交给IOC容器管理
	  使用Spring提供的注解:@Component ,就可以实现类交给IOC容器管理
	  
	2.为Controller及Service注入运行时依赖的对象
	  使用Spring提供的注解:@Autowired ,就可以实现程序运行时IOC容器自动注入需要的依赖对象
		Controller程序中注入依赖的Service层对象
		Service程序中注入依赖的Dao层对象

IOC详解

  IOC容器创建的对象称为bean对象。要把某个对象交给1OC容器管理,需要在对应的类上加上如下注解之一:

注解说明位置
@Component声明bean的基础注解不属于以下三类时,用此注解
@Controller@Component的衍生注解标注在控制器类上
@Service@Component的衍生注解标注在业务类上
@Repository@Component的衍生注解标注在数据访问类上(由于与mybatis整合,用的少)
注意事项:
	声明bean的时候,可以通过value属性指定bean的名字,如果没有指定,默认为类名首字母小写。
	使用以上四个注解都可以声明bean,但是在springboot集成web开发中,声明控制器bean只能用@Controller。

  bean想要生效,还需要被组件扫描注解@ComponentScan扫描。@ComponentScan注解虽然没有显式配置,但是实际上已经包含在了启动类声明注解@SpringBootApplication中,默认扫描的范围是启动类所在包及其子包。

DI详解

  依赖注入,是指IOC容器要为应用程序去提供运行时所依赖的资源,而资源指的就是对象。@Autowired注解,默认是按照类型进行自动装配的(去IOC容器中找某个类型的对象,然后完成注入操作)。如果在IOC容器中,存在多个相同类型的bean对象,则会报错。Spring提供了以下几种解决方案:
  使用@Primary注解:当存在多个相同类型的Bean注入时,加上@Primary注解,来确定默认的实现。

在这里插入图片描述

  使用@Qualifier注解:指定当前要注入的bean对象。 在@Qualifier的value属性中,指定注入的bean的名称。@Qualifier注解不能单独使用,必须配合@Autowired使用

在这里插入图片描述

  使用@Resource注解:是按照bean的名称进行注入。通过name属性指定要注入的bean的名称。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/346804.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

DataStream API(转换算子)

目录 源算子 转换算子 1&#xff0c;基本转换算子 1.1映射&#xff08;map&#xff09; 1.2过滤&#xff08;filter&#xff09; 1.3扁平映射&#xff08;flatMap&#xff09; 2&#xff0c;聚合算子 2.1按键分区&#xff08;keyBy&#xff09; 2.2简单聚合 3&#x…

2024-01-24(ElasticSearch)

1.mysql和elasticsearch的架构&#xff1a; 2.IK分词器利于分中文词汇。 底层是有一个中文字典&#xff0c;这个字典中的中文词汇也是可以拓展的和禁用某些词。 3.mapping常见属性&#xff1a; type&#xff1a;数据类型 index&#xff1a;是否索引 analyzer&#xff1a;分…

2024年mongodb自建三节点副本集详细教程

环境说明 系统centos7.9 自建服务器或云服务器&#xff0c;硬件要求不低于2核2G内存&#xff0c;20G硬盘&#xff0c;文件系统默认是ext4即可。 生产环境最好单独一个磁盘存放数据库&#xff0c;方便数据备份和还原&#xff0c;避免干扰到其他磁盘的运作。 mongodb 4.4.27 …

QT 实现自动生成小学两位数加减法算式

小学生加减法训练 QT实现–自动生成两位数加减法算式&#xff0c;并输出txt文件 可以copy到word文件&#xff0c;设置适当字体大小和行间距&#xff0c;带回家给娃做做题 void MainWindow::test(int answerMax, int count) {// 创建一个随机数生成器QRandomGenerator *gener…

引领AI变革:边缘计算与自然语言处理结合的无尽可能

引言 讲到Ai&#xff0c;你第一时间会想到什么&#xff1f;是Chagpt和文心一言这样与人类交流自然的Ai生成式对话服务&#xff1f;还是根据关键字快速制图的Ai绘图&#xff1f;这些都是近年来人们所常知的Ai用途&#xff0c;我们今天来讲讲以自然语言处理为辅&#xff0c;在Ai赋…

JS之歌词滚动案例

让我为大家带来一个歌词滚动的案例吧&#xff01; 详细的介绍都在代码块中 我很希望大家可以自己动手尝试一下&#xff0c;如果需要晴天的mp3音频文件可以私信我 上代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset&quo…

Vue好看的组件库:Element

文章目录 1、什么是Element2、Element快速入门3、Element布局3.1、 Layout 局部3.2、容器布局 1、什么是Element Element&#xff1a;是饿了么公司前端开发团队提供的一套基于 Vue 的网站组件库&#xff0c;用于快速构建网页 Element 提供了很多组件&#xff08;组成网页的部件…

使用DBSyncer同步Oracle11g数据到Mysql5.7中_实现全量数据同步和增量数据实时同步_操作过程---数据同步之DBSyncer工作笔记007

之前都是用mysql和Postgresql之间进行同步的,已经实现了数据的实时同步,现在要实现Oracle数据库到Mysql数据库的全量,以及增量同步. 因为之前配置的不对,这里架构名写成了orcl,所以导致,虽然能连接上,但是,在进行数据同步的时候,看不到表,所以这里说一下如何进行连接 这里,首先…

全球机器人产业:技术创新驱动下的市场与竞争新态势

原创 | 文 BFT机器人 近年来&#xff0c;随着颠覆性技术创新的不断涌现、市场新需求的迅速崛起以及外部冲击的深远影响&#xff0c;机器人产业正经历着前所未有的变革。在技术领域&#xff0c;机器人技术不断突破&#xff0c;智能化、自主化、协同化水平日益提升&#xff1b;在…

Java设计模式-装饰器模式(10)

大家好,我是馆长!今天开始我们讲的是结构型模式中的装饰器模式。老规矩,讲解之前再次熟悉下结构型模式包含:代理模式、适配器模式、桥接模式、装饰器模式、外观模式、享元模式、组合模式,共7种设计模式。。 装饰器模式(Decorator Pattern) 定义 装饰(Decorator)模式…

前端开发如何自己开发组件库

好多前端小伙伴干了五六年&#xff0c;一直在做切图仔&#xff0c;一看项目没啥亮点。今天开始&#xff0c;我就分享下自己开发组件库的历程。 注&#xff1a;文章会持续更新 环境 "dumi": "^2.2.0","father": "^4.1.0",这里我们站在巨…

消息中间件之八股面试回答篇:一、问题概览+MQ的应用场景+RabbitMQ如何保证消息不丢失(生产者确认机制、持久化、消费者确认机制)+回答模板

问题概览 目前主流的消息队列技术&#xff08;MQ技术&#xff09;分为RabbitMQ和Kafka&#xff0c;其中深蓝色为只要是MQ&#xff0c;一般都会问到的问题。浅蓝色是针对RabbitMQ的特性的问题。蓝紫色为针对Kafka的特性的问题。 MQ的应用场景 MQ主要提供的功能为&#xff1a;异…

Database history tablesupgraded

zabbix升级到6之后&#xff0c;配置安装完成会有一个红色输出&#xff0c;但是不影响zabbix使用&#xff0c;出于强迫症&#xff0c;找到了该问题的解决方法。 Database history tables upgraded: No. Support for the old numeric type is deprecated. Please upgrade to nume…

【新课上架】安装部署系列Ⅲ—Oracle 19c Data Guard部署之两节点RAC部署实战

01 课程介绍 Oracle Real Application Clusters (RAC) 是一种跨多个节点分布数据库的企业级解决方案。它使组织能够通过实现容错和负载平衡来提高可用性和可扩展性&#xff0c;同时提高性能。本课程基于当前主流版本Oracle 19cOEL7.9解析如何搭建2节点RAC对1节点单机的DATA GU…

LLM之RAG实战(二十一)| 使用LlamaIndex的Text2SQL和RAG的功能分析产品评论

亚马逊和沃尔玛等电子商务平台上每天都有大量的产品评论&#xff0c;这些评论是反映消费者对产品情绪的关键接触点。但是&#xff0c;企业如何从庞大的数据库获得有意义的见解&#xff1f; 我们可以使用LlamaIndex将SQL与RAG&#xff08;Retrieval Augmented Generation&#x…

中国县域统计年鉴,含县市卷和乡镇卷,时间覆盖2001-2022年

数据名称: 中国县域统计年鉴 数据格式: pdf、xls不定 数据时间: 2001-2022年 数据几何类型: 文本 数据坐标系: —— 数据来源&#xff1a;国家统计局 数据字段: 中国县域统计年鉴&#xff08;县市卷&#xff09;中国县域统计年鉴&#xff08;乡镇卷&#xff09;目录…

Unity - 将项目转为HDRP

Camera window -> Package Manager 之后会出现HDRP向导窗口&#xff0c;均点击修复。 在Edit中&#xff0c;更改项目中的材质

科技发展趋势,墨水屏电子桌牌将发挥更重要作用

随着科技的不断发展&#xff0c;电子桌牌作为信息展示和宣传的新型设备&#xff0c;逐渐在各个行业得到广泛应用。在国企单位、政府部门、大企业、外企等&#xff0c;墨水屏电子桌牌作为一种新型的数字化展示工具&#xff0c;也已经得到了越来越多的应用。下面&#xff0c;中科…

【Leetcode】2865. 美丽塔 I

文章目录 题目思路代码结果 题目 题目链接 给你一个长度为 n 下标从 0 开始的整数数组 maxHeights 。 你的任务是在坐标轴上建 n 座塔。第 i 座塔的下标为 i &#xff0c;高度为 heights[i] 。 如果以下条件满足&#xff0c;我们称这些塔是 美丽 的&#xff1a; 1 < hei…

【前端web入门第一天】02 HTML图片标签 超链接标签

文章目录: 1.HTML图片标签 1.1 图像标签-基本使用1.2 图像标签-属性1.3 路径 1.3.1 相对路径 1.3.2 绝对路径 2.超链接标签 3.音频标签 4.视频标签 1.HTML图片标签 1.1 图像标签-基本使用 作用:在网页中插入图片。 <img src"图片的URL">src用于指定图像…