HTTP

发送格式:

图片

响应格式:

图片

HTTPS

与HTTP相比,多了SSL/TLS
握手协议

概念:前向安全性:

  • 密钥泄露后,即使拿到以前的记录,也无法通过密钥进行破解
  • RSA、DH加密算法是非前向安全的;ECDHE是前向安全的

SSL/TLS 握手协议:

  • 目的:

    • 通过非对称加密算法,握手后协商出对称加密密钥
  • 花费:
    • 2 RTT

      • TLS 1.2 通常情况下
    • 1 RTT
      • 使用会话复用技术后
    • 0 RTT
      • TLS 1.3
        使用会话复用和Pre-shared Key(请求和Ticket一起发) #### TLS
        密钥套件Ciper suite
  • 格式:
    • TLS + 密钥协商算法 + 证书签名算法 + WITH + 对称加密算法 +
      摘要算法
  • 举例:TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256(TLS 1.2)
  • 算法说明:
    • 密钥协商算法:TLS阶段,用于生成对称密钥或者加密对称密钥的要素(要素加密)
    • 签名算法:TLS阶段,用户客户端校验服务器证书有效性、ECDHE公钥的有效性(证书校验)
    • 对称加密算法:TLS完成后,数据传输时加密(数据传输)
    • 摘要算法:TLS最后阶段,对密钥协商过程数据做摘要并验证(过程验证)
  • 举例:TLS_AES_256_GCM_SHA384(TLS 1.3)
    • 密钥协商算法不在套件内,而是通过key_share扩展指定
    • 签名算法不在套件内,而是通过signature_algorithms扩展指定

TLS 1.2 (ECDHE)握手过程:

*
TCP 握手、挥手过程在内核协议栈进行,TLS在应用层
* TLS第一次握手: * 客户端发 client hello消息
* 消息包含:客户端TLS 版本号、支持的密码套件列表、客户端随机数 *
TLS第二次握手: * 服务端发 server hello消息 *
消息包含:协商后的TLS 版本号、协商后的协议套件、服务端随机数 * 服务端发
certificate消息 * 消息包含:证书、证书对应的签名 *
服务端生成用于协议传输的公、私钥(基于协商的协议套件) * 服务端发
serverKeyExchange消息(ECDHE有该过程,RSA没有) *
消息包含:ECDHE公钥、公钥签名、椭圆曲线的参数 * 服务端发
serverHelloDone消息 *
消息包含:服务端协商相关数据已传输结束 * TLS第三次握手: *
客户端验证证书有效性(通过CA或者OSCP stampling) *
客户端生成用于协议传输的公、私钥(基于协商的协议套件) * 客户端发
clientKeyExchange消息 * ECDHE
消息包含:ECDHE公钥、公钥签名、椭圆曲线的参数 * RSA
消息包含:使用服务端证书公钥加密premaster secret后的字符串
* 客户端发 changeCipherSpec消息 *
计算出对称加密密钥,即会话密钥 *
ECDHE:双端公钥+椭圆曲线的参数+双端随机数 * RSA:pre-master
secret+双端随机数 * 消息包含:通知服务端后续使用对称加密 * 客户端发
Encrypted Handshake Message消息 *
先使用摘要算法,计算协商过程产生的数据摘要 *
客户端再使用对称加密的会话密钥对摘要加密 * 消息包含:加密的摘要 *
TLS第四次握手:(ECDHE时,客户端无需等待第四次完成即可发用户数据)
* 服务端发 changeCipherSpec消息 * 使用私钥解密出pre-master
secret,计算出对称加密密钥,即会话密钥 *
ECDHE:双端公钥+椭圆曲线的参数+双端随机数 * RSA:pre-master
secret+双端随机数 * 消息包含:通知客户端后续使用对称加密 * 服务端发
Encrypted Handshake Message消息 *
先使用摘要算法,计算协商过程产生的数据摘要 *
服务端再使用对称加密的会话密钥对摘要加密 * 消息包含:加密的摘要

TLS 1.2 和 1.3对比:

* 性能:TLS 1.2 握手4次,2RTT;TLS 1.3 握手2次,1RTT *
安全:TLS 1.3
将支持的密码套件缩减到五个,但都是前向安全

