自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 Linux用户和权限管理

Linux 中常见的系统调用有很多,它们是操作系统提供给用户空间程序访问操作系统内核功能的接口。用户和权限管理是非常重要的部分,涉及到文件和进程的访问控制、安全性等方面。系统调用的详细使用方法可以查阅对应的系统调用手册 (man) 或相关的操作系统文档。用户和权限管理涉及的系统调用和工具使得管理员可以精确控制系统中用户和进程的权限,从而提高系统的安全性和管理效率。

2024-07-15 15:42:11 310

原创 c++20新特性

包括对并发编程的支持(例如std::jthread)、对日期和时间处理的增强(std::chrono)以及其他一些新的容器和算法。这些改进使得lambda表达式在C++20中变得更加强大和灵活,能够处理更多种类的编程任务,并提供更高的表达能力和性能。这简化了对集合的操作,例如使用范围for循环来处理数据。通过operator运算符,C++20引入了一种标准的方法来定义类型的三路比较,这简化了自定义类型的比较操作。C++20引入了更灵活和一致的初始化语法,包括聚合初始化的扩展和类类型的默认成员初始化。

2024-07-15 14:32:05 470

原创 为什么删除拷贝构造函数

在上面的示例中,类 NoCopyClass 明确禁止了对象的拷贝操作,如果在 main() 函数中试图拷贝 obj1 到 obj2,编译器会报错,从而避免了不必要的拷贝。在一些情况下,对象的拷贝可能会导致资源管理上的问题,如浅拷贝导致多个对象共享相同的资源,可能会导致资源的泄漏或意外的释放。总之,删除拷贝构造函数是 C++ 提供的一种高级特性,可以帮助开发者在编译期间更好地控制对象的行为和资源管理,避免潜在的错误和不必要的性能损失。例如,单例模式中的类通常希望保持唯一性,不允许多个实例的拷贝。

2024-07-12 14:17:14 215

原创 Linux守护进程和setsid()函数

在 Unix/Linux 系统编程中,守护进程(daemon)、进程组(process group)、会话(session)是系统编程中重要的概念,它们通常在创建和管理后台进程时扮演着关键角色。setsid() 是一个系统调用,用于创建一个新的会话(session)并将调用进程设置为新会话的领头进程(session leader)。守护进程是在后台运行的一种特殊类型的进程,通常独立于控制终端并且没有用户交互界面。会话是一个或多个进程组的集合,通常与一个控制终端关联。

2024-07-12 13:32:48 675

原创 为什么用std::make_pair

std::make_pair 是 C++ 标准库中定义在 头文件中的一个函数模板。它用于方便地创建 std::pair 对象,而不需要显式指定类型。总之,std::make_pair 是 C++ 中一个非常实用的函数模板,可以帮助简化创建 std::pair 对象的过程,使代码更清晰、更易维护。

2024-07-12 11:27:26 415

原创 Fast DDS入门

Fast DDS,全称 Fast Data Distribution Service,是一种开源的、高性能的数据分发服务,它实现了实时数据通信的标准DDS(Data Distribution Service)规范。Fast DDS 的设计旨在提供快速、可靠的数据传输,适用于实时系统和分布式应用。

2024-05-06 14:27:32 367

原创 假设程序在debug版本运行正常,但是在release版本出错,如何分析解决

以下是一些可能的解决方法和分析步骤:

2024-04-28 11:19:39 684

原创 假设类A和类B中分别有一个指向对方的指针,那么这两个类能够正确释放内存吗

类A和类B中互相持有对方的指针会导致循环引用,可能会造成内存泄漏。这是因为当你释放类A的实例时,类A的析构函数可能无法释放类B实例所占用的内存,因为类B实例仍然持有指向类A实例的指针,反之亦然。为了正确释放内存,你需要在类A和类B的析构函数中处理这种循环引用情况,以确保所有相关的资源都被正确释放。当类A的实例被析构时,会检查类B实例是否仍然持有对应的指针,并在需要时将其设置为nullptr,以避免内存泄漏。类B的析构函数也采取了类似的处理方式。

2024-04-27 16:45:46 210

原创 Linux系统编程——性能调优

系统性能调优是指通过优化系统配置、调整系统参数和改进系统设计等方式来提高系统的性能和响应速度。系统性能调优是一个综合性的工作,需要根据实际情况综合考虑各种因素,并采取相应的措施来优化系统性能。在调优过程中,需要不断测试和评估系统性能,及时调整优化策略,以达到最佳的性能和稳定性。

