10X程序员工作法-极客时间-听课总结(在更)

这个专栏是对10X程序员工作法的一个总结。

为什么我们会加班加点?做出来的东西与要求不符?

《人月神话》 提到了两个非常重要的概念:本质复杂度和偶然复杂度

本质复杂度:无论如何都要做的事情

偶然复杂度:因为做事方法不对,导致要做的事情

接下来我们从这几个方面来进行梳理

一个有效的工作思考框架

如何将精力放到本质时间复杂度上,减少偶然复杂度的消耗

请回答三个问题:

1.我是什么水平

2.我要到达什么水平

3.我怎么样达到这个目标

这三个问题帮我们确定

1.现状

2.目标

3.实现

当一个产品要交代给我开发一个功能特性时,通常要问这几个问题

为什么要做这个特性,他会给用户带来什么价值?(以终为始)

什么样的用户会用到它,在什么场景下面使用,他们又会怎样使用它?(任务分解 需要将大目标切分成小的目标 所以会关心具体的使用场景)

达成这个目的是否有其他手段?是不是一定要开发一个系统?

(沟通反馈 向产品经理了解 我确实了解了这个需求)

这个特性上线之后,怎么衡量他的有效性?

(我需要了解这个产品做出来确实能够达到目标)

我们做的方案通常是一个自动化的方案,但是我们需要了解没有自动化之前是怎么做的,所以会关心是不是还有其他的现成的替代方案

四个原则是明白为什么要提出问题? 怎么问问题,可以遵循以下四个原则

1.以终为始(确定好真实的目标)

2.任务分解(找到实施路径)

3.沟通反馈(解决与人打交道的时候的问题)

4.自动化(解决机器打交道时候的问题)

|------|-------|------|
| 现在在哪 | 要到哪里去 | 怎么去 |
| 你很清楚 | 以终为始 | 任务分解 |
| 你很清楚 | 以终为始 | 沟通反馈 |
| 你很清楚 | 以终为始 | 自动化 |

1.以终为始

1.你如何让你的努力不白费?

-以终为始:一种结果导向的思考模式

如果让你设置一个功能-登录功能

你可能会想 不就是用户名密码嘛,然后就开始设计,但是我的需求是设计一个打车软件,用手机号和验证码进行登录,这就是缺乏以终为始的思维习惯

如果真的是想找个好工作,那你就应该了解工作的要求是什么,怎样才能掌握工作要求的技能

任何事物都要经过两次创造:一次是在头脑中的创造

然后才是付诸实践,也就是实际的构建或第二次创造

在动手做事之前,我们要在第一次创造上多下一些功夫,将相关各方的"集体想象"统一起来。以建筑为例,就是先在图纸上构思各种细节。对应到做软件,我们也可以做很多事,比如:

1.要给用户看产品的样子,可以用原型工具把它做出来,而不是非得把完整功能开发出来;

2.要呈现服务接口的样子,可以用模拟服务器搭出一个服务,而不用等后端全部开发完毕;

3.要让程序员知道要开发产品的细节,可以在任务上描述出软件各种场景给出的各种行为。

那么我们怎么进行以终为始的运用呢?

在团队内部,我一直坚持"以终为始",让大家在执行任务之前,先倒着想想再动手规划,这样规划出来的工作更能瞄准真正的目标 。举一个之前做产品的例子,当年在创业的时候,我们打算做一个物联网开发平台 ,但具体应该做成什么样子呢?有了"以终为始"的思维,我们考虑的是别人会怎么用我们的平台。我们设计的方式是,用户到我们的网站,阅读相关文档,然后参考文档一步一步照着做。这其中的一个关键点是:文档,特别是《起步走》的文档,这是用户接触我们这个平台的第一步,决定了他对我们产品的第一印象。

所以,我们决定从写《起步走》这个文档开始,这个文档描绘了**用户怎样一步一步使用我们的开发平台,完成第一个"Hello World"级别的应用。**请注意,这个时候,我们一行代码都没有写。写好了这个《起步走》文档,团队的所有人对于我们的平台要做成什么样子,已经有了一个比较初步的认识。更重要的是,我们可以拿着这个文档,去和外部的人讨论这个尚未出世的平台。

"以终为始"的方式,不仅仅可以帮我们规划工作,还可以帮我们发现工作中的问题。

