架构设计——概念和基础

news2024/11/11 6:53:31

🏠1 架构基础

  • 想要搞清楚架构到底指什么,架构与框架的区别,就需要了解梳理系统、子系统、模块、组件、框架和架构

1.1系统与子系统

1.1.1系统

wiki:系统泛指由一群有关联的个体组成,根据某种规则运作,能完成个别元件不能单独完成的工作的群体,它的意思是“总体”、“整体”、“联盟”
提炼:

  • 关联:有关联的个体组成才能是系统->发动机+PC≠系统,发动机+轮子+汽车相关=汽车系统
  • 规则:每个个体都按照指定规则运作,不是各自为政,规则包括分工、协调
  • 能力:系统能力≠单体能力相加,而是有一种新的能力,这是个体之间相互作用带来的结果
1.1.2子系统

子系统的定义和系统定义是类似的,只是观察角度有差异,一个系统可以是另一个更大系统的子系统

  • 微信是一个系统,聊天,登录,支付,朋友圈等是子系统
  • 朋友圈又有评论、点赞等子系统
  • 评论又包括防刷子系统,审核子系统,发布子系统等

1.2模块与组件

  • 模块和组件两个概念在实际工作中容易混淆,如下描述
    • Mysql模块主要负责存储数据,Es模块主要负责数据搜索
    • 我们有安全加密组件、审核组件
    • APP的下载模块使用了第三方的组件
      wiki-模块:Module是一套一致且互相有紧密关联的软件组织,包含程序和数据结构两部分。现代软件开发往往利用模块作为合成的单元,模块是可能被分开的单位,使得它们可用
      wiki-组件:自包含、可编程、可重用的、与语言无关的软件单元,软件组件可以很容易的被用于组装应用程序

1.3框架与架构

  • 框架和架构的概念比较相似,且有较强的关联关系
    wiki-框架:指的是为了实现某个业界标准或完成特定基本任务的软件组件规范,提供规范所要求之基础功能的软件产品
    wiki-架构:指软件系统的“基础结构”,创造这些基础结构的准则,以及对这些结构的描述
  • 只有明确说明了“基础结构”这个概念是从什么角度分解的,才能说明什么是架构什么是框架,如下
  • 以学生管理系统为例:
    Pasted image 20240103225755.png
  • 从物理部署角度触发,学生管理系统的架构如下
    Pasted image 20240103225920.png
  • 从开发规范角度:采用标准的MVC框架开发,因此架构又变成了MVC架构
    Pasted image 20240103230326.png

1.4重新定义架构

架构:软件架构指软件系统的顶层结构!

  • 首先,“系统由一群关联的个体组成”,这些“个体”可以是“子系统”“模块”“组件”等,架构需要明确系统包含哪些“个体”
  • 其次,系统中的个体需要“根据某种规则”运作,框架需要明确个体运作和协作的规则
  • 第三,wiki百科的架构定义中用到了“基础结构”这个说法,我们更改为“顶层结构”,可以更好的区分子系统和系统避免将系统架构和子系统架构混淆导致架构层次混乱

🎯2 架构设计的目的

2.1架构设计的误区

架构设计的目的?

  • 架构很重要,所以要做架构设计 ✘
    • 架构重要不是要做架构设计的原因:不做架构系统就不能跑?做了架构设计,能提高开发效率?
  • 不是每个系统都要做架构设计吗 ✘
    • 这就是麻木,盲目的跟风思想
  • 公司流程要求系统开发过程中必须有架构设计 ✘
    • 就像“架构师总要做点事”,“一天总得吃点饭”
  • 为了高性能、可用、可扩展,所以要做架构设计 ✘
    • 虽然这三个原因确实是架构设计带来的结果,但是如果带着这个观点去做架构设计,迟早有天要G
    • 上来就追求高性能、可用、可扩展,会造成最后的架构复杂无比,项目落地遥遥无期

