Python常考面试题汇总(附答案)

写在前面
本文面向中高级Python开发,太基本的题目不收录。
本文只涉及Python相关的面试题,关于网络、MySQL、算法等其他面试必考题会另外开专题整理。
不是单纯的提供答案,抵制八股文!! 更希望通过代码演示,原理探究等来深入讲解某一知识点,做到融会贯通。
部分演示代码也放在了我的github的该目录下。
语言基础篇
Python的基本数据类型
Python3 中有六个标准的数据类型:

Number(数字)(包括整型、浮点型、复数、布尔型等)
String(字符串)
List(列表)
Tuple(元组)
Set(集合)
Dictionary(字典)
Python3 的六个标准数据类型中:

不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组);
可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)。
Python是静态还是动态类型?是强类型还是弱类型?
动态强类型语言(不少人误以为是弱类型)
动态还是静态指的是编译器还是运行期确定类型
强类型指的是不会发生隐式类型转换
js就是典型的弱类型语言,例如在console下面模拟一下数字和字符串相加,会发现发生了类型转换。

而Python会报TypeError

Python常考面试题汇总(附答案)_第1张图片

什么是鸭子类型
“当一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”

鸭子类型关注的是对象的行为,而不是类型。比如file,StringIO,socket对象都支持read/write方法,再比如定义了__iter__魔术方法的对象可以用for迭代。

下面用一个例子来模拟鸭子类型:

class Duck:
    def say(self):
        print("嘎嘎")
 
 
class Dog:
    def say(self):
        print("汪汪")
 
 
def speak(duck):
    duck.say()
 
 
duck = Duck()
dog = Dog()
speak(duck) # 嘎嘎
speak(dog) # 汪汪

什么是自省
自省是运行时判断一个对象类型的能力。

python一切皆对象,用type, id, isinstance获取对象类型信息。

自省,也可以说是反射,自省在计算机编程中通常指这种能力:检查某些事物以确定它是什么、它知道什么以及它能做什么。

与其相关的主要方法:

hasattr(object, name)检查对象是否具体 name 属性。返回 bool.
getattr(object, name, default)获取对象的name属性。
setattr(object, name, default)给对象设置name属性
delattr(object, name)给对象删除name属性
dir([object])获取对象大部分的属性
isinstance(name, object)检查name是不是object对象
type(object)查看对象的类型
callable(object)判断对象是否是可调用对象

python3和python2的对比
print成为函数
编码问题。python3不再有unicode对象,默认str就是unicode
除法变化。python3除号返回浮点数,如果要返回整数,应使用//
类型注解。帮助IDE实现类型检查
优化的super()方便直接调用父类函数。Python3.x 和 Python2.x 的一个区别是: Python 3 可以使用直接使用 super().xxx 代替 super(Class, self).xxx :
高级解包操作。a, b, *rest = range(10)
keyword only arguments。限定关键字参数
chained exceptions。python3重新抛出异常不会丢失栈信息
一切返回迭代器。range, zip, map, dict.values, etc. are all iterators
性能优化等。。。
python如何传递参数
python官方文档上的话:

“Remember that arguments are passed by assignment in Python. Since assignment just creates references to objects, there’s no alias between an argument name in the caller and callee, and so no call-by-reference per Se.”

准确地说,Python 的参数传递是赋值传递 (pass by assignment),或者叫作对象的引用传递(pass by object reference)。Python 里所有的数据类型都是对象,所以参数传递时,只是让新变量与原变量指向相同的对象而已,并不存在值传递或是引用传递一说。

根据对象的引用来传递,根据对象是可变对象还是不可变对象,得到两种不同的结果。如果是可变对象,则直接修改。如果是不可变对象,则生产新对象,让形参指向新对象

可以具体结合下面的代码实例来模拟:

def flist(l):
    l.append(0)
    print(id(l))    # 每次打印的id相同
    print(l)
 
 
ll = []
print(id(ll))
flist(ll)   # [0]
flist(ll)   # [0,0]
 
print("=" * 10)
 
 
def fstr(s):
    print(id(s)) # 和入参ss的id相同
    s += "a"
    print(id(s))  # 和入参ss的id不同,每次打印结果不相同
    print(s)
 
 
ss = "sun"
print(id(ss))
fstr(ss)    # a
fstr(ss)    # a
 

python的可变/不可变对象
不可变对象: bool/int/float/tuple/str/frozenset 可变对象:list/set/dict

这里继续看两个代码例子,看下输出是什么

def clear_list(l):
    l = []
 
ll = [1,2,3]
clear_list(ll)
print(ll)
 
def fl(l=[1]):
    l.append(1)
    print(l)
fl()
fl()
答案是

[1,2,3]
[1]
[1,1]
对于第一题,l = []这一步,创建了一个新的对象,并将l贴上去(注意函数里面的l和外面的l是形参和实参的区别,不要以为是同一个),所以原来的 l 并没有改变

对于第二题,默认参数只计算一次。

有兴趣的小伙伴可以再试一下这个例子:

a = 1
def fun(a):
    print("func_in",id(a))
    a = 2
    print("re-point",id(a), id(2))
print("func_out&

你可能感兴趣的:(面试,职场和发展)