java基础总结

java基础

1.java中的“==”和equals()方法的区别

1
2
(1) ==,如果作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等;如果作用于引用类型的变量,则比较的是所指向的对象的地址.
(2) equals方法不能作用于基本数据类型的变量如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;可以对equals方法重写,比较的是所指向的对象的内容。

2.为什么不能用abstract修饰属性、私有方法、构造器、静态方法、final的方法

1
2
3
java中规定,abstract只能修饰类和方法
修饰的类为抽象类,抽象类不能实例化,需要子类继承并实现抽象方法。
修饰的方法为抽象方法,只有声明方法,并没有实现,需要子类继承实现

3.abstract class 和 interface的区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
抽象类:
含有abstract修饰符的class即为抽象类
abstract 类不能创建的实例对象。
含有abstract方法的类必须定义为abstract class
abstract class类中的方法不必是抽象的。
abstract class类中定义抽象方法必须在具体(Concrete)子类中实现,所以,不能有抽象构造方法或抽象静态方法。如果的子 类没有实现抽象父类中的所有抽象方法,那么子类也必须定义为abstract类型。

接口(interface):
接口中的所有方法都必须是抽象的
接口中的方法定义默认为public abstract类型
接口中的成员变量类型默认为public static final。

语法区别:
1.抽象类可以有构造方法,接口中不能有构造方法。
2.抽象类中可以有普通成员变量,接口中没有普通成员变量
3.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。
4. 抽象类中的抽象方法的访问类型可以是public,protected和(默认类型,虽然eclipse下不报错,但应该也不行),但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。
5. 抽象类中可以包含静态方法,接口中不能包含静态方法
6. 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,并且默认即为public static final类型。
7. 一个类可以实现多个接口,但只能继承一个抽象类。

4.对面向对象特征多态的理解

1
2
3
4
5
6
父类引用指向子类对象,可以调用子类重写的父类方法
基于继承实现的多态:对于引用子类的父类类型,在处理该引用时,它适用于继承该父类的所有子类,子类对象的不同,对方法的实现也就不同,执行相同动作产生的行为也就不同。
如果父类是抽象类,那么子类必须要实现父类中所有的抽象方法,这样该父类所有的子类一定存在统一的对外接口,但其内部的具体实现可以各异。这样我们就可以使用顶层类提供的统一接口来处理该层次的方法。

基于接口的多态:在接口的多态中,指向接口的引用必须是指定这实现了该接口的一个类的实例程序,在运行时,根据对象引用的实际类型来执行对应的方法。
继承都是单继承,只能为一组相关的类提供一致的服务接口。但是接口可以是多继承多实现,它能够利用一组相关或者不相关的接口进行组合与扩充,能够对外提供一致的服务接口。所以它相对于继承来说有更好的灵活性。

5.封装继承多态

1
封装可以隐藏实现细节,使得代码模块化;继承可以扩展已存在的代码模块(类);它们的目的都是为了——代码重用。而多态除了代码的复用性外,还可以解决项目中紧偶合的问题,提高程序的可扩展性.

6.String类的常用方法有哪些 ?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
String(byte[] bytes, String charsetName) 通过指定的字符编码解码直接数组构造新的string对象
charAt(int index)
concat(String str)
contains(CharSequence s)
endsWith(String suffix)
equals(Object anObject)
getBytes(Charset charset)
indexOf(int ch)
lastIndexOf(int ch)
length()
replace(char oldChar, char newChar)
split(String regex)
substring(int beginIndex)
toString()
trim()
toUpperCase()
toLowerCase()

7.java语句 String str = new String(“hello”);执行时,创建了几个对象?

1
2
2个对象
一个是在常量池创建一个“hello”的对象,另一个是new String()创建的对象

8.对序列化的理解

1
序列化是为了保存在内存中的各种对象的状态,经过流的传输,还可以把保存的对象状态再读出来。

9.什么是反射

1
2
3
4
5
反射机制指的是程序在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法。
反射获取对象的三种方式:
1) 对象.getClass()方法
2) Class.forName(String className)
3) 类名.class

10.什么是动态代理

1
利用Java的反射技术(Java Reflection),在运行时创建一个实现某些给定接口的新类(也称“动态代理类”)及其实例(对象)。代理的是接口(Interfaces),不是类(Class),更不是抽象类。

11.什么是多线程、线程的启动方式、线程安全问题如何解决

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
多线程:指的是一个程序(进程)运行时产生了不止一个线程。程序中有两个子系统需要并发执行,这时候就需要利用多线程编程。

创建线程的方法:
通过实现 Runnable 接口;
通过继承 Thread 类本身;
通过 Callable 和 Future 创建线程
调用start方法启动

线程安全问题如何解决
如何判断线程是否安全?
(1)是否 存在多线程环境
(2)在多线程环境下,是否有共享的变量
(3)在多线程环境下是否多共享变量进行写操作
只有三个条件同时满足,才会出现线程安全的问题
解决:
只要破坏上面的三个条件之一即可
对于2,不建议在成员的位置上定义变量
对于3,加锁(同步代码块)

12.解释protected

1
2
3
4
5
protected是java的权限修饰符,被protected修饰后,只有当前类、同包下的类以及子类能访问
public:所有位置的对象都能访问
protected:只有当前类、同包下的类、子类能访问
default(不写):只有当前类和同包下的类能访问
private:只有当前类能访问

13.StringBuilder和StringBuffer区别

1
StringBuilder是线程不安全的,而StringBuffer是线程安全的,运行速度上,StringBuilder较快

