前后端分离实现博客系统

文章目录

  • 博客系统
    • 前言
    • 1. 前端
      • 1.1 登陆页面
      • 1.2 博客列表页面
      • 1.3 博客详情页面
      • 1.4 博客编辑页面
    • 2. 后端
    • 2.1 项目部署
        • 2.1.1 创建maven项目
        • 2.1.2 引入依赖
        • 2.1.3 创建目录结构
        • 2.1.4 部署程序
    • 2.2 逻辑设计
      • 2.2.1 数据库设计
      • 2.2.2 实体类设计
      • 2.2.3 Dao层设计
        • 2.2.3.1 BlogDao
      • 2.2.4 Dao层设计
      • 2.2.3 接口设计
        • 2.2.3.1 登录接口
        • 2.2.3.2 注销接口
        • 2.2.3.3 作者查询接口
        • 2.2.3.4 博客接口
        • 2.2.3.4 删除博客接口
    • 3. 小结

博客系统

前言

基于servlet+jdbc进行后端开发,设计了一个可以发布博客,查看博客详情,删除博客,登录注销功能的简易博客系统。

1. 前端

1.1 登陆页面

在这里插入图片描述

1.2 博客列表页面

在这里插入图片描述

1.3 博客详情页面

在这里插入图片描述

1.4 博客编辑页面

在这里插入图片描述

2. 后端

2.1 项目部署

2.1.1 创建maven项目

我们在idea里面点击new project创建一个maven项目,然后一路next选择好项目位置以及命名即可。
在这里插入图片描述
在这里插入图片描述

2.1.2 引入依赖

在创建完maven项目之后我们需要加载依赖,部分同学可能由于网络问题难以加载,可以多试几遍,实在不行可以更换国内的镜像下载此处不作多介绍。以下需要引入的依赖主要有:java.servlet-api、mysql-connector-java,以及后续发送json格式的数据需要的jackson依赖(jackson-databind)

我们通过maven仓库官网https://mvnrepository.com/ 即可获取。

如图:复制链接黏贴到我们项目的pom.xml文件
在这里插入图片描述

代码 : 以下是我部署的依赖可以直接复制黏贴

 <dependencies>
<!--        servlet依赖--><!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency>
<!--        jackson依赖--><!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.14.2</version></dependency>
<!--        数据库依赖--><!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency></dependencies>

2.1.3 创建目录结构

在我们的webapp目录下面创建一个WEB-INF包并创建一个web.xml,此处结构以及名字不能改动。
在这里插入图片描述
web.xml内容:

<!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app><display-name>Archetype Created Web Application</display-name>
</web-app>

2.1.4 部署程序

我们在插件市场搜索 Smart Tomcat 插件,将Tomcat集成到idea就不用我们手动打包,之后点击即可运行。
在这里插入图片描述
然后点击新增运行配置,将Smart Tomcat加入,此处选择Tomcat路径,如果还没有下载Tomcat,可以通过官网下载。博主使用的是 3.1版本的servlet+tomcat 8

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

然后就可以点击运行:出现以下结果就是部署成功了。之后我们就可以通过127.0.0.1:8080/MessageWall/xx.html(html页面)访问,其中MessageWall是Context path,一般默认是项目名。

在这里插入图片描述

2.2 逻辑设计

2.2.1 数据库设计

我们博客系统主要有用户登录以及编写博客的功能,基于此需求在当前博客系统中主要涉及两个实体,博客和用户,所以我们需要创建两张表用于存储博客和用户信息

注意:用户与博客之间是一对多的关系;以下设计blog表和user表

  1. blog表包含blogId,title,content,postTime,userId属性;
  2. user表包含userId,userName,password;
  3. 通过userId建立关系,描述用户有哪些博客。

sql代码写到文本文件中用于记录,以便后续在别的机器上部署;
编写封装数据库的连接操作,代码如下:

import com.mysql.jdbc.Connection;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;import javax.sql.DataSource;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;/*** @author zq*/
public class DBUtil {private static DataSource dataSource = new MysqlDataSource();static {((MysqlDataSource) dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/blog_system?characterEncoding=utf8&useSSL=false");((MysqlDataSource) dataSource).setUser("root");((MysqlDataSource) dataSource).setPassword("123456");}public static Connection getConnection() throws SQLException {return (Connection) dataSource.getConnection();}public static void close(Connection connection, PreparedStatement preparedStatement, ResultSet resultSet){if (resultSet!=null){try {resultSet.close();} catch (SQLException e) {e.printStackTrace();}}if (preparedStatement!=null){try {preparedStatement.close();} catch (SQLException e) {e.printStackTrace();}}if (connection!=null){try {connection.close();} catch (SQLException e) {e.printStackTrace();}}}
}

2.2.2 实体类设计

根据我们用户表和博客表设计两个对应的实体类如下:

user类:

package model;/*** @author zq*/
public class User {private String username;private String password;private int userId;public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public int getUserId() {return userId;}public void setUserId(int userId) {this.userId = userId;}
}

blog类:

package model;import java.sql.Timestamp;
import java.text.SimpleDateFormat;/*** @author zq*/
public class Blog {private int blogId;private String title;private String content;private Timestamp postTime;private int userId;public int getBlogId() {return blogId;}public void setBlogId(int blogId) {this.blogId = blogId;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}public String getPostTime() {SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");return simpleDateFormat.format(postTime);}public Timestamp getPostTimestamp(){return postTime;}public void setPostTime(Timestamp postTime) {this.postTime = postTime;}public int getUserId() {return userId;}public void setUserId(int userId) {this.userId = userId;}
}

2.2.3 Dao层设计

封装数据库的增删改查,针对博客表创建BlogDao,针对用户表创建UserDao并且提供对应的增删改查方法。

2.2.3.1 BlogDao

针对本项目我们需要的功能有发布博客,也就是在博客表新增一条数据;显示博客详情即根据博客id查询博客内容;删除博客即根据博客id删除博客;博客列表页即查询该用户发布的所有博客;
具体实现如下:

package model;import com.mysql.jdbc.Connection;
import model.Blog;
import model.DBUtil;import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;/*** @author zq*/
//针对博客表提供的基本操作,此处暂时不考虑修改
public class BlogDao {//1。新增一个博客public void add(Blog blog)  {//1.先于数据库建立连接、Connection connection = null;PreparedStatement preparedStatement = null;try {connection = DBUtil.getConnection();//2.构造sql1语句String sql = "insert into blog values(null,?,?,now(),?)";preparedStatement = connection.prepareStatement(sql);preparedStatement.setString(1, blog.getTitle());preparedStatement.setString(2, blog.getContent());// preparedStatement.setTimestamp(3,blog.getPostTimestamp());preparedStatement.setInt(3,blog.getUserId());//3.执行sqlpreparedStatement.executeUpdate();} catch (SQLException e) {e.printStackTrace();}finally {DBUtil.close(connection,preparedStatement,null);}}//2.根据博客id查询指定博客,也就是页面的显示全文public Blog selectById(int blogId){Connection connection =null;PreparedStatement statement = null;ResultSet resultSet = null;try {//1.建立连接connection = DBUtil.getConnection();//2.构造sql语句String sql = "select * from blog where blogId = ?";statement = connection.prepareStatement(sql);statement.setInt(1,blogId);//3.执行sql语句resultSet = statement.executeQuery();//由于主键具有唯一性所以如果查到数据那么就只有一条//所以不需要用while遍历所有结果,判断是否有一条就行if (resultSet.next()){Blog blog = new Blog();blog.setBlogId(resultSet.getInt("blogId"));blog.setContent(resultSet.getString("content"));blog.setTitle(resultSet.getString("title"));blog.setUserId(resultSet.getInt("userId"));blog.setPostTime(resultSet.getTimestamp("postTime"));return blog;}}catch (SQLException throwables){throwables.printStackTrace();}finally {DBUtil.close(connection,statement,resultSet);}return null;}//3.直接查询数据库所有的博客列表(博客列表页)public List<Blog> selectAll(){Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;List<Blog> blogs = new ArrayList<>();try{//建立链接connection = DBUtil.getConnection();//构造sql语句String sql = "select * from blog order by postTime desc";statement = connection.prepareStatement(sql);//执行sqlresultSet = statement.executeQuery();while (resultSet.next()){Blog blog = new Blog();blog.setBlogId(resultSet.getInt("blogId"));//注意这里的正文内容在博客列表页,不需要全部显示出来String content = resultSet.getString("content");if (content.length()>=100){content = content.substring(0,100)+"....";}blog.setContent(content);blog.setTitle(resultSet.getString("title"));blog.setUserId(resultSet.getInt("userId"));blog.setPostTime(resultSet.getTimestamp("postTime"));blogs.add(blog);}}catch (SQLException throwables){throwables.printStackTrace();}finally {DBUtil.close(connection,statement,resultSet);}return blogs;}//4.实现删除指定博客public void delete(int blogId){Connection connection = null;PreparedStatement statement = null;try{//建立链接connection = DBUtil.getConnection();//构造sql语句String sql = "delete from blog where blogId =?";statement = connection.prepareStatement(sql);statement.setInt(1,blogId);//执行sqlstatement.executeUpdate();}catch (SQLException throwables){throwables.printStackTrace();}finally {DBUtil.close(connection,statement,null);}}
}

2.2.4 Dao层设计

本项目在设计用户表的主要功能,登录需要验证用户名与密码即根据用户名查询用户信息;主页右侧显示的用户信息即根据用户id查询用户信息;

具体实现:

package model;import com.mysql.jdbc.Connection;
import model.DBUtil;import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;/*** @author zq*/
//针对用户表提供的基本操作,由于没有写注册功能所以就不写add,
// 也没有注销功能,所以也不写delete
public class UserDao {//1.根据userID查询用户信息public User selecetById(int userId){Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;try{connection = DBUtil.getConnection();String sql = "select * from user where userId = ?";statement = connection.prepareStatement(sql);statement.setInt(1,userId);resultSet = statement.executeQuery();if (resultSet.next()){User user = new User();user.setUserId(resultSet.getInt("userId"));user.setUsername(resultSet.getString("username"));user.setPassword(resultSet.getString("password"));return user;}}catch (SQLException throwables){throwables.printStackTrace();}finally {DBUtil.close(connection,statement,resultSet);}return null;}//2.根据用户名查询用户信息public User selectByUsername(String username){Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;try{connection = DBUtil.getConnection();String sql = "select * from user where username = ?";statement = connection.prepareStatement(sql);statement.setString(1,username);resultSet = statement.executeQuery();if (resultSet.next()){User user = new User();user.setUserId(resultSet.getInt("userId"));user.setUsername(resultSet.getString("username"));user.setPassword(resultSet.getString("password"));return user;}}catch (SQLException throwables){throwables.printStackTrace();}finally {DBUtil.close(connection,statement,resultSet);}return null;}}

2.2.3 接口设计

在前后端进行数据交互时我们约定以json格式进行数据传输,前端通过ajax向后端发送请求。

2.2.3.1 登录接口

创建一个LoginServlet类继承HttpServlet类,重写doPost()方法实现对用户密码的校验,重写doGet()方法进行用户是否登录校验,只有登录了的用户才能进行博客编辑。
具体实现如下:

package api;import com.fasterxml.jackson.databind.ObjectMapper;
import model.User;
import model.UserDao;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;/*** @author zq*/@WebServlet("/login")
public class LoginServlet extends HttpServlet {private ObjectMapper objectMapper = new ObjectMapper();@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1.读取用户名和密码,由于是form表单格式所以不用jackson的类进行读取//注意如果此处的用户名密码如果包含中文会乱码,所以要设置字符集req.setCharacterEncoding("utf8");resp.setContentType("text/html; charset=utf8");String username = req.getParameter("username");String password = req.getParameter("password");if (username==null||"".equals(username)||password==null||"".equals(password)){//登录失败String html = "<h3> 登陆失败username或者password错误 </h3>" ;resp.getWriter().write(html);return;}//2.读取数据库看用户名是否存在,密码是否匹配UserDao userDao = new UserDao();User user = userDao.selectByUsername(username);if (user==null){//用户不存在String html = "<h3> 用户名或密码错误 </h3>" ;resp.getWriter().write(html);return;}if (!password.equals(user.getPassword())){String html = "<h3> 用户名或密码错误 </h3>" ;resp.getWriter().write(html);return;}//3.验证通过,接下来创建会话,使用会话保存用户信息HttpSession session = req.getSession(true);session.setAttribute("user",user);//4.进行重定向到博客列表页resp.sendRedirect("blog_list.html");}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("application/json;charset=utf8");//获取用户的登录状态,如果用户未登录当前会话就拿不到HttpSession session = req.getSession(false);if (session==null){//未登录,返回一个user对象User user = new User();String respJson = objectMapper.writeValueAsString(user);resp.getWriter().write(respJson);return;}//登录了取出user对象User user = (User) session.getAttribute("user");if (user==null){//一般不会为空user = new User();String respJson = objectMapper.writeValueAsString(user);resp.getWriter().write(respJson);return;}//成功取出user对象,直接返回String respjson = objectMapper.writeValueAsString(user);resp.getWriter().write(respjson);}
}

2.2.3.2 注销接口

创建一个LogoutServlet类继承HttpServlet类,重写doGet()方法直接将session中的该用户移除,去除该用户缓存如何自动跳转到登录页面。
具体实现如下:

package api;import model.User;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;/*** @author zq*/
@WebServlet("/logout")
public class LogoutServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {HttpSession httpSession = req.getSession(false);if (httpSession==null){//未登录状态,直接提示出错resp.setContentType("text/html;charset=utf8");resp.getWriter().write("当前未登录");}//然后直接romovehttpSession.removeAttribute("user");//然后跳转到登录页面resp.sendRedirect("blog_login.html");}
}

2.2.3.3 作者查询接口

创建一个AuthorServlet类继承HttpServlet类,重写doGet()方法实现通过前端传输的用户id获取用户信息。
具体实现如下:

package api;import com.fasterxml.jackson.databind.ObjectMapper;
import model.Blog;
import model.BlogDao;
import model.User;
import model.UserDao;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** @author zq*/
@WebServlet("/author")
public class AuthorServlet extends HttpServlet {private ObjectMapper objectMapper;@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//博客详情页根据博客id获取用户,由于是queryString所以getParameter就能拿到String blogId = req.getParameter("blogId");if (blogId==null){resp.setContentType("text/html;charset=utf8");resp.getWriter().write("参数非法缺少blogID");return;}//根据·blogId查询blog对象BlogDao blogDao = new BlogDao();Blog blog = blogDao.selectById(Integer.parseInt(blogId));if (blog==null){//说明没找到resp.setContentType("text/html;charset=utf8");resp.getWriter().write("没有找到指定博客;blogId=" + blogId);}UserDao userDao = new UserDao();User author = userDao.selecetById(blog.getUserId());String respJson = objectMapper.writeValueAsString(author);resp.setContentType("application/json;charset=utf8");resp.getWriter().write(respJson);}
}

2.2.3.4 博客接口

创建一个BlogServlet类继承HttpServlet类,重写doGet()方法实现通过判断博客id是否存在确定获取所有博客还是博客详情,重写Post()方法实现博客发布功能。
具体实现如下:

package api;import com.fasterxml.jackson.databind.ObjectMapper;
import model.Blog;
import model.BlogDao;
import model.User;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.List;/*** @author zq*/
//实现前后端交互的代码@WebServlet("/blog")
public class BlogServlet extends HttpServlet {private ObjectMapper objectMapper = new ObjectMapper();//加载页面时显示所有博客查询数据库@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {BlogDao blogDao = new BlogDao();//尝试获取一下queryString中的blogId字段String blogId = req.getParameter("blogId");if (blogId==null){//说明本次获取的是列表页List<Blog> blogs =  blogDao.selectAll();//将blogs转成符合要求的json格式字符串String respJson = objectMapper.writeValueAsString(blogs);resp.setContentType("application/json;charset=utf8");resp.getWriter().write(respJson);}else {//存在,说明此处获取的是博客内容页//根据id查询博客Blog blog = blogDao.selectById(Integer.parseInt(blogId));//可能存在博客Id不存在的情况if(blog==null){System.out.println("当前blogId=" +blogId+ "对应的博客不存在");}String respJson = objectMapper.writeValueAsString(blog);resp.setContentType("application/json;charset=utf8");resp.getWriter().write(respJson);}}@Override //实现发布博客protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//读取请求,构造blog对象,插入数据库1即可HttpSession httpSession = req.getSession(false);if (httpSession==null){resp.setContentType("text/html;charset=utf8");resp.getWriter().write("当前未登录,无法发布博客");return;}User user = (User) httpSession.getAttribute("user");if (user==null){resp.setContentType("text/html;charset=utf8");resp.getWriter().write("当前未登录,无法发布博客");return;}//在登录状态时,就拿到作者//获取博客正文和标题,此时需要指定字符集,然后通过指定的字符集插入数据库req.setCharacterEncoding("utf8");String title = req.getParameter("title");String content = req.getParameter("content");if (title==null||"".equals(title)||content==null||"".equals(content)){resp.setContentType("text/html;charset=utf8");resp.getWriter().write("当前数据为空,无法发布博客");return;}//不为空时构造blog对象然后插入到数据库Blog blog = new Blog();blog.setContent(content);blog.setTitle(title);blog.setUserId(user.getUserId());BlogDao blogDao = new BlogDao();blogDao.add(blog);//blog里面的新增博客方法//跳转到博客列表页resp.sendRedirect("blog_list.html");}
}

2.2.3.4 删除博客接口

创建一个delBlogServlet类继承HttpServlet类,重写doGet()方法实现通过判断用户是否是登录并且用户是否是博客作者,确定是否能够删除博客。
具体实现如下:

package api;import com.fasterxml.jackson.databind.ObjectMapper;
import model.Blog;
import model.BlogDao;
import model.User;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.List;/*** @author zq*/
@WebServlet("/delBlog")
public class delBlogServlet extends HttpServlet {//private ObjectMapper objectMapper;@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1.首先判断是否登录HttpSession session = req.getSession(false);if (session==null){resp.setStatus(403);resp.setContentType("text/html;charset=utf-8");resp.getWriter().write("当前未登录请登录");return;}//获取到当前用户User user = (User) session.getAttribute("user");//2.判断用户是否为空if (user==null){resp.setStatus(403);resp.setContentType("text/html;charset=utf-8");resp.getWriter().write("当前未登录请登录");return;}BlogDao blogDao = new BlogDao();//3.尝试获取一下queryString中的blogId字段,判断博客是否存在String blogId = req.getParameter("blogId");//查询到博客对象Blog blog = blogDao.selectById(Integer.parseInt(blogId));if (blogId==null){resp.setStatus(404);resp.setContentType("text/html;charset=utf8");resp.getWriter().write("博客数据不存在");return;}//4.判断登录用户是否是作者if (blog.getUserId()!= user.getUserId()){resp.setStatus(403);resp.setContentType("text/html;charset=utf-8");resp.getWriter().write("当前不能删除别人的博客");return;}//根据博客Id删除博客blogDao.delete(Integer.parseInt(blogId));resp.sendRedirect("blog_list.html");}
}

3. 小结

本项目可以在我的gitee上查看源码,后续会通过SSM框架重新实现并完善博客系统功能。https://gitee.com/zxxqqa/blog_system

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

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

相关文章

qt添加图标

1.添加资源 选择QtWidgetsApp.qrc文件打开 添加图标文件路径 添加图标文件 2.按钮添加图标 图标路径为:/res/res/swicth.jpg &#xff08;1&#xff09;代码设置图标 ui.pushButton_OPen->setIcon(QIcon(":/res/res/swicth.jpg")); &#xff08;2&#xff09;属…

apple pencil到底值不值得买?好用的iPad电容笔

随着ipad平板型号版本的不断更新&#xff0c;其的功能越来越多&#xff0c;现在它的性能已经可以和笔记本电脑相媲美了。而现在&#xff0c;随着技术的进步&#xff0c;IPAD已经不再是单纯的娱乐&#xff0c;而是一种功能强大的学习、绘画、工作等等。要增加生产效率&#xff0…

【数据结构与算法】归并排序

归并排序 归并排序&#xff08;MERGE-SORT&#xff09;是利用归并的思想实现的排序方法&#xff0c;该算法采用经典的分治&#xff08;divide-and-conquer&#xff09;策略&#xff08;分治法将问题分&#xff08;divide&#xff09;成一些小的问题然后递归求解&#xff0c;而…

stm32内存杂记

从上图中可以看出SRAM空间用来存放&#xff1a;1.各个文件中声明和定义的全局变量、静态数据和常量&#xff1b;2.未初始化的全局变量&#xff1b;3.HEAP区&#xff1b;4.STACK区 这是在.map文件中&#xff0c;双击工程target打开 堆栈是处于以0x2000xx地址处的 EQU伪代码&…

学C的第三十一天【通讯录的实现】

相关代码gitee自取&#xff1a;C语言学习日记: 加油努力 (gitee.com) 接上期&#xff1a; 学C的第三十天【自定义类型&#xff1a;结构体、枚举、联合】_高高的胖子的博客-CSDN博客 通讯录需求&#xff1a; 实现一个通讯录&#xff0c; 通讯录中存放保存人的信息&#xff1…

华为鸿蒙4本周发布:官方海报大有玄机!告别“人工智障”!

一年一度的华为开发者大会2023(HDC.Together)将于8月4日至8月6日在东莞松山湖举办。相比去年&#xff0c;今年的华为开发者大会足足提前了三个月&#xff0c;而本次大会主角之一无疑是全新国产操作系统鸿蒙4&#xff08;HarmonyOS 4&#xff09;。 官方之前用了三个词来形容鸿蒙…

C#文件操作从入门到精通(1)——INI文件操作

点击这里:微软官方文档查看writePrivateProfileString函数定义 常见错误: 1、中文路径写入失败,为啥? 2、文件不是全路径,只有文件名也会写入失败: 3、GetLastError怎么使用? GetLastError错误代码含义: (0)-操作成功完成。 (1)-功能错误。 (2)- 系统找不到指定的文件…

3个命令定位CPU飙高

top 指令找出消耗CPU最厉害的那个进程的pid top -H -p 进程pid 找出耗用CPU资源最多的线程pid printf ‘0x%x\n’ 线程pid 将线程pid转换为16进制 结合jstack 找出哪个代码有问题 jstack 进程pid | grep 16进制的线程pid -A 多少行日志 jstack 进程pid | grep 16进制的线程…

C语言指针进阶-1

本篇文章带来 1. 字符指针 2. 数组指针 3. 指针数组的相关知识详细讲解&#xff01; 如果您觉得文章不错&#xff0c;期待你的一键三连哦&#xff0c;你的鼓励是我创作的动力之源&#xff0c;让我们一起加油&#xff0c;一起奔跑&#xff0c;让我们顶峰相见&#xff01;&#…

04 http连接处理(上)

基础知识&#xff1a;epoll、http报文格式、状态码和有限状态机 代码&#xff1a;对服务端处理http请求的全部流程进行简要介绍&#xff0c;然后结合代码对http类及请求接收进行详细分析。 epoll epoll_create函数 #include <sys/epoll.h> int epoll_create(int size)…

【业务功能篇55】Springboot+easyPOI 导入导出

Apache POI是Apache软件基金会的开源项目&#xff0c;POI提供API给Java程序对Microsoft Office格式档案读和写的功能。 Apache POI 代码实现复杂&#xff0c;学习成本较高。 Easypoi 功能如同名字easy,主打的功能就是容易,让一个没见接触过poi的人员 就可以方便的写出Excel导出…

【计算机网络】408统考2014年题36

题目描述 【2014年题36】主机甲与主机乙之间使用后退N帧(GBN)协议传输数据&#xff0c;甲的发送窗口尺寸为1000&#xff0c;数据帧长为1000字节&#xff0c;信道带宽为100Mbps&#xff0c;乙每收到一个数据帧就立即利用一个短帧&#xff08;忽略其传输延迟&#xff09;进行确认…

Banana Pi BPI-KVM – 基于 Rockchip RK3568 SoC 的 KVM over IP 解决方案

Banana Pi 已经开始开发基于 Rockchip RK3568 SoC 的 BPI-KVM 盒&#xff0c;但它不是迷你 PC&#xff0c;而是 KVM over IP 解决方案&#xff0c;旨在远程控制另一台计算机或设备&#xff0c;就像您在现场一样&#xff0c;例如能够打开和关闭连接的设备、访问 BIOS 等。 商业…

eda、gnm、anm究竟是个啥?

安装prody pip install prody -i https://pypi.tuna.tsinghua.edu.cn/simpleeda、anm、gnm eda(essential dynamics analysis) 另一个名字PCA(Principal Component Analysis) 或 NMA(Normal Mode Analysis)。 eda分析可以帮助人们理解生物大分子基本的运动模式和构象变化。…

面试典中典之线程池的七大参数

文章目录 一、七大元素解释1.corePoolSize&#xff08;核心线程数&#xff09;&#xff1a;2.maximumPoolSize&#xff08;最大线程数&#xff09;&#xff1a;3.keepAliveTime&#xff08;线程空闲时间&#xff09;&#xff1a;4.unit&#xff08;时间单位&#xff09;&#x…

Elasticsearch:使用 ELSER 释放语义搜索的力量:Elastic Learned Sparse EncoderR

问题陈述 在信息过载的时代&#xff0c;根据上下文含义和用户意图而不是精确的关键字匹配来查找相关搜索结果已成为一项重大挑战。 传统的搜索引擎通常无法理解用户查询的语义上下文&#xff0c;从而导致相关性较低的结果。 解决方案&#xff1a;ELSER Elastic 通过其检索模型…

Web3 叙述交易所授权置换概念 编写transferFrom与approve函数

前文 Web3带着大家根据ERC-20文档编写自己的第一个代币solidity智能合约 中 我们通过ERC-20一种开发者设计的不成文规定 也将我们的代币开发的很像个样子了 我们打开 ERC-20文档 我们transfer后面的函数就是transferFrom 这个也是 一个账号 from 发送给另一个账号 to 数量 val…

SpringBoot中MongoDB的使用

SpringBoot中MongoDB的使用 MongoDB 是最早热门非关系数据库的之一&#xff0c;使用也比较普遍&#xff0c;一般会用做离线数据分析来使用&#xff0c;放到内网的居 多。由于很多公司使用了云服务&#xff0c;服务器默认都开放了外网地址&#xff0c;导致前一阵子大批 MongoD…

数字工厂管理系统的实施步骤是什么

数字工厂管理系统是一种基于数字化技术和智能化设备的工厂管理系统&#xff0c;它可以实现工厂的全面、实时、动态管理&#xff0c;提高生产效率、降低成本、保证产品质量。实施数字工厂管理系统需要一系列的实施步骤&#xff0c;下面就数字工厂管理系统的实施步骤进行详细说明…

openssl 命令行国密sm2的签名验签操作

快速链接: . &#x1f449;&#x1f449;&#x1f449; 个人博客笔记导读目录(全部) &#x1f448;&#x1f448;&#x1f448; 付费专栏-付费课程 【购买须知】: 密码学实践强化训练–【目录】 &#x1f448;&#x1f448;&#x1f448; 生成EC私钥&#xff1a; openssl ecp…