实时嵌入式系统环境中敏捷的基础

news2024/11/18 7:42:20

不同的人使用敏捷一词的含义不同。在计算中,该术语最初用于描述执行项目开发的轻量级方法,而最初的术语极限编程(XP)未能激发受托管理开发项目的众多管理人员。

基本上,敏捷软件开发指的是一组松散集成的原则和实践,旨在以经济有效的方式完成软件开发工作。

文章首先考虑为什么我们需要敏捷的方法来进行软件开发,然后在实时和嵌入式系统的背景下讨论敏捷。然后,与更传统的方法相比,它转向了敏捷开发过程的优势。

敏捷宣言

的好地方开始理解敏捷方法与敏捷宣言。宣言是敏捷联盟的公开意向声明,由17个签署者组成,包括肯特·贝克,马丁·福勒,罗恩·杰弗里斯,罗伯特·马丁等。该宣言最初于2001年起草,总结为四个关键优先事项:点击领取嵌入式物联网学习路线

*通过流程和工具进行个人和交互

*通过综合文档进行工作软件

*通过合同谈判进行客户协作

*根据计划响应变更

为了支持这些声明,他们给出了12条原则。我将在此处说明它们,以设置以下讨论的上下文:

1)我们的首要任务是通过尽早并持续交付有价值的软件来满足客户。

2)即使在开发后期,也欢迎不断变化的需求。敏捷流程利用变更来获得客户的竞争优势。

3)经常交付工作软件,时间从几周到几个月不等,但最好选择较短的时间。

4)在整个项目中,业务人员和开发人员必须每天一起工作。

5)围绕有积极性的人建立项目。给他们提供所需的环境和支持,并信任他们来完成工作。

6)与开发团队内部交流信息的最有效方法是面对面的交谈。

7)工作软件是进度的主要衡量标准。

8)敏捷过程促进可持续发展。赞助者,开发者和用户应该能够无限期地保持恒定的步伐。

9)持续关注技术卓越和良好的设计可增强敏捷性。

10)简单性-最大化未完成工作量的艺术-是必不可少的。

11)最好的体系结构,需求和设计来自自组织团队。

12团队会定期思考如何提高效率,然后相应地调整和调整其行为。

敏捷方法起源于XP(极限编程)运动,很大程度上基于Kent Beck和Ward Cunningham的工作。敏捷和XP都最关注IT系统,并且都高度基于代码。

在本系列文章中,我将重点介绍如何有效地将宣言的声明和原则应用于实时和嵌入式应用程序,以及如何将它们与建模结合起来以获得模型驱动开发(MDD)方法的协同优势。(获得有关敏捷建模的更多信息的好地方是Scott Ambler的敏捷建模网站。

为什么要敏捷?

但是,为什么需要诸如“敏捷”之类的概念来描述软件开发呢?当前的软件开发流程还不够好吗?

不,不是。

在这种情况下,过程可以定义为“由具有特定角色的工人执行的一组计划的工作任务,导致一个或多个工作产品的属性,状态或其他特征发生变化。” 基本假设如下:

1)使用该过程的结果是可重复的,从而产生具有预期特性(例如功能和质量)的产品。

2)当根据项目(例如,成本,工作量,日历时间)和产品(例如,功能,及时性和健壮性)属性执行流程时,可以高度预测工作产品的目标状态的产生。

3)人们可以被视为匿名的,可互换的资源。

4)嵌入式软件开发的问题是无限扩展的;也就是说,将资源加倍总是会导致日历时间减半。

事实证明,很难开发软件。从以上意义上讲,大多数现有的开发过程肯定是不可重复的或不可预测的。为此提出了许多原因。对我自己而言,我认为软件从根本上讲是复杂的,也就是说,它体现了复杂性的“东西”。

这就是软件最擅长的功能-捕获算法和状态机如何在很大范围内操纵大量数据以实现一组计算结果。这是“思想的东西”,这很难。

我听说过的关于软件可预测性的最好的故事是来自Scott Westfall在SlickEdit网站上的一个博客,叫做“洞穴的寓言”。 估计软件项目与估计探索故事中提到的未知洞穴所需的时间非常相似,但管理人员通常坚持要求进行高度精确的估计。

另外,软件范围正在迅速增加。与过去数十年的软件功能范围相比,如今的软件的数量级要高出几个数量级。

