浅谈Redis的结构和应用
前言Redis我想大家都很熟悉,Redis是Key-Value存储的,它是一个完全内存存储,当然Redis也可以进行持久化(RDB,AOF),持久化是在硬盘上的。Redis最常用是用Redis去做缓存,也可以做消息队列和数据库,内置Lua脚本引擎(分布式锁原子操作),当Redis内存使用完会使用默认LRU算法清除Key,同时还有Sentinel的高可用集群(HA)和Cluster集群实现分片存储和内存扩大(Hash一致性算法:扩容或者宕机后不会导存储发生变化即大量key由于Hash改变导致失效,Hash存储和之前保持一致)。
Redis常用的数据结构大家也都熟悉,Redis常用数据结构我想大家也都知道,除了最常用的String,List,Set,Hash,Zset;在Redis2.2版本引进BitMap,2.8版本引入HyperLogLog数据结构,3.2版本引入了存放地理信息的GEO数据结构和指令;5.0版本还引入Stream有点像抽象的日志数据结构,像日志文件一样,通常是以append only模式下打开的文件来实现的,不过这里我们久不涉及了。丰富了Redis的数据类型也增加Red ...
浅谈volatile
前言通过上一篇文章浅谈JMM,我们知道现代计算由于多级缓存和多CPU的问题,导致多线程下会出现可见性和竞争性的问题。Java为了解决这两个问题,使用了两个关键字一个是volatile解决可见性问题,一个是 synchronized 解决同步问题(synchronized也解决可见性的问题)。它们的具体实现都是由JMM定义的8种原子从去实现的,下面我们就了解一下JMM中的8种原子操作。
JMM中的8种原子操作之前的一篇文章由讲到,由于各个工作内存时隔离的,只有通过主内存才能实现Java进程中间数据的传输,所以就会出现可见性问题和竞争性问题。为了解决问题,JMM抽象出主内存和工作内存之间具体的协议(变量如何从主内存copy到工作内存,工作内存如何同步回主内存的实现细节)。Java 内存模型定义了8种操作,Java虚拟机实现时必须保证这8种操作时原子的,不可分割的(对于double和long这种在某些操作是由例外的);后面最新JSR-133已经把这8种操作简化成4种,但是原理没变我们后面在去解释。
lock(锁定):作用于主内存变量,它把一个变量标识为一条线程独占的状态。
unlock(解 ...
浅谈JMM
前言我们知道Java是一个跨平台的语言(毕竟一次编写处处异常不是白说的),我们知道Java在保证跨平台的时候使用了JVM来屏蔽了底层。同时它也有很多标准,这次我们就了解JMM(Java Memory Mode) Java内存模型。
JMM模型JVM内部使用的Java内存模型在线程堆栈和堆之间分配内存。从简单逻辑上就只有栈和队,但是实际上比这个复杂。
Java虚拟机中运行的每个线程都有其自己的线程堆栈。线程堆栈包含有关线程调用了哪些方法以达到当前执行点的信息。我将其称为“调用堆栈”。当线程执行其代码时,调用堆栈会更改。(程序计数器 Program Count Register)
线程堆栈还包含正在执行的每个方法(调用堆栈上的所有方法)的所有局部变量。线程只能访问自己的线程堆栈。由线程创建的局部变量对创建线程之外的所有其他线程不可见。即使两个线程执行的代码完全相同,这两个线程仍将在各自的线程堆栈中创建该代码的局部变量。因此,每个线程对每个局部变量都有其自己的版本。(虚拟机栈和本地方法栈)
基本类型的所有局部变量( boolean,byte,short,char,int,long, flo ...
MySQL索引浅谈
MySQL数据库相信大家都应该很熟悉。在目前大多数互联网公司都会首选MySQL做为自己业务相关的持久化储存,而在数据库中索引又是非常重要的一块内容,基本上所有的业务查询都是需要走到索引,如果数据量比较大,进行全表扫描(没有走到索引)会非常消耗系统IO和CPU导致,性能很低。所以知道熟悉数据库的索引是很重要的。
什么是索引索引(Index),是一本书籍的重要组成部分,它把书中的重要名词罗列出来,并给出它们相应的页码,方便读者快速查找该名词的定义和含义。传统意义上的索引,举个例子我们去根据偏旁部首去查询字的时候,那个对应字会给出对应额页码,而不是我们一页一页去找。那个记录字对应页数的那几页就是索引。(方便我们快速的定位位置)
MySQL的索引MySQL中的索引也叫键(key)是存储引擎用于快速查找记录的一种数据结构。MySQL中的存储引擎也是像书中索引一样,先找到索引对应的值,然后在根据匹配的索引记录找到对应的数据行。
索引类型在MySQL中常见两种索引类型,一种是Hash索引,一种是B-Tree索引。从名字中我们就能看出来两种索引的数据结构式不一样的,Hash索引存储结构的是一个Hash ...
自己动手写spring-boot-starter
写在前面的废话经常有人问我编程是一件很难的事情吗,我想说写程序其实不是一件很难的事情。你只不过是按照你自己的逻辑去写一些if-else、for-while循环,而且好多逻辑产品都会帮你梳理(有需求),你也不是凭空去写一些没有实际应用的功能。但是对于写程序,程序能跑起来有一个很重要的东西,就是跑程序的环境。
这个门槛一下子就提高了,Spring中有很多配置文件,就会让很多人折腾好久。最后发现可能就是一个配置项没有配置(某个配置项写的不对),这个可能这个坑有人踩过(你可以去Google一下),因为你要使用的好多组件都要接入Spring(组件中的对象变成Spring管理的Bean),但是要配置那些Bean是要你很熟悉这个组件,而且你要很了解Spring,知道为什么报错如何解决。为了解决这个spring-boot引入自动配置(这个之前有讲spring-factories中讲过)。这样Spring就可以通过别人之前配置好的Bean直接引入。省去你对环境的配置让你更专注业务的开发,而不是被环境搞的焦头烂额,而且也让Spring更容易使用,引入插件也更方便。(你可以搜SpringMVC和spring ...
HTTP协议浅谈
什么是HTTP协议HTTP协议我想大家应该都不陌生,在这个互联网高度发达的今天。如果你不知道什么是HTTP协议那就有点Out了。HTTP协议(Hypertext transfer protocol)翻译成中文叫超文本传输协议。(从名字上能看出来他传输的不仅仅是文本)。HTTP是互联网的数据通信的基础。
设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。通过HTTP或者HTTPS协议请求的资源由统一资源标识符(Uniform Resource Identifiers,URI)来标识。
HTTP协议是蒂姆·伯纳斯-李于1989年在欧洲核子研究组织发起的。真正第一Http协议版本是在1991年的发布的。HTTP协议已经走了20多年的经历。中间也有过好多版本的变化。
HTTP协议是应用层协议,他是基于TCP/IP协议去实现的,主要用户客户端和服务端的传递标准,默认端口是80。HTTP 是无连接无状态的协议。
HTTP/0.9版本HTTP 0.9版本是最老的HTTP版本。HTTP 0.9版本的协议简单到极点,请求时,不支持请求头,只支持 GET 方法。客户端与服务器端的交互方式是 ...
spring.factories与spring-boot
什么是spring.factoriesspring.factories是一个配置文件(spring的工厂),放到META-INF文件夹中。存放key-value关系的文件(key就是bean工厂的接口,下面的value就是对应的实现类)。主要用于Spring-Boot中扩展的问题。这个有点像Java SPI。spring.factories文件存放的是全类名,用于加载到Spring的Bean容器中。而不是通过外部声明注入。(Bean工厂实际就是生成Bean)
在spring-core的中SpringFactoriesLoader类去加载配置在spring.factories中的类(也就是之前定义好的装 好自定义Bean的类)。这个是spring-boot-autoconfigure的jar包中META-INF文件夹中spring.factories中的配置文件。这里面包含初始化(Initializers)的Bean Factory的key org.springframework.context.ApplicationContextInitializer;应用监听器(Applic ...