Jen

你,真的需要 3G 吃到飽嗎?

最近這幾天常常下雨,下雨天對騎野狼上班的我來說,實在是有點麻煩,我要穿上雨衣、雨褲、雨鞋,才能避免被雨淋濕。所以最近只要遇到下雨天,我就會選擇搭捷運上班。

我家住在頂溪捷運站附近,工作的地點則是在捷運市政府站 6 號出口附近,所以我必須在捷運忠孝新生站轉車,忠孝新生站人潮非常多。

我特別觀察早上搭捷運上班的人,10 個人當中就有 12 個人都在低頭看著自已的手機,或許搭捷運是真的不知道要做什麼,就連睡覺都覺得浪費。

故事就先講到這。

等等,不對啊,這個故事跟文章標題倒底有什麼關係 ?

我大概在 4 年前開始使用智慧型手機,開始使用 3G 網路,當時每個月都要多繳 699 ~ 800 不等的 3G 網路使用費。而現在我已經不使用網路吃到飽的方案,選擇了每個月 149 元 的 3G 網路付費方案,流量限制不能超過 1 G。這樣的改變,每個月要繳的費用從 800 降到 149,一個月可以省下651,一年則可省下7812。

而我搭捷運觀察到的那些低頭使用手機的人,真的有這麼需要 3G 網路嗎 ?
在有限的資源下,才會懂得珍惜,懂得節制。關掉手機,抬起頭,看一看那一片綠綠的森林吧。

習慣,不代表它本來就應該發生。

有位乞丐在某個天橋上乞食,路上行人川流不息;

一個年輕人常常經過這座天橋,看到乞丐便心生憐憫,每天都投100元給乞丐,乞丐收到這100元非常高興,說了許多感激以及祝福的話語; 過了一陣子年輕人每天變成只投50元,乞丐覺得奇怪,祝福的話也少說了一半;又過一陣子,年輕人每日更只施予10元而已;

一天在年輕人給了10元後,乞丐實在受不了了,追上前問年輕人為什麼錢越給越少。 年輕人回答,一開始經濟能力許可所以能給乞丐100元,一陣子後年輕人結婚了,經濟壓力變大所以只能給予50元;

再過一陣子妻子懷孕生子,經濟負擔更重了,因此每日只能投10元給乞丐。 想不到乞丐聽了年輕人的一番話後喊著:「什麼?!你把我的錢拿去給別人啦?!」

這是則我最近在 facebook 上看到的小故事。

有一家新創的軟體公司建立不久,公司剛開始運作,管理較人性化,對於員工上下班時間比較沒有硬性的規定。日子久了,大家都習慣了,也都忘了公司是有上下班時間。公司規模越來越大,如果再這樣下班,的確是會造成很多不便及問題,所以公司老闆開始宣導,請員工每天要準時上班,不要再遲到了。

又過了一陣子,老闆發現用宣導的方式好像沒什麼作用,遲到的狀況沒有得到良好的改善。
老闆決定,要求大家每天上班要打卡,記錄上班時間,並把這些記錄納入員工的考核績效裏。因此,大家變的不開心,開始抱怨。

「好啊,要我每天準時上班,我就每天準時下班,下班之後如果還要我工作,就算加班費給我」

「幹嘛搞的像血汗工廠」

這是則網路上的小故事。

以上這兩則個小故事,你是否覺得很熟悶? 抑或者是真實的故事發生在你的週遭 ?

曾幾何時,「準時上班」變成不是一個上班族應該而且是最基本應該做到的事 ?

我們都習慣了上班不需要準時,卻忘了準時上班是本來就應該做到的事。在你的生活中,是否還有類似這樣的人、事、物呢 ?

習慣,不代表它本來就應該發生。

洗個澡、睡一覺,起來後,好好感謝那些本來就不該發生的美好事物。


Windows Phone 7.5 學習筆記 - 圖片處理的小技巧

萬丈大樓平地起,基本功練得好,不怕大樓被震倒! 最近在 Windows Phone 做圖片處理時,剛好看到一篇文章,研讀一下,把心得做個整理,然後納入「最重要的小事」系列文章。

原文的內容大綱: 
  • JPG 跟 PNG 的差異
  • Resource 跟 Content 的差異
  • 圖片的非同步處理
  • 圖片快取
  • BitmapCreateOptions
  • 自訂解碼
  • 縮減取樣 
