Arch Linux 常用软件

本文部分内容基于manjaro,另外如果喜欢苹果界面,可以试下pearos。理论上基于Arch的发行版都可以使用本文进行安装。如果您安装好了manajro但是又不想重装系统,可以试下这个脚本来将Manjaro自动转换为Arch,。 Arch 安装后必装的软件 通过archinstall 安装以后,是没图形界面的。需要安装下面的一些软件和配置 安装时,声音后端的选择: PulseAudio,历史悠久、最为常用; PipeWire,新生代,采用全新架构,整合多种音频后端(PulseAudio、ALSA和JACK),提供低延迟的音频体验 启用网络 systemctl enable dhcpcd systemctl enable wpa_supplicant systemctl enable NetworkManager 蓝牙 sudo systemctl enable --now bluetooth 如果没这个服务,可能需要通过 paru -S bluetooth进行安装。 如果需要启用蓝牙音频支持,请安装 paru -S pulseaudio-bluetooth 蓝牙高级管理工具 paru -S blueman 打印机 paru -S cups ghostscript gsfont 然后启动服务 sudo systemctl enable --now cups // 可能需要启动 sudo systemctl enable --now cups-browsed 打印机驱动 paru -S foomatic-db foomatic-db-ppds # 基本驱动 paru -S foomatic-db-nonfree foomatic-db-nonfree-ppds # 非自由软件驱动 启用MTP/PTP支持 和Windows一样,Linux也支持MTP、PTP设备,这样就可以方便地与安卓手机、数码相机等外设连接,管理文件。不过对这类设备的支持并非与生俱来,而是有赖于GVFS(Gnome Virtual File System),它把对其他设备或网络环境的访问抽象成一系列I/O接口,意味着可以像平时读写磁盘那样访问它们。...

February 23, 2022 · 19 min · czyt

go-kratos使用备忘

需要特别注意的一些建议 API路由覆盖的问题 比如有两个接口 A get /v1/user/{user_id}和 B get /v1/user/profile如果A定义在B之前,那么B可能会被A覆盖路由。需要将A放到B之前。 JWT使用的建议 摘自极客时间课程《高并发系统实战课》 通讯过程必须使用 HTTPS 协议,这样才可以降低被拦截的可能。 要注意限制 token 的更换次数,并定期刷新 token,比如用户的 access_token 每天只能更换 50 次,超过了就要求用户重新登陆,同时 token 每隔 15 分钟更换一次。这样可以降低 token 被盗取后给用户带来的影响。 Web 用户的 token 保存在 cookie 中时,建议加上 httponly、SameSite=Strict 限制,以防止 cookie 被一些特殊脚本偷走。 自定义接口返回内容 正常的响应序列化逻辑通过Response Encoder实现。 错误的序列化逻辑通过ErrorEncoder实现。 注意:自定义Encoder后,可能会遇到零值字段被忽略的情况,可以参考这个issue。具体的解决办法是 proto定义返回内容,然后将生成的类型在encoder中使用。 简单代码大致如下: proto定义 import "google/protobuf/any.proto"; // BaseResponse is the base response message BaseResponse{ int32 code = 1 [json_name = "code"]; google.protobuf.Any data = 2 [json_name = "data"]; } go代码...

August 12, 2022 · 32 min · czyt

一个RustFace demo程序

下面是一个基于RustFace这个库的demo程序。基于原项目 整理。image随便下载一张,model.bin从原项目进行下载即可。 Cargo.toml配置 [package] name = "faceDemo" version = "0.1.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] rustface = "0" image= "0.23.14" src/main.rs use rustface::{Detector, FaceInfo, ImageData}; fn main() { let imageFile = "1.png"; let modelFile = "model.bin"; let mut detector = rustface::create_detector(modelFile).unwrap(); detector.set_min_face_size(20); detector.set_score_thresh(2.0); detector.set_pyramid_scale_factor(0.8); detector.set_slide_window_step(4, 4); let img = image::open(imageFile).unwrap(); let gray = img.to_luma8(); let (width, height) = gray.dimensions(); let mut image = ImageData::new(&*gray, width, height); for face in detector....

