一位互联网奔跑者的网上日记

0%

   最近最少使用算法,或 最近最久未使用算法 (Least Recently Used, LRU)是一种常用的页面置换算法(当然也可以用于文件缓存等情景)。再实际情况中,如某些页面长时间未被访问,则它们在将来还可能会长时间不会访问。算法基于这个推论,选择最近最久未使用的页面予以淘汰。

  我们认为 “最近使用” 指的是读/写相应的内存页(或值),然后以一个例子(来自参考资料1)看看:

LRU过程示意

阅读全文 »

银行家算法(Banker’s Algorithm)是一个避免死锁(Deadlock)的算法。

背景

在银行中,客户申请贷款的数量是有限的,每个客户在第一次申请贷款时要声明完成该项目所需的最大资金量,在满足所有贷款要求时,客户应及时归还。银行家在客户申请的贷款数量不超过自己拥有的最大值时,都应尽量满足客户的需要。在这样的描述中,银行家就好比操作系统,资金就是资源,客户就相当于要申请资源的进程。(维基百科

察看银行家算法的历史,它于 1965 年由 Dijkstra 和学生所设计,打算应用到 THE 系统 中的。作为那个时代的产物,这个算法或许当时在避免死锁上取得了很好的效果,而技术发展日新月异,需求的变化和性能的差异使得它今天的价值主要体现在教学和思想的传播了吧。

阅读全文 »

   晚上在写一段多线程程序时,在C++标准库中发现了这样的写法,让我很惊讶:

1
this_thread::sleep_for(2s);

Ctrl + Click 点进去看,函数的声明是这样的:

1
2
3
_NODISCARD constexpr chrono::seconds operator"" s(unsigned long long _Val) noexcept /* strengthened */ {
return chrono::seconds(_Val);
}

  像是重载了双引号的写法,翻了翻 cppreference ,原来叫用户定义字面量(字面值)。

阅读全文 »

   和使用 http 类似,测试代码可以这样写:

1
2
3
4
5
6
7
8
9
10
11
12
13
use actix_web::client::Client;

#[actix_rt::main]
async fn main() {
let mut client = Client::default();

// Create request builder and send request
let response = client.get("https://sunnysab.cn")
.send().await.unwrap();

println!("{:?}", response);

}
阅读全文 »

   借一个 Actix-web::Client 官方的例子,可以这样发送一个 HTTP 请求:

1
2
3
4
5
6
7
8
9
10
11
12
13
use actix_web::client::Client;

#[actix_rt::main]
async fn main() {
let mut client = Client::default();

// Create request builder and send request
let response = client.get("http://sunnysab.cn")
.send().await.unwrap();

println!("{:?}", response);

}
阅读全文 »

最近在用 Diesel 查询符合条件的行数时遇到了个问题。按照官方例子

1
2
let count = users.count().get_result(&connection);
assert_eq!(Ok(2), count);

get_result 返回一个 Result,在例子中是 Ok(2)。于是我写了这样一段代码:

1
2
3
4
5
6
7
8
let connection = establish_connection();
let uid_bindings_count = verifications.filter(uid.eq(self.uid))
.count()
.get_result(&connection)?;

if uid_bindings_count < 2 {
return Err(OpError(NoMoreVerification));
}
阅读全文 »

   在被 rust-postgresql 折磨之后,选择了 diesel 库,这才了解到对象关系映射(Object Relational Mapping, ORM) ,可以像使用本地变量和函数一样操作关系型数据库。这有点像非关系型数据库(如MongoDB)操作方式的意味,不过不知道孰先孰后。

初步认识

   diesel 提供了一个叫 diesel_cli 的工具,用来将 MySQL、PostgreSQL 或 Sqlite 上的数据表结构转换成代码,类似于 (schema.rs),或代为执行一些 SQL 语句:

1
2
3
4
5
6
7
8
9
10
// A simple schema.rs
table! {
verifications (id) {
id -> Int4,
uid -> Int4,
login_type -> Int4,
account -> Varchar,
credential -> Nullable<Varchar>,
}
}
阅读全文 »

本来标题是“惨痛的经历”,想想去掉了。 ——题记

  在项目中打算使用 PostgresSQL 做主力数据库,发现 Rust 下有个叫 postgres 的库,正好直接拿来用。 Rust 版本为 1.41,postgres 库版本 0.17。库官方给了 example,照着改了下,写了一小段业务代码做测试,然后一晚上就没了

阅读全文 »

   树的遍历有一个应用,便是目录的枚举。本程序实现了一个类似 tree 命令的功能,便于日后编程时参考。

阅读全文 »

   TCP全名传输控制协议(Transmission Control Protocol),被称为是面向连接的(connection-oriented)。与UDP不同的是,它为程序编写者提供了一个逻辑上的连接。就像一根结实的管道,一般不出错,可以调整大小。它为开发者实现了重传、拥塞控制等特性,并在设计和实现的时候已经尽可能照顾到传输的性能,相当于提供了一套可靠的、高级的传输数据的功能的接口。现在看来,计算机系统就是这样一层一层地向上垒起——一边扩展功能,一边保证可靠性。底层协议和模块服务于上层协议、模块和应用程序,才有了今天软件的百花齐放。

   本文上接 计算机网络(二) 运输层和UDP协议,它定义在 RFC 793(传输控制协议)RFC 1122(Requirements)RFC 1323(高性能拓展)RFC 2018(选择性确认选项) 以及 RFC 2581(拥塞控制) 中。文章内容在避免内容混乱的前提下尽可能做了解释,然而依旧需要一些基础知识去理解。

阅读全文 »