秒杀商品展示及商品秒杀

news2024/11/27 18:26:27

目录

  • 一、登录方式调整
  • 二、生成秒杀订单
    • 1、绑定秒杀商品
    • 2、查看秒杀商品
    • 3、订单秒杀
      • ①移除seata相关
      • ②生成秒杀订单
      • ③前端页面秒杀测试

一、登录方式调整

第1步:从zmall-common的pom.xml中移除spring-session-data-redis依赖
在这里插入图片描述

注意:
1)本章节中不采用spring-session方式,改用redis直接存储用户登录信息,主要是为了方便之后的jmeter压测;
2)这里只注释调用spring-session的依赖,保留redis的依赖;

第2步:在zmall-common公共模块中定义RedisConfig配置类

package com.zking.zmall.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String,Object> restTemplate(RedisConnectionFactory redisConnectionFactory){
        RedisTemplate<String,Object> redisTemplate=new RedisTemplate<>();
        //String类型Key序列化
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        //String类型Value序列化
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        //Hash类型Key序列化
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        //Hash类型Value序列化
        redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        return redisTemplate;
    }
}

这里一定要注意,最后在将RedisConnectionFactory设置到RedisTemplate中,不要在最前做该步操作,不然会导致String和Hash类型的序列化无效,将采用默认的JdkSerializationRedisSerializer进行序列化,从而导致保存的key前缀出现乱码问题。细心!!!

第3步:在zmall-common公共模块中配置redis相关服务
IRedisServcie

package com.zking.zmall.service;

import com.zking.zmall.model.User;

public interface IRedisService {

    /**
     * 将登陆用户对象保存到Redis中,并以token来命名
     * @param token
     * @param user
     */
    void setUserToRedis(String token, User user);

    /**
     * 根据token令牌从Redis中获取User对象
     * @param token
     * @return
     */
    User getUserByToken(String token);
}

RedisServcieImple

package com.zking.zmall.service.impl;

import com.zking.zmall.model.User;
import com.zking.zmall.service.IRedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class RedisServiceImpl implements IRedisService {

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    @Override
    public void setUserToRedis(String token, User user) {
        String key="user:"+token;
        redisTemplate.boundValueOps(key).set(user,7200, TimeUnit.SECONDS);
    }

    @Override
    public User getUserByToken(String token) {
        return (User) redisTemplate.opsForValue().get("user:"+token);
    }
}

用户登录成功后,将用户对象保存到Redis中,并设置超时时间7200秒。

第4步:在zmall-common公共模块中配置,配置自定义参数解析UserArgumentResolver、WebConfig
UserArgumentResolver

package com.zking.zmall.config;

import com.zking.zmall.exception.BusinessException;
import com.zking.zmall.model.User;
import com.zking.zmall.service.IRedisService;
import com.zking.zmall.util.CookieUtils;
import com.zking.zmall.util.JsonResponseStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.servlet.http.HttpServletRequest;

/**
 * 自定义用户参数类
 */
@Component
public class UserArgumentResolver implements HandlerMethodArgumentResolver {

    @Autowired
    private IRedisService redisService;

    /**
     * 只有supportsParameter方法执行返回true,才能执行下面的resolveArgument方法
     * @param methodParameter
     * @return
     */
    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        Class<?> type = methodParameter.getParameterType();
        return type== User.class;
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter,
                                  ModelAndViewContainer modelAndViewContainer,
                                  NativeWebRequest nativeWebRequest,
                                  WebDataBinderFactory webDataBinderFactory) throws Exception {
        HttpServletRequest req= (HttpServletRequest) nativeWebRequest.getNativeRequest();
        //从cookie获取token令牌
        String token = CookieUtils.getCookieValue(req, "token");
        //判断cookie中的token令牌是否为空
        if(StringUtils.isEmpty(token))
            throw new BusinessException(JsonResponseStatus.TOKEN_ERROR);
        //根据token令牌获取redis中存储的user对象,方便jmeter测试
        User user = redisService.getUserByToken(token);
        if(null==user)
            throw new BusinessException(JsonResponseStatus.TOKEN_ERROR);
        return user;
    }
}

WebConfig

package com.zking.zmall.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

@Component
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private UserArgumentResolver userArgumentResolver;

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(userArgumentResolver);
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        //添加静态资源访问映射
        //registry.addResourceHandler("/static/**")
        //        .addResourceLocations("classpath:/static/");
    }
}

