自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(40)
  • 收藏
  • 关注

原创 springboot项目利用redis脚本实现请求的限流

目的:限流 - 访问某请求的频次达到一定次数时,拒绝访问我们利用redis来记录频次,频次是value,key我们自定义,这里我们自定义考虑了两种场景,以Ip为key,或者,以请求的methodName为key,每次访问时,都以相同的key去redis中取value频次,当发现频次大于指定值时,抛出异常,拒绝执行后续逻辑。限流是针对请求的,也就是controller,所以我们采用aop包裹controller,这里以自定义注解的形式,标记controller作为pointCut。@Target(

2020-11-27 14:26:43 274

原创 前后端分离场景下SpringBoot接收前台传参的几种场景

前台请求的Content-Type对于POST类型的请求,服务端会根据请求头中的Content-Type值来获取请求中消息主体的编码方式,从而进行数据的解析。i. application/x-www-form-urlencoded原生Form表单默认的方式,提交的表单数据会转换为键值对并按照 key1=val1&key2=val2 的方式进行编码。jquery的post请求中默认也是这种"application/x-www-form-urlencoded;charset=utf-8"ii..

2020-10-19 18:18:45 689

原创 整理一下面试中遇到的技术问题

redis的数据类型共5种: string、hashset、list、set、zsetstring:字符串类型hashset: 一个string类型的field和value的映射表,注意一个key中可以包含多个field和value的映射。list: 字符串列表,有序集合set: 一个不可重复的无序集合zset:一个不可重复的有序集合,每个元素拥有double类型的评分,通过该评分实现排序。Java8的新特性1). 接口中新增了default和static方法,这两种方法可以有方法体。其.

2020-09-14 14:19:16 242

原创 面试中会被问到的Java8新特性

