【在Linux世界中追寻伟大的One Piece】应用层协议HTTP

news2024/9/20 5:52:52

目录

1 -> HTTP协议

2 -> 认识URL

2.1 -> urlencode和urldecode

3 -> HTTP协议请求与响应格式

3.1 -> HTTP请求

3.2 -> HTTP响应

4 -> HTTP的方法

4.1 -> HTTP常见方法

5 -> HTTP的状态码

6 -> HTTP常见Header

7 -> 最简单的HTTP服务器

8 -> HTTP历史及版本核心技术与时代背景


1 -> HTTP协议

虽然我们说,应用层协议是我们程序猿自己定的。但实际上,已经有大佬们定义了一些现成的,又非常好用的应用层协议,供我们直接参考使用。HTTP(超文本传输协议)就是其中之一。

在互联网世界中,HTTP(HyperText Transfer Protocol,超文本传输协议)是一个至关重要的协议。它定义了客户端(如浏览器)与服务器之间如何通信,以交换或传输超文本(如HTML文档)。

HTTP协议是客户端与服务器之间通信的基础。客户端通过HTTP协议向服务器发送请求,服务器收到请求后处理并返回响应。HTTP协议是一个无连接、无状态的协议,即每次请求都需要建立新的连接,且服务器不会保存客户端的状态信息。

2 -> 认识URL

平时我们俗称的"网址"其实就是说的URL。

2.1 -> urlencode和urldecode

像 / ?:等这样的字符,已经被url当做特殊意义理解了。因此这些字符不能随意出现。比如,某个参数中需要带有这些特殊字符,就必须先对特殊字符进行转义。

转义的规则如下:

将需要转码的字符转为16进制,然后从右到左,取4位(不足4位直接处理),每2位做一位,前面加上%,编码成%XY格式。

例如:

"+"被转义成了"%2B"。

urldecode就是urlencode的逆过程

3 -> HTTP协议请求与响应格式

3.1 -> HTTP请求

  • 首行:[方法] + [url] + [版本]。
  • Header:请求的属性,冒号分割的键值对;每组属性之间使用\r\n分隔;遇到空行表示Header部分结束。
  • Body:空行后面的内容都是Body。Body允许为空字符串。如果Body存在,则在Header中会有一个Content-Length属性来标识Body的长度。

3.2 -> HTTP响应

  • 首行:[版本号] + [状态码] + [状态码解释]。
  • Header:请求的属性,冒号分割的键值对;每组属性之间使用\r\n分隔;遇到空行表示Header部分结束。
  • Body:空行后面的内容都是Body。Body允许为空字符串。如果Body存在,则在Header中会有一个Content-Length属性来标识Body的长度;如果服务器返回了一个html页面,那么html页面内容就是在body中。

基本的应答格式

4 -> HTTP的方法

方法说明支持的HTTP协议版本
GET获取资源1.0、1.1
POST传输实体主体1.0、1.1
PUT传输文件1.0、1.1
HEAD获得报文首部1.0、1.1
DELETE删除文件1.0、1.1
OPTIONS询问支持的方法1.1
TRACE追踪路径1.1
CONNECT要求用隧道协议连接代理1.1
LINK建立和资源之间的联系1.0
UNLINE断开连接关系1.0

其中最常用的就是GET方法和POST方法。 

4.1 -> HTTP常见方法

1. GET方法

  • 用途:用于请求URL指定的资源。
  • 示例:GET /index.html HTTP/1.1
  • 特性:指定资源经服务器端解析后返回响应内容。
  • form表单:https://www.runoob.com/html/html-forms.html
C++
要通过历史写的http服务器,验证GET方法,这里需要了解一下FORM表单的问题。
这里就要引入web根目录,文件读取的基本操作了
std::string GetFileContentHelper(const std::string &path)
{
        // 一份简单的读取二进制文件的代码
        std::ifstream in(path, std::ios::binary);
        if (!in.is_open())
                return "";
        in.seekg(0, in.end);
        int filesize = in.tellg();
        in.seekg(0, in.beg);
        std::string content;
        content.resize(filesize);
        in.read((char *)content.c_str(), filesize);
        // std::vector<char> content(filesize);
        // in.read(content.data(), filesize);
        in.close();
        return content;
}

