持续交付,意味着从项目第一天开始,即使不是所有功能特性都已经实现,软件产品就已经准备好作为产品交付,并可以按照用户的要求发布给他们。《持续交付》书籍作者Jez Humble和David Farley讨论了这个概念,包括在组织内流程、人和工具这三个领域中的最佳实践,从而实现软件开发过程中各个部分自动化的过程。

\

他们谈到组织中交付软件遇到的问题:手工部署软件、只在开发完成后才部署产品环境(而不是更频繁地部署)、手工配置环境。要解决这些问题,作者阐述了配置管理和持续集成领域的最佳实践,包括使用版本控制系统不仅管理代码,还要管理其他产出物,比如软件配置和环境细节。

\

书中对部署管道(deployment pipeline)的讨论,聚焦在项目的构建和部署阶段实践,以及为了得到软件交付过程反馈而使用的度量手段。Jez和David在书里谈到的议题还包括实施测试战略,以及如何测试非功能性需求。

\

本书是2011年Jolt图书大奖的获奖者。InfoQ就持续交付的概念与两位作者进行了沟通,还谈到如何用该概念自动化软件产品交付过程,从而更高效地完成工作。

\

InfoQ:能否请你们说明下“持续交付”的概念?以及它与“持续集成”或传统的“QA(测试)”实践的区别?

\

Jez Humble:持续交付,意味着从项目第一天开始,即使不是所有功能特性都已经实现,你就已经让软件准备好作为产品交付,按照用户的要求,只要按一个按钮就可以发布给他们。支持这个概念的有多个实践和模式,但是在所有层面上良好的配置管理、持续集成和全面的自动化测试构成了基础。部署管道是关键模式,是从持续集成到产品阶段的有效扩展,借助该模式,每次代码签入都会生成一个候选发布,并会使用一系列自动化和手工测试来评估该候选发布是否适合发布到产品中。为了在每次构建时完成这些验证过程,你的回归测试,包括单元测试和验收测试层面,都必须实现自动化。所有的自动化测试验证通过后,人就可以执行探索测试、易用性测试以及展示等工作。只要有人授权,构建版本就可以按照测试、部署准备和产品环境完成自动化部署。

\

使用这些实践,团队能够快速知道交付的软件是否可用(这是诸如精益初创企业[Lean Startup]这样的方法论所要求的),并降低发布风险,达成软件交付更可靠、更易于预测的过程。

\

David Farley:从根本上来说,持续交付是要建立起开发各个方面尽可能最短的反馈循环。当软件交付给用户时,我们想要尽早知道哪些需求有效,因此我们需要尽早、尽快交付。如果某个改变破坏了某个现有功能,我们想要得到反馈,因此我们需要有出色的自动化测试,来指明这些回归测试遇到的问题。当软件可以成功部署到生产环境,我们想要得到反馈,这样我们就需要在真正进行部署前练习部署机制。

\

只要人们可以理解这个根本上的需要,所有的技术、技巧和实践只不过是关于如何尽可能更快、更清晰地传递这些反馈。

\

InfoQ:什么类型的组织文化,或者说什么级别的流程成熟度是使用持续交付实践的最佳环境?

\

Jez Humble:所有人都愿意参与交付工作,这样的文化是持续交付的核心。开发人员、测试人员、基础设施管理员、DBA、管理人员、客户,大家的协作贯穿整个生命周期。它还依赖某种程度上的交付过程自动化成熟度:构建、测试、部署、基础设施和数据库管理。在适用性上不受什么限制。不管你是开发嵌入式系统、产品或是基于web的系统,这些技术都有价值。然而,要想得到快速、可靠的软件发布过程,你必须付出一定的成本,所以持续交付应该仅仅用在战略性的软件项目上,在这些项目中,快速反馈、可预测且低风险的发布很有商业价值。

\

Dave Farley:当我还是咨询师的时候,我总觉得:在不习惯持续集成的组织中把它建立起来,这就像是敏捷实践中的滩头攻防战。持续集成是第一个、明显也是最有价值的实践,它可以带动其他各个地方的良好行为。持续交付(简称CD)更进一步。要想CD发挥作用,需要高水平的纪律,以及对质量、交付和某种程度上的效率的全面关注。这对很多组织都是挑战,因为它常常意味着组织做事方式的剧烈改变,而且范围上不仅限于开发团队。它波及到需求优先级的排定方法,以及它们如何导入开发过程,如何执行测试,如何完成发布。在我看来,对于从软件生产过程一开始就加入其中的所有角色,CD都有正面影响。任何组织都能尝试一下,并从中获益,但要想获得所有的好处,确实需要非常全面的承诺。我坚信:经过一段时间,这些技术能够产生非常重大的回报,当然也需要投入。我的直觉是:CD适合任何在3到6个月的阶段内会发生改变的软件。如果软件在完成后就落上灰尘,在3个月内再也没有任何变化,那也许就不需要CD。

