高見龍

iOS app/Ruby/Rails Developer & Instructor, 喜愛非主流的新玩具 :)

用Backup來備份你的網站

image

一直以來備份這種事就是多做沒事,少做就會出事情。有一套很棒的 gem 叫做Backup,可以來完成一些本來也許要用 shell script 才能做的事情(我對 shell script 相當苦手!),而且語法還很好寫、很漂亮。

也許大家看到 gem 就覺得這是 Ruby 吧,其實這跟你寫不寫 Ruby 或 Rails 沒太大關係,這真的是個很方便的工具,推薦大家玩看看!

其實 Backup 這個 gem 不只能備份資料庫,不過我比較需要的是就是資料庫的備份,所以特別把它筆記下來,至於其它的用法可參考官方的使用說明。

安裝

安裝Backup:

> gem install backup

安裝完成後,執行 backup:

> backup generate
Generated configuration file in '/Users/eddie/Backup/config.rb'

它會在你帳號的根目錄底下建立一個Backup資料夾,並產生一個空的config.rb。另外你還可以給它一些參數,例如:

> backup generate --databases='mysql' --storages='s3' --compressors='gzip'
Generated configuration file in '/Users/eddie/Backup/config.rb'

它會幫忙產生好一些空的 block 讓你可以改來用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#檔案:config.rb

Backup::Model.new(:eddie_blog, 'Eddie Blog DB') do

  database MySQL do |db|
    db.name               = "eddie_blog" # 你要備份的資料庫
    db.username           = "eddie_blog_user" # 資料庫登入帳號
    db.password           = "eddie_blog_password" # 資料庫登入密碼
    db.host               = "localhost"
    db.port               = 3306
    db.socket             = "/tmp/mysql.sock"
    db.skip_tables        = ['skip', 'these', 'tables'] # 哪些table不要備份的
    db.only_tables        = ['only', 'these' 'tables']  #只要備份指定的table
    db.utility_path       = "/opt/local/lib/mysql5/bin/mysqldump" # 如果你的電腦找不到mysqldump的話,才需要另外設定utility_path
    db.additional_options = ['--quick', '--single-transaction']
  end

  store_with S3 do |s3|
    s3.access_key_id      = 'my_access_key_id'
    s3.secret_access_key  = 'my_secret_access_key'
    s3.region             = 'ap-northeast-1'  # 因為我的S3 bucket是開在Tokyo,所以改這樣
    s3.bucket             = 'backup-eddie' # 我在S3上開了一個專門放備份的bucket
    s3.path               = '/databases/blog.eddie.com.tw' # 備份存放的路徑
    s3.keep               = 20  # 要保留多少個檔案,超過的話舊的就會被清掉
  end

  compress_with Gzip do |compression|
    compression.best = true
    compression.fast = false
  end

end

以上設定請依你的環境進行修改,語法應該相當簡單易懂,接著開始來進行備份:

> backup perform -t eddie_blog
[2011/05/24 05:24:27][message] Performing backup for Eddie Blog!
[2011/05/24 05:24:27][message] Backup::Database::MySQL started dumping and archiving "eddie_blog".
[2011/05/24 05:24:27][message] Backup started packaging everything to a single archive file.
[2011/05/24 05:24:27][message] Backup::Compressor::Gzip started compressing the archive.
[2011/05/24 05:24:37][message] Backup::Storage::S3 started transferring "2011.05.24.05.24.26.eddie_blog.tar.gz".
[2011/05/24 05:24:43][message] Backup started cleaning up the temporary files.

要注意的是,你在執行這段的時候可能會出現錯誤訊息,告訴你缺裝了什麼gem,它會很貼心的自動幫你安裝需要的gem,如果你權限不足,那就加個sudo吧。

這樣就完成了!

備份通知

除了備份到S3之外,還有別的像是FTP、SCP、RSync等方案,而且Backup這套gem還可以設定notifier,例如可以在備份完成後發Email通知或是自動丟到Twitter通知 (可參考 Notifiers的說明)。不過我個人不喜歡收一堆的信件通知,也不想讓備份這種雜事去洗 twitter,剛好在 Storage 裡有個 Dropbox 可以用,備份完成我同時也會收到 dropbox 的通知,我要備份的檔案都不大,所以 dropbox 對我來說是個不錯的方案。

