Java基础

Java 泛型super和extends的区别?

基类 A
A的子类A1,A1的子类 A2
A的子类B,B的子类B1
<? extends B> ?可以向下兼容本身和其子孙类,t可以是B1或者B
<?super B>?可以向上兼容,t可以是B,A。

static修饰符

1.static用于创建独立于对象的变量或者方法,在类被加载时就会创建。对象实例化之前就已经分配了内存。
2.类创建时加载顺序:静态变量 – 非静态变量 — 静态代码块 — 非静态代码块 — 构造方法
3.static修饰的方法可以被继承,子类直接调用父类的静态方法,但不能重写重写之后两个方法之间没有联系,哪个类调用就执行哪个。

final关键字

1final修饰类,被final修饰的类不能被继承
2final修饰的方法,子类不能重写父类被final修饰的方法。
3final修饰的变量必须要有初始值。final修饰的基本类型数据值不能改变,final修饰的引用类型数据,引用地址不能改变。
4内部类访问局部变量必须用final修饰。
为什么内部类访问局部变量必须用final修饰
编译时相当于内部类将局部变量复制了一遍,外部方法执行完毕之后,局部变量就会消亡(局部变量分配在JVM虚拟的栈中,这部分空间会随着程序执行完毕而回收)。用final修饰之后不会变成常量,不会随方法结束,
如果不用final修饰可能会造成内部类访问的局部变量还没有结束时,局部变量值发生了改变。
这也就是为什么线程访问变量必须用final修饰。因为new Thread相当于一个内部类

String StringBuffer和StringBUilder

1String类被final修饰,是个常量。每次改变值都是重新创建了一个对象,有个新的地址来保存他
2StringBuilder和StringBuffer是通过字符数组来保存保存字符串
3StringBuffer内部方法用Sync修饰,因此是线程安全的,StringBuilder是非线程安全.所以效率上StringBuilder比Buffer高

ArrayList,LinkedList,Vector.

ArrayList和Vector都是数组结构。数组大小大于实际存储元素个数,数组插入涉及到数组元素移动等内存操作,因此比较慢。Vector是线程安全的,因此比较慢。根据下标查找元素比较快
LinkedList的数据结构为双向链表,插入只需要记录本页的前后项,因此比较快。但是查找需要遍历比较慢。

HashMap,HashTable,ConcurrentHashMap,ArrayMap,SphraseArray

1 hashMap的数据结构为散列表,数组+链表。
2 hashTable的数据结构和HashMap相似,HashTable是同步的,因此效率比较低。
3 ConcurrentHashMap利用Segment来实现分段锁
4 ArrayMap数据存储时两个数组,一个存放hash值,一个存放key value,二分查找
5SpraseArray只能存储key为int类型的数据,并且key生序排列,二分查找。

序列化Serialable和Parcalable

序列化

序列化:是将对象信息转化为可以存储和传输的形式的过程。在序列化期间,对象将其状态写入到临时或者永久存储区,之后可以通过从存储区读取或者反序列化对象状态,重新创建对象。

Serializable

serializable使用时,只需要在需要序列化的类实现Serializabe接口。使用了反射技术,并且期间产生临时对象。
实现序列化步骤
1创建 FileInputStream对象。要保存的文件 FileInputStream fs = new FileInputStream(“a.sa”);
2创建 ObjectOutputStream 。ObjectOutpiutStream os = new ObjectOutPutStream(“fs”);
3 写入数据 WriteObject。 os.writeObject(object);
序列化
1序列化只对对象进行保存,而不管对象里的方法
2父类实现序列化,子类会自动实现序列化
3 当一个对象的实例引用其他对象,序列化该对象时也会序列化引用对象。

parcelable

parcelable的效率比Serializable高,在内存之间传递数据时可使用parcelable。
实现了parcelable的数据在序列化和反序列化的时候会把数据转化为parcel类型的数据
使用parceable时需要实现序列化WriteToParcel方法和反序列化的Caretor

JVM内存模型

在这里插入图片描述
Java程序的运行时,JVM会有一段空间来保存程序执行期间的数据和先关信息。JVM内存。

Java 栈stack

Java栈总是与线程关联的,每创建一个线程都会创建一个对应的栈。每个栈又会有多个栈帧,每个方法都会创建一个栈帧来保存他的信息,包括操作栈局部变量方法返回值等。每个方法执行完毕都会弹出该栈帧做为返回值。栈顶的栈帧
处于活动状态,pc寄存器也会指向该栈帧。
Java栈的异常情况,当栈的深度超过虚拟机所允许的最大深度,就汇报StackOverFlowError,如果虚拟机可动态扩展,当扩展无法申请到足够内存,就会报OutOfMemy异常。
线程私有的,生命周期与线程相连使用连续的内存空间。

堆heap

堆是内存管理中最大的一块,所有线程共享的,线程不安全的JVM启动时创建,存储java对象,java虚拟机规范中描述,所有对象和数组都在堆上分配。java堆时内存管理的主要空间,GC采用分代收集发,分为新生代和老年代。新生又分为 Eden,From Survivor ,To Survivor空间。

方法区

方法区也属于堆的一部分,通常所说的java堆中的永久区,用来存放类的信息,和类中的常量。方法区是线程锁共享的,不会被频繁的GC,但是当方法区使用最大内存超过其允许最大是也会被回收。
常量池属于方法区中的一个数据结构,保存一些常量

Native本地方法区

和java栈一样,但是是用来调用本地native服务的,也会抛出stackOverFlower和outofmm错误

程序计数器

程序计数器也是一种数据结构,保存当前执行程序的内存地址。Java中存在多线程,当线程执行有交叉,中断线程位置要保存下来,以便于中断线程继续执行,为了线程正确的执行下去,每个线程都有一个程序计数器,每个线程计数器互不干扰独立村存储。这类内存称为“线程私有”的内存,类似于ThreadLoad。线程安全

Java GC机制

当一个new Object对象被创建时,new Object()实例存放在堆,引用存放在栈。
GC回收机制主要是针对堆内存
分代回收,老年代和新生代,新生代分为Eden ,From Survior ToSurvior区
1绝大多数对象创建时会分配在Eden区,绝大多数对象会很快消亡,Eden时连续的内存地址,所以在分配上会很快。
2Eden区满时,执行Minor GC,清理消亡的对象,并将剩余的对象复制到From Survior区
3Eden区再次满时,清理消亡的对象,再将剩余对象复制到To Survior区。清理From Survior中的消亡对象,将可以晋级的对象放到old区,再将剩余的对象复制到 To Survior中,清空From Survior区,From 和To Survior总会有一个为空
4From 和To Survior切换多次之后仍然存活的对象放到old区,当老年代内存空间也不足时会执行Full GC。

线程和进程的区别

进程一个可以执行的程序,有自己的独立的内存地址,是系统进行资源分配最小单位。
线程存在于进程中,每个进程可以有多个线程。线程是程序执行烦人最小单位。
进程拥有独立的内存空间的内存空间,分为用户空间和内核空间,内核空间与硬件驱动。
线程拥有独立的堆栈,但是数据共享。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值