2. POST方法

  • 用途:用于传输实体的主体,通常用于提交表单数据。
  • 示例:POST /submit.cgi HTTP/1.1
  • 特性:可以发送大量的数据给服务器,并且数据包含在请求体中。
  • form表单:https://www.runoob.com/html/html-forms.html
C++
要通过历史写的http服务器,验证POST方法,这里需要了解一下FORM表单的问题。

3. PUT方法

  • 用途:用于传输文件,将请求报文主体中的文件保存到请求URL指定的位置。
  • 示例:PUT /example.html HTTP/1.1
  • 特性:不太常用,但在某些情况下,如RESTful API中,用于更新资源。

4. HEAD方法

  • 用途:与GET方法类似,但不返回报文主体部分,仅返回响应头。
  • 示例:HEAD /index.html HTTP/1.1
  • 特性:用于确认URL的有效性及资源更新的日期时间等。
C++
// curl -i 显示
$ curl -i www.baidu.com
HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: private, no-cache, no-store, proxy-revalidate, no
transform
Connection: keep-alive
Content-Length: 2381
Content-Type: text/html
Date: Sun, 16 Jun 2024 08:38:04 GMT
Etag: "588604dc-94d"
Last-Modified: Sun, 25 Aug 2024 13:27:56 GMT
Pragma: no-cache
Server: bfe/1.0.8.18
Set-Cookie: BDORZ=27315; max-age=86400; domain=.baidu.com; path=/
<!DOCTYPE html>
...
// 使用 head 方法,只会返回响应头
$ curl --head www.baidu.com
HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: private, no-cache, no-store, proxy-revalidate, no
transform
Connection: keep-alive
Content-Length: 277
Content-Type: text/html
Date: Sun, 25 Aug 2024 17:43:38 GMT
Etag: "575e1f71-115"
Last-Modified: Mon, 13 Jun 2016 02:50:25 GMT
Pragma: no-cache
Server: bfe/1.0.8.18

5. DELETE方法

  • 用途:用于删除文件,是PUT的相反方法。
  • 示例:DELETE /example.html HTTP/1.1
  • 特性:按请求URL删除指定的资源。

6. OPTIONS方法

  • 用途:用于查询针对请求URL指定的资源支持的方法。
  • 示例:OPTIONS * HTTP/1.1
  • 特性:返回允许的方法,如GET、POST等。

不支持的效果

C++
// 搭建一个 nginx 用来测试
// sudo apt install nginx
// sudo nginx -- 开启
// ps ajx | grep nginx -- 查看
// sudo nginx -s stop -- 停止服务
$ sudo nginx -s stop
$ ps ajx | grep nginx
2944845 2945390 2945389 2944845 pts/1
2945389 S+
1002
0:00
grep --color=auto nginx
$ sudo nginx
$ ps axj | grep nginx
1 2945393 2945393 2945393 ?
-1 Ss
0
0:00
nginx: master process nginx
2945393 2945394 2945393 2945393 ?
-1 S
33
0:00
nginx: worker process
2945393 2945395 2945393 2945393 ?
-1 S
33
0:00
nginx: worker process
2944845 2945397 2945396 2944845 pts/1
2945396 S+
1002
0:00
grep --color=auto nginx
// -X(大 x) 指明方法
$ curl -X OPTIONS -i http://127.0.0.1/
HTTP/1.1 405 Not Allowed
Server: nginx/1.18.0 (Ubuntu)
Date: Sun, 25 Aug 2024 08:48:22 GMT
Content-Type: text/html
Content-Length: 166
Connection: keep-alive
<html>
<head><title>405 Not Allowed</title></head>
<body>
<center><h1>405 Not Allowed</h1></center>
<hr><center>nginx/1.18.0 (Ubuntu)</center>
</body>
</html>

支持的效果

C++
HTTP/1.1 200 OK
Allow: GET, HEAD, POST, OPTIONS
Content-Type: text/plain
Content-Length: 0
Server: nginx/1.18.0 (Ubuntu)
Date: Sun, 25 Aug 2024 09:04:44 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
// 注意:这里没有响应体,因为 Content-Length 为 0

5 -> HTTP的状态码

