Java基础知识复习
本文为记录从java基础开始中遇到的难点及盲点,供复习与参考使用
Java中实现多态的机制
- 靠父类活接口的引用类型指向子类或实现类的实例对象,程序调用的方法才在运行期动态绑定,就是引用变量所指向的具体实例对象的方法,就是内存中正在运行的对象的方法,而不是变量中类型定义的方法.
synchronized和java.util.concurrent.locks.Lock的异同
- Lock能完成synchronized所实现的所有功能
- 不同:Lock比synchronized更精确的线程语义和更好的性能.synchronized会自动释放锁,而Lock一定要求手动释放.并且在finally从句中释放.
HashMap和HashTable的区别
- HashTable继承Dictionary类,HashMap是Map接口的实现
- HashTable是线程安全的,HashMap是线程不安全的
- HashMap可以使用null作为value或key
什么类型类在switch语句中使用
- 比int小的类型都可以隐式转换为String,都是可以的,但是大于int的都不行
final修饰变量,是引用不能变,还是引用的对象不能变
- 是引用变量不能变,引用指向的对象的内容还是可以改变的.
深拷贝和浅拷贝
- 使用clone()方法,基本类型是复制值,引用是复制地址,所以指向了相同的对象,此为浅拷贝.
- 如果需要重新创建对象需要实现Cloneable接口,,实现clone方法.被引用的对象也必须实现Cloneable接口并实现clone方法.
下列Integer类型数值的比较输出的结果
1 | Integer f1 = 100,f2 = 100,f3 = 150,f4 = 150; |
- 在Integer源码中如果字面量在-128到127之间就不会new新的Integer对象,而是直接使用常量池中的对象,所以结果为treu,false
Map
- Map 接口有三个实现类(HashMap:基于 hash 表的 Map 接口实现,非线程安全,高效,支持 null 值和 null 键;HashTable:线程安全,低效,不支持 null 值和 null 键;LinkedHashMap:是 HashMap 的一个子类,保存了记录的插入顺序;SortMap 接口:TreeMap,能够把它保存的记录根据键排序,默认是键值的升序排序)。
- 两者的key值均不能重复,若添加key相同的键值对,后面的value会覆盖前面的value
创建的线程池
- 在java.util.concurrent.Executors提供了生产多线程池的静态方法
- newSingleThreadExecutor:创建一个单线程的线程池,此线程池保证所有的任务的执行顺序按照的任务的提交顺序执行
- newFixedThreadPool:创建固定大小的线程池,每次提交一个认为就创建一个线程,直到线程达到线程池的最大容量
- newCachedThreadPool:创建一个可缓存的线程池,此线程池不会对线程池的大做限制,待笑傲完全依赖jvm能够创建的最大线程大小
- newScheduledThreadPool:创建一个大小无限的线程池,此线程池支持定时以及周期性执行任务的需要
- newSingleThreadExecutor:创建一个单线程线程,此线程支持定时及周期性执行任务的要求
- 以Pool结尾的为线程池,以Executors结尾的为线程执行器
进程和线程的区别
- 进程:具有一定孤立功能的程序关于每个数据集合上的一次运行活动,是操作系统资源调度和分配的一个独立单位
- 线程:是线程的一个实体,是cpu调度和分配的基本单位,是比进程更小的可以独立运行的基本单位
- 特点:线程的划分尺度小于进程,这使得多线程程序拥有高并发性,进程在运行时各自内存单元相互独立,线程之间内存共享,
工程模式
- 普通工程模式
- 根据传入的条件判断后返回不同的实例,不返回添加则不返回实例
- 静态工程模式
- 将工程方法中的方法置为静态,不需要创建工程类实例
- 抽象工厂模式
- 工厂方法如果休要添加新的类则要修改工程类,违背了闭包的原则,可以使用抽象工程模式,创建多个工程类,有新功能直接添加新的工程类就可以
建造者模式(Builder)
- 工厂类模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来进行管理,用来创建复合对象所谓复合对象就是指某个类具有不同的属性,其实建造者模式就是前面抽象工厂模式和最后的 Test 结合起来得到的。
- 我的理解:在一个类中将不同类的属性拼接整合后返回
适配器设计模式
- 适配器将某个类的接口转换为客户端期望的另一个接口表示,目的是消除接口不匹配造成的类的兼容性问题,主要有:类的适配器模式,对象的适配器模式,接口的适配器模式.
- 类的适配器模式:一个类继承了一个类实现了一个接口.在接口中定义了一个新的方法.
- 对象的适配器模式,基本思路与类的适配器基本相同,只是不在继承类,而是持有父类的实例
- 接口的适配器模式:我们写的一个接口中有多个抽象方法,当我们写该接口的实现类时,必须实现该接口的所有方法,这有时是浪费的,为了解决这个问题我们借助于一个抽象类,该抽象类实现了该接口,实现了所有的方法,而我们不与原始的接口打交道,继承抽象类,重写需要的方法.
装饰模式(Decorator)
- 装饰模式就是给一个对象增加一些新功能,而且是动态的,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例
- 我的理解:一个接口其中有一个方法,a类实现了接口,b也实现了接口,并在其内部创建了a,在自己的构造中要求传入a类,并将其赋值给自己的局部变量.在b类中重写接口中的方法,在方法中添加需要装饰的功能,并且调用了a类的方法.在测试类中,首先new a类,传入b类的构造中获得一个b类,在b类中调用接口中的方法,此方法就是b类中写的方法,实现了动态修改a类中方法的效果.
JVM垃圾回收机制和常见算法
- 不同的厂商的JVM采用的算法不尽相同.
- 如何发现无用的对象,采用的搜索算法如下:
- 引用计数器:每个对象应用时计数器+1,应用失效时-1.该算法简单效率高,但是无法判断循环引用的问题,所以此算法不再被使用
- 根搜索算法
- 根搜索算法是通过一些“GC Roots”对象作为起点,从这些节点开始往下搜索,搜索通过的路径成为引用链
(Reference Chain),当一个对象没有被 GC Roots 的引用链连接的时候,说明这个对象是不可用的 - GC Roots 对象包括:
- 虚拟机栈(栈帧中的本地变量表)中的引用的对象。
- 方法区域中的类静态属性引用的对象。
- 方法区域中常量引用的对象。
- 本地方法栈中 JNI(Native 方法)的引用的对象。
- 根搜索算法是通过一些“GC Roots”对象作为起点,从这些节点开始往下搜索,搜索通过的路径成为引用链
JVM中的内存结构和内存分配
java虚拟机将管辖的内存大致分为三个部分:方法区,java栈,java堆
- 方法区是静态的,编译器将变量绑定在某个位置上,并且这些绑定在运行不会改变.例如:常量池,源代码中的命名常量,string的常量,static变量存储在方法区
- java stack是一个逻辑概念,特点是后进先出,一个栈可能是连续的,也可能是不连续的.
最典型的Stack应用是方法的调用,java虚拟机每调用一次方法就创建一个方法栈,退出时方法对应的方法栈被弹出(pop) - java堆分配(heap allocation)意味着以任意的顺序,在运行时进行存储空间分配和回收的内存管理.
Java中引用类型都有那些(重要)
- java中对象的引用分为四种级别,从高到低分为:强引用,软引用,弱引用和虚引用
- Java 的对象是位于heap 中的,heap 中对象有强可及对象、软可及对象、弱可及对象、虚可及对象和不可到达对象。应用的强弱顺序是强、软、弱、和虚。对于对象是属于哪种可及的对象,由他的最强的引用决定。
1 | String abc=new String("abc"); |
- 第一行的对象是强引用,是强可及的
- 第二行创建对象的软引用和弱引用,对象仍然是强可及的
- 第四行后对象不再是强可及,变成软可及的
- 第五行执行后变成软可及
区别
强引用:如果一个对象被被人拥有强引用,那么垃圾回收器绝不会回收它。当内存空间不足,Java 虚拟机宁愿抛出 OutOfMemoryError 错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足问题。
软引用:如果一个对象只具有软引用,那么如果内存空间足够,垃圾回收器就不会回收它,如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。
弱引用:如果一个对象只具有弱引用,那该类就是可有可无的对象,因为只要该对象被 gc 扫描到了随时都会把它干掉。弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过, 由于垃圾回收器是一个优先级很低的线程, 因此不一定会很快发现那些只具有弱引用的对象。
虚引用:”虚引用”顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。虚引用主要用来跟踪对象被垃圾回收的活动。