【MySQL08】【死锁】

文章目录

  • 一、前言
  • 二、查看事务加锁情况
    • 1. 使用 information_schema 数据库中表获取锁信息
      • 1.1 INNODB_TRX
      • 1.2 INNODB_LOCKS
      • 1.3 INNODB_LOCK_WAITS
    • 2. 使用 SHOW ENGIN INNODB STATUS 获取锁信息
  • 三、死锁
  • 四、参考内容

一、前言

最近在读《MySQL 是怎样运行的》、《MySQL技术内幕 InnoDB存储引擎 》,后续会随机将书中部分内容记录下来作为学习笔记,部分内容经过个人删改,因此可能存在错误,如想详细了解相关内容强烈推荐阅读相关书籍。


系列文章内容目录:

  1. 【MySQL00】【 杂七杂八】
  2. 【MySQL01】【 Explain 命令详解】
  3. 【MySQL02】【 InnoDB 记录存储结构】
  4. 【MySQL03】【 Buffer Pool】
  5. 【MySQL04】【 redo 日志】
  6. 【MySQL05】【 undo 日志】
  7. 【MySQL06】【MVCC】
  8. 【MySQL07】【锁】
  9. 【MySQL08】【死锁】

二、查看事务加锁情况

1. 使用 information_schema 数据库中表获取锁信息

1.1 INNODB_TRX

INNODB_TRX 存储了 InnoDB 当前正在执行的事务信息,包括事务id(如果没有分配事务id,则显示当前事务对应的内存结构的指针)、事务状态(比如事务正在运行还是在等待获取某个锁、事务正在执行的语句、事务是何时开启的)等。如下:

  1. 开启一个事务 T1
    mysql> BEGIN;
    Query OK, 0 rows affected (0.00 sec)mysql> SELECT * FROM hero WHERE number = 8 FOR UPDATE;
    +--------+-------+---------+
    | number | name  | country |
    +--------+-------+---------+
    |      8 | c曹操 ||
    +--------+-------+---------+
    1 row in set (0.00 sec)
    
  2. 在另一个会话中查询 INNODB_TRX 表:
    mysql> SELECT * FROM  information_schema.INNODB_TRX\G
    *************************** 1. row ***************************trx_id: 195617trx_state: RUNNINGtrx_started: 2024-06-27 09:51:28trx_requested_lock_id: NULLtrx_wait_started: NULLtrx_weight: 2trx_mysql_thread_id: 10trx_query: NULLtrx_operation_state: NULLtrx_tables_in_use: 0trx_tables_locked: 1trx_lock_structs: 2trx_lock_memory_bytes: 1136trx_rows_locked: 1trx_rows_modified: 0trx_concurrency_tickets: 0trx_isolation_level: REPEATABLE READtrx_unique_checks: 1trx_foreign_key_checks: 1
    trx_last_foreign_key_error: NULLtrx_adaptive_hash_latched: 0trx_adaptive_hash_timeout: 0trx_is_read_only: 0
    trx_autocommit_non_locking: 0
    1 row in set (0.00 sec)
    

从执行结果可以看到,当前系统中有一个事务id为 195617 的事务,它的状态为 “正在运行”(RUNNING),隔离级别为 REPEATABLE READ。这里主要关注下面几个属性:

  • trx_tables_locked :表示当前事务加了多少表级锁
  • trx_rows_locked :表示当前事务加了多少行级锁
  • trx_lock_structs :表示当前事务生成了多少内存中的锁结构。

1.2 INNODB_LOCKS