改寫如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#檔案:config.rb
Backup::Model.new(:eddie_blog, 'Eddie Blog DB') do

  database MySQL do |db|
    db.name               = "eddie_blog" # 你要備份的資料庫
    db.username           = "eddie_blog_user" # 資料庫登入帳號
    db.password           = "eddie_blog_password" # 資料庫登入密碼
    db.host               = "localhost"
    db.port               = 3306
    db.socket             = "/tmp/mysql.sock"
    db.skip_tables        = ['skip', 'these', 'tables'] # 哪些table不要備份的
    db.only_tables        = ['only', 'these' 'tables']  #只要備份指定的table
    db.utility_path       = "/opt/local/lib/mysql5/bin/mysqldump" # 如果你的電腦找不到mysqldump的話,才需要另外設定utility_path
    db.additional_options = ['--quick', '--single-transaction']
  end

  store_with S3 do |s3|
    s3.access_key_id      = 'my_access_key_id'
    s3.secret_access_key  = 'my_secret_access_key'
    s3.region             = 'ap-northeast-1'  # 因為我的S3 bucket是開在Tokyo,所以改這樣
    s3.bucket             = 'backup-eddie' # 我在S3上開了一個專門放備份的bucket
    s3.path               = '/databases/blog.eddie.com.tw' # 備份存放的路徑
    s3.keep               = 20  # 要保留多少個檔案,超過的話舊的就會被清掉
  end

  store_with Dropbox do |db|
    db.email      = 'my@email.com' # dropbox登入帳號
    db.password   = 'my_dropbox_password'  # dropbox登入密碼
    db.api_key    = 'my_api_key'
    db.api_secret = 'my_api_secret'
    db.timeout    = 300
    db.path       = '/Backups/Databases'
    db.keep       = 20
  end

  compress_with Gzip do |compression|
    compression.best = true
    compression.fast = false
  end

end

這裡用到的api跟secret可到dropbox的開發者網站免費申請來用。寫好之後再執行一次備份,這次就除了備份到S3之外,也會另外備一份到Dropbox:

> backup perform -t eddie_blog
[2011/05/24 05:35:19][message] Performing backup for Eddie Blog!
[2011/05/24 05:35:19][message] Backup::Database::MySQL started dumping and archiving "eddie_blog".
[2011/05/24 05:35:19][message] Backup started packaging everything to a single archive file.
[2011/05/24 05:35:19][message] Backup::Compressor::Gzip started compressing the archive.
[2011/05/24 05:35:20][message] Backup::Storage::Dropbox started transferring "2011.05.24.05.35.18.eddie_blog.tar.gz".
[2011/05/24 05:35:30][message] Backup::Storage::S3 started transferring "2011.05.24.05.35.18.eddie_blog.tar.gz".
[2011/05/24 05:35:36][message] Backup started cleaning up the temporary files.

備份成功,而且還有個漂亮的提示視窗!

image

加入其它備份工作

那如果要再加其它的備份進來怎麼做? 就照著第一段的寫:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#檔案:config.rb

