摘要: 尾递归就是递归调用在函数的最后一步,这样的递归可以被编译器优化成类似于循环的形式,无须保存stack frame和局部变量,提高性能,一般可以通过一个accumulator参数将一个传统递归改造成尾递归, 一下是一个C++中的例子:int factorial_tail_recursion(int n, int acc){ if (n == 1) { return acc; } return factorial_tail_recursion(n-1, acc * n);}int factorial(int n){ if (n == 1) { return 1; } return n * fact 阅读全文
posted @ 2011-05-31 04:30 lzprgmr 阅读(902) 评论(0) 推荐(0) 编辑
摘要: 近来一篇<The Dark Side Of C++>在坊间广为转载,作为一个以C++为吃饭家伙的程序员,还是应该下载下来好好读一读的。 总的来讲还是总结的蛮全的,由于个人知识的限制,我读完后将其分为三类:一类是我不以为然的,觉得算不上阴暗面;一类是深有同感,深受其害;而另外一类则是还不理解,需要日后有时间的时候加以研究的。一、不以为然不断变更的标准,迫使我们需要不断更新已有代码。 作者列出了几点其实影响并不是很大(循环变量的scope;头文件后缀;名字空间)。而且,为了标准的进步,偶尔做出的妥协也是应该的吧。不断变更的style,作者举得例子是:Old and busted:for 阅读全文
posted @ 2011-05-20 11:55 lzprgmr 阅读(1644) 评论(12) 推荐(1) 编辑
摘要: 前段时间遇到了一些与BFS有关的有趣的问题,在一些朋友或者资料的帮助下有所思考,发现这个简单的算法如果能应用自如,的确能发挥强大的功效,于是乎写篇博客记录一下。BFS概念很简单,此处有介绍;BFS实现也很简单,用一个queue就可以了;而它确实也是图中一个非常重要的算法,而它确实也可以用来解决一些看似与图没啥明显关系的问题。 理解广度优先搜索,关键在于理解其应用。1. 基本应用广度优先搜索算法是基于图定义的,所以最直观的应用自然就在图中:有明确的vertex和edge。 比如地图,某个地点就是vertex,而连接两个地点的路径,就是edge,假设edge长度都一样(当然,事实上这是不可能的), 阅读全文
posted @ 2011-04-17 21:29 lzprgmr 阅读(15369) 评论(4) 推荐(5) 编辑
摘要: 这是一篇自我反思,因为我总觉得自己像个没头苍蝇:感觉有很多事要做,但其实又没做什么,把自己搞得很累却又没啥大的收获。要么毫无追求,至少有个平淡的心态去享受每天的生活;要么有所追求,努力的去达成自己的目标。我不是第一种,至少还没到那个境界,所以必须是第二条路。 那么究竟是哪里出了问题:我浪费了很多时间,很多很多时间,这种浪费不仅仅是浪费,更是培养了一种逃避的心态:要做正式的事之前,先上会微博轻松一下,“准备”一下吧;对于研究、阅读资料,我们更醉心于收集资料;在这种貌似有理,实则无用的额外工作下,时间被心安理得的浪费掉了,懒惰与拖沓在不知不觉中培养起来了。这是一个正反馈,这是一个恶性循环!那么我的 阅读全文
posted @ 2011-04-09 20:51 lzprgmr 阅读(25287) 评论(32) 推荐(10) 编辑
摘要: 之前写过一篇使用COM组件的3种方法的文章:启动COM组件的三种机制,其中后来补充了一个用免注册的方式使用进程外COM组件的方法,因为只是文字补充,没有实例,可能对于怎么实现大家不是很清楚,陆续收到一些同学的信,希望能给个例子。 所以干脆补充一篇,自己也恰好复习一下。步骤大概是这样的:我有一个com.exe的进程外com组件,暴露出一个ITestObject的接口。现在CustomizedWay.exe要调用这个com组件,但不希望通过注册表那一套。 虽然微软提供了registry-free的com组件机制,但目前只支持进程内COM组件(具体参考前文),但由于我们知道一个COM组件被调用的来龙 阅读全文
posted @ 2011-03-23 19:42 lzprgmr 阅读(9448) 评论(5) 推荐(0) 编辑
摘要: 原题是这样的:在校园招聘的季节里,为了能让学生们更好地了解微软亚洲研究院各研究组的情况,HR部门计划为每一个研究组举办一次见面会,让各个研究组的员工能跟学生相互了解和交流(如图1-4所示)。已知有n位学生,他们分别对m个研究组中的若干个感兴趣。为了满足所有学生的要求,HR希望每个学生都能参加自己感兴趣的所有见面会。如果每个见面会的时间为t,那么,如何安排才能够使得所有见面会的总时间最短?最简单的办法,就是把m个研究组的见面会时间依次排开,那我们就要用m * t的总时间,我们有10多个研究小组,时间会拖得很长,能否进一步提高效率?此题的官方解法是将问题转化为一个已知的图的问题:即图的最少着色问题 阅读全文
posted @ 2011-03-19 14:45 lzprgmr 阅读(3477) 评论(5) 推荐(1) 编辑
摘要: 有这么个问题:我们知道C++中有虚函数的类会有一个对应的虚函数表,那么纯虚类有虚表吗,如果有的话怎么调用纯虚函数?直觉上来讲,应该是有的。 可是既然是纯虚类,说明其对象永远不会被创建,那么维护个虚表貌似也不是很必要了。可以设计个程序来验证一下:class VirtualBase{public: VirtualBase() { // call pure virtual function through a non virtual function in base class's constructor non_virtual_fun(); } void non_virtual_fun() 阅读全文
posted @ 2011-03-07 21:56 lzprgmr 阅读(3281) 评论(7) 推荐(0) 编辑
摘要: 看到有这么道算法题在博客园讨论,算法eaglet和邀月都已经设计出来了,花了点时间读了下,学到点东西顺便记录下来吧。题目是从1...n的数列中,找出总和为n的连续子数列。这里先设好算法中需要用到的关键变量:s:目标子数列的第一个元素k:目标子数列的长度那么目标子数列可以表示为(s, k)1. naive算法(n^2)最笨的,但是最容易的想到的方法,就是穷举所有的子数列:for s = 1 to n for k = 1 to n-s+1 if sum(s, k) == n output(s, k)复杂度为:n + (n-1) + (n-2) + (n-3).... = n(n-1)/2所以,其复 阅读全文
posted @ 2011-03-05 17:14 lzprgmr 阅读(2824) 评论(3) 推荐(1) 编辑
摘要: 六年啦!!!要不是公司几个一起进来的同事有心,发邮件提醒了一下,还真没注意今天是在这家公司的六周年!记得六年前初来上海,和几个同学一起在公司附近租个房子,每天一起散步上班,散步下班,哦,好像还要去买菜,何其惬意!记得六年前初进公司,一上来就是3个月的培训,每天上午上课,下午做练习,一门课程结束还要考试,何其充实!六年间,从一个学生变成一个职业程序员,但还远称不上优秀;六年间,从学生变成丈夫,然后变成父亲,但似乎还不够成熟老练;十年磨一剑,4年后,再验我这把剑锋利几何 ! 阅读全文
posted @ 2011-03-01 22:18 lzprgmr 阅读(1107) 评论(6) 推荐(0) 编辑
摘要: 有些递归是很容易转化成循环的,用一个循环非常直观的映射过去就是了,如求Fibonacci数列; 而有些递归却没有那么直观,甚至可能需要多个循环才能转化过去,这里举个例子:给出一个集合,如(1, 2, 3, 4),打印出该集合的所有子集分析一下问题,子集是指取原集合中的任意多个元素,转化一下问题,就是对于原集合中的任何一个元素,我们都有两个选择,包含或者不包含,所以对于n个元素的集合,其子集数为: 2*2*2... = 2^n。那么可以得出其递归算法:递归的优点是直观、易懂:写起来如此,读起来也是这样。但是每次递归都是call stack的不断叠加,对于这个问题,其需要消耗O(n)的栈空间,栈空 阅读全文
posted @ 2011-02-12 08:18 lzprgmr 阅读(10693) 评论(8) 推荐(5) 编辑
摘要: 这是在TL讨论中Liu xinyu给出的一个例子,觉得思路挺有启发的,所以整理记录一下。给定一个数组,其内容是一些随机的、不重复的正整数,如:{4, 23, 1, 8, 9, 21, 6, 12}要求找出不在数组中出现的最小的那个数,比如这个数组中未在数组中出现的最小值是:2这个问题实际应用的原型可以是一个ID分配系统,其使用一个数组来保存已分配的ID,每次回收就从数组中删除一个元素(O(n)),而分配则需要找到最小的那个可用的ID,就是这个算法要做的事情。这个问题从naive的解法到快速的解法的思路转换是十分巧妙的,当然,如果之前没有接触过类似的题,注意到这个特性应该不是一件很容易的事。设数 阅读全文
posted @ 2011-02-10 09:25 lzprgmr 阅读(9392) 评论(26) 推荐(10) 编辑
摘要: 只要是招一个技术人员,不管是初级的程序员还是高级软件工程师,技术上的考核都必不可少。很荣幸作为面试官参与过公司的一些技术面试,从中也体会到了一些东西。首先,我觉得技术面试是需要讲究技巧的,不是随随便便拉一个技术不错的人就可以,因为面试的过程是双方相互交流的过程,你需要给对方营造一个轻松的气氛,并在不断的提问与回答的过程中,进行“合理的引导”,“适时的追问”与“正确的判断”。所以我觉得一个公司的技术... 阅读全文
posted @ 2011-01-23 18:17 lzprgmr 阅读(15827) 评论(31) 推荐(20) 编辑
摘要: 当实现一个算法或者写一个工具类的时候,我们总是需要写一些测试代码,但如果全部写在main函数里,难免组织混乱,不易清查;如果选用cppunit或者gtest等强大的单元测试框架,又是杀鸡用牛刀 - 太重了,不方便。另外一个可选的是TUT, Template Unit Test Framework,与前两者不同是其采用C++模板函数实现,而不是宏,虽说号称短小精悍,拿来一试也觉得颇显富态。其实我只需要一个很简单的框架,只是针对一个算法实现,或者一个工具类写测试,而不是项目级别的。比如我写了一个max函数求两个数中较大的那个,那么测试代码可以这么写:然后RUN_ALL_CASES就可以了。仔细想了 阅读全文
posted @ 2011-01-08 10:46 lzprgmr 阅读(2829) 评论(2) 推荐(3) 编辑
摘要: 首先,我觉得我的语言很苍白,我的思维很贫乏,每当看到一些朋友微博或者宏博(对应微博)中一些或尖锐,或深邃的词句,我就想我TM怎么就这么土呢。这还是其次,更严重的是,毕业这么些年来我觉得我的表达能力急剧下降,下降到连普通话都不标准了~~~,当然, 我不认为这和我程序员的职业有关。那跟什么有关呢? 和上进心有关,额,或者说是功利心。这么些年来,我一直勤勤恳恳想做好一个程序员,做一个好程序员,于是,我读技术书籍;我想提高自己的所谓的“软实力”,于是,我读心理学,读成功学;我想提高自己的理财能力,于是,我读经济学,学炒股;我甚至为了锻炼身体而买过什么搏击的书~~~ 好吧,这些其实都没什么成效,唯一的效 阅读全文
posted @ 2010-12-29 20:25 lzprgmr 阅读(931) 评论(9) 推荐(1) 编辑
摘要: FreeCAD是个开源的CAD软件,虽然功能还不是那么完善,但其很好的演示了如何搭建起一个完整的CAD系统 - 跨平台的。之前也研究过如何在Windows下搭建起一个CAD系统,模仿当前工作中做的那个软件,但牵扯到的都是些MFC,VBA,COM啥的。虽然我一直觉得那些抹黑微软技术,鼓吹Mac和Linux的行为很矫情,在这点上我还是宁愿俗气点:不能跨平台,总感觉心里缺了点啥的~~~现在FreeCAD使用了cMake在各个平台上统一配置编译系统,在Windows上不再提供Visual Studio工程文件,要自己产生,步骤自然要麻烦了点, 虽然其官方提供了一篇详细的教程,还不不足以详细到让你不走些 阅读全文
posted @ 2010-12-24 11:38 lzprgmr 阅读(3185) 评论(0) 推荐(0) 编辑
摘要: 这是今天下班前和同事讨论的问题。MFC的消息映射通过几个简单的宏,对Windows的消息机制做了非常好的面向对象封装,一时为无数C++程序员所模仿(当然,MFC可能也是模仿别人的)。熟悉MFC消息映射机制的人都知道,其本质无非就是把消息和其处理函数放到一个数组当中,当程序接收到某消息时,就会遍历该数组,查找对应的消息ID,找到了就调用其处理函数,找不到就往其基类的数组当中去找。对,是线性查找!那么为什么MFC没有将消息数组排序,然后用二分查找,把复杂度从O(n)提高到O(lg n)呢?原因我想可能是没有必要,可以想像,一个类中的消息处理函数的个数是十分有限的,假设有100个消息,最坏情况也就是 阅读全文
posted @ 2010-12-10 21:25 lzprgmr 阅读(771) 评论(0) 推荐(0) 编辑
摘要: 为什么Scrum对于我们team来讲,这其实是个被动的过程。我们部门之前在一些team实行过Scrum,可能是感觉效果还不错,而且觉得原来的瀑布模型太过古老和死板,于是决定今年年初开始全面实施Scrum。由于大家都是新手,公司采用了两个方法:一是超密集的培训。请专门机构来培训;请US的同事来培训;请实施过Scrum的同事来培训...二是实战演练。组成几个临时的team,用两个礼拜的时间跑一个spr... 阅读全文
posted @ 2010-11-29 20:59 lzprgmr 阅读(7275) 评论(5) 推荐(2) 编辑
摘要: 一个函数caller会在其内部调用另外一个函数callee,现在的情况是,caller可能会在多个地方被多次调用,而你希望callee只在第一次被调用时被调用一次。一般情况下,callee会是一个对环境或者资源的初始化工作。或许,从代码结构的角度来讲,你第一个想到的是把callee从caller中拿出来,放到某个合适的地方做初始化,这是个不错的方法,但相信我,在有些时候这并不是个有效的办法:你可能... 阅读全文
posted @ 2010-11-13 21:40 lzprgmr 阅读(17193) 评论(16) 推荐(4) 编辑
摘要: DLL的delay load,即延迟加载,是一项提高程序启动速度,减少进程地址空间的重要技术,用通俗一点的话来讲,就是对模块“呼之即来,挥之即去”的能力。很多程序缺乏这种灵活性,从而导致软件在第一次启动时需要加载所有可能需要的模块,严重影响了启动速度。狭义的delay load,是微软提供的一项技术,让模块在其symbol第一次被引用到时才被加载。但在广义上,我们其实有不少... 阅读全文
posted @ 2010-11-07 20:33 lzprgmr 阅读(3420) 评论(2) 推荐(3) 编辑
摘要: 在这个公司工作五年多了,因为项目不同,角色不同,层次不同,也见识与经历了我们在软件开发中的各个步骤, 花些时间,总结与回顾一下我们的开发流程。当然,先要说明一下前提:我们做的是产品开发,一年一release,而不是项目定制开发这是一个产品的持续开发、重构与维护,而不是从头搭建一个产品2009年以前,我们采用的是十分严格的瀑布开发模型,在项目初期就能拿到非常详细的spec,但2010年开始推行Scr... 阅读全文
posted @ 2010-10-30 19:47 lzprgmr 阅读(1301) 评论(2) 推荐(0) 编辑

黄将军