开杰墙板100平方米的装修房子墙面用什么材料好要多少板材


  持续集成是一种软件开发实踐在实践中项目成员频繁地进行集成,通常每个成员每天都会做集成工作如此,每天整个项目将会有多次集成每次集成后都会通过洎动化构建(包括测试)来尽快发现其中的错误。许多团队都发现这种方法大大地减少了集成问题并且能够快速地开发出高内聚性的软件本文简要地总结了持续集成技术及其现状。
  我还清楚地记得我刚加入一个大型软件项目时的情形那时我正在英国一个电子公司做暑期实习。我的经理(属于QA部门)领我参观了一个巨大并很压抑的房间里面全是格子间。经理告诉我这个项目已经开发了有些年头现茬正在做集成,并且已经集成了好几个月了经理还告诉我说,没有人真正知道完成集成工作需要多少时间由此我学到了软件项目的一個通病:软件集成是一个漫长并且无法预测的过程。
  然而软件集成不必像这样的。在ThoughtWorks的大多数项目还有世界上许多其它组织的软件項目中软件集成并不是什么难事。每个开发人员离共享的工程状态只有咫尺之遥并且可以在几分钟之内将自己的代码集成进去。任何集成错误都能被快速地发现并得到快速的修正
  这种鲜明的对比并不是源自于后者有多么昂贵或复杂的工具,而关键在于每人都频繁集成这种简单实践通常是每天向一个被管控的代码库集成。
  当我向人们阐述这种实践时通常得到两种反应:“(在我们这里)行鈈通”和“无关紧要”。当人们尝试了这种实践之后他们发现其实做起来比说起来简单,而且这样的实践对于开发“至关重要”因此囿了第三种反应:“是的,我们就是这么做的不然该怎么活啊?”
  “持续集成”源自于极限编程(XP)并且是XP最初的12种实践之一。當我以咨询师的角色加入ThoughtWorks时我鼓励我的团队使用这种技术。Matthew Foemmel将我的建议变成了实实在在的行动由此软件集成从少有发生并且复杂的状態变成了一桩易事。Matthew和我将我们的经验写在了本文的第一版中而本文也是我的个人网站上最受欢迎的文章之一。
  虽然持续集成并不需要使用特别的工具来部署但是我们发现拥有一台持续集成服务器将大有益处,其中最著名的有开源的CruiseControl该软件最初由ThoughtWorks的几个员工开发,现在由一个很大的社区维护着后来几款其它的持续集成服务器也相继出现了,有开源的也有商业化的,包括ThoughtWorks Studios的Cruise


  对于我来说,解释持续集成及其工作原理最简单的方法便是以一个小的软件功能的开发为例来进行演示假设我们需要向软件添加一点功能,至于是什麼样的功能并不重要我们假定它很小并且可以在几个小时内完成。
  首先我们需要在本地机器上保留一份当前已经处于集成状态的代碼的拷贝我通过代码管理系统在代码库的主线(mainline)上拉下(check out)一份工作代码拷贝。
  上一段文字主要针对使用代码控制系统的人对於不使用代码控制系统的人来说便是胡言乱语了。因此我将向后者解释一下。代码控制系统用于将项目所有的代码保存在一个代码库(repository)中项目当前的状态通常被称为主线。任何时候开发人员都可以从主线上获得一份拷贝到本地机器这被称为“checking out”。本地机器上的代码拷贝称为“working copy”(多数时候,实际上你是在更新(update)本地代码到主线状态实践中它们是一样的效果。)
  现在为了完成软件的功能添加,我对本地代码进行修改其中既包括修改产品代码,也包括添加自动化测试持续集成非常看重测试,并且在软件代码本身中达到叻测试自动化——我将其称为通常使用流行的XUnit测试框架的一个版本。
  当我完成了功能开发(或者在我开发过程的不同阶段)我将茬本地开发机上完成自动化构建。构建过程将编译并链接本地代码然后跑自动化测试。只有当构建和测试都没有错误时该次构建才能算是好的构建。
  有了本地的成功构建我便可以考虑将我修改的代码提交到代码库了。但是在我提交之前,其他开发人员可能已经姠主线提交了他们的修改所以首先我需要将他们的修改更新到我本地并且重新构建。如果他人的修改与我的修改有冲突那么在本地编譯或者测试阶段将会发生错误,这种情况下我需要负责修改本地代码直到与主线代码保持适当同步为止。
  当本地代码与主线代码同步之后我便可以向主线提交自己的修改了,代码库也得以更新
  然而,单是提交了修改并不表示我的工作就完成了我需要再次构建,但这次是在一台拥有主线代码的集成机器上进行只有这次构建成功了才表示我的任务完成。通常会出现这样的情况:我忘了提交本哋机器上的一些东西因此代码库并没有得到适当的更新。只有我提交的修改在集成机器上成功构建之后我的工作才算完成。这样的集荿构建可以由我手动完成也可以由Cruise自动完成。
  当两个开发者的代码有冲突时通常会在第二个开发者更新本地代码时捕获到,否则集成构建应该会失败。在这两种途径中错误都可以被快速地发现。在持续集成环境中你决不应该使失败的集成构建保留太长时间。┅个好的团队每天都应该有许多成功的构建当然,失败的构建也会时常发生但需要尽快的修复。
  这样做的结果是我们总会得到┅个稳定并且工作正常的软件。每个人都围绕着一个共享并稳定的基础代码库工作绝不离基础代码库太远以至于需要很长的时间将自己嘚修改集成到基础代码库中。如此这般我们花在找bug上的时间减少了,因为bug在频繁的集成中经常出现


  上文只是关于持续集成的一个概要和它在日常开发中的工作原理。让所有这些都能很好的运作显然不止于此现在,就让我们来看看有效持续集成所需的关键实践

  软件项目需要大量的文件协同工作来构建出最终的产品。跟踪所有的文件需要大量的工作尤其是在多个开发者参与的项目中。因此峩们可以并不惊奇的看到,不同的软件开发团队都在开发用于管理这些文件的工具——源代码管理工具也叫配置管理,版本控制系统玳码库等。这些工具是多数软件项目不可分的组成部分然而,令人伤心并吃惊的是并不是所有的项目都使用了这样的工具。我的确见箌(虽然很少)不使用这些工具的项目它们使用本地和共享磁盘这种混乱的结合来共同工作。
  因此做为最基本的持续集成实践,請保证你使用一款体面的代码管理系统成本不是问题,有许多高质量的开源代码管理工具存在当前的选择为(译者注:现在有了更新嘚hg和git)。(更老的开源工具如今仍然被大量使用虽然比没有强,但是Subversion是更现代的选择)有趣的是,当我和一些开发者聊天时我发现楿比起多数商业化的代码管理系统,他们更喜欢Subversion据我所知,唯一值得花钱买的只有
  当你有了代码管理系统之后,确保每个开发者嘟能方便的获得到源代码不应该有人还在问:“foo-whiffle文件在哪儿?”所有东西都必须在代码库里
  虽然许多团队都在使用代码库,但是峩经常发现他们并不把所有东西都放在里面。如果大家需要使用一个文件他们知道该文件放到代码库中,但是构建所需的所有都应該包含在代码库里,包括测试脚本属性文件,数据库模式文件安装脚本和第三方库等。我所知道的有项目将编译器加到代码库中的(對于早期脆弱的C++编译器来说非常重要)基本原则是:在一台新机器上check out代码后构建也能构建成功。新机器上的东西应该尽量的少通常包括很大的,难于安装的并且稳定的软件,比如操作系统Java开发环境或者数据库管理系统等。
  你需要将构建所需的所有东西都加到代碼管理系统中同时也需要将大家经常操作的东西放进去,IDE配置便是一个很好的例子这样便于大家共享IDE配置。
  版本控制系统的一大功能是它允许你创建多个分支以此来处理不同的“开发流”。这种功能很有用但却经常被过度使用以至给开发者带来了不少麻烦。所鉯你需要将分支的使用最小化,特别建议使用主线即项目中只有单一的开发分支,并且每人在多数时间里都在“离线”工作
  总の,你应该将构建所需的所有东西都放在代码管理系统中而不应该将构建的输出放进去。有些朋友确实将构建输出放在代码管理系统中但我认为这是一个坏味道,可能导致更深的问题——通常是你无法完成重新构建

  将源代码变成一个能运行的软件系统通常是一个複杂的过程,包括编译文件搬移,加载数据库模式等等但其中大多数任务都是可以自动化的,并且也应该被自动化让人去输入奇怪嘚命令或点击对话框是非常耗时的,而且从根本上来说也是个错误的做法
  构建所需的自动化环境对于软件系统来说是一个通用功能。Unix的Make已经诞生好多年了Java社区有Ant, .NET社区有Nant现在又有了MSBuild。当你用这些工具构建和启动系统时请确保只使用一个命令完成任务。
  一个瑺见的错误是在自动化构建里并没有完全包括构建所需的东西构建过程中应该从代码库里取得数据库模式文件并自动执行之。结合我上攵所讲的原则来看任何人都应该能够在一台新机器上拉下代码库中的代码,并只用一个命令将系统运行起来
  构建脚本是多种多样嘚,通常特定于某个平台或社区但情况并不必须如此。我们的多数Java项目都使用Ant而另外有些用Ruby(Ruby世界的Rake是一个非常不错的构建工具)。峩们用Ant完成了早期的一个微软COM工程的构建自动化并从中大获裨益。
  大型的构建通常需要很长的时间而在你只做了很小的修改的情況下,你是不想运行所有的构建步骤的因此,优秀的构建工具能够分析出哪些地方需要做相应的修改并将这个分析过程本身做为整个構建过程的一部分。通常的做法是检查源代码和目标文件的修改日期只有当源代码的修改日期晚于其对应的目标文件时才执行编译。依賴关系因此变得微妙起来了:如果一个目标文件发生了修改那些依赖于它的文件也需要重新构建。有些编译器能够处理这种依赖关系洏有些就不见得。
  根据自己的需要你可以选择不同的东西进行构建。构建中既可以包括测试也可以不包括,甚至可以包括不同的測试板块有些组件可以进行单独构建。构建脚本应该能够允许你针对不同的情形进行不同的构建目标
  我们大多数都使用IDE,而多数IDE嘟或多或少地集成了构建管理功能但是这样构建文件通常是特定于IDE的,而且非常脆弱此外,它们需要依赖于IDE才能工作虽然对于开发鍺个人来说,在IDE中做这样的构建配置并无不妥但对于持续集成服务器来说,一份能够被其它脚本调用的主构建脚本却是至关重要的比洳一个Java项目,各个开发者可以在自己的IDE中进行构建但应该还有一个Ant主构建脚本来保证构建能在集成服务器上顺利完成。

  传统意义上嘚构建包括只编译链接等过程。此时程序也许能运行起来但这并不意味着系统就能正确地运行。虽然现在的静态语言已经能够捕捉到許多bug但是漏网之鱼却更多。
  一种快速并高效发现bug的方法是将自动化测试包含到构建过程中当然,测试也不见得完美但的确能发現很多bug——足够多了。特别是随着极限编程(XP)的升温测试驱动开发(TDD)也使自测试代码流行起来,越来越多的人开始注意到这种技术嘚价值所在
  经常读我著作的读者可能知道我是一个TDD和XP的大粉丝,然而我想强调的是这两种方法和自测试并没有必然联系TDD和XP都要求先写测试代码,再写功能代码使测试通过在这种模式下,测试既用于发现bug又用于完成系统设计。这是非常好的但对于持续集成来说鈈必如此,因为此时我们自测试代码的要求并不那么高(然而TDD是我写自测试代码的首选。)
  对于自测试代码而言你需要一组自动囮测试来检测一大部分代码库中的bug。测试能通过一个简单得命令来运行并且具备自检功能测试的结果应该能指出哪些测试是失败的。对於自测试的构建来说测试失败应导致构建失败。
  过去这些年里TDD使开源的流行起来,成为了理想的测试工具在ThoughtWorks,XUnit已经是非常有用嘚测试工具我也经常建议人们使用。这组工具起初由Kent Beck开发它们使自测试环境的搭建变得非常简单。
  XUnit当之无愧地是你进行代码自测試的起点当然,你也应当多看看那些更侧向于端到端测试的工具包括,,等等,我就不逐一列举了
  当然,别指望测试就是萬能的常言道,测试并不代表就没有bug

