开发前期准备工作

开发前期准备工作

文章目录

  • 开发前期准备工作
    • 0 代码规范
      • 0.1 强制
      • 0.2 推荐
      • 0.3 参考
        • `dao`:跟数据库打交道
        • `service`:业务层,人类思维解决
        • `controller`:抽象化
      • 0.4 注释规范
      • 0.5 日志规范
      • 0.6 专有名词
      • 0.7 控制层
        • 统一异常
        • 统一结构体
        • 控制层
        • 提示信息
      • 0.8 控制语句
    • 1 `idea`配置
    • 2 `swagger`配置,`knife4j`
    • 3 `jrebel`配置
    • 4 常用账号汇总
    • 5 集成单元测试
    • 6 新建个人项目
    • 7 断言

0 代码规范

0.1 强制

避免在子父类的成员变量之间、或者不同代码块的局部变量之间采用完全相同的命名,使可理解性降低。

0.2 推荐

好的命名、代码结构是自解释的,注释力求精简准确、表达到位

0.3 参考

dao:跟数据库打交道

[增加]

insert:插入

batchInsert:批量插入

insertSelective:条件插入

insertUseGeneratedKeys

[删除]

delete:删除

delete*ById:根据主键删除

[修改]

update:更新

update*ById:根据主键更新

[查询]

service:业务层,人类思维解决

add:添加

find*ById:根据主键查询

find*By**:根据条件查询

find*ByList:多条件查询

modify:修改

modify*ById:根据主键修改

remove:删除

remove*ById:根据主键删除

controller:抽象化

insert:插入

batchInsert:批量插入

queryOne:查询单个

queryById:根据主键查询

queryByList:多条件查询

count:计数

update:更新

update*ById:根据主键更新

delete:删除

delete*ById:根据主键删除

0.4 注释规范

1 方法内部单行注释,在被注释语句上方另起一行,使用//注释。方法内部多行注释使用/* */注释,注意与代码对齐

2 所有的类都必须添加创建者和创建日期,而日期的设置统一为 yyyy/MM/dd 的格式

/*** @author pingmingbo* @date 2022/11/11*/

3 代码修改的同时,注释也要进行相应的修改,尤其是参数、返回值、异常、核心逻辑等的修改

4 好的命名、代码结构是自解释的,注释力求精简准确、表达到位

5 特殊注释标记,请注明标记人与标记时间。注意及时处理这些标记,通过标记扫描,经常清理此类标记

// TODO pingmingbo 20221112 20221211

0.5 日志规范

1【强制】在日志输出时,字符串变量之间的拼接使用占位符的方式。

说明:因为 String 字符串的拼接会使用 StringBuilderappend()方式,有一定的性能损耗。使用占位符仅是替换动作,可以有效提升性能。

正例:logger.debug("Processing trade with id: {} and symbol: {}", id, symbol);

2 敏感信息不能记录在日志里面,比如用户名和密码

3 日志打印禁止直接使用JSON工具将对象转换String

4 使用warn级别日志记录用户输入参数错误情况,避免用户投诉时候,无所适从;注意日志输出级别,

error级别只记录系统逻辑错误、异常等重要错误信息,如非必要,请不要在此场景打出error级别日志

5 日志输出时候,字符串之间的拼接使用占位符方式

logger.info("traceId:[{}],and symbol:[{}]",id,symbol);
说明:因为String字符串的拼接会使用StringBuilder的append方式,有一定的性能损耗,使用占位符只是替换动作,可以有效提升性能

6 如果循环体次数过多,避免打印不必要的日志

7 打印日志的时机

  • 当遇到问题,只能通过debug定位
  • 碰到if else或者 Switch分支语句,需要在各自分支首行打印日志,确定进入哪个分支
  • 经常以功能为核心进行开发,提交代码之前,可以确定通过日志看到整个流程

8 日志占位符基本格式,通过[]进行参数变量隔离

logger.info("traceId:[{}],and symbol:[{}]",id,symbol);

9 线上禁止使用System.out,System.err

10 谨慎使用e.printStackTrace(),否则出现锁死,服务挂掉问题