有一次,要将现有的系统改造成支持多租户的系统。也就是说,别的商家可以到我们的平台上发起申请,拥有和我们现有平台一样的能力。功能来了,各个团队将任务分解,然后就各忙各的去了。但我有着习惯性的不安,总担心丢点什么,于是催着项目经理梳理一下上线流程。是的,上线流程,虽然我们的代码还没开发完,但是本着"以终为始"的态度,我们就假设各个部分已经开发好了,来想一想上线应该怎么做。果不其然,一梳理上线流程,我们便发现了问题:怎么识别不同的租户呢?有人给出的方案是设置一个 HTTP 头。但谁来设置这个 HTTP 头呢?没人仔细想过。于是,一个潜在的问题就这样被发现了,至少不用在未来为它加班了。至于解决方案,作为程序员,我们有的是办法。事实上,在今天的软件开发实践中,已经有很多采用了"以终为始"原则的实践。

**比如测试驱动开发。测试是什么?**就是你这段代码的"终",只有通过测试了,我们才有资格说代码完成了。当然,测试驱动开发想做好,并不是先写测试这么简单的。

**比如持续集成,我们是要交付一个可运行的软件,倒着来想,最好的做法就是让软件一直处于可运行的状态,那就是持续地做集成。**概括地说,践行"以终为始"就是在做事之前,先考虑结果,根据结果来确定要做的事情。

如果今天的内容你只能记住一件事,那请记住:遇到事情,倒着想。

看到一个很有趣的评论:

延伸出来的思考。 拿到一个需求先写接口文档,评审过了再开发代码。争取做到接口文档就是最终的实现方案,不需要做着做着再去沟通方案。而不是拿了需求文档,直接就写代码。 好处:

  1. 写接口文档,可以更好的规划工作量和时间。

  2. 梳理的过程中,可能会发现一些考虑不周的技术问题,提前排雷。

  3. 评审的过程也是自我提高的过程,说不定沟通中有比自己认为的有更好的技术解决方案。

2.你完成了工作,为什么他们还不满意?

-完成的定义:DOD:什么叫完成

完成的定义

DoD 这个概念本身并不复杂,它就是告诉我们怎样算是完成了,尽量减少因为理解偏差造成的各种浪费。

具体怎么做呢?

就是团队在开始工作前,先制定 DoD。以前面的场景为例

团队可以规定:

|---------------------------------------------------------------------------|
| 特性开发完成,表示开发人员经过了需求澄清、功能设计、编写代码、单元测试,通过了测试人员的验收,确保代码处于一个可部署的状态,相关文档已经编写完毕。 |
| 开发完成,表示开发人员编写好功能代码,编写好单元测试代码,编写好集成测试代码,测试可以通过,代码通过了代码风格检查、测试覆盖率检查。 |

DoD 是一个清单,清单是由一个个的检查项组成的,用来检查我们的工作完成情况。DoD 的检查项,就是我们开发产品所需的一系列有价值的活动。比如:编写代码、编写测试代码、通过测试人员验收等。什么样的活动是有价值的,也许每个团队的认识是不同的。

DoD 的检查项应该是实际可检查的。你说代码写好了,代码在哪里;你说测试覆盖率达标了,怎么看到;你说你功能做好了,演示一下。DoD 是团队成员间彼此汇报的一种机制。别把"汇报"想复杂了,最简单的汇报就是说一句"这个功能做完了"。一个迭代的 DoD,比如:这个迭代规划的所有功能已经完成。一次发布的 DoD,比如:整个软件处于可发布的状态,上线计划已经明确。

评论:

之前就接过产品的类似这种需求:在某个全量表里加个字段。我接过来之后问了一个问题:业务方在什么场景下怎么用这个数据,产品经理语塞,最后这个需求转换成了一个数据分析产品的雏形,而我也用另一种临时的解决方案帮业务解决了问题。感受就是:产品当了传话筒,自己就必须搞清楚业务方要的到底是什么,也就是文中老师说的DoD。

3.接到需求任务,你要先做哪件事?

有很多时候,开始实现这个需求之前,任务双方都没有清晰地定义好边界,没能把需求描述清楚。

