Django项目常见面试问题

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 Signals信号简单使用

1. 信号的定义
所有信号都是 django.core.signals.Signal的实例。 providing_args是一个列表,由信号将提供给监听者的参数名称组成。
from django.core.signals import Signal
# 1. 定义邮件发送信号
email_send = Signal(providing_args=['email'])
2. 信号处理函数的定义
信号处理函数一般定义在定义在子应用下的signals.py文件中。
# 2. 处理函数定义
def send_email(sender, **kwargs):
        """email_send信号处理函数"""
    # TODO: 可以在这里编写信号的处理代码
    print('email_send信号处理函数被调用')
3. 信号的连接
信号连接就是将信号和处理函数对应起来,信号连接一般是在子应用配置类的ready方法中进行操作。
class TestAppConfig(object):
        # ...
    def ready(self):
          # 3. 信号连接
        email_send.connect(send_email)
4. 信号发送
发出信号之后,信号连接的处理函数就会被调用。
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>'): 删除缓存

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2019-07-24 10:47  UiPath在线接单  阅读(1992)  评论(0编辑  收藏  举报