2024-04-24 11:24:47 231

原创 Linux系统编程——设备驱动

在这个驱动中,我们实现了设备的打开、关闭、读取和写入操作函数,并使用了适当的同步机制来确保设备操作的安全性。这包括设备树(Device Tree)用于描述硬件设备的信息,以及设备类、设备结构体等用于在内核中表示设备的数据结构。:设备驱动需要实现一组设备操作函数,包括打开设备、关闭设备、读取设备数据、写入设备数据等。:设备驱动需要考虑多个进程同时访问设备时可能出现的并发和同步问题,以确保对设备的访问是安全和可靠的。2. 设备操作函数: 我们需要实现设备的打开、关闭、读取和写入操作函数。

2024-04-24 11:20:17 423

原创 Linux系统编程——信号处理

在Linux系统中,信号是一种用于通知进程发生了某种事件的机制。信号可以由内核、其他进程或进程自身发送。常见的信号包括终止进程(SIGTERM)、中断进程(SIGINT)、挂起进程(SIGSTOP)、继续进程(SIGCONT)等等。在Linux中,可以使用signal()函数或sigaction()函数来注册信号处理程序。

2024-04-24 11:10:12 500

原创 Linux系统编程——多线程

在Linux系统编程中,多线程编程是一项重要的技能,它允许程序同时执行多个任务,提高了程序的并发性和效率。当涉及到在Linux上进行多线程编程时,可以使用POSIX线程库(pthread)。POSIX线程库提供了一组函数和数据结构,使得在多线程环境下创建、同步和管理线程变得更加容易。

2024-04-23 14:56:58 775

原创 Linux系统编程——网络编程

这个服务器是单线程的,对于每个连接它都创建一个子进程来处理,但是这个示例并不适用于生产环境,因为它没有考虑到并发连接和错误处理。:Socket是Linux网络编程中最基本的概念之一。以下是一个简单的C语言示例,演示了如何在Linux上实现一个基本的HTTP服务器。:除了直接使用底层的Socket API外,还有一些网络编程框架可以简化网络应用程序的开发,例如Boost.Asio和libevent等。:Linux提供了许多套接字选项,开发者可以使用这些选项来配置套接字的行为,例如设置超时、设置缓冲区大小等。

2024-04-23 14:49:43 286

原创 Linux系统编程——内存管理

Linux系统编程中的内存管理是一个广泛的主题,涉及到许多概念和技术。当谈到Linux系统编程中的内存管理时,一般包括动态内存分配、内存映射、共享内存等。内存保护:Linux使用页表来实现内存保护。通过设置页的权限,可以防止进程访问未授权的内存区域。使用mprotect()函数来修改内存页的权限。:在C语言中,我们通常使用malloc()和free()函数进行动态内存分配和释放。:通过内存映射,可以将文件映射到进程的地址空间中,从而实现对文件的直接访问。

2024-04-23 14:37:25 199

原创 Linux系统编程——文件系统操作

文件系统操作是计算机中的基本操作之一,用于管理文件和目录,也是Linux系统编程中的一个基础而重要的概念,深入理解这些内容对于开发高效、稳定的系统应用程序至关重要。

2024-04-23 12:07:32 290

原创 Linux系统编程——进程管理

这样就实现了进程间的通信。Linux系统编程是指在Linux操作系统上进行软件开发的一种形式,涉及到与操作系统内核和系统资源的交互、管理和控制。进程管理是Linux系统编程中的一个基础而重要的概念,深入理解这些内容对于开发高效、稳定的系统应用程序至关重要。进程管理在Linux系统编程中是一个重要的主题,涉及到创建、销毁和调度进程,以及进程间通信。调用fork()创建了一个新的子进程,子进程会继承父进程的代码和数据,但有自己独立的PID。在子进程中,fork()返回0,在父进程中,返回子进程的PID。

2024-04-23 12:01:36 584

原创 gRPC客户端调用服务端方法,过程中发生了什么

将 “your_package_name” 替换为您在 .proto 文件中定义的包名称,并根据需要替换端口号和其他参数。下面是一个简单的 gRPC 实例。

2024-04-22 11:35:44 307

原创 gRPC入门

