ARTS Week 24

Algorithm

本周的 LeetCode 题目为 69. Sqrt(x)

给你一个非负整数 x ,计算并返回 x算术平方根

由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去

注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5 。

输入:x = 4
输出:2

可以使用二分法来进行处理,因为使用乘法进行判断可能会出现溢出,因此更好地处理策略是使用除法来进行计算。又最后的结果只需要保留整数部分,因此当 mid+1 > x / (mid+1)mid < x / mid 时,那么此刻最后结果就是mid

class Solution {
    public int mySqrt(int x) {
        if (x == 0 || x == 1) {
            return x;
        }
        int left = 1;
        int right = x;
        int ans = -1;
        int mid;
        while (left < right) {
            mid = left + (right - left) / 2;

            if (mid+1 <= x / (mid+1)) {
                left = mid;
            } else if (mid > x / mid) {
                right = mid;
            } else {
                ans = mid;
                break;
            }
        }
        return ans;
    }
}

Review

本周 Review 的英文文章为:改善隐私保护配置SSH的3种方法

作者介绍了如何优化SSH体验并保护服务器免受未经授权的访问,下面是作者给出具体建议。

  1. 更改默认端口

默认的SSH端口是22,尽管你改变端口后,各种端口扫描器仍能发现它,但可以减少被扫描的次数。例如,作者的一个云服务器SSH端口为 TCP 22,平均每天被扫描攻击为24,但将端口改为 TCP 45678 后,每天的攻击数降为了2个。

要更改SSH的默认端口,打开 /etc/ssh/sshd_config 并将端口值更改为大于1024的某个数字,如果有注释需要取消注释,具体示例如下:

#Port 22122
#AddressFamily any 
#ListenAddress 0.0.0.0 
#ListenAddress ::

更改端口并保存文件后,重新启动SSH服务器。

$ sudo systemctl restart sshd
  1. 没有更多的密码

作者建议使用非对称密钥进行身份验证,需要先生成一个SSH密钥对,公钥需要传输到服务器,另一个是私有的,与任何人共享。使用 ssh-keygen 创建一个新密钥,并使用 -t 选项指定一个好的、最新的加密库,例如 ed25519

$ ssh-keygen -t ed25519    
Generating public/private ed25519 key pair. 
Enter file in which to save the key (~/.ssh/id_ed25519):

按照提示输入密钥所在的位置和自定义名称,并可以指定密码,当然你也可以一路按照默认配置进行。

接下来使用 ssh-copy-id 命令将密钥复制到服务器上,例如下面的命令将公钥复制到一个名为 example.com 的服务器上。

$ ssh-copy-id jgarrido@example.com

一旦你从计算机可以在没有密码的情况下登录,编辑 sshd_config 中的允许密码登录的选项 PasswordAuthentication 设置为 no

最后使用 sudo systemctl restart sshd 重新启动ssh服务即可

  1. 决定谁可以登录

大多数Linux发行版不允许root用户通过SSH登录,打开SSH的配置文件sshd_config,添加如下一行:

AllowUsers jgarrido jane tux

这将仅允许jgarrido、jane、tux这三个用户远程登录进行操作。

除此之外,sshd_config 文件中还有大量的有用的功能和选项,你也可以使用 Fail2ban 等应用来进一步保护你的SSH服务。

Tip

C语言中 strcmpstrncmpmemcmp 这三个比较函数的区别,它们三个都可以用来比较字符串是否相同,当返回值等于0代表相同,返回值不为0代表不相同。首先根据他们的声明来对比:

函数名 函数声明 是否需要传入要比较的长度 如何结束比较
strcmp int strcmp(const char *s1, const char *s2); 不需要 \0 作为 s1 和 s2 的结尾
strncmp int strncmp(const char *s1, const char *s2, size_t n); 需要 以传入的参数 n 作为比较长度,同时以 \0 作为 s1 和 s2 的结尾
memcmp int memcmp(const void *s1, const void *s2, size_t n); 需要 以传入参数 n 作为比较长度

需要注意的是,strncmp() 会有两个条件用来判断结束,其一便是传入的长度,其二便是字符串结尾 \0,字符串 \0 后面的内容并不会被比较。

#include <stdio.h>
#include <string.h>

int main()
{
    const char s1[] = "abcd\0\0\0\0";
    const char s2[] = "abcd\0xyz";
    const char s3[] = "abcdabcd";

    printf("----- strcmp() -----\n");
    printf("strcmp(s1, s2) = %d\n", strcmp(s1, s2)); // 0
    printf("strcmp(s1, s2) = %d\n", strcmp(s1, s2)); // 0
    printf("strcmp(s1, s2) = %d\n", strcmp(s2, s3)); // -97

    printf("----- strncmp() -----\n");
    printf("strncmp(s1, s2, 4) = %d\n", strncmp(s1, s2, 5)); // 0
    printf("strncmp(s1, s3, 4) = %d\n", strncmp(s1, s3, 5)); // -97
    printf("strncmp(s2, s3, 4) = %d\n", strncmp(s2, s3, 5)); // -97
    printf("strncmp(s1, s2, 8) = %d\n", strncmp(s1, s2, 8)); // 0
    printf("strncmp(s1, s3, 8) = %d\n", strncmp(s1, s3, 8)); // -97
    printf("strncmp(s2, s3, 8) = %d\n", strncmp(s2, s3, 8)); // -97

    printf("----- memcmp() -----\n");
    printf("memcmp(s1, s2, 4) = %d\n", memcmp(s1, s2, 5)); // 0
    printf("memcmp(s1, s3, 4) = %d\n", memcmp(s1, s3, 5)); // -97
    printf("memcmp(s2, s3, 4) = %d\n", memcmp(s2, s3, 5)); // -97
    printf("memcmp(s1, s2, 8) = %d\n", memcmp(s1, s2, 8)); // -120
    printf("memcmp(s1, s3, 8) = %d\n", memcmp(s1, s3, 8)); // -97
    printf("memcmp(s2, s3, 8) = %d\n", memcmp(s2, s3, 8)); // -97

    return 0;
}

Share

这周分享下自己写的介绍如何使用C语言读写CSV文件的三篇文章。欢迎大家拍砖:)

C语言读取写入CSV文件 [一]基础篇)

C语言读取写入CSV文件 [二]进阶篇——写入CSV文件)

C语言读取写入CSV文件 [三]进阶篇——读取CSV文件)

posted @ 2022-02-06 21:34  永远是萌新的阿岩  阅读(33)  评论(0编辑  收藏  举报