敏捷子弹(摘自《代码之道》第二章)

2023-11-15

最近面试了几家公司,感觉大家对采纳Scrum流程还是挺感兴趣的。5年前,我翻译了《代码之道》这本书;其中,第二章有一篇文章谈到了敏捷方法。文章的后半部分还对Scrum做了重点介绍。作者原是微软员工,他的一些观点和建议难免会结合微软公司的实践,但总体上来说,他的观点公允,值得大家借鉴,因此也可以算是不错的入门读物吧。(只是我有点汗颜,因为现在重读这篇文章,感觉我当年的翻译确实有点生硬……)

以下是正文:


我很难做出判断。也许你可以帮我。我不能断定谁更恶心:一个是使用“敏捷”方法,并且想知道为什么微软不在全公司范围内采用它,用它解决我们面临的所有麻烦的人;另一个是认为敏捷狂热归根到底是被一些无知的学者鼓吹出来的,它实际上是一种改头换面的愚昧,它让开发者免于任何责任的人。我只能掷一枚硬币来决定了。他们两者的言论,都会使我肚子里有一股作呕的感觉。

现在让我们来纠正这两种观点:

1. 如果你认为敏捷方法解决了我们产品开发过程中的所有错误之处,那你真是个白痴。雇用成千上万个人来开发高度复杂、深度集成的软件给上亿客户来使用,这不是件容易的事。这世界上没人比我们对这个任务知道得更多,包括敏捷联盟的那些聪明家伙。并不是我们现在做的所有事情都是错的,也不是所有事情都能用敏捷方法来满足我们的需要。

2. 如果你是极端的反敏捷人士,你认为Scrum是a System of Clueless Reckless Untested Methods(一个毫无头绪、不计后果、未经试验的方法系统)的缩写,那你也是个白痴,而且更加无知。不假思索就随便以什么理由妄加否定,本身就是带有偏见而不职业的做法。像敏捷这样的草根运动总是有一些事实基础的,它可以使我们的团队和客户受益。那些概念可能并不总是直接适合于我们的业务,但当你停下来去理解它们的时候,那些事实基础总是有一些用武之地的。

作者注:敏捷在微软整个公司范围内,真的就是由一小撮人和一些小团队牵头的一次草根运动。

是时候来破除关于敏捷方法的传说了。我还将解释如何去使用这些方法背后的创新思维,以构建我们自己的优势。

 

真理的敌人

 首先,让我们来破除下面的这些敏捷传说……

传说之一:敏捷就等于极限编程(结对编程、Scrum、测试驱动开发、用户素材、或者其他敏捷方法)。敏捷方法实际上是软件开发实践的一个集合,这些实践共享公共的一套原则定义,但除了原则之外其他方面都不相关,有时甚至还是对立的。你可以从敏捷联盟(www.AgileAlliance.com)了解到关于敏捷的更多真实信息。

传说之二:敏捷方法不适合大型组织。这种说法很荒谬。敏捷是包含很多各不相同的方法的一个集合。这些方法中有一些不适合大型组织,但有一些适合,还有一些如果你创新一下的话也可能适合。在做出一个空洞的结论之前,你必须带着问题去研究具体的方法。

传说之三:敏捷方法可以用于大型组织。敏捷哲学崇尚“客户合作胜过合同谈判”和“响应变化胜过遵循计划”。跟1亿多个客户合作是艰难的。合同谈判在跨团队依赖性管理方面是至关重要的。(参见第8章的“要么听我的,要么走人”栏目。)遵循计划对于商业承诺来说是必要的,因为合作伙伴在上百万美元面前会变得难以相处。在大规模项目上应用敏捷方法,要求你灵活而创新地去处理好这些问题。

传说之四:敏捷意味着不写文档。敏捷哲学崇尚“可以工作的软件胜过面面俱到的文档”。很多敏捷的狂热者看到这个就认为,“啊,不需要文档了!”如果你认为走廊的尽头也就是世界的尽头的话,那你也不该得到在你的围墙之外产生的大量收益。敏捷哲学申明了,“虽然右项也具有价值,但我们认为左项具有更大的价值。”换句话说,可以工作的软件比文档更重要,但必要的文档对客户、合作伙伴和跨部门的依赖方仍然是有价值的。

