初识计网应用层协议HTTP
应用层数据组织与传输我们所写的提供网络服务的程序都是运行在应用层上的。在这些程序中,我们往往会使用结构体、类和对象等结构化的方式组织数据 但是在使用socket api接口时,我们只能使用字符串/字节流的格式来发送/接收信息,实现网络通信。但是对于提到的结构化数据,又该怎么使用网络通信传输呢? 应用层协议针对应用层内的通信问题,我们依然使用协议解决。只要发送方和接收方按照同一’约定’对结构化数据进行字节流编码和字节流解析,就能够实现通过网络进行通信。这样的约定就是 协议。 既然协议是一种约定,那么就能开发出各种各样的的应用层协议。但它们往往会用到序列化和反序列化技术,所以我们先了解一下什么是序列化和反序列化 序列化与反序列化这一技术能够在对象(结构化数据)和字节流之间架起桥梁,使对象能够更方便地支持网络通信,或者文件持久化。简单来说序列化就是基于某种规则把对象/结构化数据转化成字节流,反序列化就是基于同样的规则,把字节流还原成对象/结构化数据。 相关的序列化格式可以自己定义,当然也可以直接使用别人封装好的现成的格式。就比如常见的JSON,XML,YAM ...
【功能更新v1.4】同步&异步⽇志系统Sink类主题更新,新增数据库落地,及重大bug修复
本次版本更新我们采用Sink类主题更新,实现数据库落地,按小时按天滚动输出,网络输出,以及标准输出按等级染色 重大bug修复修改前的代码 12345678910void error(const char*file,size_t line,const char*fmt,...){ if(shouldLog(LogLevel::Level::ERROR) == false) return; va_list al; va_start(al,fmt);//依据fmt从内存中提取可变参数列表 log(LogLevel::Level::WARN,file,line,fmt,al);//日志输出 va_end(al);//结束可变参数列表} 可以看到里面的ERROR被错误地写成了WARN,导致输出error等级的日志时会错误输出WARN。因为这一bug涉及到项目的核心功能,所以判定为重大bug。这一重大bug导致前面的版本全都作废 数据库落地这里我们使用部署在云服务器上的MySQL数据库服务来提供远程数据库存储服务 数据库准备特别注意, ...
面向对象分析与设计(1)--软件是复杂的
复杂性complexity是软件开发避不开的问题。因为软件本质上就是复杂的,而软件开发团队的任务是制造出简单的假象(用户友好),所以软件开发者必须能够深刻认识其复杂性,并处理好复杂性问题 方法论:复杂系统的组织结构层次性一个人的能力总是有限的,复杂的系统若是没有合理的组织结构,是无法把握的,就像下图混乱组织的笔记本结构图 在上图中我们看到了有关笔记本电脑的各种相关概念,它们都是整个复杂系统的一部分,但是因为混杂在一起,彼此独立又相互有关系。但仔细观察我们可以发现,它们的关联关系并不都是等价的,因此我们按照关联关系的紧密程度,各个组成部分在系统中的地位等,将上图的概念重新组织一下 可以看到,经过多层次的组织之后。即便是复杂的笔记本结构系统,也能清晰地展示出来。而且如果我们要解释笔记本电脑的构成,也可以很自然地有了解释的顺序,比如自顶向下,笔电由软件和硬件构成,硬件又由….;在比如自底向上,我们先攒出一些列基础硬件和基础软件,然后再向上组装… 所以,对于复杂的系统,分层组织就是我们的方法论,我们的重点就是把握好每一个概念究竟是属于哪一层的,哪些概念是同一层的关系,还是上下层的关系。经过 ...
【迷你组件】MySQL登录用户管理和持久化组件
当要在代码中连接数据库时,往往需要登录用户的信息,而实际使用时登录用户常常变化,硬编码到代码中,改起来十分麻烦。所以使用Json技术将我们封装好的用户管理类序列化并储存到文件中,既能够持久化,还实现了软编码,使用户仅需方便地修改文件内容就能修改用户信息了。 用户配置类设计第三方库这里用到了两个第三方库 -ljsoncpp Json的第三方库 -lmysqlcppconn 数据库的第三方库 编译指令如下 1g++ -o $@ $^ -std=c++11 -ljsoncpp -lmysqlcppconn 代码实现作为MySQL用户配置,至少要支持储存如下信息 用户名 密码 数据库 登录ip 登录端口号 然后核心功能如下 成员变量的访问和设置 将配置写入文件 从文件读入配置 根据如上要求,我们设计的核心代码如下 DBUserConfig.hpp 12345678910111213141516171819202122232425262728293031#pragma once#include <jsoncpp/json/json.h>#include <s ...
设计模式的C++实现(5)——原型模式
模式名称: 原型模式-Prototype类型: 创建型模式问题-使用场景: 当创建不同对象的过程过于复杂,或者需要隐藏/封装创建对象的具体过程,或者组织项目需要创建过多的子类,类的数目需要优化减少时,亦或者需要动态类时,可以由原型对象来执行类的功能解决方案: 用原型实例指定创建对象的种类,并通过拷贝这些原型来创建新的对象效果: 相比其它模式,用户只需考虑怎么检索到所需要的原型对象来拷贝出新的对象给自己用,而不用考虑如何构造。这样的设计能简化用户操作,且能极大地增加扩展性。 概念抽象原型模式旨在通过使用不同的原型对象来克隆获取不同的实例,而不是声明许多派生类,再通过派生类来实例化出不同的对象。这样减少类总数的设计方式,可以很好地简化整个项目的类的结构设计,毕竟类总数越多,要维护的类关系就越复杂,理解成本就越高。 原型模式抽象出的参与者有如下三种 Client:负责找到指定原型,并调用其克隆接口,克隆出一个对象 Prototype:抽象类,声明一个抽象接口 ConcretePrototype:实现具体的克隆操作 三者的类图关系如下: 具体使用我们来举一个具体一点的例子来 ...
【补丁更新v1.2~1.3】同步&异步⽇志系统的问题优化与异常处理
解决异步日志器黏包问题由于原本的设计是一股脑直接把日志信息送进了缓冲区,导致输出的时候会产生黏包问题。但是为什么一开始没在意呢?因为标准输出和文件输出都不在意黏包问题,同时输出多条日志是没问题的。 但是!一旦要开始插入数据库,问题就很严重了。日志信息必须一行一行储存。原本的黏包问题会导致日志信息的解析不可解,所以我们需要修改原本的代码使其能够解决黏包问题 分隔符用特定的分隔符标记一次日志的头尾是最容易想到的解决方案。 然而日志信息是字符串,任何字符都有可能出现,导致找不到特定的分隔符可以安全地分隔日志信息 分隔符只适用于待封装信息的字符在限定范围内时使用。 封装报头假如我们能获得一段日志的长度就好了。 这样的愿望可以封装报头实现。在获取一长段数据时,我们规定最前面的是报头,包含第一段报文的信息(在这个项目里只简单的包括长度信息)。这样我们就能先读取信息再读取报文了。 那么怎么标定报头的范围呢? 约定使用定长报头 约定使用分隔符 定长报头很好理解,而这里又能用分隔符了是因为报头在一段信息的最前面,最先遇到的特殊字符必定是作为分隔符存在的 这里因为没太多信息需要封装进报头,所以我们采 ...
MySQL Connector/C++常见接口/类介绍
当我们有用C++程序连接MySQL数据库并执行SQL语句时,往往要用到相关的库,这里使用的是MySQL官方提供的Connector/C++库,为了更好地使用库里的内容,我们先来熟悉一下里面常用的接口和类 MySQL准备为了便于测试,我们专门创建一个用于测试的用户和数据库,并给予相关权限 12345create user 'conn'@'localhost' identified by '12345678';create database testDB;grant all privileges on testDB.* to 'conn'@'localhost'; 认识接口/类我们将逐个介绍如下类及其相关接口 sql::SQLString sql::mysql::MySQL_Driver –<mysql_driver.h> sql::mysql::get_mysql_driver_instance() sql::Connection –<mysql ...
MySQL用户管理
为什么有用户管理类比Linux中只有root用户过于危险,因为root能随意地增删查改计算机上的任意文件 MySQL只有root用户登录也是十分危险的,因为root有增删查改所有数据库和表的权限,数据安全得不到保障,所以MySQL有自己的用户管理系统 用户管理的使用用户信息显然用户信息是需要组织和管理的,所以按照先描述,再组织的原则,我们来思考一下用户信息在逻辑上是什么样的管理思路 描述用户只需略微思考一下在MySQL中描述一个对象怎么样最方便准确,很明显,就是它自带的表结构。 实际上也确实是这样,MySQL用了一个在mysql数据库中的user表用来描述所有的用户 client1234567891011121314151617181920212223242526272829mysql> use mysqlDatabase changedmysql> select host,user,authentication_string from user;+-----------+------------------+-------------------------------- ...
设计模式的C++实现(4)——迭代器Iterator
模式名称: 迭代器-Iterator类型: 行为模式问题-使用场景: 提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示解决方案: 将对列表(对象集合)的访问和遍历从具体对象中分离出来,并放入一个迭代器对象中,由它负责实现访问和遍历功能效果: 提供了统一的遍历成员的方法,降低了用户的使用难度,提高了代码的封装性和可扩展性。代价是增加了代码复杂性,增加了更多的类,提高了代码的设计难度 注:本文的迭代器风格更偏向STL库中的迭代器,而不是《设计模式》中的抽象迭代器 灵感来源:某种意义上将,Iterator要做的事就是模仿数组中的指针,指针可以前后移动,方便地遍历数组,还可以用指针访问数组元素。我们希望把这种指针特性也用在其它数据结构上(特指组织管理多个对象的聚合体),但可惜的是原生指针的这种方便依赖于数组的地址是连续的。因此为了实现遍历和访问功能,我们需要把这些功能封装在Iterator类中,让它实例化出的对象来行使数组指针一样的行为。 类层次设计我们先来设计一个抽象迭代器类来规定迭代器应有哪些行为: 12345678910111213141516171819 ...
设计模式的C++实现(0)——初识设计模式
《设计模式的C++实现》为作者对系列博客的又一次尝试:在开发过C++基于多设计模式下的同步&异步⽇志系统🔗后,作者接触到了《设计模式》这本书,颇有感触,于是决定写博客来记录读后的灵感,然而随着博客内容的不断丰富,单篇的博客已经承载不下如此多样的内容,各种各样的设计模式便是一个典例,所以我决定将设计模式相关的博客拆成一个系列博客 目录:TODO 知识基础本系列博客着重于经典设计模式的介绍和运用C++类和对象技术将其实现,所以要求读者已经能够熟练掌握C++类和对象技术。并且当我们提及抽象类,多态,或者继承,虚函数的声明与实现等概念时,你应当已经对这些概念了然于心,而不是一知半解,还要查资料复习 设计模式从何而来设计模式描述了在面向对象软件设计过程中针对特定问题的简洁而优雅的解决方案。设计模式捕获了随时间进化与发展的问题的求解方法,因此它们往往并不是人们从一开始就采用的设计方案,它们反映了不为人知的重新设计和重新编码的成果,而这些都来自软件开发者为了设计出灵活可复用的软件而长时间进行的艰苦努力。设计模式所做的事,就是捕获这些解决方案,并用简洁易用的方式表达出来。 学习目标设 ...
【代码整理】同步&异步⽇志系统的代码复盘
在项目的介绍博客🔗中,我们着重于代码功能的实现,而对项目代码整体的结构和风格欠缺重视,使其可读性有所欠缺,代码规范性也有所不足。所以在这篇博客中,我们将按上篇博客编写代码的顺序,再一次回顾写好的代码,并着重于: 调整代码结构 增加必要注释,删除冗余注释 添加必要的小括号,突出优先级 将代码的简便写法改写回易读的写法 实用类 增加功能简介 增加注释 增加空行12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576#pragma once#include <iostream>#include <fstream>#include <sstream>#include <string>#include <ctime>#include <cassert>#include <sys/stat ...
初识Linux套接字(socket)和TCP/UDP协议
这是系列博客中的第二篇,导航如下 初识计算机网络🔗 初识Linux套接字(socket)和TCP/UDP协议🔗 👈您在这里 在Linux环境中,套接字(Socket)是一种用于进程间通信(IPC)的机制,但这里的进程,包括了同一网络下其它主机的进程,所以它被广泛应用于网络编程。它允许不同计算机上的进程或同一计算机上的不同进程之间进行数据交换。 由于此时我们的网络编程基础较少,所以本文的内容更偏向于实践,而不是原理。希望能在动手实践中加深对网络编程的熟悉程度,减少陌生感 在本文中,我们将: 知识铺垫:认识IP地址, 端口号, 网络字节序等网络编程中的基本概念(简略) socket API学习 实现一个简单的UPD客户端/服务器 实现一个简单的TCP客户端/服务器(服务器包括单连接版本,多进程版本,多线程版本) 知识铺垫理解源IP地址和目的IP地址在数据包的头部中,包含两个IP地址,分别叫做源IP地址和目的IP地址 为什么要有两个IP地址?因为一般通过网络建立的通信都是双向的,而且一方接收请求后,一般还要把响应发送回去,所以含有两个IP地址才 ...
初识Linux编程&初识makefile
前言本文将以实用的视角,以快速上手Linux平台的C++编程为目的,介绍: Linux的基本操作 gcc/g++的常用指令 makefile的常用编写方式 软件准备如果选择用虚拟机,那请自己解决 这里介绍使用Linux服务器配合本地ssh链接软件的方式在服务器上编写代码 首先是服务器,可以在主流服务器平台(阿里云,腾讯云,华为云)等购买服务器,一般有学生认证会更便宜,服务器配置不限,若要使用Linux,可以选择Ubuntu内核,(CentOs也行,就是太老了,且停止维护了),然后自行查阅相关教程,设置默认管理员账户和密码,以及配置服务器,开启ssh远程链接权限 关于本地的ssh链接软件,这里我只推荐两个我使用过的 xshell7 vscode+ssh插件 其中xshell比较简单,安装好就能用 戳我去下载免费版xshell🔗,怎么登录服务器?自行百度~。但缺点是仅支持控制台,所以写代码只能用vim等支持控制台的文本编辑器 vscode+ssh插件会比xshell麻烦点,还要修改配置文件,具体教程可参考b战视频🔗 但优点是vscode在支持终端(控制台)的同时还支 ...
设计模式的C++实现(2)——代理模式
代理模式 模式名称: 代理模式-Proxy类型: 结构型问题-使用场景: 在执行类和用户间再增加一个中间人,执行类的交互对于用户来说过于复杂,执行类的接口对参数检查较严格等解决方案: 可以封装一个类,为用户提供更简洁的接口,而与执行类的交互在其内部实现;或者封装一个头文件,在里面封装全局函数和宏函数等效果: 增加代码复杂性,封装层数更高,更加抽象。具体实现方式十分多样,增加了代码编写者的工作,但减少了用户的使用难度,也能一定程度上提高安全性 代理模式指代理控制对其他对象的访问, 也就是代理对象控制对原对象的引⽤。在某些情况下,⼀个对象不适合或者不能直接被引⽤访问,⽽代理对象可以在客⼾端和⽬标对象之间起到中介的作⽤。代理模式的结构包括⼀个是真正的你要访问的对象(⽬标类)、⼀个是代理对象。⽬标对象与代理对象实现同⼀个接⼝,先访问代理类再通过代理类访问⽬标对象 按照编译时和运行时的行为,代理模式分为静态代理、动态代理: 静态代理指的是,在编译时就已经确定好了代理类和被代理类的关系。也就是说,在编译时就已经确定了代理类要代理的是哪个被代理类。 动态代理指的是,在运⾏时才动态⽣成代理类,并将 ...
设计模式的C++实现(1)——单例模式
单例模式介绍 模式名称: 单例模式-Singleton类型: 创建型问题-使用场景: 希望一个类在全局只实例化出一个对象解决方案: 使用静态成员,将构造函数私有化,删除拷贝构造和opetator=()函数效果: 略微增加代码复杂性,使用了静态成员变量/函数。但是能够保证该类只会有一个实例。 ⼀个类只能创建⼀个对象,即单例模式,该设计模式可以保证系统中该类只有⼀个实例,并提供⼀个访问它的全局访问点,该实例被所有程序模块共享。⽐如在某个服务器程序中,该服务器的配置信息存放在⼀个⽂件中,这些配置数据由⼀个单例对象统⼀读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息,这种⽅式简化了在复杂环境下的配置管理。 单例模式有两种实现模式:饿汉模式和懒汉模式 饿汉模式饿汉模式中,程序启动时就会创建⼀个唯⼀的实例对象。 因为单例对象已经确定, 所以⽐较适⽤于多线程环境中, 多线程获取单例对象不需要加锁, 可以有效的避免资源竞争,⾼性能。 123456789101112131415161718template<typename T>class Singleton &# ...
设计模式的C++实现(3)——工厂模式与建造者模式
模式名称: 工厂模式-Factory类型: 创建型问题-使用场景: 当创建不同对象的过程过于复杂,或者需要隐藏/封装创建对象的具体过程,或需要创建同一家族的产品(对象)时解决方案:将创建对象的过程封装到工厂类内,并提供设置创建不同对象的接口效果: 简化了用户操作,使创建对象,创建多个不同的对象更为简单易用,提高了代码的封装性。但是代码复杂性大大提高,类封装的层次更多了,可扩展性会有所欠缺。 模式名称: 建造者模式-Builder类型: 创建型问题-使用场景: 当创建不同对象的过程过于复杂,或者需要隐藏/封装创建对象的具体过程,或需要创建同一家族的产品(对象)时解决方案:将创建对象的过程封装到Builder内,并提供设置创建不同对象的接口,以及提供不同的Builder派生类,最后提供一个指挥者类统一指挥对象的创建效果: 可扩展性强的同时,简化了用户操作,使创建对象,创建多个不同的对象更为简单易用,提高了代码的封装性。但是代码复杂性大大提高,类封装的层次更多了。 ⼯⼚模式是⼀种创建型设计模式, 它提供了⼀种创建对象的最佳⽅式。在⼯⼚模式中,我们创建对象时不会对上 ...
【版本v1.0】C++基于多设计模式下的同步&异步⽇志系统
前置知识 Linux日志器(简易版) 初识Linux线程 初识设计模式&单例模式&代理模式–设计模式介绍(1) 工厂模式与建造者模式–设计模式介绍(2) 项目介绍背景引入 日志系统在软件开发和运维中扮演着至关重要的角色,主要体现在以下几个方面: 问题排查和调试:日志记录了系统运行过程中的重要信息,包括错误信息、异常堆栈、接口调用信息等。开发人员可以通过分析日志快速定位问题,减少排查时间,提高开发效率。 性能监控:通过记录应用程序的性能指标(如响应时间、请求吞吐量等),开发团队可以监控系统的健康状态,发现性能瓶颈并进行优化。 安全审计:日志可以记录用户的操作和系统事件,为后期的安全审计提供依据。一旦发生安全事件,通过分析日志可以追踪到攻击来源和攻击方式。 用户行为分析:通过对日志进行分析,开发团队可以了解用户的使用习惯和需求,这有助于改进产品功能和用户体验。 合规要求:在许多行业中,日志记录是合规的要求之一。维护完整的日志记录可以帮助企业满足法律法规和行业标准。 系统健康监控:通过实时监控日志,可以及时发现系统异常,进行预警和自动化处理,从而提高系统的可用性和稳定性。 ...
Cpp售货机类模拟实现
这是一篇复习类的博客,主要综合运用以下知识: 格式化输入输出及打印菜单 类的封装 类的组合 子函数概念 共享指针 lambda表达式 头文件为了简便,就把类的声明和实现写在同一个VendingMachine.h文件里了 12345678#pragma once#include <string>#include <vector>#include <unordered_map>#include <iostream>#include <algorithm>#include <windows.h>using namespace std; //展开std命名空间 这里一次性给出所用的头文件,后文便不再添加了 封装商品类售货机当然要管理商品啦,那怎么管理呢?依然是先描述,再组织 怎么描述?把它封装成商品类 1234567891011struct Item{public: Item(const string& name,double price,int cnt) :_name(name),_price( ...
初识计算机网络
—-这是第一条ARPANET信息,发送于1969年10月29日,从加州大学洛杉矶分校(UCLA)发往斯坦福大学。这条消息本来想说的是“登录”(LOGIN),但是系统崩溃了。 因特网初创于20世纪60年代,其初衷在于建造一个网络来连接分散在不同地理位置的计算机 如今的因特网由几百万个松散连接的独立网络构成,其中的每个网络都连接到另外一个或多个网络。邻近的计算机通过本地的局域网相互连接,这些局域网通常为无线以太网。网络之间通过网关或路由器相互连接。网关和路由器是专用的计算机,用来把组成信息的数据包从一个网络指引到下一个网络。(维基百科上说网关是通用设备,而路由器是其中的特例,其用途并不通用。)网关之间互相交换着路由信息,这样它们就至少知道哪些网络与本地网络相连并可以被访问到。 计算机网络背景网络发展 独立模式:计算机之间相互独立 网络互连:多态计算机连接在一起,完成数据共享 例如网吧的无盘系统,同一个房间的所有电脑连在一起,共享硬盘 局域网LAN: 网络中计算机的数量更多了,通过交换机和路由器连在一起 广域网WAN:通过局域网的层层相连,将相隔千里的计算机连在 ...
网络股票信息爬虫与可视化
背景分析背景概述在当今快速发展的金融市场中,股票市场的动态变化对投资者和金融分析师至关重要。随着信息技术的进步,特别是互联网和大数据技术的发展,投资者可以实时获得大量的股票市场信息。然而,这些信息通常以原始数据形式存在,需要进一步处理和分析才能提取有价值的洞见。在这种背景下,网络股票信息爬虫与可视化技术应运而生,成为股票市场分析的重要工具。 网络股票信息爬虫网络股票信息爬虫(Web Scraping)是一种自动化的数据收集技术,旨在从互联网上提取股票市场相关的信息。它利用程序化方法访问和抓取各种金融网站和新闻平台上的数据,例如股票价格、交易量、公司财报、新闻动态等。爬虫技术可以高效地从大规模数据源中获取最新的信息,支持实时数据更新和历史数据回溯分析。 关键技术: 爬虫框架:如Scrapy、BeautifulSoup等,用于解析HTML页面和提取数据。 由于本文的目标网站的股票数据并不在页面中,也就是说不需要做网页分析和提取 API接口:一些金融网站提供API接口,允许程序直接获取结构化的数据。 (例如本文使用Get方法的https请求,获取了json文件) 数据存储:抓取的数 ...
【python项目实践】ACVA航空公司客户价值分析
背景分析航空公司现状行业内竞争民航的竞争除了三大航空公司之间的竞争外,还将加入新崛起的各类小型航空公司、民营航空公司,甚至国外航空巨头。航空产品生产过剩,产品同质化特征愈加明显,于是航空公司从价格、服务间的竞争逐渐转向对客户的竞争 行业外竞争随着高铁、动车等铁路运输的兴建,航空公司受到巨大冲击 如上图所示,经过2010到2015年的发展,铁路运输对航空运输的冲击越发明显 航空公司数据特征说明 目前航空公司已经积累了大量的会员档案信息和其乘坐航班记录 就本项目已获取的数据,以2014-03-31为结束时间,选取宽度为两年的时间段作为分析观测窗口,抽取观测窗口内有乘机记录的所有客户的详细数据形成的历史数据,44个特征,总共62988条记录。 数据特征记录说明如下表所示: 结合数据的项目目标结合目前航空公司的数据情况,可以实现以下目标 借助航空公司客户数据,对客户进行分类 对不同的客户类别进行特征分析,比较不同类别客户的客户价值 对不同价值的客户类别提供个性化服务,制定相应的营销策略 了解客户价值分析客户营销战略倡导者Jay & Adam Curry 从国外数百家公司进行 ...
手撕红黑树
红黑树虽然AVL树作为绝对的平衡搜索二叉树,有着极高的查询效率,但正因为其严格的要求,修改AVL树的某个结点时,可能要一路调整到根节点,效率低下。为了解决这一痛点,略微没那么严格的近似平衡搜索二叉树,即红黑树被提出 红黑树的概念红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。 红黑树的性质首先与一般的定义不同,在红黑树中将空指针(上图为NIL)作为叶子节点,然后我们来讨论具体的性质 每个结点不是红色就是黑色 根节点必定是黑色的 如果一个结点是红色的,则它的两个孩子结点是黑色的 对于每个结点,该结点到其所有后代叶结点的简单路径上,均包含相同数目的黑色结点 每个叶子结点都是黑色的此处的叶子结点指的是空结点NIL 思考:为什么满足上面的性质,红黑树就能保证:其最长路径中节点个数不会超过最短路径节点个数的两倍? 红黑树的性质保证了从根节点到所有叶子结点(空结点)的路径上,包含相同数量的黑色结点。这是红黑树平衡性的重要保证 ...
C++继承
继承的概念及定义继承的概念继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的复用都是函数复用,继承是类设计层次的复用 下面用一个简单的示例演示一下继承示例 1234567891011121314151617181920212223242526272829303132333435#include <iostream>#include <string>using namespace std;class Person{public: void Info() { printf("name:%s age:%d\n", _name.c_str(), _age); }protected: string _name = "supdriver"; int _age = 24;};class Student: ...
Linux原生线程 与 互斥锁
什么是线程在一个程序(进程)里的一条执行流就叫做线程(thread),也就是说有多线程功能的进程内,可以有多个线程同时执行 所以我们可以认为: 一个进程至少有一个执行进程 线程在进程内部运行,本质是在进程提供的地址空间内运行 而对于Linux实现的线程,本质上是轻量化的进程,还是用的task_struct去维护的每一个线程 关于线程间内存共享如上图所示,线程之间只有栈区是相互独立的, 像是全局变量,堆区数据都是共享的 线程的优点 创建一个新线程的代价要比创建一个新进程小得多 与进程之间的切换相比,线程之间的切换需要操作系统做的工作要少很多 线程占用的资源要比进程少很多 能充分利用多处理器的可并行数量 在等待慢速I/O操作结束的同时,程序可执行其他的计算任务 计算密集型应用,为了能在多处理器系统上运行,将计算分解到多个线程中实现 I/O密集型应用,为了提高性能,将I/O操作重叠。线程可以同时等待不同的I/O操作。 线程的缺点性能损失一个很少被外部事件阻塞的计算密集型线程往往无法与共它线程共享同一个处理器。如果计算密集型线程的数量比可用的处理器多,那么可能会有较 ...
avatar
副驾supdriver
动物界 脊索动物门 哺乳纲 灵长目 人科 人属 智人种
我github还蛮大的
公告
主域名:
supdriver.top
网站资讯
文章数目 :
107
已运行时间 :
本站总字数 :
337.3k
本站总访问量 :
最后更新时间 :