2012年6月27日 星期三

[轉貼] Business or Geek?

原文


這個話題來自於華蟒用戶組郵件列表2010年1月的一個貼子,因為我本身不是該組的訂閱者,最近無意中搜索到,覺得有點意思就分享一些想法。
通常想創業的同學應該也遇到過這樣的一些情況,你有一個想法需要想集思廣益地跟大家分享討論,以便*期待*得到更多的人認同,從而再去推進行動。這裡的討論也由一位叫sliuqin的同學展開,他希望跟老婆想要做一個賣茶的電子商務網站:
*關於我們*: 目前,我們分別在兩家大型的電子商務公司做*前端開發*,工作2年了。朝九晚六的工作雖然挺安逸,但不是自己想要的,對!我們想創業了。


*創業項目*: 獨立電子商務網站,主營:茶葉和茶葉相關商品。
*項目優勢*: 老爸是開茶葉店的。
*項目開發:* 週期:10個月 人員:
- 我,負責網站後台開發(Ubuntu server + python + django) - 我老婆,負責前端開發,用戶體驗和視覺設計。
項目資金:10w,包含我們一年的生活費,和後期的服務器等,吃住在家裡(做寄生蟲)
現在我們開始了一部分工作,但是是公司工作之餘,我們兩個人的人生經歷還少,我本身也沒有做過專業的python開發,所以想聽聽大家的意見:這個計劃*可行嗎* ? 但這裡討論的不是這個項目是否可行,我想說的如同以下兩位
  • @john :  「你是想賣茶葉啊,還是想賣網站?」
  • @誠子 : 「business or geek?」
這真的值得作為開發人員要創業時仔細想一想,我也總會走進這樣的一個誤區,到底是在為了一項生意還是因技術追求而做呢?而且這種情況往往更多的發生在技術人員向產品轉型的人群,他們會以技術的角度去衡量一個項目,到底是用.net還是Java,是用HTML5還是HTML4,是使用Django還是Webpy等等……而忽略了去判斷商業的本身,商業計劃可行嗎?盈利模式可靠嗎?目標受眾呢?如何推進呢?…….

Business是事業,geek是愛好。當然,我從不認為純技術流不能創造一家賺錢的互聯網公司,這樣的公司在互聯網行業中俯首皆是。而且還有部分互聯網公司出現的時候就不知道該怎麼盈利,也就總會有聽到說:「等我們的用戶數足夠大了,我們就會想到盈利方式。」但如果我們認為這些創業者們沒有想過怎麼去「Business」的話,那我想一定是我搞錯了一些東西,他們有想,他們有想得到的某個固定人群,通過技術和人群建立競爭壘壁,爭奪人群本身就是一項「商業」。所以他們選擇了快速開發讓市場去驗證終端需求,而絕對不會在技術的選擇上浪費太多的時間。
繼續拿<REWORK>說事,」start with business, not a startup」說的就是這個意思,從一開始就想辦法賺錢,行動起來!別用10個月時間+不熟悉的python來做一個電子商店了,架個開源網店就開賣吧,兄弟。
  • 問某遊戲公司CEO:「你們都用什麼技術?」答:「沒關係,用最熟悉的PHP。」
  • 問手機遊戲開發者:「如何切入移動開發,iOS or Android?」答:「Android,因為我熟悉Java 。」
但話說回來,如果目的就是為了學習一門技能或公司沒有生存壓力下,我個人喜愛並推崇項目嘗試使用最新的技術,而不是固步自封。

[轉貼] 為何我們要從Node.JS遷移到Ruby on Rails

原文

聲明:這篇文章絕不是一篇討論Node.JS和Ruby on Rails孰優孰略的檄文。它描述的只是我們做決策過程中的一些思考、決策背後的原因。兩種框架都非常優秀,都出色的完成了它們的設計初衷,這也是為什麼我們部分的模塊仍然運行在Node.JS上的原因。

我是Node.JS的大粉絲,認為這是一項讓人非常興奮的技術,相信它會變的越來越流行。我對這項技術非常的欣賞——儘管我們最近把Targeter App從Node.JS遷移到了Ruby on Rails。
我們當時使用Node.JS開發它的原因很簡單。我有一個程序包,能很快的將我們的應用弄上線(我們花了54小時做這個事情),相比起Ruby,我更常使用的是JavaScript。因為我們的技術架構牽涉到MongoDB,我的這些特長只有在Node.JS環境裡才會有意義。然而,隨著應用規模的增長,我認識到,選擇Node.JS來實現這個應用是個錯誤的選擇。下面讓我來概述一下其中的原因。

