0%

内网穿透方案比较

这是一篇内网穿透流水账

自从学 linux 之后,一直想拥有自己的一台物理 linux 服务器。所以一直在折腾 linux 服务器,大学的时候笔记本安装了 linux,试用了好多的 linux 发行版,沉迷过定制化 linux 桌面。可惜最后我的笔记本显卡硬件不太兼容 linux 硬件,关机的时候会 frozen,因此只买了一台学生云。买完之后,基本空置,基本没怎么用。

工作只有还是有服务器的瘾,因此购入了一个 arm 的机顶盒,用来刷入linux系统,相当于一个简单的 homelab

为了在外面访问 homelab,需要进行内网穿透,探索了几种内网穿透的服务,用来总结一下吧

阅读全文 »

从感染新冠到康复的全过程

今年国内的疫情政策在 12 月发生了一个 180 度的大转弯,起初是河北石家庄放开之后,过了一个周,各地开始排查河北返乡人员。但又过了一个周以后,政府开始推行”防疫20条",之后很快就停止了常态化核酸检测,停止了查看核酸结果和健康码。
防疫20条以后,就经常在互联网上看到各种囤积医疗物资的分享,例如囤积呼吸机、血氧仪、各种退烧药、抗生素等。老实说我对于囤呼吸机和血氧仪不太理解,最早我是怀着鄙夷的态度,认为不过是大号的流感,没必要这么重视。 常态化核酸停了两个周左右,各个博主开始分享自己阳了之后的经历,普遍发烧(或者高烧),无力,嗓子痛等症状。我开始重视新冠病毒,于是去药店买了一盒布洛芬,一盒阿莫西林,药店向我推荐过中成药,说是卫健委推荐的新冠药,被我直接拒绝

一个周后,周围开始有零星几个病例,开始发烧,或者核酸阳性,混管阳性,同时退烧药销售一空。回家发现家里还有一盒之前买的复方氨酚烷胺胶囊(主要成分为:对乙酰氨基酚),还有几片维c泡腾片。

发作

不知道奥密克戎的潜伏期是多久,同时不清楚的还有奥密克戎发烧前的症状。所以怀疑自己新冠,怀疑了一个周,但是依然没反应。
直到周末晚上,我感觉到嗓子不舒服,我猜到应该是中招了。

阅读全文 »

GO 协程池(任务池)的实现

实现主要来源于:

servicecomb-service-center

  1. 首先创建一个协程池的结构体,考虑我们所需要的东西
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
// 任务接口,需要有一个 Run 的方法
type Task interface{
Run()
}

// 检查接口是否实现
var _ Task =(*sumtask)(nil)

// 一个求和任务,实现了 Task 接口里面的方法
type sumtask struct {
a int
b int
}

func(t *sumtask) Run() {
fmt.Println(a + b)
}


type Pool struct {
// 我们给协程设置一个空闲时间,如果协程一直没有负载,直接退出就行
idletime time.Duration
// pending 用于给运行中的协程添加任务
pending chan Task
// worker 用于限制协程数量
workers chan struct{}
}
阅读全文 »

Gitbook 使用体验

最近要写 openstack 组件的部署文档,因为有很多的组件,决定把文档拆分来写。最后可能要发布成文件,提供为他人浏览,所以需要一种可以导出到 pdf 的工具来编写文档。
尝试了几种工具,最终敲定了 gitbook

常见的 markdown 编写文档工具
1. docsify 只能导出html 2. mdbook rust 编写,单二进制,有一个导出到epub的插件。以及所有页面可以通过浏览器导出到单pdf文件(没有目录) 3. sphinx 好像不太方便 4. gitbook 支持导出 pdf(需要安装 calibre) ,可以导出 html(本地浏览需要修改 js), 不再维护,但是可以使用

Gitbook 安装

需要提前安装 node.js, npm 工具
国内源很慢,可以考虑更换npm淘宝源(详情可以百度)

阅读全文 »

一、部署监控节点 ceph-mon

启动监控节点需要下面这些内容:
1. unique id ==> fsid 集群唯一标识 id,区别集群
2. cluster name ==> 集群名(不可以有空格) 默认为 ceph, 多个集群时,集群名便于查看 ceph --cluster {cluster-name}). ,也可以简化命令行操作 3. monitor name ==> 监控实例的名字,普遍设置为监控实例所在主机的主机名,(推荐一个主机只有一个监控,最好不要有 osd 和其他监控)
4. monitor map ==> 启动时需要生成,需要 fsid, cluster name ,至少一个名字或者IP地址(大概意思时至少有一个节点吧)
5. administrator keyring ==> ceph cli 需要有 client.admin 用户,必须生成 admin 用户和 keyring 文件,添加 client.admin 用户 到 monitor keyring 中

