架构设计之需求分析

news2024/10/5 18:32:24

大家好,我是易安。

设计架构的第一步是需求分析。那么,为什么要做需求分析?如何做好需求分析?今天我们一起聊一聊需求分析这件事儿

为什么要做需求分析

为何要做需求分析?

首先,当然是因为我们做软件本身就是为了满足用户需求。那么,用户需求到底为何,我们需要清楚定义。

其次,需求边界定义的需要。用户需求理清楚了,不代表产品理清楚了。用户需求的满足一定会有行业分工,我们做什么,合作伙伴做什么,需要厘清大家的边界。

最后,架构设计的需要。架构需要切分子系统,需要我们梳理并对用户需求进行归纳与抽象。架构还需要防止过度设计,把简单的事情复杂化。

但什么是过度设计?不会发生的事情你考虑了并且为它做足了准备,就是过度设计。所以判断是不是过度设计是很困难的,需要对需求未来演化有很强的判断力。

从这几个维度来看,需求分析过程必然会涉及以下这些内容。

  • 我们要面向的核心用户人群是谁?
  • 用户原始需求是什么?最核心问题是哪几个?
  • 已经有哪些玩家在里面?上下游有哪些类型的公司,在我们之前,用户是怎么解决他们的问题的?我们的替换方案又是怎样的?
  • 进而,我们的产品创造的价值点是什么?用户最关注的核心指标是什么?
  • 用户需求潜在的变化在哪些地方?区分出需求的变化点和稳定点。

当然,我并不是说,我们应该在需求分析的文档中完整地回答这些问题。需求分析文档目的并不是回答这些问题。但是在我们梳理需求的过程中,我们无法回避对这些问题的思考。

可能有人会认为,这些问题是 CEO 或产品经理这样的角色需要回答的,而不是架构师需要回答的。

某种意义上来说这句话没错。回答这些问题的首要责任方是 CEO 或产品经理。他们有责任让团队中的每一个人理解我们的产品逻辑。

但是,如果架构师只是被动地接受产品需求,以按图索骥的方式来做架构设计,是不足以成为顶级架构师的。原因在于两点。

一方面,用户需求的深层理解是很难传递的。 你看到的产品文档,是产品经理和用户沟通交流后的二次理解,是需求的提炼和二次加工,很难原汁原味地传递用户的述求。

所以架构师自己亲身近距离地接触用户,和用户沟通,去体会用户的述求是非常有必要的。

况且,大部分人并不会那么仔仔细细地阅读别人写的文档。当然这不完全是看文档的人单方面的原因,如果团队文档平均质量不高的话,也会影响到阅读者的心态。

另一方面,产品设计过程需要架构师的深度参与,而不是单向的信息传递。 产品经理非常需要来自架构师的建设性意见。

为什么我会有这样的看法呢?这涉及我对产品的理解。产品本身是运用先进的技术来满足用户需求过程的产物。

用户需求的变化是缓慢的,真正改变的是需求的满足方式。而需求满足方式的变化,深层次来说,其背后往往由技术迭代所驱动。

从这个角度来说, 产品是桥,它一端连接了用户需求,一端连接了先进的技术。 产品经理是需要有技术高度的,他不一定要深刻了解技术的原理,但是一定要深刻理解新技术的边界。

某项技术能够做什么,不能做到什么,顶级产品经理甚至比实现这项技术的开发人员还要清楚。

认为产品经理不需要理解技术,这可能是我们普遍存在的社会现象,但很可能并不符合这个岗位的内在诉求。

产品经理和架构师其实是一体两面。两者都需要关心用户需求与产品定义。

只不过产品经理更多从用户需求出发,而架构师更多从技术实现出发,两者是在产品这座桥的两端相向而行,最终必然殊途同归。

这也是我为什么说架构师需要深度参与产品设计的原因。产品经理很可能会缺乏他应该有的技术广度,这就需要架构师去补位。产品定义过程需要反复推敲琢磨,并最终成型。

需求分析并不是纯技术的东西,和编程这件事情无关。它关乎的是用户需求的梳理、产品的清晰定义、可能的演变方向。

需求分析的重要性怎么形容都不过分。准确的需求分析是做出良好架构设计的基础。