当时,我的第一台IBM PC具有64kB的内存,并运行了一个称为DOS的基本磁盘操作系统。DOS可以放在单个360kB软盘上。(我知道我正在约会自己,但是我的IBM PC是我的第五台计算机。我仍然怀念着我拥有4kB内存的TRS-80型号的时代。)

Windows XP包含超过3000万行代码。驱动数百种不同的打印机,磁盘,显示器和其他外围设备;并需要1 GB的内存才能舒适地运行。这些软件密集型系统所提供的功能远远超过它们所取代的仅电子设备。

例如,将传统电话听筒与现代手机进行比较。或将传统的心电图(ECG)驱使像我在医学院使用的纸质记录仪与现代ECG机一样,来驱动它。

现代机器可以完成老机器所做的一切,此外还可以检测各种心律不齐,跟踪患者数据,生成报告,并测量无创血压,血氧浓度,各种温度甚至心输出量。

最后,嵌入式软件开发确实是发明,发明不是可预测的。在电子和机械工程中,大量工作从概念上讲就是简单地将各个部分组合在一起以实现期望的目标,但是在软件中,这些部分通常是每个项目的发明(或重新发明)。

这并不是要过分简化电子或机械设计的问题,而只是要指出这些学科的基础物理学比软件要成熟得多,并且要好得多。

但是,如果您相信我的解释,那并不重要。数十年来软件开发的经验结果是可用的。大多数产品迟到了。大多数产品交付时都有许多缺陷,而且往往存在重大缺陷。大多数产品未提供所有计划的功能。点击领取嵌入式物联网学习路线

我们已经习惯了重新启动设备,但是30年前,我们不得不关闭手机,取出电池,计数到30,重新插入电池,然后重新启动手机,这是无法想象的。(就像我爱我的BlackBerry一样,我惊讶于一位客户服务代表建议每天拆下电池以重新启动设备。)不幸的是,这就是当今的“最新技术”。

为此,许多聪明的人提出了解决问题的方法,以此来解决问题,并认为如果人们设计软件而不是破解软件,结果会更好。

而且它们在很大程度上已经变得更好。尽管如此,这些方法都是基于这样的前提,即软件开发可以与工业制造过程一样对待并获得相同的结果。

工业自动化问题是高度可预测的,因此,当很好地理解驱动过程的基本机制并且本质上是线性的时(例如,输入的微小变化导致输出的变化也同样小),这种方法就具有很大的意义。

当根本的机制不被完全理解或过程是高度非线性的时,它就没有意义了。不幸的是,软件开发既没有被完全理解,也没有远程线性化。

就像模糊逻辑和神经网络在非线性控制系统中的应用不同。模糊逻辑系统通过应用部分成员资格的概念并使用质心计算来确定输出来工作。

不同集合的部分隶属关系(映射到不同的方程式)是由集合隶属关系规则定义的,因此,当已知和理解规则时,例如在速度控制系统中,最好应用模糊逻辑系统。

另一方面,神经网络不了解或不在乎规则。他们通过训练简单但深度互连的处理单元(神经元)的集群来工作。培训包括应用已知的输入(“示例”)并调整连接的权重,直到获得预期的输出。

训练后,神经网络可以从以前看不见的数据输入集中产生结果,并产生控制输出。神经网络从实际数据中学习了潜在机制的影响,但是并没有以任何重要方式“理解”那些机制。当不能很好地理解底层机制时,最好使用神经网络,因为它们可以学习机制固有的数据转换。

严格计划的过程类似于模糊逻辑-它们对底层机制做出先验假设。当它们是正确的时,就会产生高度可预测的方案。点击领取嵌入式物联网学习路线

但是,如果这些先验 假设是错误的或遗漏的,那么它们将产生不太成功的结果。在这种情况下,该方法必须根据经验数据进行调整。为此,大多数传统流程都进行“额外”工作并生产“额外”产品来帮助管理流程。这些通常包括:

*进度表

*管理计划

*度量标准(例如,代码[SLOC]的源代码行或缺陷密度)

*对等和管理评审和演练

*进度报告

等等。

这个想法是,这些任务的执行和工作产品的生产与项目的及时性以及产品功能和质量密切相关。但是,即使很容易衡量,使用的许多任务和度量也没有很好的相关性。即使它们之间的相关性很好,也会招致额外的成本和时间。

敏捷方法是嵌入式软件开发社区对这些工业方法进行软件开发的高昂成本和精力的一种反应。我们发明软件的机制还没有被很好地理解,因此很难预测。此外,需求或体系结构的微小变化会导致开发方法和工作量的巨大差异。

