博客地址:https://ask.hellobi.com/blog/zhiji 欢迎大家来交流学习。
十一小长长长长长长长长假还有一天,
然而,
你不愿再冲进拥挤的人潮,
不愿再涌向苦等的队伍,
不愿再成为那个躺在床上
观看别人朋友圈的人。
或许,
我可以将你的焦虑、你的不安、你的无聊,
统统划掉!并且还将带给你一大波(python)豪(基)礼(础),
对,你没看错!快来手把手跟我复习Python基础。
本文偏理论,想到哪里就写到哪里,没有头绪-,- 各位看官将就着看。
一、python是什么?
- Python是一种解释型语言。这就是说,与C语言和C的衍生语言不同,Python代码在运行之前不需要编译。其他解释型语言还包括PHP和Ruby。
- Python是动态类型语言,指的是你在声明变量时,不需要说明变量的类型。你可以直接编写类似x=111和x="I'm a string"这样的代码,程序不会报错。
- Python非常适合面向对象的编程(OOP),因为它支持通过组合(composition)与继承(inheritance)的方式定义类(class)。Python中没有访问说明符(access specifier,类似C++中的public和private),这么设计的依据是“大家都是成年人了”。
- 在Python语言中,函数是第一类对象(first-class objects)。这指的是它们可以被指定给变量,函数既能返回函数类型,也可以接受函数作为输入。类(class)也是第一类对象。
- Python代码编写快,但是运行速度比编译语言通常要慢。好在Python允许加入基于C语言编写的扩展,因此我们能够优化代码,消除瓶颈,这点通常是可以实现的。numpy就是一个很好地例子,它的运行速度真的非常快,因为很多算术运算其实并不是通过Python实现的。
- Python用途非常广泛——网络应用,自动化,科学建模,大数据应用,等等。它也常被用作“胶水语言”,帮助其他语言和组件改善运行状况。
- Python让困难的事情变得容易,因此程序员可以专注于算法和数据结构的设计,而不用处理底层的细节。
1.python数据结构
Python中常见的数据结构可以统称为容器(container)。序列(如列表和元组)、映射(如字典)以及集合(set)是三类主要的容器。
2.设计模式
设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。
1 . 抽象工厂模式 为一个产品族提供了统一的创建接口。当需要这个产品族的某一系列的时候,可以从抽象工厂中选出相应的系列创建一个具体的工厂类。
2 . 工厂方法模式 定义一个接口用于创建对象,但是让子类决定初始化哪个类。工厂方法把一个类的初始化下放到子类。
3 . 生成器模式 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
4 . 单例模式 确保一个类只有一个实例,并提供对该实例的全局访问。
class Singleton(object): def __new__(cls, *args, **kwargs): if not hasattr(cls, '_instance'): cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs) return cls._instance
5 . 适配器模式 将某个类的接口转换成客户端期望的另一个接口表示。适配器模式可以消除由于接口不匹配所造成的类兼容性问题。
6 . 观察者模式 在对象间定义一个一对多的联系性,由此当一个对象改变了状态,所有其他相关的对象会被通知并且自动刷新。
3.栈和队列
1.什么是栈
想象一摞被堆起来的书,这就是栈。这堆书的特点是,最后被堆进去的书,永远在最上面。从这堆书里面取一本书出来,取哪本书最方便?肯定是最上面那本。栈这种数据结构的特点就是如此:后进先出(Last In First Out - LIFO),即最后被堆进去的数据,最先被拿出来。
2.栈的Python实现
class Stack(object):
# 初始化栈为空列表
def __init__(self):
self.items = []
# 判断栈是否为空,返回布尔值
def is_empty(self):
return self.items == []
# 返回栈顶元素
def peek(self):
return self.items[len(self.items) - 1]
# 返回栈的大小
def size(self):
return len(self.items)
# 把新的元素堆进栈里面(程序员喜欢把这个过程叫做压栈,入栈,进栈……)
def push(self, item):
self.items.append(item)
# 把栈顶元素丢出去(程序员喜欢把这个过程叫做出栈……)
def pop(self, item):
return self.items.pop()
Python里面实现栈,就是把list包装成一个类,再添加一些方法作为栈的基本操作。其他的数据结构在Python中也是以类似的方式实现的。
3.队列Queue()
队列是一种列表,不同的是队列只能在队尾插入元素,在队首删除元素。队列用于存储按顺序排列的数据,先进先出,这点和栈不一样,在栈中,最后入栈的元素反而被优先处理。
队列是一种先进先出(First-In-First-Out,FIFO)的数据结构。队列被用在很多地方,比如提交操作系统执行的一系列进程、打印任务池等,一些仿真系统用队列来模拟银行或杂货店里排队的顾客。
队列的两种主要操作是:向队列中插入新元素和删除队列中的元素。插入操作也叫做入队,删除操作也叫做出队。入队操作在队尾插入新元素,出队操作删除队头的元素。
4.python的垃圾回收机制
通过“引用计数”(reference counting)来跟踪和回收垃圾。
在引用计数的基础上,还可以通过“标记-清除”(mark and sweep)解决容器对象可能产生的循环引用的问题。
通过“分代回收”(generation collection)以空间换取时间来进一步提高垃圾回收的效率。
5.组合和继承?
组合和继承我们倾向于选择组合,继承体现的是一种专门化的概念而组合则是一种组装的概念
6.python代码中使用try except的优缺点?
优点: 正常操作代码的控制流不会和错误处理代码混在一起. 当某种条件发生时, 它也允许控制流跳过多个框架;集中报错。
缺点: 可能会导致让人困惑的控制流. 调用库时容易错过错误情况。
7.SOCKET编程
Socket是进程通讯的一种方式,即调用这个网络库的一些API函数实现分布在不同主机的相关进程之间的数据交换。
适用场合:socket是位于传输层的网络编程了,一般用于需要自己定义应用层的协议的应用程序。
socket的结构:socket的结构很简单,只有三个元素,协议,端口号,IP地址。Socket=Ip address+ TCP/UDP + port
TCP和UDP的区别:(TCP)传输控制协议,是一种提供可靠数据传输的通用协议。(UDP)用户数据报协议,是一个面向无连接的协议。采用该协议不需要两个应用程序先建立连接。UDP协议不提供差错恢复,不能提供数据重传,因此该协议传输数据安全性差。
8.乐观锁和悲观锁?
- 悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作
- 乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。
9.三次握手
1.客户端通过向服务器端发送一个SYN来创建一个主动打开,作为三次握手的一部分。客户端把这段连接的序号设定为随机数 A。
2.服务器端应当为一个合法的SYN回送一个SYN/ACK。ACK 的确认码应为 A+1,SYN/ACK 包本身又有一个随机序号 B。
3.最后,客户端再发送一个ACK。当服务端受到这个ACK的时候,就完成了三路握手,并进入了连接创建状态。此时包序号被设定为收到的确认号 A+1,而响应则为 B+1。
10.四次挥手
TCP的连接的拆除需要发送四个包,因此称为四次挥手(four-way handshake)。客户端或服务器均可主动发起挥手动作,在socket编程中,任何一方执行close()操作即可产生挥手操作。
(1)客户端A发送一个FIN,用来关闭客户A到服务器B的数据传送。
(2)服务器B收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号。
(3)服务器B关闭与客户端A的连接,发送一个FIN给客户端A。
(4)客户端A发回ACK报文确认,并将确认序号设置为收到序号加1。
11.HTTP和HTTPS
HTTPS(全称:Hypertext Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。
超文本传输协议 (HTTP-Hypertext transfer protocol) 是一种详细规定了浏览器和万维网服务器之间互相通信的规则,通过因特网传送万维网文档的数据传送协议。
HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全。
HTTPS和HTTP的区别主要如下:
1、https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。
2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
4、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
12.Python2和3一些区别
1. __future__
模块
from __future__ import division
如果你希望在Python 2环境下写的代码也可以在Python 3.x中运行,那么建议使用__future__
模块。
2.print
函数
Python 2中的print语句被Python 3中的print()
函数取代,这意味着在Python 3中必须用括号将需要输出的对象括起来。
3.整数除法
整型除法返回浮点数,要得到整型结果,在python3中使用//
Python2中: 3 / 2 = 1
Python3中:3 / 2 = 1.5
4.Unicode
Python 3中,终于有了Unicode(utf-8)字符串,以及两个字节类:bytes和bytearrays。
5.Xrange
在Python 3中,range()的实现方式与xrange()函数相同,所以就不存在专用的xrange()(在Python 3中使用xrange()会触发NameError)。
6.异常处理
Python 3中的异常处理也发生了一点变化。在Python 3中必须使用“as”关键字。
try:
.......
except NameError as err:
Python2:
try:
.......
except NameError, err:
7.Python 3改进了input()函数,这样该函数就会总是将用户的输入存储为str对象。在Python 2中,为了避免读取非字符串类型会发生的一些危险行为,不得不使用raw_input()代替input()。
13.GIL 含义、多线程、多线程、 协程区别
进程有哪几种基本状态?
1、就绪状态 当进程已分配到除 CPU 以外的所有必要的资源,只要获得
处理机便可立即执行,这时的进程状态称为就绪状态。2、执行状态 当进程已获得处理机,其程序正在处理机上执行,此时的进程状态称为执行状态。
3、阻塞状态 正在执行的进程,由于等待某个事件发生而无法执行时,便放弃处理机而处于阻塞状态。引起进程阻塞的事件可有多种,例如,等待 I/O 完成、申请缓冲区不能满足、等待信件(信号)等。
- GIL,即全局解释器锁(Global Interpreter Lock),是计算机程序设计语言解释器用于同步线程的工具,使得任何时刻仅有一个线程在执行。CPython 中用
GIL 来控制线程的执行,只有拿到 GIL 的线程才能执行。在 CPython 的运行中,有些内部资源不是线程安全的,所以需要有一个全局锁来保护。这就造成了即使在多核CPU中,多线程也只是做着分时切换而已。意义只是每条语句宏观上并发执行,并不能提升效率,只是并发,而没有并行。
注意:GIL 只存在于CPython 中,其他 PyPy、IronPython、Jython 没有这个问题。
进程:进程之间不共享任何状态,进程的调度由操作系统完成,每个进程都有自己的独立的内存空间,进程间的通讯主要是通过信号传递的方式来实现的,实现的方式有多种,信号量,管道,事件等,任何一种方式的通讯效率都需要通过内核,导致通讯效率比较低。由于是独立的内存空间,上下文切换的时候需要先保存调用栈的信息,CPU 各寄存器的信息,虚拟内存,以及打开的相关句柄等信息,所以导致上下文进程间切换开销很大,通讯麻烦。
线程:线程之间共享变量,解决了通讯麻烦的问题,但对变量的访问需要锁,线程的调度主要也是有操作系统完成,一个进程可以拥有多个线程,但是其中每个线程会共享父进程向操作系统申请资源,这个包括虚拟内存,文件等,由于是共享资源,所以创建线程所需要的系统资源占用比进程小很多,相应的可创建的线程数量也变得相对多很多。线程时间的通讯除了可以使用进程之间通讯的方式之外还可以通过共享内存的方式进行通信,所以这个速度比通过内核要快很多。另外在调度方面也是由于内存是共享的,所以上下文切换的时候需要保存的东西就相对少一些,这样一来上下文切换也变得高效
协程:协程的调度完全由用户控制,一个线程可以有多个协程,用户创建了几个协程,然后每个协程都是循环按照指定的任务清单顺序完成不同的任务,当任务被堵塞的时候执行下一个任务,当恢复的时候再回来执行这个任务,任务之间的切换只需要保存每个任务的上下文内容,就像直接操作栈一样的,这样就完全没有内核
14.装饰器、生成器 、迭代器
-
迭代器:迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。
特点:
1.访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一个内容
2.不能随机访问集合中的某个值 ,只能从头到尾依次访问
3.访问到一半时不能往回退
4.便于循环比较大的数据集合,节省内存 -
生成器:一个函数调用时返回一个迭代器,那这个函数就叫做生成器(generator),如果函数中包含yield语法,那这个函数就会变成生成器。
这个yield的主要效果呢,就是可以使函数中断,并保存中断状态,中断后,代码可以继续往下执行,过一段时间还可以再重新调用这个函数,从上次yield的下一句开始执行。 - 装饰器:装饰器(Decorator)是python中最吸引人的特性,可以让已有的函数不做任何改动的情况下增加功能。
二、数据库
1.数据库升序降序
数据库 中使用order by语句进行排序,其中升序用asc,降序用desc。
如:
select * from t order by 列a asc; -- 这是升序 asc可以省略不写
select * from t order by 列a desc; -- 这是降序
2.Mysql优化
- 大部分 MySQL 服务器都有查询缓存功能。这是提高性能的最有效的方法之一,这是由数据库引擎私下处理的。当同一个查询被多次执行,结果会直接从缓存里提取,这样速度就很快。
- 获取唯一行时使用 LIMIT 1
有时当你查表时,你已经知道你正在查找的结果只有一行。你可能正在获取唯一记录,或者你可能只是查询是否存在满足你的 WHERE 子句条件的记录。
在这种情况下,将 LIMIT 1 添加到查询条件中可以提高性能。这样,数据库引擎将在找到刚刚第一个记录之后停止扫描记录,而不是遍历整个表或索引 - 避免使用 SELECT *
- 索引搜索字段
3.Mysql 的连接查询有哪些
INNER JOIN(内连接,或等值连接):取得两个表中存在连接匹配关系的记录。
LEFT JOIN(左连接):取得左表(table1)完全记录,即是右表(table2)并无对应匹配记录。
RIGHT JOIN(右连接):与 LEFT JOIN 相反,取得右表(table2)完全记录,即是左表(table1)并无匹配对应记录。
4.mysql 常用的引擎InnoDB(我用的是InnoDB)
优点:InnoDB 支持事务,事务是一种高级的处理方式,如在一些列增删改中只要哪个出错还可以回滚还原;支持外键;
缺点:清空整个表时,InnoDB 是一行一行的删除,效率非常慢。
5.redis 基本类型
Redis 支持五种数据类型:string(字符串)、hash(哈希)、list(列表)、set(集合)及 zset(sorted set:有序集合)。
6.数据库的隔离级别
(一)可读取未确认(Read uncommitted)
写事务阻止其他写事务,避免了更新遗失。但是没有阻止其他读事务。
存在的问题:脏读。即读取到不正确的数据,因为另一个事务可能还没提交最终数据,这个读事务就读取了中途的数据,这个数据可能是不正确的。
解决办法就是下面的“可读取确认”。
(二)可读取确认(Read committed)
写事务会阻止其他读写事务。读事务不会阻止其他任何事务。
存在的问题:不可重复读。即在一次事务之间,进行了两次读取,但是结果不一样,可能第一次id为1的人叫“李三”,第二次读id为1的人就叫了“李四”。因为读取操作不会阻止其他事务。
解决办法就是下面的“可重复读”。
(三)可重复读(Repeatable read)
读事务会阻止其他写事务,但是不会阻止其他读事务。
存在的问题:幻读。可重复读阻止的写事务包括update和delete(只给存在的表加上了锁),但是不包括insert(新行不存在,所以没有办法加锁),所以一个事务第一次读取可能读取到了10条记录,但是第二次可能读取到11条,这就是幻读。
解决办法就是下面的“串行化”。
(四)可串行化(Serializable)
读加共享锁,写加排他锁。这样读取事务可以并发,但是读写,写写事务之间都是互斥的,基本上就是一个个执行事务,所以叫串行化。
7.数据库的ACID
ACID,是指在可靠数据库管理系统(DBMS)中,事务(transaction)所应该具有的四个特性:/原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)
8.同步异步、阻塞非阻塞
同步和异步关注的是消息通信机制 (synchronous communication/ asynchronous communication)。
- 所谓同步,就是在发出一个调用时,在没有得到结果之前,该调用就不返回。
但是一旦调用返回,就得到返回值了。
换句话说,就是由调用者主动等待这个调用的结果。 - 而异步则是相反,调用在发出之后,这个调用就直接返回了,所以没有返回结果。换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果。而是在调用发出后,被调用者通过状态、通知来通知调用者,或通过回调函数处理这个调用。
举个通俗的例子:
你打电话问书店老板有没有《分布式系统》这本书,如果是同步通信机制,书店老板会说,“你稍等,我查一下”,然后开始查啊查,等查好了(可能是 5 秒,也可能是一天)告诉你结果(返回结果)。
而异步通信机制,书店老板直接告诉你我查一下啊,查好了打电话给你,然后直接挂电话了(不返回结果)。然后查好了,他会主动打电话给你。在这里老板通过“回电”这种方式来回调。
阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态.
阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。
非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。
三、Web框架
1.CGI和WSGI
CGI是通用网关接口,是连接web服务器和应用程序的接口,用户通过CGI来获取动态数据或文件等。
CGI程序是一个独立的程序,它可以用几乎所有语言来写,包括perl,c,lua,python等等。
WSGI, Web Server Gateway Interface,是Python应用程序或框架和Web服务器之间的一种接口,WSGI的其中一个目的就是让用户可以用统一的语言(Python)编写前后端。
2.XSRF和XSS
- CSRF(Cross-site request forgery)跨站请求伪造
- XSS(Cross Site Scripting)跨站脚本攻击
CSRF重点在请求,XSS重点在脚本
3.Django 的架构
Django 采用 MVT 的架构模式:M 为 Model 模型层,是对数据库的数据的抽象与映射;V 为 View 视图层,在此层中进行业务逻辑的处理,包括操作 model和为模版层提供数据;T 为 Template 模版层,负责前端页面的展示。
4.django 对数据查询结果排序怎么做,降序怎么做,查询大于某个字段怎么做。
- 排序使用
order_by()
,如Entry.objects.order_by('blog__name', 'headline')
; - 降序需在排序的字段名前加-,如
Entry.objects.order_by('-pub_date')
; - 查询字段大于某个值:使用 filter(字段名__gt=值),如
Entry.objects.filter(pubdate__gt='2006-01-01')
5.Django处理request的流程
- 用户通过浏览器请求一个页面
- 请求到达Request Middlewares,中间件对request做一些预处理或者直接response请求
- URLConf通过urls.py文件和请求的URL找到相应的View
- View Middlewares被访问,它同样可以对request做一些处理或者直接返回response
- 调用View中的函数
- View中的方法可以选择性的通过Models访问底层的数据
- 所有的Model-to-DB的交互都是通过manager完成的
- 如果需要,Views可以使用一个特殊的Context
- Context被传给Template用来生成页面
- Template使用Filters和Tags去渲染输出
- 输出被返回到View
- HTTPResponse被发送到Response Middlewares
- 任何Response Middlewares都可以丰富response或者返回一个完全不同的response
- Response返回到浏览器,呈现给用户
Middleware(中间件,包括request, view, exception, response),URLConf(url映射关系),Template(模板系统)
6.Django 的 queryset 使用
在进行数据查询时,使用 all()、filter()、exclude()
等会返回 Queryset,在对Queryset 进行过滤链式操作的时候返回的还是 Queryset,我们可以对返回的Queryset 进行排序、切片、过滤、去重等操作。
7.Django 与 Tornado 的对比
Django 是一个大而全的框架,其设计初衷是为了快速开发,所以提供了丰富的套件供开发使用。其框架的所有业务与其内置的 ORM 紧密相关,还提供了自动化的 Admin 管理后台。
而 Tornado 不仅仅是 Web 框架,其还提供了一个高性能的 Web 服务器,其设计初衷就是为了解决性能瓶颈问题,目的要打造一个高性能的开发框架。 Tornado 作为 Web 框架要比 Django 轻量的多,没有提供丰富的套件,比如没有ORM、管理后台、表单系统,甚至没有 session 机制,但是提供了异步机制、 WebSocket 等 Django 没有的功能,属于灵活的轻量级框架。
8.Torando 的优缺点
Tornado 的优点是利用 epoll 机制实现了高性能,并以此提供了异步机制,可以达到异步非阻塞;框架轻量灵活;
其缺点是:Tornado 的运行是单进程的,一旦在处理一个请求时出现了阻塞,将影响整体性能,所有在 Tornado 的开发中要避免阻塞,出现阻塞的地方使用异步,而对于接入的第三方库或 SDK 往往并没有提供对 Tornado 框架的异步支持,所以使用第三方接口时需要我们重复造轮子,自己封装针对于 Tornado 异步的接口调用库。
9.Tornado 的工作原理
1.ioloop 是 tornado 运行的核心
2.ioloop 封装了操作管理 epoll 的工作
3.当 ioloop 实例启动时,ioloop 将服务器监听的 socket 添加到 epoll 容器中,然后循环等待 epoll 返回可处理的 socket
4.当有客户端发起连接后,ioloop 从 epoll 容器中拿到了服务器监听的 socket,并调用服务器实例处理该监听 socket 的方法,接收连接请求,并将新的与客户端对应的 socket 添加到 epoll 容器中,然后继续循环等待 epoll 返回可处理的 socket
5.当客户端发送过来请求数据后,ioloop 从 epoll 中拿到了接收数据的 socket,并调用服务器实例处理该传输 socket 的方法,从 socket 中读取出 http 报文数据,解析后调用 Application 的实例,进行路由分发,实例化具体的 RequestHandler,执行其中的具体 http 方法,生成响应数据并打包成 http 报文写入到缓冲区中。
6.当与客户端对应的 socket 可写时,ioloop 从 epoll 中拿到了对应可写的 socket,将缓冲区中对应的响应报文数据写入到 socket 中传回给客户端,完成请求处理。
7.epoll 每次只返回给 ioloop 可以处理的 socket,然后 ioloop 对拿到的 socket 依次进行处理,有效充分地利用了 cpu 时间,进而达到提升支持高并发的能力。
10.apache和nginx的区别
nginx 相对 apache 的优点:
- 轻量级,同样起web 服务,比apache 占用更少的内存及资源
- 抗并发,nginx 处理请求是异步非阻塞的,支持更多的并发连接,而apache 则是阻塞型的,在高并发下nginx 能保持低资源低消耗高性能
- 配置简洁
- 高度模块化的设计,编写模块相对简单
- 社区活跃
apache 相对nginx 的优点:
- rewrite ,比nginx 的rewrite 强大
- 模块超多,基本想到的都可以找到
- 少bug ,nginx 的bug 相对较多
- 超稳定
11.SOAP
SOAP(原为Simple Object Access Protocol的首字母缩写,即简单对象访问协议)是交换数据的一种协议规范,使用在计算机网络Web服务(web service)中,交换带结构信息。SOAP为了简化网页服务器(Web Server)从XML数据库中提取数据时,节省去格式化页面时间,以及不同应用程序之间按照HTTP通信协议,遵从XML格式执行资料互换,使其抽象于语言实现、平台和硬件。