面试总结

面试题总结

1.问:类的方法分别怎么调用,项目中在哪里可以用到

答:类的方法分为实例方法、静态方法和类方法,后两者实际上没有实质性的区别,只不过类方法的第一个参数是代表类的对象,而静态方法没有这个参数,实例方法要用对象调用(发给对象的消息),静态方法和类方法用类就可以调用(发给类对象的消息)

2.问:装饰器和中间件的区别

答:装饰器和中间件本质也是一致的,Django1.8以后官方推荐的写法中间件跟装饰器的写法是一致的,只不过中间件可以对web的请求和响应进行过滤,web的中间件更应该称为拦截过滤器

3.问:celery 怎么写

答:app = celery.Celery('模块名', broker='消息服务器的URL', backend='存储服务的URL')

4.问:RabbitMQ和MQ的分别在项目中怎么用的区别是什么

答:RabbitMQ是功能更完整的消息队列,比Redis提供的消息队列强大

8.问:云片怎么用的

答:基本上就是requests调用一个短信网关就可以了

9.问:七牛云怎么用的 CDN是干什么的

答:七牛云可以用来存储静态资源,CDN可以加速对静态资源的访问

10.问:图片存在哪儿? 怎么存进服务器,怎么在本地访问

答:图片放在静态资源服务器,可以是自己搭的静态资源服务器(文件系统),也可以用云存储,后者更好

11.问:描述一下所有的索引和怎么用

答:普通索引、主键索引、全文索引、唯一索引

12.问:djangorestframework 为什么要用它 区别在哪

答:使用DRF主要是为了做REST风格的数据接口

13.问:搜索框架ES((ElasticSearch)奶思特in瑟儿其)

答:是用来提供全文检索服务的

14.问:中间件有哪几种

答:处理请求、处理响应、处理异常、处理模板的中间件吧

15.问:悲观锁和乐观锁

答:

悲观锁:为数据库加锁,但是降低并发性。

乐观锁:乐观锁是要添加版本号的列,更新时要保证你的版本号在原来的版本号上+1,而且要大于表中的版本号才能更新,这个就是乐观锁的原理

16.问:缓存问题问题(Redis的并发问题)怎么解决

答:其实redis自身就是单线程操作,多个client并发操作,按照先到先执行的原则,先到的先执行,其余的阻塞。当然,另外的解决方案是把redis.set操作放在队列中使其串行化,必须的一个一个执行,当然加锁也是可以的,至于为什么不用redis中的事务。

世纪顶点的面试总结

1.问:富文本编辑器是怎么做到图片上传的,又是怎么关联到文章的(相当于就是一篇文章 (字 图片1 字 图片2)怎么让图片和文章进行关联)

答:富文本一般都带了支持文件上传的,只要给一个支持文件上传的url地址就可以了,图片里面加一个文章的id作为外键就可以了图片和文章就关联起来了,在存储的时候就给图片编一个号或者按照时间先后顺序生成一个时间戳就可以区分顺序了

2.问:缓存穿透和缓存雪崩怎么解决

答:

缓存穿透是指查询一个数据库一定不存在的数据。

方案1、使用互斥锁排队

业界比价普遍的一种做法,即根据key获取value值为空时,锁上,从数据库中load数据后再释放锁。若其它线程获取锁失败,则等待一段时间后重试。这里要注意,分布式环境中要使用分布式锁,单机的话用普通的锁(synchronized、Lock)就够了。这样做思路比较清晰,也从一定程度上减轻数据库压力,但是锁机制使得逻辑的复杂度增加,吞吐量也降低了,有点治标不治本。

方案2、接口限流与熔断、降级

重要的接口一定要做好限流策略,防止用户恶意刷接口,同时要降级准备,当接口中的某些服务不可用时候,进行熔断,失败快速返回机制。

方案3、布隆过滤器

bloomfilter就类似于一个hash set,用于快速判某个元素是否存在于集合中,其典型的应用场景就是快速判断一个key是否存在于某容器,不存在就直接返回。布隆过滤器的关键就在于hash算法和容器大小。

缓存雪崩:缓存在同一时间内大量键过期(失效),接着来的一大波请求瞬间都落在了数据库中导致连接异常。