传说之五:敏捷意味着没有前期设计。敏捷哲学崇尚“响应变化胜过遵循计划”。 很多敏捷的狂热者把这误解为,“没必要思考或做计划,设计到时候将突然出现!”突然从哪里出现?一个放射性污水堆积处吗?这里的要点是说,响应变化胜过过分死板地遵循原来的计划,而不要纵身跳下悬崖之后再去看会有什么后果产生。

传说之六:敏捷意味着没有个人责任。敏捷哲学崇尚“个体和交互胜过过程和工具”和“响应变化胜过遵循计划”。很多管理者看到这个感到很恐惧,认为这个意味着完全没有责任可言。实际上,敏捷在这个领域收到的效果恰恰与管理者担心的相反。敏捷使个体对团队负责,而团队对管理层负责。责任性大大地加强了,并且额外的间接层次让敏捷团队更加有效、有韧性、并且名副其实地“敏捷”。

传说之七:Scrum是个缩写词。这是个很无聊的传说,但它几乎让我发疯。Scrum是最有名的、并且实践得最广泛的敏捷方法之一,但它绝不是一个缩写词。Scrum是根据橄榄球术语来命名的,代表比赛双方的团队聚在一起,两手呈圆形闭止,准备争球。它也是Scrum团队每日例会的名字。在微软,我们已经使用了一种类似Scrum的方法达数十年,比这个术语出现要早得多。Scrum是最简单的敏捷方法之一,也最接近于微软的很多团队在现实中采用的方法。后来,更多的团队转向了Scrum。

 

拨乱反正

抽象地谈论敏捷只会招来漫无边际的争论,但到应用它的时候,却是实实在在的行动问题了。我们已经知道,敏捷实际上是软件开发实践的一个集合,问题是,“哪种方法适合在大规模项目中应用呢?”很多人对这个问题已经思考过或者撰稿论述过,但没有很多人写这样的栏目。在我给出我的观点之前,请看下面的几条基本规则:

1. 能不变就不变。如果一个团队已经在业务看重的各种度量上表现得很好,那就没有必要再改变了。改变总是有代价的,哪怕它的结果可能会很美好。你改变的目的只能是为了在最后获得改进。因此如果不需要改进,也就不需要改变。

2. 不要走得太远。如果改变是必要的,也不要一下子改变所有的东西。让功能团队每次只挑一两样改进,并且留意它们的进展状况。不是所有的团队都要一起改变,也不是所有的团队都要做相同的改变。当然,如果你改变的是一个像建造系统这样的中央服务,那么所有的团队最终都必须接受它。但即使是这种改变,我们也可以选择让它对个体团队是公开还是察觉不到。推荐的方法是:一点一点尝试,一点一点学习,循序渐进。

3. 区分项目级别和功能级别。人们感到困惑最大的地方——尤其对于敏捷方法——是在项目级别和功能级别上的差异。在项目级别,团队之间需要严格的日期和协议约束。在功能级别,其实没那么多讲究。很多管理者都不能理解这个奇异的概念——你的团队能够达到你想要达到的任何日期,问题只是你最终决定在这个日期之前做多少功能而已。只要项目级别的计划能够被跟踪和控制,你的功能团队应该选择任何能够让他们工作得最有效率的方法。

作者注:这一段像是一个电池组。值得注意的是:当组织中的几个小团队使用相似的方法时,通常这个组织会工作得更好。这些方法不需要完全相同,但如果团队步调一致的话,他们会在一起工作得非常好。否则,因为团队之间的预期时间各不相同,他们之间的协调和沟通就会变得一团糟。


准备改变了吗?

现在你想尝试敏捷方法了。但也许你只是想安抚一下部门里的那几个敏捷疯子,在他们喝着催眠的Kool-Aid饮料时,给他们送上一些Scrum“小吃”。那么,你应该尝试什么呢?你又怎样才能把它最好地集成到正常的工作中去呢?眼下有大量的敏捷方法可供选择,因此我在这里只能谈一谈最流行的那几个:Scrum、极限编程、测试驱动开发、结对编程、用户素材、重构和持续集成。

译者注:Kool-Aid是美国本土的饮料,里面含维生素C,是美国人在成长时最喜爱的饮品,不含咖啡因,口味多变。

首先,有两个方法在微软我们已经用了10几年了,它们是“重构”和“持续集成”。重构只是简单地重新组织你的代码,并不改变它原有的功能。重构用来将复杂的函数(面条代码)打散,或者在现有代码的基础上增加新的功能,比如把一个只能读取CSV文件的类改造成一个抽象类,以便能够同时读取CSV文件和XML文件。持续集成的想法是,让新代码总是集成到定期的(理想情况下是每天)完整建造中去,以便所有人都能对它进行测试。

