- 博客(55)
- 收藏
- 关注
原创 Web服务器和Web框架
监听网络端口是指 Web 服务器(如 Nginx、Apache)在启动时,会在操作系统的某个端口(Port)上持续等待来自客户端的 HTTP 请求。2.接收请求:用户在浏览器向服务器的XX端口发送HTTP请求,服务器检测到XX端口有数据,读取请求并处理,服务器生成响应(如HTML页面),通过同一端口返回给浏览器。监听网络端口,接收客户端请求 —> 解析 HTTP 请求,获取请求方法、URL、数据等信息 —>1.绑定端口:服务器启动时,会告诉操作系统,我在端口XX上等待请求,有数据发到这个端口交给我处理。
2025-04-17 16:29:13
218
原创 fork和kill
fork() + exec():复制父进程后立即替换为新的程序(如用户在终端输入 ls 时,shell 先 fork() 自身,再 exec("ls"))。不创建新进程:与 fork() 不同,exec() 不会生成子进程,而是直接覆盖当前进程的内存空间(代码、数据、堆栈等),加载并执行新程序。所以说创建进程,其实就是复制父亲进程的一个完整副本(包括代码、内存、文件描述符等),但拥有独立的进程 ID(PID)。fork():复制父进程(如 nginx 主进程 fork() 出 Worker 进程)。
2025-04-17 16:28:17
476
原创 CGI协议和FastCGI协议
客户端和服务器之间基于通用网关接口(CGI)的通信流程:用户请求:用户通过浏览器访问URL,发起HTTP请求(GET/POST等)。
2025-04-16 14:09:41
1016
原创 for循环暴力解法以及优化练习
这里主要是练习一下用等差数列解决for循环的时间复杂度的一些问题公式:等差数列求和公式:(首+尾)*项数/2等差数列项数公式:(尾-首)/公差+1有一组数组比如:1,3,5,7,9,这组数的首项就是1,尾项就是9,项数就是5(根据等差数列项数公式,尾项是9,首项是1,因为每个数字之间差2,所以公差就是2,得出项数是5)下面看几个简单的题目,练习一下。
2025-01-10 13:35:27
618
原创 牛客网 SQL37查找多列排序
如何处理对象的状态变化,取决于具体的场景和需求。简单的状态变化可以通过状态变量或者回调处理,而复杂的场景则可以使用状态模式、观察者模式或者有限状态机等设计模式。通过选择适当的模式,可以提高代码的可维护性、可扩展性和清晰度。抽象工厂模式提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们具体的类。抽象工厂模式适用于需要创建多个相关产品时。AbstractFactory:声明创建一组相关产品的方法。ConcreteFactory:实现创建一组具体产品的方法。
2024-12-19 17:06:13
897
原创 牛客网 SQL36查找后排序
在 C++ 中实现对象克隆的主要方法有:1.通过拷贝构造函数实现克隆:适用于大多数简单的对象。需要自己编写拷贝构造函数,确保正确进行深拷贝。2.通过克隆接口(clone() 方法)实现克隆:适用于有继承关系的类,能够让基类定义一个虚拟的 clone() 方法,派生类实现具体的克隆逻辑。3.使用智能指针管理克隆:适用于使用智能指针(如 std::unique_ptr 或 std::shared_ptr)管理资源的对象,可以通过拷贝构造来克隆。
2024-12-18 19:33:30
2097
原创 牛客网 SQL5将查询后的列重新命名
C++ 中的对象生命周期管理有多种方式,适用于不同的场景:1.栈对象:生命周期由作用域管理,自动销毁。2.堆对象:生命周期由程序员管理,需要显式调用 delete。3.智能指针:通过 std::unique_ptr 或 std::shared_ptr 自动管理堆对象的生命周期,减少手动管理的负担。4.RAII 模式:通过构造函数和析构函数管理资源,确保资源在正确的时机分配和释放。5.对象池:用于高性能场景,避免频繁的内存分配和释放。
2024-12-18 18:54:21
1927
原创 牛客网 SQL4查询结果限制返回行数
接口继承:只继承函数签名(通过纯虚函数),不继承具体实现。要求派生类提供实现。实现继承:继承函数签名和具体实现(如果函数是虚函数的话)。允许派生类重用和覆盖基类的代码。在C++中,接口继承通常通过包含纯虚函数的抽象基类来实现,而实现继承则是通过普通的类继承来实现。这两种继承方式在设计和构建类层次结构时都有其独特的用途和优势。
2024-12-16 21:29:06
721
原创 牛客网 SQL3查询结果去重
在某些情况下,程序员可能需要实现自定义的内存分配器来满足特定的性能需求或内存布局要求。自定义内存分配器可以通过重载全局的new和delete运算符或使用特定的内存分配策略来实现。
2024-12-16 20:23:50
951
原创 牛客网 SQL2查询多列
在main函数中,我们使用try-catch块来捕获并处理这个异常,以及任何可能抛出的标准异常或未知类型的异常。C++ 提供了一套标准的异常处理功能,允许程序在检测到错误条件时抛出异常,并在适当的位置捕获和处理这些异常。C++标准库提供了一系列派生自std::exception的类,用于表示常见的异常类型,如std::runtime_error、std::logic_error等。被抛出的异常可以是任何类型的对象,但通常是派生自std::exception的类的实例,或者是其他自定义的异常类型。
2024-12-16 19:43:59
612
原创 牛客网 SQL1查询所有列
C++的多态性通过提供统一的接口和不同的实现,使得程序设计更加灵活、可扩展和可维护。在实际项目中,使用多态可以提高代码的复用性,简化维护工作,尤其是在需要时不同类型对象执行相同操作的场景中非常有用。
2024-12-16 17:45:25
731
原创 力扣 合并区间-56
5.如果重叠,将结果数组中区间的右边界改为当前区间的右边界和结果数组中区间的右边界之中的最大的一个右边界,因为会有{1,4},{2,3}的情况。4.以引用的方式获取结果数组中的最后一个区间,方便重叠的时候直接对结果数组中的右边界进行更改。1.先将数组排好序,以便能找到重叠的区间,数组是乱序的话很难去寻找重叠的部分。3.先将第一个区间加入到结果数组中,然后从行索引为1开始遍历,方便比较。2.创建一个存结果的数组nums,用于返回结果。6.不重叠直接将当前区间加入到结果数组中。
2024-12-12 20:54:04
324
原创 力扣 K个一组翻转链表
纯虚函数(pure virtual function)是指被标明为不具体实现的虚拟成员函数。它用于定义一个基类时,会遇到无法定义基类中虚函数的具体实现,其实现依赖于不同的派生类。定义纯虚函数的一般格式为:“virtual 返回类型 函数名(参数表)=0;抽象类是一种不能被实例化的类,即不能创建抽象类的对象,它主要用于定义一些具有相同属性和行为(方法)的类的公共接口,子类需要继承这个抽象类并实现其中的抽象方法。使用关键字abstract修饰的类称为抽象类。
2024-12-11 19:18:48
676
原创 力扣 重排链表-143
多态性(Polymorphism) 是面向对象编程中的一个重要概念,指的是同一个操作或方法可以作用于不同类型的对象,并表现出不同的行为。它使得一个接口可以根据对象的实际类型进行不同的操作。1.多态性 是面向对象编程的重要特性,允许通过统一的接口操作不同类型的对象,且表现出不同的行为。2.在 C++ 中,编译时多态通过函数重载和运算符重载实现,运行时多态通过虚函数和继承实现。3.多态性增强了代码的灵活性、扩展性、可维护性,减少了耦合度。
2024-12-10 21:23:40
587
原创 力扣 最长递增子序列-300
继承(Inheritance)是面向对象编程(OOP)中的一个重要特性,它允许一个类(子类)继承另一个类(父类或基类)的属性和方法,从而实现代码的重用。通过继承,子类可以扩展、修改或者重写父类的方法,同时还可以继承父类的成员变量和成员函数。继承的基本思想是“子类是一个特殊化的父类”。即子类不仅具有父类的所有特征,还可以添加新的特征或修改父类的一些行为。继承是面向对象编程中一个重要的概念,它允许一个类继承另一个类的属性和方法,支持代码重用和层次化设计。
2024-12-10 18:45:56
578
原创 力扣 螺旋矩阵-54
封装(Encapsulation)是面向对象编程(OOP)的四大基本特性之一,指的是将数据(成员变量)和操作数据的方法(成员函数)结合在一起,并对外界隐藏数据的具体实现细节,只暴露接口供外界访问和操作。简单来说,封装就是“把数据和操作数据的代码捆绑在一起,并通过公开的接口与外界进行交互”。它帮助隐藏对象的内部实现细节,使得外部只能通过提供的接口与对象交互,而不能直接访问对象的内部数据。封装是面向对象编程的重要特性,它通过将数据和方法封装在类中,保护数据的安全性、提升代码的可维护性与可扩展性。
2024-12-10 16:26:43
986
原创 力扣 反转链表2-92
静态链接的优势是无需外部依赖,运行时加载快,但文件较大且更新不方便。动态链接的优势是可共享库文件,节省内存和磁盘空间,更新方便,但需要依赖外部库且可能影响程序启动速度。
2024-12-10 15:06:54
484
原创 力扣 对称二叉树-101
malloc 是 C 中的动态内存分配函数,返回 void* 类型的指针,不初始化内存。new 是 C++ 中的操作符,返回指向指定类型的指针,并且会初始化内存,且支持异常处理。如果 malloc 分配失败时没有检查其返回值并继续使用 NULL 指针,程序可能会出现未定义行为。未定义行为的后果是不可预测的,可能导致程序的正常功能丧失、数据损坏或其他逻辑错误。// 请求内存// 忽略malloc失败的检查,继续使用ptr// 如果malloc失败,ptr会是NULL,这里访问空指针,未定义行为。
2024-12-05 19:46:47
850
原创 力扣 LCR训练计划2(剑指 Offer 22. 链表中倒数第k个节点)-140
循环引用 发生在对象通过智能指针(如 shared_ptr)或裸指针互相引用,导致它们无法被销毁,造成内存泄漏。解决方法 主要是使用 std::weak_ptr 来打破循环引用,或者通过手动解除循环引用来管理资源。在 C++ 中,避免循环引用是一个重要的设计考虑,特别是在复杂的对象关系和资源管理场景中。对于 new 和 malloc,具体能分配多少内存受到操作系统、硬件架构、物理内存、虚拟内存空间以及内存碎片等多方面因素的限制。
2024-12-03 20:49:07
873
原创 236 二叉树的最近公共祖先-236
隐式类型转换(Implicit Type Conversion)隐式类型转换,也叫自动类型转换,是指编程语言自动将某个类型的值转换为另一个类型的过程,而无需显式地使用转换操作符或函数。这种转换通常发生在不同数据类型之间进行运算或赋值时。隐式类型转换是C++中的一个重要特性,它可以使代码更加简洁,但也可能带来精度丢失、溢出、性能问题和逻辑错误等风险。因此,在编写C++代码时,程序员应该注意隐式类型转换的潜在问题,尤其是在不同类型之间进行运算或赋值时,可以考虑显式类型转换来避免不必要的错误。
2024-12-02 19:52:14
1065
原创 力扣 二叉树的锯齿形层序遍历-103
内存对齐(Memory Alignment) 是指计算机系统中数据存储的方式,要求数据按照特定的边界(通常是数据类型的大小)存储在内存中。也就是说,数据在内存中的地址应该是其大小的整数倍。
2024-12-02 16:34:32
743
原创 力扣 全排列-46
函数重载(Function Overloading)是指在同一个作用域中,多个函数可以拥有相同的名字,但它们的参数列表(参数的个数或类型)不同。通过参数的不同,编译器可以区分调用哪个重载版本的函数。
2024-12-01 22:04:50
540
原创 力扣 岛屿数量-200
在没有移动语义的情况下,当一个对象被复制时,通常需要执行深拷贝操作,这可能会消耗大量时间,尤其是对于包含大量数据的对象(如 std::vector、std::string)。在 C++11 中,引入了 右值引用 和 移动语义 这两个重要概念,它们主要用于优化性能,减少不必要的资源拷贝,尤其是在处理大对象时。auto 也可以用于函数的返回类型,特别是当返回类型较为复杂时,或者返回值的类型依赖于某些表达式的计算结果。当你需要保持某个变量的类型,特别是引用类型时,decltype 是非常有用的。
2024-11-29 22:10:03
2059
原创 力扣 搜索旋转排序数组-33
volatile 用来告诉编译器:该变量的值可能会在程序外部发生变化,每次使用时都要从内存中读取,而不是缓存寄存器中的值。它与 线程同步、硬件寄存器、外部中断 等场景密切相关。const 用来表示该变量是常量,程序中不允许修改它的值,主要用于定义常量、函数参数保护等场景。
2024-11-28 22:03:48
426
原创 力扣 二叉树的层序遍历-102
函数对象(又称为函数符号)是一个可以像普通函数一样被调用的对象。在 C++ 中,函数对象是通过重载 operator() 来实现的。它的本质上是一个类的实例,而该类的实例具有函数调用的能力。因此,函数对象可以像普通函数一样在代码中传递和调用。要定义一个函数对象,需要:创建一个类。在类中重载 operator() 方法,使对象能够像函数一样调用。// 定义一个函数对象public:// 重载 operator() 实现加法操作Add add;// 创建函数对象。
2024-11-27 20:22:36
677
原创 力扣 最长回文字串-5
多继承(Multiple Inheritance)是指一个类(子类)可以继承自多个父类(基类)。在 C++ 中,类可以有多个父类,从而继承多个类的属性和行为。语法示例// 第一个基类public:// 第二个基类public:// 派生类public:Derived d;// 从 Base1 继承的方法// 从 Base2 继承的方法// 自己的方法return 0;在这个示例中,Derived 类继承了 Base1 和 Base2 两个类,能够访问它们的方法。
2024-11-26 21:00:06
1119
原创 力扣 最大子数组和-53
Lambda 表达式是一种匿名函数,允许在函数内定义内联函数对象。这种语法引入于 C++11,适用于需要快速定义简单函数逻辑的场景。1.定义匿名函数,提高代码灵活性和简洁性。2.用作回调函数、事件处理器或自定义算法逻辑。
2024-11-25 19:40:17
570
原创 力扣 最大数组和-53
在 C++ 中,类型别名和 using 声明 是两种用于定义和使用别名的方式,目的是简化复杂类型的使用,增强代码的可读性与可维护性。它们有一些相似之处,但也有一些细微的差别。1. 类型别名(typedef)typedef 是 C++ 中定义类型别名的传统方法。通过 typedef,我们可以给现有的类型(如结构体、类、指针、数组等)起一个更简短或更易于理解的名字。// 将 'int*' 类型定义为 'IntPtr',即 IntPtr 就是 'int*' 的别名// 这相当于声明 'int* ptr'
2024-11-24 23:10:41
1050
原创 力扣 三数之和-15
模板特化和偏特化是C++模板的高级特性,用于为特定类型或参数模式提供专门的实现。1.模板特化:完全具体化,为特定类型实现特殊版本。使用template语法。2.模板偏特化:部分具体化,处理一组参数模式。使用部分固定参数定义版本。3.函数模板没有偏特化 ,可以使用重载或SFINAE间接实现类似效果。特化和偏特化使模板更灵活,可用于优化、处理特殊类型或参数模式的需求。
2024-11-23 19:45:46
401
原创 力扣 LRU缓存-146
C++中的智能指针是一种用于管理动态内存的工具,它封装了裸指针(raw pointer),并通过 RAII(资源获取即初始化)的方式自动管理资源的生命周期,从而避免了内存泄漏和悬空指针问题。智能指针在头文件 中定义,常见的智能指针有三种:std::unique_ptr、std::shared_ptr 和 std::weak_ptr。智能指针的特点1.自动管理资源:2.避免内存泄漏:无需手动调用 delete,减少资源管理的复杂度和错误风险。
2024-11-22 21:44:23
891
原创 力扣 无重复字符的最长字串-3
移动语义是C++11中引入的一种特性,通过引入右值引用(T&&),支持资源的高效转移,而无需昂贵的拷贝操作。移动语义的核心作用是通过移动而不是复制的方式管理资源,从而提升程序性能,特别是在处理动态分配的资源(如内存、文件句柄等)时。
2024-11-21 21:34:31
723
原创 力扣 只出现一次的数字-136
C++中的初始化列表在C++中,初始化列表是用于初始化类对象成员的一种特殊语法。它在类的构造函数定义中,通过:后面跟随成员变量的初始化表达式实现。语法int a;int b;public://构造函数体(可选)这里的: a(x),b(y)就是初始化参数列表。它在构造函数体执行之前完成成员变量的初始化。作用初始化参数列表的主要作用是高效和正确地初始化类成员,尤其是以下几种情况:1.初始化常量成员public:2.初始化引用成员int& ref;public:3.调用基类构造函数。
2024-11-20 21:24:17
559
原创 力扣 移动零-283
在 C++ 中,友元函数(Friend Function)和友元类(Friend Class)是访问控制机制的一部分,允许它们访问其他类的私有(private)成员和保护(protected)成员。这种机制主要用于在类的外部实现某些操作,而这些操作需要访问类的内部数据成员或成员函数,但又不想将这些数据成员或成员函数公开暴露。
2024-11-18 21:26:18
585
原创 力扣 多数元素-169
在C++中,内联函数是一种特殊的函数,通过在函数定义前添加inine关键字来声明。例如编译器在处理内联函数时,会尝试将函数调用出直接替换为函数体的代码,而不是像普通的函数那样进行函数调用的开销(如保存当前函数的执行上下文、跳转到被调用函数的入口地址、执行完后再返回等操作)。普通函数:当调用普通函数时,程序需要执行一系列操作,如保存当前函数的执行上下文(包括寄存器的值、当前指令指针等),将参数压栈,跳转到被调用函数的入口地址,执行被调用函数的代码,最后在函数返回时恢复之前保存的执行上下文。
2024-11-17 16:46:10
670
原创 力扣 路径总和-112
在C++中,常量表达式是指在编译期间就能计算出结果的表达式。其值在程序运行过程中不会改变,并且可以在编译时确定。常量表达式可以是一个简单的常量,如字面常量(42、3.14等),也可以是由常量和运算符组成的表达式,只要这些运算符在编译阶段能够确定结果。例如,1+2、2*3+4都是常量表达式。对于变量,只有在 C++ 11 及以后的版本中,用constexpr关键字声明的变量,并且其初始化表达式是一个常量表达式时,这个变量也属于常量表达式。例如:constexpr int num = 10;
2024-11-16 22:10:59
814
原创 力扣 回文链表-234
C风格的强制类型转换:通用但不安全,会进行尽可能宽松的转换。静态类型转换:在编译时进行,用于明确且安全的类型转换。动态类型转换:在运行时进行,用于多态类型的向上或向下转换,提供安全类型检查。常量类型转换:用于添加或去除常量性(const 或 volatile)。重解释类型转换:最低级别的转换,只是重新解释位模式,通常不安全。选择哪种类型转换方式取决于具体的场景和安全性要求。
2024-11-16 17:08:21
1076
原创 力扣 最长公共前缀-14
虚拟内存是计算机系统内存管理的一种技术。它在操作系统的支持下,使用硬盘空间来模拟内存,为每个进程提供一个独立的、连续的虚拟地址空间。从进程的角度来看,它“认为”自己拥有连续的内存空间,这些地址被称为虚拟地址。当进程访问内存时,它使用的是虚拟地址,而操作系统会通过一种叫做内存管理单元(MMU)的硬件设备和相关的软件机制,将虚拟地址转换为物理地址,从而访问实际的物理内存或者硬盘上的交换空间(如果物理内存不足)。
2024-11-15 22:51:16
876
原创 力扣 二叉树的直径-543
当抛出异常时,程序需要执行一些额外的操作来查找合适的catch块,这包括栈展开(stack unwinding)过程,即从异常发生的地方开始,沿着函数调用栈向上查找catch块,在这个过程中需要清理局部对象等。以内存分配为例,当new操作符无法分配足够的内存时会抛出std::bad_alloc异常,通过try - catch块可以捕获这个异常并进行适当的处理,如释放已分配的其他资源或者向用户提示内存不足的信息。它是所有标准异常类的基类,提供了一个名为what的虚函数,用于返回异常的描述信息。
2024-11-13 20:07:22
711
原创 力扣 平衡二叉树-110
1.定义在C++中,命名空间(namespace)是一种用于将代码中的标识符(如变量、函数、类等)分组并避免命名冲突的机制。它提供了一个逻辑上的范围,它提供了一个逻辑上的范围,使得再不同命名空间中的相同名称可以独立存在。例如,有两个不同的库都定义了一个名为 print 的函数。如果没有命名空间,当同时使用这两个库时,编译器会不知道该使用哪个 print 函数,从而产生命名冲突。而命名空间可以将这些同名的标识符分隔开。2.作用避免命名冲突:这是命名空间最主要的作用。
2024-11-12 21:40:22
1118
原创 力扣 x的平方根-69
函数模板的定义以template关键字开头,后面跟着模板参数列表,通常是typename(或clss,它们在这种情况下是等价的)加上一个参数名。T temp = a;a = b;b = temp;这个函数模板可以交换两个相同类型的变量的值,T是一个模板参数,它可以代表任意类型,只要该类型支持赋值操作。类模板的定义也是以template关键字开头,后面跟着模板参数列表。int size;public://其他成员函数的定义。
2024-11-11 18:21:37
658
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