来源: https://docs.ceph.com/docs/master/install/manual-deployment/

1. 安装必要的软件包

监控节点需要安装 ceph-common ceph-base ceph-mon librados2 等包 yum install ceph-common ceph-base ceph-mon librados2

阅读全文 »

leetcode 51 N 皇后

八皇后的题目已经很熟悉了,就是回溯的思想,具体说就是深度优先搜索

这里给出一种递归的写法:

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
32
33
34
35
36
37
38
39
40
41
42
43
class Solution {
public:
void dfs(int map[], int cur, int &n, vector<vector<string>>& ret) {
if(cur >= n) {
// 将当前的状态转换为二维字符串状态
vector<string> rr ;
for(int i = 0; i < n; i++) {
string curline;
for(int j=0;j<map[i];j++)
curline += ".";
curline += "Q";
for(int j=map[i]+1;j<n;j++)
curline += ".";
rr.push_back(curline);
}
ret.push_back(rr);
}

for(int i=0; i < n; i++) {
bool flag = false;
for(int j=0;j<cur;j++){
// 重点
if(map[j] == i || abs(map[j] - i) == abs(cur-j)) {
flag = true;//killed
break;
}
}
if(!flag) {// if not killed
map[cur] = i;
// cout<<"place "<<i<<"on "<<cur<<endl;
dfs(map,cur+1,n, ret);
}
}
}


vector<vector<string>> solveNQueens(int n) {
vector<vector<string>> ret;
int map[n];
dfs(map, 0, n, ret);
return ret;
}
};

简单地说一下思路:
1. map 是一个一维的数组,但是可以用来记录二维的数据,map 的下标表示行号, map的值表示 列号, map[4]=3表示第4行、第3列防止一个皇后 2. dfs 是深度优先搜索 3. N 皇后的主要限制是横竖左右不得有其他皇后, map[j] == i || abs(map[j] - i) == abs(cur-j),前面部分表示选取两行,这两行的皇后不得在同一列上;后面部分表示这两行的皇后不得在一个对角线上。

阅读全文 »

Leetcode 32 最长的有效括号

开胃菜 Leetcode 20 有效括号

给定一个字符串,判断括号等符号个数能否匹配正确
很明显,需要使用堆栈,流程: 1. 遇到左侧符号时,将其推入到栈中 2. 遇到右侧符号时,判断栈是否为空 3. 若栈为空,直接 return false ,因为这时候需要一个左括号弹出栈,而我们是空栈,所以不匹配 4. 若栈不为空,判断栈顶元素是否与当前符号相匹配,若匹配,则弹出,若不匹配,则 return false 5. 返回第一步

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
class Solution {
public:
bool isValid(string s) {
stack<char> ss;
for(int i=0;i<s.length();i++){
if(s[i]=='('||s[i]=='{'||s[i]=='[')
ss.push(s[i]);
else{
if(ss.empty()) return false;
if(s[i]==')'&&ss.top()=='(')
{
ss.pop();
}else if(s[i]=='}'&&ss.top()=='{')
{
ss.pop();
}else if(s[i]==']'&&ss.top()=='['){
ss.pop();
}else
return false;
}
}
if(ss.empty()) return true;
else return false;
}
};

算法复杂度 O(n)
注意: 记得遇到右侧符号的时候,要检查栈是否为空,否则后面会访问空栈

阅读全文 »

Leetcode 542 01 Matrix

给定一个矩阵,求矩阵中的元素到相邻的最近的0的距离是多少,返回结果矩阵

  1. 0 元素距离最近的0,也就是自己,所以距离还是0
  2. 1 元素就要我们求了
  3. 这很明显是图论的问题,而且是求极值,而不是判断有无解的题目,所以应当用 BFS,广度优先搜索

比较巧妙的地方在于构造移动方向,以前见过的迷宫问题的移动方向是通过两个数组,一个控制 x 方向,另一个控制 y 方向,然后通过二重循环,遍历四个方向 :

1
2
3
4
5
6
7
8
9
int x_dir[]={0,0,1,-1};
int y_dir[]={1,-1,0,0};

for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
int new_x=cur_x+x_dir[i];
int new_y=cur_y+y_dir[j];
}
}
阅读全文 »

leetcode 454 4Sum II

首先想到的是四维循环。。。 但很明显❎️

大部分算法都是将问题的规模变小,然后将小问题组合成为最后需要问题的解

将前两个 vector 中所有数字组合的和记录到一个哈希表中,然后在后两个 vector 中找是否有数字和哈希表中的数字成相反数就可以了

复杂度: 遍历两个 vector 复杂度是 \(N^2\) ,所以最后的复杂度也就是 \(O(n^2)\)

阅读全文 »