你想要的Python面试题都在这里了!

第四部分 前端、框架和其他(155题)

1. 谈谈你对http协议的认识。

HTTP(Hyper Text Transfer Protocol),即超文本传输协议,是用于万维网服务器与本地浏览器之间传输超文本的协议。

坦白的讲,HTTP协议就是服务器(Server)和客户端(Client)之间进行数据交互的一种形式。

HTTP协议工作与客户端-服务端架构之上,浏览器作为HTTP客户端通过URLHTTP服务端发送所有请求,WEB服务器根据接收到的请求后,向客户端发送相应信息。

在这里插入图片描述

2. 谈谈你对websocket协议的认识。

WebSocket和HTTP都是基于TCP协议的两个不同的协议,其中WebSocket依赖于HTTP连接。

WebSocket是双向通信协议,模拟Socket协议,可以双向发送或接受信息,而HTTP是单向的。
在这里插入图片描述
每个WebSocket连接都始于一个HTTP请求。 具体来说,WebSocket协议在第一次握手连接时,通过HTTP协议在传送WebSocket支持的版本号,协议的字版本号,原始地址,主机地址等等一些列字段给服务器端,但是建立之后,在真正传输时候是不需要HTTP协议的。

3. 什么是magic string ?

无论是python还是其它的编程语言,都有magic string这类东西存在。它并不是phtyon专有的东西,类似的还有magic number这样的。

前两年有关linux一个版本的更新就有个关于magic number的小插曲:

linux一个版本更新出来后,对某个类型的显卡的驱动支持出现了问题。
然后相关代码被修复,其中在代码中就直接对一个地址加了一个偏移量,类似python中addr_offset += 123这样的操作。
这里,这个123就是一个magic number:它为什么是123?为什么不可以是124或者别的什么值?
没有说明,没有理由,它就这么神奇的出现,然后问题就神奇的被解决了。为此,linux项目负责人员很恼火,在项目中都说了脏话。

无论是magic string还是magic number,统称为magic value,即,魔法值。

它们在代码中突然出现,直接使用,没有说明,无从追溯。

这对代码的可读性,可维护性都带来了负面效应。

而在客户端向服务端发送消息时,会有一个’sec-websocket-key’和’magic string’的随机字符串, 服务端接收到消息后会把他们连接成一个新的key串,进行编码、加密,确保信息的安全性。

4. 如何创建响应式布局?
  1. 设置meta标签,禁止用户缩放
  2. 通过媒介查询来设置样式Media Queries
    Media Queries 是响应式设计的核心,它根据条件告诉浏览器如何为指定视图宽度渲染页面。
  3. 设置字体,rem是相对于根元素的,之前先重置根元素的大小
5. 你曾经使用过哪些前端框架?
  1. Bootstrap
    Boostrap是一套优美,直观并且给力的web设计工具包,可以用来开发跨浏览器兼容并且美观大气的页面。它提供了很多流行的样式简洁的UI组件,栅格系统以及一些常用的JavaScript插件。

  2. Vue
    Vue是相对比较轻量级的框架,是通过进行双向数据绑定来达到驱动页面的效果。Vue比较简单,官方文档介绍的很清楚,可以非常快速的通过异步批处理的方式对DOM进行更新,也能把可复用的、解耦的组件组合在一起使用,更能允许多种模块的安装,场景使用也更加灵活。

6. 什么是ajax请求?并使用jQuery和XMLHttpRequest对象实现一个ajax请求。
  • jQuery
$.ajax({
     url:"/handle_Ajax/",
     type:"POST",
     data:{username:"Alex",password:123},
     success:function(data){
         console.log(data)
     },
     error: function (jqXHR, textStatus, err) {
         console.log(arguments);
     },
     complete: function (jqXHR, textStatus) {
         console.log(textStatus);
     },
     statusCode: {
        '403': function (jqXHR, textStatus, err) {
               console.log(arguments);
          },
         '400': function (jqXHR, textStatus, err) {
             console.log(arguments);
         }
      }
 })
  • XMLHttpRequest
function chat() {
	// 1.获取节点值
    var text = document.getElementById("text").value;
	// 2.创建一个XMLHttpRequest()对象
    var xmlhttp = createXMLHttpRequest();

	// 3.调用XMLHttpRequest对象的open方法和send方法发送数据
    xmlhttp.open("POST","/webpage/Control/",true);
    xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
    xmlhttp.send("text="+text);

	// 4.XMLHttpRequest对象添加onreadystatechange 响应函数
    xmlhttp.onreadystatechange = function () {
    	// 5.判断响应是否完成:XMLHttpRequest 对象的readystate的属性值为4,status 属性值为200
        if(xmlhttp.readyState === 4 && xmlhttp.status === 200){
            var temp = xmlhttp.responseText;
            console.log(temp);
            alert(temp);

            document.getElementById("mine_msg").innerHTML=text;
            document.getElementById("robot_msg").innerHTML=temp;
        }
    }
}

function createXMLHttpRequest() {
    var xmlHttp;
    try{
        xmlHttp = new XMLHttpRequest(); // 适用于大多数浏览器,以及IE7和IE更高版本
    } catch (e) {
        try {
            xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");  // 适用于IE6
        } catch (e) {
            try{
                xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");   // 适用于IE5.5,以及IE更早版本
            } catch (e){}
        }
    }
    return xmlHttp;
}
7. 如何在前端实现轮训?

轮询就是通过定时器让程序每隔n秒执行一次操作,可以通过setInterval()实现。

8. 如何在前端实现长轮训?

长轮训采用阻塞模型轮询的方式,也就是说,客户端发起连接后,如果没消息,就一直不返回Response给客户端,直到有消息才返回或超时。

返回完之后,客户端再次建立连接,周而复始,基于事件的触发,一个事件接一个事件。

9. vuex的作用?

Vuex官网上这样描述:vuex是一个专为vue.js应用程序开发的状态管理模式。

vuex解决了组件之间同一状态的共享问题,当我们的应用遇到多个组件之间的共享问题时会需要多个组件依赖于同一状态。传参的方法对于多层嵌套的组件将会变得很繁琐,并且对于兄弟组件间的传递无能为力。

他采用集中式存储管理应用的所有组件的状态,这里的关键在于集中式存储管理。这意味着本来需要共享状态的更新是需要组件之间的通讯,而现在有了vuex,组件就都和store通讯了。

