当前位置: 首页 > news >正文

004 仿muduo实现高性能服务器组件_Buffer模块与Socket模块的实现

​🌈个人主页:Fan_558
🔥 系列专栏:仿muduo
🌹关注我💪🏻带你学更多知识

文章目录

  • 前言
    • Buffer模块
    • Socket模块
  • 小结

前言

这章将会向你介绍仿muduo高性能服务器组件的buffer模块与socket模块的实现

Buffer模块

在这里插入图片描述
设计思想
在这里插入图片描述
实现思想:

1、实现缓冲区得有一块内存空间,采用vector,string字符串的操作遇到’\0’就停止了,网络操作中什么样的数据都有,'\0’可能也有,string大部分的操作都是字符串操作,所以不太行

2、记录当前的读取数据位置与当前的写入数据位置,避免每次写入数据需要重新遍历数组找写入读入位置

3、考虑整体缓冲区空闲空间是否足够 (因为读位置也会向后偏移,前边有可能会有空间) 足够:则将数据(读位置开始)移动到起始位置即可
不够:扩容,从当前写位置开始扩容足够大小 数据一旦写入成功,当前写位置就要向后偏移

4、读取数据/写入数据
当前的读取/写入位置指向哪里,就从哪里开始读取/写入,前提是有数据可读/有空间可写,读取/写入完数据,读偏移/写偏移向后偏移

为了方便查阅
在这里插入图片描述
代码如下:

class Buffer{
private:std::vector<char> _buffer; //使用vector进行内存空间管理uint64_t _reader_idx; //读偏移uint64_t _writer_idx; //写偏移
public:Buffer():_reader_idx(0), _writer_idx(0) ,_buffer(BUFFER_SIZE) {}//获取_buffer起始元素的地址char* begin() {return &*_buffer.begin();}//获取当前写入起始地址(_buffer的空间起始地址,加上写偏移量char* WritePos() { return begin() + _writer_idx; }//获取当前读取起始地址(_buffer的空间起始地址,加上读偏移量char* ReadPos() { return begin() + _reader_idx; }//获取缓冲区末尾空闲空闲大小--写偏移之后的空闲空间uint64_t TailIdleSize() {return _buffer.size() - _writer_idx; }//获取缓冲区起始地址空闲空间大小--读偏移之前的空闲空间uint64_t HeadIdleSize() {return _reader_idx; }//获取可读数据大小uint64_t ReadAbleSize() {return _writer_idx - _reader_idx; }//读取数据后,将读偏移向后移动void MoveReadOffest(uint64_t len) {   //向后移动的大小,必须小于可读数据大小assert(len <= ReadAbleSize());_reader_idx += len; }//写入数据后,将写偏移向后移动void MoveWriteOffest(uint64_t len) { _writer_idx += len; }//确保可写空间足够(整体空闲空间够了就移动数据,否则就扩容)void EnsureWriteSpace(uint64_t len){//如果末尾空闲空间大小足够,直接返回if(len < TailIdleSize()) return;//如果不够,判断加上起始位置的空闲空间大小是否足够,够了就将可读数据移动到起始位置else if(len <= HeadIdleSize() + TailIdleSize()) {uint64_t sz = ReadAbleSize();   //可读数据大小_reader_idx = 0;    //更新读偏移_writer_idx = sz;   //更新写偏移return;}//总体空间不够,则需要扩容,不移动数据,直接给写偏移之后扩容足够空间即可else _buffer.resize(_writer_idx + len);}//写入数据void Write(const void* data, uint64_t len){//保证是否有足够空间EnsureWriteSpace(len);const char* d = (const char* )data;//拷贝数据到buffer当中std::copy(d, d + len, WritePos());}void WriteAndPush(const void* data, uint64_t len){Write(data, len);MoveWriteOffest(len);}//写入一个字符串void WriteString(const std::string &data){Write(data.c_str(), data.size());}//向buffer中写入一个字符串并向后移动writevoid WriteStringAndPush(const std::string &data){WriteString(data);MoveWriteOffest(data.size());}//把一个buffer类型的数据写入void WriteBuffer(Buffer &data){Write(data.ReadPos(), data.ReadAbleSize());}//向buffer中写入一个并向后移动writevoid WriteBufferAndPush(Buffer &data){WriteBuffer(data);MoveWriteOffest(data.ReadAbleSize());}//读取数据void Read(void* buf, uint64_t len){assert(len <= ReadAbleSize());//保持参数类型一致std::copy(ReadPos(), ReadPos() + len, (char*)buf);}void ReadAndPop(void* buf, uint64_t len){Read(buf, len);MoveReadOffest(len);}//把读取的数据当作一个string返回  std::string ReadAsString (uint64_t len){assert(len <= ReadAbleSize());std::string str;str.resize(len);//从缓冲区中读取长度为len的数据,并将其存储到字符串str的内存地址开始处的位置Read(&str[0], len);return str;}//读取一个string并向后移动(确保下一次不会重复读取)std::string ReadAsStringAndPop(uint64_t len){assert(len <= ReadAbleSize());std::string str = ReadAsString(len);MoveReadOffest(len);return str;}/*由于后面我们的高并发服务器会支持应用层协议的HTTP,而在HTTP协议中通常就是读取一行的数据,因为请求行和请求报头以及响应行和响应报头都是以\r\n作为分隔符的,都是一行行的数据所以我们的缓冲区也提供一个查找换行字符的位置*/char* FindCRLF(){//在可读数据范围内查找第一个出现的换行符的位置char* res = (char*)memchr(ReadPos(), '\n', ReadAbleSize());return res;}//获取一行数据std::string Getline(){char* pos = FindCRLF();if(pos == nullptr) return "";/*将换行符\n前的数据读出,+1:包括换行符(不然的话下一次再查找,换行符就在开头) */return ReadAsString(pos - ReadPos() + 1); }//读出一行数据后,将读偏移向后移std::string GetLineAndPop(){std::string str = Getline();MoveReadOffest(str.size());return str;}//清空缓冲区void clear(){//只需要将偏移量归零_writer_idx =  _reader_idx = 0;}
};