短时间大量请求访问该接口,代码异常,进入catch,打印e.printStackTrace()异常信息到控制台,

这些错误堆栈字符串存储字符串缓存池内存空间,该内存空间一下子撑爆了,其他线程进行相互等待,

堆积一定程度,整个应用就挂掉了。

11 异常日志打印规范

logger.error("异常信息 ",e);

   /*** 处理异常几种方式*/@Testpublic void testHandleCatch() {int num = 0;try {num = 3 / 0;logger.info("num : [{}]", num);} catch (Exception e) {logger.error("异常信息 ",e);}}

image-20221215230914727

0.6 专有名词

DO:数据库表对应的pojo实体类,字段一一对应,通过DAO向上传输

DTO:数据传输对象,service或者manager向外传输

BO:业务对象,service

Query:数据查询对象,各层接收上层查询请求,注意超过两个参数进行封装,禁止使用map传递

VO:通常是web层向模板引擎传输对象

0.7 控制层

统一异常

package com.geekmice.springbootselfexercise.exception;/*** @BelongsProject: spring-boot-self-exercise* @BelongsPackage: com.geekmice.springbootselfexercise.exception* @Author: pingmingbo* @CreateTime: 2023-08-10  23:07* @Description: 自定义异常* @Version: 1.0*/
public class BusinessException extends RuntimeException {private String message;public BusinessException(String message) {super(message);}
}
package com.geekmice.springbootselfexercise.exception;import com.geekmice.springbootselfexercise.utils.AjaxResult;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.List;
import java.util.Set;/*** @BelongsProject: spring-boot-self-exercise* @BelongsPackage: com.geekmice.springbootselfexercise* @Author: pingmingbo* @CreateTime: 2023-08-10  22:34* @Description: 统一异常处理* @Version: 1.0*/
@RestControllerAdvice(annotations = {Validated.class})
public class CommonExceptionHandler {/*** 用于捕获@RequestBody类型参数触发校验规则抛出的异常** @param e* @return*/@ExceptionHandler(value = MethodArgumentNotValidException.class)public AjaxResult handleValidException(MethodArgumentNotValidException e) {StringBuilder sb = new StringBuilder();List<ObjectError> allErrors = e.getBindingResult().getAllErrors();if (!CollectionUtils.isEmpty(allErrors)) {for (ObjectError error : allErrors) {sb.append(error.getDefaultMessage()).append(";");}}return AjaxResult.error(sb.toString());}/*** 用于捕获@RequestParam/@PathVariable参数触发校验规则抛出的异常** @param e* @return*/@ExceptionHandler(value = ConstraintViolationException.class)public AjaxResult handleConstraintViolationException(ConstraintViolationException e) {StringBuilder sb = new StringBuilder();Set<ConstraintViolation<?>> conSet = e.getConstraintViolations();for (ConstraintViolation<?> con : conSet) {String message = con.getMessage();sb.append(message).append(";");}return AjaxResult.error(sb.toString());}@ExceptionHandler(value = BindException.class)public AjaxResult handleConstraintViolationException(BindException e) {StringBuilder sb = new StringBuilder();List<ObjectError> allErrors = e.getAllErrors();for (ObjectError allError : allErrors) {String defaultMessage = allError.getDefaultMessage();sb.append(defaultMessage).append(";");}return AjaxResult.error(sb.toString());}@ExceptionHandler(value = Exception.class)public AjaxResult exception(Exception e) {return AjaxResult.error(e.getMessage());}/*** 自定义业务异常** @param e* @return*/@ExceptionHandler(value = BusinessException.class)public AjaxResult exception(BusinessException e) {return AjaxResult.error(e.getMessage());}
}

统一结构体

