自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 I/O多路转接之 select 与 poll

在Linux系统中,I/O多路转接是一种重要的I/O模型,它能够同时等待多个文件描述符的就绪状态,同时处理多个客户端的请求而不创建多线程,提高程序的效率。本文将重点介绍I/O多路转接中的select和poll。

2024-08-17 23:25:22 1102

原创 五种IO模型

在进行网络编程或文件操作时,IO模型的选择对程序的性能和效率有着重要的影响。本文将介绍五种IO模型,并详细讨论非阻塞IO的相关内容。数据准备、数据读写通俗一点: IO = 等待 + 拷贝。

2024-08-17 22:23:56 753

原创 从Linux内核探索 Socket 的本质

socket 中文套接字,可理解为一套用于连接的数字。sock在内核,socket_fd在用户空间,socket层介于内核和用户空间之间。在操作系统内核空间里,实现网络传输功能的结构是sock,基于不同的协议和应用场景,会被泛化为各种类型的xx_sock,它们结合硬件,共同实现了网络传输功能。为了将这部分功能暴露给用户空间的应用程序使用,于是引入了socket层,同时将sock嵌入到文件系统的框架里,sock就变成了一个特殊的文件,用户就可以在用户空间使用文件句柄,也就是socket_fd来操作内核。

2024-08-16 23:13:15 845

原创 既然IP层会分片,为什么TCP层也还要分段?

数据在TCP分段,在IP层就不需要分片,同时发生重传的时候只重传分段后的小份数据。TCP分段时使用MSS,IP分片时使用MTU。MSS是通过MTU计算得到,在三次握手和发送消息时都有可能产生变化。IP分片是不得已的行为,尽量不在IP层分片,尤其是链路上中间设备的IP分片。因此,在IPv6中已经禁止中间节点设备对IP报文进行分片,分片只能在链路的最开头和最末尾两端进行。建立连接后,路径上节点的MTU值改变时,可以通过PMTU发现更新发送端MTU的值。

2024-08-16 21:54:10 911

原创 使用 C/C++访问 MySQL

1.初始化要使用库,必须先进行初始化!返回值是一个MySQL文件句柄,后续的操作都要用它2.链接数据库初始化完毕之后,必须先链接数据库,再进行后续操作。(MySQL 网络部分是基于 TCP/IP 的)//返回nullptr则代表连接失败注意:建立好链接之后,如果获取中文是乱码,需要设置链接的默认字符集是 utf8,原始默认是 latin1。第一个参数MYSQL是 C API 中一个非常重要的变量(mysql_init的返回值),里面内存非常丰富,有portdbnamecharset。

2024-08-15 23:37:12 808

原创 leetcode:二分查找、移除元素

二分模板:详细说明,往期博客:二分专题----如何优雅的写出二分本题代码:暴力代码1:双重循环:暴力代码2:空间换时间(不满足原地修改数组的题意!)双指针代码1:同向双指针双指针代码2:对撞指针

2024-08-13 11:24:42 572

原创 Protobuf:原理、用法与 C++ 实践

在当今的软件开发领域,高效的数据序列化和通信协议是构建高性能、可扩展系统的关键。Protobuf(Protocol Buffers)作为一种流行的开源序列化框架,正因其出色的性能、简洁的语法和跨语言支持而备受青睐。本文将深入探讨 Protobuf 的原理和用法,并通过 C++ 代码进行实际操作演示。

2024-08-10 00:11:49 926

原创 TCP 通信全流程分析:从连接建立到数据传输的深度探索

假设主动关闭方发送的最后一个 ACK 丢失了,被动关闭方会因为没有收到 ACK 而重传 FIN 报文。如果主动关闭方没有处于 TIME_WAIT 状态而是直接关闭,就无法响应重传的 FIN 报文,导致被动关闭方不能正常关闭连接。

2024-08-08 17:22:06 1230

原创 C/C++关键字大全

