﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-兔子的技术博客-随笔分类-开发过程管理</title><link>http://www.cppblog.com/flyinghare/category/11477.html</link><description>兔子</description><language>zh-cn</language><lastBuildDate>Thu, 22 Aug 2013 06:43:11 GMT</lastBuildDate><pubDate>Thu, 22 Aug 2013 06:43:11 GMT</pubDate><ttl>60</ttl><item><title>几个软件研发团队管理的小问题</title><link>http://www.cppblog.com/flyinghare/archive/2013/08/22/202699.html</link><dc:creator>会飞的兔子</dc:creator><author>会飞的兔子</author><pubDate>Thu, 22 Aug 2013 06:21:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghare/archive/2013/08/22/202699.html</guid><wfw:comment>http://www.cppblog.com/flyinghare/comments/202699.html</wfw:comment><comments>http://www.cppblog.com/flyinghare/archive/2013/08/22/202699.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghare/comments/commentRss/202699.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghare/services/trackbacks/202699.html</trackback:ping><description><![CDATA[<h1><a id="cb_post_title_url" href="http://www.cnblogs.com/wanghui9072229/archive/2011/03/18/1988477.html" style="margin: 0px; padding: 0px; color: #075db3; text-decoration: none;">几个软件研发团队管理的小问题</a></h1><div style="margin: 0px; clear: both; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; line-height: 18px; background-color: #fefef2;"></div><div style="margin: 5px 0px 0px; padding: 5px 2px 5px 5px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #fefef2;"><div id="cnblogs_post_body" style="margin: 0px; word-break: normal !important;"><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">最近在与一位总经理交流的时候，他谈到他们公司的软件研发管理，说：&#8220;我们公司最大的问题是项目不能按时完成，总要一拖再拖。&#8221;他问我有什么办法能改变这个境况。从这样一个问题开始，在随后的交谈中，又引出他一连串在软件研发管理中的遇到的问题，包括：</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"><strong style="margin: 0px; padding: 0px;">. 现有代码质量不高，新来的开发人员接手时宁愿重写，也不愿意看别人留下的&#8220;烂&#8221;代码，怎么办？</strong></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"><strong style="margin: 0px; padding: 0px;">. 重构会造成回退，怎样避免？</strong></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"><strong style="margin: 0px; padding: 0px;">. 有些开发人员水平相对不高，如何保证他们的代码质量？</strong></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"><strong style="margin: 0px; padding: 0px;">. 软件研发到底需不需要文档？</strong></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"><strong style="margin: 0px; padding: 0px;">. 要求提交代码前做Code Review，而开发人员不做，或敷衍了事，怎么办？</strong></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"><strong style="margin: 0px; padding: 0px;">. 当有开发人员在开发过程中遇到难题，工作无法继续，因而拖延进度，怎么解决？</strong></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"><strong style="margin: 0px; padding: 0px;">. 如何提高开发人员的主观能动性？</strong></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">其实，每个软件研发团队的管理者都面临着或曾经面临过这些问题，也都有着自己的管理&#8220;套路&#8221;来应对这些问题。我把我的&#8220;套路&#8221;再此絮叨絮叨。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"><strong style="margin: 0px; padding: 0px;">1. 项目不能按时完成，总要一拖再拖，怎么改变？</strong></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">找解决办法前，当然要先知道问题为什么会出现。这位总经理说：&#8220;总会不断地有需求要改变和新需求提出来，使原来的开发计划不得不延长。&#8221;原来如此。知道根源，当然解决办法也就有了，那就是&#8220;敏捷&#8221;。敏捷开发因其迭代（Iterative）和增量（Incremental）的思想与实践，正好适合&#8220;需求经常变化和增加&#8221;的项目和产品。在我讲述了敏捷的一些概念，特别是Scrum的框架后，总经理也表示了对&#8220;敏捷&#8221;的认同。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">其实仔细想想，这里面还有一个非常普遍的问题。对于产品的交付时间或项目的完成时间，往往由高级管理层根据市场情况决策和确定。在很多软件企业中，这些决策者在决策时往往忽略了一个重要的参数，那就是团队的生产率（Velocity）。生产率需要量化，而不是&#8220;拍脑门子&#8221;感觉出来的。敏捷开发中有关于如何估算生产率的方法。所以使用敏捷，在估算产品交付时间或项目完成时间时，是相对较准确的。Scrum创始人之一的Jeff Sutherland说，他在一个风险投资团队做敏捷教练时，团队中的资深合伙人会向所有的待投资企业问同一个问题：&#8220;你们是否清楚团队的生产率？&#8221;而这些企业都很难做出明确的答复。软件企业要想给产品定一个较实际的交付日期，就首先要弄清楚自己的软件生产率。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"><strong style="margin: 0px; padding: 0px;">2. 现有代码质量不高，新来的开发人员接手时宁愿重写，也不愿意看别人留下的&#8220;烂&#8221;代码，怎么办？</strong></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">这可能是很多软件开发工程师都有过的体验，在接手别人的代码时，看不懂、无法加新功能，读代码读的头疼。这说明什么？排除接手人个人水平的因素，这说明旧代码可读性、可扩展性比较差。怎么办？这时，也许重构是一种两全其美的办法。接手人重构代码，既能改善旧代码的可读性和可扩展性，又不至于因重写代码带来的时间上的风险。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">从接手人心理的角度看，重构还有一个好的副作用，就是代码重构之后，接手人觉得那些原来的&#8220;烂&#8221;代码被修改成为自己引以自豪的新成就。《Scrum敏捷软件开发》的作者Mike Cohn写到过：&#8220;我的女儿们画了一幅特别令人赞叹的杰作后，她们会将它从学校带回家，并想把它展示在一个明显的位置，也就是冰箱上面。有一天，在工作中，我用C++代码实现了某个特别有用的策略模式的程序。因为我认定冰箱门适合展示我们引以为豪的任何东西，所以我就将它放上去了。如果我们一直对自己工作的质量特别自豪，可以骄傲地将它和孩子的艺术品一样展示在冰箱上，那不是很好吗？&#8221;所以这个积极的促进作用，将使得接手人感觉修改的代码是自己的了，而且期望能够找到更多的可以重构的东西。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"><strong style="margin: 0px; padding: 0px;">3. 重构会造成回退，怎样避免？</strong></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">重构确实很容易造成回退（Regression）。这时，重构会起到与其初衷相反的作用。所以我们应该尽可能多地增加单元测试。有些老产品，旧代码，可能没有或者没有那么多的单元测试。但我们至少要在重构前，增加对要重构部分代码的单元测试。基于重构目的的单元测试，应该遵循以下的原则（见《重构》第4章：构筑测试体系）：</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">- 编写未臻完善的测试并实际运行，好过对完美测试的无尽等待。测试应该是一种风险驱动行为，所以不要去测试那些仅仅读写一个值域的访问函数，应为它们太简单了，不大可能出错。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">- 考虑可能出错的边界条件，把测试火力集中在哪儿。扮演&#8220;程序公敌&#8221;，纵容你心智中比较促狭的那一部分，积极思考如何破坏代码。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">- 当事情被公认应该会出错时，别忘了检查是否有异常如期被抛出。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">- 不要因为&#8220;测试无法捕捉所有Bug&#8221;，就不撰写测试代码，因为测试的确可以捕捉到大多数Bug。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">- &#8220;花合理时间抓出大多数Bug&#8221;要好过&#8220;穷尽一生抓出所有Bug&#8221;。因为当测试数量达到一定程度之后，测试效益就会呈现递减态势，而非持续递增。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">说到《重构》这本书，其实在每个重构方法中都有&#8220;作法（Mechanics）&#8221;一段，在重构的实践中按照上面所述的步骤进行是比较稳妥的，同时也能避免很多不经意间制造的回退出现。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"><strong style="margin: 0px; padding: 0px;">4. 要求提交代码前做Code Review，而开发人员不做，或敷衍了事，怎么办？</strong></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">如果每个开发人员都是积极主动的，Code Review的作用能落到实处。但如果不是呢？团队管理者需要一些手段促使其有效地进行Code Review。首先，我们采用的Code Review有2种形式，一是Over-the-shoulder，也就是2个人座在一起，一个人讲，另一个人审查。二是用工具Code Collaborator来进行。无论哪种形式，在提交代码时，必须注明关于审查的信息，比如：审查者（Reviewer）的名字或审查号（Review ID，Code Collaborator自动生成），每天由一名专职人员来检查Checklist中的每一条，看是否有人漏写这些信息，如果发现会提醒提交的人补上。另外，某段提交的代码出问题，提交者和审查者都要一起来解决出现的问题，以最大限度避免审查过程敷衍了事。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">博主Inovy在某个评论说的很形象：&#8220;木（没）有赏罚的制度，就是带到厕所的报纸，看完就可以用来擦屁股了。&#8221;没有奖惩制度作保证，当然上面的要求没有什么效力。所以，当有人经常不审查就提交，或审查时不负责任，它的绩效评定就会因此低一点，而绩效的评分是跟每年工资涨落挂钩的。说白了，可能某个人会因为多次被查出没有做Code Review就提交代码，而到年底加薪时比别人少涨500块钱。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"><strong style="margin: 0px; padding: 0px;">5. 软件研发到底需不需要文档？</strong></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">软件研发需要文档的起原可能有2种，一是比较原始的，需要文档是为了当开发人员离职后，企业需要接手的人能根据文档了解他所接手的代码或模块的设计。二是较高层次的，企业遵从ISO9001质量管理体系或CMMI。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">对于第一种，根源可能来自于两个方面：</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">- 原开发人员设计编码水平不高，其代码可读性较差。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">- 设计思想和代码只有一个人了解，此人一旦离职，无人知道其细节。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">在编码前写一些简单的设计文档，有助于理清思路，尤其是辅以一些UML图，在交流时也是有好处的。但同时，我们也应该提高开发人员的编码水平增加其代码的可读性，比如增强其变量命名的可读性、用一些被大家所了解的设计模式来替代按自己某些独特思路编写的代码、增加和改进注释等等，以减少不必要的文档。另外推行代码的集体所有权（Collective Ownership），避免某些代码只被一个人了解，这样可以减少以此为目的而编写的文档。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">对于第二种，情况有些复杂。接触过敏捷开发的人都知道《敏捷宣言》中的&#8220;可以工作的软件胜于面面俱到的文档&#8221;。接触过CMMI开发或者ISO9001质量管理体系的人知道它们对文档的要求是多么的高。它们看起来水火不相容。但是，它们的宗旨是一致的，即：构建高质量的产品。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">对于敏捷，使用手写用户故事来记录需求和优先级的方法，以及在白板上写画的非正式设计，是不能通过ISO9001的审核的，但当把它们复印、拍照、增加序号、保存后，可以通过审核。每次都是成功的Daily Build和Auto Test报告无法证明它们是否真正被执行并真正成功，所以不能通过ISO9001的审核。但添加一个断言失败（类似assert(false)的断言）的测试后，则可以通过审核。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">CMMI与敏捷也是互补的，前者告诉组织在总体条款上做什么，但是没有说如何去做，后者是一套最佳实践。SCRUM之类的敏捷方法也被引入过那些已通过CMMI5级评估的组织。很多企业忘记了最终目标是改进他们构建软件及递交产品的方式，相反，它们关注于填写按照CMMI文档描述的假想的缺陷，却不关心这些变化是否能改进过程或产品。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">所以敏捷开发在过程中只编写够用的文档，和以&#8220;信息的沟通、符合性的证据以及知识共享&#8221;作为主要目标的质量体系文档要求并不矛盾。在实践中，我们可以按以下方法做，在实现SCRUM的同时，符合审核和评估的要求：</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">- 制作格式良好的、被细化的、被保存的和能跟踪的Backlog。复印和照片同样有效。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">- 将监管需要的文档工作也放入Backlog。除了可以确保它们不被忘记，还能使监管要求的成本是可见的。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">- 使用检查列表，以向审核员或评估员证明活动已执行。团队对&#8220;完成&#8221;的定义(Definition of &#8220;Done&#8221;)可以很容易转变为一份检查列表。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">- 使用敏捷项目管理工具。它其实就是开发程序和记录的电子呈现方式。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">总而言之，软件研发需要文档（但文档的形式可以是多种多样的，用Word写的文字式的文件是文档，用Visio画的UML图也是文档，保存在Quality Center中的测试用例也是文档），同时我们只需写够用的文档。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"><strong style="margin: 0px; padding: 0px;">6. 当有开发人员在开发过程中遇到难题，工作无法继续，因而拖延进度，怎么解决？</strong></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">这也是个常遇到的问题。如果管理者对于某个工程师的具体问题进行指导，就会陷入过度微观管理的境地。我们需要找到宏观解决办法。一，我们基于Scrum的&#8220;团队有共同的目标&#8221;这一规则，利用前面提到的集体所有权，当出现这些问题时，用团队中所有可以使用的力量来帮助其摆脱困境，而不是任其他人袖手旁观。当然这里会牵扯到绩效评定的问题，比如：提供帮助的人会觉得，他的帮助无助于自己绩效评定的提高，为什么要提供帮助。这需要人力资源部门在使用Scrum开发的团队的绩效评估中，尽量消除那些倾向个人的因素，还要包含团队协作的因素，广泛听取个方面的意见，更频繁地评估绩效等等。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">二，即使动用所有可以使用的力量，如果某个难题真的无法逾越，为了减少不能按时交付的风险，产品负责人应当站出来，并有所作为。要么重新评估Backlog的优先级，使无法继续的Backlog迟一点交付，先做一些相对较低优先级的Backlog，以保证整体交付时间不至于延长；要么减少部分功能，给出更多的时间去攻克难题。总之逾越技术上难关会使团队的生产率下降，产品负责人必须作出取舍。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"><strong style="margin: 0px; padding: 0px;">7. 有些开发人员水平相对不高，如何保证他们的代码质量？</strong></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">当然首先让较有经验的人Review其要提交的代码，这几乎是所有管理者会做的事。除此之外，管理者有责任帮助这些人（也包括水平较高的人）提高水平，他们可以看一些书，上网看资料，读别人的代码等等，途经还是很多的。但问题是你如何去衡量其是否真正有所收获。我们的经验是，在每年大约3月份为每个工程师制定整个年度的目标，每个人的目标包括产品上的，技术上的，个人能力上的等4到5项。半年后和一年后，要做两次Performance Review，目标是否实现，也会跟绩效评定挂钩。我们在制定目标时，遵循SMART原则，即：</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">Specific（明确的）：目标应该按照明确的结果和成效表述。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">Measurable（可衡量的）：目标的完成情况应该可以衡量和验证。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">Aligned（结盟的）：目标应该与公司的商业策略保持一致。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">Realistic（现实的）：目标虽然应具挑战性，但更应该能在给定的条件和环境下实现。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">Time-Bound（有时限的）：目标应该包括一个实现的具体时间。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">比如：某个人制定了&#8220;初步掌握本地化技术&#8221;的目标，他要确定实现时间，要描述学习的途经和步骤，要通过将技术施加到公司现有的产品中，为公司产品的本地化/国际化/全球化作一些探索，并制作Presentation给团队演示他的成果，并准备回答其他人提出的问题。团队还为了配合其实现目标，组织Tech Talk的活动，供大家分享每个人的学习成果。通过这些手段，提高开发人员的自学兴趣，并逐步提高开发人员的技术水平。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"><strong style="margin: 0px; padding: 0px;">8. 如何提高开发人员的主观能动性？</strong></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">提高开发人员的主观能动性，少不了激励机制。不能让开发人员感到，5年以后的他和现在比不会有什么进步。你要让他感到他所从事的是一个职业（Career），而不只是一份工作（Job）。否则，他们是不会主动投入到工作中的。我们的经验是提供一套职业发展的框架。框架制定了2类发展道路，管理类（Managerial Path）和技术类（Technical Path），6个职业级别（1-3级是Entry/Associate，Intermediate，Senior。4级管理类是Manager/Senior Manager，技术类是Principal/Senior Principal。5级管理类是Director/Senior Director，技术类是Fellow/Architect。6级是Executive Management）。每个级别都有13个方面的具体要求，包括：范围（Scope）、跨职能（Cross Functional）、层次（Level）、知识（Knowledge）、指导（Guidance）、问题解决（Problem Solving）、递交成果（Delivering Result）、责任感（Responsbility）、导师（Mentoring）、交流（Communication）、自学（Self-Learning），运作监督（Operational Oversight），客户响应（Customer Responsiveness）。每年有2次提高级别的机会，开发人员一旦具备了升级的条件，他的Supervisor将会提出申请，一旦批准，他的头衔随之提高，薪水也会有相对较大提高。从而使每个开发人员觉得&#8220;有奔头&#8221;，自然他们的主观能动性也就提高了。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">上面的&#8220;套路&#8221;涉及了软件研发团队管理中的研发过程、技术实践、文档管理、激励机制等一些方面。但只是九牛一毛，研发团队管理涵盖的内容还有很多很多，还需要管理者在不断探索和实践的道路上学习和掌握。</p></div></div>转自：<a href="http://www.cnblogs.com/wanghui9072229/archive/2011/03/18/1988477.html">http://www.cnblogs.com/wanghui9072229/archive/2011/03/18/1988477.html</a><img src ="http://www.cppblog.com/flyinghare/aggbug/202699.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghare/" target="_blank">会飞的兔子</a> 2013-08-22 14:21 <a href="http://www.cppblog.com/flyinghare/archive/2013/08/22/202699.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>配置管理的精髓</title><link>http://www.cppblog.com/flyinghare/archive/2013/08/09/202429.html</link><dc:creator>会飞的兔子</dc:creator><author>会飞的兔子</author><pubDate>Fri, 09 Aug 2013 03:32:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghare/archive/2013/08/09/202429.html</guid><wfw:comment>http://www.cppblog.com/flyinghare/comments/202429.html</wfw:comment><comments>http://www.cppblog.com/flyinghare/archive/2013/08/09/202429.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghare/comments/commentRss/202429.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghare/services/trackbacks/202429.html</trackback:ping><description><![CDATA[<div style="font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 12px; line-height: normal; background-color: #67a10f;"><div><h3><span style="font-size: 20px; font-family: 微软雅黑, 黑体, Arial, Helvetica, sans-serif;">配置管理的精髓</span>&nbsp;&nbsp;</h3><p clearfix="" nbw-act=""  fc06"="" style="zoom: 1; margin: 0px 0px 20px; padding: 0px; color: #3e6700; line-height: 20px;"><span style="float: left;"><span style="margin: 0px 2px;">2012-05-30 18:00:46</span><span style="margin: 0px 2px;">|&nbsp;&nbsp;分类：</span>&nbsp;<a m2a"="" href="http://blog.163.com/wangdan10799@126/blog/#m=0&amp;t=1&amp;c=fks_087071083086083069085086080095085086083064084086095064" title="配置管理" style="cursor: pointer; text-decoration: none; color: #e6ff82;">配置管理</a>&nbsp;<span id="$_blogTagTitle" style="margin: 0px 2px;">|&nbsp;&nbsp;标签：</span><span id="$_blogTagInfo" style="color: #e6ff82;"><a href="http://blog.163.com/wangdan10799@126/blog/#m=0&amp;t=3&amp;c=配置管理"  m2a"="" style="cursor: pointer; text-decoration: none; color: #e6ff82;">配置管理</a>&nbsp;&nbsp;<br /></span></span><span fc07=""  ztag"="" style="float: right; color: #a5d857;"><span style="margin: 0px 2px;">|</span><span fc03"="" id="$_fontswitch" style="color: #e6ff82; position: relative; cursor: default;">字号</span></span><span pnt=""  fc03"="" id="$_blog_subscribe" style="cursor: pointer; float: right; color: #e6ff82;">&nbsp;<a style="cursor: pointer;">订阅</a></span></p></div></div><div style="font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 12px; line-height: normal; background-color: #67a10f;"></div><div style="font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 12px; line-height: normal; background-color: #67a10f;"></div><div fc05="" fc11="" nbw-blog="" ztag=""  js-fs2"="" style="line-height: 25px; word-wrap: break-word; color: #02540a; margin: 15px 0px; padding-top: 5px; padding-bottom: 5px; overflow: hidden; font-family: Arial, Helvetica, simsun, u5b8bu4f53; background-color: #67a10f;"><p style="margin: 0px 0px 10px; padding: 0px;">配置管理的精髓&nbsp;<br />贝尔实验室先进技术研究院&nbsp;&nbsp; 姜海东</p><p dir="ltr" style="margin: 0px 0px 10px; padding: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 随着国内软件业的崛起和成熟，软件配置管理越来越得到重视。可以说，软件业要想更好的发展，没有软件配置管理的支持是不可能的。手工作坊式的软件开发模式将会成为历史，如何把国外成熟的软件配置管理理论和经验消化吸收，进而应用到国内软件开发中就成为国内软件业迫在眉睫的任务了。&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 软件配置管理是管理和技术相结合的一门学科。应该说，软件配置管理理论难以理解是其难以实践的原因。本文试从基本概念的角度来探讨这门对软件开发具有重要意义的领域。</p><p dir="ltr" style="margin: 0px 0px 10px; padding: 0px;"><br />什么是配置管理&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在软件开发中，变更是不可避免的。从某种角度上讲，软件开发过程就是一个变更的过程。有些变更是有益的，是具有创造性的，但是，也有些变更是有害的，导致混乱的。正像James Bach 总结的那样：&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>我们为变更所困扰，因为代码中的一个极小的混乱可能带来产品的大的故障，但是，他也能够修复大的故障或启用奇妙的新能力。我们为变更所困扰，因为某个喜欢恶作剧的单个开发者可能破坏掉项目，但是，一些奇妙的思想也源自那些喜欢恶作剧的人员。&nbsp;</strong><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 因此，如何管理这些变更是一个软件开发能否成功的关键。简言之，软件配置管理就是管理变更的过程，它贯穿着几乎软件的整个生命周期。成功的配置管理系统可以提高产品的质量、项目开发效率，而且最大限度的减少对个别&#8220;英雄&#8221;式人员的依赖。&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 尽管配置管理（Configuration Management ）这个概念被提出有几十年了，但是，业内还没有一个全面而权威的定义。Configuration 的意思是&#8220;使成形&#8221;，它来源于拉丁语的com-（表示&#8220;与&#8221;或者&#8220;一起&#8221;）和figurate ( 形成) 。它还有一个意思是&#8220;组成部件或元素的相对排列&#8221;。因此，配置管理（ConfigurationManagement ）指的是管理组成部件或者元素的相对排列。&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 配置管理的概念来自于硬件领域，美国国防部最早使用了配置管理的概念。我们知道一架飞机的构成非常复杂，比如机头、机身、机翼和机尾等。不同型号飞机的各个部分是不能随便组装的。因此，我们只有把相匹配的部件组装在一起，才能构成了一个功能完备的飞机整体。随着技术的提高，各个部件可能还要进行功能改善，我们还要使得不同版本的部件能够正确无误组合在一起。&nbsp;<br />准确地说：&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;配置管理是对产品进行标识、存储和控制，以维护其完整性、可追溯性以及正确性的学科。&nbsp;<br />从上面的描述，我们知道，配置管理的基本单位是配置项。软件配置项可以是：</p><ul dir="ltr" style="margin: 5px 0px 5px 40px; padding: 0px;"><li><div style="margin-right: 0px;">&nbsp;与合同、过程、计划和产品有关的文档和数据</div></li><li><div style="margin-right: 0px;">源代码、目标代码和可执行代码</div></li><li><div style="margin-right: 0px;">相关产品，包括软件工具、库内的可复用软件、外购软件及用户提供的软件</div></li></ul><p dir="ltr" style="margin: 0px 0px 10px; padding: 0px;">&nbsp;<br />&nbsp; 从&#8220;哲学&#8221;意义上讲，配置管理记录配置项的三个方面：&nbsp;<br /></p><ul dir="ltr" style="margin: 5px 0px 5px 40px; padding: 0px;"><li><div style="margin-right: 0px;">从哪里来？此项可归结为WWW 的问题，（Who）谁创建的？（When）什么时间创建的？（Why）为什么创建此配置项？</div></li><li><div style="margin-right: 0px;">当前在哪里？此项纪录配置项当前的存储位置以及状态。</div></li><li><div style="margin-right: 0px;">将到哪里去？通过配置控制来把配置项&#8220;组装&#8221;到正确的版本中去。</div></li></ul><p dir="ltr" style="margin: 0px 0px 10px; padding: 0px;">&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 配置项可以是大粒度的，也可以是小粒度的。如果跟踪个别需求，那么不必要把整个需求规格说明文档定义为一个配置项，可以把每个需求定义为配置项；如果把软件开发工具也放入配置管理系统，那么把配置项定义为文件级就不合适了，只需要跟踪开发工具的版本，即把整个配置工具定义为一个配置项就足够了。&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;简而言之，配置项可以是文件级粒度的，也可以使文件版本级粒度的。当然，粒度越小管理的成本越高，但是配置的精度也就越高。&nbsp;<br />一个完整的SCM系统要具有三个核心功能：配置标识、版本控制、变更控制、配置状态统计和配置审核。其中变更控制包括基线管理、变更请求管理、构建管理和发布管理。如下图所示。&nbsp;<br /><br />下面，我们来具体理解这些概念。&nbsp;<br />&nbsp;<br /><strong>配置标识&nbsp;</strong><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 配置标识就是识别产品的结构、产品的构件及其类型，为其分配唯一的标识符，也就是说，每一个配置项要有一个唯一标识。一般说来，标识包括两个方面：一是文件名，二是版本，可用如下一个二元组来标识：&lt; 文件名，版本&gt; 。每个项目首先要确定一套命名规则，例如，采用&#8220;系统.子系统.模块.文件&#8221;的方式，&lt;/videoConference/audio/compressing/m a in.c , 2.1&gt;就是一个唯一标识。&nbsp;<br />&nbsp;<br /><strong>版本控制&nbsp;</strong><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 版本控制就是对在软件开发过程中所创建的配置对象的不同版本进行管理，保证任何时候都能取到正确的版本以及版本的组合。当前，这方面典型的工具有如VSS 和CVS 。</p><p dir="ltr" style="margin: 0px 0px 10px; padding: 0px;"><br /><strong>变更控制&nbsp;</strong><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在软件开发过程，要产生许多变更，比如，配置项、配置、基线、构建的版本、发布版本等。对于所有的变更，都要有一个控制机制，以保证所有变更都是可控的、可跟踪的、可重现的。对变更进行控制的机构称为变更控制委员会（Change Control Board，简称<br />CCB ）。变更控制委员会要定期召开会议，对近期所产生的变更请求进行分析、整理，并做出决定。而且要遵循一定的变更机制。&nbsp;<br />&nbsp;&nbsp;<br />下面是一个典型的变更机制：&nbsp;&nbsp;<br /><strong>变更请求管理&nbsp;</strong><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 变更请求管理就是对变更请求（Change Request，简称CR）进行分类、追踪和管理的过程来实现的。&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 变更的起源有两种：功能变更和缺陷修补（Bug-Fix）。功能变更是为了增加或者删除某些功能。缺陷修补则是对已存在的缺陷进行修补。&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对变更请求的有效管理可以提高产品管理的透明度，经理可以清楚的知道当前产品的进展情况，比如有多少个新产生的CR，已经解决了多少CR等等，有利于经理做出正确的决策。&nbsp;<br />&nbsp;<br /><strong>基线管理&nbsp;</strong><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 基线是指经过正式评审和批准，可作为下一步工作的基准的一个配置。软件开发过程中，无论是需求分析、设计、测试都需要在完成时建立基线，以作为下一步工作的基础。</p><p dir="ltr" style="margin: 0px 0px 10px; padding: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 通过基线管理可以使用户能够通过对适当版本的选择来组成特定属性（配置）的软件系统，这种灵活的&#8220;组装&#8221;策略使得配置管理系统象搭积木似的使用已有的积木（版本）组装成各种各样、不同功能的模型。&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 基线的变更需要一个严格的流程，需要提出申请，经过审批，然后才能进行。&nbsp;<br /><strong>构建管理&nbsp;</strong><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在做构建时，我们需要首先取出正确的配置，然后再做构建。我们可以利用基线，可以取出某个基线的所有配置项，也可以利用配置管理系统的构建功能直接在工作空间内做构建。&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 构建管理需要配置管理工具的支持。&nbsp;<br /><strong>发布管理&nbsp;<br /></strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;软件产品的每个版本都是一组配置项（源代码、文档、数据）的集合。举个例子来说，我们要发布软件的32.6 版本，那么我们就要把源代码、文档、数据中所有应该包含到这个版本中的正确配置项检出。&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 所以如何管理每个版本中包含哪些配置项是非常重要的。&nbsp;&nbsp;<br /><strong>状态报告&nbsp;<br /></strong>状态报告要回答所谓4W 的问题：&nbsp;<br />What：发生了什么事？&nbsp;<br />Who：谁做的此事？&nbsp;<br />When：此事是什么时候发生的？&nbsp;<br />Why：为什么做此事？&nbsp;<br />状态报告要能够报告所有配置项以及变更请求的状态，通过量化的数据和报表反映项目开发进度的状态。&nbsp;<br /><strong>配置审核&nbsp;</strong><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 配置审核要审查整个配置管理过程是否符合规范，配置项是否与需求一致，记录正确，配置的组成是否具有一致性等等。比如，需求分析文档提交后，需要由一个由相关人组成的小组进行正式评审，只有通过了评审才能基线化。对于源代码也一样，一般说来，每行代码都要进行评审（Review），只有通过评审才能交由测试人员进行测试。&nbsp;<br /><strong>实施配置管理的好处&nbsp;</strong><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 我们知道软件有三个要素：时间、预算和质量。一个成功的软件就是要在限定的时间内，不超过预算，交付符合质量要求的产品。真正实施配置管理后，我们会对产品的开发过程进行有效的控制，可以加快开发进度，降低开发成本，保证产品的质量。&nbsp;<br /><strong>产品经理可以得到什么好处呢？</strong>&nbsp;<br /></p><ul dir="ltr" style="margin: 5px 0px 5px 40px; padding: 0px;"><li><div style="margin-right: 0px;">准确掌握项目的开发进度。配置管理系统可以提供详尽的状态报告，例如当前系统有多少个Bug，所有Bug 的状态如何？已经解决了多少Bug？</div></li><li><div style="margin-right: 0px;">了解项目组成员的工作负荷、工作效率以及工作质量。例如，我们可以知道当前分配给每个成员的工作量，每个成员已完成的工作量，每个成员未通过正式评审的工作比例等等。</div></li><li><div style="margin-right: 0px;">减少人员流动所带来的影响。每个成员的所有变更，包括文档、代码的增删都是可追踪的，而且对于变更的原因、描述也都有记录。这样，一旦成员离开，其它成员就可以在最短的时间里接手。</div></li><li><div style="margin-right: 0px;">&nbsp;有效提高过程管理，配置管理产生的许多数据可作为管理者度量项目的依据。</div></li></ul><p dir="ltr" style="margin: 0px 0px 10px; padding: 0px;"><br /><strong>开发人员和测试人员可以得到什么好处呢？</strong></p><ul dir="ltr" style="margin: 5px 0px 5px 40px; padding: 0px;"><li><div style="margin-right: 0px;">&nbsp;提交的代码被有效保存，开发人员再也不用花费精力去保存各个版本了。</div></li><li><div style="margin-right: 0px;">&nbsp;提高团队的协作效率。开发人员之间以及开发人员和测试人员之间可以有效的沟通，大家都互相知道其它人的工作状态。</div></li><li><div style="margin-right: 0px;">&nbsp;提高修复缺陷的效率。可以依据Bug 发现的版本，迅速重建环境，重现Bug，快速定位代码，找出根源。</div></li><li><div style="margin-right: 0px;">职责清楚，任务明确。每一步的工作都是基于某一基线的，比如，设计文档是依据基线化了的需求分析文档，这样一旦出现问题，就可以找出问题出在什么地方。</div></li></ul><p dir="ltr" style="margin: 0px 0px 10px; padding: 0px;"><br />&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 当然，实施配置管理的好处远不止这些。软件配置管理作为软件开发的基石，它提供了一个协作开发的环境，只有大家共同遵守配置管理规范，互相协作才能保证项目的成功。&nbsp;<br />&nbsp;<br />结束语&nbsp;<br />&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 配置管理本身无论从理论和实践都在不断丰富和发展。例如，配置管理应用于&#8220;知识库&#8221;的管理就产生了&#8220;内容管理&#8221;这一新的领域。配置管理提供的状态报告和数据统计也为软件度量提供了决策依据。配置管理为项目管理提供了各种监控项目进展的视角，为项目经理确切掌握项目进程提供了保证。配置管理也为开发人员提供了一个协作的平台，在此平台上，大家能够更有效率的交流和协作。可以说，配置管理是软件开发的基石！&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 配置管理近年来在中国得到了极大的认可，可以毫不夸张的说，没有配置管理，就谈不上软件开发，就谈不上软件质量，就谈不上软件业的发展。随着软件业规模的扩大，配置管理的实施不是要不要的问题，而是什么时间、如何实施的问题了。&nbsp;<br />参考文献：&nbsp;<br />Babich, W.A., Software Configura tion Management, Addison-Wesley, 1986. Peter H. Feiler, Configuration Management Models in Commercial Environment, CMU/SEI-91-TR-7, 1991.4&nbsp;<br />&nbsp;<br />作者简介：2000年在北方交通大学获工学硕士学位。现供职于朗讯科技（中国）有限公司贝尔实验室先进技术研究院，从事配置管理系统的研究和开发，有四年多的配置管理领域开发、咨询、培训经验。</p></div>转自：<a href="http://blog.163.com/wangdan10799@126/blog/static/10230093201243054322378/">http://blog.163.com/wangdan10799@126/blog/static/10230093201243054322378/</a><img src ="http://www.cppblog.com/flyinghare/aggbug/202429.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghare/" target="_blank">会飞的兔子</a> 2013-08-09 11:32 <a href="http://www.cppblog.com/flyinghare/archive/2013/08/09/202429.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>公司技术管理角度看C++游戏程序员发展</title><link>http://www.cppblog.com/flyinghare/archive/2012/09/10/190141.html</link><dc:creator>会飞的兔子</dc:creator><author>会飞的兔子</author><pubDate>Mon, 10 Sep 2012 11:03:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghare/archive/2012/09/10/190141.html</guid><wfw:comment>http://www.cppblog.com/flyinghare/comments/190141.html</wfw:comment><comments>http://www.cppblog.com/flyinghare/archive/2012/09/10/190141.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghare/comments/commentRss/190141.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghare/services/trackbacks/190141.html</trackback:ping><description><![CDATA[<p style="text-indent: 21pt; margin-top: 5pt; layout-grid-mode: char;" align="center"><span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;"><strong>公司技术管理角度看C++游戏程序员发展</strong></span></p><p style="text-indent: 21pt; margin-top: 5pt; layout-grid-mode: char;" align="center"><span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;"><strong>H3D,2008</strong></span></p><p style="text-indent: 21pt; margin-top: 5pt; layout-grid-mode: char;" align="left"><span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">2011补充： 这是一篇2008年的老文章。发这里原因有2，一来本blog没有。二来这篇文章最后一部分关于某个程序员个人价值的预测，部分应验。这位程序员决定出来单干后，很容易拿到一大笔投资。 某种意义上，这笔钱代表着这位技术人员和其团队的价值。是在公司还是出来创业，与本文无关。也无所谓。从一个技术员角度出发，提高自己的能力和视野与经验才是提升实现自己价值的道路。</span></p><p style="text-indent: 21pt; margin-top: 5pt; layout-grid-mode: char;" align="left"> </p><p style="text-indent: 21pt; margin-top: 5pt; layout-grid-mode: char;"><span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">这是我多年来招聘培训游戏程序员的一点想法。一直想汇总一下。主要目的是为了更好的对公司新进C++程序员进行培训，并且建立起游戏程序员培训，发展，成才，成为核心骨干，管理层，期权收益人等一整套体系。因为对于MMO游戏制作来讲，解决好C++技术队伍，是保证合格软件的基础之一。 </span></p><p>  <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">我在的H3D Studio核心技术人员和游戏制作管理人员全部是SMTH BBS游戏制作版成员。从99年开始截止BEGINER的历任版主都在H3D STUDIO里工作过。在这里我把具体的培训以及技术队伍组建的内容去掉，只和大家聊聊关于游戏程序员切身利益相关的事。 </span></p><p>  <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">另外这不是居高临下来评判什么事情。我本人也不是多么高级的技术人员或者管理人员。只是坚持做一件事情年头很长教训很多而已。所以有些体验。文中所有评判其他结构或人水平低，并不是说我本人水平有多高。不要误会。 </span></p><p>&nbsp;</p><p><span style="font-family: &quot;Times New Roman&quot;; font-size: 10.5pt; font-weight: bold;yes&quot;;">     1</span> <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt; font-weight: bold;yes&quot;;">，C++游戏程序员现状 </span></p><p>  <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">中国C++程序员100％都是自学的。因为中国几乎没有象样的C++培训机构。大家都知道社会培训是赚钱为主要目的。能在那里成才是个大运气。也不象JAVA有SUN公司一手推行。中国大学教育里也根本没有C++教学。关于C/C++基础课的知识，只是让学生入门。但对于实际的C++软件工程应用，大学课本知识实践意义不大。最重要的是，大学里没有合格的C++老师。编程是门技术，叫手艺也行。而大学是搞科研的，多的是科学家，靠出PAPER教科凭职称为生。并不是技术员。没有10万行以上代码经验和成功软件项目经验的人，很难教出中高级C++程序员。 </span></p><p>  <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">游戏制作业对C++程序员的要求是比较高的。比一般行业软件高很多。因为任何一个MMO都是个中大型软件项目。日使用人次达到几十万上百万，同时使用人数几十万在线的大型网络多人交互软件，集成了超过十几项专业领域编程技术的软件，想不大都不行。 </span></p><p>  <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">另外，中高级C++程序员能力一般都很强。因为都是自学成才，这需要较高智商，很强的自学能力，解决问题能力，和克服困难的毅力。但是这种人才在游戏行业里人数并不多。抛开凤毛麟角具备整体大型软件架构能力的高级人才不谈。能够承担独立模块开发，具备独立解决问题的能力，写出在空间，性能，可维护性等几个方面达到要求的C++程序员，也是很难找到的。而具备这些能力，同时又具备一些专业领域技术的人（图形引擎，网络引擎，等），更加稀少。 </span></p><p>  <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">所以，即便是大游戏公司，对于C++游戏程序员的需求，也是永远不能够得到满足。而已经在公司工作的C++程序员，不经过短则3个月，长达1年的锻炼，也无法真正胜任独当一面的C++游戏程序开发工作。 </span></p><p style="margin-top: 5pt; layout-grid-mode: char;"><span style="font-family: &quot;Times New Roman&quot;; font-size: 10.5pt; font-weight: bold;yes&quot;;">2</span> <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt; font-weight: bold;yes&quot;;">，MMO游戏开发对C++游戏程序员要求 </span></p><p>  <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">前面提到，所有MMO游戏都是中大型软件。软件占用空间，稳定性，性能，可维护性等各项衡量软件质量的指标，对MMO游戏软件的要求都非常严格。远大于普通行业软件。这种规模和银行系统类似。而客户端和软件逻辑比一般的商业软件又要复杂很多倍。这就要求软件编写人员具备较高的程序编写素质。 </span></p><p>  <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">游戏软件中，解决好软件工程部分，只是项目的1/3。另外两部分是策划和美术/音频。从经验来看，需求变更对于MMO游戏软件，不是偶然事件，而是一种MMO游戏软件开发的基本属性。游戏软件投入大，周期长，风险高。MMO市场变化也大，交互电子游戏发展迅速。游戏软件必须面对外界变动。又因为开发周期长，所以软件需求变动成为了软件开发的一种基本属性。犹如复杂性是软件工程的一项基本属性一样。 </span></p><p>  <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">这导致游戏软件的开发充满了不确定性。交互娱乐不同于商业应用。娱乐是属于理性和感性之间的领域。而C++开发面对就是0和1的二元世界逻辑。这两个领域存在着不可调和的矛盾。这种情况，对C++游戏程序员提出了更高的要求。 </span></p><p>  <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">首先，基本C++知识，C/C++运用技能，必须极其扎实。并不是游戏软件开发用到什么平时书本上很难得到的知识点或者技能点。游戏C++开发的知识体系和技能体系，利用现有C++书籍就可以满足。比如《C++ PAORGRAMMING LANGUAGE》《C++ PRIMER》《EFFECT C++》《MORE EFFECT C++》等。但是在开始游戏编程之前，把这些书本吃透并且实践熟练的人，非常难遇到。当然能够真做到这点的人，已经是个中高级C++程序员了。我曾经遇到过一个，毕业工作不久就去了GOOGLE </span></p><p>  <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">其次，对于面向对象的深入理解。是非常重要的。熟练掌握C/C++语法，编程技巧，只是满足了C++游戏程序员一部分要求。而面向对象观念的深刻理解，会为大型C++项目开发带来翻天覆地的变化。 有时候，在一个10人以上并行开发的C++游戏项目中，面向对象方法会成为救命稻草。《设计模式》以及《设计模式解析》相关的书籍，也是必修课。 </span></p><p>  <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">最后，好技术人员的本质是自大的。这属于正常。但是如果这种习性影响了自身继续提高和团队合作。以及影响了其成为技术管理者和项目技术核心时，那么这种技术人员的自身价值会大打折扣。 如果早日越过自命不凡这一关，扩大眼界，继续在综合素质上提高。在技术管理能力，架构能力上提高，其自身价值才会继续增长。落到实处，就是待遇和身家增长。 </span></p><p>  <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">由于游戏开发的本质是团队开发。任何时候，只有对一个团队有价值的技术人员，其本身的价值才有可能得以体现。 </span></p><p><span style="font-family: &quot;Times New Roman&quot;; font-size: 10.5pt; font-weight: bold;yes&quot;;">3</span> <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt; font-weight: bold;yes&quot;;">，成长和技术发展路线 </span></p><p><span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">一般技术人员发展有几个阶段 </span></p><p><span style="font-family: &quot;Times New Roman&quot;; font-size: 10.5pt;yes&quot;;">1</span> <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">，具备独立开发局部功能的能力 </span></p><p><span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">比如为某个UI编写逻辑接口函数。为某个LOGIN对话框编写自绘制控件等。 </span></p><p><span style="font-family: &quot;Times New Roman&quot;; font-size: 10.5pt;yes&quot;;">2</span> <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">，具备独立开发和攻关某个功能模块的能力 </span></p><p><span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">比如为游戏增加一个小型逻辑功能模块。 </span></p><p><span style="font-family: &quot;Times New Roman&quot;; font-size: 10.5pt;yes&quot;;">3</span> <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">，具备独立设计并开发某个系统的能力 </span></p><p><span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">比如设计和开发AUTOPATCH 系统 </span></p><p><span style="font-family: &quot;Times New Roman&quot;; font-size: 10.5pt;yes&quot;;">4</span> <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">，具备解决技术难题，设计架构的能力 </span></p><p><span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">比如开发网络同步仿真系统，开发一个中大型游戏制作工具 </span></p><p><span style="font-family: &quot;Times New Roman&quot;; font-size: 10.5pt;yes&quot;;">5</span> <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">，具备整体架构，管理，协调其他人共同开发一个大系统的能力 </span></p><p><span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">客户端主程，服务器主程，引擎主程等 </span></p><p><span style="font-family: &quot;Times New Roman&quot;; font-size: 10.5pt;yes&quot;;">6</span> <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">，技术director </span></p><p><span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">制定技术发展方向，技术团队建立，技术管理等 </span></p><p>&nbsp;</p><p>  <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">在迈向每个阶段的过程中，伴随的都是巨大的工作量和工程压力。有时候是跨越1年的失败等等。在公司项目不成功时转换单位，重新开始，或者继续做为核心团队留在公司继续从新的机会做起，都是好的办法。但关键是吸取经验教训，尽量多学多练。并且结合自身长处发展。当然，游戏制作人员，最好还是依靠一个核心团队。成为核心团队的一员。 </span></p><p>  <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">能够达到第三档的程序，已经是公司不可缺少的人才了。但往往程序员自身对自己的认识，和公司对其的认识，有时候会有差异。我碰到过一些人，脑子好用，写东西很快。各种技术都有涉猎。但总是不放心让他独立开发设计某个系统。哪怕是相对独立的工具。也会被搞得一塌糊涂。要后面人不停擦屁股。可自己还觉着自己水平很高。这种人浮躁，眼高手低，不愿意细致周全的做好一件完整的事。所以就可以看到他不停的跳来跳去，可在新公司的职位也没有见多么提高。公司非常重视交给一个程序员一件事，他是否能完整，考虑周全的把事情做完。哪怕时间长一点，也不能不做完。这会给工程带来致命的后果。 </span></p><p style="margin-top: 5pt; layout-grid-mode: char;"><span style="font-family: &quot;Times New Roman&quot;; font-size: 10.5pt; font-weight: bold;yes&quot;;">4</span> <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt; font-weight: bold;yes&quot;;">，发展待遇 </span></p><p>  <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">从自身经验出发谈一下公司是怎么考虑技术员工待遇的。 </span></p><p>  <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">前面提到的6档，粗略了划分了待遇水平。其实到了第三档，你的待遇已经是这个行业所决定的了。而不是某个公司决定的。因为游戏业大量缺乏这样的C++程序员。如果具备这个水平，在几个大城市游戏公司找到工作并不难。大公司提升慢，还有我这种不到百人规模的公司要。所以行业价格才是公司要考虑的。如果给少了，软件项目的C++程序员流失会带来较大影响。但给的多，其实是C++程序员自己的价值增长瓶颈。如果几年下来一直以为自己水平就该拿这么高，结果到了一家整体技术水平比较高的企业，就会彻底傻眼。这个时候再放低心态去重新开始，对技术员来讲就是件很艰难的事了。 </span></p><p>  <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">在目前游戏行业技术水平普遍较低的情况下，哄抬程序员工资水平对程序员自身好处也不会很大。就算一个新手本来拿几千的水平，给他1万。他根本就不会知道自己到底有多少水。一年下来也就多拿了3－4万人民币。可耽误的是学习，影响了心态。而那些心态好，知道努力方向的技术人员，干个3－5年后如果有拿期权和股权的机会，比那些一开始虚高的人，身家就不知道高多少倍了。 </span></p><p>&nbsp;</p><p>  <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">下面再谈谈我个人在招聘C++程序的体会。 </span></p><p><span style="font-family: &quot;Times New Roman&quot;; font-size: 10.5pt;yes&quot;;">     1 </span> <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">做为C++程序员，成长周期比较长。如果是新手（代码量少于2万，没有做过大型项目的），会考察3点。是否踏实肯钻研，有无责任心，以及是否够聪明。如今，满足这三点的人其实不多。 </span></p><p>  <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">责任心是人品，决定了是否对公司有贡献。这是最重要的。有些人其实很自私。这种人对公司贡献是负数。而且到头来，自身价值也很难起来。因为技术是要靠游戏的商业成功体现价值的。要取得商业成功，就需要一个团队为一件事付出。是否踏实决定了能学会多少技术知识。关于智商，我是最近2年才意识到人的智商确实有很大差别。干程序这行，智商必须越高越好。否则前途不大。 </span></p><p><span style="font-family: &quot;Times New Roman&quot;; font-size: 10.5pt;yes&quot;;">    2 </span> <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">如果是有过2－3年C++程序经验的人，应考察的是人品，是否自大，是否有合作意识，是否跳槽频繁。 </span></p><p>  <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">首先还是责任心。太自私，太为自己着想，时刻把自己利益看成最重要的人，到哪里都不会受欢迎。无论他技术有多好。 </span></p><p>  <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">然后考察的是是否自大。人最容易自大的时候，往往是对一门技术已经入门，取得一定的小成就。但是眼界还没有开阔，没有领略到这个领域真正深入的技术知识。周围缺少好技术的人。这个时候，技术人员都容易自大。适度的自信和自大是允许的。但是目空一切就完蛋了，说明这个技术人员的提升空间很小。  </span></p><p>  <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">合作意识是游戏开发的关键。包括交流能力，思考和解决问题的思维方式。一个喜欢独来独往的技术人员，在游戏团队里是个很可怕的事情。因为游戏软件不是一个人能够完成的事情。由于逻辑复杂，需要各种专业技术领域知识，需求变动频繁。每一步都需要团队通力配合。缺乏这种意识，或者对团队开发不适应有抵触的技术人员，在游戏开发领域存活的希望不大。 </span></p><p>  <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">做为一个C++程序员，跳槽频繁的履历是很致命的。做C++时间长的人都知道。进入一个庞大的C++软件工程本身就需要不少时间。经过培训，项目熟悉，在为项目做贡献，这个时间短不了。如果一个人经常跳槽，说明他一直没有踏实在一个项目里深入做过核心的东西。或者做失败一个马上跑掉。这种人公司不敢要。 </span></p><p><span style="font-family: &quot;Times New Roman&quot;; font-size: 10.5pt;yes&quot;;">     3 </span> <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">对于有专项技能的程序员，比如图形程序员。C++只要入门有培训空间即可。但对专业要求比较高。应该是已经在某个技术领域钻研比较深。 当然最后在公司还是得成为使用C++熟练的高级程序员。因为任何专业领域的技术如果要应用到工程中，还必须用C++做工具。 </span></p><p><span style="font-family: &quot;Times New Roman&quot;; font-size: 10.5pt;yes&quot;;">     4 </span> <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">好的C++游戏程序员，其实不容易找。如果他干得好，早就成为项目核心成员。如果项目不错，自身待遇也会很好很稳定。不需要通过一般应聘渠道应聘。不是被拉到公司做核心技术拿期权，就是自己创业。 </span></p><p>&nbsp;</p><p>  <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">这里我打个比方。网易有个云风。大家都知道他是大话西游2的客户端主程。他是中国第一个做开源C++游戏引擎的人。开放了一整套C++游戏引擎代码。这是他大学时做的。毕业后去网易。有了平台，做成了中国历史上最成功的MMO之一。做为游戏技术人员，他的价值可以说已经是很高的了。到底有多高，我们都不好瞎说什么具体数字。但可以这么刨析一下。 </span></p><p>  <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">一个经验丰富的C/C++程序员。有过中国自主研发在线过百万游戏的成功项目经验。目前有网易出钱让其独立领导队伍搞引擎和游戏产品已经快3年。这样的一个履历，经验，本身就价值很高。他在任何公司都可以找到年薪几十万的工作。如果他具备管理才能。哪怕就是项目管理，或者技术管理能力。对于一个上市公司，他能做出的贡献，应该用百万/年量级来衡量。如果他能找到一个商业人士，负责舵手，并且自己具备一定商业能力，独立创业。吸引的天使风险投资也得几千万（否则做不了事，当然）。如果产品能做成，身家到达几千万是很自然的事。 </span></p><p>  <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">我相信中国游戏程序员水平，运气，发展空间比他高的人不多。那么我们可以拿他做个标杆。 </span></p><p>  <span style="font-family: &quot;宋体&quot;; font-size: 10.5pt;yes&quot;;">我知道很多人不服他。不过这里说的问题并不是关于他本人的。也不需要对他本人做什么服不服的评判。做为一个社会的人，不是靠能写多少行代码，代码多么优雅水平多么高来衡量身家的。从这点说，技术没有转化为成功商业产品之前，它的价值为0。做为技术人员，社会衡量他价值的标准，并不是要去阅读代码是否质量优越速度飞快。而是看他能为一个成功商业产品或者公司发展做出多少贡献。这个道理，几年前我还不太明白。而且我做为一个技术人员，相信多数技术员同胞们都不太可能从根儿上理解和认同这个看法。这里不是评判水平，而是评判价值。你的价值代表了你能够拿到的待遇。这个不是某个老总说了算，某个公司说了算，而是取决于人均GDP和当前行业发展水平，行业销售额的。我想这个道理也适用于所有游戏制作相关人员。搞制作的都是技术人员。</span></p>转自：http://www.cnblogs.com/puzzy3d/archive/2011/11/02/2232672.html<img src ="http://www.cppblog.com/flyinghare/aggbug/190141.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghare/" target="_blank">会飞的兔子</a> 2012-09-10 19:03 <a href="http://www.cppblog.com/flyinghare/archive/2012/09/10/190141.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>跑步的好处</title><link>http://www.cppblog.com/flyinghare/archive/2012/05/15/174954.html</link><dc:creator>会飞的兔子</dc:creator><author>会飞的兔子</author><pubDate>Tue, 15 May 2012 03:36:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghare/archive/2012/05/15/174954.html</guid><wfw:comment>http://www.cppblog.com/flyinghare/comments/174954.html</wfw:comment><comments>http://www.cppblog.com/flyinghare/archive/2012/05/15/174954.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghare/comments/commentRss/174954.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghare/services/trackbacks/174954.html</trackback:ping><description><![CDATA[<span style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; ">1.告别臃肿身材。&nbsp;</span><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><span style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; ">许多人开始跑步就是因为减肥，跑步确实减肥的最好运动方式，跑步每分钟比起其他运动燃烧更多的卡路里。&nbsp;</span><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><span style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; ">2.防止你的骨骼，肌肉退化。&nbsp;</span><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><span style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; ">我们的骨骼是和你的身体需求相互协调的。长期坐在显示器前的我们让我们的骨骼越来越脆弱。而长期的，经常的运动会使你的骨骼保持健康。更进一步说就是防止我们身体内部老化的更快。经常的高强度锻炼，例如跑步，被证明可以促进人体荷尔蒙的生长，荷尔蒙就是那些名人为了看起来更年轻而持续注射的药剂。&nbsp;</span><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><span style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; ">3.抵抗疾病&nbsp;</span><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><span style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; ">跑步可以降低得中风和乳腺癌的风险。经常的跑步已经成为医生对那些容易引发或在已经处在早期的骨质疏松，糖尿病，高血压病人的治疗建议。&nbsp;</span><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><span style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; ">4.维持并提高总体的身体水平。&nbsp;</span><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><span style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; ">跑步是是人们可以采取的最好的锻炼身体的运动。它可以提高胆固醇,降低血液凝块的危险，锻炼你的50%的经常处于闲置状态的肺。跑步还可以通过增加你的淋巴细胞来增强你的免疫力。&nbsp;</span><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><span style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; ">5.让你更加自信。&nbsp;</span><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><span style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; ">慢跑像其他一些单人运动一样，它可以增强你的自信心。跑步让你完成一次又一次的尝试，让你变得更强大，更加肯定自己。他让你真实的越过某个山峰，穿过某个障碍.在意识到你的身体已经更加强壮，更加有用，你会得到被赋予力量和自由的感觉。自信更是那些通过跑步成功的减肥并得到自己心中理想身材的跑步者的宝贵财富。&nbsp;</span><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><span style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; ">6.放松自己，减轻压力。&nbsp;</span><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><span style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; ">慢跑可以转移聂注意力，沐浴在路旁的风景中，你的烦恼一定会消失殆尽。&nbsp;</span><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><span style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; ">长跑适合那些正处在一堆头疼，恼人的烦心事的人。还有比在两个小时的长跑中，清理的的头脑、舒缓自己的神经更好的主意了吗。&nbsp;</span><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><span style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; ">如果你此时觉得异常压抑，何不快跑一下呢，之后你会一个好的心情。&nbsp;</span><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><span style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; ">7.著名的&#8220;跑步者高峰体验&#8221;&nbsp;</span><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><span style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; ">包括释放压力，慢跑被证明提高你的心态。跑步，特别在户外和旅行中,会使身体释放一种物质让你产生一种幸福愉悦感（跑步者高峰体验）或者就是快乐的感觉。跑步已经被采用了多年来治疗临床抑郁症，上瘾等。更少的压力，更少的压抑，更少的疲劳，更少的混乱，经过一段时间的经常跑步，病人很快就有了变化。跑步让他们有了注意的对象，让他们看到了除了他们消极的状态和沉溺的事务，还有一些美好的东西的存在。&nbsp;</span><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><span style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; ">8.锻炼你的头脑。&nbsp;</span><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><span style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; ">像对你的身体有所帮助一样，跑步同样对你的头脑很有帮助。通过在跑步中克服一系列的障碍，你学会了专注和决心.在经历那些你几乎要放弃的长跑或其他项目后你会发现：你在跑步过程中产生的意志和体魄的增强让你在其他方面有着同样的专注和决心。&nbsp;</span><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><span style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; ">9.增强合作精神。&nbsp;</span><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><span style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; ">又是一个非常值得去做的好处。这点好处或许让很多人感到惊奇，因为人们认为跑步不可能得到这种益处，仅仅由于跑步是单人运动。但是跑步确实有时涉及到互相合作。旅行跑步，特别是在那些路况不好的地方，需要极大的合作意识。这些路面经常会有一些 障碍如石头、灌木让跑步进行的很困难。&nbsp;</span><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><span style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; ">10.随时随地，简单。&nbsp;</span><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><span style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; ">不是很多的运动可以在任何地方，几乎不需要设备的。我敢肯定古代希腊人会争辩说甚至是鞋子和衣服也不需要。今天，我们只是需要一双好点的跑步鞋然后就可以出发了。从市中心到郊区,整个世界的地方等待你的探索。经常出差吗？你的旅行箱里肯定会有空间来装你的运动鞋的。这个世界就是你的健身房，去再次发现它吧。&nbsp;</span><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><span style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; ">Here are some tips for how to make running a practice:&nbsp;</span><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><span style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; ">Be consistent in your running program. Plan your weekly workout schedule and stick to it. This will teach you persistence.&nbsp;</span><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><span style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; ">Know which focuses you'll use during every run. This will teach you planning and mindfulness, and improve your mind/body connection.&nbsp;</span><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><span style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; ">Constantly practice relaxing your muscles. This will help to relieve tension and train you to relax no matter what activity you're doing.&nbsp;</span><br style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; " /><span style="color: #111111; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; ">At the end of your run, spend a few minutes doing an "end-of-run review." Ask yourself how well you did with keeping your focuses, how your body felt during the run. What did you come away with that will help your next run? Then, the next time you go out for a run, you'll have something to work on that you brought forward from your last run. In this way you'll build a healthy, growing and sustainable running program.&nbsp;</span>&nbsp;<br />转自：<a href="http://www.douban.com/group/topic/20749798/">http://www.douban.com/group/topic/20749798/</a><img src ="http://www.cppblog.com/flyinghare/aggbug/174954.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghare/" target="_blank">会飞的兔子</a> 2012-05-15 11:36 <a href="http://www.cppblog.com/flyinghare/archive/2012/05/15/174954.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何成为“10倍效率”开发者</title><link>http://www.cppblog.com/flyinghare/archive/2011/12/28/162963.html</link><dc:creator>会飞的兔子</dc:creator><author>会飞的兔子</author><pubDate>Wed, 28 Dec 2011 01:10:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghare/archive/2011/12/28/162963.html</guid><wfw:comment>http://www.cppblog.com/flyinghare/comments/162963.html</wfw:comment><comments>http://www.cppblog.com/flyinghare/archive/2011/12/28/162963.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghare/comments/commentRss/162963.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghare/services/trackbacks/162963.html</trackback:ping><description><![CDATA[<div><p style="line-height: 25px; text-align: left; font-family: Helvetica, Tahoma, Arial, sans-serif; background-color: #f8fafd; "><strong>导读：Brad Feld的一篇文章</strong><a target="_blank" href="http://www.forbes.com/sites/venkateshrao/2011/12/05/the-rise-of-developeronomics/" style="color: #015fb6; text-decoration: none; "><strong>The Rise of Developeronomics</strong></a><strong>中提到了&#8220;10倍效率的开发者（10x developer）&#8221;的概念（伟大的开发者的效率往往比一般的开发者高很多，而不只是一点点），Adam Loving在读了之后受到启发，并向多位大牛（Ben Sharpe、Collin Watson和Jonathan Locke）询问如何成为&#8220;10倍效率的开发者&#8221;，最后得到了以下的答案。</strong></p><p style="line-height: 25px; text-align: left; font-family: Helvetica, Tahoma, Arial, sans-serif; background-color: #f8fafd; "><strong>1. 只做需要做的工作</strong></p><ul style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 20px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 12px; line-height: 18px; text-align: left; background-color: #f8fafd; "><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: disc; font-size: 14px; line-height: 25px; ">使用敏捷方法；</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: disc; font-size: 14px; line-height: 25px; ">全心全意做UX设计；</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: disc; font-size: 14px; line-height: 25px; ">沟通第一；</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: disc; font-size: 14px; line-height: 25px; ">编码也许不是解决问题的办法；</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: disc; font-size: 14px; line-height: 25px; ">过早的优化是一切罪恶的根源；</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: disc; font-size: 14px; line-height: 25px; ">选择最简单的解决方案。</li></ul><p style="line-height: 25px; text-align: left; font-family: Helvetica, Tahoma, Arial, sans-serif; background-color: #f8fafd; "><strong>2. 站在巨人的肩膀上</strong></p><ul style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 20px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 12px; line-height: 18px; text-align: left; background-color: #f8fafd; "><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: disc; font-size: 14px; line-height: 25px; ">使用开源框架；</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: disc; font-size: 14px; line-height: 25px; ">使用简洁语言（如HAML、Jade、Coffeescript）；</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: disc; font-size: 14px; line-height: 25px; ">不要做重复的事情（不要重新发明轮子）；</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: disc; font-size: 14px; line-height: 25px; ">利用包管理器来进行公共和私有代码分配；</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: disc; font-size: 14px; line-height: 25px; ">不要任凭巨头（如微软）的摆布而修复库中的一个Bug；</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: disc; font-size: 14px; line-height: 25px; ">不要让你的雇主逼你学习；</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: disc; font-size: 14px; line-height: 25px; ">自主学习并为自己设定新的目标。</li></ul><p style="line-height: 25px; text-align: left; font-family: Helvetica, Tahoma, Arial, sans-serif; background-color: #f8fafd; "><strong>3. 了解数据结构和算法</strong></p><p style="line-height: 25px; text-align: left; font-family: Helvetica, Tahoma, Arial, sans-serif; background-color: #f8fafd; ">如果你不知道什么时候应该使用快速排序、不懂辨认O(n2)程序、不会写递归函数，你将无法成为10倍效率的开发者。使用多种语言你才能清楚不同的框架是如何解决相同问题的。尽可能去了解底层命令（plumbing），以便能够作出明智的决定（Web框架是怎么存储session状态的？Cookie到底是什么？）。</p><p style="line-height: 25px; text-align: left; font-family: Helvetica, Tahoma, Arial, sans-serif; background-color: #f8fafd; "><strong>4. 不要怕买工具，它可以节省你的时间</strong></p><p style="line-height: 25px; text-align: left; font-family: Helvetica, Tahoma, Arial, sans-serif; background-color: #f8fafd; ">Ben说：&#8220;昨天我花50美元买了一个位图字体工具，它帮我节省的时间成本绝对超过200元。&#8221;</p><p style="line-height: 25px; text-align: left; font-family: Helvetica, Tahoma, Arial, sans-serif; background-color: #f8fafd; "><strong>5. 集中注意力</strong></p><p style="line-height: 25px; text-align: left; font-family: Helvetica, Tahoma, Arial, sans-serif; background-color: #f8fafd; ">不要整天开着你的电子邮件、Twitter、Facebook等，在工作时将它们最小化或关掉它们，戴上耳机。Tiny hack说：&#8220;即使不听音乐我也戴着耳机工作，这样便不会有人打扰到我。&#8221;</p><p style="line-height: 25px; text-align: left; font-family: Helvetica, Tahoma, Arial, sans-serif; background-color: #f8fafd; "><strong>6. 尽早并且经常性地进行代码重构</strong></p><p style="line-height: 25px; text-align: left; font-family: Helvetica, Tahoma, Arial, sans-serif; background-color: #f8fafd; ">有时，你不得不放弃漂亮的代码转而去寻找真正对项目有用的代码，但没关系，如果你的现有项目中有这样的代码，最好的方式便是不要看它，并重构。</p><p style="line-height: 25px; text-align: left; font-family: Helvetica, Tahoma, Arial, sans-serif; background-color: #f8fafd; "><strong>7. 只管去做</strong></p><p style="line-height: 25px; text-align: left; font-family: Helvetica, Tahoma, Arial, sans-serif; background-color: #f8fafd; ">将你的业余项目分享到<a target="_blank" href="http://startupweekend.org/" style="color: #015fb6; text-decoration: none; ">Startup Weekend</a>中。在我开始转到Unix和Ruby on Rails上之前，我买了一台Mac，使用Windows虚拟机花了一年时间做.NET项目。</p><p style="line-height: 25px; text-align: left; font-family: Helvetica, Tahoma, Arial, sans-serif; background-color: #f8fafd; "><strong>8. 挑选一个编辑器，并掌握它</strong></p><p style="line-height: 25px; text-align: left; font-family: Helvetica, Tahoma, Arial, sans-serif; background-color: #f8fafd; ">高效开发者喜欢用文本编辑器胜过IDE编辑器，因为这样可以学到更多东西。无论什么情况，尽量使用键盘快捷键，因为熟练使用一件工具的前提是熟悉它。</p><p style="line-height: 25px; text-align: left; font-family: Helvetica, Tahoma, Arial, sans-serif; background-color: #f8fafd; ">在选择编辑器时，认真考虑并挑选最好的（Emacs或Vim），因为它们是通用的。其次，挑选你的首选平台最支持的。使用宏，不断地写代码；使用 Mac上的TextExpander为整个段落创建快捷方式；使用Visual Studio或SublimeText的自动补齐功能；使用支持按行/列分割窗口的编辑器，这样你便能同时看到单元测试和代码（或模型、视图）。</p><p style="line-height: 25px; text-align: left; font-family: Helvetica, Tahoma, Arial, sans-serif; background-color: #f8fafd; ">一定要想清楚后再写代码。Adam说，&#8220;我有朋友在一个大项目组里工作，他们组里最高效的程序员是一个高位截瘫用嘴叼着棍子敲代码的人，他总是在写代码之前想得很仔细且很少出错。&#8221;</p><p style="line-height: 25px; text-align: left; font-family: Helvetica, Tahoma, Arial, sans-serif; background-color: #f8fafd; "><strong>9. 整洁的代码胜过巧妙的代码</strong></p><p style="line-height: 25px; text-align: left; font-family: Helvetica, Tahoma, Arial, sans-serif; background-color: #f8fafd; ">要想让其他人能够读懂你的代码，尽量使用最少的代码来完成任务。遵循DRY（Don't repeat yourself）的原则，使用明确定义的对象和库，将任务分解成小而简单的代码段。</p><p style="line-height: 25px; text-align: left; font-family: Helvetica, Tahoma, Arial, sans-serif; background-color: #f8fafd; "><strong>10. 潜意识是强大的工具</strong></p><p style="line-height: 25px; text-align: left; font-family: Helvetica, Tahoma, Arial, sans-serif; background-color: #f8fafd; ">离开10分钟往往就可以解决一个问题。控制编程时间，给自己一个多姿多彩的生活，劳逸结合能让你在工作时更高效、更愉悦。当然，即便是上了年纪的程序员也知道，以最少的时间完成最高效的工作是成为10倍效率开发者的必要条件。</p><p style="line-height: 25px; text-align: left; font-family: Helvetica, Tahoma, Arial, sans-serif; background-color: #f8fafd; ">作为一个程序员，我觉得在职业生涯中最好的一件事儿就是从电脑前站起来，去拜访那些在某一领域有所建树的人们。</p><p style="line-height: 25px; text-align: left; font-family: Helvetica, Tahoma, Arial, sans-serif; background-color: #f8fafd; "><strong>11. 推动自身和团队进步</strong></p><p style="line-height: 25px; text-align: left; font-family: Helvetica, Tahoma, Arial, sans-serif; background-color: #f8fafd; ">重视批评，以包容的态度接受批评并提升自己是非常重要的事情。没有这个基础，你不可能成为一个高效的开发者。一位智者曾经说过：&#8220;聪明的人善于从自己的错误中学习，而智慧的人善于从别人的错误中学习。&#8221;</p><p style="line-height: 25px; text-align: left; font-family: Helvetica, Tahoma, Arial, sans-serif; background-color: #f8fafd; ">英文出自：<a target="_blank" href="http://adamloving.com/internet-programming/10x-developers" style="color: #015fb6; text-decoration: none; ">adamloving</a></p><p style="line-height: 25px; text-align: left; font-family: Helvetica, Tahoma, Arial, sans-serif; background-color: #f8fafd; ">译文出自：<a target="_blank" href="http://www.iteye.com/news/23799" style="color: #015fb6; text-decoration: none; ">ITeye</a></p><div style="text-align: center; font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 12px; line-height: 18px; background-color: #f8fafd; "></div></div><img src ="http://www.cppblog.com/flyinghare/aggbug/162963.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghare/" target="_blank">会飞的兔子</a> 2011-12-28 09:10 <a href="http://www.cppblog.com/flyinghare/archive/2011/12/28/162963.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> TFS: 回滚变更集</title><link>http://www.cppblog.com/flyinghare/archive/2011/06/16/148752.html</link><dc:creator>会飞的兔子</dc:creator><author>会飞的兔子</author><pubDate>Thu, 16 Jun 2011 00:43:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghare/archive/2011/06/16/148752.html</guid><wfw:comment>http://www.cppblog.com/flyinghare/comments/148752.html</wfw:comment><comments>http://www.cppblog.com/flyinghare/archive/2011/06/16/148752.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghare/comments/commentRss/148752.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghare/services/trackbacks/148752.html</trackback:ping><description><![CDATA[<font class="Apple-style-span" face="verdana, sans-serif"><span style="font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; ">团队首次使用TFS开发，很快便需要使用回滚功能，结果虽然找到了&#8220;获取特定版本&#8221;和&#8220;历史&#8221;功能，却不知如何回滚。最后在msdn上找到一篇文章，如下。没想到居然是用如此手动的方法&#8230;&#8230;<br /><br /><div>如何：回滚变更集</div><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; "></p><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">虽然变更集是记录的永久部分，从技术上无法撤消或移除，但您仍然可以通过使用以下过程有效地&#8220;回滚&#8221;变更集。此过程是更正签入错误的常用方法。</p><div><table width="100%"><tbody><tr><th align="left"><img alt="Note" src="http://i.msdn.microsoft.com/ms194956.note%28zh-cn,VS.80%29.gif" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; " />注意</th></tr><tr><td><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">以下步骤针对单个<span style="line-height: 21px; ">file</span>，但对于一组文件来说，此过程也是相同的。</p></td></tr></tbody></table></div><h3>还原为文件以前的版本</h3><div><ol style="margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 35px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; "><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 2px; padding-right: 0px; padding-bottom: 2px; padding-left: 0px; list-style-type: decimal; "><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">在源代码管理资源管理器中，右击要回滚其变更集的文件，然后单击上下文菜单中的&#8220;获取特定版本&#8221;。</p></li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 2px; padding-right: 0px; padding-bottom: 2px; padding-left: 0px; list-style-type: decimal; "><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">在&#8220;获取&#8221;对话框中，选择文件以前的版本，然后单击&#8220;获取&#8221;。有关更多信息，请参见<a id="ctl00_rs1_mainContentContainer_ctl01" href="http://msdn.microsoft.com/zh-cn/library/ms181416%28VS.80%29.aspx" style="text-decoration: none; color: #336699; ">如何：检索变更集中文件的旧版本</a>。</p></li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 2px; padding-right: 0px; padding-bottom: 2px; padding-left: 0px; list-style-type: decimal; "><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">当此文件已位于您的工作区中之后，右击此文件，然后单击上下文菜单中的&#8220;签出以进行编辑&#8221;。</p></li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 2px; padding-right: 0px; padding-bottom: 2px; padding-left: 0px; list-style-type: decimal; "><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">再次右击此文件，然后单击&#8220;签入挂起的更改&#8221;。</p></li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 2px; padding-right: 0px; padding-bottom: 2px; padding-left: 0px; list-style-type: decimal; "><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">在&#8220;签入 - 源文件&#8221;对话框中，选择文件，然后单击&#8220;签入&#8221;。</p><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">随即出现&#8220;解决冲突&#8221;对话框。</p></li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 2px; padding-right: 0px; padding-bottom: 2px; padding-left: 0px; list-style-type: decimal; "><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">单击&#8220;解决&#8221;以打开&#8220;解决版本冲突&#8221;对话框。</p></li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 2px; padding-right: 0px; padding-bottom: 2px; padding-left: 0px; list-style-type: decimal; "><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">选择&#8220;放弃服务器更改&#8221;。</p></li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 2px; padding-right: 0px; padding-bottom: 2px; padding-left: 0px; list-style-type: decimal; "><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">单击&#8220;确定&#8221;。</p><div><table width="100%"><tbody><tr><th align="left"><img alt="Note" src="http://i.msdn.microsoft.com/ms194956.note%28zh-cn,VS.80%29.gif" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; " />注意</th></tr><tr><td><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">若要在放弃服务器更改之前复查您的决定，可以单击&#8220;比较&#8221;以同时查看服务器和本地副本。</p></td></tr></tbody></table></div></li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 2px; padding-right: 0px; padding-bottom: 2px; padding-left: 0px; list-style-type: decimal; "><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">在&#8220;解决冲突&#8221;对话框中，单击&#8220;关闭&#8221;。</p></li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 2px; padding-right: 0px; padding-bottom: 2px; padding-left: 0px; list-style-type: decimal; "><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">在源代码管理资源管理器中，右击文件，然后单击&#8220;签入挂起的更改&#8221;。</p></li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 2px; padding-right: 0px; padding-bottom: 2px; padding-left: 0px; list-style-type: decimal; "><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">在&#8220;签入 - 源文件&#8221;对话框中，单击&#8220;签入&#8221;。<br /><br /><br />转自：<a href="http://blog.csdn.net/Gildor/archive/2008/08/27/2840288.aspx">http://blog.csdn.net/Gildor/archive/2008/08/27/2840288.aspx</a></p></li></ol></div></span></font><img src ="http://www.cppblog.com/flyinghare/aggbug/148752.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghare/" target="_blank">会飞的兔子</a> 2011-06-16 08:43 <a href="http://www.cppblog.com/flyinghare/archive/2011/06/16/148752.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Visual Studio TFS 团队项目和集合指南</title><link>http://www.cppblog.com/flyinghare/archive/2011/05/12/146255.html</link><dc:creator>会飞的兔子</dc:creator><author>会飞的兔子</author><pubDate>Thu, 12 May 2011 05:52:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghare/archive/2011/05/12/146255.html</guid><wfw:comment>http://www.cppblog.com/flyinghare/comments/146255.html</wfw:comment><comments>http://www.cppblog.com/flyinghare/archive/2011/05/12/146255.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghare/comments/commentRss/146255.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghare/services/trackbacks/146255.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Visual Studio TFS 团队项目和集合指南Willy-Peter Schaub&nbsp;和&nbsp;Mike Schimmel在&nbsp;MSDN 杂志&nbsp;文章，&#8220;Visual Studio TFS 分支和合并指南&#8221;(msdn.microsoft.com/magazine/gg598921) 中，Visual Studio ALM Ra...&nbsp;&nbsp;<a href='http://www.cppblog.com/flyinghare/archive/2011/05/12/146255.html'>阅读全文</a><img src ="http://www.cppblog.com/flyinghare/aggbug/146255.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghare/" target="_blank">会飞的兔子</a> 2011-05-12 13:52 <a href="http://www.cppblog.com/flyinghare/archive/2011/05/12/146255.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VSTS在实战中的应用系列（二）</title><link>http://www.cppblog.com/flyinghare/archive/2010/10/12/129605.html</link><dc:creator>会飞的兔子</dc:creator><author>会飞的兔子</author><pubDate>Tue, 12 Oct 2010 06:28:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghare/archive/2010/10/12/129605.html</guid><wfw:comment>http://www.cppblog.com/flyinghare/comments/129605.html</wfw:comment><comments>http://www.cppblog.com/flyinghare/archive/2010/10/12/129605.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghare/comments/commentRss/129605.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghare/services/trackbacks/129605.html</trackback:ping><description><![CDATA[<div>万事开头难。每个项目的起点都是从项目规划开始做起。因此怎样去做好规划对于项目意义重大。在VSTS中，项目规划的含义与我们普通开发过程中所讲的规划的并不是很相同。在VSTS中规划的内容主要分为三项：区域和迭代的划分、工作项定义。</div>
<div>&nbsp;</div>
<div>首先，我们必须知道什么是区域和迭代？一般说来，我们要想完整的把握项目，就会从好几个角度去观察和控制它。因为任何项目本身都是高度复杂的和关联的事物组合而成。这就意味着我们很难从单个角度就能将项目观察清楚。在普通过程中我们把这种角度称做&#8220;视点&#8221;，而在VSTS中这个视点被叫做&#8220;区域&#8221;。看到这里，我们可能会有个冲动，自然的认为全面考察项目最好的办法就是全角度去看问题。但如果那样做，我们就会失去对项目至关重要那部分的聚焦。因此我们需要规划出我们感兴趣的视点，以便能将为数不多的精力投入到这些对项目来说非常重要的区域里去。</div>
<div>&nbsp;</div>
<div>在这个项目中，我可以随心所欲的规划出许多种视点来。但为了提高效率以及增加成功性。&#8220;软件工厂&#8221;模式提出了两种最常用的区域：软件工程视点的和项目管理视点。因为所有的软件项目最终的目的都是以可运行的程序的形式存在，因此工程视点是保证项目成功的重要区域。而我们产品的质量却与项目管理密切相关，而质量也是保证成功的一个重要因素。因此项目管理视点也是我们关注的重要区域。而这两个大的视点只是决定了我们如何去关注我们的项目。是一种类似原则性的东西，若想落实，还须补充更多和更细的子视点，以这两个区域做进一步的细化。下图是我对这个项目的区域进行的规划。</div>
<div>&nbsp;</div>
<div><img border=0 alt="" src="http://www.cppblog.com/images/cppblog_com/flyinghare/liucheng2.jpg" width=500 height=493></div>
<div>&nbsp;</div>
<div>可以看出从工程角度来说，我关心的软件的架构方面的划分：UI、应用服务层、通用服务层、数据层，代表了为实现客户和商业上不同的价值所付出的努力。比如，由于UI层密切与用户利益相关，那么可能这个区域下的众多工作要和客户一起完成，或者需要请更加专业的用户体验专家来做。而通用服务层可能还需要服务公司其它项目。而基于这样的商业价值，很可能这个区域下的工作将除过考虑本项目自身的设计要求外，还需要考虑一些其它项目上的额外设计要求。这些重要的东西，都需要在我们划分的观点中得到体现。项目管理区域下的几个子区域，则代表了我们为了项目保证质量而在开发过程中所采取的努力。在定义好区域后，我们通过区域与迭代的组合，就能帮我们定位某个工作项所处的位置和性重要程度。</div>
<div>&nbsp;</div>
<div>再来看软件迭代。假设现在要发布一个新版本的软件系统。我们计划通过三次迭代过程，完成整个软件的发布，因此我们定义的迭代就如下图的形式：</div>
<div><img border=0 alt="" src="http://www.cppblog.com/images/cppblog_com/flyinghare/liucheng3.jpg" width=503 height=493></div>
<div>&nbsp;</div>
<div>每一个迭代过程都包括一个完整的发布流程。每一个迭代过程也都生成一个完整的软件版本。在三次迭代过程完成之后，我们就得到一个可以发布的最终版本。</div>
<div>&nbsp;</div>
<div>另一个规划中的重要方面，就是工作项的定义。这部分比较复杂，因此放在后一章中做详细说明。<br><br><br>转自：<a href="http://zhanghonglin.blog.51cto.com/314914/61453">http://zhanghonglin.blog.51cto.com/314914/61453</a></div>
<img src ="http://www.cppblog.com/flyinghare/aggbug/129605.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghare/" target="_blank">会飞的兔子</a> 2010-10-12 14:28 <a href="http://www.cppblog.com/flyinghare/archive/2010/10/12/129605.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VSTS在实战中的应用系列（一）</title><link>http://www.cppblog.com/flyinghare/archive/2010/10/12/129604.html</link><dc:creator>会飞的兔子</dc:creator><author>会飞的兔子</author><pubDate>Tue, 12 Oct 2010 06:26:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghare/archive/2010/10/12/129604.html</guid><wfw:comment>http://www.cppblog.com/flyinghare/comments/129604.html</wfw:comment><comments>http://www.cppblog.com/flyinghare/archive/2010/10/12/129604.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghare/comments/commentRss/129604.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghare/services/trackbacks/129604.html</trackback:ping><description><![CDATA[<div>中国武术的基本训练方法就是套路和招式。但是如果将这些套路和招式直接应用到实战当中去，其结果必将是吃亏落败的结局。这是因为招式和套路存在的目的是用来为习武的人提供可供学习的形式上的指南。套路中的每招每式都用来训练实际作战时可能用到的基本技能和技巧。因此对这些技能及技巧的掌握而不是对动作招式的简单重复，才是在实战中克敌制胜的真正重要的因素。</div>
<div>&nbsp;</div>
<div>VSTS是个关于软件生命周期管理的工具组合。它可以被认为是MSF方法论和各种项目管理工具的大集成。MSF软件过程将软件开发分为四个阶段：规划、计划、开发、稳定。而VSTS集合里的工具则为这四个阶段的实现提供了软件上的基础。可以看出，这里重要的中心都是直指开发过程而不是工具。但事实上许多人却反其道而行之，他们只是简单的使用VSTS中提供的那些工具，把VSTS当VSS的数据库版来使用。这是十分不正确的，花很大代价（此产品价格不菲：《）去做和以前相同的事情，就得好好想想真的有必要去改变它吗？正如前边讲到武术出现的情况一样，VSTS的威力不在于它的工具合集里的那些工具，而在于这些工具相互配合对于团队组织对方法论上的支持，那才是它的神。</div>
<div>&nbsp;</div>
<div>此次我打算用一系列文章，围绕一个项目Demo，说明一些我对VSTS使用上的认识。当然对VSTS产品的理解我自然是比不上微软的产品专家和技术支持了，论开发方法论我也比不过那些资深的&#8220;PMP&#8221;们。但我也有自己的优势，那就是自己既在搞项目管理又在搞微软产品的技术支持。这使得我有机会能将微软的产品应用到项目实践当中去。最重要的是，我的确想拿起笔来写些什么。</div>
<div>&nbsp;</div>
<div>关于我所介绍的项目，其来源是公司研发体系某部门的一次CMMI实践需要。这个部门的领导人很希望规范自己团队软件版本发布的流程。传统的方法需要投入一定的人力，专门针对流程进行管理和控制。这样就出现两方面的问题，首先是这些人究竟是什么角色？他们是否是开发专家、或者是测试专家、或者是流程管理专家。否则他们怎么拥有管理整个流程的权利和能力？其次，无数次的实践明这种做法大都是凶多吉少的。</div>
<div>&nbsp;</div>
<div>在这种情况下，部门领导人找到我，希望得到一个由过程自动管理活动的办法。很幸运，微软正好有基于VSTS的解决方案。这个解决方案包中提供一种叫做MSF的过程管理理论，而这种理论借助VSTS工具合集里的各种工具，实现了自动化管理过程中各类活动的问题。比如WIT实现的是项目计划的跟踪与管理、TFVC实现了版本控制、FXCOP实现了代码的优化、TF Build实现了构建管理、For Test版本则实现了测试管理。</div>
<div>&nbsp;</div>
<div>基于如此多的好处，部门领导人答应让我做一次内部的POC（有效性验证）过程。并给了我需求－一张流程图：</div>
<div><img border=0 alt="" src="http://www.cppblog.com/images/cppblog_com/flyinghare/liucheng.jpg" width=560 height=409></div>
<div>&nbsp;</div>
<div>这是个很标准的流程，因此我猜想用VSTS实现它应该不是件很难做的事情。OK，那么就让我们在下一章中开始动手做吧。</div>
转自：<a href="http://zhanghonglin.blog.51cto.com/314914/61140">http://zhanghonglin.blog.51cto.com/314914/61140</a>
<img src ="http://www.cppblog.com/flyinghare/aggbug/129604.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghare/" target="_blank">会飞的兔子</a> 2010-10-12 14:26 <a href="http://www.cppblog.com/flyinghare/archive/2010/10/12/129604.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Mantis1.2.3 + xampp1.6.0 安装和配置</title><link>http://www.cppblog.com/flyinghare/archive/2010/09/25/127583.html</link><dc:creator>会飞的兔子</dc:creator><author>会飞的兔子</author><pubDate>Sat, 25 Sep 2010 02:37:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghare/archive/2010/09/25/127583.html</guid><wfw:comment>http://www.cppblog.com/flyinghare/comments/127583.html</wfw:comment><comments>http://www.cppblog.com/flyinghare/archive/2010/09/25/127583.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghare/comments/commentRss/127583.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghare/services/trackbacks/127583.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 目前 xampp 的最新版是 1.7.3 ，但发现该版本搭配 mantis 经常会导致 mantis 首页无法响应，发现 httpd 进程无法释放内存（和这里描述的现象一样：<a href="http://bbs.51testing.com/viewthread.php?tid=281964"><u><font color=#800080>http://bbs.51testing.com/viewthread.php?tid=281964</font></u></a>）。<br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 经过反复试验，发现 xampp1.6.0 和 mantis 完美结合，目前还未发现使用问题。美中不住的是，xampp1.6.0 在 windows server 2008 企业版下（Windows Server 2003 也一样），无法正确的安装、卸载服务，只好按照如下迂回的办法进行解决：<br><br>&nbsp;&nbsp;&nbsp;&nbsp; 先将 xampp1.7.3 安装到 c 盘，用图形界面的控制台安装服务（apache 和 mysql），然后，将其 c:\xampp 改名为 c:\xampp1.7.3；（改名前需要停止 apache 和 mysql 服务）<br>&nbsp;&nbsp;&nbsp;&nbsp; 现在安装 xampp1.6.0 到 c 盘，并将 mysql 的配置文件&nbsp;<span> my.conf </span><span>拷贝一份，改名为</span><span> my.ini，然后在操作系统的服务管理中启动 apache 和 mysql 服务。（注意，不要使用 xampp1.6.0 提供的图形界面启动服务）</span></p>
<br><br>&nbsp;&nbsp;&nbsp;&nbsp; 安装后，我的 mantis 配置文件如下：<br><br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;$g_hostname&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;'localhost'</span><span style="COLOR: #008000">;<br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;$g_db_type&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;'mysql'</span><span style="COLOR: #008000">;<br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;$g_database_name&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;'bugtracker'</span><span style="COLOR: #008000">;<br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;$g_db_username&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;'root'</span><span style="COLOR: #008000">;<br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;$g_db_password&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;'****'</span><span style="COLOR: #008000">;<br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;$g_user_login_valid_regex&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;'/^.+$/i'</span><span style="COLOR: #008000">;</span><span style="COLOR: #008000">&nbsp;//'/^([a-z\d\-.+_&nbsp;]+(@[a-z\d\-.]+\.[a-z]{2,4})?)$/i';</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;$g_graph_font&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;'chinese_gbk'</span><span style="COLOR: #008000">;<br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;$g_default_language&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;'chinese_simplified'</span><span style="COLOR: #008000">;<br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;$g_validate_email&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;OFF</span><span style="COLOR: #008000">;<br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;$g_send_reset_password&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;OFF</span><span style="COLOR: #008000">;<br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;$g_default_timezone&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;'Asia/Shanghai'</span><span style="COLOR: #008000">;<br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;$g_session_validation&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;OFF</span><span style="COLOR: #008000">;<br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;$g_delete_bug_threshold&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;MANAGER</span>;<br>&nbsp;&nbsp;&nbsp;<span style="COLOR: #000000"> $g_allow_no_category &nbsp;= ON;</span></div>
<br><br>参考文献：<br>&nbsp;
<p style="MARGIN: 0in; FONT-FAMILY: 宋体; COLOR: #666666; FONT-SIZE: 8pt"><a href="http://bbs.51testing.com/viewthread.php?tid=281964"><u><font color=#800080>http://bbs.51testing.com/viewthread.php?tid=281964</font></u></a><br>&nbsp;</p>
<p style="MARGIN: 0in; FONT-FAMILY: 宋体; COLOR: #666666; FONT-SIZE: 8pt"><a href="http://blog.sina.com.cn/s/blog_56cbcff901009w6h.html"><u><font color=#800080>http://blog.sina.com.cn/s/blog_56cbcff901009w6h.html</font></u></a><br>&nbsp;</p>
<p style="MARGIN: 0in; FONT-FAMILY: 宋体; COLOR: #666666; FONT-SIZE: 8pt"><a href="http://www.boofee.net/flyingbamboo/archives/242"><u><font color=#800080>http://www.boofee.net/flyingbamboo/archives/242</font></u></a><br>&nbsp;</p>
<p style="MARGIN: 0in; FONT-FAMILY: 宋体; COLOR: #666666; FONT-SIZE: 8pt" lang=zh-TW><a href="http://cwlin0416.wordpress.com/2007/04/15/integrating-mantis-with-ldap/"><u><font color=#800080>http://cwlin0416.wordpress.com/2007/04/15/integrating-mantis-with-ldap/</font></u></a><br>&nbsp;</p>
<p style="MARGIN: 0in; FONT-FAMILY: 宋体; COLOR: #666666; FONT-SIZE: 8pt"><a href="http://www.dlresearch.cn/xtykc/?p=42"><u><font color=#800080>http://www.dlresearch.cn/xtykc/?p=42</font></u></a></p>
<img src ="http://www.cppblog.com/flyinghare/aggbug/127583.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghare/" target="_blank">会飞的兔子</a> 2010-09-25 10:37 <a href="http://www.cppblog.com/flyinghare/archive/2010/09/25/127583.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>去掉禅道访问地址中的zentao</title><link>http://www.cppblog.com/flyinghare/archive/2010/09/19/127072.html</link><dc:creator>会飞的兔子</dc:creator><author>会飞的兔子</author><pubDate>Sun, 19 Sep 2010 07:16:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghare/archive/2010/09/19/127072.html</guid><wfw:comment>http://www.cppblog.com/flyinghare/comments/127072.html</wfw:comment><comments>http://www.cppblog.com/flyinghare/archive/2010/09/19/127072.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghare/comments/commentRss/127072.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghare/services/trackbacks/127072.html</trackback:ping><description><![CDATA[<div style="MARGIN-BOTTOM: 0px" id=content>
<p>按照我们的安装步骤部署禅道之后，访问路径中还会有zentao之类的路径，肯定有朋友问，怎样把其去掉呢？其实很简单，我们一起来配置下。</p>
<p>要想去掉zentao的访问路径，就需要部署虚拟主机。</p>
<ol>
    <li>找到apache的配置文件，不同的系统，其配置文件位置不同。windows一般在apache/conf下面。linux一般在/etc/apache或者/etc/httpd下面。&nbsp;
    <li>找到虚拟主机配置文件。有的apache是单独分出来的一个vhost.conf。有的则是直接写在httpd.conf中。
    <li>找到虚拟主机配置文件之后，配置下面的代码：<br>&lt;VirtualHost *:80&gt;<br><span style="COLOR: #e53333">ServerName pms.zentao.net #换成你具体的域名。</span><br><span style="COLOR: #e53333">DocumentRoot /home/www/zentaopms/www/ #换成具体的zentao下面的www目录。</span><br>&lt;Directory /&gt;<br>Options FollowSymLinks<br>AllowOverride All<br>&lt;/Directory&gt; &nbsp;<br>&lt;/VirtualHost&gt;
    <li>修改zentao的配置文件，config/my.php。将其中的webRoot改成 /<br><span style="COLOR: #e53333">$config-&gt;webRoot = '/'; &nbsp;</span>
    <li>重新启动apache。<br></li>
