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

张量与数据类型

Pytorch最基本的操作对象——张量(tensor),张量是Pytorch中重要的数据结构,可认为是一个高维数组。一般的,标量(scalar)是只有大小没有方向的量,如1、2、3等;向量(vector)是有大小和方向的量,如[1,2,3];矩阵(matrix)是由多个向量组成的,如[[1,2,3],[4,5,6]]。张量是基于向量和矩阵的推广,可以将标量视为零阶张量,向量可以视为一阶张量,矩阵是二阶张量。张量是支持高效的科学计算的数组,它可以是一个数(标量)、一维数组(向量)、二维数组(矩阵)和更高维的数组(高阶数据)。

1.1 PyTorch张量

PyTorch最基本的操作对象是张量,表示一个多维数组,张量类似NumPy的数组(ndarray),与ndarray不同的是,张量可以在GPU使用以加速计算。张量和NumPy的数组通常可以共享相同的低层内存,无须复制数据。
演示张量的创建和运算,首先导入PyTorch和NumPy,代码如下:

import torch
import numpy as np

1.1.1 初始化张量

可以使用多种形式初始化张量,如可直接从Python数据创建张量,无须指定类型,PyTorch会自动推荐其类型,可通过张量的dtype属性查看其类型。

t = torch.tensor([1, 2])      #创建一个张量     
print(t)                      #输出 tensor([1, 2])   
print(t.dtype)                #输出 torch.int64

代码输出:

tensor([1, 2])
torch.int64

在创建张量时,如果想直接创建为float类型,可使用torch.FloatTensor()方法;如果需要明确的创建为Int类型,可使用torch.LongTensor()方法。这两种类型是PyTorch中使用最多、最常见的两种类型。代码如下:

t = torch.FloatTensor([1, 2])
print(t)
print(t.dtype)

代码输出:

tensor([1., 2.])
torch.float32

======================= 代码分割线 =========================

t = torch.LongTensor([1, 2])
print(t)
print(t.dtype)

代码输出:

tensor([1, 2])
torch.int64

也可以使用torch.from_numpy()方法从NumPy数组ndarray张量。

np_array=np.array([[1,2],[3,4]])    #创建一个ndarray
t_np=torch.from_numpy(np_array)     #从ndarray创建张量
t_np

代码输出:

tensor([[1, 2],[3, 4]], dtype=torch.int32)

1.1.2 张量类型

PyTorch 张量的基础数据类型主要包含以下几种:

  1. torch.float32(或 torch.float):32 位浮动点数,最常用的数据类型,用于表示小数。
  2. torch.float64(或 torch.double):64 位浮动点数,用于需要更高精度的计算。
  3. torch.float16(或 torch.half):16 位浮动点数,常用于减少内存消耗和加速计算,尤其是在GPU上。
  4. torch.int8:8 位整数,用于表示整数值。
  5. torch.int16:16 位整数。
  6. torch.int32:32 位整数,常用整数类型。
  7. torch.int64(或 torch.long):64 位整数,通常用于较大的整数或索引。
  8. torch.uint8:8 位无符号整数,通常用于处理图像数据(如像素值)。
  9. torch.bool:布尔类型,值为 TrueFalse,用于逻辑运算。

不同数据类型适用于不同的任务和计算需求。在实际使用时,可以根据需求选择合适的张量数据类型,尤其是在性能和内存管理方面。
其中32位浮点型和64位整型是最常用的类型,这两种类型也常常被表示为torch.float和torch.long,也就是说,torch.float32等价于torch.float,torch.int64等价于torch.long,这两种类型正好对应上面的两种创建张量的方法torch.LongTensor()和torch.FloatTensor()。可在构造张量时使用dtype明确其类型。

t = torch.tensor([1,2], dtype=torch.float32)
print(t)
print(t.dtype)

代码输出:

tensor([1., 2.])
torch.float32

======================= 代码分割线 =========================

#也可以使用torch.float作为dtype的参数
t = torch.tensor([1,2], dtype=torch.float)
print(t)
print(t.dtype)

代码输出:

tensor([1., 2.])
torch.float32

======================= 代码分割线 =========================

print(torch.float==torch.float32)    #返回True
print(torch.long==torch.int64)       #返回True

代码输出:

True
True

