Download as pdf or txt
Download as pdf or txt
You are on page 1of 151

目录

PYTHON 基础篇 ......................................................................................................................................................... 16

1.为什么学习 Python.................................................................................................................................. 16

2.通过什么途径学习 Python .................................................................................................................... 16

3.谈谈对 Python 和其他语言的区别 ..................................................................................................... 16

4.简述解释型和编译型编程语言............................................................................................................... 17

5.Python 的解释器种类以及相关特点? ............................................................................................. 17

6.位和字节的关系 .......................................................................................................................................... 18

7.b、B、KB、MB、GB 的关系 .............................................................................................................. 18

8.PE8 规范 ....................................................................................................................................................... 18

9.通过代码实现如下转换(进制之间转换)........................................................................................... 19

10.请编写一个函数实现将 IP 地址转换成一个整数.......................................................................... 19

11.python 递归的最大层数? ................................................................................................................. 20

12.求结果(and or or) ................................................................................................................................. 20

13.ascii、unicode、utf-8、gbk 区别.............................................................................................. 21

14.字节码和机器码的区别.......................................................................................................................... 21

15.三元运算写法和应用场景? ................................................................................................................ 22

16.Python3 和 Python2 的区别? ...................................................................................................... 23

17.用一行代码实现数值交换 ..................................................................................................................... 24

18.Python3 和 Python2 中 int 和 long 区别 ................................................................................. 24

19.xrange 和 range 的区别 .................................................................................................................... 24

20.文件操作时:xreadlines 和 readlines 的区别? ..................................................................... 25


21.列列举布尔值为 False 的常见值? ................................................................................................... 25

22.字符串、列表、元组、字典每个常用的 5 个方法? .................................................................. 25

23.lambda 表达式格式以及应用场景? .............................................................................................. 27

24.pass、continue、break、exit 的作用 ....................................................................................... 28

25.*arg 和**kwarg 作用 ........................................................................................................................... 28

26.is 和==的区别 ......................................................................................................................................... 28

27.谈谈 Python 的深浅拷贝?以及实现方法和应用场景。 ......................................................... 28

28.Python 垃圾回收机制?...................................................................................................................... 29

29.Python 的可变类型和不可变类型? ............................................................................................... 30

30.求结果 ......................................................................................................................................................... 30

31.求结果 ......................................................................................................................................................... 31

32.列举常见的内置函数 .............................................................................................................................. 32

33.filter、map、reduce 的作用 .......................................................................................................... 34

34.一行代码实现 9*9 乘法表 .................................................................................................................... 35

35.如何安装第三方模块?以及用过哪些第三方模块? ................................................................... 35

36.常用模块都有那些? .............................................................................................................................. 36

37.re 的 match 和 search 区别? ......................................................................................................... 36

38.什么是正则的贪婪匹配? ..................................................................................................................... 36

39.求结果: ..................................................................................................................................................... 36

40.求结果: ..................................................................................................................................................... 37

41.def func(a,b=[]) 这种写法有什什么坑? ................................................................................... 37

42.如何实现 “1,2,3” 变成 [‘1’,’2’,’3’] ....................................................................... 37


43.如何实现[‘1’,’2’,’3’]变成[1,2,3] ................................................................................... 38

44.a = [1,2,3] 和 b = [(1),(2),(3) ] 以及 b = [(1,),(2,),(3,) ] 的区别? ......................... 38

45.如何用一行代码生成[1,4,9,16,25,36,49,64,81,100] ............................................................ 38

46.一⾏代码实现删除列表中重复的值 ................................................................................................... 38

47.如何在函数中设置一个全局变量 ....................................................................................................... 38

48.logging 模块的作用?以及应用场景? ......................................................................................... 39

49.请用代码简答实现 stack ...................................................................................................................... 39

50.常用字符串格式化哪几种? ................................................................................................................ 40

51.简述 生成器、迭代器、可迭代对象 以及应用场景? .............................................................. 40

52.用 Python 实现一个二分查找的函数。 ......................................................................................... 44

53.谈谈你对闭包的理解?.......................................................................................................................... 44

54. os 和 sys 模块的作用? ...................................................................................................................... 45

55. 如何生成一个随机数? ....................................................................................................................... 46

56. 如何使用 python 删除一个文件? ................................................................................................ 46

57. 谈谈你对面向对象的理解 ................................................................................................................... 47

58. Python 面向对象中的继承有什么特点 ......................................................................................... 47

59. 面向对象深度优先和广度优先是什么? ....................................................................................... 48

60. 面向对象中 super 的作用? ............................................................................................................. 49

61. 是否使用过 functools 中的函数?其作用是什么? ............................................................... 49

62. 列举面向对象中带双下划线的特殊方法,如:__new__、__init__ .................................... 50

63. 如何判断是函数还是方法? .............................................................................................................. 51

64. 静态方法和类方法区别? ................................................................................................................... 52


65. 列举面向对象中的特殊成员以及应用场景 ................................................................................... 53

66. 1、2、3、4、5 能组成多少个互不相同且无重复的三位数 ................................................. 53

67. 什么是反射?以及应⽤用场景? ..................................................................................................... 54

68. metaclass 作用?以及应用场景?................................................................................................. 54

69. 用尽量多的方法实现单例模式。 ..................................................................................................... 55

70. 装饰器器的写法以及应用场景。 ..................................................................................................... 56

71. 异常处理写法以及如何主动跑出异常(应用场景)................................................................. 57

72、什么是面向对象的 mro ..................................................................................................................... 57

73. isinstance 作用以及应用场景? ..................................................................................................... 57

74. 写代码并实现.......................................................................................................................................... 58

75. json 序列化时,可以处理的数据类型有哪些?如何定制支持 datetime 类型? ......... 58

76. json 序列化时,默认遇到中文会转换成 unicode,如果想要保留中文怎么办? ........ 58

77. 什么是断言?应用场景? ................................................................................................................... 58

78. 有用过 with statement 吗?它的好处是什么?..................................................................... 60

79. 使用代码实现查看列举目录下的所有文件。 .............................................................................. 60

80. 简述 yield 和 yield from 关键字 ................................................................................................. 60

第二部分 网络编程和并发 ............................................................................................................................... 60

81. 简述 OSI 七层协议。 ........................................................................................................................ 60

82. 什么是 C/S 和 B/S 架构? ................................................................................................................ 61

83. 简述 三次握手、四次挥手的流程。 .............................................................................................. 61

84. TCP 和 UDP 的区别? ........................................................................................................................ 61

85. 为何基于 tcp 协议的通信比基于 udp 协议的通信更可靠? ................................................ 61


86. 什么是 socket?简述基于 tcp 协议的套接字通信流程。..................................................... 62

87. 什么是粘包? socket 中造成粘包的原因是什什么? 哪些情况会发生粘包现象? .. 62

88. IO 多路复的作用? ............................................................................................................................... 63

89.select、poll、epoll 模型的区别?(属于多路复用 IO 的模型) ..................................... 63

90. 什么是防火墙以及作用? ................................................................................................................... 64

91. 简述 进程、线程、协程的区别 以及应用场景? ..................................................................... 64

92. GIL 锁是什么? ...................................................................................................................................... 65

93. Python 中如何使用线程池和进程池? ......................................................................................... 65

94. threading.local 的作用? ................................................................................................................ 65

95. 进程之间如何进行通信? ................................................................................................................... 65

96. 什么是并发和并行? ............................................................................................................................ 65

97. 进程锁和线程锁的作用? ................................................................................................................... 65

98. 解释什么是异步非阻塞? ................................................................................................................... 65

99. 路由器和交换机的区别 ....................................................................................................................... 66

100.什么是域名解析? ................................................................................................................................ 66

101.如何修改本地 hosts 件? ................................................................................................................. 66

102.生产者消费者模型应用场景及优势? ........................................................................................... 67

103.什么是 cdn?......................................................................................................................................... 67

104.LVS 是什么及作用? ........................................................................................................................... 67

105.Nginx 是什么及作用? ..................................................................................................................... 68

106.keepalived 是什么及作用? ............................................................................................................. 68

107.haproxy 是什么以及作用? ............................................................................................................ 68


108.什么是负载均衡? ................................................................................................................................ 68

109.什么是 rpc 及应用场景?.................................................................................................................. 68

110.简述 asynio 模块的作用和应用场景。 ....................................................................................... 68

111.简述 gevent 模块的作用和应用场景。 ...................................................................................... 68

112.twisted 框架的使用和应用 .............................................................................................................. 68

数据库和缓存........................................................................................................................................................ 68

113.列举常见的关系型数据库和非关系型都有那些?..................................................................... 68

114.MySQL 常见数据库引擎及比较? ................................................................................................. 69

115.简述数据库三大范式? ....................................................................................................................... 69

116、什么是事务?MySQL 如何支持事务? .................................................................................... 70

117.简述数据库设计中一对多和多对多的应用场景?..................................................................... 70

118.如何基于数据库实现商城商品计数器? ....................................................................................... 71

119.常见 SQL(必备) ............................................................................................................................... 71

120.简述触发器、函数、视图、存储过程? ....................................................................................... 71

121.MySQL 索引种类................................................................................................................................. 71

122.索引在什么情况下遵循最左前缀的规则? .................................................................................. 72

123.主键和外键的区别? ........................................................................................................................... 72

124.MySQL 常见的函数?........................................................................................................................ 72

125.列举 创建索引但是无法命中索引的 8 种情况。 ...................................................................... 73

126.如何开启慢日志查询? ....................................................................................................................... 74

127.数据库导入导出命令(结构+数据)? ........................................................................................ 74

128.数据库优化方案? ................................................................................................................................ 74
129.char 和 varchar 的区别? ............................................................................................................... 75

130.简述 MySQL 的执行计划? ............................................................................................................. 75

131.在对 name 做了唯一索引前提下,简述以下区别: ............................................................ 75

132.1000w 条数据,使用 limit offset 分页时,为什么越往后翻越慢?如何解决? ..... 76

133.什么是索引合并? ................................................................................................................................ 76

134.什么是覆盖索引? ................................................................................................................................ 77

135.简述数据库读写分离? ....................................................................................................................... 77

136.简述数据库分库分表?(水平、垂直) ....................................................................................... 78

137.redis 和 memcached 比较? ........................................................................................................ 78

138.redis 中数据库默认是多少个 db 及作用?............................................................................... 78

139.python 操作 redis 的模块? .......................................................................................................... 78

140.如果 redis 中的某个列表中的数据量非常大,如果实现循环显示每一个值? .............. 79

141.redis 如何实现主从复制?以及数据同步机制? ...................................................................... 79

142.redis 中的 sentinel 的作用? ........................................................................................................ 80

143.如何实现 redis 集群? ....................................................................................................................... 80

144.redis 中默认有多少个哈希槽? ...................................................................................................... 81

145.简述 redis 的有哪几种持久化策略及比较? .............................................................................. 81

146.列举 redis 支持的过期策略。 ......................................................................................................... 81

147.MySQL 里有 2000w 数据,redis 中只存 20w 的数据,如何保证 redis 中都是

热点数据? ....................................................................................................................................................... 81

148.写代码,基于 redis 的列表实现 先进先出、后进先出队列、优先级队列。 ................ 82

149.如何基于 redis 实现消息队列?..................................................................................................... 85


150.如何基于 redis 实现发布和订阅?以及发布订阅和消息队列的区别?............................ 86

151.什么是 codis 及作用? ...................................................................................................................... 86

152.什么是 twemproxy 及作用? ........................................................................................................ 86

153.写代码实现 redis 事务操作。 ......................................................................................................... 86

154.redis 中的 watch 的命令的作用? ............................................................................................... 87

155.基于 redis 如何实现商城商品数量计数器? .............................................................................. 88

156.简述 redis 分布式锁和 redlock 的实现机制。 ........................................................................ 88

157.什么是一致性哈希?Python 中是否有相应模块? ................................................................. 90

158.如何高效的找到 redis 中所有以 aaa 开头的 key? ............................................................... 90

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

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

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

3.什么是 magic string ?........................................................................................................................ 92

4.如何创建响应式布局? ............................................................................................................................ 92

5.你曾经使用过哪些前端框架?............................................................................................................... 93

6.什么是 ajax 请求?并使用 jQuery 和 XMLHttpRequest 对象实现一个 ajax 请求。 . 93

7.如何在前端实现轮训? ............................................................................................................................ 93

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

9.vuex 的作用?............................................................................................................................................ 96

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

11.axios 的作用? ........................................................................................................................................ 96

12.列举 vue 的常见指令。 ........................................................................................................................ 96


13.简述 jsonp 及实现原理? .................................................................................................................... 96

14.什么是 cors ? ........................................................................................................................................ 97

15.列举 Http 请求中常见的请求方式? ............................................................................................... 97

16.列举 Http 请求中的状态码? ............................................................................................................. 97

17.列举 Http 请求中常见的请求头?.................................................................................................... 98

18.看图写结果(js): ............................................................................................................................... 98

19.django、flask、tornado 框架的比较? ................................................................................. 100

20.什么是 wsgi? ...................................................................................................................................... 101

21.django 请求的生命周期? .............................................................................................................. 101

22.列举 django 的内置组件? ............................................................................................................. 102

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

24.简述什么是 FBV 和 CBV? .............................................................................................................. 105

25.FBV 与 CBV 的区别 ............................................................................................................................ 106

26.django 的 request 对象是在什么时候创建的? .................................................................... 106

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

28.列举 django orm 中所有的方法(QuerySet 对象的所有方法) .................................. 108

29.only 和 defer 的区别? .................................................................................................................... 108

30.select_related 和 prefetch_related 的区别? ..................................................................... 108

31.filter 和 exclude 的区别? ............................................................................................................. 110

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

33.django orm 中如何设置读写分离? ......................................................................................... 111

34.F 和 Q 的作用? ...................................................................................................................................... 112


35.values 和 values_list 的区别? .................................................................................................... 113

36.如何使用 django orm 批量创建数据? ..................................................................................... 113

37.django 的 Form 和 ModeForm 的作用? .............................................................................. 113

38.django 的 Form 组件中,如果字段中包含 choices 参数,请使用两种方式实现数据

源实时更新。 ................................................................................................................................................ 114

39.django 的 Model 中的 ForeignKey 字段中的 on_delete 参数有什么作用? ......... 115

40.django 中 csrf 的实现机制? ........................................................................................................ 115

41.django 如何实现 websocket?................................................................................................... 116

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

........................................................................................................................................................................... 116

43.django 中如何实现 orm 表中添加数据时创建一条日志记录。........................................ 118

44.django 缓存如何设置? ................................................................................................................... 118

45.django 的缓存能使用 redis 吗?如果可以的话,如何配置? .......................................... 119

46.django 路由系统中 name 的作用? ........................................................................................... 120

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

48.django-debug-toolbar 的作用? ............................................................................................. 120

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

50.解释 orm 中 db first 和 code first 的含义?...................................................................... 121

51.django 中如何根据数据库表生成 model 中的类? .............................................................. 121

52.使用 orm 和原生 sql 的优缺点? .................................................................................................. 121

53.简述 MVC 和 MTV ............................................................................................................................. 121

54.django 的 contenttype 组件的作用? ..................................................................................... 122

55.谈谈你对 restfull 规范的认识? ................................................................................................... 122


56.接口的幂等性是什么意思? ............................................................................................................. 122

57.什么是 RPC?........................................................................................................................................ 122

58.Http 和 Https 的区别?................................................................................................................... 123

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

60.django rest framework 框架中都有那些组件? ................................................................. 123

61.django rest framework 框架中的视图都可以继承哪些类............................................... 124

62.简述 django rest framework 框架的认证流程。............................................................... 125

63.django rest framework 如何实现的用户访问频率控制?............................................... 126

64.Flask 框架的优势? ............................................................................................................................ 126

65.Flask 框架依赖组件 ............................................................................................................................ 126

66.Flask 蓝图的作用 ................................................................................................................................. 127

67.列举使用的 Flask 第三方组件? .................................................................................................... 127

68.简述 Flask 上下文管理流程? ........................................................................................................... 127

69.Flask 中的 g 的作用? ....................................................................................................................... 127

Flask 中上下文管理主要涉及到了那些相关的类?并描述类主要作用? ............................... 128

为什么要 Flask 把 Local 对象中的的值 stack 维护成一个列表? ......................................... 128

Flask 中多 app 应用是怎么完成? ...................................................................................................... 128

在 Flask 中实现 WebSocket 需要什么组件? ............................................................................... 128

wtforms 组件的作用? ........................................................................................................................... 128

Flask 框架默认 session 处理机制? .................................................................................................. 128

解释 Flask 框架中的 Local 对象和 threading.local 对象的区别? ...................................... 129

Flask 中 blinker 是什么? ................................................................................................................... 130


SQLAlchemy 中的 session 和 scoped_session 的区别?................................................... 131

SQLAlchemy 如何执行原生 SQL? ................................................................................................... 131

ORM 的实现原理? ................................................................................................................................... 131

DBUtils 模块的作用? ............................................................................................................................. 131

SQLAchemy 中如何为表设置引擎和字符编码? .......................................................................... 133

SQLAchemy 中如何设置联合唯一索引? ........................................................................................ 133

简述 Tornado 框架的特点。 ................................................................................................................. 133

简述 Tornado 框架中 Future 对象的作用? .................................................................................. 133

Tornado 框架中如何编写 WebSocket 程序?............................................................................. 134

Tornado 中静态文件是如何处理的? 如: <link

href="{{static_url("commons.css")}}" rel="stylesheet" /> ......................................... 134

Tornado 操作 MySQL 使用的模块? ............................................................................................... 134

Tornado 操作 redis 使用的模块?..................................................................................................... 135

简述 Tornado 框架的适用场景? ........................................................................................................ 135

git 常见命令作用: .................................................................................................................................... 135

简述以下 git 中 stash 命令作用以及相关其他命令。 .................................................................. 135

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

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

如何基于 git 实现代码 review? ......................................................................................................... 137

git 如何实现 v1.0 、v2.0 等版本的管理? .................................................................................... 137

什么是 gitlab ............................................................................................................................................... 137

github 和 gitlab 的区别? .................................................................................................................... 137


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

git 中 .gitignore 文件的作用 .............................................................................................................. 137

什么是敏捷开发?....................................................................................................................................... 138

简述 jenkins 工具的作用? .................................................................................................................... 138

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

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

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

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

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

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