INNODB_LOCKS 记录了一些锁信息,主要包括:

  • 如果一个事务想要获取锁但是未获取到,则记录该锁信息
  • 如果一个事务获取到了某个所,但是这个锁阻塞了别的事务,则记录该锁信息。
  1. INNODB_LOCKS 表只有在系统中发生某个事务获取不到锁而被阻塞时才会有记录,因此我们需要再执行一个事务 T2

    mysql> BEGIN;
    Query OK, 0 rows affected (0.00 sec)mysql> SELECT * FROM hero WHERE number = 8 FOR UPDATE;
    +--------+-------+---------+
    | number | name  | country |
    +--------+-------+---------+
    |      8 | c曹操 ||
    +--------+-------+---------+
    1 row in set (0.00 sec)
    
  2. 查询 INNODB_LOCKS 表记录,如下

    mysql> SELECT * FROM  information_schema.INNODB_LOCKS;
    +-----------------+-------------+-----------+-----------+---------------+------------+------------+-----------+----------+-----------+
    | lock_id         | lock_trx_id | lock_mode | lock_type | lock_table    | lock_index | lock_space | lock_page | lock_rec | lock_data |
    +-----------------+-------------+-----------+-----------+---------------+------------+------------+-----------+----------+-----------+
    | 195619:2432:3:8 | 195619      | X         | RECORD    | `demo`.`hero` | PRIMARY    |       2432 |         3 |        8 | 8         |
    | 195617:2432:3:8 | 195617      | X         | RECORD    | `demo`.`hero` | PRIMARY    |       2432 |         3 |        8 | 8         |
    +-----------------+-------------+-----------+-----------+---------------+------------+------------+-----------+----------+-----------+
    2 rows in set, 1 warning (0.00 sec)
    

可以看到 trx_id 为 195617 和 195619两个事务存在记录,但是上述内容无法区分是到底谁获取到其他事务的需要的锁,以及谁因为没有获取到锁而阻塞。可以通过 INNODB_LOCK_WAITS 表获取到

1.3 INNODB_LOCK_WAITS

INNODB_LOCK_WAITS 表明每个阻塞的事务是因为获取不到哪个事务持有的锁而阻塞。继续上面的情况,执行如下语句

mysql> SELECT * FROM  information_schema.INNODB_LOCK_WAITS;
+-------------------+-------------------+-----------------+------------------+
| requesting_trx_id | requested_lock_id | blocking_trx_id | blocking_lock_id |
+-------------------+-------------------+-----------------+------------------+
| 195619            | 195619:2432:3:8   | 195617          | 195617:2432:3:8  |
+-------------------+-------------------+-----------------+------------------+
1 row in set, 1 warning (0.00 sec)

其中:

  • requesting_trx_id :表示因为获取不到锁而被阻塞的事务的事务id;本例中表示事务T2 的id
  • blocking_trx_id :表示因为获取到别的事务需要的锁而导致其被阻塞的事务的事务id;本地中表示事务T1的id

需要注意的是:INNODB_LOCKS 和 INNODB_LOCK_WAITS 已经被标记过时,在MySQL 8.0 中就已经被移除。

