Python基础知识
一、python基础知识要点
1、到底什么是Python?你可以在回答中与其他技术进行对比
-
解释器的特点:
- 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)
2、python常见的装饰器
-
@classmethod
- classmethod 修饰符对应的函数不需要实例化,不需要 self 参数,但第一个参数需要是表示自身类的 cls 参数,可以来调用类的属性,类的方法,实例化对象等
class A(object): bar = 1 def func1(self): print ('foo') @classmethod def func2(cls): print ('func2') print (cls.bar) cls().func1() # 调用 foo 方法 A.func2() # 不需要实例化
-
@staticmethod
- 返回函数的静态方法
class C(object): @staticmethod def f(): print('runoob'); C.f(); # 静态方法无需实例化 cobj = C() cobj.f() # 也可以实例化后调用
-
@property
- 将函数作为属性值来操作
class Rectangle: def __init__(self,width,height): self.width = width self.height = height @property def area(selef): return width * height r = Rectangle(3.14,5) # 将area函数作为属性使用 print(r.area)
3、Python的垃圾回收机制(garbage collection)
- 引用计数:
- Python在内存中存储了每个对象的引用计数(reference count)。如果计数值变成0,那么相应的对象就会消失,分配给该对象的内存就会释放出来用作他用
- 偶尔也会出现引用循环(reference cycle)
- 引用计数减少的情况
- 1、使用del语句对对象别名显示的销毁
- 2,引用超出作用域或被重新赋值
- Python中使用了某些启发式算法(heuristics)来加速垃圾回收
- 越晚创建的对象更有可能被回收
- 对象被创建之后,垃圾回收器会分配它们所属的代(generation)
- 每个对象都会被分配一个代,而被分配更年轻代的对象是优先被处理的
- 内存池机制
- Python提供了对内存的垃圾收集机制,但是它将不用的内存放到内存池而不是返回给操作系统
- Pymalloc机制:为了加速Python的执行效率,Python引入了一个内存池机制,用于管理对小块内存的申请和释放
- Python中所有小于256个字节的对象都使用pymalloc实现的分配器,而大的对象则使用系统的malloc
- 对于Python对象,如整数,浮点数和List,都有其独立的私有内存池,对象间不共享他们的内存池。也就是说如果你分配又释放了大量的整数,用于缓存这些整数的内存就不能再分配给浮点数
4、join 和 + 拼接字符串的区别
- + 执行原理
- 当用操作符+连接字符串的时候,每执行一次+都会申请一块新的内存,然后复制上一个+操作的结果和本次操作的右操作符到这块内存空间,因此用+连接字符串的时候会涉及好几次内存申请和复制
- join的执行原理
- join在连接字符串的时候,会先计算需要多大的内存存放结果,然后一次性申请所需内存并将字符串复制过去,这是为什么join的性能优于+的原因
- 所以在连接字符串数组的时候,我们应考虑优先使用join
5、_new_ 和 __init__的用法和区别
- 区别
- _new_:创建对象时调用,会返回当前对象的一个实例
- _init_:创建完对象后调用,对当前对象的一些实例初始化,无返回值
- 用法
- __new__方法会返回所构造的对象,__init__则不会,__init__无返回值
- __new__至少要有一个参数cls,代表要实例化的类(类对象),此参数在实例化时由Python解释器自动提供
- __new__必须要有返回值,返回实例化出来的实例,这点在自己实现,__new__时要特别注意,可以return父类__new__出来的实例或者直接是object的__new__出来的实例。
- __init__有一个参数self,就是这个__new__返回的实例,__init__在__new__的基础上可以完成一些其它初始化的动作,__init__不需要返回值
6、*args 和 **kwargs 的用法区别
- args: 不知道有多少个形式参数,想将其以列表或者元组的形式传递的时候使用
- **kwargs: 不知道会传入多少关键字参数的时候,使用kwargs会收集关键字参数
7、python解释器中的闭包
- 一个内部函数(定义在函数内部的函数)中,对外部作用域(不是在全局作用域中)进行引用,那么内部函数就是一个闭包函数
def test_funct(name):
def subfunction(age):
ppint("name:%s, age:%s"%(name,age))
# 这就形成了一个闭包
obj = test_funct("Tom")
obj(18)
"""
name:Tom, age:18
"""
8、python中的深浅拷贝
-
= 复制运算:将对象的引用赋值给新的变量,其改变任意一个之变量都会改变
-
浅拷贝(copy):创建一个对象,将原对象的引用地址赋值给新的对象,两个对象指向的是同一块内存地址中的同一个值
-
深拷贝(deepcopy):将原对象的值完完全全的拷贝一份,放到一个新的地址中,与原对象没有任何关系,其中的数据改变相互不在影响,相互独立
二、网络编程的基础知识要点
1、网络中进程之间如何通信?
- 消息传递(管道、FIFO、消息队列)
- 同步(互斥量、条件变量、读写锁、文件和写记录锁、信号量)
- 共享内存(匿名的和具名的)
- 远程过程调用(Solaris门和Sun RPC)
2、简述三次握手、四次挥手
- 三次握手
- 客户端向服务器发送一个SYN J
- 服务器向客户端响应一个SYN K,并对SYN J进行确认ACK J+1
- 客户端再想服务器发一个确认ACK K+1
- 四次挥手
- TCP客户端发送一个FIN,用来关闭客户到服务器的数据传送。
- 服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1;和SYN一样,一个FIN将占用一个序号
- 服务器关闭客户端的连接,发送一个FIN给客户端
- 客户端发回ACK报文确认,并将确认序号设置为收到序号加1
3、七层模型以及每一层常用的协议
- 物理层 以太网卡
- 数据链路层
- WI-FI
- 以太网
- 网络层
- IP(IPv4 IPv6)
- ICMP ARP(地址解析协议)
- 传输层
- TCP
- UDP
- PPTP
- TLS
- 会话层
- ADSP
- ISO-SP
- 表示层
- FTP
- Telnet
- ASN.1
- 应用层
- DNS
- FTP
- HTTP
- SMTP
- SSH
4、简述浏览器响应客户端的流程
- 在浏览器中输入url,直接输入ip或者输入域名。
- 如果输入的是域名就需要通过DNS解析将域名解析成IP地址,通过IP来确认访问的是哪个服务器。
- 建立TCP请求(即三次握手)
- 发送http请求
- 服务器处理请求,并将结果返回给浏览器
- 最后断开TCP连接(即四次挥手) - 浏览器根据返回结果进行处理以及页面渲染
5、Http响应状态码
- 1xx:信息,请求收到,继续处理
- 2xx:成功,行为被成功地接受、理解和采纳
- 3xx:重定向,为了完成请求,必须进一步执行的动作
- 4xx:客户端错误,请求包含语法错误或者请求无法实现
- 5xx:服务器错误,服务器不能实现一种明显无效的请求
状态码 | 请求状态 |
---|---|
200 | OK |
204 | 无内容 |
301 | 永久重定向 |
307 | 暂时重定向 |
400 | 错误的请求 |
401 | 没有授权的请求 |
404 | 请求的资源不存在 |
408 | 请求超时 |
500 | 服务器内部错误 |
503 | 服务器请求数量超出负载 |
504 | 网关超时 |
6、Http请求的常见方式
9种请求方式
请求方式 | 介绍 |
---|---|
GET | 请求指定的页面信息,并返回实体主体 |
HEAD | 类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头 |
POST | 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)数据被包含在请求体中。POST 请求可能会导致新的资源的建立和/或已有资源的修改 |
PUT | 从客户端向服务器传送的数据取代指定的文档的内容 |
DELETE | 请求服务器删除指定的页面 |
CONNECT | HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器 |
OPTIONS | 允许客户端查看服务器的性能 |
TRACE | 回显服务器收到的请求,主要用于测试或诊断 |
PATCH | 是对 PUT 方法的补充,用来对已知资源进行局部更新 |
POST请求个GET请求的区别
- get是从服务器上获取数据,post是向服务器传送数据
- GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息
- GET请求在URL中传送的参数是有长度限制的(是因为浏览器对URL的长度有限制,GET本身没有限制),而POST么有长度限制
(*IE浏览器对URL的最大限制为2083个字符,如果超过这个数字,提交按钮没有任何反应
*Firefox浏览器URL的长度限制为65,536个字符
*URL最大长度限制为8182个字符
为了让所有的用户都能正常浏览,URL最好不要超过IE的最大长度限制(2083个字符),当然,如果URL不直接提供给用户,而是提供给程序调用,这时的长度就只受Web服务器影响了) - get传送的数据量较小,不能大于2KB;post传送的数据量较大(post有的说是128K,但是理论上是没有限制的,主要取决于服务器的处理程序能力)
- GET能被缓存,POST不能
- GET回退浏览器无害,POST会再次提交请求(GET方法回退后浏览器再缓存中拿结果,POST每次都会创建新资源)
7、socket的长连接和短链接
- 长连接
- 整个通讯过程,客户端和服务端只用一个Socket对象,长期保持Socket的连接
- 短链接
- 后者是每次请求,都新建一个Socket,处理完一个请求就直接关闭掉Socket
- 区别
- 整个客户和服务端的通讯过程是利用一个Socket还是多个Socket进行的
8、http1.0和http1.1的区别
- 错误通知的管理,在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除
- http1.1默认支持长连接,http1.0支持短链接,每一次请求都要创建连接
- 缓存处理,在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略
9、http和https的区别
http和https
- http超文本传输协议,是一个基于请求与响应,无状态的,应用层的协议,常基于TCP/IP协议传输数据,互联网上应用最为广泛的一种网络协议,所有的WWW文件都必须遵守这个标准。设计HTTP的初衷是为了提供一种发布和接收HTML页面的方法
- HTTPS是一种通过计算机网络进行安全通信的传输协议,经由HTTP进行通信,利用SSL/TLS建立全信道,加密数据包
http和https的区别
- HTTPS协议需要到CA申请证书,一般免费证书很少,需要交费。
- HTTP协议运行在TCP之上,所有传输的内容都是明文,HTTPS运行在SSL/TLS之上,SSL/TLS运行在TCP之上,所有传输的内容都经过加密的。
- HTTP和HTTPS使用的是完全不同的连接方式(长短连接),用的端口也不一样,前者是80,后者是443
10、TCP和UDP的区别
-
TCP提供面向连接的传输,通信前要先建立连接(三次握手机制);UDP提供无连接的传输,通信前不需要建立连接。
-
TCP提供可靠的传输(有序,无差错,不丢失,不重复);UDP提供不可靠的传输。
-
TCP面向字节流的传输,因此它能将信息分割成组,并在接收端将其重组;UDP是面向数据报的传输,没有分组开销。
-
TCP提供拥塞控制和流量控制机制;UDP不提供拥塞控制和流量控制机制
11、网络编程的一般步骤
对于TCP连接:
1.服务器端1)创建套接字create;2)绑定端口号bind;3)监听连接listen;4)接受连接请求accept,并返回新的套接字;5)用新返回的套接字recv/send;6)关闭套接字。
2.客户端1)创建套接字create; 2)发起建立连接请求connect; 3)发送/接收数据send/recv;4)关闭套接字。
TCP总结:
Server端:create -- bind -- listen-- accept-- recv/send-- close
Client端:create------- conncet------send/recv------close.
---------------------------------------------------------------------------
---------------------------------------------------------------------------
对于UDP连接:
1.服务器端:1)创建套接字create;2)绑定端口号bind;3)接收/发送消息recvfrom/sendto;4)关闭套接字。
2.客户端:1)创建套接字create;2)发送/接收消息sendto/recvfrom;3)关闭套接字.
UDP总结:
Server端:create----bind ----recvfrom/sendto----close
Client端:create---- sendto/recvfrom----close.
12、cookie和session的区别
-
Cookie实际上是一小段的文本信息,客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie,客户端会把Cookie保存起来
-
Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上
区别 | Cookie | Session |
---|---|---|
存放位置 | 数据存放在客户的浏览器上 | 数据存放在服务器上 |
安全性 | Cookie存放在本地,容易被解析,不安全 | session在服务器较为安全 |
数据大小 | 单个Cookie保存的数据大小不能超过4K | session存储在服务器,浏览器对其没有限制 |
性能使用程度 | Cookie存放在浏览器对服务器性能没有影响 | session会在一定时间内保存在服务器上,当访问增多,会比较占用你服务器的性能 |
13、UDP如何实现可靠传输
UDP它不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用UDP较多,因为它们即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。
传输层无法保证数据的可靠传输,只能通过应用层来实现了。实现的方式可以参照tcp可靠性传输的方式,只是实现不在传输层,实现转移到了应用层。
实现确认机制、重传机制、窗口确认机制。
如果你不利用Linux协议栈以及上层socket机制,自己通过抓包和发包的方式去实现可靠性传输,那么必须实现如下功能:
发送:包的分片、包确认、包的重发
接收:包的调序、包的序号确认
目前有如下开源程序利用udp实现了可靠的数据传输。分别为RUDP、RTP、UDT。
三、进程和线程
进程
- 简单来说,进程就是正在运行的程序的实例
- 进程(process)是一块包含了某些资源的内存区域。操作系统利用进程把它的工作划分为一些功能单元
- 进程中所包含的一个或多个执行单元称为线程(thread)
- 进程还拥有一个私有的虚拟地址空间,该空间仅能被它所包含的线程访问
线程
- 轻型实体(线程的实体包括程序、数据和TCB。tcb用于指示被执行指令序列的程序计数器、保留局部变量、少数状态参数和返回地址等的一组寄存器和堆栈)
- 独立调度和分派的基本单位
- 可并发执行
- 共享进程资源(所有线程都具有相同的地址空间(进程的地址空间),这意味着,线程可以访问该地址空间的每一个虚地址;此外,还可以访问进程所拥有的已打开文件、定时器、信号量机构等。由于同一个进程内的线程共享内存和文件,所以线程之间互相通信不必调用内核)
进程和线程的区别
-
进程是资源分配的最小单位,线程是程序执行的最小单位。
-
进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵。而线程是共享进程中的数据的,使用相同的地址空间,因此CPU切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程要小很多。
-
线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式(IPC)进行。不过如何处理好同步与互斥是编写多线程程序的难点.
-
但是多进程程序更健壮,多线程程序只要有一个线程死掉,整个进程也死掉了,而一个进程死掉并不会对另外一个进程造成影响,因为进程有自己独立的地址空间。
-
CPU分给进程,即真正在CPU上运行的是线程,线程不能够独立执行,必须依存在进程中
-
进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率
资源分配给进程,同一进程的所有线程共享该进程的所有资源。 -
一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程
线程的划分尺度小于进程(资源比进程少),使得多线程程序的并发性高。
进程的优缺点
进程的优点
-
进程程序的特点:具有封闭性和可再现性;
-
程序的并发执行和资源共享。多道程序设计出现后,实现了程序的并发执行和资源共享,提高了系统的效率和系统的资源利用率
进程的缺点
-
操作系统调度切换多个线程要比切换调度进程在速度上快的多。而且进程间内存无法共享,通讯也比较麻烦。
-
线程之间由于共享进程内存空间,所以交换数据非常方便;在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。
线程的优缺点
线程的优点
- 无需跨进程边界; 程序逻辑和控制方式简单; 所有线程可以直接共享内存和变量等; 线程方式消耗的总资源比进程方式好;
- 每个进程互相独立,不影响主程序的稳定性,子进程崩溃没关系; 通过增加CPU,就可以容易扩充性能; 可以尽量减少线程加锁/解锁的影响,极大提高性能
线程的缺点
- 线程之间的同步和加锁控制比较麻烦; 一个线程的崩溃可能影响到整个程序的稳定性
- 逻辑控制复杂,需要和主程序交互; 需要跨进程边界,如果有大数据量传送,就不太好,适合小数据量传送、密集运算 多进程调度开销比较大
对比
- 进程是资源分配的基本单位,线程是调度的基本单位。进程包含线程,线程共用进程的资源
python中的多线程和多进程
-
在python中实际上并不存在真真正正的多线程,因为在python解释器中存在一个全局解释器锁(global interpreter lock),这个锁的意思是任一时间只能有一个线程使用解释器,跟单cpu跑多个程序一个意思,大家都是轮着用的,这叫“并发”,不是“并行”,
四、框架
Flask相关知识
1. 什么是Flask,有什么优点?
-
Flask是一个Web框架,就是提供一个工具,库和技术来允许你构建一个Web应用程序.这个Web应用程序可以是一些Web页面,博客,wiki,基于Web的日里应用或商业网站.
-
Flask属于微框架(micro-framework)这一类别,微架构通常是很小的不依赖外部库的框架.
- 框架很轻量
- 更新时依赖小
- 专注于安全方面的bug -
Flask的依赖:
Werkzeug 一个WSGI工具包(web服务网关接口(Python Web Server Gateway Interface,缩写为WSGI)是为python语言定义的web服务器和web应用程序或框架之间的一种简单而通用的借口,其他语言也有类似的接口)
-
jinja2模板引擎
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
retunt "Hello Flask"
if __name__ == '__main__':
app.run()
2、Django和Flask有什么区别?
Flask
- 轻量级web框架,默认依赖两个外部库:jinja2和Werkzeug WSGI工具
- 适用于做小型网站以及web服务的API,开发大型网站无压力,但架构需要自己设计
- 与关系型数据库的结合不弱于Django,而与非关系型数据库的结合远远优于Django
Django
- 重量级web框架,功能齐全,提供一站式解决的思路,能让开发者不用在选择上花费大量时间.
- 自带ORM(Object-Relational Mapping 对象关系映射)和模板引擎,支持jinja等非官方模板引擎.
- 自带ORM使Django和关系型数据库耦合度高,如果要使用非关系型数据库,需要使用第三方库
- 自带数据库管理app
- 成熟,稳定,开发效率高,相对于Flask,Django的整体封闭性比较好,适合做企业级网站的开发.
- python web框架的先驱,第三方库丰富
3、Flask-WTF是什么,有什么特点?
- Flask-wtf是一个用于表单处理,校验并提供csrf验证的功能的扩展库
- Flask-wtf能把正表单免受CSRF<跨站请求伪造>的攻击
4、 如何在Flask中访问会话?
-
会话(seesion)会话数据存储在服务器上.会话是客户端登录到服务器并注销的时间间隔.需要在此会话中进行的数据存储在服务器上的临时目录中.
from flask import session 导入会话对象 session['key'] = 'value' 给会话添加变量 session.pop('key', None) 删除会话的变量
5 解释Python Flask中的数据库连接?
- python中的数据库连接有两种方式
- 在脚本中以用第三方库正常连接,用sql语句正常操作数据库,如mysql关系型数据库的pymsql库
- 用ORM来进行数据库连接,flask中典型的flask_sqlalchemy,已面向对象的方式进行数据库的连接与操作
6、Flask框架依赖组件?
- Route(路由)
- templates(模板)
- Models(orm模型)
- blueprint(蓝图)
- Jinja2模板引擎
7、Flask蓝图的作用?
-
蓝图Blueprint实现模块化的应用
- book_bp = Blueprint(‘book’, name)创建蓝图对象
- 蓝图中使用路由@book_bp.route(‘url’)
- 在另一.py文件里导入和注册蓝图from book import book_bp app.register_blueprint(book_bp)
-
作用:
- 将不同的功能模块化
- 构建大型应用
- 优化项目结构
- 增强可读性,易于维护(跟Django的view功能相似)