2311rust,到66版本更新

1.60.0稳定版

基于源码的代码覆盖率

rustc中已稳定支持基于LLVM的覆盖率检测.可用-Cinstrument-coverage重构代码,如:

RUSTFLAGS="-C instrument-coverage" cargo build

之后,运行生成的二进制文件,它在当前目录中生成一个default.profraw文件.环境变量可覆盖路径和文件名;有关细节,见文档.

llvm-tools-preview组件包括llvm-profdata,来处理和合并原始配置文件输出(覆盖区域执行计数);及用llvm-cov来生成报告.

llvm-cov结合了llvm-profdata二进制输出,因为二进制文件嵌入了从计数器实际源码区域的映射.

rustup component add llvm-tools-preview
$(rustc --print sysroot)/lib/rustlib/x86_64-unknown-linux-gnu/bin/llvm-profdata merge -sparse default.profraw -o default.profdata
$(rustc --print sysroot)/lib/rustlib/x86_64-unknown-linux-gnu/bin/llvm-cov show -Xdemangler=rustfilt target/debug/coverage-testing \-instr-profile=default.profdata \-show-line-counts-or-regions \-show-instantiations

在简单的helloworld二进制文件上,执行上述命令会生成此带注释的报告,显示已覆盖每一行输入.

1|  1|fn main() {
2|  1|    println!("Hello, world!");
3|  1|}

细节见rustc书中的文档.
因此,确保llvm-tools-preview和编译代码的rustc使用相同版本.

cargo --timings

Cargo已稳定了对使用--timings标志收集构建信息的支持.

$ cargo build --timingsCompiling hello-world v0.1.0 (hello-world)Timing report saved to target/cargo-timings/cargo-timing-20220318T174818Z.htmlFinished dev [unoptimized + debuginfo] target(s) in 0.98s

Cargo功能的新语法

名字空间依赖和弱依赖.
Cargo长期以来一直支持带可选功能依赖项,如下面代码片所示.

[dependencies]
jpeg-decoder = { version = "0.1.20", default-features = false, optional = true }[features]
# 并行处理,启用"rayon"特征
parallel = ["jpeg-decoder/rayon"]

此例中,有两点要注意:
1,可选的jpeg-decoder依赖项隐式定义了同名的功能.启用jpeg-decoder功能依赖启用jpeg-decoder项.
2,"jpeg-decoder/rayon"语法启用jpeg-decoder依赖项,并启用jpeg-decoder依赖项的rayon特征.

名字空间功能解决了第一个问题.现在,可在[features]表中无需隐式公开,使用dep:前缀来显式引用可选依赖项.

这样可更好控制如何定义可选依赖项对应的功能,包括在更具描述性功能名后面隐藏依赖可选项.

弱依赖功能解决了第二个问题,即"optional-dependency/feature-name"语法会总是启用可选依赖.但是,一般,仅当其他某些功能已启用可选依赖项时,才想在可选依赖项上启用该功能.
1.60开始,你可像"package-name?/feature-name"一样,添加一个?,只有在其他功能已启用了可选依赖项时,才会启用给定功能.

如,假设在库中支持了一些序化,且需要在一些可选依赖项启用相应的功能.可这样:

[dependencies]
serde = { version = "1.0.133", optional = true }
rgb = { version = "0.8.25", optional = true }
[features]
serde = ["dep:serde", "rgb?/serde"]

此例中,启用serde功能,依赖启用serde项.它还依赖为rgb项启用serde功能,但前提是其他内容启用了rgb依赖项.

稳定的API

Arc::new_cyclic
Rc::new_cyclic
slice::EscapeAscii
<[u8]>::escape_ascii
u8::escape_ascii
Vec::spare_capacity_mut
MaybeUninit::assume_init_drop
MaybeUninit::assume_init_read
i8::abs_diff
i16::abs_diff
i32::abs_diff
i64::abs_diff
i128::abs_diff
isize::abs_diff
u8::abs_diff
u16::abs_diff
u32::abs_diff
u64::abs_diff
u128::abs_diff
usize::abs_diff
Display for io::ErrorKind
From<u8> for ExitCode
Not for ! (the "never" type)
_Op_Assign<$t> for Wrapping<$t>
arch::is_aarch64_feature_detected!

