Java面试准备-分布式

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: Java面试准备-分布式

分布式幂等性如何设计?


根据业务场景建立唯一索引、或者建立组合索引,这样防止产生脏数据

token机制:通过redis来实现防重复提交

悲观锁

乐观锁

分布式锁


简单描述一下HTTP请求的过程


DNS解析

HTTP请求,当输入一个请求时,会进行TCP3次握手

客户端向服务端发送请求命令(Post、Get)

客户端发送请求头信息

服务端向客户端发送数据

服务端关闭TCP连接

客户端渲染


说说你对分布式事务的了解


ACID:

A:原子性

C:一致性

I:隔离性

D:持久性

ACP:

A:一致性:同一时刻不同节点是否保持一致

C:可用性:在某一节点出现问题时,是否还可以对外提供服务

P:分区容错性:A和C必须保证一个

BASE理论:是对CAP理论的一个权衡结果,我们复发做到强一致性,但是每个应用可以根据自身的特点,采用适当的方式来达到最终一致性。


分布式事务解决方案


两阶段提交(2PC)

三阶段提交(3PC)

补偿事务(TCC)

本地消息队列

最终一致性


负载均衡有哪些算法


随机

轮询

加权轮询

最少连接

源地址hash


常见的限流算法


计数器

使用计数器在周期内累加访问次数,当达到设定的限流值,触发限流策略,下一个周期开始时从新开始计数。(在单机或者分布式情况下,可以采用redis的incr原子自增操作来实现)。零界点问题。

滑动窗口

将时间分成很多个小周期,分别记录每个小周期内访问次数,并且根据时间滑动删除过期的小周期。

漏桶算法

访问请求到来时,直接放入漏桶,如当前容量已达到上限,则直接进行丢弃。

令牌桶算法

是以固定的算法(r=时间周期/限流值)的速度向令牌桶中加入令牌,直到令牌桶满,请求到达时向令牌桶获取令牌,获取成功则继续执行,获取失败则触发限流策略。


数据库如何处理海量数据


对数据库进行:分库分表、主从架构、读写分离。


如何提高系统的并发能力?


使用分布式服务器

部署多台服务器,做负载均衡

数据库分库分表、读写分离

引入业务需要的中间件


关于分布式事务


参考资料

https://blog.51cto.com/u_15499328/5159840?b=totalstatistic

2PC 二阶段提交

二阶段提交是一种强一致设计,2PC引入一个协调者来管理各个参与者的提交和回滚,二阶段分别是指准备和提交两个阶段。

它是同步阻塞的,而且同步阻塞长时间会导致资源锁的问题,总体而言效率低,并且存在单点故障,在极端条件下存在数据不一致问题。

2PC适应于数据库层面分布式事务应用场景。

3PC 三阶段提交

参与者也引入超时机制,并且新增了一个阶段使得参与者利用这一阶段统一各自的状态

3PC:准备阶段、预提交阶段、提交阶段。多引入一个阶段也会多一些交互,因此 性能会差一些。引入参与者超时机制。

2PC、3PC都是数据库层面的。

TCC(Try - Confirm - Cancel)

2PC 和 3PC 都是数据库层面的、而TCC是业务层面的分布式事务。

Try:预留、资源的预留和锁定

Confirm:确认操作,真正的执行

Cancel:撤销操作,把预留阶段的操作取消掉

其实思想上和2PC都差不多,都是先试探性执行,如果都可以那就真正执行,如果不行就回滚。

TCC对业务侵入较大,与业务紧耦合,需根据特定的业务场景来设计,

撤销和确认操作可能需要重试,要保证接口的幂等性。

TCC需要自定义,可实现跨数据库、跨不同业务系统来实现事务。

本地消息表

利用各个系统的本地事务来实现分布式事务。

有一张存放本地消息表,一般都放在数据库中,然后在执行业务的时候,将业务的执行和消息放入消息表放在同一个事务中,这样就能保证消息放入本地表中业务肯定是执行成功的。

如果调用失败,会有 定时任务定时读取本地消息表,实现最终一致性。

消息事务

RocketMQ 支持消息事务

第一步通过发送半消息,这个消息对于消费者来说不可见,然后发送成功后再执行本地事务。

再根据本地事务向broker发送Commit还是RollBack命令

并且RocketMq会提供反查事务状态接口,

RocketMq也是通过最终一致性来实现的。

最大努力通知

最大努力通知其实表示就是柔性事务的思想:我已经尽最大努力想达成事务的最终一致性。适用于对时间不敏感的业务,如短信通知等。


秒杀系统如何设计


秒杀服务子系统

就算秒杀系统挂了,不影响其他服务,【服务降价】

页面静态化

活动页面是流量第一入口,活动页面大都是固定的:商品名称、描述、图片等。为了减少不必要的服务端请求,页面会做静态化处理,用户常规浏览SKU的时候不会请求服务端。

静态化CND,内容分发网络。

前端处理

前端加一个定时器:比如5s之内只能发送一次服务端请求,然后秒杀按钮置灰。等限制时间过了又可以继续点击。

数据库读多写少

大部分查询走 Redis

缓存问题 Redis集群

通常情况下,我们需要在Redis中存商品信息,里面包含:商品编码、商品名称、商品属性、商品库存等信息。

优先查询缓存中数据是否存在,不存在再查询数据库。【缓存预热】

不存在的商品直接缓存为空,下次来查询直接用,缓存穿透问题。

数据库库存扣减问题

可以通过乐观锁解决

Redis lua 脚本扣减库存

先判断商品是否存在、如果不存在则直接返回

获取sku库存信息

如果库存大于0,则进行库存扣减

如果库存等于0,则直接返回表示库存不足

mq异步处理

