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

微服务架构中的多进程通信--内存池、共享内存、socket

目录

1 引言

2 整体架构简介

3 疑问

3.1 我们的共享内存消息机制是用的posix还是system V

3.2 rmmt中,不同线程之间的比如访问同一个内存,用的什么锁控制的

3.3 疑问:假如一个进程发送给了另外两个进程,然后另外两个进程都同时操作这块内存怎么办

3.4 AITS的几个模块之间的关系

3.5 rmmt的socket之间有同步吗

4 代码大体流程


1 引言

    整理一下公司的一个微服务架构的代码整体流程,不牵扯到完整代码,不算泄密,纯粹是当做自己个人的代码阅读简单笔记,用于帮助自己理解和记忆。

2 整体架构简介

 

 

1:首先wmits vas vss三个他们是有socket通信的,然后wmits既做服务端也做客户端,然后vas和vss只做服务端,然后vas和vss之间是不通信的,都是由wmits去发起,比如wmits发起了一个任务,然后他就会通知vas,然后让vas去开始读取视频,读完视频之后要把视频帧的指针等一些信息发会给wmits,然后wmits再把这个指针发给vss,然后vss去做算法处理,然后vss处理完之后再把结果会发给wmits。

2:vas  vss wmits都需要跟rmmt那个服务做交互,比如vas要申请一帧数据的共享内存,然后他就要跟rmmt交互申请内存,并且rmmt这时候也要增加一个共享内存指针的引用计数,然后vas要把指针发给wmits,这时候也要通知rmmt让rmmt知道vas把指针发送给了wmtis,然后wmits接收到了指针之后也要通知下rmmt让rmmt知道。

3 疑问

3.1 我们的共享内存消息机制是用的posix还是system V

答:用的posix的,以前应该是记错了,记成system V了。

其实不是自己记错了,aits中用的的就是shm_open然后mmap的方式,只不过你当初让大模型给你写一个共享内存通信的,结果大模型给你写了一个open一个文件然后mmap的方式,这个open文件+mmap既不属于posix也不属于system V。

3.2 rmmt中,不同线程之间的比如访问同一个内存,用的什么锁控制的

答:rmmt中,当其他进程也就是客户端发送命令过来的时候,在do_rtm_cmd里面处理,无非就是申请内存。释放内存、发送内存、接受内存,这四个命令rmmt在处理的时候都要加锁控制,

比如申请内存,加锁,是为了不让不同的进程申请同一块内存,加锁后,即便有多个进程申请内存,那么申请到的不是同一块内存,

比如释放、发送、接收,这个rmmt主要就是管理一些索引,这里也要加锁,比如释放内存,如果不加锁,那么可能多个线程同时减少同一内存节点的引用计数也会出错,发送也是,多个线程要是发送的都是同一个指针,那么引用计数也是会出错。

3.3 疑问:假如一个进程发送给了另外两个进程,然后另外两个进程都同时操作这块内存怎么办

答:只要不是同时写就行,同时读是没问题的,然后我们的业务决定了不会有两个进程同时写一块内存的,因为只有vas会写内存,其他模块都是读内存。所以即便是有多个进程在读内存也没什么问题。

3.4 AITS的几个模块之间的关系

vas和vss不直接通信,都是通过wmits进行管理的,

平台下发任务也是跟wmits进行对接,然后wmits会让vas接入视频,然后数据返回给wmits,然后wmits再跟rmmt说我要发送数据了,然后wmits把数据发给vss进行处理,我们的那些比如拥堵事故的逻辑也在vss里面,

我们aits比较常用的就是vas  vss wmits  rmmt然后就是视频预览和图片预览。

3.5 rmmt的socket之间有同步吗

答:没有,rmmt因为会把进程的id发过去,不需要

4 代码大体流程

首先/data/chw/AITS/src/rmmt/rmmt_daemon/rmmt_win_daemon.cpp里面的main函数,

就是create,然后mmap

int SharedMemory::create(const char* name, size_t size)
{if (hdl) return 1;int fd = shm_open(name, O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO);if (fd == -1) {return -1;}hdl = fd;  if (ftruncate(fd, size) < 0) {return -2;}mapsize = size;basep = mmap(NULL, size, PROT_WRITE, MAP_SHARED, fd, 0);if (basep == MAP_FAILED) {basep = 0;return -3;}return 0;
}

