面试题答案
一键面试优化思路
- 使用缓存来存储用户的登录状态,这样在验证时可以先从缓存中获取,避免每次都查询数据库。
- 可以选择合适的缓存工具,比如Python中的
functools.lru_cache
(适用于简单场景,基于内存缓存),或者使用更专业的缓存工具如Redis(适用于分布式场景,更强大灵活)。这里以functools.lru_cache
为例进行说明。
代码实现
import functools
from flask import session
# 模拟数据库查询函数
def check_user_login_in_db(user_id):
# 实际这里应该是查询数据库的逻辑
return True if user_id in [1, 2, 3] else False
# 优化后的装饰器
def login_required(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
user_id = session.get('user_id')
if not user_id:
return '请先登录', 401
# 使用lru_cache缓存结果
@functools.lru_cache(maxsize=128)
def cached_check_user_login(user_id):
return check_user_login_in_db(user_id)
if cached_check_user_login(user_id):
return func(*args, **kwargs)
else:
return '权限不足', 403
return wrapper
假设这是一个Flask应用中的装饰器,session
用于存储用户会话信息。check_user_login_in_db
模拟数据库查询判断用户是否登录。login_required
装饰器通过lru_cache
缓存了数据库查询结果,提高验证效率。
如果使用Redis作为缓存:
import redis
from flask import session
r = redis.Redis(host='localhost', port=6379, db=0)
# 模拟数据库查询函数
def check_user_login_in_db(user_id):
# 实际这里应该是查询数据库的逻辑
return True if user_id in [1, 2, 3] else False
# 优化后的装饰器
def login_required(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
user_id = session.get('user_id')
if not user_id:
return '请先登录', 401
cache_key = f'user:{user_id}:is_login'
is_login = r.get(cache_key)
if is_login:
if is_login.decode('utf-8') == 'True':
return func(*args, **kwargs)
else:
return '权限不足', 403
else:
is_login = check_user_login_in_db(user_id)
r.set(cache_key, str(is_login))
if is_login:
return func(*args, **kwargs)
else:
return '权限不足', 403
return wrapper
这里使用Redis作为缓存,通过r.get
和r.set
操作缓存,将用户登录状态存储在Redis中,提高验证效率。