2.2以史为鉴

  • 机器语言 1940之前
    • 使用二进制码0-1表示指令和数据,输出数据,编程会头晕眼花
  • 汇编语言 20世纪40年代
    • 符号语言,使用地址符号,或者标号代替指令或者操作数地址
    • 本质上面向机器编程,一个简单的功能,可能会更加的复杂
  • 高级语言 20世纪50年代
    • 为了解决汇编编程麻烦的问题,又出现了Fortran,LISP,Cobol…
  • 第一次软件危机与结构化程序设计 20世纪60年代~70年代
    • 软件质量低下,项目无法如期完成,水手一号火箭因为软件发射失败等等,《人月神话》也是这个时期由布鲁克斯写的
    • 诞生了结构化程序设计:自顶向下,逐步细化,模块化
  • 第二次软件危机与面向对象 20世纪80年代
    • 由于业务需求的复杂度增加,编程应用的领域扩大,第二次软件危机很快就到来了
    • 原因在于软件的生产速度跟不上硬件和业务的发展
    • 促使了面向对象的发展(1967年就有面向对象的概念)
  • 软件架构 20世纪60年代~90年代起
    • 在20世纪60年代就已经有软件架构的概念,但是在90年代才流行
    • 随着软件系统规模的增加,计算相关的算法和数据结构不再构成主要的设计问题,系统与系统之间的组织结构成为了新的问题
      • 表现在系统规模大,耦合强,开发效率低,修改扩展困难,难排查

2.3架构设计的真正目的

架构设计的目的是为了解决复杂度带来的问题

ℹ️3 复杂度来源

架构设计是为了解决软件复杂度是指导原则,但关键点是为什么架构设计会解决复杂度

3.1高性能

  • 对性能的追求是技术发展的根本驱动力:马车->蒸气火车->内燃机->电气机车,2G->3G->4G->5G,i7-8750->i7-13700

  • 软件系统也存在同样的现象,简单的科学运算->Google每秒几万次搜索…

  • 但是技术发展带来了性能上的提升,不一定带来复杂度的提升

  • 往往一些全新的领域的技术才会给系统带来复杂度

    • 因为系统在设计时需要在这些技术间进行判断选择或组合
    • 如同飞机不能取代火车,火车不能取代高铁一样,因为不同的东西有其特殊的比较因素
  • 软件系统中高性能带来的复杂度体现在两方面

    • 一方面是单台计算机内部为了高性能带来复杂度
    • 一方面是多台计算机机群为了高性能带来的复杂度

单机复杂度

  • 计算机内部复杂度最关键的地方在于操作系统,CPU的能力发挥全靠操作系统
    • 操作系统和性能最相关的是进程和线程
    • 但是线程,进程不相关联,为了让流程变得灵活,需要任务能够在运行中进行通信->管道,MQ,信号量,共享存储
    • 进程内部的任务也需要并行处理,又出现了线程,为进程的子任务
    • 线程之间共享进程数据,所以又出现了锁
  • 总结来说
    • 操作系统通过不断进化以适应硬件尤其是CPU性能的发展
    • 从最初的批处理到进程、线程的引入
    • 再到多核多处理器架构的利用,逐步提升系统并行处理能力和资源利用率
    • 同时也带来了诸如进程间通信、多线程并发控制等一系列复杂的技术挑战。
    • 在设计高性能软件系统时,需要根据业务需求灵活运用这些技术点,并非最新或最复杂的技术就是最佳选择。

集群的复杂度

  • 硬件发展飞速,但是在互联网时代,业务的发展速度远超硬件发展速度
  • 为了支持某一复杂业务,单机不够,需要多台机器,并且之间需要配合达到高性能
任务分配

每台机器都可以处理完整的业务,不同的任务发到不同的机器->lb负载均衡

  • 需要增加任务分配器,如:交换机或者软件网络设备,或负载均衡器,需要综合考虑性能、成本可维护性、可用性等方面
  • 任务分配器和真正的业务服务器之间的连接交互能力需要选择合适的连接方式,和连接管理方式。
    • 连接的建立,检测,重连该如何处理
  • 分配器的分配算法,轮询、权重分配,负载分配,如果是负载分配还需要任务服务器自己上次负载状态

当Qps达到很高的高度时,就会把一(分配器)对n(执行)的结构转变为n对n,如下图
Pasted image 20240105154739.png

  • 出现了新的问题,如果n对n,那么用户如何选择对于的任务分配器
    • DNS轮询,智能DNS,CND等设备和方法