译者注:面条代码(Spaghetti Code)是一种经典的反模式,用来形容看上去很乱、几乎没有软件结构的一段程序或者一个系统。


让他说话

其次是“用户素材”,它们就像是应用范例和功能的单页规范书的组合。用户素材的想法是,为特定功能的实现和测试提供刚刚够用来评估的信息。

用户素材比较麻烦的是,它们应该是由用户来创建的。很多敏捷方法假设用户经常就坐在功能团队的旁边。不幸的是,当你有1亿个目标用户时这就成了问题。

不管你喜不喜欢,我们需要用户代表。像市场、产品计划、用户体验、销售和支持部门都可以充当这样的角色。他们的发现可能被写入价值主张和远景文档,而远景文档恰恰就是基于大范围的用户调研基础上的。然而,当那些宽广的远景和端到端的应用范例被分解开来的时候,我们在功能级别上仍然能够使用用户素材的概念,提供刚刚足够的文档信息,用来对一个功能集合的实现和验证进行评估。

 

你完善我

“结对编程”是指两个人共享一张桌子和一个键盘,在一起编码。它的想法是,当一个人在打字的时候,另外一个人的视野更为宽阔,可以发现不理想的设计或实现。这一对人常常交换角色。虽然两个脑袋比一个脑袋工作得好,但他们同时也花出了两倍的开销。我更愿意看到把这种双份开销用在设计和代码审查上面,这样价值会更高。然而,结对编程在新代码库的培训上面效果显著,这时通常把一个熟悉代码的人和一个不熟悉代码的人结成一对。

除了重构和持续集成,“测试驱动开发”(TDD,Test-Driven Development)和Scrum已经被证明是在微软应用的最简易、最有效的敏捷方法。我在我的栏目中描述精益工程的时候(本章的第二个栏目),关于测试驱动开发我是这么论述的:你首先为一个类定义它的功能和函数,然后给公共函数编写单元测试,再然后才是写实现代码。这是个反复的过程,并且每次都只写几个单元测试和一点点代码。这种方法让开发者在做最少量的、但又是高质量的实现设计的同时,得到了他们想要的覆盖代码的单元测试。因此,测试驱动开发这种方法相当地流行。

先写测试也更有趣。当你先写实现代码的时候,单元测试就成了一种花样翻新的痛苦,而且它只会带来坏消息;测试不能真正起到增强代码的作用。当你先写单元测试的时候,编写代码去适应测试会比较容易,而且当测试通过的时候你的心情会非常愉悦。

测试驱动开发可以和结对编程组合起来使用:一个开发者负责写一些测试,另一个负责写足够的代码来通过这些测试。他们两个的角色还可以常常交换。最后,测试驱动开发让开发者对“什么时候才算是真正完成了实现”有了清晰的认识。也就是,当所有的需求都有测试,并且所有这些测试都通过的时候。 

 

有点极端

“极限编程”是一个完整的开发方法论。它把用户素材、结对编程、测试驱动开发、重构、持续集成和另外一些实践组合在一起,非常适合应用在跟客户紧密合作的小团队中。

极限编程大量依赖团队知识,以及与客户之间的直接交互,而且几乎没有文档。如果你的团队是独立的,并且你的客户就在你的走廊边上,这种方法会很有效,但在微软这种现象并不普遍。如果我们不能每年赚到数10亿美元,我们的形势就会很悲惨。然而,就像我已经说过的那样,极限编程中的很多单个方法在我们的产品开发中应用得非常好。

 

准备玩橄榄球!

最后我将讨论的(可能也是被人误解最深的)敏捷方法是Scrum。人们可能把Scrum和极限编程(它实际上不用Scrum)混淆在一起,也可能认为敏捷就等于Scrum(哈?!)。除此之外,Scrum最令人困惑的部分就是下面这些相关的术语了:Scrum大师(Scrum Master)、急待完成任务清单(Backlog)、burn-down图、冲刺(Sprint),甚至包括猪(Pig)和小鸡(Chicken)——这些足以吓跑任何一位管理者。真是极大的误会啊!

