返回顶部

面试8

1. Http协议?
Http协议就是一个传输数据格式。

我原来学习django框架,从socket服务端开始学起。
自己创造了一个socket服务器来充当:网站。
浏览器当socket客户端。
更清楚的明白到底http协议是什么?
- 请求头 请求头
- 响应头 响应头

一次请求响应后,断开连接。
2. 常见请求头

3. 常见的请求体?
Form表单提交:
POST /index http1.1\r\nhost:www.luffycity.com...\r\n\r\nusername=alex&password=123&...
Ajax请求:
POST /index http1.1\r\nhost:www.luffycity.com...\r\n\r\nusername=alex&password=123&...
POST /index http1.1\r\nhost:www.luffycity.com...\r\n\r\n{“username”:"alex","password":123}

补充:django中获取请求体
- request.POST
- request.body

4. django请求生命周期
- wsgi, 他就是socket服务端,用于接收用户请求并将请求进行初次封装,然后将请求交给web框架(Flask、Django)
- 中间件,帮助我们对请求进行校验或在请求对象中添加其他相关数据,例如:csrf、request.session
- 路由匹配
- 视图函数,在视图函数中进行业务逻辑的处理,可能涉及到:orm、templates => 渲染
- 中间件,对响应的数据进行处理。
- wsgi,将响应的内容发送给浏览器。

5. 中间件
- 5个方法
- 应用场景:
- 登录认证,不再需要在每个函数中添加装饰器
- 权限,当用户登录时候获取当前用户所有权限并放入session,然后再次访问其他页面,获取当前url并在session中进行匹配。如果没有匹配成功,则在中间件返回“无权访问”
- 跨域,
- jsonp,动态创建一个script标签。
- cors,设置响应头
应用:本地开始前后端分离的时使用。

6. ORM操作
- only
- defer
- seleted_related
- prefetch_related

示例:
class Depart(models.Model): 5个部门
title = models.CharField(...)

class User(models.Model): 10个用户
name = models.CharField(...)
email = models.CharField(...)
dp = models.FK(Depart)

1.以前的你:11次单表查询

result = User.objects.all()
for item in result:
print(item.name,item.dp.title)

2. seleted_related,主动做连表查询(1次链表)

result = User.objects.all().seleted_related('dp')
for item in result:
print(item.name,item.dp.title)

问题:如果链表多,性能越来越差。

3. prefetch_related:2次单表查询
# select * from user ;
# 通过python代码获取:dp_id = [1,2]
# select * from depart where id in dp_id
result = User.objects.all().prefetch_related('dp')
for item in result:
print(item.name,item.dp.title)


赠送:
数据量比较大,不会使用FK,允许出现数据冗余。

7. django rest framework的作用?
快速搭建基于restful规范的接口。

8. 你理解的 restful 规范?
restful是一个规范,规定API如何编写,通过他可以让我们api更加简洁可维护。
如,最直观的:
method:
- get
- post
- put
- delete

原来都是url中设置的。
除此之外:
- api
- 版本
- 名词
- 条件
- 状态码
- 返回值
- 错误信息
- hypermedia link

9. django rest framework组件:

- 访问频率控制原理:
匿名:
1.1.1.1:[时间,时间,时间,时间,]
登录:
user:[时间,时间,时间,时间,]

默认将访问记录放在缓存中:redis/memcached
- 序列化
from rest_framework.serializers import Serializer

class XX(Serializer):
pass
ser =XX(queryset,many=True) # ListSerializer对象
ser =XX(obj, many=False) # XX对象

- 列表生成式

- 根据字符串的形式,自动导入模块并使用反射找到模块中的类【参考:s9day108】。


1. OSI 7层模型  *****

2. 三次握手、四次挥手? ******

3. TCP和UDP区别?************

4. 路由器和交换机的区别?**********

5. ARP协议?

6. DNS解析?

7. Http和Https?

8. 进程、线程、协程区别?************

9. GIL锁 *********

10. 进程如何进程共享? **************

2. twisted是什么以及和requests的区别?
requests是一个Python实现的可以伪造浏览器发送Http请求的模块。
- 封装socket发送请求

twisted是基于事件循环的异步非阻塞网络框架。
- 封装socket发送请求
- 单线程完成并发请求
PS: 三个相关词
- 非阻塞:不等待
- 异步:回调
- 事件循环:一直循环去检查状态。

2. Scrapy框架
- 组件以及执行流程?
- 引擎找到要执行的爬虫,并执行爬虫的 start_requests 方法,并的到一个 迭代器。
- 迭代器循环时会获取Request对象,而request对象中封装了要访问的URL和回调函数。
- 将所有的request对象(任务)放到调度器中,用于以后被下载器下载。

- 下载器去调度器中获取要下载任务(就是Request对象),下载完成后执行回调函数。

