做cpa用单页网站好还是/免费推广网站推荐
1、为什么要使用分布式锁
- 锁是多线程代码中的概念,只有多任务访问同一个互斥的共享资源时才需要锁。
- 单机应用开发时一般使用synchronized或lock。多线程的运行都是在同一个JVM之下。
- 应用是分布式集群,属于多JVM的工作环境,JVM之间已经无法通过多线程的锁解决同步问题。
2、分布式锁的几种方式
分布式锁的核心思路是借助外力 解决多JVM进程操作共享数据时需要使用互斥锁的问题。
常见的方式 有:
- mysql数据库分布式锁
- zookeeper分布式锁
- redis分布式锁
3、搭建测试分布式锁的环境
【1】创建工程distributed-lock-study ,pom如下
父工程
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.6</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.lyx</groupId><artifactId>distributed-lock-study</artifactId><version>0.0.1-SNAPSHOT</version><packaging>pom</packaging><name>distributed-lock-study</name><description>distributed-lock-study</description><modules><module>moduleA</module><module>moduleB</module></modules><properties><java.version>8</java.version><dubbo.starter>2.7.6</dubbo.starter><dubbo.registry.zookeeper>2.7.6</dubbo.registry.zookeeper><mysql-connection.version>8.0.26</mysql-connection.version><druid.version>1.2.1</druid.version><mybatis-plus.version>3.5.2</mybatis-plus.version><hutool.version>5.7.17</hutool.version></properties>
<dependencyManagement><dependencies><!-- Dubbo 依赖 --><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</artifactId><version>${dubbo.starter}</version></dependency><!-- zookeeper 注册中心 依赖 --><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-registry-zookeeper</artifactId><version>${dubbo.registry.zookeeper}</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql-connection.version}</version><scope>runtime</scope></dependency><!--druid连接池--><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>${druid.version}</version></dependency><!--mybatis-plus依赖--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>${mybatis-plus.version}</version></dependency><!--hutool--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>${hutool.version}</version></dependency></dependencies></dependencyManagement></project>
【2】创建moduleA和moduleB两个模块
依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.lyx</groupId><artifactId>distributed-lock-study</artifactId><version>0.0.1-SNAPSHOT</version></parent><groupId>org.example</groupId><artifactId>moduleA</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--mybatis-plus依赖--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><!--druid连接池--><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId></dependency><!--redis依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!--common-pool--><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId></dependency><!-- Redisson分布式锁使用--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.14.0</version></dependency><!--基于Curator 客户端(zookeeper的)实现分布式锁 --><dependency><groupId>org.apache.curator</groupId><artifactId>curator-framework</artifactId><version>4.0.1</version></dependency><dependency><groupId>org.apache.curator</groupId><artifactId>curator-recipes</artifactId><version>4.0.1</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>
【3】在两个模块中编写application.yml
spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/lock_db?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghaiusername: rootpassword: 123456redis:host: 192.168.184.200port: 6379lettuce:pool:max-active: 8max-idle: 8min-idle: 0max-wait: 100ms
server:port: 1111 # 两个模块的端口号不一样,其他一样
【4】编写启动类
@SpringBootApplication
@MapperScan("top.psjj.ma.mapper")
public class ModuleAApplication {public static void main(String[] args) {SpringApplication.run(ModuleAApplication.class,args);}
}
【5】准备数据库local_db,并出入下张表
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for t_goods
-- ----------------------------
DROP TABLE IF EXISTS `t_goods`;
CREATE TABLE `t_goods` (`id` int(0) NOT NULL AUTO_INCREMENT COMMENT '主键',`goods` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL,`count` int(0) NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of t_goods
-- ----------------------------
INSERT INTO `t_goods` VALUES (1, '手机', -1);
INSERT INTO `t_goods` VALUES (2, '笔记本', 100);SET FOREIGN_KEY_CHECKS = 1;
【6】编写po 、mapper 、service 、controller,两个模块代码完全一样
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("t_goods")
public class Goods implements Serializable {@Serialprivate static final long serialVersionUID = -9084934747907815210L;@TableId(type = IdType.AUTO)private Integer id;private String goods;private Integer count;
}
public interface GoodsMapper extends BaseMapper<Goods> {@Update("update t_goods set count = count-1 where id=#{id}")void subCount(Integer id);
}
public interface GoodsService extends IService<Goods> {void updateGoodsCount(Integer id);
}
@Service
public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements GoodsService {@Overridepublic void updateGoodsCount(Integer id) {Goods goods = this.baseMapper.selectById(id);Integer count = goods.getCount();if(count>0){try {Thread.sleep(5000);} catch (InterruptedException e) {throw new RuntimeException(e);}this.baseMapper.subCount(id);}}
}
@RestController
@RequestMapping("/goods")
public class GoodsController {@Autowiredprivate GoodsService goodsService;@RequestMapping("/update")public String updateGoodsCount(Integer id){goodsService.updateGoodsCount(id);return "ok";}
}
4、基于Mysql实现的分布式锁
4.1 mysql实现分布式锁原理
- 首先单独分离出一台mysql数据库,所有服务要想操作文件(共享资源),那么必须先在mysql数据库中插入一个标志,插入标志的服务就持有了锁,并对文件进行操作 。
- 操作完成后,主动删除标志进行锁释放,其余服务会一直查询数据库,看是否标志有被占用,直到没有标志占用时自己才能写入标志获取锁。
4.2 问题
- 如果服务(jvm1)宕机或者卡顿了,会一直持有锁未释放,造成死锁。因此需要一个监视锁进程,时刻监视锁的状态,如果超过一定时间未释放就要进行主动清理锁标记,然后供其他服务继续获取锁。
- 如果监视锁字段进程和jvm1同时挂掉,依旧不能解决死锁问题,于是又增加一个监视锁字段进程,这样一个进程挂掉,还有另一个监视锁字段进程可以对锁进行管理。
- 但是又诞生一个新的问题,两个监视进程必须进行同步,否则对于过期的情况管理存在不一致问题。
因此存在以下问题,并且方案变得很复杂:
-
监视锁字段进程对于锁的监视时间周期过短,仍旧会造成多售(jvm1还没处理完其持有的锁就被主动销毁,造成多个服务同时持有锁进行操作)。
-
监视锁字段进程对于锁的监视时间周期过长,会造成整个服务卡顿过长,吞吐低下。
-
多个监视锁字段进程间的同步问题。
-
当一个jvm持有锁的时候,其余服务会一直访问数据库查看锁,会造成其余jvm的资源浪费。
4.2 基于update实现分布锁(特殊情况)
关于分布式锁,因为代码直接执行语句,有数据库行级锁,不会产生超卖问题。
mysql行锁解决分布锁问题演示修改的代码:
ServiceImpl中:
//mysql行锁解决分布锁问题
try {Thread.sleep(5000);
} catch (InterruptedException e) {throw new RuntimeException(e);
}
this.baseMapper.subCount2(goods);
mapper中:
@Update("update t_goods set count=count-1 where id=#{id} and count>0")
void subCount2(Goods goods);
5、基于Redis实现分布式锁
5.1 Redis实现分布式锁优点
(1)Redis有很高的性能;
(2)Redis命令对此支持较好,实现起来比较方便
命令介绍:
setnx :
SETNX key val:当且仅当key不存在时,set一个key为val的字符串,返回1;若key存在,则什么都不做,返回0。
expire :
expire key timeout:为key设置一个超时时间,单位为second,超过这个时间锁会自动释放,避免死锁。
delete :
delete key:删除key
在使用Redis实现分布式锁的时候,主要就会使用到这三个命令。
5.2 Redis实现分布式锁原理
- 获取锁的时候,使用setnx加锁,并使用expire命令为锁添加一个超时时间,超过该时间则自动释放锁,锁的value值为一个随机生成的UUID,通过此在释放锁的时候进行判断。
- 获取锁的时候还设置一个获取的超时时间,若超过这个时间则放弃获取锁。
- 释放锁的时候,通过UUID判断是不是该锁,若是该锁,则执行delete进行锁释放。
5.3 Redisson分布式锁使用
1)引入依赖
<!-- Redisson分布式锁使用-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency><dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.14.0</version>
</dependency>
2)配置文件
spring:redis:host: 192.168.220.110port: 6379
3)代码实现
//创建锁
RLock lock = redissonClient.getLock("goods-" + id);
//加锁
try {lock.lock();Goods goods = this.baseMapper.selectById(id);Integer count = goods.getCount();if(count>0){try {Thread.sleep(5000);} catch (InterruptedException e) {throw new RuntimeException(e);}this.baseMapper.subCount(id);}
} catch (RuntimeException e) {throw new RuntimeException("超卖了");
} finally {//释放锁lock.unlock();
}
5.4 总结
可以使用缓存代替数据库实现分布式锁,性能根号。同时多数缓存服务时集群部署,可以避免单点问题。
很多缓存服务提供了实现分布式锁的方法和对数据过期自动删除的支持,如Tair的put方法,redis 的setnx方法(Redisson是Redis官方推荐的Java版的Redis客户端) 。可以设置超时时间控制锁的释放。
使用缓存实现分布式锁的优点:性能好,实现起来较为方便。
使用缓存实现分布式锁的缺点 :通过超时时间来控制所得失效时间不靠谱。
6、 基于Zookeeper实现的分布式锁
6.1 Zookeeper的特点
Zookeeper的每一个节点,都是一个天然的顺序发号器,zookeeper有以下特点:
维护了一个有层次的数据节点,类似文件系统。
有临时节点,持久节点,临时有序节点(分布式锁实现基于的数据节点) ,持久有序节点。
zookeeper可以和client客户端通过心跳机制保持长连接,断开连接自动删除临时节点。
zookeeper的节点上可以注册上用户事件(自定义),节点数据删除等事件都可以触发自定义事件。
zookeeper保持了统一视图,各服务对于状态信息获取满足一致性。
创建有序节点会有编号:
6.2 Zookeeper实现分布式锁原理
创建一个目录mylock;
线程A想获取锁就在mylock目录下创建临时顺序节点;
获取mylock目录下所有的子节点,然后获取比自己小的兄弟节点,如果不存在,则说明当前线程顺序号最小,获得锁;
线程B获取所有节点,判断自己不是最小节点,设置监听比自己小的节点;
线程A处理完,删除自己的节点,线程B监听到变更事件,判断自己是不是最小的节点,如果是则获得锁。
6.3 Zookeeper解决的问题
锁无法释放?
在创建锁的时候,客户端会在ZK中创建一个临时节点,一旦客户端获取到锁之后突然挂掉(Session连接断开),那么这个临时节点就会自动删除掉。锁就会释放。
非阻塞锁?
客户端可以通过在ZK中创建顺序节点,并且在节点上绑定监听器,一旦节点有变化,Zookeeper会通知客户端,客户端可以检查自己创建的节点是不是序号最小,如果是,那么自己就获取到锁。
不可重入?
客户端在创建节点的时候,把当前客户端的主机信息和线程信息直接写入到节点中,下次想要获取锁的时候和当前最小的节点中的数据比对。如果信息一样,直接获取到锁,如果不一样就再创建一个临时的顺序节点,参与排队。
单点问题?
ZK是集群部署的,只要集群中有半数以上的机器存活,就可以对外提供服务。
6.4 基于Curator 客户端实现分布式锁
Curator Framework提供了简化使用zookeeper更高级的API接口。它包涵很多优秀的特性,主要包括以下三点
自动连接管理:自动处理zookeeper的连接和重试存在一些潜在的问题;可以watch NodeDataChanged event和获取updateServerList;Watches可以自动被Cruator recipes删除;
更干净的API:简化raw zookeeper方法,事件等;提供现代流式API接口
Recipe实现:leader选举,分布式锁,path缓存,和watcher,分布式队列等。
依赖:
<dependency><groupId>org.apache.curator</groupId><artifactId>curator-framework</artifactId><version>4.0.1</version>
</dependency>
<dependency><groupId>org.apache.curator</groupId><artifactId>curator-recipes</artifactId><version>4.0.1</version>
</dependency>
代码:
//zookeeper 分布式锁解决超卖问题
//1.创建zookeeper连接
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
CuratorFramework client= CuratorFrameworkFactory.newClient("192.168.184.200:2181", retryPolicy);
client.start();
//创建分布式锁
InterProcessMutex interProcessMutex = new InterProcessMutex(client,"/ordersettinglock");
//加锁
try {interProcessMutex.acquire();Goods goods = this.baseMapper.selectById(id);Integer count = goods.getCount();if(count>0){try {Thread.sleep(5000);} catch (InterruptedException e) {throw new RuntimeException(e);}this.baseMapper.subCount(id);}
} catch (Exception e) {throw new RuntimeException("超卖了");
} finally {//释放锁try {interProcessMutex.release();} catch (Exception e) {throw new RuntimeException(e);}
}
6.5 总结
优点:
有效的解决单点问题、不可重入问题、非阻塞问题、锁无法释放问题。实现起来简单。
缺点:
性能上不如使用缓存实现分布式锁。需要对ZK的原理有所了解,比较复杂 。
7、分布式锁总结
上面几种方式,哪种方式都无法做到完美。就像CAP一样,在复杂性、可靠性、性能等方面无法同时满足,所以,根据不同的应用场景选择最适合自己的才是王道。
理解难易程度:
数据库>缓存(redis) >zookeeper.
复杂性:
zookeeper >= 缓存 > 数据库
性能:
缓存 > zookeeper >= 数据库
可靠性:
zookeeper > 缓存 >数据库
相关文章:

