Python基础常见面试题总结

news2024/11/23 20:14:53

在这里插入图片描述

文章目录

    • 1.深拷贝与浅拷贝
    • 2.迭代器
    • 3.生成器
    • 4.装饰器
    • 5.进程、线程、协程
    • 6.高阶函数
    • 7.魔法方法
    • 8.python垃圾回收机制


1.深拷贝与浅拷贝

  • 浅拷贝是对地址的拷贝,只拷贝第一层,第一层改变的时候不会改变,内层改变才会改变。
  • 深拷贝是对值的拷贝,不会随着原数据的变化而变化
import copy
list = [[1, 2], 'feng', 66]
a = copy.copy(list)
b = copy.deepcopy(list)


# list[1]=4

# print(a)
# print(b)
#输出结果
# [[1, 2], 'feng', 66]
# [[1, 2], 'feng', 66]

list[0][0] = 8
print(a)
print(b)
#输出结果
# [[8, 2], 'feng', 66]
# [[1, 2], 'feng', 66]


import copy
list = ['feng',[1,2], 66]
a = copy.copy(list)
b = copy.deepcopy(list)

print(id(list[0]))
print(id(a[0]))
print(id(b[0]))
print(id(list[1]))
print(id(a[1]))
print(id(b[1]))
#输出结果
# 4306918640
# 4306918640
# 4306918640
# 4307415552
# 4307415552
# 4307500992

2.迭代器

    迭代器是一个可以记住遍历位置的对象,因此不会像列表那样一次性全部生成,而是可以等到用的时候才生成,因此节省了大量的内存资源。迭代器对象从集合中的第一个元素开始访问,直到所有的元素被访问完。迭代器有两个方法:iter()next()方法。

迭代器的优点: 省内存.它是一种通过延时创建的方式生成一个序列,只有在需要的时候才被创建。

__iter____next__执行流程:

  1. 先调用__iter()__,得到可迭代对象的迭代器
  2. 调用__next()__,将上一步得到的迭代器 进行取值
  3. 将上一步取出来的值赋值给变量
  4. 重复执行,所有数据都获取完毕后,会在下一次调用__next__的时候产生Stopiteration异常。只不过 for循环中自带了异常处理,当它遇到Stopiteration异常的时候,会自动结束for循环

示例代码:

# 自定义一个迭代器,求斐波那契序列

from itertools import islice
from collections import Iterator,Iterable

class Fib(object):
    def __init__(self):
        self.prev = 0
        self.curr = 1

    def __iter__(self):
        return self

    def __next__(self):
        value = self.curr
        self.curr += self.prev
        self.prev = value
        return value

# 迭代器对象
f = Fib()
print(isinstance(f,Iterator)) # true
L = list(islice(f,0,10)) # islice对可迭代对象进行切片
print(L)
# [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

3.生成器

    在Python中,一边循环一边计算的机制,称为生成器:generator。使用了 yield 的函数被称为生成器(generator)。

生成器仅仅保存了一套生成数值的算法,并且没有让这个算法现在就开始执行,而是什么时候调它,它什么时候开始计算一个新的值,并返回。生成器是一种特殊的迭代器,能够在遍历时暂停和继续执行,使用yield定义的函数不会执行,返回一个生成器对象。迭代时遇到yield会暂停并返回yield后面的值,保存当前的状态,下次迭代从上次暂停的地方继续执行,直到再次遇到yield,优势是内存占用少,节约资源。应用场景是遍历文件或网络数据流、CPU密集型计算、图像处理等。生成器可以逐个读取大文件,并且不必将整个文件加载到内存中,避免了内存消耗和IO操作的额外开销。

当我们创建一个生成器时,第一次调用只能用next() 或者 send(None) 来启动生成器实际上next()send() 在一定意义上作用是相似的,区别是 send() 可以传递yield表达式的值进去,而next() 不能传递特定的值,只能传递None进去。因此,我们可以看做c.next()c.send(None) 作用是一样的。nextsend都是调用yield生成值的函数,next是直接调用,send是先覆盖上一个yield返回值后再调用下一个yield生成值。


