python

1. python 的内存管理

引用计数,变量的赋值只是对对象的引用,删除一个变量就减少了一个引用。 垃圾回收,当对象的引用计数为0时,对象会被垃圾回收,释放内存。自动的垃圾回收是需要一定的阈值条件,垃圾对象达到一定的数量,才会触发;主动触发gc.collect() 内存池机制,python申请的1-256k的小块内存,由malloc进行分配,垃圾回收后,内存不会释放,而是由内存池进行管理,便于下次使用。

2. 类方法与实例方法、静态方法

类方法

  • 使用@classmethod装饰的方法,第一个参数为当前类cls, 可以被类对象、实例对象引用

实例方法

  • 在类中定义的普通方法,第一个参数为当前实例对象self, 可以被类对象、实例对象引用

静态方法

  • 使用@staticmethod装饰的方法,参数不需要传cls或者self,可以自行决定传递的参数,就相当于将一个普通的方法放入类中。 可以被类对象、实例对象引用

3. python的闭包与装饰器

闭包,定义函数时,在其内部又定义了一个函数,内部函数的内部作用域引用了外部函数的局部变量,外部函数返回内部函数,这种函数嵌套的方式就是闭包。

装饰器,它是闭包的一种应用形式,可以在不改变源码的情况下扩展函数的功能。使用\@高阶函数去装饰另一个函数,进行功能扩展。

4. 什么是git? 有什么作用? 如何初始化一个本地仓库

git, 分布式版本控制工具 可以实现软件的版本控制,在多个版本之间切换; 可以实现多分支开发,提高开发效率; 可以实现历史记录,历史状态的恢复; 团队内部实现权限管理等。

初始化本地仓库: git init

5. 什么是并行?什么是并发? Python的多线程属于哪种,为什么?

并发,两个或两个以上的程序,在同一时间内执行。 并行,同时执行,异步独立 python的多线程属于并发,在python解释器内部有一个GIL,所有线程必须申请到该锁才可以解释执行。

  • python 是弱类型的语言,由python解释器边解释边执行。 源码---解释 为01001--交给CPU执行

  • Java C 强类型语言, 源代码需要编译,得到字节码文件 ---CPU执行

  • python解释器 ----开一个进程, 在这个进程里有一个GIL(Global Interpreter Lock)全局解释器锁

  • 在一个进程里开的所有的线程,必须申请这个GIL, 然后才可以执行。其他线程必须等待。

  • 所以python的多线程是属于并发。

6. Django对请求的处理流程

  1. 处理请求的中间件,在进入路由匹配之前对请求做一些预处理或者直接返回响应

  2. 主路由及分布式路由的匹配

  3. 处理视图的中间件,在请求进入视图之前,做一些预处理

  4. 在视图中接收请求、处理请求、返回响应;视图中发生异常时,还可以使用异常处理中间件进行处理。

  5. 处理响应的中间件,对响应做一些预处理

7. 开发模式有哪些?

前后端不分离,页面结构和数据由后端服务器渲染,然后返回给浏览器,由浏览器展示即可。缺点是既要做后端接口,又要做模板页面;服务器计算压力大。 前后端分离,将页面结构、数据分离开,前端服务器返回页面结构,后端服务器返回数据。 由客户端浏览器最终渲染整体页面。可以实现并行开发、充分利用客户端的资源,降低服务器的压力。

8. 什么是静态页面? 动态页面?

静态页面, html/css/js等资源均已准备就绪,由浏览器展示页面即可,不用再动态渲染。 动态页面,浏览器拿到页面后,需要执行js,经过多次与服务端交互,渲染最终的页面。

9. JWT 会话保持的流程

浏览器发起请求登陆,服务端验证身份,根据算法,将用户标识信息编码生成 token, 并且返回给浏览器做本地存储;下次请求时,把本地的 token 一起发送给服务器,服务器通过解码token,完成用户的身份认证。  

10. JWT token的生成过程?

对header {'typ':"JWT", 'alg':"HS256"}进行base64编码,然后将结果中的’=‘替换为“”, 得到第一部分; 对payload {’username‘:"laufing", .....}进行base64编码,然后将结果中的’=‘替换为’‘,得到第二部分; 第一部分通过“.” 拼接第二部分,然后使用HS256算法进行哈希加密,然后base64编码,最后将结果中的’=‘替换为’‘,得到第三部分。   以上三部分通过’.‘ 拼接为一个整体,即得到jwt token。

11. JWT 如何做身份验证的?(JWT的验证过程)

首先,JWT 的 Token 相当是明文,是可以解码的,服务端,拿到 token 后进行解码,解码成功就可拿到用户的信息,即认证成功。 解码流程:将token字符串从右边开始以“.”进行一次分割,得到签名输入部分(header编码+payload编码)、签名部分, 对签名输入部分进行哈希加密(使用header中的alg算法),然后base64编码,将编码结果中的'='替换为“”,然后与签名部分对比,两者一致则验证成功,否则失败。

12. JWT 如何防止 token 被串改?

jwt第三部分signature是关键且无法解密,能被解密出明文的,只有header和payload,假如中间串改了payload,在服务端在执行一次 signature = 哈希加密(header + “.” + payload, 密钥),然后与token中的signature对比,肯定不一致,因为哈希加密是单向不可逆的过程,只要header、payload有任何的改变,计算出的签名一定改变,从而与原来的签名不一致。

13. tcp三次握手的过程:

  • 第一次握手:客户端发送syn包(syn=i)到服务器,并进入SYN_SEND状态,等待服务器确认; SYN:同步序列编号(Synchronize Sequence Numbers)

  • 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=i+1),同时自己也发送一个SYN包(syn=j),即SYN+ACK包,此时服务器进入SYN_RECV状态;

  • 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=j+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。  

14. 类属性和实例属性的区别?

  • 实例属性:在init方法中定义的属性称为实例属性,属于某个实例,不同实例之间互不影响。

  • 类属性:在类里面和方法外面定义的属性称为类属性,属于当前类,可以被所有实例共享。

  • 对象可以访问类属性,但是不能够修改类属性。

  • 如果对象想要修改类属性怎么做?

    • 定义类方法,通过类方法修改。

15. django中csrf的实现机制?

CSRF即跨站伪造请求攻击,是利用用户登录后保存在浏览器中的认证信息(cookie),进行一些恶意操作的过程。   Django预防CSRF攻击的方法:

  1. 配置文件中开启CSRF中间件,然后在模板页面中加入{% csrf_token %}

  2. Django渲染该模板时,就会在页面中生成一个csrftoken口令,同时存入cookie一份

  3. 用户提交POST表单时,将页面中的csrftoken 和cookie中的csrftoken一起发给服务端,django验证两者是否相等,相等则认为是合法请求,否则报403

16. 什么是wsgi, uwsgi, uWSGI

WSGI: web 服务器网关接口, 是一套协议。用于接收请求并进行初次封装,然后将请求交给web框架

uwsgi: 和WSGI一样是一种通讯协议,是uWSGI的独占协议,用于定义传输信息类型

uWSGI:一个web服务器,实现了WSGI协议 uWSGI协议 http协议

17. Redis有哪些优缺点

优点

  1. 数据存储在内存, 读写速度快,性能优异

  2. 支持数据持久化,便于数据备份、恢复

  3. 支持简单的事务,操作满足原子性

  4. 支持String、List、Hash、Set、Zset五种数据类型,满足多场景需求

  5. 支持主从复制,实现读写分离,分担读的压力

  6. 支持哨兵机制,实现自动故障转移

缺点

  1. 数据存储在内存,主机断电则数据丢失

  2. 存储容量受到物理内存的限制,只能用于小数据量的高性能操作

  3. 在线扩容比较困难,系统上线时必须确保有足够的空间

  4. 用于缓存时,易出现’缓存雪崩‘,’缓存击穿‘等问题

18. 为什么要用 Redis 做缓存?

