当前位置: 首页 > news >正文

深度学习 Pytorch 张量(Tensor)的创建和常用方法

1 张量的基本创建及其类型

Numpy中的array一样,张量的本质也是结构化地组织了大量的数据。

并且在实际操作中,张量的创建和基本功能也与其非常类似。


1.1 张量(Tensor)函数创建方法

张量的最基本创建方法和Numpy中创建Array的格式一致。

# Numpy创建数组
import numpy as np		#导入numpy
a = np.array([1, 2, 3])
import torch # 首次使用,导入torch包
# 通过列表创建张量
t = torch.tensor([1, 2])
t	# output : tensor([1, 2])
# 通过元组创建张量
t = torch.tensor((1, 2))
t	# output : tensor([1, 2])
# 通过数组创建张量
a = np.array([1, 2])
t = torch.tensor(a)
t	# output : tensor([1, 2],dtype = torch.int32)

通过上述返回结果,我们发现张量也有dtype类型


1.2 张量的类型

张量和数组类似,都拥有dtype方法,可返回张量类型。

来看整型

# 整型数组的dtype方法
np.array([1, 2, 3]).dtype
# output : int32
# 整型张量的dtype方法
torch.tensor([1, 2, 3]).dtype
# output : torch.int64

不难发现,整数型的数组默认创建int32(整型)类型,而张量则默认创建int64(长整型)类型。

如果tensor中传入的参数是array数组类型,那么它将会告诉你生成的是torch.int32类型:

a = np.array([1, 2])
t = torch.tensor(a)
t	# output : tensor([1, 2],dtype = torch.int32)

来看浮点型

# 浮点型数组的dtype方法
np.array([1.1, 2.2]).dtype
# output : float64
# 浮点型张量的dtype方法
torch.tensor([1.1, 2.2]).dtype
# output : torch.float32

不难发现,浮点型的数组默认创建float64(单精度浮点型),而张量则默认创建float32(双精度浮点型)。

如果tensor中传入的是array数组类型,那么它将会告诉你生成的是torch.float64类型:

a = np.array([1.1, 2.2])
t = torch.tensor(a)
t	# output : tensor([1.1000, 2.2000],dtype = torch.float64)

除了数值型张量,常用的张量类型还有布尔型张量,也就是构成张量的各元素都是布尔类型的张量。

t=torch.tensor([True,False])
t.dtype
# output : torch.bool

当然,在PyTorch中也支持复数类型对象创建

t = torch.tensor(1 + 2j)	# 1是实部、2是虚部
t	# output : tensor(1.+2.j)

此外,我们还可以通过dtype参数,在创建张量过程中设置输出结果

# 创建int16整型张量
torch.tensor([1.1, 2.7],dtype = torch.int16)
# output : tensor([1, 2], dtype = torch.int16)

和数组不同,对于张量而言,数值型和布尔型张量就是最常用的两种张量类型,相关类型总结如下:

数据类型dtype
32bit浮点数torch.float32或torch.float
64bit浮点数torch.float64或torch.double
16bit浮点数torch.float16或torch.half
8bit无符号整数torch.unit8
8bit有符号整数torch.int8
16bit有符号整数torch.int16或torch.short
16bit有符号整数torch.int16或torch.short
32bit有符号整数torch.int32或torch.int
64bit有符号整数torch.int64或torch.long
布尔型torch.bool
复数型torch.complex64

1.3 张量类型的转化

张量类型的隐式转化

Numpyarray相同,当各张量类型属于不同类型时,系统会自动进行隐式转化

# 浮点型和整数型的隐式转化
torch.tensor([1.1, 2]).dtype
# output : torch.float
# 布尔型和数值型的隐式转化
torch.tensor([True, 2.0])
# output : torch([1., 2.])

张量类型的转化方法

除了隐式转化,我们还可以使用.float().int()方法对张量类型进行转化

