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

news2024/11/15 17:15:31

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的名称。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

国民技术N32G430C8开发笔记一-新建IAR工程

一、创建IAR工程 1、新建工程&#xff0c;保存到project文件夹。 2、添加SDK到工程。 根据原厂SDK的文件结构在IAR新建相应分组&#xff0c;把各个文件夹的文件加载进去&#xff0c;其中startup文件选择IAR平台的startup_n32g430_EWARM.s。 3、添加头文件路径&#xff0…

springboot124中药实验管理系统设计与实现

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的中药实验管理系统设计与实现 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章…

Java 枚举和注解

一、枚举类 把具体的对象一个一个例举出来的类就称为枚举类 枚举对应英文(enumeration, 简写 enum)枚举是一组常量的集合。可以这里理解&#xff1a;枚举属于一种特殊的类&#xff0c;里面只包含一组有限的特定的对象。 1.实现方式1——自定义类实现枚举 public class Enume…

HarmonyOS 讨论一下 TextInput的inputFilter正则表达式解决方案

我们 TextInput组件中有这样一个属性 inputFilter 按官方文档的描述 它有两个行参 第一个是字符串类型的 就是 正则表达式 你要怎么去匹配内容 然后 第二个是一个函数 它可以接到一个行参 如果错误时 第二个参数的方法才会执行 行参字符串类型输出被过滤的无效内容 我们可以这…

力扣hot100 两数相加 链表 思维

Problem: 2. 两数相加 Code ⏰ 时间复杂度: O ( n ) O(n) O(n) &#x1f30e; 空间复杂度: O ( n ) O(n) O(n) /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.…

【代码随想录】刷题笔记Day53

前言 不用开组会的我是多么阳光开朗&#xff0c;这周就要离开杭州回家啦&#xff0c;多刷题刷题 115. 不同的子序列 - 力扣&#xff08;LeetCode&#xff09; dp[i][j] 以i-1为结尾的s子序列中出现以j-1为结尾的t的个数为dp[i][j]递推公式 dp[i][j] dp[i - 1][j - 1] dp[i…

前端动画特效分享(附效果图及在线演示)

分享7款有趣也实用的前端动画特效 其中有CSS动画、canvas动画、js小游戏等等 下方效果图可能不是特别的生动 那么你可以点击在线预览进行查看相应的动画特效 同时也是可以下载该资源的 SVG天气图标动画特效 SVG天气图标动画特效 不管是晴天雨天等都很完美的展示出了各自真实的…

Linux——shell程序的简单实现

shell程序的简单实现 本章思维导图&#xff1a; 注&#xff1a;本章思维导图对应的.xmind和.png文件都已同步导入至资源&#xff0c;可免费查阅 在学习完有关进程的知识后&#xff0c;我们就可以开始尝试自己实现一个简单的shell程序了。 注&#xff1a;在编写简单的shell程…

R语言-检验正态性

1.为什么要检验正态性 首先需要明确正态性与正态分布是有区别的&#xff0c;正态分布&#xff08;标准分布&#xff09;是统计数据的分布方式&#xff0c;是个钟形曲线&#xff0c;已平均值为对称轴&#xff0c;数据在对称轴两侧对称分布。正态性是检验实际数据与标准正态分布…

基于Java SSM框架实现在线考试系统项目【项目源码+论文说明】

基于java的SSM框架实现在线考试系统演示 摘要 21世纪的今天&#xff0c;随着社会的不断发展与进步&#xff0c;人们对于信息科学化的认识&#xff0c;已由低层次向高层次发展&#xff0c;由原来的感性认识向理性认识提高&#xff0c;管理工作的重要性已逐渐被人们所认识&#…

字符金字塔(C语言刷题)

个人博客主页&#xff1a;https://blog.csdn.net/2301_79293429?typeblog 专栏&#xff1a;https://blog.csdn.net/2301_79293429/category_12545690.html 题目描述 请打印输出一个字符金字塔&#xff0c;字符金字塔的特征请参考样例 输入描述: 输入一个字母&#xff0c;保…

06.搭建一个自己的私有仓库-Gitea

06.搭建一个自己的私有仓库-Gitea | DLLCNX的博客 如果你是一位程序员或者IT相关领域的从业者&#xff0c;那么肯定知道git&#xff0c;而且也或多或少接触了不少开源仓库以及公司的私有仓库&#xff0c;但是我们有没有想过自己也搭建一个私有仓库呢。 这么多开源仓库&#xf…

C++练习题1-9

文章目录 NO1、选出妃子、宫女和嬷嬷No2、根据数字判断月份No3、循环计数No4、循环选数No5、玩转字符No6、计算字符串长度No7、显示字符串中的字符No8、字符串反转No9、二维数组的应用 NO1、选出妃子、宫女和嬷嬷 其他要求&#xff1a; 超女用结构体表示不要嵌套if输入所有数据…

【数据结构】72变的双端队列

双端队列 前言一、双端队列1.1 双端队列的定义1.2 输入受限的双端队列1.3 输出受限的双端队列1.5 输入输出都受限的双端队列1.6 小结 二、双端队列的使用2.1 双端队列的出队序列——暴力求解2.1.1 栈的出栈序列2.1.2 输入受限的双端队列2.1.3 输出受限的双端队列2.1.4 输入输出…

JCL中常用的DD语句

JCL中的DD语句介绍 ​ DD语句&#xff0c;主要定义数据集用的&#xff0c;也叫做DATASET DEFINE&#xff0c;分为定义设备的UNIT、VOLUME、SPACE&#xff0c;定义数据集的DSN、DISP、DCB,详细可以看英文版的《MVS JCL Reference》&#xff0c;还有一些特殊的DD&#xff0c;暂时…

一文掌握!九大提升 ECS 实例操作系统安全性技巧

云布道师 引言&#xff1a;【弹性计算技术公开课——ECS 安全季】第二节课程由阿里云弹性计算技术专家陈怀可带来&#xff0c;本文内容整理自他的课程&#xff0c;供各位阅览。 安全事件案例回顾与操作系统安全概念介绍 在介绍操作系统安全概念前&#xff0c;我们先来看一下…

每次打开都是:已在调试程序中暂停的处理

点击F12&#xff0c;把这个勾选去掉就可以了。

网安培训第二期——sql注入+中间件+工具

文章目录 宽字节注入插入注入二次注入PDO模式(动态靶机&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;)sql注入读取文件sql注入导出文件linux命令 10.12笔记sqlmapsqlmap参数 10.13笔记sqlmap 文件读写前后缀常用tamper及适用场景 10.…

操作系统-线程的概念(什么是线程 为什么线程共享进程资源 为什么线程切换开销低 引入线程的变化 线程属性 为啥要引入线程)

文章目录 总览什么是线程&#xff0c;为什么要引入线程引入线程机制的变化线程的属性 总览 什么是线程&#xff0c;为什么要引入线程 此时qq进程内的视频文字聊天传输文件可以同时进行&#xff0c;如果进程内部是顺序执行的话&#xff0c;那么将某一时刻只能执行一个功能&…

C语言王道练习题第七周两题

第一题 Description 输入一个学生的学号&#xff0c;姓名&#xff0c;性别&#xff0c;用结构体存储&#xff0c;通过 scanf 读取后&#xff0c;然后再 通过 printf 打印输出 Input 学号&#xff0c;姓名&#xff0c;性别&#xff0c;例如输入 101 xiongda m Output 输出…