- 回到spider的回调函数中,
yield Request()
yield Item()
redis 实现队列  先进先出
import scrapy_redis
import redis
# 先进先出队列
class FifoQueue(object):
    def __init__(self):
        self.server = redis.Redis(host='140.143.227.206',port=8888,password='beta')

    def push(self, request):
        """Push a request"""
        self.server.lpush('USERS', request)

    def pop(self, timeout=0):
        """Pop a request"""
        data = self.server.rpop('USERS')
        return data
# [33,22,11]
q = FifoQueue()
q.push(11)
q.push(22)
q.push(33)

print(q.pop())
print(q.pop())
print(q.pop())

redis 栈 后进先出 


import redis
#  后进先出 栈
class LifoQueue(object):
    """Per-spider LIFO queue."""
    def __init__(self):
        self.server = redis.Redis(host='140.143.227.206',port=8888,password='beta')

    def push(self, request):
        """Push a request"""
        self.server.lpush("USERS", request)

    def pop(self, timeout=0):
        """Pop a request"""
        data = self.server.lpop('USERS')
        return

# [33,22,11]

  

redis实现优先队列  


import redis
# 根据优先级队列 从小到大一个个去取
conn = redis.Redis(host='140.143.227.206',port=8888,password='beta')
# conn.zadd('score',alex=79, oldboy=33,eric=73)
#
# print(conn.keys())

v = conn.zrange('score',0,8,desc=True)
print(v)

pipe = conn.pipeline()
pipe.multi()
# zremrangebyrank 根据排序去取值
pipe.zrange("score", 0, 0).zremrangebyrank('score', 0, 0)
results, count = pipe.execute()
print(results,count)  

爬取10组图片
"""
协程+IO切换
pip3 install gevent
gevent内部调用greenlet(实现了协程)。
"""
from gevent import monkey; monkey.patch_all()
import gevent
import requests


def func(url):
    response = requests.get(url)
    print(response)

urls = [
    'http://www.baidu.com/',
    'https://www.cnblogs.com/',
    'https://www.cnblogs.com/news/',
    'https://cn.bing.com/',
    'https://stackoverflow.com/',
]
spawn_list = []
for url in urls:
    spawn_list.append(gevent.spawn(func, url))

gevent.joinall(spawn_list)
方式一
"""
基于事件循环的异步非阻塞模块:Twisted
"""
from twisted.web.client import getPage, defer
from twisted.internet import reactor

def stop_loop(arg):
    reactor.stop()


def get_response(contents):
    print(contents)

deferred_list = []

url_list = [
    'http://www.baidu.com/',
    'https://www.cnblogs.com/',
    'https://www.cnblogs.com/news/',
    'https://cn.bing.com/',
    'https://stackoverflow.com/',
]

for url in url_list:
    deferred = getPage(bytes(url, encoding='utf8'))
    deferred.addCallback(get_response)
    deferred_list.append(deferred)


dlist = defer.DeferredList(deferred_list)
dlist.addBoth(stop_loop)

reactor.run()
方式二

 

单例模式
class Singleton(object):
    __instance = None

    def __new__(cls, age, name):
        #如果类数字能够__instance没有或者没有赋值
        #那么就创建一个对象,并且赋值为这个对象的引用,保证下次调用这个方法时
        #能够知道之前已经创建过对象了,这样就保证了只有1个对象
        if not cls.__instance:
            cls.__instance = object.__new__(cls)
        return cls.__instance

  

装饰器
map 函数

# 补充的代码量请控制在 30 ⾏以内,并注明代码的时间和空间复杂度

expect = {
    "交易所": {
        "中国外汇交易中⼼": {},
        "聚合交易所": {},
        "森浦Quebee": {}
    },
    "交易模式": {
        "报价驱动模式": {
            "可执⾏持续报价(ESP)": {}
        }
    }
}


def convert_format(input_list, parent):
    tree = {}
    for item in input_list:
        if item.get("parent", "") == parent:
            tree[item["name"]] = convert_format(input_list, item["name"])
    return tree


# 空间复杂为递归的深度 n3
if __name__ == '__main__':
    input_list = [
        {
            "parent": "交易所",
            "name": "中国外汇交易中⼼"
        },
        {
            "name": "交易所"
        },
        {
            "parent": "交易所",
            "name": "聚合交易所"
        },
        {
            "parent": "交易所",
            "name": "森浦Quebee"
        },
        {
            "name": "交易模式"
        },
        {
            "parent": "交易模式",
            "name": "报价驱动模式"
        },
        {
            "parent": "报价驱动模式",
            "name": "可执⾏持续报价(ESP)"
        }
    ]
    output = convert_format(input_list, "")
    print(output)
    expect = {
        "交易所": {
            "中国外汇交易中⼼": {},
            "聚合交易所": {},
            "森浦Quebee": {}
        },
        "交易模式": {
            "报价驱动模式": {
                "可执⾏持续报价(ESP)": {}
            }
        }
    }
    assert (output == expect)

  





posted @ 2018-10-03 15:22  Crazymagic  阅读(166)  评论(0编辑  收藏  举报