Vuex是一个状态管理的插件,可以解决不同组件之间的数据共享和数据持久化。

10. vue中的路由的拦截器的作用?

拦截器可以在请求发送前和发送请求后做一些处理。

vue路由拦截,针对要先登录才能进入的页面,判断是否有Token值,如果有则next(),否则跳转到登录页面。

在这里插入图片描述

11. axios的作用?

axios主要是用于向后台发起请求的,还有在请求中做更多是可控功能。

12. 列举vue的常见指令。
  1. 文本插值:{{ }} Mustache
  2. DOM属性绑定: v-bind
  3. 指令绑定一个事件监听器:v-on
  4. 实现表单输入和应用状态之间的双向绑定:v-model
  5. 控制切换一个元素的显示:v-if 和 v-else
  6. 列表渲染:v-for
  7. 根据条件展示元素:v-show
13. 简述jsonp及实现原理?

JSONP 是json用来跨域的一个东西。原理是通过script标签的跨域特性来绕过同源策略。

JsonP解决跨域只能发送get请求,并且实现起来需要前后端交互比较多。

JSONP的简单实现:创建一个回调函数,然后在远程服务上调用这个函数并且将JSON数据作为参数传递,完成回调。

14. 是什么cors ?

CORS 全称是跨域资源共享(Cross-Origin Resource Sharing),是一种 AJAX 跨域请求资源的方式,支持现代浏览器,IE支持10以上。

CORS与JSONP的使用目的相同,但是比JSONP更强大。JSONP只支持GET请求,CORS支持所有类型的HTTP请求。JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。

浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)

只要同时满足以下两大条件,就属于简单请求

  1. 请求方法是以下三种方法之一:
HEAD
GET
POST
  1. HTTP的头信息不超出以下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

不同时满足上面两个条件,就属于非简单请求。

15. 列举Http请求中常见的请求方式?
方法名称定义
GET向特定的路径资源发出请求
POST向指定路径资源提交数据进行处理请求(一般用于提交表单或者上传文件)
PUT从客户端向服务器传送数据更新指定的资源
PATCH从客户端向服务器传送数据更新部分指定的资源
DELETE请求服务器删除指定的资源
HEAD向服务器索要与GET一样的请求,但是不返回返回体。
这个方法可以在不必传输整个响应内容的情况下,获取包含在响应消息头中的元信息
OPTIONS查询相应URL支持的HTTP方法
TRACE返回服务器收到的请求,主要用于测试或诊断
CONNECTHTTP/1.1协议中预留给能够将连接改为管道方式的代理服务
16. 列举Http请求中的状态码?

1XX:指示信息–表示请求已接收,继续处理。

2XX Success(成功状态码):成功–表示请求已被成功接收、理解、接受。

200 表示从客户端发来的请求在服务器端被正常处理
204 该状态码表示服务器接收的请求已成功处理,但在返回的响应报文中不含实体的主体部分
206 该状态码表示客户端进行了范围请求,而服务器成功执行了这部分的GET请求

3XX Redirection(重定向状态码):重定向–要完成请求必须进行更进一步的操作。

301 永久性重定向
302 临时性重定向

4XX Client Error(客户端错误状态码):客户端错误–请求有语法错误或请求无法实现。

400 该状态码表示请求报文中存在语法错误
401 该状态码表示发送的请求需要有通过HTTP认证的认证信息
403 该状态码表明对请求资源的访问被服务器拒绝了
404 该状态码表明服务器上无法找到请求的资源

5XX Server Error(服务器错误状态码):服务器端错误–服务器未能实现合法的请求。

500 该状态码表明服务器端在执行请求时发生了错误。
503 该状态码表明服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。
17. 列举Http请求中常见的请求头?
字段意思
Accept这个头信息指定浏览器或其他客户端可以处理的 MIME 类型。有text/html,image//等几种常用类型。/*可以简单的概括为告诉服务器,客户端什么数据类型都支持
Accept-Charset这个头信息指定浏览器可以用来显示信息的字符集。例如 ISO-8859-1
Accept-Encoding这个头信息指定浏览器知道如何处理的编码类型。值 gzip 或 compress 是最常见的两种可能值
Accept-Language这个头信息指定客户端的首选语言,在这种情况下,Servlet 会产生多种语言的结果。例如,en、en-us、ru 等。
Authorization这个头信息用于客户端在访问受密码保护的网页时识别自己的身份。
Connection这个头信息指示客户端是否可以处理持久 HTTP 连接。持久连接允许客户端或其他浏览器通过单个请求来检索多个文件。值 Keep-Alive 意味着使用了持续连接。
Content-Length这个头信息只适用于 POST 请求,并给出 POST 数据的大小(以字节为单位)。
Cookie这个头信息把之前发送到浏览器的 cookies 返回到服务器。
Host这个头信息指定原始的 URL 中的主机和端口。
If-Modified-Since这个头信息表示只有当页面在指定的日期后已更改时,客户端想要的页面。如果没有新的结果可以使用,服务器会发送一个 304 代码,表示 Not Modified 头信息。 Last-Modified 与If-Modified-Since都是用来记录页面的最后修改时间。当客户端访问页面时,服务器会将页面最后修改时间通过 Last-Modified 标识由服务器发往客户端,客户端记录修改时间,再次请求本地存在的cache页面时,客户端会通过 If-Modified-Since 头将先前服务器端发过来的最后修改时间戳发送回去,服务器端通过这个时间戳判断客户端的页面是否是最新的,如果不是最新的,则返回新的内容,如果是最新的,则 返回 304 告诉客户端其本地 cache 的页面是最新的,于是客户端就可以直接从本地加载页面了,这样在网络上传输的数据就会大大减少,同时也减轻了服务器的负担
If-Unmodified-Since这个头信息是 If-Modified-Since 的对立面,它指定只有当文档早于指定日期时,操作才会成功。
Referer这个头信息指示所指向的 Web 页的 URL。例如,如果您在网页 1,点击一个链接到网页 2,当浏览器请求网页 2 时,网页 1 的 URL 就会包含在 Referer 头信息中。
User-Agent这个头信息识别发出请求的浏览器或其他客户端,并可以向不同类型的浏览器返回不同的内容。
18. 说结果:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    let name = 'Alex';

    function func() {
        let name = '007';

        function inner() {
            alert(name);
        }
        return inner;
    }

    let ret = func();
    ret();
</script>
</body>
</html>

在这里插入图片描述