八:分布式锁
1、为什么要使用分布式锁 锁是多线程代码中的概念,只有多任务访问同一个互斥的共享资源时才需要锁。单机应用开发时一般使用synchronized或lock。多线程的运行都是在同一个JVM之下。应用是分布式集群,属于多JVM的工作环境,JVM之间已经无法通过…...

示例:php将文本内容写入一个文件(面向过程写法)
一、封装2个函数,读写文件 /*** desc 读取文件内容* param string $filename* return array*/ private function readContent(string $filename): array {$text file_get_contents($filename);if (!$text) {return [];}$result json_decode($text,true);return…...

Flutter开发进阶之并发操作数据库
Flutter开发进阶之并发操作数据库 尽管 Flutter 本身不包含任何数据库功能,但可以使用各种第三方库和插件来在 Flutter 应用程序中实现数据库功能; 以下将使用sqflite作为例子,sqflite允许在 Flutter 应用程序中执行 SQL 查询,创…...

docker应用:搭建uptime-kuma监控站点
简介:Uptime Kuma是一个易于使用的自托管监控工具,它的界面干净简洁,部署和使用都非常方便。 历史攻略: docker:可视化工具portainer docker-compose:搭建自动化运维平台Spug 开源地址: ht…...

在illustrator中按大小尺寸选择物体 <脚本 018>
在Illustrator中我们可以依据对象的属性 如:填充颜色、描边颜色或描边宽度来选择相同属性的对象,但是Illustrator中没有根据不同大小尺寸来选择对象的功能,下面介绍的就是根据大小尺寸选择对象的脚本。 1、下面是当前画板中的所有对象&#…...

leetcode - 934. Shortest Bridge
Description You are given an n x n binary matrix grid where 1 represents land and 0 represents water. An island is a 4-directionally connected group of 1’s not connected to any other 1’s. There are exactly two islands in grid. You may change 0’s to 1…...

k8s的存储卷、数据卷
容器内的目录和宿主机目录进行挂载。 容器在系统上的生命周期是短暂的。 k8s用控制器创建的pod。delete相当于重启。容器的状态也会恢复到初始状态。一旦恢复到初始状态,所有的后天编辑的文件都会消失 容器和节点之间创建一个可以持久化保存容器内文件的存储卷。…...

流星全自动网页生成系统重构版源码
流星全自动网页生成系统重构版源码分享,所有模板经过精心审核与修改,完美兼容小屏手机大屏手机,以及各种平板端、电脑端和360浏览器、谷歌浏览器、火狐浏览器等等各大浏览器显示。 为用户使用方便考虑,全自动网页制作系统无需繁琐…...

vscode打开c_cpp_properties.json文件的一种方式
步骤一 点击win32 步骤二 点击json 自动生成了...

发起人自选-钉钉审批
场景描述 配置一个审批流程,在某些审批节点,不能确定谁具体来审批,所以需要手工选择一个人或者多个人保证流程能得以顺利通过。有些审批流程的做法是,上一个节点来选择指定的人,而钉钉的做法是发起人来指定。 钉钉设…...

电脑DIY-显卡
显卡 英伟达(NVIDIA)RTX系列 英伟达(NVIDIA) 英伟达(NVIDIA)是一家知名的图形处理器制造商,其显卡产品系列众多。以下是英伟达显卡的主要系列: 系列面向客户说明产品GeForce系列个…...

vue3+vite+ts+pinia新建项目(略详细版)
1、新建项目 npm create vite@latest 2、安装依赖 yarn add vue-router yarn add -D @types/node vite-plugin-pages sass sass-loader 3、配置别名 //vite.config.ts import { defineConfig } from vite import path from node:path export default defineConfig({ plu…...

深入理解 Flink(五)Flink Standalone 集群启动源码剖析
前言 Flink 集群的逻辑概念: JobManager(StandaloneSessionClusterEntrypoint) TaskManager(TaskManagerRunner) Flink 集群的物理概念: ResourceManager(管理集群所有资源,管理集群所有从节点) TaskExecutor(管理从节点资源,接…...

SpringCloud Aliba-Nacos-从入门到学废【2】
🥚今日鸡汤🥚 比起不做而后悔,不如做了再后悔。 ——空白《游戏人生》 目录 🧈1.Nacos集群架构说明 🧂2.三种部署模式 🍿3.切换到mysql 1.在nacos-server-2.0.3\nacos\conf里找到nacos-mysql.sql 2.查…...

web前端算法简介之字典与哈希表
回顾 栈、队列 : 进、出 栈(Stack): 栈的操作主要包括: 队列(Queue): 队列的操作主要包括: 链表、数组 : 多个元素存储组成的 简述链表:数组&…...

【uview2.0】Keyboard 键盘 与 CodeInput 验证码输入 结合使用 uview
https://www.uviewui.com/components/codeInput.html (CodeInput 验证码输入) https://www.uviewui.com/components/keyboard.html (Keyboard 键盘) <u-keyboard mode"number" :dotDisabled"true" :show&q…...

解决chromebook kabylake安装linux没有声音问题
chromebook kabylake安装arch没有声音,好长时间没有解决,一直用的蓝牙耳机。 今天搜搜帖子解决了, 分享供参考 git clone https://github.com/eupnea-project/chromebook-linux-audiocd chromebook-linux-audio ./setup-audio提示 I Underst…...

Spring Boot - Application Events 的发布顺序_ApplicationContextInitializedEvent
文章目录 Pre概述Code源码分析 Pre Spring Boot - Application Events 的发布顺序_ApplicationEnvironmentPreparedEvent Spring Boot - Application Events 的发布顺序_ApplicationEnvironmentPreparedEvent 概述 Spring Boot 的广播机制是基于观察者模式实现的,…...

由jar包冲突导致的logback日志不输出
最近接手一个厂商移交的项目,发现后管子系统不打印日志。 项目使用的logback 本地断点调试发现logback-classic jar冲突导致 打出的war中没有 相关的jar 解决方法: 去除pom 文件中多余的 logback-classic 应用,只保留最新版本的。 重新打…...

app开发——安卓native开发思路记录
我们知道app开发目前有三种方式,第一种是webapp,第二种是hybird app,第三种是native app。 而native-app就是安卓原生app,这里记录一下安卓原生开发的基本思路。 首先,安卓原生开发虽然在当今时代不是那么常见了&…...

黑马程序员JavaWeb开发|案例:tlias智能学习辅助系统(1)准备工作、部门管理
一、准备工作 1.明确需求 根据产品经理绘制的页面原型,对部门和员工进行相应的增删改查操作。 2.环境搭建 将使用相同配置的不同项目作为Module放入同一Project,以提高相同配置的复用性。 准备数据库表(dept, emp) 资料中包含…...

C# .NET SQL sugar中 IsAny进行根据条件判断数据是否存在 IsAny的使用
SQL sugar 中控制器直接判断数据是否存在 首先确保你的Service层继承的表名 控制器中使用IsAny进行根据条件判断数据是否存在...

《Git学习笔记:Git入门 常用命令》
1. Git概述 1.1 什么是Git? Git是一个分布式版本控制工具,主要用于管理开发过程中的源代码文件(Java类、xml文件、html页面等),在软件开发过程中被广泛使用。 其它的版本控制工具 SVNCVSVSS 1.2 学完Git之后能做…...

小程序跳转安卓会跳转两次 iOS不会的解决方案
原因:元素点击事件在子元素上有绑定,父元素上也有绑定会形成冒泡事件; 原生小程序: bind:tap:会冒泡; <view bind:tap"gotoDetail"><image :src"{{ item2.img }}" mode&qu…...

vue3+ts 中实现压缩图片、blob 转 base64
压缩图片 1.npm 安装 image-compressor.js 2.引入 import ImageCompressor from image-compressor.js 3.使用 const compressImage async (file: any) > {var imageCompressor new ImageCompressor()return new Promise((resolve, reject) > {imageCompressor.comp…...

(框架设计-基础库建设) boost 库
“框架”这个词所有的开发都听过,但是有多少人能理解框架的作用?为什么要花那么大精力去弄一个框架?大家应该都听过各个大厂稍微大点的项目都会有一个“框架组”/“架构组”等。 费这么大人力组建一个组来 做框架/架构 到底值不值呢ÿ…...

将ResultSet转实体类
将ResultSet转实体类 sqlExecutor.executeQuery的执行结果的返回值是ResultSet:package java.sql; 一般在程序中我们需要把查询结果转为实体类返回给前端,此处可以使用的方法: ResultSet转实体类方法1 2 1:resultSet.getXXX(columnIndex)…...

Web后端开发
一、Maven 1.1 简介 1.2 作用 1.3 流程 通过各种插件实现项目的标准化构建。 1.4 安装 1.5 配置环境 1.5.1 当前工程环境 1.5.2 全局环境 1.6 创建 Maven项目 1.7 导入项目 1.8 依赖管理 1.8.1 依赖配置 1.8.2 依赖传递 pom.xml——右键——Diagrams——show dependen…...

CAN201 计网概念收集
Lecture 1 the theoretical basis for networking Network edge and core 地理覆盖范围:广WAN,城MAN,局LAN,个PAN 交换方式,电路,报文,分组 电路交换vs报文vs分组 Network performance pr…...

【占用网络】FlashOcc:快速、易部署的占用预测模型
前言 FlashOcc是一个它只需2D卷积就能实现“占用预测模型”,具有快速、节约内存、易部署的特点。 它首先采用2D卷积提取图形信息,生成BEV特征。然后通过通道到高度变换,将BEV特征提升到3D空间特征。 对于常规的占用预测模型,将…...