ARST打卡第217周[217/521]

Algorithm

lc1_两数之和

2023年07月01日 实在没有想到今天的今日一题居然是LeetCode第一题,震惊,哈哈,反复确认了3次

思路很简单:

  1. 直接遍历过程把 {i, nums[i]} 加到一个集合,然后每次遍历都用 target - nums[i] 查一下集合
  2. 方法二,三还可以直接记录原来的数据对应的下标
    1. O(n) 继续方法一,但是集合不用记录下标了,因为已经记录了对应的数字了,因为这种写起来比较简单,所以用这个
    2. O(nlogn) 排序一下,然后双指针

一遍过了,然后看了一下当年自己的提交记录,发现是用的同样的方法,但是写法比当年成熟了许多,哈哈。还是有一点点长进的。
但是看了一眼题解,发现自己还是少了一步优化过程,就是这里的set集合可以就用hash_table的key来承担…只能说长进不够多,以前居然没有学习题解的习惯,害,还好现在有学习题解的习惯了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_set<int> find_set;
unordered_map<int, int> nums2i;
vector<int> ans;
int find_val = 0;
for (int i = 0; i < nums.size(); i++) {
find_val = target - nums[i];
if (!find_set.empty() &&
find_set.find(find_val) != find_set.end()) {
ans.emplace_back(nums2i[find_val]);
ans.emplace_back(i);
return ans;
}
find_set.insert(nums[i]);
nums2i[nums[i]] = i;
}
return ans;
}
};

优化版,也即题解的版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> hashtable;
for (int i = 0; i < nums.size(); ++i) {
auto it = hashtable.find(target - nums[i]);
if (it != hashtable.end()) {
return {it->second, i};
}
hashtable[nums[i]] = i;
}
return {};
}
};

Review

永久存储全世界数据的方法【TED演讲】

存储技术已经进展了很多年了,但是如何存下全世界的数据呢?答案就是DNA存储。
因为DNA可以用最小的空间存储最多的数据,而且还能很友好的复制,恢复,测序__对应数据复制,读取,对比。

Tips

nfs服务器安装

Share

容器使用nfs系列问题解决方案分享

容器使用nfs没有权限

只有wsl能使用nfsd和nfs,wsl内安装的轻量版的ubuntu22.04镜像的docker无法使用,一直报错没权限,很迷惑. 比如以下操作在 wsl 中都是正常的,但是在 docker 中都是不正常的…

  • nfsd失败
1
2
3
4
5
6
7
root@69033e222523:~# /etc/init.d/nfs-kernel-server restart
* Stopping NFS kernel daemon [ OK ]
* Unexporting directories for NFS kernel daemon... [ OK ]
mount: /proc/fs/nfsd: permission denied.
* Exporting directories for NFS kernel daemon...
exportfs: No host name given with /root/share (rw,sync,no_root_squash,no_subtree_check), suggest *(rw,sync,no_root_squash,no_subtree_check) to avoid warning
exportfs: /root/share does not support NFS export [fail]
  • nfs挂载也失败
1
2
3
4
5
6
7
8
9
root@69033e222523:/opt/bin# mount -t nfs -o vers=3,nolock 172.18.170.161:/root/share /mnt/ -v
mount.nfs: timeout set for Mon Jun 26 15:30:08 2023
mount.nfs: trying text-based options 'vers=3,nolock,addr=172.18.170.161'
mount.nfs: prog 100003, trying vers=3, prot=6
mount.nfs: trying 172.18.170.161 prog 100003 vers 3 prot TCP port 2049
mount.nfs: prog 100005, trying vers=3, prot=17
mount.nfs: trying 172.18.170.161 prog 100005 vers 3 prot UDP port 55469
mount.nfs: mount(2): Operation not permitted
mount.nfs: Operation not permitted

执行命令时,必须加入–privileged这个参数,不然在Mount时会报permission denied的错误。

发现systemctl等等操作也是需要这个--privileged

A: 所以找到方法修改容器的特权属性 (如果是k8s大批量生产,则删除掉老容器,新容器 docker run--privileged 即可)

容器配置位于 /var/lib/docker/containers/<id>/hostconfig.json - 您可以编辑它并重新启动容器,但编辑它时 docker 不应运行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# docker run -ti --name test fedora:25 /bin/bash
# echo 512 > /proc/sys/net/core/somaxconn # in docker
bash: /proc/sys/net/core/somaxconn: Read-only file system
# exit # exit docker, back to host
# systemctl stop docker # or stop it with whatever servicemanager you're using

# cd /var/lib/docker/containers/b48fcbce0ab29749160e5677e3e9fe07cc704b47e84f7978fa74584f6d9d3c40/
# cp hostconfig.json{,.bak}
# 可能需要 : apt-get install -y jq
# cat hostconfig.json.bak | jq '.Privileged=true' | jq '.SecurityOpt=["label=disable"]' > hostconfig.json

