SpringBoot项目-个人博客系统的实现

news2024/9/25 19:24:43

1.博客系统简要分析

在这里插入图片描述
一共有6个网页,分别是博客列表页面,博客详情页面,发布博客页面,博客登陆页面,博客更新页面,修改个人信息页面(暂未实现),我们要实现的功能有,实现博客列表的展示页面,博客详情页面的展示功能,用户登录功能,显示用户信息功能,编辑博客功能,发布博客功能,删除博客功能,退出登录功能
我们现在就开始写吧

2.创建springBoot项目

1.创建项目,勾选需要的依赖

在这里插入图片描述
在这里插入图片描述

2.删除无用的目录及文件

在这里插入图片描述

4.创建框架

在这里插入图片描述

3.配置文件(选择yml)

application.xml

spring:
  profiles:
    active: dev
logging:
  file:
    path: logs/
  level:
    root: info

application-dev.xml

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/java_blog_spring?characterEncoding=utf8
    username: root
    password: 111111
    driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
  configuration: # 配置打印 MyBatis 执行的 SQL
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true  #自动驼峰转换
  mapper-locations: classpath:mapper/***Mapper.xml

application-prod.xml

spring:
  datasource:
      url: jdbc:mysql://127.0.0.1:3306/java_blog_spring?characterEncoding=utf8
      username: root
      password: 111111
      driver-class-name: com.mysql.cj.jdbc.Driver
mybatis: #上线就不用打印mybatis执行日志
  configuration:
    map-underscore-to-camel-case: true  #自动驼峰转换

3.数据库准备

这个项目的数据库表比较简单
只有两个表

1.设计表结构

在这里插入图片描述

2.建表sql

-- 建表SQL
create database if not exists `java_blog_spring1` charset utf8mb4;
-- 用户表
drop table if exists `java_blog_spring`.`user`;
CREATE TABLE `java_blog_spring`.`user` (
 `id` INT NOT NULL AUTO_INCREMENT,
 `user_name` VARCHAR(128) NOT NULL,
 `password` VARCHAR(128) NOT NULL,
 `photo`  VARCHAR(128) NOT NULL,
 `github_url` VARCHAR(128) NULL,
 `delete_flag` TINYINT(4) NULL DEFAULT 0,
 `create_time` TIMESTAMP NULL DEFAULT current_timestamp(),
 PRIMARY KEY (`id`),
 UNIQUE INDEX `user_name_UNIQUE` (`user_name` ASC))
ENGINE = InnoDB DEFAULT CHARACTER SET = utf8mb4 COMMENT = '用户表';
-- 博客表
drop table if exists `java_blog_spring`.`blog`;
CREATE TABLE `java_blog_spring`.`blog` (
 `id` INT NOT NULL AUTO_INCREMENT,
 `title` VARCHAR(200) NULL,
 `content` TEXT NULL,
 `user_id` INT(11) NULL,
 `delete_flag` TINYINT(4) NULL DEFAULT 0,
 `create_time` TIMESTAMP NULL DEFAULT current_timestamp(),
 PRIMARY KEY (`id`))
ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT = '博客表';
-- 新增用户信息
insert into `java_blog_spring`.`user` (`user_name`, `password`,`photo`,`github_url`)values
("zhangsan","123456","pic/doge.jpg","https://gitee.com/bubble-fish666/class-java45");
insert into `java_blog_spring`.`user` (`user_name`, `password`,`photo`,`github_url`)values
("lisi","123456","pic/doge.jpg","https://gitee.com/bubble-fish666/class-java45");
insert into `java_blog_spring`.`blog` (`title`,`content`,`user_id`) values
("第一篇博客","111我是博客正文我是博客正文我是博客正文",1);
insert into `java_blog_spring`.`blog` (`title`,`content`,`user_id`) values
("第一篇博客","222我是博客正文我是博客正⽂我是博客正文",2);

use java_blog_spring;
-- 查询两个表的数据
select * from user;
select * from blog;

4.接口设计

  1. 获取所有的博客列表

5.数据库相关查询操作

  1. 根据用户id查询用户信息
  2. 根据用户名称查询用户
  3. 查询所有未删除的博客(按照时间降序排列)
  4. 根据博客id查询博客详情
  5. 插入一条博客
  6. 根据博客id更新博客
  7. 删除博客
  8. 根据用户id查询博客数量

6.写代码准备工作

1.model包下,创建Java实体类

我们在配置文件中配置了数据库表字段到类属性的自动驼峰转换,所以可以不用进行重命名

自动驼峰映射

configuration:
 map-underscore-to-camel-case: true

1.User类

@Data
public class User {
    // java中属性使用小驼峰命名
    // 我们配置了自动驼峰转换
    private Integer id;
    private String userName;
    private String passWord;
    private String photo;
    private String githubUrl;
    private Byte deleteFlag;
    private Date createTime;
}

2.Blog类

@Data
@Data
public class Blog {
    private Integer id;
    private String title;
    private String content;
    private Integer userId;
    private Integer deleteFlag;
    private Date createTime;
}

2.mapper层

  • 简单的sql语句我们使用注解实现
  • 复杂的sql语句使用xml配置文件实现

1.userMapper接口

@Mapper
public interface UserMapper {
    /**
     * 根据用户id查询用户信息
     * @param id
     * @return
     */
    @Select("select user_name, password, photo, github_url from user where delete_flag = 0 and id = #{id}")
    User selectById(Integer id);

    /**
     * 根据用户名称查询用户
     * @param userName
     * @return
     */
    @Select(("select user_name, password, photo, github_url from user where delete_flag = 0 and user_name = #{userName}"))
    User selectByName(String userName);

}