# 原來的
Backup::Model.new(:eddie_blog, 'Eddie Blog DB') do

  database MySQL do |db|
    db.name               = "eddie_blog" # 你要備份的資料庫
    db.username           = "eddie_blog_user" # 資料庫登入帳號
    db.password           = "eddie_blog_password" # 資料庫登入密碼
    db.host               = "localhost"
    db.port               = 3306
    db.socket             = "/tmp/mysql.sock"
    db.skip_tables        = ['skip', 'these', 'tables'] # 哪些table不要備份的
    db.only_tables        = ['only', 'these' 'tables']  #只要備份指定的table
    db.utility_path       = "/opt/local/lib/mysql5/bin/mysqldump" # 如果你的電腦找不到mysqldump的話,才需要另外設定utility_path
    db.additional_options = ['--quick', '--single-transaction']
  end

  store_with S3 do |s3|
    s3.access_key_id      = 'my_access_key_id'
    s3.secret_access_key  = 'my_secret_access_key'
    s3.region             = 'ap-northeast-1'  # 因為我的S3 bucket是開在Tokyo,所以改這樣
    s3.bucket             = 'backup-eddie' # 我在S3上開了一個專門放備份的bucket
    s3.path               = '/databases/blog.eddie.com.tw' # 備份存放的路徑
    s3.keep               = 20  # 要保留多少個檔案,超過的話舊的就會被清掉
  end

  store_with Dropbox do |db|
    db.email      = 'my@email.com' # dropbox登入帳號
    db.password   = 'my_password'  # dropbox登入密碼
    db.api_key    = 'my_api_key'
    db.api_secret = 'my_api_secret'
    db.timeout    = 300
    db.path       = '/Backups/Databases'
    db.keep       = 20
  end

  compress_with Gzip do |compression|
    compression.best = true
    compression.fast = false
  end

end

# 另一個
Backup::Model.new(:my_superdb, 'Another Super DB') do

  database MySQL do |db|
    db.name               = "my_superdb" # 你要備份的資料庫
    db.username           = "my_superdb_user" # 資料庫登入帳號
    db.password           = "my_superdb_password" # 資料庫登入密碼
    db.host               = "localhost"
    db.port               = 3306
    db.socket             = "/tmp/mysql.sock"
    db.skip_tables        = ['skip', 'these', 'tables'] # 哪些table不要備份的
    db.only_tables        = ['only', 'these' 'tables']  #只要備份指定的table
    db.utility_path       = "/opt/local/lib/mysql5/bin/mysqldump" # 如果你的電腦找不到mysqldump的話,才需要另外設定utility_path
    db.additional_options = ['--quick', '--single-transaction']
  end

  store_with S3 do |s3|
    s3.access_key_id      = 'my_access_key_id'
    s3.secret_access_key  = 'my_secret_access_key'
    s3.region             = 'ap-northeast-1'  # 因為我的S3 bucket是開在Tokyo,所以改這樣
    s3.bucket             = 'backup-eddie' # 我在S3上開了一個專門放備份的bucket
    s3.path               = '/databases/blog.eddie.com.tw' # 備份存放的路徑
    s3.keep               = 20  # 要保留多少個檔案,超過的話舊的就會被清掉
  end

  store_with Dropbox do |db|
    db.email      = 'my@email.com' # dropbox登入帳號
    db.password   = 'my_password'  # dropbox登入密碼
    db.api_key    = 'my_api_key'
    db.api_secret = 'my_api_secret'
    db.timeout    = 300
    db.path       = '/Backups/Databases'
    db.keep       = 20
  end

  compress_with Gzip do |compression|
    compression.best = true
    compression.fast = false
  end

end

看到這裡我就覺得有點痛苦了,太多重複的東西,沒把它抽出來另外寫就整個很濕很難受(not DRY)。所以我把一些相關的設定抽出來寫在另外的檔案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#檔案:backup-defaults.rb

Backup::Configuration::Storage::S3.defaults do |s3|
    s3.access_key_id      = 'my_access_key_id'
    s3.secret_access_key  = 'my_secret_access_key'
    s3.region             = 'ap-northeast-1'  # 因為我的S3 bucket是開在Tokyo,所以改這樣
    s3.bucket             = 'backup-eddie' # 我在S3上開了一個專門放備份的bucket
    s3.path               = '/databases/blog.eddie.com.tw' # 備份存放的路徑
    s3.keep               = 20  # 要保留多少個檔案,超過的話舊的就會被清掉
end

Backup::Configuration::Storage::Dropbox.defaults do |dropbox|
    dropbox.email      = 'my@email.com' # dropbox登入帳號
    dropbox.password   = 'my_password'  # dropbox登入密碼
    dropbox.api_key    = 'my_api_key'
    dropbox.api_secret = 'my_api_secret'
    dropbox.timeout    = 300
    dropbox.path       = '/Backups/Databases'
    dropbox.keep       = 20