4.装饰器

    装饰器是在函数原有功能不变的基础上加上新的功能。底层采用闭包理念实现。内外函数嵌套,外层函数返回内层函数,内层函数引用外部函数的变量。

    装饰器分为有参装饰器和无参装饰器。当func被多个装饰器修饰时,装饰器会按照从下到上的顺序对func进行装饰,也就是最靠近函数的装饰器最先应用装饰,执行的时候从上往下执行

应用场景:权限验证,日志记录,接口执行时间统计,接口过滤

  • 权限验证:比如在后台管理系统中,在装饰器中检查用户权限,按照权限判断用户是否可以访问此接口;
  • 日志记录:在函数执行前后添加日志记录,用于监控函数的调用情况

代码示例:

# 多个装饰器装饰一个原函数

# 装饰器1:在调用原函数前输出 "装饰器1的开始";在调用原函数结束输出  "装饰器1的结束"
def outer1(f):
    def inner():
        print("装饰器1的开始")
        f()
        print("装饰器1的结束")
    return inner


# 装饰器2:在调用原函数前输出 "装饰器2的开始";在调用原函数结束输出  "装饰器2的结束"
def outer2(f):
    def inner():
        print("装饰器2的开始")
        f()
        print("装饰器2的结束")
    return inner


# 原函数 输出“我是原函数”
@outer2
@outer1
def func():
    print("我是原函数")
func()


# 总结:
# 装饰器的调用顺序:从下往上
# 装饰器的执行顺序:从上往下  -->执行结果

更多请点击:Python进阶:深入剖析闭包与装饰器的应用与技巧

5.进程、线程、协程

    进程是操作系统进行分配资源的基本单位,每个进程都有自己的内存空间和系统资源,进程之间不能共享内存,需要通过IPC(进程间通信:管道、队列、数据库)的方式进行通信。适合CPU密集型场景。

比如:并行计算、网络编程、爬虫、任务调度(定时任务、异步任务)、分布式计算。


    线程是程序执行的最小单元,一个进程可以有多个线程,同一个进程中的多个线程共享该进程中的全部资源,进程和线程都有五种状态:初始态、就绪态、执行态、阻塞态、终止态。适合IO密集型场景。
比如:多线程爬虫,多线程处理订单


    协程(Coroutine,又称微线程)是一种比线程更加轻量级的存在,协程不是被操作系统内核所管理,而完全是由程序所控制。

协程可以比作子程序,但执行过程中,子程序内部可中断,然后转而执行别的子程序,在适当的时候再返回来接着执行。协程之间的切换不需要涉及任何系统调用或任何阻塞调用。

协程只在一个线程中执行,是子程序之间的切换,发生在用户态上。而且,线程的阻塞状态是由操作系统内核来完成,发生在内核态上,因此协程相比线程节省线程创建和切换的开销。

6.高阶函数

    高阶函数,它指的是一个函数可以接收另一个函数作为参数,或者将函数作为结果返回。

1.map(func, list):
	将func 应用于list中的每一个元素,返回一个迭代器

2.reduce(func, list):
  计算结果与下一个数据做累积计算,必须有两个参数
  from functools import reduce	

3.filter(func, list):
  过滤掉不符合条件的元素,返回一个filter对象,可用list()转换
  
4.sorted(iterable[,cmp][,key][,reverse])  
​    从iterable的项目中返回一个新的排序后的列表。可选的参数和列表方法与sort中的相同

list_sort = sorted(d,key=lambda x:x['a'],reverse=True)

7.魔法方法

    Python 的魔法方法(Magic Methods),也称为特殊方法或双下划线方法,用于定义类的行为和特性。这些方法在特定的情况下会被自动调用。

魔法方法的分类:

初始化与析构:如__init____new____del__等,控制对象的创建和销毁。
属性访问:如__getattr____getattribute____setattr____delattr__等,控制属性的访问和修改。
容器方法:如__len____getitem____setitem____delitem__等,支持容器类型的操作。
数值方法:如__add____sub____mul__等,支持数学运算。
字符串与序列表示:如__str____repr____format__等,提供对象的字符串表示。
上下文管理:如__enter____exit__等,支持with语句的上下文管理。
比较操作符:如__eq____ne____lt____le____gt____ge__等,支持对象比较。
其他:如__call____hash__等,提供额外的功能

