【python项目实践】ACVA航空公司客户价值分析
背景分析航空公司现状行业内竞争民航的竞争除了三大航空公司之间的竞争外,还将加入新崛起的各类小型航空公司、民营航空公司,甚至国外航空巨头。航空产品生产过剩,产品同质化特征愈加明显,于是航空公司从价格、服务间的竞争逐渐转向对客户的竞争
行业外竞争随着高铁、动车等铁路运输的兴建,航空公司受到巨大冲击
如上图所示,经过2010到2015年的发展,铁路运输对航空运输的冲击越发明显
航空公司数据特征说明
目前航空公司已经积累了大量的会员档案信息和其乘坐航班记录
就本项目已获取的数据,以2014-03-31为结束时间,选取宽度为两年的时间段作为分析观测窗口,抽取观测窗口内有乘机记录的所有客户的详细数据形成的历史数据,44个特征,总共62988条记录。
数据特征记录说明如下表所示:
结合数据的项目目标结合目前航空公司的数据情况,可以实现以下目标
借助航空公司客户数据,对客户进行分类
对不同的客户类别进行特征分析,比较不同类别客户的客户价值
对不同价值的客户类别提供个性化服务,制定相应的营销策略
了解客户价值分析客户营销战略倡导者Jay & Adam Curry 从国外数百家公司进行 ...
手撕红黑树(由AVL树爆改)
红黑树虽然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操作。
线程的缺点性能损失一个很少被外部事件阻塞的计算密集型线程往往无法与共它线程共享同一个处理器。如果计算密集型线程的数量比可用的处理器多,那么可能会有较 ...
Ssystem V 共享内存
共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据,而是直接使用内存中的共享区。
我们接下来认识一下常用的接口
接口shmget 创建共享内存需要同时引入<sys/ipc.h> <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
key 是生成共享内存标示符的 关键字,唯一的key值能返回唯一的共享内存标示符,这是获得同一个共享内存的关键参数
size是指共享内存的大小,按字节算
shmflg是一个位图,控制创建时的行为和 共享内存文件的权限(缺省时为0),常见选项如下
IPC_CREAT:单独一个时,如果申请的共享内存不存在,就创建,然后返回;若存在,则获取并返回
IPC_CREAT | IPC_EXCL: 如果申请的共享内存不存在,则创建;若存在,则出错并返回-1
IPC_EXCL:不能单独使用
IPC_CREAT | 0666:创建一个权限为0666的共享内存文件,注: ...
Linux日志系统
引入首先看看AI对日志系统的重要性是怎么解释的
日志系统在软件开发和运维中扮演着至关重要的角色,主要体现在以下几个方面:
问题排查和调试:日志记录了系统运行过程中的重要信息,包括错误信息、异常堆栈、接口调用信息等。开发人员可以通过分析日志快速定位问题,减少排查时间,提高开发效率。
性能监控:通过记录应用程序的性能指标(如响应时间、请求吞吐量等),开发团队可以监控系统的健康状态,发现性能瓶颈并进行优化。
安全审计:日志可以记录用户的操作和系统事件,为后期的安全审计提供依据。一旦发生安全事件,通过分析日志可以追踪到攻击来源和攻击方式。
用户行为分析:通过对日志进行分析,开发团队可以了解用户的使用习惯和需求,这有助于改进产品功能和用户体验。
合规要求:在许多行业中,日志记录是合规的要求之一。维护完整的日志记录可以帮助企业满足法律法规和行业标准。
系统健康监控:通过实时监控日志,可以及时发现系统异常,进行预警和自动化处理,从而提高系统的可用性和稳定性。
故障恢复:在系统出现故障时,日志记录可以帮助开发和运维人员还原问题发生前的状态,从而有助于快速恢复系统。
总之,良好的日志系统能够帮助开发和 ...
手撕AVL树
AVL树的概念二叉搜索树的不足二叉搜索树虽可以缩短查找的效率,但如果数据有序或接近有序二叉搜索树将退化为单支树,查找元素相当于在顺序表中搜索元素,效率低下。
AVL树的提出两位俄罗斯的数学家G.M.Adelson-Velskii和E.M.Landis在1962年发明了一种解决上述问题的方法:当向二叉搜索树中插入新结点后,如果能保证每个结点的左右子树高度之差的绝对值不超过1(需要对树中的结点进行调整),即构建一颗绝对的平衡搜索二叉树,即可降低树的高度,从而减少平均搜索长度。
定义: 一棵AVL树或者是空树,或者是具有以下性质的二叉搜索树:
它的左右子树都是AVL树
左右子树高度之差(简称平衡因子)的绝对值不超过1(-1/0/1)
如果一棵二叉搜索树是高度平衡的,它就是AVL树。如果它有n个结点,其高度可保持在O(log_2 n),搜索的时间复杂度O(log_2 n)
封装AVL树头文件12#include <utility>#include <cassert>
封装AVL树的节点
这里采用键值(KV)类型的二叉树节点,使其泛用性更高
...
进程间通信
本篇博客更偏向于总括和导航,部分概念更细致的介绍将内嵌链接在文章中
重点内容
初识进程间通信
管道
消息队列
共享内存
信号量
进程间通信的目的
数据传输: 一个进程需要将它的数据发送给另一个进程
资源共享: 多个进程之间共享同样的资源
通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如子进程终止时要通知父进程)
进程控制: 有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变
进程间通信的主要方式
管道
System V进程间通信
POSIX进程间通信
进程间通信的分类管道
匿名管道
命名管道
System V IPC
System V 消息队列
SysTem V 共享内存
System V 信号量
POSIX IPC
消息队列
共享内存
信号量
互斥量
条件变量
读写锁
管道怎么使用?戳我去管道博客🔗
首先,管道是Unix中最古老的进程间通信的形式。它用于进程间的单向通信
那么具体是怎样实现的呢?从标题里就可以发现,是基于文件
既然一个文件可以被多个进 ...