MYSQL批量插入并发场景下的DEADLOCK

news2024/11/18 6:20:32

一、背景

公元2023-10-12(周四)上午,组内的亚梅反馈,用户生成标签报死锁异常

二、排查异常日志

查到当时报错的日志

具体异常信息如下

server-provider-info-2023-10-12.0.log:2023-10-12 09:40:50.593 [TID:bf623bded189486cbb0b6a64d81b64b4.357.16970748504097047] [4ed7b7943a8a47de912e4b644d70285e] [SimpleAsyncTaskExecutor-5080] INFO  com.emax.user.user.provider.UserTagAPIImpl:? - 签约完成,更新用户标签信息异常,用户id[1712282059297107970]org.apache.ibatis.exceptions.PersistenceException:
server-provider-info-2023-10-12.0.log-### Error flushing statements.  Cause: org.apache.ibatis.executor.BatchExecutorException: com.emax.user.user.mapper.UserTagMapper.insert (batch index #1) failed. Cause: java.sql.BatchUpdateException: Deadlock found when trying to get lock; try restarting transaction
server-provider-info-2023-10-12.0.log-### Cause: org.apache.ibatis.executor.BatchExecutorException: com.emax.user.user.mapper.UserTagMapper.insert (batch index #1)failed. Cause: java.sql.BatchUpdateException: Deadlock found when trying to get lock; try restarting transaction
server-provider-info-2023-10-12.0.log-  at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
server-provider-info-2023-10-12.0.log-  at org.apache.ibatis.session.defaults.DefaultSqlSession.flushStatements(DefaultSqlSession.java:254)
server-provider-info-2023-10-12.0.log-  at com.baomidou.mybatisplus.extension.service.impl.ServiceImpl.saveBatch(ServiceImpl.java:127)
server-provider-info-2023-10-12.0.log-  at com.baomidou.mybatisplus.extension.service.IService.saveBatch(IService.java:58)
server-provider-info-2023-10-12.0.log-  at com.baomidou.mybatisplus.extension.service.IService$$FastClassBySpringCGLIB$$f8525d18.invoke(<generated>)
server-provider-info-2023-10-12.0.log-  at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
server-provider-info-2023-10-12.0.log-  at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749)
server-provider-info-2023-10-12.0.log-  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
server-provider-info-2023-10-12.0.log-  at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
server-provider-info-2023-10-12.0.log-  at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
server-provider-info-2023-10-12.0.log-  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
server-provider-info-2023-10-12.0.log-  at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
server-provider-info-2023-10-12.0.log-  at com.emax.user.user.service.UserTagManager$$EnhancerBySpringCGLIB$$67ca0067.saveBatch(<generated>)
server-provider-info-2023-10-12.0.log-  at com.emax.user.user.provider.UserTagAPIImpl.addUserTagByUser(UserTagAPIImpl.java:236)
server-provider-info-2023-10-12.0.log-  at com.emax.user.user.provider.UserTagAPIImpl.addTagAfterSign(UserTagAPIImpl.java:116)
server-provider-info-2023-10-12.0.log-  at com.emax.user.user.provider.UserTagAPIImpl$$FastClassBySpringCGLIB$$2547ce26.invoke(<generated>)
server-provider-info-2023-10-12.0.log-  at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
server-provider-info-2023-10-12.0.log-  at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749)
--
server-provider-info-2023-10-12.0.log-  at io.seata.rm.datasource.StatementProxy.lambda$executeBatch$9(StatementProxy.java:129)
server-provider-info-2023-10-12.0.log-  at io.seata.rm.datasource.exec.ExecuteTemplate.execute(ExecuteTemplate.java:73)
server-provider-info-2023-10-12.0.log-  at io.seata.rm.datasource.exec.ExecuteTemplate.execute(ExecuteTemplate.java:51)
server-provider-info-2023-10-12.0.log-  at io.seata.rm.datasource.StatementProxy.executeBatch(StatementProxy.java:129)
server-provider-info-2023-10-12.0.log-  at sun.reflect.GeneratedMethodAccessor1346.invoke(Unknown Source)
server-provider-info-2023-10-12.0.log-  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
server-provider-info-2023-10-12.0.log-  at java.lang.reflect.Method.invoke(Method.java:498)
server-provider-info-2023-10-12.0.log-  at org.apache.ibatis.logging.jdbc.PreparedStatementLogger.invoke(PreparedStatementLogger.java:78)
server-provider-info-2023-10-12.0.log-  at com.sun.proxy.$Proxy501.executeBatch(Unknown Source)
server-provider-info-2023-10-12.0.log-  at com.baomidou.mybatisplus.core.executor.MybatisBatchExecutor.doFlushStatements(MybatisBatchExecutor.java:132)
server-provider-info-2023-10-12.0.log-  ... 71 common frames omitted
server-provider-info-2023-10-12.0.log-Caused by: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
server-provider-info-2023-10-12.0.log-  at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:123)
server-provider-info-2023-10-12.0.log-  at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
server-provider-info-2023-10-12.0.log-  at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
server-provider-info-2023-10-12.0.log-  at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:970)
server-provider-info-2023-10-12.0.log-  at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1109)
server-provider-info-2023-10-12.0.log-  at com.mysql.cj.jdbc.ClientPreparedStatement.executeBatchSerially(ClientPreparedStatement.java:849)
server-provider-info-2023-10-12.0.log-  ... 89 common frames omitted
server-provider-info-2023-10-12.0.log-