</ol>
<br><br>转自：<a href="http://www.zentao.net/help-read-79186.html">http://www.zentao.net/help-read-79186.html</a></div>
<!-- editor-->
<img src ="http://www.cppblog.com/flyinghare/aggbug/127072.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghare/" target="_blank">会飞的兔子</a> 2010-09-19 15:16 <a href="http://www.cppblog.com/flyinghare/archive/2010/09/19/127072.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Team Foundation Server 权限</title><link>http://www.cppblog.com/flyinghare/archive/2010/09/03/125791.html</link><dc:creator>会飞的兔子</dc:creator><author>会飞的兔子</author><pubDate>Fri, 03 Sep 2010 06:45:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghare/archive/2010/09/03/125791.html</guid><wfw:comment>http://www.cppblog.com/flyinghare/comments/125791.html</wfw:comment><comments>http://www.cppblog.com/flyinghare/archive/2010/09/03/125791.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghare/comments/commentRss/125791.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghare/services/trackbacks/125791.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Team Foundation Server 权限权限决定了是否授权用户进行工作区管理和项目创建等操作。在 Team Foundation Server 中创建项目时，无论您选择哪个过程模板，都会为项目创建四个默认组。默认情况下，为这些组各自定义了一组权限，这些权限决定了组成员可以执行的操作。&#183;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&...&nbsp;&nbsp;<a href='http://www.cppblog.com/flyinghare/archive/2010/09/03/125791.html'>阅读全文</a><img src ="http://www.cppblog.com/flyinghare/aggbug/125791.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghare/" target="_blank">会飞的兔子</a> 2010-09-03 14:45 <a href="http://www.cppblog.com/flyinghare/archive/2010/09/03/125791.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>软件工厂简介</title><link>http://www.cppblog.com/flyinghare/archive/2010/08/29/125195.html</link><dc:creator>会飞的兔子</dc:creator><author>会飞的兔子</author><pubDate>Sun, 29 Aug 2010 12:50:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghare/archive/2010/08/29/125195.html</guid><wfw:comment>http://www.cppblog.com/flyinghare/comments/125195.html</wfw:comment><comments>http://www.cppblog.com/flyinghare/archive/2010/08/29/125195.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghare/comments/commentRss/125195.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghare/services/trackbacks/125195.html</trackback:ping><description><![CDATA[<div>
<div>发布日期 : 11/4/2004<span> | </span>更新日期 : 11/4/2004</div>
<p>Jack Greenfield</p>
<p>Microsoft Corporation</p>
<p><strong>摘要：</strong>简要介绍 Microsoft 开发软件工厂这种方法的动机。所谓软件工厂就是指为了支持某种特定应用程序的快速开发而配置的开发环境。软件工厂从逻辑上讲就是软件开发方法和实践的下一个发展阶段。然而，通过引入产业化模式，软件工厂势必会改变软件行业的现状。 </p>
<h3 id=EPAA>扩大软件开发的规模</h3>
<p>从目前的情况来看，软件开发的速度缓慢、代价高昂而又极易出错，常常会生产出存在大量缺陷的产品，在可用性、可靠性、性能、安全以及其他服务质量方面造成严重的问题。</p>
<p>根据 Standish Group [Sta94] 的统计，美国公司每年投资约 175,000 个软件开发项目，投资额约为 2,500 亿美元。这些项目中只有 16％ 能够在预算内按计划完成。另有 31％ 的项目主要由于质量问题而被取消，经济损失约为 810 亿美元。另外 53％ 的项目平均超出预算 189％，经济损失约为 590 亿美元。完成的项目平均只实现了原来规划的功能的 42％。</p>
<p>这些数字客观地印证了我们根据经验所做出的判断，那就是软件开发是一项劳动密集型的产业，它创造每一美元的价值所消耗的人力资本超过了我们对于一个现代化行业的期望值。</p>
<p>当然，除了这些缺点以外，软件开发的成果显然为消费者带来了巨大的价值，正如需求增长的长期趋势所表明的那样。但这并不意味着消费者已经非常满意，不管是对我们提供的软件，还是对我们提供软件的方式。这只是说明他们确实看好软件的前景，愿意承担巨大的风险和损失，以此来获得软件所带来的好处。然而，正如软件开发的外包越来越受欢迎所表明的，这种情况显然不是最好的，因为它似乎不能推动软件行业在软件开发方法和实践方面作出重大的改变。</p>
<p>在过去十年中，生产率只获得了有限的提高，最重要的原因可能是采用了字节编码的语言、模式和灵活的方法。除了这些进步，我们开发软件的方法与十年前没有什么不同。我们的方法和实践实际上没有太大的改变，相应的成本和风险同样也没有太大的改变。</p>
<p>然而，这种情况就要被改变。据预测，全球对软件的总体需求将在下一个十年中以数量级的速度增长，这是由于受到全球经济中的新生力量（例如中国的崛起）的推动，以及由于新的应用类型（例如商业集成和医学信息科学）和新的平台技术（例如 Web 服务、移动设备和智能产品）而使软件在社会基础结构中的作用日益加大。</p>
<p>如果软件开发能力没有相应的增长，那么十年后势必出现总体软件开发能力大大低于总体需求的局面。当然，如果市场力量能够自由运作，这种情况不会真正出现，因为受到启发的软件提供商将出于个人利益而提供足够多的软件来满足这种需求。</p>
<div><a href="#mainSection"><img border=0 alt="" src="http://i.msdn.microsoft.com/dynimg/IC170569.gif"></a><a href="#mainSection"><font color=#1364c4>返回页首</font></a><br></div>
<h3 id=EOAA>再次面对新的挑战</h3>
<p>那么，怎样才能提供足够多的软件开发能力呢？不用太多的分析就可以看出，必须对软件开发的方法和实践进行显著的改变。</p>
<p>因为行业的生产能力取决于合格开发人员的数量以及开发人员的工作效率，因此提高行业生产能力的方法是，或者继续采用现有的方法和实践而投入更多的开发人员，或者保持相当数量的开发人员而采用不同的方法和实践。</p>
<p>尽管过去十年间培育起来的学徒制似乎已经成功地增加了合格开发人员的数量并提高了开发人员的平均水平，但至少有两个理由可以说明学徒制不大可能使软件行业的生产能力满足预期的需求水平： </p>
<ul>
    <li>
    <p>经验告诉我们，没有什么比拥有一些杰出的程序员更重要。杰出开发人员比蹩脚开发人员的工作效率高一千倍，但蹩脚开发人员的数量也几乎是杰出开发人员的一千倍 [Boe81]。 </p>
    </li>
    <li>
    <p>Brooks [Bro95] 指出，增加项目人数最终会导致边际收入减少。通过招募和培训新开发人员而获得的生产能力将逐渐下降。 </p>
    </li>
