【基于SprintBoot+Mybatis+Mysql】电脑商城项目之上传头像和新增收货地址

      🧸安清h:个人主页 

   🎥个人专栏:【Spring篇】【计算机网络】【Mybatis篇】

🚦作者简介:一个有趣爱睡觉的intp,期待和更多人分享自己所学知识的真诚大学生。


目录

🚀1.上传头像 -持久层

✨1.1规划SQL语句

✨1.2设计接口和抽象方法

✨1.3 接口的映射

✨1.4单元测试

🚀2.上传头像 -业务层

✨2.1规划异常

✨2.2设计接口和抽象方法

✨2.3抽象方法实现

🚀3.上传头像 -控制层

✨3.1规划异常

✨3.2处理异常

✨3.3设计请求

✨3.4实现请求

🚀4.上传头像 -前端页面

🚀5.解决BUG

✨5.1更改默认的大小限制

✨5.2显示头像

✨5.3登录后显示头像

🎃1.新增收货地址-数据表创建

 🎃2.新增收货地址-创建实体类

🎃3.新增收货地址-持久层

✨1.1各功能的开发顺序

✨1.2规划需要执行的SQL语句

✨1.3接口与抽象方法

✨1.4配置SQL映射

🎃4.新增收货地址-业务层

✨4.1规划异常

✨4.2接口与抽象方法

✨4.3实现抽象方法 

🎃5.新增收货地址-控制层

✨5.1处理异常

✨5.2设计请求

✨5.3处理请求

🎃6.新增收货地址-前端页面


🚀1.上传头像 -持久层

✨1.1规划SQL语句

将对应的文件保存在操作系统上,然后再把这个文件路径给记录下来,因为记录路径是非常方便和便捷的,将来如果要打开这个文件,可以依据这个路径去找到这个文件。在数据库中需要保存这个文件的路径即可。将所有的静态资源(图片,文件,其他)放到某台电脑上,再把这台电脑作为一台单独的服务器使用。

对应的是一个更新用户avatar字段的sql语句。

update t_user set avatar=?,modified_user=?,modified_time=? 
where uid=?

✨1.2设计接口和抽象方法

 UserMapper接口中来定义个抽象方法用于修改用户的头像。

     /**
      * @Param("SQL映射文件中#{}占位符的变量名"):解决的问题,
      * 当SQL语句的占位符和映射接口方法参数名不一致时,需要将某个参数强行注入到某个占位符变量上时,
      * 可以使用@Param这个注解来标注映射关系
      *也就是说@Param("avatar")就相当于mapper.xml中的#{avatar}
      *
      * 根据用户的uid修改用户的头像
      * @param uid
      * @param avatar
      * @param modifiedUser
      * @param modifiedTime
      * @return 返回值为收影响的行数
      * */
     Integer updateAvatarByUid(
                       @Param("uid") Integer uid,
                       @Param("avatar") String avatar,
                       @Param("modifiedUser") String modifiedUser,
                       @Param("modifiedTime") Date modifiedTime);

✨1.3 接口的映射

UserMapper.xml文件中编写映射的SQL语句。

    <update id="updateAvatarByUid">
        update t_user set avatar=#{avatar},
                          modified_user=#{modifiedUser},
                          modified_time=#{modifiedTime}
        where uid=#{uid}
    </update>

✨1.4单元测试

在test->mapper包下的UserMapperTests类中编写测试方法updateAvatarByUid,代码如下:

    @Test
    public void updateAvatarByUid(){
        userMapper.updateAvatarByUid(7,"/upload/avatar.png","管理员",new Date());
    }

🚀2.上传头像 -业务层

✨2.1规划异常

1.用户数据不存在,找不到对应的用户数据。

2.更新的时候,有未知异常的产生。

前面已开发完成,无需重新开发。 

✨2.2设计接口和抽象方法

注释的快捷方法:/**+enter

    /**
     * 修改用户的头像
     * @param uid 用户id
     * @param avatar 用户的头像
     * @param username 用户的名称
     */
    void changeAvatar(Integer uid,
                      String avatar,
                      String username);

✨2.3抽象方法实现