Socket模块

设计思想:
在这里插入图片描述
在该模块当中除了对socket套接字原有的操作进行封装,还提供了直接创建服务端和客户端连接的接口
为了方便查阅
在这里插入图片描述

代码如下

#define MAX_LISTEN 1024
class Socket{private:int _sockfd;public:Socket():_sockfd(-1){}Socket(int fd):_sockfd(fd){}//关闭套接字~Socket() { Close(); }int Fd(){return _sockfd;}//创建套接字bool Create(){//int socket(int domain, int type, int protocol)  AF_INET: 表示使用ipv4地址族 SOCK_STREM: 表示创建面向连接的套接字类(TCP) IPPROTO_TCP: 表示使用TCP协议_sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if(_sockfd < 0){ERR_LOG("CREATE SOCKET FAILEDQ!");return false;}return true;}//绑定地址信息bool Bind(const std::string &ip, uint16_t port){struct sockaddr_in addr;addr.sin_family = AF_INET;      //ipv4地址域类型addr.sin_port = htons(port);    //将端口号通过主机转网络字节序addr.sin_addr.s_addr = inet_addr(ip.c_str());   //将IP地址转化为网络字节序的32位ipv4地址socklen_t len = sizeof(struct sockaddr_in);//int bind(int socket, const struct sockaddr *addr. socklen_t addrlen);int ret = bind(_sockfd, (struct sockaddr*)&addr, len);if(ret < 0){ERR_LOG("BIND ADDRESS FAILEDQ!");return false;}return true;}//开始监听bool Listen(int backlog = MAX_LISTEN){int ret = listen(_sockfd, backlog);if(ret < 0){ERR_LOG("SOCKET LISTEN FAILED!");return false;}return true;}//向服务器发起连接(传入服务器的ip和端口信息)bool Connect(const std::string &ip, uint16_t port){//int connect(int sockfd, const struct sockaddr* addr, socklen_t addrlen);struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(port);addr.sin_addr.s_addr = inet_addr(ip.c_str());socklen_t len = sizeof(struct sockaddr_in);int ret = connect(_sockfd, (struct sockaddr*)&addr, len);if(ret < 0){ERR_LOG("CONNECT SERVER FAILEDQ!");return false;}return true;}//监听有新连接后,获取新连接(返回一个文件描述符)int Accept()    {int newfd = accept(_sockfd, nullptr, nullptr);if(newfd < 0){ERR_LOG("SOCKET ACCEPT FAILED!");return -1;}return newfd;}//接收数据(ssize_t为有符号整数,size_t无符号整数,默认0为阻塞操作)ssize_t Recv(void* buf, size_t len, int flag = 0){ssize_t ret = recv(_sockfd, buf, len, flag);if(ret <= 0){//EAGAIN 当前socket的接收缓冲区中没有数据了,在非阻塞的情况下才会有这个错误//EINTR 当前socket的阻塞等待被信号打断了if(errno == EAGAIN || errno == EINTR)return 0;else{ERR_LOG("SOCKET RECV FAILED");return -1;}}return ret; //返回实际接收的数据长度}ssize_t NonBlockRecv(void* buf, size_t len){return Recv(buf, len, MSG_DONTWAIT); // MSG_DONTWAIT 表示当前接收为非阻塞}//发送数据ssize_t Send(const void* buf, size_t len, int flag = 0){ssize_t ret = send(_sockfd, buf, len, flag);if(ret < 0){if(errno == EAGAIN || errno == EINTR){return 0;}ERR_LOG("SOCKET RECV FAILED");return -1;}return ret; //返回实际发送的数据长度}ssize_t NonBlockSend(void* buf, size_t len){Send(buf, len, MSG_DONTWAIT); // MSG_DONTWAIT 表示当前接收为非阻塞}//关闭套接字void Close(){if(_sockfd != -1){close(_sockfd);_sockfd = -1;}}//创建一个服务端连接bool CreateServer(uint16_t port, const std::string &ip = "0.0.0.0", bool block_flag = false){if(Create()==false) return false;//是否启动非阻塞if(block_flag) NonBlock();if(Bind(ip, port) == false) return false;if(Listen() == false) return false;ReuseAddress();return true;}//创建一个客户端连接bool CreateClient(uint16_t port, const std::string &ip){if(Create() == false) return false;if(Connect(ip, port) == false) return false;return true;}//设置套接字选项---开启地址端口重用void ReuseAddress(){// int setsockopt(int fd, int leve, int optname, void *val, int vallen)int val = 1;setsockopt(_sockfd, SOL_SOCKET, SO_REUSEADDR, (void*)&val, sizeof(int));val = 1;setsockopt(_sockfd, SOL_SOCKET, SO_REUSEPORT, (void*)&val, sizeof(int));}//设置套接字阻塞属性---设置为非阻塞void NonBlock(){//int fcntl(int fd, int cmd, ... /* arg */ );int flag = fcntl(_sockfd, F_GETFL, 0);fcntl(_sockfd, F_SETFL, flag | O_NONBLOCK);}
};

