Skip to main content

Python 面试

Python 面试

1. Python 中的列表和元组有什么区别?

  • Python 中的列表(list)和元组(tuple)都是内置的数据结构,用于存储序列数据。它们之间的主要区别在于列表是可变的,而元组是不可变的。
  • 列表和元组都可以用于存储有序的数据集合,但是列表是可变的,适合需要修改数据的场景,而元组是不可变的,适合用于创建固定数据组合的场景。

2. 如何在 Python 中管理内存?

  • 使用内建数据类型, 避免循环引用, 使用生成器, 优化数据结构,手动释放内存, 使用垃圾收集器, 跟踪内存使用情况tracemalloc, 使用contextlib中的contextmanager, 管理对象池, 如果使用 C 扩展请确保正确管理内存分配和释放。

3. python 列表推导式与生成器之间的区别?

  • 列表推导式(list comprehensions)和生成器表达式(generator expressions)在 Python 中都是用于从一个序列或可迭代对象创建新的序列的简洁且强大的工具。
  • 性能
    • 列表推导式由于需要一次性生成整个列表,所以对于小到中等大小的列表,可以快速地进行操作和访问。
    • 生成器表达式适合处理大型数据集或不确定长度的数据流,因为它们有更低的内存消耗特点,并且元素是按需生成的。
  • 用途
    • 列表推导式主要用于当你需要立即访问创建的列表时,或者当内存大小不是限制因素时。
    • 生成器表达式适用于延迟计算,特别是当你不需要立即访问所有元素,或者只需要迭代一次,或者处理大量数据时。

4. Python 中的“self”关键字是什么意思?

  • 习惯用法
  • 当你创建一个类的新实例并调用其方法时,Python 会自动传递实例作为第一个参数,这个参数通常在方法定义中被命名为 self。

5. python 面对对象中有哪些特殊的魔术方法(magic methods)?

  • __init__(self, [...]), __del__(self), __repr__(self), __str__(self)

6. 什么是 Python 的生成器?它们是如何工作的?

  • Python 中的生成器(Generator)是一种特殊的迭代器,它允许你以一种更节省内存的方式来遍历一组值。生成器的工作原理基于延迟计算(也称为惰性求值),它仅在需要时产生值,而不是一次性地生成并存储所有的值。
  • 生成器可以通过两种方式创建:
    • 使用带有 yield 关键字的函数。
    • 使用生成器表达式(类似于列表推导式,但使用圆括号)。
  • 生成器提供了一种优雅的方式来处理大数据集或无穷序列,而不必担心内存消耗问题,因为在任何给定时间点,只有一个值被存储在内存中。

7. Python 中的类和实例变量有什么区别?

  • 关键区别
    • 共享性:类变量由类的所有实例共享,而实例变量是独立于每个实例的。
    • 定义位置:类变量在类定义中声明,而实例变量通常在构造器 init 中通过 self 声明。
    • 访问方式:类变量可以通过类本身或实例访问,实例变量只能通过实例访问。
  • 注意可变数据类型和不变数据类型在其中的处理,其共享性可能导致一些不易发现的错误

8. 解释 Python 中的装饰器及其用途?

  • 在 Python 中,装饰器是一种设计模式,用来修改或增强函数、方法或类的行为,而无需直接修改其本身的代码。装饰器具有高度的灵活性和可复用性,是函数式编程的一个例证。
  • 装饰器通常是一个接收函数作为参数并返回一个新函数的可调用对象(通常也是一个函数)。
def my_decorator(func):
def wrapper():
print("Something is happening before the function is called.")
func()
print("Something is happening after the function is called.")
return wrapper

@my_decorator
def say_hello():
print("Hello!")

say_hello()
  • 装饰器的用途广泛,包括但不限于:
    • 日志记录, 认证, 缓存, 性能测试, 参数检查, 事务处理

Problem solving and debugging skills with Python

1. 在处理大型 Python 代码库时,你会如何有效地定位和解决性能问题?

  1. 分析和确定性能问题
    • 确性能问题的表现形式(如响应时间缓慢、资源消耗过高等)以及性能期望值
  2. 使用性能分析工具
    • pdb tool
    • cProfile
      • cProfile.run() # 代码或者函数
      • cProfile.enable() and cProfile.disable()
      • then report by pstats module: status = pstats.Stats(profiler), status.print_stats()
  3. Define a test case, an unittest to compare times comsumption.
  4. Review codes for the part complexe and comsume much time
    • Convert data structure unecessary
    • Repeat loop calculation
    • Many function call and recursion
  5. Opitmize strategy
    • Optmize algorithm
    • Refactorize cdoes
    • Multiple thread or processing to handle job
    • Reduce I/O operation and introduce Cache
    • Use C extension
  6. Retest after optimisation
  7. Monitoring and logs the performance if we apply into production environment
  8. Always iterate if needed

2. 如何使用 Python 的调试工具(如 pdb)进行问题定位?

python -m pdb main.py
# step into, step over(coninue), jump to certain line, set breakpoints

break 4 # set breakpoint at line 4
tbreak 4 # temporal breakpoint, break once
continue # step over
c # abbreviation step over

p value_1 # show value_1 varaible value
p values_array # show values_array list

next # execute one line and go to next line code

step # Go into deeper hold function call

until 6 # Stop when run line 6 or reached(skip running) of line 6 then show line 7

jump 6 # Save state and jump directly forcely to this line event the if condition is false

l # see the position of execution cursor

q # Quit
import pdb;

pdb.set_trace()

breakpoint() # Add breakpoint in main.py file

3. 如何在 Python 中进行单元测试?你通常会如何写测试来确保代码的稳定性和可靠性?

Test tools: unittest, pytest

使用 unittest.TestCase 创建测试类,并在类中使用断言 assertEqual, assertTrue, assertRaises

测试条件:

  • 正常值
  • 边界条件
  • 异常值

Fixtures

  • Fixtures help you configure test environment and clean state at the end.
  • setUp and tearDown in unittest, and @pytest.fixture in pytest

Mock

  • Use mock module unittest.moc and pytest-mock to mock some data of request

Integration of test into CI/CD pipeline

Use coverage.py check the cover of test

MECE principle: Mutually Exclusive, Collectively Exhaustive

  • Test one feature/function for one test
  • Readable
  • Independant: the test doesn't depend other test case or doesn't have order.
  • Repeatable: return the same value in different environment

4. 描述一个场景,在该场景中你必须阅读和理解别人的代码。你是如何适应和理解这段代码的?

  1. 文档和架构概览 Docs: 寻找任何可用的文档,如 README 文件、Developer Guid、API doc、Design doc、requirement doc 和 comments.
  2. 代码结构 Structure of codes: Check summary, make certain the modules, classes, views and tools folder.
  3. 入口点 main.py: Find main function or main.py, config file to know how to start program.
  4. Core class and method: Understand how they work.
  5. Debug tools: monitoring the state change in program.
  6. Unittest: some times we have some comments in test, or we can know the fuction/feature for one specifty funciton by unit test.
  7. Change and experiment: change minimum then observe resutls.
  8. Review codes: review others codes to know team's best practice and coding norms.
  9. Ask question: ask author and colleague who knows.
  10. Write notes: write down your understand about the codes and assemble every small understand to have a overview of the system.