hit counter for blogger

黑暗執行緒

 黑暗執行緒搬新家囉!! http://www.darkthread.net

7/31/2006

從木柵看海的日子

經過昨天慘痛的教訓後,今天一早見天空仍然湛藍,決定快點把握老天給的第二次機會,整裝再向草湳大榕樹出發。當然,臨行前反覆檢查了三次,確定有帶CF卡才出門。
昨天已經爬過二格山,加上昨天老弟的線報說猴山岳的視野奇佳,於是今天決定由大榕樹走到猴山岳(路線可以參考這裡),再原路折回,路程輕鬆一些(昨天回程時腳盤小小扭了一下,今天就別太操!);畢竟這是一趟相機復仇之旅,浪費太多時間在走路上會模糊焦點。
花了約半個多小時就從草湳大榕樹走到了猴山岳前峰,說正格的,今天的天氣比昨天差一點,雲量較多,藍天的面積大減,但視野依舊不錯。從前峰一路向北看去,幾個台北巿的主要地標,101、新光大樓、圓山大飯店、陽明山,都清晰可辨,甚至可以隱約看到北方的海面,實在是難得一見的好天氣! 感覺上昨天的天氣又更好一些,但錯過了就是錯過了,徒呼負負亦於事無補。
猴山岳真是熱門的路線,在我停留的短短二十分鐘內,山頂就換了五批登山客;不過大部分的人多半從指南宮過來,挑戰完90度的向上爬升登頂後,看一下風景離去。(90度的上升坡有多好玩呢? 可以看這裡) 今天時間稍晚,又不想當完猴子後走一大段馬路回大榕樹騎車,所以沿原路回去,帶著笑意完成了今天的復仇之旅。

MM0730A

7/30/2006

35℃, 678m, 55min, 1.3Kg-->搥心肝

清晨起床,發現今天天氣真是出奇的好,天空藍得不可思議,加上風勢不小,足以把台北平日漫天的懸浮塵粒吹散,看來終於有機會拍出風景明信片品質的照片了。
機不可失,抄起了相機Canon 10D(790g)+Canon 28-135mm IS鏡頭(540g),匆匆灌了盒牛奶(480ml),就騎著機車(125cc)到達草湳大榕樹(06:55),停好車立刻向二格山(參考: [1] [2] [3])出發。
這座山由於路況好、加上高度夠(台北市南區的第一高峰)、視野佳(登山術語叫展望良好),這幾週我幾乎每週都來報到,路線已熟到不行。一路不斷超車(共計7名歐吉桑、9名歐巴桑跟四條黑狗,一條拉不拉多),終於在55分鐘後抵達山頂(678公尺)的瞭望台。
果不其然,天空藍到不行,但風很透,並不太熱。向北方看去,台北101, 新光三越大樓, 七星山, 關渡... 一路可以看到東海;南面翡翠水庫也十分清晰,雖然仍有薄薄的白霧,但已是幾次經驗中,空前良好的視野了。
迫不及待拿出相機,前照後照了數張,忽然想看看效果,按下Review鈕,No CF Card!
No CF Card! No CF Card! No CF Card! No CF Card! No CF Card! No CF Card! No CF Card...
想起了前幾天為了替女兒照大頭照,拍完立即把卡片拿到PC上檢查效果,就忘了插回去。帶相機沒帶CF卡爬山,這是第三次了! orz
因此,今天的美景,我只能靠回憶,各位只能靠想像,這種境界比看照片高出許多,共勉之。

7/28/2006

被Javascript電得哇哇叫--location.href Behavior


