Seven's blog

你不会找到路,除非你敢于迷路

0%

ARTS-No.9

Algorithm

66. 加一

思路:

  1. 从最低位开始, 依次把当前位数字加一:
    1. 如果当前位数字加一后结果小于十, 直接返回当前数组, 程序结束;
    2. 如果当前位数字加一后结果等于十, 把当前位数字置为 0. 把当前位左移 1, 跳转到第 1 步;
  2. 如果第 1 步执行结束之后程序依然没有终止, 证明数字一直累加到了最高位, 那么当前数组长度已经放不下加一后的数字了. 重新声明一个长度加一的数组, 最高位置为 1, 其他位置按序填充原数组的内容即可.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution {
public int[] plusOne(int[] digits) {
int length = digits.length;
for (int i = length - 1; i >= 0; i--) {
if (++digits[i] < 10) {
return digits;
}

digits[i] = 0;
}

int[] temp = new int[length + 1];
temp[0] = 1;
for (int i = 1; i < temp.length; i++) {
temp[i] = digits[i - 1];
}

return temp;
}
}

执行用时: 0ms, 内存消耗: 35.1MB.

Review

声明!!!

水平以及精力有限,下文可能存在很多问题错译,仅做个人学习之用,如果需要学习 Docker, 还请查阅其他资料!!!

Post-installation steps for Linux

这个章节主要包含了 Docker 在 Linux 下的可选的优化配置.

使用非 root 用户管理 Docker

Docker 守护进程绑定在 Unix 套接字而不是 TCP 端口. 默认情况下 Unix 套接字属于 root 用户, 其他用户只能通过 sudo 命令获得授权. Docker 守护进程经常使用 root 用户身份运行.

如果你不想通过 sudo 命令运行 docker, 可以创建一个 叫做 “docker” 的 Unix 用户组并且把用户添加到这个用户组. Docker 守护进程启动的时候会创建一个 docker 用户组下所有成员都有权限的 Unix 套接字.

警告:

Docker 用户组拥有和 root 用户相同的权限.

操作流程:

  1. 创建 docker 用户组.

    1
    sudo groupadd docker
  2. 把用户添加进 docker 用户组.

    1
    sudo usermod -aG docker $USER
  3. 退出当前账户并重新登录, 当前账户的组成员信息会被重新加载.

    如果你是在虚拟机中测试, 那么你可能需要重启虚拟机.

    在 Linux 桌面版中, 你需要完全退出当前会话并重新登录.

    在 Linux 中, 你也可以使用下面的命令激活用户组的变更:

    1
    newgrp docker
  4. 使用非 sudo 方法测试 docker 命令.

    1
    docker run hello-world

设置 Docker 自启动

当前大多数 Linux 发行版使用 systemd 来管理服务自启动.

可以使用这个命令设置自启动:

1
sudo systemctl enable docker

可以使用下面的命令禁用自启动:

1
sudo systemctl disable docker

设置 Docker 守护进程监听连接

默认情况下, Docker 守护进程会通过一个 UNIX 套接字监听来自本地客户端的连接. 可以通过配置使 Docker 监听 一个 IP

和 端口来接收远程主机的连接.

通过 systemd 单元文件配置远程访问

  1. 使用命令 sudo systemctl edit docker.service 在文本编辑器中打开一个 docker.service 的替代文件.

  2. 添加或者修改这几行, 替换成你自己的值

    1
    2
    3
    [Service]
    ExecStart=
    ExecStart=/usr/bin/dockerd -H fd:// -H tcp:://127.0.0.1:2375
  3. 保存文件.

  4. 重新加载 systemctl 配置.

    1
    sudo systemctl daemon-reload
  5. 重启 Docker

    1
    sudo systemctl restart docker.service
  6. 通过观察 netstat 的输出来确认 dockerd 在监听刚才配置的端口.

    1
    2
    sudo netstat -lntp | grep dockerd
    tcp 0 0 127.0.0.1:2375 0.0.0.0:* LISTEN 3758/dockerd

通过 daemon.json 配置远程访问

  1. 设置 /etc/docker/daemon.json 中的 hosts 数组来连接 Unix 套接字和 IP 地址, 如下:

    1
    2
    3
    {
    "hosts": ["unix::///var/run/docker.sock", "tcp://127.0.0.1:2375"]
    }
  2. 重启 Docker.

  3. 通过观察 netstat 的输出来确认 dockerd 在监听刚才配置的端口.

    1
    2
    sudo netstat -lntp | grep dockerd
    tcp 0 0 127.0.0.1:2375 0.0.0.0:* LISTEN 3758/dockerd

常见问题的解决方案

对症下药, 这里不转译了.

为 Docker 指定 DNS 服务