........................................................................................................................................................................... 139

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

简述 celery 运行机制。 ........................................................................................................................... 140

celery 如何实现定时任务? ................................................................................................................... 140

简述 celery 多任务结构目录 ................................................................................................................. 140

celery 中装饰器 @app.task 和 @shared_task 的区别? ................................................... 141

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

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

简述 seleninu 模块的作用及基本使用?............................................................................................ 141

scrapy 框架中各组件的工作流程? .................................................................................................... 141

在 scrapy 框架中如何设置代理(两种方法)? ............................................................................ 142

scrapy 框架中如何实现大文件的下载? ........................................................................................... 143

scrapy 中如何实现限速?....................................................................................................................... 144


scrapy 中如何实现暂停爬虫? ............................................................................................................. 144

scrapy 中如何进行自定制命令? ......................................................................................................... 144

scrapy 中如何实现的记录爬虫的深度? ........................................................................................... 145

scrapy 中的 pipelines 工作原理? .................................................................................................... 145

scrapy 的 pipelines 如何丢弃一个 item 对象? .......................................................................... 145

简述 scrapy 中爬虫中间件和下载中间件的作用?1 ..................................................................... 145

scrapy-redis 组件的作用?................................................................................................................... 145

scrapy-redis 组件中如何实现的任务的去重? .............................................................................. 146

scrapy-redis 的调度器如何实现任务的深度优先和广度优先?.... ......................................... 148

简述 vitualenv 及应用场景? ................................................................................................................ 148

简述 pipreqs 及应用场景? ................................................................................................................. 148

在 Python 中使用过什么代码检查工具?......................................................................................... 149

简述 saltstack、ansible、fabric、puppet 工具的作用?.................................................... 149

B Tree 和 B+ Tree 的区别? ................................................................................................................ 149

请列举常见排序并通过代码实现任意三种。 .................................................................................... 149

请列举常见查找并通过代码实现任意三种。 .................................................................................... 149

请列举你熟悉的设计模式? .................................................................................................................... 149

有没有刷过 leetcode? ........................................................................................................................... 149

列举熟悉的的 Linux 命令。 ................................................................................................................... 149

公司线上服务器是什么系统? ................................................................................................................ 150

解释 PV、UV 的含义?.......................................................................................................................... 150

解释 QPS 的含义? ................................................................................................................................... 150


uwsgi 和 wsgi 的区别? ......................................................................................................................... 150

supervisor 的作用? ................................................................................................................................ 150

什么是反向代理?....................................................................................................................................... 151

简述 SSH 的整个过程。 ........................................................................................................................... 151

有问题都去那些找解决方案? ................................................................................................................ 151

是否有关注什么技术类的公众号?....................................................................................................... 151

最近在研究什么新技术? ......................................................................................................................... 151

是否了解过领域驱动模型? .................................................................................................................... 151


Python 基础篇

1.为什么学习 Python

家里有在这个 IT 圈子里面,也想让我接触这个圈子,然后给我建议学的
Python,
然后自己通过百度和向有学过 Python 的同学了解了 Python,Python 这门语
言,入门比较简单,
它简单易学,生态圈比较强大,涉及的地方比较多,特别是在人工智能,和数
据分析这方面。在未来我觉得是往自动化,
人工智能这方面发展的,所以学习了 Python

2.通过什么途径学习 Python

刚开始接触 Python 的时候,到网上里面跟着视频学基础,再后来网上到看技术


贴,然后看到有人推荐廖雪峰的 Python 教程,
练项目到 GitHub 上面找一些小项目学习。

3.谈谈对 Python 和其他语言的区别

Python 属于解释型语言,当程序运行时,是一行一行的解释,并运行,所以调
式代码很方便,开发效率高,
还有龟叔给 Python 定位是任其自由发展、优雅、明确、简单,所以在每个领域
都有建树,所有它有着非常强大的第三方库,
特点:
语法简洁优美,功能强大,标准库与第三方库都非常强大,而且应用领域也非
常广
可移植性,可扩展性,可嵌入性
缺点:
运行速度慢,

- 解释型
- python/php
- 编译型
- c/java/c#

- Python 弱类型
(1)与 java 相比:在很多方面,Python 比 Java 要简单,比如 java 中所有变
量必须声明才能使用,而 Python 不需要声明,用少量的代码构建出很多功能;(高
效的高级数据结构)
(2)与 php 相比:python 标准包直接提供了工具,并且相对于 PHP 代码更易于维
护;
(3)Python 与 c 相比:
Python 和 C Python 这门语言是由 C 开发而来
对于使用:Python 的类库齐全并且使用简洁,如果要实现同样的功能,
Python 10 行代码可以解决,C 可能就需要 100 行甚至更多.
对于速度:Python 的运行速度相较与 C,绝逼是慢了
Python 的优势:
1、Python 易于学习;
2、用少量的代码构建出很多功能;(高效的高级数据结构)
3、Python 拥有最成熟的程序包资源库之一;
4、Python 完全支持面向对象;
5、Python 是跨平台且开源的。
6、动态类型:

4.简述解释型和编译型编程语言

