自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(26)
  • 收藏
  • 关注

原创 【集合源码系列】TreeSet源码解析

TreeSetNavigableSet 定义了一些有方向的操作数据结构private transient NavigableMap<E,Object> m;// Dummy value to associate with an Object in the backing Mapprivate static final Object PRESENT = new Object();构造方法TreeSet(NavigableMap<E,Object> m) {

2020-09-30 11:50:05 247

原创 【集合源码系列】HashSet源码解析

HashSetHashSet ,基于 HashMap 的 Set 实现类。数据结构// HashSet 只有一个属性,那就是 mapprivate transient HashMap<E, Object> map;// 因为 HashSet 没有 value 的需要,所以使用一个统一的 PRESENT 即可private static final Object PRESENT = new Object();构造方法public HashSet() { map =

2020-09-30 11:49:42 260

原创 【集合源码系列】HashTable源码解析

HashTable区别 HashMap线程安全Hashtable 是线程安全的,HashMap 不是线程安全的。Hashtable 所有的元素操作如put-get等都是 synchronized 修饰的,而 HashMap 并没有。public synchronized V put(K key, V value);public synchronized V get(Object key);// ...性能优劣既然 Hashtable 是线程安全的,每个方法都要阻塞其他线程,所以 Has

2020-09-29 17:29:57 230

原创 【集合源码系列】TreeMap中子Map源码解析

范围查找在 SortedMap 接口中,定义了按照 key 查找范围,返回子 SortedMap 结果的方法#subMap(K fromKey, K toKey)#headMap(K toKey)#tailMap(K fromKey)在 NavigableMap 中,定义了按照 key 查找范围,返回子 NavigableMap 结果的方法:#subMap(K fromKey, K toKey)#subMap(K fromKey, boolean fromInclusive, K toK

2020-09-29 17:29:24 342

原创 【集合源码系列】TreeMap其余方法源码解析

