① 深浅拷贝的区别
1.copy 和 deepcopy 的根本区别就是内存地址和数值的不同复制的区别
深浅拷贝都是对象的拷贝都会生成一个看起来与原对象相同的对象,它们的本质区别就是拷贝出来的对象地址是否和原对象一致。
2.浅拷贝是对一个对象父级外层的表面复制 并不会拷贝子级内部数据不会被复制
浅拷贝的不同数据类型
对于可变数据类型 不会拷贝深层次的索引 浅拷贝会开辟新的内存空间去存放
对于不可变的数据类型 浅拷贝对象的时候,引用对象的地址空间
3.深拷贝是对所有层级的拷贝,递归 内部外部都会被拷贝进去
对于可变的数据类型 深拷贝可以将内部外部全部直接复制
对于不可变数据类型 深拷贝会同浅拷贝一样,是对地址的引用。
② 面向对象的特性
1.封装 根据职责将属性和方法封装到一个抽象的类中定义类的准则
2.继承 实现代码的重用 相同的代码不必重复的编写 减少代码冗余 子类继承父类
3.多态 不同的子类调用相同的父类产生不同的结果
③ 闭包的含义
闭包是有两个函数嵌套定义的, 内部函数调用外部函数的变量值,变量值加上内部还是里面的代码组成的代码块组成一个新的内存空间,我们把这个空间叫做闭包 闭包 = 函数 + 环境变量 (在函数定义的时候定义 ,不是全局变量,这个环境变量一定要被内部函数调用才算是闭包
④ 匿名函数 / 函数 / 闭包 /对象 在做实参的时候的区别是什么?
'''
lambda function 函数嵌套 object
1.lambda 匿名函数 能够完成基本的简单功能 节省创建函数对象的流程 传递是这个函数的引用 只有功能
2.function 普通函数 能够完成函数的普通功能 传递是这个函数的引用 只有功能
3.函数嵌套 闭包 能够完成复杂的功能函数 传递的是闭包函数中的函数和数据 传递是功能和数据
4.object 对象 能够完成复杂的功能 可传递多个数据和很多功能 因此是数据+功能
'''
⑤ 进程线程协程的解释含义和区别 以及各自的优缺点
'''
进程线程协程的含义 区别 适用于那种场景类型
含义*
1.1.进程是系统中进行资源分配和资源调度的一个独立单位 一个程序至少有一个进程 一个进程至少有一个线程
1.2.线程是进程的一个实体,是cpu调度和分派的基本单位 线程是比进程更小的可以独立运行的基本单位
线程不拥有系统资源,拥有的是在运行时不可少的计数器寄存器和栈 在进程中的线程可以共享在进程中的其他资源
线程是不能独立执行的,必须依存在进程中
1.3.协程是一种比线程更加轻量级的存在,一个线程可以有多个协程
区别*
2.1. 进程切换需要的资源很大,效率低
2.2. 线程切换需要的资源相对于进程较低, 效率相对于进程高一点
2.3. 协程切换任务资源很小,三者中效率最高。
2.4. 多进程 多线程 根据CPU核数不一样可能是并行 但是协程在一个线程中所以是并发
适用的场景类型*
3.1. 计算密集型 进程 process
3.2. IO密集型 线程thread 协程 多线程
协程比线程快的原因
4.1. 高并发 + 高扩展性 + 低成本 一个CPU支持上万个协程都不是问题,很适合用于高并发处理协程
所以很适用于高并发处理协程能保留上一次调用时的状态,不管是进程还是线程,每次阻塞切换都需要陷入系统调用,
使用线程时需要小心的处理同步问题,而协程完全不存在这个问题
'''
⑥ 装饰器 生成器 迭代器的解释 区别 特点
'''
迭代器 iterator 可以将迭代对象直接迭代出来 list for迭代循环
for和迭代的区别就是 迭代是next循环出来每个值
迭代是将集合中的元素访问出来,迭代器保存的是获取数据的方式而不是结果所以想用的时候就可以生成
可以节省大量内存空间,它是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问
直到所有的元素被访问完结束。迭代器只能往前不能后退
迭代器的创建有两种方式 iter() next() 字符串列表或者元组对象均可以创建迭代对象
生成器genetor 的概念
所谓生成器就是一边循环一边计算的机制,使用了yield的函数被称为生成器
生成器是一个返回迭代器的函数 只能用于迭代操作 简单理解就是生成器就是一个特殊的迭代器
在调用生成器运行的过程中遇到yield时函数会暂停并且保存当前所运行的信息 返回yield值
并且在下一次执行next方法时 从当前位置继续执行
生成器和迭代器的区别
generator iterator
使用for循环遍历的是可迭代对象
迭代方法就是加next方法就是迭代器
生成器是特殊的迭代器 生成器可以做到迭代器的所有动作和行为
自动创建了next和iter方法 生成器就会显得特别简洁高效
使用生成器表达式取代列表解析可以同时节省内存空间
为什么要使用生成器
可迭代对象(列表 字符串 元组 )所有的数据都在内存中会非常耗费内存
如果说只是想要访问后面的数据就会严重耗费内存 如果说列表元素按照某种算法推算出来,
我们就可以在循环的过程中不断推算出后续元素,
这样不必创建完整的list 这样可以节省空间
想要得到庞大的数据又不想占据空间的话这个时候就要使用生成器则为 iter next
生成器仅仅保存了一套生成数值的算法,并且没有让这个算法直接执行,我什么时候调用它,他就开始计算一个新的值并且给你返回。
什么是装饰器 为什么要使用它
装饰器本身是函数 这个函数的主要作用是包装另外一个函数或者类
包装的目的是不改变原来函数的情况下改变被包装对象的行为
接受一个函数,内部进行包装,然后返回一个新函数
通过高阶函数传递函数参数,新函数增加旧函数的需求,然后执行旧函数
在django中middleware中间件 其实就是高级的装饰器
⑦ 对GIL的解释和什么时候释放GIL锁 互斥锁和GIL的区别
什么是GIL锁*
global lock GIL锁是python中的全局解释器锁,一个进程中有多个线程,当这个线程运行的时候就会霸占GIL锁
当霸占这个GIL锁的时候就会阻止其他线程继续运行,当这个线程执行完之后,才会继续执行之后的线程。
如果线程中遇到耗时操作IO密集型任务,解释器锁会解开,使得其他线程运行。
所以说在多线程中,线程的运行是有先后顺序的并不是同时进行
什么时候释放GIL锁*
1.时间片耗尽 cpu时间
2.任务遇到IO等待时间
3.执行任务结束
4.执行到字节码阈值时
互斥锁和GIL的区别
互斥锁在多线程的情况下,确保当前线程执行完之后,继续下个任务,如果说当前任务仍然在执行的时候,下个任务会阻塞
GIL锁是保证在同一时间有一个线程,当释放掉GIL的时候,会继续下一个线程
但是也有可能是IO流阻塞,并没有完成该线程任务就直接释放,该线程的任务分多少次执行完这个会安装GIL默认策略。
互斥锁是必须保证当前任务在当前线程的完成
GIL锁是不一定在当前线程完成任务 情况是IO流阻塞的时候,直接停止当前线程继续下次线程
网友评论