以上代码中直接将torch.float与torch.float32做相等判断,判断后发现返回结果为True,说明这两个写法是完全等价的。PyTorch针对torch.float32与torch.int64类型有专门这样的简写形式是因为,这两种类型特别重要,模型的输入类型一般都是torch.float32,而模型分类问题的标签类型一般为torch.int64。
PyTorch中张量的类型可以使用type()方法转换,代码如下。

t = torch.tensor([1,2], dtype=torch.float32)
print(t.dtype)
#type()方法转换类型
t=t.type(torch.int64)
print(t.dtype)

代码输出:

torch.float32
torch.int64

编写代码过程中,由于转换为torch.float32和torh.int64两个类型最常见,框架提供了两个快捷的实例转换方法,即float()方法和long()方法。代码如下。

t = torch.tensor([1,2], dtype=torch.float32)
t=t.long()
print(t.dtype)
t=t.float()
print(t.dtype)

代码输出 :

torch.int64
torch.float32

1.1.3 创建随机值张量

可使用torch.rand()方法创建0~1均匀的随机数,使用torch.randn()方法创建标准正态分布随机数,使用torch.zeros()和torch.ones()方法创建全0和全1的张量,代码如下。

t = torch.rand(2, 3)
print(t)

代码输出:

tensor([[0.7330, 0.2682, 0.0917],[0.8569, 0.2710, 0.8089]])

======================= 代码分割线 =========================

t = torch.rand(2, 3)
print(t)

代码输出:

tensor([[0.5205, 0.9647, 0.5108],[0.7746, 0.4297, 0.5655]])

======================= 代码分割线 =========================

t = torch.zeros(3)
print(t)

代码输出:

tensor([0., 0., 0.])

======================= 代码分割线 =========================

t = torch.ones(3, 2)
print(t)

代码输出:

tensor([[1., 1.],[1., 1.],[1., 1.]])

还可以从另一个张量创建新的张量,除非明确覆盖,否则新的张量保留原来张量的属性(形状、数据类型),如下所示。

x = torch.zeros_like(t)      #类似的方法还有torch.ones_like()
print(x)

代码输出:

tensor([[0., 0.],[0., 0.],[0., 0.]])

======================= 代码分割线 =========================

x = torch.rand_like(t)     
print(x)

代码输出:

tensor([[0.2793, 0.3023],[0.5073, 0.3336],[0.7823, 0.4880]])

1.1.4 张量属性

tensor.shape属性可返回张量的形状,它与tensor.size()方法等价,后者更灵活,可以通过给定参数返回某一个维度的形状;tensor.dtype属性可返回当前张量的类型。代码如下。

t=torch.ones(2,3,dtype=torch.float64)
print(t.shape)         #输出torch.Size([2, 3])
print(t.size())        #输出torch.Size([2, 3])
print(t.size(1))       #输出第一维度大小 3   
print(t.dtype)         #输出torch.float64
print(t.device)        #输出cpu

代码输出:

torch.Size([2, 3])
torch.Size([2, 3])
3
torch.float64
cpu

可通过使用tensor.device属性查看当前张量所在的设备(device)。直接创建的张量都在内存中,所以显示的device是CPU,如果是显存中的张量,则显示为CUDA。

1.1.5 将张量移动到显存

张量可进行算术运算、线性代数、矩阵操作等计算,这些计算可以在CPU上运行,也可在GPU运行,在GPU上的运算速度通常高于CPU。默认情况下是在CPU创建张量。如果有可用的GPU,可以使用tensor.to()方法明确地将张量移动到GPU。代码如下。

#如果GPU可用,将张量移动到显存
if torch.cuda.is_available():t = t.to('cuda')
print(t.device)          #如果GPU可用,输出类似device(type='cuda',index=0)

代码输出:

cpu

在编码过程中,一般可用如下代码获取当前可用设备。

#获取当前可用设备
device="cuda" if torch.cuda.is_available() else "cpu"
print("Using {} device".format(device))     #打印当前可用设备
t=t.to(device)                              #将t放到当前可用设备上
print(t.device)                             #如果GPU可用,输出类似device(type='cuda',index=0)

代码输出:

Using cpu device
cpu

