暂时未有相关云产品技术能力~
暂无个人介绍
1.环境和依赖 1.1.spring boot版本 springboot 2.2.X版本采用的maven构建,2.3.X采用gradle构建,因此采用2.2.X,mavan构建的便于源码阅读。本文以2.2.9为例进行Spring Boot自动装配原理的解析。 1.2.依赖管理 引入Spring Boot的方式有两种 引入spring-boot-dependencies的pom文件 将spring-boot-starter-parent作为父级pom
1.下载安装 下载地址: Download | SonarQube | Sonar (下载页面向下拉)选择稳定版本下载。
1.准备国际化文件 建三个配置文件 第一个负责显示初始化的值 第二个映射第一种语言 第二个映射第二种语言 建好三个properties后IDEA会自动识别放到一个bundle下
1.概述 缓存穿透: 当查询的数据在缓存(redis)中没有时,一般业务上就会去查询数据存储(数据库),这种情况称为缓存穿透。穿透的数量太大会造成数据存储撑不住(数据库)而宕机。 解决思路: 用一个结构来记录哪些数据是存在于缓存中的。但这个结构不能太长,要是把所有缓存中的数据都 单独记一条在某个结构中,那就相当于又造了个缓存,完全失去意义。 目前常用的方案是布隆过滤器或者布谷鸟过滤器来解决缓存穿透问题。
1.概述 结构化方法是世界上第一个软件开发方法学,用来指导从需求分析、到设计开发各个阶段该怎么样做,采用什么样的方法,产出什么样的结果,从而保证整个软件开发周期可控。
本文只讲解通过插件来自动部署项目,Jenkins的安装可以看博主的另一篇文章,绝对保姆级,简洁丝滑的安装教程: jenkins下载安装__BugMan的博客-CSDN博客 1.安装插件 目前业内常用的解决方法是使用publish ssh插件将Jenkins上构建好的项目后发布到远端服务器。
1.下载安装 安装清单: JDK 1.8 Maven 3.6.3 git Jenkins 2.334 环境: centos 7 Jenkins是JAVA编写的,需要JDK环境,构建maven项目时需要maven环境,拉取代码时需要git环境,所以需要顺序安装好JDK、maven,git缺一不可。
造成重复消费的原因: MQ向消费者推送message,消费者向MQ返回ack,告知所推送的消息消费成功。但是由于网络波动等原因,可能造成消费者向MQ返回的ack丢失。MQ长时间(一分钟)收不到ack,于是会向消费者再次推送该条message,这样就造成了重复消费。
1.概述 1.1.数据丢失的原因 在消息中有三种可能性造成数据丢失: 消费者消费消息失败 生产者生产消息失败 MQ数据丢失 消费者消费消息失败:
依赖、配置 依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency>
1.概述 mock,一种JAVA单元测试技术,mock允许使用模拟对象替换测试中的系统部件,并断言它们是如何被使用的一项技术。 当某个接口或者功能模块依赖于其他接口或者模块,而所依赖的模块或接口未开发完毕,可以使用mock模拟依赖的模块。 mockito,JAVA单元测试中使用频率最高的mock框架之一。 mock遵循流程:输入—期望—验证
1.安装依赖 yum -y install gcc pcre-devel zlib-devel openssl opensll-devel 2.下载安装包 下载地址: https://nginx.org/download/ 使用wget进行下载: wget https://nginx.org/download/nginx-1.16.1.tar.gz 具体版本可以去网页自行选择 如果没有wget命令,安装一下:
1.概述 概念: redis集群是从3.0版本开始支持的一个功能,是redis的一种水平扩展方式,将全局数据分散的存储在N个结点上,从而来将请求流量打散到各个结点上,减轻单结点压力。 实现原理: redis的集群进行数据散列时使用了一致性hash算法的思想,如果对一致性hash算法有兴趣可以参照博主的另一篇文章:
redis的主从关系通过在从结点上使用slaveof [ip] [port]进行配置,同样在从节点上也可以使用该命令来解除主从关系,即从节点重新认主,将自己认做主节点: slaveof 127.0.0.1 6379 重新认主后要重新启动,不然从结点仍然会认为自己是从结点:
1.业务场景 假设有30000张图片需要存放到编号为1、2、3的3台服务器上。
1.概述 当面临大流量时,redis可以采取集群的方式进行扩容,将压力分散到集群中的多个结点上去防止redis被打挂。redis的扩容方式有两种: 垂直扩容,即读写分离。 水平扩容,即分区。 读写分离,将写请求和读请求分开来处理,写请求打到主结点上去,读请求打到从结点上去,主节点、从节点之间通过复制的方式进行数据同步。 因为从节点中存放有全局数据,所以可以通过负载均衡的方式将读请求的流量打散,将压力分摊给各个从节点。在面对读多写少的大流量情景时,使用读写分离集群是很好的解决方式。
1.概述 大key: 含有较大数据或含有大量成员的Key称之为大Key,常见的大key如: String类型的Key值大于10kb list、set、zset、hash的成员个数超过5000 list、set、zset、hash的成员数量虽然只有1000个但这些成员的value总大小为100MB(成员体积过大)
1.下载 下载地址:Index of /releases/ 2.解压 tar -zxvf 压缩包名 3.编译 因为redis使用c语言编写的,所以需要c语言环境来编译,所以首先要安装gcc和gcc-c++ yum install -y gcc g++ gcc-c++ 安装完gcc和gcc-c++后,进入解压出来的redis目录,使用make命令进行编译,编译成功会显示如下结果:
1.JAVA的发展史 JAVA语言于1995年面世,主要开发者为——James Gosline,后被称为JAVA语言之父。最早该语言叫Oak,在注册商标时,发现Oak已经被人使用,由于开发小组的成员当时在喝一款叫做JAVA的咖啡,于是将该语言命名为Java。至今JAVA的图标还是一杯咖啡。
13.1.概述 最小生成树,包含图的所有顶点的一棵树,树的边采用包含在图中的原有边中权重和最小的边。翻译成人话就是遍历一遍全图所有顶点的最短路径,这条路径就叫最小生成树。 最小生成树存在和图是连通图互为充要条件,顶点都不连通,肯定不可能有路能遍历一遍全图。 求解最小生成树有两种常用算法:
12.1.概述 12.1.1.无权图的最短路径 无权图的最短路径,即最少步数,使用BFS+贪心算法来求解最短路径,比较好实现,此处不做展开讨论。
11.1.图的遍历 图的遍历,即将图内所有顶点都访问一遍。 有两种遍历方式: BFS DFS 以下图的遍历为例:
10.1.概念 定义: 图,用来表示多对多的关系,比如地图里城市之间的通路、比如人际关系。 图由顶点和边组成,顶点是图里的每个结点,边是顶点之间的通路,可以一条边都没有,但是不能一个顶点都没有。
9.1.概述 概念: 根节点是自己所在子树中的最值的完全二叉树。 根节点是所在子树的最大值,称为大顶堆。 根节点是所在子树的最小值,称为小顶堆。 堆的任何子树的根节点到子树上的任意节点,路径上的节点都是有序的,大顶堆为降序,小顶堆为升序。 此处展示一个大顶堆:
8.1.B树 8.1.1.概述 B树存在的意义: 二叉树在存储数据时可能出现向一边倾斜导致查询效率降低的情况,为了防止二叉树的倾斜,出现了平衡二叉树,通过旋转的方式保证二叉树的平衡。但是就算是保持绝对的平衡,在面对要存储的数量量级够大的时候也会出现树的高度整体偏高的问题,树的高度过高,即使是使用了二分查找,依然会出现查找效率变低的情况。尤其是磁盘查找数据本身是个机械完成的动作,这一动作本身就十分耗时。因此需要一种能进行二分查找缩短查找时间,能存储大量数据后树高也不会过高的树形结构,这就是B树。
7.1.概述 平衡二叉树是要求任意结点的左右子树高度差不超过1,因此在AVL中用旋转来保证树的绝对平衡,但是这些旋转操作步骤繁多很耗时间,所以在面对经常会有数据插入的场景时,AVL不是一个性能优秀的选择。这时候反过来思考一个问题,旋转是为了保证树的绝对平衡,但是树的绝对平衡是必须的吗?显然不是,树的高度差只要不是太高从而退化成斜二叉树其实就能接受。
6.1.概述 二叉搜索树存在一个问题,就是树的姿态和数据的插入顺序是有关系的,有时候树会变成某一边的子树高度过高,甚至直接退化成斜二叉树,使得查找从二分查找跌落为顺序查找:
5.1.概述 二叉搜索树,也叫二叉查找树、二叉排序树,顾名思义,这种二叉树是专门用来进行数据查找的二叉树。二叉搜索树的查找其实就是二分查找。 二叉搜索树的定义: 二叉搜索树可以为空 如果二叉搜索树不为空,那么每个有孩子结点的结点,其左孩子的值一定要小于它,其右孩子的值一定要大于它。
4.1.树 树,由n(n≥0)个有限节点和边组成一个具有层次关系的数据结构。树需要满足以下条件: 任何结点的子节点不相交。 任何子结点只有一个父节点。 N个结点,N-1条边。 对于一个非空树(结点数≥0),具有以下性质: 起始结点称为“根” 除根结点外可分为m个互不相交的有限集合,其中每个集合本身也是一棵树,称为原来这棵树的“子树”。
3.1.顺序查找 顺序查找,时间复杂度是O(n),逻辑很简单,就是依次遍历一个线性的数据结构判断所要查找的目标数据是否在这个数据结构里。以下是代码实现:
2.1.概述 算法的基本定义: 求解问题的一系列计算或者操作。 衡量算法性能的指标: 时间复杂性 空间复杂性
1.1.线性表 线性表是指由同种元素构成的有序且线性的一种数据结构,由于其有序且线性的特点,可以抽象出对其的一个操作集:
5.1.概述 讨论内存管理之前,首先要搞清楚内存中到底存放的是什么东西?内存中存放的是进程,内存中各个进程圈地而治,所圈的地盘中存放各个进程自己的指令和数据,进程执行完毕后,退出内存,还出圈给它的地。如何给各个进程圈地,就是存储管理的核心。 计算机的存储技术可以从两个维度来分类: 连续还是离散? 简单还是虚拟? 连续还是离散: 连续存储技术,程序一定是被连续存储的。离散存储技术,程序可能是被离散(分散)存储的。
4.1.进程通信 4.1.1.概述 在一个进程调用另一个进程时,进程间需要进行通信。在管理进程时,需要与进程进行通信。 4.1.2.管道通信 Windows采用匿名管道技术进行进程间通信。匿名管道通信只支持具有亲缘关系的进程之间通信(父进程、子进程、兄弟进程)。管道是单向的,由写的一方建立,一头写一头读,若要双向通信,需要两条管道。Windows并不是只支持父子进程之间通信,因为Windows并不是只使用了匿名管道技术来支撑底层间进程的通信。
3.1.概述 数据不一致问题: 程序的并发执行会造成数据一致问题: 假设程序A去内存中读取了一个数据i,将这个数据改为i=100,在程序A的打印语句执行之前,程序B去读取了i并将这个数据改为了i=200,那么就会出现程序A期望打印的时候数据i是100,但实际上打印出来是1=200。这就是程序并发,造作内存中的共享变量带来的数据不一致的问题。
2.1.概述 2.2.CPU的管理 CPU本质上就是一个去内存中根据地址取指令,然后执行指令的硬件。CPU的完整取址执行流程如下: CPU要执行的指令的地址存在寄存器中,指令存放在内存中。 例如PC寄存器中存放50,CPU读到存放的50,发出一条取址指令,经由地址总线去取出地址为50的内存单元中的指令。最后CPU解释执行该指令,CPU工作的过程就是不断的取址执行。
1.1.定义 如果我们直接将计算机的硬件组装在一起后就拿来使用,至少会有以下几大问题: 不友好 不安全 效率低 不友好: 硬件操作是十分复杂的,如果对计算机的操作都是直面硬件,对于操作者(用户或者应用软件)而言将会十分不友好。
1.图灵机 1936年英国数学家图灵根据人在现实生活中进行数学运算的过程抽象出了图灵机的模型。 现实生活中人去计算需要:大脑、草稿纸、笔, 大脑去草稿纸上读数然后运行大脑中的运算逻辑,将得出的结果写回草稿纸。 例如: 计算3+2,那么草稿纸上写的内容就应该是——3 2 +(计算机里的特色,为了更好的辨别运算符的优先级,采用了后缀表达式)
4.1.概述 IO,input output的缩写,即计算机的输入输出系统。这里我们要明确输入输出的边界是哪里。向主机内部送称为输入,向主机外部送称为输出,直白且笼统的来说的话向磁盘或者网络里送称为输出,向内存里送称为输入。 整个IO的发展经历了以下几个阶段:
3.1.概述 3.1.1.定义 存储器,用于存储数据和程序。存储器中,以二进制的方式存储数据和程序,存储器由N个存储单元构成,存储单元由N个存储电路组成,这N个存储电路用来保存一个N位二进制数。每个存储单元的编号称为==地址==,存储器中能存放的数据的总位数(byte)称为存储容量,常用单位,KB、MB、GB…..
2.1.概述 总线,连接多个部件的信息传输线,是各个部件共享的传输介质。当多个部件与总线相连时,在某一时刻,只允许有一个部件向总线发送消息,而多个部件可以同时从总线上接收相同的信息。 总线一共有三种: 数据总线 传输数据信息 地址总线 传输数据总线上传输的数据在内存中的地址 控制总线 传输控制信号,如中断信号、复位信号、就绪信号等。
1.1.定义 计算机,一种可以存储程序,并且通过执行程序指令,可以自动、高速、精确地对数字信息进行各种复杂处理,然后输出运算结果的电子设备。1.2.发展史 1944年,“冯诺依曼”加入美国军方一个名叫“ENIAC”的计算机研制项目,1945年他提出了一个名叫“存储程序通用电子计算机”的方案——“EDVAC”。该方案中定义了计算机的工作方式以及几大组成部分,后来将该方案中提出的这一套对于计算机的整体架构称为——“冯诺依曼体系”。 1946年参照冯诺依曼体系,在宾夕法尼亚大学诞生了世界上第一台计算机。如今世界上的计算机都是参照冯诺依曼体系进行的实现。
.跨域的概念 跨域问题是源自“同源策略”,“同源策略”是一种约定,本质上是限制一个域的JavaScript脚本和另一个域内的内容进行交互。 “同源策略”是保证浏览器安全的一种核心机制,所有浏览器在实现上都必须实现该机制,否则该浏览器将会非常容易被攻击。所谓“同源”,即在一个域内,一个域由协议、主机、端口三部分组成,有任何一个部分不同,都不是一个域、一个源。
1.概述 RPC: RPC(Remote Procedure Call),一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议,RPC可以用HTTP协议实现,并且用HTTP是建立在 TCP 之上最广泛使用的 RPC,但是互联网公司往往用自己的私有协议,比如鹅厂的JCE协议,私有协议不具备通用性但是相比于HTTP协议,RPC采用二进制字节码传输,更加高效也更加安全。 用一个比较形象的例子来形容,你老婆出去打麻将,然后想起家里洗衣机里的衣服还没洗,于是打电话给在家里的你,叫你把洗衣机里的衣服洗了,这就是远程过程调用。微服务中服务的调用底层就是使用的RPC机制。
1.概述 JMM,JAVA多线程内存模型,JAVA中有两个内存模型,一个是JVM——JAVA虚拟机内存模型,一个是JMM——JAVA多线程内存模型,两者不是一个概念,需要严格区分。JMM的逻辑架构如下:
1.概念 程序 存储在磁盘上的一段指令的集合,是静态的。 进程 运行中的程序,指计算机在某个数据集合上的一次运行活动,每个进程都有独立的资源空间,是操作系统进行资源分配与调度的基本单位。 (数据集合包含两方便,一是数据,二是硬件资源,如CPU,IO等) 线程 又称轻量级进程,是为了提高资源利用率以及CPU的并发度,而对进程进行的一种优化。线程是进程中的一个个的实体,是进程的一个个的执行单元。同一进程的线程共享该进程的资源,即电脑所分配的资源空间。
1.定义 内部类,即将一个类定义在另一个类内部。 2.规定 2.1权限修饰符 外部类只能使用public、default修饰, 内部类可以使用private、public、protect、default,(即全部修饰符)修饰。
一个业务场景 假设我们要编写一个购买商品的程序,程序的内容很简单: 商品的库存数量存放在数据库中,每次完成库存数量-1。我们很快可以写出伪代码
堆污染是由于泛型的使用造成的一种潜在危险。 总结起来,堆污染就是因为使用泛型参数化类内部成员变量,同一类的不同实例对象内部里面成员变量的类型可能不同, 编译阶段无法发现,运行期间才能被发现的类型转换错误问题。 以下面一图说明泛型可能带来的堆污染问题:
概念 代理:代替处理,又称委托模式。 实现:为目标对象提供(包装)了一个代理,这个代理可以控制对目标对象的访问。外界不直接访问目标对象,而是访问代理对象,再由代理对象调用目标对象。