Skip to content

Python 面试高频问题 (含 Flask) - 面向新手

基础知识

  • Python 的特点是什么?

    • 易于学习、可读性好、解释型语言。
    • 动态类型、面向对象,拥有丰富的库。
  • Python 的基本数据类型有哪些?

    • 整型 (int): 例如 1, 2, -3
    • 浮点型 (float): 例如 3.14, -2.5
    • 字符串 (str): 例如 "hello", 'world'
    • 布尔型 (bool): TrueFalse
  • 什么是可变类型和不可变类型?举例说明。

    • 可变类型: 值可以修改。例如:列表 (list), 字典 (dict), 集合 (set)。
      python
      my_list = [1, 2, 3]
      my_list[0] = 10  # 可以修改
      print(my_list)  # 输出: [10, 2, 3]
    • 不可变类型: 值不能修改。例如:整型 (int), 浮点型 (float), 字符串 (str), 元组 (tuple)。
      python
      my_string = "hello"
      # my_string[0] = 'H'  # 错误!  字符串不能修改
  • 什么是深拷贝和浅拷贝?有什么区别?

    • 浅拷贝: 创建一个新对象,但新对象中的子对象仍然是原对象的引用。 使用 copy.copy()
    • 深拷贝: 创建一个新对象,并且递归地拷贝所有子对象,创建一个完全独立的副本。 使用 copy.deepcopy()
    python
    import copy
    list1 = [1, [2, 3]]
    list2 = copy.copy(list1)  # 浅拷贝
    list3 = copy.deepcopy(list1) # 深拷贝
    
    list1[1][0] = 99  # 修改 list1 的子列表
    print(list1)  # 输出: [1, [99, 3]]
    print(list2)  # 输出: [1, [99, 3]]  (浅拷贝,子列表也改变)
    print(list3)  # 输出: [1, [2, 3]]  (深拷贝,子列表不变)
  • Python 中如何进行类型转换?举例说明。

    • 使用内置函数:
      • int(): 转换为整数
      • float(): 转换为浮点数
      • str(): 转换为字符串
      • bool(): 转换为布尔值
      • list(), tuple(), dict(), set(): 转换为对应的容器类型
      python
      x = "10"
      y = int(x)  # 将字符串 "10" 转换为整数 10
      print(y)   # 输出: 10
  • 什么是列表推导式?如何使用?举例说明。

    • 一种用一行代码创建新列表的简洁方式。
    • 基本语法: [expression for item in iterable if condition]
    python
    # 创建一个包含 1 到 10 的偶数的列表
    even_numbers = [x for x in range(1, 11) if x % 2 == 0]
    print(even_numbers)  # 输出: [2, 4, 6, 8, 10]
  • 什么是字典推导式?如何使用?举例说明。

    • 一种用一行代码创建新字典的简洁方式。
    • 基本语法: {key_expression: value_expression for item in iterable if condition}
    python
    # 创建一个字典,键是数字,值是数字的平方
    squares = {x: x*x for x in range(1, 6)}
    print(squares)  # 输出: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
  • 什么是生成器 (generator)?有什么作用?

    • 使用 yield 语句的函数。
    • 可以创建迭代器,逐个生成值,而不是一次性生成所有值,节省内存,提高效率。
    python
    def my_generator(n):
        for i in range(n):
            yield i  # 每次生成一个值
    
    for value in my_generator(5):
        print(value)  # 输出: 0, 1, 2, 3, 4
  • 什么是迭代器 (iterator)?有什么作用?

    • 可以被 for 循环遍历的对象。
    • 需要实现 __iter__()__next__() 方法。
    • 迭代器用于逐个访问集合中的元素。
  • __init____new__ 的区别是什么?

    • __new__: 创建实例,先于 __init__ 执行。
    • __init__: 初始化实例,在实例创建后执行。
  • Python 中的多线程是什么?它有什么限制?

    • 使用 threading 模块创建多个线程并发执行。
    • 限制: 由于 GIL (全局解释器锁) 的存在,Python 的多线程在 CPU 密集型任务中无法实现真正的并行(同一时刻只有一个线程能执行 Python 字节码)。 适合 I/O 密集型任务(例如,网络请求)。
  • Python 中的多进程是什么?有什么优势?

    • 使用 multiprocessing 模块创建多个进程并发执行。
    • 优势: 可以实现真正的并行,克服 GIL 的限制,适用于 CPU 密集型任务。
  • 什么是 GIL (全局解释器锁)?它有什么影响?为什么会有 GIL?

    • 全局解释器锁 (Global Interpreter Lock): 在同一时刻只允许一个线程拥有 Python 解释器的控制权。
    • 影响: 限制了 Python 多线程在 CPU 密集型任务中的并行性。
    • 为什么会有 GIL? GIL 是为了简化 CPython 解释器的内存管理,避免多线程同时操作同一内存区域导致的数据竞争问题。 历史原因,以及 CPython 的设计选择。
    • 绕过 GIL 的方法: 使用多进程、使用 C 扩展 (例如,使用 C 编写 CPU 密集型代码,然后通过 Python 调用)。
  • 什么是装饰器 (decorator)?如何使用?

    • 一种用来修改函数或类的强大工具,不修改函数或类本身的代码。
    • 使用 @ 符号。
    python
    def my_decorator(func):  # 装饰器是一个函数
        def wrapper():
            print("Before the function is called.")
            func()
            print("After the function is called.")
        return wrapper
    
    @my_decorator  # 使用装饰器
    def say_hello():
        print("Hello!")
    
    say_hello()
  • 装饰器的作用是什么?有哪些常见的应用场景?

    • 作用:在不修改原有函数代码的情况下,增加额外的功能。
    • 应用场景:
      • 日志记录
      • 性能测试
      • 权限控制
      • 缓存
  • 常见的装饰器有哪些?举例说明。

    • @staticmethod@classmethod: 改变方法的作用域。
      python
      class MyClass:
          @staticmethod
          def my_static_method():
              print("This is a static method.")
      
          @classmethod
          def my_class_method(cls):
              print(f"This is a class method, cls is {cls}")
    • @property: 将方法伪装成属性,可以进行属性的读、写、删除操作。
      python
      class Circle:
          def __init__(self, radius):
              self._radius = radius  # 使用 _ 约定  (并非强制)
      
          @property
          def radius(self):
              return self._radius
      
          @radius.setter
          def radius(self, value):
              if value >= 0:
                  self._radius = value
              else:
                  raise ValueError("Radius cannot be negative")
      
          @property
          def diameter(self):
              return self.radius * 2
    • @functools.wraps: 用于保留原始函数的元信息 (例如,__name__, __doc__)。 重要! 当装饰器修改了函数时,原函数的元信息会丢失,导致问题。 使用 functools.wraps 可以解决。
      python
      import functools
      
      def my_decorator(func):
          @functools.wraps(func)  # 保留原始函数的元信息
          def wrapper(*args, **kwargs):
              """This is the wrapper function's docstring."""
              print("Before the function is called.")
              result = func(*args, **kwargs)
              print("After the function is called.")
              return result
          return wrapper
      
      @my_decorator
      def say_hello():
          """This is the original function's docstring."""
          print("Hello!")
      
      print(say_hello.__name__)  # 输出: say_hello
      print(say_hello.__doc__)   # 输出: This is the original function's docstring.
    • Flask 路由装饰器: 例如,@app.route('/')
  • Python 中的魔法方法 (magic methods) / 特殊方法是什么?举例说明。

    • 以双下划线 __ 开头和结尾的方法。
    • 用于实现类的特殊行为,例如:
      • __init__: 初始化对象。
      • __str__: 返回对象的字符串表示。
      • __len__: 返回对象的长度 (用于 len() 函数)。
      • __getitem__: 实现索引访问 (例如 obj[index])。
      • __setitem__: 实现索引赋值 (例如 obj[index] = value)。
      • __delitem__: 实现索引删除 (例如 del obj[index])。
  • 什么是面向对象编程 (OOP)?Python 如何实现 OOP?

    • OOP: 一种编程范式,将程序组织成对象,对象包含数据 (属性) 和操作数据的方法。
    • Python 实现 OOP: 类、对象、继承、多态、封装。
  • self 的作用是什么?

    • 指向类的实例本身
    • 在实例方法中,必须作为第一个参数传递。
  • Python 中的继承是什么?

    • 一个类 (子类) 可以继承另一个类 (父类) 的属性和方法。
    • class 子类(父类):
  • Python 中的多态是什么?举例说明。

    • 不同的对象可以对同一方法做出不同的响应。 Python 是动态语言,依赖鸭子类型。
    python
    class Dog:
        def speak(self):
            return "Woof!"
    
    class Cat:
        def speak(self):
            return "Meow!"
    
    def animal_sound(animal):
        print(animal.speak())  # 无论是什么动物,调用speak()方法
    
    dog = Dog()
    cat = Cat()
    animal_sound(dog)  # 输出: Woof!
    animal_sound(cat)  # 输出: Meow!
  • Python 中的封装是什么?

    • 将数据 (属性) 和方法封装在一个类中,隐藏实现细节,只暴露必要的接口。
    • 使用访问修饰符 (public, protected, private)。 (Python 没有严格的 private 修饰符,使用 ___ 来约定)。