任务分解

任务分解是通过将整个任务流程分解,或者说“拆服务”,如下
Pasted image 20240105155114.png

  • 将子业务拆分,将庞大的业务系统拆分,不管从开发的角度,还是故障排查的角度都能在一定程度上带来提升
    • 前提是拆的好有必要拆
  • 分解的优点
    • 简单的系统更容易做到高性能:系统简单,更容易找到关键性能点进行优化
    • 可以针对单个任务进行扩展:在单体架构下,往往影响系统的就那一两个功能,将功能拆分后,就可以对特定的功能拓展机器,提升性能

3.2高可用

高可用是指“系统无中断执行其能力”,代表系统的可用性程度

  • 无中断(关键):从单个硬件或者软件的层面出发,不可能做到无中断
    • 自身:比如硬件故障、老化问题,软件会有bug,软件的复杂度越来越高和庞大
    • 外部因素:断电,断网,灾害等等
  • 系统的高可用方案五花八门,但是万变不离其宗,本质上都是通过“冗余”来实现高可用
  • 虽然冗余方案和高性能看起来很像都是堆机器
    • 但本质上有根本区别:高性能在于扩展处理性能,高可用在于冗余处理单元
  • 冗余增强了可用性,但是也带来的复杂度

计算高可用(计算->业务的逻辑处理)

计算有一个特点:无论在哪台机器上进行计算,只要逻辑算法相同,参数一样,那么产出也是一样的

  • 所以将计算从一台机器迁移到另一台机器对业务没有影响,那么计算高可用的复杂度在哪呢?
单机变双机的简单架构

Pasted image 20240106150850.png

  • 复杂度在于
    • 增加一个任务分配器,要综合考虑性能、成本、可维护性、可用性等方面
    • 任务分配器的连接管理
    • 任务分配器的分配算法
高可用集群架构

Pasted image 20240106151621.png

  • 可以看出集群 的分配算法可能更加复杂
    • 可以是1主3备,2主2备,3主1备,4主0备,没有哪一种是最好的,要根据实际业务需求分析判断,比如ZK就是1主多备,Memcached采用全主0备,Redis采用3主6从+哨兵

存储高可用

对于存储数据的系统来说,系统的高可用设计关键点就在于存储高可用

  • 存储与计算相比的本质区别:将数据从一台机器搬到另一个机器,需要经过线路进行传输。
    • 线路传输是毫秒级:同一个机房能做到毫秒级,但是分布在各地的机房要做到线路传输,如果算上网络稳定网络分区物理线路故障等问题,那么延迟将会达到500毫秒到秒级
  • 因为业务=数据+逻辑如果数据没能成功同步,对于整个集群来说,可能就会出现数据不一致,那么就会出现业务表现不一致,如下
    Pasted image 20240107131338.png
    无论正常情况还是异常情况下的传输都会导致系统在某个时间点的数据不一致,从而导致业务不一致,但是不做冗余,系统的整体的高可用又无法保证
    所以存储高可用的难度不在于如何备份数据,而在于如何减少和规避数据不一致对业务造成的影响
高可用状态决策(判断是否可用)
  • 无论计算高可用还是存储高可用,基础都是“状态决策”,也就是系统要能够判断当前机器是否是正常还是异常
    • 异常就要采用行动来保证数据一致性
    • 但是通过冗余来实现高可用,状态决策本质上就不可能做到完全正确这是相矛盾的
独裁式决策
  • 存在一个决策主体,一个leder
    • 主要负责收集信息然后进行决策
  • 存在多个上报者
    • 主要将自己的状态信息发送给决策者
  • 独裁式不会出现脑裂类似的情况,因为只有一个决策者
    Pasted image 20240107144518.png
