在贵司的工作经历:

  • 2021/6 - 2022/2:实习
  • 2022/7 - 至今:

毕业后,2022 年 7 月 2 号入职贵司已经快两年了。从实习开始算的话,已经三年了。这三年来

  • 我做了什么?
  • 我到底学到了什么?
  • 我变成什么样了呢?
  • 我是如何改变的?
  • 我的状态符合两年前、三年前我自己的预期吗?
  • 我未来将走向何处?

借着这次转组的契机,我尝试对自己进行一次中期的总结和记录。

工作到底做了些啥

此部分是个人流水账

2021/6 ~ 2022/2

实习期主要是参与 TiDB Data Migration(DM)的开发的维护,主要和 MySQL 的 binlog 打交道。

其中一个大的工作就是重构一部分 syncer 模块。在修这个 pr 的时候,瞅着增量同步那一块主流程代码怎么看怎么不爽,各个函数含义不清,完全不知道要怎么改。。。所以直接来了一波重构(track issue),当时的 mentor(Lei 哥)竟然直接同意我这个菜鸡做了😂。一干就是几个月。。。从此对重构远古代码的人产生了敬畏之心。

另一个大的工作是优化 DM 的 precheck 功能(track issue)。这是我第一次尝试 own 一个单独的项目,也是第一次写真实使用的并发代码。虽然是一个小项目,但对我来说意义非凡,算是我步入软件工程领域的起点。之前我是真不会呀,太菜了呜呜呜😭。纪念一下第一次写并发代码(https://github.com/pingcap/tiflow/pull/3975 ,139 个 conversation😂)。

其他各种杂活

  • 当时测试团队搞了一个自动化测试平台,我被安排去趟坑,把脚手架什么的搞定,写了几个基本的 case,以方便后面的兄弟继续写 case。
  • 应组织要求,把一个 repo 合入了我们的主 repo。贡献行数直线提升:) https://github.com/pingcap/tidb/issues/28775

纪念一下实习离职信

2022/7 ~ 2023/8

这一整段时间主要是和前端打交道,即和用户打交道;另外还需要和 infra 资源打交道,即 k8s。
毕业后正式入职后的半年,一直都是被大佬们带着做 cloud 上的偏后端的事。

  • 当时公司正高举 cloud first 大旗,我在简单适应工作环境后,就也被安排去了 cloud 大军(紧急!缺人!)。我们组当时负责 Data Import、Data Migration(DM)这类数据流入的工具。所以我就开始参与了 Data Import 云上(简称 Import)的开发。
  • 当时跟着 mentor 一起做 Import 的第一次界面重构。当时啥也不懂,也不懂 web 后端,也不懂 cloud infra,也就是一边跟着做一边学习。我的工作主要涉及 web 后端这块。
  • 十月份组里开始了 DM cloud 的项目,这是一个更大的跨好几个 team 的项目,并且前置工作已经做了超久。我们 team 主要负责 web 后端、e2e 测试以及整体项目的上线验收。我也是跟着另一个大佬边做边学习。

入职半年后是一个转折点,从一个 newbie 转变成一个真正的工程师。后面这半年多我一直专职在做 Import 的工作。

  • 公司在这一年推出了 serverless 产品,这个产品是希望用户尽量平滑地尽量快地 landing 使用的。基于这个原则,我们开发了从本地上传文件进行数据导入的功能。这是我第一次作为 owner 负责 cloud 上的 feature,贯穿方案设计 -> 方案验证 -> 所有后端开发 -> 测试 -> 上线所有流程。这期间我需要和 PM、FE、UX、QA 全程协作完成。在此之后,我基本就一直以 owner 角色参与 Import 的功能开发了。
  • 作为本地文件导入的后续优化,我们进一步优化了后台导入方式,在完全不改变用户使用的情况下,把之前需要 1 分钟才能导入完成的任务缩短到秒级导入成功,导入时间缩短了 95%!
  • 解决了 serverless 那边的需求,我们想要解决 Import 日常流程中的一些顽疾——之前一直修修补补但始终无法彻底解决的问题。在经过无数讨论,测试验证后,我们最终确定了一版方案,彻底修改了创建 Import 任务的用户流程,让用户丝滑地使用,并尽可能地让用户在遇到问题后自闭环解决问题。新版本上线后再也没有出现过之前频繁遇到的 oncall 了,完美!
  • 大需求就是上面这些了,因为组织架构的调整,我们 team 日常还需要维护与 Import 相关的除了(PM、FE、UX、QA)外几乎所有事情:)

tidbcloud:https://tidbcloud.com/

Import 文档:https://docs.pingcap.com/tidbcloud/tidb-cloud-import-local-files

