8 Star 25 Fork 5

xinhe65045 / study

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
README.md 9.40 KB
一键复制 编辑 原始数据 按行查看 历史
xinhe65045 提交于 2019-03-16 08:22 . 目录结构

1. 语法

2. 词法结构

3. 类型、值和变量

4. 类型转换与上下文

5. 命名

6. 包

6.1. 包结构概述

  • java.lang
    Java语言包,这个包下的文件不需要显式import。包括:Object类,数据类型相关的类(String,Long,Byte),Class类,线程相关类Thread,异常类Throwable,等。
  • java.io
    I/O操作相关的类。包括:文件类File,FileReader,FileWriter,输入输出流InputStream/OutputStream,等。
  • java.net
    网络相关类。包括:http连接类HttpURLConnection,socket类,等。
  • java.util
    工具类。包括:数据结构相关的类ArrayList、Hashmap,日期类Date,随机数类Random,等。

7. 类

8. 接口

9. 数组

10. 异常

11. JAVA内存模型

11.1. 什么是内存模型(个人理解)

    在编译器各种优化及多种类型的微架构平台上,Java语言规范制定者试图创建一个虚拟的概念并传递到Java程序员,让他们能够在这个虚拟的概念上写出线程安全的程序来,而编译器实现者会根据Java语言规范中的各种约束在不同的平台上达到Java程序员所需要的线程安全这个目的。
  • 处理器内存模型有强弱区分,弱内存模型需要程序对数据可见性做控制并提供了相应的支持。
  • Java内存模型描述了在多线程代码中哪些行为是合法的,以及线程如何通过内存进行交互。
  • Java包含了几个语言级别的关键字,包括:volatile, final以及synchronized,目的是为了帮助程序员向编译器描述一个程序的并发需求。

11.2. 重排序

11.2.1. 编译器重排序

编译期重排序的典型就是通过调整指令顺序,在不改变程序语义的前提下,尽可能减少寄存器的读取、存储次数,充分复用寄存器的存储值。

11.2.2. CPU重排序

一条指令需要若干个CPU时钟周期处理,而通过流水线并行执行,可以在同等的时钟周期内执行若干条指令,具体做法简单地说就是把指令分为不同的执行周期,例如读取、寻址、解析、执行等步骤,并放在不同的元件中处理,同时在执行单元EU中,功能单元被分为不同的元件,例如加法元件、乘法元件、加载元件、存储元件等,可以进一步实现不同的计算并行执行。

11.3. happens-before

  • 程序顺序规则:一个线程中的每个操作,happens-before 于该线程中的任意后续操作。
  • 监视器锁规则:对一个监视器锁的解锁,happens-before 于随后对这个监视器锁的加锁。
  • volatile变量规则:对一个volatile域的写,happens-before 于任意后续对这个volatile域的读。
  • 传递性:如果A happens-before B,且B happens-before C,那么A happens-before C。
  • happens-before是JMM的近似模型
  • happens-before内存模型描绘了一个必要而非充分的约束集。即JMM中有部分约束条件在happens-before中不做要求,比如happens-before允许变量凭空出现。

11.4. final

  • final字段只初始化一次且不再改变。这种语义允许编译器在读取这类字段时进行激进优化。

11.5. double和long的非原子性处理

  • 对非 volatile long 或 double 值的单次写操作视作两 次分开的写操作:每次 32 位。这可能会导致一种情况,某个线程会看到某次写操 作中 64 位的前 32 位,以及另外一次写操作的后 32 位。

11.6. wait集、通知

11.7. wait、sleep、yield、join

12. OTHER

