面经
面经
加浓美式好喝
when you fall down,just try again.
展开
-
建造者模式
【代码】建造者模式。原创 2024-04-21 11:57:39 · 368 阅读 · 0 评论 -
NULL和nullptr
在C++中指针必须有明确的类型定义。但是将NULL定义为0带来的另一个问题是无法与整数的0区分。在C++语言中,NULL则被定义为整数0。原创 2024-04-16 09:43:14 · 230 阅读 · 0 评论 -
深浅拷贝区别
只是拷贝一个指针,并没有新开辟一个地址,拷贝的指针和原来的指针指向同一块地址,如果原来的指针所指向的资源释放了,那么再释放浅拷贝的指针的资源就会出现错误。STL的容器包括string,vector,map等。还有智能指针包括等。unique_ptr如何实现深拷贝?C++标准库中哪里用了深拷贝。C++标准库中哪里用了深拷贝。原创 2024-04-15 16:24:08 · 219 阅读 · 0 评论 -
迭代器和指针的区别
迭代器是一种抽象的数据访问接口,它提供了一种统一的方式来遍历容器中的元素,不直接操作内存地址。指针是一种直接操作内存地址的原始数据类型,它可以指向任何数据类型的内存地址,并支持指针算术运算(如加法、减法)和解引用操作(迭代器是一种高级别的、抽象的数据访问接口,它隐藏了容器内部数据的具体实现细节,提供了一种统一的方式来遍历容器中的元素。迭代器通常提供了更多的安全保证,例如在边界检查、空容器检查等方面做了更多的工作,从而降低了出错的可能性。指针是一种低级别的、直接操作内存地址的工具,它提供了对内存的底层访问。原创 2024-04-15 16:19:15 · 319 阅读 · 0 评论 -
auto的工作原理
关键字声明变量时,编译器会根据变量初始化的表达式推导出其类型。编译器会分析初始化表达式,并根据表达式的类型来确定变量的类型。关键字替换为实际的类型,从而得到完整的类型声明。这意味着在编译后的代码中,变量的类型是明确的,与使用显式类型声明的效果相同。关键字可以使代码更加简洁,减少重复的类型声明,提高代码的可读性和可维护性。关键字适用于任何可以通过表达式推导出类型的情况,包括函数返回值、迭代器类型、lambda 表达式等。类型推导发生在编译时,因此不会影响程序的运行时性能。可以简化代码,减少错误。原创 2024-04-15 16:18:04 · 305 阅读 · 0 评论 -
push_back和emplace_back
的效率更高主要是因为它避免了不必要的拷贝或移动操作,以及不必要的临时对象的构造和销毁,直接在容器内部就地构造新元素。因此,在需要构造新元素时,尤其是对于大型对象或不能被移动的对象的容器来说,推荐使用。时,元素会直接在容器内部就地构造,而不是首先构造一个临时对象,然后再将其拷贝或移动到容器中。时,参数列表会直接传递给元素类型的构造函数,因此不会发生拷贝或移动操作,而是直接在容器中构造新元素。时,参数会被拷贝或移动到容器中,因此会调用元素类型的拷贝构造函数或移动构造函数。对于构造一个新元素而言,使用。原创 2024-04-15 16:03:52 · 417 阅读 · 0 评论 -
如何用C语言实现继承
函数指针允许在结构体内部存储对函数的引用,从而实现一些类似于面向对象的特性,比如多态性。通过将函数指针作为结构体的成员,可以在结构体内部模拟类似于对象的行为。在 C 语言中,struct内部不能直接包含函数,但可以包含。原创 2024-04-15 15:45:22 · 592 阅读 · 0 评论 -
预防内存泄漏
什么是内存泄漏什么是内存泄漏。原创 2024-04-15 15:39:24 · 169 阅读 · 0 评论 -
为什么内存要对齐
处理器对于不同数据类型的访问可能有不同的要求,例如,某些处理器要求对于4字节整数的地址必须是4的倍数。当数据对齐时,处理器可以更加高效地从内存中加载数据,而不需要额外的处理步骤,从而提高内存访问的效率。例如,某些处理器可能要求访问4字节整数的地址必须是4的倍数,否则可能会导致。的产生,提高内存的利用率。在结构体或对象中,对齐字段可以使得整个结构体的大小更加紧凑,避免不必要的填充,节省内存空间。不同的硬件平台可能对于内存访问有不同的要求,内存对齐可以帮助确保代码在各种平台上都能正常运行。原创 2024-04-15 15:30:59 · 731 阅读 · 0 评论 -
内存的管理
在程序运行过程中,代码区存放的是程序的机器码指令,也就是编译器或者汇编器生成的二进制指令。这些指令是CPU能够直接执行的,用于指示计算机执行特定的操作,比如进行算术运算、控制流程、访问内存等。代码区的内容通常包括程序的所有函数和指令,每个函数的起始地址以及指令的地址都是固定的。编译器会根据程序的代码和变量分配情况生成适当的汇编指令序列,以确保正确地管理栈区的内存。来将参数值从调用者的栈帧复制到被调用函数的栈帧中的特定位置。需要注意的是,代码区通常是只读的,因为程序在运行时不应该修改自身的指令。原创 2024-04-15 14:53:43 · 428 阅读 · 0 评论 -
多态的原理
通过监视可以发现,基类和子类的虚表指针指向的是不同的虚表(监视窗口可以证实),而且虚表里面的函数地址也是不一样的。这就符合我们的预期了,因为多态的调用的时候,就是通过虚表指针去找到对应虚表里面的虚函数,正巧子类和基类里面的func1函数构成了多态调用,所以在运行时会调用到不同的func1,所以监视窗口里就有不同的两个func1。可以看到子类继承了基类的虚表指针,所以有两个指针,分别指向的是两个虚表。子类继承了基类的虚表,并对派生类重写了的虚函数地址进行覆盖,就形成了子类独享的虚表。原创 2024-03-09 21:46:07 · 394 阅读 · 0 评论 -
迭代器失效问题(C++)
删除元素:迭代器失效就是迭代器指向的位置已经不是原来的含义了,或者是指向的位置是非法的。以下是失效的几种情况:删除元素:此处发生了迭代器的失效,因为erase返回的是下一个元素的位置的迭代器,所以在删除1这个元素的时候,迭代器已经指向了下一个元素。而for循环体内还有一次it++,所以此时it的位置在3。不是预期的2,所以2被忽略了,后面的4同理。可以这样修改:像list/map这样的非连续内存的容器,它们不像vector那样删除元素后会移动元素。原创 2024-03-07 21:46:16 · 468 阅读 · 0 评论 -
C++特殊类设计
【代码】C++特殊类设计。原创 2024-03-13 13:19:47 · 376 阅读 · 0 评论 -
Linux守护进程
因为在运行期间,一个进程可能会打开和操作其当前工作目录下的文件,如果这个目录被删除或移动,可能会导致一些意想不到的错误。守护进程的特点使它们非常适合作为服务器上的服务进程,处理如邮件传输、打印服务、文件传输等任务。如果守护进程尝试从标准输入读取数据,而标准输入没有输入,它可能会被阻塞等待输入。:守护进程通常会启动一个新的会话,并成为该会话的首进程,从而与启动它们的终端和用户会话脱离关系。创建一个新的会话,使进程成为会话首进程,脱离原有控制终端。:这样可以保证该进程不是进程组的首进程,允许它调用。原创 2024-03-15 17:02:46 · 626 阅读 · 0 评论 -
Linux动静态库
2.设置LD_LIBRARY_PATH的路径,LD_LIBRARY_PATH是Linux系统下的环境变量名,类似于Path(设置可执行文件的搜索路径)在/etc/ld.so.conf.d/下新建.conf配置文件,里面写入库路径,保存退出后使用sudo ldconfig命令即可。这是搜索头文件和库文件的默认目录,不需要-L和-I指定位置但是仍需要使用-l指定是哪个库。和静态库大同小异,区别之一是使用生成.o文件的时候需要加上-fPIC选项。-o libadd.so add.o即可。4.将头文件和库结合。原创 2024-03-17 10:34:17 · 399 阅读 · 0 评论 -
C++智能指针
当一块资源被一个对象指向时,就count++。循环引用问题:当两种shared_ptr对象相互指向时,A对象的释放需要靠B对象释放,因为B对象释放了自己的引用计数才会--,当减到0时就调用析构函数。故类似一种“死锁”的情况,两者资源都得不到释放。注意:shared_ptr可以定制删除器,因为默认对该资源的释放是delete,但是当出现new [] 或者文件指针时,delete不管用。auto_ptr的特点是当拷贝或者赋值该对象时,原先的资源将转移到新的对象上,当访问之前那个对象时,就会发现程序崩溃。原创 2024-03-13 16:45:27 · 757 阅读 · 0 评论 -
设计模式——单例模式
6.Garbo是垃圾回收类,当garbo对象出了作用域调用析构函数释放时,会顺带释放单例对象的资源。当然这个操作不是必要的,毕竟所占内存也特别小。5.饿汉式是线程安全的,在类创建的同时就已经创建好一个静态的对象供系统使用,以后不在改变,懒汉式不一定。2.把成员私有,避免类外直接对该静态成员进行赋值或者其他操作。3.把成员写成静态是因为静态成员每个类只存在一份,保证了单例。4.饿汉模式直接创建对象,该行为发生在main函数创建之前。1.把构造函数私有,是避免类外进行创建该对象。原创 2024-03-04 13:00:28 · 1614 阅读 · 0 评论 -
设计模式——工厂模式
工厂模式的意义是为了简化用户创建某个对象的过程,假设一个对象创建需要经过读文件,解析文件,设置参数,创建对象等复杂的步骤。注意:如果增加了一个产品族,那么会影响到整个代码的编写,如果只是增加一个产品等级,那么只需要再添加代码即可。该模式符合开闭原则。一个工厂类对应一个singer派生类,分别创建对应的对象。但是这样会使工厂类数量增大。但是以上模式不符合开闭原则, 当新增singer派生类的时候,就需要修改工厂内的源码。提供一个产品类的库,所有的产品以同样的接口出现,从而使得客户端不依赖于具体的实现。原创 2024-03-03 22:48:37 · 541 阅读 · 0 评论 -
聚簇索引和非聚簇索引
一张表只能有一个聚簇索引,因为聚簇索引决定了数据行的物理存储顺序与索引的键值顺序相同,也就是说,索引的键值决定了数据在磁盘上的物理排列方式。而Myisam存储引擎在磁盘上的文件是以.MYD结尾的表数据 和.MYI结尾的表索引,这其实就是非聚簇索引。由于索引存储的是索引键值和对应的行地址,而不是实际的数据行,因此可以减少从磁盘读取数据的次数,降低了I/O开销。非聚簇索引的叶子节点存放的是索引值(目录)以及存放真实数据的地址。Innodb存储引擎在磁盘上的文件是以.idb结尾的文件,它存放的是表索引+数据。原创 2024-03-31 14:47:05 · 205 阅读 · 0 评论 -
lambda表达式(面试高频考点)
可选部分,用于指定Lambda函数的返回类型,如果省略了返回类型,则由编译器根据Lambda函数的实际返回类型进行推导。lambda 表达式在 C++ 中的实现通常是通过函数对象(仿函数)来实现的。lambda表达式是一种匿名函数,通常用于简化代码或者在需要函数作为参数的地方使用。Lambda函数的参数列表,可以为空或包含一个或多个参数,参数类型可以显式指定也可以由编译器推导。,使其可以像函数一样被调用。Lambda函数的实际执行体,通常包含一系列语句,可以是简单的表达式或复杂的代码块。原创 2024-04-15 11:46:45 · 571 阅读 · 0 评论 -
MySQL——锁
行级锁可以提高数据库的并发性能,因为它允许多个事务同时对同一张表的不同行进行操作,而不会发生锁竞争。只有当两个事务试图修改同一行数据时,才会发生锁竞争,其中一个事务会被阻塞,直到另一个事务释放锁。页级锁可以提高并发性能,因为它允许多个事务在同时操作不同的数据页,而不会发生锁竞争。只有当两个事务试图同时修改同一个数据页时,才会发生锁竞争,其中一个事务会被阻塞,直到另一个事务释放锁。另外,全局锁只能阻止写操作,全局锁是一种数据库锁定机制,它可以锁定整个数据库,阻止其他会话对数据库的读写操作。原创 2024-03-30 13:28:00 · 407 阅读 · 0 评论 -
为什么索引的底层结构是B+树
1.数据库与数据交互的单位是page,而B+树的每个节点都是一个page,访问一个节点,就相当于进行了一次I/O操作。而B树的同层节点没有指针指向,所以可能需要在非叶子节点进行递归搜索,相对来说操作复杂度更高。数据查询的时间主要依赖于磁盘IO的次数,二叉树深度越大,查找的次数越多,性能越差。在AVL树中,为了保持树的平衡性,可能需要进行频繁的旋转操作,例如左旋和右旋。红黑树在范围查询操作中可能需要进行中序遍历,而且遍历过程中的节点访问顺序是不确定的,这导致了范围查询的效率较低。为什么不用二叉搜索树。原创 2024-03-30 15:18:11 · 558 阅读 · 0 评论 -
Redis分布式锁
可以利用set ex nx设置锁的过期时间,解决了服务器崩了没有正常释放锁的问题。但是之前加的锁的数据从节点不知道。但是在这种情况下,就会导致服务器2刚加上的锁就被解除了。因为在GET的时候,已经通过了校验,因为此时的锁的id正是服务器1的id。解决方法有两种,一是实现redis的事务,保证线程B的两个命令是原子执行的。总结:单个Redis实例可能存在单点故障的风险,一旦发生故障,可能导致锁的不可用。Redlock算法通过在多个Redis实例之间创建相同的分布式锁,能够提高系统的可用性和可靠性。原创 2024-04-06 17:33:00 · 735 阅读 · 0 评论 -
HTTP/HTTPS
HTTP/2.0 引入了多路复用(Multiplexing)技术,允许在单个 TCP 连接上同时发送多个请求和响应,避免了 HTTP/1.0 中的队头阻塞(Head-of-Line Blocking)问题,提高了网络利用率和页面加载速度。: 如果服务器的证书验证通过,客户端会生成一个随机的对称密钥(会话密钥),用于加密通信数据。HTTP/1.1 引入了持久连接机制,允许在单个连接上发送多个请求和响应,减少了连接建立和关闭的开销,提高了性能。: 客户端使用服务器的公钥加密生成的会话密钥,并将其发送给服务器。原创 2024-04-02 16:57:03 · 725 阅读 · 0 评论 -
进程间通信——匿名管道
7.读进程关闭,而写进程一直写,那么系统会发送SIGPIPE信号终止进程。6.写进程写完后关闭。读进程读完后继续执行后续任务不会挂起。4.写进程一直写而读进程不读,那么会使写进程挂起。5.读进程一直读而写进程不写,那么会使读进程挂起。2.匿名管道写进的数据不会写入磁盘,仅在内存中。1.匿名管道仅限有亲缘关系的进程间通信。3.匿名管道只能单向通信。原创 2024-03-17 22:45:22 · 354 阅读 · 0 评论 -
如何用Redis实现消息队列
Stream数据结构中每个消息都有消息ID,保证消息的消费需要用到这个消息ID。当消费者在消费消息的时候宕机了,这时候消费者不会发送XACK,当消费者重新上线后,会将消息重新发给消费者。4.每个消费者再订阅一个队列的时候,在redis中会给每个消费者分配一块内存消费消息的缓冲区,当由大量的消息过来的时候,消费者消费不及时,造成消息堆积达到一定阈值的时候,redis就会强制让这个消费者下线。2.Redis 不会对发布的消息进行持久化存储,如果 Redis 服务器重启或者出现故障,未处理的消息可能会丢失。原创 2024-03-31 11:15:18 · 595 阅读 · 0 评论 -
为什么Redis设计成单线程
中,读取速度非常快,而写入操作通常采用异步持久化的方式,将数据定期写入到磁盘,避免了磁盘IO成为性能瓶颈。这样一来,Redis 可以在高速内存中快速响应读取请求,而异步持久化保证了数据的持久性和安全性。的,保证了多个操作的一致性和可靠性。由于 Redis 是单线程执行指令的,所以不会出现多线程并发访问共享数据的问题,3.采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU。来处理客户端请求,避免了多线程间的上下文切换和锁竞争,从而提高了并发处理能力。原创 2024-03-30 17:07:23 · 354 阅读 · 0 评论 -
Git的使用
也可以查看是否有未add的文件或者是否有未commit的在暂存区中的文件。,其中soft是只回退版本库的内容,mixed是回退版本库和暂存区的内容,hard是全部回退包括工作区。其中objects存放的是每一次修改后的版本。暂存区和master里面存的是一个个的索引,指向不同的文件版本。文件名的方法删除了工作区和暂存区的数据,之后进行git commit操作后版本库的数据就被删除了。,在工作区的文件是不能被Git接管的。原理:回退实际就是把指针的指向(指向的是objects里面的内容)改变了。原创 2024-04-10 21:05:23 · 431 阅读 · 0 评论 -
如何保证Redis和数据库数据一致性
假设此时有两个线程,一个线程修改了数据库的内容。之后向数据库进行修改操作。那么就会读到修改前的旧数据了。当线程1发起修改操作的请求给数据库后。数据库会进行修改并返回给redis,要求redis删除数据。如果在数据库同步数据之前,有线程2进行读操作,那么可能会读到旧数据。等到数据库将新的数据返回给redis之后,再将数据清空。保证了redis里不会有旧的数据了,虽然有加锁保证强一致性的操作,但是这样会大大影响效率。而不是直接进行redis的修改。一是先操作redis,一是先操作mysql。原创 2024-04-06 15:10:31 · 471 阅读 · 0 评论 -
为什么用了索引,搜索速度还是很慢
然而,如果我们在 "name" 列和 "age" 列上都创建了索引,并且查询条件中只包含 "name" 列,数据库系统可能会错误地选择使用 "age" 列上的索引来执行查询,因为它认为 "name" 列的索引并不是最优选择。因此,在选择索引列时,需要考虑查询的频率和字段的选择性,尽量选择在查询中经常被用到并且具有较高选择性的列作为索引列,以提高索引的效率和搜索速度。例如,如果一张表上存在多个索引,而且这些索引的列有重叠,那么数据库系统在选择索引时可能会选择不合适的索引,导致索引失效,从而无法提高查询性能。原创 2024-03-30 14:20:43 · 884 阅读 · 0 评论 -
Redis集群
Redis 中的槽位数量通常选择为 16384(即 2 的 14 次方),而每个键都会通过 CRC16 算法计算出一个 16 位的哈希值,然后将该哈希值与槽位数量取模,得到键所属的槽位编号。所以干脆用空间换时间。槽位的数量应该是 2 的幂次方,因为将哈希值映射到槽位时,通常会使用取模运算。所以我们需要引入新的机制,来提高Redis的存储的数据量。当客户发送请求时,如果接收到的那个服务器判断该槽位不是由自己负责时,就返回给客户MOVED的错误信息,并将需要处理这个请求的Redis服务器的ip和port给它。原创 2024-03-30 17:45:41 · 315 阅读 · 0 评论 -
MyISAM和InnoDB
3.ACID属性:InnoDB引擎遵循ACID属性(原子性、一致性、隔离性和持久性),这意味着它可以确保事务在数据库中的操作是原子的、一致的、隔离的和持久的。InnoDB 使用自己的方式管理数据和索引的存储,采用行级存储方式,每行数据包含着完整的记录,包括索引键和数据。:InnoDB 存储引擎支持事务,具有较强的事务一致性和数据完整性保证,适合对数据一致性要求较高的应用场景,如金融、电子商务等。4.不支持一致性:MyISAM表在发生故障或崩溃时,可能会出现数据不一致的情况,因为它不提供事务的一致性保证。原创 2024-03-30 12:52:10 · 1081 阅读 · 0 评论 -
多进程和多线程
独享的资源有:线程的栈,用于存储局部变量、函数调用信息等、线程的ID、寄存器组的值:当线程切换时,必须将原有的线程的寄存器集合的状态保存,以便重新切换时得以恢复。多进程之间通信的主要方式是通过进程间通信机制,如管道、消息队列、共享内存等。多线程适用于需要共享数据和共享资源的任务,线程之间可以更方便地进行通信和协作。多进程适用于需要完全隔离的任务,每个进程拥有独立的资源和地址空间,互不干扰。多进程适用于需要稳定性和可靠性的应用,一个进程崩溃不会影响其他进程。多进程是指在操作系统中同时运行多个独立的进程。原创 2024-03-30 15:48:44 · 764 阅读 · 0 评论 -
select,poll,epoll
调用函数后,返回的参数是已经修改过的,显示的是已经就绪的文件描述符,只包含那些有事件发生的文件描述符。边缘触发的优点是效率高,它减少了事件的重复通知,适用于高性能的场景,特别是处理大量并发连接时。默认情况下,如果不显式指定,:同样没有硬性的文件描述符数量限制,并且因为其内部机制,即使在监视数千甚至数万个文件描述符时,也能保持较高的性能。报告了某个文件描述符上的事件,该事件不会再被报告,直到该文件描述符的状态再次发生变化。所有监视的文件描述符来检查状态,这使得随着文件描述符数量的增加,它们的效率线性下降。原创 2024-04-01 16:52:54 · 733 阅读 · 0 评论 -
Redis的持久化
redis的持久化原创 2024-01-27 10:15:41 · 552 阅读 · 0 评论 -
Redis的数据类型
Redis的5个基本数据类型原创 2024-01-25 14:00:46 · 1017 阅读 · 0 评论 -
设计模式——开闭原则
但是这段代码存在问题:如果想对该计算器类增添新的功能,比如说取余或者开方等等。那么就需要修改函数内的代码,这样就导致了一个问题:我们在修改代码的时候可能会出错,导致一系列后果,这就是所谓的高耦合。但是我们想到的是低耦合的代码。所以可以将不同的运算分别写在一个类中。原创 2024-03-03 14:48:55 · 646 阅读 · 0 评论