寫了多年的網頁程式,自認精通Javascript,卻在今天又再一次體會活到老學到老的真諦。
同事請我幫忙抓一隻難纏的蟲,程式參考自MSDN一篇關於長時間網頁(Long Run)等待狀態顯示的Design Pattern,目的在避免使用者久候不耐的感受,實務上一些執行時間高達數十秒到數分鐘的網頁,總是讓人搞不清楚是當機還是在處理中。如果在等待的同時可以顯示一些”安撫使用者”的進度資料,可以減少網頁被使用者放棄的機率。
原文中有一段Javascript location.href轉向的特殊用法,讓我頓時丈二金鋼摸不著腦袋。我把相當的邏輯簡化成以下兩個網頁:
Start.htm [用來觸發Long Run網頁,並顯示等待秒數安撫使用者]
<html><body>
<button onclick="process();">Process</button>
Time: <span id=msg></span>
<script>
function process() {
        setInterval("showTimer();",1000);
        location.href="Process.aspx";
}
var i=0;
function showTimer() {
        i++;
        msg.innerText=i;
}
</script></body></html>
Process.aspx [模擬Long Run網頁,Delay 10秒後顯示Finished!]
<%@ Page Language="C#"%>
<html><body>
<% System.Threading.Thread.Sleep(10000); %>
Process Finished!
</body></html>
依我過去的認知,在location.href=”…”之後,目前的網頁應該就會Unload,瀏覽器會立即連上新網頁,若新網頁耗時很久,則使用者勢必會有一段時間看著白色的網頁發呆。但事實不然….
反覆做了幾個測試,即使Process.aspx先Response.Write一些文字,利用Response.Buffer=false或Response.Flush先送一部分內容到IE,Thread.Sleep後再送出第二段文字後結束,結果還是一致的--當使用location.hreflocation.replace導向其他網頁後,IE會停留在原網頁上,一直到新網頁內容傳輸全部完成為止
因此,上述的Start.htm程式中的setInterval會啟動讀秒,等待Process.aspx完全執行結束後,IE才會用Process.aspx的網頁內容取代Start.htm。實際Demo可以看這裡
今天的觀察所得,一下子推翻了多年來深信不移的概念,幸好早年幾位嗜賭成性的老友Max, Ryan, 小毛不在,不然可能已經輸掉一客牛排。沒想到自稱老鳥還是被電得哇哇叫,只能說技術領域實在太浩瀚了,永遠不要自滿,心態才會健康!
另外,今天還學到一個新method—location.replace(),跟location.href一樣,可以用來Redirect,但最大的不同是replace後新URL可以取代Browser的歷史記錄,也就是被取代掉的URL將從回上一頁的清單中消失,如果你不想要某個網頁被Reload,這也是個可以考量的方法。

7/21/2006

機器更名大作戰