</ul>
<p>因此解决问题的出路应是改变我们的方法和实践。我们必须通过各种途径提高开发人员的工作效率。</p>
<div><a href="#mainSection"><img border=0 alt="" src="http://i.msdn.microsoft.com/dynimg/IC170569.gif"></a><a href="#mainSection"><font color=#1364c4>返回页首</font></a><br></div>
<h3 id=ENAA>创新曲线与模式转变</h3>
<p>作为一个行业，我们从一开始就需要共同面对这种情况。软件开发的历史是一个与复杂和变化作斗争的过程，时而盈利时而亏损，随着时代的进步而产生更多的需求。虽然仅仅半个世纪就取得了不少辉煌的成绩，然而道路并不平坦。相反，软件开发一直沿着著名的创新曲线模式在前进，如图 1 所示 [Chr97]。</p>
<p><img alt="" src="http://i.msdn.microsoft.com/dynimg/IC158595.gif"></p>
<div><strong>图</strong><strong> 1</strong><strong>：</strong>创新曲线</div>
<p>典型的情况是，一个不连续的创新为一个新的技术时代奠定基础。新基础之上的发展一开始是快速的，但随着基础的稳固和成熟，发展速度逐渐慢下来。最后，这个基础失去了继续创新的能力，达到发展的顶峰。同时，另一个不连续的创新为另一个新技术时代的到来奠定基础，于是上述模式得以重复。Kuhn 称上述基础为模式，称它们之间的转变为模式转变 [Kuh70]。模式转变发生在需要改变现状以继续前进的交汇时刻。我们现在正处在这样一个交汇时刻。</p>
<div><a href="#mainSection"><img border=0 alt="" src="http://i.msdn.microsoft.com/dynimg/IC170569.gif"></a><a href="#mainSection"><font color=#1364c4>返回页首</font></a><br></div>
<h3 id=EMAA>提高抽象水平</h3>
<p>在历史上，模式的转变曾经成功地提高了开发人员的抽象水平，为在平台和语言中获得知识并重复利用知识提供了强大的概念。例如，在平台方面，我们从批处理开始，经历了终端/主机、客户机/服务器、个人计算、多层系统和企业应用集成，再到异步、松散耦合的服务。在语言方面，我们从数字编码语言开始，经历了汇编语言、结构化语言和面向对象的语言，再到字节编码的语言和模式，这可以看作是基于语言的抽象。Smith 和 Stotts 对此进步作了意味深长的总结 [SS02]：</p>
<p><em>编程的历史是在体系结构抽象方面的一种锻炼。在每个时代，语言设计人员通过总结上一代的经验教训创造出结构，然后体系结构设计师使用这些结构创造出更复杂，更强大的抽象。</em></p>
<p>他们还指出，新的抽象一般先出现在平台上，然后移植到语言中。我们现在的情况是，基于语言的抽象已远远落后基于平台的抽象。换句话说，现在是工具远远落后于平台。我们现在正在使用最新的平台技术（例如，通过采用配乐法编写服务，我们现在能够使位于这个星球上任何位置的多个企业间的进程自动化），但我们仍然在手动编写每个应用程序，好象这是首选的方法一样。我们从小的具体概念（例如循环、字符串和整数）入手来创造大的抽象概念（例如保险索赔和证券交易）。我们勤勤恳恳一丝不苟地工作，将上百万小的相关源代码片段和资源组合在一起，形成巨大而复杂的结构。如果半导体行业也采用类似的做法，他们需要用手焊接晶体管来建立起支持这些应用程序的巨大而复杂的处理器。相反，他们通过组装称为特定用途集成电路 (ASIC) 的预定义组件，使用如图 2 所示的工具来完成实现。</p>
<p><img alt="" src="http://i.msdn.microsoft.com/dynimg/IC113902.gif"></p>
<div>图 2：基于 ASIC 的设计工具7</div>
<p>难道我们不能采用类似的方式来实现软件开发的自动化吗？当然能，而且实际上我们已经在这样做。例如，数据库管理系统通过 SQL 实现数据访问自动化，提供了诸如数据集成和独立性等优点，使数据驱动的应用程序更易于创建和维护。与此类似，Widget 框架和 WYSIWYG 编辑器使得创建和维护图形用户界面更容易，提供了诸如设备独立性和可视化组装等优点。仔细分析这些做法，我们可以发现一个反复出现的模式。 </p>
<ul>
    <li>
    <p>在给定问题领域开发出大量系统之后，我们为该领域确定一组可以重复利用的抽象，然后我们制订一组模式，规定如何使用这些抽象。 </p>
    </li>
    <li>
    <p>然后我们开发一个运行时（例如框架或服务器），将这些抽象和模式代码化。这样，我们可以通过对运行时所定义的组件实例化、调整、配置和组装，从而在该领域中创建系统。 </p>
    </li>
    <li>
    <p>然后我们定义一种语言并创建支持该语言的工具（例如编辑器、编译器和调试器），使组装过程自动化。这样可以帮助我们对不断变化的要求做出快速响应，因为部分实现已经完成，而且可以轻松地加以修改。 </p>
    </li>