1.61.0稳定版

主的自定义退出码

一开始,Rust主函数只能(隐式或显式)返回单元类型(),总是在退出状态下指示成功,如果想要其他,则必须调用process::exit(code).

Rust1.26开始,允许main返回Result,其中Ok转换为CEXIT_SUCCESS,Err转换为EXIT_FAILURE(也调试打印错误).在后台,由终止特征统一这些替代返回类型.

此版本中,最终用包装了相关平台的返回类型的更通用的ExitCode类型,稳定了终止特征.它有SUCCESSFAILURE常量,且还为更多任意值实现了From<u8>.
可为你自己的类型实现终止特征,允许在转换为ExitCode自定义报告类型.
如,下面是为git bisect run脚本编写退出码类型的安全方法:

use std::process::{ExitCode, Termination};
#[repr(u8)]
pub enum GitBisectResult {Good = 0,Bad = 1,Skip = 125,Abort = 255,
}
impl Termination for GitBisectResult {fn report(self) -> ExitCode {//也许在此打印一条消息ExitCode::from(self as u8)}
}
fn main() -> GitBisectResult {std::panic::catch_unwind(|| {todo!("test the commit")}).unwrap_or(GitBisectResult::Abort)
}

const fn的更多功能

此版本中稳定了几个渐进特征,以在函数中启用更多功能:
1,fn指针的基本处理:现在可在const fn创建,传递和转换函数指针.如,这对解释器构建编译时函数表可能很有用.但是,仍禁止调用fn指针.

2,特征边界:在泛型参数上,现在可把如T:Copy特征边界写入const fn,以前只允许Sized.
3,dyn Trait类型:类似,const fn现在可处理特征对象dyn Trait.
4,impl Trait类型:const fn参数和返回值现在可以是不透明的impl Trait类型.

注意,在const fn中,特征功能尚不支持,从这些特征调用方法.

更多

锁定stdio的静态句柄

三个标准I/O流(Stdin,StdoutStderr)都有一个lock(&self),来更好控制同步读写.然而,他们返回带从&self借用生命期锁警卫,因此仅限于原始句柄的域.

这是不必要的限制,因为底层锁实际在静态存储中,因此现在与句柄断开连接时,返回带"静态生命期"的警卫.

如,常见错误是,试取句柄并在语句锁定它:

//`error[E0716]`:借用时,丢弃了临时值
let out = std::io::stdout().lock();
//^^^^^^^^^^^^^^^^^在此语句末尾释放`临时值`,创建仍在使用时释放了的临时.

现在锁警卫静态的,而不是临时借来的,所以这有效!

稳定的API

Pin::static_mut
Pin::static_ref
Vec::retain_mut
VecDeque::retain_mut
Write for Cursor<[u8; N]>
std::os::unix::net::SocketAddr::from_pathname
std::process::ExitCode
std::process::Termination
std::thread::JoinHandle::is_finished

以下以前稳定的函数现在是:

<*const T>::offset and <*mut T>::offset
<*const T>::wrapping_offset and <*mut T>::wrapping_offset
<*const T>::add and <*mut T>::add
<*const T>::sub and <*mut T>::sub
<*const T>::wrapping_add and <*mut T>::wrapping_add
<*const T>::wrapping_sub and <*mut T>::wrapping_sub
<[T]>::as_mut_ptr
<[T]>::as_ptr_range
<[T]>::as_mut_ptr_range

1.62.0稳定版

cargo add

现在,可用cargo add,直接从命令行添加新的依赖项.支持指定功能和版本.还可用来修改现有依赖项.
如:

cargo add log
cargo add serde --features derive
cargo add nom@5

更多.

#[默认]枚举变体

现在,如果指定默认变体,则可在枚举上使用#[derive(Default)].如,目前,必须手动为此枚举编写默认实现:

#[derive(Default)]
enum Maybe<T> {#[default]Nothing,Something(T),
}

目前,只允许标记"单位"变体(无字段变体)为#[default].细节.

Linux上更薄,更快的互斥锁

以前,由Linux上的pthreads库,支持Mutex,CondvarRwLock.pthreads锁支持比RustAPI自身更多的功能,包括运行时配置,且可用于静态保证比Rust更少的语言.

如,按无法移动的40个字节实现互斥锁.这强制标准库在后台为使用pthreads的平台的每个新互斥锁分配一个Box.

现在在Linux上,Rust的标准库提供了原始基于futex实现的,它非常轻量,不需要额外分配.

1.62.0中,在Linux上的内部状态中,互斥锁只需要5个字节,更多.

裸金属x86_64目标

现在,为x86_64构建无操作系统二进制文件更加容易,如在编写内核时.x86_64-unknown-none目标已提升到第2级,可用rustup安装.

rustup target add x86_64-unknown-none
rustc --target x86_64-unknown-none my_no_std_program.rs

嵌入式的rust

稳定的API

bool::then_some
f32::total_cmp
f64::total_cmp
Stdin::lines
windows::CommandExt::raw_arg
impl<T: Default> Default for AssertUnwindSafe<T>
From<Rc<str>> for Rc<[u8]>
From<Arc<str>> for Arc<[u8]>
FusedIterator for EncodeWide

aarch64上的RDM内部函数,这里

1.62.1稳定版

1,编译器修复了涉及impl Trait返回类型的不健全函数强制.
2,编译器修复了异步 fn生命期的增量编译错误.
3,窗口同步读写中的重叠I/O添加了回退.

1.63.0稳定版

域线程

1.0开始,Rust代码可用std::thread::spawn启动新线程,但此函数要用'static绑定闭包.即,即线程当前必须有传递到闭包中的参数的所有权;

不能把借用数据传递到线程中.如果(通过join()),应该在结束函数时,退出线程,这不必要,可能需要在Arc中放置数据等变通方法.

现在,在1.63.0中,标准库添加了允许生成从本地栈帧中借用线程域线程.std::thread::scope,API提供,即在返回前,生成线程都已退出,从而安全借用数据的必要保证.
下面是一例:

let mut a = vec![1, 2, 3];
let mut x = 0;
std::thread::scope(|s| {s.spawn(|| {println!("hello from the first scoped thread");//可在此借用`"a"`.dbg!(&a);});s.spawn(|| {println!("hello from the second scoped thread");//甚至可在此可变借用`"x"`,因为没有其他线程使用它.x += a[0] + a[2];});println!("hello from the main thread");
});
//在域后,可再次`修改和访问`变量:
a.push(4);
assert_eq!(x, a.len());

(I/O安全)原始文件描述符/句柄的Rust所有权

以前,(在unix风格平台上)使用带原始文件描述符或(在窗口上)句柄的平台APIRust代码,一般直接使用相关平台的描述符表示(如,c_int或别名RawFd).
对与此类原生APIRust绑定,类型系统无法编码API是否取得文件描述符的所有权(如,close)还是仅借用它(如,dup).

现在,Rust提供了按#[repr(transparent)]标记的BorrowedFdOwnedFd等包装器类型,即外部"C"绑定可直接用它们编码所有权语义.

建议新的API使用它们,而不是以前的(如RawFd)类型别名.

初化const互斥锁,RwLock,Condvar

现在可在环境中调用Condvar::new,Mutex::newRwLock::new函数,这样可避免使用像lazy_static仓库来创建互斥(Mutex),RwLockCondvar全局静态值.

带impl Trait的鱼泛型

对像fn foo<T>(value:T,f:impl Copy)类函数签名,通过指定T具体类型是错误的:foo::<u32>(3,3)将失败,并显示:

error[E0632]: cannot provide explicit generic arguments when `impl Trait` is used in argument position--> src/lib.rs:4:11|
4 |     foo::<u32>(3, 3);|           ^^^ explicit generic argument not allowed|= note: see issue #83701 <https://github.com/rust-lang/rust/issues/83701> for more information

1.63中,放宽了此限制,且可指定泛型显式类型.但是,impl Trait参数尽管是泛型,但仍是不透明的,无法通过指定.

稳定的API

array::from_fn
Box::into_pin
BinaryHeap::try_reserve
BinaryHeap::try_reserve_exact
OsString::try_reserve
OsString::try_reserve_exact
PathBuf::try_reserve
PathBuf::try_reserve_exact
Path::try_exists
Ref::filter_map
RefMut::filter_map
NonNull::<[T]>::len
ToOwned::clone_into
Ipv6Addr::to_ipv4_mapped
unix::io::AsFd
unix::io::BorrowedFd<'fd>
unix::io::OwnedFd
windows::io::AsHandle
windows::io::BorrowedHandle<'handle>
windows::io::OwnedHandle
windows::io::HandleOrInvalid
windows::io::HandleOrNull
windows::io::InvalidHandleError
windows::io::NullHandleError
windows::io::AsSocket
windows::io::BorrowedSocket<'handle>
windows::io::OwnedSocket
thread::scope
thread::Scope
thread::ScopedJoinHandle

这些API现在可在环境中使用:

array::from_ref
slice::from_ref
intrinsics::copy
intrinsics::copy_nonoverlapping
<*const T>::copy_to
<*const T>::copy_to_nonoverlapping
<*mut T>::copy_to
<*mut T>::copy_to_nonoverlapping
<*mut T>::copy_from
<*mut T>::copy_from_nonoverlapping
str::from_utf8
Utf8Error::error_len
Utf8Error::valid_up_to
Condvar::new
Mutex::new
RwLock::new

1.64.0稳定版

IntoFuture增强.await

Rust1.64稳定了,类似IntoIterator的特征,但不是支持for循环,而是改变.await的工作方式的IntoFuture特性.

使用IntoFuture,.await关键字不仅可等待未来;还可等待可通过IntoFuture转换为Future的任意东西,帮助API更加用户友好!
如,构造通过网络请求某个存储提供者构建器:

pub struct Error { ... }
pub struct StorageResponse { ... }:
pub struct StorageRequest(bool);
impl StorageRequest {///创建`"StorageRequest"`的新实例.pub fn new() -> Self { ... }///决定是否应启用调试模式.pub fn set_debug(self, b: bool) -> Self { ... }///发送请求并接收响应.pub async fn send(self) -> Result<StorageResponse, Error> { ... }
}

典型用法可能如下:

let response = StorageRequest::new()  //`1`.创建新实例.set_debug(true)//`2`.设置一些选项.send()         //`3`.构建未来.await?;        //`4`.运行未来+传播错误

这还不错,但在此还可更好.使用IntoFuture,可把构建"未来"(第3行)和"运行未来"(第4行)合并为一个步骤:

let response = StorageRequest::new()  //`1`.创建新实例.set_debug(true)    //`2`设置一些选项.await?;//`3`.构造+运行未来+传播错误

为此,可为StorageRequest实现IntoFuture.IntoFuture要求有个可创建"盒子<未来>"并为其定义一个类型别名来完成的可返回的命名未来:

//首先,必须导入一些新类型到域中.
use std::pin::Pin;
use std::future::{Future, IntoFuture};
pub struct Error { ... }
pub struct StorageResponse { ... }
pub struct StorageRequest(bool);
impl StorageRequest {///创建`"StorageRequest"`的新实例.pub fn new() -> Self { ... }///决定是否应启用调试模式.pub fn set_debug(self, b: bool) -> Self { ... }///发送请求并接收响应.pub async fn send(self) -> Result<StorageResponse, Error> { ... }
}
//新的实现:`1`.创建新的`命名未来`类型
//`2`.为`"StorageRequest"`实现`"IntoFuture"`
pub type StorageRequestFuture = Pin<Box<dyn Future<Output = Result<StorageResponse, Error>> + Send + 'static>>
impl IntoFuture for StorageRequest {type IntoFuture = StorageRequestFuture;type Output = <StorageRequestFuture as Future>::Output;fn into_future(self) -> Self::IntoFuture {Box::pin(self.send())}
}

更多实现代码,但给用户提供了更简单API.
未来,Rust异步工作组想通过在类型(type)别名(类型别名实现特征或TAIT)中支持impl Trait简化创建新的命名未来.
通过简化类型别名的签名,来简化实现IntoFuture的过程,并从类型别名中删除Box提高性能.

核心和分配中与C兼容的FFI类型

调用或被CABI调用时,Rust代码可无需相关目标代码或条件,用(如c_uintc_ulong)类型别名来匹配目标上C的相应类型.
以前,仅在std中可用分类名,因此为嵌入目标和其他只能使用corealloc的场景,编写的代码不能用类型别名.

Rust1.64现在提供了core::ffi中的所有c_*类型别名,及处理C串core::ffi::CStr.Rust1.64还提供了alloc::ffi::CString,来仅使用alloc仓库而不是完整的std库来处理拥有的C串.

现在可通过rustup取得rust-analyzer

rust-analyzer这里,现在包含在Rust附带的工具集合中.这样更容易下载和访问rust-analyzer,并在多平台上可用.可作为rustup组件使用,如下安装:

rustup component add rust-analyzer

此时,要运行rustup安装的版本,这样调用它:

rustup run stable rust-analyzer

rustup的下个版本提供内置代理,以便运行可执行的rust-analyzer会启动适当版本.
发布,vsc插件

改进Cargo:工作区继承和多目标构建

现在,在一个Cargo工作区中,使用相关库或二进制仓库的集合时,可避免在仓库之间重复通用字段值,如通用版本号,仓库URLrust-version,及从工作区继承依赖项.
帮助更新仓库时保持这些值间同步.

在为多个目标构建时,现在可传递多个--target选项给cargo build,以一次构建所有这些目标.还可在.cargo/config.toml中,将build.target设置为包含多个目标的数组,以便默认为多个目标构建.

稳定的API

future::IntoFuture
num::NonZero*::checked_mul
num::NonZero*::checked_pow
num::NonZero*::saturating_mul
num::NonZero*::saturating_pow
num::NonZeroI*::abs
num::NonZeroI*::checked_abs
num::NonZeroI*::overflowing_abs
num::NonZeroI*::saturating_abs
num::NonZeroI*::unsigned_abs
num::NonZeroI*::wrapping_abs
num::NonZeroU*::checked_add
num::NonZeroU*::checked_next_power_of_two
num::NonZeroU*::saturating_add
os::unix::process::CommandExt::process_group
os::windows::fs::FileTypeExt::is_symlink_dir
os::windows::fs::FileTypeExt::is_symlink_file

以前在std::ffi中是稳定的,但现在在corealloc中也可用:

core::ffi::CStr
core::ffi::FromBytesWithNulError
alloc::ffi::CString
alloc::ffi::FromVecWithNulError
alloc::ffi::IntoStringError
alloc::ffi::NulError

以前在std::os::raw中是稳定的,但现在在core::ffistd::ffi中也可用:

ffi::c_char
ffi::c_double
ffi::c_float
ffi::c_int
ffi::c_long
ffi::c_longlong
ffi::c_schar
ffi::c_short
ffi::c_uchar
ffi::c_uint
ffi::c_ulong
ffi::c_ulonglong
ffi::c_ushort

已稳定了一些来future下面低级实现的Poll助手:

future::poll_fn
task::ready!

将来,可能会提供更简单的较少低级细节的,如PollPinAPI,但同时,这些助手使得更加容易编写此类代码.
现在可在环境中使用这些API:

slice::from_raw_parts

Rust1.64.0更改了Ipv4Addr,Ipv6Addr,SocketAddrV4SocketAddrV6内存布局,使其更加紧凑和内存高效.

1.65.0稳定版

(GAT)泛型关联类型

现在可在关联类型上定义生命期,类型和常量泛型,如下:

trait Foo {type Bar<'x>;
}

这里有些示例特征,以了解它们的强大:

///可从"Self"中借用的,类似"迭代器"的特征
trait LendingIterator {type Item<'a> where Self: 'a;fn next<'a>(&'a mut self) -> Option<Self::Item<'a>>;
}
///可通过(如`"Rc"`或`"Arc"`)灵针实现,以便允许在指针类型上泛型trait PointerFamily {type Pointer<T>: Deref<Target = T>;fn new<T>(value: T) -> Self::Pointer<T>;
}
///允许借用`项目数组`.适合类似`'NdArray'`的不必连续`存储`数据的类型.
trait BorrowArray<T> {type Array<'x, const N: usize> where Self: 'x;fn borrow_array<'a, const N: usize>(&'a self) -> Self::Array<'a, N>;
}

