拆分巨石:将MVPS和MVAS应用于遗留应用程序——可持续架构(六)
前言
- MVP 和 MVA 的概念不仅适用于新应用程序;它们提供了一种新颖的方式来审视对遗留系统的范围变更,以防止过快地承担过多的变化 - 参见图1。
- MVA 可以帮助组织评估和更新其技术标准,通过展示新技术如何真正对支持 MVP 至关重要。
- 创建 MVA 可以帮助团队评估哪些遗留系统的部分现在需要现代化,哪些部分可以等待。
- 遗留应用程序,由于其经常是使命关键的,需要特别关注可持续性。
- 最后,有必要记住,今天的遗留应用程序在很多情况下曾经是闪亮而新颖的。将 MVA 视为每个新发布的一部分有助于保持应用程序的新鲜度。
遗留应用程序通常陷入慢车道:老化和脆弱,理解不足且几乎得不到支持,基于老化技术,它们往往是最后一个受益于诸如持续交付之类现代概念的应用程序。然而,由于它们潜在的不稳定性,实际上它们是最能从诸如最小可行产品(MVP)及其相关的最小可行架构(MVA)等概念中受益的应用程序。
这是怎么可能的呢?大多数遗留应用程序相对来说是巨石的,很难逐步发布。
一旦你意识到每个发布都是价值实验,其中发布要么提高了客户体验的价值,要么没有,你就会意识到每个发布,即使是遗留应用程序的发布,也可以从MVP的角度来考虑。每个发布实际上都是一个与您希望提供的附加价值相关的MVP。因此,每个发布也都有一个MVA。MVP和MVA等概念为团队提供了对他们所测试的有关客户真正价值变化的假设的绝对必要性的极致关注。
由于MVP概念最常与新产品相关联,因此将现有应用程序的每个新版本视为最小可行增量可能更好,即团队认为将产生客户体验价值改进的最小变化集。但由于“MVP”一词已经被广泛使用,我们将继续使用它。
正如我们在之前的文章中最小可行产品需要最小可行架构所指出的,MVA是确保MVP满足其质量属性需求(QARs)所需的最小架构量。由于对我们而言,架构主要是关于技术决策,因此遗留应用程序发布的MVA代表了团队需要进行的最小应用程序更改集,以确保发布支持其QARs。
发布准备的MVP标准通常集中在发布是否能让团队测试其对客户期望结果的理解上;MVP并不是“技术概念验证”。同样,通过评估对遗留应用程序进行的更改是否能确保发布能够满足应用程序的QARs,并且通过这样做能够可持续地满足客户需求,可以确定MVA的发布准备情况。
图1:MVP和MVA提供了一个以新的方式看待遗留系统的“视角”
流程挑战
任何发布的标准之一,尤其是组织所依赖的应用程序,是该应用程序已通过一组测试(最好是自动化的),验证发布候选版本是否满足其质量属性要求(QARs)。进行手动测试以评估QARs太繁琐且容易出错,不足以保证可靠性。缺乏自动化测试来确定发布是否符合其功能要求和QARs是阻止组织以小批量交付价值的因素之一。
其他因素有时会阻止组织以小批量方式发布,导致它们以相对较大、复杂的增量发布变更。这些因素包括:
- 缺乏有效的构建、测试和发布自动化。当交付流程的重要部分是手动的时候,手动步骤引入的延迟和错误会阻碍组织迅速行动。即使部分自动化,团队之间的交接引入的延迟也会减慢速度。虽然这些问题的解决方案层出不穷,但它们要求组织改变工作方式,有时还要改变组织的结构。
- 应用程序之间的紧密耦合。当应用程序共享数据或组件时,对其中一个应用程序的更改可能需要重新发布另一个应用程序。具有紧密耦合的遗留应用程序的组织可能很难进行小的更改,因为他们无法承担重新发布可能需要重新发布的所有应用程序的时间或精力。
- 繁琐的发布批准流程。由于许多遗留应用程序在某种程度上已成为业务关键,因此需要从可能并不真正了解与变更相关的技术问题的高级业务主管那里获得更改批准。当他们需要对更改的范围和风险感到满意时,将更改转化为通用术语所需的时间和精力可能是相当可观的。
- 监管限制。受监管行业的组织可能需要获得监管批准以发布新产品,或者对现有产品进行重大改变。他们还需要向监管机构报告客户对这些产品的使用情况。他们很难利用MVP概念,因为监管机构通常希望了解新产品或更改产品的各个方面。使用MVP的整个目的是通过真实的客户体验数据回答关键问题,因此组织陷入了一种进退两难的境地;他们无法发布产品来测试MVP,但他们又无法完全定义新产品(或更改的产品)而没有经验。这些公司似乎注定要受到监管限制的困扰,因为他们可能会过度投资于客户不需要的产品,因为他们无法及早和逐步地测试想法。
- 专业知识短缺(或丧失)。在某些情况下,组织可能不再真正了解遗留应用程序的业务逻辑或应用程序所基于的技术。解决此问题的一种方法是逐步用更有效的现代解决方案替换仍然相关的遗留应用程序部分,逐个解决客户结果。这样做,组织可能会发现许多遗留应用程序不再相关或不再需要,但要弄清楚这一点需要时间,在短期内,组织将面临一个更加碎片化的解决方案,存在永远无法完全解决的风险,因为其他挑战总是会出现。
除了监管限制外,这些问题都可以解决,但需要时间和共同努力。
偿还技术债务的困境
在有机会偿还债务时,听起来好像是件好事,对吧?
有时组织会受到诱惑,要做额外的技术工作,现代化,或减少他们的技术债务,因为,正如他们可能合理化的解释的那样,"我们无论如何都会在应用程序的那部分上工作,所以我们应该趁着在那里的时候把事情处理好。"虽然出于善意,但这几乎总是一个不好的决定,会导致不必要的成本和延迟,因为一旦开始,很难决定停下来。
这就是MVA概念发挥作用的地方:它给了每个人一个决定哪些变化必须进行,哪些变化不应该进行,至少还不应该进行的方式。如果一个变化对于实现发布的所需客户结果是必要的,那么它就是MVA的一部分,否则就被排除在外。
有时,一个团队可能会审视应用程序所需的变化,并决定,考虑到代码的状态,进行完全重写是必要的。应用于遗留应用程序的MVA概念有助于通过质疑这一点来缓和,即这些变化是否真的必要以产生所期望的客户结果的逐步改进。
应用程序可能确实已经过时无法扩展了,但根据我们的经验,“全面重写”几乎从未成功过(我们从未见过,甚至没有听说过这些项目中的一个真正交付了任何东西)。如果你真的要重新设计,不要重新编写现有系统;相反,从客户期望的结果出发,寻找不同的交付方式。
可行性和发布范围
MVA对MVP有影响,特别是对于遗留应用程序而言。MVA和MVP都包含一个重要的词:可行性。如果在评估团队需要对应用程序进行的更改以实现MVP时,他们确定以可持续的方式实现MVP成本太高,那么就需要重新考虑并可能更改MVP。
利用MVA方法:使用QARs
最小可行架构(MVA)方法(参见文章【最小可行产品需要最小可行架构】)提供了一种决定现代化程度“足够好”的方式,以便交付MVP。将MVA作为MVP交付工作的一部分来创建有助于评估技术可行性,并为产品提供一个稳定的基础,可以随着产品的发展而进行调整。透明地进行MVA架构决策有助于组织更好地理解为何会做出某些选择的原因,从而帮助他们更好地决定如何将产品适应不断变化的市场条件和不断发展的客户需求。
QARs驱的决策:需要做出的最重要的MVA架构决策可能是选择最少量的架构组件,使MVP能够处理与产品/系统特性相关的QARs,例如:
- 并发性——与产品必须响应的同时用户数量、传感器和其他创建事件的设备数量有关。
- 吞吐量——与产品必须在定义的时间段内处理的交易或数据量有关。
- 延迟和响应性——与产品必须对事件作出响应的速度有关。
- 可扩展性——与系统通过增加系统成本来处理增加的工作量的能力有关,通常是近线性关系。
- 持久性——与产品必须存储和检索的数据的吞吐量和结构(或缺乏结构)有关。通常包括有关不同种类数据存储技术的决策(例如SQL数据库管理系统、NoSQL数据库管理系统等)。
- 安全性——与产品如何保护自己免受未经授权的使用或访问产品数据的影响有关,实现机密性、完整性和可用性。
- 监控——与产品如何被仪表化以便支持产品的人员可以了解产品何时开始无法满足QARs并防止关键系统问题有关。
- 平台——与产品如何满足与系统资源约束相关的QARs,例如内存、存储、事件信号等有关。例如,实时和嵌入式产品(如数字手表或自动制动系统)与基于云的信息系统具有完全不同的约束条件。
- 用户界面——与产品如何与用户进行通信的决策有关;例如,虚拟现实界面与二维图形用户界面具有完全不同的QARs,而命令行界面则与二者具有完全不同的QARs。这些决策可能会影响上述其他QARs。(图形用户界面、虚拟现实、命令行或其他类型的界面。)
例如,假设您计划构建一个移动应用程序,以支持在新市场推出产品,使用开源或商业框架来帮助您快速交付MVP,同时为传统系统数据创建一个新界面。在这样做的过程中,传统应用程序将不可避免地面临其设计未能处理的工作负载。这些增加的工作负载会导致传统系统失败吗?额外的工作负载会威胁传统系统满足现有用户的QARs的能力吗?移动应用程序会改变传统系统的QARs吗?
不可避免地,访问传统系统数据的新应用程序将通过改变工作负载、吞吐量、响应性和安全相关需求等方式改变传统系统的QARs。传统系统并非建立在满足新应用程序用户需求的基础上,而在决定如何以及在何处修改传统系统时,必须考虑到这些需求。在某些情况下,无论付出多少工作,传统系统都无法满足新的QARs,在这种情况下,传统系统将不得不被替换,以便支持新的应用程序。
经验主义是评估这些问题的强大工具,新移动应用程序的每个发布至少都将为评估传统系统架构是否能够满足对其提出的新需求提供机会。开发团队很可能需要修改传统应用程序以满足新的QARs。将传统应用程序的变化视为移动应用程序MVP发布的一部分将有助于团队决定要承担多少变化以实现移动应用程序MVP发布的目标。
QARs是诊断传统系统潜在改进领域的非常有用的工具。专注于QARs可以帮助您将变化范围限制在目前仅需最小限度的内容,以支持MVP。这有助于防止滑入到“全面重写”的泥潭,这是昂贵的、耗时的、容易失败的,而且通常对于MVP来说是不必要的。
限制新功能的范围:抵制超出MVP范围的诱惑,将此努力变成一个更大的项目,包括MVP所不必要的“不错的”功能。领域驱动设计(DDD)是一种极其强大的软件开发方法,对于确定需要实现的新功能范围以支持MVP并将其限制在确切所需的内容方面非常有效。
尝试解耦和简化系统组件。在与传统系统一起工作的挑战之一是它们缺乏模块化,许多系统在编写时并没有鼓励模块化代码,大多数代码重用都是通过“复制和粘贴”完成的。尽管重构所有这些冗余代码很诱人,但要保持在支持MVP所需的范围内。当您确实需要重构或替换代码时,确保新代码是模块化且可重用的。在某些情况下,微服务和无服务器函数也很有效。在需要更改的应用程序中,用对共享组件或服务的调用替换代码,同时为可能有类似机会的其他应用程序做笔记。这样,当其他团队必须修改其应用程序以使用类似服务时,他们将有一些优势。
开始将新工作远离传统系统。除非在传统系统中实现新功能显着简单且更可持续,否则应使用现代技术(如基于云的服务)开发与MVP相关的新业务功能。如果新功能必须从旧程序启动,那么为新工作编写一个新的组件或服务,然后只需从旧代码中调用它。随着时间的推移,上述解耦工作以及将新代码移至现代技术将减少您需要担心的传统代码量。
使用诸如“植绳者模式”或“分支抽象”模式等模式,以及在适用时实现网关来路由请求到新的MVA组件可能对此迁移有所帮助。请记住,所有方法和工具都有局限性。例如,使用“植绳者模式”适用于从单个应用程序迁移明确定义的功能块,但如果您需要替换影响数十个应用程序的破损基础设施,则可能不是正确的方法。
开始识别“死代码”并找机会消除它。使用静态和动态代码分析工具找出传统系统中不再使用的部分,范围包括MVA。将死代码作为消除目标(但不要立即着手 - 要注意范围蔓延)。这可以延伸到报告 - 旧系统产生大量报告,其中一些(或许多)可能对任何人都不再有用;业务可能已经发生了变化,而系统没有变化。识别不再有用的代码可以帮助团队更轻松地看到该代码是否会影响MVA。部署的代码越少,其余代码越可靠,关键系统资源的使用越轻。即使团队决定不消除代码,他们也应该识别死代码的潜在消除机会,以帮助其他团队做出未来的决策。
组织技术标准延续了传统系统。组织技术标准对于防止不可支持的配置和基础设施技术组合的增加非常有用,但如果保留时间过长,它们可能会让组织根深蒂固于过去,无法适应未来。使用MVA概念可以帮助组织了解新技术是否真正需要以使团队能够交付特定的MVP。有了MVA提供的证明,组织可以决定MVP是否真正战略,并因此需要改变技术标准。
组织技术标准延续了传统系统。组织技术标准对于防止不可支持的配置和基础设施技术组合的增加非常有用,但如果保留时间过长,它们可能会让组织根深蒂固于过去,无法适应未来。使用MVA概念可以帮助组织了解新技术是否真正需要以使团队能够交付特定的MVP。有了MVA提供的证明,组织可以决定MVP是否真正战略,并因此需要改变技术标准。
你应该将MVA数据存储在哪里。关键的MVA决策之一是选择一个数据存储库来存储与MVP相关的数据。这些数据很可能已经存在于传统的数据存储库中,而且在大多数情况下,还需要捕获和存储额外的数据。这些数据可以整合到传统的数据存储库中,或者可以实现一个新的、更现代化的数据库管理系统(DBMS)来存储新数据。第一种方法简化了数据聚合和报告,但会扩展可能被淘汰的技术的使用范围——例如,IMS/DB。如果只需要添加少量现有的MVA传统数据来支持MVP,则可能是合适的选择。第二种方法限制了传统数据存储库的使用,但复杂化了数据聚合,如果需要添加大量现有的MVA传统数据,则应考虑该方法。第二种方法的一个变体是将现有的MVA传统数据迁移到新的DBMS中。然而,迁移数据比迁移功能更加困难,因为这些数据可能被MVA范围之外的多个传统应用程序使用。尝试这样做可能会导致超出MVA范围的工作。
总结
传统系统有点像一个古老的城市,仍然是一个繁荣的大都市:它们的新旧混合使得很难跟上所需的修复工作,更别提对其进行大规模的翻新以适应快速变化的需求了。但是,找到一种持续适应传统系统的方式对于将企业发展到一个不断变化的世界中至关重要。
MVP和MVA的概念不仅适用于新应用程序;它们提供了一种新颖的方法来审视对传统系统的变更范围,以防止过快地进行过多的变更。事实上,每一个新应用程序在其第一个重大发布之后都会成为一种“传统应用程序”,因此在应用程序不断发展的过程中,限制变更范围的方式很重要。
MVA方法可以帮助组织通过展示新技术如何真正支持MVP来评估和修改其技术标准。它使您能够通过真实数据来挑战技术标准,而不仅仅是凭借偏好和观点。
创建MVA的过程可以帮助团队评估现在需要现代化的传统系统的哪些部分,以及哪些部分可以等待。许多组织已经在失败的“全面重写”现代化项目上花费了巨额资金,而事实上,这些项目事后证明是不必要的。识别现在必须现代化的部分,以及哪些部分可以等待是有用的,因为这使得组织更好地了解了他们的技术债务,同时为他们提供了一个非常需要的过滤器,以防止不必要的工作。
由于传统应用程序通常是至关重要的,因此它们需要特别关注可持续性。事实上,害怕使传统应用程序变得不稳定阻止了许多组织对它们进行重要和必要的渐进性改进,使它们变得更加脆弱和充满风险。专注于可持续性QAR,包括培养团队发展应用程序所需的技能,有助于使应用程序随着时间的推移变得更加强大。
最后,值得记住的是,今天的“传统”应用程序在很多情况下,在不久前还是全新的。这些不仅仅是40年前编写的应用程序;它们也是仅仅10年前甚至更近期编写的应用程序。一旦一个应用程序不再持续更新,它就开始腐化。将MVA作为每个新版本的一部分考虑,有助于保持应用程序的新鲜度。
相关文章:
拆分巨石:将MVPS和MVAS应用于遗留应用程序——可持续架构(六)
前言 MVP 和 MVA 的概念不仅适用于新应用程序;它们提供了一种新颖的方式来审视对遗留系统的范围变更,以防止过快地承担过多的变化 - 参见图1。MVA 可以帮助组织评估和更新其技术标准,通过展示新技术如何真正对支持 MVP 至关重要。创建 MVA 可…...
Linux renice命令教程:如何优雅地调整进程优先级(附案例详解和注意事项)
Linux renice命令介绍 renice命令在Linux中用于修改已经运行的进程的优先级。这个命令允许你改变一个已经运行的进程的调度优先级。如果我们给一个进程设置了更高的优先级,那么内核将为该进程分配更多的CPU时间。 Linux renice命令适用的Linux版本 renice命令在所…...
Gitea 的详细介绍
什么是 Gitea? Gitea 是一个开源、轻量级的自托管 Git 服务,它允许用户搭建类似于 GitHub 或 GitLab 的代码托管平台。由于采用 Go 语言开发,Gitea 具有高效的性能和跨平台特性,适合个人开发者或小团队使用。 Gitea 的特点 轻量…...
Kotlin object
object 的三种用法 Kotlin 的 object 关键字有三种用法: 对象声明 ,一般用来实现单例伴生对象 ,类似 Java 的 static 关键字,也可以用于工厂方法模式对象表达式 ,一般用来代替 Java 的匿名内部类 对象声明 object 的语义是这样的: 定义一个类并创建一个实例 。不管是对象…...
【Redis】数据类型、事务执行、内存淘汰策略
目录 数据类型 Redis事务执行步骤 步骤: redis内存淘汰策略 设置内存淘汰策略 1.设置配置文件 2.通过命令设置 数据类型 官网解释 Understand Redis data types | Redis 首先,Redis 的所有键都是字符串,常用的数据类型有 5 种:Strin…...
Python Flask Web框架初步入门
前言 flask基础 搭建flask服务器 定义html 使用templates模板定义页面的html html页面编写 render_template传参变量 定义图片 创建static目录,存入图片 html编写 flask入门 网站多域名 网站之间超链接跳转 入门案例 将centos的rpm包下载链接集成到自…...
【设计模式】工厂方法模式详解
在java中,万物皆对象,这些对象都需要创建,如果创建的时候直接new该对象,就会对该对象耦合严重,假如我们要更换对象,所有new对象的地方都需要修改一遍,这显然违背了软件设计的开闭原则。如果我们…...
独立游戏《星尘异变》UE5 C++程序开发日志3——UEC++特供的数据类型
本篇日志将介绍FString,FText、FName的用法和相互转换,以及容器TMap,TArray的增删查改 一、字符串相关数据类型:FString、FText、FName FString是最接近std::string的类型,字符串本身可以看做一个存储char型的动态数…...
递归方法的理解
递归方法调用 :方法自己调用自己的现象就称为递归。 递归的分类 : 直接递归、间接递归。 直接递归:方法自身调用自己 public void methodA (){ methodA (); } 间接递归:可以理解为A()方法调用B()方法,B()方法调用C()方法&am…...
css之flex布局文本不换行不显示省略号的解决方法
文章目录 一、单行长文本显示省略号二、flex布局下的处理技巧 一、单行长文本显示省略号 先讲讲常规情况下长文本不跨行显示省略号的代码: overflow: hidden; //不允许内容超出盒子 white-space: nowrap; //不允许文本跨行 text-overflow: ellipsis; //文本超…...
华清远见STM32U5开发板助力2024嵌入式大赛ST赛道智能可穿戴设备及IOT选题项目开发
第七届(2024)全国大学生嵌入式芯片与系统设计竞赛(以下简称“大赛”)已经拉开帷幕,大赛的报名热潮正席卷而来,高校电子电气类相关专业(电子、信息、计算机、自动化、电气、仪科等)全…...
若依框架实现不同端用户登录(后台管理用户和前台会员登录——sping security多用户)
目录 需求背景 前期准备 实现UserDetailsService接口 改造loginUser 声明自定义AuthenticationManager 的bean 自定义登录接口 参考文章 效果如下 需求背景 用若依搭建的后台管理环境,但是前台用户系统(前端)并没有和若依的前端集成在一起。…...
【解決|三方工具】Obi Rope 编辑器运行即崩溃问题
开发平台:Unity 2021.3.7 三方工具:Unity资产工具 - Obi Rope 问题背景 使用Unity三方开发工具 - Obi Rope 模拟绳索效果。配置后运行 Unity 出现报错并崩溃。通过崩溃日志反馈得到如下图所示 这是一个序列化问题造成的崩溃,指向性为 Obi…...
岭师大数据技术原理与应用-序章-软工版
HeZaoCha-CSDN博客 序章—软工版 一、环境介绍1. VMware Workstation Pro2. CentOS3. Java4. Hadoop5. HBase6. MySQL7. Hive 二、系统安装1. 虚拟网络编辑器2. 操作系统安装 三、结尾 先说说哥们写这系列博客的原因,本来学完咱也没想着再管部署这部分问题的说&…...
Leetcode 680. 验证回文串 II
给你一个字符串 s,最多 可以从中删除一个字符。 请你判断 s 是否能成为回文字符串:如果能,返回 true ;否则,返回 false 。 示例 1: 输入:s “aba” 输出:true 示例 2:…...
网络安全接入认证-802.1X接入说明
介绍 802.1X是一个网络访问控制协议,它可以通过认证和授权来控制网络访问。它的基本原理是在网络交换机和认证服务器之间建立一个安全的通道,并要求客户端提供身份验证凭据。如果客户端提供的凭据是有效的,交换机将开启端口并允许访问。否则&…...
iPhone的iOS系统:定义移动智能体验,引领科技潮流之巅
来自:dlshuhua.com/post/83721.html 在移动智能设备领域,iPhone一直以其出色的性能和独特的用户体验脱颖而出。而这一切的背后,离不开其强大的操作系统——iOS。iOS系统不仅为iPhone提供了强大的性能支持,更通过不断创新和升级&a…...
计算机网络:传输控制协议(Transmission Control Protocol-TCP协议
计算机网络:传输控制协议(Transmission Control Protocol-TCP协议) 本文目的前置知识点TCP协议简介主要特性通信流程1. 建立连接的过程(三次握手,243)1.1 为什么要三次握手,两次不行吗? 2. 释放连接的过程(…...
GEE实践应用|热岛效应(一)地表温度计算
目录 1.学习目标 2.理论介绍 3.从MODIS获得地表温度 4.从Landsat卫星获得地表温度 1.学习目标 ①了解如何使用GEE计算地表温度 2.理论介绍 城市化涉及用建筑物、道路和停车场等建筑结构取代自然景观。这种土地覆盖的改变也改变了土地表面的特性。这些变化的范围从表面反射和…...
Java查找算法知识点(含面试大厂题和源码)
查找算法是计算机科学中的基础概念,它们在解决实际问题时扮演着关键角色。了解和掌握不同的查找算法,能够帮助我们更高效地处理数据检索任务。以下是一些关于查找算法的关键知识点: 算法分类: 线性查找算法:按照顺序逐…...
67、yolov8目标检测和旋转目标检测算法部署Atlas 200I DK A2开发板上
基本思想:需求部署yolov8目标检测和旋转目标检测算法部署atlas 200dk 开发板上 一、转换模型 链接: https://pan.baidu.com/s/1hJPX2QvybI4AGgeJKO6QgQ?pwdq2s5 提取码: q2s5 from ultralytics import YOLO# Load a model model YOLO("yolov8s.yaml")…...
A Little Is Enough: Circumventing Defenses For Distributed Learning
联邦学习的攻击方法:LIE 简单的总结,只是为了能快速想起来这个方法。 无目标攻击 例如总共50个客户端,有24个恶意客户端,那么这个时候,他需要拉拢2个良性客户端 计算 50 − 24 − 2 50 − 24 0.923 \frac{50-24-2}{…...
文心一言 VS 讯飞星火 VS chatgpt (225)-- 算法导论16.3 7题
七、推广赫夫曼算法,使之能生成三进制的码字(即码字由符号0、1、2组成),并证明你的算法能生成最优三进制码。如果要写代码,请用go语言。 文心一言: 推广赫夫曼算法以生成三进制码字需要对算法进行一定的修改,确保在每…...
【计算机】——51单片机——持续更新
单片机是一种内部包含CPU、存储器和输入/输出接口等电路的集成电路(IC芯片) 单片机是单片微型计算机(Single Chip Microcomputer)的简称,用于控制领域,所以又称为微型控制器(Microcontroller U…...
QT资源添加调用
添加资源文件,新建资源文件夹,命名resource,然后点下一步,点完成 资源,右键add Prefix 添加现有文件 展示的label图片切换 QLabel *led_show; #include "mainwindow.h" #include<QLabel> #include&l…...
LeetCode-49. 字母异位词分组【数组 哈希表 字符串 排序】
LeetCode-49. 字母异位词分组【数组 哈希表 字符串 排序】 题目描述:解题思路一:哈希表和排序,这里最关键的点是,乱序单词的排序结果必然是一样的(从而构成哈希表的key)。解题思路二:解题思路三…...
绘制特征曲线-ROC(Machine Learning 研习十七)
接收者操作特征曲线(ROC)是二元分类器的另一个常用工具。它与精确度/召回率曲线非常相似,但 ROC 曲线不是绘制精确度与召回率的关系曲线,而是绘制真阳性率(召回率的另一个名称)与假阳性率(FPR&a…...
.Net 知识杂记
记录平日中琐碎的.net 知识点。不定期更新 目标框架名称(TFM) 我们创建C#应用程序时,在项目的工程文件(*.csproj)中都有targetFramework标签,以表示项目使用的目标框架 各种版本的TFM .NET Framework .NET Standard .NET5 及更高版本 UMP等 参考文档&a…...
海豚【货运系统源码】货运小程序【用户端+司机端app】源码物流系统搬家系统源码师傅接单
技术栈:前端uniapp后端vuethinkphp 主要功能: 不通车型配置不通价格参数 多城市定位服务 支持发货地 途径地 目的地智能费用计算 支持日期时间 预约下单 支持添加跟单人数选择 支持下单优惠券抵扣 支持司机收藏订单评价 支持订单状态消息通知 支…...
01---java面试八股文——mybatis-------10题
1、什么是MyBatis Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。程序员直接编写原生态sql,…...
做网站建设一年能赚多少/百度网络营销中心
之前的两篇文章我们了解了委托和事件,本文我们看一下线程。 1,一个窗体程序,默认拥有一个线程(相当于一个商店里面,只有一个店员),这个默认的线程叫做 UI线程/主线程。 2,进程和线程…...
网站改版iis301跳转如何做/淘宝推广怎么做
因为公司需要分类链接所以再输出的时候就查了很多的函数。。用来用去这个最方便直接: 做笔记 strstr是C一个函数。 会返回一个指针位置,如果这个指针为空就是不存在这个标志符,指针不为空就证明存在,那就输出整段 Http_GW it…...
山东德铭工程建设公司网站/老鬼seo
B. 买酒Time Limit: 1000 ms Case Time Limit: 1000 ms Memory Limit: 64 MBTotal Submission: 43 Submission Accepted: 6Description众所周知,西瓜是一个很爱喝酒的人。有一天西瓜和朋友去酒楼喝酒,却发现酒楼在大酬宾,活动规则如下。…...
做网红用哪个网站/必应搜索引擎网站
16年元旦顶着大风来北京面试,一天6轮,在回去的高铁上感觉面试可能挂了,一个礼拜后收到了Offer。由于自身各方面的原因,18年元旦,选择离开微软。It is hard to say LEAVE, 这里整理了一下我在微软的两年经历,…...
北京响应式网站建设费用/高级搜索入口
旋转字符串 解法一:暴力移位法 初看此题,可能最先想到的方法是按照题目所要求的,把需要移动的字符一个一个地移动到字符串的尾部,如此我们可以实现一个函数LeftShiftOne(char* s, int n) ,以完成移动一个字符到字符串…...
建站工具交流/宁波seo公司推荐
先筛出来1000以内的素数。枚举x^(1/3) 和 y^(1/3)以内的素因子,这样除完以后对于x和y剩下的因子,小的那个的平方必须等于大的。然后判断每个素因数的次数之和是否为3的倍数,并且小的那个次数不小于大的次数的两倍。当然这题是有O(…...