为什么添加缓存要在释放锁之前?

news2024/11/22 9:04:08

为什么加缓存要放在释放锁之前?

线程拿到锁会去查缓存是否有数据,又因为我们向redis存入缓存数据是在释放锁之后
那么释放锁之后,下一个线程查缓存,上一个线程并未存入完成。此时就会出现查询多次数据库的情况,锁失效
故,存缓存数据应在锁释放之前完成,尽量保证原子性操作

测试1:锁释放之后向redis缓存存入数据

在这里插入图片描述

//TODO 产生堆外内存溢出 OutOfDirectMemoryError
    //gulimall.com查询分类
    @Override
    public Map<String, List<CategoryLevel2Vo>> getCatelogJson() {
        /**
         * 问题 :解决办法
         * 1.缓存穿透 高并发情况下查询缓存不存在的数据导致并发查数据库    解决办法:查询数据库结果为null时,在缓存中设置不为null的空值(0,1),并设置过期时间,保证缓存能查到该数据
         * 2.缓存雪崩 高并发情况下查询时,因为key设置相同的过期时间而key集体失效     解决办法:给key设置随机过期时间,防止集体失效 set("categoryJson",s,1,xxx)
         * 3.缓存击穿 高并发情况下同时访问同一个Key   解决办法:加锁
         */

        String categoryJson = stringRedisTemplate.opsForValue().get("categoryJson");
        //缓存为空就查数据库
        if (StringUtils.isEmpty(categoryJson)){
            System.out.println("缓存未命中,查数据库");
            //查数据库
            Map<String, List<CategoryLevel2Vo>> fromData = getCatelogJsonFromData();
            //存入redis
            String s = JSON.toJSONString(fromData);
            stringRedisTemplate.opsForValue().set("categoryJson",s,1, TimeUnit.DAYS);
            return fromData;
        }
        System.out.println("缓存命中,直接返回");
        //缓存有数据直接返回缓存数据
        Map<String, List<CategoryLevel2Vo>> object = JSON.parseObject(categoryJson, new TypeReference<Map<String, List<CategoryLevel2Vo>>>() {});
        return object;
    }

查数据库逻辑

//Map<一级分类id,二级分类集合>
    public Map<String, List<CategoryLevel2Vo>> getCatelogJsonFromData() {

        synchronized (this) {
            /**
             * 这种加锁,此项目只部署在一台服务器的情况下可以,本地锁锁住一个实例
             * 分布式情况下就不行,此项目部署在多台服务器上吗,每个锁锁住自己的实例只放一个线程进来
             * 如果8太服务器就会有8个线程同时访问,失去了锁的作用
             * 本地锁只能锁住当前进程,不能锁住其他服务
             *
             */
            //TODO 本地锁(当前进程锁)synchronized 、 (JUC)Lock  ,分布式情况下必须使用分布式锁
            //下一个线程拿到锁之后先查缓存,缓存中没有再查数据库,避免频繁查库
            String categoryJson = stringRedisTemplate.opsForValue().get("categoryJson");
            if (StringUtils.isNotBlank(categoryJson)){
                Map<String, List<CategoryLevel2Vo>> object = JSON.parseObject(categoryJson, new TypeReference<Map<String, List<CategoryLevel2Vo>>>() {});
                return object;
            }
            System.out.println("当前进程锁查询了数据库");
            List<CategoryEntity> categoryGetAll = baseMapper.selectList(null);
            //一级分类
            List<CategoryEntity> category1Level = getParentCid(categoryGetAll,0L);
            Map<String, List<CategoryLevel2Vo>> collect = category1Level.stream().collect(Collectors.toMap(item -> item.getCatId().toString()
                    , l1 -> {
                        //二级分类
                        List<CategoryEntity> category2Level = getParentCid(categoryGetAll,l1.getCatId());
                        List<CategoryLevel2Vo> collect2 = null;
                        if (category2Level != null){
                            collect2 = category2Level.stream().map(l2 -> {
                                //三级分类
                                List<CategoryEntity> category3Level = getParentCid(categoryGetAll,l2.getCatId());
                                List<CategoryLevel2Vo.CategoryLevel3Vo> collect3 = null;
                                if (category3Level != null){
                                    collect3 = category3Level.stream().map(level3 -> {
                                        return new CategoryLevel2Vo.CategoryLevel3Vo(l2.getCatId().toString(),level3.getCatId().toString(),level3.getName());
                                    }).collect(Collectors.toList());
                                }
                                return new CategoryLevel2Vo(l1.getCatId().toString(),collect3,l2.getCatId().toString(),l2.getName());
                            }).collect(Collectors.toList());
                        }
                        return collect2;

                    }));
            return collect;

        }

    }

