0、前言
最近和几位面试的朋友聊天,部分公司会有笔试环节,而很多中小型公司现在都没有了笔试环节。如果遇到有笔试的公司,一些基础 Python 知识点考查的频率还是很高的。今天,小编就给大家整理了 10 道较为常见的 Python 面试题,以及相应的答案,来帮助小伙伴们更好的了解和学习 Python,也为后续的面试,奠定一定的基础。
1、请简述工作常用的 Python 标准库?
工作中,我常用的 Python 标准库主要有:os、time、random、threading、json 等。
os: 操作系统相关的操作
time: 时间相关业务
random: 随机数相关的操作
threading: 线程相关的业务
json: 数据格式转
工作中,我常用的 Python第三方库主要有:flask、django、requests、openpyxl、pyaudio 等
flask: 轻量级 Web 开发框架,灵活、可扩展性高
django: 一站式 Web 开发框架,功能齐全
requests: 发送 HTTP 请求
openpyxl: 自动化办公相关的逻辑
pyaudio: 音频相关的业务
2、请简述 Python 中赋值、浅拷贝和深拷贝的区别。
(1) 赋值在 Python 中,对象的赋值就是简单的对象引用,如下所示:
a = "可乐python说"
b = a
print(a is b) # True
通过上面的例子我们可以发现,a 和 b 是一样的,它们指向同一片内存空间,b 不过是 a 的别名,是引用。
赋值操作(包括对象作为参数、返回值)不会开辟新的内存空间,它只是复制了对象的引用。
也就是说除了 b 这个名字之外,没有其他的内存开销,修改了 a,也就影响了 b,同理,修改了 b,也就影响了 a。
(2) 浅拷贝浅拷贝会创建新的对象,其内容并非原对象本身的引用,而是原对象内第一层对象的引用。
浅拷贝可以通过切片、工厂函数、copy 模块中的 copy 函数实现,我们以最后一种来演示:
from copy import copy
a = ["可乐", "python", "说"]
b = copy(a)
print(a is b) # False
print(id(a)) # 69524328
print(id(b)) # 69751304
for i in a:
# 69309456
# 66912864
# 69309504
print(id(i))
for j in b:
# 69309456
# 66912864
# 69309504
print(id(j))
浅拷贝产生的列表 b 不再是原来的列表 a 了,使用 is 判断可以发现他们不是同一个对象,使用 id 查看,他们也指向不同的内存空间。
但是当我们使用 id(i) for i in a 和 id(j) for j in b 来查看 a 和 b 中元素的地址时,可以发现二者包含的元素的地址是相同的。
这种情况下,修改 a 或者 b 并不会对彼此产生影响。
(3) 深拷贝深拷贝只有一种形式,可使用 copy 模块中的 deepcopy() 函数实现。
深拷贝和浅拷贝对应,深拷贝拷贝了对象的所有元素,包括多层嵌套的元素,深拷贝拷贝出来的对象根本就是一个全新的对象,不再与原来的对象有任何的关联。
(4) 注意事项对于非容器类型,如数字、字符串,以及其他的 "原子" 类型,就没有拷贝一说,产生的都是原对象的引用。如果元组变量值包含原子类型对象,即使采用了深拷贝,也只能得到浅拷贝。
3、请简述 Python 中的模块与包。
在 Python 中,模块是搭建程序的一种方式。每一个 Python 代码文件都是一个模块,并且可以引用其他的模块,比如模块中的对象、属性等。一个包含许多 Python 代码的文件夹是一个包,一个包可以包含模块和子文件夹,一般,包中会包含一个 __init__.py 文件。
4、请简述 Python 中的字典与 Json 的区别。
字典是 Python 中的一种数据结构,字典的 key 值只要是 hashable 的数据类型即可;而 json 是一种数据表现形式,一种数据格式,json 中的 key 必须是使用双引号引起来的字符串类型,使用单引号或者不用引号会导致读取数据错误。
5、请简述你对缺省参数的理解。
缺省参数是指在调用函数的时候,没有传入参数的情况下,则使用默认的参数,在调用函数的同时传入参数,所传入的参数就会替代默认参数生效。*args 是不定长参数,它表示输入参数是不确定的,可以是任意多个;**kwargs 是关键字参数,赋值的时候是以键 = 值的方式,参数是可以任意多对;在定义函数的时候不确定会有多少参数会传入时,就可以使用两个参数。
6、请简述 Python 中递归函终止的条件。
递归的终止条件一般定义在递归函数内部,在递归调用前要做一个条件判断,根据条件判断的结果,选择是继续调用自身,还是 return 返回,终止递归。终止的条件如下:(1) 判断递归函数的次数是否达到某一限定值;(2) 判断运算的结果是否达到某个范围等,根据设计的目的来选择。
7、请手写 Python 中的单例代码如下:
class KelePython(object):
__instance = None
def __new__(cls, *args, **kwargs):
if cls.__instance is None:
cls.__instance = object.__new__(cls)
return cls.__instance
else:
return cls.__instance
8、请简述单例模式的应用场景有哪些?
单例模式一般应用在以下场景:(1)资源共享的情况下,避免由于资源操作时导致的性能或损耗等,如日志文件,应用配置等;(2)控制资源的情况下,方便资源之间的互相通信,如网站的计数器、应用配置、多线程池、数据库配置、数据库连接池、应用程序的日志应用等。
9、请简述迭代器与生成器的区别。
迭代器:是一个抽象的概念,任何对象,如果它的类有 next 方法和 iter 方法并且返回自己本身的,都是迭代器。
对于 string、list、dict、tuple 等这类容器对象,在后台 for 语句,其实是对容器对象调用 iter() 函数,会返回一个定义了 next()方法的迭代器对象,它在容器中逐个访问容器内元素,在没有后续元素时,next() 会抛出一个 StopIteration 异常。
生成器:是创建迭代器的简单而强大的工具,写起来就像是正规的函数,只是在需要返回数据的时候 使用 yield 语句。
每次 next() 被调用时,生成器会返回它脱离的位置(它记忆语句最后一次执行的位置和所有的数据值)
区别:生成器能做到迭代器能做的所有事,而且因为自动创建了 iter() 和 next() 方法,生成器显得特别简洁,而且生成器也更加高效,使用生成器表达式取代列表解析可以同时节省内存。
除了创建和保存程序状态的自动方法,当生成器终结时,还会自动抛出 StopIteration 异常。
10、请简述同步,异步,阻塞与非阻塞这四个概念的含义。
同步、异步是相对于多任务而言的,关注的是消息通信机制。
同步:多个任务之间按照先后顺序执行,一个任务执行完,下一个任务才能执行。
异步:多个任务之间没有先后顺序,可以同时执行,有时候一个任务可能要在必要的时候,获取另一个同时执行的任务的结果,一般把这种情况称为回调。
举个例子: 你打电话问朋友最近公司还招不招人,如果是同步机制,朋友会说,你稍等,我先问一下人事的同事,然后就跑去问了,没有挂电话,经过一段时间后,朋友就把问到的结果告诉你(返回结果)。
而如果是异步通信机制,朋友会说,我先去问一下人事的同事,然后直接挂掉电话,等问到结果后再主动打电话联系你,这里的回电就是上面说的回调。
阻塞、非阻塞是相对于代码执行而言的,关注的是程序在等待调用结果时的状态。
阻塞:程序执行卡在了某个阶段,调用者在收到调用结果返回之前,当前线程会被挂起,只用拿到调用结果之后才会返回。
非阻塞:即使调用者不能立刻得到结果,调用线程也不会被挂起,而是可以继续执行。
举个例子: 你打电话问朋友最近公司还招不招人,朋友会说,我先问一下人事的同事,如果是阻塞式调用,你就会一直在电话前等待,直到等到朋友的回复。而如果是阻塞式调用,你可以不需要一直守在电话前,可以先去忙其他的事情,偶尔过来检查一下朋友有没有回复即可。
11、总结
1、扎实的基础,不仅能让我们应付面试,还能为我们以后的进阶赋能。
2、有些知识点官方的描述可能没那么好理解,但是我们结合一些身边的生活例子去理解,也许就没那么难了。
3、不管面结果如何,只要我们多总结,每次都会有新的收获,也能让我们更加清晰地认识自己,查漏补缺。
欢迎在线答题 python数据分析师(数据分析/python)