zoukankan      html  css  js  c++  java
  • Flask------一些面试题

    1.请手写一个flask的hello world。


    hello.py中

    #coding = utf-8
    
    # 第一步:导入Flask类
    from flask import Flask
    app = Flask(__name__)
    
    @app.route("/")
    def helloworld():
        return "<h1>hello world</h1>"
    
    if __name__ == " __main__":
        app.run(debug=True)

    2.Flask框架的优势及适用场景?


    优势:

    1.轻量;(Micro Framework)

    2.简洁

    3.扩展性好*

    4 第三方库的选择面广,开发时可以结合自己喜欢用的轮子,也可以结合强大的python库

    5.核心(werzeugjinja2),jinja2就是指模板引擎。

    应用场景:

      适用于小型网站,适用于开发web服务的API;

      开发大型网站也毫无压力,但是代码架构需要开发者自己设计;

    Flask和Nosql数据库的结合优于django

    3.Flask框架组件


    flask_sqlalchemy:将Flask和SQLAlchemy很好的结合在一起,如django中的ORM操作

    flask_script:用于生成命令,在项目根目录路径下使用命令;例如:python manage.py runserver 

    flask_migrate:用来实现数据库迁移(依赖flask_script)

    flask-session:session放在redis里面

    blinker:信号-触发信号

      PS:# flask中的信号blinker 信号主要是让开发者可是在flask请求过程中定制一些行为。 或者说flask在列表里面预留了几个空列表,在里面存东西。 简言之,信号允许某个'发送者'通知'接收者'有事情发生了

    4.Flask蓝图的作用


    # blueprint把实现不同功能的module分开.也就是把一个大的App分割成各自实现不同功能的module.

    # 在一个blueprint中可以调用另一个blueprint的视图函数, 但要加相应的blueprint名.

    通常情况下,我是使用flask框架的项目组织结构是这样的:

    我们看看视图方法:

    #views.py
    from app import app
    
    
    @app.route('/user/index')
    def index():
        return 'user_index'
    
    @app.route('/user/show')
    def show():
        return 'user_show'
    
    @app.route('/user/add')
    def add():
        return 'user_add'
    
    @app.route('/admin/index')
    def adminindex():
        return 'admin_index'
    
    @app.route('/admin/show')
    def adminshow():
        return 'admin_show'
    
    @app.route('/admin/add')
    def adminadd():
        return 'admin_add'

    #从视图方法中,我们看到有6个视图,分别对应admin,user两个不同用户的3个功能index,add,show.
    这样写显然没问题,但是明显与python提倡的模块化冲突;

    当然根据Pythonic特点,我们肯定希望尽可能的把代码尽量的模块化,让我们的代码看起来更加的优雅和顺畅,这个时候flask.Blueprint(蓝图)就派上用场了

    一个蓝图定义了可用于单个应用的视图,模板,静态文件等等的集合

    上面的例子中只有两个组件(模块)admin,user,我们可以创建名为admin.py和user.py的两个文件,分别在里面创建两个蓝图的实例对象admin,user.

    #admin.py
    from flask import Blueprint,render_template, request
    
    admin = Blueprint('admin',__name__)
    
    @admin.route('/index')
    def index():
        return render_template('admin/index.html')
    
    @admin.route('/add')
    def add():
        return 'admin_add'
    
    @admin.route('/show')
    def show():
        return 'admin_show'
    
    #要想创建一个蓝图对象,你需要import flask.Blueprint()类并用参数name和import_name初始化。import_name通常用__name__,一个表示当前模块的特殊的Python变量,作为import_name的取值。
    
    
    #user.py

    from
    flask import Blueprint, render_template, redirect user = Blueprint('user',__name__) @user.route('/index') def index(): return render_template('user/index.html') @user.route('/add') def add(): return 'user_add' @user.route('/show') def show(): return 'user_show'

    视图函数已经分开了 再看看view.py

    #view.py
    
    from app import app
    from .admin import admin
    from .user import user
    #这里分别给app注册了两个蓝图admin,user
    #参数url_prefix='/xxx'的意思是设置request.url中的url前缀,
    #即当request.url是以/admin或者/user的情况下才会通过注册的蓝图的视图方法处理请求并返回
    app.register_blueprint(admin,url_prefix='/admin')
    app.register_blueprint(user, url_prefix='/user')

    再看看使用蓝图后的项目结构:

    如果项目不大的话就没有必要使用蓝图了,我们甚至可以把除了所有css,js,html的代码都写到一个文件中去。

    5.列举Flask使用的第三方组件


    # 第三方组件:

      Wtforms:快速创建前端标签、文本校验

      dbutile:创建数据库连接池

      gevent-websocket:实现websocket

    # 自定义Flask组件

      auth认证

      参考flask-login

    6.简述Flask上下文管理流程。


    Flask中有两种上下文,请求上下文应用上下文

    request和session都属于请求上下文对象。

      request:封装了HTTP请求的内容,针对的是http请求。举例:user = request.args.get('user'),获取的是get请求的参数。

      session:用来记录请求会话中的信息,针对的是用户信息。举例:session['name'] = user.id,可以记录用户信息。还可以通过session.get('name')获取用户信息

    current_app和g都属于应用上下文对象。

      current_app:表示当前运行程序文件的程序实例。

      g:处理请求时,用于临时存储的对象,每次请求都会重设这个变量。比如:我们可以获取一些临时请求的用户信息。

      当调用app = Flask(_name_)的时候,创建了程序应用对象app;
      request 在每次http请求发生时,WSGI server调用Flask.call();然后在Flask内部创建的request对象;
      app的生命周期大于request和g,一个app存活期间,可能发生多次http请求,所以就会有多个request和g。
      最终传入视图函数,通过return、redirect或render_template生成response对象,返回给客户端。
    他们的区别:

     请求上下文:保存了客户端和服务器交互的数据。 应用上下文:在flask程序运行过程中,保存的一些配置信息,比如程序文件名、数据库的连接、用户信息等

    # a、简单来说,falsk上下文管理可以分为三个阶段: 
      1、'请求进来时':将请求相关的数据放入上下问管理中
      2、'在视图函数中':要去上下文管理中取值 
      3、'请求响应':要将上下文管理中的数据清除#
    # b、详细点来说:  
      1、'请求刚进来':
        将request,session封装在RequestContext类中
        app,g封装在AppContext类中
        并通过LocalStack将requestcontext和appcontext放入Local类中
      2、'视图函数中':
        通过localproxy--->偏函数--->localstack--->local取值
      3、'请求响应时':
        先执行save.session()再各自执行pop(),将local中的数据清除

    7.Flask中g的作用


    g:gloal

    1.g对象是专门用来来保存用户数据的;

    2.g对象在一次请求中的所有的代码的地方,都是可以使用的

    # g是贯穿于一次请求的全局变量,当请求进来将g和current_app封装为一个APPContext类,
    # 再通过LocalStack将Appcontext放入Local中,取值时通过偏函数在LocalStack、local中取值;
    # 响应时将local中的g数据删除

    8.如何编写flask的离线脚本


    9.Flask中上下文管理主要是涉及到了哪些相关的类?并描述类主要的作用


    RequestContext  #封装进来的请求(赋值给ctx)
    AppContext      #封装app_ctx
    LocalStack      #将local对象中的数据维护成一个栈(先进后出)
    Local           #保存请求上下文对象和app上下文对象

    10.为什么要Flask把Local对象中的值stack维护程一个列表


    # 因为通过维护成列表,可以实现一个栈的数据结构,进栈出栈时只取一个数据,巧妙的简化了问题。
    # 还有,在多app应用时,可以实现数据隔离;列表里不会加数据,而是会生成一个新的列表
    # local是一个字典,字典里key(stack)是唯一标识,value是一个列表

    11.Flask中多app应用如何编写?


    请求进来时,可以根据URL的不同,交给不同的APP处理。蓝图也可以实现

        #app1 = Flask('app01')
        #app2 = Flask('app02')
        #@app1.route('/index')
        #@app2.route('/index2')

    源码中在DispatcherMiddleware类里调用app2.__call__,

    原理其实就是URL分割,然后将请求分发给指定的app。

    之后app也按单app的流程走。就是从app.__call__走。

    12.在Flask中实现WebSocket需要什么组件?


    gevent-websocet

    13.wtforms组件的作用?


    定义:WTForms是一个支持多个web框架的form组件,主要用于对用户请求数据进行验证。

    两种导入方式:

    from wtforms import Form
    from flask_wtf  import FlaskForm  需要设置csrf

    安装:

    pip3 install wtforms
    

    作用:

      快速创建前端标签、文本校验:如django的ModelForm

    14.Flask框架默认的session处理机制?


    15.解释Flask框架中Local对象和threadinglocal对象的区别?


    # a.threading.local
    作用:为每个线程开辟一块空间进行数据存储(数据隔离)。

    问题:自己通过字典创建一个类似于threading.local的东西。
    storage = {
       4740: {val: 0},
       4732: {val: 1},
       4731: {val: 3},
       }

    # b.自定义Local对象
    作用:为每个线程(协程)开辟一块空间进行数据存储(数据隔离)。

    class Local(object):
       def __init__(self):
          object.__setattr__(self, 'storage', {})
       def __setattr__(self, k, v):
          ident = get_ident()
          if ident in self.storage:
             self.storage[ident][k] = v
          else:
             self.storage[ident] = {k: v}
       def __getattr__(self, k):
          ident = get_ident()
          return self.storage[ident][k]
    obj = Local()
    def task(arg):
       obj.val = arg
       obj.xxx = arg
       print(obj.val)
    for i in range(10):
       t = Thread(target=task, args=(i,))
       t.start()

    16.SQLAlchemy中的session和scoped_session的区别?


    # Session:
      由于无法提供线程共享功能,开发时要给每个线程都创建自己的session
      打印sesion可知他是sqlalchemy.orm.session.Session的对象
    # scoped_session:
      为每个线程都创建一个session,实现支持线程安全
      在整个程序运行的过程当中,只存在唯一的一个session对象。
      创建方式:通过本地线程Threading.Local()
      # session=scoped_session(Session)
      创建唯一标识的方法(参考flask请求源码)

    17.SQLAlchemy如何执行原生SQL?


    # 使用execute方法直接操作SQL语句(导入create_engin、sessionmaker)
      engine=create_engine('mysql://root:pwd@127.0.0.1/database?charset=utf8')
      DB_Session = sessionmaker(bind=engine)
      session = DB_Session()
      session.execute('select * from table...;')

    18.ORM的实现原理?


    # ORM的实现基于以下三点

      映射类:描述数据库表结构,

      映射文件:指定数据库表和映射类之间的关系

      数据库配置文件:指定与数据库连接时需要的连接信息(数据库、登录用户名、密码or连接字符串)

    19.DBUtils模块的作用?


    # DBUtils是数据库连接池模块

    使用模式:

      1、为每个线程创建一个连接,连接不可控,需要控制线程数

      2创建指定数量的连接在连接池,当线程访问的时候去取,不够了线程排队,直到有人释放*

    两种写法:

      1.用静态方法装饰器,通过直接执行类的方法来连接使用数据库;

      2.通过实例化对象,通过对象调用方法使用语句;

    20.SQLAlchemy中的如何为表设置引擎和字符编码?


    sqlalchemy设置编码字符集,一定要在数据库访问的URL上增加'charset=utf8',否则数据库的连接就不是'utf8'的编码格式

    1. 设置引擎编码方式为utf8:

      engine = create_engine('mysql://root:root@localhost:3306/test2?charset=utf8',echo=True) 

    2. 设置数据库表编码方式为utf8:

      engine = create_engine("mysql+pymysql://root:123456@127.0.0.1:3306/sqldb01?charset=utf8")  

    class UserType(Base):
      __tablename__ = 'usertype' i
      d = Column(Integer, primary_key=True)
      caption = Column(String(50), default='管理员')
       # 添加配置设置编码
      __table_args__ = {
         'mysql_charset':'utf8'
      }

    这样生成的SQL语句就自动设置数据表编码为utf8了,__table_args__还可设置存储引擎、外键约束等等信息。

    21.SQLAlchemy中如何设置联合唯一索引

    通过'UniqueConstraint'字段来设置联合唯一索引

    __table_args=(UniqueConstraint('h_id','username',name='_h_username_uc'))

    #h_id和username组成联合唯一约束

     持续更新....

  • 相关阅读:
    nginx设置开机自启
    sublimeText3和phpstrom使用
    快捷键整理
    nginx日志分割及备份
    nginx日志设置
    nginx上部署PHP
    C语言三种参数传递方式
    浮点数在内存中的存储方式
    windows下git安装过程
    偏移二进制编码和二进制补码的区别
  • 原文地址:https://www.cnblogs.com/Utopia-Clint/p/10824238.html
Copyright © 2011-2022 走看看