end

Backup::Configuration::Database::MySQL.defaults do |mysql|
    mysql.host               = "localhost"
    mysql.port               = 3306
    mysql.utility_path       = "/opt/local/lib/mysql5/bin/mysqldump" # 如果你的電腦找不到mysqldump的話,才需要另外設定utility_path
    mysql.additional_options = ['--quick', '--single-transaction']
end

Backup::Configuration::Compressor::Gzip.defaults do |compressor|
    compressor.best = true
    compressor.fast = false
end

所以原來的設定檔就可以變成:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# 檔案:config.rb

require 'backup-defaults'

Backup::Model.new(:eddie_blog, 'Eddie Blog') do

  compress_with Gzip

  store_with Dropbox
  store_with S3 do |s3|
    s3.path = '/databases/blog.eddie.com.tw'
  end

  database MySQL do |db|
    db.name               = "my_superdb" # 你要備份的資料庫
    db.username           = "my_superdb_user" # 資料庫登入帳號
    db.password           = "my_superdb_password" # 資料庫登入密碼
  end

end

Backup::Model.new(:my_superdb, 'Another Super DB') do

  compress_with Gzip

  store_with Dropbox
  store_with S3 do |s3|
    s3.path = '/databases/blog.eddie.com.tw'
  end

  database MySQL do |db|
    db.name               = "my_superdb" # 你要備份的資料庫
    db.username           = "my_superdb_user" # 資料庫登入帳號
    db.password           = "my_superdb_password" # 資料庫登入密碼
  end

end

乾淨多了!

如果你不介意S3的存放路徑的話,也可以把s3.path寫回defaults值裡,程式碼可以更短。

自動備份

確定整個備份沒問題之後,再來要怎麼把它設定為自動備份? 如果你知道怎麼寫cronjob的話那就直接開起來寫。官網有建議另一套gem叫做whenever,這是一套很棒的gem,能做滿多事情的,不過這裡我們只用它來簡單的執行一個指令而已。

安裝請參考whenever的github project。建一個config資料夾準備放設定檔(其實自己手動建也行,反正它幫你產生的也是空白的):