February 27, 2024 · 1 min · czyt

Rust完整备忘单【译】

原文 https://katib.moe/the-completesh-rust-cheat-sheet 本文大部分通过机器翻译进行翻译,小部分进行了微调。官方有个更全的 https://cheats.rs 这个“完整的 Rust 备忘单”提供了 Rust 编程语言的全面指南,涵盖了它的所有主要功能。涵盖的主题范围从非常基础的知识(例如语法和基本概念)到更复杂的方面(例如并发和错误处理)。该备忘单还深入研究了 Rust 的独特功能,例如所有权、借用和生命周期,以及其强大的类型系统和健壮的宏系统。对于每个主题,都提供了清晰的示例来阐明解释。对于刚刚开始使用 Rust 的初学者和想要快速回顾特定 Rust 概念的经验丰富的开发人员来说,这是一个理想的资源。 我编写了这份备忘单作为 Rust 编程语言的综合指南,旨在将其作为个人参考工具。然而,Rust 社区的美妙之处在于共享学习和协作。因此,如果您发现我遗漏的内容、错误,或者您有改进建议,请随时分享您的反馈。请记住,没有人是绝对正确的,本资源也不例外 - 通过您的见解,我们可以继续改进和完善它。快乐 Rustacean! 基本语法和概念 你好世界 这是标准的“你好,世界!” Rust 中的程序。 fn main() { println!("Hello, world!"); } 变量和可变性 Rust 中的变量默认是不可变的。要使变量可变,请使用 mut 关键字。 let x = 5; // immutable variable let mut y = 5; // mutable variable y = 6; // this is okay 数据类型 Rust 是一种静态类型语言,这意味着它必须在编译时知道所有变量的类型。 let x: i32 = 5; // integer type let y: f64 = 3....

February 23, 2024 · 12 min · czyt

Rust的一些难点解惑【译】

原文 https://katib.moe/the-hard-things-about-rust, 本文使用机器翻译而成,部分文字进行了调整。 Rust 是一种系统编程语言,运行速度极快,可防止段错误并保证线程安全。虽然这些功能使 Rust 成为系统编程的强大工具,但它们也引入了一些对于来自其他语言的人可能不熟悉的新概念。 在这份综合指南“Rust 的困难之处”中,我们的目标是阐明 Rust 的这些具有挑战性的方面,并使新手和经验丰富的程序员都可以使用它们。我们将阐明这些复杂的概念,并用具体示例和现实场景来说明每个概念,以便更好地理解。 以下是我们将要介绍的内容: 所有权:我们将从 Rust 中所有权的基本概念开始。我们将探讨一个值拥有所有者意味着什么,所有权如何转移,以及 Rust 的所有权模型如何帮助内存管理。 借用和生命周期:在所有权的基础上,我们将深入研究借用和生命周期,这两个相互关联的概念可让您安全地引用数据。 切片:我们将揭开切片的神秘面纱,切片是内存块的视图,它在 Rust 中广泛用于高效访问数据。 错误处理:Rust 处理错误的方法是独特且稳健的。我们将介绍 Result 和 Option 类型,以及如何使用它们进行优雅的错误处理。 并发:我们将深入研究 Rust 强大而复杂的并发模型。我们将讨论线程、消息传递和共享状态并发等。 高级类型和Trait:我们将探索 Rust 的一些高级类型,例如 Box 、 Rc 、 Arc 。我们还将介绍 Trait 和 Trait 对象。 Async/Await 和 Futures:当我们转向高级概念时,我们将解释 Rust 的 async/await 语法和用于处理异步编程的 Futures 模型。 本指南的目标不仅仅是提供这些主题的概述,而是帮助您了解这些概念背后的基本原理、它们在幕后如何工作以及如何在 Rust 程序中有效地使用它们。 无论您是希望深入了解该语言的 Rust 初学者,还是旨在巩固对这些复杂概念的理解的中级 Rustacean,本指南都适合您。让我们踏上这段征服 Rust 难点的旅程吧! 所有权 所有权是 Rust 的一个基本概念。它是 Rust 内存安全方法的一部分,使 Rust 在编程语言中独一无二。理解所有权对于编写 Rust 程序至关重要,因为许多其他 Rust 概念(例如借用和生命周期)都是建立在它之上的。...