与传统的RPC系统相比,gRPC具有更高的性能和可扩展性,支持双向流、流控制、连接复用等特性,适用于需要高性能、低延迟的分布式系统。上面的示例中定义了一个名为 MyService 的服务,它包含一个名为 SayHello 的方法,该方法接受一个 HelloRequest 参数并返回一个 HelloResponse 结果。gRPC 在底层使用了 HTTP/2 协议,因此它利用了 HTTP/2 的许多优点,如多路复用、头部压缩、流控制等,以提供高效的、低延迟的远程过程调用。

2024-04-22 11:30:10 464

原创 从输入URL到收到请求响应完成,中间发生了什么事情?

当你在浏览器中输入 URL 并按下回车键时,发生了以下过程:

2024-04-21 13:23:30 279

原创 HTTP协议

HTTP是在Web服务器和客户端之间传输数据的协议,允许客户端发出请求并接收服务器的响应。POST 和 GET 是 HTTP 协议中最常用的两种请求方法,它们用于客户端与服务器之间的通信,但在用法和语义上有一些区别。数据被包含在请求的消息体中,不像 GET 请求那样在 URL 中可见。向服务器提交数据,数据会附加在URL的后面,以查询字符串的形式发送。可以发送大量数据,且数据不会在 URL 中暴露,适合传输敏感信息。用于向服务器提交指定资源的数据,通常用于向服务器提交表单数据。用于请求指定的资源。

2024-04-21 13:07:59 158

原创 制作 Docker 镜像

这将在当前目录中构建一个名为 my-cpp-app 的 Docker 镜像。以下是一些在运行 Docker 镜像时常用的参数,你可以使用。命令来查看所有可用的选项和参数。

2024-04-20 13:00:44 253

原创 FFmpeg框架入门

你只需要将输入文件和输出文件的路径传递给 convert_to_yuv422 函数即可。该函数会构造正确的 FFmpeg 命令并执行,将输入图像转换为 YUV422 格式。FFmpeg 是一个开源的跨平台音视频处理工具库和程序集,包含了用于处理音视频的各种工具和库函数。它提供了音视频的录制、转码、编解码、流媒体处理等功能,是一个功能强大而且灵活的多媒体处理工具。代码示例如下,确保你已经安装了 Python 和 FFmpeg 库,你可以使用 pip 命令安装 ffmpeg-python 库。

2024-04-19 17:55:45 469 1

原创 STL迭代器原理

具体来说,STL中的每种容器都有自己的迭代器类型,这些迭代器提供了一组操作符(如*、->、++等),用于访问容器中的元素。STL迭代器是STL中非常关键的概念之一,它允许对STL容器(如vector、list、map等)中的元素进行遍历和访问。然后,定义了一个MyContainer类,它包含了begin()和end()函数,分别返回容器的起始和结束迭代器。在main()函数中,创建了一个整数数组作为容器的数据,并使用自定义迭代器遍历了容器中的所有元素,打印出每个元素的值。

2024-04-19 11:02:48 174

原创 设计模式——策略模式

策略模式是一种行为型设计模式,它定义了一系列算法,并将每个算法封装到一个独立的类中,使得它们可以相互替换。策略模式可以使得算法的变化独立于使用算法的客户端。策略模式通过定义一系列算法,使得它们可以相互替换,而不影响使用算法的客户端。策略模式将每个算法封装到一个独立的类中,客户端根据需要选择合适的算法进行使用。

2024-04-18 15:23:59 127

原创 设计模式——观察者模式

ConcreteSubject 是具体被观察者类,它维护了一个观察者列表,并实现了具体的注册、移除和通知方法。在客户端中,我们创建了被观察者对象,并注册了多个观察者对象。被观察者对象的状态改变后,会通知所有的观察者对象进行更新。观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,使得当一个对象的状态发生变化时,所有依赖于它的对象都会得到通知并自动更新。观察者模式也被称为发布-订阅模式。被观察者维护了一个观察者列表,当其状态发生变化时,会通知所有的观察者,并调用观察者的相应方法进行更新。

2024-04-18 15:20:25 176

原创 设计模式——代理模式

Proxy 是代理类,它也实现了 Subject 接口,并持有一个指向真实主题对象的指针。在客户端中,我们首先创建了真实主题对象,然后创建了代理对象,并将真实主题对象传入代理对象中。代理模式通过引入一个代理对象来控制对另一个对象的访问。这个代理对象充当了被代理对象的中间人,客户端通过代理对象间接地访问被代理对象,从而实现了对被代理对象的控制和管理。代理模式是一种结构型设计模式,它允许通过一个代理对象控制对另一个对象的访问。代理模式通常用于在访问对象时添加额外的功能,或者限制对对象的访问。

