Thoughtworks洞见

其他

低代码平台中的“不可能三角”

(星标我们,洞见更多!)近年来,“低代码”这一概念在资本市场上愈发火热,各种低代码平台项目也纷纷上马。然而,此类平台的设计者与维护者们,或早或晚,终将会面对“低代码”与生俱来的一组底层矛盾,而是否能合理地处理这组矛盾,最终决定了此平台的发展前景。背景我们团队正在维护一套基于DSL(领域特定语言)的表单管理平台。该平台由客户方团队自建,其中包含了前端UI、数据管理、表单规则管理等模块。设计目标是:让业务人员以书写DSL的方式定义表单模板,此后可以直接基于模板生成UI并管理表单数据,从而达到低代码甚至零代码创建表单的效果。该平台自建立以来,已经支持了数百个大型表单的成功上线,支持了公司业务的快速成长。然而随着业务的持续发展,该平台的疲态也日益凸显:难以支持复杂的表单需求(可用的表单组件、数据结构、DSL语法不足,且新增成本过高)平台代码极度难以维护大型表单的性能表现糟糕不可能三角以上案例,生动展现了一款低代码平台的典型生命周期:前期:平台能力弱,但业务也简单。平台开始起步。中期:平台能力趋于成熟,业务逐渐变得复杂但仍在平台能力范围之内。平台支撑着业务快速发展。后期:平台触达能力上限,部分业务需求开始超出平台能力。而此类平台之所以会有如此表现,根本症结在于其发展受到了“低代码”天然自带的一组矛盾的掣肘,该矛盾可以用不可能三角的形式加以描述:如图,该三角的三个顶点分别代表了低代码平台的三个核心设计目标:Easy
1月23日 下午 8:20
其他

生成式 AI 带给软件开发的三个幻觉:速度快、质量高、人更少

Bug人编写的代码难免存在缺陷,这是软件质量的基本共识。而且似乎越有经验的程序员,越容易生产出隐晦的问题,要过了很久才会被发觉。线上问题更让人提心吊胆,但这样的担心很难避免。AI
1月16日 下午 8:20
其他

技术写作的困境

1
2023年12月12日
其他

如何在组织中有效地使用低代码工具?

实现自己需要的应用。通过将低代码与传统代码和开发实践相结合,组织可以在不牺牲核心软件所需的灵活性和可扩展性的情况下,赋予公民开发人员部分权力。这才是真正应用低代码的甜头
2023年12月5日
其他

DDD诊所——聚合过大综合症

from》”是一种自定义的衍型,意味着该对象映射自其他上下文。持续交付流水线领域模型团队按照这个模型落地了代码,随着交付的深入,这个模型的缺点也浮现出来。引发问题1.
2023年8月17日
其他

如何编写技术文档?

软件开发中,为你的软件系统编写文档并不是一件新鲜的事情。几乎所有人都明白这样的道理:你的软件产品如何优秀对用户来说并不是最重要的,因为你的文档如果不够优秀,用户不会使用它!即便用户在某些情况下不得不使用你的产品,没有好的文档,用户无法高效使用或者以错误的方式使用你的产品。不幸的是,鲜少能见到关于如何正确组织技术文档的实践及方法论。团队工作中,编写文档仍面临挑战。仓促地开始和结束编写技术文档这个任务看起来总是:优先级不够高,特别花时间并且没有立竿见影的正反馈!于是文档编写被一推再推,直至在某些时刻不得不做,比如新人要上项目了,我的开源产品要发布了,才震惊地发现我竟没有文档。文档最后被随意编写,以至于完成后就被彻底忽视。随着系统的演进,这些文档慢慢脱节,变成谎言!这个论断乍一看如此地荒谬,可是却在我身边常常发生。混乱的结构如同代码编写一样,混乱的结构是相当致命的。我们能使用类似于technical-writing-template这样,基于模板约定的方式使得单篇文章的质量达到一定的水准。然而在复杂的软件系统中,高质量的单篇显然是杯水车薪的。事实上,众多优秀的软件产品它们基本都具备恰到好处的文档,清晰的结构使得初学者和长期用户读起来都毫不费力。我以为,未能使文档免于混乱的原因有以下几点:文档是由多个人编写的。《解析极限编程》中描述一个XP团队中会有“文档撰写员”的角色。即便敏捷实践大行其道的今天,敏捷团队中,不论是成熟的“角色是帽子”,还是传统的“角色是岗位”,都大概很少会见到“文档撰写员”这一角色。文档是由不同的人编写不同的部分,再组合而成的,混乱是自然而然的结果。缺少对抗混乱的模式。不同于软件编写,我们有架构风格这样深入人心的默认约定。甚至有C4
2023年8月15日
其他

你有“搜商”吗?

Google学术是直接从开放的电子期刊中检索到的,还可以直接下载。同时,还可以获取相关文章和来源版本,检索能力和准确性都比较高。唯一不足就是无法大部分检索的内容无法直接下载。知网
2023年8月10日
其他

如何建立你的离岸交付团队?

