自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 SQL 注入攻击

用户登录,输入用户名 lianggzone , 密码 123 or 1=1 ,如果此时使用参数构造的方法,就会出现select * from user where name = 'lianggzone' and password = '123' or '1' = '1';攻击者在 HTTP 请求中注入恶意的 SQL 代码,服务器使用参数构建数据库 SQL 命令时,恶意 SQL 被一起构造,并在数据库中执行。使用预编译的 PrepareStatement 是必须的,但是一般我们会从两个方面同时入手。

2025-02-19 10:50:12 293

原创 UDP

提供无连接的,尽最大努力的数据传输服务(不保证数据传输的可靠性)

2025-02-18 10:24:36 1076

原创 TCP

指在进行TCP数据传输时,多个小的数据包被合并成一个大的数据包进行传输的现象。指一个大的数据包被拆分成多个小的数据包进行传输的现象。1、应用程序向 TCP 套接字写入数据时,没有明确的边界划分,TCP 协议会根据自己的优化策略将数据进行合并或拆分。2、数据包大小超过了网络传输的最大传输单元(MTU)3、如果接收方读取数据的速度较慢,而发送方发送数据的速度较快,那么就可能会导致多个数据包在接收方的缓冲区中堆积,从而形成粘包现象。1、消息定长。2、在包尾部增加回车符或者换行符等特殊字符进行分割。

2025-02-17 20:16:28 1206

原创 HTTPS

SSL代表安全套接字层。它是一种用于加密和验证应用程序(如浏览器)和 Web 服务器之间发送的数据的协议。如今已逐渐被更安全的 TLS (传输层安全)协议取代。HTTPS 的加密机制是一种混合加密机制,结合了共享密钥加密(对称加密)和公开密钥加密(非对称加密)。对称加密的优点在于加密、解密效率通常很高。在 HTTPS 通信中,首先使用非对称加密交换密钥,然后利用对称加密进行实际的数据传输加密。非对称加密中,公钥是公开的,私钥则严格保密。

2025-02-16 10:58:14 798

原创 HTTP

建立起客户机和服务器连接。建立连接后,客户机发送一个请求给服务器。服务器收到请求,处理后给予响应信息。客户端浏览器将返回的内容解析并呈现,断开连接。

2025-02-15 10:58:22 1048

原创 TCP粘包/拆包

指在进行TCP数据传输时,多个小的数据包被合并成一个大的数据包进行传输的现象。指一个大的数据包被拆分成多个小的数据包进行传输的现象。1、应用程序向 TCP 套接字写入数据时,没有明确的边界划分,TCP 协议会根据自己的优化策略将数据进行合并或拆分。2、数据包大小超过了网络传输的最大传输单元(MTU)3、如果接收方读取数据的速度较慢,而发送方发送数据的速度较快,那么就可能会导致多个数据包在接收方的缓冲区中堆积,从而形成粘包现象。1、消息定长。2、在包尾部增加回车符或者换行符等特殊字符进行分割。

2025-02-13 22:07:01 347

原创 高并发 协程

将静态资源(图片,视频,js,css 等)单独保存到专门的静态资源服务器中,在客户端访问的时候从静态资源服务器中返回静态资源,从主服务器中返回应用数据。因为效率最高,消耗资源最小的就是纯静态的 html 页面,所以可以把网站上的页面尽可能用静态的来实现,在页面过期或者有数据更新之后再将页面重新缓存,或者先生成静态页面,然后用 ajax 异步请求获取动态数据。(集群是所有服务器都有相同的功能,请求哪台都可以,主要起分流作用)

2025-02-12 10:34:17 280

原创 多线程的同步机制

但屏障对象的概念更广,允许任意数量的线程等待,直到所有的线程完成处理工作,而线程不需要退出,当所有的线程达到屏障后可以接着工作。自旋锁顾名思义就是一个死循环,不停的轮询,当一个线程未获得自旋锁时,不会像互斥锁一样进入阻塞休眠状态,而是不停的轮询获取锁,如果自旋锁能够很快被释放,那么性能就会很高,如果自旋锁长时间不能够被释放,甚至里面还有大量的 IO 阻塞,就会导致其他获取锁的线程一直空轮询,导致 CPU 使用率达到 100%。因此 new 出来的都是共享的(16位平台上分全局堆和局部堆,局部堆时独享的)

2025-02-11 09:46:29 369

原创 内核空间和用户空间

