数据库部分,前端

数据库部分                         css

 

 

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

 

关系型数据库前端

 

Oracle、DB二、Microsoft SQL Server、Microsoft Access、MySQLvue

 

非关系型java

 

NoSql、Cloudant、MongoDb、redis、HBasenode

 

 

 

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

 

MyISAM:默认的MySQL插件式存储引擎,它是在Web、数据仓储和其余应用环境下最常使用的存储引擎之一。mysql

 

注意,经过更改STORAGE_ENGINE配置变量,可以方便地更改MySQL服务器的默认存储引擎。react

 

  InnoDB:用于事务处理应用程序,具备众多特性,包括ACID事务支持。(提供行级锁)jquery

 

  BDB:可替代InnoDB的事务引擎,支持COMMIT、ROLLBACK和其余事务特性。

 

  Memory:将全部数据保存在RAM中,在须要快速查找引用和其余相似数据的环境下,可提供极快的访问。

 

  Merge:容许MySQL DBA或开发人员将一系列等同的MyISAM表以逻辑方式组合在一块儿,并做为1个对象引用它们。对于诸如数据仓储等VLDB环境十分适合。

 

  Archive:为大量不多引用的历史、归档、或安全审计信息的存储和检索提供了完美的解决方案。

 

  Federated:可以将多个分离的MySQL服务器连接起来,从多个物理服务器建立一个逻辑数据库。十分适合于分布式环境或数据集市环境。

 

  Cluster/NDB:MySQL的簇式数据库引擎,尤为适合于具备高性能查找要求的应用程序,

 

这类查找需求还要求具备最高的正常工做时间和可用性。

 

  Other:其余存储引擎包括CSV(引用由逗号隔开的用做数据库表的文件),

 

Blackhole(用于临时禁止对数据库的应用程序输入),以及Example引擎

 

(可为快速建立定制的插件式存储引擎提供帮助)。

 

 

 

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

 

第一范式

 

   一、每一列属性都是不可再分的属性值,确保每一列的原子性

 

   二、两列的属性相近或类似或同样,尽可能合并属性同样的列,确保不产生冗余数据。

 

第二范式

 

每一行的数据只能与其中一列相关,即一行数据只作一件事。只要数据列中出现数据重复,就要把表拆分开来。

 

第三范式

 

数据不能存在传递关系,即没个属性都跟主键有直接关系而不是间接关系。

 

像:a-->b-->c  属性之间含有这样的关系,是不符合第三范式的。

 

 

 

4. 什么是事务?MySQL如何支持事务?

 

事务是由一步或几步数据库操做序列组成逻辑执行单元,这系列操做要么所有执行,要么所有放弃执行。

 

程序和事务是两个不一样的概念。通常而言:一段程序中可能包含多个事务。

 

(说白了就是几步的数据库操做而构成的逻辑执行单元)

 

事务具备四个特性:原子性(Atomicity)、一致性(Consistency)、

 

隔离性(Isolation)和持续性(Durability)。这四个特性也简称ACID性。

 

 

 

MYSQL的事务处理主要有两种方法

 

  1.用begin,rollback,commit来实现

 

    begin开始一个事务

 

    rollback事务回滚

 

       commit 事务确认

 

  2.直接用set来改变mysql的自动提交模式

 

          mysql默认是自动提交的,也就是你提交一个query,就直接执行!能够经过

 

          set autocommit = 0 禁止自动提交

 

          set autocommit = 1 开启自动提交

 

 

 

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

 

数据库实体间有三种对应关系:一对一,一对多,多对多。

 

       一对一关系示例:

 

一个学生对应一个学生档案材料,或者每一个人都有惟一的身份证编号。

 

       一对多关系示例:

 

一个学生只属于一个班,可是一个班级有多名学生。

 

       多对多关系示例:

 

一个学生能够选择多门课,一门课也有多名学生。

 

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

 

建立一个商城表---包含(id,商品名,每个商品对应数量)

 

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

 

触发器:触发器是一个特殊的存储过程,它是MySQL在insert、update、delete的时候自动执行的代码块。

 

函数:MySQL中提供了许多内置函数,还能够自定义函数(实现程序员须要sql逻辑处理)

 

视图:视图是由查询结果造成的一张虚拟表,是表经过某种运算获得的一个投影

 

存储过程:把一段代码封装起来,当要执行这一段代码的时候,能够经过调用该存储过程来实现

 

(通过第一次编译后再次调用不须要再次编译,比一个个执行sql语句效率高)

 

 

 

8. MySQL索引种类

 

索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),更通俗的说,

 

数据库索引比如是一本书前面的目录,能加快数据库的查询速度MySQL索引的类型:  

 

1. 普通索引:这是最基本的索引,它没有任何限制  

 

2.惟一索引:索引列的值必须惟一,但容许有空值,若是是组合索引,则列值的组合必须惟一  

 

3.全文索引:全文索引仅可用于 MyISAM 表,能够从CHAR、VARCHAR或TEXT列中做为

 

CREATE TABLE语句的一部分被建立,或是随后使用ALTER TABLE 或CREATE INDEX被添加

 

(切记对于大容量的数据表,生成全文索引是一个很是消耗时间很是消耗硬盘空间的作法)  

 

4. 单列索引、多列索引:多个单列索引与单个多列索引的查询效果不一样,

 

由于执行查询时,MySQL只能使用一个索引,会从多个索引中选择一个限制最为严格的索引。  

 

5.组合索引(最左前缀):简单的理解就是只从最左面的开始组合(

 

实在单列索引的基础上进一步压榨索引效率的一种方式

 

 

 

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

 

mysql在使用组合索引查询的时候须要遵循“最左前缀”规则

 

 

 

10. 主键和外键的区别?

 

1.主键是能肯定一条记录的惟一标识

 

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

 

 

 

11. MySQL常见的函数?

 

聚合函数:  

 

AVG(col)返回指定列的平均值  

 

COUNT(col)返回指定列中非NULL值的个数  

 

MIN(col)返回指定列的最小值  

 

MAX(col)返回指定列的最大值  

 

SUM(col)返回指定列的全部值之和  

 

GROUP_CONCAT(col) 返回由属于一组的列值链接组合而成的结果

 

数学函数:  

 

ABS(x) 返回x的绝对值  

 

BIN(x) 返回x的二进制(OCT返回八进制,HEX返回十六进制)

 

 

 

12. 列举 建立索引可是没法命中索引的8种状况。

 

1.若是条件中有or,即便其中有条件带索引也不会使用(这也是为何尽可能少用or的缘由)

 

2.对于多列索引,不是使用的第一部分,则不会使用索引

 

3.like查询是以%开头

 

4.若是列类型是字符串,那必定要在条件中将数据使用引号引用起来,不然不使用索引

 

5.若是mysql估计使用全表扫描要比使用索引快,则不使用索引

 

6 对小表查询

 

7 提示不使用索引

 

8 统计数据不真实

 

9.单独引用复合索引里非第一位置的索引列.

 

 

 

13. 如何开启慢日志查询?

 

1 执行 SHOW VARIABLES LIKE “%slow%”,获知 mysql 是否开启慢查询 slow_query_log

 

慢查询开启状态 OFF 未开启 ON 为开启 slow_query_log_file 慢查询日志存放的位置(

 

这个目录须要MySQL的运行账号的可写权限,通常设置为MySQL的数据存放目录)

 

2 修改配置文件( 放在[mysqld]下),重启 long_query_time 查询超过多少秒才记录

 

3 测试是否成功

 

4 慢查询日志文件的信息格式

 

 

 

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

 

1.导出整个数据库   mysqldump -u用户名 -p密码 数据库名 > 导出的文件名   

 

例如:C:\Users\jack> mysqldump -uroot -pmysql sva_rec > e:\sva_rec.sql   

 

2.导出一个表,包括表结构和数据   mysqldump -u用户名 -p 密码 数据库名 表名> 导出的文件名   

 

例如:C:\Users\jack> mysqldump -uroot -pmysql sva_rec date_rec_drv> e:\date_rec_drv.sql   

 

3.导出一个数据库结构   

 

例如:C:\Users\jack> mysqldump -uroot -pmysql -d sva_rec > e:\sva_rec.sql

 

4.导出一个表,只有表结构   mysqldump -u用户名 -p 密码 -d数据库名 表名> 导出的文件名    

 

例如:C:\Users\jack> mysqldump -uroot -pmysql -d sva_rec date_rec_drv> e:\date_rec_drv.sql   

 

5.导入数据库   经常使用source 命令   进入mysql数据库控制台,   

 

mysql -u root -p   mysql>use 数据库   而后使用source命令,后面参数为脚本文件(如这里用到的.sql)   

 

mysql>source d:wcnc_db.sql

 

 

 

15. 数据库优化方案?

 

整体思路从如下几个方面:

 

一、选取最适用的字段属性

 

二、使用链接(JOIN)来代替子查询(Sub-Queries)

 

三、使用联合(UNION)来代替手动建立的临时表

 

四、事务(当多个用户同时使用相同的数据源时,它能够利用锁定数据库的方法来为用户提供一种安全的访问方式,

 

这样能够保证用户的操做不被其它的用户所干扰)

 

5.锁定表(有些状况下咱们能够经过锁定表的方法来得到更好的性能)

 

六、使用外键(锁定表的方法能够维护数据的完整性,可是它却不能保证数据的关联性。

 

这个时候咱们就能够使用外键)

 

七、使用索引

 

八、优化的查询语句(绝大多数状况下,使用索引能够提升查询的速度,但若是SQL语句使用不恰当的话,

 

索引将没法发挥它应有的做用)

 

 

 

16. char和varchar的区别?

 

char:定长,char的存取数度相对快

 

varchar:不定长,存取速度相对慢

 

 

 

17. 简述MySQL的执行计划?

 

执行计划explain命令是查看查询优化器如何决定执行查询的主要方法。

 

这个功能有局限性,并不总会说出真相,但它的输出是能够获取的最好信息,经过输出结果反推执行过程

 

 

 

18. 在对name作了惟一索引前提下,简述如下区别:


 

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


 

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

 

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

 

查找到tb表中全部name = ‘Oldboy’的数据

 

select * from tb where name = ‘Oldboy’ limit 1------

 

查找到tb表中全部name = ‘Oldboy’的数据只取其中的第一条

 

 

 

19. 1000w条数据,使用limit offset 分页时,为何越日后翻越慢?如何解决?

 

当一个数据库表过于庞大,LIMIT offset, length中的offset值过大,则SQL查询语句会很是缓慢,

 

你需增长order by,而且order by字段须要创建索引。

 

 

 

20. 什么是索引合并?

 

1.索引合并是把几个索引的范围扫描合并成一个索引。

 

二、索引合并的时候,会对索引进行并集,交集或者先交集再并集操做,以便合并成一个索引。

 

三、这些须要合并的索引只能是一个表的。不能对多表进行索引合并。

 

 

 

21. 什么是覆盖索引?

 

覆盖索引又能够称为索引覆盖。

 

  解释一: 就是select的数据列只用从索引中就可以取得,没必要从数据表中读取,

 

换句话说查询列要被所使用的索引覆盖。

 

  解释二: 索引是高效找到行的一个方法,当能经过检索索引就能够读取想要的数据,

 

那就不须要再到数据表中读取行了。若是一个索引包含了(或覆盖了)知足查询语句中字段

 

与条件的数据就叫作覆盖索引。

 

  解释三: 是非汇集组合索引的一种形式,它包括在查询里的Select、Join和Where子句用到的全部列

 

(即创建索引的字段正好是覆盖查询语句[select子句]与查询条件[Where子句]中所涉及的字段,

 

也即,索引包含了查询正在查找的全部数据)。

 

 

 

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

 

读写分离从字面意思就能够理解,就是把对数据库的读操做和写操做分离开。

 

读写分离在网站发展初期能够必定程度上缓解读写并发时产生锁的问题,

 

将读写压力分担到多台服务器上,一般用于读远大于写的场景。

 

*读写分离的好处*

 

1)数据是网站的生命,读写分离经过主从备份数据,保证了系统的冗余,保护了珍贵的数据。

 

