一、什么是 HTTP 协议

        上节说到,应用层的协议需要约定通信的内容和数据格式。我们可以自定义应用层协议,也可以基于现成的应用层协议进行开发。协议的种类很多,最常见的之一就是 HTTP,广泛用于网站和手机 App。准确来说,现在大多使用的是 HTTPS 协议,它在 HTTP 协议上加了安全层。Ps:HTTP 本身不限定数据格式,具体数据格式由应用决定,并通过协议中的 Content-Type 告知。

        之前学习的 TCP、UDP、IP、以太网……都是基于二进制格式的协议(格式按照 xxx 个字节来安排)。HTTP 是“超文本传输协议”,是基于文本格式的协议,但文本中包含了视频、音频、图片、链接等更复杂的内容。HTTP 属于应用层协议,传输层依赖 TCP 进行实现(2.0 及其之前的版本;由于 TCP 的传输效率限制,最新版本 3.0 的传输层依赖 UDP 实现,在应用层实现传输的可靠性,但目前不稳定。HTTP 1.1 是最常用的版本)。

        HTTP 是典型的一问一答模型,即客户端发起请求,服务器返回响应。在 HTTP 交互过程中,我们需要关心请求、响应的格式。

二、抓包软件

        为了观察 HTTP 协议格式,我们需要用到抓包软件。它本质上是一个代理程序,如果是代替客户端做事,就是正向代理;如果是代替服务器做事,就是反向代理。安装了抓包软件后,它就能监听网卡上通过的数据获取客户端-服务器之间传输数据的详情(客户端-服务器之间有了一个中间站,在服务器之前获取客户端的请求,在客户端之前获取服务器的响应)。

        学校里边一般用 wireshark 进行教学,它功能强大,TCP、UDP、IP、以太网数据帧都能抓包,但使用复杂。为了快速上手,我们使用专门的 HTTP/HTTPS 的抓包软件 Fiddler。在工作中,如果想抓包 TCP 等,更常用的是 tcpdump。

        下载程序,推荐使用 bing/google 搜索官网。国内搜索引擎容易搜到广告等一些杂乱信息。

Web Debugging Proxy and Troubleshooting Tools | Fiddler

新版要收钱,我们选经典版:

打开安装包,一路 next 即可。Fiddler 默认不开启 HTTPS,我们需要手动开启:

Tools》Options》HTTPS:首次勾选,会弹出是否信任安全证书,选信任。

左侧是 HTTP/HTTPS 请求/响应列表,看到有很多,即使我们没有点击任何东西,后台也会做一些事情。如果什么都没有,看看电脑上是否有其他代理程序。右上是请求详情,右下是响应详情Raw 是 HTTP/HTTPS 的原始数据

接下来我们要从列表中找到我们主动触发的请求响应,以在浏览器中搜索 sogou.com 为例:

首先清空列表,删除之前的记录:Crl+x 。然后观察域名,找到 sogou.com。再观察颜色

  • 蓝色:该请求/响应是 HTML 的内容。
  • 紫色:该请求/响应是 CSS 的内容。
  • 绿色:该请求/响应是 JavaScript 的内容。

网页由三个关键部分组成:

  • HTML:网页的结构。(有什么组件)
  • CSS:网页的样式。(组件的颜色、大小、位置等)
  • JavaScript:网页的交互。(用户点击网页上的组件,网页给出动态反应)

因此,浏览器和服务器之间的 HTTP 交互是一组,分别获取 HTML、CSS、JavaScript、图片音频视频等依赖资源。

如果仅仅是点网页的刷新,很可能没有 CSS、JS 的 HTTP 交互。因为浏览器有一个缓存功能首次访问网站,浏览器会将 CSS、JS、依赖资源保存到硬盘上后续再次访问,只从服务器获取 HTML。这样优化的原因是,计算机访问存储设备的速度:cpu/寄存器 > 内存 > 硬盘 > 网络(当是万兆网卡时,网络大概率比硬盘快,但家用设备都达不到万兆)。而访问搜狗主页需要将所有内容加载出来才能正确显示。因此,为了观察到完整的一组 HTTP,使用 “全量获取数据”,Crl+F5Crl+刷新