\

InfoQ:书中提到的持续交付实践,能否用在使用传统瀑布式开发方法论的软件开发环境中?

\

Jez Humble:当然可以,没有问题。我们讨论的技术都是工程实践,很多时候不依赖你的项目管理过程。即使使用瀑布式,自动化和协作也同样重要,而且它们能够对软件的质量和交付过程的可预测性产生巨大影响。

\

Dave Farley:我同意Jez,使用CD的瀑布式项目会比不用它的项目更好。不过,有时候估算CD的成本会很困难,这让日程安排变得不好办。CD过程的一部分建立在失败的基础之上,它需要及时而有效地了解软件的状态,需要全力投入来达成这个目标。如果你的自动化测试指出代码中的某个问题,那么你就需要做出反应,修复问题。同样地,如果你的自动化测试指出反馈周期的问题,典型的问题是测试运行速度过慢,你也需要对其做出反应。因此,任何过程使用CD,当问题出现时,都得具备对问题响应并尽快修复的灵活能力。

\

不过呢,我还是要说:尽管我相信CD实践对任何软件开发方法有效果,它还是跟敏捷开发实践配合度最高,而且这些实践能将CD的正面效应最大化。

\

InfoQ:软件质量测试和验证过程常常包括自动化测试(通过代码扫描)、手工功能测试和手工代码复查。这些不同的质量验证方法要如何组合才能达到最好的效果?

\

Jez Humble:Brian Marick创建了一个测试象限,将软件开发中不可或缺的不同形式的测试做了分类,这些测试都是必不可少的。开发人员应该使用测试驱动开发,以确保他们交付的代码质量足够高。开发人员和测试人员应该一起工作,创建自动化功能测试套件作为开发过程的一部分,确保软件能够满足需求。测试人员应该执行探索性测试和易用性测试。从项目早期开始,各个团队应该一起测试跨功能的需求,比如安全、可用性、性能,并尽可能自动化。

\

戴明博士有一句关于软件开发的话我非常喜欢,他说:“不要依赖大量检查满足质量要求,从一开始就要改善流程,并将质量融入到产品中。”这就意味着:测试阶段不应在开发完成之后执行,应该贯穿于整个交付过程中,需要所有人参与,并使用诸如行为驱动开发和验收测试驱动开发这样的技术。它还意味着质量不只是测试人员的责任,整个团队都要对质量负责。测试人员对于创建高质量软件很重要,但是他们的工作是确保系统的质量对大家透明,而不是对质量负责。

\

Dave Farley:Jez说的一针见血,质量是所有人的责任。CD的一个主要好处,就是能让软件项目相关的所有人都能看到项目的状态,这样任何人都能对某些看起来不太对的东西做出反应。人们不善于处理复杂而且重复的任务。使用任何人工形式的回归测试都不合适。计算机很善于做这件事,所以,所有的回归测试、功能测试、性能测试,等等等等,所有这些重复的动作,确确实实都应该自动化。

\

人很善于匹配模式。人们应该探索系统,指出“看起来不太对劲儿”的东西,他们应该担心易用性,并找出关于哪里可能有问题的细微的线索。在我的项目中,我在所有的质量评审中都会使用这个区别,我们自动化所有重复的工作,不管是测试、构建、部署还是其他什么工作。我们鼓励所有人都能利用自己的直觉和理性来指出任何来源的问题,不管是源代码、构建问题、版本发布问题、性能问题、代码质量问题,任何问题。CD的一个重要原则就是高度关注持续改进。

\

InfoQ:对于地理分散的团队来说,有哪些版本控制和发布管理方面的最佳实践?

\

Jez Humble:首先,系统中任何需要构建、测试和部署的东西都应该放在版本控制系统中。接入新的工作机器,从版本控制系统中签出所有需要构建、测试和部署的东西到任何你有权限的环境中,这些工作应该都可以完成。向测试环境部署软件应该只需按一个按钮。这对分布团队来说更为重要,否则,你就要浪费时间,找出为什么在他们的机器上没有问题的东西,在别的地方别人的机器上不能正常运行。

\

还有一点也很重要:每个人每天都要向主干签入代码,确保所有人都在系统真实的单一代码来源的基础上工作。在分布式环境中,因为网络连接效果不好,使用分布式版本控制系统,比如Git和Mercurial,能够让工作变得简单很多,这你就不必依赖于等待另一个大洲的集中版本控制系统来分享你的工作。相反,你每天都可以在本地签入多次,并以更低的频率将更新推送到指定的外部中央代码库中(但每天至少还是要做一次)。

\

Dave Farley:在CD中,每次提交都被看作发布待选。这意味着它必须可以跟其他东西一起工作,并可以发布,被用户使用。我们从不提交将来有意修复的变更。这意味着为了评估任何一次提交,我们必须能将其与其他变更一起评估。理想状况下,所有的提交都会在HEAD中发生,这是应用系统状态的单一权威表示,这样如果我们的变更造成问题,我们就能以最快速度得到反馈。分布式版本控制系统很好,我也是其粉丝,但是它们有些常用模式与CD截然相反。我的首要原则是:如果没有做到至少每天一次将变更合并到HEAD中,你就没有做持续集成,当使用CD过程的时候,就会付出高昂成本。

\

InfoQ:在一个组织中,如果开发团队希望将架构实践集成在软件开发过程中,而又不想太过影响项目的截止时间,同时还希望创建出对特定项目有帮助的软件组件和服务,(长期来说)这些组件和服务还要能在多个项目中重用,他们应该怎么做?

\

Jez Humble:Wow,这可是个大问题!不少书籍都针对这个话题。我觉得短时间我很难说清楚。要说的是:首先你必须集中精力创造出一个可用的产品。可重用很重要,但是它要服从于创建出可用的软件。从现有系统中找出相似性,这是创建框架和组件最好的方法。不过,如何搭建软件的结构至关重要。使用封装、低耦合等技术创建模块化软件,Bob Martin大叔提出的SOLID模式是创建可维护系统的重要方法。

\

Dave Farley:这个问题算是问到我心坎儿上了,但是这么大的话题,一时半会儿也说不清楚。可以先说点儿简单的,在我现在的项目里,我们有很多测试,验证架构上的一致性(比如,如果你想直接从web服务器访问数据库,构建就会失败)。测试要远比此更为全面,但是能给人以方向感。

\

从更宽泛的角度来说,我认为好的设计与开发过程是正交的。我坚信:好的设计是迭代的过程,好的软件会随时间演化。这就是说:我认为敏捷、迭代的开发过程让创建好的设计更容易,但是任何开发过程都能写出糟糕的软件。唯一的银弹,是有才能的人。

\

虽说如此,我认为好的设计还是有一些共通之处。持续关注质量和效率,好软件做的事情很简单,如果某件事看起来很复杂,那可能就错了。

\

建模——好软件有形貌(shape),其中有各种抽象,允许对于正在发生的事情有简要描述。

\

自动化测试——你可以开发出经过完全测试的恶劣软件,你也可以开发出没有自动化测试的好软件,但是这真得很难。我认为:开发出好软件已经很难了,不要再忽略测试,让它变得更难。

\

InfoQ:另一个架构相关的问题。要想审查、验证软件的构建,以确保它符合架构和设计标准,什么时间合适?

\

Jez Humble:什么时间都合适。结对编程——特别是让资深开发人员常常跟新进开发人员一起结对来指导他们——还有资深开发人员带领的定期代码复查,这些都是确保及早发现问题的绝佳方式。不过,给交付过程把门儿,在每次签入合并前都做复查,这样的做法我不推荐。实际上,资深开发人员应该通过feed来监控签入内容,然后在必要时通过结对帮助人们重构。

\

Dave Farley:所有的时候。每次提交都应该验证某种程度上的架构一致性,不过要做的更宽泛。对于我参与开发的软件,我喜欢维护我的“白板模型”。这是一个图表,展示出重要的抽象。它意义重大,应该可以在足够高的抽象程度上提供对于系统的共同理解,任何相对资深的团队成员都可以根据记忆在白板上把它重现出来,它不应涉及太多细节。新的需求应该可以根据白板模型评估,看看它们是否符合,以及是否需要模型做出变化。如果模型需要变化,我们就会召集团队,共同讨论变化。

\