2)提升了系统性能,必定程度提升了数据库负载能力。

 

*适用读写分离场景*

 

1)网站初期想要缓解数据负载最简单可行的方案。

 

2)服务器面对的是读远大于写的场景,而且业务可以容许时间上一些延迟。

 

*读写分离实现方式*

 

目前读写分离方案网上找了几个并作了对比。

 

1.mycat 基于阿里的cobar改版的(比较稳定,论坛活跃)

 

2.atlas 360开发的 网友说不是很稳定 (已经好久没更新)

 

3.mysql-proxy mysql自带 (不是很稳定)

 

4.oneproxy 比较稳定 性能也很好 (须要付费)

 

5.amoeba 好像还行,有一些公司使用 (可是好久没有更新了)

 

 

 

 

 

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

 

从字面上简单理解,就是把本来存储于一个库的数据分块存储到多个库上,

 

把本来存储于一个表的数据分块存储到多个表上。

 

 

 

数据库中的数据量不必定是可控的,在未进行分库分表的状况下,随着时间和业务的发展,

 

库中的表会愈来愈多,表中的数据量也会愈来愈大,相应地,数据操做,增删改查的开销也会愈来愈大;

 

另外,因为没法进行分布式式部署,而一台服务器的资源(CPU、磁盘、内存、IO等)是有限的,

 

最终数据库所能承载的数据量、数据处理能力都将遭遇瓶颈。

 

 

 

分库分表有垂直切分和水平切分两种。

 

何谓垂直切分,即将表按照功能模块、关系密切程度划分出来,部署到不一样的库上。

 

例如,咱们会创建定义数据库workDB、商品数据库payDB、用户数据库userDB、日志数据库logDB等,

 

分别用于存储项目数据定义表、商品定义表、用户数据表、日志数据表等。

 

 

 

何谓水平切分,当一个表中的数据量过大时,咱们能够把该表的数据按照某种规则,

 

例如userID散列,进行划分,而后存储到多个结构相同的表,和不一样的库上。

 

例如,咱们的userDB中的用户数据表中,每个表的数据量都很大,

 

就能够把userDB切分为结构相同的多个userDB:part0DB、part1DB等,

 

再将userDB上的用户数据表userTable,切分为不少userTable:userTable0、userTable1等,

 

而后将这些表按照必定的规则存储到多个userDB上。

 

 

 

 

 

 

 

24. redis和memcached比较?

 

一、Redis和Memcache都是将数据存放在内存中,都是内存数据库。不过memcache还可用于缓存其余东西。例如图片、视频等等;

 

二、Redis不只仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储;

 

三、虚拟内存--Redis当物理内存用完时,能够将一些好久没用到的value

 

 交换到磁盘;

 

四、过时策略--memcache在set时就指定,例如set key1 0 0 8,即永不过时。Redis能够经过例如expire 设定,

 

例如expire name 10;

 

五、分布式--设定memcache集群,利用magent作一主多从;redis能够作一主多从。均可以一主一从;

 

六、存储数据安全--memcache挂掉后,数据没了;redis能够按期保存到磁盘(持久化);

 

七、灾难恢复--memcache挂掉后,数据不可恢复;

 

 redis数据丢失后能够经过aof恢复;

 

八、Redis支持数据的备份,即master-slave模式的数据备份;

 

九、应用场景不同:Redis出来做为NoSQL数据库使用外,还能用作消息队列、数据堆栈和数据缓存等;

 

Memcached适合于缓存SQL语句、数据集、用户临时性数据、延迟查询数据和session等。

 

 

 

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

 

#redis默认有16dbdb0~db15(能够经过配置文件支持更多,无上限)

 

而且每一个数据库的数据是隔离的不能共享

 

能够随时使用SELECT命令更换数据库:redis> SELECT 1#

 

注意:     

 

多个数据库之间并非彻底隔离的

 

       好比FLUSHALL命令能够清空一个Redis实例中全部数据库中的数据。

 

 

 

26. python操做redis的模块?

 

一、基本操做

 

redis提供两个类Redis和StrictRedis用于实现Redis的命令,StrictRedis用于实现大部分官方的命令,并使用官方的语法和命令,Redis是StrictRedis的子类,用于向后兼容旧版本的redis-py。

 

redis链接实例是线程安全的,能够直接将redis链接实例设置为一个全局变量,直接使用。若是须要另外一个Redis实例(or Redis数据库)时,就须要从新建立redis链接实例来获取一个新的链接。同理,python的redis没有实现select命令。

 

链接redis,加上decode_responses=True,写入的键值对中的value为str类型,不加这个参数写入的则为字节类型。

 

链接池

 

(1) redis-py使用connection pool来管理对一个redis server的全部链接,避免每次创建、释放链接的开销。默认,每一个Redis实例都会维护一个本身的链接池。
能够直接创建一个链接池,而后做为参数Redis,这样就能够实现多个Redis实例共享一个链接池

 

二、管道

 

redis默认在执行每次请求都会建立(链接池申请链接)和断开(归还链接池)一次链接操做,
若是想要在一次请求中指定多个命令,则能够使用pipline实现一次请求指定多个命令,而且默认状况下一次pipline 是原子性操做。

 

管道(pipeline)是redis在提供单个请求中缓冲多条服务器命令的基类的子类。它经过减小服务器-客户端之间反复的TCP数据库包,从而大大提升了执行批量命令的功能。

 

三、发布订阅

 

 

 

27. 若是redis中的某个列表中的数据量很是大,若是实现循环显示每个值?

 

经过scan_iter分片取,减小内存压力

 

scan_iter(match=None, count=None)增量式迭代获取redis里匹配的的值# match,匹配指定key

 

# count,每次分片最少获取个数

 

     r = redis.Redis(connection_pool=pool)

 

     for key in r.scan_iter(match='PREFIX_*', count=100000):

 

         print(key)

 

 

 

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

 

Redis中的主从复制,也就是Master-Slave模型,其实现相对比较简单,通常使用在多个Redis实例间

 

的数据同步以及Redis集群中用的比较多。

 

Redis的主从同步机制能够确保redis的master和slave之间的数据同步。按照同步内容的多少能够分为

 

全同步和部分同步;按照同步的时机能够分为slave刚启动时的初始化同步和正常运行过程当中的数据

 

修改同步;本文将对这两种机制的流程进行分析。

 

# 实现主从复制

 

    '建立63796380配置文件'

 

    redis.conf6379为默认配置文件,做为Master服务配置;

 

    redis_6380.conf6380为同步配置,做为Slave服务配置;

 

    '配置slaveof同步指令'

 

    Slave对应的conf配置文件中,添加如下内容:

 

    slaveof 127.0.0.1 6379# 数据同步步骤:

 

    (1)Slave服务器链接到Master服务器.

 

    (2)Slave服务器发送同步(SYCN)命令.

 

    (3)Master服务器备份数据库到文件.

 

    (4)Master服务器把备份文件传输给Slave服务器.

 

    (5)Slave服务器把备份文件数据导入到数据库中.

 

 

 

29. redis中的sentinel的做用?

 

Redis SentinelSentinel(哨兵)是用于监控redis集群中Master状态的工具,其已经被集成在redis2.4+的版本中。

 

Sentinel做用:

 

  1):Master状态检测

 

  2):若是Master异常,则会进行Master-Slave切换,将其中一个Slave做为Master,将以前的Master做为Slave

 

  3):Master-Slave切换后,master_redis.conf、slave_redis.conf和sentinel.conf的内容都会发生改变,

 

master_redis.conf中会多一行slaveof的配置,sentinel.conf的监控目标会随之调换

 

 

 

  1. 如何实现redis集群?

 