> wheneverize .
[add] writing `./config/schedule.rb'
[done] wheneverized!

編輯設定檔:

1
2
3
4
5
#檔案 config/schedule.rb

every 12.hours do
  command "backup perform -t eddie_blog"
end

更新到cronjob裡:

> whenever --update-crontab
[write] crontab file updated

看一下cronjob:

> crontab -e
# Begin Whenever generated tasks for: /home/eddie/Backup/config/schedule.rb
0 0,12 * * * /bin/bash -l -c 'backup perform -t eddie_blog'

它設定在每天的0點及12點的時候會進行備份的工作。

打完,收工!

結論

有人會懷疑像這種S3或Dropbox的備份安全性如何? 會不會被其它人或是雲端主機自己內部的員工看到你的檔案?

對我來說,我要備份的檔案都不會太機密,我要的只是萬一出問題,可以找得到檔案來快速還原,有真正重要的我會另外找方案處理。我想這些雲端主機的安全性應該是不會太差,但如果你信不過它,而且要備份的東西是非常極機密,萬一外流就有人會死的那種,那你也許可以試著把Storage的地方改成SCP或SFTP之類的,把檔案備到你的機器上囉。

最後,感謝神人們寫出這麼方便的gem,讓我睡覺可以睡得更安穩一些了!

參考資料:

補充:

2011.5.27 我用whenever的時候發現cronjob沒辦法正常執行,在/var/log/syslog裡會出現”failed with exit status 127″的錯誤訊息(OS: Ubuntu),似乎是找不到執行的執令的關係,不知道是哪邊環境沒設定好,不過我後來手動把crontab修改成:

0 0,12 * * * /bin/bash -l -c '/usr/local/bin/backup perform -t eddie_blog'

把backup改成完整路徑就ok了!

Users in my blog

今天從Google Analytics翻了一些我自己這個小blog的數字出來看:

image

雖然僅列出前10名,但看到IE只剩2%多,感覺真好!

image

從前10名的數字來看螢幕解析度的話,大家的螢幕都越來越大,1024×768以下的都快消失了,也許以後設計網站的時候可以有更大的發揮空間了。

不過因為這只是個小小小站,樣本數不多(小於一萬),而且也不是很平民化的內容,所以應該會有滿大的偏差,僅供參考。

關於AS讀書會

image

昨天是第四回的AS讀書會,沒想到竟然能辦到第四回,真的太感謝大家的支持,到目前為止,每回的報名人數都一直在90~110人之間,比我想像的多很多。

沒關係,人多也有人多的玩法。

其實我沒特別跟大家說明,不過如果大家有注意到的話,每次上台分享的講者,我會刻意安排一位前輩搭配相對比較不那麼老鳥的新鳥。老鳥們通常有豐富的業界或講課的經驗,通常可以給我們帶來很完整的演出,而新鳥雖然也許講話會緊張,或可能會有些小狀況,但也常帶來一些”原來可以這樣玩”的新想法。

image

上台表演跟坐在底下聽,真的是完全兩個不同的世界

會這樣安排的原因是我想讓新鳥也有磨練的舞台,希望讓他們有一天也變成老鳥,然後再來提攜新的新鳥,這樣循環下去。我真心的希望可以藉由這樣的形式來達到另一種的“人人有功練”的理想,所以每次在向老鳥取經的同時,若新鳥們在表演時有些小的狀況的話,也還請各位多多包涵。

如果你也想上台分享心得,或是對某個主題/神人有興趣的,請別客氣的跟我說,狀況許可的話我再來幫忙橋時間。

我想這樣的聚會除了聽大家心得分享之外,會中、會後的時間,同好交流才是我覺得最重要的。我看到大家在休息時間大多不會只是坐在椅子上休息,而會起來找人聊天,這樣很棒!

image

你也想認識高手神人們嗎? 下次別害羞,名片拿上手,上前去說聲「您好,我是XXX,久仰大名..」,別擔心碰壁,這些高手神人們都很nice的。

而辦這個聚會對我個人我有什麼好處? 其實我賺很大:

  • 講話似乎有比較不會抖,人也比較不會晃、也不會飄來飄去
  • 見識到老鳥們是怎麼”表演”的
  • 學到不少辦活動的眉角,例如橋人、橋時間、橋場地等..

這些經驗值都不是花錢去上課就學得到的,我真的賺到了!!

最後

  • 只要大家願意繼續支持,我們就讓這個聚會繼續辦下去。
  • 希望可以在一年內辦超過12場次。
  • 誠徵願意跟大家分享心得的講者。

若有任何建議或想法,請別客氣的讓我知道。

感謝大家的支持!

Learning Something New

image

最近寫不太出技術相關的東西,那就來個比較閒聊(嘴砲)性質的主題吧!

在第三回的AS讀書會上,maso兄的talk裡的第一張投影片寫著:

“人活得好好的,幹嘛寫app?”

當下我也覺得,真的,人活得好好的,幹嘛找一些自己不熟的新東西來砸自己的腳?

AS2寫得好好的,幹嘛要學什麼AS3? Flash寫得好好的,幹嘛要寫什麼iOS app? PHP寫得好好的,幹嘛要學什麼Ruby/Rails?

在PTT的Flash板,偶爾會有一些類似「我該學AS3嗎」的主題。當然這樣的主題還是有少數保守派的板友會建議學AS2就夠用啦,幹嘛學AS3? 我承認新的東西不一定就比較好,但當看到越來越多的lib都只做給AS3的時候,也應該要知道整個環境的是往哪邊走了。

Rails 3.1將把CoffeeScriptSass加入變成預設支援;Adobe AIR的效能越來越好,也許在不久的將來用來寫行動app還滿有搞頭的;聽說GAE也開始支援Go了..或語有人對新東西會反抗或害怕,但新的東西一直在一出來,世界一直在進步,抗拒前進的人等於是在退步的. 當你遇到新的問題的時候,雖然用舊的解決方法不見得差,但說不定新的解決可以更簡單、省力。

又剛好在某個國外的研討會上,學到了polyglot這個單字,在wikipedia上翻到的解釋是:

“Polyglot (person), someone who uses many languages”

想想其實寫程式的工程師挺苦命的,為了糊口飯吃,除了基本的中、英文外,還得學各式各樣的程式語言。

我認為的”學新東西”不是指電腦程式語言,而是指學習新東西的心態。學習本身有人覺得苦也有人覺得樂,有可能你的老闆發現最近寫水果app好像可以賺很大,所以也要求你去學會它來幫公司賺錢,這也許會有點苦;對我來說,我沒辦法一直用同一招闖江湖,不學新東西來刺激一下我會死,所以對我來說是樂遠大於苦。而且我又是個愛現的人,每當在學習的過程中有新的領悟的時候,那種高潮的感覺如果只有自己爽,是會得內傷的。引用朋友Jace在噗浪上的一段話

“分享技術的目的,在於想讓大家都能感受到自己在瞭解一個新知識的那份感動...”

不吐不快,差不多就是這個心境。

也許有人看了TIOBE的排行,會擔心是不是自己所學的東西已經不流行了、過時了。我倒是不會擔心這個問題,任何一門程式語言被發明一定都有它的原因。

知名的Rubyist Aaron Patterson在某次的Ruby Conference上也提到:

“no language is perfect, every great tool has it’s dark-side”

這世上沒有所謂的最強的程式語言,只有最適合的程式語言。

好處?

學新東西有什麼好處?

你不知道你什麼時候會用到它

我自己的故事是,記得剛退伍的第一份工作是寫ASP的,但剛好公司某台重要的主機的作業系統是Linux,在我到職的第一天就發生主機硬碟空間不夠的情形。但因為同事們大多較熟悉微軟的作業系統,對於發生的狀況不太知道該怎麼做。其實我只用了簡單的tar指令,把一些過期但又不能刪掉的檔案給壓縮起來,並把這些動作寫成某個shell script並排到cronjob裡,問題就暫時解決了,當下也給主管不錯的印象。

當你學了不同的程式語言之後,可以同時也學到不同流派的想法

雖然程式語言免不了就是if..else.., for loop, while loop之類的東西,但在使用者的”文化”上就有不同的設計哲學。例如在Ruby裡有Enumerator#each可以用,for跟while就變得很少用或幾乎不用。雖然method後面的小括號可有可無,但大部份的ruby code都是把它省略掉的。

Python的程式碼強制縮排來取代大括號,讓程式碼看起來比較有一致性。如果你對Python有興趣,也可以進到interpreter裡輸入import this就可以看到The Zen of Python

Perl則是”TIMTOWTDI”(There is more than one way to do it)。

每個生態圈都有自己的文化,就跟小時候做的生物觀察的科學實驗一樣,觀察各個生態圈是很有趣的。

跟著趨勢走,對自己的飯碗也許也是另一種保障

時代會變、技術會變,沒人知道明天會流行什麼。

習慣新的東西,也會比較習慣新的狀況

簡單的說,你手上可以運用的籌碼越多,當遇到問題的時候就有更多種的解決辦法。

更有自信

承上,你會知道遇到狀況的時候該用哪種工具來處理是最快最簡單的,可以把事情做得又快又好,自信心就會慢慢的建立起來了。

有”活著”的感覺

古語說得好:「滾石不生苔」呀

也許本來已經熟悉的A,有可能會因為學會了B之後發現原來之前在A那邊有更好的解法

不同的語言帶來不同的思維,也許本來卡關很久的,用了別的思考方式一下子就解出來了。

有困難?

好啦,用講的誰都會,但做起來就是有困難,為什麼?

上班趕公司、客戶的案子做不完,下班之後都很累了..

下班後得帶小孩

的確,這個我不否認,照顧小朋友的確花了我相當多的時間,我幾乎得在小朋友晚上睡著之後才有自己的時間。

不是資訊相關科系的..

放心,我也不是。不過這不用太擔心,老實說,除了少部份的天才外,大部份的人透過練習是可以把一門技術給學得不錯的。

如何開始?

那該從哪邊著手? 以下是一些建議:

上課

我不是很鼓勵別人去補習班的,不過有的人就是沒人教就是學不會,那也許可以去試試無妨。

參加讀書會/社群聚會/研討會

你可能可以在這裡找到同好,有同好一起學習是件樂事,而且近來實體的聚會越來越熱絡,樂見其成。

要讀書

不讀書會面目可憎,我已經在胖了,再面目可憎下去就不能看了..雖然現在網路上的資料已經多到看不完了,但書本還是提供比較完整的學習結構。我習慣隨身都會帶一、二本書,也許在等車、等人的時間太無聊,可以拿出來打發時間。託iPad的福,現在可以一口氣帶很多本了。

寫blog

寫文章可以練習自己的表達能力、組織能力,可以讓自己學習過的東西透過整理變得印象更深刻。別擔心自己寫錯怕被高手電,其實高手都很忙,願意電你是你的福氣。又或許你會想現在大家都嘛在玩facebook/twitter/plurk了,誰還在寫blog那種過時的玩意? 那你可以參考這篇。 (我剛發現原來我的第一篇blog文字是在2005年1月的時候,在安裝phpMyAdmin遇到的問題)

在Ruby/Rails圈應該很多人聽過Gregg Pollack,不久前在他的一篇blog也寫到”Looking for a Mentor“,像Gregg這麼厲害的角色也還是一直不斷的在想辦法進步,我這種小角色怎麼能不努力呢?

當然,學習新東西也不是完全沒問題,在學習的過程中,有幾點可能要注意的:

  • 不要興趣太廣泛,把東西學到一定程度之後要換再換,不然最後”樣樣通、樣樣鬆”的機會很大。
  • 當你學了某種程式語言之後,你可能就會把它當做你手中的鐵槌,但千萬不要把遇到的問題都當成釘子,不然就失去了學新東西的意義了。

我的偏方

最後提供我自己的一些個人的學習偏方,不一定適合你,僅供參考:

找些硬的東西來啃

最近我試著在睡覺前把API拿出來啃,還滿助眠的。我現在儘量把它列為我目前每天睡覺前、起床後的工作之一,因為我覺得那是最基本的東西。不一定要熟記,但至少遇到問題的時候,你腦袋裡有關鍵字可以很快的找到答案。拜ipad所賜,可以讓我躺著看到自然睡著。另外拿別人寫好的原始程式碼來讀也不錯,很多高手寫的東西是書上不會教的,常會有「喔! 原來這個可以這樣寫」的體悟。

聽Podcast、廣播練英聽

我一直覺得自己的英文能力不夠,我會開英國BBC電台的廣播起來練聽力,部份聽不懂是難免的,但就讓自己的耳朵跟腦袋習慣這個聲音的存在。為什麼BBC? 單純個人喜好而已。

看影集練英聽

我喜歡看歐美電視影集,一週七天幾乎每天都看,如果時間夠的話,我一集會看兩次,第一次是沒字幕的,第二次才是放有字幕的。不過這個就自己斟酌了,因為很可會因為影集看了著迷而忌了原本該做的事。

結論

年輕時一直以為自己可以找到什麼密技能速成的,或是以為自己是天才隨便學一下就會的,事實上並不是,語言的東西不管是一般語言或是電腦程式語言根本沒銀彈,只有多練習一條路而已。

來算個簡單的數學,你知道1.01的365次方是多少嗎? 答案是37.78。也就是說如果你能每天進步1%,一年之後你會比現在厲害37倍. 雖然這數字有些理想化,但即便只做到三成,至少也能強10倍。

最後提醒大家,新技術通常很好玩,但不要盲目追求新技術,但也不要對新事物太過害怕而不去學它,過與不及之間該如何取捨,請小心拿捏。當找到屬於你自己的學習方法,也許你會發現其實這也是很有趣的。

一些個人的心得,與大家分享