19. 说结果:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script type="text/javascript">
    function main() {
        if (1 === 1){
            var name = 'Alex';
        }
        console.log(name);
    }
    main();
</script>
</body>
</html>

console输出内容:

Alex
20. 说结果:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    xo = 'Alex';

    function func() {
        var xo = '007';

        function inner() {
            var xo = 'Bei';
            console.log(xo);
        }

        inner();
    }

    func();
</script>
</body>
</html>

console输出内容:

Bei
25. 什么是wsgi?

是web服务网关接口,是一套协议。
通过以下模块实现了wsgi协议:
- wsgiref
- werkzurg
- uwsgi 关于部署

以上模块本质:编写socket服务端,用于监听请求,当有请求到来,则将请求数据进行封装,然后交给web框架处理。

26. django请求的生命周期?

在这里插入图片描述

  1. uWSGI服务器通过wsgi协议,将HttpRequest交给web框架 (Flask、Django)

  2. 首先到达request中间件,对请求对象进行校验或添加数据,例如:csrf、request.session,如果验证不通过直接跳转到response中间件

  3. 过URL配置文件找到urls.py文件

  4. 根据浏览器发送的URL,通过视图中间件去匹配不同的视图函数或视图类,如果没有找到相对应的视图函数,就直接跳转到response中间件

  5. 在视图函数或视图类中进行业务逻辑处理,处理完返回到response中间件

  6. 模型类通过ORM获取数据库数据,并返回序列化json或渲染好的Template到response中间件

  7. 所有最后离开的响应都会到达response中间件,对响应的数据进行处理,返回HttpResponse给wsgi

  8. wsgi经过uWSGI服务器,将响应的内容发送给浏览器。

27. 列举django的内置组件?

Admin是对model中对应的数据表进行增删改查提供的组件
model组件:负责操作数据库
form组件:1.生成HTML代码2.数据有效性校验3校验信息返回并展示
ModelForm组件即用于数据库操作,也可用于用户请求的验证

28. 列举django中间件的5个方法?以及django中间件的应用场景?

process_request : 请求进来时,权限认证
process_view : 路由匹配之后,能够得到视图函数
process_exception : 异常时执行
process_template_responseprocess : 模板渲染时执行
process_response : 请求有响应时执行

29. 简述什么是FBV和CBV?

FBV(function base views)使用视图函数处理请求

CBV(class base views)使用视图类处理请求

30. django的request对象是在什么时候创建的?
class WSGIHandler(base.BaseHandler):
    request = self.request_class(environ)

请求走到WSGIHandler类的时候,执行cell方法,将environ封装成了request。

31. 如何给CBV的程序添加装饰器?

导入 method_decorator 装饰器

from django.utils.decorators import method_decorator
  1. 给方法加
@method_decorator(check_login)
def post(self, request):
    '''给方法加'''
    ...
  1. 给dispatch加
@method_decorator(check_login)
def dispatch(self, request, *args, **kwargs):
    '''给dispatch加'''
    ...
  1. 给类加
@method_decorator(check_login, name="get")
@method_decorator(check_login, name="post")
class HomeView(View):
    '''给类加'''
    ...
32. 列举django orm 中所有的方法(QuerySet对象的所有方法)

<1> all(): 查询所有结果

<2> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象。获取不到返回None

<3> get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个。如果符合筛选条件的对象超过一个或者没有都会抛出错误。

<4> exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象

<5> order_by(*field): 对查询结果排序

<6> reverse(): 对查询结果反向排序

<8> count(): 返回数据库中匹配查询(QuerySet)的对象数量。

<9> first(): 返回第一条记录

<10> last(): 返回最后一条记录

<11> exists(): 如果QuerySet包含数据,就返回True,否则返回False

<12> values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系 model的实例化对象,而是一个可迭代的字典序列

<13> values_list(*field): 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列

<14> distinct(): 从返回结果中剔除重复纪录

33. only和defer的区别?

defer(‘id’,‘name’):取出对象,字段除了id和name都有

only(‘id’,‘name’):取的对象,只有id和name

34. select_related和prefetch_related的区别?

有外键存在时,可以很好的减少数据库请求的次数,提高性能。

select_related通过多表join关联查询,一次性获得所有数据,只执行一次SQL查询

prefetch_related分别查询每个表,然后根据它们之间的关系进行处理,执行两次查询

35. filter和exclude的区别?

两者取到的值都是QuerySet对象,filter选择满足条件的,exclude:排除满足条件的。

36. 列举django orm中三种能写sql语句的方法。

1.使用execute执行自定义的SQL

  • 直接执行SQL语句(类似于pymysql的用法)
# 更高灵活度的方式执行原生SQL语句
from django.db import connection
cursor = connection.cursor()
cursor.execute("SELECT DATE_FORMAT(create_time, '%Y-%m') FROM blog_article;")
ret = cursor.fetchall()
print(ret)

2.使用extra方法 :queryset.extra(select={“key”: “原生的SQL语句”})

3.使用raw方法

  1. 执行原始sql并返回模型
  2. 依赖model多用于查询
37. django orm 中如何设置读写分离?

方式一:手动使用queryset的using方法

from django.shortcuts import render,HttpResponse
from app01 import models
def index(request):

    models.UserType.objects.using('db1').create(title='普通用户')
  # 手动指定去某个数据库取数据
    result = models.UserType.objects.all().using('db1')
    print(result)

    return HttpResponse('...')

方式二:写配置文件

class Router1:
  # 指定到某个数据库取数据
    def db_for_read(self, model, **hints):
        """
        Attempts to read auth models go to auth_db.
        """
        if model._meta.model_name == 'usertype':
            return 'db1'
        else:
            return 'default'
  # 指定到某个数据库存数据
    def db_for_write(self, model, **hints):
        """
        Attempts to write auth models go to auth_db.
        """
        return 'default'

再写到配置

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    },
    'db1': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}
DATABASE_ROUTERS = ['db_router.Router1',]
38. F和Q的作用?

F:主要用来获取原数据进行计算。

Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取模的操作。

修改操作也可以使用F函数,比如将每件商品的价格都在原价格的基础上增加10

from django.db.models import F
from app01.models import Goods

# 对于goods表中每件商品的价格都在原价格的基础上增加10元
Goods.objects.update(price=F("price")+10)

F查询专门对对象中某列值的操作,不可使用__双下划线!

Q:用来进行复杂查询