解决方案:

方案1、也是像解决缓存穿透一样加锁排队,实现同上;

方案2、建立备份缓存,缓存A和缓存B,A设置超时时间,B不设值超时时间,先从A读缓存,A没有读B,并且更新A缓存和B缓存;

方案3、设置缓存超时时间的时候加上一个随机的时间长度,比如这个缓存key的超时时间是固定的5分钟加上随机的2分钟,酱紫可从一定程度上避免雪崩问题

4.问:接口怎么做限流

答:接口限流是配置throttle_classes

5.问:缓存并发问题

答:缓存并发没有问题的,Redis是单线程+异步IO的工作模式

6.问:Redis的事务

答:会将一个事务中的所有命令序列化,然后按顺序执行

Redis不可能在一个Redis事务的执行过程中插入执行另一个客户端发出的请求

在一个Redis事务中,Redis要么执行其中的所有命令,要么什么都不执行。因此,Redis事务能够保证原子性。

7.问:db的事务

答:一个是事务的ACID特性,一个是事务隔离级别,对应到底层的锁机制

事务的ACID特性:

1. 原子性(atomic),事务必须是原子工作单元;对于其数据修改,要么全都执行,要么全都不执行

2. 一致性(consistent),事务的执行结果,必须是从一个一致状态,变成另一个新的一致状态。事务的原子性保证其一致性

3. 隔离性(insulation),主要在并发时,各个事务之间互不影响。并发事务所作的修改必须与任何其它并发事务所作的修改隔离。

4. 持久性(Duration),事务一旦提交,数据就永久的保存在数据库,它对于系统的影响是永久性的。

事务隔离级别:

1. Serializable 串行化

2. Repeatable Read 可重复读

3. Read Commited 可读已提交

4. Read Uncommited 可读未提交

锁的机制

  1. 共享锁

共享锁的代号是S,共享锁的锁粒度是行或元组(多个行)。一个事务获取了共享锁之后,可以对锁定范围内的数据执行读操作。

  1. 排它锁

排它锁的代号是X,排它锁的粒度与共享锁相同,也是行或元组。一个事务获取了排它锁之后,可以对锁定范围内的数据执行写操作。

  1. 意向锁

意向锁是一种表锁,锁定的粒度是整张表,分为意向共享锁(IS)和意向排它锁(IX)两类。意向共享锁表示一个事务有意对数据上共享锁;意向排它锁表示一个事务有意对数据上排它锁。

使用意向锁来保护锁层次结构的底层资源,以防止其他事务对自己锁住的资源造成伤害。

意向锁可以提高性能,因为数据库引擎仅在表级检查意向锁,确定事务是否能安全地获取该表上的锁,而不需要检查表中的每行或每页上的锁以确定事务是否可以锁定整个表。

MYSQL锁级别

  1. 表级锁:直接锁定整张表,在锁定期间,其它进程无法对该表进行写操作,若是排他锁,则其它进程读也不允许。开销小,加锁快,不会出现死锁,冲突概率高,并发度低。

  2. 行级锁:仅对指定的记录进行加锁,其它进程还是可以对同一个表中的其它记录进行操作。开销大,加锁慢,会出现死锁,冲突概率低,并发度高。

  3. 页级锁:页级锁取了折衷,一次锁定相邻的一组记录。开销和加锁时间界于表级锁和行级锁之间,会出现死锁,并发度一般。

8.问:怎么解决脏读幻读

答:脏读幻读都是设置事务隔离级别就可以了

9.问:数据库的优化

答:

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

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

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

4、事务

5、锁定表

6、使用外键

7、使用索引

8、优化的查询语句

10.问:数据库的定义

答:?

12. 问:高并发怎么处理

答:

1、HTML静态化

2、图片服务器分离

3、数据库集群和库表散列

4、缓存

5、镜像

6、负载均衡

13.问:并发引发数据库的安全问题

答:1 脏读:一个事务读取到另一个事务未提交的数据,显然该未提交事务可能发生错误而回滚没有保存进数据库,那么读到的数据就是错误的数据。

 2.第一类更新丢失:开启一个事务,读取到一行数据,另一个事务也读到同一行数据。后一个事务提交事务保存到数据库后第一个事务更新时发生异常而回滚导致后一个事务的更新丢失