无论好坏,Scrum是由一个喜欢有趣名字和故事的人发明的。实践本身既不复杂,也无争议。因此,除了重构和持续集成之外,Scrum是多年来我们内部一直在做的、最接近于敏捷方法的一种实践,并且我们还有一些重大的改进。

接下去,让我们先来澄清那些令人困惑的术语。“Scrums”是指每天的例会,“Scrum大师”是指功能团队的组织者,“急待完成任务清单”是一些功能或者工作条款的列表,“burn-down图”用于展示剩余的工作,“冲刺”是指小型的里程碑,“猪”和“小鸡”则是指企业家的农场动物(故事很长,但很好笑)。

这些概念没有一个是新创出来的,但Scrum的确带来了一些大的改进:

*** Scrum的每日例会组织得非常好,用于收集有用的数据。团队的组织者(Scrum大师)简单地问所有的团队成员3个问题:从昨天到现在完成了哪些工作(并且花费多久时间),现在到明天到来之前准备做什么(并且告知剩余的工作量),什么正阻碍着工作的进展。

作者注:跟踪每个任务完成所花费的时间,是我的团队对微软的Scrum作的一点小小的贡献。通过把这些信息加入到burn-down数据中(还剩下多少工作量),你就可以画出美妙的累积流线图,度量花在进展中的任务和工作上的时间,并且更好地估计团队的生产力。典型情况下,产品团队花在任务上的时间大概为42%,花在沟通上的时间为30%,拿我来说,我花在一起协作的功能团队上的时间有60%之多。

*** 在Scrums会议上收集到的数据被输入到一个电子表格或者数据库中。基于这个电子表格,你可以分析花在任务上的时间、完成日期、进展中的工作、计划变更和许多项目问题。这种情况下最流行使用burn-down图——一种展示时间和总剩余工作量之间的动态关系的图表。 

*** Scrum大师是一个独立于团队之外的力量。他甚至最好不是组织中的一员,但这通常不太现实。Scrum大师有权利排除阻碍每日例会进程的因素,保持会议的简短。

*** 功能列表或者时间表称作为“产品任务清单”(ProductBacklog),而工作条款列表或时间表称作为“冲刺任务清单”(SprintBacklog)。通过分离这两个列表,管理层可以关注在他们想要完成的工作上(产品任务清单),而团队则关注在手头的工作上(冲刺任务清单)。为了保证所有事情都在正常的轨道上,Scrum大师一般每周跟管理层开一次会(比如每周的主管会议),进行状态更新。

*** 冲刺作为小型的里程碑,它的时间长度是固定的。当时间用完了,一个冲刺也就结束了。典型情况下,一个冲刺大概30天。( 译者注:其实,Scrum推荐的Sprint周期为2~4周。)

*** 每次冲刺结束后,功能团队会跟管理层一起复审工作(不错的改变,哈?),总结本轮冲刺做得好的地方,以及下轮冲刺需要改进的地方(这总比等上1年或者10年、产品最终出货后再做总结来得强),然后为下轮冲刺制定计划并重新估计工作条款(改变原先的计划和估计?决不!)。

通过使用每天、每周、每月的反馈机制,Scrum允许团队在一个多变的环境中保持高效的工作,并且富有弹性。通过收集一些关键数据,Scrum允许团队和管理层知道团队的运作状况,在问题还没有成为问题之前就把它解决。通过分离管理层掌管的功能列表和功能团队掌管的工作条款列表,Scrum允许团队自我指导、工作更加投入,使团队内的每个成员和团队外的管理层都很有责任感。

 

最后你要知道的

不是所有的敏捷方法都适合于每一个人。很多根本就不适合微软的大型项目。但Scrum、测试驱动开发、重构和持续集成可以被很多微软的团队使用,并且会有显著的效果。结对编程和用户素材的适用程度要低一点,但如果条件适宜的话,应用这些方法也能很有效。只要你不是心急、一下子走得太远,或者强迫你的团队采用敏捷,应用这些方法定会有大量收获的。

作者注:几乎在我任职过的所有地方,我都见到过有管理者强迫工程师改变他们的方法论的情况。这绝对行不通,哪怕像Scrum这样很受大众欢迎的东西。管理者可以建议、支持、资助行为方面的改变,但绝对不要强制。

如果你想作更多的了解,请在我们的内部网络或者互联网上搜索敏捷方法。同时也请留意2006年春天即将开设的关于敏捷方法的新课程。如果你的团队方方面面都表现得很出色,那建议你不要做任何改变。但如果你希望看到一点更高的质量,或者更好的基于功能团队的项目管理,你自己思量一下是否要采取一些行动,尝试一下敏捷方法。


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