JMeter性能压测

测试环境

  • 测试之前清空redis缓存
  • 因为是在本地服务器上面运行,单体应用服务器测试进程锁synchronized,实例对象为当前服务(数量:1)
  • 测试线程数:100

预期结果:只查询一次数据库,根据逻辑,如果控制台只打印一次 “当前进程锁查询了数据库” 代表成功

在这里插入图片描述

在这里插入图片描述
测试结果
线程锁测试失败,两次查询数据库,打印了两次 “当前进程锁查询了数据库”

缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
当前进程锁查询了数据库
缓存未命中,查数据库
缓存未命中,查数据库
2023-06-04 00:05:18.208  INFO 6348 --- [io-10001-exec-7] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
2023-06-04 00:05:18.297  INFO 6348 --- [io-10001-exec-7] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
缓存未命中,查数据库
2023-06-04 00:05:18.304 DEBUG 6348 --- [io-10001-exec-7] c.a.g.p.dao.CategoryDao.selectList       : ==>  Preparing: SELECT cat_id,name,parent_cid,cat_level,show_status,sort,icon,product_unit,product_count FROM pms_category WHERE show_status=1 
缓存未命中,查数据库
2023-06-04 00:05:18.316 DEBUG 6348 --- [io-10001-exec-7] c.a.g.p.dao.CategoryDao.selectList       : ==> Parameters: 
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
2023-06-04 00:05:18.344 DEBUG 6348 --- [io-10001-exec-7] c.a.g.p.dao.CategoryDao.selectList       : <==      Total: 1425
当前进程锁查询了数据库
2023-06-04 00:05:18.351 DEBUG 6348 --- [o-10001-exec-42] c.a.g.p.dao.CategoryDao.selectList       : ==>  Preparing: SELECT cat_id,name,parent_cid,cat_level,show_status,sort,icon,product_unit,product_count FROM pms_category WHERE show_status=1 
2023-06-04 00:05:18.351 DEBUG 6348 --- [o-10001-exec-42] c.a.g.p.dao.CategoryDao.selectList       : ==> Parameters: 
缓存未命中,查数据库
2023-06-04 00:05:18.365 DEBUG 6348 --- [o-10001-exec-42] c.a.g.p.dao.CategoryDao.selectList       : <==      Total: 1425
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回

测试2:锁释放之前向redis缓存存入数据

修改代码,在锁释放前存入redis