</ul>
<p>这就是 Roberts 和 Johnson [RJ96] 所描述的著名的&#8220;语言框架&#8221;模式。一个框架可以按数量级降低开发一个应用程序的成本，但只使用一个框架则很困难。一个框架定义一种具有某种典型体系结构的产品（例如应用程序或子系统），这些产品可以通过各种方式进行完善和专门化的处理，以满足不同的要求。将每种产品的要求映射到框架中绝不是一个小问题，通常需要借助于体系结构设计师或高级开发人员的专业技能。通过使用语言表达式捕获各种要求，然后生成框架完成代码，基于语言的工具可以自动完成此过程。</p>
<div><a href="#mainSection"><img border=0 alt="" src="http://i.msdn.microsoft.com/dynimg/IC170569.gif"></a><a href="#mainSection"><font color=#1364c4>返回页首</font></a><br></div>
<h3 id=ELAA>实现软件开发的产业化</h3>
<p>在其他行业，提高生产能力的途经是从手工作业过渡到机械生产。在手工作业阶段，所有产品都是由个人或小组从无到有制造出来的，而在机械生产阶段，各种产品通过组装多家供应商生产的可重复利用的组件迅速生产出来，在这个过程中，许多机械琐碎的任务都是由机器自动完成的。这些行业对工艺、设计和包装进行标准化，借助产品线实现系统性重复利用，并通过供应链分担成本和风险。现在已有部分行业可以实现大规模定制，根据需求快速而经济地制造出各种产品，以满足不同客户的特定要求。</p>
<div><a href="#mainSection"><img border=0 alt="" src="http://i.msdn.microsoft.com/dynimg/IC170569.gif"></a><a href="#mainSection"><font color=#1364c4>返回页首</font></a><br></div>
<h3 id=EKAA>软件能够实现产业化吗？</h3>
<p>人们对软件与实物之间的类比进行过热烈的讨论。这些产业化模式能够应用于软件行业吗？难道软件行业没有因其产品性质的不同而比其他行业特殊吗？Peter Wegner 对它们之间的异同总结如下 [Weg78]：</p>
<p><em>软件产品在某些方面与传统工程学科中的有形产品（如桥梁、建筑物和计算机）存在相似之处。但也存在某些重要的区别，使得软件开发与众不同。由于软件是逻辑概念而非实物，因此其成本集中在开发过程中而不是生产过程中。又因为软件不会磨损，因此其可靠性取决于逻辑质量（如正确性和稳健性）而非物理质量（如硬度和韧性）。</em></p>
<p>有些讨论将实物的生产与软件的开发比作&#8220;苹果与桔子&#8221;。理清这些困扰的关键是理解生产和开发之间的不同，以及规模经济与范围经济的不同。</p>
<p>为了获得投资回报，必须尽最大可能重复利用那些可重复利用的组件而不仅仅是收回开发成本，无论是直接通过降低成本，还是间接通过降低风险、缩短进入市场的时间或改进质量来实现。从投资角度讲，可重复利用的组件属于金融资产。由于为使组件可重复利用而耗费的成本通常非常高，很难达到可获利的重复利用程度，因此需要有一种系统的方法来实现重复利用。这通常包括确定一个要开发多个系统的领域，找出该领域中重现出现的问题，开发出一套解决该问题的集成生产资产，然后将这些资产应用到在该领域中开发系统的过程中。</p>
<div><a href="#mainSection"><img border=0 alt="" src="http://i.msdn.microsoft.com/dynimg/IC170569.gif"></a><a href="#mainSection"><font color=#1364c4>返回页首</font></a><br></div>
<h3 id=EJAA>规模经济与范围经济</h3>
<p>系统性重复利用可以同时产生规模经济和范围经济的效应。这两种效应在其他行业广为人知。尽管二者都是通过集中而非单独生产多个产品来减少时间和降低成本并提高产品质量，但二者在产生这些优点的方式上却存在着不同。</p>
<p>当集中而非单独生产一个设计的多个相同实例时，就产生了规模经济，如图 3 所示。规模经济可能出现在生产机器螺钉等产品时，在这种生产过程中，可以使用机床等生产资产生产出多个相同的产品实例。工程师通过一种资源密集的过程（称为开发）完成设计与最初的实例（称为原型）。然后通过另一个由机器和/或低成本劳动力完成的过程（称为生产）创造出更多实例（称为复制品），以满足市场需要。</p>
<p><img alt="" src="http://i.msdn.microsoft.com/dynimg/IC44325.gif"></p>
<div>图 3：规模经济</div>
<p>范围经济通过集中而非单独生产多个相似但不同的设计和原型而实现，如图 4 所示。例如在汽车制造业，多个相似但不同的汽车设计通常是通过组合子部件（如底盘、车体、内部装饰及传动装置）的现有设计来开发的，而不同的款式或型号通常是通过改变现有设计中的某些功能（如发动机和装饰水平）来产生的。换言之，可以使用相同的方法、工艺、工具和材料设计出多个相似但不相同的产品，并制作出相似但不相同的原型。商业建筑同样如此，很少看到多座桥梁或多幢摩天大楼采用同一种设计。但商业建筑领域存在一个有趣的现象，即每个成功的设计通常只会产生一两个实例，因而规模经济几乎从未真正实现过。在汽车制造业，通常会从成功的设计产生出许多不同的实例，通过复制每个原型，范围经济与规模经济形成互补，如图 4 所示。</p>
<p><img alt="" src="http://i.msdn.microsoft.com/dynimg/IC15362.gif"></p>
<div>图 4：范围经济</div>
<p>当然，软件无论与汽车制造还是与商业建筑之间都存在重要区别，但它们常常有着相似的地方。 </p>
<ul>
    <li>
    <p>在诸如用户桌面产品之类的市场中，操作系统和工作效率应用程序等产品通过复制形成批量生产，软件行业呈现出规模经济的特点，如同在汽车制造业中一样。 </p>
    </li>
    <li>
    <p>而在诸如企业用户产品之类的市场中，为获得竞争优势而开发的商业应用程序很少能够进行批量生产，软件仅呈现出范围经济的特点，如同在商业建筑领域中一样。 </p>
    </li>