很多团队的一个状态就是,程序员们都知道要开发的功能是什么,但这个功能是谁在什么样的场景下使用的,很多人却回答不上来。 如果你去问他为什么要开发这个功能,他通常会说:这是功能列表里规定的。 这种功能列表式的需求描述方式,将一个完整的需求敲成了碎片。 根据这种基于功能列表的需求描述,每个组在安排工作的时候,都会按照自己的理解进行功能排列。所以,当你的组完成了一个功能时,这个功能却可能上不了线,因为你还要依赖于其他组的工作,而这个组不巧,却刚好把相关的功能开发排在了后面。

替代功能需求列表的方式 - 是用户故事 站在用户的角度来描述了一个用户希望得到的功能,关注用户在系统中完成一个动作需要经过怎样的路径。

用户故事有什么用?

我们看看用户故事有什么用?

1.标题 ,简要地说明这个用户故事的主要内容,比如:注册用户使用用户名密码登录。

2.概述 ,简要地介绍这个用户故事的主要内容,一般会用这样的格式:As a (Role), I want to (Activity), so that (Business Value).

例子:作为一个注册用户,我想要注册登录,以便我可以使用注册用户才能够使用的服务

**3.详述,**详细地描述这个用户故事的完整流程,我们会把操作流程、用户界面等信息都放到这里。

用户使用正确用户名和密码登录,就可以登录成功;如果密码不正确,则登录页面提示用户"用户名密码不正确"。

4.验收标准,这个部分会描述一个正常使用的流程是怎样的,以及各种异常流程系统是如何给出响应的,这是程序员常常会欠缺的思考。它会把详述中很多叙述的部分变成一个具体的测试用例。

比如 下面有两个验收用例:

正常场景:给定一个注册用户张三,其用户名是 zhangsan,密码是 foobar,当张三使用 zhangsan 和 foobar 登录系统时,可以成功登录,登录成功后,跳转到用户中心。

异常场景:给定一个注册用户张三,其用户名是 zhangsan,密码是 foobar,当张三使用 zhangsan 和 wrong 登录系统时,登录失败,在登录页面上提示"用户名密码不正确"。

当我们说自己开发完成,可以交给测试人员测试时,我们需要照着验收标准给测试人员演示一遍,证明我们的系统确实能够跑通。这之后,测试人员才会把系统接手过去,做更系统的测试

你的角色

虽然你名义上是程序员,但当拿到一个需求的时候,你要做的事不是立即动手写代码,而是扮演产品经理的角色,分析需求,圈定任务范围。相信我,事前分析绝对比你拿一个写好的系统给老板,而他却告诉你这不是他想要的,好太多了。另外我想提醒你注意的是,扮演不同角色的时候,我们的思考模式是不同的。还是以开发用户名密码登录为例,你想到的可能是:输入正确的用户名和密码可以正常登录,输入错误的用户名和密码不能登录,并且给出提示**。**

如果你只扮演开发人员的角色,想到这些就算不错了。但如果你扮演的是产品经理的角色,会从产品的角度进行思考,也就会看到不同的内容,比如:登录是否需要验证码是否需要第三方登录用户名和密码的长度在系统内是否有限制密码是否需要满足一定的规则

4.持续集成,本身就是写代码的一个环节

写完代码不是团队的交付物,而是一个真正可以运行的软件,如果想将每个程序员编写的代码很好地组合在一起,我们就必须做一件事:集成

1996 年,Steve McConnel 出版了一本著作《Rapid Development》,国内译作《快速软件开发》。在这本书中,作者首次提出了解决集成问题的优秀实践:Daily Build,每日构建。通过这个名字,我们便不难看出它的集成策略,即每天集成一次

持续集成这个想法固然好,但是不是需要有专人负责盯着大家的工作,只要有人提交了代码,这个负责人就要去集成呢?显然,这在真实工作中是行不通的。既然是程序员的想法,程序员解决问题的方案自然就是自动化这个过程。于是,有人编写了一个脚本,定期去源码服务器上拉代码 ,出现程序更新时,就自动完成构建。后来,人们发现这段脚本与任何具体项目都是无关的。于是,把它进一步整理并发布出来,逐步迭代发展成为今天广为人知的持续集成服务器

由 Martin Fowler 所在的 ThoughtWorks 公司发布了市面上第一款持续集成服务器 CruiseControl。CruiseControl 可谓是持续集成服务器的鼻祖,后来市面上的服务器基本都是在它的基础上改良而来的。Martin Fowler 的重磅文章和首款持续集成服务器的问世,让软件行业对持续集成进行了更为深入的探讨,人们对于持续集成的认知程度一路走高,持续集成服务器成为了开发团队在集成阶段最得心应手的工具。围绕着持续集成的一系列行为准则逐渐成型。