2. 使用 SHOW ENGIN INNODB STATUS 获取锁信息

  1. 以下面SQL为例

    mysql> BEGIN;
    Query OK, 0 rows affected (0.00 sec)mysql> SELECT * FROM hero FORCE INDEX(idx_name) WHERE name > 'c曹操' AND name <= 'x荀彧' AND country != '吴' ORDER BY name DESC FOR UPDATE;
    +--------+-------+---------+
    | number | name  | country |
    +--------+-------+---------+
    |     15 | x荀彧 ||
    |      1 | l刘备 ||
    +--------+-------+---------+
    2 rows in set (0.00 sec)
    

    该SQL的加锁流程在 【MySQL07】【锁】有过分析,其加锁结构如下:
    在这里插入图片描述

  2. 执行 SHOW ENGINE INNODB STATUS,如下:

    mysql> SHOW ENGINE INNODB STATUS\G
    *************************** 1. row ***************************
    ... 省略部分信息
    ------------
    TRANSACTIONS
    ------------
    # 下一个待分配的事务id信息
    Trx id counter 195622
    # 一些关于 purge 信息
    Purge done for trx's n:o < 195295 undo n:o < 0 state: running but idle# 每个回滚段中有一个 History 链表,这些链表的总长是 1933
    History list length 1933# 每个事务的具体信息
    LIST OF TRANSACTIONS FOR EACH SESSION:
    ---TRANSACTION 283969552689208, not started
    0 lock struct(s), heap size 1136, 0 row lock(s)
    ---TRANSACTION 283969552688336, not started
    0 lock struct(s), heap size 1136, 0 row lock(s)
    ---TRANSACTION 283969552687464, not started
    0 lock struct(s), heap size 1136, 0 row lock(s)
    ---TRANSACTION 283969552686592, not started
    0 lock struct(s), heap size 1136, 0 row lock(s)
    ---TRANSACTION 283969552685720, not started
    0 lock struct(s), heap size 1136, 0 row lock(s)# 事务id为 195621 的事务,处于活跃状态 139s
    ---TRANSACTION 195621, ACTIVE 139 sec
    # 该事务有4个锁结构, 9 个行锁
    4 lock struct(s), heap size 1136, 9 row lock(s)# 执行该事务的线程在 MySQL 中的编号为 9,操作系统中的线程号是 19744, 本次查询的编号是 255,,客户端主机名为 localhost, 用户名四 root
    MySQL thread id 9, OS thread handle 19744, query id 255 localhost ::1 root cleaning up... 忽略剩余内容1 row in set (0.00 sec)
    

    上面输出的结构无法看出到底哪个事务对哪些记录加了哪些锁,因此可以将 innodb_status_output_locks 设置为 on 然后再输出日志,如下(这里只保存了 TRANSACTIONS 部分的日志,上述SQL 重新执行了,所以下面的事务ID 有了变化,本次事务id 195625):

    # 设置 innodb_status_output_locks = ON
    mysql> SET GLOBAL innodb_status_output_locks = ON;
    Query OK, 0 rows affected (0.00 sec)# 再次执行 SHOW ENGINE INNODB STATUS语句
    mysql> SHOW ENGINE INNODB STATUS\G
    *************************** 1. row ***************************
    ... 省略部分信息
    ------------
    TRANSACTIONS
    ------------
    Trx id counter 195625
    Purge done for trxs n:o < 195623 undo n:o < 0 state: running but idle
    History list length 1934
    LIST OF TRANSACTIONS FOR EACH SESSION:
    ---TRANSACTION 283969552690080, not started
    0 lock struct(s), heap size 1136, 0 row lock(s)
    ---TRANSACTION 283969552689208, not started
    0 lock struct(s), heap size 1136, 0 row lock(s)
    ---TRANSACTION 283969552688336, not started
    0 lock struct(s), heap size 1136, 0 row lock(s)
    ---TRANSACTION 283969552687464, not started
    0 lock struct(s), heap size 1136, 0 row lock(s)
    ---TRANSACTION 283969552686592, not started
    0 lock struct(s), heap size 1136, 0 row lock(s)
    ---TRANSACTION 283969552685720, not started
    0 lock struct(s), heap size 1136, 0 row lock(s)
    ---TRANSACTION 195624, ACTIVE 51 sec
    4 lock struct(s), heap size 1136, 9 row lock(s)
    MySQL thread id 9, OS thread handle 19744, query id 264 localhost ::1 root cleaning up
    # 表明事务id = 195624 的事务对 hero 表加了 IX 锁(意向独占锁)。
    TABLE LOCK table `demo`.`hero` trx id 195624 lock mode IX
    # 表示一个锁结构,这个锁结构的 Space ID 为 2432, Page No 为 4, n_bits 为 80, 对应的索引是 idx_name, 这个锁结构存放的锁的类型是 X 型 gap 锁
    RECORD LOCKS space id 2432 page no 4 n bits 80 index idx_name of table `demo`.`hero` trx id 195624 lock_mode X locks gap before rec
    # 上面锁结构加锁的详细信息(就是 name = z诸葛亮的 二级索引记录)
    Record lock, heap no 6 PHYSICAL RECORD: n_fields 2; compact format; info bits 00: len 10; hex 7ae8afb8e8919be4baae; asc z         ;;1: len 4; hex 80000003; asc     ;;
    # 表示一个锁结构,这个锁结构的 Space ID 为 2432, Page No 为 4, n_bits 为 80, 对应的索引是 idx_name, 这个锁结构存放的锁的类型是 X 型 next-key 锁
    RECORD LOCKS space id 2432 page no 4 n bits 80 index idx_name of table `demo`.`hero` trx id 195624 lock_mode X
    # 上面锁结构加锁的详细信息(就是name = l刘备、c曹操、x荀彧、s孙权)
    Record lock, heap no 2 PHYSICAL RECORD: n_fields 2; compact format; info bits 00: len 7; hex 63e69bb9e6938d; asc c      ;;1: len 4; hex 80000008; asc     ;;Record lock, heap no 3 PHYSICAL RECORD: n_fields 2; compact format; info bits 00: len 7; hex 6ce58898e5a487; asc l      ;;1: len 4; hex 80000001; asc     ;;Record lock, heap no 4 PHYSICAL RECORD: n_fields 2; compact format; info bits 00: len 7; hex 73e5ad99e69d83; asc s      ;;1: len 4; hex 80000014; asc     ;;Record lock, heap no 5 PHYSICAL RECORD: n_fields 2; compact format; info bits 00: len 7; hex 78e88d80e5bda7; asc x      ;;1: len 4; hex 8000000f; asc     ;;Record lock, heap no 7 PHYSICAL RECORD: n_fields 2; compact format; info bits 320: len 7; hex 67e585b3e7bebd; asc g      ;;1: len 4; hex 8000001e; asc     ;;
    # 表示一个锁结构,这个锁结构的 Space ID 为 2432, Page No 为 3, n_bits 为 80, 对应的索引是 PRIMARY, 也就是聚簇索引,这里存放的锁的类型是 X 型正经记录锁(lock_mode X locks rec but not gap)
    RECORD LOCKS space id 2432 page no 3 n bits 80 index PRIMARY of table `demo`.`hero` trx id 195624 lock_mode X locks rec but not gap
    # 上面锁结构加锁的详细信息(就是id = 1,15,20 的记录)
    Record lock, heap no 2 PHYSICAL RECORD: n_fields 5; compact format; info bits 00: len 4; hex 80000001; asc     ;;1: len 6; hex 00000001761e; asc     v ;;2: len 7; hex 3c000002c10110; asc <      ;;3: len 7; hex 6ce58898e5a487; asc l      ;;4: len 3; hex e89c80; asc    ;;Record lock, heap no 4 PHYSICAL RECORD: n_fields 5; compact format; info bits 00: len 4; hex 8000000f; asc     ;;1: len 6; hex 000000017634; asc     v4;;2: len 7; hex a90000011d0110; asc        ;;3: len 7; hex 78e88d80e5bda7; asc x      ;;4: len 3; hex e9ad8f; asc    ;;Record lock, heap no 10 PHYSICAL RECORD: n_fields 5; compact format; info bits 00: len 4; hex 80000014; asc     ;;1: len 6; hex 000000017642; asc     vB;;2: len 7; hex 30000001e81fb2; asc 0      ;;3: len 7; hex 73e5ad99e69d83; asc s      ;;4: len 3; hex e590b4; asc    ;;... 省略部分信息1 row in set (0.00 sec)

