计算机组成原理(六)——系统总线
一、系统总线的特性及其应用
总线:是计算机体系结构的重要组成部分,通过它可以将计算机系统中各个功能部件连接起来,构成一个完整的系统。














二、总线性能和总线事务










三、总线连接方式








四、总线仲裁、操作和定时


















五、总线标准













*快速面经(from七牛云 go面经)
https加密过程
(1)首先,客户端发起握手请求,以明文传输请求信息,包含版本信息,加密-套件候选列表,压缩算法候选列表,随机数,扩展字段等信息(这个没什么好说的,就是用户在浏览器里输入一个HTTPS网址,然后连接到服务端的443端口)。
(2)服务端的配置,采用HTTPS协议的服务器必须要有一套数字证书,可以自己制作,也可以向组织申请。区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用受信任的公司CA申请的证书则不会弹出提示页面。这套证书其实就是一对公钥和私钥。如果对公钥不太理解,可以想象成一把钥匙和一个锁头,只是世界上只有你一个人有这把钥匙,你可以把锁头给别人,别人可以用这个锁把重要的东西锁起来,然后发给你,因为只有你一个人有这把钥匙,所以只有你才能看到被这把锁锁起来的东西。
(3)服务端返回协商的信息结果,包括选择使用的协议版本 version,选择的加密套件 cipher suite,选择的压缩算法 compression method、随机数 random_S 以及证书。(这个证书其实就是公钥,只是包含了很多信息,如证书的颁发机构,过期时间等等)。
(4)客户端验证证书的合法性,包括可信性,是否吊销,过期时间和域名。(这部分工作是由客户端的SSL/TLS来完成的,首先会验证公钥是否有效,比如颁发机构,过期时间等等,如果发现异常,则会弹出一个警示框,提示证书存在的问题。如果证书没有问题,那么就生成一个随机值。然后用证书(也就是公钥)对这个随机值进行加密。就好像上面说的,把随机值用锁头锁起来,这样除非有钥匙,不然看不到被锁住的内容)。
(5)客户端使用公匙对对称密匙加密,发送给服务端。(这部分传送的是用证书加密后的随机值,目的是让服务端得到这个随机值,以后客户端和服务端的通信就可以通过这个随机值来进行加密解密了)。
(6)服务器用私钥解密,拿到对称加密的密匙。(服务端用私钥解密后,得到了客户端传过来的随机值,然后把内容通过该随机值进行对称加密,将信息和私钥通过某种算法混合在一起,这样除非知道私钥,不然无法获取内容,而正好客户端和服务端都知道这个私钥,所以只要加密算法够彪悍,私钥够复杂,数据就够安全)。
(7)传输加密后的信息,这部分信息就是服务端用私钥加密后的信息,可以在客户端用随机值解密还原。
(8)客户端解密信息,客户端用之前生产的私钥解密服务端传过来的信息,于是获取了解密后的内容。整个过程第三方即使监听到了数据,也束手无策。
三次握手为什么是三次,四次挥手为什么是四次?
(1)三次握手才可以阻止重复历史连接的初始化(主要原因),三次握手才可以同步双方的初始序列号,三次握手才可以避免资源浪费。
(2)关闭连接时,客户端向服务端发送 FIN
时,仅仅表示客户端不再发送数据了但是还能接收数据。服务器收到客户端的 FIN
报文时,先回一个 ACK
应答报文,而服务端可能还有数据需要处理和发送,等服务端不再发送数据时,才发送 FIN
报文给客户端来表示同意现在关闭连接。从上面过程可知,服务端通常需要等待完成数据的发送和处理,所以服务端的 ACK
和 FIN
一般都会分开发送,从而比三次握手导致多了一次。
go channel的使用场景
把channel用在数据流动的地方:
(1)消息传递、消息过滤
(2)信号广播
(3)事件订阅与广播
(4)请求、响应转发
(5)任务分发
(6)结果汇总
(7)并发控制
(8)同步与异步
goroutine泄漏问题
goroutine泄漏是指客户端生成一个goroutine来做一些异步任务,并在任务完成后将一些数据写入一个channel,但是没有监听程序消耗该channel的数据写入。
channel关闭后再写入会怎样,读写过程分别是怎样的?
①读已关闭的channel
读已经关闭的channel无影响。
如果在关闭前,通道内部有元素,会正确读到元素的值;如果关闭前通道无元素,则会读取到通道内元素类型对应的零值。
若遍历通道,如果通道未关闭,读完元素后,会报死锁的错误。
fatal error: all goroutines are asleep - deadlock!
②写已关闭的通道
会引发panic: send on closed channel
③关闭已关闭的通道
会引发panic: close of closed channel
总结:对于一个已初始化,但并未关闭的通道来说,收发操作一定不会引发 panic。但是通道一旦关闭,再对它进行发送操作,就会引发 panic。如果我们试图关闭一个已经关闭了的通道,也会引发 panic。
slice切片底层
Go 的 slice 底层数据结构是由一个 array 指针指向底层数组,len 表示切片长度,cap 表示切片容量。
slice 的主要实现是扩容。对于 append 向 slice 添加元素时,假如 slice 容量够用,则追加新元素进去,slice.len++,返回原来的 slice。当原容量不够,则 slice 先扩容,扩容之后 slice 得到新的 slice,将元素追加进新的 slice,slice.len++,返回新的 slice。
对于切片的扩容规则:当切片比较小时(容量小于 1024),则采用较大的扩容倍速进行扩容(新的扩容会是原来的 2 倍),避免频繁扩容,从而减少内存分配的次数和数据拷贝的代价。当切片较大的时(原来的 slice 的容量大于或者等于 1024),采用较小的扩容倍速(新的扩容将扩大大于或者等于原来 1.25 倍),主要避免空间浪费,网上其实很多总结的是 1.25 倍,那是在不考虑内存对齐的情况下,实际上还要考虑内存对齐,扩容是大于或者等于 1.25 倍。
MySQL索引类别 优点缺点
普通索引:仅加速查询
唯一索引:加速查询 + 列值唯一(可以有null)+ 表中可以多个唯一索引
主键索引:加速查询 + 列值唯一(不允许有null)+ 表中只有一个主键(特殊的唯一索引)
组合索引:多列值组成一个索引,专门用于组合搜索,其效率大于索引合并
全文索引:对文本的内容进行分词,进行搜索
一、索引的优点
1)创建索引可以大幅提高系统性能,帮助用户提高查询的速度;
2)通过索引的唯一性,可以保证数据库表中的每一行数据的唯一性;
3)可以加速表与表之间的链接;
4)降低查询中分组和排序的时间。
二、索引的缺点
1)索引的存储需要占用磁盘空间;
2)当数据的量非常巨大时,索引的创建和维护所耗费的时间也是相当大的;
3)当每次执行CRU操作时,索引也需要动态维护,降低了数据的维护速度。
Redis有哪些数据类型 以及各种数据类型的底层结构
Redis是一款基于键值对的NoSQL数据库,它的值支持多种数据结构:字符串(strings)、哈希(hashes)、列表(lists)、集合(sets)、有序集合(sorted sets)等随着Redis版本的更新迭代,还有四种数据类型:bitmap、GEO、HyperLogLog,以及Redis5.0中的Streams。

Redis集群查询数据保存在哪里
Redis集群查询数据保存在每个节点的内存中,并可以通过复制机制在节点之间进行同步。
Redis集群哨兵搭建
1 为什么要使用哨兵模式
主从模式下,主机会自动将数据同步到从机,为了分载Master的读操作压力,Slave服务器可以为客户端提供只读操作的服务,写服务依然必须由Master来完成,实现读写分离。当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用。
2 哨兵模式的工作原理
在主从模式下,redis同时提供了哨兵命令redis-sentinel,哨兵是一个独立的进程,作为进程,它会独立运行。其原理是哨兵进程向所有的redis机器发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例。
哨兵可以有多个,一般为了便于决策选举,使用奇数个哨兵。哨兵可以和redis机器部署在一起,也可以部署在其他的机器上。多个哨兵构成一个哨兵集群,哨兵直接也会相互通信,检查哨兵是否正常运行,同时发现master宕机哨兵之间会进行决策选举新的master。
项目 项目设计表设计 怎么解决支付失败 原子性问题
支付失败,可以进行重试的机制,重试一定的次数,并且为了防止重复支付,做幂等处理,幂等处理可以用全局唯一的key做表示,比较有名的是雪花算法,雪花算法利用到集群、机器、随机数等关键信息防止重复。
DNS协议 详细过程
dns协议是域名协议,将域名解析成IP地址,常用的有两种方式,递归方法和迭代方式,递归方式是,先根据域名查询机器的dns缓存,判断是否查找,查不到的话,在去根域名进行查找顶层域名服务器在哪,在下发到子层域名服务器,一直找到后,在发送给本地。迭代的方式,需要发送多次报文。具体流程是:先查询host文件,在判断本地dns缓存或者浏览器缓存有没有,没有的话,在通过域名服务器去查询。
https四次握手详细过程
https是一个比较安全的协议,在http基础之前添加了一层tls、ssl层用于安全校验,https先进行非对称加密交换对称加密的密钥,后续的数据传输采用对称加密进行传输。大体流程是:客户端首次连接服务器,会带上自己支持加密算法的集合、随机数1,服务端收到随机数1之后,发送自己的随机数2和加密算法(这个加密算法必须是客户端发送的子集),服务端会把自己的ca证书发送给客户端,客户端收到ca证书之后,会拿着ca证书去ca机构认证一下ca证书的合法性,合法之后,会取出ca证书的非对称加密的公钥,自己生成一个预密钥,通过公钥加密之后传输给服务端,服务端通过私钥进行解密,获取随机数1、随机数2、预密钥,服务端将之组装成对称加密的密钥,在客户端和服务端游共同的密钥之后,以后的数据传输都采用对称加密传输。
go channel详细底层结构 有无缓冲并发数据读写问题 底层锁
chan是go语言并发通信的核心之一,chan可以类比成一个queue加上mutex的组合,chan名字为管道或者通道,chan的底层是是一个循环数组,有读写标志位,还有读写等待队列,数据类型标志,还有Mutex用于处理并发问题,chan分为两类,一种是无缓冲的,另一种是有缓冲的,无缓冲的chan必须以有一个协程读,一个协程负责写,处理不好的话,很容易出现死锁,而有缓冲的chan,只有在缓冲区写完了才会进行写阻塞。
go interface接口 GMP模型
Golang在底层实现了混合型线程模型。M即系统线程,由系统调用产生,一个M关联一个KSE,即两级线程模型中的系统线程。G为Groutine,即两级线程模型的的应用及线程。M与G的关系是N:M。

G-M-P分别代表:
G - Goroutine,Go协程,是参与调度与执行的最小单位
M - Machine,指的是系统级线程
P - Processor,指的是逻辑处理器,P关联了的本地可运行G的队列(也称为LRQ),最多可存放256个G。
GMP调度流程
线程M要想运行任务,就要先获取P,即M先与P关联
P从本地队列(local p) 中获取G
若本地队列中没有可供运行的G,M会先尝试从全局队列获取一批G放到P的本地队列
若全局队列也没有找到可以运行的G,M会随机从其他P的本地队列中偷一半的G放到自己的P本地队列
拿到可以运行的G后,M先运行G,G执行以后,M会从P中获取下一个G,一直不断重复
GMP调度策略
复用线程: work stealing 和 hand off 机制保证M线程的高效复用
利用并行: GOMAXPROCS 设置P的数量,充分利用CPU的多核和m多线程
抢占:完全公平的时间片轮转,每个G只能占用10ms,防止其他G饿死