东风草堂博客

公众号:开发者来风

Windows Subsystem for Linux(简称WSL)是一个在Windows 10上能够运行原生Linux二进制可执行文件(ELF格式)的兼容层。它是由微软与Canonical公司合作开发,其目标是使纯正的Ubuntu、Debian等映像能下载和解压到用户的本地计算机,并且映像内的工具和实用工具能在此子系统上原生运行。

使用了wsl可以丢弃VMware。

安装wsl

参考:https://docs.microsoft.com/en-us/windows/wsl/install-manual

PowerShell执行下面命令安装wsl:

阅读全文 »

网络编程的痛点

reactor是基于异步事件的网络模型,但io操作都是同步的:非阻塞io,io多路复用,拷贝数据时还是需要等待。
同步和异步的区别是结果是否在发起调用处返回。阻塞与非阻塞的区别是io没有就绪的情况下是否立刻返回。
reactor的事件处理是异步的,回调太多会影响业务逻辑的编写,一个业务逻辑在不同的回调中完成,需要保存和传递上下文。需要通过协程捏合回调。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
void on_login(struct bufferevent *bev, struct Arg *args) {
if (args->eles < 2) {
reply_error(bev, "on_login 登陆参数个数不对\n");
return;
}
Arg *params = args->next;
const char *name = params->str;
size_t name_len = params->len;

params = params->next;
const char *password = params->str;
size_t password_len = params->len;

replyContext *rc = (replyContext *)malloc(sizeof(replyContext));
rc->bev = bev;
rc->args = args;

redisAsyncCommand(redis_conn, redis_login_hget, rc, "hgetall roll: %s", name); // redis_login_hget为回调函数,需要传递上下文
}

// redisAsyncCommand实现思路
// 1. 准备socket
// 2. connect
// 3. 准备好协议
// 4. send
// 5. fd、callback加入epoll,使用yield,跑到下方的2.read部分

// callback处理,这是另外一个线程(协程要想办法改为同一个线程)
// 1. epoll_wait
// 2. read fd
// 3. 解析对应的数据,使用resume,接着跑上面的第五步
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function CMD.login(fd, name, password)
if not name or not password then
socket.write(fd, "没有设置账号或密码\n")
return
end
if clients[fd] then
socket.write(fd, ("%s 用户已登陆\n"):format(name))
return
end
local ok, err = rds:exists("role:"..name)
if ok == 0 then
rds:hmset("role:"..name,
"name", name,
"password", password) -- 同步处理
local cli = {}
cli.fd = fd
cli.name = name
cli.password = password
clients[fd] = cli
socket.write(fd, ("%s 注册成功\n"):format(name))
return
end
end

协程

阅读全文 »

Makefile 中=和:= 的区别

1
2
3
4
5
x = foo
y = $(x) bar
x = xyz
all:
@echo "$(y)"

执行make后,得到结果
xyz bar

1
2
3
4
5
x := foo
y := $(x) bar
x := xyz
all:
@echo "$(y)"

执行make后,得到结果
foo bar

阅读全文 »

无重复字符的最长子串

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
滑动窗口解法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {
public:
int lengthOfLongestSubstring(string s) {
unordered_map<char, int> dic;
int i = -1, res = 0, len = s.size();
for(int j = 0; j < len; j++) {
if (dic.find(s[j]) != dic.end())
i = max(i, dic.find(s[j])->second); // 更新左指针
dic[s[j]] = j; // 哈希表记录
res = max(res, j - i); // 更新结果
}
return res;
}
};

动态规划解法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution {
public:
int lengthOfLongestSubstring(string s) {
unordered_map<char, int> dic;
int res = 0, tmp = 0, len = s.size(), i;
for(int j = 0; j < len; j++) {
if (dic.find(s[j]) == dic.end()) i = - 1;
else i = dic.find(s[j])->second; // 获取索引 i
dic[s[j]] = j; // 更新哈希表
tmp = tmp < j - i ? tmp + 1 : j - i; // dp[j - 1] -> dp[j]
res = max(res, tmp); // max(dp[j - 1], dp[j])
}
return res;
}
};
阅读全文 »

分布式锁

多个服务竞争稀缺资源,需要使用分布式锁。

  • 锁是一种资源,需要存储,高可用性,避免锁全局失效。
  • 隐含条件:加锁和释放锁必须是同一个对象,需要记录持有锁的对象。
  • 另外需要实现互斥的语义,获取锁做个标记,释放锁时取消标记。
  • 获取锁和释放锁都是网络通信实现的,需要考虑锁超时的问题。
  • 锁释放通知问题:a.定时探寻。b. 被动通知(包括广播,和通知能够获取锁的特例)
  • 是否允许同一个对象多次获取锁,可重入锁

特性:互斥性、可重入性、锁超时(取到锁的进程可能会宕机)、高可用性(redis集群实现,哨兵模式和cluster模式都是异步复制、最终一致性,可能会丢数据,cluster集群lua脚本可能失效)、分类(公平锁:根据队列顺序获取锁、非公平锁:随机派发锁)
其中高可用可分为计算型和存储型,计算型的是无状态的,存储型需要有一致性的协议,主要包括选举主节点、数据复制。

实现方式:redis/mysql、zookeeper/etcd

阅读全文 »

在 CMake 中,add_dependenciestarget_link_libraries 是两个不同的命令,用于不同的目的。

add_dependencies

add_dependencies 用于在目标之间建立构建依赖关系。它指定一个目标在另一个目标之前构建。

语法:

1
add_dependencies(target-name dependency-target1 [dependency-target2 ...])
阅读全文 »

都2022年了,再来谈谈拥有一个属于自己的留言板小程序的必要性,特别是想多和粉丝进行互动的号主朋友,为了增加与粉丝的粘性,为了让公众号变得有点灵性,还是有必要有一个自己的留言功能的,而且需要一个稳定可靠的留言功能。

没有留言功能,也不知道自己的文章写的好不好,得不到读者的反馈,渐渐的也就失去了坚持下去的动力,如果留言功能经常出问题,也会影响读者的体验,不知道的还以为公众号文章出问题了。

什么是留言小程序

首先要说明一下,留言板小程序是显示在文章末尾为小程序链接,需要引导读者点击进去进行留言的,并不是直接显示在文章末尾,那个只有微信原版的留言功能才能做到这样了。

界面是和微信原生基本保持一致的,功能上只会多不会少,可以回复留言、留言点赞、留言置顶、粉丝互动(即粉丝间可以互相留言),这些都是最基本的留言功能。

阅读全文 »

stl组成部分

容器、算法、迭代器、仿函数(函数对象),比如比较器、适配器、空间适配器(内存分配器)

容器

C++ 提供了多种标准容器。以下是 C++ 中常见的容器:
Array:静态数组,大小固定。
Vector:动态数组,支持随机访问和动态扩容。
List:双向链表,支持插入和删除操作。
Forward_list:单向链表,支持插入和删除操作。
Deque:双端队列,支持在队首和队尾进行插入和删除操作。
Stack:栈,支持基本的栈操作,先进后出。
Queue:队列,支持基本的队列操作,先进先出。
PriorityQueue:优先队列,支持按优先级插入和删除元素。
Set:集合,不允许重复元素,元素按一定的排序规则存储。
Map:映射,不允许重复的 key,元素按 key 的大小排序存储。
Unordered_set:哈希表实现的集合,不允许重复元素。
Unordered_map:哈希表实现的映射,不允许重复的 key。

迭代器的实现原理

阅读全文 »
0%