let-else语句

引入了一个新的,带可反驳的模式和发散的不匹配模式时执行的else块的let型语句.

let PATTERN: TYPE = EXPRESSION else {DIVERGING_CODE;
};

普通let语句只能使用无可反驳模式,即静态已知总是匹配.该模式一般只是单个变量绑定,但也可解包如结构,元组和数组复合类型.

但是,这不适合如提取枚举变体的条件匹配,但现在使用let-else,可像普通let一样匹配绑定域内变量的可反驳的模式,或在(如break,return,panic!)模式不匹配时发散.

fn get_count_item(s: &str) -> (u64, &str) {let mut it = s.split(' ');let (Some(count_str), Some(item)) = (it.next(), it.next()) else {panic!("Can't segment count item pair: '{s}'");};let Ok(count) = u64::from_str(count_str) else {panic!("Can't parse integer: '{count_str}'");};(count, item)
}
assert_eq!(get_count_item("3 chairs"), (3, "chairs"));

名字绑定的域,是使其与matchiflet-else式不同的主要因素.以前,可通过一些重复和外部的来模拟这些模式:

let (count_str, item) = match (it.next(), it.next()) {(Some(count_str), Some(item)) => (count_str, item),_ => panic!("Can't segment count item pair: '{s}'"),
};
let count = if let Ok(count) = u64::from_str(count_str) {count
} else {panic!("不能解析整:{count_str}'");
};

