参考
- 鳌丙 - codesheep - 廖雪峰https://www.liaoxuefeng.com/ - hollishttps://www.hollischuang.com/成神 - javaguidehttps://snailclimb.gitee.io/ - 程序员内功https://github.com/iamshuaidi/algo-basic - 源码阅读 |
- java程序设计实用教程 第五版 叶核亚 - 深入理解Java虚拟机 Java虚拟机规范 - Java并发编程的艺术 - Java 核心技术Thinking in Java Java编程思想 - Memcache/Redis/Mongodb |
Java学到什么程度才能叫精通? https://www.zhihu.com/question/28903757/answer/575333243 Java基础常见笔试题总结 https://blog.csdn.net/qq_16633405/article/details/79211002 https://www.bilibili.com/read/cv6753808 java源码阅读 https://www.cnblogs.com/shawnyue-08/p/12590133.html |
---|---|---|
CVTE面试题 | - OpenJDKhttp://hg.openjdk.java.net/ - OracleJDK - https://www.jianshu.com/p/4f73957acc5b - sunJDK - registerNatives方法 |
https://blog.csdn.net/Saintyyu/article/details/90452826 | |
概述
- java之父詹姆斯·高斯林James Gosling
- Java特点
- 跨平台特性
- 完全面向对象和简单性
- 可靠性指针 内存
- Java版本
- 三大平台技术体系划分
- Java SE(Java Platform,Standard Edition)
- Java EE(Java Platform,Enterprise Edition)Java 平台企业版
- Java ME(Java Platform,Micro Edition)
- 之前叫J2 java2
- https://www.jianshu.com/p/92ccf737bece
- https://www.jianshu.com/p/62c232f83e86
- Oracle甲骨文sun
- 反编译
- cfrhttp://www.benf.org/other/cfr/index.html
- https://www.hollischuang.com/archives/58
JDK目录结构+作用分析
|
- bin
- java.exe:这个可执行程序其实就是JVM,运行Java程序,就是启动JVM,然后让JVM执行指定的编译后的代码;
- javac:这是Java的编译器,它用于把Java源码文件(以.java后缀结尾)编译为Java字节码文件(以.class后缀结尾);
- javap.exe
- jar:用于把一组.class文件打包成一个.jar文件,便于发布;
- javadoc:用于从Java源码中自动提取注释并生成文档;
- jdb:Java调试器,用于开发阶段的运行调试。
- jps.exe(Java Virtual Machine Process Status Tool)
- https://www.cnblogs.com/rainy-shurun/p/5015927.html
- https://www.cnblogs.com/nbjin/p/7392541.html
- jvisualvm.exe
- https://www.cnblogs.com/xifengxiaoma/p/9402497.html
- javaDump
- jstack
- jmap
- jstat
- jconsole
- javap
- jar包http://www.hollischuang.com/archives/337
|
- lib
- jre
- bin
- lib
- include
| https://blog.csdn.net/qq_38989725/article/details/76136117?utm_medium=distribute.pc_relevant.none-task-blog-OPENSEARCH-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-OPENSEARCH-1.nonecase
- https://www.cnblogs.com/chenglc/p/7997988.html
- https://blog.csdn.net/kagurawill/article/details/102583059
| | —- | —- | —- |
课程
|
- 实验
《Java基础》实验说明.doc
《Java基础》实验说明(1).doc
Java基础实验报告(第一次).docJava基础实验报告(第二次).docJava基础实验报告(第三次).docJava基础实验报告(第四次).docJava基础实验报告(第五次).docJava基础实验报告(第六次).doc
Java基础实验报告(第一次).docJava基础实验报告(第二次).doc
Java基础实验报告(第三次).docJava基础实验报告(第四次).docJava基础实验报告(第五次).docJava基础实验报告(第六次).doc |
- 考试
知识点总结-1.docx知识点总结-2.docx知识点总结-3.docx知识点总结-4.docx知识点总结5.docx
知识点总结(6-8)章) .docx
JAVA样卷及答案.pdf
第六章作业.docx | 《Java程序设计实用教程(第5版)》单元测验和样卷答案.ppt《Java程序设计实用教程(第5版)习题解答》.ppt |
| —- | —- | —- |
|
- 代码
JAVA上课代码.zip |
- 书籍附带
第01章 Java概述.ppt第02章 Java语言基础.ppt第03章 类的封装、继承和多态.ppt第04章 接口、内部类和Java API基础.ppt第05章 异常处理.ppt第06章 图形用户界面设计.ppt第07章 多线程编程.ppt第08章 流和文件操作.ppt第09章 Socket通信.ppt第10章 数据库应用.ppt第11章 基于JSP的Web应用.ppt第12章 综合应用设计.ppt
[Java程序设计实用教程(第5版)][叶核亚][电子教案(PPT版本)].zip[Java程序设计实用教程(第5版)][叶核亚][配套练习题].zip[Java程序设计实用教程(第5版)][叶核亚][程序源代码].zip《Java程序设计实用教程(第5版)》单元测验和样卷答案.ppt《Java程序设计实用教程(第5版)习题解答》.ppt |
- 课件
第01章 开发简单JAVA应用程序.ppt第02章 Eclipse简单应用.ppt第03章 Java 语言基础_01数据类型_02.ppt第03章 Java 语言基础_02运算符和表达式+控制语句_02.ppt第03章 Java 语言基础_03字符串_03.ppt第04章 面向对象编程_01_03.ppt第04章 面向对象编程_04类和包.ppt第04章 面向对象编程_05对象.ppt第04章 面向对象编程_06封装.ppt第04章 面向对象编程_06类的方法.ppt第04章 面向对象编程_07继承和多态.ppt第04章 面向对象编程_08接口和抽象类.ppt第05章 异常处理.ppt第06章 输入输出流及文件操作.ppt第07章 集合框架.ppt
集合总结.txt
抽象类和接口练习.docxJava程序员:如何有效地使用Java HashMap.docxread.txtJava 基础语法.docxJava 开发环境配置.docx |
基础
注释
数据
- 字面常量直接量literal
- 变量-作用域生命期
- 常量
- 数据形式
- 十进制数形式:如 54、-67、0。
- 八进制数形式:Java 中的八进制常数的表示以 0 开头,如 0125 表示十进制数 85,-013 表示十进制数 -11。
- 十六进制数形式:Java 中的十六进制常数的表示以 0x 或 0X 开头,如 0x100 表示十进制数 256,-0x16 表示十进制数 -22。
- 字符型
- 布尔型
- 数据类型DateType
|
- 基本数据类型PrimitiveType
- 数值型
- 整型 byte,short,int,long (1B, 2B , 4B , 8B)都有符号位
- 浮点型 float,double (4B , 8B)
- https://blog.csdn.net/shuzfan/article/details/53814424
- 布尔逻辑型 boolean(1B)
- 字符型 char(16位)
|
- 引用类型ReferenceType
|
- 数据类型转换
- 显式转换
以下 b 的值是: byte b = (byte)129;正确答案: B -126-127-128-129
- 隐式转换
| | —- | —- | —- |
运算符-操作数表达式
- 优先级结合性
- 算术运算符 +、-、*、/、%、++、—
- 关系运算符 >、<、>=、<=、==、!=
- 逻辑运算符 !、&&、||、&、|
- 赋值运算符
- 类型强制转换运算符()
- 条件运算符
- new运算符:申请数组的存储空间,创建对象。
- 位运算符
- 移位运算>>>
图形用户界面GUI
- AWT抽象窗口工具箱(Abstract Window Toolkit,AWT)
- swing
- javaFX
Java安全Security
- java.security包
- java.security.MessageDigest抽象类
Java单元测试
参考
http://www.hollischuang.com/archives/category/%e7%bb%bc%e5%90%88%e5%ba%94%e7%94%a8/%e5%8d%95%e5%85%83%e6%b5%8b%e8%af%95
https://www.liaoxuefeng.com/wiki/1252599548343744/1255945269146912
https://blog.csdn.net/YF_Li123/article/details/83004095
https://blog.csdn.net/chenbetter1996/article/details/80441178
Java异常Exception
- 数据类型 - java.lang.Throwable类 - java.lang.Exception类 - printStackTrace方法 - java.lang.RuntimeException运行异常类 - java.lang.IOException - java.lang.Error类 - |
||
---|---|---|
捕获异常
try{
String s = "abc";
int n = Integer.parseInt(s);
}catch (RuntimeException runtimeException){//只有一个能执行
}catch (Exception e){
e.printStackTrace();
}finally {不管发生异常没有 都会执行
}
抛出异常
- 手动抛出throw
- 抛出异常声明throws
日志系统
- 数据类型 - java.util.logging.Logger - Commons Logging+Log4j - SLF4J+Logback |
- 日志级别 |
|
---|---|---|
断言Assertion
- assert
Java反射Reflection
- 抽象:反射机制指的是程序在运行时能够获取自身的信息。
- 具体:程序在运行的时候可以拿到类的所有信息,比如字段,方法,构造方法,继承关系,还可以实例化类等等
- 还可以拿到实例化对象字段的值
|
- 获取class类的Class类实例化
- Class cls = String.class;
- Class cls = new String().getClass();
- Class cls = Class.forName(“java.lang.String”);
| | | | —- | —- | —- | |
- java.lang.Class类
- 类型名
System.out.println(“is interface: “ + cls.isInterface());
System.out.println(“is enum: “ + cls.isEnum());
System.out.println(“is array: “ + cls.isArray());
System.out.println(“is primitive: “ + cls.isPrimitive());
- 类名
- 包名
- 注解
- 字段方法
- 类关系
- getSuperclass()
- getInterfaces()
- 实例化类
- 缺点:只能调用公有无参构造方法
String str = String.class.newInstance(我什么都不可填写); |
- java.lang.reflect.Field类
- Class对象获取字段
Field getField(name):根据字段名获取某个public的field(包括父类)
Field getDeclaredField(name):根据字段名获取当前类的某个field(不包括父类)
Field[] getFields():获取所有public的field(包括父类)
Field[] getDeclaredFields():获取当前类的所有field(不包括父类)
- 通过字段获取对象对应字段的值
Field.get(Object obj)//获得字段值
Field.set(Object, Object)//设置字段值
Field.setAccessible(true)//private的字段也可以访问 |
- java.lang.reflect.Method类
- Class对象获取
Method getMethod(name, Class…):获取某个public的Method(包括父类)
Method getDeclaredMethod(name, Class…):获取当前类的某个Method(不包括父类)
Method[] getMethods():获取所有public的Method(包括父类)
Method[] getDeclaredMethods():获取当前类的所有Method(不包括父类)
- 方法信息方法名 返回值类型 参数类型 修饰符
getName():返回方法名称,例如:”getScore”;
getReturnType():返回方法返回值类型,也是一个Class实例,例如:String.class;
getParameterTypes():返回方法的参数类型,是一个Class数组,例如:{String.class, int.class};
getModifiers():返回方法的修饰符,它是一个int,不同的bit表示不同的含义。
- 调用
- invoke | |
- java.lang.reflect.Constructor类
|
- 动态代理
- 生成字节码
| |
- 还可以拿到实例化对象字段的值
|
Java注解Annotation
- java.lang.annotation.Annotation接@Interface默认继承的接口 - java.lang.annotation.RetentionPolicy枚举 - SOURCE-CLASS-RUNTIME - java.lang.annotation.ElementType枚举 - TYPE - java.lang.Deprecate注解 - 所标注内容,不再被建议使用。 - java.lang.Override注解 - 只能标注方法,表示该方法覆盖父类中的方法。 |
- 元注解MetaAnnotation - java.lang.annotation.Documented(将此注解包含再javadoc中) - java.lang.annotation.Retention(表示再什么级别保存该注解信息) - java.lang.annotation.Target(表示该注解可以用于什么地方) - java.lang.annotation.Inherited(允许子类继承父类中的注解) |
- 使用注解 - 定义注解 - 处理注解 |
---|---|---|
Java泛型Generics
- 类型参数TypeParameters
- 形式参数实际参数
|
- 实现原理
- 类型擦除替换
- 不支持基本类型
|
- 泛型形参标识符
- E
- K
- V
- N
- ?
|
- 通配https://segmentfault.com/a/1190000005337789#item-3-3
- extends通配符上界<? extends Number>
- super通配符 下界<? super Number>
- <?>无界通配符
| | —- | —- | —- |
JVMJava虚拟机JavaVirtualMachine
- JVM支持的其他语言
- Groovy-Scala-Kotlin
- Java系统属性JAVA_HOME、PATH、CLASSPATH
- HotSpotVM JRockit虚拟机StrongTalkhttps://blog.csdn.net/tianshuhao/article/details/89819214
- 发展史https://www.cnblogs.com/guchunchao/p/10497177.html
- 初衷-跨设备运行代码
参考
|
- 参考
|
| | | —- | —- | —- |
JVM体系结构
- 类装载器子系统ClassLoaderSubsystem
- 运行时数据区RuntimeDataArea
- 执行引擎ExecutiveEngine
JVM参数-调优
- 非标准参数(-X) - -Xms20m :设置jvm初始化堆大小为20m,一般与-Xmx相同避免垃圾回收完成后jvm重新分。 - -Xmx20m:设置jvm最大可用内存大小为20m。 - -Xmn10m:设置新生代大小为20m。 - -Xss128k:设置每个线程的栈大小为128k。 |
- 标准参数(-) - -version -help - -verbose:class,-verbose:gc,-verbose:jni |
非Stable参数(-XX) |
---|---|---|
记忆参考 https://baijiahao.baidu.com/s?id=1663410856124616488&wfr=spider&for=pc |
https://www.cnblogs.com/wjh123/p/11080121.html |
ClassLoaderSubsystem类装载器子系统
| 类的生命周期
| 参考
-
| 面试
|
| —- | —- | —- |
| Bootstrap CLassloder
Extention ClassLoader
AppClassLoader
sun.misc.Launcher最先被初始化
sun.boot.class.path
java.ext.dirs
java.class.path
加载
- 通过类的全限定名读取Java字节码代码(.class文件)到内存中
- 并在方法去创建java.lang.Class类的一个实例(每个实例代表一个Java类)。
- 将常量池中的符号引用和字面量放到运行时常量区
> 加载阶段是类加载过程的第一个阶段。在这个阶段,JVM 的主要目的是将字节码从各个位置(网络、磁盘等)转化为二进制字节流加载到内存中,接着会为这个类在 JVM 的方法区创建一个对应的 Class 对象,这个 Class 对象就是这个类各种数据的访问入口。
相关类
- 类结构
- Launcher launcher; 类 java的入口类
- ClassLoader 抽象类;loadClass 方法getParent方法 findLoadedClass findClass
- URLClassLoader 实现类
- ExtClassLoader 实现类 Launcher子类
- AppClassLoader 实现类 Launcher子类
- https://blog.csdn.net/how_interesting/article/details/80091472
- 加载器
- AppClassLoader appClassLoader;java代码
- ExtClassLoader extClassLoader;java代码 负责加载\lib\ext下面的.class文件
- findBootstrapClass c++代码 java本地方法接口 负责 lib目录下文件
- 工作模式 双亲委派
- 类的分类
- 系统类 rt.jar
- 扩展类 ext文件夹下的
- 程序员自定义的类 classpath下的
- 加载方式
- java命令 指定类
- 隐式 第一次 new的时候
- 调用静态方法时候
- forname方法显式
- 加载的动态性
- 用到了 在加载 节省内存
| 连接
- 验证
> 验证是否符合jvm字节码的规范,版本对不对准备
> 为类变量分配内存并初始化,初始化的值是0值或null static-final例外解析
> 符号引用替换成直接其在内存中的直接引用| 类的初始化> 类初始化(构造)方法
编译器完成 把静态变量的赋值,静态块代码 按照顺序集中到一起 就是类的初始化方法
|
JVM运行时数据区RuntimeDataArea=JVM内存结构
| 方法区MethodArea
- 存储内容: 类的元数据MetaData描述信息
- 参考运行时常量池(Runtime Constant Pool)
- 内容: 存放jvm对class文件的常量池信息
class文件常量池(Class Constant Pool)
用于存放编译器生成的各种字面量(Literal)和符号引用(Symbolic References)。
- 字面量 123 hollis就是
int a = 123;
String s = “hollis”;
- 符号引用
类和接口的全限定名 字段的名称和描述符 方法的名称和描述符
字符串常量池(StringConstantPool)
| 堆(Heap)
- 存储内容: 存放程序实例化的对象
- 逻辑划分: 根据对象的在内存中存活时间的不同 划分为 新生代、老年代和永久代(java8已经没有了)NewGeneration, OldGeneration
-
| | —- | —- | —- | | 虚拟机栈(Stack)栈帧(Stack Frame)调用栈callstack
方法执行的内存模型
- 内容: 一个方法对应一个帧栈 存有 局部变量表
- 大小 : 有限的
- TLAB(Thread Local Allocation Buffer)
| 程序计数器寄存器ProgramCounterRegister
- 内容 : 下一条指令的地址
- 大小 : 最小的
| 本地方法栈(NativeMethodStack)**
- 内容: 区别于虚拟机栈 方法信息存的是本地的
- JNI :JNI是JavaNativeInterface
| | 直接内存不受虚拟机管理的一片区域,操作系统管理,java调用本地方法创建的
- 问题
静态变量 Class对象实例 存到哪里
如何验证呢
|
- 参考
http://www.hollischuang.com/archives/2374 | |
JavaGC(GarbageCollection)Java垃圾回收
| System.gc();//告诉虚拟机来一次垃圾回收 来不来不一定
finalize()
回收区域
- 方法区
- 堆
| 对象判定回收之前的判定方法 GC算法的基础
- 引用计数法
> 每个对象添加一个引用计数器,每被引用一次,计数器加1,失去引用,计数器减1,当计数器在一段时间内保持为0时,该对象就认为是可以被回收得了
- 无法解决互相引用
- 参考
https://blog.csdn.net/u013077468/article/details/79603497
- 可达性分析算法
> 根搜索算法是从离散数学中的图论引入的,程序把所有的引用关系看作一张图,从一个节点GC ROOT开始,寻找对应的引用节点,找到这个节点以后,继续寻找这个节点的引用节点,当所有的引用节点寻找完毕之后,剩余的节点则被认为是没有被引用到的节点,即无用的节点
java中可作为GC Root的对象有
- 虚拟机栈中引用的对象(本地变量表)
- 本地方法栈中引用的对象
- 方法区中静态属性引用的对象
- 方法区中常量引用的对象
- 参考
- https://blog.csdn.net/luzhensmart/article/details/81431212
|
- Young(年轻代)
- 一个Eden区,两个Survivor区
- Tenured(年老代)
- Perm(持久代)
- 新生代、旧生代、持久代
- New Generation或者Young Generation
|
| —- | —- | —- |
| 标记-清除算法(Mark-Sweep)> 首先标记(用的可达性分析)出所有需要回收的对象,在标记完成后统一回收所有被标记的对象,遍历
缺点:
- 时间:遍历法,太慢了
- 空间:内存碎片,不连续的空间太多,实例化大对象的时候又需要GC
| 标记-整理(或叫压缩)算法(Mark-Compact)> 标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存| 复制算法(Copying)> 当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。这样使得每次都是对整个半区进行内存回收,内存分配时也就不用考虑内存碎片等复杂情况,只要移动堆顶指针,按顺序分配内存即可,实现简单,运行高效
实际HotSpot 虚拟机默认 Eden 和 Survivor 的大小比例是 8:1:1
| | 分代收集算法> 在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法,标记整理只需要付出少量存活对象的复制成本就可以完成收集。而老年代中因为对象存活率高、没有额外空间对它进行分配担保,就必须使用“标记-清理”或者“标记一整理”算法来进行回收综合了前面算法的优点,划分代配合使用
| 参考
| 垃圾收集器
- 串行GC(SerialGC)
- 并行回收GC(Parallel Scavenge)
- 并行GC(ParNew)
|
JVM内存分配
Java对象模型JavaObjectModel Java对象结构JavaObjectStructure
| c++底层OOP-Klass Model
。
OOP(Ordinary Object Pointer
)指的是普通对象指针Klass
用来描述对象实例的具体类型。
- OOP或OOPS(Ordinary Object Pointer)指的是普通对象指针,主要职能是表示对象的实例数据,存储在堆里面
- Klass用来描述对象实例的具体类型,实现语言层面的Java类,存储在元空间(方法区)
| 对象结构
- 对象头(Header)
- 元数据指针ClassMetaData 就是Class类对象指针
- 标记词mark word 并发编程相关
- 实例数据(InstanceData)
- 对齐填充(Padding)
虚拟机要求 对象内存字节数必须8的倍数
| 参考
对象内存Java Object Layout: Core
对象头 | | —- | —- | —- |
执行引擎(ExecutiveEngine)
|
- 即时编译器(JITCompiler,just-in-time compiler)
即时编译器(Just In Time Compiler),也称为 JIT 编译器 解释器(Interpreter)热点代码(HotSpotCode)
- 解释
- 自适应优化
| 参考 |
|
| —- | —- | —- |
Java内存模型JavaMemoryModel-JMM
| 计算机内存模型Memory Model
- 原因:cpu太快,主存太慢,所以需要高速缓存
- cpu读取数据按照层级关系,
- 模型:cpu(寄存器)->高速缓存->主存
- 多核cpu拥有多套缓存
- 任务管理器查看
确实是3级缓存 逻辑处理器8个
| 问题(硬件软件优化升级导致的)> - 缓存一致性问题其实就是可见性问题。
多核多线程每个核的自己的缓存中,关于同一个数据的缓存内容可能不一致.
- 处理器优化是可以导致原子性问题的。
那就是为了使处理器内部的运算单元能够尽量的被充分利用,处理器可能会对输入代码进行乱序执行处理,我理解为切换线程指令
- 指令重排即会导致有序性问题
指令重排的目的是为了在不改变程序执行结果的前提下,优化程序的运行效率
数据安全性> 我们说,并发编程,为了保证数据的安全,需要满足以下三个特性:
原子性是指在一个操作中就是cpu不可以在中途暂停然后再调度,既不被中断操作,要不执行完成,要不就不执行。 可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。 有序性即程序执行的顺序按照代码的先后顺序执行。
内存模型> 为了保证共享内存的正确性(可见性、有序性、原子性),内存模型定义了共享内存系统中多线程程序读写操作行为的规范
> 方式:限制处理器优化和使用内存屏障
Java内存模型> Java内存模型(Java Memory Model ,JMM)就是一种符合内存模型规范的,屏蔽了各种硬件和操作系统的访问差异的,保证了Java程序在各种平台下对内存的访问都能保证效果一致的机制及规范。
JMM是一种规范,目的是解决由于多线程通过共享内存进行通信时,存在的本地内存数据不一致、编译器会对代码指令重排序、处理器会对代码乱序执行等带来的问题。
具体> Java内存模型规定了所有的变量都存储在主内存中,每条线程还有自己的工作内存,线程的工作内存中保存了该线程中是用到的变量的主内存副本拷贝,线程对变量的所有操作都必须在工作内存中进行,而不能直接读写主内存。不同的线程之间也无法直接访问对方工作内存中的变量,线程间变量的传递均需要自己的工作内存和主存之间进行数据同步进行。
> Java内存模型,除了定义了一套规范,还提供了一系列原语,封装了底层实现后,供开发者直接使用。
volatile、synchronized、final、concurren包
- 参考
http://www.hollischuang.com/archives/1003
https://zhuanlan.zhihu.com/p/85403728
https://www.cnblogs.com/xdecode/p/8948277.html | |
| —- | —- | —- |
Java执行过程
- 编写helloworld.java文件
- javac.exe 文件 编译 helloworld.java 生成 helloworld.class字节码 二进制的文件
- java.exe虚拟机程序 解释 生成机器码
.classByteCode字节码文件
- 命令
- javap -v HelloWorld
- 参考