阿里 P8 面试官:如何设计一个扛住千万级并发的架构?,java面试问题大全及答案大全最新

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

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

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

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

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

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

正文

如果你们公司现在的产品能够支持 10W 用户访问,你们老板突然和你说,融到钱了,会大量投放广告,预计在 1 个月后用户量会达到 1000W,如果这个任务交给你,你应该怎么做?

1000W 用户的问题分解

=============

如何支撑 1000W 用户其实是一个非常抽象的问题,对于技术开发来说,我们需要一个非常明确的对于执行关键业务上的性能指标数据,比如,高峰时段下对于事务的响应时间、并发用户数、QPS、成功率、以及基本指标要求等,这些都 必须要非常明确,只有这样才能够指导整个架构的改造和优化。所以,如果大家接到这样一个问题,首先需要去定位到问题的本质,也就是首先得知道一些可量化的数据指标。

  • 如果有过往的相似业务交易历史数据经验,你需要尽量参考,处理这些收集到的原始数据(日志),从而分析出高峰时段,以及该时段下的交易行为,交易规模等,得到你想要看清楚的需求细节

  • 另外一种情况,就是没有相关的数据指标作为参考,这个时候就需要经验来分析。比如可以参考一些类似行业的比较成熟的业务交易模型(比如银行业的日常交易活动或交通行业售检票交易活动)或者干脆遵循“2/8”原则和“2/5/8”原则来直接下手实践。

当用户能够在 2 秒以内得到响应时,会感觉系统的响应很快;

当用户在 2-5 秒之间得到响应时,会感觉系统的响应速度还可以;

当用户在 5-8 秒以内得到响应时,会感觉系统的响应速度很慢,但是还可以接受;

而当用户在超过 8 秒后仍然无法得到响应时,会感觉系统糟透了,或者认为系统已经失去响应,而选择离开这个 Web 站点,或者发起第二次请求。

在估算响应时间、并发用户数、TPS、成功率这些关键指标的同时,你仍需要关心具体的业务功能维度上的需求,每个业务功能都有各自的特点,比如有些场景可以不需要同步返回明确执行结果,有些业务场景可以接受返回“系统忙,请等待!”这样暴力的消息,以避免过大的处理流量所导致的大规模瘫痪,因此,学会平衡这些指标之间的关系是必要的,大多数情况下最好为这些指标做一个优先级排序,并且尽量只考察几个优先级高的指标要求。(SLA 服务等级)

SLA:Service-Level Agreement 的缩写,意思是服务等级协议。服务的 SLA 是服务提供者对服务消费者的正式承诺,是衡量服务能力等级的关键项。服务 SLA 中定义的项必须是可测量的,有明确的测量方法。

并发中相关概念的解释


在分析上述问题之前,先给大家普及一下,系统相关的一些关键衡量指标。

TPS

TPS(Transaction Per Second)每秒处理的事务数。

站在宏观角度来说,一个事务是指客户端向服务端发起一个请求,并且等到请求返回之后的整个过程。从客户端发起请求开始计时,等到收到服务器端响应结果后结束计时,在计算这个时间段内总共完成的事务个数,我们称为 TPS。

站在微观角度来说,一个数据库的事务操作,从开始事务到事务提交完成,表示一个完整事务,这个是数据库层面的 TPS。

QPS

QPS(Queries Per Second)每秒查询数,表示服务器端每秒能够响应的查询次数。这里的查询是指用户发出请求到服务器做出响应成功的次数,可以简单认为每秒钟的 Request 数量。

针对单个接口而言,TPS 和 QPS 是相等的。如果从宏观层面来说,用户打开一个页面到页面渲染结束代表一个 TPS,那这个页面中会调用服务器很多次,比如加载静态资源、查询服务器端的渲染数据等,就会产生两个 QPS,因此,一个 TPS 中可能会包含多个 QPS。

QPS=并发数/平均响应时间

RT

RT(Response Time),表示客户端发起请求到服务端返回的时间间隔,一般表示平均响应时间。

并发数

并发数是指系统同时能处理的请求数量。