4、static修饰成员函数,不与特定的对象相关联,可以通过类名和作用域解析运算符直接调用,虽然仍然可以使用实例化对象调用静态成员函数,但在实际编程中不推荐这样的写法,因为静态成员函数不依赖于具体的对象实例,它是属于整个类的。通过将成员设置为私有,并提供公共的接口函数来控制对象的状态和行为,可以更好地实现面向对象编程中的封装和信息隐藏原则,增强代码的健壮性、可维护性和可扩展性。前置++返回已经修改过的对象本身,而后置++返回被修改之前的临时对象,所以后置++的表达式不能作为左值,但前置++可以。

2024-08-03 20:23:53 781

原创 Lambda表达式

除了显式列出我们希望使用的父作域的变量之外,还可以让编译器根据函数体中的代码来推断需要捕获哪些变量,这种方式称之为隐式捕获。在 lambda 函数中,如果以传值方式捕获变量,则函数体中不能修改该变量,否则会引发编译错误。和函数引用参数一样,引用变量的值在 lambda 函数体中改变时,将影响被引用的对象。采用值捕获时,lambda 函数生成的类用捕获变量的值初始化自己的成员变量。需要注意的是:显式捕获的变量必须使用和默认捕获不同的方式捕获。选项,但是,在 lambda 函数的外部,变量的值不会被修改。

2024-08-01 23:37:16 744

原创 HTTP协议:网络通信的基石

HTTP 协议作为互联网的基础,不断演进和发展,为我们提供了高效、便捷的网络通信服务。深入理解 HTTP 协议对于开发 Web 应用、优化网络性能以及保障网络安全都具有重要意义。

2024-08-01 21:49:36 1024

原创 进程间通信与线程间通信的方法汇总

无论进程还是线程,通信的本质都是让不同的执行流“看到”同一份资源!!!

2024-07-30 23:36:48 928

原创 设计模式:模板方法模式:封装不变,扩展可变

模板方法模式由两部分组成:抽象类和具体子类。抽象类:定义了模板方法和一系列抽象方法。模板方法封装了算法的骨架,包含了按照特定顺序调用的抽象方法和其他已经实现的方法。具体子类:继承自抽象类,实现抽象类中的抽象方法,从而完成特定的算法步骤。模板方法模式是一种强大的设计模式,通过将算法的骨架与具体实现分离,提高了代码的复用性、灵活性和可维护性。在实际开发中,当遇到具有固定流程但部分步骤需要定制的情况时,模板方法模式是一个很好的选择。

2024-07-28 22:29:14 840

原创 进程调度算法

例如,在一个数据处理中心,如果大量服务器的 CPU 利用率低,那么运营成本会增加,而处理任务的速度却没有达到最优。以一个打印任务为例,从用户提交打印请求开始,包括在队列中等待被处理、实际在打印机上打印以及可能的传输和其他相关操作,直到打印完成,这整个过程所经历的时间就是周转时间。例如,在在线游戏中,用户点击操作按钮后,游戏界面迅速显示出相应的变化,这个从点击到首次看到变化的时间就是响应时间。这些性能指标在评估操作系统和调度算法的优劣时都具有重要的参考价值,不同的应用场景可能会对某些指标有更高的要求。

2024-07-28 17:18:49 436

原创 进程和线程的区别

不同进程间的数据很难共享(不同火车上的乘客很难直接交换),而同一进程下不同线程间的数据很容易共享(同一辆火车的车厢之间交换相对容易)。线程是进程的一个实体,是 CPU 调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器、一组寄存器和栈),但它可与同属一个进程的其他线程共享进程所拥有的全部资源。线程没有独立的地址空间,多个线程共享所属进程的资源,如地址空间、页表、文件描述符表等,但线程有自己独立的栈。

2024-07-27 22:28:44 333

原创 匿名管道及其应用

匿名管道是一种在具有亲缘关系的进程间进行单向通信的方式。它主要用于父子进程之间的数据传递。Linux指令中的 | 就是在使用匿名管道:用于查找当前系统中所有包含字符串。

2024-05-12 21:51:37 1238

原创 进程间通信:连接不同程序世界的桥梁

在计算机编程的领域中,进程间通信(Inter-Process Communication,IPC)是一个至关重要的概念。当我们在操作系统中运行多个程序或进程时,它们往往需要相互协作、交换信息,而这就是进程间通信发挥作用的地方。想象一下,在一个复杂的系统中,可能有多个进程同时运行,比如一个图形界面程序、一个数据处理程序和一个网络通信程序。它们各自承担着不同的任务,但有时需要共享数据、协调行动或发送信号。没有有效的进程间通信机制,这些进程就会如同孤立的岛屿,无法高效地协同工作。

