成为管理者之前和之后我都做了些什么

我是如何成为管理者的

Posted by Lnn on April 20, 2023

加入新公司不久之后,我很快参与到了 LeanCloud 的即时通信、消息推送这两个服务从 Clojure 向 Golang 和 Java 的重构中,是 RTM 小组的负责人。

不久之后团队接手了一个坑比较多业务和一部分移交过来的人员,直属 Leader 和我沟通之后让我参与到这个团队的组建之中。

bigshit

从实际情况出发,先了解再参与

了解的方式途径包括沟通、观察、代码等等,回过头去看这是当时对团队现状列的一些描述:

  • 线上故障频发
  • 需求、版本管理混乱
  • 有着比较差的工程实践
  • 团队人员能力相对比较差,缺乏资深工程师
  • 历史遗留比较重

更具体的比如,这个业务交接过来的第二天就出了线上故障,此后陆陆续续有出了几个线上故障,后端系统没有任何业务 metirc 无法知晓系统状态,甚至部分代码仓库只使用两个固定分支进行迭代,需求管理混乱等等。

作为参与者如果希望重构代码,那么首先就应该熟悉代码;如果希望做架构改动,那么就应该先熟悉架构。如果希望故障能够尽快得到解决,那么即使一开始不熟悉代码,也应该积极参与到故障排查和故障善后中去。总得来说,想改善什么先去了解和参与效率会更高。

主动做沟通

信任是有效沟通的前提,当彼此不信任的时候,很多时候沟通没有效果的。

如果你想推动一些事情往前走,主动沟通是避免不了的。很多时候一些误会或者不理解都是因为缺乏沟通引起的。这里包括和研发、QA、产品,以及合作伙伴等等同事的沟通。我个人比较喜欢和同事保持一定频率的 one-on-one, 主动与下属同事沟通以解决 TA 们的困惑,和产品、运营等沟通获取 TA 们的预期争取 TA 们的支持。

赢得信任

保证你想法在团队里能得到实施一个关键是,大家都信任你。一旦大家都不信任你的时候,又或者是你不信任自己的时候,那么这个团队就会出现问题。而 信任感是需要我们一步步地去构建出,从一次次小的成功中去获得。 通过多次小规模的改动和优化帮助其他同事可能是一个很好的切入方式。

持续且渐进的工程改进

任何新方案的实施都要以对现状的理解为基础 , 比如说现有的组织结构、对新方法的接受度、具体的业务特征、技术成熟度等。脱离具体的上下文,照搬“普适”的框架,会带来巨大的适配成本。前期花费大量精力在组织和流程上,却不直接改善交付效能,特别是业务可见的效能。这非常容易带来怀疑和抵制,让实施效果大打折扣,甚至半途而废。

从现状出发,寻求持续且渐进的改进。这是我在故障频发期间采取的策略,当然头脑里对我们需要走到哪一步会有一个大致的路径,在系统改进目标的牵引下,以小步前进,每个小步都带来改进,最终实现系统和全面的转型。渐进不是妥协。恰恰相反,它是在明确且坚定的最终目标下选择更坚实和可持续的路径。改变必须从理解和尊重现状开始。

接手团队的前两个月基本在左冲右突的救火,之后伴随着很长时间的持续且渐进的改进。比如支付系统在支付成功通知下游时的调度任务是纯内存的,机器一重启就缺失了只能手动去排查和重推。于是我把对下游的通知任务改为放到 MQ 里,这样即使机器重启通知也不会有缺失和延迟。

小步重构

不管是代码层面还是架构层面的改造优化都采用的是小步重构,在满足新需求的同时逐步做一些代码层面的重构。

在架构层面则更为谨慎,比如支付系统的到账通知对下游业务系统的回调,原来是存储在服务器本地内存中的一旦系统重启就不会再自动重推了。之后我把到账回调进行了持久化,并引入了 RocketMQ 进行异步通知。这一改动从写设计文档、方案讨论、编码、测试所使用的时间并不长,但是灰度的过程却相对比较谨慎。

在小步重构的过程中要分清主次、短期中长期目标,不要过早的优化。比如先消除系统里的故障隐患,再推进性能优化等等。

代码评审和自动化测试

我们如何做代码评审提到团队现在实施着严格的代码评审以及一定程度的自动化测试,但是这个过程并不是一蹴而就的。

