我的轻敏捷技术管理方法论

最近两年一直在从事技术管理方面的工作,这一路走来有很多思考和收获,也犯了很多错误。我们讨论的是技术管理,从某种程度上说是工程领域的一种实践。而在我理解的工程的本质是在我们这个不断熵增的社会里寻求一定程度的熵减,从无序中构造出有序,将人的思考和专业能力转化为产品的过程。因其熵减的性质,注定是一个复杂的过程,以一切特定的方法,需要组织一群人,经过长久持续的努力才能实现。在这里对技术管理中有效的管理工具、方法做一个思考和总结,我称之为轻敏捷技术管理

技术与管理

一直以来我比较认同一个观点,即理科、技术 是零和一的问题。如果一段程序work,那么他就是work的,就是 1;如果他不好用那么他就是不work的,就是零,这是计算机创造的一个模型清晰、黑白分明的世界。而对于文科领域(管理、社会、经济、艺术)而言则没有那么绝对,一个新想法,关于历史、政治、管理等,需要经历长久的时间才能看出效果。很多时候,在这些领域的两个不同的方案,我们是很难一下子看出他们之前优劣,相当于对于文科的 0 和 1 之间存在无数的 点,方案和方案之间有无数的空间。

这需要我们头脑中处理事情的底层逻辑发生转变,这种变化对于一个从基层技术人员,转型为技术管理者,一开始都会有很多不适应。我们处理的不只是机器的是或非的问题,而是面对一个复杂的真实社会,使用的也是跟之前不是很相同的技能栈。

适应变化的管理风格

针对不同规模、周期的团队管理需要使用不同的管理方式。我的上一家公司是一家比较成熟的企业,内部的开发流程有比较完整的定义,虽然能极大避免项目开发的不确定性,但从某种程序上来说也限制开发者的某种自由。而这种自由正是我当时所追寻的。所以我在开始从事管理工作时,在团队中推行一种偏左的硅谷式的"工程师文化",给予工程师以极大的自由去写符合自身期望的代码。但是随着时间的增长,交付日期的临近,我发现这种方式:没有完整的测试、上线流程会极大的影响项目进度,导致代码风格不同意、项目无法按时交付、交付后线上问题较多,影响客户使用。

进而我开始总结经验,整体的管理风格越来越转向另一侧,把之前被我抛弃的各种流程和管理方法逐渐加了回来,整体的项目可控性提高了不少。

正如王国维讲的:有我之境和无我之境。我们每个人思考的时候都会头脑中构建出一个虚拟的世界,但这终究只是一个现实世界的不完全模型,现实世界是个动态的过程,我们很难把全部因素都考虑进去。那么在面对这种动态问题时,我们该怎么办?最近对中庸的学习和理解中给我打开的一条新的思路,作为中国古代经典,中庸在我之前的理解中就是保持中间位置,不左也不右。但孟子说:

子莫执中,执中为近之,执中无权,犹执一也

就是说,如果执着与追求走中间道路,那么跟执着于左 或者 右又有什么区别呢?我们要理解对于不同的组织和公司、不同的团队和项目,管理上不可一概而论,对于同一个团队的不同阶段也是如此。在团队、业务的创始阶段,我们需要偏向保守,扶植业务、流程走向正轨,而后逐渐偏向自由开放,给予团队最大的自主性产生创新。中庸不是让我们固守中间,而是根据事物动态的发展而动态的调整策略,正所谓极高明而道中庸。

理解人与人的大不同

我在这一年多的管理生涯中犯的第一个错误就是认为人都是可以培养的,我不认为任何人本质上有什么差别,先天上人与人之间智力的差别很有限,更多的是一种在后天的培养中逐步养成的性格、习惯,在由此迸发出的对专业知识的兴趣和理解。简单来说,就是人和人都是相同的,都是可以培养的。但后续事情的发展让我逐渐理解了人和人其实是很不一样的,优秀的人和平庸的人之间有天壤之别。优秀的人才处理事情事半功倍,而平庸的人处理就事倍功半。在软件开发领域尤其如此,所以我们要尽最大的可能招到最优秀的人。

简而言之,20000美元/年的程序员的生产率可能是可能是10000美元/年的程序员的10倍 —— 《人月神话》

态度也很重要

