美团一面究竟有多难

电话面。跟前两面风格完全不一样!

  1. 先问我学过什么科目?

    我说计算机网络、操作系统、编译原理、数据结构、计算机组成原理、数据库等等;

    对什么科目感兴趣?

    我说计算机网络吧

    为什么喜欢这门课?

    我说因为上课听得懂,这门课的体系也比较清晰,分层来学,循序渐进,分数考得高,有成就感所以就喜欢了。


  2. 这门课有哪些让你记忆深刻的地方?


我说 tcp、ip吧,tcp 比较记忆深刻因为他很重要,出现的地方比较多,ip的话应该我们现实生活中也总是提起,所以记忆比较深刻一些。

3 .那我们现实中说到的 ip 和 你这里的 ip 有什么区别?

我说一个是 ip 协议,主要功能是定义IP地址格式,数据包的格式,分组转发规则,而我们现实中的 ip,是指的 ip 地址,这是主机在网络中的标识,一般我们接触的都是 IPv4,即 32 位的地址。

******4.那你讲讲 IPV4 有什么吧 「我自己加的问题」******

IPv4 分为网络号和主机号,网络号就是主机或者路由器所连接到的网络的标识,主机号就是主机或者路由器在这个网络内的标识。

既然谈到了路由器,那路由器有 ip 地址吗,路由器又有什么功能呢?

路由器肯定是有 ip 地址的,并且路由器总是有两个或两个以上的 ip 地址,路由器的每一个端口都有一个不同网络号的 ip 地址,因为路由器最主要的功能就是分组转发路由,通过路由表对报文进行相应的转发。

5. 那网关又是什么?和路由器有什么关系呢?

这个真的难…平时还真不会去思考这些问题…

在这里插入图片描述
在这里插入图片描述

如上图所示,路由器其实就是实现了网关的功能,网关是一个逻辑概念,指的是网络的出口和入口「网络边界」,而路由器则是一个物理概念,实现了网关的功能,是不同网关的沟通桥梁和物理基础。

6. 你说的 ip 协议是什么?属于哪一层?

我们通常使用的协议是 IPv4 协议,属于网络层。

介绍一下 IPv4 协议有哪些内容,然后说说网络层的一些其他协议吧?

首部固定20字节,包括版本,首部长度,源地址,目的地址等等。

网络层的其他协议包括 ARP「地址解析协议,用于IP地址和MAC地址的映射」、NAT「网络地址转换,对外隐藏内部的 ip」、ICMP「网络报文控制协议,允许主机和路由器报告差错和异常情况」、CIDR「子网划分协议,无分类域间路由选择,没有子网概念,但是有用子网掩码」

还要 DHCP,不过这个是应用层协议,基于 UDP,用于给主机动态分配 IP 地址,我们的笔记本突然接入 wifi 获得的 IP 就是 DHCP 协议获取的。

第一段落告终,因为我实在是听不清对面面试官说话,声音太低了,并且由于他使用的公司的 vpn,压根听不清…我所有的注意力基本上都集中在听他说话上了…根本没心思思考问题…莫名的紧张…

然后他换了电话打过来,终于听得清楚了,也终于不用尽全力听他讲话了,于是就不紧张了,然后我们就继续聊了下去。

***7.除了计算机网络,还对哪门课程比较有印象?***

数据库吧,自己因为做项目也一直有用。

***8.那你平时用的是什么数据库?***

Mysql、mongodb

9 这两个数据库有什么区别

一个是关系型数据库,一个是非关系型数据库。

那什么是关系型数据库,什么是非关系型数据库?为什么要分成这两种数据库呢?各自的优势和使用场景在哪呢?

关系型数据库指采用了关系模型来组织数据的数据库,关系模型可以简单的理解为一个二维表,所以里面的字段名称和字段类型都是在建表的时候就确定好了的;

非关系型数据库则是结构不固定,集合内数据字段可以不一样,数据比较松散,一般以键值对的形式存储,比如一般都是json数据直接存储。

适合使用SQL开发的项目:

    可以预先定义逻辑相关的离散数据的需求
    数据一致性是必要的{acid}
    具有良好的开发者经验和技术支持的标准的成熟技术

适合使用NoSQL开发的项目:

    不相关,不确定和逐步发展的数据需求
    更简单或者更宽松的能够快速开始编程的项目
    速度和可扩展性至关重要的

