Skip to content

高级面试题

python 常用的标准库

面试题目

  • 级别: L1
  • 知识模块: Python 编程语言

python 常用的标准库有哪些?

公司

  • 字节外包

招聘类型

  • 社招

题目解析

答案

开发一个随机验证码生成函数

面试题目

  • 级别: L1
  • 知识模块: Python 编程语言

开发一个随机验证码生成函数,生成 20 个由 5 位数字或字母构成的字符串,但数字最多不能超过 2 个。

开发另一个单元测试函数,验证生成的字符串的确没有大于 2 个的数字。

公司

  • 字节外包

招聘类型

  • 社招

题目解析

在这道题目中,我们需要开发一个函数来生成 20 个验证码,每个验证码由 5 位字符构成,其中数字最多不能超过 2 个。然后,我们还需要编写一个单元测试函数来验证这些验证码的格式是否符合要求。

答案

为了生成符合要求的验证码,可以使用 random 模块生成随机字符,并确保每个验证码中的数字不超过 2 个。

代码:

import random
import string

def generate_verification_codes(count=20, length=5, max_digits=2):
    codes = []
    for _ in range(count):
        while True:
            code = ''.join(random.choices(string.ascii_letters + string.digits, k=length))
            if sum(c.isdigit() for c in code) <= max_digits:
                codes.append(code)
                break
    return codes

# 生成 20 个验证码
verification_codes = generate_verification_codes()
for code in verification_codes:
    print(code)

单元测试函数

为了验证生成的验证码是否符合要求,可以使用 unittest 模块编写一个单元测试函数。

import pytest
from your_module import generate_verification_codes  # 请将 `your_module` 替换为你实际的模块名

def test_verification_codes():
    codes = generate_verification_codes()
    assert len(codes) == 20, "生成的验证码数量不是20个"
    for code in codes:
        assert len(code) == 5, f"验证码 {code} 的长度不是 5 位"
        assert sum(c.isdigit() for c in code) <= 2, f"验证码 {code} 中的数字超过 2 个"

if __name__ == "__main__":
    pytest.main()

解析

  1. 随机验证码生成函数:

    • 随机选择字符: 使用 random.choices() 从字母和数字的组合中随机选择字符生成验证码。
    • 确保数字数量限制: 使用 sum(c.isdigit() for c in code) 计算验证码中的数字个数,如果超过 2 个则重新生成。
  2. 单元测试函数:

    • 验证长度: 使用 assertTrue 确保每个验证码的长度是 5。
    • 验证数字数量: 使用 assertTrue 确保每个验证码中的数字不超过 2 个。

通过上述函数和测试,我们可以确保生成的验证码符合题目要求,并且通过单元测试函数验证这些验证码的格式是否正确。

如何在不改变类的情况下改变类的功能

面试题目

  • 级别: L1
  • 知识模块: Python 编程语言

如何在不改变类的情况下改变类的功能

公司

  • 传音控股

招聘类型

社招

题目解析

题目主要考察对面向对象编程原则的理解。

答案

此题目可分两种角度回答。

  1. 继承重写

通过继承中的方法,在子类中重写同名方法,实现不改变类的情况下更改类的功能

class A(object):
    def show(self):
        print("类中原有方法的功能")

class B(A):
    def show(self):
        print("不改变A类的情况下改变类中方法的功能")

def call_func(obj):
    obj.show()

if __name__ == '__main__':
    a = A()
    b = B()
    call_func(a)
    call_func(b)
  1. 装饰器

可以使用装饰器来扩展类的功能,而不改变原有类的实现。

def method_decorator(func):
    def wrapper(*args, **kwargs):
        print("调用前")
        result = func(*args, **kwargs)
        print("调用后")
        return result
    return wrapper

class MyClass:
    @method_decorator
    def my_method(self):
        print("类中的方法")

# 当调用 my_method 时,会先打印 "调用前",然后执行方法,最后打印 "调用后"

python 中类可以作为装饰器吗?

面试题目

  • 级别: L2
  • 知识模块: Python 编程语言