三、死锁

执行顺序事务 T1事务T2
1BEGIN;
2BEGIN;
3SELECT * FROM hero WHERE number = 1 FOR UPDATE;
4SELECT * FROM hero WHERE number = 3 FOR UPDATE;
5SELECT * FROM hero WHERE number = 1 FOR UPDATE; (阻塞)
6SELECT * FROM hero WHERE number = 1 FOR UPDATE;(阻塞)

上述流程比较清楚:

  1. 事务T1 获取到了 number = 1 的行锁,对该记录加了X 锁;
  2. 事务T2 获取到了 number = 3 的行锁,对该记录加了X 锁;
  3. 事务T1 获取 number = 3 的行锁,但是因为该行记录锁被 T2 持有因此陷入等待;
  4. 事务T2 获取 number = 1 的行锁,但是因为该行记录锁被 T1 持有因此陷入等待,陷入死锁。

InnoDB 有个死锁检测机制,当检测到死锁发生时,会选择一个较小的事务(在事务执行过程中插入、更新、删除记录条数更少的记录)进行回滚,并提示客户端信息:

Deadlock found when trying to get lock; try restarting transaction

可以通过 SHOW ENGINE INNODB STATUS 语句来查看最近发生的一次死锁信息,

SHOW ENGINE INNODB STATUS 只会显示最近一次发生的死锁信息,如果死锁频繁出现,可以将全局系统变量 innodb_print_all_deadlocks 设置为 ON,这样可以将死锁发生时的信息都记录在 MySQL 的错误日志中。

