人物采访 / T SALON

编辑内容

overtrue 谈开源项目与开发者成长:从真实需求到长期维护

整理 T Chat 第 16 期的两段录播:overtrue 从寻找开源创意、编码测试、文档、版本发布与持续维护,谈到自学 PHP、项目重构、职业选择、负责人协作、技术学习和团队工程实践。

T Chat 第 16 期 overtrue 分享开源项目实践与开发者成长的访谈封面
T Chat 第 16 期 overtrue 分享开源项目实践与开发者成长的访谈封面

本期视频发布于 2022 年。文中的技术状态、个人经历与观点均为当时情况。

T Chat 第 16 期请到 overtrue,先分享如何从零开始打造开源项目,再讨论开发者怎样成长。在第一段自我介绍中,他谈到 EasyWeChat、Laravel 中文社区等开源经历,以及当时在腾讯 CDC 参与 CoDesign 的工作。选题围绕他反复经历的过程展开:一个自己用得上的工具,怎样变成别人能理解、能使用,也能长期依赖的项目。

第二段把这些实践放回个人经历。从为了修改博客而学习 PHP,到承担需求设计、环境维护和大型接口重构,他所说的成长,往往发生在必须把一个具体问题解决完整的时候。

开源项目:从自己的需求走向别人的使用

先找到问题,再决定是否创建项目

参与开源有许多入口。修复缺陷、补充文档、纠正文字、提交有价值的问题,都可以成为贡献;创建一个新的仓库只是其中一种。overtrue 提醒,把代码放到 GitHub 上很容易,让项目对别人持续有用需要更多工作。

他寻找创意时首先看自己的工作和使用体验。某段功能在项目里反复出现,或者现有工具始终解决不好一个需求,就可能值得提取成独立组件。自己成为第一个用户,能够帮助作者发现接口是否顺手、安装是否麻烦,以及哪些假设只在自己的环境里成立。

社区也是需求来源。群里的求助、日常讨论和成熟项目的 issue,都会暴露尚未解决的问题。可以先尝试复现、反馈或参与修复,再判断是否需要另做一个项目。对于停止维护但仍有用户的项目,他也提到在遵守原项目许可的前提下继续改进。这里的起点始终是具体需求,而非为了拥有一个开源项目而寻找题目。

代码风格、测试与自动化要一起考虑

公开代码面对的是不熟悉作者习惯的人。命名、格式、目录组织和注释需要让其他开发者读得懂;采用已有规范,也能减少合作时反复讨论个人偏好的成本。他以 PHP 的规范和工具为例,建议把格式检查、静态分析、测试等重复工作交给工具,并接入持续集成。

测试在他的经验里有两重价值。一方面,修改代码后可以较快发现回归;另一方面,如果某个功能很难测试,往往值得回头检查依赖关系与设计是否过于纠缠。他讨论了单元、功能和集成等不同层面的测试,也强调边界条件:反复验证同一种简单输入,并不能替代对失败路径和特殊情况的检查。

对没有时间写测试的疑问,他把问题放进交付过程里回答。测试需要学习和编写时间,应尽量在估算和沟通时为它留出空间;缺少这部分投入,时间也可能在后续排查缺陷时付出。他没有给出消除全部问题的保证,也承认工作安排未必总能支持理想做法。个人项目和开源项目可以成为练习场,逐步建立可测试的写法与工具习惯。

他提到过去团队曾采用较高的代码覆盖率要求,但那是特定团队的实践,伴随着培训和适应成本。测试还要能持续运行:例如提交前通过 Git hooks 检查,提交后由 GitHub Actions 执行。公开项目不断收到修改时,自动化能帮助维护者更稳定地获得反馈。

文档先回答新用户的问题

文档的语言和形式应服务于目标读者。面向中文用户可以先把中文说明写清楚;需要接触更多开发者时,可以借助翻译工具逐步补充英文。简单项目可能用 README 就足够,内容较多时再考虑 GitHub Pages、VuePress 或 VitePress 等文档形式。他特别在意资料能否直接访问,避免把加入某个聊天群变成阅读文档的前提。

文档最常见的偏差,是作者已经知道所有背景,读者却刚刚到来。因此,首页应尽快让人判断:这个项目解决什么问题,适合谁,运行它需要什么,以及怎么完成一个最小的使用过程。版本、构建等状态信息可以帮助读者了解项目状况;一个有代表性的示例,则能让人初步感受 API 和使用方式。按作者实现代码的顺序介绍所有内部细节,未必符合读者的理解顺序。

