Python常见面试题的详解10

1. 哪些操作会导致 Python 内存溢出,怎么处理?

  • 要点

        1. 创建超大列表或字典:当我们一次性创建规模极为庞大的列表或字典时,会瞬间占用大量的内存资源。例如,以下代码试图创建一个包含 10 亿个元素的列表,在执行这段代码时,由于需要为这 10 亿个整数分配内存空间,很容易就会导致内存溢出错误。

python

huge_list = [i for i in range(10**9)]

        2. 递归深度过大:递归函数在没有正确设置终止条件的情况下,会不断地自我调用,从而使得栈空间持续被占用,最终耗尽内存。下面是一个简单的无限递归示例:

python

def recursive_function():return recursive_function()
recursive_function()

         3. 大文件读取:使用 read() 方法一次性将大文件的全部内容读取到内存中,对于大型文件而言,这会使内存占用急剧增加,若 large_file.txt 文件非常大,将其全部内容读入内存会迅速耗尽可用内存。

python

with open('large_file.txt', 'r') as f:content = f.read()
  • 解决办法
  1. 使用生成器:生成器是一种特殊的迭代器,它不会一次性生成所有元素,而是在需要时逐个生成,从而节省大量内存。例如,我们可以使用生成器表达式来生成一系列数字,在这个例子中,huge_generator 并不会立即生成 10 亿个数字,而是在每次循环时才生成一个数字,当满足条件 num > 100 时就停止生成,大大减少了内存的使用。

python

huge_generator = (i for i in range(10**9))
for num in huge_generator:if num > 100:break

      2. 优化递归:将递归函数改为迭代函数,或者手动实现尾递归优化(虽然 Python 本身不支持尾递归优化)。以下是将递归的阶乘函数改为迭代实现的示例,通过迭代的方式,避免了递归调用带来的栈空间占用问题。

python

# 递归实现阶乘
def factorial_recursive(n):if n == 0 or n == 1:return 1return n * factorial_recursive(n - 1)# 迭代实现阶乘
def factorial_iterative(n):result = 1for i in range(1, n + 1):result *= ireturn resultprint(factorial_iterative(5))

       3. 分块读取文件:使用 read(size) 方法按指定大小分块读取文件,或者逐行读取文件。例如按块读取文件的代码如下,这样每次只读取 1024 字节的数据,处理完后再读取下一块,有效控制了内存的使用。

python

with open('large_file.txt', 'r') as f:while True:chunk = f.read(1024)if not chunk:break# 处理 chunkprint(chunk)
  • 总结
  1. 导致内存溢出的操作主要包括创建超大数据结构、递归深度过大和大文件一次性读取。

  2. 处理内存溢出问题可以采用生成器、优化递归和分块读取文件等方法。

2. 内存管理机制及调优手段?

  • 要点

     1. 对象池:Python 对一些常用的小整数(-5 到 256)和短字符串进行了缓存处理。当多次使用相同的对象时,不会重新分配内存,而是直接复用已有的对象。这里的 100 在 -5 到 256 范围内,所以 ab 指向同一个内存地址。

python

a = 100
b = 100
print(a is b)  # 输出 True,说明 a 和 b 指向同一个对象

      2. 引用计数:每个 Python 对象都有一个引用计数,当引用计数为 0 时,对象所占用的内存会被自动释放。以下是引用计数变化的示例,在这个过程中,通过 del 语句减少对象的引用计数,当引用计数为 0 时,Python 会回收该对象的内存。

python

a = [1, 2, 3]  # 列表对象引用计数加 1
b = a  # 引用计数再加 1
del a  # 引用计数减 1
del b  # 引用计数减为 0,对象内存释放

      3. 垃圾回收:当存在循环引用时,引用计数机制无法解决内存泄漏问题,Python 会使用标记 - 清除和分代回收算法进行垃圾回收。

python