如下:

mysql> SHOW ENGINE INNODB STATUS\G
*************************** 1. row ***************************... 忽略部分信息# 最近一次死锁
------------------------
LATEST DETECTED DEADLOCK
------------------------
# 死锁发生时间, 0x3d08 是操作系统为当前会话分配的线程的线程编号。
2024-06-27 13:55:20 0x29ec
# 死锁发生的第一个事务的有关信息
*** (1) TRANSACTION:
# 为事务分配的id是 195635, 事务处于 ACTIVE 状态 7s了,事务当前做的操作是 " starting index read"
# 该事务的id 比第二个事务的id 小,也就说明当前事务是先执行的,即 事务 T1
TRANSACTION 195635, ACTIVE 7 sec starting index read
# 此事务当前执行的语句使用了一个表,为一个表上了锁
mysql tables in use 1, locked 1
# 此事务处于 LOCK WAIT 状态,拥有3个锁结构,2个行锁
LOCK WAIT 3 lock struct(s), heap size 1136, 2 row lock(s)
# 执行此事务的线程信息
MySQL thread id 22, OS thread handle 15624, query id 461 localhost ::1 root statistics
# 发生死锁时执行的语句
SELECT * FROM hero WHERE number = 3 FOR UPDATE
# 此事务当前在等待获取的锁
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 2432 page no 3 n bits 80 index PRIMARY of table `demo`.`hero` trx id 195635 lock_mode X locks rec but not gap waiting
Record lock, heap no 9 PHYSICAL RECORD: n_fields 5; compact format; info bits 00: len 4; hex 80000003; asc     ;;1: len 6; hex 00000001763c; asc     v<;;2: len 7; hex ad000001210110; asc     !  ;;3: len 10; hex 7ae8afb8e8919be4baae; asc z         ;;4: len 3; hex e89c80; asc    ;;# 死锁发生时第二个事务的信息
*** (2) TRANSACTION:
# 为事务分配的id是 195636, 事务处于 ACTIVE 状态 5s了,事务当前做的操作是 " starting index read"
# 该事务的id 比第一个事务的id 大,也就说明当前事务是后执行的, 也就是事务T2
TRANSACTION 195636, ACTIVE 5 sec starting index read, thread declared inside InnoDB 5000
# 此事务当前执行的语句使用了一个表,为一个表上了锁
mysql tables in use 1, locked 1
# 此事务拥有3个锁结构,2个行锁
3 lock struct(s), heap size 1136, 2 row lock(s)
# 执行此事务的线程信息
MySQL thread id 21, OS thread handle 10732, query id 460 localhost ::1 root statistics
# 发生死锁时执行的语句
SELECT * FROM hero WHERE number = 1 FOR UPDATE
# 此事务已经获取的锁
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 2432 page no 3 n bits 80 index PRIMARY of table `demo`.`hero` trx id 195636 lock_mode X locks rec but not gap
Record lock, heap no 9 PHYSICAL RECORD: n_fields 5; compact format; info bits 00: len 4; hex 80000003; asc     ;;1: len 6; hex 00000001763c; asc     v<;;2: len 7; hex ad000001210110; asc     !  ;;3: len 10; hex 7ae8afb8e8919be4baae; asc z         ;;4: len 3; hex e89c80; asc    ;;# 此事务等待的锁
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 2432 page no 3 n bits 80 index PRIMARY of table `demo`.`hero` trx id 195636 lock_mode X locks rec but not gap waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 5; compact format; info bits 00: len 4; hex 80000001; asc     ;;1: len 6; hex 00000001761e; asc     v ;;2: len 7; hex 3c000002c10110; asc <      ;;3: len 7; hex 6ce58898e5a487; asc l      ;;4: len 3; hex e89c80; asc    ;;# InnoDB 决定回滚 第二个事务
*** WE ROLL BACK TRANSACTION (2)... 忽略部分信息1 row in set (0.00 sec)

四、参考内容