2024-05-11 23:25:24 724

原创 贪心算法----摆动序列

发现最长摆动序列都是极大值和极小值 再加上两个端点,那么我们保证每次都能选择到每个极值点,就能从局部最优推广全局最优了!遍历数组时,我们可以用一个left来记录这个值左边是递增还是递减,然后和这个数的右边判断,单调性不同即可记录该元素。今日题目:leetcode376。

2024-05-11 22:58:54 375

原创 贪心算法----最大数

要把这些数组组成最大的数,首先我们把数字转化为字符串,根据自定义的排序规则把这些字符串字数排列,再用一个字符串接受这些字符串数字拼接成最大的字符串数字。对于两个字符串数字s1和s2,有两种拼接方式:s1+s2 或 s2+s1,如果前者更大,那么就让s1在s2的前面,如果后者更大,就让s2在s1的前面。本题中,如果s1+s2 > s2+s1 ,则说明满足排序规则,返回true,故而我们可以直接返回这个表达式的bool值即可。,则表示两个元素a、b的顺序不变,不需要交换;,则表示两个元素a、b的顺序需要交换,

2024-05-10 23:14:20 413

原创 贪心算法--将数组和减半的最小操作数

要尽快的把数组和减小,那么每次挑出数组中最大的元素减半即可,由于每次都是找出最值元素,可以用优先队列来存储这些数组元素。每次取出最值,减半后再放入优先队列中,操作次数+1,直到数组和小于等于原总和的一半。本题是力扣2208---

2024-05-09 22:48:57 275

原创 深入理解 Linux 文件系统与动静态库

我们可以通过配置/etc/ld.so.conf.d/的方式解决该问题,/etc/ld.so.conf.d/路径下存放的全部都是以.conf为后缀的配置文件,而这些配置文件当中存放的都是路径,系统会自动在/etc/ld.so.conf.d/路径下找所有配置文件里面的路径,之后就会在每个路径下查找你所需要的库。其实无论是动态库还是静态库,都是把一堆源文件编译处理出的.o文件(二进制文件)整理在一起,在加上这些源文件对应的头文件,就是一个完整的库了,这样既隐藏了库的源代码,也能让其他开发者使用这个库的功能。

2024-05-09 22:16:44 1543

原创 贪心算法-----柠檬水找零

今日题目:leetcode860。柠檬水找零,贪心算法

2024-05-08 21:50:07 1461

原创 递归与递推---题目练习

是指在函数的定义中使用函数自身的方法。它通过不断地将问题分解为更小的子问题,直到达到基本情况,然后再逐层返回结果。则是通过已知的前一个或前几个状态来推导出后续状态的方法。它是按照一定的规律逐步计算出后续结果的过程。从宏观上来看,递归是将一个大问题分解为多个相同类型的小问题,不断重复;递推是根据前一个或前几个状态逐步推出后续状态,也就是从小问题解决到大问题。本文是递归与递推的算法题练习,题目都源于网站。

2024-05-06 11:10:09 634

原创 前缀和---预处理数组的利器

前缀和(Prefix Sum)是一种在数组或序列上的计算技巧,通过对数组的预处理,可以快速计算给定区间内元素的总和。二维前缀和、一维前缀和

2024-05-04 18:59:14 898

原创 二分专题----如何优雅的写出二分

二分算法是一种在有序数组中查找特定元素的高效算法。它的基本思想是通过不断将数组分成两部分,然后比较目标元素与中间元素的大小,从而逐步缩小查找范围,直到找到目标元素或确定目标元素不存在。

2024-05-03 14:47:54 868

原创 递归专题---如何优雅的编写递归函数