3 第二类更新丢失:一个事务从数据库得到一行数据保存在内存中,这时另一个事务开发也读到同一行一样的数据,另一个事务更改了事务并提交保存到数据库。这时第一个事务依然是最开始的数据(没有重新去数据库读取)进行修改提交导致另一个事务提交的信息丢失。

4 不可重复读:一个事务两次读取同一行数据,结果得到不同状态结果,如中间正好另一个事务更新了该数据,两次结果相异,不可信任。

5 幻读: A事务读取B事务提交的新增数据,这时A事务将出现幻象读的问题

14.问:RESTful架构风格是什么,为什么要用

答:RESTful架构应该遵循统一接口原则,统一接口包含了一组受限的预定义的操作,不论什么样的资源,都是通过使用相同的接口进行资源的访问。接口应该使用标准的HTTP方法如GET,PUT和POST,并遵循这些方法的语义。

如果按照HTTP方法的语义来暴露资源,那么接口将会拥有安全性和幂等性的特性,例如GET和HEAD请求都是安全的, 无论请求多少次,都不会改变服务器状态。而GET、HEAD、PUT和DELETE请求都是幂等的,无论对资源操作多少次, 结果总是一样的,后面的请求并不会产生比第一次更多的影响。

[图片上传失败...(image-229917-1557284862991)]

15.问:信号机制

答:Django Signal信号机制是一种事件触发基础,比如在保存一个模型之后,可以引发事件做额外的操作

16.问:项目流程

答:?

17.问:功能模块是否独立完成

答:是

18.问:软件工程有哪些必修课

答:计算机导论、C语言程序设计、面向对象程序设计、数据库概论、操作系统、数据结构和算法、编译原理、计算机网络、人工智能,大概就这些

19.问:ags和*kwags分别代表什么

答:args是非关键字参数 传入元祖*kwargs是关键字参数用于字典

20.问:Nginx主从配置

答:?

21.问:平时用Djangorestfram还是Django原生 为什么

答:?

22.问:平时用什么调试

答:代码评审可以分为代码评审会议和Single Review(一对一审查),主要就是检查代码的风格、逻辑这些,可以用工具进行辅助检查 或者是用工具(单元测试、pylint检查代码风格)

23.问:MySQL的优化

答:

a: 表的设计合理化(符合3NF)

b: 添加适当索引(index) [四种: 普通索引、主键索引、唯一索引unique、全文索引]

c: 分表技术(水平分割、垂直分割)

d: 读写[写: update/delete/add]分离

e: 存储过程 [模块化编程,可以提高速度]

f: 对mysql配置优化 [配置最大并发数my.ini, 调整缓存大小 ]

g: mysql服务器硬件升级

h: 定时的去清除不需要的数据,定时进行碎片整理(MyISAM)

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

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

https://blog.csdn.net/zhangbijun1230/article/details/81608252

24.问:python的内存管理机制

答:就是引用计数器机制和垃圾回收机制的混合机制

25.问:Python中的垃圾回收

答:当Python的某个对象的引用计数降为0时,说明没有任何引用指向该对象,该对象就成为要被回收的垃圾。比如某个新建对象,被分配给某个引用,对象的引用计数变为1。如果引用被删除,对象的引用计数为0,那么该对象就可以被垃圾回收。

26.问:Python内存池机制

答:Python中有分为大内存和小内存:(256K为界限分大小内存)

1、大内存使用malloc进行分配

2、小内存使用内存池进行分配

3、Python的内存池(金字塔)

第3层:最上层,用户对Python对象的直接操作

第1层和第2层:内存池,有Python的接口函数PyMem_Malloc实现-----若请求分配的内存在1~256字节之间就使用内存池管理系统进行分配,调用malloc函数分配内存,但是每次只会分配一块大小为256K的大块内存,不会调用free函数释放内存,将该内存块留在内存池中以便下次使用。

第0层:大内存-----若请求分配的内存大于256K,malloc函数分配内存,free函数释放内存。

第-1,-2层:操作系统进行操作

27.问:git的版本控制

答:

28.问:怎么相互Review对方代码

答:单元测试 pylint 一对一审查

30.问Python2和Python3的区别

