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)類問題總結

相關文章
相關標籤/搜索