想象一下这样的情景:“大约400万行PHP代码,由报酬过低、有时并不是善意的自由职业者和学生在8年的时间里编写而成。虽然初创企业的首席执行官编写了大部分代码,但在2004年为了学习新技术而中断。”
这就是一家初创企业当初为了走捷径而到最后不得不重新编写代码的情况,其面临的技术债务达到难以承受的程度。
但是,如果你在初创企业担任技术职务,就会知道避免技术债务并不像听起来那么容易。
初创企业通常有很多发展里程碑需要在很短的时间内完成。在人员和预算有限的情况下,初创企业为了开发最小可行产品有时需要走捷径,虽然他们知道将来必须进行一些重构。
但适度实施很重要。当初创企业背负技术债务时,就像爬山一样,必须先爬过这座山才能继续前进,初创企业只有先背负一些技术债务然后才能扩大规模。企业现在节省的工程时间都必须得到偿还,通常还要偿还利息。许多从事过严重技术债务项目的开发人员都有这样的故事:曾在几个庞大而杂乱的代码库中工作过,在那里进行了一次重大重构,花费的时间比预期的要长,然后在完成之前将资源转移其他项目上。其最终结果是构建了一个更大、更混乱、更难理解的代码库!
换句话说,当技术债务变得过重时,即使有很多资源可以解决这个问题,修复它也会变得非常棘手。对于初创企业来说,最好的方法是避免承担任何不必要的技术债务,所以需要了解一下初创企业可以做的六件事,以尽量减少或消除在扩大之前必须偿还的技术债务。
1、不要承担不需要的债务
这个建议听起来很简单,但真正实施可能具有挑战性。初创企业需要承担什么债务并不总是很明显。一家初创企业在早期几乎总是需要做出一些妥协,但随着工具和技术的变化和发展,可能很难弄清楚真正需要做出哪些妥协。
例如创建事务数据库。一家初创企业在几年前不得不做出一个艰难的决定,而且不可避免地涉及妥协:是否选择能够快速轻松地扩展并处理潜在的一致性问题但成本更高的NoSQL数据库?或者选择像PostgreSQL这样可靠、简单且免费的开发人员现在可以使用的东西,但将来可能难以扩展?
这些都不是理想的选择,采用NoSQL方法可能会带来一系列令人不快的后续问题。但采用Postgres方法也承担了一种技术债务,因为以后必须人工扩展。正如初创教育机构Kami公司在新冠疫情期间所面临的那样,扩展Postgres可能会很痛苦。该公司的一位代表表示,“我们知道留在Postgres并设置分片会有多复杂,管理多个数据分片会有一个持续的阻力。我们团队中没有人愿意完成这种工具,使我们设置了分片,也无法将业务增长10倍。”
不过,如今只需选择正确的堆栈,就可以避免承担大量技术债务——尽管什么构成“正确”在很大程度上取决于企业正在构建的内容以及已经熟悉的内容。然而,在任何一种情况下,初创企业都必须妥协进行选择。
当然,事务数据库只是技术堆栈的一部分,但现在几乎每一层都存在类似的解决方案。例如,应用程序的业务逻辑可以迁移到基于云计算的无服务器服务,例如AWS Lambda、Google Cloud Functions或Azure Serverless Functions,从而实现几乎无限的可扩展性,而无需在前期投入大量的时间或费用。
因此,对于初创企业来说,了解他们的选择至关重要。由于有了新工具,像Kami这样的公司被迫做出的妥协现在可能完全避免。特别是,无服务器产品在整个堆栈中的激增使初创企业有可能扩展规模。这反过来又使他们能够避免使用难以扩展的技术而承担的技术债务,只是因为它们是获得最小可行产品的最便宜和最快的方式。
初创企业团队现在可以使用无服务器选项进行构建,这些选项既免费又容易获得最小可行产品,同时还提供云原生自动化规模,以保持成本最小化和应用程序性能一致,无论应用程序是处理360个并发用户还是36万个并发用户。
因此,初创企业在早期阶段避免技术债务,有时是一种让其时刻保持警惕并了解所有选择的功能。不到一年前,还没有免费的、无服务器分布式SQL数据库的选择,而现在已经有了。了解这些选项可以帮助企业避免承担技术债务,并避免妥协。
2、尽量减少运维工作
在初创企业发展的早期阶段,开发人员身兼多职是很常见的。例如,初创企业的开发人员通常会在运营方面担负双重职责,直到公司规模大到能够雇佣专门的IT运营人员。
但启动开发时间表往往很短,企业的发展路线图上有很多功能,而且需要快速周转。开发人员花在运维工作上的时间其实都是应该花费在构建应用程序上的时间,而且他们构建的时间越少,可能不得不削减一些功能以在最后期限交付。而每一次偷工减料都是一小部分技术债务。
出于这个原因,选择托管服务有时可能是一种最经济的选择,即使这意味着要承担更高的前期成本。初创企业可能并不愿意通过托管来节省成本,因为必须自己开发,但重要的是要考虑让开发人员了解和管理运营相关的成本。
这一成本超出了开发人员在开展运维工作时浪费的开发时间。选择托管服务将运维工作交到第三方专业人士手中,他们通常会提供优先的技术支持以促进集成,这可能意味着更顺畅的集成过程、更好的应用程序性能以及在出现运维问题时更快地解决。
3、灵活性
当初创企业做出设计选择或选择以后难以改变的服务时,可能会在不知情的情况下承担技术债务。
虽然有很多这样的例子,但最常见的例子之一是初创企业锁定在单个云平台的生态系统中。在一开始这样做通常有令人信服的理由,因为当将AWS Lambda功能连接到其他AWS云服务(如Aurora、ElastiCache或Redshift)时,可以利用其提供的功能。
但从长远来看,如果谷歌云平台或微软Azure成为更实惠的选择呢?或者,如果意识到为用户提供最可靠的服务将需要使用多云怎么办?突然之间,一笔巨大的技术债务到期,初创企业的团队将不得不弄清楚如何处理,例如将其仅限AWS云平台的数据库迁移到可以支持AWS和谷歌云平台的数据库,从而避免引发一系列其他问题。
只要有可能,选择设计和工具以保持灵活性是值得的。有时这需要权衡利弊,但在其他时候,只需选择不同的工具即可获得相同的性能和更高的灵活性。因此,即使选择的功能仍然在AWS云平台上构建和部署,拥有一个与云计算无关的数据库也可以灵活地切换到另一个云平台或在未来采用多云,而无需更改数据库。
4、不要解决已经解决的问题
作为工程师,不要尝试解决别人已经解决的问题。虽然不断改进的动力是许多技术创新背后的动力,但创业公司要想获得成功,就必须与实践相结合。虽然定制解决方案可能是完美的,但也有可用的第三方解决方案,可以在不花费开发人员时间的情况下提供99%的功能。
例如,Starburst公司提供的一个数据分析引擎为客户的数据提供一个单一并且快速的访问点。为了确保为客户提供更好的性能,Starburst公司需要构建一个多区域关系数据库。该公司当然可以尝试构建一个定制的解决方案。但正如Starburst公司工程副总裁Ken Pickering所说:“当一个工程团队已经建立了一个可靠的解决方案时,我为什么要让工程团队尝试解决多区域问题?我们需要对第三方技术解决方案做出明智的选择。因为我们需要为客户的数据负责。”
对于大多数初创企业来说也是如此,即使还没有为客户要求所困扰,也需要做出明智的选择来保护其开发人员的时间。
为了快速发展和成长,初创企业需要专注于解决他们的团队需要解决的核心问题。如果开发人员偏离正轨,转而构建定制解决方案,那么他们的时间将非常紧迫,以至于他们在开发产品的核心功能时不得不偷工减料。那么这就成为企业最终必须偿还的技术债务。
5、尽早建立编码最佳实践
虽然人们关注的是使用为技术堆栈选择的解决方案来避免技术债务的更宏观的方法,但很多技术都可以追溯到草率编写代码,这通常是因为时间匆忙。
如果企业的目标是为避免技术债务,那么重要的是确保从第一天开始就实施并遵循编码最佳实践,但这应该包括可重复的、形式化的系统。虽然开发人员都知道这一点,但当初创企业的开发团队只有几个人(甚至只有一个人)时,这些都是很难做到的。当交付截止日期快到的时候,很容易决定不需要评测或记录代码,但是每次跳过类似的步骤时,都会增加技术债务,而这些技术债务总有一天要偿还。
当然,开发人员是否有时间遵循所有这些最佳实践并不总是掌握在他们手中。在通常情况下,开发时间表是从自上而下传递。
6、立足当下,展望未来
避免技术债务的真正关键是善于平衡当前的需求和未来的目标。实际上,这样做具有挑战性,需要将以上讨论过的所有内容结合起来,并将这些知识带到关于企业目标和时间表的更广泛的讨论中。
例如,如果初创企业的首席执行官设定了开发期限,如果不承担某种形式的技术债务,就很难达到这一目标,那么技术人员需要能够确定并传达这些权衡,以便将其纳入预算和规划中。如果首席执行官希望在本季度发布两个主要功能,那么很可能只能发布一个功能,因为下个季度将会处理技术债务,可能花费大量时间和精力处理客户支持问题和重构有缺陷的代码。
在平衡有限的时间、技能和预算的同时尝试优化以获得最佳结果是一项真正的挑战。但是建立一家初创企业并不容易,也不可能完全避免技术债务,尤其是在创业初期。但是,如果可以在堆栈中做出正确的选择,并构建良好的内部护栏,以避免走捷径或解决不需要解决的问题,那么初创企业可以确信自己走上了正确的道路。