协商式决策
  • 两个独立的个体通过交流信息,然后根据规则进行决策,最常用的就是主备决策
    Pasted image 20240107144724.png
  • 规则如下
    1. 2台服务器启动时都是备机
    2. 2台服务器建立连接
    3. 2台服务器交换状态信息
    4. 某1台服务器做出决策成为主机,另1台服务器继续保持备机身份、
  • 可以发现协商式的架构和规则并不复杂,真正的难点在于交换信息发生了问题(网络分区),此时决策该怎么做
    1. 如果一旦发生联系不上另一个机器就认为其出现故障,但是如果只是网络问题,那么就会出现两个主机
    2. 如果不认为主机故障,那么当主机真的故障了怎么办
    3. 采用多个连接,只要有一个连接可用就能使用
      Pasted image 20240107145623.png
      1. 多连接又会存在,如果多个连接之间的信息不同,该听谁的
        所以协商式在某些场景下总会有一些问题
民主式决策
  • 民主式决策是指多个独立的个体通过投票的方式进行状态决策。
    • 如ZK选举Leder时就采用这种方式
  • 民主和协商很像,都是独立个体交换信息,按照多数取胜的规则来决定状态,不同在于民主比协商决策规则更复杂
  • 民主式有一个固有缺陷:脑裂,来源于集群由于网络分区导致两个子集群各自做出了两套决策
    Pasted image 20240107150442.png
  • 为了解决脑裂,民主决策系统一般采用超过系统总结点数一半的规则来处理
综上(无论采取什么方案,都会有一定的问题,选哪个还是要进行分析、判断和抉择)

3.3可扩展性

可扩展性是指系统为应对将来需求变化而提供的一种扩展能力

  • 可扩展性越强,可能在新的需求出现时修改的代码量更少,无需整个系统重构
  • 面相对象思想提出就是为了更好解决可扩展性的问题
预测变化
  • 软件系统与硬件或者建筑相比,有一个很大的差异:软件可以在发布后不断修改和演进,可以扩展,但是建筑等却不行。

  • 但是如果我们只在乎当下,不去预测变化,或者推演判断架构将来的变化和缺陷,那么就会出现一个需求大改一次系统,这和建房子推翻重造有什么区别

  • 所以我们要去在有限的条件内去预测系统的变化,但是
    人不是神,不会全部预测正确,并且如果总是去预测所有变化也是不现实的,并且预测的结果过于离谱需要投入的资源很多也是没有必要

  • 所以预测变化的复杂性在于:

    1. 不能每个设计点都考虑扩展性
    2. 不能完全不考虑可扩展性
    3. 所有的预测都存在出错的可能
  • 对于架构师来说,把握预测程度和提升预测结果的准确性是很复杂的事情

    • 没有通用的标准
    • 只能靠直觉和经验
应对变化
  • 即使所有的变化都能准确预测,那么预测后用什么方案来解决也是一个问题,方案用错了即使预测对了也没用

  • 第一种应对变化的常见方案是将“变化”封装在一个变化层,不变化的就放在“稳定层”

    • 无论变化依赖稳定,还是稳定依赖变化都可以,如下两个架构就是不同的依赖情况
  • 支持XML、JSON、ProtocolBuffer接入方式,接入方式为变化层

  • 支持MySQL、Oracle、DB2数据存储,数据存储为变化层

  • 无论采用哪种形式,通过剥离变化和稳定层来应对变化,都会带来两个复杂行问题

    • 谁是稳定层谁是变化层,现实的例子不会如同我们举的例子一样,不同的人有不同的理解,怎么界定稳定和变化是一个复杂的问题
    • 设计变化和稳定层之间的接口,稳定层的接口肯定要稳定,变化层的接口需要抽象出共同点,还要保证新功能加入时不影响原有接口
  • 第二个问题可以通过设计模式解决,比如装饰器模式