三、HTTP 报文格式

1、整体格式

可以看到,HTTP 的请求/响应的原始数据是行文本,使用记事本打开:

        请求

  • 首行(第一行)
  • 请求头header,从第二行开始往后若干行)
  • 空行(请求头的结束标志)
  • 请求正文body,请求中可以有,可以没有)

        响应:

        HTTP 响应可能被压缩,因此文本行中会有一些乱码:Content-Encoding 显示以 gzip 算法压缩。

        由于网络通信中最贵的硬件资源是带宽,而 CPU 很便宜,因此就把原始文本压缩成二进制减少网络传输的内容,数据到了对端再通过 CPU 解压。点击这个部分进行解压

  • 首行
  • 响应头
  • 空行
  • 响应正文(大多数情况有。该正文包含了 HTML 的内容)

        之前学的报文格式不要求记忆,用的时候查询一下。但是 HTTP 格式需要重点理解记忆,我们在以后工作中经常需要调试。起手式就是抓包,找出 bug 是前端还是后端的问题:如果是请求错了,就是前端的问题。如果是响应错了,就是后端的问题。如果请求、响应都没错,显示错了,也是前端的问题。

2、首行

请求:

2.1、URL(请求)

        唯一资源定位符Uniform Resource Locator,URL)描述了网络上某个资源的具体位置。

        格式

  • 登录信息:已淘汰,现已没有网站用这种认证方式。
  • 服务器地址:服务器 IP 地址,域名。
  • 带层次的文件路径:一个机器上的一个程序可能管理很多资源。真实的文件,或者虚拟的动态生成的资源(根据请求计算的响应)。

        搜狗的主页是典型的静态资源,有一个固定的 “主页.html” 文件:

        搜狗的搜索页是典型的动态资源,根据用户的输入得到不同的结果:

  • 查询字符串(query string):请求中的参数,通过参数进一步解释说明。由程序员自定义,键值对格式,= 分隔键和值,& 分隔键值对
  • 片段标识符:标识网页中的某个部分,实现页面内跳转功能。文档类网站会有,如:简介 | Vue.js

        URL 可以搭配很多网络协议使用,比如 HTTPS、JDBC。回忆一下,JDBC 中第一步是创建 DataSource,设置 url、user、password。jdbc 的 url:jdbc:mysql://127.0.0.1:3306/数据库名?characterEncoding=utf8&useSSL=false。

        https://sogou.com 好像只有域名,实际上端口号、带层次的路径都有省略值,而查询字符串(程序员自定义)、片段标识符(程序员自定义)不是必要的。客户端的端口号是系统分配的空闲端口,服务器的端口号使用的 “知名端口号”,http:// 对应 80;https:// 对应 443。带层次的路径的省略值是 /,即根目录,通常对应网站的主页。

        我们可以发现,搜索页的 url 的 query string 部分的一些 value 显示的是用户输入的中文,但复制后显示的是看不懂的编码:

 

        url 中有一些特殊字符有特殊的含义,比如 =、&、? 等。而中文是由 utf8/gbk 编码,某个汉字的某个字节中可能含有特殊字符的 ascii 编码,导致读取错误。为了避免这种错误,需进行 url encode,将中文/符号按字节加 %。这种 utf8 编码解码的过程有专门库实现,我们在编写程序时要有这种意识。

2.2、方法(请求)

语义:(开发者不一定严格遵守)

  • GET:从服务器获取某个资源。

        最常用的方法,很多操作都会触发 GET 请求:

(1)浏览器地址栏输入 url、点击收藏夹。

(2)点击网页上的跳转链接。

(3)HTML 间接加载其他资源(通过 link 标签加载 css,通过 script 标签加载 JS,通过 img 标签加载图片等)。

