亿级高并发电商项目-- 实战篇 --万达商城项目 十三(编写购物车、优化修改商品、下架商品方法、购物车模块监听修改商品、删除商品消息)
👏作者简介:大家好,我是小童,Java开发工程师,CSDN博客博主,Java领域新星创作者
📕系列专栏:前端、Java、Java中间件大全、微信小程序、微信支付、若依框架、Spring全家桶
📧如果文章知识点有错误的地方,请指正!和大家一起学习,一起进步👀
🔥如果感觉博主的文章还不错的话,请👍三连支持👍一下博主哦
🍂博主正在努力完成2023计划中:以梦为马,扬帆起航,2023追梦人
专栏:高并发项目
编写购物车服务接口
用户购买商品的流程为: 搜索商品 > 查看商品详情 > 添加到购物车 > 生成商品订单 > 支 付 ,搜索商品和查看商品详情功能已经完成,接下来我们编写购物 车服务。购物车数据属于临时数据,为了节约数据库开销,我们会 将其存放到redis中。
在通用模块编写购物车服务接口:
// 购物车服务
public interface CartService {// 新增商品到购物车void addCart(Long userId, CartGoods cartGoods);// 修改购物车商品数量void handleCart(Long userId, Long goodId, Integer num);// 删除购物车商品void deleteCartOption(Long userId, Long goodId);// 获取用户购物车List<CartGoods> findCartList(Long userId);// 更新redis中的商品数据,在管理员更新商品后执行void refreshCartGoods(CartGoods cartGoods);// 删除redis中的商品数据,在管理员下架商品后执行void deleteCartGoods(CartGoods cartGoods);
}
创建购物车服务模块
1、创建名为 shopping_cart_service 的SpringBoot工程,添加相关依赖。
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>com.itbaizhan</groupId><artifactId>shopping_common</artifactId><version>0.0.1-SNAPSHOT</version></dependency><!-- dubbo --><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</artifactId><version>2.7.8</version></dependency><!-- 操作zookeeper --><dependency><groupId>org.apache.curator</groupId><artifactId>curator-recipes</artifactId><version>4.2.0</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- redis --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>
</dependencies>
2、设置该工程的父工程为 shopping 。
<parent><groupId>com.ittxc</groupId><artifactId>shopping</artifactId><version>1.0-SNAPSHOT</version>
</parent>
3、给 shopping 工程设置子模块
<!-- 子模块 -->
<modules><!-- 购物车服务 --><module>shopping_cart_service</module>
</modules>
4、编写配置文件 application.yml
# 端口号
server:port: 9009
# 日志格式
logging:pattern:console: '%d{HH:mm:ss.SSS} %clr(%-5level) --- [%-15thread] %cyan(%-50logger{50}):%msg%n'
spring:# redisredis:host: 192.168.0.159port: 6379timeout: 30000jedis:pool:max-active: 8max-wait: -1max-idle: 8min-idle: 0
dubbo:application:name: shopping_cart_service # 项目名registry:address: zookeeper://192.168.0.159 #注册中心地址port: 2181 # 注册中心的端口timeout: 10000 # 注册到zk上超时时间,msprotocol:name: dubbo # dubbo使用的协议port: -1 # dubbo自动分配端口scan:base-packages: com.itbaizhan.shopping_cart_service.service # 包扫描
5、启动类忽略数据源自动配置
@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})
public class ShoppingCartServiceApplication {public static void main(String[] args)
{SpringApplication.run(ShoppingCartServiceApplication.class, args);}
}
创建购物车Api模块
1、创建名为 shopping_cart_customer_api 的SpringBoot工程,添加相关依赖。
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- dubbo --><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</artifactId><version>2.7.8</version></dependency><!-- 操作zookeeper --><dependency><groupId>org.apache.curator</groupId><artifactId>curator-recipes</artifactId><version>4.2.0</version></dependency><dependency><groupId>com.itbaizhan</groupId><artifactId>shopping_common</artifactId><version>0.0.1-SNAPSHOT</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-startertest</artifactId><scope>test</scope></dependency>
</dependencies>
2、设置该工程的父工程为 shopping 。
<parent><groupId>com.ittxc</groupId><artifactId>shopping</artifactId><version>1.0-SNAPSHOT</version>
</parent>
3、给 shopping 工程设置子模块
<!-- 子模块 -->
<modules><!-- 购物车api --><module>shopping_cart_customer_api</module>
</modules>
4、编写配置文件 application.yml
# 端口号
server:port: 8005
# 日志格式
logging:pattern:console: '%d{HH:mm:ss.SSS} %clr(%-5level) --- [%-15thread] %cyan(%-50logger{50}):%msg%n'
dubbo:application:name: shopping_cart_customer_api # 项目名registry:address: zookeeper://192.168.0.159 #注册中心地址port: 2181 # 注册中心的端口timeout: 10000 # 注册到zk上超时时间,msprotocol:name: dubbo # dubbo使用的协议port: -1 # dubbo自动分配端口
5、启动类忽略数据源自动配置
@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})
public class ShoppingUserCustomerApiApplication {public static void main(String[] args)
{SpringApplication.run(ShoppingUserCustomerApiApplication.class, args);}
}
编写查询用户购物车功能
我们将用户的购物车信息保存到redis当中,所有用户的购物车作为 一个hash类型的数据保存,hash的键是用户id,hash的值是购物车商品列表。
在购物车服务模块创建购物车服务接口的实现类,重写查询用户购物车功能
@DubboService
public class CartServiceImpl implements CartService {@Autowiredprivate RedisTemplate redisTemplate;@Overridepublic List<CartGoods> findCartList(Long userId) {Object cartList = redisTemplate.boundHashOps("cartList").get(userId);if (cartList == null) {return new ArrayList<CartGoods>();} else {return (List<CartGoods>)cartList;}}
}
编写添加商品到购物车方法
@Override
public void addCart(Long userId, CartGoods cartGoods) {// 1.根据用户id获取用户购物车列表List<CartGoods> cartList = findCartList(userId);// 2.查询购物车是否有该商品,如果有商品,添加商品数量for (CartGoods cartGoods1 : cartList) {if(cartGoods.getGoodId().equals(cartGoods1.getGoodId())){int newNum = cartGoods1.getNum() + cartGoods.getNum();cartGoods1.setNum(newNum);redisTemplate.boundHashOps("cartList").put(userId,cartList);return;}}// 3.如果购物车没有该商品,将商品添加到购物车列表cartList.add(cartGoods);redisTemplate.boundHashOps("cartList").put(userId,cartList);
}
编写修改购物车商品数量方法
@Override
public void handleCart(Long userId, Long goodId, Integer num) {// 获取用户购物车列表List<CartGoods> cartList = findCartList(userId);// 遍历列表找到对应商品for (CartGoods cartGoods : cartList) {if(goodId.equals(cartGoods.getGoodId())) {// 改变商品数量cartGoods.setNum(num);break;}}// 将新的购物车列表保存到redis中redisTemplate.boundHashOps("cartList").put(userId, cartList);
}
编写删除购物车商品方法
@Override
public void deleteCartOption(Long userId,Long goodId) {// 获取用户购物车列表List<CartGoods> cartList = findCartList(userId);// 将商品移出列表for (CartGoods cartGoods : cartList) {if (goodId.equals(cartGoods.getGoodId())) {cartList.remove(cartGoods);break;}}// 将新的购物车列表保存到redis中redisTemplate.boundHashOps("cartList").put(userId, cartList);
}
编写购物车控制器
在进行购物车操作之前,要先获取用户的Id,而用户的令牌中只保存了用户名,所以我们要修改JWT工具类,让令牌中也保存用户的 Id:
1、修改JWT工具类
public class JWTUtil {//token过期时间,一天private static final Long EXPIRE_DATE = 1000*60*60*24L;// 秘钥private static final String SECRET = "xiaotong";// 签发者private static final String ISSUER = "XIAOTONG";/*** 签名生成* @param shoppingUser* @return*/public static String sign(ShoppingUser shoppingUser){String token = JWT.create().withIssuer(ISSUER) // 签发者.withIssuedAt(new Date())// 签发时间.withExpiresAt(new Date(new Date().getTime() + EXPIRE_DATE))// 过期时间.withSubject(shoppingUser.getUsername())// 保存用户名.withClaim("userId",shoppingUser.getId())// 保存用户id.sign(Algorithm.HMAC256(SECRET)); // 秘钥return token;}/*** 签名解析* @param token 签名字符串* @return 解析得出的用户名*/public static String verify(String token){try {String username = JWT.require(Algorithm.HMAC256(SECRET)).withIssuer(ISSUER).build().verify(token).getSubject();return username;} catch (Exception e){throw new BusException(CodeEnum.VERIFY_TOKEN_ERROR);}}/*** 签名解析,获取用户id* @param token 签名字符串* @return 用户id*/public static Long getId(String token){try {Long userId = JWT.require(Algorithm.HMAC256(SECRET)).withIssuer(ISSUER).build().verify(token).getClaim("userId").asLong();return userId;} catch (Exception e){throw new BusException(CodeEnum.VERIFY_TOKEN_ERROR);}}
}
2、在购物车Api模块编写购物车控制器
/**
* 购物车
*/
@RestController
@RequestMapping("/user/cart")
public class CartController {@DubboReferenceprivate CartService cartService;/*** 查询用户购物车* @param token 用户令牌* @return 用户购物车列表*/@GetMapping("/findCartList")public BaseResult<List<CartGoods>> findCartList(@RequestHeader String token){Long userId = JWTUtil.getId(token); // 获取用户idList<CartGoods> cartList = cartService.findCartList(userId);return BaseResult.ok(cartList);}/*** 新增商品到购物车* @param cartGoods 购物车商品* @param token 用户令牌* @return 操作结果*/@PostMapping("/addCart")public BaseResult addCart(@RequestBody CartGoods cartGoods,@RequestHeader String token){Long userId = JWTUtil.getId(token); // 获取用户idcartService.addCart(userId,cartGoods);return BaseResult.ok();}/*** 修改购物车商品数量* @param token 用户令牌* @param goodId 商品id* @param num 修改后的数量* @return 操作结果*/@GetMapping("/handleCart")public BaseResult addCart(@RequestHeader String token,Long goodId,Integer num){Long userId = JWTUtil.getId(token); // 获取用户idcartService.handleCart(userId,goodId,num);return BaseResult.ok();}/*** 删除购物车商品* @param token 用户令牌* @param goodId 商品id* @return 操作结果*/@DeleteMapping("/deleteCart")public BaseResult addCart(@RequestHeader String token,Long goodId){Long userId = JWTUtil.getId(token); // 获取用户idcartService.deleteCartOption(userId,goodId);return BaseResult.ok();}
}
编写修改所有用户购物车商品方法
当管理员修改了商品的价格等数据后,需要将数据同步到用户购物车中,所以我们要编写给所有用户的购物车中修改某件商品的方法。
@Override
public void refreshCartGoods(CartGoods
cartGoods) {// 获取所有用户购物车商品BoundHashOperations cartList = redisTemplate.boundHashOps("cartList");Map<Long,List<CartGoods>> allCartGoods = cartList.entries();Set<Map.Entry<Long, List<CartGoods>>> entries = allCartGoods.entrySet();// 遍历所有用户的购物车for (Map.Entry<Long, List<CartGoods>> entry : entries) {List<CartGoods> goodsList = entry.getValue();// 遍历一个用户购物车的所有商品for (CartGoods goods : goodsList) {// 如果该商品是被更新的商品,修改商品数据if(cartGoods.getGoodId().equals(goods.getGoodId())){goods.setGoodsName(cartGoods.getGoodsName());goods.setHeaderPic(cartGoods.getHeaderPic());goods.setPrice(cartGoods.getPrice());}}}// 将改变后所有用户购物车重新放入redisredisTemplate.delete("cartList");redisTemplate.boundHashOps("cartList").putAll(allCartGoods);
}
编写删除所有用户购物车商品方法
当管理员下架某件商品后,所有用户的购物车中该商品也应该被删除,所以我们要编写给所有用户的购物车中删除某件商品的方法。
@Override
public void deleteCartGoods(CartGoods cartGoods) {BoundHashOperations cartList = redisTemplate.boundHashOps("cartList");// 所有用户的购物车Map<String,List<CartGoods>> allCartGoods = cartList.entries();Set<Map.Entry<String, List<CartGoods>>> entries = allCartGoods.entrySet();// 遍历所有用户的购物车for (Map.Entry<String, List<CartGoods>> entry : entries) {List<CartGoods> goodsList = entry.getValue();// 遍历一个用户购物车的所有商品for (CartGoods goods : goodsList) {// 如果该商品是被删除的商品if (cartGoods.getGoodId().equals(goods.getGoodId())){goodsList.remove(goods);break;}}}// 将改变后的map重新放入redisredisTemplate.delete("cartList");redisTemplate.boundHashOps("cartList").putAll(allCartGoods);
}
优化修改商品、下架商品方法
接下来我们修改商品服务模块代码,在修改商品后发送消息同步修 改购物车数据;在下架商品后发送消息同步删除购物车数据:
1、在MQ配置文件创建队列,绑定队列到交换机:
@Configuration
public class RabbitConfig {// 交换机private final String GOODS_EXCHANGE = "goods_exchange";// 同步商品数据队列private final String SYNC_GOODS_QUEUE = "sync_goods_queue";// 删除商品数据队列private final String DEL_GOODS_QUEUE = "del_goods_queue";// 向购物车同步商品队列private final String SYNC_CART_QUEUE = "sync_cart_queue";// 向购物车删除商品队列private final String DEL_CART_QUEUE = "del_cart_queue";// 创建交换机@Bean(GOODS_EXCHANGE)public Exchange getExchange() {return ExchangeBuilder.topicExchange(GOODS_EXCHANGE) // 交换机类型.durable(true) // 是否持久化.build();}// 创建队列@Bean(SYNC_GOODS_QUEUE)public Queue getQueue1() {return new Queue(SYNC_GOODS_QUEUE); // 队列名}@Bean(DEL_GOODS_QUEUE)public Queue getQueue2() {return new Queue(DEL_GOODS_QUEUE);// 队列名}@Bean(SYNC_CART_QUEUE)public Queue getQueue3() {return new Queue(SYNC_CART_QUEUE);// 队列名}@Bean(DEL_CART_QUEUE)public Queue getQueue4() {return new Queue(DEL_CART_QUEUE);
// 队列名}// 交换机绑定队列@Beanpublic Binding bindQueue1(@Qualifier(GOODS_EXCHANGE) Exchange exchange,@Qualifier(SYNC_GOODS_QUEUE) Queue queue){return BindingBuilder.bind(queue).to(exchange).with("#.sync_goods.#").noargs();}@Beanpublic Binding bindQueue2(@Qualifier(GOODS_EXCHANGE) Exchange exchange,@Qualifier(DEL_GOODS_QUEUE) Queue queue) {return BindingBuilder.bind(queue).to(exchange).with("#.del_goods.#").noargs();}@Beanpublic Binding
bindQueue3(@Qualifier(GOODS_EXCHANGE)
Exchange exchange,@Qualifier(SYNC_CART_QUEUE) Queue queue)
{return BindingBuilder.bind(queue).to(exchange).with("#.sync_cart.#").noargs();}@Beanpublic Binding bindQueue4(@Qualifier(GOODS_EXCHANGE) Exchange exchange,@Qualifier(DEL_CART_QUEUE) Queue queue) {return BindingBuilder.bind(queue).to(exchange).with("#.del_cart.#").noargs();}
}
@DubboService
public class GoodsServiceImpl implements
GoodsService {@Autowiredprivate GoodsMapper goodsMapper;@Autowiredprivate GoodsImageMapper goodsImageMapper;@Autowiredprivate RabbitTemplate rabbitTemplate;@Overridepublic void update(Goods goods) {// 删除旧图片数据Long goodsId = goods.getId(); //商品idQueryWrapper<GoodsImage> queryWrapper = new QueryWrapper();queryWrapper.eq("goodsId",goodsId);goodsImageMapper.delete(queryWrapper);// 删除旧规格项数据goodsMapper.deleteGoodsSpecificationOption(goodsId);// 插入商品数据goodsMapper.updateById(goods);// 插入图片数据List<GoodsImage> images = goods.getImages(); // 商品图片for (GoodsImage image : images) {image.setGoodsId(goodsId); // 给图片设置商品idgoodsImageMapper.insert(image); // 插入图片}// 插入商品_规格项数据List<Specification> specifications = goods.getSpecifications(); // 获取规格List<SpecificationOption> options = new ArrayList(); // 规格项集合// 遍历规格,获取规格中的所有规格项for (Specification specification : specifications) {options.addAll(specification.getSpecificationOptions());}// 遍历规格项,插入商品_规格项数据for (SpecificationOption option : options) {goodsMapper.addGoodsSpecificationOption(goodsId,option.getId());}rabbitTemplate.convertAndSend("goods_exchange","sync_goods",findById(goodsId));// 将商品修改数据同步到用户购物车CartGoods cartGoods = new CartGoods();cartGoods.setGoodId(goods.getId());cartGoods.setGoodsName(goods.getGoodsName());cartGoods.setHeaderPic(goods.getHeaderPic());cartGoods.setPrice(goods.getPrice());rabbitTemplate.convertAndSend("goods_exchange","sync_cart",cartGoods);}@Overridepublic void putAway(Long id, Boolean isMarketable) {goodsMapper.putAway(id,isMarketable);if (isMarketable){// 上架时同步到ESrabbitTemplate.convertAndSend("goods_exchange","sync_goods",findById(id));}else{// 下架删除ES数据rabbitTemplate.convertAndSend("goods_exchange","del_goods",id);// 商品下架删除用户购物车CartGoods cartGoods = new CartGoods();cartGoods.setGoodId(id);rabbitTemplate.convertAndSend("goods_exchange","del_cart",cartGoods);}}
}
购物车模块监听修改商品、删除商品消息
1、在购物车服务模块添加RabbitMQ依赖
<!-- RabbitMQ -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
2、添加RabbitMQ配置
spring:# redisredis:host: 192.168.0.159port: 6379timeout: 30000jedis:pool:max-active: 8max-wait: -1max-idle: 8min-idle: 0# rabbitmqrabbitmq:host: 192.168.0.159port: 5672username: guestpassword: guestvirtual-host: /
3、修改购物车服务接口实现类,监听队列
@DubboService
@Service
public class CartServiceImpl implements CartService {@Autowiredprivate RedisTemplate redisTemplate;// 监听修改购物车商品队列@RabbitListener(queues = "sync_cart_queue")public void listenSyncQueue(CartGoods cartGoods){refreshCartGoods(cartGoods);}// 监听删除购物车商品队列@RabbitListener(queues = "del_cart_queue")public void listenDelQueue(CartGoods cartGoods){deleteCartGoods(cartGoods);}
}
4、测试管理员修改商品、下架商品,看用户购物车是否发生改变。
相关文章:

亿级高并发电商项目-- 实战篇 --万达商城项目 十三(编写购物车、优化修改商品、下架商品方法、购物车模块监听修改商品、删除商品消息)
👏作者简介:大家好,我是小童,Java开发工程师,CSDN博客博主,Java领域新星创作者 📕系列专栏:前端、Java、Java中间件大全、微信小程序、微信支付、若依框架、Spring全家桶 Ǵ…...

springboot 虚拟线程demo
jd19支持虚拟线程,虚拟线程是轻量级的线程,它们不与操作系统线程绑定,而是由 JVM 来管理。它们适用于“每个请求一个线程”的编程风格,同时没有操作系统线程的限制。我们能够创建数以百万计的虚拟线程而不会影响吞吐。 做个 spri…...

CTFer成长之路之逻辑漏洞
逻辑漏洞CTF 访问url: http://1b43ac78-61f7-4b3c-9ab7-d7e131e7da80.node3.buuoj.cn/ 登录页面用随意用户名密码登录 访问url: http://1b43ac78-61f7-4b3c-9ab7-d7e131e7da80.node3.buuoj.cn/user.php 登陆后有商品列表,共三个商品,点击购买flag 钱…...

入门力扣自学笔记238 C++ (题目编号:1144)
1144. 递减元素使数组呈锯齿状 题目: 给你一个整数数组 nums,每次 操作 会从中选择一个元素并 将该元素的值减少 1。 如果符合下列情况之一,则数组 A 就是 锯齿数组: 每个偶数索引对应的元素都大于相邻的元素,即 A…...

蓝桥杯-寒假作业
没有白走的路,每一步都算数🎈🎈🎈 题目描述: 有四个等式,每个等式的运算规则已经定好了,也就是我们常见的小学的四则运算,但是能够用来四则运算的数字非常有限,包括1~13…...

测试用例篇
1.测试用例的意义 测试用例(Test Case)是为了实施测试而向被测试的系统提供的一组集合,这组集合包含:测试环境、操作步骤、测试数据、预期结果等要素。 测试用例的意义是为了帮助测试人员了解测什么,怎么测 eg&#x…...

自动驾驶自主避障概况
文章目录前言1. 自主避障在自动驾驶系统架构中的位置2. 自主避障算法分类2.1 人工势场法(APF)2.1.1引力势场的构建2.1.2斥力势场的构建2.1.3人工势场法的改进2.2 TEB(Timed-Eastic-Band, 定时弹性带)2.3 栅格法2.4 向量场直方图(V…...

Python实用的库排名…
Python 是一个功能强大的编程语言,有着丰富的第三方库和模块,可以帮助你解决各种各样的问题。以下是一些比较厉害的 Python 库: NumPy:一个强大的数值计算库,提供了高效的数组和矩阵操作功能。 Pandas:提供…...

【YOLO系列】YOLOv4论文超详细解读1(翻译 +学习笔记)
前言 经过上一期的开篇介绍,我们知道YOLO之父Redmon在twitter正式宣布退出cv界,大家都以为YOLO系列就此终结的时候,天空一声巨响,YOLOv4闪亮登场!v4作者是AlexeyAB大神,虽然换人了,但论文中给出…...

【神经网络】Transformer基础问答
1.Transforme与LSTM的区别 transformer和LSTM最大的区别就是LSTM的训练是迭代的,无法并行训练,LSTM单元计算完T时刻信息后,才会处理T1时刻的信息,T 1时刻的计算依赖 T-时刻的隐层计算结果。而transformer的训练是并行了࿰…...

制定防火墙策略的步骤和建议
制定防火墙策略是保护企业网络环境安全的关键一步。下面是一些制定防火墙策略的步骤和建议,供参考: 识别网络资产:确定企业网络环境中所有的网络资产,包括服务器、应用程序、数据库、移动设备和终端用户设备等,并进行…...

新必应(New Bing)国内申请与使用教程
微软的新必应(New Bing)基于GPT4模型,比ChatGPT的GPT3.5模型领先半个世代。并且集成了Edge浏览器的数据资源,功能更加强大。经过不断的踩坑,终于申请到了New Bing的使用权限,且国内网络也能够正常使用&…...

博客系统——项目测试报告
目录 前言 博客系统——项目介绍 1、测试计划 1.1、功能测试 1.1.1、编写测试用例 1.1.2、实际执行步骤 1.2、使用Selenium进行Web自动化测试 1.2.1、引入依赖 1.2.2、提取共性,实现代码复用 1.2.3、创建测试套件类 1.2.4、博客登录页自动化测试 1.2.5、…...

Macbook M1 安装PDI(Kettle) 9.3
Macbook M1 安装PDI(Kettle) 9.3 当前 PDI(Kettle)最新版为9.3,依赖Java JDK 11。因为没有专门用于 M1的程序,需要下载并安装x86_64架构的JDK及依赖软件,并 “强制在Intel模式下运行shell” 的方式来实现 Kettle 的正…...

机器学习——模型评估
在学习得到的模型投放使用之前,通常需要对其进行性能评估。为此,需使用一个“测试集”(testing set)来测试模型对新样本的泛化能力,然后以测试集上的“测试误差( tootino error)作为泛化误差的近似。我们假设测试集是从样本真实分…...

react react-redux学习记录
react react-redux学习记录1.原理2.怎么用呢2.1 容器组件2.2UI组件2.3 App.jsx3.简化3.1简写mapDispatch3.2 Provider组件的使用3.3整合UI组件和容器组件1.原理 UI组件:不能使用任何redux的api,只负责页面的呈现、交互等。 容器组件:负责和redux通信&…...

nodejs环境配置
啥是node.js 简单理解就是js运行环境 啥是npm 简单理解就是nodejs包管理工具,全称Node Package Manager 啥是cnpm npm的开源镜像,在国内使用cnpm替代npm可以起到加速的效果 https://npmmirror.com/ ①安装node.js https://nodejs.org/en/download/ 下载…...

数据治理之元数据管理Atlas
数据治理之元数据管理的利器——Atlas 一、数据治理与元数据管理 1.1 背景 为什么要做数据治理? 业务繁多,数据繁多,业务数据不断迭代。人员流动,文档不全,逻辑不清楚,对于数据很难直观理解,…...

15 Nacos客户端实例注册源码分析
Nacos客户端实例注册源码分析 实例客户端注册入口 流程图: 实际上我们在真实的生产环境中,我们要让某一个服务注册到Nacos中,我们首先要引入一个依赖: <dependency><groupId>com.alibaba.cloud</groupId>&l…...

C++将派生类赋值给基类(向上转型)
1.将派生类对象赋值给基类对象 #include <iostream> using namespace std;//基类 class A{ public:A(int a); public:void display(); public:int m_a; }; A::A(int a): m_a(a){ } void A::display(){cout<<"Class A: m_a"<<m_a<<endl; }//…...

使用Platform Designer创建Nios II 最小系统
Nios II简介 Nios II 软核处理器十多年前就有了,它和xilinx的MicroBlaze类似,性能相比硬核处理器要差得多,工程应用也不是很多,那还有必须学习一下吗?我个人认为了解一下Nios II开发流程,对intel FPGA开…...

CD销售管理系统
技术:Java、JSP等摘要:二十一世纪是一个集数字化,网络化,信息化的,以网络为核心的社会。中国的网民充分领略到“畅游天地间,网络无极限” 所带来的畅快。随着Internet的飞速发展,使得网络的应用…...

华为OD机试模拟题 用 C++ 实现 - 玩牌高手(2023.Q1)
最近更新的博客 【华为OD机试模拟题】用 C++ 实现 - 最多获得的短信条数(2023.Q1)) 文章目录 最近更新的博客使用说明玩牌高手题目输入输出描述示例一输入输出说明Code使用说明 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。 华为…...

Hive 的Stage如何划分?
Hive 的Stage如何划分,也是Hive SQL需要优化的一个点,这个问题,我也是在实际的工作中遇到的。所以我查询了网络的解答并记录下来,以便日后复习。以下是主要内容,enjoy~~~ 一个 Hive 任务会包含一个或多个 stage&#…...

《嵌入式应用开发》实验一、开发环境搭建与布局(上)
1. 搭建开发环境 去官网(https://developer.android.google.cn/studio)下载 Android Studio。 安装SDK(默认Android 7.0即可) 全局 gradle 镜像配置 在用户主目录下的 .gradle 文件夹下面新建文件 init.gradle,内容为…...

电子科技大学软件工程期末复习笔记(五):生产率和工作度量
目录 前言 重点一览 软件产品度量 测量软件生产率的两种方法 基于LOC测量 例题: 优点 缺点 基于功能点测量 例题: 本章小结 前言 本复习笔记基于王玉林老师的课堂PPT与复习大纲,供自己期末复习与学弟学妹参考用。 重点一览 这一部分内…...

400G光模块知识大全
400G光模块是目前高速传输领域中的一种先进产品,被广泛应用于高性能数据中心、通信网络、大规模计算、云计算等领域。本文将从400G光模块的定义、技术、产品型号、应用场景以及未来发展方向进行详细介绍。一、什么是400G光模块?400G光模块是指传输速率达…...

【Linux】零成本在家搭建自己的私人服务器解决方案
我这个人自小时候以来就特喜欢永久且免费的东西,也因此被骗过(花巨款买了永久超级会员最后就十几天)。 长大后骨子里也是喜欢永久且免费的东西,所以我不买服务器,用GitHubPage或者GiteePage搭建自己的静态私人博客&…...

Python 多线程、多进程和协程
一、多线程 threading 模块 threading 模块对象 对象描述Thread表示一个执行线程的对象Lock锁原语对象(与 thread 模块中的锁一样)RLock可重入锁对象,使单一线程可以(再次)获得已持有的锁(递归锁&#x…...

Xml 注解
文章目录XmlRootElement(name"MyRootElement")XmlAccessorType(XmlAccessType.FIELD)XmlElementXmlAttributeXmlValueXmlElementRefXmlRootElement(name“MyRootElement”) XmlRootElement(name"MyRootElement") public class AccessorType {public Strin…...