2.BlogMapper接口

@Mapper
public interface BlogMapper {

    /**
     * 查询所有未删除的博客.按照时间降序排列
     * @return
     */
    @Select("select id, title, content, user_id, create_time from blog where delete_flag = 0 order by create_time;")
    List<Blog> selectAllBlog();

    /**
     * 根据博客id查询博客详情
     * @param blogId
     * @return
     */
    @Select("select id, title, content, user_id, create_time from blog where delete_flag = 0 and id = #{blogId}")
    Blog selectByBlogId(Integer blogId);

    /**
     * 插入一条博客
     * @param blog
     * @return
     */
    @Insert("insert into blog (title, content, user_id) values (#{title, #{content}, #{userId})")
    Integer insertBlog(Blog blog);

    /**
     * 根据博客id更新博客
     * 删除博客就是把delete_id改为1
     * @return
     */
    Integer updateBlog(Blog blog);

    /**
     * 根据用户id查询博客数量
     * @param userId
     * @return
     */
    @Select("select count(id) from blog where delete_flag = 0 and user_id = #{userId}")
    Integer selectBlogCount(Integer userId);

}

因为更新博客内容的sql语句比较复杂,我们就不采用注解的方式,使用配置文件的方式来写

3.BlogMapper.xml

<?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.example.springblog.mapper.BlogMapper">

    <update id="updateBlog">
        update blog
        <set>
            <if test="title!=null">title=#{title},</if>
            <if test="content!=null">content=#{content},</if>
            <if test="deleteFlag!=null">delete_flag=#{deleteFlag},</if>
        </set>
        <where>
            id = #{id}
        </where>
    </update>
</mapper>

3.Service包下

service层被称作业务层,它用来处理逻辑上的业务,而不去考虑具体的实现,这样controller层就不会直接去调用mapper层,可以将代码解耦,便于扩展

1.UserService类

@Service
public class UserService {
    @Autowired
    // 将UserMapper对象注入进来
    private UserMapper userMapper;

    /**
     * 根据用户id查询用户信息
     * @param id
     * @return
     */
    public User selectById(Integer id) {
        return userMapper.selectById(id);
    }

    /**
     * 根据用户名称查询用户
     * @param userName
     * @return
     */
    public User selectByName(String userName) {
        return userMapper.selectByName(userName);
    }

}

2.BlogService类

@Service
public class BlogService {

    @Autowired
    private BlogMapper blogMapper;
    /**
     * 查询所有未删除的博客.按照时间降序排列
     * @return
     */
    public List<Blog> selectAllBlog() {
        return blogMapper.selectAllBlog();
    }

    /**
     * 根据博客id查询博客详情
     * @param blogId
     * @return
     */
    public Blog selectByBlogId(Integer blogId) {
        return blogMapper.selectByBlogId(blogId);
    }

    /**
     * 插入一条博客
     * @param blog
     * @return
     */
    public Integer insertBlog(Blog blog) {
        return blogMapper.insertBlog(blog);
    }

