2012年6月18日 星期一

讀書心得:Peopleware腦力密集產業的人才管理之道


知道這本書,是從「約耳談軟體」上面看到的
後來跑去書局看了一下,覺得這本書還蠻有趣的
就把這本書買回來了

感覺作者對於管理軟體開發人員的要點,就是...「帶人要帶心
以前我還待在SI公司的時候
對有些事情不太滿意的地方(不過,我可是很喜歡這間公司的),都在這本書上找到了解答
舉個例來說,以前每個星期都要開專案進度會議
全部門的人,待在會議室排排坐,等著主管一個一個點名報名進度
我一直覺得這是個很浪費時間的做法
要掌控專案進度,有很多種方法,沒有必要花費大家的時間來聽其他人的進度
以及聽主管在罵人
每次開會時間,少則半個小時,多則二個多小時
我後來在這本書上找到了解答
作者說明了主管會以這樣的形式開會,是因為某些原因(當然是不要的原因)

除了這個之外
這本書還說明了何謂團隊殺手
哪些是團隊形成的化學因素
甚至辦公室座位的安排..等等
很有趣的一本書
值得從事軟體開發人員買回家收藏,每年都要拿出來看一次





2012年5月9日 星期三

ASP.NET MVC:改變View的charset編碼(Encoding)


最近有一個case是要將資料用post的方式傳給其他業者
其中有一個參數是中文字
而對方系統是使用big5編碼(都西元2012了...)
我們當然是UTF8
這下子有點玩了
看一下我的處理方式

以前在寫php時,只要在程式裡面加了下面這一行
header('Content-type: text/html; charset=big5');
Web Server在產生網頁時,就會以big5編碼

但是asp.net mvc 3呢
我的處理方式是:
寫一個繼承ActionFilterAttribute的class

protected class Big5CharsetAttribute : ActionFilterAttribute
{
  public override void OnActionExecuted(ActionExecutedContext filterContext)
  {
    filterContext.HttpContext.Response.AddHeader("Content-Type", "text/html; charset=big5");
    filterContext.HttpContext.Response.ContentEncoding = System.Text.Encoding.GetEncoding("Big5");
  }
}

重點就是這兩行
filterContext.HttpContext.Response.AddHeader("Content-Type", "text/html; charset=big5");
filterContext.HttpContext.Response.ContentEncoding = System.Text.Encoding.GetEncoding("Big5");
將ASP.NET MVC預設的header和編碼改成big5

然後,Controller的action名稱前面再加上[Big5CharsetAttribute]
例如:
[Big5CharsetAttribute]
public ActionResult AutoSubmitForm()
{
//your code

return View();
}

這樣,這個action就會用big5來產生view

還沒完喔,再來是html的部份
view最好要加上這一行
<meta http-equiv="Content-Type" content="text/html; charset=big5" />

這樣兩個系統就能用中文來溝通啦。
(還是老話一句,現在是unicode的時代...)

2012年5月1日 星期二

讀書心得:序

從開始工作以來
一直保持著喜歡看書的習慣
不過大部份看的都是跟軟體開發有關的書
除了自己喜歡學習之後
深深的感覺到,軟體開發這一行
光有經驗是還不夠的
必須再吸收一些新的東西
因為你可能從前輩身上學到的,也不一定是最好的做法
軟體是會隨著時間的淬練(資料、架構、需求的擴大)
來驗證你所開發的軟體是否經得起考驗
因此必須不斷的吸收新知識,來讓自己前進

不過話說回來,我所看的書,大部份是跟系統分析、開發有關的書
之後有時間,我會慢慢的把看了這些書的心得寫上來
除了方便自己記錄之外
也讓想看這些書的人,做個參考。

2012年4月23日 星期一

C#:convert to ASCII

在C#中,要將字元或字串轉成ASCII code的方法如下

char charWord = 'a';
int asciiCode = Convert.ToInt32(charWord);

string stringWord = "812";
byte[] asciiBytes = Encoding.ASCII.GetBytes(stringWord);

若是char時,直接用Convert.ToInt32()來轉換即可
若是string,則利用Encoding.ASCII.GetBytes()來取得陣列
以812為例,會取得56 49 50

2012年4月20日 星期五

C#:string convert to DateTime


將日期型態轉成字串格式,最常用的就是:
string testDate = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");

但是要將字串轉成日期型態就比較麻煩一點的
可以用DateTime.ParseExact()來處理
假設有一個字串格式為yyyyMMddHHmmss
那麼轉換的code如下


