- 博客(35)
- 收藏
- 关注
原创 从JVM层面来研究字符串
字符串String是日常Java开发中使用最多的数据类型之一,今天我将从JVM层面来分析一下字符串的原理先简单解释一下什么是字符串:在Java中String表示字符串,使用一对""来表示,它有如下特点:String类被声明为final类型,说明String不可被继承String实现了Serializable和Comparable接口,表示字符串支持序列化,并且可以比较大小的String在JDK8及以前内部定义了final char[] value用于存储字符串数据,JDK9改为byte[],说明
2021-01-01 17:38:28
262
原创 The valid characters are defined in RFC 7230 and RFC错误解决
这段时间在在把一个JDK1.7的老项目适配成JDK1.8,这个老项目是JSP+SSM+Tomcat7的项目。所有工作做完后,自测没有发现任何问题,于是上线就给领导用了。但是一个礼拜后有人反映有个表单的提交功能用不了,于是我就开始了定位问题之旅。
2020-12-20 22:13:21
1102
原创 Maven配置阿里云中央仓库
在Maven安装目录中找到conf/settings.xml,找到标签,在内部加上如下内容:<mirror> <id>aliyunmaven</id> <mirrorOf>*</mirrorOf> <name>阿里云公共仓库</name> <url>https://maven.aliyun.com/repository/public</url></mirror>
2020-12-07 21:23:32
1896
原创 Java并发包中常用的类及其用法
介绍几种Java并发包(juc)中常用的类及其用法。1.ReentrantLockReentrantLock可重入锁,与synchronized的区别:1.ReentrantLock需要自己手动加锁解锁,synchronized的不需要2.ReentrantLock可以tryLock尝试获取锁(指定时间内),锁未被占用则获取锁(锁会在tryLock返回true后被调用线程获取),则返回true,否则返回false3.ReentrantLock可以设定公平锁和非公平锁,synchronized只有非
2020-12-05 13:54:21
1053
原创 多线程的三大特性以及Java中如何保证线程安全
Java工程师基本都知道,很多Java程序在单线程和多线程环境中运行往往会得到不同的结果,多线程有三大特性:可见性、有序性、原子性,要保证程序在并发条件下正确执行,就需要保证上述三个特性,缺少一个都有可能导致程序运行不正确。那么多线程的三种特性具体是什么以及在Java中是如何保证以上特性的呢?1、可见性:所谓可见性,就是当一个线程修改了某个线程共享变量的值,其他线程能够立即得知这个修改。为什么其他线程一般情况下无法立即感知变量值的修改呢?原因是CPU和内存之间是有缓存的,正是缓存的存在,使得任一线程修
2020-11-23 23:10:08
1740
原创 Java中锁的四种状态以及锁升级过程
在Java(1.6+)中锁的状态一共有四种,级别由低到高分别是:无锁、偏向锁、轻量级锁、重量级锁,这几个状态会随着竞争情况逐渐升级,其中锁可以升级,但是不能降级。Java中加锁的最简单方式就是加synchronized关键字,那么为什么锁会有这么多状态的锁呢?在Java早期,synchronized叫做重量级锁,加锁过程需要操作系统在内核态访问核心资源,因此操作系统会在用户态与内核态之间切换,效率很低下。于是JDK1.6之后,JVM为了提高锁的获取与释放效率,对synchronized进行了优化,引入了偏
2020-11-11 23:11:10
2506
原创 Java对象的内存布局
开始先抛出一个问题:一个对象o,Object o = new Object();创建完成后会占用多少字节的内存?要能回答这个问题,就需要了解java对象的内存布局。对象内存布局一个Java对象在内存中包括对象头、实例数据和对齐填充三个部分。如下图所示:对象头Mark Word:包含一系列的标记位比如hashcode、GC分代年龄、偏向锁位,锁标志位等。这个Mark Word在对象被加了不同量级的锁时所包含的内容和布局都有所不同,这涉及到锁升级的知识,暂不展开讨论Klass Pointer:是一
2020-11-04 21:58:49
464
3
原创 红黑树原理及代码实现(删除部分)(二)
上一篇讲了红黑树,只讲到了红黑树添加节点,这一篇来讲讲红黑树的删除。不得不说红黑树的删除真的是太太复杂了,我是肝了好几个星期,网上找遍了资料,也没有几个能读懂的,后来结合源码,终于是对红黑树的删除有了一些基本的理解。先奉上一个红黑树大图,用于参照,便于后面的理解:删除红黑树的删除其实就是一个穷举的过程,把节点每一种的情况都考虑一遍,然后尽可能的简化操作,达到代码的精简。对待删除节点的不同状态,可以分成三个大类:1.待删除节点没有子节点2.待删除节点只有一个子节点3.待删除节点有两个子节点当待
2020-10-07 13:31:31
388
1
原创 红黑树原理及代码实现(一)
红黑树简介红黑树是一种自平衡的二叉查找树,它的统计性能要优于平衡二叉树,因此在很多地方都有应用,例如Java中的TreeMap,HashMap等数据结构都使用到了红黑树。红黑树对很多人来说熟悉而陌生,熟悉则是因为知道红黑树在很多场景中有使用,但又对其原理很陌生或者一知半解。今天就来剖析一下红黑树原理红黑树是一种二叉查找树,但是它在二叉查找树基础上增加了着色和相关的性质使得其相对平衡,从而保证了红黑树的查找、插入、删除的时间复杂度最坏为O(log n)。红黑树具备以下5个性质:1.每个节点要么是黑色,要
2020-08-31 23:28:45
809
原创 分布式无状态登录授权解决方案
1.无状态登录1.1.有状态在了解无状态登录之前先解释一下什么是有状态:有状态服务,即服务端需要记录每次会话的客户端信息,从而识别客户端身份,根据用户身份进行请求的处理,最典型的就是Tomcat中的Session。例如:用户登录后,我们会将登录用户的信息保存在Session中,然后返回用户一个记录Session值的Cookie。下次登录时,用户携带Cookie,服务端识别Cookie中Session,从而验证用户信息。缺点:服务端保存大量数据,增加服务端压力服务端保存用户状态,无法进行水平扩展
2020-08-15 15:29:47
581
1
原创 Spring Cloud Config配置中心的使用
Spring Boot项目代码开发过程中有这样一个原则:“约定大于配置”,SpringBoot为我们提供了properties和yml类型的文件供我们编写配置文件,而这些配置文件的编写是要遵循约定,这样一来,就有了一个统一的规范,使得我们在使用任何第三方组件时,都能按照规则配置文件,减少耦合。因此,我们在微服务开发时,会接触到大量的配置,其中有的配置是基础配置,也就是项目要跑起来所需的配置,或者第三方组件要用到的默认配置;同时也有些配置是我们业务需要的,是我们程序员自己定义的。基础配置一般在项目运行之后不
2020-05-11 21:45:16
937
原创 java如何执行cmd命令
今天学到一个小知识,就是如何使用java实现在Windows下执行cmd命令或者在Linux的终端执行命令,也就是执行第三方命令,这里记录一下。要使用到一个类ProcessBuilder,使用方式如下:public class TestProcessBuilder { public static void main(String[] args) throws IOException {...
2020-04-16 23:02:00
3033
原创 Springboot如何读取配置文件中的属性
Springboot自定义属性注入SpringBoot是基于约定的,所以很多配置都有默认值,但如果想使用自己的配置替换默认配置的话,就可以使用application.properties或者application.yml(application.yaml)进行配置。SpringBoot默认会从resources目录下加载application.properties或application.ym...
2020-04-07 21:56:33
721
原创 结合redis实现秒杀业务
背景:某电商网站实现秒杀功能,用户在某个时间段内能够抢购到特价商品,且某一商品最多只能被同一用户抢购一次。基本思路:秒杀商品由商家后台添加,秒杀商品数据保存在tb_seckilll_goods表中,关键字段包括:id,status(审核状态),start_time(开始时间),end_time(结束时间),stock_count(库存量);写一个定时器,定时从秒杀商品表中扫描数据...
2020-04-06 20:56:24
514
2
原创 RabbitMQ使用详解
RabbitMQ是基于AMQP的一款消息管理系统。AMQP(Advanced Message Queuing Protocol),是一个提供消息服务的应用层标准高级消息队列协议,其中RabbitMQ就是基于这种协议的一种实现。常见mq:ActiveMQ:基于JMSRabbitMQ:基于AMQP协议,erlang语言开发,稳定性好RocketMQ:基于JMS,阿里巴巴产品,目前交由Apac...
2020-03-08 16:50:51
363
2
原创 图的深度优先遍历和广度优先遍历
1.图的表示图一般有两种表示方式:一是用二维数组表示(邻接矩阵),而是用数组加链表表示(邻接表)邻接矩阵:将所有结点从0-n标记好索引,分别作为二维数组的横向索引和纵向索引,如果图中两个节点直接相连,则两个结点索引对应的坐标元素设为1,否则为0,如图这种表示方式的优点是简单,便于后面的计算和遍历,缺点是空间浪费邻接表:一个长度为结点个数的数组,数组每个元素都是一个链表,记录了当前数组元素...
2020-03-03 22:39:20
1035
原创 java跳出多重循环的方法
今天学习到了一个极为简单的跳出多重循环的方法:使用带有标号的的break语句。使用方法就是在最外层循环的前面设置一个循环标签,例如outer:,在内层循环中使用break outer即可中断最外层循环。public class TestBreakCircle { public static void main(String[] args) { outer: ...
2020-02-21 16:38:48
178
1
原创 SpringBoot如何统一规范接口返回值以及统一异常处理
如今SpringBoot框架为我们提供了一个极为方便的搭建微服务项目的方案,但是,在使用SpringBoot进行微服务开发时,我们并不能一上来就写代码(当然,如果一上来就写也没什么问题),我们还应该提前指定一些开发规范,否则代码写到后面会越写越烂,毫无规范可言。我通过平时的开发,总结了一套关于统一接口返回类型以及统一异常处理的规范,仅供参考。接口返回值类型规范如今的后台开发,接口规范基本遵循...
2020-02-14 14:34:35
2760
1
原创 使用vue-cli快速搭建一个vue项目
vue-cli是vue官方提供的一个快速搭建vue项目的脚手架,使用它能够快速的构建一个web工程模板。官网:https://github.com/vuejs/vue-cli安装vue-cli的命令:npm install -g vue-cli执行命令之前要保证电脑已经安装nodejs,这是最基本的,不多过述了。快速上手我们新建一个module:切换到该目录:用vue-cli...
2020-02-12 22:04:34
435
原创 网络正常情况下maven依赖仍无法下载的解决方法
网络正常情况下maven依赖仍无法下载的解决方法有时候我们在maven项目的pom文件中添加了依赖坐标之后,部分依赖无法正常导入,如果使用的是idea工具,依赖坐标会飘红,此时网络连接正常,刷新maven之后仍无法下载jar包。出现这种情况的原因可能是配置的maven远程仓库中没有指定的jar包,或者网络原因,无论什么原因,如果不想耽误时间,可以采取下面的方法,来进行手动导入依赖到本地maven...
2020-02-10 18:13:07
2020
原创 快速排序原理及代码实现
快速排序的基本思想所谓快速排序,就是“快速地”确定序列中的某个元素的在序列中的位置,并且在该位置左边的所有元素都比它小,右边所有的元素都比它大,然后通过递归的方式,分别对该位置左边的序列以及右边的序列进行排序。要实现上述思想,我们必须首先确定一个基准数,使得序列中比基准数小的数都在左边,比基准数大的数都在右边。如何确定基准数?其实可以任意,不过一般取第一个数或者序列中间位置的数,我们这里取第一...
2019-12-01 20:43:36
241
原创 希尔排序原理及代码实现
希尔排序基本思想:要想理解希尔排序,首先需要理解插入排序,关于插入排序的原理,我的另一篇博客已经阐述,有兴趣的朋友可以参考一下。分析过插入排序后,我们发现了插入排序的一个弊端,就是在插入过程中,我们是将后面的元素依次与前面的元素按照从后往前的顺序比较,一旦一个很小的元素在序列最后,那么它要比较的次数就会很多,这个问题在希尔排序中得到了解决。希尔排序思路如下:在进行插入排序时,不再只是对该组...
2019-11-16 20:03:09
592
原创 插入排序原理及代码实现
插入排序的基本思想:从arr[1]开始,将每个元素与该元素之前的所有元素按照从后往前的顺序依次比较,如果发现比该元素大,则将较大的元素往后挪一位。这有点像现实生活中玩扑克牌,当我们手上的牌已经拍好序,这个时候来了一张较小的牌,那么我们可以从后往前找,将大的牌依次往后挪,直到找到一个位置,这个位置前的牌都比这张牌小,且这个位置之后的牌都比这张牌大,那么就将牌插入到这个位置即可。可能用语言描述有...
2019-11-16 19:07:27
389
原创 选择排序原理及代码实现
选择排序基本思想:第一轮从arr[0]~arr[n-1]中找到最小的元素,与arr[0]进行交换;第二轮从arr[1]~arr[n-1]中找到最小的元素,与arr[1]进行交换;…依次类推,经过n-1轮之后,就形成了有序序列选择排序java代码实现:public class SelectSort { public static void selectSort(int[] num...
2019-11-16 17:39:13
241
原创 冒泡排序的原理及代码实现
冒泡排序基本思想:通过对待排序序列从前往后,依次比较相邻元素,若发现逆序,则交换位置,使较大的元素逐渐从前往后移动,就像水底的气泡一样逐渐向上冒。假如一个序列有n个元素,具体实现步骤如下:第一轮比较:第1个元素和第2个元素比较,如果逆序,则交换两个元素的位置,否则不交换;接着第2个元素与第3个元素比较,如果逆序则交换,直到比较第n-1个元素和第n个元素结束,此时,整个序列的最大值会移动到最后...
2019-11-16 17:12:24
454
原创 逆波兰计算器原理和实现
逆波兰表达式也叫后缀表达式,其特点是运算符在两个运算数字(或表达式)后,例如:3,4 ,+ , 5,x,6 ,-,后缀表达式虽然不利于人的阅读,但是便于计算机处理。提到后缀表达式也不得不说一下中缀表达式,中缀表达式就是我们最常见的表达式形式,其特点是运算符在两个运算数字(或表达式)之间,例如(3+4)*5-6,中缀表达式符合人类阅读习惯要实现逆波兰计算器,需要完成两个步骤:1.将中缀表达式转...
2019-10-27 13:46:44
685
原创 栈实现计算器计算四则混合运算表达式
以前在学校学习编程时,一般都会接触一道简单的编程题,就是完成一个可以实现加减乘除的简易计算器,但这种计算器只能完成一次加减乘除的运算。这里,我提供了一种计算器可以完成复杂的运算,只要给定一个混合表达式,就可以计算出表达式的值,表达式中可以包含+、-、*、/,以及(,)。思路如下:首先创建两个栈,一个栈存储要计算的数,另一个栈存储计算符遍历字符串的每一个字符2.1. 如果是数字,则要判断是...
2019-10-26 14:09:58
2379
1
原创 循环单向链表解决约瑟夫问题
约瑟夫问题:设编号为1,2,…n的人围成一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m的那个人出列,它的下一位又从1开始报数,数到m的那个人再出列,以此类推,直到所有人都出列,由此产生出一个出队列编号的序列。这里n个人围成一圈,依次出队,这跟我们学到到的循环链表很像,因此我们就通过循环链表来模拟出队情况。首先,需要设计一个节点类型Person,包含num和next两...
2019-10-20 12:42:18
291
原创 IDEA中在父工程下新建子模块后无法自动引入父工程pom中的依赖
今天我在开发一个项目时遇到一个奇怪的问题。项目是这样的,有一个父工程以及多个微服务项目,父工程pom文件控制着微服务的依赖,我在父工程下新建一个Module时,发现新建后的模块始终无法引入父工程的依赖,在模块的pom文件中添加dependency后idea无法引入正确的版本,且发现了idea右侧的Maven Projects工具栏中新建的模块名称是灰色的,现象如下:后来查过很多资料才找到原因:...
2019-10-20 12:02:10
7274
6
原创 单向链表代码实现
链表是有序的列表,以节点的方式进行存储,但在内存中的各节点地址并不连续。其中单链表的特点是每个节点包含data域(存储数据)和next域(指向下一个节点)。单链表分带头结点链表和不带头结点的链表,根据实际需求来确定。这里用代码实现带头结点的单链表:1.先自定义一个节点:class Node { int data;//节点存储的数据 Node next;//指向下一个节点 ...
2019-10-07 22:53:44
296
原创 稀疏数组的实现
稀疏数组就是一个数组中大部分元素都未被使用或者为0,这种数组会造成内存的浪费,所以可以通过一种压缩的方式来表示稀疏数组的内容。压缩方式:1.记录数组一共有几行几列,有多少个非零的值2.把非零元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模,其转化如下图:压缩后的稀疏数组是一个n行3列的数组,其中第一行分别记录原始数组中的行数、列数和非零元素个数;从第二行开始,每行分别记录原始数...
2019-10-01 20:42:21
227
原创 JDK8新特性之函数式接口
函数式接口函数式接口在Java中是指:有且仅有一个抽象方法的接口。函数式接口的实现都可以通过JDK8引入的lambda表达式来表达。在java中,只有确保接口中有且仅有一个抽象方法,才能通过lambda顺利地进行推导。@FunctionalInterface注解与 @Override 注解的作用类似,Java 8中专门为函数式接口引入了一个新的注解: @FunctionalInterface...
2019-09-28 16:24:21
383
原创 java类中静态变量是如何被赋值的
我们知道java中类加载的过程分为:加载、连接、初始化,其中连接阶段又分为验证、准备和解析,准备阶段的动作就是为类的静态变量分配内存,并将其设置为一个默认值,java中各种数据类型的默认值如下:数据类型默认值byte0short0int0long0float0.0double0.0char(空)booleanfalse...
2019-09-08 11:41:34
15041
7
原创 类加载器的阶段分析
类加载器的阶段分析类加载器的阶段加载连接初始化主动使用与被动使用主动使用被动使用在java代码中,类的加载、连接与初始化过程都是在程序运行期间完成的类加载器的阶段类加载过程分为:加载、连接、初始化三个大的阶段,其中连接又可以细分为验证、准备、解析三个过程。加载查找并加载类的二进制数据,在此阶段,虚拟机完成以下3件事情:通过一个类的权限定类名来获取定义此类的二进制字节流。将这个字节流...
2019-08-31 11:54:51
371
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人