InfoQ:大多数组织需要遵从某些规定或是内部审计要求。把安全策略和合规性与软件开发过程整合起来,在这方面你们觉得怎样做最好?

\

Jez Humble:合规性有两个重要的领域。首先是交付过程本身。你要确定错误或是后门不会溜到系统里面去,而且你的软件交付过程是可审计的。这些问题的最佳解决方案是全面的配置管理,将构建、测试、部署和发布过程自动化,并与所有加入交付的人紧密协作。结对编程和定期复查,是检查和平衡进入代码库的内容的绝佳方式。其次,你要确认软件服从安全等方面的需求,还要有能力审计系统内的数据。这些是通过自动化验证过程-测试来保证的,每个发布版本待选都会通过部署管道运行测试。部署管道提供端到端的可跟踪性,能够跟踪交付过程中所有的信息,并确保每个发布版本待选都运行了必要的验证。

\

在这个月马上要出版的Cutter IT Journal杂志上,我发表了一篇文章,详细讨论了一些细节。

\

Dave Farley:目前我在金融行业中工作,所以对于合规性问题并不陌生。我最近的经验是:没有比持续交付更好的流程能够达成合规性。

\

给像审计人员或是合规性专家解释起来可能很困难,原因仅在于这对他们是新鲜事物。完整的CD系统能够提供的可跟踪性一应俱全。在我的组织里,我们有完整的自动化审核痕迹,这是我们采用的技术带来的免费副产品。我们的需求系统记录了需求创建时间、开发开始时间和完成时间,还有谁参与了各个步骤。这与我们的版本控制系统相关联,展示出哪些变更与该需求相关。我们的部署系统使用版本号与版本控制系统相关联,并可审核谁同意了将某个版本的软件发布到特定的环境中。我们几乎可以回答任何功能特性的生命周期相关的问题,并展示出完整的变更审计痕迹。我前面说过,这是副作用,得到这种水平的可跟踪性,我们没有做任何额外的工作,它作为全面版本控制的某种“美德”免费出现。

\

我所遇到的审计人员都喜欢这样的东西。

\

InfoQ:最近,很多人非常关注开发人员(Dev)和运维人员(Ops)之间的协作,他们会把与部署和软件交付任务相关的开发和测试任务集成起来。你们能否谈谈这个领域内的最佳实践和指南?

\

Jez Humble:再次说明,在即将出版的Cutter IT Journal杂志的那篇文章里有更多细节。不过根本上说,要确保开发人员、测试人员和运维人员在整个交付过程中一起协作。也就是说,所有这些人在项目初期、展示和回顾阶段都要出现。然而,大多数组织中,开发人员根据产出衡量,运维人员根据成产系统的稳定性衡量。这造成了很大的障碍。开发人员应该负责他们创建的代码的稳定性,要鼓励这一点,可以让他们戴上传呼机,每当生产系统出现问题时,他们都得去帮助解决问题。运维人员也必须要为产出负责,要让他们确保开发人员能够以自服务方式,使用与生产环境类似的环境来测试,从而让软件可以自动化发布,而且不出现问题。说到底,这对大家都有好处。

\

Dave Farley:交付应该是每个人的责任。整个团队应该重点关注向用户成功交付高质量软件,提供发布生命周期良好的可见性是其中的一个重要部分。此外,确保造成问题的人负责解决问题,这对于建立高效反馈循环非常重要。

\

InfoQ:如果把软件部署在云上而不是内部托管,持续交付过程和实践会有哪些区别?使用云来做持续交付有哪些优缺点?

\

Jez Humble:持续交付与系统的部署平台是正交的。不管是发布嵌入式系统、基于云的解决方案,还是在某个大型机上的东西,技术都是同样可用的。这会依赖于软件的跨功能需求。

\

Dave Farley:没有什么实质性区别。托管系统的虚拟化是云计算的内在本质,技术角度看,这会让持续交付变得更容易,从卸载到重新布置软件的正确部署环境都是如此。但这是我看到的唯一区别,流程和相关方式都是一样的。

\

InfoQ:为了总结本次采访,从流程、人和工具的角度,你们如何评价这三个元素对于成功的持续交付的重要性?是否有某个元素比其他二者更重要?

\