公司啟動了新的資安規定,取消了DHCP,要求所有Client PC一律使用固定IP,且依公司所配發的名稱為電腦命名。
辦公室桌上的XPC SB81P是2003年底買的,跟著我流浪過三家公司,OS也一直沿用至今,沒再重灌過。這下被要求改名,沒法預先攤出需要更動的設定有哪些,只有先更名,再用打地鼠的方式,等問題自己冒出來,遇到一個解一個。
IP跟機器名稱改好重開機後,第一步就是試試機器上的各個功能是否正常。為了減少衝擊,我特別在lmhosts及host兩個檔案裡,將新的IP Mapping回我的舊電腦名稱,這樣本機的程式即使Sql Connection String或UNC指的還是舊Machine Name,可以完全不用更動,繼續運作。
不過,當我用IE開啟本機的WSS個人Portal時,第一關來了,IIS Web起不來,所有的Web處於停止狀態,要去啟動時,出現了 The format of the specified network name is invalid
“的錯誤訊息,然後系統事件簿中出現了
HTTP Error Event 15005
Unable to bind to the underlying transport for 10.0.15.91:80. The IP Listen-Only list may contain a reference to an interface which may not exist on this machine.  The data field contains the error number.
W3SVC Error Event 1004
Cannot register the URL prefix 'http://*:80/' for site '1'. The site has been deactivated.  The data field contains the error number.
幸好,這兩個訊息非常明確,Google了一下就找到答案。這才想去前陣子為了Try SubVersion,裝了Apache HTTPD,所以指定了HKEY_LOCAL_MACHINE\Service\CurrentControlSet\Services\HTTP\Parameters\ListenOnlyList,讓出一個IP的80 Port給Apache用。ListenOnlyList的IP還是舊的,造成了Web無法啟動。修改Registry,再net stop http /y, net start w3svc一下,Web就可以啟動了。(注意要重啟HTTP,光IISRESET是沒有用的!)
Web Server OK了,此時第二關出現了。連上本機WSS時,出現大大的Server Application Unavailable訊息。幸好,Event Log中可以找到明確的錯誤:
W3SVC Warning Event 1057
The identity of application pool 'WSSPool' is invalid, so the World Wide Web Publishing Service can not create a worker process to serve the application pool.  Therefore, the application pool has been disabled.
W3SVC Error Event 1059
A failure was encountered while launching the process serving application pool 'WSSPool'. The application pool has been disabled.
原來是IIS Application Pools中開了一個WSS專用的App Pool,其中指定了MachineName\WSSAccount作為執行身份,現在電腦名稱改了,它沒跟著自動更新,就只有出錯的份了。改了Identity,WSS就OK了,SQL Connection的部分完全不需要改,看來是lmhosts發生功效!
晚上回到家,用VPN連回公司,第三關來了! 要用Terminal Service連上XPC時,卻發現無法連通,用ping、net use驗證了一下,機器活著,RPC是通的,看來是Windows 2003的內建防火牆作祟。之前設定過只有特定IP網段才能連上Terminal Service,這下IP改了,鎖定的網段卻沒調整,當然不通。不過,只有RPC可通,要如何解決這個問題呢?
雖然是睡一覺明天上班就可以解決的小事,但利用有限功能取得主機操作權的挑戰,實在太有駭客攻門的味道了,讓我的駭客基因蠢蠢欲動,頓時精神百倍!! 不過由於RPC可通,我又有Administrators權限,事實上並非難事。Google了一下,前後試了幾個方法:
1.       netsh可以修改firewall設定,但我測試的結果似乎只能修改本機firewall,連結遠端主機時,無法使用firewall這個Command。
2.       如果遠端不可用netsh firewall,那麼telnet進去再執行總行了吧? 開啟電腦管理的MMC,再連至XPC(因為RPC可通),啟動了Telnet Server,卻發現Port 23被防火牆擋下來,第二波攻勢無功而返。
3.       再Google了一下,發現了一個好工具-sc.exe,可以控制遠端機器上的Service,利用sc \\MachineName stop SharedAccess,就可停用防火牆。Bingo! Terminal Service可用了。參考資料
這三隻地鼠應該只是先鋒部隊,後面幾週應該還有得打,就等遇到再說吧!


[Updated 2006-07-27 17:35]
又發現地鼠一隻... Scheduled Task中設定的Identity用的是本機帳號,前方會跟著機器名稱,機器更名後記得也要改,另外以此類推: COM+ Application、Window Service裡也可能有漏網之魚。

7/18/2006

文字檔Encoding的識別

從以前DOS時代BIG5的一統江湖,演進到Windows的Unicode時代,看似有唯一的標準,但只要轉換到檔案、網路傳輸時,還是得面對Encoding方法的選擇,應該不少人都有吃過Encoding的苦頭吧?
UltraEdit支援Encoding的轉換,可以在Unicode、ASCII(Big5)、UTF-8間轉來轉去,只是我常常檔案一開啟時,完全搞不清楚現在是什麼Encoding。今天同事小熊子分享了一個Tips,我這才發現原來UltraEdit的Status Bar就有得看!
DOS->ASCII(Big5)、U-DOS->Unicode、U8-DOS->UTF-8
UEdtEncoding
另外,還認識了另一個跟UltraEdit有拼的Text Editor--EmEditor,日本人寫的,大概更是了解非英語系國家使用者的痛苦,Encoding的顯示更是明確到不行。
EmEditor Free版具有大部分UltraEditor的功能,不想花錢註冊又不想黑心長期試用的朋友可以試試!
EmEditorEncoding
 
 

7/16/2006

Live Messenger不明連線謎底揭曉!