交接过来的业务团队从来没有实施过 code review 制度,那么想要推行严格有效得 code review 是比较困难的。这时候可以先从做好自己开始,比如从把自己的代码发给别人 review 开始,分享一些自己案例,当遇到有意思的讨论也可以发出来让更多的人参与进来讨论,实际可见的参与感或者价值是最有说服力的。

而自动化测试,也是从:先有第一个自动化测试用例 -> 先有覆盖几个登录、支付核心接口 -> 全面覆盖登录、支付核心接口 -> 覆盖所有核心接口这样的过程,并且我们并不在是更多采用单元测试和采用集成测试上纠结,而是寻求根据实际情况逐步调整的过程。并且最重要的是能够自动化

推行适当的文档文化

文档是非常重要的工具,能够全面、准确地记录项目信息,促进团队成员之间的沟通与合作。

对于架构设计、数据结构设计、前后端接口设计等都需要在 Confluence 上写好文档,并与相关的同事讨论特别是与代码评审的同事提前达成设计上的一致。设计文档应该贴在 Megre Request 的描述里,方便以后代码评审以及后继维护。

鼓励团队成员在撰写文档时进行协作。例如,一份文档可能由多个人共同编写,然后由一个主要的负责人进行审查和最终编辑。

好的文档应该具有清晰、简洁、及时更新、协作等优点。文档应该是有时效性的,如果文档涉及到某个产品或功能的版本信息,还应该包括版本号。如果文档已经过期了或者暂时还未完整则应该在文档内说明。虽然技术设计文档写在了 Confluence 上,但是我们希望所有的文档都可以通过 gitlab 的 wiki 找到,当然可以直接链接到 Confluence 上。

尽管代码评审、自动化测试、文档文化在软件工程上已经被无数历史案例证明了它们的作用, 但我向来反对不尊重现状和团队需要的工程实践,还需要考虑到业务的特性、团队成员的能力、我们所拥有的和缺失的,选择合适的时机去实践。这些工程实践需要团队管理层的支持也需要团队成员的坚持,作为 Tech Lead 在 hands-on 的过程首先应该自己做到表率的作用。

和团队一起制定 OKR、RoadMap,持续投资重要且有价值的事情

研发上的混乱很多时候是团队没有一致的目标导致的,也很容易导致在不断地临时性需求中迷失。而且作为上游服务,没有计划性也让下游的需求方缺乏安全感。

因此在我成为团队管理者之后每个季度都会和团队、产品、运营、外部合作方一起制定 OKR, 制定年度 roadmap。每个人的 OKR 都是公开且可评论的。年度 roadmap 放在 Figma 上供大家查看和评论,并及时同步给上下游。

制定 OKR 和 roadmap 也让我们可以持续投资重要但不紧急的事情,比如自动化测试、把手动类的事务自动化掉、历史遗留消除计划。这样事情从长期来看都是非常值得投资的,也是我们提高效率的方式之一。

改进版本管理和需求管理

在需求管理上需要和产品经理更多的沟通,在产品能力的建设上还有计划性和持续性。临时性的需求往往是紧急的,但也容易让我们迷失。还是应该在一个季度或者半年回头看的时候,能够看到产品上有明显的积累。

有了 OKR 以及 roadmap 之后,也让版本管理变得更主动一些,可以看到我们的版本更新日志。我们基本保持半个月一个小版本,一个半月一个大版本的频率,当然这个频率并不总是固定,还是要看团队实际的情况。

争取尽可能多的支持

  • 搞清楚上级的期望:过去的一年里,我一直和直属 Leader 保持每个月至少一次 one-on-one, 及时同步彼此的预期,讨论一下我关于团队管理上的困惑以及困难。也及时争取有一些应该争取的支持。

  • 文档:和技术支持团队沟通把对外支持和答疑交给技术支持,在日常中让研发同事的时间不被分割的过于零散。文档的主要内容依然由研发来负责,但是文档的改善交给技术支持。并和技术支持团队的主管保持每个季度至少一次沟通,和对接的技术支持同事保持每个月至少一次沟通。
  • SRE:和 SRE 团队沟通把更多的业务运维的事情交给 ops 同事,降低研发在 ops 上的投入。

适当的时候强势一些可能是必要的

知乎上有个问题为什么管理者要多听团队的想法, 听取团队的想法这当然很重要。在我们团队也鼓励坦诚沟通,尊重一线同事决策权的文化。但是很多时候为了提高决策的效率,适当的强势是有必要的。以下是我暂时想到的一些场景:

  • 团队 RoadMap 的最终制定
  • 需求管理混乱时
  • 出故障时
  • 有较多临时性需求时
  • 技术架构无法达成一致时
  • 研发流程变动时