(4)也可通过代码手动构造 GET 请求。

        特点一般没有 body,除非自己构造的 GET 请求故意加上 body。通过路径/query string 向服务器传递数据

  • POST:向服务器上传某个资源。

(1)登陆时

body 部分是用户名和密码(经过编码的)。

(2)上传资源时(上传头像为例)

body 部分是图片,属于二进制文件。但是当前上传的图片比较小,为了便于服务器处理,将二进制通过 base64 转为了文本内容。3 个字节的二进制数据,编码成 4 个 ascii 字符,每个字符有 6 位。

        body 可以存二进制,但 url 的 query string 不能,如果非要用它存二进制内容,要用 base64 转成文本。

        特点:用 body 传输数据给服务器;通常没有 query string

  • PUT:向服务器上传某个资源(文件)。特点跟 POST 差不多。
  • DELETE:删除服务器某个资源。特点跟 GET 差不多。

        经典面试题:谈谈 GET 和 POST 的区别。

        本质上没有区别,只是两个不同的方法,他们俩可以互相代替。

        从使用习惯上,有两个主要区别

  • GET 没 body,通过 query string 传输数据给服务器。POST 有 body,通常不需要 query string 传输数据。(不绝对,也可以自己构造 GET、POST 打破这个习惯)
  • 语义上的区别:GET 表示获取,POST 表示提交。(实际上,在实践中会混用)

        之所以是习惯上,是因为这两个区别不是绝对的。

        当然,网上还有一些其它说法:

  • GET 不安全,POST 更安全。因为 GET 是吧密码存 url 里,POST 存 body 里,别人看你屏幕看不到。【错误】安全是通过加密实现的。如果使用 body 存没有加密的密码,黑客也可以抓包获取。
  • HTTP 标准文档中,建议 GET 实现成幂等的(请求一定,响应就一定),而 POST 无要求。【但这只是建议,实际不一定遵守,特别是现在的网站很讲究 “个性化”,给不同客户端的响应都是不同的】
  • 可缓存,承接幂等。GET 实现幂等,就可以将一定的响应缓存。POST 不实现幂等就不能缓存。
  • 传输的数据量。之前有个说法,GET传输的数据量少,因为 url 有长度限制;而 POST 传输的数据量大。【但 HTTP 标准文档中并没有说明 url 的限制。而这个限制在以前是存在的,也是由于浏览器、服务器的实现的限制,不是 url 的限制。现在实际上能看到很长的、保存一个完整图片的 url】
  • 数据的类型。GET 通过 query string 只能传输文本;POST 通过 body 能传输问题,也能传输二进制。【query string 虽然不能直接存二进制数据,但能先进行 base64 转成文本】

        需要用到 PUT、DELETE 方法的场景:Restful 风格的 HTTP 的 API(应用程序编程接口)设计。有些服务器可以认为是 API 的提供者,给浏览器/前端进行调用。以后我们需要写提供接口的服务器,需要统一设计风格,为的是降低学习成本、提高开发效率。满足以下约束

  • 不同方法表示不同语义

GET:查询

POST:新增

PUT:修改

DELETE:删除

  • 通过 URL 的路径表示操作的资源:

正面例子:不同路径下存放不同的视频文件。

反面例子:不管搜索什么,动态响应都存在 search 路径下。

  • 请求、响应携带的数据,尽量用 json 格式的数据

  • 通过 HTTP 响应的状态码表示失败的原因

2.3、版本号

        最主流的是 HTTP 1.1。

请求在后:

响应在前:

