contributed by < Brianpan >
要確認malloc是否成功
移除queue的時候要連所包含的內容一起釋放
所以要使用list_for_each_safe api
插入新元素要考慮是否有成功分配空間
除此之外,這兩者的差別只在list_add, list_add_tail的api使用
一開始使用間接指標去memcpy 發現 case-07過不了
改進後 commit 參考同學的實作改用strncpy去避免這樣的情況
這裡埰用間接的方式去實作,我們把head->prev->prev指標當作q_remove_head的head,
其實就是q_remove_head
我們採用快慢指標的做法,這裡要確認兩個條件
這邊的思路是用兩層迴圈去判定是否需要重複的元素需要刪除,因為已經假定是排序過後的儲列所以重複的會串接在一起,我們我們用兩個指標start, curr去表示這之間的元素是重複的
之後透過dup判定有重複的話就使用list_cut_position去去移除[start, curr]指標之間的元素,值得一題這邊因為是要使用list head當作參數,所以我們要我們要傳入start->prev當作list head
commit
交換採取一個while迴圈確認是否停在倒數第二個元素
並且交換的指標更新是交換後的first指標的next
commit
這邊的思路是元素從第二個開始,我們一直把元素往head指標之後插入
這個就是reverseK當k=2的情況
commit
reverseK的思路則是把reverse的點子延伸,多跑一層while迴圈去分群k個元素的交換
這裡用group_head代表一個分群的head指標
這個實作需要考慮一個情況,當串列的個數是k的倍數,我們必需更新head->prev指標成最後一輪的first指標
思考怎麼用指標的指標優化
commit
這個實作學習使用以下API:
具體作法有參考同學和非連續記憶體講座
具體操作是:
commit
兩個的做法只差在排序上面, 所以實作細節放在同一個函式q_remove_nodes(struct list_head *head, bool descend)
主要思路是從尾部往回看如果是遞減排序代表最後一個一定是最小的,只要前面比它更小的元素就刪除
commit
這裡一開始有點不懂怎麼找到串列的串列,有參考同學的資料後知道是使用
之後就是採取非連續記憶體講座的頭尾合併方法,中間的優化有參考同學的實作
思路是跑兩個迴圈:
外迴圈是合併終止條件end指標是head->next
內迴圈是首尾合併並且利用q_merge實作
至於為什麼是使用end指標則是分奇數偶數個數討論
偶數個數下end指標會跑到最後一個start指標指到的位置
奇數個數下end指標是最中間都沒合併到的元素
目前還有最後一個測試沒有通過
shuffle
Pearson's chi-squared test 能檢驗虛無假說(Null hypothesis),即某特定事件在樣本中觀察到的頻率分佈與特定理論分佈一致,事件必須是互斥且機率為 1。
如果要 shuffle 三個不同的數字,會出現六種可能的結果,彼此是互斥的,且發生機率加起來為 1。那假設 shuffle 是公平的(六種結果發生的機率相同),並遵守 Uniform distribution,那虛無假說為:
接下來透過 Pearson's chi-squared test 來驗證 shuffle 三個數字的頻率是符合 Uniform distribution:
根據測試程式跑出的結果
自由度: 4! - 1 = 23
根據這個網站提供的chi-squre表格
18.41的chi-square值介於為0.9 - 0.1之間也就是p值是介在0.9-0.1
因為p值大於我們假設的顯著水準0.05
所以我們無法拒絕虛無假設
代表這個分佈是平均的
在我們假設為真的情況,實際實驗觀測到這個可能發生的機率,
換句話說當p值越小,我們預期這個狀況發生的情況很小
如果我們觀測的樣本出現p值很小的情況 < 顯著水準
直觀的意義是正確的話出現機率只有p
但是好死不死被我們碰上了
所以可能我們的假設有錯,不然怎麼這麼低的機率都會發生
Any problem in computer science can be solved by another layer of indirection
David Wheeler
可以多加一層實作去解決任何問題
bool run_console(char *infile_name): console進入函式
主要要關注的是cmd_select(): 這裡認為是模擬一個簡單的select, 測試在web模式和cmd模式下
buf_stack->fd都是STDIN_FILENO, 問題來了web模式怎麼把資料寫入buffer的
回頭看do_web, 先透過web_open去完成一個網頁伺服器端的必要操作
socket->bind->listen
緊接著註冊一個回呼函數
For example, the main
loop of this package can only deal with standard input file descriptor
originally. When this callback function is invoked, it allows the main loop
of this package to deal with multiple file descriptors from different input
alongside with the origin feature to deal with the standard input.
簡單來說就是允許從stdin之外的fd去讀取輸入
web_eventmux的函式類型是
這個相當於傳入一個將來要被讀取的buffer
然後伺服器的功能是透過select確認有請求可以被讀取後呼叫accept系統呼叫
接著在web_recv中再呼叫parse_request以rio方式取得輸入內容
最後把結果寫回buffer
之後這個buffer就可以透過linenoise()函式取得內容
達到qtest可以同時接收伺服器請求
論文說明fixed class可以是極端條件的一種
目前根據ttest.c裡面的描述是使用差值的方式動態更新平均
主要呼叫的方式是透過巨集呼叫fixture.c中的test_const的函式,test_const再呼叫doit去執行實際的測試邏輯
目前實作有時跑過有時失敗,可能原因在沒有剔除極端值,因為實驗環境是在lxc虛擬機器或是digital ocean提供的kvm虛擬機中, 同時可能和多個工作競爭資源
得知他的去除極端值是兩個class合在一起看,本來的想法是應該要分成class 0和class 1再個別去除,或許是他假設如果兩個class是constant time 應該是放在同個母體剔除?
實作採取類似原始程式碼的方式,差別在於原始程式用第一輪來計算百分位數,而這裡使用每輪結束後剔除,這樣的缺點是會多跑很多次排序,但是這樣剔除極端值會比只採用一輪好
此外,論文的百分位數公式是使用指數百分位數
代表函數以指數方式成長百分位數越大差距越明顯