特别是出故障时我会侵入一线工程师的职权和细节里,以保证故障能够得到及时处理和响应;需求管理混乱时我会侵入到产品经理的职权里,让产品需求更有规划性一些。当然这会在和他们沟通好的前提下,而且会充分尊重各自的职业分工范围。

在适当的时候强势一些实际上是一种无需任何歉意的“贵族专制统治”,这也是组织赋予你作为团队管理者的权利。

意外总会发生的,重要的是如何面对

现实总是残酷的,即使做了一些努力,做了一些改进。但是可能短时间内看不到直接的效果,也有可能是做的方式不对。你可能依然会遇到线上故障,也会遇到外部的质疑或者来自上级的压力。作为团队的管理者,如何及时处理故障然后做好事后总结,如何和外部伙伴沟通赢得改善的机会可能更为重要。

一句话:出了事,作为团队管理者不能怯懦!

适当放权

客户端放权:虽然我有过写一些 Android Demo 以及 iOS Demo 的经历,但是在客户端方面我并不是一个合格的工程师,而且短时间内也很难在这方面有快速的补齐。因此在团队稳定之后决定把客户端的协调的工作交给了一位比较有潜力的客户端同事,TA 负责客户端接口以及架构相关的决策以及对外的客户端问题沟通。在客户端方面除了版本计划、架构设计、代码评审等为了保持对业务的熟悉我会略有参与外即使是这些事情更多的也是客户端小组的负责人来跟进,绝大多数的事情我并不会直接干预。

服务端的稳定性是团队的核心任务,因此我对服务端的关注以及实际 coding 也更多。我依然保持每周都有代码提交,跟进一线研发需求。

一个团队管理者能力再强,也无法只通过一个人的能力做完所有的事情。如何适当的放权,是所有管理者应该不断学习的一项能力。

让不合适的人尽早离开

在团队相对稳定之后我决定让其中一位同事离开,可能这出乎一部分人的意料。大部人觉得当团队主管不久应该求稳以及当老好人是更好的选择。

主动裁人可能是一个非常痛苦的过程,但是对于管理者来说可能又是必须经历的事情。不合适的人在团队里可能确实起到一个人力的作用能干一些活,但是却可能拖累团队,同时也容易让优秀的人更加容易离开。因此当发现一个人真的不合适团队的时候,应该尽早考虑和安排让 TA 离开的计划。

当然发现一个人是否合适团队是一个持续观察的过程,同时也应该侧面关注和 TA 协作的同事对 TA 的评价,征求直属 Leader 的看法等等,而不是单纯的从管理者自己个人的情绪或者短期的主观判断。在技术能力、业务理解、团队融入、外部沟通这些方面综合考虑之后做的决定。

如果最终决定要做汰换 , 可以:

  • 考虑清楚汰换的计划,汰换的前提是尽量不影响业务的推进以及团队的士气
  • 和上级主管、部门 HR 沟通好汰换的计划
  • 推进招聘,补充新鲜血液
  • 让新人逐渐融入
  • 和被动离开的同事做沟通,这个过程可以让 HR 来推动,但是提前双方能够”和平分手“
  • 主动和团队的核心成员沟通,告知被动离开同事离开的时间和原因,这更多是为了稳定团队士气

不合适团队的人并不是表示 TA 不够优秀,也并不意味着和被动离开的同事成“敌我”双方,更多的是双方不匹配,所以在沟通上我们还是应该尽可能地争取”和平分手“,该为离开同事争取的利益就应该主动和公司以及 HR 争取。

把事情做好,好的结果是顺其自然的事情

把一个混沌的系统治理到相对不那么混沌的状态并不是一朝一夕的事情,也不可能只可通过做一两件事情就做到。

从故障频繁到系统相对平稳,之后一个季度无故障,然后连续半年无故障。这个过程需要团队所有的人共同努力。

wtf-per-minute

到了年底被直属主管和部门负责人提名年度优秀员工

wtf-per-minute

然后被评选为 100 多人的大团队里唯一一个年度优秀员工

youxiu

一个员工在原有职级上想要往上晋升,可能需要两到三个季度持续表现出上一个职级的能力才可能获得机会。很多时候我们会过分地纠结于是先付出还是先得到,但这样的犹豫可能会很容易让机会溜走