因此,经验,纪律,质量和利益相关者都必须存在于我们的开发过程中。为此,敏捷方法不是关于黑客代码,而是将精力集中在可证明增加价值的事情上,而不是将精力放在没有价值的事情上。

为什么实时嵌入式系统需要敏捷

性当然,软件开发很难。嵌入式软件开发更加困难。实时嵌入式软件比这还要难。这并不是为了最大程度地减少可靠开发应用软件的难度,但是对于实时和嵌入式系统而言,存在很多问题,这些问题并没有出现在典型应用的生产中。

嵌入式系统是指至少包含一个CPU但不向最终用户提供常规计算服务的系统。手机被认为是嵌入式计算平台,因为它包含一个或多个CPU但提供了专用的服务集(尽管在许多现代手机中这种区别是模糊的)。

我们的现代社会充满了嵌入式计算设备:洗衣机,空中交通管制计算机,激光打印机,电视,患者呼吸机,心脏起搏器,导弹,全球定位系统(GPS)甚至是汽车-列表几乎是无止境的。

实时嵌入式系统中出现的问题主要体现在四个方面。首先,有效运行在资源高度受限的环境中所需的优化使嵌入式系统的创建更具挑战性。的确,嵌入式系统的运行范围从洗碗机和类似机器中的8位进程到协作的64位计算机集。

但是,大多数(但不是全部)嵌入式系统在处理器速度,内存和用户界面(UI)方面受到限制。这意味着许多标准的应用程序开发方法本身是不够的,必须进行优化以适应计算环境并执行其任务。

因此,嵌入式系统通常比标准桌面应用程序需要更多的优化。我记得为心脏起搏器编写了一个实时操作系统(RTOS),该操作系统具有32kB的静态存储器,相当于嵌入式6502处理器。(它甚至还有一个小的文件系统来管理不同的节奏和监视应用程序)现在,这是一个嵌入式系统!

与高度受限的环境一起,通常需要为嵌入式系统编写比标准应用程序开发更多的设备驱动程序级软件。

这是因为这些系统更可能具有不存在驱动程序的自定义硬件,但是即使存在驱动程序,它们也常常不符合平台约束。这意味着不仅必须开发主要功能,而且还必须编写底层设备驱动程序。

许多嵌入式系统的实时性意味着可预测性和可调度性会影响应用程序的正确性。另外,许多这样的系统具有很高的可靠性和安全性要求。

这些特性需要其他分析,例如可调度性(例如速率单调分析或RMA),可靠性(例如故障模式和影响分析或FMEA)和安全性(例如故障树分析或FTA)分析。除了“做数学”之外,还必须努力确保满足这些附加要求。

最后,嵌入式应用程序与传统应用程序之间的最大区别是所谓目标环境的性质,即目标应用程序将在其上运行的计算平台。大多数桌面应用程序“托管”(编写)在用作目标平台的同一台标准桌面计算机上。这意味着可以使用一组丰富的测试和调试工具来验证和验证应用程序。

相反,大多数嵌入式系统是从台式机主机“交叉编译”到嵌入式目标的。嵌入式目标缺乏在主机上发现的可见性和对程序执行的控制,并且大多数台式机工具都无法在其嵌入式目标上调试或测试应用程序。

嵌入式系统开发中使用的调试工具几乎总是比台式机更原始,功能更弱。嵌入式应用不仅更加复杂(由于优化),而且不仅必须驱动低级设备,而且不仅必须满足其他服务质量(QoS)要求集,而且还必须进行调试工具的能力也远远不够。

应当指出,嵌入式和“ IT”软件开发之间还存在另一个差异。IT系统通常是不断提供服务的维护系统,软件工作在很大程度上包括为消除缺陷和增加功能而进行的少量增量工作。

嵌入式系统的不同之处在于它们可以即时发布并在该瞬间提供功能。实际上,更新嵌入式系统需要付出更大的努力,因此实际上,它们通常在IT方面被替换而不是“维护”。这意味着与嵌入式系统相比,IT软件可以以较小的增量进行维护,并且“发行版”在嵌入式软件开发中具有更大的意义。

“实时系统”是及时性对于正确性很重要的系统。许多开发人员错误地认为“实时”是指“实时”。显然没有。实时系统“足够快地可以执行任务”。

