网页微信注册新号怎么注册/昆明百度搜索排名优化
以下测试代码实现的功能是:持续从内存块中获取原始数据,然后依次进行解码、编码、最后保存成mp4视频文件。
可保存成单个视频文件,也可指定每个视频文件的总帧数,保存多个视频文件。
为了便于查看和修改,这里将可独立的程序段存放在单个函数中:
1.线程函数set_packet:独立线程,用于用户向指定的内存块中持续写入数据,这里通过调用队列类PacketScaleQueue,可参考:https://blog.csdn.net/fengbingchun/article/details/132128885 中说明。这里填充的数据参考FFmpeg源码中的doc/examples/encode_video.c:每次向队列中写入一帧数据
void set_packet(PacketScaleQueue& packet_encode)
{while (packet_encode_flag) {Buffer buffer;packet_encode.popPacket(buffer);static int i = 0;// refrence: ffmpeg/doc/examples/encode_video.c// prepare a dummy image: Yunsigned char* p1 = buffer.data;for (auto y = 0; y < height; ++y) {for (auto x = 0; x < width; ++x) {p1[y * width + x] = x + y + i * 3;}}// Cb and Crunsigned char* p2 = buffer.data + width * height;unsigned char* p3 = buffer.data + width * height + width * height / 4;for (auto y = 0; y < height / 2; ++y) {for (auto x = 0; x < width / 2; ++x) {p2[y * width / 2 + x] = 128 + y + i * 2;p3[y * width / 2 + x] = 64 + x + i * 5;}}packet_encode.pushScale(buffer);if (++i > 25) i = 0;std::this_thread::sleep_for(std::chrono::milliseconds(40));}
}
2.回调函数read_packet:avio_alloc_context中使用,不断从队列中获取数据,av_read_frame中也会从这里获取数据:每次从队列中获取一帧数据
int read_packet(void* opaque, uint8_t* buf, int buf_size)
{PacketScaleQueue* packet_encode = static_cast<PacketScaleQueue*>(opaque);Buffer buffer;packet_encode->popScale(buffer);memcpy(buf, buffer.data, buf_size);packet_encode->pushPacket(buffer);return buf_size;
}
3.函数get_input_format_context:创建输入AVFormatContext,需要调用av_dict_set设置video_size和pixel_format
AVFormatContext* get_input_format_context(AVIOContext* avio_ctx)
{AVFormatContext* ifmt_ctx = avformat_alloc_context();if (!ifmt_ctx) {print_error_string(AVERROR(ENOMEM));return nullptr;}ifmt_ctx->pb = avio_ctx;AVDictionary* dict = nullptr;av_dict_set(&dict, "video_size", video_size, 0);av_dict_set(&dict, "pixel_format", pixel_format, 0);auto ret = avformat_open_input(&ifmt_ctx, nullptr, av_find_input_format("rawvideo"), &dict);if (ret < 0) {fprintf(stderr, "Could not open input\n");print_error_string(ret);return nullptr;}av_dict_free(&dict);ret = avformat_find_stream_info(ifmt_ctx, nullptr);if (ret < 0) {fprintf(stderr, "Could not find stream information\n");print_error_string(ret);return nullptr;}for (unsigned int i = 0; i < ifmt_ctx->nb_streams; ++i) {const AVStream* stream = ifmt_ctx->streams[i];if (stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {video_stream_index = i;fprintf(stdout, "type of the encoded data: %d, dimensions of the video frame in pixels: width: %d, height: %d, pixel format: %d\n",stream->codecpar->codec_id, stream->codecpar->width, stream->codecpar->height, stream->codecpar->format);}}if (video_stream_index == -1) {fprintf(stderr, "error: no video stream\n");return nullptr;}if (ifmt_ctx->streams[video_stream_index]->codecpar->codec_id != AV_CODEC_ID_RAWVIDEO) {fprintf(stderr, "error: this test code only support rawvideo encode: %d\n", ifmt_ctx->streams[video_stream_index]->codecpar->codec_id);return nullptr;}av_dump_format(ifmt_ctx, 0, "nothing", 0);return ifmt_ctx;
}
4.函数get_decode_context:创建解码AVCodecContext
AVCodecContext* get_decode_context(AVFormatContext* ifmt_ctx)
{AVCodec* decoder = nullptr;auto ret = av_find_best_stream(ifmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0);if (ret < 0) {fprintf(stderr, "fail to av_find_best_stream: %d\n", ret);print_error_string(ret);return nullptr;}AVCodecContext* dec_ctx = avcodec_alloc_context3(decoder);if (!dec_ctx) {fprintf(stderr, "fail to avcodec_alloc_context3\n");return nullptr;}ret = avcodec_parameters_to_context(dec_ctx, ifmt_ctx->streams[video_stream_index]->codecpar);if (ret < 0) {fprintf(stderr, "fail to avcodec_parameters_to_context: %d\n", ret);print_error_string(ret);return nullptr;}dec_ctx->framerate = av_guess_frame_rate(ifmt_ctx, ifmt_ctx->streams[video_stream_index], nullptr);ret = avcodec_open2(dec_ctx, decoder, nullptr);if (ret != 0) {fprintf(stderr, "fail to avcodec_open2: %d\n", ret);print_error_string(ret);return nullptr;}return dec_ctx;
}
5.函数get_encode_context:创建编码AVCodecContext,注意对enc_ctx的相关成员的赋值
AVCodecContext* get_encode_context(AVFormatContext* ifmt_ctx)
{AVCodec* encodec = avcodec_find_encoder_by_name("mpeg1video"); // ffmpeg.exe -encodersif (!encodec) {fprintf(stderr, "fail to avcodec_find_encoder_by_name\n");return nullptr;}AVCodecContext* enc_ctx = avcodec_alloc_context3(encodec);if (!enc_ctx) {fprintf(stderr, "fail to avcodec_alloc_context3\n");return nullptr;}enc_ctx->bit_rate = 400000;enc_ctx->framerate = ifmt_ctx->streams[video_stream_index]->r_frame_rate;enc_ctx->pix_fmt = AV_PIX_FMT_YUV420P;enc_ctx->height = ifmt_ctx->streams[video_stream_index]->codecpar->height;enc_ctx->width = ifmt_ctx->streams[video_stream_index]->codecpar->width;enc_ctx->time_base = av_inv_q(av_d2q(frame_rate, 4096));enc_ctx->max_b_frames = 1;//if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER) // trueenc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;auto ret = avcodec_open2(enc_ctx, encodec, nullptr);if (ret != 0) {fprintf(stderr, "fail to avcodec_open2: %d\n", ret);print_error_string(ret);return nullptr;}return enc_ctx;
}
6.函数get_output_format_context:创建输出AVFormatContext
AVFormatContext* get_output_format_context(const AVCodecContext* enc_ctx, const char* filename)
{AVFormatContext* ofmt_ctx = nullptr;auto ret = avformat_alloc_output_context2(&ofmt_ctx, nullptr, nullptr, filename);if (ret < 0 || !ofmt_ctx) {fprintf(stderr, "fail to avformat_alloc_output_context2: %d\n", ret);print_error_string(ret);return nullptr;}AVStream* out_stream = avformat_new_stream(ofmt_ctx, nullptr);if (!out_stream) {fprintf(stderr, "fail to avformat_new_stream\n");return nullptr;}ret = avcodec_parameters_from_context(out_stream->codecpar, enc_ctx);if (ret < 0) {fprintf(stderr, "fail to avcodec_parameters_from_context: %d\n", ret);print_error_string(ret);return nullptr;}out_stream->time_base = enc_ctx->time_base;if (!(ofmt_ctx->oformat->flags & AVFMT_NOFILE)) { // trueret = avio_open(&ofmt_ctx->pb, filename, AVIO_FLAG_WRITE);if (ret < 0) {fprintf(stderr, "fail to avio_open: %d\n", ret);print_error_string(ret);return nullptr;}}ret = avformat_write_header(ofmt_ctx, nullptr);if (ret < 0) {fprintf(stderr, "fail to avformat_write_header: %d\n", ret);print_error_string(ret);return nullptr;}av_dump_format(ofmt_ctx, 0, filename, 1);return ofmt_ctx;
}
7.函数decode: 注意对packet的判断,它有可能为nullptr;调用一次avcodec_send_packet,可能需调用多次avcodec_receive_frame,因此需要将avcodec_receive_frame放在while中;需要对dec_ctx->time_base进行设置
int decode(AVPacket* packet, AVFormatContext* ifmt_ctx, AVCodecContext* dec_ctx, AVFrame* frame)
{if (packet)av_packet_rescale_ts(packet, ifmt_ctx->streams[video_stream_index]->time_base, dec_ctx->time_base);auto ret = avcodec_send_packet(dec_ctx, packet);if (ret < 0) {fprintf(stderr, "fail to avcodec_send_packet: %d\n", ret);print_error_string(ret);return -1;}while (1) {ret = avcodec_receive_frame(dec_ctx, frame);if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { // AVERROR(EAGAIN): decode is not yet complete//fprintf(stderr, "Warning: avcodec_receive_frame: %d\n", ret);//print_error_string(ret);break;}else if (ret < 0) {fprintf(stderr, "fail to avcodec_receive_frame: %d\n", ret);print_error_string(ret);return ret;}frame->pts = frame->best_effort_timestamp;break;}if (packet)av_packet_unref(packet);return 0;
}
8.函数encode:注意:调用一次avcodec_send_frame,可能需要调用多次avcodec_receive_packet,因此需要将avcodec_receive_packet放在while中;需要对ofmt_ctx->streams[0]->time_base进行设置,否则生成的mp4中无法获取帧速率;也可在调用avformat_write_header时设置video_track_timescale指定
int encode(AVCodecContext* enc_ctx, AVFrame* frame, AVPacket* packet, AVFormatContext* ifmt_ctx, AVFormatContext* ofmt_ctx)
{auto ret = avcodec_send_frame(enc_ctx, frame);if (ret < 0) {if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {fprintf(stderr, "Warning: avcodec_send_frame: %d\n", ret);print_error_string(ret);ret = 0;}else {fprintf(stderr, "fail to avcodec_send_frame: %d\n", ret);print_error_string(ret);return ret;}}while (1) {ret = avcodec_receive_packet(enc_ctx, packet);if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { // AVERROR(EAGAIN): encode is not yet complete//fprintf(stderr, "Warning: avcodec_receive_packet: %d\n", ret);//print_error_string(ret);break;}if (ret < 0) {fprintf(stderr, "fail to avcodec_receive_packet: %d\n", ret);print_error_string(ret);return ret;}packet->stream_index = 0;av_packet_rescale_ts(packet, ifmt_ctx->streams[video_stream_index]->time_base, ofmt_ctx->streams[0]->time_base);//packet2->pts = packet2->dts = frame->pts *// ofmt_ctx->streams[0]->time_base.den / ofmt_ctx->streams[0]->time_base.num / // (enc_ctx->framerate.num / enc_ctx->framerate.den);ret = av_interleaved_write_frame(ofmt_ctx, packet);if (ret < 0) {print_error_string(ret);return ret;}av_packet_unref(packet);}return 0;
}
9.主函数test_ffmpeg_save_video_slice:注意:在退出前需要flush decoder和encoder;写入视频文件需先调用avformat_write_header,然后持续调用av_interleaved_write_frame,退出前再需调用av_write_trailer;每次新文件的写入,需重新调用get_decode_context、get_encode_context、get_output_format_context并在之前作相应free
int test_ffmpeg_save_video_slice()
{PacketScaleQueue packet_encode;packet_encode.init(queue_size, block_size);std::thread thread_packet(set_packet, std::ref(packet_encode));uint8_t* avio_ctx_buffer = static_cast<uint8_t*>(av_malloc(block_size));if (!avio_ctx_buffer) {print_error_string(AVERROR(ENOMEM));return -1;}AVIOContext* avio_ctx = avio_alloc_context(avio_ctx_buffer, block_size, 0, &packet_encode, &read_packet, nullptr, nullptr);if (!avio_ctx) {print_error_string(AVERROR(ENOMEM));return -1;}AVFormatContext* ifmt_ctx = get_input_format_context(avio_ctx);if (!ifmt_ctx) {fprintf(stderr, "fail to get_input_format_context\n");return -1;}AVPacket *packet = av_packet_alloc(), *packet2 = av_packet_alloc();if (!packet || !packet2) {fprintf(stderr, "fail to av_packet_alloc\n");return -1;}AVFrame* frame = av_frame_alloc();if (!frame) {fprintf(stderr, "fail to av_frame_alloc\n");return -1;}int count = 0, name = 1;AVCodecContext* enc_ctx = nullptr;AVFormatContext* ofmt_ctx = nullptr;AVCodecContext* dec_ctx = nullptr;while (1) {auto ret = av_read_frame(ifmt_ctx, packet);if (ret < 0) {break;}if (packet->stream_index != video_stream_index) {av_packet_unref(packet);continue;}if (count % slice_size == 0) {enc_ctx = get_encode_context(ifmt_ctx);if (!enc_ctx) {fprintf(stderr, "fail to avcodec_alloc_context3\n");return -1;}std::string filename = std::to_string(name) + ".mp4";filename = std::string(path) + filename;ofmt_ctx = get_output_format_context(enc_ctx, filename.c_str());if (!ofmt_ctx) {fprintf(stderr, "fail to get_output_format_context\n");return -1;}dec_ctx = get_decode_context(ifmt_ctx);if (!dec_ctx) {fprintf(stderr, "fail to get_decode_context\n");return -1;}++name;}if (decode(packet, ifmt_ctx, dec_ctx, frame) != 0) return -1;if (encode(enc_ctx, frame, packet2, ifmt_ctx, ofmt_ctx) != 0) return -1;//fprintf(stdout, "count: %d\n", count);if (count + 1 == total_frames) { // terminate looppacket_encode_flag = false;// flush the decoderdecode(nullptr, ifmt_ctx, dec_ctx, frame);if (frame->data[0])encode(enc_ctx, frame, packet2, ifmt_ctx, ofmt_ctx);// flush the encoderencode(enc_ctx, nullptr, packet2, ifmt_ctx, ofmt_ctx);av_write_trailer(ofmt_ctx);break;}++count;if (count > 1 && count % slice_size == 0) {// flush the decoderdecode(nullptr, ifmt_ctx, dec_ctx, frame);if (frame->data[0])encode(enc_ctx, frame, packet2, ifmt_ctx, ofmt_ctx);// flush the encoderencode(enc_ctx, nullptr, packet2, ifmt_ctx, ofmt_ctx);av_write_trailer(ofmt_ctx);avcodec_free_context(&dec_ctx);avcodec_free_context(&enc_ctx);avio_closep(&ofmt_ctx->pb);avformat_free_context(ofmt_ctx);}}av_packet_free(&packet);av_packet_free(&packet2);av_frame_free(&frame);avcodec_free_context(&dec_ctx);avcodec_free_context(&enc_ctx);avio_closep(&ofmt_ctx->pb);avformat_close_input(&ofmt_ctx);avformat_close_input(&ifmt_ctx);// note: the internal buffer could have changed, and be != avio_ctx_bufferif (avio_ctx) {av_freep(&avio_ctx->buffer);av_freep(&avio_ctx);}thread_packet.join();fprintf(stdout, "test finish\n");return 0;
}
执行结果如下图所示:
可调用ffprobe.exe验证每个生成的视频文件的总帧数,如1.mp4,执行如下命令:
ffprobe.exe -v error -select_streams v:0 -show_entries stream=nb_frames -of default=nokey=1:noprint_wrappers=1 1.mp4
GitHub:https://github.com/fengbingchun/OpenCV_Test
相关文章:

FFmpeg将编码后数据保存成mp4
以下测试代码实现的功能是:持续从内存块中获取原始数据,然后依次进行解码、编码、最后保存成mp4视频文件。 可保存成单个视频文件,也可指定每个视频文件的总帧数,保存多个视频文件。 为了便于查看和修改,这里将可独立的…...

设置VsCode 将打开的多个文件分行(栏)排列,实现全部显示
目录 1. 前言 2. 设置VsCode 多文件分行(栏)排列显示 1. 前言 主流编程IDE几乎都有排列切换选择所要查看的文件功能,如下为Visual Studio 2022的该功能界面: 图 1 图 2 当在Visual Studio 2022打开很多文件时,可以按照图1、图2所示找到自…...

Vue.js2+Cesium1.103.0 六、标绘与测量
Vue.js2Cesium1.103.0 六、标绘与测量 点,线,面的绘制,可实时编辑图形,点击折线或多边形边的中心点,可进行添加线段移动顶点位置等操作,并同时计算出点的经纬度,折线的距离和多边形的面积。 De…...

【redis 延时队列】使用go-redis的list做异步,生产消费者模式
分享一个用到的,使用go-redis的list做异步,生产消费者模式,接着再用 go 协程去检测队列里是否有东西去消费 如果队列为空,就会一直pop,空轮询导致 cpu 资源浪费和redis qps无效升高,所以可以通过 time.Sec…...

激光焊接塑料多点测试全画面穿透率测试仪
工程塑料由于其具有高比强度、电绝缘性、耐磨性、耐腐蚀性等优点,已广泛应用于各个重要领域。另一方面,工程塑料还具有良好的焊接性,是制成复合材料的基体材料的优良选择,因此目前已成为国内外新型复合材料的研究热点。 工程塑料…...

用 Uno 当烧录器给 atmega328 烧录 bootloader
用 Uno 当烧录器给 atmega328 烧录 bootloader date: 2023-8-10 https://backmountaindevil.github.io/#/hackaday/arduino/isp 引脚接线 把两个板子的 11(MOSI)、12(MISO)、13(SCK)、5V、GND 两两相连,还要把 Uno(烧录器)的 10 接到atmeg…...

spring boot策略模式实用: 告警模块为例
spring boot策略模式实用: 告警模块 0 涉及知识点 策略模式, 模板方法, 代理, 多态, 反射 1 需求概括 场景: 每隔一段时间, 会获取设备运行数据, 如通过温湿度计获取到当前环境温湿度;需求: 对获取回来的进行分析, 超过配置的阈值需要产生对应的告警 2 方案设计 告警的类…...

Camunda 7.x 系列【10】使用 Rest API 运行流程实例
有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 2.7.9 本系列Camunda 版本 7.19.0 源码地址:https://gitee.com/pearl-organization/camunda-study-demo 文章目录 1. 前言2. 官方接口文档3. 本地接口文档3.1 Postman3.2 Camunda Platform Run Swagger3.3 S…...

Python-OpenCV中的图像处理-边缘检测
Python-OpenCV中的图像处理-边缘检测 边缘检测Canny算子 边缘检测Canny算子 Canny 边缘检测是一种非常流行的边缘检测算法,是 John F.Canny 在 1986 年提出的。它是一个有很多步构成的算法:噪声去除、计算图像梯度、非极大值抑制、滞后阀值等。 Canny(i…...

一文了解Java序列化和反序列化:对象的存储与传输
一文了解Java序列化和反序列化:对象的存储与传输 作者:Stevedash 发布时间:2023年8月9日 21点30分 前言 Java序列化是一项强大而重要的技术,它允许我们将对象转换为字节流,以便在存储、传输和重建时使用。在本文中&…...

react-codemirror2 编辑器需点击一下或者延时才显示数据的问题
现象: <Codemirror/>组件的数据已经赋上值的情况下,初始状态不渲染数据,需要点击编辑框获取焦点后才展示,或者延迟了几秒才显示出来。 原因: 指定了一些依赖的版本,可能不兼容了一些功能,…...

火山引擎联合Forrester发布《中国云原生安全市场现状及趋势白皮书》,赋能企业构建云原生安全体系
国际权威研究咨询公司Forrester 预测,2023年全球超过40%的企业将会采用云原生优先战略。然而,云原生在改变企业上云及构建新一代基础设施的同时,也带来了一系列的新问题,针对涵盖云原生应用、容器、镜像、编排系统平台以及基础设施…...

需要数电发票接口的,先熟悉下数电发票基本常识
最近有一些技术小伙伴来咨询数电发票接口的时候,对数电发票的一些常识不太了解, 导致沟通起来比较困难。比较典型的这三个问题: 一、开具数电票时,如何设置身份认证频次? 请公司的法定代表人或财务负责人登录江苏省电…...

node-sass是什么
一、Sass(Syntactically Awesome Style Sheets) 是一种CSS预处理器,它扩展了CSS的功能并提供了更强大的样式表语言。Sass允许开发人员使用变量、嵌套规则、混合(Mixins)、继承等高级功能来编写更简洁、可维护的样式代…...

C语言指针之 进阶
前言 今天来较为深入的介绍一下指针,希望大家能有所收获~ 那么,先进行一些简单的基础知识复习吧。 字符指针 格式:char * 补充: 表达式“abcdef”的值是首字符a的地址 所以当像下面这么使用时,它的含…...

C++单例模式
文章目录 1、什么是单例2、一个好的单例应该具备的条件3、懒汉模式与饿汉模式4、单例实现:线程安全、内存安全的懒汉式单例(基于C11的智能指针和互斥锁) 1、什么是单例 单例 Singleton 是设计模式的一种,其特点是只提供唯一一个类…...

C++ 析构函数
析构函数 析构函数于构造函数相对应,构造函数是对象创建的时候自动调用的,而析构函数就是对象在销毁的时候自动调用的 特点: 1)构造函数可以有多个来构成重载,但析构函数只能有一个,不能构成重载 2&…...

CSS——字体选择
在网页设计和开发中,字体选择是一个非常重要的因素。字体不仅仅是文字的表现形式,它们还能够传达出一种特定的情感和风格。在CSS中,我们可以通过使用字体代码来定义网页中使用的字体。 CSS提供了一种简单而灵活的方式来设置字体。通过使用fo…...
SpringBoot自动装配及run方法原理探究
自动装配 1、pom.xml spring-boot-dependencies:核心依赖在父工程中!我们在写或者引入一些SpringBoot依赖的时候,不需要指定版本,就因为有这些版本仓库 1.1 其中它主要是依赖一个父工程,作用是管理项目的资源过滤及…...

Mybatis实现JsonObject对象与JSON之间交互
项目中使用PostGresql数据库进行数据存储,表中某字段为Json类型,用于存储Json格式数据。PG数据库能够直接存储Json算是一大特色,很多特定情境下使用直接存储Json字段数据能够大量节省开发时间,提高后台数据查询和转换效率。 1、基…...

spring boot 集成 jetcache【基础篇:@Cached、@CreateCache、@CacheRefresh】
手打不易,如果转摘,请注明出处! 注明原文:https://zhangxiaofan.blog.csdn.net/article/details/129832925 目录 前言 版本 配置通用说明 项目结构 代码 启动类 实体类 基础使用——增删改查(Cached、CacheInv…...

个人对前后端分离的一些看法
内容简介:前端开发过程中能完全不依赖后端的才是真正的前后端分离指的是工作过程中,前端的的代码中往往会掺杂一些后端的逻辑。后端返回了一个json对象 前端开发过程中能完全不依赖后端的才是真正的前后端分离 指的是工作过程中,前端的的代码…...

TailWindCss 在Hbuilderx中使用
基于这个插件 weapp-tailwindcss 地址 本次说明基于HbuilderX 创建的项目非CLI 安装步骤按照文档走,先安装上几个依赖。然后是几个配置文件 tailwind-input.css tailwind的css文件用来引入到app.vue /* #ifdef H5 */ tailwind base; /* 如果是小程序的话&#x…...

Unity导入图片时,通过设置属性快速实现资源的压缩
是在学习tilemap绘制世界地图的时候发现的这个功能。 之前一直只是粗略的知道这部分是对应图片资源的压缩的。比如Compression是指的压缩质量,想要完全不压缩就设置None,会导致图片资源会大一些。 在我的例子工程中,其他图片资源的尺寸都是6…...

AlmaLinux 9 安装 Go 1.20
AlmaLinux 9 安装 Golang 1.20 1. 下载 go 安装包2. 安装 go3. 配置环境变量4. 确认 go 版本 1. 下载 go 安装包 访问 https://go.dev/dl/,下载你想安装的版本,比如 go1.20.7.linux-amd64.tar.gz, 2. 安装 go (可选)删除旧版本,…...

【Docker】数据库动态授权组件在Kubernetes集群下的测试过程记录
目录 背景 组件原理 测试设计 环境 测试脚本 脚本build为linux可执行文件 镜像构建 Dockerfile Docker build 镜像有效性验证 总结 资料获取方法 背景 我们都知道出于安全性考虑,生产环境的权限一般都是要做最小化控制,尤其是数据库的操作授…...

数据结构【第3章】——线性表
线性表的定义 线性表:零个或多个数据元素的有限序列。 1)线性表是一个序列。即元素之间是有顺序的,若元素存在多个,则第一个元素无前驱,最后一个元素无后继,其他每个元素都有且只有一个前驱和后继。 2&a…...

MySql之分库分表
数据库瓶颈 不管是IO瓶颈还是CPU瓶颈,最终都会导致数据库的活跃连接数增加,进而逼近甚至达到数据库可承载的活跃连接数的阈值。在业务service来看, 就是可用数据库连接少甚至无连接可用,接下来就可以想象了(并发量、吞…...

数据结构—图的遍历
6.3图的遍历 遍历定义: 从已给的连通图中某一顶点出发,沿着一些边访问遍历图中所有的顶点,且使每个顶点仅被访问一次,就叫作图的遍历,它是图的基本运算。 遍历实质:找每个顶点的邻接点的过程。 图的…...

MySQL主从复制基于二进制日志的高可用架构指南
前言 在现代数据库架构中,MySQL主从复制技术扮演着重要角色。它不仅可以提升数据库性能和可扩展性,还赋予系统卓越的高可用性和灾难恢复能力。本文将深入剖析MySQL主从复制的内部机制,同时通过一个实际案例,展示其在实际场景中的…...