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

qt下ffmpeg录制mp4经验分享,支持音视频(h264、h265,AAC,G711 aLaw, G711muLaw)

前言

    MP4,是最常见的国际通用格式,在常见的播放软件中都可以使用和播放,磁盘空间占地小,画质一般清晰,它本身是支持h264、AAC的编码格式,对于其他编码的话,需要进行额外处理。本文提供了ffmpeg录制mp4的封装代码,经测试视频上它支持h264、h265编码,音频支持了AAC、G711的aLaw、muLaw编码。对于以上编码的支持,部分是需要修改ffmpeg的源码,本文也有提供已编译好的ffmpeg以及说明源码上需要修改的地方。

一、时间戳处理

    在mp4录制中,有碰到一个问题,即在录制实时流后,用播放器进行播放,播放时间没有从0秒开始。windows自带的media play播放时,一开始都是静止的画面,从第n秒后,才开始正式播放,用VLC可以直接跳到n秒进行播放。这个问题的原因是时间戳没有处理好,需要记录下首帧,指定首帧时间戳为0,然后后续视频帧的时间戳等于当前帧的时间戳减去首帧时间戳。代码如下:
在这里插入图片描述

二、添加h264、h265、AAC解码头信息

    解码头信息是保存在解码器上下文(AVCodecContext)的extradata中,这些信息包含h264的SPS、PPS头信息,AAC的adts头信息,h265的VPS、SPS、PPS,我们需要使用比特流过滤器(AVBitStreamFilter)来为每一种格式添加相应的头部信息,这样才能在解码器中正常进行解码。以下为添加解码头信息的相关代码:
    初始化时视频:
在这里插入图片描述
    循环读帧中,视频:
在这里插入图片描述
    初始化时音频:
在这里插入图片描述
    循环读帧中,音频:
在这里插入图片描述

三、ffmpeg支持g711 aLaw muLaw

在ffmpeg源码movenc.c文件中,找到mov_write_audio_tag函数,修改以下:
在这里插入图片描述
和在该文件中增加以下:
在这里插入图片描述
muLaw修改类似,它的MKTAG为 ‘u’,‘l’, ‘a’,‘w’。

四、代码分享

mp4recorder.h

