1、new创建新对象
2、通过反射机制
3、采用clone机制
4、通过序列化机制
前两者都需要显式地调用构造方法. 对于clone机制,需要注意浅拷贝和深拷贝的区别,对于序列化机制需要明确其实现原理,在java中序列化可以通过实现Externalizable或者Serializable来实现.
equals()
,clone()
,getClass()
,notify(),notifyAll(),wait()
,toString
在一个java文件中只能有一个public公共类,但是可以有多个default修饰的类.
浅拷贝:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅拷贝仅仅复制所考虑的对象,而不复制它所引用的对象.
深拷贝:被复制对象的所有变量都含有与原来的对象相同的值.而那些引用其他对象的变量将指向被复制过的新对象.而不再是原有的那些被引用的对象.换言之.深拷贝把要复制的对象所引用的对象都复制了一遍.
被final修饰的类不可以被继承
被final修饰的方法不可以被重写
被final修饰的变量不可以被改变.如果修饰引用,那么表示引用不可变,引用指向的内容可变.
被final修饰的方法,JVM会尝试将其内联,以提高运行效率
被final修饰的常量,在编译阶段会存入常量池中.
静态变量存储在方法区,属于类所有.实例变量存储在堆当中,其引用存在当前线程栈.需要注意的是从JDK1.8开始用于实现方法区的PermSpace被MetaSpace取代了.
String和StringBuffer主要区别是性能:String是不可变对象,每次对String类型进行操作都等同于产生了一个新的String对象,然后指向新的String对象.所以尽量不要对String进行大量的拼接操作,否则会产生很多临时对象,导致GC开始工作,影响系统性能.
StringBuffer是对象本身操作,而不是产生新的对象,因此在有大量拼接的情况下,我们建议使用StringBuffer(线程安全).
StringBuffer和StringBuilder的实现原理一样,其父类都是AbstractStringBuilder.StringBuffer是线程安全的,StringBuilder是JDK 1.5新增的,其功能和StringBuffer类似,但是非线程安全.因此,在没有多线程问题的前提下,使用StringBuilder会取得更好的性能.
线程安全就是在多线程环境下也不会出现数据不一致,而非线程安全就有可能出现数据不一致的情况。
线程安全由于要确保数据的一致性,所以对资源的读写进行了控制,换句话说增加了系统开销。
多线程环境下,线程安全比非线程安全的效率要高,
而在在单线程环境中,线程安全比非线程安全的效率要低些,
但是如果线程间数据相关,需要保证读写顺序,用线程安全模式
JVM中垃圾回收机制最基本的做法是分代回收.内存中的区域被划分成不同的世代,对象根据其存活的时间被保存在对应世代的区域中.一般的实现是划分成3个世代:年轻,年老和永久代.所有新生成的对象优先放在年轻代的(大对象可能被直接分配在老年代,作为一种分配担保机制),年轻代按照统计规律被分为三个区:一个Eden区,两个 Survivor区.在年轻代中经历了N次垃圾回收后仍然存活的对象,就会被放到年老代中.因此可以认为年老代中存放的都是一些生命周期较长的对象.
方法区也被称为永久代,用于存储每一个java类的结构信息:比如运行时常量池,字段和方法数据,构造函数和普通方法的字节码内容以及类,实例,接口初始化时需要使用到的特殊方法等数据,根据虚拟机实现不同,GC可以选择对方法区进行回收也可以不回收.
对于不同的世代可以使用不同的垃圾回收算法。比如对由于年轻代存放的对象多是朝生夕死,因此可以采用标记-复制,而对于老年代则可以采用标记-整理/清除.
Minor GC
发生在新生代的GC为Minor GC .在Minor GC时会将新生代中还存活着的对象复制进一个Survivor中,然后对Eden和另一个Survivor进行清理.所以,平常可用的新生代大小为Eden的大小+一个Survivor的大小.
Major GC
在老年代中的GC则为Major GC.
Full GC
通常是和Major GC等价的,针对整个新生代,老年代,元空间metaspace(java8以上版本取代perm gen)的全局范围的GC.
关于GC的类型,其实依赖于不同的垃圾回收器.可以具体查看相关垃圾回收器的实现.
内部类可以有多个实例,每个实例都有自己的状态信息,并且与其他外围对象的信息相互独立.在单个外围类当中,可以让多个内部类以不同的方式实现同一接口,或者继承同一个类.创建内部类对象的时刻不依赖于外部类对象的创建.内部类并没有令人疑惑的”is-a”关系,它就像是一个独立的实体.此外,内部类提供了更好的封装,除了该外围类,其他类都不能访问.
JDK: 顾名思义它是给开发者提供的开发工具箱,是给程序开发者用的。它除了包括完整的JRE(Java Runtime Environment),Java运行环境,还包含了其他供开发者使用的工具包。
JRE:普通用户而只需要安装JRE(Java Runtime Environment)来 来运行Java程序。而程序开发者必须安装JDK来编译、调试程序。
主要作用是完成对类对象的初始化工作。可以执行。因为一个类即使没有声明构造方法也会有默认的不带参数的构造方法。
HashMap 在并发执行 put 操作时会引起死循环,导致 CPU 利用率接近100%。因为多线程会导致 HashMap 的 Node 链表形成环形数据结构,一旦形成环形数据结构,Node 的 next 节点永远不为空,就会在获取 Node 时产生死循环。
了解了 HashMap 为什么线程不安全,那现在看看如何线程安全的使用 HashMap。这个无非就是以下三种方式:
1、Hashtable
当一个线程访问 HashTable 的同步方法时,其他线程如果也要访问同步方法,会被阻塞住。举个例子,当一个线程使用 put 方法时,另一个线程不但不可以使用 put 方法,连 get 方法都不可以效率很低,现在基本不会选择它了。
2、ConcurrentHashMap
ConcurrentHashMap 于 Java 7 的,和8有区别,在8中 CHM 摒弃了 Segment(锁段)的概念,而是启用了一种全新的方式实现,利用 CAS 算法,有时间会重新总结一下。
3、SynchronizedMap
synchronizedMap() 方法后会返回一个 SynchronizedMap 类的对象,而在 SynchronizedMap 类中使用了 synchronized 同步关键字来保证对 Map 的操作是线程安全的。
类加载过程:加载、验证(验证阶段作用是保证Class文件的字节流包含的信息符合JVM规范,不会给JVM造成危害)、准备(准备阶段为变量分配内存并设置类变量的初始化)、解析(解析过程是将常量池内的符号引用替换成直接引用)、初始化。
双亲委派模型中方法:双亲委派是指如果一个类收到了类加载的请求,不会自己先尝试加载,先找父类加载器去完成。当顶层启动类加载器表示无法加载这个类的时候,子类才会尝试自己去加载。当回到最开的发起者加载器还无法加载时,并不会向下找,而是抛出ClassNotFound异常。
方法:启动(Bootstrap)类加载器,标准扩展(Extension)类加载器,应用程序类加载器(Application ),上下文(Custom)类加载器。意义是防止内存中出现多份同样的字节码 。
1、防止重复加载同一个.class
。通过委托去向上面问一问,加载过了,就不用再加载一遍。保证数据安全。
2、保证核心.class
不能被篡改。通过委托方式,不会去篡改核心.clas
,即使篡改也不会去加载,即使加载也不会是同一个.class
对象了。不同的加载器加载同一个.class
也不是同一个Class
对象。这样保证了Class
执行安全。
jvm是如何判断一个对象已经变成了可回收的“垃圾”,一般是两个方法:引用记数法和根搜索算法。引用记数法没办法解决循环引用的问题,所以用根搜索。从一系列的”GC Roots“对象开始向下搜索,搜索走过的路径称为引用链。当一个对象到”GC Roots“之间没有引用链时,被称为引用不可达。引用不可到的对象被认为是可回收的对象。
几种垃圾收集器:1,Serial New/Serial Old(串行),2,Parrallel New (并行),3,Parrallel Scavenge,4,Parrallel Old,5,CMS(CMS收集器是一个以获得最短回收停顿时间为目标的收集器,它是一种并发收集器,采用的是Mark-sweep算法。),6,G1(是一款并行与并发收集器,并且可建立可预测的停顿时间模型,整体上是基于标记清理,局部采用复制)
1)方法区(method):被所有的线程共享。方法区包含所有的类信息和静态变量。
2)堆(heap):被所有的线程共享,存放对象实例以及数组,Java堆是GC的主要区域。
3)栈(stack):每个线程包含一个栈区,栈中保存一些局部变量等。
4)程序计数器:是当前线程执行的字节码的行指示器。
持久代主要存放的是Java类的类信息,与垃圾收集要收集的Java对象关系不大。所有新生成的对象首先都是放在年轻代的,年老代中存放的都是一些生命周期较长的对象。
1)管道(Pipe),2)命名管道(named pipe),3)信号(Signal),4)消息(Message)队列,5)共享内存,6)内存映射(mapped memory),7)信号量(semaphore),8)套接口(Socket)