以下均是自己对学习的理解,理解可能偏差
- java 编译与反编译
发展:机器语言--汇编语言--高级语言,例如java 。
编译: 高级语言需要转换成机器能够识别的机器语言运行,java 通过javac编译器将.java文件编译成.class字节码文件,然后JVM java虚拟机将class文件转换成机器语言,这就是java语言运行的过程
反编译:过程和编译刚好相反,java反编译即将.class文件转换为.java文件
反编译工具:javap、jad、cfr
编译流程:源代码 - 词法分析 - 符号流 - 语法分析 - 语法树 - 语义分析 - 语法树 - 中间代码生成 - 中间代码 - 代码优化 - ---机器语言
问题:编译解释再执行,速度比可执行字节码慢很多,为解决该问题引入JIT技术--热点代码检测优化,基于计数器的热点探测方法--方法调用计数器,回边计数器, 编译优化
-
JVM、java语言规范(如基本数据类型在所有平台的一致性)及编译成统一的.class文件保证其跨平台性
-
值传递和引用传递
值传递:创建副本copy,不改变原始对象
引用传递:不创建副本,可以改变原始对象
Java是值传递,只是传递的内容是基本数据类型和对象的引用,这两者原始对象都不会被改变 -
八种数据类型 1字节=8位(bit)
字符:char
整型:byte 1字节 short 2字节 int 4字节 long 8字节
布尔:boolean
浮点型:float 4字节 double 8字节 二进制的表示,很多小数是没法精确表示出来,所以去近似值表现法,所以不能表示金额,建议BigDecimal 或Long
溢出,基础数据类型溢出的时候并不会抛异常,也没有任何提示
Java中,为什么byte类型的取值范围为-128~127?
机器数、真值、原码、反码、补码 为了运算
除法变成乘法,,乘法变成加法,减法变成加法,计算机运算
包装类,自动装箱,自动拆箱 --有缓存,复用,节约空间
Java中整型的缓存机制 -
字符串的不可变性
一旦一个string对象在内存(堆)中被创建出来,他就无法被修改。特别要注意的是,String类的所有方法都没有改变字符串本身的值,都是返回了一个新的对象。
如果你需要一个可修改的字符串,应该使用StringBuffer 或者 StringBuilder。否则会有大量时间浪费在垃圾回收上,因为每次试图修改都有新的string对象被创建出来。
6 String对“+”的重载
String s = "a" + "b",编译器会进行常量折叠(因为两个都是编译期常量,编译期可知),即变成 String s = "ab"
对于能够进行优化的(String s = "a" + 变量 等)用 StringBuilder 的 append() 方法替代,最后调用 toString() 方法 (底层就是一个 new String())
7 字符串拼接
使用+拼接字符串 --->底层使用了StringBuilder
concat方法来拼接字符串 --> 创建了一个字符数组
使用StringBuffer、StringBuilder可以方便的对字符串进行拼接,StringBuilder不是线程安全
耗时:StringBuilder<StringBuffer<concat<+<StringUtils.join
循环体内不要用+
8 switch 对String的支持
switch只支持一种数据类型,那就是整型,其他数据类型都是转换成整型之后再使用switch的。
char -> 比较ascii码,string 比较hashcode,再通过equals进行检查
9 intern
JVM为了减少字符重复创建,节省内存,会单独开辟一块内存,保存字符串常量,称为字符串常量池,
当出现双引号创建字符串时,会先检查常量池,存在相同内容的对象引用就返回引用,否则创建新的,并将引用放进常量池,
使用intern 将字符串内容放到常量池
10 双亲委派
JVM有四种类加载器,Bootstrap ClassLoader(加载核心类库),Extension ClassLoader(加载扩展类库ext目录),Application ClassLoader(加载当前应用classpath的所有类), User ClassLoader(自定义加载)
image.png
层次依次降低,双亲委派:当一个类加载器收到类加载请求,不会马上去加载,而是委托给父类加载器加载,父类加载器无法加载时,才由当前指定的类加载器加载。
实现方法:loadClass(),重写loadClass可破坏双亲委派机制,不想破坏,重写findClass(),loadClass父加载失败会调用自身的findClass()方法,很多框架会主动破坏双亲委派机制,比如Tomcat作为web容器,可能部署多个服务,服务可能引用相同jar,但版本不一致,采用默认双亲委派,无法加载多个相同类,所以为了实现隔离,优先加载web应用自身定义的类
随着jdk发展,模块化技术应用,加载机制也变成复杂的网状结构
双亲委派
11 Java内存模型
计算机硬件,CPU 和内存执行速度的差异,增加缓存,多线程情况下存在缓存一致性问题,对代码的乱序执行,为指令重排
软件:对应的是可见性问题(一个线程的修改,其他线程要能看到),原子性(一个操作必须连续完成,不能终端),有序性(必须保证多线程下的执行顺序)
原子性: synchronized(影响性能)->需要通过字节码指令monitorenter和monitorexit保证
可见性: volatile(被其修饰的变量在被修改后可以立即同步到主内存)、final、synchronized
有序性: volatile(禁止指令重排优化)、synchronized
12 Java 虚拟机锁优化技术
线程状态自旋锁:时间很短的线程,时刻检查共享资源是否可以被访问,因为等待时间很短,放弃处理器执行时间,等待被唤醒会很慢
锁消除:(逃逸分析)判断锁对象是否只被一个线程访问,即无线程安全问题
锁粗化:大部分时候减小锁的范围、粒度,避免不必要的阻塞,但如果连续对同一对象反复加锁解锁,相当耗费资源,这种情况可以适当放宽加锁范围
锁消除、锁粗化、偏向锁、适应性自旋锁尽在Java虚拟机server模式下起作用,运行Java时添加-server参数
13 集合
Collection、List、Set
ArrayList:可改变大小的数组,查询、修改性能好(数据量大),扩容50%
LinkedList:双链表,添加、删除性能好,实现了Queue接口,比List多offer(0,peek(),poll()等方法,
Vector:安全,扩容100%
网友评论