例如,在32位系统中,用户空间的地址范围一般是 0 到 3GB(或 4GB 中的一部分),而内核空间的地址范围是 3GB(或更高)到 4GB。系统调用是一种特殊的机制,它允许用户空间的程序请求内核执行特定的操作,并在操作完成后返回用户空间。用户空间的程序在执行时具有较低的权限级别。当用户空间的程序需要执行一些只有内核才能完成的操作时,如读取硬盘数据、分配内存、创建进程等,就需要通过系统调用进入内核空间。内核空间的代码具有最高的执行权限,可以执行任何指令,访问任何硬件资源,并对系统的状态进行全面的控制。

2025-02-10 12:54:47 320

原创 PCB/进程地址空间

是指一个进程在运行时所看到的虚拟内存空间,每个进程都认为自己拥有独立的、连续的内存空间,但是实际上这是操作系统通过虚拟内存技术为每个进程提供的一种假象。实现进程的切换和恢复,当一个进程被切换出去时,操作系统将其PCB中的信息保存起来,当再次切换回来时,根据PCB中的信息恢复进程的运行状态。提供了进程之间的内存隔离,每个进程都有自己独立的地址空间,一个进程不能直接访问另一个进程的内存,从而提高了系统的安全性和稳定性。如进程的同步与互斥信号量、资源清单等,用于实现进程之间的同步、互斥以及对资源的管理。

2025-02-09 11:09:30 175

原创 多进程与多线程的对比

任务间相关性比较强的用多线程,相关性比较弱的用多进程。因为线程之间的数据共享和同步比较简单。需要大量计算的优先使用多线程,因为需要消耗大量CPU资源且切换频繁,所以多线程好一点。但是实际中更常见的是进程加线程的结合方式,并不是非此即彼的。可能要扩展到多机分布的用多进程,多核分布的用多线程。需要频繁创建和销毁的优先使用多线程。

2025-02-08 10:21:00 300

原创 死锁的产生与恢复

一个资源每次只能被一个进程使用。一个进程因请求资源而阻塞时,对已获得的资源保持不放。进程已获得的资源,在未使用完之前,不能强行剥夺。若干个进程之间形成一种头尾相接的循环等待资源关系。因为系统资源不足。进程运行推进的顺序不合适资源分配不当等。

2025-02-07 09:29:32 127

原创 进程调度方法和执行过程

按照作业到达任务队列的顺序调度 FCFS 是非抢占式的,易于实现,效率不高,性能不好,有利于长作业(CPU 繁忙性)而不利于短作业(I/O 繁忙性)。每次从队列里选择预计时间最短的作业运行。SJF 是非抢占式的,优先照顾短作业,具有很好的性能,降低平均等待时间,提高吞吐量。但是不利于长作业,长作业可能一直处于等待状态,出现饥饿现象;完全未考虑作业的优先紧迫程度,不能用于实时系统。

2025-02-06 09:40:35 347

原创 进程之间的通信方法

一个进程写入共享内存的信息,可以被其他使用这个共享内存的进程,通过一个简单的内存读取读出,从而实现了进程间的通信。的方式从缓冲区中读取存储数据:管道一端的进程顺序的将进程数据写入缓冲区,另一端的进程则顺序的读取数据,该缓冲区可以看作一个循环队列,读和写的位置都是自动增加的,一个数据只能被读一次,读出以后再缓冲区都不复存在了。当缓冲区读空或者写满时,有一定的规则控制相应的读进程或写进程是否进入等待队列,当空的缓冲区有新数据写入或满的缓冲区有数据读出时,就唤醒等待队列中的进程继续读写。管道是最容易实现的,

2025-02-05 10:13:39 385

原创 进程与线程

进程是对运行时程序的封装,是系统进行资源分配和调度的基本单元,而线程是进程的子任务,是CPU分配和调度的基本单元。一个进程可以有多个线程,但是一个线程只能属于一个进程。进程的创建需要系统分配内存和CPU,文件句柄等资源,销毁时也要进行相应的回收,所以进程的管理开销很大;但是线程的管理开销则很小。进程之间不会相互影响;而一个线程崩溃会导致进程的崩溃,从而影响同个进程里面的其他线程。线程是存在进程的内部,一个进程中可以有多个进程,一个进程只能存在一个进程中。

2025-01-28 10:33:06 379

原创 char 和 varchar

固定长度最大255字符数据长度不足会在尾部填充空格,查询时会自动去掉空格效率高,占空间长度可变最大可设置 65535 字节。

2025-01-27 09:46:43 251

原创 哈希算法 位图 Bloom Filter