在计算机科学中,递归是一种重要的概念和技术。它允许函数直接或间接地调用自身,以解决复杂的问题。递归的基本思想是将一个大问题分解成若干个较小的、相似的子问题,然后通过不断地递归调用自身来解决这些子问题,直至达到基本情况。递归在许多领域都有广泛的应用,如算法设计、数据结构处理等。它可以帮助我们更简洁、优雅地解决一些原本复杂的问题。在算法题中,我们什么时候会使用递归,为什么会使用递归呢?当我们分析一道算法题时,发现主问题可以划分为相同的子问题,此时就可以考虑使用递归。

2024-05-01 22:16:57 754 1

原创 滑动窗口详解

滑动窗口是双指针算法中细分的一种,它由暴力枚举算法优化而来,解决的是同向双指针问题;当一个题目在暴力解法中发现枚举时其实可以不用把“指针”往回走,就可以使用滑动窗口的思想来解决。也就是滑动窗口通过题目的某种性质,忽略了很多无效枚举,维护两个指针间的区间保持某种性质,从而把时间复杂度从O(n^2)优化到O(n)只要题目的研究对象是一段连续区间或者能转化为一段连续区间,就可以考虑用滑动窗口来做,思路不清晰时可以先想题目的暴力枚举,从中优化而来。

2024-04-30 21:49:16 1031

原创 动态规划---斐波那契数列模型

在计算新的子问题时,如果其解已经保存,则直接利用保存的解,否则通过解决更小的子问题来得到其解,并将解保存起来。在斐波那契数列问题中,我们可以使用动态规划技术,从下往上计算斐波那契数列,并将每个计算结果保存起来,这样在计算较大的斐波那契数时,就可以直接使用之前保存的结果,通过空间换时间的操作,大大提高了计算效率。初始时,列表的前两个元素被设置为斐波那契数列的前两项。动态规划的基本思想是将问题分解为若干个子问题,并将这些子问题的解保存起来,以便在计算新的子问题时能够直接利用之前的结果,避免重复计算。

2024-04-24 10:47:09 1797

原创 Linux中文件描述符与重定向的深入探索

在Linux操作系统中,文件描述符和重定向是处理文件输入/输出(IO)操作的两个核心概念。本文将深入探讨这两个概念,帮助您更好地理解它们的工作原理以及在实际应用中的使用。

2024-04-23 22:05:10 749

原创 计算机网络基础:宏观认识

随着信息技术的飞速发展,计算机网络已经成为了现代社会不可或缺的一部分。无论是工作、学习还是娱乐,我们几乎都离不开网络。那么,计算机网络究竟是如何运作的呢?本文将带领大家走进计算机网络的世界,了解网络的发展背景,认识局域网和广域网的概念,深入理解网络协议的意义,并重点探讨TCP/IP五层结构模型,以及网络传输的基本流程和封装分用机制。

2024-04-17 23:07:49 851

原创 数组中两个字符串的最短距离---一题多解(贪心/二分)

方法:贪心 / 二分。贪心:要找出字符串数组中指定两个字符串的最小距离,即找出指定字符串对应下标之差的最小值思考:如果是直接暴力求解,需要两层for循环,依次判断是否是指定字符串,如果是,则找出当前指定字符串的最小距离;时间复杂度O(N^2),题目给的数据范围是10^5,是过不了的;我们基于暴力求解的思路拓展,暴力解法中,我们在找每一个指定字符串的最小距离时,都是针对该字符串位置逐一枚举,那如果优化一下找指定字符串最小距离的方法呢?在遍历数组的过程中,用两个变量记录str1、str2的最近下标

2024-04-17 19:24:23 540 2

原创 深度优先搜索DFS 入门

它的基本思想是从一个起始状态开始,尽可能深入地探索可能的状态,直到达到目标状态或无法继续前进为止。在实际应用中,需要根据问题的特点进行适当的优化,如使用记忆化搜索、剪枝等技术,以提高算法的效率和性能。这次的dfs函数多了一个参数start,用来记录每次从哪开始枚举,因为这次是组合型枚举,顺序不同其实是同一种,利用start来避免重复枚举。使用了记忆化搜索来避免重复计算。这个示例枚举每个数字的选或不选情况,并通过递归构建所有可能的组合。这个示例枚举每个位置可以填充的数字,并通过递归构建所有可能的排列。

2024-03-28 15:42:48 366

原创 【C++】map 和 set 的使用

