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

The Rust Programming Language 学习 (二)

通用编程概念

变量和可变性

默认情况下变量是不可变的(immutable),不过你也可以选择让变量是可变的(mutable).

变量的遮蔽

你可以声明和前面变量具有相同名称的新变量,说这个是第一个变量被第二个变量遮蔽(shadow),这意味着当我们使用变量时我们看到的会是第二个变量的值。我们可以通过使用相同的变量名并重复使用 let 关键字来遮蔽变量,如下程序并不会报错:

let x = 5;
let x = x+1;
{let x = x*3;
}
let x = String::new();

遮蔽和将变量标记为 mut 的方式不同,因为除非我们再次使用 let 关键字,否则若是我们不小心尝试重新赋值给这个变量,我们将得到一个编译错误。通过使用 let,我们可以对一个值进行一些转换,但在这些转换完成后,变量将是不可变的。

mut 和遮蔽之间的另一个区别是,因为我们在再次使用 let 关键字时有效地创建了一个新的变量,所以我们可以改变值的类型,但重复使用相同的名称。

常量

与不可变变量类似,常量(constant)是绑定到一个常量名且不允许更改的值,但是常量和变量之间存在一些差异。

首先,常量不允许使用 mut。常量不仅仅默认不可变,而且自始至终不可变。常量使用 const 关键字而不是 let 关键字来声明,并且值的类型必须注明。

最后一个不同点是常量只能设置为常量表达式或能在运行时计算得到的值。,而不能是函数调用的结果.

Rust 常量的命名约定是全部字母都使用大写,并使用下划线分隔单词。

将整个程序中用到的硬编码(hardcode)值命名为常量,对于将该值的含义传达给代码的未来维护者很有用。如果将来需要更改硬编码的值,则只需要在代码中改动一处就可以了。

数据类型

Rust 的每个值都有确切的数据类型(data type),该类型告诉 Rust 数据是被指定成哪类数据,从而让 Rust 知道如何使用该数据。

请记住 Rust 是一种静态类型(statically typed)的语言,这意味着它必须在编译期知道所有变量的类型。编译器通常可以根据值和使用方式推导出我们想要使用的类型。

标量类型

标量(scalar)类型表示单个值。Rust 有 4 个基本的标量类型:整型、浮点型、布尔型和字符。

整数

整数(integer)是没有小数部分的数字

举个例子u32 类型。此类型声明表明它关联的值应该是占用 32 位空间的无符号整型(有符号整型以 i 开始,i 是英文单词 integer 的首字母,与之相反的是 u,代表无符号 unsigned 类型)

长度有符号类型无符号类型
8 位i8u8
16 位i16u16
32 位i32u32
64 位i64u64
128 位i128u128
archisizeusize

有符号数字以二进制补码形式存储

此外,isize 和 usize 类型取决于程序运行的计算机体系结构,在表中表示为“arch”:若使用 64 位架构系统则为 64 位,若使用 32 位架构系统则为 32 位。

数字字面量示例
十进制98_222
十六进制0xff
八进制0o77
二进制0b1111_0000
字节 (仅限于 u8)b'A'
整型溢出

比方说有一个 u8 ,它可以存放从 0 到 255 的值。那么当你将其修改为范围之外的值,比如 256,则会发生整型溢出(integer overflow),这会导致两种行为的其中一种。当在调试(debug)模式编译时,Rust 会检查整型溢出,若存在这些问题则使程序在编译时 panic.Rust 使用 panic 这个术语来表明程序因错误而退出。

在当使用 --release 参数进行发布(release)模式构建时,Rust 不检测会导致 panic 的整型溢出。相反当检测到整型溢出时,Rust 会进行一种被称为二进制补码包裹(two’s complement wrapping)的操作。简而言之,大于该类型最大值的数值会被“包裹”成该类型能够支持的对应数字的最小值。比如在 u8 的情况下,256 变成 0,257 变成 1,依此类推。程序不会 panic,但是该变量的值可能不是你期望的值。依赖整型溢出包裹的行为不是一种正确的做法。

要显式处理溢出的可能性,可以使用标准库针对原始数字类型提供的以下一系列方法:

  • 使用 wrapping_* 方法在所有模式下进行包裹,例如 wrapping_add
  • 如果使用 checked_* 方法时发生溢出,则返回 None 值
  • 使用 overflowing_* 方法返回该值和一个指示是否存在溢出的布尔值
  • 使用 saturating_* 方法使值达到最小值或最大值