1、使用哈希算法进行数据分布,将数据分散存储在多个文件或多个机器上。通过合适地哈希函数,可以实现均匀地数据分布。2、将任意长度的二进制值串映射为固定长度地二进制值串,这个映射地规则就是哈希算法,而通过原始数据映射之后得到地二进制值串就是哈希值。1)从哈希值不能反向推导出原始数据(所以哈希算法也叫单向哈希算法);2)对输入数据非常敏感,哪怕原始数据只修改了一个 bit ,最后得到的哈希值也大不相同;3)散列冲突的概率要很小,对于不同的原始数据,哈希值相同的概率非常小;

2025-01-26 10:32:44 625

原创 map 和 unordered——map 实现原理

当插入一个元素时,map 根据键的大小将元素插入到红黑树中的适当位置,并确保树的平衡性。哈希表是一种根据键直接进行访问的数据结构。当进行查找操作时,unordered_map 会通过哈希函数计算出键所对应地哈希值,然后根据哈希值找到相应地桶,最后在该桶对应地链表或红黑树中查找目标元素。通过这些特性,红黑树保证了其相对平衡的性质,在最坏情况下,它能够保证插入、删除和查找操作的时间复杂度为 O(logn) 其中 n 是树中节点的数量。这个特性保证了红黑树的节点颜色的明确性,节点颜色的确定性是实现平衡的关键。

2025-01-24 16:36:52 411

原创 STL内存优化

首先先要检查申请空间的大小,如果大于128字节就调用第一级配置器,小于128字节就检查对应的空闲链表,如果该空闲链表中有可用数据块,则直接拿来用(拿取空闲链表中的第一个可用的数据块,然后把该空闲链表的地址设置为该数据块指向的下一个地址),如果没有可用的数据块,则调用refill重新填充空间。如果一块都无法提供,则把剩余的内存挂到自由链表,然后向系统heap申请空间,如果申请失败,则看看自由链表还有没有可用的块,如果也没有,则最后调用一级空间配置器。如果内存池空间足够,则取出内存。

2025-01-20 10:15:36 389

原创 vector扩容 list和vector的比较

vector是一个动态数组,它会根据元素的个数,适当的去申请内存。可以简单的把vector理解为,其内部有一个void*指针,用于指向在堆上申请的空间。void*指向的空间用于存放vector元素。vector一直维护着void*空间的大小,当void*指向的堆区空间没有空间存放新插入的元素时,他都会去系统申请之前空间大小的两倍空间,并把之前的元素全部拷贝到新的空间,释放掉原空间,在新空间中插入新的元素。

2025-01-19 10:14:00 437

原创 vector迭代器

最后,iter 将指向 ivec 中的最后一个元素,处理完最后一个元素后,iter 再增加 1,就会与 end 操作的返回值相等,在这种情况下,循环终止。如果 ivec 为空,则 begin 返回的迭代器不指向任何元素,由于没有元素,所以它不能指向任何元素———在这种情况下,从 begin 操作返回的迭代器与从 end c操作返回的迭代器的值相同,因此 for 语句中的测试条件立即失败。迭代器类型定义了一些操作来获取迭代器所指向的元素,并允许程序员将迭代器从一个元素移动到另一个元素。

2025-01-17 11:34:10 756

原创 归并排序

1、将数组进行分解,当分解成单个元素为一组的时候才是组内有序的(将目标数组拆分成两个数组,设初始数组最小下标为 L,最大下标为 R,控制项 mid = (R - L) / 2 + L,得到两个子数组。2、将两两有序的数组进行合并,先申请等于两个数组合并后大小的空间,然后将两个排序好的数组逐一比较,向申请的空间中放入较小元素,直至两个有序数组组合成为一个有序数组。查找成功,返回关键字所在数组下标,没找到返回 -1;若大于,则在后半个区域中继续进行折半查找。将两个有序数组合并成一个有序数组。

2025-01-15 10:37:15 148

原创 快速排序

如果 vec[index] = 2,swap[vec[index],vec[--right]);right 的含义:使数组中下标 >=right 的部分都比 1 大,right 的初始值为 n;如果 vec[index] = 0,swap(vec[index++],vec[++left];left 的含义:使数组中下标

2025-01-13 14:51:28 311

原创 堆排序 OSI的七层模型

1)完全二叉树:若设二叉树的深度为 h,除第 h 层外,其他各层(1~h-1)的节点数都达到最大个数,第 h 层所有节点都连续集中在最左边,只能从最深处最右边从右往左缺省。2)最大堆结构:是一个完全二叉树,堆中每个节点的值总是不大于其父亲节点的值(即根节点总是最大元素)

2025-01-12 10:52:56 342

原创 插入排序 计数排序 数据库的三范式