STL的容器分为两类:序列是容器、关联式容器;序列式容器是线性的数据结构,只有存储元素的功能,且像vector、list等还可以指定插入位置;而关联式容器底层底层的数据结构是较高级的红黑树、哈希表等,里面存储的是结构的键值对,在数据检索时比序列式容器效率更高,但是数据的插入不能像vector那样指定插入位置,它底层有自己的插入逻辑,这样才来保证高效的数据检索能力。

2023-10-30 22:49:19 186

原创 二叉搜索树的实现(递归方式)

本文介绍了使用递归的方式实现BST的插入和删除操作,并提供了完整代码和测试案例。递归虽然简洁,但需要注意递归边界条件、参数传递方式等问题。在实际应用中,也可以使用迭代的方式实现BST的基本操作。

2023-10-26 16:06:44 246

原创 二叉搜索树的实现(迭代方式)

否则,从根节点开始,根据当前节点的键值与待插入键值的大小关系,沿着左子树或右子树逐步查找插入位置,直到找到一个空位置,然后创建新节点并插入。针对第4点,左子树的最右节点和右子树的最左节点,只有这两个节点能起到承上启下的作用,比所有的左子树节点都大,比所有的右子树节点都小;函数用于查找指定的键值。从根节点开始,根据当前节点的键值与目标键值的大小关系,沿着左子树或右子树逐步查找,直到找到目标键值或遍历完整个树。这段代码实现了BST的基本功能,包括查找、插入和删除操作,并且通过遍历删除的测试验证了代码的正确性。

2023-10-26 11:42:27 179

原创 C++:程序在mian函数执行前后做了哪些工作?

但需要注意的是,虽然某些编译器可能支持这种三个参数的形式,但它并不属于标准C++,因此代码依赖于该特性会导致与其他平台或编译器的不兼容性。如果需要使用环境变量相关的功能,建议使用操作系统或库提供的特定接口来处理环境变量,而不是依赖于。然而,根据C标准(ISO/IEC 9899:2018)的允许,这是最常见的用法,并且在大多数C++编译器中都得到支持。函数只有两种参数形式:无参数和带两个参数。按照C++标准规定,

2023-10-22 20:39:01 286

原创 C++:为什么析构函数一般写为虚函数

如果父类的析构函数没有声明为虚函数,那么delete时就只是一个普通的成员函数调用,只会调用父类的析构函数,造成析构不完全,在子类有指向外部的资源时(heap),会引发内存泄漏问题。,这种情况下,如果没有把析构函数写为虚函数,因为delete是先调用析构函数再释放内存空间,此时就只会调用基类的析构函数,造成了析构不完全,容易引发内存泄漏。,所以这里会构成多态调用,最终会调用子类的析构函数,在子类析构函数结束时会自动调用父类析构函数。如果没有继承关系,析构函数写不写为虚函数都可以。

2023-10-22 19:20:20 290

原创 进程的虚拟地址空间

对于C/C++程序员,我们看到的程序中的地址,都不是物理地址,而是操作系统映射的虚拟地址/线性地址,每一个进程都映射了同样结构的虚拟地址空间,让进程以为自己在独享内存资源,下图是以Linux下32位操作系统的虚拟地址空间分布图:平时程序中定义的静态局部变量,真的存放在函数栈帧里吗?并不是,而是存放在全局变量区域中,即.data段、.bss段堆栈两块区域是相对生长的,heap区域随着内存的分配向上申请内存资源;而stack区域在申请分配内存时则是向下生长的,但是注意,是!原因是什么呢?

2023-10-17 23:07:49 777

原创 C++继承探究

继承方式、作用域、菱形继承、虚继承、继承、组合继承可以理解为一个类从另一个类获取成员变量和成员函数的过程。成员变量继承一份给自己,成员函数和父类共用。被继承的类称为基类或父类,继承的类称为派生类或子类。派生类除了拥有基类的成员,还可以定义新的成员,以增强其功能。

2023-10-15 21:31:11 127

原创 vector用法

size为容器的有效元素,size=_last - _first_end - _first 为容器当前的最大容量。

2023-10-14 14:06:28 150

空空如也

空空如也

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

TA关注的人

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