敏捷子弹(摘自《代码之道》第二章) 的相关文章

  • SCRUM框架包括3个角色、3个工件、5个活动、5个价值

    转自http www scrumcn com agile scrum knowledge library scrum html SCRUM 是一个用于开发和维持复杂产品的框架 Scrum 是一个用于开发和维持复杂产品的框架 xff0c 是一
  • 什么是scrum中的3355?

    3355表示的是3个核心角色 xff0c 3个工件 xff0c 5个关键事件以及5大价值观 3个工件 xff1a 产品Backlog Sprint Backlog 潜在可交付软件增量 3个核心角色 xff1a 产品负责人 xff08 PO
  • Daily Scrum: 2012/12/8

    成员角色今天工作明天计划王安然PM Dev已请假 xff0c 开会 继续开会 黄杨PM Dev已收拾skynet的小问题并且通过测试 xff08 312 xff09 xff0c 编写武器项cracker xff08 313 xff09 完成
  • 基本流程图与跨职能流程图

    流程可以用流程图来表示 但它们有一个缺点 标准流程图无法表明谁负责这些活动 流程可以用流程图来表示 但它们有一个缺点 标准流程图无法表明谁负责这些活动 因此 跨职能流程图 或称为泳道图 泳道流程图 跨职能流程图 通过定义谁做什么来使流程更加
  • 高校软件工程期末复习——ICONIX

    ch01 软件工程危机 定义 软件在开发和维护过程中遇到的一系列严重的问题 含义 如何开发软件 如何维护数量不断膨胀的已有软件 原因 客户对软件需求的描述不精确 可能有遗漏 有二义性 有错误 在软件开发过程中 用户提出修改软件功能 界面 支
  • 程序员如何写好一篇技术文章?

    结合自身写作经历以及本次训练营直播分享的内容 谈一谈写作技巧以及程序员如何写好一篇技术文章 1 写作训练营回顾 2020 年 12 月 26 日下午 我参加了一个写作训练营的直播 活动内容如下 该训练营是以直播的方式开展 四位嘉宾给大家分享
  • 用自然语言进行编程的时代真的要来了

    用自然语言进行编程的时代真的要来了 GitHub CEO托马斯 多姆克在官方博客上宣布 代码辅助工具Copilot进行重大升级 接入GPT 4 更名Copilot X 因此 原来只能帮你补全代码的它 现在通过打字聊聊天甚至语音就能 直接写代
  • 什么是 Scrum 工件?

    What is Scrum Artifacts 随着我们的技术系统和项目在规模和复杂性方面不断发展 Scrum 会议和敏捷方法已成为许多公司开发过程中不可或缺的一部分 Scrum 会议是团队成员协作的好方法 可确保队列中的所有项目和任务都得
  • Sprint回顾会议的一种简单玩法

    原文作者 Mike Cohn 回顾会议该怎么开 团队不同 大家的做法或许各有不同 我想介绍一种我最喜欢的方式 特别是因为这种方法经受住了时间的考验 很多年以来 我已经把它运用在了很多很多的团队里 开始 停止 继续 我喜欢在sprint回顾会
  • 敏捷开发知识体系笔记

    敏捷开发知识体系整体框架 敏捷开发工程实践 项目管理 迭代开发 风险价值生命周期 多级项目规划 完整团队 每日站立会议 任务板 燃尽图 需求管理 需求订单 业务流程草图 用例驱动开发 用户故事 架构 演进的架构 演进的设计 基于组件的架构设
  • 敏捷开发“松结对编程”实践之三:共同估算篇(大型研发团队,学习型团队,139团队,师徒制度,敏捷设计,估算扑克,扑克牌估算)

    转载自 http blog csdn net cheny com article details 6587277 本文是 松结对编程 系列的第三篇 之一 之二 之三 之四 之五 之六 之七 之八 此系列之九及之后文章请见栏目总目录 估算是经
  • 我的DirectShow著作

    DirectShow开发指南 清华大学出版社出版 2003年12月 本书以DirectX SDK 9 0版为蓝本 涉及的内容几乎涵盖了在Windows平台上使用DirectShow进行C 编码的方方面面 全书共分4个部分 第1部分详细介绍了
  • 互联网小拼,这一生的故事,你要看看吗

    前言 谁也不知道 今天竟然是我的最后一天加班 我叫小拼 我来自农村 一个国家级贫困县 原以为会在老家种田一辈子 谁曾想 考上了一所大学 学了计算机专业改变了我的一生 大学毕业以前都没什么好说的 九年义务教育 再加高中三年 大学四年 毕业后
  • 敏捷子弹(摘自《代码之道》第二章)

    最近面试了几家公司 感觉大家对采纳Scrum流程还是挺感兴趣的 5年前 我翻译了 代码之道 这本书 其中 第二章有一篇文章谈到了敏捷方法 文章的后半部分还对Scrum做了重点介绍 作者原是微软员工 他的一些观点和建议难免会结合微软公司的实践
  • 传统的项目经理可以担当Scrum Master吗

    原文链接作者 Amir Nasiri 一个习惯了传统项目管理方法的项目经理 可以在敏捷组织里担当ScrumMaster吗 这是一个很有意思的问题 也是所有项目经理在有朝一日面对敏捷方法 比如Scrum 的时候需要思考的问题 敏捷在落地实施时
  • 用免费敏捷工具Leangoo领歌做敏捷需求管理

    传统的瀑布工作模式使用详细的需求说明书来表达需求 需求人员负责做需求调研 根据调研情况编制详细的需求说明书 进行需求评审 评审之后签字确认交给研发团队设计开发 在这样的环境下 需求文档是信息传递的主体 也是一份契约 然而详细的需求说明书有以
  • 关于 Team Foundation 中的功能和积压项目,Epics 是什么? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 From 这个链接 https stackoverflow com questions 16698363 difference betwe
  • Scrum 和 Fogbugz [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 有人同时使用 Fogbugz 和 Scrum 吗 我们广泛使用 Fogbugz 并且我正在寻找任何可能将其用作 Scrum 一部分的人的想法 我
  • 敏捷环境中的需求、规格和管理[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我的公司尝试采用 Scrum 方法 但取得了不同程度的成功 这些是我们遇到问题的一些领域 你如何处理这些 跟踪要求来自 产品营销贯穿于产品 我们
  • 在敏捷/Scrum 用户故事中,多少细节才足够? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 通常的反应是足够详细就足够了 在我们目前正在忙的项目中 该项目不完整并且在没有任何类型的 brs 文档 用户故事的情况下移交给我们 我们得

随机推荐

  • 关于“Could not open ServletContext resource [/WEB-INF/applicationContext.xml]”解决方案

    问题产生 最近学了Maven 并尝试将以前的项目 springmvc myabtis 重构成Maven项目 Maven项目推荐各种资源文件都放在src java resources目录下 所以我自然把spring的配置文件 包括spring
  • blender模型和材质导入UE4的工作流

    UE4设置 打开UE4 设置 gt 插件 搜索script 启用 然后编辑 gt 项目设置 找到python 是否远程执行打勾 Blender设置 然后下载Blender to UE4的插件 作者地址https github com ana
  • ios的input点击时有阴影

    最近做项目时遇到一个问题 就是h5页面 在ios浏览器中打开的时候 上面的input框点击的时候会出现一片阴影 然后一闪而过 对功能没什么阴影 就是不太美观 经过试验发现 当input使用默认边框时 也会有闪 因为有边框的原故 闪的不太明显
  • Springboot前后端数据传递的序列化数据格式:json字符串

    Springboot进行前后端数据传递格式json字符串的简单理解 1 对象的序列化和反序列化都什么时候用 当你想把内存中的对象保存到磁盘上的文件或者数据库中时 当你想用套接字在网络上传送对象时 当你想通过RMI传输对象时就牵扯到对象的序列
  • Java Scanner类中next()和nextLine()的区别

    next next 一定要读取到有效字符后才可以结束输入 对输入有效字符之前遇到的空格键 Tab键或Enter键等结束符 next 方法会自动将其去掉 只有在输入有效字符之后 next 方法才将其后输入的空格键 Tab键或Enter键等视为
  • Windows 安装 RabbitMq 和 Erlang

    1 安装Erlang 音乐RabbitMq是基于Erlang开发的 所以先要安装这个环境 下载地址 32位 64位 其他版本自己找 官网 下载完之后无脑安装直接一直下一步 2 配置Erlang环境变量 2 1 新建ERLANG HOME 把
  • unity如何解决协程开启频繁导致的程序卡顿

    unity如何解决协程开启频繁导致的程序卡顿 一 协程 协程并不会在Unity中开辟新的线程来执行 其执行仍然发生在主线程中 当我们有较为耗时的操作时 可以将该操作分散到几帧或者几秒内完成 而不用在一帧内等这个操作完成后再执行其他操作 二
  • 去掉页眉横线三法 (WORD)

    在使用WORD中 我们时常会用到页眉 但是加上页眉后 在页眉下往往有一横线 可是我们有时根本不需要这条横线 但它删都删不掉 怎么办呢 小弟在此奉上一计 一首先 打开一文档就不用说了 点击 视图 页眉和页脚 然后光标定位在页眉中 点击 格式
  • oracle在线日志损坏,前在线日志文件损坏与ora-600 [4000]处理

    这次又是一台机器上面有两个实例A和B 又是由于非当前的在线日志文件的状态是处于closed状态的 裸设备 于是dba将A节点的非当前在线日志文件填加到了B节点上面去了 于是在A节点日志发生切换时 导致了当前在线日志文件损坏 一般情况下当前在
  • 前端性能优化之页面加载

    牛客在线求职答疑中心 35799 牛客在线求职答疑中心 华为oppe 联洲国际3个offer该如何选择 牛客在线求职答疑中心 35799 牛客在线求职答疑中心 华为oppe 联洲国际3个offer该如何选择 想问一下紫光同芯这家公司 他们的
  • 【计算机网络】(五)网络层之ip地址+数据封装

    1 ip地址 1 1 IP地址一些概述 Internet protocol 互联网协议 IP地址 其实就是互联网协议里使用的地址 一台电脑 一个服务器都是一台主机 IP地址是主机唯一的标识 保证主机间正常通信 一种网络编码 用来确定网络中一
  • python os 模块

    os 模块 可以通过os模块调用系统命令 获得路径 获取操作系统的类型等都是使用该模块 1 通过os 获取系统类型 os name import os print os name nt nt 代表windows posix linux gt
  • C++ set容器及其常见操作

    文章目录 前言 一 什么是set容器 二 set容器的特征 三 set容器的常见操作 四 使用步骤 1 引入头文件 2 set容器的定义 3 set的插入和删除 4 set的遍历 5 set size 总结 前言 使用集合框架不仅能提高我们
  • c++动静编译的区别

    动态编译和静态编译的区别 动态编译决定了在程序运行时才会连接库文件 需要部署的坏境安装对应库 程序体积小 静态编译在编译时就连接好库文件了 所有库文件都打包进程序了 所以体积大 不过移植性好 demo 静态编译 test h ifndef
  • 使用docker创建fdfs并使用

    1 拉取镜像 docker pull delron fastdfs 2 使用docker镜像构建tracker容器 docker run dti network host name tracker v var fdfs tracker va
  • linux执行使分区生效的命令,Linux硬盘分区生效命令partprobe

    在Linux中使用fdisk命令进行分区时 有时会遇到 WARNING Re reading the partition table failed with error 16 Device or resource busy The kern
  • nodejs知识系列:npm查询包的所有版本及安装指定版本

    说明 在添加依赖或者安装本地环境时 有时候不支持最新的安装包 需要自己指定版本号 博主最近在win7开发nestjs和angular经常遇到 解决方案 npm view 目标包名 versions json或cnpm view 目标包名 v
  • python矩阵交换两行_Python 实现交换矩阵的行示例

    Python 实现交换矩阵的行示例 如下所示 TODO r1 r2 直接修改参数矩阵 无返回值 def swapRows M r1 r2 M r1 M r2 M r2 M r1 pass 以上这篇Python 实现交换矩阵的行示例就是小编分
  • 人工智能-统计机器学习- 自适应提升算法

    监督学习 Boosting adaptive boosting 自适应提升 对于一个复杂的分类任务 可以将其分解为 若干子任务 然后将若干子任务完成方法综合 最终完成该复杂任务 我们将这若干子任务称为弱分类器 weak classifier
  • 敏捷子弹(摘自《代码之道》第二章)

    最近面试了几家公司 感觉大家对采纳Scrum流程还是挺感兴趣的 5年前 我翻译了 代码之道 这本书 其中 第二章有一篇文章谈到了敏捷方法 文章的后半部分还对Scrum做了重点介绍 作者原是微软员工 他的一些观点和建议难免会结合微软公司的实践