解释型和编译型语言的区别
注意:Java 有些特殊,java程序也需要编译,但是没有直接编译成为机器语言,而是编译称为字节码,然后用解释方式执行字节码。
简述下 Python 中的字符串、列表、元组和字典
字符串(str):字符串是用引号括起来的任意文本,是编程语言中最常用的数据类型。
列表(list):列表是有序的集合,可以向其中添加或删除元素。
元组(tuple):元组也是有序集合,元组中的数无法修改。即元组是不可变的。
字典(dict):字典是无序的集合,是由键值对(key-value)组成的。
集合(set):是一组 key 的集合,每个元素都是唯一,不重复且无序的。
is 和 == 的区别
==是比较操作符,只是判断对象的值(value)是否一致,而 is 则判断的是对象之间的身份(内存地址)是否一致。对象的身份,可以通过 id() 方法来查看。
简述read、readline、readlines的区别
①read读取整个文件
②readline读取下一行数据
③readlines读取整个文件到一个迭代器以供我们遍历(读取 到一个list中,以供使用,比较方便)
python中match()和search()的区别?
match()函数只检测RE是不是在string的开始位置匹配,
search()会扫描整个string查找匹配, 也就是说match()只有在0位置匹配成功的话才有返回,如果不是开始位置匹配成功的话,match()就返回none
线程中start方法和run方法的区别?
①若调用start,则先执行主进程,后执行子进程;
②若调用run,相当于正常的函数调用,将按照程序的顺序执行
介绍一下except的用法和作用?
捕获try except中间代码发生的异常,如果发生异常执行except的代码,不管是否发生异常都执行finally中的代码
except可以有0个或多个,如果有多个从上到下依次根据异常类型匹配,匹配某个Exception这执行对应的except中代码
Python 函数中的参数类型
位置参数,默认参数,可变参数,关键字参数。
*arg 和 **kwarg 作用
允许我们在调用函数的时候传入多个实参
>>> def test(*arg, **kwarg):
... if arg:
... print("arg:", arg)
... if kwarg:
... print("kearg:", kwarg)
...
>>> test('ni', 'hao', key='world')
arg: ('ni', 'hao')
kearg: {'key': 'world'}
可以看出,*arg 会把位置参数转化为 tuple,**kwarg 会把关键字参数转化为 dict。
py的语言特性: 动态强类型
静/动态: 编绎/运行 时确定变量类型
弱/强类型: 会/不会发生隐式类型转换
py作为后端语言的优缺点
pytorch和tensorflow的区别
运算差异:前者是一个动态的框架,所谓动态框架,就是说在运算过程中,会根据不同的数值,按照最优方式进行合理安排。而相对来说后者属于静态框架,所谓静态框架,就是只需要建构一个tensorflow的计算图,然后才能够将不同的数据输入进去,进行运算,这世界上就带来了一个非常严重的问题,那就是计算的流程处于固定状态,这种不灵活的运算方式,必然会导致在结算结果上效率比较低下。从运算过程的区别来看,pytorch的优势比较明显。
使用对象:Pytorch,相对来说更能够在短时间内建立结果和方案更适合于计算机程序爱好者或者是小规模项目,包括研究人员。而tensorflow则更适合在大范围内进行操作,尤其是对于跨台或者是在实现嵌入式部署的时候更具优势。
灵活性
tensorflow:静态计算图,数据参数在CPU与GPU之间迁移麻烦,调试麻烦
pytorch:动态计算图,数据参数在CPU与GPU之间迁移十分灵活,调试简便
计算速度
同等条件下:
tensorflow 在CPU上运行速度比 pytorch 快
tensorflow 在GPU上运行速度和 pytorch 差不多
数据加载
tensorflow:API设计庞大,使用有技巧,但有时候不能直接把数据加载进TensorFlow
pytorch:API整体设计粗糙,但加载数据的API设计很友好。加载数据的接口由一个数据集、一个取样器和一个数据加载器构成。
设备管理
tensorflow:不需要手动调整,简单
pytorch:需要明确启用的设备
python的装饰器
本质上是一个python函数。它经常用于有切面需求的场景。比如:插入日志、性能测试、事务处理、缓存、权限校验等
作用:
它能使函数的功能得到扩充,而同时不用修改函数本身的代码。
它能够增加函数执行前、执行后的行为,而不需对调用函数的代码做任何改变。
Python的垃圾回收机制
python垃圾回收机制以引用计数为主,标记-清除和分代回收为辅。
引用计数:Python在内存中存储每个对象的引用计数,对象被引用了计数加一,对象被释放了,计数减一,如果计数变成0,该对象就会消失,分配给该对象的内存就会释放出来。
标记-清除:是一种基于追踪回收(tracing GC)技术实现的垃圾回收算法。它分为两个阶段:第一阶段是标记阶段,GC会把所有的活动对象打上标记,第二阶段是把那些没有标记的对象非活动对象进行回收。对象之间通过引用(指针)连在一起,构成一个有向图,对象构成这个有向图的节点,而引用关系构成这个有向图的边。从根对象(root object)出发,沿着有向边遍历对象,可达的(reachable)对象标记为活动对象,不可达的对象就是要被清除的非活动对象。根对象就是全局变量、调用栈、寄存器。主要处理容器对象
分代回收:Python将内存根据对象的存活时间划分为不同的集合,每个集合称为一个代,Python将内存分为了3“代”,分别为年轻代(第0代)、中年代(第1代)、老年代(第2代),他们对应的是3个链表,它们的垃圾收集频率与对象的存活时间的增大而减小。新创建的对象都会分配在年轻代,年轻代链表的总数达到上限时,Python垃圾收集机制就会被触发,把那些可以被回收的对象回收掉,而那些不会回收的对象就会被移到中年代去,依此类推,老年代中的对象是存活时间最久的对象,甚至是存活于整个系统的生命周期内。
Python多线程(multi-threading)
Python并不支持真正意义上的多线程,Python提供了多线程包。
Python中有一个叫Global Interpreter Lock(GIL)的东西,它能确保你的代码中永远只有一个线程在执行。经过GIL的处理,会增加执行的开销。这就意味着如果你先要提高代码执行效率,使用threading不是一个明智的选择,当然如果你的代码是IO密集型,多线程可以明显提高效率,相反如果你的代码是CPU密集型的这种情况下多线程大部分是鸡肋。
什么是lambda表达式?它有什么好处?
简单来说,lambda表达式通常是当你需要使用一个函数,但是又不想费脑袋去命名一个函数的时候使用,也就是通常所说的匿名函数。
lambda表达式一般的形式是:关键词lambda后面紧接一个或多个参数,紧接一个冒号“:”,紧接一个表达式。lambda表达式是一个表达式不是一个语句。
pass语句有什么作用
pass语句不会执行任何操作,一般作为占位符或者创建占位程序。
Python里面如何拷贝一个对象?
Python中对象之间的赋值是按引用传递的,如果要拷贝对象需要使用标准模板中的copy
copy.copy:浅拷贝,只拷贝父对象,不拷贝父对象的子对象。
copy.deepcopy:深拷贝,拷贝父对象和子对象。
__new__和__init__的区别。
__init__为初始化方法,__new__方法是真正的构造函数。
__new__是实例创建之前被调用,它的任务是创建并返回该实例,是静态方法
__init__是实例创建之后被调用的,然后设置对象属性的一些初始值。
总结:__new__方法在__init__方法之前被调用,并且__new__方法的返回值将传递给__init__方法作为第一个参数,最后__init__给这个实例设置一些参数。
Python中单下划线和双下划线分别是什么。
__name__:一种约定,Python内部的名字,用来与用户自定义的名字区分开,防止冲突
_name:一种约定,用来指定变量私有
__name:解释器用_classname__name来代替这个名字用以区别和其他类相同的命名
什么是自省?
运行时判断一个对象的类型的能力
python一切皆对象、用type、id、isinstance获取对象类型信息
什么是生成器?
生成器是一种可迭代对象,可以挂起并保持当前的状态
生成器遇到yield处会停止执行,调用next()或send()才会继续执行
定义一个生成器有两种方式,一种是生成器推导式,一种是在普通函数中添加yield语句并实例化
迭代器和可迭代对象的区别
可迭代对象类,必须自定义__iter__()魔法方法,range,list类的实例化对象都是可迭代对象
迭代器类,必须自定义__iter__()和__next__()魔法方法,用iter()函数可以创建可迭代对象的迭代器
async和await的作用
async: 声明一个函数为异步函数,函数内只要有await就要声明为async
await: 搭配asyncio.sleep()时会切换协程,当切换回来后再继续执行下面的语句
Python 中的反射
反射就是通过字符串的形式,导入模块;通过字符串的形式,去模块寻找指定函数,并执行。利用字符串的形式去对象(模块)中操作(查找/获取/删除/添加)成员,一种基于字符串的事件驱动!
metaclass 元类
类与实例:首先定义类以后,就可以根据这个类创建出实例,所以:先定义类,然后创建实例;
类与元类:先定义元类, 根据 metaclass 创建出类,所以:先定义 metaclass,然后创建类。
简述闭包
如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)。
闭包特点: