python面试题
python面试题
1.讲讲python基本数据类型?--(2.x/3.x)
Python 中的基本数据类型包括数字、字符串、布尔值、列表、元组和字典
2.讲讲python的可变和不可变类型?
不可变类型包括数字、字符串、元组等。不可变类型的值在创建后不能被修改,如果需要修改,必须创建一个新的对象
可变类型包括列表、字典等。可变类型的值可以在原地进行修改,不需要创建新的对象
3.讲讲可hash和不可hash?
可哈希对象是指在其生命周期内其哈希值不变的对象,比如整数、浮点数、字符串、元组等。可哈希对象可以用作字典的键和集合的元素,因为这些数据结构需要将对象存储为哈希表的形式,而哈希表需要根据对象的哈希值来存储和查找对象。在 Python 中,不可变对象通常是可哈希对象。
不可哈希对象是指在其生命周期内其哈希值可能会变化的对象,比如列表、字典、集合等。这些对象由于其可变性,不能用作字典的键和集合的元素。如果尝试将不可哈希对象用作字典的键或集合的元素,则会引发报错。
4.两个list合并成一个list的方法?
+ 、extend() 、遍历
5.两个dict如何合并一起?
update()、**、遍历
6.dict里面两个相同的key 会发生什么?
--后者覆盖前者
7.dict的底层是怎么实现的?
二维数组--hash--二维数组--python3.7以前无序 以后有序
无序:维护一个二维数组
8.讲讲python脚本执行的过程(test.py)?
9.讲讲名称空间(namespace)?
存放名字与对象绑定关系的地方,如果想访问一个变量值,需要先访问对应的名称空间,拿到名字与对应的内存地址绑定关系,分为内置名称空间、全局名称空间、局部名称空间
如果从局部名称空间执行查找:局部 > 全局 > 内置,内置找不到就报错
如果从全局名称空间执行查找: 全局 > 内置,内置找不到就报错
10.讲讲堆和栈(heap and stack)?
堆和栈都是计算机内存中的重要概念,用于存储程序中的变量和数据等信息。堆是动态分配内存的数据结构,可以用于存储动态创建的数据;栈是静态分配内存的数据结构,用于存储函数调用时的临时数据。在 Python 中,所有的对象都存储在堆中,函数调用时使用栈来保存临时数据。
11.讲讲python的语言特性?
Python 是一种动态解释性类型的语言,变量不需要预先声明类型。是一种面向对象的编程语言一切皆对象。自带垃圾回收机制引用计数>标记清除>分代回收。
12.讲讲装饰器的原理?
装饰器可以在不修改函数源代码的情况下,为函数添加新的功能或行为,从而提高代码的复用性和可维护性。
装饰器的原理是通过函数嵌套和函数对象的引用来实现的,装饰器本身是一个函数,接受一个函数作为参数,返回一个新的函数。在装饰器的内部,它会定义一个新的函数,这个新函数会调用原函数,并在原函数执行前后添加一些额外的功能。最后,装饰器返回这个新的函数,用于替换原函数。
13.讲讲闭包特性?
闭包函数是 函数的嵌套、函数对象、名称空间与作用域的结合体
14.手写装饰器?
15.讲讲变量查找顺序?
局部-嵌套-全局-内置
16.讲讲python GIL锁?
GIL本质是一把互斥锁,相当于执行权限,每个进程内都会存在一把GIL同一进程内的多线程,必须抢到GIL之后才能使用Cpython解释器来执行自己的代码,即同一进程下的多个线程无法实现并行,但可以实现并发
17.有了GIL锁 为什么python还要有thread包?
虽然 threading 模块仍然受到 GIL 的限制,但在 I/O 密集型任务中可以充分利用多线程的优势,提高程序的并发性能。
multiprocessing 模块则提供了多进程编程的支持,可以充分利用多核 CPU 的性能优势,避免了 GIL 的限制,但也带来了一些额外的开销,例如进程间通信和数据共享等问题。
18.讲讲python的进程 线程 协程?
进程:资源单位
线程:执行单位
协程:单线程下实现并发,在I/O密集型的情况下,使用协程提高执行效率,手动的实现在同一线程下 “ 遇到I/O切换+保存状态 ” 让操作系统误以为没有I/O操作,将CPU执行权限继续交给你
即:在单线程下实现多个任务遇到IO就切换可以降低单线程的IO时间,从而最大限度的提升单线程的效率
19.讲讲IO密集型和计算密集型?
IO密集型应用程序是指其主要的瓶颈在于输入/输出(I/O)操作,例如读写文件、网络通信等。这类应用程序的特点是:CPU 能够很快地完成计算,但是等待 I/O 操作完成会花费较长的时间。在优化 IO 密集型应用程序时,应该尽可能减少 I/O 操作的次数和等待时间,可以采用异步 I/O、缓存、并发等技术来提高性能,例如使用线程池、事件驱动等方式来处理 I/O 操作。
计算密集型应用程序是指其主要的瓶颈在于计算操作,例如大量的数值计算、图像处理、加密解密等。这类应用程序的特点是:计算量大、时间长,需要大量的 CPU 资源来完成计算。在优化计算密集型应用程序时,应该尽可能利用多核 CPU 和并行计算技术,例如使用多线程、多进程、分布式计算等方式来提高性能。
20.讲讲线程的并行 并发 串行?
并发:在单核(一个CPU)的情况下,当执行当 a ,b 两个程序,先运行a时,当a遇到IO时,b开始执行,看着像同时运行
并行:在多核情况下,当执行 a ,b 两个程序,a 与 b 同时执行,真正意义上的同时执行
串行:指多个线程按照顺序依次执行,每个线程要等到前一个线程执行完成后才能开始执行
21.协程是否受到GIL锁影响?
与线程不同的是,协程在执行过程中是不会被 GIL 锁所限制的,因为协程是在单个线程中执行的,并且协程是由开发者手动控制的,可以自由地切换执行上下文,从而实现并发执行。因此,在 I/O 密集型任务中,协程可以充分利用 CPU 的性能,提高程序的并发性能。
22.讲讲生成器和迭代器/可迭代对象?
可迭代对象(Iterable):指实现了 __iter__() 方法的对象,例如列表、元组、集合、字典等。可迭代对象可以通过 for 循环进行迭代,也可以通过 iter() 函数获取一个迭代器。
迭代器(Iterator):指实现了 __next__() 方法的对象,每次调用 __next__() 方法可以返回迭代器中的下一个元素,如果迭代器中没有元素了,则抛出 StopIteration 异常。迭代器可以通过 iter() 函数获取自身,因此也是可迭代对象。
生成器(Generator):是一种特殊的迭代器,可以通过生成器函数来创建。生成器函数是一种特殊的函数,它可以在函数中使用 yield 语句来暂停函数的执行,并返回一个值,下次调用函数时可以从上次暂停的位置继续执行,直到函数执行完毕或者遇到 return 语句。生成器可以像迭代器一样使用 for 循环进行迭代,也可以使用 next() 函数手动获取下一个值。
需要注意的是,生成器和迭代器/可迭代对象的区别在于,生成器可以通过生成器函数来动态生成元素,而迭代器/可迭代对象的元素通常是静态的,需要在创建时就确定下来。生成器可以在迭代过程中动态生成元素,避免了一次性生成大量元素的开销,因此在处理大量数据时比较常用。
23.在什么业务场景下用到了生成器,为什么要用?
处理大型文件:如果需要读取一个非常大的文件,一次性将所有数据加载到内存中可能会导致内存溢出。此时可以使用生成器来逐行读取文件内容,避免一次性加载大量数据,从而降低内存占用和提高程序的性能。
处理网络数据:在网络编程中,往往需要从网络中读取大量的数据流,一次性读取所有数据可能会导致阻塞和资源浪费。此时可以使用生成器来按需读取数据,避免阻塞和资源浪费,提高程序的并发性能。
数据库查询:在处理数据库查询时,如果一次性查询大量数据,可能会导致数据库连接超时或者内存溢出。此时可以使用生成器来分批次查询数据,避免一次性查询大量数据,从而提高程序的性能和稳定性。
大量计算:在进行大量计算时,如果一次性生成所有计算结果,可能会导致内存溢出或者计算时间过长。此时可以使用生成器来逐步生成计算结果,从而避免一次性生成大量计算结果,提高程序的性能和效率。
24.元祖套列表,列表可修改吗?为什么?这样设计合理吗?
可以。在元组套列表中,元组和列表都是对象,元组本身是不可变的,但是元组内部的对象可以是可变的,包括其中的列表。因此,如果元组套列表中的列表是可变的,那么可以对列表进行修改操作。
25.讲讲drf 两字段拼接方法?
自定义一个字段SerializerMethodField 类来自定义一个方法,然后实现get_字段名 : 中实现拼接
26.讲讲django中间件/restful规范
请求来时由Django中间件默认的七个关口进行校验,当任意一个校验不通过都会返回,当七个默认关口都校验成功后,判断是不是第一次请求,如果不是,会直接去缓存数据库中查找数据,拿到数据后再通过中间件默认七个关口,通过web服务网关接口后返回给客户端浏览器数据,当第一次请求来时会依次通过url,views最后到数据库拿到数据后由视图层直接到中间件通过七个关口校验,当校验成功后,将数据进入缓存数据库一份,再通过web服务网关接口发送到客户端浏览器一份数据
自定义五个中间件:process_request、process_response、process_view、process_template_response、process_exception
27.讲讲apiview(源码)
as_view()返回的结果是 ---> view,view()函数返回的结果是 ---> dispatch(),在dispatch中进行获取反射获取请求方式,从而调用我们自定义的类中的对应的方法
28.序列化 把两个表放到一起 序列化器怎么写
29.讲讲django生命周期
web->http协议请求-web服务网关接口uwsgi-中间件-路由层-视图层-模型层-数据库
30.讲讲常用ORM查询
31.django更新数据库的方法
32.在浏览器输入一个地址 回车 会发生什么
33.讲讲HHTP和HTTPS 有哪些请求方法
34.自动取消订单机制
35.数据库慢查询优化
1. 优化索引:对于经常被查询的字段,可以添加索引来加快查询速度。需要注意的是,索引也会占用存储空间,过多的索引可能会影响写入性能。
2. 优化查询语句:在编写查询语句时,需要注意避免使用子查询、多重嵌套、全表扫描等低效操作。可以通过使用 JOIN 操作、使用 EXISTS、IN 子查询等方式来优化查询语句。
3. 分析执行计划:通过分析数据库的执行计划,可以了解查询语句的执行情况,找到影响查询性能的瓶颈。可以使用 EXPLAIN 或者其他工具来获取执行计划,然后根据执行计划优化查询语句或者修改索引。
4. 数据库分片:对于数据量过大的表,可以采用数据库分片的方式来分割数据,将数据存储在多个物理数据库中,以减少单个数据库的查询压力。
5. 数据库缓存:可以使用缓存技术来缓存查询结果,减少对数据库的访问次数。需要注意的是,缓存的数据可能会与实际数据不一致,需要确保缓存的数据及时更新。
6. 数据库优化参数:可以根据实际情况调整数据库的优化参数,例如调整缓存大小、调整并发连接数等,以提高数据库的性能。
36.关系型数据库有哪些
37.公司数据库有哪些规范
命名、权限、备份、文档、性能
38.讲讲python的递归
递归是一种函数调用自身的技术,通常用于解决需要重复执行相同任务的问题,最大递归深度998
39.函数里面的代码是什么时候运行的
40.定义一个类的时候 类里面的代码是什么时候运行的
定义是一种可执行语句,类里面的代码是在解释器加载模块时运行的。类定义中的代码用于创建并初始化类对象和类实例,可以包括属性和方法的定义、初始化操作和其他的辅助函数等
41.粘包问题
无法确认对方发送过来数据大小,在发送数据间隔短并且数据量小的情况下,会将所有数据一次性发送
解决粘包问题,使用struct模块,struct 是一个python内置的模块,它可以将固定长度的数据,打包成固定格式的长度,模式:i:4,或其他模式
42.mysql常用存储引擎 innodb基本单位是什么
页16kb
43.索引 字段类型 是否命中索引 回表操作
44.有2个经常查询字段a,b,建立了联合索引,实际有几个索引树? 为什么?
45.mysql主从同步 binlog日志 偏移量 可以用来恢复数据
46.redis是单线程吗?
主线程-1.网络IO(通过网络接收/发送数据) 2.键值对的读写
其他线程-持久化 异步删除 集群数据同步
47.redis是怎么恢复数据库的,持久化存储
aof写的操作日志记录写入到文件中, rdb一段时间内的快照
aof日志重写机制解决随着写的操作日志记录文件越来越多的问题,异步进行的
AOF 日志重写的过程如下:
1. Redis fork 一个子进程,用于执行 AOF 日志重写操作。
2. 子进程遍历 Redis 数据库当前的状态,并将遍历到的写操作重新生成一份新的 AOF 文件。
3. 当新的 AOF 文件生成完成后,子进程会将其替换旧的 AOF 文件,并通知 Redis 主进程使用新的 AOF 文件。
4. 旧的 AOF 文件会被删除,新的 AOF 文件会继续记录 Redis 的写操作。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!