有一次和一个朋友交流时提到,你们面试那么严,问的问题在工作中都会用到么?明明网上搜一下就有答案,只是根据人有没有背网上的答案确定一个候选人能力的高低吗? 他的回答比较触动我:如果候选人把网上的问题都背下来的,至少证明他愿意为了这份工作花一些功夫,可以证明他至少态度是正确的。

我们在工作中遇到遇到的一些事情不会很简单,处理起来需要耐心、责任心、价值观和刻苦的工作。有些人能力很强,但是不愿意为进入一家公司多背几道面试题,那么你怎么能保证他在进入到你的公司之后在工作上的处理也是有正确的价值观和责任心的呢。

我们曾不止一次的听到过这样的事情,某编程大神面试 Google / Facebook 因为一道算法没写上来被拒。很多时候,一个大型组织需要的其实不是非常有个性、有自我认知和独立思考的人,这样的人非常不好管理。他们需要的其实是最符合他们价值观的人中,最聪明的那些人。就算一个人有多么多么牛逼,他的行为不符合这个公司的价值观,能带给公司的价值也会比较有限,甚至可能会提高管理的难度。

正如 兰迪·波许 说的 每一个困难都是挡在你面前的一堵高墙,但墙之所以存在,不是为了阻拦你,而是为了激励你,墙是想检验你到底有多想要墙背后的东西,是为了阻拦没那么想要的人

但是对于创业公司、团队,情况似乎又不太一样,大神是可以带起整个团队的节奏。所以关于这一点我们需要根据团队的情况动态平衡。

量化招聘 候选人考察算法

从之前我去其他公司面试的经验来看,一个公司的面试题难度与这家公司在该领域的专业度成正比。一个在某领域非常专业和优秀的公司的面试题难度一定是比较高的。从逻辑上来说:优秀的人会成就了优秀的业务,同时优秀的业务会吸引优秀的人。所以我们能看到一线大厂的面试题总是比较难。但我觉得现在的互联网技术团队面试总是过于关注技术领域,一个人是不只有技术的一面,我们更应该对候选人做全面的考察。

我认为对候选人的考察应该包括以下几个方面:

  • 专业能力 60分

  • 逻辑能力、复杂事物思考能力 20分

  • 团队配合、耐心、责任心、稳定性 10分

  • 学习能力 10分

专业能力

在技术面试中,对算法和一些基础技术问题的考察一直是大厂面试受人诟病的一点,正所谓 "面试造火箭,入职拧螺丝"。但一方面,这些具有上面阐述的对于价值观考察的重要价值,另外一点,算法的确是我们日常编程的基础能力。关于一些树的相关算法操作在日常工作中是会经常用到的,算法锻炼的是人的一种思维模式,以最高效、简洁的方式解决不同的问题,所以对于算法的考察是合理并且必不可少的。

非专业能力

对于除技术专业度的其他层面的考察,网上有很多测验题,我们可以动态的调整几种基础能力的权重,形成一种算法。比如对于应届生而言,专业能力就显得不那么重要,而其他方面是我们决定是否要录用和培养的关键;对于一个资深工程师而言,我们期望的是他的专业度可以带给团队不一样的公司,那么专业度的分数就需要提高。

关于这方面的工具,北森的一套人才测试系统是一个很好的方案,里面会选择几百道测验题,包括逻辑能力、心理测验等多个方面,虽然需要候选人花些时间,但是可以帮助我们更全面考察候选人。

技术团队的组织形态

随着业务的发展,我们承接的项目会越来越多,团队的规模也会逐步扩大,在我经历过的技术团队中,主要分为两种组织模式,一种是按照技术栈管理技术成员,即前端组、后端组、测试组、运维组、产品组,每个组配备组长,当一个新任务过来,前端组组长从前端组中挑选人员,后端组组长从后端挑选人员,组成一个临时的项目组进行开发,项目上线后,整个项目组被打散,接下一份需求。而以项目划分的团队以项目经理牵头,其中包含为这个项目组所需的全部技术人员 及 产品经理,长期维护、迭代一个项目。

技术栈模式

  • 研发资源得到充分利用,有人协调技术栈的全部研发资源,一旦有新的任务,可以从全部资源中调配

  • 技术栈相对比较统一,技术栈有统一的领导,技术栈和技术选型比较容易把控,相对来说可以避免技术选型的混乱情况

  • 技术人员针对项目没有长期维护的心态,不同项目在不同阶段的维护人员可能不同,导致项目代码没有统一的、长期的规划