</ul>
<p>现在我们可以清楚地看到苹果与桔子之间的区别了。将实物行业的生产与软件开发进行比较未免有些天真。不管是软件还是实物，在任何类型的开发中寻求规模经济效果都是没有意义的。但是，我们却可以期待软件开发的产业化能够带来范围经济的效果。</p>
<div><a href="#mainSection"><img border=0 alt="" src="http://i.msdn.microsoft.com/dynimg/IC170569.gif"></a><a href="#mainSection"><font color=#1364c4>返回页首</font></a><br></div>
<h3 id=EIAA>产业化会带来什么样的结果？</h3>
<p>假设可以在软件行业实现产业化，那么结果将会是什么样子呢？当然，在事情发生之前我们不可能确切地知道。但是，我们可以根据软件行业的发展道路以及其他行业产业化后的情形作出合理的推测。显然，软件开发永远不会简单到懒人们所希望的那种纯机械化的程度。相反，满足全球需求的关键是不要再把杰出开发人员的时间浪费在机械琐碎的任务上。我们必须尽一切努力更好地利用这些稀有资源，不要再让他们把时间花费在手动构造因为下一个主要平台版本的出现或者市场条件的变化而致使行业需求改变进而导致短短几个月或几年内就需要维护甚至替换掉的最终产品上。</p>
<p>实现此目的的方法之一就是为开发人员提供各种途经，使他们能够将自己的知识转化成可供他人重复利用的资产。这个目标是否遥遥无期？有些模式已经表现出重复利用知识的有效性，尽管利用程度不高。下一步是使用语言、框架和工具自动生成模式化的应用程序，从而实现从编程到自动化的飞越。</p>
<p>半导体开发为软件开发实现产业化后的情形提供了预演。这并不是说软件组件很快就能象 ASIC 那样易于组装，ASIC 是经过封装和接口技术领域二十年的创新和标准化而开发出来的产品。但另一方面，软件开发可能用不了 20 年。软件开发的优势在于只需要处理比特，而半导体行业还需要承担组件实现所需的物理材料工程的额外负担。与此同时，比特所固有的短寿特性也为诸如数字知识产权保护等带来了难题，正如我们在电影和音乐行业所看到的那样。</p>
<div><a href="#mainSection"><img border=0 alt="" src="http://i.msdn.microsoft.com/dynimg/IC170569.gif"></a><a href="#mainSection"><font color=#1364c4>返回页首</font></a><br></div>
<h3 id=EHAA>结论</h3>
<p>本文描述了软件行业在利用现有方法和实践来面对预期需求上的无能为力。这里只对许多问题进行了简要叙述，无疑会引发读者寻求证据或更多详细的讨论。要获得更详细的讨论，请参阅此书 Software Factories: Assembling Applications with Patterns, Models, Frameworks and Tools，此书的作者为 Jack Greenfield 和 Keith Short，由 John Wiley and Sons 出版社出版。有关详细信息，也可以访问 <a href="http://msdn.microsoft.com/architecture/overview/softwarefactories"><font color=#1364c4>http://msdn.microsoft.com/architecture/overview/softwarefactories</font></a> 和 <a href="http://www.softwarefactories.com/"><font color=#1364c4>http://www.softwarefactories.com/</font></a>，这里提供了各种文章，介绍了阻止从手工作业向机械生产转换的长期问题、帮助行业克服这些问题的重大创新以及集成了重大创新的软件工厂方法。</p>
<p><strong>版权声明</strong></p>
<p>&#169; 版权所有 2004 Jack Greenfield。&#169; 部分版权所有 2003 Jack Greenfield 和 Keith Short，已从 Wiley Publishing Inc. 获准再版。保留所有权利。</p>
<p><strong>参考资料</strong></p>
<ol>
    <li>
    <p>[Boe81] B Boehm.Software Engineering Economics.Prentice Hall PTR, 1981</p>
    </li>
    <li>
    <p>[Bro95] F Brooks.The Mythical Man-Month.Addison-Wesley, 1995</p>
    </li>
    <li>
    <p>[Chr97] C Christensen.The Innovator's Dilemma, Harvard Business School Press, 1997</p>
    </li>
    <li>
    <p>[Kuh70] T Kuhn.The Structure Of Scientific Revolutions.The University Of Chicago Press, 1970</p>
    </li>
    <li>
    <p>[RJ96] D Roberts and R. Johnson. Evolving Frameworks:A Pattern Language for Developing Object-Oriented Frameworks.Proceedings of Pattern Languages of Programs, Allerton Park, Illinois, September 1996</p>
    </li>
    <li>
    <p>[SS02] J. Smith and D Stotts.Elemental Design Patterns &#8211; A Link Between Architecture and Object Semantics.Proceedings of OOPSLA 2002</p>
    </li>
    <li>
    <p>本图利用 Virtuoso&#174; Chip Editor 和 Virtuoso&#174; XL Layout Editor 生成，并得到了 Cadence Design Systems, Inc. 的许可。&#169; 版权所有 2003 Cadence Design Systems, Inc.。保留所有权利。Cadence 和 Virtuoso 是 Cadence Design Systems, Inc. 的注册商标。</p>
    </li>
    <li>
    <p>[Sta94] The Standish Group.The Chaos Report.http://www.standishgroup.com/sample_research/PDFpages/chaos1994.pdf</p>
    </li>
    <li>
    <p>[Weg78] P Wegner.Research Directions In Software Technology.Proceedings Of The 3rd International Conference On Software Engineering. 1978</p>
    </li>