#基于【分片】来完成。

 

    - 集群是将你的数据拆分到多个Redis实例的过程

 

    - 能够使用不少电脑的内存总和来支持更大的数据库。

 

    - 没有分片,你就被局限于单机能支持的内存容量。#redis将全部能放置数据的地方建立了 16384 个哈希槽。

 

#若是设置集群的话,就能够为每一个实例分配哈希槽:

 

    - 192.168.1.200-5000

 

    - 192.168.1.215001-10000

 

    - 192.168.1.2210001-16384#之后想要在redis中写值时:set k1 123

 

    - k1经过crc16的算法转换成一个数字,而后再将该数字和16384求余,

 

    - 若是获得的余数 3000,那么就将该值写入到 192.168.1.20 实例中。#集群方案:

 

    - redis cluster:官方提供的集群方案。

 

    - codis:豌豆荚技术团队。

 

    - tweproxyTwiter技术团队

 

 

 

一般有3个途径:官方Redis Cluster;经过Proxy分片;客户端分片(Smart Client)

 

Redis Cluster(官方):虽然正式版发布已经有一年多的时间,但还缺少最佳实践;

 

对协议进行了较大修改,致使主流客户端也并不是都已支持,部分支持的客户端也没有通过大规模生产环境的验证;

 

无中心化设计使整个系统高度耦合,致使很难对业务进行无痛的升级。

 

Proxy:如今不少主流的Redis集群都会使用Proxy方式,例如早已开源的Codis。这种方案有不少优势,

 

由于支持原声redis协议,因此客户端不须要升级,对业务比较友好。而且升级相对平滑,能够起多个Proxy后,

 

逐个进行升级。可是缺点是,由于会多一次跳转,平均会有30%左右的性能开销。

 

并且由于原生客户端是没法一次绑定多个Proxy,链接的Proxy若是挂了仍是须要人工参与。除非相似Smart

 

 Client同样封装原有客户端,支持重连到其余Proxy,但这也就带来了客户端分片方式的一些缺点。而且虽然Proxy能够使用多个,而且能够动态增长proxy增长性能,可是全部客户端都是共用全部proxy,那么一些异常的服务有可能影响到其余服务。为每一个服务独立搭建proxy,也会给部署带来额外的工做。而咱们选择了第三种方案,客户端分片(SmartClient)。客户端分片相比Proxy拥有更好的性能,及更低的延迟。固然也有缺点,就是升级须要重启客户端,并且咱们须要维护多个语言的版本,但咱们更爱高性能。

 

 

 

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

 

Redis 集群有16384个哈希槽,每一个key经过CRC16校验后对16384取模来决定放置哪一个槽.

 

集群的每一个节点负责一部分hash槽

 

 

 

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

 

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

 

     - 缺点:数据不完整

 

     - 优势:速度快

 

#AOF:把全部命令保存起来,若是想从新生成到redis,那么就要把命令从新执行一次。

 

     - 缺点:速度慢,文件比较大

 

     - 优势:数据完整

 

 

 

Redis的持久化策略:2种

 

    ---------rdb:快照形式是直接把内存中的数据保存到一个dump文件中,定时保存,保存策略

 

    ---------aof:把全部的对redis的服务器进行修改的命令都存到一个文件里,命令的集合

 

RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操做过程是fork一个子进程,

 

先将数据集写入临时文件,写入成功后,再替换以前的文件,用二进制压缩存储。

 

AOF持久化以日志的形式记录服务器所处理的每个写、删除操做,查询操做不会记录,以文本的方式记录,能够打开文件看到详细的操做记录

 

 

 

33. 列举redis支持的过时策略。

 

maxmemory-policy 六种方式

 

volatile-lru:只对设置了过时时间的key进行LRU(默认值) 

 

allkeys-lru  删除lru算法的key   

 

volatile-random:随机删除即将过时key   

 

allkeys-random:随机删除   

 

volatile-ttl  删除即将过时的   

 

noeviction  永不过时,返回错误  

 

 

 

34. 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(驱逐):禁止驱逐数据

 

 

 

# 限定Redis占用的内存,根据自身数据淘汰策略,淘汰冷数据,把热数据加载到内存。

 

# 计算一下 20W 数据大约占用的内存,而后设置一下Redis内存限制便可。

 

 

 

 

 

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

 

 

 

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

 

能够利用redis存储数据类型的list类型实现消息发送与消费的一对一模式,使用lpush向list的左端推送数据(发送消息),使用rpop从右端接收数据(消费消息)。因为rpop须要周期性的从list中获取数据,能够考虑使用brpop代替rpop,brpop是一个阻塞方法,直到获取到数据

 

# 经过发布订阅模式的PUBSUB实现消息队列

 

# 发布者发布消息到频道了,频道就是一个消息队列。

 

# 发布者: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,用它作缓存、作计算,还作任务队列,压力太大,很差。

 

 

 

 

 

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

 

# 发布和订阅,只要有任务就全部订阅者每人一份。

 

发布者: #发布一次

 

    import redis

 

    conn = redis.Redis(host='127.0.0.1',port=6379)

 

    conn.publish('104.9MH', "hahahahahaha")

 

订阅者: #'while True'一直在接收

 

    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)

 

 

 

38. 什么是codis及做用?

 

Codis 是一个分布式 Redis 解决方案, 对于上层的应用来讲, 链接到 Codis Proxy 和链接原生的

 

Redis Server 没有明显的区别 (不支持的命令列表), 上层应用能够像使用单机的 Redis 同样使用,

 

Codis 底层会处理请求的转发, 不停机的数据迁移等工做, 全部后边的一切事情,

 

对于前面的客户端来讲是透明的, 能够简单的认为后边链接的是一个内存无限大的 Redis 服务.

 

 

 

39. 什么是twemproxy及做用?

 

Twemproxy 也叫 nutcraker。是 Twtter 开源的一个 Redis 和 Memcache 代理服务器,

 

主要用于管理 Redis 和 Memcached 集群,减小与Cache 服务器直接链接的数量

 

其功能:

 

经过代理的方式减小缓存服务器的链接数。

 

自动在多台缓存服务器间共享数据。

 

经过不一样的策略与散列函数支持一致性散列。

 

经过配置的方式禁用失败的结点。

 

运行在多个实例上,客户端能够链接到首个可用的代理服务器。

 

支持请求的流式与批处理,于是可以下降来回的消耗。

 

 

 

40. 写代码实现redis事务操做。

 

使用MULTI命令即可以进入一个Redis事务。这个命令的返回值老是OK。此时,用户能够发出多个Redis命令。Redis会将这些命令放入队列,而不是执行这些命令。一旦调用EXEC命令,那么Redis就会执行事务中的全部命令。相反,调用DISCARD命令将会清除事务队列,而后退出事务。

 

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', 'zgc')

 

pipe.set('role', 'haha')

 

pipe.lpush('roless', 'haha')# 提交pipe.execute()'注意':咨询是否当前分布式redis是否支持事务

 

 

 

41. redis中的watch的命令的做用?

 

watch 用于在进行事务操做的最后一步也就是在执行exec 以前对某个key进行监视

 

若是这个被监视的key被改动,那么事务就被取消,不然事务正常执行.

 

通常在MULTI 命令前就用watch命令对某个key进行监控.若是想让key取消被监控,能够用unwatch命令

 

 

 

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

 

指定键的值作加加操做,返回加后的结果。

 

'经过rediswatch实现'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()

 

数据库的锁

 

 

 

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

 

在不一样进程须要互斥地访问共享资源时,分布式锁是一种很是有用的技术手段。  

 

一个Client想要得到一个锁须要如下几个操做:

 

获得本地时间Client使用相同的key和随机数,按照顺序在每一个Master实例中尝试得到锁。在得到锁的过程当中,为每个锁操做设置一个快速失败时间(若是想要得到一个10秒的锁, 那么每个锁操做的失败时间设为5-50ms)。这样能够避免客户端与一个已经故障的Master通讯占用太长时间,经过快速失败的方式尽快的与集群中的,其余节点完成锁操做。客户端计算出与master得到锁操做过程当中消耗的时间,当且仅当Client得到锁消耗的时间小于锁的存活时间,

 

而且在一半以上的master节点中得到锁。才认为client成功的得到了锁。

 

若是已经得到了锁,Client执行任务的时间窗口是锁的存活时间减去得到锁消耗的时间。

 

若是Client得到锁的数量不足一半以上,或得到锁的时间超时,那么认为得到锁失败。

 

客户端须要尝试在全部的master节点中释放锁, 即便在第二步中没有成功得到该Master节点中的锁,

 

仍要进行释放操做。

 

# redis分布式锁?

 

# 不是单机操做,又多了一/多台机器

 

# redis内部是单进程、单线程,是数据安全的(只有本身的线程在操做数据)

 

----------------------------------------------------------------#ABC,三个实例()

 

1、来了一个'隔壁老王'要操做,且不想让别人操做,so,加锁;

 

    加锁:'隔壁老王'本身生成一个随机字符串,设置到ABC(xxx=666)2、来了一个'邻居老李'要操做ABC,一读发现里面有字符串,擦,被加锁了,不能操做了,等着吧~

 

3'隔壁老王'解决完问题,不用锁了,把ABC里的key'xxx'删掉;完成解锁4'邻居老李'如今能够访问,能够加锁了# 问题:

 

1、若是'隔壁老王'加锁后忽然挂了,就没人解锁,就死锁了,其余人干看着无法用咋办?2、若是'隔壁老王'去给ABC加锁的过程当中,刚加到A,'邻居老李'就去操做C了,加锁成功or失败?3、若是'隔壁老王'去给ABC加锁时,C忽然挂了,此次加锁是成功仍是失败?4、若是'隔壁老王'去给ABC加锁时,超时时间为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

 

 

 

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

 

# 一致性哈希一致性hash算法(DHT)能够经过减小影响范围的方式,解决增减服务器致使的数

 

据散列问题,从而解决了分布式环境下负载均衡问题;

 