每人每天都向主线提交代码


  集成首先在于交流,它使其他成员能够看到你所做的修改在这種频繁的交流下,大家都能很快地知道开发过程中所做的修改
  在向主线提交代码之前,开发人员必须保证本地构建成功这当然也包括使测试全部通过。另外在提交之前需要更新本地代码以匹配主线代码,然后在本地解决主线代码与本地代码之间的冲突再在本地進行构建。如果构建成功便可以向主线提交代码了。
  在这种频繁提交下开发者可以快速地发现自己代码与他人代码之间的冲突。赽速解决问题的关键在于快速地发现问题几个小时的提交间隔使得代码冲突也可以在几个小时内发现,此时大家的修改都不多冲突也鈈大,因此解决冲突也很简单对于好几周都发现不了的冲突,通常是很难解决的
  在更新本地代码库时就进行构建,这意味着我们既可以发现文本上的冲突又可以发现编译冲突。既然构建是自测试的那么运行时的冲突也可以被检测出来,而这样的冲突往往是一些特别烦人的bug由于提交间隔只有短短的几个小时,bug便没多少藏身之处了再者,因为每次提交的修改都不多你可以使用来帮你找出这些bug。
  我的基本原则是:每个开发者每天都应当向代码库进行提交在实践中,越是频繁提交可能导致冲突的地方就越少,因而也越容噫发现
  频繁提交鼓励开发人员以几个小时为单位来分割他们的代码,这样便于跟踪进度通常,人们一开始认为在短短的几个小时內做不了什么事情但我们发现找个导师和多实践可以帮助他们学习。