第5步:用户登录业务调整,将spring-session方式更改为redis方式存储登录用户信息。

package com.zking.zmall.service.impl;

import com.alibaba.nacos.common.utils.MD5Utils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zking.zmall.mapper.UserMapper;
import com.zking.zmall.model.User;
import com.zking.zmall.service.IUserService;
import com.zking.zmall.util.CookieUtils;
import com.zking.zmall.util.JsonResponseBody;
import com.zking.zmall.util.JsonResponseStatus;
import com.zking.zmall.vo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.UUID;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author xnx
 * @since 2023-02-06
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    @Autowired
    private RedisServiceImpl redisService;

    @Override
    public JsonResponseBody<?> userLogin(UserVo user,
                                         HttpServletRequest req,
                                         HttpServletResponse resp) {
        //1.判断用户账号和密码是否为空
        if(StringUtils.isEmpty(user.getLoginName())||
                StringUtils.isEmpty(user.getPassword()))
            return new JsonResponseBody<>(JsonResponseStatus.USERNAME_OR_PWD_EMPTY);
        //2.根据用户名查询数据对应的用户信息
        User us = this.getOne(new QueryWrapper<User>()
                .eq("loginName", user.getLoginName()));
        //3.判断us用户对象是否为空
        if(null==us)
            return new JsonResponseBody<>(JsonResponseStatus.USERNAME_ERROR);
        try {
            //MD5加密转换处理
            String pwd= MD5Utils.md5Hex(user.getPassword().getBytes());
            //4.判断输入密码与数据库表存储密码是否一致
            if(!us.getPassword().equals(pwd)){
                return new JsonResponseBody<>(JsonResponseStatus.PASSWORD_ERROR);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return new JsonResponseBody<>(JsonResponseStatus.ERROR);
        }
//        //5.通过UUID生成token令牌并保存到cookie中
//        String token= UUID.randomUUID().toString().replace("-","");
//        //将随机生成的Token令牌保存到Cookie中,并设置1800秒超时时间
//        CookieUtils.setCookie(req,resp,"token",token,7200);
//        //6.将token令牌与spring session进行绑定并存入redis中
//        HttpSession session = req.getSession();
//        session.setAttribute(token,us);
        //5.通过UUID生成token令牌并保存到cookie中
        String token= UUID.randomUUID().toString().replace("-","");
        //将随机生成的Token令牌保存到Cookie中,并设置1800秒超时时间
        CookieUtils.setCookie(req,resp,"token",token,7200);
        //6.将token令牌与spring session进行绑定并存入redis中
        //HttpSession session = req.getSession();
        //session.setAttribute(token,us);
        //将token令牌与user绑定后存储到redis中,方便jmeter测试
        redisService.setUserToRedis(token,us);
        return new JsonResponseBody<>(token);
    }
}

这里采用Redis方式直接存储登录用户信息,只为后续使用Jmeter压测时提供便利。正常运行使用项目还是可以使用spring-session方式。

第6步:修改商品服务zmall-product模块中的index方法,将之前从HttpSession中获取登录用户信息改换成User对象参数方式

@RequestMapping("/index.html")
public String index(Model model, User user){
    System.out.println(user);
}

在调用index方法之前,先由自定义的参数解析器进行参数解析并返回解析结果User,所以在这里可直接在方法参数中获取的User对象。

第7步:重启zmall-user和zmall-product模块,完成用户登录后,直接在浏览器地址栏输入:http://zmall.com/product-serv/index.html,查看zmall-product模块中的控制台是否已经获取到登录用户对象信息。
在这里插入图片描述

二、生成秒杀订单

1、绑定秒杀商品

添加sellDetail.html页面到zmall-product模块中;实现首页秒杀商品展示,必须保证秒杀商品状态为已激活、且秒杀商品的活动时间为有效时间范围之内。

index.html

 <#if kills??>
     <#list kills as g>
         <div class="sell_${g_index?if_exists+1}">
             <div class="sb_img"><a href="${ctx}/sellDetail.html?pid=${g.item_id}"><img src="${g.fileName}" width="242" height="356" /></a></div>
             <div class="s_price"><span>${g.price}</span></div>
             <div class="s_name">
             <h2><a href="${ctx}/sellDetail.html?pid=${g.item_id}">${g.name}</a></h2>
             倒计时:<span>1200</span><span>30</span><span>28</span></div>
         </div>
     </#list>
 </#if>

