python进程间通信 - 大大的大笨熊 - 博客园
二、概念:
2、COCO:全称是Common Objects in COntext,是微软团队提供的一个可以用来进行图像识别的数据集。
3、图像识别,是指利用计算机对图像进行处理、分析和理解,以识别各种不同模式的目标和对象的技术,是应用深度学习算法的一种实践应用。
4、图像分割是指将一幅图像分成若干互不重叠的子区域,使得每个子区域具有一定的相似性、而不同子区域有较为明显的差异。
5、物联网(英语:Internet of Things,缩写IoT)是互联网、传统电信网等信息承载体,让所有能行使独立功能的普通物体实现互联互通的网络。
6、RPC:远程方法调用,就是像调用本地方法一样调用远程方法。
7、REST是一种架构风格,指的是一组架构约束条件和原则。
8、语义分割:比如说一幅图中有person、cat、dog三个类。语义分割得出的结果是person、cat、dog这三类别,而实例分割是不仅分类的出person、cat、dog这三类别,还对不同的类别进行细分,其中狗有person1、person2;cat1、cat2、cat3;dog1、dog2、dog3
9、backbone:神经网络模型
10、Detectron是Facebook AI研究院(FAIR)于2018年初公开的目标检测平台,包含了大量业内最具代表性的目标检测、图像分割、关键点检测算法。
11、Maven 是一个项目管理工具,可以对 Java 项目进行构建、依赖管理。
12、OTS以数据表的形式组织数据,保证强一致性,并提供视图和分页的功能来加速查询。用户可以通过RESTful API来使用服务,也可使用WEB 页面对数据进行管理。
oss是以文件的形式存储数据。 用户可以通过简单的REST接口,在任何时间、任何地点上传和下载数据,基于OSS,用户可以搭建出各种多媒体分享网站、网盘、个人企业数据备份等基于大规模数据(文件)进行存储的服务。
13、Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。
14、Habor是由VMWare公司开源的容器镜像仓库。事实上,Habor是在Docker Registry上进行了相应的企业级扩展,从而获得了更加广泛的应用,这些新的企业级特性包括:管理用户界面,基于角色的访问控制 ,AD/LDAP集成以及审计日志等,足以满足基本企业需求。
15、Azkaban是由Linkedin开源的一个批量工作流任务调度器。用于在一个工作流内以一个特定的顺序运行一组工作和流程。Azkaban定义了一种KV文件格式来建立任务之间的依赖关系,并提供一个易于使用的web用户界面维护和跟踪你的工作流。
16、Jenkins是一个开源的、提供友好操作界面的持续集成(CI)工具,起源于Hudson(Hudson是商用的),主要用于持续、自动的构建/测试软件项目、监控外部任务的运行(这个比较抽象,暂且写上,不做解释)。Jenkins用Java语言编写,可在Tomcat等流行的servlet容器中运行,也可独立运行。通常与版本管理工具(SCM)、构建工具结合使用。常用的版本控制工具有SVN、GIT,构建工具有Maven、Ant、Gradle。
17、CI(Continuous integration,中文意思是持续集成)是一种软件开发时间。持续集成强调开发人员提交了新代码之后,立刻进行构建、(单元)测试。根据测试结果,我们可以确定新代码和原有代码能否正确地集成在一起。借用网络图片对CI加以理解。
CD(Continuous Delivery, 中文意思持续交付)是在持续集成的基础上,将集成后的代码部署到更贴近真实运行环境(类生产环境)中。比如,我们完成单元测试后,可以把代码部署到连接数据库的Staging环境中更多的测试。如果代码没有问题,可以继续手动部署到生产环境。下图反应的是CI/CD 的大概工作模式。
18、docker swarm
Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。
20、高可用:(分层)
指的是通过设计减少系统不能提供服务的时间。系统一直可以运行,可用性100%。
高可用保证的原则是“集群化”,或者叫“冗余”:只有一个单点,挂了服务会受影响;如果有冗余备份,挂了还有其他backup能够顶上。
方法论上,高可用是通过冗余+自动故障转移来实现的
部署nginx,会有shadow-nginx(冗余),自动进行故障转移,使用keepalived存活探测,相同virtual IP提供服务。将流量自动迁移到shadow-nginx
nginx会探测
service-connection-pool能够探测到
4>服务层到缓存层
redis天然支持主从同步,redis官方也有sentinel哨兵机制,来做redis的存活性检测,主挂了,会迁移到其他redis
5>服务层到数据库层
1>读层
数据库层都用了“主从同步,读写分离”架构保证高可用。
读库挂了,db-connection-pool探测到
> 写层
当写库挂了的时候,keepalived能够探测到,会自动的进行故障转移,将流量自动迁移到shadow-db-master,由于使用的是相同的virtual IP,这个切换过程对调用方是透明的。
21、分布式(kafka)
集群是个物理形态,分布式是个工作方式。
分布式比如celery 的worker可以监听不同消息队列,部署到不同的机器上去处理,就叫分布式。
比如redis django 就可以分布式缓存
分布式是以缩短单个任务的执行时间来提升效率的,而集群则是通过提高单位时间内执行的任务数来提升效率。
先写操作系统的页缓存(Page Cache),然后由操作系统自行决定何时刷到磁盘。
1>>页缓存是在内存中分配的,所以消息写入的速度很快。
2>>Kafka 不必和底层的文件系统进行交互,所有繁琐的 I/O 操作都由操作系统来处理。
3>>Kafka 采用追加写的方式,避免了磁盘随机写操作。
4>>使用以 sendfile 为代表的零拷贝技术提高了读取数据的效率。
页缓存还有好处:当broker进程崩溃,堆内存数据丢失,页缓存会有,重启可以继续。
概念:比如每秒百万并发的中间件系统、每日百亿请求的网关系统、瞬时每秒几十万请求的秒杀大促系统。
微服务设计
大部分的高并发场景,都是读多写少,数据库和缓存里都写一份,然后读的时候大量走缓存不就得了
出现高并发写的情况,比如一个业务增删改几十次,那就使用mq,排队慢慢写。
那么就将一个数据库拆分为多个库,多个库来扛更高的并发;然后将一个表拆分为多个表,每个表的数据量保持少一点,提高 sql 跑的性能
读写分离,这个就是说大部分时候数据库可能也是读多写少,没必要所有请求都集中在一个库上吧,可以搞个主从架构,主库写入,从库读取,搞一个读写分离。读流量太多的时候,还可以加更多的从库。
es 是分布式的,可以随便扩容
这个就是通过远程接口查询对应的数据,使用map当成临时数据库进行存储,并进行拼接
24、冗余
冗余有两层含义,第一层含义是指多余的不需要的部分,第二层含义是指人为增加重复部分,其目的是用来对原本的单一部分进行备份,以达到增强其安全性的目的,这在信息通信系统当中有着较为广泛的应用。
25、LAN局域网 WAN外网
26、正向代理反向代理
客户端和代理机器同属于一个LAN,属于正向
服务段端和代理机器同属于一个LAN,属于反向
27、mysql 和redis 的区别
mysql是关系型数据库,存放持久化数据,粗放在硬盘中
Redis是nosql,数据放在缓存中
1>创建型模式
工厂模式
单例模式
原型模式
建造者模式
2>结构型模式
装饰器模式
3>行为型模式
迭代器模式
4>J2EE模式
MVC模式
以Partition的形式存放日志由两个好处:
1 方便在集群中扩展,一个topic可以由多个分区组层,每个分区可以放在多个borker上,可以做到适合任意大小的消息量。
2 可以提高并发,消费时是针对consumer消费的,通过增加partation、consumer可以提升性能。
1>工作原理:
Broker:可以多个,直接进行磁盘读写,线性读写,避免了数据在jvm和系统内存之间复制,减少对象创建和垃圾回收耗性能。
1>可以使用自己zk或者搭建zk
2>生产者参数
producer.retries 生产者发送失败,重试的次数
producer.batch.size 批量发送大小 默认是16kB
producer.linger 发送延时 吞吐量低,延时小,相反
producer.buffer.memory 缓存消息的缓冲区的大小,默认32M
producer.request.timeout.ms 返回时间
3>kafka三种容错方式
kafka.producer.acks 0代表只负责发送,不管数据丢失,优势吞吐量高 1代表等待broker的leader partition该消息写入本地日志的确认,无需等待其他followers写入该消息 -1或all代表等待fllowers写入消息完成确认
4>消费端配置
consumer.enable.auto.commit 控制kafka是自动提交偏移量(True)还是手动提交偏移量(False)
注:消费者消费完会记录下标,下次加1位置执行,手动的话加consumer.commitSync();
consumer.auto.commit.interval 自动提交间隔
consumer.auto.offset.reset 定义消费顺序
Earliest 当各分区下有已提交的offset时,从提交的offset开始消费;无提交的offset时,从头开始消费
latest当各分区下有已提交的offset时,从提交的offset开始消费;无提交的offset时,消费新产生的该分区下的数据
none topic各分区都存在已提交的offset时,从offset后开始消费;只要有一个分区不存在已提交的offset,则抛出异常
## 是否在消费消息后将offset同步到zookeeper,当Consumer失败后就能从zookeeper获取最新的offset
auto.commit.enable =true
## 每次重新选举leader的时间
refresh.leader.backoff.ms
连接zookeeper,创建topic、leader和备份的关系等
Kafka出现重复消费和消息丢失解决
重复
设置offset为自动提交,关闭kafka时,如果在close之前,调用 consumer.unsubscribe() 则有可能部分offset没提交,下次重启会重复消费。
丢失
设置offset为自动定时提交,当offset被自动定时提交时,数据还在内存中未处理,此时刚好把线程kill掉,那么offset已经提交,但是数据未处理,导致这部分内存中的数据丢失。
解决方案:首先对kafka进行限速,其次启用重试机制,重试间隔时间设置长一些,最后Kafka设置acks=all。
维护offset
记录offset和恢复offset的方案。理论上记录offset,下一个group consumer可以接着记录的offset位置继续消费。
简单offset记录方案:
每次消费时更新每个topic+partition位置的offset在内存中,
Map
当调用关闭consumer线程时,把上面Map的offset数据记录到 文件中*(分布式集群可能要记录到redis中)。
下一次启动consumer,需要读取上一次的offset信息,方法是 以当前的topic+partition为key,从上次的Map中去寻找offset。
然后使用consumer.seek()方法指定到上次的offset位置。
1.>配置管理
Hbase:客户端连接zk,获取hbase集群配置信息
Kafka:zk来维护kafka的broker信息
Dubbo:zk管理配置实现服务治理
2>名字服务
3>分布式锁 选举机制
4>集群管理
数据入队时,数据量小于10k,redis很快,如果大于10k,很慢,出队事数据大小都很快。
31、
数据挖掘是个很宽泛的概念,数据挖掘常用方法大多来自于机器学习这门学科,深度学习是机器学习一类比较火的算法,本质上还是原来的神经网络。
1>架构上
Mq遵循AMQP协议,rabbitMQ以broker为中心;有消息的确认机制。
mq消息发送确认,
1、ConfirmCallback 生产者到交换器回调spring.rabbitmq.publisher-confirms = true
2、ReturnCallback 交换器到队列回调 spring.rabbitmq.publisher-returns = true
Mq消息接收确认:
kafka遵从一般的MQ结构,以consumer为中心,消息的消费信息保存的客户端consumer上,consumer根据消费的点,从broker上批量pull数据;无消息确认机制。
2>吞吐量
kafka高吞吐量,内部采用消息的批量处理,zero-copy机制,数据的存储和获取是本地磁盘顺序批量操作,具有O(1)的复杂度,消息处理的效率很高。
rabbitMQ在吞吐量方面稍逊于kafka,rabbitMQ支持对消息的可靠的传递,支持事务,不支持批量的操作;基于存储的可靠性的要求存储可以采用内存或者硬盘。
面向对象的程bai序设计,编程语言可du分为面向过程和面向对象两种,zhi
面向过程的有汇编语dao言,c语言 (可理解为这些语言代码是一行一行写的:))。。
面向对象的有c++语言。(其实许多面向对象的语言是混合型语言,即可以面向过程,也可以面向对象)
34、Python和Go之间的区别是什么?
1>、范例
Python是一种基于面向对象编程的多范式,命令式和函数式编程语言。它坚持这样一种观点,即如果一种语言在某些情境中表现出某种特定的方式,理想情况下它应该在所有情境中都有相似的作用。但是,它又不是纯粹的OOP语言,它不支持强封装,这是OOP的主要原则之一。
Go是一种基于并发编程范式的过程编程语言,它与C具有表面相似性。实际上,Go更像是C的更新版本。
2>、类型化
Python是动态类型语言,而Go是一种静态类型语言,它实际上有助于在编译时捕获错误,这可以进一步减少生产后期的严重错误。
3>、并发
Python没有提供内置的并发机制,而Go有内置的并发机制。
4>、安全性
Python是一种强类型语言,它是经过编译的,因此增加了一层安全性。Go具有分配给每个变量的类型,因此,它提供了安全性。但是,如果发生任何错误,用户需要自己运行整个代码。
5>、速度:
Go的速度远远超过Python。
6>、用法
Python更多地用于Web应用程序,它非常适合解决数据科学问题。Go更多地围绕系统编程,即Go更像是一种系统语言。
7>、管理内存
Go允许程序员在很大程度上管理内存。而,Python中的内存管理完全自动化并由Python VM管理;它不允许程序员对内存管理负责。
8>、库
与Go相比,Python提供的库数量要大得多。然而,Go仍然是新的,并且还没有取得很大进展。
9>、语法
Python的语法使用缩进来指示代码块。Go的语法基于打开和关闭括号。
10>、详细程度
为了获得相同的功能,Golang代码通常需要编写比Python代码更多的字符。
三、数据结构和算法
1、贪心算法:
原问题复杂度过高;
求全局最优解的数学模型难以建立;
求全局最优解的计算量过大;
没有太大必要一定要求出全局最优解,“比较优”就可以。
2、列表对头插入和队尾插入
List.insert()队头慢 list.append()队尾快
最优即最理想:[1, 2, 3, 4,5] N
最差:[3,2,2,5,2] N2
List.pop(i) 如果是最后一个O(1), 但是如果是第一个O(N).
5、基本数据类型和高级数据结构
Int\float\string\ list\tuple\dictionary\set
6、内存
一个整数对应4个字节,8位bit。
Char:字符串的一个字符占1个字节。 四个字节00000001, 代表
7、顺序表(存储空间必须连续,如果不够,需要动态改变)
Int = 1, 2, 3
Li = [1, 2, 3] 1对应0*01 2对应0*05 3对应0*09 顺序存放,指针定位
8、顺序表操作
Python的list和tuple就是利用顺序表实现存储,list可以修改,tuple不可以修改。
查询时间复杂度 O(1)
9、顺序表结构和实现
采用加倍扩充,使用空间换时间策略。
10、链表(节点和节点之间通过链连接,前面元素保存后面元素位置)
线性表包括链表和顺序表。(一维的) 二维的是树。
11、单向链表
单向链表也称单链表。每个节点包含两个域,信息域和链接域。这个链接指向链表中的下个节点,最后一个节点指向一个空值。
12、链表和顺序表对比
链表占内存更大,因为链接占内存,但是内存可以是分散的,可以充分利用内存。但是开销大,访问元素链表时间复杂度是O(n), 访问顺序表是O(1).
操作系统内存分散,可以使用链表,如果内存连续大,就使用顺序表。
插入元素的话,链表是遍历,顺序表是搬迁。
都是线性表。顺序表连续,链表离散。
使用场景:
在进行尾插的时候用顺序表,因为相对于链表来说,顺序表进行尾插不需要进行遍历来找到最后一个位置,而链表则需要遍历。这样会影响程序运行的效率。
同样的,在进行头插和中插的时候,顺序表需要将插入位置后面的所有数据都向后挪动一次,而链表只需要创建一个新的节点,然后将节点链入到所要插入的位置,节省了效率。所以在进行头插和中插的时候要使用链表会获得更高的效率。
13、双向链表
14、单项循环列表
15、栈
栈是操作,线性表是存放。 顺序表和链表都可以实现栈。 先进后出。
16、队列
队列是先进先出,一端添加一端去取,可以通过线性表实现。树结构的深度遍历可以通过队列实现,
双端队列
17、排序算法
1>插入排序
2>选择排序算法,从右边无序中找出最小的
时间复杂度都是O(N)
3>冒泡排序
4>快速排序
5>归并排序
6>二分查找
7>希尔排序
19、树
20、前序中序后序
1>前序遍历(先输出当前节点,再左节点和右节点)
ABDGHCEIF
2>中序遍历(先左、中、右)
GDHBAEICF
3>后序(左右中)
GHDBIEFCA
4>前中推导
A是根,其次B,GDHB在左,EICF在右
5>中后推导
后看A根,后看B根,后看D根,后看右C根
20、算法工程师
算法工程师根据研究领域来分主要有音频/视频算法处理、图像技术方面的二维信息算法处理和通信物理层、雷达信号处理、生物医学信号处理等领域的一维信息算法处理。
不同的算法可能用不同的时间、空间或效率来完成同样的任务。一个算法的优劣可以用空间复杂度与时间复杂度来衡量。算法工程师就是利用算法处理事物的人。
21、redis集群一致性hash算法
问题:1、同一份数据可能在多个redis库,冗余
2、随机请求,不一定命中存数据redis
解决:使用hash算法
该模块提供了堆排序算法的实现。堆是二叉树,最大堆中父节点大于或等于两个子节点,最小堆父节点小于或等于两个子节点。
首先,最底层的就是dto层,dto层就是所谓的model,dto中定义的是实体类,也就是.class文件,该文件中包含实体类的属性和对应属性的get、set方法;
其次,是dao层(dao层的文件习惯以*Mapper命名),dao层会调用dto层,dao层中会定义实际使用到的方法,比如增删改查。一般在dao层下还会有个叫做sqlmap的包,该包下有xml文件,文件内容正是根据之前定义的方法而写的SQL语句;
alter user 'root'@'localhost' identified with 5322688 by 'root';
之后,到了service层,service层会调用dao层和dto层,service层也会对数据进行一定的处理,比如条件判断和数据筛选等等;
最后,是controller层,controller层会调用前面三层,controller层一般会和前台的js文件进行数据的交互, controller层是前台数据的接收器,后台处理好的数据也是通过controller层传递到前台显示的。
1>mysql5.5之后默认存储引擎innodb,使用独立表空间形式,之前是MyISAM,使用系统表空间。
2>区别1、添加隐藏索引 2、设置持久化 3、utf8mb4
脏读:一个事务数据未提交,另一个事务访问到这个数据。
隔离级别Mysql 事务隔离级别 - 茶饭不撕 - 博客园
1>把连接放到一个Theard.local的实例中,request请求完成就关闭,如果设置了CONN_MAX_AGE,就会持久连接,有则服用。
2>QuerySet.select_related()和prefetch_related() 一次性取出数据,减少连接
class Province(models.Model):
name = models.CharField(max_length=10)
class City(models.Model):
name = models.CharField(max_length=5)
province = models.ForeignKey(Province)
class Person(models.Model):
firstname = models.CharField(max_length=10)
lastname = models.CharField(max_length=10)
visitation = models.ManyToManyField(City, related_name = "visitor")
hometown = models.ForeignKey(City, related_name = "birth")
living = models.ForeignKey(City, related_name = "citizen")
citys = City.objects.all()
>>> for c in citys:
... print c.province
四次查询
citys = City.objects.select_related().all()
>>> for c in citys:
... print c.province
一次inner_join查询
select_related主要针一对一和多对一关系进行优化。
zhangs = Person.objects.select_related('living__province').get(firstname=u"张",lastname=u"三")
zhangs.living.province
可以通过可变长参数指定需要select_related的字段名。也可以通过使用双下划线“__”连接字段名来实现指定的递归查询。没有指定的字段不会缓存,没有指定的深度不会缓存,如果要访问的话Django会再次进行SQL查询
是通过jion实现
对于多对多字段(ManyToManyField)和一对多字段,可以使用prefetch_related()来进行优化。ForeignKey就是一个多对一的字段,而被ForeignKey关联的字段就是一对多字段了。
分别查询每个表,通过python处理他们之间的关系。
zhangs = Person.objects.prefetch_related('visitation').get(firstname=u"张",lastname=u"三")
for city in zhangs.visitation.all() :
print city
第一条SQL查询仅仅是获取张三的Person对象,第二条比较关键,它选取关系表`QSOptimize_person_visitation`中`person_id`为张三的行,然后和`city`表内联(INNER JOIN 也叫等值连接)得到结果表。
3>加载数据较慢可以放入缓存中。
4>Save()将数据重新写一遍,update()只是对修改的数据保存。
1>在where和order by实际字段建立索引
2>避免使用<> != =null in or like
3>exists 可以代替in
4>索引过多会对update、insert起反作用
5>优先选数字型存储,避免存储额外开销 123
6>尽可能使用varchar,代替char,变长类型节约存储空间,查询快
7>select * from t 尽量不适用*
7、mysql约束与索引(约束是保证数据的完整性,索引是提高查询效率)
1>非空约束 唯一约束 主键约束 外键约束 自增约束 默认约束 检查性约束
2>主键索引 唯一索引 常规索引 全文索引
ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` )
ALTER TABLE `table_name` ADD UNIQUE (`column`)
mysql>ALTER TABLE `table_name` ADD INDEX index_name ( `column` )
ALTER TABLE `table_name` ADD FULLTEXT ( `col
8、视图、存储过程、函数、触发器、事件
1>视图的作用
比如表开启权限,和复杂sql,可以视图
不同点:
(5)create procedure param_pro(in id int , out num int, inout p_sal int)
begin
delete from emp where empno = id ;
select max(sal) from emp into num;
select count(*) into p_sal from emp where sal >P_sal ;
end
set @p_sal = 1250 ;
call param_pro(7369 , @num , @p_sal);
select @num , @p_sal ;
(6)create function fun1(id int) returns int
begin
return (select sal from emp where empno=id);
end //
select fun1(7698)
3>触发器(salary 为 tb_emp6 中新插入的 salary 字段值的 2 倍)
CREATE TRIGGER double_salary
-> AFTER INSERT ON tb_emp6
-> FOR EACH ROW
-> INSERT INTO tb_emp7
-> VALUES (NEW.id,NEW.name,deptId,2*NEW.salary);
4>事件(定时器。一个事件可调用一次,也可周期性的启动)隔5s插入数据
CREATE EVENT IF NOT EXISTS e_test ON SCHEDULE EVERY 5 SECOND
-> ON COMPLETION PRESERVE
-> DO INSERT INTO tb_eventtest(user,createtime)VALUES('MySQL',NOW());
5> 存储过程游标的作用就是用于对查询数据库所返回的记录进行遍历,以便进行相应的操作。
HADOOP的核心组件有:HDFS(分布式文件系统)、YARN(运算资源调度系统)、MAPREDUCE(分布式运算编程框架)
实现了分布式文件系统hdfs。hdfs有高容错性,高吞吐量,最核心:hdfs和mapreduce
1>core-site.xml
配置namenode的主机名和port
2>hdfs-site.xml
dfs.replication 指定了hdfs数据库的复制次数
3>NameNode:是Master节点,是大领导。管理数据块映射;处理客户端的读写请求;配置副本策略;管理HDFS的名称空间;
4>datanode:Slave节点,奴隶,干活的。负责存储client发来的数据块block;执行数据块的读写操作。
5>Secondary NameNode的整个目的是在HDFS中提供一个检查点。
namenode存放元数据(描述数据信息),可以持久化到磁盘,但是启动很麻烦,secondary namenode定期检查edit log,是否有变化,把变化更新到fsimage中。
6>Yarn的组件主要包括:
ResourceManager : 资源管理
Application Master : 任务调度
NodeManager : 节点管理,负责执行任务
Yarn的工作流程如下图所示:
Hive中的表是纯逻辑表,就只是表的定义等,即表的元数据。Hive本身不存储数据,它完全依赖HDFS和MapReduce。这样就可以将结构化的数据文件映射为为一张数据库表,并提供完整的SQL查询功能,并将SQL语句最终转换为MapReduce任务进行运行。 而HBase表是物理表,适合存放非结构化的数据。用mysql存储元数据。
HBase的数据通常存储在HDFS上。HDFS为HBase提供了高可靠性的底层存储支持。
Hbase是Hadoop database即Hadoop数据库。它是一个适合于非结构化数据存储的数据库,HBase基于列的而不是基于行的模式。
HBase是Google Bigtable的开源实现,类似Google Bigtable利用GFS作为其文件存储系统,HBase利用Hadoop HDFS作为其文件存储系统;Google运行MapReduce来处理Bigtable中的海量数据,HBase同样利用Hadoop MapReduce来处理HBase中的海量数据。
HDFS为HBase提供了高可靠性的底层存储支持,Hadoop MapReduce为HBase提供了高性能的计算能力,Zookeeper为HBase提供了稳定服务和failover机制。Pig和Hive还为HBase提供了高层语言支持,使得在HBase上进行数据统计处理变的非常简单。 Sqoop则为HBase提供了方便的RDBMS(关系型数据库)数据导入功能,使得传统数据库数据向HBase中迁移变的非常方便。
支持事务的提交和回滚,支持外键,支持并发处理和崩溃恢复
插入数据块,空间和内存使用低。如果考虑高效率和低并发,可以选择
数据在内存中,安全性低,读写速度快,不能建立大表
Mongodb是非关系型数据库(nosql ),属于文档型数据库。文档是mongoDB中数据的基本单元,类似关系数据库的行,多个键值对有序地放置在一起便是文档,语法有点类似javascript面向对象的查询语言,它是一个面向集合的,模式自由的文档型数据库。
可以存储图片
1、Json.dumps/loads处理的是字符串
Json.dump/load处理的是文件
2、删除字典键、合并字典
3、解决pythonGIL锁的办法
1>. 使用多进程执行,此将要面临解决共享数据的问题,多用queue或pipe解决;
pipe是管道但是不是很推荐使用,因为有着不安全的危险,queue就相当于pipe加上lock,比较安全,但是的注意他们的close的时间,详见python3中的day38的笔记
Value、Array是通过共享内存的方式共享数据
Manager是通过共享进程的方式共享数据。
2>. 使用Python多线程load C的module执行。(或者java)
gcc xxx.c -shared -o libxxxx.so
3>、python IO密集型可以考虑多线程,计算密集型考虑多进程。
4、fun(*args,**kwargs)
5、python2和python3的range()区别
python2返回列表,python3返回迭代器,节约内存
6、函数可以作为参数传递的语言,可以使用装饰器
7、HTTP1.1额外请求方式 PATCH是局部更新(可以只是更新某个字段)
HEAD类似于GET,只不过返回没有具体内容,用于获取报头
OPTIONS 允许客户端查看服务端性能
8、单例模式
class SingleIns():
def __init__(self, name):
self.name = name
def __new__(cls, *args, **kwargs):
_instance = None
if _instance is None:
_instance = object.__new__(cls)
return _instance
9、with方法帮我们实现了finally中f.close
10、map, reduce Python的lambda表达式、filter、map、reduce等函数的用法 - gdjlc - 博客园
list2 = filter(lambda x:x%2==0, [1,2,3,4,5,6])print(list(list2)) #输出:[2, 4, 6]
#用lambda改写上面语句
list1_1 = map(lambda x : x*2, [1,2,3,4,5])print(list(list1_1)) #输出:[2, 4, 6, 8, 10]
print(reduce(lambda x,y:x+y,[1, 2, 3, 4, 5], 10))#输出:25
11、正则
1>match是从开始位置匹配,返回第一个匹配对象
import re
ret = re.match("hello","hello word")
print(ret.group()) # 使用group()方式返回对应的分组
2>search从字符串任意位置匹配
lst = "\d{2,4}" #贪婪匹配
ret = re.search(lst,"12345abcd")
print(ret.group()) 结果: >>>1234
lst = "\d{2,4}?" #惰性匹配
ret = re.search(lst,"12345abcd")
print(ret.group()) 结果: >>>12
3>findall
ret=re.fildall('\d+','hello123,word456')
print(ret)
结果: >>>['123','456']
4>sub替换
strs = 'abcd123efg345hi'
ret = re.sub(r'\d+','HELLO',strs)
print(ret) >>>abcdHELLOefgHELLOhi
5>匹配手机号
1[3-9]\d{9} 16619932058
任意整数 [1-9]\d* 123
6>符号
? 0或者1次
+ 1到无限次
* 0到不限
\d 0-9数值
\w 数字字母下划线中文
\s 空格、回车、tab
\D 匹配数字
. 换行符以外任意字符
(ab) 将括号中字符作为一个分组
12、assert断言
14、distinct sql消除重复
15、python数据类型和结构
数据类型:int、float、bool、complex、str、tuple、list、dict、set
不可变数据类型(可哈希):int、float、bool、complex、str、tuple
可变数据类型(不可哈希):list、dict、set
数据结构:tuple、list、dict、set
16、sort \sorted
Sort对列表自身排序,sorted返回一个新列表
Dict = {} flase 从小到大
Ss = sorted(dict.items, key=lambda i:i[0], resverse=flase)
# foo = [3, 2, 4, -2, -4, -2, -1] 整数从小到大负数从大到小
A = sorted(foo, lambda x:(x<0,abs(x)))
17、lambda
Sum = lambda a, b:a+b
Sum(1, 2)
18、正则匹配
小数: 50.234 \d+\.?\d*
1>__call__
把类变成可调用对象。
Class Person():
Def __init__(name):
Self.name = name
Def __call__():
Print(’fdsfds‘)
Return self.name = ‘shuju’
_list1 = [[1,2],[3,4],[5,6]]
# ss = [j for i in _list1 for j in i]
import numpy
ss = numpy.array(_list1).flatten().tolist()
print(ss)
[1, 2, 3, 4, 5, 6]
a = [1, 2, 3]
b = 'abc'
ss = zip(a, b)
1>使用生成器,节约内存
协程是一中多任务实现方式,它不需要多个进程或线程就可以实现多任务。
yield能实现协程,不过实现过程不易于理解,greenlet是在这方面做了改进,通过switch。
greenlet可以实现协程,不过每一次都要人为的去指向下一个该执行的协程,显得太过麻烦。
python还有一个比greenlet更强大的并且能够自动切换任务的模块gevent,gevent每次遇到io操作,需要耗时等待时,会自动跳到下一个协程继续执行
迭代器: 有next方法为迭代器,range只是迭代对象,没有next方法。
生成器: 可以实现多任务,协程
ijson迭代器 内存,不会把所有json都都加载进来
2>循环代码优化,避免过多重复代码的执行
3>核心模块用Cython PyPy等,提高效率,这两个都是解释器,在解释器基础上开发。
使用Cpython:深入Cpython (编写一个Cpython 模块) - 码农教程
Pypy解释器没有第三方包。
4>多个if elif条件判断,可以把最有可能先发生的条件放到前面写,这样可以减少程序判断的次数,提高效率
5>多进程、多线程、协程
asycio 需要自己在代码中让出CPU,控制权在自己手上
gevent 用会替换标准库,你以为调用的是标准库的方法实际已经被替换成gevent自己的实现,遇到阻塞调用,gevent会自动让出CPU
像不像手动挡和自动挡的区别·····
优点:
调用内函数,过后消亡,但是闭包变量只有一份
回调函数是一个参数,将函数作为参数传给另一个函数,执行参数函数,就叫回调,主函数的事先干完,回头再调用传进来的参数。
def aa(call_func):
call_func()
print('结束')
def bb():
print('回调函数')
aa(bb)
1>对于不可变类型任何拷贝的内容和地址都不变
2>Deepcopy对于可变类型 list = [1, 2, [3, 4]]
Copy.copy list外层地址改变,内层不变
Copy.deepcopy 内外层地址都变
1>__str__
print类对象,就会打印return的数据
2>__del__ Python __del__()方法:销毁对象
删除对象执行的方法
3>一般来说__str__的可读性更强,而__repr__的返回结果更具有准确性,更加的适合开发者
对象调用就走__repr__,
4>__new__单例模式
比如建立数据库连接,为了减少内存占用,使用单利
1>内存管理
python提供了对象池,放一些常用单词,用取出不用放回,速度快,不常用的需要创建
内存分配器:
2>垃圾回收机制
采用自动引用计数的方式。每个对象都有计数器,如果变量引用该对象,计数器加1,取消则减1,如果为0,自动调用__del__回收。
以标记-清除来解决对象产生循环引用造成无法回收的问题;
标记清除算法作为Python的辅助垃圾收集技术,主要处理的是一些容器对象,比如list、dict、tuple等,因为对于字符串、数值对象是不可能造成循环引用问题。
缺点:需要扫描整个堆内存,哪怕只有一小部分未活动
分代回收是建立在标记清除技术基础之上的,是一种以空间换时间的操作方式。
Python 将内存分为3代,年轻代、中年代、老年代,是3个链表,年轻代满了,触发回收机制,把可以回收的回收,不可以回收的移到中年代,老年代是存活最久的。
1>app_name存在的意义
不同的应用存在相同的url,为了避免使用reverse()方法出现反向解析错误
namespace存在的意义
一个项目可以创建多个url映射到一个app中,那么如何让app的reverse()区分到底是哪个url访问它呢
有namespace必须有app_name,反之不成立
2>多对多、一对多
Django中多对多查询方式_Allen_by的博客-CSDN博客_django多对多查询
保证硬件没问题
1、更换ip。 在DNS上设置IP轮询实时进行监控 具备网站宕机监测功能
2、更换web服务器
3、重启服务进程
悲观锁, 就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。
乐观锁,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制,乐观锁适用于多读的应用类型,这样可以提高吞吐量
def singleton(cls):
_instanse = {}
def wrapper(x):
if cls in _instanse:
return _instanse[cls]
else:
_instanse[cls] = cls(x)
return _instanse[cls]
return wrapper
@singleton
class A:
def __init__(self, x=0):
self.x = x
# 单例类
class SingleIns():
def __init__(self, name):
self.name = name
def __new__(cls, *args, **kwargs):
_instance = None
if _instance is None:
_instance = object.__new__(cls)
return _instance
MRO 就是用来处理这种问题的。它有三个原则:
原因:数据库的django_migrations 表中的迁移版本记录和代码中的迁移脚本不一致导致的。
常见错误示例:
table xx already exist
python manage.py migrate --fake appname
--fake (由于人工操作,migration与实际table不一致,--fale 不会执行sql操作,只是对migration做标记,生成django_migrations表的内容。 重新一致。)
对于有数据的表,想保留数据,并且migrations一致,很重要
先写dockerfile ,在dockerfile统计目录再构建镜像
docker build -t='django_1.11.9' .
可以将镜像保存到仓库
# 运行容器
docker run -di --name=mydjango -p 8080:8080 -v /home/myproject:/home django_1.11.9
1>limit y 分句表示: 读取 y 条数据
limit x, y 分句表示: 跳过 x 条数据,读取 y 条数据
limit y offset x 分句表示: 跳过 x 条数据,读取 y 条数据
HAVING SUM(access_log.count) > 200;
MID() 函数用于从文本字段中提取字符。
SELECT MID(column_name,start[,length]) FROM table_name;
1>如果属性的名字以两个下划线开始,就表示为私有属性,没有下划线开始的表示公有属性。
六、真题
1、求三个方法打印结果
fn("one",1)直接将键值对传给字典;
fn("two",2)因为字典在内存中是可变数据类型,所以指向同一个地址,传了新的额参数后,会相当于给字典增加键值对
fn("three",3,{})因为传了一个新字典,所以不再是原先默认参数的字典
2、
Leedcode
inincode