后端面试大全

目录

Mysql

事务的隔离级别

MVCC

B+树

索引

聚簇索引

辅助索引

索引覆盖

InnoDB vs MyISAM

Redis

跳表

缓存穿透、缓存击穿、缓存雪崩

集群

哨兵模式

集群模式和哨兵模式的区别

网络

TCP三次握手

TCP四次挥手

Maximum Segment Lifetime 报文最大生存时间

TCP/IP 五层模型

HTTP

SSL

502、504

301、302


Mysql

事务的隔离级别

  • Read uncommitted(读未提交),可能出现脏读,也就是说事务B读取到了事务A未提交的数据
  • Read committed(读提交),可能出现不可重复读。事务A事先读取了数据,事务B紧接着更新了数据,并提交了事务,而事务A再次读取该数据时,数据已经发生了改变。
  • Repeatable read(可重复读取),可能会出现幻读
  • Serializable(可序化),不仅可以避免脏读、不可重复读,还避免了幻读

MVCC

  • 数据库隐式定义的DB_TRX_ID,DB_ROLL_PTR,DB_ROW_ID
  • insert undo log,只在事务回滚时需要,并且在事务提交后可以被立即丢弃,update undo log,不仅在事务回滚时需要,在快照读时也需要;所以不能随便删除,只有在快速读或事务回滚不涉及该日志时,对应的日志才会被purge线程统一清除
  • Read View就是事务进行快照读操作的时候生产的读视图(Read View),在该事务执行的快照读的那一刻,会生成数据库系统当前的一个快照,记录并维护系统当前活跃事务的ID(当每个事务开启时,都会被分配一个ID, 这个ID是递增的,所以最新的事务,ID值越大)
  • 参考:MVCC详解 - xuwc - 博客园

B+树

  • B树:二叉树,每个结点只存储一个关键字,等于则命中,小于走左结点,大于走右结点;
  • B-树:多路搜索树,非叶子结点存储指向关键字范围的子结点;所有关键字在整颗树中出现,且只出现一次,非叶子结点可以命中;

  • B+树:在B-树基础上,为叶子结点增加链表指针,所有关键字都在叶子结点中出现,非叶子结点作为叶子结点的索引;B+树总是到叶子结点才命中;

  • B*树:在B+树基础上,为非叶子结点也增加链表指针

索引

聚簇索引

聚簇索引是物理索引,数据表就是按顺序存储的,物理上是连续的。因为聚簇索引是按该列的排序存储的,因此一个表只能有一个聚簇索引。

  • 如果你为表定义了一个主键,MySQL将使用主键作为聚簇索引。
  • 如果你不为表指定一个主键,MySQL讲索第一个组成列都not null的唯一索引作为聚簇索引。
  • 如果InnoBD表没有主键且没有适合的唯一索引(没有构成该唯一索引的所有列都NOT NULL),MySQL将自动创建一个隐藏的名字为“GEN_CLUST_INDEX ”的聚簇索引。

因此每个InnoDB表都有且仅有一个聚簇索引。

推荐使用自增ID作为主键自增ID可以保证每次插入时B+索引是从右边扩展的,可以避免B+树和频繁合并和分裂(对比使用UUID)。如果使用字符串主键和随机主键,会使得数据随机插入,效率比较差。

辅助索引

所有不是聚簇索引的索引都叫非聚簇索引或者辅助索引。在InnDB存储引擎中,每个辅助索引的每条记录都包含主键,也包含非聚簇索引指定的列。MySQL使用这个主键值来检索局促索引。因此应该尽可能将主键缩短,否则辅助索引占用空间会更大。一般来说用自增的整数型列作为主键列。

索引覆盖

将被查询的字段,建立到联合索引里去,防止回表。

InnoDB vs MyISAM

  • InnoDB是聚集索引,使用B+Tree作为索引结构,数据文件是和(主键)索引绑在一起的
  • MyISAM是非聚集索引,也是使用B+Tree作为索引结构,索引和数据文件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的。
  • InnoDB支持表、行(默认)级锁,而MyISAM支持表级锁
  • Innodb存储文件有frm、ibd,而Myisam是frm、MYD、MYI。Innodb:frm是表定义文件,ibd是数据文件。Myisam:frm是表定义文件,myd是数据文件,myi是索引文件

Redis