t = torch.tensor([1, 2])	#创建张量t
# 转化为默认浮点型(32位)
t.float()
# output : tensor([1., 2.])
# 转化为双精度浮点型
t.double()
# output : tensor([1., 2.],dtype = torch.float64)
# 转化为16位整数
t.short()
# output : tensor([1, 2],dtype = torch.int16)

2 张量的维度与形变

张量作为一组数的结构化表示,同样具有维度的概念。

简单理解,向量就是一维的数组,而矩阵就是二维的数组。

在张量中,我们还可以定义更高维度的数组。

当然,张量的高维数组和NumpyArray概念类似。


2.1 创建高维张量

用简单序列创建一维数组

t = torch.tensor([1, 2])
# 使用ndim属性查看张量的维度
t.ndim
# output : 1
# 使用shape查看形状
t.shape
# output : torch.Size([2])
# 和shape函数相同
t.shape()
# output : torch.Size([2])

注:和Numpy不同,PyTorchsize方法返回结果和shape属性返回结果一致

此外,还需要注意有两个常用的函数/方法,用来查看张量的形状

# 返回拥有几个(N-1)维张量
len(t1)
# output : 2,表示有两个0维张量
# 比如对二维张量采用len()方法,返回的就是多少个一维张量
# 返回总共拥有几个数
t.numel()
# output : 2

注:一维张量lennumel返回结果相同,但更高维度张量则不然


用“序列”的“序列”创建二维数组

以此类推,我们还可以用形状相同的序列组成一个新的序列,进而将其转化为二维张量。

# 用list的list创建二维数组
t = torch.tensor([[1, 2], [3, 4]])
t	
# output:
tensor([[1, 2],[3, 4]])
# 查看维度
t.ndim
# output : 2# 查看形状
t.shape
# output : torch.Size([2, 2])# 查看形状
t.size()
# output : torch.Size([2, 2])# 查看有几个(N-1)维张量
len(t)
# output : 2,表示由两个一维张量构成# 查看拥有几个数
t.numel()
# output : 4

“零”维张量

Pytorch中,还有一类特殊的张量被称为零维张量。该类张量只包含一个元素,但又不是单独一个数。

t=torch.tensor(1)
t	# output : tensor(1)
t.ndim	# output : 0
t.shape		# output : torch.Size([])
t.numel()	# output : 1

理解:我们可以将零维张量视为拥有张量属性的单独一个数。