项目组模式

  • 有利于项目的长期维护、迭代

  • 技术人员对项目有长期维护的预期

  • 项目组更易于对项目的成长及产出,可量化的和非可量化的部分进行衡量

  • 容易造成一定程度的超额配置,研发资源冗余

技术团队的这两种组织形式各有各的优缺点,对于组织形式的选择有两个主要因素:项目周期、成本限制、技术复杂度。比如项目周期较长的项目选择项目组的形式比较好,对成本比较敏感的团队选择技术栈的形式比较好。抛开其他的因素对我来说最理想组织形态是:技术人员分为两条线,主组织架构按照业务/项目组划分,其外设定虚拟组织架构,按照技术栈划分,每个项目组由项目中需要的各个技术栈成员、产品经理、项目经理组成。各个技术栈成员又分别隶属于按照技术栈划分的虚拟组织架构,即前端、后端组的架构师/基础架构团队的管理。这样既保证了技术栈的统一性,又保证项目可长期迭代。

完美主义的悖论

有一些同事极度重视代码质量,不仅自己努力写出及其优秀的代码,而且要求团队所有成员也按照最高标准执行。虽然想法是好的,但是和现实充满冲突。现实情况中,很多时候我们都需要为了业务进度,而在技术层面不得不作出一些妥协,有的时候虽然表面上是优秀的代码。实际上因为过于关注代码细节而耽误了整体的进度,最后造成的结果就是整个项目每个细节都是完美的,但最后放到一起却无法使用。一个无法work 的项目对业务来说是无用的,归根结底,我们是做技术的,技术是要为业务服务的,就算技术代码写的在完美,设计的在美好,无法完成业务上的目标对于公司和团队来说也是无价值的。当然,完全不考虑质量也是极其错误的。这也是第一节中讲到的权变的作用,管理上很多时候我们都要寻求一种动态平衡,既不能太左也不宜太右。

轻敏捷方法论

我对于完整敏捷开发流程的感觉是冗余和形式化的,也很少见现在的技术团队推广完整的敏捷开发流程。在敏捷的基础上,结合一些经验,梳理出一些对技术管理有帮助的小技巧,我称之为轻敏捷

业务理解

  • UserStory:产品同学需要站在用户的角度讲出用户故事,帮助技术更准确的理解产品需求

  • 领域建模:数据库模型是后端的一大基础工程,在开始一段新需求之前首先要对业务实体模型进行设计。另外,对业务领域模型的分析可以实现核心业务逻辑与技术细节的分离,对需求的理解更为透彻

进度跟进

  • 看板:看板的核心功能就是让团队成员了解自己的任务,让团队管理者了解大家的任务。让所有人了解项目的整体进度,并且可以作为量化考核的一个工具。看板有一个关键的点就是卡片的任务拆分,我个人比较倾向于任务拆分越小越好,最小以天为单位,最大单个卡片不能超过一周工作量,以三天为宜。如果一张卡片连续一周多没有移动,那么肯定是出了什么问题。并且要鼓励大家自己去维护自己的卡片,这样让所有人对进度有个了解。

  • 晨会:参会的目的是 跟进进度、及时发现问题,有些团队是一周开一次周会,我不太认同这种时间周期。因为有些问题可能随着周的这个时间维度才能暴露出来的,而对于一个互联网团队来说,这种速度是非常影响进度的。每次一次会,让问题今早暴露出来,大家一起寻找解决方案才是正确的处理之道。

  • 周报:周报的基础内容就是本周工作、下周工作、遇到的问题和挑战。但是我更希望从我的团队的周报中看到的是一种学习和成长,周报是一周的工作的总结,如果你每周都能总结出本周的学习、思考和收获,遇到的问题与解决的办法,那么累计几年,这些周报就是一种财富。