三、代码所在地

查看发生Deadlock的代码现场。

代码如下:

    /**
     * 增加用户标签
     * @param user 用户信息
     * @param tagNameList 标签集合
     */
    private void addUserTagByUser(User user, List<String> tagNameList){
        log.info("用户添加标签入参信息,当前用户id[{}],标签信息[{}]", user.getUserId(), JSON.toJSONString(tagNameList));
        Set<String> existTags = new HashSet<>();
        final List<UserTag> userTagList = userTagManager.listUserTagByUserId(user.getUserId());
        if(CollectionUtils.isNotEmpty(userTagList)){
            existTags = userTagList.stream().map(UserTag::getTagName).collect(Collectors.toSet());
        }
        //遍历合集 如果不存在旧数据 直接都新增 存在 判断当前数据是否在旧数据中
        List<UserTag> newInsertList = new ArrayList<>();
        for(String name : tagNameList){
            if (StringUtils.isNotBlank(name) && existTags.add(name)) {
                newInsertList.add(userTagManager.buildEntity(user.getUserId(), user.getIdcardNo(), name));
            }
        }
        userTagManager.saveBatch(newInsertList);
    }

观察代码,大致逻辑是,先根据用户id查询出所有标签信息,计算出来需要新增的用户标签,批量入库。其中,user_tag表存储用户的标签数据。两个关键字段 user_id(用户id)和tag_name(标签)上面具有唯一索引,插入的数据也主要是这两个字段。

从这段代码并不容易判断出来如何会产生死锁。推测是多个线程同时操作相同的数据,并发插入导致的死锁。

四、并发操作日志

elk上查询方法入参日志。果然在发生异常的时间节点上,发现了两条插入相同数据的日志。相同时间点,两个traceId,可见当时发生了并发调用。

找到当时另一个线程的操作日志,日志无异常,数据入库成功。见下面截图。

五、数据库死锁日志验证推测

当天下午上班后,找运维大哥帮忙,找出死锁日志

执行命令 show ENGINE INNODB status 

得到信息如下

=====================================
2023-10-12 13:49:17 0x7fea5ae87700 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 61 seconds
-----------------
BACKGROUND THREAD
-----------------
srv_master_thread loops: 3123131 srv_active, 0 srv_shutdown, 7715544 srv_idle
srv_master_thread log flush and writes: 10838675
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 3905404
OS WAIT ARRAY INFO: signal count 27617015
RW-shared spins 0, rounds 21456656, OS waits 2772950
RW-excl spins 0, rounds 41132727, OS waits 487320
RW-sx spins 227170, rounds 4363782, OS waits 66152
Spin rounds per wait: 21456656.00 RW-shared, 41132727.00 RW-excl, 19.21 RW-sx
------------------------
LATEST DETECTED DEADLOCK
------------------------
2023-10-12 09:40:50 0x7fecedb1e700
*** (1) TRANSACTION:
TRANSACTION 404898333, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 1136, 1 row lock(s), undo log entries 1
MySQL thread id 11375251, OS thread handle 140644580488960, query id 1031478425 10.128.0.160 emax_base update
INSERT INTO emax_user_tag  ( user_id,
id_card_no,
tag_name,
create_time,
update_time )  VALUES  ( 1712282059297107970,
'A978B69811B82F4B08F929D26B360F2D980CDCB5F419F1DD46527FB90BE1E5A9',
'市场推广',
'2023-10-12 09:40:50.481',
'2023-10-12 09:40:50.481' )
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 1155 page no 65295 n bits 312 index uniq_user_id_tag_name of table `emax_base`.`emax_user_tag` trx id 404898333 lock mode S waiting
Record lock, heap no 242 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 8; hex 97c33f75fbadb002; asc   ?u    ;;
 1: len 12; hex e5b882e59cbae68ea8e5b9bf; asc             ;;
 2: len 8; hex 000000000044c0da; asc      D  ;;