浮点型

浮点数(floating-point number)是带有小数点的数字,在 Rust 中浮点类型(简称浮点型)数字也有两种基本类型。Rust 的浮点型是 f32 和 f64,它们的大小分别为 32 位和 64 位。默认浮点类型是 f64,因为在现代的 CPU 中它的速度与 f32 的几乎相同,但精度更高。所有浮点型都是有符号的。f32 类型是单精度浮点型,f64 为双精度浮点型。

数字运算

Rust 的所有数字类型都支持基本数学运算:加法、减法、乘法、除法和取模运算。整数除法会向下取整。

布尔型

和大多数编程语言一样,Rust 中的布尔类型也有两个可能的值:true 和 false。布尔值的大小为 1 个字节.

字符类型

Rust 的 char(字符)类型是该语言最基本的字符类型

注意,我们声明的 char 字面量采用单引号括起来,这与字符串字面量不同,字符串字面量是用双引号括起来。Rust 的字符类型大小为 4 个字节,表示的是一个 Unicode 标量值,这意味着它可以表示的远远不止是 ASCII。标音字母,中文/日文/韩文的文字,emoji,还有零宽空格(zero width space)在 Rust 中都是合法的字符类型。Unicode 值的范围为 U+0000 ~ U+D7FF 和 U+E000~U+10FFFF。不过“字符”并不是 Unicode 中的一个概念,所以人在直觉上对“字符”的理解和 Rust 的字符概念并不一致。

补充一下计算机基础知识

一个字节(byte)由 8 位(bit) 组成。这是计算机科学中标准的定义

位(bit):是计算机中最小的数据单位,它可以表示两种状态之一,通常用 0 或 1 表示

字节(byte):是计算机存储数据的基本单位。一个字节由 8 个位组成,可以表示 2的8次方=256 种不同的值(从 0 到 255)。

1 字节 (Byte) = 8 位 (bit)
1 千字节 (KB) = 1024 字节 (B)
1 兆字节 (MB) = 1024 千字节 (KB)
1 吉字节 (GB) = 1024 兆字节 (MB)

复合类型

复合类型(compound type)可以将多个值组合成一个类型。Rust 有两种基本的复合类型:元组(tuple)和数组(array)。

元组

元组是将多种类型的多个值组合到一个复合类型中的一种基本方式。元组的长度是固定的:声明后,它们就无法增长或缩小。

我们通过在小括号内写入以逗号分隔的值列表来创建一个元组。元组中的每个位置都有一个类型,并且元组中不同值的类型不要求是相同的。

let tup: (i32, f64, u8) = (500, 6.4, 1);

变量 tup 绑定到整个元组,因为元组被认作是单个复合元素。 想从元组中获取个别值,我们可以使用模式匹配来解构(destructure)元组的一个值

let tup = (500, 6.4, 1);
let (x, y, z) = tup;

该程序首先创建一个元组并将其绑定到变量 tup 上。 然后它借助 let 来使用一个模式匹配 tup,并将它分解成三个单独的变量 x、y 和 z。 这过程称为解构(destructuring)

除了通过模式匹配进行解构外,我们还可以使用一个句点(.)连上要访问的值的索引来直接访问元组元素

let x: (i32, f64, u8) = (500, 6.4, 1);
let five_hundred = x.0;
let six_point_four = x.1;
let one = x.2;

该程序创建一个元组 x,然后通过使用它们的索引为每个元素创建新的变量。和大多数编程语言一样,元组中的第一个索引为 0。

没有任何值的元组 () 是一种特殊的类型,只有一个值,也写成 ()。该类型被称为单元类型(unit type),该值被称为单元值(unit value)。如果表达式不返回任何其他值,就隐式地返回单元值。

数组类型

将多个值组合在一起的另一种方式就是使用数组(array)。与元组不同,数组的每个元素必须具有相同的类型。与某些其他语言中的数组不同,Rust 中的数组具有固定长度。

我们在方括号内以逗号分隔的列表形式将值写到数组中:

let a = [1, 2, 3, 4, 5];
// 数组的另一种声明方式 i32 是每个元素的类型。分号之后,数字 5 表明该数组包含 5 个元素。
let a: [i32; 5] = [1, 2, 3, 4, 5];
// 指定初始值,和个数的数组
let a = [3; 5];
访问数组元素

数组是可以在栈上分配的已知固定大小的单个内存块。可以使用索引访问数组的元素

let a = [1, 2, 3, 4, 5];
let first = a[0];
let second = a[1];

在这个例子中,名为 first 的变量将获得值 1,因为它是数组中索引 [0] 处的值。名为 second 的变量将从数组中的索引 [1] 中获取得 2。

当你尝试使用索引访问元素时,Rust 将检查你指定的索引是否小于数组长度。如果索引大于或等于数组长度,Rust 会出现 panic。这种检查必须在运行时进行,尤其是在这种情况下,因为编译器可能无法知道用户之后运行代码时将输入什么值。

函数

Rust 代码中的函数和变量名使用下划线命名法(snake case,直译为蛇形命名法)规范风格。在下划线命名法中,所有字母都是小写并使用下划线分隔单词。

Rust 中的函数定义以 fn 开始,后跟着函数名和一对圆括号。大括号告诉编译器函数体在哪里开始和结束。

可以使用函数名后跟圆括号来调用我们定义过的任意函数。函数的定义位置无关紧要,不用非要像c语言那样一定要在面之前或者在面之前需要一个定义.Rust 不关心函数定义于何处,只要定义了就行。

参数

函数也可以被定义为拥有参数(parameter),参数是特殊变量,是函数签名的一部分。当函数拥有参数(形参)时,可以为这些参数提供具体的值(实参)。技术上讲,这些具体值被称为实参(argument),但是在日常交流中,人们倾向于不区分使用 parameter 和 argument 来表示函数定义中的变量或调用函数时传入的具体值。

在函数签名中,必须声明每个参数的类型。这是一个 Rust 设计中经过慎重考虑的决定:要求在函数定义中提供类型标注,意味着编译器几乎从不需要你在代码的其他地方注明类型来指出你的意图。

语句和表达式

Rust 是一门基于表达式(expression-based)的语言.

语句(statement)是执行一些操作但不返回值的指令。表达式(expression)计算并产生一个值

{let x = 3;x + 1
}

这是一个表达式,注意,x + 1 行的末尾没有分号,这与你目前见过的大部分代码行不同。表达式的结尾没有分号。如果在表达式的末尾加上分号,那么它就转换为语句,而语句不会返回值。在接下来探讨函数返回值和表达式时,请记住这一点。

记住,代码块的值是其最后一个表达式的值,而数字本身就是一个表达式

带有返回值的函数

函数可以向调用它的代码返回值。我们并不对返回值命名,但要在箭头(->)后声明它的类型。在 Rust 中,函数的返回值等同于函数体最后一个表达式的值。使用 return 关键字和指定值,可以从函数中提前返回;但大部分函数隐式返回最后一个表达式。这是一个有返回值函数的例子:

fn five() -> i32 {5
}fn main() {let x = five();println!("The value of x is: {}", x);
}

在 five 函数中没有函数调用、宏,甚至没有 let 语句——只有数字 5 本身。这在 Rust 中是一个完全有效的函数。注意,函数返回值的类型也被指定好,即 -> i32

注释

//  单行注释/*多行注释
*//// 文档注释
/// 说明函数功能等/**
* 文档注释
* 用于说明函数功能等	
*/

控制流

if表达式

if number < 5 {println!("condition was true");
} else {println!("condition was false");
}

if 表达式中与条件关联的代码块有时被叫做分支(arm)和 match 表达式中的分支一样.

另外值得注意的是代码中的条件必须是 bool 值。如果条件不是 bool 值,我们将得到一个错误

else if

    if number % 4 == 0 {println!("number is divisible by 4");} else if number % 3 == 0 {println!("number is divisible by 3");} else if number % 2 == 0 {println!("number is divisible by 2");} else {println!("number is not divisible by 4, 3, or 2");}

在let语句中使用if

因为 if 是一个表达式,我们可以在 let 语句的右侧使用它来将结果赋值给一个变量

	let condition = true;let number = if condition { 5 } else { 6 };

使用循环重复执行

loop