以下是一些常用的 Python 魔法方法详解:

  • __new__: 用于创建对象实例时调用。它在对象实例化之前被调用,并且必须返回一个新的对象实例,在使用普通的类实例化对象时,默认会先调用 __new__ 方法来创建对象实例,然后再调用 __init__ 方法进行初始化。但是,我们可以重写 __new__ 方法以自定义对象的创建过程。
  • __init__(self, [...]): 构造函数,在创建对象时调用,用于初始化对象的属性。
  • __del__(self): 析构函数,在对象被销毁时调用,用于清理资源。
  • __str__(self): 字符串表示方法,在使用 str() 函数或 print() 函数打印对象时调用。
  • __repr__(self): 表示方法,返回对象的完整、可读性较好的字符串表示形式,在交互模式下会自动调用。
  • __len__(self): 长度方法,在使用 len() 函数获取对象长度时调用。
  • __getitem__(self, key): 索引访问方法,在通过索引访问对象时调用。
  • __setitem__(self, key, value): 索引赋值方法,在通过索引设置对象值时调用。
  • __iter__(self): 迭代器方法,返回一个对象的迭代器,在使用 for 循环遍历对象时调用。
  • __next__(self): 迭代器中的下一个元素方法,在迭代器中调用以获取下一个元素。
  • __eq__(self, other): 相等比较方法,判断对象是否相等时调用。
  • __lt__(self, other): 小于比较方法,判断对象是否小于另一个对象时调用。
  • __gt__(self, other): 大于比较方法,判断对象是否大于另一个对象时调用。

此外,还有很多其他的魔法方法可以用于自定义类的行为,比如数学运算相关的 __add____sub____mul____div____pow__ 等。详细的魔法方法列表可参考 Python 官方文档。通过定义这些方法,我们可以灵活地控制和定制类的操作和行为。

与python反射相关的魔法方法:
    反射使得程序能够在运行时动态地访问和操作对象的内部结构,包括属性和方法。

__getattr__(self, name):当访问的属性不存在时调用。适用于动态属性访问。
__getattribute__(self, name):访问任何属性时调用,拦截所有对对象属性的访问。谨慎重写,因为它可能导致无限递归。
__setattr__(self, name, value):用于设置或更新对象的属性。当你为对象的属性赋值时,Python会自动调用这个方法。
__delattr__(self, name):删除属性时调用。当使用del语句或delattr函数删除对象的属性时,如果类中定义了__delattr__方法,Python会调用这个方法而不是直接删除属性。
__dir__(self):获取对象的所有属性名和方法名列表,用于dir()函数

8.python垃圾回收机制

在Python中,垃圾回收(Garbage Collection)是一种自动化的内存管理机制,它通过检测和清除不再使用的内存来释放内存资源,从而提高程序的性能和效率。

Python使用了一种称为"引用计数"的策略来跟踪对象的引用次数。每当一个对象被引用时,其引用计数就会增加;当它不再被引用时,引用计数就会减少。 当一个对象的引用计数达到零时,该对象就成为垃圾对象,将被垃圾回收机制清理掉。

除了引用计数,Python还使用了其他垃圾回收策略来处理一些特殊情况,会在下面介绍。

  1. 标记-清除(Mark and Sweep): 当引用计数策略无法解决循环引用问题时,Python使用标记-清除算法来检测和清除不再使用的对象。该算法的原理是,首先从根对象(如全局变量、函数调用栈等)开始标记所有可访问的对象,然后清除那些未标记的对象

  2. 分代回收(Generational Collection): Python中的对象按照其年龄进行分组,被分为三代:0代、1代和2代。大部分新创建的对象属于0代,当一个对象经过一次垃圾回收后仍然存活,它会被移到下一代。分代回收机制的原理是,根据经验观察到的现象,大部分对象在短时间内就会变成垃圾,而那些存活得更久的对象更可能长时间存活下去。因此,分代回收机制可以根据对象的存活情况进行不同频率的垃圾回收,提高效率。

  3. 内存池机制(Memory Pools): Python使用内存池来管理小块内存的分配和释放。内存池是一块连续的内存空间,包含多个大小固定的块,每个块都可以独立分配给一个对象。这个机制显著减少了内存碎片的产生,并且提高了内存分配的效率。