*** (2) TRANSACTION:
TRANSACTION 404898332, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1
3 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 2
MySQL thread id 11375224, OS thread handle 140655576868608, query id 1031478426 10.128.0.160 emax_base update
INSERT INTO emax_user_tag  ( user_id,
id_card_no,
tag_name,
create_time,
update_time )  VALUES  ( 1712282059297107970,
'A978B69811B82F4B08F929D26B360F2D980CDCB5F419F1DD46527FB90BE1E5A9',
'信息技术服务',
'2023-10-12 09:40:50.481',
'2023-10-12 09:40:50.481' )
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 1155 page no 65295 n bits 312 index uniq_user_id_tag_name of table `emax_base`.`emax_user_tag` trx id 404898332 lock_mode X locks rec but not gap
Record lock, heap no 242 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 8; hex 97c33f75fbadb002; asc   ?u    ;;
 1: len 12; hex e5b882e59cbae68ea8e5b9bf; asc             ;;
 2: len 8; hex 000000000044c0da; asc      D  ;;

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 1155 page no 65295 n bits 312 index uniq_user_id_tag_name of table `emax_base`.`emax_user_tag` trx id 404898332 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 242 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 8; hex 97c33f75fbadb002; asc   ?u    ;;
 1: len 12; hex e5b882e59cbae68ea8e5b9bf; asc             ;;
 2: len 8; hex 000000000044c0da; asc      D  ;;

*** WE ROLL BACK TRANSACTION (1)

此处省略掉若干非关键信息行 ---------------------------- END OF INNODB MONITOR OUTPUT ============================

该日志信息量很多,已省略掉若干非关键信息行,我们主要关注最后一次死锁相关信息。

六、死锁复现

sql准备

INSERT INTO emax_user_tag ( user_id, id_card_no, tag_name, create_time, update_time ) VALUES ( 1712282059297107970, 'A978B69811B82F4B08F929D26B360F2D980CDCB5F419F1DD46527FB90BE1E5A9', '市场推广', '2023-10-12 09:40:50.481', '2023-10-12 09:40:50.481' );

INSERT INTO emax_user_tag ( user_id, id_card_no, tag_name, create_time, update_time ) VALUES ( 1712282059297107970, 'A978B69811B82F4B08F929D26B360F2D980CDCB5F419F1DD46527FB90BE1E5A9', '信息技术服务', '2023-10-12 09:40:50.481', '2023-10-12 09:40:50.481' );

本地创建一个和生产一样的数据库emax_user_tag,同样,在user_id和tag_name两个字段上创建唯一索引。

操作步骤1

在窗口一执行

begin;

INSERT INTO emax_user_tag ( user_id, id_card_no, tag_name, create_time, update_time ) VALUES ( 1712282059297107970, 'A978B69811B82F4B08F929D26B360F2D980CDCB5F419F1DD46527FB90BE1E5A9', '市场推广', '2023-10-12 09:40:50.481', '2023-10-12 09:40:50.481' );

操作步骤2

在窗口二执行

begin;

INSERT INTO emax_user_tag ( user_id, id_card_no, tag_name, create_time, update_time ) VALUES ( 1712282059297107970, 'A978B69811B82F4B08F929D26B360F2D980CDCB5F419F1DD46527FB90BE1E5A9', '市场推广', '2023-10-12 09:40:50.481', '2023-10-12 09:40:50.481' );