3.4低成本

  • 一般情况下成本并不是我们重点关注的目标

    • 当我们的架构方案只涉及几台或十几台服务器时,成本并不高
    • 但是当这个方案涉及几百上千台服务器时,成本就会变成一个非常重要的考虑点
  • 可以想象如果一台机器的成本一年为2万元,那么如果1万台机器节省20%,一年就可以节省4000万成本

  • 当我们设计高性能和高可用架构时通用手段都是通过增加更多服务器来满足其要求

    • 而低成本正好和其要求相反
    • 所以在设计高性能高可用时,还要评估方案是否满足成本目标
      • 但是成本也不是一成不变的😏
  • 低成本给架构设计带来的复杂度就在于:往往只有创新才能达到低成本目标

    • 这里的创新既包括开创一个全新的技术领域,也包括引入新技术(没找到可以解决问题的新技术,那就只能自己创造新技术)
    • 例如:
      • NoSQL的出现就是解决关系型数据库无法因对高并发访问带来的访问压力
      • 全文搜索引擎的出现是为了解决关系型数据模糊查询低效问题
      • Hadoop的出现是为了解决传统文件系统无法应对海量数据存储和计算的问题
      • FaceBook为了解决PHP低效,做了类似Java的JVM的虚拟机运行字节码
      • 微博将传统的Redis/MC + MySQL方式,扩展为Redis/MC + SSD Cache + MySQL,SSD Cache作为二级缓存,解决了Redis等成本高,容量小,也解决穿透DB带来的数据库压力
      • Kafka消息系统,解决了Linkedin为了处理每天 5千亿 个事件的大数据消息消费
    • 创造技术对于小公司来说是性价比很低的事,往往引入新技术来达到低成本目标
    • 而大公司有可能去创造新技术达到低成本->大公司独有的资源、技术、时间

3.5安全

从技术角度讲,安全分为两类:功能上的安全与架构上的安全

3.5.1功能安全

  • 常见的XSS攻击、CSRF攻击、SQL注入、Windows漏洞、密码破解等

    • 让黑客有机可乘的是系统本身就有漏洞,黑客的能通过多种手段分析你的系统漏洞,然后进行攻破,手段很多
    • 所以功能安全更像是填补漏洞,《保卫系统》
  • 功能安全更多是和具体的编码相关,与架构关系不大。但是很多开发框架内嵌了常见的安全的功能能尽量避免一些安全问题

  • 我们所能知道的是,漏洞是不断被发现的,已知的漏洞可以修复,但是新的漏洞很可能就需要被攻破后才能进行补救

  • 所以系统架构设计的功能安全不是一劳永逸的

3.5.2架构安全

  • 功能安全是防漏洞,那么架构安全就是防“强盗”,一个“炸弹”给你扬了,故意破坏有时候比漏洞安全更可怕

  • 传统的架构安全主要依靠防火墙,进行隔离网络,将网络划分不同的区域,制定出不同区域的访问控制策略
    Pasted image 20240110180315.png
    可以看到整个系统根据不同分区部署多个防火墙来保证安全

  • 防火墙虽然吊,但是在传统的银行和企业应用领域较多

  • 互联网领域防火墙应用场景并不多,主要是互联网的业务具有高并发和海量用户访问的特点,防火墙性能支撑不了

    • 尤其是DDOS攻击,轻则几个G,上不封顶
    • 海量DDOS攻击用防火墙来抗,就需要部署大量防火墙成本高
  • 综上所述,互联网系统的架构安全目前并没有太好的设计手段实现,更多是依靠运营商或者云服务商强大的带宽和流量清洗能力

3.6规模

规模带来的复杂度:量变引起质变

  • 有一些系统,没有高性能、双中心高可用、扩展性等要求,但反而会显得很复杂
    • 因为往往这类系统的功能很多、逻辑分支多
    • 发展时间长,功能的不断叠加,让人一看一抹黑

3.6.1功能增加导致

功能越做越多,导致系统复杂度指数级上升

例如:某个系统最开始只有三大功能,后来增加到8个,复杂度如下:
3个功能:3(自身)+3(功能交互)=6
8个功能:8(自身)+28(功能交互)=36
Pasted image 20240111164043.png
可以发现具备8个功能的系统复杂度要更高

3.6.2数据增加导致

数据越来越多,系统复杂度发生质变

为什么数据量增大会导致系统复杂度变高?
以MySQL数据量达到10亿行举例子

  1. 添加索引会更慢,可能几个小时,你会想“我擦这么久”,是的就是这么久,并且这几个小时中,表是没办法插入数据的,业务卡死
  2. 修改表结构和添加索引存在类似问题
  3. 即使有索引,数据索引性能也会降低
  4. 数据库备份耗时增加,主从同步时间间隔增加,数据不一致的情况会更严重

