实战项目——智慧社区(一)

1、项目介绍

系统功能

登录、修改密码、登出

(1)首页

        (1.1)数据统计:小区人员统计对比图,占比图

(2)物业管理

        (2.1)小区管理:小区数据的增删改查

                (2.1.1)摄像头管理:小区摄像头数据的增删改查

        (2.2)居民管理:居民数据的增删改查,居民人脸采集,Excel 数据导入,Excel 数据导出

        (2.3)小区地图:所有小区在地图上的分布情况

(3)门禁管理

       (3.1) 人脸识别:居民出入小区人脸识别功能

        (3.2)出入记录:所有居民出入小区的人脸识别记录查询

        (3.3)访客登记:访客数据的增删改查,进入登记,离开登记

(4)系统管理

        (4.1)用户管理:用户数据的增删改查,给用户赋予角色设置不同的管理权限

        (4.2)角色管理:角色数据的增删改查,给角色赋予权限

        (4.3)菜单管理:菜单数据的增删改查,不同角色可设置不同的菜单权限

        (4.4)日志管理:实时记录系统所有操作的日志,为排查问题提供依据

技术栈描述

前端:Vue+ElementUI+BaiduMap+ECharts

后端:SpringBoot+SpringMVC+MyBatisPlus+Spring Data Redis+ Swagger

第三方服务:人脸识别,腾讯AI接口(后端)

​                         BaiduMap,ECharts(前端)

数据库:MySQL 数据库存储、Redis 缓存

其他技术:POI Excel 文件导入导出、Swagger 接口文档管理、JWT 登录认证、Spring AOP 日志管理、前端代理解决跨域问题

2、登录模块

数据表设计

用户信息表(user)

用于存储登录用户的登录信息

实现思路

①获取验证码:首先借助UUID或者其它工具生成一个符合要求的验证码;然后存入到缓存数据库redis当中,并设置超时时间;最后将验证码返回给前端

②登录验证:第一步在redis中查询验证码,验证验证码是否有效和正常 ;第二步验证用户名;第三步验证密码(JWT加密,生成token);第四步验证用户状态是否正常;第五步创建token,生成令牌,将token存入到redis中;第六步获取token的过期时间,将token和过期时间返回给前端,允许用户登录并访问首页

获取验证码

①redis配置,redis用于存储验证码和登录生成的token

spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/community?useUnicode=true&characterEncoding=utf-8username: rootpassword: 123456jackson:time-zone: GMT+8date-format: yyyy-MM-dd HH:mm:ssredis:open: truedatabase: 2host: localhostport: 6379

②导入验证码的依赖

<dependency><groupId>com.github.whvcse</groupId><artifactId>easy-captcha</artifactId><version>1.6.2</version>
</dependency><!--工具包-->
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.2.4</version>
</dependency>

