面试题30天打卡-day26

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

1、什么是 AOP?Spring AOP 和 AspectJ AOP 有什么区别?有哪些实现 AOP 的方式?


AOP(Aspect-Oriented Programming,面向切面编程)是一种编程思想,可以在不修改原有业务逻辑代码的情况下,动态地增加新的行为和功能。它通过将横切关注点(cross-cutting concerns)从业务逻辑中分离出来,以切面(aspect)的形式进行封装,实现了系统功能的模块化。


Spring AOP 和 AspectJ AOP 都是基于 AOP 思想的实现方式,其中 Spring AOP 是 Spring 框架提供的轻量级 AOP 框架,主要基于动态代理技术,可以对方法进行拦截和切入增强等操作。而 AspectJ AOP 则是基于 AspectJ 编译器独立的 AOP 框架,提供了更加强大的AOP能力,支持静态代理和动态代理两种方式,可以在编译期、类加载期、运行期等多个层面进行增强操作。


它们的主要区别在于:


Spring AOP 只支持方法级别的切面,而 AspectJ AOP 支持更加细粒度的切面,包括方法、属性、构造函数等。

Spring AOP 只支持运行时织入(runtime weaving),而 AspectJ AOP 支持编译时织入(compile-time weaving)和类加载时织入(load-time weaving),可以更加灵活地进行切面的织入。

除了 Spring AOP 和 AspectJ AOP,还有其他一些实现 AOP 的方式:


使用动态代理实现 AOP,这是一种比较轻量级的方式,可以实现对类的方法进行切面织入。

使用字节码增强技术实现 AOP,这种方式可以实现更加细粒度的切面织入,但相对比较复杂。

使用自定义类来实现AOP:主要是利用Java中的反射机制或者字节码工具,在运行时动态生成代理类实现AOP功能。

使用注解处理器实现 AOP,这是一种基于编译时的技术,可以通过注解来指定切面的织入点,比较灵活方便。

2、如何使用 Redis 实现分布式锁?

使用 Redis 实现分布式锁的核心思想是利用 Redis 的原子性操作,对Redis中特定的key进行setnx(set if not exists)操作,如果成功返回true表示获取到了锁,否则返回false表示没有获取到锁。在获取到锁的情况下,需要设置过期时间和在释放锁之前判断当前锁是否是自己持有的,以防出现死锁等问题。


具体实现步骤如下:


生成一个唯一的锁标识key,并设置锁的过期时间。

使用 setnx 命令尝试获取锁,如果返回结果为1,则表示获取锁成功,进入下一步;否则等待一段时间重试,直到获取到锁为止。

在持有锁的时间内,执行相关业务逻辑操作,并定时更新锁的过期时间,防止锁时间过长而导致锁自动失效。

释放锁,通过比较锁的持有者是否是自己来判断是否能够释放锁。


7622b005c4d8e154101d3f7ac92ac2c2.png

public class RedisDistributedLock {
    private static final String LOCK_PREFIX = "redis_lock_";
    private static final int EXPIRE_TIME = 5; // 锁过期时间5秒
    private RedisTemplate<String, Object> redisTemplate;
    private String lockKey;
    private String lockValue;
  // 构造函数
    public RedisDistributedLock(RedisTemplate<String, Object> redisTemplate, String lockKey) {
        this.redisTemplate = redisTemplate;
        this.lockKey = LOCK_PREFIX + lockKey;
        this.lockValue = UUID.randomUUID().toString();
    }
    // 获取锁
    public boolean lock() {
        try {
            String result = redisTemplate.execute((RedisCallback<String>) connection -> {
                JedisCommands commands = (JedisCommands) connection.getNativeConnection();
                return commands.set(lockKey, lockValue, "NX", "EX", EXPIRE_TIME);
            });
            return StringUtils.isNotBlank(result);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    // 释放锁
    public boolean unlock() {
        try {
            String script = "if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end";
            Long result = redisTemplate.execute((RedisCallback<Long>) connection -> {
                JedisCommands commands = (JedisCommands) connection.getNativeConnection();
                return (Long) commands.eval(script, Collections.singletonList(lockKey), Collections.singletonList(lockValue));
            });
            return result != null && result > 0;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
}

3、什么是分布式的 BASE 理论,它与 CAP 理论有什么联系?


分布式的BASE理论是建立在BASE理论(Basically Available, Soft State, Eventually Consistent)的基础上,针对分布式系统而提出的一种指导思想。它强调在分布式系统中,为了实现高可用性和可扩展性,有时需要牺牲一致性,通过异步复制、副本同步、冲突解决等方式来实现最终一致性。在这种情况下,系统的基本可用性和性能应该得到保障,并在最终一致性的前提下,尽量减少一致性等待时间。


区别:


CAP理论(Consistency, Availability, Partition Tolerance)是严格的理论限制。在分布式系统中,无法同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition Tolerance)三个条件,只能选择其中两个进行保障。由于在分布式系统中,节点之间可能会出现网络分区(Partition)导致通信中断,从而需要在可用性和一致性之间做出取舍。


Consistency:所有节点在同一时间看到相同的数据,即数据在多个节点间保持强一致性。

Availability:系统能够在有限时间内对外提供服务,即系统具有高可用性。

Partition Tolerance:系统能够在节点之间发生网络分区时继续工作,即系统具有分区容错性。

分布式的BASE理论认为,在分布式系统中,一致性不是绝对必须的,如果系统能够满足基本可用性和最终一致性,就可以放宽一致性要求,实现更高的性能和可扩展性。


两者的联系:


CAP理论和BASE理论都是面向分布式系统的理论,而且都关注系统的可用性。但它们关注的方面不同:


CAP理论关注分布式系统中数据的一致性和可用性,强调一致性和可用性之间需要进行取舍;

BASE理论关注分布式系统中数据的最终一致性和可用性,强调最终一致性和可用性之间的平衡。

场景:


当需要保证强一致性和数据安全性时,可以采用CAP理论,例如金融交易系统、电商系统等;

取舍;

BASE理论关注分布式系统中数据的最终一致性和可用性,强调最终一致性和可用性之间的平衡。

场景:


当需要保证强一致性和数据安全性时,可以采用CAP理论,例如金融交易系统、电商系统等;

当需要追求高性能和可扩展性时,可以采用BASE理论,例如社交网络、日志系统等。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
NoSQL 关系型数据库 MySQL
面试题30天打卡-day11
面试题30天打卡-day11
45 0
|
Java 关系型数据库 MySQL
面试题30天打卡-day03
面试题30天打卡-day03
26 0
|
Java 数据库连接 数据库
面试题30天打卡-day06
面试题30天打卡-day06
41 0
|
3月前
|
JavaScript 前端开发 API
面试题总结
面试题总结
104 58
|
前端开发 JavaScript 开发工具
【面试题2】2
【面试题2】
|
消息中间件 分布式计算 NoSQL
面试题30天打卡-day27
面试题30天打卡-day27
63 0
|
NoSQL 关系型数据库 应用服务中间件
面试题30天打卡-day15
面试题30天打卡-day15
43 0
|
前端开发 Java 数据库
面试题30天打卡-day01
面试题30天打卡-day01
53 0
|
Web App开发 前端开发 容器
【面试题总结3】
【面试题总结3】
|
前端开发
【面试题一】
【面试题一】