July 2007 - 文章

TIPS-WTF Intellisense For Radio Input

今天遇到一則有意思的案例:

在VS 2005中,ASPX網頁新增了一個<input type="radio">,由於要設為預設選取,準備輸入checked屬性,VS 2005很貼心地提供了Intellisense...

照著VS 2005的提示輸入check="checked",接著瀏覽網頁... 嘩~~~ 出鎚了

Parser Error Message: Cannot create an object of type 'System.Boolean' from its string representation 'checked' for the 'Checked' property.

依上述的說明,改成checked="true"後,ASPX就可以正常執行了。但回到VS 2005中,你會在Error List清單中看到以下的錯誤,表示true不是checked Attribute的合法結果!

Error    7    Validation (XHTML 1.0 Transitional): The values permitted for this attribute do not include 'true'.

這... 這... 這...

阿公欲煮醎,阿媽欲煮淡,兩人相扑來弄破鼎... orz

我認為這個問題應該是runat="server"的語法要求與VS 2005 XHTML的驗證規則衝突所致,除了等MS在XHTML Validation Rules中加上但書,現階段大家能做的,就先忽視XHTML Validation Error吧!

TIPS-About <script src="...">

有人知道以下的HTML裡有什麼問題嗎?

<html><head>
<script type="text/javascript" src="inc.js" />
<script type="text/javascript">alert("Hi!");</script>
</head><body>JS Lab</body></html>

以上HTML中的Javascript不會被執行,所以你不會看到"Hi!"的Popup。

我們都知道XML的語法規格中,Tag必須有始有終,一個<tag>要配一個</tag>;而當Node中未包含任何InnerText時,可以有兩種表示方法:

<br></br> 或 <br />

在HTML的規則中,<script src="..."></script>卻不可以簡寫成<script src="..." />,對IE or Firefox都是如此,但Safari倒可以接受,大家留意一下吧!

Trixie Script: PIXNET Slide Show Enhancement

最近迷上用Trixie"改造"網站!(謎之聲: 哪有人"改造"會改到熱血沸騰的,你這個死駭客,就大方承認吧! )

同事有個任務需要反覆查詢某個網站的多項內容另存網頁;但該網站用window.showModalDialog顯示內容,多了許多限制,還加上了防右鍵、防選取等防護,造成擷取資料時諸多不便,我只花了五分鐘用IE Developer Toolbar解析DOM結構跟寫了五行Trixie用的Script,便把showModalDialog改為在原視窗開啟,並讓網頁"返璞歸真",恢復了應有的右鍵及選取操作,讓同事可以順利搞定原本煩人的工作。

今天在酪梨壽司的Blog上看到她馬上就要跟大白成親的消息,順便看了壽司的香港行照片

第一次使用PIXNET的相簿投影片播放,發現上一張/下一張居然是VIP會員才能享有的功能。不能依著自己的閱讀速度看照片實在很悶,於是我就小小地寫了幾行Code,掛到Trixie中,當下立刻升級成VIP啦! 呵呵

想試試的朋友,可以按這裡下載。(設定與安裝的方法請參見先前介紹Trixie的Post)

超扯的機車驚魂

騎機車快要20年了,遇過不少鮮事,沒有一件比得上今天遇到的來得經典。

回家時路經萬芳社區的上坡路,騎著騎著,忽然覺得有東西掉到催油門的右手上,嚇了一跳,手反射性地甩開把手。不過,這可是上坡耶,右手放開豈不要倒退嚕? 於是右手準備要回去握把手催油門,就在手掌將要握緊把手的瞬間,一種詭異的感覺由右手食指、中指指腹迅速傳至大腦:

軟軟的 溫溫的 長長的 軟軟的 溫溫的 長長的 軟軟的 溫溫的 長長的...

媽呀! 這是啥? 一面想看清楚是什麼鬼東西(它躲在把手的另一側,摸得到看不到,噁~~),一面又要設法只用手掌貼著把手努力讓動力逐失的車子保持平衡,總算搖搖晃晃地減速停好車,仔細一看:

一隻壁虎大小的蜥蜴[註]趴在右把手上,驚魂未定地張大眼睛看著驚魂未定的我,對望了十秒鐘,我恢復意識:

快 點 把 牠 趕 走 !

用手捏死牠? 太殘忍也太噁心了。