用户与贡献者还需要不同的说明。贡献指南可以交代如何报告问题、准备修改、运行检查和测试,以及提交合并请求时有哪些约定;篇幅较长时,可以独立成文。许可、上游项目、灵感来源和贡献者也应清楚标明。对复杂项目,入门教程、贡献流程和详细 API 参考各自承担不同任务,不必全挤进同一段说明。

版本号传达的是兼容性

讲到发布,overtrue 用相当长的篇幅解释版本号的含义。按语义化版本的思路,主版本变化对应不兼容的公共接口变化,次版本用于兼容的功能增加,修订版本用于兼容的缺陷修复。判断依据是使用者是否必须改变原来的用法。一处参数顺序或类型的调整,即便代码改动很少,也可能让原有调用失效;内部重写了大量实现,只要公开使用方式保持兼容,情况就不同。

他建议在可能时保留兼容层,将不兼容调整集中到有准备的主版本中,并通过预发布版本等方式让用户有机会试用。依赖版本声明和更新策略会影响用户实际拿到哪个版本,因此发布者需要认真对待版本号给出的信号。

一个小程序组件库的升级经历说明了这一点。据他的回忆,库从 2.1 升到 2.2 时,一处加载方式变化破坏了兼容性。部署更新依赖后出现问题,本地却因为保留着旧的依赖目录而一度无法复现,直到在干净环境重新获取和构建才找到原因。维护者认为改动只有很少几行,双方对版本含义的理解却不同。这个例子提醒发布者,要从已有调用者的处境判断影响,也提醒使用者检查环境和依赖版本差异。

传播需要相关性,也需要可信的表达

发布后,项目还需要被合适的人发现。overtrue 建议在相关社区里讨论真实问题,说明项目能解决什么、适合哪些人,以及有哪些使用条件。向不相关的群反复投放链接,通常只会消耗他人的注意力;推广也补不了功能和文档本身的不足。

他把个人识别度与日常沟通也视为项目传播的一部分。相对稳定的昵称和头像,方便别人把项目、文章与作者联系起来。面对尖锐甚至误解性的反馈时,维护者仍可以给出简洁的说明、指向文档,并为持续争吵设置边界。他回顾自己早年参与语言争论的经历,认为长期争辩很难带来相应收益。

更专业的社区和有实际内容的文章,能够帮助项目接触目标读者。他也分享过基于自己社区经验选择发帖时段的做法,例如工作日某些时段比周末更容易获得反馈。这只是他当时的运营观察,不能直接推成适用于所有社区的流量规律。传播内容仍应围绕实际痛点、功能、适用人群和反馈方式展开。

反馈、发布节奏与长期维护

用户反馈既能指出缺陷,也可能带来下一轮创意。issue、文档修改入口、讨论区或群组,都应让人知道在哪里提出问题。overtrue 介绍自己的处理习惯:定期查看新问题,小问题尽快解决,复杂问题做好标记,安排后续工作。及时回应并不意味着立即实现每一个请求,但能让用户理解项目还在怎样推进。

发布节奏要和变化的性质相配。兼容的小功能可以更频繁地发布,主版本则需要更完整的规划;他以 EasyWeChat 的实践说明不同发布周期的安排。变更记录要说明实际改了什么、谁会受到影响,以及升级时需要做什么。文档改善、重构和用户反馈处理,也属于持续维护的工作。

分享最后回到投入与责任。当项目没有明显回报、却不断收到问题甚至批评时,继续维护并不轻松。他尤其提醒,发布时声势很大、之后却长期无人回应的项目,会给依赖它的人带来困扰。开源项目获得了使用者,就需要面对这些真实依赖;持续维护是这场分享中比创建仓库更艰难的一部分。

成长对谈:在解决问题的过程中扩展能力

为什么走向 PHP 与后端

第二段的第一个问题,是他为什么选择后端。overtrue 回忆,自己在大学学习偏网络与硬件的专业,却对相关方向兴趣不大,于是借书自学前端。后来想修改 WordPress 博客的主题,求助未果,就开始读代码、查 PHP 文档、自己尝试。问题解决之后,他进一步编写主题和插件;别人的使用给了他成就感,找工作时也顺着这个方向走了下去。

这段经历也解释了他对重复造轮子的态度。已有项目满足不了自己的需要,反馈又迟迟没有进展时,重新实现可能是一种学习和改进方式。可以先参与已有项目;如果参与不成,又确实有把握做出更合适的东西,也不必仅因同类产品已经存在就放弃。他把使用者的反馈看作持续动力的一部分,提醒开发者观察自己做这件事时能否获得足够的正向反馈。

哪些工作让成长加快了

谈到不同阶段的成长,他先提到自学中的检索习惯:从报错中提取关键部分,确认所用工具和概念,再寻找答案。这个经验服务于当时的搜索与排障过程,帮助他把模糊的困难变成能够调查的问题。