类别原因短语
1XXInformational(信息性状态码)接收的请求正在处理
2XXSuccess(成功状态码)请求正常处理完毕
3XXRedirection(重定向状态码)需要进行附加操作以完成请求
4XXClient Error(客户端错误状态码)服务器无法处理请求
5XXServer Error(服务器错误状态码)服务器处理请求出错

最常见的状态码,比如 200(OK),404(Not Found),403(Forbidden),302(Redirect,重定向),504(Bad Gateway)。

状态码含义应用样例
100Continue上传大文件时,服务器告诉客户端可以继续上传。
200OK访问网站首页,服务器返回网页内容。
201Created发布新文章,服务器返回文章创建成功的信息。
204No Content删除文章后,服务器返回“无内容”表示操作成功。
301Moved Permanently网站换域名后,自动跳转到新域名;搜索引擎更新网站链接时使用。
302Found或See Other用户登录成功后,重定向到用户首页
304Not Modified浏览器缓存机制,对未修改的资源返回304状态码。
400Bad Request填写表单时,格式不正确导致提交失败。
401Unauthorized访问需要登录的页面时,未登录或认证失败。
403Forbidden尝试访问有没有权限查看的页面
404Not Found访问不存在的网页链接
500Internal Server Error服务器崩溃或数据库错误导致页面无法加载
502Bad Gateway使用代理服务器时,代理服务器无法从上游服务器获取有效响应。
503Service Unavailable服务器维护或过载,暂时无法处理请求。

以下是仅包含重定向相关状态码的表格:

状态码含义是否临时重定向应用样例
301Moved Permanently否(永久重定向)网站换域名后,自动跳转到新域名;搜索引擎更新网站链接时使用。
302Found或See Other是(临时重定向)用户登录成功后,重定向到用户首页。
307Temporary Redirect是(临时重定向)临时重定向资源到新的位置(较少使用)。
308Permanent Redirect否(永久重定向)永久重定向资源到新的位置(较少使用)。

关于重定向的验证,以301为代表:

HTTP状态码301(永久重定向)和302(临时重定向)都依赖Location选项。以下是关于两者依赖Location选项的详细说明:

HTTP状态码301(永久重定向):

  • 当服务器返回HTTP 301状态码时,表示请求的资源已经被永久移动到新的位置。
  • 在这种情况下,服务器会在响应中添加一个Location头部,用于指定资源的新位置。这个Location头部包含了新的URL地址,浏览器会自动重定向到该地址。
  • 例如,在HTTP响应中,可能会看到类似于以下的头部信息。
C++
HTTP/1.1 301 Moved Permanently\r\n
Location: https://www.new-url.com\r\n

HTTP状态码302(临时重定向):

  • 当服务器返回HTTP 302状态码时,表示请求的资源临时被移动到新的位置。
  • 同样地,服务器也会在响应中添加一个Location头部来指定资源的新位置。浏览器会暂时使用新的URL进行后续的请求,但不会缓存这个重定向。
  • 例如,在HTTP响应中,可能会看到类似于以下的头部信息。
C++
HTTP/1.1 302 Found\r\n
Location: https://www.new-url.com\r\n

总结:无论是HTTP 301还是HTTP 302重定向,都需要依赖Location选项来指定资源的新位置。这个Location选项是一个标准的HTTP响应头部,用于告诉浏览器应该将请求重定向到哪个新的URL地址。 

6 -> HTTP常见Header

  •  Content-Type:数据类型(text/html等)。
  • Content-Length:Body的长度。
  • Host:客户端告知服务器,所请求的资源是在哪个主机的哪个端口上。
  • User-Agent:声明用户的操作系统和浏览器版本信息。
  • referer:当前页面是从哪个页面跳转过来的。
  • Location:搭配3XX状态码使用,告诉客户端接下来要去哪里访问。
  • Cookie:用于在客户端存储少量信息。通常用于实现会话(session)的功能。

关于connection报头

HTTP中的Connection 字段是HTTP报文头的一部分,它主要用于控制和管理客户端与服务器之间的连接状态。

核心作用

  • 管理持久连接:Connection 字段还用于管理持久连接(也称为长连接)。持久连接允许客户端和服务器在请求/响应完成后不立即关闭 TCP 连接,以便在同一个连接上发送多个请求和接收多个响应。

