您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

从高级程序员的角度来看,Rust 基础知识

时间:2022-04-18 12:11:13  来源:CSDN  作者:

作者 | Daniel Bulant

译者 | 弯月

出品 | CSDN(ID:CSDNnews)

刚开始从事编程工作的时候,我使用的是php。个人感觉,PHP的语法有点笨拙且不自然,有时甚至很讨厌(为什么我必须在每个变量前加上 $ 前缀?常量前面没有$,它不是照样能理解吗?)在学习了其他语言之后,我就不喜欢PHP了,但PHP的有些地方还是还招人喜欢的,比如数组循环很容易,而且还有多种编程范式:函数式、面向对象以及trAIt等。

后来,我又学习了JS,它很像C语言,而且随处可见。期间,我也做过一些JAVA和C#的项目,但后来还是回到了JS。

我也尝试过学习C(和 C++),虽然获得了Sololearn的证书,但是我从未真正使用过这两种语言,它们看上去似乎很复杂:快速访问内存的功能很酷,但为什么我必须使用free?为什么它不知道超出作用域时,应该自动释放内存呢?

所以,我还是比较喜欢使用JS编程,因为我无需考虑内存的问题。而且,如今与IO相关的操作也不会限制V8的速度。

后来,我听说了Rust,这门语言由Mozilla开发,多年来一直雄踞StackOverflow最受喜欢编程语言的榜首,甚至超过了我十分喜爱的Typescript(我之所以喜欢Typescript,主要是因为类型安全)。所以,我就想着应该找机会试一试。

从高级程序员的角度来看,Rust 基础知识从高级程序员的角度来看,Rust 基础知识

 

学习资源

我遇到的一大难题是,寻找方便理解且简短的好资源。我不喜欢 YouTube 视频,我更喜欢快速浏览一些文档,或者在通勤路上阅读一些学习资源,而且无需耗费大量流量。

以下是我找到的资源列表:

