协议是通信双方必须遵守的规则,确保数据能够正确传输和解析,它规定了数据格式、传输顺序、错误处理等细节。应用层的协议一般都是我们自己进行定义的,但是有很多程序员前辈已经写出来了很哇塞的协议,我们直接进行学习和使用即可

HTTP协议

认识URL

初识URL

URL(Uniform Resource Locator,统一资源定位符就是我们口中的网址,是用来标识和定位互联网上的资源的字符串,这里的资源包括文本、图片视频等等。

URL的结构

服务器地址其实就是IP地址,IP地址标定主机的唯一性,通过IP地址和特定端口号就可以和服务器进行建立链接,通过文件路径就可以申请访问服务器特定路径下的资源信息

http就是通过http协议进行访问服务器的资源,我们能够在网络上能够进行看到的就是资源,既然是资源就需要进行存储,服务器中的资源当然也不例外,服务器中的资源当然存在于服务器的磁盘上,所以要想进行访问服务器中的资源就是要找到资源的特定路径进行访问。

urlencode和urldecode

enlencode

在URL中 ‘ / ’和 ‘ ?’是有特殊含义的分隔符,对于斜杠“/”,应该说明它在路径中的分层作用,比如如何表示资源的位置结构,还可能提到根目录和相对路径的区别;关于问号“?”,需要明确它是查询参数的起始符,后面跟着键值对,多个参数用“&”连接。当我们需要进行使用这些特殊符号进行当作我们的内容怎么办?岂不是会将这个内容当作分隔符进行处理然后造成内容出现差错??当然不会,URL会进行将特殊字符进行转义。

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

URL 中某些字符(如空格、中文)需转义为 % 后跟十六进制值(称为 百分号编码)。

示例:空格 → %20,中文字符“你” → %E4%BD%A0

目的是确保 URL 在传输中无歧义,兼容所有系统和协议。

urldecode

http请求和响应的宏观格式

http以行为单位的协议

http 请求的宏观格式

  • 请求行中的数据:请求的方法  请求的URL  请求的版本(1.0  1.1  2.0)
  • 请求报头:存放各种属性(多行)大多数是key -- val的格式
  • http请求的空行
  • 请求正文,请求正文是可以为空的

上述结构整体称为http的报头

http响应的宏观格式

  • 状态行:响应的版本  状态码(请求的正确性) 状态码描述(404->资源不存在)
  • 响应报头:存放服务器的各种属性
  • 空行:
  • 响应正文:一般是服务器中的资源

基于宏观格式的细节问题 

  • http请求和响应是如何进行通信的?

        http请求是通过tcp进行建立链接,然后向服务器进行发送请求;http响应也是通过tcp进行链接socket,向客户端进行返回响应。

  • 请求和响应是如何保证应用层读取完毕了呢??

        写个读一行的函数

        通过while循环,进行读取请求行+请求报头,知道读取到空行为止

        分析读取报头中的属性信息,其中有一条属性信息是正文内容的长度,

        根据解析出来的正文内容,进行读取正文中的属性信息

  • 请求和响应是如何做到序列化和反序列化的?

        这并不需要我们自己进行实现,这是http自己进行实现的,请求行/状态行+请求报头/响应报头只需要进行按照\r\n进行1->即可!

进行编码实现验证

HTTP服务端代码的封装

//HTTP_server.hpp#pragma once
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <functional>
#include <cstring>
#include <unistd.h>
#include <sys/wait.h>
#include "protocol.hpp"
#include "util.hpp"static int gbacklog = 5;
int sockid = -1;
#define SIZE 1024
typedef std::function<bool(const HttpRequest &req, HttpResponse &resp)> func_t;class HttpServer
{
public:HttpServer(func_t func,uint16_t port): _listen_sockid(-1), _port(port),_func(func){}void InitServer(){// 进行创建套接字_listen_sockid = socket(AF_INET, SOCK_STREAM, 0);if (_listen_sockid < 0){exit(1);}std::cout << "listen_sockid:" << _listen_sockid << std::endl;// 进行bind绑定struct sockaddr_in local;memset(&local, 0, sizeof(local));local.sin_family = AF_INET;local.sin_addr.s_addr = INADDR_ANY;local.sin_port = htons(_port);socklen_t len = sizeof(local);int n = bind(_listen_sockid, (struct sockaddr *)&local, len);if (bind < 0){exit(2);}// 设置socket为监听状态                  //哪些客户端申请进行访问“我”(服务器)int m = listen(_listen_sockid, gbacklog);if (m < 0){exit(3);};}void StartServer(){for (;;){// 进行获取链接struct sockaddr_in client;memset(&client, 0, sizeof(client));socklen_t len = sizeof(client);sockid = accept(_listen_sockid, (struct sockaddr *)&client, &len);if (sockid < 0){exit(4);}// 进行通信// 通过创建多进程的方式进行通信pid_t id = fork();if (id == 0){// 子进程close(_listen_sockid);if (fork() > 0){exit(0);}// http处理方法httpHandler(sockid);close(sockid);// exit(0);}close(sockid);waitpid(id, nullptr, 0);}}void httpHandler(int sockid){// 进行获取完整的数据// 进行反序列化// 将反序列化的数据进行处理// 将处理的数据进行序列化// 发送完整的数据// 定义一个缓冲区将数据进行存储char buffer[4096];int n = recv(sockid, buffer, sizeof(buffer) - 1, 0);if (n <= 0){if (n == 0){std::cerr << "对方关闭写通道" << std::endl;}else{std::cerr << "读取数据失败" << std::endl;}}else{buffer[n]=0;HttpRequest req;HttpResponse resp;req.inbuffer = buffer;req.prase();_func(req, resp);send(sockid,resp.outbuffer.c_str(),resp.outbuffer.size(),0);}}~HttpServer(){if (sockid > 0){close(sockid);}}private:uint16_t _port;int _listen_sockid;func_t _func;};

HTTP服务端的调用

//HTTP_server.cpp#include "HTTP_server.hpp"
#include <memory>void Usage(std::string proc)
{std::cerr << "Usage:\n\t" << proc << " port\r\n\r\n";
}//通过suffix和Content-Type进行补充描述信息
std::string suffixToDesc(const std::string suffix)
{std::string ret="Content-Type: ";if(suffix==".html"){ret+="text/html";}else if(suffix==".jpg"){ret += "application/x-jpg";}ret+="\r\n";return ret;
}bool Get(const HttpRequest &req, HttpResponse &resp)
{// for teststd::cout << "----------------------http request start---------------------------" << std::endl;std::cout << req.inbuffer << std::endl;std::cout << "method: " << req.method << std::endl;std::cout << "url: " << req.url << std::endl;std::cout << "httpversion: " << req.httpversion << std::endl;std::cout << "path: " << req.path << std::endl;std::cout << "suffix: " << req.suffix << std::endl;std::cout << "size: " << req.size << std::endl;std::cout << "----------------------http request end---------------------------" << std::endl;std::string respline = "HTTP/1.1 200 OK\r\n";// 这里也不想进行硬编码// std::string respheader = "Content-Type: text/html\r\n";std::string respheader = suffixToDesc(req.suffix);std::string respblank = "\r\n";// 不要进行硬编码// std::string body = "<html lang=\"en\"><head><meta charset=\"UTF-8\"><title>for test</title><h1>hello world</h1></head><body><p>北京交通广播《一路畅通》“交通大家谈”节目,特邀北京市交通委员会地面公交运营管理处处长赵震、北京市公安局公安交通管理局秩序处副处长 林志勇、北京交通发展研究院交通规划所所长 刘雪杰为您解答公交车专用道6月1日起社会车辆进出公交车道须注意哪些?</p></body></html>";// 从文件中进行获得std::string body;body.resize(req.size+1);if (Util::readFile(req.path, (char*)body.c_str(),body.size()) == 0){Util::readFile(error_html, (char*)body.c_str(),body.size());}// 进行填充responseresp.outbuffer += respline;resp.outbuffer += respheader;resp.outbuffer += respblank;std::cout << "----------------------http response start---------------------------" << std::endl;std::cout << resp.outbuffer << std::endl;std::cout << "----------------------http response end---------------------------" << std::endl;resp.outbuffer += body;return true;
}int main(int args, char *argv[])
{if (args != 2){Usage(argv[0]);exit(0);}uint16_t port = atoi(argv[1]);std::unique_ptr<HttpServer> hs(new HttpServer(Get, port));hs->InitServer();hs->StartServer();return 0;
}

HTTP协议有关的封装

//prococal.hpp#pragma once
#include <iostream>
#include <sstream>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>const std::string sep = "\r\n";
const std::string default_root = "./wwwroot";
const std::string home_page = "index.html";
const std::string error_html = "./wwwroot/404.html";
#include "util.hpp"
class HttpRequest
{
public:HttpRequest(){}~HttpRequest(){}void prase(){// 1. 从inbuffer中拿到第一行,分隔符\r\nstd::string line = Util::getOneLine(inbuffer, sep);if (line.empty())return;// 2. 从请求行中提取三个字段// std::cout << "line: " << line << std::endl;std::stringstream ss(line);ss >> method >> url >> httpversion;// 3. 添加web默认路径path = default_root; // ./wwwroot,path += url;         //./wwwroot/a/b/c.html, ./wwwroot/if (path[path.size() - 1] == '/')path += home_page;// 4.进行后缀的查询auto pos = path.rfind(".");if (pos == std::string::npos){suffix = ".html";}else{suffix = path.substr(pos);}// 5.进行获取资源大小struct stat st;int n = stat(path.c_str(), &st);if (n == 0)size = st.st_size;elsesize = -1;}public:std::string inbuffer;// std::string reqline;// std::vector<std::string> reqheader;// std::string body;std::string method;std::string url;std::string httpversion;std::string path;std::string suffix;int size;
};class HttpResponse
{
public:std::string outbuffer;
};

其他有关函数的封装

//util.hpp#pragma once #include<iostream>
#include<string>
#include<fstream>class Util
{
public:static std::string getOneLine(std::string& buffer,const std::string& sep){auto pos=buffer.find(sep);if(pos==std::string::npos){return "";}std::string ret=buffer.substr(0,pos);return ret;}static bool readFile(const std::string path,char* buffer,int size){//以二进制的形式进行打开读取pathstd::ifstream in(path);if(!in.is_open()){return false;}//error:// std::string line;// while(std::getline(in,line))// {//     body+=line;// }in.read(buffer,size);in.close();return true;}
};

通过上面的代码我们可以清晰的得知,网页资源其实是通过多个资源进行整合而成的,我们要进行访问一整个网页资源,需要进行发送若干次的网络请求。

结合代码加强对宏观结构的影响

HTTP方法

http请求不但可以进行获取资源还是可以进行资源的交互的。我们通过http进行向服务端进行数据的上传时,本质事通过form表单进行提交的,浏览器会自动将form表单中的内容转化成http方法进行请求,http常用的两种方法分别是POST/GET方法

POST/GET两种方法的区别

  • GET方法是将用户通过HTTP进行提交的数据直接进行拼接到URL上,也就是说GET方法是通过URL进行传递参数
  • POST方法是将用户通过HTTP进行提交的数据进行放到正文部分,通过正文进行参数的提交

说明:

GET方法进行提交参数由于是通过URL进行提交的,所以说我们通过URL就可以看到我们进行通过HTTP提交的参数,POST由于是通过正文进行提交参数的,所以一般用户是看不到的,私密性正好,但是不敢说通过POST就比通过GET方法安全性更高,我们通过抓包工具都是可以进行看到参数的明文的,要想进行提高安全性,必须进行加密,https就是经过加密之后的。

HTTP状态码

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

3XX是重定向状态码,重定向在网络中的是如何进行理解的呢?

上述这种先进行访问服务器,然后服务器通过返回一个3XX的错误码,并且附带一个新的URL,客户端通过新的URL进行访问的方式称为重定向

重定向分为临时重定向和永久重定向

临时重定向:当我们进行访问某个网站的时候,首先自动为我们进行跳转到广告商金主爸爸那里,之所以称为临时重定向是因为这种跳转URL并不是唯一的,当金主爸爸换人之后进行跳转的链接也就不一样了

永久重定向:与临时重定向不同的是,永久重定向进行跳转的目标每次都是唯一的,例如一个网站慢慢壮大之后由于服务器配置不够用了,需要进行将一些用户进行引流到新的网站,当老用户进行登陆后,通过URL 进行识别,然后跳转新的服务器进行使用,这种方式就是永久重定向。

长链接的概念

通过http进行请求网络资源,由于http网页中的资源是由若干部分进行组成的,按道理也就是说客户端需要多次通过http请求才能完整的获取网页中的资源,但是http协议是应用层的协议是基于传输层的TCP的,TCP是面向链接的,会出现频繁创建链接的问题。

所以说client如果和server都支持长链接,直接通过"一条长链接进行读取大份资源。"进行获取大份资源的理解其实本质上是通过一个TCP连接进行传输多个HTTP请求和响应。

Connection: keep-alive        支持长链接

Connection: close                不支持长连接

会话保持

会话保持的认识

当我们通过浏览器进行通过URL进行访问指定服务器的资源时,首次进行访问时需要进行信息的认证才可以进行访问服务器中的资源,当我们短时间内再次进行访问网站,继续需要用户认证,这对于用户来说体验感是非常差的;当服务器的资源并不是完全部署在一台服务器上的,而是网站文件放在一台服务器,资源(如图片、视频)存放在另一台服务器上,当我们进行访问资源时,每进行访问一个资源就首先开始进行用户认证登录,这是非常非常难受的。

由于HTTP本身是无状态的,为了解决上述用户体验问题,让用户进行登录后就可以按照自己的身份(因为有些资源是有权限的,例如VIP视频)进行随意访问,这种方式就叫做会话保持(保证用户长时间在线)。

会话保持的实现

老方法

cookie文件中存储的信息一般包括用户标识信息(用户ID:唯一标识用户的编号或字符串。用户名:用户的登录名或显示名。会话ID:用于识别用户当前会话的唯一标识符。认证信息(登录状态:标记用户是否已登录,令牌:用于身份验证的令牌)。偏好设置(用户选择的语言、用户选择的界面主题等等)。浏览行为信息(记录用户浏览历史)

补充:cookie是分为cookie文件级别和cookie内存级别,如何进行区分cookie是文件级别还是内存级别,通过以浏览器进行为例,当我们通过进行将浏览器进行访问特定服务器,当我们将浏览器这个进程进行杀掉后,在进行重新打开浏览器进行访问特定的服务器如果不需要重新进行认证登录则cookie就是内存级的,怎么理解呢??如果这个cookie是内存级别的,则这个cookie是存在在进程中的,当进程被杀掉后,则这个cookie就消失了,所以说需要进行重新认证登录。而文件级别的Cookie则被写入到用户电脑的某个文件夹中,比如在Windows系统里可能是特定的目录下。cookie技术分为cookie文件级别(关闭浏览器)和内存级别  ----cookie是内存级别还是文件级别可以在浏览器中进行配置。

老方法可能存在的问题

当一些黑客通过某些方式进行将木马散播出去(例如陌生邮件中的链接等等),当误点进入这个链接中时,木马就会浸入我们的浏览器中进行盗取我们浏览器中cookie文件中的信息,例如访问某些特定服务器中的身份信息(用户ID,账号密码等等),黑客通过拿到这些cookie信息直接模拟用户的身份验证,直接进行访问服务器。

新方法

新方法通过将用户的信息及使用缓存痕迹不在浏览器中进行存储了,直接进行放到服务端中session文件中,当用户首次进行申请该服务器中的资源时,服务器接收到申请后进行返回唯一的session id作为身份验证的信息,在会话保持中通过session id进行身份验证进行访问服务器中的资源。即使黑客进行拿到我们的cookie文件,cookie文件中只是验证信息并没有用户的数据,很大程度上减少了用户数据泄漏的风险。

新方法可能存在的问题

当黑客同样将木马进行散播进入我们的服务器中进行窃取我们的cookie文件,虽然减少了用户数据泄漏的风险,但还是无法进行阻止别人通过cookie文件中的信息进行绕开服务器中的验证进行访问服务器,但是这种方案极易配合其他策略进行增加安全性,例如当服务器进行检测到用户的IP发生短时间的长距离跨越时,会进行向绑定的设备进行推送警告信息,甚至进行强制下线。

HTTPS协议

通过上面两个工具的使用,我们可以看到通过HTTP进行数据的传输,无论GET方法还是POST方法,数据无异于进行裸奔,HTTPS就是通过加密的方式进行解决这种问题

简单认识HTTPS的加密过程

HTTP通过SSL/TLS握手过程中进行实现将HTTP的明文数据进行加密形成的密文数据通过协议栈进行传输到另一台主机,然后通过将数据进行解密进行拿到发送方进行网络通信的内容

数据指纹

数据指纹又称为数据摘要,其基本原理是利用单向散列函数(Hash函数)对信息进行运算,生成一串固定长度的字符串。数据指纹并不是一种加密机制,但是可以用来进行判断数据有没有被篡改。

常见的摘要算法:MD5,SHA1,SHA256,SHA512等,算法将无线映射成有限,因此也是有可能出现哈希碰撞,但是概率是非常非常的低的。

数据指纹是不属于加密过程的,因为加密过程是可逆的能够进行解密,但是数据指纹是通过映射性成的,不能进行可逆的解密过程。

应用:

进行判断两份数据是否是相同的,如果两份数据通过相同的算法进行哈希映射,将映射后的数据进行比对,如果相同则则是同一份数据,反之则是不同的数据

百度网盘的秒传功能就是通过这种方式进行实现的,当用户A进行传入某种资源后,当用户B在进行上传相同的资源时,通过查询数据摘要是否存在,如果数据存在,百度网盘并不会再将相同的资源进行重新上传一份,而是通过建立通过建立软连接的形式进行让用户B进行访问资源.

数据库中的表单行列中的密码行列也是通过某种算法经过Hash映射进行形成数据摘要,即使数据库进行泄漏也较大程度保护用户的隐私.

HTTPS的加密过程

在进行网络通信的过程中,往往会出现数据安全问题,例如数据被监听,数据被篡改,只有通过加密的方式解决这几种问题,通过下面几种方式进行理解对称加密和非对称加密,并且分析各种各种方案的优劣,找出最优加密方式

只采用对称加密

客户端在进行推送数据之前首先将自己密钥进行送,但是在进行推动密钥的过程中,由于密钥是没有进行机密的,容易被中间人进行拿到并拷贝,当服务端在进行通过密钥进行机密数据,让加密的数据在网络中进行传递时,中间人也是有密钥的,直接可以对数据进行监听和修改.

只采用非对称加密

采用非对称加密虽然能够继续宁确保客户端到服务端的数据安全,因为即使中间人进行窃取客户端向服务端的数据,但是无法对加密的数据进行解密,服务端到客户端的数据不安全由于服务端在进行推送自己的公钥给客户端时容易被中间人拿到并拷贝,导致服务端后续进行向客户端进行发送数据的时候容易被篡改,导致后续进行数据传输的时候造成数据不安全问题。 

双方使用非对称加密

双方都采用非堆成的加密方式,每一方都将自己的自己的公钥进行推送给对方,之后在进行数据传输的过程中,都是用对方的公钥进行加密,这样只能通过对应的私钥才能进行解密,即使中间人拿到双发的公钥也无法进行解密,确保数据的安全。

但是这种方式加解密过程依赖复杂的数学运算(如大数分解或椭圆曲线运算),相比对称加密速度慢数百倍,且加密后的数据体积更大,不适合处理大量传输数据。而对称加密算法(如 AES)结构简单、加解密速度快、资源消耗低,适合高效的数据传输

采用非对称加密+对称加密

 这种方式先通过非对称加密进行将客户端的对称密钥进行安全的交给服务端,然后后续直接通过对称加密即可,这种方式并没有将加密的对称密钥进行暴露给中间人,又可以进行高效传输。这种方式兼顾了安全性与性能。

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

浅尝 Spring AI【使用超级简单~】

一直想要体验下 Spring AI&#xff0c;最近自己的一个工具有这个需求&#xff0c;所以这里准备使用下。其实使用起来超级简单。 1.IDEA 新建 Spring项目 1&#xff09;这里可以根据自己的喜好选择 项目名、jdk版本等 2&#xff09;这里选择 在ai中选择 openAI 即可。然后我另…

DDL期间TDSQL异常会话查询造成数据库主备切换

问题描述&#xff1a;7*24联机交易系统&#xff0c;傍晚时分&#xff0c;从客户端后台对3千万行的大表执行缩短varchar类型字段长度的ddl语句&#xff0c;执行期间&#xff0c;为了查看ddl进度&#xff0c;从TDSQL-MySQL赤兔前端页面点击异常会话查询&#xff0c;之后数据库卡住…

弧焊机器人气体全方位节能指南

氩弧焊&#xff08;TIG焊接&#xff09;作为其中一种高效且精密的技术&#xff0c;凭借其稳定性和高质量的焊接效果&#xff0c;在航空航天、汽车制造、船舶建造以及石油化工等领域占据了不可或缺的地位。氩弧焊通过使用惰性气体&#xff08;如氩气&#xff09;保护电弧和熔池&…

数据清洗(ETL/ELT)原理与工具选择指南:企业数字化转型的核心引擎​

目录 一、数据清洗&#xff08;ETL/ELT&#xff09;到底在干啥&#xff1f; 1.揪出并处理异常值 2.把缺失的数据补上&#xff08;或处理好&#xff09; 3.数据转换与标准化 4.一致性校验 二、工具怎么选&#xff1f;看菜吃饭&#xff0c;量体裁衣 1.数据量不大、要求不高…

阿里云服务器,CentOS7.9上安装YApi 接口管理平台

目录 1.node安装 1.1下载node,解压 1.2 部署bin文件 1.3 安装mongodb 2.启动yapi 2.1 前置命令 2.2 启动服务 3.利用pm2方便服务管理维护 3.1.安装pm2 3.2 常用 PM2 命令 4.常见问题 4.1. 确认 MongoDB 是否安装 4.2. 安装 MongoDB&#xff08;若未安装&#xff…

阿里云错题集分享

有最近想要考试阿里云的可以私信我 &#xff0c;一起加油错题集1.在使用阿里云的负载均衡SLB实例时&#xff0c;做了如下健康检查的配置:成功响应和超时响应时间均为1秒&#xff0c;健康检查间隔为2秒&#xff0c;不健康阈值为3&#xff0c;健康阈值为3。即对于确认一个云服务器…

Android 12 - 部分相机横屏显示方案

1.相机过渡界面方向旋转 Android 10 - 相机过渡界面默认角度 同A10 有些区别&#xff0c;再次增加记录修改。 这个文件没有修改&#xff0c;只是说明 src/com/android/camera/CameraActivity.javaprivate void freezeScreenCommon(boolean async) {long startTime System.…

Operation Blackout 2025 Phantom Check hayabusa+ControlSet001+VirtualBox

QAQA攻击者使用哪个 WMI 类来检索型号和制造商信息以进行虚拟化检测&#xff1f;Win32_ComputerSystem攻击者执行了哪个 WMI 查询来检索计算机的当前温度值&#xff1f;SELECT CurrentTemperature FROM MSAcpi_ThermalZoneTemperature攻击者加载了 PowerShell 脚本以检测虚拟化…

《O-PAS™标准的安全方法》白皮书:为工业自动化系统筑起安全防线

The Open Group 最新白皮书《O-PAS™标准的安全方法》重磅发布&#xff0c;为流程工业在迈向开放架构与多供应商互操作的过程中&#xff0c;指明了安全实践的方向。O-PAS™标准的安全方法ABOUT PUBLICATION亮点一&#xff1a;首次系统阐释 O-PAS™ 标准安全方法与 IEC/ISA 6244…

UML 图类型全解析:结构图与行为图分类详解

作为软件架构的核心建模语言&#xff0c;UML&#xff08;统一建模语言&#xff09;通过14种标准图表提供系统多维度视角。这些图表分为结构图&#xff08;静态模型&#xff09; 和 行为图&#xff08;动态模型&#xff09; 两大类&#xff0c;覆盖从需求到实现的完整生命周期。…

lodash不支持 Tree Shaking 而 lodash-es可以

lodash 无法有效支持 Tree Shaking 而 lodash-es 可以&#xff0c;核心区别在于‌模块规范、文件结构和静态分析兼容性‌。以下是具体原因分析&#xff1a; ⚙️ 一、模块规范差异&#xff08;核心原因&#xff09; lodash&#xff08;CommonJS 规范&#xff09;‌ 使用 requir…

java+vue+SpringBoo高校实习信息发布网站(程序+数据库+报告+部署教程+答辩指导)

源代码数据库LW文档&#xff08;1万字以上&#xff09;开题报告答辩稿ppt部署教程代码讲解代码时间修改工具 技术实现 开发语言&#xff1a;后端&#xff1a;Java 前端&#xff1a;vue框架&#xff1a;springboot数据库&#xff1a;mysql 开发工具 JDK版本&#xff1a;JDK1.8 数…

uniApp实战五:自定义组件实现便捷选择

文章目录1.最终效果预览2.快速选择组件封装3.弹框组件封装4.组件逻辑实现5.组件样式6.页面引入1.最终效果预览 2.快速选择组件封装 <uv-cell :border"isShowBorder"><template v-slot:title><text class"title-key">{{ title }}</te…

AI在垂直领域的深度应用:医疗、金融与自动驾驶的革新之路

AI在垂直领域的深度应用:医疗、金融与自动驾驶的革新之路 一、医疗领域:AI驱动的精准诊疗与效率提升 1. 医学影像诊断 AI算法通过深度学习技术,已实现对X光、CT、MRI等影像的快速分析,辅助医生检测癌症、骨折等疾病。例如,Google DeepMind的AI系统在乳腺癌筛查中,误检率…

模块三:现代C++工程实践(4篇)第二篇《性能调优:Profile驱动优化与汇编级分析》

性能调优&#xff1a;Profile驱动优化与汇编级分析实战&#xff1a;优化矩阵乘法至SSE/AVX指令集&#xff08;终极加强版&#xff09;一、性能瓶颈的全链路诊断&#xff08;深度扩展&#xff09;1.1 硬件性能计数器的极致利用PMU事件深度定制&#xff1a;# 捕获L1缓存事件与分支…

二刷 黑马点评 商户查询缓存

缓存 数据交换的缓冲区&#xff0c;俗称的缓存是缓冲区内的数据&#xff0c;一般从数据库中获取&#xff0c; 例1:Static final ConcurrentHashMap<K,V> map new ConcurrentHashMap<>(); 本地用于高并发例2:static final Cache<K,V> USER_CACHE CacheBuild…

【前端】【组件库开发】【原理】【无框架开发】现代网页弹窗开发指南:从基础到优化

效果 现代网页弹窗开发指南&#xff1a;从基础到优化 弹窗&#xff08;Modal&#xff09;作为网页交互的重要组件&#xff0c;在用户通知、确认操作和表单输入等场景中广泛应用。本文将循序渐进地讲解弹窗的技术实现与最佳实践。 一、弹窗基础概念 弹窗是一种覆盖在主内容之…

【操作系统】线程

JavaEE—线程 一、进程与线程 1.包含管理 2.资源布局 2.1公共资源 2.2私有资源 二、并发编程 1.多线程优势 1.1创建 1.1.1多线程 1.1.2多进程 1.2通信 1.2.1多线程 1.2.2多进程 1.3调度 1.3.1多线程 1.3.2多进程 1.4销毁 1.4.1多线程 1.4.2多进程 2.多进程…

React 自定义Hook——页面或元素滚动到底部监听 Hook

功能简介 useReachBottom 是一个 React 自定义 Hook&#xff0c;支持监听页面&#xff08;body&#xff09;或任意可滚动元素&#xff08;如 div&#xff09;是否滚动到底部。它能帮助你在用户滑动到底部时触发加载更多、显示提示等操作&#xff0c;极大提升前端交互体验。 亮…

当Powerbi遇到quickbi,性能优化方式对比

powerbi性能优化对于powerbi&#xff0c;性能优化可以从15个方面考虑&#xff1a; 1.过滤源数据【quickbi数据集过滤或sql过滤】2.删除无关列 【quickbi不选字段或sql不查询】3.聚合分析粒度 【quickbi使用sql聚合或计算字段聚合】4.整理字段 【quickbi使用sql聚合或计算字段聚…