搬家

2008年7月6日从魏公村举家(人数一)迁往五道口。这一次是来北京后的第五次搬家。一切都还顺利,从此每天又可以步行上班了,感觉好好……

[ 分类: 动态 News ] 由 Pan 发表于 July 8, 2008 12:45 am  固定链接  评论( 2 )

软件使用时间统计

timesnapper对我现在这台笔记本上的软件使用时间做了一个统计,统计周期为一个月,结果如下:
program statistics
可见,在俺的业余时间,使用电脑的主要目的是上网冲浪,占据使用时间的45%(opera+iexplore+ttraveler+firefox+fterm)。其次是开发,占据使用时间的17%(devenv+editplus+pietty),然后是游戏和聊天并列9%(游戏:war3,聊天:qq+msn+skype)。结果和我预想的基本一致,除了感觉游戏有些偏高。

更新20080705:
WebLeOn’s Blog了解到提供类似功能的软件还有WakoopaRescueTime。我正在试用Wakoopa。

[ 分类: 动态 News ] 由 Pan 发表于 June 29, 2008 12:36 am  固定链接  评论( 0 )

有意思的魔方

魔方前段时间微软给技术部送来了几个魔方,办公室就开始流行玩这个东西。有个同事是玩魔方专家,我让他给捎了一个国丙的三阶魔方,花了40人民币,质量很不错,非一般地摊货可比。然后照着教程鼓捣鼓捣,基本也算可以弄全六面,当然都是照着教程一边看一边转的。

魔方的初级玩法一般按六步走:
1.拼好底面和底面的四个棱、四个角。这一步转转就弄会了,非常简单。
2.调整第二层的棱;
3.顶面划十字;
4.对好顶面;
5.调整顶面四角顺序;
6.排列好最后的棱色块。

每一步都有两种算法,但是其实所有的算法都是另一种算法的对角线镜像,转两遍的效果和另外一种是相同的,负负得正嘛:),所以不追求速度的话每一步记住一种算法就可以了。

教程地址:魔方的入门玩法
PDF下载:http://panweizeng.com/download/rubik-tutorial.pdf
为大家都能学好初级玩法,在这里特别免费放出秘笈图纸一张,打印出来每天演练一遍,十日可成。

更新(20080621):
我已经可以脱离教程和图纸完成六面。

[ 分类: 学习 Learning ] 由 Pan 发表于 June 10, 2008 12:16 am  固定链接  评论( 2 )

工作变化

昨天办完了交接手续,正式从凤凰新媒体(www.ifeng.com)离职,如果一切顺利的话,我将在6月初加盟一个做SNS社区的创业团队。

从毕业入职到现在刚好满两年,要离开已经熟悉的人和熟悉的事情,有点感伤。在工作交接的两周时间,每天都恍恍惚惚,好像我是在做梦一样,怀疑自己是不是真的做出了离职的决定。每天都一如既往地按时上班,每天中午聚餐的时候也都和同事们海阔天空的聊天,每天晚上回家才发现距离最后的离职日期又少了一天。

在凤凰的两年,是我职业生涯的第一步。在这两年中我有很多的收获,技术能力和业务经验都有了一些积累,在人际交往方面也有很大的长进(这个方面最大的收获就是要经常站在别人的角度考虑问题)。部门在2006年和2007年都获得了优秀团队的奖励,这是我最值得骄傲的事情。昨天资讯中心的刘老师请我在魏公村的鑫百万吃饭,每人三瓶啤酒下肚之后,得知我在资讯中心的口碑还是比较高的,工作也得到了编辑们的肯定。凤凰所有共事的同学们,多谢了。

离职的原因很简单,我想有一个拼命学习的环境,把技术能再提高一些。那为什么一定要离开凤凰呢?其实我也不算是真的离开,加入凤凰的时候自己注定这辈子是个凤凰人,说不定只是一次暂别。最后祝凤凰新媒体的事业蒸蒸日上,更上一层楼,也希望自己在互联网行业能走得更远。

[ 分类: 动态 News ] 由 Pan 发表于 May 31, 2008 11:41 am  固定链接  评论( 6 )

有意思的lambda表达式