若是存在热点数据,能够经过增添节点的方式,对热点区间进行划分,将压力分配至其余服务器, 从新达到负载均衡的状态。# 模块:hash_ring

 

 

 

45. 如何高效的找到redis中全部以zhugc开头的key?

 

redis 有一个keys命令。

 

# 语法:KEYS pattern

 

# 说明:返回与指定模式相匹配的所用的keys该命令所支持的匹配模式以下:1?:用于匹配单个字符。例如,h?llo能够匹配hellohallohxllo等;2*:用于匹配零个或者多个

 

字符。例如,h*llo能够匹配hlloheeeello等;2[]:能够用来指定模式的选择区间。例如h[ae]llo能够匹配hellohallo,可是不能匹配hillo。同时,能够使用“/”符号来转义特殊的字符# 注意KEYS 的速度很是快,但若是数据太大,内存可能会崩掉,

 

若是须要从一个数据集中查找特定的key,最好仍是用Redis的集合结构(set)来代替。

 

4八、悲观锁和乐观锁的区别?

 

# 悲观锁    从数据开始更改时就将数据锁住,直到更改完成才释放;会形成访问数据库时间较长,并发性很差,特别是长事务。# 乐观锁    直到修改完成,准备提交修改到数据库时才会锁住数据,完成更改后释放;相对悲观锁,在现实中使用较多。

 

 前端及其余                     

 

 

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

 

HTTP协议(HyperText Transfer Protocol,超文本传输协议)是用于从WWW服务器传输超文本到本地浏览器的传送协议。它能够使浏览器更加高效,使网络传输减小。它不只保证计算机正确快速地传输超文本文档,还肯定传输文档中的哪一部分,以及哪部份内容首先显示(如文本先于图形)等。 

 

HTTP是一个应用层协议,由请求和响应构成,是一个标准的客户端服务器模型。HTTP是一个无状态的协议。端口号为80

 

 

 

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

 

WebSocket是HTML5开始提供的一种在单个 TCP 链接上进行全双工通信的协议。

 

WebSocket API中,浏览器和服务器只须要作一个握手的动做,而后,浏览器和服务器之间就造成了,一条快速通道。二者之间就直接能够数据互相传送。

 

浏览器经过 JavaScript 向服务器发出创建 WebSocket 链接的请求,链接创建之后,

 

客户端和服务器端就能够经过 TCP 链接直接交换数据。

 

 

 

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-width768px{

 

     .pg-header{

 

           

 

      }      

 

}

 

@media   (min-width:992px){

 

     .pg-header{

 

            

 

     }

 

}    

 

 

 

代码

 

<!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{

 

            

 

            height: 48px;

 

        }

 

 

 

        @media (min-width: 768px) {

 

            .pg-header{

 

                

 

            }

 

        }

 

        @media (min-width: 992px) {

 

            .pg-header{

 

                

 

            }

 

        }

 

    </style>

 

</head>

 

<body>

 

    <div class="pg-header"></div>

 

</body>

 

</html>

 

 

 

 

 

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

 

Bootstrap / vue、Django

 

jQuery

 

 Vue.js(vue齐名的前端框架ReactAngular)

 

 

 

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

 

AJAX是在不加载整个页面的状况异步下与服务器发送请求交换数据并更新部分网页的艺术

 

 

 

$.ajax({    url:'user/add',//当前请求的url地址    

 

type:'get',//当前请求的方式 get post   

 

data:{id:100},//请求时发送的参数    

 

dataType:'json',//返回的数据类型    

 

success:function(data){        //ajax请求成功后执行的代码        

 

console.log(data);    },    

 

error:function(){        //ajax执行失败后执行的代码        

 

alert('ajax执行错误');    },    

 

timeout:2000,//设置当前请求的超时时间 异步请求生效    

 

async:true //是否异步 false同步 true异步})

 

 

 

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

 

特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP request,

 

而后由服务器返回最新的数据给客户端的浏览器。

 

<!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. 如何在前端实现长轮训?

 

ajax实现:在发送ajax后,服务器端会阻塞请求直到有数据传递或超时才会返回,

 

客户端js响应处理函数会在处理完服务器返回的信息后在次发出请求,

 

从新创建链接

 

 

 

<!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:路由系统,添加动态参数

 

5cookie操做:vue-cookies

 

6:多组件之间共享:vuex

 

7:发送ajax请求:axios (js模块)

 

 

 

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

 

vue-resourceinterceptors拦截器的做用正是解决此需求的妙方。
在每次http的请求响应以后,若是设置了拦截器以下,会优先执行拦截器函数,获取响应体,而后才会决定是否把response返回给then进行接收

 

 

 

11. axios的做用?

在浏览器中发送 XMLHttpRequests 请求

node.js 中发送 http请求

支持 Promise API

拦截请求和响应

转换请求和响应数据

自动转换 JSON 数据

客户端支持保护安全免受 XSRF 攻击

 

12. 列举vue的常见指令。

1v-if指令:判断指令,根据表达式值得真假来插入或删除相应的值。

   2v-show指令:条件渲染指令,不管返回的布尔值是true仍是false,元素都会存在在 html中,只是false的元素会隐藏在html中,并不会删除.

   3v-else指令:配合v-ifv-else使用。

   4v-for指令:循环指令,至关于遍历。

   5v-bind:DOM绑定元素属性。

   6v-on指令:监听DOM事件。

 

13. 简述jsonp及实现原理?

JSONP是用来解决跨域请求问题的 

跨域:协议 域名 端口号有一个不同就是跨域 

实现原理: 

script标签src属性中的连接却能够访问跨域的js脚本,利用这个特性,服务端再也不返回JSON格式的数据,

而是返回一段调用某个函数的js代码,在src中进行了调用,这样实现了跨域。

 

14.什么是什么cors ?

CORS

浏览器将CORS请求分红两类:简单请求和赋复杂请求

 

简单请求(同时知足如下两大条件)

1)请求方法是如下三种方法之一:

HEAD

GET

POST

2HTTP的头信息不超出如下几种字段:

Accept

Accept-Language

Content-Language

Last-Event-ID

Content-Type  :只限于三个值application/x-www-form-urlencodedmultipart/form-datatext/plain

凡是不一样时知足上面两个条件,就属于非简单请求

 

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

GET/POST

 

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

1**  信息,服务器收到请求,须要请求者继续执行操做

2**  成功,操做被成功接收并处理

3** 重定向,须要进一步的操做以完成请求

4** 客户端错误,请求包含语法错误或没法完成请求

5** 服务器错误,服务器在处理请求的过程当中发生了错误

 

常见的状态码

200 -请求成功
202 -已接受请求,还没有处理
204 -请求成功,且不需返回内容

301 - 资源(网页等)被永久转移到其余url
400 - 请求的语义或是参数有错
403 - 服务器拒绝请求

404 - 请求资源(网页)不存在

500 - 内部服务器错误
502 - 网关错误,通常是服务器压力过大致使链接超时
503 - 因为超载或系统维护,服务器暂时的没法处理客户端的请求

 

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

User-Agent:浏览器类型,若是Servlet返回的内容与浏览器类型有关则该值很是有用。

Cookie:这是最重要的请求头信息之一

Content-Type:请求类型

 

18.alert(李杰)

 

19.console.log('武沛齐')

 

20.

console.log(‘老男孩’)

 

21.结果什么也没有 由于console.log.的时候xo尚未定义

 

22.alert(”武沛齐’)

 

23.alert(”武沛齐’)

 

24.

Django:Python 界最全能的 web 开发框架,battery-include 各类功能完备,可维护性和开发速度一级棒。

常有人说 Django 慢,其实主要慢在 Django ORM 与数据库的交互上,因此是否选用 Django,

取决于项目对数据库交互的要求以及各类优化。而对于 Django 的同步特性致使吞吐量小的问题,

其实能够经过 Celery 等解决,倒不是一个根本问题。Django 的项目表明:Instagram,Guardian。

Tornado:天生异步,性能强悍是 Tornado 的名片,然而 Tornado 相比 Django 是较为原始的框架,诸多内容须要本身去处理。固然,随着项目愈来愈大,框架可以提供的功能占比愈来愈小,

更多的内容须要团队本身去实现,而大项目每每须要性能的保证,这时候 Tornado 就是比较好的选择。Tornado项目表明:知乎。

Flask:微框架的典范,号称 Python 代码写得最好的项目之一。Flask 的灵活性,也是双刃剑:

能用好 Flask 的,能够作成 Pinterest,用很差就是灾难(显然对任何框架都是这样)。

Flask 虽然是微框架,可是也能够作成规模化的 Flask。加上 Flask 能够自由选择本身的数据库交互组件

(一般是 Flask-SQLAlchemy),并且加上 celery +redis 等异步特性之后,Flask 的性能相对

Tornado 也不逞多让,也许Flask 的灵活性多是某些团队更须要的。

 

25.什么是wsgi?

WSGI(Web Server Gateway Interface,Web 服务器网关接口)则是Python语言中1所定义的Web服务器和Web应用程序之间或框架之间的通用接口标准。

WSGI就是一座桥梁,桥梁的一端称为服务端或网关端,另外一端称为应用端或者框架端,WSGI的做用就是在协议之间进行转化。WSGI将Web组件分红了三类:Web 服务器(WSGI Server)、Web中间件(WSGI Middleware)与Web应用程序(WSGI Application)。

Web Server接收HTTP请求,封装一系列环境变量,按照WSGI接口标准调用注册的WSGI Application,最后将响应返回给客户端。

 

 

26.django请求的生命周期?

前端请求—>nginx—>uwsgi.—>中间件—>url路由—->view试图—>orm—->拿到数据返回给view—->试图将数据渲染到模版中拿到字符串—->中间件—>uwsgi—->nginx—->前端渲染

 

 

27. 列举django的内置组件?

url 、view、model、template、中间件

 

28. 列举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)

 

29. 简述什么是FBV和CBV?

django中请求处理方式有2种:FBV 和 CBV

