架构设计——概念和基础

🏠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.xdnf.cn/news/1537246.html

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

相关文章

Python编码系列—Python外观模式:简化复杂系统的快捷方式

🌟🌟 欢迎来到我的技术小筑,一个专为技术探索者打造的交流空间。在这里,我们不仅分享代码的智慧,还探讨技术的深度与广度。无论您是资深开发者还是技术新手,这里都有一片属于您的天空。让我们在知识的海洋中…

QT安装时出现错误(镜像)

QT下载网站 下载网址 QT安装时出现错误 解决方法 按“win+R”键弹出“运行”窗口,输入"cmd",点击确定; 打开如下图运行框,将Qt文件拖到窗口里->空一格输入“–mirror https://mirrors.aliyun.com/qt”->按enter键进入,即可成功安装 正式安

gazebo遇到的阶段性问题汇总

目录 1 gazebo中碰撞模型崩坏或者飞的问题2 编译报错解决方法 3 控制器无法正常启动解决方法 4 xacro:macro 定义函数5 xacro:property 定义变量的值报错截图解决方法 6 gazebo 模型视觉穿模(已设置碰撞体积)解决方法穿模截图 1 gazebo中碰撞模型崩坏或者…

王道408考研数据结构-绪论

1.1 数据结构的基本概念 数据结构 数据结构是相互之间存在一种或多种特定关系的数据元素的集合。在任何问题中,数据元素 都不是孤立存在的,它们之间存在某种关系,这种数据元素相互之间的关系称为结构(Structure)。 数据结构包括三方面的内…

中秋的“超级月亮”在哪?来竹海幻境寻找心中的白月光

夜幕低垂,一场视觉盛宴悄然拉开序幕——《桃花江竹海幻境》(下文简称《竹海幻境》)剧场中。一轮轮明月仿佛穿越时空的使者,与葱郁的竹林交相辉映,与天际那轮皎洁的明月共同编织出一幅“超级月亮”的绝美画卷&#xff0…

sizeof与strlen()函数的对比总结

目录 1.sizeof操作符1.1sizeof操作符特点 2.strlen( )函数2.1 函数简介2.2 创建字符串 3.sizeof 和 strlen的对比 1.sizeof操作符 在学习操作符的时候,我们学习了 sizeof , sizeof 计算变量所占内存内存空间⼤⼩的,单位是字节,如…

C++的类与对象下

目录 1.初始化列表 2.隐式类型转换 1.单参数 2.多参数(C11提供的新功能) 3.static成员 4.友元 5.内部类 6.匿名对象 1.初始化列表 C祖师爷规定初始化列表是成员变量定义与初始化的地方。 class Time { public:Time(int hour):_hour(hour){cout &…

从虚拟机安装CentOS到自定义Dockerfile构建tomcat镜像

写在开头 整个过程中涉及的三方软件均来源于三方的官网,因此需要有一个稳定良好的访问公网网络的环境,可能需要科学上网 下载并安装 VMware Workstation Player 下载 需要先注册登录:https://login.broadcom.com/signin 下载页面&#xff1a…

7-23 还原二叉树

代码&#xff1a; #include<iostream> using namespace std; int n; char a[55],b[55]; int dfs(int l,int r,int x,int y){ // printf("**l%d,r%d,x%d,y%d\n",l,r,x,y);if(l>r) return 0; // if(lr) return 1;int i;for(ix;i<y;i){if(a[l]b[i]) break;…

信息安全工程师(6)网络信息安全现状与问题

一、网络信息安全现状 威胁日益多样化&#xff1a;网络攻击手段不断翻新&#xff0c;从传统的病毒、木马、蠕虫等恶意软件&#xff0c;到勒索软件、钓鱼攻击、DDoS攻击、供应链攻击等&#xff0c;威胁形式多种多样。这些攻击不仅针对个人用户&#xff0c;还广泛影响企业、政府等…

【OJ刷题】双指针问题5

这里是阿川的博客&#xff0c;祝您变得更强 ✨ 个人主页&#xff1a;在线OJ的阿川 &#x1f496;文章专栏&#xff1a;OJ刷题入门到进阶 &#x1f30f;代码仓库&#xff1a; 写在开头 现在您看到的是我的结论或想法&#xff0c;但在这背后凝结了大量的思考、经验和讨论 目录 1…

Mac下nvm无法安装node问题

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

关于一道逻辑思维训练题的理解(手表、闹钟、标准时间的骗局)

说有一块手表&#xff0c;比闹钟每时慢30秒&#xff0c;而闹钟比标准时间每时快30秒&#xff0c;那么&#xff0c;这块手表是准时的么 &#xff1f; 这道题就是个带时间刻度的四维骗局 就是个文字游戏 接下来我们来分析一下&#xff0c;为什么说它是个骗局&#xff0c;简直与…

初写MySQL四张表:(3/4)

我们已经完成了四张表的创建&#xff0c;学会了创建表和查看表字段信息的语句。 初写MySQL四张表:(1/4)-CSDN博客 初写MySQL四张表:(2/4)-CSDN博客 接下来&#xff0c;我们来学点对数据的操作&#xff1a;增 删 查&#xff08;一部分&#xff09;改 先来看这四张表以及相关…

Java入门,初识Java

Java背景知识 Java是早期美国 sun 公司&#xff08;Stanford University Network&#xff09;在1995年推出的一门计算机高级编程语言。Java早期称为Oak&#xff08;中文翻译为&#xff1a;橡树&#xff09;&#xff0c;后期改名为Java。&#xff08;因为当时sun公司门口有很多…

【Linux系统编程】用互斥量和信号量加锁STL容器,避免并发问题

目录 引言 容器模型 容器代码 个人主页&#xff1a;东洛的克莱斯韦克-CSDN博客 引言 STL容器并没有保证线程安全&#xff0c;而大多数应用场景下&#xff0c;为了追求效率&#xff0c;多线程是必不可少的。而底层容器难免会有并发问题。从设计上来说要么在上层代码做加锁处…

Effective C++笔记之二十三:非void函数不写return

一.main函数 Qt Creator查看汇编的步骤如下 上图是g编译器下的汇编 eax就是main()函数的返回值 如果删掉return 0&#xff1b; 可以发现编译器还是把eax的值设为了0&#xff0c;由此可见&#xff0c;即使在main函数中不写return 0&#xff0c;编译器还是会默认添加个return 0。…

如何使用ssm实现一家运动鞋店的产品推广网站的设计

TOC ssm623一家运动鞋店的产品推广网站的设计jsp 绪论 1.1 研究背景 当前社会各行业领域竞争压力非常大&#xff0c;随着当前时代的信息化&#xff0c;科学化发展&#xff0c;让社会各行业领域都争相使用新的信息技术&#xff0c;对行业内的各种相关数据进行科学化&#xf…

手把手教你:在微信小程序中加载map并实现拖拽添加标记定位

本文将为大家详细介绍如何在微信小程序中加载map组件&#xff0c;并实现拖拽标记定位功能。 实现步骤 1、首先&#xff0c;我们需要在项目的app.json文件中添加map组件的相关配置。如下所示&#xff1a; {"pages": ["pages/index/index"],"permiss…

【网络安全 | 代码审计】PHP无参数RCE

未经许可,不得转载。 文章目录 无参数RCE代码审计1、利用Session ID实现无参数RCE2、利用get_defined_vars ()函数实现无参数RCE3、利用getallheaders()实现无参数RCE4、利用getenv()实现无参数RCE5、利用scandir()实现无参数RCE靶场实例无参数RCE 一般情况下,RCE需要通过传…