我个人认为架构师在整个架构设计的过程中,至少应该花费三分之一的精力在需求分析上。

这也是为什么很多非常优秀的架构师换到一个新领域后,一上来并不能保证一定能够设计出良好的架构,而是往往需要经过几次迭代才趋于稳定。

原因就在于:领域的需求理解是需要一个过程的,对客户需求的理解不可能一蹴而就。

怎么做需求分析

那么怎么才能做好需求分析?

首先,心态第一,心里得装着用户。 除了需要 “在心里对需求反复推敲” 的严谨态度外,对用户反馈的尊重之心也至关重要。

其次,对问题刨根究底,找到根源需求。 有很多用户反馈需求的时候,往往已经带着他自己给出的解决方案。

这种需求反馈已经属于二次加工的需求,而非原始需求。这个时候我们要多问多推敲,把它还原到不带任何技术实现假设的根源需求。

alt

如上图所示,根源需求可能会有非常非常多的技术方案可以满足它。我们上面示意图中的小圆点是一个个用户反馈的需求。在用户提这些需求的时候,往往可能会带着他熟悉的技术方案的烙印。

对于那些我们明显不关心的需求,如上图的小红点,相对容易排除在外。毕竟产品的边界意识大家还是会有的,产品不可能无限制膨胀下去。

但是对于上面的小绿点,决策上就比较难了。不做?可能会丢了这个客户。做?如果我们手放宽一点,最后产品需求就会被放大(如上图中蓝色的圆圈),做出一个四不像的产品。

最后,在理清楚需求后,要对需求进行归纳整理。 一方面,将需求分别归类到不同的子类别中。另一方面,形成需求的变化点和稳定点的基本判断。

在需求分析时,要区分需求的变化点和稳定点。稳定点往往是系统的核心能力,而变化点则需要对应地去考虑扩展性上的设计。

要注意的是,在讨论需求的变化点和稳定点的时候,我们需要有明确参考的坐标系。在不同视角下,稳定点和变化点的判断是完全不同的。

所以 需要明确的一点是,当我们说需求的变化点和稳定点时,这是站在我们要设计的产品角度来说的。

比如我们要设计一台计算机,那么多样化的外部设备是一个变化点。但是如果我们今天是在设计一台显示器,问题域就完全变了,需求的变化点和稳定点也就完全发生了变化。

本质上来说,对变化点的梳理,是一次产品边界的确立过程。所谓的开放性设计,就是说我把这个功能交给了合作伙伴,但是我得考虑怎么和合作伙伴配合的问题。

开放性设计并不是一个纯粹的用户需求问题,它通常涉及技术方案的探讨。因此,产品边界的确立不是一个纯需求,也不是一个纯技术,而是两者合而为一的过程。

对变化点的梳理至关重要。产品功能必须是收敛的,必须是可完成的。

如果某个子类别的需求呈现出发散而无法收敛的趋势,这个事情,团队一定要坐下来一起去反复推敲。不断拷问,不断明确响应需求的正确姿势到底为何。

产品定义

需求分析的目标和最终结果,都是要最终形成清晰的产品定义。产品定义并不是简单的产品需求的归类。

alt

上面我也说过,产品是桥,它一端连接了用户需求,一端连接了先进的技术。所以产品定义不可能做到和技术方案完全没关系。

首先,需要明确产品中有哪些元素,或者叫资源,以及这些资源的各类操作方式。 如果我们从技术的视角来理解,这就是定义对象和方法。当然这仅仅是这么理解,实际上一个我们技术上的对象方法,从产品需求角度会有多条路径的操作方式来达到相同的目的。

其次,需要对产品如何满足用户需求进行确认。 用户的使用场景未必全部是我们的产品所能直接满足的,面向特定的行业,有可能需要相应的行业解决方案,把我们的产品整合进去。

alt

我们要避免把行业方案视作产品的一部分。更多的情况下,需要我们更加开放的心态来看待这件事情,优先寻找合作伙伴来一起完成这类行业的需求覆盖。

最后,产品定义还需要考虑市场策略,我们的产品如何进入市场,和既有市场格局中的其他主流解决方案的关系是什么样的。

alt