FBV(function base views) 就是在视图里使用函数处理请求。

CBV(class base views)就是在视图里使用类处理请求 类须要继承view

 

30. django的request对象是在何时建立的?

当请求一个页面时,Django会创建一个包含请求元数据的 HttpRequest 对象。

Django 加载对应的视图时,HttpRequest 对象将做为视图函数的第一个参数。

每一个视图会返回一个HttpResponse 对象。

 

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

from django.views import View  

from django.utils.decorators import method_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('...')

 

 

32. 列举django orm 中全部的方法(QuerySet对象的全部方法)

返回Query Set对象的方法有: 

* all() * filter() * exclude() * order_by() * reverse() * dictinct()

 

特殊的QuerySet: 

* values() 返回一个可迭代的字典序列 

* values_list() 返回一个可迭代的元祖序列

 

返回具体对象的: 

* get() * first() * last()

 

返回布尔值的方法有: * existe()

 

返回数学的方法有: * count( )

 

  1. 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')

 

34. select_related和prefetch_related的区别?

select_related经过多表join关联查询,一次性得到全部数据,经过下降数据库查询次数来提高性能,

但关联表不能太多,由于join操做原本就比较消耗性能

prefetch_related()的解决方法是,分别查询每一个表,而后用Python处理他们之间的关系! 

都是为了减小SQL查询的数量

 

 

35. filter和exclude的区别?

filter是查询知足条件的数据

exclude是查询不知足添加的数据

def filter(self, *args, **kwargs)

      # 条件查询(符合条件)

       # 查出符合条件

      # 条件能够是:参数,字典,Q

 

  def exclude(self, *args, **kwargs)

      # 条件查询(排除条件)

      # 排除不想要的

      # 条件能够是:参数,字典,Q

 

36. 列举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")

 

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

 

方式一:手动使用querysetusing方法

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',]

 

38. F和Q的做用?

F:操做数据表中的某列值,F( )容许Django在未实际连接数据的状况下具备对数据库字段的值的引用,

不用获取对象放在内存中再对字段进行操做,直接执行原生产sql语句操做。

一般状况下咱们在更新数据时须要先从数据库里将原数据取出后方在内存里,而后编辑某些属性,最后提交

Q:对对象进行复杂查询,并支持&(and),|(or),~(not)操做符。

 

39. values和values_list的区别?

values方法能够获取number字段的字典列表。

values_list能够获取number的元组列表。

values_list方法加个参数flat=True能够获取number的值列表。

 

def values(self, *fields):

     # 获取每行数据为字典格式

 

def values_list(self, *fields, **kwargs):

     # 获取每行数据为元祖

 

40. 如何使用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)

 

41. 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                            

  - 应用:只要是客户端向服务端发送表单数据时,均可以进行使用,如:用户登陆注册

 

42. 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

 

43. django的Model中的ForeignKey字段中的on_delete参数有什么做用?

on_delete有CASCADE、PROTECT、SET_NULL、SET_DEFAULT、SET()五个可选择的值

CASCADE:此值设置,是级联删除。

PROTECT:此值设置,是会报完整性错误。

SET_NULL:此值设置,会把外键设置为null,前提是容许为null。

SET_DEFAULT:此值设置,会把设置为外键的默认值。

SET():此值设置,会调用外面的值,能够是一个函数。

 

44. django中csrf的实现机制

Django预防CSRF攻击的方法是在用户提交的表单中加入一个csrftoken的隐含值,这个值和服务器中保存的csrftoken的值相同,这样作的原理以下:

一、在用户访问django的可信站点时,django反馈给用户的表单中有一个隐含字段csrftoken,这个值是在服务器端随机生成的,每一次提交表单都会生成不一样的值

二、当用户提交django的表单时,服务器校验这个表单的csrftoken是否和本身保存的一致,来判断用户的合法性

三、当用户被csrf攻击从其余站点发送精心编制的攻击请求时,因为其余站点不可能知道隐藏的csrftoken字段的信息这样在服务器端就会校验失败,攻击被成功防护

具体配置以下:template中添加{%csrf_token%}标签

 

45. django如何实现websocket?

利用dwebsocket在Django中使用Websocket

django中能够经过channel实现websocke

 

46. 基于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>

 

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

 

settings.py中添加:

LOGGING = {

'disable_existing_loggers': False,

'version': 1,

'handlers': {

'console': {

# logging handler that outputs log messages to terminal

'class': 'logging.StreamHandler',

'level': 'DEBUG', # message level to be written to console

},

},

'loggers': {

'': {

# this sets root level logger to log debug and higher level

# logs to console. All other loggers inherit settings from

# root level logger.

'handlers': ['console'],

'level': 'DEBUG',

'propagate': False, # this tells logger to send logging message

# to its parent (will send if set to True)

},

'django.db': {

# # django also has database level logging

'handlers': ['console'],

'level': 'DEBUG',

'propagate': False,

},

},

}

 

 

48. django缓存如何设置?

  三种粒度缓存

   1 中间件级别

       'django.middleware.cache.UpdateCacheMiddleware',

       'django.middleware.cache.FetchFromCacheMiddleware',

        CACHE_MIDDLEWARE_SECONDS=10

 

   2 视图级别

      from django.views.decorators.cache import cache_page

      @cache_page(15)

      def index(request):

          import time

          t=time.time()

          return render(request,"index.html",locals())

 

   3 局部缓存

      {% load cache %}

          ...

          ...

      {% cache 15 "time_cache" %}

      <h3>缓存时间:{{ t }}</h3>

      {% endcache %}

 

49. 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('...')

 

50. django路由系统中name的做用?

反向解析路由字符串

路由系统中name的做用:反向解析
url(r'^home', views.home, name='home')
在模板中使用:{ % url 'home' %}
在视图中使用:reverse(“home”

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

filter : 相似管道,只能接受两个参数第一个参数是|前的数据

simple_tag : 相似函数

一、模板继承:{ % extends 'layouts.html' %}
二、自定义方法
     'filter':只能传递两个参数,能够在if、for语句中使用
     'simple_tag':能够无线传参,不能在if for中使用
     'inclusion_tags':能够使用模板和后端数据
三、防xss攻击: '|safe''mark_safe'

52. django-debug-toolbar的做用?

django_debug_toolbar 是django的第三方工具包,给django扩展了调试功能。

包括查看执行的sql语句,db查询次数,request,headers,调试概览等。

https://blog.csdn.net/weixin_39198406/article/details/78821677

 

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

对于每个测试方法都会将setUp()tearDown()方法执行一遍

会单独新建一个测试数据库来进行数据库的操做方面的测试,默认在测试完成后销毁。

 

 

 

 

在测试方法中对数据库进行增删操做,最后都会被清除。也就是说,在test_add中插入的数据,在test_add测试结 束后插入的数据会被清除。

 

django单元测试时为了模拟生产环境,会修改settings中的变量,例如, DEBUG变量修改成True, ALLOWED_HOSTS修改成[*]

 

 

 

 

 

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

 

db first: 先建立数据库,再更新表模型

 

code first:先写表模型,再更新数据库

 

 

 

datebase first就是表明数据库优先,那么前提就是先建立数据库。

 

model first就是表明model优先,那么前提也就是先建立model,而后根据model自动创建数据库。

 

 

 

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

 

1、修改seting文件,在setting里面设置要链接的数据库类型和名称、地址

 

2、运行下面代码能够自动生成models模型文件

 

       - python manage.py inspectdb

 

3、建立一个app执行下下面代码:

 

       - python manage.py inspectdb > app/models.py

 

 

 

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

 

ORM框架:

 

  对象关系映射,经过建立一个类,这个类与数据库的表相对应!类的对象代指数据库中的一行数据。

 

简述ORM原理:

 

  让用户再也不写SQL语句,而是经过类以及对象的方式,和其内部提供的方法,进行数据库操做!把用户输入的类或对象转换成SQL语句,转换以后经过pymysql执行完成数据库的操做。

 

ORM的优缺点:

 

优势: 

 

* 提升开发效率,下降开发成本 

 

* 使开发更加对象化 

 

* 可移植 

 

* 能够很方便地引入数据缓存之类的附加功能

 

缺点: 

 

* 在处理多表联查、where条件复杂之类的查询时,ORM的语法会变得复杂。就须要写入原生SQL

 

 

 

57. 简述MVC和MTV

 

MVC: 模型 视图 控制器

 

MTV: 模型 模板 视图

 

 

 

58. django的contenttype组件的做用?

 

django内置的ContentType组件就是帮咱们作连表操做

 

若是一个表与其余表有多个外键关系,咱们能够经过ContentType来解决这种关联

 

http://www.cnblogs.com/iyouyue/p/8810464.html

 

 

 

59. 谈谈你对restfull 规范的认识?

 

restful其实就是一套编写接口的协议,协议规定如何编写以及如何设置返回值、状态码等信息。 

 

最显著的特色: 

 

restful: 给用户一个url,根据method不一样在后端作不一样的处理,好比:post 建立数据、get获取数据、put和patch修改数据、delete删除数据。 

 

no rest: 给调用者不少url,每一个url表明一个功能,好比:add_user/delte_user/edit_user/

 

固然,还有协议其余的,好比: 

 

版本,来控制让程序有多个版本共存的状况,版本能够放在 url、请求头(accept/自定义)、GET参数

 

状态码,200/300/400/500

 

url中尽可能使用名词,restful也能够称为“面向资源编程”

 

api标示: 

 

api.YueNet.com 

 

www.YueNet.com/api/

 

 

 

 

 

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

 

一个接口经过首先进行1次访问,而后对该接口进行N次相同访问的时候,对访问对象不形成影响,那么就认为接口具备幂等性。 

 

好比: 

 

* GET, 第一次获取数据、第二次也是获取结果,幂等。 

 

* POST, 第一次新增数据,第二次也会再次新增,非幂等。 

 

* PUT, 第一次更新数据,第二次不会再次更新,幂等。 

 

* PATCH,第一次更新数据,第二次可能再次更新,非幂等。 

 

* DELTE,第一次删除数据,第二次不会再次删除,幂等。

 

 

 

 

 

61. 什么是RPC?

 

RPC(Remote Procedure Call)—远程过程调用,它是一种经过网络从远程计算机程序上请求服务,而不须要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通讯程序之间携带信息数据。在OSI网络通讯模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。

 

 

 

62. Http和Https的区别?

 

超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息,HTTP协议以明文方式发送内容,不提供任何方式的数据加密,若是攻击者截取了Web浏览器和网站服务器之间的传输报文,就能够直接读懂其中的信息,所以,HTTP协议不适合传输一些敏感信息,好比:信用卡号、密码等支付信息。

 

为了解决HTTP协议的这一缺陷,须要使用另外一种协议:安全套接字层超文本传输协议HTTPS,为了数据传输的安全,HTTPS在HTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器的身份,并为浏览器和服务器之间的通讯加密。

 

#Http: 80端口

 

#https: 443端口

 

# http信息是明文传输,https则是具备安全性的ssl加密传输协议。

 

#- 自定义证书

 

    - 服务端:建立一对证书

 

    - 客户端:必须携带证书

 

#- 购买证书

 

    - 服务端: 建立一对证书,。。。。

 

    - 客户端: 去机构获取证书,数据加密后发给我们的服务单

 

    - 证书机构:公钥给改机构

 

 

 

6三、为何要使用django rest framework框架?

 

 

 

1.客户端-服务端分离 

 

优势:提升用户界面的便携性,经过简化服务器提升可伸缩性…. 

 

2.无状态(Stateless):从客户端的每一个请求要包含服务器所须要的全部信息 

 

优势:提升可见性(能够单独考虑每一个请求),提升了可靠性(更容易从局部故障中修复),提升可扩展性(下降了服务器资源使用) 

 

3.缓存(Cachable):服务器返回信息必须被标记是否能够缓存,若是缓存,客户端可能会重用以前的信息发送请求 

 

优势:减小交互次数,减小交互的平均延迟 

 

4.统一接口 

 

优势:提升交互的可见性,鼓励单独改善组件 

 

5.支持按需代码(Code-On-Demand 可选) 

 

优势:提升可扩展性

 

 

 

6四、django rest framework框架中都有那些组件?

 

 

 

#- 路由,自动帮助开发者快速为一个视图建立4url

 

        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

 

        - 定义方法

 

    - 请求数据格式校验

 

#- 渲染器 

 

 

 

6五、django rest framework框架中的视图均可以继承哪些类?

 

a. 继承APIView(最原始)但定制性比较强

 

    这个类属于rest framework中的顶层类,内部帮助咱们实现了只是基本功能:认证、权限、频率控制,

 

但凡是数据库、分页等操做都须要手动去完成,比较原始。

 

    class GenericAPIView(APIView)

 

    def post(...):

 

          pass

 

 

 

b.继承GenericViewSetViewSetMixingenerics.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 --> 快速开发,复杂点的genericviewapiview

 

 

6六、简述 django rest framework框架的认证流程。

 

如何编写?写类并实现authticate

方法中能够定义三种返回值: 

user,auth),认证成功