//TODO 产生堆外内存溢出 OutOfDirectMemoryError
    //gulimall.com查询分类
    @Override
    public Map<String, List<CategoryLevel2Vo>> getCatelogJson() {
        /**
         * 问题 :解决办法
         * 1.缓存穿透 高并发情况下查询缓存不存在的数据导致并发查数据库    解决办法:查询数据库结果为null时,在缓存中设置不为null的空值(0,1),并设置过期时间,保证缓存能查到该数据
         * 2.缓存雪崩 高并发情况下查询时,因为key设置相同的过期时间而key集体失效     解决办法:给key设置随机过期时间,防止集体失效 set("categoryJson",s,1,xxx)
         * 3.缓存击穿 高并发情况下同时访问同一个Key   解决办法:加锁
         */

        String categoryJson = stringRedisTemplate.opsForValue().get("categoryJson");
        //缓存为空就查数据库
        if (StringUtils.isEmpty(categoryJson)){
            System.out.println("缓存未命中,查数据库");
            //查数据库
            Map<String, List<CategoryLevel2Vo>> fromData = getCatelogJsonFromData();
            return fromData;
        }
        System.out.println("缓存命中,直接返回");
        //缓存有数据直接返回缓存数据
        Map<String, List<CategoryLevel2Vo>> object = JSON.parseObject(categoryJson, new TypeReference<Map<String, List<CategoryLevel2Vo>>>() {});
        return object;
    }

    //Map<一级分类id,二级分类集合>
    public Map<String, List<CategoryLevel2Vo>> getCatelogJsonFromData() {

        synchronized (this) {
            /**
             * 这种加锁,此项目只部署在一台服务器的情况下可以,本地锁锁住一个实例
             * 分布式情况下就不行,此项目部署在多台服务器上吗,每个锁锁住自己的实例只放一个线程进来
             * 如果8太服务器就会有8个线程同时访问,失去了锁的作用
             * 本地锁只能锁住当前进程,不能锁住其他服务
             *
             */
            //TODO 本地锁(当前进程锁)synchronized 、 (JUC)Lock  ,分布式情况下必须使用分布式锁
            //下一个线程拿到锁之后先查缓存,缓存中没有再查数据库,避免频繁查库
            String categoryJson = stringRedisTemplate.opsForValue().get("categoryJson");
            if (StringUtils.isNotBlank(categoryJson)){
                Map<String, List<CategoryLevel2Vo>> object = JSON.parseObject(categoryJson, new TypeReference<Map<String, List<CategoryLevel2Vo>>>() {});
                return object;
            }
            System.out.println("当前进程锁查询了数据库");
            List<CategoryEntity> categoryGetAll = baseMapper.selectList(null);
            //一级分类
            List<CategoryEntity> category1Level = getParentCid(categoryGetAll,0L);
            Map<String, List<CategoryLevel2Vo>> collect = category1Level.stream().collect(Collectors.toMap(item -> item.getCatId().toString()
                    , l1 -> {
                        //二级分类
                        List<CategoryEntity> category2Level = getParentCid(categoryGetAll,l1.getCatId());
                        List<CategoryLevel2Vo> collect2 = null;
                        if (category2Level != null){
                            collect2 = category2Level.stream().map(l2 -> {
                                //三级分类
                                List<CategoryEntity> category3Level = getParentCid(categoryGetAll,l2.getCatId());
                                List<CategoryLevel2Vo.CategoryLevel3Vo> collect3 = null;
                                if (category3Level != null){
                                    collect3 = category3Level.stream().map(level3 -> {
                                        return new CategoryLevel2Vo.CategoryLevel3Vo(l2.getCatId().toString(),level3.getCatId().toString(),level3.getName());
                                    }).collect(Collectors.toList());
                                }
                                return new CategoryLevel2Vo(l1.getCatId().toString(),collect3,l2.getCatId().toString(),l2.getName());
                            }).collect(Collectors.toList());
                        }
                        return collect2;

                    }));

            /**
             * 为什么将存入redis放在释放锁之前?
             * 线程拿到锁会去查缓存是否有数据,又因为我们向redis存入缓存数据是在释放锁之后
             * 那么释放锁之后,下一个线程查缓存,上一个线程并未存入完成。此时就会出现查询多次数据库的情况,锁失效
             * 故,存缓存数据应在锁释放之前完成
             */
            //存入缓存redis
            String s = JSON.toJSONString(collect);
            stringRedisTemplate.opsForValue().set("categoryJson",s,1, TimeUnit.DAYS);

            return collect;

        }

    }

测试结果
情况redis缓存,再次测试

缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
缓存未命中,查数据库
当前进程锁查询了数据库
2023-06-04 00:15:55.335  INFO 20204 --- [o-10001-exec-84] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2023-06-04 00:15:55.489  INFO 20204 --- [o-10001-exec-84] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2023-06-04 00:15:55.495 DEBUG 20204 --- [o-10001-exec-84] c.a.g.p.dao.CategoryDao.selectList       : ==>  Preparing: SELECT cat_id,name,parent_cid,cat_level,show_status,sort,icon,product_unit,product_count FROM pms_category WHERE show_status=1 
2023-06-04 00:15:55.506 DEBUG 20204 --- [o-10001-exec-84] c.a.g.p.dao.CategoryDao.selectList       : ==> Parameters: 
2023-06-04 00:15:55.528 DEBUG 20204 --- [o-10001-exec-84] c.a.g.p.dao.CategoryDao.selectList       : <==      Total: 1425
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回
缓存命中,直接返回

测试成功,只打印了一次“当前进程锁查询了数据库”
在这里插入图片描述
单体服务本地锁测试成功,如果是分布式服务使用单体锁synchronized,那么多少服务实例就会有多少进程,虽然体量不大,但是未达到加锁的目的,为了能更好的解决缓存击穿问题,分布式情况下就不能使用单体进程锁了,必须使用分布式锁
在这里插入图片描述
分布式模拟测试,这里同时启动4个服务,执行线程数100,循环五次
在这里插入图片描述