class A:pass
class B:passa = A()
b = B()
a.b = b
b.a = a# 此时 a 和 b 存在循环引用,即使没有其他外部引用,引用计数也不会为 0
# Python 的垃圾回收机制会在适当的时候检测并处理这种循环引用
  • 解决办法

      1. 减少对象创建:尽量复用已有的对象,避免频繁地创建和销毁对象。例如,在需要多次使用相同字符串时,可以先将其赋值给一个变量,然后重复使用该变量,这样避免了每次循环都创建一个新的字符串对象。

python

message = "Hello, World!"
for _ in range(10):print(message)

       2. 及时释放对象:使用 del 语句删除不再使用的对象,减少引用计数,加快内存释放。

python

data = [i for i in range(1000)]
# 使用 data 进行一些操作
# ...
del data  # 及时释放 data 占用的内存

         3. 使用 gc 模块:手动调用 gc.collect() 方法可以触发垃圾回收,清理不再使用的内存。

python

import gc
# 手动触发垃圾回收
gc.collect()
  • 总结
  1. Python 的内存管理机制包括对象池、引用计数和垃圾回收。

  2. 内存调优手段有减少对象创建、及时释放对象和手动触发垃圾回收。

3. 内存泄露是什么?如何避免?

  • 要点

内存泄露是指程序在运行过程中,由于某些原因导致一些内存无法被释放,随着程序的持续运行,这些未释放的内存会不断累积,最终导致内存耗尽。例如以下代码存在循环引用问题,可能会导致内存泄露:

python

class A:pass
class B:passa = A()
b = B()
a.b = b
b.a = a# 即使没有其他外部引用指向 a 和 b,由于它们之间的循环引用,引用计数不会为 0,内存无法释放
  • 解决办法

       1. 避免循环引用:尽量避免对象之间的循环引用,如果无法避免,可以手动解除引用。这样就打破了循环引用,使得对象的引用计数可以降为 0,从而被垃圾回收机制回收。

python

class A:pass
class B:passa = A()
b = B()
a.b = b
b.a = a# 手动解除引用
del a.b
del b.a

       2. 正确关闭资源:对于文件、数据库连接等资源,使用 with 语句可以确保资源在使用完毕后正确关闭。

python

with open('file.txt', 'r') as f:content = f.read()
# 文件会自动关闭,避免资源占用
  • 总结
  1. 内存泄露是指内存无法正常释放,导致内存不断消耗。

  2. 避免内存泄露的方法包括避免循环引用和正确关闭资源。

4. python 常见的列表推导式?

  • 要点

       1. 基本列表推导式:可以简洁地生成列表。例如生成 0 到 9 的平方列表,这种方式比使用传统的 for 循环更加简洁明了。

python

squares = [i**2 for i in range(10)]
print(squares)  # 输出 [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

        2. 带条件的列表推导式:带条件的列表推导式可以根据条件筛选元素。例如生成 0 到 9 中偶数的平方列表,通过 if 条件筛选出偶数,然后计算其平方。

python

even_squares = [i**2 for i in range(10) if i % 2 == 0]
print(even_squares)  # 输出 [0, 4, 16, 36, 64]

         3. 嵌套列表推导式及示例可以用于生成多维列表。例如生成一个 3x3 的矩阵。

python

matrix = [[i * j for j in range(3)] for i in range(3)]
print(matrix)
# 输出 [[0, 0, 0], [0, 1, 2], [0, 2, 4]]
  • 总结
  1. 基本列表推导式用于快速生成列表。

  2. 带条件的列表推导式可根据条件筛选元素。

  3. 嵌套列表推导式用于生成多维列表。

5. 简述 read、readline、readlines 的区别?

  • 要点

  1.read() 方法:会一次性读取文件的全部内容,并将其作为一个字符串返回。如果文件非常大,会占用大量内存。当 file.txt 文件内容较多时,content 会占用较多内存。

python

with open('file.txt', 'r') as f:content = f.read()print(content)

  2.readline() 方法:每次读取文件的一行内容,并将其作为一个字符串返回。可以通过循环多次调用 readline() 来逐行读取文件。这种方式逐行读取文件,内存占用相对较小。

python