Q查询可以组合使用 “&”, “|” 操作符,当一个操作符是用于两个Q的对象,它产生一个新的Q对象,

Q对象可以用 “~” 操作符放在前面表示否定,也可允许否定与不否定形式的组合。

Q对象可以与关键字参数查询一起使用,不过一定要把Q对象放在关键字参数查询的前面。

Q(条件1) | Q(条件2) 或
Q(条件1) & Q(条件2) 且
Q(条件1) & ~Q(条件2) 非

39. values和values_list的区别?

values : queryset类型的列表中是字典

values_list : queryset类型的列表中是元组

40. 如何使用django orm批量创建数据?
def bulk_create(self, objs, batch_size=None):
# 批量插入
# batch_size表示一次插入的个数
objs = [
    models.DDD(name='r11'),
    models.DDD(name='r22')
]
models.DDD.objects.bulk_create(objs, 10)
41. django的Form和ModeForm的作用?
  • 作用:对用户请求数据格式进行校验、自动生成HTML标签
  • 区别:

Form,字段需要自己手写。

class Form(Form):
    xx = fields.CharField(.)
    xx = fields.CharField(.)
    xx = fields.CharField(.)
    xx = fields.CharField(.)

ModelForm,可以通过Meta进行定义

class MForm(ModelForm):
    class Meta:
        fields = "__all__"
        model = UserInfo              
  • 应用:只要是客户端向服务端发送表单数据时,都可以进行使用,如:用户登录注册
42. django的Form组件中,如果字段中包含choices参数,请使用两种方式实现数据源实时更新。

1.重写构造函数

def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self.fields["city"].widget.choices = models.City.objects.all().values_list("id", "name")

2.利用ModelChoiceField字段,参数为queryset对象

authors = form_model.ModelMultipleChoiceField(queryset=models.NNewType.objects.all())//多选
43. django的Model中的ForeignKey字段中的on_delete参数有什么作用?

删除关联表中的数据时,当前表与其关联的field的操作。

django2.0之后,表与表之间关联的时候,必须要写on_delete参数,否则会报异常。

on_delete有CASCADE、PROTECT、SET_NULL、SET_DEFAULT、SET()五个可选择的值

CASCADE:此值设置,是级联删除。
PROTECT:此值设置,是会报完整性错误。
SET_NULL:此值设置,会把外键设置为null,前提是允许为null。
SET_DEFAULT:此值设置,会把设置为外键的默认值。
SET():此值设置,会调用外面的值,可以是一个函数。
一般情况下使用CASCADE就可以了。
44. django中csrf的实现机制?
  1. django第1次响应来自某个客户端的请求时,服务器随机产生1个token值,把这个token保存在session中;同时服务器把这个token放到cookie中交给前端页面;

  2. 该客户端再次发起请求时,把这个token值加入到请求数据或者头信息中,一起传给服务器;

  3. 服务器校验前端请求带过来的token和session里的token是否一致。

45. django如何实现websocket?

django实现websocket使用channels。

channels通过http协议升级到websocket协议,保证实时通讯。

也就是说,我们完全可以用channels实现我们的即时通讯,而不是使用长轮询和计时器方式来保证伪实时通讯。

他使用asgi协议而不是wsgi协议,他通过改造django框架,使django既支持http协议又支持websocket协议。

46. 基于django使用ajax发送post请求时,都可以使用哪种方法携带csrf token?

方式一:给每个ajax都加上上请求头

function Do1(){
    $.ajax({
        url:"/index/",
        data:{id:1},
        type:'POST',
       data:{csrfmiddlewaretoken:'{{ csrf_token }}',name:'alex'}
            success:function(data){
                console.log(data);
            }
        });
    }

方式二:需要先下载jQuery-cookie,才能去cookie中获取token

        function Do1(){
        $.ajax({
            url:"/index/",
            data:{id:1},
            type:'POST',
            headers:{
              'X-CSRFToken':$.cookie('csrftoken')  // 去cookie中获取
            },
            success:function(data){
                console.log(data);
            }
        });
    }
47. django中如何实现orm表中添加数据时创建一条日志记录。

给信号注册函数

使用django的信号机制,可以在添加、删除数据前后设置日志记录

pre_init  		# Django中的model对象执行其构造方法前,自动触发
post_init  		# Django中的model对象执行其构造方法后,自动触发
pre_save  		# Django中的model对象保存前,自动触发
post_save  		# Django中的model对象保存后,自动触发
pre_delete  	# Django中的model对象删除前,自动触发
post_delete  	# Django中的model对象删除后,自动触发
48. django缓存如何设置?

Django中提供了6种缓存方式:

  开发调试(不加缓存)
  内存
  文件
  数据库
  Memcache缓存(python-memcached模块)
  Memcache缓存(pylibmc模块)

安装第三方组件支持redis:
  django-redis组件

设置缓存

全站缓存(中间件)

MIDDLEWARE_CLASSES = (
    ‘django.middleware.cache.UpdateCacheMiddleware’, #第一
    'django.middleware.common.CommonMiddleware',
    ‘django.middleware.cache.FetchFromCacheMiddleware’, #最后
)

视图缓存

from django.views.decorators.cache import cache_page
import time
  
@cache_page(15)          #超时时间为15秒
def index(request):
   t=time.time()      #获取当前时间
   return render(request,"index.html",locals())

模板缓存

{% load cache %}
 <h3 style="color: green">不缓存:-----{{ t }}</h3>
  
{% cache 2 'name' %} # 存的key
 <h3>缓存:-----:{{ t }}</h3>
{% endcache %}
49. django的缓存能使用redis吗?如果可以的话,如何配置?
pip install django-redis  

在setting添加配置文件

CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache", # 缓存类型
        "LOCATION": "127.0.0.1:6379", # ip端口
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",  #
            "CONNECTION_POOL_KWARGS": {"max_connections": 100} # 连接池最大连接数
            # "PASSWORD": "密码",
        }
    }
}

使用

from django.shortcuts import render,HttpResponse
from django_redis import get_redis_connection
  
def index(request):
# 根据名字去连接池中获取连接
conn = get_redis_connection("default")
    conn.hset('n1','k1','v1') # 存数据
    return HttpResponse('...')
50. django路由系统中name的作用?

反向解析路由字符串

路由系统中name的作用:反向解析

url(r'^home', views.home, name='home')

在模板中使用:{ % url ‘home’ %}
在视图中使用:reverse(“home”)