DM cloud 文档:https://docs.pingcap.com/tidbcloud/migrate-from-mysql-using-data-migration

2023/8 ~ 2024/5

机缘巧合,我们组和另外一个组合并了。所以在日常维护 Import 之余,我又有机会参与了 TiDB SQL 层的开发。

  • 参与了分布式执行框架的开发。一个把大大大型任务拆分再拆分、调度到不同节点分布式执行的项目。涉及到任务管理和抽象、节点间通信、任务调度、高可用、任务 revert、资源管理等问题。很有意思。
  • 负责了 BDR DDL 部分的设计、开发和测试。它可以让本就是分布式数据库的 TiDB 经过 TiCDC 和另一个 TiDB 集群建立双向同步链路,最终形成多个 TiDB 集群之间双向同步的拓扑,BDR 就是这种拓扑下的解决方案,进一步拓展 TiDB 的边界。(detail docs

工作过程中还做了些啥

翻看我自己的旧文档,感觉最有意思的部分,就是我对自己的反思和复盘。同样在这里记录和纪念一下🤓

都是写给自己看的,所以写的都很直接,回看起来又有些莫名其妙的正经😝

第一次重构

刚实习四个月

第一次 own 项目

own cloud 项目时

前面三张是实习的时候写的,最后一张是在第一次 owner cloud 项目的时候写的。

最有价值的东西

这些东西,其实都是老生常谈。但真正工作后才知道,能做到的人有多少。

项目管理

所有软件都会延期,换句话说,延期可能就是软件开发的一部分(狗头)。

《人月神话》是我项目管理的启蒙书,是在 2023 年上半年读完的。一些观点:

  • 写代码是软件开发中耗时最短的部分,更重要的部分是设计和测试
  • 如果大型项目要延期,临时加人手并不会提高人效,反而会提高沟通成本

一些我作为 owner 对于项目延期的应对手段:

  • 内心需要清楚的知道一个项目从 kick off 到上线的全流程。如果是小白,确实不清楚流程,项目大概率延期,自己心里要有预期。
  • 跨团队合作一定要提前预约其他团队的时间和排期,重要会议最好是从一开始就 involve 所有参与的人员一起,减少后续的沟通成本。
  • 作为 owner 需要了解项目的全貌:为什么要做?要解决什么问题?要如何解决?有没有必要用这种方法?做完了之后用户使用起来是否会满意?有任何疑惑的地方都需要及时和 PM 对齐。在弄清楚之前最好不要给出确定的交付时间
  • 写设计文档时候就需要对某些不确定的部分做技术验证和测试,用测试结果给出确切的方案和提案,而不是一群人在会议上猜测可行性,浪费所有人的时间。
  • 设计文档 review 一定要充分,把有异议的部分直接在设计阶段就讨论清楚,不要在代码都写好了,结果 review 时同事说,这样不行呀。后者有极大的风险。
  • 设计文档的 review 大概率是会持续一段时间的,某些争议的地方肯定需要反复讨论,在这个期间可以直接开始做已经被 approve 的部分。这样会加快项目进度,能多早开始就多早开始。
  • 在设计文档还有较大争议时,不要轻易给出交付承诺
  • 所有需要联调的功能一定要先利用工具把自己的部分测试完毕,再进行联调。否则联调时出现自己这边的问题,沟通成本和 bug fix 的成本都很高。
  • 如果是小白,可以在正常排期的基础上 *2
  • 大型做好预期管理,让 PM 知道项目是可能会延期的
  • 在出现较大风险的时候,一定要及时同步给相关的人
  • 尽量避免项目做着做着加需求,但是可以大胆地砍需求,能砍就砍🐶
  • 如果被加了需求,需要给 PM 做预期管理,需求增加导致了开发、测试工作量的增加,从而会导致延期
  • 大型项目一定要指定好 milestone,小步快跑,不要总想着憋大招,出现一个项目半年了还没有任何东西交付的情况。
  • 最后,延期不可怕,直面它

顺便说一下我理解的开会的 sop,这也会影响到整个 team 的效率,间接影响项目的推进:

  • 非必要不开会,开会一定要事先准备好
    1. 开会要解决的问题
    2. 最好能提供一个文档,文档中给出 background、问题、各个问题的自己的想法、事先了解到的各种方案(相当于技术调研)、方案的优缺点。
    3. 提前放出文档,让参会人员提前 review,并给出 comment。
    4. 最好是大家充分 comment 之后,再开会。(说不定就不用约会了)
  • 会议结束后一定要总结罗列的问题
    1. 是否得到了参会人员一致同意的结论
    2. 没有结论的问题,需要定下来下一步做什么。谁来做?是需要进一步调研?还是需要其他人员的支持?还是需要技术验证?什么时候时候能再次讨论,并确定结论。
    3. ”这个问题暂时不需要解决“,也是一个结论,甚至还挺好的

警惕不看文档只开会的人,远离他们

产品思维

这是我在过去两年和 PM 沟通交流、不断碰撞后,对我留下的影响。我觉得异常珍贵,能在一个 infra 公司得到这样的体验。超级感谢优秀的 PM 同学!

这块我没系统看过什么书,所以以下都是基于我自己的理解。

Project vs product
产品是面向用户的,Project 不一定。做 project 并不一定需要太考虑用户,但是产品一定需要。产品是一个完整的“物”,用户使用产品,然后发生一些作用/反应,以帮助到用户。project 没有 product 那么“精美”,它可能是一个带有“毛刺”的“物”,或者可能是 product 的一部分。(有点抽象😓,等我系统学习后再试着描述下)

总之,产品思维是,我们需要完整地考虑用户端到端的体验。需要详尽地遍历用户旅程,站在用户的角度,考虑他们在使用过程中可能遇到的所有情况。用户遇到一个报错,他能做什么?一个功能,到底是用户真的需要它,还是开发者、PM 意淫出来的自己以为用户需要它?

要想做好一个产品,一定要了解用户,最好自己就是用户。

另外,好的产品是迭代出来的。所以产品有问题是非常正常的事,遇到问题、找到根因、找一个合适的方式解决它。这就是我们的工作。

代码质量

这块我读过最好的书是《程序员修炼之道》,读几遍都不会多。以下是我觉得比较重要的点:

  • 可读性。因为比较菜,我自己经常会读到比较难以理解的代码,所以在自己写代码的时候不自觉会想,别人读我写的这段代码,会不会有 confused。So,在写代码的时候,尽量使用有意义的命名,避免使用魔术数等
  • 可测试的代码。所有新增的代码应该都要加上单测,如果发现自己写的代码好像很难写单测,那就应该把它改成容易写单测的样子!
  • TDD。在修 bug 的时候现在经常会用 TDD 的模式,先写自动化测试或者单元测试,测出有 bug 的地方。然后再改代码,让测试跑过。
  • 好的代码是迭代出来的。不要试图一次性写出完美的代码,这样会让效率降低,很容易陷入到一些不重要的小细节纠结中。也不可能一次性写出完美的代码,所以,在 peer review 之前,尽量都 self review 一遍。

符合预期吗

Yes。

如今拥有的技术栈:

  • golang:database 开发、cloud 开发(aws/gcp sdk、k8s crd、reconcile)、Web 后端开发
  • git/Github action
  • k8s
  • Aws/Gcp
    • s3/bucket
    • IAM
    • EKS/GKE
    • RDS/SQL
  • Pulumi

而我觉得最重要的能力就是——解决问题的能力。并不是指某个方面某个具体的问题,而是广义的解决问题的能力。具体的问题有很多,比如上面的 golang 的各种语法、database 的各种基本概念、aws IAM 中的 user/role/policy、什么是 eks/gke、kubectl 的各种命令、k8s 的概念等等等等,这些就是理论上的知识,也就是面试常考的八股文;还有项目/产品上的问题,比如 DM 同步报错、一行数据如何从上游通过 DM 同步到 TiDB 中、用户导入任务从创建到完成后台发生了什么等等。这些具体的问题,只要自己了解了、学会了、熟悉了,那这个具体的领域遇到问题,解决起来就相对容易、快速了。

对于一个公司某个岗位来说,它就需要你熟悉某些领域就够了。但是对自身而言,更重要的应该是广义的解决问题的能力。遇到一个你不熟悉的领域的问题,你将如何分析、解构、学习、了解、重新分析、验证、最终完成它,这个过程中你可以利用所有你可以利用的工具,比如 chatgpt、google、code、你的同事、公司的文档等等。

这种能力很难量化。我只能说现阶段对自己这个能力还算,比较满意。

我认为面试就应该考核解决问题的能力

后续方向

现在,我新转到了 storage 部门,又可以开始学习新的知识了,可以继续拓展 PD 和 TiKV 的技术栈咯。

致谢

谢谢所有一起组内共事过的同事,你们都是那么的优秀,闪闪发光。

谢谢 Cloud 上一起合作的同事,合作是那么的愉快和顺畅,一起“做”一个产品的感觉真的很赞!

感谢所有 mentor 过我的大佬(dsdashun,ehco,GMHDBJD,glorv),真幸运能有过这么多 mentor,你们所有给予我的指导,都是我的幸运。