小结

今日的项目分享就到这里啦,下一篇将会向你介绍Channel与Poller模块

相关文章:

004 仿muduo实现高性能服务器组件_Buffer模块与Socket模块的实现

​&#x1f308;个人主页&#xff1a;Fan_558 &#x1f525; 系列专栏&#xff1a;仿muduo &#x1f339;关注我&#x1f4aa;&#x1f3fb;带你学更多知识 文章目录 前言Buffer模块Socket模块 小结 前言 这章将会向你介绍仿muduo高性能服务器组件的buffer模块与socket模块的实…...

研发效能DevOps: Ubuntu 部署 JFrog 制品库

目录 一、实验 1.环境 2.Ubuntu 部署 JFrog 制品库 3.Ubuntu 部署 postgresql数据库 4.Ubuntu 部署 Xray 5. 使用JFrog 增删项目 二、问题 1.Ubuntu 如何通过apt方式部署 JFrog 制品库 2.Ubuntu 如何通过docker方式部署 JFrog 制品库 3.安装jdk报错 4.安装JFrog Ar…...

hadoop学习笔记

hadoop集群搭建 hadoop摘要 Hadoop 是一个开源的分布式存储和计算框架&#xff0c;旨在处理大规模数据集并提供高可靠性、高性能的数据处理能力。它主要包括以下几个核心组件&#xff1a; Hadoop 分布式文件系统&#xff08;HDFS&#xff09;&#xff1a;HDFS 是 Hadoop 的分布…...

使用dockerfile快速构建一个带ssh的docker镜像

不多说先给代码 FROM ubuntu:22.04 # 基础镜像 可替换为其他镜像 USER root RUN echo root:root |chpasswd RUN apt-get update -y \&& apt-get install -y git wget curl RUN apt-get install -y openssh-server vim && apt clean \&& rm -rf /tmp/…...

linux部署运维1——centos7.9离线安装部署涛思taos2.6时序数据库TDengine

在实际项目开发过程中&#xff0c;并非一直都使用关系型数据库&#xff0c;对于工业互联网类型的项目来说&#xff0c;时序型数据库也是很重要的一种&#xff0c;因此掌握时序数据库的安装配置也是必要的技能&#xff0c;不过对于有关系型数据库使用的开发工作者来说&#xff0…...

Linux shell编程学习笔记51: cat /proc/cpuinfo:查看CPU详细信息

0 前言 2024年的网络安全检查又开始了&#xff0c;对于使用基于Linux的国产电脑&#xff0c;我们可以编写一个脚本来收集系统的有关信息。对于中央处理器CPU比如&#xff0c;我们可以使用cat /proc/cpuinfo命令来收集中央处理器CPU的信息。 1. /proc/cpuinfo 保存了系统的cpu…...

Ps:调整画笔工具

调整画笔工具 Adjustment Brush Tool可以将选区、创建蒙版和应用调整的传统工作流程合并为一个步骤&#xff0c;简化了对图像进行非破坏性局部调整的操作。 快捷键&#xff1a;B 调整画笔工具是 Photoshop 2024 年 5 月版&#xff08;25.9 版&#xff09;新增的工具。 ◆ ◆ …...

香橙派 AIpro上手体验并验证车道线识别算法

香橙派 AIpro上手体验并验证车道线识别算法 1.前言 最近入手了一块香橙派AIpro&#xff0c;体验了一下&#xff0c;感觉还不错&#xff0c;在这里分享给大家&#xff0c;大家可以做个参考。 2.开箱 整套产品包含一块主板、一个电源插头和一条双端Type-C的数据线&#xff0c;…...

为啥装了erlang,还报错erl: command not found?

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 问题背景&#xff1a; 在一台不通外网的服务器上装rabbitmq&#xff0c;然后在启动的时候&#xff0c;遇到了报错 “/usr/lib/…...

容器技术基础理论与常用命令:必知必会,效率翻倍!

如何利用容器技术提升你的工作效率&#xff1f;掌握基础理论和常用命令是必不可少的&#xff0c;本文将为你全面介绍容器技术&#xff0c;并教你必知必会的技能&#xff0c;让你工作、学习效率翻倍&#xff0c;对于网络安全工作者也是必不可少的技能&#xff01; 0. 引言 学习…...

ChatGPT Edu版本来啦:支持GPT-4o、自定义GPT、数据分析等

5月31日&#xff0c;OpenAI在官网宣布&#xff0c;推出ChatGPT Edu版本。 据悉&#xff0c;这是一个专门为大学校园提供的ChatGTP&#xff0c;支持GPT-4o、网络搜索、自定义GPT、数据分析、代码生成等功能&#xff0c;可以极大提升学生、老师的学习质量和教学效率。 目前&…...