需要注意,并发数和 QPS 不要搞混了,QPS 表示每秒的请求数量,而并发数是系统同时处理的请求数量,并发数量会大于 QPS,因为服务端的一个连接需要有一个处理时长,在这个请求处理结束之前,这个连接一直占用。

举个例子,如果 QPS=1000,表示每秒钟客户端会发起 1000 个请求到服务端,而如果一个请求的处理耗时是 3s,那么意味着总的并发=1000*3=3000,也就是服务端会同时有 3000 个并发。

计算方法

上面说的这些指标,怎么计算呢?举个例子。

假设在 10 点到 11 点这一个小时内,有 200W 个用户访问我们的系统,假设平均每个用户请求的耗时是 3 秒,那么计算的结果如下:

  • QPS=2000000/60*60 = 556 (表示每秒钟会有 556 个请求发送到服务端)

  • RT=3s(每个请求的平均响应时间是 3 秒)

  • 并发数=556*3=1668

从这个计算过程中发现,随着 RT 的值越大,那么并发数就越多,而并发数代表着服务器端同时处理的连接请求数量,也就意味服务端占用的连接数越多,这些链接会消耗内存资源以及 CPU 资源等。所以 RT 值越大系统资源占用越大,同时也意味着服务端的请求处理耗时较长。

但实际情况是,RT 值越小越好,比如在游戏中,至少做到 100ms 左右的响应才能达到最好的体验,对于电商系统来说,3s 左右的时间是能接受的,那么如何缩短 RT 的值呢?

按照 2/8 法则来推算 1000w 用户的访问量


继续回到最开始的问题,假设没有历史数据供我们参考,我们可以使用 2/8 法则来进行预估。

  • 1000W 用户,每天来访问这个网站的用户占到 20%,也就是每天有 200W 用户来访问。

  • 假设平均每个用户过来点击 50 次,那么总共的 PV=1 亿。

  • 一天是 24 小时,根据 2/8 法则,每天大部分用户活跃的时间点集中在(24*0.2) 约等于 5 个小时以内,而大部分用户指的是(1 亿点击 * 80%)约等于 8000W(PV), 意味着在 5 个小时以内,大概会有 8000W 点击进来,也就是每秒大约有 4500(8000W/5 小时)个请求。

  • 4500 只是一个平均数字。在这 5 个小时中,不可能请求是非常平均的,有可能会存在大量的用户集中访问(比如像淘宝这样的网站,日访问峰值的时间点集中在下午 14:00、以及晚上 21:00,其中 21:00 是一天中活跃的峰值),一般情况下访问峰值是平均访问请求的 3 倍到 4 倍左右(这个是经验值),我们按照 4 倍来计算。那么在这 5 个小时内有可能会出现每秒 18000 个请求的情况。也就是说,问题由原本的支撑 1000W 用户,变成了一个具体的问题,就是服务器端需要能够支撑每秒 18000 个请求(QPS=18000)

服务器压力预估


大概预估出了后端服务器需要支撑的最高并发的峰值之后,就需要从整个系统架构层面进行压力预估,然后配置合理的服务器数量和架构。既然是这样,那么首先需要知道一台服务器能够扛做多少的并发,那这个问题怎么去分析呢?我们的应用是部署在 Tomcat 上,所以需要从 Tomcat 本身的性能下手。

下面这个图表示 Tomcat 的工作原理,该图的说明如下。

  • LimitLatch 是连接控制器,它负责控制 Tomcat 能够同时处理的最大连接数,在 NIO/NIO2 的模式中,默认是 10000,如果是 APR/native,默认是 8192

  • Acceptor 是一个独立的线程,在 run 方法中,在 while 循环中调用 socket.accept 方法中接收客户端的连接请求,一旦有新的请求过来,accept 会返回一个 Channel 对象,接着把这个 Channel 对象交给 Poller 去处理。