用拖鞋打死牠? 又不是小強,況且我穿的是皮鞋。

用東西把牠撥走? 機車上順手可得的長形物體只有機車大鎖,要用大砲打小鳥嗎?

此時我才留意車子停在水泥擋土牆旁,頭上有幾根垂下的爬藤。這下子我明白蜥蜴怎麼來的了,接著想到的第二件事是--那就用垂下的枝葉把牠撥掉吧!

沒想到蜥蜴的天然奈米科技硬是了得,怎麼撥也撥不掉,只是一路一直由右把手爬過儀表板,退到左把手上,接著就藏身進龍頭裡,再也看不到了。

既然看不到也就無從趕起了,心想牠被這麼一驚,應該也不會再出來了,接著上路回家。至於這隻我沒能收服的神奇寶貝(木守宮嗎?)下落如何? 如果我明天早上騎車再有遇到牠的話,再向各位報告。

註: 為什麼我會覺得牠是蜥蜴不是壁虎? 主要因為我印象中的壁虎都是皮膚色的,而這隻體型雖然跟壁虎差不多,但卻是深茶色上有白點,比較像印象中的蜥蜴。

TIPS-About Modal Dialog Detection

這陣子一直被一個問題所苦,有個放在Modal Dialog中的ASPX,在送出時會另開新視窗。這類問題在我的Modal Dialog Mini FAQ中有提過,只要加個<base target="_self">就可以擺平。

為了怕開發人員忘了主動加上,我的做法是由Custom WebControl在網頁加入以下的Code:

//ShowModalDialog模式時,強迫將Base Target設為_self;
if (window.dialogArguments) {
    var oBaseColl = document.all.tags('BASE');
    if (oBaseColl && oBaseColl.length) oBaseColl[0].target='_self';
    else {
        var oBase=document.createElement('BASE');
        oBase.target='_self';
        document.getElementsByTagName('head')[0].appendChild(oBase);
    }
}

怎樣? 很聰明吧? Script會自動判斷是否在Modal Dialog中,然後在<head>區設定或加上<base target="_self">, 有時我還真佩服自己~~~ XD

只可惜,百密一疏,以上的寫法有個漏洞。雖然我已確定window.showModalDialog()時都會傳入window Object做為參數,以便在Modal Dialog中可以用window.dialogArguments取得呼叫端的DOM。因此我順理成章地檢查window.dialogArguments來決定是否在Modal Dialog中,不過忘了一點---呼叫端與Modal Dialog網頁跨網域時,會因IE的安全限制禁止Modal Dialog存取呼叫端的window object,此時window.dialogArguments==undefined。這解釋了在正式環境裡,由於呼叫端與Modal Dialog分處不同的機器,造成window.dialogArguments判斷失效,連帶導致沒加<base target>,最後的下場就是Submit時另開新視窗...

解決方法? 很簡單,用if (window.dialogWidth)取代if (window.dialogArguments)就可搞定。收工!!

TBM-ASP.NET Project File Encoding Converter

跟WSS/SPS 2003時代一樣,想要在MOSS 2007網站上加掛自己的Web Application,得調整web.config中一堆設定方能苦盡甘來(如何設定可以參考小熊子的KB),但我還發現另一件中文使用者要面對的麻煩事...

在中文環境下建立ASP.NET Web Application Project,預設會使用Windows預設語系作為檔案的編碼標準(參考文件),以台灣地區為例,存檔預設多會用BIG5編碼。大家可能都有經驗,當程式碼中輸入Big5難字後,Visual Studio就會提示你存成UTF-8格式。於是專案檔案就會變成有些存Big5,有些存成UTF-8。

這種Big5與UTF-8交雜的Web Application在一般的狀況下沒啥問題,因為ASP.NET會自動判別處理得宜。但是當它被搬到MOSS 2007的網站裡,MOSS在Root Web下強制宣告了<globalization fileEncoding="utf-8" />,Root Web下再加掛的Web Application就會因為web.config的繼承關係受到影響。於是專案中存成Big5的ASPX, CS等就會因強制以UTF-8解讀而發生編碼錯誤,小則網頁出現亂碼,大則因CS/VB解析錯誤而Compile失敗...

解決方法很簡單,開啟Big5編碼的ASPX, CS再重新存成UTF-8編碼即可。用嘴巴講是很快啦! 如果專案中有上千個檔,會搞死人吧?