前幾天發現Windows Live Messenger開啟了不明的HTTP連線連到幾台Seednet撥接IP的不明伺服器上,追查了一番,才它們是Live Messenger部分動畫快遞(Winks)的檔案來源。
文章貼出後,一位熱心的朋友提供了回應,我才知道原來是自己孤陋寡聞了,Akamai可是有名的網路內容遞送服務,Google了一下,發現Akamai有官方網站,台灣甚至有代理商,而微軟與Akamai也建立了策略聯盟,無怪乎會在Live Messenger身上發現它的影蹤。既然Akamai是MS目前採行分散網路內容傳輸的策略,將來應該也會在其他的產品上發現這種模式。只是Akamai你也幫幫忙,既是國際知名的服務供應者,就算用ADSL來節省在全球部署12,000台伺服器的成本,好歹也設定一下固定IP,申請個DNS Name。不然網管人員一天到晚看到自己公司內的PC在Inernet上的尋常百姓家四處遊走,恐怕也要捏把冷汗吧?

USB 2.0 vs SATA速度測試

同事小熊子有個3.5" IDE HD外接盒,同時提供了USB 2.0及SATA介面,前幾天他分別採用兩種連接方式連上PC,測了一下速度,並跟我分享了測試結果。結果當然是SATA以44.2 MB/s狂勝USB的17.2 MB/s。速度不敵在預期之內,但由這種測試結果,我才發現到另一個事實: USB 2.0吃CPU也吃得挺凶的,CPU耗用率超過25%! 只是USB插頭幾乎每台PC都用,SATA介面的普及率還不算高,而且不像USB一樣會在機殼前後提供插頭,必須要設法自己牽線,方便性差多了。但是由這個數據來看,如果是長期、重度使用時,還是值得花點功夫去爭取較有效率的連線方式。
USB2.0HDSpeed
SATAHDSpeed

7/13/2006

頭腦體操--解答版


有意思的邏輯推理小品,大家來挑戰一下,看多久可以解出來。
這題的難易看來挺適中的,據說有公司拿來當成程式設計師應徵的考題,哈!
 
P先生、Q先生都具有足夠的推理能力。
這天,他們正在接受推理面試。
他們被告知桌子抽屜裡有以下16張撲克牌:
紅心 A、Q、4
黑桃 J、8、4、2、7、3
梅花 K、Q、5、4、6
方塊 A、5
葉教授從這16張牌中挑出一張牌,

並把這張牌的點數告訴P先生,
把這張牌的花色告訴Q先生。
 
葉教授問P先生和Q先生: 你們能從已知的點數或花色中推知這張牌是什麼牌嗎?
 
P先生:"我不知道是哪一張牌。"
Q先生:"我想你一定不知道是哪張牌。"
P先生:"現在我知道是哪張牌了。"
Q先生:"我想我也知道了。"
 
請問:這張牌是什麼牌?

黑暗大師解題顯示答案

7/12/2006

KB-Windows Live Messenger可疑連線解密


無意發現Windows Live Messenger開了多條HTTP連線到一台Seednet撥接IP的主機
MSNWeirdHttp
理論上Live Messenger連線的對象應是世界性的Server才對,怎麼會是台來自Seednet撥接網路的機器呢?
試著telnet連上這台機器的80 Port、21 Port及25 Port,都是螢幕全黑後輸入任何字元後被斷線,看來需要特殊規格的Client端才能連。

由以上這些線索,讓我不禁懷疑,該不會是中了木馬吧? 莫非這台是後門程式通訊用的閘道想到這裡,神經都繃了起來!
用Ethereal眼睜睜看著它建連線卻抓不到封包,又更讓人冒冷汗。難道這木馬還有特殊的匿蹤功能,Hook了API後為自己作隱身
又找了個免費軟體VisualSniffer,並重新啟動Live Messenger(或許Ethereal就是卡在Live Messenger沒重啟才沒抓到),總算看到傳輸的Request了,是一堆menu_*.xml。不過該台主機一直傳回HTTP 304 Not Modified,所以也看不出XML內容是什麼。將IE Cache清空後,再試一次,menu*.xml的內容終於現形了。
MSNHttpContent
由XML中的圖檔追下來,才發現這是所謂動畫快遞(Winks)下載目錄的選項資料。