</ol>
<p><strong>作者简介</strong><strong></strong></p>
<p>Jack Greenfield 是 Microsoft 公司负责开发企业框架和工具的体系结构设计师。他曾担任 Rational Software Corporation 公司 Practitioner Desktop Group 小组的主要体系结构设计师，他还是 InLine Software Corporation 公司的创始人和首席技术官。他曾在 NeXT 开发了企业对象框架，现在称为 Apple Web Object。他是著名的演讲者和作家，同时他还对 UML、J2EE 及相关的 OMG 和 JSP 规范做出过很大贡献。他拥有 George Mason University 物理学学士学位。可通过 <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#106;&#97;&#99;&#107;&#103;&#114;&#64;&#109;&#105;&#99;&#114;&#111;&#115;&#111;&#102;&#116;&#46;&#99;&#111;&#109;"><font color=#1364c4>jackgr@microsoft.com</font></a> 与 Jack 获得联系。 </p>
<p>&#160;</p>
<div><a href="#mainSection"><img border=0 alt=返回页首 src="http://i.msdn.microsoft.com/dynimg/IC170569.gif"></a><a href="#mainSection"><font color=#1364c4>返回页首</font></a></div>
<br><br>转自：<a href="http://msdn.microsoft.com/zh-cn/library/aa480032.aspx">http://msdn.microsoft.com/zh-cn/library/aa480032.aspx</a></div>
<img src ="http://www.cppblog.com/flyinghare/aggbug/125195.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghare/" target="_blank">会飞的兔子</a> 2010-08-29 20:50 <a href="http://www.cppblog.com/flyinghare/archive/2010/08/29/125195.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>解决无法更改本地文件夹与 TFS 项目之间映射的问题</title><link>http://www.cppblog.com/flyinghare/archive/2010/06/22/118443.html</link><dc:creator>会飞的兔子</dc:creator><author>会飞的兔子</author><pubDate>Tue, 22 Jun 2010 02:40:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghare/archive/2010/06/22/118443.html</guid><wfw:comment>http://www.cppblog.com/flyinghare/comments/118443.html</wfw:comment><comments>http://www.cppblog.com/flyinghare/archive/2010/06/22/118443.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghare/comments/commentRss/118443.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghare/services/trackbacks/118443.html</trackback:ping><description><![CDATA[<span style="FONT-SIZE: 13px; LINE-HEIGHT: 22px; FONT-FAMILY: Arial; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px">问题说明：更换了一台新的 TFS 服务器，旧的 TFS 服务器停止使用。但从客户端 VS2008 连接到新的服务器，并下载源码到本地原来工作的文件夹时，出现错误提示，说本地文件夹已被映射到了旧的服务器上，不能从新服务器获取源码。通过源代码管理－工作区管理，把跟旧服务器相关的所有工作区项都删掉后，仍出现此提示。
<p style="FONT-SIZE: 13px; BACKGROUND-IMAGE: url(http://hi.baidu.com/xiaoheilong/css/lb/gray_line.gif); MARGIN: 10px 0px 0px; LINE-HEIGHT: 22px; TEXT-ALIGN: justify; background-origin: initial; background-clip: initial">&nbsp;&nbsp;&nbsp; 解决办法：<br>在文件 C:\Documents and Settings\当前用户\Local Settings\Application Data\Microsoft\Team Foundation\2.0\Cache\VersionControl.config 中，<br>（vista 在 C:\Users\当前用户\AppData\Local\Microsoft\Team Foundation\2.0\Cache）<br>缓存了本地文件夹到旧服务器的一些映射关系，只要把跟旧服务器相关的 ServerInfo 节点删掉，问题即可解决。</p>
<p style="FONT-SIZE: 13px; BACKGROUND-IMAGE: url(http://hi.baidu.com/xiaoheilong/css/lb/gray_line.gif); MARGIN: 10px 0px 0px; LINE-HEIGHT: 22px; TEXT-ALIGN: justify; background-origin: initial; background-clip: initial">转自：<span style="FONT-SIZE: medium; LINE-HEIGHT: normal; FONT-FAMILY: 微软雅黑; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px"><a href="http://hi.baidu.com/xiaoheilong/blog/item/1cf703467acce8006a63e57d.html">http://hi.baidu.com/xiaoheilong/blog/item/1cf703467acce8006a63e57d.html</a></span></p>
</span>
<img src ="http://www.cppblog.com/flyinghare/aggbug/118443.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghare/" target="_blank">会飞的兔子</a> 2010-06-22 10:40 <a href="http://www.cppblog.com/flyinghare/archive/2010/06/22/118443.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>微软不怕面试题公开</title><link>http://www.cppblog.com/flyinghare/archive/2010/04/22/113259.html</link><dc:creator>会飞的兔子</dc:creator><author>会飞的兔子</author><pubDate>Thu, 22 Apr 2010 09:12:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghare/archive/2010/04/22/113259.html</guid><wfw:comment>http://www.cppblog.com/flyinghare/comments/113259.html</wfw:comment><comments>http://www.cppblog.com/flyinghare/archive/2010/04/22/113259.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghare/comments/commentRss/113259.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghare/services/trackbacks/113259.html</trackback:ping><description><![CDATA[转自：<a href="http://www.4oa.com/office/748/940/941/200712/156538.html">http://www.4oa.com/office/748/940/941/200712/156538.html</a><div><span  style="color: rgb(101, 109, 119); font-family: 宋体; font-size: 12px; line-height: 21px; ">微软不怕面试题公开&#8220;挑战&#8221;就是秘密武器&nbsp;<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">微软一直把公司的面试问题视为秘密，但天下没有绝对的秘密。&#8220;什么能给你快乐？&#8221;、&#8220;你认为做事情是完美还是速度重要？&#8221;、&#8220;如果微软想要按照你的选择投资500万美元，你会选择什么业务？&#8221;这类普通问题，这里就不赘言了，现在只选择脑筋急转弯、&#8220;圈套&#8221;题、创造力测试等等，让我们来一窥微软的面试秘密。<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">微软智力题从哪儿来&nbsp;<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">逻辑题目是微软16号楼自助餐厅里流行午餐休闲谈话的一部分。微软的竞争精神认为能够提出&#8220;新&#8221;而&#8220;有效&#8221;问题是一件很&#8220;酷&#8221;的事情。<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">许多微软的难题带有传奇色彩。据说有一次史蒂夫&#183;鲍尔默和另一位微软高官正在慢跑时看到了一个下水道盖子，便随口问道：&#8220;为什么下水道盖子是圆形的？&#8221;另一个人灵机一动道：&#8220;哟，这可是一个面试的好问题。&#8221;这个故事可能是真有其事，然而，几乎可以肯定鲍尔默并不是第一个提出下水道盖子这个问题的人。实际上微软公司的面试智力题都在一些智力题汇编书或者一些以智力题为主要内容的网站上出现过，微软只不过是给它们&#8220;化了妆&#8221;而已。<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">问题<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">在不使用天平的情况下，你怎样称出一架喷气式飞机的重量？<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">为什么镜子里的影像左右颠倒而不是上下颠倒？<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">为什么你在宾馆里一打开热水龙头就有热水流出来？<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">M＆M巧克力是怎样做出来的？<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">你在船上，把一只箱子抛起来，水平面会升高还是下降？<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">世界上有多少钢琴调音师？<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">美国有多少加油站？<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">每小时有多少密西西比河水流过新奥尔良？<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">一个曲棍球场里的冰有多重？<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">如果你能够搬走美国50个州中的任何一个，你会搬走哪一个？<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">地球上有多少个这样的点：往南走1公里，往东走1公里，再往北走1公里，你能回到原来的出发点吗？<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">一天中钟表的指针重叠多少次？<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">迈克和托德两人一共有21美元。迈克的钱比托德多20美元，每个人各有多少钱？在你的答案中不能有分数。<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">一般说来，曼哈顿的电话册要翻多少次才能找到你想要找的人名？<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">你会怎样设计比尔&#183;盖茨的浴室？<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">你怎样设计一个由计算机控制的微波炉？　　　　<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">&#8220;挑战&#8221;就是秘密武器<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">微软以及其他许多公司在面试中都有一个&#8220;秘密测试武器&#8221;，这个秘密武器通常被称为&#8220;挑战&#8221;。我的一个朋友没有通过微软的面试，面试后我与他共进了晚餐。他抱怨说：&#8220;我恨死那个主考官了，他简直是个蠢货。他连皮亚诺公理这样的基础知识都不懂！&#8221;我的这位朋友对此感到愤怒，因为他觉得之所以面试搞砸是因为这个主考官对所谈话的话题的无知造成的。<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">结果实情是什么呢？他所申请的职位是项目经理，这是一个负责设计软件而不是编程工作的职位，因此这个职位需要做很多说服性的工作。项目经理要和一群有着很强逻辑思维能力、但缺乏社交技巧的程序员打交道，这需要一种特别的才能。要想做一名项目经理，你需要具备的独特能力是：说服人们接受那些你认为正确的事实。而这基本上就是你的日常工作。你必须是耐心和友好的，这就是项目经理职位对一个人的素质的基本要求。<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">&#8220;挑战&#8221;的最早版本出现在口头进行的斯坦福-比奈智商测试。测试的人可能给出下列题目：<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">我们都知道，水能够把水中的鱼托起来，那么请回答这个问题：如果我们有一个桶只有半桶水，把桶放到天平上，水和桶刚好重45公斤。然后把一条5公斤的鱼放进桶里，现在总重为多少？<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">大多数成年人都会说45加5是50公斤。主持测试的人这时候可能会问道：&#8220;这怎么会是正确的呢？你知道水是会把鱼托起来的。&#8221;特曼曾写道：&#8220;如果被测试的人不断地改变答案，然后说我觉得答案应该是50公斤但并不确定，那么得分为零。&#8221;只有在被测试者利用逻辑为自己的正确答案进行辩护，并连续挫败两次&#8220;挑战&#8221;，答案才会被认为是正确的。<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">这些问题似乎并不针对智力一类的事情做出测试，但是毫无疑问，应用这种&#8220;诡辩&#8221;测试的公司很重视这种测试的结果。根据斯波斯基的说法，在微软情形如下：在整个面试过程中，你引导应聘者说出一些完全肯定、毫无争议的正确答案。然后你说&#8220;等一下，等一下&#8221;，再故意和他唱两分钟的反调，直到他们能够充分证明自己答案的正确。<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">&#8220;懦弱的应聘者会选择放弃，这样的人绝对不会被录取。好的应聘者会设法通过某种方法来说服你。他们会搬用一整套戴尔&#183;卡耐基(DaleCarnegie)的做法来说服你，他们可能会说出&#8216;可能是我误解你了&#8217;这样的话，但他们总是坚持自己的立场。这样的人，录用。<br style="word-wrap: break-word; word-break: break-all; ">无答案的公开试题<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">微软对面试问题的公开虽不乐意，但也很无奈。早在互联网出现之初，这些试题就已经有所公开了。<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">20世纪90年代早期，克里斯&#183;塞尔斯(ChrisSells)在DevelopMentor公司面试。在面试快结束的时候，一位公司的创始人说道：&#8220;好的，你被录用了。但是再问你一个微软公司在面试时常常问到的问题——为什么下水道盖子是圆形的？<br style="word-wrap: break-word; word-break: break-all; ">塞尔斯回答说：&#8220;没问题，如果你先回答了这个问题，我再来回答你的问题——为什么消防员的背带是红色的？<br style="word-wrap: break-word; word-break: break-all; ">这位公司创始人对此哑口无言。<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">这次经历促使塞尔斯开始收集微软的面试问题。1996年他创建了一个网站，并开始把自己听说的试题张贴在网上。<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">南加利福尼亚大学学生柯朗&#183;邦德拉帕提(KiranBondalapati)和他的几个朋友一起参加了微软的一次面试。邦德拉帕提把问题整理出来，形成了自己的&#8220;微软面试题库&#8221;。还有另外一些其他网站提供类似的服务，例如，4guysfromRolla.com网站的&#8220;微软面试问题&#8221;和迈克尔&#183;普赖尔(MichaelPryor)的&#8220;技术面试问题&#8221;(网站里包含各种各样的试题，不只是微软的面试试题)。<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">你可能认为微软对自己公司的面试问题被公开十分恼怒，事实并不完全是这样。邦德拉帕提和塞尔斯都听说过微软人力资源部门的人指点员工在初次担任主考官时到他们的网站上参考参考。<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">当然，应聘者也可以利用这些网站为面试预先准备，但塞尔斯和邦德拉帕提的网站都不提供或者很少提供问题的答案。邦德拉帕提有一次就接到了一个朋友的朋友打来的紧急电话，当时是参加微软面试的前夜，她正在万豪酒店。她面前摆着一大堆从邦德拉帕提网站上打印出来的东西，但是没有一个问题有确定的答案，她想要邦德拉帕提告诉她。<br style="word-wrap: break-word; word-break: break-all; "><br style="word-wrap: break-word; word-break: break-all; ">塞尔斯收到许多公司的电子邮件，他们也想要&#8220;像微软一样招聘&#8221;。那么问题在哪儿呢？他们也需要知道问题答案，而塞尔斯的网站把答案都略去了。塞尔斯说：&#8220;我总是回答，如果你们不知道答案，就不应该在面试时问这些问题。这往往使他们恼羞成怒。</span></div><img src ="http://www.cppblog.com/flyinghare/aggbug/113259.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghare/" target="_blank">会飞的兔子</a> 2010-04-22 17:12 <a href="http://www.cppblog.com/flyinghare/archive/2010/04/22/113259.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在敏捷开发中采用演进式架构设计</title><link>http://www.cppblog.com/flyinghare/archive/2010/04/07/111836.html</link><dc:creator>会飞的兔子</dc:creator><author>会飞的兔子</author><pubDate>Wed, 07 Apr 2010 02:42:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghare/archive/2010/04/07/111836.html</guid><wfw:comment>http://www.cppblog.com/flyinghare/comments/111836.html</wfw:comment><comments>http://www.cppblog.com/flyinghare/archive/2010/04/07/111836.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghare/comments/commentRss/111836.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghare/services/trackbacks/111836.html</trackback:ping><description><![CDATA[转自：<a href="http://www.phpchina.com/?action_zendinfoview_itemid_34567.html">http://www.phpchina.com/?action_zendinfoview_itemid_34567.html</a><div><span  style="color: rgb(23, 115, 180); font-family: arial, Tahoma, 'Lucida Grande', 'Lucida Sans Unicode', 宋体, 新宋体, verdana, sans-serif; font-size: 12px; line-height: 21px; "><div class="rct" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; font-weight: bold; font-size: 16px; background-image: url(http://www.phpchina.com/images/zend/ptbg.jpg); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; width: 505px; color: rgb(26, 128, 200); line-height: 28px; height: 27px; background-position: initial initial; background-repeat: no-repeat no-repeat; "><span class="rctl" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; word-wrap: break-word; ">在敏捷开发中采用演进式架构设计</span></div><div class="rcc" style="margin-top: 10px; margin-right: auto; margin-bottom: 10px; margin-left: 10px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; line-height: 19px; "><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">　　在敏捷开发过程中，我们还需要对系统架构进行设计吗?事实上，Martin Fowler在《Is Design Dead?》一文中已经给出了答案，那就是我们同样不能忽略对系统架构的设计。与计划性的设计(Planned Design)不同，我们需要演进式的设计(Evolutionary Design)。在敏捷开发的生命周期中，我们通过每一次迭代来丰富与更新我们的设计方案，以使其最大限度地符合客户对系统的需求。这里所指的需求，包括功能性需求和非功能性需求。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">　　在Agile Journal四月刊中，IBM's Methods Group的敏捷专家Scott W. Ambler详细地阐述了在敏捷语境中的架构设计方法，他提出了所谓&#8220;架构预测(Architectural Envisioning)&#8221;的方法，以应对敏捷开发中逐步演进的架构设计过程。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">　　Scott指出，敏捷模型驱动开发(Agile Model Driven Development，AMDD)明确地包括了初始需求分析与架构建模，这个过程发生在敏捷项目开发的第0次迭代中。所谓第0次迭代，就相当于项目的热身活动，是项目得以启动的基础。在此迭代期间，团队需要充分地理解项目的范围，甄别可行地技术策略。这个阶段所能够收集到的信息将有助于你对整个项目最初的粗略估计，以制定合适的项目计划，从而获得启动项目的资金与足够的支持。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">　　敏捷模型驱动开发的生命周期如下图所示：</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">　　<img height="331" alt="" src="http://dev.yesky.com/imagelist/2009/078/7uiuhsuj4h68.jpg" width="500" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; border-right-width: 0px; border-right-style: initial; border-right-color: initial; border-top-width: 0px; border-top-style: initial; border-top-color: initial; border-left-width: 0px; border-left-style: initial; border-left-color: initial; border-bottom-width: 0px; border-bottom-style: initial; border-bottom-color: initial; "></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">　　根据图中所示，在每次迭代的初期，制定的迭代计划都应该包括建模的工作。在此期间，可以召开建模的头脑风暴会议，讨论系统的功能特征，并思考实现这些特征的高层设计策略。大多数敏捷团队都会通过测试驱动开发(TDD)确定需求与设计的细节。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">　　通过对架构的预测，可以在项目早期进行一些高层次的架构建模，以助于团队与关键利益相关人商讨系统采取的技术策略。这一行为的关键目标是识别出架构策略，而不是撰写如山一般堆积的文档，从而使得你能够快速完成架构建模。其中的窍门就是尽量保持简单。开发者不需要对大量的细节进行建模，而只需要足够即可。如果你正在编写用例，意味着你只需要以标注形式列出用例的要点就足够好了。如果你正在对领域建模，可以直接在白板上绘图，或者使用CRC卡片。你的目的在于对信息的共享与交流，而不是编写细致的文档。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">　　如果采用架构预测的方式，你需要对哪些内容进行建模呢?Scott在文中指出有如下四部分内容需要建模：</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">　　技术图表。例如UML部署图。这些图表有助于开发者预测主要的<a class="fllink" href="http://product.yesky.com/software/" target="_bank" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; color: rgb(7, 81, 154); text-decoration: none; font-style: normal !important; "><font color="#000000" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">软件</font></a>和硬件组件，包括你需要访问的旧系统和<a class="fllink" href="http://product.yesky.com/database/" target="_bank" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; color: rgb(7, 81, 154); text-decoration: none; font-style: normal !important; "><font color="#000000" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">数据库</font></a>，系统有可能会与它们进行交互。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">　　用户交互流程图。通过分析用户交互的主要页面/外观和报告，对系统的UI进行架构设计。如果在进行架构设计的时候不考虑用户交互界面，就可能存在潜在危机，那就是你构建的系统不是利益相关人所希望看到的。请记住，UI才是最终用户使用的系统。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">　　领域图。在最初的架构建模中，一个重要的组成部分是对领域的高层建模。模型可以非常微小，只需要捕获主要的业务实体，以及它们之间的关系。有的人可能认为领域模型应该属于需求建模的一部分，而不是架构建模。但正如上图所示，这两者在第0次迭代中是并发进行的。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">　　变更情形。就是在架构级需求中描述可能的技术或业务变更，而这些变更需要在未来能够提供支持。变更情形要求你考虑架构的扩展能力，但并不是过度构建你的系统。因为你只是要考虑由于变更所造成的影响，以确保你构建的系统还能够正常工作。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">　　架构建模是贯穿于整个项目周期的，因此这些图表就是在项目结束时形成的整体文档的基础。由于你事先明确架构是演进的，因此就不必承担架构设计在项目早期必须&#8220;正确无误&#8221;的压力，而只需要在当前形势下保证足够好就可以了。Scott建议使用白板和草稿纸等简便工具，勾勒出这些模型的初始版本。当然，如果团队成员具有熟练的建模技巧，也可以使用专门的建模工具。这一建议足以体现架构设计的敏捷性，与长篇累牍的传统架构设计方式迥然不同。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">　　对于这样一种架构设计方式，熟悉传统架构设计方式的架构师普遍不以为然。Scott对这一看法给与了强有力的反驳。他将架构设计场景分为三种类型。第一种是架构师熟悉系统架构设计所必需的技能与经验。既然你已经熟悉了这些内容，当然就没有必要作出完整的设计了。你只需要在白板上体现你的架构设计，保证团队的每个人都能够按照相同的体系架构进行实现就可以了。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">　　第二种场景是架构师对相关技巧与经验完全不知。此时，仍然只需要作少量的初始建模即可。因为你缺乏足够的知识来完成细致而又全面的架构设计，反而会因为了解不够而导致错误，从而增加项目的风险，并且阻碍了项目的进度。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">　　第三种场景则是架构师熟悉部分知识。这种情形也是团队开发中最常见的场景。在这种情况下，可以耗费几天时间作出一个初始的架构建模，以验证系统可能存在的风险，并制定可能策略以减轻风险可能造成的后果。你可以实现一些可工作的代码来验证架构。建模在这种情况下是非常有意义的，因为它使得你可以定义一个一致的技术愿景，为团队成员所分享，并对系统的主要问题进行思考。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">　　当你的团队成员是分散在各地时，或者当团队非常庞大，下面分为多个小组时，这种初始的架构建模就能够带来无与伦比的价值。它有助于在团队成员之间建立一个公共的愿景，更重要的是它能够识别出分离的组件/子系统，以及这些组件的初始接口。一旦识别出这些耦合度较低的组件或子系统，就能够合理地对团队进行分组，并保证小组之间设计与实现的一致性。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">　　Scott指出，所谓的&#8220;架构预测&#8221;能够提供如下价值：</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">　　提高生产力</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">　　降低技术风险</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">　　减少开发时间</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">　　增强沟通</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">　　可伸缩的敏捷软件开发。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; word-wrap: break-word; ">　　需要明确的是，这样的一种架构预测方式，正好符合敏捷开发迭代的需要。在项目开发早期，对系统整体进行一次高层次的概览，并对关键业务需求进行甄别与分析，划分合理的系统模块，有助于在迭代开发中为团队成员建立一个统一的标准与目标。而在每次迭代过程中，团队就可以对本次迭代期间的功能进行深入的架构建模，然后通过TDD充分理解需求，对模块的细节进行设计与实现。这是敏捷架构设计的核心操作原理，它与敏捷开发原则是一脉相承的。</p></div></span></div><img src ="http://www.cppblog.com/flyinghare/aggbug/111836.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghare/" target="_blank">会飞的兔子</a> 2010-04-07 10:42 <a href="http://www.cppblog.com/flyinghare/archive/2010/04/07/111836.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>架构设计的方法学</title><link>http://www.cppblog.com/flyinghare/archive/2010/04/07/111834.html</link><dc:creator>会飞的兔子</dc:creator><author>会飞的兔子</author><pubDate>Wed, 07 Apr 2010 02:37:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghare/archive/2010/04/07/111834.html</guid><wfw:comment>http://www.cppblog.com/flyinghare/comments/111834.html</wfw:comment><comments>http://www.cppblog.com/flyinghare/archive/2010/04/07/111834.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghare/comments/commentRss/111834.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghare/services/trackbacks/111834.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 转自：http://blog.chinaunix.net/u/15169/showart_82408.html&nbsp;&nbsp;约公元前25年，古罗马建筑师维特鲁威说：&#8220;理想的建筑师应该既是文学家又是数字家，他还应通晓历史，热衷于哲学研究，精通音乐，懂得医药知识，具有法学造诣，深谙天文学及天文计算。&#8221;（好难哪，软件构架设计师的要求呢？大家好好想想吧。）&nbsp;&n...&nbsp;&nbsp;<a href='http://www.cppblog.com/flyinghare/archive/2010/04/07/111834.html'>阅读全文</a><img src ="http://www.cppblog.com/flyinghare/aggbug/111834.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghare/" target="_blank">会飞的兔子</a> 2010-04-07 10:37 <a href="http://www.cppblog.com/flyinghare/archive/2010/04/07/111834.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>小议软件架构设计要点</title><link>http://www.cppblog.com/flyinghare/archive/2010/03/22/110292.html</link><dc:creator>会飞的兔子</dc:creator><author>会飞的兔子</author><pubDate>Mon, 22 Mar 2010 06:25:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghare/archive/2010/03/22/110292.html</guid><wfw:comment>http://www.cppblog.com/flyinghare/comments/110292.html</wfw:comment><comments>http://www.cppblog.com/flyinghare/archive/2010/03/22/110292.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghare/comments/commentRss/110292.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghare/services/trackbacks/110292.html</trackback:ping><description><![CDATA[转自：<a href="http://tech.it168.com/a2009/0417/272/000000272586.shtml">http://tech.it168.com/a2009/0417/272/000000272586.shtml</a><br><br>
<p>&nbsp;&nbsp;&nbsp; 如何更好地进行<a title=软件 style="COLOR: #000000" href="http://software.it168.com/" target=_blank><u>软件</u></a>架构设计，这是软件工程领域中一个永恒的重点话题。过去几十年来，国际软件工程界在软件架构设计方面已经获得了长足发展，大量图书、文章和文献记载了这方面的成熟经验与成果。软件架构设计往往是一件非常复杂的工作，涉及到很多细节和方方面面，可探讨的话题也非常之多。囿于篇幅限制，以下只能根据笔者个人理解，遴选出软件架构设计的个别要点，结合当前流行的敏捷软件工程思想，与大家分享一下自己在软件架构设计方面的心得和体会。</p>
<p>&nbsp;&nbsp;&nbsp; <strong>架构决定成败</strong></p>
<p>&nbsp;&nbsp;&nbsp; 软件架构是软件产品、软件系统设计当中的主体结构和主要矛盾。任何软件都有架构，哪怕一段短小的HelloWorld程序。软件架构设计的成败决定了软件产品和系统研发的成败。软件架构自身所具有的属性和特点，决定了软件架构设计的复杂性和难度。</p>
<p>&nbsp;&nbsp;&nbsp; 这几年流行一个说法（管理谚语）：&#8220;细节决定成败&#8221;，这句话其实只说对了一半。细节确实很重要，很多项目、产品就输在细节的执行上。一方面，战术细节固然很重要，但另一方面，战略全局也同样重要，对应的我们可以说：&#8220;战略决定成败&#8221;。战略性失败，就好比下一盘围棋，局部下得再漂亮、再凌厉，如果罔顾大盘，己方连空都不够了，还有官子（细节）获胜的机会吗？必然是中盘告负。</p>
<p>&nbsp;&nbsp;&nbsp; 类似地，正确的软件架构设计，应该既包括战略全局上的设计，也包括战术细节（关键路径）上的设计。有一种错误的观点认为，软件架构设计只要分分层和包，画一个大体的轮廓草图，就完事了。这种&#8220;纸上谈兵&#8221;型的架构师行为是非常有害的。事实上，既然软件架构是软件建筑的主体结构、隐蔽工程、承重墙和要害部位，那么软件架构也必然要落实到实际的算法和代码，不但要有实现代码，还要包括对这部分架构进行测试的代码，以保证获得高质量的、满足各种功能和非功能质量属性要求的架构。除了完成概念、模型设计外，软件架构师一定要参与实际的编码、测试和调试，做一位真正的hands-on practitioner，这已经成为了敏捷软件工程所倡导的主流文化。</p>
<p>&nbsp;&nbsp;&nbsp; <strong>两个架构</strong></p>
<p>&nbsp;&nbsp;&nbsp; 我们在日常的软件产品和系统开发中，实际上会遇到两种、两个部分的软件架构，即待开发的应用部分的软件架构（简称&#8220;应用架构&#8221;），以及既有的基础平台部分的软件架构（简称&#8220;基础架构&#8221;）。这两部分架构之间是互为依赖、相辅相成的关系，它们共同组成了整个软件产品和系统的架构。</p>
<p>&nbsp;&nbsp;&nbsp; 基础架构的例子包括：.NET和J2EE等主流的基础平台和各种公共应用框架，由基础库API、对象模型、事件模型、各种开发和应用的扩展规则等内容组成。我们只有熟悉基础架构的构造细节、应用机理，才能有效地开发出高质量、高性能的上层应用。然而，开发一个面向最终用户的软件应用系统和产品，仅仅掌握一般的计算机高级编程语言知识和基础平台架构、API的使用知识显然是不够的，我们还需要根据客户应用的类型和特点，在基础架构之上，设计出符合用户要求的高质量应用软件。</p>
<p>&nbsp;&nbsp;&nbsp; 熟悉OOA、OOD抽象建模技术、设计原则以及架构模式和设计模式等等方法技术，不但有助于我们更好地理解和利用基础平台架构，也有助于我们设计开发出更高质量的应用软件架构。</p>
<p>&nbsp;&nbsp;&nbsp;<strong> 风险<a title=驱动 style="COLOR: #000000" href="http://driver.it168.com/" target=_blank><u>驱动</u></a>、敏捷迭代的架构设计与开发</strong></p>
<p>&nbsp;&nbsp;&nbsp; 软件架构将随着软件产品和系统的生命周期而演化，其生命期往往超过了一个项目、一次发布，甚至有可能长达数年之久，因而软件架构无论对于客户还是开发商来说都是一项极其重要的资产。</p>
<p>&nbsp;&nbsp;&nbsp; 软件架构的设计应该遵循什么样的开发过程？或者说，有没有更好的、成熟的软件架构设计和开发过程？回答是，21世纪的软件架构设计应该优先采用敏捷迭代的开发方式和方法。与传统做法不同，敏捷迭代开发主张软件架构采用演进式设计（evolutionary design），一个软件产品或系统的架构是通过多次迭代，乃至多次发布，在开发生命周期中逐步建立和完善起来的。</p>
<p>&nbsp;&nbsp;&nbsp; 好的软件架构不是一蹴而就的。在架构设计开发过程中，我们应该尽量避免瀑布式思维，通过一个&#8220;架构设计阶段&#8221;来完成系统的架构设计乃至详细设计，然后再根据架构图纸和模型，在&#8220;编码实现阶段&#8221;按图索骥进行架构的编码与实现。这种传统做法的错误在于认为软件架构就是图纸上的模型，而不是真正可以高质量执行的源代码。几十年的软件工程实践表明，没有经过代码实现、测试、用户确认过的架构设计，往往会存在着不可靠的臆想、猜测和过度设计、过度工程，极易造成浪费和返工，导致较高的失败率。</p>
<p>&nbsp;&nbsp;&nbsp; 风险是任何可能阻碍和导致软件产品/系统研发失败的潜在因素和问题。软件架构是软件产品和系统研发的主要矛盾和主要技术风险，软件架构的质量决定了整个软件系统和产品的质量。不确定性往往是软件架构设计当中一种最大的潜在风险。因此，软件架构的设计与开发应该遵循风险驱动的原则，在整个开发生命周期内至始至终维护一张风险问题清单，随着迭代的前进，根据风险的实时动态变化，首先化解和处理最主要的架构风险，再依次化解和处理次要的架构风险。</p>
<br>
<p>&nbsp;&nbsp;&nbsp; <strong>架构设计的可视化建模</strong></p>
<p>&nbsp;&nbsp;&nbsp; <a title=软件 style="COLOR: #000000" href="http://software.it168.com/" target=_blank><u>软件</u></a>架构设计的难度源于软件设计问题本身的复杂性，一个复杂的软件系统往往存在大量复杂的、难于被人类所理解的细节和不确定因素。抽象与建模是人类自诞生以来就已掌握的理解复杂事物的方法，因而人类所从事的软件设计工作本质上也是一个不断建模的过程。我们可以通过各种抽象的模型和视图，从各个不同层次、宏观和微观的角度来理解复杂的软件架构，以保证作出正确和有效的设计。</p>
<p>&nbsp;&nbsp;&nbsp; 有人认为：&#8220;软件架构就是源代码（source codes）&#8221;以及&#8220;源代码就是设计&#8221;。这种说法其实是片面的。什么是真正的软件？我们知道，最终可以在电脑上执行的真正的软件其实是二进制代码0和1，借助编译器我们把高级编程语言翻译成底层的汇编语言、机器语言等，没有人能直接、完整地看到二进制程序在<a title=CPU style="COLOR: #000000" href="http://product.it168.com/list/b/0217_1.shtml" target=_blank><u>CPU</u></a>上的实际运行状况（runtime），人们大多只能通过各种调试工具、窗口视图等方式来间接地动态观察这些真正的软件的运行片段。因此，Java、C#、C++ 等等设计时（design time）源代码在本质上也是一种模型，虽然是一种经处理后可执行的静态模型，但显然它们并不是真实软件和软件架构的全部。可见，源代码模型（有时也叫实现模型）与UML模型其实都是软件架构的一种模型（逻辑反映），差别就在于抽象层次的不同。完整的软件架构（建筑）不仅仅包括源代码（实现模型），还包括了需求模型、分析模型、设计模型、实现模型和测试模型等等许多模型，软件架构本身就是一组模型的集合。</p>
<p>&nbsp;&nbsp;&nbsp; UML、SysML是当前国际上流行的软件/系统架构可视化建模语言。在编写实际的代码之前，利用包图、类图、活动图、交互图、状态图等等各种标准图形符号对软件架构进行建模，探讨和交流各种可行的设计方案，发现潜在的设计问题，保证具体编码实现之前抽象设计的正确性，被实践证明是一种非常有效和高效、敏捷的工作方式。</p>
<p>&nbsp;&nbsp;&nbsp; <strong>架构设计的重用</strong></p>
<p>&nbsp;&nbsp;&nbsp; 重用（Reuse）是在软件工程实践中获得高效率、高质量产品和系统开发的一种基本手段和主要途径，通过有组织的、系统和有效的重用，我们往往可以获得10倍率以上的效率提升。而一个优秀的、有长久生命力的软件架构（比方主流的一些框架软件），其本身或其组件被重用的次数越多，其体现的价值也就越大。</p>
<p>&nbsp;&nbsp;&nbsp; 软件重用有各种不同的范围、层次、粒度和类型，从函数重用、类重用、构件/组件重用、库（API）重用，到框架重用、架构重用、模式重用，再到软件设计知识、思想的重用等等，重用的效能和效果各有不同。</p>
<p>&nbsp;&nbsp;&nbsp; 软件工程经过几十年的发展，已经积累了大量的软件架构模式和设计模式，它们记载、蕴藏了大量成熟、已经验证的软件设计知识、思想和经验。我们平时对各种基础平台、主流框架和API的应用和调用，本身就是一种最为普遍的重用形式。而一个优秀、成熟的软件研发组织，必然会在日常开发中注意收集各种软件设计知识和经验，建立和维护基于架构模式和设计模式等内容的软件重用知识库，积极主动和频繁地运用各种软件模式来解决实际工程问题。</p>
<p>&nbsp;&nbsp;&nbsp; 框架（Framework）是一类具有高可重用度的软件，针对某一类应用或领域，它们具有非常灵活的、高度可扩展的软件架构。那么，如何才能设计出可重用的软件架构或其组件？借助于OOA、OOD等抽象分析和设计技术是一种重要的方法。人们在实践中发现，往往越抽象的东西，其适应面也就越广，可重用度也就越高；相反，越具体的东西，其适应面也就越窄，可重用度也就越低。重用，意味着充分利用现成、既有的东西、成果来解决新问题或重复的问题，以&#8220;不变&#8221;应&#8220;万变&#8221;。在软件架构设计中，应该主动地区分软件架构中的&#8220;不变&#8221;与&#8220;可变&#8221;之处，系统地管理好这些稳定点和变化点以适应未来的变化，这也是提高软件架构重用度、获得高质量框架设计的一种重要方法。</p>
<p>&nbsp;&nbsp;&nbsp; <strong>架构设计的权衡</strong></p>
<p>&nbsp;&nbsp;&nbsp; 与其它所有工程行业一样，软件工程本质上也是一门讲究权衡的科学和艺术。软件架构设计的最难之处往往在于如何在各种相互竞争、矛盾的制约条件之下，作出巧妙的最佳权衡。软件架构设计的权衡水平，也是最能体现软件架构师的设计经验、能力和技巧的地方。</p>
<p>&nbsp;&nbsp;&nbsp; 在软件开发和软件架构的设计过程中，从选择平台，到选择语言，选择框架，选择设计模式，选择工具&#8230;等等，我们无时不刻都需要权衡，对各种候选项作出合理评判。在架构师带领下，软件研发团队往往还需要对近期目标与远期目标、质量与速度和效率、质量与成本、功能与性能、灵活性与复杂性&#8230;等等许多彼此矛盾的设计选项、因素和约束进行细致、小心和理性的权衡。</p>
<p>&nbsp;&nbsp;&nbsp; 理性权衡意味着科学决策。进行有效的架构设计权衡，离不开科学的方法，也就是如何运用定量分析和定性分析相结合的方法、因果逻辑和根源分析等等技术，找到最终的甜点（Sweet Spot）。许多时候，能否在很短的时间内作出迅速、果断而正确的科学权衡与取舍决策，构成了一个软件研发团队核心竞争能力的一部分。</p>
<img src ="http://www.cppblog.com/flyinghare/aggbug/110292.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghare/" target="_blank">会飞的兔子</a> 2010-03-22 14:25 <a href="http://www.cppblog.com/flyinghare/archive/2010/03/22/110292.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>软件开发的任务分解</title><link>http://www.cppblog.com/flyinghare/archive/2010/03/15/109746.html</link><dc:creator>会飞的兔子</dc:creator><author>会飞的兔子</author><pubDate>Mon, 15 Mar 2010 08:23:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghare/archive/2010/03/15/109746.html</guid><wfw:comment>http://www.cppblog.com/flyinghare/comments/109746.html</wfw:comment><comments>http://www.cppblog.com/flyinghare/archive/2010/03/15/109746.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghare/comments/commentRss/109746.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghare/services/trackbacks/109746.html</trackback:ping><description><![CDATA[转自：<a href="http://www.javaeye.com/topic/5746">http://www.javaeye.com/topic/5746</a><br><br>说到任务分解，肯定就得说说WBS了。下边是摘自网上的一段对WBS的介绍： <br><br><span style="COLOR: blue">项目分解结构一般采用WBS（Works Breakdown Structure）方法，其步骤如下： <br>1．工程项目的结构分析 <br>项目的总任务是完成确定的技术系统（功能、质量、数量等）的工程，完成这个任务是通过许多互相联系、互相影响、互相依赖的工程活动实现的。 <br>2．工程项目结构分析的主要工作 <br>（1）工程项目的结构分解。 <br>（2）项目单元的定义。 <br>（3）项目单元之间逻辑关系的分析 <br>3．项目结构分解 <br>对一个项目进行结构分解，通常按系统分析方法，由粗到细，由总体到具体，由上而下地将工程项目分解成树型结构。结构分解的结果有：①树型结构图②项目结构分析表。 <br>4．项目结构分解过程 <br>（1）将项目分解成单个定义的且任务范围明确的子部分（子项目）。 <br>（2）研究并确定每个子部分的特点和结构规则，它的执行结果以及完成它所需的活动，以作进一步的分解。 <br>（3）将各层次结构单元（直到最低层的工作包）收集于检查表上，评价各层次的分解结果。 <br>（4）用系统规则，将项目单元分组，构成系统结构图（包括子结构图）。 <br>（5）分析并讲座分解的完整性，如有可能让相关部门的专家或有经验的人参加，并听取他们的意见。 <br>（6）由决策者决定结构图，并作相应的文件。 <br>（7）在设计和计划过程中确定各单元的（特别是工作包）说明文件内容，研究并确定系统单元之间的内部联系。 <br>5．项目结构分解方法 <br>（1）以产品结构进行分解。 <br>（2）按平面或空间位置进行分解。 <br>（3）按功能进行分解。 <br>（4）按要素进行分解。 <br>（5）按项目实施过程进行分解。</span> <br><br>用WBS对软件开发项目进行任务分解，我觉得主要是从两个方向进行分解：横向分解（对问题域进行拆分）和纵向分解（对实现过程进行拆分）。 <br>《PMP：Project Management Professional Study Guide》里边采用的就是纵向优先的拆分方法。 <br>而清华的那本《项目管理核心教程与PMP实战》比较乱，他举的两个例子都是纯粹的纵向分解，而他附录里的案例却是纯粹的横向分解。@_@ <br>我比较偏向于横向优先的拆分。 <br>因为纵向拆分通常意味着一个线性的过程，而横向的分解通常更利于迭代开发和FDD。 <br><br>进行任务分割时应当注意任务之间关于知识和技术的耦合程度，以及任务内关于知识和技术的内聚程度，以减少项目内耗。 <br>尽量做到低耦合，以降低对成员之间交流的依赖程度，让大多数成员（需要把握全局的骨干成员除外）无需考虑太多繁杂的、不相干的东西；尽量做到高内聚，让成员可以尽量发挥他的能力以及已经获得的项目相关信息。 <br>这些考虑很重要，但是却常常被忽略掉。 <br><br>对于划分好的任务，要仔细地分析它的难点和工作量，这些东西都是任务分配必须的约束条件。 <br>一定要结合技术含量、相关知识的学习难度来深入考虑，切不可以表面数据（代码行/页数/功能点数）来评估。 <br><br><br>任务分割完毕之后，就可以开始任务分配。 <br>任务分配的总则是<span style="COLOR: red">减少对交流的依赖</span>。 <br><br>对于不同的人来说，同一个任务的难度是不相同的。 <br>因此要调整任务分配，让合适的人做合适的工作，减少整体难度。 <br>分配过程中，尽量把高耦合的任务分给同一个成员，避免把过多过琐碎的无关任务分给同一个成员。 <br>此外，分配任务时，还应当把任务相应的知识/技术要点列表，连同其他任务资料一起提交给成员，以便成员能够提前做好准备，做到胸有成竹，以避免不必要的技术风险。 <br><br>如果工作量实在太大，或是工期要求太紧，不得不把高耦合任务甚至同一任务分给多个成员负责，这时候就要特别注意成员间工作相关知识的同步、信息的交流的问题。选择几个没有结怨的人，让这几个人坐在一起工作，就能使他们方便地交流。 <br><br>如果由于成员调度、个人进度、需求变更、以前遗漏的任务或者某种不可抗力等原因，而不得不更改任务分配，这时候一定要考虑如何最大化地利用项目人员已经做过的工作、已经获得的项目相关信息，尽量减少任务更改而引起的交流、培训和再教育花费。 
<img src ="http://www.cppblog.com/flyinghare/aggbug/109746.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghare/" target="_blank">会飞的兔子</a> 2010-03-15 16:23 <a href="http://www.cppblog.com/flyinghare/archive/2010/03/15/109746.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>微软软件开发过程与团队模型</title><link>http://www.cppblog.com/flyinghare/archive/2010/03/12/109483.html</link><dc:creator>会飞的兔子</dc:creator><author>会飞的兔子</author><pubDate>Fri, 12 Mar 2010 01:53:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghare/archive/2010/03/12/109483.html</guid><wfw:comment>http://www.cppblog.com/flyinghare/comments/109483.html</wfw:comment><comments>http://www.cppblog.com/flyinghare/archive/2010/03/12/109483.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghare/comments/commentRss/109483.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghare/services/trackbacks/109483.html</trackback:ping><description><![CDATA[转自：<a href="http://www.iteer.net/modules/doc/article.php?storyid=735">http://www.iteer.net/modules/doc/article.php?storyid=735</a><br><br>软件开发过程模型比较 <br>　　微软是世界上最大的软件公司，但微软并没有通过CMM认证，不使用RUP，也不使用XP。微软有自己的软件开发过程PCM。他们之间有什么区别？有什么共同点？微软是否有从CMM、TSP、PSP中取长补短？而中国软件企业又如何从这些林林总总的开发过程模型中选取适合自己的方法？CMM真的对中国软件企业有帮助么？来听听微软资深项目经理的现身说法吧。 <br>　　源代码管理与每日编译 <br>　　源代码控制(Source Control，又称源代码管理、版本控制、软件配置管理等)和每日编译(Daily Build，又称Nightly Build、持续集成等)是软件开发过程中最重要的方法，也是实施其他各种流程的必须基础(例如变更管理、缺陷管理、自动测试等)。 <br>　　上兵伐谋：微软产品规划方法 <br>　　好的起点是成功的一半，只有正确的制定产品开发策略，才能使产品在推向市场后被用户接受，在交付客户后令客户满意。在这个专题中，您将了解到微软如何策划新软件的特性、进行市场调研、了解和分析客户需求、收集用户反馈等。 <br>　　发布零缺陷软件：缺陷管理 <br>　　Bug管理是软件开发中非常重要的一个环节。在大型的商业软件开发中，没有Bug管理是不可想象的。Bug管理在微软的软件开发流程中同样起到举足轻重的作用，无论是Windows、Office这样大型的软件，还是内部使用的各种各样的小工具，Bug的管理都贯穿于整个开发流程的始终。 <br>　　单元测试 <br>　　随着软件产品复杂度的增加，越来越多的软件公司开始重视单元测试，意识到单元测试的重要性。单元测试在微软开发流程中同样是非常重要的一个环节。本专题将结合微软的.NET技术，对单元测试的方法和工具进行详细的介绍，帮助您建立起单元测试的流程。 <br>　　微软程序经理 <br>　　程序经理在微软产品开发的&#8220;三架马车&#8221;中具有非常重要的作用，在软件行业，只有微软设有该职位。在本专题中，将概要阐述微软程序经理产生的原因、使命，重点阐述应该具备什么样的优秀品质，以及程序经理的职业发展之路。 <br>　　撰写功能规格书 <br>　　功能规格书是微软开发流程中又一独具特色的内容。在整个开发过程中起到非常重要的作用，开发团队中每一个成员的工作都将以功能规格书为依据。一份详尽而实用的功能规格书可以确保整个开发团队向着统一的目标努力，不会出现偏差。 <br>　　撰写设计规格书 <br>　　设计规格书是功能规格书到最终产品实现之间的桥梁，它把电影剧本变成分镜头脚本，把抽象的功能描述变成程序员的设计语言。本专题将介绍设计规格书的写法，它与&#8220;概要设计&#8221;、&#8220;详细设计&#8221;的区别和联系，它到底要写到多详细，是否要定义所有的类接口和伪代码&#8230;。这些问题都将在本专题中得到解答。 <br>　　进度跟踪与控制 <br>　　开发一个合理的、实施性强的进度表，并对它进行有效的跟踪和控制，在项目管理中非常重要。本专题介绍微软制定进度表的步骤及方法，同时介绍了对进度表进行有效跟踪和控制的基本技能。 <br>　　管理需求与设计变更 <br>　　在软件的编写过程中，变更是不可避免的。变更使得开发团队成员之间的沟通难度增加，如果在变更之前没有做过很好的分析，变更实现没有被记录，并且没有向需要知道变更的人报告变化，那么项目组就会产生混乱，结果就是降低软件产品的质量，提高软件成本。本专题介绍变更管理的关键概念和流程，同时分析了实现有效变更控制的关键，并将剖析微软开中的变更管理实例，帮助您制订一个清楚的，简单适用的变更规则，并且帮助您使用好它，达到增进团队成员之间的了解，提高软件质量，降低开发风险和成本的目的。 <br>　　软件开发中的项目管理 <br>　　客户的需求永远在改变，项目可利用的资源永远不够，项目的进度永远会延后，这是项目管理永恒的话题。本主题将从项目管理的专业知识体系入手，贯穿微软项目管理的成功经验，与您共同探讨项目管理中永存的三个话题，并分享微软项目管理的十大成功法则以及科学高效的管理方法、管理技术和管理工具。 <br>　　软件性能测试 <br>　　使用压力工具1性能测试。有效的性能测试的最终目的是帮助产品提高性能，让产品响应更快、容量更大、占用资源更少。按照本专题所介绍的&#8220;计划、准备、执行、分析、提高&#8221;五步方法，能够让您在正确了解客户对性能的需求的基础上，有目的的了解系统的性能问题、有的放矢的找到瓶颈、立竿见影的提高性能。 <br>　　软件测试自动化实践 <br>　　使用自动化测试工具1自动化测试。本专题不谈具体工具，而是与您分享微软的心得体会，让您亲眼看到微软产品组如何将自动化测试运用自如，让您了解自动化并不神秘，你马上就能够在自己项目中运用；让您了解自动化测试并不是&#8220;银弹&#8221;，帮助您消除您的领导和客户对自动化测试的不正确的期望值。本专题能帮助你更好的进行自动化测试，而不仅仅是一个工具的实用者。 <br>　　用户界面设计 <br>　　优秀的软件界面和网站设计总是让用户感觉到处处顺手。但我们也常能看到一些缺乏设计的界面虽然堆满了控件却仍然不便使用，一些效果华丽的网站好看却不实用。怎么让你的产品的界面既美观大方又方便易用？怎么让你的系统界面看上去更专业？本专题介绍的用户界面设计的原则您一定要了解。 <br>　　易用性测试 <br>　　本专题将介绍微软特有的易用性实验室和易用性测试，以及如何通过易用性测试使您的产品更易学、易用，用户拿到产品不必看用户手册就会使用。 <br>　　团队编码制胜策略 <br>　　如果没有好的团队编码方法，一个程序员是龙，一群程序员是虫。微软是如何将大量的优秀程序员组织起来，让个人的技能和团队合作结合起来，编写出可靠、易读、高质量的代码。
<img src ="http://www.cppblog.com/flyinghare/aggbug/109483.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghare/" target="_blank">会飞的兔子</a> 2010-03-12 09:53 <a href="http://www.cppblog.com/flyinghare/archive/2010/03/12/109483.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>软件的架构与模式之经典架构模式简介</title><link>http://www.cppblog.com/flyinghare/archive/2010/01/05/104803.html</link><dc:creator>会飞的兔子</dc:creator><author>会飞的兔子</author><pubDate>Tue, 05 Jan 2010 02:46:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghare/archive/2010/01/05/104803.html</guid><wfw:comment>http://www.cppblog.com/flyinghare/comments/104803.html</wfw:comment><comments>http://www.cppblog.com/flyinghare/archive/2010/01/05/104803.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghare/comments/commentRss/104803.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghare/services/trackbacks/104803.html</trackback:ping><description><![CDATA[<p>转自：<a href="http://dev.yesky.com/387/2012387.shtml">http://dev.yesky.com/387/2012387.shtml</a><br><br>　　根据<a class=bluekey href="http://www.yesky.com/key/4747/159747.html" target=_blank><font color=#204890>Linda</font></a> Rising的《Pattern Almanac》一书，已知的架构模式有七十多种。这是一个只多不少的统计，其中包括了很多通常认为是设计模式的模式，比如Bridge，Facade，Interpreter，Mediator等模式通常认为是设计模式，但是在许多情况下，也可以作为架构模式出现，因此也常常被当作架构模式。<br><br>　　<strong>Layers架构模式</strong><br><br>　　在<a class=bluekey href="http://www.yesky.com/key/4340/174340.html" target=_blank><font color=#204890>收集</font></a>到用户对软件的要求之后，架构设计就开始了。架构设计一个主要的目的，就是把系统划分成为很多"板块"。划分的方式通常有两种，一种是横向的划分，一种是纵向划分。<br><br>　　横向划分将系统按照商业目的划分。比如一个<a class=bluekey href="http://www.yesky.com/key/1561/136561.html" target=_blank><font color=#204890>书店</font></a>的管理系统可以划分成为进货、销售、<a class=bluekey href="http://www.yesky.com/key/633/165633.html" target=_blank><font color=#204890>库存</font></a>管理、员工管理等等。<br><br>　　纵向划分则不同，它按照<a class=bluekey href="http://www.yesky.com/key/4805/289805.html" target=_blank><font color=#204890>抽象</font></a>层次的高低，将系统划分成"层"，或叫Layer。比如一个公司的内网管理系统通常可以划分成为下面的几个Layer:<br><br>　　一、网页，也就是用户界面，负责显示数据、接受用户输入；<br><br>　　二、领域层，包括JavaBean或者COM对象、<a class=bluekey href="http://www.yesky.com/key/4672/134672.html" target=_blank><font color=#204890>B2B</font></a>服务等，封装了必要的商业<a class=bluekey href="http://www.yesky.com/key/3446/223446.html" target=_blank><font color=#204890>逻辑</font></a>，负责根据商业逻辑决定显示什么数据、以及如何根据用户输入的数据进行计算；<br><br>　　三、数据库，负责存储数据，按照查询要求提供所存储的数据。<br><br>　　四、操作系统层，比如Windows NT或者Solaris等<br><br>　　五、硬件层，比如SUN E450服务器等<br><br>　　有人把这种Layer叫做Tier，但是Tier多带有<a class=bluekey href="http://www.yesky.com/key/365/180365.html" target=_blank><font color=#204890>物理</font></a>含义，不同的Tier往往位于不同的计算机上，由网络连接起来，而Layer是纯粹逻辑的概念，与物理划分无关。 <br><br>　　Layers架构模式的好处是：<br><br>　　第一、任何一层的变化都可以很好地局限于这一层，而不会影响到其他各层。<br><br>　　第二、更容易容纳新的技术和变化。Layers架构模式容许任何一层变更所使用的技术<br><br>　　<strong>Fa?ade架构模式</strong><br><br>　　外部与一个子系统的通讯必须通过一个统一的门面（Facade）对象进行，这就是Facade模式。<br><br>　　现代的软件系统都是比较复杂的，设计模式的任务就是协助设计师处理复杂系统的设计。<br><br>　　设计师处理复杂系统的一个常见方法便是将其"分而治之"，把一个系统划分为几个较小的子系统。但是这样做了以后，设计师往往仍然会发现一个子系统内仍然有太多的类型要处理。而使用一个子系统的使用端往往只关注一些特定的功能，却要同时与子系统内部的许多对象打交道后才能达到目的，请见下面的对象图。<br><br>
<table width="90%" align=center border=0>
    <tbody>
        <tr>
            <td>
            <div align=center><img src="http://image.tianjimedia.com/imagelist/05/06/a87695fj2vm9.gif" border=0><br>图4、Facade架构模式的结构图。</div>
            </td>
        </tr>
    </tbody>