string testDate = DateTime.Now.ToString("yyyyMMddHHmmss");
IFormatProvider cultureStyle = new System.Globalization.CultureInfo("zh-TW", true);
DateTime time = DateTime.ParseExact(testDate, "yyyyMMddHHmmss", cultureStyle);

2012年4月9日 星期一

T SQL: stored procedure讀取XML


這裡記錄一下自己覺得好用的讀XML方法
首先,看一下要執行的SP及傳入的XML參數
Exec sp_TestXML
@prdxml ='<products>
<data>
<id>3</id>
<itemdata>
<itemname>notebook</itemname>
<amount>30000</amount>
</itemdata>
<itemdata>
<itemname>CPU</itemname>
<amount>5000</amount>
</itemdata>
</data>
</products>'


XML的格式說明:
<products>的tag裡,只能有一個<data> tag
但是<data>裡可以有多個<itemdata>
也就是master-detail的格式

再來看一下stroed procedure內容:

Create PROCEDURE [dbo].[sp_TestXML]
@prdxml xml

AS
BEGIN
Select x.value('.','VARCHAR(5)') as id
from @prdxml.nodes('/Products/data/id') as params(x)


Select Item.value('(./ItemName)[1]','VARCHAR(max)') as ItemName
,Item.value('(./Amount)[1]','int') as Amount
from @prdxml.nodes('/Products/data/ItemData') as params(x)


Select Item.value('ItemName[1]','VARCHAR(max)') as ItemName
,Item.value('Amount[1]','int') as Amount
from @prdxml.nodes('/Products/data/ItemData') as Product(Item)


RETURN

END

首先,參數要宣告成xml型態
裡面第一段寫法,是要讀XML的master部份
第二段和第三段寫法,都是要讀detail的部份
只是table的名稱有差異
可以比較一下這三段的From子句
以及Select子句的差別
看自己喜歡哪種寫法







2012年4月5日 星期四

SQL: ISNULL(), NVL(), IFNULL() 函數

在寫SQL語法時
若要將SELECT的欄位由NULL轉為空字串(empty string)
以我用過的三個資料庫的函數分別如下:
Oracle: NVL()
SQL Server: ISNULL()
MySQL: IFNULL()

以SQL Server為例,可以用這樣的語法來將null轉為你要替換的字串
SELECT ISNULL(Column,'')
FROM YourTable

不過,寫了這麼多年的SQL
很少遇到要將欄位的空字串轉為NULL
我是用REPLACE()來轉換
SQL Server的用法如下:
SELECT REPLACE(Column,'',NULL)
FROM YourTable


2012年4月3日 星期二

取得Identity的方法:@@IDENTITY, SCOPE_IDENTITY(), IDENT_CURRENT()

關於取得SQL Server的IDENTITY(識別值),有以下三種方法(可點hyperlink連到MSDN看明細)

上面三種用法也不太一樣
我在寫stored procedure的時候
若需要寫入的資料是master-detail的話
比較常用的是@@IDENTITY
在寫入master之後
可用下面語法來取得寫入master Table的IDENTITY後,再寫入Detail Table
 DECLARE  @TableIdentity  BIGINT


SET @TableIdentity  = @@IDENTITY


若是除了寫入master-detail的table之外
還需要寫入log檔的table
那麼我會用下面語法來取得該Table最後的一筆IDENTITY
再將這個IDENTITY寫入到log檔


SET @TableIdentity  = IDENT_CURRENT('TableName')


因為master-detail有可能會寫入失敗
若使用@@IDENTITY,則會取到null值
而使用IDENT_CURRENT(),會取得原本應該產生的IDENTITY



2012年3月19日 星期一

軟體開發必須做的事之二: 要有issue tracking systme

下面的問題,專案負責人可以在5分鐘之內回答出來嗎?
你負責的專案現在有多少bug還沒改完?
bug發生的趨勢在這個月中,是增加還是減少?
有多少新增需求還沒完成?
完成了多少客戶的需求?

若貴公司有使用issue tracking systme的話
上面的問題一定可以很快的回答出來

不曉得台灣跟軟體開發相關的公司或部門
有多少的比例有使用issue tracking system來記錄bug、requirement、要改善的功能、或是客戶所提問的問題
就我自己以前待過CMMI認證過的系統服務公司
使用的issue tracking system真的是很方便
可以記錄這個bug是如何發生的
可以記錄這個bug的解決過程,以方便下次遇到相同的問題時,可以找得到解決方法
測試人員(或user)跟開發人員對於這個bug的溝通也可記錄在此

