Arts 第七周(4/29 ~ 5/5)

ARTS是什么?
Algorithm:每周至少作一个leetcode的算法题;
Review:阅读并点评至少一篇英文技术文章;
Tip:学习至少一个技术技巧;
Share:分享一篇有观点和思考的技术文章。java

Algorithm

题目一
linux

LC 41. First Missing Positive算法

解答
数组

给一个整形数组,找出最小缺失的正整数,例如 [0,-1,2] 中最小缺失的正整数就是 1,[1,2,4,9] 中最小缺失的正整数就是 3。这道题若是不加上 O(n) 时间和 O(1) 空间这样的限定条件,应该再简单不过,可是加上了这两个要求,一会儿使问题变得棘手。怎么来思考?首先这道题给定的条件颇有限,输入参数就只有数组,若是非要用 O(n) 时间和 O(1) 空间来作的话,表示咱们除了输入数组之外,不能借助任何其余的数据结构。数组应该是属于一类最最基础的数据结构,除去 length 以外,就只有两个属性 index 和 value,那这道题就变成了 “如何利用数组的 value 和 index 之间的关系来找到最小缺失正整数”,若是想到了这一点,就已经成功了一半。若是继续想下去有几点是能够明确的:数据结构

  1. 缺失的正整数确定在 [1, array.length + 1] 这个范围内
  2. 咱们能够交换输入数组中的元素的位置来让 index 和 value 的关系更加明确
  3. 保证 index 和 value 的关系后,咱们能够经过 index 来断定整数的存在性

第一点很好理解,一个数组总共有 array.length 这么多个数,所有排满,也就是 1,2,...array.length, 那么答案就是 array.length + 1,没有排满,那么在这之间确定是有缺失元素的。第二点是说咱们能够经过交换来让 index 和 value 造成对应,咱们看的是 value,可是 index 能够辅助咱们寻找。前两点明确了,第三点就是从头至尾寻找答案的过程。post

实现参考代码学习

public int firstMissingPositive(int[] nums) {
    if (nums == null || nums.length == 0) {
        return 1;
    }
    
    for (int i = 0; i < nums.length;) {
        if (nums[i] <= 0 || nums[i] > nums.length || nums[nums[i] - 1] == nums[i]) {
            i++;
            continue;
        }
        
        // swap
        int tmp = nums[nums[i] - 1];
        nums[nums[i] - 1] = nums[i];
        nums[i] = tmp;
    }
    
    for (int i = 0; i < nums.length; ++i) {
        if (nums[i] != i + 1) {
            return i + 1;
        }
    }
    
    return nums.length + 1;
}
复制代码

总结
spa

代码中 index 和 value 的对应关系是 index = value - 1,代码实现有两点须要注意,第一是,交换完后,须要判断交换过来的数是否须要被放到相应的地方,例如 [2,3,1];第二点时,元素越界的话,以及元素 value 已经和 index 对应上了,那么就应该继续遍历,例如 [0,-1,1][1,1]。总的来讲这道题并无涉及什么算法和数据结构的应用,有点像脑筋急转弯的感受,想到了就作的出,想不到的话就作不出,可是它给咱们解数组问题提供了一个新的方向:利用 index 和 value 的对应关系来辅助求解操作系统


Review

两篇关于 Linux 操做系统的启动和初始化的文章:
.net

An introduction to the Linux boot and startup processes

An introduction to GRUB2 configuration for your Linux machine