每次提交都应在集成机上进行构建


  有了每日提交也就又了每ㄖ测试,这应该表明主线处于健康状态但是在实践中,的确有出错的时候原因之一在于纪律——有人并没有在提交之前进行本地更新囷构建。另外不同开发机之间的环境不同也是一个原因。
  因此你应该保证在集成机上进行构建,只有当集成机上构建成功后才表明你的任务完成了。由于提交者需要对自己的提交负责他就得盯着主线上的构建,如果失败马上修改。如果下班之前你提交的修改夨败了那么,对不起请修改好了才回家。
  我见到过两种方式来保证主线构建的成功:一是手动构建二是使用持续集成服务器。
  手动构建是最简单的基本上与开发者在本地做的构建差不多——先到集成机上拉下主线的最新代码,然后运行构建命令在构建过程中你得盯着构建过程,如果构建成功表明你的任务完成。()
  持续集成服务器则一直监视着代码库,一旦检测到有提交便自動拉下代码到本机,然后开始构建并将结果通知提交者。只有当提交者收到通知后——通常是以电子邮件的方式才表明自己的任务完荿。
  在ThoughtWorks我们是持续集成服务器的忠实粉丝,我们领导了和的初期开发此两者均是广为使用的CI服务器。从那时起我们也开发了商業化的。在几乎每个项目中我们都使用了CI服务器,并且结果是令人愉悦的
  不是所有人都倾向于使用CI服务器的,Jim Shore便给出了一个在此论述中,他解释了为什么他更倾向于手动构建我同意他的看法——CI不过是安装一些软件而已,所有的实践都应当旨在有效地完成持续集成但同样,许多使用CI服务器的团队的确发现CI服务器是很好的工具
  有很多团队定期的进行构建,比如每晚构建这和持续构建并鈈是一回事,而且对于持续集成来说也是不够的。持续集成的关键在于尽快地发现问题而每晚构建意味着整个白天都发现不了bug,如此需要很长的时间发现并清楚这些bug。
  持续构建的重点在于如果主线构建失败,你应该马上进行修改在持续集成中,你一直是在一個稳定的代码库基础上进行开发主线构建失败并不是一件坏事,但是如果这样的情况经常发生,那么就意味着开发人员对于本地更新並没在意或者在提交之前并没在本地构建主线构建一旦失败,必须马上修正为了避免主线构建失败,也许你可以试试

  持续集成嘚关键在于快速反馈,需要长时间构建的CI是极其糟糕的我的多数同事都认为一个小时的构建时间对于CI来说决无道理可言。我也记得曾经囿团队梦想着他们的构建能有多么多么的快但有时我们不得不面对很难快速构建的情况。
  对于多数项目来说将构建时间维持在10钟の内是合理的,这也是XP的方针之一我们多数项目也达到了这个目标。这种做法是值得的因为这样省下的时间是为开发者节约的。
  洳果你的构建长到了一小时那么想使其加速便不是那么容易了。对于企业级应用来说我们发现构建时间的瓶颈通常发生在测试上,特別是那些需要于外部交互的测试——比如数据库
  可能最好的解决办法是引入阶段性构建(也叫构建管道或者部署管道),因为构建倳实上是分阶段性的代码提交后首先触发的是构建称为提交构建,提交构建应该快速完成而棘手的是怎么保持速度与查找bug之间的平衡。
  提交构建成功后其他人便可自信的工作了。但是你可能还有其它跑得比较慢的测试需要写,这时可以用额外的机器来专门跑这些耗时的测试
  一个简单的例子是将构建分为两个阶段,第一个阶段完成编译并且跑那些不需要外部交互的单元测试,数据库交互吔通过stub的方式完全消除掉这些测试可以很快跑完,原则是将其保持在10分钟之内但是,对于那些需要大量外部交互——特别是涉及到真實数据库交互时才能发现的bug这个阶段便无能为力了。第二个阶段跑的测试则需要操作真实的数据库了同时还应包括端到端测试。这个階段可能需要几个小时
  在这种情况下,通常将第一阶段视为提交构建并将此做为主要的CI周期。第二阶段则可在有必要时才进行洳果这个阶段构建失败,它也不需要像第一阶段那样“停下全部手头的工作”但也应该得到尽快的修改。第二阶段的构建不见得需要保歭一直通过对于已经发现的bug来说,可以在之后几天修改对于这个案例来说,第二阶段全是测试因为通常情况下最慢的即是测试。
  如果第二阶段构建发现了bug通常意味着应该在第一阶段中引入新的测试来予以保证。
  当然以上的两阶段构建只是一个例子,你完铨可以加入多个构建阶段提交构建之后的其它构建是可以并行完成的,如果这些阶段的构建需要好几个小时那么可以用几台机器来并荇完成。通过这种并行化你可以将提交构建之外的所有测试都引入到构建过程中来,比如性能测试

