- 博客(84)
- 收藏
- 关注
原创 互斥锁、原子锁、自旋锁
在选择锁的类型时,需要根据具体的应用场景和性能要求来决定使用哪种锁。在某些情况下,可能会结合使用多种锁,例如,使用互斥锁保护共享资源,同时使用原子锁保证某些操作的原子性。多线程编程中,锁是一种同步机制,用于控制多个线程对共享资源的访问。
2024-10-08 20:50:56 622
原创 x32 x64区别
x32和x64指的是计算机架构中的指令集和寄存器大小,它们决定了软件和硬件的兼容性以及性能。总的来说,x64架构提供了更多的内存寻址能力和更好的性能,已经成为市场的主流选择。而x32架构虽然在某些特定场景下仍有其用途,但逐渐被边缘化。
2024-10-08 20:48:15 338
原创 C++调用C语言
在编译和链接时,确保C和C++代码都能被正确处理。如果使用命令行编译器,可能需要指定不同的编译器或编译选项。来告诉C++编译器这些函数是C语言函数,以便正确处理名称修饰(name mangling)。C++编译器会对函数名进行修饰(name mangling),以支持重载等功能。在C++代码中,可以直接调用C语言函数,就像调用C++中的函数一样。在C++代码中,可以直接包含C语言的头文件。可以防止这种情况,确保C++调用的函数名与C中定义的相同。如果C代码中有全局变量,可以在C++中通过。
2024-09-25 18:28:18 277
原创 多用组合少用继承
在软件开发中,“多用组合少用继承”是一种设计原则,它强调使用组合而不是继承来设计类和对象的关系。:组合允许更容易地添加新功能,因为可以通过添加新的类来实现新的行为,而不需要修改现有的类。这种方式可以动态地将行为和数据组合在一起,而继承则是静态地将一个类的特性传递给另一个类。:继承可能会导致歧义,因为派生类可能会覆盖基类的行为,这可能会导致代码难以理解和预测。组合则可以避免这种歧义,因为对象的行为是明确定义的。:组合提供了更高的灵活性,因为它允许在运行时动态地改变对象的行为。
2024-09-25 09:48:34 337
原创 socket编程描述tcp的三次握手
TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。在两个网络实体之间建立TCP连接之前,必须进行三次握手过程。在C++中,使用socket编程实现TCP三次握手的过程涉及到网络编程,需要包含头文件<unistd.h>和。
2024-09-25 09:40:53 637
原创 哈夫曼树
哈夫曼树是一种高效的编码工具,利用字符的频率分布为数据压缩提供了一个简单而有效的解决方案。通过构建哈夫曼树,可以为每个字符生成独特的二进制编码,从而实现无损压缩。
2024-09-24 16:04:23 198
原创 用malloc分配内存,操作系统会为程序分配物理内存,什么时候会分配?
虚拟内存与物理内存的分配时机虚拟内存的分配: 当程序调用malloc函数请求一定大小的内存时,malloc会首先尝试在进程的虚拟地址空间中为该请求分配一块连续的虚拟内存区域。这个过程通常是通过系统调用如brk(对于小块内存)或mmap(对于大块内存)来完成的。 重要的是要理解,这个步骤只是分配了虚拟内存,并没有直接涉及物理内存的分配。虚拟内存空间在逻辑上是连续的,但实际上它与物理内存的映射关系是动态的,即按需建立。 物理内存的分配: 物理内存的分配发生在进程第一次尝试访问已分配的虚拟内存
2024-09-18 17:15:08 919
原创 vector扩容
是 C++ 标准模板库(STL)中的一个非常重要的容器,用于存储一个动态数组。它的底层实现通常包括三个主要部分:一个连续的存储空间、一个指向这个存储空间起始位置的迭代器(或指针)、以及一个记录当前。中元素个数的计数器。
2024-09-18 17:12:04 280
原创 i++&volatile
i++操作本身并不是线程安全的。这是因为i++是一个复合操作,包括读取i的值、将i的值加1、然后写回i。如果在多线程环境中,多个线程同时执行i++操作,就可能发生竞态条件(race condition),即一个线程的操作被另一个线程的操作打断,导致最终结果不确定或错误。为了在多线程环境中安全地使用i++,需要采用同步机制,如互斥锁(mutex)或原子操作(如C++11中的),来确保在任何时候只有一个线程能够执行i++操作。这样可以避免竞态条件,保证线程安全。
2024-09-18 14:56:16 390
原创 静态函数能是虚函数吗
静态函数不依赖于对象实例,它在类的作用域内存在,不能使用对象的虚函数表(vtable)。虚函数的机制依赖于对象实例的 vtable 来决定调用哪个函数,但静态函数没有 vtable,因此不适用虚函数机制。:虚函数的主要目的是为了实现动态多态性,即通过基类指针或引用调用派生类的实现。而静态函数在类层面而不是对象层面进行操作,不涉及动态绑定。:虚函数通过对象调用,静态函数通过类名调用。虚函数机制涉及到对象的动态类型信息,而静态函数没有这个信息。
2024-09-10 17:26:14 327
原创 C++ move
在 C++ 中,std::move是一个标准库函数,属于<utility>头文件。它用于将左值(lvalue)显式地转换为右值(rvalue),以便能够使用右值引用来实现移动语义。std::move并不执行任何实际的移动操作,而是仅仅转换值的类别。
2024-09-10 17:18:47 355
原创 左右值引用
移动后的对象一般会变成一个“有效但状态不确定”的对象,但它仍然是一个左值。移动操作不改变对象的左值或右值身份,仅仅改变了资源的所有权。:转移后的对象的生命周期依然和普通对象一样。它的生命周期从创建开始,到对象销毁结束。移动语义只是改变了对象的内部状态或资源所有权。:表示一个临时的值或一个没有持久状态的对象,通常是计算结果或字面量,可以出现在赋值符号的右边。移动语义的主要目的是将资源从一个对象“移动”到另一个对象,避免不必要的复制,并提升性能。主要用于实现移动语义和完美转发。
2024-09-10 17:15:47 245
原创 动态链接库和静态链接库
(Dynamic Link Library)是在程序运行时才进行链接的库文件。它在Windows上通常具有。(Static Library)是在编译时将库代码与程序代码链接在一起的库文件。扩展名,在Unix/Linux上则通常是。(在Unix/Linux上)扩展名。(在Windows上)或。
2024-09-10 15:33:34 328
原创 乐观锁&悲观锁
的核心思想是“总是认为会发生冲突”,所以在访问共享资源时会对其加锁,以确保其他线程不能同时修改。这种方式确保了线程在操作资源时的互斥性。的核心思想是“尽量不去锁定资源,而是尽量让线程并发地工作”,并在最后阶段检查冲突,只有在检测到冲突时才会采取纠正措施。
2024-09-10 15:30:49 295
原创 单例模式
饿汉式(Eager Initialization)是一种简单的单例模式实现方法,在类加载时就创建唯一实例。Singleton类中的构造函数、拷贝构造函数和赋值运算符被私有化,并且使用了delete关键字,这样可以防止外部直接实例化对象或进行拷贝。而getInstance()方法是静态方法,它返回一个指向唯一实例的引用。在getInstance()方法中,我们使用了局部静态变量instance来保存唯一的实例。
2024-09-06 11:08:37 1136
原创 工厂模式
抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。抽象工厂模式允许客户使用抽象的接口来创建一组相关的产品,而不需要知道实际产出的具体产品是什么。这样一来,客户就可以从具体的产品中被解耦出来。优点可以在类的内部对产品族进行约束,一个具体工厂只能创建一定范围的产品内的产品。增加新的产品族很方便,无须修改已有系统,符合开闭原则。缺点产品族扩展非常困难,要增加新的产品族就必须修改抽象工厂接口,增加新的抽象方法和修改所有具体工厂类来实现新方法。
2024-09-06 10:50:38 275
原创 C++父子类相互赋值
在C++中,父类对象(基类对象)不能直接赋值给子类对象(派生类对象),因为子类可能包含父类中没有的成员变量或成员函数,这会导致信息丢失或类型不匹配的问题。然而,子类对象可以赋值给父类对象的引用或指针,但这需要理解其中的“切片”现象和“多态”的概念。
2024-09-06 10:31:04 281
原创 Redis面试
所谓热key问题就是,突然有几十万的请求去访问redis上的某个特定key,那么这样会造成流量过于集中,达到物理网卡上限,从而导致这台redis的服务器宕机引发雪崩。提前把热key打散到不同的服务器,降低压力加入二级缓存,提前加载热key数据到内存中,如果redis宕机,走内存查询缓存击穿的概念就是单个key并发访问过高,过期时导致所有请求直接打到db上,这个和热key的问题比较类似,只是说的点在于过期导致请求全部打到DB上而已。
2024-08-08 11:42:40 951
原创 Redis
假如用户第一次访问数据库中的某些数据。这个过程会比较慢,因为是从硬盘上读取的。将该用户访问的数据存在缓存中,这样下一次再访问这些数据的时候就可以直接从缓存中获取了。操作缓存就是直接操作内存,所以速度相当快。如果数据库中的对应数据改变之后,同步改变缓存中相应的数据即可!直接操作缓存能够承受的请求是远远大于直接访问数据库的,所以我们可以考虑把数据库中的部分数据转移到缓存中去,这样用户的一部分请求会直接到缓存这里而不用经过数据库。
2024-08-08 11:40:23 1094 1
原创 const关键字
使用const声明的变量在初始化后不能被修改。这有助于防止意外地改变某些重要的值。指针可以使用const,这样可以控制指针本身或指向的数据的可修改性。
2024-08-07 20:00:48 269
原创 C++ 动态规划
t[j - 1]),此时相当于t要删除元素,t如果把当前元素t[j - 1]删除,那么dp[i][j] 的数值就是 看s[i - 1]与 t[j - 2]的比较结果了,即:dp[i][j] = dp[i][j - 1]。
2024-08-02 14:10:17 927
原创 C++ 快排、归并、堆排
堆排序的时间复杂度为O(n log n),因为构建堆的复杂度为O(n),而每次堆化的复杂度为O(log n),如此需要进行n-1次堆化操作。
2024-08-01 11:48:50 312
原创 MySQL事务
事务是作为单个逻辑工作单元执行的一系列操作,通俗易懂的说就是一组原子性的 SQL 查询。Mysql 中事务的支持在存储引擎层,MyISAM 存储引擎不支持事务,而 InnoDB 支持,这是 Mysql 5.5.5 以后默认引擎由 MyISAM 换成 InnoDB 的最根本原因。
2024-07-31 19:59:46 959
原创 MySQL索引
索引是按照指定列和规则建立的一种数据排列组合的结构,当遇到数据表数据量比较大,检索消息成为系统瓶颈的时候,首先会想到为数据表创建索引。但索引对于一个业务而言,并非是必须的,尤其是对于数据量比较小的数据表或者修改频率比较大的数据表而言,索引的创建不仅不会加快查询速度,反而会降低查询速度,因为需要额外的索引维护。索引的作用根据索引的类型划分主要包括:提高数据检索的效率、维护数据的唯一性。另外使用order by和group by的时候,恰当地使用索引,还可以减少排序和分组的时间,从而间接的加快数据检索的效率。
2024-07-31 17:21:23 699
原创 strcpy 和 strncpy
该函数返回目标字符串的指针。but不检查目标缓冲区的大小,这可能导致缓冲区溢出。如果源字符串的长度超过了目标缓冲区的大小,就会导致内存被错误地覆盖,进而引发严重的安全问题,如应用程序崩溃、数据破坏,甚至被恶意代码利用。函数可以指定要复制的最大字符数,从而提供了一定程度的缓冲区保护。然而,仍需要小心处理,因为如果源字符串的长度小于指定的长度,目标字符串可能未被正确终止。是 C 标准库中的两个用于字符串复制的函数。或者使用C++ std::string.函数用于将源字符串复制到目标字符串中。
2024-07-30 16:01:42 252
原创 C++ std::condition_variable
是C++11引入的一个同步机制,主要用于在线程之间进行事件通知协调。它是标准库中的一个类,声明在头文件中。允许一个或多个线程等待另一个线程发送的信号(通过条件变量来实现的),从而基于某些条件进行协调动作。
2024-07-30 15:38:07 959
原创 多线程与并发思想
设计并发程序的就是为了使程序运行得更快(时间就是金钱、生命),提高软件的性能。并发程序之所以能快,就在于这个“并”字,因为程序能并发(单核)或并行(多核、多CPU)执行,当然能快。这就好比工人搬砖块,人当然是越多越快。但是,这之中有个关键问题,大家是否想到,那就是这个事情(如搬砖块)是否可以并发或并行来做。
2024-07-29 17:10:30 1152
原创 僵尸进程和孤儿进程
特性 僵尸进程 (Zombie Process) 孤儿进程 (Orphan Process) 定义 僵尸进程是一个已经终止但其父进程尚未调用wait()系统调用进行清理的进程。 孤儿进程是其父进程已经终止的进程,孤儿进程会被init进程收养。 进程状态 僵尸状态 (Z - Zombie) 正常运行或睡眠状态 (R - Running, S - Sleep) 资源占用 只占用进程表中的一个条目,不占用其他资源。 继承父进程的资源,占用系统资源。
2024-07-24 20:04:35 184
原创 python字典和JSON
Python 字典:一种包含键值对的数据结构,属于 Python 内置的数据类型。:一种轻量级的数据交换格式,常用于在网络上传输数据,以文本格式表示。JSON 是语言无关的,但目前在多数编程语言中都有很好的支持。
2024-07-22 20:14:42 265
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人