- 博客(318)
- 收藏
- 关注
原创 揭秘YUV:为何人眼被“欺骗”却浑然不觉
YUV是一种基于人眼特性的图像编码方式,将图像分为亮度(Y)和色度(U/V)分量。人眼对亮度更敏感(视杆细胞),而对色度敏感度较低(视锥细胞)。通过色度降采样(如4:2:0格式),每2×2像素共用一组UV值,可在保持视觉质量的同时减少50%-70%数据量。这种设计广泛应用于视频、直播等场景,既保证清晰度又节省带宽,是典型的工程优化方案。
2025-12-21 11:24:30
447
原创 通用音频系统全链路实战指南
本文系统阐述了通用音频系统的核心原理与技术实现。重点解析了音频处理全链路:1)PCM作为系统内部通用语言,WAV用于本地存储,MP3/AAC用于网络传输;2)采样率/位深/声道必须统一处理;3)音频帧与包的区别及其在实时传输中的作用;4)完整编码流程包含分帧、频域分析、心理声学建模等关键步骤;5)重采样和混音是直播系统的必经环节;6)主流编码格式AAC和Opus的适用场景。文章最终整合了从采集到播放的完整音频处理链路,并提炼出"系统处理PCM、网络传输编码流"的工程本质。
2025-12-20 17:14:01
605
原创 音频工程实战:7大场景与核心格式解析
音频处理工程实践摘要 本文系统梳理了音频处理在工程实践中的核心应用场景与技术选型。PCM作为基础格式贯穿所有音频处理流程,是解码后、播放前的必经环节。AAC凭借高音质、低延迟特性成为在线播放、直播和视频音轨的主流选择,MP3因兼容性强仍用于本地音乐存储。工程实践中,WAV格式常用于调试阶段保存原始音频数据,便于问题排查。音频处理必须在PCM层面进行,不可直接操作压缩格式。典型工程架构以PCM为核心,外围对接各类编解码器和处理模块。开发调试时,将问题PCM转为WAV格式直接播放是工程师的关键排障手段。
2025-12-20 16:41:00
768
原创 采样率,采样位数,声道数
数字音频三大核心参数解析:采样率决定声音细节还原度(如44.1kHz覆盖人耳极限),采样位数影响动态范围和底噪(16bit=CD音质),声道数决定空间感(立体声最常见)。三者共同决定音频质量与文件大小,标准搭配如音乐用44.1kHz/16bit/立体声。简单说:采样率管"细不细",位数管"准不准",声道管"从哪来"。(149字)
2025-12-20 16:37:05
700
原创 STL-适配器(面试复习4)
本文整理了C++ STL适配器的高频面试题,涵盖基础概念、容器适配器、算法复杂度等核心内容。适配器不是新组件,而是对已有容器/迭代器/函数对象的接口封装,分为容器适配器(stack/queue/priority_queue)、迭代器适配器和函数适配器三类。重点包括:stack/queue默认使用deque作底层容器;priority_queue基于vector实现堆结构;适配器不提供迭代器以维护数据结构语义;priority_queue的时间复杂度;实现小顶堆的方法等。文章还对比了push/emplace操
2025-12-20 16:15:52
925
原创 音频格式全解析:PCM到AAC
C++音视频开发核心概念解析:文章系统介绍了音频处理中的关键格式和关系。基础是PCM原始音频数据,具有无压缩、高质量特点;WAV作为PCM的容器格式添加了文件头;MP3和AAC则是有损压缩格式,分别适用于普通和高品质音频场景。文中通过对比表格清晰展示了各格式特性差异,并梳理了从原始声音到压缩编码的处理流程。这些知识是使用FFmpeg等工具进行音频采集、处理和播放的基础,对音视频开发学习具有重要指导意义。
2025-12-19 13:38:23
815
原创 音视频C++开发进阶指南
摘要: 音视频C++开发岗位需掌握核心基础(音频/视频原理、FFmpeg框架及API、数据处理能力),进阶能力(实时音视频协议、WebRTC技术、播放器/推流器开发)是大厂考察重点,高阶加分项包括性能优化、跨平台工程能力及编码算法。推荐分三阶段学习:1.基础与FFmpeg实战;2.实时协议与流媒体开发;3.WebRTC与性能优化。掌握这些技能可显著提升竞争力,尤其针对腾讯、字节等大厂岗位。
2025-12-19 13:13:51
929
原创 Qt多线程阻塞:为何信号失效?
Qt多线程编程中,事件循环机制是核心。当子线程进入while循环执行密集任务时,会阻塞事件循环的执行,导致无法处理QueuedConnection信号。主线程直接调用或使用原子变量可以绕过事件队列,实现即时控制。这解释了为什么在密集型计算场景下,需要采用原子变量等"硬控制"方式,而非依赖异步信号机制。
2025-12-18 22:38:08
397
原创 WebSocket与Webhook:实时通信技术对比
WebSocket和Webhook是两种不同的实时通信机制。WebSocket通过全双工长连接实现双向实时通信,适合高频交互场景如在线聊天和实时监控。Webhook采用事件驱动的HTTP回调,由服务端单向推送事件通知,适用于支付回调等业务场景。核心区别在于:WebSocket保持持久连接,支持双向通信;Webhook基于短连接,仅单向推送。选择依据取决于实时性要求、交互频率和系统架构需求,高频双向交互选WebSocket,事件通知类业务选Webhook更合适。
2025-12-18 11:52:33
521
1
原创 STL-关联容器(面试复习4)
STL关联容器分为有序和无序两类:有序容器(map/set等)基于红黑树,查找复杂度O(logN);无序容器(unordered_map/unordered_set等)基于哈希表,平均O(1)但最坏O(N)。关键区别在于有序性、复杂度保证和自定义要求(如排序规则或哈希函数)。使用场景取决于是否需要有序访问、性能要求及key类型特性。常见操作如operator[]可能隐式插入,而find/count等则不会。迭代器稳定性、元素修改限制和高效更新策略也是重要考量。此外,自定义排序和哈希支持、时间复杂度的权衡以及
2025-12-18 11:35:55
616
原创 音频同步:从假时钟到真时钟的蜕变
摘要: 音频同步的关键在于区分"塞入数据"与"实际播放"。旧代码错误地将写入缓冲区的数据视为已播放(类似刚倒水入水管就认为水流完),导致Seek后视频疯狂追赶音频。新代码通过查询声卡实际播放时长(类似水管出口装水表),实现音视频精准同步。这种以硬件实际输出为基准的同步方式,正是FFmpeg/VLC等播放器的行业标准解决方案,从"虚拟计时"升级为"真实物理时钟"。(149字) 核心对比: ❌旧逻辑:播放时间=写入缓冲区的时间 ✅新
2025-12-17 16:13:46
587
原创 Modbus TCP关键知识点回顾
摘要:本文系统讲解ModbusTCP协议核心要点,包括协议本质(基于TCP/IP的Modbus)、4种数据模型(线圈/离散输入/输入寄存器/保持寄存器)和报文结构(7字节MBAP头+PDU)。重点解析功能码使用(03/10最常用)、地址偏移计算(40001对应地址0)和TCP特性(无CRC校验)。通过实际报文示例展示读写操作流程,并强调工程实践中90%问题源于地址偏移、数据类型和字节序处理。关键记忆点:ModbusTCP=7字节MBAP+功能码+数据(大端格式)。
2025-12-16 13:13:36
586
原创 Qt 多线程编程: moveToThread 模式讲解
Qt多线程编程推荐使用"Worker-Object"模式,通过moveToThread方法实现。相比继承QThread的传统做法,该模式能确保Worker对象的所有槽函数在子线程执行,避免线程安全问题。关键步骤包括:创建继承QObject的Worker类、实例化QThread、调用moveToThread、连接信号槽后启动线程。需注意不要在Worker构造函数中创建对象,应在init槽函数中分配资源。线程退出时通过信号槽机制实现优雅的资源释放。对于简单任务可使用QtConcurrent:
2025-12-12 22:13:16
686
原创 STL-list面试剖析(面试复习4)
摘要: 本文解析C++中std::list的核心特性与使用场景。底层实现为双向链表,与std::vector相比,list支持O(1)任意位置插入/删除但无随机访问,内存不连续导致缓存命中率低。迭代器失效规则严格:仅被删除节点迭代器失效,遍历时需用erase返回值更新迭代器或C++20的erase_if。内存开销较大,每个元素需额外16字节指针(64位系统)。特殊操作包括成员函数sort()(归并排序)和O(1)的splice(节点转移)。单向链表std::forward_list更节省内存但功能受限。应用
2025-12-12 10:48:03
945
原创 STL-deque面试剖析(面试复习4)
摘要:2025年C++ STL deque高频面试题解析,涵盖7个核心问题:1) deque分段连续内存与中控器原理;2) 与vector在内存布局、扩容机制等关键差异;3) 作为stack/queue默认容器的优势;4) 迭代器失效规则(两端插入不失效);5) 相比vector的性能取舍;6) 与list的适用场景对比;7) 缓冲区大小的实现相关特性。重点剖析了deque"分段连续"的底层设计及其在首尾操作、随机访问方面的独特优势,同时指出其缓存局部性不如vector的局限性。(149
2025-12-11 10:58:53
482
原创 面向对象 (OOP)(面试复习3)
本文系统讲解了C++面向对象三大特性及虚函数实现原理。首先通过生活实例通俗解释封装、继承和多态概念。重点剖析了虚函数机制,包括vtable/vptr实现原理、虚析构函数必要性、纯虚函数与抽象类等核心问题。详细区分了重载、重写和隐藏三种函数关系,并解答了虚继承解决菱形继承问题的原理。最后总结了三种继承方式的权限变化规律,建议面试重点掌握虚函数内存模型和构造/析构函数的虚函数特性。全文深入浅出,直击C++面向对象编程的核心难点与面试要点。
2025-12-08 10:57:14
761
原创 C++ 内存管理与编译原理 (面试复习2)
本文摘要: C++内存管理核心知识总结:1)内存布局分为栈、堆、全局/静态区、常量区和代码区,重点掌握堆栈区别;2)内存分配详解new/malloc差异、delete/delete[]使用场景、内存泄漏检测工具及内存对齐原理;3)编译链接过程包含预处理、编译、汇编、链接四阶段,并对比静态/动态链接特性。建议通过Valgrind检测内存泄漏、查看预处理和汇编代码来加深理解。全文系统梳理了C++内存管理的核心概念和技术要点。
2025-12-03 23:45:09
778
原创 Qt处理tcp数据 粘包 拆包 的简单方法
摘要:C++Qt上位机开发中TCP通信采用流式传输,存在粘包和拆包问题。文章提出三种解决方案:固定长度、特殊分隔符和包头+包体协议(推荐)。重点介绍了基于Qt的实现方法:使用QByteArray作为缓冲区,通过解析包头长度循环处理完整数据包。代码示例展示了网络字节序处理、安全性检查等关键环节,并针对性能优化和异常处理给出建议。核心在于明确定义通信协议,通过缓冲区管理和包头解析实现可靠的数据包分割。
2025-12-03 23:26:05
753
原创 哈希-力扣hot100-128.最长连续序列
本文提出了一种使用哈希表高效求解最长连续序列的算法。通过将数组元素存入unordered_set实现去重和O(1)时间查找,算法仅从可能的序列起点(即x-1不存在的元素x)开始向后扩展,统计连续序列长度。这种方法避免了重复计算,确保每个元素最多被访问两次,从而实现O(n)时间复杂度和O(n)空间复杂度。C++实现代码展示了具体操作流程,包括集合构建、起点判断和连续序列扩展等关键步骤。
2025-12-03 10:12:58
367
原创 C++ 语言基础(面试复习1)
本文摘要:C++核心概念解析 指针与引用 指针存储地址,引用是别名;引用必须初始化且不可变 野指针产生原因及防范措施 nullptr解决NULL的二义性问题 关键字解析 const修饰变量、指针、函数的不同作用 static的三种应用场景 volatile与atomic的区别 extern "C"的作用机制 inline函数与宏定义的差异 sizeof与strlen的本质区别 类型转换 四种强制转换的使用场景 dynamic_cast基于RTTI的实现原理 类型安全转换的最佳实践 (共1
2025-12-02 11:44:53
739
原创 深度剖析 emplace / push !!!
本文对比了C++中所有权移交(Move/Copy)和原地构造(Emplace/Push)的区别。在任务队列场景中,push和emplace行为相似,关键区别在于是否使用std::move:带move会转移所有权(原件失效),不带move则保留副本。在对象容器场景中,emplace_back直接传入构造参数实现原地构造,比push_back(需先构造临时对象再移动)更高效。核心要点:std::move决定资源转移方式,emplace/push决定构造方式,应根据实际需求选择合适方法。
2025-12-01 11:49:22
226
原创 链表-力扣hot100-LRU缓存-146
本文介绍了一种使用哈希表和双向链表实现LRU缓存的方案。通过std::unordered_map实现O(1)查找,std::list实现O(1)的节点移动和删除。链表头部存储最近使用数据,尾部存储最久未使用数据。当缓存满时,优先淘汰尾部数据。哈希表存储key到链表迭代器的映射,可直接定位节点位置。使用list::splice函数在O(1)时间内移动节点,实现高效访问顺序更新。该方案完美满足LRU缓存的O(1)时间复杂度要求,同时利用STL容器自动管理内存,保证代码简洁安全。
2025-11-30 09:39:38
411
原创 STL适配器高频考点
STL适配器是C++标准库中用于改变现有组件接口的设计模式,主要分为三类:容器适配器(stack/queue/priority_queue)、迭代器适配器(如back_inserter)和函数适配器(如std::bind)。容器适配器通过封装底层容器(默认stack/queue用deque,priority_queue用vector)实现特定数据结构特性;迭代器适配器扩展迭代器功能;函数适配器则用于参数绑定和函数组合。重点包括:stack/queue为何无迭代器(保证数据结构语义)、priority_que
2025-11-26 11:37:17
798
原创 链表-力扣hot-合并K个升序链表-23
本文介绍了合并K个有序链表的高效解法。推荐使用优先队列(最小堆)方法,其时间复杂度为O(Nlogk),空间复杂度为O(k)。算法核心是维护一个包含各链表当前节点的最小堆,每次取出最小值节点,并将其后继节点重新入堆。这种方法充分利用了输入链表的升序特性,避免了完全重新排序,具有较好的扩展性。文章提供了完整的C++实现代码,包括自定义比较器和哑节点处理技巧,适用于处理大规模数据合并问题。
2025-11-26 10:45:23
306
原创 C++中std::sort和std::priority_queue的排序逻辑对比
C++中std::sort和std::priority_queue的排序逻辑对比:std::sort返回true表示元素应排在前面(a>b为降序,a<b为升序),而priority_queue返回true表示元素优先级低应沉底(a>b形成小顶堆输出升序,a<b形成大顶堆输出降序)。关键区别在于sort的true表示"排前面",priority_queue的true表示"沉底"。记忆口诀:sort谁true谁在前,priority_queue谁t
2025-11-26 09:40:08
355
原创 链表-力扣hot100-排序链表-148
本文介绍了使用归并排序算法解决链表排序问题的方法。针对大规模数据(节点数达5×10⁴),归并排序因其O(NlogN)的时间复杂度成为最优选择。算法采用分治思想:首先通过快慢指针找到中点并断开链表,然后递归排序左右两部分,最后合并两个有序链表。实现中使用了哨兵节点简化合并操作。该算法时间复杂度为O(NlogN),空间复杂度为O(logN)(递归栈空间)。这种方法特别适合链表结构,避免了随机访问的需求。
2025-11-26 09:11:48
282
原创 Qt事件循环队列剖析!!!
本文主要介绍了Qt框架中事件(Event)与信号(Signal)的区别及工作机制。事件是系统向对象发送的消息,信号是对象发出的通知。Qt程序的核心是事件循环,它不断从系统获取消息并分发给相应控件。文章详细解析了鼠标点击事件的完整流程:从系统消息→QMouseEvent→事件过滤器→控件事件处理→信号发送→槽函数调用。最后介绍了两种拦截事件的方法:重写控件事件函数或使用事件过滤器(eventFilter)。全文以通俗易懂的方式阐述了Qt事件处理机制的关键要点。
2025-11-25 11:27:08
758
原创 链表-力扣hot100-随机链表的复制138
用很白话的话说,这题就是:有一条「很特别的链表」,每个节点不止有 next(下一个),还有一个 random(随便指向谁)。你要,但:新链表里的每个节点,都是(不能直接用原来的节点)新链表的结构(next 链接)要和原来一模一样新链表里的 random 关系也要和原来一模一样比如:原来 A.random 指向 B,那新链表里的 a.random 就要指向 bnext:正常链表的下一个random:可以指向链表里的任意一个节点或者是null不能只复制数值和指针引用到原节点,那叫“浅拷贝”
2025-11-25 10:39:13
298
原创 Qt面试题day01
本文摘要: Qt核心机制解析涵盖五大技术要点:1)信号与槽基于观察者模式实现,通过MOC生成元数据实现解耦;2)元对象系统通过MOC预处理实现C++反射功能;3)对象树通过父子关系自动管理内存;4)事件系统处理底层输入事件;5)QML与C++交互通过Q_PROPERTY和注册机制实现。文章详细分析了各机制原理、应用场景及注意事项,特别强调多线程环境下的安全实现,并提供了性能优化建议和常见问题解决方案,为Qt开发者提供了深入的技术参考。
2025-11-24 14:20:48
848
原创 力扣hot100 - K 个一组翻转链表 - 25
本文介绍了一种迭代法解决LeetCode25题"K个一组翻转链表"的方案。算法核心思想是将链表分割成长度为k的子链表组,依次翻转每个子链表后重新连接。通过使用虚拟头节点简化边界处理,算法实现了O(N)时间复杂度和O(1)额外空间复杂度。文章详细阐述了翻转步骤:检查节点数、切断子链表、翻转、重新连接,并提供了C++代码实现和具体示例的图解说明。该方案有效解决了链表分组翻转问题,特别适合处理大规模数据时的性能要求。
2025-11-24 10:58:44
343
原创 力扣hot100 - 两两交换链表中的节点 - 24
本文介绍了使用虚拟头节点迭代法实现链表节点两两交换的算法。通过创建dummyHead简化头节点处理,使用temp指针遍历链表,当后续存在两个节点时进行交换:先调整temp指向,再处理节点间的连接关系。算法时间复杂度O(N),空间复杂度O(1),适用于任意长度的链表交换操作。
2025-11-23 09:36:32
443
原创 力扣hot100 - 删除链表的倒数第 N 个结点 - 19
本文介绍了删除链表倒数第N个节点的双指针解法。通过引入虚拟头结点统一处理边界情况,使用快慢指针实现一次遍历:快指针先走N步,然后与慢指针同步移动,当快指针到达末尾时,慢指针正好位于目标节点的前驱位置。该方法时间复杂度O(L),空间复杂度O(1),高效解决了链表操作中的经典问题,尤其适合处理删除头节点等特殊情况。
2025-11-23 09:06:36
339
原创 力扣hot100 - 两数相加 - 2
本文介绍了链表相加问题的解决方案。使用哨兵节点简化操作,通过模拟竖式加法逐位计算。关键点包括:1)使用虚拟头节点避免空指针处理;2)短链表补零确保同步遍历;3)循环条件需包含进位检查以防遗漏。算法时间复杂度为O(max(M,N)),空间复杂度O(1)。代码展示了完整的C++实现,包括链表遍历、进位处理和内存释放等细节。
2025-11-23 08:41:16
298
原创 力扣hot100 - 合并两个有序链表21
本文实现了一个合并两个有序链表的算法。通过使用哨兵节点(dummy)简化边界条件处理,算法比较两个链表的当前节点值,将较小值的节点连接到结果链表尾部。当任一链表遍历完后,直接将剩余部分链接到结果链表。时间复杂度为O(n+m),空间复杂度为O(1)。代码包含完整的测试用例和内存管理辅助函数,展示了如何创建、打印和释放链表,并提供了三个测试示例验证算法正确性。
2025-11-22 11:45:14
173
原创 力扣hot100-环形链表(2)142
摘要:本文介绍了使用快慢指针法(Floyd判圈算法)检测链表中环的存在并确定环入口的解法。通过设置快慢两个指针,快指针每次走两步,慢指针走一步,当两者相遇时表明存在环。根据数学推导,相遇后从头节点和相遇点分别出发两个指针,每次前进一步,最终会在环入口相遇。该算法时间复杂度为O(N),空间复杂度为O(1),是一种高效的解决方案。
2025-11-21 10:00:44
325
原创 力扣hot100-141.环形链表
摘要:本文介绍判断链表是否有环的经典解法——快慢指针算法。该方法使用两个指针,慢指针每次移动一步,快指针每次移动两步。若无环,快指针会先到达末尾;若有环,快指针会在环内追上慢指针。算法时间复杂度为O(n),空间复杂度为O(1)。代码实现简洁高效,通过比较指针是否相遇来判断环的存在。
2025-11-20 13:44:57
301
原创 力扣hot100-回文链表234
本文介绍了一种判断链表是否为回文的高效算法。该算法使用快慢指针找到链表中点,反转后半部分链表,然后比较前后两部分是否相同。时间复杂度为O(n),空间复杂度为O(1)。关键步骤包括:1)快慢指针定位中点;2)反转后半链表;3)逐节点比较;4)(可选)恢复链表结构。算法适用于奇偶长度链表,并通过反转操作避免了额外空间使用。文中还提供了完整的C++实现代码和测试用例,展示了算法在[1,2,2,1]等典型情况下的应用。
2025-11-20 12:48:32
375
原创 如何把一个压缩的视频文件,解压成一张张原始图片-decode_video.c
本文系统介绍了音视频开发的核心概念与解码流程。第一部分通过"冷冻食品加工厂"的比喻,详细解释了编解码、容器格式、Packet/Frame关系、解析器、YUV颜色空间、帧类型及DTS/PTS时序等7个关键概念。第二部分深入解析了FFmpeg解码实现的四个步骤:初始化工具配置、数据流解析切包、解码器投喂与接收机制,以及图像保存处理。文章特别强调了音视频处理的通用流程:数据源→解析切包→压缩数据包→解码缓冲→原始帧输出,为初学者提供了清晰的学习路径。通过将抽象概念具象化,帮助读者快速建立音视频
2025-11-20 11:03:07
1043
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