蚂蚁金服一面:十道经典面试题解析,2024年最新docker面试题及调优

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
img

正文

  • 线程终止规则:线程中所有的操作都先行发生于线程的终止检测,我们可以通过Thread.join()方法结束、Thread.isAlive()的返回值手段检测到线程已经终止执行

  • 线程中断规则:对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生

  • 对象终结规则:一个对象的初始化完成先行发生于他的finalize()方法的开始

  • 传递性:如果操作A先行发生于操作B,而操作B又先行发生于操作C,则可以得出操作A先行发生于操作C

实际上volatile保证可见性和禁止指令重排都跟内存屏障有关。我们来看一段volatile使用的demo代码

public class Singleton {

private volatile static Singleton instance;

private Singleton (){}

public static Singleton getInstance() {

if (instance == null) {

synchronized (Singleton.class) {

if (instance == null) {

instance = new Singleton();

}

}

}

return instance;

}

}

复制代码

编译后,对比有volatile关键字和没有volatile关键字时所生成的汇编代码,发现有volatile关键字修饰时,会多出一个lock addl $0x0,(%esp),即多出一个lock前缀指令,lock指令相当于一个「内存屏障」

lock指令相当于一个内存屏障,它保证以下这几点:

  • 1.重排序时不能把后面的指令重排序到内存屏障之前的位置

  • 2.将本处理器的缓存写入内存

  • 3.如果是写入动作,会导致其他处理器中对应的缓存无效。

第2点和第3点就是保证volatile保证可见性的体现嘛,第1点就是禁止指令重排列的体现。内存屏障又是什么呢?

内存屏障四大分类:(Load 代表读取指令,Store代表写入指令)

| 内存屏障类型 | 抽象场景 | 描述 |

| — | — | — |

| LoadLoad屏障 | Load1; LoadLoad; Load2 | 在Load2要读取的数据被访问前,保证Load1要读取的数据被读取完毕。 |

| StoreStore屏障 | Store1; StoreStore; Store2 | 在Store2写入执行前,保证Store1的写入操作对其它处理器可见 |

| LoadStore屏障 | Load1; LoadStore; Store2 | 在Store2被写入前,保证Load1要读取的数据被读取完毕。 |

| StoreLoad屏障 | Store1; StoreLoad; Load2 | 在Load2读取操作执行前,保证Store1的写入对所有处理器可见。 |

为了实现volatile的内存语义,Java内存模型采取以下的保守策略

  • 在每个volatile写操作的前面插入一个StoreStore屏障。

  • 在每个volatile写操作的后面插入一个StoreLoad屏障。

  • 在每个volatile读操作的后面插入一个LoadLoad屏障。

  • 在每个volatile读操作的后面插入一个LoadStore屏障。

有些小伙伴,可能对这个还是有点疑惑,内存屏障这玩意太抽象了。我们照着代码看下吧:

内存屏障保证前面的指令先执行,所以这就保证了禁止了指令重排啦,同时内存屏障保证缓存写入内存和其他处理器缓存失效,这也就保证了可见性,哈哈~

5. 讲一讲7层网络模型,tcp的为什么要三次握手


计算机网路体系结构有三层:OSI七层模型、TCP/IP四层模型、五层体系结构,如图:

七层模型,亦称OSI(Open System Interconnection),国际标准化组织(International Organization for Standardization)制定的一个用于计算机或通信系统间互联的标准体系。

  • 应用层:网络服务与最终用户的一个接口,常见的协议有:HTTP FTP SMTP SNMP DNS.

  • 表示层:数据的表示、安全、压缩。,确保一个系统的应用层所发送的信息可以被另一个系统的应用层读取。

  • 会话层:建立、管理、终止会话,对应主机进程,指本地主机与远程主机正在进行的会话.

  • 传输层:定义传输数据的协议端口号,以及流控和差错校验,协议有TCP UDP.

  • 网络层:进行逻辑地址寻址,实现不同网络之间的路径选择,协议有ICMP IGMP IP等.

  • 数据链路层:在物理层提供比特流服务的基础上,建立相邻结点之间的数据链路。

  • 物理层:建立、维护、断开物理连接。