package com.geekmice.springbootselfexercise.utils;/*** @BelongsProject: spring-boot-scaffold* @BelongsPackage: com.geekmice.sbparamsvalidated.util* @Author: pingmingbo* @CreateTime: 2023-04-19  11:34* @Description: 自定义统一返回结果* @Version: 1.0*/import org.apache.commons.lang3.ObjectUtils;
import org.springframework.http.HttpStatus;import java.util.HashMap;/*** 操作消息提醒** @author ruoyi*/
public class AjaxResult extends HashMap<String, Object> {private static final long serialVersionUID = 1L;/*** 状态码*/public static final String CODE_TAG = "code";/*** 返回内容*/public static final String MSG_TAG = "msg";/*** 数据对象*/public static final String DATA_TAG = "data";/*** 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。*/public AjaxResult() {}/*** 初始化一个新创建的 AjaxResult 对象** @param code 状态码* @param msg  返回内容*/public AjaxResult(int code, String msg) {super.put(CODE_TAG, code);super.put(MSG_TAG, msg);}/*** 初始化一个新创建的 AjaxResult 对象** @param code 状态码* @param msg  返回内容* @param data 数据对象*/public AjaxResult(int code, String msg, Object data) {super.put(CODE_TAG, code);super.put(MSG_TAG, msg);if (ObjectUtils.isNotEmpty(data)) {super.put(DATA_TAG, data);}}/*** 返回成功消息** @return 成功消息*/public static AjaxResult success() {return AjaxResult.success("操作成功");}/*** 返回成功数据** @return 成功消息*/public static AjaxResult success(Object data) {return AjaxResult.success("操作成功", data);}/*** 返回成功消息** @param msg 返回内容* @return 成功消息*/public static AjaxResult success(String msg) {return AjaxResult.success(msg, null);}/*** 返回成功消息** @param msg  返回内容* @param data 数据对象* @return 成功消息*/public static AjaxResult success(String msg, Object data) {return new AjaxResult(HttpStatus.OK.value(), msg, data);}/*** 返回错误消息** @return*/public static AjaxResult error() {return AjaxResult.error("操作失败");}/*** 返回错误消息** @param msg 返回内容* @return 警告消息*/public static AjaxResult error(String msg) {return AjaxResult.error(msg, null);}/*** 返回错误消息** @param msg  返回内容* @param data 数据对象* @return 警告消息*/public static AjaxResult error(String msg, Object data) {return new AjaxResult(HttpStatus.INTERNAL_SERVER_ERROR.value(), msg, data);}/*** 返回错误消息** @param code 状态码* @param msg  返回内容* @return 警告消息*/public static AjaxResult error(int code, String msg) {return new AjaxResult(code, msg, null);}/*** 方便链式调用** @param key   键* @param value 值* @return 数据对象*/@Overridepublic AjaxResult put(String key, Object value) {super.put(key, value);return this;}
}

控制层

package com.geekmice.springbootselfexercise.controller;import com.geekmice.springbootselfexercise.annotation.MethodExporter;
import com.geekmice.springbootselfexercise.utils.AjaxResult;
import com.geekmice.springbootselfexercise.vo.ParamVO;
import com.geekmice.springbootselfexercise.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;import javax.validation.Valid;/*** @BelongsProject: spring-boot-self-exercise* @BelongsPackage: com.geekmice.springbootselfexercise.controller* @Author: pingmingbo* @CreateTime: 2023-08-10  22:29* @Description: TODO* @Version: 1.0*/
@RestController
@RequestMapping(value = "param")
@Slf4j
@Validated
public class ParamController {@GetMapping(value = "getMethod")public AjaxResult getMethod(@Valid ParamVO paramVO) {return AjaxResult.success();}@PostMapping(value = "postMethod")public AjaxResult postMethod(@Valid @RequestBody ParamVO paramVO) {return AjaxResult.success();}
}
package com.geekmice.springbootselfexercise.vo;import lombok.Data;import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Date;/*** @BelongsProject: spring-boot-self-exercise* @BelongsPackage: com.geekmice.springbootselfexercise.vo* @Author: pingmingbo* @CreateTime: 2023-08-10  22:28* @Description: 入参VO* @Version: 1.0*/
@Data
public class ParamVO {/*** 用户名*/@NotBlank(message = "用户名不能为空")private String userName;/*** 生日*/@NotNull(message = "生日不为空")private Date birthday;/*** 性别*/@NotBlank(message = "性别不为空")private String sex;/*** 地址*/private String address;/*** 分数*/private Integer score;}