③获取生成验证码

    @Autowiredprivate RedisTemplate redisTemplate;/**    * 获取生成验证码* @return*/@GetMapping("/captcha")public Result getCaptcha(){//1、借助UUID或者其它工具生成一个符合要求的验证码//2、存入到缓存数据库redis当中,并设置超时时间//3、验证码返回给前端//利用生成验证码图片的工具类,指定宽和高,以及生成的验证码数量4SpecCaptcha specCaptcha = new SpecCaptcha(130, 48, 4);//将生成的验证码图片转成小写字符串String code = specCaptcha.text().toLowerCase();//通过工具类产生一个UUID值,当成验证码信息存储在redis数据库中的主键String uuid = IdUtil.simpleUUID();//存入redis并设置过期时间为2分钟this.redisTemplate.opsForValue().set(uuid, code, 120, TimeUnit.SECONDS);Map<String, String> map = new HashMap<String, String>(3);map.put("uuid", uuid);map.put("code", code);//将验证码图片转成base64的图片信息,方便前端将图片解析进行显示map.put("captcha", specCaptcha.toBase64());//响应200,就是请求到达了控制器return Result.ok().put("data", map);}

登录验证

①jwt配置,jwt用于验证用户的身份和权限,生成token

jwt:secret: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4K67DMlSPXbgG0MPp0gHexpire: 86400000#  expire: 10000subject: door

 ②导入jwt依赖

        <dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency>

③jwt工具包

package com.qcby.community.util;import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;import java.util.Date;
import java.util.UUID;@ConfigurationProperties(prefix = "jwt")
@Component
public class JwtUtil {private long expire;private String secret;private String subject;/*** 生成token** @param userId* @return*/public String createToken(String userId) {String token = Jwts.builder()//载荷:自定义信息.claim("userId", userId)//载荷:默认信息.setSubject(subject) //令牌主题.setExpiration(new Date(System.currentTimeMillis() + expire)) //过期时间.setId(UUID.randomUUID().toString())//签名哈希.signWith(SignatureAlgorithm.HS256, secret)//组装jwt字符串.compact();return token;}//Token校验public boolean checkToken(String token){if(StringUtils.isEmpty(token)){return false;}try {Jws<Claims> claimsJws = Jwts.parser().setSigningKey(secret).parseClaimsJws(token);} catch (Exception e) {return false;}return true;}public long getExpire() {return expire;}public void setExpire(long expire) {this.expire = expire;}public String getSecret() {return secret;}public void setSecret(String secret) {this.secret = secret;}public String getSubject() {return subject;}public void setSubject(String subject) {this.subject = subject;}
}

④登录请求处理

    @Autowiredprivate JwtUtil jwtUtil;/*** 前端发送过来的登录请求* @param loginForm* @param session* @return*/@PostMapping("/login")public Result login(@RequestBody LoginForm loginForm, HttpSession session){//1、查询redis验证,验证码是否有效和正常//2、验证用户名//3、验证密码(JWT加密,生成token)//4、验证用户状态是否正常//5、允许用户登录并访问首页//验证码校验String code = (String) this.redisTemplate.opsForValue().get(loginForm.getUuid());//判断验证码是否有效if(code == null){
//            return Result.error("验证码已过期");return Result.ok().put("status", "fail").put("date", "验证码已过期");}//判断验证码是否正确if(!code.equals(loginForm.getCaptcha())){
//            return Result.error("验证码错误");return Result.ok().put("status", "fail").put("date", "验证码错误");}//判断用户名是否正确QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.eq("username", loginForm.getUsername());User user = this.userService.getOne(queryWrapper);if(user == null){return Result.error("用户名错误");}//判断密码是否正确,密码加密之后比对String password = SecureUtil.sha256(loginForm.getPassword());if(!password.equals(user.getPassword())){return Result.error("密码错误");}//验证用户是否可用if(user.getStatus() == 0) {return Result.error("账号已被锁定,请联系管理员");}//登录成功session.setAttribute("user", user);//创建token,生成令牌String token = this.jwtUtil.createToken(String.valueOf(user.getUserId()));//将token存入redis,每一次访问不需要重复登录,直接验证令牌this.redisTemplate.opsForValue().set("communityuser-"+user.getUserId(), token,jwtUtil.getExpire());Map<String,Object> map = new HashMap<>();map.put("token", token);map.put("expire", jwtUtil.getExpire());
//        LogAspect.user = user;return Result.ok().put("data", map);}

界面

3、修改密码

实现思路

①发送更新密码请求,弹出更新密码弹出层

②前端密码格式验证,新旧密码是否一致验证

③修改密码:第一步获取session中的用户信息;第二步将根据用户查询的密码和前端传来的旧密码进行比较,如果相等,将新密码加密后在数据库中更新密码字段信息,密码更新成功,返回。

修改密码请求处理

     /*** 修改密码* @return*/@PutMapping("/updatePassword")public Result updatePassword(@RequestBody UpdatePasswordForm updatePasswordForm, HttpSession session){User user = (User)session.getAttribute("user");String pwd = user.getPassword();String password = SecureUtil.sha256(updatePasswordForm.getPassword());if(pwd.equals(password)){String newpassword = SecureUtil.sha256(updatePasswordForm.getNewPassword());user.setPassword(newpassword);if(userService.updateById(user)){return Result.ok().put("status","success");}return Result.error("更新密码失败");}return Result.ok().put("status","passwordError");}

界面 

4、登出模块

实现思路

①登出请求:将当前session设置为无效

②将token设置为空

③将router设置为空

④将cookie里面的token信息清空

⑤返回登录页面

登出请求处理

     /*** 用户退出* @param session* @return*/@PostMapping("/logout")public Result logOut(HttpSession session){session.invalidate();return Result.ok();}

5、首页

登录成功后,根据当前的登录用户来动态加载对应的菜单列表(路由),显示该用户能访问的菜单;并且同时查看小区数据统计,通过柱状图和饼状图展示

数据表设计

角色表(role)

用于存储用户的角色信息

用户角色关联表(user_role)

用户存储角色和用户的关联信息

 

菜单表(menu)

用于存储前端展示的菜单信息,其中parent_id代表父级菜单的序号,0代表一级菜单,name代表菜单名称,path代表菜单url,component代表组件路径,icon代表组件图标

角色菜单关联表(role_menu) 

用于存储角色拥有的菜单权限信息

小区信息表(community) 

用户存储小区信息,其中term_count代表楼栋数量,seq代表排序,lng和lat分别代表经度和纬度

住户表(person)

存储小区的住户信息,其中state代表人脸录入状态,2代表已录入,1代表未录入

加载动态路由

实现思路

①通过session获取用户信息

②根据userId获取角色名称,需要在user_role表和role表中联表查询

③根据userId获取用户的权限菜单:

第一步:根据用户的id查询该用户所对应的角色以及该角色所对应的菜单,需要user_role、user_menu、menu三个表联表查询;

第二步:按照查询出来的菜单进行封装,一个一级菜单的信息封装进一个列表,此菜单下的二级菜单的信息封装进此列表的子列表中,若有三级菜单以此类推进行封装

④返回用户信息、角色名称和用户的权限菜单信息,格式如下

 "data": {
        "userId": 1,
        "username": "admin", 
        "password": "8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92",
        "userType": 1, 
        "realName": "管理员", 
        "contact": "", 
        "mobile": "15679711120", 
        "status": 1, 
        "roleIdList": null
    },
    "roles": "超级管理员",
    "routers": [
        {
            "name": "系统管理",
            "path": "/sys",
            "hidden": "false",
            "redirect": "noRedirect",
            "component": "Layout",
            "alwaysShow": true,
            "meta": {
                "title": "系统管理",
                "icon": "system"
            },
            "children": [
                {
                    "name": "管理员管理",
                    "path": "/user",
                    "hidden": "false",
                    "component": "sys/user/index",
                    "meta": {
                        "title": "管理员管理",
                        "icon": "user"
                    }
                }
            ]
        }
    ]

封装返回的routers信息MenuRouterVO

@Data
public class MenuRouterVO {private String name;private String path;private String component;private String hidden;private String redirect = "noRedirect";private Boolean alwaysShow = true;private MetaVO meta;private List<ChildMenuRouterVO> children;
}@Data
public class ChildMenuRouterVO {private String name;private String path;private String component;private String hidden;private MetaVO meta;
}@Data
public class MetaVO {private String title;private String icon;
}

加载动态路由controller请求

    /*** 通过登录的用于加载动态路由* 显示该用户能访问的菜单* @param session* @return*/@GetMapping("/getRouters")public Result getRouters(HttpSession session){//获取用户名称User user = (User)session.getAttribute("user");//获取用户的角色名称String roles = roleMapper.getRoleNameByUserId(user.getUserId());//获取用户的权限菜单List<MenuRouterVO> routers = this.menuService.getMenuRouterByUserId(user.getUserId());return Result.ok().put("data", user).put("roles", roles).put("routers",routers);}

获取用户的角色名称的mapper

//根据userId获取角色名称@Select("SELECT role_name FROM role, user_role where user_role.role_id=role.role_id and user_role.user_id=#{userId}")public String getRoleNameByUserId(Integer userId);

获取用户的菜单信息service

@Autowiredprivate MenuMapper menuMapper;@Overridepublic List<MenuRouterVO> getMenuRouterByUserId(Integer userId) {//1.根据用户的id查询该用所对应的角色以及该角色所对应的菜单List<Menu> menuList = this.menuMapper.getMenusByUserId(userId);//2.创建一个集合List<MenuRouterVO> 最终的集合List<MenuRouterVO> list = new ArrayList<>();//3.遍历该用户所能查看的所有菜单找到一级菜单封装进MenuRouterVOfor (Menu menu : menuList) {//挑选出父级菜单if (menu.getParentId() == 0) {MenuRouterVO menuRouterVO = new MenuRouterVO();//给父级菜单对象赋值,bean实体类的封装工具类,框架提供//将源对象menu中的相同属性赋值给新对象menuRouterVOBeanUtils.copyProperties(menu, menuRouterVO);//再将没有的属性进行赋值MetaVO metaVO = new MetaVO();metaVO.setTitle(menu.getName());metaVO.setIcon(menu.getIcon());menuRouterVO.setMeta(metaVO);//生成childrenInteger menuId = menu.getMenuId();//4.不是一级菜单的继续遍历找到属于哪个一级菜单下挂在该菜单下List<ChildMenuRouterVO> children = new ArrayList<>();for (Menu child : menuList) {if(child.getParentId() == menuId){//5.封装子菜单ChildMenuRouterVO  在放进集合List<ChildMenuRouterVO>ChildMenuRouterVO childVO = new ChildMenuRouterVO();BeanUtils.copyProperties(child, childVO);MetaVO childMetaVO = new MetaVO();childMetaVO.setTitle(child.getName());childMetaVO.setIcon(child.getIcon());childVO.setMeta(childMetaVO);children.add(childVO);}}//6.将子菜单集合挂在MenuRouterVO的children的集合属性下menuRouterVO.setChildren(children);//7.将每一个MenuRouterVO放进大集合list.add(menuRouterVO);}}return list;}

获取用户的菜单信息mapper

​
@Repository
public interface MenuMapper extends BaseMapper<Menu> {@Select({"select m.menu_id,m.parent_id,m.name,m.path,m.component," +"m.menu_type,m.status,m.icon,m.sort,m.hidden from " +"user_role ur,role_menu rm,menu m where ur.role_id = rm.role_id" +" and rm.menu_id = m.menu_id " +"and ur.user_id = #{userId} order by m.sort"})public List<Menu> getMenusByUserId(Integer userId);
}​

查看小区数据统计

实现思路

查询出所有的小区名称,以及每个小区的对应的住户数量,并将小区名称与其对应的住户数量封装成单个list,从小区信息表community和住户表person中联表查询出来,返回数据如下所示:

"data": {
        "names": [
            "栖海澐颂",
            "宸悦国际",
            "流星花园二区",
            "农学院家属院",
            "金达园",
            "建发城建·文源府",
            "北清云际"
        ],
        "nums": [
            5,
            3,
            1,
            2,
            4,
            2,
            1
        ],
        "list":[
            {
                "name": "栖海澐颂",
                value: 5
            }
        ]

echarts安装

cnpm install echarts@4.9.0 --save

前端代码 

drawLine(){chart().then(res => {// 基于准备好的dom,初始化echarts实例let myChart = this.$echarts.init(document.getElementById('myChart'))// 绘制图表myChart.setOption({color: ['#3398DB'],title: {text: '智慧社区住户量统计',subtext: '对比图',left: 'center'},tooltip: {trigger: 'axis',axisPointer: {type: 'shadow'}},xAxis: {data: res.data.names},yAxis: {},series: [{name: '住户量',type: 'bar',data: res.data.nums}],animationType: 'scale',animationEasing: 'elasticOut',animationDelay: function (idx) {return Math.random() * 200;}});let myChart2 = this.$echarts.init(document.getElementById('myChart2'))myChart2.setOption({title: {text: '智慧社区住户量统计',subtext: '占比图',left: 'center'},tooltip: {trigger: 'item',formatter: '{a} <br/>{b} : {c} ({d}%)'},visualMap: {show: false,min: 80,max: 600,inRange: {colorLightness: [0, 1]}},series: [{name: '住户量',type: 'pie',radius: '55%',center: ['50%', '50%'],data: res.data.list.sort(function (a, b) { return a.value - b.value; }),roseType: 'radius',itemStyle: {color: '#3398DB'},animationType: 'scale',animationEasing: 'elasticOut',animationDelay: function (idx) {return Math.random() * 200;}}]});});}

chartVO数据封装

@Data
public class ChartVO {private Integer value;private String name;
}

查看小区数据统计controller请求

     /*** 查看小区数据统计* @return*/@GetMapping("/chart")public Result chart(){Map map = this.inOutRecordService.chart();return Result.ok().put("data", map);}

查看小区数据统计service 

    @Autowiredprivate InOutRecordMapper inOutRecordMapper;@Overridepublic Map chart() {Map<String, List> map = new HashMap<>();List<String> names = new ArrayList<>();List<Integer> nums = new ArrayList<>();List<ChartVO> chartVOList = inOutRecordMapper.chart();List<ChartVO> list = new ArrayList<>();for(ChartVO chartVo: chartVOList){names.add(chartVo.getName());nums.add(chartVo.getValue());list.add(chartVo);}map.put("names",names);map.put("nums",nums);map.put("list",list);return map;}

 查看小区数据统计mapper

@Select("select count(*) value, c.community_name name from community c, person p where p.community_id=c.community_id group by c.community_id")List<ChartVO> chart();

界面

6、代码生成器

生成代码

生成entity、mapper、mapper.xml、service、serviceImpl、controller文件

package com.qcby.community;import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;import java.util.Arrays;
import java.util.List;public class Main {public static void main(String[] args) {AutoGenerator autoGenerator = new AutoGenerator();DataSourceConfig dataSourceConfig = new DataSourceConfig();dataSourceConfig.setDbType(DbType.MYSQL);dataSourceConfig.setDriverName("com.mysql.cj.jdbc.Driver");dataSourceConfig.setUsername("root");dataSourceConfig.setPassword("123456");dataSourceConfig.setUrl("jdbc:mysql://localhost:3306/community?useUnicode=true&characterEncoding=UTF-8");autoGenerator.setDataSource(dataSourceConfig);GlobalConfig globalConfig = new GlobalConfig();globalConfig.setOpen(false);globalConfig.setOutputDir(System.getProperty("user.dir")+"/src/main/java");globalConfig.setAuthor("admin");globalConfig.setServiceName("%sService");autoGenerator.setGlobalConfig(globalConfig);PackageConfig packageConfig = new PackageConfig();packageConfig.setParent("com.qcby.community");packageConfig.setEntity("entity");packageConfig.setMapper("mapper");packageConfig.setController("controller");packageConfig.setService("service");packageConfig.setServiceImpl("service.impl");autoGenerator.setPackageInfo(packageConfig);StrategyConfig strategyConfig = new StrategyConfig();strategyConfig.setEntityLombokModel(true);strategyConfig.setNaming(NamingStrategy.underline_to_camel);strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);strategyConfig.setInclude("community");TableFill tableFill1 = new TableFill("create_time", FieldFill.INSERT);List<TableFill> list = Arrays.asList(tableFill1);strategyConfig.setTableFillList(list);autoGenerator.setStrategy(strategyConfig);autoGenerator.execute();}
}

生成示例,以community为例

entity

package com.qcby.community.entity;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import java.io.Serializable;
import java.util.Date;import lombok.Data;
import lombok.EqualsAndHashCode;/*** <p>* * </p>** @author admin* @since 2024-03-26*/
@Data@EqualsAndHashCode(callSuper = false)public class Community implements Serializable {private static final long serialVersionUID=1L;@TableId(value = "community_id", type = IdType.AUTO)private Integer communityId;/*** 小区名称*/private String communityName;/*** 楼栋数量*/private Integer termCount;/*** 序号*/private Integer seq;/*** 创建人*/private String creater;/*** 创建时间*/@TableField(fill = FieldFill.INSERT)private Date createTime;/*** 经度*/private Float lng;/*** 维度*/private Float lat;}

mapper

package com.qcby.community.mapper;import com.qcby.community.entity.Community;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;/*** <p>*  Mapper 接口* </p>** @author admin* @since 2024-03-26*/
public interface CommunityMapper extends BaseMapper<Community> {}

mapper.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.qcby.community.mapper.CommunityMapper"></mapper>

service

package com.qcby.community.service;import com.qcby.community.entity.Community;
import com.baomidou.mybatisplus.extension.service.IService;
import com.qcby.community.form.CommunityListForm;
import com.qcby.community.vo.PageVO;/*** <p>*  服务类* </p>** @author admin* @since 2024-03-26*/
public interface CommunityService extends IService<Community> {}

serviceImpl

package com.qcby.community.service.impl;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qcby.community.entity.Community;
import com.qcby.community.form.CommunityListForm;
import com.qcby.community.mapper.CommunityMapper;
import com.qcby.community.mapper.PersonMapper;
import com.qcby.community.service.CommunityService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qcby.community.vo.CommunityVO;
import com.qcby.community.vo.PageVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.ArrayList;
import java.util.List;/*** <p>*  服务实现类* </p>** @author admin* @since 2024-03-26*/
@Service
public class CommunityServiceImpl extends ServiceImpl<CommunityMapper, Community> implements CommunityService {}

controller

package com.qcby.community.controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.stereotype.Controller;/*** <p>*  前端控制器* </p>** @author admin* @since 2024-03-26*/
@Controller
@RequestMapping("//community")
public class CommunityController {}

7、返回封装结果Result

此系统所有的结果都是返回json格式,统一返回样式如下,因此进行返回结果集的统一封装

{
    "msg": "操作成功",
    "code": 200

    // 其它数据
}

代码如下:

package com.qcby.community.util;import java.util.HashMap;public class Result extends HashMap<String,Object> {public static Result ok(){Result result = new Result();result.put("code", 200);result.put("msg", "操作成功");return result;}public static Result error(String msg){Result result = new Result();result.put("code", 500);result.put("msg", msg);return result;}@Overridepublic Result put(String key, Object value) {super.put(key, value);return this;}
}

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

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

相关文章

在开发过程中使用 git rebase 还是 git merge

在开发过程中使用 git rebase 还是 git merge Merge(合并)的优点和缺点Rebase(变基)的优点和缺点总结&#xff1a; Git merge 和rebase的目的是一样的&#xff0c;它们都是将多个分支合并成一个。 虽然他们最终的目标是一样的&#xff0c;但这两种方法实现的方式是不同的。那么…

leetcode73 矩阵置零

题目描述 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用原地算法。 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 输出&#xff1a;[[1,0,1],[0,0,0],[1,0,1]] 输入&#xff1a;matrix [[0,1,2,0],[3,4…

【数据结构】单链表(一)

上一篇【数据结构】顺序表-CSDN博客 我们了解了顺序表&#xff0c;但是呢顺序表涉及到了一些问题&#xff0c;比如&#xff0c;中间/头部的插入/删除&#xff0c;时间复杂度为O(N);增容申请空间、拷贝、释放旧空间会有不小的消耗&#xff1b;增容所浪费的空间... 我们如何去解…

java数据结构与算法刷题-----LeetCode210. 课程表 II

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 文章目录 深度优先遍历但不进行逆拓扑排序&#xff08;不用栈&#xff09;…

leetcode 343. 整数拆分

题目 给定一个正整数 n &#xff0c;将其拆分为 k 个 正整数 的和&#xff08; k > 2 &#xff09;&#xff0c;并使这些整数的乘积最大化。 返回 你可以获得的最大乘积 。 示例 1: 输入: n 2 输出: 1 解释: 2 1 1, 1 1 1。 示例 2: 输入: n 10 输出: 36 解释: 1…

记一次IP访问MySQL失败多次被自动锁定导致无法连接问题,解决方法只需一条SQL。

&#x1f469;&#x1f3fd;‍&#x1f4bb;个人主页&#xff1a;阿木木AEcru &#x1f525; 系列专栏&#xff1a;《Docker容器化部署系列》 《Java每日面筋》 &#x1f4b9;每一次技术突破&#xff0c;都是对自我能力的挑战和超越。 前言 今天下午还在带着耳机摸鱼&#xff…

Netty的基本架构与组件

Netty实战精髓 前言 Netty的组成部分 1、Channel 2、Callback 3、Future ChannelFuture 提供多个附件方法来允许一个或者多个 ChannelFutureListener 实例&#xff0c;这个回调方法 operationComplete() 会在操作完成时调用。 4、Event和Handler 5、EventLOOP Netty 通过触发…

如何在极狐GitLab 启用依赖代理功能

本文作者&#xff1a;徐晓伟 GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署极狐GitLab。 本文主要讲述了如何在[极狐GitLab…

SSH穿透ECS访问内网RDS数据库

处于安全考虑&#xff0c;RDS一般只会允许指定的IP进行访问&#xff0c;而我们开发环境的IP往往是动态的&#xff0c;每次IP变动都需要去修改RDS的白名单&#xff0c;为我们的工作带来很大的不便。 那么如何去解决这个问题&#xff1f; 假如我们有一台ESC服务器&#xff0c;E…

STC89C52学习笔记(八)

STC89C52学习笔记&#xff08;八&#xff09; 综述&#xff1a;本文讲述了LED点阵屏以及如何进行数据串行输入&#xff0c;并行输出。 一、LED点阵屏 1.介绍 LED点阵屏由多个LED组成&#xff0c;以矩阵形式排列&#xff08;类似于矩阵键盘&#xff09;&#xff0c;像素一般…

CSS滚动条样式修改

前言 目前我们可以通过 CSS伪类 来实现滚动条的样式修改&#xff0c;以下为修改滚动条样式用到的CSS伪类&#xff1a; ::-webkit-scrollbar — 整个滚动条 ::-webkit-scrollbar-button — 滚动条上的按钮 (上下箭头) ::-webkit-scrollbar-thumb — 滚动条上的滚动滑块 ::-web…

了解大语言模型的参数高效微调(Parameter-Effcient Fine-Tuning)

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 大语言模型在众多应用领域实现了突破性的进步&#xff0c;显著提升了各种任务的完成度。然而&#xff0c;其庞大的规模也带来了高昂的计算成本。这些模型往往包含数十亿甚至上千亿参数&#xff0c;需要…

Golang使用PGO优化程序性能

文章目录 参考文章PGO是什么使用PGO的好处PGO做了什么热函数内联什么是内联内联的好处Go默认的内联策略查看内联预算PGO的热函数内联 去虚拟化调用指令高速缓存 PGO有什么缺点可执行程序变大构建时间变长 PGO怎么使用典型的工作流程收集CPU配置文件生产环境启动PGO代码改动重新…

Electron+React 搭建桌面应用

创建应用程序 创建 Electron 应用 使用 Webpack 创建新的 Electron 应用程序&#xff1a; npm init electron-applatest my-new-app -- --templatewebpack 启动应用 npm start 设置 Webpack 配置 添加依赖包&#xff0c;确保可以正确使用 JSX 和其他 React 功能&#xff…

3.1 基本形式 机器学习

从本章本节开始就开始正式介绍机器学习的算法了&#xff01;我们首先登场的是---------线性模型。 w可以理解为权重&#xff0c;我们的x就是我们的样本点的各个特征数值&#xff0c;最后输出模型f&#xff08;x&#xff09;。其代表我们把样本点带入&#xff0c;以二分类为例&a…

厂房起火3D消防灭火安全救援模拟演练

深圳VR公司华锐视点依托前沿的VR虚拟现实制作、三维仿真和图形图像渲染技术&#xff0c;将参训者带入栩栩如生的火灾现场。佩戴VR头盔&#xff0c;参训者将真切体验火势蔓延的紧张与危机&#xff0c;身临其境地感受火灾的恐怖。 并且消防安全VR虚拟现实演练系统精心模拟了住宅、…

修复 Windows 上的 PyTorch 1.1 github 模型加载权限错误

问题: 在 Windows 计算机上执行示例 github 模型加载时,生成了 master.zip 文件的权限错误(请参阅下面的错误堆栈跟踪)。 错误堆栈跟踪: 在[4]中:en2de = torch.hub.load(pytorch/fairseq, transformer.wmt16.en-de, tokenizer=moses, bpe=subword_nmt) 下载:“https://…

uniapp 卡片勾选

前言 公司的app项目使用的uniapp&#xff0c;项目里有一个可勾选的卡片功能&#xff0c;效果图如下&#xff1a; 找了一圈没找到什么太好的组件&#xff0c;于是就自己简单写了一个&#xff0c;记录一下。避免以后还会用到 代码 <template><view class"card-…

ELK 企业级日志分析系统 简单介绍

目录 一 ELK 简介 1&#xff0c; elk 是什么 2&#xff0c;elk 架构图 3&#xff0c;elk 日志处理步骤 二 Elasticsearch 简介 1&#xff0c; Elasticsearch 是什么 2&#xff0c; Elasticsearch 的核心概念 3&#xff0c; Elasticsearch 的原理 三 Logstas…

labview技术交流-如何判断一个数是否为质数

问题起源 如何判断一个数是否为质数&#xff0c;其实并不难&#xff0c;只要你知道质数的定义&#xff0c;按照它的定义去编写代码就可以了。但是没有思路的人可能就会一直找不到方向&#xff0c;所以我就简单介绍一下。 还有我想吐槽的点&#xff0c;labview本来就是很小众的语…