● 《The Rust Programming Language》(
https://doc.rust-lang.org/book/):这是一本在线书籍,其中介绍了可以利用Rust实现的最常见的功能。

● 《A Gentle Introduction To Rust》(
https://stevedonovan.Github.io/rust-gentle-intro/):一本简短的书,可以在一两个小时内读完,然后再拿出一两天的时间尝试一下示例。文中涉及的内容比较深入,但很容易掌握。


https://www.reddit.com/r/rust/:这是一个reddit 社区(如果你遇到比较复杂的问题,则可以发布在此处,等待其他人解答。)

● discord社区:你可以通过这个社区向其他开发人员请教有关Rust的问题。

● Rust By Example(
https://doc.rust-lang.org/rust-by-example/index.html):其中介绍了一些示例,可以作为入门首选书。

从高级程序员的角度来看,Rust 基础知识

 

入门

参照Rust网站
https://www.rust-lang.org/)上的说明,使用rustup即可。

如果想创建一个新项目,请运行 cargo init <dir>(如果位于一个空目录内,则不需要指定 <dir>)。

然后即可从src/main.rs开始编写。

与 C 类似,主程序都包装在 main 中。不同之处在于,它不接受任何参数,也不应该返回一个整数,这些功能应该使用命名空间std::env。

另外,我推荐使用CLion并安装Rust扩展。VSCode 也有 Rust 扩展,但相比之下它的效果很差。当然你可以使用其他的JetBrains编辑器,但 CLion 具有其他编辑器没有的一些原生功能(比如调试)。拥有 GitHub 教育包的学生可以免费使用该插件。

从高级程序员的角度来看,Rust 基础知识

 

有趣的注意事项

  • 一切都有作用域

不仅是变量,就连函数和trait内部也可以使用嵌套函数和use。这些无法从外部访问,而且如果不使用就不会出现在代码中。至少我是这样认为的。

  • 必须遵守的命名方案

变量和函数/方法只能使用小写字母、数字和下划线,比如snake_case,但数字不能放在开头。

结构(和其他类型)、枚举(包括枚举值)和trait(但不包括它们的函数/方法)需要以大写字母开头,并且不能包含任何下划线。

  • 没有增量运算符

实际上有,你可以使用i += 1。与赋值相同,该表达式将返回赋值后的值(即,将 i 设置为 i + 1,然后返回 i)。

没有 i++(或者 ++i、i-- 和 --i),因为这些运算符有点混乱。

你确定如下操作的结果吗(尤其是在没有指定语言的情况下)?

a[i++ + ++i] = i++ + ++i + a[++i]

问题在于,直到最近上述运算的实际行为还是未定义的,这意味着不同的编译器(甚至可能是同一个编译器的不同版本)可能会产生不同的行为。为了解决这个问题并提高代码的可读性(Rust非常重视可读性和冗长,甚至不惜多敲几次键盘),Rust仅支持 i += 1,几乎所有人都知道该表达式的意思是变量i加1,并返回最终结果。所以,你不必知道 i++ 实际上返回的是原始值(不是新值),而且还会加1。

此外,运算符重载会使用trait,但本文不打算详细讨论。

  • 几乎所有的东西都是表达式

除了函数调用之外,还有 if、while、match 和 for 都是表达式。

你可以直接使用 if 来代替其他语言中常见的三元运算符:

let var = if something { 1 } else { 2 };

循环会根据break的调用返回结果。你可以利用它,反复重试某个操作,直到成功。

从高级程序员的角度来看,Rust 基础知识

 

变量

变量通过 let 声明,并且有作用域。类型是可选的,Rust 非常擅长推断类型(比 Typescript 更出色)。

let var: usize = 1;

上述变量定义了一个类型为usize的变量var(usize是一个32或64位的数字,具体取决于计算机架构)。

你可以重复声明变量。当重复声明某个变量时,之前声明的变量就会被删除(除非该变量被引用,在这种情况下只有引用会保留,而原始变量会被删除),而且变量的类型也会改变。

let var = 1;let var = "something";

在默认情况下,变量是不可变的。如果你想修改它们,则需要在 let 之后加上关键字 mut。

let var = 1;var = 2; // 错误!不可以修改不可变的变量
let mut var = 1;var = 2;
从高级程序员的角度来看,Rust 基础知识

 

函数

fn main(arg: u8) -> u8 { // something arg}

函数的行为几乎与JS一模一样,只不过它们并不是数据类型,而且语法上略有不同。

参数的指定与 Typescript 类似,即key: type。返回类型通过 -> 指定。

有趣的是,虽然 Rust 需要分号,但如果最后一个表达式后面的分号忘写了,它会被作为返回值(即使没有 return 关键字)。

从高级程序员的角度来看,Rust 基础知识

 

If语句

if something {} else {} else if something_else {}

if 语句的使用非常基本,不在此赘述。

有一点需要注意,如非必要,使用括号实际上是错误的。你可以利用括号指定执行顺序:

if (something || something_else) && something_other {}

如前所述,if 也可以返回一个值,而该值可用于赋值、参数、返回或其他地方。

let var = if something { 1 } else { 2 };

这里的花括号是必需的。

从高级程序员的角度来看,Rust 基础知识

 

类型

Rust的类型有两种:基本数据类型(数字、str),结构(String)。

二者之间唯一的区别是,基本类型的初始化可以直接赋值,而复杂类型则需要某种构造函数。

堆与栈

我之前几乎不需要考虑堆与栈的问题。(据我所知,JS中的对象都存储在堆中,只有基本类型在栈中。)

堆:

● 速度慢

● 比较大

● 非常快

● 比较小

基本类型和基本的结构都存储在栈中。要在堆中存贮值,需要使用Box<T>。另外,Vec<T> 也可以将值保存到堆中。

如果你使用的内存较多,或者需要在结构中使用带有值的enum,则可能需要使用堆。

如果发生栈溢出,则说明你使用了过多的栈内存。对于一些较大的值,应该使用Box。

常见的基本类型

数字:

● i8、i16、i32、i64、i128:有符号整数,包括负数。数字表示值的比特数。

● u8、u16、u32、u64、u128:无符号整数,从零开始。它们的最大容量翻了一倍,因为有一个额外的比特可用(在有符号整数中用于表示符号)。数字表示值的比特数。

● f32 和 f64:浮点数。JavaScript 世界中常见的数字。

字符串:

● str:简单的UTF-8 字符串(所有 Rust 字符串都是 UTF-8。不能使用无效的 UTF-8 字符串,会引发异常或造成panic)。通常用作指针(即 &str)。

● String:一种更复杂的类型(严格来说不是基本类型),存储在堆中。

数组:

● T :具有固定长度的数组(如果使用 Option<T> 类型,则数组内包含的元素数量可以小于实际长度)。

元组

元组可用于存储不同类型的多个值(从本质上来说就是可以容纳不同类型且大小固定的数组)。

与数组不同,元组可通过点(.)直接访问,例如 tuple.0 表示获取第一项,而 tuples 没有.len 之类的方法。

let var = (1, "str");

有一个很有意思的小技巧,你可以通过(空元组)返回“void”。既没有 return 语句,也不会返回值的函数会返回。

常见结构

Option<T>

● 这是一个枚举,值为Some(T) 或 None。(我们稍后再讨论enum,Rust中的枚举与其他语言略有不同。)

● 如果想获取该值,你可以使用 match,就像使用其他枚举一样,或者使用 .unwrap (如果值为None,则会导致panic)。

Result<T, E>

● 这个结构与 Option 类似,但常用于处理错误(通常由 IO 方法返回)。

● 它的值是 Ok(T) 或 Err(E)。

● 如果想获取该值,你可以使用match 块或 unwrap。

● 为了方便使用,当函数返回 Result<T, E> 时,可以在返回值为 Result<T, E>(其中E必须为兼容的类型)的方法调用之后使用 ? 来返回错误E(类似于使用.unwrap(),但当函数出错时不会造成panic)。

fn example -> Result<, Error> { // 一种错误类型。为了简便起见,你可以使用String,或自定义enum。 something_that_returns_result?; Ok() // returns empty Tuple}

Vec<T>

● 向量是可增长的数组,存储在堆上。

● 向量支持 .push、.pop 等常用操作。详情参见Rust文档。

Box<T>

● 在堆上存储T。可用于在结构中使用enum,或者用于释放栈空间。

定义结构

结构类似于对象,但它们的大小是静态的。

结构可以通过如下几种方式定义。

● 使用Tuple作为声明(类似于元组的别名)

struct Something(u8, u16); // a struct with 2 numbers, one unsigned 8 bit, the other one unsigned 16 bit

● 使用对象表示法(类似于声明类或对象)

struct Something { value: u8, another_value: u16}

● 使用struct作为别名

struct Something = u8; // a single value

这种方法的适用情况为:你试图创建一个enum,而其值可能是正在定义的结构,而该结构中又要(直接或间接)引用该enum。

struct MaybeRecursive { possibly_self: Option<MaybeRecursive> // error!}struct MaybeRecursive { possibly_self: Option<Box<MaybeRecursive>> // fine} 

我在为自己的shell创建抽象语法树时,就遇到了这个问题。

要创建结构的实例,需要使用下述写法(类似于C#中定义数组):

Something { variable: 1, another_variable: 1234}
从高级程序员的角度来看,Rust 基础知识

定义enum

下面是示例:

enum EnumName { First, Second}

可以为enum指定数值(例如序列化或反序列化数值的情况):

enum EnumName { First = 1, Second // auto incremented}

更强大的写法如下:

enum EnumName { WithValue(u8), WithMultipleValues(u8, u64, SomeStruct), CanBeSelf(EnumName), Empty}

你可以用match提取出值。

从高级程序员的角度来看,Rust 基础知识

Match

match是Rust最强大的功能之一。

Match是更强大的switch语句。使用方法与普通的swtich语句一样,除了一点:它必须覆盖所有可能的情况。

let var = 1;match var { 1 => println!("it's 1"), 2 => println!("it's 2"), // following required if the list is not exhaustive _ => println!("it's not 1 or 2")}

也可以match范围:

match var { 1..=2 => println("it's between 1 and 2 (both inclusive)"), _ => println!("it's something else")}

也可以什么都不做:

match var { _ => {}}

可以使用match安全地unwrap Result<T, E>和Option<T>,以及从其他enum中获取值:

let option: Option<u8> = Some(1);match option { Some(i) => println!("It contains {i}"), None => println!("it's empty :c") // notice we don't need _ here, as Some and None are the only possible values of option, thus making this list exhaustive}

如果你不使用i(或其他值),Rust会发出警告。你可以使用_来代替。

match option { Some(_) => println!("yes"), None => println!("no")}

match也是表达式:

let option: Option<u8> = Some(1);let surely = match option { Some(i) => i, None => 0}println!("{surely}");

你可以看看Option的文档(或通过IDE的自动补齐,看看都有哪些可以使用的trait或方法)。

你也许注意到了,你可以使用.unwrap_or(val)来代替上述代码(上述match等价于.unwrap_or(0))。

从高级程序员的角度来看,Rust 基础知识

Loop

loop循环是最简单的循环。只需要使用loop即可。

loop { if something { break }}

该代码会一直运行,直到遇到break(或return,return也会同时返回父函数)。

从高级程序员的角度来看,Rust 基础知识

for

for循环是最简单易用的循环。它比传统的for循环更容易使用。

for i in 1..3 {} // for(let i = 1; i < 3; i++) // i++ is not a thing, see things to notefor i in 1..=3 {} // for(let i = 1; i <= 3; i++)for i in 1..=var {} // for(let i = 1; i <= var; i++)for i in array_or_vec {} // for(let i of array_or_vec) in JS// again, as most other things, uses a trait, here named "iterator"// for some types, you need to call `.iter` or `.into_iter`.// Rust Compiler will usually tell you this.for i in something.iter {}
从高级程序员的角度来看,Rust 基础知识

while

很简单的循环。与其他语言不同,Rust没有do...while,只有最基础的while。

while condition { looped;}

语法与if一样,只不过内容会循环执行。

从高级程序员的角度来看,Rust 基础知识

打印输出

打印输出可以使用 print! 和 println!。

!表示这是一个宏(即可以扩展成其他代码的快捷方式),但你不需要过多考虑。另一个常用的宏是 vec! ,它能利用数组创建 Vec<T> (使用 [] 内的值)。

这些宏都有一个简单的模板系统。

● 输出一行使用 println!。

● 输出一个静态字符串使用 print!("something")。println!中ln的意思是行,也就是说它会添加换行符号(n)。console.log会默认添加换行。

● 要输出一个实现了Display trait的值(绝大多数基本类型都实现了),可以使用 print!("{variable}")。

● 要输出一个实现了Debug trait的值(可以从Display继承),使用 print!("{variable:?}")。

● 要输出更复杂的实现了Display trait的内容,使用 print!("{}", variable)。

● 要输出更复杂的实现了Debug trait的内容,使用 print!("{:?}", variable)。

从高级程序员的角度来看,Rust 基础知识

Trait

Trait是Rust中最难理解的概念之一,也是最强大的概念之一。

Rust没有采用基于继承的系统(面向对象的继承,或JavaScript基于原型的继承),而是采用了鸭子类型(即,如果一个东西像鸭子一样叫,那么它就是鸭子)。

每个类型都有且只有一个“默认”(或匿名)trait,只能在与该类型同一个模块中实现。通常都是该类型独有的方法。

其他的都叫trait。例如:

trait Duck { fn quack(&self) -> String; /// returns if the duck can jump fn can_jump(&self) -> bool { // default trait implementation. Code cannot have any assumptions about the type of self. false // by default duck cannot jump }}struct Dog; // a struct with empty tupleimpl Dog { // a nameless default trait. fn bark(&self) -> String { String::from("bark!") }}impl Duck for Dog { // implement Duck trait for Dog type (struct) fn quack(&self) -> String { String::from("quark!") } // dog kind of quacks differently}let dog = Dog {};dog.bark;dog.quack;

首先,我们定义了trait(在面向对象语言中叫做接口,但它只包含方法或函数)。然后为给定的类型(上例中为Dog)实现trait。

一些trait可以自动实现。常见的例子就是Display和Debug trait。这些trait要求,结构中使用的类型必须要相应地实现Display或Debug。

#[derive(Display,Debug)]struct Something { var: u8}println!("{:?}", Something { var: 1 });

作用域

Trait有作用域,而且与它实现的类型的作用域是独立的。也就是说,你可以使用一个类型,但无法使用一个trait的实现(例如,如果这个实现来自另外一个库,而不是来自该类型本身)。你可以use这个实现。

self

trait中的self指向它实现的类型。&self是指向 self: &Self 的别名,其中Self表示该类型(上例中的 self: &Dog)。self也是self: Self的别名,但两者的区别就是后者会移动变量(即消耗该变量,该变量就无法从外部访问了)。

当函数定义不以self、&self或&mut self开始时(&mut self相当于带有可改变引用的 &self),就是一个静态方法。Trait依然可以像任何方法一样定义并实现静态方法。常见的一个静态方法是new,用于创建类型或结构的实例:

impl Something { fn new -> Something { Something { x: 1 } }}...let var = Something::new;
从高级程序员的角度来看,Rust 基础知识

指针

指针实际上非常易懂,尽管它来自其他更高级的语言。我经常会用错。

&A指向A,使用时只需要确保A存在,即可保证&A存在,因为我们不应该让指针指向不存在的对象。

Rust会在编译时进行静态检查,确保不会出现上述情况。它会自动释放超出作用域的变量,并且不允许指针的存活超过变量。另一个安全保证是,只能有一个可改变的指针。

也就是说下述代码是错误的:

let a = 1;let b = &a;let c = &mut a;println!("{b}"); // Error! there can only be one mutable pointerc = 1;

我们只需要保证原始变量在指针的作用域中一直存在即可。

在结构中使用指针会有点问题,因为编译器不喜欢这种做法(因为结构的寿命通常比原始变量更长)。我通常会采用所有权转移或克隆(.clone(),Clone trait的一部分,可以被derived)。

有时候,一些函数要求只能用指针,不能用所有权转移。这时,只需在值的前面加上 & (或 &mut)即可。

something(&a);

此外,还有双重、三重等指针,但很少见,而且一般来说只会更难处理。

你也不需要考虑释放变量的问题,Rust会在超出作用域时自动释放。

从高级程序员的角度来看,Rust 基础知识

命名空间

使用全名就无需导入。导入只不过是别名。

std::env::args
use std::env;env::args
use std::env::args;args

选择多个“命名空间”可以使用{},如:

use std::env::{args, var};

也可以重复使用use:

use std::env;use std::env::args;env::var;args

还有一点,你也可以在函数内使用use。这样,如果代码没有被执行,库就不会被导入(即,如果函数没有在代码路径中出现,例如,use了一个测试用的库,而use只写在了测试用例中,那么在正常构建时就不会导入该库)。

fn test { use std::env; env::var;}

但我不推荐在正常的代码路径中这样写,应该使用全局的导入。

从高级程序员的角度来看,Rust 基础知识

可见性

讨论完命名空间之后,我们来讨论一下可见性。

本质上,默认情况下任何东西都是私有的,只能被它所在的文件访问。

● trait及其方法

● 结构及其成员

● enum(成员继承enum的可见性,这是合理的,参见Match)

● 函数

● trait的实现依赖于trait和实现该trait的结构,即,只有两者都是公有的,该实现才是公有的。

要设置为公有(即可以从外部访问),需要使用关键字pub:

pub struct Something { pub letter: char}pub trait CustomTrait { ... }pub fn method {}
从高级程序员的角度来看,Rust 基础知识

使用多个文件

有时候我会想念 require("./fire")。

要想“导入”一个文件,要使用 mod指令。通过cargo下载的crate会自动导入。

main.rs

mod my;fn main { my::function; // or use my::function; function;}

my.rs

pub fn function { println!("function");} 

你也可以使用pub mob重新导出一个文件。绝大多数已有的Rust代码都会对支持文件夹采用下列操作:

main.rs

mod my;use my::file;fn main { file::function;}

my/mod.rs - mod.rs这个名字是特殊的,类似于index.js

pub mod file;

my/file.rs

pub fn function { println!("function");}

关于println!,参见“打印输出”。

从高级程序员的角度来看,Rust 基础知识

编写文档

编写文档只需使用三个斜线 ///。一些IDE会采用不同的高亮方式显示。

类似于JSDoc,只不过其类型不会显式标注,因为代码中已经写了类型。

/// a description of varlet var = "something";

原文地址:
https://danbulant.eu/posts/rust-basics



Tags:Rust   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
Rust编程语言的内存安全与性能:如何平衡?
Rust编程语言自诞生以来,就以其独特的内存安全特性和高性能而备受瞩目。然而,如何在保证内存安全的同时,实现高效的性能,一直是Rust开发者们面临的挑战。本文将深入探讨Rust的内...【详细内容】
2024-04-12  Search: Rust  点击:(10)  评论:(0)  加入收藏
聊聊Rust里面的数据类型
嘿,朋友们!今天我们来聊聊Rust里面的数据类型。你知道吗?Rust的数据类型可是很重要的哦,它们帮助我们定义变量和函数可以处理什么样的数据。基本数据类型首先,让我们来看看Rust提...【详细内容】
2024-04-11  Search: Rust  点击:(7)  评论:(0)  加入收藏
Rust 标准库 1.77.2 发布,修复高危漏洞
IT之家 4 月 10 日消息,Rust 的优势之一就是安全,但这并不代表该编程语言就没有漏洞。安全专家近日发现了追踪编号为 CVE-2024-24576 的漏洞,攻击者利用 Rust 标准库中的一个安...【详细内容】
2024-04-10  Search: Rust  点击:(9)  评论:(0)  加入收藏
在Rust中使用Serde的详细指南
在处理HTTP请求时,我们总是需要在一种数据结构(可以是enum、struct等)和一种可以存储或传输并稍后重建的格式(例如JSON)之间来回转换。Serde是一个库(crate),用于高效、通用地...【详细内容】
2024-03-26  Search: Rust  点击:(18)  评论:(0)  加入收藏
Rust 写脚手架,Clap你应该知道的二三事
有感而发最近,在和前端小伙伴聊天发现,在2024年,她们都有打算入局Rust学习的行列。毕竟前端现在太卷了,框架算是走到「穷途末路」了,无非就是在原有基础上修修补补。所有他们想在...【详细内容】
2024-03-11  Search: Rust  点击:(31)  评论:(0)  加入收藏
前端开始“锈化”?Vue团队开源JS打包工具:基于Rust、速度极快、尤雨溪主导
Vue 团队已正式开源Rolldown &mdash;&mdash; 基于 Rust 的 JavaScrip 打包工具。Rolldown 是使用 Rust 开发的 Rollup 替代品,它提供与 Rollup 兼容的应用程序接口和插件接口...【详细内容】
2024-03-09  Search: Rust  点击:(23)  评论:(0)  加入收藏
Rust中的数据可视化指南
可视化是数据分析和解释的一个关键方面。虽然Rust主要以其性能和安全特性而闻名,但它也为数据可视化提供了强大的工具。在这个全面的指南中,我们将深入研究Rust中的数据可视化...【详细内容】
2024-03-07  Search: Rust  点击:(35)  评论:(0)  加入收藏
如何在Rust中操作JSON,你学会了吗?
sonic-rs ​还具有一些额外的方法来进行惰性评估和提高速度。例如,如果我们想要一个 JSON​ 字符串文字,我们可以在反序列化时使用 LazyValue​ 类型将其转换为一个仍然带有斜...【详细内容】
2024-02-27  Search: Rust  点击:(50)  评论:(0)  加入收藏
记一次Rust内存泄漏排查之旅
在某次持续压测过程中,我们发现 GreptimeDB 的 Frontend 节点内存即使在请求量平稳的阶段也在持续上涨,直至被 OOM kill。我们判断 Frontend 应该是有内存泄漏了,于是开启了排...【详细内容】
2024-02-27  Search: Rust  点击:(15)  评论:(0)  加入收藏
Rust 最受欢迎的这些库
今天分享主题是,关于一些值得注意的 Rust 库,这些库可以根据它们的功能和在编码中的受欢迎程度进行选择。什么是 Rust 库?在 Rust 中,常被称为 “crate” 的库,是一个打包的单元...【详细内容】
2024-02-19  Search: Rust  点击:(53)  评论:(0)  加入收藏
▌简易百科推荐
Meta如何将缓存一致性提高到99.99999999%
介绍缓存是一种强大的技术,广泛应用于计算机系统的各个方面,从硬件缓存到操作系统、网络浏览器,尤其是后端开发。对于Meta这样的公司来说,缓存尤为重要,因为它有助于减少延迟、扩...【详细内容】
2024-04-15    dbaplus社群  Tags:Meta   点击:(1)  评论:(0)  加入收藏
SELECT COUNT(*) 会造成全表扫描?回去等通知吧
前言SELECT COUNT(*)会不会导致全表扫描引起慢查询呢?SELECT COUNT(*) FROM SomeTable网上有一种说法,针对无 where_clause 的 COUNT(*),MySQL 是有优化的,优化器会选择成本最小...【详细内容】
2024-04-11  dbaplus社群    Tags:SELECT   点击:(1)  评论:(0)  加入收藏
10年架构师感悟:从问题出发,而非技术
这些感悟并非来自于具体的技术实现,而是关于我在架构设计和实施过程中所体会到的一些软性经验和领悟。我希望通过这些分享,能够激发大家对于架构设计和技术实践的思考,帮助大家...【详细内容】
2024-04-11  dbaplus社群    Tags:架构师   点击:(2)  评论:(0)  加入收藏
Netflix 是如何管理 2.38 亿会员的
作者 | Surabhi Diwan译者 | 明知山策划 | TinaNetflix 高级软件工程师 Surabhi Diwan 在 2023 年旧金山 QCon 大会上发表了题为管理 Netflix 的 2.38 亿会员 的演讲。她在...【详细内容】
2024-04-08    InfoQ  Tags:Netflix   点击:(5)  评论:(0)  加入收藏
即将过时的 5 种软件开发技能!
作者 | Eran Yahav编译 | 言征出品 | 51CTO技术栈(微信号:blog51cto) 时至今日,AI编码工具已经进化到足够强大了吗?这未必好回答,但从2023 年 Stack Overflow 上的调查数据来看,44%...【详细内容】
2024-04-03    51CTO  Tags:软件开发   点击:(9)  评论:(0)  加入收藏
跳转链接代码怎么写?
在网页开发中,跳转链接是一项常见的功能。然而,对于非技术人员来说,编写跳转链接代码可能会显得有些困难。不用担心!我们可以借助外链平台来简化操作,即使没有编程经验,也能轻松实...【详细内容】
2024-03-27  蓝色天纪    Tags:跳转链接   点击:(16)  评论:(0)  加入收藏
中台亡了,问题到底出在哪里?
曾几何时,中台一度被当做“变革灵药”,嫁接在“前台作战单元”和“后台资源部门”之间,实现企业各业务线的“打通”和全域业务能力集成,提高开发和服务效率。但在中台如火如荼之...【详细内容】
2024-03-27  dbaplus社群    Tags:中台   点击:(13)  评论:(0)  加入收藏
员工写了个比删库更可怕的Bug!
想必大家都听说过删库跑路吧,我之前一直把它当一个段子来看。可万万没想到,就在昨天,我们公司的某位员工,竟然写了一个比删库更可怕的 Bug!给大家分享一下(不是公开处刑),希望朋友们...【详细内容】
2024-03-26  dbaplus社群    Tags:Bug   点击:(9)  评论:(0)  加入收藏
我们一起聊聊什么是正向代理和反向代理
从字面意思上看,代理就是代替处理的意思,一个对象有能力代替另一个对象处理某一件事。代理,这个词在我们的日常生活中也不陌生,比如在购物、旅游等场景中,我们经常会委托别人代替...【详细内容】
2024-03-26  萤火架构  微信公众号  Tags:正向代理   点击:(14)  评论:(0)  加入收藏
看一遍就理解:IO模型详解
前言大家好,我是程序员田螺。今天我们一起来学习IO模型。在本文开始前呢,先问问大家几个问题哈~什么是IO呢?什么是阻塞非阻塞IO?什么是同步异步IO?什么是IO多路复用?select/epoll...【详细内容】
2024-03-26  捡田螺的小男孩  微信公众号  Tags:IO模型   点击:(10)  评论:(0)  加入收藏
站内最新
站内热门
站内头条