    /**
     * 根据博客id更新博客
     * 删除博客就是把delete_id改为1
     * @return
     */
    public Integer updateBlog(Blog blog) {
        return blogMapper.updateBlog(blog);
    }

    /**
     * 根据用户id查询博客数量
     * @param userId
     * @return
     */
    public Integer selectBlogCount(Integer userId) {
        return blogMapper.selectBlogCount(userId);
    }
}


4.测试

使用BlogMapper做演示,UserMapper同理

在mapper接口点击Fn+Alt+Insert(按钮因电脑而异,不行可以试下Alt+Insert)
然后在弹出框中点击Test

在这里插入图片描述
然后勾选需要测试的方法
在这里插入图片描述
此时就可以看到test包下出现了对应的类
在这里插入图片描述
然后我们就可以在这里写测试方法

1.BlogMapperTest测试类

@SpringBootTest
class BlogMapperTest {

    @Autowired
    private BlogService blogService;

    @Test
    void selectAllBlog() {
        List<Blog> blogs = blogService.selectAllBlog();
        System.out.println(blogs.toString());
    }

    @Test
    void selectByBlogId() {
        System.out.println(blogService.selectByBlogId(2).toString());
    }

    @Test
    void insertBlog() {
        Blog blog = new Blog();
        blog.setTitle("测试");
        blog.setContent("测试正文");
        blog.setUserId(1);
        System.out.println(blogService.insertBlog(blog));
    }

    @Test
    void updateBlog() {
        Blog blog = new Blog();
        blog.setTitle("测试更新");
        blog.setId(1);
        System.out.println(blogService.updateBlog(blog));
    }

    @Test
    void deleteBlog() {
        Blog blog = new Blog();
        blog.setDeleteFlag(1);
        blog.setId(1);
        System.out.println(blogService.updateBlog(blog));
    }

    @Test
    void selectBlogCount() {
        System.out.println(blogService.selectBlogCount(2));
    }
}

2.UserMapperTest测试类

@SpringBootTest
class UserMapperTest {

    @Autowired
    private UserService userService;

    @Test
    void selectById() {
        System.out.println(userService.selectById(1).toString());
    }

    @Test
    void selectByName() {
        System.out.println(userService.selectByName("zhangsan").toString());
    }
}

3.测试结果

在这里插入图片描述

在这里插入图片描述

5.添加前端界面

把之前写好的博客系统静态页面拷贝到static⽬录下
在这里插入图片描述

6.添加公共模块

⼯具层(common) => 统⼀返回类, 统⼀异常处理类

1.添加统一返回类Result

@Data
public class Result {

    private Integer code;
    private String msg;
    private Object data;


    /**
     * 业务执行成功返回的数据
     * @return
     */
    public static Result success(String msg, Object data) {
        Result result = new Result();
        result.setCode(200);
        result.setMsg(msg);
        result.setData(data);
        return result;
    }

    /**
     * 业务执行成功返回的数据
     * @return
     */
    public static Result success(Object data) {
        Result result = new Result();
        result.setCode(200);
        result.setMsg("执行成功");
        result.setData(data);
        return result;
    }

    /**
     * 业务执行失败返回的数据
     * @return
     */
    public static Result fail(Integer code, String msg, Object data) {
        Result result = new Result();
        result.setCode(code);
        result.setMsg(msg);
        result.setData(data);
        return result;
    }

    /**
     * 业务执行失败返回的数据
     * @return
     */
    public static Result fail(Integer code, String msg) {
        Result result = new Result();
        result.setCode(code);
        result.setMsg(msg);
        return result;
    }
}


2.添加统一异常处理类

使用code = -1表示出现异常

@ControllerAdvice
@ResponseBody
public class ErrorAdvice {

    @ExceptionHandler
    public Result error (Exception e) {
        return Result.fail(-1, e.getMessage());
    }

}

3.添加统一返回格式

在数据返回之前调用此方法,将返回数据格式统一
如果是String类型会报错,所以我们要处理一下,异常使用@SneakyThrows注解
如果返回的数据格式,已经是Result类型,就不需要处理,直接返回即可