</table>
<br>　　这就是一种不便，它使得系统的逻辑变得不必要的复杂，维护成本提高，复用率降低。<br><br>　　用一个范例说明，中国<a class=bluekey href="http://www.yesky.com/key/3161/168161.html" target=_blank><font color=#204890>大陆</font></a>的<a class=bluekey href="http://www.yesky.com/key/3390/138390.html" target=_blank><font color=#204890>医院</font></a>便是一个子系统，按照部门职能，这个系统可以划分为挂号、门诊、划价、化验、收银、取药等。看病的病人要与这些部门打交道，就如同一个子系统的使用端与一个子系统的各个类型打交道一样，不是一件容易的事情。<br><br>　　首先病人必须先挂号，然后门诊。如果医生要求化验，病人必须首先划价，然后缴款，才能到化验部门做化验。化验后，再回到门诊室，请见下面的对象图。<br><br>
<table width="90%" align=center border=0>
    <tbody>
        <tr>
            <td>
            <div align=center><img src="http://image.tianjimedia.com/imagelist/05/06/ho315ggk8hk0.jpg" border=0><br>图5、描述病人在医院里的体验。图中的方框代表医院。 </div>
            </td>
        </tr>
    </tbody>
</table>
<br>　　解决这种不便的方法便是引进Facade模式。仍然通过医院的范例说明，可以设置一个接待员的位置，由接待员负责代为挂号、划价、缴费、取药等。这个接待员就是Facade模式的体现，病人只接触接待员，由接待员负责与医院的各个部门打交道，请见下面的对象图。<br><br>
<table width="90%" align=center border=0>
    <tbody>
        <tr>
            <td>
            <div align=center><img src="http://image.tianjimedia.com/imagelist/05/06/631z3q347q41.jpg" border=0><br>图6、描述经过Facade模式的<a class=bluekey href="http://www.yesky.com/key/3989/148989.html" target=_blank><font color=#204890>改装</font></a>后，病人在医院里的体验。图中的方框代表医院。</div>
            </td>
        </tr>
    </tbody>
</table>
<br>　　Facade模式要求一个子系统的外部与其内部的通讯必须通过一个统一的门面（Facade）对象进行。Facade模式提供一个<a class=bluekey href="http://www.yesky.com/key/4920/184920.html" target=_blank><font color=#204890>高等</font></a>级的接口，使得子系统更易于使用。<br><br>　　使用了Facade模式之后，本章的第一个图中所描述的一个子系统的使用端对象所面对的复杂关系就可以简化为下面这个样子。 <br><br>
<table width="90%" align=center border=0>
    <tbody>
        <tr>
            <td>
            <div align=center><img src="http://image.tianjimedia.com/imagelist/05/06/4j1k41qbnf7h.gif" border=0><br>图7、Facade架构模式的结构图</div>
            </td>
        </tr>
    </tbody>
</table>
<br>　　描述经过Facade模式的改装后，一个子系统的使用端与子系统的关系。图中的大方框代表一个子系统。<br><br>　　就如同医院的接待员一样，Facade模式的门面类型将使用端与子系统的内部复杂性分隔开，使得使用端只需要与门面对象打交道，而不需要与子系统内部的很多对象打交道。<br><br>　　<strong>Mediator架构模式</strong><br><br>　　Mediator模式包装了一系列对象相互作用的方式，使得这些对象不必互相明显参照；从而使它们可以较松散地耦合。当这些对象中的某些对象之间的相互作用发生改变时，不会立即影响到其它的一些对象之间的相互作用；从而可以保证这些相互作用可以彼此独立地变化。 <br><br>　　在下面的示意图中有大量的对象，这些对象既会影响别的对象，又会被别的对象所影响，因此常常叫做同事（Colleague）对象。这些同事对象通过彼此的相互作用形成系统的行为。从图中可以看出，几乎每一个对象都需要与其它的对象发生相互作用，而这种相互作用表现为一个对象与另一个对象的直接耦合。<br><br>
<table width="90%" align=center border=0>
    <tbody>
        <tr>
            <td>
            <div align=center><img src="http://image.tianjimedia.com/imagelist/05/06/u3xb76t989n9.gif" border=0><br>图8、这是一个过度耦合的系统</div>
            </td>
        </tr>
    </tbody>
</table>
<br>　　通过引入调停者对象（Mediator），可以将系统的网状结构变成以中介者为中心的星形结构，如下图所示。在这个星形结构中，同事对象不再通过直接的联系与另一个对象发生相互作用；相反地，它通过调停者对象与另一个对象发生相互作用。调停者对象的存在保证了对象结构上的稳定，也就是说，系统的结构不会因为新对象的引入造成大量的修改工作。 <br><br>
<table width="90%" align=center border=0>
    <tbody>
        <tr>
            <td>
            <div align=center><img src="http://image.tianjimedia.com/imagelist/05/06/ty1x3qa272mo.gif" border=0><br>图9、这是一个使用了Mediator架构模式之后的结构图</div>
            </td>
        </tr>
    </tbody>