我们希望获取的用户,可能大部分都已经有一个既有的产品和技术方案,在满足他的需求。在考虑如何让客户从既有方案迁移到我们的产品后,我们确定产品的边界时又会复杂很多。

在一些极其关键的市场,我们有可能会把迁移需求视作产品需求的一部分。但更多的情况下,我们产品上只为这些市场上的主流方案提供迁移路径,而不是完整的迁移方案。

需求分析实战-打造 “互联网”

从对信息科技的影响面来说,最为标志性的两个事件,一个是计算机的诞生,另一个是互联网的诞生。

我们以 “互联网” 这个产品为题,看看应该怎么去做需求分析。

我们想象一下,把我们自己置身于互联网诞生之前。互联网并不是第一张网。在此之前的信息世界中,更多的是某个企业专用的局域网。不同的企业会选择不同公司所提供的网络方案。这些网络方案缺乏统一的规划,彼此并不兼容。

那么,怎么才能打造一个连接人与人、企业与企业,甚至是物与物,能够 “连接一切” 的 “互联网”?

首先,从根源需求来说,我们期望这不是某个巨头公司的网,也不是政府的网。这是需求的原点,这一点上的不同,产生的结果可能就很不一样。

如果我们忽略这一点,就有可能会把它做成微信网(WechatNet),或者中国网(ChinaNet)。它们可能会是一张巨大的网,但都不是 “互联网”。

所谓 “互联网” 首先应该是一张开放的网。它应该可以让很多国家很多公司参与其中,形成合力。它不应该存在 “造物主”,一个可以在这张网络中主宰一切的人。

开放,最基础的层次来说,意味着需要定义网络协议标准,尤其是跨网的数据交换标准。这里的跨网,指的是跨不同的网络设备,不同的网络运营商。

开放,从另一个角度来说,是对应用程序软件的开放。想要 “互联网” 真正能够连接一切,只是把物理的网络连接在一起是不够的,还要有能够丰富的 “连接一切” 的应用。

为了能够让更多应用可以更便捷地连接网络,我们需要提供方便应用接入的高层协议。这个协议需要屏蔽掉网络连接的复杂性(丢包重传等)。

但这还不够。“互联网” 这样的基础设施,启动阶段没有应用去吸引用户是不行的。所以我们需要 “吃自己的狗粮”,开发若干互联网应用的典型代表。

有一些需求可能非常非常重要,但是我们需要阶段性放弃,例如安全。加密传输并没有作为互联网的内建特性,这极大降低了互联网的实施难度。

从另一个角度考虑,为什么不把安全放在最底层,也要考虑方案的可持续性。一个安全方案是否能够长期有效,这非常存疑。

但是物理网络一旦存在,就很难做出改变(想想我们从 IPv4 过渡到 IPv6 需要多少年吧)。所以从这个角度来说,我们也不希望安全是一个网络的底层设施。

这并不意味着安全问题可以不解决,只是把这事儿留给了软件层,留给操作系统和应用程序。这是一个极其明智的选择。相比物理网络而言,软件层更加能够经受得起变更。

总结来说,要想把 “互联网” 这个项目做成,需要考虑这样一些事情。

  • 一个能够连接所有既有网络的协议标准,我们不妨叫它互联网协议(Internet Protocol),简称 IP 协议。
  • 一张连接城市的骨干网络,至少有两个城市互联的试点。
  • 打通骨干网络和主流企业专用网络的路由器。
  • 一套方便应用开发的高阶网络协议,工作在 IP 协议之上。
  • 一份支撑互联网应用程序的基础网络协议栈源代码或包(package),方便主流操作系统厂商、网络设备厂商集成。
  • 若干典型互联网应用,如电子邮件(Email)、万维网(WWW)等。
  • 一份安全传输的网络协议方案(远期),及其源代码或包(package)。

让我们先来看下物理网络的构建。

首先,构建骨干网络。不同城市可以由若干个骨干网路由器相连。骨干路由器可以看做是由一个负责路由算法的计算机,和若干网络端口构成,如下图所示。

alt

每个端口可能和其他城市相连,也可能和该城市内的某些大型局域网相连。一个局域网和城际网络从抽象视角看,没有非常本质的不同,只不过是采用的网络技术有异,使用的网络协议有异。