6.说说线程池的工作原理


面试官如果要我们讲下线程池工作原理的话,大家讲下以下这个流程图就可以啦:

为了形象描述线程池执行,加深大家的理解,我打个比喻:

  • 核心线程比作公司正式员工

  • 非核心线程比作外包员工

  • 阻塞队列比作需求池

  • 提交任务比作提需求

  • 当产品提个需求,正式员工(核心线程)先接需求(执行任务)

  • 如果正式员工都有需求在做,即核心线程数已满),产品就把需求先放需求池(阻塞队列)。

  • 如果需求池(阻塞队列)也满了,但是这时候产品继续提需求,怎么办呢?那就请外包(非核心线程)来做。

  • 如果所有员工(最大线程数也满了)都有需求在做了,那就执行拒绝策略。

  • 如果外包员工把需求做完了,它经过一段(keepAliveTime)空闲时间,就离开公司了。

7.你们数据库的高可用是怎么实现的?


高可用,即High Availability,是分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计减少系统不能提供服务的时间。单机部署谈不上高可用,因为单点故障问题。高可用都是多个节点的,我们在考虑MySQL数据库的高可用的架构时,需要考虑这几个方面:

  • 如果数据库节点宕机,需要尽快回复,保证业务不受宕机影响。

  • 从数据库节点的数据,尽可能跟主节点数据实时保持一致,至少保证最终一致性。

  • 数据库节点切换时,数据不能缺失。

7.1 主从或主主半同步复制

用双节点数据库,搭建单向或者双向的半同步复制。架构如下:

通常会和proxy、keepalived等第三方软件同时使用,即可以用来监控数据库的健康,又可以执行一系列管理命令。如果主库发生故障,切换到备库后仍然可以继续使用数据库。

这种方案优点是架构、部署比较简单,主机宕机直接切换即可。缺点是完全依赖于半同步复制,半同步复制退化为异步复制,无法保证数据一致性;另外,还需要额外考虑haproxy、keepalived的高可用机制。

7.2 半同步复制优化

半同步复制机制是可靠的,可以保证数据一致性的。但是如果网络发生波动,半同步复制发生超时会切换为异步复制,异复制是无法保证数据的一致性的。因此,可以在半同复制的基础上优化一下,尽可能保证半同复制。如双通道复制方案

  • 优点:这种方案架构、部署也比较简单,主机宕机也是直接切换即可。比方案1的半同步复制,更能保证数据的一致性。

  • 缺点:需要修改内核源码或者使用mysql通信协议,没有从根本上解决数据一致性问题。

7.3 高可用架构优化

保证高可用,可以把主从双节点数据库扩展为数据库集群。Zookeeper可以作为集群管理,它使用分布式算法保证集群数据的一致性,可以较好的避免网络分区现象的产生。

  • 优点:保证了整个系统的高可用性,扩展性也较好,可以扩展为大规模集群。

  • 缺点:数据一致性仍然依赖于原生的mysql半同步复制;引入Zookeeper使系统逻辑更复杂。

7.4 共享存储

共享存储实现了数据库服务器和存储设备的解耦,不同数据库之间的数据同步不再依赖于MySQL的原生复制功能,而是通过磁盘数据同步的手段,来保证数据的一致性。

DRBD磁盘复制

DRBD是一个用软件实现的、无共享的、服务器之间镜像块设备内容的存储复制解决方案。主要用于对服务器之间的磁盘、分区、逻辑卷等进行数据镜像,当用户将数据写入本地磁盘时,还会将数据发送到网络中另一台主机的磁盘上,这样的本地主机(主节点)与远程主机(备节点)的数据就可以保证实时同步。常用架构如下:

当本地主机出现问题,远程主机上还保留着一份相同的数据,即可以继续使用,保证了数据的安全。

  • 优点:部署简单,价格合适,保证数据的强一致性

  • 缺点:对IO性能影响较大,从库不提供读操作

7.5 分布式协议