February 21, 2024 · 9 min · czyt

golang检测字节是否为utf-8字节的起始字节

原理 UTF-8 编码使用不同长度的字节序列来表示 Unicode 字符。这些序列的长度从一个字节到四个字节不等,每个字节都有特定的比特模式。您可以通过观察任何字节的最高位(也就是最左边的几位比特),来判断这个字节是不是某个字符的 UTF-8 编码的起始字节或中间字节: 单字节字符(U+0000 到 U+007F)以 0xxxxxxx 为模式,其中 x 可以是 0 或 1。这种单字节的高位为 0,表示它是 ASCII 字符的起始(也是唯一)字节。 UTF-8 编码的起始字节(即多字节序列的第一个字节)模式为 110xxxxx(对于两字节编码)、1110xxxx(对于三字节编码)或 11110xxx(对于四字节编码)。 对于一个 UTF-8 字符的非起始字节(也称为连续字节或中间字节),其模式为 10xxxxxx。 因此,如果你看到一个字节,它的最高两位是 10,那么它是 UTF-8 编码中的一个连续字节。如果最高一位是 0 或者高位模式匹配 110、1110 或 11110,它就是起始字节。 举例来说: 0xxxxxxx - UTF-8 字符的起始字节(单字节 ASCII 字符) 110xxxxx - 两字节编码的起始字节 1110xxxx - 三字节编码的起始字节 11110xxx - 四字节编码的起始字节 10xxxxxx - 中间字节 通过检查字节的最高位,您就可以迅速确定它是 UTF-8 编码序列的起始字节还是中间字节。 实现 go语言实现 package main import ( "fmt" ) // isUTF8StartByte checks whether a byte is a UTF-8 start byte....

February 19, 2024 · 1 min · czyt

go switch的6种用法【译】

文章原文链接为 https://blog.devtrovert.com/p/switch-in-go-6-ways-to-use-it 照片由 Zbyněk Skrčený 在 Unsplash 上拍摄 Go 以其简单而闻名,但我注意到并不是每个人都熟悉 switch 语句在这种语言中的多功能性。 首先,如果您不熟悉 Go 的 switch 语句,与其他语言相比,它可能看起来有点不同。这是一个简单的例子来展示它的样子: func main() { var i int = 1 switch i { case 1: fmt.Println("i is 1") case 2: fmt.Println("i is 2") default: fmt.Println("i is not 1 or 2") } } Go 的 switch 的一个很酷的事情是,一旦找到匹配项,它就会停止,你不需要在每个 case 的末尾添加一个 break 语句。 但不仅仅如此。 Go 中的 switch 语句有两部分:分号之前的部分是初始化器,分号之后的部分是我们要检查的值。 我们可以选择同时使用、使用其中之一或都不使用: switch initializer; value {} switch initializer {} switch value {} switch {} 有趣,对吧?...

February 17, 2024 · 3 min · czyt

跟AI学习Rust