本文作者:崔娇,金倩倩,郭瑞紫,黄小青前言2020年对于各个行业的公司来说无疑是充满挑战的一年。这些公司不但需要适应愈发数字化的世界,也必须迅速创新,加速实施数字化计划,以在竞争激烈的市场中立足。不论是B2B、B2C或者混合型的运营模式,都必须依赖快速、高效且具有成本效益的技术解决方案,以确保提供给消费者优质的用户体验。根据组织自身情况量身定制的全球交付模型是一种优化方案,能够以最具成本效益的方式加速数字化项目同时保持高质量。目前,全球交付模型主要包括离岸交付(Offshore
2023年8月8日
其他

如何高效使用Gherkin

背景时间回到2022年,我参与了一个使用了Flutter技术构建的Web前端项目。在这个项目上,我们小组的目标是实施Flutter前端自动化测试。彼时,Flutter
2023年8月3日
其他

低碳 Web 实践指南

现状和问题2023年7月6日,世界迎来有记录以来最热的一天。气候变化是如今人类面临的最大健康威胁。据世界卫生组织预测2030年至2050年期间,气候变化预计每年将造成约25万人死亡。这是人们可以真切感受到的变化,而背后的主要推手是碳排放。而在万物互联的数字化时代,碳排放很重要的来源之一是互联网,全球三分之二的人口预计将在2023年通过互联网连接。随着人们对数据和网络服务的需求日益增长,互联网在数据中心、网络通信和终端用户设备等各个环节都消耗了大量电力,其碳排放也在不断增加。如果我们将
2023年8月2日
其他

简化Java单元测试数据

字段的内容设置为指定的日期。在可读性方面,由于避免了冗长的初始化参数,所以使开发者在阅读单元测试时,能够快速理解测试场景,进而也比较容易修改或维护单元测试。第三,EasyModeling
2023年7月27日
其他

持续测试基础设施

持续测试基础设施的必要性基础设施作为应用程序的支柱,为之提供关键的运行环境、网络连接和资源调度等支持。一旦基础设施出现故障,整个应用生态系统都可能面临严重的连锁反应,如性能降低、数据丢失乃至系统崩溃。因此,基础设施的稳定性和可靠性对于运行在其上的应用程序至关重要。持续测试可以在基础设施的整个生命周期中进行检查,确保一切运行正常,尽早发现并解决潜在问题,减少影响扩散。此外,持续测试通过为团队提供即时的状态反馈,有助于提高基础设施的可维护性和可扩展性,进而支持业务持续增长和变化的需求。因此,持续测试不仅是持续交付高质量软件的必要保障,对于基础设施而言,其价值和影响更为深远。本文来分享一下我们团队是如何对基础设施进行测试的。测试的范围首先我们要识别出需要测什么。在
2023年7月11日
其他

大规模敏捷测试怎么做(基础篇)

本文由赵泽鑫,张海云,冯曌合作出品大多数的敏捷团队是由10位以内不同角色的人员组建。其中包括但不仅限于BA、QA、UX、PM、DEV等关键角色。我们通过成熟的方法论以及每日站立会议(Stand-up
2023年6月20日
其他

如何打造 DevOps 基础设施

我们都知道DevOps诞生于互联网企业。Netflix、AWS等互联网企业号称每天往生产环境部署成百上千次。如此之快的部署频率让众多传统企业也跃跃欲试。所以大量的传统企业都纷纷投入巨资打造自己的DevOps基础设施
2023年6月15日
其他

DevOps最佳实践之操作系统和服务

本系列内容是我们在不同项目的维护过程中总结的关于DevOps/SRE方面的最佳实践,我们将致力于在项目上尽最大的努力来推行这些最佳实践。我们希望这些最佳实践能对项目的稳定运营提供帮助,也希望刚接触DevOps/SRE的新人能通过学习这些最佳实践来提升自己在这方面的水平。当涉及到
2023年6月13日
其他

Kubernetes部署让Spark更灵活

中是一个里程碑似的产物。Operator的安装可以使用helm快速部署(quick-start-guide)。他将Spark的任务提交与传统Kubernetes的yaml
2023年5月30日
其他

前端无障碍开发指南

A11y),虽然常常会被解释为”为残障人士服务“,但其无障碍设计的核心在于为所有人提供同等的体验。我们每个人都有可能在某些时刻成为失能者,这称为场景性残疾(situational
2023年5月11日
其他

有态度的前沿技术解析,第28期技术雷达正式发布!

注册新的登录信息时,它会产生一对密钥:网站收到公钥而用户保留私钥。它使用非对称加密处理登录。用户需要证明他们拥有私钥,但与密码不同,私钥不会被发送到网站上。在用户的设备上,会使用生物识别技术或
2023年4月27日
其他

为什么企业要做大规模敏捷?

背景软件工程里一个重要的指标就是“可用的软件”,敏捷宣言里也同样告诉我们“工作的软件高于详尽的文档”,那“可用的软件”、“工作的软件”意味着什么呢?在我的理解里,可以经历用户
2023年4月25日
其他

数据离奇丢失案件的侦破与思考

推荐阅读都是脏数据惹的祸测试右移——生产环境下的QA测试右移:QA与Ops通力合作打造反脆弱的软件系统测试右移之日志收集与监控测试右移:缺陷分析如何帮助质量内建扫描上方二维码,获取《Tech
2023年4月20日
其他

何为Tech Lead?希望这本小书能给你启发

职位时的激动心情。作为一名资深的程序员,我知道这个角色将会带来更大的挑战和机会。然而,很快我就发现这项工作并不像我想象得那样简单,我相信许多刚刚成为
2023年4月14日
其他

AI测试的迷思

近年来,我一直关注AI相关的测试,并积极参与多个全国性测试社区和社群。在这些社区中,我与不同公司和领域的测试专家交流探讨AI测试相关话题,包括业界顶尖公司的专家和国内知名测试学者。我也参加了多个大会,聆听了许多关于AI测试的主题分享,并尝试了多款AI相关的测试工具,从中获得了许多知识和感悟。在这些测试社区和社群中,我遇到了许多关于AI测试的问题,例如什么是AI测试,如何进行AI测试,AI测试有哪些工具与方法等。然而,当我在网上搜索AI测试相关的书籍时,却发现大量的AI开发相关书籍,却鲜有专门介绍AI测试的书籍。这说明测试业界仍在混沌中不断摸索前进。为了分享我所学到的AI测试相关知识和经验,我梳理了自己的学习经历,尝试回答了一些我遇到的关于AI测试的常见问题,并将这些内容整理成文章,与大家一起交流探讨。AI测试的迷思在讨论AI测试时,通常存在两种理解:第一种是利用AI辅助当前的软件测试,例如使用AI系统学习测试分析和测试设计,进而自动生成测试用例并自动化实现这些测试用例。第二种则是对AI系统进行测试。尽管业界对于AI系统进行测试仍然使用常规测试手段,如功能测试、性能测试和安全测试等,但测试其功能有效性时往往难以获取明确的测试数据和验收条件。这种情况下,只能通过对算法的深入理解和根据经验生成或寻找数据,并大致评估功能测试结果的有效性来进行测试。而利用AI辅助当前的自动化测试则是一个新兴领域。使用AI(如深度学习)系统来帮助测试工作绝对是近几年最热门的测试趋势之一,其中包括自动生成并执行自动化测试、大规模测试结果分析、自动化探索性测试、缺陷定位等。美国已经有多家公司推出了商用的AI测试工具。在朱少民老师的公众号“软件质量报道”中,有一篇名为《未来已来,人工智能测试势不可挡:介绍9款AI测试工具》的文章,介绍了9款基于AI的测试工具。但这些AI测试工具普遍存在测试用例准确性和大规模测试用例可维护性等问题。第一个问题:AI辅助测试真的能用吗?虽然许多公司已经开始研究AI辅助测试,并有许多工具问世,但它们都有一个显著问题:准确性。由于现有的AI学习算法本身的限制,学习并生成的测试用例和验证条件的准确率都不是非常高。我曾参加过几个大会,其中一些中国一线互联网厂商分享的AI辅助测试的准确率仅略高于80%,不到90%。这种准确率在金融等某些对精度要求高的系统中很难得到认可。其次,当自动化测试用例规模很大时,测试用例的维护工作很难依靠人工完成,只能依靠工具。由于AI测试工具的不准确性,导致维护工作的准确性也不是十分理想。尽管如此,在质量要求不高的大型系统中,AI辅助测试可以极大地降低测试成本,因此在这些系统中,AI辅助自动化测试已经得到应用。此外,在质量要求高并且资源充足的项目中,AI辅助测试可以作为人工自动化测试的扩展,作为自动化探索性测试的一种工具,可以进一步保证软件质量。第二个问题:AI辅助测试已经发展到什么程度了?目前,AI辅助测试仍处于初级阶段。我将AI辅助测试分为三个阶段:第一阶段是通过深度学习模型自动产生测试用例的输入,然后通过人工验证输出结果的正确性。第二阶段是通过深度学习模型自动产生测试用例的输入,并通过规则模型自动验证输出结果的正确性。第三阶段是通过深度学习模型自动产生测试用例的输入和输出,并自动验证输出结果的正确性。目前业界已经基本实现了第一阶段,有一些公司也已经开始实现第二阶段。然而,只有极少数的大公司已经实现了第三阶段,并且这些公司的准确性还有待提高。因此,AI辅助测试仍有很长的路要走。第三个问题:哪些软件系统能用AI辅助测试?理论上,任何软件系统都可以使用AI来辅助自动化测试工作。然而,由于目前AI测试系统的现状,它还不能真正用于所有类型的软件系统。许多实际项目只在某些特定系统的特定接口层上使用AI测试,例如Web
2023年3月7日
其他

好代码的五个特质

Facade模式,https://design-patterns.readthedocs.io/zh_CN/latest/structural_patterns/facade.html•
2023年2月28日
其他

在DDD中建立领域模型

在前文《当我们谈论DDD时我们在谈论什么》中我们讨论了DDD的战略设计和战术设计。在本文中我们将继续探讨领域模型。用领域模型表达领域概念在实际项目中,模型设计者往往过早陷入具体构造块类型的识别,比如实体、聚合、领域服务,而忽略了领域模型表达领域概念的目的。我们应该基于领域概念设计领域模型,然后再采用合适的模式降低领域模型的复杂度,进一步增加领域模型的表达能力。领域模型的作用,一方面是关联代码实现,一方面是关联通用语言。我们对于模型和实现的关联轻车熟路,但是对于语言和模型关联往往有待提升。在沟通中刻意使用通用语言可以帮助我们验证模型的合理性。我们以一个题目为例,方便后续讨论。活动平台提供用户参与活动得到奖品的功能,吸引用户及潜在用户参与,以达到拉新、促活、引流的目的。运营人员可以创建和修改活动,活动的配置内容包括活动名称、活动介绍、活动开放的开始时间和结束时间、参与资格、权益。用户可以看到活动列表,在活动开放的时间段内进入活动页面看到活动介绍。用户在活动页面领取权益,经判断符合资格的用户就会获得一份奖品。权益可能是信用卡积分,也可能是优惠券。参与资格可能是:一天内注册的用户、VIP用户、当月生日的用户等。客户希望系统可以方便扩展支持灵活的资格类型,以支持多样的活动形式。对于一个活动,一个用户只能参加一次。建立模型第一步是根据需求分析模型。我们可以找到以下概念:活动、参与资格、权益。其中参与资格是扩展点。对于需求「一个用户只能参加一次活动的」,需要记录用户是否参与过活动,所以需要「活动参与记录」的概念。参与活动的结果可能有2种:符合参与资格则返回权益,不符合则返回「不符合」。所以我们用了Optional类型。我们到这里只识别了各种名词,需要走查用例,寻找缺失的概念:用例1,运营人员可以创建并修改活动用例2,用户可以参与活动并获得权益对于用例1,创建和修改活动,目前模型已经满足了需求。对于用例2,这里有一个模型之外的规则:「一个用户只能参加一次活动」。这是所有活动都需要遵守的规则,我们将其称为「活动通用规则」。虽然只是一个很简单的逻辑,但是提取「活动通用规则」这个概念非常有用。如果没有这个概念,那么每次去描述这个概念,只能用「一个用户只能参加一次活动的规则」去表示,非常繁琐;也让概念没有安身之地,容易被随便放到万能的Service中。我们将其加入领域模型。PS:这里故意省略了参与资格的实现。我们没有把「活动通用规则」放到活动概念里,一部分原因是这个判断逻辑不需要具体活动的信息。使用通用语言验证模型有了领域模型,就有了通用语言。使用通用语言重新描述需求,并尽量在沟通中使用通用语言。运营人员可以创建和修改活动,活动的配置内容包括活动名称、活动介绍、活动开放的开始时间和结束时间时间段、参与资格、权益。用户可以看到活动列表,在活动开放的时间段内进入活动页面看到活动介绍。用户在活动页面领取权益,经判断符合资格参与资格的用户就会获得一份奖品权益。权益可能是信用卡积分,也可能是优惠券。参与资格可能是:一天内注册的用户、VIP用户、当月生日的用户等。客户希望系统可以方便扩展支持灵活的资格类型,以支持多样的活动形式。同时有「活动通用规则」:对于一个活动,一个用户只能参加一次。这里去掉了「开始时间」、「资格」、「奖品」等模糊不清晰的描述。使用基于领域模型的语言,让需求描述清晰没有歧义。到目前为止,主要的领域模型都已经分析出来。所有的模型都对应明确的领域概念,不多也不少。识别构造块类型在分析了领域模型后,我们再来分析构造块类型。我们通过是否有状态来做区分。首先识别有状态的对象:活动、各种参与资格、权益、活动参与记录、用户。一般有状态的对象都是事物,对应的构造块类型也就是实体或者值对象。其次判断其状态是否会改变:活动会被修改,所以状态会被改变;参与资格会被修改,但是参与资格从属于活动,修改后可以直接使用新的对象替换旧的,所以可以设计成状态不变;权益和参与资格一样,也可以设计成状态不变;活动参与记录,状态可能发生变化;用户在这个模型中只是临时存在,状态不会变化。状态会改变的是实体,包括活动和活动参与记录;状态不变的就是值对象,包括参与资格、权益和用户。最后剩下的就是无状态的对象:活动通用规则。对应的构造块类型是领域服务。这里的无状态对象大都可以转化成有状态的对象,例如活动通用规则,可以将方法参数的Optional变成成员变量。只是这里我们选择了无状态的设计方法。由于领域服务没有状态,所以可以在应用启动时就创建出来,也可以在使用时才创建。经过分析,我们的领域模型都有了类型。设计聚合首先识别生命周期长的领域对象:在一个操作中被创建出来,操作结束后仍会被其他操作使用的对象。活动、参与资格、权益和活动参与记录都是生命周期长的对象。其他有状态的对象都是临时对象:在一个操作中被创建出来,操作结束后就不会再被使用。模型中的用户,在一次操作中从其他服务获取,使用后即被丢弃。这里我们总结下各构造块类型的特点:实体值对象领域服务是否有状态有且状态可变有且状态不可变无生命周期长长或者短长短均可在生命周期的长的对象中,我们要设计聚合。聚合作为操作单元,主要解决以下几个问题:整个模型往往庞大复杂,为了降低知识负载,需要将其分解成多个小且简单的模型,划分清晰的边界部分模型对象之间存在一致性规则,例如需要被一起删除,所以需要放在一个操作中多个用户可能会并发操作模型,为了避免相互干扰,需要让操作单元尽可能小对于操作单元,需要将其频繁加载到内存中,如果单元过大,往往不能满足性能要求根据对业务的了解,活动及参与资格、权益都是一起被创建和修改,可以放在一个聚合里;活动和活动参与记录之间没有一致性规则,可以分开;因为活动参与记录数量会很多,如果和活动在一个聚合中,会降低性能。所以我们将活动、参与资格、权益设计成一个聚合,而活动参与记录作为一个单独的聚合。而活动和活动参与记录分别作为这两个聚合的聚合根。对应的,聚合都会配备其专属的Repository。同时加上遍历方向箭头。由于活动是聚合根,从活动可以遍历到聚合内部的参与资格和权益。另外查询活动参与记录,可以通过其Repository,所以没有活动到活动参与记录的箭头。由于我们将活动和活动参与记录之间划分成不同聚合,那他们之间的关联将使用聚合的ID来关联,而不是聚合本身。PS:如果使用了关联对象,遍历方向也可以是从活动到活动参与记录。如何使用领域模型领域模型已经建立完毕,我们来看如何使用领域模型以满足用例。运营人员创建活动基本信息及其关联的参与资格和权益。领域模型的客户(一般来说是应用服务),使用运营人员输入的参数构造出活动对象,再利用Repository将其保存。运营人员修改活动。应用服务利用Repository获取需要修改的活动,再根据运营人员提供的参数修改活动,最后利用Repository保存活动对象。用户参与活动。应用服务:使用活动通用规则判断用户是否可以参加。由于活动通用规则需要用到活动参与记录,因此应用服务会使用Repository获取活动参与记录;如果可以参加,则执行活动的参与活动方法获得结果。这需要利用Repository获取用户参与的活动,并构造用户对象(可能需要调用用户服务获取用户信息,但是领域层并不关心这些逻辑);如果结果是获得权益,则创建活动参与记录,并利用Repository保存。考虑到并发情况,应用服务可以在第1步前加锁,并在第3步后释放锁。再次思考配置和参与活动可否是两个模型?在实现运营人员配置活动的用例过程中,我们会发现可能找到了一个隐藏的领域概念,将输入的参数转换成领域模型的逻辑有些枯燥和复杂,同样将领域模型和数据库的数据模型之间转换也如此。输入参数和数据模型都是只是扁平的数据数据,没有继承结构。如果使用另外一种面向数据的模型,也许这些用例实现起来会简单得多。每个模型都是为了解决某个问题。这里运营人员配置和用户参与活动是不同的问题,如果用一个模型来解决这两个问题,可能会有些吃力。那么干脆设计成两个模型,使用限界上下文的概念将这两个模型限定在各自的上下文中,也许更加合理。两个模型可以共享同一份数据库数据,并加上一段(非领域层的)逻辑用于模型之间的转换。这实际上是一种配置-使用模式。在配置阶段,注重配置类型和参数、审批等;在使用阶段,注重逻辑计算和性能。活动参与记录是否可以建模成领域事件?活动参与记录实际上是不可变的,可以将其设计为领域事件。用户参与活动的用例里,逻辑复杂,有泄漏领域概念的嫌疑?如果发现应用服务里逻辑变得复杂,可能意味着我们找到了一个隐藏的领域概念。我们可以定义一个「用户参与活动逻辑」的概念:如果用户通过了活动通用规则的判断,则可以参与活动。将其加入模型和通用语言中,在沟通中验证此概念是否合理。总结很多项目虽然也使用了以领域模型为中心的架构,但是设计者仍然是数据模型/贫血领域模型的思考方式,把大量领域逻辑放置在了万能的Service中,让领域概念隐藏在了冗长的过程代码中,无法享受到DDD带来的收益。最后总结下本文想要强调的要点:领域模型和领域概念一一对应领域模型和实现关联,也和通用语言关联。刻意使用通用语言沟通以验证模型是否合理演示了一种设计领域模型的步骤构造块类型不是最重要的,领域模型本身更加重要更多的使用可以表达业务含义的值对象和临时值对象聚合是一种设计,需要方法权衡使用Repository、Factory获取和创建领域模型是应用层的职责,领域层应该关注在表达领域概念-
2023年2月21日
其他

使用契约测试得不偿失?试试契约先行开发

良好的支持。如果不能根据契约生成好用的代码,或者在生成代码的过程中需要做过多的定制化,那么该方法可能并不适用,或者并不划算。在开发过程中需要有健全的集成测试或者组件测试。上述生成的代码中,虽然
2023年2月16日
其他

代码的简单设计五原则

」广义理解为要满足业务需求,不论是自动化测试还是手工测试,你需要做的是满足业务需求,只不过我们提倡尽可能编写足够的自动化回归测试。原则二:消除重复(职责)“重复乃万恶之源——Kent
2023年2月14日
其他

测试左移之需求质量

测试左移的由来缺陷的修复成本逐步升高下面是质量领域司空见惯的一张图,看图说话,容易得出:大部分缺陷都是早期引入的,同时大部分缺陷都是中晚期发现的,而缺陷发现的越晚,其修复成本就越高。因此,为了降低缺陷修复成本,我们期望在更早的时间发现缺陷。那么上图是否完全没问题呢?不是的,这张图来源于1996年的一本书《Applied
2023年2月9日
其他

被遗漏的度量指标

Productivity(参见参考资料1)中获得了印证。这篇文章中所提到的SPACE,代表度量软件开发生产力的5个维度——Satisfaction
2023年2月7日
其他

前后端分离的陷阱

不管你设计的系统架构是怎么样,最后都是你的组织内的沟通结构胜出。这个观点一直在组织内不断地被证明,但也不断地被忽略。前后端分离的利与弊近几年,随着微服务架构风格的引入、前后端生态的快速发展、多端产品化的出现,前后端分离已经成为行业的普遍实践,也是大型企业级分布式架构的缺省选择。前后端分离也给软件技术人员的职业发展和协作方式带来了新的变化,分别出现了前端工程师、后端工程师、前端开发团队以及后端开发团队。前后端分离使得前端关注信息架构,处理用户体验相关问题;而后端则关注构建业务能力、数据处理、持久化等问题,并向前端提供API接口(API
2023年2月2日
其他

怎样做好需求评审?

的还原度,后果是前端代码中所有的页面都有自己的样式文件,组件几乎无法复用。大的团队往往有自己的设计规范、设计系统等,这样也减少了高保真的输出,使用设计系统,不必输出高保真。开发人员使用原型图
2023年1月31日
其他

关于性能测试需要知道的

随着各企业的业务发展、用户量以及数据量的不断增加,系统承载的压力也会随之增加,服务系统的性能好坏又严重影响企业的利益。因此,性能测试重要性与需求越来越强烈。常见的性能测试目的性能测试是确定系统在特定工作负载下的稳定性和响应能力。在进行性能测试之前,首先是要明确性能测试的目的,目的不同,对应的解决方案会有很大差异,最常见的性能测试目的(或契机)有三种:评测当前系统性能通过性能测试了解系统当前的性能是否达到预期。例如:新系统上线前、技术升级后,都会进行性能测试,确保系统在线上稳定可靠地运行。寻找瓶颈,优化性能系统已知有性能问题,进行测试寻找瓶颈,以便优化其性能。例如:用户提出业务操作响应时间长,需要定位问题,调整性能;系统运行一段时间后,速度变慢,寻找瓶颈,进而优化预测系统未来的性能、可扩展性通过性能测试预测系统在未来达到一定负载量的情况下,系统的性能表现。为的是提前预防并降低风险。扩展能力非常好的系统,性能是随资源扩展呈线性或接近线性提升。性能测试的不同类型基准测试基准测试:系统较低压力时,查看系统的运行状况并记录相关数作为基础参考。负载测试负载测试是通过逐渐增加系统负载,测试系统性能的变化,并最终确定在满足性能指标的情况下,系统能承受的最大负载量的测试。目标:确定系统的性能容量(如系统在保证一定响应时间情况下能够允许多少并发用户的访问),系统各项指标,如吞吐量、响应时间、CPU负载、内存使用等如何决定系统的性能。压力测试压力测试通过确定一个系统的瓶颈或者不能接受的性能点,来获得系统能提供的最大服务级别的测试。目标:压力测试是为了发现在什么条件下您的应用程序的性能会变得不可接受。并发性能测试负载测试和压力测试通常被合称为并发性能测试。即大并发场景下的系统性能,多用户同时访问时,检测系统是否能够稳定运行。平均并发用户数C=nL/Tn:平均每天访问用户数(login
2023年1月19日
其他

结对编程踩坑指南

背景最近,我开始重新审视这些融入日常的工程实践方式,去尝试找出实际与理论的差距,分析差距成因,基于分析结果,尝试找出可以逐步弥补差距的实践方式,从而让日常软件交付工作变得更加“顺滑”。本文作为“沉思录”的第一篇,将列举实际交付项目中,在结对编程时遇到的几个实际问题,并针对具体问题给出一些尝试过的解决方式。如有其他更好的建议,欢迎共同讨论👋。注意:以下话题不在本文的讨论范围中,并且默认读者已经具备下列问题相关的知识:为什么进行结对编程?(如果想了解,可以参见维基百科(https://en.wikipedia.org/wiki/Pair_programming)
2023年1月17日
其他

敏捷是知与行的功夫

敏捷不是“一”种方法“敏捷是一种用于项目管理和软件开发的迭代方法,可帮助团队更快地向客户交付价值并减少风险。它不是将一切都押在“大爆炸”发布上,而是以小的增量交付成果。不断评估需求、计划和结果,因此能够快速地响应变化。”以上是一段常见的关乎敏捷的定义。而当我们动态地看待过去几十年的敏捷发展史,光是围绕敏捷二字产生的框架、实践、理论等,便是五花八门。早期的时候,有诸如
2023年1月12日
其他

来自开发者的点赞,Thoughtworks 入选 2022 中国技术品牌影响力企业榜

Google、Intel、阿里巴巴、百度、微软、腾讯、亚马逊云科技、字节跳动等。相信开发者的力量,一直以来
2023年1月11日
其他

技术债的前世今生

-分布式系统下的认证与授权作为QA,我们要如何思考?点击【阅读原文】可至洞见网站查看原文&加粗字体部分的相关链接。本文版权属Thoughtworks公司所有,如需转载请在后台留言联系。
2023年1月10日
其他

DDD的哲学意味(下)

阅读本系列前两篇文章:DDD的哲学意味(上)DDD的哲学意味(中)核心域与主要矛盾大约公元前800年至前200年间,中国、希腊、印度和以色列的文明几乎在同一时期兴起,这被称为人类文明的轴心时代。不同文明展现出了不同的风貌。中国古代文化强调辩证逻辑,重视变化、联系和综合的思维方式,同时又有“子不语怪力乱神,六合之外存而不论”的唯物主义倾向。古希腊则重视严格的推理和分析,孕育了形式逻辑和公理化的数学体系。印度在婆罗门和佛教哲学中,从另一个方向将辩证法、逻辑和语言学推向极致。以色列的先知则创立了一神论的犹太教和政教合一的社会体制。直到近代,西方才产生了系统的辩证法体系,集大成者是黑格尔。马克思和恩格斯吸收了黑格尔的辩证法,扬弃了其中的唯心主义成分,形成了辩证唯物主义,成为了风起云涌的无产阶级革命的理论基础。后来唯物辩证法传入中国,与中国传统文化中的辩证法和唯物主义思想一拍即合。为了将马克思主义中国化,毛老师写出了《实践论》和《矛盾论》。前文提到了《矛盾论》第一部分“两种宇宙观”,这一节看一下第四部分“主要的矛盾和主要的矛盾方面”。事物中包含着多种矛盾,其发展变化成为事物发展的内在动力。在多种矛盾中,一般会有一种占主导地位,称为“主要矛盾”。要有效地处理问题,就要抓住主要矛盾。例如某筹备开业的保险公司要开发一个保险核心系统。在开始时,“快速开展新单业务的需要与落后的新单处理能力”的矛盾就是主要矛盾,而“快速理赔的要求与落后的理赔能力”之间的矛盾则是次要矛盾。这是因为,新开业的保险公司首先面临的是新单业务的压力而不是理赔的压力。在领域驱动设计中,领域模型中包含主要矛盾的部分,称为“核心域”(Core
2023年1月3日
其他

周四直播 |如何用Team Topologies 落地组织架构设计?

Topologies落地组织架构设计及其优化?假如一家科技公司高管要优化组织架构,有哪些建议?👇点击阅读原文报名直播
2023年1月2日
其他

作为QA,我们要如何思考?

随着测试人员陆续开始尝试角色转变,坚守的QA需要找到自己的发展之路。兴趣和性格是客观因素,好奇心和发散性思维则是帮助成为优秀QA的必要因素。我想通过一些小的例子来与大家互动探讨。测试你做对了吗?让我们从这样一个现实中的小例子来开始我们的思考之旅
2022年12月29日
其他

分布式系统下的认证与授权

(https://www.pingidentity.com/en/resources/blog/post/jwt-security-nobody-talks-about.html)由于
2022年12月27日
其他

你的团队是王者还是青铜(下)

接着你的团队是王者还是青铜(上)继续聊。问题4:谁动了团队的时间?如果重来一个迭代,你有7*40个小时的投资,你要如何决策团队的工作安排?““小溪,一会约开卡;小溪,我这有个问题;小溪,一会约验收......”“龙哥,第三方集成那边临时有个会议,需要来沟通一下;龙哥,客户那里有个代码规范变化了,你来看一眼;龙哥,API设计的不对;龙哥,日志找不到了......”“阿泰,七哥,早上新开的卡都先别做了,有另外一个feature进来”“小波(刚加入团队2周),需要你去另一个团队”“刚打开微信准备回复一个消息,看到之前同事的消息又顺手处理一下,一封邮件从屏幕上弹了出来,又顺手点开”。。。。。。”“公司特别热衷于保护,保护了那么多的东西,却总是没能护住最脆弱也最稀有的东西:员工的时间和注意力...,这是我们最稀缺的资源”
2022年12月22日
其他

单体优先的微服务架构

-使用CDC模式改造遗留系统DevOps最佳实践之应用开发和部署点击【阅读原文】可至洞见网站查看原文&加粗字体部分的相关链接。本文版权属Thoughtworks公司所有,如需转载请在后台留言联系。
2022年12月20日
其他

你的代码会说话吗?(下)

篇首语代码不讲真话的直接后果是所有人被误导了,然后做了一件错误的事情,不自知地将错就错,让错误越陷越深,最后浪费宝贵的时间。可不讲真话,编写代码的人又不是故意的,也万万不可上纲上线,袁帅秉着内训师作为知识沉淀者和文化传播者角色的原则,借助教育代码的机会组织了一次部门内部的闲聊会,并美其名曰:Clean
2022年12月15日
其他

Thoughtworks x 哈佛商业评论|超越技术,利用 Data Mesh 创造业务价值

方法下,数据管理标准是分布式的,这意味着处理数据产品的每个领域都需要遵循这些标准。第一步是创建可分布、适用于整个组织的标准。下一步是确保数据团队在其产品中维护这些标准。利用
2022年12月13日
其他

用测试金字塔指导数据应用的测试

由于数据应用开发和功能性软件系统开发存在很大的不同,在我们实践过程中,在开发人员和质量保证人员间常常有大量关于测试如何实施的讨论。下文将尝试总结一下数据应用开发的特点,并讨论在这些特点之下,对应的测试策略应该是怎么样的。功能性软件的测试先来回顾一下功能性软件系统开发中的测试。测试一般分为自动化测试和手工测试。由于手工测试对人工依赖程度很高,如果主要依赖手工测试来保证软件质量,将无法满足软件快速迭代上线的需要。现代软件开发越来越强调自动化测试的作用,这也是敏捷软件开发的基本要求。有了全方位的自动化测试保障,就有可能做到每周上线,每日上线甚至随时上线。这里主要讨论自动化测试。测试金字塔我们一般会按照如下测试金字塔的原则来组织自动化测试。测试金字塔分为三层,自下而上分别对应单元测试、集成测试、端到端测试。单元测试是指函数或类级别的,较小范围代码的测试,一般不依赖外部系统(可通过Mock或测试替身等实现)。单元测试的特点是运行速度非常快(最好全部在内存中运行),所以执行这种测试的成本也就很低。单元测试在测试金字塔的最底端,占的面积最大。这指导我们应该构建大量的这类测试,并以这类测试为主来保证软件质量。集成测试是比单元测试集成程度更高的测试,它在运行时执行的代码路径更广,通常会依赖数据库、文件系统等外部环境。由于依赖了外部环境,集成测试的运行速度更慢,执行测试的成本更高。集成测试在测试金字塔的中间,这指导我们应该构建中等数量的这类测试。集成测试在Web应用场景中也常常被称为服务测试(Service
2022年12月13日
其他

打工人的发展困境

近期在公司内部QE社区举办了一场研讨会,主题是《QA角色职业发展机遇讨论》。收集到以下观点,觉得挺有意思,又不局限于特定角色,于是用XX代替QA。无论是在公司内部还是外部,XX都是单独作战居多,从他人身上学习的机会较少。XX最终的发展,技术或管理,技术就一定需要代码能力很强吗?如果XX一直走技术路线,能达到什么高度?XX行业上升通道天花板比其他角色低。据传XX行业萎缩,门槛低,管道压力大。发展方向很多,不容易选择。工作本身已经失去了成长价值。想推动一些优秀实践,但推不动或者效果不好,怎么办?打工人的发展困境从观点中可以看出,不少伙伴对自己未来的职业发展充满了困惑,主要集中在以下几个方面:价值感缺失、晋升通道不明朗、干系人不满意,下面我们来展开详细的讨论。价值感缺失价值感缺失,正常又普遍。我们所做的大部分重复性事务,都很难说有多高的价值。喜欢的音乐,设置成闹铃后就会厌倦;美味的食物,反复吃就味同嚼蜡;你爱谈天我爱笑,也会从一往情深走到相看两厌。并不是事物本身发生了变化,而是体验者心境变了,人性本就厌恶重复。不仅大量重复的手动测试会造成价值感缺失,大量重复的写自动化测试、写业务代码、写需求卡片,都一样会厌倦。究其根本,不断重复会提升熟练程度,由最初的思考产生决策变为依赖经验主义,逐渐失去挑战、步入舒适区,不再汲取新的东西,没有新的收获,也就体会不到价值。这不是某单一角色特有的问题,从普通而又琐碎的日常中寻找价值,是每个人都需要面临的问题。晋升通道不明朗传统的人才结构中,有“双通道职业发展体系”,不管是走管理路线,还是走技术路线,发展通道都是明确的,我们都有光明的未来。在这个体系中的每个人,都知道自己可能的发展方向和晋升通道。但那是以前。“双通道”
2022年12月8日
其他

DDD的哲学意味(中)

“关联”、《矛盾论》、毕达哥拉斯学派DDD的哲学意味(上)说到了“模型驱动的设计”以及其中两个重要的模式“实体”和“值对象”,两者统称“领域对象”。在领域建模的过程中,建立领域对象间的“关联(Association)”也是非常重要的。《DDD》第5.1节对此进行了专门的讨论。不过与实体不同,艾老师并没有把关联当做一种正式的“模式”。这一点实属可惜,因为关联至少与实体有同样的重要性。为什么这么说呢?下面还是先扯几句哲学。前面提到毛老师的《实践论》,这里再说说怹老人家的另一篇杰作《矛盾论》。这篇论文的第一部分“两种宇宙观”中提到了两种认识论体系:“形而上学”和“唯物辩证法”。前者是错误的、后者是正确的。形而上学认为事物的发展是静态的、外因驱动的、孤立的;唯物辩证法则认为事物的发展是动态的、内因驱动的、联系的(还记得中学政治课背过吗?)。前两点我们后面再聊,这里先讨论“联系”。《矛盾论》中引用列宁的话:“要真正地认识事物,就必须把握住、研究清楚它的一切方面、一切联系和‘中介’。我们永远也不会完全做到这一点,但是,全面性这一要求可以使我们防止犯错误和防止僵化。”这强调了,只有充分了解事物之间的联系,才能充分认识事物。DDD中,领域(事物)的概念以实体、值对象、聚合、模块等方式表达出来。有些伙伴把领域中的主要聚合或实体识别出来后,却没有识别它们之间的关联,就认为已经完成了领域建模。这样的模型其实是不完整的。那么,如果我们认识到了这一点,并且识别出了关联之后,还要进一步识别关联上的哪些信息呢?让我们先看一下古老的毕达哥拉斯学派。这个学派在古希腊最早对数学进行了系统的研究。他们发现了无理数,然后把泄露无理数秘密的团队成员扔进了大海。毕达哥拉斯认为世界的本原是“数”。宇宙的和谐来源于数的和谐。而数的和谐体现在十组对立的关系中:一与多、奇与偶、左与右、阴与阳、动与静、曲与直、明与暗、善与恶、方与长、有限与无限。在这十组关系中,最根本的是“一与多”。也就是说,只有把握了“一与多”,才能把握“数”,进而把握世界。从毕达哥拉斯的学说中,我们或许可以得到这样的启发(嗯
2022年12月6日