2024-04-18 15:15:50 169

原创 设计模式——装饰器模式

装饰器模式是一种结构型设计模式,它允许在不修改现有对象结构的情况下,动态地向对象添加新功能。这种模式通过将对象包装在装饰器对象中来实现,从而允许向对象添加新的行为。装饰器模式允许你通过将对象放入包含有特殊行为的装饰器对象中,来动态地为对象添加新的功能。装饰器模式实际上是对继承的一种替代方案,它通过组合而不是继承来实现功能的扩展。

2024-04-18 15:09:27 248

原创 设计模式——适配器模式

适配器模式是一种结构型设计模式,它允许接口不兼容的类之间进行合作。它通过引入一个适配器来充当两个不兼容接口之间的中间层,使得它们可以一起工作。

2024-04-18 15:04:07 184

原创 设计模式——原型模式

原型模式是一种创建型设计模式,其核心思想是通过复制现有对象来创建新对象,而无需通过标准的构造函数来创建。这种模式通常用于创建成本较高或复杂的对象,以提高性能和减少资源消耗。

2024-04-18 14:59:40 166

原创 设计模式——建造者模式

我们通过抽象建造者类 PizzaBuilder 定义了构建产品的抽象接口,具体的建造者类 HawaiianPizzaBuilder 和 SpicyPizzaBuilder 实现了这些接口来完成具体的构建过程。这种模式的关键是将构造过程与最终对象分离,使得相同的构造过程可以创建不同的表示。建造者模式的实现原理是将一个复杂对象的构建过程分解为多个步骤,然后通过一个指导者类来逐步指导构建,最终得到完整的对象。这种方式将构建过程与表示分离,使得相同的构建过程可以创建不同的表示。

2024-04-18 14:51:12 187

原创 设计模式——工厂模式

工厂模式是一种创建型设计模式,用于创建对象的过程,将对象的创建和使用分离开来。工厂模式通过提供一个通用的接口来创建对象,而不需要暴露对象的创建逻辑。:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。抽象工厂模式允许客户端使用抽象的接口来创建一组相关的产品对象,而不需要知道实际的实现类。:由一个工厂类负责创建所有产品对象的实例。客户端通过传递不同的参数给工厂类,来获取不同的产品对象实例。:定义一个用于创建对象的接口,但将实际的创建工作延迟到子类中。这样子类可以决定要实例化的类是哪一个。

2024-04-18 14:45:44 116

原创 设计模式——单例模式

这两种模式的区别是,懒汉模式在 getInstance() 方法中检查了实例是否存在,如果不存在则创建新的实例。而饿汉模式则在定义时就创建了实例,因此不需要在 getInstance() 方法中进行检查。懒汉模式是在需要时才创建实例,而饿汉模式是在程序启动时就创建实例。单例模式确保一个类只有一个实例,并提供了一个全局访问点,这在许多软件设计中都是很有用的。:有时候,单例对象不需要在程序启动时立即创建,可以在需要时才创建。:在多线程环境下,确保单例对象的创建是线程安全的,避免出现竞态条件或多次实例化的情况。

2024-04-18 14:37:04 235

原创 算法——Floyd-Warshall算法

下面的示例中,使用c++简单实现了Floyd-Warshall算法。首先,我们用邻接矩阵表示图,并初始化所有顶点对之间的最短路径。然后,我们通过嵌套的循环来逐步更新最短路径矩阵,直到找到所有顶点对的最短路径。Floyd-Warshall算法是一种用于解决图中所有顶点对之间最短路径的动态规划算法。它可以处理有向图或无向图,以及负权边(但不能处理负权回路)。Floyd-Warshall算法采用了动态规划的思想,通过逐步更新所有顶点对之间的最短路径来求解问题。

2024-04-17 19:14:26 138

原创 算法——Bellman-Ford算法

在这个例子中,我们使用邻接列表表示图,通过 Graph 类来存储图的边。然后实现了 Bellman-Ford 算法,并对给定的源点进行调用。Bellman-Ford算法是用于解决单源最短路径问题的一种算法,可以处理图中存在负权边的情况。该算法还能够检测图中是否存在负权回路。

2024-04-17 19:10:32 153