一个局域网可以简化理解为由若干台交换机连接所有的计算机设备。而交换机同样也可以看做是由一个负责路由算法的计算机,和若干网络端口构成,如下图所示:

alt

剩下的问题是怎么对接骨干网络和局域网。这需要有人负责进行网络协议转换,它就是路由器。一台路由器上有两类端口,一类端口为本地端口,连接局域网内的设备,比如交换机,或者直接连普通的计算机。另一类端口为远程端口,负责接入互联网。

alt

理清楚了物理网络后,我们再来看应用构建。我们打算打造两个杀手级应用(Killer Application):电子邮件(Email)和万维网(WWW)。

在考虑应用的用户交互体验时,我们发现,物理网络能够处理的 IP 地址,和人类方便记忆的地址非常不同,故而我们决定引入域名(domain)作为人与人交流用途的地址。为此,我们引入了 DNS 地址簿协议,用于将域名解析为物理网络可理解的 IP 地址。

综上分析,最终我们得到 MVP 版本的 Internet 项目的各子系统如下:

alt

需求分析实战- “对象存储”

对象存储是非常新兴的一种存储系统。是什么样的需求满足方式的变化,导致人们要创造一种新的存储呢?

对象存储是伴随互联网的兴起,尤其是移动互联网的兴起而产生的。

首先,互联网应用兴起,软件不再是单机软件,用户在使用应用软件的过程中产生的数据,并不是跟随设备,而是跟随账号。 这样,用户可以随心所欲地切换设备,不必考虑数据要在设备间倒来倒去的问题。

数据跟随账号,这是互联网应用的第一大特征,区别于单机软件的关键所在。

其次,用户交互方式的变化。 用户不再打字用纯文本沟通,而是用照片、视频、语音等多媒体内容来表达自己的想法。

移动化加剧了这一趋势,在手机上打字是非常痛苦的事情。拍拍照、拍拍视频、说说话(语音输入)更加符合人的天性,尤其是手机用户覆盖面越来越宽,大部分用户属于没有经过专业培训的普通用户,这些手段是最低准入门槛的交互方式。

最后,用户体验诉求的提升。 计算机显示器早年是黑白的,后来有了256色,有了真彩色(TrueColor);显示器的屏幕分辨率,也从320x240,到640x480,到今天我们再也不关心具体分辨率是多大。随之发生变化的,是一张照片从100K,到几兆,到几十兆。

这些趋势,对存储系统带来的挑战是什么?

其一,规模。 那么多用户的数据,一台机器显然放不下了,要很多很多台机器一起来保存。

其二,可靠。 用户单机对存储的要求并不高,机器硬盘出问题了,不会想着找操作系统厂商或者软件应用厂商去投诉。但是,用户数据在服务端,数据丢了那就是软件厂商的责任,要投诉。

其三,成本。 从软件厂商来说,那么多的用户数据,怎么做才能让成本更低一些。

其四,并发吞吐能力。 大量的用户同时操作,有读有写,怎么保证系统是高效的。

另外,从存储系统的操作接口来说,我们分为关系型存储(数据库,结构化数据)和文件型存储(非结构化数据)。我们今天的关注点在文件型存储上。

对于文件型存储来说,相关的备选解决方案有很多,我们简单罗列如下。

alt

第一类是大家最熟悉的、最古老的存储系统:本地文件系统。 虽然有很多种具体的实现方案,但是它们的使用接口大同小异,实现方案也只是在有限的几种选择中平衡。

第二类是网络文件系统,可以统称为 NAS,如上面的 NFS、FTP、Samba(CIFS)、WebDAV,都只是 NAS 存储不同的访问接口。

第三类是数据库,它通常用于存储结构化数据,比较少作为文件型存储。但也有人在这么做,如果单个文件太大,会切成多个块放到多行。

第四类是 SAN,它是块存储。块存储和关系型存储、文件型存储都不同,它模拟的是硬盘,是非常底层的存储接口。很少会有应用直接基于块存储,更多的是 mount 到虚拟机或物理机上,然后供应用软件需要的存储系统使用。

第五类是分布式文件系统 GFS/HDFS。GFS 最早是为搜索引擎网页库的存储而设计,通常单个文件比较大,非常适合用于日志类数据的存储。这也是为什么 Hadoop最后从大数据领域跑出来,原因就是因为大数据处理的就是日志。