消息丢失问题:本地记录消息表,本地记录成功再发送mq队列,有失败的消息通过job机制

延迟消息队列:订单超时取消。

限流

基于Nginx限流、基于Redis限流

基于用户限流、基于IP限流。

加验证码限流:三方验证码-滑块验证码。

基于业务限流:会员体系,限制条件。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
3月前
|
Java 数据库
在Java中使用Seata框架实现分布式事务的详细步骤
通过以上步骤,利用 Seata 框架可以实现较为简单的分布式事务处理。在实际应用中,还需要根据具体业务需求进行更详细的配置和处理。同时,要注意处理各种异常情况,以确保分布式事务的正确执行。
|
1月前
|
安全 架构师 Java
Java大厂面试高频:Collection 和 Collections 到底咋回答?
Java中的`Collection`和`Collections`是两个容易混淆的概念。`Collection`是集合框架的根接口,定义了集合的基本操作方法,如添加、删除等;而`Collections`是一个工具类,提供了操作集合的静态方法,如排序、查找、同步化等。简单来说,`Collection`关注数据结构,`Collections`则提供功能增强。通过小王的面试经历,我们可以更好地理解这两者的区别及其在实际开发中的应用。希望这篇文章能帮助你掌握这个经典面试题。
46 4
|
28天前
|
Java 程序员
Java社招面试中的高频考点:Callable、Future与FutureTask详解
大家好,我是小米。本文主要讲解Java多线程编程中的三个重要概念:Callable、Future和FutureTask。它们在实际开发中帮助我们更灵活、高效地处理多线程任务,尤其适合社招面试场景。通过 Callable 可以定义有返回值且可能抛出异常的任务;Future 用于获取任务结果并提供取消和检查状态的功能;FutureTask 则结合了两者的优势,既可执行任务又可获取结果。掌握这些知识不仅能提升你的编程能力,还能让你在面试中脱颖而出。文中结合实例详细介绍了这三个概念的使用方法及其区别与联系。希望对大家有所帮助!
164 60
|
4天前
|
Java 程序员 开发者
Java社招面试题:一个线程运行时发生异常会怎样?
大家好,我是小米。今天分享一个经典的 Java 面试题:线程运行时发生异常,程序会怎样处理?此问题考察 Java 线程和异常处理机制的理解。线程发生异常,默认会导致线程终止,但可以通过 try-catch 捕获并处理,避免影响其他线程。未捕获的异常可通过 Thread.UncaughtExceptionHandler 处理。线程池中的异常会被自动处理,不影响任务执行。希望这篇文章能帮助你深入理解 Java 线程异常处理机制,为面试做好准备。如果你觉得有帮助,欢迎收藏、转发!
45 14
|
7天前
|
安全 Java 程序员
Java 面试必问!线程构造方法和静态块的执行线程到底是谁?
大家好,我是小米。今天聊聊Java多线程面试题:线程类的构造方法和静态块是由哪个线程调用的?构造方法由创建线程实例的主线程调用,静态块在类加载时由主线程调用。理解这些细节有助于掌握Java多线程机制。下期再见! 简介: 本文通过一个常见的Java多线程面试题,详细讲解了线程类的构造方法和静态块是由哪个线程调用的。构造方法由创建线程实例的主线程调用,静态块在类加载时由主线程调用。理解这些细节对掌握Java多线程编程至关重要。
37 13
|
25天前
|
存储 人工智能 算法
解锁分布式文件分享的 Java 一致性哈希算法密码
在数字化时代,文件分享成为信息传播与协同办公的关键环节。本文深入探讨基于Java的一致性哈希算法,该算法通过引入虚拟节点和环形哈希空间,解决了传统哈希算法在分布式存储中的“哈希雪崩”问题,确保文件分配稳定高效。文章还展示了Java实现代码,并展望了其在未来文件分享技术中的应用前景,如结合AI优化节点布局和区块链增强数据安全。
|
27天前
|
算法 安全 Java
Java线程调度揭秘:从算法到策略,让你面试稳赢!
在社招面试中,关于线程调度和同步的相关问题常常让人感到棘手。今天,我们将深入解析Java中的线程调度算法、调度策略,探讨线程调度器、时间分片的工作原理,并带你了解常见的线程同步方法。让我们一起破解这些面试难题,提升你的Java并发编程技能!
68 16
|
24天前
|
Java 程序员 调度
Java 高级面试技巧:yield() 与 sleep() 方法的使用场景和区别
本文详细解析了 Java 中 `Thread` 类的 `yield()` 和 `sleep()` 方法,解释了它们的作用、区别及为什么是静态方法。`yield()` 让当前线程释放 CPU 时间片,给其他同等优先级线程运行机会,但不保证暂停;`sleep()` 则让线程进入休眠状态,指定时间后继续执行。两者都是静态方法,因为它们影响线程调度机制而非单一线程行为。这些知识点在面试中常被提及,掌握它们有助于更好地应对多线程编程问题。
55 9
|
29天前
|
安全 Java 程序员
Java面试必问!run() 和 start() 方法到底有啥区别?
在多线程编程中,run和 start方法常常让开发者感到困惑。为什么调用 start 才能启动线程,而直接调用 run只是普通方法调用?这篇文章将通过一个简单的例子,详细解析这两者的区别,帮助你在面试中脱颖而出,理解多线程背后的机制和原理。
60 12
|
27天前
|
存储 缓存 Java
Java中的分布式缓存与Memcached集成实战
通过在Java项目中集成Memcached,可以显著提升系统的性能和响应速度。合理的缓存策略、分布式架构设计和异常处理机制是实现高效缓存的关键。希望本文提供的实战示例和优化建议能够帮助开发者更好地应用Memcached,实现高性能的分布式缓存解决方案。
39 9

热门文章

最新文章