非关系型数据库的优势:

    性能 NOSQL是基于键值对的,可以想象成表中的主键和值的对应关系,而且不需要经过SQL层的解析,所以性能非常高。

    可扩展性 同样也是因为基于键值对,数据之间没有耦合性,所以非常容易水平扩展。

关系型数据库的优势:

    复杂查询 可以用SQL语句方便的在一个表以及多个表之间做非常复杂的数据查询。
    事务支持 使得对于安全性能很高的数据访问要求得以实现。

对于这两类数据库,对方的优势就是自己的弱势,反之亦然。

但是近年来这两种数据库都在向着另外一个方向进化。例如:NOSQL数据库慢慢开始具备SQL数据库的一些复杂查询功能的雏形,比如Couchbase的index以及MONGO的复杂查询。对于事务的支持也可以用一些系统级的原子操作来实现例如乐观锁之类的方法来曲线救国。SQL数据库也开始慢慢进化,比如HandlerSocker技术的实现,可以在MYSQL上实现对于SQL层的穿透,用NOSQL的方式访问数据库,性能可以上可以达到甚至超越NOSQL数据库。可扩展性上例如Percona Server,可以实现无中心化的集群。

虽然这两极都因为各自的弱势而开始进化出另一极的一些特性,但是这些特性的增加也会消弱其本来具备的优势,比如Couchbase上的index的增加会逐步降低数据库的读写性能。所以怎样构建系统的短期和长期存储策略,用好他们各自的强项是架构师需要好好考虑的重要问题。

   引用【 作者:陈鼎星 链接:https://www.zhihu.com/question/24225007/answer/81501685来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处】。

***10.那你讲讲 mysql 中你印象深刻的地方吧***

    第一个,对 mysql 支持的 RR 隔离级别非常的印象深刻,竟然可以做到修改了但不去读这种隔离级别;

    还有就是 Mysql 的高可用机制;「必须疯狂转入自己熟悉的地方啊」

    Mysql 的 Write Ahead Logging 也是一个很大的特点,有去使用 redolog、undolog、binlog;

    Mysql 的锁也是一个很大的特点,里面有丰富的锁,跟 juc 下的锁有的一拼,甚至更丰富;

    还有就是 Mysql 中的索引,能提高检索速度。

『机会来了就要把握住,这种问题是最适合展现自己的学习深度』

***11。那你分别讲讲这五个吧***

其实面试官并没有让我讲这五个,只是让我讲讲 rr 级别如何实现的,但是为了复习,我还是把这五个再串一遍吧。

*先讲第一个,mysql 如何实现的 RR 隔离级别*

主要是采用了事务的一致性视图,和当前行的一个 row_tranc_id,根据一致性视图里面的低水位和高水位和 row_tranc_id 进行比较,判断是否需要用 undolog 拿到上一个值,undolog 在这里就是实现 mvcc 的基础。这里有一个值得注意的地方,就是如果 select 是不加悲观锁的去读,没有问题,是rr级别的读取,但是如果 select 显式的加锁,比如说加了行锁中的读锁「在语句最后加 in shared mode」或者写锁「for update」,这样跟 update 一样强制去进行一个加锁,导致只能去当前读,此时 mvcc 是失效的。

*再讲第二个,mysql 的高可用机制是如何实现的?*

这里我在腾讯面试部分也有提到,但是腾讯那部分主要侧重讲了主从一致是如何实现的,而高可用则是建立在主从一致的基础上的。

先上一个自己画的图:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200718000112276.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0phc29uX0hvbmV5Mg==,size_16,color_FFFFFF,t_70)



高可用机制[3]

mysql 的高可用的实现,基础就是能够做到主备切换,而主备切换的前提是要保证主从的一致性,这样才能切换,不然肯定会影响数据,但是要保证主从一致性,就会带来主从延迟的情况,具体的主从一致性的实现可以看我上面讲的,主从延迟可能会有图中那些原因,针对不可避免的主从延迟,主备切换有两种策略:

    可靠性优先策略。具体步骤是等延迟小于某个数时,例如 5 秒,将主库 A 改成只读状态,然后再看主从延迟「seconds_behind_master」,等其变为 0 后,将备库 B 改成可读写状态,然后把业务切换到备库 B 上,这个策略的好处就是能保证主从的完全一致性,但是会有少量时间导致系统处于不可写的状态,不过影响不大,这也是最常用的策略;
    可用性优先策略。不等主备数据同步,直接把连接切到备库B,并且让备库B可以读写,那么系统几乎就没有不可用时间了。好处就是没有不可用时间,但是容易导致数据逻辑出现问题。