最後證實,原來是虛驚一場。只是為什麼跟Messenger相關的服務卻用的是Seednet撥接上網的Server,真不知其中有什麼祕辛
 

7/11/2006

世足賽的驚嘆號

世足賽落幕了,對我來說是個驚嘆號,而不是句點! 席丹的告別作竟然以一張紅牌收場,還賠上他一向沈穩冷靜的形象,叫人惋惜... (新聞在這裡)

馬特拉奇究竟跟席丹咬耳朵說了什麼,讓好脾氣的席丹老大抓狂失控,各方做了多種揣測,我蒐集幾種有趣的版本:
1) 少林足球版(newsgroup: tw.bbs.rec.sports.soccer)
馬特拉奇: 金剛腿是吧? 金剛腿是吧?
席丹: 更! 我是鐵頭功啦!

2) 落健版(大悶鍋: 李熬)
馬特拉奇: 非洲人傳說,只要用頭鎚倒身旁的足球隊員,失去的頭髮就能再長回來...
席丹: 像這樣嗎? 咚~~
裁判: 不要再相信沒有根據的說法了。給你紅牌出場,快去買瓶落健吧!

3) 海霸王版(大悶鍋: 邱異)
馬特拉奇: 海霸王現在10人一桌現在只要2500...
席丹: OK,那我先出場去佔位,你們等下快點來。咚~~


KB-詭異的NOT IN


今天被一個詭異的SQL查詢結果搞到昏頭,查兩個TABLE
SELECT * FROM A WHERE ID=123 à 有資料
SELECT * FROM B WHERE ID=123 à 沒資料
由以上結果,推測
SELECT * FROM A WHERE ID NOT IN (SELECT ID FROM B)
該至少有一筆資料才對吧?
 
 
答案是不一定!!
若Table B中有部分資料的ID欄位為NULL,則第三個NOT IN查詢的結果將會是空值。
 
NULL被用來比較時,其結果是很特別的。例如: 以下有五個測試
SELECT 'YES' WHERE 1=null
SELECT 'YES' WHERE 1<>null
SELECT 'YES' WHERE null=null
SELECT 'YES' WHERE null<>null
SELECT 'YES' WHERE null is null
以上五個查詢條件,只有最後一項會為true,這解釋了NOT IN失效的原因。

7/10/2006

變調的電腦展

今天在新聞上看到台北多媒體電腦展的報導,沒介紹今年主打的PC機種、也沒提現場有什麼優惠,兩分多鐘的新聞影片中只看到主辦單位由日本重金禮聘來號稱有J-Cup的"寫真"女優,跟台灣有名的Show-Girl大車拼。依據新聞旁白,有位號稱這方面專家的歐吉桑拿著捲尺東量西量,然後結論是日本女優勝出(廢話! 花大錢找了日本人來還輸,豈不是"潘仔"?)。接著更令人瞠目結舌的表演來了,女優在台上舖了張瑜珈軟墊,開始做起體操,展現"偉大的"胸襟。這段新聞最後以令人傻眼的一段訪問做為結尾: 女優在台上忽然就難過得哭起來,透過翻譯的說明,原來她發現本地的報紙將她誤為"AV"女優,但她是"寫真"女優,讓她倍受委屈,現場看到這麼多媒體(呃... 其實其中夾雜一部分是拿著DSLR的攝影狂,一部分是醉翁之意不在酒的色情狂),一時悲從中來... 幾年前辣風乍起時,電腦展找來36 G-Cup的女優來台助威,我還認真地替主辦單位思量,研判是Seagate或WD贊助,用以促銷"36G HD"。這次找來J-Cup,又不是IBM Developer大會要替"J"ava打知名度,對不起,我沒法幫忙拗了。
沒想到,一場熱鬧的電腦展,被電視新聞去蕪存菁後,剩下值得報導的訊息只剩J-Cup、AV vs 寫真。近年來台灣的展覽似乎開始變了味道,管他汽車、電腦還是家俱,一律得靠Show Girl軍團、管他寫真還是AV女優來壯聲勢、博版面,至於展覽的重點、內容是什麼,似乎都只是次要的。幾番下來,大家越吃越辣,不辣的反而就變成不上道;就好像開車一路過去,檳榔西施一攤比一攤敢露,中間要是夾雜一攤只有歐巴桑在包檳榔的,少不了會招來一聲"更"吧!
相關新聞: 這裡