</table>
<br>　　比较传统的设计方法，面向对象的技术可以更好地协助设计师管理更为复杂的系统。一个好的面向对象的设计可以使对象之间增加协作性（Collaboration），减少耦合度（<a class=bluekey href="http://www.yesky.com/key/2395/162395.html" target=_blank><font color=#204890>Coupling</font></a>）。一个深思熟虑的设计会把一个系统分解为一群相互协作的同事对象，然后给每一个同事对象以独特的责任，恰当的配置它们之间的协作关系，使它们可以在一起工作。<br><br>　　在Mediator模式中，所有的成员对象都可以协调工作，但是又不直接相互管理。这些对象都与一个处于中心地位的调停者对象发生紧密的关系，由这个调停者对象进行协调工作。这个协调者对象叫做调停者（Mediator），而调停者所协调的成员对象称做同事（Colleague）对象。<br><br>　　<a class=bluekey href="http://www.yesky.com/key/193/200193.html" target=_blank><font color=#204890>在C</font></a>olleague对象内部发生的事件会影响到所有的同事，但是这种影响不是以直接管理的方式直接传到其它的对象上的。记住在小组的成员增加时，这样的相互作用关系是以比指数更快的方式增加的。相反，这种影响仅仅直接影响到调停者对象，而调停者对象反过来会协调其它的同事，形成整个系统的行为。<br><br>　　如果小组的成员增加时，调停者对象可能会面临修改，而其它的同事则可以装做不知道这个新的成员一样，不必修改。反过来，如果小组的成员之一被从系统中删除的话，调停者对象需要对此做出修改，而小组中其它的同事则不必改动。<br><br>　　<strong>Interpreter架构模式</strong><br><br>　　给定一个语言之后，Interpreter模式可以定义出其文法的一种表示，并同时提供一个直译器；使用端可以使用这个直译器来解释这个语言中的句子。<br><br>　　如果某一类型问题一再地发生的话，那么一个有意义的做法就是将此类型问题的各个实例表达为一个简单语言中的语句。这样就可以建造一个直译器，通过解释这些语句达到解决问题的目的。<br><br>　　例如，依照一个匹配模式搜寻字符串便是一个常见的问题。与其为每一个匹配模式建造一个特定的算法，不如建造一个一般性的算法处理各种常规表达式。当接到一个指定的常规表达式时，系统使用一个直译器解释这个常规表达式，从而对字符串进行匹配。<br><br>　　再比如<a class=bluekey href="http://www.yesky.com/key/1069/136069.html" target=_blank><font color=#204890>VBA</font></a>（Visual <a class=bluekey href="http://www.yesky.com/key/2906/137906.html" target=_blank><font color=#204890>Basic</font></a> for Applications）就不仅仅出现在微软的Office系列软件中，并且可以供第三<a class=bluekey href="http://www.yesky.com/key/2945/157945.html" target=_blank><font color=#204890>厂家</font></a>出产的软件嵌入使用；Crystal <a class=bluekey href="http://www.yesky.com/key/920/165920.html" target=_blank><font color=#204890>Reports</font></a>报表生成软件也包括了一个便于使用的宏语言，使用户可以执行较为复杂的命令操作。一般而言，将VBA或者其它的语言软件嵌入到自己的<a class=bluekey href="http://www.yesky.com/key/3887/173887.html" target=_blank><font color=#204890>软件产品</font></a>中，可以使产品定制化（Customization）能力大大增强，但是这些宏语言引擎往往都很昂贵。<br><br>　　现在要介绍的Interpreter模式将描述怎样在有了一个简单的文法后，使用模式设计解释这些语句。熟悉了这个模式以后，一个没有接收过形式语言和编译器的正规训练的设计师也可以自行设计一个简单的直译器，以便为使用端提供一个简单语言，或者在系统内部使用一个简单语言描述一个合适的问题。<br><br>　　<strong>语言、直译器和剖析器</strong><br><br>　　Interpreter模式只描述直译器是怎样工作的，并不指明怎样在执行时创建新的直译器。虽然广义地讲直译器不一定要有一个剖析器（Parser），但是使用剖析器仍然是最常见的建立直译器的办法。一个剖析器可以从一个档或命令行读入文字性命令，并创建直译器。<br>剖析器是一种能够识别文字并将文字按照一定规则进行分解以便进一步处理的对象。剖析器能够识别的字符串叫做语言。通常建立的小型计算机语言是与环境无关的语言，也就是遵循一定的文法的文字模式，所谓文法，便是决定怎样将语言的元素组合起来的规则的集合。剖析器便是根据组合规则将字符串分解的。<br><br>　　抽象地讲，语言并不一定是以字符串的形式表达的。在Interpreter模式里面所提到的语言是指任何直译器对象能够解释的任何组合。在Interpreter模式中，需要定义一个代表文法的命令类型的等级结构，也就是一系列的组合规则；每一个命令对象都有一个解释方法，代表对命令对象的解释。<br><br>　　命令对象的等级结构中的对象的任何排列组合都是一个语言，而剖析器的工作便是将一个文字性语言翻译成为等效的直译器语言。因此，直译器往往需要剖析器。<br><br>　　<strong>认识Jack吗</strong>？<br><br>　　剖析器生成器（Parser Generator），常常称为编译器的编译器（Compiler Complier）。Sun Microsystem提供一个专为Java程序员发明的强大的剖析器生成器，最初叫做Jack，后来改名为JavaCC。<br><br>　　要使用JavaCC，必须使用它提供的脚本语言<a class=bluekey href="http://www.yesky.com/key/4285/189285.html" target=_blank><font color=#204890>编写</font></a>一个脚本，然后执行JavaCC生成Java源代码。这生成的源代码就是所需的剖析器。现在Sun已经不再负责JavaCC的研发，对JavaCC感兴趣的读者可以从http://www.experimentalstuff.com/Technologies/JavaCC得到免费的JavaCC和相关数据。<br><br>　　JavaCC最早命名为Jack是为了与一个早就广泛使用的剖析器生成器YACC谐音。如果读者已经熟悉了YACC，可以使用YACC达到同样的目的；只是相比之下JavaCC更容易得到Java程序员的喜爱。<br><!--文章页底部广告开始--><br></p>
<img src ="http://www.cppblog.com/flyinghare/aggbug/104803.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghare/" target="_blank">会飞的兔子</a> 2010-01-05 10:46 <a href="http://www.cppblog.com/flyinghare/archive/2010/01/05/104803.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>TFS中撤消别的用户对某个文件的锁定</title><link>http://www.cppblog.com/flyinghare/archive/2009/09/27/97333.html</link><dc:creator>会飞的兔子</dc:creator><author>会飞的兔子</author><pubDate>Sun, 27 Sep 2009 01:21:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghare/archive/2009/09/27/97333.html</guid><wfw:comment>http://www.cppblog.com/flyinghare/comments/97333.html</wfw:comment><comments>http://www.cppblog.com/flyinghare/archive/2009/09/27/97333.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghare/comments/commentRss/97333.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghare/services/trackbacks/97333.html</trackback:ping><description><![CDATA[转自：<a href="http://www.cnblogs.com/longjxchina/archive/2009/02/13/1389681.html">http://www.cnblogs.com/longjxchina/archive/2009/02/13/1389681.html</a><br><br>
<p style="MARGIN: 12pt 0cm 3pt"><strong><span style="FONT-FAMILY: 'Calibri','sans-serif'">（转载说明：根据本机测试情况，对原文稍加改动）</span></strong></p>
<p style="LINE-HEIGHT: 18.4pt; TEXT-INDENT: 24pt; MARGIN: 0cm 0cm 0pt 7.45pt; BACKGROUND: white; WORD-BREAK: break-all" align=left>&nbsp;<span style="FONT-FAMILY: 宋体; COLOR: black; FONT-SIZE: 10pt">想要在</span><span style="COLOR: black; FONT-SIZE: 10pt">TFS</span><span style="FONT-FAMILY: 宋体; COLOR: black; FONT-SIZE: 10pt">中撤消别的用户对某个文件的锁定，首先需要使用此用户在本地获得一个工作区</span><span style="COLOR: black; FONT-SIZE: 10pt">(WorkSpace)</span><span style="FONT-FAMILY: 宋体; COLOR: black; FONT-SIZE: 10pt">，并且获取需要解锁定的文件的最新版本。然后执行以下步骤：</span></p>
<p style="LINE-HEIGHT: 18.4pt; TEXT-INDENT: 24pt; MARGIN: 0cm 0cm 0pt 7.45pt; BACKGROUND: white; WORD-BREAK: break-all" align=left>&nbsp;<span style="COLOR: black; FONT-SIZE: 10pt">1</span><span style="FONT-FAMILY: 宋体; COLOR: black; FONT-SIZE: 10pt">、打开命令窗口：&#8220;开始&#8221;</span><span style="COLOR: black; FONT-SIZE: 10pt">-&gt;</span><span style="FONT-FAMILY: 宋体; COLOR: black; FONT-SIZE: 10pt">&#8220;</span><span style="COLOR: black; FONT-SIZE: 10pt">CMD</span><span style="FONT-FAMILY: 宋体; COLOR: black; FONT-SIZE: 10pt">&#8221;</span></p>
<p style="LINE-HEIGHT: 18.4pt; TEXT-INDENT: 24pt; MARGIN: 0cm 0cm 0pt 7.45pt; BACKGROUND: white; WORD-BREAK: break-all" align=left>&nbsp;<span style="COLOR: black; FONT-SIZE: 10pt">2</span><span style="FONT-FAMILY: 宋体; COLOR: black; FONT-SIZE: 10pt">、定位到</span><span style="COLOR: black; FONT-SIZE: 10pt">Visual Studio</span><span style="FONT-FAMILY: 宋体; COLOR: black; FONT-SIZE: 10pt">的安装文件夹：</span><span style="COLOR: black; FONT-SIZE: 10pt">cd %LocalDisk%"Program Files"Microsoft Visual Studio 8"Common7"IDE"</span></p>
<p style="LINE-HEIGHT: 18.4pt; TEXT-INDENT: 24pt; MARGIN: 0cm 0cm 0pt 7.45pt; BACKGROUND: white; WORD-BREAK: break-all" align=left>&nbsp;<span style="COLOR: black; FONT-SIZE: 10pt">3</span><span style="FONT-FAMILY: 宋体; COLOR: black; FONT-SIZE: 10pt">、输入如下命令：</span></p>
<p style="LINE-HEIGHT: 18.4pt; TEXT-INDENT: 24pt; MARGIN: 0cm 0cm 0pt 34.45pt; BACKGROUND: white; WORD-BREAK: break-all" align=left><span style="COLOR: black; FONT-SIZE: 10pt">Tf workspaces /owner:</span><span style="FONT-FAMILY: 宋体; COLOR: black; FONT-SIZE: 10pt">所有者或</span><span style="COLOR: black; FONT-SIZE: 10pt">* /server:</span><span style="FONT-FAMILY: 宋体; COLOR: black; FONT-SIZE: 10pt">服务器名称或</span><span style="COLOR: black; FONT-SIZE: 10pt">IP</span></p>
<p style="LINE-HEIGHT: 18.4pt; TEXT-INDENT: 24pt; MARGIN: 0cm 0cm 0pt 34.45pt; BACKGROUND: white; WORD-BREAK: break-all" align=left><span style="FONT-FAMILY: 宋体; COLOR: black; FONT-SIZE: 10pt">通过此命令来显示此用户的多个工作区，如下图所示：<span style="FONT-FAMILY: 'Verdana','sans-serif'; COLOR: black; FONT-SIZE: 11.5pt; mso-fareast-font-family: 宋体; mso-bidi-font-family: 宋体; mso-no-proof: yes; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA" lang=EN-US><v:shapetype id=_x0000_t75 coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f">&nbsp;<v:stroke joinstyle="miter"></v:stroke><v:formulas><v:f eqn="if lineDrawn pixelLineWidth 0"></v:f><v:f eqn="sum @0 1 0"></v:f><v:f eqn="sum 0 0 @1"></v:f><v:f eqn="prod @2 1 2"></v:f><v:f eqn="prod @3 21600 pixelWidth"></v:f><v:f eqn="prod @3 21600 pixelHeight"></v:f><v:f eqn="sum @0 0 1"></v:f><v:f eqn="prod @6 1 2"></v:f><v:f eqn="prod @7 21600 pixelWidth"></v:f><v:f eqn="sum @8 21600 0"></v:f><v:f eqn="prod @7 21600 pixelHeight"></v:f><v:f eqn="sum @10 21600 0"></v:f></v:formulas><v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"></v:path><o:lock v:ext="edit" aspectratio="t"></o:lock></v:shapetype></span></span></p>
<p style="LINE-HEIGHT: 18.4pt; TEXT-INDENT: 24pt; MARGIN: 0cm 0cm 0pt 7.45pt; BACKGROUND: white; WORD-BREAK: break-all" align=left></p>
<p style="LINE-HEIGHT: 18.4pt; TEXT-INDENT: 24pt; MARGIN: 0cm 0cm 0pt 34.45pt; BACKGROUND: white; WORD-BREAK: break-all" align=left></p>
<p style="LINE-HEIGHT: 18.4pt; TEXT-INDENT: 24pt; MARGIN: 0cm 0cm 0pt 7.45pt; BACKGROUND: white; WORD-BREAK: break-all" align=left><span style="COLOR: black; FONT-SIZE: 10pt"><img border=0 alt="" src="http://www.cppblog.com/images/cppblog_com/flyinghare/200909270001.png" width=688 height=152><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;注意：以上命令在 TFS2008 下测试成功；<span style="COLOR: #ff0000"><strong style="FONT-SIZE: 14pt">在 TFS2010 下，server 参数貌似需要加完整路径</strong></span>，例如：&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;/source:http://source:8080/tfs/source<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #ff0000">怎样查看 TFS 完整路径</span>：在团队资源管理器中，选中服务器根节点，查看属性窗口中的 URL 属性。<br></span></p>
<p style="LINE-HEIGHT: 18.4pt; TEXT-INDENT: 24pt; MARGIN: 0cm 0cm 0pt 7.45pt; BACKGROUND: white; WORD-BREAK: break-all" align=left><span style="COLOR: black; FONT-SIZE: 10pt">4</span><span style="FONT-FAMILY: 宋体; COLOR: black; FONT-SIZE: 10pt">、输入命令撤消文件锁定：</span></p>
<p style="LINE-HEIGHT: 18.4pt; TEXT-INDENT: 24pt; MARGIN: 0cm 0cm 0pt 34.45pt; BACKGROUND: white; WORD-BREAK: break-all" align=left><span style="COLOR: black; FONT-SIZE: 10pt">Tf undo /workspace:</span><span style="FONT-FAMILY: 宋体; COLOR: black; FONT-SIZE: 10pt">工作区名称</span><span style="COLOR: black; FONT-SIZE: 10pt">;</span><span style="FONT-FAMILY: 宋体; COLOR: black; FONT-SIZE: 10pt">所有者</span><span style="COLOR: black; FONT-SIZE: 10pt"> /server:</span><span style="FONT-FAMILY: 宋体; COLOR: black; FONT-SIZE: 10pt">服务器名称或</span><span style="COLOR: black; FONT-SIZE: 10pt">IP </span><span style="FONT-FAMILY: 宋体; COLOR: black; FONT-SIZE: 10pt">被锁定文件在TFS服务器的路径<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="FONT-FAMILY: 宋体; COLOR: black; FONT-SIZE: 10pt">通过此命令就可以把被锁定的文件锁给撤消，不过要注意的是：如果完成这些操作是在客户端机器上的话，命令会给出没有权限警告并要求输入服务器的管理员帐户和密码。只有输入正确的帐户和密码后才可以正常的撤消锁定，如下图所示：</span></p>
<p style="LINE-HEIGHT: 18.4pt; TEXT-INDENT: 24pt; MARGIN: 0cm 0cm 0pt 7.45pt; BACKGROUND: white; WORD-BREAK: break-all" align=left></p>
<p style="LINE-HEIGHT: 18.4pt; TEXT-INDENT: 24pt; MARGIN: 0cm 0cm 0pt 34.45pt; BACKGROUND: white; WORD-BREAK: break-all" align=left><span style="FONT-FAMILY: 宋体; COLOR: black; FONT-SIZE: 10pt"><img border=0 alt="" src="http://www.cppblog.com/images/cppblog_com/flyinghare/200909270002.png" width=674 height=110></span></p>
<p style="LINE-HEIGHT: 18.4pt; TEXT-INDENT: 24pt; MARGIN: 0cm 0cm 0pt 34.45pt; BACKGROUND: white; WORD-BREAK: break-all" align=left><span style="FONT-FAMILY: 宋体; COLOR: black; FONT-SIZE: 10pt">虽然上图显示的是&#8220;没有要撤消的挂起更改，但是更改仍然是正常的运行了，只要你刷新一下</span><span style="COLOR: black; FONT-SIZE: 10pt">TFS</span><span style="FONT-FAMILY: 宋体; COLOR: black; FONT-SIZE: 10pt">界面就可以看到效果，并且也可以正常对此文件进行签出和编辑。</span></p>
<p style="LINE-HEIGHT: 18.4pt; TEXT-INDENT: 24pt; MARGIN: 0cm 0cm 0pt 34.45pt; BACKGROUND: white; WORD-BREAK: break-all" align=left><span style="FONT-FAMILY: 宋体; COLOR: black; FONT-SIZE: 10pt"><br></span></p>
其他相关文章：http://cleocn.appspot.com/?p=85033 
<img src ="http://www.cppblog.com/flyinghare/aggbug/97333.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghare/" target="_blank">会飞的兔子</a> 2009-09-27 09:21 <a href="http://www.cppblog.com/flyinghare/archive/2009/09/27/97333.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用Google code + SVN进行多人开发</title><link>http://www.cppblog.com/flyinghare/archive/2009/09/20/96786.html</link><dc:creator>会飞的兔子</dc:creator><author>会飞的兔子</author><pubDate>Sun, 20 Sep 2009 10:04:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghare/archive/2009/09/20/96786.html</guid><wfw:comment>http://www.cppblog.com/flyinghare/comments/96786.html</wfw:comment><comments>http://www.cppblog.com/flyinghare/archive/2009/09/20/96786.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghare/comments/commentRss/96786.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghare/services/trackbacks/96786.html</trackback:ping><description><![CDATA[<p>转自：<a href="http://blog.csdn.net/cc_net/archive/2009/08/16/4452890.aspx">http://blog.csdn.net/cc_net/archive/2009/08/16/4452890.aspx</a><br><br>说到源码管理，CVS,VSS,SVN,TFS大家在公司可能都用的比较多了。但是在公司的环境基本都是在局域网中或者是专线连结到远程服务器来使用。平时自己在家和朋友一些写一些代码的时候都苦于没有代码管理工具，没有网络环境，而不能不把代码传来传去，很是麻烦。不过Google code提供了免费的SVN空间，主要注册了GMAIL，然后就可以使用SVN进行源码管理，和其他人共同开发了。</p>
<p>网上有介绍的，不过我看了都不怎么详细，自己摸索了下，写下来大家分享下。</p>
<p>一 访问Google code<br>Google code的地址是 <a href="http://code.google.com/">http://code.google.com/</a>&nbsp; ，如果使用cn去访问好像访问不了，我这里是一片空白。管理项目的话可以直接使用<a href="http://code.google.com/hosting/">http://code.google.com/hosting/</a> 地址访问。用Gmail登录进去，页面的中间有【Create a new project 】，点击以后就可以创建项目了。</p>
<p>&nbsp;<img border=0 alt="" src="http://www.cppblog.com/images/cppblog_com/flyinghare/2009-08-16_15-02-39.jpg" width=752 height=768></p>
<p>二 创建自己的项目<br>在创建项目的页面，填写项目名，概要和描述，其中项目名开头要小写，还不能有空格和其他符号。然后就是选择版本管理系统，证书等等，这些我也不懂，随便选吧，反正这有选好了，【Create Project】才可用。这里要注意的是项目名字可能冲突。如果创建成功就可以进入项目管理界面</p>
<p>&nbsp;<img border=0 alt="" src="http://www.cppblog.com/images/cppblog_com/flyinghare/2009-08-16_15-08-59.jpg" width=926 height=618></p>
<p>三 项目管理<br>项目管理中，上方的菜单【Project Home】可以看到项目的概述和描述。点击【Source】就可以进行源码的管理。其中有2个地址，一个是Https开头的，一个是http的，https开头的是带加密的，所以如果要commit新的代码的时候就需要使用这个地址。而如果仅仅是取得代码可以只使用http开头的地址。</p>
<p>使用https的地址的时候需要提供用户名和密码，这里的用户名是Gmail的用户名，而密码是Google给每个项目生成的，而非是Gmail的密码。点击【When prompted, enter your generated googlecode.com password 】后面的蓝色连接可以看到密码。这个密码是你所有项目的密码，而不是每个项目一个密码。</p>
<p>&nbsp;<img border=0 alt="" src="http://www.cppblog.com/images/cppblog_com/flyinghare/2009-08-16_15-13-36.jpg" width=963 height=564><br>四 用户管理<br>项目建立好以后就可以把其他人加入到项目中，这样就可以共同开发了。首先点击上方的【Administer】，然后点【Project members】，在下面填入要加入的用户Gmail就可以了。有Project owners，Project committers，Project contributors。具体解释右侧都有。点击保存后，其他用户登录后，在右上方的【My Favorite】下就可以看到自己加入的项目了。然后按三中介绍的方法找到密码。</p>
<p>五 其他管理<br>Google Code还提供了wiki等功能，我没用上，所以不是太了解。</p>
<p>六 安装客户端和VS插件<br>上面的工作做好后就是上传源码和文档。但是我找了半天也不知道怎么上传。以为是直接网页上上传，原来也要安装SVN客户端。在这里</p>
<p><a href="http://tortoisesvn.net/downloads">http://tortoisesvn.net/downloads</a>&nbsp; 可以下载到最新的TortoiseSVN，这个应该是目前用的最多的SVN客户端软件了。E文不好的朋友上面还提供了中文语言包。</p>
<p>安装完客户端后需要重启电脑，然后就可以远程连接到SVN服务器了。其中URL就填写Google 提供的哪个https的URL地址，然后填写用户名（Gmail）和密码（项目密码），保存后就OK了。客户端可以支持连接多个URL，每次启动的时候可以选择要连接到那一个。</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>支持SVN的VS插件我使用的是AnkhSvn，<a href="http://ankhsvn.open.collab.net/servlets/ProjectDocumentList?folderID=198">http://ankhsvn.open.collab.net/servlets/ProjectDocumentList?folderID=198</a> 这里可以下载到最新版本。目前可以支持到VS2010，之前使用老版本对VS2008支持不好，文件状态不对，而且不能提交，换到最新版的时候就好了。安装的时候配置VS要比较长时间，不要以为是死掉了。</p>
<p>如果只安装AnkhSvn而不安装TortoiseSVN也是可以的，不过你在VS中会发现，操作的功能少了很多，比如分支，合并等等。</p>
<p>&nbsp;</p>
<p>七 使用VS进行开发和源码管理<br>进入到VS中，打开【工具】--【选项】--【Source Control】，默认应该是已经配置好了为AnkhSvn。然后可以点击【文件】-【Subvwrsion】打开服务器上的源码。和其他工具一样，要选择一个本地路径来保存。</p>
<p>&nbsp;</p>
<p>1：文件状态介绍</p>
<p>蓝色小勾：Check out状态；橙色小勾：文件被修改状态；橙色小方块：文件修改被保存；加号：新添加文件。</p>
<p>2：SNV版本控制</p>
<p>和VSS不同的时，VSS默认是锁住的状态，需要手动Check Out，而SVN是自动Check Out。那么这样不是会有冲突吗，其实这个和VSS允许多人牵出是一样的。在你Commit的时候，会检查版本，会自动合并或提示冲突或是版本过期等等。</p>
<p>&nbsp;</p>
<p>获取最新代码：这个不用说了就是从服务器上拿最新代码，但是如果你修改了文件，然后拉最新代码，这个时候系统会自动吧你修改的不部分和最新代码进行合并，如果有冲突会提示，要修修改冲突。</p>
<p>获取指定版本代码：这个可以通过查看历史，或者指定版本号来拉去指定版本的代码。这是同样会合并代码。需要注意的是，SVN的版本号和VSS不同，是全局版本号，而不是每个文件有一个版本号。这个要特别注意，因为你会发现一个文件版本号可能是跳跃的。</p>
<p>Switch：有这样一个功能，可以把当前版本切换为制定的版本，和获取指定版本不同，他也会自动合并不同的地方。</p>
<p>Revert：恢复功能，恢复到修改前的状态。这个要注意的是，如果你对文件修改，然后获取了最新代码，然后恢复，这个时候是恢复到最新版本，而不是修改前的那个版本。这点要注意</p>
<p>版本冲突：这里版本冲突有2种情况，</p>
<p>如果你当前版本为1，服务器版本为2，你修改或提交，服务器会提示你本地版本过期了，你可以拉最新代码，并解决冲突后再次提交；</p>
<p>如果你当前版本为2，服务器版本为2，而你从服务器获取版本1的代码，修改后，然后提交，这个时候是不会提示版本过期的，会覆盖掉服务器上的版本2，而成为版本3。这样是会冲掉代码的。</p>
<p>锁：SVN提供了锁的功能，就和VSS的单用户Check out是一样的，不能同时修改。但是目前Google Svn不提供锁的功能，所以没有办法使用了。</p>
<p>八 SVN资料<br>以前没有使用过SVN的源码管理，所以有些地方感觉不一样。关于SVN的版本控制的方法和SVN介绍可以参考一下网站</p>
<p><a href="http://www.subversion.org.cn/svnbook/1.4/svn.basic.vsn-models.html">http://www.subversion.org.cn/svnbook/1.4/svn.basic.vsn-models.html</a> </p>
<p>&nbsp;</p>
<p>本文来自CSDN博客，转载请标明出处：<a href="http://blog.csdn.net/cc_net/archive/2009/08/16/4452890.aspx">http://blog.csdn.net/cc_net/archive/2009/08/16/4452890.aspx</a></p>
<img src ="http://www.cppblog.com/flyinghare/aggbug/96786.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghare/" target="_blank">会飞的兔子</a> 2009-09-20 18:04 <a href="http://www.cppblog.com/flyinghare/archive/2009/09/20/96786.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>免费 SVN 服务器收集</title><link>http://www.cppblog.com/flyinghare/archive/2009/08/19/93773.html</link><dc:creator>会飞的兔子</dc:creator><author>会飞的兔子</author><pubDate>Wed, 19 Aug 2009 01:52:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghare/archive/2009/08/19/93773.html</guid><wfw:comment>http://www.cppblog.com/flyinghare/comments/93773.html</wfw:comment><comments>http://www.cppblog.com/flyinghare/archive/2009/08/19/93773.html#Feedback</comments><slash:comments>10</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghare/comments/commentRss/93773.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghare/services/trackbacks/93773.html</trackback:ping><description><![CDATA[&nbsp;国内：<br>http://www.coollittlethings.com/ <br>只需要注册即可使用，速度很快，使用http进行传输，无web管理功能。<br><br>国外：<br>http://code.google.com/hosting/<br>google提供的，速度比较快，申请即可使用，使用https进行传输，安全性，可靠性高，带有web管理功能。<br><br>http://developer.novell.com/wiki/index.php/Project_Hosting<br>novell公司提供，申请后需要审核，速度较快，使用https进行传输，安全性，可靠性高，带有web管理功能。<br><br>
<p>OpenSVN - 台湾的服务器<br><a href="https://opensvn.csie.org/"><u><font color=#0066cc>https://opensvn.csie.org/</font></u></a><br>支持http https 协议 允许个人项目使用 其他不详...详细说明参见<a href="http://wiki.ptt.cc/-OpenSVNFAQ"><u><font color=#0066cc>http://wiki.ptt.cc/-OpenSVNFAQ</font></u></a></p>
<p>SVN源代码托管服务器 - 上海电信服务器<a href="http://www.svnhost.cn/"><br><u><font color=#0066cc>http://www.svnhost.cn/</font></u></a><br>支持svn协议....允许建立一个个人项目的源码库...Open Sourse 不限!<br>速度相当可以.只不过公司外网防火墙BT...无法响应...所以没用这个了!</p>
<a href="http://www.javaforge.com/"><font color=#1a8bc8><br><font color=#000000>提供免费的Subversion服务器申请</font><br>http://www.javaforge.com</font></a>&nbsp;，对于公司来说也许没什么很大的用处，但对网上朋友小型的团队开发，而又没有自已的版本控制服务器的朋友来说还是挺有用的。<br><br>而另外的就是去申请SVN Hosting了，这里有一个SVN Hosting 值得考虑：<br>[ <strong><a href="http://svn.coollittlethings.com/" target=_blank><font color=#864f0e>http://svn.coollittlethings.com/</font></a></strong> ]，或许能给正在为天天办公室和家里同步代码的人烦恼人用上！<br><br><a href="http://code.svnspot.com/">http://code.svnspot.com/</a><br>
<img src ="http://www.cppblog.com/flyinghare/aggbug/93773.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghare/" target="_blank">会飞的兔子</a> 2009-08-19 09:52 <a href="http://www.cppblog.com/flyinghare/archive/2009/08/19/93773.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>