![](https://img-blog.csdnimg.cn/20191227102624150.jpeg?x-oss-process=image/resize,m_fixed,h_224,w_224)
Java实战项目分享
文章平均质量分 67
好玩的实战项目源码分享
凉拌海蜇丝
我要一步一步往上爬~
展开
-
Springboot+Maven做启动类与业务模块分离的架构模式
之前的项目一直是启动类与Controller,Service,Mapper等包同级。Maven仅仅是引入其他模块或者第三方Jar包工具。但是最新接手一套项目的架构非常有趣,也是记录一下分享一下,直接上示意图:上图一共五个Maven项目,父模块包含着四个子模块,子模块中有一个就是负责启动ABC那个子模块的启动类,ABC三套子模块中,又有各自的controller,service,mapper的包,然而仅需要ABC三个子模块的controller的包名路径一样(⚠️最好要保持一致,不然该案例的配置会扫描不原创 2022-05-13 17:33:37 · 1341 阅读 · 1 评论 -
InheritableThreadLocal的使用和最简单易懂源码分析
ThreadLocal的基本使用和源码关于ThreadLocal的知识点需要看另外一篇博客:ThreadLocal从简单使用及源码InheritableThreadLocal基本使用在了解完ThreadLocal后,我们来看下面例子:会发现ThreadLocal的一个弊端:父子线程无法共享数据那么我们对例子进行一下改造:使用InheritableThreadLocal完美解决这个问题源码分析:这里先试着停下思考:(1)它是怎么让子线程拿到了父线程设置的参数?(2)它放在哪里?又怎么取原创 2022-02-22 11:15:30 · 628 阅读 · 1 评论 -
邻近分类算法---KNN(Java实现+公式计算例子)
名词解释:KNN:K-Nearest-Neighbor K值最邻近所以网上有好几种叫法:最近邻,邻近…其实都是指的KNN,其实按照翻译都对。KNN算法产生于1968年,是数据挖掘和数据分类技术中最简单的入门级算法。按照字面意思,就是计算出距离K值最近的邻居数据,设对应数据为X,然后把待分类数据归类为X。原理基于大量不同维度的训练数据,做循环比较分析,具体经历下面四步流程:①准备数据,对数据进行预处理 。②计算测试样本点(也就是待分类点)到其他每个样本点的距离 。③对每个距离进行排序,然后选择原创 2022-02-18 17:27:00 · 3746 阅读 · 2 评论 -
CyclicBarrier的多种使用姿势和简单源码分析
是什么?循环屏障,顾名思义像一个屏障那样,可以拦截一定数量的线程,当足够数量多的线程到达屏障后,就会“突破”屏障,所有被拦截的线程会继续往下执行,也类似于一个“集合点”“计数器”,不过它可以被循环利用怎么用?例子1:举一个简单的例子,学校开校运会,所有学生站上赛道后才能开跑public class School { private static CyclicBarrier barrier = new CyclicBarrier(3); public static void ma原创 2022-02-14 16:50:41 · 295 阅读 · 0 评论 -
ThreadLocal从简单使用及源码
是什么?直译是“线程本地(变量)”,一个类似map结构的类,为每个线程变量单独创建一个副本,保证线程安全为什么要用?理由1:跨越多个方法进行参数传递public class School { static ThreadLocal<String> threadLocal = new ThreadLocal<>(); public static void main(String[] args) { say(1); } stat原创 2022-02-10 15:29:43 · 560 阅读 · 0 评论 -
从局部变量表和操作数栈理解 i++ 和 ++i
两个概念:局部变量表:类被创建后的一小块内存区域,存放当前类的局部变量值操作数栈:栈帧中的一小块内存区域,专门用于存放计算的中间结果值三个点:1:赋值操作其实是把操作数栈中的中间结果值进行计算后再赋值给某个变量,是最后一步操作2: i++ 是指先把i放入操作数栈中,自身局部变量表中的i变量自增+13: ++i 是先把局部变量表i的值自增+1,再放入到操作数栈例子一:输出的b是多少,应该很多人都知道是1,因为大学时候老师说过a++是先使用a,再++但是a因为++了,所以是2执行过程:(原创 2022-02-08 17:07:08 · 1103 阅读 · 0 评论 -
Variable used in lambda expression should be final or effectively final 问题的解决和追根溯源
翻译:lambda表达式中的变量必须是final的为什么?因为lambda表达式和匿名内部类一样,不需要额外定义类就可以直接写接口方法的实现,但是实际上只是简化了我们的写法,还是会由产生的一个内部类做了该接口的方法实现,那么这个时候,可以理解为其实有两个类,外部类的方法,调用了内部类的方法。而外面那个username,就是外部类的方法中的变量。基于这点认识,我们分析会出现如下两个问题:(1)如果像上面例子的异步执行,有可能就会出现外部类的方法执行完成出栈了,方法中的局部变量username被垃圾回.原创 2022-01-17 15:46:23 · 7225 阅读 · 0 评论 -
Java中的retry:标志
在线程池执行任务的源码中看到的,没接触过,所以当时记录了下来学习后补充。具体作用:就是一个标志位,用来定位的,用于更加优雅更加细化的跳出循环,常见搭配是continue retry 和break retry,举例说明普通for循环public static void main(String[] args) { for (int i = 0; i < 2; i++) { System.out.println("这是 i:"+i); for (int a =原创 2021-11-16 11:38:48 · 685 阅读 · 0 评论 -
Spring自定义注解失效的小坑和解决方案
业务需求写了个自定义注解,作用域加在方法上的,使用方法如下:class Test { @自定义注解 public void methodA(){ ...... }}写完了切面service和各种环绕方法后,测试了一下,生效了,于是提交,告诉队友们可以用起来,结果有一位伙计说注解不生效了,过去看,确实是加在方法上,不过是下面这样调用的:class Test { public void methodA(){ this.methodB(); } @自定义注解 public voi原创 2021-11-10 19:23:01 · 5462 阅读 · 0 评论 -
线程池执行任务原理
我们都很清楚多线程任务怎么创建,也知道线程池怎么用,那么这篇文章主要是用来分析线程池是怎样执行多线程任务的,首先我们创建一个线程池,从它的execute执行方法做为故事起点~(1)执行任务方法源码入参command就是待执行的任务,这一点源码解释了int c 是获取线程池的运行状态和线程数之类的信息,在线程池这个类的每一步操作都会判断一次,这样才能随时知道线程池的运行状态,它底层比较复杂,是通过Int类型的32位取值来表示不同的运行状态,这里不做展开,详情有另外一篇博客说明。判断假如worker原创 2021-10-25 11:07:39 · 403 阅读 · 0 评论 -
数据仓库分层概念
ODSOperational Data Store 操作数据存储(贴源层)指的是从数据源中经过Extract(数据抽取)-Transform(数据转换)-Load(数据加载)获取到的数据存储到该层。不是简单的数据换个地方存,而是经过了一定的过滤,去重,还原,清洗工作后保存的一层数据。跟源数据最贴近,但不是源数据的一层数据存储层,为整个数仓的加工数据提供来源的一层。例如通过Kafka增量获取通过FlinkJob进行过滤去重清洗,保存到ODS层的TiDB/ClickHouse/Hive之类的存储服务上。原创 2021-10-22 11:16:35 · 720 阅读 · 0 评论 -
Java读取Excel文档每一行数据
public String readExcel() throws IOException { Map<Integer,Object> map = new HashMap<>(); File excelFile = new File("D:\\XX\\jojo\\Desktop\\XXXX.xlsx"); XSSFWorkbook wb = new XSSFWorkbook(new FileInputStream(excelFile));原创 2021-08-31 10:29:51 · 2196 阅读 · 0 评论 -
CloseableHttpClient的Get/Post基本使用与小坑
前言:是什么?当用习惯了Spring自带得RestTemplate,就很少用HttpClient接口的方式了,其实CloseableHttpClient也是http网络请求的一种工具包,实现了HttpClient接口,可以让我们方便的设置请求参数和请求头信息,还能让我们决定连接超时时间和socket超时时间,同时它会自己维护一个连接池,可以做连接数限制(默认5)和过期回收策略,防止每次请求都要创建新的connect,非常的方便。(1)准备工作依赖:Gradle:implementation 'or原创 2021-08-03 11:43:19 · 7239 阅读 · 0 评论 -
Mybatis列与实体类ORM映射失效解决方法
ORM框架的映射正常来说只要遵循规则,都是可以映射到的。要注意以下几个点(1)开启驼峰映射规则在项目的properties文件中添加:mybatis.configuration.map-underscore-to-camel-case=true或者,在mybatis-config.xml(2)确保POJO类遵循了驼峰命名例如:数据库中列名叫:create_timepojo中属性就应该叫:createTime如果pojo中叫createDate,又不好随便改,牵涉的旧代码很多,怎原创 2021-07-30 10:36:27 · 748 阅读 · 0 评论 -
一文看懂Concurrent面试常问类Executor,ExecutorService,AbstractExecutorService,ThreadPoolExecutor作用,关系与区别
Concurrent包是jdk1.5所提供的一个针对高并发进行编程的包,也是多线程并发编程最喜欢问的,特别是从线程,线程池的使用做为最简单的切入点,先看个不太好理解的类图接下来我们从头往下,一步步拆分开来研究:Executor:多线程框架的主要接口,它底层就是一个execute执行方法。它代表着线程任务的执行,也是一切的开始,不管什么线程安全策略,多线程管理,定时,串行执行,都是建立在这个“执行”的基础之上,没有execute执行,线程也就等于无用。看它源码注释:An object that ex原创 2021-07-20 18:54:12 · 456 阅读 · 0 评论 -
Mybatis中的一二级缓存通俗易懂解析
前言:缓存我们都知道,是把数据存放在内存中,依靠内存的高速读写能力提高查询效率,那么mybatis中的一二级缓存又是什么呢?有什么区别呢?我们一上来先不说概念,以更简单理解的角度入手(1)实际业务需求假设有个业务需求,需要读取Hbase中二进制格式的数据,要我们设计一个类似ORM(Object Relational Mapping 对象关系映射)映射的功能,我们会怎么做?这一块我在自定义注解中读取Hbase列族列名解析后映射到对应的对象中做过,只需要遵循一定规范,常见例如驼峰,例如蛇形,甚至自己.原创 2021-07-19 16:26:55 · 426 阅读 · 1 评论 -
BeanUtils.copyProperties基本用法与小坑
(1)实际应用BeanUtils.copyProperties(赋值目标对象,模板源对象);我们都知道当有两个对象AB,属性名称一样的情况下,如果需要把A的全部属性给B,传统写法是:B.setXX(A.getXX());如果只有几个特别的参数需要赋值过去这样写没问题,如果AB有100个参数需要粘过去,那么代码就太冗余太长了,BeanUtils.copyProperties就是为了解决这个问题的,现在假设有AB两个对象:static class DemoA { private String原创 2021-07-15 17:33:18 · 9764 阅读 · 0 评论 -
Java序列化与反序列化(实战应用与小坑)
前言:杜绝八股取士,活学活用从我做起,本文将会从简单的维度入手,分析序列化到底是什么?为什么要用?怎么用?有什么坑?希望能帮助到更多学习道路上的同学1:是什么?简单来说,序列化就是把内存中的对象通过一定的规则转换成字节序列,然后保存到磁盘,反序列化就是从磁盘中读取对应的字节序列出来恢复成原来那个对象,也可以说是根据字节序列“创建”出原来那个对象,我们都记得创建对象的几种方式:new,clone,reflect,序列化与反序列化。2:为什么要用?首先很明显就是保存某个对象在某一时期的某种状态,又或.原创 2021-07-09 17:24:50 · 395 阅读 · 2 评论 -
深入源码一步步看懂thread.join()做线程同步
(1)怎么理解join?它的意思是:加入,融合我们可以想象多线程其实就是异步的一种形式,new thread跟当前主线程正常情况下并行执行互不影响,有可能主线程执行快,有可能新的子线程执行快,都不确定,如果主线程需要用到子线程的处理结果,也就是主线程需要等待子线程执行完成之后再执行,这个时候就要用到join()方法了。join方法可以暂停主线程,等待某个子线程执行完之后再继续执行下面的代码那么join方法的意思就很明显了,让当前线程“加入”子线程的执行后面,变得类似串型化执行(2)怎么使用?假设需原创 2021-06-24 17:09:05 · 241 阅读 · 0 评论 -
park(), wait(), sleep()线程的挂起/唤醒的基本使用与区别
直接上代码,先看一段很简单的创建线程的代码:Thread threadB = new Thread(new Runnable() { @Override public void run() { System.out.println("BBB"); }});threadB.start();执行结果没问题(1)假设有个业务场景,线程任务必须在满足某个条件才执行,而不是start的时候执行,怎么做?这个时候理所当然就想着先把当前线程挂起,满足条件时候再唤醒。经过改造,写出如下代码:原创 2021-06-23 16:41:10 · 2304 阅读 · 0 评论 -
面试基础:谈String类的不可改变性
String是我们用得最多的一个类,它不是基本类型,但底层是依赖char[]字符一维数组实现的,我们还是直接看它长什么样,再做进一步分析。final 修饰的类,所以String自身不可以被继承(原因下面说)final 修饰了char一维数组,所以创建出来后就不允许再进行重新赋值(原因下面说)基于这个String,下面考几道常见面试题:(1)String a = "a";String b = "a";System.out.println(a == b);结果是true,因为a,b变量都指向原创 2021-06-17 18:10:45 · 236 阅读 · 2 评论 -
Java的强引用,软引用,弱引用,虚引用
所谓的强引用,软引用,弱引用,虚引用其实是几种不同的对象创建方式,相当于给创建出来的对象打上不同的标签。我们都知道对象的生命周期由垃圾收集器做GC来控制,我们虽然无法控制垃圾回收,但是我们能配合垃圾回收的规则,通过编码来管理某些对象的生命周期,更充分利用内存,减少无效对象的内存占用,避免OOM,这就可以用上强引用,软引用,弱引用,虚引用几种方式。(1)强引用Object o = new Object();String a = new String(“hello world”);在一个方法中使用原创 2021-06-16 17:21:12 · 176 阅读 · 0 评论 -
Java8 stream常用流式操作(集合类的转换,元素的最大最小平均值/查重/排序/过滤/删除/个数限制/跳跃/奇偶性...)
想象一下如果以前的Java写法针对List与Map容器类相互转换,特定属性的排重,集合元素排序,过滤筛选,删除元素,奇偶性判断,返回限制的个数……之类的操作,第一步就是需要写for循环,把每个元素遍历出来,再做自己逻辑操作。这里抛开以前在for循环里面写代码的固化思维,减少一点for,简化代码,如何写得更加简洁?首先创建今天的主角类:Zoo,类属性很简单:id和namepublic class Zoo { private int id; private String name;原创 2021-06-15 17:51:22 · 2333 阅读 · 1 评论 -
通过动物园来理解:内部类,静态内部类,匿名内部类
(1)内部类类用来描述现实中的某一个东西所具有的属性,所具有的方法等等,类与类之间可以有关联,例如动物园Zoo类里可以有:鱼Fish类,猴子Monkey类,狮子Lion类。这些不同的动物类,有自己独特的属性(鳃,爪子,翅膀,利齿)和活动方法。所以我们可以称Zoo为外部类,而Fish,Monkey,Lion等都可以做为Zoo的内部类。通过内部类这种形式,可以更形象的描述某一个东西的组成部分,可以更好更细致的描述复杂的类之间的关系public class Zoo { private String n原创 2021-05-28 17:30:13 · 301 阅读 · 0 评论 -
Java中Comparable与Comparator适用场景与区别
了解了并总结了一下该知识盲区,在今后的开发工作中遇到合适的场景刚好能用得上官方文档:https://tool.oschina.net/apidocs/apidoc?api=jdk-zh简单点说,就是通过实现该接口,使类具有“自然排序”的功能,先拿简单的类型Integer和String做实验可以看到strArray和intArray都是两组乱序的数组,在调用Arrays.sort之后,再打印输出,就变成了有序的了。根据这个sort方法点击进入:有一个countRunAndMakeAscend原创 2021-05-26 18:28:31 · 275 阅读 · 2 评论 -
策略模式
(1)是什么?策略模式其实很简单,就是针对不同的场景,做出不同的处理策略(2)策略模式的优缺点:优点:(1)可以砍掉代码中过多的if else if 和 switch case语句,使代码更加整洁优雅,一定程度上提高了性能。(2) 新增类型或者场景仅仅需要新增一个处理策略,不需要改动旧代码,遵循了开闭原则,更好维护。缺点:(1)如果场景过多,会产成过多的策略类,一定程度上增加了理解成本(3)怎么用?(案例演示)假设有一个需求,是根据传入的类型Type的不同,构造出不同的对象并且调用相对应的原创 2021-05-21 15:35:38 · 4502 阅读 · 1 评论 -
线程池隔离与信号量隔离
隔离:针对不同的服务资源做的限制不会影响到其它服务,例如商城应用有AB两个接口,A接口只允许10个线程访问,B接口允许20个,他们两个应该是互不干扰的服务资源,也就是A接口调用满了不会影响B接口调用。如果不对AB两个接口做资源隔离,只对商城应用做一个大的限制(30)的话,有可能会因为A接口执行较慢,导致占满了30个线程,导致B接口不可用(因为整体应用只允许30)。线程池隔离就是把请求扔给不同的资源(也就是要调用的服务,针对每个服务都创建线程池)的线程池,让线程池创建线程去调用服务执行任务,具体的线程数原创 2021-05-20 15:48:10 · 2742 阅读 · 0 评论 -
通过抢厕所理解Java中的信号量Semaphore
信号量是一个并发工具类,(重复)是一个工具类,控制并发线程数,内部保存有虚拟的许可数量,线程执行操作时候要先获得许可,执行完毕释放许可,如果没有可用许可,则阻塞直到其它线程释放。init(也就是new Semaphore)方法进行许可数的初始化release方法释放许可Acquire方法申请许可,元子操作假设有个临界资源A每次只允许一个线程访问,所以许可初始化为1,利用信号量就可以做隔离线程t1和t2都要访问临界资源At1,t2都进行acquire,元子操作许可-1,t1获得许可,t2阻塞t原创 2021-05-20 15:42:18 · 151 阅读 · 1 评论 -
记一次OOM与内存泄漏排查经历
场景:测试环境有个应用容易爆OOM,导致容器也会不断重启,大佬怀疑是内存泄漏导致的,于是对它进行排查登陆上对应的服务器,安装ArthasArthas使用指南查看仪表盘:dashboard开始压测前开始压测后:堆内存比较满,而且是survivor区和eden区占用率飙升严重,右上角垃圾回收次数不断增加,eden区回收占用时间较长但是还不能确定是否存在内存泄漏,所谓内存泄漏,也就是内存脱离JVM的控制,无法对泄漏的内存进行回收利用,测试方法是手动GC:jcmd XXX(Java应用的进程号原创 2021-05-12 15:22:58 · 366 阅读 · 1 评论 -
TiDB两阶段提交(乐观事务与悲观事务)
学习TiDB事务的底层原理思想,总结一下自己的理解官方文档乐观事务:一种与传统分布式事务不同的解决方案,不一定会加锁,能够实现跨节点的分布式事务安全,如果写冲突不频繁,那么可以通过跳过获取行锁而提高性能,如果写同一行冲突频繁,性能会低于悲观事务下面请对照着官网的一张图,配合理解乐观事务的实现(1)客户端事务开始,TiDB接到begin后,向PD管理层申请一个time stamp (下面简称ts)做为事务起始编号 start_ts .(2)执行客户端SQL:1:读请求,则先向PD获取Regio原创 2021-04-27 17:45:02 · 958 阅读 · 0 评论 -
TiDB几个重要生态工具
官方文档https://docs.pingcap.com/zh/tidb/stable/hardware-and-software-requirements网上的概念: TiDB 是一款定位于联机事务处理/联机分析处理( HTAP: Hybrid Transactional/Analytical Processing)的融合型数据库产品,结合了传统的行式存储数据库服务和NoSql非关系型数据库的特点,实现了一键水平伸缩,支持无限水平扩展,引入MVCC多版本控制协议保证数据强一致性(可以防止脏读幻读不可重原创 2021-04-23 16:31:49 · 443 阅读 · 0 评论 -
TiDB配置文件常见坑
(1) net.core.somaxconn = 128, should be greater than 32768net.core.somaxconn是Linux中的一个内核(kernel)参数,表示socket监听(listen)的监听队列上限。而socket server可以一次性处理backlog中的所有请求,处理后的请求不再位于监听队列中。当Server处理请求较慢时,导致监听队列被填满后,新来的请求就会被拒绝。FIX:vi /etc/sysctl.conf新增:net.core.soma原创 2021-04-23 15:49:55 · 3317 阅读 · 0 评论 -
TiDB集群部署(Centos7 * 3)
(1)安装TiUP1.下载 : curl --proto ‘=https’ --tlsv1.2 -sSf https://tiup-mirrors.pingcap.com/install.sh | sh2.设置环境变量:source .bash_profile3.安装 TiUP cluster 组件:tiup cluster4.升级TiUP cluster组件版本:tiup update --self && tiup update cluster(2) 写配置文件1.直接下载配置原创 2021-04-23 15:39:18 · 520 阅读 · 0 评论 -
不声明第三个参数(临时变量)交换两个数的值+快速查找数组中只出现一次的数字+异或运算的底层原理
题目1:设数组{3,2,1,7,2,3,7},除一个数字外,其它数字都是成对出现,求如何快速找出只出现了一次的数字?解:public static void main(String[] args) { int[] array = new int[]{3,2,1,7,2,3,7}; int result = array[0]; for (int i = 1; i < array.length; i++) { result = r原创 2021-04-19 11:42:34 · 137 阅读 · 0 评论 -
动态规划:鸡蛋掉落问题图文解析+Java实现
题目:你将获得 K 个鸡蛋,并可以使用一栋从 1 到 N 共有 N 层楼的建筑。每个蛋的功能都是一样的,如果一个蛋碎了,你就不能再把它掉下去。你知道存在楼层 F ,满足 0 <= F <= N 任何从高于 F 的楼层落下的鸡蛋都会碎,从 F 楼层或比它低的楼层落下的鸡蛋都不会破。每次移动,你可以取一个鸡蛋(如果你有完整的鸡蛋)并把它从任一楼层 X 扔下(满足 1 <= X <= N)。你的目标是确切地知道 F 的值是多少。无论 F 的初始值如何,你确定 F 的值原创 2021-04-14 16:05:37 · 480 阅读 · 0 评论 -
SpringBoot拦截器简单的拦截校验小Demo
拦截器其实功能上跟过滤器一样,也是AOP切面编程的一种实现方式,只不过它能更方便的充分调用Service方法,可以注入 Controller层,Service层,Mapper层等等进行逻辑判断,因为拦截器是基于Java反射机制创建并调用的,属于SpringMvc子容器,父容器完成初始化完成后才进行创建,所以可以注入和调用所有父容器中的service假设有个需求:根据某个入参ID判断是否1.是的话才允许调用并且同时记录请求响应时间,不是的话就返回(1)自定义一个拦截器:package com.examp原创 2021-04-12 18:15:27 · 343 阅读 · 0 评论 -
SpringBoot过滤器实战超简单上手演示
Filter依赖于Servlet容器,属于Servlet的一部分,生命周期由Servlet容器管理,是AOP切面编程的一种具体实现,它自身其实是一个通用的特殊的Service,在请求时会先经过过滤器的处理再针对Service发起真正的请求但是它粒度比较粗,只能针对HttpRequest和HttpResponse前后进行相关校验和逻辑判断处理。同时由于它属于Servlet容器管理,在过滤器内部无法注入Spring容器的实例,也无法调用相关Service方法。例如:自定义Filter:package原创 2021-04-12 17:02:06 · 221 阅读 · 0 评论 -
Spring中@Import作用
在Spring中@Import是一粒非常强力的注解,可以将一个一个类快速注册入容器,这样说可能很抽象,下面将通过两个例子来说明。首先我们回忆一下如何要往Spring容器注入一个类,要加哪些注解?@Controller,@Service,@Repository,@Bean,@Configuration … 加在哪里,就是把当前类实例注入到容器。而@Import,它更像是一种解决依赖关系的,帮助别的类快速注入到容器例:(1)我首先有一个POJO叫Test,(2)我们都知道POJO一般不加注解,要用的原创 2021-04-07 18:15:35 · 454 阅读 · 0 评论 -
自增ID,UUID,雪花ID的使用
主键ID主要有:数据库自增主键uuid雪花ID数据库的自增主键:从大学做实验开始就一直用自增主键,以前也没考虑过用自增主键有啥问题,直到工作后…(1)首先自增主键不适用于分库分表情况,在做数据集合的时候会出现主键重复问题,做多个系统的数据汇总也会有冲突(2)其次,详情…删除…查询…这些接口如果都是依赖着自增主键做操作,很容易有安全性问题(这是测试同学做渗透测试的时候告诉我的),同时很容易造成越权(掌握你自增主键的规律然后一定程度上越过某些校验获取数据)所以以后再给我好好设计数据库的话,我都不原创 2021-04-07 11:39:19 · 2922 阅读 · 0 评论 -
SpringBoot+testNG做单元测试并且生成单元测试覆盖率报告
良好的单元测试习惯可以大大减少Bug,这里将会详细展示如何进行单元测试并且生成覆盖率报告等。(1)创建压测类注意!⚠️与启动类同级的test下的Java目录下!!!与项目的层级结构必须一样!!完全一样!(否则无法生成覆盖率报告: No coverage results)(2)导入依赖!!!<dependency> <groupId>org.testng</groupId> <artifactId>原创 2021-04-06 18:07:49 · 1492 阅读 · 1 评论