mall-swarm简介 mall-swarm是一套微服务商城系统,采用了 Spring Cloud Greenwich、Spring Boot 2、MyBatis、Docker、Elasticsearch等核心技术,同时提供了基于Vue的管理后台方便快速搭建系统。mall-swarm在电商业务的基础集成了注册中心、配置中心、监控中心、网关等系统功能。 系统架构图 系统架构图 后端技术栈 技术 说明 Spring Cloud 微服务框架 Spring Boot 容器+MVC框架 Spring Security 认证和授权框架 MyBatis ORM框架 MyBatisGenerator 数据层代码生成 PageHelper MyBatis物理分页插件 Swagger-UI 文档生产工具 Elasticsearch 搜索引擎 RabbitMq 消息队列 Redis 分布式缓存 MongoDb NoSql数据库 Docker 应用容器引擎 Druid 数据库连接池 OSS 对象存储 MinIO 对象存储 JWT JWT登录支持 LogStash 日志收集 Lombok 简化对象封装工具 Seata 全局事务管理框架 Portainer 可视化Docker容器管理 Jenkins 自动化部署工具 项目结构
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
mall ├── mall-common -- 工具类及通用代码模块 ├── mall-mbg -- MyBatisGenerator生成的数据库操作代码模块 ├── mall-security -- 封装SpringSecurity+JWT的安全认证的模块 ├── mall-registry -- 基于Eureka的微服务注册中心 ├── mall-config-- 基于Spring Cloud Config的微服务配置中心 ├── mall-gateway -- 基于Spring Cloud Gateway的微服务API网关服务 ├── mall-monitor -- 基于Spring Boot Admin的微服务监控中心 ├── mall-admin -- 后台管理系统服务 ├── mall-search -- 基于Elasticsearch的商品搜索系统服务 ├── mall-portal -- 移动端商城系统服务 └── mall-demo -- 微服务远程调用测试服务 |
学习路线 之前有朋友问我,mall-swarm这个项目有没有学习教程?其实这个项目的功能与mall项目基本一致,只是在此基础上改成了微服务版本,只要看我写的《mall学习教程》和《Spring Cloud学习教程》即可,下面聊聊我所推荐的学习路线。 学习mall 《mall学习教程》主要分为如下几个部分,推荐学习顺序是除参考篇以外可以按下面的顺序学习,对于参考篇,可以在用到里面相关技术时再学习。 序章:mall项目的整体架构及功能介绍,同时对于新手推荐了一些相关书籍资料; 架构篇:mall项目的架构搭建教程,手把手教你搭建一个mall项目在使用的基本项目骨架; 业务篇:mall项目电商业务相关教程,对于了解项目业务有很大帮助; 技术要点篇:mall项目中的一些技术要点解析,主要介绍一些技术在项目中的运用; 部署篇:mall项目的部署教程,包括Windows、Linux和自动化部署方案; 参考篇:mall项目中所用技术和工具的入门教程,每一篇都可以单独学习,对于mall项目,这些教程的深入程度都刚刚好。 项目地址:https://github.com/macrozheng/mall-learning 学习SpringCloud 《Spring Cloud学习教程》是一套涵盖大部分核心组件使用的教程,包括Spring Cloud Alibaba及分布式事务Seata,基于Spring Cloud Greenwich及SpringBoot 2.1.7。20篇文章,篇篇精华,30个Demo,涵盖大部分应用场景。mall-swarm项目中所用到的Spring Cloud技术该教程基本都涵盖了,学习该教程可以为学习mall-swarm项目打下良好的Spring Cloud基础。 项目地址:https://github.com/macrozheng/springcloud-learning 学习mall-swarm 当我们学习了《mall学习教程》和《Spring Cloud学习教程》之后就可以着手学习mall-swarm这个项目了。首先需要的就是按之前的教程把项目跑起来,然后进行源码的学习,相信有了学习上面两套教程的基础,搞懂源码并不是什么难事。下面提供下mall-swarm的部署教程: mall-swarm在Windows环境下的部署 mall-swarm在Linux环境下的部署(基于Docker容器) 微服务架构下的自动化部署,使用Jenkins来实现! […]
View Details【安装】 1、下载安装包: 在官网下载https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 2、上传到服务器/usr/lib目录下 3、解压:
|
1 2 |
cd /usr/lib tar -zxvf /usr/lib/jdk-8u211-linux-x64.tar.gz |
4、配置环境变量
|
1 |
vi /etc/profile |
添加
|
1 2 |
export JAVA_HOME=/usr/lib/jdk1.8.0_211 export PATH=$JAVA_HOME/bin:$PATH |
5、生效
|
1 2 |
chmod -R 755 /usr/lib/jdk1.8.0_211 source /etc/profile |
6、检查是否生效
|
1 |
java -version |
出现版本号则已生效 【调优配置】 1、堆配置 -Xms 初始堆大小 -Xmx 最大堆大小 -Xmn 设置年轻代大小 -Xss 设置每个线程的堆栈大小 典型设置: -Xmx3550m 设置JVM最大可用内存为3550m; -Xms3550m 设置JVM初始内存为3550m,此值可以设置-Xmx相同,以避免每次垃圾回收完成以后JVM重新分配内存; -Xmn2g 设置年轻代大小为2G。整个堆大小=年轻代大小+年老代大小+持久代大小。持久代一般固定为64M,所以增大年轻代后,将会减少年老代大小,此值对系统性能影响比较大,Sun官方推荐配置为整个堆的3/8; -Xss128k 设置每个线程的堆栈大小。JDK5.0以后每个线程栈大小为1M,以前每个线程堆栈大小为256k。根据应用的线程所需要内存大小进行调整。在相同物理内存下,减少这个值能够生成更多的线程。但是操作系统对一个进程内的线程还是有限制的,不能无限生成,经验值在3000-5000左右。 为什么要区分新生代和老生代 堆中区分的新生代和老年代是为了垃圾回收,新生代中的对象存活期一般不长,而老年代中的对象存活期较长,所以当垃圾回收器回收内存时,新生代中垃圾回收效果较好,会回收大量的内存,而老年代中回收效果较差,内存回收不会太多。 2、设置年轻代大小 -XX:NewSize 年轻代初始值 -XX:MaxNewSize 年轻代最大值 -XX:NewRatio 年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代) -XX:SurvivorRatio 年轻代中Eden区与Survivor区的大小比值 3、回收器的选择 -XX:+UseParallelGC 选择垃圾收集器为并行收集器。此配置仅对年轻代有效。即上述配置下,年轻代使用并行收集,而年老代仍旧使用串行收集。 -XX:PARALLELgcThreads 配置垃圾回收线程数,即:同时多少个线程一起进行垃圾回收。此值最好配置与处理器数目相同。 -XX:+UseParallelOldGC 配置年老代来及收集方式为并行收集,JDK6.0支持对年老代并行收集 -XX:MaxGCPauseMillis=100 设置每次年轻代垃圾回收的最长时间,如果无法满足此时间,JVM会自动调整年轻代大小,以满足此值 -XX:+UseAdaptiveSizePolicy 设置此选项以后,并行收集器会自动选择年轻代区大小和相应的Survivor区比例,以达到目标系统规定的最低响应时间或者收集频率等,此值建议使用并行收集器时,一直打开 【调优工具】 Jconsole,jProfile,VisualVM
View Detailseclipse已安装lombok插件,ide提示均正常,但gradle中编译报错cannot find symbol 经过排查发现是build.gradle中少了annotationProcessor配置导致,补充第二行配置后刷新项目搞定 implementation 'org.projectlombok:lombok:1.18.10' annotationProcessor 'org.projectlombok:lombok:1.18.10' ———————————————— 版权声明:本文为CSDN博主「chandtler」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/chandtler/article/details/103287550
View Details一、数组声明 两种形式(方括号位置放变量前后都可以): int arr[ ]; int[ ] arr2; 二、数组初始化 数组初始化也有两种形式,如下(使用new或不使用new): int arr[] = new int[]{1, 3, 5, 7, 9}; int[] arr2 = {2, 4, 6, 8, 10}; 三、遍历数组 遍历数组可用for/foreach,如下: for循环略 int arr[] = new int[]{1, 3, 5, 7 ,9}; for (int x: arr) { System.out.print(x + "\t"); } 四、Arraysfill填充数组(修改数组) 使用Arrays类的静态方法,需要import包java.util.Arrays,定义了许多重载方法。 void fill(int[] a, int val)全部填充 void fill(int[] a, int fromIndex, int toIndex, int val)填充指定索引的元素 左闭右开
|
1 2 3 |
int[] arr = new int[]{6,6,6,6,6,6}; Arrays.fill(arr, 8); //8,8,8,8,8,8 Arrays.fill(arr3, 1, 3, 9); //6,9,9,8,8,8 |
五、Arrayssort对数组排序(使用Arrays.调用) void sort(int[] a)全部排序 默认升序 void sort(int[] a, int fromIndex, int toIndex)排序指定索引的元素
|
1 2 3 |
int [] array=new int[]{3,7,8,2,1,9}; Arrays.sort(array); //全排序 Arrays.sort(array,2,5); //2到5排序 |
六、ArrayscopyOf复制数组 int[] copyOf(int[] original, int newLength)复制数组,指定新数组长度 int[] copyOfRange(int[] original, int from, int to)复制数组,指定所复制的原数组的索引
|
1 2 3 |
int [] array=new int[]{3,7,8,2,1,9}; array2=Arrays.copyOf(array,3); //新数组的长度为3 array3=Arrays.copyOfRange(array,3,5); //复制第三到五个元素 |
七、检查数组中是否包含某一个值 先使用Arrays.asList()将Array转换成List<String>,这样就可以用动态链表的contains函数来判断元素是否包含在链表中 […]
View Details简述 方法其实有很多种的。我先放一些,之后有再遇到对应代码再放上来。 最简单的当然是一个个找进行对比的方法啦~ 当然还是有一些有趣的操作的 实例一:
|
1 2 3 4 5 6 |
import java.util.Arrays; public static int MAX(int[] arr) { Arrays.sort(arr); return arr[arr.length-1]; } |
就是先排序再来得到结果 实例二 这个是菜鸟教程上的一份代码
|
1 2 3 4 5 6 7 8 9 10 11 12 |
import java.util.Arrays; import java.util.Collections; public class Main { public static void main(String[] args) { Integer[] numbers = { 8, 2, 7, 1, 4, 9, 5}; int min = (int) Collections.min(Arrays.asList(numbers)); int max = (int) Collections.max(Arrays.asList(numbers)); System.out.println("最小值: " + min); System.out.println("最大值: " + max); } } |
实例三:
|
1 2 3 4 |
import java.util.Arrays public static int MAX(int[] arr) { return Arrays.stream(arr).max().getAsInt(); } |
from:https://blog.csdn.net/a19990412/article/details/81296234
View DetailsString[]与List的相互转换 1.0 String[]与List的相互转换
|
1 2 |
String[] arr = new String[]{"s1","s2","s3"}; List<String> list = Arrays.asList(arr); |
1.2 List转String[]
|
1 2 3 4 5 |
List<String> list = new ArrayList<String>(); list.add("s1"); list.add("s2"); list.add("s3"); String[] arr = list.toArray(new String[list.size()]); |
字符数组char[]和字符串String之间的转换 2.0 使用String.valueOf()将字符数组转换成字符串
|
1 2 3 4 5 6 7 |
void (){ char[] s={'A','G','C','T'}; String st=String.valueOf(s); System.out.println("This is : "+st); } >> This is : AGCT |
2.1使用.toCharArray()将字符串转换成字符数组
|
1 2 3 4 5 6 7 8 9 10 |
String str="AGCT"; char[] s=str.toCharArray(); for (int i=0;i<str.length();i++){ System.out.println("This s[i] "+i+s[i]); } This s[i] 0 A This s[i] 1 G This s[i] 2 C This s[i] 3 T |
from:https://blog.csdn.net/qq_41076577/article/details/106909006
View Details工作中需要根据身份证获取性别、出生日期及年龄,且要还要支持15位长度的身份证号码,网上搜索了一下,经过测试好像多少存在点问题,干脆自已写一个。 CertificateNo.java
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
package com.bijian.study; import java.util.Calendar; import java.util.regex.Pattern; /** * 根据身份证获取性别、出生日期、年龄,支持15、18位身份证 */ public class CertificateNo { public ResultDTO parseCertificateNo(String certificateNo) { ResultDTO resultDTO = new ResultDTO(); String myRegExpIDCardNo = "^\\d{6}(((19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])\\d{3}([0-9]|x|X))|(\\d{2}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])\\d{3}))$"; boolean valid=Pattern.matches(myRegExpIDCardNo,certificateNo)||(certificateNo.length() == 17 && Pattern.matches(myRegExpIDCardNo,certificateNo.substring(0,15))); if(!valid){ resultDTO.setStatueMessage("证件号码不规范!"); return resultDTO; } int idxSexStart = 16; int birthYearSpan = 4; //如果是15位的证件号码 if(certificateNo.length() == 15) { idxSexStart = 14; birthYearSpan = 2; } //性别 String idxSexStr = certificateNo.substring(idxSexStart, idxSexStart + 1); int idxSex = Integer.parseInt(idxSexStr) % 2; String sex = (idxSex == 1) ? "M" : "F"; resultDTO.setSex(sex); //出生日期 String year = (birthYearSpan == 2 ? "19" : "") + certificateNo.substring(6, 6 + birthYearSpan); String month = certificateNo.substring(6 + birthYearSpan, 6 + birthYearSpan + 2); String day = certificateNo.substring(8 + birthYearSpan, 8 + birthYearSpan + 2); String birthday = year + '-' + month + '-' + day; resultDTO.setBirthday(birthday); //年龄 Calendar certificateCal = Calendar.getInstance(); Calendar currentTimeCal = Calendar.getInstance(); certificateCal.set(Integer.parseInt(year), Integer.parseInt(month)-1, Integer.parseInt(day)); int yearAge = (currentTimeCal.get(currentTimeCal.YEAR)) - (certificateCal.get(certificateCal.YEAR)); certificateCal.set(currentTimeCal.get(Calendar.YEAR), Integer.parseInt(month)-1, Integer.parseInt(day)); int monthFloor = (currentTimeCal.before(certificateCal) ? 1 : 0); resultDTO.setAge(yearAge - monthFloor); return resultDTO; } } |
ResultDTO.java
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
package com.bijian.study; public class ResultDTO { private String statueMessage; private String sex; private String birthday; private int age; public String getStatueMessage() { return statueMessage; } public void setStatueMessage(String statueMessage) { this.statueMessage = statueMessage; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getBirthday() { return birthday; } public void setBirthday(String birthday) { this.birthday = birthday; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String toString() { String res = ""; if(this.statueMessage != null) { res += this.statueMessage; }else { res += "sex:" + this.sex + ",birthday:" + this.birthday + ",age:" + this.age; } return res; } } |
CertificateNoTest.java
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
package com.bijian.test; import junit.framework.Assert; import org.junit.Before; import org.junit.Test; import com.bijian.study.CertificateNo; import com.bijian.study.ResultDTO; /** * 说明: * 1.身份证信息完全是测试时随便写的,如有雷同,纯属巧合 * 2.写此测试案例的日期是2015-02-08,有测生日当天及前后的案例,后续再运行需更改 */ public class CertificateNoTest { private CertificateNo certificateNo; private ResultDTO resultDTO; @Before public void setUp() throws Exception { certificateNo = new CertificateNo(); } @Test public void test_abnormality_certificateNo_of_18_digit_430522199812623535() { resultDTO = certificateNo.parseCertificateNo("430522199812623535"); Assert.assertNotNull(resultDTO); Assert.assertEquals("证件号码不规范!", resultDTO.getStatueMessage()); } @Test public void test_abnormality_certificateNo_of_18_digit_430522198813013210() { resultDTO = certificateNo.parseCertificateNo("430522198813013210"); Assert.assertNotNull(resultDTO); Assert.assertEquals("证件号码不规范!", resultDTO.getStatueMessage()); } @Test public void test_normality_certificateNo_of_18_digit_430522199812101515() { resultDTO = certificateNo.parseCertificateNo("430522199812101515"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1998-12-10", resultDTO.getBirthday()); Assert.assertEquals(16, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_18_digit_430522199812101595() { resultDTO = certificateNo.parseCertificateNo("430522199812101595"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1998-12-10", resultDTO.getBirthday()); Assert.assertEquals(16, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_18_digit_430522199812101585() { resultDTO = certificateNo.parseCertificateNo("430522199812101585"); Assert.assertNotNull(resultDTO); Assert.assertEquals("F", resultDTO.getSex()); Assert.assertEquals("1998-12-10", resultDTO.getBirthday()); Assert.assertEquals(16, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_18_digit_430522198810103212() { resultDTO = certificateNo.parseCertificateNo("430522198810103212"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1988-10-10", resultDTO.getBirthday()); Assert.assertEquals(26, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_18_digit_before_birthday() { //测试的时间是2015-02-08,表明昨天刚过生日 resultDTO = certificateNo.parseCertificateNo("430522198802073210"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1988-02-07", resultDTO.getBirthday()); Assert.assertEquals(27, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_18_digit_birthday() { //测试的时间是2015-02-08,表明当天正好生日 resultDTO = certificateNo.parseCertificateNo("430522198802083210"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1988-02-08", resultDTO.getBirthday()); Assert.assertEquals(27, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_18_digit_after_birthday() { //测试的时间是2015-02-08,表明第二天才过生日 resultDTO = certificateNo.parseCertificateNo("430522198802093210"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1988-02-09", resultDTO.getBirthday()); Assert.assertEquals(26, resultDTO.getAge()); } @Test public void test_abnormality_certificateNo_of_15_digit_130503671401001() { resultDTO = certificateNo.parseCertificateNo("130503671401001"); Assert.assertNotNull(resultDTO); Assert.assertEquals("证件号码不规范!", resultDTO.getStatueMessage()); } @Test public void test_normality_certificateNo_of_15_digit_430522760201356() { resultDTO = certificateNo.parseCertificateNo("430522760201356"); Assert.assertNotNull(resultDTO); Assert.assertEquals("F", resultDTO.getSex()); Assert.assertEquals("1976-02-01", resultDTO.getBirthday()); Assert.assertEquals(39, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_15_digit_130503670401001() { resultDTO = certificateNo.parseCertificateNo("130503670401001"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1967-04-01", resultDTO.getBirthday()); Assert.assertEquals(47, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_15_digit_370802940221002() { resultDTO = certificateNo.parseCertificateNo("370802940221002"); Assert.assertNotNull(resultDTO); Assert.assertEquals("F", resultDTO.getSex()); Assert.assertEquals("1994-02-21", resultDTO.getBirthday()); Assert.assertEquals(20, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_15_digit_370802941031331() { resultDTO = certificateNo.parseCertificateNo("370802941031331"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1994-10-31", resultDTO.getBirthday()); Assert.assertEquals(20, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_15_digit_before_birthday() { //测试的时间是2015-02-08,表明昨天刚过生日 resultDTO = certificateNo.parseCertificateNo("370802940207331"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1994-02-07", resultDTO.getBirthday()); Assert.assertEquals(21, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_15_digit_birthday() { //测试的时间是2015-02-08,表明当天正好生日 resultDTO = certificateNo.parseCertificateNo("370802940208331"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1994-02-08", resultDTO.getBirthday()); Assert.assertEquals(21, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_15_digit_after_birthday() { //测试的时间是2015-02-08,表明第二天才过生日 resultDTO = certificateNo.parseCertificateNo("370802940209331"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1994-02-09", resultDTO.getBirthday()); Assert.assertEquals(20, resultDTO.getAge()); } } |
from:https://www.iteye.com/blog/bijian1013-2184409
View Details为什么要做性能调优? 一款线上产品如果没有经过性能测试,那它就好比是一颗定时炸弹,你不知道它什么时候会出现问题,你也不清楚它能承受的极限在哪儿。 所以,要不要做性能调优,这个问题其实很好回答。所有的系统在开发完之后,多多少少都会有性能问题,我们首先要做的就是想办法把问题暴露出来,例如进行压力测试、模拟可能的操作场景等等,再通过性能调优去解决这些问题。 好的系统性能调优不仅仅可以提高系统的性能,还能为公司节省资源。这也是我们做性能调优的最直接的目的!所以,接下来我就给大家带来了一份“阿里巴巴lava性能调优实战(2021华山版)”想要学习的朋友们,我们就先来看看文章大概内容:(同时在文末会有笔记领取方式!大家自行解决) 主要内容 模块一 概述 为你建立两个标准。-个是性能调优标准,告诉你可以通过哪些参数去衡量系统性能;另-一个是调优过程标准,带你了解通过哪些严格的调优策略,我们可以排查性能问题,从而解决问题。 模块二 Java 编程性能调优 JDK是Java语言的基础库,熟悉JDK中各个包中的工具类,可以帮助你编写出高性能代码。这里我会从基础的数据类型讲起,涉及容器在实际应用场景中的调优,还有现在互联网系统架构中比较重要的网络通信调优。 03.字符串性能优化不容小觑,百M内存轻松存储几十G数据 05.ArrayList还是LinkedList?使用不当性能差千倍 06.Stream如何提高遍历集合效率? 10.网络通信优化之通信协议:如何优化RPC网络通信? 11.推荐几款常用的性能测试工具 模块三 多线程性能调优 目前大部分服务器都是多核处理器,多线程编程的应用广泛。为了保证线程的安全性,通常会用到同步锁,这会为系统埋下很多隐患;除此之外,还有多线程高并发带来的性能问题,这些都会在这个模块重点讲解。 12.多线程之锁优化(上):深入了解Synchronized同步锁的优化方法 13.多线程之锁优化(中):深入了解Lock 同步锁的优化方法 15.多线程调优(上):哪些操作导致了上下文切换? 17.并发容器的使用:识别不同场景下最优容器 模块四 JVM性能监测及调优 Java 应用程序是运行在JVM之上的,对JVM进行调优可以提升系统性能。这里重点讲解Java对象的创建和回收、内存分配等。 20. 磨刀不误砍柴工:欲知JVM调优先了解JVM内存模型 21.深入JVM即时编译器JIT,优化Java编译 22.如何优化垃圾回收机制? 模块五 设计模式调优 在架构设计中,我们经常会用到-一些设计模式来优化架构设计。这里我将结合一-些复 杂的应用场景,分享设计优化案例。 29.生产者消费者模式:电商库存设计优化 30. 装饰器模式:如何优化电商系统中复杂的商品价格策略? 模块六 数据库性能调优 数据库最容易成为整个系统的性能瓶颈,这里我会重点解析-一些数据库的常用调优方法。 33.MySQL调优之事务:高并发场景下的数据库事务调优 35.记一次线上SQL死锁事故:如何避免死锁? 38.数据库参数设置优化,失之毫厘差之千里 模块七 实战演练场 以上六个模块的内容,都是基于某个点的调优,现在是时候把你前面所学都调动起来了,这里我将带你进入综合性能问题高频出现的应用场景,学习整体调优方法。 41.如何设计更优的分布式锁? 43.如何使用缓存优化系统性能? 最后 作者:努力向上的小芷 链接:https://juejin.cn/post/6920124384027885581 来源:掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
View DetailsDevTools的检测时间和idea的编译所需时间存在差异。在idea还没完成编译工作前,DevTools就开始进行重启和加载,导致@RequestMapping没有被全部正常处理。其他方法没试,就直接用了看起来最简单的方法:牺牲一点时间,去加长devtools的轮询时间,增大等待时间。 解决方案如下: spring.devtools.restart.poll-interval=3000ms spring.devtools.restart.quiet-period=2999ms from:https://www.cnblogs.com/yxfcnbg/p/11510426.html
View Details