面试总结1

1 django和flask的区别

  django:大而全,包含了很多组件,eg:ORM、form、ModelForm、session。。。

  flask:轻量级的可扩展强的框架,有丰富的第三方组件

    相同点:

      1 都要依赖wsgi

    不同点

      1 django组件多,flask组件少(默认的)

      2 最大的区别就是对于请求的处理不一样。

        django-一步一步将请求传递给视图

        flask-将请求放置在“某个地方”,以后想要使用就自己去拿即可

 

2 flask上下文处理机制  (处理请求的)  基本原理

  - 服务端如果是单进程单线程,同一时刻服务端只能处理一个请求,客户端来的多,那么就排队等候。

  - 服务端如果是单进程多线程,同一时刻服务端可以处理多个请求,客户端来的多,那么就排队等候

    问题:请求如何不被拿错?

      方法:

        处理请求的身份证号。

        在保存数据的地方,保证服务端的每个线程只能去自己的一块区域中存取值。

 

3 如何实现每个线程都在自己的区域中进行存取数据

  import threading

  import time

  data = threading.local()

  

  def task(arg):

    # prient(arg, threading.get)_ident())  # 线程号

    # 按理说第一个值被第二个值给覆盖掉了,但是是threading.local()对象  读的时候去自己的线程空间去读值 所以不会被覆盖

    data.num = arg   # 设置

    time.sleep(2)

    print(data.num)   # 读取

  for i in range(2):

    t = threadiing.Thread(target=task, args=(i,))

    t.start()

 

4 threading.local()的内部实现原理

  内部维护了一个字典

  data = threading.local()  = {

    "线程ID1": {

      'k1': 123

    },

    "线程ID2":{

      'k1': 123

    }  

  }

  

  from threading import get_ident, Thread

  class Local(object):

    def __init__(self):

      # self._storage={}  # 会出现递归的问题

      object.__setattr__(self, "_storage", {})

    def __setattr__(self, key, value):

      ident = get_ident()  # 获取当前执行此方法的线程ID

      if ident in self._storage:

        self._storage["ident"]["key"] = value

      self._storage["ident"] = {key: value}

    def __getattr__(self, item):

      ident = get_ident()  # 获取当前执行此方法的线程ID

      return self._storage[ident]['item']

  obj = Local()

  # obj.k1 = 123  # __setarttr__

  # obj.k1    # __getattr__

  print(obj._storage)

  def task():

    obj.k1 = 123

  for i in range(2):

    t = Thread(target=task)

    t.start()

  print(obj._storage)

 

比threading.local()更厉害,为每个协程开辟一个空间进行存储

 

  from threading import get_ident, Thread  # 线程ID

  from greenlet import getcurrent as get_ident  # 协程ID

  class Local(object):

    def __init__(self):

      # self._storage={}  # 会出现递归的问题

      object.__setattr__(self, "_storage", {})

    def __setattr__(self, key, value):

      ident = get_ident()  # 获取当前执行此方法的线程ID

      if ident in self._storage:

        self._storage["ident"]["key"] = value

      self._storage["ident"] = {key: value}

    def __getattr__(self, item):

      ident = get_ident()  # 获取当前执行此方法的线程ID

      return self._storage[ident]['item']

  obj = Local()

  # obj.k1 = 123  # __setarttr__

  # obj.k1    # __getattr__

  print(obj._storage)

  def task():

    obj.k1 = 123

  for i in range(2):

    t = Thread(target=task)

    t.start()

  print(obj._storage)

 

注意:greenlet是需要pip install greenlet的,如果有就走这个,没有走线程的!

 

5 threading.local()和锁是什么关系

  无关系

    - 锁,多个线程去同时去操作同一份数据的时,为了保证数据安全才加锁,加锁后让多个线程排队执行

    - threading.local(),让多个线程自己维护自己的数据  

 

6 简述Flask请求上下文的实现流程

  请求上下文的流程

  ctx = RequestContext()对象       放两个对象  一个request,一个session

  stack = LocalStack()对象              背后有Locak()对象-自己维护-升级版的threading.local()

  LocalProxy()对象

 

  请求进来后先交给RequestContext()对象进行数据的加工   封装 request和创建session

  将封装好的数据给LocalStack()对象,

  将值给了local = Local()对象

    {

      1211:{

        stack: [ctx, ]  # LocalStack()对象  

      }

    }

  去cookie中获取session的数据,并赋值给ctx.session 

  到达视图,request.method/session['k1'] = 999!只要这两段代码存在就会去调用LocalProxy()对象。 request = localproxy()   session = LocalProxy()

  请求结束!把stack中ctx删除!把数据删掉,把session获取到将它加密变为字符串,存到浏览器的cookie中。

 

  应用上下文

  app_ctx = AppContext()   app = app  g = {}

  stack = LocalStack() 

  local = Local()

  

  视图中加current_app.config  / g.x = 123123  ! current_app = LocalProxy()  g = LocalProxy()

  请求结束!把stack中ctx删除!只处理session不处理其他!

 

7 flask中session处理机制

  请求上下文中,请求结束,处理session

 

8 flask中g 的作用

  在一个请求声明中存活的一个变量

 

 

 

 

 

 

 

 

  

 

posted @ 2019-01-18 20:14  小学弟-  阅读(96)  评论(0编辑  收藏  举报