2.4、状态码、状态详情(响应)

        我们需要了解几个关键的,这个板块属于经典面试题

  • 200 OK:HTTP 层面的成功(访问成功),不是业务层面的成功(注册失败、成功)(会用其它属性标识,比如 body 的 json 引入键值对 code)。2 开头的都是成功,但是成功之间有区别。
  • 404 Not Found: 客户端访问的资源不存在。url 里面的层次结构路径不存在。
  • 403 Forbidden: 访问被拒绝,没有权限。跟业务有关:1)可以通过 HTTP 403 返回。2)可以通过 HTTP 200 返回,body 的 code 返回出错信息。4 开头都表示客户端出错,打开方式不对。
  • 418:彩蛋,一个玩笑。
  • 500 Internal Server Error: 服务器挂了,代码抛出异常没有 catch 住。我们写代码常见,知名网站不常见。
  • 502 Bad Gateway、504 Gateway Timeout: 网关功能比较简单,不容易挂,通常挂的是网关后面连接的机器。5 开头的都是服务器出错,程序员赶紧修复。
  • 301 Moved Permanently、302 Move temporarily: 旧的地址永久、暂时重定向到新的地址。 3 开头的响应一般不需要 body,但是在 header 中需要 Location,表示要跳转到哪个页面

3、报头

        行文本,每一行就是一个键值对,用 :空格 隔开。每个键值对由标准规定,也允许用户自定义。下面讲一些重要的键值对:

3.1、Host

        目标服务器的地址(域名)和端口(知名端口可省略)。HTTPS 会把 header 加密。url 里的地址和端口就可以和 Host 里加密的进行校验。

3.2、Content-Length、Content-Type

        有 body 才有这俩属性。分别代表 body 的长度数据格式

        Length:HTTP 在传输层通过 TCP 实现,是面向字节流传输,存在粘包问题。body 的长度可以解决这个问题。

        分辨一个完整的 HTTP 包:

  • 如果没有 body,读到空行结束。
  • 如果有 body,读到空行后,再读取 Content-Length 长度的 body。

        常见的 Type 值:浏览器/服务器通过这个值决定 body 如何使用

        如果一个请求/响应有 body,但是没有 Content-Length 或 Content-Type,就是一个非法的请求。商业级的程序具有鲁棒性,就算是非法的也能运行正确。比如没有 Content-Type,就根据 body 猜一个类型;没有 Content-Length,就按照下一个请求一定是 GET/POST 来猜。

3.3、User-Agent

        早期浏览器访问的网站是纯文本的,后来加了多媒体(音频、视频、图片),再后来加了交互能能力(JS),再后来有了更复杂的交互体系……为了兼容老版本和新版本,根据客户端的请求中的 User-Agent 来判定用户的浏览器/系统版本,来决定提供哪个版本的网站。现在的浏览器,上面的功能都有,所以 User-Agent 只有一个主要功能:区分 PC 端和移动端。之所以要区分,是因为 PC 屏和手机屏大小不一样。如果 UA 里是 Windows/MacOS,则是 PC 版;如果 UA 里是 Android/IOS,则是手机版。

        但是这种规则也不能完全解决问题,因为还有平板这种设备,以及 PC、移动端里都叫鸿蒙系统。目前前端流行一种开发技术 “响应式编程”,只写一套代码,自适应浏览器宽度。

3.4、Referer

        在跳转页面的请求中存在,用于记录从哪个 url 来的。例如,我在“蛋糕”的搜索结果页面中,点击了一个广告链接:

搜索结果:

跳转到广告:

发送的 http 请求:

        从浏览器搜索、点击收藏夹发送的请求,都包含该键值对。但浏览器的回退功能与此无关,不依赖 HTTP 协议,而是维护了一个栈记录。

        Referer 的主要应用场景是“点击计费”。广告主可以在多个平台上投放广告,广告主如何知道用户是从哪个平台点击过来的,就是查看 Referer。广告平台服务器、广告主服务器会分别计数,最后数目对得上才行。

        十年前,运营商作为请求的中间必经之路,把请求中的 Referer 改成自己的 url 的行为十分猖獗。虽然各大广告平台跟运营商打赢了官司,但是付出的代价也很大。为了预防这种事的发生,广告平台们加急将基于 HTTP 协议(明文)的服务升级为 HTTPS 协议(含加密层)。 