解释型:就是边解释边执行(Python,php)
编译型:编译后再执行(c、java、c#)

5.Python 的解释器种类以及相关特点?

CPython
是官方版本的解释器:CPython。是使用 C 语言开发的,所以叫 CPython。在命
令行下运行 python 就是启动 CPython 解释器。
CPython 是使用最广的 Python 解释器。教程的所有代码也都在 CPython 下执
行。
IPython
IPython 是基于 CPython 之上的一个交互式解释器,也就是说,IPython 只是在
交互方式上有所增强,但是执行 Python 代码的功能和 CPython 是完全一样的。
CPython 用>>>作为提示符,而 IPython 用 In [序号]:作为提示符。
PyPy
由 Python 写的解释器,它的执行速度是最快。PyPy 采用 JIT 技术,对 Python
代码进行动态编译(注意不是解释),
绝大部分 Python 代码都可以在 PyPy 下运行,但是 PyPy 和 CPython 有一些是不
同的,这就导致相同的 Python 代码在两种解释器下执行可能会有不同的结果。
Jython
Jython 是运行在 Java 平台上的 Python 解释器,可以直接把 Python 代码编译
成 Java 字节码执行。
IronPython
IronPython 和 Jython 类似,只不过 IronPython 是运行在.Net 平台上的
Python 解释器,可以直接把 Python 代码编译成.Net 的字节码。
小结:
Python 的解释器很多,但使用最广泛的还是 CPython。如果要和 Java
或.Net 平台交互,最好的办法不是用 Jython 或 IronPython,而是通过网络调
用来交互,确保各程序之间的独立性。
6.位和字节的关系

1 字节 = 8 位
位(bit),数据存储是以“字节”(Byte)为单位,数据传输是以大多是以
“位”(bit,又名“比特”)为单位,
一个位就代表一个 0 或 1(即一个二进制),二进制是构成存储器的最小单
位,每 8 个位(bit,简写为 b)组成一个字节(Byte,简写为 B),
字节是最小一级的信息单位

7.b、B、KB、MB、GB 的关系

b --->位(bit)
B --->字节 一个字节等于 8 位
1B = 8 bit
1kb = 1024 B
1 MB = 1024 KB
1 GB = 1024 MB

8.PE8 规范

1、使用 4 个空格而不是 tab 键进行缩进。


2、每行长度不能超过 79
3、使用空行来间隔函数和类,以及函数内部的大块代码
4、必要时候,在每一行下写注释
5、使用文档注释,写出函数注释
6、在操作符和逗号之后使用空格,但是不要在括号内部使用
7、命名类和函数的时候使用一致的方式,比如使用 CamelCase 来命名类,
使用 lower_case_with_underscores 来命名函数和方法
8、在类中总是使用 self 来作为默认
9、尽量不要使用魔法方法
10、默认使用 UTF-8,甚至 ASCII 作为编码方式
11、换行可以使用反斜杠,最好使用圆括号。
12、不要在一句 import 中多个库,
空格的使用
各种右括号前不要加空格。
逗号、冒号、分号前不要加空格。
函数的左括号前不要加空格。如 Func(1)
序列的左括号前不要加空格。如 list[2]
操作符左右各加一个空格,不要为了对齐增加空格
函数默认参数使用的赋值符左右省略空格
不要将多句语句写在同一行,尽管使用‘;’允许
if/for/while 语句中,即使执行语句只有一句,也必须另起一行
函数命名使用全部小写的方式,常量命名使用大写,类属性(方法和变量)
使用小写
类的命名首字母大写

9.通过代码实现如下转换(进制之间转换)

# 二进制转换成十进制-->int
v = "0b1111011"
b = int(v,2)
print(b) # 123

# 十进制转换成二进制--->bin
v2 = 18
print(bin(int(v2)))
# 0b10010

# 八进制转换成十进制
v3 = "011"
print(int(v3))
# 11

# 十进制转换成八进制:---> oct
v4 = 30
print(oct(int(v4)))
# 0o36

# 十六进制转换成十进制:
v5 = "0x12"
print(int(v5,16))
# 18

# 十进制转换成十六进制:---> hex
v6 = 87
print(hex(int(v6)))
# 0x57

10.请编写一个函数实现将 IP 地址转换成一个整数

请编写一个函数实现将 IP 地址转换成一个整数。
如 10.3.9.12 转换规则为:
10 00001010
3 00000011
9 00001001
12 00001100
再将以上二进制拼接起来计算十进制结果:00001010 00000011 00001001
00001100 = ?

def v1(addr):
# 取每个数
id = [int(x) for x in addr.split(".")]
print(id)
return sum(id[i] << [24, 16, 8, 0][i] for i in range(4))

print(v1("127.0.0.1"))

# [127, 0, 0, 1]
# 2130706433

11.python 递归的最大层数?

998
主要还是要和执行的机器有关

12.求结果(and or or)

1. 求结果:1 or 3
print(1 or 3) # 1

2. 求结果:1 and 3
print(1 and 3) # 3

3. 求结果:0 and 2 and 1


print(0 and 2 and 1) # 0

4. 求结果:0 and 2 or 1
print(0 and 2 or 1) # 1

5. 求结果:0 and 2 or 1 or 4
print(0 and 2 or 1 or 4) # 1

6. 求结果:0 or Flase and 1


print(0 or False and 1) # Flase

总结:
# x or y 如果 x 为真,则值为 x, 否则为 y
# x and y 如果 x 为真,则值为 y,否则为 x
运算符:
1. 求结果:2 & 5
print(2 & 5) # 10 & 101 => 000 => 0
2. 求结果:2 ^ 5
print(2 ^ 5) # 10 ^ 101 => 111 => 1*2**0+1*2**1+1*2**2=1+2+4=7

13.ascii、unicode、utf-8、gbk 区别

python2 内容进行编码(默认 ascii),而 python3 对内容进行编码的默认为


utf-8。
ascii 最多只能用 8 位来表示(一个字节),即:2**8 = 256,所以,ASCII
码最多只能表示 256 个符号。
unicode 万国码,任何一个字符==两个字节
utf-8 万国码的升级版 一个中文字符==三个字节 英文是一个字节 欧
洲的是 2 个字节
gbk 国内版本 一个中文字符==2 个字节 英文是一个字节
gbk 转 utf-8 需通过媒介 unicode

14.字节码和机器码的区别

机器码,学名机器语言指令,有时也被称为原生码,是电脑的 CPU 可直接解读的数


据。
字节码是一种中间状态(中间码)的二进制代码(文件)。需要直译器转译后才能
成为机器码。
什么是机器码

机器码(machine code),学名机器语言指令,有时也被称为原生码(Native
Code),是电脑的 CPU 可直接解读的数据。
通常意义上来理解的话,机器码就是计算机可以直接执行,并且执行速度最快
的代码。

总结:机器码是电脑 CPU 直接读取运行的机器指令,运行速度最快,但是非常


晦涩难懂,也比较难编写

什么是字节码
字节码(Bytecode)是一种包含执行程序、由一序列 op 代码/数据对 组成的
二进制文件。
字节码是一种中间码,它比机器码更抽象,需要直译器转译后才能成为机器码
的中间代码。

总结:字节码是一种中间状态(中间码)的二进制代码(文件)。需要直译器
转译后才能成为机器码。

-----------
#is 比较的是内存地址
#== 比较的是值
# int 具有范围:-5---256
#对于 int 小数据池
范围:-5----256 创建的相间的数字,都指向同一个内存地址

#对于字符串 (面试)
1、小数据池 如果有空格,那指向两个内存地址,
2、长度不能超过 20
3、不能用特殊字符

i = 'a'*20
j = 'a'*20
print(i is j) # True

i = "a"*21
j = "a"*21
print(i is j) # False

关于编码所占字节
unicode: 所有字符(无论英文、中文等) 1 个字符:2 个字节
gbk:一个字符,英文 1 个字节,中文两个字节
utf-8:英文 1 个字节、 欧洲:2 个字节, 亚洲:3 个字节、

在 utf-8 中,一个中文字符占用 3 个字节


在 gbk 中一个汉字占用 2 个字节
黎诗 = utf-8(6 字节)=48
黎诗 = gbk(4 字节)=32

字节和位的关系。
#一个字节(byte) = 8 位(bit)
# 位为最小的单位

简述变量命名规范
#1、以字母,数字,下划线任由结合
#2、不能以命名太长,不使用拼音,中文
#3、不能以数字开头
#4、不能用关键词

15.三元运算写法和应用场景?

应用场景:简化 if 语句
# 关于三元运算
# 结果+ if + 条件 + else + 结果
result='gt' if 1>3 else 'lt'
print(result) # lt
# 理解:如果条件为真,把 if 前面的值赋值给变量,否则把 else 后面的值赋
值给变量。

lambda 表达式
temp = lambda x,y:x+y
print(temp(4,10)) # 14

可替代:
def foo(x,y):
return x+y
print(foo(4,10)) # 14

16.Python3 和 Python2 的区别?

1:打印时,py2 需要可以不需要加括号,py3 需要
python 2 :print ('lili') , print 'lili'
python 3 : print ('lili')
python3 必须加括号

exec 语句被 python3 废弃,统一使用 exec 函数

2:内涵
Python2:1,臃肿,源码的重复量很多。
2,语法不清晰,掺杂着 C,php,Java,的一些陋习。
Python3:几乎是重构后的源码,规范,清晰,优美。

3、输出中文的区别
python2:要输出中文 需加 # -*- encoding:utf-8 -*-
Python3 : 直接搞

4:input 不同
python2 :raw_input
python3 :input 统一使用 input 函数

5:指定字节
python2 在编译安装时,可以通过参数-----enable-unicode=ucs2 或-----
enable-unicode=ucs4 分别用于指定使用 2 个字节、4 个字节表示一个
unicode;
python3 无法进行选择,默认使用 ucs4
查看当前 python 中表示 unicode 字符串时占用的空间:

impor sys
print(sys.maxunicode)
#如果值是 65535,则表示使用 usc2 标准,即:2 个字节表示
#如果值是 1114111,则表示使用 usc4 标准,即:4 个字节表示

6:
py2:xrange
range
py3:range 统一使用 range,Python3 中 range 的机制也进行修改并提高了大
数据集生成效率

7:在包的知识点里
包:一群模块文件的集合 + __init__
区别:py2 : 必须有__init__
py3:不是必须的了

8:不相等操作符"<>"被 Python3 废弃,统一使用"!="

9:long 整数类型被 Python3 废弃,统一使用 int

10:迭代器 iterator 的 next()函数被 Python3 废弃,统一使用


next(iterator)

11:异常 StandardError 被 Python3 废弃,统一使用 Exception

12:字典变量的 has_key 函数被 Python 废弃,统一使用 in 关键词

13:file 函数被 Python3 废弃,统一使用 open 来处理文件,可以通过


io.IOBase 检查文件类型

17.用一行代码实现数值交换

a = 1
b = 2
a, b = b, a

18.Python3 和 Python2 中 int 和 long 区别

在 python3 里,只有一种整数类型 int,大多数情况下,和 python2中的长整型类


似。

19.xrange 和 range 的区别


都在循环时使用,xrange 内存性能更好,xrange 用法与 range 完全相同,range
一个生成 list 对象,xrange 是生成器
要生成很大的数字序列的时候,用 xrange 会比 range 性能优很多,因为不需要一
上来就开辟一块很大的内存空间。
在 python2 中:
range([start,] stop[, step]),根据 start 与 stop 指定的范围以及 step 设定
的步长,生成一个序列
xrange 用法与 range 完全相同,所不同的是生成的不是一个数组,而是一个生成
器。
由上面的示例可以知道:要生成很大的数字序列的时候,用 xrange 会比 range 性
能优很多,因为不需要一上来就开辟一块很大的内存空间,这两个基本上都是在循
环的时候用。
在 Python 3 中,range() 是像 xrange() 那样实现,xrange()被抛弃。

20.文件操作时:xreadlines 和 readlines 的区别?

readlines 返回一个列表
xreadlines 返回一个生成器

21.列列举布尔值为 False 的常见值?

0,“”,{},[],(),set()
0 Flask 负数 不成立的表达式 None 等

22.字符串、列表、元组、字典每个常用的 5 个方法?

字符串:
字符串用单引号(')或双引号(")括起来,不可变
1,find 通过元素找索引,可切片,找不到返回-1
2,index,找不到报错。
3,split 由字符串分割成列表,默认按空格。
4,captalize 首字母大写,其他字母小写。
5,upper 全大写。
6,lower 全小写。
7,title,每个单词的首字母大写。
8,startswith 判断以什么为开头,可以切片,整体概念。
9,endswith 判断以什么为结尾,可以切片,整体概念。
10,format 格式化输出
#format 的三种玩法 格式化输出
res='{} {} {}'.format('egon',18,'male') ==> egon 18 male
res='{1} {0} {1}'.format('egon',18,'male') ==> 18 egon 18
res='{name} {age} {sex}'.format(sex='male',name='egon',age=18)
11,strip 默认去掉两侧空格,有条件, 12,lstrip,rstrip 14,center 居
中,默认空格。
15,count 查找元素的个数,可以切片,若没有返回 0
16,expandtabs 将一个 tab 键变成 8 个空格,如果 tab 前面的字符长度不足 8
个,则补全 8 个,
17,replace(old,new,次数)
18,isdigit 字符串由字母或数字组成 isalpha, 字符串只由字母组成
isalnum 字符串只由数字组成
19,swapcase 大小写翻转
20,for i in 可迭代对象。
字典:
1 无序(不能索引)2:数据关联性强 3:键值对,键值对。唯一一个映射数据类
型。
#字典的键必须是可哈希的 不可变类型。
在同一个字典中,键(key)必须是唯一的。

列表是有序的对象集合,字典是无序的对象集合。两者之间的区别在于:字典
当中的元素是通过键来存取的,而不是通过偏移存取
key: 输出所有的键
clear:清空
dic:删除的键如果没有则报错
pop:键值对删,有返回,没有原来的键会报错(自行设置返回键就不会报错)
popitem:随机删键值对
del:删除的键如果没有则报错
改 update
查 用 get 时。不会报错# 没有可以返回设定的返回值
注意:
1、字典是一种映射类型,它的元素是键值对。
2、字典的关键字必须为不可变类型,且不能重复。
3、创建空字典使用 { }。
列表:
索引,切片,加,乘,检查成员。
增加:有三种,
append:在后面添加。
Insert 按照索引添加,
expend:迭代着添加。
list.extend(seq) - 在列表末尾一次性追加另一个序列中的多个值(用新列表
扩展原来的列表)
pop 删除 (pop 有返回值)
remove 可以按照元素去删
clear 清空列表
del 1、可以按照索引去删除 2、切片 3、步长(隔着删)
改 1、索引 2、切片:先删除,再迭代着添加
list.count(obj) - 统计某个元素在列表中出现的次数
list.index(obj) - 从列表中找出某个值第一个匹配项的索引位置
list.reverse() - 反向列表中元素
list.sort([func]) - 对原列表进行排序
注意:
1、List 写在方括号之间,元素用逗号隔开。
2、和字符串一样,list 可以被索引和切片。
3、List 可以使用+操作符进行拼接。
4、List 中的元素是可以改变的。
元组:
()元组的元素不能修改
1、cmp(tuple1, tuple2):比较两个元组元素。
2、len(tuple):计算元组元素个数。
3、max(tuple):返回元组中元素最大值。
4、min(tuple):返回元组中元素最小值。
5、tuple(seq):将列表转换为元组。
注意
1、与字符串一样,元组的元素不能修改。
2、元组也可以被索引和切片,方法一样。
3、注意构造包含 0 或 1 个元素的元组的特殊语法规则。
4、元组也可以使用+操作符进行拼接。
Set(集合)
:集合(set)是一个无序不重复元素的序列。
可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须
用 set() 而不是 { },因为 { } 是用来创建一个空字典。

23.lambda 表达式格式以及应用场景?

匿名函数:为了解决那些功能很简单的需求而设计的一句话函数
函数名 = lambda 参数 :返回值

#参数可以有多个,用逗号隔开
#匿名函数不管逻辑多复杂,只能写一行,且逻辑执行结束后的内容就是返回值
#返回值和正常的函数一样可以是任意数据类型

lambda 表达式
temp = lambda x,y:x+y
print(temp(4,10)) # 14
可替代:
def foo(x,y):
return x+y
print(foo(4,10)) # 14

24.pass、continue、break、exit 的作用

pass: 代码占位语句,不做任何操作
continue:结束本次循环,使程序进入到下一次循环
break:结束当前的循环
exit:结束当前程序

25.*arg 和**kwarg 作用

*args 代表位置参数,它会接收任意多个参数并把这些参数作为元祖传递给
函数。
**kwargs 代表的关键字参数,返回的是字典,位置参数一定要放在关键字前面

26.is 和==的区别

a = 'lishi'
str1 = "li"
str2 = "shi"
str3 = str1 + str2
print("a == str3",a == str3)
print("a is str3",a is str3)
print("id(a)",id(a))
print("id(str3)",id(str3))
# a == str3 True == ---> 只需要内容相等
# a is str3 False is ---> 只需要内存地址相等
# id(a) 38565848
# id(str3) 39110280

is 比较的是两个实例对象是不是完全相同,它们是不是同一个对象,占用的内
存地址是否相同。

== 比较的是两个对象的内容是否相等,即内存地址可以不一样,内容一样就可
以了。默认会调用对象的 __eq__()方法。

27.谈谈 Python 的深浅拷贝?以及实现方法和应用场景。


浅拷贝只是增加了一个指针指向一个存在的地址,而深拷贝是增加一个指针并且开
辟了新的内存,这个增加的指针指向这个新的内存,采用浅拷贝的情况,释放内
存,会释放同一内存,深拷贝就不会出现释放同一内存的错误

一层的情况:

import copy

# 浅拷贝
li1 = [1, 2, 3]
li2 = li1.copy()
li1.append(4)
print(li1, li2) # [1, 2, 3, 4] [1, 2, 3]

# 深拷贝
li1 = [1, 2, 3]
li2 = copy.deepcopy(li1)
li1.append(4)
print(li1, li2) # [1, 2, 3, 4] [1, 2, 3]

多层的情况:

import copy

# 浅拷贝 指向共有的地址
li1 = [1, 2, 3,[4,5],6]
li2 = li1.copy()
li1[3].append(7)
print(li1, li2) # [1, 2, 3, [4, 5, 7], 6] [1, 2, 3, [4, 5, 7], 6]

# 深拷贝 重指向
li1 = [1, 2, 3,[4,5],6]
li2 = copy.deepcopy(li1)
li1[3].append(7)
print(li1, li2) # [1, 2, 3, [4, 5, 7], 6] [1, 2, 3, [4, 5], 6]

28.Python 垃圾回收机制?

1 引用计数:
每一个对象都有 ob_refcnt 就是引用计数器,默认值为 1,当有其他的
变量引用对象时,引用计数器就会发生变化。
当一个引用计数器为 0 时,意味着没有人再使用这个对象,没有人是
使用,就要进行垃圾回收
2 标记清除:
为了解决引用计数器的循环引用的问题
在 Python 的内部某种情况下触发,到可能存在循环引用的单独链表进
行扫描,检查是否有循环引用,如果存在循环引用,就让双方的引用计数都-
1,如果引用计数器都成 0,则认为是垃圾,系统进行回收
3 分代回收:将可能存在循环引用的对象维护三个链表
0 代:0 代中对象个数达到 700 扫描一次
1 代:0 代扫描 10 次,则 1 代扫描一次
2 代:1 代扫描 10 次,则 2 代扫描一次
4 缓存机制:
为了避免重复的创建和销毁一些常见的对象,python 在启动时维护了
一个池子,存放:-5、-4、-3...256,这些数据的占据的内存空间是确定的标
记清除

29.Python 的可变类型和不可变类型?

可变数据类型:列表、字典、可变集合
不可变数据类型:数字、字符串、元组、不可变集合

30.求结果

def multipliers():
return [lambda x:i*x for i in range(4)]
print([m(2) for m in multipliers()])
def a():
return [lambda x:i*x for i in range(4)]
b=a() #返回个列表函数
# b[2](1)

print(b[1](1))
# print(type(b),b)
print([m(1) for m in a()])
print([i*i for i in [1,2,3]])
[3, 3, 3, 3]
[1, 4, 9]

'''
def multipliers():
return [lambda x:i*x for i in range(4)]
print([m(2) for m in multipliers()])
#解释:
函数返回值为一个列表表达式,经过 4 次循环结果为包含四个 lambda 函数
的列表,
由于函数未被调用,循环中的 i 值未被写入函数,经过多次替代,循环结束后
i 值为 3,
故结果为:6,6,6,6
func=lambda x:x+1
print(func(1))
#2
print(func(2))
#3

#以上 lambda 等同于以下函数


def func(x):
return(x+1)
'''
请修改 multipliers 的定义来产生期望的结果(0,2,4,6)。
def multipliers():
return (lambda x:i*x for i in range(4)) #返回一个生成器
表达式
print([m(2) for m in multipliers()])
-面试题 2:
现有两个元组(('a'),('b')),(('c'),('d')),请使用 python 中匿名函数生成
列表[{'a':'c'},{'b':'d'}]

#匿名函数形式:
l1=(('a'),('b'))
l2=(('c'),('d'))
ret=map(lambda n:{n[0]:n[1]},zip(l1,l2))
print(list(ret))
#列表表达式形式:
l1=(('a'),('b'))
l2=(('c'),('d'))
print([{n[0]:n[1]} for n in zip(l1,l2)])

31.求结果

v = dict.fromkeys(['k1', 'k2'], [])


v['k1'].append(666)
print(v)
v['k1'] = 777
print(v)

结果:
{'k1': [666], 'k2': [666]}
{'k1': 777, 'k2': [666]}

解释:
Python 字典(Dictionary) fromkeys() 函数用于创建一个新字典,以序列 seq
中元素做字典的键,value 为字典所有键对应的初始值,默认为 None。

v1 = dict.fromkeys(['k1', 'k2'])
print(v1) # {'k1': None, 'k2': None}

v2 = dict.fromkeys(['k1', 'k2'], [])


print(v2) # {'k1': [], 'k2': []}

32.列举常见的内置函数

abs()
返回数字的绝对值
map
根据函数对指定序列做映射
map()函数接收两个参数,一个是函数,一个是可迭代对象,map 将传入的函数
依次作用到序列的每个元素,并把结果作为新的 list 返回。

返回值:
Python2 返回列表
Python3 返回迭代器

例子 1:
def mul(x):
return x*x
n=[1,2,3,4,5]
res=list(map(mul,n))
print(res) #[1, 4, 9, 16, 25]

例子 2:abs() 返回数字的绝对值
ret = map(abs,[-1,-5,6,-7])
print(list(ret))
# [1, 5, 6, 7]
filter
filter()函数接收一个函数 f(函数)和一个 list(可迭代对象),这个函数 f
的作用是对每个元素进行判断,返回 True 或 False,
filter()根据判断结果自动过滤掉不符合条件的元素,返回由符合条件元素组
成的新 list。
def is_odd(x):
return x % 2 == 1

v=list(filter(is_odd, [1, 4, 6, 7, 9, 12, 17]))


print(v) #[1, 7, 9, 17]
map 与 filter 总结
# filter 与 map 总结
# 参数: 都是一个函数名 + 可迭代对象
# 返回值: 都是返回可迭代对象
# 区别:
# filter 是做筛选的,结果还是原来就在可迭代对象中的项
# map 是对可迭代对象中每一项做操作的,结果不一定是原来就在可迭代对象
中的项
isinstance\type
isinstance() 函数来判断一个对象是否是一个已知的类型,类似 type()。
isinstance() 与 type() 区别:
type() 不会认为子类是一种父类类型,不考虑继承关系。
isinstance() 会认为子类是一种父类类型,考虑继承关系。
如果要判断两个类型是否相同推荐使用 isinstance()。
# 例一
a = 2
print(isinstance(a,int)) # True
print(isinstance(a,str)) # False

# type() 与 isinstance() 区别
class A:
pass

class B(A):
pass

print("isinstance",isinstance(A(),A)) # isinstance True


print("type",type(A()) == A) # type True

print('isinstance',isinstance(B(),A) ) # isinstance True


print('type',type(B()) == A) # type False
zip 拉链函数
# zip 拉链函数,
# 将对象中对应的元素打包成一个个元组,
# 然后返回由这些元组组成的列表迭代器。
# 如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同。
print(list(zip([0,1,3],[5,6,7],['a','b'])))
# [(0, 5, 'a'), (1, 6, 'b')]
zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个
元组,然后返回由这些元组组成的列表。
>>>a = [1,2,3]
>>> b = [4,5,6]
>>> c = [4,5,6,7,8]
>>> zipped = zip(a,b) # 打包为元组的列表
[(1, 4), (2, 5), (3, 6)]
>>> zip(a,c) # 元素个数与最短的列表一致
[(1, 4), (2, 5), (3, 6)]
>>> zip(*zipped) # 与 zip 相反,可理解为解压,返回二维矩阵式
[(1, 2, 3), (4, 5, 6)]
reduce
'''
reduce() 函数
reduce() 函数会对参数序列中元素进行累积
函数将一个数据集合(链表、元组等)中的所有数据进行下列操作
'''

注意:
Python3 已经将 reduce() 函数从全局名字空间里移除了,它现在被放置在
fucntools 模块里,如果想要使用它,则需要通过引入 functools 模块来调用
reduce() 函数:

from functools import reduce


def add(x,y):
return x + y

print(reduce(add,[1,2,3,4,5]))
# 15

print(reduce(lambda x, y: x+y, [1,2,3,4,5])) # 15

print(reduce(add,range(1,101)))
# 5050

33.filter、map、reduce 的作用
内置函数:map、reduce、filter 的用法和区别
map:根据函数对指定序列做映射
map
参数
接收两个参数:一个是函数,一个是序列(可迭代对象)
返回值
Python2 返回列表
Python3 返回迭代器

# 例子:
# abs() 函数返回数字的绝对值
# 新的内容的个数等于原内容的个数
# ret = map(abs,[-1,-5,6,-7])
# print(list(ret))
# [1, 5, 6, 7]
filter:过滤函数 新的内容少于等于原内容的时候。才能使用 filter
filter() 函数用于过滤序列,过滤不符合条件的元素,返回由符合条件元素组
成的心列表

参数:
function 函数
iterable 可迭代对象
返回值:
返回列表

# 筛选大于 10 的数
def is_odd(x):
if x>10:
return True

ret = filter(is_odd,[1,4,5,7,8,9,76]) # 为迭代器


print(list(ret))
# [76]
reduce:对于序列内所有元素进行累计操作
'''
reduce() 函数
reduce() 函数会对参数序列中元素进行累积
函数将一个数据集合(链表、元组等)中的所有数据进行下列操作
'''

from functools import reduce


def add(x,y):
return x + y

print(reduce(add,[1,2,3,4,5]))
# 15

print(reduce(lambda x, y: x+y, [1,2,3,4,5])) # 15

print(reduce(add,range(1,101)))
# 5050

34.一行代码实现 9*9 乘法表

print('\n'.join([' '.join(['%s*%s=%-2s' % (j, i, i * j) for j in


range(1, i + 1)]) for i in range(1, 10)]))

35.如何安装第三方模块?以及用过哪些第三方模块?
1:pip 包管理器
2:源码下载
-下载
-解压
-python setup.py build
-python setup.py install

用过的第三方模块:requests,pymysql,DbUtils,SQLAlchemy 等

36.常用模块都有那些?

re 模块,os 模块,json 模块,time 模块,


爬虫里面的 requests/beautifulsoup4(bs4)

37.re 的 match 和 search 区别?

re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的
话,match()就返回 none。
re.search 扫描整个字符串并返回第一个成功的匹配。

38.什么是正则的贪婪匹配?

匹配一个字符串没有节制,能匹配多少就去匹配多少,知道没有匹配的为止

39.求结果:

a. [ i % 2 for i in range(10) ]

print([ i % 2 for i in range(10) ]) # [0, 1, 0, 1, 0, 1, 0, 1, 0, 1]


print([ i for i in range(10) ]) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print([ 10 % 2]) # [0]
# %是个运算符。

b. ( i % 2 for i in range(10) )

print(( i % 2 for i in range(10) ))


# <generator object <genexpr> at 0x00000000020CEEB8> 生成器
# 在 Python 中,有一种自定义迭代器的方式,称为生成器(Generator)。
# 定义生成器的两种方式:
# 1.创建一个 generator,只要把一个列表生成式的[]改成(),就创建了一个
generator:
# generator 保存的是算法,每次调用 next(),就计算出下一个元素的值,直
到计算到最后一个元素,
没有更多的元素时,抛出 StopIteration 的错误。
# 2.定义 generator 的另一种方法。如果一个函数定义中包含 yield 关键字,
那么这个函数就不再是一个普通函数,
而是一个 generator

40.求结果:

a. 1 or 2
b. 1 and 2
c. 1 < (2==2)
d. 1 < 2 == 2
>>> 1 or 2
1
>>> 1 and 2
2
>>> 1 < (2==2)
False
>>> 1 < 2 == 2
True

41.def func(a,b=[]) 这种写法有什什么坑?

def func(a,b = []):


b.append(1)
print(a,b)

func(a=2)
func(2)
func(2)

'''
2 [1]
2 [1, 1]
2 [1, 1, 1]
函数的默认参数是一个 list 当第一次执行的时候实例化了一个 list
第二次执行还是用第一次执行的时候实例化的地址存储
所以三次执行的结果就是 [1, 1, 1] 想每次执行只输出[1] ,默认参数应
该设置为 None
'''

42.如何实现 “1,2,3” 变成 [‘1’,’2’,’3’]


list("1,2,3".split(','))

43.如何实现[‘1’,’2’,’3’]变成[1,2,3]

[int(x) for x in ['1','2','3']]

python 里如何把['1','2','3'] 变成[1,2,3]

a = ['1','2','3']
b = [int(i) for i in a]
print(b)
# [1, 2, 3]

44.a = [1,2,3] 和 b = [(1),(2),(3) ] 以及 b = [(1,),(2,),(3,) ] 的区别?

补充:

a=[1,2,3,4,5],b=a 和 b=a[:],有区别么?

a = [1,2,3,4,5]
b = a
b1 = a[:]
print(b) # [1, 2, 3, 4, 5]
# print(b) # [1, 2, 3, 4, 5]

b.append(6)
print("a",a) # a [1, 2, 3, 4, 5, 6]
print("b",b) # b [1, 2, 3, 4, 5, 6] 传递引用
print("b1",b1) # b1 [1, 2, 3, 4, 5] 拷贝
# 一个列表 A=[2,3,4],Python 如何将其转换成 B=[(2,3),(3,4),(4,2)]?
# B = zip(A, A[1:]+A[:1])

45.如何用一行代码生成[1,4,9,16,25,36,49,64,81,100]

[i*i for i in range(1,11)]

46.一⾏代码实现删除列表中重复的值

list(set([1, 2, 3, 4, 45, 1, 2, 343, 2, 2]))

47.如何在函数中设置一个全局变量
python 中的 global 语句是被用来声明全局变量的。

x = 2
def func():
global x
x = 1
return x
func()
print(x) # 1

48.logging 模块的作用?以及应用场景?

logging
模块定义的函数和类为应用程序和库的开发实现了一个灵活的事件日志系统

作用:可以了解程序运行情况,是否正常
在程序的出现故障快速定位出错地方及故障分析

49.请用代码简答实现 stack

l Stack() 创建一个新的空栈
l push(item) 添加一个新的元素 item 到栈顶
l pop() 弹出栈顶元素
l peek() 返回栈顶元素
l is_empty() 判断栈是否为空
l size() 返回栈的元素个数
# 实现一个栈 stack,后进先出

'''
class Stack:
def __init__(self):
self.items = []

def is_empty(self):
# 判断是否为空
return self.items == []

def push(self,item):
# 加入元素
self.items.append(item)

def pop(self):
# 弹出元素
return self.items.pop()

def peek(self):
# 返回栈顶元素
return self.items[len(self.items)-1]

def size(self):
# 返回栈的大小
return len(self.items)

if __name__ == "__main__":
stack = Stack()
stack.push("H")
stack.push("E")
stack.push("L")
print(stack.size()) # 3
print(stack.peek()) # L
print(stack.pop()) # L
print(stack.pop()) # E
print(stack.pop()) # H
'''

50.常用字符串格式化哪几种?

1.占位符%
%d 表示那个位置是整数;%f 表示浮点数;%s 表示字符串。
print('Hello,%s' % 'Python')
print('Hello,%d%s%.2f' % (666, 'Python', 9.99)) # 打印:
Hello,666Python10.00

2.format

print('{k} is {v}'.format(k='python', v='easy')) # 通过关键字


print('{0} is {1}'.format('python', 'easy')) # 通过关键字

51.简述 生成器、迭代器、可迭代对象 以及应用场景?

迭代器
含有__iter__和__next__方法 (包含__next__方法的可迭代对象就是迭代器)
生成器
:包括含有 yield 这个关键字,生成器也是迭代器,调动 next 把函数变成迭代
器。
应用场景:
range/xrange
- py2: range(1000000) ,会立即创建,xrange(1000000)生成器
- py3:range(10000000)生成器
- redis 获取值

conn = Redis(...)

def hscan_iter(self, name, match=None, count=None):

"""

Make an iterator using the HSCAN command so that the client

doesn't

need to remember the cursor position.

``match`` allows for filtering the keys by pattern

``count`` allows for hint the minimum number of returns

"""

cursor = '0'

while cursor != 0:

# 去 redis 中获取数据:12

# cursor,下一次取的位置

# data:本地获取的 12 条数数据

cursor, data = self.hscan(name,

cursor=cursor,match=match, count=count)

for item in data.items():

yield item

stark 组件

def index(request):
data = [

{'k1':1,'name':'alex'},

{'k1':2,'name':'老男孩'},

{'k1':3,'name':'小男孩'},

new_data = []

for item in data:

item['email'] = "xxx@qq.com"

new_data.append(item)

return render(request,'xx.html',{'data':new_data})

可迭代对象

一个类内部实现__iter__方法且返回一个迭代器。

应用场景:
- wtforms 中对 form 对象进行循环时候,显示 form 中包含的所有字段。
class LoginForm(Form):
name = simple.StringField(
label='用户名',
validators=[
validators.DataRequired(message='用户名不能为
空.'),
validators.Length(min=6, max=18, message='用户名
长度必须大于%(min)d 且小于%(max)d')
],
widget=widgets.TextInput(),
render_kw={'class': 'form-control'}
)
pwd = simple.PasswordField(
label='密码',
validators=[
validators.DataRequired(message='密码不能为空.'),
validators.Length(min=8, message='用户名长度必须
大于%(min)d'),
validators.Regexp(regex="^(?=.*[a-z])(?=.*[A-
Z])(?=.*\d)(?=.*[$@$!%*?&])[A-Za-z\d$@$!%*?&]{8,}",
message='密码至少 8 个字符,至少
1 个大写字母,1 个小写字母,1 个数字和 1 个特殊字符')

],
widget=widgets.PasswordInput(),
render_kw={'class': 'form-control'}
)

form = LoginForm()
for item in form:
print(item)

- 列表、字典、元组
装饰器
装饰器:
能够在不修改原函数代码的基础上,在执行前后进行定制操作,闭包函数的一
种应用
场景:
- flask 路由系统
- flask before_request
- csrf
- django 内置认证
- django 缓存
# 手写装饰器;
import functools
def wrapper(func):
@functools.wraps(func) #不改变原函数属性
def inner(*args, **kwargs):
执行函数前
return func(*args, **kwargs)
执行函数后
return inner
1. 执行 wapper 函数,并将被装饰的函数当做参数。 wapper(index)
2. 将第一步的返回值,重新赋值给 新 index = wapper(老 index)
@wrapper #index=wrapper(index)
def index(x):
return x+100
调用装饰器其实是一个闭包函数,为其他函数添加附加功能,不修改被修改的源代
码和不修改被修饰的方式,装饰器的返回值也是一个函数对象。
比如:插入日志、性能测试、事物处理、缓存、权限验证等,有了装饰器,就可以
抽离出大量与函数功能本身无关的雷同代码并继续重用。

52.用 Python 实现一个二分查找的函数。

二分查找算法:简单的说,就是将一个列表先排序好,比如按照从小到大的顺序排
列好,当给定一个数据,比如 3,查找 3 在列表中的位置时,可以先找到列表中间
的数 li[middle]和 3 进行比较,当它比 3 小时,那么 3 一定是在列表的右边,反
之,则 3 在列表的左边,比如它比 3 小,则下次就可以只比较[middle+1, end]的
数,继续使用二分法,将它一分为二,直到找到 3 这个数返回或者列表全部遍历完
成(3 不在列表中)
优点:效率高,时间复杂度为 O(logN);
缺点:数据要是有序的,顺序存储。
li = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

def search(someone, li):


l = -1
h = len(li)

while l + 1 != h:
m = int((l + h) / 2)
if li[m] < someone:
l = m
else:
h = m
p = h
if p >= len(li) or li[p] != someone:
print("元素不存在")
else:
str = "元素索引为%d" % p
print(str)

search(3, li) # 元素索引为 2

53.谈谈你对闭包的理解?

ef foo():
m=3
n=5
def bar():
a=4
return m+n+a
return bar

>>>bar = foo()
>>>bar()
12
说明:
bar 在 foo 函数的代码块中定义。我们称 bar 是 foo 的内部函数。
在 bar 的局部作用域中可以直接访问 foo 局部作用域中定义的 m、n 变量。
简单的说,这种内部函数可以使用外部函数变量的行为,就叫闭包。

闭包的意义与应用

54. os 和 sys 模块的作用?

os 模块负责程序与操作系统的交互,提供了访问操作系统底层的接口;
sys 模块负责程序与 python 解释器的交互,提供了一系列的函数和变量,用于操
控 python 的运行时环境。
os 与 sys 模块的官方解释如下:
os: This module provides a portable way of using operating system
dependent functionality.
这个模块提供了一种方便的使用操作系统函数的方法。
sys: This module provides access to some variables used or maintained
by the interpreter and to
functions that interact strongly with the interpreter.
这个模块可供访问由解释器使用或维护的变量和与解释器进行交互的函数。
os 常用方法
os.remove() 删除文件
os.rename() 重命名文件
os.walk() 生成目录树下的所有文件名
os.chdir() 改变目录
os.mkdir/makedirs 创建目录/多层目录
os.rmdir/removedirs 删除目录/多层目录
os.listdir() 列出指定目录的文件
os.getcwd() 取得当前工作目录
os.chmod() 改变目录权限
os.path.basename() 去掉目录路径,返回文件名
os.path.dirname() 去掉文件名,返回目录路径
os.path.join() 将分离的各部分组合成一个路径名
os.path.split() 返回( dirname(), basename())元组
os.path.splitext() 返回 (filename, extension) 元组
os.path.getatime\ctime\mtime 分别返回最近访问、创建、修改时间
os.path.getsize() 返回文件大小
os.path.exists() 是否存在
os.path.isabs() 是否为绝对路径
os.path.isdir() 是否为目录
os.path.isfile() 是否为文件
sys 常用方法
sys.argv 命令行参数 List,第一个元素是程序本身路径
sys.modules.keys() 返回所有已经导入的模块列表
sys.exc_info() 获取当前正在处理的异常类,exc_type、exc_value、
exc_traceback 当前处理的异常详细信息
sys.exit(n) 退出程序,正常退出时 exit(0)
sys.hexversion 获取 Python 解释程序的版本值,16 进制格式如:0x020403F0
sys.version 获取 Python 解释程序的版本信息
sys.maxint 最大的 Int 值
sys.maxunicode 最大的 Unicode 值
sys.modules 返回系统导入的模块字段,key 是模块名,value 是模块
sys.path 返回模块的搜索路径,初始化时使用 PYTHONPATH 环境变量的值
sys.platform 返回操作系统平台名称
sys.stdout 标准输出
sys.stdin 标准输入
sys.stderr 错误输出
sys.exc_clear() 用来清除当前线程所出现的当前的或最近的错误信息
sys.exec_prefix 返回平台独立的 python 文件安装的位置
sys.byteorder 本地字节规则的指示器,big-endian 平台的值是
'big',little-endian 平台的值是'little'
sys.copyright 记录 python 版权相关的东西
sys.api_version 解释器的 C 的 API 版本
总结:
os 模块负责程序与操作系统的交互,提供了访问操作系统底层的接口;
sys 模块负责程序与 python 解释器的交互,提供了一系列的函数和变量,用于
操控 python 的运行时环境。

55. 如何生成一个随机数?

import random

print(random.random()) # 用于生成一个 0 到 1 的随机符点数: 0


<= n < 1.0
print(random.randint(1, 1000)) # 用于生成一个指定范围内的整数

56. 如何使用 python 删除一个文件?

import os
file = r'D:\test.txt'
if os.path.exists(file):
os.remove(file)
print('delete success')
else:
print('no such file:%s' % file)

57. 谈谈你对面向对象的理解

三大特性以及解释?
面对对象是一种编程思想,以类的眼光来来看待事物的一种方式。将有共同的属性
和方法的事物封装到同一个类下面。

继承:将多个类的共同属性和方法封装到一个父类下面,然后在用这些类来继承这
个类的属性和方法

封装:将有共同的属性和方法封装到同一个类下面

• 第一层面:创建类和对象会分别创建二者的名称空间,我们只能用类名.或

者 obj.的方式去访问里面的名字,这本身就是一种封装

• 第二层面:类中把某些属性和方法隐藏起来(或者说定义成私有的),只在类

的内部使用、外部无法访问,或者留下少量接口(函数)供外部访问。

多态:Python 天生是支持多态的。指的是基类的同一个方法在不同的派生类中有

着不同的功能

58. Python 面向对象中的继承有什么特点

继承概念的实现方式主要有 2 类:实现继承、接口继承。

实现继承是指使用基类的属性和方法而无需额外编码的能力;
接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能
力(子类重构爹类方法);
python 两种类:经典类 新式类
python3 新式类 —— 都默认继承 object class Animal(object): == class
Animal:
python2 经典类和新式类 并存
class Animal: 经典类 —— 继承顺序 个别使用方法
class Animal(object): 新式类
继承分为单继承和多继承
Python 是支持多继承的
如果没有指定基类,python 的类会默认继承 object 类,object 是所有 python
类的基类,它提供了一些常见方法(如__str__)的实现。

补充继承的应用(面试题)

1、对象可以调用自己本类和父类的所有方法和属性, 先调用自己的 自己没有


才调父类的。谁(对象)调用方法,方法中的 self 就指向谁

class Foo:
def __init__(self):
self.func()

def func(self):
print('Foo.func')

class Son(Foo):
def func(self):
print('Son.func')

s = Son()
# Son.func

========================================================
class A:
def get(self):
self.say()

def say(self):
print('AAAAA')

class B(A):
def say(self):
print('BBBBB')

b = B()
b.get() #输出结果为:BBBBB

59. 面向对象深度优先和广度优先是什么?

Python 的类可以继承多个类,Python 的类如果继承了多个类,那么其寻找方法


的方式有两种
当类是经典类时,多继承情况下,会按照深度优先方式查找 py3
当类是新式类时,多继承情况下,会按照广度优先方式查找 py2
简单点说就是:经典类是纵向查找,新式类是横向查找
经典类和新式类的区别就是,在声明类的时候,新式类需要加上 object 关键
字。在 python3 中默认全是新式类

60. 面向对象中 super 的作用?

用于子类继承基类的方法
class FooParent(object):
def __init__(self):
self.parent = 'I\'m the parent.'
print('Parent')
print('1111')

def bar(self, message):


print("%s from Parent" % message)

class FooChild(FooParent):
def __init__(self):
# super(FooChild,self) 首先找到 FooChild 的父类(就是类
FooParent),然后把类 B 的对象 FooChild 转换为类 FooParent 的对象
super(FooChild, self).__init__()
print('Child')

# def bar(self, message):


# # super(FooChild, self).bar(message)
# print('Child bar fuction')
# print(self.parent)

if __name__ == '__main__':
fooChild = FooChild()
fooChild.bar('HelloWorld')

61. 是否使用过 functools 中的函数?其作用是什么?

用于修复装饰器

import functools

def deco(func):
@functools.wraps(func) # 加在最内层函数正上方
def wrapper(*args, **kwargs):
return func(*args, **kwargs)

return wrapper

@deco
def index():
'''哈哈哈哈'''
x = 10
print('from index')

print(index.__name__)
print(index.__doc__)

# 加@functools.wraps
# index
# 哈哈哈哈

# 不加@functools.wraps
# wrapper
# None

62. 列举面向对象中带双下划线的特殊方法,如:__new__、__init__

__new__:生成实例
__init__:生成实例的属性
__call__:实例对象加( )会执行 def __call__:... 方法里边的内容。
__del__:析构方法,当对象在内存中被释放时,自动触发执行。如当 del obj 或
者应用程序运行完毕时,执行该方法里边的内容。
__enter__和__exit__:出现 with 语句,对象的__enter__被触发,有返回值则赋值
给 as 声明的变量;with 中代码块执行完毕时执行__exit__里边的内容。
__module__:表示当前操作的对象在那个模块 obj.__module__
__class__ :表示当前操作的对象的类是什么 obj.__class__
__doc__:类的描述信息,该描述信息无法被继承
__str__:改变对象的字符串显示 print 函数 --->obj.__str__()
__repr__:改变对象的字符串显示 交互式解释器 --->obj.__repr__()
__format__:自定制格式化字符串
__slots__:一个类变量 用来限制实例可以添加的属性的数量和类型
__setitem__,__getitem,__delitem__:
class Foo:
def __init__(self,name):
self.name=name

def __getitem__(self, item):


print(self.__dict__[item])

def __setitem__(self, key, value):


self.__dict__[key]=value
def __delitem__(self, key):
print('del obj[key]时,我执行')
self.__dict__.pop(key)
def __delattr__(self, item):
print('del obj.key 时,我执行')
self.__dict__.pop(item)

f1=Foo('sb')
f1['age']=18
f1['age1']=19
del f1.age1
del f1['age']
f1['name']='alex'
print(f1.__dict__)
__get__():调用一个属性时,触发
__set__():为一个属性赋值时,触发
__delete__():采用 del 删除属性时,触发
__setattr__,__delattr__,__getattr__ :

63. 如何判断是函数还是方法?

看他的调用者是谁,如果是类,就需要传入一个参数 self 的值,这时他就是一个


函数,
如果调用者是对象,就不需要给 self 传入参数值,这时他就是一个方法
print(isinstance(obj.func, FunctionType)) # False
print(isinstance(obj.func, MethodType)) # True
class Foo(object):
def __init__(self):
self.name = 'lcg'

def func(self):
print(self.name)

obj = Foo()
print(obj.func) # <bound method Foo.func of <__main__.Foo object at
0x000001ABC0F15F98>>

print(Foo.func) # <function Foo.func at 0x000001ABC1F45BF8>

# ------------------------FunctionType, MethodType------------#

from types import FunctionType, MethodType

obj = Foo()
print(isinstance(obj.func, FunctionType)) # False
print(isinstance(obj.func, MethodType)) # True

print(isinstance(Foo.func, FunctionType)) # True


print(isinstance(Foo.func, MethodType)) # False

# ------------------------------------------------------------#
obj = Foo()
Foo.func(obj) # lcg

obj = Foo()
obj.func() # lcg

"""
注意:
方法,无需传入 self 参数
函数,必须手动传入 self 参数
"""

64. 静态方法和类方法区别?

尽管 classmethod 和 staticmethod 非常相似,但在用法上依然有一些明显的区


别。classmethod 必须有一个指向类对象的引用作为第一个参数,而
staticmethod 可以没有任何参数。

举个栗子:

class Num:
# 普通方法:能用 Num 调用而不能用实例化对象调用
def one():
print ('1')

# 实例方法:能用实例化对象调用而不能用 Num 调用
def two(self):
print ('2')

# 静态方法:能用 Num 和实例化对象调用


@staticmethod
def three():
print ('3')

# 类方法:第一个参数 cls 长什么样不重要,都是指 Num 类本身,调用时


将 Num 类作为对象隐式地传入方法
@classmethod
def go(cls):
cls.three()

Num.one() #1
#Num.two() #TypeError: two() missing 1 required positional
argument: 'self'
Num.three() #3
Num.go() #3

i=Num()
#i.one() #TypeError: one() takes 0 positional arguments but
1 was given
i.two() #2
i.three() #3
i.go() #3

65. 列举面向对象中的特殊成员以及应用场景

__call__
__new__
__init__
__doc__
__class__
__del__
__dict__
__str__
在 falsk 源码用到......

66. 1、2、3、4、5 能组成多少个互不相同且无重复的三位数

60 个
题意理解:组成后的数值不相同,且组合的三个位数之间数字不重复。
使用 python 内置的排列组合函数(不放回抽样排列)
product 笛卡尔积 (有放回抽样排列)
permutations 排列 (不放回抽样排列)
combinations 组合,没有重复 (不放回抽样组合)
combinations_with_replacement 组合,有重复 (有放回抽样组合)
import itertools

print(len(list(itertools.permutations('12345', 3)))) # 60

67. 什么是反射?以及应⽤用场景?

反射的核心本质就是以字符串的形式去导入个模块,利用字符串的形式去执行
函数。
Django 中的 CBV 就是基于反射实现的。

68. metaclass 作用?以及应用场景?

metaclass 用来指定类是由谁创建的。
类的 metaclass 默认是 type。我们也可以指定类的 metaclass 值。在 python3
中:
class MyType(type):
def __call__(self, *args, **kwargs):
return 'MyType'

class Foo(object, metaclass=MyType):


def __init__(self):
return 'init'

def __new__(cls, *args, **kwargs):


return cls.__init__(cls)

def __call__(self, *args, **kwargs):


return 'call'

obj = Foo()
print(obj) # MyType
69. 用尽量多的方法实现单例模式。

1:使用模块
Python 的模块就是天然的单例模式。
因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加
载 .pyc 文件,而不会再次执行模块代码。
因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例
对象了。
例如:
class V1(object):
def foo(self)
pass
V1 = V1()
将上面代码保存在文件 test.py,要使用时,直接在其他文件中导入此文件中的
对象,这个对象既是单例模式的对象

如:from a import V1

2:使用装饰器
def Singleton(cls):
_instance = {}
def _singleton(*args, **kargs):
if cls not in _instance:
_instance[cls] = cls(*args, **kargs)
return _instance[cls]
return _singleton
@Singleton
class A(object):
a = 1
def __init__(self, x=0):
self.x = x
a1 = A(2)
a2 = A(3)

3:使用类
4:基于__new__方法实现
当我们实例化一个对象时,是先执行了类的__new__方法
当:(我们没写时,默认调用 object.__new__),实例化对象;然后再执行类
的__init__方法,对这个对象进行初始化,所有我们可以基于这个,实现单例
模式

70. 装饰器器的写法以及应用场景。

含义:装饰器本质就是函数,为其他函数添加附加功能
原则:
不修改被修饰函数的代码
不修改被修饰函数的调用方式
应用场景:
无参装饰器在用户登录 认证中常见
有参装饰器在 flask 的路由系统中见到过
import functools
def wrapper(func):
@functools.wraps(func)
def inner(*args, **kwargs):
print('我是装饰器')
return func
return inner

@wrapper
def index():
print('我是被装饰函数')
return None
index()

# 应用场景
- 高阶函数
- 闭包
- 装饰器
- functools.wraps(func)
71. 异常处理写法以及如何主动跑出异常(应用场景)

# 触发异常
def temp_convert(var):
try:
return int(var)
except ValueError as Argument:
print ("参数没有包含数字%s"%Argument)

# 调用函数
temp_convert("xyz")
# 以 10 为基数的 int()的无效文字:“xyz”

---------------------------------------------------------------------
-------
# raise 语法
#raise [Exception [, args [, traceback]]]
# 语句中 Exception 是异常的类型,args 是自已提供的异常参数。

class Networkerror(RuntimeError):
def __init__(self, arg):
self.args = arg
try:
raise Networkerror("Bad hostname")
except Networkerror as e:
print(e.args)

72、什么是面向对象的 mro

mro 就是方法解析顺序

73. isinstance 作用以及应用场景?

isinstance(对象,类) 判断这个对象是不是这个类或者这个类的子类的实例化
# # 判断 a 属不属于 A 这个类(可以判断到祖宗类)
class A:
pass

class B(A):
pass
a = A()
b = B()
print(isinstance(b,A)) # ===> True 判断到祖宗类
# 任何与 object 都是 True,内部都继承 object
class A:pass
a = A() # 实例化
print(isinstance(a,object)) # True
应用场景:rest framework 认证的流程
scrapy-redis

74. 写代码并实现

Given an array of integers, return indices of the two numbers such


that they add up to a
specific target.You may assume that each input would have exactly one
solution, and you may
not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1]

75. json 序列化时,可以处理的数据类型有哪些?如何定制支持 datetime 类

型?

76. json 序列化时,默认遇到中文会转换成 unicode,如果想要保留中文怎么

办?
在序列化时,中文汉字总是被转换为 unicode 码,在 dumps 函数中添加参数
ensure_ascii=False 即可解决。

77. 什么是断言?应用场景?

assert 是的作用?断言
条件成立(布尔值为 True)则继续往下,否则跑出异常,一般用于:满足某个
条件之后,才能执行,否则应该跑出异常。

写 API 的时候,继承 GenericAPIView

class GenericAPIView(views.APIView):
"""
Base class for all other generic views.
"""
# You'll need to either set these attributes,
# or override
`get_queryset()`/`get_serializer_class()`.
# If you are overriding a view method, it is
important that you call
# `get_queryset()` instead of accessing the
`queryset` property directly,
# as `queryset` will get evaluated only once, and
those results are cached
# for all subsequent requests.
queryset = None
serializer_class = None

# If you want to use object lookups other than


pk, set 'lookup_field'.
# For more complex lookup requirements override
`get_object()`.
lookup_field = 'pk'
lookup_url_kwarg = None

# The filter backend classes to use for queryset


filtering
filter_backends =
api_settings.DEFAULT_FILTER_BACKENDS

# The style to use for queryset pagination.


pagination_class =
api_settings.DEFAULT_PAGINATION_CLASS

def get_queryset(self):

assert self.queryset is not None, (


"'%s' should either include a `queryset`
attribute, "
"or override the `get_queryset()`
method."
% self.__class__.__name__
)

queryset = self.queryset
if isinstance(queryset, QuerySet):
# Ensure queryset is re-evaluated on each
request.
queryset = queryset.all()
return queryset

78. 有用过 with statement 吗?它的好处是什么?

79. 使用代码实现查看列举目录下的所有文件。

80. 简述 yield 和 yield from 关键字

第二部分 网络编程和并发

81. 简述 OSI 七层协议。

物理层:主要是基于电器特性发送高低电压(电信号),高电压对应数字 1,低电
压对应数字 0
数据链路层:定义了电信号的分组方式
网路层:引入一套新的地址用来区分不同的广播域/子网,这套地址即网络地址
传输层:建立端口到端口的通信
会话层:建立客户端与服务端连接
表示层:对来自应用层的命令和数据进行解释,按照一定格式传给会话层。如编
码、数据格式转换、加密解密、压缩解压
应用层:规定应用程序的数据格式

82. 什么是 C/S 和 B/S 架构?

c/s 架构,就是 client(客户端)与 server(服务端)即:客户端与服务端的架


构。
b/s 架构,就是 brosver(浏览器端)与 sever(服务端)即:浏览器端与服务端
架构
优点:统一了所有应用程序的入口、方便、轻量级

83. 简述 三次握手、四次挥手的流程。

三次握手:
第一次握手
1:客户端先向服务端发起一次询问建立连接的请求,并随机生成一个值作为标

第二次握手
2:服务端向客户端先回应第一个标识,再重新发一个确认标识
第三次握手
3:客户端确认标识,建立连接,开始传输数据

四次挥手 ---> 断开连接


第一次挥手
客户端向服务端发起请求断开连接的请求
第二次挥手
服务端向客户端确认请求
第三次挥手
服务端向客户端发起断开连接请求
第四次挥手
客户端向服务端确认断开请求

84. TCP 和 UDP 的区别?

TCP/UDP 区别
TCP 协议是面向连接,保证高可靠性传输层协议
UDP:数据丢失,无秩序的传输层协议(qq 基于 udp 协议)

85. 为何基于 tcp 协议的通信比基于 udp 协议的通信更可靠?

tcp:可靠,因为只要对方回了确认收到信息,才发下一个,如果没收到确认信
息就重发
UDP:不可靠,它是一直发数据,不需要对方回应
流式协议: TCP 协议,可靠传输
数据报协议: UDP 协议,不可传输

86. 什么是 socket?简述基于 tcp 协议的套接字通信流程。

Socket 是应用层与 TCP/IP 协议族通信的中间软件抽象层,它是一组接口。


在设计模式中,Socket 其实就是一个门面模式,它把复杂的 TCP/IP 协议族隐
藏在 Socket 接口后面,
对用户来说,一组简单的接口就是全部。

服务端:
创建 socket 对象,
绑定 ip 端口 bind(),
设置最大链接数 listen(),
accept()与客户端的 connect()创建双向管道,等到联接,
send(), recv(), 收发数据
close()

客户端:
创建 socket 对象,
connect()与服务端 accept()创建双向管道 ,
send(),
recv(),
close()

87. 什么是粘包? socket 中造成粘包的原因是什什么? 哪些情况会发生粘

包现象?

只有 TCP 有粘包现象,UDP 永远不会粘包


粘包:在获取数据时,出现数据的内容不是本应该接收的数据,如:对方第一次发
送 hello,第二次发送 world,
我方接收时,应该收两次,一次是 hello,一次是 world,但事实上是一次收到
helloworld,一次收到空,这种现象叫粘包

原因
粘包问题主要还是因为接收方不知道消息之间的界限,不知道一次性提取多少
字节的数据所造成的。

什么情况会发生:
1、发送端需要等缓冲区满才发送出去,造成粘包(发送数据时间间隔很短,数
据了很小,会合到一起,产生粘包)
2、接收方不及时接收缓冲区的包,造成多个包接收(客户端发送了一段数据,
服务端只收了一小部分,
服务端下次再收的时候还是从缓冲区拿上次遗留的数据,产生粘包)

88. IO 多路复的作用?

socketserver,多个客户端连接,单线程下实现并发效果,就叫多路复用。
与多进程和多线程技术相比,I/O 多路复用技术的最大优势是系统开销小,系统不
必创建进程/线程,也不必维护这些进程/线程,从而大大减小了系统的开销。

89.select、poll、epoll 模型的区别?(属于多路复用 IO 的模型)

都是 i/o 多路复用的机制,监视多个 socket 是否发生变化,本质上都是同步


i/o
select,poll 实现需要自己不断轮询所有监测对象,直到对象发生变化,
在这个阶段中,
可能要睡眠和唤醒多次交替,而 epoll 也需要调用 epoll_wait 不断轮询就绪链
表,但是当对象发生变化时,
会调用回调函数,将变化的对象放入就绪链接表中,并唤醒在 epoll_wait 中进
入睡眠的进程。
虽然都会睡眠和唤醒,但是 select 和 poll 在被唤醒的时候要遍历整个监测对
象集合,
而 epoll 只要判断就绪链表是否为空即可,节省了大量 cpu 的时间

select、poll、epoll 都是 IO 多路复用的机制,但 select,poll,epoll 本


质上都是同步 I/O,
因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程
是阻塞的.

FD(文件描述符)
select 模型
优点:
1:可移植性好,在某些 Unix 系统不支持 poll()
2:对于超时值提供了更好的精度:微妙,而 poll 是毫秒
缺点:
1:最大并发数限制,因为一个进程所打开的 FD (文件描述符)是有限制
的,由 FD_SETSIZE 设置,默认值是 1024/2048 ,因此 Select 模型的最大并
发数就被相应限制了。
2:效率问题,select 每次调用都会线性扫描全部的 FD 集合,所以将
FD_SETSIZE 改大,会越慢
3:需要维护一个用来存放大量 fd 的数据结构,这样会使得用户空间和内
核空间在传递该结构时复制开销大。
poll 本质上和 select 没有区别,它将用户传入的数组拷贝到内核空间,
它没有最大连接数的限制,原因是它基于链表来存储的但是同样有一个缺点:
大量的 fd 的数组被整体复制于用户态和内核地址空间,而不管这样的复制是不
是有意义

90. 什么是防火墙以及作用?

防火墙是一个分离器、一个限制器,也是一个分析器,有效地监控了内部网和
Internet 之间的任何活动,保证了内部网络的安全

作用
防火墙是网络安全的屏障
可以强化网络安全策略
对网络存取和访问进行监控审计
防止内部信息的外泄
除了安全作用,防火墙还支持具有 Internet 服务特性的企业内部网络技术体系
VPN(虚拟专用网)。

91. 简述 进程、线程、协程的区别 以及应用场景?

线程是指进程内的一个执行单元,
# 进程
进程拥有自己独立的堆和栈,既不共享堆,亦不共享栈,进程由操作系统调
度。
# 线程
线程拥有自己独立的栈和共享的堆,共享堆,不共享栈,线程亦由操作系统调

# 协程和线程
协程避免了无意义的调度,由此可以提高性能;但同时协程也失去了线程使用
多 CPU 的能力

进程与线程的区别
(1)地址空间:线程是进程内的一个执行单位,进程内至少有一个线程,他们
共享进程的地址空间,而进程有自己独立的地址空间
(2)资源拥有:进程是资源分配和拥有的单位,同一个进程内线程共享进程的
资源
(3)线程是处理器调度的基本单位,但进程不是
(4)二者均可并发执行
(5)每个独立的线程有一个程序运行的入口

协程与线程
(1)一个线程可以有多个协程,一个进程也可以单独拥有多个协程,这样
Python 中则能使用多核 CPU
(2)线程进程都是同步机制,而协程是异步
(3)协程能保留上一次调用时的状态

92. GIL 锁是什么?

GIL 本质就是一把互斥锁,既然是互斥锁,所有互斥锁的本质都一样,都是将并发
运行变成串行,以此来控制同一时间内共享数据只能被一个任务所修改,进而保证
数据安全。
GIL 保护的是解释器级的数据,保护用户自己的数据则需要自己加锁处理
应用(总结):
多线程用于 IO 密集型,如 socket,爬虫,web
多进程用于计算密集型,如金融分析
1. 每个 cpython 进程内都有一个 GIL
2. GIL 导致同一进程内多个进程同一时间只能有一个运行
3. 之所以有 GIL,是因为 Cpython 的内存管理不是线程安全的
4. 对于计算密集型用多进程,多 IO 密集型用多线程

93. Python 中如何使用线程池和进程池?

94. threading.local 的作用?

实现线程局部变量的传递。
ThreadLocal 最常用的地方:
为每个线程绑定一个资源(数据库连接,HTTP 请求,用户身份信息等),这样一
个线程的所有调用到的处理函数都可以非常方便地访问这些资源。

95. 进程之间如何进行通信?

文件、信号、消息队列….

96. 什么是并发和并行?
# 并发:同一时刻只能处理一个任务,但一个时段内可以对多个任务进行交替
处理(一个处理器同时处理多个任务)
# 并行:同一时刻可以处理多个任务(多个处理器或者是多核的处理器同时处理
多个不同的任务)
# 类比:并发是一个人同时吃三个馒头,而并行是三个人同时吃三个馒头。

97. 进程锁和线程锁的作用?

98. 解释什么是异步非阻塞?

非阻塞:不等待
即:遇到 IO 阻塞不等待(setblooking=False),(可能会报错->捕捉异常)
- sk=socket.socket()
- sk.setblooking(False)
异步:回调,当达到某个指定的状态之后,自动调用特定函数

实例
nb_async.py 实现异步非阻塞的模块

异步体现在回调上,回调就是有消息返回时告知一声儿进程进行处理。非阻塞
就是不等待,不需要进程等待下去,继续执行其他操作,不管其他进程的状
态。

99. 路由器和交换机的区别

1:交换机:是负责内网里面的数据传递(arp 协议)根据 MAC 地址寻址


路由器:在网络层,路由器根据路由表,寻找该 ip 的网段
2:路由器可以处理 TCP/IP 协议
3:路由器可以把一个 IP 分配给很多个主机使用,这些主机对外只表现出一个
IP。
交换机可以把很多主机连起来,这些主机对外各有各的 IP。
4:交换机是做端口扩展的,也就是让局域网可以连进来更多的电脑。
路由器是用来做网络连接,也就是;连接不同的网络

100.什么是域名解析?

在互联网上,所有的地址都是 ip 地址,现阶段主要是 IPv4(比如:


110.110.110.110)。
但是这些 ip 地址太难记了,所以就出现了域名(比如 http://baidu.com)。
域名解析就是将域名,转换为 ip 地址的这样一种行为。

101.如何修改本地 hosts 件?

Hosts 是一个没有扩展名的系统文件,可以用记事本等工具打开,其作用就是
将一些常用的网址域名与其对应的 IP 地址建立一个关联“数据库”,
当用户在浏览器中输入一个需要登录的网址时,系统会首先自动从 Hosts 文件
中寻找对应的 IP 地址,
一旦找到,系统会立即打开对应网页,如果没有找到,则系统会再将网址提交
DNS 域名解析服务器进行 IP 地址的解析。

浏览器访问网站,要首先通过 DNS 服务器把要访问的网站域名解析成一个唯一


的 IP 地址,之后,浏览器才能对此网站进行定位并且访问其数据。

文件路径:C:\WINDOWS\system32\drivers\etc。
将 127.0.0.1 www.163.com 添加在最下面
修改后用浏览器访问“www.163.com”会被解析到 127.0.0.1,导致无法显示该
网页。

102.生产者消费者模型应用场景及优势?

生产者与消费者模式是通过一个容器来解决生产者与消费者的强耦合关系,生
产者与消费者之间不直接进行通讯,
而是利用阻塞队列来进行通讯,生产者生成数据后直接丢给阻塞队列,消费者
需要数据则从阻塞队列获取,
实际应用中,生产者与消费者模式则主要解决生产者与消费者生产与消费的速
率不一致的问题,达到平衡生产者与消费者的处理能力,而阻塞队列则相当于
缓冲区。

应用场景:用户提交订单,订单进入引擎的阻塞队列中,由专门的线程从阻塞
队列中获取数据并处理

优势:
1;解耦
假设生产者和消费者分别是两个类。如果让生产者直接调用消费者的某个方
法,那么生产者对于消费者就会产生依赖(也就是耦合)。
将来如果消费者的代码发生变化,可能会影响到生产者。而如果两者都依赖于
某个缓冲区,两者之间不直接依赖,耦合也就相应降低了。
2:支持并发
生产者直接调用消费者的某个方法,还有另一个弊端。由于函数调用是同步的
(或者叫阻塞的),在消费者的方法没有返回之前,生产者只能一直等着
而使用这个模型,生产者把制造出来的数据只需要放在缓冲区即可,不需要等
待消费者来取

3:支持忙闲不均
缓冲区还有另一个好处。如果制造数据的速度时快时慢,缓冲区的好处就体现
出来了。
当数据制造快的时候,消费者来不及处理,未处理的数据可以暂时存在缓冲区
中。等生产者的制造速度慢下来,消费者再慢慢处理掉。

103.什么是 cdn?

目的是使用户可以就近到服务器取得所需内容,解决 Internet 网络拥挤的状


况,提高用户访问网站的响应速度。

cdn 即内容分发网络

104.LVS 是什么及作用?

LVS :Linux 虚拟服务器


作用:LVS 主要用于多服务器的负载均衡。
它工作在网络层,可以实现高性能,高可用的服务器集群技术。
它廉价,可把许多低性能的服务器组合在一起形成一个超级服务器。
它易用,配置非常简单,且有多种负载均衡的方法。
它稳定可靠,即使在集群的服务器中某台服务器无法正常工作,也不影响整体
效果。另外可扩展性也非常好。

105.Nginx 是什么及作用?

106.keepalived 是什么及作用?

107.haproxy 是什么以及作用?

108.什么是负载均衡?

109.什么是 rpc 及应用场景?

110.简述 asynio 模块的作用和应用场景。

111.简述 gevent 模块的作用和应用场景。

112.twisted 框架的使用和应用

数据库和缓存

113.列举常见的关系型数据库和非关系型都有那些?
关系型数据库(需要有表结构)
mysql、oracle 、 spl、server、db2、sybase

非关系型数据库(是以 key-value 存储的,没有表结构)(NoSQL)


MongoDB
MongoDB 是一个高性能,开源,无模式的文档型数据库,开发语言是 C++。它
在许多场景下可用于替代传统的关系型数据库或键/值存储方式。
Redis
Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化
的日志型、Key-Value 数据库,并提供多种语言的 API。目前由 VMware 主持开
发工作。

114.MySQL 常见数据库引擎及比较?

InnoDB
支持事务
支持表锁、行锁(for update)
表锁:select * from tb for update
行锁:select id,name from tb where id=2 for update

myisam
查询速度快
全文索引
支持表锁
表锁:select * from tb for update

NDB
高可用、 高性能、高可扩展性的数据库集群系统

Memory
默认使用的是哈希索引

115.简述数据库三大范式?

数据库的三大特性:
'实体':表
'属性':表中的数据(字段)
'关系':表与表之间的关系
----------------------------------------------------
# 数据库设计三大范式:
1:确保每列保持原子性(即数据库表中的所有字段值是不可分解的原子值)

2:确保表中的每列都是和主键相关(表中只能保存一种数据,不可以把多种数
据保存在同一张表中)--->完全属于当前表的数据
3:确保每列都和主键直接相关,而不是间接相关(在一个数据库表中保存的数
据只能与主键相关)----> 消除传递依赖(间接)
比如在设计一个订单数据表的时候,可以将客户编号作为一个外键和订单表建
立相应的关系。
而不可以在订单表中添加关于客户其它信息(比如姓名、所属公司等)的字
段。
数据库五大约束'
1.primary KEY:设置主键约束;
2.UNIQUE:设置唯一性约束,不能有重复值;
3.DEFAULT 默认值约束
4.NOT NULL:设置非空约束,该字段不能为空;
5.FOREIGN key :设置外键约束。

116、什么是事务?MySQL 如何支持事务?

事务用于将某些操作的多个 SQL 作为原子性操作,一旦有某一个出现错误,即


可回滚到原来的状态,从而保证数据库数据完整性。

事务的特性:
原子性: 确保工作单元内的所有操作都成功完成,否则事务将被中止在故障
点,和以前的操作将回滚到以前的状态。
一致性: 确保数据库正确地改变状态后,成功提交的事务。
隔离性: 使事务操作彼此独立的和透明的。
持久性: 确保提交的事务的结果或效果的系统出现故障的情况下仍然存在。

Mysql 实现事务
InnoDB 支持事务,MyISAM 不支持
# 启动事务:
# start transaction;
# update from account set money=money-100 where name='a';
# update from account set money=money+100 where name='b';
# commit;
'start transaction 手动开启事务,commit 手动关闭事务'

117.简述数据库设计中一对多和多对多的应用场景?

FK(一对多)
下拉框里面的数据就需要用 FK 关联另一张表

M2M(多对多)
多选的下拉框,或者 checkbox
118.如何基于数据库实现商城商品计数器?

119.常见 SQL(必备)

group by 分组对聚合的条件进行筛选需要通过 havhing

SQL 的 left join 、right join、inner join 之间的区别


left join (左连接) 返回包括左表中的所有记录和右表中联结字段相等的记录
right join(右连接) 返回包括右表中的所有记录 1 和左表中联结字段相等的记

inner join(内连接): 只返回两个表中联结字段相等的行

https://www.luffycity.com/

120.简述触发器、函数、视图、存储过程?

触发器:
对数据库某张表的增加、删除,修改前后定义一些操作

函数:(触发函数是通过 select)
聚合函数:max/sum/min/avg
时间格式化:date_format
字符串拼接:concat

存储过程:
将 SQL 语句保存到数据库中,并命名,以后在代码调用时,直接调用名称即可
参数类型:
in 只将参数传进去
out 只拿结果
inout 既可以传,可以取

函数与存储过程区别:
本质上没区别。只是函数有如:只能返回一个变量的限制。而存储过程可以返
回多个。而函数是可以嵌入在 sql 中使用的,可以在 select 中调用,而存储过
程不行。

视图:
视图是一个虚拟表,不是真实存在的(只能查,不能改)

121.MySQL 索引种类

单列
功能
普通索引:加速查找
唯一索引:加速查找 + 约束:不能重复(只能有一个空,不然就重复了)
主键(primay key):加速查找 + 约束:不能重复 + 不能为空
多列
联合索引(多个列创建索引)-----> 相当于单列的普通索引
联合唯一索引 -----> 相当于单列的唯一索引
ps:联合索引的特点:遵循最左前缀的规则
其他词语:
·· - 索引合并,利用多个单例索引查询;(例如在数据库查用户名和密码,
分别给用户名和密码建立索引)
- 覆盖索引,在索引表中就能将想要的数据查询到;

122.索引在什么情况下遵循最左前缀的规则?

联合索引

123.主键和外键的区别?

主键是能确定一条记录的唯一标示。例如,身份证证号

外键:用于与另一张表的关联,是能确定另一张表记录的字段,用于保持数据
的一致性
主键 外键

定 唯一标识一条记录,不能有重复 表的外键是另一张表的主键,外键可以
义 的,不允许为空 有重复的,可以为空


用来保证数据完整性 用来与其他表建立联系的


主键只能有一个 一个表可以有多个外键

124.MySQL 常见的函数?

聚合函数
max/sum/min/avg

时间格式化
date_format
字符串拼接
concat(当拼接了 null,则返回 null)

截取字符串
substring

返回字节个数
length

125.列举 创建索引但是无法命中索引的 8 种情况。

1.- like '%xx'


select * from tb1 where name like '%cn';
2.- 使用函数
select * from tb1 where reverse(name) = 'wupeiqi';
3.- or
select * from tb1 where nid = 1 or email = 'seven@live.com';
特别的:当 or 条件中有未建立索引的列才失效,以下会走索引
select * from tb1 where nid = 1 or name = 'seven';
select * from tb1 where nid = 1 or email =
'seven@live.com' and name = 'alex'
4.- 类型不一致
如果列是字符串类型,传入条件是必须用引号引起来,不然...
select * from tb1 where name = 999;
5.- !=
select * from tb1 where name != 'alex'
特别的:如果是主键,则还是会走索引
select * from tb1 where nid != 123
6.- >
select * from tb1 where name > 'alex'
特别的:如果是主键或索引是整数类型,则还是会走索引
select * from tb1 where nid > 123
select * from tb1 where num > 123
7.- order by
select email from tb1 order by name desc;
当根据索引排序时候,选择的映射如果不是索引,则不走索引
特别的:如果对主键排序,则还是走索引:
select * from tb1 order by nid desc;

8.- 组合索引最左前缀
如果组合索引为:(name,email)
name and email -- 使用索引
name -- 使用索引
email -- 不使用索引
126.如何开启慢日志查询?

修改配置文件
slow_query_log = OFF 是否开启慢日志记录
long_query_time = 2 时间限制,超过此时
间,则记录
slow_query_log_file = /usr/slow.log 日志文件
log_queries_not_using_indexes = OFF 为使用索引的搜索是否记录

下面是开启
slow_query_log = ON
long_query_time = 2
log_queries_not_using_indexes = OFF
log_queries_not_using_indexes = ON

注:查看当前配置信息:
show variables like '%query%'
修改当前配置:
set global 变量名 = 值

127.数据库导入导出命令(结构+数据)?

导出现有数据库数据:(当有提示出入密码。-p 就不用加密码)
mysqldump -u 用户名 -p 密码 数据库名称 >导出文件路径 # 结
构+数据
mysqldump -u 用户名 -p 密码 -d 数据库名称 >导出文件 路径 #
结构

导入现有数据库数据:
mysqldump -uroot -p 密码 数据库名称 < 文件路径

128.数据库优化方案?

1、创建数据表时把固定长度的放在前面()
2、将固定数据放入内存: 例如:choice 字段 (django 中有用到,数字 1、
2、3…… 对应相应内容)
3、char 和 varchar 的区别(char 可变, varchar 不可变 )

4、联合索引遵循最左前缀(从最左侧开始检索)
5、避免使用 select *
6、读写分离
- 实现:两台服务器同步数据
- 利用数据库的主从分离:主,用于删除、修改、更新;从,用于
查;
读写分离:利用数据库的主从进行分离:主,用于删除、修改更新;从,用于查
7、分库
- 当数据库中的表太多,将某些表分到不同的数据库,例如:1W 张表

- 代价:连表查询
8、分表
- 水平分表:将某些列拆分到另外一张表,例如:博客+博客详情
- 垂直分表:讲些历史信息分到另外一张表中,例如:支付宝账单

9、加缓存
- 利用 redis、memcache (常用数据放到缓存里,提高取数据速度)

如果只想获取一条数据
- select * from tb where name=‘alex’ limit 1

129.char 和 varchar 的区别?

char 和 varchar 的区别(char 可变, varchar 不可变 )

130.简述 MySQL 的执行计划?

查看有没有命中索引,让数据库帮看看运行速度快不快
explain select * from table;

当 type 为 all 时,是为全表索引

131.在对 name 做了唯一索引前提下,简述以下区别:

select * from tb where name = ‘Oldboy-Wupeiqi’


select * from tb where name = ‘Oldboy-Wupeiqi’ limit 1
是这样的的,用 where 条件过滤出符合条件的数据的同时,进行计数,
比如 limit 1,那么在 where 过滤出第 1 条数据后,他就会直接把结果 select
出来返回给你,整个过程就结束了。

没做唯一索引的话,前者查询会全表扫描,效率低些

limit 1,只要找到对应一条数据,就不继续往下扫描.

然而 name 字段添加唯一索引了,加不加 limit 1,意义都不大;

132.1000w 条数据,使用 limit offset 分页时,为什么越往后翻越慢?如何

解决?

答案一:
先查主键,在分页。
select * from tb where id in (
select id from tb where limit 10 offset 30
)
答案二:
按照也无需求是否可以设置只让用户看 200 页

答案三:
记录当前页 数据 ID 最大值和最小值
在翻页时,根据条件先进行筛选;筛选完毕之后,再根据 limit offset
查询。

select * from (select * from tb where id > 22222222) as B limit


10 offset 0

如果用户自己修改页码,也可能导致慢;此时对 url 种的页码进行加密


(rest framework )

133.什么是索引合并?

1、索引合并是把几个索引的范围扫描合并成一个索引。
2、索引合并的时候,会对索引进行并集,交集或者先交集再并集操作,以便合
并成一个索引。
3、这些需要合并的索引只能是一个表的。不能对多表进行索引合并。

简单的说,索引合并,让一条 sql 可以使用多个索引。对这些索引取交集,并


集,或者先取交集再取并集。
从而减少从数据表中取数据的次数,提高查询效率。
134.什么是覆盖索引?

在索引表中就能将想要的数据查询到

135.简述数据库读写分离?

- 实现:两台服务器同步数据
- 利用数据库的主从分离:主,用于删除、修改、更新;从,用于
查;
方式一:是视图里面用 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',]

136.简述数据库分库分表?(水平、垂直)

1、分库
当数据库中的表太多,将某些表分到不同数据库,例如:1W 张表时
代价:连表查询跨数据库,代码变多
# 2、分表
水平分表:将某些列拆分到另一张表,例如:博客+博客详情
垂直分表:将某些历史信息,分到另外一张表中,例如:支付宝账单

137.redis 和 memcached 比较?

区别
1:redis 不仅支持简单的 key_value 类型,还支持字典,字符串,列表,集
合,有序集合类型
2:内存使用效率对比,使用简单的 key-value 存储的话,
Memcached 的内存利用率更高而如果 Redis 采用 hash 结构来做 key-value
存储,由于其组合式的压缩,其内存利用率会高于 Memcached。
3.性能对比:由于 Redis 只使用单核,而 Memcached 可以使用多核,.
所以平均每一个核上 Redis 在存储小数据时比 Memcached 性能更高。而在
100k 以上的数据中,Memcached 性能要高于 Redis,
4.Redis 虽然是基于内存的存储系统,但是它本身是支持内存数据的持久化
的,而且提供两种主要的持久化策略:RDB 快照和 AOF 日志。
而 memcached 是不支持数据持久化操作的。
5.集群管理不同,Memcached 本身并不支持分布式,因此只能在客户端通过像
一致性哈希这样的分布式算法来实现 Memcached 的分布式存储。

138.redis 中数据库默认是多少个 db 及作用?

Redis 默认支持 16 个数据库,可以通过配置 databases 来修改这一数字。客户


端与 Redis 建立连接后会自动选择 0 号数据库,不过可以随时使用 SELECT 命令
更换数据库

Redis 支持多个数据库,并且每个数据库的数据是隔离的不能共享,并且基于
单机才有,如果是集群就没有数据库的概念。
139.python 操作 redis 的模块?
- 连接
- 直接连接:
import redis
r = redis.Redis(host='10.211.55.4', port=6379)
r.set('foo', 'Bar')
print r.get('foo')
- 连接池:
import redis
pool = redis.ConnectionPool(host='10.211.55.4', port=6379)

r = redis.Redis(connection_pool=pool)
r.set('foo', 'Bar')
print r.get('foo')

140.如果 redis 中的某个列表中的数据量非常大,如果实现循环显示每一个

值?

- 如果一个列表在 redis 中保存了 10w 个值,我需要将所有值全部循环并


显示,请问如何实现?
一个一个取值,列表没有 iter 方法,但能自定义
def list_scan_iter(name,count=3):
start = 0
while True:
result = conn.lrange(name, start, start+count-1)
start += count
if not result:
break
for item in result:
yield item

for val in list_scan_iter('num_list'):


print(val)
场景:投票系统,script-redis

141.redis 如何实现主从复制?以及数据同步机制?

优势:
- 高可用
- 分担主压力
注意:
- slave 设置只读

从的配置文件添加以下记录,即可:
slaveof 1.1.1.1 3306

142.redis 中的 sentinel 的作用?

帮助我们自动在主从之间进行切换
检测主从中 主是否挂掉,且超过一半的 sentinel 检测到挂了之后才进行
进行切换。
如果主修复好了,再次启动时候,会变成从。

启动主 redis:
redis-server /etc/redis-6379.conf 启动主 redis
redis-server /etc/redis-6380.conf 启动从 redis

在 linux 中:
找到 /etc/redis-sentinel-8001.conf 配置文件,在内部:
- 哨兵的端口 port = 8001
- 主 redis 的 IP,哨兵个数的一半/1

找到 /etc/redis-sentinel-8002.conf 配置文件,在内部:
- 哨兵的端口 port = 8002
- 主 redis 的 IP, 1

启动两个哨兵

143.如何实现 redis 集群?

redis 集群、分片、分布式 redis


redis-py-cluster
集群方案:
- redis cluster 官方提供的集群方案。
- codis,豌豆荚技术团队。
- tweproxy,Twiter 技术团队。
redis cluster 的原理?
- 基于分片来完成。
- redis 将所有能放置数据的地方创建了 16384 个哈希槽。
- 如果设置集群的话,就可以为每个实例分配哈希槽:
- 192.168.1.20【0-5000】
- 192.168.1.21【5001-10000】
- 192.168.1.22【10001-16384】
- 以后想要在 redis 中写值时,
set k1 123
将 k1 通过 crc16 的算法,将 k1 转换成一个数字。然后再将该数字和 16384 求
余,如果得到的余数 3000,那么就将该值写入到 192.168.1.20 实例中。
144.redis 中默认有多少个哈希槽?

16384

145.简述 redis 的有哪几种持久化策略及比较?

RDB:每隔一段时间对 redis 进行一次持久化。


- 缺点:数据不完整
- 优点:速度快
AOF:把所有命令保存起来,如果想到重新生成到 redis,那么就要把命令重新
执行一次。
- 缺点:速度慢,文件比较大
- 优点:数据完整

146.列举 redis 支持的过期策略。

voltile-lru: 从已设置过期时间的数据集(server.db[i].expires)中
挑选最近频率最少数据淘汰
volatile-ttl: 从已设置过期时间的数据集(server.db[i].expires)中
挑选将要过期的数据淘汰
volatile-random:从已设置过期时间的数据集(server.db[i].expires)中
任意选择数据淘汰

allkeys-lru: 从数据集(server.db[i].dict)中挑选最近最少使用
的数据淘汰
allkeys-random: 从数据集(server.db[i].dict)中任意选择数据淘汰
no-enviction(驱逐):禁止驱逐数据

147.MySQL 里有 2000w 数据,redis 中只存 20w 的数据,如何保证

redis 中都是热点数据?

相关知识:redis 内存数据集大小上升到一定大小的时候,就会施行数据淘
汰策略(回收策略)。redis 提供 6 种数据淘汰策略:

volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑
选最近最少使用的数据淘汰
volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑
选将要过期的数据淘汰
volatile-random:从已设置过期时间的数据集(server.db[i].expires)中
任意选择数据淘汰
allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据
淘汰
allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
no-enviction(驱逐):禁止驱逐数据

148.写代码,基于 redis 的列表实现 先进先出、后进先出队列、优先级队列。

参看 script—redis 源码
from scrapy.utils.reqser import request_to_dict, request_from_dict

from . import picklecompat

class Base(object):
"""Per-spider base queue class"""

def __init__(self, server, spider, key, serializer=None):


"""Initialize per-spider redis queue.

Parameters
----------
server : StrictRedis
Redis client instance.
spider : Spider
Scrapy spider instance.
key: str
Redis key where to put and get messages.
serializer : object
Serializer object with ``loads`` and ``dumps`` methods.

"""
if serializer is None:
# Backward compatibility.
# TODO: deprecate pickle.
serializer = picklecompat
if not hasattr(serializer, 'loads'):
raise TypeError("serializer does not implement 'loads'
function: %r"
% serializer)
if not hasattr(serializer, 'dumps'):
raise TypeError("serializer '%s' does not implement
'dumps' function: %r"
% serializer)
self.server = server
self.spider = spider
self.key = key % {'spider': spider.name}
self.serializer = serializer

def _encode_request(self, request):


"""Encode a request object"""
obj = request_to_dict(request, self.spider)
return self.serializer.dumps(obj)

def _decode_request(self, encoded_request):


"""Decode an request previously encoded"""
obj = self.serializer.loads(encoded_request)
return request_from_dict(obj, self.spider)

def __len__(self):
"""Return the length of the queue"""
raise NotImplementedError

def push(self, request):


"""Push a request"""
raise NotImplementedError

def pop(self, timeout=0):


"""Pop a request"""
raise NotImplementedError

def clear(self):
"""Clear queue/stack"""
self.server.delete(self.key)

class FifoQueue(Base):
"""Per-spider FIFO queue"""

def __len__(self):
"""Return the length of the queue"""
return self.server.llen(self.key)

def push(self, request):


"""Push a request"""
self.server.lpush(self.key, self._encode_request(request))

def pop(self, timeout=0):


"""Pop a request"""
if timeout > 0:
data = self.server.brpop(self.key, timeout)
if isinstance(data, tuple):
data = data[1]
else:
data = self.server.rpop(self.key)
if data:
return self._decode_request(data)

class PriorityQueue(Base):
"""Per-spider priority queue abstraction using redis' sorted
set"""

def __len__(self):
"""Return the length of the queue"""
return self.server.zcard(self.key)

def push(self, request):


"""Push a request"""
data = self._encode_request(request)
score = -request.priority
# We don't use zadd method as the order of arguments change
depending on
# whether the class is Redis or StrictRedis, and the option
of using
# kwargs only accepts strings, not bytes.
self.server.execute_command('ZADD', self.key, score, data)

def pop(self, timeout=0):


"""
Pop a request
timeout not support in this queue class
"""
# use atomic range/remove using multi/exec
pipe = self.server.pipeline()
pipe.multi()
pipe.zrange(self.key, 0, 0).zremrangebyrank(self.key, 0, 0)
results, count = pipe.execute()
if results:
return self._decode_request(results[0])
class LifoQueue(Base):
"""Per-spider LIFO queue."""

def __len__(self):
"""Return the length of the stack"""
return self.server.llen(self.key)

def push(self, request):


"""Push a request"""
self.server.lpush(self.key, self._encode_request(request))

def pop(self, timeout=0):


"""Pop a request"""
if timeout > 0:
data = self.server.blpop(self.key, timeout)
if isinstance(data, tuple):
data = data[1]
else:
data = self.server.lpop(self.key)

if data:
return self._decode_request(data)

# TODO: Deprecate the use of these names.


SpiderQueue = FifoQueue
SpiderStack = LifoQueue
SpiderPriorityQueue = PriorityQueue

149.如何基于 redis 实现消息队列?

# 通过发布订阅模式的 PUB、SUB 实现消息队列


# 发布者发布消息到频道了,频道就是一个消息队列。
# 发布者:
import redis
conn = redis.Redis(host='127.0.0.1',port=6379)
conn.publish('104.9MH', "hahahahahaha")
# 订阅者:
import redis
conn = redis.Redis(host='127.0.0.1',port=6379)
pub = conn.pubsub()
pub.subscribe('104.9MH')
while True:
msg= pub.parse_response()
print(msg)
对了,redis 做消息队列不合适
业务上避免过度复用一个 redis,用它做缓存、做计算,还做任务队列,压力
太大,不好。

150.如何基于 redis 实现发布和订阅?以及发布订阅和消息队列的区别?

发布和订阅,只要有任务就给所有订阅者没人一份
发布者:
import redis

conn = redis.Redis(host='127.0.0.1',port=6379)
conn.publish('104.9MH', "hahaha")
订阅者:
import redis

conn = redis.Redis(host='127.0.0.1',port=6379)
pub = conn.pubsub()
pub.subscribe('104.9MH')

while True:
msg= pub.parse_response()
print(msg)

151.什么是 codis 及作用?

Codis 是一个分布式 Redis 解决方案, 对于上层的应用来说, 连接到 Codis


Proxy 和连接原生的 Redis Server 没有明显的区别
(不支持的命令列表), 上层应用可以像使用单机的 Redis 一样使用, Codis 底
层会处理请求的转发, 不停机的数据迁移等工作,
所有后边的一切事情, 对于前面的客户端来说是透明的, 可以简单的认为后边
连接的是一个内存无限大的 Redis 服务.

152.什么是 twemproxy 及作用?

是 Twtter 开源的一个 Redis 和 Memcache 代理服务器,主要用于管理


Redis 和 Memcached 集群,
减少与 Cache 服务器直接连接的数量。

153.写代码实现 redis 事务操作。

import redis

pool = redis.ConnectionPool(host='10.211.55.4', port=6379)


conn = redis.Redis(connection_pool=pool)

# pipe = r.pipeline(transaction=False)
pipe = conn.pipeline(transaction=True)
# 开始事务
pipe.multi()

pipe.set('name', 'bendere')
pipe.set('role', 'sb')

# 提交
pipe.execute()

注意:咨询是否当前分布式 redis 是否支持事务

154.redis 中的 watch 的命令的作用?

在 Redis 的事务中,WATCH 命令可用于提供 CAS(check-and-set)功能。


假设我们通过 WATCH 命令在事务执行之前监控了多个 Keys,倘若在 WATCH 之后
有任何 Key 的值发生了变化,
EXEC 命令执行的事务都将被放弃,同时返回 Null multi-bulk 应答以通知调用
者事务执行失败。

面试题:你如何控制剩余的数量不会出问题?
方式一:- 通过 redis 的 watch 实现
import redis
conn = redis.Redis(host='127.0.0.1',port=6379)

# conn.set('count',1000)
val = conn.get('count')
print(val)

with conn.pipeline(transaction=True) as pipe:

# 先监视,自己的值没有被修改过
conn.watch('count')

# 事务开始
pipe.multi()
old_count = conn.get('count')
count = int(old_count)
print('现在剩余的商品有:%s',count)
input("问媳妇让不让买?")
pipe.set('count', count - 1)

# 执行,把所有命令一次性推送过去
pipe.execute()
方式二 - 数据库的锁

155.基于 redis 如何实现商城商品数量计数器?

import redis

conn = redis.Redis(host='192.168.1.41',port=6379)

conn.set('count',1000)

with conn.pipeline() as pipe:

# 先监视,自己的值没有被修改过
conn.watch('count')

# 事务开始
pipe.multi()
old_count = conn.get('count')
count = int(old_count)
if count > 0: # 有库存
pipe.set('count', count - 1)

# 执行,把所有命令一次性推送过去
pipe.execute()

156.简述 redis 分布式锁和 redlock 的实现机制。

在不同进程需要互斥地访问共享资源时,分布式锁是一种非常有用的技术手
段。
有很多三方库和文章描述如何用 Redis 实现一个分布式锁管理器,但是这些库
实现的方式差别很大
,而且很多简单的实现其实只需采用稍微增加一点复杂的设计就可以获得更好
的可靠性。
用 Redis 实现分布式锁管理器的算法,我们把这个算法称为 RedLock。

实现
- 写值并设置超时时间
- 超过一半的 redis 实例设置成功,就表示加锁完成。
- 使用:安装 redlock-py
from redlock import Redlock
dlm = Redlock(
[
{"host": "localhost", "port": 6379, "db": 0},
{"host": "localhost", "port": 6379, "db": 0},
{"host": "localhost", "port": 6379, "db": 0},
]
)

# 加锁,acquire
my_lock = dlm.lock("my_resource_name",10000)
if my_lock:
# J 进行操作
# 解锁,release
dlm.unlock(my_lock)
else:
print('获取锁失败')
redis 分布式锁?
# 不是单机操作,又多了一/多台机器
# redis 内部是单进程、单线程,是数据安全的(只有自己的线程在操作数据)
----------------------------------------------------------------
\A、B、C,三个实例(主)
1、来了一个'隔壁老王'要操作,且不想让别人操作,so,加锁;
加锁:'隔壁老王'自己生成一个随机字符串,设置到 A、B、C 里(xxx=666)
2、来了一个'邻居老李'要操作 A、B、C,一读发现里面有字符串,擦,被加锁
了,不能操作了,等着吧~
3、'隔壁老王'解决完问题,不用锁了,把 A、B、C 里的 key:'xxx'删掉;完
成解锁
4、'邻居老李'现在可以访问,可以加锁了
# 问题:
1、如果'隔壁老王'加锁后突然挂了,就没人解锁,就死锁了,其他人干看着没
法用咋办?
2、如果'隔壁老王'去给 A、B、C 加锁的过程中,刚加到A,'邻居老李'就去操
作 C 了,加锁成功 or 失败?
3、如果'隔壁老王'去给 A、B、C 加锁时,C 突然挂了,这次加锁是成功还是失
败?
4、如果'隔壁老王'去给 A、B、C 加锁时,超时时间为 5 秒,加一个锁耗时 3
秒,此次加锁能成功吗?
# 解决
1、安全起见,让'隔壁老王'加锁时设置超时时间,超时的话就会自动解锁(删
除 key:'xxx')
2、加锁程度达到(1/2)+1 个就表示加锁成功,即使没有给全部实例加锁;
3、加锁程度达到(1/2)+1 个就表示加锁成功,即使没有给全部实例加锁;
4、不能成功,锁还没加完就过期,没有意义了,应该合理设置过期时间
# 注意
使用需要安装 redlock-py
----------------------------------------------------------------
from redlock import Redlock
dlm = Redlock(
[
{"host": "localhost", "port": 6379, "db": 0},
{"host": "localhost", "port": 6379, "db": 0},
{"host": "localhost", "port": 6379, "db": 0},
]
)
# 加锁,acquire
my_lock = dlm.lock("my_resource_name",10000)
if my_lock:
# 进行操作
# 解锁,release
dlm.unlock(my_lock)
else:
print('获取锁失败')
\通过 sever.eval(self.unlock_script)执行一个 lua 脚本,用来删除加锁时
的 key

157.什么是一致性哈希?Python 中是否有相应模块?

一致性哈希
一致性 hash 算法(DHT)可以通过减少影响范围的方式,解决增减服务器导致
的数据散列问题,从而解决了分布式环境下负载均衡问题;
如果存在热点数据,可以通过增添节点的方式,对热点区间进行划分,将压力
分配至其他服务器,重新达到负载均衡的状态。
Python 模块--hash_ring,即 Python 中的一致性 hash

158.如何高效的找到 redis 中所有以 aaa 开头的 key?

redis 有一个 keys 命令。


# 语法:KEYS pattern
# 说明:返回与指定模式相匹配的所用的 keys。
该命令所支持的匹配模式如下:
1、?:用于匹配单个字符。例如,h?llo 可以匹配 hello、hallo 和 hxllo 等;
2、*:用于匹配零个或者多个字符。例如,h*llo 可以匹配 hllo 和 heeeello
等;
2、[]:可以用来指定模式的选择区间。例如 h[ae]llo 可以匹配 hello 和
hallo,但是不能匹配 hillo。同时,可以使用“/”符号来转义特殊的字符
# 注意
KEYS 的速度非常快,但如果数据太大,内存可能会崩掉,
如果需要从一个数据集中查找特定的 key,最好还是用 Redis 的集合结构(set)
来代替。
回到顶部

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

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

浏览器本质,socket 客户端遵循 Http 协议


HTTP 协议本质:通过\r\n 分割的规范+ 请求响应之后断开链接 == >
无状态、 短连接
具体:
Http 协议是建立在 tcp 之上的,是一种规范,它规范定了发送的数据的数
据格式,
然而这个数据格式是通过\r\n 进行分割的,请求头与请求体也是通过 2 个\r\n
分割的,响应的时候,
响应头与响应体也是通过\r\n 分割,并且还规定已请求已响应就会断开链接
即---> 短连接、无状态

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

websocket 是给浏览器新建的一套(类似与 http)协议,协议规定:(\r\n 分


割)浏览器和服务器连接之后不断开,
以此完成:服务端向客户端主动推送消息。

websocket 协议额外做的一些操作
握手 ----> 连接钱进行校验
加密 ----> payload_len=127/126/<=125 --> mask key

本质
创建一个连接后不断开的 socket
当连接成功之后:
客户端(浏览器)会自动向服务端发送消息,包含: Sec-WebSocket-Key:
iyRe1KMHi4S4QXzcoboMmw==
服务端接收之后,会对于该数据进行加密:base64(sha1(swk +
magic_string))
构造响应头:
HTTP/1.1 101 Switching Protocols\r\n
Upgrade:websocket\r\n
Connection: Upgrade\r\n
Sec-WebSocket-Accept: 加密后的值\r\n
WebSocket-Location: ws://127.0.0.1:8002\r\n\r\n
发给客户端(浏览器)
建立:双工通道,接下来就可以进行收发数据
发送数据是加密,解密,根据 payload_len 的值进行处理
payload_len <= 125
payload_len == 126
payload_len == 127
获取内容:
mask_key
数据
根据 mask_key 和数据进行位运算,就可以把值解析出来。

3.什么是 magic string ?

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

4.如何创建响应式布局?

响应式布局是通过@media 实现的
@media (min-width:768px){
.pg-header{
background-color:green;
}
}
@media (min-width:992px){
.pg-header{
background-color:pink;
}
}

代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-
scale=1">
<title>Title</title>
<style>
body{
margin: 0;
}
.pg-header{
background-color: red;
height: 48px;
}

@media (min-width: 768px) {


.pg-header{
background-color: aqua;
}
}
@media (min-width: 992px) {
.pg-header{
background-color: blueviolet;
}
}
</style>
</head>
<body>
<div class="pg-header"></div>
</body>
</html>

5.你曾经使用过哪些前端框架?

jQuery
- BootStrap
- Vue.js(与 vue 齐名的前端框架 React 和 Angular)

6.什么是 ajax 请求?并使用 jQuery 和 XMLHttpRequest 对象实现一个

ajax 请求。

基于原生 AJAX - Demo

基于 jQueryAjax - Demo

http://www.cnblogs.com/wupeiqi/articles/5703697.html

7.如何在前端实现轮训?

轮询:通过定时器让程序每隔 n 秒执行一次操作。

<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-
scale=1">
<title>Title</title>
</head>
<body>
<h1>请选出最帅的男人</h1>
<ul>
{% for k,v in gg.items() %}
<li>ID:{{ k }}, 姓名:{{ v.name }} ,票数:
{{ v.count }}</li>
{% endfor %}
</ul>

<script>
setInterval(function () {
location.reload();
},2000)
</script>
</body>
</html>

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

客户端向服务器发送请求,服务器接到请求后 hang 住连接,等待 30 秒,30s


过后再重新发起请求,
直到有新消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务
器发送新的请求。

<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-
scale=1">
<title>Title</title>
</head>
<body>
<h1>请选出最帅的男人</h1>
<ul>
{% for k,v in gg.items() %}
<li style="cursor: pointer" id="user_{{ k }}"
ondblclick="vote({{ k }});">ID:{{ k }}, 姓名:{{ v.name }} ,票数:
<span>{{ v.count }}</span></li>
{% endfor %}
</ul>

<script src="/static/jquery-3.3.1.min.js"></script>
<script>
$(function () {
get_new_count();
});

function get_new_count() {
$.ajax({
url: '/get_new_count',
type:'GET',
dataType:'JSON',
success:function (arg) {
if (arg.status){
// 更新票数
var gid = "#user_" + arg.data.gid;
$(gid).find('span').text(arg.data.count);
}else{
// 10s 内没有人投票
}
get_new_count();

}
})
}

function vote(gid) {
$.ajax({
url: '/vote',
type:'POST',
data:{gid:gid},
dataType:"JSON",
success:function (arg) {

}
})
}
</script>
</body>
</html>

9.vuex 的作用?

多组件之间共享:vuex

补充 luffyvue
1:router-link / router-view
2:双向绑定,用户绑定 v-model
3:循环展示课程:v-for
4:路由系统,添加动态参数
5:cookie 操作:vue-cookies
6:多组件之间共享:vuex
7:发送 ajax 请求:axios (js 模块)

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

vue-resource 的 interceptors 拦截器的作用正是解决此需求的妙方。


在每次 http 的请求响应之后,如果设置了拦截器如下,会优先执行拦截器函
数,获取响应体,然后才会决定是否把 response 返回给 then 进行接收

11.axios 的作用?

发送 ajax 请求:axios (js 模块)

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 及实现原理?

JSONP
jsonp 是 json 用来跨域的一个东西。原理是通过 script 标签的跨域特性来绕
过同源策略。
JSONP 的简单实现模式,或者说是 JSONP 的原型:创建一个回调函数,然后在
远程服务上调用这个函数并且将 JSON 数据形式作为参数传递,
完成回调。
14.什么是 cors ?

CORS
浏览器将 CORS 请求分成两类:简单请求和赋复杂请求

简单请求(同时满足以下两大条件)
(1)请求方法是以下三种方法之一:
HEAD
GET
POST
(2)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(修改数据)
HEAD(类似于 get 请求,只不过返回的响应中没有具体的内容,用于获取报头)
DELETE

传值代码 f
Request.QueryString 方法针对控件 id
Request.Form 方法针对控件名称 name

16.列举 Http 请求中的状态码?

分类:
1** 信息,服务器收到请求,需要请求者继续执行操作
2** 成功,操作被成功接收并处理
3** 重定向,需要进一步的操作以完成请求
4** 客户端错误,请求包含语法错误或无法完成请求
5** 服务器错误,服务器在处理请求的过程中发生了错误

常见的状态码
200 -请求成功
202 -已接受请求,尚未处理
204 -请求成功,且不需返回内容
301 - 资源(网页等)被永久转移到其他 url
400 - 请求的语义或是参数有错
403 - 服务器拒绝请求
404 - 请求资源(网页)不存在

500 - 内部服务器错误
502 - 网关错误,一般是服务器压力过大导致连接超时
503 - 由于超载或系统维护,服务器暂时的无法处理客户端的请求。

17.列举 Http 请求中常见的请求头?

- user-agent
- host
- referer
- cookie
- content-type

18.看图写结果(js):

李杰
看图写结果(js)

武沛奇
看图写结果:
(js)

老男孩
看图写结果:
(js)

undefined
看图写结果:
(js)
武沛奇
看图写结果:
(js)

Alex

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,异步非阻塞。
django 和 flask 的共同点就是,他们 2 个框架都没有写 socket,所以他们都是
利用第三方模块 wsgi。
但是内部使用的 wsgi 也是有些不同的:django 本身运行起来使用 wsgiref,而
flask 使用 werkzeug wsgi

还有一个区别就是他们的请求管理不太一样:django 是通过将请求封装成
request 对象,再通过参数传递,而 flask 是通过上下文管理机制

Tornado

# 是一个轻量级的 Web 框架,异步非阻塞+内置 WebSocket 功能。

'目标':通过一个线程处理 N 个并发请求(处理 IO)。

'内部组件

#内部自己实现 socket

#路由系统

#视图

#模板
#cookie

#csrf

20.什么是 wsgi?

是 web 服务网关接口,是一套协议。
是通过以下模块实现了 wsgi 协议:
- wsgiref
- werkzurg
- uwsgi 关于部署
以上模块本质:编写 socket 服务端,用于监听请求,当有请求到来,则将请求
数据进行封装,然后交给 web 框架处理。

21.django 请求的生命周期?

用户请求进来先走到 wsgi 然后将请求交给 jango 的中间件 穿过


django 中间件(方法是 process_request)
接着就是 路由匹配 路由匹配成功之后就执行相应的 视图函数
在视图函数中可以调用 orm 做数据库操作 再从模板路径 将模板拿到 然
后在后台进行模板渲染
模板渲染完成之后就变成一个字符串 再把这个字符串经过所有中间件(方
法:process_response) 和 wsgi 返回给用户

22.列举 django 的内置组件?

form 组件
- 对用户请求的数据进行校验
- 生成 HTML 标签

PS:
- form 对象是一个可迭代对象。
- 问题:choice 的数据如果从数据库获取可能会造成数据无法实时更新
- 重写构造方法,在构造方法中重新去数据库获取值。
- ModelChoiceField 字段
from django.forms import Form
from django.forms import fields
from django.forms.models import ModelChoiceField
class UserForm(Form):
name = fields.CharField(label='用户名',max_length=32)
email = fields.EmailField(label='邮箱')
ut_id =
ModelChoiceField(queryset=models.UserType.objects.all())

依赖:
class UserType(models.Model):
title = models.CharField(max_length=32)

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 中,然后再每次请求进来在中间件里,根据
当前的 url 去 session 中匹配,
判断当前用户是否有权限访问当前 url,有权限就继续访问,没有就返回,
(检查的东西就可以放到中间件中进行统一处理)在 process_request 方法里
面做的,
我们的中间件是放在 session 后面,因为中间件需要到 session 里面取数据
session
cookie 与 session 区别
(a)cookie 是保存在浏览器端的键值对,而 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
的时候可能给我们的响应加处理

为什么使用缓存
将常用且不太频繁修改的数据放入缓存。
以后用户再来访问,先去缓存查看是否存在,如果有就返回
否则,去数据库中获取并返回给用户(再加入到缓存,以便下次访问)

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.py
url(r'^login/$',views.login, name="login"),

# views.py
def login(request):
if request.method == "POST":
print(request.POST)

return render(request,"login.html")

# HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-
scale=1">
<title>登录页面</title>
</head>
<body>
<form action="{% url 'login' %}" method="post"
enctype="multipart/form-data">
<input type="text" name="user2">
<input type="file" name="file">
<input type="submit" value="提交">

</form>
</body>
</html>

CBV 基于类
# urls.py
url(r'^login/$',views.Login.as_view(), name="login"),

# 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):
pass

def 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_decorator

def auth(func):
def inner(*args,**kwargs):
return func(*args,**kwargs)
return inner

class 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_exempt

class 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_protect

@method_decorator(csrf_exempt,name='dispatch') ---> 指定名字


class UserView(View):
def dispatch(self, request, *args, **kwargs):
return HttpResponse('...')

28.列举 django orm 中所有的方法(QuerySet 对象的所有方法)

返回 QuerySet 对象的方法有:
all()
filter()
exclude()
order_by()
reverse()
distinct()
特殊的 QuerySet:
values() 返回一个可迭代的字典序列
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
select_related 主要针一对一和多对一关系进行优化,通过多表 join 关联查
询,一次性获得所有数据,
存放在内存中,但如果关联的表太多,会严重影响数据库性能。
def index(request):
obj = Book.objects.all().select_related("publisher")
return render(request, "index.html", locals())
\prefetch_related
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,


IntegerField
Article.objects.annotate(
numviews=Count(Case(
When(readership__what_time__lt=treshold, then=1),
output_field=CharField(),
))
)

students =
Student.objects.all().annotate(num_excused_absences=models.Sum(
models.Case(
models.When(absence__type='Excused', then=1),
default=0,
output_field=models.IntegerField()
)))
# 1 次 SQL
# select * from userinfo
objs = UserInfo.obejcts.all()
for item in objs:
print(item.name)

# n+1 次 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)

select_related()
# 1 次 SQL
# 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__lte=8).prefetch_related('ut')
for obj in objs:
print(obj.name,obj.ut.title)

31.filter 和 exclude 的区别?

def filter(self, *args, **kwargs)


# 条件查询(符合条件)
# 查出符合条件
# 条件可以是:参数,字典,Q

def 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
extra
- extra
def extra(self, select=None, where=None, params=None,
tables=None, order_by=None,
select_params=None)
# 构造额外的查询条件或者映射,如:子查询
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=["foo='a' 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, params=None, translations=None, using=None):
# 执行原生 SQL
models.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',
translations=name_map)
# 指定数据库
models.UserInfo.objects.raw('select * from userinfo',
using="default")

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 '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',]

34.F 和 Q 的作用?

F:主要用来获取原数据进行计算。
Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取模的操
作。
修改操作也可以使用 F 函数,比如将每件商品的价格都在原价格的基础上增加
10
from django.db.models import F
from app01.models import Goods

Goods.objects.update(price=F("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_size=None):


# 批量插入
# batch_size 表示一次插入的个数
objs = [
models.DDD(name='r11'),
models.DDD(name='r22')
]
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_length=32)
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 Form
from django.forms import fields
from django.forms.models import ModelChoiceField
class UserForm(Form):
name = fields.CharField(label='用户名',max_length=32)
email = fields.EmailField(label='邮箱')
ut_id =
ModelChoiceField(queryset=models.UserType.objects.all())
依赖:
class UserType(models.Model):
title = models.CharField(max_length=32)

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'

举例说明:

user=models.OneToOneField(User)

owner=models.ForeignKey(UserProfile)

需要改成:

user=models.OneToOneField(User,on_delete=models.CASCADE) --
在老版本这个参数(models.CASCADE)是默认值

owner=models.ForeignKey(UserProfile,on_delete=models.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 中获取 token


function 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 type="button" onclick="Do1();" value="Do it"/>
<input type="button" onclick="Do2();" value="Do it"/>
<input type="button" onclick="Do3();" value="Do 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 模块)

安装第三方组件支持 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 %}

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_connection

def index(request):
# 根据名字去连接池中获取连接
conn = get_redis_connection("default")
conn.hset('n1','k1','v1') # 存数据
return HttpResponse('...')

46.django 路由系统中 name 的作用?

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

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

在模板中使用:{ % 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

MVC:model、view(模块)、controller(视图)
MTV:model、tempalte、view
54.django 的 contenttype 组件的作用?

contenttype 是 django 的一个组件(app),它可以将 django 下所有 app 下的表


记录下来
可以使用他再加上表中的两个字段,实现一张表和 N 张表动态创建 FK 关系。
- 字段:表名称
- 字段:数据行 ID
应用:路飞表结构优惠券和专题课和学位课关联

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 个 url
www.oldboyedu.com/api/v1/student/$
www.oldboyedu.com/api/v1/student(?P<format>\w+)$
www.oldboyedu.com/api/v1/student/(?P<pk>\d+)/$
www.oldboyedu.com/api/v1/student/(?P<pk>\d+)(?P<format>\w+)$
#- 版本处理
- 问题:版本都可以放在那里?
- url
- GET
- 请求头
#- 认证
- 问题:认证流程?
#- 权限
- 权限是否可以放在中间件中?以及为什么?
#- 访问频率的控制
匿名用户可以真正的防止?无法做到真正的访问频率控制,只能把小白拒
之门外。
如果要封 IP,使用防火墙来做。
登录用户可以通过用户名作为唯一标示进行控制,如果有人注册很多账
号,则无法防止。
#- 视图
#- 解析器 ,根据 Content-Type 请求头对请求体中的数据格式进行处理。
request.data
#- 分页
#- 序列化
- 序列化
- source
- 定义方法
- 请求数据格式校验
#- 渲染器

61.django rest framework 框架中的视图都可以继承哪些类

a. 继承 APIView(最原始)但定制性比较强
这个类属于 rest framework 中的顶层类,内部帮助我们实现了只是基本功
能:认证、权限、频率控制,
但凡是数据库、分页等操作都需要手动去完成,比较原始。
class GenericAPIView(APIView)
def post(...):
pass

b.继承 GenericViewSet(ViewSetMixin,generics.GenericAPIView)
首先他的路由就发生变化
如果继承它之后,路由中的 as_view 需要填写对应关系
在内部也帮助我们提供了一些方便的方法:
get_queryset
get_object
get_serializer
get_serializer_class
get_serializer_context
filter_queryset
注意:要设置 queryset 字段,否则会抛出断言的异常。

代码
只提供增加功能 只继承 GenericViewSet
class TestView(GenericViewSet):
serialazer_class = xxx
def 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 则不可访问

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、'请求刚进来':
将 request,session 封装在 RequestContext 类中
app,g 封装在 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 是一个字典,字典里 key(stack)是唯一标识,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(target=task, 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()
# session=scoped_session(Session)
创建唯一标识的方法(参考 flask 请求源码)

SQLAlchemy 如何执行原生 SQL?

# 使用 execute 方法直接操作 SQL 语句(导入 create_engin、sessionmaker)


engine=create_engine('mysql://root:*****@127.0.0.1/database?charset=u
tf8')
DB_Session = sessionmaker(bind=engine)
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 的字段是否正确?如果不正确请更正:

fromdatetime importdatetime

fromsqlalchemy.ext.declarative

importdeclarative_base

fromsqlalchemy importColumn, Integer, String, DateTime

Base =declarative_base()

classUserInfo(Base):

__tablename__ ='userinfo'

id=Column(Integer, primary_key=True, autoincrement=True)

name =Column(String(64), unique=True)

ctime =Column(DateTime, default=datetime.now())


from datetime import datetime
from sqlalchemy.ext.declarative
import declarative_base
from sqlalchemy import Column, Integer, String, DateTime

Base = declarative_base()
class UserInfo(Base):
__tablename__ = 'userinfo'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(64), unique=True)
ctime = Column(DateTime, default=datetime.now())
---------------------------------------------------------------------
--
不正确:
Ctime 字段中参数应为’default=datetime.now’
now 后面不应该加括号,加了的话,字段不会实时更新。
SQLAchemy 中如何为表设置引擎和字符编码?

sqlalchemy 设置编码字符集,一定要在数据库访问的 URL 上增加


'charset=utf8'
否则数据库的连接就不是'utf8'的编码格式

eng=create_engine('mysql://root:root@localhost:3306/test2?charset=utf
8',echo=True)
1. 设置引擎编码方式为 utf8。

engine =
create_engine("mysql+pymysql://root:123456@127.0.0.1:3306/sqldb01?cha
rset=utf8")
2. 设置数据库表编码方式为 utf8

class UserType(Base):
__tablename__ = 'usertype'
id = Column(Integer, primary_key=True)
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 框架的特点。

异步非阻塞+websocket

简述 Tornado 框架中 Future 对象的作用?

# 实现异步非阻塞
视图函数 yield 一个 futrue 对象,futrue 对象默认:
self._done = False ,请求未完成
self._result = None ,请求完成后返回值,用于传递给回调函数使用。
tornado 就会一直去检测 futrue 对象的_done 是否已经变成 True。

如果 IO 请求执行完毕,自动会调用 future 的 set_result 方法:


self._result = result
self._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")}}" rel="stylesheet" />

# 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 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.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

如何基于 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 库中

什么是 gitlab

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

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'是一个可扩展的持续集成引擎。

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

公司如何实现代码发布?

nginx+uwsgi+django

简述 RabbitMQ、Kafka、ZeroMQ 的区别?

https://blog.csdn.net/zhailihua/article/details/7899006
RabbitMQ 如何在消费者获取任务后未处理完前就挂掉时,保证数据不丢失?
为了预防消息丢失,rabbitmq 提供了 ack
即工作进程在收到消息并处理后,发送 ack 给 rabbitmq,告知 rabbitmq 这时
候可以把该消息从队列中删除了。
如果工作进程挂掉 了,rabbitmq 没有收到 ack,那么会把该消息 重新分发给
其他工作进程。
不需要设置 timeout,即使该任务需要很长时间也可以处理。

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

RabbitMQ 如何对消息做持久化?

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

2、返回一个 ack,进程收到消息并处理完任务后,发给 rabbitmq 一个 ack 表


示任务已经完成,可以删除该任务

3、镜像队列:将 queue 镜像到 cluster 中其他的节点之上。


在该实现下,如果集群中的一个节点失效了,queue 能自动地切换到镜像中的
另一个节点以保证服务的可用性

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

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

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

以下 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 个或多个

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

# Celery 是由 Python 开发的一个简单、灵活、可靠的处理大量任务的分发系


统,
# 它不仅支持实时处理也支持任务调度。
# http://www.cnblogs.com/wupeiqi/articles/8796552.html

简述 celery 运行机制。

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)
},
}

简述 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、data
json、params、proxy
# 常用返回值:
content
iter_content
text
encoding="utf-8"
cookie.get_dict()

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

# BeautifulSoup
用于从 HTML 或 XML 文件中提取、过滤想要的数据形式
#常用方法
解析:html.parser 或者 lxml(需要下载安装)
find、find_all、text、attrs、get

简述 seleninu 模块的作用及基本使用?

Selenium 是一个用于 Web 应用程序测试的工具,


他的测试直接运行在浏览器上,模拟真实用户,按照代码做出点击、输入、打
开等操作

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

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,但很明显你也可以使用 Beutifulsoup,
lxml 或其他你爱用啥用啥。
#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 Request

class ChoutiSpider(scrapy.Spider):
name = 'chouti'
allowed_domains = ['chouti.com']
start_urls = ['https://dig.chouti.com/']

def start_requests(self):
os.environ['HTTP_PROXY'] = "http://192.168.11.11"

for url in self.start_urls:


yield Request(url=url,callback=self.parse)

def parse(self, response):


print(response)

方式二:自定义下载中间件
import random
import base64
import six
def to_bytes(text, encoding=None, errors='strict'):
"""Return the binary representation of `text`. If `text`
is already a bytes object, return it as-is."""
if isinstance(text, bytes):
return text
if 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-8'
return 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 BytesIO

class _ResponseReader(protocol.Protocol):
def __init__(self, finished, txresponse, file_name):
self._finished = finished
self._txresponse = txresponse
self._bytes_received = 0
self.f = open(file_name, mode='wb')
def dataReceived(self, bodyBytes):
self._bytes_received += len(bodyBytes)
# 一点一点的下载
self.f.write(bodyBytes)
self.f.flush()
def connectionLost(self, reason):
if self._finished.called:
return
if 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 ScrapyCommand
from scrapy.utils.project import get_project_settings
class Command(ScrapyCommand):
requires_project = True
def syntax(self):
return '[options]'
def short_desc(self):
return 'Runs all of the spiders'
def 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'调度器
'dupefilter'URL 去重规则(被调度器使用)
'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(url='http://www.cnblogs.com/wupeiqi.html')

result = request.request_fingerprint(req)

print(result) # 8ea4fd67887449313ccc12e5b6b92510cc53675c
scrapy 和 scrapy-redis 的去重规则(源码)
1. scrapy 中去重规则是如何实现?
class RFPDupeFilter(BaseDupeFilter):
"""Request Fingerprint duplicates filter"""

def __init__(self, path=None, debug=False):


self.fingerprints = set()

@classmethod
def 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 Scrapy's scheduler.

"""

logger = logger

def __init__(self, server, key, debug=False):

# self.server = redis 连接
self.server = server
# self.key = dupefilter:123912873234
self.key = key

@classmethod
def from_settings(cls, settings):

# 读取配置,连接 redis
server = get_redis_from_settings(settings)

# key = dupefilter:123912873234
key = defaults.DUPEFILTER_KEY % {'timestamp':
int(time.time())}
debug = settings.getbool('DUPEFILTER_DEBUG')
return cls(server, key=key, debug=debug)

@classmethod
def 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.server=redis 连接
# 添加到 redis 集合中:1,添加工程;0,已经存在
added = self.server.sadd(self.key, fp)
return added == 0

def 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 中使用过什么代码检查工具?

1)PyFlakes:静态检查 Python 代码逻辑错误的工具。


2)Pep8: 静态检查 PEP8 编码风格的工具。
3)NedBatchelder’s McCabe script:静态分析 Python 代码复杂度的工具。
Python 代码分析工具:PyChecker、Pylint

简述 saltstack、ansible、fabric、puppet 工具的作用?

B Tree 和 B+ Tree 的区别?

1.B 树中同一键值不会出现多次,并且有可能出现在叶结点,也有可能出现在
非叶结点中。
而 B+树的键一定会出现在叶结点中,并有可能在非叶结点中重复出现,以维
持 B+树的平衡。
2.因为 B 树键位置不定,且在整个树结构中只出现一次,

请列举常见排序并通过代码实现任意三种。

冒泡/选择/插入/快排

https://www.cnblogs.com/Liqiongyu/p/5911613.html

http://www.cnblogs.com/feixuelove1009/p/6143539.html

请列举常见查找并通过代码实现任意三种。

无序查找、二分查找、插值查找

请列举你熟悉的设计模式?
工厂模式/单例模式等

有没有刷过 leetcode?

leetcode 是个题库,里面有多很编程题目,可以在线编译运行。

https://leetcode-cn.com/problemset/all/
列举熟悉的的 Linux 命令。
1 创建目录
mkdir /data
cd /
mkdir data

2:查看目录
ls
ls -l 显示详细信息

公司线上服务器是什么系统?

Linux/Centos

解释 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

You might also like