从标签块中断开

现在可按中断(break)目标标记普通块式,来提前终止该块.有点类似goto语句,但它不是goto语句,只是从块内跳到块尾.
这在循环块中已是可能的,你可能会看到总是只执行一次的循环,只是为了得到有标签中断.

现在有个专门为此的语言功能!与循环一样,标签break也可包含式值,让多语句块有早期的"返回"值.

let result = 'block: {do_thing();if condition_not_met() {break 'block 1;}do_next_thing();if condition_not_met() {break 'block 2;}do_last_thing();3
};

拆分Linux调试信息

早在Rust1.51中,编译器团队在macOS上添加了对拆分调试信息的支持,现在在Linux上也可稳定使用该选项.

1,-Csplit-debuginfo=unpacked会将调试信息拆分为多个.dwo,DWARF目标文件.
2,-Csplit-debuginfo=packed除了输出二进制文件,还生成一个打包所有调试信息在一起的.dwpDWARF文件.
3,-Csplit-debuginfo=off仍是默认,在目标和最终二进制文件中的.debug_*ELF节中包括DWARF数据.
拆分DWARF允许链接器避免处理调试信息(因为它不再在链接目标文件中),这可加快链接时间!

对相关平台的默认值,其他目标现在也接受-Csplit-debuginfo作为稳定选项,但其他值仍不稳定.