Jez Humble:你需要三者全部到位,才能成功。不过我认为:最重要的还是要关注人。很多IT中的问题都会归结到人的问题上。从根本上,持续交付需要软件开发人员的纪律性,需要团队为了改进调整环境的能力。没有这些,你无法一直交付有价值的、高质量的软件。工具和过程很重要,但是他们是必要条件,不是充分条件。关于持续集成,我最喜欢的文章是James Shore的《持续集成一天一美元》,他在其中展示了如何使用一台老式开发电脑、一只橡皮小鸡和一个铃铛来完成持续集成。持续集成是实践,不是工具。在你的特性分支代码上运行Jenkins,这并不意味着你就在做持续集成。

\

不过,很多时候人们喜欢从工具开始,因为这样很容易而且具体,使用某种工具也要比改变人们的行为更容易。工具能起到很重要的推动作用,我会推荐人们在实践中使用持续集成工具,但是它们不是是否成功的决定性因素。

\

Dave Farley:基本上我同意Jez,要想把事情做正确,所有的元素都很重要。进一步说,我会说工具是最不重要的因素,但只是因为如果你有优秀人才和高效的流程,他们会创建出他们需要的工具(其实没有那么难)。CD的重要之处在于:它不跟特定的产品、工具和技术相关,一般来说,它是对技术的有效使用,以支持流程发挥推动作用。

\

根本上说,在理想状况下,我认为软件开发应该基于探索和度量的过程,我想这是比较科学的角度。持续集成有效,我认为是因为它采取探索式的方式,提供了真实的、有价值的流程输出度量,并将这些结果返回到流程中。

\

InfoQ:感谢二位花时间参与本次采访!

\

关于作者:

\

Jez Humble是ThoughtWorks的首席咨询师,也是《持续交付》一书的作者之一。从11岁得到他的第一台ZX Spectrum开始,他就痴迷于计算机和电子器件,并用多年时间使用6502、ARM汇编语言和BASIC探索Acorn机器,直到他的年龄足以找到一份工作。他在2000年加入IT行业,及时赶上了互联网泡沫。从那时起,他的工作职责涵盖开发人员、系统管理员、培训师、咨询师、经理和演讲者,用过多种平台和技术,咨询工作涵盖非盈利机构、电信企业、金融服务和在线零售公司。从2004年开始,他进入ThoughtWorks,并在北京、班加罗尔、伦敦和旧金山的ThoughtWorks Studio工作。他拥有牛津大学的物理和哲学学士学位,以及伦敦大学亚非学院的民族音乐学音乐硕士学位。现在他和妻子、女儿居住在旧金山。

\

Dave Farley 享受电脑带来的乐趣已经有30年了。这段时间里,他接触过大多数类型的软件,包括固件、修补操作系统和设备驱动、编写游戏,以及各种类型和规模的商用应用。他从20年前就开始处理大型分布式系统,研究低耦合、基于消息的系统,这是SOA的前身。他带领团队开发复杂软件的经验非常广泛,规模大小都有,地域跨越英美。Dave是敏捷开发技术的早期使用者,从二十世纪90年代起,就在商业项目中使用迭代开发、持续集成和多层面的自动化测试。在ThoughtWorks工作的4年半时间里,他作为公司遇到的某些最大、最富有挑战性的项目的技术负责人,磨炼了自己的敏捷开发能力。Dave目前为London Multi-Asset Exchange(LMAX)工作,该组织搭建了世界上性能最高的金融交易系统,这个系统依赖于书中提到的所有重要技术。

\

英文原文链接:Interview and Book Review: Continuous Delivery

\


给InfoQ中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家加入到InfoQ中文站用户讨论组中与我们的编辑和其他读者朋友交流。