TLS 握手性能优化:

  • 硬件优化:

    • 提升CPU性能(HTTPS协议是计算密集型)
  • 软件优化:
    • 软件升级:openssl
    • 协议升级:
      • 使用TLS 1.3
      • 密钥交换算法使用ECDHE(替换RSA
    • 证书优化:
      • 证书传输:

        • 选择使用ECDSA替换RSA(前者协议数据更小)
      • 验证过程:
        • OCSP
          在线证书状态协议:向CA查询证书的有效状态,按需查询。建议使用。
        • CRL
          证书吊销列表:向CA拉取证书吊销列表,一次查全量,但数据太大。
        • OCSP Stapling
          • 原先为了验证的服务器的身份,服务器会在 TLS
            握手过程中,把自己的证书发给客户端用于验证
          • 使用OCSP Stapling,服务端向CA周期性地查询证书状态,在握手时返回给客户端,这样客户端就不用再去查询有效性了
  • 工程优化:
    • 会话复用:

      • 含义:把首次TLS握手协商的对称加密密钥缓存起来,后续需要建立 HTTPS
        连接时,直接复用
      • 基于Session ID
        • 服务端和客户端都缓存。使用唯一Session ID将密钥缓存到内存
      • 基于Session Ticket
        • 仅客户端缓存。客户端握手时上传Session Ticket,服务端解密验证
      • 基于Pre-shared Key
        • 在 TLS 1.3支持
        • 客户端重连后,不进行握手,而是直接发
          HTTP请求,将Session Ticket同时传给服务器
    • 会话复用的缺点:
      • 非前向安全
      • 无法应对重放攻击
      • 应对方法:需要设置好有效期 #### 实战经验:
  • wireshark解析TLS加密报文:
    • 修改系统环境变量:export SSLKEYLOGFILE=“/data/sslkeylogfile”
    • 修改wireshark配置
      • 【编辑】->【首选项】->【Protocols】->【TLS】->【Pre-Master
        Secret log】-> “/data/sslkeylogfile”

HTTP/1.0

  • 略过

HTTP/1.1

  • 基于TCP,使用文本进行传输 #### HTTP/1.1 的改进:
  • 长连接:复用TCP连接,避免TCP握手的消耗
  • 管道网络传输(pipeline):客户端的请求可以并发,但服务端响应需要有序(HTTP2.0
    解决)
  • 缓存策略:更复杂的缓存,协商缓存
  • 大文件范围请求Range:断点续传
  • 必须要Host头字段:一台服务器可以托管多个域名的网站

HTTP/1.1 存在的问题:

  • 并发连接有限

    • 浏览器最大并发连接数是 6 个
    • TCP 和 TLS 握手耗时
  • HTTP队头阻塞问题
    • 同一连接只能在完成一个 HTTP
      事务(请求和响应)后,才能处理下一个事务
  • HTTP头部巨大且重复
  • 不支持服务器推送消息,需要通过轮询方式

针对 HTTP/1.1 优化手段:

  • 减少请求:

    • 缓存数据、304 Not Modify
    • 减少重定向次数
    • 合并请求
    • 按需获取
  • 数据压缩:
    • Accept-Encoding、Content-Encoding
    • 无损压缩:gzip
    • 有损压缩:webp、png、heif

HTTP/2.0

特征:

  • 兼容HTTP/1.1,基于TCP,使用二进制传输
  • 语义不改变,只是全部都是小写
  • 语法改变大,HTTP报文的传输格式改变
  • “h2”表示使用 TLS加密(HTTPS)的HTTP/2.0,“h2c”非加密(HTTP)

HTTP/2.0 的改进:

HPACK头部压缩
  • 静态表编码:

    • 共61组,HTTP/2.0协议内默认编码好了
  • 动态表编码:
    • 非静态表的头部,由客户端和服务端自行构建
    • 仅对同一个TCP连接生效、当出现重复传输完全相同的HTTP头部时,才会起作用
    • 存放在内存中,如果连接一直占用,可能会占用较高内存
  • Huffman 编码(压缩算法)
  • 存在的问题:
    • HPACK队头阻塞问题:动态表发生变化+并发下,如果完整的编码未被接收,会导致后续压缩结果无法被发送,造成队头阻塞
二进制格式编码
  • HTTP/1.1 使用文本,HTTP/2.0
    使用二进制

  • 化整为零,将传输信息(header+body)分割为更小的帧

  • 名词解释:

    • HEADERS 帧:传输请求Header 内容
    • DATA 帧:传输请求正文(多个
      Data帧属于同一个流,有先后顺序)
    • Frame Header:帧头(属于帧内的结构)
    • Frame Payload:帧数据(属于帧内的结构)
  • h2包解析:

多路复用
  • 含义:

    • 一条 TCP 连接在同一时间可以跑多个Stream
  • TCP connection、stream、message、frame的关系:
    • connection可以有多个Stream
    • Stream包含两个Message请求message响应message
    • Message包含一个或者多个Frame(Message 对应
      HTTP/1 中的请求或响应)
    • Frame是 HTTP/2 最小单位,以二进制压缩存放 HTTP/1
      中的头部和包体,Frame是有顺序的,一个 Frame 可以由多个 TCP
      报文构成`
服务器推送(Server
Push/ Cache Push)
  • 作用:

    • 将可能会用到的数据先发送给客户端缓存下来
  • 服务端推送时创建的stream ID是偶数
  • 客户端请求时创建的stream ID是奇数
解决HTTP的队头阻塞
  • 通过Stream多路复用解决
  • 同一个tcp连接中,http1的请求需要排队等待http事务完成后才能进行下一个(默认不开启pipeline,即使开启,服务端响应需要有序返回,这样也会阻塞);
  • http2使用流可以在同一个tcp中实现并发

HTTP/2.0 未解决的问题:

  • TCP队头阻塞问题

    • 发生丢包时依赖tcp重传,得等到收到数据包后才能继续处理后续的流
  • 网络迁移需要重新建立TCP连接
    • 一个 TCP 连接是由四元组确定,IP地址或者端口变动,就需要TCP与
      TLS重新握手(TCP存在连接状态导致,UDP无该问题)

帧协议格式:

图片
  • 帧长度:

    • 单个帧最大2^24 = 16M
  • 帧类型:
    • 大致可以分成:

      • 数据帧:HEADERS 、DATA
      • 控制帧:SETTINGS、PING、PRIORITY等
    • 此外 gRPC 定义了几种自用的新帧类型。
  • 帧标志:
    • End Headers:表示header传输结束,在HEADERS帧使用
    • End stream:表示客户端或者服务端单方面数据传输结束,在HEADRS帧(get)、DATA帧(post)使用
    • Padded:表示该流是用来填充的,在任意帧都使用
    • Ack:表示确认,在PING帧SETTING帧中使用
  • 流标识符:Stream ID
    • 流 ID 是递增的:

      • 客户端发起的 ID 是奇数
      • 服务器端发起的 ID 是偶数
    • 流是可并发的:
      • 一个连接上可以同时有多个流,即“多路复用”也就是并发多请求;
    • 流是双向的
      • 客户端和服务器都可以创建流,双方互不干扰
      • 一个流对应一次http请求、响应
    • 流之间是独立的
      • 但流内部的帧是有严格顺序的
    • 流是有优先级的:
      • 在流上发送PRIORITY帧,让服务器优先处理某些流
      • e.g. 先传 HTML/CSS,后传图片,优化用户体验
    • 流是可取消的:
      • 在流上发送RST_STREAM帧可以随时终止流,取消接收或发送
    • 第0号流比较特殊,不能关闭,也不能发送数据帧,只能发送控制帧,用于流量控制。

数据收发:

  • 从不同层对应的消息:

    • 在“流”内看,消息由有序的“帧”序列组成
    • 在“TCP”的层面上看,消息是乱序收发的“帧”
      • 多个请求/响应之间没有了顺序关系,不需要根据请求顺序排队等待
  • 数据发送过程:
    1. 发送方将多个请求分到多个流中,然后将请求内容拆成帧,进行二进制传输
    2. 多个请求的帧,在传输层打散乱序发送
    3. 接收方根据每个帧首部的流标识符重新进行组装
    4. 可以根据优先级,决定优先处理哪个流的数据
    5. 因为TCP滑动窗口的原因,如果某个包没被确认,虽然后续包已到达,也不会被确认,而是一直阻塞
    6. 1.1 vs 2.0 发送示意图:

HTTP/3.0(HTTP-over-QUIC)

  • 在HTTP/3.0中,数据流由传输层QUIC提供,而在HTTP/2中,流由HTTP层完成
    ### QUIC:
  • 特征:
    • QUIC
      基于UDP,是一个自己处理数据流的传输层协议,自身实现了TCP的一些特性
    • QUIC 使用且必须用TLS 1.3传输层安全协议
    • QUIC流 可以是单向的、也可以是双向的,由发起端决定
    • QUIC
      在用户空间中实现,使用QUIC意味着选择了套接字API之外的另一套API
    • 建立过程:可能在首次握手时协商使用HTTP/2协议,通过Alt-Svc头部,服务器通告客户端它对HTTP/3的支持与偏好。所以首次连接可能会有TCP连接和UDP同时进行(跟DNS解析ipv4和ipv6同时进行类似)
      • e.g. Alt-Svc:
        h3=“:50781”,建议客户端使用UDP端口50781提供的HTTP/3

解决HTTP/2.0 的问题:

  • TCP 队头阻塞:

    • QUIC的流基于UDP连接,每个流相互独立,互不影响(因为UDP不管顺序,不管丢包,所以传输层没有阻塞问题)
  • TCP 建立连接的延迟更低:
    • HTTP2.0:tcp + tls = 1RTT +2 RTT
    • QUIC:传输层握手和tls合并
  • 网络迁移(wifi和蜂窝互换)需要重新建立TCP连接
    • HTTP2.0 基于TCP,tcp 五元组唯一确认一个连接
    • QUIC
      基于UDP,使用唯一的connection id,端口号同UDP端口

QUIC协议:

  • 总览:
UDP Header
Packet Header -----
QUIC Frame Header -- TLS1.3
HTTP3 Frame Header --
HTTP Message -----

Img
  • Packet(负责连接可靠):

    • 定义Connection ID,类似TCP连接四元组

      • 64比特位(8字节)整数标识
    • Packet Number实现了类似TCP的可靠的连接
      • 重传:当 UDP 报文丢失后,通过 Packet Header 中的 Packet Number
        实现报文重传。
      • Packet Number 单调递增,重传的包Packet Number不一样:
        • RTT是精确的,没有TCP重传导致的RTT歧义
        • 包可以被乱序确认
          • 通过Stream ID +
            Offset可以确认是同一个包,即使packet Number不一样
    • Connection ID实现了连接迁移:
      • 记录Destination Connection ID,在客户端 IP
        地址、端口变化后,绕过 UDP 四元组,继续维持连接
    • 一个 Packet 报文中可以存放多个
      QUIC Frame,不能超过PMTUD(1200字节)
    • 上图Area Data即多个QUIC Frame,即在一个connection
      中并发多个请求
  • QUIC Frame(负责字节流有序):
    • 一个Frame不可跨越多个Packet传输
    • Frame Type
      • 定义不同类型的Frame

        • QUIC STREAM Frame 应用层数据传输
        • other Frame 状态管理
    • QUIC STREAM Frame
      • Stream Id 实现有序的字节流:

        • 在无序的 Packet
          报文中,Stream Id相同表示同一个HTTP消息(消息过大时,可跨Packet传输)
        • 最低2位比特位用于识别连接的类型(单向、双向、发起者)
          • 最低1比特位表示流的发起者:

            • 0:双数流,客户端发起; 1:单数流,服务器发起
          • 第2个比特位识别单/双向流:
            • 0:双向;1:单向
      • offset用于重建字节流,实现消息的序列化:
        • 通过Offset字段完成类似于TCP协议中的Sequence序号,进行累计确认
      • Length 指明了Frame数据的长度
      • 以下为QUIC STREAM Frame格式:
        • Stream Data即HTTP/3 Frame
  • HTTP/3 Frame(负责HTTP语义):
    • Type:类似 HTTP/2的帧类型:

      • DATA帧、HEADERS帧、SETTINGS帧、GOAWAY帧、MAX_PUSH_ID帧(限制服务器推送消息数量)
    • Frame Payload
      • 存放二进制的 HTTP message
    • 作用:
      • 可跨越多个Packet
      • 实现服务器推送
      • 实现 QPACK 编解
      • 权重优先级设定
      • 流量控制
  • HTTP Message(具体消息内容):
    • 通用HTTP协议数据,header、body等

QUIC机制:

自定义连接:
  • 不再以四元组标识,而是以一个64位的随机数作为Connection ID来标识
  • 加密算法的版本协商与传输层握手合并完成,以减小延迟
自定义重传机制:
  • Packet Number(数据包编号):在QUIC协议中,每个数据包都有一个唯一的编号,用于标识数据包在传输过程中的顺序和重传情况。Packet
    Number 用于确保数据包按正确的顺序传输,并在需要时进行重传
无阻塞的多路复用:
  • 同一条 QUIC Connection Id上可以创建多个 stream 来发送多个请求(跟HTTP
    2.0 一致)
  • QUIC为每个Stream分配独立的滑动窗口。在传输层面如果出现丢包,只影响包所在的stream,其他stream无需等待。(跟HTTP2.0差异点,因为是基于UDP的)
自定义流量控制:
  • stream级别的滑动窗口:

    1. QUIC 通过
      window_update帧来告诉对端它可以接受的字节数
    2. QUIC 窗口的起始位置为当前收到的最大 offset
    3. QUIC 的 ACK 是基于 offset 的,每个 offset
      的包来了,进了缓存,就可以应答(相信中间的空档一定会到来)
    4. QUIC为每个Stream分配独立的滑动窗口,相互之间不影响
      窗口示意图:TCP 和 QUIC
    5. 可用窗口左边界:
      • TCP:已确认的序号
      • QUIC:收到的最大Offset
  • 连接级别的流量控制窗口:
    • 对所有的stream做整体大小控制
服务器推送(Server
Push/ Cache Push)
  • 作用:

    • 将可能会用到的数据先发送给客户端缓存下来,需要客户端同意
  • 过程:
    • 服务器通过请求流发送一个
      PUSH_PROMISE 帧,使该推送请求看上去像是一个响应,然后通过新的流发送实际推送数据
    • 客户端可随时通过CANCEL_PUSH 帧取消推送
    • 客户端可以设置推送次数限制

HTTP/3.0机制

头部压缩
  • QPACK:

    • 为什么要改HPACK:

      • 由于动态表具有时序性,QUIC中数据流互相独立,并发下因为可能还未建立动态表会导致失败
    • QPACK使用两个额外的单向QUIC流,用于在两个方向上传递动态表信息
      • QPACK Encoder Stream:用于传输动态表信息

      • QPACK Decoder Stream:用于对传输内容的确认响应

二进制格式编码
  • 同HTTP2.0相似,将传输信息(header+body)分割为更小的帧
HTTP/3.0 Frame:

* 帧类型与HTTP2基本相同 * 流的相关功能前置到传输层QUIC实现
* 头部压缩算法使用QPACK

对比:

* 参考: * https://http3-explained.haxx.se/zh/why-QUIC/why-tcphol
* https://xiaolincoding.com/network
* https://kiosk007.top/post/quic-%E5%8D%8F%E8%AE%AE/

08.*应用层、HTTP(七层)的更多相关文章

  1. OSI七层模型数据流

    前段时间去学习了思科网络基础CCNA的知识,与我们运维所需的网络基础大同小异,当然其包容性要大很多.我们主要来看下网络方面的内容: 网络七层模型 七层网络模型是我们进行网络间通信的基本理论依据,由上至 ...

  2. Iptables详解七层过滤

    <Iptables详解七层过滤> 一.防火墙简介 防火墙其实就是一个加固主机或网络安全的一个设备或者软件而已,通过防火墙可以隔离风险区域与安全区域的连接,同时不会妨碍风险区域的访问.当然需 ...

  3. python网络编程-Json序列化功能扩展-软件开发架构-OSI七层协议-TCP-01

    面向对象补充知识点(面向对象的应用) 扩展json序列化所支持的数据类型(分析源码) import json from datetime import datetime, date # ------- ...

  4. Linux--网络基础(概念+协议的了解+OSI七层模型,TCP/IP五层协议,网络数据传输流程)

    网络的发展 网络的发展有下面几个阶段: 独立模式:计算机最开始是以单机模式被广泛使用的.每一台计算机都是独立的,之间不能够进行数据共享与通信 网络互联: 计算机之间可以链接在一起,完成数据共享,计算机 ...

  5. OSI七层模型详解 TCP/IP协议

      总结 OSI中的层 功能 TCP/IP协议族 应用层 文件传输,电子邮件,文件服务,虚拟终端 TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet 等等 表示层 数据格式化,代码转 ...

  6. python网络编程-OSI七层模型详解

    OSI 七层模型通过七个层次化的结构模型使不同的系统不同的网络之间实现可靠的通讯,因此其最主要的功能就是帮助不同类型的主机实现数据传输 . 完成中继功能的节点通常称为中继系统.在OSI七层模型中,处于 ...

  7. 温故知新--计算机网络 iso/osi七层模型 tcp/ip四层模型

    ISO七层模型由下至上为1至7层,分别为: 应用层(Application layer) 表示层(Presentation layer) 会话层(Session layer) 传输层(Transpor ...

  8. 面试题系列——OSI七层模型

    OSI(开放式系统互联模型)是一个开放性的通行系统互连参考模型,是一个协议规范.它把网络协议从逻辑上分了七层,每一层都有对应的物理设备. OSI七层模型是一种框架性的设计方法,设计的主要目的是为了解决 ...

  9. OSI七层模型

    OSI 七层模型通过七个层次化的结构模型使不同的系统不同的网络之间实现可靠的通讯,因此其最主要的功能就是帮助不同类型的主机实现数据传输 . 完成中继功能的节点通常称为中继系统.在OSI七层模型中,处于 ...

  10. TCP/IP四层模型和OSI七层模型

    TCP/IP四层模型 TCP/IP是一组协议的代名词,它还包括许多协议,组成了TCP/IP协议簇.TCP/IP协议簇分为四层,IP位于协议簇的第二层(对应OSI的第三层),TCP位于协议簇的第三层(对 ...

随机推荐

  1. 前端开发系列100-小程序篇之UI组件库的使用和封装

    本文介绍微信小程序开发中常用的第三方UI组件库的基本使用流程和如何自定义组件. 1.0 第三方UI组件库的基本使用流程 通常,在使用第三方组件库之前首先需要通过代码的托管仓库和组件库文档来了解该组件库 ...

  2. java Filehandler

    简介 最近的好像都没有手敲,只是看了一下.这个是文件管理的 code /* * @Author: your name * @Date: 2020-11-08 15:30:36 * @LastEditT ...

  3. Claude Code如何集成到VSCode、PyCharm IDE及使用技巧

    1.Claude Code 简介 Claude Code 是由 Anthropic 公司推出的一款基于 Claude Sonnet 模型的智能 AI 编程工具,安装方法与介绍介绍,可查阅之前的文章: ...

  4. 【Container App】创建Container App后发现Application URL不完整

    问题描述 新创建了一个Container App服务,构建在内部访问的环境中( Container App Environment配置了虚拟网络并设置为内部访问). ##Container Apps ...

  5. SciTech-EECS-Autosar(自动驾驶)-Hardware:硬件:-EV充电 : 全球充电接口五大标准及控制电路

    SciTech-EECS-Autosar(自动驾驶)-Hardware:硬件: 参考 https://www.chongdiantou.com/archives/360277.html 新能源汽车 指 ...

  6. AcWing 113. 特殊排序

    有关数据 \(\texttt{Time Limit}\) \(\texttt{Memory Limit}\) \(\texttt{Difficulty}\) \(\color{green}{\text ...

  7. 高效编解码协议之protobuf协议详解

    Protocol Buffers(简称 protobuf)是 Google 开发的 高效二进制序列化工具,用于结构化数据的存储和传输. 核心特性 特性 说明 跨语言支持 支持 Java.C++.Pyt ...

  8. Origin图表技巧之轻松绘制阶梯图

    阶梯图是将两个相邻数据点采用水平阶梯线或垂直阶梯线相连形成的一种图表,又分为水平阶梯图和垂直阶梯图,下面给大家分享使用Origin软件绘制阶梯轴的方法: 操作步骤: 1.打开Origin2022软件, ...

  9. .NET周刊【7月第3期 2025-07-20】

    国内文章 从 Redis 客户端超时到 .NET 线程池挑战:饥饿.窃取与阻塞的全景解析 https://www.cnblogs.com/code-daily/p/18985234 本文探讨了在使用 ...

  10. Java变量与常量全解析(包含常量类、interface 与 final 的比较)

    ​ Java中的变量 变量是Java程序中最基本的存储单元,用于存储数据值.变量在程序运行期间其值可以改变.变量必须先声明后使用. 变量声明语法: 数据类型 变量名 [= 初始值]; 变量分类: 局部 ...