书籍:《MySQL是怎样运行的——从根儿上理解MySQL》、《MySQL技术内幕 InnoDB存储引擎 》
https://blog.csdn.net/filling_l/article/details/112854716

如有侵扰,联系删除。 内容仅用于自我记录学习使用。如有错误,欢迎指正

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1522646.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Android之Handler的post方法和sendMessage的区别

目录 post 方法方法特点 sendMessage 方法方法特点 使用场景区别总结 Handler 类在 Android 中用于在不同线程之间传递消息和执行代码。它提供了两种主要的方式来执行任务&#xff1a;通过 post 方法和通过 sendMessage 方法。这两种方法有不同的使用场景和特点。 post 方法 方…

浅谈架构实战

目录 背景 1 架构演变 2 如何实现高层的复用 2 中台产生案例 3 技术架构的核心要点 4 技术架构的高可用案例 背景 业务架构、数据架构、应用架构和技术架构它们是相互关联和相互支持的&#xff0c;共同构成了企业的总体架构&#xff0c;业务架构是源头&#xff0c;然后才…

自动生成对话视频!如何使用Captions的AI视频生成与编辑API工具?

Captions公司最近发布了一套AI驱动的视频生成和编辑API工具&#xff0c;为创作者和开发者提供了一个强大的视频创作生态系统。这个系统包含AI Creator、AI Twin、AI Edit、和AI Translate四大核心功能&#xff0c;每个工具都针对不同的创作需求进行优化。下面我们就一起来详细测…

第九周:机器学习

目录 摘要 Abstract 一、RNN 1、引入 2、RNN的分类 二、LSTM 1、基本结构 2、具体步骤 3、举例说明 4、原理理解 总结 摘要 本周主要围绕RNN进行探讨&#xff0c;从为什么需要这类”循环网络“入手&#xff0c;提到了”slot filling“技术&#xff0c;接着又对R…

AT3340:支持BDS/GPS双模授时板数据手册

AT3340采用ATGM331C-5T31授时模块&#xff0c;是高授时精度的BDS/GPS双模接收机板卡&#xff0c;包含32个跟踪通道&#xff0c;支持GPS和BDS的单系统授时定位和双系统联合授时定位&#xff0c;可以通过上位机命令切换。其中的射频前端芯片和基带芯片全部由杭州中科微独立研发&a…

RAG数据集自动构造探索, 附prompt

从文档中手动创建数百个 QA&#xff08;问题-上下文-答案&#xff09;样本可能非常耗时且劳动密集。此外&#xff0c;人工生成的问题可能难以达到全面评估所需的复杂程度&#xff0c;最终影响评估的质量。通过使用合成数据生成&#xff0c;开发人员在数据聚合过程中的时间可以减…

嵌入式Linux:常见信号的默认行为

信号是一种软件中断&#xff0c;用于通知进程发生了某种异步事件。信号可以由用户、其他进程或操作系统内核产生。进程可以选择捕获并处理这些信号&#xff0c;或者忽略它们&#xff0c;让系统执行默认操作。 不可靠信号&#xff08;非实时信号&#xff09;&#xff1a;编号为 …

观测云核心技术解密:eBPF Tracing 实现原理

前言 eBPF 是一种强大的内核技术&#xff0c;允许在内核中安全地执行自定义代码。通过 eBPF&#xff0c;开发者可以在不修改内核源码的情况下&#xff0c;对内核功能进行扩展和监控。eBPF Tracing 利用这一技术&#xff0c;对系统调用、内核函数等进行跟踪&#xff0c;从而实现…

【IPV6从入门到起飞】2-1 获取你的IPV6(手机、CPE等)

【IPV6从入门到起飞】2-1 获取你的IPV6&#xff08;手机、CPE等&#xff09; 1 IPV6就在身边2 手机IPV62.1 查看IPV62.2 IPV6 ping包测试2.3 IPV6入站测试 3 电脑通过CPE获取IPV63.1 拉不起宽带的打工人3.2 开始部署IPV6环境3.2.1 刷系统3.2.2 激活IPV63.2.3 设置防火墙入站&am…

JAVA - 关于防重复提交探讨

