lambda 表达式、Stream API、时间 API
Jigsaw、Jshell、Reactive Streams
局部变量类型推断、G1 的并行 Full GC、ThreadLocal 握手机制
ZGC、Epsilon、增强 var
响应式编程
Future模式是多线程中非常常见的一种设计模式,它的核心思想是异步调用。
当我们需要调用一个函数方式是,如果这个函数执行很慢,那么我们就要进行等待。但有时候,我们可能并不急着需要结果。,因此,我们可以让被调者立即返回,让他在后台慢慢处理这个请求。对于调用者来说,则可以先处理一些其他任务,在真正需要数据的场合再去尝试获得需要的数据。
以上成员均在java.util.concurrent包中,是JDK并发包的核心类。其中ThreadPoolExecutor表示一个线程池。Executors类则扮演着线程池工厂的角色,通过Executors可以取得一个拥有特定功能的线程池。
主要工厂方法:
上下文切换
上下文切换是指CPU的控制权由运行任务转移到另外一个就绪任务时所发生的事件;
让步式上下文切换:指执行线程主动释放CPU,与锁竞争眼中程度成正比,可通过减少锁竞争来避免。
抢占式上下文切换:指线程因分配的时间片用尽而被迫泛起CPU或者被其他优先级更高的线程所抢占,一般由于线程数大于CPU可用核心数引起,可通过调整线程数,适当减少线程数来避免。
减少上下文切换
无锁并发编程:多线程竞争锁时,会引起上下文切换,所以多线程处理数据时,可以用一些办法来避免使用锁,如将数据的 ID 按照 Hash 算法取模分段,不同的线程处理不同段的数据;
CAS:避免加锁和线程阻塞;
使用最少线程:避免创建不需要的线程,比如任务很少,但是创建了很多线程来处理,这样会造成大量线程都处于等待状态;
协程:比线程更轻量级的并发机制;在单线程实现多任务的调度,并在单线程里维持多个任务间的切换。
详细参考:实战Java高并发程序设计第四章
对于行存储(相比列存储)的表和索引,启用数据压缩最直接效果是能够减小数据占用的存储空间的大小;除了节省空间之外,数据压缩还能提高 I/O 密集型查询的性能,因为数据存储在更少的数据页(Data Page)中,SQL Server需要从磁盘读取的数据页更少,数据从Disk加载到内存的速度更快,查询的性能更好。但是,压缩和解压缩的过程都需要消耗额外的CPU资源,开发者必须均衡CPU资源,数据存储和硬盘IO的开销。
详细介绍:数据压缩
此章节待整理
线程 Dump、内存 Dump、gc 情况
分析死锁、分析内存泄露
jstack、jstat、jmap、jhat、Arthas
HeapOutOfMemory、 Young OutOfMemory、
MethodArea OutOfMemory、ConstantPool OutOfMemory、
DirectMemory OutOfMemory、Stack OutOfMemory Stack OverFlow
jvm 相关、class/classloader 相关、monitor/watch/trace 相关、
options、管道、后台异步任务
文档:https://alibaba.github.io/arthas/advanced-use.html
内存溢出、线程死锁、类加载冲突
当一个 Java 程序响应很慢时如何查找问题
当一个 Java 程序频繁 FullGC 时如何解决问题
如何查看垃圾回收日志
当一个 Java 应用发生 OutOfMemory 时该如何解决
如何判断是否出现死锁
如何判断是否存在内存泄露
使用 Arthas 快速排查 Spring Boot 应用404/401问题
使用 Arthas 排查线上应用日志打满问题
利用 Arthas 排查 Spring Boot 应用 NoSuchMethodError
待整理
待整理
MyISAM
访问速度快,但不支持事务,也不支持外键;对事务完整性没有要求或者以SELECT、INSERT为主的应用基本都可以使用这个引擎。
曾经有位阿里面试官告诉我,MyISAM基本不会使用了,其功能都可以使用Memcached完成。
InnoDB
事务型存储引擎,MySQL默认的存储引擎。支持行级锁定和外键约束。
参考链接:MySQL执行计划解析
MySQL会解析查询,并创建内部数据结构(解析树),并对其进行各种优化,包括重写查询、决定表的读取顺序、选择合适的索引等。
Column | JSON Name | Meaning |
---|---|---|
id | select_id | 查询序列号 |
select_type | None | 查询类型 |
table | table_name | 输出行信息所属表 |
partitions | partitions | 匹配的分区 |
type | access_type | 连接使用类型 |
possible_keys | possible_keys | 可能加速查询的索引 |
key | key | 真正使用的索引 |
key_len | key_length | 使用的索引长度,在不损失精确性的情况下,长度越短越好 |
ref | ref | 索引所在的列 |
rows | rows | 引擎认为必须检查的用来返回请求数据的行数 |
filtered | filtered | 按表条件过滤的行百分比 |
Extra | None | 附加信息 |
参考:MySQL官方文档
亦可参考链接:MySQL执行计划解析
哈希索引就是采用一定的哈希算法,把键值换算成新的哈希值,检索时不需要类似B+树那样从根节点到叶子节点逐级查找,只需一次哈希算法即可立刻定位到相应的位置,速度非常快。
完全是因为计算机的内存-机械硬盘两层存储结构。内存可以完成快速的随机访问(随机访问即给出任意一个地址,要求返回这个地址存储的数据)但是容量较小。而硬盘的随机访问要经过机械动作(1磁头移动 2盘片转动),访问效率比内存低几个数量级,但是硬盘容量较大。典型的数据库容量大大超过可用内存大小,这就决定了在B+树中检索一条数据很可能要借助几次磁盘IO操作来完成。
当数据库一条记录里包含多个字段时,一棵B+树就只能存储主键,如果检索的是非主键字段,则主键索引失去作用,又变成顺序查找了。这时应该在第二个要检索的列上建立第二套索引。 这个索引由独立的B+树来组织。
有两种常见的方法可以解决多个B+树访问同一套表数据的问题,一种叫做聚簇索引(clustered index ),一种叫做非聚簇索引(secondary index)。
InnoDB使用的是聚簇索引
将主键组织到一棵B+树中,而行数据就储存在叶子节点上,若使用"where id = 14"这样的条件查找主键,则按照B+树的检索算法即可查找到对应的叶节点,之后获得行数据。若对Name列进行条件搜索,则需要两个步骤:第一步在辅助索引B+树中检索Name,到达其叶子节点获取对应的主键。第二步使用主键在主索引B+树种再执行一次B+树检索操作,最终到达叶子节点即可获取整行数据。
MyISM使用的是非聚簇索引
非聚簇索引的两棵B+树看上去没什么不同,节点的结构完全一致只是存储的内容不同而已,主键索引B+树的节点存储了主键,辅助键索引B+树存储了辅助键。表数据存储在独立的地方,这两颗B+树的叶子节点都使用一个地址指向真正的表数据,对于表数据来说,这两个键没有任何差别。由于索引树是独立的,通过辅助键检索无需访问主键的索引树。
以上参考链接:MySQL的InnoDB索引原理详解
covering index 指的是一个查询语句的执行只用从索引中就能够获得查询结果,不必从数据表中读取,也可以称之为索引覆盖。如果一个索引包含了(或覆盖了)满足查询语句中字段与条件的数据就叫做覆盖索引。
当一条查询语句符合覆盖索引条件时,sql只需要通过索引就可以返回查询所需要的数据,这样避免了查到索引后再返回表操作,减少I/O提高效率。
使用覆盖索引Innodb比MyISAM效果更好----InnoDB使用聚集索引组织数据,如果二级索引中包含查询所需的数据,就不再需要在聚集索引中查找了。
遇到以下情况,执行计划不会选择覆盖查询:
在联合索引(多列索引)中,选择索引的列顺序有一个经验法则:将选择性最高的列放到索引最前列。
在一个多列B-Tree索引中,索引列的顺序以为着索引首先按照最左列进行排序,其次是第二列。
也就是说,当进行查找时,首先是最先匹配最左的条件,在匹配第二个。然而当查找条件不包含联合索引中其中索引列的任一左边的列时,此时查询都不会走索引。
例:
select * from test where a = ‘1’ and b = ‘2’ and c = ‘3’;
其中联合索引:index(a,b,c)
当查询过程中,查询条件只有b,c 时,不会命中联合索引;
只有a, c 时,亦不会命中;
Using Index Condition Pushdown, the scan proceeds like this instead:
Get the next row’s index tuple (but not the full table row).
Test the part of the WHERE condition that applies to this table and can be checked using only index columns. If the condition is not satisfied, proceed to the index tuple for the next row.
If the condition is satisfied, use the index tuple to locate and read the full table row.
Test the remaining part of the WHERE condition that applies to this table. Accept or reject the row based on the test result.
SELECT * FROM people
WHERE zipcode='95054'
AND lastname LIKE '%etrunia%'
AND address LIKE '%Main Street%';
当没有使用ICP时,MySQL服务器首先查询出满足"zipcode=‘95054’" 条件的所有数据,在内存中再筛选出"lastname LIKE ‘%etrunia%’"和"address LIKE ‘%Main Street%’"条件满足的数据返回给客户端。
使用了ICP条件时,直接在读出数据之前会筛选出符合后两个条件的数据,减少IO读操作,提高性能。
索引下推只能作用在辅助索引( secondary indexes)上;
对于InnoDB的聚簇索引,索引下推技术无效,其完整记录已经读入了InnoDB的缓冲区中,所以并不能减少IO操作。
参考链接:sql优化的几种方式
隔离级别参考链接:面试官:谈谈Mysql事务隔离级别?
详细介绍:MySQL中的锁(表锁、行锁)
ZooKeeper是一个开放源码的分布式协调服务,它是集群的管理者,监视着集群中各个节点的状态根据节点提交的反馈进行下一步合理操作。最终,将简单易用的接口和性能高效、功能稳定的系统提供给用户。
分布式应用程序可以基于Zookeeper实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master选举、分布式锁和分布式队列等功能。
客户端的读请求可以被集群中的任意一台机器处理,如果读请求在节点上注册了监听器,这个监听器也是由所连接的zookeeper机器来处理。对于写请求,这些请求会同时发给其他zookeeper机器并且达成一致后,请求才会返回成功。因此,随着zookeeper的集群机器增多,读请求的吞吐会提高但是写请求的吞吐会下降。
有序性是zookeeper中非常重要的一个特性,所有的更新都是全局有序的,每个更新都有一个唯一的时间戳,这个时间戳称为zxid(Zookeeper Transaction Id)。而读请求只会相对于更新有序,也就是读请求的返回结果中会带有这个zookeeper最新的zxid。