sellDetail.html

<table border="0" style="width:100%; margin-bottom:50px;" cellspacing="0" cellpadding="0">
                  <tr valign="top">
                    <td width="315">
                    	<div class="lim_name">${(prod.name)!}</div>
                        <div class="lim_price">
                        	<span class="ch_txt">¥${(prod.price)!}</span>
                       		<a href="javascript:void(0);" class="ch_a" pid="${(prod.item_id)!}" price="${(prod.price)!}">抢购</a>
                        </div>
                        <div class="lim_c">
                        	<table border="0" style="width:100%; color:#888888;" cellspacing="0" cellpadding="0">
                              <tr>
                                <td width="35%">市场价 </td>
                                <td width="65%">折扣</td>
                              </tr>
                              <tr style="font-family:'Microsoft YaHei';">
                                <td style="text-decoration:line-through;">¥${(prod.price)!}</td>
                                <td>8.0</td>
                              </tr>
                            </table>
                        </div>
                        <div class="lim_c">
                        	<div class="des_choice">
                                <span class="fl">型号:</span>
                                <ul>
                                    <li class="checked">30ml<div class="ch_img"></div></li>
                                    <li>50ml<div class="ch_img"></div></li>
                                    <li>100ml<div class="ch_img"></div></li>
                                </ul>
                            </div>
                            <div class="des_choice">
                                <span class="fl">颜色:</span>
                                <ul>
                                    <li>红色<div class="ch_img"></div></li>
                                    <li class="checked">白色<div class="ch_img"></div></li>
                                    <li>黑色<div class="ch_img"></div></li>
                                </ul>
                            </div>
                        </div>
                        <div class="lim_c">
                        	<span class="fl">数量:</span><input type="text" value="${(prod.total)!}" class="lim_ipt" />
                        </div>
                        <div class="lim_clock">
                        	距离团购结束还有<br />
                            <span>1200 时 30 分 28 秒</span>
                        </div>
                    </td>
                    <td width="525" align="center" style="border-left:1px solid #eaeaea;"><img src="${(prod.fileName)!}" width="460" height="460" /></td>
                  </tr>
                </table>

web层

@RequestMapping("/index.html")
    public ModelAndView toIndex(User user){
        System.out.println("user:"+ JSON.toJSONString(user));
        ModelAndView mv=new ModelAndView();
        //获取热卖商品列表
        List<Product> hot = productService.list(new QueryWrapper<Product>()
                .orderByDesc("hot")
                .last("limit 4"));

        //获取显示秒杀商品
        List<Map<String, Object>> maps = productService.queryKillProdNews();

        mv.addObject("kills",maps);
        mv.addObject("hots",hot);
        mv.setViewName("index");


        return mv;
    }

service层

public interface IProductService extends IService<Product> {
    void updateStock(Integer pid,Integer num);

    /**
     * 首页显示秒杀商品查询
     * @return
     */
    List<Map<String,Object>> queryKillProdNews();

    /**
     * 根据商品ID查询秒杀商品信息
     * @param pid 秒杀商品ID
     * @return
     */
    Map<String,Object> queryKillProdById(Integer pid);
}
@Override
    public List<Map<String, Object>> queryKillProdNews() {
        return productMapper.queryKillProdNews();
    }

    @Override
    public Map<String, Object> queryKillProdById(Integer pid) {
        return productMapper.queryKillProdById(pid);
    }

mapper层

@Repository
public interface ProductMapper extends BaseMapper<Product> {
//    @MapKey("queryKillProdNews")
    List<Map<String,Object>> queryKillProdNews();

    Map<String,Object> queryKillProdById(Integer pid);
}

productMapper.xml

<select id="queryKillProdNews" resultType="java.util.Map">
        select
        k.id,k.item_id,p.name,p.price,p.fileName
        from
        zmall_kill k,zmall_product p
        where k.item_id=p.id and
        k.is_active=1 and
        (now() between start_time and end_time)
        order by k.create_time desc
        limit 4
    </select>
    <select id="queryKillProdById" resultType="java.util.Map">
        select
        k.id,k.item_id,k.total,p.name,p.price,p.fileName
        from
        zmall_kill k,zmall_product p
        where k.item_id=p.id and k.is_active=1 and item_id=#{value}
    </select>