Poller 的本质是一个 Selector ,它同样也实现了线程,Poller 在内部维护一个 Channel 数组,它在一个死循环里不断检测 Channel 的数据就绪状态,一旦有 Channel 可读,就生成一个 SocketProcessor 任务对象扔给 Executor 去处理

  • SocketProcessor 实现了 Runnable 接口,当线程池在执行 SocketProcessor 这个任务时,会通过 Http11Processor 去处理当前这个请求,Http11Processor 读取 Channel 的数据来生成 ServletRequest 对象。

  • Executor 就是线程池,负责运行 SocketProcessor 任务类, SocketProcessor 的 run 方法会调用 Http11Processor 来读取和解析请求数据。我们知道, Http11Processor 是应用层协议的封装,它会调用容器获得响应,再把响应通过 Channel 写出。

从这个图中可以得出,限制 Tomcat 请求数量的因素四个方面。

当前服务器系统资源

我想可能大家遇到过类似“Socket/File:Can’t open so many files”的异常,这个就是表示 Linux 系统中的文件句柄限制。

在 Linux 中,每一个 TCP 连接会占用一个文件描述符(fd),一旦文件描述符超过 Linux 系统当前的限制,就会提示这个错误。

我们可以通过下面这条命令来查看一个进程可以打开的文件数量

ulimit -a 或者 ulimit -n

复制代码

open files (-n) 1024 是 linux 操作系统对一个进程打开的文件句柄数量的限制(也包含打开的套接字数量)

这里只是对用户级别的限制,其实还有个是对系统的总限制,查看系统总线制:

cat /proc/sys/fs/file-max

复制代码

file-max 是设置系统所有进程一共可以打开的文件数量 。同时一些程序可以通过setrlimit调用,设置每个进程的限制。如果得到大量使用完文件句柄的错误信息,是应该增加这个值。

当出现上述异常时,我们可以通过下面的方式来进行修改(针对单个进程的打开数量限制)

vi /etc/security/limits.conf root soft nofile 65535 root hard nofile 65535 * soft nofile 65535 * hard nofile 65535

复制代码

  • *代表所有用户、root表示 root 用户。

  • noproc 表示最大进程数量

  • nofile 代表最大文件打开数量。

  • soft/hard,前者当达到阈值时,制作警告,后者会报错。

另外还要注意,要确保针对进程级别的文件打开数量反问是小于或者等于系统的总限制,否则,我们需要修改系统的总限制。

vi /proc/sys/fs/file-max

复制代码

TCP 连接对于系统资源最大的开销就是内存。

因为 tcp 连接归根结底需要双方接收和发送数据,那么就需要一个读缓冲区和写缓冲区,这两个 buffer 在 linux 下最小为 4096 字节,可通过 cat /proc/sys/net/ipv4/tcp_rmem 和 cat /proc/sys/net/ipv4/tcp_wmem 来查看。

所以,一个 tcp 连接最小占用内存为 4096+4096 = 8k,那么对于一个 8G 内存的机器,在不考虑其他限制下,最多支持的并发量为:8_1024_1024/8 约等于 100 万。此数字为纯理论上限数值,在实际中,由于 linux kernel 对一些资源的限制,加上程序的业务处理,所以,8G 内存是很难达到 100 万连接的,当然,我们也可以通过增加内存的方式增加并发量。

Tomcat 依赖的 JVM 的配置

我们知道 Tomcat 是 Java 程序,运行在 JVM 上,因此我们还需要对 JVM 做优化,才能更好的提升 Tomcat 的性能,简单带大家了解一下 JVM,如下图所示。

在 JVM 中,内存划分为堆、程序计数器、本地方发栈、方法区(元空间)、虚拟机栈。

堆空间说明

其中,堆内存是 JVM 内存中最大的一块区域,几乎所有的对象和数组都会被分配到堆内存中,它被所有线程共享。 堆空间被划分为新生代和老年代,新生代进一步划分为 Eden 和 Surivor 区,如下图所示。

总结:心得体会

既然选择这个行业,选择了做一个程序员,也就明白只有不断学习,积累实战经验才有资格往上走,拿高薪,为自己,为父母,为以后的家能有一定的经济保障。