如果处理您的eBay订单多花了几秒钟,则服务器应用程序仍可以执行其工作。尽管可以优化此类系统以使其每秒处理数千个事务,但通常不将其视为实时系统,因为如果系统速度变慢,则不会影响系统的正确性。

实时系统是不同的。如果心脏起搏器未能在正确的时间感应通过心肌的电流,则患者的心脏可能会发生纤颤。如果导弹制导系统未能及时纠正其姿态,则可能会击中错误的目标。如果GPS卫星不能高度精确地测量时间,则基于其信号的位置计算将完全是错误的。

实时系统可以通过多种方式进行分类。最常见的是将“硬”和“软”分为大类。如果每个动作都没有在其时间范围内执行,则“硬”实时系统将表现出重大故障。及时性的度量标准称为截止期限 –行动启动后必须完成行动的时间。并非所有截止日期都必须在微秒级的时间范围内才能实时。

该F2T2EA (发现,修正,跟踪目标,参与,评估)杀伤链 是几乎所有作战系统的一个基本方面; 此复合动作的端到端截止日期可能在10分钟左右,但是飞行员绝对必须达到这些截止日期才能提高战斗力。

动作完成的价值随时间变化是实时系统中的重要概念,并表示为“效用函数”,如下图1.1所示。此图向系统用户表示完成操作的价值。实际上,效用函数是平滑曲线,但是最常被建模为不连续的阶跃函数,因为这简化了它们的数学分析。

图1.1实用程序功能

在图中,直到某个瞬间(即期限),动作完成的价值才很高。此时,该动作完成的值为零。从当前时间到截止日期的时间长度是对操作紧急性的度量。

功能的高度是完成动作的关键性或重要性的度量。紧急度和紧急度是任何实时系统中动作的重要正交属性。不同的调度模式优化了紧急性,其他调度模式优化了重要性,还有其他模式则支持公平性(所有动作以大约相同的速率前进)。

动作是并发单元(例如任务或线程)的原始构建块。并发单元是知道顺序的一系列动作;并发单元可能具有分支点,但是一组分支内的操作顺序是完全确定的。对于并发单元之间的操作,情况并非如此。在并发单元之间,除了明确的同步点外,操作顺序是未知的或不关心的。

下面的图1.2 说明了这一点。完全指定了这三个任务(在UML活动图上显示)中每一个的流程。例如,在任务1中,顺序是首先发生动作A,然后是动作B,然后是动作C或动作D。

同样,其他两项任务的顺序也已完全定义。没有定义任务之间的顺序。动作C发生在动作W或动作Gamma之前还是之后?答案是你不知道,你不在乎。

但是,我们知道在动作F,动作X和动作Zeta发生之前,动作E,动作Z和动作Gamma都已发生。这就是任务同步点的意思。

图1.2。并发单位

因为在实时系统中,同步点和资源共享是很常见的,所以它们需要在IT系统开发中很少发现的实时系统中特别注意。

在一个任务中,几个不同的属性很重要,必须对其进行建模和理解,以使该任务正确运行(下图1.3)。基于时间的任务以一定的频率(称为周期)发生。点击领取嵌入式物联网学习路线

图1.3。任务时间

该时间段是任务调用之间的时间。周期周围的变化称为抖动。对于基于事件的任务启动,任务调用之间的时间称为到达时间。对于大多数可调度性分析,使用最短的时间(称为最小到达时间)进行分析。

从任务启动到必须完成其一系列操作的时间,称为期限。当任务共享资源时,可能无法使用所需的资源。当较低优先级的任务锁定了必要的资源时,当前任务必须阻止并允许较低优先级的任务完成对资源的使用,然后才能运行原始任务。

阻止运行较高优先级任务的时间长度称为阻塞时间。即使已准备好运行较高优先级的任务,也必须运行较低优先级的任务这一事实被称为优先级倒置,并且是在任务线程之间共享资源的所有优先级调度系统的属性。当任务共享资源时,优先级倒置是不可避免的,但如果不受控制,则会导致错过截止日期。

实时系统必须做的一件事是绑定优先级反转(例如,将阻塞限制在单个任务的深度上)以确保系统的及时性。任务执行其动作所需的时间段,包括任何潜在的阻塞时间,称为任务执行时间。

为了进行分析,通常使用最长的时间段,即最坏的执行时间,以确保系统始终能够满足其截止日期。

最后,执行结束到最后期限之间的时间称为松弛时间。在实时系统中,捕获,表征和管理所有这些任务属性非常重要。