1、将数组分为有序表和无序表,每次从无序表中取出一个元素,插入到有序表的适当位置,刚开始有序表中只有一个数,无序表中有 n-1 个数。2、每遍历一次,有序表中元素增加一个,无序表中元素个数减少一个,重复 n-1 次,完成排序。O(n^2)O(n)比较 n-1 趟,每一趟比较一次,不移动元素,故最好时间复杂度为 O(n)O(n^2)第一次排序时有序表 1 个元素,无序表 n-1 个元素,比较 1 次,移动 1 次第二次排序时有序表 2 个元素,无序表 n-2 个元素,比较 2 次,移动 2 次。

2024-12-22 20:18:36 415

原创 选择排序 冒泡排序 MySQL 架构

1、遍历数组,选择找到最大值,记录最大值下标 maxindex,然后将最大值与最后一个值交换,即 swap(vec[maxindex] , vec[n-1]);2、在剩下的待排序数组中,重新找到最大值,重复第一步,swap(vec[maxindex] , vec[n-2]);循环操作,直至数组排序完成。第一次排序时是 n 个元素,比较 n-1 次第二次排序时是 n-1 个元素,比较 n-2 次第 n-1 次排序时是 2 个元素,比较 1 次第 n 次排序时是 1 个元素,比较 0 次。

2024-12-21 15:32:21 799

原创 处理对象的创建与销毁的时机 处理对象的状态存储与恢复

正确处理对象的创建和销毁时机对于程序的正确性和性能至关重要。如果对象创建过早或销毁过晚,可能会浪费资源。如果创建过晚或销毁过早,可能会导致程序出现错误。同时,合理的创建和销毁时机可以提高程序的可维护性和可读性。

2024-12-20 22:26:07 359

原创 对象的状态变化 工厂模式

工厂模式是一种创建对象的设计模式,它提供了一种创建对象的方式,将对象的创建和使用分离。通过工厂模式,可以根据不同的条件创建不同类型的对象,而不需要在客户端代码中显式的指定具体的对象类型。

2024-12-19 15:45:47 447

原创 对象的克隆 单例模式

单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点来访问这个实例。单例模式在整个程序运行期间只创建一个对象,常用于管理全局资源、实现日志系统等场景。

2024-12-18 14:38:28 677

原创 对象的生命周期管理

正确管理对象的生命周期对于确保程序的正确性和稳定性至关重要。如果对象的创建和销毁对象 没有得到妥善处理可能会导致内存泄漏、资源泄漏或悬空指针等问题。同时,合理的生命周期管理可以提高程序的性能,避免不必要的资源分配和释放操作。

2024-12-17 14:01:01 187

原创 序列化和反序列化 类层次结构

序列化是将对象的状态转换为可以存储或传输的形式,如二进制数据或文本格式。反序列化则是将序列化后的数据转换回对像的状态,这在需要保存对象状态、在网络上传输对象或者在不同的程序之间传递对象时非常有用。

2024-12-16 16:21:50 358

原创 接口继承与实现继承的区别 处理多态性与性能的平衡

例如,在一个游戏开发中,可能有一个基础的角色类,其他具体的角色类可以继承这个基础角色类的实现,并进行特定的扩展。接口继承:适用于定义一组通用的接口,让不同的类实现这些接口,以实现多态性。例如,在图形绘制系统中,可以定义一个抽象的图形接口类,让不同的具体图形类实现这个接口。接口继承是指子类只继承基类的纯虚函数,即只继承基类的接口,而不继承基类的实现。优化关键路径:对于性能关键的代码路径,可以考虑避免使用多态性,或者使用其他技术,如模板元编程来实现类似的功能,以提高性能。2) 如何处理多态性与性能的平衡?

2024-12-15 14:31:18 343

原创 C++ 中动态绑定、内存管理

当使用基类指针或引用调用虚函数时,实际调用的是派生类中重写的函数,具体调用哪个函数却决于指针或引用所指向的对象的实际类型。它允许在不修改现有代码的情况下,通过添加新的派生类来扩展程序的功能,并且能够在运行时根据具体的对象类型选择合适的函数调用。例如,对于动态分配的内存,可以在构造函数中进行分配,在析构函数中进行释放。使用智能指针:如 std::unique_ptr、std::shared_ptr 和 std::weak_ptr,可以自动管理内存的分配和释放,避免内存泄漏和悬空指针的问题。

2024-12-14 14:45:57 286

原创 面向对象编程设计原则 如何处理异常

当程序出现错误或异常情况时,通过抛出和捕获异常,可以使程序更加优雅地处理错误,而不是直接崩溃。同时,异常处理也可以使错误处理代码与正常的业务逻辑分离,提高代码的可读性和可维护性。在可能抛出异常的代码块中使用" try " 语句,然后再" catch " 块中捕获特定类型的异常并进行处理。这意味着在设计软件时,应该尽量使软件易于扩展新的功能,而不需要修改现有的代码。这意味着一个类应该只负责一项单一的职责,避免类的功能过于复杂和庞大。这意味着在设计接口时,应该尽量使接口小而专一,避免提供不必要的功能。