51. django的模板中filter和simple_tag的区别?

filter : 类似管道,只能接受两个参数第一个参数是|前的数据

simple_tag : 类似函数

1、模板继承:{ % extends ‘layouts.html’ %}
2、自定义方法
‘filter’:只能传递两个参数,可以在if、for语句中使用
‘simple_tag’:可以无线传参,不能在if for中使用
‘inclusion_tags’:可以使用模板和后端数据
3、防xss攻击: ‘|safe’、‘mark_safe’

52. django-debug-toolbar的作用?

django-debug-toolbar 是一组可配置的面板,可显示有关当前请求/响应的各种调试信息,并在单击时显示有关面板内容的更多详细信息。

一、查看访问的速度、数据库的行为、cache命中等信息。
二、尤其在Mysql访问等的分析上大有用处(sql查询速度)

53. django中如何实现单元测试?

Django的单元测试使用python的unittest模块,这个模块使用基于类的方法来定义测试。类名为django.test.TestCase,继承于python的unittest.TestCase。

单元测试框架提供:用例编写规范、专业的比较方法(断言assert)以及丰富的测试日志。

  1. 导入测试库:from django.test import TestCase
  2. 测试用例编写:setUp():测试环境构造(初始化)、assertEqual()、test_function_name()

注:所有测试用例均以test_开头。

Django 测试过程中,测试用例是以独立函数存在。一个函数可作为一个单独测试用例,测试结果判断(assertEqual)直接在函数中进行。测试用例执行是在独立的cmd下命令执行,可以分层执行。

58. Django的ContentType组件的作用?

contenttypes 是Django内置的一个应用,可以追踪项目中所有app和model的对应关系,并记录在ContentType表中。

models.py文件的表结构写好后,通过makemigrations和migrate两条命令迁移数据后,在数据库中会自动生成一个django_content_type表。

每当我们创建了新的model并执行数据库迁移后,ContentType表中就会自动新增一条记录。

那么这个表有什么作用呢?这里提供一个场景,网上商城购物时,会有各种各样的优惠券,比如通用优惠券,满减券,或者是仅限特定品类的优惠券。在数据库中,可以通过外键将优惠券和不同品类的商品表关联起来:

from django.db import models


class Electrics(models.Model):
    """
    id    name
     1   小天鹅洗衣机
     2   三星电视
    """
    name = models.CharField(max_length=32)


class Foods(models.Model):
    """
    id   name
    1    面包
    2    烤鸭
    """
    name = models.CharField(max_length=32)


class Clothes(models.Model):    """
    id   name
    1    阿迪达斯
    2    耐克
    """
    name = models.CharField(max_length=32)


class Coupon(models.Model):  # 特殊关系表
""" 
  id    name    electric_id   food_id   cloth_id   more...   # 每增加一张表,关系表的结构就要多加一个字段。
    1   通用优惠券   null       null      null 
    2   冰箱满减券   2         null     null 
    3   面包狂欢节   null        1      null 
""" 
name = models.CharField(max_length=32) 
electric = models.ForeignKey(to='Electrics', null=True) 
food = models.ForeignKey(to='Foods', null=True) 
cloth = models.ForeignKey(to='Clothes', null=True)

如果是通用优惠券,那么所有的ForeignKey为null,如果仅限某些商品,那么对应商品ForeignKey记录该商品的id,不相关的记录为null。

但是这样做是有问题的:实际中商品品类繁多,而且很可能还会持续增加,那么优惠券表中的外键将越来越多,但是每条记录仅使用其中的一个或某几个外键字段。

通过使用contenttypes 应用中提供的特殊字段GenericForeignKey,我们可以很好的解决这个问题。

  1. 在model中定义ForeignKey字段,并关联到ContentType表。通常这个字段命名为“content_type”
  2. 在model中定义PositiveIntegerField字段,用来存储关联表中的主键。通常这个字段命名为“object_id”
  3. 在model中定义GenericForeignKey字段,传入上述两个字段的名字。

为了更方便查询商品的优惠券,我们还可以在商品类中通过GenericRelation字段定义反向关系。

from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation


class Electrics(models.Model):
    name = models.CharField(max_length=32)
    price = models.IntegerField(default=100)
    coupons = GenericRelation(to='Coupon')  # 用于反向查询,不会生成表字段

    def __str__(self):
        return self.name


class Foods(models.Model):
    name = models.CharField(max_length=32)
    price=models.IntegerField(default=100)
    coupons = GenericRelation(to='Coupon')

    def __str__(self):
        return self.name


class Clothes(models.Model):
    name = models.CharField(max_length=32)
    price = models.IntegerField(default=100)
    coupons = GenericRelation(to='Coupon')

    def __str__(self):
        return self.name


class bed(models.Model):
    name = models.CharField(max_length=32)
    price = models.IntegerField(default=100)
    coupons = GenericRelation(to='Coupon')


class Coupon(models.Model):
    """
    Coupon
        id    name                      content_type_id       object_id_id
    美的满减优惠券            9(电器表electrics)  3
    猪蹄买一送一优惠券        10                    2
    南极被子买200减50优惠券   11                    1
    """
    name = models.CharField(max_length=32)
	
	# step 1
    content_type = models.ForeignKey(to=ContentType) 
    # step 2
    object_id = models.PositiveIntegerField() 
    # step 3
    content_object = GenericForeignKey('content_type', 'object_id') 

    def __str__(self):
        return self.name

注意:ContentType只运用于1对多的关系!!!并且多的那张表中有多个ForeignKey字段。

总结: 当一张表和多个表FK关联,并且多个FK中只能选择其中一个或其中n个时,可以利用contenttypes app,只需定义三个字段就搞定!

59. 谈谈你对restfull 规范的认识?
  1. 面向资源编程
    每个URL代表一种资源,URL中尽量不要用动词,要用名词。
  2. 根据method不同,进行不同的操作
    GET/POST/PUT/DELETE/PATCH
  3. 在URL中体现版本
    https://www.bootcss.com/v1/mycss
  4. 在URL中体现是否是API
    https://www.bootcss.com/api/mycss
  5. 在URL中的过滤条件
    https://www.bootcss.com/v1/mycss?page=3
  6. 尽量使用HTTPS
    https://www.bootcss.com/v1/mycss
  7. 响应时设置状态码
      1* 信息,服务器收到请求,需要请求者继续执行操作
      2* 成功,操作被成功接收并处理
      3* 重定向,需要进一步的操作以完成请求
      4* 客户端错误,请求包含语法错误或无法完成请求
      5* 服务器错误,服务器在处理请求的过程中发生了错误
  8. 返回值
      GET请求 返回查到所有或单条数据
      POST请求 返回新增的数据
      PUT请求 返回更新数据
      PATCH请求 局部更新 返回更新整条数据
      DELETE请求 返回值为空
  9. 返回错误信息
    返回值携带错误信息
  10. Hypermedia API
    如果遇到需要跳转的情况 携带调转接口的URL