需要注意的是,Python的垃圾回收是自动进行的,开发者不需要显式地调用垃圾回收函数。垃圾回收机制是Python解释器的一部分,它会在适当的时候自动运行,确保内存资源的有效利用。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2211397.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【第十六周】回顾线性回归与逻辑回归以及它们的详细推导过程

目录 摘要Abstract1.线性回归1.1.一元线性回归1.1.1.函数凹凸性判断 1.2.多元线性回归1.3.进一步理解梯度下降法 2.逻辑回归2.1.信息论角度推导交叉熵损失函数2.2.概率论角度推导交叉熵损失函数 3.额外阅读:Label Smoothing3.1.One-hot 和 Label Smoothing 的优缺点…

解决报错:Invalid number of channels [PaErrorCode -9998]

继昨天重装了树莓派系统后,今天开始重新安装语音助手。在测试录音代码时遇到了报错“Invalid number of channels [PaErrorCode -9998]”,这是怎么回事? 有人说这是因为pyaudio没有安装成功造成的。于是,我pip3 install –upgrad…

利用python创建接口

目录 1. 创建一个简单的接口1.1 具体过程1.2 代码解读1. **导入 Flask**2. **创建 Flask 应用**3. **定义一个路由**4. **运行应用** 1.3 遗留问题 2. 创建一个复杂接口2.2 具体过程 1. 创建一个简单的接口 1.1 具体过程 from flask import Flaskapp Flask(__name__)app.rou…

pip安装指定版本的tensorflow

安装CPU版本:(以2.9.0版本为例) pip install tensorflow2.9.0安装GPU版本:(以2.9.0版本为例) pip install tensorflow-gpu2.9.0若下载缓慢,使用阿里国内镜像源加速下载:(以2.9.0版本为例) pip install -i https://mirrors.aliy…

一些硬件知识【20241013】

3C认证要花很多钱: X电容可以滤除差模信号干扰,当火线上有高频干扰信号时候,X电容利用两端压差将干扰送到N: Y电容针对于零火线上有相位相同的共模干扰信号的时候,将干扰导向大地: 电阻上并联一个电容有什么作用&#…

mac安装homebrew和git

简介 由于把自己的新mac拿来撸代码,开始环境搭建,安装各种工具和依赖,安装 git 需要先安装 homebrew,然后就遇到了 homebrew 安装失败的问题。 curl: (7) Failed to connect to raw.githubusercontent.com port 443: Connection…

多字节字符集MFC使用 Windows Visual Styles

新建一个记事本&#xff0c;然后添加以下代码 <?xml version"1.0" encoding"UTF-8" standalone"yes"?> <assembly xmlns"urn:schemas-microsoft-com:asm.v1" manifestVersion"1.0"><trustInfo xmlns"…

STM32 | STM32F4OTA_ESP8266_Bootloader为引导程序远程更新的代码(APP)

更新。点击上方"蓝字"关注我们 01、思路 >>> STM32F4OTA_ESP8266_Bootloader为引导程序 远程更新的代码&#xff08;APP&#xff09;:远程更新的APP Ymoden_server&#xff1a;为运行在Linux的TCP服务器 备注&#xff1a;STM32 OTA远程更新需要连接热点 电…

地级市-国内旅游收入、国内旅游人数数据(2000-2023年)

国内旅游收入是指国内游客在旅行过程中的全部花费&#xff0c;包括交通、参观游览、住宿、餐饮、购物和娱乐等。这一指标不包括国际游客在国内的消费&#xff0c;主要反映国内旅游市场的经济规模和发展水平&#xff0c;是评估旅游行业对国民经济贡献的重要参数。 地级市-国内旅…