分布式协议可以很好解决数据一致性问题。常见的部署方案就是MySQL cluster,它是官方集群的部署方案,通过使用NDB存储引擎实时备份冗余数据,实现数据库的高可用性和数据一致性。如下:

  • 优点:不依赖于第三方软件,可以实现数据的强一致性;

  • 缺点:配置较复杂;需要使用NDB储存引擎;至少三节点;

8. 读写分离的场景下,怎么保证从数据库读到最新的数据?


数据库读写分离,主要解决高并发时,提高系统的吞吐量。来看下读写分离数据库模型:

  • 写请求是直接写主库,然后同步数据到从库

  • 读请求一般直接读从库,除飞强制读主库

在高并发场景或者网络不佳的场景,如果存在较大的主从同步数据延迟,这时候读请求去读从库,就会读到旧数据。这时候最简单暴力的方法,就是强制读主库。实际上可以使用缓存标记法

  • A发起写请求,更新主库数据,并在缓存中设置一个标记,表示数据已更新,标记格式为:userId+业务Id。

  • 设置此标记,设置过期时间(估值为主库和从库同步延迟的时间)

  • B发起读请求,先判断此请求,在缓存中有没有更新标记。

  • 如果存在标记,走主库;如果没有,请求走从库。

这个方案,解决了数据不一致问题,但是每次请求都要先跟缓存打交道,会影响系统吞吐。

9. 如何保证MySQL数据不丢?


MySQL这种关系型数据库,是日志先行策略(Write-Ahead Logging),只要binlog和redo log日志能保证持久化到磁盘,我们就能确保MySQL异常重启后,数据不丢失。

binlog日志

binlog,又称为二进制日志,它会记录数据库执行更改的所有操作,但是不包括查询select等操作。一般用于恢复、复制等功能。它的格式有三种:statement、mixed和row

  • statement:每一条会修改数据的sql都会记录到binlog中,不建议使用。

  • row:基于行的变更情况记录,会记录行更改前后的内容,推荐使用

  • mixed:混合statement和row两个模式,不建议使用。

binlog 的写入机制是怎样的呢?

事务执行过程中,先把日志写到 binlog cache,事务提交的时候,再把binlog cache写到binlog文件中

系统为每个客户端线程分配一个binlog cache,其大小值控制参数是binlog_cache_size。如果binlog cache的值超过阀值,就会临时持久化到磁盘。当事务提交的时候,再将 binlog cache中完整的事务持久化到磁盘中,并且清空binlog cache。

binlog写文件

binlog写文件分write和fsync两个过程:

  • write:指把日志写到文件系统的page cache,并没有把数据持久化到磁盘,因此速度较快。

  • fsync,实际的写盘操作,即把数据持久化到磁盘。

write和fsync的写入时机,是由变量sync_binlog控制的:

如果IO出现性能瓶颈,可以将sync_binlog设置成一个较大的值。比如设置为(100~1000)。但是,会存在数据丢失的风险,当主机异常重启时,会丢失N个最近提交的事务binlog

redo log日志

redo log,又称为重做日志文件,只记录事务对数据页做了哪些修改,它记录的是数据修改之后的值。redo 有三种状态

  • 物理上是在MySQL进程内存中,存在redo log buffer中,

  • 物理上在文件系统的page cache里,写到磁盘 (write),但是还没有持久化(fsync)。

  • 存在hard disk,已经持久化到磁盘。

日志写到redo log buffer是很快的;wirte到page cache也很快,但是持久化到磁盘的速度就慢多了。

为了控制redo log的写入策略,Innodb根据innodb_flush_log_at_trx_commit参数不同的取值采用不同的策略,它有三种不同的取值:

    1. 设置为0时,表示每次事务提交时都只是把redo log留在redo log buffer 中 ;
    1. 设置为1时,表示每次事务提交时都将 redo log 直接持久化到磁盘;
    1. 设置为2时,表示每次事务提交时都只是把redo log 写到page cache。

三种模式下,0的性能最好,但是不安全,MySQL进程一旦崩溃会导致丢失一秒的数据。1的安全性最高,但是对性能影响最大,2的话主要由操作系统自行控制刷磁盘的时间,如果仅仅是MySQL宕机,对数据不会产生影响,如果是主机异常宕机了,同样会丢失数据。

10. 高并发下如何设计秒杀系统?