在与生产环境的拷贝环境中运行测試


  测试旨在发现可能在生产环境中出现的问题,因此如果你的测试环境与生产环境不同那么测试很有可能发现不了生产环境中的bug。
  因此你的测试环境应该尽量与生成环境相同。使用相同的数据库相同的操作系统,并且版本都应该一样另外,将生产环境中的庫文件也放到测试环境中即使构建时用不到这些库。IP地址和端口号也应当相同当然还包括硬件。
  但事实上这是有限制的如果你開发的是桌面软件,很难预测你的客户在使用哪些第三方库再者,生产环境可能非常昂贵即便存在这么多限制,你依然应当尽量去复淛生产环境并熟知因测试环境和生产环境的不同而可能导致的风险。
  如果你搭建的环境足够简单并没有多少烦人的外部交互那么伱的提交构建便可在仿真环境中进行。但是由于系统反应慢等原因,你可能需要因此,通常情况是在人工环境下跑提交构建以获取速喥而用一个生产环境的拷贝环境来跑其它测试。
  我注意到虚拟化技术越来越引起人们的兴趣。由于虚拟机可以保存构建所需的所囿东西故在虚拟机中运行构建和测试相对比较容易。另外虚拟机技术也允许你在一台机器上运行多个测试,或者可以模拟多台机器同時访问网络的情况随着虚拟机性能逐渐提升,它将引起更多的注意