[more]
JPG 跟 PNG 的差異
JPG 只能用來不透明的圖,PNG 用來做透明的圖,你可能會認為,乾脆都用PNG 做圖就好啦,省得麻煩,但在 Windows Phone OS 裏,對 JPG 解碼效能會比 PNG 來的好,所以站在優化的角度來看,在規劃設計 App 的時候,最好就要定義出哪些圖是需要透明的,而不需要透明的圖都用 JPG ,以節省 OS 的資源。
Resource 跟 Content 的差異
你把一些圖檔或靜態檔案加到 Windows Phone 的 Solution 時,預設的 「Build Action」是 Resource。 如果你從 Bin 資料夾把 xap 副檔名改名為 zip,然後解壓縮,你只會看到把 Build Action 設為 Content 的圖檔(或檔案)。簡單的說,把圖檔的 Build Action 設為 Resource 的話,編譯之後會一起 embed 到 dll 裏面去,而設為 Content ,則會被檔案實體檔案存在手機的 Disk 裏面去。
這樣有什麼不同呢? 如果把所有的圖檔一起 embed 到 dll 裏面去,dll 檔案會變大,應用程式一開始載入到記憶體的時候會比較慢,但也因為已經載到記憶體,執行時讀取檔會比較快。那如果不是 embed 到 dll 去,相對的檔案比較小,一開始載入記憶比較快,但讀取圖檔時,就會有個 Disk I/O 的 battleneck,會稍為比較慢。
在使用上會有點不一樣:

設為 Content : <Image Source="/ImagesAsContent/smiley1.png" /> 
設為 Resource : <Image Source="..\ImagesAsResource\smiley3.png" /> 
圖片的非同步處理
在做圖片處理,要跟 BitmapImage 這個類別混熟一點,它常會做一些你看不到的事情,例如 JPG 及 PNG Decode 的背景作業,不用自已再去寫一些用 Thread 去處理讀圖檔的程式碼。
原文中有提到 2 種使用方式:
  • BitmapImage.UriSource = uriSource; // 透過 URI 做非同步讀圖檔的動作
  • BitmapImage.SetSource(stream);     // 同步讀取 Stream 
BitmapImage 還有一些事件需要知道,
非同步讀取圖檔的時候:
  • 失敗的時候會觸發 ImageFailed 事件
  • 成功的時候會觸發 ImageOpened 事件
同步讀取圖檔的時候:
  • 失敗的時候會丟出 Exception。
  • 成功的時候並不會觸發 ImageOpened 事件
圖片快取
有圖片快取的好處是可以避免不必要的重複下載及重複解碼。當你把 Image 這個 Control 移掉之後,原本指給 Image 的 BitmapImage 依舊還在記憶體快取中,並沒有跟著 Image 這個 Control 一起消失掉,會佔著一部分的記憶體,只要你確定這個 BitmapImage 沒有需要再使用的話,是可以用下面這個方式把它從記憶體中移除。 
BitmapImage bitmapImage = image.Source as BitmapImage;
bitmapImage.UriSource = null;
image.Source = null;
BitmapCreateOptions
查一下 MSDN BitmapCreateOptions 會有三個舉例的值,用來指定你要用什麼樣的方式來產生圖檔,
  • DelayCreation (預設值)
    • 當圖出現在「可視範圍」才會被畫出來,假設你有個 ListBox,當圖出現在使用者看得到的地方,才會被畫出來。
  • None
    • 不管圖有沒有出現在可視範圍,直接都先把圖畫出來。
  • IgnoreImageCache
    • 當圖出現在「可視範圍」時,再畫一次。上面兩個是只畫一次,有需要的話就會從 Cache 中抓圖出來,但這個選擇是不會從 Cache 抓圖,只要出現在「可視範圍」就再畫一次,也就是說你的記憶體會一直爆增、爆增。通常用在測試期間才會使用這個選項,如果上 App Hub ,我想會被退件吧。
解碼
預設 Windows Phone 會用圖片原本的解析度來處理它,但很多時候,我們的原圖會很大,而在手機上會來的比原圖小很多,假設你在網路上有張 500x500 的圖,下載到手機記憶體後縮成了 100x100,最後顯示,這樣的動作會浪費不少記憶體及手機資源,不建議這麼做。 Windows Phone 提供了PictureDecoder API 讓你在接 stream 的時候就可以做縮圖,不會浪費記憶體: 
image.Source = PictureDecoder.DecodeJpeg(jpgStream, 192, 256);
  