@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {

    /**
     * 内容是否需要重写
     * 返回true表示需要重写
     * @param returnType
     * @param converterType
     * @return
     */
    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return true;
    }

    /**
     * 方法返回之前调用此方法
     */
    //
    @SneakyThrows
    @Override
    public Object beforeBodyWrite(Object body, // 相应的正文内容
                                  MethodParameter returnType,
                                  MediaType selectedContentType,
                                  Class selectedConverterType,
                                  ServerHttpRequest request,
                                  ServerHttpResponse response) {
        //如果返回的数据格式,已经是Result类型,就不需要处理,直接返回即可
        if (body instanceof Result) {
            return body;
        }
        // 如果是String类型会报错,所以我们要处理一下
        if (body instanceof String) {
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.writeValueAsString(body);
        }
        return Result.success(body);
    }
}

7.实现博客列表显示

1.约定前后端交互的接口

【请求】

  • blog/getList

【响应】

  1. [200]
  • [200]返回数据成功,显示博客列表
  • [-1]目前没有博客
  1. [401]没有权限访问
  2. [error]访问出现错误,打印异常信息

浏览器给服务器发送一个blog/getList这样的Http请求,服务器返回给浏览器一个json格式的数据

2.实现服务器代码

@RestController
@RequestMapping("/blog")
public class BlogController {

    @Autowired
    private BlogService blogService;

    @RequestMapping("/getList")
    public List<Blog> getList() {
        // 获取博客列表
        List<Blog> blogs = blogService.selectAllBlog();
        if (blogs == null) {
            return null;
        }
        return blogs;
    }
}

使用postman测试成功,服务器正确返回数据
在这里插入图片描述

3.实现客户端代码

修改 blog_list.html, 删除之前写死的博客内容(即 <div class=“blog”> ), 并新增js 代码处理 ajax 请求.

  1. 使用ajax给服务器发送数据
  2. 服务器返回一个json数据格式的响应
  3. 前端根据这个响应使用DOM API构造页面内容
  4. 响应中的时间为时间戳,需要修改
  5. 列表中拿到的content应该是已经裁剪过的摘要
  6. 跳转到博客详情页的url应该在后面加上参数blogId=1,这样可以让博客详情页知道当前访问的是哪篇博客
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
    <script>
        $.ajax({
            type: "get",
            url: "/blog/getList",
            success: function (result) {
                if (result.code == 200 && result.data != null && result.data.length > 0) {
                    //循环拼接数据到document
                    var finalHtml = "";
                    for (var blog of result.data) {
                        finalHtml += '<div class="blog">';
                        finalHtml += '<div class="title">' + blog.title + '</div>';
                        finalHtml += '<div class="date">' + blog.createTime + '</div>';
                        finalHtml += '<div class="desc">' + blog.content + '</div>'
                        finalHtml += '<a class="detail" href="blog_detail.html?blogId = '+blog.id+'">查看全⽂&gt;&gt;</a>'
                        finalHtml += '</div>';
                    }
                    $(".right").html(finalHtml);
                } else if (result.code == -1) {
                    alert(result.mag);
                }
            },
            error: function () {
                console.log("后端返回失败");
            }
        });
    </script>

4.处理日期显示问题

SimpleDateFormat 格式化
创建一个DateUtil工具类

public class DateUtil {
    public static String format(Date date) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yy-MM-dd HH:mm:ss");
        return simpleDateFormat.format(date);
    }
}

重新获取博客创建时间

@Data
public class Blog {
    private Integer id;
    private String title;
    private String content;
    private Integer userId;
    private Integer deleteFlag;
    private Date createTime;

    public String getCreateTime() {
        return DateUtil.format(createTime);
    }
}

5.处理裁剪摘要问题

博客列表页面应该显示的是正文的摘要,并非全部显示出来,在博客的详情页面才需要全部显示出来
修改Blog Service中的方法

    /**
     * 查询所有未删除的博客.按照时间降序排列
     * @return
     */
    public List<Blog> selectAllBlog() {
        List<Blog> blogs = blogMapper.selectAllBlog();
        // 遍历如果博客的正文长度超过100,就裁剪
        for (Blog blog : blogs) {
            if (blog.getContent().length() > 100) {
                blog.setContent(blog.getContent().substring(0,100)+"...");
            }
        }
        return blogs;
    }

4.博客列表界面显示成功

在这里插入图片描述

8.实现博客详情

点击查看全文能进入当前博客详情页面,根据博客id动态的获取博客详情

1.约定前后端交互接口

【请求】

  • blog/getBlogDetails