这样设置要比直接使用t.to(‘cuda’)更稳妥,可以确保代码中无论有无GPU都能正常运行,并且如果GPU可用就用GPU.

1.2 张量运算

张量的运算规则、切片索引规则与NumPy类似,运算中遵循广播原则和同形状相同位置元素对方运算的原则,代码如下。

t1 = torch.randn(2, 3)
t2 = torch.ones(2, 3)
print(t1 + 3)           #t1中每一个元素都加3
print(t1 + t2)          #t1与t2中每一个相同位置的元素相加
print(t1.add(t2))       #等价于t1+t2,结果与上面相同print(t1)               #输出当前t1值
t1.add_(t2)             #运行add_这个计算方法,add_方法中的下划线代表就地改变原值
print(t1)               #查看运行结果

代码输出:

tensor([[2.8404, 2.7435, 4.1129],[2.7789, 4.4589, 4.5274]])
tensor([[0.8404, 0.7435, 2.1129],[0.7789, 2.4589, 2.5274]])
tensor([[0.8404, 0.7435, 2.1129],[0.7789, 2.4589, 2.5274]])
tensor([[-0.1596, -0.2565,  1.1129],[-0.2211,  1.4589,  1.5274]])
tensor([[0.8404, 0.7435, 2.1129],[0.7789, 2.4589, 2.5274]])

在PyTorch中,如果一个运算方法后面加上下画线,代表就地改变原值,即t1.add_(t2)会直接将运算结果保存为t1,这样做可以节省内存,但是缺点是会直接改变t1原值,因为在使用的时候需要谨慎。
张量可以进行常见的算术运算,如abs(绝对值)、cunsum(累加)、divide(除)、floor_divide(整除)、mean(均值)、min(最小值)、max(最大值)、multiply(乘)等,这里不再一一演示。在深度学习中,矩阵运算常用到转置(tensor.T)和矩阵乘法(matmul或@),代码如下。

print(t1.matmul(t2.T))     #t1与t2的转置进行矩阵乘法
print(t1@(t2.T))           #与上一行运行等价,t1与t2的转置进行矩阵乘法  

代码输出:

tensor([[3.6968, 3.6968],[5.7652, 5.7652]])
tensor([[3.6968, 3.6968],[5.7652, 5.7652]])

对于只有一个元素的张量,可以使用tensor.item()方法将其转换为标量,也就是Python的基本类型。

t3 = t1.sum()
print(t3)              #t3是只有一个元素的张量
print(t3.item())       #输出一个Python浮点数 

代码输出:

tensor(9.4620)
9.461990356445312

以上代码中,首先将张量中所有的元素求和,得到只有一个元素的张量,然后使用tensor.item()方法将其转为标量,这种转换在我们希望打印模型正确率和损失值的时候很常见。

1.2.1 与NumPy数据类型的转换

1.1.1节演示了可使用torch.from_numpy()方法将ndarray转为张量,张量也可以使用tensor.numpy()方法得到它对应的ndarray数组,它们共用相同的内存。

### 与ndarray数据类型的转换import numpy as np
a = np.random.randn(2, 3)    #创建一个形状为(2,3)的ndarray
print(a)                     #输出此ndarray
t = torch.from_numpy(a)      #使用此ndarray创建一个张量
print(t)                     
print(t.numpy())             #使用tensor.numpy()方法获得张量对应的ndarray

代码输出:

[[ 0.22605693  0.04398624 -0.21096077][-0.66368309  1.23512604  2.0399825 ]]
tensor([[ 0.2261,  0.0440, -0.2110],[-0.6637,  1.2351,  2.0400]], dtype=torch.float64)
[[ 0.22605693  0.04398624 -0.21096077][-0.66368309  1.23512604  2.0399825 ]]

1.2.2 张量的变形

tensor.size()方法和tensor.shape属性可以返回张量的形状。当需要改变张量的形状时,可以通过tensor.view()方法,这个方法相当于NunPy中的reshape方法,用于改变张量的形状。需要注意的是,在转换过程要确保元素数量一致。代码如下。

t=torch.randn(4,6)    #创建一个形状为(4,6)的张量
print(t.shape)        #输出t的形状为torch.Size([4, 6])
t1=t.view(3,8)        #调整成(3,8)形状,这里元素数量是相等的
print(t1.shape)       #输出t1的形状为torch.Size([3, 8])

