2018q1 Homework3 (list)
contributed by <rwe0214
>
作業說明
生日悖論
如何透過近似的運算式,估算上述機率計算呢?附上有效的 LaTeX 算式
- 假設 1 年有 365 天
- n 個人生日不重複的事件為
- 樣本數為
- 機率 為
- 則 n 個人生日重複的機率 為
- 將 展開可得
- 將 n = 22 代入
- 將 n = 23 代入 ,機率為
- 生日攻擊 即利用在 hash function 中的 collision 現象做攻擊。
- 一個設計良好的 hash function 不容易利用 hash value 反推回原本的明文 ,但是若是這個 hash value 的 bit 數不夠多( 即值域不夠大 ),那麼我們可以透過生日悖論的想法,去枚舉找到另一份明文 其
- 也許枚舉這個動作聽來不怎麼可怕,但是將生日悖論求得的數學式代入會發現
- 若 則
- 換句話說,我只需要枚舉 的 就有超過一半的機率使得
- 換句話說這個產生器也只能產生接近真的亂數的偽亂數而已
- 那要如何產生真正的亂數呢?
- 在這個產生器裡,亂數產生是根據使用者輸入的 seed 所 "計算" 出來的。
- 所以我們只要在每次產生亂數的時候,隨機的輸入 seed 的就行了!
- ???
- 產生亂數的時候要先隨機輸入 seed,這不就是蛋生雞還是雞生蛋一樣的問題了嗎!
- 參考資料
Linux 風格的 linked list
為何 Linux 採用 macro 來實作 linked list?一般的 function call 有何成本?
- function call 會在程式呼叫時將 function 所需 argument 和 pc 返回地址
push
進 stack,並且在 function 結束時從 stack pop
出正確的 pc 返回地址。
- 而 macro 則是會在程式呼叫的地方直接展開插入程式碼,而省略了 push 和 pop 的動作。
Linux 應用 linked list 在哪些場合?舉三個案例並附上對應程式碼,需要解說,以及揣摩對應的考量
- 在老師的講座中有提到,linux 在排程管理上使用了 linked list 來實做,所以我便以這個方向去查詢。
- linux/kernel/sched/sched.h
- 功能:process 管理
- 依據註解的說明這個 struct 是 real-time schedule 的 priority-queue,而這個 queue 是以 linked list 來實做
- linux/mm/slab.h
- 功能:kernel memory 的管理
- 由註解中可以看到在這個 struct 中也是以 linked list 穿接起系統中所有的 slab cache
- What is slab cache ?
- Slab 算是 Kernel 裡最早的一種演算法,事實上,除了 Slab 之外,Linux Kernel 已經實作出數種演算法,以優化記憶體的配置機制。前面提到,Kernel 的底層是以 page 為記憶體配置的單位,因此,哪怕只是需要 1 Byte 的空間,都會佔用一個 page,所以良好的 Slab 演算法,才能盡可能避免記憶體浪費和破碎的問題。
- Slab Allocator 實作了一個 cache 的架構(這裡的 cache 並非意指快取),對系統程式下的記憶體需求群組化,以達到管理的目的。一般的程式可以藉由向 Slab 註冊 cache,以得到記憶體的配置。
- 參考資料:Linux Kernel 記憶體管理機制之美
- linux/mm/swap.c
- 功能:釋放一連串的 page ( 以 lru 法則挑選 )
- 不僅行程排班是以 linked list 實做,連記憶體的 page 結構也是以 linked list 來完成。
GNU extension 的 typeof 有何作用?在程式碼中扮演什麼角色?
解釋以下巨集的原理
- 這個 macro 定義了
ptr
去指向 member
這個結構成員的地址,這個地方也使用 typeof 來讓 ptr
可以是使用者所指定的 type。
- 最後再減掉這個 member 在原本
struct
中的記憶體位移量來算出 struct
的記憶體起始位置。
除了你熟悉的 add 和 delete 操作,list.h 還定義一系列操作,為什麼呢?這些有什麼益處?
- 說明在某些已經知道 pre/next 節點的情況下,使 __xxx 版本的 linked list 操作會更 useful。
LIST_POISONING
這樣的設計有何意義?
- 當程式 access 到
LIST_POISONING
時便會發出 page fault 以便確保沒有人會使用到沒有初始化過得 list entry ( 被刪除掉的 )
- 而在
list_del()
中可發現被刪除的 list entry 都會指向 LIST_POISONING
linked list 採用環狀是基於哪些考量?
- 因為 linux 使用 doubly linked list 使用 circular 可以省掉總是需要兩個指標去指向頭和尾的空間,並在操作上也省去這些步驟。
list_for_each_safe
和 list_for_each
的差異在哪?"safe" 在執行時期的影響為何?
for_each 風格的開發方式對程式開發者的影響為何?
程式註解裡頭大量存在 @
符號,這有何意義?你能否應用在後續的程式開發呢?
tests/
目錄底下的 unit test 的作用為何?就軟體工程來說的精神為何?
- 可以看到在 test/ 目錄底下有許多小程式,且幾乎每個裡面皆有使用
assert()
,這時查看 MAKEFILE
發現在 make 的時候便會執行所有的小程式,並測試這些程式能不能正確執行完畢。
- 這些小程式的目的即檢測
list.h
內的 function 能不能正確執行。
- 當我們在撰寫大型專案的時候,常常會寫許多工具函式,如果沒有先確保這些工具函式的正確性,往後向上層設計整個系統的時候便會不知道是在何處出錯,是使用的工具函式的邏輯錯誤還是整個工具函式有問題
- 如果我們能夠先行利用
tests
的手法確認函式的正確性,更能增進往後撰寫程式的效率。
tests/
目錄的 unit test 可如何持續精進和改善呢?
- 參考
rex662624
- 可以增加變異性,並測試一些 boundary condition。或是故意測試一些會出錯的值,看程式碼是否能夠抓到並印出 warning。
針對 linked list 的排序演算法
對 linked list 進行排序的應用場合為何?
- 因 linux 行程管理是使用 linked list 串接,所以假設我們需要查看現在是哪些行程佔用了 cpu,並比較何行程佔的比例最大,就會使用到 linked list 的排序。
考慮到 linked list 在某些場合幾乎都是幾乎排序完成,這樣貿然套用 quick sort 會有什麼問題?如何確保在平均和最差的時間複雜度呢?
-
quick-sort 的時間複雜度,取決於一開始的 pivot 值能否有效的把資料有效切割。因為一般情形下 quick-sort 的 pivot 值通常是取第一個或是最後一個 element,所以如果對已經排序過的資料做 quick-sort,取出的 pivot 就會是最大值或最小值,此情形即為 quick-sort 的 worst-case。
-
如果能在取 pivot 的過程動一些些手腳,使 pivot 不為最大或最小,即能提昇時間複雜度,例如使用 medium-of-mediums 的方法。
能否找出 Linux 核心原始程式碼裡頭,對 linked list 排序的案例?
- 參閱
rex662624
的工具可以直接搜尋 linux 的程式碼
- 輸入指令
path: list_sort.h
可以看到所有使用 list_sort.h 函式庫的程式。
- 總共
28 matches found
透過 skiplist 這樣的變形,能否加速排序?
linux-list 裡頭 examples
裡頭有兩種排序實作 (insertion 和 quick sort),請簡述其原理
- insert-sort 是將資料從第一個 element 插入進一個新的 linked list ( head ),而新的 list 中是已經排序過的資料,並從頭比對資料大小做插入排序,而因為這個過程須走訪每個節點,所以時間複雜度為 。
- quick-sort 是利用 pivot 值將原本的資料序列做分割,然後分割後的 list 再遞迴呼叫 quick-sort 排序。
- 分割過程為將資料和 pivot 比大小,將比 pivot 小的是值搬到 list 頭,將比 pivot 小的值搬到 list 尾。
- 此過程是要確保在 pivot 之前資料都是小於 pivot 的,反之在 pivot 後的資料皆大於 pivot。
- 平均情形:
實作測試程式,批次建立包含若干大小的 linked list,隨機放入數值為介於 1 到 366 之間 (包含) 的節點 (代表 day number) ,至少應該涵蓋 101, 102, 103, … 106 等數量,透過前述的 insert, quick, merge sort 進行排序,分析執行時間並解讀其行為
可以看到 insert-sort 在時間上耗費相當的大,所以之後的比較省略 insert-sort。
可以發現 merge-sort 在資料量大的時候表現比 quick-sort 優異許多。
設計 deduplication 程式,將上述輸入中的數值挑出重複的節點並與刪除,透過統計分析,解讀執行時間分佈,以及探討 data deduplication 的效益