3.5、Cookie

        Cookie 的内容就是一些自定义的键值对(;隔开键值对,=隔开键和值):

        我们回顾一下,HTTP 协议中,内容是键值对的元素:

        Cookie 本质是网站在本地存储数据的机制。手机 app/电脑桌面应用程序,在下载客户端的时候就会把很多数据保存下来,它们有应用商店审核,所以比较安全。但是网站的数据完全是从服务器获取的,没有人审核安全性,很有可能有病毒程序对电脑产生破坏。为了把控安全,浏览器不允许网站访问电脑上的硬盘,也不能调用电脑上的其它程序。那怎么存储网站的一些数据呢?服务器会将数据传给浏览器并保存在硬盘上(这些数据只能是一些简单的键值对,且有过期时间),当再次访问服务器时,就将数据加载到 Cookie 中,通过请求发送到服务器。 

        访问 sogou.com,查看服务器请求,每个键值对对应一个 Set-Cookie

        在浏览器中查看所有 Cookie,键值对存储到了本地硬盘(访问搜狗主页,可能会与服务器有多次 HTTP 交互,即多个响应,所以上文一个服务器响应只包含了部分 Cookie):

        应用场景:

  • 存放有用,但不重要的信息。Cookie 容易丢失。比如 “上次访问时间”(可有可无);流量标签(记录广告点击来自于旧版式还是新版式),做实验性功能(统计哪个版式的流量更好)。
  • 保存用户的身份标识。很多网站需要登陆,登陆后服务器会将用户的唯一会话标识存 sessionId 储到 Set-Cookie 中返回,之后用户进行的一些列操作都是在该会话中进行的,当登出时会话结束。会话是有存活时间的,存活时间越短安全性越高,比如支付宝、网银。会话和 Cookie 是两个不同的机制,服务器存储会话中所有的详细信息,客户端/浏览器在 Cookie 中保存会话标识。Cookie 按照域名维度存储,在 A 网站申请的会话标识只能用于 A 网站。

4、正文

        主要认识数据格式,在后续实践中进一步体会。

四、构造 HTTP 请求

1、应用场景

  • 开发阶段:浏览器的网页中要构造 HTTP 请求,实现前后端交互。
  • 测试阶段:模拟前端功能,构造 HTTP 请求测试服务器功能。

2、实现方法