代码输出:

torch.Size([4, 6])
torch.Size([3, 8])

======================= 代码分割线 =========================

#现在我们需要将t展平为最后一个维度为1的张量
#第二个参数1代表第二维长度为1,参数-1表示根据元素个数自动计算第一维
t1=t.view(-1,1)
print(t1.shape)

代码输出:

torch.Size([24, 1])

======================= 代码分割线 =========================

# 也可以使用view增加维度,当然元素个数是不变的
t1=t.view(1,4,6)       #调整成三维的,其中第一维的长度为1
print(t1.shape)

代码输出:

torch.Size([1, 4, 6])

对于维度长度为1的张量,可以使用torch.squeeze()方法去掉长度为1的维度,相应的也有一 个增加长度为1维度的方法,即torch.unsqueeze(),代码如下。

t2=torch.squeeze(t1)
print(t2.shape)

代码输出:

torch.Size([4, 6])

======================= 代码分割线 =========================

t3=torch.unsqueeze(t2,0)     #参数0表示指定在第一个维度上增加维度
print(t3.shape)

代码输出:

torch.Size([1, 4, 6])

1.3 张量的自动微分

在PyTorch中,张量有一个requires_grad属性,可以在创建张量时指定些属性为True。如果requires_grad属性被设置为True,PyTorch将开始跟踪对此张量的所有计算,完成计算后,可以对计算结果调用backward() 方法,PyTorch将自动计算所有梯度。该张量的梯度将累加到.grad属性中。张量的grad_fn属性则指向运算生成此张量的方法。简单的说,张量的requires_grad属性用来明确是否跟踪张量的梯度,grad属性表示计算得到的梯度,grad_fn属性表示运算得到生成此张量的方法。代码演示如下。注意查看代码中的注释。

t = torch.ones(2, 2, requires_grad=True)    # 这里设置 requires_grad 为True
print(t.requires_grad)                      # 输出 True
print(t.grad)               # tensor.grad输出张量的梯度,这里输出 None,因为目前 t 没有梯度
print(t.grad_fn)            # tensor.grad_fn指向运算生成此张量的方法,这里为 None# 进行张量运算,得到 y
y = t + 5
print(y)           # 输出 tensor([[6., 6.],[6., 6.]], grad_fn=<AddBackward0>)
# y由于是运算而创建的,因此grad_fn属性不是空
print(y.grad_fn)   # 输出类似<AddBackward0 object at 0x00000237DF1A4250># 进行更多运算
z = y * 2
out = z.mean()     #求张量的均值,实例方法
print(out)         # 输出 tensor(12., grad_fn=<MeanBackward0>)

代码输出:

True
None
None
tensor([[6., 6.],[6., 6.]], grad_fn=<AddBackward0>)
<AddBackward0 object at 0x000001B460445750>
tensor(12., grad_fn=<MeanBackward0>)

上面的代码中,首先创建了张量,并指定requires_grad属性为True,因为这是一个新创建的张量,它的grad和grad_fn属性均为空。然后经过加法、乘法和取均值运算,得到了out这个最终结果。注意:现在out只有单个元素,它是一个标量值。下面在out上执行自动微分运算,并输出t的梯度(d(out)/d(x)微分运算的结果),代码如下。

out.backward()    # 自动微分运算, 注意 out 是标量值
print(t.grad)     #输出t的梯度,也就是d(out)/d(x)微分运算的结果

代码输出:

tensor([[0.5000, 0.5000],[0.5000, 0.5000]])

当张量的 requires_grad 属性为 True 时,PyTorch会一直跟踪记录此张量的运算;

print(t.requires_grad)           # 输出 True ,PyTorch框架会跟踪此张量的运算
s = t + 2                        # 进行运算,得到新的张量 s
print(s.requires_grad)           # 输出 True ,PyTorch框架会继续跟踪此张量的运算

代码输出:

True
True

也可使用 tensor.detach() 来获得具有相同内容但不需要跟踪运算的新张量,可以认为获取张量的值,代码如下。

print(out.requires_grad)     # 输出 True
s = out.detach()             # 获取out的值,也可以使用out.data()方法
print(s.requires_grad)       # 输出 False

代码输出:

True
False