提示信息

{
“msg”: “生日不为空;性别不为空;用户名不能为空;”,
“code”: 500
}

0.8 控制语句

1 在一个 switch 块内,每个 case 要么通过 continue/break/return 等来终止,要么注释说明程序将继续执行到哪一个 case 为止;在一个 switch 块内,都必须包含一个 default语句并且放在最后,即使它什么代码也没有。

说明:注意 break 是退出 switch 语句块,而 return 是退出方法体。

switch(str){case str1:// 业务代码break;case str2:// 业务代码breakdefault:break;
}

2 三目运算符 condition? 表达式 1 : 表达式 2 中,高度注意表达式 1 和 2 在类型对齐时,可能抛出因自动拆箱导致的 NPE 异常

说明:以下两种场景会触发类型对齐的拆箱操作:

1) 表达式 1 或表达式 2 的值只要有一个是原始类型。

2) 表达式 1 或表达式 2 的值的类型不一致,会强制拆箱升级成表示范围更大的那个类型


3 当某个方法的代码总行数超过 10 行时,return / throw 等中断逻辑的右大括号后均需要加一个空行。

说明:这样做逻辑清晰,有利于代码阅读时重点关注。

4 除常用方法(如 getXxx/isXxx)等外,不要在条件判断中执行其它复杂的语句,将复杂逻辑判断的结果赋值给一个有意义的布尔变量名,以提高可读性。

说明:很多 if 语句内的逻辑表达式相当复杂,与、或、取反混合运算,甚至各种方法纵深调用,理解成本非常高。如果赋值一个非常好理解的布尔变量名字,则是件令人爽心悦目的事情。

5 循环体中的语句要考量性能,以下操作尽量移至循环体外处理,如定义对象、变量、获取数据库连接,进行不必要的 try-catch 操作(这个 try-catch 是否可以移至循环体外)

6 避免采用取反逻辑运算符

1 idea配置

博客地址

2 swagger配置,knife4j

<dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId><version>2.0.7</version>
</dependency>
<!--接口平台-->
<dependency><groupId>io.springfox</groupId><artifactId>springfox-boot-starter</artifactId><version>3.0.0</version>
</dependency>

配置类

package com.geekmice.springbootselfexercise.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;/*** @BelongsProject: spring-boot-scaffold* @BelongsPackage: com.geekmice.sbhelloworld.com.geekmice.sbpagehelper.config* @Author: pingmingbo* @CreateTime: 2023-07-30  15:45* @Description: TODO* @Version: 1.0*/
@Configuration
public class Knife4jConfig {@Bean(value = "defaultApi2")public Docket customDocket() {return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select().apis(RequestHandlerSelectors.basePackage("com.geekmice.springbootselfexercise.controller")).build();}/*** 构建 api文档的详细信息函数* @return*/private ApiInfo apiInfo() {return new ApiInfoBuilder().title("现货交易").version("1.0.0").description("现货交易详情").contact(new Contact("geekmice","http://geekmice.cn","2437690868@qq.com")).build();}
}

控制层