loop 关键字告诉 Rust 一遍又一遍地执行一段代码直到你明确要求停止。

	loop {println!("again!");}

Rust 也提供了一种从代码中跳出循环的方法。可以使用 break 关键字来告诉程序何时停止循环,循环中的 continue 关键字告诉程序跳过这个循环迭代中的任何剩余代码,并转到下一个迭代。

如果存在嵌套循环,break 和 continue 应用于此时最内层的循环。你可以选择在一个循环上指定一个循环标签(loop label),然后将标签与 break 或 continue 一起使用,使这些关键字应用于已标记的循环而不是最内层的循环。下面是一个包含两个嵌套循环的示例:

fn main() {let mut count = 0;'counting_up: loop {println!("count = {}", count);let mut remaining = 10;loop {println!("remaining = {}", remaining);if remaining == 9 {break;}if count == 2 {break 'counting_up;}remaining -= 1;}count += 1;}println!("End count = {}", count);
}

从循环返回

loop 的一个用例是重试可能会失败的操作,比如检查线程是否完成了任务。然而你可能会需要将操作的结果从循环中传递给其它的代码。为此,你可以在用于停止循环的 break 表达式添加你想要返回的值;该值将从循环中返回,以便您可以使用它,如下所示:

fn main() {let mut counter = 0;let result = loop {counter += 1;if counter == 10 {break counter * 2;}};println!("The result is {}", result);
}

while 条件循环

fn main() {let mut number = 3;while number != 0 {println!("{}!", number);number -= 1;}println!("LIFTOFF!!!");
}

使用for遍历集合

fn main() {let a = [10, 20, 30, 40, 50];for element in a {println!("the value is: {}", element);}
}
fn main() {for number in (1..4).rev() {println!("{}!", number);}println!("LIFTOFF!!!");
}

相关文章:

The Rust Programming Language 学习 (二)

通用编程概念 变量和可变性 默认情况下变量是不可变的&#xff08;immutable&#xff09;,不过你也可以选择让变量是可变的&#xff08;mutable&#xff09;. 变量的遮蔽 你可以声明和前面变量具有相同名称的新变量,说这个是第一个变量被第二个变量遮蔽&#xff08;shadow&…...

http链接转成https的链接的几种方法

以下是一个将HTTP链接转换为HTTPS的JavaScript函数&#xff0c;处理了多种常见输入情况&#xff1a; function convertToHttps(url) {if (typeof url ! string) return url;// 移除首尾空格并处理空字符串const trimmedUrl url.trim();if (!trimmedUrl) return https://;// 替…...

STM32——串口通信 UART

一、基础配置 Universal Asynchronous Receiver Transmitter 异步&#xff0c;串行&#xff0c;全双工 TTL电平 &#xff1a;高电平1 低电平0 帧格式&#xff1a; 起始位1bit 数据位8bit 校验位1bit 终止位1bit NVIC Settings一栏使能接受中断。 之前有设置LCD&#xff0c;…...

mybatis日期格式与字符串不匹配bug

异常特征&#xff1a;java.lang.IllegalArgumentException: invalid comparison: java.time.LocalDateTime and java.lang.String ### Error updating database. Cause: java.lang.IllegalArgumentException: invalid comparison: java.time.LocalDateTime and java.lang.Str…...

文献分享: ConstBERT固定数目向量编码文档

&#x1f602;图放这了&#xff0c;大道至简的 idea \text{idea} idea不愧是 ECIR \text{ECIR} ECIR &#x1f449;原论文 1. ConstBERT \textbf{1. ConstBERT} 1. ConstBERT的原理 1️⃣模型的改进点&#xff1a;相较于 ColBERT \text{ColBERT} ColBERT为每个 Token \text{Tok…...

学习记录-用例设计编写

黑马测试视频记录 目录 一、 软件测试流程 二、测试用例编写格式 1、等价类法 2、边界值分析法 3、 判定表法 4、场景法​编辑 5、错误推荐法 一、 软件测试流程 二、测试用例编写格式 1、等价类法 2、边界值分析法 3、 判定表法 4、场景法 5、错误推荐法 时间紧任务重…...

学习工具的一天之(burp)

第一呢一定是先下载 【Java环境】&#xff1a;Java Downloads | Oracle 下来是burp的下载 Download Burp Suite Community Edition - PortSwigger 【下载方法二】关注的一个博主 【BurpSuite 安装激活使用详细上手教程 web安全测试工具】https://www.bilibili.com/video/BV…...