安全可靠测评结果公告(2024年第2号)

大家可以选择对应的数据库&#xff0c;中央处理器&#xff0c;供参考

【C++】--内存管理

&#x1f47e;个人主页: 起名字真南 &#x1f47b;个人专栏:【数据结构初阶】 【C语言】 【C】 目录 1 C/C内存分布2 C语言中动态内存管理方式 &#xff1a;3 C内存管理方式3.1 new/delete操作内置类型3.2 new和delete操作自定义类型 4 operator new与operator delete4.1 opera…

Cortex-M 内核的 OS 特性

目录 一、通用堆栈知识二、双堆栈用法三、PendSV 中断介绍和用法四、SVC 软中断介绍和用法五、特权级和非特权级使用方法 一、通用堆栈知识 在前面讲解 STM32 启动文件的时候就已经提到过&#xff0c;有关堆栈大小的设置是在启动文件中设置的&#xff1a; Heap 主要用于 Mal…

学习Redisson实现分布式锁

官网&#xff1a;https://redisson.org/ 官方文档&#xff1a;https://redisson.org/docs/getting-started/ 官方中文文档&#xff1a;https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95 1、引入依赖 <!--redisson--> <dependency><groupId>or…

基础教程 | 用VuePress搭建一个简单的个人博客(附源码)

先附上自己个人博客页面&#xff1a;https://illusionno.github.io/ 源码也在这里&#xff1a;https://github.com/illusionno/my-blog &#xff08;如果觉得有帮助&#xff0c;可以点颗star✨&#xff09; 使用的主题是vuepress-theme-reco2.x&#xff0c;并在上面进行了一些调…

基于Java Web众筹系统的设计与实现

文未可获取一份本项目的java源码和数据库参考。 体育俱乐部是我国体育产业的重要组成部分&#xff0c;而乒乓球作为“国球”&#xff0c;在我国拥有最广泛的群众基础。在世界乒坛&#xff0c;面对如此激烈的外部竞争环境&#xff0c;我国乒乓球运动应扎扎实实地研究基层职业乒乓…

考研C语言程序设计_语法相关(持续更新)

目录 一、语法题strlen转义字符内置数据类型字符串结束标志局部变量和全局变量名字冲突 局部优先switch语句中的关键字数组初始化是否正确注意define不是关键字C语言中不能用连等判断switch( )的括号里可以是什么类型?关于if关于switch 二、程序阅读题有关static有关continue说…

初级前端面试(2)

1.讲一下闭包相关知识&#xff0c;和普通函数有什么区别 闭包是什么&#xff1a;JS中内层函数可以访问外层函数的变量&#xff0c;外层函数无法操作内存函数的变量的特性。我们把这个特性称作闭包。 闭包的好处&#xff1a; 隔离作用域&#xff0c;保护私有变量&#xff1b;…

快速了解接口测试

1、定义 什么是接口测试&#xff1f; 接口测试是测试系统组件间接口的一种测试。接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。测试的重点是要检查数据的交换&#xff0c;传递和控制管理过程&#xff0c;以及系统间的相互逻辑依赖关系等。 接口测…

Vue3高级API的使用

介绍 在前面的内容中&#xff0c;我们已经学习到了很多 Vue 3 的基础语法与一些常用的 API。 本节我们将介绍一些高级 API&#xff0c;带领大家进一步深入了解 Vue 3。 主要内容 ●customRef() ●markRaw() ●toRaw() ●获取 DOM 元素 customRef 方法 customRef&#…

DNS隧道技术原理及其典型应用场景剖析

DNS隧道&#xff08;DNS Tunneling&#xff09;本质为一种网络通信技术&#xff0c;它利用DNS协议在客户端和服务器之间传输数据&#xff0c;主要用来绕过网络限制进行数据隐蔽传输&#xff0c;但在实际场景中&#xff0c;DNS隧道已经成为黑客忠爱的攻击媒介。 1. 概览 DNS是互…