博客

  • C#研究系列-List<>与ArrayList的几个研究心得及问题(上)

    代码放在gist.github.com上了,看不到的请留言。

    第一个心得,是我看某本书提到,IList用起来要比ArrayList快。

    这里面用到了我上一篇博客提到的高精度计时器 http://sunxiunan.com/?p=1829

    我在开始定义了两个类。
    // public class List : IList, ICollection, IEnumerable, IList, ICollection, IEnumerable
    class CFromList : List{}

    // public class ArrayList : IList, ICollection, IEnumerable, ICloneable
    class CFromArrayList : ArrayList{}
    List和ArrayList的定义在注释中给出,可以看出来其实都差不多。ArrayList只是多了ICloneable,还少了几个泛型接口继承。

    在后面代码中都用Add方法向list中添加int类型数据,然后通过foreach形式枚举数据,注意!枚举部分的代码是有问题的,我们在(下)中会提到。

    这里还要推荐一个非常棒的工具ILSpy,是sharpdevelop开发的,强烈建议dotnet程序员都下载使用。

    我把ILSpy disassemble出来的C#代码和IL代码分别列在后面。注意对于ArrayList的foreach语句,C#形式的代码与源代码有些差别(79到96行),编译器加入一个IEnumerator enumerator2 = cFromArrayList.GetEnumerator();本地变量,另外使用int num5 = (int)enumerator2.Current;这样访问iterator。而且还加入了IDisposable的finally部分。

    再继续看IL代码部分,对于List形式,IL代码没有box装箱指令,而ArrayList在145行有个box指令,这是性能差别之一。
    但是奇怪的是,在枚举部分,ILSpy生成的(以及ILDasm)IL代码,对于ArrayList和List而言,基本上差别不大,一样也有对MoveNext和Current以及IDisposable接口的调用。只不过ArrayList多出unbox和box的指令。

    运行结果如我们所料,List要比ArrayList快不少。

    但是我们在枚举部分的代码是有问题的,我明天在(下)中会介绍。

  • C#高精度定时器,可用于profiling

    如果想准确profiling函数或者代码性能,一个高精度定时器是必备的。
    参考这几个资料吧,
    http://en.wikipedia.org/wiki/Time_Stamp_Counter

    注意rdtsc在多核下的问题
    http://msdn.microsoft.com/en-us/library/ee417693%28v=vs.85%29.aspx

    最好最方便的还是这个函数QueryPerformanceCounter

    jeffz_cn在他的blog中提到另外一种方法,但是不支持windowsXP,而且好像精度上也没有我下面写的这个高。

    要注意的是软件定时器都不是非常准的,只是比较准罢了。另外定时器不要加的太多,需要的几个位置加一下就可。

    实际上,我以前在C++用到的,也是一样的win32函数:


    class HighResolutionTimer
    {
    private bool isPerfCounterSupported = false;
    private Int64 frequency = 0;
    // Windows CE native library with QueryPerformanceCounter().
    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern int QueryPerformanceCounter(ref Int64 count);
    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern int QueryPerformanceFrequency(ref Int64 frequency);
    public HighResolutionTimer()
    {
    int returnVal = QueryPerformanceFrequency(ref frequency);
    if (returnVal != 0 && frequency != 1000)
    {
    // The performance counter is supported.
    isPerfCounterSupported = true;
    }
    else
    {
    // The performance counter is not supported. Use
    // Environment.TickCount instead.
    frequency = 1000;
    }
    Start();
    }

    public Int64 Frequency
    {
    get
    {
    return frequency;
    }
    }

    public Int64 Value
    {
    get
    {
    Int64 tickCount = 0;

    if (isPerfCounterSupported)
    {
    // Get the value here if the counter is supported.
    QueryPerformanceCounter(ref tickCount);
    return tickCount;
    }
    else
    {
    // Otherwise, use Environment.TickCount.
    return (Int64)Environment.TickCount;
    }
    }
    }

    private Int64 _startValue;
    public void Start()
    {
    _startValue = Value;
    }

    public Int64 Stop()
    {
    Int64 stopValue = Value;
    return stopValue - _startValue;
    }
    }

  • 如何学习使用C++一个实用主义者的观点

    最近CoolShell连续发了两篇文字,《如何学习C语言》以及《如何学习C++》。我在twitter发了一些牢骚,因为我也曾经写过一篇《漫谈C语言及如何学习C语言》http://sunxiunan.com/?p=1661 ,文字写的还算用心,可惜反响不是很热烈。

    最近C++社区最大的新闻,毫无疑问就是最新标准终于Final Draft了,C++2011终于有望实现。

    可是,谁会关心呢?

    国内C++译作圈比较出名的就这几个人,刘未鹏PongBa,自从进入微软以后好像更加关注心智方面的研究,关于C++的文字几乎就没了。孟岩http://blog.csdn.net/myan 也是很久没有新博客文字,也少见C++方面的内容。荣耀,好像也是非常低调。最出名的莫过台湾的侯捷老师,他现在忙于企业培训,估计没啥时间写新文字。这些人里面关于C++最新标准的,还是刘未鹏在07年写的C++0X漫谈。

    07年啊!!那时候房价还没有这么高!!物价也没有这么高!!!车也没有这么多!!!路也没有这么堵!!搞C++的程序员你伤不起啊!!!

    瞎扯一下,回到正题。(一个初学者)如何学习以及使用C++

    看完coolshell的文字,以及刘未鹏曾经写过的《学习C++:实践者的方法》http://blog.csdn.net/pongba/archive/2007/12/11/1930150.aspx
    可以发现他们都倾向于这样一种个人觉得并不很好的方式:列书单。

    我在《漫谈C语言及如何学习C语言》也列书单,但不仅仅列书单。一个初学者光靠看书,只能完成学习过程中30%甚至更少的进度。

    想学好C++,能真正把C++用起来,必须要读、写、看、说多种手段多种方法结合使用。

    另外我个人对C++的态度,就是不要学习使用它的全部,把它的基础部分掌握了就好,足够用了。比如模板元编程这种高级话题,初学者不要牵扯过多,以免一叶障目不见泰山。学编程是干嘛的?如果是为了使用,那就学最核心最基本的那些好了。

    在你学习C++之前,先明确自己的目的,为什么要学C++?为什么要用C++?可能是大学老师要你学,可能是公司开发项目需要你学。如果没有目的没有需求,不要用学习C++来折磨自己了,学点英语,学点Python编程都比学C++好玩有用多了。

    学习C++之间,还需要准备一下练习环境。我这里偷一下懒,在《漫谈C语言及如何学习C语言》http://sunxiunan.com/?p=1661 这里提到的开发工具全都支持C++开发,所以你在里面选择一个安装就可以了。在Windows下开发,我建议大家安装VC2010和SP1(怎么搞到?别问我,问迅雷吧),新版本虽然有些慢,但是支持Win7操作系统,对C++标准支持更好。不是像有些人说的2003到2010没啥变化,这种人估计从来不看release note吧?!至于VC6,还是抛弃了吧。

    还有一点想罗嗦一下,C++最好不要作为你的第一门编程语言,选择C语言更适合。首先是你在C语言中学到的东西,基本上在C++都可以用,包括一直遭人唾骂的MACRO宏。另外C语言入门级好书很多。而C++入门级好书不好选。如何学习C语言,看我《漫谈C语言及如何学习C语言》吧,用心点的话,大概需要半年到一年时间就足够了。

    第一阶段,读书。

    建议大家先一次买齐下面5本书,其他书籍不对初学者推荐:

    stanly lippman的《C++ Primer》
    《Effective C++:改善程序与设计的55个具体做法:第3版 》
    《C++标准程序库—自修教程与参考手册》侯捷孟岩翻译
    《More Effective C++:35个改善编程与设计的有效方法(中文版)》
    《C++编程规范:101条规则、准则与最佳实践》

    第一本书非常难选,我这里建议几个候选者,读者可以到书店去翻看一下,哪一本觉得合口味就用哪一本。

    候选者A,钱能老师的《C++程序设计教程(修订版)–设计思想与实现 》 http://product.china-pub.com/46574
    我上学的时候,翻过钱能写的C++书,感觉还不错。至于这一本实话实话我没看过,但是按照国人教学风格应该是一板一眼的。

    候选者B,stanly lippman的《essential C++》,这本书我有,但是感觉不适合作为初学者使用,如果你有一两年编程经验,看看这本书也许还行。

    候选者C,stanly lippman的《C++ Primer》,基本上用这本书入门,应该是比较花费时间的,但也很正统,这本书买了肯定不白瞎。

    我推荐A+C,或者你到图书馆选择随便选一本《C++设计教程》作为A的替代,先知道一下皮毛。

    初学者阶段需要注意的是,每看完一段,都(必须的!)要自己做做上机实验,把章节后面的练习,文章中的代码示例,自己动手把程序敲进去,编译一下,运行起来,调试调试。这一步非常重要,如果你做不到,那就学不好。

    至于IDE如何调试,如何设置断点,如何建立、配置项目,不属于这篇文字范畴,但有问题的话,欢迎留言,我会尽量解答。

    C++包含几个方面范式,一个是传统的结构化编程,一个是面向对象程序设计,一个是基于模板编程,还有就是STL标准模板库的使用。

    读者可以按部就班,先学习结构化编程,主要掌握基本的程序语法、关键字、数据结构,比如const的使用,4种xxx_cast概念等等。

    面向对象编程,要熟练掌握class、new、delete,对象(资源)管理,对象生命周期,构造、析构、拷贝构造、拷贝赋值这些与对象实例相关的内容,了解一下多态、继承、重载、覆盖、operator重载这些内容。另外简单了解一下多重继承、异常处理机制等等概念。写写例子实现一下,其实都不难理解。

    模板方面的内容不要挖的太深,了解并且实验一下如何定义模板类模板函数偏特化这些基本知识就够了。我可能用的比较浅,但是我八年工作经历来看,模板的内容属于不常使用的。

    STL方面,掌握几个基本的类型比如vector、list、map、set、string,了解一些基本算法,比如find之类,基本上工作就足够了。

    在这里要推荐第二本C++必须有的书籍《C++标准程序库—自修教程与参考手册》侯捷孟岩翻译。这是一本必须放在手边的书籍,因为MSDN关于STL的内容写得真是太烂了,比其它内容差的太多太多。前面介绍的STL,有了这本书在一边辅助,有问题一查便知。

    我一直在提的就是了解基本就足够了。没错!对于初学者而言,千万不要想着什么都学什么都会。C++的内容太多陷阱重重,什么都想知道,只能是胡子眉毛一把抓。抓主干抓基本抓核心,对我提到的内容,注意不同的层次:掌握、熟悉、了解,这些内容多看看,其它的碰到了在深入学习。

    C++第三方library,比如boost,如果没有必要,不建议大家学习和使用在自己的项目中。当然也有例外,比如asio和boost-python都是最近风头很劲的库,做网络编程或者配合python的话,可以选择。

    如果对于C++基本语法以及common knowledge有了认识了解,下面需要增加的就是工程实践设计方面的内容,基本上大家都推荐这几本,我也不例外。
    《Effective C++:改善程序与设计的55个具体做法:第3版 》
    《More Effective C++:35个改善编程与设计的有效方法(中文版)》
    《C++编程规范:101条规则、准则与最佳实践》

    这三本书的风格都是条目式,内容很实在,不玩虚的不炫技,里面的内容都可以立刻用在工程实践当中。

    另外需要说明的是,纯粹C++知识对于实际编程工作是不够的,必须结合特定领域,比如Windows下编程你要知道SDK API,Linux编程你要知道常用的system call,数据库编程要知道一些如何连接查询更新的步骤。这些没法在这里一一介绍,可以咨询公司内的其他同事,或者留言给我好了。

    看完这几本书,可能你对C++的了解已经上了一个台阶,这时候就不要继续死读书了,该动手做点什么了。

    第二阶段,写代码。

    书读百遍其义自现,代码写的多,bug就会多。开场诗念完就讲讲如何写代码。这其实是非常难的一步,有不少朋友书读了很多,但是就是写不出一行代码,或者写出来的还是非常奇怪充斥着低级错误的代码。这就是熟练度不够的缘故。

    平时喝茶的时间拿出来,想想代码该如何设计;平时泡妞的时间拿出来,想想这个函数有没有更好的实现;看到winzip、迅雷、QQ,想想如果自己写该如何实现功能。不仅要想,还要动手做一做。

    如果你是做Windows编程,这里推荐一下codeproject.com,这个网站上的项目设计了Windows开发的方方面面,比如GDI如何操作,数据库,控件菜单窗口消息循环等等,都比较短小精干,而且都包含了整个项目代码下载(而不仅仅是某个片段),下载以后编译调试一下,会对自己提高帮助很大。

    现在坊间也有一些step by step的书籍,教你如何一步步实现某个功能,这种书可以根据书评销量选一本然后照着实践编程。

    第三阶段,看高人编程。

    这一步针对读者已经工作而且公司中有高手存在的情况。跟高手拉好关系,然后坐在一边看他编程,一般有些人不喜欢别人看,但是如果你表现出很仰慕的表情,问题应该不大。一般比较靠谱的软件公司对于新人都会指定一个导师,如果幸运的话,你就看你的导师如何编程好了。

    其实这是学徒到大师中很关键的一步,有个词叫”传帮带“,就是师傅手把手的教。其实编程也是一门手艺,如果没看过师傅真实的工作状态,想变成高手要比较困难一些。

    看高人编程看什么,看他如何写代码,如何思考,用了哪些工具、快捷键,遇到问题怎么调试怎么跟踪的?这些都是书本上很少见,但是工程实践中又非常有用的东西。

    第四阶段,分享知识。

    自己水平够不够,一做分享就知道。

    不少公司都会定期举行技术分享会这类活动,或者有些地方社区也会搞搞技术分享。如果你觉得自己学的差不多了,就试着把自己知道的讲出来,分享给其他人。

    这样做有几个好处,一个是增加你对知识的了解。我做过不少ppt,当自己想说点什么的时候才知道自己有多深浅哪个地方还欠缺,这个办法万试万灵。在问答环节,你还可以与其他人互动,其他人的问题未必你都懂,这时候就可以继续深入学习。另外可以增加你自己的技术知名度,是一个很好的广告效应。

    如果没有类似的技术分享怎么办?

    我建议读者注册一个stackoverflow.com的账号,到那里去回答问题,一样也是非常好的分享方式。

  • 个人常用的免费iPad app软件(个人风格突出且不需越狱)

    我的iPad系统是iOS4.3没有越狱,推荐下面这些免费软件给各位iPad玩家。

    这些软件都是通过美国app store下载来的,不用信用卡注册一个美国app store其实很简单,就是购买一个free的软件就行了。某些情况下也许需要翻墙。

    下面推荐的软件都是免费的,在app store中可以搜索名字找到下载。不需要越狱也不需要破解,基本上已经满足了我日常需求。

    先说说我觉得应该有但是现在还不够好(或者我还不知道的)软件:

    1)浏览器,safari无法浏览桌面版google reader,太惨了,是我最不可容忍的。Firefox或者Chrome有iOS版本么?或者有什么软件浏览google reader比较像是正常浏览器的?

    2)pdf阅读软件,我想要的pdf阅读器其实就需要两个功能,一个是固定缩放比例,一个是固定缩放view或者说是切白边的功能,Apabi可以切白边,但是不能固定缩放。而且我也不喜欢翻页模式,如果能做成电脑上那种pdf连续阅读模式就更好了,为什么非要模拟实体书阅读呢?这些程序设计者其实也进入一个误区。

    当然也可以买ibook或者kindle,那是另外一个事情了。

    3)游戏方面,没有特别好玩的,操作感以及游戏大作各方面比较,都比psp差多了,这让我也感到很欣慰,psp不需要下岗。至于愤怒的小鸟,其实不很好玩。玩游戏还是需要有手柄才有感觉。

    我推荐的这些软件主要分几大类,下面让我一一道来:

    编程技术相关

    推荐软件就是一个Zite。由于没有碰到好的RSS阅读软件,或者有些软件(比如MobileRSS之类)的阅读习惯与google reader差别太大,基本不推荐。

    http://itunes.apple.com/us/app/zite/id419752338?mt=8&ls=1

    Zite这个软件号称是可以学习你的阅读习惯,进入软件以后可以先定制自己喜欢的频道,或者加上自己感兴趣的tag keyword,不过要注意这些tag关键字都是Zite预置的,现在还不存在你自己添加个新关键字的可能。

     

    在文章阅读页面,可以选择”喜欢“”不喜欢“,或者“一直给我推荐这个网站文章”“分享到twitter/FB/Email”等等功能。所谓能自我学习,也就是从读者不断地点击喜欢不喜欢来计算权值,进行文章推荐的吧。

     

    由于没有VPN,所以只能把自己喜欢的文章用email发给自己。

     

    英语、时事相关

    推荐《The Economist》《usa today》《nytimes》《CNN》《NPR》。

     

    免费版的经济学人《The Economist》只能看到“Editor’ s highlights”,但是基本上也足够了,因为不像是技术文章那么容易看懂。另外”经济学人“还可以下载音频收听,选择右上角的耳机图标就可以了。

    在通过听看新闻学英语的这些资源中,比较推荐”CNN“和”NPR“,因为他们几乎所有的音视频都有脚本字幕(transcript),如果遇到看不懂听不懂的,看看脚本就可以了。

    杂项新闻相关

    推荐iWeekly周末画报,Zaker,Flipboard。

    其中周末画报相对制作比较精美,而Zaker由于来源比较混杂,排版不是很好看,有了Zite以后,基本上就不用Zaker了。

    游戏相关

    推荐TradeNations。

    除了切水果,跳跃忍者,愤怒的小鸟这一类大家总所周知的游戏,TradeNations算是一个社交加农场养成类的游戏,你可以加好友,然后到好友的农场里进行交易,买花买家具买衣服等等,这个游戏是tinyfool在twitter上推荐,还真是挺好玩,每天稍微打理一下就可以了,如果你也玩了这个游戏,欢迎加我的账号sagasw。

     

    读书相关

    推荐CloudReader,Stanza,Apabi Reader(方正阅读器),ibook,kindle。

    没有特别出色的,相比来说Apabi特点突出一些,但也不是很好用。基本上ibook,kindle,Apabi阅读pdf都属于残废。但是我已经想到一个用ipad阅读pdf的方法,正在研究中。

     

    免费、限期免费相关

    推荐”app每日推送“以及”软件游戏猎手“这两款。

  • Why we need unittest?

    这是我给team member写的一封邮件,感觉很有通用性,值得推广给各位。
    我们的项目主要是以COM interface形式被其它软件使用,所以我写了一个ProjectAutoTest项目来实现功能测试。
    ProjectAutoTest通过config.txt这样的文本形式配合一些必要文件来定义测试用例,实现了不增加修改代码就可引入新测试用例的目的。

    因为针对的不是内部代码而是COM接口,严格的说算不上单元测试。
    但是,ProjectAutoTest可以帮助我提高软件质量,检测潜在的问题,就足够了。

    “Why we need unittest? it wastes time”

    Why we need unittest, because we need good code quality.

    1) The issue comes from ProjectA, and changes in our project.
    And AAA told me why it happens and debug with project,
    but we can’t repeat this step in every code change.

    2) Which files are affected, how to duplicate the issue more simple more easy?
    The unittest of ProjectAutotest is most easy way to get it.

    3) When we fix the issue for ProjectA, for ProjectB,
    it maybe affects our projects or others in same time. How could we know the change good or bad?
    Whether this change affect other defects?

    It is just my suggestion, but if you want to keep the code quality of our project,
    Following steps will be good way to do, and
    I have mentored BBB, CCC to follow the rule, it is not difficult.

    ====================================
    Step1) duplicate the issue with Defect description.

    Step2) convert the issue to ProjectAutoTest testcase. There must be one or two files.
    There must be one or more interface function are called.
    There have incorrect result or no output.

    Step3) run your new adding testcase, it should be able to duplicate the issue too.
    If some incorrect result is output, the incorrect result should same as Defect issue too.

    Step4) Fix the bug. Find the root cause.

    Step5) Change the code, and try with the testcase in ProjectAutoTest.
    It should get correct result.

    Step6) Test with all testcases in ProjectAutoTest, results should be correct too.

    Step7) Test with Defect duplication steps. It should be correct too.

    Step8) Check in the code, and change Defect state.

    !!! Note: the testcase in ProjectAutoTest should be checked in too.
    The testcase must be maintained same as source code, and consider the testcase as same importance too.

    For the code review, it should have changed code, and new testcase in same time.