Python-Flask 面试
Flask 面试
1. 描述 Flask 框架及其主要用途
- 使用 Python 编写的轻量级 Web 应用框架,适用于小型项目、原型设计,以及作为学习 web 开发的工具。
- Flask 的主要特性包括, WSGI (Web Server Gateway Interface) 兼容, 路由, 模版渲染(Jinja2), 调试支持, 开发服务器, 单元测试支持, 可扩展。
- Flask 以其最小主义的核心理念脱颖而出,即使在扩展功能的同时,它也鼓励开发者按照自己的方式来扩展应用。这种微框架的方式为开发者提供了很多灵活性,允许他们使用最适合他们需求的组件来构建应用。
2. Flask 和 Django 在 Web 开发中有什么不同?
- 设计哲学:
- Flask: 它是一个微框架,提供了完成 Web 应用开发的最基本工具和功能,如路由、请求响应处理和模板渲染。Flask 的核心简单,它不包括内置的 ORM(对象关系映射)或表单验证工具。
- Django: 它是一个全栈框架,遵循“电池包括在内”的哲学,这意味着它包括了创建一个功能完备 Web 应用所需要的几乎所有东西,例如一个内置的 ORM 系统、一个内置的管理界面、表单序列化与验证工具、文件上传支持、用户认证系统等。
- 开箱即用的功能:
- Flask: Flask 核心非常轻量,Flask 通常需要通过 Flask 扩展来添加这些额外的功能。
- Django: Django 提供了丰富的功能集,包括自动的管理界面、数据库迁移工具、内置的类视图用于快速开发、中间件支持等。
- 灵活性与控制:
- Flask: 更加灵活
- Django: 约定俗成,默认解决方案
- 适用案例
- Flask: 通常用于小到中等规模的项目,API 开发,微服务架构,以及当开发者希望手动选择组件的项目。
- Django: 适合快速开发大型项目,内容管理系统(CMS),有复杂数据库模型和需要高级功能(如用户验证、内容管理等)的应用。
3. 解释在 Flask 中如何处理路由。
- 使用
@app.route("/")
装饰器来告诉 Flask URL"/"
匹配哪个函数 - 加入可变路径, 使用
<
和>
表示 - 加入方法,使用
keyword parameters
, 即methods=["GET", "POST"]
4. 在 Flask 应用中如何管理用户会话?
- 在 Flask 应用中管理用户会话,可以使用 Flask 自带的 session 对象。这个对象背后是一个基于密钥的签名的 cookie ,它可以存储在用户浏览器中。
- 如果你需要存储大量数据,session 也可以将数据存储到 redis/数据库 中,通过在初始化时提供 redis/数据库 的连接设置
- session["user_id"] = user_id
- session["authenicated"] = True
5. 如何在 Flask 应用中实现数据库集成的?
(psycopg2) ORM: Flask-SQLAlchemy
pip install Flask-SQLAlchemy
Define table
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
db.create()
# db.create_all()
db.session.add(new_user)
db.session.commit()
User.query.all()
User.query.filter_by(username="xxx").first()
User.query.filter_by(username="xxx").order_by(model.Entry.amount.desc())
User.get([pk])
select(user_table).where(user_table.c.name == "spongebob")
db.session.delete(user)
db.session.commit()
6. 解释 Flask 中的请求和响应对象
在 Flask 中,请求和响应对象是处理 HTTP 请求和生成 HTTP 响应的核心部分。Flask 使用 Werkzeug 库来提供请求和响应对象,并且使它们易于使用和扩展。
flask.Request
- 请求方法: 可以通过 request.method 访问请求的方法,例如 GET, POST, PUT, DELETE 等。
- URL: request.path 返回请求的路径,而 request.url 返回包括查询字符串在内的完整 URL。
- 表单数据: 对于 POST 或 PUT 请求,表单数据可以通过 request.form 来访问。
- 查询字符串: 查询字符串可以通过 request.args 来访问。
- JSON 数据: 如果请求是一个 JSON 请求,那么可以通过 request.json 来访问 JSON 数据。
- 文件: 上传的文件可以通过 request.files 来访问。
- Cookies: 可以通过 request.cookies 来读取请求中发送的 cookies。
- Headers: 请求头可以通过 request.headers 来访问。
- query_string
flask.Response
响应对象代表服务器返回给客户端的 HTTP 响应。它包括状态码、响应头、响应体等信息。
- 字符串: Flask 会将字符串包装成一个带有 200 OK 状态码和 text/htmlMIME 类型的响应对象。
- 响应对象: 如果你创建了一个 Response 对象,可以直接返回它。这在需要更复杂的响应(如不同的 MIME 类型或特殊的头部信息)时非常有用。
- 元组: 你可以返回一个包含响应体、状态码和头部信息的元组。例如:return 'Hello World!', 200, {'Content-Type': 'text/plain'}。
7. 在 Flask 中如何实现 RESTful API?
- Create Flask app
- Use Flask-restful to createa a API app
from flask_restful import Api
api = Api(app)
- Define resource class
from flask_restful import Resource
class HelloWorld(Resource):
def get(self):
return {'hello': 'world'}
- Add resource to api
api.add_resource(HelloWorld, '/')
- Start api server
if __name__ == '__main__':
app.run(debug=True)
8. Flask 的蓝图(Blueprints)是什么,以及为什么要使用它们?
在 Flask 中,蓝图(Blueprints)是一种组织和重用代码的方式,类似于 Django 中的应用。
蓝图允许你将应用分割成不同的组件,每个组件都有自己的视图函数、模板、静态文件等。这种划分可以帮助你构建大型的、模块化的应用,并且保持代码的清晰和可维护性。
它能够帮助我们把最相关的代码模块化,并且模块与模块之间是相互调用。对于可能出现重复的路由,我们可以注册的过程中提供 prefix_url 的方式为每个模块提供独特的 url 地址。
这能帮助我们简化大型应用代码的管理成本。
9. 描述在 Flask 应用中实现安全措施的策略。
在 Flask 应用中实现安全措施是至关重要的,以保护应用避免各种网络攻击和漏洞利用。
- Protocal
- 使用 HTTPS
- Use secure HTTP head
- header such as X-Content-Type-Options, X-Frame-Options
- Use Flask-Taliman for settings
- Validate all inputs
- 防止跨站脚本攻击 (XSS)
- escape all values
- Use {{ variable | safe }} filter to render html
- 防止跨站请求伪造 (CSRF, Cross-Site Request Forgery):
- Use Flask-WTF or Flask-SeaSurf
- Ensure all form submit contains CSRF token
- 密码处理:
- No save string directly for password
- Use strong password then weak password
- Hash password with
bcrypt
package
- Limit uploaded file type and size
- 防止跨站脚本攻击 (XSS)
- Database
- SQL 注入保护: 使用 ORM 像 SQLAlchemy 这样的库来避免拼接 SQL 查询。
- Codebasde
- Handle all error and exception in app creat custome error page
- limit log content to filter pasword of personal information
- Use
pylint
tool to check the syntax of codes
- Outside
- AWS WAF & Shield (Detect bot traffic, DDoS: Distributed denial-of-service)
- Rate Limiting
- application
- Flask-Limiter
- Infrastructure
- AWS WAF(Web Application Firewall)
- API Gateway
- Apploication Load Blancer(ALB)
- Cache
- Redis
- AWS ElasticCache
- application
10. 如何使用 Flask-Migration
install
pip install Flask-Migration
setup app and create model
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///yourdatabase.db'
db = SQLAlchemy(app)
migrate = Migrate(app, db)
# Define your models (example)
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)
# Other models can follow...
initialze database
db.create_all()
create and apply migrations
flask db migrate -m "Initial migration."
flask db upgrade
flask db downgrade
migrations_file.py
"""Create account table
Revision ID: 011ae1053cfe
Revises: None
Create Date: 2021-01-01 12:34:56.789012
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic
revision = '011ae1053cfe'
down_revision = None
branch_labels = None
depends_on = None
def upgrade():
# Instructions for upgrading the database to the next revision:
op.create_table(
'account',
sa.Column('id', sa.Integer, primary_key=True),
sa.Column('name', sa.String(50), nullable=False),
sa.Column('description', sa.Unicode(200)),
)
def downgrade():
# Instructions for downgrading the database to the previous revision:
op.drop_table('account')