- 博客(65)
- 收藏
- 关注
原创 简述一下C++的重载和重写,以及他们的区别和实现方式
在同一作用域内(如类内部或全局作用域),定义多个同名函数,但它们的参数列表不同(参数类型、数量或顺序不同)。在派生类中重新定义基类的虚函数,要求函数名、参数列表和返回类型完全相同。派生类函数使用 override 关键字(C++11 起)明确表示重写。重写是运行时多态的核心机制,通过虚函数(virtual)实现动态绑定。返回类型可以不同,但仅返回类型不同不足以构成重载。必须发生在继承关系中(基类与派生类)。可以是成员函数,也可以是全局函数。2. 重写(Override)重写(Override)
2025-02-12 18:01:59
336
原创 C++面向对象三大特性
通过封装,我们可以控制类成员的访问级别(例如:public、protected 和 private),限制对类内部数据的直接访问,确保数据的完整性和安全性。继承允许一个类(派生类)基于另一个类(基类)创建,派生类会自动拥有基类的属性和方法,同时可以扩展或修改这些属性和方法。封装是将数据(属性)和操作这些数据的函数(方法)组合在一个类(Class)中的过程。多态是允许不同类的对象使用相同的接口名字,但具有不同实现的特性。通过多态,我们可以编写更加通用、可扩展的代码,提高代码的灵活性。
2025-02-12 18:01:02
221
原创 什么是野指针?怎样避免?
野指针(Dangling Pointer) 是指向已经被释放或无效内存地址的指针。使用野指针会导致不可预知的行为,包括程序崩溃、数据损坏或安全漏洞。在释放指针指向的内存后,立即将指针设为 NULL(C/C++)或 nullptr(C++11+)。若需返回堆内存,使用动态分配(malloc/new)并确保调用者负责释放。std::shared_ptr:共享所有权,引用计数归零时释放内存。std::unique_ptr:独占所有权,自动释放内存。比如:线程A释放了指针p指向的内存。2. 使用智能指针(C++)
2025-02-12 16:57:33
191
原创 什么是内存泄漏?怎样检测和防止?
如果程序的设计的错误导致这部分内存没有被释放,那么此后这块内存将不会被使⽤,就会产⽣ Heap Leak.当基类指针指向⼦类对象时,如果基类的析构函数不是 virtual,那么⼦类的析构函数将不会被调⽤,⼦类的资源没有正确是释放,因此造成内存泄露。智能指针(C++):如 std::unique_ptr(独占所有权)和 std::shared_ptr(共享所有权,需避免循环引用)。弱引用(Weak Reference):在需要循环引用的场景使用弱引用(如 C++ 的 std::weak_ptr)。
2025-02-12 16:54:17
378
原创 堆和栈的区别
自动分配/释放:由编译器自动管理,内存分配和释放遵循作用域规则(如函数调用结束或局部变量超出作用域时自动释放)。手动分配/释放:需通过 new/malloc 显式申请内存,通过 delete/free 显式释放。栈溢出风险:过度分配(如大数组、深度递归)会导致栈溢出(Stack Overflow)。自由分配:内存块可以在任意时间分配和释放,但需程序员自行管理,否则会导致内存泄漏。可能产生碎片:频繁分配/释放不同大小的内存块会导致内存碎片,降低利用率。无碎片:严格按 LIFO 顺序分配/释放,内存始终连续。
2025-02-10 19:21:49
295
原创 delete和free的区别
delete在释放内存后,能够确保内存内容被释放,并合并成一块可用的空间。free不具备任何行为保证,释放后的地址空间中仍可能存在原来数据的残留物,甚至可能覆盖其他已经被释放的对象。delete具有行为保证(即无论是否出错都会表现一致),能够确保释放内存不会对其他对象造成影响。delete是C++语言自带的运算符,对于类对象进行删除时调用类的析构函数。free是C标准库函数,仅释放空间,不会释放一个类(或者结构体)对象的空间。允许全局或类特定的重载,支持自定义内存管理策略(如内存池)。
2025-02-10 19:21:17
278
原创 new和malloc的区别
malloc 返回的是 void* ,需要进⾏类型转换,因为它不知道所分配内存的⽤途。malloc 是C语⾔库函数,只分配指定⼤⼩的内存块,不会调⽤构造函数。malloc 只是分配指定⼤⼩的内存块,不了解所分配内存块的具体⽤途。new 是C++的运算符,可以为对象分配内存并调⽤相应的构造函数。允许全局或类特定的重载,支持自定义内存管理策略(如内存池)。new 返回的是具体类型的指针,⽽且不需要进⾏类型转换。delete 会调⽤对象的析构函数,然后释放内存。new 可以⽤于动态分配数组,并知道数组⼤⼩。
2025-02-10 17:51:42
224
原创 智能指针的实现原理是什么
多个 shared_ptr 可以指向同一对象,引用计数记录当前有多少个 shared_ptr 指向该对象。当引用计数降为 0 时,对象被销毁。weak_ptr 是为了解决 shared_ptr 的 循环引用问题 而设计的。内部同样维护一个指向控制块的指针,但不操作引用计数(use_count),只操作弱引用计数(weak_count)。两个对象互相持有对方的 shared_ptr,导致引用计数永远无法降为 0,资源无法释放。弱引用计数(weak_count):记录 weak_ptr 的引用次数。
2025-02-09 15:25:14
381
原创 什么是智能指针,C++有哪几种智能指针
智能指针是C++中的一种对象,用于管理动态分配的内存,确保在适当的时候自动释放内存,从而避免内存泄漏。智能指针通过封装原始指针,并在其生命周期结束时自动释放内存,简化了内存管理。独占所有权的智能指针,确保同一时间只有一个unique_ptr指向某个对象。使用引用计数来跟踪对象的引用次数,当引用计数为0时,对象会被自动删除。共享所有权的智能指针,多个shared_ptr可以指向同一个对象。weak_ptr不增加引用计数,因此不会影响对象的生命周期。弱引用的智能指针,通常与shared_ptr配合使用。
2025-02-09 15:23:30
127
原创 结构体与类之间的区别
通常, struct ⽤于表示⼀组相关的数据,⽽ class ⽤于表示⼀个封装了数据和操作的对象,在实际使⽤中,可以根据具体的需求选择使⽤ struct 或 class。如果只是⽤来组织⼀些数据,⽽不涉及复杂的封装和继承关系, struct 可能更直观;如果需要进⾏封装、继承等⾯向对象编程的特性,可以选择使⽤ class。如果结构体没有定义任何构造函数,编译器会⽣成默认的⽆参数构造函数。如果类没有定义任何构造函数,编译器也会⽣成默认的⽆参数构造函数。类中的成员默认是私有的(private)。
2025-02-08 22:05:06
223
原创 常量指针和指针常量之间有什么关系
/ 正确:可以修改 a 的值(a = 30)// *ptr = 30;指针本身是常量:指针的指向地址不可变(必须初始化),但可以通过指针修改指向的值。// ptr 是指针常量,必须初始化。// 正确:指针可以指向其他地址。指向的数据是常量:不能通过指针修改指向的值,但指针可以指向其他地址。// ptr 是常量指针。2. 常量指针(const int* 或 int const*)语法:类型* const 指针名 = 初始地址;指针的地址(指向)可以改变。指针的地址(指向)不可变。
2025-02-08 22:04:35
115
原创 static关键字和const关键字的作用
2. 指针和引⽤:声明指向常量的指针,表示指针所指向的值是常量,不能通过指针修改。声明常量引⽤,表示引⽤的值是常量,不能通过引⽤修改。3. 成员函数:⽤于声明常量成员函数,表示该函数不会修改对象的成员变量(对于成员变量是⾮静态的情况)。static void helper() { // 静态函数,仅在 file1.cpp 中可见。// 指向常量的指针。6. 常量指针参数:声明函数参数为指向常量的指针,表示函数不会通过指针修改传⼊的数据。5. 常引⽤参数:声明函数参数为常量引⽤,表示函数不会修改传⼊的参数。
2025-02-08 22:04:05
447
原创 C++内存分区
堆⽤于存储动态分配的内存的区域,由程序员⼿动分配和释放。使⽤ new 和 delete 或 malloc 和 free 来进。全局区存储全局变量和静态变量。⽣命周期是整个程序运⾏期间。在程序启动时分配,程序结束时释放。栈⽤于存储函数的局部变量、函数参数和函数调⽤信息的区域。函数的调⽤和返回通过栈来管理。常量区也被称为只读区。存储常量数据,如字符串常量。⾏堆内存的分配和释放。
2025-02-08 22:03:09
227
原创 指针和引用的区别
在 C++ 中,指针(Pointer) 和 引用(Reference) 都可以用来间接访问变量,但它们在语法、使用方式、内存管理和可变性等方面存在明显的区别。引用是某个变量的别名(alias),必须在定义时初始化,且不能更改绑定的对象。// ref 是 a 的引用。可以动态更改指向的对象(即指针可以重新指向不同的地址)。// 通过指针修改 a 的值。// p 存储 a 的地址。// 直接修改 a 的值。需要使用 * 和 & 操作符进行解引用和取地址操作。指针是存储变量地址的变量,可以指向其他变量。
2025-02-08 22:01:59
185
原创 静态变量,全局变量和局部变量的区别,在内存上是怎么分布的
1. 静态局部变量作⽤域: 限定在定义它的函数内。⽣命周期: 与程序的⽣命周期相同,但只能在定义它的函数内部访问。关键字: 使⽤ static 关键字修饰。初始化: 仅在第⼀次调⽤函数时初始化,之后保持其值。当希望在函数调⽤之间保留变量的值,并且不希望其他函数访问这个变量时,可以使⽤静态局部变量void exampleFunction() {static int count = 0; // 静态局部变量count++;cout << "Count: " << count << endl;}内存分布:存储在静
2025-02-08 22:01:23
288
原创 如何保证数据库和缓存的一致性
问题:假如有两个操作⼀个更新⼀个查询,第⼀个操作先更新数据库,还没来及删除数据库,查询操作可能拿到的就是旧的数据;还有的问题就是有⼀个是读操作没有命中缓存,然后就到数据库中取数据,此时来了⼀个写操作,写完数据库后,让缓存失效,然后,之前的那个读操作再把⽼的数据放进去,也会造成脏数据。Read Through:就是在查询操作中更新缓存,也就是说,当缓存失效的时候,Cache Aside策略是由调⽤⽅负责把数据加载⼊缓存,⽽Read Through则⽤缓存服务⾃⼰来加载,从⽽对调⽤⽅是透明的。
2025-02-08 22:00:20
149
原创 Redis缓存雪崩,击穿穿透和解决方法
2. 缓存击穿是指⼀个缓存中不存在但是数据库中存在的数据,当有⼤量并发请求查询这个缓存不存在的数据时,导致请求直接访问数据库,增加数据库的负载。典型的场景是当⼀个缓存中的数据过期或被清理,⽽此时有⼤量请求访问这个缓存中不存在的数据,导致⼤量请求直接访问底层存储系统。3. 缓存穿透是指查询⼀个在缓存和数据库都不存在的数据,这个数据始终⽆法被缓存,导致每次请求都直接访问数据库,增加数据库的负载。对于缓存雪崩,可以通过合理设置缓存的过期时间,分散缓存失效时间点,或者采⽤永不过期的策略,再结合定期更新缓存。
2025-02-08 21:59:48
144
原创 Redis持久化机制有哪些
Redis 可以同时开启 RDB 和 AOF,结合两种方式的优点。通过快照方式,将内存中的数据以二进制文件保存到磁盘。通过记录每次写操作的日志,逐步重建数据。缺点:可能丢失最后一次快照后的数据。优点:适合大规模数据恢复,效率高。缺点:文件体积较大,恢复速度较慢。优点:数据安全性高。
2025-02-08 21:58:14
174
原创 Redis是单线程还是多线程的,为什么
Redis 的设计在核心命令处理上是单线程的,但在某些特定场景(如网络 I/O 和持久化操作)中引入了多线程。单线程足以高效处理内存中的键值操作。所有命令在单线程中串行执行,天然支持原子性操作(如事务、Lua 脚本),无需额外同步机制。减少了线程切换的开销,提高了 CPU 缓存的局部性,适合处理高吞吐量的内存操作。单线程模型不需要处理多线程的竞争条件(如锁、原子操作),简化了代码复杂度。多线程:网络 I/O 和持久化操作使用多线程提升性能。单线程:核心命令执行保持单线程,确保原子性和简单性。
2025-02-08 21:57:40
121
原创 Redis的数据类型有哪些
Redis 常⻅的五种数据类型:String(字符串),Hash(哈希),List(列表),Set(集合)及 Zset(sortedset:有序集合)。5. 有序集合 ZSET :类似于集合,但每个元素都关联⼀个分数,可以按分数进⾏排序。HyperLogLog :⽤于基数估算的数据结构,⽤于统计元素的唯⼀数量。1. 字符串 STRING :存储字符串数据,最基本的数据类型。2. 哈希表 HASH :存储字段和值的映射,⽤于存储对象。4. 集合 SET :存储唯⼀的字符串元素,⽆序。
2025-02-08 21:57:09
230
原创 Redis有什么优缺点?为什么Redis查询会比较快
支持字符串(String)、哈希(Hash)、列表(List)、集合(Set)、有序集合(ZSet)、流(Stream)等数据结构,可直接实现复杂业务逻辑(如排行榜、消息队列)。极高性能:内存存储:数据直接存储在内存中,避免了磁盘I/O的瓶颈,读写速度达到微秒级(单机 QPS 可达 10万+)。支持主从复制、哨兵模式(Sentinel)和集群模式(Cluster),可水平扩展应对海量数据和高并发。提供 RDB(快照)和 AOF(日志追加)两种持久化方式,可根据需求平衡性能与数据安全性。
2025-02-04 17:06:52
231
原创 MySQL和Redis的区别
Redis:键值对存储(NoSQL),支持多种数据结构(如字符串、哈希、列表、集合、有序集合等)。MySQL:关系型数据库,采用表格结构存储数据,支持复杂的SQL查询、多表关联(JOIN)、事务、外键约束等。Redis:单线程模型(避免锁竞争)和内存存储使其吞吐量极高(每秒数十万次操作),适合高并发、低延迟场景(如缓存、计数器)。MySQL:完整支持ACID事务(原子性、一致性、隔离性、持久性),适合需要强一致性的场景(如支付系统)。需要复杂查询、事务、数据一致性的场景(如用户账户、订单系统)。
2025-02-04 17:06:16
465
原创 什么是慢查询?原因是什么?可以怎么优化
数据库查询的执⾏时间超过指定的超时时间时(long_query_time:默认10秒 ),就被称为慢查询。硬件资源不⾜:如果MySQL服务器上同时运⾏了太多的查询,会导致服务器负载过⾼,从⽽导致查询变慢。查询数据量⼤:当查询的数据量庞⼤时,即使查询本身并不复杂,也可能导致较⻓的执⾏时间。查询语句⽐较复杂:查询涉及多个表,包含复杂的连接和⼦查询,可能导致执⾏时间较⻓。缺少索引:如果查询的表没有合适的索引,需要遍历整张表才能找到结果,查询速度较慢。数据库设计不合理:数据库表设计庞⼤,查询时可能需要较多时间。
2025-02-03 15:22:38
236
原创 undo log redo log和binlog有什么用
undo log 记录的信息包括操作类型(插⼊、删除还是更新),修改前的数据值,被修改的数据的位置,事务标识id等,⽐如在更新⼀条记录时,要把被更新的列的旧值记下来,这样之后回滚时再把这些列更新为旧值就好了。redo log 是物理⽇志,记录了某个数据⻚做了什么修改,⽐如对 XXX 表空间中的 YYY 数据⻚ ZZZ 偏移量的地⽅做了AAA 更新,每当执⾏⼀个事务就会产⽣这样的⼀条或者多条物理⽇志。通过 undo log ,数据库系统可以逆向执⾏事务的操作,将数据库还原到事务开始前的状态。
2025-02-03 15:22:04
308
原创 说一下索引失效的场景
在 WHERE ⼦句中,如果在 OR 前的条件列是索引列,⽽在 OR 后的条件列不是索引列,那么索引会失效。数据分布不均匀: 如果数据分布不均匀,例如某个索引列的⼤多数值都相同,选择性降低,导致索引失效。隐式类型转换: 如果查询中的条件涉及到隐式类型转换,例如将字符串与数字⽐较,索引可能⽆法被使⽤。使⽤左或者左右模糊匹配:⽐如 LIKE '%abc' 这样的查询会导致索引失效。在索引列上使⽤函数或表达式: 索引列上参与计算,索引失效。违背最左匹配原则,索引失效。
2025-02-03 15:21:34
185
原创 MySQL为什么用B+树做索引
B+树的⾮叶⼦节点不存放实际的记录数据,仅存放索引,所以数据量相同的情况下,相⽐存储即存索引⼜存记录的 B 树,B+树的⾮叶⼦节点可以存放更多的索引,因此 B+ 树可以⽐ B 树更「矮胖」,查询底层节点的磁盘 I/O次数会更少。B+ 树有⼤量的冗余节点(所有⾮叶⼦节点都是冗余索引),这些冗余索引让 B+ 树在插⼊、删除的效率都更⾼,⽐如删除根节点的时候,不会像 B 树那样会发⽣复杂的树的变化;
2025-02-03 15:20:58
225
原创 MySQL的执行引擎有哪些
InnoDB : MySQL默认的事务性存储引擎,⽀持事务的提交(commit)和回滚(rollback),提供了⾏级锁定,⽀持外键约束和MVCC。在MySQL中,可以通过 SHOW ENGINES;命令查看当前数据库⽀持的存储引擎。InnoDB是较为通⽤和常⽤的存储引擎。Memory : 将数据放在内存中,数据处理速度很快,但是当数据库重启或崩溃时,存储在内存中的数据将丢失。MyISAM : MyISAM 使⽤表级锁定, 不⽀持事务,⽀持全⽂索引,适⽤于以读操作为主的应⽤。
2025-02-03 15:20:28
300
原创 事务的四大特征
3. 隔离性:多个事务并发执⾏时,每个事务都应该被隔离开来,⼀个事务的执⾏不应该影响其他事务的执⾏。4. 持久性:⼀旦事务被提交,它对数据库的改变就是永久性的,即使在系统故障或崩溃后也能够保持。1. 原⼦性:确保事务的所有操作要么全部执⾏成功,要么全部失败回滚,不存在部分成功的情况。2. ⼀致性:事务在执⾏前后,数据库从⼀个⼀致性状态转变到另⼀个⼀致性状态。事务的四⼤特性通常被称为 ACID 特性。
2025-02-03 15:19:58
107
原创 数据库的事务隔离级别
事务执⾏期间,多次读取同⼀数据会得到相同的结果,即在事务开始和结束之间,其他事务对数据的修改不可⻅。最⾼的隔离级别,确保事务之间的并发执⾏效果与串⾏执⾏的效果相同,即不会出现脏读、不可重复读和幻读。⼀个事务只能读取已经提交的数据。其他事务的修改在该事务提交之后才可⻅。最低的隔离级别,存在脏读、不可重复读和幻读的问题。允许⼀个事务读取另⼀个事务尚未提交的数据修改。解决了脏读问题,但仍可能出现不可重复读和幻读。解决了不可重复读问题,但仍可能出现幻读。
2025-02-03 15:19:27
146
原创 一条SQL语句是如何进行的
查询缓存:查询语句如果命中查询缓存则直接返回,否则继续往下执⾏。MySQL 8.0 已删除该模块;预处理阶段:检查表或字段是否存在;将 select * 中的 * 符号扩展为表上的所有列。解析 SQL,通过解析器对 SQL 查询语句进⾏词法分析、语法分析,然后构建语法树。执⾏阶段:根据执⾏计划执⾏ SQL 查询语句,从存储引擎读取记录,返回给客户端。优化阶段:基于查询成本的考虑, 选择查询成本最⼩的执⾏计划;连接器:跟客户端建⽴连接、获取权限、维持和管理连接。
2025-02-03 15:18:53
192
原创 说一下select,poll,epoll
poll: poll是select的⼀种改进,它使⽤轮询⽅式来检查多个⽂件描述符的状态,避免了select中⽂件描述符数量有限的问题。I/O多路复⽤允许在⼀个线程中处理多个I/O操作,避免了创建多个线程或进程的开销,允许在⼀个线程中处理多个I/O操作,避免了创建多个线程或进程的开销。效率相对较⾼: poll 在查找就绪的⽂件描述符时,只需要遍历实际使⽤的⽂件描述符数组,⽽不是整个⽂件描述符集合。⽂件描述符数量不受限制:由于 poll 使⽤⼀个动态数组来表示⽂件描述符,因此它可以处理任意数量的⽂件描述符。
2025-02-03 15:18:19
261
原创 如何查看某个端口有没有被占用
t 表示 TCP 协议,-u 表示 UDP 协议,-l 显示监听端口,-n 以数字格式显示。-ano 表示显示所有连接和监听端口(a)、以数字格式显示(n)、并显示进程 PID(o)。grep 端口号: 使用 grep 命令过滤出指定的端口号信息。netstat -ano | findstr :<端口号>netstat -tuln | grep :<端口号>ss -tuln | grep :<端口号>方法一:使用 netstat 命令。1. Windows 系统。2. Linux 系统。
2025-02-03 15:17:37
3675
原创 熟悉哪些linux指令
apt(Debian/Ubuntu)或 yum(Red Hat/CentOS):包管理器,⽤于安装、更新和删除软件包。head 和 tail:查看⽂件的开头和结尾部分。tar:创建和提取归档⽂件(通常是.tar⽂件)。ls:列出当前⽬录下的⽂件和⼦⽬录。mv:移动⽂件或⽬录,也⽤于重命名。chown:更改⽂件或⽬录的所有者。chmod:更改⽂件或⽬录的权限。pwd:显示当前⼯作⽬录的路径。find:查找⽂件和⽬录。touch:创建新⽂件。cat:显示⽂件的内容。rm:删除⽂件或⽬录。cp:复制⽂件或⽬录。
2025-02-03 15:17:06
177
原创 有哪些页面置换算法
这种策略基于你对⻆⾊的喜好,认为最近被使⽤过的⻆⾊很可能还会被使⽤,⽽最久未被使⽤的⻆⾊很可能不会再被使⽤。时钟⻚⾯置换算法:把所有的⻚⾯都保存在⼀个类似钟⾯的「环形链表」中,⻚⾯包含⼀个访问位。置换在「未来」最⻓时间不访问的⻚⾯,但是实际系统中⽆法实现,因为程序访问⻚⾯时是动态的我们是⽆法预知每个⻚⾯在「下⼀次」访问前的等待时间,因此作为实际算法效率衡量标准。最不常⽤算法 :记录每个⻚⾯访问次数,当发⽣缺⻚中断时候,将访问次数最少的⻚⾯置换出去,此⽅法需要对每个⻚⾯访问次数统计,额外开销。
2025-02-03 15:16:36
192
原创 你知道的线程同步方式有哪些
2. 条件变量:条件变量⽤于线程间通信,允许⼀个线程等待某个条件满⾜,⽽其他线程可以发出信号通知等待线程。通常与互斥锁⼀起使⽤。线程同步机制是指在多线程编程中,为了保证线程之间的互不⼲扰,⽽采⽤的⼀种机制。1. 互斥锁:互斥锁是最常⻅的线程同步机制。它允许只有⼀个线程同时访问被保护的临界区(共享资源)3. 读写锁: 读写锁允许多个线程同时读取共享资源,但只允许⼀个线程写⼊资源。4. 信号量:⽤于控制多个线程对共享资源进⾏访问的⼯具。
2025-02-03 15:16:05
117
原创 讲一讲你理解的虚拟内存
操作系统将虚拟内存划分为一块块页面,每个页面可以映射到物理内存中的一个页面,或者映射到磁盘中的交换空间(如交换文件或交换分区)。页面置换:当物理内存不足时,操作系统会将不常用的内存页从内存中移到磁盘的交换空间中,腾出空间来加载其他页。地址空间隔离:每个进程都有自己的虚拟地址空间,它们之间是相互隔离的,这样可以避免一个进程访问或修改另一个进程的内存,增加了系统的安全性和稳定性。通过虚拟内存,操作系统能有效地扩展内存容量,提高系统的利用率,并且使得进程能够在有限的物理内存上运行更大的应用程序。
2025-01-27 22:00:29
158
原创 介绍几种典型的锁
互斥锁:互斥锁是⼀种最常⻅的锁类型,⽤于实现互斥访问共享资源。在任何时刻,只有⼀个线程可以持有互斥锁,其他线程必须等待直到锁被释放。这确保了同⼀时间只有⼀个线程能够访问被保护的资源。读写锁:允许多个线程同时读共享资源,只允许⼀个线程进⾏写操作。⾃旋锁:⾃旋锁是⼀种基于忙等待的锁,即线程在尝试获取锁时会不断轮询,直到锁被释放。悲观锁:认为多线程同时修改共享资源的概率⽐较⾼,所以访问共享资源时候要上锁。乐观锁:先不管,修改了共享资源再说,如果出现同时修改的情况,再放弃本次操作。其他的锁都是基于这两个锁的。
2025-01-27 21:59:57
179
原创 什么是死锁?如何预防死锁
破坏不可剥夺条件:占⽤部分资源的线程进⼀步申请其他资源时,如果申请不到,可以主动释放它占有的资源。让所有进程按照相同的顺序请求资源,释放资源则反序释放。环路等待条件:多个进程之间形成⼀个循环等待资源的链,每个进程都在等待下⼀个进程所占有的资源。不可剥夺条件:资源不能被强制性地从⼀个进程中剥夺,只能由持有者⾃愿释放。请求保持条件:⼀个线程因为请求资源⽽阻塞的时候,不会释放⾃⼰的资源。互斥条件:⼀个进程占⽤了某个资源时,其他进程⽆法同时占⽤该资源。破坏请求与保持条件:⼀次性申请所有的资源。
2025-01-27 21:59:24
203
原创 Cookie和Session是什么?有什么区别
Cookie 是存储在⽤户浏览器中的⼩型⽂本⽂件,⽤于在⽤户和服务器之间传递数据。这就是 Session。Cookie 和 Session 都⽤于管理⽤户的状态和身份, Cookie 通过在客户端记录信息确定⽤户身份, Session 通过在服务器端记录信息确定⽤户身份。服务器在接收到来⾃客户端浏览器的请求之后,就能够通过分析存放于请求头的Cookie得到客户端特有的信息,从⽽动态⽣成与该客户端相对应的内容。存储位置:Cookie 数据存储在⽤户的浏览器中,⽽ Session 数据存储在服务器上。
2025-01-26 15:13:34
122
原创 CDN是什么
CDN,全称为内容分发⽹络 (Content Delivery Network) , 过将内容存储在分布式的服务器上,使⽤户可以从距离较近的服务器获取所需的内容,从⽽减少数据传输的时间和距离,提⾼内容的传输速度、减少延迟和提升⽤户体验。如果有缓存,CDN 节点会直接返回缓存的资源,如果没有缓存所需资源,它会从源服务器(原始服务器)回源获取资源,并将资源缓存到节点中,以便以后的请求。如果⽹站启⽤了 CDN,DNS 解析会返回距离⽤户最近的 CDN 节点的 IP 地址,⽽不是原始源服务器的 IP 地址。
2025-01-26 15:13:02
127
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人