在这里插入图片描述
测试结果:
第一次:只有第一个服务查询了一个数据库,其他服务未查询数据库
第二次:四个服务都只查询了一次数据库,这就符合本地锁只能锁住当前服务,不能锁住其他分布式服务

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

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

相关文章

chatgpt赋能python:Python如何重复运行——让你的代码运行更高效

Python如何重复运行——让你的代码运行更高效 Python作为一种非常流行的编程语言&#xff0c;在程序员中间被广泛使用。无论是从事科学计算、数据分析还是网页爬虫&#xff0c;都离不开Python。但是&#xff0c;如果你只会最基础的Python语法&#xff0c;你可能会花费更多的时…

《三维存储芯片技术》----学习记录(一)

第1章 NAND存储器的生态 1.1 存储器行业变迁 可以说近10年是整个存储行业历史上变化最大的10年。 1.1.1 NAND及存储器供应商的整合 如图1.1所示&#xff0c;过去6年中&#xff0c;全球存储器95%的供应集中到5家厂商。 图片来源于《三维存储芯片技术》 1.1.2 NAND技术发展 …

行业应用|立仪光谱共焦位移传感器在玻璃方面的检测

项目&#xff1a;玻璃管管壁单边测厚 行业应用|立仪光谱共焦位移传感器在玻璃方面的检测 行业应用|立仪光谱共焦位移传感器在玻璃方面的检测 检测方案 用D35A7镜头对玻璃管管壁进行单边测厚&#xff0c;取三个点静态测量厚度并记录重复性。 1、采用D35A7R2S35镜头对玻璃管管…

springboot+vue企业设备管理系统

解决的思路&#xff1a; &#xff08;1&#xff09;通过进行需求分析&#xff0c;建立用例模型&#xff0c;上网查找资料&#xff0c;摸清业务流程。 &#xff08;2&#xff09;通过运用vue 技术进行界面的设计&#xff0c;上网搜集符合所做管理系统的相关图片&#xff0c;使用…

springboot 配置文件密码加密处理

一、修改pom文件 <dependency> <groupId>com.github.ulisesbocchio</groupId> <artifactId>jasypt-spring-boot-starter</artifactId> <version>3.0.4</version> </dependency> 二、在启动类中加上注解 EnableEncryptableProp…

开源实时位置共享服务Hauk

【勘误】&#xff1a;在上文 『事务与项目跟踪软件Jira』 一文中&#xff0c;老苏错误的将 4G 内存写成了 4M&#xff0c;感谢网友 纸飞机 和 cwz 的指正。虽然老苏确实用过 4M 内存的机器&#xff0c;但那是20 多年前的事情了。 什么是 Hauk &#xff1f; Hauk 是一个完全开源…

Mysql数据库入门基础篇--mysql基本了解

【Mysql数据库入门基础篇--mysql基本了解 &#x1f53b;一、Mysql5.7 VS Mysql8.0 详解1.1 ⛳字符编码1.2 ⛳用户的创建与授权1.3 ⛳ 认证插件1.4 ⛳ 隐藏索引1.5 ⛳ 持久化设置1.6 ⛳ 通用表达式&#xff08;Common Table Expressions&#xff09;1.7 ⛳ 性能提升1.8 ⛳ 参数变…

chatgpt赋能python:Python如何输出在同一行

Python如何输出在同一行 在Python编程中&#xff0c;有时候我们需要将多个输出放在同一行中。这篇文章将介绍几种方法来实现这个任务&#xff0c;并给出一些例子来帮助你更好地理解。 方法一&#xff1a;使用print函数 Python中的print函数默认会在每个输出之间换行。但是&a…

【大数据工具】HBase 集群搭建与基本使用

HBase 集群搭建 HBase 安装包下载地址&#xff1a;https://archive.apache.org/dist/hbase/ 安装 HBase 的前提&#xff1a; ZooKeeper 集群 OKHadoop 集群 OK 1. HBase 集群安装 1. 将 HBase 软件包上传至 Hadoop0 解压并重命名 使用 FileZilla 将 hbase-1.3.1-bin.tar.g…

pytorch中Dataloader读取数据太慢的问题

文章目录 pytorch中Dataloader读取数据太慢的问题1. 方法2. 方法3. 解决方法&#xff1a;提取加载数据 pytorch中Dataloader读取数据太慢的问题 数据读取的速度远远大于GPU训练的速度&#xff0c;导致整个训练流程中有大部分时间都在等待数据发送到GPU&#xff0c;在资源管理器…