講了這麼多使用issue tracking sytem的好處
要真的用過的人,才知道它奧妙的地方在哪
像我之前剛到某家公司任職的時候
主管問我部門有哪些可以改進的地方
我其中一項就是建議要有issue tracking system
當時主管是面有難色的說「這個提議很好
可是要叫別部門的user填問題單在這個系統,恐怕有點困難
而且我們部門也沒那個權力叫user填,他們就要填」
跟我說明了公司的企業文化就是這樣

不過,小小的螺絲釘也是有想挑戰企業文化的時候呀~~~~
心機鬼如我,我找了我們部門的測試工程師
跟他說明了使用這個系統後,對他的好處
他聽了也覺得不錯
他就把這個系統架了起來
自己測到的bug就記錄在上面
而user那邊,我就負責請他們填寫在上面
一開始,他們還是習慣用電話講問題,或是發email過來
不過我最後都會請他們記得在issue tracking系統上面補一筆資料上去

為什麼user會乖乖的去補建一筆資料呢
我想除了他們人真的很nice之外
我也跟他們說:「你這樣發mail過來,到最後還是會忘了我們到底有沒有幫你處理完了沒
或是你會忘記你當時到底是直接電話講,還是發email?
甚至也會忘了當初提了哪些問題
那就乾脆填在這個系統,所有記錄都在上面,問題都解決了
而且我們改完之後,你也可以即時的收到系統寄給你的mail,通知你已經改好了
就這樣,我負責的專案都是以issue tracking系統來管理bug和需求
主管到最後也是在上面看目前有哪些問題還沒處理
不過,我沒聽主管的話,在他心目中應該也黑掉了Orz


最後就我自己使用過的兩套issue tracking
我都覺得很好用
分別是需要收費的JIRA
以及open source的Mantis

大家有什麼問題可以跟我討論
謝謝

2012年3月1日 星期四

ASP.NET MVC如何避免CSRF攻擊

最近在研究web security
其中對於CSRF攻擊的介紹如下



至於在ASP.NET MVC 3 中要如何避免CSRF
可參考對岸朋友的這篇
http://kb.cnblogs.com/page/125667/
主要就是在Action前加上[ValidateAntiForgeryToken]
然後在相對應的view中加上@Html.AntiForgeryToken()
程式在執行的時候就會在cookie中產生一個像下面的token
例如: __RequestVerificationToken_Lw__=VjPo5qgNE7l5QSBoAe6FdD7/7Zh89aTW02jDYiAyJ+RmCxK5/KPMBrvkm8P/1PopvzaV9YvT08DgLNpcGu+ryEMRUNISZfhVlcl7eO3MbvXy68lGxZoR0U6mB/7yRzzPsMQ5HSkcwi7iKZnVzkCkPrSmCY6pYQimniihsxpLqCo=

然後在頁面post給action的時候
會多傳送一個token參數給action做識別
傳送參數如下:
__RequestVerificationToken=OOQLm1dSsAUruZiv1nM0gVr4tEPlxpZM2kTPTJMZGzLJAvv8VGdMqrtB0KwMXu%2BYbQiIkg%2FyNsGwtq%2FcIBSUill9pz4baRKy%2BkkptZiQpdWEy1SzqSHgicQz6T9jZUp2O759QuXTYu%2FWTpHSn6Ho5NQjyM%2Fd4PNRLG5WgUNyg3Q%3

可以利用Fiddler看一下form和cookie的變化。

2012年2月15日 星期三

ASP.NET MVC的cross domain功能

最近在做一個cross domain的功能
需要從A網站的網頁透過ajax到B網站去要資料
A網站和B網站都是公司服務的網站
這種cross domain的需求之前只有用過iframe的方式
不過這次是使用回傳JSONP的格式來達到cross domain的需求

後來找了很多資料,最後是參考到這篇:
Ajax json post to Controller across domains, “not allowed by” Access-Control-Allow-Headers

主要是寫一個回傳JsonpResult的ActionResult
Controller再透過JsonResult來回傳給ajax
而ajax的dataType記得要設定成'jsonp'格式

2012年1月10日 星期二

Jenkins設定schedule build

設定完Jenkins後
大部份的人都會有一個定時將程式build的需求
在Jenkins要設定排程來build專案還蠻簡單的
可從專案job的「設定」->「Build Triggers」,勾選「Build periodically」
依照設定cron job排程的方式來設定你要的時間
例如,你想要每天早上10點和下午4點來build你的專案
可以設定成:

0 10,16 * * *

完全跟linux下設定cron job一模一樣
關於設定cron job的方法
想詳細瞭解的人
可參考http://en.wikipedia.org/wiki/Cron