可以使用 requires_grad_() 就地改变张量的这个属性,当我们希望模型的参数不再随着训练变化时,可以用此方法,代码如下:

print(t.requires_grad)      # 输出 True
t.requires_grad_(False)     # 就地改变requires_grad为False
print(t.requires_grad)      # 输出 False

代码输出:

True
False

1.4 小结

讲解了张量的创建、PyTorch数据类型、张量运算、张量自动微分等基础知识,这是PyTorch中比较基础的内容。

相关文章:

张量与数据类型

Pytorch最基本的操作对象——张量&#xff08;tensor&#xff09;&#xff0c;张量是Pytorch中重要的数据结构&#xff0c;可认为是一个高维数组。一般的&#xff0c;标量&#xff08;scalar&#xff09;是只有大小没有方向的量&#xff0c;如1、2、3等&#xff1b;向量&#x…...

torchvision.utils.make_grid 解释下

torchvision.utils.make_grid 是 PyTorch 中 torchvision 库提供的一个实用函数,用于将多个图像拼接成一个网格,方便进行可视化。 主要功能 make_grid 将一批图片组织成一个网格形式,输出一个单一的张量,便于使用可视化工具(如 Matplotlib)查看图像。 参数解释 torchvi…...

Android原生Widget使用步骤

需要创建三个XML文件以及一个Class文件 三个XML文件分别是 Widget布局文件 <?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_p…...

实验八 指针2

7-1 利用指针返回多个函数值 分数 30 全屏浏览 切换布局 作者 陈晓梅 单位 广东外语外贸大学 读入n个整数&#xff0c;调用max_min()函数求这n个数中的最大值和最小值。 输入格式: 输入有两行&#xff1a; 第一行是n值&#xff1b; 第二行是n个数。 输出格式: 输出最大…...

1 数据库(下):多表设计 、多表查询 + SQL中的with查询语法(MySQL8.0以后版本才支持这种新语法)+ 数据库优化(索引优化)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、多表设计1 多表设计-概述2 三种多表关系一对多&#xff08;多对一&#xff09;&#xff08;1&#xff09;无外键约束&#xff08;逻辑外键&#xff09;&…...

什么是.net framework,什么是.net core,什么是.net5~8,版本对应关系

我不知道有多少人和我一样&#xff0c;没学习过.netCore&#xff0c;想要学习&#xff0c;但是版本号太多就蒙了&#xff0c;不知道学什么了&#xff0c;这里解释下各个版本的关系 我们一般开始学习微软的时候&#xff0c;都是开始学习的.netframework&#xff0c;常用的就是4…...

vulhub-wordpress靶场

一.主题上传漏洞 来到靶场点击主题选择add new 这里有一个上传主题的地方 我们可以去网上找到wordpress主题下载一个 wordpress模板 网页设计模板 免费 免费下载 - 爱给网 下载完成后对我们有用的东西只有这一个目录&#xff0c;把它拖出来 点开moban目录后&#xff0c;创建…...

安装与配置

《PHP Libxml》是一个在PHP中处理XML和HTML文档的重要库。它提供了丰富的API&#xff0c;支持DOM、SimpleXML和XMLReader等多种解析方式&#xff0c;广泛应用于各种编程语言和项目中。 安装与配置 安装: 在PHP中&#xff0c;libxml扩展通常是默认启用的。如果你需要手动安装&…...

斗鱼Android面试题及参考答案

常用的图片框架有哪些? Glide:是一个快速高效的 Android 图片加载库,专注于平滑滚动。它支持多种图片格式,包括 GIF,具有高效的缓存策略,能自动管理图片的生命周期,避免内存泄漏和 OOM 错误。其 API 简洁易用,可轻松实现图片的加载、显示和缓存等功能,如一行代码即可实…...

Could not install Gradle distribution from 的解决办法

在安装完成AndroidStudio之后,运行工程出现如下错误 Could not install Gradle distribution from https://services.gradle.org/distributions/gradle-6.5-bin.zip. 错误原因是:对应版本的Gradle文件下载失败了,我这里是gradle-6.5-bin.zip,不同版本的android studio也可…...

基于 SensitiveWordBs 实现敏感词过滤功能