编写业务层的更新头像的方法。

    @Override
    public void changeAvatar(Integer uid, String avatar, String username) {
        User result = userMapper.findByUid(uid);
        if(result == null || result.getIsDelete() == 1){
            throw new UserNotFoundException("用户数据不存在");
        }
        Integer rows = userMapper.updateAvatarByUid(uid,avatar, username, new Date());
        if(rows != 1){
            throw new UpdateException("更新时数据产生未知的异常");
        }
    }

测试业务层方法的执行。

    @Test
    public void changeAvatar(){
        userService.changeAvatar(7,"/upload/test.png","haha");
    }

🚀3.上传头像 -控制层

✨3.1规划异常

文件异常的父类:

        FileUploadException 泛指文件上传的异常。(父类)继承RuntimeException

父类是:FileUploadException

        FileEmptyException 文件为空的异常。

        FileSizeException 文件大小超出限制的异常。

        FileStateException 文件状态产生异常,即文件在打开状态时无法上传。

        FileTypeException 文件类型异常。

        FileUploadIOException 文件读写的异常。

 五个构造方法显式声明出来,再去继承相关的父类。

在controller包下新建包ex,在ex包里新建以上六个类。其中父类FileUploadException继承RuntimeException,其余五个类继承父类FileUploadException,在此不再做过多代码描述。

✨3.2处理异常

在基类BaseController类中进行编写和统一处理。

else if (e instanceof FileEmptyException) {
            result.setState(6000);
        } else if (e instanceof FileSizeException) {
            result.setState(6001);
        } else if (e instanceof FileTypeException) {
            result.setState(6002);
        } else if (e instanceof FileStateException) {
            result.setState(6003);
        } else if (e instanceof FileUploadIOException) {
            result.setState(6004);
        }

 在异常统一处理方法的参数列表上增加新的异常处理作为它的参数。

✨3.3设计请求

请求路径:/users/change_avatar

请求方式:POST(get请求提交数据2KB,不够清晰)

请求数据:HttpSession session,MutipartFile file

响应结果:JsonResult<String>(记录图片的路径,图片路径是一个串,即用String,如果不记录下来,再切换到其他页面就展示不出来了)

✨3.4实现请求

MultipartFile接口是SpringMVC提供一个接口,这个接口为我们包装了获取文件类型的数据(任何类型的file都可以接受),SpringBoot它又整合了SpringMVC,只需要在处理请求的方法参数列表上声明一个参数类型为MultipartFile,然后SpringBoot会自动将传递给服务的文件数据赋值给这个参数。

@RequestParam:表示请求中的参数,将请求中的参数注入请求处理方法的某个参数上,如果名称不一致则可以使用@RequestParam注解进行标记和映射。

/**
     *
     * @param session
     * @param file
     * @return
     */
    @RequestMapping("change_avatar")
    public JsonResult<String> changeAvatar(HttpSession session,
                                           @RequestParam("file") MultipartFile file) {
//        判断文件是否为空
        if(file.isEmpty()){
            throw new FileEmptyException("文件为空");
        }
//        判断文件大小是否超出限制
        if(file.getSize() > AVATAR_MAX_SIZE){
            throw new FileSizeException("文件超出限制");
        }
//        判断文件的类型是否为我们规定的和后缀类型
        String contentType = file.getContentType();
        if(!AVATAR_TYPE.contains(contentType)){
            throw new FileTypeException("文件类型不支持");
        }
//       上传的文件.../upload/文件.png
        String parent = session.getServletContext().getRealPath("upload");
//      File对象指向这个路径,File是否存在
      File dir = new File(parent);
      if(!dir.exists()){
          dir.mkdir();  //创建当前的目录
      }
//      获取到这个文件名称,UUID工具来将生成一个新的字符串作为文件名
//        返回的只是文件名,不包含目录结构.例如:avatar01.png。
//        在后续中,前面的avatar01即名称部分可以根据uid来生成一个随机的大小写字符串保存下来,
//        后缀需要保存下来
        String originalFilename =file.getOriginalFilename();
        System.out.println("OriginalFilename"+originalFilename);
        int index = originalFilename.lastIndexOf(".");  //查找字符串中最后一次出现的点号(.)的位置。
        String suffix = originalFilename.substring(index);  //从字符串的指定索引位置开始截取字符串,直到字符串的末尾。
        String filename = UUID.randomUUID().toString().toUpperCase() + suffix;
        File dest = new File(dir,filename);  //在dir下创建一个叫filename的文件,此时它是一个空文件
//        将参数file中的数据写入到空文件当中
        try{
            file.transferTo(dest);  //将file中的数据写入到dest文件中
        }catch (FileStateException e){
            throw new FileStateException("文件状态异常");
        }catch (IOException e){
            throw new FileUploadIOException("文件读写异常");
        }
        Integer uid = getuidFromSession(session);
        String username = getUsernameFromSession(session);
//        返回头像路径/upload/test.png,相对路径
        String avatar = "/upload"+filename;
        userService.changeAvatar(uid,avatar,username);
//        返回用户头像的路径给前端页面,将来用于头像的展示使用
        return new JsonResult<>(OK,avatar);
    }