实时系统通常也是嵌入式系统,并承担那些开发负担。另外,实时系统具有及时性和可调度性约束。

实时系统必须及时-也就是说,它们必须满足任务完成时间的限制。如果所有任务都是及时的,则整个任务集可以调度。

实时系统不一定(或什至通常)是确定性的,但是它们必须在时间上可预测地受到限制。存在一些数学方法来分析系统的可调度性,并且有工具11可以支持这种分析。

关键安全性和高可靠性系统是实时和嵌入式系统的特例。安全一词的意思是“没有事故或损失”,通常涉及没有故障以及存在单点故障的安全性。可靠性通常是系统交付服务的时间百分比的随机度量。

对安全至关重要的系统是实时系统,因为安全分析包括容错时间的属性,即容错时间在导致事故之前可以容忍的时间。它们几乎也总是嵌入式系统,并提供关键服务,例如生命支持,飞机飞行管理,医疗监控等。

通过使用附加分析(例如FTA,FMEA,故障模式,影响和严重性分析(FMECA))可以确保安全性和可靠性,并且通常会生成称为危害分析的文档。

这将故障可能性,故障严重性,风险(前两者的乘积),危险条件,故障保护手段,容错时间,故障检测时间和故障保护动作时间结合在一起。对安全至关重要的高可靠性系统需要进行额外的分析和记录,以获取诸如FAA和FDA之类的监管机构的批准。

对于公司和项目而言,为此类系统的开发指定非常繁重的流程(安全关键,高可靠性,实时或嵌入式)作为向这些系统注入质量的一种方式并不少见。

它在一定程度上有效。但是,它的成本很高。敏捷方法为这类系统的开发提供了另一种观点,即重量轻但不牺牲质量。嵌入式软件开发

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1139775.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue echarts 折线图 背景颜色渐变 (两种实现方式)

需求 实现方式 两种方法 方法一:color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{},{},{}]) 方法二:避开new echarts,color: {x: 0, y: 0, x2: 0, y2: 1,colorStops: [{},{},{}]} …

【嵌入式】HC32F07X DAC模拟输出 + DMA传输

一 背景说明 使用小华(华大)的MCU HC32F07X实现两个通道的 0-5V 电压模拟输出。 二 原理分析 【1】DAC原理说明: 所谓DAC,就是Digital-Analog-Converter,数字模拟转换器。在模拟电路中,电流电压变化是连续…

漏洞复现-dedecms文件上传(CVE-2019-8933)

dedecms文件上传_CVE-2019-8933 漏洞信息 Desdev DedeCMS 5.7SP2版本中存在安全漏洞CVE-2019-8933文件上传漏洞 描述 ​ Desdev DedeCMS(织梦内容管理系统)是中国卓卓网络(Desdev)公司的一套基于PHP的开源内容管理系统&#x…

WebSocket 原理揭秘:让你彻底搞懂 Websocket 原理

WebSocket 的原理 WebSocket 是什么? WebSocket 是一种新型的协议,它可以在客户端和服务器之间建立长连接,实现双向通信。在传统的 HTTP 协议中,当客户端向服务器发送请求后,服务器会返回响应,然后连接就…

创建python虚拟环境

为什么要创建python虚拟环境? 在python开发中,我们可能会遇到一种情况,就是当前的项目依赖的是某一个版本,但是另一个项目依赖的是另一个版本,这样就会造成依赖冲突,在不同的环境中进行不同需求的项目开发…

ChinaSoft 论坛巡礼 | 智慧化 IDE 论坛

2023年CCF中国软件大会(CCF ChinaSoft 2023)由CCF主办,CCF系统软件专委会、形式化方法专委会、软件工程专委会以及复旦大学联合承办,将于2023年12月1-3日在上海国际会议中心举行。 本次大会主题是“智能化软件创新推动数字经济与社…

华为OD机考算法题:矩阵最大值

题目部分 题目矩阵最大值难度难题目说明给定一个仅包含 0 和 1 的 N*N 二维矩阵,请计算二维矩阵的最大值,计算规则如下: 1. 每行元素按下标顺序组成一个二进制数(下标越大越排在低位),二进制数的值就是该行…

怎样下载视频号视频?分享6种有效方法

在今天的数字时代,视频号视频成为了人们生活中不可或缺的一部分。有时候,我们看到了一段精彩的视频,希望能够保存下来欣赏或分享给朋友,却因为平台限制而困难重重。为了帮助你实现这个目标,本文将介绍几种简单而有效的…