el-tree右键节点动态位置展示菜单;el-tree的节点图片动态根据节点属性color改变背景色;加遮罩层(opacity)

一、el-tree右键节点动态位置展示菜单 关键:@node-contextmenu="handleRightClick"与@node-click=“handleNodeClick” <div class="content"><el-tabs class="tabs" @tab-click="handleClick" v-model="Modal"…...

K8s 1.27.1 实战系列(一)准备工作

一、主机规划与硬件要求 1、节点数量 至少需要 3 台服务器(1 台 Master 节点,2 台 Worker 节点)。本地测试可缩容:若仅用于测试,可缩减为 1 个 Master 和 1 个 Worker,但需注意稳定性风险。2、硬件配置 ​Master 节点:建议 2 核 CPU、8GB 内存、80GB 硬盘。​Worker 节…...

说一下SpringBoot3新特新和JDK17新特性

JDK1.8&#xff08;Java8&#xff09;新特性 stream流式编程 流处理 Stream API 提供了对集合数据进行操作的一种高效、简洁的方式。它支持顺序和并行的聚合操作 如&#xff1a;过滤&#xff08;filter&#xff09;、排序&#xff08;sort&#xff09;、映射&#xff08;map&…...

Linux系统服务安全检测手记

一&#xff1a;服务器ip暴露ip和端口的安全问题 服务器IP和端口暴露在外网中确实存在一定的安全风险&#xff0c;以下是几个主要的安全问题及相应的缓解措施&#xff1a; ### 主要安全问题 1. **直接攻击**&#xff1a; - 暴露的IP地址和开放的端口可能成为黑客直接攻击的…...

鸿蒙与DeepSeek深度整合:构建下一代智能操作系统生态

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 https://www.captainbed.cn/north 目录 技术融合背景与价值鸿蒙分布式架构解析DeepSeek技术体系剖析核心整合架构设计智能调度系统实现…...

[创业之路-329]:华为铁三角实施的步骤

一、通用过程 华为铁三角实施的步骤主要包括以下几个关键阶段&#xff1a; 1、明确角色与职责 确定铁三角成员&#xff1a;组建由客户经理&#xff08;AR&#xff09;、解决方案经理&#xff08;SR&#xff09;和交付经理&#xff08;FR&#xff09;组成的铁三角团队。制定岗…...

1.15-16-17-18迭代器与生成器,函数,数据结构,模块

目录 15&#xff0c;Python3 迭代器与生成器15-1 迭代器15-1-1 基础知识15-1-2 迭代器与for循环工作原理 15-2 生成器&#xff08;本质就是迭代器&#xff09;15-2-1 yield 表达式15-2-2 三元表达式15-2-3 列表生成式15-2-4 其他生成器&#xff08;——没有元祖生成式——&…...

java面向对象(详细讲解)

第一章 类和对象 1.面向对象的介绍 1.面向过程&#xff1a;自己的事情自己做&#xff0c;代表语言c语言 2.面向对象&#xff1a;自己的事情别人做&#xff0c;代表语言java 3.为啥要使用面向对象思想编程&#xff1a;很多功能别人给我们实现好了&#xff0c;我们只需要拿过…...

代码随想录二刷|图论2

图论 基础知识 1 无向图 &#xff08;1&#xff09;度&#xff1a;一个顶点连n条边就度为n &#xff08;2&#xff09;权 加权无向图&#xff1a;有边长的无向图 &#xff08;3&#xff09;通道&#xff1a;两个顶点之间有一些边和点&#xff0c;并且没有重复的边 路&am…...

毕业项目推荐:基于yolov8/yolov5/yolo11的暴力行为检测识别系统(python+卷积神经网络)

文章目录 概要一、整体资源介绍技术要点功能展示&#xff1a;功能1 支持单张图片识别功能2 支持遍历文件夹识别功能3 支持识别视频文件功能4 支持摄像头识别功能5 支持结果文件导出&#xff08;xls格式&#xff09;功能6 支持切换检测到的目标查看 二、数据集三、算法介绍1. YO…...

服务器CPU微架构

