自從Steve Jobs於數年前讓智能電話降臨於世上後,整個IT程式開發環境改變了不少。他令到大家發現,原來程式不一定要在辦公室內,或家居內的笨重電腦內執行。大家的褲袋或手袋內亦可執行媲美於笨重電腦上執行的程式。要行client-server base嗎?只要你能連上Wifi或mobile data (不論GPRS/EDGE/3G/4G/LTE...) 亦可。
於是乎,不論是為了gimmick,還是實際需要,大小企業紛紛一窩蜂地推出不少mobile app去搶山頭,又,因為有了不少app去令到智能電話功能再次強大,於是又有一班人去投入智能電話懷抱。商家們有眼見用家潛能不容忽視,又一窩蜂地推出不少mobile app...(之後不斷loop)總之,市場上寫app變成了主流。
奈何大部份人,卻忘記了環境因素,尤其以i字頭的更甚。
從前您大概可以寫好環境規格,基於電腦更新週期長,基本上一個系統無事無幹你都可以用三五七年,到要換電腦時,系統亦都可以到期revamp了。
寫web的話亦大同小異,只要鬥快處理好IE問題的話,大不了便叫用家不要用IE,或者不要把IE更新吧。
但mobile app呢,先說i字頭,OS更新週期短,而且話改就改,亦不大可能叫用家為了你而去不作出更新,去放棄一大籮未必有用的新豬頭骨functions。至於綠色機械人,機多,再加上version fragmentation問題,與及每間設備廠商均對OS作出『優化』,結果這部機夾這個版本行得。不少人就是欠缺這方面的思維,再加上不願理解平台特性,與及budget考慮,只用模擬器,或寫個wrapper去包住個webpage,結果app的質素難有保證。(幸而當年錢途無限,只計iPad都有十數部,再加上五六部Android device,與及某廠商願意借出不少未出街的device,方能製作到個勉強合格的app。)
因此,大部分公司,只懂急急出一個app,卻不懂去維護一個app,更不明白寫app其實是被兩大巨頭與廠商牽著鼻子走。到頭來,大多在半年後,留下來的,就只有一堆垃圾app。
Showing posts with label Development. Show all posts
Showing posts with label Development. Show all posts
Tuesday, September 16, 2014
Monday, October 24, 2011
Load 唔起 ScriptResource.axd
背景
剛deploy了一個用.net framework 4.0寫好的Web Application上測試server,之後,負責測試的同事告知我個Menu唔識得drop down
Javascript error ???
見個Browser左下角有個黃色三角形,看來是load個page時出現error,大概是有些file 未能成功download。開Fiddler一看,完來load ScriptResource.axd發生404 not found這個錯誤。
Google了一下之後,發現大部份website都長篇大論講話係server config問題,只有一個website提到了一個keyword - Server Time。
再查看一下,因為測試需要,同事們經常要將server時間更改來做一些時間有關的測試。
Solution
雖然沒有甚麼網頁有詳細解釋到,不過我估個問題大概是,假如server time係早過個web application個binary的file date time的話,問題就會出現。因此,要解決這個問題,只要不好將server time時間改在binary的file date time前即可。
剛deploy了一個用.net framework 4.0寫好的Web Application上測試server,之後,負責測試的同事告知我個Menu唔識得drop down
Javascript error ???
見個Browser左下角有個黃色三角形,看來是load個page時出現error,大概是有些file 未能成功download。開Fiddler一看,完來load ScriptResource.axd發生404 not found這個錯誤。
Google了一下之後,發現大部份website都長篇大論講話係server config問題,只有一個website提到了一個keyword - Server Time。
再查看一下,因為測試需要,同事們經常要將server時間更改來做一些時間有關的測試。
Solution
雖然沒有甚麼網頁有詳細解釋到,不過我估個問題大概是,假如server time係早過個web application個binary的file date time的話,問題就會出現。因此,要解決這個問題,只要不好將server time時間改在binary的file date time前即可。
Thursday, September 3, 2009
ORA-12154: TNS:could not resolve service name
背景
尋日deploy了一個用C# (.net framework 2.0) 寫的server-side program仔,用作將MSSQL + FoxPro的data抽去Oracle。C# program是用System.Data.OracleClient來連接Oracle的。UAT時無問題,不過上了production後,就發現個execution log 出現了ORA-12154: TNS:could not resolve service name這個error
尋日deploy了一個用C# (.net framework 2.0) 寫的server-side program仔,用作將MSSQL + FoxPro的data抽去Oracle。C# program是用System.Data.OracleClient來連接Oracle的。UAT時無問題,不過上了production後,就發現個execution log 出現了ORA-12154: TNS:could not resolve service name這個error
Tuesday, August 18, 2009
FULL OUTER JOIN
背景
改完某個page,發現load個page時慢到嚇死人,睇返個logic,個bottleneck係有條stored proc行得好慢
邪惡的FULL OUTER JOIN
原來條stored proc入面的query用了FULL OUTER JOIN
Solution
因應情況而嘗試改用UNION ALL,結果係execution plan經已看到,而execution time亦由50s 減到1s