Continuous Integration

一个好的做法是尽早把代码和已有代码集成到一起,而不应该等着所有代码都开发完了,再去做提交。怎样尽早呢?你需要懂得任务分解,这是我们在之后的"任务分解"主题下会讲到的内容。

评论:

曾经参与过一个项目,中美印三地开发,开发测试产品加起来可能过百吧。当时,我们中国团队做过一个这样的工具,每次在git-review上提交/更新review时,自动构建一个当前branch是最新版,打上review的patch,然后构建,跑UT,UT覆盖率在95%再向下走。 做到这一步,其实不算什么,但是已经超过国内80%的同行水平了。然后我们还会构建一个虚拟机镜像安装这个build,安装好了在专门的虚拟测试网络上启起来,利用自动测试工具跑一些基本的case,比如登陆啊,基本的操作啊,这一系列跑完,才可以正式的让人review。 这个项目因为一些方向性和市场的问题,一年多就失败了,项目组解散。但是集成水平,的确是我经历过的最高的。

5.精益创业,产品经理不靠谱,你该怎么办?

之所以我们能很好地回绝了产品经理不恰当的需求,是因为我们问了一些好问题,但更重要的是,我们为什么能问出这些问题。

但是随着互联网深入人心,软件开始向各个领域蔓延。越来越多的人进入到 IT 行业,不同的人开始在各个方向上进行尝试。这时候,软件开发的主流由面向确定性问题,逐渐变成了面向不确定性问题。

那精益创业到底说的是什么呢?其实很简单。我们不是要面向不确定性创造新事物吗?既然是不确定的,那你唯一能做的事情就是"试"。

怎么试呢?试就要有试的方法。精益创业的方法论里,提出"开发(build)- 测量(measure)- 认知(learn)" 这样一个反馈循环。就是说,当你有了一个新的想法(idea)时,就把想法开发成产品(code)投入市场,然后,收集数据(data)获取反馈,看看前面的想法是不是靠谱。

既然是试,既然是不确定这个想法的有效性,最好的办法就是以最低的成本试,达成同样一个目标,尽可能少做事。精益创业提出一个非常重要的概念,最小可行产品,也就是许多人口中的 MVP(Minimum Viable Product)。简言之,少花钱,多办事。

你为什么要学习精益创业?

当产品经理要做一个新产品或是产品的一个新特性,我们就可以用精益创业的这几个概念来检验一下产品经理是否想清楚了。

比如,你要做这个产品特性,你要验证的东西是什么呢?他要验证的目标是否有数据可以度量呢?要解决的这个问题是不是当前最重要的事情,是否还有其他更重要的问题呢?

如果上面的问题都得到肯定的答复,那么验证这个目标是否有更简单的解决方案,是不是一定要通过开发一个产品特性来实现呢?

6.解决了很多技术问题,为什么你依然在坑里?

角色的差异

不同角色工作上真正的差异是上下文的不同。这是什么意思呢?以前面的问题为例,你在项目里打杂,你只能关注到一个具体的任务,而项目主力心目中是整个系统。虽然写的代码都一样,但你看到的是树木,人家看到的是森林,他更能从全局思考。

多问几个为什么,交流一下是不是可以换个做法 ,许多困惑可能就烟消云散了。而能想到问这样的问题,前提就是要跳出程序员角色思维,扩大自己工作的上下文。虽然我不是项目主力 ,但不妨碍我去更深入地了解系统全貌;虽然我不是项目负责人,但不妨碍我去了解系统与其他组的接口 ;同样,虽然我不是项目经理 ,但我可以去了解一下项目经理是怎样管理项目的;虽然我不是产品经理,但了解一个产品的设计方法对我来说也是有帮助的。当你对软件开发的全生命周期都有了认识之后,你看到的就不再是一个点了,而是一条线。与别人讨论问题的时候,你就会有更多的底气,与那些只在一个点上思考的人相比,你就拥有了降维攻击的能力。

评论:

我在项目中也多次遇到过通过扩大上下文而解决问题的情况,**比如有一次客户提了一个定期从我方系统提取数据同步给某外围系统的需求,开发过程中我们发现提数逻辑涉及关联一张上亿多数据的大表,查询性能很差,技术层面无论如何是无法解决的,最后我们从需求层面出发,着手绕过这个坎,经过分析,发现关联这张大表的作用主要就是为了过滤掉一些脏数据,再结合客户最终的使用场景分析,发现其实由外围系统进行此项过滤会更容易,最后我们说服了客户和友商,不仅很好的绕过了这个坎,也成功实现了该需求;**类似的案例还有很多,技术解决不了的问题就通过非技术手段解决,这个案例中开发人员搞了几天一直没能解决,后来报了进度风险,最后版本经理想到从需求层面绕过去,这或许就是他们两个角色的上下文不同的区别吧。

7.为什么做事情之前要推演

一个技术任务

你现在在一家发展还不错的公司工作。随着业务的不断发展,原来采用的关系型数据库越发无法满足快速的变化。于是,项目负责人派你去做个技术选型,把一部分业务迁移到更合适的存储方式上。经过认真的调研和思考,你给负责人提出了自己的建议,"我们选择 MongoDB。"出于对你的信任,负责人无条件地同意了你的建议,你获得了很大的成就感。在你的喜悦尚未消退时,负责人进一步对你委以重任,让你来出个替代计划。替代计划?你有些不相信自己的耳朵,嘴里嘟囔着:"把现在存到数据库的内容写到 MongoDB 不就成了,我就一个表一个表地替换。难道我还要把哪天替换哪个表列出来吗? "刚刚还对你欣赏有加的负责人,脸色一下子沉了下来。"只有表改写吗?"他问你。你一脸懵地看着他,心里想,"不然呢?""上线计划呢?"负责人问。"我还一行代码都没写呢?"你很无辜地看着负责人。"我知道你没写代码,我们就假设代码已经写好了,看看上线是怎样一个过程。""不是发新版本就好了吗?"你还是不知道负责人到底想说什么。"你能确定新版代码一定是对的吗?"虽然你已经叱咤编程很多年,但作为老江湖,一听这话反而是有些怯的。"不能。"你痛快地承认了。**"一旦出错,我们就回滚到上一个版本不就成了。"常规的处理手段你还是有的。"但数据已经写到了不同的存储里面,查询会受到影响,对不对?"**负责人一针见血。"如果这个阶段采用两个数据存储双写的方案,新代码即便出问题,旧存储的代码是正常,我们还有机会回滚。"你一下子就给出了一个解决方案,咱最不怕出问题了。"对。"负责人认同了你的做法,一副没看错人的神情。"让你出上线方案,就是为了多想想细节。"

出了一个版本,但是负责人又问了,"原有的数据怎么办?"负责人又问了一个问题。你一下子意识到,确实是问题。"没有原有数据,一旦查询涉及到原有数据,查询的结果一定是错的。所以,还应该有一个原有数据的迁移任务。"你尴尬地笑了笑。

把这个问题想清楚了,你重新整理了自己的思路,列出了一个自己的问题解决计划。

1.先从结果的角度入手,看看最终上线要考虑哪些因素。

2.推演出一个可以一步一步执行的上线方案,用前面考虑到的因素作为衡量指标。

3.根据推演出来的上线方案,总结要做的任务。

评论:

项目上线之前,一般都会有一个launch plan, 数据库迁移这种项目,不去考虑上线回滚我认为是设计上的缺失。我们公司的launch plan一般是写成一步一步的checklist, 在上线之前会做同伴审查。

8.你的工作可以用数字衡量吗?

我们前面讨论了各种"终",但通常靠语言定义的"终",或多或少都会存在一些模糊的地方,也就是容易产生误解的地方。而数字却是一个明明白白的"终"。比如,测试覆盖率要求 100%,即便你做到了 99.9%,不达标就是不达标,没什么好说的,说破天也是不达标。

再比如,之前内容我们讲到精益创业时,提到了一个重要的反馈循环:开发(build)- 测量(measure)- 认知(learn)。你会发现,在这个循环中,开发(build)是可控的,认知(learn)必须是得到反馈之后才能有的。所以,这里面最需要我们回答的问题是测量(measure)。而这里的测量,最好的检验标准当然就是数字。