例如,张量可以存在GPU上,但``Python`原生的数值型对象不行,而零维张量可以。

从学术名称来说,Python中单独一个数是scalars(标量),而零维的张量则是tensor


高维张量

三维及三维以上的张量称其为高维张量。

a1 = np.array([[1, 2, 2], [3, 4, 4]])
a1
# output : 
array([[1, 2, 2][3, 4, 4]])
a2 = np.array([[5, 6, 6], [7, 8, 8]])
a2
# output : 
array([[5, 6, 6][7, 8, 8]])
# 由两个形状相同的二维数组创建一个三维的张量
t3 = torch.tensor([a1, a2])
t3
# output :
tensor([[[1, 2, 2],[3, 4, 4]],[[5, 6, 6],[7, 8, 8]]], dtype=torch.int32)
t3.ndim
# output : 3
t3.shape
# output : torch.Size([2, 2, 3])	包含两个,两行三列的矩阵的张量
len(t3)
# output : 2
t3.numel()
# output : 12

2.2 张量的形变

张量作为数字的结构化集合,其结构也是可以根据实际需求灵活调整的


flatten拉平:将任意维度张量转化为一维张量

t2 = torch.tensor([[1, 2], [3, 4]])	#二维张量
t2.flatten()
# output : tensor([1, 2, 3, 4])
t3 = torch.tensor([a1, a2])		#三维张量
t3.flatten()
# output : tensor([1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8], dtype = int32)

注:如果将零维张量使用flatten,则会转化为一维张量

t = torch.tensor(1)		# 零维张量
t.flatten()
# output : tensor([1])

reshape方法:任意变形

t1 = torch.tensor([1, 2])
# 转化为两行、一列的向量
t1.reshape(2, 1)
# output :
tensor([[1],[2]])

注意reshape转化后的维度由该方法输入的参数个数决定


转化后生成一维张量

t1.reshape(2)
# output : tensor([1, 2])
# 另一种表达形式
t1.reshape(2, )
t1.reshape(2).ndim
# output : 1

转化后生成二维张量

t1.reshape(1, 2)
# output : tensor([[1, 2]])
t1.reshape(1, 2).ndim
# output : 2

转化后生成三维张量

t1.reshape(1, 1, 2)
# output : tensor([[[1, 2]]])
t1.reshape(1, 2, 1)
# output :
tensor([[[1],[2]]])
# 注意转化过程维度的变化
t1.reshape(1, 2, 1).ndim
# output : 3

3 特殊张量的创建方法

在很多数学科学计算过程中,会创建一些特殊取值的张量用于模拟特殊取值的矩阵。如全0矩阵、对角矩阵等。

因此,PyTorch中也存在很多创建特殊张量的函数。


3.1 特殊取值的张量创建方法

全0张量

torch.zeros([2, 3])		#创建全是0的两行、三列的张量(矩阵)
# output :
tensor([[0., 0., 0.],[0., 0., 0.]])

由于zeros就已经确定了张量元素取值,因此该函数传入的参数实际上决定了张量的形状


全1张量

torch.ones([2, 3])
# output :
tensor([[1., 1., 1.],[1., 1., 1.]])

单位矩阵

torch.eye(5)
# output :
tensor([[1., 0., 0., 0., 0.],[0., 1., 0., 0., 0.],[0., 0., 1., 0., 0.],[0., 0., 0., 1., 0.],[0., 0., 0., 0., 1.]])

对角矩阵

pytorch中,需要利用一维张量去创建对角矩阵

t1 = torch.tensor([1, 2])
torch.diag(t1)
# output :
tensor([[1, 0],[0, 2]])

千万不能直接使用list创建对角矩阵.


rand:服从0-1均匀分布的张量

torch.rand(2, 3)
# output :
tensor([[0.0214, 0.3989, 0.0814],[0.8888, 0.1773, 0.2567]])

randn:服从标准正态分布的张量

torch.randn(2, 3)
# output :
tensor([[-0.8638,  1.0079,  0.0267],[ 1.3223,  0.0856, -0.7271]])

normal:服从指定正态分布的张量

torch.normal(2, 3, size=(2, 2))		# 均值为2,标准差为3的张量
# output :
tensor([[ 1.5616, -0.9688],[ 3.4087, -0.0917]])

randint:整数随机采样结果

torch.randint(1, 10, [2, 4])	# 在1-10之间随机抽取整数,组成两行四列的张量
# output :
tensor([[4, 1, 9, 8],[4, 2, 5, 7]])

arange/linspace:生成数列

torch.arange(5)	# 和range相同
# output : tensor([0, 1, 2, 3, 4])
torch.arange(1, 5, 0.5)		# 从1到5(左闭右开),每隔0.5取值一个
# output :
tensor([1.0000, 1.5000, 2.0000, 2.5000, 3.0000, 3.5000, 4.0000, 4.5000])
torch.linspace(1, 5, 3)		# 从1到5(左右都包含),等距取三个数
# output :
tensor([1., 3., 5.])

empty:生成未初始化的指定形状矩阵

torch.empty(2, 3)	# 生成的值只是内存中的原始字节
# output :
tensor([[3.1056e-33, 1.8203e-42, 0.0000e+00],[0.0000e+00, 0.0000e+00, 0.0000e+00]])

full:根据指定形状,填充指定数值

torch.full([2, 4], 2)
# output :
tensor([[2, 2, 2, 2],[2, 2, 2, 2]])

3.2 创建指定形状的数组

我们还可以根据指定对象的形状进行数值填充,只需要在上述函数后面加上_like即可

t1 = torch.tensor([1, 2])
t2 = torch.tensor([[1, 2], [3, 4]])
torch.full_like(t1, 2)		# 根据t1形状,填充数值2
# output : tensor([2, 2])
torch.randint_like(t2, 1, 10)
# output :
tensor([[1, 1],[2, 9]])
torch.zeros_like(t1)
# output : tensor([0, 0])

需要注意的是,_like函数需要注意转化前后数据类型一致的问题。

t10 = torch.tensor([1.1, 2.2])	# 传入randn_like的参数必须为浮点型
torch.randn_like(t10)
# output :
tensor([1.0909, 0.0379])

4 张量和其它相关类型之间的转化方法

张量、数组和列表是较为相似的三种类型对象。在实际操作中,经常会涉及三种对象的相互转化。

在前面中torch.tensor函数可以直接将数组或者列表转化为张量,我们也可以将张量转化为数组或者列表


.numpy方法:张量转化为数组

t = torch.tensor([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
t.numpy()
# output :
array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], dtype = int64)
# 也可以用np.array函数直接转化为array
np.array(t)

.tolist方法:张量转化为列表

t.tolist()
# output : [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

list函数:张量转化为列表

list(t)
# output :
[tensor(1),tensor(2),tensor(3),tensor(4),tensor(5),tensor(6),tensor(7),tensor(8),tensor(9),tensor(10)]

此时转化的列表是由一个个零维张量构成的列表,而非张量的数值组成的列表


.item()方法:转化为数值

在很多情况下,我们需要将最终计算的结果作为单独的数值进行输出

n = torch.tensor(1)
n.item()
# output : 1

5 张量的深拷贝

张量和python一样,等号赋值操作实际上是浅拷贝。

进行深拷贝时需要使用clone方法

t1 = torch.tensor([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
t2 = t1
t1[1] = 10
t2	#浅拷贝会和t2的值一起修改
# output : tensor([ 1, 10, 3, 4, 5, 6, 7, 8, 9, 10])

此时t1t2指向相同的对象。要使t2不随t1对象改变而改变,则需要对t2进行深拷贝,独自拥有一份对象。

t3 = t1.clone()
t1[0] = 100
t3
# output : tensor([ 1, 10, 3, 4, 5, 6, 7, 8, 9, 10])

相关文章:

深度学习 Pytorch 张量(Tensor)的创建和常用方法

1 张量的基本创建及其类型 和Numpy中的array一样,张量的本质也是结构化地组织了大量的数据。 并且在实际操作中,张量的创建和基本功能也与其非常类似。 1.1 张量(Tensor)函数创建方法 张量的最基本创建方法和Numpy中创建Array的格式一致。 # Numpy创建…...

在VMwareFusion中使用Ubuntu

在VMwareFusion使用Ubuntu 在VMwareFusion使用Ubuntu背景在VMwareFusion虚拟机里使用Ubuntu1、集成桌面工具2、主机和虚拟机之间共享剪贴板内容3、设置root用户密码4、设置静态ip4.1、静态ip和动态ip的区别4.2、查看当前ip4.2、linux网络配置文件所在位置4.3、基于ubuntu22.04.…...

%.*s——C语言中printf 函数中的一种格式化输出方式

在C语言中,%.*s 是 printf 函数中的一种格式化输出方式,用于控制字符串的输出长度。具体来说,%.*s 中的 * 表示输出宽度(即最多输出的字符数)是一个变量,这个变量的值在运行时通过 printf 函数的参数传递。…...

基于微信小程序的摄影竞赛系统设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…...

hydra破解密码

hydra九头蛇是常用的密码破解工具 1、破解centos ssh密码 hydra -l root -P password.txt ssh://192.168.1.107:2222 hydra -l root -P password.txt -s 2222 192.168.1.107 ssh2、破解ftp hydra -l allen -P e:\aa.txt ftp://127.0.0.1 hydra -l allen -P e:\aa.txt ftp:…...

JAVA之外观模式

外观模式,又称门面模式,是一种结构型设计模式,旨在为复杂的子系统提供一个统一且简化的接口。通过这一模式,客户端可以更加便捷地与子系统交互,而无需深入了解其内部结构和实现细节。外观模式不仅简化了客户端的使用&a…...

如何选择合适的服务器?服务器租赁市场趋势分析

服务器租赁市场概览 服务器租赁 market可以分为两种类型:按小时、按月和按年,每种模式都有其特点和适用场景,按小时租赁是最经济实惠的选择,适用于短期需求;按月租赁则适合中长期使用;而按年租赁则是最灵活…...

CentOS 下载软件时报Error: Failed to synchronize cache for repo ‘AppStream‘解决方法

下载软件时出现以下问题 直接把CentOS-AppStream.repo改个名字就行 cd /etc/yum.repos.d/ mv CentOS-AppStream.repo CentOS-AppStream.repo.bak就可以了 解决思路 把AI问遍,无人会,解决法 想要下载软件通通失败了,解决方法当然是问AI&am…...

鲍厚霖:引领AI广告创新,搭建中美合作桥梁

2024年是鲍厚霖和她领导的超能S咨询公司(Triple S AI)收获颇丰的一年。这一年中,她以卓越的战略眼光和创新能力,为中美教育、文化与技术的深度融合注入了新的活力。2025年,Triple S AI计划推出全新2.0版本平台,进一步深化人工智能驱动的营销与文化合作领域,推动产业变革与社会福…...

学习记录1

[SUCTF 2019]EasyWeb 直接给了源代码&#xff0c;分析一下 <?php function get_the_flag(){// webadmin will remove your upload file every 20 min!!!! $userdir "upload/tmp_".md5($_SERVER[REMOTE_ADDR]);if(!file_exists($userdir)){mkdir($userdir);}if…...

【Gossip 协议】Golang的实现库Memberlist 库简介

Gossip 协议简介 Gossip 协议是一种分布式协议&#xff0c;用于在节点之间传播信息&#xff0c;常用于成员管理、故障检测、服务发现等场景。在这个协议中&#xff0c;每个节点定期与其他节点交换信息&#xff0c;最终保证所有节点达到一致的状态。它的工作原理类似于人群中的…...

LDD3学习7--硬件接口I/O端口(以short为例)

1 理论 1.1 基本概念 目前对外设的操作&#xff0c;都是通过寄存器。寄存器的概念&#xff0c;其实就是接口&#xff0c;访问硬件接口&#xff0c;有I/O端口通信和内存映射I/O (Memory-Mapped I/O)&#xff0c;I/O端口通信是比较老的那种&#xff0c;都是老的串口并口设备&am…...

openharmony电源管理子系统

电源管理子系统 简介目录使用说明相关仓 简介 电源管理子系统提供如下功能&#xff1a; 重启服务&#xff1a;系统重启和下电。系统电源管理服务&#xff1a;系统电源状态管理和休眠运行锁管理。显示相关的能耗调节&#xff1a;包括根据环境光调节背光亮度&#xff0c;和根…...

【Rust自学】13.4. 闭包 Pt.4:使用闭包捕获环境

13.4.0. 写在正文之前 Rust语言在设计过程中收到了很多语言的启发&#xff0c;而函数式编程对Rust产生了非常显著的影响。函数式编程通常包括通过将函数作为值传递给参数、从其他函数返回它们、将它们分配给变量以供以后执行等等。 在本章中&#xff0c;我们会讨论 Rust 的一…...

在 macOS 上,用命令行连接 MySQL(/usr/local/mysql/bin/mysql -u root -p)

根据你提供的文件内容&#xff0c;MySQL 的安装路径是 /usr/local/mysql。要直接使用 mysql 命令&#xff0c;你需要找到 mysql 可执行文件的路径。 在 macOS 上&#xff0c;mysql 客户端通常位于 MySQL 安装目录的 bin 子目录中。因此&#xff0c;完整的路径应该是&#xff1…...

mono3d汇总

lidar坐标系 lidar坐标系可以简单归纳为标准lidar坐标系和nucense lidar坐标系&#xff0c;参考链接。这个坐标系和车辆的ego坐标系是一致的。 标准lidar坐标系 opendet3d&#xff0c;mmdetection3d和kitt都i使用了该坐标系 up z^ x front| /| /left y <------ 0kitti采…...

K8S 节点选择器

今天我们来实验 pod 调度的 nodeName 与 nodeSelector。官网描述如下&#xff1a; 假设有如下三个节点的 K8S 集群&#xff1a; k8s31master 是控制节点 k8s31node1、k8s31node2 是工作节点 容器运行时是 containerd 一、镜像准备 1.1、镜像拉取 docker pull tomcat:8.5-jre8…...

【2024年华为OD机试】 (C卷,200分)- 反射计数(Java JS PythonC/C++)

一、问题描述 题目解析 题目描述 给定一个包含 0 和 1 的二维矩阵&#xff0c;一个物体从给定的初始位置出发&#xff0c;在给定的速度下进行移动。遇到矩阵的边缘时会发生镜面反射。无论物体经过 0 还是 1&#xff0c;都不影响其速度。请计算并给出经过 t 时间单位后&#…...

AI编程工具使用技巧——通义灵码

活动介绍通义灵码1. 理解通义灵码的基本概念示例代码生成 2. 使用明确的描述示例代码生成 3. 巧妙使用注释示例代码生成 4. 注意迭代与反馈原始代码反馈后生成优化代码 5. 结合生成的代码进行调试示例测试代码 其他功能定期优化生成的代码合作与分享结合其他工具 总结 活动介绍…...

挖掘机检测数据集,准确识别率91.0%,4327张原始图片,支持YOLO,COCO JSON,PASICAL VOC XML等多种格式标注

挖掘机检测数据集&#xff0c;准确识别率91.0%&#xff0c;4327张图片&#xff0c;支持YOLO&#xff0c;COCO JSON&#xff0c;PASICAL VOC XML等多种格式标注 数据集详情 数据集分割 训练组70&#xff05; 3022图片 有效集20&#xff05; 870图片 测试集10&…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂&#xff08;如抗体、抑制肽&#xff09;在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上&#xff0c;高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术&#xff0c;但这类方法普遍面临资源消耗巨大、研发周期冗长…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

JAVA后端开发——多租户

数据隔离是多租户系统中的核心概念&#xff0c;确保一个租户&#xff08;在这个系统中可能是一个公司或一个独立的客户&#xff09;的数据对其他租户是不可见的。在 RuoYi 框架&#xff08;您当前项目所使用的基础框架&#xff09;中&#xff0c;这通常是通过在数据表中增加一个…...

LeetCode - 199. 二叉树的右视图

题目 199. 二叉树的右视图 - 力扣&#xff08;LeetCode&#xff09; 思路 右视图是指从树的右侧看&#xff0c;对于每一层&#xff0c;只能看到该层最右边的节点。实现思路是&#xff1a; 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...

AGain DB和倍数增益的关系

我在设置一款索尼CMOS芯片时&#xff0c;Again增益0db变化为6DB&#xff0c;画面的变化只有2倍DN的增益&#xff0c;比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析&#xff1a; 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...

算法:模拟

1.替换所有的问号 1576. 替换所有的问号 - 力扣&#xff08;LeetCode&#xff09; ​遍历字符串​&#xff1a;通过外层循环逐一检查每个字符。​遇到 ? 时处理​&#xff1a; 内层循环遍历小写字母&#xff08;a 到 z&#xff09;。对每个字母检查是否满足&#xff1a; ​与…...

动态 Web 开发技术入门篇

一、HTTP 协议核心 1.1 HTTP 基础 协议全称 &#xff1a;HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09; 默认端口 &#xff1a;HTTP 使用 80 端口&#xff0c;HTTPS 使用 443 端口。 请求方法 &#xff1a; GET &#xff1a;用于获取资源&#xff0c;…...

Netty从入门到进阶(二)

二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架&#xff0c;用于…...