工商网站查询企业,wordpress页面导航条,动易sitefactorycms 网站配置保存不了问题,服务之家网站推广公司前端相关
1.谈谈你对http协议的认识。 浏览器本质#xff0c;socket客户端遵循Http协议 HTTP协议本质#xff1a;通过\r\n分割的规范 请求响应之后断开链接 无状态、 短连接 具体#xff1a; Http协议是建立在tcp之上的#xff0c;是一种规范#xff0c;它…前端相关
1.谈谈你对http协议的认识。 浏览器本质socket客户端遵循Http协议 HTTP协议本质通过\r\n分割的规范 请求响应之后断开链接 无状态、 短连接 具体 Http协议是建立在tcp之上的是一种规范它规范定了发送的数据的数据格式然而这个数据格式是通过\r\n 进行分割的请求头与请求体也是通过2个\r\n分割的响应的时候响应头与响应体也是通过\r\n分割并且还规定已请求已响应就会断开链接即--- 短连接、无状态 2.谈谈你对websocket协议的认识。 a.什么是websocket 是给浏览器新建的一套协议 协议规定:创建连接后不断开 通过\r\n分割,让客户端和服务端创建连接后不断开、验证数据加密 # b.本质: # 就是一个创建连接后不断开的socket # 当连接成功后: - 客户端(浏览器)会自动向服务端发送消息 - 服务端接收后,会对该数据加密:base64(sha1(swkmagic_string)) - 构造响应头 - 发送给客户端 # 建立双工通道,进行收发数据 # c.框架中是如何使用websocket的 djangochannel flaskgevent-websocket tornado内置 # d.websocket的优缺点 优点代码简单不再重复创建连接 缺点兼容性没有长轮询好如IE会有不兼容 WebSocket和HTTP的区别 http协议是用在应用层的协议他是基于tcp协议的http协议建立链接也必须要有三次握手才能发送信息。 http链接分为短链接长链接短链接是每次请求都要三次握手才能发送自己的信息。即每一个request对应一个response。长链接是在一定的期限内保持链接。保持TCP连接不断开。客户端与服务器通信必须要有客户端发起然后服务器返回结果。客户端是主动的服务器是被动的。 WebSocket他是为了解决客户端发起多个http请求到服务器资源浏览器必须要经过长时间的轮训问题而生的他实现了多路复用他是全双工通信。在webSocket协议下客服端和浏览器可以同时发送信息。 建立了WenSocket之后服务器不必在浏览器发送request请求之后才能发送信息到浏览器。这时的服务器已有主动权想什么时候发就可以发送信息到服务器。而且信息当中不必在带有head的部分信息了与http的长链接通信来说这种方式不仅能降低服务器的压力。而且信息当中也减少了部分多余的信息。 3.什么是magic string 客户端向服务端发送消息时会有一个sec-websocket-key和magic string的随机字符串(魔法字符串) 服务端接收到消息后会把他们连接成一个新的key串进行编码、加密确保信息的安全性 4.如何创建响应式布局
# a.可以通过引用Bootstrap实现
# b.通过看Bootstrap源码文件可知其本质就是通过CSS实现的style/*浏览器窗口宽度大于768,背景色变为 green*/media (min-width: 768px) {.pg-header{background-color: green;}}/*浏览器窗口宽度大于992,背景色变为 pink*/media (min-width: 992px) {.pg-header{background-color: pink;}}/style
/head
body
div classpg-header/div
/body
5.你曾经使用过哪些前端框架 jQuery - BootStrapH-ui - Vue.js(与vue齐名的前端框架React和Angular) 6.什么是ajax请求并使用jQuery和XMLHttpRequest对象实现一个ajax请求。 1.没用ajax浏览器访问服务器请求用户看得到页面刷新也就等同于重新发请求刷新看得到也就等同于请求看得到。等请求完页面刷新新内容出现用户看到新内容。 2.用ajax浏览器访问服务器请求用户看不到是悄悄进行。等请求完页面不刷新新内容也会出现用户看到新内容。 http://www.cnblogs.com/wupeiqi/articles/5703697.html 7.如何在前端实现轮训
# 轮询是在特定的的时间间隔如每1秒由浏览器对服务器发出HTTP request
# 然后由服务器返回最新的数据给客户端的浏览器。
var xhr new XMLHttpRequest();setInterval(function(){xhr.open(GET,/user);xhr.onreadystatechange function(){};xhr.send();},1000) 8.如何在前端实现长轮训
# ajax实现:在发送ajax后,服务器端会阻塞请求直到有数据传递或超时才返回。
# 客户端JavaScript响应处理函数会在处理完服务器返回的信息后再次发出请求重新建立连接。function ajax(){var xhr new XMLHttpRequest();xhr.open(GET,/user);xhr.onreadystatechange function(){ajax();};xhr.send();} 9.vuex的作用 1.不同组件之间共享状态可以进行状态的修改和读取。 2.可以理解为是一个全局对象所有页面都可以访问 3.还有比较重要的单一状态树管理让数据的修改脉络更加清晰便于定位问题。 # 比如用户做了一些加减的操作、三个页面都要用、可以用传参、但是很麻烦、这种时候用vuex就简单一些 10.vue中的路由的拦截器的作用 # 统一处理所有http请求和响应时可以用axios的拦截器。 # 通过配置http response inteceptor当后端接口返回401 Unauthorized未授权让用户重新登录。 # so可以用来做登录拦截验证 11.axios的作用 # axios是vue-resource后出现的Vue请求数据的插件 # 可以做的事情 从浏览器中创建 XMLHttpRequest 从 node.js 发出 http 请求 支持 Promise API 拦截请求和响应 转换请求和响应数据 取消请求 自动转换JSON数据 客户端支持防止 CSRF/XSRF 12.列举vue的常见指令。 # 1、v-if指令:判断指令根据表达式值得真假来插入或删除相应的值。 # 2、v-show指令: # 条件渲染指令无论返回的布尔值是true还是false元素都会存在html中 # false的元素会隐藏在html中并不会删除. # 3、v-else指令:配合v-if或v-else使用。 # 4、v-for指令:循环指令相当于遍历。 # 5、v-bind:给DOM绑定元素属性。 # 6、v-on指令:监听DOM事件。 13.简述jsonp及实现原理
应为有同源策略所以需要使用scripy 标签 # 原理 1、先在客户端注册一个callback, 然后把callback的名字传给服务器。 2、此时服务器先生成 json 数据。 3、然后以 javascript 语法的方式生成一个function , function 名字就是传递上来的参数 jsonp. 4、最后将 json 数据直接以入参的方式放置到 function 中这样就生成了一段 js 语法的文档返回给客户端。 客户端浏览器解析script标签并执行返回的 javascript 文档此时数据作为参数 传入到了客户端预先定义好的 callback 函数里.动态执行回调函数 # 注意 # JSON 是一种数据格式 # JSONP 是一种数据调用的方式 14.什么是cors # 跨域资源共享Cross-Origin Resource Sharing # 其本质是设置响应头使得浏览器允许跨域请求。 # 简单请求(一次请求) 1、请求方式HEAD、GET、POST 2、请求头信息 Accept Accept-Language Content-Language Last-Event-ID Content-Type 对应的值是以下三个中的任意一个 application/x-www-form-urlencoded multipart/form-data text/plain # 非简单请求(两次请求) 在发送真正的请求之前会默认发送一个options请求做预检预检成功后才发送真正的请求 # 预检 如果复杂请求是PUT等请求则服务端需要设置允许某请求否则“预检”不通过 Access-Control-Request-Method 如果复杂请求设置了请求头则服务端需要设置允许某请求头否则“预检”不通过 Access-Control-Request-Headers 15.列举Http请求中常见的请求方式 http请求方法有8种: GET POST HEAD OPTIONS PUT(修改数据) DELETE TRACE CONNECT 16.列举Http请求中的状态码 # 2开头成功 200请求成功 202已接受请求尚未处理 204请求成功且不需返回内容 # 3开头重定向 301永久重定向 302临时重定向 # 4开头客户端错误 400Bad Request请求的语义或是参数有错 403Forbidden服务器拒绝了请求(csrf) 404Not Found找不到页面(资源) # 5开头服务器错误 500服务器遇到错误无法完成请求 502网关错误一般是服务器压力过大导致连接超时 503服务器宕机 17.列举Http请求中常见的请求头 # 常见请求头User-Agent、Referer、Host、Cookie、Connection、Accept 18.看图写结果js 李杰
Python框架 19.django、flask、tornado框架的比较 - django大而全的框架它的内部组件比较多内部提供ORM、Admin、中间件、Form、ModelForm、Session、缓存、信号、CSRF功能也都挺完善的 - flask微型框架内部组件就比较少了但是有很多第三方组件来扩展它比如说有那个wtform与django的modelform类似表单验证、flask-sqlalchemy操作数据库的、flask-session、flask-migrate、flask-script、blinker可扩展强第三方组件丰富。所以对他本身来说有那种短小精悍的感觉 - tornado异步非阻塞。是一个轻量级的Web框架异步非阻塞内置WebSocket功能。目标通过一个线程处理N个并发请求(处理IO)。内部组件内部自己实现socket、路由系统、视图、模板、cookie、csrf django和flask的共同点就是他们2个框架都没有写socket所以他们都是利用第三方模块wsgi。 但是内部使用的wsgi也是有些不同的django本身运行起来使用wsgiref而flask使用werkzeug wsgi 还有一个区别就是他们的请求管理不太一样django是通过将请求封装成request对象再通过参数传递而flask是通过上下文管理机制 20.什么是wsgi 是web服务网关接口是一套协议。 是通过以下模块实现了wsgi协议 - wsgiref - werkzurg - uwsgi 关于部署 以上模块本质编写socket服务端用于监听请求当有请求到来则将请求数据进行封装然后交给web框架处理。 Django
21.django请求的生命周期 用户请求进来先走到 wsgi -- 然后将请求交给 jango的中间件 -- 穿过django中间件方法是process_request接着就是 路由匹配 -- 路由匹配成功之后就执行相应的 视图函数 -- 在视图函数中可以调用orm做数据库操作 -- 再从模板路径 将模板拿到 -- 然后在后台进行模板渲染 -- 模板渲染完成之后就变成一个字符串 -- 再把这个字符串经过所有中间件方法process_response 和wsgi 返回给用户 22.列举django的内置组件
form 组件
- 对用户请求的数据进行校验
- 生成HTML标签
PS
- form对象是一个可迭代对象。
- 问题choice的数据如果从数据库获取可能会造成数据无法实时更新- 重写构造方法在构造方法中重新去数据库获取值。- ModelChoiceField字段from django.forms import Formfrom django.forms import fieldsfrom django.forms.models import ModelChoiceFieldclass UserForm(Form):name fields.CharField(label用户名,max_length32)email fields.EmailField(label邮箱)ut_id ModelChoiceField(querysetmodels.UserType.objects.all()) 依赖class UserType(models.Model):title models.CharField(max_length32)def __str__(self):return self.title信号
django的信号其实就是django内部为开发者预留的一些自定制功能的钩子。
只要在某个信号中注册了函数那么django内部执行的过程中就会自动触发注册在信号中的函数。
如
pre_init # django的modal执行其构造方法前自动触发
post_init # django的modal执行其构造方法后自动触发
pre_save # django的modal对象保存前自动触发
post_save # django的modal对象保存后自动触发
场景:
在数据库某些表中添加数据时可以进行日志记录。CSRF
目标防止用户直接向服务端发起POST请求。
对所有的post请求做验证/ 将jango生成的一串字符串发送给我们一种是从请求体发过来一种是放在隐藏的标签里面用的是process_view
方案先发送GET请求时将token保存到cookie、Form表单中隐藏的input标签
以后再发送请求时只要携带过来即可。ContentType
contenttype是django的一个组件app
为我们找到django程序中所有app中的所有表并添加到记录中。可以使用他再加上表中的两个字段实现一张表和N张表创建FK关系。 - 字段表名称 - 字段数据行ID
应用路飞表结构优惠券和专题课和学位课关联。中间件
对所有的请求进行批量处理在视图函数执行前后进行自定义操作。
应用用户登录校验
问题为甚么不使用装饰器
如果不使用中间件就需要给每个视图函数添加装饰器太繁琐session
cookie与session区别
acookie是保存在浏览器端的键值对而session是保存的服务器端的键值对但是依赖cookie。也可以不依赖cookie可以放在url或请求头但是cookie比较方便
b以登录为例cookie为通过登录成功后设置明文的键值对并将键值对发送客户端存明文信息可能存在泄漏不安全session则是生成随机字符串发给用户并写到浏览器的cookie中同时服务器自己也会保存一份。
c在登录验证时cookie根据浏览器发送请求时附带的cookie的键值对进行判断如果存在则验证通过session在请求用户的cookie中获取随机字符串根据随机字符串在session中获取其对应的值进行验证cors跨域场景前后端分离时本地测试开发时使用
如果网站之间存在跨域域名不同端口不同会导致出现跨域但凡出现跨域浏览器就会出现同源策略的限制
解决在我们的服务端给我们响应数据加上响应头--- 在中间件加的缓存
常用的数据放在缓存里面就不用走视图函数请求进来通过所有的process_request,会到缓存里面查数据有就直接拿没有就走视图函数关键点1执行完所有的process_request才去缓存取数据2执行完所有的process_response才将数据放到缓存关于缓存问题
1:为什么放在最后一个process_request才去缓存
因为需要验证完用户的请求才能返回数据2:什么时候将数据放到缓存中
第一次走中间件缓存没有数据会走视图函数取数据库里面取数据
当走完process_response,才将数据放到缓存里因为走process_response的时候可能给我们的响应加处理3.为什么使用缓存
将常用且不太频繁修改的数据放入缓存。
以后用户再来访问先去缓存查看是否存在如果有就返回
否则去数据库中获取并返回给用户再加入到缓存以便下次访问 23.列举django中间件的5个方法以及django中间件的应用场景 process_request(self,request) 先走request 通过路由匹配返回 process_view(self, request, callback, callback_args, callback_kwargs) 再返回执行view process_template_response(self,request,response) 当视图函数的返回值 process_exception(self, request, exception) 当视图函数的返回值对象中有render方法时该方法才会被调用 process_response(self, request, response) 24.简述什么是FBV和CBV
FBV 基于函数
# FBV 写法
# urls.pyurl(r^login/$,views.login, namelogin),# views.py
def login(request):if request.method POST:print(request.POST)return render(request,login.html)# HTML
!DOCTYPE html
html langen
headmeta charsetUTF-8meta http-equivX-UA-Compatible contentIEedgemeta nameviewport contentwidthdevice-width, initial-scale1title登录页面/title
/head
body
form action{% url login %} methodpost enctypemultipart/form-datainput typetext nameuser2input typefile namefileinput typesubmit value提交/form
/body
/htmlCBV 基于类
# urls.py
url(r^login/$,views.Login.as_view(), namelogin), # views.py
from django.views import View
class Login(View): # 类首字母大写def get(self,request):return render(request,login.html)def post(self,request):print(request.POST)return HttpResponse(OK)加装饰器
class IndexView(View):# 如果是crsf相关必须放在此处def dispach(self,request):# 通过反射执行post/get method_decoretor(装饰器函数)def get(self,request):passdef post(self,request):pass
路由IndexView.as_view()
25.FBV与CBV的区别
- 没什么区别因为他们的本质都是函数。CBV的.as_view()返回的view函数view函数中调用类的dispatch方法
在dispatch方法中通过反射执行get/post/delete/put等方法。D非要说区别的话
- CBV比较简洁GET/POST等业务功能分别放在不同get/post函数中。FBV自己做判断进行区分。 26.django的request对象是在什么时候创建的
当请求一个页面时, Django会建立一个包含请求元数据的 HttpRequest 对象.
当Django 加载对应的视图时, HttpRequest对象将作为视图函数的第一个参数.
每个视图会返回一个HttpResponse对象. 27.如何给CBV的程序添加装饰器
添加装饰器
方式一
from django.views import View
from django.utils.decorators import method_decorator --- 需要引入memethod_decoratordef auth(func):def inner(*args,**kwargs):return func(*args,**kwargs)return innerclass UserView(View):method_decorator(auth)def get(self,request,*args,**kwargs):return HttpResponse(...) 方式二
- csrf的装饰器要加到dispath前面
from django.views import View
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt,csrf_protect --- 需要引入 csrf_exemptclass UserView(View):method_decorator(csrf_exempt)def dispatch(self, request, *args, **kwargs):return HttpResponse(...)或者
from django.views import View
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt,csrf_protectmethod_decorator(csrf_exempt,namedispatch) --- 指定名字
class UserView(View):def dispatch(self, request, *args, **kwargs):return HttpResponse(...)
28.列举django orm 中所有的方法QuerySet对象的所有方法
返回QuerySet对象的方法有all()filter()exclude()order_by()reverse()distinct()特殊的QuerySetvalues() 返回一个可迭代的字典序列values_list() 返回一个可迭代的元组序列返回具体对象的get()first()last()返回布尔值的方法有exists()返回数字的方法有count()
29.only和defer的区别 def defer(self, *fields):models.UserInfo.objects.defer(username,id)或models.UserInfo.objects.filter(...).defer(username,id)#映射中排除某列数据def only(self, *fields):#仅取某个表中的数据models.UserInfo.objects.only(username,id)或models.UserInfo.objects.filter(...).only(username,id)
30.select_related和prefetch_related的区别
# 他俩都用于连表查询减少SQL查询次数
select_related主要针一对一和多对一关系进行优化通过多表join关联查询一次性获得所有数据
存放在内存中但如果关联的表太多会严重影响数据库性能。
def index(request):obj Book.objects.all().select_related(publisher)return render(request, index.html, locals())prefetch_related是通过分表先获取各个表的数据存放在内存中然后通过Python处理他们之间的关联。
def index(request):obj Book.objects.all().prefetch_related(publisher)return render(request, index.html, locals())# 举例
def select_related(self, *fields)# 性能相关表之间进行join连表操作一次性获取关联的数据。model.tb.objects.all().select_related()model.tb.objects.all().select_related(外键字段)model.tb.objects.all().select_related(外键字段__外键字段)def prefetch_related(self, *lookups)# 性能相关多表连表操作时速度会慢使用其执行多次SQL查询在Python代码中实现连表操作。# 获取所有用户表# 获取用户类型表where id in (用户表中的查到的所有用户ID)models.UserInfo.objects.prefetch_related(外键字段)from django.db.models import Count, Case, When, IntegerFieldArticle.objects.annotate(numviewsCount(Case(When(readership__what_time__lttreshold, then1), output_fieldCharField(),)))students Student.objects.all().annotate(num_excused_absencesmodels.Sum(models.Case(models.When(absence__typeExcused, then1),default0,output_fieldmodels.IntegerField()))) # 1次SQL
# select * from userinfo
objs UserInfo.obejcts.all()
for item in objs:print(item.name)# n1次SQL
# select * from userinfo
objs UserInfo.obejcts.all()
for item in objs:# select * from usertype where id item.id print(item.name,item.ut.title)# 1次SQL使用select_related
# select * from userinfo inner join usertype on userinfo.ut_id usertype.id
objs UserInfo.obejcts.all().select_related(ut) 连表查询
for item in objs:print(item.name,item.ut.title).prefetch_related()# select * from userinfo where id 8# 计算[1,2]# select * from usertype where id in [1,2]objs UserInfo.obejcts.filter(id__lte8).prefetch_related(ut)for obj in objs:print(obj.name,obj.ut.title)
31.filter和exclude的区别 def filter(self, *args, **kwargs)# 条件查询(符合条件)# 查出符合条件# 条件可以是参数字典Qdef exclude(self, *args, **kwargs)# 条件查询(排除条件)# 排除不想要的# 条件可以是参数字典Q
32.列举django orm中三种能写sql语句的方法。
# 原生SQL --- connection
from django.db import connection, connections
cursor connection.cursor() # cursor connections[default].cursor()
cursor.execute(SELECT * from auth_user where id %s, [1])
row cursor.fetchone() # fetchall()/fetchmany(..)# 靠近原生SQL--extra\raw
# extradef extra(self, selectNone, whereNone, paramsNone, tablesNone, order_byNone,
select_paramsNone)# 构造额外的查询条件或者映射如子查询Entry.objects.extra(select{new_id: select col from sometable where othercol %s},select_params(1,))Entry.objects.extra(where[headline%s], params[Lennon])Entry.objects.extra(where[fooa OR bar a, baz a])Entry.objects.extra(select{new_id: select id from tb where id %s}, s
elect_params(1,), order_by[-nid])# raw
def raw(self, raw_query, paramsNone, translationsNone, usingNone):# 执行原生SQLmodels.UserInfo.objects.raw(select * from userinfo)# 如果SQL是其他表时必须将名字设置为当前UserInfo对象的主键列名models.UserInfo.objects.raw(select id as nid,name as title from 其他表)# 为原生SQL设置参数models.UserInfo.objects.raw(select id as nid from userinfo where nid%s, params[12,])# 将获取的到列名转换为指定列名name_map {first: first_name, last: last_name, bd: birth_date, pk: id}Person.objects.raw(SELECT * FROM some_other_table, translationsname_map)# 指定数据库models.UserInfo.objects.raw(select * from userinfo, usingdefault)
33.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 db1else: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,]
34.F和Q的作用?
# F:主要用来获取原数据进行计算。
# Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取模的操作。
# 修改操作也可以使用F函数,比如将每件商品的价格都在原价格的基础上增加10
from django.db.models import F
from app01.models import GoodsGoods.objects.update(priceF(price)10) # 对于goods表中每件商品的价格都在原价格的基础上增加10元F查询专门对对象中某列值的操作不可使用__双下划线
Q:用来进行复杂查询Q查询可以组合使用 “”, “|” 操作符当一个操作符是用于两个Q的对象,它产生一个新的Q对象Q对象可以用 “~” 操作符放在前面表示否定也可允许否定与不否定形式的组合。Q对象可以与关键字参数查询一起使用不过一定要把Q对象放在关键字参数查询的前面。Q(条件1) | Q(条件2) 或Q(条件1) Q(条件2) 且Q(条件1) ~Q(条件2) 非
35.values和values_list的区别
def values(self, *fields):# 获取每行数据为字典格式def values_list(self, *fields, **kwargs):# 获取每行数据为元祖 36.如何使用django orm批量创建数据
def bulk_create(self, objs, batch_sizeNone):# 批量插入# batch_size表示一次插入的个数objs [models.DDD(namer11),models.DDD(namer22)]models.DDD.objects.bulk_create(objs, 10)
37.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 - 应用只要是客户端向服务端发送表单数据时都可以进行使用如用户登录注册
38.django的Form组件中如果字段中包含choices参数请使用两种方式实现数据源实时更新。
# 方式一:重写构造方法在构造方法中重新去数据库获取值class UserForm(Form):name fields.CharField(label用户名,max_length32)email fields.EmailField(label邮箱)ut_id fields.ChoiceField(# choices[(1,普通用户),(2,IP用户)]choices[])def __init__(self,*args,**kwargs):super(UserForm,self).__init__(*args,**kwargs)self.fields[ut_id].choices models.UserType.objects.all().values_list(id,title)# 方式二: ModelChoiceField字段from django.forms import Formfrom django.forms import fieldsfrom django.forms.models import ModelChoiceFieldclass UserForm(Form):name fields.CharField(label用户名,max_length32)email fields.EmailField(label邮箱)ut_id ModelChoiceField(querysetmodels.UserType.objects.all()) # 依赖class UserType(models.Model):title models.CharField(max_length32)def __str__(self):return self.title
39.django的Model中的ForeignKey字段中的on_delete参数有什么作用
在django2.0后定义外键和一对一关系的时候需要加on_delete选项此参数为了避免两个表里的数据不一致问题不然会报错
TypeError: __init__() missing 1 required positional argument: on_delete举例说明usermodels.OneToOneField(User)
ownermodels.ForeignKey(UserProfile)需要改成
usermodels.OneToOneField(User,on_deletemodels.CASCADE) --在老版本这个参数models.CASCADE是默认值
ownermodels.ForeignKey(UserProfile,on_deletemodels.CASCADE) --在老版本这个参数models.CASCADE是默认值参数说明
on_delete有CASCADE、PROTECT、SET_NULL、SET_DEFAULT、SET()五个可选择的值
CASCADE此值设置是级联删除。
PROTECT此值设置是会报完整性错误。
SET_NULL此值设置会把外键设置为null前提是允许为null。
SET_DEFAULT此值设置会把设置为外键的默认值。
SET()此值设置会调用外面的值可以是一个函数。
一般情况下使用CASCADE就可以了。
40.django中csrf的实现机制
目的防止用户直接向服务端发起POST请求- 用户先发送GET获取csrf token: Form表单中一个隐藏的标签 token
- 发起POST请求时需要携带之前发送给用户的csrf token
- 在中间件的process_view方法中进行校验。在html中添加{%csrf_token%}标签
41.django如何实现websocket
django中可以通过channel实现websocket 42.基于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中获取tokenfunction Do1(){$.ajax({url:/index/,data:{id:1},type:POST,headers:{X-CSRFToken:$.cookie(csrftoken) // 去cookie中获取},success:function(data){console.log(data);}});}方式三搞个函数ajaxSetup当有多的ajax请求即会执行这个函数$.ajaxSetup({beforeSend:function (xhr,settings) {xhr.setRequestHeader(X-CSRFToken,$.cookie(csrftoken))} });函数版本
body
input typebutton onclickDo1(); valueDo it/
input typebutton onclickDo2(); valueDo it/
input typebutton onclickDo3(); valueDo it/script src/static/jquery-3.3.1.min.js/script
script src/static/jquery.cookie.js/script
script$.ajaxSetup({beforeSend: function(xhr, settings) {xhr.setRequestHeader(X-CSRFToken, $.cookie(csrftoken));}});function Do1(){$.ajax({url:/index/,data:{id:1},type:POST,success:function(data){console.log(data);}});}function Do2(){$.ajax({url:/index/,data:{id:1},type:POST,success:function(data){console.log(data);}});}function Do3(){$.ajax({url:/index/,data:{id:1},type:POST,success:function(data){console.log(data);}});}
/script
/body
43.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对象删除后,自动触发 44.django缓存如何设置
jango中提供了6种缓存方式开发调试不加缓存内存文件数据库Memcache缓存python-memcached模块Memcache缓存pylibmc模块安装第三方组件支持redisdjango-redis组件设置缓存
# 全站缓存中间件
MIDDLEWARE_CLASSES (‘django.middleware.cache.UpdateCacheMiddleware’, #第一django.middleware.common.CommonMiddleware,‘django.middleware.cache.FetchFromCacheMiddleware’, #最后
)# 视图缓存
from django.views.decorators.cache import cache_page
import timecache_page(15) #超时时间为15秒
def index(request):ttime.time() #获取当前时间return render(request,index.html,locals())# 模板缓存
{% load cache %}h3 stylecolor: green不缓存:-----{{ t }}/h3{% cache 2 name %} # 存的keyh3缓存:-----:{{ t }}/h3
{% endcache %}
45.django的缓存能使用redis吗如果可以的话如何配置
pip install django-redis
apt-get install redis-serv# 在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_connectiondef index(request):
# 根据名字去连接池中获取连接
conn get_redis_connection(default)conn.hset(n1,k1,v1) # 存数据return HttpResponse(...)
46.django路由系统中name的作用 路由系统中name的作用反向解析路由字符串 url(r^home, views.home, namehome) 在模板中使用{ % url home %} 在视图中使用reverse(“home” 47.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 48.django-debug-toolbar的作用 一、查看访问的速度、数据库的行为、cache命中等信息。 二、尤其在Mysql访问等的分析上大有用处(sql查询速度) 49.django中如何实现单元测试 对于每一个测试方法都会将setUp()和tearDown()方法执行一遍 会单独新建一个测试数据库来进行数据库的操作方面的测试默认在测试完成后销毁。 在测试方法中对数据库进行增删操作最后都会被清除。也就是说在test_add中插入的数据在test_add测试结束后插入的数据会被清除。 django单元测试时为了模拟生产环境会修改settings中的变量例如, 把DEBUG变量修改为True, 把ALLOWED_HOSTS修改为[*]。 50.解释orm中 db first 和 code first的含义 db first: 先创建数据库再更新表模型 code first先写表模型再更新数据库 https://www.cnblogs.com/jassin-du/p/8988897.html 51.django中如何根据数据库表生成model中的类 1、修改seting文件在setting里面设置要连接的数据库类型和名称、地址 2、运行下面代码可以自动生成models模型文件 - python manage.py inspectdb 3、创建一个app执行下下面代码 - python manage.py inspectdb app/models.py 52.使用orm和原生sql的优缺点 SQL # 优点执行速度快 # 缺点编写复杂开发效率不高 ORM # 优点让用户不再写SQL语句提高开发效率;可以很方便地引入数据缓存之类的附加功能 # 缺点在处理多表联查、where条件复杂查询时ORM的语法会变得复杂;没有原生SQL速度快 53.简述MVC和MTV MVCmodel(数据库)、view(模块)、controller(视图控制) MTVmodel(数据库)、tempalte(视图)、view(控制) 54.django的contenttype组件的作用 contenttype是django的一个组件(app)它可以将django下所有app下的表记录下来 可以使用他再加上表中的两个字段,实现一张表和N张表动态创建FK关系。 - 字段表名称 - 字段数据行ID 应用路飞表结构优惠券和专题课和学位课关联 Restfull
55.谈谈你对restfull 规范的认识 restful其实就是一套编写接口的协议规定如何编写以及如何设置返回值、状态码等信息。 # 最显著的特点 # 用restful: 给用户一个url根据method不同在后端做不同的处理 比如post创建数据、get获取数据、put和patch修改数据、delete删除数据。 # 不用restful: 给调用者很多url每个url代表一个功能比如add_user/delte_user/edit_user/ # 当然还有协议其他的比如 版本来控制让程序有多个版本共存的情况版本可以放在 url、请求头accept/自定义、GET参数 状态码200/300/400/500 url中尽量使用名词restful也可以称为“面向资源编程” api标示 api.luffycity.com www.luffycity.com/api/ 56.接口的幂等性是什么意思
一个接口通过1次相同的访问再对该接口进行N次相同的访问时对资源不造影响就认为接口具有幂等性。GET #第一次获取结果、第二次也是获取结果对资源都不会造成影响幂等。POST #第一次新增数据第二次也会再次新增非幂等。PUT #第一次更新数据第二次不会再次更新幂等。PATCH#第一次更新数据第二次不会再次更新非幂等。DELTE#第一次删除数据第二次不在再删除幂等。
57.什么是RPC
远程过程调用协议
是一种通过网络从远程计算机程序上请求服务而不需要了解底层网络技术的协议。
进化的顺序: 现有的RPC,然后有的RESTful规范 58.Http和Https的区别
#Http: 80端口
#https: 443端口
# http信息是明文传输https则是具有安全性的ssl加密传输协议。
#- 自定义证书 - 服务端创建一对证书- 客户端必须携带证书
#- 购买证书- 服务端 创建一对证书。。。。- 客户端 去机构获取证书数据加密后发给咱们的服务单- 证书机构:公钥给改机构
59.为什么要使用django rest framework框架
# 在编写接口时可以不使用django rest framework框架
# 不使用也可以做可以用django的CBV来实现开发者编写的代码会更多一些。
# 使用内部帮助我们提供了很多方便的组件我们通过配置就可以完成相应操作如序列化可以做用户请求数据校验queryset对象的序列化称为json解析器获取用户请求数据request.data会自动根据content-type请求头的不能对数据进行解析分页将从数据库获取到的数据在页面进行分页显示。# 还有其他组件认证、权限、访问频率控制
60.django rest framework框架中都有那些组件
#- 路由自动帮助开发者快速为一个视图创建4个urlwww.oldboyedu.com/api/v1/student/$www.oldboyedu.com/api/v1/student(?Pformat\w)$www.oldboyedu.com/api/v1/student/(?Ppk\d)/$www.oldboyedu.com/api/v1/student/(?Ppk\d)(?Pformat\w)$
#- 版本处理- 问题版本都可以放在那里- url- GET - 请求头
#- 认证 - 问题认证流程
#- 权限 - 权限是否可以放在中间件中以及为什么
#- 访问频率的控制匿名用户可以真正的防止无法做到真正的访问频率控制只能把小白拒之门外。如果要封IP使用防火墙来做。登录用户可以通过用户名作为唯一标示进行控制如果有人注册很多账号则无法防止。
#- 视图
#- 解析器 根据Content-Type请求头对请求体中的数据格式进行处理。request.data
#- 分页
#- 序列化- 序列化- source- 定义方法- 请求数据格式校验
#- 渲染器
61.django rest framework框架中的视图都可以继承哪些类
a. 继承APIView最原始但定制性比较强这个类属于rest framework中的顶层类内部帮助我们实现了只是基本功能认证、权限、频率控制但凡是数据库、分页等操作都需要手动去完成比较原始。class GenericAPIView(APIView)def post(...):pass b.继承GenericViewSetViewSetMixingenerics.GenericAPIView首先他的路由就发生变化如果继承它之后路由中的as_view需要填写对应关系在内部也帮助我们提供了一些方便的方法get_querysetget_objectget_serializerget_serializer_classget_serializer_contextfilter_queryset
注意要设置queryset字段否则会抛出断言的异常。代码
只提供增加功能 只继承GenericViewSetclass TestView(GenericViewSet):serialazer_class xxxdef creat(self,*args,**kwargs):pass # 获取数据并对数据c. 继承 modelviewset -- 快速快发-ModelViewSet(增删改查全有数据库操作)-mixins.CreateModelMixin只有增,GenericViewSet-mixins.CreateModelMixin,DestroyModelMixin,GenericViewSet对数据库和分页等操作不用我们在编写只需要继承相关类即可。示例只提供增加功能
class TestView(mixins.CreateModelMixin,GenericViewSet):serializer_class XXXXXXX
*** modelviewset -- 快速开发复杂点的genericview、apiview 62.简述 django rest framework框架的认证流程。
- 如何编写写类并实现authenticators请求进来认证需要编写一个类类里面有一个authenticators方法我们可以自定义这个方法可以定制3类返回值。成功返回元组返回none为匿名用户抛出异常为认证失败。源码流程请求进来先走dispatch方法然后封装的request对象会执行user方法由user触发authenticators认证流程
- 方法中可以定义三种返回值- user,auth认证成功- None , 匿名用户- 异常 认证失败
- 流程- dispatch - 再去request中进行认证处理
63.django rest framework如何实现的用户访问频率控制
# 对匿名用户根据用户IP或代理IP作为标识进行记录为每个用户在redis中建一个列表{throttle_1.1.1.1:[1526868876.497521,152686885.497521...]throttle_1.1.1.2:[1526868876.497521,152686885.497521...]throttle_1.1.1.3:[1526868876.497521,152686885.497521...]} 每个用户再来访问时需先去记录中剔除过期记录再根据列表的长度判断是否可以继续访问。如何封IP在防火墙中进行设置
--------------------------------------------------------------------------
# 对注册用户根据用户名或邮箱进行判断。{throttle_xxxx1:[1526868876.497521,152686885.497521...]throttle_xxxx2:[1526868876.497521,152686885.497521...]throttle_xxxx3:[1526868876.497521,152686885.497521...]}
每个用户再来访问时需先去记录中剔除过期记录再根据列表的长度判断是否可以继续访问。
\如1分钟40次列表长度限制在40超过40则不可访问
Flask 64.Flask框架的优势 Flask自由、灵活可扩展性强透明可控第三方库的选择面广开发时可以结合最流行最强大的Python库 65.Flask框架依赖组件 # 依赖jinja2模板引擎 # 依赖werkzurg协议 66.Flask蓝图的作用 # blueprint把实现不同功能的module分开.也就是把一个大的App分割成各自实现不同功能的module. # 在一个blueprint中可以调用另一个blueprint的视图函数, 但要加相应的blueprint名. 67.列举使用的Flask第三方组件 # Flask组件 flask-session session放在redis flask-SQLAlchemy 如django里的ORM操作 flask-migrate 数据库迁移 flask-script 自定义命令 blinker 信号-触发信号 # 第三方组件 Wtforms 快速创建前端标签、文本校验 dbutile 创建数据库连接池 gevnet-websocket 实现websocket # 自定义Flask组件 自定义auth认证 参考flask-login组件 68.简述Flask上下文管理流程? # a、简单来说falsk上下文管理可以分为三个阶段 1、请求进来时将请求相关的数据放入上下文管理中 2、在视图函数中要去上下文管理中取值 3、请求响应要将上下文管理中的数据清除 # b、详细点来说 1、请求刚进来 将requestsession封装在RequestContext类中 appg封装在AppContext类中 并通过LocalStack将requestcontext和appcontext放入Local类中 2、视图函数中 通过localproxy---偏函数---localstack---local取值 3、请求响应时 先执行save.session()再各自执行pop(),将local中的数据清除 69.Flask中的g的作用 # g是贯穿于一次请求的全局变量当请求进来将g和current_app封装为一个APPContext类 # 再通过LocalStack将Appcontext放入Local中取值时通过偏函数在LocalStack、local中取值 # 响应时将local中的g数据删除 Flask中上下文管理主要涉及到了那些相关的类并描述类主要作用 RequestContext #封装进来的请求赋值给ctx AppContext #封装app_ctx LocalStack #将local对象中的数据维护成一个栈先进后出 Local #保存请求上下文对象和app上下文对象 为什么要Flask把Local对象中的的值stack 维护成一个列表 # 因为通过维护成列表可以实现一个栈的数据结构进栈出栈时只取一个数据巧妙的简化了问题。 # 还有在多app应用时可以实现数据隔离列表里不会加数据而是会生成一个新的列表 # local是一个字典字典里keystack是唯一标识value是一个列表 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__走。 在Flask中实现WebSocket需要什么组件 gevent-websocket wtforms组件的作用 #快速创建前端标签、文本校验如django的ModelForm Flask框架默认session处理机制 # 前提: 不熟的话:记不太清了,应该是……分两个阶段吧 # 创建: 当请求刚进来的时候,会将request和session封装成一个RequestContext()对象, 接下来把这个对象通过LocalStack()放入内部的一个Local()对象中; 因为刚开始 Local 的ctx中session是空的; 所以,接着执行open_session,将cookie 里面的值拿过来,重新赋值到ctx中 (Local实现对数据隔离,类似threading.local) # 销毁: 最后返回时执行 save_session() 将ctx 中的session读出来进行序列化,写到cookie 然后给用户,接着把 ctx pop掉 解释Flask框架中的Local对象和threading.local对象的区别 # 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(targettask, args(i,)) t.start() Flask中 blinker 是什么 # flask中的信号blinker 信号主要是让开发者可是在flask请求过程中定制一些行为。 或者说flask在列表里面预留了几个空列表在里面存东西。 简言之信号允许某个发送者通知接收者有事情发生了 before_request有返回值blinker没有返回值 # 10个信号 request_started _signals.signal(request-started) #请求到来前执行 request_finished _signals.signal(request-finished) #请求结束后执行 before_render_template _signals.signal(before-render-template)#模板渲染前执行 template_rendered _signals.signal(template-rendered)#模板渲染后执行 got_request_exception _signals.signal(got-request-exception) #请求执行出现异常时执行 request_tearing_down _signals.signal(request-tearing-down)#请求执行完毕后自动执行无论成功与否 appcontext_tearing_down _signals.signal(appcontext-tearing-down)# 请求上下文执行完毕后自动执行无论成功与否 appcontext_pushed _signals.signal(appcontext-pushed) #请求app上下文push时执行 appcontext_popped _signals.signal(appcontext-popped) #请求上下文pop时执行 message_flashed _signals.signal(message-flashed)#调用flask在其中添加数据时自动触发 SQLAlchemy中的 session和scoped_session 的区别 # Session 由于无法提供线程共享功能开发时要给每个线程都创建自己的session 打印sesion可知他是sqlalchemy.orm.session.Session的对象 # scoped_session 为每个线程都创建一个session实现支持线程安全 在整个程序运行的过程当中只存在唯一的一个session对象。 创建方式: 通过本地线程Threading.Local() # sessionscoped_session(Session) 创建唯一标识的方法(参考flask请求源码) SQLAlchemy如何执行原生SQL # 使用execute方法直接操作SQL语句(导入create_engin、sessionmaker) enginecreate_engine(mysql://root:*****127.0.0.1/database?charsetutf8) DB_Session sessionmaker(bindengine) session DB_Session() session.execute(alter table mytablename drop column mycolumn ;) ORM的实现原理 # ORM的实现基于一下三点 映射类描述数据库表结构 映射文件指定数据库表和映射类之间的关系 数据库配置文件指定与数据库连接时需要的连接信息(数据库、登录用户名、密码or连接字符串) DBUtils模块的作用 # 数据库连接池 使用模式 1、为每个线程创建一个连接连接不可控需要控制线程数 2、创建指定数量的连接在连接池当线程访问的时候去取不够了线程排队直到有人释放(推荐) --------------------------------------------------------------------------- 两种写法 1、用静态方法装饰器通过直接执行类的方法来连接使用数据库 2、通过实例化对象通过对象来调用方法执行语句 https://www.cnblogs.com/ArmoredTitan/p/Flask.html 以下SQLAlchemy的字段是否正确如果不正确请更正
from datetime import datetime
from sqlalchemy.ext.declarative
import declarative_base
from sqlalchemy import Column, Integer, String, DateTimeBase declarative_base()
class UserInfo(Base):__tablename__ userinfo id Column(Integer, primary_keyTrue, autoincrementTrue)name Column(String(64), uniqueTrue)
ctime Column(DateTime, defaultdatetime.now())
-----------------------------------------------------------------------
不正确Ctime字段中参数应为’defaultdatetime.now’now 后面不应该加括号加了的话字段不会实时更新。 SQLAchemy中如何为表设置引擎和字符编码 1. 设置引擎编码方式为utf8。 engine create_engine(mysqlpymysql://root:123456127.0.0.1:3306/sqldb01?charsetutf8) 2. 设置数据库表编码方式为utf8 class UserType(Base): __tablename__ usertype id Column(Integer, primary_keyTrue) caption Column(String(50), default管理员) # 添加配置设置编码 __table_args__ { mysql_charset:utf8 } 这样生成的SQL语句就自动设置数据表编码为utf8了,__table_args__还可设置存储引擎、外键约束等等信息。 SQLAchemy中如何设置联合唯一索引 通过UniqueConstraint字段来设置联合唯一索引 __table_args(UniqueConstraint(h_id,username,name_h_username_uc)) #h_id和username组成联合唯一约束 Tornado
简述Tornado框架的特点。 异步非阻塞websocket 简述Tornado框架中Future对象的作用
# 实现异步非阻塞
视图函数yield一个futrue对象futrue对象默认self._done False 请求未完成self._result None 请求完成后返回值用于传递给回调函数使用。tornado就会一直去检测futrue对象的_done是否已经变成True。如果IO请求执行完毕自动会调用future的set_result方法self._result resultself._done True
参考http://www.cnblogs.com/wupeiqi/p/6536518.html自定义异步非阻塞web框架
Tornado框架中如何编写WebSocket程序
Tornado在websocket模块中提供了一个WebSocketHandler类。
这个类提供了和已连接的客户端通信的WebSocket事件和方法的钩子。
当一个新的WebSocket连接打开时open方法被调用
而on_message和on_close方法分别在连接、接收到新的消息和客户端关闭时被调用。此外WebSocketHandler类还提供了write_message方法用于向客户端发送消息close方法用于关闭连接。
Tornado中静态文件是如何处理的
如 link href{{static_url(commons.css)}} relstylesheet /
# settings.py
settings {static_path: os.path.join(os.path.dirname(__file__), static),# 指定了静态文件的位置在当前目录中的static目录下cookie_secret: 61oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo,login_url: /login,xsrf_cookies: True,
}经上面配置后
static_url()自动去配置的路径下找commons.css文件
Tornado操作MySQL使用的模块
torndb
torndb是基于mysqldb的再封装所以使用时要先安装myqldb Tornado操作redis使用的模块
tornado-redis 简述Tornado框架的适用场景
web聊天室在线投票 git
git常见命令作用
# git init初始化当前所在的文件夹可以被管理且以后版本相关的数据都会存储到.git文件中
# git status查看当前文件夹以及子目录中文件是否发生变化内容修改/新增文件/删除已经变化的文件会变成红色已经add的文件会变成绿色
# git add .给发生变化的文件贴上一个标签或 将发生变化的文件放到某个地方只写一个句点符就代表把git status中红色的文件全部打上标签
# git commit -m新增用户登录认证功能以及xxx功能将“绿色”文件添加到版本中
# git log查看所有版本提交记录可以获取版本号
# git reset --hard 版本号 将最新的版本回退到更早的版本
# git reflog 回退到之前版本后悔了再更新到最新或者最新之前的版本
# git reset --hard 版本 回退
简述以下git中stash命令作用以及相关其他命令。
git stash将当前工作区所有修改过的内容存储到“某个地方”将工作区还原到当前版本未修改过的状态
git stash list查看“某个地方”存储的所有记录
git stash clear清空“某个地方”
git stash pop将第一个记录从“某个地方”重新拿到工作区可能有冲突
git stash apply编号, 将指定编号记录从“某个地方”重新拿到工作区可能有冲突
git stash drop编号删除指定编号的记录
git 中 merge 和 rebase命令 的区别。
merge
会将不同分支的提交合并成一个新的节点之前的提交分开显示
注重历史信息、可以看出每个分支信息基于时间点,遇到冲突,手动解决,再次提交
rebase
将两个分支的提交结果融合成线性不会产生新的节点;
注重开发过程遇到冲突手动解决继续操作
公司如何基于git做的协同开发
1、你们公司的代码review分支怎么做谁来做
答组长创建review分支我们小功能开发完之后合并到review分支交给老大小组长来看
1.1、你组长不开发代码吗他开发代码但是它只开发核心的东西任务比较少。或者抽出时间我们一起做这个事情
2、你们公司协同开发是怎么协同开发的
每个人都有自己的分支阶段性代码完成之后合并到review然后交给老大看
--------------------------------------------------------------------------
# 大致工作流程
公司下载代码git clone https://gitee.com/wupeiqi/xianglong.git或创建目录 cd 目录 git init git remote add origin https://gitee.com/wupeiqi/xianglong.gitgit 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
如何基于git实现代码review
https://blog.csdn.net/june_y/article/details/50817993 git如何实现v1.0 、v2.0 等版本的管理
在命令行中使用“git tag –a tagname –m “comment”可以快速创建一个标签。
需要注意命令行创建的标签只存在本地Git库中还需要使用Git push –tags指令发布到服务器的Git库中
github和gitlab的区别
1、gitHub是一个面向开源及私有软件项目的托管平台
(创建私有的话需要购买最低级的付费为每月7刀支持5个私有项目)
2、gitlab是公司自己搭建的项目托管平台 如何为github上牛逼的开源项目贡献代码
1、fork需要协作项目
2、克隆/关联fork的项目到本地
3、新建分支branch并检出checkout新分支
4、在新分支上完成代码开发
5、开发完成后将你的代码合并到master分支
6、添加原作者的仓库地址作为一个新的仓库地址
7、合并原作者的master分支到你自己的master分支,用于和作者仓库代码同步
8、push你的本地仓库到GitHub
9、在Github上提交 pull requests
10、等待管理员你需要贡献的开源项目管理员处理
git中 .gitignore文件的作用
一般来说每个Git项目中都需要一个“.gitignore”文件
这个文件的作用就是告诉Git哪些文件不需要添加到版本管理中。实际项目中很多文件都是不需要版本管理的比如Python的.pyc文件和一些包含密码的配置文件等等。 敏捷开发
什么是敏捷开发
敏捷开发是一种以人为核心、迭代、循序渐进的开发方式。它并不是一门技术而是一种开发方式也就是一种软件开发的流程。
它会指导我们用规定的环节去一步一步完成项目的开发。
因为它采用的是迭代式开发所以这种开发方式的主要驱动核心是人 简述 jenkins 工具的作用?
Jenkins是一个可扩展的持续集成引擎。主要用于持续、自动地构建/测试软件项目。监控一些定时执行的任务。 公司如何实现代码发布
nginxuwsgidjango 简述 RabbitMQ、Kafka、ZeroMQ的区别
https://blog.csdn.net/zhailihua/article/details/7899006 RabbitMQ如何在消费者获取任务后未处理完前就挂掉时保证数据不丢失
为了预防消息丢失rabbitmq提供了ack
即工作进程在收到消息并处理后发送ack给rabbitmq告知rabbitmq这时候可以把该消息从队列中删除了。
如果工作进程挂掉 了rabbitmq没有收到ack那么会把该消息 重新分发给其他工作进程。
不需要设置timeout即使该任务需要很长时间也可以处理。ack默认是开启的工作进程显示指定了no_ackTrue
RabbitMQ如何对消息做持久化
1、创建队列和发送消息时将设置durableTure如果在接收到消息还没有存储时消息也有可能丢失就必须配置publisher confirmchannel.queue_declare(queuetask_queue, durableTrue)2、返回一个ack进程收到消息并处理完任务后发给rabbitmq一个ack表示任务已经完成可以删除该任务3、镜像队列将queue镜像到cluster中其他的节点之上。
在该实现下如果集群中的一个节点失效了queue能自动地切换到镜像中的另一个节点以保证服务的可用性
RabbitMQ如何控制消息被消费的顺序
默认消息队列里的数据是按照顺序被消费者拿走
例如消费者1 去队列中获取奇数序列的任务消费者2去队列中获取偶数序列的任务。channel.basic_qos(prefetch_count1)
表示谁来谁取不再按照奇偶数排列同时也保证了公平的消费分发 以下RabbitMQ的exchange type分别代表什么意思如fanout、direct、topic。
amqp协议中的核心思想就是生产者和消费者隔离生产者从不直接将消息发送给队列。
生产者通常不知道是否一个消息会被发送到队列中只是将消息发送到一个交换机。
先由Exchange来接收然后Exchange按照特定的策略转发到Queue进行存储。
同理消费者也是如此。Exchange 就类似于一个交换机转发各个消息分发到相应的队列中。
--------------------------------------------------
typefanout 类似发布者订阅者模式会为每一个订阅者创建一个队列而发布者发布消息时会将消息放置在所有相关队列中
typedirect 队列绑定关键字发送者将数据根据关键字发送到消息exchangeexchange根据 关键字 判定应该将数据发送至指定队列。
typetopic 队列绑定几个模糊的关键字之后发送者将数据发送到exchangeexchange将传入”路由值“和 ”关键字“进行匹配匹配成功
则将数据发送到指定队列。
---------------------------------------------------
发送者路由值 队列中
old.boy.python old.* -- 不匹配 *表示匹配一个
old.boy.python old.# -- 匹配 #表示匹配0个或多个
celery 简述 celery 是什么以及应用场景
# Celery是由Python开发的一个简单、灵活、可靠的处理大量任务的分发系统
# 它不仅支持实时处理也支持任务调度。
# http://www.cnblogs.com/wupeiqi/articles/8796552.html 简述celery运行机制。 celery如何实现定时任务
# celery实现定时任务
启用Celery的定时任务需要设置CELERYBEAT_SCHEDULE 。
CELERYBEAT_SCHEDULEdjcelery.schedulers.DatabaseScheduler#定时任务
创建定时任务
# 通过配置CELERYBEAT_SCHEDULE
#每30秒调用task.add
from datetime import timedelta
CELERYBEAT_SCHEDULE {add-every-30-seconds: {task: tasks.add,schedule: timedelta(seconds30),args: (16, 16)},
}
简述 celery多任务结构目录
pro_cel├── celery_tasks # celery相关文件夹│ ├── celery.py # celery连接和配置相关文件│ └── tasks.py # 所有任务函数├── check_result.py # 检查结果└── send_task.py # 触发任务
celery中装饰器 app.task 和 shared_task的区别
# 一般情况使用的是从celeryapp中引入的app作为的装饰器app.task
# django那种在app中定义的task则需要使用shared_task 简述 requests模块的作用及基本使用
# 作用
使用requests可以模拟浏览器的请求
# 常用参数url、headers、cookies、datajson、params、proxy
# 常用返回值contentiter_contenttext encodingutf-8cookie.get_dict()简述 beautifulsoup模块的作用及基本使用
# BeautifulSoup
用于从HTML或XML文件中提取、过滤想要的数据形式
#常用方法
解析html.parser 或者 lxml需要下载安装 find、find_all、text、attrs、get 简述 seleninu模块的作用及基本使用?
Selenium是一个用于Web应用程序测试的工具
他的测试直接运行在浏览器上模拟真实用户按照代码做出点击、输入、打开等操作爬虫中使用他是为了解决requests无法解决javascript动态问题scrapy
scrapy框架中各组件的工作流程
#1、生成初始的Requests来爬取第一个URLS并且标识一个回调函数
第一个请求定义在start_requests()方法内默认从start_urls列表中获得url地址来生成Request请求
默认的回调函数是parse方法。回调函数在下载完成返回response时自动触发
#2、在回调函数中解析response并且返回值
返回值可以4种a、包含解析数据的字典b、Item对象c、新的Request对象新的Requests也需要指定一个回调函数d、或者是可迭代对象包含Items或Request
#3、在回调函数中解析页面内容
通常使用Scrapy自带的Selectors但很明显你也可以使用Beutifulsouplxml或其他你爱用啥用啥。
#4、最后针对返回的Items对象将会被持久化到数据库通过Item Pipeline组件存到数据库或者导出到不同的文件通过Feed exports
http://www.cnblogs.com/wupeiqi/articles/6229292.html
在scrapy框架中如何设置代理两种方法
方式一内置添加代理功能
# -*- coding: utf-8 -*-
import os
import scrapy
from scrapy.http import Requestclass ChoutiSpider(scrapy.Spider):name choutiallowed_domains [chouti.com]start_urls [https://dig.chouti.com/]def start_requests(self):os.environ[HTTP_PROXY] http://192.168.11.11for url in self.start_urls:yield Request(urlurl,callbackself.parse)def parse(self, response):print(response)方式二自定义下载中间件
import random
import base64
import six
def to_bytes(text, encodingNone, errorsstrict):Return the binary representation of text. If textis already a bytes object, return it as-is.if isinstance(text, bytes):return textif not isinstance(text, six.string_types):raise TypeError(to_bytes must receive a unicode, str or bytes object, got %s % type(text).__name__)if encoding is None:encoding utf-8return text.encode(encoding, errors)class MyProxyDownloaderMiddleware(object):def process_request(self, request, spider):proxy_list [{ip_port: 111.11.228.75:80, user_pass: xxx:123},{ip_port: 120.198.243.22:80, user_pass: },{ip_port: 111.8.60.9:8123, user_pass: },{ip_port: 101.71.27.120:80, user_pass: },{ip_port: 122.96.59.104:80, user_pass: },{ip_port: 122.224.249.122:8088, user_pass: },]proxy random.choice(proxy_list)if proxy[user_pass] is not None:request.meta[proxy] to_bytes(http://%s % proxy[ip_port])encoded_user_pass base64.encodestring(to_bytes(proxy[user_pass]))request.headers[Proxy-Authorization] to_bytes(Basic encoded_user_pass)else:request.meta[proxy] to_bytes(http://%s % proxy[ip_port])配置DOWNLOADER_MIDDLEWARES {# xiaohan.middlewares.MyProxyDownloaderMiddleware: 543,}
scrapy框架中如何实现大文件的下载
from twisted.web.client import Agent, getPage, ResponseDone, PotentialDataLoss
from twisted.internet import defer, reactor, protocol
from twisted.web._newclient import Response
from io import BytesIOclass _ResponseReader(protocol.Protocol):def __init__(self, finished, txresponse, file_name):self._finished finishedself._txresponse txresponseself._bytes_received 0self.f open(file_name, modewb)def dataReceived(self, bodyBytes):self._bytes_received len(bodyBytes)# 一点一点的下载self.f.write(bodyBytes)self.f.flush()def connectionLost(self, reason):if self._finished.called:returnif reason.check(ResponseDone):# 下载完成self._finished.callback((self._txresponse, success))elif reason.check(PotentialDataLoss):# 下载部分self._finished.callback((self._txresponse, partial))else:# 下载异常self._finished.errback(reason)self.f.close()
scrapy中如何实现限速
http://scrapy-chs.readthedocs.io/zh_CN/1.0/topics/autothrottle.html scrapy中如何实现暂停爬虫
# 有些情况下例如爬取大的站点我们希望能暂停爬取之后再恢复运行。
# Scrapy通过如下工具支持这个功能:
一个把调度请求保存在磁盘的调度器
一个把访问请求保存在磁盘的副本过滤器[duplicates filter]
一个能持续保持爬虫状态(键/值对)的扩展
Job 路径
要启用持久化支持你只需要通过 JOBDIR 设置 job directory 选项。
这个路径将会存储所有的请求数据来保持一个单独任务的状态(例如一次spider爬取(a spider run))。
必须要注意的是这个目录不允许被不同的spider 共享甚至是同一个spider的不同jobs/runs也不行。
也就是说这个目录就是存储一个 单独 job的状态信息。
scrapy中如何进行自定制命令
在spiders同级创建任意目录如commands
在其中创建crawlall.py文件此处文件名就是自定义的命令
from scrapy.commands import ScrapyCommandfrom scrapy.utils.project import get_project_settingsclass Command(ScrapyCommand):requires_project Truedef syntax(self):return [options]def short_desc(self):return Runs all of the spidersdef run(self, args, opts):spider_list self.crawler_process.spiders.list()for name in spider_list:self.crawler_process.crawl(name, **opts.__dict__)self.crawler_process.start()
在settings.py中添加配置COMMANDS_MODULE 项目名称.目录名称
在项目目录执行命令scrapy crawlall
scrapy中如何实现的记录爬虫的深度
DepthMiddleware是一个用于追踪每个Request在被爬取的网站的深度的中间件。
其可以用来限制爬取深度的最大深度或类似的事情。
DepthMiddleware可以通过下列设置进行配置(更多内容请参考设置文档):DEPTH_LIMIT:爬取所允许的最大深度如果为0则没有限制。
DEPTH_STATS:是否收集爬取状态。
DEPTH_PRIORITY:是否根据其深度对requet安排优先
scrapy中的pipelines工作原理
Scrapy 提供了 pipeline 模块来执行保存数据的操作。
在创建的 Scrapy 项目中自动创建了一个 pipeline.py 文件同时创建了一个默认的 Pipeline 类。
我们可以根据需要自定义 Pipeline 类然后在 settings.py 文件中进行配置即可 scrapy的pipelines如何丢弃一个item对象 通过raise DropItem()方法 简述scrapy中爬虫中间件和下载中间件的作用1
http://www.cnblogs.com/wupeiqi/articles/6229292.html scrapy-redis组件的作用
实现了分布式爬虫url去重、调度器、数据持久化
scheduler调度器
dupefilterURL去重规则被调度器使用
pipeline数据持久化 scrapy-redis组件中如何实现的任务的去重 a. 内部进行配置连接Redis b.去重规则通过redis的集合完成集合的Key为 key defaults.DUPEFILTER_KEY % {timestamp: int(time.time())} 默认配置 DUPEFILTER_KEY dupefilter:%(timestamp)s c.去重规则中将url转换成唯一标示然后在redis中检查是否已经在集合中存在 from scrapy.utils import request from scrapy.http import Request req Request(urlhttp://www.cnblogs.com/wupeiqi.html) result request.request_fingerprint(req) print(result) # 8ea4fd67887449313ccc12e5b6b92510cc53675c scrapy和scrapy-redis的去重规则源码
1. scrapy中去重规则是如何实现
class RFPDupeFilter(BaseDupeFilter):Request Fingerprint duplicates filterdef __init__(self, pathNone, debugFalse):self.fingerprints set()classmethoddef from_settings(cls, settings):debug settings.getbool(DUPEFILTER_DEBUG)return cls(job_dir(settings), debug)def request_seen(self, request):# 将request对象转换成唯一标识。fp self.request_fingerprint(request)# 判断在集合中是否存在如果存在则返回True表示已经访问过。if fp in self.fingerprints:return True# 之前未访问过将url添加到访问记录中。self.fingerprints.add(fp)def request_fingerprint(self, request):return request_fingerprint(request)2. scrapy-redis中去重规则是如何实现
class RFPDupeFilter(BaseDupeFilter):Redis-based request duplicates filter.This class can also be used with default Scrapys scheduler.logger loggerdef __init__(self, server, key, debugFalse):# self.server redis连接self.server server# self.key dupefilter:123912873234self.key keyclassmethoddef from_settings(cls, settings):# 读取配置连接redisserver get_redis_from_settings(settings)# key dupefilter:123912873234key defaults.DUPEFILTER_KEY % {timestamp: int(time.time())}debug settings.getbool(DUPEFILTER_DEBUG)return cls(server, keykey, debugdebug)classmethoddef from_crawler(cls, crawler):return cls.from_settings(crawler.settings)def request_seen(self, request):fp self.request_fingerprint(request)# This returns the number of values added, zero if already exists.# self.serverredis连接# 添加到redis集合中1添加工程0已经存在added self.server.sadd(self.key, fp)return added 0def request_fingerprint(self, request):return request_fingerprint(request)def close(self, reason):self.clear()def clear(self):Clears fingerprints data.self.server.delete(self.key)
scrapy-redis的调度器如何实现任务的深度优先和广度优先.... 简述 vitualenv 及应用场景?
vitualenv是一个独立的python虚拟环境
如当前项目依赖的是一个版本但是另一个项目依赖的是另一个版本这样就会造成依赖冲突而virtualenv就是解决这种情况的virtualenv通过创建一个虚拟化的python运行环境将我们所需的依赖安装进去的不同项目之间相互不干扰 简述 pipreqs 及应用场景
可以通过对项目目录扫描自动发现使用了那些类库并且自动生成依赖清单。pipreqs ./ 生成requirements.txt 在Python中使用过什么代码检查工具
1PyFlakes静态检查Python代码逻辑错误的工具。
2Pep8 静态检查PEP8编码风格的工具。
3NedBatchelder’s McCabe script静态分析Python代码复杂度的工具。
Python代码分析工具PyChecker、Pylint 简述 saltstack、ansible、fabric、puppet工具的作用 B Tree和B Tree的区别
1.B树中同一键值不会出现多次并且有可能出现在叶结点也有可能出现在非叶结点中。而B树的键一定会出现在叶结点中并有可能在非叶结点中重复出现以维持B树的平衡。
2.因为B树键位置不定且在整个树结构中只出现一次 请列举常见排序并通过代码实现任意三种。
算法基础之排序 请列举常见查找并通过代码实现任意三种。 无序查找、二分查找、插值查找 请列举你熟悉的设计模式
工厂模式/单例模式等 有没有刷过leetcode leetcode是个题库里面有多很编程题目可以在线编译运行。 https://leetcode-cn.com/problemset/all/ 列举熟悉的的Linux命令。 公司线上服务器是什么系统 linux/centos7 解释 PV、UV 的含义 PV访问量Page View即页面访问量每打开一次页面PV计数1刷新页面也是。 UV访问数Unique Visitor指独立访客访问数一台电脑终端为一个访客。 解释 QPS的含义 QPS(Query Per Second)每秒查询率是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准 uwsgi和wsgi的区别
wsgi是一种通用的接口标准或者接口协议实现了python web程序与服务器之间交互的通用性。uwsgi:同WSGI一样是一种通信协议
uwsgi协议是一个uWSGI服务器自有的协议它用于定义传输信息的类型
uWSGI是实现了uwsgi和WSGI两种协议的Web服务器负责响应python的web请求。 supervisor的作用
# Supervisor
是一款基于Python的进程管理工具可以很方便的管理服务器上部署的应用程序。
是C/S模型的程序其服务端是supervisord服务,客户端是supervisorctl命令# 主要功能:
1 启动、重启、关闭包括但不限于python进程。
2 查看进程的运行状态。
3 批量维护多个进程。
什么是反向代理
正向代理代理客户端(客户端找哟个代理去访问服务器服务器不知道你的真实IP)
反向代理代理服务器(服务器找一个代理给你响应你不知道服务器的真实IP) 简述SSH的整个过程。
SSH 为 Secure Shell 的缩写是建立在应用层基础上的安全协议。
SSH 是目前较可靠为远程登录会话和其他网络服务提供的安全性协议。
利用 SSH 协议可以有效防止远程管理过程中的信息泄露问题。 有问题都去那些找解决方案
起初是百度发现搜到的答案不精准净广告
转战谷歌但墙了捣鼓怎么FQ还会去知乎、stackoverfloow、必应、思否(segmentfault) 是否有关注什么技术类的公众号
python之禅(主要专注Python相关知识作者刘志军)
码农翻身(主要是Java的但不光是java涵盖面很广作者刘欣)
实验楼(在线练项目)
and so on 最近在研究什么新技术
Numpy
pandas(金融量化分析、聚宽)
百度AI
图灵API
智能玩具 是否了解过领域驱动模型
Domain-Driven Design二进制与十进制之间的转换
1、十进制 与 二进制之间的转换 (1)、十进制转换为二进制分为整数部分和小数部分 整数部分
方法除2取余法即每次将整数部分除以2余数为该位权上的数而商继续除以2余数又为上一个位权上的数。
这个步骤一直持续下去直到商为0为止最后读数时候从最后一个余数读起一直到最前面的一个余数。下面举例例将十进制的168转换为二进制
得出结果 将十进制的168转换为二进制101010002
168 / 2 84 -- 0
84 / 2 42 -- 0
42 / 2 21 -- 0
21 / 2 10 -- 1
10 / 2 5 -- 05 / 2 2 -- 1
2 / 2 1 -- 0
1 / 2 0 -- 1
二进制从后往前读 10101000
小数部分
方法乘2取整法即将小数部分乘以2然后取整数部分剩下的小数部分继续乘以2然后取整数部分
剩下的小数部分又乘以2一直取到小数部分为零为止。如果永远不能为零就同十进制数的四舍五入一样
按照要求保留多少位小数时就根据后面一位是0还是1取舍如果是零舍掉如果是1向入一位。
换句话说就是0舍1入。读数要从前面的整数读到后面的整数
二进制转换为十进制 (不分整数和小数部分)
方法按权相加法即将二进制每位上的数乘以权然后相加之和即是十进制数。
例将二进制数101.101转换为十进制数。
得出结果101.1012(5.625)10
在做二进制转换成十进制需要注意的是
1要知道二进制每位的权值
2要能求出每位的值 101.101 转换为十进制
整数部分2^2 2^0 5
小数部分2^(-1) 2^(-3) 1/2 1/8 0.5 0.125 0.625
十进制 2^2 2^0 2^(-1) 2^(-3) 5.625