持久连接(长连接)

  • HTTP/1.1:在HTTP/1.1协议中,默认使用持久连接。当客户端和服务器都不明确指定关闭连接时,连接将保持打开状态,以便后续的请求和响应可以复用同一个连接。
  • HTTP/1.0:在HTTP/1.0协议中,默认连接是非持久的。如果希望在HTTP/1.0上实现持久连接,需要在请求头中显式设置Connection: keep-alive。

语法格式

  • Connection: keep-alive:表示希望保持连接以复用TCP连接。
  • Connection: close:表示请求/响应完成后,应该关闭TCP连接。

附上一张关于HTTP常见header的表格:

字段名含义样例
Accept客户端可接受的响应内容类型

Accept:

text/html,application/xhtml+xml,app

lication/xml;q=0.9,image/webp,image

/apng,*/*;q=0.8

Accept-Encoding客户端支持的数据压缩格式Accept-Encoding: gzip, deflate, br
Accept-Language客户端可接受的语言类型Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Host请求的主机名和端口号Host: www.example.com:8080
User-Agent客户端的软件环境信息User-Agent: Mozilla/5.0 (Windows NT
10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like
Gecko) Chrome/91.0.4472.124
Safari/537.36
Cookie客户端发送给服务器的HTTP cookie信息Cookie: session_id=abcdefg12345;
user_id=123
Referer请求的来源URLReferer:
http://www.example.com/previous_pag
e.html
Content-Type实体主体的媒体类型Content-Type: application/x-wwwform-urlencoded (对于表单提交) 或
Content-Type: application/json (对于JSON数据)
Content-Length实体主体的字节大小Content-Length: 150
Authorization认证信息,如用户名和密码Authorization: Basic
QWxhZGRpbjpvcGVuIHNlc2FtZQ== (Base64编码后的用户名:密码)
Cache-Control缓存控制指令请求时:Cache-Control: no-cache 或
Cache-Control: max-age=3600;响应
时:Cache-Control: public, max-age=3600
Connection请求完后是关闭还是保持连接Connection: keep-alive 或
Connection: close
Date请求或响应的日期和时间Date: Sun, 25 Aug 2024 19:11:00 GMT
Location重定向的目标URL(与3XX状态码配合使用)Location:
http://www.example.com/new_location
.html (与 302 状态码配合使用)
Server服务器类型Server: Apache/2.4.41 (Unix)
Last-Modified资源的最后修改时间Last-Modified: Sun, 25 Aug 2024
19:29:00 GMT
ETag资源的唯一标识符,用于缓存ETag: "3f80f-1b6-5f4e2512a4100"
EXpires响应过期的日期和时间Expires: Sun, 25 Aug 2024 19:28:00GMT

7 -> 最简单的HTTP服务器

实现一个最简单的HTTP服务器,只在网页上输出"hello world";只要我们按照HTTP协议的要求构造数据,就很容易能做到。

#define _CRT_SECURE_NO_WARNINGS 1

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void Usage() 
{
	printf("usage: ./server [ip] [port]\n");
}

int main(int argc, char* argv[]) 
{
	if (argc != 3) 
	{
		Usage();

		return 1;
	}

	int fd = socket(AF_INET, SOCK_STREAM, 0);
	if (fd < 0) 
	{
		perror("socket");

		return 1;
	}

	struct sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = inet_addr(argv[1]);
	addr.sin_port = htons(atoi(argv[2]));
	int ret = bind(fd, (struct sockaddr*)&addr, sizeof(addr));
	if (ret < 0) 
	{
		perror("bind");

		return 1;
	}

	ret = listen(fd, 10);
	if (ret < 0) 
	{
		perror("listen");

		return 1;
	}

	for (;;) 
	{
		struct sockaddr_in client_addr;
		socklen_t len;
		int client_fd = accept(fd, (struct sockaddr*)&client_addr,
			&len);
		if (client_fd < 0) 
		{
			perror("accept");

			continue;
		}

		char input_buf[1024 * 10] = { 0 }; // 用一个足够大的缓冲区直接把数据读完.
		size_t read_size = read(client_fd, input_buf,
				sizeof(input_buf) - 1);
		if (read_size < 0) 
		{
			return 1;
		}

		printf("[Request] %s", input_buf);

		char buf[1024] = { 0 };
		const char* hello = "<h1>hello world</h1>";

		sprintf(buf, "HTTP/1.0 200 OK\nContent-Length:%lu\n\n%s",
		strlen(hello), hello);

		write(client_fd, buf, strlen(buf));
	}
	return 0;
}

注意:

此处使用9090端口号启动了HTTP服务器。虽然HTTP服务器一般使用80端口,但这只是一个通用的习惯。并不是说HTTP服务器就不能使用其他的端口号。使用chrome测试我们的服务器时,可以看到服务器打出的请求中还有一个GET/favicon.ico HTTP/1.1这样的请求。

8 -> HTTP历史及版本核心技术与时代背景

HTTP(Hypertext Transfer Protocol,超文本传输协议)作为互联网中浏览器和服务器间通信的基石,经历了从简单到复杂、从单一到多样的发展过程。以下将按照时间顺序,介绍HTTP的主要版本、核心技术及其对应的时代背景。

HTTP/0.9

核心技术:

  • 仅支持GET请求方法。
  • 仅支持纯文本传输,主要是HTML格式。
  • 无请求和响应头信息。

时代背景:

  • 1991年,HTTP/0.9版本作为HTTP协议的最初版本,用于传输基本的超文本HTML内容。
  • 当时的互联网还处于起步阶段,网页内容相对简单,主要以文本为主。

HTTP/1.0

核心技术:

  • 引入POST和HEAD请求方法。
  • 请求和响应头信息,支持多种数据格式(MIME)。
  • 支持缓存(cache)。
  • 状态码(status code)、多字符集支持等。

时代背景:

  • 1996年,随着互联网的快速发展,网页内容逐渐丰富,HTTP/1.0版本应运而生。
  • 为了满足日益增长的网络应用需求,HTTP/1.0增加了更多的功能和灵活性。
  • 然而,HTTP/1.0的工作方式是每次TCP连接只能发送一个请求,性能上存在一定局限。

HTTP/1.1

核心技术:

  • 引入持久连接(persistent connection),支持管道化(pipelining)。
  • 允许在单个TCP连接上进行多个请求和响应,提高了性能。
  • 引入分块传输编码(chunked transfer encoding)。
  • 支持Host头,允许在一个IP地址上部署多个Web站点。

时代背景:

  • 1999年,随着网页加载的外部资源越来越多,HTTP/1.0的性能问题愈发突出。
  • HTTP/1.1通过引入持久连接和管道化等技术,有效提高了数据传输效率。
  • 同时,互联网应用开始呈现出多元化、复杂化的趋势,HTTP/1.1的出现满足了这些需求。

HTTP/2.0

核心技术:

  • 多路复用(multiplexing),一个TCP连接允许多个HTTP请求。
  • 二进制帧格式(binary framing),优化数据传输。
  • 头部压缩(header compression),减少传输开销。
  • 服务器推送(server push),提前发送资源到客户端。

时代背景:

  • 2015年,随着移动互联网的兴起和云计算技术的发展,网络应用对性能的要求越来越高。
  • HTTP/2.0通过多路复用、二进制帧格式等技术,显著提高了数据传输效率和网络性能。
  • 同时,HTTP/2.0还支持加密传输(HTTPS),提高了数据传输的安全性。

HTTP/3.0

核心技术:

  • 使用QUIC协议替代TCP协议,基于UDP构建的多路复用传输协议。
  • 减少了TCP三次握手及TLS握手时间,提高了连接建立速度。
  • 解决了TCP中的线头阻塞问题,提高了数据传输效率。

时代背景:

  • 2022 年,随着5G、物联网等技术的快速发展,网络应用对实时性、可靠性的要求越来越高。
  • HTTP/3.0通过使用QUIC协议,提高了连接建立速度和数据传输效率,满足了这些需求。
  • 同时,HTTP/3.0还支持加密传输(HTTPS),保证了数据传输的安全性。

感谢各位大佬支持!!!

互三啦!!!

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

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

相关文章

Linux系统报错“version ‘GLIBC_2.34‘ not found”解决方法

注意&#xff0c;此文章慎用&#xff0c;glibc不可随意升级&#xff0c;可能导致系统崩溃 一、查看版本 ldd --version 二、添加高版本源 sudo vi /etc/apt/sources.list.d/my.list 进入编辑页面 "i"键进入插入模式 输入源 deb http://th.archive.ubuntu.com/…

【信创】推荐一款超级好用的文件同步备份工具 _ 统信 _ 麒麟 _ 方德

往期好文&#xff1a;【信创】统信UOS打包工具介绍与使用教程 Hello&#xff0c;大家好啊&#xff01;今天给大家推荐一款在Linux系统上超级好用的文件同步和备份工具——FreeFileSync。无论是在日常工作还是数据管理中&#xff0c;文件同步和备份都是至关重要的任务。FreeFile…

【自动驾驶】控制算法(五)连续方程离散化与离散LQR原理

写在前面&#xff1a; &#x1f31f; 欢迎光临 清流君 的博客小天地&#xff0c;这里是我分享技术与心得的温馨角落。&#x1f4dd; 个人主页&#xff1a;清流君_CSDN博客&#xff0c;期待与您一同探索 移动机器人 领域的无限可能。 &#x1f50d; 本文系 清流君 原创之作&…

QT6 setCentralWidget 和 takeCentralWidget

qt6 中&#xff0c;初始化界面完成之后&#xff0c;可以使用setCentralWidget 设置当前的widget为中心页面 如果你存在多个widget想要多个切换 如果存在widget1 和 widget2 在初始化的时候 setCentralWidget(widget1)触发操作切换到 widget2 如果没有先takeCentralWidget 直…

13.深入解析ThreadPoolExecutor线程池

ThreadPoolExecutor线程池 线程池简介线程池的使用创建线程池ThreadPoolExecutor——推荐使用线程池的核心参数 Executors——不推荐使用 提交任务如何执行批量任务如何执行定时、延时任务如何执行周期、重复性任务 关闭线程池线程池的参数设计分析核心线程数(corePoolSize)最大…

EEMD-MPE-KPCA-BiLSTM、EEMD-MPE-BiLSTM、EEMD-PE-BiLSTM故障识别、诊断(Matlab)

EEMD-MPE-KPCA-BiLSTM(集合经验分解-多尺度排列熵-核主元分析-双向长短期网络)故障识别、诊断&#xff08;Matlab) 目录 EEMD-MPE-KPCA-BiLSTM(集合经验分解-多尺度排列熵-核主元分析-双向长短期网络)故障识别、诊断&#xff08;Matlab)效果一览基本介绍程序设计参考资料 效果一…

RK3588人工智能开发----【1】初识NPU

NPU 的诞生&#xff01; 随着人工智能和大数据时代的到来&#xff0c;传统嵌入式处理器中的CPU和GPU逐渐无法满足日益增长的深度学习需求。为了应对这一挑战&#xff0c;在一些高端处理器中&#xff0c;NPU&#xff08;神经网络处理单元&#xff09;也被集成到了处理器里。NPU的…

【GNSS射频前端】MA2769初识

MAX2769 芯片概述&#xff1a; MAX2769是一款单芯片多系统GNSS接收器&#xff0c;采用Maxim的低功耗SiGe BiCMOS工艺技术。集成了包括双输入低噪声放大器&#xff08;LNA&#xff09;、混频器、图像拒绝滤波器、可编程增益放大器&#xff08;PGA&#xff09;、压控振荡器&#…

note38:tdsql数据库迁移

数据迁移过程中遇到的具体问题&#xff1a; ①提供给系统团队的表结构与生产不一致&#xff0c;导致脚本报错。因为历史遗留问题&#xff0c;存在部分直接在生产环境更改字段长度或添加索引的情况&#xff0c;导致测试环境和生产环境的表结构不同步。 今后所有生产的变动&…

Vulkan 学习(5)---- Vulkan 内存分配

目录 Overview枚举内存信息分配内存内存映射 Overview Vulkan 将内存管理的工作交给了开发者自己负责&#xff0c;如何分配内存&#xff0c;如何指定内存策略都是由开发者自己决定的&#xff0c;当然处理问题也是由开发者自己负责的 Vulkan 将内存划分为两大类&#xff1a;主…

Android自定义简单仿QQ运动步数进展圆环

实现效果主要效果分为三个部分&#xff1a; 1.固定蓝色的大圆弧 color borderWidth 2.可以变化的小圆弧(红色) color borderWidth 3.中间的步数文字 color textSize drawArc方法 startAngle 确定角度的起始位置 sweepAngle 确定扫过的角度 useCenter 是否使用中心&#xff1a…

MyBatis XML配置文件(下)

MyBatis的开发有两种方式&#xff1a;1、注解 2、XML。使用MyBatis的注解方式&#xff0c;主要是来完成一些简单的增删改查功能。如果需要实现复杂的SQL功能&#xff0c;建议使用XML来配置映射语句&#xff0c;也就是将SQL语句写在XML配置文件中。 MyBatis XML开发的方式需要以…

UE5学习笔记17-让人物的视线和鼠标移动时的方向一致,并且不让人物模型旋转,只改变视线方向

一、创建标准动画帧 1.我想让人物在装备武器后根据鼠标的移动方向改变人物的视线方向&#xff0c;并且人物模型不会改变朝向 2.我的动画中存在一个四个方向瞄准的动画&#xff0c;将左下&#xff0c;坐上&#xff0c;左转&#xff0c;右上&#xff0c;右下&#xff0c;右转&…

C++ 设计模式——组合模式

C 设计模式——组合模式 C 设计模式——组合模式1. 主要组成成分2. 逐步构建透明组合模式1. 定义抽象组件&#xff08;Component&#xff09;2. 实现叶子组件&#xff08;Leaf&#xff09;3. 实现组合组件&#xff08;Composite&#xff09;4. 主函数&#xff08;Main&#xff…

Nacos踩坑

最近遇到项目部署&#xff0c;遇到Nacos中的配置读取不到&#xff0c;导致服务起不来。服务器银河麒麟x86&#xff0c;Nacos版本2.3.2, openJdk8u43 报错如下&#xff1a; java.lang.UnsatisfiedLinkError: no com_alibaba_nacos_shaded_io_grpc_netty_shaded_netty_transport…

Linux磁盘操作之du命令

使用du命令&#xff0c;您可以查看指定目录或文件的磁盘使用量总计。这对于了解特定目录或文件占用的磁盘空间大小非常有用&#xff0c;可以帮助您进行磁盘空间管理和清理。 参数说明 du是一个用于显示目录或文件的磁盘使用情况的命令&#xff0c;du是disk usage的缩写&#…

从图像到视频:Web Codecs API编码技术解析

初探Web Codecs API 三 前言 在之前的文章中,咱们简单的介绍了解码相关的东西,这一节咱们来简单聊聊编码相关的东西。 编码的目的就是为了压缩,去除空间、时间维度的冗余。 这里又不得不提起前面所说的I 帧、P 帧、B 帧和 IDR 帧。 众所周知,视频是连续的图像序列,由…

【添加核心机械臂动力学】Model and Control a Manipulator Arm with Robotics and Simscape

机械臂动力学 为了设计控制器&#xff0c;机械臂动力学必须表示给定力矩输入的关节位置。这在机械臂动力学子系统中通过一个前向动力学块实现&#xff0c;该块将关节力矩转换为给定当前状态的关节加速度&#xff0c;然后通过两次积分得到完整的关节配置。积分器初始化为q0和dq…

自闭症托管托养机构:星贝育园的优势与使命

在当今社会&#xff0c;自闭症儿童作为一群需要特别关注和照顾的群体&#xff0c;其教育与康复问题日益受到社会各界的重视。自闭症托管托养机构作为这一领域的重要力量&#xff0c;承担着为自闭症儿童提供全方位、个性化支持的重任。星贝育园&#xff0c;作为一所全日寄宿制的…

使用libsvm时遇到MATLAB has encountered an internal problem and needs to close

最近在MATLAB中使用libsvm跑别人的程序&#xff0c;该程序在大部分数据集上可以正常运行&#xff0c;但在有一个数据集上运行时MATLAB会报“MATLAB has encountered an internal problem and needs to close”的错误&#xff1a; 凭直觉猜应该是数据集有啥问题&#xff0c;但又…