1.数字签名、私钥签名、公钥验证
数字签名(又称为公钥数字签名)
目前,通用的单钥加密算法为DES(Data Encryption Standard),通用的双钥加密算法为RSA( Rivest-Shamir-Adleman),都产生于上个世纪70年代。
在双钥体系中,公钥用来加密信息,私钥用来数字签名。
每一对公钥和私钥都是一一对应的,世界上独一无二。
公钥私钥都可以解密对方加密过得数据
通过公钥很难或者不可能推算出私钥
数字证书包含 公钥、证书信息、公钥方的信息
1.客户端发送一个加密请求
2.服务器用私钥加密网页;用hash去除文章的摘要,然后用私钥加密摘要生成签名;将加密的网页和签名和CA认证的证书一块发送给客户端
3.客户端用CA公钥解密,获得服务端的公钥,用公钥解密数字签名,获得摘要,证明发送方是服务端,对文章解密后进行hash生成摘要判断与数字签名中的摘要是否一样,来验证文章是否被修改过。
4.客户端验证数字证书可靠后,就用数字证书中的公钥加密信息,与服务端进行通信。
2.二级索引或辅助索引(就是非聚簇索引的别名),聚簇索引和非聚簇索引的区别
B+树索引分为聚簇索引和非聚簇索引
聚簇索引:data域存的是真实的数据行
聚簇索引就是按照每张表的主键构造一颗B+树,同时叶子节点中存放的就是整张表的行记录数据,也将聚集索引的叶子节点称为数据页。这个特性决定了索引组织表中数据也是索引的一部分,每张表只能拥有一个聚簇索引。
Innodb通过主键聚集数据,如果没有定义主键,innodb会选择非空的唯一索引代替。如果没有这样的索引,innodb会隐式的定义一个主键来作为聚簇索引。
聚簇索引优点:
1.数据访问更快,因为聚簇索引将索引和数据保存在同一个B+树中,因此从聚簇索引中获取数据比非聚簇索引更快。聚簇索引对于主键的排序查找和范围查找速度非常快
聚簇索引的缺点:
1.插入速度严重依赖于插入顺序,按照主键的顺序插入是最快的方式,否则将会出现页分裂,严重影响性能。因此,对于InnoDB表,我们一般都会定义一个自增的ID列为主键
2.更新主键的代价很高,因为将会导致被更新的行移动。因此,对于InnoDB表,我们一般定义主键为不可更新。
3.二级索引访问需要两次索引查找,第一次找到主键值,第二次根据主键值找到行数据。
非聚簇索引:data域存的是主键的值
辅助索引访问数据总是需要二次查找,先通过非聚簇索引找到主键值,再通过主键的值去聚簇索引找到相应的数据。
辅助索引的存在不影响数据在聚簇索引中的组织,所以一张表可以有多个辅助索引。在innodb中有时也称辅助索引为二级索引。
MyISAM:data域存的是数据的地址
MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址
在MyISAM中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求key是唯一的,而辅助索引的key可以重复
B树每个节点都会存数据,而B+树只有叶子结点才会存储数据,减少IO操作,B+树查找会更快
聚簇索引的叶子节点存放的是主键值和数据行,支持覆盖索引;二级索引的叶子节点存放的是主键值或指向数据行的指针。
由于节子节点(数据页)只能按照一颗B+树排序,故一张表只能有一个聚簇索引。辅助索引的存在不影响聚簇索引中数据的组织,所以一张表可以有多个辅助索引
Innodb和MyISAM中的非聚簇索引不同,一个存的是主键值,一个存的是数据的地址。
3.事务隔离级别
可能出现的问题:
1.丢失修改,两个事务同时修改,一个事务的修改丢失
2.不可重复度,一个事务两次读取数据的期间有另一个事务修改了数据,导致两次读的数据不一样
3.脏读,读到了别人未提交的数据,之后别人的事务又回滚了,所以之前读到的数据为无效数据
4.幻读,读取一个范围内的数据,之后有事务在此范围内插入了新的数据,再次查询此范围读取到的数据条数不一致
读未提交:
读:不加锁
写:行级共享锁,事务提交时释放
解决丢失修改问题
读提交:
读:行级共享锁,读完立即释放
写:行级排他锁,事务结束释放
可重复读:
读:行级共享锁,事务提交时释放
写,行级排他锁,事务提交时释放
串行化:
直接加表级锁
select xxx lock in share mode
select xxx for update
不用上面两句使用的就是快照读,否则就是当前读
mvcc
读是当前读,每行记录里保存了行的创建时间和删除时间(版本号)。
可重复读mvcc:
select:查找版本号早于当期事务的版本号,保证是事务开始前就有的,且未被删除
insert:为新插入的一行保存当前事务的版本号作为创建版本号
delete:未删除的每一行保存当前事务版本号作为行的删除版本号
update:插入一行新的记录,保存当前事务版本号作为该行的创建版本号;同时保存当前事务版本号作为原来行的删除版本号。
undo log:逻辑日志,记录的insert、update、delete操作,用undo log实现MySQL中的innodb的mvcc
redo log:物理日志:记录物理修改操作
4.sql中的事务怎么写
begin 事务名
commit 事务名
rollback 事务名
5.STL类库
vector
map
set
unordered_set
unordered_map
queue
stack
list
deque
priority_queue
6.线程安全的map(go,java,c++)
go中map的清除标记删除元素有些类似java垃圾回收中survive和from survive清除不用元素的思想,左右来回倒腾
go sync.map核心的数据结构
mu Mutex 锁
read atomic.Value 用来读数据,类似快照读
dirty map[interface{}]*entry 存数据的字典
misses int 存储查找read失败的次数,如果超过dirty的长度就重新将dirty拷贝给read,将dirty和misses清空!并将read.amended设为false,当有read中没有的数据存储进来之后又变为true
Load()
先去read中查找数据,不加锁,如果read中有就返回,没有就加锁,然后再判断,再去dirty中查找相应的数据,让misses++。如果找到就返回,没找到就返回nil
Store()
两种操作,修改和新增
先在read中查找,如果有就直接在read中修改
之后加锁,先判断在read中是否为expunged,如果是在dirty中重新添加该key并替换value,再判断如果read中没有而dirty中有,就直接替换dirty中的value,再判断当两个地方都没有,是否刚进行过dirty转read,有就调用dirtyLocked()然后再dirty中添加数据,dirtylocked方法将read中的v不为nil的kv复制到dirty中,read为nil的kv(后面可以知道这是被delete掉的kv)则将v设置为expunged,在下次dr转换时即被永久删除。
Delete()
Delete方法,调用Delete后先看在read中是否有该kv,如果有,就调用e.delete方法进行删除,如果没有再看dirty中是否存在该kv,如果有则用golang的delete方法从dirty中删除,e.delete方法是是惰性删除,调用后将read中该kv的v设置为nil。
7.C++11的新特性
1.引入nullptr用来区分NULL和0,防止函数重载时候发生的混乱
2.auto关键字可以推断类型,例如书写迭代器,一长串就只用写一个auto了,auto不能用于函数传参
3.for(auto i : a) for循环的区间迭代方式
4.引入unordered_map和unordered_set,unordered_multimap和unordered_multiset,array等
8.Go语言的method输入是pointer还是变量值
go语言默认是值拷贝,除了切片,map,channel是传递指针
如果需要修改结构体中的内容,需要用结构体类型的指针作为接收器,而不能用指针类型本身
func (p *Point) f1() // 正确
type PP *Point
func (pp PP) f2() { // 编译错误
}
9.1NF,2NF,3NF,以及为什么要规定范式(去冗余,维护一致性)
范式是指满足一系列要求的集合,第几范式就是第几级别,一般数据库只满足第三范式就可以了
范化是将一句换转换为数据库表的过程,让一个表修改尽量不影响其他表
第一范式:第一范式的数据表必须是二维数据表,第一范式是指数据库的每一列都是不可分割的基本数据项,强调列的原子性,不满足第一范式的一定不是关系型数据库。
第二范式:建立在第一范式基础上,满足第二范式的一定满足第一范式。第二范式要求,表必须有一个主键,没有包含在主键中的列必须完全依赖于主键,而不能只依赖主键的一部分(联合主键)。
第三范式:某一个表是第二范式,且每一个非主属性都不传递依赖于该范式的候选键,即不能存在非主键列A依赖于非主键列B,非主键B依赖主键的情况
BCNF:在第三范式的基础上,进一步的修正,是由B和C两个人提出的。消除主属性之间的部分函数依赖和传递函数依赖
10.https证书,对称加密,非对称加密,以及整个流程
11.Http状态码200、400、501等
1xx 表示请求正在处理
2xx 表示请求被成功处理
3xx 重定向
4xx 客户端错误
5xx 服务端错误
100 continue 客户端继续处理请求
101 Switching protocol 服务器根据客户端的请求切换到更高级的协议
200 ok 请求成功
201 created 请求已实现,并且有一个新的资源已经依据需求而建立
202 accepted 请求已接受,但还未处理完
203 Non-Authoritative Information 非授权信息,请求成功,但是返回的meta信息不是原始服务器的,而是一个副本
204 No Content 无内容。服务器成功处理了请求,但不需要返回任何实体内容
205 Reset Content 重置内容。与 204 类似,不同点是返回此状态码的响应要求请求者重置文档视图
206 Partial Content 部分内容。服务器成功处理了部分 GET 请求
300 Multiple Choices 多种选择。被请求的资源有一系列可供选择的回馈信息,用户或浏览器能够自行选择一个首选地址进行重定向
301 Moved Permanently 永久移动。请求的资源已被永久地移动到新 URI,返回信息会包含新的 URI,浏览器会自动定向到新 URI
302 Found 临时移动。与 301 类似。但资源只是临时被移动,客户端应继续使用原有URI
303 See Other 查看其它地址。与301类似。使用GET和POST请求查看
304 Not Modified 未修改。如果客户端发送了一个带条件的 GET 请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个状态码
305 Use Proxy 使用代理。被请求的资源必须通过指定的代理才能被访问
306 Unused 在最新版的规范中,306状态码已经不再被使用
307 Temporary Redirect 临时重定向。请求的资源现在临时从不同的URI 响应请求,与302类似
400 Bad Request 客户端请求的语法错误,服务器无法理解;请求的参数有误
401 Unauthorized 当前请求需要用户验证
402 Payment Required 该状态码是为了将来可能的需求而预留的
403 Forbidden 服务器已经理解请求,但是拒绝执行它
404 Not Found 请求失败,请求所希望得到的资源未被在服务器上发现
405 Method Not Allowed 客户端请求中的方法被禁止
406 Not Acceptable 请求的资源的内容特性无法满足请求头中的条件,因而无法生成响应实体
407 Proxy Authentication Required 与401响应类似,只不过客户端必须在代理服务器上进行身份验证
408 Request Time-out 请求超时。服务器等待客户端发送的请求时间过长,超时
409 Conflict 由于和被请求的资源的当前状态之间存在冲突,请求无法完成
410 Gone 被请求的资源在服务器上已经不再可用,而且没有任何已知的转发地址
411 Length Required 服务器拒绝在没有定义 Content-Length 头的情况下接受请求
412 Precondition Failed 客户端请求信息的先决条件错误
413 Request Entity Too Large 服务器拒绝处理当前请求,因为该请求提交的实体数据大小超过了服务器愿意或者能够处理的范围
414 Request-URI Too Large 请求的 URI 长度超过了服务器能够解释的长度,因此服务器拒绝对该请求提供服务
415 Unsupported Media Type 服务器无法处理请求附带的媒体格式
416 Requested range not satisfiable 客户端请求的范围无效
417 Expectation Failed 服务器无法满足Expect的请求头信息
500 Internal Server 服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理
501 Not Implemented 服务器不支持当前请求所需要的某个功能
502 Bad Gateway 作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到无效的响应
503 Service Unavailable 由于临时的服务器维护或者过载,服务器当前无法处理请求,一段时间后可能恢复正常
504 Gateway Time-out 充当网关或代理的服务器,未及时从远端服务器获取请求
505 HTTP Version not supported 服务器不支持,或者拒绝支持在请求中使用的 HTTP 版本
12.https和http的区别,https的连接过程,非对称加密为什么比对称加密性能低
13.加密算法
常见的 对称加密 算法主要有 DES、3DES、AES 等,常见的 非对称算法 主要有 RSA、DSA 等,散列算法 主要有 SHA-1、MD5 等。
14.tcp三次握手,问什么是三次而不是四次或者
三次握手的主要目的是确认自己和对方的发送和接收都是正常的,从而保证了双方能够进行可靠通信。若采用两次握手,当第二次握手后就建立连接的话,此时客户端知道服务器能够正常接收到自己发送的数据,而服务器并不知道客户端是否能够收到自己发送的数据。
我们知道网络往往是非理想状态的(存在丢包和延迟),当客户端发起创建连接的请求时,如果服务器直接创建了这个连接并返回包含 SYN、ACK 和 Seq 等内容的数据包给客户端,这个数据包因为网络传输的原因丢失了,丢失之后客户端就一直接收不到返回的数据包。由于客户端可能设置了一个超时时间,一段时间后就关闭了连接建立的请求,再重新发起新的请求,而服务器端是不知道的,如果没有第三次握手告诉服务器客户端能否收到服务器传输的数据的话,服务器端的端口就会一直开着,等到客户端因超时重新发出请求时,服务器就会重新开启一个端口连接。长此以往, 这样的端口越来越多,就会造成服务器开销的浪费。
15.TIME_WAIT和CLOSE_WAIT的含义和区别
在服务器收到客户端关闭连接的请求并告诉客户端自己已经成功收到了该请求之后,服务器进入了 CLOSE-WAIT 状态,然而此时有可能服务端还有一些数据没有传输完成,因此不能立即关闭连接,而 CLOSE-WAIT 状态就是为了保证服务器在关闭连接之前将待发送的数据发送完成。
TIME-WAIT 发生在第四次挥手,当客户端向服务端发送 ACK 确认报文后进入该状态,若取消该状态,即客户端在收到服务端的 FIN 报文后立即关闭连接,此时服务端相应的端口并没有关闭,若客户端在相同的端口立即建立新的连接,则有可能接收到上一次连接中残留的数据包,可能会导致不可预料的异常出现。除此之外,假设客户端最后一次发送的 ACK 包在传输的时候丢失了,由于 TCP 协议的超时重传机制,服务端将重发 FIN 报文,若客户端并没有维持 TIME-WAIT 状态而直接关闭的话,当收到服务端重新发送的 FIN 包时,客户端就会用 RST 包来响应服务端,这将会使得对方认为是有错误发生,然而其实只是正常的关闭连接过程,并没有出现异常情况。
16.TIME_WAIT为什么时长是2MSL而不是MSL
当客户端发出最后的 ACK 确认报文时,并不能确定服务器端能够收到该段报文。所以客户端在发送完 ACK 确认报文之后,会设置一个时长为 2 MSL 的计时器。MSL(Maximum Segment Lifetime),指一段 TCP 报文在传输过程中的最大生命周期。2 MSL 即是服务器端发出 FIN 报文和客户端发出的 ACK 确认报文所能保持有效的最大时长。
若服务器在 1 MSL 内没有收到客户端发出的 ACK 确认报文,再次向客户端发出 FIN 报文。如果客户端在 2 MSL 内收到了服务器再次发来的 FIN 报文,说明服务器由于一些原因并没有收到客户端发出的 ACK 确认报文。客户端将再次向服务器发出 ACK 确认报文,并重新开始 2 MSL 的计时。
若客户端在 2MSL 内没有再次收到服务器发送的 FIN 报文,则说明服务器正常接收到客户端 ACK 确认报文,客户端可以进入 CLOSE 阶段,即完成四次挥手。
所以客户端要经历 2 MSL 时长的 TIME-WAIT 阶段,为的是确认服务器能否接收到客户端发出的 ACK 确认报文。
17.go内存模型
18.处理高并发有哪些方法
1.微服务拆分系统,每个系统用自己的数据库,负责自己的服务,提高并发能力
2.缓存
3.MQ消息队列
4.分库分表
5.读写分离
6.搭建集群,负载均衡
19.epoll和select有什么区别,使用线程处理并发一定比使用epoll差吗
20.mysql的索引类型,说一下B+数索引,为什么要用B+树
21.MapReduce的Map和Reduce是怎么做的,简短说一下wordcount
22.Hash索引和B+树索引各自的优劣势
23.epoll的水平触发和边缘触发的区别,如何处理边缘触发模式下数据的读取
24.在浏览器输入一个网址后的过程,dns解析的过程
25.Redis有多少种数据类型,底层实现,插入查找的时间复杂度
26.Linux的内核空间和用户空间的区别
27.fork具体发生了哪些事情
28.对链表进行排序,我给出归并排序的方法,又问不使用递归如何做归并排序,还有其他方法可以对它排序吗,回答冒泡排序,又问如何优化冒泡排序,如果链表部分有序如何优化?
29.页面置换算法,OPT、FIFO、CLOCK、LRU的实现
30.Redis有序集合为什么使用跳表,而不用B+树