答:

一、 print 从语句变为函数

原: print 1, 2+3

改为: print ( 1, 2+3 )

二、range 与 xrange

原 : range( 0, 4 ) 结果 是 列表 [0,1,2,3 ]

改为:list( range(0,4))

原 : xrange( 0, 4 ) 适用于 for 循环的变量控制

改为:range(0,4)

三、字符串

原: 字符串以 8-bit 字符串存储

改为: 字符串以 16-bit Unicode 字符串存储

四、try except 语句的变化

原: try:

** ......**

** except Exception**, e :

** ......**

改为

**try:**

** ......**

** except Exception as e :**

** ......**

五、打开文件

原: file( ..... )

open(.....)

改为:

只能用 **open**(**.....**)

六、从键盘录入一个字符串

原: raw_input( "提示信息" )

改为: input( "提示信息" )

七、bytes 数据类型

31.问:怎么看短信也没有发送成功

答:Celery有个backed可以看异步任务的执行结果,可以把结果写到数据库或文件,然后以此可以看短信什么的有没有发送成功

32.问:怎么实现全文检索

答:一个是只有MyISAM引擎支持,创建表时需要指定,而是需要对my.ini进行配置。

设置条件

1.表的存储引擎是MyISAM,默认存储引擎InnoDB不支持全文索引(新版本MYSQL5.6的InnoDB支持全文索引)

2.字段类型:char、varchar和text

三、配置

my.ini配置文件中添加

MySQL全文索引查询关键词最小长度限制

[mysqld]

ft_min_word_len = 1

保存后重启MYSQL,执行SQL语句

注:重新设置配置后,已经设置的索引需要重新设置生成索引

33.问:怎么实现的秒杀

答:

34.问:怎么实现搜索

答:使用haystack whoosh实现产品搜索,使用jieba进行中文分词

35: 问:怎么实现权限控制

答:用表实现,主要是将公司内部的岗位与角色和权限挂钩,明确用户的职权。

36.问:流程怎么实现

答:流程表 确认表 和权限差不多

37:问:oa系统怎么写

答:

38.问:mysql工作原理

答:1、Connectors

     连接器,与其他程序的SQL连接交互,完成连接的建立及认证、授权等。当请求到处后,会暂时存放在连接池中,并交由服务管理器管理。

2、Management Serveices & Utilities

      服务管理和控制工具。管理过来的请求,当请求从等待队列进入处理队列,会将请求交给SQL Interface处理。

3、Connection Pool

      连接池,管理缓冲用户连接,线程处理等需要缓存的需求。

4、SQL Interface

     SQL接口,接受用户的SQL命令,并且返回用户需要查询的结果。比如select from就是调用SQL Interface。

     SQL Interface接口会对请求做进行hash处理,根据计算结果先到缓存中查找,找到匹配数据则直接返回,没有匹配数据则要重新查找。

5、Parser

    SQL命令传递到解析器的时候会被解析器验证和解析。

    主要功能:

    a . 将SQL语句分解成数据结构,并将这个结构传递到后续步骤,后面SQL语句的传递和处理就是基于这个结构的

    b.  如果在分解构成中遇到错误,那么就说明这个sql语句是不合理的,语句将不会继续执行下去

6、Optimizer

     优化器,SQL语句在查询之前会使用查询优化器对查询进行优化(产生多种执行计划,最终数据库会选择最优化的方案去执行,尽快返会结果) 他使用的是“选取-投影-联接”策略进行查询。

    用一个例子就可以理解: select uid,name from user where gender = 1;

    这个select 查询先根据where 语句进行选取,而不是先将表全部查询出来以后再进行gender过滤;

    这个select查询先根据uid和name进行属性投影,而不是将属性全部取出以后再进行过滤;

    将这两个查询条件联接起来生成最终查询结果。

7、Caches&Buffers

    缓存,如果查询缓存有命中的查询结果,查询语句就可以直接去查询缓存中取数据。

    这个缓存机制是由一系列小缓存组成的。比如表缓存,记录缓存,key缓存,权限缓存等。

    buffers是指用来给块设备做的缓冲大小。cached是用来给文件做缓冲。那就是说:buffers是用来存储,目录里面有什么内容,权限等等。而cached直接用来记忆我们打开的文件。