【响应】

  1. [200]
  • [200]返回数据成功,显示博客详情
  • [-1]该博客不存在
  1. [401]没有权限访问
  2. [error]访问出现错误,打印异常信息

浏览器给服务器发送一个blog.getDetails的Http请求,服务器返回给浏览器一个json格式的数据

2.实现服务器代码

    @RequestMapping("/blog/getBlogDetails")
    public Result getDetails(Integer blogId) {
        // 判合法
        if (blogId == null || blogId <= 0) {
            return Result.fail(-1,"博客不存在");
        }
        Blog blog = blogService.selectByBlogId(blogId);
        if (blog == null) {
            return Result.fail(-1,"博客不存在");
        }
        return Result.success(blog);
    }

使用postman测试成功,服务器正确返回数据
在这里插入图片描述

3.实现客户端代码

  1. 使用ajax,根据当前页面的URL中的blogId参数(使⽤ location.search 即可得到形如 ?blogId=1 的数据),给服务器发送请求
  2. 服务器返回一个json数据格式的响应
  3. 前端根据这个响应使用通过 editor.md 转换成 html, 并显示

1. 引⼊ editor.md

    <!-- 引⼊ editor.md 的依赖 -->
    <link rel="stylesheet" href="blog-editormd/css/editormd.css" />
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js">
    </script>
    <script src="blog-editormd/lib/marked.min.js"></script>
    <script src="blog-editormd/lib/prettify.min.js"></script>
    <script src="blog-editormd/editormd.js"></script>

2.新增 js 代码, 从服务器获取博客详情数据

    <script>
        $.ajax({
            type: "get",
            url: "/blog/getBlogDetails" + location.search,
            success: function (result) {
                console.log(result);
                if (result.code == 200 && result.data != null) {
                    $(".title").text(result.data.title);
                    $(".date").text(result.data.createTime);
                    editormd.markdownToHTML("content", {
                        markdown: result.data.content,
                    });
                } else {
                    alert(result.msg);
                }
            },
            error: function () {
                console.log('访问出错');
            }
        });

    </script>

4.博客列表界面显示成功

9.实现登陆

  • 登录页面提供一个form表单,通过form的方式把用户名密码提交给服务器
  • 服务器端验证⽤户名密码是否正确
  • 如果密码正确, 则在服务器端创建 Session , 并把 sessionId 通过 Cookie 返回给浏览器
  • 前后端分离的项⽬中, 虽然主要使⽤ ajax 进⾏前后端交互, 但是也不是完全不能⽤ form
    

1.约定前后端交互接口

【请求】

  • user/login

【响应】

  1. [200]
  • [200] 登陆成功
  • [-1] 用户名或密码不能为空
  • [-2] 用户名或密码错误
  1. [error]访问出现错误,打印异常信息

2.实现服务器代码

创建 UserController

@RequestMapping("/user")
@RestController
public class UserController {
    
    @Autowired
    private UserService userService;

	@RequestMapping("/login")
    public Result login(String username, String password) {
        // 判空
        if (!StringUtils.hasLength(username) || !StringUtils.hasLength(password)) {
            return Result.fail(-1,"用户名或密码不能为空");
        }
        // 判断用户名密码是否匹配
        User user = userService.selectByName(username);
        if (user == null || !user.getPassWord().equals(password)) {
            return Result.fail(-2,"用户名或密码错误");
        }
        return Result.success("登陆成功");
    }
}

使用postman测试登录成功

在这里插入图片描述

3.实现客户端代码

    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
    <script>
        function login() {
            $.ajax({
                type: "post",
                url: "/user/login",
                data: {
                    "username": $("#username").val(),
                    "password": $("#password").val()
                },
                success: function (result) {
                    if (result.code == 200 && result.data == 1) {
                        location.assign("blog_list.html");
                    } else if(result.code == -1){
                        alert("⽤户名或密码不能为空");
                        return;
                    } else if(result.code == -2){
                        alert("⽤户名或密码错误");
                        return;
                    }
                },
                error : function (error) {
                    console.log(error.msg);
                }
            })
        }
    </script>

