面试的一些答案

HTTP和HTTPS

http是超文本传输协议,基于socket作用于应用层之上的协议,基于请求相应,无状态,无连接。

https信息是明文传输,而https则是具有安全性的ssl加密传输协议,比http更安全。

 

TCP与UDP协议优缺点

UDP是用户用户数据报协议,不可靠,差错控制开销较小,传输大小限制在 64 KB以下,不需要建立连接。

TCP可靠,传输大小无限制,但是需要连接建立时间,差错控制开销大。

 

Linux常用命令

pwd、cd、history、vim、ls、cp

 

线程、协程

线程:拥有自己的堆和共享的栈 共享栈 但不共享堆 线程也是由操作系统调度

协程:协程和线程一样有自己的堆和共享的栈 共享栈但不共享堆 协程由开发人员在适当情况调用

线程池:提前创建若干个线程,如果有任务需要处理,线程池里的线程就会处理任务,处理完之后线程并不会被销毁,而是等待下一个任务。要注意线程池大小、并发错误、线程泄漏

 

互斥锁

一个线程获得资源的使用权后就会将该资源加锁,使用完后会将其解锁,如果在使用过程中有其他线程想要获取该资源的锁,那么它就会被阻塞陷入睡眠状态,直到该资源被解锁才会被唤醒,如果被阻塞的资源不止一个,那么它们都会被唤醒,但是获得资源使用权的是第一个被唤醒的线程,其它线程又陷入沉睡.

 

GIL锁

全局解释器锁。当我们用多线程的时候,每一个进程中只有一个GIL锁,那么这多个线程中谁拿到GIL锁,谁即可以用cpu(ps:多个进程有多个Gil锁,但每个进程中只有一个GIL)

 

同步和异步

同步异步关注的是消息通信机制

同步:就是在发出一个调用时,在没有得到结果之前,该调用就不返回。但是一旦调用返回,就得到返回值。换句话说,就是由调用者主动等待这个调用结果。

异步:调用在出发之后,这个调用就直接返回了,所以没有返回结果。换句话说,当一个异步过程调用出发后,调用者不会立刻得到结果。而是在调用出发后,被调用者通过状态、来通知调用者或通过回调函数处理这个调用。

 

阻塞和非阻塞

指的是程序的运行状态

阻塞:程序运行过程中遇到IO操作 无法继续

非阻塞:程序正在运行中,并且没有遇到IO,即使遇到IO也不会阻塞,CPU不会切走

 

垃圾回收机制

栈(先进先出、临时存储、局部)| 堆(先进后出、持久化存储、全局)

引用计数(优点:一旦没有引用,内存就直接释放,缺点:维护引用计数消耗资源、循环引用)、标记清除、分代回收

 

MySQL事务

  1. 原子性:最小的工作单元,不可再分。事务中的所有操作必须全部成功或全部失败,成功后写入底层数据,失败后回滚rollback到事务开启的状态。
  2. 一致性:事务在完成时,必须使所有的数据都保持一致状态,保持数据库的完整性。
  3. 隔离性:并发事务之间存在隔离,互不干扰。
  4. 持久性:事务完成之后,它对于系统的影响是永久性的。该修改即使出现致命的系统故障也将一致保持。

 

MySQL查询优化

  1. 储存引擎选择:如果数据表需要事务处理,应该考虑使用InnoDB,因为它完全符合ACID特性。如果不需要事务处理,使用默认存储引擎MyISAM是比较明智的
  2. 分表分表,主从
  3. 对查询进行优化,要尽量避免全表扫,首先应考虑在where及order by涉及的列上建立索引
  4. 应尽量避免在where子句中对字段进行null值判断,否则将导致引擎放弃使用索引而进行全表扫
  5. 应尽量避免在where子句中使用!=或< >操作符,否则将引擎放弃使用索引而进行全表扫
  6. 应尽量避免在where子句中使用or来连接条件,如果一个字段有索引,一个字段没有索引,将导致引擎放弃使用索引而进行全表扫
  7. Update语句,如果只更改1、2个字段,不要Update全部字段,否则频繁调用会引起明显的性能消耗,同时带来大量日志

 

