昨天晚上在慵懶的狀態下寫今年 Google Code Jam 資格賽。

A 跟 B 很簡單,A 就照著算一下,B 簡單 Greedy,看到過 C 的比例比較低先跳過,看 D 覺得要想一下,可是已經在想睡覺……丟了一次很爛的 algo 上去果然 WA,放棄收工了,只要 B 的 large input 有對也是會過,阿要是沒對就 GG 了!XD

遙想我每次玩 Code Jam 都只有過資格賽……Orz……看今年會不會有鬥志一點,至少兩次時間可以參加的 Round 1 都去玩一下。

貼這種 code 出來好像在丟人現眼

簡單針對 code 檢討一下好了,algo 沒什麼好檢討的,因為寫的兩題太簡單。

  1. 跟 C++ IO 不熟,才會出現很明顯的 copy。還為了 output 七位小數而混雜 printf(),因為我不會調 C++ 的 output format。比賽的時候懶得查直接用最熟的比較快
  2. 變數名稱亂取,不過算了比賽程式不要計較太多 XD

Octopress 的後端就是自己的電腦,有多台電腦時需要在其他電腦再建立 Octopress 的撰寫環境,並且拿 Github 上面的 repos 下來繼續寫。

安裝環境

基本環境:Git for WindowsRubyInstaller 1.9.3Ruby Development kit。如果用到 code highlight,要裝 Python 2,否則 rake generate 會生出空白頁。安裝完 Ruby 跟 Python 要在環境變數 PATH 加入 Ruby 的 bin 資料夾路徑以及 Python 的安裝路徑,如 C:\Ruby193\binC:\Python27

Clone repository

1
2
3
4
$ git clone -b source https://github.com/[username]/[username].github.io octopress

$ cd octopress
$ git clone https://github.com/[username]/[username].github.io _deploy

Octopress 將 master branch 放在 _deploy/

Rake installation and configuration

1
2
3
$ gem install bundler
$ bundle install
$ rake setup_github_pages

最後一個指令會要求輸入 Github 的 repository URL。

Pull repository

有多台電腦編輯時,開始前要記得將 local repository 更新到最新。

1
2
3
$ git pull origin source
$ cd _deploy
$ git pull origin master

Ref

用想放空的假期把寫在 Dokuwiki 上的筆記搬到 Octopress 來。原本因為可以自己任意編排,加上寫給自己看的筆記是用 Dokuwiki,就繼續沿用 Dokuwiki。漸漸發現要找資料的時候都直接用搜尋功能,沒怎麼在用原本的分類頁。越來越覺得那樣編排可能沒有必要,似乎有搜尋跟標籤就可以了。

好一陣子前 survey 過 Octopress,當時好像因為不習慣網頁上沒有管理的功能,暫且不用。可能最近有點轉性,覺得網頁上沒管理功能好像也還好。本來就喜歡用 Notepad++ 寫東西,配合 Git Bash 讓我覺得在 Windows 上用 command line 沒那麼卡,再加上有 Github 可以放,乾脆搬來了。

目前讓我比較困擾的是這 blog 的 repos 只有在我的桌機上,所以只能從桌機寫,之後要看怎麼在另一台電腦上建立同樣的環境。這是網頁不直接提供管理功能的缺點,可是我在用的電腦就那幾台,也不太可能用手機寫這類的文章,只要幾個環境架起來之後應該還好。

這 blog 主要拿來放 Computer Science 的筆記,之後慢慢寫些小程式應該也會把相關的東西放上來吧。

一邊搬筆記一邊稍微看一下,真心覺得我有些用句很怪,看起來有點像英文文法的中文。XD

清除特定頁面 cache

在該頁面網址後面加上

1
?purge=true

clean cache script

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/bash

cleanup() {
# $1 ... full path to data directory of wiki
# $2 ... number of days after which old files are to be removed

# purge files older than $2 days from attic and media_attic (old revisions)
find "$1"/{media_,}attic/ -type f -mtime +$2 -print0 | xargs -0r rm -f

# remove stale lock files (files which are 1-2 days old)
find "$1"/locks/ -name '*.lock' -type f -mtime +1 -print0 | xargs -0r rm -f

# remove empty directories
find "$1"/{attic,cache,index,locks,media,media_attic,media_meta,meta,pages,tmp}/ \
-mindepth 1 -type d -empty -print0 | xargs -0r rmdir

# remove files older than $2 days from the cache
find "$1"/cache/?/ -type f -mtime +$2 -print0 | xargs -0r rm -f
}

使用方式:

1
$ ./cleanwiki.sh <path of dokuwiki>/data <天數>

Ref

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 上沒特別研究。

安裝 git

看是在哪種 Linux distribution 上,通常可以直接裝套件(Fedora 用 yum,Ubuntu 用 apt,Gentoo 用 emerge,可參考這裡)。

設定 ssh key

為了方便跟 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)貼上去。

在 github 新增 repository

照著網頁按,幾乎只要輸入 repository name 就可以了。

將現有的 git repository 上傳(push)至 github

1
2
3
$ cd mygit
$ git remote add origin git@github.com:[userid]/[rep's name].git
$ git push origin master

[userid] 是 github 上的帳號。[rep’s name] 是 repository name。

下載(clone)github 上的 repository 到 local 端

初次下載,在 Git 稱為 clone。

抓自己或其他人的皆可。

1
2
$ git clone git@github.com:[userid]/[rep's name].git [local dir name]
$ git clone https://github.com/[userid]/[rep's name].git [local dir name]

使用兩種不同 protocol clone。

將自己的修改傳上 github

1
$ git push

將 github 上較新的 code 抓下來

1
$ git pull

Ref

繼承分為 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
  • impure virtual function
  • non-virtual function

C++ virtual and inheritance

pure virtual function

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

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

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 的。

Ref

  • 《Effective C++》Differentiate between inheritance of interface and inheritance of implementation.

應避免在 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。

Ref

不能修改 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。

Ref

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