稳定的API

std::backtrace::Backtrace
Bound::as_ref
std::io::read_to_string
<*const T>::cast_mut
<*mut T>::cast_const

特别注意,Backtrace,API允许使用一般恐慌回溯的相同平台相关的实现,来随时抓栈回溯.如,这对向错误类型添加运行时环境可能很有用.
这些API现在可在环境中使用:

<*const T>::offset_from
<*mut T>::offset_from

其他更改

Rust1.65版本中还有其他更改,包括:
现在启用了MIR内联以优化编译.
调度构建时,Cargo现在会排序等待处理作业的队列,以提高性能.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/151877.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Nginx 核心配置文 nginx.conf介绍

Nginx核心配置文件结构 我们知道Nginx的核心配置文件默认是放在/usr/local/nginx/conf/nginx.conf&#xff0c; 读取Nginx自带的Nginx配置文件&#xff0c;我们将其中的注释部分删除掉后&#xff0c;就剩下下面核心内容: worker_processes 1;events {worker_connections 1…

微服务和注册中心

微服务和注册中心是紧密相关的概念&#xff0c;可以说注册中心是微服务架构中必不可少的一部分。 在微服务架构中&#xff0c;系统被拆分成了若干个独立的服务&#xff0c;因此服务之间需要进行通信和协作。为了实现服务的发现和调用&#xff0c;需要一个中心化的注册中心来进…