with open('file.txt', 'r') as f:line = f.readline()while line:print(line)line = f.readline()

   3.readlines() 方法会一次性读取文件的所有行,并将每行内容作为一个元素存储在列表中返回。同样,如果文件很大,会占用大量内存。例如:

python

with open('file.txt', 'r') as f:lines = f.readlines()for line in lines:print(line)
  • 总结
  1. read() 一次性读取整个文件内容。

  2. readline() 逐行读取文件。

  3. readlines() 一次性读取所有行并存储在列表中。

6. 什么是 Hash(散列函数)?

散列函数是一种将任意长度的输入数据转换为固定长度输出的函数。这个固定长度的输出通常称为哈希值或散列值。

  • 要点

     1. 确定性:对于相同的输入,散列函数总是返回相同的输出。例如在 Python 中使用 hash() 函数:

python

hash_value1 = hash('hello')
hash_value2 = hash('hello')
print(hash_value1 == hash_value2)  # 输出 True

       2. 高效性:计算哈希值的速度很快,能够在短时间内完成大量数据的哈希计算。

       3. 均匀性:哈希值在输出范围内均匀分布,减少哈希冲突的概率。例如不同的字符串经过哈希函数计算后,其哈希值会尽可能均匀地分布在哈希空间中。

  • 总结
  1. 散列函数将任意长度输入转换为固定长度输出。

  2. 具有确定性、高效性和均匀性特点。

7. 什么是函数重载机制?

  • 要点

Python 本身不支持传统意义上的函数重载,即根据函数参数的数量或类型不同来定义多个同名函数。但可以通过以下几种方式实现类似的功能:

      1. 使用默认参数及示例:使用默认参数可以让函数在不同的调用方式下表现出不同的行为。当只传入一个参数时,b 使用默认值 0;当传入两个参数时,使用传入的参数进行计算。

python

def add(a, b=0):return a + bprint(add(1))  # 输出 1
print(add(1, 2))  # 输出 3

         2. 使用 *args**kwargs 及示例*args 用于接收可变数量的位置参数,**kwargs 用于接收可变数量的关键字参数。通过判断参数的类型和数量,可以实现不同的处理逻辑。

python

def func(*args, **kwargs):if len(args) == 1 and isinstance(args[0], int):print(f"Received an integer: {args[0]}")elif len(args) == 2 and all(isinstance(arg, str) for arg in args):print(f"Received two strings: {args[0]} and {args[1]}")else:print("Unknown input")func(1)
func("hello", "world")
  • 总结
  1. Python 不支持传统函数重载。

  2. 可以使用默认参数、*args**kwargs 实现类似功能。

7. 手写一个判断时间的装饰器

python

import timedef time_check(func):def wrapper(*args, **kwargs):start_time = time.time()result = func(*args, **kwargs)end_time = time.time()execution_time = end_time - start_timeprint(f"Function {func.__name__} took {execution_time} seconds to execute.")return resultreturn wrapper@time_check
def example_function():time.sleep(2)return "Function executed."print(example_function())
  • 要点

这个装饰器 time_check 用于测量函数的执行时间。在函数执行前后分别记录时间,计算时间差并打印出来。

  1. 装饰器是一种高阶函数,接收一个函数作为参数并返回一个新的函数。

  2. 可以利用装饰器对函数进行功能扩展,如时间测量、日志记录等。

9. 如何使用 Python 内置的 filter () 方法来过滤?

filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回一个迭代器对象。例如过滤出列表中的偶数:

python

numbers = [1, 2, 3, 4, 5, 6]
even_numbers = filter(lambda x: x % 2 == 0, numbers)
print(list(even_numbers))  # 输出 [2, 4, 6]
  • 要点
  1. filter() 函数接收一个函数和一个可迭代对象作为参数。

  2. 函数用于判断元素是否符合条件,符合条件的元素会被保留。

  3. 返回的是一个迭代器对象,可通过 list() 函数将其转换为列表。

10. 写出编写函数的 4 个原则

  • 单一职责原则

一个函数应该只做一件事情,并且把这件事情做好。这样可以提高函数的可读性和可维护性。例如一个函数只负责计算两个数的和,这个函数的功能非常明确,只进行加法运算。