python 中类可以作为作为装饰器吗?

公司

  • 传音控股

招聘类型

社招

题目解析

题目主要考察对装饰器概念的理解。

答案

类可以作为装饰器,通过在类中实现 __call__ 方法来实现装饰器的功能。

python
class MyDecorator:
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        print("Before calling the function")
        result = self.func(*args, **kwargs)
        print("After calling the function")
        return result

@MyDecorator
def my_function():
    print("Inside the function")

my_function()

在上面的示例中,MyDecorator 类是一个类装饰器,它接受一个函数作为参数,并在 __call__ 方法中定义装饰器的逻辑。在这个示例中,装饰器会在调用 my_function 函数前后打印出相应的信息。

当使用 @MyDecorator 语法将一个函数装饰时,实际上会调用 MyDecorator 类的构造函数,并将被装饰的函数作为参数传递给构造函数。然后,Python 将实例化 MyDecorator 类的对象,并将其返回值作为装饰后的函数。

通过类装饰器,您可以将更复杂的逻辑封装在一个类中,实现更灵活的装饰器功能。类装饰器还允许您在实例化装饰器对象时进行一些初始化操作,从而更好地定制装饰器行为。

python 中如果我要实现反射,怎么实现?

面试题目

  • 级别: L1
  • 知识模块: Python 编程语言

python 中如果我要实现反射,怎么实现?

公司

  • 传音控股

招聘类型

社招

题目解析

题目主要考察 Python 基础知识和动态编程。

答案

可以使用 getattr()、hasattr()、setattr()等方法来实现反射。

迭代器与生成器

面试题目

  • 级别: L1
  • 知识模块: Python 编程语言

迭代器与生成器。

公司

  • 字节外包

招聘类型

  • 社招

题目解析

迭代器和生成器是 Python 中处理数据流的两种重要机制。理解它们之间的区别以及应用场景对于写出高效、优雅的 Python 代码至关重要。

迭代器 (Iterator)

迭代器是一个实现了迭代器协议的对象,即包含 __iter__()__next__() 方法。迭代器用于遍历容器(如列表或字典)中的所有元素。

  • __iter__(): 返回迭代器对象本身。
  • __next__(): 返回容器的下一个元素,如果没有更多元素则抛出 StopIteration 异常。

迭代器的特点:

  1. 惰性计算:迭代器在调用 __next__() 方法时才会计算或获取下一个值。
  2. 单次遍历:迭代器一次遍历后就耗尽,不能重复使用。

示例代码:

class MyIterator:
    def __init__(self, data):
        self.data = data
        self.index = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.index < len(self.data):
            result = self.data[self.index]
            self.index += 1
            return result
        else:
            raise StopIteration

my_iter = MyIterator([1, 2, 3])
for value in my_iter:
    print(value)

生成器 (Generator)

生成器是简化版的迭代器,使用 yield 关键字定义。生成器函数每次遇到 yield 时会暂停并返回一个值,保留函数的运行状态,下一次调用生成器的 __next__() 方法时会从上次暂停的地方继续执行。

生成器的特点:

  1. 惰性求值:和迭代器一样,生成器也是按需生成值。
  2. 更易实现:相比于编写完整的迭代器类,生成器函数更加简洁易读。
def my_generator():
    yield 1
    yield 2
    yield 3

gen = my_generator()
for value in gen:
    print(value)

答案

迭代器和生成器是 Python 中用于处理迭代数据的一种机制。迭代器通过实现 iter()next() 方法来遍历数据结构。生成器是迭代器的一种简化形式,使用 yield 关键字定义,可以在每次调用 next() 时暂停和恢复。

迭代器更加灵活,但需要编写更多的样板代码。它适用于需要自定义迭代逻辑的场景。比如,需要从一个复杂的数据结构中提取数据。

生成器则提供了更简洁的语法,适合于大多数的迭代场景。它可以显著减少代码量,提高代码的可读性。生成器尤其适用于处理需要按需生成数据的场景,比如读取大文件或处理无限序列。