8、Pluggable Storage Engines

    存储引擎,存储引擎是MySql中具体的与文件打交道的子系统。也是Mysql最具有特色的一个地方。

    Mysql的存储引擎是插件式的。它根据MySql AB公司提供的文件访问层的一个抽象接口来定制一种文件访问机制(这种访问机制就叫存储引擎)。

9、File System

     文件系统,管理不同的存储文件。

10、Files & Logs

     文件和日志,保存数据集日志信息。

39.问:socket编程

答:首先要一个服务端 一个客户端

首先:创建Socket,涉及到的主要参数有:domain、type、protocal。

  domain是协议域,其中AF_INET->IPv4;AF_INET6->IPv6 。

  type对应socket类型,SOCK_STREAM->TCP;SOCK_DGRAM->UDP。

  protocol是IPPROTO_TCP,若传入0,则会根据第二个参数type,自动选择合适的参数。

  其次,连接到服务器,主要参数:

  客户端socket

  指向数据结构socketaddr的指针,其中包括目的端口和IP地址

  结构体数据长度

  再次,发送数据到服务器,主要参数:

  客户端socket

  发送内容地址

  发送内容长度

  发送方式标志,一般为0

  又再次,从服务器接受数据,主要参数:

  客户端socket

  接受内容缓冲区地址

  接受内容缓冲区长度

  接受方式,0表示阻塞,必须等待服务器返回数据返回值,若成功,则返回读入的字节数,失败则 返回SOCKET_ERROR。

  最后,关闭socket即可。

40.问:如何解决跨站点请求

答:可以写requests获取,转成自己服务器数据,在自己服务器渲染,缺点是不能保证一定能解决问题,也增加自己服务器流量

42.问:为什么要用redis做缓存,不直接用mysql

答:快,一个是内存,一个是硬盘级别

可用可不用的时候, 不用当然行

你直接拿MySQL的Memory类型表来做也很快

redis 能存储json,有时候数据库里的数据取出来要各种组合计算拼接出满足条件的数据,这个过程很长,算出来放redis里会好点。

一些高并发的时候需要用redis来抗,例如抢购扣减库存的时候。频繁操作DB产生的问题。

另外就是分布式系统里,用这个可以解决session 共享啊,mysql 肯定没法解决。

43.问:mysql在机械硬盘和固态硬盘下支持的并发一般是多少

答:

44.问:redis的数据过期机制

答:

45.问:nginx的轮询有哪几种轮询方式?怎么配置的

答:

46.问:一个请求在django的具体处理流程

答:

[图片上传失败...(image-30af55-1557284862989)]

1)Django使用的是根URLconf模块。

这个值通常是通过ROOT_URLCONF设置

(在…/settings.py文件中)。

2)Django加载URLconf模块(urls.py文件),

并寻找可用的urlpatterns。

3)Django依次匹配每个URL模式,

在与请求的URL匹配的第一个模式处停下来。

4)一旦其中的一个正则表达式匹配上,则Django将请求指向对应的视图函数处理。

5)如果没有匹配到正则表达式,或者过程中抛出一个异常,则Django将调用一个适当的错误处理视图。

47.问:一个请求在django的生命

答:

1. 当用户在浏览器中输入url时,浏览器会生成请求头和请求体发给服务端

请求头和请求体中会包含浏览器的动作(action),这个动作通常为get或者post,体现在url之中.

2. url经过Django中的wsgi,再经过Django的中间件,最后url到过路由映射表,在路由中一条一条进行匹配,

一旦其中一条匹配成功就执行对应的视图函数,后面的路由就不再继续匹配了.

3. 视图函数根据客户端的请求查询相应的数据.返回给Django,然后Django把客户端想要的数据做为一个字符串返回给客户端.

4. 客户端浏览器接收到返回的数据,经过渲染后显示给用户.

48:问:url怎么加锁

答:

1、如果只是编码字符串,不和URL有半毛钱关系,那么用escape

2、如果你需要编码整个URL,然后需要使用这个URL,那么用encodeURI

3、当你需要编码URL中的参数的时候,那么encodeURIComponent是最好方法。

你可能感兴趣的:(面试总结)