常用模块

  • os 模块的作用是什么?常用的方法有哪些?

    • 提供与操作系统交互的功能。
    • 常用方法:
      • os.getcwd(): 获取当前工作目录。
      • os.chdir(path): 改变当前工作目录。
      • os.listdir(path): 列出指定目录下的文件和目录。
      • os.mkdir(path): 创建目录。
      • os.remove(path): 删除文件。
      • os.rename(src, dst): 重命名文件或目录。
      • os.path.join(path1, path2, ...): 拼接路径。
      • os.path.exists(path): 判断路径是否存在。
  • sys 模块的作用是什么?常用的方法有哪些?

    • 提供与Python 解释器交互的功能。
    • 常用方法:
      • sys.argv: 命令行参数列表。
      • sys.path: 模块搜索路径。
      • sys.exit(): 退出程序。
      • sys.stdin, sys.stdout, sys.stderr: 标准输入、标准输出、标准错误。
  • re 模块的作用是什么?常用的正则表达式有哪些?

    • 用于正则表达式操作。
    • 常用正则表达式:
      • .: 匹配任意字符 (除了换行符)。
      • ^: 匹配字符串的开头。
      • $: 匹配字符串的结尾。
      • *: 匹配 0 次或多次。
      • +: 匹配 1 次或多次。
      • ?: 匹配 0 次或 1 次。
      • []: 字符集,匹配其中任意一个字符。
      • (): 分组。
    • 常用方法:
      • re.search(pattern, string): 在字符串中搜索匹配项。
      • re.match(pattern, string): 从字符串的开头开始匹配。
      • re.findall(pattern, string): 查找所有匹配项,返回列表。
      • re.sub(pattern, repl, string): 替换匹配项。
  • datetime 模块的作用是什么?常用的类有哪些?

    • 用于处理日期和时间
    • 常用类:
      • datetime.datetime: 表示日期和时间。
      • datetime.date: 表示日期。
      • datetime.time: 表示时间。
      • datetime.timedelta: 表示时间差。
  • json 模块的作用是什么?常用的方法有哪些?

    • 用于处理 JSON 数据 (序列化和反序列化)。
    • 常用方法:
      • json.dumps(obj): 将 Python 对象序列化为 JSON 字符串。
      • json.loads(json_str): 将 JSON 字符串反序列化为 Python 对象。
  • requests 模块的作用是什么?常用的方法有哪些?

    • 用于发送 HTTP 请求
    • 常用方法:
      • requests.get(url): 发送 GET 请求。
      • requests.post(url, data=data): 发送 POST 请求。
      • requests.put(url, data=data): 发送 PUT 请求。
      • requests.delete(url): 发送 DELETE 请求。
  • math 模块的作用是什么?常用的方法有哪些?

    • 提供数学运算相关函数。
    • 常用方法:
      • math.sqrt(x): 求平方根。
      • math.sin(x), math.cos(x), math.tan(x): 三角函数。
      • math.pi: π 值。
      • math.e: e 值。
  • random 模块的作用是什么?常用的方法有哪些?

    • 生成随机数
    • 常用方法:
      • random.randint(a, b): 生成 [a, b] 范围内的随机整数。
      • random.random(): 生成 [0.0, 1.0) 范围内的随机浮点数。
      • random.choice(seq): 从序列中随机选择一个元素。
      • random.shuffle(seq): 将序列中的元素随机打乱。