这里没有办法测试,数据类型模拟不出来,file每一种类型的文件编码都不一样。 

🚀4.上传头像 -前端页面

在upload页面中编写上传头像的代码。.ajax()请求它可以把一个数据解析成一个大串,来拼接在参数名的后边,但file可以直接把一个文件作为一个整体提交。表单中action可以整体提交。

说明:如果直接使用表单进行文件的上传,需要给表单显示的添加一个属性:

enctype="multipart/form-data";声明出来,不会将目标文件的数据结构做修改再上传,不同字符串。

🚀5.解决BUG

✨5.1更改默认的大小限制

SpringMVC默认为1MB文件可以进行上传,手动的去修改SpringMVC默认上传文件爱的大小。

方式一:直接可以在配置文件中进行配置:

spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=15MB

✨5.2显示头像

页面中通过ajax的请求来提交文件,提交完成后返回了json串,解析出data中的数据,设置到img头像标签的src属性上就可以了。

1.在这里把submit改成button,因为submit不能够添加点击事件。

<input id="btn-change-avatar" type="button" class="btn btn-primary" value="上传" />

    2.这里原来的serialize提交的是一个串的类型,不能够解析文件,所以要换成类似一下方式:

    • serialize():可以将表单数据自动拼接成key=value的结构进行提交给服务器,一般提交是普通控件类型中的数据(text/password/radio/checkbox)。
    • FromData类:将表单中的数据保持原有的结构进行提交。new FromData($("#form")[0]);将form表单中某一个元素的整体值作为FromData()创建对象的数据,所以这个对象的格式就放在了这个对象当中,这样格式就不会被看做其他的对象被更改或调整。
    •  ajax默认处理数据时按照字符串的形式进行处理,以及默认会采用字符串的形式进行提交数据。关闭这两个默认的功能。
    new FromData($("#form")[0])

    ✨5.3登录后显示头像

    可以更新头像成功后,将服务器返回的头像路径保存在客户端的cookie对象中,然后每次检测到用户打开上传头像页面,在这个页面中通过ready()方法来自动监测去读取cookie中的头像并设到src上。

    1.设置cookie中的值:

    导入cookie.js的文件:

    <script src="../bootstrap3/js/jquery.cookie.js" type="text/javascript" charset="utf-8"></script>
    		<script src="../js/autoLogin.js" type="text/javascript"></script>

    调用cookie的方法:

    $.cookie(key,value,time);  //单位:天(存活时间)

    2.在upload.html页面先引入cookie.js文件

    <script src="../bootstrap3/js/jquery.cookie.js" type="text/javascript" charset="utf-8"></script>
    		<script src="../js/autoLogin.js" type="text/javascript"></script>

    3.在upload.html页面通过ready()自动读取cookie中的数据。

    $(document).ready(function (){
    				let avatar = $.cookie("avatar");
    				// 将cookie中的值获取出来设置到头像src属性上
    				$("#img-avatar").attr("src",avatar);
    			});

    5.4显示最新头像

    在更改完头像后,将最新的头像地址,再次保存到cookie,同名保存会覆盖原有cookie中的值。

    $.cookie("avatar",json.data,{expires: 7});

    🎃1.新增收货地址-数据表创建

    CREATE TABLE t_address (
    	aid INT AUTO_INCREMENT COMMENT '收货地址id',
    	uid INT COMMENT '归属的用户id',
    	`name` VARCHAR(20) COMMENT '收货人姓名',
    	province_name VARCHAR(15) COMMENT '省-名称',
    	province_code CHAR(6) COMMENT '省-行政代号',
    	city_name VARCHAR(15) COMMENT '市-名称',
    	city_code CHAR(6) COMMENT '市-行政代号',
    	area_name VARCHAR(15) COMMENT '区-名称',
    	area_code CHAR(6) COMMENT '区-行政代号',
    	zip CHAR(6) COMMENT '邮政编码',
    	address VARCHAR(50) COMMENT '详细地址',
    	phone VARCHAR(20) COMMENT '手机',
    	tel VARCHAR(20) COMMENT '固话',
    	tag VARCHAR(6) COMMENT '标签',
    	is_default INT COMMENT '是否默认:0-不默认,1-默认',
    	created_user VARCHAR(20) COMMENT '创建人',
    	created_time DATETIME COMMENT '创建时间',
    	modified_user VARCHAR(20) COMMENT '修改人',
    	modified_time DATETIME COMMENT '修改时间',
    	PRIMARY KEY (aid)
    ) ENGINE=INNODB DEFAULT CHARSET=utf8;
    

     🎃2.新增收货地址-创建实体类

    创建一个类Address类,在类中定义表的相关字段,采用驼峰命名方式,最后再去继承BaseEntity类。

    //收货地址数据的实体类
    public class Address extends BaseEntity {
        private Integer aid;
        private Integer uid;
        private String name;
        private String provinceName;
        private String provinceCode;
        private String cityName;
        private String cityCode;
        private String areaName;
        private String areaCode;
        private String zip;
        private String address;
        private String phone;
        private String tel;
        private String tag;
        private Integer isDefault;
    }

    🎃3.新增收货地址-持久层

    ✨1.1各功能的开发顺序

    当前收货地址功能模块:列表的展示、修改、删除、设置默认、新增收货地址。开发顺序:新增收货地址->列表展示->设置默认收货地址->删除收货地址->修改收货地址。

    ✨1.2规划需要执行的SQL语句

    1.对应的插入语句:

    insert into t_address(除aid外的字段列表) values(字段值列表)

    2. 一个用户的收货地址最多只能有20条数据对应。在插入用户数据之前先做查询操作。收货地址逻辑控制方面的一个异常。

    select count(*) from t_address where uid=?

    ✨1.3接口与抽象方法

    1.创建一个新的接口Address,在这个接口中来定义上面两个SQL语句抽象方法定义。

    /**
         * 插入用户的收货地址
         * @param address 收货地址数据
         * @return 受影响的行数
         */
        Integer insert(Address address);
    
        /**
         * 根据用户的id统计收货地址的数量
         * @param uid 用户的id
         * @return 当前用户的收货地址总数
         */
        Integer count(Integer uid);

    ✨1.4配置SQL映射

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.cy.store.mapper.AddressMapper">
        <resultMap id="AddressEntityMap" type="com.cy.store.entity.Address">
            <id column="aid" property="aid"/>
            <result column="province_code" property="provinceCode"/>
            <result column="province_name" property="provinceName"/>
            <result column="city_code" property="cityCode"/>
            <result column="city_name" property="cityName"/>
            <result column="area_code" property="areaCode"/>
            <result column="area_name" property="areaName"/>
            <result column="is_delete" property="isDelete"></result>
            <result column="created_user" property="createdUser"></result>
            <result column="created_time" property="createdTime"></result>
            <result column="modified_user" property="modifiedUser"></result>
            <result column="modified_time" property="modifiedTime"></result>
        </resultMap>
    
        <insert id="insert" useGeneratedKeys="true" keyProperty="aid">
            insert into t_address (
                uid, name, province_name, province_code, city_name, city_code, area_name, area_code, zip,
                address, phone, tel,tag, is_default, created_user, created_time, modified_user, modified_time
            ) values (
                         #{uid}, #{name}, #{provinceName}, #{provinceCode}, #{cityName}, #{cityCode}, #{areaName},
                         #{areaCode}, #{zip}, #{address}, #{phone}, #{tel}, #{tag}, #{isDefault}, #{createdUser},
                         #{createdTime}, #{modifiedUser}, #{modifiedTime}
                     )
        </insert>
    
        <select id="countByUid" resultType="java.lang.Integer">
            select count(*) from t_address where uid=#{uid}
        </select>
    </mapper>

    2.在test下的mapper文件夹下创建一个AddressMapperTests的测试类。

    @Test
        public void insert(){
            Address address = new Address();
            address.setUid(6);
            address.setPhone("15374583927");
            address.setName("备备");
            addressMapper.insert(address);
        }
    
        @Test
        public void countByUid(){
            Integer count = addressMapper.countByUid(6);
            System.out.println(count);
        }

    🎃4.新增收货地址-业务层

    ✨4.1规划异常

    1.如果用户是第一次插入收货地址,规则:当用户插入的地址是第一条时,需要将当前地址作为默认收货地址,如果查询到统计总数为0,则将当前地址的is_default设置为1。查询统计的结果为0不代表异常。

    查询到的结果大于20,这时候需要抛出业务控制的异常AddressCountLimitException异常。自行创建这个异常。

    public class AddressCountLimitException extends ServiceException{
        public AddressCountLimitException() {
            super();
        }
    
        public AddressCountLimitException(String message) {
            super(message);
        }
    
        public AddressCountLimitException(String message, Throwable cause) {
            super(message, cause);
        }
    
        public AddressCountLimitException(Throwable cause) {
            super(cause);
        }
    
        protected AddressCountLimitException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
            super(message, cause, enableSuppression, writableStackTrace);
        }
    }
    

    2.插入数据时产生异常。 

    ✨4.2接口与抽象方法

    1.创建一个IAddressService接口,在里面定义业务的抽象方法。

        void addNewAddress(Integer uid,String username,Address address);

    2.创建一个AddressServiceImpl实现类,去实现接口中的抽象方法。

    在配置文件中定义数据

    #Spring读取配置文件中数据:@Value(${user.address.max-count})
    user.address.max-count=20

    ✨4.3实现抽象方法 

    在实现类中实现业务控制 。

    //新增收货地址的实现类
    @Service
    public class AddressServiceImpl implements IAddressService {
        @Autowired
        private AddressMapper addressMapper;
    
        @Value("${user.address.max-count}")
        private Integer count;
        @Override
        public void addNewAddress(Integer uid, String username, Address address) {
    //        调用收货地址统计的方法
            Integer count = addressMapper.countByUid(uid);
            if(count >= 20){
                throw new AddressCountLimitException("用户收货地址超出上限");
            }
    
            //    uid、isDelete
            address.setUid(uid);
            Integer isDelete = count == 0?1:0;  //1表示默认,0表示不默认
            address.setIsDefault(isDelete);
    //    补全4项日志
            address.setCreatedUser(username);
            address.setCreatedTime(new Date());
            address.setModifiedUser(username);
            address.setModifiedTime(new Date());
            
    //        插入收货地址的方法
            Integer rows = addressMapper.insert(address);
            if(rows != 1){
                throw new InsertException("插入用户地址时产生未知异常");
            }
        }
    
    
    }
    

    3.测试业务层功能是否正常。AddressServiceTests测试来测试业务功能。

        @Test
        public void addNewAddress(){
            Address address = new Address();
            address.setPhone("11874583927");
            address.setName("备备");
            addressService.addNewAddress(6,"小明",address);
        }

    🎃5.新增收货地址-控制层

    ✨5.1处理异常

    业务层抛出了收货地址总数超标的异常,在BaseController中进行处理。

    else if(e instanceof AddressCountLimitException) {
                result.setState(4003);
                result.setMessage("用户收货地址超出上限的异常");
            }

    ✨5.2设计请求

    请求路径:/addresses/add_new_address

    请求方式:POST

    请求数据:Address address,HttpSession session

    响应结果:JsonResult<Void>

    ✨5.3处理请求

    在控制层创建AddressController来处理用户收货地址的请求和响应。

     @RequestMapping("add_new_address")
        public JsonResult<Void> addNewAddress(Address address, HttpSession session){
            Integer uid = getuidFromSession(session);
            String username = getUsernameFromSession(session);
            addressService.addNewAddress(uid,username,address);
            return new JsonResult<>(OK);
        }

    先登录用户,然后再访问http://localhost:8080/address/add_new_address?name=tom&phone=1826478328 进行测试。

    🎃6.新增收货地址-前端页面

    <script>
    			$("#btn-add-new-address").click(function (){
    				$.ajax({
    					url:"/addresses/add_new_address",
    					type:"POST",
    					data:$("#form-add-new-address").serialize(),
    					dataType:"JSON",
    					success:function (json){
    						if(json.state==200){
    							alert("新增收货地址成功");
    						}else{
    							alert("新增收货地址失败");
    						}
    					},
    					error:function (xhr){
    						alert("新增收货地址时产生未知的异常"+xhr.message);
    					}
    				});
    			});
    		</script>

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

    如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

    相关文章

    【大模型】硅基流动对接DeepSeek使用详解

    目录 一、前言 二、硅基流动介绍 2.1 硅基流动平台介绍 2.1.1 平台是做什么的 2.2 主要特点与功能 2.2.1 适用场景 三、硅基流动快速使用 3.1 账户注册 3.2 token获取 3.2.1 获取token技巧 四、Cherry-Studio对接DeepSeek 4.1 获取 Cherry-Studio 4.2 Cherry-Stud…

    告别2023~2024

    时间过得真快&#xff0c;距离上次写作2年多了。2023年&#xff5e;2024年的这两年时光里经历太多人生大事&#xff1a; 房贷&#xff0c;提前还贷买车&#xff0c;全款拿下租房搬家媳妇怀孕&#xff0c;独自照顾&#xff0c;……老人离世开盲盒喜提千金&#xff0c;百岁宴&am…

    基于yolov11的阿尔兹海默症严重程度检测系统python源码+onnx模型+评估指标曲线+精美GUI界面

    【算法介绍】 基于YOLOv11的阿尔兹海默症严重程度检测系统是一种创新的医疗辅助工具&#xff0c;旨在通过先进的计算机视觉技术提高阿尔兹海默症的早期诊断和病情监测效率。阿尔兹海默症是一种渐进性的神经退行性疾病&#xff0c;通常表现为认知障碍、记忆丧失和语言障碍等症状…

    2025我的第二次社招,写在春招之季

    先说一个好消息&#xff0c;C那些事 4w star了&#xff01; 前面断更了一个月&#xff0c;本篇文章就可以看到原因&#xff0c;哈哈。 大家好&#xff0c;我叫光城&#xff0c;腾讯实习转正做后端开发&#xff0c;后去小公司做数据库内核&#xff0c;经过这几年的成长与积累&am…

    使用Docker + Ollama在Ubuntu中部署deepseek

    1、安装docker 这里建议用docker来部署&#xff0c;方便简单 安装教程需要自己找详细的&#xff0c;会用到跳过 如果你没有安装 Docker&#xff0c;可以按照以下步骤安装&#xff1a; sudo apt update sudo apt install apt-transport-https ca-certificates curl software-p…

    Java集合List详解(带脑图)

    允许重复元素&#xff0c;有序。常见的实现类有 ArrayList、LinkedList、Vector。 ArrayList ArrayList 是在 Java 编程中常用的集合类之一&#xff0c;它提供了便捷的数组操作&#xff0c;并在动态性、灵活性和性能方面取得了平衡。如果需要频繁在中间插入和删除元素&#xf…

    【config目录】SpringBoot应用配置存放的地方

    application.properties之前总是存放于默认的resources目录下&#xff0c;现在想想其实是不合适的&#xff0c;上线后其实这个配置是需要更改的&#xff0c;因此我们不要打包到jar包中。 根据SpringBoot应用配置查找规则&#xff0c;如果在jar包中resources目录查找不到的话&a…

    洛谷 B3616 【模板】队列

    B3616 【模板】队列 - 洛谷 | 计算机科学教育新生态 题目描述 请你实现一个队列&#xff08;queue&#xff09;&#xff0c;支持如下操作&#xff1a; push(x)&#xff1a;向队列中加入一个数 x。pop()&#xff1a;将队首弹出。如果此时队列为空&#xff0c;则不进行弹出操作…

    布丁扫描:手机扫描的纯净之选

    在众多手机扫描软件中&#xff0c;布丁扫描凭借其纯粹的使用体验脱颖而出。它是一款功能强大且完全免费的手机端扫描工具&#xff0c;没有任何广告干扰&#xff0c;用户可以畅享纯净的使用过程。更值得一提的是&#xff0c;布丁扫描从未设置过充值入口&#xff0c;也不会在扫描…

    2025 CCF BDCI|“基于TPU平台的OCR模型性能优化”一等奖作品

    2024年12月&#xff0c;中国计算机学会在海南博鳌成功举办了第十二届CCF大数据与计算智能大赛&#xff08;简称2024 CCF BDCI&#xff09;。本届比赛的算能赛道吸引了1748名选手报名&#xff0c;经过激烈角逐&#xff0c;北京航空航天大学的“常务副SOTA”团队脱颖而出&#xf…

    22.[前端开发]Day22-CSS单位-CSS预处理器-移动端视口

    1 CSS常见单位详解 CSS中的单位 CSS中的绝对单位&#xff08; Absolute length units &#xff09; CSS中的相对单位&#xff08; Relative length units &#xff09; 1.em: 相对自己的font-size&#xff1b;如果自己没有设置, 那么会继承父元素的font-size 2.如果font-size中…

    网站改HTTPS方法

    默认的网站建设好后打开的样子那看起来像是钓鱼网站&#xff0c;现在的浏览器特别只能&#xff0c;就是你新买来的电脑默认的浏览器同样也会出现这样“不安全”提示。 传输协议启动了向全球用户安全传输网页内容的流程。然而&#xff0c;随着HTTPS的推出&#xff0c;传输协议通…

    MySQL的底层原理与架构

    前言 了解MySQL的架构和原理对于很多的后续很多的操作会有很大的帮助与理解。并且很多知识都与底层架构相关联。 了解MySQL架构 通过上面的架构图可以得知&#xff0c;Server层中主要由 连接器、查询缓存、解析器/分析器、优化器、执行器 几部分组成的&#xff0c;下面将主要…

    极客说|利用 Azure AI Agent Service 创建自定义 VS Code Chat participant

    作者&#xff1a;卢建晖 - 微软高级云技术布道师 「极客说」 是一档专注 AI 时代开发者分享的专栏&#xff0c;我们邀请来自微软以及技术社区专家&#xff0c;带来最前沿的技术干货与实践经验。在这里&#xff0c;您将看到深度教程、最佳实践和创新解决方案。关注「极客说」&a…

    艾蒿染色体水平基因组-文献精读111

    A chromosome-scale genome assembly of Artemisia argyi reveals unbiased subgenome evolution and key contributions of gene duplication to volatile terpenoid diversity 一项关于艾蒿&#xff08;Artemisia argyi&#xff09;的染色体尺度基因组组装揭示了无偏的亚基因…

    【Linux系统】线程:线程的优点 / 缺点 / 超线程技术 / 异常 / 用途

    1、线程的优点 创建和删除线程代价较小 创建一个新线程的代价要比创建一个新进程小得多&#xff0c;删除代价也小。这种说法主要基于以下几个方面&#xff1a; &#xff08;1&#xff09;资源共享 内存空间&#xff1a;每个进程都有自己独立的内存空间&#xff0c;包括代码段…

    光学和光子学模拟工具在 AR/VR 中的作用

    AR/VR 中的光学和光子学 增强现实 (AR) 和虚拟现实 (VR) 站在数字进化的前沿。光学和光子学这一复杂的科学深入研究了光的产生、检测和操控&#xff0c;在这一转变中发挥着至关重要的作用。 图 1 (a) 展示了 AR 系统的设计&#xff0c;强调了光学的关键作用。该图描绘了光的旅…

    U3D支持webgpu阅读

    https://docs.unity3d.com/6000.1/Documentation/Manual/WebGPU-features.html 这里看到已经该有的差不多都有了 WOW VFX更是好东西 https://unity.com/cn/features/visual-effect-graph 这玩意儿化简了纯手搓一个特效的流程 如果按原理说就是compute shader刷position&#…

    BFS算法篇——FloodFill问题的高效解决之道(下)

    文章目录 前言一. 图像渲染1.1 题目链接&#xff1a;https://leetcode.cn/problems/flood-fill/description/1.2 题目分析&#xff1a;1.3 思路讲解&#xff1a;1.4 代码实现&#xff1a; 二. 岛屿数量2.1 题目链接&#xff1a;https://leetcode.cn/problems/number-of-islands…

    DEEPSEEK与GPT等AI技术在机床数据采集与数字化转型中的应用与影响

    随着人工智能&#xff08;AI&#xff09;技术的迅猛发展&#xff0c;深度学习、自然语言处理等先进技术开始广泛应用于各行各业。在制造业尤其是机床行业&#xff0c;AI技术的融合带来了巨大的变革&#xff0c;尤其在机床数据采集与机床数字化方面的应用。本文将探讨DEEPSEEK、…