***![再讲第三个,Mysql 的 Write Ahead Logging](https://img-blog.csdnimg.cn/2020071800014190.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0phc29uX0hvbmV5Mg==,size_16,color_FFFFFF,t_70)

Mysql 中常见的三个日志文件分别是 undolog、redolog以及binlog,redolog 主要是负责 crash-safe,也就是崩溃恢复的工作,binlog主要是做一个归档的作用,redolog和binlog是两阶段提交的,这也是常用的分布式的手段吧,大家都okay了才commit,redolog是可擦除的,存储的是物理日志,但是binlog是顺序写,存储的是逻辑日志,并且 redolog 是 Innodb 独有的,binlog则是 server端有的。undlog 主要是负责 mvcc 和回滚,在数据修改的时候,不仅记录了redo,还记录了相对应的undo,如果因为某些原因导致事务失败或回滚了,可以借助该undo进行回滚。undo log和redo log记录物理日志不一样,它是逻辑日志。可以认为当delete一条记录时,undo log中会记录一条对应的insert记录,反之亦然,当update一条记录时,它记录一条对应相反的update记录。

再讲第四个,Mysql 中的锁

Mysql 从锁的范围上讲分为全局锁、表级锁以及行锁。

全局锁称为 Flash Tables with Read Lock,主要用来全库逻辑备份,这个命令可以使整个库处于只读状态。**使用该命令之后,数据更新语句、数据定义语句和更新类事务的提交语句等操作都会被阻塞。**如果这个命令在主库操作的话,会导致业务停摆,如果再备库操作的话,会导致备库无法写从主库传来的binlog,造成主备延迟,所以我们很少使用它,一般都是使用mysql自带的 mysqldump 去进行全库逻辑备份,因为 mysqldump 有 mvcc 的支持,所以可以一边备份一边读写,但是这个必须要数据库引擎支持rr这个隔离级别,像 MyISAM 就不行。

表级锁又分为表锁和元数据锁MDL,其中表锁需要我们去显式加锁,例如 lock tables … read/write,如果一个线程对其显式加了表读锁,那么其他线程和该线程只能读该表,如果该线程加了表写锁,那么其他线程啥也干不了,所以这个锁表的粒度还是太大,一般不会采用。

表级锁的另外一种是元数据锁MDL,这是系统默认加上的,对表进行 DML 是加读锁,对表进行 DDL 是加写锁,读写互斥,读共享,相当于 ReadWriteLock,但是这里没有写降级的过程。

行锁是我们最经常用的了,也分为读锁和写锁,这里的读单指 select,这里的写指的是 update、delete、insert等等,当然我们也可以对 select 进行显式的加锁,此时 select 就从乐观读锁「跟 StampedLock 类似,一个是通过 version 判断数据有没有变化,一个是通过 stamp 判断」变成了悲观读锁或者写锁了,此时mvcc是失效的,是跟 update等语句一样强制去当前读的。

再讲第五个,Mysql 的索引?

索引有很多,常见的就是聚集索引和非聚集索引,聚集索引就是元素的逻辑位置和物理位置保持一致,也称为主键索引,是B+树,因为支持范围查询,并且索引节点只有指针和索引,这样单个节点就能容纳更多的指针域,从而使得树的高度下降。

非聚集索引要注意减少回表的次数,常用的方法就是覆盖索引、使用最左前缀原则尽量减少索引的建立,同时注意可以使用索引下推来减少回表的次数。

好勒,数据库差不多了,***最后讲一讲范式吧***

mysql中常用的范式就是三大范式

第一范式:确保每列的原子性,比如说地址这一属性,有的业务可能对城市用的比较多,我们就就应该细分,这样在对用户使用城市进行分类的时候就非常方便,也提高了数据库的性能。

第二范式:确保表中的每列都和主键相关,去除部分依赖。最典型的场景就是多对多的场景,比如订单-商品表,因为订单中可能会有多种商品,所以要将订单编号和商品编号作为数据库表的联合主键,如果此时把商品信息也写在这个表中,就不符合第二范式了,这样会造成数据冗余,分表会更好。

第三范式:确保没有传递依赖,也就是每个非主属性都要依赖于主属性,例如订单表,和用户是一对多的关系,此时用户的id会是这个表的外键,如果在这里加上用户的名字,就违反了第三范式,也是会造成数据的冗余的。

参考: https://www.cnblogs.com/linjiqin/archive/2012/04/01/2428695.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值