津津's profile溪流漫话BlogLists Tools Help

溪流漫话

漫漫长路远,冷冷又梦清,雪里一片清醒……

津津 柯

No list items have been added yet.
8/10/2009

激进一点点还是保守一些?

最近觉得 RD 和 QA 是天敌……老是被鸡蛋里挑骨头,而且经常不得不承认,这的确是骨头。

有个比较郁闷的是,对一些需求上不怎么明确的、可算可不算的问题,总被拿另一个项目当参照物:XXX里是怎样的?XXX里做到了,所以也必须做到……有时候看上去更像是 QA 在提需求了。

说实话这让我感到很压抑。进而想到一个基本原则问题——碰到某些用的不太顺手的东西,该果断采用新技术呢,还是沿用原先的一套?后者的好处是,大多数不太好解决的问题,都可以规避掉,因为“原先的XXX也没做到”,而坏处是,要永远这么吃力下去;前者的好处是,可能可以解决掉大多数问题,但是一旦遇到一个不好解决的问题,压力就会很大——谁叫你当初推崇用这个的呢?

有说,“保守是混日子,激进是干大事,自觉得有能力就干大事,没能力就混吧”。是啊,我算什么呀,我何德何能去审视一些不该由我去关心的东西呢?可是呢,老这么混,自己也会觉得意思不大,而且拿XXX当挡箭牌的时候,自己也觉得自己很无耻,这是一个“朝气蓬勃”的人所该有的态度吗?或者……1、3、5保守,2、4、6激进?

突然强烈地感到出来混太早,毕业得太快,灰常灰常后悔最后一个学期没有好好享受清福了……

8/5/2009

Visual Studio 2010 及 C++ 0x、C# 4.0(二)