原创 算法——贪心算法(Dijkstra算法)

贪心算法的核心思想是每一步都选择当前状态下的最佳选项,并希望通过这种局部最优的选择最终达到全局最优解。在每一步,贪心算法都会做出一个局部最优选择,而不考虑该选择可能会导致的后续结果。因此,贪心算法通常不会回溯或者检查之前的选择是否会影响到后续步骤。这段代码定义了一个函数 makeChange,它接受一个整数金额作为参数,并返回一个向量,包含了找零所需的最少硬币数量,以及使用的硬币面额。Dijkstra算法是用来解决单源最短路径问题的一种贪心算法。它通过不断地选择距离起始点最近的顶点来逐步扩展最短路径。

2024-04-17 19:01:58 368

原创 算法——哈希算法

在哈希表中,键(Key)通过哈希函数映射到表中的索引,然后在该索引处存储对应的值(Value)。哈希表的查找操作通常具有较高的效率,其时间复杂度为O(1),即常数时间。在实际的应用中,哈希表的查找操作通常还会涉及解决哈希冲突的问题。哈希冲突指的是不同的键经过哈希函数得到的哈希值相同,因此需要额外的方法来处理这种情况。哈希函数的设计应该尽可能使得不同的键映射到不同的哈希值,以减少冲突(Collision)的概率。通常,哈希表的底层数据结构是一个数组,索引位置就是数组的下标。如果存在值,则返回该值;

2024-04-16 13:58:42 229

原创 算法——启发式搜索

通过设计适当的启发式函数,可以在大规模的搜索空间中快速找到接近最优解的解决方案。启发式搜索是一类基于估计值(启发式函数)来指导搜索的算法,常见的有 A* 算法。:启发式搜索在游戏博弈中有着广泛的应用,例如在国际象棋、围棋、扑克等游戏中。其原理是在搜索过程中,不仅仅考虑当前的搜索状态,还利用一定的启发式信息来指导搜索方向,从而更加高效地达到目标状态。:启发式搜索还可以用于智能体的决策问题,例如在强化学习中,智能体可以使用启发式搜索来选择动作以最大化累积奖励。

2024-04-16 13:53:10 734

原创 算法——深度优先搜索

深度优先搜索是另一种图搜索算法,从起始节点开始,沿着一条路径直到到达叶子节点,然后回溯并探索下一个分支。它接受一个图的邻接表表示和一个起始节点作为输入,然后通过深度优先搜索遍历整个图,并打印出遍历的节点顺序。深度探索:首先访问起始节点,然后递归地访问该节点的相邻节点,依次向下深度探索,直到达到图的末端,或者无法继续深入。连通性检测:DFS 可用于检测图中的连通性,即检查图中的所有节点是否可以通过边相互连接。遍历所有节点:保证每个节点都被访问过,并且在访问的过程中不重复访问已经访问过的节点。

2024-04-16 13:05:44 173

原创 算法——广度优先搜索

它从图的起始节点开始,逐层地向外探索,先访问当前层的所有节点,然后再逐层向下扩展。它接受一个图的邻接表表示和一个起始节点作为输入,然后通过 BFS 遍历整个图,并打印出遍历的节点顺序。逐层探索:接下来,对于每个相邻节点,再访问它们的相邻节点,以此类推,直到达到目标节点或者所有可达节点都已访问。最短路径:BFS可以用于找到两个节点之间的最短路径,因为它会首先访问距离起始节点最近的节点。探索相邻节点:首先访问起始节点,然后访问起始节点的所有相邻节点。图的遍历:BFS可用于遍历整个图,以访问所有可达节点。

2024-04-16 13:01:54 299

原创 算法——二分搜索

在这个示例中,binarySearch 函数接受一个已排序的整型数组、数组大小和目标元素作为参数,然后使用二分搜索算法在数组中查找目标元素。二分搜索(Binary Search),也称为折半搜索,是一种高效的搜索算法,适用于已排序的数组。二分搜索在实际应用中有许多用途,特别是在需要高效搜索已排序数据的情况下。例如,在有序数组中查找第一个大于等于目标值的元素,或者查找最后一个小于等于目标值的元素。:在某些图论问题中,可以使用二分搜索来确定最小或最大边界,例如最小生成树中的最小边权值或最短路径中的最大边权值。

2024-04-16 12:53:40 316

空空如也

空空如也

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

TA关注的人

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