type
status
date
slug
summary
tags
category
icon
password
comment
说说什么是解释性语言,什么是编译性语言?
计算机不能直接理解高级语言,只能理解机器语言,所以必须要把高级语言翻译成机器语言,计算机才能执行高级语言编写的程序。
解释性语言在运行程序的时候才会进行翻译。
编译型语言写的程序在执行之前,需要一个专门的编译过程,把程序编译成机器语言(可执行文件)。
说是Python程序运行过程?
Python程序在解释器上执行分两个过程:
编译:
首先把程序的字节码保存为一个以.pyc为扩展名的文件。作为一种启动速度的优化,下一次运行程序时,如果没有修改过源码的话,Python将会加载.pyc文件并跳过编译这个步骤。
执行:
当程序编译成字节码后,发送到Python虚拟机上来执行。虚拟机是Python的运行引擎。是Python解释器的最后一步。
注:解释器即让其他程序运行起来的程序,是代码与机器的计算机硬件之间的软件逻辑层。Python也是一个名为解释器的软件包。
说说Python的作用域?
Python中的作用域分4种情况:
L:local,局部作用域,即函数中定义的变量;
E:enclosing,嵌套的父级函数的局部作用域;
G:global,全局变量,就是模块级别定义的变量;
B:built-in,系统固定模块里面的变量,比如int,bytearray等。搜索变量的优先级顺序依次是:作用域局部>外部作用域>当前模块中的全局>python内置作用域,也就是LEGB。
说说Python的数据结构?
Python中绝大部分数据结构都可以被最终分解为三种类型:集合(Set),序列(Sequence),映射(Mapping).
集合是独立于标量,序列和映射之外的特殊数据结构,它支持数学理论的各种集合的运算。它的存在使得用程序代码实现数学理论变得方便。
序列是Python中最为基础的内建类型。它分为其中类型:列表、字符、元祖、Unicode字符串、字节数组、缓冲区和xrange对象。常用的是:列表(List)、字符串(String)、元祖(Tuple).
映射在Python的实现是数据结构字典(Dictionary).作为第三种基本单位,映射的灵活使得它在多种场合中都有广泛的应用和良好的可拓展性。
说说Python中可变与不可变类型?
Python可变类型是列表、集合、字典,不可变有字符串、元祖、数字。
说说进程与线程?
进程:一个运行的程序就是一个进程,没有运行的代码叫程序,进程是系统资源分配的最小单位,进程拥有自己独立的内存空间,所有进程间数据不共享,开销大。
线程:cpu调度执行的最小单位,也叫执行路径,不能独立存在,依赖进程存在,一个进程至少有一个线程,叫主线程,而多个线程共享内存(数据共享,共享全局变量),从而极大提高了程序的运行效率。
说说Python中的多线程?
Python在任意时刻,只有一个线程在解释器中运行。对Python虚拟机的访问由全局解释器锁(GIL)来控制,正是这个锁能保证同一时刻只有一个线程在运行。
多线程共享主线程的资源,所以可能还会改变其中的变量,这个需要加上线程锁,每次执行完一个线程再执行下一个线程。
一个CPU在同一个时刻只能执行一个线程,但是当遇到IO操作或者运行一定的代码量的时候就会释放全局解释器锁,执行另外一个线程。
说说Python中的多进程?
Python中的多进程是通过multiprocessing包来实现,每个进程中所有数据(包括全局变量)都各自拥有一份,互不影响。它可以利用Process类来创建一个进程对象。
进程对象的方法和线程对象的方法差不多,也有start(),run(),join()等,但是,Thread线程对象中的守护线程方法是setDeamon,而Process进程对象的守护进程是通过设置deamon属性来完成。
说说Python互斥锁与死锁?
互斥锁:即确保某段关键代码的数据只能由一个线程从头到尾完整执行,保证了这段代码数据的安全性,但是这样就会导致死锁。
死锁:多个子线程在等待对方解除占用状态,但是都不先解锁,互相等待,这就是死锁。
说说Lambda?
lambda函数是一个可以接受任意多个参数(包括可选参数)并且返回单个表达式值的函数
lambda函数比较轻便,即用即扔,很适合需要完成一项功能,但是此功能只在一处使用,连名字都很随意的情况
匿名函数,一般用来给filter,map这样的函数式编程服务
作为回调函数,传递给某些应用,比如消息处理。
说说Python的深拷贝与浅拷贝?
浅拷贝(copy):创建新对象,其内容是原对象的引用。拷贝父对象,不会拷贝对象的内部子对象。
深拷贝(deepcopy):copy模块的deepcopy方法,完全拷贝了父对象及其子对象。深拷贝出来的对象是一个全新的对象,不在与原来的对象有任何关联。
说说Python多线程是否能用多个CPU,为什么?
Python的多线程不能利用多核CPU。
因为Python解释器使用了GIL锁,在任何时刻只允许单个Python线程运行。无论系统有多个CPU核心,Python程序只能在一个CPU上运行。
注:GIL的功能是:在CPython解释器执行的每一个Python线程,都会先锁住自己,以阻止别的线程执行。
说说Python垃圾回收机制?
Python的垃圾回收机制是以:引用计数器为主,标记清除和分代回收为辅。
方式1:引用计数:每个对象内部都维护了一个值,该值记录此对象被引用的次数,如果次数为0,则Python垃圾回收机制会自动清除此对象。
方式2:标记-清除:被分配对象的计数值与被释放对象的计数值之间的差异累计超过某个阈值,则Python的收集机制就启动。
标记阶段:遍历所有对象,如果是可达的,也就是还有对象引用它,那么就标记该对象可达;
清除阶段:再次遍历对象,如果发现某个对象没有标记可达,则就将其回收。
方式3:分代回收:当代码中主动执行gc.collect()命令时,Python解释器就会进行垃圾回收。
总体来说,在Python中,主要通过引用计数进行垃圾回收;通过标记-清除解决容器对象可能产生的循环引用问题;通过分代回收以空间换时间的方法提高垃圾回收效率。
说说Python里的生成器?
生成器是一种可以简单有效的创建迭代器的工具。像常规函数一样撰写,但是在需要返回数据的时候使用yield语句。每当对它调用next()函数,生成器从它上次停止的地方重新开始。
说说迭代器与生成器的区别?
迭代器有2个方法next方法和iter方法,iter方法获取对象的迭代器,next方法返回下一个迭代器。
生成器:使用了yield的函数被称为生成器(generator),在调用生成器的过程中,每次遇到yield时函数会暂停并保存当前所有的运行信息,返回yield的值并在下一次执行next()方法时从当前位置继续运行。调用一个生成器函数,返回的是一个迭代器对象。
区别:
语法:生成器是通过函数的形式中调用yield或者()的形式创建的;迭代器可以通过iter()内置函数创建
用法:生成器在调用next()函数或for循环中,所有过程被执行,且返回值;迭代器在调用next()函数或for循环中,所有值被返回,没有其他过程或动作。
总结:
迭代器:在循环遍历自定义容器对象时,会使用python内置函数iter()调用遍历对象的iter(self)获得一个迭代器,之后再循环对这个迭代器使用next()调用迭代器对象的next(self).
生成器:只能遍历一次,是一类特殊的迭代器。生成器能做到迭代器能做的所有事,而且因为自动创建了iter()和next()方法,生成器显得特别简洁,而且生成器也是高效的,使用生成器表达式取代列表解析可以同时节省内存。除了创建和保存程序状态的自动方法,当生成器终结时,还会自动抛出Stopiteration异常。