Spring boot中使用Redis
引入依赖
1 | <dependency> |
参数配置
1 | # REDIS (RedisProperties) |
访问测试
1 | @RunWith(SpringJUnit4ClassRunner.class) |
沉心、静气、学习、总结、进步
1 | <dependency> |
1 | # REDIS (RedisProperties) |
1 | @RunWith(SpringJUnit4ClassRunner.class) |
Swagger2用于解决前后端开发人员之间的api对接,减少与其他团队开发期间的沟通成本。Swagger2可以轻松的整合到Spring boot中,并与SpringMVC程序配合组织处强大的Restful API文档。即可以减少我们创建文档的工作量,同时说明内容整合到实现代码中,让维护文档和修改代码整合为一体,可以让我们在修改代码逻辑的同时方便的修改文档说明。
另外,Swagger2也提供了强大的页面测试功能来调试每个Restful API
1 | <dependency> |
在这里引入了pagehelper
,pagehelper
是MyBatis的分页插件,通过几行简单的代码就是实现分页功能;在与Spring boot整合的时候,只要整合了pagehelper
就自动整合了MyBatis。
1 | <dependencies> |
在application.yml
中添加数据源配置和MyBatis的mapper.xml的路径配置。
1 | server: |
主要是修改数据库连接配置,MyBatis generator生成的model、mapper接口、mapper.xml文件的路径。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<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<properties resource="generator.properties"/>
<context id="MySqlContext" targetRuntime="MyBatis3" defaultModelType="flat">
<property name="beginningDelimiter" value="`"/>
<property name="endingDelimiter" value="`"/>
<property name="javaFileEncoding" value="UTF-8"/>
<!-- 为模型生成序列化方法-->
<plugin type="org.mybatis.generator.plugins.SerializablePlugin"/>
<!-- 为生成的Java模型创建一个toString方法 -->
<plugin type="org.mybatis.generator.plugins.ToStringPlugin"/>
<!-- 数据库资源配置 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://127.0.0.1:13307/spring"
userId="hoo"
password="hoo">
<!--解决mysql驱动升级到8.0后不生成指定数据库代码的问题-->
<property name="nullCatalogMeansCurrent" value="true" />
</jdbcConnection>
<!-- 生成的model放置路径 -->
<javaModelGenerator targetPackage="com.hoo.springboot.mbg.model" targetProject="./src/main/java"/>
<!-- 生成的mapper接口放置路径 -->
<sqlMapGenerator targetPackage="com.hoo.springboot.mbg.mapper" targetProject="./src/main/resources"/>
<!-- 生成的mapper配置文件放置路径 -->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.hoo.springboot.mbg.mapper"
targetProject="./src/main/java"/>
<!--生成全部表tableName设为%-->
<table tableName="%">
<generatedKey column="id" sqlStatement="MySql" identity="true"/>
</table>
</context>
</generatorConfiguration>
1 | public class Generator { |
类的加载是指将类的.class
文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区,然后在Java堆中创建一个java.lang.Class对象(类也是对象),用来封装类在方法区内的数据结构。
类加载的最终产物是位于堆中的Class对象,该Class对象封装了类在方法区内的数据结构,并且向开发者提供了访问方法区内的数据结构的接口。
类加载器不需要等到某个类被“首次主动使用”时再加载,JVM规范允许类加载器在预料某个类将要被使用的时候就预先加载,如果在预先加载的过程中遇到了.class
文件缺失或存在错误,类加载器必须在程序首次主动使用该类时才报告错误,如果这个类一直没有被程序主动使用,那么类加载器就不会报告错误。
类的生命周期主要包含加载
、验证
、准备
、解析
、初始化
、使用
、卸载
。
在加载过程中的五个阶段中,加载
、验证
、准备
、初始化
发生的顺序是一定的,而解析
在某些情况下可以在初始化
阶段之后执行。这是为了支持Java语言的运行时绑定。
另外需要注意的是:这几个阶段是按照顺序开始,而不是按照顺序进行或完成,因为这些阶段通常是相互交叉混合进行的,通常在一个阶段执行的过程中需要调用或激活另一个阶段。
事实上,在使用Collections.sort(list)
的时候,就调用list.sort()1
2
3public static <T extends Comparable<? super T>> void sort(List<T> list) {
list.sort(null);
}
我们在深入进去后,发现其实调用的就是Array.sort()1
2
3
4
5
6
7
8
9
10@SuppressWarnings({"unchecked", "rawtypes"})
default void sort(Comparator<? super E> c) {
Object[] a = this.toArray();
Arrays.sort(a, (Comparator) c);
ListIterator<E> i = this.listIterator();
for (Object e : a) {
i.next();
i.set((E) e);
}
}
而在Array.sort中,会根据该对象是否能够通过归并排序来选择不同的排序方式。1
2
3
4
5
6
7
8
9
10public static <T> void sort(T[] a, Comparator<? super T> c) {
if (c == null) {
sort(a);
} else {
if (LegacyMergeSort.userRequested)
legacyMergeSort(a, c);
else
TimSort.sort(a, 0, a.length, c, null, 0, 0);
}
}
TimSort 算法为了减少对升序部分的回溯和对降序部分的性能倒退,将输入按其升序和降序特点进行了分区。排序的输入的单位不是一个个单独的数字,而是一个个的块-分区。其中每一个分区叫一个run。针对这些 run 序列,每次拿一个 run 出来按规则进行合并。每次合并会将两个 run合并成一个 run。合并的结果保存到栈中。合并直到消耗掉所有的 run,这时将栈上剩余的 run合并到只剩一个 run 为止。这时这个仅剩的 run 便是排好序的结果。
线程池:可以根据字面意思简单的理解,一个管理线程的池子。
1 | public ThreadPoolExecutor(int corePoolSize, |
昨天,在跟同学&同事谈人生谈理想的时候。他告诉我他学长面试头条,其中一道题是如何判断一个整数在不在40亿整数集中;他说他学长竟然不知道bitmap
(原题链接)!!!然后我又给他科普了一下布隆过滤器
和布谷鸟过滤器
。
所以借此文章来记录一下这些知识,并巩固一下。
Bitmap,直译就叫位图。可以理解为通过一个bit数组存储特定数据的一种数据结构;由于bit是数据的最小单位,所以这种数据结构往往是非常节省存储空间的。在Java和Redis中都存在同名实现结构。
在一个记录只有两种状态,是或不是的场景下,如果使用其他数据结构存储则会存在大量空间空间的浪费。即使存在海量的数据,我们也只需要为每个数据分配1byte
的空间就可以记录了。比如:用户画像
Bitmap可以节省大量的存储空间,所以可以很容易的倍一次性加载到内存中。Bitmap结构还有一个很重要的特点:可以很方便的进行位运算
比如我们需要统计用户满足以下条件的用户:程序员、带眼镜、长头发。。。。那么我们可以将对相应条件的用户画像的Bitmap
结构做AND
操作,就可以方便的过滤出满足条件的对象了。
随着JDK版本的快速迭代,作为优秀(kubi)的Java拥护者,为了跟随时代的潮流,也开始使用1.8版本。
但是,某一天。。。。苦逼的事情发生了,一个项目原本是好好的,突然报错起不来了。最终查到的原因是某个项目的Jar包使用的JDK为1.7….于是就有了这篇记录。
在终端下面使用java -version
查看就可以查看使用的JDK版本了。
使用/usr/libexec/java_home -V
可以查看本地已经安装的JDK
关于JDK1.x for mac的安装略过,网上有大把的教程。
我这里以安装3个版本1.6/1.7/1.8为例。
一、编辑.bash_profilevim ~/.bash_profile
二、在.bash_profile中添加下面的内容:1
2
3
4
5
6
7
8
9
10
11export JAVA_6_HOME=`/usr/libexec/java_home -v 1.6`
export JAVA_7_HOME=`/usr/libexec/java_home -v 1.7`
export JAVA_8_HOME=`/usr/libexec/java_home -v 1.8`
#默认设为JDK1.7
export JAVA_HOME=$JAVA_7_HOME
#alias命令动态切换JDK版本
alias jdk6="export JAVA_HOME=$JAVA_6_HOME"
alias jdk7="export JAVA_HOME=$JAVA_7_HOME"
alias jdk8="export JAVA_HOME=$JAVA_8_HOME"
三、刷新环境source ~/.bash_profile
四、测试
执行:jdk8
,再执行java -version
,看看是不是1.8版本?
执行:jdk6
,再执行java -version
,看看是不是1.6版本?
Cloneable接口是Java开发中常用的一个接口,它的作用是使一个类的实例能够将自身拷贝到另一个新的实例当中。
在开发过程中,如果一个类中的字段比较多,而我们如果采用在客户端中逐字段复制的方法来进行拷贝操作的话,将不可避免的造成客户端代码繁杂,而且也无法对类中的私有对象进行复制,而如果让需要具备拷贝功能的类实现Cloneable
接口,并重写clone()
方法的方式来简洁地实现实例拷贝功能。
private class Demo implements Cloneable{}
我们创建一个Demo类,并让他实现Cloneable接口。1
2public interface Cloneable {
}
然后我们发现Cloneable
几口里面并没有定义任何接口方法。
这是因为在Object
类中已经将clone()
方法定义为所有类都应该具有的基本功能,只是将该方法声明为了protected
类型。它是一个native
本地方法。
如果一个类不实现该接口就直接调用clone()
方法的话,就会抛出“不支持拷贝”异常。
所以如果要让一个类具有拷贝实例的功能,那么除了要重写Object
类中clone()
方法外,还必须实现Cloneable接口。
定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
这种方式在类加载时就完成了初始化,所以类加载比较慢,但是获取对象的速度快。这种方式基于类加载机制避免了多线程的同步问题。1
2
3
4
5
6
7
8public class Singleton {
private static Singleton singleton = new Singleton();
private Singleton(){}
public static Singleton getSingleton() {
return singleton;
}
}
懒汉模式声明了一个静态对象,在用户第一次调用时进行初始化,虽然节约了资源,但第一次加载时需要实例化,反应稍微慢一点,而且在多线程下不能工作。1
2
3
4
5
6
7
8
9
10
11
12
13public class Singleton{
private static Singleton singleton;
public Singleton() {
}
public static Singleton getSingleton() {
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}