1). 接口中新增了default和static方法,这两种方法可以有方法体。其中default修饰的方法,接口实现类的子类可以调用或覆写,static修饰的方法不能,static修饰的方法只能被接口内部调用。如果一个接口实现类同时实现了两个接口且这两个接口中含有同名同参default方法,那这个实现类覆写该方法时,需要指明覆写的是哪个接口。public class TestImpl implements T1,T2{ @Override public void defaultFunc(){ T

2020-09-13 21:46:13 413

原创 springboot基于rabbitMQ削峰原理实现抢豆子小游戏

缘由rabbitMQ消息中间件的简单使用。基于削峰原理,设计一个抢豆子的小游戏,服务器中设有100颗豆子,所有用户均可进行抢夺,用户的请求被缓存放入消息队列中,豆子被抢光或游戏时间耗尽,游戏结束。效果图步骤1.下载安装并开启rabbitMQ2.springboot集成rabbitMQ并配置参数3.本例中以redis作为共享内存放置数据4.配置监听器,在程序开启后,初始化游戏信息(豆子数量、用户成绩、游戏状态)5.设置定时任务,每十分钟开启游戏,在第9分钟时,关闭游戏。6.编写生产者,即

2020-09-04 14:15:18 623

原创 springboot整合security及token验证

缘由添加security安全框架,去除session,使用token票据验证ps:token是指登录后向客户端发送一个票据,下次发起请求时,验证票据即可,票据中包含用户登录等信息,不需要session。步骤1.实现UserDetailsService接口,security的认证中会执行这个接口中的loadUserByUsername方法。2.自定义登录逻辑,调用security的authenticationManager对象执行登入验证,security的配置就完成了。3.在security中配

2020-09-01 16:58:19 6867 3

原创 springboot利用线程池异步记录日志(二)

缘由在业务逻辑中记录日志,繁琐且耦合度高,利用aop结合注解形式,更便捷步骤1.自定义【日志记录】注释2.自定义日志记录实体类3.利用aop,拦截被注释的方法,整理日志数据,插入数据库ps:原理很简单,跟着代码读一遍就ok了/** * 自定义日志记录注释* /@Target({ ElementType.PARAMETER, ElementType.METHOD })@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @inter

2020-09-01 12:49:29 848

原创 springboot利用线程池异步记录日志(一)

缘由记录日志录入数据库时,脱离主线程,实现异步插入,这样不会拖延主线程的执行时间ps:记录日志,可以写在业务逻辑中,也可以利用aop自动记录。 ... service{ public void login(){ // 登录逻辑 ...... // 记录日志插入数据库 // 这个记录过程是要占用当前线程时间的 // 通过异步线程执行,可以摆脱这种时间的消耗 logService.loginInfo(userInfo); } }步骤1.配置线程池2.自

2020-09-01 12:29:56 2552

原创 springboot配置多数据源(又名主从库的配置)

缘由单个库已无法满足需求,并且要求在代码中动态更改数据来源。代码运行时根据各自方法或类中的不同标识来自动判断使用哪个库获取数据。比如人员数据在a库获取、业绩数据在b库获取。步骤1.springboot集成mysql驱动、mybatis以及druid连接池2.填写多个库的配置数据,分别配置对应的数据源以及一个动态数据源。3.继承AbstractRoutingDataSource(每次访问mysql均会由它获取数据源),覆写获取数据源的方法。4.自定义一个注解,标记那些需要切换数据源的方法或类。

2020-09-01 01:02:58 1637

原创 springboot中针对表单重复提交问题的解决案例

言简意赅1.自定义一个annotion注解,标记那些想防止重复提交的方法。2.利用自定义的拦截器或者aop,拦截住刚刚标记的方法。3.获取redis中是否存在相同的请求,如果存在且时间间隔极短,此次视为重复性请求。4.方法末尾将本次请求信息保存到redis中,供做下次请求的判断依据。上代码// 自定义注解@Inherited@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @i

2020-08-30 15:37:24 598

原创 Vue+Springboot 自制规划打卡系统【明日计划】(一)

目录简介预览初衷设计思路代码逻辑技术栈注册相关注册用户密码修改邮件激活随机昵称生成器尾声简介预览自制的一套规划打卡系统,上效果图初衷首先讲讲我开发这套系统的初衷,想直接看代码的往下划在日复一日的上班工作中,我发现生活之余所剩的时间少之又少,而且剩下的这些时间又被大量的闲杂琐事与自身的慵懒占据,下班躺床上玩手机、追剧、看小说,时间眨眼就过去,回首望去,自己的生活抛去工作,似乎没有什么有意义的事物存在。然而工作并不是生活的全部啊。空心病这个词逐渐在身边浮现,毫无在意的事,刻苦的努力一瞬间变得毫无意

2020-08-24 17:20:05 1749

原创 final及其应用

final修饰类:该类不可被继承扩展修饰方法:该方法不可被重写修饰变量:当变量赋值后不可被修改final修饰的变量,如果值是"对象引用",那么不可改变的是这个引用,而不是引用指向的地址中存的值,比如数组final int[] a = [1,2,3];int[] b = [2,3,4];//这是会报错的,a的值是数组的地址,不能被修改a = b;//这是可以的,因为并没有改变a值(也就是数组的引用地址)a[0] = 32;immutable状态不可变模式指对象一旦初始化建立之后,其属

2020-07-20 14:44:04 228

原创 常见的异常类分析

Exception和Error都继承了Throwable。Error:正常情况不会出现,它会使程序变成非正常、不可恢复的状态,它是JVM侦测到的无法预期的错误。不可捕获,常见如:OutOfmemoryErrorException:它是可恢复的异常,它分为可检查异常和运行时异常,可检查异常(checked exception):需在代码中显式的捕获处理,如IO异常、SQL异常,JAVA编译器强制要求我们对这些异常进行处理。运行时异常 (RuntimeException):运行时异常我们可以处理、也可

2020-07-20 14:42:19 175

原创 多线程中的乐观锁、悲观锁

多线程中,共享变量存放于共享内存,各个线程会将其copy到自己的线程内存中,更改数据,最后把线程内存中的数据复制给共享内存。应用于多线程的乐观锁乐观的以为每次拿取数据时别人都不会更改数据,但在更新的时候也会以某种方法判断一下有没有人更新这个数据。乐观锁应用于多读少写的场景。判断有没有人更新数据有两种方法:版本号控制 和 CAS(compare and swap)比较和交换版本号控制比如,给数据加一个版本字段,凡线程对其进行数据更新后,版本号+1,当另一个线程对其更新时,会比对一下,共享内存中该数据

2020-07-20 14:37:03 1160

原创 List、Set、Queue集合框架

集合CollectionList类(允许元素重复)Vector 基于sychronize保障线程安全,底部实现为数组,在扩容时,自动增加1倍,需要arrayCopy。ArrayList 无线程安全限制,所以性能比Vector高,底部实现为数组,扩容时增加50%LinkList 基于链表实现,增、删效率高,查询效率低。//链表的结构private static class Node<E> { E item; Node<E> next; Node

2020-07-20 14:11:25 235

原创 String、StringBuffer、StringBuilder三者关系

String典型的状态不可改变(Immutable)类StringBuffer以synchronized保障了线程安全,这也导致性能开销的增大,除非有线程安全需求,不然不建议使用StringBuilder与StringBuffer类似,只是去掉了其中的线程安全,推荐使用事实上,StringBuffer、StringBuilder底层都是使用可修改数组实现的。初始构建时会分配一定长度n,当存储的值过长时,会自动扩容长度n,如果还不够,继续扩容长度n。注意:扩容的过程是抛弃原有数组,创建新数组,然后

2020-07-20 13:51:27 143

原创 四种引用类型分析

数据类型除了原始数据类型的变量,其他所有都是所谓的引用类型。不同的引用类型,主要体现的是对象不同的可达性状态和对垃圾收集的影响(其实就是GCRoot中的可达性分析)我们在创建各种引用并关联到响应对象时,可以选择是否需要关联引用队列。如果引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。强引用类型即常见的普通对象,有引用指向对象,对象即还活着,不会被GC当做垃圾,即使OOM了也不会把强引用视为垃圾。但,一旦引用超出作用域或显示=null,则允许被GC当做垃圾

2020-07-15 20:54:50 226

原创 动态类及其应用

运行时动态生成Java类程序启动后,根据代码逻辑,在执行代码过程中,动态生成字节码文件并以进行相应的类装载等。他与程序启动前,我们编写代码,生成.class,JVM装载类这个过程不同。动态生成意味着原本没有相应.class文件,是我们后来自己生成的.class,然后装载。JVM之所以能够这样是因为,凡是正确的、符合相应结构的字节码数据,都可以平滑的向JVM中转换(也就是被JVM加载),所以甚至是我们动态的手写字节码都是可以的。当然,动态生成JAVA类,我们通常是采用如cglib、ASM等类库来实现。

2020-07-15 17:57:56 868

原创 java的类加载分析

JAVA的类加载java文件经过JVM编译器编译成字节文件后,再经过类装载器装载到JVM内存的过程。类加载器的执行在预料某个类将要被使用时就预先加载它类加载过程分为三个阶段:加载、链接、初始化加载:读取类的字节流,在方法区(元数据区)存储,并,在堆中生成一个Class对象,作为方法区对应数据的入口。链接:包括jvm对数据的验证、准备(为静态变量、常量初始化赋值,对基础类型的变量赋予数据类型的默认值,比如int的0)、解析(将符号引用替换为直接引用)初始化:真正的初始化赋值,如果类未被加载和链接,

2020-07-15 14:06:32 131

原创 JVM的运行

JAVA的运行.java(源码) -> .class(字节码) -> 机器码 java文件 -> 通过JDK中的编译器生成字节码文件(.class),这部分可视为是独立的 -> 交由jvm运行以下所说的运行/执行,都是针对编译后的字节码文件来说的。 解释执行:将编译好的字节码一行一行地翻译为机器码执行。 编译执行:以方法为单位,将字节码一次性翻译为机器码后执行。 AOT编译==:JAVA9提供,运行前,将所有字节码直接编译为机器码。在解释执行模式下,执行字节码文件时

2020-07-15 13:43:28 128

原创 GC垃圾判断与回收

GC垃圾回收不会涉及到虚拟机栈的GC垃圾回收的几种基础算法先言-将内存空间比喻为一个excel表格,每个单元格为存储的数据。标记清除法:遍历,将非垃圾存储单元格进行标记,再将所有未标记的对象当做垃圾清除。这将带来内存碎片问题(因为存活对象的位置变得杂乱无章)复制:将excel表一份为二,只用其一,在进行垃圾清扫时,将存活对象放到另一个侧,从新排列。这样就解决了会出现内存碎片问题。标记整理法:前期同标记清除法一样去除垃圾,而后将存活对象向一端进行移动整理。GC是如何判断垃圾的判断对象是否为垃圾通

2020-07-15 13:41:43 204

原创 JVM内存结构剖析

JVM内存JVM内存分为两个区域,一个是以线程为单位,每个线程都有各自的(包括:虚拟机栈、本地方法栈、程序计数器),另一个是以jvm为单位,它是唯一的,相当于全局的(包括:方法区、堆)。程序计数器它记录JVM中执行的字节码指令的行号(即指令所在的地址),也就是JVM在解释执行我们编译后的字节码文件时边执行边做的标记。JVM的多线程是通过CPU时间片轮转算法来实现的,所以当切换执行到某个线程时,需要知道之前这个线程执行到哪里了,此时程序计数器就可以为其提供上次执行的地址。1.每个线程有各自的程序计数器

2020-07-14 14:09:37 166

原创 java入门级知识点回顾

jdk包含jre,jre包含jvm裸机安装操作系统,得到虚拟计算机虚拟计算机安装jdk,进而得到java虚拟机——jvmjvm本身不是跨平台的,java提供了不同操作系统下的jvm版本java文件经过java编译器处理成jvm能识别的字节码文件(.class),jvm会将字节码文件转化成对应操作系统的本地机器码,最终操作系统运行机器码。java内存主要4块:栈内存——stack:存放基本类型数据 和 对象名(引用,包括数组名)堆内存——heap:存放对象实体(包括数组的实体)数据区:静态变量

2020-05-30 16:19:21 178

原创 springboot入门——数据库事务的隔离级别及传播行为

事务处理Spring中,数据库事务是通过AOP技术来提供服务的声明式事务标注:@Transactionalpublic class UserServiceImpl im...{ ... @Override //一旦sql执行异常,事务自动回滚 @Transactional public int insertUser(User user){ return userDao.isertUser(user); } ...}@Transactional注解有很多可配置的参数,这里只讨论i

2020-05-11 13:53:14 679

原创 Springboot入门——初学者对AOP代码层实现原理的理解与@AspectJ的实际应用

原理(概念)AOP,面向切面编程,它是一种约定流程的编程方式。什么是切面呢?我们把在业务逻辑中一个对象的方法想象成就是一个切面,切面编程就是在这个方法的前前后后进行一些列的相关操作,比如在方法执行之前设置一个函数编写我们自定义的程序代码,或者在方法执行之后,或者在方法抛错后等等。初学者此时可能会提出问题,既然是在方法的前后编写自定义的程序,那直接写在方法前面或者后面不就可以了么?可以,但是!这样做大大增加了代码的耦合度。我们的目的,是在方法执行之时,以这个方法执行为触发点,自动的调用我们自定义的前前

2020-05-10 00:22:34 331

原创 Springboot入门——初学者对Spring Ioc技术的理解与运用,包含Bean生命周期

Spring IocSpring所依赖的两个核心理念:控制反转(Ioc)、面向切面编程(AOP)初学者可能不理解什么叫控制反转,那么我们来进一步描述一下Ioc。Ioc是一种通过描述来生成或获取对象的技术,这里的对象当然是指java对象。在Java中我们更多的是通过new关键字来创建对象,在Spring中,则是通过描述来创建对象。所以我们知道了,Ioc就是用来获取java对象的东西,“控制反转”这个词先往后放放。对象有了,我们就需要一个东西对这些对象进行存放、管理,用什么呢,没错,一个容器。Sp

2020-05-09 15:14:23 509

原创 Java入门——网络编程协议IP、TCP、HTTP(初学者需着重了解)

网络编程初学者应注意,我们搭建网站是为了进行网络通信的,那么java网络通信需要遵循什么协议呢。在此之前我们需要先了解一个名词——OSI模型,它是一种概念模型,国际标准化组织提出,一个试图使各种计算机在世界范围内互连为网络的标准框架。1.协议OSI七层网络模型(从下往上):物理层(从物理器件到局部局域网上传数据)数据链路层(主要负责网络寻址)网络层(决定数据的路径选择和转寄,将网络...

2020-05-07 23:55:35 1347

原创 Java入门——流

流x字节型字符型输入流InputStreamReader输出流OutputStreamWriter他们均作为抽象类,很多其他的流均由他们派生出来。输入流输入流的信息源可以位于文件、内存、或网络套接字socket等,类型可以为对象、字符、声音、图像等等,初学者可以将输入流类视为包裹在信息源的一层外衣,通过操作输入流类所带的方法,来从信息源中拿取数据。...

2020-05-07 19:29:24 150

原创 Java入门——面向对象、接口、集合

面向对象封装:隐藏细节继承:子类继承父类多态:final关键字:子类不能覆盖父类中final修饰的方法,会报语法错误,属性没事儿,final意为最终(即不可更改),属性没事儿应该是因为它被理解为是子类的属性,不是重写的父类。对象类型转化:强转容易出错,建议先 instanceof 判断类型,再强转。子类可以通过super调用父类中的属性或方法,也可以调用被覆盖重写的属性的原版值。...

2020-05-03 22:05:22 253

原创 Java入门——数据类型及常用方法

数据类型1.布尔型是占一个字节的(1btye=28bit)2.字符型(char)是占两个字节的数组初始化 int[] a = {2,4,56};//静态初始化 int[] d= new int[10];//初始值都以0补充 // 数字的,初始值是0 // 布尔的,初始值是false // 字符的,初始值是'\0' // 对象的,初始值是null数组常用方法这几个方法Arra...

2020-05-03 17:23:18 329

原创 MySQL入门——性能优化(结构篇)

性能优化(结构篇)字段繁多的表,可以考虑将其中使用频率低的字段,另建一张关联表存放数据。如果两张表关联查询较频繁,可以适当考虑增设中间表存储目标数据。毕竟关联查询消耗的资源要比单表查询多。在执行大量数据插入时,可以考虑先禁用掉索引和唯一性检查,插入完毕后再打开。因为每一条插入都会去维护索引数据做重新进行排序等操作。insert插入语句尽量写成如下形式,而不是语句上一条一条的插>...

2020-04-29 23:35:11 159

原创 MySQL入门——性能优化(索引篇)

性能优化(索引篇)数据库性能查询语句(了解即可)> show status like 'value' ; // 查询数据库的性能,value可以是如下值Connections:连接mysql服务器的次数uptime:服务器上线时间Slow_queries:慢查询次数Com_select:查询操作的次数Com_insert:插入操作的次数Com_delete:删除操作的次数...

2020-04-29 23:09:57 172

原创 MySQL入门——事务

事务事务是指逻辑上的一组操作(可以包含n条sql语句)如果初学者了解过springboot中的事务注解,请先忘掉那段,单独来看mysql中的这个事务。事务的流程如下:开启事务,BEGIN 或 START TRANSACTION 显式地开启一个事务,当然单条的时候默认是隐式开启提交事务,COMMIT对数据库进行的所有修改成为永久性的[回滚事务],如果sql执行出错会自动回滚事务,使数据...

2020-04-29 17:15:14 223

原创 MySQL入门——触发器与视图

触发器与视图触发器: 当指定的insert/update/delete事件发生后,触发执行自定义的sql操作。视图:基于已存在的基础表,自定义生成的一种虚拟的表。它相当于表的窗口,用户可以自定义设置透过该窗口所能看到的东西。作用有些类似于筛选。实际应用中无论是触发器还是视图,通常都是通过可视化视图工具来操作的,初学者无需硬记代码,大概了解即可。> // 触发器是基于insert/up...

2020-04-29 14:23:11 339

原创 MySQL入门——存储过程/函数

存储过程/函数存储过程/函数 是保存在mysql服务器中的一些sql语句的集合(当然其中也会包含一些变量声明、逻辑语句等)。注意它是在mysql服务器上的,这样一来,客户端与mysql服务端的交流中,无需具体sql的传递,仅仅一个存储过程名或函数名即可,sql语句是在mysql服务器内部读取的,会非常迅速。mysql的存储过程/函数与oracle的相差无几。初学者了解大概即可,注意下存储过...

2020-04-29 13:09:06 321

原创 MySQL入门——索引

索引索引可以优化mysql的数据检索速度。无索引的数据检索是进行的全文检索,即对整个库/表逐个数据进行的搜索,而设置索引后,数据库/表相当于拥有了一个目录,搜索时将会根据该目录,直接跳转到指定的位置进行搜索,进而使速度上提升了很多。mysql中常用的索引类型有:普通索引、唯一索引、全文索引、单列索引、多列索引、空间索引。主键与索引:主键的用途有两个,1是唯一地标识一行数据,2是作为一个可...

2020-04-29 12:20:31 163

原创 MySQL入门——常用语句、函数

语句初学者了解大部分语句即可,部分函数等了解即可,无需全部死记硬背。> CREATE DATABASE 数据库名; //创建数据库> SHOW DATABASES; //查看所有数据库> USE 数据库明; //设置当前使用的数据库,通常进入mysql后,需以此指定要操作的数据库 > DROP DATABASE 数据库名; //删除数据库(无法恢复)> C...

2020-04-29 01:28:19 197

原创 MySQL入门——四类运算符

运算符包括:算术运算符、比较运算符、逻辑运算符、位运算符初学者应注意在sql语句中运算符不仅仅可以存在于查询条件当中算术运算符加+、减-、乘*、除/、取余%比较运算符除了大于小于等于不等于一系列的,还包括运算符示例IS NULLid is nullIS NOT NULLBETWEEN ANDid between 1 and 5INid ...

2020-04-29 00:08:58 279

原创 MySQL入门——数据类型分析

MySQL的数据类型Mysql的数据类型主要分为三类: 数字型、字符串型、日期和时间类型需要学习者着重了解的是char与varchar的固定长度与可变长度的意义、int(M)所代表的意义数字型整型(部分):类型字节TINYINT1BOOL1SMALLINT2INT(也就是INTEGER)4BIGINT8浮点(部分):...

2020-04-29 00:04:37 172

原创 MySQL入门——存储引擎

目录存储引擎InnoDBMyISAMMEMORY存储引擎 存储引擎是数据库存储数据的某种技术(也可以说是存储数据所采用的一些特定的规则方式)。 不同存储引擎的存储机制、索引设定、锁定方式等都不相同,存储引擎决定了数据的存储方式。Mysql中存在多种存储引擎(默认使用的是InnoDb),你可以自定义你存储数据时需要采用的存储引擎。mysql> show engines;//查看数据...

2020-04-28 23:42:19 159

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除