縮減取樣
在 Windows Phone 7 所有的元素都不能超過 2048x2048 的大小,只要任何一邊超過2048,就會被剪掉,造成無法顯示完整的圖檔。為了避免這樣事情的發生,Windows Phone 7 有提供自動縮減取樣的機制,只要任何一邊超過 2048 便會自動按比例縮小到 2 邊都不超過 2048。只有在 Windows Phone 才有,Silverlight on Desktop 就沒有這樣的限制。
現學現賣
記得有很多吉他的教材在每個單元結束後都會有個現學現賣,我也來個寫簡單的練習範例, 裏面會有兩個專案,一個是 WebSite ,專門提供 JSON 資料及圖片,一個則是 Windows Phone 的專案,我把它Commit 到 GitHub 上,有興趣再去看看吧。
  • WebSite 有 2 個 Service:
    • ~/Source/GetTech : 取得十幾筆帶有圖檔檔名的 JSON 資料。
    • ~/Source/GetImage?name={圖檔檔名} : 透過傳入的圖檔檔名,回傳一張圖檔。
       
  • Windows Phone 專案:
    • ~/Converts/ImageConvert 類別:包含上面所提到的 CreationOption、ImageFaild ...等等屬性及事件的用法。
    • MainPage.xaml 的 31 ~ 39 行放一個 Timer ,用來顯示記憶體用量的變化,可以試試各種 CreationOption 所造成的影響。
參考文章:

Mongo DB - RepliSet Mode 懶人設定筆記

之前分享的 Mongo DB Sharding 心得筆記 (一) 提到每個 Shard 可以是個 RepliSet,以避免台主機掛掉之後,資料就救不回來的情況發生。簡單做個筆記。
 [more] 
【RepliSet 設定】
假設我們要以 3 個 Mongod 來做 1 個 RepliSet,我們會用以下指令來啟動 3 Mongod:
mongod --dbpath "C:\MongoDB\Database\Set1" --port 10001 --replSet fpgSet
mongod --dbpath "C:\MongoDB\Database\Set2" --port 10002 --replSet fpgSet
mongod --dbpath "C:\MongoDB\Database\Set3" --port 10003 --replSet fpgSet
然後用 mongo 指令,連上任意 1 個節點,設定 Config ,
config = { _id: "fpgSet", members: [
... { _id:0, host:"localhost:10001" },
... { _id:1, host:"localhost:10002" },
... { _id:2, host:"localhost:10003" }
... ]}

rs.initiate(config);
這些資訊都會存在 database 中預設的 local 這個 collection 中,如果設定失敗,要先確定是否有切到 local 這個 collection。
使用 rs.isMaster() 查看目前 ReplSet 的 Member 跟 master 是哪個節點。
如果用 shell 連上 Slave 的節點,預設是不能做查詢,下 rs.slaveOk() 指令 或 rs.slaveOk=true ,即可查詢。
_id是流水號,請注意,如果有個成員被移除的話,該 _id 就不能再被使用。
參考1

【新增、移除 RepliSet 的成員】
要新增一個成員也是很簡單,需要注意的是新成員的資料必須是空的或是從其他成員複製過來的資料,啟動新的 mongod 並給他一個 RepliSet 的名稱:
mongod --replSet fpgSet --host localhost --port 10004 --dbpath "c:\MongoDB\Database\Set4"
 
新增成員:
rs.add("localhost:10004")
移除現有的成員:
rs.remove("localhost:10004")
1.舊的成員重新加入?
2.快速增加新的成員,可以拿現有的成員資料,重新複製新的成員加到 RepliSet。
要「乾淨」並且是「最近的」的資料檔案。
參考1參考2 

【重新設定 RepliSet 的成員】
使用參考1  : 當一個成員 down 掉時。
使用參考2  : 當成員 up。

Windows Phone 7 疑難雜症 - WindowsPhone71.Overrides.targets was not found

今天在 Code Samples for Windows Phone 下載了一些 Sample Code 來看,但是在開啟的時候會跳出以下這個錯誤視窗。
接著在 Visaul Studio 2010 的 Output 視窗顯示以下錯誤。
The imported project "C:\Program Files\MSBuild\Microsoft\Silverlight for 
Phone\v4.0\Microsoft.Silverlight.WindowsPhone71.Overrides.targets" was not found.

打開指定的目錄,只發現一個名為Microsoft.Silverlight.WindowsPhone.Overrides.targets 的檔案。
【解決方式】
如果要修正這個錯誤,用 Notepad ++ 打開專案目錄下的 *.csproj,以我為例就是 sdkContactsCS.csproj 這個檔案。
開啟後,找到以下這一段:
WindowsPhone71
改成:
WindowsPhone
存檔重新開啟就完成了。
========================
2011/12/7 更新
搞笑了,我裝的 Windows Phone SDK 是 7.0 舊版的,MSDN 的 Sample Code都是 7.1 版的,所以才會出現這錯訊,所以我就先移除 7.0 版 SDK ,再重裝 7.1版的 SDK,就可以不須做以上的修改,這一篇是錯誤學習。