5.ConcurrentHashMap详解
ConcurrentHashMap跟HashMap,HashTable的对比 我们都知道HashMap不是线程安全的,所以在处理并发的时候会出现问题。
而HashTable虽然是线程安全的,但是是通过整个来加锁的方式,当一个线程在写操作的时候,另外的线程则不能进行读写。
而ConcurrentHashMap则可以支持并发的读写。跟1.7版本相比,1.8版本又有了很大的变化,已经抛弃了Segment的概念,虽然源码里面还保留了,也只是为了兼容性的考虑。
ConcurrentHashMap原理概览在ConcurrentHashMap中通过一个Node<K,V>[]数组来保存添加到map中的键值对,而在同一个数组位置是通过链表和红黑树的形式来保存的。但是这个数组只有在第一次添加元素的时候才会初始化,否则只是初始化一个ConcurrentHashMap对象的话,只是设定了一个sizeCtl变量,这个变量用来判断对象的一些状态和是否需要扩容,后面会详细解释。
第一次添加元素的时候,默认初期长度为16,当往map中继续添加元素的时候,通过hash值跟数组长度取与来决定放在数组的 ...
06.MySQL的主从复制
MySQL BinLogMySQL 的 Binlog 日志是一种二进制格式的日志,Binlog记录所有的DDL和DML语句(除了数据查询语句Select, show 等),以Event的形式记录,同时记录语句执行时间。
BInlog的 主要作用有两种:
数据恢复:
因为Binlog详细记录所有修改数据的SQL,当某一个时刻的数据误操作而导致出问题,或者数据库当局数据丢失,那么可以根据binlog回放历史数据
主从复制
想做多级备份的业务,可以去监听当前写库的Binlog日志,同步写库的所有更改
Binlog包括两类文件
二进制日志索引文件(.index):记录所有的二进制文件
二进制日志文件(.00000*):记录所有DDL和DML语句事件
Binlog日志功能默认是开启的,线上情况下的Binlog日志的增长速度是很快的,在MySQL配置文件my.cnf 中提供一些参数来对 Binlog 进行设置。
123456789101112131415161718设置此参数表示启用binlog功能,并制定二进制日志的存储目录log-bin=/home/mysql/binlog/#my ...
05.Spring-Bean(2)
Spring Bean的生命周期
初始化
BeanNameAware.setBeanName() 在创建此bean的bean工厂中设置bean的名称,在普通属性设置之后调用,在InitializinngBean.afterPropertiesSet()方法之前调用
BeanClassLoaderAware.setBeanClassLoader(): 在普通属性设置之后,InitializingBean.afterPropertiesSet()之前调用
BeanFactoryAware.setBeanFactory() : 回调提供了自己的bean实例工厂,在普通属性设置之后,在InitializingBean.afterPropertiesSet()或者自定义初始化方法之前调用
EnvironmentAware.setEnvironment(): 设置environment在组件使用时调用
EmbeddedValueResolverAware.setEmbeddedValueResolver(): 设置StringValueResolver 用来解决嵌入式的值域问题
ResourceL ...
05.Spring-IoC(2)
Spring IoCSpring IoC容器 作用控制反转即IoC(Inversion of Control),将传统上由程序代码直接控制的对象的调度权交给容器,通过容器来实现对象组件的装配和管理。所谓的”控制反转”概念就是对组件对象控制权的转移,从本身程序代码转到容器,Spring IOC 负责创建对象,管理对象(通过依赖注入(DI),装配对象,配置对象,并且管理这些对象的整个生命周期)。对于l0C来说,最重要的就是容器。容器管理着Bean的生命周期,控制着Bean的依赖注入。
控制反转(oC)有什么作用
管理对象的创建和依赖关系的维护:对象的创建并不是一件简单的事,在对象关系比较复杂时,如果依赖关系需要程序猿来维护的话,那是相当头疼的
解耦:由容器去维护具体的对象
托管了类的产生过程:比如我们需要在类的产生过程中做一些处理,最直接的例子就是代理,如果有容器程序可以把这部分处理交给容器,应用程序则无需去关心类是如何完成代理的
Spring loc的实现机制Spring中的loC的实现原理就是工厂模式加反射机制。
1234567891011121314151617181920212 ...
10.Java内存模型
Java内存模型(JMM)JVM内存模型指的是JVM的内存分区;而java内存模型是一种虚拟机规范
JMM就是Java内存模型(Java Mermory Model)。因为在不同的硬件生产商和不同的操作系统下,内存的访问有一定的差异,所以会造成相同的代码运行在不同的系统上会出现各种问题。所以Java内存模型(JMM)屏蔽掉各种硬件和和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的并发效果
Java内存模型规定所有的变量存储在主内存中,包括 实例变量,静态变量,但是不包括局部变量和方法参数,每个线程都有自己的工作内存,线程的工作内存保存了该线程用的到变量和主内存的副本拷贝,线程对变量的操作 都在工作内存中进行。线程不能直接读写主内存中的变量。
不同的线程之间也无法访问对方工作内存中的变量,线程之间变量值的传递均需要通过主内存来完成
每个线程的工作内存都是独立的,线程操作数据只能在工作内存中进行,然后刷会主存,这是JMM的线程基本工作方式
JMM定义了什么整个Java内存模型实际上是围绕着三个特征建立起来的。分别是:原子性(Atomicity),可见性(Visib ...
05.分布式锁
分布式锁什么是锁
在单线程的系统中,当存在多个线程可以同时改变某个变量(可变共享变量)时,就需要对变量或代码块做同步,使其在修改这种变量时能够线性执行消除并发修改变量
而同步的本质是通过锁实现的。为了实现多个线程在一个时刻同一代码块只能有一个线程可执行,那么需要在某个地方做个标记,这个必须每个线程都能看到,当标记不存在时可以设置该标记,其余后续线程发现已经有标记了则等待拥有标记的线程结束同步代码块取消标记后再去尝试设置标记。这个标记可以理解为锁。
不同地方实现锁的方式也不一样,只要能满足所有线程都能看到标记即可。如java中synchroniuze是 在对象头设置标记,Lock接口的实现类基本上都只是某一个volitile修饰的int型变量其保证每个线程都能拥有对该int的可见性和原子性修改,linux内核中也是利用互斥量或信号量等内存数据标记
除了利用内存数据做锁其他任何互斥的都能做锁(只考虑互斥情况),如流水表中流水号与实践结合做幂等校验可以看作是一个不会释放的锁,或者使用某个文件是否存在作为锁等。只需要满足在对标记进行修改能保证原子性和内存可见性即可。
什么是分布式分布式的CA ...
18.字符串常量池
JVM——字符串常量池详解引言 在Java开发中不管是前后端交互的JSON串,还是数据库中的数据存储,我们常常需要使用到String类型的字符串。作为最常用也是最基础的引用数据类型,JVM为String提供了字符串常量池来提高性能,本篇文章我们一起从底层JVM中认识并学习字符串常量池的概念和设计原理。
字符串常量池由来 在日常开发过程中,字符串的创建是比较频繁的,而字符串的分配和其他对象的分配是类似的,需要耗费大量的时间和空间,从而影响程序的运行性能,所以作为最基础最常用的引用数据类型,Java设计者在JVM层面提供了字符串常量池。
实现前提
实现这种设计的一个很重要的因素是:String类型是不可变的,实例化后,不可变,就不会存在多个同样的字符串实例化后有数据冲突;
运行时,实例创建的全局字符串常量池中会有一张表,记录着长相持中每个唯一的字符串对象维护一个引用,当垃圾回收时,发现该字符串被引用时,就不会被回收。
实现原理 为了提高性能并减少内存的开销,JVM在实例化字符串常量时进行了一系列的优化操作:
在JVM层面为字符串提供字符串常量池,可以理解为是一个缓存区;
...
19.oom排查
1、使用dmesg命令查看系统日志dmesg |grep -E ‘kill|oom|out of memory’,可以查看操作系统启动后的系统日志,这里就是查看跟内存溢出相关联的系统日志。-
2、这时候,需要启动项目,使用ps命令查看进程-ps -aux|grep java 或者是 ps -ef|grep java 命令查看一下你的java进程,就可以找到你的java进程的进程id。-
3、接着使用top命令top命令显示的结果列表中,会看到%MEM这一列,这里可以看到你的进程可能对内存的使用率特别高。以查看正在运行的进程和系统负载信息,包括cpu负载、内存使用、各个进程所占系统资源等。
4、使用jstat命令用jstat -gcutil 20886 1000 10命令,就是用jstat工具,对指定java进程(20886就是进程id,通过ps -aux | grep java命令就能找到),按照指定间隔,看一下统计信息,这里会每隔一段时间显示一下,包括新生代的两个S0、s1区、Eden区,以及老年代的内存使用率,还有young gc以及full gc的次数。-使用 jstat - ...
04.MySQL索引原理及慢查询优化
背景MySQL凭借着出色的性能、低廉的成本、丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库。虽然性能出色,但所谓“好马配好鞍”,如何能够更好的使用它,已经成为开发工程师的必修课,我们经常会从职位描述上看到诸如“精通MySQL”、“SQL语句优化”、“了解数据库原理”等要求。我们知道一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,所以查询语句的优化显然是重中之重。背景
MySQL索引原理索引目的索引的目的在于提高查询效率,可以类比字典,如果要查“mysql”这个单词,我们肯定需要定位到m字母,然后从下往下找到y字母,再找到剩下的sql。如果没有索引,那么你可能需要把所有单词看一遍才能找到你想要的,如果我想找到m开头的单词呢?或者ze开头的单词呢?是不是觉得如果没有索引,这个事情根本无法完成?
索引原理除了词典,生活中随处可见索引的例子,如火车站的车次表、图书的目录等。它们的原理都是一样的,通过不断的缩小想要获得数据的范围来筛选出最终想要的结果,同时把随机的事件变成顺序的事件,也就是我们 ...
03.一条SQL查询语句如何执行
一条SQL查询语句如何执行
MySQL可以分为Server层和存储引擎层两部分
Server层包括 连接器、查询缓存、分析器、优化器、执行器等,涵盖了MySQL的大多数核心功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程,触发器,视图等。
而存储引擎层负责数据的存储和提取。其架构模式是插件式的,支持InnoDB、MyISAM、Memory等多个存储引擎。现在最常用的存储引擎InnoDB,它从MySQL5.5.5版本开始成为默认存储引擎。
也就是说,你执行create table建表的时候,如果不执行搜索引擎,默认的是innodb,不过,你也可以通过执行存储引擎的类型来选择别的引擎,比如在create table 语句中使用 engine=memory,来执行使用内存引擎创建表。不同存储引擎的表数据存取方式不同,支持的功能也不同。
连接器第一步,你会先连接到这数据库上,这时候接待你的就是连接器。连接器负责跟客户端建立连接,获取权限,位置和管理连接。连接命令一般是这么写的:
1mysql -h$ip -P$port -u$user ...