web系统中的缓存是一种降低数据库的查询压力,提高服务性能的一种数据存储方案。它需要更快的数据读写操作,满足多场景的数据类型,更健全的数据安全、数据可用机制等,而redis恰好具有以上这些优点,所以常用Redis作为缓存。

19. Redis为什么这么快

  1. 完全基于内存,内存操作,非常快速。而且数据结构类似于 HashMap,查找和操作的时间复杂度都是O(1);

  2. 采用单线程,避免了不必要的上下文切换和竞争条件,不用考虑各种锁的问题,不存在加锁释放锁操作

  3. 使用 I/O 多路复用,非阻塞 IO模型

20. Redis的应用场景

  • 计数器 可以对 String 进行自增自减运算,从而实现计数器功能。

  • 缓存 将热点数据放到内存中进行缓存,降低数据库的查询压力

  • 会话缓存(session) 可以使用 Redis 来统一存储多台应用服务器的会话信息,解决session不能共享的问题。

  • 全页缓存(FPC) 缓存整个页面,加快页面的响应速度

  • 查找表 查找表和缓存类似,也是利用了 Redis 快速的查找特性。但是查找表的内容不能失效,而缓存的内容可以失效,因为缓存不作为可靠的数据来源。

  • 消息队列 List 是一个双向链表,可以作为生产者、消费者之间的中间队列。不过最好使用 Kafka、RabbitMQ 等消息中间件。

  • 分布式锁实现 在分布式场景下,无法使用单机环境下的锁来对多个节点上的进程进行同步。可以使用 Redis 自带的 SETNX 命令实现分布式锁,除此之外,还可以使用官方提供的 RedLock 分布式锁实现。

  • 其它 Set 可以实现交集、并集等操作,从而实现共同好友等功能。ZSet 可以实现有序性操作,从而实现排行榜等功能。

21. 什么是Redis持久化

持久化就是把内存的数据写到磁盘中去,防止服务宕机了内存数据丢失。 有RDB、AOF两种方式

RDB,将内存数据以二进制形式存入磁盘; AOF,将操作指令写入日志文件。

22. Redis 的持久化机制是什么?各自的优缺点?

方式一:RDB

RDB:是Redis DataBase缩写快照 RDB是Redis默认的持久化方式。按照一定的时间将内存的数据以快照的形式保存到硬盘中,对应产生的数据文件为dump.rdb。通过配置文件中的save参数来定义快照的周期。

优点:

  1. 只有一个文件 dump.rdb,方便持久化。

  2. 容灾性好,一个文件可以保存到安全的磁盘。

  3. 性能最大化,fork 子进程来完成写操作,让主进程继续处理命令,所以是 IO 最大化。

  4. 相对于数据集大时,比 AOF 的启动效率更高。

缺点:

  • 据安全性低

    RDB 是间隔一段时间进行持久化,如果持久化之间 redis 发生故障,会发生数据丢失。所以这种方式更适合数据要求不严谨的时候

方式二 :AOF

  AOF持久化(即Append Only File持久化),则是将Redis执行的每次写命令记录到单独的日志文件中,当重启Redis会重新将持久化的日志中文件恢复数据。

当两种方式同时开启时,数据恢复Redis会优先选择AOF恢复。

优点:

  1. 数据安全,aof 持久化可以配置 appendfsync 属性,有 always,每进行一次 命令操作就记录到 aof 文件中一次。

  2. 通过 append 模式写文件,即使中途服务器宕机,可以通过 redis-check-aof 工具解决数据一致性问题。

  3. AOF 机制的 rewrite 模式。文件过大时会对命令 进行合并重写, 可以删除其中的某些命令

缺点:

  1. AOF 文件比 RDB 文件大,且恢复速度慢。

  2. 数据集大的时候,比 rdb 启动效率低。

两种持久化的对比?

  • AOF文件比RDB更新频率高,优先使用AOF还原数据。

  • AOF比RDB更安全也更大

  • RDB性能比AOF好

  • 如果两个都配了优先加载AOF