如大家所想的,潛盾機出現了!

程式的使用方法很簡單(我希望有做到不需說明書就會用),輸入路徑,按下分析就可以掃瞄所有子目錄中的aspx, cs, vb及js檔(分析作業支援Multi-Threading, Thread數可調),並列出其編碼;按下檔名連結可以用NotePad開檔來看,勾選後可以批次將檔案轉換為UTF-8或Big5。

有大專案要搬到MOSS下的朋友,不妨試試。

檔案下載

國中先修班數學題,答案揭曉!

【本報訊】 喧騰一時的質因數分解案,終於有了突破性發展。

上上週經本報記者踢爆台北市某國中先修班之數學練習題目,疑似題意不清及題目有誤,造成學生及家長、親友深感困擾,進而引發社會嚴重關注。

事件爆發後,該名數學老師隨即走避國外,並斷絕與外界一切連繫,僅留下代課老師應付蜂踴而至的媒體。代課老師面對各方質疑,僅低調地承認該題目的確"疑似"有錯,但他不便代替出題老師做出結論。

出題老師在沈重的輿論壓力下,終於決定搭機返國說明,由於現場守侯的媒體實在太多,甚至在數學老師現身時,還一度發生推擠,造成多名記者在拉扯中受傷,警方也因此被迫出動大陣仗維護現場秩序。

數學老師在面對媒體與家長的強烈質疑下,終於坦承題目有錯,該題的數字應為462。在老師宣布題目有錯後,記者發現人群中有一名家長友人格外激動,除了臉上壓抑不住興奮之情,還喃喃自語: "嬴了! 嬴了!",透露出內情並不單純,就在記者欲上前詢問時,該名男子似乎刻意躲避媒體,立刻快閃離開。

轟動一時的國中先修班數學題懸案,就在一片喧鬧混亂中,畫下了句點。

===== 我是分隔線 =====

上回國中先修班數學題目答案揭曉了! 跟大多數人預期的一樣,數學老師宣布題目有錯,要改成462。

而我,嘿嘿,賭嬴了~~~  為了怕揭曉答案的Post只有一行太單薄,上面是委請"榴槤日報"記者胡謅的新聞,就算灌水也灌得很講究吧? 哈!

Posted 24 July 2007 01:54 AMJeffrey | no comments
Filed under:
Trixie Script: Avoid Machine-Translated MS KB

先前寫過一篇Post,介紹過如何用Trixie在IE加上自訂Script,一直以來還沒真的拿來寫些實用的東西,今天開張了!!