1、微架构图 前端&#xff1a;预解码、解码、分支预测、L1指令缓存、指令TLB缓存 后端&#xff1a;顺序重排缓存器ROB处理依赖&#xff0c;调度器送到执行引擎 执行引擎&#xff1a;8路超标量&#xff0c;每一路可以进行独立的微操作处理 Port0、1、5、6支持整数、浮点数的加…...

用本地浏览器打开服务器上使用的Tensorboard

文章目录 前言一、Tensorboard的安装二、使用步骤1.服务器上的设置2.在本地打开 总结 前言 最近有使用服务器上的Tensorboard的需求&#xff0c;踩了几个雷&#xff0c;现已在搜索和帮助下解决&#xff0c;总结于此。 一、Tensorboard的安装 pip install tensorboard2.12.0注…...

Nginx或Tengine服务器配置SSL证书

本文将全面介绍如何在Nginx或Tengine服务器配置SSL证书&#xff0c;具体包括下载和上传证书文件&#xff0c;在Nginx上配置证书文件、证书链和证书密钥等参数&#xff0c;以及安装证书后结果的验证。成功配置SSL证书后&#xff0c;您将能够通过HTTPS加密通道安全访问Nginx服务器…...

利用ngx_stream_return_module构建简易 TCP/UDP 响应网关

一、模块概述 ngx_stream_return_module 提供了一个极简的指令&#xff1a; return <value>;在收到客户端连接后&#xff0c;立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量&#xff08;如 $time_iso8601、$remote_addr 等&#xff09;&a…...

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

MySQL 8.0 事务全面讲解

以下是一个结合两次回答的 MySQL 8.0 事务全面讲解&#xff0c;涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容&#xff0c;并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念&#xff08;ACID&#xff09; 事务是…...

Unity UGUI Button事件流程

场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...

uniapp 实现腾讯云IM群文件上传下载功能

UniApp 集成腾讯云IM实现群文件上传下载功能全攻略 一、功能背景与技术选型 在团队协作场景中&#xff0c;群文件共享是核心需求之一。本文将介绍如何基于腾讯云IMCOS&#xff0c;在uniapp中实现&#xff1a; 群内文件上传/下载文件元数据管理下载进度追踪跨平台文件预览 二…...

QT开发技术【ffmpeg + QAudioOutput】音乐播放器

一、 介绍 使用ffmpeg 4.2.2 在数字化浪潮席卷全球的当下&#xff0c;音视频内容犹如璀璨繁星&#xff0c;点亮了人们的生活与工作。从短视频平台上令人捧腹的搞笑视频&#xff0c;到在线课堂中知识渊博的专家授课&#xff0c;再到影视平台上扣人心弦的高清大片&#xff0c;音…...

相关类相关的可视化图像总结

目录 一、散点图 二、气泡图 三、相关图 四、热力图 五、二维密度图 六、多模态二维密度图 七、雷达图 八、桑基图 九、总结 一、散点图 特点 通过点的位置展示两个连续变量之间的关系&#xff0c;可直观判断线性相关、非线性相关或无相关关系&#xff0c;点的分布密…...

ubuntu中安装conda的后遗症

缘由: 在编译rk3588的sdk时&#xff0c;遇到编译buildroot失败&#xff0c;提示如下&#xff1a; 提示缺失expect&#xff0c;但是实测相关工具是在的&#xff0c;如下显示&#xff1a; 然后查找借助各个ai工具&#xff0c;重新安装相关的工具&#xff0c;依然无解。 解决&am…...

StarRocks 全面向量化执行引擎深度解析

StarRocks 全面向量化执行引擎深度解析 StarRocks 的向量化执行引擎是其高性能的核心设计&#xff0c;相比传统行式处理引擎&#xff08;如MySQL&#xff09;&#xff0c;性能可提升 5-10倍。以下是分层拆解&#xff1a; 1. 向量化 vs 传统行式处理 维度行式处理向量化处理数…...

[特殊字符] Spring Boot底层原理深度解析与高级面试题精析

一、Spring Boot底层原理详解 Spring Boot的核心设计哲学是约定优于配置和自动装配&#xff0c;通过简化传统Spring应用的初始化和配置流程&#xff0c;显著提升开发效率。其底层原理可拆解为以下核心机制&#xff1a; 自动装配&#xff08;Auto-Configuration&#xff09; 核…...