23. Redis持久化数据和缓存怎么做扩容

  • 如果Redis被当做缓存使用,使用一致性哈希实现动态扩容缩容。

  • 如果Redis被当做一个持久化存储使用,搭建集群实现扩容。

24. 过期键的删除策略

  • 定时过期:每个设置过期时间的key都需要创建一个定时器,到过期时间就会立即清除。该策略可以立即清除过期的数据,对内存很友好;但是会占用大量的CPU资源去处理过期的数据,从而影响缓存的响应时间和吞吐量。

  • 惰性过期:只有当访问一个key时,才会判断该key是否已过期,过期则清除。极端情况可能出现大量的过期key没有再次被访问,从而不会被清除,占用大量内存。

  • 定期扫描:每隔一定的时间,会扫描expires字典中key,并清除其中已过期的key。该策略是前两者的一个折中方案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得CPU和内存资源达到最优的平衡效果。

25. Redis key的过期时间和永久有效分别怎么设置?对过期的数据怎么处理呢?

EXPIRE设置过期时间和PERSIST设置永久有效。

常见的策略有两种:

  1. 定时去清理过期的缓存;

  2. 当有用户请求过来时,再判断这个请求所用到的缓存是否过期,过期的话就删除。

26. Redis的内存淘汰策略有哪些?

Redis的用于缓存的内存不足时,怎么处理需要新写入且需要申请额外空间的数据。

  • noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。

  • allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key。(这个是最常用的)

  • allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key。

  • volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key。

  • volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key。

  • volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除。

总结

Redis的内存淘汰策略的选取并不会影响过期的key的处理。内存淘汰策略用于处理内存不足时的需要申请额外空间的数据;过期策略用于处理过期的缓存数据。

27. 数据库事务的四大特性

原子性(Atomicity);指事务是一个不可分割的单元,事务中的操作要么全部执行,要么全部不执行。 一致性(Consistency);事务执行前后数据的完整性必须保持一致。这里的完整性包括实体完整性、参照完整性、用户定义的完整性。 隔离性(Isolation);多个用户并发访问数据库时,数据库为每一个用户开启一个事务,多个事务并发执行时,相互之间是隔离开的,互不影响。 持久性(Durability);事务一旦被提交,对数据库中数据的改变是永久性性的。

28. 事务的隔离级别

读未提交

事务A更新了数据,但是还没提交;事务B就读取到A更新的数据,事务A回滚后,B就看不到更新的数据。这种现象就是读未提交,即脏读

读已提交

事务A更新数据并完成提交;事务B内部就可以读取到A更新的数据。

如:开始时,事务A、B读取的库存量都是100; 事务A更新库存为80,并进行了提交。由于事务B处理比较耗时,还没执行结束,B再次读取库存时,已经变成了80;最后B在更新库存时就要在80的基础上进行更新。

可重复读

事务A更新数据并完成提交;在事务B提交之前,其内部无法读取到A更新的数据,只能读取到之前的旧数据。(普通查询,即快照读) 缺点:容易出现幻读

什么是幻读?

对于innodb存储引擎,可重复读的隔离级别,使用当前读(加共享锁)时容易出现幻读,即一个事务进行两次相同条件的查询时,后一次查询看到了上一次没有看到的行。

串行(xing)化

所有事务串行执行,一个执行完成,再执行另一个。

29. 什么是悲观锁、乐观锁?如何选择

悲观锁:在查询语句上加锁,保证多事务写入时串行执行。

例如,在多个用户同时进行订单提交时,哪个事务先执行到该语句则获取锁,等事务结束后才会释放,其他事务阻塞等待获取锁,保证了同一时刻只有一个事务在写入;

乐观锁:查询时不加锁,在变更时对比原数据与当前重新查询的数据是否一致,若不一致则本次变更失败(即乐观的认为当前没有其他事务在同时进行此过程)

在冲突较少时,如订单并发量较少,使用乐观锁(省去加锁、释放锁的开销,提高性能),在冲突较多时,如订单并发量大,使用悲观锁。一般将整个事务的过程都放置于try中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值