1、前端提交按钮做单次点击 2、后端接收判断请求的数据包&#xff0c;生成唯一key存redis&#xff0c;设置几秒的过期时间&#xff08;缺陷&#xff1a;带时间戳的数据&#xff0c;需要做些逻辑判断&#xff09; 3、后端代码逻辑redis分布式锁&#xff08;缺陷&#xff1a;re…

P01-Java何谓数组

P01-Java何谓数组 一、数组声明创建 1.1 数组声明的语法 与c有所不同 在Java中&#xff0c;数组声明语法 首选语法&#xff1a; //数据类型[] 数组名称; int[] arr;次选&#xff0c;与c类似 //数据类型 数组名称[]; int arr[];1.2 数组创建语法 与c指针有所相似&#xff0…

从源码开始:打造智能化食堂采购与供应链管理平台

随着食堂规模的扩大和供应链的复杂化&#xff0c;这些问题更加突出。智能化的食堂采购平台可以通过自动化流程、数据分析和智能推荐&#xff0c;显著提高采购效率&#xff0c;减少浪费&#xff0c;并降低运营成本。 要打造这样一个平台&#xff0c;首先需要对食堂的日常运营需…

Python基础语法(多进程开发进程建数据共享进程锁进程池)

Python基础语法文章导航&#xff1a; Python基础&#xff08;01初识数据类型&变量&#xff09;Python基础&#xff08;02条件&循环语句&#xff09;Python基础&#xff08;03字符串格式化&运算符&进制&编码&#xff09;Python基础&#xff08;04 基础练习…

【MATLAB源码-第259期】基于matlab的64QAM调制解调锁相环环载波同步仿真,对比前后星座图,输出锁相环响应曲线。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 1. 概述 在现代数字通信系统中&#xff0c;为了提高频谱利用率和数据传输效率&#xff0c;经常采用多阶调制技术。64QAM&#xff08;64阶正交幅度调制&#xff09;便是其中的一种&#xff0c;它通过将数据映射到64个不同的复…

入门篇 LeetCode算法之旅启程 - 从零开始的编程进阶之路

你是否曾经在技术面试中因为算法题而汗流浃背?是否在日常编码中感觉自己的解决问题能力有待提高? 目录 LeetCode: 你的算法训练场为什么选择LeetCode?LeetCode平台使用指南1. 注册与登录2. 探索题库3. 解题过程4. 提交与反馈5. 学习与讨论6. 追踪进度7. 参与竞赛 制定你的…

【专项刷题】— 哈希表

1、两数之和 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 使用哈希表&#xff0c;将每次x target - nums[i]&#xff0c;查看哈希表中是否含有这个x值代码&#xff1a; public int[] twoSum(int[] nums, int target) {int n nums.length;Map<Integer,Inte…

坐牢第三十四天(c++)

一.作业 1.栈的手写 #include <iostream> using namespace std; // 封装一个栈 class stcak { private:int *data; //int max_size; // 最大容量int top; // 下标 public:// 无参构造函数stcak();// 有参构造函数stcak(int size);// 拷贝构造函数stcak(const s…

0903作业+思维导图

一、作业 1》多态的实现 1、代码 #include <iostream>using namespace std; //父类 class Person { public:string name;int age; public:Person(){}Person(string n,int a):name(n),age(a){}~Person(){}//纯虚函数virtual void show() 0; }; //子类1 class Stu:publ…

wsl下将Ubuntu从c盘移动到其他盘

一、概述 因为自己的C盘内存不足&#xff0c;加上之后需要在Ubuntu下面下载许多的内容和东西&#xff0c;需要将其移动到d盘上面&#xff0c;这样可以拥有更大的空间。这里记载了一下自己的操作过程。 二、具体步骤 &#xff08;一&#xff09;过程 1.查看当前系统中wsl分发版…

Haskell爬虫:连接管理与HTTP请求性能

爬虫技术作为数据抓取的重要手段&#xff0c;其效率和性能直接影响到数据获取的质量与速度。Haskell&#xff0c;作为一种纯函数式编程语言&#xff0c;以其强大的类型系统和并发处理能力&#xff0c;在构建高效爬虫方面展现出独特的优势。本文将探讨在Haskell中如何通过连接管…