菜鸟程序员的成长日记
堆和栈的区别
1、申请方式的不同。栈由系统自动分配,而堆是人为申请开辟;
2、申请大小的不同。栈获得的空间较小,而堆获得的空间较大;
3、申请效率的不同。栈由系统自动分配,速度较快,而堆一般速度比较慢;
4、存储内容的不同。栈在函数调用时,函数调用语句的下一条可执行语句的地址第一个进栈,然后函数的各个参数进栈,其中静态变量是不入栈的。而堆一般是在头部用一个字节存放堆的大小,堆中的具体内容是人为安排;
5、底层不同。栈是连续的空间,而堆是不连续的空间。
谈一下你对MySQL索引的理解
首先提到索引,先来了解一下索引是什么?索引是帮助MySQL高校获取数据的数据结构,那么索引能干什么?索引非常关键,尤其是当表中的数据量越来越大时,索引对于性能的影响愈发重要。 索引能够轻易将查询性能提高好几个数量级,总的来说就是可以明显的提高查询效率。
那么这里要延伸一个问题:索引的分类
索引的分类
1 从存储结构上来划分: BTree索引(B-Tree或B+Tree索引),Hash索引,full-index全文索引,R-Tree索引。这里所描述的是索引存储时保存的形式
2 从应用层次来分: 普通索引、唯一索引、主键索引、复合索引
3 根据索引与数据的存储关系划分: 聚簇索引和非聚簇索引
普通索引: 即一个索引只包含单个列,一个表可以有多个单列索引
唯一索引: 索引列的值必须唯一,但允许有空值
主键索引: 唯一索引 + 不允许有空值
复合索引: 多列值组成一个索引,专门用于组合搜索,其效率大于索引合并
聚簇索引的优缺点
优点:
1、可以把相关数据保存在一起,例如可以根据用户id来聚集数据,这样只需要从磁盘读取少数的数据页就能获取某个用户的全部邮件,如果没有使用聚簇索引,那么每一封邮件都可能导致一次磁盘的IO。
2、访问数据更快,聚簇索引将索引和数据保存在一个B+树上,因为比非聚簇索引获取数据更快,非聚簇索引还得回表到聚簇索引上根据主键查询需要的数据行。
3、使用索引覆盖扫描的查询可以直接使用页节点中的主键值。
缺点:
1、插入速度严重依赖于插入顺序,按照主键的顺序插入是加载数据页到InnoDB表中速度最快的方式。但是如果不按照主键顺序加载数据,那么在加载完成后最好使用 optimize table 命令重新组织一下表。
2、更新聚簇索引列的代价很高,因为会强制InnoDB将每个被更新的行移动到新的位置。插入的时候会面临页分裂的问题。页分裂会导致表占用更多的磁盘空间。
3、二级索引可能比想象的大,因为二级索引的叶子结点保存了引用行的主键
4、二级索引访问需要两次索引查找,要回表,对于innodb,自适应hash索引能够减少这样的重复工作。
MySQL里面存在对应的索引,底层的数据结构是通过B+树或者hash表来实现的,具体的数据结构是和存储引擎相关的,如果使用的是MyISAM或者是InnoDB存储引擎,底层的数据结构是B+树,如果是MEMORY存储引擎,则底层是hash表,不同的存储引擎表示的是数据在磁盘上的组织形式。那为什么MyISAM和InnoDB要使用B+树,因为B+树可以让我们树的高度尽可能的最小,减少io次数,提高读取效率。
这里就会延伸出一个问题,MyISAM和InnoDB的区别
MyISAM和InnoDB的区别
1 存储结构(主索引/辅助索引)
- InnoDB的数据文件本身就是主索引文件。而MyISAM的主索引和数据是分开的。
- InnoDB的辅助索引data域存储相应记录主键的值而不是地址。而MyISAM的辅助索引和主索引没有多大区别。
- innoDB是聚簇索引,数据挂在主键索引之下。
2 锁
- MyISAM支持表级锁
- InnoDB支持表、行级锁(默认)
3 事务
- MyISAM没有事务支持和MVCC
- InnoDB支持事务和MVCC
4 外键
- MyISAM不支持,InnoDB支持
5 数据存储形式
Innodb存储文件有frm、ibd,而Myisam是frm、MYD、MYI
- Innodb:frm是表定义文件,ibd是数据文件。
- Myisam:frm是表定义文件,myd是数据文件,myi是索引文件。
持此之外还会延伸一个问题就是B树和B+树的区别
B树和B+树的区别
区别有以下两点:
1 B+树中只有叶子节点会带有指向记录的指针,而B树则所有节点都带有,在内部节点出现的索引项不会再出现在叶子节点中。
2 B+树中所有叶子节点都是通过指针连接在一起,而B树不会。
B+树的优点:
1 非叶子节点不会带上指针,这样,一个块中可以容纳更多的索引项,一是可以降低树的高度。二是一个内部节点可以定位更多的叶子节点。
2 叶子节点之间通过指针来连接,范围扫描将十分简单,而对于B树来说,则需要在叶子节点和内部节点不停的往返移动。
请你简单介绍以下TCP的三次握手和四次挥手
首先要讲解一下TCP报文格式
通过图片可以看出,TCP的包头字段存在三个重要的标识ACK,SYN,FIN
- ACK: 表示验证字段
- SYN:位数置1,表示建立TCP连接
- FIN:位数置1,表示断开TCP连接
三次握手
三次握手过程说明:
1 由客户端发送建立TCP连接的请求报文,其中报文中包含seq序列号,是由发送端随机生成的,并且将报文中的SYN字段置为1,表示需要建立TCP连接。(SYN=1,seq=J,J为随机生成数值)
2 由服务端回复客户端发送的TCP连接请求报文,其中包含seq序列号,是由回复端随机生成的,并且将SYN置为1,ACK置为1,而且会产生ack字段,ack字段数值是在客户端发送过来的序列号seq的基础上加1进行回复,以便客户端收到信息时,知晓自己的TCP建立请求已得到验证。(SYN=1,ACK=1,ack=J+1,seq=K,K为随机生成数值)这里的ack加1可以理解为是确认和谁建立连接。
3 客户端收到服务端发送的TCP建立验证请求后,会使自己的序列号加1表示,并且再次回复ack验证请求,在服务端发过来的seq上加1进行回复。(SYN=1,ACK=1,seq=J+1,ack=K+1)
四次挥手
四次挥手过程说明:
1、客户端发送断开TCP连接请求的报文,其中报文中包含seq序列号,是由发送端随机生成的,并且还将报文中的FIN字段置为1,表示需要断开TCP连接。(FIN=1,seq=M,M由客户端随机生成)
2、服务端会回复客户端发送的TCP断开请求报文,其包含seq序列号,是由回复端随机生成的,而且会产生ack字段,ack字段数值是在客户端发过来的seq序列号基础上加1进行回复,以便客户端收到信息时,知晓自己的TCP断开请求已经得到验证。(FIN=1,ack=M+1,seq=K,K由服务端随机生成)
3、服务端在回复完客户端的TCP断开请求后,不会马上进行TCP连接的断开,服务端会先确保断开前,所有传输到A的数据是否已经传输完毕,一旦确认传输数据完毕,就会将回复报文的FIN字段置1,并且产生随机seq序列号。(FIN=1,ack=M+1,seq=K,K由服务端随机生成)
4、客户端收到服务端的TCP断开请求后,会回复服务端的断开请求,包含随机生成的seq字段和ack字段,ack字段会在服务端的TCP断开请求的seq基础上加1,从而完成服务端请求的验证回复。(FIN=1,ack=K+1,seq=h,h为客户端随机生成)
至此TCP断开的4次挥手过程完毕
11种状态
1、一开始,建立连接之前服务器和客户端的状态都为CLOSED;
2、服务器创建socket后开始监听,变为LISTEN状态;
3、客户端请求建立连接,向服务器发送SYN报文,客户端的状态变味SYN_SENT;
4、服务器收到客户端的报文后向客户端发送ACK和SYN报文,此时服务器的状态变为SYN_RCVD;
5、然后,客户端收到ACK、SYN,就向服务器发送ACK,客户端状态变为ESTABLISHED;
6、服务器端收到客户端的ACK后变为ESTABLISHED。此时3次握手完成,连接建立!
由于TCP连接是全双工的,断开连接会比建立连接麻烦一点点。
1、客户端先向服务器发送FIN报文,请求断开连接,其状态变为FIN_WAIT1;
2、服务器收到FIN后向客户端发送ACK,服务器的状态围边CLOSE_WAIT;
3、客户端收到ACK后就进入FIN_WAIT2状态,此时连接已经断开了一半了。如果服务器还有数据要发送给客户端,就会继续发送;
4、直到发完数据,就会发送FIN报文,此时服务器进入LAST_ACK状态;
5、客户端收到服务器的FIN后,马上发送ACK给服务器,此时客户端进入TIME_WAIT状态;
6、再过了2MSL长的时间后进入CLOSED状态。服务器收到客户端的ACK就进入CLOSED状态。
至此,还有一个状态没有出来:CLOSING状态。
CLOSING状态表示:
客户端发送了FIN,但是没有收到服务器的ACK,却收到了服务器的FIN,这种情况发生在服务器发送的ACK丢包的时候,因为网络传输有时会有意外。
状态
LISTEN:等待从任何远端TCP 和端口的连接请求。
SYN_SENT:发送完一个连接请求后等待一个匹配的连接请求。
SYN_RECEIVED:发送连接请求并且接收到匹配的连接请求以后等待连接请求确认。
ESTABLISHED:表示一个打开的连接,接收到的数据可以被投递给用户。连接的数据传输阶段的正常状态。
FIN_WAIT_1:等待远端TCP 的连接终止请求,或者等待之前发送的连接终止请求的确认。
FIN_WAIT_2:等待远端TCP 的连接终止请求。
CLOSE_WAIT:等待本地用户的连接终止请求。
CLOSING:等待远端TCP 的连接终止请求确认。
LAST_ACK:等待先前发送给远端TCP 的连接终止请求的确认(包括它字节的连接终止请求的确认)
TIME_WAIT:等待足够的时间过去以确保远端TCP 接收到它的连接终止请求的确认。
TIME_WAIT 两个存在的理由:
1.可靠的实现tcp全双工连接的终止;
2.允许老的重复分节在网络中消逝。
CLOSED:不在连接状态(这是为方便描述假想的状态,实际不存在)