自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(127)
  • 收藏
  • 关注

原创 仿Spdlog日志系统项目

参考开源项目Spdlog,实现日志库

2025-02-26 00:03:42 833 1

原创 【高阶数据结构(一)】:LRU Cache

LRU概念、LRU实现机制、以力扣(146. LRU 缓存)实现所有操作(增删查改)时间复杂度为O(1)

2025-02-05 23:27:54 606 1

原创 Mysql:数据库

在mysql中,不仅仅物理磁盘上存在的表结构叫表,中间筛选出来的,以及最终结果也是逻辑上的表。而口语中思的数据库指数据在磁盘上存取的一套解决方案(create databases创建出来的数据库)日常口语中的数据库其实是指在磁盘或内存中存储的特定组织结构的数据。修改表的结构有,比如字段名字,字段大小,字段类型,表的字符集类型,表的存储引擎等等。存储引擎是:数据库管理系统如何存储数据、如何为存储的数据建立索引和如何更新、查询数据等技术的实现方法(目录下的一个目录文件,而建表本质就是该该目录下的一些普通文件。

2025-02-05 22:57:01 1429

原创 【Linux 网络 (五)】Tcp/Udp协议

本篇文章主要介绍TCP/Udp报头相关字段,以及tcp可靠性保证机制:确认应答信号、重发机制、连接管理、窗口控制、流量控制、拥塞控制;以及tcp连接管理(3次握手,4次挥手,及相关状态转变细节)

2024-12-23 17:53:11 1595 3

原创 【Linux 网络 (三)】:https协议加密解密分析 —— 秘钥协商

本篇博客主要介绍加密、解密、常见加密方式(对称加密和非对称加密)、数据摘要 && 数据指纹、数字签名、HTTPS 的⼯作过程探究(加密流程)

2024-12-23 17:50:58 798

原创 Linux通信System V:消息队列 & 信号量

System V版本基于消息队列和信号量的通信方式,以及OS如何管理ipc资源

2024-12-21 00:22:15 675 2

原创 Linux文件:动静态库制作 & 动态库链接原理解析

动静态库制作、动态库链接原理解析、链接库报错原理解析

2024-12-20 21:31:53 1081

原创 【Linux网络 (二)】套接字编程

本篇文章将会详细介绍套接字概念,以及TCP/UDP套接字编程接口

2024-11-23 11:39:35 1052 16

原创 Mysql数据库约束

数据库是用户数据的最后一道保护屏障,所以数据库存在大量的约束,保证数据库中数据的完整性和可预期性。数据库中,数据类型本身就是一种约束,除此在外还有: null/not null,default, comment,zerofill,primary key,auto_increment,unique key。

2024-10-05 23:06:41 1486 2

原创 Mysql:数据库和表增删查改基本语句

创建数据库本质就是创建一个目录(ubuntu,创建的目录文件存放在后续创建表本质就是在该目录下创建文件(不同存储引擎,会创建的文件数目是不同的)!编码集是mysql存储数据时的编码格式。在mysql中,经常需要进程数据比较操作,但比较的前提是数据先被读出来。而校验集就是mysql读取数据时采用的编码格式。

2024-10-05 21:37:54 753

原创 C++:类型转换(static_cast、reinterpret_cast、const_cast、dynamic_cast)、RTTI

由于C语言两种类型转换方式都存在缺陷:隐式类型转换会导致诸如数据精度丢失等问题;而显示类型转化代码不清晰。所以C++在兼容C的基础之上,增加了4中强制类型转换:static_cast、reinterpret_cast、const_cast、dynamic_cast。RTTI:Run-time Type identification的简称,即:运行时类型识别。typeid运算符dynamic_cast运算符decltype。

2024-09-22 10:47:34 1255 4

原创 C++11新增特性:智能指针(RAII)

在C++的发展史中,一个出现了4种智能指针,依次为auto_ptr、unique_ptr、shared_ptr、weak_ptr(weak_ptr不符合RAII思想,用于对shared_ptr的补贴)同理,n1的引用计数也更新为2!但是_next属于n2的成员,n1释放了,_next才会析构,而n2由_prev管理,_prev属于n1成员,此时就发生了循环引用,谁也不会释放。weak_ptr不符合RAII,不参与引用计数,仅是对 shared_ptr 所管理对象的一个非拥有性引用,但可以像指针一样使用!

2024-09-22 10:35:34 1636 1

原创 C++:异常

assert断言。比如程序发送段错误时,会触发assert,导致程序直接退出。错误码。程序异常返回错误码,虽然每种错误码背后对于一类错误,但程序员还是无法明确错误原因,以及错误位置,需要程序员自身去查找!所有C++引入了异常机制。当一个函数发生无法处理的错误后,会抛出异常,让函数的直接或间接调用者对该异常进行捕获处理!!C++通过throw抛出异常,当一段段程序可能抛出错误,捕获异常的方式采用try和catch关键字。其中try中存放可能抛出异常的代码,而try中的代码也被称为保护代码;

2024-09-17 22:45:00 1288 3

原创 C++11新增特性:lambda表达式、function包装器、bind绑定

在c++98中,我们使用sort对一段自定义类型进行排序的时候,每次都需要传一个仿函数,即手写一个完整的类。甚至有时需要同时实现排升序和降序,就需要各自手写一个类,非常不方便!所以C++11引入了lambda表达式!lamaba是一个匿名函数对象,是一个可调用对象,表达式本质上也是一个类(vs中类名为lambda_),并实现了operator()。

2024-09-17 22:00:00 1798

原创 如何快速判断一个数是否为2的倍数?(正整数)

牛牛有一个数组,里面的数可能不相等,现在他想把数组变为:所有的数都相等。牛牛可以进行的操作是:将数组中的任意一个数改为这个数的两倍。首先,如果一个数是2的倍数,此时该数都对应的二进制只存在唯一 一个1(比如8对应1000)。前面以及提到过,如果个数是2的倍数,此时该数的二进制只存在唯一的1,其余全为0。所以如果一个数为2的倍数,此时x&-x得到的结果任然为x。所以如果一个数为2的倍数,此时x & (x - 1)=0!,一旦出现模2结果非0的情况,则表明该数不是2的倍数!

2024-09-07 00:59:36 813 4

原创 C++11重大新增特性:左值引用 & 右值引用 & 移动构造 & 移动赋值

如果能想要限制某些默认函数的生成,在C++98中,是该函数设置成private,并且只声明补丁已,这样只要其他人想要调用就会报错。(这很好理解,以移动构造和移动赋值为例,其最重要的功能就是转移右值的资源。在C++11中更简单,只需在该函数声明加上=delete即可,该语法指示编译器不生成对应函数的默认版本,称=delete修饰的函数为删除函数。只有当自定义类型中存在资源的深拷贝时,此时才能移动构造和移动赋值的价值。类似于拷贝构造函数,移动构造函数的第一个参数是该类类型的引用,不同的是引用参数是一个右值。

2024-09-04 14:30:41 1323 3

原创 C++11新增特性:列表初始化(std::initializer_list)& decltype、auto、nullptr、范围for

C++11扩大了初始化列表的使用范围,可用于所有的内置类型和自定义类型的初始化。在C++11中,初始化类列表可用于容器默认构造函数和拷贝复制函数的统一初始值设定!但获取到的变量类型是以字符串形式显示的,无法作为类型定义变量继续使用。在C++98之前,{}一般被用于对数组或结构体元素的统一的列表初始值设定。作为参数的构造函数和赋值重载函数,这样初始化容器对象就更方便了。对象中的值,然后调用容器插入相关接口插入数据。可以将变量类型声明为表达式的指定类型!在C++11中,几乎所有的容器都新增了。

2024-09-04 14:13:44 1093 1

原创 【Linux 网络(一)】初识网络,理解TCP/IP五层模型

本篇文章将会介绍网络产生的背景、OSI网络7层、已经网络传递过程中报文解包封装的宏观结构

2024-08-27 21:09:31 1420 3

原创 Linux 操作系统:基于环形队列的生产者消费者模型

环形队列采用数组模拟,用模运算来模拟环状特性。和基于阻塞队列的生产者消费者模型不同的是,环形队列将公共资源分成多份使用,而阻塞队列则是将公共资源当作一个整体使用!!Linux OS:线程封装 | RAII封装锁 | 随机数运算任务封装。

2024-08-09 21:40:19 1435 22

原创 Linux OS:基于阻塞队列的生产者消费者模型

阻塞队列是一种常用于实现生产者消费者模型的数据结构。和普通队列不同的时,队列存在上限,当队列未满时,往队列中插入数据的操作会被阻塞;当队列为空时,从队列中获取数据的操作也会被阻塞!在Linux OS:线程封装 | RAII封装锁 | 随机数运算任务封装中,对锁进行了封装,后续加锁解锁操作都基于此!

2024-08-05 14:16:40 1349 3

原创 Linux:线程概念 | 线程控制

当CPU调度执行该“”进程“时,只会执行原本进程中的一部分代码和数据,执行我们要执行任务的一部分任务,我们将这种比传统“进程”更加轻量化的进程就称为线程!)下,其中一些线程抢占锁的能力是非常强的,导致其他线程长时间无法获得锁资源,导致线程饥饿问题。我们也将这种线程称为轻量级进程!在Linux中,如果操作系统真的支持线程,此时在计算机中必然存在大量的线程,所以OS需要对线程进行管理。如果不关心线程的返回值,join是一种负担,这个时候,我们可以将线程设置为分离状态,告诉系统,当线程退出时,自动释放线程资源!

2024-07-28 22:15:00 2084 3

原创 Linux: Mysql环境安装

安装mysql环境

2024-07-13 15:11:11 1095 6

原创 Linux通信:基于System V共享内存方式实现进程间通信

一、基于共享内存通信方式原理二、共享内存优缺点2.1 共享内存优缺点2.2 基于文件通信 vs 共享内存通信三、相关函数调用接口2.1 创建共享内存(shmget)2.1.1 key2.1.2 size2.1.3 shmflg2.1.4 返回值2.2 共享内存段挂接到进程地址空间(shmat)2.3 将共享内存段与当前进程脱离(shmdt)2.4 用于控制共享内存(删除)(shmctl)四、基于System V共享内存实现进程间通信

2024-07-12 21:30:00 2052 5

原创 Linux进程间通信:匿名管道 &命名管道

管道最早是UNIX中的一种进程通信方式。我们把一个进程到另一个进程的一个数据流称为管道!!管道文件时一个纯内存级文件,不需要想磁盘刷新。进程间通信的本质是不同进程看到同一份资源。该资源一般由操作系统提供!!(比如缓冲区) 进程间通信目的主要有:数据传输:一个进程需要将它的数据发送给另一个进程。资源共享:多个进程之间共享同样的资源。通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程)。进程控制:有些进程希望完全控制另一个进程的执行(如Debug

2024-07-11 21:30:00 1348 1

原创 Linux:进程池制作(匿名管道版本 & 命名管道版本)

创建进程是有时间成本的。当计算机要执行任务时才创建进程,势必会影响执行任务的性能。所以我们可以通过提前创建一批进程,当有任务需要被执行时直接喂给这些进程即可。我们把这些提前创建好的进程称为进程池!!下面我们会通过一个主进程(父进程)通过匿名管道和一批工作进程(子进程)进行通信。父进程通过不断派发任务给子进程,子进程通过读取管道文件中的任务码来执行对应的任务,从而模拟进程池的整个行为!!

2024-07-11 21:30:00 1479 6

原创 Linux进程信号的产生、保存、处理

详细介绍信号的产生、保存、处理全流程。包含core dump、可重入函数、volatile关键字、SIGCHLD信息相关知识

2024-07-10 05:45:00 1768 24

原创 Linux文件:EXT2文件系统工作原理 & 软硬链接

一、磁盘结构、存储策略:磁盘存储结构、磁盘存储策略、磁盘的逻辑存储结构二、如何管理磁盘文件三、如何管理组、每个组保存的数据种类、如何管理数据1、节点表(inode Table)、inode Bitmap、Data blocks、Block Bitmap、Group Descriptor Table、超级块(Super Block)四、目录、文件名和inode映射关系五、挂载:格式化、挂载六、操作系统查找、打开、创建文件过程:查找文件、打开文件、创建文件七、软硬链接

2024-07-10 00:22:20 1343 8

原创 Linux:进程终止和进程替换

一、进程终止1.1 进程退出场景和创建退出方式1.2 exit 和 _exit区别二、进程程序替换2.1 进程替换函数2.2 函数解释及命名解释函数解释命名解释2.3 单进程程序替换(无子进程)2.3.1 带`l`函数进程替换(execl为例)2.3.2 带`p‘函数进程替换(execlp为例)2.3.3 execv、execvp替换函数应用实例2.4 进程替换其他程序,调用运行其他语言程序三、进程替换时环境变量的继承3.1 进程替换时,子进程环境变量由来3.2 为何父子进程间

2024-07-07 00:31:00 1432 4

原创 Linux: 命令行参数和环境变量究竟是什么?

一、命令行参数:main函数参数意义、命令行参数概念、命令行参数实例二、环境变量:环境变量概念、 环境变量、PWD、HOME三、获取环境变量的3种方式:getenv()函数、main函数传参、通过第三方变量environ获取四、环境变量如何获取:子进程环境变量获取方式、父进程环境变量获取方式五、本地变量和环境变量六、Linux命令分类和环境变量相关的命令

2024-07-05 18:15:18 1510 6

原创 vscode:如何解决”检测到include错误,请更新includePath“

 配置vscode是出现如下错误:”检测到include错误,请更新includePath“

2024-05-26 12:59:59 7575 9

原创 Linux文件:缓冲区、缓冲区刷新机制 | C库模拟实现

我们可以快速向缓冲区中写入数据,然后通过一定的刷新方式。将数据从语言级别的缓冲区中拷贝到内核缓冲区。下面我们调用3个常见的C库函数和一个系统调用,都向显示器文件中进行写入。对于文件的IO等操作,用户可以直接通过系统调用直接向操作系统进行读操作和写操作。缓冲区可以暂存数据,必定存在一定的刷新机制。的原因在于:系统调用在语言之下,数据不是向语言基本的缓冲区中写入;此时数据属于操作系统,不在属于进程!同时由于缓冲区的存在,我们可以积累一定的数据后在统一发生,C所提供的缓冲区是二次加上的,由C本身所提供!

2024-05-23 20:46:19 1209 8

原创 Linux文件:重定向底层实现原理(输入重定向、输出重定向、追加重定向)

在Linux中,操作系统会为每一个文件创建对应的描述结构体对象。该结构体中一定存在3个部分:打开文件的所有属性、文件的操作集、文件缓冲区(内存)。其中由于冯诺依曼体系决定了,无论对文件进行读操作还是写操作,都需要先将数据加载到文件缓存区!我们在应用层进行对数据读写的操作本质上是用户缓冲区和内核数据缓冲区之间的相互拷贝!!!

2024-05-15 23:06:49 1695 5

原创 Linux:文件 | 文件描述符 | Linux下一切皆文件

所有对文件的操作本质上就分为:对内容的修改和对属性的修改。内容是数据,属性也是数据。所以存储文件,必须同时存储文件相关的数据信息和属性信息。默认情况下文件存储在磁盘中,但由于冯诺依曼体系,CPU只能从内存中获取文件信息,对文件进行操作。所以当进程打开文件时,OS需要先将文件信息加载到内存中,在被CPU调度执行对文件进行操作!!一个进程可以打开多个文件,多个进程也可以打开同一个文件。所以当文件被加载到内存时,被打开的文件可能存在多个。操作系统需要对这些文件进行管理。先组织在描述!!

2024-05-15 19:21:39 1326

原创 进程并发究竟是如何进行进程切换的?Linux内核原理解析

实时操作系统(Real Time Operating System,简称RTOS)是指当外界事件或数据产生时,能够接受并以足够快的速度予以处理,其处理的结果又能在规定的时间之内来控制生产过程或对处理系统做出快速响应,调度一切可利用的资源完成实时任务,并控制所有实时任务协调一致运行的操作系统。此时操作系统会在进程被剥离前,将当前进程的运行相关信息保存到PCB中,然后将该进程的PCB从活跃队列中移除,加载到过期队列。至于新产生的需要被调度的进程,则是直接添加到过期队列中。活跃进程、过期进程。

2024-04-06 10:50:22 1866 5

原创 Linux:进程等待究竟是什么?如何解决子进程僵尸所带来的内存泄漏问题?

一、进程等待的概念二、进程等待存在的意义三、如何进行进程等待3.1 wait()是实现进程等待3.2 waitpid()实现进程等待四、获取子进程status实现机制五、阻塞等待和非阻塞等待5.1 阻塞等待5.2 非阻塞等待(非阻塞 + 轮询方案)六、非阻塞轮询方案示例演示

2024-04-06 10:46:45 3496 96

原创 算法沉淀 —— 动态规划(子序列问题(上))

几乎所有的动态规划问题大致可分为以下5个步骤,后续所有问题分析都将基于此1.、状态表示:通常状态表示分为以下两种,其中更是第一种为主。以i为结尾,dp[i] 表示什么,通常为代求问题(具体依题目而定)以i为开始,dp[i]表示什么,通常为代求问题(具体依题目而定)2、状态转移方程以上述的dp[i]意义为根据, 通过最近一步来分析和划分问题,由此来得到一个有关dp[i]的状态转移方程。3、dp表创建,初始化动态规划问题中,如果直接使用状态转移方程通常会伴随着越界访问等风险,所以一般需要初始化。

2024-04-04 18:17:18 1381 40

原创 算法沉淀——动态规划篇(子数组系列问题(下))

几乎所有的动态规划问题大致可分为以下5个步骤,后续所有问题分析都将基于此1.、状态表示:通常状态表示分为以下两种,其中更是第一种为主。以i为结尾,dp[i] 表示什么,通常为代求问题(具体依题目而定)以i为开始,dp[i]表示什么,通常为代求问题(具体依题目而定)2、状态转移方程以上述的dp[i]意义为根据, 通过最近一步来分析和划分问题,由此来得到一个有关dp[i]的状态转移方程。3、dp表创建,初始化动态规划问题中,如果直接使用状态转移方程通常会伴随着越界访问等风险,所以一般需要初始化。

2024-04-04 18:16:50 1472 32

原创 算法沉淀 —— 动态规划篇(简单多状态dp问题上)

力扣:面试题 17.16. 按摩师、LCR 090. 打家劫舍 II、740. 删除并获得点数、LCR 091. 粉刷房子

2024-04-02 23:31:09 1058 5

原创 算法沉淀 —— 深度搜索(dfs)

leetcode:2331. 计算布尔二叉树的值、129. 求根节点到叶节点数字之和、814. 二叉树剪枝、98. 验证二叉搜索树、230. 二叉搜索树中第K小的元素

2024-04-01 16:14:07 1656 29

原创 递归究竟是什么?如何快速编写正确的递归代码? —— 力扣经典面试题详解

归是一种算法设计技术,它允许一个函数在其定义或说明中有直接或间接调用自身的方法。递归在数学和计算机科学中有着广泛的应用,它通过将复杂问题分解为规模较小、形式相同的子问题来求解。递归的基本原理包括:每一级的函数调用都有自己的变量;每一次函数调用都会有一次返回;递归函数中,位于递归调用前的语句和各级被调用函数具有相同的执行顺序;递归函数中,位于递归调用后的语句的执行顺序和各个被调用函数的顺序相反;虽然每一级递归都有自己的变量,但是函数代码并不会得到复制。

2024-04-01 16:12:10 1455 46

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除