如果换成用数字的方式进行讨论,效果就会更好。有一次,为了改善用户体验,我们准备进行一次主页改版。产品团队希望在主页上加上大量的内容,而开发团队则认为太多的内容会导致主页加载变慢,进而造成用户体验下降。正当这个对话即将进入"空对空"的讨论之时,我们找到了一个测量指标:主页加载速度。只要保证主页加载速度,产品团队就可以按照自己的理解来做调整。于是,一个即将不可挽回的讨论,变成了在一定约束条件下的讨论,双方谁也不再思维发散,讨论就能继续推进了。如果你认同了数据本身的价值,那么再结合"以终为始"的理念,我们就应该在着手做一件事之前,先来想怎么去测量。无论是在讨论产品特性,还是功能开发,"信口雌黄"是容易的,落到数字上,人们就会多想一下,这是对彼此的约束。

我的一个同事有个观点非常值得玩味,他说,从数字上看,好的系统应该是"死水一潭"。我是赞同这个观点的,因为出现波动尤其是大幅度波动,又不能给出一个合理解释的话,就说明系统存在着隐患。而让系统稳定,正是我们工作的一个重要组成部分。

9.迭代0,启动开发之前你应该做什么?

一般来说,第一个迭代周期就是迭代 1,然后是迭代 2、迭代 3,依次排列。从名字上你就不难发现,所谓迭代 0,就是在迭代 1 之前的一个迭代,所以,我们可以把它理解成开发的准备阶段。既然迭代 0 是项目的准备阶段,我们就可以把需要提前准备好的各项内容,在这个阶段准备好。事先声明,这里给出的迭代 0,它的具体内容只是基本的清单。在了解了这些内容之后,你完全可以根据自己项目的实际情况,扩展或调整这个清单。

1. 细化过的迭代 1 需求

一个项目最重要的是需求,而在迭代 0 里最重要的是,弄清楚第一步怎么走。当我们决定做一个项目时,需求往往是不愁的,哪些需求先做、哪些需求后做,这是我们必须做的决策。迭代 0 需要做的事,就是把悬在空中的内容落到地上 。在需求做好分解之后,我们就会有一大堆待开发的需求列表。注意,这个时候需求只是一个列表,还没有细化。因为你不太可能这个时候把所有的内容细化出来。如果你做过 Scrum 过程,你的 backlog 里放的就是这些东西。然后,我们要根据优先级从中挑出迭代 1 要开发的需求,优先级是根据我们要完成的最小可行产品(minimum viable product,MVP)来确定的 ,这个最小可行产品又是由我们在这个迭代里要验证的内容决定的。一环扣一环,我们就得到了迭代 1 要做的需求列表。确定好迭代 1 要做的需求之后,接下来就要把这些需求细化了,细化到可执行的程度**。前面讲用户故事时,我们已经说过一个细化需求应该是什么样子的,这里的关键点就是要把验收标准定义清楚**。

如何让用户用着舒服,这是一门学问。我们在市面上看到很多难用的网站或 App,基本上都是程序员按照自己习惯设计出来的。现如今,我们可以很容易地在市面上找到画原型的工具,某些工具用得好的话,甚至可以达到以假乱真的地步。如果能再进一步的话,甚至可以用一些模拟服务器的工具,把整个交互的界面都做出来。作为 Moco 这个模拟服务器的开发者,我很清楚,一个原型可以达到怎样的高度。所以,一个有用户界面的项目需要在迭代 0 中给出用户界面和用户交互。

技术方面

技术方面,需要在项目一开始就准备好的事比较多。其中有一些是你很容易想到的,比如:在进入迭代 1 开始写代码之前,我们需要确定技术选型,确定基本的技术架构等等。也许你还能想到,数据库表结构也是这个阶段应该准备的。

持续集成

对于持续集成,我们通常的第一反应是搭建一个持续集成服务器。没错,但还不够。这里的重点其实是构建脚本。因为持续集成服务器运行的就是构建脚本。那要把什么东西放在构建脚本里呢?最容易想到的是编译打包这样的过程。感谢现在的构建工具,它们一般还会默认地把测试也放到基本的构建过程中。但仅有这些还是不够,我们还会考虑把更多的内容放进去,比如:构建 IDE 工程、代码风格检查、常见的 bug 模式检查、测试覆盖率等等。持续集成还有一个很重要的方面,那就是持续集成的展示。为什么展示很重要?当你的持续集成失败时,你怎么发现呢?一个简单的解决方案是:摆个大显示器,用一个 CI Monitor 软件,把持续集成的状态展示在上面。更有甚者,会用一个实体的灯,这样感官刺激更强一些。