2.1、手动写代码

        基于 tcp socket 构造 HTTP GET 请求:按照 HTTP 请求的格式,向 tcp socket 写入字符串。

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;public class httpClient {Socket socket = null;public httpClient(String host, int port) throws UnknownHostException, IOException {// 与目标服务器建立连接socket = new Socket(host, port);}// 构建 GET 请求public void get(String url) {// 构造 HTTP GET 请求:首行+请求头+空行String request = "GET " + url + " HTTP/1.1\n" +"Host: " + socket.getInetAddress().getHostAddress() + ":" + socket.getPort() + "\n" +"\n";try(InputStream inputStream = socket.getInputStream();OutputStream outputStream = socket.getOutputStream()) {// 发送请求outputStream.write(request.getBytes());outputStream.flush();// 接收响应byte[] bytes = new byte[1024*1024];int len = inputStream.read(bytes);String response = new String(bytes, 0, len);System.out.println(response);} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) {}
}

        但这种方法不好测试,因为现在的网站都是 HTTPS 协议没有可以测试的服务器。我们以后自己写了 HTTP 服务器后,可以用这个方法。

        如果是构造 HTTPS 请求,通过 tcp socket 构造很复杂,都是用现成的库实现。

2.2、使用工具

        在工作中,特别在测试阶段,更常用现成工具构造 HTTP 请求。最老牌的就是 Postman,然后还有个知名的国产新秀(2020年之后)API fox(相比 Postman 多了团队成员管理)。

        Postman:

        API fox:

        后端把服务器写完了测试,就是用上面的工具。最后前端和后端会坐一起联调测试。

五、HTTPS

1、为什么要升级为 HTTPS

       HTTP 是明文传输的,不安全。例子如下:

        我们在网页中下载应用时,肯定遇到过这种情况:明明点击下载的是天天音乐,但是下载的链接却是 QQ 浏览器。

        罪魁祸首就是运营商,被金钱蒙蔽了双眼,更改了服务器响应中的下载链接:

        所以我们需要对传输内容进行加密(涉及到密码学,与程序员无关),将明文(原始数据)加密成密文,反操作就是解密。加密解密的过程需要用到密钥HTTPS = HTTP + SSL(下文讲述的工作过程)/TSL(SSL 升级版,但是核心内容一致)。

        军事场景中,密码学就已经很重要了。二战时期,没有计算机,通过无线电报通信(滴答的摩斯电码),这些电报容易被敌人获取。德国就发明了 engima 机,进行高强度加密。英国的图灵大佬发明了 boom 对 engima 的加密电报进行解密。但这不是图灵的真正目标,而是计算机,冯诺依曼邀请他去美国一起研究计算机,他拒绝了。可惜的是因为他喜欢同性被英国政府(当时是政教合一)迫害,因承受不住痛苦而吃了毒苹果自杀。苹果公司的 logo 就是为了纪念图灵。

2、HTTPS 的工作过程

经典面试题

2.1、对称密钥

        用同一个密钥对 HTTP 请求/响应(首行不加密,需要知道目的服务器地址)进行加密解密。但是仅仅是对称密钥存在一个问题,服务器与每个客户端的密钥肯定是要不同的,不管是客户端还是服务器生成密钥,都要告诉对方密钥是什么才能解密/加密。这样会引发问题,必定要在网络上传输密钥,那么黑客就能获取密钥。因此,对称密钥也需要加密。如果用另一个对称密钥对密钥加密?不行,也需要传输。

2.2、非对称密钥

        非对称密钥就是用来给对称密钥加密的。那为什么不直接用非对称密钥给传输的数据加密?因为非对称加密的计算成本远比对称加密的计算成本,密钥肯定比 HTTP 报文的数据量小很多。

        原理:服务器生成一对公钥和私钥,分别要么解锁,要么加锁。把公钥传输出去,谁都可以获得;私钥只能服务器自己持有。

2.3、中间人攻击

        狸猫换太子,用黑客自己生成的公钥密钥替换服务器生成的公钥密钥

2.4、证书

        服务器开发者向第三方公证机构提交资质申请证书,这个证书可以证明公钥是服务器创建的,而不是黑客伪造的,解决中间人攻击

        证书是结构化的字符串,包含属性:

        客户端验证证书的合法性,需要依靠数字签名

        数字签名的生成:公证机构针对证书计算校验和,然后用自己生成的公钥私钥中的私钥对验证和进行加密,就得到了数字签名。

        数字签名的验证:客户端对证书计算一次校验和 check1,再用公钥解密数字签名得到公证机构计算的校验和 check2,如果 check1 和 check2 对不上就说明证书被篡改过。当不匹配时,浏览器就会弹出 “该网站存在风险”。

        问题解答

1)黑客能否篡改公钥?

        不能。check2 会跟 check1 对不上。

2)黑客能否篡改公钥后,把验证和也篡改了?

        不能。第一,黑客无法获取公钥,因为是内置在客户端系统中的(也可以通过其它途径安装,如果黑客搞了一个有问题的系统镜像,就会存在风险),无法对验证和进行解密。第二,黑客没有公证机构的私钥,无法对篡改后的验证和进行加密

3)黑客能否把整个证书替换掉?

        不能。证书中包含了服务器的域名,替换掉域名就变了。

        关于 fiddler 在开启 HTTPS 抓包时,为什么要信任安装证书的解答:抓包实际上就是中间人攻击。我们需要信任 fiddler 的安装证书,它才能替换掉服务器的证书,允许它进行中间人攻击,拿到对称密钥,把所有的数据解密给我们看。

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

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

相关文章

C语言的数组与字符串练习题4