异常处理

  • Python 中如何进行异常处理?

    • 使用 try...except...finally 语句。
    python
    try:
        # 可能会发生异常的代码
        result = 10 / 0  # 抛出 ZeroDivisionError 异常
    except ZeroDivisionError:
        # 处理 ZeroDivisionError 异常
        print("除数不能为零!")
    except ValueError:
        # 处理 ValueError 异常
        print("数值错误!")
    finally:
        # 无论是否发生异常,都会执行的代码 (例如,释放资源)
        print("执行 finally 块")
  • 常见的异常类型有哪些?

    • TypeError: 类型错误。
    • ValueError: 值错误。
    • IndexError: 索引超出范围。
    • KeyError: 字典键不存在。
    • IOError: 输入/输出错误。
    • ZeroDivisionError: 除数为零。
    • NameError: 变量名未定义。
    • FileNotFoundError: 文件未找到 (是 IOError 的子类)。
    • AttributeError: 尝试访问对象不存在的属性。
    • ImportError: 模块导入错误。
  • 如何自定义异常?

    • 创建一个新的类,继承自 Exception 类。
    python
    class MyCustomError(Exception):
        def __init__(self, message):
            self.message = message
        def __str__(self):  # 定义异常的字符串表示
            return f"MyCustomError: {self.message}"
    
    try:
        raise MyCustomError("这是一个自定义异常")
    except MyCustomError as e:
        print(f"捕获到自定义异常: {e}")

