<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[leimeili的博客]]></title><description><![CDATA[]]></description><link>https://blog.youkuaiyun.com/leimeili</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; leimeili]]></copyright><item><title><![CDATA[一、音视频基础]]></title><link>https://blog.youkuaiyun.com/leimeili/article/details/142782043</link><guid>https://blog.youkuaiyun.com/leimeili/article/details/142782043</guid><author>leimeili</author><pubDate>Thu, 10 Oct 2024 17:43:58 +0800</pubDate><description><![CDATA[音视频播放原理主要涉及解协议、解封装、解码、音视频同步、播放等关键步骤。解协议：对于在线播放，这一步骤涉及将流媒体协议的数据解析为标准的封装格式数据。解封装：将封装格式的数据分离成音频流压缩编码数据和视频流压缩编码数据。解码：将压缩编码的音视频数据解码成非压缩的音视频原始数据。音视频同步：根据时间戳等信息同步解码出来的视频和音频数据。播放：将处理后的音视频数据送至系统的显卡和声卡进行播放。]]></description><category></category></item><item><title><![CDATA[面试二十七、 CAS和Atomic]]></title><link>https://blog.youkuaiyun.com/leimeili/article/details/139302104</link><guid>https://blog.youkuaiyun.com/leimeili/article/details/139302104</guid><author>leimeili</author><pubDate>Sat, 01 Jun 2024 11:38:27 +0800</pubDate><description><![CDATA[通过硬件提供的原子指令实现无锁的原子操作，确保在多线程环境下的数据一致性和线程安全。通过使用内存顺序，可以进一步控制操作的可见性和顺序，以满足不同的并发编程需求。CAS只能保证变量的原子性，不能保证变量的内存可见性。CAS获取共享变量的值时，需要和volatile配合使用，来保证共享变量的可见性。而并发量过高，会导致自旋重试耗费大量的CPU资源。CAS只能保证单个变量的原子操作，要保证多个变量的原子操作，可以使用锁机制。，但可以通过将版本号和指针组合在一起实现类似的效果。来保证多个变量的原子操作的示例。]]></description><category></category></item><item><title><![CDATA[面试二十七、异步的日志]]></title><link>https://blog.youkuaiyun.com/leimeili/article/details/139354418</link><guid>https://blog.youkuaiyun.com/leimeili/article/details/139354418</guid><author>leimeili</author><pubDate>Fri, 31 May 2024 15:43:09 +0800</pubDate><description><![CDATA[日志消息的写入操作在一个独立的线程中进行，而不是在调用log函数的主线程中进行。这意味着主线程可以继续执行其他任务，而不需要等待日志消息写入完成。这提高了程序的性能和响应速度，特别是在日志写入操作耗时较长的情况下。]]></description><category></category></item><item><title><![CDATA[面试二十六、c++语言级别的多线程编程]]></title><link>https://blog.youkuaiyun.com/leimeili/article/details/139267219</link><guid>https://blog.youkuaiyun.com/leimeili/article/details/139267219</guid><author>leimeili</author><pubDate>Tue, 28 May 2024 21:25:49 +0800</pubDate><description><![CDATA[这里的c++语言级别的多线程和linux的有一定的区别，c++语言级别提供的多线程比较严格，如果主线程结束了，但是子线程没有结束，进程就会异常终止，而linux不会，会继续执行。unique_lock允许右值引用的拷贝构造和赋值，]]></description><category></category></item><item><title><![CDATA[面试八-存泄漏是什么，有哪几种，怎么解决？]]></title><link>https://blog.youkuaiyun.com/leimeili/article/details/136720346</link><guid>https://blog.youkuaiyun.com/leimeili/article/details/136720346</guid><author>leimeili</author><pubDate>Tue, 28 May 2024 14:55:00 +0800</pubDate><description><![CDATA[当使用基类指针指向派生类对象时，如果基类的析构函数不是虚函数，那么在使用基类指针来删除这个对象时，只会调用基类的析构函数，而不会调用派生类的析构函数。野指针可能是在创建指针后没有给它赋值（即未初始化指针），或者是在释放内存后未将指针置空，但继续使用该指针。因此，在多线程环境下，需要确保对智能指针的操作是线程安全的。：如果存在循环引用（例如，两个对象相互持有对方的智能指针），会导致对象永远无法被释放，从而造成内存泄漏。：如果将智能指针转换为裸指针，并在转换后使用裸指针来管理资源，容易造成资源。]]></description><category></category></item><item><title><![CDATA[面试二十五、remove和earse的区别]]></title><link>https://blog.youkuaiyun.com/leimeili/article/details/138485941</link><guid>https://blog.youkuaiyun.com/leimeili/article/details/138485941</guid><author>leimeili</author><pubDate>Mon, 06 May 2024 10:40:42 +0800</pubDate><description><![CDATA[vector中erase的作用是删除掉某个位置position或一段区域（begin, end)中的元素，减少其size，返回被删除元素下一个元素的位置。vector中remove的作用是将范围内为val的值都remove到后面，返回新的_last值（非val部分的end）,但传入的原vector的end并没有发生改变，因此size也就没有变化。remove。]]></description><category></category></item><item><title><![CDATA[面试二十四、继承多态]]></title><link>https://blog.youkuaiyun.com/leimeili/article/details/138340391</link><guid>https://blog.youkuaiyun.com/leimeili/article/details/138340391</guid><author>leimeili</author><pubDate>Wed, 01 May 2024 18:22:20 +0800</pubDate><description><![CDATA[如果派生类中没有show（）函数，则可以调用基类的show（）方法，但是如果派生类中存在show（）同名的，不管参数列表，会将基类的show隐藏，包括基类中show函数的全部重载。首先看指针的类型，然后看调用函数在父类中是正常的函数还是虚函数，如果是正常函数在编译的时候就知道了，如果是虚函数，先要查找子类的虚函数表（因为虚函数会被重写或者覆盖），然后调用函数，：继承是实现多态的基础。：继承关系可以形成继承链，允许多层次的继承，子类可以继承父类的属性和行为，而子类的子类又可以继承子类的属性和行为，以此类推。]]></description><category></category></item><item><title><![CDATA[面试二十三、 strcpy 和memcpy 以及字符串和字符数组相互转换]]></title><link>https://blog.youkuaiyun.com/leimeili/article/details/138249383</link><guid>https://blog.youkuaiyun.com/leimeili/article/details/138249383</guid><author>leimeili</author><pubDate>Sat, 27 Apr 2024 15:01:35 +0800</pubDate><description><![CDATA[strcpy和memcpy都是浅拷贝操作，它们只是简单地将源数据复制到目标位置，而不会复制源数据所指向的内容。strcpy会复制源字符串的内容直到遇到null终止符，并将其复制到目标字符串中。但是它不会复制源字符串指针所指向的内存，因此如果源字符串是指向动态分配内存的指针，只会复制指针值而不会复制其指向的内存块。这就是所谓的浅拷贝。memcpy会复制指定长度的内存块，但它对数据的内容一无所知，只是简单地按字节复制。因此，如果源数据包含指针或其他引用，memcpy。]]></description><category></category></item><item><title><![CDATA[面试二十二、跳表SkipLists]]></title><link>https://blog.youkuaiyun.com/leimeili/article/details/138199902</link><guid>https://blog.youkuaiyun.com/leimeili/article/details/138199902</guid><author>leimeili</author><pubDate>Thu, 25 Apr 2024 22:09:28 +0800</pubDate><description><![CDATA[跳表全称为跳跃列表，它允许快速查询，插入和删除一个有序连续元素的数据链表。跳跃列表的平均查找和插入时间复杂度都是O(logn)。快速查询是通过维护一个多层次的链表，且每一层链表中的元素是前一层链表元素的子集（见右边的示意图）。一开始时，算法在最稀疏的层次进行搜索，直至需要查找的元素在该层两个相邻的元素中间。这时，算法将跳转到下一个层次，重复刚才的搜索，直到找到需要查找的元素为止。一张跳跃列表的示意图。每个带有箭头的框表示一个指针, 而每行是一个稀疏子序列的链表；底部的编号框（黄色）表示有序的数据序列。]]></description><category></category></item><item><title><![CDATA[面试二十一、红黑树]]></title><link>https://blog.youkuaiyun.com/leimeili/article/details/138161928</link><guid>https://blog.youkuaiyun.com/leimeili/article/details/138161928</guid><author>leimeili</author><pubDate>Wed, 24 Apr 2024 22:08:06 +0800</pubDate><description><![CDATA[性质：