在这里插入图片描述

2、查看秒杀商品

点击限时秒杀中的秒杀商品,根据秒杀商品ID查询秒杀商品详情信息并跳转到sellDetail.html页面展示秒杀商品信息。

@RequestMapping("/sellDetail.html")
    public String sellDetail(@RequestParam Integer pid, Model model){
        //根据商品ID查询秒杀商品信息
        Map<String, Object> prod = productService.queryKillProdById(pid);
        model.addAttribute("prod",prod);
        return "sellDetails";
    }

在这里插入图片描述

3、订单秒杀

①移除seata相关

第1步:先注释掉zmall-order和zmall-product模块中的seata依赖

第2步:分别删掉zmall-order和zmall-product模块中resources目录下的bootstrap.xml和register.conf文件

seata分布式事务,进行jmeter压测秒杀订单接口效率太低(1000个并发请求,吞吐量为4.5/s)

②生成秒杀订单

将SnowFlake雪花ID生成工具类导入到zmall-common模块中utils,然后再生成秒杀订单时使用雪花ID来充当秒杀订单编号;在zmall-order模块中完成秒杀订单生成工作。
IOrderService

public interface IOrderService extends IService<Order> {
    Order createOrder(Integer pid,Integer num);

    /**
     * 生成秒杀订单
     * @param user 登陆用户对象
     * @param pid  秒杀商品ID
     * @param price 秒杀商品价格
     * @return
     */
    JsonResponseBody<?> createKillOrder(User user, Integer pid, Float price);
}

OrderServiceImpl

@Autowired
private KillServiceImpl killService;
@Autowired
private OrderDetailServiceImpl orderDetailService;

@Transactional
    @Override
    public JsonResponseBody<?> createKillOrder(User user, Integer pid, Float price) {
        //1.根据秒杀商品编号获取秒杀商品库存是否为空
        Kill kill = killService.getOne(new QueryWrapper<Kill>().eq("item_id",pid));
        if(kill.getTotal()<1)
            throw new BusinessException(JsonResponseStatus.STOCK_EMPTY);
        //2.秒杀商品库存减一
        killService.update(new UpdateWrapper<Kill>()
                .eq("item_id",pid)
                .setSql("total=total-1"));
        //3.生成秒杀订单及订单项
        SnowFlake snowFlake=new SnowFlake(2,3);
        Long orderId=snowFlake.nextId();
        int orderIdInt = new Long(orderId).intValue();
        //创建订单
        Order order=new Order();
        order.setUserId(user.getId());
        order.setLoginName(user.getLoginName());
        order.setCost(price);
        order.setSerialNumber(orderIdInt+"");
        this.save(order);
        //创建订单项
        OrderDetail orderDetail=new OrderDetail();
        orderDetail.setOrderId(orderIdInt);
        orderDetail.setProductId(pid);
        orderDetail.setQuantity(1);
        orderDetail.setCost(price);
        orderDetailService.save(orderDetail);
        return new JsonResponseBody();
    }

OrderController

@RequestMapping("/createKillOrder/{pid}/{price}")
    @ResponseBody
    public JsonResponseBody<?> createKillOrder(User user,
                                               @PathVariable("pid") Integer pid,
                                               @PathVariable("price") Float price){
        return orderService.createKillOrder(user,pid,price);
    }

③前端页面秒杀测试

在sellDetail.html页面中添加订单秒杀JS方法。

<script>
    $(function(){
        $('.ch_a').click(function(){
            let pid=$(this).attr('alt');
            console.log(pid);
            $.post('http://zmall.com/order-serv/createKillOrder',{pid:pid},function(rs){
                console.log(rs);
                if(rs.code===200)
                    alert('秒杀成功');
                else
                    alert(rs.msg);
            },'json');
        });
    });
</script>

在这里插入图片描述

这里虽然已经能正常展示秒杀效果,但是还是存在很多问题,比如:重复抢购问题等等问题。

注意:

 $.post('http://user.zmall.com/userLogin',{
                loginName:loginName,
                password:password
            },function(rs){
                console.log(rs);
                if(rs.code===200){
                    location.href='http://product.zmall.com/index.html';
                }else{
                    alert(rs.msg);
                }
            },'json');

post方式不能跨二级域名发送请求,location.href可以跨二级域名发送请求;

