Skip to content

Update README.md #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 47 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
a7b72b6
Update README.md
ouzhrm Dec 7, 2017
cd6f161
Update README.md
ouzhrm Dec 8, 2017
efea624
Update README.md
ouzhrm Dec 8, 2017
1ec5d4a
Update README.md
ouzhrm Dec 8, 2017
7ab52ed
Update README.md
ouzhrm Dec 12, 2017
d333bd1
Update README.md
ouzhrm Dec 12, 2017
77fa7a8
Update README.md
ouzhrm Dec 12, 2017
5048a1c
Update README.md
ouzhrm Dec 12, 2017
5379670
Update README.md
ouzhrm Dec 12, 2017
95f97a1
Update README.md
ouzhrm Dec 12, 2017
936df4e
Update README.md
ouzhrm Dec 13, 2017
f615863
Update README.md
ouzhrm Dec 15, 2017
2aab3b7
Update README.md
ouzhrm Dec 16, 2017
bcfd6d9
Update README.md
ouzhrm Dec 18, 2017
6430d09
Update README.md
ouzhrm Dec 19, 2017
9c4d4a2
Update README.md
ouzhrm Dec 19, 2017
b98dd82
Update README.md
ouzhrm Dec 19, 2017
52a6fd5
Update README.md
ouzhrm Dec 20, 2017
e955446
Update README.md
ouzhrm Dec 20, 2017
2db7fa8
Update README.md
ouzhrm Dec 21, 2017
8ef19a0
Update README.md
ouzhrm Dec 21, 2017
456be6c
Update README.md
ouzhrm Dec 21, 2017
d2da52c
Update README.md
ouzhrm Dec 24, 2017
7f70a2c
Update README.md
ouzhrm Dec 24, 2017
550f95c
Update README.md
ouzhrm Mar 15, 2018
c13c0ad
Update README.md
ouzhrm Mar 18, 2018
58bb951
Create GC在什么时候对什么东西做了什么事情.md
ouzhrm Mar 21, 2018
3977dcb
Update GC在什么时候对什么东西做了什么事情.md
ouzhrm Mar 21, 2018
3177512
Update GC在什么时候对什么东西做了什么事情.md
ouzhrm Mar 21, 2018
ff287f2
Create ThreadLocal源码解析.md
ouzhrm Mar 22, 2018
275f120
Update ThreadLocal源码解析.md
ouzhrm Mar 22, 2018
5b1ad35
Create java中hashMap的默认大小为什么是2的幂.md
ouzhrm Mar 24, 2018
4afc0b4
Create ConcurrentHashMap源码分析.txt
ouzhrm Mar 26, 2018
9856f6a
Create spring的实现思想和原理.md
ouzhrm Apr 3, 2018
083aa24
Create 问题与答案.md
ouzhrm Apr 6, 2018
6e66819
Update 问题与答案.md
ouzhrm Apr 6, 2018
ab1451d
Update 问题与答案.md
ouzhrm Apr 6, 2018
48a3070
Update README.md
ouzhrm Apr 6, 2018
0ef7d46
Update 问题与答案.md
ouzhrm Apr 6, 2018
3c6dde5
Update README.md
ouzhrm Apr 6, 2018
be47300
Update 问题与答案.md
ouzhrm Apr 6, 2018
371b447
Update README.md
ouzhrm Apr 6, 2018
c0dee22
Update README.md
ouzhrm Apr 6, 2018
446edfa
Update README.md
ouzhrm Apr 6, 2018
44b7d94
Update README.md
ouzhrm Apr 7, 2018
9c76519
Update 问题与答案.md
ouzhrm Apr 7, 2018
796642e
Update 问题与答案.md
ouzhrm Apr 9, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions ConcurrentHashMap源码分析.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package com.testconcurrent;

import java.util.concurrent.ConcurrentHashMap;

