首页 > 实在智能科技-java麻经
头像
Tansty
编辑于 03-26 20:58
+ 关注

实在智能科技-java麻经

分布式锁的原理

我用的是redission

1.使用 key 作为锁的标识:Redisson 实现分布式锁的方式是通过 Redis 的 key 来作为锁的标识。当客户端需要获取锁时,它会通过相应的 key 去请求 Redis。

2.基于 Redis 的 setnx 命令:Redisson 使用 Redis 的 setnx(set if not exist)命令来尝试获取锁。如果 setnx 成功,那么就表示客户端获得了锁。

3.设置锁的过期时间:为了避免因为某个客户端在获取锁后出现异常而无法释放锁,Redisson 为锁设置了一个过期时间。如果锁在过期时间之前没有被释放,那么 Redis 会自动释放该锁。

4.可重入锁:Redisson 还支持可重入锁,即同一个线程可以多次获取同一个锁,而不会产生死锁。

5.锁的释放:当客户端完成对资源的操作后,它会调用 Redisson 的unlock方法来释放锁。这样可以确保只有获得锁的客户端才能释放它。

6.监控和诊断:Redisson 还提供了很多工具类和接口,用于监控和诊断分布式锁的问题,比如获取锁的持有情况、获取等待获取锁的线程等。

LUA脚本的弊端

虽然 Redis Lua 提供了更高级的功能和灵活性,但也有一些弊端需要注意:

  1. 可维护性:Lua脚本通常存储在Redis服务器端,维护起来可能不如存储在应用程序中的代码方便。更新和修改Lua脚本可能需要重启Redis服务器。
  2. 性能开销:Lua脚本的执行会占用Redis服务器的CPU资源,如果Lua脚本中包含复杂逻辑或循环操作,可能会影响Redis服务器的性能。
  3. 调试困难:在Redis中调试Lua脚本相对困难,可能需要通过日志或其他方式进行调试,不如在本地开发环境中进行调试方便。
  4. 单点故障:如果Redis服务器发生故障或重启,Lua脚本可能会丢失,需要重新加载。这可能会导致数据不一致或操作失败。
  5. 扩展性:Lua脚本的扩展性有限,难以实现复杂的分布式计算或跨节点操作,限制了Redis在某些场景下的扩展性

为什么使用LUA脚本会带来损耗

  1. 脚本加载和执行开销:在执行Lua脚本之前,Redis需要加载和编译Lua脚本,这会引入一定的开销。虽然Redis会缓存已经编译过的脚本,但仍然存在一定的加载和执行开销。
  2. CPU资源消耗:Lua脚本的执行是在Redis服务器端进行的,会占用CPU资源。如果Lua脚本中包含复杂逻辑、循环操作或大量计算,会导致服务器的CPU资源消耗增加,影响Redis的性能。
  3. 通信开销:在执行Lua脚本时,客户端需要将Lua脚本发送到Redis服务器,并接收执行结果。这种通信开销会占用网络带宽和增加延迟。
  4. 内存占用:Lua脚本执行期间可能会产生临时变量、缓存数据等,占用一定的内存空间。如果Lua脚本执行过程中需要大量内存,可能会导致内存压力增加。
  5. 单线程模型:Redis采用单线程模型,执行Lua脚本时会阻塞其他操作。如果Lua脚本执行时间过长,可能会影响其他客户端的请求响应速度。

mybatis mapper接口和xml底层的转换原理

MyBatis是一个持久层框架,它提供了Mapper接口和对应的XML映射文件来实现数据库操作。Mapper接口和XML底层的转换原理如下:

  1. Mapper接口:Mapper接口定义了数据库操作的方法,方法名和参数映射了具体的SQL语句。MyBatis使用动态代理技术来生成Mapper接口的实现类,实现类中包含了具体的SQL语句的执行逻辑。Mapper接口方法和XML映射文件中的SQL语句是一一对应的关系,Mapper接口方法的方法名和参数会被解析为对应的SQL语句。
  2. XML映射文件:XML映射文件定义了SQL语句和参数的映射关系,以及结果集的映射关系。XML映射文件中包含了SQL语句的定义,可以使用动态SQL来实现条件判断、循环等功能。MyBatis通过XML配置文件中的<Mapper>标签来加载Mapper接口和XML映射文件的映射关系。
  3. 转换原理:当应用程序调用Mapper接口的方法时,MyBatis会通过动态代理技术生成Mapper接口的实现类。实现类中会解析Mapper接口方法的方法名和参数,根据配置文件中的映射关系找到对应的SQL语句。MyBatis会根据SQL语句的定义执行数据库操作,并将结果映射到Java对象中返回给应用程序。

总的来说,Mapper接口和XML底层的转换原理是通过动态代理技术生成Mapper接口的实现类,实现类中根据配置文件中的映射关系执行对应的SQL语句,实现数据库操作和结果映射。这种设计模式让开发者可以通过接口定义和XML配置文件灵活地实现数据库操作,提高了代码的可维护性和可扩展性。

mysql最左索引前缀匹配为什么要这么设计

  1. 索引存储方式:MySQL的B+tree索引是按照索引列的顺序存储的,最左前缀匹配可以更好地利用这种存储方式,提高查询效率。
  2. 查询优化:通过最左前缀匹配,MySQL可以更快地定位到符合条件的记录,减少不必要的索引扫描,提高查询性能。
  3. 索引选择性:最左前缀匹配可以提高索引的选择性,即查询条件中使用索引的列是索引列的前缀,可以更准确地过滤出符合条件的记录。
  4. 减少索引冗余:通过最左前缀匹配,可以避免创建冗余的索引,减少索引占用的存储空间。

平时给你一个题目你是怎么考虑的

  1. 理解问题:首先要仔细阅读题目,确保理解清楚要解决的问题和需求是什么。如果有不明确的地方,可以向题目提供者或其他人请教。
  2. 分析需求:将问题分解为更小的子问题,明确每个子问题的输入、输出以及解决方法。考虑可能涉及的算法、数据结构等方面。
  3. 选择合适的语言和工具:根据问题的特点和自己的熟悉程度,选择合适的编程语言和开发工具。
  4. 设计算法和数据结构:根据问题的特点选择合适的算法和数据结构来解决问题,确保解决方案的效率和可扩展性。
  5. 编写代码:根据设计好的算法和数据结构,开始编写程序代码。保持代码清晰、模块化和易于理解。
  6. 测试和调试:编写完代码后,进行测试和调试,确保程序能够正确运行,并处理各种边界情况和异常情况。
  7. 优化和改进:根据测试结果和反馈,对程序进行优化和改进,提高代码的性能和可维护性。
  8. 文档编写:最后,编写必要的文档,包括程序的使用说明、代码注释等,以方便他人理解和使用。

有三个猴子和一堆桃子,轮流吃1个2个或3个,输出最终吃了几个

import java.util.Random;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @version 1.0
 * @Author Tansty
 * @Description //TODO
 * @Date 2024/3/26 14:01
 */
public class Test {

    public static void main(String[] args) {
        int peaches = 100;
        int monkeys = 3;
        Random random = new Random();
        int[] res = new int[3];
        while (true){
            for (int i = 0; i < monkeys; i++) {
                int count = random.nextInt(3)+1;
                if(peaches>=count) {
                    peaches -= count;
                    res[i] += count;
                }else{
                    res[i] += peaches;
                    for (int j = 0; j < res.length; j++) {
                        System.out.println("monkey:"+j+",eat:"+res[j]);
                    }
                    return;
                }

            }
        }
    }


}

全部评论

(11) 回帖
加载中...
话题 回帖