$(function(){
       $('.ch_a').click(function(){
            let pid=$(this).attr("pid");
            let price=$(this).attr("price");
            console.log("pid=%s,price=%s",pid,price);
           $.post('http://zmall.com/order-serv/createKillOrder/'+pid+'/'+price,{},function(rs){
               console.log(rs);
               if(rs.code===200)
                   alert('秒杀成功');
               else
                   alert(rs.msg);
           },'json');
       });
    });

$.post(‘http://zmall.com/order-serv/createKillOrder/’+pid+‘/’+price,{},function(rs){});能够正常访问;

$.post(‘http://order.zmall.com/createKillOrder/’+pid+‘/’+price,{},function(rs){});则会出现跨域问题;

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

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

相关文章

RocketMQ Broker消息处理流程及部分源码解析

&#x1f34a; Java学习&#xff1a;Java从入门到精通总结 &#x1f34a; 深入浅出RocketMQ设计思想&#xff1a;深入浅出RocketMQ设计思想 &#x1f34a; 绝对不一样的职场干货&#xff1a;大厂最佳实践经验指南 &#x1f4c6; 最近更新&#xff1a;2023年2月10日 &#x…

wait 和 notify

由于线程之间是抢占式执行的, 因此线程之间执行的先后顺序难以预知.但是实际开发中有时候我们希望合理的协调多个线程之间的执行先后顺序. wait() / wait(long timeout): 让当前线程进入等待状态.notify() / notifyAll(): 唤醒在当前对象上等待的线程. 注意: wait, notify,…

ChatGPT大火,你被这四种手段“割韭菜”了嘛?

目录 黑灰产利用ChatGPT的牟利方式 1、贩卖ChatGPT账号 2、售卖ChatGPT注册工具 3、制作山寨版ChatGPT 4、制作ChatGPT教程 ChatGPT对业务安全的帮助 提升漏洞挖掘的广度和精度 提升业务安全情报的效率和广度 ChatGPT自身的安全隐患 2022年11月&#xff0c;ChatGPT发布时&#…

FastJson序列化和反序列化时处理数据

FastJson序列化和反序列化时处理数据序列化时处理数据反序列化时处理json数据中的值https://github.com/alibaba/fastjson/wiki/PropertyProcessable_cn https://www.cnblogs.com/ariter/p/14254342.html 序列化时处理数据 1、自定义注解用来标识json数据需要处理的属性 impo…

ESP32S3系列--SPI主机驱动详解(二)

一、目的 在上一篇《ESP32S3系列--SPI主机驱动详解(一)》我们介绍了ESP32S3的SPI外设的基本情况以及主机驱动的一些知识点,包括主机驱动的特点、总线的初始化、从设备的加入、传输模式分类等等。 本篇我们将从代码角度帮助大家进一步理解传输接口的一些细节问题。 二、实战 …

6个常见的 PHP 安全性攻击

了解常见的PHP应用程序安全威胁&#xff0c;可以确保你的PHP应用程序不受攻击。因此&#xff0c;本文将列出 6个常见的 PHP 安全性攻击&#xff0c;欢迎大家来阅读和学习。 1、SQL注入 SQL注入是一种恶意攻击&#xff0c;用户利用在表单字段输入SQL语句的方式来影响正常的SQL执…

Blender——物体的随机分布

问题描述将正方体随机分布在平面上。问题解决点击编辑-->偏好设置。在【插件】中的【物体】类型中勾选【Object: Scatter Objects】。右下的活动工具与工作区设置中就会出现【物体散列】的模块&#xff0c;可以调节各参数。选中正方体&#xff0c;按着Shift&#xff0c;选中…

关于 OAuth 你又了解哪些?

作者罗锦华&#xff0c;API7.ai 技术专家/技术工程师&#xff0c;开源项目 pgcat&#xff0c;lua-resty-ffi&#xff0c;lua-resty-inspect 的作者。 OAuth 的背景 OAuth&#xff0c;O 是 Open&#xff0c;Auth 是授权&#xff0c;也就是开放授权的意思。OAuth 始于 2006 年&a…

error when starting dev server:Error: Failed to resolve vue/compiler-sfc.

对于node 的包管理工具&#xff0c;我一般习惯用 yarn&#xff0c;但是最近使用 yarn 创建前端项目的时候出了一些问题。yarn create vite vite-project报错如下&#xff1a;error when starting dev server:Error: Failed to resolve vue/compiler-sfc.vitejs/plugin-vue requ…

[Arxiv 2022] A Novel Plug-in Module for Fine-Grained Visual Classification

Contents MethodPlug-in ModuleLoss functionExperimentsReferencesMethod Plug-in Module Backbone:为了帮助模型抽取出不同尺度的特征,作者在 backbone 里加入了 FPNWeakly Supervised Selector:假设 backbone 的 i i

LayUI渲染数据失败之Ajax异步交互

案例 在layui中调用jquery的ajxa&#xff0c;返回数据&#xff0c;赋值给全局变量&#xff0c;通过DOM渲染到页面。 //定义变量 let sale;//定义请求 $.ajax({type: "GET",url: "http://localhost:8080/product/sale",data: null,dataType: "json&q…

离散数学 课时一 命题逻辑的基本概念

1 命题 1、命题&#xff1a;可以判断其真值的陈述句 2、真值&#xff1a;真或者假(1或者0) 3、真命题&#xff1a;真值为真的命题 4、假命题&#xff1a;真值为假的命题 5、原子命题&#xff1a;不可以再被分解成更简单的命题 6、复合命题&#xff1a;由原子命题通过联结词联结…

12 Day:内存管理

前言&#xff1a;今天我们要完成我们操作系统的内存管理&#xff0c;以及一些数据结构和小组件的实现&#xff0c;在此之前大家需要了解我们前几天一些重要文件的内存地址存放在哪&#xff0c;以便我们更好的去编写内存管理模块 一&#xff0c;实现ASSERT断言 不知道大家有没有…

< Linux >:Linux 进程概念 (4)

目录 五、孤儿进程 六、进程优先级 6.1、基本概念 6.2、查看时实系统进程 6.3、PRI and NI 七、其他概念 四、X 状态&#xff1a;死亡状态 所谓进程处于 X 状态(死亡状态)代表的就是该进程已经死亡了&#xff0c;即操作系统可以随时回收它的资源(操作系统也可以…

代码质量与安全 | 开发人员必备的安全编码实践指南

在任何新的软件开发项目开始时&#xff0c;您就应该考虑软件安全。开始一个新项目或许会令人望而生畏&#xff0c;因为有许多的决定要做&#xff0c;有许多想法必须考虑清楚。通常来说&#xff0c;这些决定和想法包括了定义项目需求、选择正确的流程、选择正确的工具以及确保软…

QML- 导入库包语法

QML- 导入库包语法一、概述二、Import语句的语法1. Module (namespace) 模块(命名空间)导入1. 非模块命名空间的导入2. 导入到限定局部命名空间2. 路径 import1. 本地目录导入2. 远程目录3. JavaScript资源导入三、QML导入路径四、调试一、概述 import 语句其实在QML文档里面体…

Springboot扩展点之SmartInstantiationAwareBeanPostProcessor

前言这是Springboot扩展点系列的第5篇了&#xff0c;主要介绍一下SmartInstantiationAwareBeanPostProcessor扩展点的功能特性、和实现方式。SmartInstantiationAwareBeanPostProcessor与其他扩展点最明显的不同&#xff0c;就是在实际的业务开发场景中应用到的机会并不多&…

机器学习框架sklearn之特征降维

目录特征降维概念特征选择过滤式①低方差特征过滤②相关系数③主成分分析特征降维 0维 标量 1维 向量 2维 矩阵 概念 降维是指在某些限定条件下&#xff0c;降低随机变量&#xff08;特征&#xff09;个数&#xff0c;得到一组“不相关”主变量的过程 注&#xff1a;正是…

微信小程序 java 医生预约挂号答疑问询系统

生预约答疑系统用户端是基于微信小程序端&#xff0c;医生和管理员是基于网页后端。本系统分为用户&#xff0c;管理员&#xff0c;医生三个角色&#xff0c;用户的主要功能是注册登陆小程序&#xff0c;查看新闻资讯&#xff0c;查看医生列表&#xff0c;预约医生&#xff0c;…

【unity细节】关于资源商店(Package Maneger)无法下载资源问题的解决

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 秩沅 原创 收录于专栏&#xff1a;unity细节和bug ⭐关于资源商店为何下载不了的问题⭐ 文章目录⭐关于资源商店为何下载不了的问题…