第一篇文章讲的是关于 Linux 操做系统的启动和初始化,有如下几个阶段:

  • BIOS POST(Power On Self Test)
    • 检查硬件功能是否正确
    • 完毕后会触发 BIOS 中断,定位到引导扇区(为接下来的 Bootloader 做准备)
  • GRUB2(GRand Unified Bootloader, version 2)
    • 启动管理器,帮助计算机可以找到操做系统内核,并把它加载到内存中运行
    • 配置文件目录在 /boot/grub2/grub.cfg
    • 三个阶段
      • 阶段 1,在 MBR(Master Boot Record) 扇区中找到 boot.img 文件,只有 446 Bytes,这一步只是为下一步做准备
      • 阶段 1.5,在 MBR 和第一扇区之间,对应到 core.img 文件,这是开始运行文件系统的驱动器,为下一个阶段做准备
      • 阶段 2,全部的相关文件在 /boot/grub2/i386-pc 目录下,这个阶段主要是找到并加载 Linux kernel 到 RAM,把计算机的控制权交给 kernel,有关 kernel 的文件,开头都是 vmlinuz,能够在 /boot 目录下查看现有的 kernel
      • kernel 能够本身提取和解压,kernel 运行后,加载 systemd,也就是最初始进程,并把控制权交给它,启动阶段到此结束
  • 初始化阶段
    • systemd
      • 是全部进程的母进程
      • 加载文件系统,定义在 /etc/fstab
      • 配置文件在 /etc/systemd/system/default.target 里,这里面定义了什么状态和目标须要被初始化到当前用户
      • 根据需求来启动相应的 target 文件

第二篇文章讲的是如何配置 GRUB2

  • 配置文件在 /boot/grub2/grub.cfg,产生于 Linux 的安装,每当新的 kernel 被安装,会从新生成
  • grub.cfg 要找的配置文件在 /etc/grub.d 目录下,这些文件开头的数字是为了给 grub.cfg 文件一个参考顺序,以便对应正确。用户能够在这个目录下本身添加文件,主要目的是为了非 Linux 的操做系统,但注意必须紧跟着 10_linux 以前或以后
  • 因为 grub.cfg 文件较为复杂,能够考虑更改 /etc/default/grub 文件来达到目的,这个文件里面存放的都是很简单的 key-value 对,下面是一些 keys 的定义:
    • GRUB_TIMEOUT:GRUB 启动时的 kernel 选择菜单持续时间,单位 /秒
    • GRUB_DISTRIBUTOR:kernel 选择菜单上面 kernel 对应的具体名称
    • GRUB_DEFAULT:启动时默认的 kernel
    • GRUB_CMDLINE_LINUX:kernel 启动时的传入参数,一经设置,对全部 kernels 生效
    • GRUB_DISABLE_RECOVERY:若是设成 “false”,恢复通道会在每一个安装的 kernel 产生,若是设成 “true”,不会产生恢复通道
    • ...
  • 使用命令 grub2-mkconfig > /boot/grub2/grub.cfg 来产生 grub.cfg 文件
  • 建议把 GRUB_DISABLE_RECOVERY 设成 “false”,而后根据本身的定义生成 grub.cfg 文件

Tip

在看极客时间上面操做系统专栏的时候,学习了一个 PPT 记笔记的方法,严格意义上来说,这个不能算是一个技术技巧,应该算是一个学习技巧,可是用好了能够帮助咱们更清晰高效地记笔记。步骤以下:

  1. 为文章中一段知识(也能够是一个章节)作一张 PPT,标题就是段落大意,正文罗列这段当中的全部知识点,并给不清楚,不了解的知识点标号
  2. 针对步骤 1 当中不清楚、不了解的知识点进行学习,查找资料补充,将资料和重要的点贴在接下来的几张 PPT 中,这里可能还会出现不清楚,不了解的嵌套知识,继续编号便可
  3. 当第一张 PPT 中全部不清楚的地方都弄懂了,把全部以知识点为标题的 PPT 都放在最后看成附页

这么下来,回头看文章就会以为很是清晰,忘了的地方也可很方便地去对应附页中寻找。这样的记笔记的方法可让你深刻一个知识点,把书读 “厚”,很适合精学。


Share

最近写算法题写的比较多,分享的内容也都是和算法有关的,感受题型总结、分类很重要,时常回顾也很重要。但愿本身在这个阶段多多积累些基础知识,不光是算法,还有其余不少不少须要学的基础知识。

LeetCode 滑动窗口(Sliding Window)类问题总结

相关文章
相关标签/搜索