欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 国际 > 腾讯音乐二面

腾讯音乐二面

2025/5/23 7:08:49 来源:https://blog.csdn.net/2301_77011032/article/details/148150617  浏览:    关键词:腾讯音乐二面

在这里插入图片描述

  1. ReentrantLock 的源码及实现

    • ReentrantLock 是 Java 中的一种可重入的互斥锁。它通过 AQS(AbstractQueuedSynchronizer)框架来实现。AQS 使用一个 FIFO 队列来管理获取锁的线程。ReentrantLock 有公平锁和非公平锁两种模式。
    • 非公平锁:当线程尝试获取锁时,如果锁被其他线程持有,当前线程会被加入到同步队列中。但是,非公平锁允许插队,即新线程有可能在已经排队的线程之前获取到锁。它通过 CAS(Compare - And - Swap)操作来修改同步状态。如果获取锁成功,则返回;否则,将当前线程加入同步队列,并可能被 park(挂起)。
    • 公平锁:会按照线程申请锁的顺序来获取锁。线程会先检查同步队列是否有线程在等待,如果有,则只有当锁被释放并且轮到自己时才能获取锁。
  2. Redis 分布式锁与 zk 分布式锁的区别

    • 实现原理方面

      • Redis 分布式锁通常是基于 SETNX(Set if Not Exists)命令来实现获取锁。它将锁存储为一个键值对,键是锁的标识,值可以是线程标识或者其他信息。获取锁时,如果键不存在则设置键,并设置过期时间(防止死锁)。释放锁时,通过 Lua 脚本判断键的值是否匹配当前线程,匹配则删除键。
      • ZooKeeper 实现分布式锁一般是利用其临时顺序节点。当多个客户端尝试创建某个父节点下的临时顺序节点,创建成功的客户端获得锁,其他客户端则监听该父节点下的节点变化。当持有锁的客户端断开连接或者主动释放锁(删除临时节点),其他客户端可以按照顺序获取锁。
    • 性能方面

      • Redis 分布式锁在单点故障和网络分区情况下可能会出现锁不可用或者数据不一致的问题(如果 Redis 实例挂掉且没有正确配置主从),但是它在获取和释放锁的性能较高,因为它使用简单的键值操作。
      • ZooKeeper 的分布式锁性能相对 Redis 较低,因为它的锁获取和释放需要进行节点创建、删除以及监听等操作,涉及较多的网络通信和 ZooKeeper 内部的事务处理。但 ZooKeeper 在可靠性方面较强,它通过多个服务器组成的集群来提供高可用和强一致性。
    • 功能方面

      • Redis 分布式锁可以设置自动续期机制,以防止因线程执行时间过长而锁过期被其他线程获取。而 ZooKeeper 的锁机制本身具有临时节点的自动清理功能(当客户端会话失效时,临时节点会被删除),但是没有自动续期功能。
  3. 接口幂等性的保证方法

    • 数据库层面 :在数据库中为关键操作的字段添加唯一约束。例如,在支付接口中,根据订单号来确保支付操作的幂等性。当重复提交支付请求时,数据库会因订单号重复而拒绝第二次及之后的写入操作。
    • 业务逻辑层面 :记录操作的状态,例如在订单状态更新接口中,只有当订单当前状态是 “待处理” 时,才允许更新为 “处理中” 或 “已完成” 等状态。对于重复的状态更新请求,直接返回成功而不进行实际操作。
    • 分布式锁层面 :在执行接口操作时,先获取分布式锁。这样可以保证同一时间只有一个请求能够进行操作,从而避免重复执行导致的不幂等问题。
  4. RR(可重复读)隔离级别实现原理及解决不可重复读的方法

    • 实现原理 :在可重复读隔离级别下,InnoDB 存储引擎通过 MVCC(多版本并发控制)来实现。每个事务在读取数据时,都会看到一个数据的快照。这个快照是事务开始时的数据状态。在可重复读级别,一个事务在读取某一行数据后,再次读取该行数据时,会一直看到事务开始时的版本,即使其他事务对该行数据进行了修改并提交。
    • 解决不可重复读的方法 :通过 MVCC 机制,为事务提供数据的一致性读。在事务读取数据期间,其他事务对数据的修改不会影响当前事务所看到的数据版本。这样就避免了不可重复读的问题。例如,事务 A 先读取某一行数据的值为 10,在事务 A 还未提交期间,事务 B 修改该行数据为 20 并提交。事务 A 再次读取该行数据时,仍然是 10,从而保证了可重复读。
  5. 项目中分布式锁的使用方式

    • 业务场景选择 :在项目中,分布式锁通常用于高并发场景下的共享资源访问控制,例如库存扣减、秒杀活动的订单生成等。以库存扣减为例,当多个用户同时请求购买同一商品时,为了保证库存数据的正确性,会在扣减库存的代码段使用分布式锁。
    • 具体实现步骤 :在代码中,使用 Redisson 等分布式锁库获取锁。在获取锁的代码块中,执行业务逻辑(如扣减库存)。设置锁的超时时间,防止死锁。例如:
      • 使用 Redisson 的RLock lock = redissonClient.getLock("stockLock");
      • 尝试获取锁boolean isLock = lock.tryLock(10, 1, TimeUnit.SECONDS);
      • 如果获取锁成功,执行库存扣减操作;否则,返回失败信息。
      • 最后,无论是否成功,都要在 finally 块中释放锁lock.unlock();
  6. MySQL 查询语句慢的排查和优化方法

    • 分析慢查询 :首先开启慢查询日志,通过SHOW VARIABLES LIKE 'slow_query_log';查看慢查询日志是否开启,开启后通过SHOW VARIABLES LIKE 'slow_query_log_file';查看日志文件路径。分析日志中的查询语句。
    • 使用 EXPLAIN 分析查询计划 :对慢查询语句使用EXPLAIN关键字,查看查询的执行计划。重点关注type(连接类型,如全表扫描、索引扫描等)、key(使用的索引)、rows(扫描的行数)等字段。
    • 优化方法 :如果发现没有使用索引,添加合适的索引。例如,对于频繁作为查询条件的列添加索引。如果查询语句中存在复杂的子查询,尝试将子查询改写为连接查询或者使用临时表。对大数据量的表进行分页查询时,合理设置分页参数,避免一次性查询过多数据。
  7. 除了 GC 外使用安全点的场景

    • 类加载阶段 :在 Java 虚拟机的类加载过程中的准备阶段,需要为类的静态变量分配内存,并且设置初始值。在这个过程中,虚拟机可能会使用安全点来确保线程不会干扰类的初始化操作。
    • JVMTI(Java Virtual Machine Tool Interface)事件处理 :当虚拟机需要处理某些 JVMTI 事件(如线程开始、线程结束、异常抛出等)时,可能会要求线程到达安全点以便进行事件通知和处理。例如,在调试工具中,当需要获取线程的堆栈信息时,线程需要在安全点暂停,以便堆栈信息的准确获取。
  8. 分库分表方案中数据倾斜问题的解决方法

    • 调整分片键选择 :数据倾斜是因为分片键的分布不均匀导致某些分片的数据量过大。如果原来的分片键存在数据倾斜问题,可以尝试更换分片键。例如,如果按照用户 ID 分片导致数据倾斜,可以尝试将用户 ID 和其他字段(如订单时间)进行组合作为分片键。
    • 增加分片数量 :适当增加分片数量可以将数据进一步分散到更多的分片中。例如,原本按照用户 ID 模 10 分片,将分片数增加到 20,这样每个分片的数据量可能会减少,从而缓解数据倾斜问题。
    • 使用分片策略优化算法 :采用更合理的分片策略,如一致性哈希算法。它可以在添加或删除分片时,只影响少量的数据迁移,减少数据倾斜的可能性。
  9. MySQL 行级锁锁住的具体内容

    • 行级锁是针对数据库表中的行记录的锁。在 InnoDB 存储引擎中,行级锁是通过索引上的锁来实现的。如果一条 SQL 语句没有使用索引,那么 InnoDB 存储引擎会使用表级锁。例如,在查询语句中使用了主键索引进行查询,并且执行了更新操作,那么行级锁会锁住对应主键索引指向的行记录。如果查询语句使用的是非聚集索引,并且更新操作涉及到聚集索引(如主键)相关的列,那么可能会锁住聚集索引对应的行。
  10. 查询优化器选错索引的解决方法
    * 分析查询语句 :首先使用EXPLAIN查看查询的执行计划,确定查询优化器选择的索引是否合理。如果发现优化器没有选择最优的索引,可以查看查询语句是否符合索引的使用条件。
    * 调整索引统计信息 :通过ANALYZE TABLE命令来更新表的索引统计信息。如果统计信息不准确,查询优化器可能会做出错误的索引选择决定。
    * 使用索引提示 :在查询语句中使用索引提示(如FORCE INDEX),强制查询优化器使用指定的索引。例如SELECT * FROM table1 FORCE INDEX (index_name) WHERE conditions;。但这种方法需要谨慎使用,因为随着数据的变化,原本合适的索引可能在后期变得不合适。

  11. Netty 相比原生 IO 模型的优势
    * 异步非阻塞 IO 模型 :Netty 基于 Java 的 NIO(New IO)模型,采用异步非阻塞的方式处理网络请求。与原生的 BIO(Blocking IO)相比,它可以同时处理大量的客户端连接而不会阻塞线程。例如,在高并发的聊天服务器中,Netty 可以高效地处理成千上万的客户端连接,每个连接对应一个 Channel,而不需要为每个连接创建一个线程。
    * 高效的数据缓冲和处理 :Netty 提供了丰富的 Buffer 类型(如 ByteBuf),可以更高效地进行数据读写操作。它允许直接操作内存中的字节缓冲区,并且可以避免不必要的数据复制。而原生 IO 模型在数据读写过程中可能会涉及多次数据复制,导致性能下降。
    * 灵活的事件驱动模型 :Netty 基于事件驱动架构,可以方便地处理各种网络事件(如连接建立、数据读写、异常等)。开发者可以通过自定义 ChannelHandler 来处理不同的事件。相比之下,原生 IO 模型需要开发者自己处理复杂的事件循环和回调机制。

  12. 表数据量大影响查询效率的主要原因
    * 缺少合适的索引 :如果查询语句中涉及的列没有索引,数据库可能会进行全表扫描。例如,一个查询语句通过 “name” 列进行查询,而没有在 “name” 列上创建索引。随着数据量的增加,全表扫描的性能会急剧下降。
    * 索引选择不当 :即使有索引,如果索引设计不合理(如索引字段顺序不当、重复索引等),也会影响查询效率。例如,一个复合索引的字段顺序与查询语句中的条件顺序不匹配,导致索引无法有效利用。
    * 表结构设计问题 :表结构中存在冗余字段或者字段类型过大也会导致数据存储量增加。例如,在一个日志表中,存储了大量的文本字段,而这些字段在查询时并不常用,增加了磁盘 I/O 操作。
    * 数据碎片 :随着数据的频繁插入、删除和更新,表中的数据可能会产生碎片。数据碎片会导致磁盘空间的利用率降低,并且增加了数据读取的时间。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词