12.1. StringBuilder StringBuffer

  • 线程安全
    • StringBuilder是非线程安全的,StringBuffer是线程安全的
    • 二者继承自同一个父类:AbstractStringBuilder
    • StringBuffer相比StringBuilder在很多方法上增加了synchronized关键字
  • 性能问题
    • StringBuilder默认初始化的数组大小只有16
    • 扩容时需要重新开辟一块内存(length*2+2),并拷贝原有数据
          /**
          * This implements the expansion semantics of ensureCapacity with no
          * size check or synchronization.
          */
          void expandCapacity(int minimumCapacity) {
              int newCapacity = value.length * 2 + 2;
              if (newCapacity - minimumCapacity < 0)
                  newCapacity = minimumCapacity;
              if (newCapacity < 0) {
                  if (minimumCapacity < 0) // overflow
                      throw new OutOfMemoryError();
                  newCapacity = Integer.MAX_VALUE;
              }
              value = Arrays.copyOf(value, newCapacity);
          }
      
    • 使用时需要考虑扩容造成的性能损失
  • 使用时机
    • 如果编译器本身能对String操作做优化,使用StringBuilder并不合算

12.2. NIO

12.2.1. 实现原理

这里暂时只分析linux下的原理

  • select
    • 单个进程能够监视的文件描述符的数量存在最大限制,通常是1024(#define __FD_SETSIZE)
    • 内核 / 用户空间内存拷贝问题,select需要复制大量的句柄数据结构,产生巨大的开销
    • select返回的是含有整个句柄的数组,应用程序需要遍历整个数组才能发现哪些句柄发生了事件
  • poll
    • 数组改成链表,没有了监视文件数量的限制,但其他问题仍然存在
  • epoll
    • 采用事件机制,只处理关注的IO事件,不必遍历所有

12.2.2. 基本概念

  • selector 监听IO就绪状态,实现多路复用
  • buffer 高性能缓冲区
  • channel 对IO连接的封装

12.3. 代理

  • 静态代理
  • 动态代理,要求实现类继承接口
    • 遍历接口列表,不会大于65535
    • 生成字节码文件,可选择是否写磁盘
    • ClassLoader加载类
    • Constructor创建实例,实际会有缓存,保证单例
    • InvocationHandler.invoke
  • Cglib,子类代理,不能代理final、private

12.4. 注解

  • 注解的作用
注解也叫元数据,它主要的作用有以下四方面:
生成文档,通过代码里标识的元数据生成javadoc文档。
编译检查,通过代码里标识的元数据让编译器在编译期间进行检查验证。
编译时动态处理,编译时通过代码里标识的元数据动态处理,例如动态生成代码。
运行时动态处理,运行时通过代码里标识的元数据动态处理,例如使用反射注入实例。
  • @Target
表示该注解可以用于什么地方,可能的ElementType参数有:
CONSTRUCTOR:构造器的声明
FIELD:域声明(包括enum实例)
LOCAL_VARIABLE:局部变量声明
METHOD:方法声明
PACKAGE:包声明
PARAMETER:参数声明
TYPE:类、接口(包括注解类型)或enum声明
  • @Retention
表示需要在什么级别保存该注解信息。可选的RetentionPolicy参数包括:
SOURCE:注解将被编译器丢弃
CLASS:注解在class文件中可用,但会被VM丢弃
RUNTIME:VM将在运行期间保留注解,因此可以通过反射机制读取注解的信息。
  • @Document 将注解包含在Javadoc中

  • @Inherited 允许子类继承父类中的注解

  • 注解处理器就是通过反射机制获取被检查方法上的注解信息,然后根据注解元素的值进行特定的处理

12.5. 集合

12.5.1. HashMap

  • 使用数组加链表的结构实现
  • 插入
    • 获取要插入的key的hash
    • 与当前length求模(例如:hash&63)
    • 上一步的计算结果作为数组的index
    • 生成链表,保存到对应的index
    • 如果发生碰撞,作为当前value的next
    • 1.8优化:如果链表长度超过8,转换为红黑树
  • 扩容
    • 当使用量超过75%(loadfactor,可设置),执行扩容
    • 1.8优化:前一位为0时不做处理

12.5.2. concurrentHashMap

12.6. 线程

12.7. 锁

其他
1
https://gitee.com/xinhe65045/study.git
git@gitee.com:xinhe65045/study.git
xinhe65045
study
study
master

搜索帮助