算法基础面试题(面试必看 )
下面是好好范文网小编收集整理的算法基础面试题(面试必看 ),仅供参考,欢迎大家阅读!
本合集整理了计算机专业相关算法/开发面试中遇到的【python基础】相关面试题,后续会持续更新,有需要的小伙伴可以点赞or收藏随时查阅哦!♥
可变对象:list dict set
不可变对象:tuple string int float bool
可变对象是可以直接被改变的(地址不变),不可变对象反之(创建新对象后开辟新的地址)。在Python中,数字、字符或者元组等不可变对象类型都属于值传递,而字典dict或者列表list等可变对象类型属于引用传递。python不允许程序员选择采用传值还是传引用。
如果要想修改新赋值后原对象不变,则需要用到python的copy模块,即对象拷贝。
Q:python深拷贝?浅拷贝?
直接赋值:其实就是对象的引用(别名)。
Python中对象的赋值都是进行对象引用(内存地址)传递。
使用copy.copy(),可以进行对象的浅拷贝,它复制了对象,但对于对象中的元素,依然使用原始的引用。
如果需要复制一个容器对象,以及它里面的所有元素(包含元素的子元素),可以使用copy.deepcopy()进行深拷贝。
对于非容器类型(如数字、字符串、和其他'原子'类型的对象)没有被拷贝一说。
如果元组变量只包含原子类型对象,则不能深拷贝。
Q:python容器?生成器?
容器是一系列元素的集合,str、list、set、dict、file、sockets对象都可以看作是容器,容器都可以被迭代(用在for,while等语句中),因此他们被称为可迭代对象。
可迭代对象实现了__iter__
方法,该方法返回一个迭代器对象。
迭代器持有一个内部状态的字段,用于记录下次迭代返回值,它实现了__next__
和__iter__
方法,迭代器不会一次性把所有元素加载到内存,而是需要的时候才生成返回结果。
生成器是一种特殊的迭代器,它的返回值不是通过return
而是用yield
。
Q:*Args 与 **kwargs?
*args是可变的positional arguments列表,**kwargs是可变的keyword arguments列表;
*args必须位于**kwargs之前,因为positional arguments必须位于keyword arguments之前;
*args表示任何多个无名参数,它是一个tuple;**kwargs表示关键字参数,它是一个dict。
Q:python2和python3区别?
Python3 使用 print 必须要以小括号包裹打印内容,比如 print('hi'), Python2 既可以使用带小括号的方式,也可以使用一个空格来分隔打印内容,比 如 print 'hi';
python2 range(1,10)返回列表,python3中返回迭代器,节约内存;
python2中使用ascii编码,python中使用utf-8编码;
python2中unicode表示字符串序列,str表示字节序列, python3中str表示字符串序列,byte表示字节序列;
python2中为正常显示中文,引入coding声明,python3中不需要;
python2中是raw_input()函数,python3中是input()函数。
Q:Python内存?
动态类型:Python中不但变量名无需事先声明,而且也无需类型声明。在Python语言中,对象的类型和内存占用都是运行时确定的。尽管代码被编译成字节码,Python仍然是一种解释型语言。在赋值时解释器会根据语法和右侧的操作数来决定新对象的类型。在对象创建后,一个该对象的应用会被赋值给左侧的变量。
python内存分配?
作为一个负责任的程序员,我们知道在为变量分配内存时,是在借用系统资源,在用完之后,应该释放借用的系统资源。Python解释器承担了内存管理的复杂任务,这大大简化了应用程序的编写。
引用计数
Python内部记录着所有使用中的对象 各有多少引用。一个内部跟踪变量,称为引用计数器。每个对象各有多少个引用,简称引用计数。当对象被创建时,就创建了一个引用计数,当这个对象不再需要时,也就是说,这个对象的引用计数变为0时,它被垃圾回收。(并不是100%这样)
增加引用计数?
当对象被创建并赋值给变量时,该对象的引用计数就被设置为1。
当同一个变量又被赋值给其他变量时,或作为参数传递给函数、方法或类实例,或者被赋值为一个窗口对象的成员时,该对象的一个新的引用,或者称为别名,就被创建(则该对象的引用计数就自动加1)。
如下代码:
语句x=3,将3赋值给x。x是第一个引用,因此,该对象的引用计数被设置为1。语句y=x创建了一个指向同一对象的别名y。事实上并没有为y创建一个新的对象,而是该对象的引用计数增加了一次(变成了2)。这是对象引用计数增加的方式之一。还有一些其他的方式也能增加对象的引用计数,比如该对象作为参数被函数调用或这个对象被加入到某个列表等对象当中。
总之,对象的引用计数增加是:
对象被创建
2. 另外的别名被创建
3. 作为参数传递给函数
4. 成为容器对象的一部分
减少引用计数?
当对象的引用被销毁时,引用计数会减小。最明显的例子就是当引用离开其作用范围时,这种情况最经常出现在函数运行结束时,所有的局部变量都被自动销毁,对象的引用计数也就随之减少。
当变量被赋值给另外一个对象时,原对象的引用计数也会自动减1:
当字符串对象“xyz”被创建并赋值给foo时,它的引用计数是1。当增加一个别名bar时,引用计数变成了2。不过当foo被重新赋值给整型对象123时,xyz对象的引用计数自动减1,又重新变成了1。
其他造成对象引用计数减少的方式包括使用del语句删除一个变量,或者当一个对象被移出一个窗口对象时。
引用计数减少
一个本地引用离开了其作用的范围。比如foo() 函数结束时。
对象别名被显式销毁
3. 对象的一个别名被赋值给其他对象
4. 对象被从一个窗口对象中移除
5. 窗口对象本身被销毁
Q:python垃圾回收?
不再使用的内存会被一种称为垃圾收集的机制释放。像上面说的,虽然解释器跟踪对象的引用计数,但垃圾收集器负责释放内存。垃圾收集器是一块独立代码,它用来寻找计数为0的对象。它也负责检查那些虽然引用计数大于0但也应该被销毁的对象。特定情形会导致循环引用。
Q:python多进程多线程GIL?
对于任何Python程序,不管有多少的处理器,任何时候都总是只有一个线程在执行。
因为Python的线程虽然是真正的线程,但解释器执行代码时,有一个GIL锁:Global Interpreter Lock,任何Python线程执行前,必须先获得GIL锁,然后,每执行100条字节码,解释器就自动释放GIL锁,让别的线程有机会执行。这个GIL全局锁实际上把所有线程的执行代码都给上了锁,所以,多线程在Python中只能交替执行,即使100个线程跑在100核CPU上,也只能用到1个核。- GIL(global intepreter lock, 即全局解释锁),GIL的存在使得Python字节码在同一个进程内只能串行执行,所以Python多线程是一个伪并行.
简单来说,Python全局解释器锁是一个互斥锁,它只允许一个线程来控制Python解释器。
注:本文答案多数来自网络,不一一标注引用。