Spark RDD案例

Apache Spark中的RDD&#xff08;Resilient Distributed Dataset&#xff09;是一个不可变、分布式对象集合&#xff0c;它允许用户在大型集群上执行并行操作。虽然RDD在Spark的早期版本中非常核心&#xff0c;但随着DataFrame和Dataset的引入&#xff0c;RDD的使用在某些场景下…...

【线性表 - 数组和矩阵】

数组是一种连续存储线性结构&#xff0c;元素类型相同&#xff0c;大小相等&#xff0c;数组是多维的&#xff0c;通过使用整型索引值来访问他们的元素&#xff0c;数组尺寸不能改变。 知识点数组与矩阵相关题目 # 知识点 数组的优点: 存取速度快 数组的缺点: 事先必须知道…...

Springboot 开发 -- 跨域问题技术详解

一、跨域的概念 跨域访问问题指的是在客户端浏览器中&#xff0c;由于安全策略的限制&#xff0c;不允许从一个源&#xff08;域名、协议、端口&#xff09;直接访问另一个源的资源。当浏览器发起一个跨域请求时&#xff0c;会被浏览器拦截&#xff0c;并阻止数据的传输。 这…...

【Qt】之【项目】整理可参考学习的git项目链接(持续更新)

Tcp 通信相关 IM即时通讯设计 高并发聊天服务&#xff1a;服务器 qt客户端&#xff08;附源码&#xff09; - DeRoy - 博客园 未使用protobuf通讯协议格式 github&#xff1a;GitHub - ADeRoy/chat_room: IM即时通讯设计 高并发聊天服务&#xff1a;服务器 qt客户端 QT编…...

2024年5月个人工作生活总结

本文为 2024年5月工作生活总结。 研发编码 golang 多个defer函数执行顺序 golang 函数中如有多个defer&#xff0c;倒序执行。示例代码&#xff1a; func foo() {defer func() {fmt.Println("111")}()defer func() {fmt.Println("2222")}()defer func()…...

Kafka Java API

1、增加依赖 <dependency><groupId>org.apache.kafka</groupId><artifactId>kafka-clients</artifactId><version>1.0.0</version> </dependency>2、三个案例 案例1&#xff1a;生产数据 import org.apache.kafka.clients.p…...

pushd: not found

解决方法&#xff1a; pushd 比 cd 命令更高效的切换命令&#xff0c;非默认&#xff0c;可在脚本开头添加&#xff1a; #! /bin/bash ubuntu 编译时出现/bin/sh: 1: pushd: not found的问题-CSDN博客...

【第十三节】C++控制台版本坦克大战小游戏

目录 一、游戏简介 1.1 游戏概述 1.2 知识点应用 1.3 实现功能 1.4 开发环境 二、项目设计 2.1 类的设计 2.2 各类功能 三、程序运行截图 3.1 游戏主菜单 3.2 游戏进行中 3.3 双人作战 3.4 编辑地图 一、游戏简介 1.1 游戏概述 本项目是一款基于C语言开发的控制台…...

酷得单片机方案 2.4G儿童遥控漂移车

电子方案开发定制&#xff0c;我们是专业的 东莞酷得智能单片机方案之2.4G遥控玩具童车具有以下比较有特色的特点&#xff1a; 1、内置充电电池&#xff1a;这款小车配备了可充电的电池&#xff0c;无需频繁更换电池&#xff0c;既环保又方便。充电方式可能为USB充电或者专用…...

【为什么 Google Chrome 打开网页有时极慢?尤其是国内网站,如知网等】

要通过知网搜一点资料&#xff0c;发现怎么都打不开。而且B站&#xff0c;知乎这些速度也变慢了&#xff01;已经检查过确定不是网络的问题。 清空了记录&#xff0c;清空了已接受Cookie&#xff0c;清空了缓存内容……没用&#xff01;&#xff01;&#xff01; 不断搜索&am…...