编码规范 & 工具

  • PEP 8 是什么?

    • Python 的代码风格规范,规定了代码的排版、命名、注释等。
  • 常用的 Python 代码风格检查工具?

    • pylint: 更全面的代码质量检查工具。
    • flake8: 结合了 pycodestyle, pyflakes, 和 mccabe 的检查工具。
    • black: 一个自动化的代码格式化工具,会帮你把代码格式化成符合 PEP 8 的风格。
  • 如何使用虚拟环境?有什么作用?

    • 使用 venv 模块 (Python 3.3 及以上) 或 virtualenv 包。
    • 作用: 隔离不同项目的依赖包,避免版本冲突。
    • 创建虚拟环境:
      bash
      python -m venv <venv_name>  # 使用 venv
      # 或者
      virtualenv <venv_name>  # 使用 virtualenv
    • 激活虚拟环境:
      • Linux/macOS: source <venv_name>/bin/activate
      • Windows: <venv_name>\Scripts\activate
    • 安装依赖: pip install <package_name>
    • 退出虚拟环境: deactivate
  • pip 的作用是什么?

    • Python 的包管理工具,用于安装、卸载、管理 Python 包。
  • requirements.txt 的作用是什么?

    • 记录项目依赖的包及其版本
    • 用于方便地在不同环境中安装项目依赖,实现环境的可复现性
    • 生成 requirements.txt: pip freeze > requirements.txt
    • 安装依赖: pip install -r requirements.txt

进阶问题

  • 如何在 Python 中实现单例模式?

    • 使用元类 (metaclass)。
    python
    class Singleton(type):
        _instances = {}
        def __call__(cls, *args, **kwargs):
            if cls not in cls._instances:
                cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
            return cls._instances[cls]
    
    class MyClass(metaclass=Singleton):
        def __init__(self, name):
            self.name = name
    • 使用模块 (简单易用)。
    python
    # singleton_module.py
    class MyClass:
        def __init__(self, name):
            self.name = name
    instance = MyClass("example")
    
    # another_file.py
    import singleton_module
    print(singleton_module.instance.name)  #  访问单例
    • 使用装饰器。
  • 什么是上下文管理器 (context manager)?如何使用?

    • 用于管理资源的工具,确保资源在使用后被正确释放(例如,关闭文件,释放锁)。
    • 使用 with 语句。
    python
    with open("file.txt", "r") as f:  # 自动处理文件的打开和关闭
        content = f.read()
        print(content)
  • 如何创建自定义的上下文管理器?

    • 实现 __enter__()__exit__() 方法。
    python
    class MyContextManager:
        def __enter__(self):
            print("Entering the context...")
            return self  # 可以返回一个对象,供 with 语句使用
    
        def __exit__(self, exc_type, exc_value, traceback):
            print("Exiting the context...")
            if exc_type:
                print(f"An exception occurred: {exc_type}, {exc_value}")
            return False  # 如果返回 True,则抑制异常
    
    with MyContextManager() as cm:
        print("Inside the context...")
        # 模拟异常
        # raise ValueError("Something went wrong")
    • 可以使用 @contextlib.contextmanager 装饰器。
  • Python 中的协程 (coroutine) 是什么?

    • 一种并发编程方式,使用 asyncawait 关键字。
    • 基于 asyncio 库,用于编写异步代码。 协程是单线程的,但可以实现并发的效果(在等待 I/O 时,切换到其他任务)。
  • 什么是装饰器模式?

    • 在不修改原有对象的情况下,动态地给对象添加一些额外的职责。
    • Python 中使用装饰器来实现。
  • 解释一下 Python 的鸭子类型?

    • 关注对象的行为,而不是其类型。 如果一个对象实现了特定的方法,就可以像该类型一样使用。 “如果它走起来像鸭子,叫起来像鸭子,那么它就是鸭子。”
  • Python 中的 GIL 对多线程和多进程的影响是什么?

    • GIL (全局解释器锁): 限制了 Python 多线程在 CPU 密集型任务中的并行性。
    • 多线程: 在 CPU 密集型任务中,由于 GIL 的存在,多个线程无法真正并行,无法提高性能。
    • 多进程: 可以克服 GIL 的限制,实现真正的并行,适用于 CPU 密集型任务。