插入：







旋转：




]]></description><category></category></item><item><title><![CDATA[面试二十、AVL平衡二叉树]]></title><link>https://blog.youkuaiyun.com/leimeili/article/details/138139460</link><guid>https://blog.youkuaiyun.com/leimeili/article/details/138139460</guid><author>leimeili</author><pubDate>Tue, 23 Apr 2024 21:42:40 +0800</pubDate><description><![CDATA[]]></description><category></category></item><item><title><![CDATA[面试二十、BST二叉排序树]]></title><link>https://blog.youkuaiyun.com/leimeili/article/details/138130145</link><guid>https://blog.youkuaiyun.com/leimeili/article/details/138130145</guid><author>leimeili</author><pubDate>Tue, 23 Apr 2024 21:07:18 +0800</pubDate><description><![CDATA[二叉排序树是一种二叉树，其每个节点的值大于其左子树中任意节点的值，小于其右子树中任意节点的值，这样可以保证树的有序性。对于动态查找表，插入和删除操作频繁，而二叉排序树能够在 O(log n) 的时间内实现插入和删除操作，并且能够保持树的有序性。顺序表通过数组实现，可以提供常数时间的随机访问，因此在静态情况下，适合顺序表存储，这样可以简化数据的组织和访问。对于查找操作，由于有序表，可以采用二分查找算法来实现，其时间复杂度为 O(log n)，这是一种高效的查找方法。]]></description><category></category></item><item><title><![CDATA[面试十九、哈希表]]></title><link>https://blog.youkuaiyun.com/leimeili/article/details/138130209</link><guid>https://blog.youkuaiyun.com/leimeili/article/details/138130209</guid><author>leimeili</author><pubDate>Tue, 23 Apr 2024 16:10:58 +0800</pubDate><description><![CDATA[]]></description><category></category></item><item><title><![CDATA[面试十八、容器适配器]]></title><link>https://blog.youkuaiyun.com/leimeili/article/details/137888996</link><guid>https://blog.youkuaiyun.com/leimeili/article/details/137888996</guid><author>leimeili</author><pubDate>Mon, 22 Apr 2024 22:02:50 +0800</pubDate><description><![CDATA[容器适配器是一种特殊类型的容器，它们提供了一种不同于常规容器的接口和行为。容器适配器通常是建立在其他容器之上，通过改变接口或添加限制来满足特定的需求或解决特定的问题。优先队列是一种特殊类型的队列，它的元素按照一定的优先级进行排序，每次删除操作都会删除优先级最高的元素。队列是一种先进先出（FIFO）的数据结构，它允许在队列的一端进行插入操作，在另一端进行删除操作。栈是一种后进先出（LIFO）的数据结构，它只允许在栈顶进行插入和删除操作。是一个容器适配器，它的默认实现基于双端队列。优先队列适配器提供了。]]></description><category></category></item><item><title><![CDATA[面试十七、list和deque]]></title><link>https://blog.youkuaiyun.com/leimeili/article/details/138090490</link><guid>https://blog.youkuaiyun.com/leimeili/article/details/138090490</guid><author>leimeili</author><pubDate>Mon, 22 Apr 2024 20:22:52 +0800</pubDate><description><![CDATA[Deque容器是连续的空间，至少逻辑上看来如此，连续现行空间总是令我们联想到array和vector,array无法成长，vector虽可成长，却只能向尾端成长，而且其成长其实是一个假象，事实上(1) 申请更大空间 (2)原数据复制新空间 (3)释放原空间 三步骤，元素存放在堆中，每个元素都是放在一块内存中，他的内存空间可以是不连续的，通过指针来进行数据的访问，这个特点使得它的随机存取变得非常没有效率，因此它没有提供[]操作符的重载。但是由于链表的特点，它可以很有效率的支持任意地方的删除和插入操作。]]></description><category></category></item><item><title><![CDATA[面试十六、emplace原理]]></title><link>https://blog.youkuaiyun.com/leimeili/article/details/138083628</link><guid>https://blog.youkuaiyun.com/leimeili/article/details/138083628</guid><author>leimeili</author><pubDate>Mon, 22 Apr 2024 17:02:31 +0800</pubDate><description><![CDATA[【代码】面试十六、emplace原理。]]></description><category></category></item><item><title><![CDATA[面试十五 容器]]></title><link>https://blog.youkuaiyun.com/leimeili/article/details/137939993</link><guid>https://blog.youkuaiyun.com/leimeili/article/details/137939993</guid><author>leimeili</author><pubDate>Mon, 22 Apr 2024 15:15:27 +0800</pubDate><description><![CDATA[记录了用户从中获取的哪一个元素的迭代器，记录在Iterator_Base链表中，哪一个迭代器增加或删除要让其失效并重新更新。迭代器失效是指：迭代器的底层其实就是容器的原生指针，插入元素可能导致容器内部的数据结构重新分配，从而使得原先的迭代器指向的位置不再有效；删除元素可能导致迭代器指向的位置被移动或删除，从而使得原先的迭代器不再指向期望的位置。然后判断链表中的迭代器，看它是否在插入、删除点和_last之间，将会失效，失效的话将迭代器的容器对象赋值为nullptr，再进行 operator!]]></description><category></category></item><item><title><![CDATA[面试十四、内存泄漏]]></title><link>https://blog.youkuaiyun.com/leimeili/article/details/138035521</link><guid>https://blog.youkuaiyun.com/leimeili/article/details/138035521</guid><author>leimeili</author><pubDate>Sun, 21 Apr 2024 15:45:04 +0800</pubDate><description><![CDATA[当基类指针指向子类对象时，如果基类的析构函数不是virtual，那么子类的析构函数将不会被调用，子类的资源没有正确是释放，因此造成内存泄露。：RAII 是一种重要的编程技巧，通过在对象的构造函数中获取资源，在析构函数中释放资源，来确保资源的正确管理。：智能指针是 C++ 中的一个重要特性，它能够自动管理动态分配的内存，当智能指针超出作用域时，会自动释放所指向的内存。：在需要动态内存分配时，应该尽量减少动态内存的使用，优先考虑使用栈上的对象，避免频繁地进行动态内存分配和释放。]]></description><category></category></item><item><title><![CDATA[面试十三、malloc 、calloc、realloc以及new的区别]]></title><link>https://blog.youkuaiyun.com/leimeili/article/details/138034058</link><guid>https://blog.youkuaiyun.com/leimeili/article/details/138034058</guid><author>leimeili</author><pubDate>Sun, 21 Apr 2024 15:19:09 +0800</pubDate><description><![CDATA[3.new操作符内存分配成功时，返回的是对象类型的指针，类型严格与对象匹配，无须进行类型转换；void free(void *p)   ，释放之前有调用 calloc、malloc 或 realloc 所分配的内存空间，*p指针指向一个要释放内存的内存块。2. 原地址空间没有连续的内存，则重新开辟一片空间，将数据拷贝到新空间，释放原空间，返回新地址指针（注意显式释放问题，引起二次释放的问题）（3） realloc 函数：在之前分配的内存块的基础上，将内存重新分配为更大或者更小的部分。]]></description><category></category></item><item><title><![CDATA[面试十二、装饰器模式]]></title><link>https://blog.youkuaiyun.com/leimeili/article/details/136920437</link><guid>https://blog.youkuaiyun.com/leimeili/article/details/136920437</guid><author>leimeili</author><pubDate>Thu, 21 Mar 2024 20:55:09 +0800</pubDate><description><![CDATA[装饰器（Decorator）模式的定义：指在不改变现有对象结构的情况下，动态地给该对象增加一些职责（即增加其额外功能）的模式，它属于对象结构型模式。如果使用组合关系来创建一个包装对象（即装饰对象）来包裹真实对象，并在保持真实对象的类结构不变的前提下，为其提供额外的功能，这就是装饰器模式的目标。其主要缺点是：装饰器模式会增加许多子类，过度使用会增加程序得复杂性。]]></description><category></category></item></channel></rss>