Node.JS很適合做那些有大量短生命期請求的應用。對於傳統的CRUD應用,它也很好,但不是非常的理想。在PHP,Ruby,Python語言裡都有很成熟、優化的很好的框架來處理這種應用。Node.JS裡的所有東西都異步執行的理念對於CRUD應用來說沒有任何效果。其它語言裡的流行的框架能提供非常好的緩存技術,你所有的需求都能滿足,包括異步執行。
Node.JS是一種非常年輕的技術框架,它的周邊程序庫都不是很成熟。我說這些並沒有任何對那些代碼捐贈者冒犯的意思,他們很優秀,開發出來很多優秀的程序庫。然而,大部分程序庫需要改進,而Node.JS的這種快速成長的環境意味著每一版升級中都帶有大量的變化;當你使用一種前沿技術時,你十分有必要盡快的緊跟最新的版本。這給創業型的企業帶來了很多的麻煩。

另外一個原因是關於測試。Node.JS裡的測試框架還不錯,但跟Django或RoR平台上的相比還是差一些。對於一個每天都有大量的代碼提交、並且在一兩天內就要發佈的應用來說,程序不能出問題是至關重要的,否則你為此辛苦的努力變得得不償失。沒有人願意花一天的時間改一些弱智的bug。 最後一點,我們需要的是一種能緩存一切的東西,並且要盡快的實現。儘管我們的應用在增長,每秒鐘有上萬次的hits,但絕不會出現很大量的訪問請求;這不是一個聊天程序!主程序最多時也就達到1000RPS,這樣的負載對於Ruby on Rails和Nginx來說算不了什麼。

如果你現在還在讀這篇文章,那你已經看到了我所有要說的了,你也許非常堅持的想知道我們的應用什麼地方還在使用Node.JS。是這樣的,我們的應用由兩部分組成。一是界面,用戶看到的這部分,二是負責報表管理的部分,以及做日誌的功能。後者是Node.JS的一個最佳使用場景,存在有大量的短週期的請求。這部分的動作需要盡快的執行完成,甚至要在我們的數據推送還沒有完成之前。這很重要,當請求執行還未結束,瀏覽器繼續等待響應結束,這會影響用戶使用體驗。Node.JS的異步特性救了我們。數據要麼被存入數據庫,要麼被處理掉,當請求一旦執行完成,瀏覽器就可以開始做其它重要的事情了。

[轉貼] C# Delegate/event 的簡單理解

看這篇前可以先看這篇文章瞭解Delegate的語法與使用方式
本篇原文=================
簡單來說就是增加一層間接層來實現晚綁定,從而獲得更為鬆散的耦合

為什麼要有Delegate? 
假設有兩個不同類實現的對象A和B,A和B分別有方法a和b。現在需要a方法以一觸發,便執行對象B的方法b。 不使用delegate,我們可以在設計A類的時候在將B類作為參數傳入a方法,這樣可以實現我們的要求。但是這樣做有明顯的缺陷:   
    1. 我們需要事先知道B類。   
    2. 如果還存在C類、D類等的方法需要一併執行,這樣必須重新修改A類的代碼。 如果有了  Delegate,我們可以事先設計一個函數指針,這樣當對象A執行a方法的時候,就可以根據該指針指向的,符合該函數指針法則的方法進行執行。這樣,我們就不需要在設計A類的時候知道B類,只需要知道B的b方法的參數和返回值就可以了。如果還有C類、D類方法需要一併執行,也可以添加到該指針指向的數據結構中。


示例代碼分析:
代碼
    class Program
{
static void Main(string[] args)
{
A a
= new A();
B b
= new B(a);
a.Method_A();
}
}


class A
{
public delegate void Delegate_A();
public event Delegate_A da;
public void Method_A()
{
da();
}
}