跳表

 对于一个单链表来讲,查找效率很低,时间复杂度很高,是 O(n)。如果我们想要提高其查找效率,可以考虑在链表上建索引的方式。每两个结点提取一个结点到上一级,我们把抽出来的那一级叫作索引。当有大量的数据时,我们可以增加多级索引,其查找效率可以得到明显提升。

Redis使用跳跃表作为有序集合键的底层实现之一,如果一个有序集合包含的元素数量比较多,又或者有序集合中元素的成员是比较长的字符串时, Redis就会使用跳跃表来作为有序集合健的底层实现。

参考:Redis数据结构——跳跃表 - Mr于 - 博客园

缓存穿透、缓存击穿、缓存雪崩

  • key对应的数据在数据源并不存在,每次针对此key的请求从缓存获取不到,请求都会到数据源,从而可能压垮数据源。最常见的则是采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被 这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。另外也有一个更为简单粗暴的方法(我们采用的就是这种),如果一个查询返回的数据为空(不管是数据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。
  • key对应的数据存在,但在redis中过期,此时若有大量并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮。业界比较常用的做法,是使用mutex。简单地来说,就是在缓存失效的时候(判断拿出来的值为空),不是立即去load db,而是先使用缓存工具的某些带成功操作返回值的操作(比如Redis的SETNX或者Memcache的ADD)去set一个mutex key,当操作返回成功时,再进行load db的操作并回设缓存;否则,就重试整个get缓存的方法。
  • 当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,也会给后端系统(比如DB)带来很大压力。大多数系统设计者考虑用加锁或者队列的方式保证来保证不会有大量的线程对数据库一次性进行读写,从而避免失效时大量的并发请求落到底层存储系统上。还有一个简单方案就时讲缓存失效时间分散开,比如我们可以在原有的失效时间基础上增加一个随机值,比如1-5分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。

集群

  • 添加主节点

./src/redis-cli --cluster add-node 172.26.237.83:7002 172.26.237.83:7000 -a 0123456789

  • 分配哈希槽
./src/redis-cli --cluster reshard  ip:port -a 密码
  • 添加从节点

./src/redis-cli --cluster add-node --cluster-slave --cluster-master-id db10a9d5c1662d9e3cee21c5776f2e9709f76619 127.0.0.1:7008 127.0.0.1:7007
  • 主从复制

全量复制,部分复制,指令传播

哨兵模式

  • 通过发送命令,让Redis服务器返回监控其运行状态,包括主服务器和从服务器。

  • 当哨兵监测到master宕机,会自动将slave切换成master,然后通过发布订阅模式通知其他的从服务器,修改配置文件,让它们切换主机。

然而一个哨兵进程对Redis服务器进行监控,可能会出现问题,为此,我们可以使用多个哨兵进行监控。各个哨兵之间还会进行监控,这样就形成了多哨兵模式。

用文字描述一下故障切换(failover)的过程。假设主服务器宕机,哨兵1先检测到这个结果,系统并不会马上进行failover过程,仅仅是哨兵1主观的认为主服务器不可用,这个现象成为主观下线。当后面的哨兵也检测到主服务器不可用,并且数量达到一定值时,那么哨兵之间就会进行一次投票,投票的结果由一个哨兵发起,进行failover操作。切换成功后,就会通过发布订阅模式,让各个哨兵把自己监控的从服务器实现切换主机,这个过程称为客观下线。这样对于客户端而言,一切都是透明的。

参考:Redis哨兵(Sentinel)模式 - 简书

集群模式和哨兵模式的区别

  • 哨兵模式监控权交给了哨兵系统,集群模式中是工作节点自己做监控
  • 哨兵模式发起选举是选举一个leader哨兵节点来处理故障转移,集群模式是在从节点中选举一个新的主节点,来处理故障的转移

网络

TCP三次握手

  • 序列号seq:占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号,第一个字节的编号由本地随机产生;给字节编上序号后,就给每一个报文段指派一个序号;序列号seq就是这个报文段中的第一个字节的数据编号。

  • 确认号ack:占4个字节,期待收到对方下一个报文段的第一个数据字节的序号;序列号表示报文段携带数据的第一个字节的编号;而确认号指的是期望接收到下一个字节的编号;因此当前报文段最后一个字节的编号+1即为确认号。

  • 确认ACK:占1位,仅当ACK=1时,确认号字段才有效。ACK=0时,确认号无效

  • 同步SYN:连接建立时用于同步序号。当SYN=1,ACK=0时表示:这是一个连接请求报文段。若同意连接,则在响应报文段中使得SYN=1,ACK=1。因此,SYN=1表示这是一个连接请求,或连接接受报文。SYN这个标志位只有在TCP建产连接时才会被置1,握手完成后SYN标志位被置0。

  • 终止FIN:用来释放一个连接。FIN=1表示:此报文段的发送方的数据已经发送完毕,并要求释放运输连接

  • ACK、SYN和FIN这些大写的单词表示标志位,其值要么是1,要么是0;ack、seq小写的单词表示序号。

TCP四次挥手

参考:TCP的三次握手与四次挥手理解及面试题(很全面) - 李卓航 - 博客园 

Maximum Segment Lifetime 报文最大生存时间

MSL是Maximum Segment Lifetime英文的缩写,中文可以译为“报文最大生存时间”,他是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。因为tcp报文(segment)是ip数据报(datagram)的数据部分,具体称谓请参见《数据在网络各层中的称呼》一文,而ip头中有一个TTL域,TTL是time to live的缩写,中文可以译为“生存时间”,这个生存时间是由源主机设置初始值但不是存的具体时间,而是存储了一个ip数据报可以经过的最大路由数,每经过一个处理他的路由器此值就减1,当此值为0则数据报将被丢弃,同时发送ICMP报文通知源主机。RFC 793中规定MSL为2分钟,实际应用中常用的是30秒,1分钟和2分钟等。

    TTLMSL是有关系的但不是简单的相等的关系,MSL要大于等于TTL

参考:什么是2MSL_xiaofei0859的专栏-CSDN博客_2msl

TCP/IP 五层模型

  • 物理层

  • 数据链路层

  • 网络层:ICMP IGMP IP(IPV4 IPV6)

  • 传输层:TCP、UDP

  • 应用层:HTTP FTP TFTP SMTP SNMP DNS TELNET HTTPS POP3 DHCP

HTTP

SSL

  1. 客户端向服务器发送一个开始信息“Hello”以便开始一个新的会话连接;
  2. 服务器根据客户的信息确定是否需要生成新的主密钥,如需要则服务器在响应客户的“Hello”信息时将包含生成主密钥所需的信息;
  3. 客户根据收到的服务器响应信息,产生一个主密钥,并用服务器的公开密钥加密后传给服务器;
  4. 服务器回复该主密钥,并返回给客户一个用主密钥认证的信息,以此让客户认证服务器。

TLS的基本工作方式是,客户端使用非对称加密与服务器进行通信,实现身份验证并协商对称加密使用的密钥,然后对称加密算法采用协商密钥对信息以及信息摘要进行加密通信,不同的节点之间采用的对称密钥不同,从而可以保证信息只能通信双方获取。

502、504

  • 502 Bad Gateway和php-fpm.conf的设置有关,php-fpm.conf有两个至关重要的参数,一个是”max_children”,另一个是”request_terminate_timeout” 
  • 504 Gateway Time-out则是与nginx.conf的设置有关,fastcgi_connect_timeout 600;fastcgi_send_timeout 600;fastcgi_read_timeout 600;

301、302

301 代表永久性转移(Permanently Moved),302 代表暂时性转移(Temporarily Moved )。搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址;302表示旧地址A的资源还在(仍然可以访问),这个重定向只是临时地从旧地址A跳转到地址B,搜索引擎会抓取新的内容而保存旧的网址。

需要重定向的场景:

  • 网站调整(如改变网页目录结构);
  • 网页被移到一个新地址;
  • 网页扩展名改变(如应用需要把.php改成.Html或.shtml)。

使用301跳转的场景:

  • 域名到期不想续费(或者发现了更适合网站的域名),想换个域名
  • 在搜索引擎的搜索结果中出现了不带www的域名,而带www的域名却没有收录,这个时候可以用301重定向来告诉搜索引擎我们目标的域名是哪一个。

使用302跳转的场景:

  • 尽量使用301跳转,防止网址劫持。

从网站A(网站比较烂)上做了一个302跳转到网站B(搜索排名很靠前),这时候有时搜索引擎会使用网站B的内容,但却收录了网站A的地址,这样在不知不觉间,网站B在为网站A作贡献,网站A的排名就靠前了。

参考:http状态码301和302详解及区别_幽雨雨幽-CSDN博客_301 302

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值