2024-12-13 14:49:57 285

原创 C++ 中多态性 和 数据隐藏

在C++中,可以通过将数据成员声明为私有或受保护,并提供公有的成员函数来访问和修改这些数据成员,从而实现数据隐藏。在一个图形绘制系统中,可以定义一个抽象的图形类,然后派生出各种具体的图形类,如圆形、矩形、三角形等。同时,数据隐藏也使得类的内部实现细节对外部不可见,这样在修改类的内部实现时,不会影响外部代码的使用。通过多态性,可以使用一个统一的接口来绘制不同类型的图形,而不需要为每种图形都编写单独的绘制函数。在编写设备驱动程序时,可以定义一个抽象的设备类,然后针对不同的设备类型派生出具体的设备类。

2024-12-12 14:32:24 183

原创 C++运算符重载

可以使自定义类型的对象像内置类型一样使用运算符进行操作,增强了代码的表达能力。例如,可以为自定义的矩阵类重载加法、乘法等运算符,使得矩阵的运算更加直观和方便。同时,运算符重载也可以提高代码的可读性,使代码更符合人们的习惯思维。对于成员函数形式的重载,运算符函数的参数个数比实际操作数少一个,因为第一个操作数是对象本身。运算符重载是指赋予C++已有的运算符新的含义,使其能够用于特定类型的对象操作。通过重载运算符,可以使代码更加简洁、直观,提高代码的可读性和可维护性。2)如何在 C++ 中进行运算符重载?

2024-12-11 15:37:35 214

原创 C++纯虚函数

这有助于提高代码的可扩展性和可维护性,因为可以在不修改现有代码的情况下添加新的派生类来实现新的功能。它们提供了一种抽象机制,使得程序员可以定义一个通用的接口,而具体的实现由派生类来完成。纯虚函数的存在表明该函数在基类中没有具体的实现,需要在派生类中进行重写。他的主要作用是为派生类提供一个统一的接口,强制派生类实现某些特定的功能。同时,抽象类也可以作为一种设计约束,确保派生类实现了特定的功能。纯虚函数是在基类中声明但没有具体实现的虚函数,其声明形式为。3) 纯虚函数和抽象类在面向对象编程中的意义是什么?

2024-12-08 15:32:15 186

原创 C++中多态

例如,在一个图形绘制程序中,可以使用多态性来处理不同类型的图形对象,只需要一个统一的接口来绘制各种图形,而不需要为每种图形都编写单独的绘制函数。多态性可以提高代码的灵活性和可扩展性,使程序能够根据不同的对象类型执行不同的操作。通过基类指针或引用调用虚函数时,实际调用的是派生类中重写的函数。多态性是指通过基类指针或引用调用派生类的函数,实现不同的行为。同时,多态性也可以提高代码的可重用性,减少重复代码的编写。在基类中声明虚函数,在派生类中重写这些虚函数。2)C++中如何实现多态?3) 多态性的好处是什么?

2024-12-07 17:38:53 362

原创 C++中继承

使用 “ class 派生类名 :继承方式 基类名 ” 的语法来实现继承。注意事项包括避免继承层次过深,防止出现复杂的继承关系导致代码难以理解和维护。还要注意继承方式的选择,不同的继承方式会影响基类成员在派生类中的访问权限。继承性允许一个类(派生类)继承另一个类(基类)的属性和方法。派生类可以扩展和修改基类的功能,实现代码的重用和层次化设计。同时,继承可以建立类之间的层次关系,使代码结构更加清晰。好处是可以实现代码重用,减少重复代码的编写。3) 继承的好处和注意事项有哪些?2)C++中如何实现继承?

2024-12-06 15:39:09 243

原创 C++封装性

封装性是将数据和操作封装在类中,通过访问修饰符(如public、private、protected)控制对类成员的访问权限。将类的成员变量声明为private或protected,提供public的成员函数来访问和修改这些成员变量。当内部实现需要改变时,只需要修改类的内部代码,而不会影响外部代码的使用。同时,封装可以使类的接口更加清晰,提高代码的可读性和可维护性。可以防止外部代码直接访问和修改类的内部数据,减少错误的发生。这里可以隐藏内部实现细节,提高代码的安全性和可维护性。3) 封装性的好处是什么?

2024-12-05 14:36:57 173

空空如也

空空如也

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

TA关注的人

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