默认的配置文件是 /etc/docker/daemon.json. 你可以使用 --config-file 标记更改配置文件的位置. 下面的文档假设配置文件是 /etc/docker/daemon.json.

  1. 创建或者修改 docker 进程配置文件, 这个文件默认是 /etc/docker/daemon.json.

    1
    sudo nano /etc/docker/daemon.json
  2. 添加一个名为 dns 的键, 对应的值可以写一个或者多个 IP 地址. 如果这部分内容已经存在于文件中, 你只需要添加或者修改 dns 对应的那一行.

    1
    2
    3
    {
    "dns": ["8.8.8.8", "8.8.4.4"]
    }

    如果你的内网 DNS 服务器不能解析公网 IP 地址, 请至少配置一个可以解析公网 IP 地址的 DNS 服务器. 以便于你可以连接到 Docker 中心并且你的容器可以解析公网域名.

    保存并且关闭文件.

  3. 重启 Docker 进程.

    1
    sudo service docker restart
  4. 通过拉取一个镜像验证 Docker 可以解析外部 IP 地址.

    1
    docker pull hello-world
  5. 如果有需要, 可以通过 ping 一个内部 IP 地址来验证 Docker 是否可以解析内部 IP 地址.

    1
    2
    3
    4
    5
    6
    7
    docker run --rm -it alpine ping -c4 <my_internal_host>

    PING google.com (192.168.1.2): 56 data bytes
    64 bytes from 192.168.1.2: seq=0 ttl=41 time=7.597 ms
    64 bytes from 192.168.1.2: seq=1 ttl=41 time=7.635 ms
    64 bytes from 192.168.1.2: seq=2 ttl=41 time=7.660 ms
    64 bytes from 192.168.1.2: seq=3 ttl=41 time=7.677 ms

允许通过防火墙远程访问 API

如果你在运行 Docker 的同一台主机上运行了防火墙, 在 Docker 中启用了远程访问并且希望从另一台主机访问 Docker 的 API, 你需要配置防火墙来允许外部连接访问 Docker 端口, 默认端口在开启了 TLS 加密传输的情况下是 2376, 其他情况下是 2375.

两个比较常见的防火墙是 UFW 和 firewalld.

  • UFW: 在 UFW 中进行如下配置: DEFAULT_FORWARD_POLICY="ACCEPT".

  • firewalld: 把类似的规则添加到你的策略中(其中一条是入口规则, 另一条是出口规则), 一定要确认接口名字和链路名字是正确的.

    1
    2
    3
    4
    <direct>
    [ <rule ipv="ipv6" table="filter" chain="FORWARD_direct" priority="0"> -i zt0 -j ACCEPT </rule> ]
    [ <rule ipv="ipv6" table="filter" chain="FORWARD_direct" priority="0"> -o zt0 -j ACCEPT </rule> ]
    </direct>

Your kernel does not support cgroup swap limit capabilities

在 Ubuntu 或者 Debian 系统中, 你可能会在运行镜像的时候遇到类似的错误:

1
WARNING: Your kernel does not support swap limit capabilities. Limitation discarded.

这个警告不会出现在基于 RPM 的系统, 它们已经默认启用了这些功能.

如果你不需要这些特性, 你可以忽视这个警告. 或者你也可以通过下面的说明启用这些特性, 但是内存和交换会产生总内存的 1% 并且总体性能会降低 10%, 即使 Docker 没有在运行.

  1. 使用拥有 sudo 权限的账号登录系统 (Ubuntu 或者 Debian);

  2. 编辑 /etc/default/grub 文件, 添加或者编辑 GRUB_CMDLINE_LINUC 这一行并添加如下两个键值对:

    1
    GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1"

    保存并关闭文件.

  3. 更新 GRUB.

    1
    sudo update-grub

    如果你的 GRUB 配置文件有错误, 这里一步会发生错误. 在这种情况下, 你需要重复第 2 步和第 3 步.

    这个设置会在系统重启后生效.

Tip

SpringBoot 单元测试事务回滚

SpringBoot 中如果要写单元测试只需要给测试类添加两个注解即可:

1
2
@SpringBootTest
@RunWith(SpringRunner.class)

如果需要进行事务回滚, 可以通过添加 @Transitional 注解实现, @Transitional 可以添加到类或者方法上:

  • 如果添加到方法上, 那么只对当前方法进行事务回滚;

  • 如果添加到类上, 那么当前类的所有方法都会进行事务回滚;

    在这种情况下, 如果要对个别方法提交事物, 可以在对应方法上添加 @Rollback(false) 注解来提交事务.

Share

不尝试一下,你怎么知道自己不行?

记录了 ARTS 第一期的打卡总结, 因为文字较多, 独立写了一篇文章.

参考文献

  • SpringBoot实现单元测试时回滚事务 — Alphathur
微信公众号
扫码关注, 一起进步!