FastAPI - 数据库操作5

先安装mysql驱动程序 pipenv install pymysql安装数据库ORM库SQLAlchemy pipenv install SQLAlchemy修改文件main.py文件内容 设置数据库连接 # -*- coding:utf-8 –*- from fastapi import FastAPIfrom sqlalchemy import create_engineHOST 192.168.123.228 PORT 3306 …...

HTML静态网页成品作业(HTML+CSS)—— 冶金工程专业展望与介绍介绍网页(2个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有2个页面。 二、作品演示 三、代…...

Flutter基础 -- Dart 语言 -- 注释函数表达式

目录 1. 注释 1.1 单行注释 1.2 多行注释 1.3 文档注释 2. 函数 2.1 定义 2.2 可选参数 2.3 可选参数 默认值 2.4 命名参数 默认值 2.5 函数内定义 2.6 Funcation 返回函数对象 2.7 匿名函数 2.8 作用域 3. 操作符 3.1 操作符表 3.2 算术操作符 3.3 相等相关的…...

“仿RabbitMQ实现消息队列”---整体架构与模块说明

顾得泉&#xff1a;个人主页 个人专栏&#xff1a;《Linux操作系统》 《C从入门到精通》 《LeedCode刷题》 键盘敲烂&#xff0c;年薪百万&#xff01; 一、概念性框架理解 我们主要实现的内容&#xff1a; 1.Broker服务器&#xff1a;消息队列服务器&#xff08;服务端&…...

springboot如何快速接入minio对象存储

1.在项目中添加 Minio 的依赖&#xff0c;在使用 Minio 之前&#xff0c;需要在项目中添加 Minio 的依赖。可以在 Maven 的 pom.xml 文件中添加以下依赖&#xff1a; <dependency><groupId>io.minio</groupId><artifactId>minio</artifactId>&l…...

第六届“智能设计+运维”国产工业软件研讨会暨2024年天洑软件用户大会圆满召开

2024年5月23-24日&#xff0c;第六届“智能设计运维”国产工业软件研讨会暨2024年天洑软件用户大会在南京举办。来自国产工业软件研发企业、制造业企业、高校、科研院所的业内大咖&#xff0c;能源动力、船舶海事、车辆运载、航空航天、新能源汽车、动力电池、消费电子、石油石…...

05.k8s弹性伸缩

5.k8s弹性伸缩 k8s弹性伸缩,需要附加插件heapster监控 弹性伸缩&#xff1a;随着业务访问量的大小&#xff0c;k8s系统中的pod比较弹性&#xff0c;会自动增加或者减少pod数量&#xff1b; 5.1 安装heapster监控 1:上传并导入镜像,打标签 ls *.tar.gz for n in ls *.tar.gz…...

【数据结构】详解二叉树

文章目录 1.树的结构及概念1.1树的概念1.2树的相关结构概念1.3树的表示1.4树在实际中的应用 2.二叉树的结构及概念2.1二叉树的概念2.2特殊的二叉树2.2.1满二叉树2.2.2完全二叉树 2.3 二叉树的性质2.4二叉树的存储结构2.4.1顺序结构2.4.2链表结构 1.树的结构及概念 1.1树的概念…...

MapDB:轻量级、高性能的Java嵌入式数据库引擎

MapDB&#xff1a;轻量级、高性能的Java嵌入式数据库引擎 在今天的软件开发中&#xff0c;嵌入式数据库因其轻便、高效和易于集成而备受欢迎。对于Java开发者来说&#xff0c;MapDB无疑是一个值得关注的选项。MapDB是一个纯Java编写的嵌入式数据库引擎&#xff0c;它提供了高性…...

Rye: 一个革新的Python包管理工具

文章目录 Rye: 一个革新的Python包管理工具Rye的诞生背景Rye的核心特性Rye的安装与使用Rye的优势与挑战Rye的未来展望结语 Rye: 一个革新的Python包管理工具 在Python生态系统中&#xff0c;包管理一直是一个复杂且令人头疼的问题。随着Python社区的不断发展&#xff0c;出现了…...

如何在C#代码中判断当前C#的版本和dotnet版本

代码如下&#xff1a; using System.Reflection; using System.Runtime.InteropServices;var csharpVersion typeof(string).Assembly.GetCustomAttributes(typeof(AssemblyFileVersionAttribute), false).OfType<AssemblyFileVersionAttribute>().FirstOrDefault()?.…...

Linux 36.3@Jetson Orin Nano之系统安装

Linux 36.3Jetson Orin Nano之系统安装 1. 源由2. 命令行烧录Step 1&#xff1a;下载Linux 36.3安装程序Step 2&#xff1a;下载Linux 36.3根文件系统Step 3&#xff1a;解压Linux 36.3安装程序Step 4&#xff1a;解压Linux 36.3根文件系统Step 5&#xff1a;安装应用程序Step …...

案例实践 | 基于长安链的首钢供应链金融科技服务平台

案例名称-首钢供应链金融科技服务平台 ■ 建设单位 首惠产业金融服务集团有限公司 ■ 用户群体 核心企业、资金方&#xff08;多为银行&#xff09;等合作方 ■ 应用成效 三大业务场景&#xff0c;共计关联29个业务节点&#xff0c;覆盖京票项目全部关键业务 案例背景…...

Vue3实战笔记(55)—Vue3.4新特性揭秘:defineModel重塑v-model,拥抱高效双向数据流!

文章目录 前言defineModel() 基本用法总结 前言 v-model 可以在组件上使用以实现双向绑定。 从 Vue 3.4 开始&#xff0c;推荐的实现方式是使用 defineModel() 宏 defineModel() 基本用法 定义defineModel()&#xff1a; <!-- Child.vue --> <script setup> con…...

C++ | Leetcode C++题解之第123题买卖股票的最佳时机III

题目&#xff1a; 题解&#xff1a; class Solution { public:int maxProfit(vector<int>& prices) {int n prices.size();int buy1 -prices[0], sell1 0;int buy2 -prices[0], sell2 0;for (int i 1; i < n; i) {buy1 max(buy1, -prices[i]);sell1 max(…...

微信小程序中Button组件的属性值和用法详解

在微信小程序开发中&#xff0c;Button组件是非常常用的UI组件之一&#xff0c;它可以让用户进行交互操作&#xff0c;比如提交表单、跳转页面等。了解Button组件的属性值和用法对于开发者来说至关重要。 1. Button组件简介 简要介绍Button组件在小程序中的作用和重要性&…...

等保测评 | 等保测评简介及流程具体是什么?

等保测评是指对信息系统进行安全性评估和测试&#xff0c;以确保其符合国家相关等级保护要求。在当前信息时代&#xff0c;各类机构和企业面临着日益严峻的网络安全风险&#xff0c;等保测评成为了保障信息系统安全的重要手段之一。本文将介绍等保测评的基本概念、流程和重要性…...

CompassArena 司南大模型测评--代码编写

测试角度 要说测试模型&#xff0c;对咱们程序员来说&#xff0c;那自然是写代码的能力强不强比较重要了。那么下面我们以 leetcode 中的一道表面上是困难题的题目来考考各家大模型&#xff0c;看看哪个才应该是咱们日常写程序的帮手。 部分模型回答 问题部分如下截图&#…...

叉积和法向量学习笔记

目录 叉积用的内积 相似点 给定平面上的两个向量 A 和 B&#xff0c;叉积和法向量相等吗 理解这点的关键&#xff1a; 结论&#xff1a; 叉积判断平面内两个向量是否相交 叉积&#xff08;Cross Product&#xff09;和法向量&#xff08;Normal Vector&#xff09;确实有…...

YZW900规格书

title: “深圳市沃进科技有限公司” 深圳市沃进科技有限公司 TOP视图 特性 异地组网&#xff0c;远程访问有线/无线备份单模双卡备份5G转有线&#xff0c;5G转WIFI2.4G5.8G双频WIFI三网口&#xff0c;WAN/LAN可切换软硬件看门狗智能防掉线云平台、客户端远程管理安装支架安装铝…...

9岁学生学什么编程好一些:探索编程启蒙的奥秘

9岁学生学什么编程好一些&#xff1a;探索编程启蒙的奥秘 在数字时代&#xff0c;编程已逐渐成为一项基本技能。对于9岁的学生来说&#xff0c;选择适合的编程课程或平台&#xff0c;对于培养逻辑思维、创新思维以及解决问题的能力至关重要。那么&#xff0c;9岁学生学什么编程…...

Java反射实战指南:反射机制的终极指南

1. 反射机制简介 在Java中&#xff0c;反射机制提供了一种强大的工具&#xff0c;用于在运行时检查类、接口、字段和方法。但它的重要性不止于此&#xff0c;它允许程序动态加载、探索和使用编译时完全未知的代码。这种能力是Java语言支持的一种“动态”特性&#xff0c;使得J…...

高效训练超越LoRA,北航发布MoRA

什么&#xff01;LoRA我都没有学懂&#xff0c;又出现了MoRA&#xff1f;&#xff1f;&#xff1f; LoRA作为当下最火热的大语言模型参数高效微调技术&#xff0c;正在以前所未有的速度迭代更新。从最初的LoRA到陆续推出的LoRA、DoRA、AsyLoRA等变体&#xff0c;LoRA家族可谓是…...

【Spring】Spring之依赖注入源码解析(上)

目录 Spring中到底有几种依赖注入的方式&#xff1f; 手动注入 自动注入 XML的autowire自动注入 Autowired注解的自动注入 寻找注入点 桥接方法 注入点进行注入 字段注入 Set方法注入 Spring中到底有几种依赖注入的方式&#xff1f; 首先分两种&#xff1a; 手动注…...

HBase 常用 shell 操作

下面给大家介绍一些HBase 常用 shell 操作&#xff0c;各位看官看好了啦&#xff0c;我要献丑了。 进入 HBase 客户端命令操作界面 $ bin/hbase shell查看帮助命令 > help查看当前数据库中有哪些表 > list创建一张表 创建 user 表&#xff0c;包含 info、data 两个列…...

【区分vue2和vue3下的element UI InputNumber 计数器组件,分别详细介绍属性,事件,方法如何使用,并举例】

在 Vue 2 中&#xff0c;Element UI 提供了 el-input-number 组件作为计数器组件&#xff0c;用于处理数字输入。而在 Vue 3 中&#xff0c;Element Plus 同样提供了类似的组件&#xff0c;但可能有一些属性、事件或方法的细微差异。下面我将分别介绍 Vue 2 的 Element UI 和 V…...

科普健康短视频:成都鼎茂宏升文化传媒公司

科普健康短视频&#xff1a;引领健康知识新潮流 在数字化时代的浪潮中&#xff0c;短视频以其短小精悍、直观易懂的特点&#xff0c;迅速成为大众获取信息的重要渠道。其中&#xff0c;科普健康短视频更是凭借其科学、权威、实用的内容&#xff0c;吸引了大量关注健康的观众。…...

Amis源码构建 sdk版本

建议在linux环境下构建&#xff08;mac环境下也可以&#xff09;&#xff0c;需要用到sh脚本&#xff08;amis/build.sh&#xff09;。 Js sdk打包是基于fis进行编译打包的&#xff0c;具体可见fis-conf.js&#xff1a; amis-master源码下载:https://github.com/baidu/amis g…...

【MySQL数据库】:MySQL复合查询

目录 基本查询回顾 多表查询 自连接 子查询 单行子查询 多行子查询 多列子查询 在from子句中使用子查询 合并查询 前面我们讲解的mysql表的查询都是对一张表进行查询&#xff0c;在实际开发中这远远不够。 基本查询回顾 【MySQL数据库】&#xff1a;MySQL基本查…...