python

def add(a, b):return a + b
  • 避免副作用原则

函数应该尽量避免修改外部变量或产生其他副作用。如果需要修改外部状态,应该明确告知调用者。add_to_list 函数不会修改原始列表,而是返回一个新的列表。

python

# 不好的示例,修改了外部列表
my_list = [1, 2, 3]
def modify_list():my_list.append(4)# 好的示例,返回新列表
def add_to_list(lst, item):return lst + [item]
  • 提供清晰的接口原则

函数的参数和返回值应该有明确的含义和类型。可以使用类型注解来提高代码的可读性。通过类型注解,明确了参数和返回值的类型。

python

def multiply(a: int, b: int) -> int:return a * b
  • 可测试性原则

函数应该易于测试,尽量减少依赖外部资源。可以通过单元测试来验证函数的正确性。square 函数不依赖外部资源,很容易进行测试。

python

def square(x):return x ** 2# 简单的测试
assert square(2) == 4
  • 要点
  1. 编写函数应遵循单一职责、避免副作用、提供清晰接口和可测试性原则。

  2. 这些原则有助于提高代码的质量和可维护性。

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

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

相关文章

多个用户如何共用一根网线传输数据

前置知识 一、电信号 网线(如以太网线)中传输的信号主要是 电信号,它携带着数字信息。这些信号用于在计算机和其他网络设备之间传输数据。下面是一些关于网线传输信号的详细信息: 1. 电信号传输 在以太网中,数据是…

华为昇腾 910B 部署 DeepSeek-R1 蒸馏系列模型详细指南

本文记录 在 华为昇腾 910B(65GB) * 8 上 部署 DeepSeekR1 蒸馏系列模型(14B、32B)全过程与测试结果。 NPU:910B3 (65GB) * 8 (910B 有三个版本 910B1、2、3) 模型:DeepSeek-R1-Distill-Qwen-14B、DeepSeek…

【前端】Vue组件库之Element: 一个现代化的 UI 组件库

