Tuesday, December 31, 2013

What is RabbitMQ and Celery?


key points from Wiki

  • Open source message broker software
  • AMQP (Advanced Message Queuing Protocol)
  • Written in the Erlang Programming Language
  • Built on the Open Telecom Platform framework
words from their official website
Celery is an asynchronous task queue/job queue based on distributed message passing. It is focused on real-time operation, but supports scheduling as well.
The execution units, called tasks, are executed concurrently on a single or more worker servers using multiprocessing, Eventlet, or gavent. Tasks can execute asynchronously (in the background) or synchronously (wait until ready).

Wednesday, November 20, 2013

Install nox-classic on Ubuntu 12.04

It's seems that there are problems if just following the instruction in their wiki page. Try the instructions below if you have problems while installing nox.

Update apt-get download list

  • cd /etc/apt/sources.list.d/
  • sudo wget http://openflowswitch.org/downloads/debian/nox.list
  • sudo apt-get update
  • sudo apt-get install nox-dependencies

Download from Github

  • cd ~
  • apt-get install nox-dependencies libtbb-dev libboost-serialization-dev libboost-all-dev
  • git clone git://github.com/noxrepo/nox
  • cd nox
  • ./boot.sh
  • mkdir build
  • cd build


  • ../configure
  • make
  • sudo make install


  • cd src
  • ./nox_core -i ptcp:6633
  • ./nox_core -v -i ptcp:6633 switch

Monday, November 18, 2013

Setup eCos Development Environment on Ubuntu 12.04 for STM32

Before You Begin

Install Required Tools & Dependencies

  • sudo apt-get install cvs libstdc++5 ia32-libs libglib2.0-dev

Download eCos then Setup

  • wget --passive-ftp ftp://ecos.sourceware.org/pub/ecos/ecos-install.tcl
  • sh ecos-install.tcl
    • choose a faster distribution site, like "[16] ftp://ftp.u-aizu.ac.jp/pub/gnu/cygnus/ecos", which may locate in Japan
    • choose a location to store the downloads, take default /home/<username>/ecos as example in this article
    • select "[1] arm-eabi", which is said in my course assignment instruction; however, I found we don't need this if we have arm-none-eabi (which we've installed already)
  • cd /home/<username>/ecos
  • cvs -z3 -d :pserver:anoncvs@ecos.sourceware.org:/cvs/ecos co -P ecos
  • in file "ecosenv.sh", modify "ECOS_REPOSITORY=/home/<username>/ecos/ecos-3.0/packages ; export ECOS_REPOSITORY" to "ECOS_REPOSITORY=/home/<username>/ecos/ecos/packages ; export ECOS_REPOSITORY"
  • . ecosenv.sh
    • this exports the system PATHs for ecos tools

Create HelloWorld Project

  • cd <somewhere you like to place you project>
  • mkdir ecos_project && cd ecos_project
  • ecosconfig new stm32f4discovery
  • configtool
    • change "eCos HAL->Cortex-M Architecture->Cortex-M3/-M4 STM32 Variant->STMicoelectronics STM32F4-Discovery board HAL->Startup Type" to ROM instead of JTAG
    • this starts an GUI interface, open the "ecos.ecc" file which locates in the folder "stm32f4discovery" just created
    • press "Build" -> "Generate Build Tree"
  • create an hello.c file, like:
#include <stdio.h>
int main(){
  printf("hello ecos!\r\n");

  • arm-none-eabi-gcc -o Hello.elf hello.c -Lecos_install/lib -I ecos_install/include -mcpu=cortex-m4 -mthumb -g -O2 -ffunction-sections -fdata-sections -Ttarget.ld -nostdlib
  • arm-none-eabi-objcopy -O binary -R .sram Hello.elf Hello.bin
    • finally, you got Hello.bin here, and burn it into stm32 by following the instruction in last article using QSTLink2 

Sunday, November 17, 2013

Fast way to Start VM and SSH into it on Mac

Though Mac OS is based on FreeBSD, but still lots of unix-based tools are not as good as those on Linux. And, it turns out people start to use "port", "brew", etc to get the tools they want. However, in my point of view, "port", "brew", etc are still not good as "apt-get" or "yum" since they are not well integrated.

So, I am using VirtualBox with Ubuntu guest. And, I write a simple script to:

  • Start the Ubuntu VM
  • SSH into the machine
  • Save the VM state when finishes SSH
I don't even need the GUI of Ubuntu. Also, the machine saves its state instead of turning off, so I don't have to wait long.

Tuesday, November 12, 2013

Operating System Study - Questions & Answers for Shumin

While I was discussing with Shumin, I found there are few things I don't really sure, so I wrote them down and try to find out the answers here. Since these are part of the discussion, they may be not that formal and precise.

Difference between Emulation & Virtualization

Virtualiztion: 模擬出整套系統真實的環境(包含模擬硬體),ex. VirtualBox。
  • Pros: 被模擬的環境比較真實,容易安裝或測試想跑的程式。
  • Cons: 消耗原本系統較大的資源(就像是你Mac會卡住)。

Emulation: 在原本系統中複製類似的環境,ex. WINE(可以讓你在linux/mac上面裝Windows程式的,很有名)。
  • Pros: 比較便宜、不耗成本的做法。
  • Cons: 不好用,被模擬的程式看到的環境比較差,容易壞、不易當測試環境。

What is "System Call"

  1. 先知道有個東西叫作API,是系統提供使用者的控制系統的方法,printf, read, write, open..都是。
  2. “The system-call interface intercepts function calls in the API and invokes the necessary system calls within the operating system.”
  3. “The intended system returns the status of the system call and any return values.”
Heron: 簡單來說就是system提供一些函式讓user可以call,之後怎麼handle就交給system(OS)去處理。

What is "static"

課本裡說”Thread-Local Storage”(TLS)類似於static,而不同處在於TLS在不同thread中是unique的。
static: "a static variable is a variable that has been allocated statically—whose lifetime or "extent" extends across the entire run of the program” (from Wikipedia) 表示static變數不是一般會動態分配的變數(heap memory)也不是函式呼叫時候的變數(call stack)。
而在C/C++語言中(http://en.wikipedia.org/wiki/Static_(keyword)) ,static變數表示:Lifetime為整份program執行期間、只能被內部(如同一class裡面)看見的變數。

Monday, November 11, 2013

Does the number of Cores = the number of kernel threads?


"Does the number of Cores = the number of kernel threads?"

While we were studying for the midterm of Operating System, few people started to ask this question. It seems that the textbook, "Operating System Concepts (by Abraham Silberschatz, Peter B. Galvin, Greg Gagne)", doesn't explain this clearly enough. Therefore, I started to find out the answer on the internet. Here comes my study.


NO! The maximum number of the kernel threads can up to around 15,000 on a general machine. And, the number of the cores mostly are round 2~4. It means that "one core can run more than 2 kernel threads in the same time", which is called "Hyper-Threading".


Saturday, November 9, 2013

Using Shared Memory for Matrix Multiplication


This is one of the assignment in Operating System course. The deadline is passed already, and I would like to take notes here descripting how I implemented this assignment.

In this assignment, we are ask to calculate the multiplication(matrix C) of two input matrix A and B. A and B is simply defined in n dimension, the are same and looks like:

[ [ 0, 1, ....., n-1],
  [ n, n+1, ...,2n-1],
  [... ,   ......n*n] ]

which mean A[i][j] = B[i][j] = i*n + j.

We are asked to use shared memory for matrix C. And threads are forked in the original process, so that this multiplication can be processed by 2 or 4 processes in the same time, which will showed much faster if using 4 processes. The result we have to show is the sum of matrix C.


To create, attach, detach and release the shared memory, we can apply the following functions:

  • shmget(key, sizeof(unsigned int) * n * n, shmflg)
    • Getting a shared memory ID from the system, you will get the same ID if you are using the same input key, which can be any integer.
  • shmat(shmidC, NULL, 0))
    • By passing the shared memory ID, shmat returns the real address of the shared memory.
  • shmdt(C)
    • After we've done all the things related to the shared memory, we have to detach the shared memory (this should be called before exiting any child process).
  • shmctl(shmidC, IPC_RMID, 0)
    • Release the shared memory. While we're not using the shared memory anymore, it's time to release the memory, so that the operating system won't have to clean up manually.


#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/wait.h>
#include <sys/time.h>

/* Magic Number for Key */
#define MAGIC_NUMBER    1111

/* Global Array for A, B */
unsigned int A[800][800], B[800][800];
unsigned int *C;

/* Function Definitions */
unsigned long long processOne(int n);
unsigned long long processTwo(int n);
unsigned long long processFour(int n);
void initMemory();

/* Global Variables for shared memory ID */
int shmidC;

/* Self-write Functions for Attaching Shared Memories */
unsigned int *attachSharedMemoryC(int n);
void detachSharedMemory();
void detachAndReleaseSharedMemory();

/* Main */
int main() {

    // inits
    unsigned long long sum = 0;
    int n, sec, usec;
    struct timeval start, end;
    printf("Input the matrix dimension: ");
    scanf("%d", &n);


    // 1-partition
    gettimeofday(&start, 0);
    sum = processOne(n);
    gettimeofday(&end, 0);
    sec = end.tv_sec - start.tv_sec;
    usec = end.tv_usec - start.tv_usec;
    printf("Multiplying matrices by 1 process: %f sec\n", sec + (usec/1000000.0));
    printf("Element Sum: %llu\n\n", sum);

    // 2-partition
    gettimeofday(&start, 0);
    sum = processTwo(n);
    gettimeofday(&end, 0);
    sec = end.tv_sec - start.tv_sec;
    usec = end.tv_usec - start.tv_usec;
    printf("Multiplying matrices by 2 processes: %f sec\n", sec + (usec/1000000.0));
    printf("Element Sum: %llu\n\n", sum);

    // 4-partition
    gettimeofday(&start, 0);
    sum = processFour(n);
    gettimeofday(&end, 0);
    sec = end.tv_sec - start.tv_sec;
    usec = end.tv_usec - start.tv_usec;
    printf("Multiplying matrices by 4 processes: %f sec\n", sec + (usec/1000000.0));
    printf("Element Sum: %llu\n\n", sum);

    return 0;

void initMemory(int n){
    int i, j;
    for( i=0 ; i<n ; i++ ){
        for( j=0 ; j<n ; j++ ){
            A[i][j] = B[i][j] = i*n + j;

unsigned long long processOne(int n){
    int i, j, k;
    unsigned long long sum = 0;
    // calculate C
    for( i=0 ; i<n ; i++ ){
        for( j=0 ; j<n ; j++ ){
            unsigned int tc = 0;
            for( k=0 ; k<n ; k++ ){
                tc += (A[i][k] * B[k][j]);
            sum += tc;
    return sum;

unsigned long long processTwo(int n){

    int i, j, k;
    C  = attachSharedMemoryC(n);

    // sum saves here
    unsigned long long sum = 0;

    // fork here
    pid_t pid;
    pid = fork();

    if(pid <0) {
        // if error, fork failed
        fprintf(stderr, "Fork Failed");
    else if(pid == 0){
        // child, and calc the first part, i=0 ~ n/2
        for( i=0 ; i<n/2 ; i++ ){
            for( j=0 ; j<n ; j++ ){
                C[i*n + j] = 0;
                for( k=0 ; k<n ; k++ ){
                    C[i*n + j] += A[i][k] * B[k][j];

    else {
        // parent, i=n/2 ~ n
        for( i=n/2 ; i<n ; i++ ){
            for( j=0 ; j<n ; j++ ){
                C[i*n + j] =0;
                for( k=0 ; k<n ; k++ ){
                    C[i*n + j] += A[i][k] * B[k][j];

        // if parent

        // sum up here
        for( i=0 ; i<n*n ; i++ ) sum += C[i];

    return sum;

unsigned long long processFour(int n){

    int i, j, k;
    unsigned long long sum = 0;
    C  = attachSharedMemoryC(n);

    // fork here
    pid_t pid;
    pid = fork();

    if(pid <0) {
        // if error, fork failed
        fprintf(stderr, "Fork Failed");
    else if(pid == 0){
        // fork here
        pid_t pid2;
        pid2 = fork();

        if(pid2 <0) {
            // if error, fork failed
            fprintf(stderr, "Fork Failed");
        else if(pid2 == 0){
            // child, and calc the first part, i=0 ~ n/2
            for( i=0 ; i<n/2 ; i++ ){
                for( j=0 ; j<n/2 ; j++ ){
                    C[i*n + j] = 0;
                    for( k=0 ; k<n ; k++ ){
                        C[i*n + j] += A[i][k] * B[k][j];

        else {
            // parent, i=n/2 ~ n
            for( i=n/2 ; i<n ; i++ ){
                for( j=0 ; j<n/2 ; j++ ){
                    C[i*n + j] = 0;
                    for( k=0 ; k<n ; k++ ){
                        C[i*n + j] += A[i][k] * B[k][j];

    else {
        // fork here
        pid_t pid3;
        pid3 = fork();

        if(pid3 <0) {
            // if error, fork failed
            fprintf(stderr, "Fork Failed");
        else if(pid3 == 0){
            // child, and calc the first part, i=0 ~ n/2
            for( i=0 ; i<n/2 ; i++ ){
                for( j=n/2 ; j<n ; j++ ){
                    C[i*n + j] = 0;
                    for( k=0 ; k<n ; k++ ){
                        C[i*n + j] += A[i][k] * B[k][j];
        else {
            // parent, i=n/2 ~ n
            for( i=n/2 ; i<n ; i++ ){
                for( j=n/2 ; j<n ; j++ ){
                    C[i*n + j] = 0;
                    for( k=0 ; k<n ; k++ ){
                        C[i*n + j] += A[i][k] * B[k][j];

            // if parent

            // sum up here
            for( i=0 ; i<n*n ; i++ ) sum += C[i];

    return sum;

void detachAndReleaseSharedMemory(){
    if (shmctl(shmidC, IPC_RMID, 0) == -1) {
        fprintf(stderr, "shmctl(IPC_RMID) failed\n");

void detachSharedMemory(){
    if (shmdt(C) == -1) {
        fprintf(stderr, "shmdt failed\n");

unsigned int *attachSharedMemoryC(int n){
    // setup shared memory
    key_t key = MAGIC_NUMBER;
    int shmflg = IPC_CREAT | 0666;

    if((shmidC = shmget(key, sizeof(unsigned int) * n * n, shmflg)) == -1) {
        perror("shmget: shmget failed");

    unsigned int *sC;
    if((sC = shmat(shmidC, NULL, 0)) == (unsigned int*)-1) {
        perror("shmat: attach error");

    return sC;

Friday, November 8, 2013

"Pitch It" is Released

App Site: http://pitchit.nctucs.net/
Apple Store: https://itunes.apple.com/us/app/pitch-it-perfect-pitch-challenge/id736721019?ls=1&mt=8

I've been working on this app, "Pitch It", for around one month. This interesting work is cooperated with Shumin, who has brought out lots of beautiful design and being a great partner.

"Pitch It" is a note guessing game. It plays a music note and ask to the user to tell if he/she can tell which note it is. People define a person who have "absolute pitch" or "perfect pitch" if he/she can answer more than 70% of the questions. With this app, the app can tell if you have "absolute pitch" or not.

On the other hand, this app is fast-implemented. I wanted to see how the Apple Store distribution works. That was a little complicated, and take a long for app reviewing by Apple. There, I write done time when the state is changed of this app on iTunes Connect.
  • Sat, Nov 2, 2013 at 12:38 AM: turned to Waiting For Upload
  • Sat, Nov 2, 2013 at 01:18 AM: turned to Waiting For Review
  • Fri, Nov 8, 2013 at 06:32 AM: turned to In Review
  • Fri, Nov 8, 2013 at 07:58 AM: turned to Processing for App Store
  • Fri, Nov 8, 2013 at 08:45 AM: turned to Ready for Sale
It means that takes 6 days for "Waiting For Review" state, and less than two hours for them to review and release.

Friday, November 1, 2013



若是這一台空的Linux機器安裝Wordpress,沒設定情況下會發現不能上傳相片,出現類似這樣的Error Message:"Unable to create directory wp-content/uploads"。
此問題來自上傳檔案這目標位置權限設定上並不能寫入,而網路上有許多做法是將 wp-content/uploads 改成777之類的,但這樣會變成任何人都可以讀寫,出現不合理的資訊安全問題。



(以環境為Ubuntu 12.04 with Apache為例)
mkdir <Web-root Directory>/wp-contents/uploads 
chgrp www-data <Web-root Directory>/wp-contents/uploads 
chmod 775 <Web-root Directory>/wp-contents/uploads


Thursday, October 17, 2013

Install OpenCV 2.6.4 on Ubuntu 12.04

I can still remember the time I was installing OpenCV library three years ago. It's not easy for the first time to install such a large library onto my own IDE. Knowledges about "Makefiles", system PATH, pkg-config, etc. are required to setup OpenCV. Also, you may also be familiar with your IDF, so that you can find where to fill in the right settings.

Here, take a common environment as example, is the way to install OpenCV 2.6.4 (or any other latest version) on Ubuntu 12.04. This is simple thanks for the script written by jayrambhia.

  1. git clone https://github.com/jayrambhia/Install-OpenCV
  2. cd Install-OpenCV/Ubuntu
  3. chmod +x opencv_latest.sh
  4. ./opencv_latest.sh

These steps ask the machine to download the script from jayrambhia's github, then run the script in it. Remember you may be asked to type in your password in order to run the "sudo" commands. After running the four commands, you'll completely installed OpenCV on your Ubuntu machine.

Sunday, October 13, 2013


There's some notes about "Naming" which I learned from "The Practice of Programming" by Brian W. Kernighan and Rob Pike. It's base on the book "The C Programming Language".
  • use descriptive names for globals, short names for locals
  • local variable
    • i and j for loop indices
    • p and q for pointers
    • s and t for strings
  • Programmers are often encourage to use long variable names regardless of context. This is a mistake: clarity is often achieved through brevity. (清楚與否需要透果簡潔以實現)
  • initial capital letters for Globals, all capitals for CONSTANTS
  • be consistent
  • use active names for functions
    • ex. getTime(), putChat()
    • bool functions: isoctal()
  • be accurate

Wednesday, October 9, 2013

STM32 Development Environment Setup on Ubuntu


During the class in "I/O and Drivers", I learned how to setup the environment on Windows including ARM GCC Tool Chain, GNUmake, and ST-Link Utility so that I can install our own code into the board, STM32.

Back to my home, I don't have any Windows machine. Then, I tried to build the same environment on Ubuntu or Mac OS X, which turned out that it’s much easier to setup the environment on Ubuntu. This report will cover the things I've done in order to install our own program on STM32 using Ubuntu.

Note: I'm using Ubuntu 12.04.

My Environment

  1. install the libraries or other dependencies we need
    • bash> sudo apt-get install build-essential git flex bison libgmp3-dev libmpfr-dev libncurses5-dev libmpc-dev autoconf texinfo libtool libftdi-dev libusb-1.0-0-dev && sudo apt-get build-dep gcc-4.5
  2. install ARM toolchain
  3. add the bin files to system PATH
    • echo 'export PATH=/home/YOUR_USER/sat/bin:$PATH' > ~/.bashrc
  4. install QSTLink2 (this program burns the bin files into the board)
    • install its dependencies: bash> sudo apt-get install qt4-qmake libqt4-dev libqt4-gui libqt4-xml qt4-designer qtcreator libusb-0.1-4 libusb-1.0-0-dev
    • download QSTLink2 source code: http://vedder.se/wp-content/uploads/2012/07/qstlink2.zip
    • unzip QSTLink2 source code
    • install QSTLink2: bash> qmake-qt4 && make && sudo make install && sudo reload udev

Run & Burn the Code

  1. make
  2. open QSTLink2
  3. connect
  4. select bin file
  5. send to the board

Tuesday, October 8, 2013


This post is my class note for 1.2: The Power of Prototyping

Why Prototype

  1. 在短時間內得到feedback
  2. 解決難以預測的情況

Rights for Prototype

  1. 不被要求是具有完整功能的
  2. 容易被修改的
  3. 一定會被換掉

Main Point

"Prototypes are questions, ask lots of them."

Saturday, October 5, 2013

Finite Automata

Few notes from my reading of Introduction to the Theory of Computation chapter 1.1:

Definition of Finite Automaton

A finite automaton is a 5-tuple (Q, Σ, δ, q0, F), where
  1. Q is a finite set called the states,
  2. Σ is a finite set called the alphabet,
  3. δ: Q × Σ → Q is the transition function,
  4. q0 ∈ Q is the start state, and
  5. F ⊆ Q is the set of accept states (final states).

Definition of Regular Language

A language is called a regular language if some finite automaton recognizes it.

Definition of Regular Operatioins

Let A and B be languages. We define the regular operations union, concatenation, and start as follows.
  • Union: A ∪ B = { x | x∈A or x∈B }
  • Concatenation: A ○ B = { xy | x∈A and y∈B }
  • Star: A* = {x1 x2 ... xk | k ≧ 0 and each xi ∈ A}
  • the concatenation operation attaches a string from A in front of a string from B in all possible ways to get the strings in the new language
  • the star operation is a unary operation instead of a binary operation
  • because "any number" includes 0 as a possibility, the empty string ε is always a member of A*, no matter what A is

Friday, October 4, 2013

constraintsWithVisualFormat, the most interesting coding style I've ever seen

WWDC 2012的演講中,介紹了auto layout,相對於其他文件,這關於排版的程式設計透過影片能比較快的學起來,其中最酷的是一個constraintsWithVisualFormat的函式,讓我們感覺到除了在裝置、界面設計上別出心裁的Apple,在開發者這端也有很有趣的設計。

Apple在iOS 5之後的開發平台上提供auto layout的功能,可以在點選storyboard點選某個view後,於右側的選單中開啓這功能(多已經預設),而constraints就是其中最重要的機制,不會複雜,說穿了,constraint就是一個一維線性代數(y = ax + b),裡頭的y和x分別是某個物件中的某個位置或長度,a和b就是個常數,於是乎,auto layout就是透過這些constraints對於物件擺放的敘述而排版,好的敘述會讓版面不論縮放、旋轉後都是好看的。

constraints可以用一般的函式一一輸入 y = ax + b,但是Apple在設計時候可能是發現這樣太麻煩了,一個constraint的函式表示要六、七行以上呢!所以提出Visual Format這樣的東西,是透過視覺化程式碼,對於喜歡ASCII Art的人的一大福音!

以下是WWDC 2012演講簡報中部分的內容,很酷!




Saturday, September 28, 2013


In the course "Formal Language", we learned about "DFA and NFA", and here's my study notes.


Finite Automaton

A finite automaton is a processor that has states and reads input, each input character potentially setting it into another state.
 In my opinion, we can see this as a finite state machine.

Deterministic Finite Automaton (1943)

A finite state machine that accepts/rejects finite strings of symbols and only produces a unique computation (or run) of the automaton for each input string. 'Deterministic' refers to the uniqueness of the computation.
In one state at a time.

Nondeterministic Finite Automaton (1959)

A finite state machine that (1)does not require input symbols for state transitions and (2)is capable of transitioning to zero or two or more states for a given start state and input symbol.
In more than one state at a time.

Difference between DFA and NFA

  • all transitions are uniquely determined
  • an input symbol is required for all state transitions
  • DFAs are easier to understand, but NFAs are generally smaller. 

Sunday, September 22, 2013

Upload File using jQuery-File-Upload

Original Code


My Work

This is cool jQuery library which allows the user to upload their files with cool interface. It also support "drag & drop", so it's much faster for people to select files. However, security may be a big issue in this case.

Problems I Met & How I Solved Them

Error, unable to upload the file

Solving this problem by giving right permission to the folder which the website is going to save files (in the example code, it's ./server/php/files). Make sure that "www-data" is able to "write" the folder.

The thumbnails are not showing up

I directly type in the URL of the thumbnails, and the browser showed a message asked me to read the error log file. In the log file, it says:
Invalid command 'Header', perhaps misspelled or defined by a module not included in the server configuration, referer: http://heron.nctucs.net/upload/index.html
So, here my solution from this website:
ln -sf /etc/apache2/mods-available/headers.load /etc/apache2/mods-enabled/headers.load

Saturday, September 21, 2013


Original Document

Facts (sentences from the paper)

  • In its early days, Facebook ran on a single server that cost $85 a month and had to handle traffic for every Harvard student who used the service.
  • Facebook.com was first coded in PHP, which was perfect for the quick iterations that have since defined our style of product rollouts and release engineering.
  • Facebook has grown to 5,299 employees and 1.15 billion users as of June 2013.
  • Every day, there are more than 4.75 billion content items shared on Facebook, more than 4.5 billion "Likes," and more than 10 billion messages sent. More than 250 billion photos have been uploaded to Facebook, and more than 350 million photos are uploaded every day on average.
  • To build more efficient apps, Facebook is working to solve:
    • Diversity of devices and operating system
    • Geographic diversity
      • 1.15 billion people
      • 70 different languages
    • Network connectivity
      • Testing to ensure consistent network connectivity (Air Traffic Control to simulate different network conditions right inside Facebook' offices)
    • Consuming less data


What I learned

Facebook.com was first complemented using PHP, what we all think it's easy and fast for developing. Then, they started to work very deep into PHP when more people using Facebook. This is new to me, what I thought is that this kind of websites doesn't go really deep into the technology but learning human psychology/business/etc insteads.

Wednesday, August 21, 2013



當航空公司頁面有更新的時候這隻程式便會發出聲音,而我設定的聲音則是「I am a bad feeling about this」,是個從免費網站下載的聲音檔。

import sched, time
import urllib2
import pygame

s = sched.scheduler(time.time, time.sleep)
url = "http://www.china-airlines.com/ch/schedule/cancel.htm"

original_html = ""

def do_something(sc):

    global url, original_html

    # do your stuff
    response = urllib2.urlopen(url)
    html = response.read()

    if cmp(original_html, html):
        print "New!!!"

    sc.enter(2, 1, do_something, (sc,))

def original():
    global original_html
    response = urllib2.urlopen(url)
    original_html = response.read()

def main():


    s.enter(2, 1, do_something, (s,))

if __name__ == "__main__":

Monday, July 1, 2013

Delegate in iOS

My question is "what is delegation?" after writing several iOS programs.

"Delegation is a simple and powerful pattern in which one object in a program acts on behalf of, or in coordination with, another object. The delegating object keeps a reference to the other object - the delegate - and at the appropriate time sends a message to it. The message informs the delegate of an event that the delegating object is about to handle or has just handled. The delegate may respond to the message by updating the appearance or state of itself or other objects in the application, and in some cases it can return a value that affects how an impending event is handled. The main value of delegation is that it allows you easily customize the behavior of several objects in one central object."

Basically, "delegation" is way that one object communicate with the other object.

這網頁中的Example 1是一個很好的範例,講述有兩個object,為brain和beer bottle,brain可以不斷下達指令給beer bottle要喝,但是brain因為要看電視所以太忙沒有辦法知道什麼時候beer被喝完,於是乎,beer bottle此時就要用delegation,當沒有beer時告知brain。

這網頁講述了delegation中物件的關係,若此時物件A call 物件B:

  • A是B的delegate object
  • B會有A的reference
  • A會implement B的delegate method
  • B可以與A communicate,用delegate methods


Sunday, June 30, 2013

Learning VIM (if using Windows)

  1. 安裝gVim http://www.vim.org/download.php#pc
  2. 透過ssh等方式連到一台linux/unix的機器
  3. 使用Cygwin創立linux/unix模擬環境






vim指令設計上其實是非常符合手指位置的(人體工學?)。一般而言,看到一份文件第一個用的指令是向下卷,即是指令 j ,可以使游標往下,而 j 恰好是右手食指位置,不需要移動手指就可以按到,向上的指令 k 則是位居第二名。

而有些則是從名稱的縮寫而來,例如 i 是insertion的縮寫 d 是delete等。


vim非常適合處理反覆的情況,例如,往上的指令是 k ,若希望往上八行,打 8k 即可。
更深入的部分有巨集,使用指令 q ,可以記憶一連串的指令,然後再重複!(寫verilog十分需要)






Real Tutorial這裡:
  1. 基本指令(其實大概80%在用的都出現在此網頁):http://yannesposito.com/Scratch/en/blog/Learn-Vim-Progressively/
  2. Vim Adventure,透過玩遊戲的方式學習vim: http://vim-adventures.com/
  3. Vim Cheat Sheet,圖片方式的指令集: http://www.viemu.com/a_vi_vim_graphical_cheat_sheet_tutorial.html
  4. Complete Tutorial: ftp://ftp.vim.org/pub/vim/doc/book/vimbook-OPL.pdf
// end here

Drupal Installation

Follow the instruction in Drupal tutorial:

However, for the permission setting part, it's not working if I follow the instruction.
During the installation, Drupal may have to do some modifications on the files in sites/default/, they may be modified. So, 'w' is required.

The easiest way to solve the permission issue here is to grant all the permissions and modify them back as soon as the installation is done.

  • chmod 777 settings.php && chmod 777 ../default/
  • process the installation
  • chmod 644 settings.php ^&& chmod 755 ../default/

Sunday, June 23, 2013



#include <cstdio>
#include <vector>

using namespace std;

int main(){

 vector<int> myVector;

 // setter: push new
 myVector.push_back(2); // index = 0
 myVector.push_back(5); // index = 1
 myVector.push_back(1); // index = 2

 // getter: by index
 printf("%d\n", myVector[1]); // 5

 // get size
 int size = myVector.size();
 printf("size = %d\n", size);

 return 0;


std::map是C++中的函式,include <map>之後可以使用。



  1. setter:設定新的項目
  2. getter:取得已存的項目,若不存在會回傳0,並被加入map中
  3. is not found:檢查該key有無存在在map中
  4. wall through:走過所有map中的項目

#include <cstdio>
#include <map>
#include <iostream>

using namespace std;

int main(){

 map<char, int> myMap;
 map<char, int>::const_iterator iter;

 // setter

 // getter
 printf("%d\n", myMap['h']); //2
 printf("%d\n", myMap['e']); //3
 printf("%d\n", myMap['r']); //0, not exist

 // check if exsit
 int isNotFound;
 isNotFound = ( myMap.find('z') == myMap.end() );
 printf("%c\n", (isNotFound)?'y':'n'); // y

 isNotFound = ( myMap.find('e') == myMap.end() );
 printf("%c\n", (isNotFound)?'y':'n'); // n

 // walk through all elements in map
 for(iter = myMap.begin() ; iter != myMap.end() ; iter++)
  printf("- %c:%d\n", iter->first, iter->second);

 return 0;

Thursday, May 16, 2013

Matchismo on iOS

This is the first assignment for the course CS193P at Stanford 2013 winter session. It shows how the "MVC" structure works, and also includes really good coding style in objective-oriented programming.


Some interesting stuffs I would like to share is as below:

  1. Connecting the "View" related events or properties by dragging the object from GUI programming interface to text code. Cool.
  2. NIL pointer design, I've written things about this in last post.
  3. General initialisation design. Objects in objective-C mostly have the some usage in initialisations, setters/getters, function callings, etc. It's easy for the developers to learn some basic examples and apply on different occasions.
  4. Auto-complete editing design in Xcode. Although this feature, auto-complete while typing the code, is not new stuff, it's still the best auto-complete mechanism I've ever seen. It's fast, and smart. It allows you to jump to next blank in a very short time. While writing the program, you spent very little time on typing. Around 80%~90% of the code can be done by the auto-complete function, only the new names for object/function/etc are needed to be typed completely. At last, Xcode also generates those an annoying special characters in the code, like "", [], {}, etc.
Finally, the developing environment for iOS is not only including great designs but also so much fun.