操作步骤3

在窗口一执行

INSERT INTO emax_user_tag ( user_id, id_card_no, tag_name, create_time, update_time ) VALUES ( 1712282059297107970, 'A978B69811B82F4B08F929D26B360F2D980CDCB5F419F1DD46527FB90BE1E5A9', '信息技术服务', '2023-10-12 09:40:50.481', '2023-10-12 09:40:50.481' );

commit;

操作步骤4

切回窗口二

操作步骤5

执行命令 show ENGINE INNODB status 查看死锁日志。与上面的情况一样。

=====================================
2023-10-13 14:52:43 0x7fe759575700 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 24 seconds
-----------------
BACKGROUND THREAD
-----------------
srv_master_thread loops: 137590 srv_active, 0 srv_shutdown, 2010475 srv_idle
srv_master_thread log flush and writes: 2148065
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 6627679
OS WAIT ARRAY INFO: signal count 14339066
RW-shared spins 0, rounds 22104735, OS waits 1859432
RW-excl spins 0, rounds 258795010, OS waits 2238669
RW-sx spins 6551822, rounds 136672247, OS waits 1786313
Spin rounds per wait: 22104735.00 RW-shared, 258795010.00 RW-excl, 20.86 RW-sx
------------------------
LATEST DETECTED DEADLOCK
------------------------
2023-10-13 14:50:31 0x7fe892ad0700
*** (1) TRANSACTION:
TRANSACTION 293171186, ACTIVE 10 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 1136, 1 row lock(s), undo log entries 1
MySQL thread id 1266048, OS thread handle 140631613069056, query id 35172347 192.168.48.179 develop update
/* ApplicationName=DBeaver 22.2.1 - SQLEditor <Script-4.sql> */ INSERT INTO emax_user_tag ( user_id, id_card_no, tag_name, create_time, update_time ) VALUES ( 1712282059297107970, 'A978B69811B82F4B08F929D26B360F2D980CDCB5F419F1DD46527FB90BE1E5A9', '市场推广', '2023-10-12 09:40:50.481', '2023-10-12 09:40:50.481' )
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 14171 page no 4 n bits 72 index user_id_tag_name of table `dbsyncer_mf`.`emax_user_tag` trx id 293171186 lock mode S waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 8; hex 97c33f75fbadb002; asc   ?u    ;;
 1: len 12; hex e5b882e59cbae68ea8e5b9bf; asc             ;;
 2: len 8; hex 80000000000358d0; asc       X ;;

*** (2) TRANSACTION:
TRANSACTION 293171182, ACTIVE 19 sec inserting
mysql tables in use 1, locked 1
3 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 2
MySQL thread id 1266036, OS thread handle 140636869953280, query id 35172492 192.168.48.179 develop update
/* ApplicationName=DBeaver 22.2.1 - SQLEditor <Script-1.sql> */ INSERT INTO emax_user_tag ( user_id, id_card_no, tag_name, create_time, update_time ) VALUES ( 1712282059297107970, 'A978B69811B82F4B08F929D26B360F2D980CDCB5F419F1DD46527FB90BE1E5A9', '信息技术服务', '2023-10-12 09:40:50.481', '2023-10-12 09:40:50.481' )
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 14171 page no 4 n bits 72 index user_id_tag_name of table `dbsyncer_mf`.`emax_user_tag` trx id 293171182 lock_mode X locks rec but not gap
Record lock, heap no 2 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 8; hex 97c33f75fbadb002; asc   ?u    ;;
 1: len 12; hex e5b882e59cbae68ea8e5b9bf; asc             ;;
 2: len 8; hex 80000000000358d0; asc       X ;;

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 14171 page no 4 n bits 72 index user_id_tag_name of table `dbsyncer_mf`.`emax_user_tag` trx id 293171182 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 8; hex 97c33f75fbadb002; asc   ?u    ;;
 1: len 12; hex e5b882e59cbae68ea8e5b9bf; asc             ;;
 2: len 8; hex 80000000000358d0; asc       X ;;

*** WE ROLL BACK TRANSACTION (1)
View Code

七、死锁分析

根据死锁日志进行分析。

执行操作步骤一时:

事务一   获取到了插入意向锁

执行操作步骤二时:

事务二  将事务的意向锁升级为唯一索引排他锁,并且尝试获取唯一索引共享锁(还没有获得共享锁,排队中)

执行操作步骤三时:

事务一 尝试获取插入意向间隙锁

事务二等待事务一释放排他锁

事务一等待事务二释放共享锁

形成相互等待关系,死锁。

八、总结归纳

1.批量插入操作尽量保证数据有序性

2.可借助性能更高的redis进行并发拦截 或 同步处理控制

3.将参数 innodb_deadlock_detect 设置为 on,死锁时会进行回滚(数据库默认开启)

4.业务代码需要考虑数据库异常

5.当前mysql数据库版本是5.7.28-log。经细心的红洁同学验证,mysql-8.0版本针对这个场景做了优化,不会发生死锁。

文献参考 https://blog.csdn.net/minghao0508/article/details/129093202

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

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

相关文章

【C语言】memmove()函数(拷贝重叠内存块函数详解)

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:C语言 ⚙️操作环境:Visual Studio 2022 目录 一.memmove()函数简介 1.函数功能 2.函数参数 1>.void * destination 2>.onst void * source 3>.size_t num 3.函数返回值 4.函数头文件 二.memmove()函数…

【爬虫】charles手机抓包环境设置(设置系统证书)

1.说明 想要对手机抓包&#xff0c;最关键的是需要设置好根证书&#xff0c;用户证书在安卓7.0之后就不受信任了&#xff0c;想要对手机app抓包&#xff0c;就需要把用户证书设置为系统证书&#xff08;根证书&#xff09; 注意&#xff0c;想要设置为根证书&#xff0c;你的…

JavaScrip的DOM接口

JavaScript的DOM&#xff08;Document Object Model&#xff09;是一种接口&#xff0c;它允许程序和脚本动态地访问和更新文档的内容、结构和样式。DOM是一种将HTML或XML文档表示为对象树的标准方式。 在JavaScript中&#xff0c;DOM提供了一种方式来操作HTML或XML文档的元素…

基于nodejs+vue人脸识别考勤管理系统的设计与实现

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

unocss和tailwindcss css原子引擎

第一种tailwindcss&#xff1a; tailwindcss官网 https://tailwindcss.com/docs/grid-column 基本介绍及优点分析 Tailwind CSS 中文文档 - 无需离开您的HTML&#xff0c;即可快速建立现代网站 PostCss 处理 Tailwind Css 基本流程 PostCSS - 是一个用 JavaScript 工具和插…

分享Keil5设置忽略编译过程中的警告

Keil5忽略编译过程中的警告 分享Keil5设置忽略编译过程中的警告 分享Keil5设置忽略编译过程中的警告 加上这段字符就好了 --diag_suppress68 --diag_suppress111 --diag_suppress188 --diag_suppress223 --diag_suppress546 --diag_suppress1295实测有效

Vue3-02_Vue基础入门

背景 这里&#xff0c;跟vue官网的介绍章节稍有差异。官网上侧重组件原理&#xff0c;从浅到深介绍各种组件。后续是系统生态。 教程上更偏路线化&#xff0c;需要用到的优先讲解。完成综合案例。所以我主要按照教程的思路来进行学习。 ◆ 能够知道 vue 的基本使用步骤 ◆ 掌…

知识图谱相关的操作

微软生成自己的图谱&#xff1a;GitHub - microsoft/SmartKG: This project accepts excel files as input which contains the description of a Knowledge Graph (Vertexes and Edges) and convert it into an in-memory Graph Store. This project implements APIs to searc…

SSH安全登录远程主机

SSH服务器简介 SSH即Security SHell的意思&#xff0c;它可以将连线的封包进行加密技术&#xff0c;之后进行传输&#xff0c;因此相当的安全。 SSH是一种协议标准&#xff0c;其目的是实现安全远程登录以及其它安全网络服务。 SSH协定&#xff0c;在预设的状态下&#xff0c;…

计算机网络重点概念整理-第一章 计算机网络概述【期末复习|考研复习】