使用Google查詢連結到MS的KB時(例如: http://support.microsoft.com/kb/826007),微軟的Support網站會很貼心地視Browser的預設語系,自動切換成該語系的語言版本。

只是中文版KB分為兩種,一種是請人以中文重新翻譯撰寫過的,另一種看似中文,實際上卻是令人舌頭打結,眼睛出血的機器英翻中。

雖然,頁面上已明顯地標明了警語:

注意:本文是不經人為參與的自動機器翻譯系統翻譯完成。這些文章是Microsoft為非英語系國家使用者所提供,讓使用者可以了解文章的內容。Microsoft 不保證翻譯的語言品質也不對由於內容的錯譯或客戶針對內容使用所發生的任何直接或間接可能的問題負責。

但我還是無法接受,既然自知品質難以被人接受,為何還好意思把它變成某些人的預設內容?? 就好像先聲明吸煙會致癌,然後再塞了根煙到你嘴裡般令人不快。

// ==UserScript==
// @name          MS KB強制原文顯示
// @namespace     http://www.darkthread.net
// @description      避免MS開啟KB時自動跳至自動中文翻譯版本
// @include       http://support.microsoft.com/kb/*
// @exclude          http://support.microsoft.com/kb/*/en-us
// ==/UserScript==
(function()
{
    var divDefault = document.getElementById("default");
    if (divDefault) {
        for (var i=0; i<divDefault.childNodes.length; i++) {
            var node=divDefault.childNodes[i];
            if (node.tagName && node.tagName=="DIV" 
                && node.className=="disclaimer mt"
                && node.innerText.indexOf("不保證翻譯的語言品質")>-1
                )
            {
                //用location.replace,將自動翻譯版本從History中剔除
                document.location.replace(
                    document.location.href.replace("/zh-tw","")
                    +"/en-us"
                );
                break;
            }
        }
    }
})();

於是我用Trixie自力救濟一番,寫了以上的Script。當發現MS KB中出現"不保證翻譯的語言品質"云云,立即自動切到英文原文,以免讀了機器翻的爛中文傷眼睛,或是屢屢切換累手指。

整個Script很簡單,就不多做說明,只補充一個Javascript小技巧: 這裡切換網頁用的是location.replace(),而不是用location.href=new_url的寫法。主要原因是可以避免轉址過程被保留在瀏覽記錄中,到時按回上頁要多按一次。

KB-Rapid-Fail Protection of IIS 6

對一台IIS 6進行壓力測試時,因壓力過大Web不支倒地,接著再連上Web,出現的都是HTTP 503 Service Unavailable。

查看Event可以看到5個接連的W3SVC Warning及一個W3SVC Error。

Warning Event 1011 from W3SVC 共有四個

伺服應用程式集區 'DefaultAppPool' 的處理序與 World Wide Web Publishing 服務通訊時發生嚴重錯誤。處理序識別碼為 '3808'。資料欄位含有錯誤號碼。
A process serving application pool ApplicationPool suffered a fatal communication error with the World Wide Web Publishing Service. The process id was '3808'.

接著是Error Event 1002 from W3SVC

正在自動停止應用程式集區 'DefaultAppPool',因為在伺服該應用程式集區的處理序中發生許多失敗。
Application pool 'DefaultAppPool' is being automatically disabled due to a series of failures in the process(es) serving that application pool.

同事小熊子分享了他的經驗,原來這是IIS6所謂的Rapid Fail Protection保護機制。當IIS因為程式不良或遭到惡意攻擊時,造成Worker Process Crash,IIS會自動重啟一個新的Worker Process繼續提供服務;但如果新啟動的Worker Process接連Crash,IIS就會停用該Application Pool,以免持續不斷重啟新Worker Process的沈重負擔把Server搞掛(參考)。

預設值是5分鐘內發生5次異常就會觸發Rapid Fail Protection,這就是為什麼在事件簿中看到5個Warning+1個Error的理由。Rapid-Fail Protection的設定UI如下:

TIPS-Using PIVOT In SQL 2005

遇到一個可以應用SQL 2005 PIVOT新功能的好例子,拿出來分享一下。

分析IIS Log時,我希望統計每一秒鐘不同執行結果(Status Code=200, 304, 401, 404, 500 ...)的次數,由IISLog匯入而成的Table可以找到LogTime與StatusCode兩個欄位。
要統計每秒不同StatusCode的數量不難,例如以下的T-SQL:

SELECT LogTime, StatusCode, Count(*) As Cnt 
FROM IISLogTable
GROUP BY LogTime, StatusCode
ORDER BY LogTime
查出的結果會像這樣:
LogTime  StatusCode Cnt
-------- ---------- -----------
06:40:05 200        5
06:40:05 302        1
06:40:06 304        1
06:40:06 200        10
06:40:07 200        5
06:40:07 500        3
06:40:08 200        11
06:40:08 404        1

但在實際應用時,我們會希望將每秒鐘的各StatusCode整合在一列中,像LogTime, StatusCode, Count200, Count302, Count304, Count401...的形式,以方便用Excel製表或繪圖,但這少不了要費一番手腳。

當使用的資料庫是SQL 2005時,我們多了一項新武器---PIVOT! 用如下的語法,就可以將以上的結果由列轉成欄,變成我們要的樣子。

SELECT * FROM 
(
    SELECT LogTime, StatusCode, COUNT(*) AS Cnt
    FROM IISLogTable
    GROUP BY LogTime, StatusCode
) AS X
PIVOT
(
    SUM(Cnt)
    FOR StatusCode IN 
    ([200],[302],[304],[401],[404],[500])
) AS PVT

查詢結果變成:

LogTime  200         302         304         401         404         500
-------- ----------- ----------- ----------- ----------- ----------- -----------
06:40:05 5           1           NULL        NULL        NULL        NULL
06:40:06 10 NULL 1 NULL NULL NULL 06:40:07 5 NULL NULL NULL NULL 3
06:40:08 11 NULL NULL NULL 1 NULL
怎樣,很省事很酷吧?
KB-Application Center Test Tool, Old, But Good

時間都來到2007,眼看Visual Studio 2008都要上市了! 是哪個死白目又回頭介紹起Visual Studio.NET 2003的壓力測試工具??

大家先別氣到要拔網路線,待我說明原委。

這兩天,同事的系統需要做壓力測試,問我有無建議的工具。想了一下,Visual Studio 2005的壓力測試工具只剩Tester Edition及Team Suite才有,有些開發人員裝的是VS 2005 Developer Edition未必有得用。新的壓力測試專案雖然換湯不換藥,使用操作方式卻已有所改變,我還沒花時間學(事實上,看來也甭學了,等VS 2008好了),讓侏儸紀時代的阿公級壓力測試工具—Application Center Test再露個兩手,一樣做出漂漂亮亮的測試報表,有何不可?

我翻出兩年前在雜誌發表過介紹ACT的舊文章,讓有需要的人參考看看,早就精通ACT或對老舊工具過敏的朋友請略過本文。

【注意】這篇文章的時空背景是2004年,請大家抱著懷舊的心情閱讀,勿挑剔其中不合時宜之處。

下載文章

TIPS-Windows Recovery Setting

最近處理一台主機的異常,發現因為幾個地方沒調好,造成自我復原過程的不順暢。這裡整理分享一下我自己常用的啟動修復設定建議,給大家參考參考。

不管是Windows NT/2000/XP/2003,都可以在"我的電腦"按右鍵選"內容",找到以上的"啟動與修復"設定頁面。說明其中兩個設定重點:

  1. 自動重新開機:
    當Windows出現Blue Screen(BSOD)時,Windows預設會自動重新開機。今天處理的主機,這個選項卻是被取消的,所以,當錯誤發生後,畫面就一直停在Blue Screen上,必須要有人跑進機房幫忙重開(Terminal Service等遠端功能早掛了)。保留現場的主意不錯,但大部分的人不大能由Blue Screen看出端倪,而正式主機常被關在機房中,未必有人時時刻刻盯著,會延誤重啟復原的時機。另一方面,有挺高的比例,Windows只需重開機就又是一條好漢,因此自動重開符合力求減少Down Time的管理實務。只是即使自動開機後能恢復正常,系統管理者也應認真追查每次導致當機的真實原因,設法排除,切忌鄉愿,不然遲早Blue Screen會代替月亮懲罰你的。
  2. 撰寫偵錯資訊:
    (挺爛的翻譯,Writiing Debugging Information中的Writing應該翻"寫入"就好,事實上它不過是將當機時的記憶體內容寫入Disk中,又不是論文或Proposal,說"撰寫"未免沈重。)
    系統發生嚴重錯誤時,OS會呼叫SAVEDUMP.EXE將完整的記憶體內容保留下來,CSI鑑定專家就能100%還原命案現場,找出問題所在,這是多美好的一件事?! 只是地球上有能力解讀Memory Dump的超人沒幾位(我知道一位: Debugger Lady),加上分析工程浩大,除非當機的真相影響重大(例如: 兩顆子彈之類的),否則我們很少會真的將Memory Dump檔案交給MS Support解析(或者閣下自己就有能力解讀? 失敬! 失敬!)。既然用不到,就沒必要花時間跟空間將數GB的RAM內容寫到Disk上;系統預設會"完整記憶體傾印"(具有2GB+ RAM的主機則是"核心記憶體傾印"),記得把它停用,或寫個64K意思意思就好了。

最後分享幾次被SAVEDUMP.EXE扯後腿的經驗。

一般來說Memory Dump應發生在Blue Screen的同時,也就是Blue Screen的下方跑出一個百分比進度,顯示已將多少%的Memory寫入Disk了,跑到100%後再重新開機。但是我卻發現,有時SAVEDUMP.EXE會在Reboot後才啟動(記憶體都重置過了,莫非在寫心酸的? 記憶體Dump會先放在PageFile中,隔次開機時才處理)。最狠的是,SAVEDUMP會佔用掉全部的記憶體空間,讓重開機後的啟動程序陷入極度的記憶體不足及嚴重Swapping的狀況,搞得所有的程序都慢到不行。最悲情的一次經驗,Windows因故Blue Screen當機重開後,SAVEDUMP被叫出執行吃光記憶體,接某個Service在記憶體嚴重不足的狀況下不支倒地,再度造成Blue Screen,於是Windows自動重開後SAVEDUMP再跑出來吃RAM,接著Service因記憶體不足又再Blue Screen... 好個無間地獄~~~ orz

聽完以上的鬼故事,我想你應該會像我一樣(**不會分析Memory Dump File**),現在就去把Windows的System Failure Memory Dump功能關起來。

【延伸閱讀】微軟關於Memory Dump的完整說明

【Update @ 2007-07-31】

有高人路過小站,特別指點了一下,原來開機後的SaveDump是在處理當機前留在PageFile中資料。謝謝someonepoor賜教!
另外,順便補充一點,朋友Steve寫了一篇關於IIS Crash Dump分析工具的Post。這年頭好用的分析工具愈來愈多,真是茶包射手們的一大福音。

KB-Inside SQL 2005 Maintenance Cleanup Task

之前我有介紹過在SQL 2005的維護計劃中,若要清除過期檔案得另外加設Maintenance Cleanup Task

後來接到網友回應,提到資料庫備份到獨立子目錄時(Create a sub-directory for each database)的清理問題,由於原先也沒深入研究過,就順勢剖析了一下Maintenance Cleanup Task的原理。

下圖是Maintenance Cleanup Task的設定畫面,如果你備份時選取了Create a sub-directory for each database,在此就要加選"Include first-level subfolders"。

勾選後,SQL 2005會逐一清查X:\Backup下的各個子目錄,尋找其中過期的bak檔加以刪除。

我們可以用Process Monitor證明這一點! 下圖中,橘色區是選取"Include first-level subfolder"的情形,sqlserver會逐一檢查X:\Backup下的msdb, master, model(搜索範圍甚至到了由其他程式建立的Mail資料夾,不過我測試的結果,它會識別備份檔的命名規則,不致濫殺無辜)的*.bak,下方黃色區則可看出sqlserver只檢查了X:\Backup\*.bak。測試的結果

Maintenance Cleanup Task的設定畫面中,有個View T-SQL,按下後可以發現清理工作其實是由一隻文件沒記載的Stored Procedure所執行的:

EXECUTE master.dbo.xp_delete_file 0,N'X:\Backup',N'bak',N'07/13/2007 08:00:00',1

Include first-level subfolders選項會決定後方是否加上參數1。知道了原理,我們還可以衍生一些花式用法,例如: 只保留八小時的檔案之類的,哈!

QUIZ: 奧妙的國中先修班數學題

就是這題!! 明明是國中先修班的數學題目,卻讓三、四個具備大學、碩士學歷的資訊從業人員在深夜解題解到滿身大汗...

[答案近期揭曉! 我已經押了賭注了,緊張緊張...]

Posted 11 July 2007 10:14 AMJeffrey | 8 comment(s)
Filed under:
TIPS-Web Page with Mixed Client Script Languages

今天同事回報一個問題。

我之前寫的控件,會Render一段<script>(ASP.NET 1.1時代寫的,當時年紀小,沒宣告language也沒宣告type)。同事在<head>區加入了一段VBScript後,VBScript執行正常,跑到後方<script>中的Javascript時IE就出錯了。

由錯誤訊息看起來,應是IE遇到第一個<script> Block是VBScript,就把預設Client-Side Script Language設成VBScript,導致沒加註type/language的Script Block也被當成VBScript解讀。在之前處理木馬問題時,我們就見識過這個自作聰明的特性,而在HTML 4.01的規格之後才能強制宣告Client-Script Default Language。

所以以下的HTML在IE裡是會出錯的。

<html><head>
<script type="text/vbscript">
MsgBox "Test1"
</script>
<script>
alert("Test2");
</script>
</head><body>
Mixed Client-Script Language Test
</body></html>

要怎麼解決? 改控件在<script>上加註type是比較斧底抽薪的正解;如果想鋸箭,在VBScript Block的前端插個隊,再塞一個Javascript Block先佔先鸁,也是可行的。

更多文章 下一頁 »

搜尋

Go

<July 2007>
SunMonTueWedThuFriSat
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234
 
RSS
【工商服務】
最新回應

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


BlogLook Score and Rank

Syndication