public class ChmTest {
/**
* 补充二叉树和红黑树相关知识。
* 二叉树特点:左边子节点(值大小)<= 父节点 <= 右边子节点
* 二叉树思想:二分查找
* 二叉树缺点:无法保证平衡左右子节点个数,通俗的说:比如左边节点的个数远远大于右边节点的个数。
* 弥补二叉树的缺点:红黑树(可保证根节点到叶节点的最大长度小于等于最小长度的两倍)
* 红黑树保持左右节点个数平衡的五大规则:
* 1、节点不是黑色就是红色的。
* 2、根节点必须是黑色的。
* 3、叶节点(NUL节点或者是空节点)必须是黑色的。
* 4、红色节点下的子节点必须黑色的。 (重要,必须记住)
* 5、从任一一个节点向下查找,直到叶节点的所有路径里的黑色节点都相等。 (重要,必须记住)
* 变色:黑色变成红色或者红色变成黑色。
* 旋转方式有两种:
* 左旋:http://img.blog.csdn.net/20170323102309404?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvU3VuX1RUVFQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast
* 右旋:http://img.blog.csdn.net/20170323102237896?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvU3VuX1RUVFQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast
* 原地址:https://blog.csdn.net/sun_tttt/article/details/65445754
* 那什么时候会进行旋转和变色呢?插入和删除元素时,破坏上面五大规则的时候。旋转和变色有可能组合进行,但最终得到的红黑树都必须是符合上面五大规则的。
*/
public static void main(String[] args) {

//概念:在JDK1.7版本中,ConcurrentHashMap的数据结构是由一个Segment数组和多个HashEntry数组组成,即数组+链表+红黑树
//Segment数组的意义就是锁分离技术

//初始化:
//ConcurrentHashMap的初始化是会通过位与运算来初始化Segment的大小,用ssize来表示 ,一般默认ssize = 1;
//因为ssize用位于运算来计算(ssize <<=1),所以Segment的大小取值都是以2的N次方
//HashEntry大小的计算也是2的N次方(cap <<=1), cap的初始值为1,所以HashEntry默认最小的容量为2
ConcurrentHashMap<Integer, String> chm = new ConcurrentHashMap<Integer, String>();

//put操作
//第一步:初始化Segment:
//Segment实现了ReentrantLock,也就带有锁的功能
//当执行put操作时,会进行第一次key的hash来定位Segment的位置,如果该Segment还没有初始化,即通过CAS操作进行赋值
//第二步:初始化HashEntry
//先找位置:segment的hash值&( 位与运算)表的长度-1
//然后尝试获取Segment锁,如果获取到,直接插入,如果获取不到,则进行自旋(while(!tryLock())),达到一定的次数,将等待唤醒
chm.put(123, "123");

//get操作
//获取对应的segment的锁,如果没有获取到,则返回null,获取到则通过hash key定位到segment的位置。
//然后定位到HashEntry,遍历比较获取值
System.err.println(chm.get(123));

//size操作(两种方案)
//第一种方案:三次获取值比较,相同则没有改变,直接返回
//第二种方案:第一种方案不成立,则给所有segment加锁,然后取值,返回
System.out.println(chm.size());
chm.clear();//调用segment数组的clear方法
chm.contains("123");//先上segment锁,在遍历hashEntry的链表
chm.containsKey(123);//先上segment锁,在遍历hashEntry的数组
//...还有很多方法,这就不一一分析,实现不复杂

//jdk1.8和1.7的ConcurrentHashMap的区别
//一、1.8的ConcurrentHashMap锁的粒度会更细,1.7的chm(ConcurrentHashMap)采用segment+HashEntry+红黑树实现,
//一个segment包含多个HashEntry,锁为segment(继承ReentrantLock)
//而1.8将抛弃segment,采用CAS+Node(HashEntry)+synchronized+红黑树实现,锁的粒度为HashEntry

//1.8的put方法
//是否正在扩容?正在扩容,则先扩容。
//是否有hash冲突?即检查插入点有没数据,如果没有数据,则直接CAS插入(调用CompareAndSwapInt方法),如果有hash冲突,则加锁,等待插入。
//插入方式的选择?hashentry的方式有两种,一种是直接插入链表的尾端,另外一种是根据红黑树的特点调整插入,选择那一种方案取决于链表的长度,是否大于等于8
//是否需要扩容?多条线程进行扩容。

//1.8的get方法
//检查是否只有一个头结点?有则直接返回。没有则获取锁,直接遍历返回.
//hashentry链表长度不是一的时候,还得检查是否正在扩容?如果是,则调用节点的find方法,遍历之后返回
}
}
18 changes: 18 additions & 0 deletions GC在什么时候对什么东西做了什么事情.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
##### GC在什么时候,对什么东西,做了什么事情?
* 答:什么时候?这个时间不好确定。
* 但有一点肯定的是,eden区满了的时候会进行MinorGC。
* 人为的调用System.GC()的时候对象总大小大于老年代的剩余空间的时候,空间担保失败并且在HandlePromotionFailure开关开启的时候,会进行fullGC。
* 当然我们也可以通过NewRatio开关控制新生代和老年代的分配空间的比例,让老年代的空间大些,
* 设置MaxTenuringThreshold参数让达到进入老年的对象存活次数大些,从而通过空间的大小使得
* 垃圾回收的时候向后延长。
* 对什么东西?
* 通过可达性分析,从GC Root向下搜索不到,经过第一次标记清理后,仍然没有复活的对象。
* 做了什么事情?
* 删除不使用的对象,回收内存空间。
* 新生代会采用复制算法清理。
* 新生代分eden区和两个survivor区(from,to),eden:from:to = 8:1:1,
* 每次使用只用eden区和一个from区,eden区和from区存活的对象复制到区,然后清空
* eden区和from区,最后from区和to区替换。
* 老年代会采用标记清理算法清理。
* 标记GC root向下搜索到的存活对象,
* 清理是遍历堆中所有的对象,清理没有被标记的对象
41 changes: 10 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,17 @@
## java基础