有这么一种场景,有一个Category的实体类对应着一个名为Category的数据库表。Category类中有Name和Path属性,在新建或更新Category对象时要保证这两个属性在数据库中的值唯一。当然你可以在数据库中的Name和Path字段都建一个唯一索引,那如果不采用这种做法应该怎么做呢?最简单的方法就是写两个名为CheckNameValid和CheckPathValid的函数。很明显这种做法不易于维护,比如说当Category类增加其他需要保证唯一的属性或者属性名字需要改变的时候。我的写法如下:

  1. /// <summary>
  2. /// 检查数据库字段中的值是否唯一
  3. /// </summary>
  4. /// <param name="t">Cateroy的集合</param>
  5. /// <param name="func">表达式</param>
  6. /// <param name="isNew">是否是新建Category</param>
  7. /// <returns></returns>
  8. protected bool CheckValid(
  9.                 IEnumerable<Category> t,
  10.                 Func<Category, Boolean> func,
  11.                 bool isNew)
  12. {
  13.     Category c = t.SingleOrDefault(func);
  14.     if (isNew)
  15.         return c == null;
  16.     else
  17.         return c == null || (c != null && c.ID == Convert.ToInt32(ID.Text));
  18. }
  19.  
  20. //调用方法一
  21. protected Func<Category, Boolean> func = null;
  22. protected void Page_Load(object sender, EventArgs e)
  23. {
  24.     func = selectCategory;
  25. }
  26. protected bool selectCategory(Category c)
  27. {
  28.     return c.Name == this.Name.Text;
  29. }
  30. CheckValid(kr.Categories, selectCategory, true);
  31. //调用方法二
  32. CheckValid(kr.Categories, delegate(Category c){ 
  33.         return c.Name == Name.Text;
  34.     }
  35.     , true);
  36. CheckValid(kr.Categories, delegate(Category c){ 
  37.         return c.Path == Path.Text;
  38.     }
  39.     , false);
  40. //调用方法三
  41. CheckValid(kr.Categories, c => c.Name == Name.Text, true);
  42. CheckValid(kr.Categories, c => c.Path == Path.Text, false);

三种调用方法,当然是使用了lambda表达式的方法三最简洁明了。还可以扩展一下,可以把它写成某个Utility类泛型静态方法,专门检查实体类在数据库字段中的值是否唯一,这时Convert.ToInt32(ID.Text)就要抽出来做成一个参数,这里不就写了。

另外在瘦子师兄的点拨下,发现C# 3.0里面有个类似Javascript中prototype的概念,称为扩展方法(Extension Methods),在System.Linq中运用了大量的扩展方法(例如前面例子中的SingleOrDefault)。扩展方法貌似没prototype灵活,比较的例子如下:

  1. public static class Program 
  2. {
  3.     public static void Main(string [] args)
  4.     {
  5.         string s = "Hello World";
  6.         s.Print();
  7.         s.ToString();
  8.         Console.WriteLine(s.ToString());
  9.         Console.Read();
  10.     }
  11. }
  12. public static class Tools
  13. {
  14.     public static void Print(this string s)
  15.     {
  16.         Console.WriteLine(s.ToUpper());
  17.     }
  18.     public static void ToString(this string s)
  19.     {
  20.         Console.WriteLine(s.ToUpper());
  21.     }
  22. }
  1. function A(){this.name = "AA";}
  2. A.prototype = {
  3.     show:function(){ alert(this.name);}
  4. }
  5. var a1 = new A();
  6. a1.show();
  7. //直接覆写A的prototype中的show
  8. A.prototype.show = function(){ alert("modified:"+this.name);}
  9. var a2 = new A();
  10. a2.name = "a2";
  11. a2.show();

对于一个你不能修改源代码的类,可以通过这种方式为它添加方法。但这个只是编译期的(s.Print()翻译成tools.Print(s)),也就是说编译之后是不能通过反射来取得它的,它并不是要扩展类(例子中的String类)中的真正方法,而是某个静态类(例子中的Tools)的静态方法。
具体介绍参见这篇文章Deep Dive on Extension Methods

[ 分类: 学习 Learning ] 由 Pan 发表于 May 25, 2008 4:28 pm  固定链接  评论( 0 )