C语言的数组与字符串练习题4 16. 数组元素去重 题目描述: 编写一个C程序,输入一组整数存储在数组中,去除数组中的重复元素,并输出去重后的数组。 解题思路: 遍历数组,对于每个元素,检查它之前是否已经存在相同的元素。如果不存在,则将其保留;否则,跳过。可以使用一…

Transformers简单介绍 - 来源于huggingface

Transformers介绍 - 来源于huggingface 文章目录Transformers介绍 - 来源于huggingfaceTransformers能做什么pipeline()函数零样本分类推理API完形填空命名实体识别问答摘要提取翻译transformers是如何工作的transformers的具体组成注意力层机制transformers原始结构architectu…

template<typename R = void> 意义

在 C 中&#xff0c;template<typename R void> 表示定义一个模板参数 R&#xff0c;其默认类型为 void。这意味着&#xff1a;如果用户没有显式指定 R&#xff0c;则 R 默认为 void。如果用户显式指定了 R&#xff08;如 template<typename R void> 后面跟着 &l…

国产3D大型装配设计新突破①:图纸打开设计双加速 | 中望3D 2026

本文为CAD芯智库整理&#xff0c;未经允许请勿复制、转载&#xff01;在中望3D 2026的新版中&#xff0c;不仅在设计效率上进行了重大优化&#xff0c;更是在装配方面实现了突破性的改进&#xff0c;让每一个项目都能快速、精确地从概念变为现实。 中望3D2026亮点速递装配篇将…

游戏开发状态机与行为树的优缺点

在游戏开发中&#xff0c;状态机&#xff08;Finite State Machine, FSM&#xff09; 和行为树&#xff08;Behavior Tree, BT&#xff09; 是两种常用的 AI 逻辑控制框架&#xff0c;分别适用于不同场景&#xff0c;其优缺点对比可从灵活性、维护成本、适用场景等多个维度分析…

Linux下ELF文件的介绍

目录 1.温故知新 2.ELF文件介绍 3.ELF文件组成 4.ELF文件形成到加载 5.连接过程 1.温故知新 上一篇博客&#xff0c;我们介绍了我们的动静态&#xff0c;知道了我们的库其实也是文件&#xff0c;如果我们想写一个库也是可以的&#xff0c;我们的把我们的库文件编译成.o文件…

人工智能领域、图欧科技、IMYAI智能助手2025年6月更新月报

2025年6月AI领域重要模型更新与平台优化汇总 摘要&#xff1a; 本文汇总了2025年6月期间AI领域发布的多项重要模型更新及平台功能优化信息&#xff0c;涵盖Google Gemini、阿里通义万相、字节豆包、百度文心一言、MiniMax海螺02、Google Veo3、快手可灵2.1、FLUX Kontext等模型…

从零开始学Express,理解服务器,路由于中间件

当我们初学前端时&#xff0c;常常只关注页面效果和交互&#xff0c;但随着项目复杂度提升&#xff0c;我们迟早会遇到“服务端”的问题&#xff1a;如何让一个页面的数据是从数据库来的&#xff1f;怎么让不同的用户看到不同的内容&#xff1f;这时候&#xff0c;我们就需要一…

Codeforces Round 987 (Div. 2)

ABC 略D预处理出每个位置的前缀最大和后缀最小。从后向前枚举&#xff0c;如果一个数无法后移&#xff0c;那么答案就是最大前缀&#xff0c;否则答案要不是前缀最大&#xff0c;要不就是这个数先移到前缀最大位置再移到能移到的最大的位置此处的答案。用线段树维护#include<…

Javascript/ES6+/Typescript重点内容篇——手撕(待总结)

前端核心知识点梳理与面试题详解 1. Promise 核心知识点 Promise 是异步编程的解决方案&#xff0c;用于处理异步操作三种状态&#xff1a;pending&#xff08;进行中&#xff09;、fulfilled&#xff08;已成功&#xff09;、rejected&#xff08;已失败&#xff09;状态一旦改…

[自动化Adapt] 父子事件| 冗余过滤 | SQLite | SQLAlchemy | 会话工厂 | Alembic