你可以看到,除了数据库和 SAN,我们不用细分析就知道它们不是文件型存储的最佳选择,其他几类包括本地文件系统、NAS、GFS/HDFS 有一个共同特征,就是它们的使用接口都是文件系统(FileSystem)。

那么,我们就来看下文件系统(FileSystem)对于大规模的文件型存储来说有什么问题。

最大的问题是,文件系统是一棵树(Tree)。除了对单个文件的操作只需要锁住该文件外,所有对树节点的修改操作,比如把 A 节点移到 B 处,都是一次事务操作,需要锁住整棵树。

这对规模和并发吞吐能力都是伤害。从规模来说,分布式事务是很难的(这也是为什么分布式数据库很难做的原因),做出来性能也往往好不到哪里去。从并发吞吐能力来说,如果系统存在大锁,即在锁里面执行费时的操作,就会大幅降低系统的并发吞吐能力。

传统的 NAS 出现比较早,所以它没有考虑“大规模条件下存储会有什么样的挑战”是非常正常的。

GFS/HDFS 为什么没有考虑大规模问题?这是 Google 设计 GFS 的背景导致的,网页库存储,或者日志型存储的共同特征是单个文件很大,可以到几个 G 级别,这样的话文件系统的元数据就会减少到单台机器就可以存储的级别。

所以对象存储出现了。它打破了文件型存储访问接口一定是文件系统(FileSystem)的惯例。它用的是键值存储(Key-Value Storage)。

从使用接口来说,首先选择文件所在的桶(Bucket),它类似于数据库的表(Table),只是一个逻辑划分的手段;然后选择文件的键(Key),就可以存取文件了。

这意味着文件之间并不存在关联(树型结构是文件之间的一种关联),可以通过某种算法将文件元信息分散到不同的机器上。

那么为什么文件型存储,不必考虑文件之间的关联?因为关系都在数据库里面,文件型存储只需要负责文件内容的存储,有个键(Key)能够找到文件内容即可。

从本质上来说,这是因为服务端和桌面软件面临的用户场景是完全不同的。文件系统是在桌面软件下的产物,桌面系统是单用户使用的,没有那么高的并发访问需求。

服务端一上来就面临着并发访问的问题,所以很早就出现了数据库这样的存储中间件。数据库的出现,其实已经证明文件系统并不适合服务端。只不过因为文件型存储在早期的服务端开发的比重并不大,所以没有被重视。

但是,互联网的发展极大地加速了文件型存储的发展。互联网增加的 90% 以上的数据,都是非结构化数据,包括图片、音频、视频、日志。

对象存储能够支撑的文件数量规模上非常非常大。比如七牛云存储,我们已经支持万亿级别的文件。

这在传统 NAS 这种基于文件系统访问接口的存储是难以想象的,我们看到的 NAS 存储 POC 测试要求,基本上都是要能够支持 1-2 亿级别的文件存储规模。

另外,对象存储的高速发展,很大程度上会逐步侵蚀 Hadoop 生态的市场。因为 HDFS 这种日志型存储,其实只是对象存储里面的一个特例。在人们习惯了对象存储后,他们并不希望需要学习太多的存储系统;所以大数据的整个生态会逐步过渡到以对象存储为基石。

总结

需求分析并不是纯技术的东西,和编程这件事情无关。它关乎的是用户需求的梳理、产品的清晰定义、可能的演变方向。

怎么提升需求分析能力,尤其是预判能力?

首先,心态第一,心里得装着用户。除了需要 “在心里对需求反复推敲” 的严谨态度外,对用户反馈的尊重之心也至关重要。

其次,对问题刨根究底,找到根源需求。

最后,对需求进行归纳整理。一方面,将需求分别归类到不同的子类别中。另一方面,形成需求的变化点和稳定点的基本判断。

需求分析的目标和最终结果,都是要最终形成清晰的产品定义。产品定义将明确产品的元素,明确产品的边界,与产业上下游、合作伙伴的分工。