None , 匿名用户

异常 ,认证失败

流程: 

dispatch

再去request中进行认证处理

 

6七、django rest framework如何实现的用户访问频率控制?

a. 基于用户IP限制访问频率

b. 基于用户IP显示访问频率(利于Django缓存) 

c. view中限制请求频率

d. 匿名时用IP限制+登陆时用Token限制

# 对匿名用户,根据用户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则不可访问

 

6八、Flask框架的优点?

1、总体设计方面

首先,二者都是很是优秀的框架。总体来说,二者设计的哲学是区别最大的地方。Django提供一站式的解决方案,从模板、ORM、Session、Authentication等等都分配好了,连app划分都作好了,总之,为你作尽可能多的事情,并且还有一个killer级的特性,就是它的admin,配合django-suit,后台就出来了,其实最初Django就是由在新闻发布公司工做的人设计的。Flask只提供了一些核心功能,很是简洁优雅。它是一个微框架,其余的由扩展提供,但它的blueprint使它也可以很方便的进行水平扩展。

2、路由设计

Django的路由设计是采用集中处理的方法,利用正则匹配。Flask也能这么作,但更多的是使用装饰器的形式,这个有优势也有缺点,优势是读源码时看到函数就知道怎么用的,缺点是一旦源码比较长,你要查路由就不太方便了,但这也促使你去思考如何更合理的安排代码。

3、应用模块化设计

Django的模块化是集成在命令里的,也就是说一开始Django的目标就是为之后玩大了作准备的。每一个都是一个独立的模块,为之后的复用提供了便利。Flask经过Blueprint来提供模块化,本身对项目结构划分红不一样的模块进行组织。

 

6九、Flask框架依赖组件?

Route(路由)

templates(模板)

Models(orm模型)

blueprint(蓝图)

Jinja2模板引擎

     依赖werkzurg协议

 

70、Flask蓝图的做用?

将不一样的功能模块化

构建大型应用

优化项目结构

加强可读性,易于维护(跟Django的view功能类似)

# blueprint把实现不一样功能的module分开.也就是把一个大的App分割成各自实现不一样功能的module.

# 在一个blueprint中能够调用另外一个blueprint的视图函数, 但要加相应的blueprint.

 

7一、列举使用过的Flask第三方组件?

 

内置: - 配置 - 路由 - 视图 - 模板 - session - 闪现 - 蓝图 - 中间件 - 特殊装饰器 

第三方: - Flask组件: - flask-session - flask-SQLAlchemy - flask-migrate 

- flask-script - blinker -

公共组件: - wtforms - dbutile - sqlalchemy - 自定义Flask组件 - auth ,参考flask- login组件

 

7二、简述Flask上下文管理流程?

 

a、简单来讲,falsk上下文管理能够分为三个阶段:

  1'请求进来时':将请求相关的数据放入上下问管理中

  2'在视图函数中':要去上下文管理中取值

  3'请求响应':要将上下文管理中的数据清除

# b、详细点来讲:

  1'请求刚进来'

        requestsession封装在RequestContext类中

        appg封装在AppContext类中

        并经过LocalStackrequestcontextappcontext放入Local类中

  2'视图函数中'

        经过localproxy--->偏函数--->localstack--->local取值

  3'请求响应时'

        先执行save.session()再各自执行pop(),local中的数据清除

 

7三、Flask中的g的做用?

 g是贯穿于一次请求的全局变量,当请求进来将gcurrent_app封装为一个APPContext类,再经过LocalStackAppcontext放入Local中,取值时经过偏函数在LocalStacklocal中取值;响应时将local中的g数据删除

 

7四、Flask中上下文管理主要涉及到了那些相关的类?并描述类主要做用?

 

RequestContext  #封装进来的请求(赋值给ctx

AppContext      #封装app_ctx

LocalStack      #local对象中的数据维护成一个栈(先进后出)

Local           #保存请求上下文对象和app上下文对象

 

7五、为何要Flask把Local对象中的的值stack 维护成一个列表?

# 由于经过维护成列表,能够实现一个栈的数据结构,进栈出栈时只取一个数据,巧妙的简化了问题。

# 还有,在多app应用时,能够实现数据隔离;列表里不会加数据,而是会生成一个新的列表

# local是一个字典,字典里keystack)是惟一标识,value是一个列表

 

7六、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__走。

 

7七、在Flask中实现WebSocket须要什么组件?

 

Flask-SocketIO

Flask-Sockets是Flask框架的一个扩展,经过它,Flask应用程序能够使用WebSocket。

gevent-websocket

 

7八、wtforms组件的做用?

WTForms是一个支持多个web框架的form组件,主要用于对用户请求数据进行验证。

 

7九、Flask框架默认session处理机制?

Flask的默认session利用了Werkzeug的SecureCookie,把信息作序列化(pickle)后编码(base64),放到cookie里了。

 

过时时间是经过cookie的过时时间实现的。

 

为了防止cookie内容被篡改,session会自动打上一个叫session的hash串,这个串是通过session内容、SECRET_KEY计算出来的,看得出,这种设计虽然不能保证session里的内容不泄露,但至少防止了不被篡改。

 

80、解释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()

8一、Flask中 blinker 是什么?

Flask框架中的信号基于blinker,可让开发者在flask请求过程当中 定制一些用户行为执行。 

在请求先后,模板渲染先后,上下文先后,异常 的时候

 

8二、SQLAlchemy中的 session和scoped_session 的区别?

使用scoped_session的目的主要是为了线程安全。 

scoped_session相似单例模式,当咱们调用使用的时候,会先在Registry里找找以前是否已经建立session了。 

要是有,就把这个session返回。 

要是没有,就建立新的session,注册到Registry中以便下次返回给调用者。 

这样就实现了这样一个目的:在同一个线程中,call scoped_session 的时候,返回的是同一个对象

 

8三、SQLAlchemy如何执行原生SQL?

 

  from sqlalchemy import create_engine  from sqlalchemy.orm import sessionmaker   engine = create_engine('mysql://root:*****@127.0.0.1/database?charset=utf8')  DB_Session = sessionmaker(bind=engine)  session = DB_Session()  session.execute('alter table mytablename drop column mycolumn ;')

 

8四、ORM的实现原理?

 

