14. 启动 Django 服务的方法?
runserver 方法是调试 Django 时经常用到的运行方式,它使用 Django 自带的 WSGI Server 运 行,主要在测试和
开发中使用,并且 runserver 开启的方式也是单进程 。
15. 怎样测试 django 框架中的代码?
Django的单元测试使用python的unittest模块,这个模块使用基于类的方法来定义测试。类名为
django.test.TestCase ,继承于python的 unittest.TestCase 。
执行目录下所有的测试(所有的test*.py文件):运行测试的时候,测试程序会在所有以test开头的文件中查找所有的
test cases(inittest.TestCase的子类),自动建立测试集然后运行测试。
16. 有过部署经验?用的什么技术?可以满足多少压力?
1. 有部署经验,在阿里云服务器上部署的
2. 技术有:nginx + uwsgi 的方式来部署 Django 项目
3. 无标准答案(例:压力测试一两千)
17. Django 中哪里用到了线程?哪里用到了协程?哪里用到了进程?
Django 中耗时的任务用一个进程或者线程来执行,比如发邮件,使用 celery。
部署 django 项目的时候,配置文件中设置了进程和协程的相关配置。
18. django 关闭浏览器,怎样清除 cookies 和 session?
设置 Cookie
读取 Cookie
以键值对的格式写会话。 request.session['键']=值
根据键读取值。 request.session.get('键',默认值)
清除所有会话,在存储中删除值部分。 request.session.clear()
清除会话数据,在存储中删除会话的整条数据。 request.session.flush()
删除会话中的指定键及值,在存储中只删除某个键及对应的值。 del request.session['键']
设置会话的超时时间,如果没有指定过期时间则两个星期后过期。 如果 value 是一个整数,会话将在 value 秒没
有活动后过期。 如果 value 为 0,那么用户会话的 Cookie 将在用户的浏览器关闭时过期。 如果 value 为 None,
那么会话在两周后过期。 request.session.set_expiry(value)
Session 依赖于 Cookie,如果浏览器不能保存 cookie 那么 session 就失效了。因为它需要浏览 器的 cookie 值去
session 里做对比。session 就是用来在服务器端保存用户的会话状态。
cookie 可以有过期时间,这样浏览器就知道什么时候可以删除 cookie 了。 如果 cookie 没有设 置过期时间,当用
户关闭浏览器的时候,cookie 就自动过期了。可以改变 SESSION_EXPIRE_AT_BROWSER_CLOSE 的设置来控制
session 框架的这一行为。
SESSION_COOKIE_AGE:设置 cookie 在浏览器中存活的时间。
缺省情况下, SESSION_EXPIRE_AT_BROWSER_CLOSE 设置为 False ,这样,会话 cookie 可以在用户浏览器中
保 持有效达 SESSION_COOKIE_AGE 秒(缺省设置是两周,即 1,209,600 秒)如果你不想用户每次 打开浏览器
都必须重新登陆的话,用这个参数来帮你。如果 SESSION_EXPIRE_AT_BROWSER_CLOSE 设置为 True ,当浏览
器关闭时,Django 会使 cookie 失效。
19. 代码优化从哪些方面考虑?有什么想法?
1. 优化算法时间复杂度
算法的时间复杂度对程序的执行效率影响最大,在 Python 中可以通过选择合适的数据结构来优化 时间复杂
度,如 list 和 set 查找某一个元素的时间复杂度分别是 O(n)和 O(1)。不同的场景有不同的 优化方式,总得来
说,一般有分治,分支界限,贪心,动态规划等思想 。
def cookie_set(request):
response = HttpResponse("<h1>设置 Cookie,请查看响应报文头</h1>")
response.set_cookie('h1', 'hello django')
return response
读取 Cookie
def cookie_get(request):
response = HttpResponse("读取 Cookie,数据如下:<br>")
if request.COOKIES.has_key('h1'):
response.write('<h1>' + request.COOKIES['h1'] + '</h1>')
return response
以键值对的格式写会话。 request.session['键']=值
根据键读取值。 request.session.get('键',默认值)
清除所有会话,在存储中删除值部分。 request.session.clear()
清除会话数据,在存储中删除会话的整条数据。 request.session.flush()
删除会话中的指定键及值,在存储中只删除某个键及对应的值。 del request.session['键']
设置会话的超时时间,如果没有指定过期时间则两个星期后过期。 如果 value 是一个整数,会话将在 value 秒没
有活动后过期。 如果 value 为 0,那么用户会话的 Cookie 将在用户的浏览器关闭时过期。 如果 value 为 None,
那么会话在两周后过期。 request.session.set_expiry(value)
Session 依赖于 Cookie,如果浏览器不能保存 cookie 那么 session 就失效了。因为它需要浏览 器的 cookie 值去
session 里做对比。session 就是用来在服务器端保存用户的会话状态。
cookie 可以有过期时间,这样浏览器就知道什么时候可以删除 cookie 了。 如果 cookie 没有设 置过期时间,当用
户关闭浏览器的时候,cookie 就自动过期了。可以改变 SESSION_EXPIRE_AT_BROWSER_CLOSE 的设置来控制
session 框架的这一行为。
SESSION_COOKIE_AGE:设置 cookie 在浏览器中存活的时间。
缺省情况下, SESSION_EXPIRE_AT_BROWSER_CLOSE 设置为 False ,这样,会话 cookie 可以在用户浏览器中
保 持有效达 SESSION_COOKIE_AGE 秒(缺省设置是两周,即 1,209,600 秒)如果你不想用户每次 打开浏览器
都必须重新登陆的话,用这个参数来帮你。如果 SESSION_EXPIRE_AT_BROWSER_CLOSE 设置为 True ,当浏览
器关闭时,Django 会使 cookie 失效。
19. 代码优化从哪些方面考虑?有什么想法?
1. 优化算法时间复杂度
算法的时间复杂度对程序的执行效率影响最大,在 Python 中可以通过选择合适的数据结构来优化 时间复杂
度,如 list 和 set 查找某一个元素的时间复杂度分别是 O(n)和 O(1)。不同的场景有不同的 优化方式,总得来
说,一般有分治,分支界限,贪心,动态规划等思想 。
2. 减少冗余数据
如用上三角或下三角的方式去保存一个大的对称矩阵。在0元素占大多数的矩阵里使用稀疏矩阵表示。
3. 合理使用copy与deepcopy
对于dict和list等数据结构的对象,直接赋值使用的是引用的方式。而有些情况下需要复制整个对象,这时可
以使用copy包里的copy和deepcopy,这两个函数的不同之处在于后者是递归复制的。效率也不一样:(以下
程序在ipython中运行)
4. 使用dict或set查找元素
python dict和set都是使用hash表来实现(类似c++11标准库中unordered_map),查找元素的时间复杂度是
O(1)
5. 合理使用生成器(generator)和yield
使用 () 得到的是一个generator对象,所需要的内存空间与列表的大小无关,所以效率会高一些。在具体应
用上,比如set(i for i in range(100000))会比set([i for i in range(100000)])快。
对于内存不是非常大的list,可以直接返回一个list,但是可读性 yield 更佳(人个喜好)。
6. 优化循环
循环之外能做的事不要放在循环内
7. 优化包含多个判断表达式的顺序
对于and,应该把满足条件少的放在前面,对于or,把满足条件多的放在前面
8. 使用join合并迭代器中的字符串
join 对于累加的方式,有大约5倍的提升。
9. 不借助中间变量交换两个变量的值
使用 a,b=b,a 而不是 c=a;a=b;b=c; 来交换a,b的值,可以快1倍以上。
10. 使用 if is
使用 if is True 比 if == True 将近快一倍。
11. 并行编程
因为GIL的存在,Python很难充分利用多核CPU的优势。但是,可以通过内置的模块multiprocessing实现下
面几种并行模式:
多进程:对于CPU密集型的程序,可以使用multiprocessing的Process,Pool等封装好的类,通过多进程
的方式实现并行计算。但是因为进程中的通信成本比较大,对于进程之间需要大量数据交互的程序效率
未必有大的提高。
多线程:对于IO密集型的程序,multiprocessing.dummy模块使用multiprocessing的接口封装
threading,使得多线程编程也变得非常轻松(比如可以使用Pool的map接口,简洁高效)。
分布式:multiprocessing中的Managers类提供了可以在不同进程之共享数据的方式,可以在此基础上
开发出分布式的程序。
不同的业务场景可以选择其中的一种或几种的组合实现程序性能的优化。
12. 终级大杀器:PyPy
PyPy是用RPython(CPython的子集)实现的Python,根据官网的基准测试数据,它比CPython实现的Python
要快6倍以上。快的原因是使用了Just-in-Time(JIT)编译器,即动态编译器,与静态编译器(如gcc,javac等)不
同,它是利用程序运行的过程的数据进行优化。由于历史原因,目前pypy中还保留着GIL,不过正在进行的
STM项目试图将PyPy变成没有GIL的Python。
如果python程序中含有C扩展(非cffiffiffi的方式),JIT的优化效果会大打折扣,甚至比CPython慢(比Numpy)。
所以在PyPy中最好用纯Python或使用cffiffiffi扩展。
20. Django 中间件是如何使用的?
在http请求 到达视图函数之前 和视图函数return之后,django会根据自己的规则在合适的时机执行中间件中相应
的方法。
中间件的执行流程
1. 执行完所有的request方法 到达视图函数。
2. 执行中间件的其他方法
3. 经过所有response方法 返回客户端。
注意:如果在其中1个中间件里 request方法里 return了值,就会执行当前中间的response方法,返回给用户 然后
报错。。不会再执行下一个中间件。
中间件可以定义五个方法,分别是:(主要的是 process_request和process_response)
process_request(self,request)
process_view(self, request, view_func, view_args, view_kwargs)
process_template_response(self,request,response)
process_exception(self, request, exception)
process_response(self, request, response)
中间件不用继承自任何类(可以继承 object),下面一个中间件大概的样子:
from django.utils.deprecation import MiddlewareMixin
class MD1(MiddlewareMixin):
def process_request(self, request):
print("MD1里面的 process_request")
def process_response(self, request, response):
print("MD1里面的 process_response")
return response