60. 接口的幂等性是什么意思?

等幂是数学和计算机科学中某些运算的性质,在这种运算中,它们可以多次应用,而不会改变初始应用以外的结果。等幂的概念出现在抽象代数(特别是投影算子和闭包算子理论)和函数编程(其中它与引用透明性的性质有关)中的许多地方。

一句话讲:在数学和计算机服务中,对于某种操作执行多次,结果相同。

在计算机中,由于网络抖动,临时故障,服务调用失败避免不了,尤其是分布式系统中,接口调用失败更为常见,接口的幂等设计尤其更为重要。

一个接口通过1次相同的访问,再对该接口进行N次相同的访问时,对资源不造影响就认为接口具有幂等性。

GET,  #第一次获取结果、第二次也是获取结果对资源都不会造成影响,幂等。
POST, #第一次新增数据,第二次也会再次新增,非幂等。
PUT,  #第一次更新数据,第二次不会再次更新,幂等。
PATCH,#第一次更新数据,第二次不会再次更新,非幂等。
DELTE,#第一次删除数据,第二次不在再删除,幂等。
61. 什么是RPC?

RPC(Remote Procedure Call,即远程过程调用)是建立在Socket之上的,在一台机器上运行的主程序,可以调用另一台机器上准备好的子程序,就像LPC(本地过程调用)。

也就是说两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数/方法,由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达调用的数据。

对于RPC架构来说,应用越底层,代码越复杂、灵活性越高、效率越高;应用越上层,抽象封装的越好、代码越简单、效率越差。

在网络通信中,不管是TCP 还是UDP,我们都要在传输层上设计自己的应用层协议,使得前后端的数据可以相互通信传输一个可以识别的内容。

后来,人们期望能够更方便一点地让前后端进行交互,于是提出了RPC,就像调用函数一样来让前后端来进行通信,屏蔽掉复杂的应用层协议。

62. Http和Https的区别?

HTTP(Hyper Text Transfer Protocol),即超文本传输协议,是用于万维网服务器与本地浏览器之间传输超文本的协议。

坦白的讲,HTTP协议就是服务器(Server)和客户端(Client)之间进行数据交互的一种形式。

HTTPS (Secure Hypertext Transfer Protocol)安全超文本传输协议,HTTPS是在HTTP上建立SSL加密层,并对传输数据进行加密,是HTTP协议的安全版。

63. 为什么要使用django rest framework框架?

现在新一代web应用都开始采用前后端分离的方式来进行,淘汰了以前的服务器端渲染的方式。前后端分离方式有许多好处,比如

1、可以前后端并行开发,提高开发效率
2、页面都在客户端进行渲染,提高了渲染速度,减小了服务器的压力
3、一套api提供给多个客户端使用,而且不限制客户端的类型(web,app均可)

提到前后端分离必然会提到restful,目前这是最流行的接口规范。

Django REST framework是基于Django实现的一个RESTful风格API框架,能够快速开发RESTful风格的API,帮我们减少了很多工作量,尤其在序列化与反序列化成我们需要的格式帮了我们省了很多事。

64. django rest framework框架中都有那些组件?
  1. 序列化组件:serializers 对queryset序列化以及对请求数据格式校验
  2. 路由组件routers 进行路由分发
  3. 视图组件ModelViewSet 帮助开发者提供了一些类,并在类中提供了多个方法
  4. 认证组件 写一个类并注册到认证类(authentication_classes),在类的的authticate方法中编写认证逻辑
  5. 权限组件 写一个类并注册到权限类(permission_classes),在类的的has_permission方法中编写认证逻辑。
  6. 频率限制 写一个类并注册到频率类(throttle_classes),在类的的allow_request/wait 方法中编写认证逻辑
  7. 解析器 选择对数据解析的类,在解析器类中注册(parser_classes)
  8. 渲染器 定义数据如何渲染到到页面上,在渲染器类中注册(renderer_classes)
  9. 分页 对获取到的数据进行分页处理, pagination_class
  10. 版本 版本控制用来在不同的客户端使用不同的行为
65. django rest framework框架中的视图都可以继承哪些类?
  1. APIView
  2. GenericAPIView
66. 简述 django rest framework框架的认证流程。
  • 如何编写?写类并实现authenticators
      请求进来认证需要编写一个类,类里面有一个authenticators方法,我们可以自定义这个方法,可以定制3类返回值。
      成功返回元组,返回none为匿名用户,抛出异常为认证失败。

源码流程:请求进来先走dispatch方法,然后封装的request对象会执行user方法,由user触发authenticators认证流程

  • 方法中可以定义三种返回值:
    • (user,auth),认证成功
    • None , 匿名用户
    • 异常 ,认证失败
  • 流程:
    • dispatch
    • 再去request中进行认证处理
67. django rest framework如何实现的用户访问频率控制?

对匿名用户,根据用户IP或代理IP作为标识进行记录,为每个用户在redis中建一个列表。

对注册用户,根据用户名或邮箱进行判断。

每个用户再来访问时,需先去记录中剔除过期记录,再根据列表的长度判断是否可以继续访问。

96. git常见命令作用:
git add 		# 将工作区的修改提交到暂存区
git commit 		# 将暂存区的修改提交到当前分支
git reset		# 回退到某一个版本
git stash 		# 保存某次修改
git pull 		# 从远程更新代码
git push 		# 将本地代码更新到远程分支上
git reflog 		# 查看历史命令
git status 		# 查看当前仓库的状态
git diff 		# 查看修改
git log 		# 查看提交历史
git revert 		# 回退某个修改
97. 简述以下git中stash命令作用以及相关其他命令。

‘git stash’:将当前工作区所有修改过的内容存储到“某个地方”,将工作区还原到当前版本未修改过的状态
‘git stash list’:查看“某个地方”存储的所有记录
‘git stash clear’:清空“某个地方”
‘git stash pop’:将第一个记录从“某个地方”重新拿到工作区(可能有冲突)
‘git stash apply’:编号, 将指定编号记录从“某个地方”重新拿到工作区(可能有冲突)
‘git stash drop’:编号,删除指定编号的记录