概念: 对象关系映射(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不一样类型系统的数据之间的转换。

详细介绍: 让咱们从O/R开始。字母O起源于”对象”(Object),而R则来自于”关系”(Relational)。几乎全部的程序里面,都存在对象和关系数据库。在业务逻辑层和用户界面层中,咱们是面向对象的。当对象信息发生变化的时候,咱们须要把对象的信息保存在关系数据库中。

当你开发一个应用程序的时候(不使用O/R Mapping),你可能会写很多数据访问层的代码,用来从数据库保存,删除,读取对象信息,等等。你在DAL中写了不少的方法来读取对象数据,改变状态对象等等任务。而这些代码写起来老是重复的。 

ORM解决的主要问题是对象关系的映射。域模型和关系模型分别是创建在概念模型的基础上的。域模型是面向对象的,而关系模型是面向关系的。通常状况下,一个持久化类和一个表对应,类的每一个实例对应表中的一条记录,类的每一个属性对应表的每一个字段。

 

ORM技术特色: 

* 提升了开发效率。因为ORM能够自动对Entity对象与数据库中的Table进行字段与属性的映射,因此咱们实际可能已经不须要一个专用的、庞大的数据访问层。 

* ORM提供了对数据库的映射,不用sql直接编码,可以像操做对象同样从数据库获取数据。

 

8五、DBUtils模块的做用?

使用DBUtils模块

两种使用模式: 

1. 为每一个线程建立一个链接,链接不可控,须要控制线程数 

1. 建立指定数量的链接在链接池,当线程访问的时候去取,若是不够了线程排队,直到有人释放。平时建议使用这种!

 

8六、如下SQLAlchemy的字段是否正确?若是不正确请更正:

 

fromdatetime importdatetimefromsqlalchemy.ext.declarativeimportdeclarative_basefromsqlalchemy importColumn, Integer, String, DateTimeBase = 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())ctime字段中的参数应该为default=datetime.now, now后面不该该加括号.若是加了,字段不会随时更新

 

8七、SQLAchemy中如何为表设置引擎和字符编码?

 

sqlalchemy设置编码字符集必定要在数据库访问的URL上增长charset=utf8,不然数据库的链接就不是utf8的编码格式 

eng = create_engine(‘mysql://root:root@localhost:3306/test2?charset=utf8’,echo=True)

 

88. SQLAlchemy中如何设置联合惟一索引?

UniqueConstraint 设置联合惟一索引

 

8九、简述Tornado框架的特色。

 

Tornado的独特之处在于其全部开发工具可以使用在应用开发的任意阶段以及任何档次的硬件资源上。并且,完整集的Tornado工具能够使开发人员彻底不用考虑与目标链接的策略或目标存储区大小。

 

Tornado 结构的专门设计为开发人员和第三方工具厂商提供了一个开放环境。已有部分应用程序接口能够利用并附带参考书目,内容从开发环境接口到链接实现。Tornado包括强大的开发和调试工具,尤为适用于面对大量问题的嵌入式开发人员。这些工具包括C和C++源码级别的调试器,目标和工具管理,系统目标跟踪,内存使用分析和自动配置. 另外,全部工具能很方便地同时运行,很容易增长和交互式开发。

90、简述Tornado框架中Future对象的做用?

# 实现异步非阻塞视图函数yield一个futrue对象,futrue对象默认:

    self._done = False   ,请求未完成

    self._result = None  ,请求完成后返回值,用于传递给回调函数使用。

 

tornado就会一直去检测futrue对象的_done是否已经变成True

 

若是IO请求执行完毕,自动会调用futureset_result方法:

            self._result = result

            self._done = True

 

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

Tornadowebsocket模块中提供了一个WebSocketHandler类。

这个类提供了和已链接的客户端通讯的WebSocket事件和方法的钩子。

当一个新的WebSocket链接打开时,open方法被调用,

on_messageon_close方法,分别在链接、接收到新的消息和客户端关闭时被调用。

 

此外,WebSocketHandler类还提供了write_message方法用于向客户端发送消息,close方法用于关闭链接。

 

9二、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'文件

 

9三、Tornado操做MySQL使用的模块?

torndb是一个轻量级的基于MySQLdb封装的一个模块,从tornado3.0版本之后,其已经做为一个独立模块发行了。torndb依赖于MySQLdb模块,所以,在使用torndb模块时,要保证系统中已经有MySQLdb模块。

 

9四、Tornado操做redis使用的模块?

tornado-redis

9五、简述Tornado框架的适用场景?

 

Tornado是使用Python编写的一个强大的、可扩展的Web服务器。它在处理严峻的网络流量时表现得足够强健,但却在建立和编写时有着足够的轻量级,并可以被用在大量的应用和工具中。

 

咱们如今所知道的Tornado是基于Bret Taylor和其余人员为FriendFeed所开发的网络服务框架,当FriendFeed被Facebook收购后得以开源。不一样于那些最多只能达到10,000个并发链接的传统网络服务器,Tornado在设计之初就考虑到了性能因素,旨在解决C10K问题,这样的设计使得其成为一个拥有很是高性能的框架。此外,它还拥有处理安全性、用户验证、社交网络以及与外部服务(如数据库和网站API)进行异步交互的工具。

 

96. git常见命令做用

 

某个文件夹中的内容进行版本管理:

进入文件夹,右键git bash

git init 初始化,当前所在的文件夹能够被管理且之后版本相关的数据都会存储到.git文件中

git status 查看当前文件夹以及子目录中文件是否发生变化:内容修改/新增文件/删除,已经变化的文件会变成红色,已经add的文件会变成绿色

git add .  给发生变化的文件(贴上一个标签)或 将发生变化的文件放到某个地方,只写一个句点符就表明把git status中红色的文件所有打上标签

git commit -m ‘新增用户登陆认证功能以及xxx功能’ 将“绿色”文件添加到版本中

git log 查看全部版本提交记录,能够获取版本号

git reset –hard 版本号   将最新的版本回退到更早的版本

git reflog   回退到以前版本后悔了,再更新到最新或者最新以前的版本

git reset –hard 版本 回退    

 

97. 简述如下git中stash命令做用以及相关其余命令。

 

stash用于将工做区发生变化的全部文件获取临时存储在“某个地方”,将工做区还原当前版本未操做前的状态;stash还能够将临时存储在“某个地方”的文件再次拿回到工做区。

 

git stash             将当前工做区全部修改过的内容存储到“某个地方”,将工做区还原到当前版本未修改过的状态

git stash list        查看“某个地方”存储的全部记录

git stash clear     清空“某个地方”

git stash pop       将第一个记录从“某个地方”从新拿到工做区(可能有冲突)

git stash apply     编号, 将指定编号记录从“某个地方”从新拿到工做区(可能有冲突)

git stash drop      编号,删除指定编号的记录

 

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

merge

会将不一样分支的提交合并成一个新的节点,以前的提交分开显示,

注重历史信息、能够看出每一个分支信息,基于时间点,遇到冲突,手动解决,再次提交

rebase

将两个分支的提交结果融合成线性,不会产生新的节点;

注重开发过程,遇到冲突,手动解决,继续操做

 

99. 公司如何基于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

100、如何基于git实现代码review?

利用github/gitlab自带的在线Diff展现功能作。

https://blog.csdn.net/maray/article/details/50206927

 

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

在命令行中,使用“git tag –a tagname –m “comment”能够快速建立一个标签。

须要注意,命令行建立的标签只存在本地Git库中,还须要使用Git push –tags指令发 布到服务器的Git库中

 

102. 什么是gitlab?

gitlab是公司本身搭建的项目代码托管平台

GitLab 是一个用于仓库管理系统的开源项目,使用Git做为代码管理工具,并在此基础上搭建起来的web服务。安装方法是参考GitLab在GitHub上的Wiki页面。

 

10三、github和gitlab的区别?

 

先说一下相同点,两者都是基于web的Git仓库,在很大程度上GitLab是仿照GitHub来作的,它们都提供了分享开源项目的平台,为开发团队提供了存储、分享、发布和合做开发项目的中心化云存储的场所。

GitHub做为开源代码库及版本控制系统,拥有超过900万的开发者用户,目前仍然是最火的开源项目托管系统。GitHub同时提供公共仓库和私有仓库,但若是要使用私有仓库,是须要付费的。

GitLab解决了这个问题,你能够在上面建立私人的免费仓库。

GitLab让开发团队对他们的代码仓库拥有更多的控制,相比于GitHub,它有很多的特点:

容许免费设置仓库权限;容许用户选择分享一个project的部分代码;容许用户设置project的获取权限,进一步的提高安全性;能够设置获取到团队总体的改进进度;经过innersourcing让不在权限范围内的人访问不到该资源。

从代码私有性方面来看,有时公司并不但愿员工获取到所有的代码,这个时候GitLab无疑是更好的选择。但对于开源项目而言,GitHub依然是代码托管的首选。

 

10四、如何为github上牛逼的开源项目贡献代码?

 

1fork须要协做项目

2、克隆/关联fork的项目到本地

3、新建分支(branch)并检出(checkout)新分支

4、在新分支上完成代码开发

5、开发完成后将你的代码合并到master分支

6、添加原做者的仓库地址做为一个新的仓库地址

7、合并原做者的master分支到你本身的master分支,用于和做者仓库代码同步

8push你的本地仓库到GitHub

9、在Github上提交 pull requests

10、等待管理员(你须要贡献的开源项目管理员)处理

 

10五、git中 .gitignore文件的做用?

 

通常来讲每一个Git项目中都须要一个“.gitignore”文件,

这个文件的做用就是告诉Git哪些文件不须要添加到版本管理中。

实际项目中,不少文件都是不须要版本管理的,好比Python的.pyc文件和一些包含密码的配置文件等等。

106. 什么是敏捷开发?

敏捷开发以用户的需求进化为核心,采用迭代、按部就班的方法进行软件开发。在敏捷开发中,软件项目在构建初期被切分红多个子项目,各个子项目的成果都通过测试,具有可视、可集成和可运行使用的特征。换言之,就是把一个大项目分为多个相互联系,但也可独立运行的小项目,并分别完成,在此过程当中软件一直处于可以使用状态。

11九、简述 requests模块的做用及基本使用?

使用requests能够模拟浏览器发送的请求

发送get请求:requests.get()

发送post请求:requests.post()

读取请求返回内容:requests.text()

保存cookie:requests.cookie()

# 做用:使用requests能够模拟浏览器的请求

# 经常使用参数:   urlheaderscookiesdata

   jsonparamsproxy

# 经常使用返回值:   content

   iter_content

   text

   encoding="utf-8"

   cookie.get_dict()

 

120、简述 beautifulsoup模块的做用及基本使用?

 

# BeautifulSoup用于从HTMLXML文件中提取、过滤想要的数据形式

#经常使用方法解析:html.parser 或者 lxml(须要下载安装)

   findfind_alltextattrsget

 

12一、简述 seleninu模块的做用及基本使用?

 

selenium最初是一个自动化测试工具,而爬虫中使用它主要是为了解决requests没法直接执行JavaScript代码的问题

selenium本质是经过驱动浏览器,彻底模拟浏览器的操做,好比跳转、输入、点击、下拉等,来拿到网页渲染以后的结果,可支持多种浏览器

 

12二、scrapy框架中各组件的工做流程?

Scrapy Engine(引擎):

负责Spider、ItemPipeline、Downloader、Scheduler中间的通信,信号、数据传递等。

Scheduler(调度器): 它负责接受引擎发送过来的Request请求,并按照必定的方式进行整理排列,入队,当引擎须要时,交还给引擎。

Downloader(下载器):

负责下载Scrapy Engine(引擎)发送的全部Requests请求,并将其获取到的Responses交还给Scrapy Engine(引擎),由引擎交给Spider来处理,

Spider(爬虫):

它负责处理全部Responses,从中分析提取数据,获取Item字段须要的数据,并将须要跟进的URL提交给引擎,再次进入Scheduler(调度器),

Item Pipeline(管道):它负责处理Spider中获取到的Item,并进行进行后期处理(详细分析、过滤、存储等)的地方.

Downloader Middlewares(下载中间件):

你能够看成是一个能够自定义扩展下载功能的组件。

Spider Middlewares(Spider中间件):

你能够理解为是一个能够自定扩展和操做引擎和Spider中间通讯的功能组件(好比进入Spider的Responses;和从Spider出去的Requests)

#1、生成初始的Requests来爬取第一个URLS,而且标识一个回调函数第一个请求定义在start_requests()方法内默认从start_urls列表中得到url地址来生成Request请求,

默认的回调函数是parse方法。回调函数在下载完成返回response时自动触发

#2、在回调函数中,解析response而且返回值返回值能够4种:

    a、包含解析数据的字典

    bItem对象

    c、新的Request对象(新的Requests也须要指定一个回调函数)

    d、或者是可迭代对象(包含ItemsRequest

#3、在回调函数中解析页面内容一般使用Scrapy自带的Selectors,但很明显你也能够使用Beutifulsouplxml或其余你爱用啥用啥。

#4、最后,针对返回的Items对象将会被持久化到数据库    经过Item Pipeline组件存到数据库

    或者导出到不一样的文件(经过Feed exports

 

12三、在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,

    }

 

 

12四、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()

 

12五、scrapy中如何实现限速?

修改setting文件的AUTOTHROTTLE_START_DELAY 打开后默认限速为5秒

 

12六、scrapy中如何实现暂定爬虫?

 

cmd上cd 进入项目

而后在项目目录下建立 记录文件:remain/001

而后输入:scrapy crawl  zhihu  -s JOBDIR=remain/001

回车运行就好了

ctrl+c 暂停

继续运行只要再次输入:scrapy crawl  zhihu  -s JOBDIR=remain/001就好了

须要从新爬取就换个文件 002就好了

 

12七、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'

 

12八、scrapy中如何实现的记录爬虫的深度?

'DepthMiddleware'是一个用于追踪每一个Request在被爬取的网站的深度的中间件。

其能够用来限制爬取深度的最大深度或相似的事情。

'DepthMiddleware'能够经过下列设置进行配置(更多内容请参考设置文档):

 

'DEPTH_LIMIT':爬取所容许的最大深度,若是为0,则没有限制。

'DEPTH_STATS':是否收集爬取状态。

'DEPTH_PRIORITY':是否根据其深度对requet安排优先

12九、scrapy中的pipelines工做原理?

Scrapy 提供了 pipeline 模块来执行保存数据的操做。

在建立的 Scrapy 项目中自动建立了一个 pipeline.py 文件,同时建立了一个默认的 Pipeline 类。咱们能够根据须要自定义 Pipeline 类,而后在 settings.py 文件中进行配置便可

 

130、scrapy的pipelines如何丢弃一个item对象?

经过raise DropItem()方法

pipelines的时候不执行持久化保存就会什么也不执行也就是丢弃

13一、简述scrapy中爬虫中间件和下载中间件的做用?

下载器中间件(Downloader Middlewares)

位于Scrapy引擎和下载器之间的框架,主要是处理Scrapy引擎与下载器之间的请求及响应。

爬虫中间件(Spider Middlewares)

介于Scrapy引擎和爬虫之间的框架,主要工做是处理蜘蛛的响应输入和请求输出。

13二、scrapy-redis组件的做用?

实现了分布式爬虫,url去重、调度器、数据持久化

scheduler - 调度器

   dupefilter - URL去重规则(被调度器使用)

   pipeline   - 数据持久化

 

13三、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

scrapyscrapy-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)

13四、scrapy-redis的调度器如何实现任务的深度优先和广度优先

简述 jenkins 工具的做用?

'Jenkins'是一个可扩展的持续集成引擎。

主要用于:

   持续、自动地构建/测试软件项目。

   监控一些定时执行的任务。

公司如何实现代码发布?

nginx+uwsgi+django

简述 RabbitMQ、Kafka、ZeroMQ的区别?

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

为了预防消息丢失,rabbitmq提供了ack

即工做进程在收到消息并处理后,发送ack给rabbitmq,告知rabbitmq这时候能够把该消息从队列 中删除了。

若是工做进程挂掉 了,rabbitmq没有收到ack,那么会把该消息 从新分发给其余工做进程。

不须要设置timeout,即便该任务须要很长时间也能够处理。

 

ack默认是开启的,工做进程显示指定了no_ack=True

RabbitMQ如何对消息作持久化?

一、建立队列和发送消息时将设置durable=Ture,若是在接收到消息尚未存储时,消息也有可能丢失,就必须配置publisher confirm

    channel.queue_declare(queue='task_queue', durable=True)

二、返回一个ack,进程收到消息并处理完任务后,发给rabbitmq一个ack表示任务已经完成,能够删除该任务

三、镜像队列:将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开发的一个简单、灵活、可靠的处理大量任务的分发系统,

# 它不只支持实时处理也支持任务调度。

简述 vitualenv 及应用场景?

'vitualenv'是一个独立的python虚拟环境

如:

   当前项目依赖的是一个版本,可是另外一个项目依赖的是另外一个版本,这样就会形成依赖冲突,

   virtualenv就是解决这种状况的,virtualenv经过建立一个虚拟化的python运行环境,

   将咱们所需的依赖安装进去的,不一样项目之间相互不干扰

简述 pipreqs 及应用场景?

能够经过对项目目录扫描,自动发现使用了那些类库,而且自动生成依赖清单。

pipreqs ./ 生成requirements.txt

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

1PyFlakes:静态检查Python代码逻辑错误的工具。

2Pep8: 静态检查PEP8编码风格的工具。

3NedBatchelder’s McCabe script:静态分析Python代码复杂度的工具。

Python代码分析工具:PyCheckerPylint

简述 saltstack、ansible、fabric、puppet工具的做用?

 

B Tree和B+ Tree的区别?

1.B树中同一键值不会出现屡次,而且有可能出如今叶结点,也有可能出如今非叶结点中。

  B+树的键必定会出如今叶结点中,并有可能在非叶结点中重复出现,以维持B+树的平衡。

2.由于B树键位置不定,且在整个树结构中只出现一次,

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

冒泡/选择/插入/快排

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

无序查找、二分查找、插值查找

请列举你熟悉的设计模式

工厂模式/单例模式等

有没有刷过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'是实现了uwsgiWSGI两种协议的Web服务器,负责响应pythonweb请求。

 

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,涵盖面很广,做者:刘欣)

 