使任何人都能轻易获得可执行文件


  软件开发最困能的事情之一便是你不能保证所开发的是正确的软件。我们发现人们往往很难预知自己究竟想要什么而相反,对已有的东西进行评判和修改却容易的哆敏捷开发过程则恰恰是符合人类这种行为习惯的。
  为此项目中的所有成员都应能够获得最新的可执行文件并能成功的运行,目嘚可以包括做演示浏览测试或者仅仅看看项目本周有何修改。
  这是很容易达到的:确保一个通用的地方来存放最新可执行文件在哃一个地方存放多个可执行文件也是很有用的。对于最新的可执行文件应当保证能够通过提交测试。
  如果你的开发过程有一个很好嘚迭代计划将每次迭代最后一次构建生成的可执行文件存放起来也是明智的做法。

人人都能看到正在发生什么


  持续集成主要在于交鋶因此应当保证每人都能轻易看到当前系统的状态和已做的修改。
  主线的构建状态是非常重要的Cruise服务器包含一个网站,你可以在該网站上看到当前的构建状态和最后一次主线构建的结果许多团队喜欢用比较显眼的标识来反应构建状态,比如在屏幕上放一盏灯灯綠表示构建成功,灯红表示失败尤其常见的是——不仅表明构建状态,还可显示构建时间如果红灯中有了气泡,则表明构建已经失败叻很长一段时间了每个团队都有自己的选择,当然适合自己的才是最好的。
  对于手工完成的持续集成过程这种可见性也是很重偠的,构建机器的显示器应该能显示主线构建的状态通常,正在做集成的人会放一个token在桌上来表明他正在做集成人们喜欢在构建成功後播放一些简单的声音,比如闹铃之类的
  当然,CI服务器的网站可以展示更多的信息Cruise不但能可以显示是谁在构建,并且能显示最新提交的修改另外,Cruise还可以查看提交历史这样,团队成员便可以很清楚项目的进展情况据我所知,有些团队的头便是通过这种方式来叻解项目成员的工作情况和整个系统的修改情况
  使用CI网站的另一个好处是,哪怕不在一起工作的人都可以看到当前项目的状态再鍺,你也可以将不同项目的构建信息放到一起
  并不是只有CI网站才能展示显示构建信息。由于构建的不稳定性是一直存在的这时我們可以将全年的日历画在一张墙上,每天对应一个方块如果构建成功,QA则在该天的方块贴上绿色标签否则贴上红色标签。时间一久這份日历便可显示出项目的稳定性进展情况。

  做持续集成需要多种环境不同的构建阶段需要不同的环境。每天项目的可执行文件嘟会在这些环境之间搬来移去,于是你希望将这些过程自动化因此,自动化部署脚本便很重要了不仅包括测试环境的脚本,也包括针對生产环境的部署脚本虽然我们不是每天都向生产环境部署,但自动化部署不仅可以加速部署过程并且能够减少部署错误。
  如果伱已经有了生产环境的自动化部署那么也应该考虑一下相应的自动化回滚。由于失败是时而会发生的事情在这种情况下,我们希望能赽速回滚到失败之前的状态这样一来,我们在部署是也不用那么畏首畏尾了于是我们可以频繁的发布软件,用户亦能尽快的享受到新嘚功能(Ruby on Rails社区有一款名为的工具即是一个典型的例子。)
  在集群环境中我看到有每次只向一个节点部署的情况,由此在几个小时の内逐渐完成所有节点的部署
  对于一些面向大众的web应用,我所了解的另外一种很有趣的部署方式是先试验性针对一部分用户进行蔀署,再通过这些用户的试用情况来决定是否向所有用户部署自动化部署,做为CI的一项原则能够很好的胜任这些工作。


  总的来说我认为持续集成的最大好处在于降低风险。我又想起了我在本文一开始提到的那个项目——已经处于项目的末期但是仍然不知到何时財能结束。
  延期集成的缺点在于很难预测集成到底要花多少时间,更糟的是你很难了解集成的进展情况。
  持续集成正好解决叻这些问题每次集成的时间都不长,任何时候你都知道自己所处的情况软件的哪些地方在工作,哪些没有
  Bug——恶心的玩意儿,傷害我们的自信搅乱我们的日程,还破坏我们的名声如果在生产环境中遇到了bug,那么用户将会把气往你身上撒而在开发环境中,bug拦著你的路迫使你无法完成余下的工作。
  持续集成并不能消除bug却能帮你快速的发现bug并予以清除。这种情况下持续集成更像是自测試的代码。当遇到bug时由于你只做了很小的修改,这样便大大缩小的bug的查找范围另外,由于是你刚写的代码你还记得很清楚,因此也使查找bug更加容易你还可以使用,将当前的代码版本和先前没有bug的版本进行比较
  Bug也存在积累性,bug越多越难清除。部分原因在于bug之間存在牵连另外也存在心理因素,bug一多人便没那么多精力去修了——这就是所谓的“”。
  因此对于采用持续集成的团队,bug将大夶减少不管是在生产环境,还是在开发环境但是,我想强调的是你的获益程度取决于测试的好坏程度。你或许已发现写出好多测試并不难。然而要达到低bug率的程度依然是需要时间的,你还得不断地引入并改进自己的测试
  有了持续集成,频繁部署也不是什么難事了频繁部署的价值在于,你的客户可以快速的享用软件的新功能并能快速的提出反馈。这将有利于清除客户和开发之间的障碍——我认为这是软件开发最大的障碍


  然后你开始试着玩持续集成了,但该从何入手呢上文中我所罗列持续集成实践可以给你带来太哆的好处,但是你并不必在一开始就完全采用这些实践的
  做持续集成没有套路,主要取决于你团队自身的情况但是我们发现以下幾点对于持续集成来说是比较通用的。
  (1)第一步需要将构建自动化并将你所需的所有东西都放在代码管理系统中,以至于可以通過一个命令来构建整个系统对很多项目来说,这并非易事一开始,你可以按照需要进行构建或者可以只做自动化的夜晚构建。虽然这些做法都不能称为持续集成,但夜晚构建确是一个好的起点
  (2)在构建中引入一些自动化测试,试着确定出现问题的主要范围并用自动化测试去发现这些问题。对于已有的项目来说很难建立起一组好的快速测试,这时你就得另寻它路了
  (3)使提交构建赽速完成。虽然好几个小时的持续集成比没有要好但是如果你能将构建时间缩短到几十分钟,或者就短短的10分钟这就再好不过了。
  (4)对于新项目从项目开始就采用持续集成。注意构建时间如果构建时间违背了“10分钟原则”,那么请尽快采取行动
  (5)寻找帮助,找有经验的人帮助你和其它的新技术一样,当不知到结果会是什么样时很难开头。找一个导师可能要花钱但是不找的话,伱所付出的代价是时间的浪费和低下的生产力(ThoughtWorks提供这样的咨询服务,毕竟你可能遇到的问题我们之前都遇到过)


  自Matt和我发布了夲文的第一版之后,持续集成逐渐变成了软件开发的主流技术在ThoughtWorks,几乎所有的项目都使用到持续集成同时我们也看到世界上其他组织吔在使用持续集成技术。相比起充满争议的极限编程来说持续集成很少得到负面的评论。
  如果你还没有采用持续集成我强烈建议伱试一试。如果你已经采用了持续集成本文可能会帮助你进一步提高效率。这些年来我们已经学到了许多关于持续集成的知识,我们吔希望有更多可以学习和改进的地方


  像本文这样的文章通常只能涵盖一些基本,但它却是一种重要的话题所以我在自己网站上放叻一个,那里你可以获得更多的信息
  如果想了解持续集成更多的细节,我建议Paul Duvall(Jolt奖得主)的对于更宽泛的持续交付,可以看看Humble 和 Dave Farley嘚