他随后回忆 2013 年参与雅虎台湾商城项目的经历。当时,他既是开发者,也是两边团队的沟通人和开发环境的维护者。别人遇到环境问题会来找他,而许多答案也是他在处理过程中逐步查出来的。反复排查让他积累了 Linux 环境和基础设施方面的经验。

这份工作还要求在动手之前写出完整技术文档,把需求、技术方案、接口交互和实现安排交代清楚,达到其他开发者接手也能继续做的程度。严格的代码格式检查和工具约束,在适应期带来了压力,也训练了他消化需求、设计接口、书面表达和跨团队沟通的能力。他把这一阶段视为自己成长很快的一段时间。

之后的一份工作,又让他独立承担了更完整的交付过程。从随产品经理见客户、确认需求,到带着草稿再次核对细节,再到数据库设计、编码、环境部署和上线,都需要自己串起来。比如文章与标签的关系,看似一个局部功能,也要在沟通时把行为说清楚。项目因此训练了超出单一编码岗位的综合能力。

在手机微博的经历中,任务变成重构已有系统。据他回忆,旧项目经过多年迭代后,小需求也要花很长时间确认和测试。他先重新设计基础结构,考虑业务逻辑和测试怎样更容易编写,再与其他开发者迁移约 480 个接口。连发一条微博这样看起来简单的操作,背后的历史逻辑也需要一边阅读、一边记笔记,才能逐渐弄清。挑战不只是重新写代码,还包括理解旧行为和为后续协作建立基础。

这些例子共同指向他给出的建议:不要只看任务是否麻烦,也要看到它能训练什么能力。陌生环境、复杂需求和历史包袱让人难受,却可能提供平时接触不到的学习机会。这是他的个人成长路径,不意味着每一种困难都必然值得承受。

大公司与小团队怎么选

主持人用大公司与小团队的选择继续追问。overtrue 没有给出统一答案,而是列出自己观察到的差异。大组织有资源和优秀开发者,也会有复杂协作、历史系统和难以推动的变化;规模小的团队在调整工具、规范和技术方案时可能更灵活,也可能形成很好的工程习惯。

因此,他建议了解具体团队:负责人怎样看待技术,代码规范和开发环境如何,已有成员的真实体验是什么。可以通过曾经在那里工作的人、团队公开的技术内容等寻找信息。公司名气不能直接说明自己将加入的团队每天怎样工作。

对于去大公司跟优秀的人学习这一期待,他提醒,身边有人经验丰富,不等于对方有大量时间手把手教你。学习仍需要自己参与需求、处理问题、消化经验。岗位、收入、履历和未来生活规划都可能影响选择;他和主持人都把这件事看作取舍,而没有把某一类公司作为所有人的标准答案。

从开发者到负责人,变化在哪里

overtrue 说,实际承担责任有时早于正式头衔。一个人主动推进工作、能够处理复杂问题,就可能开始负责某一部分。角色变化首先体现在时间和沟通上:会议、协调、帮助新同事会把时间切得更碎,沟通对象也从自己的需求接口,扩展到产品、设计、前后端、测试和项目管理等角色。

负责人需要更早看见实现背后的问题。评审交互和需求时,要想清楚怎么实现、哪里可能有风险、第三方依赖是否可控,以及当前方案会不会阻碍后续扩展。发现不合理之处,还要把理由说清楚,推动各方找到更合适的方案。必要时,他也会替团队挡住不合适的需求。接受或拒绝都要考虑项目整体,而非只看眼前能否完成。

维护质量同样需要协调资源。业务团队未必能单独安排一个月做重构,他的做法是在相关需求中协商增加半天、一天,把局部改进带进去,逐步处理问题。主持人把这种先承担问题、再形成影响力的过程联系到 ownership;它不仅是获得决策权,也包括提前发现风险、解释取舍和持续照顾项目的可维护性。

怎样看待语言争论与 PHP

面对关于 PHP 的社区老梗,overtrue 把讨论拉回工具和场景。他喜欢 PHP 的开发体验,也使用 JavaScript;在当时的项目中,他认为 PHP 与 Laravel 能够满足团队的需求。这里的评价来自他的使用经验,不能推导成所有负载下的性能结论。

他也把技术适用性与就业市场分开。某种语言是否有更多岗位、更适合个人生活选择,需要看现实情况;他明确表示自己没有持续研究相关岗位数据,不据此作市场判断。单凭一种工具受到调侃,就给所有使用者下结论,没有太大帮助。