結論:FULL OUTER JOIN 真的很邪惡
改完某個page,發現load個page時慢到嚇死人,睇返個logic,個bottleneck係有條stored proc行得好慢
邪惡的FULL OUTER JOIN
原來條stored proc入面的query用了FULL OUTER JOIN
Solution
因應情況而嘗試改用UNION ALL,結果係execution plan經已看到,而execution time亦由50s 減到1s
結論:FULL OUTER JOIN 真的很邪惡
Tuesday, January 13, 2009
食Excel
背景
近期寫了個module係去食user一個upload的Excel,再將D data process過後放入DB。
基於flexibility及re-usability,我就寫了個C# function將個Excel transform 落 System.Data.DataSet入面,個logic大概係咁:
GetSchema("Tables")
請求user提供那個excel後,行debug mode看,才發現當我用GetSchema("Tables")去get個list of worksheet時,有很多很多不知名table走了出來,Google後發現該是一些user於excel行filter後留下來的working temp worksheet。不過,基於MSDN並無提及到對個Excel 用GetSchema("Tables") return 回來的data有任何詳細的解釋,結果唯有在各forum的提示下,用一個不大安全的方法去做個workaround。
Solution
首先,經GetSchema("Tables")而穫得的table 名是在worksheet 名加上"$",在各Forum提示下,這類working temp worksheet個table name的pattern是 worksheet name + "$" + others (like GUID),因此,我就假設,逢table name最尾一個"$" 後有其他字串的話,就會ignore有關table,因此就即是:
最後,本人coding經驗尚未算深,如有錯漏,敬請指正~
近期寫了個module係去食user一個upload的Excel,再將D data process過後放入DB。
基於flexibility及re-usability,我就寫了個C# function將個Excel transform 落 System.Data.DataSet入面,個logic大概係咁:
- 用OleDB開個connection落個Excel到
- 用GetSchema("Tables")去食個Excel個list of available worksheet
- 憑Step 2 return回來的list去用 SELECT * FROM "worksheet name" 去將每張worksheet的全部data放入dataset入面
GetSchema("Tables")
請求user提供那個excel後,行debug mode看,才發現當我用GetSchema("Tables")去get個list of worksheet時,有很多很多不知名table走了出來,Google後發現該是一些user於excel行filter後留下來的working temp worksheet。不過,基於MSDN並無提及到對個Excel 用GetSchema("Tables") return 回來的data有任何詳細的解釋,結果唯有在各forum的提示下,用一個不大安全的方法去做個workaround。
Solution
首先,經GetSchema("Tables")而穫得的table 名是在worksheet 名加上"$",在各Forum提示下,這類working temp worksheet個table name的pattern是 worksheet name + "$" + others (like GUID),因此,我就假設,逢table name最尾一個"$" 後有其他字串的話,就會ignore有關table,因此就即是:
// Get list of available worksheets by using GetSchema
DataTable dtSchemaInfo = conn.GetSchema("Tables");
foreach (DataRow drSchemaInfo in dtSchemaInfo.Rows)
{
if (drSchemaInfo["TABLE_NAME"] is string && Convert.ToString(drSchemaInfo["TABLE_NAME"]) != null && Convert.ToString(drSchemaInfo["TABLE_NAME"]) != string.Empty)
{
// Only handle table ended with $ or $'
string tableName = Convert.ToString(drSchemaInfo["TABLE_NAME"]);
if(!(tableName.LastIndexOf("$'") > 0 && tableName.Substring(tableName.LastIndexOf("$'") + 2) == string.Empty) &&
!(tableName.LastIndexOf("$") > 0 && tableName.Substring(tableName.LastIndexOf("$") + 1) == string.Empty))
continue;
// Select all data from the worksheet
DbDataAdapter adapter = factory.CreateDataAdapter();
adapter.SelectCommand = conn.CreateCommand();
adapter.SelectCommand.CommandText = string.Format(TEMPLATE_SQL_GET_ALL_DATA, tableName);
try
{
adapter.Fill(_dsExcel, tableName);
}
catch
{
;
}
finally
{
adapter.Dispose();
}
}
}
最後,本人coding經驗尚未算深,如有錯漏,敬請指正~
Friday, December 5, 2008
實戰 - 將ASP.net的Web Site Project轉為Web Application Project
以下例子只適合MS Visual Studio.net 2005
最近因為工作關係,要將個做緊的Project從Web Site Projcet (唔駛compile)變成Web Application Project (WAP, 要compile)。其實,MSDN本身都有Web Site Project轉為Web Application Project的walkthrough,不過下面講的會係concern埋Source Control(用VSS)的問題。
因為根據Guideline,我係要先獨立地起一個新的Web Application Project先,再將Web Site Project D file再clone過去,再行conversion wizard。因此個source control 係convert完之後就因為當個Web Application Project係新Project,而會當D files 係新的,因此舊有的change history就會無左。
為避免這個情況,又唔見有現成的solution,我就唯有自行研究解決方法:
改Solution file(.sln)
Solution file 是用作控制一個solution入面D Projects的relationship,setting及source control。
因為Web Site Project無csproj file 去store一些有關它自己的設定,因此我們在轉做Web Application後便要人手改動這個file,去通知個solution個Web Site Project已轉為一個Web Application Project。
建議找一些file comparision tools去幫幫手compare新舊兩邊project 的solution file,可事半工倍
最近因為工作關係,要將個做緊的Project從Web Site Projcet (唔駛compile)變成Web Application Project (WAP, 要compile)。其實,MSDN本身都有Web Site Project轉為Web Application Project的walkthrough,不過下面講的會係concern埋Source Control(用VSS)的問題。
因為根據Guideline,我係要先獨立地起一個新的Web Application Project先,再將Web Site Project D file再clone過去,再行conversion wizard。因此個source control 係convert完之後就因為當個Web Application Project係新Project,而會當D files 係新的,因此舊有的change history就會無左。
為避免這個情況,又唔見有現成的solution,我就唯有自行研究解決方法:
- 於VSS 拿最latest的full source,並確保每一個ASPX 的 code behind及App_Code folder內的class都係belongs to 一個正確的namespace (因為Web Site Project default係不用define namespace),如果不是的話就改到係為止。
- 改完code就 compile行下,看看有無問題。將改好了的file check in。
- 將整個Web Site Project 與及 Solution file check out
- 關閉 VS.net
- Backup整個solution file
- Copy 一整套 solution 到另一個folder
- 用vs.net 開啟copy了出來的那一套solution,於VSS選項內unbind全部Project及solution
- Save and Exit VS.net
- 以Command prompt將Step 7的solution folder入面全部files 的attrib -r -h -s,並delete全部source control file (.scc, .vssscc)及excluded file (.exclude)
- 開返step 6個file,如出dialog問係咪唔做source control的話就選"是"
- 確保個solution去到呢個moment都行得
- 跟MSDN walkthrough做conversion,並確保App_Code folder經以改名,再於solution內delete整個Web Site Projcet。
- 試Build及試行個system,唔得改到得(記得include reference)
- 行得smooth後close個VS.net
- 以Explorer或其他方法,總之就不要在VS.net或VSS內,於有source control的那套solution內,delete Web Site Project 個folder內全部file
- 將Step 13那個solution內的files copy 落於有source control的那套solution內原 Web site project 的那個folder內
- 改Solution file (見下文)
- 以VS.net開啟Merge好後的solution,這時,在solution explorer內該可見到個Web Site已轉了Web App,並可看見新加的designer.cs files
- 試Build及試行個system,唔得改到得(如果Step 13試好的話該無問題,否則可能copy漏file,這時就只好restore backup)
-- Point of no return -- - Check In全部files,並關閉VS.net
- 於VSS內該可看到有不少file個 status 仲係 Check Out,manually remove這些files
- 開返個Merge 好的solution,再get latest並在試Build及試行個system,如果有問題的話好大可能是App Code folder未被delete
- ~完~
改Solution file(.sln)
Solution file 是用作控制一個solution入面D Projects的relationship,setting及source control。
因為Web Site Project無csproj file 去store一些有關它自己的設定,因此我們在轉做Web Application後便要人手改動這個file,去通知個solution個Web Site Project已轉為一個Web Application Project。
建議找一些file comparision tools去幫幫手compare新舊兩邊project 的solution file,可事半工倍
- 1. 第一個difference該是一個以"Project"一字做頭的section,如在行Web Site Application的solution file會見到
Project("{E24C65DC-7377-472B-9ABA-BC803B739999}") = "C:\...\Web\", "Web", "{63B50FD7-F0B7-4E2E-B4C8-B3AD4A3B9999}"
Web Application 的是
Project("{E24C65DC-7377-472B-9ABA-BC803B739999}") = "MyCompany.MyProject.Web", "Web\MyCompany.MyProject.csproj", "{6991311F-FDEA-4F4E-A776-CE835AA59999}"
當要merge這段的時候,要更改"="後的那段string,最後的GUID其實就是Web Project的GUID;
Debug/Release.AspNetCompiler* 的那幾行,新那邊無的話可直接移走舊solution的那幾行 - 第二個difference該是下列的一段
SccWebProject[n] = true
SccProjectUniqueName[n] = Web
SccLocalPath[n] = .
SccProjectFilePathRelativizedFromConnection[n] = Web\\
SccProjectEnlistmentChoice[n] = 2
[n]是一個數字
在舊Solution中可移走下列兩行
SccWebProject[n] = true
SccProjectEnlistmentChoice[n] = 2
並將SccProjectUniqueName 改做跟新Solution file的那個"......Web.csproj" - 第三個difference該是下列的一段
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{63B50FD7-F0B7-4E2E-B4C8-B3AD4A3B9999}.Debug|.NET.ActiveCfg = Debug|.NET
{63B50FD7-F0B7-4E2E-B4C8-B3AD4A3B9999}.Debug|.NET.Build.0 = Debug|.NET
{63B50FD7-F0B7-4E2E-B4C8-B3AD4A3B9999}.Debug|Any CPU.ActiveCfg = Debug|.NET
...
EndGlobalSection
將整段setting由新solution copy 入舊solution - Save
Tuesday, December 2, 2008
Web Site vs Web Application project in Visual Studio.net
今日講開VS.net (2005/08)的 Web Site v.s. Web Application,於是就Google了一輪...
MSDN - Introduction to Web Application Projects
http://msdn.microsoft.com/en-us/library/aa730880(VS.80).aspx
MSDN - Web Application介紹
http://msdn.microsoft.com/en-us/asp.net/aa336618.aspx
有關Web Site v.s. Web Application 的blog
http://maordavid.blogspot.com/2007/06/aspnet-20-web-site-vs-web-application.html
http://www.compiledthoughts.com/2008/05/web-site-vs-web-application-project.htmlhttp://petesbloggerama.blogspot.com/2007/05/web-site-project-or-web-application.html
其實看過網上大部份討論,都是比較一面倒支持Web Application instead of Web Site,原因綜合來說可以歸納位:
最後,都係那句,本人coding經驗尚未算深,如有錯漏,敬請指正~
MSDN - Introduction to Web Application Projects
http://msdn.microsoft.com/en-us/library/aa730880(VS.80).aspx
MSDN - Web Application介紹
http://msdn.microsoft.com/en-us/asp.net/aa336618.aspx
有關Web Site v.s. Web Application 的blog
http://maordavid.blogspot.com/2007/06/aspnet-20-web-site-vs-web-application.html
http://www.compiledthoughts.com/2008/05/web-site-vs-web-application-project.htmlhttp://petesbloggerama.blogspot.com/2007/05/web-site-project-or-web-application.html
其實看過網上大部份討論,都是比較一面倒支持Web Application instead of Web Site,原因綜合來說可以歸納位:
- Better Project/Source Management
- Better Consistence across the code
- Better Performance - Binaries are pre-compile
- Easier Deployment and better protection against un-intented code change
當然,Web Site 是否一無是處呢,這個我不敢說,不過在我角度而言,我就見不到有任何理由要用Web Site了。
Thursday, November 20, 2008
CalendarExtender 出現 script error
背景
Visual Studio 2005 (.net framework 2.0) + AJAX Control ToolKit
用了Calendar Extender 做了一個要入Date的Search screen.
Visual Studio 2005 (.net framework 2.0) + AJAX Control ToolKit
用了Calendar Extender 做了一個要入Date的Search screen.
個Calendar Extender的主要目的就是容許user按下月曆旁的icon去算擇日期。
'null' is null or not an object
不過,當個user係全keyboard input的話,只要根住呢個sequence去做,就會出現javascript error:
- Date From 輸入一個日期(e.g. 01/01/2008)
- Tab 落下一個control
- Tab Back 返去Date From,再輸入一個同Step 1不同年份的日期 (e.g. 01/01/2009)
- Javascript error
Search過之後,在這個ASP.net 個 forum查到原來係因為CalendarExtender裡面係假設user只會以Calender輸入日期,而不會以keyboard direct input日期,而在轉年份時,因為CalendarExtender段script會企途refresh個Calendar,因為在純keyboard input的情況下,個calendar根本未被render,因此就出現error 了。
Solution
在Ajax Control Toolkit個 Issue Tracker (#12051) 發現了同樣的問題,並據稱而在新的release解決了個問題。
(原來currently用緊1.0.10618.0)
Saturday, November 15, 2008
DOM appendChild
背景
近日將D blog遷移到用埋Blogger Server去host,於搬Travel Blog其間,就趁機執一執個Map effect的Javascript,等我可以用blogger的Layout中的Html/Javascript widget就可以加到同initialize到D visual effect.
那自然,一些牽涉到加一些新DOM element的event便改了在[body]入面行,如我有一個function做:
function createObject(){var newDOMObj = document.createElement("div");...document.body.appendChild(newDOMObj);}
我就打算用下面的code去行呢個function
[body]...[script]createObject();[/script]...[/body]
自己一向用Firefox 3同Chrome做development,試過,無問題wor,點知一去到IE,無論係IE6定IE7,都出fatal error,連頁面都出唔到。
appendChild
經過Google一番後就發現,係[body]入面做appendChild時,因為個DOM structure跟本未ready,因此如果在那時就新加一些element落個DOM入面的話,就會有可能有問題(今次來說,就是IE有問題)。
Solution
自己因為工作上會用到YUI,結果我就用了YUI Event Utility 中的onDomReady去解決呢個問題,如:
[body]...[script]YAHOO.util.Event.onDOMReady(createObject);[/script]...[/body]
在更改以後,因為body.appendChild的動作會被延後到整個[body] tag render好後做 (實際上,等同將createObject()變成再body.onLoad時執行,因此問題就得以解決了。
最後,本人coding經驗尚未算深,如有錯漏,敬請指正~
註:因為Blogger唔可以係文章入面由〈body〉呢個tag,因此我將< > 變成 [ ]
Monday, November 3, 2008
VS.net 中 DataSet 個 namespace
背景
IDE: VS.net 2005
Source Control: VSS
Language: C# (.net framework 2.0)
今日寫好了一個新的module,Compile行過無事後便將D code Check In。之後再將成個Project Get Latest一次來試,以便試下個新module會不會和同事做的改動唔夾。
Get Latest下來之後,我便立即將個Project Compile,不過IDE就不斷出Warning話有個DataSet (Class) declaration不見了,因此無法將個Project compile。經過一輪目視debug後,終於發現到問題所在,就是錯namespace。
錯namespace
IDE: VS.net 2005
Source Control: VSS
Language: C# (.net framework 2.0)
今日寫好了一個新的module,Compile行過無事後便將D code Check In。之後再將成個Project Get Latest一次來試,以便試下個新module會不會和同事做的改動唔夾。
Get Latest下來之後,我便立即將個Project Compile,不過IDE就不斷出Warning話有個DataSet (Class) declaration不見了,因此無法將個Project compile。經過一輪目視debug後,終於發現到問題所在,就是錯namespace。
錯namespace
簡單點來說,每一個Class都係屬於一個namespace。當我係個Project內create DateSet時,VS.net 會以Project + DataSet個fille所屬的folder來allocate一個namespace比個DataSet,就好似如果我係 JohnShum 呢個Project 內的 \MyDataSet\Blog 起一個叫 Testing 的 DataSet,那Testing 這個 DataSet 就會 belongs to JohnShum.MyDataSet.Blog,當我要refer呢個DataSet,我一係就 JohnShum.MyDataSet.Blog.Testing ,一係就係code header那處加 using JohnShum.MyDataSet.Blog;
至於為何compile唔到個Project?從目視debugging後我估計是因為他發覺了個DataSet應該要belongs落另一個namespace,因此就用了copy and paste方法將個source files 搬落另一個folder,卻無為意其實個namespace係無改到的。又,因為呢個operation應該不會trigger到令VS.net去recompile個DataSets 的Project,因此問題未有即時被發覺。
Solution
好,原因找到了,如何解決才是重點。
對於以上的問題,解決方法看來十分即接,就是將Testing這個DataSet的namespace改好。不過問題是,如何改呢?因為改system generate 的Designer.cs 係唔recommend的。
其實好簡單,係IDE 入面Drag and Drop 過一次即可。
至於為何compile唔到個Project?從目視debugging後我估計是因為他發覺了個DataSet應該要belongs落另一個namespace,因此就用了copy and paste方法將個source files 搬落另一個folder,卻無為意其實個namespace係無改到的。又,因為呢個operation應該不會trigger到令VS.net去recompile個DataSets 的Project,因此問題未有即時被發覺。
Solution
好,原因找到了,如何解決才是重點。
對於以上的問題,解決方法看來十分即接,就是將Testing這個DataSet的namespace改好。不過問題是,如何改呢?因為改system generate 的Designer.cs 係唔recommend的。
其實好簡單,係IDE 入面Drag and Drop 過一次即可。
最後,本人coding經驗尚未算深,如有錯漏,敬請指正~
Friday, October 31, 2008
程式設計師的格言
近日係某個forum度見到這篇『程式設計師的格言』,身為日日寫code的我真係有不少共鳴。就好似...
5. 程式碼不要在開發現場寫! 去客戶那寫!...
這令我想起第一份工,每次上site做deployment都等同上site做coding~~
14. 付錢愈計較的客人愈囉唆。
這令我想起第一份工的X太,同埋上一份工的EM, SL (唔指名道姓了~)
17. bug過了一晚可能就變成規格了。
當一個bug 係個system一段日子,那個bug就變成了feature。當你有朝一日走去fix呢個bug,user就會話做mud無咁個feature,個system有bug (此乃真人真事,聞說當年改緊code時發現有個validation routine 根本無行,執好之後,user偷唔到雞,做唔到野,結果...我地最後要enhance個bug ...)
64. 啊,那是微軟的規格。
這個excuse用了一次,就係話說user要係個system度抽data落excel,再寫個Macro將d data轉做Pivot Table。不過原來Excel 97有個limitation,令到假如raw data太多,個轉Pivot Table 的Macro就會行不到,微軟的solution就是叫你upgrade X_X
假如你是一個IT人,你好可能會對那篇格言另有體會~
5. 程式碼不要在開發現場寫! 去客戶那寫!...
這令我想起第一份工,每次上site做deployment都等同上site做coding~~
14. 付錢愈計較的客人愈囉唆。
這令我想起第一份工的X太,同埋上一份工的EM, SL (唔指名道姓了~)
17. bug過了一晚可能就變成規格了。
當一個bug 係個system一段日子,那個bug就變成了feature。當你有朝一日走去fix呢個bug,user就會話做mud無咁個feature,個system有bug (此乃真人真事,聞說當年改緊code時發現有個validation routine 根本無行,執好之後,user偷唔到雞,做唔到野,結果...我地最後要enhance個bug ...)
64. 啊,那是微軟的規格。
這個excuse用了一次,就係話說user要係個system度抽data落excel,再寫個Macro將d data轉做Pivot Table。不過原來Excel 97有個limitation,令到假如raw data太多,個轉Pivot Table 的Macro就會行不到,微軟的solution就是叫你upgrade X_X
假如你是一個IT人,你好可能會對那篇格言另有體會~
Subscribe to:
Posts (Atom)