大健康产业的先行者「完美公司」携手企企通,推进企业采购供应链数字化进程

随着中国经济持续向好&#xff0c;消费升级和美妆步骤增加&#xff0c;美妆和个人护理产品已逐渐成为中国消费者的日用消费品&#xff0c;推动了护肤品和化妆品的销售额增速均超过10%&#xff0c;成为中国整个快速消费品市场中的一颗亮眼明珠。 据国家统计局数据显示&#xff0…

Linux(Ubuntu)安装JDK环境

系统环境 Ubuntu20.04 下载JDK压缩包 前往Oracle官网进行后续下载或单击下载JDK压缩包 下拉找到JDK8&#xff0c;在Linux板块下选择适配系统架构的压缩包文件(后缀为tar.gz)&#xff0c;系统架构可通过uname -m命令查看 安装JDK 安装环境通常放在/usr/local下&#xff0c;进入…

【数据结构】栈与队列面试题(C语言)

我们再用C语言做题时&#xff0c;是比较不方便的&#xff0c;因此我们在用到数据结构中的某些时只能手搓或者Ctrlcv 我们这里用到的栈或队列来自栈与队列的实现 目录 有效的括号解题思路&#xff1a;代码实现&#xff1a; 用队列实现栈解题思路&#xff1a;代码实现&#xff1a…