学习时间都是自己挤出来的,短时间或许很难看到效果,一旦坚持下来了,必然会有所改变。不如好好想想自己为什么想进入这个行业,给自己内心一个答案。

面试大厂,最重要的就是夯实的基础,不然面试官随便一问你就凉了;其次会问一些技术原理,还会看你对知识掌握的广度,最重要的还是你的思路,这是面试官比较看重的。

最后,上面这些大厂面试真题都是非常好的学习资料,通过这些面试真题能够看看自己对技术知识掌握的大概情况,从而能够给自己定一个学习方向。包括上面分享到的学习指南,你都可以从学习指南里理顺学习路线,避免低效学习。

大厂Java架构核心笔记(适合中高级程序员阅读):

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

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

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
常好的学习资料,通过这些面试真题能够看看自己对技术知识掌握的大概情况,从而能够给自己定一个学习方向。包括上面分享到的学习指南,你都可以从学习指南里理顺学习路线,避免低效学习。

大厂Java架构核心笔记(适合中高级程序员阅读):

[外链图片转存中…(img-8ysh4zMJ-1713552317191)]

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

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

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

  • 15
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 答案:首先,您可以尝试运行fsck以检查文件系统,然后运行sudo apt-get update和sudo apt-get upgrade命令以更新和更新系统。如果这些操作不起作用,您可以尝试重新安装Ubuntu系统。 ### 回答2: 当Ubuntu开机后显示"/dev/nvme0n1p8:clean"而没有响应时,可能是系统遇到了一些错误导致停止了进一步的启动。以下是一些可能的解决方法: 1. 强制关机并重启:按电源按钮关闭计算机,然后再次启动计算机。有时候这个问题可能只是一个暂时的错误,通过重新启动可以解决。 2. 检查硬件问题:这个错误可能是由于硬件故障引起的。确保计算机的硬件连接正确,并检查是否有任何硬件故障。 3. 检查文件系统:这个错误可能是由于文件系统错误引起的。可以尝试使用Ubuntu的Live CD或USB启动计算机,然后使用磁盘工具检查和修复文件系统错误。 4. 更新和修复GRUB引导程序:GRUB是负责引导Ubuntu的程序。可以尝试通过Ubuntu的Live CD或USB进入恢复模式,并重新安装或修复GRUB引导程序。 5. 检查硬盘驱动器:这个错误可能是由于硬盘驱动器的问题引起的。可以尝试更新或更换硬盘驱动器的驱动程序来解决问题。 6. 重装或修复操作系统:如果以上方法都没有解决问题,最后的解决方法是重装或修复操作系统。可以尝试使用Ubuntu的Live CD或USB进行重新安装或修复操作系统。 请注意,在尝试以上方法之前,务必备份重要的数据,以免数据丢失。如果问题仍然存在,建议咨询Ubuntu的技术支持或论坛,以获取更专业的帮助。 ### 回答3: 当Ubuntu开机后显示"/dev/nvme0n1p8: clean"且没有响应时,可能有以下解决方法: 1. 强制重启:可能出现这个问题是由于系统挂起或崩溃导致的。按计算机的电源按钮强制关机,然后再重新启动计算机。 2. 检查硬件连接:确保硬盘正常连接,没有松动或损坏的连接线。可以尝试拔掉硬盘连接线,然后再重新连接一次。 3. 检查硬盘状态:使用Ubuntu的Live CD或USB启动Ubuntu,在终端中使用命令"sudo fdisk -l"来查看硬盘的状态。如果硬盘出现损坏或其他错误,可以考虑修复硬盘或者更换硬盘。 4. 检查文件系统:使用Ubuntu的Live CD或USB启动Ubuntu,在终端中使用命令"sudo fsck /dev/nvme0n1p8"来检查文件系统并进行修复。如果文件系统有错误,可以尝试修复它。 5. 重新安装系统:如果以上方法都无效,可以考虑重新安装Ubuntu系统。备份重要数据后,使用Ubuntu的安装媒体重新安装系统。 请注意,这些解决方法都需要谨慎操作,并根据实际情况选择合适的方法。如果不确定如何操作,建议寻求专业人士的帮助。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值