g_mpol.init_rst(shm_sz);

然后这里应该是相当于初始化内存池的大小。

void rmt_start_server(const std::string& suri, uint32_t concurrent_tasks)
{auto xf = [](int af, int _sock) {/*每一个process的librmmt_sdk初始化连入,维护一个TCP|Unix-sock长连接。初始接收pid(process-id),进行process-local数据结构初始化然后一个for循环,不断接收命令请求并响应。通用命令协议格式:(二进制)流(整个命令体)[ u64(命令ctx), i32(命令类型id), ...(剩余部分为命令数据内容,不同命令类别不一样) ]*/sockwrapper sw(_sock);if (af == AF_INET || af == AF_INET6) {sk_set_tcpnodelay(sw, true);}int pid = 0;//process本地mem-node引用计数。用来保存本process内有生存期的mem-node信息。//核心功能是为了让本服务检测到process退出时,假如有部分mem-node未来得及调用析构(命令2),则可以通过此结构进行清理。map_t<uint64_t, int> lmemRef;atomic_int pending = {};try {cxx_recv(sw, pid);assert(pid > 0);cxx_send_string(sw, g_res);cxx_send(sw, g_memsize_kb);//step1: add new pid to Map{CFutex::scoped_lock wlg(gmt_memMap);g_pids.insert(pid);}//step2: loop for new commandsfor (;;) {std::string cmddata = cxx_recv_string(sw);assert(cmddata.size() >= 12);pending.fetch_add(1);{uint64_t ucmdctx = *(uint64_t*)cmddata.data();int cmdid = *(int*)(cmddata.data() + 8);shared_ptr<MsgSendInfo> msi = make_shared<MsgSendInfo>(256, sw);msi->bb_out.bset(4);msi->bb_out << ucmdctx;CharSeqReader chrd(cmddata.data() + 12, cmddata.size() - 12);//针对不同命令的处理过程do_rtm_cmd(pid, lmemRef, ucmdctx, cmdid, chrd, msi->bb_out);g_taskQue.push([msi, &pending](){   //pipeline异步发送,提升处理效率byte_buffer& bb = msi->bb_out;int dsize = (int)bb.data_size();*(int*)bb.raw_data() = dsize;send_all(msi->sock, bb.raw_data(), dsize + 4);pending.fetch_sub(1);});}//*/}}catch (...) {}//wait for all pending tasks to be completed!while (pending > 0) {Sleep(5);}vector<int64_t> rc;ostringstream oss;oss << "[" << pid << "]#process quit! mn=[";{//清理本process内来不及释放的内存(如果有的话)CFutex::scoped_lock _lc(gmt_memMap);g_pids.erase(pid);pmem_clean2(pid, lmemRef, rc);}//释放清理掉的内存node//free interprocess memnodesfor (int64_t m : rc) {shm_free_memnode(m);oss << m << ",";}oss << "]";LOG_INFO(MSG_LOG,"{}", oss.str());};///lambda 'xf' definition END.//异步线程池实现g_taskQue.set_capacity(concurrent_tasks + 4);for (uint32_t i = 0; i < concurrent_tasks; i++) {std::thread([]() {for (function<void()> t;;) {g_taskQue.pop(t);t();}}).detach();}//启动socket-serverstart_sock_raw_serverT(suri, xf, true);
}
void start_sock_raw_serverT(std::string server_uri, std::function<void(int af,int sock)>&& cb,bool bLoopHere)
{using namespace std;//step1> analysis urisockaddr_ex bindaddr;{size_t p1 = server_uri.find("://");if (p1 == string::npos)throw GeneralException(-1, "invalid server uri! not contain ://");server_uri[p1] = 0;if (strcmp(server_uri.data(), "ip") == 0) {size_t p2 = server_uri.find(':', p1 + 3);server_uri[p2] = 0;int port = 0;   sscanf(&server_uri[p2 + 1], "%d", &port);char* ip = &server_uri[p1 + 3];if (sk_tcp_addr(bindaddr, ip, port)) {throw GeneralException(-1).format_errmsg("gen ip address failed! ip=%s,port=%d", ip, port);}}else if (strcmp(server_uri.data(), "un") == 0) {sk_unix_addr(bindaddr, &server_uri[p1 + 3]);}}if (bindaddr.sa_family == 0)throw GeneralException(-1, string("unrecognized protocol! uri=") + server_uri);SOCKET server = sk_create(bindaddr.sa_family, SOCK_STREAM, 0);if (server == INVALID_SOCKET) throw GeneralException(-2, system_errmsg());if (bindaddr.sa_family == AF_INET || bindaddr.sa_family == AF_INET6) {int on = 1;setsockopt(server, SOL_SOCKET, SO_REUSEADDR, (char*)&on, 4);}if (::bind(server, &bindaddr, bindaddr.addr_len())) {GeneralException e(-3, system_errmsg());sk_close(server);throw e;}if (listen(server, SOMAXCONN)) {GeneralException e(-4, system_errmsg());sk_close(server);throw e;}auto loop = [cb](SOCKET sock) {for (sockaddr_ex addr;;) {SOCKET s = sk_accept2(sock,addr);if (s == INVALID_SOCKET) {perror("accept");break;}std::thread(cb, (int)addr.sa_family, (int)s).detach();}perror("socket-accept!");sk_close(sock);};if (bLoopHere) {loop(server);}else {std::thread(loop, server).detach();}
}

这里xf这个lambda表达式其实是相当于是当接收到请求之后的处理然后,然后start_sock_raw_serverT这个函数起了一个服务,当其他进程链接这个rmmt服务后,就会用哪个lambda表达式处理客户端发过来的请求,

static void do_rtm_cmd(int pid, map_t<uint64_t,int>& lmemRef, uint64_t uctx, int cmdid, CharSeqReader& chrd,byte_buffer& out)
{/**/try {//printf("[%d]cmdId=%d\n", pid,cmdid);  fflush(stdout);switch (cmdid){case 1: //alloc-memory{uint32_t msize, malign;chrd >> msize >> malign;int64_t mn = shm_alloc_memnode(msize, malign);
#ifdef _DEBUG_PRINTprintf("[%06d] alloc mem @%ld\n", pid, (long)mn);
#endifif (mn < 0) {out << (int)-1 << BBPW("memory allocate failed!");return;} {CFutex::scoped_lock _l(gmt_memMap);mem_addnew(mn);}lmemRef[mn]++; //*/out << (int)0 << mn;}break;case 2: //free memory{int64_t mn = 0;chrd >> mn;lmemRef[mn]--;  bool bf = false; {CFutex::scoped_lock _l(gmt_memMap);bf = mem_deref( mn);    }if (bf) {shm_free_memnode(mn);}
#ifdef _DEBUG_PRINTLOG_INFO(MSG_LOG,"[{}] free mem @{}  {}", pid, (long)mn , bf ? "(Freed!)" : "");
#endifout << (int)0;}break;case 4://pre-send memory!{static atomic<int64_t> uid_(1);int64_t bid = uid_.fetch_add(1), mn = 0;    uint32_t n = 0;chrd >> n;
#ifdef _DEBUG_PRINTostringstream oss;oss << "[" << pid << "] pre-send mem(s),bid=" << bid << ",ct=" << n << "(";
#endifSendinfMemInfo simi;    simi.from_pid = pid;if (n > 0) {simi.vmn.resize(n);chrd.read_data((void*)simi.vmn.data(), n * sizeof(uint64_t));
#ifdef _DEBUG_PRINTfor (auto x : simi.vmn) {oss << x << ",";}
#endif // _DEBUG}chrd >> simi.to_pid;{CFutex::scoped_lock wlg(gmt_memMap);for (auto x : simi.vmn) {mem_addref(x);}g_sdmMap[bid].swap(simi);}out << (int)0 << bid;
#ifdef _DEBUG_PRINTLOG_INFO(MSG_LOG,"{}).", oss.str());
#endif}break;case 5://recv memory!{uint32_t n = 0; int64_t bid = 0; int r_pid = 0;chrd >> bid >> n >> r_pid;#ifdef _DEBUG_PRINTostringstream oss;oss << "[" << pid << "] recv mem(s),bid="<< bid << ",ct=" << n << "(";
#endif{CFutex::scoped_lock wlg(gmt_memMap);auto it = g_sdmMap.find(bid);assert(it != g_sdmMap.end());auto& simi=(it->second);assert(n == simi.vmn.size() && r_pid==simi.from_pid && pid==simi.to_pid);for (uint32_t i = 0; i < n; i++) {uint64_t  mn = simi.vmn[i];lmemRef[mn]++;#ifdef _DEBUG_PRINToss << mn << ",";
#endif}g_sdmMap.erase(bid);}out << (int)0;
#ifdef _DEBUG_PRINTLOG_INFO(MSG_LOG,"{}).", oss.str());
#endif}break;default:out << (int)1001 << BBPW("invalid command id!");break;}}catch (std::exception& e) {assert(e.what() == nullptr);}catch (GeneralException& e) {printf("%d %s\n", e.err_code(), e.err_str());}}

这个是真正处理发过来的命令的代码。

相关文章:

微服务架构中的多进程通信--内存池、共享内存、socket

目录 1 引言 2 整体架构简介 3 疑问 3.1 我们的共享内存消息机制是用的posix还是system V 3.2 rmmt中&#xff0c;不同线程之间的比如访问同一个内存&#xff0c;用的什么锁控制的 3.3 疑问&#xff1a;假如一个进程发送给了另外两个进程&#xff0c;然后另外两个进程都同…...

使用 adb 命令截取 Android 设备的屏幕截图

使用 adb 命令截取 Android 设备的屏幕截图。以下是两种常见的方法&#xff1a; 方法一&#xff1a;截屏后保存到电脑 adb shell screencap -p /sdcard/screenshot.png adb pull /sdcard/screenshot.png解释&#xff1a; adb shell screencap -p /sdcard/screenshot.png&…...

Jenkins服务器配置密钥对

1. 在 Jenkins 服务器上执行以下命令 # 生成 SSH 密钥对 ssh-keygen -t rsa -b 2048 -f ~/.ssh/id_rsa -N ""# 查看公钥内容 cat ~/.ssh/id_rsa.pub 2. 将显示的公钥内容复制&#xff0c;然后在目标服务器上执行 # 在目标服务器上执行 mkdir -p /root/.ssh chmod …...

Docker中部署Alertmanager

在 Docker 中部署 Alertmanager&#xff08;通常与 Prometheus 告警系统配合使用&#xff09;的步骤如下&#xff1a; 一、拉取镜像prom/alertmanager docker pull prom/alertmanager二、 创建 Alertmanager 配置文件 首先准备Alertmanager的配置文件 alertmanager.yml(如存…...

Keil软件中STM32(ARM)与C51兼容方法

推荐其他UP主&#xff1a;Keil5安装教程&#xff08;包含C51与MDK共存&#xff09; - Kojull - 博客园 我已经实现了&#xff01;...

青少年编程与数学 02-019 Rust 编程基础 19课题、项目发布

青少年编程与数学 02-019 Rust 编程基础 19课题、项目发布 一、准备工作1. 创建和配置项目2. 编写代码和测试3. 文档注释 二、构建发布版本1. 构建优化后的可执行文件2. 静态链接&#xff08;可选&#xff09; 三、发布到 crates.io1. Crates.io核心功能使用方法特点最新动态 2…...

一洽小程序接入说明

接入说明 文档以微信小程序作为示例介绍&#xff0c;其他小程序接入操作与此类似 1、添加校验文件 开发者使用微信小程序提供的 webview 组件可以实现打开一洽的H5对话 小程序的“域名配置”中添加一洽的对话域名地址&#xff0c;需要获取校验文件提供给一洽放在域名根目录下…...

RabbitMQ的基本使用

RabbitMQ 是一个非常流行的消息中间件&#xff0c;用于实现生产者与消费者之间的异步通信。它基于 AMQP 协议&#xff08;高级消息队列协议&#xff09;&#xff0c;支持多种编程语言和平台。 以下是 RabbitMQ 的基本使用说明&#xff0c;包括安装、核心概念、基本操作和 Pyth…...

CSS专题之常见布局

前言 石匠敲击石头的第 13 次 作为一名前端开发&#xff0c;在日常开发中&#xff0c;写页面是必不可少的工作&#xff0c;但有时候发现很多的页面结构都是类似的&#xff0c;所以打算写一篇文章来梳理一下日常开发中常见的布局&#xff0c;如果哪里写的有问题欢迎指出。 单列…...

CentOS 7连接公司网络配置指南

在物理主机上安装了一个CentOS 7&#xff0c;需要连接公司的网络&#xff0c;但是公司的网络需要输入用户名密码才能连接 解决方案 需要 同时设置 wifi-sec.key-mgmt 和 802-1x 参数。以下是分步操作&#xff1a; 1. 创建基础 Wi-Fi 连接 sudo nmcli con add con-name &quo…...

RustDesk CentOS自建中继节点

一、需开放端口 TCP: 21115, 21116, 21117, 21118, 21119 UDP: 21116 二、安装docker 1.使用 root 权限登录 CentOS。确保 yum 包更新到最新 yum update 2. 卸载旧版本 yum remove docker 3. 安装 Docker 所需依赖 yum -y install yum-utils device-mapper-persistent-d…...

CentOS 7上部署BIND9 DNS服务器指南

场景假设&#xff1a; 我们要为内部网络 192.168.1.0/24 搭建一个权威 DNS 服务器。 域名&#xff1a;mylab.localDNS 服务器 IP&#xff1a;192.168.1.10我们将配置正向解析 (hostname -> IP) 和反向解析 (IP -> hostname)。 一、安装 BIND9 更新系统并安装 BIND 及工…...

面试突击:消息中间件之RabbitMQ

一&#xff1a;你们项目中哪里用到了RabbitMQ ? 难易程度&#xff1a;☆☆☆ 出现频率&#xff1a;☆☆☆☆ 我们项目中很多地方都使用了RabbitMQ , RabbitMQ 是我们项目中服务通信的主要方式之一 , 我们项目中服务通信主要有两种方式实现 : 通过Feign实现服务调用通过MQ实现服…...

基于 ESP32 与 AWS 全托管服务的 IoT 架构:MQTT + WebSocket 实现设备-云-APP 高效互联

目录 一、总体架构图 二、设备端(ESP32)低功耗设计(适配 AWS IoT) 1.MQTT 设置(ESP32 连接 AWS IoT Core) 2.低功耗策略总结(ESP32) 三、云端架构(基于 AWS Serverless + IoT Core) 1.AWS IoT Core 接入 2.云端 → APP:WebSocket 推送方案 流程: 3.数据存…...

将 /dev/vdb1 的空间全部合并到 /dev/mapper/centos-root(即扩展 CentOS 的根分区)

要将 /dev/vdb1 的 1TB 空间合并到 /dev/mapper/centos-root&#xff08;即扩展 CentOS 的根分区&#xff09;&#xff0c;可以采用 LVM&#xff08;逻辑卷管理&#xff09; 的方式。以下是详细步骤&#xff1a; 步骤 1&#xff1a;检查当前磁盘和 LVM 情况 1.1 确认 /dev/vdb…...

CentOS Stream安装MinIO教程

1. 下载 MinIO 二进制文件 # 进入 MinIO 安装目录 sudo cd /usr/local/bin/# 下载 MinIO 二进制文件&#xff08;替换为最新版本链接&#xff09; wget https://dl.min.io/server/minio/release/linux-amd64/minio chmod x minio2. 创建专用用户和存储目录 # 创建 minio 用户…...

游戏引擎学习第299天:改进排序键 第二部分

回顾并为当天内容做准备 我们会现场编写完整的游戏代码。回顾上周发现自己对游戏中正确的排序规则并没有清晰的理解。主要原因是我们更擅长三维游戏开发&#xff0c;缺乏二维游戏和二维游戏技术的经验&#xff0c;对于二维精灵排序、模拟三维效果的最佳方案等没有太多技巧和经…...

设计模式----软考中级软件设计师(自用学习笔记)

目录 1、设计模式的要素 2、设计模式的分类 3、简单工厂模式 4、工厂方法 5、抽象工厂 6、生成器 7、原型 8、单例模式 9、适配器 10、桥接 11、组合模式 12、装饰 13、外观 14、享元 15、代理 16、责任链 17、命令 18、解释器 19、迭代器 20、中介者 21、…...

uniapp如何设置uni.request可变请求ip地址

文章目录 简介方法一&#xff1a;直接在请求URL中嵌入变量方法二&#xff1a;使用全局变量方法三&#xff1a;使用环境变量方法四&#xff1a;服务端配置方法五&#xff1a;使用配置文件&#xff08;如config.js&#xff09;:总结 简介 在uni-app中&#xff0c;uni.request 用…...

Centos上搭建 OpenResty

一、OpenResty简介 OpenResty 是基于 Nginx 的扩展平台&#xff0c;完全兼容 Nginx 的核心功能&#xff08;如 HTTP 服务和反向代理&#xff09;&#xff0c;同时通过内嵌 LuaJIT 支持&#xff0c;允许开发者用 Lua 脚本灵活扩展业务逻辑。它简化了动态逻辑的实现。 二、安装…...

Kotlin与物联网(IoT):Android Things开发探索

在物联网&#xff08;IoT&#xff09;领域&#xff0c;Kotlin 凭借其简洁性、安全性和与 Java 生态的无缝兼容性&#xff0c;逐渐成为 Android Things 开发的有力工具。尽管 Google 已于 2022 年宣布停止对 Android Things 的官方支持&#xff0c;但其技术思想仍值得探索&#…...

WIFI信号状态信息 CSI 深度学习篇之CNN(Python)

本博客是一篇非新手导向的CNN处理CSI图像帧的教程&#xff0c;基于tensorflow框架构建CNN模型进行训练&#xff0c;训练对象依然是前述博客中所提到的CSI图像帧&#xff08;500 x 90 x 1&#xff09;。代码里用到了深度可分离卷积&#xff0c;这种结构在减少计算量和参数数量方…...

深度学习实战 04:卷积神经网络之 VGG16 复现三(训练)

在后续的系列文章中&#xff0c;我们将逐步深入探讨 VGG16 相关的核心内容&#xff0c;具体涵盖以下几个方面&#xff1a; 卷积原理篇&#xff1a;详细剖析 VGG 的 “堆叠小卷积核” 设计理念&#xff0c;深入解读为何 332 卷积操作等效于 55 卷积&#xff0c;以及 333 卷积操作…...

欧拉系统离线部署docker

https://www.cnblogs.com/hsh96/p/18150538 Docker 离线安装指南 本文介绍了如何在 Linux 系统上进行 Docker 的离线安装。首先&#xff0c;确保欧拉系统安装的是server版本&#xff0c;否则没有tar工具。 您需要下载 Docker 的离线安装包。您可以从以下链接获取所需的安装包&a…...

Java 中 final 与 static 的区别

Java 中 final 与 static 的区别 在 Java 中&#xff0c;final 和 static 是两个不同的关键字&#xff0c;它们的核心作用和不可变性特性有本质区别&#xff1a; 一、final 的核心作用 1. 变量&#xff08;不可变引用&#xff09; 不可重新赋值&#xff1a;final 修饰的变量…...

多模态实时交互边界的高效语音语言模型 VITA-Audio 介绍

介绍 VITA-Audio是由Zuwei Long等研究者提出的端到端大型语音语言模型&#xff0c;其核心目标是通过跨模态令牌生成技术&#xff0c;解决传统语音交互系统中首音频令牌生成延迟高的问题。该模型的创新点主要体现在&#xff1a; 低延迟&#xff1a;VITA-Audio 是首个能够在初次…...

LLM | 论文精读 | NAACL 2025 | Clarify When Necessary:教语言模型何时该“问一句”再答!

&#x1f50d; 解读 NAACL 2025 重磅论文《Clarify When Necessary》&#xff1a;教语言模型何时该“问一句”再答&#xff01; &#x1f9e9; 一、现实问题&#xff1a;大模型“看不懂装懂”有多危险&#xff1f; 我们每天用的 ChatGPT、Claude 等大型语言模型&#xff08;LL…...

MySQL 8.0 OCP 英文题库解析(七)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题51~60 试题51:…...

深度解析Vue项目Webpack打包分包策略 从基础配置到高级优化,全面掌握性能优化核心技巧

深度解析Vue项目Webpack打包分包策略 从基础配置到高级优化&#xff0c;全面掌握性能优化核心技巧 一、分包核心价值与基本原理 1.1 为什么需要分包 首屏加载优化&#xff1a;减少主包体积&#xff0c;提升TTI&#xff08;Time to Interactive&#xff09;缓存利用率提升&am…...

MySQL——基本查询内置函数

目录 CRUD Create Retrieve where order by limit Update Delete 去重操作 聚合函数 聚合统计 内置函数 日期函数 字符函数 数学函数 其它函数 实战OJ 批量插入数据 找出所有员工当前薪水salary情况 查找最晚入职员工的所有信息 查找入职员工时间升序排…...

实现图片自动压缩算法,canvas压缩图片方法

背景&#xff1a; 在使用某些支持webgl的图形库&#xff08;eg&#xff1a;PIXI.js&#xff0c;fabric.js&#xff09;场景中&#xff0c;如果加载的纹理超过webgl可处理的最大纹理限制&#xff0c;会导致渲染的纹理缺失&#xff0c;甚至无法显示。 方案 实现图片自动压缩算…...

零基础设计模式——创建型模式 - 单例模式

第二部分&#xff1a;创建型模式 - 单例模式 (Singleton Pattern) 欢迎来到创建型模式的第一站——单例模式&#xff01;这是最简单也最常用的设计模式之一。 核心思想&#xff1a;关注对象的创建过程&#xff0c;将对象的创建与使用分离&#xff0c;降低系统的耦合度。 单例…...

数据挖掘:从数据堆里“淘金”,你的数据价值被挖掘了吗?

数据挖掘&#xff1a;从数据堆里“淘金”&#xff0c;你的数据价值被挖掘了吗&#xff1f; 在这个数据爆炸的时代&#xff0c;我们每天都在产生海量信息&#xff1a;社交媒体上的点赞、网购时的浏览记录&#xff0c;甚至是健身手环记录下的步数。这些数据本身可能看似杂乱无章…...

k8s1.27版本集群部署minio分布式

需求&#xff1a; 1.创建4个pv&#xff0c;一个pv一个minio-pod。使用sts动态分配pvc(根据存储类找到pv)。----持久化 2.暴露minio的9001端口。&#xff08;nodeport&#xff09;----管理界面 镜像&#xff1a;minio/minio:RELEASE.2023-03-20T20-16-18Z--->换国内源 说明…...

雷军:芯片,手机,平板,SUV一起发

大家好&#xff0c;我是小悟。 5月19日&#xff0c;雷军在微博上宣布&#xff0c;5月22日晚7点将举办小米战略新品发布会。 这场被官方称为“人车家全生态”战略升级的重要活动&#xff0c;一口气带来了小米手机SoC芯片“玄戒O1”、旗舰手机小米15S Pro、小米平板7 Ultra&…...

使用Dockerfile构建含私有Maven仓库依赖包的Java容器

背景 需要用JDBC方式访问ArgoDB星环提供了ArgoDB jar包应用将以Container的方式运行我希望打包成镜像之后&#xff0c;镜像启动就能测试连接是否成功连接URL串需要能够传递进去 失败的方案一&#xff1a;本地文件导入POM pom.xml 配置本地路径 <dependency><groupI…...

AI指令模板综述(Prompt Review)

文章目录 DeepSeek DeepSeek 参考&#xff1a;DeepSeek学术指令大全 找到有价值的研究方向 "作为我的学术研究助手&#xff0c;你需要基于以下要求为我生成5个具有学术价值的创新选题&#xff1a; 请聚焦于[具体研究领域&#xff0c;如’社交媒体用户行为’或’深度学习…...

软件架构之-论分布式架构设计及其实现

论分布式架构设计及其实现 摘要正文 摘要 2023年2月&#xff0c;本人所在集团公司承接了长三角地区某省渔船图纸电子化审查项目开发&#xff0c;该项目旨在为长三角地区渔船建造设计院、渔船审图机构提供一个便捷化的服务平台。在次项目中&#xff0c;我作为项目成员参与了整个…...

零售EDI:Belk Stores EDI需求分析

Belk Stores 成立于 1888 年&#xff0c;是美国历史最悠久的家族百货连锁品牌之一&#xff0c;总部位于北卡罗来纳州夏洛特市。作为美国东南部领先的零售企业&#xff0c;Belk 在16个州拥有近300家门店&#xff0c;主要经营服装、鞋履、美妆、家居用品等多个品类&#xff0c;服…...

LangChain4j入门(六)整合提示词(Prompt)

前言 提示词&#xff08;Prompt&#xff09;是用户输入给AI模型的一段文字或指令&#xff0c;用于引导模型生成特定类型的内容。通过提示词&#xff0c;用户可以告诉AI“做什么”、 “如何做”以及“输出格式”&#xff0c;从而在满足需求的同时最大程度减少无关信息的生成。有…...

【HarmonyOS 5】金融应用开发鸿蒙组件实践

【HarmonyOS 5】金融应用开发鸿蒙组件实践 一、鸿蒙生态观察 2024 年 1 月 18 日&#xff1a; 发布 原生鸿蒙操作系统星河版&#xff0c;面向开发者开放申请&#xff0c;余承东宣布鸿蒙生态设备数达 8 亿台&#xff1b;建设银行、邮储银行等完成鸿蒙原生应用 Beta 版本开发。 …...

cv2.VideoWriter_fourcc(*‘mp4v‘)生成的视频无法在浏览器展

看这个博主的博客&#xff0c;跟我碰到的问题的一致&#xff0c;都是使用AVC1写视频时报编码器不存在的异常&#xff0c;手动编译opencv-python或者使用conda install -c conda-forge opencv安装依赖即可。 博主博客&#xff1a;Python OpenCV生成视频无法浏览器播放问题说明及…...

MD编辑器推荐【Obsidian】含下载安装和实用教程

为什么推荐 Obsidian &#xff1f; 免费 &#xff08;Typora 开始收费了&#xff09;Typora 实现的功能&#xff0c;它都有&#xff01;代码块可一键复制 文件目录支持文件夹 大纲支持折叠、搜索 特色功能 – 白板 特色功能 – 关系图谱 下载 https://pan.baidu.com/s/1I1fSly…...

新书速览|GraphPad Prism图表可视化与统计数据分析:视频教学版

《GraphPad Prism图表可视化与统计数据分析:视频教学版 》 本书内容 《GraphPad Prism图表可视化与统计数据分析:视频教学版 》以GraphPad Prism 10为平台&#xff0c;讲述统计分析软件GraphPad Prism的具体应用方法。在介绍《GraphPad Prism图表可视化与统计数据分析:视频教学…...

波峰波谷策略

这是一个基于数据分布的峰度(kurtosis)和偏度(skewness)的交易策略。 当数据呈现趋势性,并且潜在趋势为正时,我们做多。 当数据呈现趋势性,并且潜在趋势为负时,我们做空。 当趋势发生反转后,我们平仓。 那么,我们如何确定趋势和趋势的强度呢?让我们先来复习一下峰…...

【综述】视频目标分割VOS

目录 1、Associating Objects with Transformers for Video Object Segmentation1&#xff09;背景知识2&#xff09;研究方法3&#xff09;实验结果4&#xff09;结论 2、Rethinking Space-Time Networks with Improved Memory Coverage for Efficient Video Object Segmentat…...

基于线性回归的数据预测

1. 自主选择一个公开回归任务数据集&#xff08;如房价预测、医疗数据、空气质量预测等&#xff0c;可Kaggle&#xff09;。 2. 数据预处理&#xff1a;完成标准化&#xff08;Normalization&#xff09;、特征选择或缺失值处理等步骤。 3. 使用线性回归模型进行建模。采用80…...

第5天-python饼图绘制

一、基础饼图绘制(Matplotlib) 1. 环境准备 python 复制 下载 pip install matplotlib numpy 2. 基础饼图代码 python 复制 下载 import matplotlib.pyplot as plt# 数据准备 labels = [1, 2, 3, 4] sizes = [30, 25, 15, 30] # 各部分占比(总和建议100) colors…...

c++学习方向选择说明

文章目录 前言一、什么样的人适合用c找编程相关工作二、c可以投递什么岗位三、应届生c怎么学才可以找到好工作那这样的话&#xff0c;校招生搞c应该怎么学才能凸显自己的优势呢&#xff1f;那有人就问了&#xff0c;那我应该学啥啊&#xff1f; 四、零基础学习c路线 前言 做了…...

采集需要登录网站的教程

有些网站需要用户登录才能显示相关信息&#xff0c;如果要采集这类网站&#xff0c;有以下几个方法&#xff1a; 1. 写发布模块来抓包获取post的数据&#xff1b; 2. 有些采集器内置浏览器获取这些信息&#xff0c;但是经常获取的不准确&#xff0c;可靠性太低&#xff1b; 3. …...