request中的字典如何成为不可变的?
分析:在request中的字典要成为不可变的,说明在__setitem__和__delitme__的时候直接异常捕获,所以成为一个不可变的字典。
JWT是什么鬼?
JWT(JSON Web Token):JWT是一个字符串,我们在发起网络请求时,将其放在header或者url中,这样可以保证传递的数据被篡改时能被我们发现,保证安全性。
http://www.example.com/private/?token=xxxxx.yyyyy.zzzzz header.payload.signature
Header:header所表示的JSON对象通常由2个部分组成:token的类型,即"JWT"; token所采用的hash算法,例如HMAC SHA256或者RSA。
Payload:payload为JWT的第二部分,其JSON对象包含一系列键值对(key/value)。其中,有些预定义键有特殊含义,比如iat、exp等,iat表示JWT生成的实际,而exp代表JWT过期的时间。开发者可以使用其他非预定义的键用于传输数据。
Signature:signatrue,即签名,是JWT的第三部分。它由编码的header和payload,使用用户指定的密钥secret,采用header中指定的哈希算法生成。
OneToOneField的本质是什么?
本质是继承了ForeignKey。
全局式唯一ID
- 全局唯一性:不能出现重复的ID号,既然是唯一标识,这是最基本的要求。
- 趋势递增:在MySQL InnoDB引擎中使用的是聚集索引,由于多数RDBMS使用B-tree的数据结构来存储索引数据,在主键的选择上面我们应该尽量使用有序的主键保证写入性能。
- 单调递增:保证下一个ID一定大于上一个ID,例如事务版本号、IM增量消息、排序等特殊需求。
- 信息安全:如果ID是连续的,恶意用户的扒取工作就非常容易做了,直接按照顺序下载指定URL即可;如果是订单号就更危险了,竞对可以直接知道我们一天的单量。所以在一些应用场景下,会需要ID无规则、不规则。
由此总结下一个ID生成系统应该做到如下几点:
TPS:是TransactionsPerSecond的缩写,也就是事务数/秒。它是软件测试结果的测量单位。一个事务是指一个客户机向服务器发送请求然后服务器做出反应的过程。客户机在发送请时开始计时,收到服务器响应后结束计时,以此来计算使用的时间和完成的事务个数
- 平均延迟和TP999延迟都要尽可能低(TP90就是满足百分之九十的网络请求所需要的最低耗时。TP99就是满足百分之九十九的网络请求所需要的最低耗时。同理TP999就是满足千分之九百九十九的网络请求所需要的最低耗时);
- 可用性5个9(99.999%);
- 高QPS(每秒查询率,是一台服务器每秒能够相应的查询次数,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准)。
分布式全局唯一ID常用解决方案:
uuid:
这是最容易想到的方案,UUID(Universally Unique Identifier)是32个16进制数字,以连字号分为五段,形式为8-4-4-4-12的36个字符,目前生成方式有5种,可参考A Universally Unique IDentifier (UUID) URN Namespace
优点:
- 性能非常高:本地生成,没有网络消耗。
缺点:
- 不易于存储:UUID太长,16字节128位,通常以36长度的字符串表示,很多场景不适用。
- 信息不安全:基于MAC地址生成UUID的算法可能会造成MAC地址泄露,这个漏洞曾被用于寻找梅丽莎病毒的制作者位置。
- ID作为主键时在特定的环境会存在一些问题,比如做DB主键的场景下,UUID就非常不适用
数据库自增主键:
可以创建一个表,通过数据插入获取对应的自增主键,作为全局唯一id
缺点也很明显,就是高并发的场景下,受限于单台mysql的性能。而且可用性差,DB出现问题会导致id无法生成。
当然可以通过主从的方式增强可用性,同时增加表采用不同自增步长的方式增加并发性能,比如假设我们要部署N台机器,步长需设置为N,每台的初始值依次为0,1,2…N-1;但是还会带来新的问题,比如不利于拓展,想提升性能就要堆机器,但是步长已经确定不好更改,主从延迟会导致唯一id的不唯一。
优点:
- 非常简单,利用现有数据库系统的功能实现,成本小,有DBA专业维护。
- ID号单调自增,可以实现一些对ID有特殊要求的业务。
缺点:
- 强依赖DB,当DB异常时整个系统不可用,属于致命问题。配置主从复制可以尽可能的增加可用性,但是数据一致性在特殊情况下难以保证。主从切换时的不一致可能会导致重复发号。
- ID发号性能瓶颈限制在单台MySQL的读写性能。
snowflake:
这是twitter开源的分布式id生成算法,这种方案把64-bit分别划分成多段,分开来标示机器、时间等。
上面第一个部分,是1个bit:0,这个是无意义的上面第二个部分是41个bit:表示的是时间戳;上面第三个部分是5个bit:表示的是机房id,10001上面第四个部分是5个bit:表示的是机器id,1 1001上面第五个部分是12个bit:表示的序号,就是某个机房某台机器上这一毫秒内同时生成的id的序号,0000 00000000
优点:
- 毫秒数在高位,自增序列在低位,整个ID都是趋势递增的。
- 不依赖数据库等第三方系统,以服务的方式部署,稳定性更高,生成ID的性能也是非常高的。
- 可以根据自身业务特性分配bit位,非常灵活。
缺点:
- 强依赖机器时钟,如果机器上时钟回拨,会导致发号重复或者服务会处于不可用状态。
邮箱前面的字符(数字,字母,下划线)
sql的左连接,右连接,内连接,全连接(笛卡尔积)
左连接:select * from A left join B on A.id = B.id
右连接:select * from A right join B on A.id = B.id
内链接:select * from A inner join B on A.id = B.id
全连接:select * from A full join B on A.id = B.id