面试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)