Flask 相关

  • Flask 的特点是什么?

    • 轻量级、易于使用、灵活、可扩展。
    • 基于 Werkzeug WSGI 工具包和 Jinja2 模板引擎。
  • Flask 的基本结构是什么?

    python
    from flask import Flask, render_template, request, jsonify
    
    app = Flask(__name__)  # 创建 Flask 实例
    
    @app.route("/")  # 定义路由,对应一个 URL
    def hello_world():
        return "<p>Hello, World!</p>"  # 视图函数,返回响应
    
    if __name__ == '__main__':
        app.run(debug=True)  # 启动开发服务器
  • Flask 的路由 (Routing) 机制是什么?

    • 使用 @app.route() 装饰器定义 URL 规则和关联的视图函数。
    • 支持动态路由 (例如 <int:id>),用于处理 URL 参数。
    • 支持 HTTP 方法 (GET, POST, PUT, DELETE, etc.)。
  • Flask 中的请求 (Request) 对象有什么作用?如何获取请求数据?

    • request 对象用于访问客户端发送的请求数据。
    • 常用属性:
      • request.method: HTTP 方法 (GET, POST, etc.)
      • request.args: GET 请求的查询参数 (例如 /search?q=python)。
      • request.form: POST 请求的表单数据。
      • request.files: 上传的文件。
      • request.headers: HTTP 请求头。
      • request.cookies: Cookie 信息。
    python
    from flask import Flask, request, jsonify
    
    app = Flask(__name__)
    
    @app.route('/login', methods=['POST'])
    def login():
        username = request.form.get('username')  # 从表单获取数据
        password = request.form.get('password')
        # ... 验证用户 ...
        return jsonify({'message': 'Login successful'})
  • Flask 中的响应 (Response) 对象有什么作用?如何构建响应?

    • Response 对象用于构建服务器的响应。
    • 可以返回字符串、HTML 内容,或者使用 make_response() 创建自定义响应。
    • jsonify() 可以将 Python 对象转换为 JSON 响应。
    python
    from flask import Flask, jsonify, make_response
    
    app = Flask(__name__)
    
    @app.route('/api/data')
    def get_data():
        data = {'message': 'Hello, Flask!'}
        return jsonify(data)  # 返回 JSON 响应
    
    @app.route('/error')
    def error_example():
        response = make_response("Error!", 500)  # 设置状态码
        return response
    • 设置状态码:response.status_code = 200 (或其他状态码)。
  • Flask 中的模板 (Template) 是什么?如何使用模板?

    • 使用 Jinja2 模板引擎。
    • render_template() 函数用于渲染模板。
    • 模板中可以使用变量、控制结构 (if/else, for 循环) 和模板继承。
    python
    from flask import Flask, render_template
    
    app = Flask(__name__)
    
    @app.route('/hello/<name>')
    def hello(name):
        return render_template('hello.html', name=name)  # 渲染模板
    
    # hello.html 模板 (示例)
    # <h1>Hello, {{ name }}!</h1>
  • Flask 中的静态文件处理是怎么样的?

    • 静态文件 (CSS, JavaScript, 图片等) 存储在 static 目录下。
    • 使用 url_for('static', filename='...') 生成静态文件 URL。
    python
    # 假设 static 目录下有一个 style.css 文件
    from flask import Flask, url_for
    
    app = Flask(__name__)
    
    @app.route('/')
    def index():
        css_url = url_for('static', filename='style.css')
        return f'<link rel="stylesheet" href="{css_url}">'
  • Flask 的上下文 (Context) 是什么?有哪些类型的上下文?

    • 请求上下文 (Request Context): 包含与特定请求相关的信息 (例如 request 对象, session 对象)。 由 app.app_context()app.test_request_context() 创建。
    • 应用上下文 (Application Context): 包含与应用程序相关的信息 (例如 current_app, 配置)。 由 app.app_context() 创建.
    • 上下文用于在处理请求期间访问全局对象。
  • Flask 中的会话 (Session) 是什么?

    • 用于在用户会话期间存储数据
    • 默认情况下,Flask 使用 Cookie 存储会话数据 (有安全风险)。
    • 可以配置使用其他存储方式 (例如,服务器端存储)。
    • 使用 session 对象访问会话数据。
    python
    from flask import Flask, session, redirect, url_for
    
    app = Flask(__name__)
    app.secret_key = "your_secret_key"  # 设置 secret_key  用于加密session
    
    @app.route('/login')
    def login():
        session['username'] = 'example_user'
        return redirect(url_for('profile'))  # 重定向到 profile 页面
    
    @app.route('/profile')
    def profile():
        if 'username' in session:
            return f"Hello, {session['username']}!"
        return "You are not logged in"
  • Flask 中的配置 (Configuration) 是什么?如何设置?

    • 用于配置 Flask 应用程序的行为
    • app.config 字典用于存储配置信息。
    • 可以从文件加载配置、设置环境变量。
    python
    from flask import Flask
    
    app = Flask(__name__)
    app.config['DEBUG'] = True  # 启用调试模式
    app.config['SECRET_KEY'] = "your_secret_key"  # 设置密钥
    # app.config.from_pyfile('config.py') # 从文件加载配置
    • 常用配置项:DEBUG, SECRET_KEY, DATABASE_URL
  • Flask 中的蓝图 (Blueprint) 是什么?

    • 用于组织大型 Flask 应用程序
    • 可以将相关的视图、模板、静态文件组织到蓝图中。
    • 蓝图可以重复使用,方便代码复用和模块化。
  • Flask 中如何处理表单?

    • 使用 request.form 访问表单数据 (POST 请求)。
    • 可以使用 Flask-WTF 扩展,简化表单处理和验证。
  • Flask 中如何进行数据库操作?

    • 可以使用 Flask-SQLAlchemy 扩展,简化与数据库的交互。
    • 定义数据库模型。
    • 使用 ORM (Object-Relational Mapping) 操作数据库。
  • Flask 中如何进行单元测试?

    • 使用 app.test_client() 创建测试客户端。
    • 模拟 HTTP 请求。
    • 断言响应状态码、内容等。
    • 可以使用 pytest 等测试框架。
  • Flask-SQLAlchemy 是什么?作用是什么?

    • Flask 的一个扩展,用于简化与 SQLAlchemy 数据库的交互。
    • 提供 ORM (Object-Relational Mapping) 功能。
  • ORM (Object-Relational Mapping) 的作用是什么?

    • 将数据库表映射为 Python 对象。
    • 使用 Python 代码操作数据库,简化数据库操作。
  • SQLAlchemy 是什么?如何在 Flask 中使用 SQLAlchemy (通过 Flask-SQLAlchemy)?

    • SQLAlchemy: 是一个强大的 Python SQL 工具包和 ORM 库。
    • Flask-SQLAlchemy: 是 Flask 的一个扩展,简化了在 Flask 应用中使用 SQLAlchemy 的过程。
    • 使用步骤:
      1. 安装: pip install flask-sqlalchemy
      2. 配置数据库连接: 在 Flask 应用中配置数据库 URL。 例如:
        python
        from flask import Flask
        from flask_sqlalchemy import SQLAlchemy
        
        app = Flask(__name__)
        app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///example.db' # 使用 SQLite 数据库,文件名为 example.db
        app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False  # 禁用追踪修改,可以提高性能
        
        db = SQLAlchemy(app) # 创建 SQLAlchemy 实例
      3. 定义模型 (models): 定义数据库表对应的 Python 类。
        python
        class User(db.Model):
            id = db.Column(db.Integer, primary_key=True)
            username = db.Column(db.String(80), unique=True, nullable=False)
            email = db.Column(db.String(120), unique=True, nullable=False)
        
            def __repr__(self):  # 定义对象的字符串表示,便于调试
                return '<User %r>' % self.username
      4. 创建数据库表:
        python
        with app.app_context():  # 必须在应用上下文里创建
            db.create_all()  # 创建所有模型对应的表
      5. 数据库操作 (CRUD): 使用 Python 代码进行数据库的增删改查。
        python
        from flask import Flask, render_template, request, redirect, url_for
        from flask_sqlalchemy import SQLAlchemy
        
        app = Flask(__name__)
        app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///example.db'
        app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
        db = SQLAlchemy(app)
        
        class User(db.Model):
            id = db.Column(db.Integer, primary_key=True)
            username = db.Column(db.String(80), unique=True, nullable=False)
            email = db.Column(db.String(120), unique=True, nullable=False)
        
            def __repr__(self):
                return '<User %r>' % self.username
        
        with app.app_context():
            db.create_all()
        
        @app.route('/')
        def index():
            users = User.query.all() # 查询所有用户
            return render_template('index.html', users=users)
        
        @app.route('/add', methods=['POST'])
        def add_user():
            if request.method == 'POST':
                username = request.form['username']
                email = request.form['email']
                new_user = User(username=username, email=email)
                db.session.add(new_user) # 添加到 session
                db.session.commit() # 提交到数据库
                return redirect(url_for('index')) # 重定向到首页
        
            return render
  • SQLAlchemy 数据库操作 (CRUD - 增删改查) 怎么做? (接上一个问题)

    • 创建 (Create):

      • 创建模型实例,添加到 session,提交。
      python
      from flask import Flask, request, redirect, url_for
      from flask_sqlalchemy import SQLAlchemy
      
      app = Flask(__name__)
      app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///example.db'
      app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
      db = SQLAlchemy(app)
      
      class User(db.Model):
          id = db.Column(db.Integer, primary_key=True)
          username = db.Column(db.String(80), unique=True, nullable=False)
          email = db.Column(db.String(120), unique=True, nullable=False)
      
          def __repr__(self):
              return '<User %r>' % self.username
      
      with app.app_context():
          db.create_all()
      
      @app.route('/add', methods=['POST'])
      def add_user():
          if request.method == 'POST':
              username = request.form['username']
              email = request.form['email']
              new_user = User(username=username, email=email)
              db.session.add(new_user) # 添加到 session
              db.session.commit() # 提交到数据库
              return redirect(url_for('index')) # 重定向到首页
          return "Add User Form"
    • 读取 (Read):

      • 使用 query 对象进行查询。
      • User.query.all(): 获取所有用户。
      • User.query.get(id): 根据 ID 获取用户。
      • User.query.filter_by(username='xxx').first(): 根据用户名获取第一个用户。
      • User.query.filter(User.email.like('%@example.com%')).all(): 使用 filter 进行更复杂的查询 (like, 比较运算符等)。
      python
      @app.route('/')
      def index():
          users = User.query.all() # 查询所有用户
          return render_template('index.html', users=users)
    • 更新 (Update):

      • 获取要更新的实例。
      • 修改实例的属性。
      • 添加到 session,提交。
      python
      @app.route('/update/<int:user_id>', methods=['POST'])
      def update_user(user_id):
          user = User.query.get_or_404(user_id)
          if request.method == 'POST':
              user.username = request.form['username']
              user.email = request.form['email']
              db.session.commit()
              return redirect(url_for('index'))
          return render_template('update.html', user=user)
    • 删除 (Delete):

      • 获取要删除的实例。
      • 从 session 中删除。
      • 提交。
      python
      @app.route('/delete/<int:user_id>')
      def delete_user(user_id):
          user = User.query.get_or_404(user_id)
          db.session.delete(user)
          db.session.commit()
          return redirect(url_for('index'))
  • Flask 中的中间件 (Middleware)?

    • 在请求到达视图函数之前或响应返回给客户端之后执行的代码。
    • 可以用于日志记录、身份验证、请求处理等。
    • 使用 app.before_request, app.after_request, app.teardown_request 装饰器。
    python
    from flask import Flask, request, jsonify
    
    app = Flask(__name__)
    
    @app.before_request
    def before_request_callback():
        print("Before request...")
        # 可以进行身份验证,日志记录等操作
    
    @app.after_request
    def after_request_callback(response):
        print("After request...")
        # 可以修改响应,设置响应头等
        return response
    
    @app.route('/')
    def hello():
        return jsonify({'message': 'Hello, World!'})
  • 如何部署 Flask 应用?

    • 使用 WSGI 服务器 (例如 Gunicorn, uWSGI)。 WSGI 服务器将请求转发给你的 Flask 应用。
    • 使用反向代理服务器 (例如 Nginx, Apache)。 反向代理可以处理静态文件、负载均衡、SSL 证书等。
    • 云服务平台 (例如 AWS, Google Cloud, Heroku)。 这些平台提供了方便的部署和管理工具。
    • 部署步骤 (典型):
      1. 准备代码: 确保你的 Flask 应用代码已准备好 (包括 requirements.txt)。
      2. 选择 WSGI 服务器: 例如 Gunicorn: gunicorn --workers 3 --bind 0.0.0.0:5000 app:app (假设你的 Flask 应用在 app.py 中,app 是 Flask 实例)
      3. 配置反向代理 (可选): 如果需要负载均衡、SSL 等,配置 Nginx 或 Apache。
      4. 设置环境变量: 设置必要的环境变量 (例如,数据库连接字符串、密钥)。
      5. 启动服务: 启动 WSGI 服务器,或者配置云服务平台。