Arrays.sort实现原理和Collection实现原理
foreach和while的区别(编译之后)
线程池的种类,区别和使用场景
分析线程池的实现原理和线程的调度过程
线程池如何调优
线程池的最大线程数目根据什么确定
动态代理的几种方式
HashMap的并发问题
了解LinkedHashMap的应用吗
反射的原理,反射创建类实例的三种方式是什么?
cloneable接口实现原理,浅拷贝or深拷贝
Java NIO使用
hashtable和hashmap的区别及实现原理,hashmap会问到数组索引,hash碰撞怎么解决
arraylist和linkedlist区别及实现原理
反射中,Class.forName和ClassLoader区别


10、反射的原理,反射创建类实例的三种方式是什么?
11、cloneable接口实现原理,浅拷贝or深拷贝
12、Java NIO使用

反射中,Class.forName和ClassLoader区别  
String,Stringbuffer,StringBuilder的区别?
有没有可能2个不相等的对象有相同的hashcode
简述NIO的最佳实践,比如netty,mina
TreeMap的实现原理

### JVM相关

类的实例化顺序,比如父类静态数据,构造函数,字段,子类静态数据,构造函数,字段,他们的执行顺序
JVM内存分代
Java 8的内存分代改进
JVM垃圾回收机制,何时触发MinorGC等操作
jvm中一次完整的GC流程(从ygc到fgc)是怎样的,重点讲讲对象如何晋升到老年代,几种主要的jvm参数等
你知道哪几种垃圾收集器,各自的优缺点,重点讲下cms,g1
新生代和老生代的内存回收策略
Eden和Survivor的比例分配等
深入分析了Classloader,双亲委派机制

深入分析了Classloader,双亲委派机制  
JVM的编译优化
对Java内存模型的理解,以及其在并发中的应用
指令重排序,内存栅栏等
Expand Down Expand Up @@ -149,9 +130,7 @@ Http请求get和post的区别以及数据包格式
简述tcp建立连接3次握手,和断开连接4次握手的过程;关闭连接时,出现TIMEWAIT过多是由什么原因引起,是出现在主动断开方还是被动断开方。

## 其他