实验楼(在线练项目)

 

最近在研究什么新技术?

 

Numpy pandas(金融量化分析、聚宽) 百度AI 图灵API 智能玩具

 

是否了解过领驱动模型

 

Domain-Driven Design

 

二进制与十进制之间的转换

 

一、十进制 与 二进制之间的转换
    (1)、十进制转换为二进制,分为整数部分和小数部分

 

整数部分

 

方法:除2取余法,即每次将整数部分除以2,余数为该位权上的数,而商继续除以2,余数又为上一个位权上的数。

 

这个步骤一直持续下去,直到商为0为止,最后读数时候,从最后一个余数读起,一直到最前面的一个余数。下面举例:

 

小数部分

 

方法:乘2取整法,即将小数部分乘以2,而后取整数部分,剩下的小数部分继续乘以2,而后取整数部分,
剩下的小数部分又乘以2,一直取到小数部分为零为止。若是永远不能为零,就同十进制数的四舍五入同样,
按照要求保留多少位小数时,就根据后面一位是0仍是1,取舍,若是是零,舍掉,若是是1,向入一位。
换句话说就是01入。读数要从前面的整数读到后面的整数

 

二进制转换为十进制 (不分整数和小数部分)

 

方法:按权相加法,即将二进制每位上的数乘以权,而后相加之和便是十进制数。

 

例:将二进制数101.101转换为十进制数。

 

得出结果:(101.1012=(5.625)10

 

在作二进制转换成十进制须要注意的是

 

1)要知道二进制每位的权值

 

2)要能求出每位的值 101.101 转换为十进制

 

整数部分:2^2 + 2^0 = 5

 

小数部分:2^(-1) + 2^(-3) = 1/2 + 1/8 = 0.5 + 0.125 = 0.625

 

十进制: 2^2 + 2^0 + 2^(-1) + 2^(-3) = 5.625

相关文章
相关标签/搜索