7/05/2006

陰險的Bug,沈重的一擊



這張圖中隱藏著一隻邪惡的Bug,讓三日不Coding手就會癢的我,罕見地度過十餘小時萬念俱灰,了無生趣的職業生涯低潮,連多年來累積的自信都差點毁於一旦... 只有orz能代表我此刻的心情~~~
這陣子在寫一隻Window Form程式串接一個已存在的後台系統,目的要取代現行功能、效率不甚理想的終端程式。由於已有別人寫好的程式做為模仿對象,手上有詳細的協定文件(但沒有Sample Code),而通訊用Library可提供詳細的Log。本以為應該沒啥大問題,卻發現新寫的程式始終得不到Server端的正常回應。
於是分別把老程式與新Code的Log拿來比了又比,甚至還用Ethereal抓了封包,Follow TCP Stream將完整的傳輸內容Dump下來,用UltraEdit開成上下視窗一行一行比對,明明我的傳送內容與老程式完全相同,為何會被Server識破,就是不給我正確的回應??
排除了傳送內容有異的假設,我開始朝一些細微且可能性不高的機車細節推敲,例如: 送出各訊息間的Delay間隔、傳接用的Thread別...等等,由這些看似吹毛求疵的舉動,自己都可以感覺到,此時已經站在喪心病狂的臨界點了,距離拿鍵盤敲頭自殘大概也不遠了。
忽然一個念頭閃過,決定冷靜下來,回頭再仔細思考一次,最大的問題應該還是在於送出的訊息內容有誤! 於是我重新抓了正常與異常的Log,用UltraEdit一個字元一個字元比對,看起來仍然是完全相同的。害怕會是不可見的字元(例如: Tab, \n)之類惹的禍,於是叫出了UltraEdit的二進位比對功能。這才看到,原來要送出01,我卻誤打為O1(字母O跟數字1,這是個離譜的打字錯誤,打字時被鬼附身是我想到比較合理的解釋),而在UltraEdit、VS.NET中,0與O看起來幾乎是完全相同的,也是我比對了數十次卻一直未能發現的理由。
送錯了訊息內容,但Server未回應內容有錯,卻選擇了沈默不回應;UltraEdit與Visual Studio編輯環境的字型設定讓0與O二者難以用肉眼識別;過快跳離了最有可能的原因(錯送內容導致結果不同),太早鑽研罕見的狀況... 一連串的巧合,讓這個小小的Bug快速長成巨獸,給了Coding老鳥難以承受的沈重一擊。
不過,這樣的經驗,也讓我回頭檢討自己習以為常的Coding、Debugging Style是否流於過度自信,造成在某些狀況下陰溝裡翻船。謝謝這個Bug給自以為是的老骨頭一個謙卑自省的機會,重新學會用敬畏的心去面對技術議題。
PS: 忽然回想起當年擁有的第一部電腦,Intel 8088 4.77MHz的Acer PC,初學電腦的我,看著滿是綠色字母的單色CRT,老對零中間多的那一撇很感冒,抱怨為何硬要跟平常看的印刷字母不一樣。今天的我,特別想念那些有一撇的零...

蕃薯藤新聞,救甘心ㄋㄟ~~


中午吃便當時看到這則新聞,忍不住就笑了出來... 只能說蕃薯藤的編輯大人實在是太體貼了,怕大家看到不調薪的新聞太過沮喪,特地跟大家開示一下正確的人生觀。