谈到 Laravel 的学习门槛,他认为理解语言基础有助于看懂框架的写法,并介绍了自己对这个框架的偏好。更核心的提醒,是不要把职业身份收窄为只会某一种语言:需求理解、问题解决和主动承担责任,会影响工具最终用得怎样。他更愿意把自己称为 Web 开发者,主持人也回应,应从问题本身出发选择工具。

有没有更快提升自己的方法

他不认为存在省掉积累的速成路线。看完教程、收藏文章或买下书,容易带来已经掌握的错觉,实际编写与调试才会暴露理解中的空白。他提到大量写代码的重要性,其中关于代码行数的说法是一种强调实践的表达,不是经过验证的能力门槛。

提高效率可以从解决问题的方法入手。查找错误时提炼关键词,学习工具时优先读官方手册和已有实现,都能帮助缩小问题。他个人不偏好依赖一步一步的视频教程,主要担心寻找一个小问题的答案要花很长时间,以及观看操作容易掩盖基础理解不足;他也明确说这并非绝对禁止用视频学习。

另一个方法,是用陌生技术实现自己熟悉的东西。他学 Node.js 时,给自己设定了一个小目标:做一个能处理路由、使用模板并输出页面的 Web 框架。因为知道这类功能应有怎样的行为,就可以把注意力放在新技术如何实现它们,带着问题查文档、调试,直到基础流程跑通。原片也讲到那次投入过度、连续熬夜的个人经历;可借鉴的是任务设计方法,不必复制他的作息。

最后是模仿与提炼。阅读 Laravel、Symfony 等项目源码时,可以留意一种写法怎样组织职责,再尝试放进自己的业务场景。直接照搬未必合适,修改和比较的过程才会逐渐揭示这种写法的条件与收益。主持人把这组建议归纳为减少绕路的经验,而非保证快速成为专家的秘籍。

他所在团队怎样做工程

关于腾讯的工程师文化,overtrue 首先限定了回答范围:公司很大,不同部门和团队差异明显,他无法代表整个公司。他提到当时公司内部在推进规范、工具、测试和开源等实践,随后主要介绍自己所在 CoDesign 后端团队的做法。

技术选型可以讨论,提出方案的人需要说明优缺点、说服协作者,并考虑出了问题由谁接手。自由使用工具,与团队能否维护它是连在一起的。测试方面,他介绍团队要求后端编写集成测试,覆盖接口的正常、异常和边界情况,并设有接口层面的覆盖要求;这里不能把他口述的覆盖数字直接等同于统一的代码行覆盖指标。

此外还有提交信息规范、格式化工具、自动检查和流水线校验。代码审查则按改动的复杂程度安排:较复杂的改动让更多后端成员一起看,较小的改动可以找同事检查。他没有把这套实践包装为全公司的统一制度,也没有声称每次合并都采用同样流程。

对直播间的招聘问题,他当时的答复是团队没有招聘名额,即使人手紧张也不能据此推断有岗位。这条信息只属于 2022 年的现场交流。

理解前后端,对交付和协作有什么帮助

谈到全栈能力,他首先想到的是把想法做出来的自主性:从设计、前端、接口到部署,能够独立打通一个基础产品,就不必总等某个角色加入。另一个收益是协作时更理解对方。设计接口时会考虑前端怎样使用,前端遇到问题时也更容易从其处境分析原因。

跨方向接触还会扩大技术视野。在一种语言或框架中看到的组织方式,可能帮助自己重新理解另一端的实现。主持人补充了自己懂一些设计后与设计师沟通的经历,两人的落点都在于:理解相邻角色的工作,会使合作更顺畅。

现场也谈到了团队前后端人数的大致比例,以及 CoDesign 的产品定位。面对主持人将其理解为搭建系统的猜测,overtrue 说明它是设计交付平台,并用同类产品帮助解释。这里讨论的是当时具体产品的工作分工,不能据此给其他团队推导固定的人员配比或产品能力。

后端开发者未来怎样发展

最后一个问题很大,overtrue 没有给出一条普遍路线。他说自己走向后端本就带有偶然性,兴趣仍是写代码,继续改善自己不满意的实现;当时并没有把成为架构师或专家设为必须完成的目标。他也不把自己完全限制在后端身份里,而是希望继续沿开发者这条路走下去。

主持人随后从邀请嘉宾的经历谈到不同方向的职业空间,并把更宏观的架构与发展问题留给后续嘉宾。那是现场讨论中的观察,不能单凭受邀嘉宾的职位,就认定某类开发者拥有统一的职业上限。回到 overtrue 本人的回答,持续写出更好的代码,是他当时愿意继续投入的方向。

完整原片、分段信息可从第 16 期访谈页继续查看。

查看本期原视频与分段信息:overtrue:从 0 开始打造开源项目 →