3.实现客户端代码

    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
    <script>
        function login() {
            $.ajax({
                type: "post",
                url: "/user/login",
                data: {
                    "username": $("#username").val(),
                    "password": $("#password").val()
                },
                success: function (result) {
                    if(result.code == -1){
                        alert(result.msg);
                    } else if(result.code == -2){
                        alert(result.msg);
                    }
                    else if (result.code == 200 && result.data != null) {
                        location.assign("blog_list.html");
                    }
                },
                error : function (error) {
                    console.log(error.msg);
                }
            })
        }
    </script>

4.登陆功能实现成功

在这里插入图片描述
剩下的功能在下篇博客实现~

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

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

相关文章

什么是 MySQL 的“回表”?怎么减少回表的次数?

什么是 MySQL 的“回表”&#xff1f;怎么减少回表的次数&#xff1f; 索引结构 要搞明白这个问题&#xff0c;需要大家首先明白 MySQL 中索引存储的数据结构。这个其实很多小伙伴可能也都听说过&#xff0c;BTree 嘛&#xff01; BTree 是什么&#xff1f;那你得先明白什么…

使用Python将图像转换为PDF:一次性解决您的批量转换需求

导语&#xff1a; 在数字化时代&#xff0c;我们经常需要处理大量的图像文件。将这些图像转换为PDF格式可以方便地存档、分享和打印。本文将介绍如何使用Python编程语言将图像批量转换为PDF&#xff0c;并提供了一个简单易用的图形界面来跟踪转换进度。 准备工作 在开始之前…

AI编程工具Copilot与Codeium的实测对比

csdn原创谢绝转载 简介 现在没有AI编程工具&#xff0c;效率会打一个折扣&#xff0c;如果还没有&#xff0c;赶紧装起来&#xff0e; GitHub Copilot是OpenAi与github等共同开发的的AI辅助编程工具&#xff0c;基于ChatGPT驱动&#xff0c;功能强大&#xff0c;这个没人怀疑…

Linux进程(二)

文章目录 进程&#xff08;二&#xff09;Linux的进程状态R &#xff08;running&#xff09;运行态S &#xff08;sleeping&#xff09;阻塞状态D &#xff08;disk sleep&#xff09;深度睡眠T&#xff08;stopped&#xff09;状态X&#xff08;dead&#xff09;状态Z&#x…

2024年浙师大MBA项目招生信息全面了解

2024年全国管理类硕士联考备考已经到了最火热的阶段&#xff0c;不少考生开始持续将注意力集中在备考的规划中&#xff01;杭州达立易考教育整合浙江省内的MBA项目信息&#xff0c;为大家详细梳理了相关报考参考内容&#xff0c;方便大家更好完成择校以及针对性的备考工作。本期…

C语言基础知识点一

C语言基础知识点一&#xff1a; 1.数据类型 2.bool类型&#xff1a; 使用bool时时&#xff0c;需要增加<stdbool.h>头文件。 说明&#xff1a;bool 类型只有非零&#xff08;true&#xff09;和零&#xff08;false&#xff09;两种值。 如: if&#xff08;-1&#xf…

Qt下开发基于QGIS的应用程序

Qt下开发基于QGIS的应用程序 目的版本说明1、Qt的安装2、MSVC套件与Windows 10 SDK的下载3、QGIS开发有关的库文件下载4、环境搭建5、QGIS开发环境搭建6、展示网页地图 目的 由于有在背景地图上进行动态轨迹&#xff08;曲线&#xff09;显示的需要&#xff0c;故采用QtQGIS的…

CVS,SVN,Git,Mercurial 代码管理工具

现代软件开发过程中要实现高效的团队协作&#xff0c;需要使用代码分支管理工具实现代码的共享、追溯、回滚及维护等功能。目前流行的代码管理工具&#xff0c;包括 CVS&#xff0c;SVN&#xff0c;Git&#xff0c;Mercurial 等 CVS 和 SVN 是集中管理&#xff0c;Git 具有非常…

Docker 容器化学习

文章目录 前言Docker架构 1、 docker安装2、启动docker服务3、设置docker随机器一起启动4、docker体验5、docker常规命令5.1、容器操作docker [run|start|stop|restart|kill|rm|pause|unpause]docker [ps|inspect|exec|logs|export|import] 5.2、镜像操作docker images|rmi|tag…

AOF日志:宕机了,Redis如何避免数据丢失

当服务器宕机后&#xff0c;数据全部丢失&#xff1a;我们很容易想到的一个解决方案是从后端数据库恢复这些数据&#xff0c;但这种方式存在两个问题&#xff1a;一是&#xff0c;需要频繁访问数据库&#xff0c;会给数据库带来巨大的压力&#xff1b;二是&#xff0c;这些数据…