MySQL索引优化

  1. 前导模糊查询

  2. union、in、or都能够命中索引,建议使用in

  3. 负向条件查询不能使用索引,可以优化为in查询

  4. 联合索引最左前缀原则(又叫最左侧查询)

  5. 范围列可以用到索引(联合索引最左前缀原则)

  6. 把计算放到业务层而不是数据层

  7. 强制类型转换会全表扫描

  8. 更新十分频繁、数据区分度不高的字段上不宜建立索引

  9. 利用覆盖索引来进行查询操作,避免回表

  10. 如果有order by、group by的场景,请注意利用索引的有序性

  11. 使用短索引(又叫前缀索引)来优化索引

  12. 建立索引的列,不允许使用null

  13. 利用延迟关联或者子查询优化超多分页场景

  14. 业务上具有唯一特性的字段,即使是多个字段的组合,也必须建成唯一索引

  15. 超过三个表最好不要用join

  16. 如果明确知道只有一条结果返回,limit1能够提高效率

  17. SQL性能优化expalin中的type:至少要达到range级别,要求是ref级别,如果可以是consts最好

  18. 单表索引建议控制在5个以内

  19. 单索引字段数不允许超过5个

  20. 创建索引时避免以下错误观念

    索引越多越好,认为一个查询就需要建一个索引

    宁缺勿滥,认为索引会消耗空间、严重拖慢更新和新增速度

    抵制唯一索引,认为业务的唯一性一律需要在应用层通过“先查后插”方式解决

    过早优化,在不了解系统的情况下就开始优化

 

MySQL主从复制

  1. 从库开启主从同步之后,开启了两个线程:IO线程(从主库同步数据即bin-log)、SQL线程(负责将同步过来的sql语句进行执行)
  2. 同步主库也会开启一个dump线程,等待着从库过来请求数据
  3. io线程带着从本地‘master.info’中的pos标记,去主库中查询有没有比这个标记更新的数据,如果有的话,主库会将标记到的最新的pos标记之间的数据进行返回
  4. 等io线程接收到数据之后,将数据存放在tcp/ip缓存中,不用等待,从库的sql进程执行整个过程是异步的,在tcp/ip接收到数据之后返回一个ack给主库代表着成功接收到数据
  5. 然后将数据放到‘relay-log’交由sql线程执行当前已经执行的标志位‘relay-log.info’中获得,拿着标签去‘relay-log’中获得数据进行同步。

 

MongoDB

MongoDB是一个面向文档的数据库系统,使用C++编程,不支持SQL,但有自己功能强大的查询语法。

MongoDB使用BSON作为数据存储和传输的格式,BSON是一种类似JSON的、二进制序列化文档,支持嵌套对象和数组。

MongoDB很像MySQL占用空间过大,维护工具不够成熟。

 

MongoDB应用场景

  1. 网站数据:mongodb非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。
  2. 缓存:由于性能很高,mongodb也适合作为信息基础设施的缓存层。在系统重启之后,由mongodb搭建的持久化缓存可以避免下层的数据源过载。
  3. 大尺寸、低价值的数据:使用传统的关系型数据酷存储一些数据时可能会比较贵,在此之前,很多程序员往往会选择传统的文件进行存储。
  4. 高伸缩性的场景:mongodb非常适合由数十或者数百台服务器组成的数据库
  5. 用于对象及JSON数据的存储:mongodb的BSON数据格式非常适合文档格式化的存储与查询
  6. 重要数据:mysql,一般数据:mongodb,临时数据:memcache

 

Django request请求流程

浏览器发送http请求通过后台的web服务网关接口里面的wsgiref解析和封装了http数据(WSGI是协议:wsgiref、uwsgi、werkzeug都是基于该协议),之后通过Django的中间件(默认是7个中间件,五个是可自定义方法,全局访问频率限制、权限限制等process_request:请求刚进来时、process_view:经过url执行视图函数之前、process_template_response:视图函数中return render时触发、process_exception:视图函数报错执行、process_response:返回相应响应时)中间件执行顺序请求来从上向下、请求走从下往上,之后经过路由层(可以是有名分组和无名分组,可以通过include实现路由分发,反向解析前端通过{ % url ''%} 后端通过reverse),之后通过视图函数层(FBV和FBV)通过获取models进行渲染前端页面然后返回给浏览器。

 