#ifndef MP4RECORDER_H
#define MP4RECORDER_Hextern "C"
{#include "libavcodec/avcodec.h"#include "libavformat/avformat.h"#include "libavfilter/avfilter.h"#include "libswscale/swscale.h"#include "libavutil/frame.h"#include "libavutil/imgutils.h"#include "libavcodec/bsf.h"
}#include <QObject>
#include <QMutex>class mp4Recorder : public QObject
{Q_OBJECT
public:explicit mp4Recorder(QObject *parent = nullptr);virtual ~mp4Recorder();bool Init(AVFormatContext *pIfmtCtx, int nCodecType, int nAudioCodecType, QString& sFile);bool DeInit();bool isInit() {return m_bInit;}bool saveOneFrame(AVPacket& pkt, int nCodecType, int nAudioCodecType);private:uint64_t         m_nCounts;bool             m_bFirstGoP;bool             m_bInit;QString          m_sRecordFile;AVFormatContext *m_pIfmtCtx;AVFormatContext *m_pOfmtCtx; // output stream format. copy from instream format.const AVOutputFormat  *m_pOfmt; // save file format.QMutex           m_lock;int64_t          m_nVideoTimeStamp;int              m_nVideoDuration;int              m_nVideoIndex = -1;int              m_nAudioIndex = -1;int				 m_nSpsPpsSize = 0;AVBSFContext    *m_pBsfc = nullptr;AVBSFContext    *m_pBsfcAAC = nullptr;AVPacket        *m_pktFilter = nullptr;AVPacket        *m_pktFilterAudio = nullptr;int64_t         m_nFirstVideoPts = 0;int64_t         m_nFirstAudioPts = 0;bool            m_bTransCode = false;// stream map.int  *m_pStreamMapping;int   m_nMappingSize;};#endif // MP4RECORDER_H

mp4recorder.cpp

#include "mp4recorder.h"
#include "commondef.h"
#include "cteasyaacencoder.h"#define TRANSCODE 0mp4Recorder::mp4Recorder(QObject *parent) : QObject(parent)
{QMutexLocker guard(&m_lock);m_sRecordFile.clear();m_pIfmtCtx = nullptr;m_pOfmtCtx = nullptr;m_pOfmt = nullptr;m_pStreamMapping = nullptr;m_nMappingSize = 0;m_nCounts = 0;m_bFirstGoP = false;m_bInit = false;
}mp4Recorder::~mp4Recorder()
{DeInit();
}bool mp4Recorder::Init(AVFormatContext *pIfmtCtx, int nCodecType, int nAudioCodecType, QString &sFile)
{QMutexLocker guard(&m_lock);if(!pIfmtCtx || sFile.isEmpty()){MY_DEBUG << "sFile.isEmpty().";return false;}m_sRecordFile = sFile;m_pIfmtCtx = pIfmtCtx;QByteArray ba = m_sRecordFile.toLatin1();const char* pOutFile = ba.data();qDebug() << "pOutFile:" << pOutFile;unsigned i = 0;int ret = 0;int stream_index = 0;// 1. create output contextavformat_alloc_output_context2(&m_pOfmtCtx, nullptr, nullptr, pOutFile);if (!m_pOfmtCtx){MY_DEBUG << "Could not create output context.";ret = AVERROR_UNKNOWN;goto end;}// 2. get memory.m_nMappingSize = pIfmtCtx->nb_streams;m_pStreamMapping = (int*)av_mallocz_array(m_nMappingSize, sizeof(*m_pStreamMapping));if (!m_pStreamMapping){MY_DEBUG << "av_mallocz_array fail.";ret = AVERROR(ENOMEM);goto end;}// 3. copy steam information.m_pOfmt = m_pOfmtCtx->oformat;for (i = 0; i < pIfmtCtx->nb_streams; i++){AVStream *pOutStream;AVStream *pInStream = pIfmtCtx->streams[i];AVCodecParameters *pInCodecpar = pInStream->codecpar;if (pInCodecpar->codec_type != AVMEDIA_TYPE_AUDIO &&pInCodecpar->codec_type != AVMEDIA_TYPE_VIDEO &&pInCodecpar->codec_type != AVMEDIA_TYPE_SUBTITLE){m_pStreamMapping[i] = -1;continue;}if(pInCodecpar->codec_type == AVMEDIA_TYPE_VIDEO){m_nVideoIndex = i;//1.找到相应解码器的过滤器if(nCodecType == AV_CODEC_ID_HEVC){const AVBitStreamFilter *bsf = av_bsf_get_by_name("hevc_mp4toannexb");if (!bsf){MY_DEBUG << "av_bsf_get_by_name() video failed";return false;}//2.过滤器分配内存av_bsf_alloc(bsf, &m_pBsfc);}else{const AVBitStreamFilter *bsf = av_bsf_get_by_name("h264_mp4toannexb");if (!bsf){MY_DEBUG << "av_bsf_get_by_name() video failed";return false;}//2.过滤器分配内存av_bsf_alloc(bsf, &m_pBsfc);}//3.添加解码器属性avcodec_parameters_copy(m_pBsfc->par_in, pInCodecpar);//4. 初始化过滤器上下文av_bsf_init(m_pBsfc);}else if(pInCodecpar->codec_type == AVMEDIA_TYPE_AUDIO){m_nAudioIndex = i;#if TRANSCODEif(nAudioCodecType == AV_CODEC_ID_PCM_ALAW || nAudioCodecType == AV_CODEC_ID_PCM_MULAW){MY_DEBUG << "ctEasyAACEncoder Init";if(nAudioCodecType == AV_CODEC_ID_PCM_ALAW)ctEasyAACEncoder::getInstance().Init(Law_ALaw);elsectEasyAACEncoder::getInstance().Init(Law_ULaw);m_bTransCode = true;}elsem_bTransCode = false;#endifif(m_bTransCode || nAudioCodecType == AV_CODEC_ID_AAC){//1. 找到相应解码器的过滤器const AVBitStreamFilter *bsf = av_bsf_get_by_name("aac_adtstoasc");if (!bsf){MY_DEBUG << "av_bsf_get_by_name() audio failed";return false;}//2.过滤器分配内存av_bsf_alloc(bsf, &m_pBsfcAAC);//3.添加解码器属性avcodec_parameters_copy(m_pBsfcAAC->par_in, pInCodecpar);//4. 初始化过滤器上下文av_bsf_init(m_pBsfcAAC);}#if TRANSCODEif(m_bTransCode)m_pBsfcAAC->par_in->codec_id = AV_CODEC_ID_AAC;
#endif}// fill the stream index.m_pStreamMapping[i] = stream_index++;// copy the new codec prameters.pOutStream = avformat_new_stream(m_pOfmtCtx, nullptr);if (!pOutStream){MY_DEBUG << "Failed allocating output stream";ret = AVERROR_UNKNOWN;goto end;}ret = avcodec_parameters_copy(pOutStream->codecpar, pInCodecpar);if (ret < 0){MY_DEBUG << "Failed to copy codec parameters";goto end;}
#if TRANSCODEif(m_bTransCode && pInCodecpar->codec_type == AVMEDIA_TYPE_AUDIO)pOutStream->codecpar->codec_id = AV_CODEC_ID_AAC;
#endif//pOutStream->codecpar->bit_rate = 2000000;//pOutStream->codecpar->codec_tag = 0;}// 4. create MP4 header.if (!(m_pOfmt->flags & AVFMT_NOFILE)) // network stream{ret = avio_open(&m_pOfmtCtx->pb, pOutFile, AVIO_FLAG_WRITE);if (ret < 0){MY_DEBUG << "Could not open output file " << m_sRecordFile;goto end;}}// 5. write file header.ret = avformat_write_header(m_pOfmtCtx, nullptr);if (ret < 0){MY_DEBUG << "Error occurred when opening output file ret:" << ret;goto end;}m_pktFilter = new AVPacket;av_init_packet(m_pktFilter);m_pktFilter->data = NULL;m_pktFilter->size = 0;m_pktFilterAudio = new AVPacket;av_init_packet(m_pktFilterAudio);m_pktFilterAudio->data = NULL;m_pktFilterAudio->size = 0;m_nFirstVideoPts = 0;m_nFirstAudioPts = 0;m_bFirstGoP = false;m_bInit = true;m_nCounts = 0;return true;end:DeInit();if (ret < 0 && ret != AVERROR_EOF){MY_DEBUG << "Error occurred.";}return false;
}bool mp4Recorder::DeInit()
{// 1. save tail.if(m_bInit && m_pOfmtCtx){av_write_trailer(m_pOfmtCtx);}m_bInit = false;// 2. close outputif (m_pOfmtCtx && !(m_pOfmt->flags & AVFMT_NOFILE)){avio_closep(&m_pOfmtCtx->pb);}// 3. free contex.if(m_pOfmtCtx){avformat_free_context(m_pOfmtCtx);m_pOfmtCtx = nullptr;}av_freep(&m_pStreamMapping);if(m_pBsfc){av_bsf_free(&m_pBsfc);m_pBsfc = nullptr;}if(m_pBsfcAAC){av_bsf_free(&m_pBsfcAAC);m_pBsfcAAC = nullptr;}#if TRANSCODEif(m_bTransCode){ctEasyAACEncoder::getInstance().DeInit();m_bTransCode = false;}
#endifreturn true;
}bool mp4Recorder::saveOneFrame(AVPacket &pkt, int nCodecType, int nAudioCodecType)
{int ret = 0;if(!m_bInit){return false;}AVStream *pInStream, *pOutStream;if(nCodecType == AV_CODEC_ID_H264){if(m_bFirstGoP == false){if(pkt.flags != AV_PKT_FLAG_KEY){av_packet_unref(&pkt);return false; // first frame must be Iframe.}else{m_bFirstGoP = true;}}}pInStream  = m_pIfmtCtx->streams[pkt.stream_index];if (pkt.stream_index >= m_nMappingSize ||m_pStreamMapping[pkt.stream_index] < 0){av_packet_unref(&pkt);return true;}pkt.stream_index = m_pStreamMapping[pkt.stream_index];pOutStream = m_pOfmtCtx->streams[pkt.stream_index];if(pInStream->codecpar->codec_type != AVMEDIA_TYPE_VIDEO &&pInStream->codecpar->codec_type != AVMEDIA_TYPE_AUDIO){av_packet_unref(&pkt);return false;}if(pInStream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO){av_bsf_send_packet(m_pBsfc, &pkt);av_bsf_receive_packet(m_pBsfc, m_pktFilter);m_pktFilter->pts = av_rescale_q_rnd(m_pktFilter->pts, pInStream->time_base, pOutStream->time_base, AV_ROUND_NEAR_INF);m_pktFilter->dts = av_rescale_q_rnd(m_pktFilter->dts, pInStream->time_base, pOutStream->time_base, AV_ROUND_NEAR_INF);m_pktFilter->duration = av_rescale_q_rnd(m_pktFilter->duration, pInStream->time_base, pOutStream->time_base, AV_ROUND_NEAR_INF);m_pktFilter->stream_index = pOutStream->index;//时间戳处理if(m_nFirstVideoPts == 0){m_nFirstVideoPts = m_pktFilter->pts;m_pktFilter->pts = 0;m_pktFilter->dts = 0;}else{m_pktFilter->pts = m_pktFilter->pts - m_nFirstVideoPts;m_pktFilter->dts = m_pktFilter->dts - m_nFirstVideoPts;}//av_packet_rescale_ts(&pkt, pInStream->time_base, pOutStream->time_base);m_pktFilter->pos = -1;m_pktFilter->flags |= AV_PKT_FLAG_KEY;ret = av_interleaved_write_frame(m_pOfmtCtx, m_pktFilter);av_packet_unref(&pkt);if (ret < 0){qDebug() << "Video Error muxing packet";}}else{
#if TRANSCODEif(m_bTransCode){AVPacket* pAACPkt = av_packet_clone(&pkt);if(ctEasyAACEncoder::getInstance().G711ToAAC(pkt.data, pkt.size, pAACPkt->data, pAACPkt->size) == false){av_packet_unref(&pkt);return false;}av_bsf_send_packet(m_pBsfcAAC, pAACPkt);av_bsf_receive_packet(m_pBsfcAAC, m_pktFilterAudio);}else
#endifif(m_bTransCode || nAudioCodecType == AV_CODEC_ID_AAC){av_bsf_send_packet(m_pBsfcAAC, &pkt);av_bsf_receive_packet(m_pBsfcAAC, m_pktFilterAudio);m_pktFilterAudio->pts = av_rescale_q_rnd(m_pktFilterAudio->pts, pInStream->time_base, pOutStream->time_base, AV_ROUND_NEAR_INF);m_pktFilterAudio->dts = av_rescale_q_rnd(m_pktFilterAudio->dts, pInStream->time_base, pOutStream->time_base, AV_ROUND_NEAR_INF);m_pktFilterAudio->duration = av_rescale_q_rnd(m_pktFilterAudio->duration, pInStream->time_base, pOutStream->time_base, AV_ROUND_NEAR_INF);m_pktFilterAudio->stream_index = pOutStream->index;//用差值作时间戳if(m_nFirstAudioPts == 0){m_nFirstAudioPts = m_pktFilterAudio->pts;m_pktFilterAudio->pts = 0;m_pktFilterAudio->dts = 0;}else{m_pktFilterAudio->pts = m_pktFilterAudio->pts - m_nFirstAudioPts;m_pktFilterAudio->dts = m_pktFilterAudio->dts - m_nFirstAudioPts;}m_pktFilterAudio->pos = -1;m_pktFilterAudio->flags |= AV_PKT_FLAG_KEY;ret = av_interleaved_write_frame(m_pOfmtCtx, m_pktFilterAudio);}else{pkt.pts = av_rescale_q_rnd(pkt.pts, pInStream->time_base, pOutStream->time_base, AV_ROUND_NEAR_INF);pkt.dts = av_rescale_q_rnd(pkt.dts, pInStream->time_base, pOutStream->time_base, AV_ROUND_NEAR_INF);pkt.duration = av_rescale_q_rnd(pkt.duration, pInStream->time_base, pOutStream->time_base, AV_ROUND_NEAR_INF);pkt.stream_index = pOutStream->index;//用差值作时间戳if(m_nFirstAudioPts == 0){m_nFirstAudioPts = pkt.pts;pkt.pts = 0;pkt.dts = 0;}else{pkt.pts = pkt.pts - m_nFirstAudioPts;pkt.dts = pkt.dts - m_nFirstAudioPts;}pkt.pos = -1;pkt.flags |= AV_PKT_FLAG_KEY;ret = av_interleaved_write_frame(m_pOfmtCtx, &pkt);}av_packet_unref(&pkt);if (ret < 0){qDebug() << "Audio Error muxing packet";}}return (ret == 0);
}

四、ffmpeg库下载

链接地址:https://download.csdn.net/download/linyibin_123/87542123

相关文章:

qt下ffmpeg录制mp4经验分享,支持音视频(h264、h265,AAC,G711 aLaw, G711muLaw)

前言 MP4&#xff0c;是最常见的国际通用格式&#xff0c;在常见的播放软件中都可以使用和播放&#xff0c;磁盘空间占地小&#xff0c;画质一般清晰&#xff0c;它本身是支持h264、AAC的编码格式&#xff0c;对于其他编码的话&#xff0c;需要进行额外处理。本文提供了ffmpeg录…...

C#读取Excel解析入门-1仅围绕三个主要的为阵地,进行重点解析,就是最理性的应对上法所在

业务中也是同样的功能点实现。只是多扩展了很多代码&#xff0c;构成了项目的其他部分&#xff0c;枝干所在。但是有用的枝干&#xff0c;仅仅不超过三个主要的&#xff01;所以您仅仅围绕三个主要的为阵地&#xff0c;进行重点解析&#xff0c;就是最理性的应对上法所在了 str…...

一起Talk Android吧(第五百一十八回:在Android中使用MQTT通信五)

文章目录 知识回顾问题描述解决过程经验分享各位看官们大家好,这一回中咱们说的例子是" 在Android中使用MQTT通信五",本章回内容与前后章节内容无关联。闲话休提,言归正转,让我们一起Talk Android吧! 知识回顾 我们在前面章回中介绍了如何使用MQTT通信,包含它…...

100种思维模型之混沌与秩序思维模型-027

人类崇尚秩序与连续性&#xff0c;我们习惯于我们的日常世界&#xff0c;它以线性方式运作&#xff0c;没有不连续或突跳。 为此&#xff0c;我们学会了期望各种过程以连续方式运行&#xff0c;我们的内心为了让我们更有安全感&#xff0c;把很多事物的结果归于秩序&#xff0c…...

Java开发 - Redis初体验

前言 es我们已经在前文中有所了解&#xff0c;和es有相似功能的是Redis&#xff0c;他们都不是纯粹的数据库。两者使用场景也是存在一定的差异的&#xff0c;本文目的并不重点说明他们之间的差异&#xff0c;但会简要说明&#xff0c;重点还是在对Redis的了解和学习上。学完本…...

Python - 使用 pymysql 操作 MySQL 详解

目录创建连接 pymsql.connect() 方法的可传参数连接对象 conn pymsql.connect() 方法游标对象 cursor() 方法使用示例创建数据库表插入数据操作数据查询操作数据更新操作数据删除操作SQL中使用变量封装使用简单使用&#xff1a; import pymysqldb pymysql.connect(host,user…...

机器学习-卷积神经网络CNN中的单通道和多通道图片差异

背景 最近在使用CNN的场景中&#xff0c;既有单通道的图片输入需求&#xff0c;也有多通道的图片输入需求&#xff0c;因此又整理回顾了一下单通道或者多通道卷积的差别&#xff0c;这里记录一下探索过程。 结论 直接给出结论&#xff0c;单通道图片和多通道图片在经历了第一…...

考研复试——计算机组成原理

文章目录计算机组成原理1. 计算机系统由哪两部分组成&#xff1f;计算机系统性能取决于什么&#xff1f;2. 冯诺依曼机的主要特点&#xff1f;3. 主存储器由什么组成&#xff0c;各部分有什么作用&#xff1f;4. 什么是存储单元、存储字、存储字长、存储体&#xff1f;5. 计算机…...

硬件设计 之摄像头分类(IR摄像头、mono摄像头、RGB摄像头、RGB-D摄像头、鱼眼摄像头)

总结一下在机器人上常用的几种摄像头&#xff0c;最近在组装机器人时&#xff0c;傻傻分不清摄像头的种类。由于本人知识有限&#xff0c;以下资料都是在网上搜索而来&#xff0c;按照摄像头的分类整理一下&#xff0c;供大家参考&#xff1a; 1.IR摄像头&#xff1a; IRinfr…...

PTA:C课程设计(2)

山东大学&#xff08;威海&#xff09;2022级大一下C习题集&#xff08;2&#xff09;2-5-1 字符定位函数&#xff08;程序填空题&#xff09;2-5-2 判断回文&#xff08;程序填空题&#xff09;2-6-1 数字金字塔(函数)2-6-2 使用函数求最大公约数(函数)2-6-3 使用函数求余弦函…...

第四章:面向对象编程

第四章&#xff1a;面向对象编程 4.1&#xff1a;面向过程与面向对象 面向过程(POP)与面向对象(OOP) 二者都是一种思想&#xff0c;面向对象是相对于面向过程而言的。面向过程&#xff0c;强调的是功能行为&#xff0c;以函数为最小单位&#xff0c;考虑怎么做。面向对象&…...

Linux 安装npm yarn pnpm 命令

下载安装包 node 下载地址解压压缩包 tar -Jxf node-v19.7.0-linux-x64.tar.xz -C /root/app echo "export PATH$PATH:/app/node-v16.9.0-linux-x64" >> /etc/profile source /etc/profile ln -sf /app/node-v16.9.0-linux-x64/bin/npm /usr/local/bin/ ln -…...

linux SPI驱动代码追踪

一、Linux SPI 框架概述 linux系统下的spi驱动程序从逻辑上可以分为3个部分: SPI Core&#xff1a;SPI Core 是 Linux 内核用来维护和管理 spi 的核心部分&#xff0c;SPI Core 提供操作接口&#xff0c;允许一个 spi master&#xff0c;spi driver 和 spi device 在 SPI Cor…...

Ls-dyna材料的相关学习笔记

Elastic Linear elastic materials -Isotropic:各向同性材料 -orthotropic 正交各向异性的 -anistropic 各向异性的...

Arrays方法(copyOfRange,fill)

Arrays方法 1、Arrays.copyOfRange Arrays.copyOfRange的使用方法 功能&#xff1a; 将数组拷贝至另外一个数组 参数&#xff1a; original&#xff1a;第一个参数为要拷贝的数组对象 from&#xff1a;第二个参数为拷贝的开始位置&#xff08;包含&#xff09; to&#xff1a;…...

AcWing - 蓝桥杯集训每日一题(DAY 1——DAY 5)

文章目录一、AcWing 3956. 截断数组&#xff08;中等&#xff09;1. 实现思路2. 实现代码二、AcWing 3729. 改变数组元素&#xff08;中等&#xff09;1. 实现思路2. 实现代码三、AcWing 1460. 我在哪&#xff1f;&#xff08;简单&#xff09;1. 实现思路2. 实现代码四、AcWin…...

RHCSA-文件的其他命令(3.7)

目录 文件的其他命令&#xff1a; 文本内容统计wc 移动和复制&#xff08;cp&#xff09; 移动 查找文件的路径 压缩和解压缩 .tar&#xff08;归档命令&#xff09; shell-命令解释器 linux中的特殊字符 查看系统上的别名&#xff1a;alias 历史命令&#xff08;his…...

多线程update导致的mysql死锁问题处理方法

最近想起之前处理过的一个mysql 死锁问题&#xff0c;是在高并发下update批量更新导致的&#xff0c;这里探讨一下发生的原因&#xff0c;以及解决办法&#xff1b; 发生死锁的sql语句如下&#xff0c;其中where条件后的字段是有复合索引的。 update t_push_message_device_h…...

SpringBoot 如何保证接口安全?

为什么要保证接口安全对于互联网来说&#xff0c;只要你系统的接口暴露在外网&#xff0c;就避免不了接口安全问题。 如果你的接口在外网裸奔&#xff0c;只要让黑客知道接口的地址和参数就可以调用&#xff0c;那简直就是灾难。举个例子&#xff1a;你的网站用户注册的时候&am…...

英伟达驱动爆雷?CPU占用率过高怎么办?

又有一新驱动导致CPU占用率过高&#xff1f; 上周英伟达发布531.18显卡驱动&#xff0c;为大家带来了视频超分辨率技术&#xff0c;并为新发布的热门游戏《原子之心》提供支持。 但在安装新驱动后没过不久就有玩家反映&#xff0c;在游戏结束后会出现CPU占用率突然飙升到10%以…...

链表经典面试题【典中典】

&#x1f4af;&#x1f4af;&#x1f4af;链表经典面试题❗❗❗炒鸡经典&#xff0c;本篇带有图文解析&#xff0c;建议动手刷几遍。&#x1f7e5;1.反转链表&#x1f7e7;2.合并两个有序链表&#x1f7e8;3.链表分割&#x1f7e9;4.链表的回文结构&#x1f7e6;5.相交链表&…...

Java泛型深入

一. 泛型的概述和优势 泛型概述 泛型&#xff1a;是JDK5中引入的特性&#xff0c;可以在编译阶段约束操作的数据类型&#xff0c;并进行检查。泛型的格式&#xff1a;<数据类型>&#xff0c;注意&#xff1a;泛型只能支持引用数据类型。集合体系的全部接口和实现类都是…...

体验Linux USB 驱动

目录 一、USB OTG 二、I.MX6ULL USB 接口简介 硬件原理图 1、USB HUB 原理图 2 、USB OTG 原理图 三、使能驱动 1、打开 HID 驱动 2、 使能 USB 键盘和鼠标驱动 3 、使能 Linux 内核中的 SCSI 协议 4、使能 U 盘驱动 四、测试u盘 五、 Linux 内核自带 USB OTG USB 是…...

servlet 中的ServletConfig与servletContext

ServletConfig对象&#xff1a;servlet配置对象&#xff0c;主要把servlet的初始化参数封装到这个对象中。 一个网站中可能会存在多个servletConfig对象&#xff0c;一个servletConfig对象就封装了一个servlet的配置信息。 可以在web.xml中通过<init-param></init-p…...

Hadoop3.1.3单机(伪分布式配置)

参考&#xff1a;林子雨老师网站博客 Hadoop安装搭建伪分布式教程&#xff08;全面&#xff09;吐血整理 环境 Vmare12 Ubuntu16.04 创建Hadoop用户 若安装Ubuntu不是用的“hadoop”用户&#xff0c;则需要增加一个名为"hadoop"的用户 直接快捷键ctrlaltt或者点…...

HBase---浅谈HBase原理

浅谈HBase原理 文章目录浅谈HBase原理HBase定义HBase逻辑结构HBase物理存储结构TimeStampType数据模型NaneSpaceRegionRowColumnTineStampCellHBase架构MasterMaster 架构Meta 表格介绍Region ServerRegionServer 架构MemStoreWALBlockCacheZookeeperHDFSHBase写数据流程HBase读…...

学习笔记四:dockerfile

Dockerfile概述dockerfile语法详解FROMMAINTAINERRUN&#xff1a;指定在当前镜像构建过程中要运行的命令EXPOSE指令CMDENTERYPOINTCOPYADDVOLUMEWORKDIRENVUSERONBUILDLABELHEALTHCHECKARG概述 Dockerfile 是一个用来构建镜像的文本文件&#xff0c;文本内容包含了一条条构建镜…...

微服务里的小问题

1.微服务为什么设置不同的namespace 为了实现三种服务三种情况下的隔离。 2.为什么要用nginx为naocos集群结点做负载均衡&#xff1f; 2.1 正向代理 就像我们访问外网需要一个代理。 2.2 反向代理 我们不需要访问真实的ip&#xff0c;只需要访问 这个服务的代理服务器即可&a…...

数据库之基本功:Where 中常用运算符

1. 运算符及优先级 ( )优先级最高 SQL> show user; USER is "SCOTT" SQL> select ename, job, sal, comm from emp where jobSALESMAN OR jobPRESIDENT and sal> 1500;ENAME JOB SAL COMM …...

浅谈 Nodejs原型链污染

一直在做php的题目&#xff0c;对其它语言做的很少。刚好在西湖论剑2022复现时&#xff0c;遇到了一道原型链污染的题目&#xff0c;借此机会开始简单学习一下 Nodejs的洞 p&#x1f402;讲解的十分清楚&#xff0c;因此下面举例子就直接用p&#x1f402;的例子进行解释了 目…...

django做网站比较容易/鞋子软文推广300字

精选30云产品&#xff0c;助力企业轻松上云&#xff01;>>> 践行精细美 用心去打造&#xff0c;初心本次带来 LTSB|1709|1809|LTSC 四版集合八合一&#xff0c;精选这几个比较经典的版本集合到一起&#xff0c;一个ISO可以拥有4个不同版本的系统&#xff0c;节省了不…...

title 门户网站建设招标书/关键词优化技巧有哪些

之前在介绍使用JdbcTemplate和Spring-data-jpa时&#xff0c;都使用了单数据源。在单数据源的情况下&#xff0c;Spring Boot的配置非常简单&#xff0c;只需要在application.properties文件中配置连接参数即可。但是往往随着业务量发展&#xff0c;我们通常会进行数据库拆分或…...

做的网站.如何在局域网内访问/无锡百姓网推广

昨天开始接到用户提报&#xff0c;说是iprocess没有同步个人账号。这个简单&#xff0c;在我们本身的程序上跑一下就可以添加。所以很简单运行一下。com.staffware.sso.data.vException: SAL system error what&#xff1f;报错了&#xff1f;我晕&#xff0c;当时简单的认为&a…...

做pc端网站适配/网站运营主要做什么工作

分享一下我老师大神的人工智能教程&#xff01;零基础&#xff0c;通俗易懂&#xff01;http://blog.csdn.net/jiangjunshow也欢迎大家转载本篇文章。分享知识&#xff0c;造福人民&#xff0c;实现我们中华民族伟大复兴&#xff01;1&#xff0e; Kafka整体结构图Kafka名词解释…...

上虞中国建设银行官网站/百度公司

作为一名工程师&#xff0c;一名做技术的工程师&#xff0c;NUMA也是我的近期工作重点之一。在工作时间&#xff0c;在茶余饭后&#xff0c;也看了些NUMA的资料&#xff0c;学习了英特尔下一代Xeon处理器。这里就是我的一点小结&#xff0c;一点心得&#xff0c;和感兴趣的朋友…...

哪个行业最容易做网站/哪些平台可以免费打广告

以下信件于2月7日由Provost Martin A. Schmidt发送给麻省理工学院社区。对麻省理工学院社区的成员&#xff1a;2018年10月&#xff0c;麻省理工学院宣布成立麻省理工学院斯蒂芬A.施瓦茨曼计算学院。该学院旨在建立一个共享的学术结构&#xff0c;以促进计算奖学金和资源与麻省理…...