整数规划——第三章 全单模矩阵

整数规划——第三章 全单模矩阵 若线性规划问题的约束矩阵为全单模矩阵&#xff0c;则该问题可行域的顶点都是整数点&#xff0c;从而线性规划与整数规划的最优解相同。 3.1 全单模性与最优性 考虑线性整数规划问题&#xff1a; (IP) min ⁡ c T x , s . t . A x ≤ b , x …

19、springboot引用配置属性或引用生成文件的属性或引用随机值

引用配置属性或引用生成文件的属性或引用随机值 ★ 使用占位符引用其他配置属性&#xff1a; 配置文件中可用${}占位符引用已有的属性&#xff0c;被引用的属性可以是&#xff1a; - 已定义的属性。 - 来自其他配置源&#xff08;比如命令行的选项参数、环境变量、系统属性等…

JGJ79-2012建筑地基处理技术规范

为了在地基处理的设计和施工中贯执行国家的技术经济政策&#xff0c;做到安全适用、技术先进、经济合理、确保质量、保护环境&#xff0c;制定本规范。 本规范适用于建筑工程地基处理的设计、施工和质量检验。 地基处理除应满足工程设计要求外&#xff0c;尚应做到因地制宜就…

【数模】奇异值分解SVD和图形处理

介绍奇异值分解在图形压缩中的运用&#xff0c;并将简单介绍下Matlab对于图形和视频的处理 一、奇异值分解介绍 1.1 基本概念 奇异值分解(Singular Value Decomposition&#xff0c;以下简称SVD)是线性代数中一种重要的矩阵分解&#xff1a; U和V都是正交矩阵∑是奇异值矩阵&…

操作系统_内存管理

这里写目录标题 虚拟内存是什么为什么要有虚拟内存虚拟内存的实现方式1.分页查找过程页表的底层实现 2.分段段表的底层实现 3.段页式 分段和分页有什么区别什么是交换空间物理地址、逻辑地址、有效地址、线性地址、虚拟地址页面替换算法什么是缓冲区溢出 有什么危害malloc 是如…

Arthas协助MQ消费性能优化

背景 项目中使用AWS的SQS消息队列进行异步处理&#xff0c;QA通过压测发现单机TPS在23左右&#xff0c;目标性能在500TPS&#xff0c;所以需要对消费逻辑进行优化&#xff0c;提升消费速度。 目标 消费TPS从23提升到500 优化流程 优化的思路是先分析定位性能瓶颈&#xff…

如何加载模型YOLOv8 ONNXRuntime

YOLOv8 是 YOLO(You Only Look Once)目标检测系统的最新版本(v8)。YOLO 是一种实时、一次性目标检测系统,旨在在网络的单次前向传递中执行目标检测,使其快速高效。YOLOv8是之前YOLO模型的改进版本,具有更高的精度和更快的推理速度。 ONNX(开放神经网络交换)是一种表示…

算法练习--leetcode 数组

文章目录 爬楼梯问题裴波那契数列两数之和 [数组]合并两个有序数组移动零找到所有数组中消失的数字三数之和 爬楼梯问题 输入n阶楼梯&#xff0c;每次爬1或者2个台阶&#xff0c;有多少种方法可以爬到楼顶&#xff1f; 示例1&#xff1a;输入2&#xff0c; 输出2 一次爬2阶&a…

正点原子HAL库入门1~GPIO

探索者F407ZGT6(V3) 理论基础 IO端口基本结构 F4/F7/H7系列的IO端口 F1在输出模式&#xff0c;禁止使用内部上下拉 F4/F7/H7在输出模式&#xff0c;可以使用内部上下拉不同系列IO翻转速度不同 F1系列的IO端口 施密特触发器&#xff1a;将非标准方波&#xff0c;整形为方波 当…

WebRTC 之音视频同步

在网络视频会议中&#xff0c; 我们常会遇到音视频不同步的问题&#xff0c; 我们有一个专有名词 lip-sync 唇同步来描述这类问题&#xff0c;当我们看到人的嘴唇动作与听到的声音对不上的时候&#xff0c;不同步的问题就出现了 而在线会议中&#xff0c; 听见清晰的声音是优先…