Django as_view的执行过程

当urls中as_view()方法它实际是一个必包,它的作用就是做一些检查工作,在返回view方法

view方法的作用是给请求对象补充三个参数,并调用dispatch方法进行处理

dispatch方法查找到指定的请求方法,并执行相应的代码

(比如一个get请求过来,首先匹配路由,匹配到后执行后面的视图函数,比如匹配的是index函数 执行他的as_view,index中没有as_view回去找它继承的APIView执行APIView中的as_view方法,其实这个as_view就是执行的Django原来的view方法,但是执行self.dispatch的时候,执行的就不是原来view中的dispatch,而是APIView中的dispatch方法,这个dispatch就是在原来的dispatch方法上添加了initialize_request方法,对requext进行了封装,包含了原来的request,然后执行initial认证、权限、频率组件执行原来的流程,执行视图函数,返回response)

 

cookie、session、token

cookie:cookie是浏览器中永久存储的一种数据,仅仅是浏览器实现的一种数据存储功能。由服务器产生发送给浏览器,浏览器把cookie以key,value键值对形式保存到某个文件下,下次访问同一网站再发送给服务器。

session:服务器把session临时保存在服务器上,用户离开网站后session就会被销毁。

token:是无状态可扩展的,支持移动设备,跨程序调用,安全

 

RESTful规范

url连接设计:采用https方式,有api关键字,有版本需要明确版本,请求链接用名词来表示资源,具体的操作方式采用请求方式来确定

url响应数据设计:需要明确状态码、错误信息、成功结果,子资源一般用子资源接口来标注

 

缓存雪崩,缓存击穿,缓存穿透

缓存雪崩:缓存中的数据大批量到过期时间,查询数据量巨大,引起数据库压力过大而宕机(缓存数据的过期时间设为随机,防止同一时间大量数据过期、如果缓存数据库是分布式部署,那就把热点数据均匀分布在不同缓存数据库中、设置热点数据永不过期)

缓存击穿:指在缓存中没有但是在数据库中有的数据(一般是缓存数据过期),很多用户同时访问,缓存数据库中没有,就直接去访问数据库,造成数据库压力过大(设置热点数据永不过期,加互斥锁)

缓存穿透:指缓存中和数据库中都没有的数据,很多用户同时访问,如果找的是id为"-1"或id特别大不存在的数据,会造成用户变成攻击者,导致数据库压力过大。(可以加频率限制或者接口校验id校验)

flask请求上下文

 

六大设计原理

  1. 单一职责原则
  2. 里氏替换原则
  3. 依赖倒装原则
  4. 接口隔离原则
  5. 迪米特法则
  6. 开闭原则

 

冒泡排序

# 时间复杂度:O(n^2) 空间复杂度:O(1)
def bubble_sort(li):
    for i in range(len(li) - 1):
        flag = False
        for j in range(len(li) - 1 - i):
            if li[j] > li[j + 1]:
                li[j], li[j + 1] = li[j + 1], li[j]
                flag = True
        if not flag:
            return

 

快速排序

 时间复杂度:O(n log n)
def partition(li, left, right):
    tmp = li[left]
    while left < right:
        while left < right and li[right] >= tmp:
            right = right - 1
        li[left] = li[right]
        while left < right and li[left] <= tmp:
            left = left + 1
        li[right] = li[left]

    li[left] = tmp
    return left


def quick_sort(li, left, right):
    if left < right:
        middle = partition(li, left, right)  # O(n)
        quick_sort(li, left, middle - 1)  # O(log n)
        quick_sort(li, middle + 1, right)  # O(log n)

 

设计模式

单例模式

工厂模式

代理模式

 

posted @ 2019-08-14 18:37  -Rye-  阅读(163)  评论(0)    收藏  举报