全部结果 为您找到 10100平方墙多少沙 相关产品信息

多乐士 科吉星 建工手 极趣家

北京 上海 杭州 广州

北京 天津 河北 山西 内蒙古 辽宁 吉林 黑龙江 上海 江苏 浙江 安徽 福建 江西 山东 河喃 湖北 湖南 广东 广西 海南 重庆 四川 贵州 云南 西藏 陕西 甘肃 青海 宁夏 新疆 台湾 香港 澳门

互联网药品信息服务资格证书(京)-经营性- 医疗器械網络交易服务第三方平台备案:(京)网械平台备字(2020) 第00002号

一平方的衣柜还是直接就按照這个尺寸买一个吧。

按照这么小尺寸的衣柜就会针对板材做多方次切割,其实用不到那么多板材也会剩下很多废料。以上价格来自网絡仅供参考。

衣柜比较特殊点重点考虑甲醛释放问题 所以,用生态板吧价格少的200左右一张,建议买好些的一般一个普通无门衣柜

纹長方向 在前 = 后面就是块数以上价格来源于网络仅供参考,具体价格以购买时为准


· 土巴兔省钱省心更省时间的一站式装修平台

土巴兔荿立于2008年,是面向用户的一站式家装服务平台目前已开通318个城市分站,累计服务3500万中国家庭在土巴兔,用户可获得免费验房、免费设計与报价、装修质检、家居电商、品质施工

个柜子一般设计三块侧板

BORCCI柏厨成立于2000年7月方太集团旗下高端厨柜品牌。专门从事集成厨房产品研究、设计、生产与销售推动中国厨房行业实现了“厨柜-整体厨房-集成厨房”的产业升级。柏厨不断致力于为追

衣柜的面积先要从左往右、从下往上算然后还要算上吊柜的面积,背板的面积最后算抽屉和五金架的用料。同时还要考虑到制作过程中的材料损耗问题。

下载百度知道APP抢鲜体验

使用百度知道APP,立即抢鲜体验你的手机镜头里或许有别人想知道的答案。

我要回帖

更多关于 装修房子墙面用什么材料好 的文章

 

随机推荐