《持续交付》书评与访谈相关推荐

  1. 访谈Stuart Davidson:Skyscanner的持续交付推广

    \ 看新闻很累?看技术新闻更累?试试下载InfoQ手机客户端,每天上下班路上听新闻,有趣还有料! \ \\ Stuart Davidson是Skyscanner的一名工程管理者,他在QConLondo ...

  2. 关于《在Windows与.NET平台上的持续交付实践》的问答录

    <在Windows与.NET平台上的持续交付实践>(Continuous Delivery with Windows and .Net)(免费下载)是由Matthew Skelton与Ch ...

  3. docker和java容器_使用Docker容器和Java EE进行持续交付

    docker和java容器 组织需要一种使应用程序交付快速,可预测和安全的方法,而诸如docker之类的容器所提供的敏捷性则可以帮助开发人员实现这一目标. 对于Java EE应用程序,这可以在容器中打 ...

  4. 使用Docker容器和Java EE进行持续交付

    组织需要一种使应用程序交付快速,可预测和安全的方法,而诸如docker之类的容器所提供的敏捷性则可以帮助开发人员实现这一目标. 对于Java EE应用程序,这可以在容器中打包应用程序,应用程序服务器和 ...

  5. Atlassian是怎样进行持续交付的?且听 Steve Smith一一道来

    在Devoxx UK 2015大会上的一场演讲中,Steve Smith为听众展示了Atlassian是如何进行持续交付的.会后,InfoQ有幸与Steve进行了一次访谈,深入地探讨了演讲内容的更多细 ...

  6. 乔梁:“持续交付”不是守业者的游戏

    非商业转载请注明作译者.出处,并保留本文的原始链接:http://www.ituring.com.cn/article/207218 乔梁,腾讯高级管理顾问,负责指导IEG .MIG和SNG团队提高组 ...

  7. 学python多久能上线部署网站_从开发到上线,实战持续交付

    「开发者最佳实践日」是由七牛云存储发起并联合各方小伙伴为开发者举办的系列技术沙龙,关注开发者在实际应用中可能遇到的技术问题.致力于为勇于创新的开发者们提供行业内最前沿最热门的技术干货,以技术驱动应用创 ...

  8. Android架构篇-5 CI/CD(持续集成、持续交付、持续部署)

    Android架构篇-5 CI/CD(持续集成.持续交付.持续部署) CI CI是指持续集成,代码的更新会定期自动构建.测试并合并到公共仓库中,方便多分支时解决冲突问题 CD CD是指持续交付和/或持 ...

  9. iOS架构篇-5 CI/CD(持续集成、持续交付、持续部署)

    iOS架构篇-5 CI/CD(持续集成.持续交付.持续部署) CI CI是指持续集成,代码的更新会定期自动构建.测试并合并到公共仓库中,方便多分支时解决冲突问题 CD CD是指持续交付和/或持续部署, ...

  10. DevOps与持续交付实践

    Danilo Sato表示:DevOps是旨在打破开发团队与运维团队之间的壁垒的一次尝试,这两者对于成功的软件交付来说都是必不可少的.他的新作<实战DevOps:可靠的自动化软件交付>(D ...

最新文章

  1. 一文详解CMakeLists文件编写语法规则详解
  2. flinksql获取系统当前时间搓_FlinkSQL 动态加载 UDF 实现思路
  3. 怎么测试本地网页在不同分辨率下电脑显示效果_汇总一波百万高清壁纸站,8K分辨率的都有...
  4. hibernate 多表查询
  5. [译]Chipmunk教程 - 5 跟踪球体的运动
  6. Hibernate读书笔记-----事件机制
  7. Android在线电影播放器案例
  8. tomcat Failed creating java C:\Program Files\Java\jre6\bin\client\jvm.dll %1 不是有效的 Win32 应用程序。...
  9. mysql数据库文件查找网站后台密码_怎么查看数据库的密码?
  10. AttributeError: 'module' object has no attribute 'urlopen报错解决办法
  11. magicbook14能装鸿蒙系统吗,荣耀magicbook14锐龙版评测_magicbook14锐龙版缺点
  12. Cloud Rush—聚是一团火
  13. android activity_main.xml,Android Studio 打开activity_main.xml不能正常显示
  14. (完美可行)小米设备一键激活XPOSED框架方法
  15. matlab与vs混合编程,matlab与vs混合编程/matlab移植
  16. 华为桌面云虚拟机如何安装Ubuntu 20.04.3-live-server
  17. SUN公司Java认证和考试纵览
  18. 俞敏洪励志演讲:摆脱恐惧
  19. 视频监控客户端开发(IP Camera)总结
  20. matlab的函数库,matlab函数库大全

热门文章

  1. 美国诚实签经验——是不是户籍和常住作业地在一起?是不是有居住证?明白居住证信息吗?英语超卓,应变能力强,有幽默感 10分...
  2. Excel 某招聘网站职位分析项目
  3. 怎样将图片上文字转换成word文字
  4. java 专业英语单词_java_专业英语单词_力荐
  5. 操作系统知识点总结(十四)文件保护:文件访问类型和访问控制
  6. PLC中忘记cpu密码怎么办?
  7. 139显示无法imap服务器,139邮箱客户端 imap服务器
  8. android设置主题背景为壁纸_Android 应用背景加载系统动态壁纸
  9. JavaSE(J2SE)入门学习笔记(二)
  10. maven项目中JRE System Library Problem J2SE-1.5问题