98. git 中 merge 和 rebase命令 的区别。

merge:
会将不同分支的提交合并成一个新的节点,之前的提交分开显示,注重历史信息、可以看出每个分支信息,基于时间点,遇到冲突,手动解决,再次提交

rebase:
将两个分支的提交结果融合成线性,不会产生新的节点;
注重开发过程,遇到冲突,手动解决,继续操作

99. 公司如何基于git做的协同开发?

每个人都有自己的分支,阶段性代码完成之后,合并到review,然后交给老大看。

大致工作流程

公司:
    下载代码
        git clone https://gitee.com/wupeiqi/xianglong.git
        或创建目录 
        cd 目录 
        git init 
        git remote add origin https://gitee.com/wupeiqi/xianglong.git
        git pull origin maste 
    创建dev分支
        git checkout dev 
        git pull origin dev 
        继续写代码
        git add . 
        git commit -m '提交记录'
        git push origin dev 
回家: 
    拉代码:
        git pull origin dev 
    继续写:
        继续写代码
        git add . 
        git commit -m '提交记录'
        git push origin dev 
100. 如何基于git实现代码review?

1、根据开发任务,建立git分支, 分支名称模式为feature/任务名,比如关于API相关的一项任务,建立分支feature/api:git checkout -b feature/api

2、运行git branch 确认切换到了feature/api分支

3、编辑代码完成开发任务, commit相关代码

git add -A
git commit -m "implement api architecture"

4、将分支代码push到服务器

git push origin -u feature/api

5、登录到源代码库,点击Pull request按钮去创建一个pull request

6、再pull request详细页面, 填写相关标题/说明/reviewer, 目前请将reviewer设成lijing_dkhs和zhuangqunxiong

7、请提醒reviewer去审核pull request,系统也会发邮件提醒reviewer

8、Reviewer打开pull request页面,查看代码修改情况,也可以在相应的代码处添加注释,提示代码作者哪里应该修正。

9、代码作者根据reviewer的要求,调整代码后commit/push到服务器。 然后reviewer继续设置, 如此循环,直到没有问题。

10、当代码没有问题以后, 需要将任务代码merge到主代码库, 有两种方法:

  1. Reviewer可以在pull request页面点击Merge按钮, 把代码merge到主代码库
  2. 代码作者自己merge到主代码库, 并push到服务器。
git pull origin
git log ..master

11、代码作者删除feature子分支。

git checkout master
git branch -D feature/api
git push origin :feature/api

git pull origin master #从主分支pull到子分支
101. git如何实现v1.0 、v2.0 等版本的管理?

在命令行中,使用“git tag –a tagname –m “comment”可以快速创建一个标签。

需要注意,命令行创建的标签只存在本地Git库中,还需要使用git push –tags指令发布到服务器的Git库中

102. 什么是gitlab?

gitlab是公司自己搭建的项目代码托管平台

103. github和gitlab的区别?

1、gitHub是一个面向开源及私有软件项目的托管平台
(创建私有的话,需要购买)

2、gitlab是公司自己搭建的项目托管平台

104. 如何为github上牛逼的开源项目贡献代码?

1、fork需要协作项目
2、克隆/关联fork的项目到本地
3、新建分支(branch)并检出(checkout)新分支
4、在新分支上完成代码开发
5、开发完成后将你的代码合并到master分支
6、添加原作者的仓库地址作为一个新的仓库地址
7、合并原作者的master分支到你自己的master分支,用于和作者仓库代码同步
8、push你的本地仓库到GitHub
9、在Github上提交 pull requests
10、等待管理员(你需要贡献的开源项目管理员)处理

105. git中 .gitignore文件的作用

一般来说每个Git项目中都需要一个“.gitignore”文件,
这个文件的作用就是告诉Git哪些文件不需要添加到版本管理中。

实际项目中,很多文件都是不需要版本管理的,比如Python的.pyc文件和一些包含密码的配置文件等等。

106. 什么是敏捷开发?

‘敏捷开发’:是一种以人为核心、迭代、循序渐进的开发方式。

它并不是一门技术,而是一种开发方式,也就是一种软件开发的流程。
它会指导我们用规定的环节去一步一步完成项目的开发。

因为它采用的是迭代式开发,所以这种开发方式的主要驱动核心是人。

107. 简述 jenkins 工具的作用?

'Jenkins’是一个可扩展的持续集成引擎。

主要用于:
持续、自动地构建/测试软件项目。
监控一些定时执行的任务。

108. 公司如何实现代码发布?

nginx+uwsgi+django

109. 简述 RabbitMQ、Kafka、ZeroMQ的区别?

1.从社区活跃度
按照目前网络上的资料,RabbitMQ、activeM、ZeroMQ三者中,综合来看,RabbitMQ是首选。

2.持久化消息比较
ZeroMq不支持,ActiveMq和RabbitMq都支持。持久化消息主要是指我们机器在不可抗力因素等情况下挂掉了,消息不会丢失的机制。

3.综合技术实现
可靠性、灵活的路由、集群、事务、高可用的队列、消息排序、问题追踪、可视化管理工具、插件系统等等。

RabbitMq / Kafka最好,ActiveMq次之,ZeroMq最差。当然ZeroMq也可以做到,不过自己必须手动写代码实现,代码量不小。尤其是可靠性中的:持久性、投递确认、发布者证实和高可用性。

4.高并发
毋庸置疑,RabbitMQ最高,原因是它的实现语言是天生具备高并发高可用的erlang语言。

5.比较关注的比较
RabbitMq比Kafka成熟,在可用性上,稳定性上,可靠性上, RabbitMq胜于 Kafka] (理论上)。

另外,Kafka的定位主要在日志等方面, 因为Kafka设计的初衷就是处理日志的,可以看做是一个日志(消息)系统一个重要组件,针对性很强,所以 如果业务方面还是建议选择 RabbitMq。

还有就是,Kafka的性能(吞吐量、TPS)比RabbitMq要高出来很多。

110. RabbitMQ如何在消费者获取任务后未处理完前就挂掉时,保证数据不丢失?

为了预防消息丢失,rabbitmq提供了ack,即工作进程在收到消息并处理后,发送ack给rabbitmq,告知rabbitmq这时候可以把该消息从队列中删除了。