maven解决依赖冲突,快照版和发行版的区别
Linux下IO模型有几种,各自的含义是什么
Linux下IO模型有几种,各自的含义是什么  
实际场景问题,海量登录日志如何排序和处理SQL操作,主要是索引和聚合函数的应用
实际场景问题解决,典型的TOP K问题
线上bug处理流程
Expand Down
17 changes: 17 additions & 0 deletions ThreadLocal源码解析.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#### 什么是ThreadLocal?
* ThreadLocal这个类位于lang包下的,专门用于解决在高并发环境下,对共享变量的访问导致线程出现不安全的问题。也就是通过线程内部副本变量的方式。
#### 那ThreadLocal内部的结构是怎么样的,如何保证线程安全的?
* ThreadLocal内部维护着一个ThreadLocalMap,这个map是ThreadLocal的静态内部类,静态内部类保证了线程访问内部类属性的安全,
里面存储的是键值对。key一般是线程的id,value就是我们想要的目的值。这样做的好处就是保证每一个线程维护自己的局部映射表。
而ThreadLocalMap是如何解决散列冲突的,也可以说我们知道的hash碰撞。我们知道,解决hash碰撞有两种方式,一种是链表的方式。
HashMap内部就是使用这种方式解决hash碰撞的,也就是对key进行hashcode以后得到的存储的地址,如果有值存在,就在值的后面添加
一条小尾巴,就是链表,下次我们可以通过遍历链表查询得到我们想要的值,而另外一种方式就是通过开放地址法,什么是开放地址法,就是
对key进行hashcode后得到的内存地址有值后,就向后位移,找到空位坐下,因为一般hashcode比较均匀,所以才采用这种方式。到了数组的
末尾还没有找到空位,就返回头部继续找空位。那这个hash值为什么会这么均匀呢?它是通过automicInteger和一个固定的值累加上去的。添加
一对key-value,automicInteger就自动加一。
#### ThreadLocal的应用场景?
* 一般是数据库连接的时候和管理Session的时候。因为数据库如何大量连接而且很多是重复的ip地址的话,数据库容易崩溃的。
Session也是。
#### ThreadLocal内存泄漏的原因以及我们应该如何解决?
* ThreadLocal内存泄漏的原因是ThreadlocalMap是静态修饰的,生命周期和ThreadLocal一样长,如果用完没有手动删除对应的key就可能导致内存泄漏。
所以预防的策略就是要养成一个好习惯,用完之后也就是获取了之后及时remove对应key的数据。
4 changes: 4 additions & 0 deletions java中hashMap的默认大小为什么是2的幂.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#### java中hashMap的默认大小为什么是2的幂?
* 提高空间的利用率,尽可能的减少hash碰撞,或者说是散列冲突。比如:我们设定hasmap的容量为15,那么调用hash方法的时候,那个公式没记错的,
原来的hash值&(容量-1),如果是15那么出来的hash值尾数肯定是1,而entry是不会占用这样的位置的,所以导致尾数为1的位置的空间剩余,导致资源的
浪费,也尽可能会出现hash碰撞,降低程序的运行效率。
18 changes: 18 additions & 0 deletions spring的实现思想和原理.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
spring基本原理其实就是通过反射解析类及其类的各种信息,包括构造器、
方法及其参数,属性。然后将其封装成bean定义信息类、constructor信息类、
method信息类、property信息类,最终放在一个map里,
也就是所谓的container,池等等,其实就是个map。。汗。。。。

当你写好配置文件,启动项目后,框架会先按照你的配置文件找到那个要scan的
包,然后解析包里面的所有类,找到所有含有@bean,@service等注解的类,
利用反射解析它们,包括解析构造器,方法,属性等等,然后封装成各种信息
类放到一个map里。每当你需要一个bean的时候,框架就会从container找是不
是有这个类的定义啊?如果找到则通过构造器new出来(这就是控制反转DI,不用你new,
框架帮你new),

再在这个类找是不是有要注入的属性或者方法,比如标有@autowired的
属性,如果有则还是到container找对应的解析类,new出对象,并通过之前解析出来的
信息类找到setter方法,然后用该方法注入对象(这就是依赖注入IOC)。

动态代理(AOP),也称运行时增强。它的思想是面向切面编程的,比如在一个方法执行时,我们
想在方法执行的前后增加另外一些方法,让它和这个方法一同执行,那么这种技术就是动态代理。
Loading