设计一个秒杀系统,需要考虑这些问题:

如何解决这些问题呢?

  • 页面静态化

  • 按钮至灰控制

  • 服务单一职责

  • 秒杀链接加盐

  • 限流

  • 分布式锁

  • MQ异步处理

  • 限流&降级&熔断

页面静态化

秒杀活动的页面,大多数内容都是固定不变的,如商品名称,商品图片等等,可以对活动页面做静态化处理,减少访问服务端的请求。秒杀用户会分布在全国各地,有的在上海,有的在深圳,地域相差很远,网速也各不相同。为了让用户最快访问到活动页面,可以使用CDN(Content Delivery Network,内容分发网络)。CDN可以让用户就近获取所需内容。

按钮至灰控制

秒杀活动开始前,按钮一般需要置灰的。只有时间到了,才能变得可以点击。这是防止,秒杀用户在时间快到的前几秒,疯狂请求服务器,然后秒杀时间点还没到,服务器就自己挂了。

服务单一职责

我们都知道微服务设计思想,也就是把各个功能模块拆分,功能那个类似的放一起,再用分布式的部署方式。

如用户登录相关的,就设计个用户服务,订单相关的就搞个订单服务,再到礼物相关的就搞个礼物服务等等。那么,秒杀相关的业务逻辑也可以放到一起,搞个秒杀服务,单独给它搞个秒杀数据库。

服务单一职责有个好处:如果秒杀没抗住高并发的压力,秒杀库崩了,服务挂了,也不会影响到系统的其他服务。

秒杀链接加盐

链接如果明文暴露的话,会有人获取到请求Url,提前秒杀了。因此,需要给秒杀链接加盐。可以把URL动态化,如通过MD5加密算法加密随机的字符串去做url。

限流

一般有两种方式限流:nginx限流和redis限流。

  • 为了防止某个用户请求过于频繁,我们可以对同一用户限流

  • 为了防止黄牛模拟几个用户请求,我们可以对某个IP进行限流

  • 为了防止有人使用代理,每次请求都更换IP请求,我们可以对接口进行限流

  • 为了防止瞬时过大的流量压垮系统,还可以使用阿里的Sentinel、Hystrix组件进行限流。

分布式锁

可以使用redis分布式锁解决超卖问题。

难道这样就够了吗?不,远远不够!

提前多熟悉阿里往年的面试题肯定是对面试有很大的帮助的,但是作为技术性职业,手里有实打实的技术才是你面对面试官最有用的利器,这是从内在散发出来的自信。

备战阿里时我花的最多的时间就是在学习技术上,占了我所有学习计划中的百分之70,这是一些我学习期间觉得还是很不错的一些学习笔记

我为什么要写这篇文章呢,其实我觉得学习是不能停下脚步的,在网络上和大家一起分享,一起讨论,不单单可以遇到更多一样的人,还可以扩大自己的眼界,学习到更多的技术,我还会在csdn、博客、掘金等网站上分享技术,这也是一种学习的方法。

今天就分享到这里了,谢谢大家的关注,以后会分享更多的干货给大家!

阿里一面就落马,恶补完这份“阿里面试宝典”后,上岸蚂蚁金服

阿里一面就落马,恶补完这份“阿里面试宝典”后,上岸蚂蚁金服

image.png

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
备战阿里时我花的最多的时间就是在学习技术上,占了我所有学习计划中的百分之70,这是一些我学习期间觉得还是很不错的一些学习笔记

我为什么要写这篇文章呢,其实我觉得学习是不能停下脚步的,在网络上和大家一起分享,一起讨论,不单单可以遇到更多一样的人,还可以扩大自己的眼界,学习到更多的技术,我还会在csdn、博客、掘金等网站上分享技术,这也是一种学习的方法。

今天就分享到这里了,谢谢大家的关注,以后会分享更多的干货给大家!

[外链图片转存中…(img-SWWZ1bKJ-1713156649791)]

[外链图片转存中…(img-2x6S90NW-1713156649791)]

[外链图片转存中…(img-X00HP1LZ-1713156649791)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-b3tw7R50-1713156649792)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 21
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值