RESTful API 相关

  • RESTful API 的概念是什么?

    • Representational State Transfer,一种设计风格
    • 使用 HTTP 方法 (GET, POST, PUT, DELETE) 对资源进行操作。
    • 使用 JSON 或 XML 作为数据交换格式。
    • 核心原则:
      • 客户端-服务器: 客户端和服务器分离。
      • 无状态性: 服务器不保存客户端的状态。 每个请求都包含所有必要的信息。
      • 缓存: 可以缓存服务器的响应,提高性能。
      • 统一接口: 使用统一的接口 (HTTP 方法) 来操作资源。
      • 分层系统: 客户端可以访问中间层,隐藏服务器的复杂性。
  • Flask 中如何创建 RESTful API?

    • 使用 Flask 的路由和视图函数,处理 HTTP 请求。
    • 使用 request 对象获取请求数据。
    • 使用 jsonify() 返回 JSON 响应。
    • 可以结合 Flask-RESTful 或 Flask-RESTX 等扩展,简化 API 的创建。
  • HTTP 方法 (GET, POST, PUT, DELETE) 的作用是什么?

    • GET: 获取资源。 幂等 (多次执行结果一致)。
    • POST: 创建资源。
    • PUT: 更新资源 (完整替换)。 幂等。
    • PATCH: 更新资源 (部分更新)。
    • DELETE: 删除资源。 幂等。
    • 幂等性: 多次执行相同操作,结果一致。例如,PUT 和 DELETE 是幂等的,而 POST 通常不是。
  • HTTP 状态码的作用是什么?有哪些常见的状态码?

    • 表示服务器对客户端请求的处理结果。
    • 2xx (成功):
      • 200 OK (成功)
      • 201 Created (已创建)
      • 204 No Content (成功,但没有内容返回)
    • 3xx (重定向):
      • 301 Moved Permanently (永久移动)
      • 302 Found (临时移动)
      • 304 Not Modified (未修改,使用缓存)
    • 4xx (客户端错误):
      • 400 Bad Request (错误请求)
      • 401 Unauthorized (未授权)
      • 403 Forbidden (禁止访问)
      • 404 Not Found (未找到)
      • 405 Method Not Allowed (方法不允许)
      • 422 Unprocessable Entity (请求格式正确,但语义错误,例如,数据验证失败)
    • 5xx (服务器错误):
      • 500 Internal Server Error (服务器内部错误)
      • 503 Service Unavailable (服务不可用)

