1.python中的lambda是什么意思,可以举例
1 匿名函数 2 a = lambda x:x+1 3 print(a(1))
2.请写出以下代码执行的结果
1 class Parent(object): 2 x = 1 3 class Child1(Parent): 4 pass 5 class Child2(Parent): 6 pass 7 print(Parent.x, Child1.x, Child2.x) 8 Child1.x = 2 9 print(Parent.x, Child1.x, Child2.x) 10 parent.x = 3 11 print(Parent.x, Child1.x, Child2.x) 12 13 14 111 121 323
3.写出A0-A2的输出结果,并解释原因
1 A0 = [i for i in range(10) if i % 2 == 0] 2 A1 = {i: i+2 for i in A0} 3 A2 = sorted(A0, reverse=True) 4 5 6 A0 = [0, 2, 4, 6, 8] 7 A1 = {0:2,2:4,4:6,6:8,8:10} 8 A2 = [8,6,4,2,0]
4.写出下列程序的输出
1 a = [2, 5] 2 b = [a] * 4 3 b = tuple(b) 4 b[0][0] = 4 5 print(b) 6 print(a) 7 8 9 ([4,5],[4,5],[4,5],[4,5]) 10 [4,5]运算符来操作列表时浅拷贝,只拷贝最外边一层,内层还是原来的引用。
5.写出下边代码打印的内容
1 def decorate(func): 2 print("func") 3 def inner(**kwargs): 4 print("123456") 5 ret = func(**kwargs) 6 print("789") 7 return ret 8 print('inner') 9 return inner 10 @decorate 11 @decorate 12 def func(**kwargs): 13 return kwargs 14 15 16 17 func 18 inner 19 func 20 inner
6.如何用redis实现分布式锁
1 import redis 2 redis_conn = redis.StrictRedis(host="127.0.0.1", port=6379) 3 try: 4 lock_num = lock_num = redis_conn.incr("lock", 1) 5 if lock_num == 1: 6 # 执行操作,拼接response 7 response 8 else: 9 return 404 10 finally: 11 redis_conn.incr("lock", -1) 12 return response 13 14 15 原理:redis是单线程的 16 目的,在分布式应用中,将并发变为串行,减少数据库压力,提升安全性能
7.redis中的数据类型有哪些
1 string list hash set zset
8.使用生成器写一个到n的斐波那契数列def feibo(n):
1 def feibo(n): 2 a, b = 1, 0 3 for _ in range(n): 4 a, b = b, a + b 5 yield b
9.简述Python的内存管理机制
小整数池 intern机制 引用计数为主,分代回收为辅
10.mysql事务隔离级别有哪些,分别会出现哪些问题,默认的事务隔离级别是什么
默认事务隔离级别是可重复读
11.简述对进程和线程的认识,并说说他们的区别
12.使用装饰器实现一个单例
1 def wrap(cls): 2 instance = {} 3 def inner(*args, **kwargs): 4 if cls not in instance: 5 instance[cls] = cls(*args, **kwargs) 6 return instance[cls] 7 return inner 8 @wrap 9 class A(object): 10 def __init__(self, name): 11 self.name = name
13.HTTP常用状态码有哪些
200 - 请求成功
201 - 已创建。成功请求并创建了新的资源
301 - 资源(网页等)被永久转移到其它URL
302 - 临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI
404 - 请求的资源(网页等)不存在
403 - 服务器理解请求客户端的请求,但是拒绝执行此请求
500 - 内部服务器错误
505 - 服务器不支持请求的HTTP协议的版本,无法完成处理
14.post和get的区别是什么
15.对称加密和非对称加密是什么
对称加密
非对称性加密
一对公钥和一对私钥
用户和银行分别有自己的公钥
用户使用银行给的公钥对原文进行加密
银行可以用自己的私钥对密文进行解密
非对称加密速度很慢。
现实中加密方式的使用
用户使用对称加密,通过秘钥对原文进行加密
将秘钥使用非对称加密方式加密然后传给银行
银行使用秘钥解密
非对称性加密
一对公钥和一对私钥
用户和银行分别有自己的公钥
用户使用银行给的公钥对原文进行加密
银行可以用自己的私钥对密文进行解密
非对称加密速度很慢。
现实中加密方式的使用
用户使用对称加密,通过秘钥对原文进行加密
将秘钥使用非对称加密方式加密然后传给银行
银行使用秘钥解密
16.Python线程安全模块时什么,怎么使用
互斥锁
1 import threading 2 # 定义全局变量 3 g_num = 0 4 # 创建全局互斥锁 5 lock = threading.Lock() 6 # 循环一次给全局变量加1 7 def sum_num1(): 8 # 上锁 9 lock.acquire() 10 for i in range(1000000): 11 global g_num 12 g_num += 1 13 print("sum1:", g_num) 14 # 释放锁 15 lock.release() 16 # 循环一次给全局变量加1 17 def sum_num2(): 18 # 上锁 19 lock.acquire() 20 for i in range(1000000): 21 global g_num 22 g_num += 1 23 print("sum2:", g_num) 24 # 释放锁 25 lock.release() 26 if __name__ == '__main__': 27 # 创建两个线程 28 first_thread = threading.Thread(target=sum_num1) 29 second_thread = threading.Thread(target=sum_num2) 30 # 启动线程 31 first_thread.start() 32 second_thread.start()
17.写出代码的结果
1 def f(x, l=[]): 2 for i in range(x): 3 l.append(i*i) 4 print(l) 5 f(2) 6 f(3, [3,2,1]) 7 f(3) 8 9 10 11 [0, 1] [3,2,1,0,1,4] [0,1,0,1,4]
18.描述Python GIL的概念,以及它对python多线程的影响
1.全局解释锁。每个线程在执行的过程都需要先获取GIL,保证同一时刻只有一个线程可以执行代码 2.python语言和GIL并没有关系,是由于历史原因在Cpython解释器中难以移除GIL。 3.线程释放GIL锁的情况:在IO操作等可能引起阻塞的系统调用之前,可以暂时释放GIL,cpu会切换执行其他线程,
但在执行完毕后,必须重新获取GIL。python3使用计时器(执行时间达到阈值后,当前线程释放GIL) 如何解决GIL问题 1.换解释器,默认是Cpython,可以换成jpython 2.使用其他语言写其他线程。 3.进程+协程 结论: 1.Python使用多进程可充分利用多核cpu的资源 2.多线程爬取比单线程性能有提升,因为遇到IO阻塞会自动释放GIL锁。 为什么有了GIL锁多线程使用时还要使用互斥锁: GIL锁不能保证一个线程是否执行完成,互斥锁可以保证一个线程执行完成之后解锁,让别的程序再加锁执行。
19.一行实现对列表a中的下标为偶数的元素进行加3后求和
1 sum([i+3 for i in a[1::2]])
20.对比说明jwt机制和cookie session机制的优缺点
cookie Session:
优点:
简单方便,通用性好,可以存放敏感信息,可以灵活控制用户的状态
缺点:
每个用户经过我们的应用认证之后,我们的应用都要在服务端做一次记录,以方便用户下次请求的鉴别,通常而言
session都是保存在内存中,而随着认证用户的增多,服务端的开销会明显增大。
扩展性: 用户认证之后,服务端做认证记录,如果认证的记录被保存在内存中的话,这意味着用户下次请求还必须
要请求在这台服务器上,这样才能拿到授权的资源,这样在分布式的应用上,相应的限制了负载均衡器的能力。
这也意味着限制了应用的扩展能力。
CSRF: 因为是基于cookie来进行用户识别的, cookie如果被截获,用户就会很容易受到跨站请求伪造的攻击。
jwt机制:
优点:
不需要在服务端去保留用户的认证信息或者会话信息,减少服务器开销
基于token认证机制的应用不需要去考虑用户在哪一台服务器登录了,这就为应用的扩展提供了便利。
缺点:
已颁布分令牌无法主动让其失效(可以通过后端实现黑名单来实现,但其实黑名单的原理和cookie session其实
是一样的)
21.谈谈你对drf的认识快速开发符合restful风格api接口的django扩展。
主要的核心组件:
序列化器、视图、视图集,结合django自带的model和url
使用drf其实已经不再符合django的mvt开发模式了
主要的功能:
分页、限流、权限、认证等
22.celery的工作流程是什么
celery架构由三个模块组成:消息中间件(message broker),任务执行单元(worker)和任务执行结果存储(
taskresult store)组成。
消息中间件(Broker): 消息中间人,是任务调度队列,是一个独立的服务,是一个生产者消费者模式,生产者把任务
放入队列中,消费者(worker)从任务队列中取出任务执行,任务的执行可以按照顺序依次执行也可以按照计划时间进行。
但是Broker本身不提供队列服务,所以要集成第三方队列,推荐使用RatbbitMQ或Redis.
任务执行单元(worker):即执行任务的程序,可以有多个并发。它实时监控消息队列,获取队列中调度的任务,并执
行它。
任务执行结果存储(task result store):由于任务的执行同主程序分开,如果主程序想获取任务执行的结果,
就必须通过中间件存储。同消息中间人一样,存储也可以使用RabbitMQ、Redis;另外,假如不需要保存执行的结果也
可以不配置这个模块。
23.Django中间件常用的5个方法
1 中间件:允许开发人员在请求之前或之后进行相应的处理。 2 3 1.10之前,Django中间件注册`MIDDLEWARE_CLASSES`: 4 process_request 5 process_view 6 process_response 7 process_template_response 8 process_exception 9 10 1.10及之后,Django中间件注册`MIDDLWARE`: 11 def simple_middleware(get_response): 12 # 一次性配置和初始化。 13 14 def middleware(request): 15 # 在调用视图(以及稍后的中间件)之前 16 # 要为每个请求执行代码。 17 18 response = get_response(request) 19 20 # 为每个请求/响应执行的代码 21 # 在调用视图之后 22 23 return response 24
25 return middleware
24.同步和异步有什么区别,Python如何实现异步同步:多个任务之间有先后顺序执行,一个执行完下个才能执行。
异步:多个任务之间没有先后顺序,可以同时执行有时候一个任务可能要在必要的时候获取另一个
同时执行的任务的结果,这个就叫回调!
阻塞:如果卡住了调用者,调用者不能继续往下执行,就是说调用者阻塞了。
非阻塞:如果不会卡住,可以继续执行,就是说非阻塞的。
同步异步相对于多任务而言,阻塞非阻塞相对于代码执行而言
答celery可以 asyncio可以了解一下
25.sql语句中使用limit遇到哪些问题,是如何解决的
日常分页SQL语句 select id,name,content from users order by id asc limit 100000,20 扫描100020行 如果记录了上次的最大ID select id,name,content from users where id>100073 order by id asc limit 20 扫描20行。
26.
所有信号都是 django.core.signals.Signal
的实例。 providing_args
是一个列表,由信号将提供给监听者的参数名称组成。
from django.core.signals import Signal # 1. 定义邮件发送信号 email_send = Signal(providing_args=['email'])
信号处理函数一般定义在定义在子应用下的signals.py
文件中。
# 2. 处理函数定义 def send_email(sender, **kwargs): """email_send信号处理函数""" # TODO: 可以在这里编写信号的处理代码 print('email_send信号处理函数被调用')
信号连接就是将信号和处理函数对应起来,信号连接一般是在子应用配置类的ready
方法中进行操作。
class TestAppConfig(object): # ... def ready(self): # 3. 信号连接 email_send.connect(send_email)
发出信号之后,信号连接的处理函数就会被调用。
email_send.send(sender='信号发出者', **kwargs)
27.django懒加载是什么?
答:懒加载:使用的时候再去加载。 1)数据库查询: all,filter, exclude, order_by:返回查询集QuerySet 惰性查询:只有使用查询集中数据的时候才会进行数据库的查询。 2)项目配置信息 from django.conf import settings
28.Django请求的生命周期
请求生命周期:客户端发起请求->服务器响应完整过程
29.列举Django的内置中间件
SessionMiddleWare:session中间件 获取:request.session['<key>'] 设置:request.session['<key>'] = '<value>' CsrfViewMiddleware:csrf保护中间件 每次请求之前,进行csrf的验证 process_view AuthenticationMiddleware:认证中间件 request.user:登录的用户对象 request.user:匿名用户类的对象
30.简述Django下(内建的)缓存机制
你的缓存配置是通过setting 文件的CACHES 配置来实现的: CACHES保存位置: 1. 服务器内存(默认) 2. 保存到数据库的表中 3. 保存到文件中 4. 保存到内存型数据库:redis Memcached 缓存级别: 1. 整站缓存 2. 视图缓存 3. 模板片段缓存 底层缓存API: from django.core.cache import cache cache.set('<key>', '<value>'): 设置缓存 cache.get('<key>'): 获取缓存 cache.delete('<key>'): 删除缓存