本文为学习rust过程中,向ai提问的内容汇总。配套图书为《Rust程序设计 第2版》 基础 迭代器 fuse Cow 在 Rust 中,Cow 是 “Clone on Write” 的缩写,它是一个智能指针类型,属于标准库的 std::borrow 模块。Cow 可以用来封装一个可能是借用(borrowed)也可能是拥有(owned)的值。Cow类型实际上是一个枚举类型,定义如下: enum Cow<'a, B> where B: 'a + ToOwned + ?Sized, { Borrowed(&'a B), Owned(<B as ToOwned>::Owned), } 其中 B 是被借用的类型,而 <B as ToOwned>::Owned 是该类型的拥有版本。一个具体类型必须实现 ToOwned trait,这样 Cow 才能根据需要clone被借用的数据产生一个拥有的副本。 实际用途: Cow 最大的优势在于它提供了一种方法来延迟昂贵的克隆操作,直到真正需要修改数据时才进行,这样可以提高性能。它经常被用于以下场景: 优化读多写少的情况:当数据通常只是被读取,但偶尔需要被修改时,Cow 可以避免不必要的克隆操作。 提供 API 的灵活性:某些函数可能需要对输入数据做出修改,但并不总是需要。这时,使用 Cow 作为参数类型允许调用者传递拥有的也可以是借用的值,增加了 API 的使用灵活性。 处理字符串数据:当处理字符串切片(&str)和字符串(String)时,Cow<str> 可以根据实际情况借用静态字符串或者拥有一个可变的字符串副本。 避免生命周期问题:当要返回一个引用但函数的实际行为可能需要返回一个拥有的值时,使用 Cow 可以更好地管理生命周期问题。 示例: 你可以在下面的示例中看到 Cow 的用法: use std::borrow::Cow; fn greeting(name: &str) -> Cow<str> { if name....

February 16, 2024 · 9 min · czyt

使用结构或可变参数选项简化go函数签名【译】

文章内容来自func25的 twitter 在Go中设计函数时,我们可能会遇到需要传递大量参数的情况。 这可能会影响函数的目的,并使维护代码成为一件苦差事,特别是当涉及相同类型的参数时。 为了保持整洁,请考虑两种策略: 选项结构。 可变选项。 选项结构体 将参数捆绑到一个结构中,这不仅增强了可读性,还简化了参数传递。 什么时候使用它? 你的函数有一个很长的参数列表。 您的目标是自记录代码,因为结构字段本质上描述了它们的用途(通过名称)。 您希望轻松设置默认值或灵活修改选项。 使用此模式时, context.Context 应保留为单独的参数,而不应包含在选项结构中。 这是由于上下文在控制请求范围值、截止日期和取消信号方面的独特作用。 但在使用时有一些小技巧: 该结构应该向后兼容,以便在添加新字段时,我们不会破坏之前的任何内容。 我们始终可以在处理结构之前对其进行验证。 考虑隐藏您的选项结构(使其不导出),然后公开 NewXXX() 函数并在那里设置默认值。 可变参数选项 此方法利用 Go 的函数功能,允许您以更简洁的方式传递灵活数量的选项。 它在以下情况下是理想的: 该功能需要高度可配置。 大多数选项是可选的或很少使用。 您更喜欢简洁的调用站点。 设置默认值比使用可选结构更容易,您不需要隐藏它,只需将默认值直接放在 ConnectToDatabase 中即可。

February 14, 2024 · 1 min · czyt

在 Rust 中使用 Axum【译】

本文原文地址为 https://www.shuttle.rs/blog/2023/12/06/using-axum-rust Rust Web 生态系统中有如此多的后端 Web 框架,很难知道该选择什么。尽管在更早的过去,您可能会看到 Rocket 在受欢迎程度方面跃居排行榜首位,但现在通常是 Axum 和 actix-web 展开激烈的竞争,Axum 慢慢地登上了榜首。在本文中,我们将深入研究 Axum,这是一个由 Tokio 团队支持的用于制作 Rust REST API 的 Web 框架,它易于使用,并且与 Tower 具有超兼容性,Tower 是一个强大的可重用、模块化组件库,用于构建网络应用程序。 在本文中,我们将全面了解如何使用 Axum 编写 Web 服务。这也将包括 0.7 的更改。 Axum的路由 Axum 遵循 REST 风格的 API(例如 Express)的风格,您可以在其中创建处理函数并将它们附加到 axum 的 axum::Router 类型。路线的示例可能如下所示: async fn hello_world() -> &'static str { "Hello world!" } 然后我们可以将它添加到我们的路由器中,如下所示: use axum::{Router, routing::get}; fn init_router() -> Router { Router::new() .route("/", get(hello_world)) } 为了使处理函数有效,它需要是 axum::response::Response 类型或实现 axum::response::IntoResponse 。这已经针对大多数原始类型和 Axum 自己的所有类型实现了 - 例如,如果我们想要将一些 JSON 数据发送回用户,我们可以使用 Axum 的 JSON 类型作为返回类型来轻松实现这一点, axum::Json 类型包装了我们想要发回的任何内容。正如您在上面看到的,我们还可以单独返回一个字符串(切片)。...

January 30, 2024 · 6 min · czyt