其他

  • 解释一下你对单元测试、集成测试和端到端测试的理解?

    • 单元测试: 测试单个函数或类的方法。 目的是验证代码的最小单元是否按预期工作。 编写单元测试时,通常需要 mock 依赖项。
    • 集成测试: 测试多个模块协同工作的情况。 验证模块之间的交互是否正确。
    • 端到端测试: 测试整个系统的功能,模拟用户操作。 从用户角度出发,测试系统是否满足业务需求。
  • 你在 Python 项目中遇到的最大的挑战是什么?你是如何解决的? (准备好项目经验,包括具体技术,解决问题的步骤,和学到的东西) 例如:

    • 性能问题 (如何分析,如何优化)
    • 数据库问题 (SQL 优化,ORM 问题)
    • 依赖管理问题 (虚拟环境,包版本冲突)
    • 代码可读性和可维护性问题 (代码风格,重构)
    • 团队协作问题 (代码审查,沟通)
  • 你最喜欢的 Python 特性是什么? (例如,列表推导式、装饰器、生成器等) 为什么喜欢? 解释其优点和应用场景。

  • 你最熟悉的 Python 库是什么? (准备好相关的项目经验,说明你为什么熟悉它,它解决了什么问题,你的使用经验)

  • 面试准备建议:

    • 回顾基础知识: 确保你对 Python 的基本概念 (数据类型、控制流、函数等) 有清晰的理解。
    • 动手实践: 编写代码,解决一些小问题,加深对 Python 的理解。
    • 准备项目经验: 准备好分享你参与过的项目,着重描述你做了什么,遇到了什么问题,以及如何解决的。 准备一个简短的 Flask 项目示例。
    • 清晰表达: 用清晰的语言解释你的理解,展示你的沟通能力。
    • 积极思考: 如果不知道答案,可以尝试分析问题、给出你的思路,或者说明你如何查找答案。
    • 提问: 面试结束时,可以向面试官提问,了解更多关于公司和团队的信息。 例如:
      • 团队使用的技术栈
      • 团队的开发流程
      • 你的角色和职责
      • 公司的发展方向
      • 你未来可能面临的挑战