文章目录 前言一、官网1、官网主页2、设计原则3、导航4、组件 二、核心功能:开箱即用的组件生态1、丰富的组件体系2、特色功能亮点 三、快速上手:三步开启组件化开发1、安装(使用Vue 3)2、全局引入3、按需导入(推荐&am…

关于uniApp的面试题及其答案解析

我的血液里流淌着战意!力量与智慧指引着我! 文章目录 1. 什么是uniApp?2. uniApp与原生小程序开发有什么区别?3. 如何使用uniApp实现条件编译?4. uniApp支持哪些平台,各有什么特点?5. 在uniApp中…

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_pool_t 类型

ngx_pool_t 定义在 src/core/ngx_core.h typedef struct ngx_pool_s ngx_pool_t; ngx_pool_s 定义在 src/core/ngx_palloc.h struct ngx_pool_s {ngx_pool_data_t d;size_t max;ngx_pool_t *current;ngx_chain_t *chain;ng…

力扣 最长递增子序列

动态规划,二分查找。 题目 由题,从数组中找一个最长子序列,不难想到,当这个子序列递增子序列的数越接近时是越容易拉长的。从dp上看,当遍历到这个数,会从前面的dp选一个最大的数加上当前数,注意…

Linux | 进程控制(进程终止与进程等待)

文章目录 Linux | 进程控制 — 进程终止 & 进程等待1、进程终止进程常见退出方法1.1退出码基本概念获取退出码的方式常见退出码约定使用场景 1.2 strerror函数 & errno宏1.3 _exit函数1.4_exit和exit的区别1.4.1 所属头文件与函数原型1.4.2 执行过程差异**结合现象分析…

Android - Handler使用post之后,Runnable没有执行

问题:子线程创建的Handler。如果 post 之后,在Handler.removeCallbacks(run)移除了,下次再使用Handler.postDelayed(Runnable)接口或者使用post时,Runnable是没有执行。导致没有收到消息。 解决办法:只有主线程创建的…

鱼皮面试鸭30天后端面试营

day1 1. MySQL的索引类型有哪些? MySQL里的索引就像是书的目录,能帮数据库快速找到你要的数据。以下是各种索引类型的通俗解释: 按数据结构分 B树索引:最常用的一种,数据像在一棵树上分层存放,能快速定位范围数据…

【核心算法篇十二】《深入解剖DeepSeek多任务学习:共享表示层的24个设计细节与实战密码 》

引言:为什么你的模型总在"精神分裂"? 想象你训练了一个AI实习生: 早上做文本分类时准确率90%下午做实体识别却把"苹果"都识别成水果公司晚上做情感分析突然开始输出乱码这就是典型的任务冲突灾难——模型像被不同任务"五马分尸"。DeepSeek通…

DeepSeek应用——与PyCharm的配套使用

目录 一、配置方法 二、使用方法 三、注意事项 1、插件市场无continue插件 2、无结果返回,且在本地模型报错 记录自己学习应用DeepSeek的过程,使用的是自己电脑本地部署的私有化蒸馏模型...... (举一反三,这个不单单是可以用…

2025最新智能优化算法:改进型雪雁算法(Improved Snow Geese Algorithm, ISGA)求解23个经典函数测试集,MATLAB

一、改进型雪雁算法 雪雁算法(Snow Geese Algorithm,SGA)是2024年提出的一种新型元启发式算法,其灵感来源于雪雁的迁徙行为,特别是它们在迁徙过程中形成的独特“人字形”和“直线”飞行模式。该算法通过模拟雪雁的飞行…

vscode通过ssh连接服务器实现免密登录+删除

文章目录 参考: 1、 vscode通过ssh连接服务器实现免密登录删除(吐血总结)

MySQL 主从复制原理及其工作过程

一、MySQL主从复制原理 MySQL 主从复制是一种将数据从一个 MySQL 数据库服务器(主服务器,Master)复制到一个或多个 MySQL 数据库服务器(从服务器,Slave)的技术。以下简述其原理,主要包含三个核…

【赵渝强老师】Spark RDD的缓存机制

Spark RDD通过persist方法或cache方法可以将计算结果的缓存,但是并不是这两个方法被调用时立即缓存,而是触发后面的action时,该RDD才会被缓存在计算节点的内存中并供后面重用。下面是persist方法或cache方法的函数定义: def pers…

设计模式相关知识点

目录 设计模式 设计模式 代码设计原则 设计模式 设计模式 干掉if...else,最好用的3种设计模式! | 小傅哥 bugstack 虫洞栈 代码设计原则-CSDN博客 23种设计模式-CSDN博客 策略模式(Strategy Pattern)-CSDN博客 责任链模式…

ShenNiusModularity项目源码学习(9:项目结构)

ShenNiusModularity源码主要有11个project(其实还有officialweb、test两个文件夹,大致有4、5个project,但看着跟主要项目代码没太大关系,暂时不管),这11个project的依赖关系如下图所示,其中最下…

ubuntu22.4搭建单节点es8.1

下载对应的包 elasticsearch-8.1.1-linux-x86_64.tar.gz 创建es租户 groupadd elasticsearc useradd elasticsearch -g elasticsearch -p elasticsearch chmod uw /etc/sudoers chmod -R elasticsearch:elasticsearch elasticsearch 修改配置文件 vim /etc/sysctl.conf vm…

Docker 部署 ollama + DeepSeek

拉取并运行 Ollama Docker 镜像 使用以下命令从 Docker Hub 拉取 Ollama 镜像并运行容器: docker run -d -p 11434:11434 --name ollama ollama/ollama -d:以守护进程模式运行容器,即让容器在后台运行。-p 11434:11434:将容器内…

解决DeepSeek服务器繁忙的有效方法

全球42%的企业遭遇过AI工具服务器过载导致内容生产中断(数据来源:Gartner 2025)。当竞品在凌晨3点自动发布「智能家居安装指南」时,你的团队可能正因DeepSeek服务器繁忙错失「净水器保养教程」的流量黄金期⏳。147SEO智能调度系统…