前面说到 C++ 0x 的 Lambda 表达式,前几天我总是感觉它缺了点什么,但说不出来。
现在觉得可能可以表达出来了。那就是,C++ 中没有明确的“委托”类型。
(为了表达这个概念,又不与 C++ 中已有概念混淆,这里请允许我使用 C# 中的名词。)
 
其实也不是没有,C++ 的函数指针其实就是形式上很精确的“委托”类型。虽然它归根结底却是一个模糊得不能再模糊的普通指针而已,但起码,一个这样的函数放在那里:

void sort(int arr[], int size, bool (*comparer)(int, int));

给人的信息是非常明确且严格的。
但是如上篇所试验,不能像这样传入 Lambda 表达式:

sort(arr, N, [](int a, int b){ return a >= b; });

而只能先定义一个小函数,然后使用:

bool greater_than(int a, int b)

{

    return a >= b;

}

sort(arr, N, greater_than);

但是 Lambda 的引入,不就是为了解决这种小函数的问题的吗?
另外,如果把函数改为

template <typename T>

void sort(int elem[], int n, T comparer); 

这样,虽然(可能)确实可以 sort(arr, N, [](int a, int b){ return a >= b; }); ,
但是实际使用的时候,我却不能知道 comparer 到底要符合什么样的形式。
 
而 C# 中,由于有明确的委托类型存在,这种问题也就不存在了:

delegate bool BinaryIntComparer(int a, int b);

void sort(int[] arr, BinaryIntComparer comparer);

使用的时候:

sort(arr, (int a, int b) => a >= b);

 
所以,对于 C++ 0x 来说,作为语法糖的 Lambda,似乎还不够甜……
 
==============================华丽的分隔线==============================
今天随意看了一下 C# 4.0 的特性。所谓的协变性和逆变性一下子还看不明白。。。(果然 C# 是用来玩设计的)
动态特性倒是理解了一点点:
 

class Plane

{

    public void Fly()

    {

        Console.WriteLine("Plane flies.");

    }

}

 

class Car

{

    public void Run()

    {

        Console.WriteLine("Car runs");

    }

}

 

class Bird

{

    public void Fly()

    {

        Console.WriteLine("Bird flies.");

    }

}

 

class Program

{

    static void LetItFly(dynamic thing)

    {

        try

        {

            thing.Fly();

        }

        catch

        {

            Console.WriteLine("Method \"Fly()\" does not exists.");

        }

    }

 

    static void Main(string[] args)

    {

        LetItFly(new Plane());

        LetItFly(new Car());

        LetItFly(new Bird());

    }

}

 
结果:
Plane flies.
Method "Fly()" does not exists.
Bird flies.
 
我们所折腾的就是被声明为 dynamic 类型的 thing。“thing.Fly();”中的句点后面可以随意写个方法名称,编译的时候不来检查,到运行的时候才检查。
如果没有 dynamic,参数就要被声明为 object,然后根据反射特性,去查询 Fly 方法有没有……
看起来 dynamic 只是把这一堆繁琐的过程省略了。
 
至于网上牛人们说的动态语言静态语言大融合这高度上的东东,我暂时是没有体会到,大概是我动态语言没怎么玩过的缘故吧。。。呃……JavaScript 也是动态语言?我怎么没感觉呢。。。
 
 
 
7/29/2009

Visual Studio 2010 及 C++ 0x(一)

我记得之前下过 Visual Studio 2010 CTP 的,昨晚翻来翻去找不着了,只好重新下过。最新版本 beta1 了。
之前看到过 C++ 0x 的一些新特性,忍不住试一试。
 
首先是 lambda 表达式。网上有很多介绍 C++ 0x 特性的文章,其中关于 lambda 表达式的文章几乎是千篇一律的

std::for_each(v.begin(), v.end(), [](int n) { cout << n << " "; });

比较感兴趣的是 lambda 表达式本身的类型,也就是,上述 for_each 中的第三个参数该怎么声明?
 
试验一:

bool greater_than(int a, int b, bool (*comparer)(int, int))

{

    return comparer(a, b);

}

 

int _tmain(int argc, _TCHAR* argv[])

{

    bool b = greater_than(1, 2, [](int a, int b)->bool { return a > b; });

 

    return 0;

}

 
编译不过:
Error 1 error C2664: 'greater_than' : cannot convert parameter 3 from '`anonymous-namespace'::<lambda0>' to 'bool (__cdecl *)(int,int)'
 
可见 Lambda 表达式不能向下兼容到函数指针。
看了一下 std::for_each 的定义,它的第三个参数是一个 functor。所以,
 
试验二:

template <typename Comparer>

bool greater_than(int a, int b, Comparer compare)

{

    return compare(a, b);

}

 

int _tmain(int argc, _TCHAR* argv[])

{

    bool b = greater_than(1, 2, [](int a, int b)->bool { return a > b; });

 

    return 0;

}

 
编译通过,运行也正确。
 
所以,似乎 Lambda 表达式的本质是 functor?
 
有点怀疑能否进行严格的类型检查在上例中,故意传给 greator_than 一个不实现 operator()(int, int) 的对象,即
 
试验三:

template <typename Comparer>

bool greater_than(int a, int b, Comparer compare)

{

    return compare(a, b);

}

 

int _tmain(int argc, _TCHAR* argv[])

{

    bool b = greater_than(1, 2, [](int a)->bool { return true; });

 

    return 0;

}

 
这里这个 Lambda 表达式只接受一个参数,意味着 Comparer 只实现了 operator()(int),而没有实现 operator()(int, int)。
 
结果:
Error 2 error C2064: term does not evaluate to a function taking 2 arguments
 
突然醒悟了一下,觉得自己灰常灰常土了,C++ 的 functor 应该本来就是强类型的,支持编译期类型检查的吧?
怪不得那些库都抛开了函数指针,而使用 functor 了。
 
==============================华丽的分隔线==============================
 
强类型 enum 似乎 VS2010 里没有实现(据说 g++ 4.4 实现了)?怎么试怎么不行

enum Enum1 : double

{

    a1,

    b1,

    c1

};

 

enum class Enum1

{

    a2,

    b2,

    c2

};

 
都通不过……
 
[待续]
4/1/2009

来了位新主管

从一开始,不知道该不该汇报什么时候汇报工作,到现在刚刚有点习惯了也不怕了
今天来了位未来的新主管,有点怕怕,跟他说话好紧张的说,希望不要留下太坏的印象,bless~
 
3/22/2009

发现其实周末挺忙的

昨天白天把俞老师要的小站给草草做了下,顺便尝试下 ASP 上新的写法。其中最主要的是搞了一段 DBHelper:
 

Class DBHelper

 

    Private ConnectionString

    Private Connection

 

    Private Sub Class_Initialize()

        ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & Server.MapPath(DBPath)

        Connection = Server.CreateObject("ADODB.Connection")

        Connection.Open(ConnectionString)

        DbgPrint("DBOpen")

    End Sub

 

    Private Sub Class_Terminate()

        Connection.Close()

        Connection = Nothing

        DbgPrint("DBClosed")

    End Sub

 

    Public Sub ExecNonQuery(ByVal sql)

        DbgPrint("ExecNonQuery:" & sql)

        Connection.Execute(sql)

    End Sub

 

    Public Function ExecQueryScale(ByVal sql)

        DbgPrint("ExecQueryScale:" & sql)

        ExecQueryScale = Connection.Execute(sql)(0)

    End Function

 

    Public Function ExecQueryReader(ByVal sql)

        DbgPrint("ExecQueryReader:" & sql)

        ExecQueryReader = Server.CreateObject("ADODB.RecordSet")

        ExecQueryReader.Open(sql, Connection, 1, 3)

    End Function

 

End Class

 

Set DB = new DBHelper

 

之后操作起来就方便了些。。。VBScript 的 Class 虽然不强,但还凑合哈
 
郁闷的是,今天收到回复,还要查询、统计,还要界面漂亮。。。晕,过两天再说了,也许又是一周
 
前几天一直在看 SVN 版本库该如何组织。我自去年九月份就在自己机器上给装了个 SVN 服务端,自己用。一直都是一个项目一个版本库的,也没去多想。看到公司里都 trunk、tag、branch,很是奇怪,去查了下才知道。另外,我一直不知道许多项目改放一个版本库里呢,还是分开放。分开放就是不能互相引用了,为了这个看了两三天网上评论。最后决定还是用同一个版本库了,那以前的全部重新组织,到昨天晚上十多点才搞好,除了移文件、删 .svn 目录外,做了 60 次  commit 动作……最后的结果:
 
然后开始构思着,是不是自己搞个小型库出来。以前写过 Vector、String,这两个就很常用了,可以避开 STL 以及 CString。但是仅仅有这个还不够,上次写 xlWarKey 的时候,在 CList 中存指针,为了不每次 detele,简单地包装了一下,这回要写个通用的。于是去查怎么实现 -> 的操作不变性,发现原来 -> 是可以重载的,原来这个就叫“智能指针”……除了这些,又有新的想法了,是不是也得搞个 List,是不是给 Vector 和 List 抽象出 IEnumerable,那么还得搞个类似迭代器的 IEnumerator 了。对,是不是可以实现同一的 foreach?!又去查了下,原来有好事者早就做过这事儿了。到最后,几乎啥也没干,智能指针实现了,foreach 的可行性试过了。觉得这么想下来,这个库可就庞大起来了,那该如何组织呢……回过头来想想,当初的 String 写得也很弱,想要搞得好用一点要写好多,而这些,STL 里不是都有么,干嘛要重复劳动呢?于是找出 C++ Primer 电子书,找 STL 内容看,终于知道除了 vector、list、deque、queue、stack 等外还有 map 和 set。怪不得当初百度GG问我一篇文章里查单词出现次数我说hash但不知道怎么设计这个hash算法后有点小惊讶。他大概在想,这个人连 map 都不知道。。。不过我还是认为,C++ 是 C++,STL 只不过是一个库而已,仅仅是一个库……
 
下午突然想到了很久以前有个电视剧里的什么歌有一句蛮好听的,于是去查七侠五义、三侠五义,最后发现是《救姻缘》,那个我觉得蛮好听的一句是“生生世世,姻缘不断”。
 
昨晚发现了一大堆适合我这种民工吃饭的地方,想不到滨江饭店都开得这么偏僻……
 
周五拍的办公室照片(趁这几天两台电脑在哈,坐在那里好有感觉呀):
 
又没时间做毕设的事了,充实呀充实
 
话说今晚出去吃饭的时候,路边一个四五岁的小MM无端地叫我大笨蛋,!