【JAVA基础】多线程与线程池

多线程与线程池 文章目录 多线程与线程池1. 相关概念1.1 线程调度1.2 守护线程 2. 生命周期3. 同步机制/同步锁3.1 synchronized3.2 lock3.3 synchronized 与 Lock 的对比 4. 死锁5. 线程通信5.1 线程间的通信5.2 等待唤醒机制5.3 举例5.4 调用 wait 和 notify 需注意的细节5.5…

docker应用部署---MySQL的部署配置

docker应用部署---MySQL的部署配置 1. 搜索mysql镜像2. 拉取mysql镜像3. 创建容器,设置端口映射、目录映射4. 进入容器,操作mysql5. 登录mysql6. 使用外部机器连接容器中的mysql 1. 搜索mysql镜像 docker search mysql2. 拉取mysql镜像 #安装5.6版本的M…

<script> 标签的 defer 和 asnyc 属性的作用以及二者的区别

前言 在现代Web开发中,JavaScript的使用几乎是不可避免的。随着Web应用变得越来越复杂,JavaScript文件的大小也在不断增长。为了提高页面加载性能,浏览器提供了async和defer两个属性,用于改变浏览器加载和执行JavaScript文件的方…

AI数字人系统源码部署,打造自己品牌的数字人克隆直播平台

AI数字人是一种利用人工智能技术生成的虚拟形象,可以模仿真人的外貌、声音、表情和动作,实现与人类的自然交互。AI数字人有着广泛的应用场景,如虚拟主播、电商直播、客服助理、教育培训等。要实现AI数字人的功能,需要部署一套完整…

数据库调优(Mysql)

1 索引 索引是帮助数据库高效查询的一种数据结构: 查询语句:select * from t where t.Col2 89; 不加索引进行数据库查询时,每次都需要将所有数据遍历一次,直到找到符合目标的数据。 加上索引之后,可以根据数据结构不同…

Hutool中那些常用的工具类和实用方法 | 京东云技术团队

❓背景 灵魂拷问1:还在为新项目工具类搬迁而烦恼? 灵魂拷问2:还在为项目中工具类维护而烦恼? 📘简述 **Hutool**它是一个Java工具集类库,包含了很多静态方法的封装:流处理、时间日期处理、正…

SAP BC PP 物料搜索帮助修改

ECC on Oracle 升级S4 on HANA ,公司启用了物料状态 MARA-MSTAE 用户想在做物料搜索帮助里面加上这个 物料状态 参考 <SAP简使-ABAP>自定义搜索帮助 - 知乎 (zhihu.com) 过程如下&#xff1a; 1)spro-物流-常规--物料主数据-工具-维护搜索帮助 以 “MAT1L” 物料&am…

SpringBoot集成Redis Cluster集群(附带Linux部署Redis Cluster高可用集群)

目录 一、前言二、集成配置2.1、POM2.2、添加配置文件application.yml2.3、编写配置文件2.4、编写启动类2.5、编写测试类测试是否连接成功 一、前言 这里会使用到spring-boot-starter-data-redis包&#xff0c;spring boot 2的spring-boot-starter-data-redis中&#xff0c;默…

前端 读取/导入 Excel文档

情况&#xff1a; 需要通过Excel表&#xff0c;将数据导入到数据库&#xff0c;但是后台人员出差了&#xff0c;我又只会PHP&#xff0c;没用过node&#xff0c;所以只能前端导入Excel文件&#xff0c;然后循环调用后台的单条添加接口了。 库&#xff1a; Excel.js&#xff08…

基于Java的宠物商店管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09; 代码参考数据库参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者&am…

03_Flutter自定义下拉菜单

03_Flutter自定义下拉菜单 在Flutter的内置api中&#xff0c;可以使用showMenu实现类似下拉菜单的效果&#xff0c;或者使用PopupMenuButton组件&#xff0c;PopupMenuButton内部也是使用了showMenu这个api&#xff0c;但是使用showMenu时&#xff0c;下拉面板的显示已经被约定…

MedNeXt: Transformer-driven Scaling ofConvNets for Medical Image Segmentation

论文标题;MedNeXt: Transformer-driven Scaling of ConvNets for Medical Image Segmentation 论文链接&#xff1a;2303.09975.pdf (arxiv.org)https://arxiv.org/pdf/2303.09975.pdf 论文&#xff1a; MedNeXt&#xff1a;用于医学图像分割的转换器驱动的ConvNets缩放 项目…