14.cglib和jdk的核心

1
2
3
4
5
6
7
8
9
静态代理:简单,代理模式,是动态代理的理论基础。常见使用在代理模式
jdk动态代理:需要有顶层接口才能使用,但是在只有顶层接口的时候也可以使用,常见是mybatis的mapper文件是代理。使用反射完成。使用了动态生成字节码技术。
cglib动态代理:可以直接代理类,使用字节码技术,不能对 final类进行继承。使用了动态生成字节码技术。

JDK代理是不需要第三方库支持,只需要JDK环境就可以进行代理,使用条件:
1)实现InvocationHandler 
2)使用Proxy.newProxyInstance产生代理对象
3)被代理的对象必须要实现接口
CGLib必须依赖于CGLib的类库,但是它需要类来实现任何接口代理的是指定的类生成一个子类,覆盖其中的方法,是一种继承但是针对接口编程的环境下推荐使用JDK的代理;

15.乐观锁和悲观锁

1
2
3
4
5
6
7
8
悲观锁
总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。Java中synchronized和ReentrantLock等独占锁就是悲观锁思想的实现。

乐观锁
总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和CAS算法实现。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁。在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式CAS实现的。

两种锁的使用场景
从上面对两种锁的介绍,我们知道两种锁各有优缺点,不可认为一种好于另一种,像乐观锁适用于写比较少的情况下(多读场景),即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。但如果是多写的情况,一般会经常产生冲突,这就会导致上层应用会不断的进行retry,这样反倒是降低了性能,所以一般多写的场景下用悲观锁就比较合适。

16.垃圾回收机制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
1)如何确定某个对象是需要被回收?
在java中是通过引用来和对象进行关联的,也就是说如果要操作对象,必须通过引用来进行。那么很显然一个简单的办法就是通过引用计数来判断一个对象是否可以被回收。不失一般性,如果一个对象没有任何引用与之关联,则说明该对象基本不太可能在其他地方被使用到,那么这个对象就成为可被回收的对象了。这种方式称为引用计数法。

以下三类对象在jvm中作为GC roots,来判断一个对象是否可以被回收 (通常来说我们只要知道虚拟机栈和静态引用就够了)

  1、虚拟机栈(JVM stack)中引用的对象(准确的说是虚拟机栈中的栈帧(frames)) 。我们知道,每个方法执行的时候,jvm都会创建一个相应的栈帧(栈帧中包括操作数栈、局部变量表、运行时常量池的引用),栈帧中包含这在方法内部使用的所有对象的引用(当然还有其他的基本类型数据),当方法执行完后,该栈帧会从虚拟机栈中弹出,这样一来,临时创建的对象的引用也就不存在了,或者说没有任何gc roots指向这些临时对象,这些对象在下一次GC时便会被回收掉

  2、方法区中类静态属性引用的对象 。静态属性是该类型(class)的属性,不单独属于任何实例,因此该属性自然会作为gc roots。只要这个class存在,该引用指向的对象也会一直存在。class 也是会被回收的,在面后说明

  3、本地方法栈(Native Stack)引用的对象
  下面介绍下关于软引用(softReference)和弱引用(weakReference)的对象垃圾回收对他们做的处理
String str = new String("hello");//A
SoftReference<String> sr = new SoftReference<String>(new String("java"));//B
WeakReference<String> wr = new WeakReference<String>(new String("world"));//C
  上面的几个对象中回收情况如下,B在内存不足的情况下会将String对象判定为可回收对象,C无论什么情况下String对象都会被判定为可回收对象。也就是说软引用会在内存溢出(OOM)的时候回收,而弱引用无论什么情况都会在下一轮回收的时候回收掉。
  一般jvm会对这些对象回收
  1、显示地将某个引用赋值为null或者将已经指向某个对象的引用指向新的对象。
  2、局部引用所指向的对象。
  3、上面说的弱引用(weakReference)。

2)典型的垃圾收集算法,是怎么回收对象的?
1、Mark-Sweep(标记-清除)算法
2、Copying(复制)算法
3、Mark-Compact(标记-整理)算法
4、Generational Collection(分代收集)算法
3)典型的垃圾收集器有哪些?
1.Serial/Serial Old
  Serial/Serial Old收集器是最基本最古老的收集器,它是一个单线程收集器,并且在它进行垃圾收集时,必须暂停所有用户线程。Serial收集器是针对新生代的收集器,采用的是Copying算法,Serial Old收集器是针对老年代的收集器,采用的是Mark-Compact算法。它的优点是实现简单高效,但是缺点是会给用户带来停顿。
2.ParNew
  ParNew收集器是Serial收集器的多线程版本,使用多个线程进行垃圾收集。
3.Parallel Scavenge
  Parallel Scavenge收集器是一个新生代的多线程收集器(并行收集器),它在回收期间不需要暂停其他用户线程,其采用的是Copying算法,该收集器与前两个收集器有所不同,它主要是为了达到一个可控的吞吐量。
4.Parallel Old
  Parallel Old是Parallel Scavenge收集器的老年代版本(并行收集器),使用多线程和Mark-Compact算法。
5.CMS
  CMS(Current Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器,它是一种并发收集器,采用的是Mark-Sweep算法。
6.G1
  G1收集器是当今收集器技术发展最前沿的成果,它是一款面向服务端应用的收集器,它能充分利用多CPU、多核环境。因此它是一款并行与并发收集器,并且它能建立可预测的停顿时间模型。
0%