# systemctl start docker
# docker start test
test
# docker exec -ti test /bin/bash
# echo 512 > /proc/sys/net/core/somaxconn # in docker, now works

NOTICE: 需要重启docker服务,而不只是重启容器(只重启容器的话,配置更改没法生效).
当然,这会在您进行更改时关闭所有容器

终于不报错权限问题了,当成nfs客户端也是能够成功了,但是 nfsd exportfs 还有有点点问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
root@69033e222523:/# mount -t nfs -o vers=3,nolock 172.18.170.161:/root/share /mnt/ -v
mount.nfs: timeout set for Mon Jun 26 16:24:35 2023
mount.nfs: trying text-based options 'vers=3,nolock,addr=172.18.170.161'
mount.nfs: prog 100003, trying vers=3, prot=6
mount.nfs: trying 172.18.170.161 prog 100003 vers 3 prot TCP port 2049
mount.nfs: prog 100005, trying vers=3, prot=17
mount.nfs: trying 172.18.170.161 prog 100005 vers 3 prot UDP port 55469
root@69033e222523:/# ll /mnt/
total 16
drwxr-xr-x 2 root root 4096 Jun 26 14:33 ./
drwxr-xr-x 1 root root 4096 Jun 13 10:20 ../
-rw-r--r-- 1 root root 2 Jun 26 14:28 a
-rw-r--r-- 1 root root 2 Jun 26 14:33 b

root@69033e222523:/# /etc/init.d/nfs-kernel-server restart
* Stopping NFS kernel daemon [ OK ]
* Unexporting directories for NFS kernel daemon... [ OK ]
* Exporting directories for NFS kernel daemon...
# 下面这个确实可以加个 `*` 去除掉告警
exportfs: No host name given with /root/share (rw,sync,no_root_squash,no_subtree_check), suggest *(rw,sync,no_root_squash,no_subtree_check) to avoid warning
exportfs: /root/share does not support NFS export [fail]

容器exportfs目录无效的问题

问题原因: nfsd对于分享的文件目录的文件系统有要求,好像得是ext4什么的,然而容器使用的文件系统是 OverlayFS (nfs-kernel-server 无法使用 FUSE 文件夹,例如加密的ecryptfs主目录和 OverlayFS )

解决方案一: 用 -v 映射宿主机的一个目录给 docker 来作为 docker 的 nfsd 共享目录,有人已经验证过了: 在docker容器中执行exportfs -a命令提示不支持NFS导出
解决方案二: 也许挂载一个其他的盘,并且格式化掉这个盘的文件系统格式来共享

容器没法使用systemctl

如法炮制之前修改 privilege 的方法

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
# 在容器外面,关闭掉容器服务
# systemctl stop docker # or stop it with whatever servicemanager you're using

# cd /var/lib/docker/containers/69033e22252338879cca59d256e03061c9f2068625a83e755358bdfccbaf94d3/
# cp config.v2.json{,.bak}
# 可能需要 : apt-get install -y jq
# man jq 了解 更多 jq 的用法
# 这样Cmd没有加中括号的 or 没有搞成2层嵌套的(见下面2注解),会导致失败: cat config.v2.json.bak | jq '.Cmd="/sbin/init"' | jq '.Path="/sbin/init"' > config.v2.json
# 1. 复制命令不要复制到了 `#` 2. 好像.Cmd这里会生成第二个 Cmd,没有捕获 .Cmd成功 __ 仔细看了一下,发现原始的 Cmd 是 Config的子选项,因此 .Config.Cmd
# cat config.v2.json.bak | jq '.Config.Cmd=["/sbin/init"]' | jq '.Path="/sbin/init"' > config.v2.json

# 作完上面操作之后,内容变成人类易读的样子,在docker启动后, json文件又会变回单行文件
# systemctl start docker
# docker start du22
du22
# docker exec -it du22 bash
root@69033e222523:/# systemctl status ssh # in docker, now works
● ssh.service - OpenBSD Secure Shell server
Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2023-06-26 19:01:05 CST; 30s ago
Docs: man:sshd(8)
man:sshd_config(5)
Process: 72 ExecStartPre=/usr/sbin/sshd -t (code=exited, status=0/SUCCESS)
Main PID: 80 (sshd)
CGroup: /docker/69033e22252338879cca59d256e03061c9f2068625a83e755358bdfccbaf94d3/system.slice/ssh.service
└─80 "sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups"

Jun 26 19:01:04 69033e222523 systemd[1]: Starting OpenBSD Secure Shell server...
Jun 26 19:01:05 69033e222523 sshd[80]: Server listening on 0.0.0.0 port 22.
Jun 26 19:01:05 69033e222523 sshd[80]: Server listening on :: port 22.
Jun 26 19:01:05 69033e222523 systemd[1]: Started OpenBSD Secure Shell server.