【JavaWeb】日程管理系统 项目搭建 第二期

文章目录

  • 一、数据库准备
  • 二、导入依赖 与 JDBC工具类
  • 三、pojo包处理
  • 四、dao
    • dao包工具类
  • 五、service
  • 六、controller
    • servlet 基类 反射
  • 七、加密工具类 MD5
  • 八、页面文件
  • 九、业务代码
    • 9.1 注册业务处理
    • 9.2 登录业务处理
  • 总结


一、数据库准备

创建数据库:
1

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;


-- ----------------------------
-- 创建日程表
-- ----------------------------
DROP TABLE IF EXISTS `sys_schedule`;
CREATE TABLE `sys_schedule`  (
  `sid` int NOT NULL AUTO_INCREMENT,
  `uid` int NULL DEFAULT NULL,
  `title` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `completed` int(1) NULL DEFAULT NULL,
  PRIMARY KEY (`sid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- 插入日程数据
-- ----------------------------

-- ----------------------------
-- 创建用户表
-- ----------------------------
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user`  (
  `uid` int NOT NULL AUTO_INCREMENT,
  `username` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `user_pwd` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  PRIMARY KEY (`uid`) USING BTREE,
  UNIQUE INDEX `username`(`username`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- 插入用户数据
-- ----------------------------
INSERT INTO `sys_user` VALUES (1, 'zhangsan', 'e10adc3949ba59abbe56e057f20f883e');
INSERT INTO `sys_user` VALUES (2, 'lisi', 'e10adc3949ba59abbe56e057f20f883e');

SET FOREIGN_KEY_CHECKS = 1;

1

二、导入依赖 与 JDBC工具类

使用lombok处理 getter setter equals hashcode 构造器
1

导入JDBCUtil连接池工具类并准备jdbc.properties配置文件

package com.doug.wake.util;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

/**
 * @Description: JDBCUtil连接池工具类
 */
public class JDBCUtil {
    private static ThreadLocal<Connection> threadLocal =new ThreadLocal<>();

    private static DataSource dataSource;
    // 初始化连接池
    static{
        // 可以帮助我们读取.properties配置文件
        Properties properties =new Properties();
        InputStream resourceAsStream = JDBCUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
        try {
            properties.load(resourceAsStream);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        try {
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    /*1 向外提供连接池的方法*/
    public static DataSource getDataSource(){
        return dataSource;
    }

    /*2 向外提供连接的方法*/
    public static Connection getConnection(){
        Connection connection = threadLocal.get();
        if (null == connection) {
            try {
                connection = dataSource.getConnection();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
            threadLocal.set(connection);
        }

        return connection;
    }

    /*定义一个归还连接的方法 (解除和ThreadLocal之间的关联关系) */
    public static void releaseConnection(){
        Connection connection = threadLocal.get();
        if (null != connection) {
            threadLocal.remove();
            // 把连接设置回自动提交的连接
            try {
                connection.setAutoCommit(true);
                // 自动归还到连接池
                connection.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

1

driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/schedule_system
username=root
password=root
initialSize=5
maxActive=10
maxWait=1000

三、pojo包处理

实体类:

使用lombok处理getter setter equals hashcode 构造器

implements Serializable : 习惯上要实现序列化接口,与缓存、分布式项目数据传递有关 将对象序列化 防止报错

@AllArgsConstructor // 全参构造
@NoArgsConstructor // 添加无参构造
@Data         //getter setter equals hashcode toString
public class SysUser implements Serializable {
    private int uid;
    private String username;
    private String userPwd;
}

@AllArgsConstructor
@NoArgsConstructor
@Data
public class SysSchedule {
    private int sid;
    private int uid;
    private String title;
    private int completed;
}

四、dao

Data access Object 数据访问对象
该类中用于定义针对数据库表格CRUD的方法
DAO层一般需要定义接口和实现类

dao包工具类

package com.doug.wake.dao;

import com.doug.wake.util.JDBCUtil;

import java.lang.reflect.Field;
import java.sql.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * @Description: Dao工具类
 */
public class BaseDao {
    // 公共的查询方法  返回的是单个对象
    public <T> T baseQueryObject(Class<T> clazz, String sql, Object ... args) {
        T t = null;
        Connection connection = JDBCUtil.getConnection();
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        int rows = 0;
        try {
            // 准备语句对象
            preparedStatement = connection.prepareStatement(sql);
            // 设置语句上的参数
            for (int i = 0; i < args.length; i++) {
                preparedStatement.setObject(i + 1, args[i]);
            }

            // 执行 查询
            resultSet = preparedStatement.executeQuery();
            if (resultSet.next()) {
                t = (T) resultSet.getObject(1);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != resultSet) {
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (null != preparedStatement) {
                try {
                    preparedStatement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }

            }
            JDBCUtil.releaseConnection();
        }
        return t;
    }
    // 公共的查询方法  返回的是对象的集合

    public <T> List<T> baseQuery(Class clazz, String sql, Object ... args){
        List<T> list =new ArrayList<>();
        Connection connection = JDBCUtil.getConnection();
        PreparedStatement preparedStatement=null;
        ResultSet resultSet =null;
        int rows = 0;
        try {
            // 准备语句对象
            preparedStatement = connection.prepareStatement(sql);
            // 设置语句上的参数
            for (int i = 0; i < args.length; i++) {
                preparedStatement.setObject(i+1,args[i]);
            }

            // 执行 查询
            resultSet = preparedStatement.executeQuery();

            ResultSetMetaData metaData = resultSet.getMetaData();
            int columnCount = metaData.getColumnCount();

            // 将结果集通过反射封装成实体类对象
            while (resultSet.next()) {
                // 使用反射实例化对象
                Object obj =clazz.getDeclaredConstructor().newInstance();

                for (int i = 1; i <= columnCount; i++) {
                    String columnName = metaData.getColumnLabel(i);
                    Object value = resultSet.getObject(columnName);
                    // 处理datetime类型字段和java.util.Data转换问题
                    if(value.getClass().equals(LocalDateTime.class)){
                        value= Timestamp.valueOf((LocalDateTime) value);
                    }
                    Field field = clazz.getDeclaredField(columnName);
                    field.setAccessible(true);
                    field.set(obj,value);
                }

                list.add((T)obj);
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null !=resultSet) {
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
            if (null != preparedStatement) {
                try {
                    preparedStatement.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
            JDBCUtil.releaseConnection();
        }
        return list;
    }

    // 通用的增删改方法
    public int baseUpdate(String sql,Object ... args) {
        // 获取连接
        Connection connection = JDBCUtil.getConnection();
        PreparedStatement preparedStatement=null;
        int rows = 0;
        try {
            // 准备语句对象
            preparedStatement = connection.prepareStatement(sql);
            // 设置语句上的参数
            for (int i = 0; i < args.length; i++) {
                preparedStatement.setObject(i+1,args[i]);
            }

            // 执行 增删改 executeUpdate
            rows = preparedStatement.executeUpdate();
            // 释放资源(可选)


        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if (null != preparedStatement) {
                try {
                    preparedStatement.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }

            }
            JDBCUtil.releaseConnection();
        }
        // 返回的是影响数据库记录数
        return rows;
    }
}

基本按照这样写:

  • Dao 接口
/**
 * @Description: 日程表CRUD
 */
public interface SysScheduleDao {
    /**
     * 用于向数据中增加一条日程记录
     * @param schedule 日程数据以SysSchedule实体类对象形式入参
     * @return 返回影响数据库记录的行数,行数为0增加失败,行数大于0增加成功
     */
    int addSchedule(SysSchedule schedule);

    /**
     * 查找所有的日程信息
     * @return 返回全部日程数据
     */
    List<SysSchedule> findSchedule();
}
public interface SysUserDao {
    /**
     * 向数据库表sys_user增加一条用户记录的方法
     * @param sysUser 要增加记录的username和usePwd 以SysUser对象的形式接收
     * @return 增加 成功返回 1, 失败0
     */
    int addUser(SysUser sysUser);
}
  • Dao实现类:
public class SysScheduleDaoImpl extends BaseDao implements SysScheduleDao {
    @Override
    public int addSchedule(SysSchedule schedule) {
        String sql = "insert into sys_schedule values(DEFAULT,?,?,?)";
        int rows = baseUpdate(sql, schedule.getUid(),schedule.getTitle(), schedule.getCompleted());
        return rows;
    }

    @Override
    public List<SysSchedule> findSchedule() {
        String sql = "select sid,uid,title,completed from sys_schedule";
        List<SysSchedule> scheduleList = baseQuery(SysSchedule.class, sql);
        return scheduleList;
    }
}
public class SysUserDaoImpl extends BaseDao implements SysUserDao {
    @Override
    public int addUser(SysUser sysUser) {
        String sql = "insert into sys_user values(DEFAULT,?,?);";
        int rows = baseUpdate(sql, sysUser.getUsername(), sysUser.getUserPwd());
        return rows;
    }
}

五、service

1
这样写: 写注释

/**
 * 该接口定义了以 sys_user 表 为核心的业务处理功能
 */
public interface SysUserService {

    /**
     * 用户注册方法
     * @param sysUser 要注册的用户名和明文密码 以SysUser对象的形式接收
     * @return 注册 成功返回1 , 失败返回0
     */
    int regist(SysUser sysUser);
}

public class SysUserServiceImpl implements SysUserService {
    private SysUserDao userDao = new SysUserDaoImpl();

    @Override
    public int regist(SysUser sysUser) {
        //密码加密
        sysUser.setUserPwd(MD5Util.encrypt(sysUser.getUserPwd()));
        return userDao.addUser(sysUser);
    }
}

六、controller

前端 action 格式: servlet 的名字 + 方法名
user/add
user/remove …

  • 接收前端传来的URI【 /user/add 】截取后面的add 再定义同名方法,
  • 这样就自动invoke执行相同名字的方法
  • 不用自己手动去写ifelse( 加一个方法就得写一个
    2

servlet 基类 反射

/**
 * @Description: Controller servlet基类 使用反射调用方法
 */
public class BaseController extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //拿到方法的URI 格式:项目上下文Context 加上 后缀名 
        //举例项目Context设置为空时: /schedule/add
        String requestURI = req.getRequestURI();
        //拿到最后的 add 方法名
        String[] split = requestURI.split("/");
        String methodName = split[split.length - 1];
        //使用反射 获取所有的方法
        Class aClass = this.getClass();
        try {
            Method declaredMethod = aClass.getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
            //取消访问检查 防止方法为私有导致不能执行
            declaredMethod.setAccessible(true);
            //执行方法 传入参数
            declaredMethod.invoke(this, req, resp);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

这样只要 继承基类 定义 方法即可

@WebServlet("/schedule/*")
public class SysScheduleController extends BaseController{
    protected void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("add");
    }
}
@WebServlet("/user/*")
public class SysUserController extends BaseController{
    private SysUserService userService = new SysUserServiceImpl();

    /**
     * 接收用户注册的业务请求 处理方法
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void regist(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String userPwd = req.getParameter("userPwd");
        SysUser sysUser = new SysUser(null, username, userPwd);
        int rows =  userService.regist(sysUser);
        if (rows > 0){
            resp.sendRedirect("/registSuccess.html");
        }else{
            resp.sendRedirect("/registFail.html");
        }
    }
}

七、加密工具类 MD5

public class MD5Util {
    public static String encrypt(String strSrc) {
        try {
            char hexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
                    '9', 'a', 'b', 'c', 'd', 'e', 'f' };
            byte[] bytes = strSrc.getBytes();
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(bytes);
            bytes = md.digest();
            int j = bytes.length;
            char[] chars = new char[j * 2];
            int k = 0;
            for (int i = 0; i < bytes.length; i++) {
                byte b = bytes[i];
                chars[k++] = hexChars[b >>> 4 & 0xf];
                chars[k++] = hexChars[b & 0xf];
            }
            return new String(chars);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            throw new RuntimeException("MD5加密出错!!!");
        }
    }
}

八、页面文件

1
注册页面:
1
登录页面
2

九、业务代码

9.1 注册业务处理

controller (servlet)

@WebServlet("/user/*")
public class SysUserController extends BaseController{
    private SysUserService userService = new SysUserServiceImpl();

    /**
     * 接收用户注册的业务请求 处理方法
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void regist(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String userPwd = req.getParameter("userPwd");
        SysUser sysUser = new SysUser(null, username, userPwd);
        int rows =  userService.regist(sysUser);
        if (rows > 0){
            resp.sendRedirect("/registSuccess.html");
        }else{
            resp.sendRedirect("/registFail.html");
        }
    }
}

service 业务代码

/**
 * 该接口定义了以 sys_user 表 为核心的业务处理功能
 */
public interface SysUserService {

    /**
     * 用户注册方法
     * @param sysUser 要注册的用户名和明文密码 以SysUser对象的形式接收
     * @return 注册 成功返回1 , 失败返回0
     */
    int regist(SysUser sysUser);
}

public class SysUserServiceImpl implements SysUserService {
    private SysUserDao userDao = new SysUserDaoImpl();

    @Override
    public int regist(SysUser sysUser) {
        //密码加密
        sysUser.setUserPwd(MD5Util.encrypt(sysUser.getUserPwd()));
        return userDao.addUser(sysUser);
    }
}

dao 数据库

/**
 * @Description: 用户CRUD
 */
public interface SysUserDao {
    /**
     * 向数据库表sys_user增加一条用户记录的方法
     * @param sysUser 要增加记录的username和usePwd 以SysUser对象的形式接收
     * @return 增加 成功返回 1, 失败0
     */
    int addUser(SysUser sysUser);
}
public class SysUserDaoImpl extends BaseDao implements SysUserDao {
    @Override
    public int addUser(SysUser sysUser) {
        String sql = "insert into sys_user values(DEFAULT,?,?);";
        int rows = baseUpdate(sql, sysUser.getUsername(), sysUser.getUserPwd());
        return rows;
    }
}

9.2 登录业务处理

controller :

 /**
     * 接收用户登录请求,完成登录业务接口
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void login(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String userPwd = req.getParameter("userPwd");
        //通过用户名查找对象
        SysUser loginUser = userService.findUserByUsername(username);
        //用户为Null不存在
        if(null == loginUser){
            resp.sendRedirect("/loginUsernameError.html");
            //密码不匹配
        } else if (!MD5Util.encrypt(userPwd).equals(loginUser.getUserPwd())) {
            resp.sendRedirect("/loginUserPwdError.html");
        }else{
            resp.sendRedirect("/showSchedule.html");
        }
    }

service

    /**
     * 根据用户名查找完整的user对象
     * @param username 要查找的用户名
     * @return 查到返回SysUser对象,找不到返回Null
     */
    SysUser findUserByUsername(String username);

    @Override
    public SysUser findUserByUsername(String username) {
        return userDao.findUserByUsername(username);
    }

dao

    /**
     * 根据用户名查找完整的user对象
     * @param username 要查找的用户名
     * @return 查到返回SysUser对象,找不到返回Null
     */
    SysUser findUserByUsername(String username);

    @Override
    public SysUser findUserByUsername(String username) {
        String sql = "select uid,username,user_pwd as userPwd from sys_user where username=?;";
        List<SysUser> sysUserList = baseQuery(SysUser.class, sql, username);
        return sysUserList != null && sysUserList.size() > 0 ? sysUserList.get(0) : null;
    }

总结

开启注解处理:
1
测试类:
测试日程表的CRUD 调用DAO层方法

public class TestSysScheduleDao {
    private static SysScheduleDao sysScheduleDao;

    @BeforeClass
    public static void initSysScheduleDaoImpl(){
        sysScheduleDao = new SysScheduleDaoImpl();
    }

    @Test
    public void testAddSchedule(){
        int rows = sysScheduleDao.addSchedule(new SysSchedule(null, 2, "学习后端", 0));
        System.out.println(rows);
    }

    @Test
    public void testFindSchedule(){
        List<SysSchedule> scheduleList = sysScheduleDao.findSchedule();
        scheduleList.forEach(System.out::println);
    }
}

测试BaseDao工具类:

    private static BaseDao baseDao;

    @BeforeClass
    public static void initBaseDao(){
        baseDao = new BaseDao();
    }

    @Test
    public void testBaseUpdate(){
        String sql = "insert into sys_schedule values(DEFAULT,?,?,?)";
        int rows = baseDao.baseUpdate(sql, 1, "学习JS", 1);
        System.out.println(rows);
    }

    @Test
    public void testBaseQuery(){
        String sql = "select sid,uid,title,completed from sys_schedule";
        List<SysSchedule> listSchedules = baseDao.baseQuery(SysSchedule.class, sql);
        listSchedules.forEach(System.out::println);
    }

    @Test
    public void testBaseSingleQuery(){
        String sql = "select count(1) from sys_schedule";
        Long aLong = baseDao.baseQueryObject(Long.class, sql);
        System.out.println(aLong);
    }

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

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

相关文章

python-自动篇-办公-用Excel画画

文章目录 代码所遇问题ModuleNotFoundError: No module named xlsxwriterFileNotFoundError: [Errno 2] No such file or directory: 111.jpg 效果附件图片excel 代码 # coding: utf-8from PIL import Image from xlsxwriter.workbook import Workbookclass ExcelPicture(obje…

风二西CTF流量题大集合-刷题笔记|NSSCTF流量题(2)

21.[SUCTF 2018 招新赛]follow me SUCTF{password_is_not_weak} 22.[MoeCTF 2022]usb moectf{Learned_a6ou7_USB_trffic} 23.[黑盾杯 2020]Blue flag{Gre4t_j0B_ON_This_Blue_sh4rk} 24.[蓝帽杯 2022 初赛]domainhacker2 提交发现&#xff0c;07ab403ab740c1540c378b0f5aaa4…

vue(vue2)使用svg格式图标

先安装插件 配置svg文件夹&#xff0c;新建icons文件&#xff0c;svg文件夹放svg后缀文件 index.js文件中的配置 import Vue from "vue" import svgIcon from "/common/iconSvg/index.vue"Vue.component(svg-icon,svgIcon) //挂载全局组件//下面…

深入浅出AI落地应用分析:AI音乐生成之「Suno.ai」

接下来会每周集中体验一些通用或者垂直的AI落地应用&#xff0c;主要以一些全球或者国外国内排行较前的产品为研究对象&#xff0c;「AI 产品榜&#xff1a; aicpb.com」以专题的方式在博客进行分享。 本节主要介绍和体验AI音乐生成应用产品Suno AI&#xff0c;Suno来自目前最…

【 CSS 】定位

不要因为小小的失败而放弃大大的梦想&#xff0c;每一次坚持都是通向成功的一步。- 马克吐温 1. 定位 1.1 为何使用定位 我们先来看一个效果&#xff0c;同时思考一下用标准流或浮动能否实现类似的效果&#xff1f; 场景1: 某个元素可以自由的在一个盒子内移动位置&#xff0c…

【MySQL数据库】专栏文章索引

为了方便 快速定位 和 便于文章间的相互引用等 作为一个快速准确的导航工具 MySQL数据库 &#xff08;一&#xff09;.CentOS 7 安装配置MySQL

基于神经网络的电力系统的负荷预测

一、背景介绍&#xff1a; 电力系统负荷预测是生产部门的重要工作之一&#xff0c;通过准确的负荷预测&#xff0c;可以经济合理地安排机组的启停、减少旋转备用容量、合理安排检修计划、降低发电成本和提高经济效益。负荷预测按预测的时间可以分为长期、中期和短期负荷预测。…

win10系统 pdf 文件无法正常预览

网上也看了不少办法&#xff0c;修改注册表什么的&#xff0c;太麻烦了&#xff0c;尝试了一下下载Adobe Acrobat Reader&#xff0c;安装后就可以成功预览显示啦&#xff01;对&#xff0c;就是这么简单&#xff01;Adobe Acrobat Reader下载链接&#xff1a;link

【每日一题】2.LeetCode——删除有序数组中的重复项

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更新的动力❤️ &#x1f64f;小杨水平有限&#xff0c;欢迎各位大佬指点&…

性能优化-OpenCL运行时API介绍

「发表于知乎专栏《移动端算法优化》」 本文首先给出 OpenCL 运行时 API 的整体编程流程图&#xff0c;然后针对每一步介绍使用的运行时 API&#xff0c;讲解 API 参数&#xff0c;并给出编程运行实例。总结运行时 API 使用的注意事项。最后展示基于 OpenCL 的图像转置代码。在…

CSS 蜡烛效果

<template><view class="holder"><!-- 身子 --><view class="candle"><!-- 光源 --><view class="blinking-glow"></view><!-- 火星子 --><view class="thread"></view>…

Unity 建造者模式(实例详解)

文章目录 说明实例1&#xff1a;构建游戏角色实例2&#xff1a;构建游戏场景实例3&#xff1a;构建UI界面 说明 在Unity中&#xff0c;建造者模式&#xff08;Builder Pattern&#xff09;是一种创建型设计模式&#xff0c;它通过分离对象构建过程的复杂性&#xff0c;允许您以…

JAVA 学习 面试(二)多线程篇

Java多线程 线程池 线程池原理 创建方式&#xff1a;newFixedThreadPool (固定数目线程的线程池)、newCachedThreadPool(可缓存线程的线程池)、newSingleThreadExecutor(单线程的线程池)、newScheduledThreadPool(定时及周期执行的线程池)、new ThreadPoolExecutor() &#x…

windows 11安装VMware 17 ,VMware安装Ubuntu 20.4

一、下载安装激活VMware 17 下载与激活&#xff1a;Vmware 17 下载地址、最新激活码 2024 _ 注意&#xff1a;安装路径自己选择&#xff0c;路径中尽可能避免中文或空格 二、下载Ubuntu 镜像 下载镜像地址&#xff1a;清华大学开源软件镜像站 点开下载镜像地址&#xff0c;找…

[docker] 关于docker的面试题

docker命名空间 docker与虚拟机的区别 容器虚拟机所有容器共享宿主机的内核每个虚拟机都有独立的操作系统和内核通过namespace实现资源隔离&#xff0c;通过cgroup实现限制资源的最大使用量完全隔离。每个虚拟机都有独立的硬件资源秒级启动速度分钟级启动速度容器相当于宿主机…

如何测试你的 Golang 代码

文章目录 简单概述最易想到的方法一个快速体验案例学会使用 go testing测试的编写规则灵活记忆 API 的使用 实践一个案例简洁紧凑的表组测试详细的日志输出灵活控制运行哪些测试总结参考 不论是开源项目&#xff0c;还是日常程序的开发&#xff0c;测试都是必不可少的一个环节。…

软件测试Fiddler手机抓包iPhone

Fiddler不但可以截获各种浏览器发出的HTTP/HTTPS请求&#xff0c;也可以截获各种移动设备&#xff0c;发出的HTTP/HTTPS请求。最关键的是&#xff0c;Fiddler还可以断点调试&#xff0c;修改Request和Response&#xff0c;而且即便抓包的是IOS设备&#xff0c;这些操作也可以直…

Hive 行列转化 方式总结

行列转换 列转行 使用 lateral view explode(array|map) 或 lateral view inline(array_struct) 可以将列转换为行。 单列转多行&#xff0c;降维&#xff08;单列数组或键值对&#xff09; 示例1&#xff1a;explode(array(…)) select ..., A from T lateral view exp…

C语言——结构体讲解

目录 一、结构体类型的声明 二、结构体变量的定义和初始化 三、结构体的重命名 四、结构体的自引用 五、结构体内存对齐 六、结构体传参 七、结构体实现位段 7.1 什么是位段 7.2 位段的声明和使用 7.3 位段的空间大小计算 7.4 位段的内存分配 7.5 位段的跨平…

wamp集成环境部署

Windows下Apache服务器搭建 第一步&#xff1a;下载Windows下的最新ZIP压缩包 推荐下载网址&#xff1a;http://www.apachelounge.com/download/ 为了让Apache服务器发挥更好的性能&#xff0c;请根据自己的系统选择下载&#xff0c;如果不清楚自己的系统是64位还是32位&am…