openGauss学习笔记-128 openGauss 数据库管理-设置透明数据加密(TDE)

文章目录 openGauss学习笔记-128 openGauss 数据库管理-设置透明数据加密&#xff08;TDE&#xff09;128.1 概述128.2 前提条件128.3 背景信息128.4 密钥管理机制128.5 表级加密方案128.6 创建加密表128.7 切换加密表加密开关128.8 对加密表进行密钥轮转 openGauss学习笔记-12…

网络运维与网络安全 学习笔记2023.11.19

网络运维与网络安全 学习笔记 第二十天 今日目标 STP工作原理、STP高级配置、MSTP工作原理 MSTP配置案例、MSTP负载均衡 STP工作原理 单点故障 PC之间的互通链路仅仅存在1个 任何一个设备或链路出现问题&#xff0c;PC之间都会无法通信 解决方案 增加冗余/备份设备 增加冗…

在Broker端进行消息过滤

在Broker端进行消息过滤&#xff0c;可以减少无效消息发送到Consumer&#xff0c;少占用网络带宽从而提高吞吐量。Broker端有三种方式进行消息过滤。 1.消息的Tag和Key 对一个应用来说&#xff0c;尽可能只用一个Topic&#xff0c;不同的消息子类型用Tag来标识&#xff08;每条…

springboot引入redisson分布式锁及原理