测试

测试测试是个很有趣的东西,程序员对它又爱又恨。一般来说,运行测试已经成为现在很多构建工具的默认选项,如果你采用的工具没有这个能力,建议你自己将它加入构建脚本。让你为一个项目补测试,那是一件非常痛苦的事,如果在一开始就把测试作为规范加入进去的话,那么在边开发边写测试的情况下,相对来说,写测试痛苦度就低多了,团队成员也就容易遵守这样的开发规范。

大多数团队提起测试,尤其是开发者测试,多半想到的都是单元测试和集成测试。把整个系统贯穿在一起的"端到端测试"却基本上交给其他人来做,也有不少团队是交给测试团队专门开发的特定程序来做。在今天的软件开发中,有一些更适合描述这类测试的方法,**比如 BDD,再比如 Specification by Example。你可以简单地把它们理解成一种描述系统行为的方式。还有一点做得好的地方是,有一些软件框架很好地支持了这种开发方法,比如 Cucumber。**如果你有这种测试,不妨也将它加入构建脚本。

数据库迁移

如果你做的是服务器端开发,多半离不开与数据库打交道。只要是和数据库打交道,强烈建议你把数据库变更管理起来。管理数据库变更的方式曾是很多团队面临的困扰。好在现在已经有了很多工具支持,比如,我最近喜欢的工具是 flyway,它可以把每一次数据库变更都当作一个文件。这样一来,我们就可以把数据库变更放到版本控制工具里面,方便进行管理。管理变更有几种不同的做法,一种是每个变更是一个文件,一种是每一次发布是一个文件。各有各的好处,你可以根据需要,自行选择。

发布

技术团队擅长做功能开发,但上线部署或打包发布却是很多团队在前期最欠考量的内容,也是很多团队手忙脚乱的根源。如果一开始就把部署或发布过程自动化,那么未来的生活就会轻松很多。如果你采用的是 Docker,就准备好第一个可以部署的 Dockerfile;如果是自己部署,就编写好 Shell 脚本。其实你会发现,上面提到的所有内容即便不在迭代 0 做,在项目的各个阶段也会碰到。而且一般情况下,即便你在迭代 0 把这些工作做好了,后续依然要不断调整。但我依然建议你在迭代 0 把这些事做好,因为它会给你的项目定下一个基调,一个自动化的基调。

2.任务分解

1.向马斯克学习任务分解

2.测试也是程序员的事情吗?

3.先写测试,就是测试驱动开发了吗?

4.大师级别程序员的工作秘籍

5.手把手带你分解任务

6.为什么你的测试不够好

7.程序员也可以砍需求吗

8.需求管理:太多人给你安排任务,怎么办?

9.如何用最小代价做产品?

3.沟通反馈

1.为什么世界和你理解的不一样

2.你的代码为谁而写?

3.轻量级沟通:你总是在开会吗?

4.可视化,以一种更为直观的方法去沟通

5.快速反馈:为什么你的公司总是做不好持续集成

6.开发中的问题一再出现,怎么办

7.你应该聆听用户的声音

8.尽早暴露问题,为什么指责的总是你

9.结构化,写文档也是一种学习方式

4.自动化

1.懒惰应该是所有程序员的骄傲

2.一个好的项目自动化是怎么样的

3.程序员怎么学习运维知识

4.持续交付:有持续集成就够了吗?

5.如何做好验收测试

6.你的代码怎么变混乱的

7.你的代码是怎么变混乱的

8.总是说MVC架构,你真的了解分层吗?

9.为什么总有人说5w块钱就能做成淘宝

10.先做好DDD再谈微服务

相关推荐
zzzzzz3102 天前
9K Star 炸裂开源!这个 C 语言写的代码知识图谱,把 Linux 内核索引压缩到了 3 分钟
linux·服务器·sql
XIAOHEZIcode2 天前
Linux系统鼠标偏移常见原因以及修复方案
linux·运维·游戏
用户0328472220702 天前
如何搭建本地yum源(上)
运维
大树885 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠5 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质5 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
小宇宙Zz5 天前
Maven依赖冲突
java·服务器·maven
Inhand陈工5 天前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信
酣大智5 天前
ARP代理--工作原理
运维·网络·arp·arp代理
shushangyun_5 天前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化