在现代的互联网应用中&#xff0c;敏感词过滤已成为一个必不可少的功能&#xff0c;尤其是在社交媒体、评论审核等需要保证内容健康的场景下。本文将基于开源库https://github.com/houbb/sensitive-word&#xff0c;详细讲解如何通过自定义敏感词库和工具类实现高效的敏感词过滤…...

网络安全威胁2024年中报告

下载地址&#xff1a; 网络安全威胁2024年中报告-奇安信...

批次特征组杂记

批次特征组杂记 运维的时候新增了一个批次特征&#xff0c;然后发现不能按照要求跑到之前已经分好的批次特征组。 研究了半天原来是通过布局实现的。 特此记录。...

【HarmonyOS】解决自定义弹框和键盘之间安全距离的问题

【HarmonyOS】解决自定义弹框和键盘之间安全距离的问题 一、问题背景 我们在应用开发评论输入框时&#xff0c;常规的需求样式是&#xff1a;输入框view和键盘贴近&#xff0c;上半部展示信息区的形式&#xff0c;这样的设计&#xff0c;方便用户不割裂的去评论发言。 但是在…...

如何在LabVIEW中更好地使用ActiveX控件?

在LabVIEW中&#xff0c;ActiveX控件可以帮助实现与其他应用程序或第三方组件的集成&#xff08;例如Microsoft Excel、Word、Internet Explorer等&#xff09;。以下是一些建议&#xff0c;帮助您更好地在LabVIEW中使用ActiveX控件&#xff1a; ​ 1. 理解ActiveX控件的基本原…...

【视觉SLAM:四、相机与图像】

相机模型 相机模型是计算机视觉中的重要内容&#xff0c;用于描述真实相机如何将三维世界投影到二维图像平面。以下从多个角度介绍常见的相机模型。 针孔相机模型 针孔相机模型是最简单的相机模型&#xff0c;用数学公式描述从三维世界到二维图像平面的映射关系。核心公式如…...

如何利用无线路由器实现水泵房远程监测管理

水泵站广泛部署应用在工农业用水、防洪、排涝和抗旱减灾等方面&#xff0c;如果水泵站发生异常&#xff0c;往往会对生产生活造成诸多损失&#xff0c;甚至引发安全事故。因此&#xff0c;建立一套高效、可靠的泵站远程监测管理系统至关重要。 方案背景 目前&#xff0c;我国大…...

使用ArcGIS Pro自带的Notebook计算多个遥感指数

在之前的分享中&#xff0c;我们介绍了如何使用ArcPy将GEE下载的遥感影像转为单波段文件。基于前面创建的单波段文件&#xff0c;我们可以一次性计算多种遥感指数&#xff0c;例如NDVI、EVI、NDSI等。我这里直接在ArcGIS Pro中自带的Notebook进行的运行。如下图所示&#xff0c…...

宝塔-firefox(Docker应用)-构建自己的Web浏览器

安装基础软件 宝塔中安装firefox(Docker应用) 。宝塔中需要先安装docker及docker-composefirefox配置安装 点击firefox应用&#xff0c;选择【安装配置】点击右边绿色按钮&#xff0c;进行安装&#xff0c;这一步等待docker-compose根据你的配置初始化docker应用 等待安装 …...

OpenCV-Python实战(8)——图像变换

一、缩放 cv2.resize() img cv2.resize(src*,dsize*,fx*,fy*,interpolation*) img&#xff1a;目标图像。 src&#xff1a;原始图像。 dsize&#xff1a;&#xff08;width&#xff0c;height&#xff09;图像大小。 fx、fy&#xff1a;可选参数&#xff0c;水平/垂直方向…...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

React第五十七节 Router中RouterProvider使用详解及注意事项

前言 在 React Router v6.4 中&#xff0c;RouterProvider 是一个核心组件&#xff0c;用于提供基于数据路由&#xff08;data routers&#xff09;的新型路由方案。 它替代了传统的 <BrowserRouter>&#xff0c;支持更强大的数据加载和操作功能&#xff08;如 loader 和…...

Java 8 Stream API 入门到实践详解

一、告别 for 循环&#xff01; 传统痛点&#xff1a; Java 8 之前&#xff0c;集合操作离不开冗长的 for 循环和匿名类。例如&#xff0c;过滤列表中的偶数&#xff1a; List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...