1.Python的数据类型
注:需要列出重要的几个数据类型的特点
Python3中有六个标准的数据类型:字符串(String)、数字(Digit)、列表(List)、元组(Tuple)、集合(Sets)、字典(Dictionary)。
Python 中,数值类型(int 和 float)、字符串 str、元组 tuple 都是不可变类型(该对象所指向的内存中的值不能被改变)。而列表 list、字典 dict、集合 set 是可变类型(该对象所指向的内存中的值可以被改变)。
拓展:
元组tuple:有序、可以重复、不可变,不能进行增删改,可以索引或切片进行查
列表list:可以进行增(append、extend、insert);删(pop、remove、del,clear);改、查(通过索引切片)
集合set:无序、不可重复、可变。增(add、update);删(pop、discard、remove、del),不可改不可查。
字典dict:无序,增(直接通过键值对,update);删(pop,popitem随机删除一对,del,clear);改,查(通过键值对,get)
- 列表与字典的区别:
- 列表有序,字典无序;
- 列表通过索引(偏移)访问元素,字典通过键(key)访问元素。
2.迭代器、生成器是什么(区别)
迭代器是访问集合元素的一种方式,含有__iter__
和__next__
方法。迭代器对象从集合的第一个元素开始访问,直到所有元素被访问完结束。迭代器只能往前不会后退。
一个函数调用时返回一个迭代器,那这个函数就叫做生成器。如果函数中包含yield语法,那这个函数就会变成生成器;
拓展:
1、迭代器有两个基本的方法:iter() 和 next()。
2、迭代器协议:对象必须提供iter或next方法,执行该方法要么返回迭代中的下一项,要么引起StopIteration异常,以终止迭代(只能往下走,不可回退)。
3、生成器本质就是迭代器。
区别:
- 生成器能做到迭代器能做的所有事,而且因为自动创建了 iter()和 next()方法,生成器显得特别简洁,而且生成器也是高效的,使用生成器表达式取代列表解析可以同时节省内存。除了创建和保存程序状态的自动方法,当发生器终结时,还会自动抛出StopIteration 异常。
3.装饰器是什么(作用)
装饰器也是一个函数,作用是在不改变函数的基础上,增加一些功能进行装饰。
- 装饰器的本质是闭包,什么是闭包:
- 在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包。
- 闭包的作用:
- 可以读取函数内部的变量;
- 让这些变量的值始终保持在内存中,不会被自动清除。
import time
def timeit(func):
def wrapper():
start = time.time()
func()
end =time.time()
print('used:',end - start)
return wrapper
@timeit
def foo():
time.sleep(1)
print('in foo()')
foo()
#输出结果:
in foo()
used: 1.0045325756072998
4.函数的三大特性
- 继承:当我们定义一个新类的时候,可以从某个现有的类继承,新的类就被称为子类,而被继承的类则被称为基类,父类,超类
- 多态:当子类和父类存在相同的方法时,子类的方法会覆盖父类的方法,再运行代码时,总会调用子类和父类同名的方法。
- 封装:隐藏对象的属性和实现细节,仅对外提供公共访问的方式。
5.赋值、深浅拷贝的区别
赋值:不会开辟新的内存空间(内存地址相同),它只是复制了对象的引用。(修改了a,也就影响了b,同理,修改了b,也就影响了a。)
浅拷贝:会创建新对象(内存地址不同),其内容非原对象本身的引用,而是原对象内第一层对象的引用,浅拷贝只拷贝一层(copy.copy,即修改多层嵌套的话,b列表会发生改变)
深拷贝:深拷贝和浅拷贝对应,深拷贝拷贝了对象的所有元素,包括多层嵌套的元素。(copy.deepcopy)
6.进程线程协程是什么(区别)
进程:系统进行资源分配与调度的基本单位,是程序的实体
线程:轻量级进程,独立调度和分派的基本单位,是程序执行流的最小单位
协程:是一种用户态的轻量级线程
-
进程的组成:
- 文本区域存储处理器执行的代码
- 数据区域存储变量和进程执行期间使用的动态分配的内存
- 堆栈存储活动过程调用的指令和本地变量。
-
进程的特征:
- 动态性
- 并发性
- 独立性
- 异步性(由于进程间相互制约,进程按各自独立的,不可预知的速度向前推进)
- 结构特征(进程的实体由程序、数据和进程控制块组成)
-
并发与并行:
- 并发处理:在同一时间间隔内多个任务都在运行,但并不会在同一时刻同时运行,存在交替执行的情况。实现并发的库有:threading
- 并行处理:同一时刻多个任务同时在执行。实现并行的库有:multiprocessing
-
GIL(全局解释器锁):
- 作用:每个线程在执行时候都需要先获取GIL,保证同一时刻只有一个线程可以执行代码,即同一时刻只有一个线程使用CPU。
-
进程和线程的关系:
- 一个进程至少有一个线程,一个线程只能属于一个进程。
- 线程作为调度和分配的基本单位,进程作为拥有资源的基本单位。
- 进程可以实现并行,线程只能并发
- 同一个进程内的线程可以直接通信,而进程之间的通信需要借助中间代理
-
进程线程与协程的关系:
- 一个线程可以拥有多个协程,一个进程也可以单独拥有多个协程。
- 线程和进程都是同步机制,而协程则是异步的。
- 协程能保留上一次调用时的状态
- 线程是协程的资源。协程通过Interceptor来间接使用线程这个资源。
-
同步与异步(相对于多任务而言):
- 同步:发送方发送请求后,需要等待接收响应,否则会一直等待
- 异步:发送方发送请求后,不需要等待响应,可以继续发送下一个请求,或者主动挂起线程并释放CPU
-
阻塞与非阻塞(相对于代码执行而言):
- 阻塞调用是指调用结果返回之前,当前线程会被挂起。函数只有在得到结果之后才会返回
- 非阻塞在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回。
-
Python中的进程与线程的使用场景:
- 多进程适合在CPU密集型操作(cpu操作指令较多,如位数多的浮点运算)
- 多线程适合在IO密集型操作(读写数据操作较多的,比如爬虫)
-
IO密集型与CPU密集型的区别:
- IO密集型:系统运作,大部分状况是CPU在等I/O(硬盘/内存)的读/写
- CPU密集型:大部分时间用来做计算、逻辑判断等CPU动作的程序
7.进程共享资源
进程之间的通信:无名管道,FIFO(命名管道),消息队列,信号量,共享内存
8.多线程竞争
当各个线程访问数据资源时会出现竞争状态即:数据几乎同步会被多个线程占用,造成数据混乱即所谓的线程不安全。
(如何解决:加锁,互斥锁)
线程同步保证多个线程安全访问竞争资源,最简单的同步机制就是引入互斥锁。
加锁的好处:用于解决多线程竞争资源的问题(互斥锁保证了每次只有一个线程写入操作,从而保证了多线程情况下数据的正确性。)
加锁的坏处:阻止了多线程并发执行,包含锁的某段代码实际上只能以单线程模式执行,效率大大下降了。
(一个CPU执行多个线程,就是并发)
9.死锁是什么,如何解决:
死锁:在线程间共享多个资源时,如果两个线程分别占有一部分资源,并且同时等待对方的资源,就会造成死锁。
解决方法:
- 在同一时刻不允许一个线程访问多个资源
- 为资源访问权的获取定义一个关系顺序
- 为所有访问资源的请求系统地定义一个最大等待时间,并妥善处理请求失败的情况。
GIL全局解释器锁(只在Cpython才有),作用是限制多线程同时执行,保证同一时间只有一个线程执行。所以Cpython里的多线程其实是伪多线程。
10.MySQL的查询优化
- 用索引,避免全表扫描
- 减少对不必要字段的查询
- 尽量使用数值型字段
- 尽量避免使用游标,游标效率差
。。。。。。
11.数据库三范式
第一范式(1NF):强调的是列的原子性,即列不能够再分成其他几列。
第二范式(2NF):首先是 1NF,另外包含两部分内容,一是表必须有一个主键;二是没有包含在主键中的列必须完全依赖于主键,而不能只依赖于主键的一部分。
第三范式(3NF):首先是 2NF,另外非主键列必须直接依赖于主键,不能存在传递依赖。
12.事务
- 什么是事务
是数据库操作的最小工作单位,是指程序中一系列严密的逻辑操作。
- 四大特性
原子性:事务中包含的各操作要么都做,要么都不做。
一致性:事务的执行使数据从一个状态转换为另一个状态,但是对于整个数据的完整性保持稳定。
隔离性:一个事务的执行不能被其它事务干扰,多个并发事务之间要相互隔离。
持久性:指一个事务一旦提交,它对数据库中的数据的改变是永久性的。
- 并发事务导致的问题
脏读:脏读发生在一个事务读取了另一个事务改写但尚未提交的数据时。如果改写在稍后被回滚了,那么第一个事务获取的数据就是无效的。
不可重复读:不可重复读发生在一个事务执行相同的查询两次或两次以上,但是每次都得到不同的数据时。这通常是因为另一个并发事务在两次查询期间进行了更新。
幻读:幻读与不可重复读类似。它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据时。在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录。
13.Redis、MongoDB应用场景
Redis:适用于对读写效率要求都很高,数据处理业务复杂和对安全性要求较高的系统(如新浪微博的计数和微博发布部分系统)。Redis主要把数据存储在内存中,其“缓存”的性质远大于其“数据存储“的性质。
MongoDB:主要解决海量数据访问效率的提升。
14.Redis的数据类型
(string、hash、set、zset、list)
zset:有序集合,不能重复。适合做排行榜,排序需要一个分数属性。
15.Django的框架
(Django重点看一下)
-
框架:MTV模型
模型(Model):负责业务对象与数据库的对象(orm)
模板(Template):负责把数据展示给用户(前端的东西)
视图(View):负责业务逻辑,并在适当的时候会调用Model和Template,相当于模型与模板之间的桥梁
-
ORM框架:(对象-关系映射,在项目与数据库之间起桥梁作用)
核心思想:
用面向对象的方式去操作数据库的创建表、增删改查等操作。把面向对象中的类和数据表进行了一个映射,通过操作类和对象,对数据表实现数据操作,不需要写sql,由orm框架生成。
操作原理:
Django的orm操作本质上会根据对接的数据库引擎,翻译成对应的sql语句;所有使用Django开发的项目无需关心程序底层使用的是MySQL、Oracle、sqlite…,如果数据库迁移,只需要更换Django的数据库引擎即可
优点:
- 数据模型都在一个地方定义,更容易更新和维护,也利于重用代码。
- ORM 有现成的工具,很多功能都可以自动完成,比如数据消毒、预处理、事务等等。
- 它迫使你使用 MVC 架构【模型(model)-视图(view)-控制器(controller)的缩写】,ORM 就是天然的 Model,最终使代码更清晰。
- 基于 ORM 的业务代码比较简单,代码量少,语义性好,容易理解。
- 你不必编写性能不佳的 SQL。
缺点:
- ORM 库不是轻量级工具,需要花很多精力学习和设置。
- 对于复杂的查询,ORM 要么是无法表达,要么是性能不如原生的 SQL。
- ORM 抽象掉了数据库层,开发者无法了解底层的数据库操作,也无法定制一些特殊的 SQL。
ORM单表操作、连表操作、F查询、Q查询
- 当需要字段和字段作比较的时候用F查询
- 当查询条件是 或 的时候用Q查询,因为默认的filter参数都是且的关系
16.Django的请求生命周期
1、浏览器输入url发送访问请求,首先到达django的URL控制器(urls.py)
2、URL控制器通过URL地址分配跳转到相应的View视图(views.py)中的对应函数。
3、View视图如果需要访问数据库操作数据,需要实例化Model模型中的类(models.py),然后通过对类的操作就是对数据库的操作。
4、
a)如果未创建数据库,Model模型里面是以面向对象的形式将每张数据表以类的方式创建出来,然后通过makemigrations就可以同步到数据库来进行表的创建和表关系的建立。
b)如果已创建数据库,并且已经同步数据库,那么实例化类的对象,就可以操作数据库了。
5、返回数据库请求的数据。
6、Model模型将请求的数据返回给View视图。
7、在View视图中,通过对数据的操作或者其他的相应操作、计算等,将数据传递到Template模板。
8、Template模板将View视图中的数据接收,通过将其嵌入到前端页面的代码中,实现可视化展示。
17.Django中的model继承
抽象继承:创建一个通用父类,为了使父类不会被创建,在抽象父类的Meta中设置abstract=True就可以。子类会继承父类相同的字段。
多表继承:从现有的Model继承并让每个Model都有自己的数据表。
代理 model (Proxy models) :只在 model 中修改 Python-level 级的行为,而不涉及字段改变。
18.Scrapy框架、流程
Spider将需要解析的url传给引擎;
引擎传递request请求给调度器,调度器接受请求,压入队列中,进行去重过滤,当引擎需要时,交还给引擎;
引擎将请求传给下载器,下载器下载资源,将获取到的response交还给引擎;
Spider处理所有Response,从中分析提取数据,Item字段需要的数据传给管道进行后期处理。
19.调度器的作用
负责接受引擎发送过来的Request请求,并按照一定的方式进行整理排列,入队,去重过滤。
20.对Channels的了解
21.魔法方法
__init__
构造器,当一个实例被创建的时候初始化的方法,但是它并不是实例化调用的第一个方法。
__new__
才是实例化对象调用的第一个方法,它只取下cls参数,并把其他参数传给__init___
。
___new__
很少使用,但是也有它适合的场景,尤其是当类继承自一个像元祖或者字符串这样不经常改变的类型的时候。
__call__
让一个类的实例像函数一样被调用。
__getitem__
定义获取容器中指定元素的行为,相当于self[key]。
__getattr__
定义当用户试图访问一个不存在属性的时候的行为。
__setattr__
定义当一个属性被设置的时候的行为。
__getattribute___
定义当一个属性被访问的时候的行为。
22.Python2与Python3的区别
- print中Python3必须加括号,Python2 中 print 为 class;
- Python2中使用xrange,Python3中使用range;
- Python2中默认的字符串类型为ASCII,Python3中默认的字符串类型是 Unicode
- Python2中
/
的结果为整型,Python3中为浮点型 - Python2中unicode类型表示字符串序列,str类型表示字节序列;Python3中str类型表示字符串序列,byte类型表示字节序列
- Python2中True和False为两个全局变量,可以随意赋值;Python3把True和False变成了两个关键字,指向了两个固定的对象,不能再被重新赋值。
23.Python 的解释器种类以及相关特点?
Python是强类型(不同数据类型不能做计算)的解释型编程语言(每次执行代码需要重新用解释器编译一遍),属于动态语言(数据类型在执行时确定)(解释型还有Java,编译型执行前,把程序编译成机器语言的文件,运行时不需要重新翻译, C 、C++)
- CPython c 语言开发的,使用最广的解释器
- IPython 基于 cPython 之上的一个交互式计时器,交互方式增强功能和 cPython 一样
- PyPy 目标是执行效率,采用 JIT 技术。对 Python 代码进行动态编译,提高执行效率
- JPython 运行在 Java 上的解释器,直接把 Python 代码编译成 Java 字节码执行
- IronPython 运行在微软 .NET 平台上的解释器,把 Python 编译成 . NET 的字节码。
24.Cookie与Session的区别
cookie:
位于用户的计算机上,用来维护用户计算机中的信息,直到用户删除。
以文本格式存储在浏览器上,存储量有限。
session:
位于web服务器上,主要负责访问者与网站之间的交互,当关闭网站时就表示会话已经结束,网站无法访问该信息了,所以它无法保存永久数据。
存储在服务端,可以无限量存储多个变量并且比cookie更安全。
区别:
(1)Cookie以文本文件格式存储在浏览器中,而session存储在服务端。
(2)Cookie的存储限制了数据量,只允许4KB,而session是无限量的。
(3)我们可以轻松访问cookie值但是我们无法轻松访问session值,因此它更安全。
(4)设置cookie时间可以使cookie过期,但是使用session_destory(),将会销毁session。
25.Tcp与Udp
应用场景:
- Udp面向无连接的,可一对一或一对多,相对Tcp速度更快,实时性更好,耗资源更少,但稳定性、可靠性比tcp差 。适用于多点通信,比如广播通信;当对网络通讯质量要求不高时,要求网络通讯速度能尽量的快,比如语音,实时视频
- Tcp面向连接,且一对一,比Udp稳定、可靠。适合通信质量要求较高的场景,http传输,文件传输,smtp等等。
udp总结:
-
使用udp发送/接收数据步骤:
- 创建客户端套接字
- 发送/接收数据
- 关闭套接字
import socket def main(): #1、创建套接字 udp_socket=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #socket.AF_INET表示IPv4协议,AF_INET6表示IPv6协议 #socket.SOCK_DGRAM 数据报套接字,只要用于udp协议 #2、准备接收方地址 #元组类型,ip是字符串类型,端口号为整型 dest_addr=('192.168.113.111',8888) send_data="我是要发送的数据" #3、发送数据 udp_socket.send(send_data.encode('utf-8'),dest_addr) #4、等待接受方发送的数据,如果没有收到数据则会阻塞等待,直到收到数据 #接收的数据是一个元组 recv_data,addr=udp_socket.recvfrom(1024) #1024表示本次接收的最大字节数 #5、关闭套接字 udp_socket.close() if __name__=='__main__': main()
-
udp绑定端口号
- 创建客户端套接字
- 绑定端口号
- 发送/接收数据
- 关闭套接字
import socket def main(): #1、创建udp套接字 udp_socket=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #socket.AF_INET表示IPv4协议,AF_INET6表示IPv6协议 #socket.SOCK.DGRAM 数据报套接字,只要用于udp协议 #2、绑定端口 local_addr=('',7777) udp_socket.bind(local_addr) #3、准备接收方地址 #元组类型,ip是字符串类型,端口号为整型 dest_addr=('192.168.113.111',8888) send_data="我是要发送的数据" #4、发送数据 udp_socket.send(send_data.encode('utf-8'),dest_addr) #5、等待接受方发送的数据,如果没有收到数据则会阻塞等待,直到收到数据 #接收的数据是一个元组 recv_data,addr=udp_socket.recvfrom(1024) #1024表示本次接收的最大字节数 #6、关闭套接字 udp_socket.close() if __name__=='__main__': main()
使用Socket套接字需要传入哪些参数?
Address Family和Type,分别表示套接字的应用场景还有类型。
family的值可以是AF_UNIX(Unix域,用于同一台机器上的进程间通讯),也可以是AF_INET(AF_INET表示IPv4协议,AF_INET6表示IPv6协议)
type参数,SOCK_STREAM(流套接字)或SOCK_DGRAM(数据报文套接字),SOCK_RAW(raw套接字)。
Tcp服务端创建流程:
- 创建服务端的server_socket,用于监听客户端的请求
- 绑定端口
- server_socket开启监听,由主动连接模式变为被动连接模式
- 假如有客户端的请求,则立即接收,且创建一个与客户端对接的socket,与客户端通信
- 使用新创建的socket与客户端通信
- 关闭与客户端通信的socket,当该socket关闭,则不再与当前的客户端通信
- 关闭用于监听的server_socket,当该socket关闭后,则不再接收新的客户端请求。
http协议:
超文本传输协议:用于web服务器与浏览器之间传输超文本(网页)的协议
http请求报文格式组成:
- 请求行 [请求方式(get post) 请求路径 http版本]
- 请求头 [请求头名称: 头值]
- 空行 [\r\n] 作用: 把请求头与请求体分开
- 请求体 [向服务端发送的请求参数]
浏览器访问网站的过程:
- 用户输入网址.
- 浏览器请求DNS服务器, 获取域名对应的IP地址.
- 请求连接该IP地址服务器.
- 发送资源请求.
- web服务器接收到请求, 并解析请求, 判断用户意图.
- 获取用户想要的资源.
- 将资源返回给http服务器程序.
- http服务器程序将资源数据通过网络发送给浏览器.
- 浏览器解析呈现请求的数据.
短链接与长连接:
-
短连接的特点:
- 管理简单,占用资源相对长连接要少,但是每次请求都需要建立连接和释放连接
- 适合于访问不频繁的操作,比如访问简单的web页面,一次用户注册,一次数据查询,一次文件下载
-
长连接的特点:
- 长连接可以省去较多的TCP建立和关闭的操作,减少浪费,节约时间。但长连接数太多会影响服务端性能,服务端可以通过设置最大连接数和对长连接设置timeout(超时时间)来管理长连接数量。
- 适合于访问频繁的操作,比如即使通信,请求复杂的web页面
详细:tcp的三次握手
- 第一次握手:客户端发送syn报文(syn=j)到服务器,并随机生成一个序列号,等待服务器端确认;(客户端进入SYN_SEND状态)
- 第二次握手:服务器端收到syn报文,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN报文(syn=k),即SYN+ACK报文。(服务器端进入SYN_RECV状态)
- 第三次握手:客户端收到服务器的SYN+ACK报文,向服务器发送ACK报文(ack=k+1)(发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手,客户端与服务器开始传送数据。)
详细:tcp的四次挥手
- 第一次挥手:客户端发送一个FIN报文给服务器端,请求通信关闭,客户端进入FIN_WAIT_1状态。
- 第二次挥手: 服务器端收到FIN后,发送一个ACK给客户端,确认序号为收到序号+1,服务器端进入CLOSE_WAIT状态。
- 第三次挥手: 服务器端发送一个FIN,请求关闭通信,服务器端进入LAST_ACK状态。
- 第四次挥手:客户端收到FIN后,客户端进入TIME_WAIT(TIME_WAIT等待2MSL时间,范围在1-4分钟)状态,接着发送一个ACK给服务器端,确认序号为收到序号+1,服务器端进入CLOSED状态,完成四次挥手。
(2MSL等待的原因:报文段有生存时间,当连接关闭时,有可能收到迟到的报文段。这时,若立马就建立新的连接(同一端口),那么新的连接就会接收迟到的报文,误以为是发给自己的。另一个原因是可靠的实现全双工连接的终止。)
全双工数据传输是一种在同一时间内数据可双向流动的传输模式
TCP应答机制:
- 超时重传
- 错误校验
- 流量控制和阻塞管理
TCP/IP协议:
网络层(IP)、传输层(Tcp/Udp)、应用层(HTTP/RTSP/FTP)、链路层。
26.HTTP请求主要分为Get
和Post
区别
- GET是从服务器上获取指定页面信息,POST是向服务器提交数据并获取页面信息。
- GET请求参数都显示在URL上,服务器根据该请求所包含URL中的QueryString参数来产生响应内容。 “Get” 请求的参数是URL的一部分。
- POST请求参数在请求体Formdata中,消息长度没有限制而且以隐式的方式进行发送,通常用来向HTTP服务器提交量比较大的数据(比如请求中包含许多参数或者文件上传操作等)。 "POST"请求的参数不在URL中,而在请求体中。
27.HTTP和HTTPS的主要区别
- https协议需要到CA申请证书,一般免费证书较少,因而需要一定费用。
- http和https用的端口不一样,前者是80,后者是443。
- http是超文本传输协议,https是HTTP的安全版,在HTTP基础上增加了SSL加密传输协议。
- http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
28.模块和包
模块是搭建程序的一种方式,每一个Python代码文件都是一个模块。并且可以引用其他模块,比如对象和属性。
一个包含许多Python代码的文件夹就是一个包,包可以包含模块和子文件夹。
29.猴子补丁
所谓的猴子补丁,是指在运行时修改类或模块,而不去改变源码,达到hot patch的目的。
30.常用的Linux命令
ls
查看目录中的文件
pwd
显示工作路径
cd ..
返回上一级目录
mkdir
创建目录
rm
删除文件
mv
移动文件/重命名
cp
拷贝文件
ps
查看系统进程
kill
终止系统进程
find
查找文件
groupadd group_name
创建一个新的用户组
31. Linux关机命令
reboot
重新启动操作系统
shutdown -r now
重新启动操作系统,shutdown会给别的用户提示
shutdown -h now
立刻关机,其中now相当于时间为0的状态
shutdown -h 20:25
系统在今天的20:25 会关机
shutdown -h +10
系统再过十分钟后自动关机
init 0
关机
init 6
重启
32.垃圾回收机制
- 引用计数: 当一个 Python 对象被引用时其引用计数增加1, 当其不再被一个变量引用时则计数减 1。当 Python 的某个对象的引用计数为 0 时,说明没有任何引用指向该对象,该对象就成为要被回收的垃圾了。
- 分代收集:Python将内存根据对象的存活时间划分为不同的集合,分别为年轻代(第0代)、中年代(第1代)、老年代(第2代),他们对应的是3个链表。新创建的对象都会分配在0代,0代链表的总数达到上限时,Python垃圾回收机制就会被触发,把那些可以被回收的对象回收掉,而那些不会回收的对象就会被移到1代去,依此类推,2代中的对象是存活时间最久的对象。
- 标记清除:如果两个对象的引用计数都为 1,但是仅仅存在他们之间的循环引用,那么这两个对象都是需要被回收的,也就是说,它们的引用计数虽然表现为非 0,但实际上有效的引用计数为 0。所以先将循环引用摘掉,就会得出这两个对象的有效计数。
(拓展内存管理机制:引用计数、垃圾回收、内存池。)
33.Python的参数传递
位置参数、默认参数、可变参数、关键字参数。
函数的传值到底是值传递还是引用传递,要分情况:不可变参数用值传递,可变参数是引用传递的。
缺省参数:
缺省参数指没有参数传递时使用默认值,有传递参数时使用传递值,不用默认值。
*args 是不定长参数,他可以表示输入参数是不确定的,可以是任意多个,输出的结果为元组。
**kwargs 是关键字参数,就是形参中按照关键字传值把多余的传值以字典的方式呈现。
34.内建函数
map函数:,第一个参数是函数,第二个是序列(列表或元组)。其中,函数(即 map的第一个参数位置的函数)可以接收一个或多个参数。
**reduce函数:**第一个参数是函数,第二个是序列(列表或元组)。但是,其函数必须接收两个参数。
35.递归函数停止的条件
递归的终止条件一般定义在递归函数内部,在递归调用前要做一个条件判断,根据判断的结果选择是继续调用自身,还是 return,返回终止递归
条件:
- 判断递归的次数是否达到某一限定值
- 判断运算的结果是否达到某个范围等
36.yield的用法
yield就是保存当前程序执行状态。用for循环时,每次取一个元素就会计算一次。用yield的函数叫generator生成器,好处是不用一次计算所有元素,而是用一次计算一次,可以节省很多空间。生成器每次计算需要上次计算结果,所以用 yield,否则一return,上次计算结果就没了。
def createGenerator():
mylist=range(3)
for i in mylist:
yield i*i
mygenerator=createGenerator()
print(mygenerator)
for i in mygenerator:
print(i)
#输出结果:
<generator object createGenerator at 0x072A7570>
0
1
4
37.对面向对象的理解
面向对象是相对于面向过程而言的。
面向过程语言是一种基于功能分析的、以算法为中心的程序设计方法;
而面向对象是一种基于结构分析的、以数据为中心的程序设计思想。在面向对象语言中有一个有很重要东西,叫做类。 面向对象有三大特性:封装、继承、多态。
38.用Python匹配html tag时,<.*>
和<.*?>
的区别?
<.*>
是贪婪匹配,会从第一个”<“开始匹配,直到最后一个">"中间所有的字符都会匹配到,中间可能会包含”<>“
<.*?>
是非贪婪匹配,会从第一个”<“开始匹配,遇到第一个">"结束匹配,中间的字符都会匹配到,但是不会有”<>“
39.Http常见请求头
- Host(主机和端口号)
- Connection(链接类型)
- User-Agent(浏览器名称)
- Accept(传输文件类型)
- Accept-Encoding(文件编解码格式)
- Referer(页面跳转处)
- Cookie
40.url的形式
形式 scheme://host[:port#]/path/.../[?query-string][#anchor]
scheme:协议(例如:http,https,ftp)
host:服务器的IP地址或者域名
port:服务器的端口(如果是走协议默认端口,80 or 443)
path:访问资源的路径
query-string:参数,发送给http服务器的数据
anchor:锚(跳转到网页指定锚点位置)
#demo
http://localhost:4000/file/part01/1.2.html
http://item.jd.com/11936238.html#product-detail