1.引入依赖 <dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.13.6</version> </dependency>2.配置类创建bean /*** author qujingye* Classname RedissonConfig* Description TOD…

HDFS入门--学习笔记

1&#xff0c;大数据介绍 定义 数据指的是&#xff1a;一种可以被鉴别的、对客观事件进行记录的符号&#xff0c;除了可以是最简单的 数字外&#xff0c;也可以是各类符号、文字、图像、声音等。 通俗地说&#xff0c;数据就是对人类的行为及发生事件的一种记录。 存在的价值…

2023超详细的软件测试八股文(入门篇)

今天给大家分享软件测试面试题入门篇&#xff0c;看看大家能答对几题 一、请你说一说测试用例的边界 参考回答&#xff1a; 边界值分析法就是对输入或输出的边界值进行测试的一种黑盒测试方法。通常边界值分析法是作为对等价类划分法的补充&#xff0c;这种情况下&#xff0…

设计模式-创建型模式-单例模式

一、什么是单例模式 单例模式&#xff0c;属于创建类型的一种常用的设计模式。通过单例模式的方法创建的类在当前进程中只有一个实例&#xff08;根据需要&#xff0c;也有可能一个线程中属于单例&#xff0c;如&#xff1a;仅线程上下文内使用同一个实例&#xff09;。 对于系…

本地私域线上线下 线上和线下的小程序

私域商城是一种新型的零售模式&#xff0c;它将传统的线下实体店与线上渠道相结合&#xff0c;通过会员、营销、效率等方式&#xff0c;为消费者提供更加便利和高效的购物体验。私域商城的发展趋势表明&#xff0c;它将成为未来零售业的重要模式&#xff0c;引领零售业的创新和…

【设计模式】聊聊策略模式

策略模式的本质是为了消除if 、else代码&#xff0c;提供拓展点&#xff0c;对拓展开放&#xff0c;对修改关闭&#xff0c;也就是说我们开发一个功能的时候&#xff0c;要尽量的采用设计模式进行将不变的东西进行抽取出来&#xff0c;将变化的东西进行隔离开来&#xff0c;这样…

【开源】基于Vue.js的音乐偏好度推荐系统的设计和实现

项目编号&#xff1a; S 012 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S012&#xff0c;文末获取源码。} 项目编号&#xff1a;S012&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、系统设计2.1 功能模块设计2.1.1 音乐档案模块2.1…

【数据库】你听说过矢量数据库吗?

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️其他领域】 文章目录 前言什么是向量/矢量数据库嵌入模型使用向量数据库的优势与传统数据库的对比其他方面 AWS 如何支持您的矢量数据库需求&#xff1f;Amazon OpenSearch ServiceAmazon Aurora Pos…

[Docker]记一次使用jenkins将镜像文件推送到Harbor遇到的问题

系统版本&#xff1a; Ubuntu 18.01 私服&#xff1a; Harbor Docker版本&#xff1a; Docker version 18.09.5 首先需要明确的是&#xff0c;即在harbor里项目设置为公开&#xff0c;但是在push的时候还是需要用户验证的&#xff0c;即需要使用docker登录 docker login harbo…

CF1514 C. Product 1 Modulo N [妙妙题]

传送门:CF [前题提要]:感觉这道题是真的妙,解这道题的所有步骤都是一步一步按图索骥来的,有种玩解密游戏的感觉 题目很简单,就是求1~n中最长的子序列,使得这n个数的乘积模n为1. 乍一看很不好解决.那不妨先假设我们挑选了 k k k个数,然后这 k k k个数的乘积为 K K K, K K K模 …

【Unity】流体模拟(更新ing)

Fluid Simulation 参考于 Sebastian Lague 的项目进行分析学习 流体模拟视频链接 文章目录 Fluid Simulation2D流体Simulation2D.cs 2D流体 Simulation2D.cs 流体的边界用OnDrawGizmos设置流体的边界 void OnDrawGizmos(){Gizmos.color new Color(0, 1, 0, 0.4f);Gizmos.Dr…

vue中绑定class样式和条件渲染

绑定class样式 字符串写法&#xff1a; 适用于&#xff1a; 样式的类名不确定&#xff0c;需要动态指定 数组写法&#xff1a; 适用于&#xff1a; 要绑定的样式个数不确定&#xff0c;名字也不确定 绑定对象&#xff1a;适用于&#xff1a;要绑定的样式个数确定、名字确定、…