class B
{
public B(A a)
{
a.da
+= new A.Delegate_A(Method_B);
}
public void Method_B()
{
Console.WriteLine(
"B's method!");
}
}
1. 先看Class A中   
public delegate void Delegate_A(); 這個語句規定了函數指針指向的函數應該符合的規範:沒有返回值,沒有參數傳入。
2. 接著實例化了一個 Delegate_A的對象da,這裡使用event關鍵字表明它是一個事件。 
3. 再看Class B的的構造函數,可見B構造時,往對象a的事件中傳入了Method_B的函數地址(a.da += new A.Delegate_A(Method_B)
4. 在Main函數中執行A對象的Method_A時,觸發了事件da,而da指向了B的方法。這樣即便A對象對B對象一無所知,也同樣能執行B的方法Method_B。這就是Delegate的好處。

Event有什麼用:
實際上在上例中將Event關鍵字刪除程序同樣能執行。之所以要加上Event,是因為在程序編譯時,加上Event以後該Delegate的對象會成為該類的私有成員,這樣外界只能通過 += 和 -=來對Delegate的對象da進行操作,而不能直接進行賦值。

2012年6月26日 星期二

C# 物件配置與記憶體議題

對於實值型別(等同Java中稱的基本型別)一樣是放在stack
在method中也同樣是以複製的形式傳遞
也就是method中作的變動不會影響到原本的實值型別物件
不過若要改變傳遞的形式則可以使用 ref、out 兩個關鍵字

ref的用法為宣告使用call by reference
如:public void swap(ref int x, ref int y){ ... //code for swap x&y }


使用method時亦用ref,如:

int a = 1;    int b = 2;
swap(ref a, ref b);


如此一來a與b的值就會在method呼叫過後改變了
C#在配置物件(參考型別資料)時亦隱含了ref的宣告
所以省略不寫也沒關係
但若明白的了ref宣告
則必須在參數、引述的地方都宣告,否則會引起編譯錯誤,如:

public void dosth(ref int[,] intary){ .... }

int[,] a = new int[]{{1,2},{3,4}}
dosth(ref a);     //如果參數、引數只有其中一方宣告ref會引起錯誤


out關鍵字的作用則是傳出值,如:
public void assignValue(out int x, out int y){
    x = 6;  y = 10;                //必須在method中宣告值
.........
}

int a; int b;                           //未賦予初始值
assignValue(out a, out b);    //此時a = 6, b = 10


不過用法雖然多樣化了,但似乎連Visual Studio Team也不鼓勵ref、out的使用
畢竟若設計師不熟悉用法則容易出錯
一般是建議找替代方法來達成目標

struct的使用可以參考MSDN上的說明-使用結構
使用上有無法繼承與多型的限制,但在僅用來儲存field時會有較class更好的效能
其記憶體配置也是位在stack
所以指派的時候也是使用複製,等同於創造出新的struct
注意這點以避免疏失
而struct作為參數傳遞時,可考慮使用ref,以優化性能(當然這時候要注意值的變化)

C#的class有時候並不提供擴展,如第三方的類別等
要封裝類別只要在class宣告前加入sealed關鍵字,如:sealed class ap{...}
如果打算擴展這些類別,C#提供如下作法:

static class secondAp{
    public static string getAns(this ap apobj, double fi1){...}
}


擴張方法必須是存在於靜態類別中的靜態方法
this ap 指定擴充ap類別

[轉載]強制使用javascript-檢查該頁面是否啟用javascript

原文====================

現在ajax的技術很流行,也用在很多web 2.0的網站上,但該技術是基於使用者端瀏覽器的javascript,萬一使用者把它關閉怎麼辦?還要為它們另外撰寫ajax或javascript特效的替代程式嗎?我不負責任的回答是:不要!

大部份網頁瀏覽器,預設都是啟用javascript,那誰會停用?
第一個是什麼都不懂,不小心關掉的人;第二個是很懂,非常非常在乎安全,或想亂搞的人。 我會和客戶說,這兩類的人,少之又少,又很難搞定,與其多花時間金錢來照顧它們寫替代程式,不如直接告訴它們請啟用javascript再來瀏覽此頁面。 方法很簡單:
在想強制使用javascript的頁面,<head>和</head>間,插入這段通用的tag

<noscript>
     <META HTTP-EQUIV="Refresh" CONTENT="0;URL=JS_Please.html">
</noscript>


如果有人瀏覽這頁面卻未啟用javascript,就會直接轉到JS_Please.html,接著在JS_Please.html上撰寫請啟用javascript的說明,或教不小心關掉的人要怎麼開啟它

後記:
php有個函式是get_browser,原以為是可以檢查瀏覽器所有的狀態,就很高興的拿來試試…沒想到只能得知瀏覽器是否有支援javascript,卻無法得知是否啟用;真是個讓人白高興一場的函式…
網路上還有很多檢查javascript是否啟用的方法和資訊,但大多複雜難用;用noscript來轉頁,是最簡便的方法。

2012年6月21日 星期四

ASP.NET Web Application 離線方式

這是我目前看ASP.NET中覺得最好的功能之一XD
在網站需要進行維護等需離線的行為時
為了避免讓User誤會而可以使用這個功能

只要在Application的根目錄底下建立App_Offline.htm 並將訊息寫在這個頁面即可
只要目錄底下有這個檔案
.NET就會自動將網頁導覽到這個頁面
如此就可以很方便的進行升級

要注意的事項則是網頁大小必須超過512k
且對於根目錄的權限要小心
以免被惡意寫入這個檔案而導致整個Application不起作用

2012年6月14日 星期四

固定ASP.NET程式開發伺服器的Port for web網站

在web application專案中可以使用專案工具控制([專案]>[屬性])
而如果只是建置時選擇web網站的話,則用以下方式解決

step1. 在visual studio的[工具]>[選項]>[專案和方案]>[一般]>取消"永遠顯示方案"
step2.[工具]>[外部工具]>[加入]>輸入以下設定
          標題: sever port:8080       <--隨便打
          命令:C:\Program Files (x86)\Common Files\microsoft shared\DevServer\9.0\
                      WebDev.WebServer.EXE
          引述:/port:8080/path:$(ProjectDir)\
step3.[工具]選項中就會出現剛才輸入的標題,執行以啟動固定的port
step4.在網站上按右鍵>[屬性頁]>[起始選項]>[使用自訂伺服器]>基礎URL輸入
          http://localhost:8080

測試:直接輸入http://localhost:8080/Default.aspx

SSIS 心得與小技巧

SSIS為Microsoft SQL Server裡Business Intelligence的一環
功能是整合各個不同來源的資料
以下環境處理使用SQL Server 2008
注意雖然SQL Server2012提供了轉換的功能來相容2008的檔案
但實際上還是很有可能會發生問題

 SSIS的檔案建立後會是dtsx檔
實際上裡面的內容是XML檔,由SSIS引擎進行實際操作
2008的版本有時候會發生問題是整個專案檔中作了變更
而dtsx檔卻沒跟著做正確變更,特別是在連線相關元件的連線改變時
有時候最好的情形甚至是將用到連線的元件砍掉重練
如果碰到設定應該沒問題卻總是收到SSIS的失敗訊息,那就應該考慮這個作法
假如遇到連線設定一直無法寫入連線元件(通常是連線的密碼)
可以考慮使用全域變數來規避,或是重新開啟SSIS試看看
在我接觸的經驗裡,連線設定是SSIS很弱的一個部分

SSIS開啟時會還原到上次處理時的內容
接著重新驗證載入內容裡面每一個處理過程,其中包含連線到裡面的資料來源
這樣往往使得SSIS在開啟過程花費大量時間而延誤處理
記得關閉SSIS前先關閉目前開啟的每一個dtsx檔

另外開啟SSIS的專案檔可以先做一個設定
上方工具列中的SSIS -> work offline
這樣可以避免SSIS在載入較大的檔案時卡在驗證的流程
當要用到取得網路上的資料時就取消work offine
雖然麻煩了些,但卻是省下時間的一招

雖然SSIS中有Script Component可以用來寫入程式運作
但在維護的考量上,部門鼓勵的處理方式是盡量用SSIS元件進行處理
使用元件能明顯的表達設計的意圖
雖然有時可能會較使用程式的方式來的麻煩,但帶來的好處應該是更多


以下紀錄曾碰過疑問的情境

1.重覆資料判斷處理

情境:想將重覆的資料判別出並寫進log,而不只是用sort工具將多出來的資料刪去
問題:如何判別資料是duplicate instances
解決:先利用derived column 新增欄位,再用aggregate元件裡的count物件來取得
            duplicate instance其數量,再將他寫入新欄位中,用conditional split處理

2.對應空值處理

情境:針對客戶給的資料做預防處理
問題:資料有可能不會有該欄位或該欄位無值
解決:conditional split裡 ISNULL(xxx) 和 TRIM(xxx) == "" 兩條件併用,
            TRIM()是預防給予的資料是數格空白

3.Thread

情境:欲建立物件來處理從data flow中經conditional split分支出來的資料
問題:物件在同時處理兩端不同走向的資料時可能會有multi-thread處理的問題
解決:先利用union all原件將所有要處理的資料先做統整,再用物件處理

4.Thread-2

情境:寫資料進error log碰到前端流程有太多錯誤資料要寫,使後端流程無法取得log檔
問題:手動加入lock控管機制也碰到lock object的取得也有thread上的問題
解決:經討論後直接濾掉前端的錯誤資料以避免整體流程發生錯誤
            實際上SSIS的線程管理是不常看到討論的一環,而且也容易有問題
            有這類需求時再考慮盡量避免掉資料存取衝突的可能,重新設計SSIS流程