第五章&#xff1a;事件处理与融合 欢迎回到OpenAdapt探索之旅~ 在第四章&#xff1a;系统配置中&#xff0c;我们掌握了如何定制化系统参数。更早的第一章&#xff1a;录制引擎则展示了系统如何捕获海量原始操作数据。 假设我们需要训练机器人输入"hello"一词。原…

组合期权:跨式策略

文章目录0.简介1.买入跨式组合&#xff08;Long Straddle&#xff09;1.1 适用场景​1.2 合约选择1.3 损益分析1.4 案例示范2.卖出跨式组合&#xff08;Short Straddle&#xff09;2.1 适用场景​2.2 合约选择2.3 损益分析2.4 案例示范3.小结参考文献0.简介 跨式策略是一种交易…

Vue计算属性详解2

可写计算属性 计算属性默认是只读的,但在特殊场景下,我们可以创建"可写"的计算属性,通过同时提供getter和setter实现: <script setup>import { ref, computed } from vueconst firstName = ref(John)const lastName = ref(Doe)const fullName = computed(…

UniStorm 5.3.0 + Unity2022 + URP配置说明

一、前言 以前我用的是UniStorm3.0&#xff0c;主要用在内置管线里面&#xff0c;最近想在URP管线里面使用UniStorm天气系统&#xff0c;于是弄了UniStorm5.3.0的包&#xff0c;在Unity2022.3的URP模式下配置&#xff0c;直接导入package&#xff0c;两次宣告失败。最后看了官方…

力扣经典算法篇-44-组合总和(回溯问题)

1、题干 给你一个无重复元素的整数数组candidates和一个目标整数 target &#xff0c;找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 &#xff0c;并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一个 数字可以 无限制重复被选取 。…

矩阵与高斯消元:数学算法在计算机领域的应用

一、概述和基本概念 矩阵&#xff0c;类似于在 C 中我们看到的二维数组。它有两个维度&#xff0c;行和列。下面是一个典型的矩阵&#xff1a; M[12342345445610111213] M \begin{bmatrix} 1 & 2 & 3 & 4 \\ 2 & 3 & 4 & 5 \\ 4 & 4 & 5 &…

【补题】CodeTON Round 1 (Div. 1 + Div. 2, Rated, Prizes!) D. K-good

题意&#xff1a;给一个n&#xff0c;如果能被k个数整除&#xff0c;要求这k个数%k后不相同&#xff0c;问如果可以&#xff0c;任意k是多少&#xff0c;如果不可以输出-1 思路&#xff1a; D. K-good_牛客博客 从来没见过&#xff0c;太诡异了&#xff0c;做题做少了 1.…

LLM推理框架的“权力的游戏”:vLLM之后的群雄逐鹿

既然我们已经深入探讨了本地与云端的两大代表Ollama和vLLM&#xff0c;是时候将视野拓宽&#xff0c;检视一下在高性能推理这片“高手如云”的竞技场中&#xff0c;还有哪些重量级的玩家。vLLM的出现点燃了战火&#xff0c;但远非终点。 欢迎来到LLM推理框架的“后vLLM时代”—…

TDengine IDMP 背后的技术三问:目录、标准与情景

过去十年&#xff0c;#工业 和#物联网 场景经历了快速的#数字化 建设&#xff1a;传感器接入、系统联网、数据上云……数据平台已能轻松承载每秒千万级别的写入&#xff0c;每天几 TB 的存储量。但今天再回头看&#xff0c;这些看似“完成”的系统&#xff0c;实际上只解决了一…

MyBatis基础操作完整指南

文章目录MyBatis简介环境搭建Maven依赖数据库表结构核心配置MyBatis配置文件数据库配置文件实体类基础CRUD操作Mapper接口Mapper XML映射文件工具类测试类动态SQL常用标签高级特性一对一关联映射一对多关联映射分页查询使用注解方式MyBatis简介 MyBatis是Apache的一个开源项目…