所以,当单表数据量太大时,就需要拆表,拆表也会带来复杂度

  • 按照什么规则拆表,维度是哪个,如用户表,是按id分还是注册时间分
  • 拆完怎么查询?

📖4 小结

  • 系统:泛指由一群有关联的个体组成,根据某种规则运行,能完成个别元件不能单独完成的工作群体
  • 子系统:定义和系统类似,只不过他是更大系统的一部分
  • 软件模块:是一套一致而互相紧密关联的软件阻止,分别包含程序和数据结构
  • 软件组件:为自包含、可编程、可重用的、与语言无关的软件单元,可以很容易被组装应用程序中
  • 软件框架:为了实现某个业界标准或完成特定任务的软件组件规范
  • 软件架构:软件系统的顶层结构
  • 同一软件系统从不同角度进行分解会得到不同架构
  • 架构设计的主要是为了解决软件系统复杂度带来的问题
  • 主要的软件复杂度:高性能、高可用、高扩展、低成本、安全、规模几种

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

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

相关文章

无限制使用OpenAI最新o1-mini、o1-preview模型:经济高效的AI推理模型

OpenAI 最新推出的 o1 模型是该公司推理模型家族的首位成员,它通过创新的“思维链”训练模式,显著提升了逻辑推理和问题解决的能力。o1 模型在编程竞赛问题、数学奥林匹克资格赛以及物理、生物和化学问题的基准测试中表现出色,甚至在某些领域…

数据爬虫中遇到验证码的解决方法

