15.【.NET 8 实战--孢子记账--从单体到微服务--转向微服务】--单体转微服务--如何拆分单体
单体应用(Monolithic Application)是指将所有功能模块集中在一个代码库中构建的应用程序。它通常是一个完整的、不可分割的整体,所有模块共享相同的运行环境和数据库。这种架构开发初期较为简单,部署也较为方便,但随着应用规模的增大,模块间的高度耦合会导致维护困难、扩展性差等问题。
微服务(Microservices)是一种将应用程序拆分为多个独立服务的架构设计,每个服务专注于完成特定的功能,如用户管理、订单处理或支付等。微服务是松耦合的,每个服务可以独立开发、部署和扩展,并通过轻量级协议(如REST或消息队列)与其他服务通信。它强调单一职责原则,允许团队按需为每个服务选择最佳的技术栈。
将单体应用拆分为微服务的主要原因在于灵活性和效率的提升。微服务架构允许独立扩展某些高负载模块,而无需扩展整个系统,从而提高资源利用率。团队开发效率也得到提高,因为不同的团队可以并行开发不同的服务。系统的可靠性也更高,即使某个服务发生故障,也不会影响整个系统的运行。此外,微服务还便于技术更新,每个服务可独立演进,减少技术债。然而,拆分过程需要权衡复杂性,确保转换的收益大于成本。
一、拆分前的准备工作
在将单体应用拆分为微服务之前,必须对现有的单体架构有一个全面的理解,并明确拆分的优先级。这是整个微服务迁移过程的基础,决定了后续拆分的方向和效率。如果没有充分的准备,可能会导致系统无法正常运行或者拆分效果不佳。因此,准备工作主要包括两个方面:理解现有单体架构和确定拆分优先级。
1.1 理解现有单体架构
要成功将单体应用拆分为微服务,首先需要对现有的单体架构进行全面而详细的分析。这不仅包括对业务功能的梳理,还需要深入了解模块之间的依赖关系以及当前系统的性能瓶颈和维护难点。
-
梳理业务功能模块
梳理业务功能模块是理解单体架构的第一步。可以通过以下几种方式进行:- 功能清单:列出当前单体应用中所有的功能模块,例如用户管理、订单处理、支付系统、库存管理等。将功能模块按照业务逻辑进行分类,形成一个清晰的功能层次结构。
- 流程分析:绘制系统的业务流程图,明确每个功能模块在各个流程中的职责和作用。例如,用户下单需要依赖用户模块、订单模块和支付模块,理解这些流程有助于后续划分微服务的边界。
- 代码分析:通过代码阅读工具或代码分析工具(如SonarQube)来挖掘模块之间的耦合度,找到哪些模块独立性较高,哪些模块与其他模块强依赖。
通过梳理业务功能模块,可以清楚地了解系统的核心功能以及支持功能,为后续的模块拆分打下基础。
-
分析模块间的依赖关系
模块之间的依赖关系是单体架构的核心特点之一,深刻理解这些依赖关系可以帮助我们找到拆分的关键点。一个常见的问题是模块之间的强耦合,这会导致拆分难度增加。因此,以下几个方面需要重点关注:- 数据依赖:哪些模块共享了同一数据库表?例如,用户模块和订单模块可能都会访问用户表,这种数据共享会在拆分时产生挑战。
- 功能调用:哪些模块需要频繁调用其他模块的功能?例如,订单模块可能频繁调用库存模块检查库存,这种强调用关系可能需要通过API重新设计。
- 耦合点分析:通过代码分析工具,统计模块之间的调用次数和调用方向,找到耦合点最多的模块。
在分析依赖关系时,建议绘制模块依赖图,直观地展示模块之间的相互关系。这对于后续选择拆分优先级以及设计微服务通信是非常重要的。
-
识别性能瓶颈与维护难点
单体应用的性能瓶颈和维护难点通常是推动微服务化的主要动因。通过以下手段可以识别这些问题:- 性能监控:通过性能监控工具(如Prometheus、New Relic),分析系统中高负载的模块。例如,某些模块的响应时间过长或某些数据库查询频率过高。
- 错误日志分析:检查系统的错误日志,找到故障率较高的模块。这些模块在微服务化时需要特别关注。
- 维护历史记录:通过版本管理工具(如Git),查看哪些模块的代码更改频繁。更改频繁的模块可能存在设计缺陷或者业务逻辑复杂,适合优先拆分。
通过对性能瓶颈和维护难点的识别,可以明确微服务化后需要重点优化的部分,确保拆分能够带来实际的效益。
1.2 确定拆分优先级
在充分理解单体架构后,需要根据业务需求和技术需求确定拆分的优先级。这一步的核心是选择合适的模块作为起点,逐步推进微服务化的过程。
-
基于业务领域划分
业务领域是划分微服务的基础,一个合理的划分可以让微服务更贴近实际的业务需求。基于业务领域划分时,需要遵循以下原则:- 领域驱动设计(DDD):通过领域驱动设计的方法,识别出核心领域、支撑领域和通用领域,确保每个微服务都能独立完成其业务功能。
- 核心业务优先:优先拆分核心业务模块,例如订单处理模块或支付模块。这些模块通常是业务的核心驱动力,也是性能优化的重点。
- 边界清晰:确保每个业务领域的边界清晰,避免功能重叠。例如,用户模块只应负责用户相关的功能,而不要涉及订单逻辑。
通过业务领域划分,可以确保微服务的职责单一,降低后续开发和维护的复杂性。
-
基于技术需求选择
除了业务领域外,还需要考虑技术上的需求。例如,一些模块由于性能压力大或者技术栈落后,可能需要优先拆分:- 高并发模块:如支付模块或搜索模块,这些模块通常需要独立扩展以应对高并发请求。
- 技术栈更新:某些模块可能使用了过时的技术栈,维护成本高且难以扩展。将这些模块拆分为微服务后,可以选择更现代的技术栈重新实现。
- 独立性较高的模块:例如日志记录模块或文件上传模块,这些模块通常与其他模块的依赖较少,适合作为拆分的起点。
通过技术需求的分析,可以优先拆分那些能够快速带来收益的模块,为后续的拆分积累经验。
二、微服务架构设计
微服务架构的设计是实现单体应用拆分的核心步骤,它直接决定了后续微服务的开发、部署和运维的效率与质量。在设计微服务架构时,需要明确微服务的边界、数据独立性、通信机制以及安全性,确保系统的可扩展性和可靠性。
2.1 定义微服务边界
-
按业务领域划分
微服务的边界应与业务领域高度契合,这样可以使每个微服务聚焦于特定的业务功能。例如,电商系统可以划分为用户服务、订单服务、支付服务、商品服务等,每个服务负责一类业务逻辑。使用领域驱动设计(DDD)的方法,可以帮助识别核心领域和支撑领域,从而定义清晰的服务边界。 -
遵循单一职责原则
微服务的设计应遵循单一职责原则(SRP),即每个服务只关注一个特定的功能领域,避免职责混乱。例如,订单服务只负责订单的创建、查询和管理,而不应该包含任何与用户认证或库存管理相关的逻辑。单一职责不仅有助于服务的独立开发和维护,还可以降低服务间的耦合度。
2.2 数据独立性
-
数据库拆分策略
在微服务架构中,每个服务应拥有独立的数据库,避免多个服务直接共享数据库。常见的拆分策略包括:- 按业务领域拆分:每个服务拥有与其业务领域相关的数据。例如,用户服务使用用户数据库,订单服务使用订单数据库。
- 按数据存储类型拆分:不同的服务可以选择最适合其业务场景的数据库类型,例如关系型数据库(MySQL)或文档型数据库(MongoDB)。
-
数据同步与一致性处理
微服务之间的数据交互可能会导致数据不一致的问题,需要设计合适的同步与一致性机制:- 事件驱动架构:通过消息队列(如Kafka或RabbitMQ)实现服务间的异步通信,确保数据的最终一致性。
- 分布式事务:在必须保证强一致性的场景中,可以使用分布式事务管理器(如Saga模式或TCC模式)来协调多个服务的操作。
2.3 服务通信机制
-
RESTful API、gRPC、消息队列等通信方式
微服务之间的通信方式需要根据具体需求选择:- RESTful API:适用于简单的HTTP通信,易于实现和调试。
- gRPC:适用于高性能场景,支持多语言和二进制通信。
- 消息队列:适用于需要解耦的异步通信场景,例如使用RabbitMQ或Kafka处理事件通知。
-
服务发现与负载均衡设计
微服务架构需要支持动态扩展和服务发现:- 服务注册与发现:使用工具(如Eureka、Consul、Zookeeper)实现服务的自动注册和发现。
- 负载均衡:通过反向代理(如Nginx)或服务网格(如Istio)实现流量分发,提升系统性能和可靠性。
2.4 安全性与认证
- OAuth2、JWT 等认证机制
微服务之间的通信和用户访问需要确保安全性:- OAuth2:适用于统一的用户认证,提供授权码模式、客户端模式等多种认证方式。
- JWT(JSON Web Token):通过签名的方式验证请求的合法性,适合服务间的轻量级认证。
- 加密通信:使用TLS/SSL加密服务间的通信,避免数据被窃听或篡改。
通过以上架构设计,微服务能够在保证独立性、性能和安全性的前提下,实现系统的高可用性和扩展性。这些设计原则和方法为后续的开发和部署提供了清晰的指导方向。
三、拆分与迁移步骤
拆分与迁移是从单体应用过渡到微服务架构的关键阶段。在这一阶段,需要选择合适的模块作为切入点,逐步拆分并迁移到微服务架构,同时通过重构和测试,保证系统的稳定性和功能的完整性。
3.1 选择模块并逐步拆分
-
从低风险模块开始
在拆分初期,优先选择低风险模块进行微服务化,例如日志记录服务、身份认证服务或文件上传服务。这些模块通常与核心业务逻辑耦合较低,其功能相对独立,拆分和迁移对整体系统的影响较小。
低风险模块的拆分可以帮助团队快速积累经验,验证微服务架构的技术选型和设计模式,为后续高复杂度模块的拆分奠定基础。 -
使用 API 替代原有的内部调用
拆分模块后,原本在单体应用中通过方法调用实现的功能需要改为通过 API 调用来交互。可以采用以下步骤:- 定义清晰的接口:为每个微服务设计统一的 API 接口,明确输入输出数据格式和通信协议。
- 逐步替换调用:在重构过程中,将原有的内部方法调用替换为微服务 API 调用,确保功能一致。
- 接口文档与测试:编写详细的 API 文档,并使用 Postman、Swagger 等工具测试接口的可靠性。
通过这种逐步替换的方式,可以在不影响现有系统运行的前提下完成模块的拆分。
3.2 重构与验证
-
单元测试与集成测试
在拆分过程中,测试是保障系统功能稳定的核心手段:- 单元测试:为每个拆分后的微服务编写详细的单元测试,验证其独立功能的正确性。
- 集成测试:在多个微服务间进行交互测试,确保服务间的通信正常,数据流转无误。
- 模拟环境测试:在测试环境下模拟生产环境的服务调用场景,验证微服务的负载能力和容错机制。
-
保证新旧模块共存的同时平稳过渡
为了避免业务中断,可以采用“蓝绿部署”或“分阶段迁移”的方式,保证新旧模块在一段时间内共存:- 在拆分初期,新微服务上线后,仍保留单体应用中相应的模块,确保系统在功能上的延续性。
- 通过流量分流工具(如 Nginx、API 网关)部分引导流量到新微服务进行验证,观察其性能和稳定性。
- 当新微服务经过充分验证后,逐步完全切换流量并移除旧模块,实现系统的平稳过渡。
通过选择合适的拆分模块、替换调用方式以及全面的测试和验证,单体应用可以逐步拆分为微服务架构,同时保证系统在拆分和迁移过程中的稳定性和可靠性。
四、总结
单体应用是将所有功能模块集中在一个代码库中的整体软件架构,开发和部署较为简单,但随着系统复杂度的增加,模块间的耦合度过高会导致维护困难、扩展性差等问题。相比之下,微服务架构将应用拆分为多个独立的服务,每个服务聚焦于特定功能,具备独立开发、部署和扩展的能力。这种架构通过轻量级通信协议(如REST或消息队列)实现服务间的协作,强调单一职责原则,并允许团队为每个服务选择最合适的技术栈。
从单体应用迁移到微服务架构,需要全面理解现有单体系统,包括梳理业务功能模块、分析模块依赖关系以及识别系统的性能瓶颈与维护难点。基于业务领域和技术需求划分微服务边界,每个服务独立拥有数据库,通过事件驱动或分布式事务等机制保障数据一致性。同时,微服务通过API、消息队列等方式实现通信,借助OAuth2、JWT等机制实现安全认证。
迁移过程中,优先拆分低风险模块,通过替换原有内部调用为API调用逐步完成拆分。在拆分后,通过单元测试和集成测试确保功能稳定性,并采取蓝绿部署等策略保证新旧系统的平稳过渡。最终,微服务架构能够显著提高系统的灵活性、可靠性及扩展性,但需要平衡复杂性与收益。
相关文章:
15.【.NET 8 实战--孢子记账--从单体到微服务--转向微服务】--单体转微服务--如何拆分单体
单体应用(Monolithic Application)是指将所有功能模块集中在一个代码库中构建的应用程序。它通常是一个完整的、不可分割的整体,所有模块共享相同的运行环境和数据库。这种架构开发初期较为简单,部署也较为方便,但随着…...
C++: char类型既不是signed char也不是unsigned char
对于 int, short, long, long long 类型, 增加 signed, 类型不变。 对于 char 类型, 增加 signed, 类型变了。 char 既不是 signed char, 也不是 unsigned char。 虽然 char 的取值范围, 一定是࿱…...
测试第二课-------测试分类
作者前言 🎂 ✨✨✨✨✨✨🍧🍧🍧🍧🍧🍧🍧🎂 🎂 作者介绍: 🎂🎂 🎂 🎉🎉🎉…...
16.【.NET 8 实战--孢子记账--从单体到微服务--转向微服务】--单体转微服务--微服务的部署与运维
部署与运维是微服务架构成功实施的关键环节。一个良好的部署与运维体系能够保障微服务的高可用性、可扩展性和可靠性。在这一阶段,重点包括微服务的容器化与编排、API 网关的实现以及日志与监控体系的建设。 一、容器化与编排 1.1 使用 Docker 容器化微服务 容器…...
什么是供应链金融
供应链金融(Supply Chain Finance) 是一种基于供应链上下游真实交易场景的金融服务模式,通过整合物流、信息流、资金流和数据流,为核心企业及其上下游中小企业提供灵活、高效的融资解决方案。其核心目标是优化供应链资金周转效率&…...
个人博客系统后端 - 注册登录功能实现指南
一、功能概述 个人博客系统的注册登录功能包括: 用户注册:新用户可以通过提供用户名、密码、邮箱等信息创建账号用户登录:已注册用户可以通过用户名和密码进行身份验证,获取JWT令牌身份验证:使用JWT令牌访问需要认证…...
微信小程序运行机制详解
微信小程序运行机制详解 微信小程序是介于 Web 和原生 App 之间的一种应用形态,具有无需安装、用完即走、体验流畅的特点。本文将从架构层面、运行环境、通信机制等方面深入剖析微信小程序的运行机制。 一、小程序运行架构概览 微信小程序采用双线程模型ÿ…...
GGML源码逐行调试(中)
目录 前言1. 简述2. 加载模型超参数3. 加载词汇表4. 初始化计算上下文5. 初始化计算后端6. 创建模型张量7. 分配缓冲区8. 加载模型权重结语下载链接参考 前言 学习 UP 主 比飞鸟贵重的多_HKL 的 GGML源码逐行调试 视频,记录下个人学习笔记,仅供自己参考&…...
高阶函数/柯里化/纯函数
本篇文章主要是介绍一下标题里面的概念,在面试的时候经常文档,结合阅读到的资料,结合本人的个人见解出品了该文章,如有写的不好的地方或理解有误的,还望阁下多多指教。 1、高阶函数 什么是高阶函数? 接受…...
docker部署scylladb
创建存储数据的目录和配置目录 mkdir -p /root/docker/scylla/data/data /root/docker/scylla/data/commitlog /root/docker/scylla/data/hints /root/docker/scylla/data/view_hints /root/docker/scylla/conf快速启动拷贝配置文件 docker run -d \--name scylla \scylladb/…...
Python创意:AI图像生成
1. 基本概念 AI 图像生成通常基于以下几种方法: 一.生成对抗网络 (GAN) 生成对抗网络(GAN,Generative Adversarial Network)是一种深度学习框架,主要用于生成新的、类似于训练数据的样本。自2014年由Ian Goodfellow及…...
十九、UDP编程和IO多路复用
1、UDP编程 服务端: #include<stdio.h> #include <arpa/inet.h> #include<stdlib.h> #include<string.h> #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> #include <pthread.h> #include &l…...
【MySQL】复合查询
文章目录 👉基本查询回顾👈select 子查询 👉多表查询👈👉自连接👈👉子查询👈单行子查询多行子查询多列子查询在from子句中使用子查询合并查询 👉总结👈 &…...
并发编程--条件量与死锁及其解决方案
并发编程–条件量与死锁及其解决方案 文章目录 并发编程--条件量与死锁及其解决方案1.条件量1.1条件量基本概念1.2条件量的使用 2. 死锁 1.条件量 1.1条件量基本概念 在许多场合中,程序的执行通常需要满足一定的条件,条件不成熟的时候,任务…...
【NLP解析】多头注意力+掩码机制+位置编码:Transformer三大核心技术详解
目录 多头注意力:让模型化身“多面手” 技术细节:多头注意力如何计算? 实际应用:多头注意力在Transformer中的威力 为什么说多头是“非线性组合”? 实验对比:多头 vs 单头 进阶思考:如何设计更高…...
#关于数据库中的时间存储
✅ 一、是否根据“机器当前时区”得到本地时间再转 UTC? 结论:是的,但仅对 TIMESTAMP 字段生效。 数据库(如 MySQL)在插入 TIMESTAMP 类型数据时: 使用当前会话的时区(默认跟随系统时区&#…...
C# --- yield关键字 和 Lazy Execution
C# --- yield关键字 和 Lazy Execution 延迟执行(Lazy Execution)yield关键字lazy execution与yield的关系LINQ 和 lazy exectuion 延迟执行(Lazy Execution) 延迟执行指操作不会立即计算结果,而是在实际需要数据时才执…...
Qt报错dependent ‘..\..\..\..\..\..\xxxx\QMainWindow‘ 或者 QtCore\QObject not exist
Qt5.15编译项目报错如下: dependent ‘..\..\..\..\..\..\Qt\5.15.2\msvc2019_64\include\QtW...
彻底掌握 XMLHttpRequest(XHR):前端通信的基石
一、XHR 的起源与演进 1.1 技术背景 XHR(XMLHttpRequest)是现代 Web 应用的异步通信基石,最早由微软在 IE5 中通过 ActiveXObject 引入,后来被 Mozilla 推广并成为 W3C 的标准接口。XHR 的出现推动了 AJAX(Asynchrono…...
Bartender 5 for Mac 多功能菜单栏管理
Bartender 5 for Mac 多功能菜单栏管理 一、介绍 Bartender 5,是一款菜单栏管理软件,可以帮助用户隐藏、组织和自定义Mac菜单栏中的图标和通知。使用Bartender 5,用户可以将不常用的图标隐藏起来,使菜单栏保持整洁,并…...
重读《人件》Peopleware -(5)Ⅰ管理人力资源Ⅳ-质量—若时间允许
20世纪的心理学理论认为,人类的性格主要由少数几个基本本能所主导:生存、自尊、繁衍、领地等。这些本能直接嵌入大脑的“固件”中。我们可以在没有强烈情感的情况下理智地考虑这些本能(就像你现在正在做的那样),但当我…...
人事招聘专员简历模板
模板信息 简历范文名称:人事招聘专员简历模板,所属行业:人力资源,模板编号:K8TG60 专业的个人简历模板,逻辑清晰,排版简洁美观,让你的个人简历显得更专业,找到好工作。…...
Java中equals与 “==” 的区别
首先我们要掌握基本数据类型和引用类型的概念 基本数据类型: byte,short,int,long,float,double,boolean,char 基本的八大数据类型都各自封装着包装类,提供了更多的方法,并且都是引言类型 引用类型: 引…...
20250412_代码笔记_CVRProblemDef
文章目录 前言一、get_random_problems 函数分析二、augment_xy_data_by_8_fold 函数分析代码 前言 该笔记分析代码的功能是生成随机VRP问题的数据,包含仓库坐标、节点坐标和节点需求。 对该代码进行改进 20250412-代码改进-拟蒙特卡洛 一、get_random_problems 函…...
《算法笔记》3.4小节——入门模拟->日期处理
日期差值 #include <iostream> using namespace std; int month[13][2]{{0,0},{31,31},{28,29},{31,31},{30,30},{31,31},{30,30},{31,31},{31,31},{30,30},{31,31},{30,30},{31,31} }; bool is_leap(int year){return (year%40&&year%100!0||year%4000); }int m…...
JetBrain/IDEA :Request for Open Source Development License
Request for Open Source Development License...
Java学习手册:Java集合框架详解
Java集合框架(Java Collections Framework)是Java语言中用于存储和操作数据集合的一组接口和类的集合。它提供了丰富的数据结构和算法,帮助开发者高效地管理和操作数据。掌握集合框架的使用是Java开发者的必备技能。 本文将深入探讨Java集合…...
20250412 机器学习ML -(3)数据降维(scikitlearn)
1. 背景 数学小白一枚,看推理过程需要很多时间。好在有大神们源码和DS帮忙,教程里的推理过程才能勉强拼凑一二。 * 留意: 推导过程中X都是向量组表达: shape(feature, sample_n); 和numpy中的默认矩阵正好相反。 2. PCA / KPCA PCAKPCA(Li…...
深入解析系统频率响应:通过MATLAB模拟积分器对信号的稳态响应
稳态响应分析与MATLAB可视化 在控制系统中,线性时不变系统的稳态响应是描述输入与输出之间关系的关键。对于一个频率为 ω i \omega_i ωi 的正弦输入 u ( t ) M i sin ( ω i t φ i ) u(t) M_i \sin(\omega_i t \varphi_i) u(t)Misin(ωitφi)&…...
[16届蓝桥杯 2025 c++省 B] 画展布置
解题思路 理解 ( L ) 的本质 当 ( B ) 按平方值从小到大排序后,相邻项的差非负,此时 ( L ) 等于区间内最大平方值与最小平方值的差(数学公式推导) 滑动窗口找最小差值 遍历所有长度为 ( M ) 的连续…...
从代码学习深度学习 - Bahdanau注意力 PyTorch版
文章目录 1. 前言为什么选择Bahdanau注意力本文目标与预备知识2. Bahdanau注意力机制概述注意力机制简述加性注意力与乘性注意力对比Bahdanau注意力的数学原理与流程图数学原理流程图可视化与直观理解3. 数据准备与预处理数据集简介数据加载与预处理1. 读取数据集2. 预处理文本…...
具身智能零碎知识点(三):深入解析 “1D UNet”:结构、原理与实战
深入解析 “1D UNet”:结构、原理与实战 【深度学习入门】1D UNet详解:结构、原理与实战指南一、1D UNet是什么?二、核心结构与功能1. 整体架构2. 编码器(Encoder)3. 解码器(Decoder)4. 跳跃连…...
基于论文的大模型应用:基于SmartETL的arXiv论文数据接入与预处理(二)
上一篇 文章介绍了arXiv采集处理的任务背景、整体需求,并对数据进行了调研。 本文介绍整体方案设计。 4.整体方案设计 4.1.总体流程 基于上述调研了解的情况,针对工作需求设计处理流程如下: 下载kaggle数据集作为流程输入,出…...
Halo 设置 GitHub - OAuth2 认证指南
在当今数字化时代,用户认证的便捷性和安全性愈发重要。对于使用 Halo 搭建个人博客或网站的开发者而言,引入 GitHub - OAuth2 认证能够极大地提升用户登录体验。今天,我们就来详细探讨一下如何在 Halo 中设置 GitHub - OAuth2 认证。 一、为…...
脑影像分析软件推荐 | AIDA介绍
目录 1.软件界面 2.工具包功能简介 3.软件安装注意事项 1.软件界面 2.工具包功能简介 AIDAmri是一种新型的基于图谱的成像数据分析流程,用于处理小鼠大脑的结构和功能数据,包括解剖MRI、基于扩散张量成像(DTI)的纤维追踪以及基…...
SQL:Relationship(关系)
目录 🔗 什么是 Relationship? 三种基本关系类型(基于实体间的关系): 1. 一对一(One-to-One) 2. 一对多(One-to-Many) 3. 多对多(Many-to-Many…...
【今日三题】压缩字符串(模拟) / chika和蜜柑(topK) / 01背包
⭐️个人主页:小羊 ⭐️所属专栏:每日两三题 很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~ 目录 压缩字符串 (模拟)chika和蜜柑 (topK)01背包 压缩字符串 (模拟) 压缩字符串 class Solution { public:string compressStri…...
PHP多维数组
在 PHP 中,多维数组是数组的数组,允许你存储和处理更复杂的数据结构。多维数组可以有任意数量的维度,但通常我们最常用的是二维数组(数组中的数组)。 首先来介绍一下一维数组, <?php//一维数组 $strAr…...
智能手机功耗测试
随着智能手机发展,用户体验对手机的续航功耗要求越来越高。需要对手机进行功耗测试及分解优化,将手机的性能与功耗平衡。低功耗技术推动了手机的用户体验。手机功耗测试可以采用powermonitor或者NI仪表在功耗版上进行测试与优化。作为一个多功能的智能终端,手机的功耗组成极…...
0x02.Redis 集群的实现原理是什么?
回答重点 Redis 集群(Redis cluster)是通过多个 Redis 实例组成的,每个主节点实例负责存储部分的数据,并且可以有一个或多个从节点作为备份。 具体是采用哈希槽(Hash Slot)机制来分配数据,将整…...
游戏引擎学习第219天
游戏运行时的当前状态 目前的工作基本上就是编程,带着一种预期,那就是一切都会很糟糕,而我们需要一个系统来防止它变得更糟。接下来,我们来看看目前的进展。 简要说明昨天提到的无限调试信息存储系统 昨天我们完成了内存管理的…...
二叉树深度解析:从基础概念到算法实现与应用
一、二叉树的本质定义与核心特性 (一)递归定义与逻辑结构 二叉树是一种 严格有序的树结构,其递归定义为: 空树:不含任何结点的集合,是二叉树的特殊形态。非空二叉树:由以下三部分组成&#x…...
Model Context Protocol(MCP)模型上下文协议
Model Context Protocol(MCP)模型上下文协议 前言一、什么是MCP二、MCP的作用三、MCP与Function call对比四、构建一个简单的MCP DEMO环境准备实现MCP Server运行 ServerMCP Client端配置验证 总结 前言 在Agent时代,将Agent确立为大模型未来…...
代码随想录算法训练营第十六天
LeetCode题目: 530. 二叉搜索树的最小绝对差501. 二叉搜索树中的众数236. 二叉树的最近公共祖先3272. 统计好整数的数目(每日一题) 其他: 今日总结 往期打卡 530. 二叉搜索树的最小绝对差 跳转: 530. 二叉搜索树的最小绝对差 学习: 代码随想录公开讲解 问题: 给你一个二叉搜…...
类似东郊到家的上门按摩预约服务系统小程序APP源码全开源
🔥 为什么上门按摩正在席卷全国? 万亿蓝海市场爆发 2024年中国按摩市场规模突破8000亿,上门服务增速达65% 90后成消费主力,**72%**白领每月至少使用1次上门按摩(数据来源:艾媒咨询) 传统痛点…...
MySQL 5.7.30 Linux 二进制安装包详解及安装指南
MySQL 5.7.30 Linux 安装包详解 mysql-5.7.30-linux-glibc2.12-x86_64.tar 是 MySQL 服务器 5.7.30 版本的 Linux 二进制发行包。 mysql-5.7.30-linux-glibc2.12-x86_64.tar 安装包下载 链接:https://pan.quark.cn/s/2943cd209ca5 包信息 版本: MySQL 5.7.30 平…...
C语言超详细指针知识(二)
在上一篇有关指针的博客中,我们介绍了指针的基础知识,如:内存与地址,解引用操作符,野指针等,今天我们将更加深入的学习指针的其他知识。 1.指针的使用和传址调用 1.1strlen的模拟实现 库函数strlen的功能是…...
Java集合框架详解:核心类、使用场景与最佳实践
文章目录 一、Java集合框架概览二、核心集合类详解1. List接口(有序、可重复)**ArrayList****LinkedList****List对比表** 2. Set接口(无序、唯一)**HashSet****TreeSet****Set对比表** 3. Queue接口(队列)…...
模板引擎语法-标签
模板引擎语法-标签 文章目录 模板引擎语法-标签[toc]一、用于进行判断的{% if-elif-else-endif %}标签二、关于循环对象的{% for-endfor %}标签三、关于自动转义的{% autoescape-endautoescape %}标签四、关于循环对象的{% cycle %}标签五、关于检查值是否变化的{% ifchange %}…...
刘火良FreeRTOS内核实现与应用学习之7——任务延时列表
在《刘火良FreeRTOS内核实现与应用学习之6——多优先级》的基础上:关键是添加了全局变量:xNextTaskUnblockTime ,与延时列表(xDelayedTaskList1、xDelayedTaskList2)来高效率的实现延时。 以前需要在扫描就绪列表中所…...