一卓的博客

怕什么真理无穷,
进一寸有一寸的欢喜。

0%

为什么要进行数据库版本控制?

假设我们有一个名为 Shiny 的项目,其主要交付项目是一个名为 Shiny Soft 的软件,该软件连接到名为 Shiny DB 的数据库。
最简单的图可能看起来像这样:
img

阅读全文 »

引言

用 swagger2 来生成接口文档,让我们脱离了传统的手写文档的模式,它可以轻松的整合到 Spring Boot 中,用很少的代码就能生成一份漂亮的文档,同时让维护文档和修改代码整合为一体,可以让我们在修改代码逻辑的同时同步维护接口文档。另外 Swagger2 也提供了强大的页面测试功能来调试每个 RESTful API。具体效果如下图所示:

swagger

阅读全文 »

在 Web 开发中,静态资源的访问是必不可少的,如:图片、JS、CSS 等资源的访问。
Spring Boot 对静态资源访问提供了很好的支持,基本使用默认配置就能满足开发需求。

默认静态资源映射

Spring Boot 默认将 /** 所有访问映射到静态资源目录。

  • Spring Boot 提供默认静态资源目录位置需置于 classpath 下,目录名需符合如下规则:
1
2
3
4
/static
/public
/resources
/META-INF/resources

举例:我们可以在 src/main/resources/ 目录下创建目录 static,在该位置创建一个 demo.txt 文件,内容为 Hello world 。启动程序后,尝试访问 http://localhost:8080/demo.txt 。如能显示 Hello world,则配置成功。

阅读全文 »

在 Linux 系统上,打开终端,一般默认的颜色是黑白。这样颜色比较单调,有时我们需要在终端上打印出一些提示语,需要使用不同的颜色,那怎么设置终端输出内容的颜色呢?本文将详细讲解

颜色控制原理 ANSI 转义序列

ANSI 转义序列是一种带内信号的转义序列标准,用于控制视频文本终端上的光标位置、颜色和其他选项。在文本中嵌入确定的字节序列,大部分以 ESC 转义字符[字符开始,终端会把这些字节序列解释为相应的指令,而不是普通的字符编码。

终端颜色就是 ANSI 转义序列应用中的一个。

阅读全文 »

常用 Maven 插件介绍

我们都知道 Maven 本质上是一个插件框架,它的核心并不执行任何具体的构建任务,所有 这些任务都交给插件来完成,例如编译源代码是由 maven- compiler-plugin 完成的。进一步说,每个任务对应了一个插件目标(goal),每个插件会有一个或者多个目标,例如 maven- compiler-plugin 的 compile 目标用来编译位于src/main/java/目录下的主源码,testCompile 目标用来编译位于src/test/java/目录下的测试源码。

用户可以通过两种方式调用 Maven 插件目标。第一种方式是将插件目标与生命周期阶段(lifecycle phase)绑定,这样用户在命令行只是输入生命周期阶段而已,例如 Maven 默认将 maven-compiler-plugin 的 compile 目标与 compile 生命周期阶段绑定,因此命令 mvn compile 实际上是先定位到 compile 这一生命周期阶段,然后再根据绑定关系调用 maven-compiler-plugin 的 compile 目标。第二种方式是直接在命令行指定要执行的插件目标,例如 mvn archetype:generate 就表示调用 maven-archetype-plugin 的 generate 目标,这种带冒号的调用方式与生命周期无关。

阅读全文 »

轻量级锁的加锁过程

(1)在代码进入同步块的时候,如果同步对象锁状态为无锁状态(锁标志位为“01”状态,是否为偏向锁为“0”),虚拟机首先将在当前线程的栈帧中建立一个名为锁记录(Lock Record)的空间,用于存储锁对象目前的Mark Word的拷贝,官方称之为 Displaced Mark Word。这时候线程堆栈与对象头的状态如图2.1所示。
(2)拷贝对象头中的Mark Word复制到锁记录中。
(3)拷贝成功后,虚拟机将使用CAS操作尝试将对象的Mark Word更新为指向Lock Record的指针,并将Lock record里的owner指针指向object mark word。如果更新成功,则执行步骤(4),否则执行步骤(5)。
(4)如果这个更新动作成功了,那么这个线程就拥有了该对象的锁,并且对象Mark Word的锁标志位设置为“00”,即表示此对象处于轻量级锁定状态,这时候线程堆栈与对象头的状态如图2.2所示。
(5)如果这个更新操作失败了,虚拟机首先会检查对象的Mark Word是否指向当前线程的栈帧,如果是就说明当前线程已经拥有了这个对象的锁,那就可以直接进入同步块继续执行。否则说明多个线程竞争锁,轻量级锁就要膨胀为重量级锁,锁标志的状态值变为“10”,Mark Word中存储的就是指向重量级锁(互斥量)的指针,后面等待锁的线程也要进入阻塞状态。 而当前线程便尝试使用自旋来获取锁,自旋就是为了不让线程阻塞,而采用循环去获取锁的过程。

阅读全文 »

Hotspot 虚拟机中,对象在内存中的布局分为三块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding);

1564927152784

从上面的这张图里面可以看出,对象在内存中的结构主要包含以下几个部分:

  • Mark Word(标记字段):对象的Mark Word部分占4个字节,其内容是一系列的标记位,比如轻量级锁的标记位,偏向锁标记位等等。
  • Klass Pointer(Class对象指针):Class对象指针的大小也是4个字节,其指向的位置是对象对应的Class对象(其对应的元数据对象)的内存地址
  • 对象实际数据:这里面包括了对象的所有成员变量,其大小由各个成员变量的大小决定,比如:byte和boolean是1个字节,short和char是2个字节,int和float是4个字节,long和double是8个字节,reference是4个字节
  • 对齐:最后一部分是对齐填充的字节,按8个字节填充。
阅读全文 »