查找元素单个元素public V get(Object key) { // 获得 key 对应的 Entry 节点 Entry<K,V> p = getEntry(key); // 返回 value 值 return (p == null ? null : p.value);}final Entry<K,V> getEntry(Object key) { // 不使用 comparator 查找 // Offload compar

2020-09-29 17:29:00 229

原创 【集合源码系列】TreeMap核心方法源码解析

TreeMapNaviableMap 定义了一些有方向操作红黑树每个节点要么是红色,要么是黑色。根节点必须是黑色红色节点不能连续(也即是,红色节点的孩子和父亲都不能是红色)。对于每个节点,从该点至null(树尾端)的任何路径,都含有相同个数的黑色节点。数据结构// key 排序器private final Comparator<? super K> comparator;// 红黑树的根节点private transient Entry<K,V&gt

2020-09-29 17:28:33 562

原创 【集合源码系列】LinkedHashMap源码解析

LinkedHashMapLinkedHashMap 继承自 HashMap 类,基本上没有重写 HashMap 的方法,只是把 HashMap 空实现的预留拓展点实现了。数据结构Map 拓展属性/** * 头节点。 * * 越老的节点,放在越前面。所以头节点,指向链表的开头 */transient LinkedHashMap.Entry<K,V> head;/** * 尾节点 * * 越新的节点,放在越后面。所以尾节点,指向链表的结尾 */transi

2020-09-29 17:28:08 266

原创 【集合源码系列】HashMap源码补充

迭代器1、Map 未实现迭代器接口,需要转换成集合keySettransient Set<K> keySet;public Set<K> keySet() { // 获得 keySet 缓存 Set<K> ks = keySet; // 如果不存在,则进行创建 if (ks == null) { ks = new KeySet(); keySet = ks; } return k

2020-09-29 17:27:12 149

原创 【集合源码系列】HashMap其余方法源码解析

移除元素移除单个元素public V remove(Object key) { Node<K,V> e; // hash(key) 求哈希值 return (e = removeNode(hash(key), key, null, false, true)) == null ? null : e.value;}final Node<K,V> removeNode(int hash, Object key, Object value

2020-09-29 17:26:41 179

原创 【集合源码系列】HashMap核心方法源码详解

HashMap数据结构// 底层存储的数组transient Node<K,V>[] table;// 调用 `#entrySet()` 方法后的缓存transient Set<Map.Entry<K,V>> entrySet;// key-value 的键值对(映射)数量transient int size;// HashMap 的修改次数transient int modCount;/** * 阀值 * * 如果 table

2020-09-29 17:26:15 250

原创 【集合源码系列】LinkedList源码解析

LinkedListjava.util.Deque 接口,提供双端队列的功能,LinkedList 支持快速的在头尾添加元素和读取元素,所以很容易实现该特性。继承了 java.util.AbstractSequentialList 抽象类,它是 AbstractList 的子类,实现了只能连续访问“数据存储”,基于迭代器顺序遍历后,从而实现后续的操作。例如 #get(int index)、#add(int index, E element) 等等随机操作的方法。数据结构// 链表大小

2020-09-29 17:25:50 247

原创 【集合源码系列】ArrayList源码解析

ArrrayListjava.util.RandomAccess 接口,表示 ArrayList 支持快速的随机访问数据结构transient Object[] elementData;// 实际存储数据的多少private int size;构造方法指定大小// 初始化长度为0时,给elementData赋值的空数组private static final Object[] EMPTY_ELEMENTDATA = {};public ArrayList(int init

2020-09-29 17:25:19 1500

原创 Centos7配置PPTP共享网络

一、检查是否支持PPTP1、查看系统是否支持PPTPmodprobe ppp-compress-18 && echo success #应该输出:success2、是否开启TUN/TAPcat /dev/net/tun #应该输出:cat: /dev/net/tun: File descriptor in bad state3、是否开启pppcat /dev/ppp #应该输出:cat: /dev/ppp: No such device or address如果环境

2020-09-18 19:58:49 5519 9

原创 Linux使用AutoSSH做内网穿透

配置公网的服务器修改ssh配置文件vi /etc/ssh/sshd_config#连接相关配置GatewayPorts yes # 是否允许远程主机连接本地的转发端口TcpKeepAlive yes # 是否保持连接ClientAliveInterval 30 # 心跳发送间隔ClientAliveCountMax 5 # 心跳发送最大失败次数配置内网的服务器1、配置免密登录公网的服务器用ssh-keygen生成密钥ssh-keygen# 这里填写的路径是最终生成密钥的路径,

2020-09-17 14:01:07 1163 1

原创 SPI机制源码解析

概念​ SPI 全称为 (Service Provider Interface) ,是JDK内置的一种服务提供发现机制。SPI是一种动态替换发现的机制, 比如有个接口,想运行时动态的给它添加实现,你只需要添加一个实现。​ 当服务的提供者提供了一种接口的实现之后,需要在classpath下的META-INF/services/目录里创建一个以服务接口命名的文件,这个文件里的内容就是这个接口的具体的实现类。使用:创建源码:获取源码:时序图:核心类UrlClassPa

2020-09-14 00:20:10 319

原创 函数式编程与Lamda底层

概念:Java一直是面向对象的语言,一切皆对象,如果想要调用一个函数,函数必须属于一个类或对象,然后在使用类或对象进行调用。但是在其它的编程语言中,如js,c++,我们可以直接写一个函数,然后在需要的时候进行调用,即可以说是面向对象编程,也可以说是函数式编程。从功能上来看,面向对象编程没什么不好的地方,但是从开发的角度来看,面向对象编程会多写很多可能是重复的代码行。比如创建一个Runnable的匿名类的时候:Runnable runnable = new Runnable() { @Overr

2020-09-14 00:19:50 198

原创 Stream并行流源码解析

承接我的上一篇Stream源码博客并行流并行流调试代码截图:并行流源码核心类图(可以看出Fork-Join)和串行开始有区别的地方去重:排序:​小结:并行流对于有状态中间操作,会先设置其CombineFlag然后遍历每个流,如果是有状态的,则调用opEvaluateParallelLazy() 返回该有状态操作执行后的流(因为java doc中说到有状态的操作,没法同时和无状态操作一起并行进行)ForkJoin进行任务拆分执行,其实

2020-09-13 15:16:24 408

原创 Stream执行流程源码解析

Stream使用Stream中的操作可以分为两大类:中间操作与结束操作,中间操作只是对操作进行了记录,只有结束操作才会触发实际的计算(即惰性求值),这也是Stream在迭代大集合时高效的原因之一。注意事项不要使用基本类型的数组获取流,因为得到的流还是数组流的执行顺序是一个元素会把流执行到底,并不是一个环节全部收集后再一起执行下一环节核心类图上面截图代码执行源码:总结:

2020-09-13 15:16:02 865 1

原创 注解底层源码解析

注解元注解@Target:注解的作用目标@Retention:注解的生命周期RetentionPolicy.SOURCE:当前注解编译期可见,不会写入 class 文件RetentionPolicy.CLASS:类加载阶段丢弃,会写入 class 文件RetentionPolicy.RUNTIME:永久保存,可以反射获取@Documented:注解是否应当被包含在 JavaDoc 文档中@Inherited:是否允许子类继承该注解内置三大注解@Override(Retenti

2020-09-13 15:15:02 294

原创 反射相关问题与源码解析

反射可以JVM运行时动态的加载类,还可以调用类的方法或者修改其属性。反射原理Class.forName()时序图源码clazz.getDeclaredMethod()时序图Class反射的元数据对象:源码method.invoke()时序图源码:比较GenerateMethodAccessorImpl对比该方法调用15次前,每次都是jvm本地方法调用。15次后,说明该方法经常使用,专门用a

2020-09-13 15:14:26 471

原创 序列化原理及技术实现

序列化理解序列化并不是说要把对象或者消息直接编码为二进制串,而是转化为本地某一种可以持久化或者传输的结构。编码为二进制串是网络七层模型中第六层表现层完成(通过获得序列化后文件的输入流,然后进行编码即可)。Java API相关Serializable 接口是一个标记接口,不用实现任何方法。一旦实现了此接口,该类的对象就是可序列化的。Serializable接口的反序列化并不会调用构造方法。对象是由JVM自己生成的对象,不通过构造方法生成。因此,它存在一定的安全隐患。一个精心构造的byte[]数组

2020-09-13 15:13:51 995 1

原创 final套餐及常见问题

final相关区别final修饰符(关键字)被final修饰的类,就意味着不能再派生出新的子类,不能作为父类而被子类继承。因此一个类不能既被abstract声明,又被final声明。被final声明的方法也同样只能使用,即不能方法重写。将变量或方法声明为final,可以保证他们在使用的过程中不被修改。被声明为final的变量必须在声明时给出变量的初始值,而在以后的引用中只能读取。finally是在异常处理时提供finally块来执行任何清除操作。不管有没有异常被抛出、捕获,finally块

2020-09-13 15:13:21 214

原创 异常设计原则与继承体系

异常异常体系Error与ExceptionError是程序无法处理的错误,比如OutOfMemoryError、ThreadDeath、NoClassDefFoundError等。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止。Exception是程序本身可以处理的异常,这种异常分两大类运行时异常和非运行时异常。程序中应当尽可能去处理这些异常,使程序继续正常运行。Exception运行时异常运行时异常都是RuntimeException类及其子类异常,如NullPoint

2020-09-13 15:12:49 355

原创 Object类与相关实现

Object类基本方法1、clone方法保护方法,实现对象的浅复制即把每个属性的原封不动复制过来,官方文档说"字段的内容本身不会被克隆", 即如果某个属性是对象,只会复制其引用,而不会复制其值还说"如果一个类仅包含基本字段或对不可变对象的引用,则通常情况是不需要super.clone 修改对象返回的字段",所以要实现深拷贝就要重写clone)只有实现了Cloneable接口才可以调用该方法,否则抛出CloneNotSupportedException异常。2、getClass方法fina

2020-09-13 15:12:12 171

原创 String常见问题及编译后实现

String底层内部结构public final class String implements Serializable,Comparable<String>,CharSequence { // 用于存储字符串的值 private final char value[] // 缓字符串的hash code private int hash;}值类使用final修适的原因安全,不会再有自类进行修改,从而导致出现安全问题高效

2020-09-13 15:11:34 385

原创 基本类型及包装类源码解析

基本与包装类基本类型有默认值,而包装类型初始为null所有的POJO类必须使用包装类型,在rpc方法中定义参数和返回值的类型用包装类,因为默认值不代表空值,比如0不代表该属性为空泛型调用函数必须用包装类,因为其参数类型都是Object。但是反射调用方法,其方法参数可以为基本类型,在invoke的java doc中说明了原始类型会和引用类型自动转换。在本地变量推荐使用基本类型。什么时候该用包装类,什么时候用基本类型,看基本的业务来定:这个字段允不允许null值或者参数为Object,则必然要用封装

2020-09-13 15:10:27 1410

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除