通过对打造“互联网”和“对象存储”这两个案例的分析,我们可以看出不同市场差异还是很大的。“互联网” 这个产品它并不是替换某种既有的方案,而是把既有的方案连接在一起。所以 “互联网” 的历史包袱很少,基本上不太需要考虑历史问题。

“对象存储” 产品则不同。在对象存储之前,存储已经经历了很长时间的发展。只不过因为文件型的数据爆发式的增长,带来了存储系统的新挑战,从而给对象存储这样的新技术一个市场机会。

当然,另外一个原因是云服务的诞生,让存储有了新的交付形态。我们不再需要拿着硬件往用户家里搬,这就出现了一个新的空白市场。

但是解决了空白市场的需求后,对象存储还是要面临 “既有市场中用户采用的老存储方案怎么搬迁” 的问题。所以存储网关这样的产品就出现了。存储网关做什么?简单说,就是把对象存储包装成 NAS,提供 NFS、FTP、Samba(CIFS)、WebDAV 这些访问接口给用户使用。

本文由 mdnice 多平台发布

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

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

相关文章

迭代器失效问题,以及解决方法。

迭代器的主要作用就是让算法能够不用关心底层数据结构,其底层实际就是一个指针,或者是对指针进行了封装,比如:vector的迭代器就是原生态指针T* 。因此迭代器失效,实际就是迭代器底层对应指针所指向的空间被销毁了&…

【小沐学Python】Python实现Web服务器(Flask+Vue+node.js,web单页增删改查)

文章目录 1、简介1.1 flask1.2 vue 2、开发2.1 新建flask项目2.2 安装flask库2.3 新建flask的主脚本2.4 新建Vue项目2.5 安装vue项目依赖项2.6 新增组件Ping.vue2.7 Ping.vue增加HTTP请求2.8 美化vue前端页面2.9 新增组件Books.vue2.10 flask增加路由Books2.11 Books.vue增加HT…

什么是ChatGPT?怎么用?

最近全网爆火的黑科技,叫做chatGPT。ChatGPT声称,它的AI对话模型能在大范围、细粒度问题上给出普遍准确的答案。简单地说,AI对话模型可以达到基本不犯错误的水平了。那么到底这个ChatGPT是什么?怎么用?本篇文章就来带大…

算法修炼之练气篇——练气二层

博主:命运之光 专栏:算法修炼之练气篇 题目 1084: 用筛法求之N内的素数 题目描述 用筛法求之N内的素数。 输入格式 N 输出格式 0~N的素数 样例输入 100 样例输出 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 …

学系统集成项目管理工程师(中项)系列21a_整体管理(上)

1. 含义 1.1. 包括为识别、定义、组合、统一和协调各项目管理过程组的各种过程和活动而开展的工作,是项目管理中一项综合性和全局性的管理工作 2. 项目经理是整合者 2.1. 【21上选33】 2.1.1. 【19上选37】 2.1.2. 【22上选33】 2.2. 通过与项目干系人主动、全…

shell脚本(磁盘空间、服务状态)

1、判断当前磁盘剩余空间是否有20G,如果小于20G,则将报警邮件发送给管理员,每天检查一次磁盘剩余空间。 第一步:创建脚本名为shell1.sh如下: vim shell1.sh 第二步:做计划在shell1文件中,命令…

Kyligence Zen 简直就是一站式指标平台的天花板

一、Kyligence Zen是什么? 1、Kyligence Zen是做啥的? Kyligence Zen是一款指标分析和管理的工具,是基于 Kyligence 核心 OLAP 能力打造,Kyligence Zen 提供集业务模型、指标管理、指标加工、数据服务于一体的一站式服务&#x…

孙溟㠭20余载春秋,4000多方印章,这双质朴的手有多么倔强的生命力

作品的背后往往折射出艺术家人生的广度和厚度。 先锋篆刻、书画艺术家孙溟㠭, 上世纪90年代开始接触篆刻, 至今,20载有余,积累了4000多方篆刻作品。 在他创作纪念吴品超院士的作品《药生尘》时, 我们拍到了艺术家…

高级Web题库

高级Web题库 For ZPT 声明 一切开发旨在学习,请勿用于非法用途 by rick rick 关注 永雏塔菲喵 永雏塔菲喵 选择题 第1题 知识点:CSS 题目:设置text-decoration属性的删除线的值为( )。 选项: A underlin…

