python常用数据类型 6种
不可变数据类型: 数值, 字符串, 元组
可变数据类型: 列表, 字典, 集合
元组:
可以存储数值,字符串,元组,列表,字典,集合6种数据类型,
元组是有序的,元素可以重复,
元组不支持修改,仅支持查询,但可以使用del删除元组对象。 若存储的元素要是可变数据类型,则可以进行对应操作。比如列表,就可以对其进行增删改查。
定义:a = (1,2,2,3,[11,22])
操作:
a[4].append(33)
del a
列表:
可以存储6种数据类型的数据,
列表是有序的
支持增删改查
操作:
a = [1,2,3]
a.append(4) # 末尾添加
a,insert(2, 5) # 指定下标处 插入
a.pop() # 弹出最后一个元素
a.pop(2) # 弹出指定下标元素
a[0] = 7# 修改
a.remove(3) # 删除指定元素,多个时删除第一个匹配的
a.extend(b) # 合并列表
字典:
key: 必须是不可变数据类型, (数值, 字符串, 元组),不可重复
值:可以存储6种基本数据类型的数据
默认字段是无序的, 使用from collections import Orderdict 可以定义有序字典
a = {"name": [1,2,3]}
a["age"] = 12
del a["age]
集合:
集合只能存储不可变数据类型的数据
内部数据没有重复的。
集合是无序列的
可以对两个集合操作:
交集(&),
并集(|),
异或即去掉公共部分(^),
差集(-),
判读子集(set1.issubset(set2) set1是set2的子集 set1.issuperset(set2) set1是set2的的父集 返回布尔值 )
a = {1,2,3,"aa"}
a.add([11,22],(1,2,3))
a.remove(1) # 不存在 会报错
a.discard("addr")# 不存在 不会报错
参数:
位置参数,
默认参数;
关键字参数:key_val形式
可变参数 *arge 和**kwargs *arge包裹以元组形式存储的参数, **kwars中包裹以字典形式存储的参数
可变类型数据,引用传毒
不可变类型数据:值传递
类方法, 实例方法, 静态方法
类方法:使用装饰器@classmethod, 第一个参数形参”cls“ 表示当前类对象, 用来传递类属性和方法 类和实例对象都能调用
实例方法:第一个参数是self, 表示实例对象, 用来传递实例的属性和方法, 只能由实例对象调用
静态方法:使用装饰器@staticmethod, 参数随意, 没有cls 和self参数。 但是方法体中不能使用类或实例的任何属性和方法。类和实例对象都可以调用。
hash冲突解决: 开放寻址法 拉链法----已解决
开放寻址法:如果哈希函数返回的位置已经有值,则可以向后探查新的位置来存储这个值
线性探查:如果位置i被占用,则探查i+1,i+2,......
二次探查:如果位置i被占用,则探查i+1^2, i-1^2, i+2^2, i-2^2......
二度哈希:有多个哈希函数,当使用第1个哈希函数h1发生冲突时,则尝试使用h2,h3
拉链法:哈希表每个位置都连接一个链表,当冲突发生时,冲突的元素将被加到该位置链表的最后
redis的数据结构:
字符串,一个key对应一个字符串, 底层是 简单动态字符串, 包括已占用空间,剩余空间和数据空间, 在返回产犊时 时间复杂度为O(1), 存储数据时,先判断有无可用空间。
列表:一个key对用一个字符串列表,底层使用双向链表实现。
哈希:hash结构体 类似于python的字段 key-val存储。
集合:使用intset或字典实现, 当数据全是数值,且数量小于512个时,使用intset, 是一个有序集合; 其他情况使用字典,将value设置为NUll, 处理hash冲突使用拉链法。
有序集合:有序集合每个元素包含数据本身和一个对应和的分数(score),数据结构:字典+跳表。跳表-> 有序单链表。
redis持久化: RDB快照和AOF
DRB: 周期性的遍历数据,将其以二进制格式,存入RDB文件。通过fork一个子进程完成。
周期持久化策略:三种。
1. save 900 1
2. sav2 300 10
3. save 60 10000 60秒内有10000个写入
AOF: 将执行的每一次写命令,以类似于mysql二进制文件binlog形式,写入AOF文件,
随着命令记录的写入,AOF文件会越来越大,会对其进行压缩,会有重写AOF操作。 AOF重写时,有新的写命令时,会追加到aof_rewrite_buf缓冲区中, 待重写完成后,将其追加到最后,最后替换原AOF文件。
AOF同步策略:
参数appendfsync指定同步策略:always每个事件周期都同步一次, everysec每秒同步刷新, no操作系统决定写入的时机。
redis缓存 穿透, 雪崩,击穿
穿透:
解释:请求的key在缓存中不存在,去后端持久化层查找,导致后端过载,甚至宕机。
解决:
1. 缓存空对象。没有命中时, set(key,null)
2.布隆过滤器。在访问缓存层和存储曾之前,将存在的key用布隆过滤器提前保存起来,做第一层拦截,存在则进入缓存层和存储层。(一句话:检索一个元素是否在一个集合中)
雪崩:缓存层宕机或大量缓存由于超时时间相同在同一时间失效,大量请求直接达到存储层,存储层压力过大导致崩溃。
解决:
1. 缓存层设计为高可用,RedisCluster集群部署
2. 多级缓存,本地一级缓存, redis二级缓存, 设置超时时间不同,岔开
3. 缓存过期时间使用随机值,尽量避免大量key过期时间相同。
击穿:热点key 在缓存失效的瞬间,大量线程来重建缓存,导致后端负载过大,
解决:
1.使用分布式互斥锁。只允许一个线程重建缓存,其他线程等待重建完成后重新获取数据即可。
2. 热点key设置永不过期
redis分布式锁的实现,setnx: 原理:因为Rediskey必须保证是唯一的,只要谁能够创建成功谁就能够获取锁 zookeeper创建的是临时节点,临时节点也是唯一的。
redis主从复制:缺点:主宕机了,写服务就不可用了, 引入集群模式。
从服务器指向主服务器的ip和端口
一旦主服务器有任何写操作,都会有快照记录
当快照发生变化时, 主服务器通知下面所有的从服务器,更新数据
redis集群模式:
哨兵模式:
Master的故障发现:单个哨兵会向主的master节点发送ping的命令,如果master节点没有及时的响应,哨兵会认为该master节点为“主观不可用状态”会发送给其他都哨兵确认该Master节点是否不可用,
当前确认的哨兵节点数>=quorum(可配置),会实现重新选举。
redisCluster模式
迭代器 :
迭代是访问集合元素的一种方式。
可迭代对象:以直接作用于for循环的对象统称为可迭代对象:Iterable。可以使用isinstance()判断一个对象是否是可迭代对象(Iterable)
迭代器:迭代器是一个可以记住遍历位置的对象,可以被next()函数调用并不断返回下一个值。 迭代器只能往前不能后退。, 有两个基本的方法 iter()和next
可以使用iter()函数获取可迭代对象的迭代器
生成器:
在python中,一边循环一边计算的机制,称为生成器:generator. 生成器的两种方法 __next__()和send()方法,生成器只能遍历一次。
生成器函数:常规函数定义,但是使用yield语句而不是return语句返回结果。yield语句每次返回一个结果,但每个结果中间,挂起函数的状态,以便下次从它离开的地方继续执行
闭包 :
外部函数中又定义了一个内部函数,且内部函数使用了外部函数的局部变量,最后返回内部函数的引用。成为闭包
装饰器:
装饰器是一个闭包,可以在不修改原函数功能的情况下,增加一些额外的功能, 一般使用语法糖@表示,多个装饰器作用域同一函数时,从上到下依次执行。 应用(异常捕获, 重试机制)
设计模式:
单例模式: 一个类只有一个实例,且由他自己实现,并对外提供唯一访问点。有饿汉式和懒汉式
饿汉式: 在函数加载时就进行实例化。线程安全的
懒汉式: 将实例化延迟,可以通过get_instance方法去实例化, 线程非安全, 安全的懒汉式,需要增加互斥锁。
工厂模式:定义一个创建对象的接口,让其子类决定实例化哪一个工厂类, 使实例化的过程延迟到子类进行
抽象工厂模式:提供一个创建一系列或相互依赖对象的接口,而无需指定他们具体的类, 每个生成的工厂都能按照工厂模型提供对象, 简而言之就是工厂的工厂
策略模式:定义一系列的算法,把他们一个个封装起来,并且使他们可以相互替换。
结构:客户端 策略接口,具体策略
主要技术:使用装饰器@property将策略接口类中的方法变为属性,以及使用装饰器@方法名.setter来动态的修改属性,已达到在客户端动态改变策略的目的
Nginx+ lvs+keepalived
Nginx七层负载均衡
nginx的负载均衡策略:轮询, 加权轮询, ip_hash, url_hash
lvs 四层负载均衡 VRRP(虚拟路由冗余协议)
三种模型:
NAT模型:在服务器中修改目标ip达到转发目的,返回的请求重新到代理服务器,由代理服务器将数据返回给请求端。压力较大
UN模型:在代理服务器中通过增加一层ip层,达到转发。 解析请求后,进行响应,修改源ip为VIP,目标IP为CIP 通过真实服务的io接口的etho网卡 将数据响应给请求端。
DR模型:通过在代理服务器中修改MAC地址达到转发目的,真实服务器收到请求,解析发现mac地址时自己的,处理请求,完成后通过RS的i接口的etho网卡,将数据响应给请求端,mac寻址也是统一网络中寻址的方法。但代理服务器合真实服务器(RS)必须在同一网络中
8种调度算法:轮询,加权轮询,最少链接,加权最少链接,源地址散列调度算法, 目标地址散列调度算法。(基于局部的最少连接调度算法, 复杂的基于局部最少连接调度算法)
mysql三范式 事务,索引 数据结构 索引分类 索引优化
三范式:
1NF: 强调列的原子性, 即不能再分为其他几列(比如地址, 需拆分为国籍,省,区)
2NF: 在1NF的基础上, 另外包含两部分内容, 1. 表必须有一个主键, 2,没有包含在主键种的列必须完全依赖于主键,而不能只依赖主键的一部分
3NF: 在2NF的基础上, 非主键列要直接依赖于主键,不能存在依赖传递。
mysql事务 事务的特性ACID(原子性, 一致性, 隔离性, 持久性)
事务:事务是应用程序种一系列严密的操作,所有操作必须全部成功,否则每个操作中所作的所有更改都会被撤销。
原子性:所有操作必须全部成功,否则每个操作中所作的所有更改都会被撤销。
一致性:事务执行的结果必须使数据库从一个一致性状态变到另一个一致性状态。
隔离性:事务的执行不能相互干扰
持久性:一个事务一旦提交,它对数据库中的数据改变就应该是永久的。接下来的其他操作或故障不应该对其执行结果有任何影响。
事务的隔离级别4种:
未提交读 问题:脏读 问题原因:读取到其他事务 未提交的数据
已提交读 问题:不可重复读, 同一事务多次读取,可能会读取到不同的结果 问题原因:多次读取中 其他事务对该数据做了修改 且已提交。 解决:加锁 读,行级共享锁, 写,行级排他锁
可重复读: 问题:幻读 事务在之后读物同一数据 与其启动时第一次读取的数据一致, 实现原理:读取,共享锁 直到事务结束 写 排他锁 直到事务结束释放。
序列化:将事务排序,原理,每个读的数据行上加上共享锁。
进程 线程 协程
进程是资源分配的最小单位, 多进程:切换需要系统开销, 适合计算密集型任务。
线程是cpu调度的最小单位 多线程,适合I/O密集型任务
协程:一种用户级的轻量级线程,协程拥有自己的寄存器上下文和栈,协作式的多任务,在一个线程内,无需切换, 只是用户控制执行。 可以用yeild实现协程, 高级用法,使用yeild from一个生成器 可以指定切换的另一个局部任务。
一个进程中可以有多个线程, 这些线程共享进程中的系统资源, 除了cpu为其分配的寄存器和栈空间。
GIL:
全局解释器锁: 在python中 多进程其实是并行的而不是并发的。 一个进程中有一个全局解释器锁, 只有获得锁的线程才能运行其任务。 多线程适合I/O密集型任务, 因为线程在执行I/O操作时会释放GIL. 一般采用多进程+协程方式。
线程安全
进程安全
进程池 from multiprocessing import Pool
线程池
垃圾回收机制(GC):
引入计数为主,标记清理和分代回收为辅。
引用计数:在对象被创建的时候,同时创建该对象的计数器, 对象被创建,引用或加入list等容器时,引用计数+1. 当对象超出作用域,引用被重新赋值时,引用计数-1. 当一个对象的引用计数为0时,就会被回收。 但是如果存在两个对象相互引用时,引用计数都为1,此时不会被回收,需要使用标记清理的方式进行垃圾回收。
标记清理:以对象为节点,以引用为边,构成一个有向图, 从根对象出发,可以被访问的对象,标记为活跃对象,遍历访问完成后,未被标记为活跃对象的对象,就会被回收。 但是每次都遍历一边所有对象,比较耗时。所以就引入了分代回收机制。
分代回收:将对象按照存活时间分为不同的“代”,“代”可以理解为一种对象集合, 新创建的对象一般都会被放在第0代中, 久一点的放在第1代中 最久的放在第2代中。 第0代中的对象被遍历的间隔时间较短,遍历一遍后,会将存活时间久一点的对象,放在第1代中,依次类推。 一般第2代被遍历则第1代会被触发遍历, 第1代遍历则第0代会被触发遍历, 三者遍历的触发机制不同,按照存活比例计算(700, 10, 10)
I/O模型 select poll epoll
在网络环境下I/O分为两部分:
1.等待:等待数据准备好,也就是到达内核的某个缓冲区
2.复制;将数据从内核缓冲区,复制到应用程序缓冲区
同步/异步:关注的是消息通知机制,调用后能否向后执行。
同步:等待对方返回消息
异步: 被调用者通过状态通知或者回调机制通知调用者,被调用者的运行状态。
阻塞/非阻塞:关注的是调用者在等待结果返回之前所处的状态。
阻塞:blocking 调用结果返回之前,调用者被挂起(只针对同步) 第一步和第二部都是阻塞的
非阻塞:noblocking调用结果返回之前,调用者不会被挂起 第一步是非组阻塞的,但第二步是阻塞的。
同步I/O:
阻塞I/O: 第一步和第二部都阻塞
非阻塞I/O: 第一步不阻塞, 第二步阻塞。
s = socket(AF_INET, SOCK_STREAM)
s.setblocking(False)
信号驱动I/O,
先建立一个SIGIO信号处理程序,数据准备好后,通过信号处理程序通知应用程序。
I/O复用:阻塞I/O和非阻塞I/O, 应该程序都是阻塞在recvfrom系统调用上, 而I/O复用将阻塞状态转移到上一层, 如select.poll或epoll等。 可以同时监听多个文件描述符,高并发时很有优势,
实现I/O多路复用的机制:
select() 最多监控1024个I/O, 会过滤没有数据的socket.
poll没有监控数量限制,select和poll 必须遍历所有socket, 筛选效率比较低
epoll,套接字有数据了就主动通知调用者处理,通过回调机制实现效率提升。
异步I/O:
异步I/O
组合:
同步阻塞
同步非阻塞
异步非阻塞
11
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 【壹】 “每天早上醒来,你和阳光都在,就是我想要的未来。”年少的时候,这是对爱情最美的憧憬,清晰而美好。 长大后,...
- 呵呵·今天光棍节属于我的节日··开心抑或是不开心? 我也不清楚 好像自己很少写日志 每天都会有很多的心情 很多的话...
- 我与她,只见过几次面,但我从她身上却闻到了一种我特别喜欢的味道———书香味。 我想到了元代王冕的《墨梅》...
- 文/李现风 如果说班级文化的建设,能营造良好的环境氛围,能通过文化环境熏陶人、感染人,从而自觉让孩子们在环境...