package com.geekmice.springbootselfexercise.controller;import com.geekmice.springbootselfexercise.injector.EasySqlInjector;
import com.geekmice.springbootselfexercise.utils.AjaxResult;
import com.geekmice.springbootselfexercise.utils.SpringUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** @BelongsProject: spring-boot-self-exercise* @BelongsPackage: com.geekmice.springbootselfexercise.controller* @Author: pingmingbo* @CreateTime: 2023-08-09  21:52* @Description: bean操作* @Version: 1.0*/
@RestController
@RequestMapping(value = "bean")
@Api(tags = "3.获取bean操作")
@Slf4j
public class BeanController {@GetMapping(value = "getBean")@ApiOperation(value = "获取bean")public AjaxResult getBean() {// 根据class获取beanEasySqlInjector bean = SpringUtil.getBean(EasySqlInjector.class);// 根据name获取beanEasySqlInjector easySqlInjector = (EasySqlInjector)SpringUtil.getBean("easySqlInjector");// 根据name和class获取beanEasySqlInjector easySqlInjectorSecond = SpringUtil.getBean("easySqlInjector", EasySqlInjector.class);log.info("easySqlInjectorSecond : [{}]" , easySqlInjectorSecond);log.info("easySqlInjector : [{}]", easySqlInjector);log.info("bean : [{}]", bean);return AjaxResult.success();}
}

3 jrebel配置

4 常用账号汇总

git账号
系统用户账号
开发环境 MySQL

5 集成单元测试

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions>
</dependency>
<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope>
</dependency>

与事务相关的测试类

package com.geekmice.springbootselfexercise;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.geekmice.springbootselfexercise.config.DataSourceProperties;
import com.geekmice.springbootselfexercise.dao.UserDao;
import com.geekmice.springbootselfexercise.domain.UserDomain;
import com.geekmice.springbootselfexercise.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.ibatis.session.ResultContext;
import org.apache.ibatis.session.ResultHandler;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.env.Environment;
import org.springframework.test.context.junit4.SpringRunner;import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;/*** @description 测试类,需要调用dao*/
@Slf4j
@SpringBootTest(classes = SpringBootSelfExerciseApplication.class)
@RunWith(SpringRunner.class)
class DaoTest {private String port;private static String newPort;@Value("${server.port}")public void setPort(String port){newPort=port;}@Autowiredprivate DataSourceProperties dataSourceProperties;@Autowiredprivate Environment environment;@Resourceprivate UserService userService;@Resourceprivate UserDao userDao;@Testvoid contextLoads() {// log.info("端口号:【{}】",port);String username = dataSourceProperties.getUsername();String password = dataSourceProperties.getPassword();String url = dataSourceProperties.getUrl();String driverClassName = dataSourceProperties.getDriverClassName();log.info("用户名:【{}】",username);log.info("密码:【{}】",password);log.info("地址URL:【{}】",url);log.info("驱动类:【{}】",driverClassName);}}

与事务无关的测试类

package com.geekmice.springbootselfexercise;import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.geekmice.springbootselfexercise.domain.TempData;
import com.geekmice.springbootselfexercise.domain.UserDomain;
import com.geekmice.springbootselfexercise.utils.BigDecimalUtil;
import com.geekmice.springbootselfexercise.utils.DateUtil;
import com.geekmice.springbootselfexercise.utils.FileUtil;
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.env.Environment;
import org.springframework.util.Assert;import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;/*** @BelongsProject: spring-boot-self-exercise* @BelongsPackage: com.geekmice.springbootselfexercise* @Author: pingmingbo* @CreateTime: 2023-08-06  09:27* @Description: 无事务* @Version: 1.0*/
@Slf4j
@SpringBootTest
public class NoDaoTest {/*** 解决map修改key问题*/@Testpublic void testSetMapKey() {log.info("需求:k1变为k2,value不变");Map<String, Object> map = new HashMap<>();map.put("k1", "v1");log.info("修改前");for (Map.Entry<String, Object> entry : map.entrySet()) {log.info("key:【{}】,value:【{}】", entry.getKey(), entry.getValue());}String pendingItem = map.get("k1").toString();map.remove("k1");map.put("k2", pendingItem);log.info("修改后");for (Map.Entry<String, Object> entry : map.entrySet()) {log.info("key:【{}】,value:【{}】", entry.getKey(), entry.getValue());}}}

6 新建个人项目

工具类,配置类,切面,过滤器,监听器,常量,统一异常,统一结构体,文件解析类,自定义注解,反射

7 断言

处理抛异常情况,简单场景可以使用

逻辑复杂使用iflese,throw抛异常

// 对象
Assert.notNull(null, "对象不为空");
Assert.isNull(new Object(), "对象为空");// 集合
Assert.notEmpty((Map)null, "集合不为空");
Assert.isTrue(CollectionUtils.isEmpty(testBuildData()), "集合必须空");// 字符串包含
Assert.isTrue(StringUtils.contains("abc", "e"), "不能包含");
Assert.isTrue(!StringUtils.contains("abc", "a"), "必须包含");// 表达式
Assert.isTrue(1>2, "条件表达式为false");

img

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

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

相关文章

java线程和go协程

一、线程的实现 线程的实现方式主要有三种&#xff1a;内核线程实现、用户线程实现、用户线程加轻量级进程混合实现。因为自己只对java的线程比较熟悉一点&#xff0c;所以主要针对java线程和go的协程之间进行一个对比。 线程模型主要有三种&#xff1a;1、内核级别线程&#…

Unittest自动化测试框架vs Pytest自动化测试框架

引言   前面一篇文章Python单元测试框架介绍已经介绍了python单元测试框架&#xff0c;大家平时经常使用的是unittest&#xff0c;因为它比较基础&#xff0c;并且可以进行二次开发&#xff0c;如果你的开发水平很高&#xff0c;集成开发自动化测试平台也是可以的。而这篇文章…

如何培养潜在客户?看完这篇你就懂了

图片来源于&#xff1a;SaleSmartly官网 有效的潜在客户培育策略将帮助您将更多潜在客户转化为付费客户。 但是&#xff0c;这并不总是那么容易——您必须与其他公司争夺受众的注意力&#xff0c;并向您的领导证明为什么值得投资您的产品或服务。在本文中&#xff0c;我将向您展…

STM32 RTC实验

RTC时钟简介 STM32F103的实时时钟&#xff08;RTC&#xff09;是一个独立的定时器。 STM32的RTC模块拥有一组连续计数的计数器&#xff0c;在相对应的软件配置下&#xff0c;可提供时钟日历的功能。 修改计数器的值可以重新设置系统的当前时间和日期。 RTC模块和时钟配置系统…

iKeyPrime完美解4G信号,可以登录iCloud,有消息通知,支持最新iOS16.6。

iKeyPrime是一款绕过激活锁界面的解锁工具&#xff0c;可以激活所有iPhone苹果手机&#xff0c;二网/三网恢复信号&#xff0c;并且支持插卡接打电话、收发短信、4G流量上网&#xff0c;支持iCloud登录&#xff0c;有消息通知&#xff0c;支持iPhone5S~X的所有型号&#xff0c;…

精益制造、质量管控,盛虹百世慧共同启动MOM(制造运营管理)

百世慧科技依托在电池智能制造行业中的丰富经验&#xff0c;与盛虹动能达成合作&#xff0c;为其提供MOM制造运营管理平台&#xff0c;并以此为起点&#xff0c;全面提升盛虹动能的制造管理水平与运营体系。 行业困境 中国动力电池已然发展为全球最大的电池产业&#xff0c;但…

[ROS]yolov7部署ROS

Yolov7是一种基于PyTorch深度学习框架的目标检测算法&#xff0c;具有高精度和快速的特点&#xff0c;被广泛应用于机器人领域。将Yolov7部署到ROS中可以方便地实现机器人对环境的感知和理解。 在部署Yolov7到ROS之前&#xff0c;需要准备以下环境和工具&#xff1a; Ubuntu …

Netty—FuturePromise

Netty—Future&Promise 一、JDK原生 Future二、Netty包下的 Future三、Promise1、使用Promise同步获取结果2、使用Promise异步获取结果.3、使用Promise同步获取异常 - sync & get4、使用Promise同步获取异常 - await5、使用Promise异步获取异常 在异步处理时&#xff0…

Img标签的src地址自动拼接本地域名(localhost:8080)导致图片不显示问题

摘要&#xff1a;做Vueelement ui项目的时候&#xff0c;发现使用element ui的upload上传图片时&#xff0c;不显示的问题。我项目的图片是上传到七牛云&#xff0c;长传成功后返回存储在七牛云中的地址。后面发现是因为返回的地址是外部地址&#xff0c;需要完整的URL&#xf…

Android大厂需要刷的(999道)面试题

想必大家都在为今年的金九银十做准备&#xff0c;今年也是最为艰难的一年。作为程序员从未感觉到如此艰难&#xff0c;身边不是被辞退就是找不到工作。先不说2023年应届生毕业即失业&#xff0c;作为开发15年的老Android程序员&#xff0c;现在也在和300个人挣一个岗位。 肉少…

使用Dbeaver连接GaussDB

1.下载DBeaver&#xff0c;官网地址 2.安装软件&#xff0c;打开软件&#xff0c;点击数据库->驱动管理器&#xff0c;具体操作如下图&#xff1a; 3、选择新建后进行参数设置&#xff0c;如下图&#xff1a; 具体参数如下图 驱动名称: GS #随便定义 驱动类型&#…

Docker-安装(Linux,Windows)

目录 前言安装版本Docker版本说明前提条件Linux安装使用YUM源部署获取阿里云开源镜像站YUM源文件安装Docker-ce配置Docker Daemon启动文件启动Docker服务并查看已安装版本 使用二进制文件部署 Windows安装实现原理安装步骤基本使用 参考说明 前言 本文主要说明Docker及其相关组…

如何使用代理配置快速定位接口测试脚本问题?

在调试接口用例过程中&#xff0c;如果响应结果和预期结果不一致&#xff0c;则需要检查请求信息。通过代理获取自动化测试中的请求响应信息&#xff0c;对比与正常请求响应的区别&#xff0c;就能够更直观的排查请求错误&#xff0c;相当于编写代码时的 debug 功能。 实战练习…

软件上线测评报告怎么做?

软件上线测试 软件上线前必须经过一个整体的测评&#xff0c;从而帮助企业了解软件的运行情况。软件上线测评检测报告&#xff08;软件产品测试报告&#xff09;也通常被称为&#xff1a;科技项目验收测试报告、&#xff08;软件类&#xff09;科技成果鉴定测试、软件检测报告…

cron介绍

cron表达式在线生成 在使用定时调度任务的时候&#xff0c;我们最常用的&#xff0c;就是cron表达式了。通过cron表达式来指定任务在某个时间点或者周期性的执行。 cron表达式的组成 cron表达式是一个字符串&#xff0c;由6到7个字段组成&#xff0c;用空格分隔。其中前6个字…

解决uniapp下拉框 内容被覆盖的问题

1. 下拉框 内容被覆盖的问题 场景: 现在是下拉框被表格覆盖了 解决办法: 在表格上添加css 样式来解决这个问题 .add-table{display: static;overflow: visible; } display: static: 将元素会按照默认的布局方式进行显示&#xff0c;不会分为块状或行内元素。 overflow: vi…

NAT地址转换,路由器作为出口设备,实现负载分担

路漫漫其修远兮&#xff0c;吾将上下而求索 一个善于创造的人&#xff0c;一定是一个善于分享的人。 今天整理了一个实验&#xff0c;具备NAT地址转换&#xff0c;路由器作为出口设备&#xff0c;实现负载分担&#xff0c;实现路由策略 目录 实验图 实验要求 实验配置 基…

Linux--I/O复用之select

目录 一&#xff1a;概念 二&#xff1a;使用 三&#xff1a;参数介绍&#xff1a; 1.ndfs&#xff1a; 2.fd_set类型&#xff1a; 3.readfds&#xff1a; 4.writefds&#xff1a; 5.exceptfds&#xff1a; 6.timeout&#xff1a; 7.返回值&#xff1a; 四&#xff1…

2023年7月京东投影仪行业品牌销售排行榜(京东大数据)

鲸参谋监测的京东平台7月份投影仪行业销售数据已出炉&#xff01; 7月份&#xff0c;投影仪市场呈现增长趋势。根据鲸参谋平台的数据可知&#xff0c;7月京东平台投影仪的销量将近20万&#xff0c;同比增长约16%&#xff1b;销售额将近3.8亿&#xff0c;同比增长约4%。 ​*数据…

django.core.exceptions.AppRegistryNotReady: Apps aren‘t loaded yet.

运行django测试用例报错django.core.exceptions.AppRegistryNotReady: Apps arent loaded yet. 解决&#xff1a;在测试文件上方加上 django.setup() django.setup()是Django框架中的一个函数。它用于在非Django环境下使用Django的各种功能、模型和设置。 在常规的Django应用…