Dokuwiki Tips
清除特定頁面 cache
在該頁面網址後面加上
1 | ?purge=true |
clean cache script
1 |
|
使用方式:
1 | $ ./cleanwiki.sh <path of dokuwiki>/data <天數> |
在該頁面網址後面加上
1 | ?purge=true |
1 | #!/bin/bash |
使用方式:
1 | $ ./cleanwiki.sh <path of dokuwiki>/data <天數> |
Eclipse 編輯區預設背景是白色的,對於用慣 vim、console 這種底都黑黑的我來說實在是有點不舒服,理所當然的就要來找找 theme。
發現一個 plugin:Eclipse Color Themes
官網:http://eclipsecolorthemes.org/
update site:http://eclipse-color-theme.github.com/update/
Help → Install New Software 將 update site 加進去,就可以選 Eclipse Color Themes 來裝。
theme 可以到官網抓 EPF 格式,File → Import → Preference 套用。
用 github 可以做到類似遠端備份的功能,類似 svn 的中央 server(但不一樣)。每個 client 在本地端都有完整的 git repository,在 local 就可以做 commit 等操作,而非一定要連到 github。
先到 Github 申請帳號。github 提供免費帳號無上限的 public repository,如果要私人的 Repository 就要付錢囉。
以下操作都是在 Linux 上,在 Windows 上沒特別研究。
看是在哪種 Linux distribution 上,通常可以直接裝套件(Fedora 用 yum
,Ubuntu 用 apt
,Gentoo 用 emerge
,可參考這裡)。
為了方便跟 github 傳輸資料,要設 ssh 的 public/private key:
1 | $ ssh-keygen -t rsa |
產生一組 key,預設放在 ~/.ssh/
。
Enter passphrase 是每次存取這把 key 時要輸入的密碼,有輸入的話每次用 git 指令 access github 都要打一次密碼。
到 github Account Setting 中的 SSH KEYS 增加 key,把剛產生的 public key(預設是 ~/.ssh/id_rsa.pub
)貼上去。
照著網頁按,幾乎只要輸入 repository name 就可以了。
1 | $ cd mygit |
[userid] 是 github 上的帳號。[rep’s name] 是 repository name。
初次下載,在 Git 稱為 clone。
抓自己或其他人的皆可。
1 | $ git clone git@github.com:[userid]/[rep's name].git [local dir name] |
使用兩種不同 protocol clone。
1 | $ git push |
1 | $ git pull |
繼承分為 interface 繼承與 implement 繼承。interface 繼承僅繼承 interface,implementation 部分則由繼承者決定。implement 繼承則連同實作一同繼承。
C++ 語意上用 virtual 區分 base class 希望 derived class 自己定義與不希望 derived class 修改的 function,virtual 為希望 derived class 自行定義,non-virtual 則不希望 derived class 修改。
C++ 在區分 interface 及 implement 繼承上有:
pure virtual function 是為了讓 derived class 繼承 base class 的 interface,而 implementation 則由 derived class 全權處理。當一 class 宣告 pure virtual function 時,代表要求 derived class 必須 implement 這些 pure virtual function(沒寫會 compile error),通常是這個繼承體系所需要的共同性質。
impure virtual function 是為了讓 derived class 繼承 interface 及預設的 implementation。也就是說,derived class 可以自己實作,也可以直接用 base class 的實作。
這有個風險是,因為在 derived class 中並不強迫要寫出 base class 的 impure virtual function,導致在 derived class 應該有自己實作的狀況下,programmer 可能忘記在 derived class 實作。
non-virtual function 主要是為了讓 derived class 繼承 base class 的實作。
雖然語法上 derived class 可 override base class 的 non-virtual function,但語意上的設計不建議 derived class override base class 的 non-virtual function。另外,override virtual function 跟 override non-virtual function 在實際執行上會有不同行為。
non-virtua function 是 static binding。在一個繼承體系中 call non-virtual function 時會直接 call 宣告 type 的 class function。如果 derived class 沒有 override function,則因繼承關係 call 到 base class 的 function。如果 dervied class override function,則會 call 到 derived class 的。
應避免在 constructor 跟 destructor 中 call virtual function,否則容易造成跟預期不符的行為(誤以為可以 call 到 derived class 的 virtual function)。
construct 到 base class 時,C++ 視該 object 為 base class object,derived class 的 virtual function 跟 member 都還沒建出來,所以 call 不到 derived class 的 virtual function。
反過來的 destruct 則是在 derived class destructor 跑完後,derived class 的東西都刪光光了,該 object 就被當作 base class object,所以在 base class destructor 裡 call virtual function 不會 call 到 derived class 的 virtual function。
除了要避免 constructor 跟 destructor call 到 virtual function,也要避免它們 call 的 function 再間接 call 到 virtual function。
不能修改 class non-static member data 也不能 call 其他非 const member function 的 member function。
宣告 function 時在最後面加個 const 的 function,ex:
1 | int GetIndex() const; |
Declaring a member function with the const keyword specifies that the function is a “read-only” function that does not modify the object for which it is called. A constant member function cannot modify any non-static data members or call any member functions that aren’t constant.
compiler 會檢查 const member function 是否有改到 member data、return value 是否為 pointer 或 reference,如果改到 member data 或傳回可以讓外界修改 member data 時 compiler 會 error。可以透過這個特性反向檢查一個原本非 const 的 member function 是否有修改到 member data。
如果要在 const member function 中修改特定 member data,可以在該 member data 的宣告前面加上 mutable。
Read-Write lock 分成用於 read 跟 write 兩種 lock。使用 read lock 表示只會對 resource 做 read-only 的 access,使用 write lock 表示會修改 resource。
當一個 thread 要做 write 時,其他 read-only thread 會被 block 直到 write 做完。
Read-Write lock 適合有較多 read,write 較少但 priority 比較高的時候。
Qt 跟 Read-Write lock 相關的 class:QReadWriteLock、QReadLocker、QWriteLocker
Linux 中 process 結束時系統會回收該 process 使用的大部分 resource,僅留下結束資訊供它的 parent 取得。parent 回收 child process、取得這些資訊後,剩餘的 resource 才會被釋放。如果 parent 沒有回收結束的 child process,child 會變殭屍(zombie),即執行結束了但沒有把 resource 釋放乾淨,會佔用 PID 及一些記憶體空間放 exit status。
parent process 透過 call wait()
回收 child process 並取得 child process 的 exit status。
process 結束分成正常結束(terminate normally)跟不正常結束(terminate abnormally or crash)。
以系統的角度來看,process call exit()
或從 main()
return 算 terminate normally。(實際上從 main()
return 後就會 call exit()
系列 function。)process crash、被 signal 結束或其他狀況算 terminate abnormally。
以程式或 programmer 的角度來看,exit()
的參數為非 0 通常代表有些檢查沒有通過,程式無法繼續完成工作才會在中間 call exit()
。這個狀況是「程式正常結束,但沒有完成該有的運作」,屬於程式執行邏輯上的錯誤,跟 crash 不同。
Linux 中以 exit status code 表示 process 結束時的狀態(它怎麼結束的)。
系統 exit status code 的範圍為 0 至 255。若程式設置超過 255 的 code,會以 mod 256 作為 exit code。
有些 code 已保留給系統使用、有固定意義。一般不建議 programmer 再對這些 code 定義其他意義。系統已保留的 exit code 為:0、1、2、126 ~ 165、255。
在 C/C++ program 中 exit()
的參數值是在 process 正常結束下,讓 programmer 得知「程式階層上」的 exit status,跟系統所使用的 exit status code 相關但不相等。
PHP 的 Unit Test Framework。
Whenever you are tempted to type something into a print statement or a debugger expression, write it as a test instead.
~ Martin Fowler
test 要是 independent。一個 test 的 result 不能 depend 其他 test 的 result。
1 | $ sudo apt-get remove phpunit // 應該是前面有先用 apt-get install 裝了才需要 |
最後兩個指令看起來很好笑,好像是 pear 的 script 有問題。用倒數第三行裝完之後,又會說找不到 PHP_CodeCoverage_Filter::getInstance()
,後來做這兩行就動了。
不能直接用
1 | $ sudo apt-get install phpunit |
不然 run 的時候會該找不到 PHP Code Coverage。
run all tests
1 | $ phpunit |
PHPUnit 在一些系統上會有 header already sent 的錯誤,加 --stderr
可以避免 PHPUnit 把這視為測試錯誤。
執行單一測試,指定某測試檔做測試。
1 | $ phpunit --stderr <test file path> |
failure 是 assertion function fail(要測試的 function 的 output 不符合預期)。以 F 代表。
error 是出現 unexpected exception 或 PHP error。以 E 代表。
為了讓測試是正確且獨立的,要保持執行 test 時環境是乾淨的。在每次執行一個 test method 前會 call setUp()
建立 test 所需要的 object、變數等等。run 完 test method 後會 call tearDown()
清東西。
通常只需 implement tearDown()
,用來 close file、socket 等。
可以用 file system 的 directory structure 達到組合出一個 test suite 的目的。這也是最簡單的方式。:)
建立一 test dir 並建立跟 project dir 中一樣的 directory structure。把 test case source file(就是 test method 的 source code)以相應 project source file 的位置放進去。PHPUnit 會自動 traverse test dir 做 test。
舉例說明:
這是 project directory:
1 | object/ |
這是 test directory:
1 | tests/ |
PHPUnit 會在 test dir(上例的 tests/)底下找 *Test.php 來做測試。
1 | $ phpunit --stderr <test dir path> |
man page 對 condition variable 的說明:
A condition (short for ``condition variable’’) is a synchronization device that allows threads to suspend execution and relinquish the processors until some predicate on shared data is satisfied. The basic operations on conditions are: signal the condition (when the predicate becomes true), and wait for the condition, suspending the thread execution until another thread signals the condition.
讓某些 thread suspend 起來,等某個條件成立才繼續往下執行。而另外有些 thread 則會更動條件中變數的值,並在該條件成立時 “signal condition” 叫起在 wait 的 thread 來執行。
A condition variable must always be associated with a mutex, to avoid the race condition where a thread prepares to wait on a condition variable and another thread signals the condition just before the first thread actually waits on it.
condition variable 必須搭配 mutex,避免 race condition:thread A 在 thread B signal condition 後才 wait 這個 condition variable,這種狀況可能讓 thread A 永遠在 sleep(如果沒有人會再 signal 這個 condition variable)。
如果所有 thread 在 signal condition variable 之前都 lock mutex,就能保證 condition 不會在 thread lock mutex 跟 wait condition variable 之間被 signal。或者說是不會在 check 過 condition 到 call wait function 以前其他 thread 就 signal condition variable。
pthread_cond_signal()
會叫起一個正在 wait condition variable 的 thread 來 run。如果沒有 thread 正在 wait,什麼事都不會發生。
pthread_cond_wait()
會 atomically unlcok mutex 並讓 calling thread wait condition variable(suspend 此 thread,suspend 的 thread 不會使用任何 CPU time)。這兩個動作是 atomically 執行的,不會被打斷。
進入 pthread_cond_wait()
前必須先 lock mutex。而 pthread_cond_wait()
在 return(可以 return 是因為有人 signal condition variable)前,會重新 lock 住 mutex。