如果工作进程挂掉 了,rabbitmq没有收到ack,那么会把该消息重新分发给其他工作进程。不需要设置timeout,即使该任务需要很长时间也可以处理。

ack默认是开启的,工作进程显示指定了no_ack=True

111. RabbitMQ如何对消息做持久化?

1、创建队列和发送消息时将设置durable=Ture,如果在接收到消息还没有存储时,消息也有可能丢失,就必须配置publisher confirm
channel.queue_declare(queue=‘task_queue’, durable=True)

2、返回一个ack,进程收到消息并处理完任务后,发给rabbitmq一个ack表示任务已经完成,可以删除该任务

3、镜像队列:将queue镜像到cluster中其他的节点之上。
在该实现下,如果集群中的一个节点失效了,queue能自动地切换到镜像中的另一个节点以保证服务的可用性

112. RabbitMQ如何控制消息被消费的顺序?

默认消息队列里的数据是按照顺序被消费者拿走,
例如:消费者1 去队列中获取奇数序列的任务,消费者2去队列中获取偶数序列的任务。

channel.basic_qos(prefetch_count=1)
表示谁来谁取,不再按照奇偶数排列(同时也保证了公平的消费分发)

113. 以下RabbitMQ的exchange type分别代表什么意思?如:fanout、direct、topic。

amqp协议中的核心思想就是生产者和消费者隔离,生产者从不直接将消息发送给队列。

生产者通常不知道是否一个消息会被发送到队列中,只是将消息发送到一个交换机。

先由Exchange来接收,然后Exchange按照特定的策略转发到Queue进行存储。

同理,消费者也是如此。Exchange 就类似于一个交换机,转发各个消息分发到相应的队列中。


type=fanout 类似发布者订阅者模式,会为每一个订阅者创建一个队列,而发布者发布消息时,会将消息放置在所有相关队列中

type=direct 队列绑定关键字,发送者将数据根据关键字发送到消息

exchange,exchange根据 关键字 判定应该将数据发送至指定队列。

type=topic 队列绑定几个模糊的关键字,之后发送者将数据发送到exchange,exchange将传入”路由值“和 ”关键字“进行匹配,匹配成功,
则将数据发送到指定队列。


发送者路由值 队列中
old.boy.python old.* – 不匹配 *表示匹配一个
old.boy.python old.# – 匹配 #表示匹配0个或多个

114. 简述 celery 是什么以及应用场景?

Celery是专注实时处理和任务调度的分布式异步任务队列,是一种跨进程,跨机器的工作机制,可以让任务的执行脱离主程序,甚至不在一台主机上。

Celery包含客户端(比如django) , 任务队列broker(存放任务的地方,rabbitmq或者redis,能够解耦合) , 任务处理者worker(真正执行任务的一方)。

115. 简述celery运行机制。

在这里插入图片描述

116. celery如何实现定时任务?
# celery实现定时任务
# 启用Celery的定时任务需要设置CELERYBEAT_SCHEDULE
CELERYBEAT_SCHEDULE='djcelery.schedulers.DatabaseScheduler'
'创建定时任务'
# 通过配置CELERYBEAT_SCHEDULE:
# 每30秒调用task.add
from datetime import timedelta
CELERYBEAT_SCHEDULE = {
    'add-every-30-seconds': {
        'task': 'tasks.add',
        'schedule': timedelta(seconds=30),
        'args': (16, 16)
    },
}
117. 简述 celery多任务结构目录
pro_cel
    ├── celery_tasks     # celery相关文件夹
    │   ├── celery.py    # celery连接和配置相关文件
    │   └── tasks.py     # 所有任务函数
    ├── check_result.py  # 检查结果
    └── send_task.py     # 触发任务
118. celery中装饰器 @app.task 和 @shared_task的区别?

一般情况使用的是从celeryapp中引入的app作为的装饰器:@app.task
django那种在app中定义的task则需要使用@shared_task

119. 简述 requests模块的作用及基本使用?

作用:
使用requests可以模拟浏览器的请求

常用参数:
url、headers、cookies、data
json、params、proxy

常用返回值:
content
iter_content
text
encoding=“utf-8”
cookie.get_dict()

120. 简述 beautifulsoup模块的作用及基本使用?

BeautifulSoup

用于从HTML或XML文件中提取、过滤想要的数据形式

常用方法
解析:html.parser 或者 lxml(需要下载安装)
find、find_all、text、attrs、get

121. 简述 Selenium 模块的作用及基本使用?

Selenium是一个用于Web应用程序测试的工具,他的测试直接运行在浏览器上,模拟真实用户,按照代码做出点击、输入、打开等操作。

爬虫中使用他是为了解决requests无法解决javascript动态问题。

美的集团(SZ.000333)是一家以家电制造业为主的大型综合性企业集团,于2013年9月18日在深交所上市,旗下拥有小天鹅(SZ000418)、威灵控股(HK00382)两家子上市公司。  1968年,美的创业,1980年,美的正式进入家电业,1981年注册美的品牌。目前,美的集团员工人数10.8万人,旗下拥有美的、小天鹅、威灵、华凌、安得、美芝等十余个品牌。集团在国内建有广东顺德、广州、中山;安徽合肥及芜湖;湖北武汉及荆州;江苏无锡、淮安、苏州及常州;重庆、江西贵溪、河北邯郸等14个生产基地,辐射华南、华东、华中、西南、华北五大区域;在越南、白俄罗斯、埃及、巴西、阿根廷、印度等6个国家建有生产基地。 主要家电产品有家用空调、商用空调、大型中央空调、冰箱、洗衣机、微波炉、风扇、洗碗机、电磁炉、电饭煲、电压力锅、豆浆机、饮水机、热水器、空气能热水机、吸尘器、取暖器、电水壶、烤箱、抽油烟机、净水设备、空气清新机、加湿器、灶具、消毒柜、照明等和空调压缩机、冰箱压缩机、电机、磁控管、变压器等家电配件产品。现拥有中国最完整的空调产业链、冰箱产业链、洗衣机产业链、微波炉产业链和洗碗机产业链;拥有中国最完整的小家电产品群和厨房家电产品群;在全球设有60多个海外分支机构,产品远销200多个国家和地区。  2014年,美的集团整体实现销售收入1423亿元,其中外销销售收入498亿。 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大风车滴呀滴溜溜地转

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值