Rust 猜数字游戏:从 0 到 1 的完整实现与深入解析
一、项目概述
1.1 为什么选择“猜数字”?
“猜数字”是编程入门中非常经典的一个项目。它看似简单,却能很好地展示:
- 输入输出 (I/O):提示用户输入并读取内容。
- 随机数:每次运行生成一个随机值,保证游戏的多样性。
- 逻辑判断与控制流:比较大小并给出提示。
- 错误处理:当用户输入不合法内容时,我们如何应对?
- 循环:允许玩家多次猜测,直到猜对为止。
这些功能组合起来,就能覆盖 Rust 中相当多的常用特性和写法,非常适合用来练手和深入理解语言机制。
1.2 本文内容预览
- 环境准备与项目初始化:安装 Rust,创建新项目结构。
- 用户输入与输出:使用 Rust 标准库
std::io
读写命令行数据。 - 随机数生成:学习如何在
Cargo.toml
中添加依赖并使用社区库rand
。 - 字符串解析与比较:将输入的字符串转为数字,并比较与随机数的大小。
- 循环与错误处理:通过
loop
允许多次猜测,使用match
处理各种错误场景。 - 总结与扩展:提供改进思路,例如多模式输入、添加回合数等。
在这个过程中,我们将看到 Rust 是如何在编译期就帮助我们杜绝许多潜在错误,并且通过 Cargo 让依赖管理和构建变得简单高效。
二、准备工作:安装 Rust 与熟悉 Cargo
2.1 安装 Rust
Rust 官方推荐用 rustup 安装与管理版本。简单来说,终端里执行一行安装脚本即可完成大部分操作。安装完成后,可用下列命令确认版本:
rustc --version
cargo --version
如果能正确显示版本号,说明你已经拥有了编写和构建 Rust 程序所需的环境。
2.2 初步认识 Cargo
Cargo 是 Rust 自带的包管理工具兼构建系统,为我们提供以下功能:
- 快速初始化新的 Rust 项目骨架
- 管理第三方库(crate)依赖
- 编译、运行、测试、发布项目
在本教程中,Cargo 将始终贯穿项目的整个生命周期,帮助我们简化琐碎操作。
三、新建“猜数字”项目
3.1 使用 Cargo 创建项目
在你想要放置项目的目录下,执行:
cargo new guessing_game
cd guessing_game
这会生成一个 guessing_game
文件夹,内部结构如下:
guessing_game
├── Cargo.toml
└── src└── main.rs
Cargo.toml
:项目的配置文件,包含依赖版本、项目元数据等。src/main.rs
:Rust 程序入口。
3.2 默认示例运行
src/main.rs
里默认写着 “Hello, world!” 测试代码。若你执行:
cargo run
就会看到编译并立即运行,屏幕上输出“Hello, world!”。这说明我们的项目骨架和工具链都已就绪。
四、读入用户输入并输出到控制台
4.1 引入 std::io
猜数字游戏的第一步是让用户在命令行输入他们的猜测。Rust 标准库中负责读写终端输入输出的主要模块是 std::io
,我们需要在 main.rs
顶部写:
use std::io;
4.2 读入并存储到字符串
让我们写一段能够提示用户并读入其输入的代码。替换 main.rs
的内容为:
fn main() {println!("Guess the number!");println!("Please input your guess.");let mut guess = String::new();io::stdin().read_line(&mut guess).expect("Failed to read line");println!("You guessed: {guess}");
}
逐行分析:
println!("Guess the number!")
:打印游戏开场信息。println!("Please input your guess.")
:提示玩家输入。let mut guess = String::new();
:创建一个可变字符串guess
用于存储用户输入。io::stdin().read_line(&mut guess)
:从标准输入读取一行文本并附加到guess
。.expect("Failed to read line")
:如果读取失败,就打印错误并退出程序。println!("You guessed: {guess}")
:将玩家输入的内容原样输出,验证读取结果。
运行 cargo run
,输入一些内容后回车,程序会将你的输入回显出来,这说明 I/O 已正确工作。
五、生成随机数:使用 rand
crate
5.1 在 Cargo.toml
中添加依赖
Rust 标准库并未内置随机数生成器,需要借助第三方库(crate)。最常用的库是 rand。
打开 guessing_game
文件夹下的 Cargo.toml
,在文件末尾添加:
[dependencies]
rand = "0.8.5"
保存后,执行:
cargo build
这时 Cargo 会自动下载并编译 rand
及其依赖。初次下载可能稍慢,但后续都会利用缓存,加快构建速度。
5.2 在代码中使用 rand
在 main.rs
顶部增加:
use rand::Rng;
然后在 main
函数中生成一个 1~100 的随机整数:
fn main() {println!("Guess the number!");let secret_number = rand::thread_rng().gen_range(1..=100);println!("The secret number is: {secret_number}"); // 测试用println!("Please input your guess.");// ...
}
rand::thread_rng()
:获得一个基于当前线程的随机数生成器。.gen_range(1..=100)
:指定生成区间是[1, 100]
。
再次运行 cargo run
可以看到,每次执行都会输出一个不同的随机数。(调试完成后可删除这行输出,避免剧透。)
六、解析并比较用户猜测与神秘数
6.1 将字符串转为数字
用户的输入在 Rust 中被读取到一个 String
里,如果想要比较,就必须转成数字。最简单的方式是:
let guess: u32 = guess.trim().parse().expect("Please type a number!");
guess.trim()
:去除首尾空白字符(含换行)。.parse()
:将字符串解析成指定数值类型,这里是u32
。.expect("...")
:若解析失败,打印错误并退出。
6.2 使用 std::cmp::Ordering
和 match
进行比较
Rust 的比较函数 cmp
会返回一个 Ordering
枚举,可能是 Less
、Greater
或 Equal
。我们用 match
对应不同情况进行处理:
use std::cmp::Ordering;match guess.cmp(&secret_number) {Ordering::Less => println!("Too small!"),Ordering::Greater => println!("Too big!"),Ordering::Equal => println!("You win!"),
}
把这些放进 main.rs
里,就能初步实现一次猜测的逻辑:
fn main() {use std::io;use rand::Rng;use std::cmp::Ordering;println!("Guess the number!");let secret_number = rand::thread_rng().gen_range(1..=100);println!("Please input your guess.");let mut guess = String::new();io::stdin().read_line(&mut guess).expect("Failed to read line");let guess: u32 = guess.trim().parse().expect("Please type a number!");println!("You guessed: {guess}");match guess.cmp(&secret_number) {Ordering::Less => println!("Too small!"),Ordering::Greater => println!("Too big!"),Ordering::Equal => println!("You win!"),}
}
现在可以猜一次,但猜错后程序就直接结束。我们需要让玩家多次猜测,直到猜中为止。
七、允许多次猜测:使用 loop
搭配 break
7.1 无限循环
Rust 提供了 loop
关键字,可用来创建一个无限循环。我们只要在合适时机用 break
跳出循环即可。修改代码如下:
fn main() {use std::io;use rand::Rng;use std::cmp::Ordering;println!("Guess the number!");let secret_number = rand::thread_rng().gen_range(1..=100);loop {println!("Please input your guess.");let mut guess = String::new();io::stdin().read_line(&mut guess).expect("Failed to read line");let guess: u32 = guess.trim().parse().expect("Please type a number!");println!("You guessed: {guess}");match guess.cmp(&secret_number) {Ordering::Less => println!("Too small!"),Ordering::Greater => println!("Too big!"),Ordering::Equal => {println!("You win!");break; // 猜对就退出循环}}}
}
程序运行后,当你输入数字并与“神秘数”不匹配时,会再次提示输入;只有在 guess == secret_number
时打印“You win!” 并结束。
7.2 更友好的错误处理
目前,若用户输入非数字(例如 “abc”),expect("Please type a number!")
就会直接崩溃退出,这并不友好。想继续游戏,就得显式地通过 match
来处理可能出现的解析错误:
let guess: u32 = match guess.trim().parse() {Ok(num) => num,Err(_) => {println!("Please type a valid number!");continue; // 直接跳过本次循环迭代}
};
如此,当玩家输入非法内容时,程序会提示重试而不崩溃。将此逻辑整合到整体代码中:
use std::io;
use std::cmp::Ordering;
use rand::Rng;fn main() {println!("Guess the number!");let secret_number = rand::thread_rng().gen_range(1..=100);loop {println!("Please input your guess.");let mut guess = String::new();io::stdin().read_line(&mut guess).expect("Failed to read line");// 改用 match 来处理 parse 的返回let guess: u32 = match guess.trim().parse() {Ok(num) => num,Err(_) => {println!("Please type a valid number!");continue;}};println!("You guessed: {guess}");match guess.cmp(&secret_number) {Ordering::Less => println!("Too small!"),Ordering::Greater => println!("Too big!"),Ordering::Equal => {println!("You win!");break; // 跳出循环}}}
}
删除调试用的打印神秘数行,我们就完成了最核心、最简洁的猜数字游戏!
八、深入理解:Rust 关键机制与编译特性
-
所有权与借用 (Ownership & Borrowing)
- 在
read_line(&mut guess)
里,我们传的是&mut guess
(一个可变引用),保证同时只有一个对该数据的可变引用,从而避免了并发读写时的竞争。 - Rust 编译器会在编译期自动帮你检查借用规则,如果出现违规借用,代码就无法通过编译。
- 在
-
Result 枚举与错误处理
- 像
read_line
、parse
这样的函数都返回一个Result
。它可能是Ok(T)
表示成功,也可能是Err(E)
表示失败,并携带错误信息。 - Rust 强制在编译期显式处理错误,这能让代码更健壮,减少运行期意外崩溃。
- 像
-
match 表达式
match
要求你列出所有可能的匹配分支,编译器会检查是否有遗漏;这也符合 Rust“让潜在错误在编译期就暴露”的设计理念。- 例如,我们用
match guess.cmp(&secret_number)
彻底覆盖了Less
、Greater
、Equal
三个场景。
-
Cargo 编译缓存
- 在第一次编译或添加新依赖时,Cargo 可能要下载并编译更多内容。但只要你后续没变动这些依赖,Cargo 不会重复下载编译,执行
cargo build
或cargo run
都会非常高效。
- 在第一次编译或添加新依赖时,Cargo 可能要下载并编译更多内容。但只要你后续没变动这些依赖,Cargo 不会重复下载编译,执行
-
可移植性与跨平台
- Rust 标准库本身就是跨平台的,如果你在某平台编译并生成二进制文件,在同样架构、操作系统的机器上通常都能直接运行。这让部署工作变得简单许多。
九、项目运行演示
假设我们已经全部代码写好且去掉了 secret_number
的打印,现在执行 cargo run
,会如下所示:
Guess the number!
Please input your guess.
30
You guessed: 30
Too small!
Please input your guess.
abc
Please type a valid number!
Please input your guess.
80
You guessed: 80
Too big!
Please input your guess.
66
You guessed: 66
You win!
- 当输入数字不合法时,程序不会崩溃,而是继续让你重试。
- “Too small!” 或 “Too big!” 提示可以帮助玩家逐步逼近答案,直到猜中后结束。
这就是我们想要的完整小游戏体验!
十、可能的扩展与改进
-
自定义退出命令
- 在玩家想要提前退出时,可以输入 “q” 或 “quit”。实现上,可以在
parse()
前先判断guess.trim()
是否等于"q"
等,再决定是退出还是继续。
- 在玩家想要提前退出时,可以输入 “q” 或 “quit”。实现上,可以在
-
增加回合数统计
- 可以在循环外声明一个
let mut attempts = 0;
,每猜一次就attempts += 1;
。猜中后告诉玩家“你总共猜了 x 次”。
- 可以在循环外声明一个
-
多重难度
- 在游戏开始时让用户选择难度,比如简单难度(150)和困难难度(11000)。根据选择,动态调整
gen_range
的范围。
- 在游戏开始时让用户选择难度,比如简单难度(150)和困难难度(11000)。根据选择,动态调整
-
发布与分发
- 用
cargo build --release
可生成优化过的可执行文件,它通常体积更小、运行更快;适合给他人使用或部署到生产环境。
- 用
-
更完善的错误提示
- 如果想知道具体的错误类型(如空输入、非数字、超出范围等),可以在
Err(e)
分支里分析e
,输出更个性化的错误信息。
- 如果想知道具体的错误类型(如空输入、非数字、超出范围等),可以在
十一、常见问题 (FAQ)
Q1: parse()
可以转什么类型?
任何实现了 FromStr
trait 的类型都行,比如 u8
, i32
, f64
等。我们只需在 let guess: u32
里显式指定想要的类型。
Q2: expect
、match
、?
的使用场景?
expect(...)
常用于简化处理,一旦失败就退出程序。match
适合需要自定义分支逻辑或在失败时继续其他操作。?
操作符适合在函数里把错误向上抛出,但对于交互式游戏来说,我们往往需要在错误处做更多处理,如提示信息和继续输入,因此match
会更灵活。
Q3: Rust 编译器为什么很“严苛”?
Rust 的编译器在编译期执行严格的所有权和借用检查,防止常见的内存错误(如空悬指针、数据竞争)。尽管上手时感觉被“逼迫”写额外的语法或注释,但长远看,这能极大降低运行期错误和调试成本。
十二、总结
通过这个“猜数字”小游戏,我们掌握了以下 Rust 开发基础要点:
- Cargo 工具链:
cargo new
初始化项目,cargo run
编译并执行,cargo build --release
发布优化版本。 - 依赖管理:在
Cargo.toml
中添加[dependencies]
后,Cargo 会自动下载并构建第三方库(crate)。 - I/O 与字符串处理:
read_line
读用户输入,使用trim()
去掉空白,再用parse()
转成数值。 - 错误处理与 Result:在 Rust 中显式处理错误,使用
expect
快捷退出或用match
做自定义逻辑。 - 循环与分支:
loop
和break
控制流程,match
匹配枚举值全面覆盖大小比较结果。 - 随机数与 trait:
rand::Rng
trait 定义随机数方法,通过.gen_range(1..=100)
生成区间随机整数。
Rust 的编译器在安全与性能之间找到了独特的平衡,令你能够用“近乎 C++ 的效率”写出“有如 Java 的安全性”的代码。虽然初学可能觉得严格的类型系统和所有权规则有点“繁琐”,但一旦掌握之后,你会发现它们能帮你在编译期就捕获大量潜在错误,让程序更健壮、更可维护。
欢迎你在此基础上继续挖掘更高级的 Rust 特性:如所有权与借用的更深层机制、生命周期与智能指针、并发编程(std::thread
、std::sync
)、宏系统等,或结合 Web、网络、嵌入式等领域的框架和库来发挥 Rust 的威力。
下一步建议
- 阅读官方文档 The Rust Programming Language 后续章节,深入掌握语言核心要素。
- 尝试更多有趣的小项目或到 Crates.io 搜索你所需的功能库,将它们整合起来感受 Rust 生态的魅力。
- 学习并编写测试(
cargo test
),编写注释并通过cargo doc --open
生成文档。
这就是本篇博客的全部内容。希望通过“猜数字”小游戏的开发,你能对 Rust 的开发流程和特性有一个体系化的认识。有什么疑问或想分享的想法,欢迎在评论区留言,让我们一起在实践中不断成长,成为更好的 Rustacean!
以上内容仅用于技术分享,所示示例并非唯一做法,读者可自由发挥、举一反三。在不断实践中体会 Rust 的优势和乐趣,愿我们都能写出更加可靠和高效的程序。
相关文章:
Rust 猜数字游戏:从 0 到 1 的完整实现与深入解析
一、项目概述 1.1 为什么选择“猜数字”? “猜数字”是编程入门中非常经典的一个项目。它看似简单,却能很好地展示: 输入输出 (I/O):提示用户输入并读取内容。随机数:每次运行生成一个随机值,保证游戏的…...
使用C语言实现栈的插入、删除和排序操作
栈是一种后进先出(LIFO, Last In First Out)的数据结构,这意味着最后插入的元素最先被删除。在C语言中,我们可以通过数组或链表来实现栈。本文将使用数组来实现一个简单的栈,并提供插入(push)、删除(pop)以及排序(这里采用一种简单的排序方法,例如冒泡排序)的操作示…...
职场的三个阶段及其应对规划:以前端开发工程师为例
作为职场人士,特别是 IT 开发工程师,职业生涯的发展路径往往伴随着不同的挑战与机遇。一般而言,职场生涯可以划分为三个阶段:找工作阶段、有工作阶段以及职业转型阶段。每个阶段都有其特定的特征和应对策略,下面我将从…...
【人工智能】:搭建本地AI服务——Ollama、LobeChat和Go语言的全方位实践指南
前言 随着自然语言处理(NLP)技术的快速发展,越来越多的企业和个人开发者寻求在本地环境中运行大型语言模型(LLM),以确保数据隐私和提高响应速度。Ollama 作为一个强大的本地运行框架,支持多种先…...
蓝桥杯训练—斐波那契数列
文章目录 一、题目二、解析三、代码 一、题目 求100以内的斐波那契数列 斐波那契数列(Fibonacci sequence),又称黄金分割数列 ,因数学家莱昂纳多斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入&…...
TensorFlow DAY3: 高阶 API(Keras,Estimator)(完)
TensorFlow 作为深度学习框架,当然是为了帮助我们更便捷地构建神经网络。所以,本次实验将会了解如何使用 TensorFlow 来构建神经网络,并学会 TensorFlow 构建神经网络的重要函数和方法。 知识点 Keras 顺序模型Keras 函数模型Keras 模型存储…...
复健第二天之[MoeCTF 2022]baby_file
打开题目在线环境可以看到: 感觉要用伪协议去求,但是我们并不知道flag的位置,这里我选择用dirsearch去扫一下: 最像的应该就是flag.php了 于是就构建payload: **?filephp://filter/convert.base64-encode/resource…...
【QT用户登录与界面跳转】
【QT用户登录与界面跳转】 1.前言2. 项目设置3.设计登录界面3.1 login.pro参数3.2 界面设置3.2.1 登录界面3.2.2 串口主界面 4. 实现登录逻辑5.串口界面6.测试功能7.总结 1.前言 在Qt应用程序开发中,实现用户登录及界面跳转功能是构建交互式应用的重要步骤之一。下…...
【docker踩坑记录】
docker踩坑记录 踩坑记录(持续更新中.......)docker images 权限问题 踩坑记录(持续更新中…) docker images 权限问题 permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Head "http://%2Fvar%2Frun%2Fdocker.s…...
【Azure 架构师学习笔记】- Azure Function (2) --实操1
本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Function 】系列。 接上文【Azure 架构师学习笔记】- Azure Function (1) --环境搭建和背景介绍 前言 上一文介绍了环境搭建,接下来就在本地环境下使用一下。 环境准备 这里我下载了最新的VS studio&…...
豆包MarsCode:构造特定数组的逆序拼接
问题描述 思路分析 1. 数组的组成: 我们要根据 i 的不同值拼接出不同长度的子数组。对于每个 i 从 1 到 n,我们要把数字从 n 逆序到 i 拼接成一个子数组。 例如,当 i 1 时,拼接 [n, n-1, ..., 1]。当 i 2 时,拼接 …...
14-美妆数据分析
前言 美妆数据分析可以帮助企业更好地理解市场趋势、客户偏好和产品表现 import pandas as pd import numpy as np 一、数据清洗 data pd.read_csv(rC:\Users\B\Desktop\美妆数据.csv,encodinggbk) data.head()data.info()data data.drop_duplicates(inplaceFalse) data.r…...
新阿里云买服务器配置需手动配置80端口
新买阿里云服务器需手动配置80,端口才可以访问nginx CentOS系统 安装nginx 1. 安装 Nginx yum install nginx 2. 启动 Nginx 服务 systemctl start nginx 3. 修改默认网页 cd /usr/share/nginx/ echo "666" >index.html cat index.html 访问ngin最后…...
Mysql--实战篇--连接泄漏问题(什么是连接泄漏,未关闭SqlSession,长事务处理,连接池管理等)
1、什么是连接泄漏(Connection Leak)? 连接泄漏是指应用程序未能正确关闭数据库连接,导致连接池中的可用连接逐渐减少,最终耗尽所有连接。连接泄漏可能会导致新的请求无法获得连接,进而引发服务中断。 连…...
【ESP32】ESP-IDF开发 | WiFi开发 | AP模式 + 基站连接例程
1. 简介 前面一篇讲了WiFi的基站模式,演示了怎么编程连接AP,所以这一篇讲一讲AP模式,ESP32作AP,让其他的设备连接自己。 1.1 DHCP 这里需要补充一个知识点——DHCP服务器。当基站连接一个AP时,会被分配一个IP…...
Ubuntu升级Linux内核教程
本文作者CVE-柠檬i: CVE-柠檬i-CSDN博客 本文使用的方法是dpkg安装,目前版本为5.4.0-204,要升级成5.8.5版本 下载 下载网站:https://kernel.ubuntu.com/mainline/ 在该网站下载deb包,选择自己想要升级的版本,这里是5…...
关于AWS网络架构的思考
目录: AWS概述 EMR Serverless AWS VPC及其网络 关于AWS网络架构的思考 在AWS K8S中部署的业务,有不同的流量路径。 流量进入 客户端请求 普通的客户端流量流向从前到后是: 客户端公司网关(endpoint)业务的Endpoint ServiceLoad Balancers(监听80和…...
Pandas库的常用内容归纳
Pandas 是一个强大的 Python 数据分析库,提供了大量用于数据处理和分析的功能。以下是一些 Pandas 库中常用的功能: 数据创建和操作 Series 和 DataFrame:创建一维的 Series 和二维的 DataFrame 对象。数据导入:从 CSV、Excel、…...
【错误解决方案记录】spine3.8.75导出的数据使用unity-spine3.8插件解析失败报错的解决方案
报错信息 Exception: Unsupported skeleton data, please export with a newer version of Spine. Spine.SkeletonBinary.ReadSkeletonData (System.IO.Stream file) (at Assets/Spine/Runtime/spine-csharp/SkeletonBinary.cs:132) Spine.Unity.Editor.AssetUtility.AddRequi…...
Python与PyTorch的浅拷贝与深拷贝
1.Python赋值操作的原理 在python中,x something, 这样的赋值操作,准确的理解是:给存储something建立一个索引x (即存储地址), x通过访问something的存储内容,获得something的值。 在下面代码中ÿ…...
【unity进阶篇】弧度、角度和三角函数(Mathf),并实现类似蛇的运动
考虑到每个人基础可能不一样,且并不是所有人都有同时做2D、3D开发的需求,所以我把 【零基础入门unity游戏开发】 分为成了C#篇、unity通用篇、unity3D篇、unity2D篇。 【C#篇】:主要讲解C#的基础语法,包括变量、数据类型、运算符、…...
【分类】【损失函数】处理类别不平衡:CEFL 和 CEFL2 损失函数的实现与应用
引言 在深度学习中的分类问题中,类别不平衡问题是常见的挑战之一。尤其在面部表情分类任务中,不同表情类别的样本数量可能差异较大,比如“开心”表情的样本远远多于“生气”表情。面对这种情况,普通的交叉熵损失函数容易导致模型…...
支持selenium的chrome driver更新到132.0.6834.83
最近chrome释放新版本:132.0.6834.83 如果运行selenium自动化测试出现以下问题,是需要升级chromedriver才可以解决的。 selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This version of ChromeDriver only su…...
IO模型与NIO基础二
抽象基类之二 FilterInputStream FilterInputStream 的作用是用来“封装其它的输入流,并为它们提供额外的功能”。 它的常用的子类有BufferedInputStream和DataInputStream。 (1) BufferedInputStream的作用就是为“输入流提供缓冲功能,以及mark()和res…...
什么是FPGA开发?
FPGA(Field-Programmable Gate Array),即现场可编程门阵列,是一种通过编程方式实现特定功能的集成电路。与传统的ASIC(专用集成电路)相比,FPGA具有灵活性高、开发周期短、成本相对较低等优势&am…...
寻找川味:成都九尺板鸭
寻找川味:成都九尺板鸭 在四川这片美食的天堂里,隐藏着无数令人垂涎的传统名吃。其中,成都九尺板鸭以其悠久的历史、独特的制作工艺和令人难以抗拒的美味,成为了许多食客心中不可错过的地道川味。 历史渊源 九尺板鸭,顾名思义,因主产于四川省成都市彭州市九尺镇而得名。早在5…...
Object常用的方法及开发中的使用场景
在前端开发中,Object 对象提供了许多常用的方法,这些方法帮助我们操作对象的属性和结构。以下是常用的 Object 方法及其功能简要说明: 对象常用的方法 1. 创建对象 Object.create(proto[, propertiesObject]) 创建一个具有指定原型对象和属性…...
ElasticSearch上
安装ElasticSearch Lucene:Java语言的搜索引擎类库,易扩展;高性能(基于倒排索引)Elasticsearch基于Lucene,支持分布式,可水平扩展;提供Restful接口,可被任何语言调用Ela…...
基于SpringCloud的广告系统设计与实现(二)
一、common公共模块 1.common的作用 通用的代码、配置不应该散落在各个业务模块中,不利于维护与更新 一个大的系统,响应对象需要统一外层格式 各种业务设计与实现,可能会抛出各种各样的异常,异常信息的收集也应该做到统一 2.统…...
2011年西部数学奥林匹克的几何题
2011G1 证明: 显然, O O O, I I I, F F F 共线, E I / / M O EI//MO EI//MO, △ E I F ∼ △ M O F \triangle EIF \sim \triangle MOF △EIF∼△MOF. 进而 E F / M F r 1 / r 2 EF/MFr_1/r_2 EF/MFr1/r2. ( r 1 (r_1 (r1 为圆 I I I 的半径, r 2 r_2 r2 为…...
(一)afsim第三方库编译
注意:防止奇怪的问题,源码编译的路径最好不要有中文,请先检查各文件夹名 AFSIM版本 Version: 2.9 Plugin API Version: 11 软件环境 操作系统: Kylin V10 SP1 项目构建工具: cmake-3.26.0-linux-aarch6…...
boss直聘 __zp_stoken__ 分析
声明: 本文章中所有内容仅供学习交流使用,不用于其他任何目的,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关! 逆向过程 py代码 import execjs imp…...
python matplotlib绘图,显示和保存没有标题栏和菜单栏的图像
目录 1. 使用plt.savefig保存无边框图形 2. 显示在屏幕上,并且去掉窗口的标题栏和工具栏 3. 通过配置 matplotlib 的 backend 和使用 Tkinter(或其他图形库) 方法 1:使用 TkAgg 后端,并禁用窗口的工具栏和标题栏 …...
AI-Talk开发板之替换唤醒词
一、说明 聆思提供的Demo唤醒词默认为"小美,小美",V2.4及之后的SDK支持替换唤醒词,聆思提供了在线工具生成唤醒词固件。 工具:tool.listenai.com/audio-custom/products/ 官方博客教程:实操给桌面AI语音助理ÿ…...
C#实现字符串反转的4种方法
见过不少人、经过不少事、也吃过不少苦,感悟世事无常、人心多变,靠着回忆将往事串珠成链,聊聊感情、谈谈发展,我慢慢写、你一点一点看...... 1、string.Reverse 方法 string content "Hello World";string reverseStri…...
【MySQL索引:B+树与页的深度解析】
文章目录 MySQL索引:B树与页的深度解析1. 索引使用的数据结构——B树1.1 B树介绍1.2 B树的特点1.3 B树和B树的对比 2. MySQL中的页2.1 页的介绍2.2 页主体2.3 页目录2.4 B树在MySQL索引中的应用 MySQL索引:B树与页的深度解析 在MySQL数据库中࿰…...
在 macOS 上,用命令行连接 MySQL(/usr/local/mysql/bin/mysql -u root -p)
根据你提供的文件内容,MySQL 的安装路径是 /usr/local/mysql。要直接使用 mysql 命令,你需要找到 mysql 可执行文件的路径。 在 macOS 上,mysql 客户端通常位于 MySQL 安装目录的 bin 子目录中。因此,完整的路径应该是࿱…...
深入HDFS——数据上传源码
引入 就如RPC篇章里提到的观点一样,任何一种能广为传播的技术,都是通过抽象和封装的思想,屏蔽底层底层复杂实现,提供简单且强大的工具,来降低使用门槛的。 HDFS的风靡自然也是如此。 通过前面深入了NameNode和DataN…...
归并排序算法
归并排序 1算法介绍 和选择排序一样,归并排序的性能不受输入数据的影响,但表现比选择排序好的多,因为始终都是O(n log n)的时间复杂度。代价是需要额外的内存空间。归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用…...
优雅解决webview_flutter不支持安卓选择图片视频文件问题
这个问题,网上一搜索,就是要去修改别人写好的插件。 搞Flutter开发,尽量不要去修改别人的插件 ,特别是像 webview_flutter 这种比较大的官方插件。 相信我,你拿捏不了它。 主要问题就是: webview_flutter…...
Linux UDP 编程详解
一、引言 在网络编程领域,UDP(User Datagram Protocol,用户数据报协议)作为一种轻量级的传输层协议,具有独特的优势和适用场景。与 TCP(Transmission Control Protocol,传输控制协议࿰…...
UllnnovationHub,一个开源的WPF控件库
目录 UllnnovationHub1.项目概述2.开发环境3.使用方法4.项目简介1.WPF原生控件1.Button2.GroupBox3.TabControl4.RadioButton5.SwitchButton6.TextBox7.PasswordBox8.CheckBox9.DateTimePicker10.Expander11.Card12.ListBox13.Treeview14.Combox15.Separator16.ListView17.Data…...
[Python学习日记-78] 基于 TCP 的 socket 开发项目 —— 模拟 SSH 远程执行命令
[Python学习日记-78] 基于 TCP 的 socket 开发项目 —— 模拟 SSH 远程执行命令 简介 项目分析 如何执行系统命令并拿到结果 代码实现 简介 在Python学习日记-77中我们介绍了 socket 基于 TCP 和基于 UDP 的套接字,还实现了服务器端和客户端的通信,本…...
css3过渡总结
一、过渡的定义与作用 CSS3 过渡(Transitions)允许 CSS 属性在一定的时间区间内平滑地过渡,从一个值转变为另一个值。它能够让网页元素的状态变化更加自然、流畅,给用户带来更好的视觉体验。例如,当一个元素从隐藏状态…...
生产环境中常用的设计模式
生产环境中常用的设计模式 设计模式目的使用场景示例单例模式保证一个类仅有一个实例,并提供一个访问它的全局访问点- 日志记录器- 配置管理器工厂方法模式定义一个创建对象的接口,让子类决定实例化哪个类- 各种工厂类(如视频游戏工厂模式创…...
【STM32-学习笔记-4-】PWM、输入捕获(PWMI)
文章目录 1、PWMPWM配置 2、输入捕获配置3、编码器 1、PWM PWM配置 配置时基单元配置输出比较单元配置输出PWM波的端口 #include "stm32f10x.h" // Device headervoid PWM_Init(void) { //**配置输出PWM波的端口**********************************…...
游戏行业销售数据分析可视化
完整源码项目包获取→点击文章末尾名片! 🌟分析: 可看出最近五年用户最喜爱的游戏类型依然还是Action-动作类(当然市场发行的也很多) Sports-运动类和Shooter-射击类顺序互换,但我估计现在大环境局势紧张可以会推动射击…...
微服务网关,如何选择?
什么是API网关 API网关(API Gateway)是微服务架构中的一个关键组件,它充当了客户端与后端服务之间的中间层。其主要功能包括请求路由、协议转换、负载均衡、安全认证、限流熔断等。通过API网关,客户端无需直接与多个微服务交互&a…...
Java开发提速秘籍:巧用Apache Commons Lang工具库
一、Java 开发效率之困 在当今数字化时代,Java 作为一门广泛应用的编程语言,在各类软件开发项目中占据着举足轻重的地位。无论是大型企业级应用、互联网平台,还是移动应用后端,都能看到 Java 的身影。然而,Java 开发者…...
多用户商城系统源码哪家好用?怎么选?
想拥有属于自己的多用户商城系统,但回头一看自己又是个技术小白,看着网上眼花缭乱的b2b2c商城系统,更是不知道如何选起?下面给大家分享一条较为成熟的选择思路,以作参考。 1、从需求上决定系统方向 企业在选型b2b2c商…...