固定翼无人机培训第二周总结——多轴和起降

博主学的III类固定翼垂直起降无人机,起降采用多旋翼(下图中红框就是旋翼),巡航采用固定翼。 理论大部分也是多旋翼,多轴旋翼无人机是指三个旋翼轴及以上的特殊直升机,多旋翼无人机靠旋翼速度和方向来控制无…

代码随想录算法训练营第三十八天 | 动态规划基础流程

动态规划理论基础 代码随想录 (programmercarl.com) 如果某一问题有很多重叠子问题,使用动态规划是最有效的。 所以动态规划中每一个状态一定是由上一个状态推导出来的,这一点就区分于贪心,贪心没有状态推导,而是从局部直接选最…

Java结合POI框架实现Excel导入

Java结合POI框架实现Excel导入 一、流程概念二、conroller中的方法三、导入成功 一、流程概念 我们需要把excel通过上传得方式导入数据库,需要以下几个步骤 将excel上传到服务器指定文件夹内并重命名(upload)获取到文件公共路径和别名路径将…

InsCode再进步,AI 辅助编程帮你打开思路

文章目录 一、前言二、使用 AI 辅助完成代码1. 基于模板创建项目2. 使用 AI 辅助开拓思路3. 使用 AI 辅助生成代码4. 使用 AI 辅助优化代码 三、InsCode AI Chat 的使用建议四、总结 一、前言 你好,我是小雨青年,一名独立开发的程序员。 在之前的文章中…

Ubuntu22.04安装PyTorch1.13.0 GPU版本

目录 一、电脑相关信息 1. 电脑显卡环境: 二、安装Pytorch1.13.0/cu117(GPU版本) 1. 准备:新建虚拟环境 2. 用conda在线安装pytorch1.13.0/cu117(pytorch1.13.0 torchvision0.14.0 pytorch-cuda11.7)…

博客管理系统前端分析

目录结构博客列表页&#xff1a;所有页面共同的样式代码&#xff1a;博客详情页博客登录页博客编辑页 目录结构 博客列表页&#xff1a; 页面效果&#xff1a; 代码&#xff1a; <!-- 博客列表页 --> <!DOCTYPE html> <html lang"en"> <head…

计算机视觉的深度学习 Lecture4:Optimization 笔记 EECS 498.008

数值计算梯度 问题是慢&#xff0c;每个都要注意做步长&#xff0c;求除法。 应该用求导方法解决。 SGD通过每次抽取一部分&#xff08;mini-batch&#xff09;来计算梯度&#xff0c;而不是遍历整个数据集来求梯度&#xff0c;大大增大了求梯度速度&#xff0c;并且性能不…

TCP 协议特性详解

TCP 协议特性总结 TCP协议特点TCP协议段格式TCP原理确认应答&#xff08;安全机制&#xff09;超时重传&#xff08;安全机制&#xff09;连接管理&#xff08;安全机制&#xff09;(面试高频题)三次握手四次挥手 滑动窗口&#xff08;效率机制&#xff09;流量控制&#xff08…

【LeetCode】数据结构题解(8)[链表中的入口节点]

链表中的入口节点 1.题目来源2.题目描述3.解题思路4.代码展示 1.题目来源 链表中的入口节点 2.题目描述 给定一个链表&#xff0c;返回链表开始入环的第一个节点。 从链表的头节点开始沿着 next 指针进入环的第一个节点为环的入口节点。如果链表无环&#xff0c;则返回 null…

08-HTML-样式和语意标签

1、<style> 标签用于为 HTML 文档定义样式信息。type 属性是必需的&#xff0c;定义 style 元素的内容。唯一可能的值是 "text/css"。style 元素位于 head 部分中。 2、<div> 可定义文档中的分区或节&#xff08;division/section&#xff09;。<div&…

Unity Audio -- (4)为声音添加特殊效果

本节我们使用声音混响区域&#xff08;audio reverb zone&#xff09;实现一些特殊效果。 什么是混响区域&#xff08;audio reverb zone&#xff09; 不同障碍物对声波的反射和吸收能力不同&#xff0c;坚硬平整表面反射声波能力强&#xff0c;松软多孔的表面吸收声波能力强。…