质量管理

  • CodeReview

  • 必要且适当的代码Lint:Lint 规则可以适当严格,统一大家的编码风格,防止一些用法上的错误。

  • 文档化:文档化一般来说对于通用组件、基础架构团队比较重要,但是对于一般的业务技术团队来说,只要涉及人与人沟通的层面,那么文档化就是不可或缺的一个部分。文档的核心一定要简洁精炼,站在使用者的角度编写文档。在我看来必不可少的文档有:

    • README.md:介绍项目主要功能,技术选型以及各个环境启动模式

    • CONTRIBUTING.md:这个文档在开源项目中非常常见,主要介绍如何给该项目贡献代码、git 工作流、项目代码风格等

    • 接口文档:这个对于前后端分离项目是不可或缺的,描述接口的定义、功能、参数和返回值

    • 数据库模型设计文档:参见业务理解的领域模型部分,这里推荐一个代码化的画图工具: plantuml

    • 前端组件库文档:前端经常复用的 UI 及 业务组件的文档

  • 设计资源统一:这部分是对前端同学来说的,我们需要将全部的 颜色、长度 统一起来配置化,将项目中所有可能用到的 ICON、资源、字体 统一实现方式。避免同样的代码写的到处都是,也可以方便换肤等操作

自动化

为什么信息革命能提高我们生活中各个方面的效率,就是因为原先需要人去处理的任务,现在机器自动的去做了。我们做的软件就是自动化的一种工具。自动化是一种大趋势,我们在学习计算机底层原理的时候就会发现,从与或非们到逻辑元,从 ALU 到 CPU,从C语言 到 Java ,整个计算机科学 软硬件的底层逻辑就是一层叠一层的不断进行抽象,一步步更加自动化、智能化 的 大趋势。所以一些有效的自动化是值得推荐的,对于一些大型的开发团队,更是有专门的工程效率和基础架构部门专注于研发这些自动化工具提高开发效率,这里列几项常用的工具。

  • 持续集成

  • 容器化

  • 关键业务的自动化测试:对于全部代码都走自动化测试所需要付出的成本是极高的,不如我们只针对核心的业务流程做自动化测试,保证一些常用的、常改的、核心的业务流程不会因为某次修改而出现意想不到的问题。

  • Git PreCommit:方式不符合标准的、甚至有错误的代码侵入污染代码库的一种自动化的策略,PreCommit 规则在我看来和 Eslint 一样,可以适当的严格一点,还有就是针对 commit message 要有固定的格式要求。

团队成长

  • 适当的开源:开源的好处不用多说,我们做工程的本质上会有一种希望自己的成果被更多人使用的期望,所有适当的开源,会提升大家的积极性,更努力的写出更好的代码。并且开源项目有更多人使用,从产品层面会使得产品更加健壮。另外开源也是培养工程师文化、吸引人才的一个重要的途径。

  • 技术分享:技术分享对做分享的那个人会有很大的提升,技术方面会有一定的总结、沟通交流方面也会有一定的锻炼。定期轮流的做技术分享

  • 项目复盘:关于复盘,我在另外一篇文章中有一些推荐的复盘小技巧(高效能的小技巧

  • 必要且适当的重构:这里加上了 必要且适当 作为修饰,重构总是痛苦的,因为之前的代码尽管各种不好,还是考虑的很多东西。要想把这块重新写一边就需要把这些东西重新考虑一遍。但是重构在某种程度上又是必要的,他是项目、团队精进的一种重要的方式。尝试不断的优化同一个功能,使其代码逻辑变得越来越清晰、运行速度越来越快 可以帮助大家学习更多。

团队建设

  • Backup:对于关键人员的 Backup 安排对于业务稳定至关重要,马云说得好 晴天修房顶,这一部分临阵磨枪是来不及的,尤其需要提前规划。团队中核心人员的 Backup 以及 作为 Leader,你自己的 Backup。对于下级的培养其实是可以毫无保留的,我之前的领导说的一段话印象特别深刻:做管理者要有格局,你培养出来一个经理,你就是高级经理,你培养出来一个高级经理你就是总监。

  • TeamBuilding:我理想中的团建间隔为半年一次,半年时间,让大家停下匆匆的脚步,观察下彼此还是很有帮助的。

  • 1v1 Talk:TL与团队成员的 1v1 以两个月为宜,可以及时发现成员的心理变化和想法,对稳定和建设有事关重要的作用。

越写篇幅越长,感觉要是每个点都展开,完全可以写成一本书了。总的来说,技术管理不是一个一成不变的事情。随着技术的演变、业务的发展、团队的变化需要动态调整的一个过程,我们需要根据事物的变化时左时右,不断的寻求某种平衡,保证团队和业务的发展。本文之后会持续维护,不断加入一些新的管理方法。但求精进,无问西东。

2020.04.11