在数据爬虫中遇到验证码是一个常见且复杂的问题,验证码的存在主要是为了阻止自动化工具(如爬虫)对网站进行过度访问或数据抓取,以保护网站的安全性和数据的准确性。 一、验证码的基本概念与类型 验证码(CAPTCHA&…

PointNet++改进策略 :模块改进 | LFA | RandLA-Net,通过随机采样与局部特征聚合提升大规模3D点云处理效率

论文题目:RandLA-Net: Efficient Semantic Segmentation of Large-Scale Point Clouds发布期刊:CVPR作者地址:1牛津大学、2中山大学、3国防科学技术大学代码地址:https://github.com/QingyongHu/RandLA-Net介绍 这篇论文题为《RandLA-Net: Efficient Semantic Segmentatio…

我又做了一个国标GB28181设备模拟器的Windows版本,让国标28181开发更简单,不用再费劲弄个摄像机来调试国标GB28181开发了

之前我搞过一个《EasyGBD国标GB28181设备端模拟器帮助测试国标GB28181平台(EasyGBD->EasyGBS)》,当时,主要是在安卓手机上,用摄像机的本地摄像头来做为视频源、用摄像机的麦克风做为音频源,对外…

基于windows的mysql5.7安装配置教程

目录 0.写在前面的话 1.下载安装包 2.进行目录选择和解压操作 3.配置环境变量 4.创建my.ini文件 5.管理员运行终端 6.安装mysqld 7.初始化数据库 8.启动mysql服务 9.进入mysql管理终端 10.修改root密码 11.刷新权限 12.注销内容 13.重启mysql 14.输入密码测试 1…

Node.js 安装及项目实践

node.js安装 node安装,选择版本 一直next,或者自己修改路径,添加两个包 选择自己的安装的node的路径,cmd或者winr cmd 显示node与npm的版本号 node -vnpm -v可以跟着这个博客将node安装 2024最新版Node.js下载安装及环境配…

云原生信息安全:筑牢数字化时代的安全防线

云原生信息安全:筑牢数字化时代的安全防线 一、云原生信息安全概述 云原生安全包含两层重要含义。一方面,面向云原生环境的安全,目标是防护云原生环境中的基础设施、编排系统和微服务等系统的安全。在云原生内部,安全机制多以云原…

Java--String类(StringBuilder与StringBuffer)

String类的特征: String类的特点: 1. String 类在设计时就是不可改变的, String 类实现描述中已经说明了 String部分源码如下: 2. 所有涉及到可能修改字符串内容的操作都是创建一个新对象,改变的是新对象 例如…

string的模拟实现and友元

一、引言 “知所从来,方知其往。”只有了解一个物体的构造才能更好的使用它。正所谓“不入虎穴,焉得虎子。”那我们学会使用一个类了,可不可以建造一个简易的类和对象出来呢?答案显而易见。因为这是C的内容,所以我们用…

C++八股文之STL篇

🤖个人主页:晚风相伴-CSDN博客 思维导图链接:STL 持续更新中…… 💖如果觉得内容对你有帮助的话,还请给博主一键三连(点赞💜、收藏🧡、关注💚)吧 &#x1f64…

找搭子是什么意思?有没有找搭子的平台?靠谱找搭子软件推荐!

“找搭子” 指寻找在特定活动或兴趣方面有共同爱好的伙伴。比如饭搭子一起吃饭,运动搭子共同健身。它满足人们在特定场景下的社交需求,让生活更丰富有趣,是一种新型社交方式。以下是国内排名靠前的找搭子平台 1. 咕哇找搭子小程序&#xff1a…

Mac下nvm无法安装node问题

背景 最近换用mac开发,然后使用nvm(版本0.40.1)进行node安装的时候出现了一些问题 使用 nvm ls-remote发现只有 iojs 版本 原因可能是nodejs升级了某个协议导致的 解决方案 可以使用 NVM_NODEJS_ORG_MIRRORhttp://nodejs.org/dist nvm ls-re…

Cartographer源码理解

一、前言 最近一个半月,利用空余时间对Cartographer源码进行了简单的阅读,在这里做了个简单梳理,和大家分享交流。 cartographer源码量其实是有点大的,逐行逐句去解释实在是有心无力了,而且已经有大佬做了类似的事情…

分治算法归并排序

分治算法 基本概念 把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题…直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。 分治法的基本步骤 分治法在每一层递归上都有三个步骤: step1分…

单细胞CCA整合流程学习(SeuratV5/V4)

CCA(Canonical Correlation Analysis)和 Harmony 是两种常用于单细胞 RNA 测序(scRNA-seq)数据整合和批次效应校正的方法。 CCA 通过计算两个(或多个)数据集的线性组合,使这些组合之间的相关性…

1、vectorCast单元测试常用操作

一、自动创建测试工程 1、设置工作目录 进入软件主页面,点击file,选择set working directory,随便选择一个保存该项目的目录即可。 2、创建一个空工程 编译器选择vector自带的编译器,vectorCast MinGW C。 此时项目工程就创建好了 2.1、配置编译器节点 点击编译器节点…

JAVA毕业设计173—基于Java+Springboot+vue3的酒店民宿管理系统(源代码+数据库)

毕设所有选题: https://blog.csdn.net/2303_76227485/article/details/131104075 基于JavaSpringbootvue3的酒店民宿管理系统(源代码数据库)173 一、系统介绍 本项目前后端分离(可以改为ssm版本),分为用户、员工、管理员三种角色 1、用户&#xff1a…

Nowcoder—链表的回文结构

题目描述 题目分析 1.回文结构是指一个序列或字符串从前往后读或从后往前读都是相同的。 2.时间复杂度为O(n),说明循环只能有一层;空间复杂度为O(1),说明不能额外的申请空间。 3.链表的结点最多不会超过900个。 思路 1 思路1:…

2024年数字中国创新赛-MISC

1 wireshark-1 可以看到在theanswerishere.php执行了sql注入,所以存在漏洞的PHP页面名称是theanswerishere.php 2 wireshark-2 从以上漏洞测试我们发现在一共有三列 3 wireshark-3 从这里我们可以看到注入的列名是th1sfI4g 4 wireshark-4 从这里回显包我们能看到…

鸿蒙next web组件和h5 交互实战来了

前言导读 鸿蒙next web组件这个专题之前一直想讲一下 苦于没有时间,周末把代码研究的差不多了,所以就趁着现在这个时间节点分享给大家。也希望能对各位读者网友工作和学习有帮助,废话不多说我们正式开始。 效果图 默认页面 上面H5 下面ArkU…