七年磨一剑!苹果王炸产品Vision Pro诞生,未来已来

这是第一款「不见却可透见」的苹果产品 等了整整七年&#xff01;2023年6月5日&#xff0c;WWDC23大会上&#xff0c;苹果发布首款头显Vision Pro&#xff0c;Vision Pro 可以算是苹果公司自 2015 年 Apple Watch 首次亮相以来最大的硬件产品发布&#xff0c;或许它会彻底改变数…

【深度学习】BERT变种—百度ERNIE 1.0

ERNIE: Enhanced Representation through Knowledge Integration是百度在2019年4月的时候&#xff0c;基于BERT模型&#xff0c;做的进一步优化&#xff0c;在中文的NLP任务上得到了state-of-the-art的结果。 ERNIE 是百度开创性提出的基于知识增强的持续学习语义理解框架&…

苹果又一黑科技产品 Apple Vision Pro,正式问世!

公众号关注 “GitHubDaily” 设为 “星标”&#xff0c;每天带你逛 GitHub&#xff01; 在电影《钢铁侠》中&#xff0c;托尼通过简单的手势动作&#xff0c;配合空间中的虚拟界面&#xff0c;成功将贾维斯创造出来。 当时片中的这个镜头&#xff0c;让无数科幻迷为之疯狂&…

pyspark数据输入

学习目标&#xff1a; 现在只需要知道PDD是一个数据集。 【运行实例&#xff08;1&#xff09;】&#xff1a; from pyspark import SparkConf, SparkContext # conf:创建对象&#xff1b;Sparkconf&#xff1a;创建入口&#xff1b;setMaster&#xff1a;运行方式&#xff1…

chatgpt赋能python:Python如何输出两个值

Python如何输出两个值 在Python编程中&#xff0c;经常需要输出多个值。下面我们来介绍几种常用的方法。 方法一&#xff1a;使用逗号分隔符 使用逗号分隔符可以在一行代码中输出多个值。例如&#xff1a; a, b 1, 2 print(a, b) # 输出 1 2在输出时&#xff0c;多个值之…

图解未成年人个人信息保护要求(附下载)

未成年人互联网普及率持续提升。据2023年中国互联网络信息中心发布的第51次《中国互联网络发展状况统计报告》数据&#xff0c;2021年我国未成年人互联网普及率达96.8%&#xff1b;截至2022年12月&#xff0c;使用过短视频的青少年群体占比65.6%&#xff0c;未成年人已成网络参…

【Linux:进程间信号】

文章目录 1 生活角度的信号2 技术应用角度的信号3 信号的产生3.1 由系统调用向进程发信号3.1.1 signal3.1.2 kill3.1.3 raise 3.2 由软件条件产生信号3.3 硬件异常产生信号3.4 通过终端按键产生信号3.5 总结思考一下 4 信号的保存4.1信号其他相关常见概念4.2在内核中的表示4.3 …

如何评价 Facebook 发布的数字货币 Libra?

一句话总结&#xff1a;Libra 最大的亮点&#xff0c;在于它是 Facebook 做的。 随着数字货币市场的迅速发展&#xff0c;各类加密货币层出不穷。然而&#xff0c;在这个领域中&#xff0c;Facebook 所推出的 Libra 显得尤为引人关注。那么&#xff0c;Libra 到底有何特点&…

专家助阵!IoTDB X EMQ 智慧工厂主题 Meetup 讲师曝光!

期待已久的智慧工厂主题 Meetup 活动将在 4 天后线下线上同步举办&#xff01; 天谋科技将联手 EMQ&#xff0c;通过数据基础设施平台的核心技术与实践经验分享&#xff0c;提供流程协同、运营提效、生产质量保障等智能制造目标的可行方案。快来在推文结尾预约直播&#xff0c;…

【大数据工具】Flink集群搭建

Flink 集群安装 1. 单机版 Flink 安装与使用 1、下载 Flink 安装包并上传至服务器 下载 flink-1.10.1-bin-scala_2.11.tgz 并上传至 Hadoop0 /software 下 2、解压 [roothadoop0 software]# tar -zxvf flink-1.10.1-bin-scala_2.11.tgz3、创建快捷方式 [roothadoop0 soft…