第一章 计算机网络概述 【期末复习|考研复习】 计算机网络系列文章传送门&#xff1a; 第一章 计算机网络概述 第二章 物理层 第三章 数据链路层 第四章 网络层 第五章 传输层 第六章 应用层 第七章 网络安全 计算机网络整理-简称&缩写 文章目录 第一章 计算机网络概述 【…

微信小程序之投票管理

前言 对于会议管理模块&#xff0c;必不可少的当然就是我们的投票管理&#xff0c;实现真正意义上的无纸化办公&#xff0c;本期博客为大家介绍会议管理模块&#xff0c;包括发布投票及查看各类投票的状态 所用技术点 MyBatis、SpringMVC、VentUI MyBatis和SpringMVC在博客主…

PyCharm社区版安装

PyCharm社区版安装 到中国官网下载 https://www.jetbrains.com/zh-cn/pycharm/download/?sectionwindows 首次创建项目&#xff0c;会自动下载安装Python 3.9 社区版的区别 社区版的区别

Vue项目搭建及使用vue-cli创建项目、创建登录页面、与后台进行交互,以及安装和使用axios、qs和vue-axios

目录 1. 搭建项目 1.1 使用vue-cli创建项目 1.2 通过npm安装element-ui 1.3 导入组件 2 创建登录页面 2.1 创建登录组件 2.2 引入css&#xff08;css.txt&#xff09; 2.3 配置路由 2.5 运行效果 3. 后台交互 3.1 引入axios 3.2 axios/qs/vue-axios安装与使用 3.2…

【微信小程序】发布投票与用户投票完整讲解

目录 前言 组件功能示例 一、数据库 二、后端接口定义 三、前端准备 3.1 定义连接接口 3.2 Vant Weapp UI 组件库 3.3 授权登录与相关工具 四、小程序编写 4.1 投票组件 WXML WXSS JSON WXJS 效果展示讲解&#xff1a; 4.2 发布投票组件 WXML WXSS JSON WX…

线扫相机DALSA--采集卡Base模式设置

采集卡默认加载“1 X Full Camera Link”固件&#xff0c;Base模式首先要将固件更新为“2 X Base Camera Link”。 右键SCI图标&#xff0c;选择“打开文件所在的位置”&#xff0c;找到并打开SciDalsaConfig的Demo&#xff0c;如上图所示&#xff1a; 左键单击“获取相机”&a…

生成的二维码如何解析出原来的地址?

生成的二维码如何解析出原来的地址&#xff1f; 随着移动互联网的发展&#xff0c;二维码作为一种快速获取信息的方式&#xff0c;在我们的生活中越来越常见。而PHP作为Web语言之一&#xff0c;也有着二维码解码的功能。 PHP中有着众多的二维码解码库&#xff0c;例如&#x…

前端将图片储存table表格中,页面回显

<el-table :data"tableData" v-loading"loading" style"width: 100%" height"calc(100vh - 270px)" :size"tableSize"row-dblclick"enterClick"><el-table-column prop"name" label"文档…

代码随想录Day30 贪心05 LeetCode T435无重叠区间 T763划分字母区间 T56 合并区间

LeetCode T435 无重叠区间 题目链接:435. 无重叠区间 - 力扣&#xff08;LeetCode&#xff09; 题目思路: 这题思路和昨天的打气球类似,我们需要按照左区间或者右区间进行排序,然后哦判断第i个区间的左端点和第i-1个区间的右端点的大小关系,,如果大于等于,那么就无需操作,一旦…

一文搞懂 MineCraft 服务器启动操作和常见问题 2023年10月

文章目录 前言1. 新建文件夹2. 创建 bat 文件3. 编辑 bat 文件4. 启动服务器5. 恭喜完成 文章持续更新中&#xff0c;如果你有问题可以通过 qq 1317699264 获取免费协助&#xff0c;解决的问题将会被更新到本文章中 前言 无论你是使用服务端整合包&#xff0c;还是从上一篇我的…

3.线性神经网络

#pic_center R 1 R_1 R1​ R 2 R^2 R2 目录 知识框架No.1 线性回归基础优化算法一、线性回归1、买房案例2、买房模型简化3、线性模型4、神经网络5、损失函数6、训练数据7、参数学习8、显示解9、总结 二、 基础优化算法1、梯度下降2、学习率3、小批量随机梯度下降4、批量大小5、…