Java面试题总结(1)

(1)java基础知识点

1.java中==和equals和hashCode的区别

hash码的主要用途就是在对对象进行散列的时候作为key输入, 哈希算法也称为散列算法,是将数据依特定算法直接
指定到一个地址上。散列函数将任意长度的二进制值映射为较短的固定长度的二进制值,这个小的二进制值称为哈希值。

2.int、char、long各占多少字节数

char 2字节,long 8 字节

3.int与integer的区别

1.Integer是int的包装类,int则是java的一种基本数据类型;
2.Integer变量必须实例化后才能使用,而int变量不需要;
3.Integer实际是对象的引用,当new一个Integer时,实际上是生成一个指针指向此对象,而int则是直接存储数据值; 
4.Integer的默认值是null,int的默认值是0;

4.谈谈对java多态的理解

1.面向对象的三大特性:封装、继承、多态
2.多态的定义:指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。
3.实现多态的技术称为:动态绑定(dynamic binding),是指在执行期间判断所引用对象的实际类型,根据其实际
    的类型调用其相应的方法。
4、多态的作用:消除类型之间的耦合关系。
5、Java中多态的实现方式:接口实现,继承父类进行方法重写,同一个类中进行方法重载。

5.String、StringBuffer、StringBuilder区别

1.String 字符串常量,stringBuffer 字符串变量(线程安全),StringBuilder 字符串变量(非线程安全)
2.简要的说, String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象, 因此在每
次对 String 类型进行改变的时候,其实都等同于生成了一个新的其实都等同于生成了一个新的 String 对象,然
后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统
性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,那速度是一定会相当慢的。而如果是
使用 StringBuffer 类则结果就不一样了,每次结果都会对 StringBuffer 对象本身进行操作,而不是生成新的
对象,再改变对象引用。所以在一般情况下我们推荐使用 StringBuffer ,特别是字符串对象经常改变的情况下。

3.StringBuffer线程安全的可变字符序列。一个类似于 String 的字符串缓冲区,但不能修改。虽然在任意时间点
上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。可将字符串缓冲区安全地用于多
个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所
涉及的每个线程进行的方法调用顺序一致。

4.StringBuilder此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 
的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为
在大多数实现中,它比 StringBuffer 要快。两者的方法基本相同。

6.什么是内部类?内部类的作用

内部类主要分为普通内部类、局部内部类、匿名内部类、嵌套内部类(静态内部类)。非静态内部类中不能定义静态成
员,静态内部类不能访问外部类的非静态成员。
1.普通内部类(成员内部类):内部类的名字是嵌套在外部类中的;2)外部类将有一个方法,该方法返回一个内部类
的引用。
2.局部内部类:在方法或者代码的作用域内创建一个完整的类,称作局部内部类,其作用范围为所在的代码块,是内
部类中最少使用的一种类型。局部内部类和局部变量一样,不能被public、protected、private和static修饰,只
能访问方法中定义为final类型的局部变量。
3.匿名内部类:没有类名的内部类,不使用关键字class、extends、implements,没有构造函数,必须继承其他类
或实现其他接口。匿名内部类的好处是代码更加简洁紧凑,但坏处是易读性下降。
4.嵌套内部类:内部类是static时,称作是嵌套类。则
1)创建嵌套类的对象时不再需要其外围类的对象;
2)不能从嵌套类的对象中访问非静态的外围类对象。静态内部类不能访问外部类的普通成员变量,只能访问外部类中
的静态成员和静态方法。
内部类的好处:
1)内部类可以有多个实例,每个实例都有自己的状态信息,并且与其外围类对象那个的信息相互独立;
2)在单个外围类中,可以让多个内部类以不同的方式实现同一个接口,或继承同一个类;
3)创建内部类对象的时刻并不依赖于外围类对象的创建;
4)内部类并没有令人迷惑的“is-a”关系,它就是一个独立的实体。

7.抽象类和接口区别

接口是抽象方法的集合。如果一个类实现了某个接口,那么它就继承了这个接口的抽象方法。
1.抽象类和接口都可以包含静态成员变量,抽象类中静态成员变量访问类型可以任意,但接口中定义的变量只能是
public static final 类型,并且默认为public static final 类型;
2.抽象类中可以包含普通成员变量,接口中没有普通成员变量。
3.抽象类中的方法method不能同时是静态的; 
相似性:
1.接口和抽象类都不能被实例化,它们都位于继承树的顶端,用于被其他类实现和继承。
2.接口和抽象类都可以包含抽象方法,实现接口或继承抽象类的普通子类都必须实现这些抽象方法。
区别:
1 接口里只能包含抽象方法,静态方法和默认方法,不能为普通方法提供方法实现,抽象类则完全可以包含普通方法。
2 接口里只能定义静态常量,不能定义普通成员变量,抽象类里则既可以定义普通成员变量,也可以定义静态常量。
3 接口不能包含构造器,抽象类可以包含构造器,抽象类里的构造器并不是用于创建对象,而是让其子类调用这些构
造器来完成属于抽象类的初始化操作。
4 接口里不能包含初始化块,但抽象类里完全可以包含初始化块。
5 一个类最多只能有一个直接父类,包括抽象类,但一个类可以直接实现多个接口,通过实现多个接口可以弥补Java单继承不足。

8.抽象类的意义

抽象类和抽象方法用 abstract 关键字修饰。
抽象类不能被实例化。(其实可以通过多态的方式实例化)
抽象类除了不能直接实例化外,其它特性都和普通类一样,同样有成员变量,常量,成员方法。而抽象方法是强制子类实现的功能。
意义:
1,为子类提供一个公共的类型;
2,封装子类中重复内容(成员变量和方法);
3,定义有抽象方法,子类虽然有不同的实现,但该方法的定义是一致的。

9.抽象类与接口的应用场景

1、相同点

 A. 两者都是抽象类,都不能实例化。
 B. interface实现类及abstrct class的子类都必须要实现已经声明的抽象方法。

2、不同点

A. interface需要实现,要用implements,而abstract class需要继承,要用extends。
B. 一个类可以实现多个interface,但一个类只能继承一个abstract class。
C. interface强调特定功能的实现,而abstract class强调所属关系。 
D. 尽管interface实现类及abstrct class的子类都必须要实现相应的抽象方法,但实现的形式不同。interface
中的每一个方法都是抽象方法,都只是声明的(declaration, 没有方法体),实现类必须要实现。而abstract 
class的子类可以有选择地实现。

3、interface的应用场合

 A. 类与类之前需要特定的接口进行协调,而不在乎其如何实现。
 B. 作为能够实现特定功能的标识存在,也可以是什么接口方法都没有的纯粹标识。
 C. 需要将一组类视为单一的类,而调用者只通过接口来与这组类发生联系。
 D. 需要实现特定的多项功能,而这些功能之间可能完全没有任何联系。

4、abstract class的应用场合

 一句话,在既需要统一的接口,又需要实例变量或缺省的方法的情况下,就可以使用它。最常见的有:
 A. 定义了一组接口,但又不想强迫每个实现类都必须实现所有的接口。可以用abstract class定义一组方法体,
    甚至可以是空方法体,然后由子类选择自己所感兴趣的方法来覆盖。
 B. 某些场合下,只靠纯粹的接口不能满足类与类之间的协调,还必需类中表示状态的变量来区别不同的关系。
abstract的中介作用可以很好地满足这一点。
 C. 规范了一组相互协调的方法,其中一些方法是共同的,与状态无关的,可以共享的,无需子类分别实现;而另
一些方法却需要各个子类根据自己特定的状态来实现特定的功能

10、抽象类是否可以没有方法和属性?

抽象类中可以没有抽象方法,但有抽象方法的一定是抽象类。所以,java中 抽象类里面可以没有抽象方法。比如HttpServlet类。
抽象类和普通类的区别就在于,抽象类不能被实例化,就是不能被new出来,即使抽象类里面没有抽象方法。

抽象类的作用在于子类对其的继承和实现,也就是多态;而没有抽象方法的抽象类的存在价值在于:实例化了没有意
义,因为类已经定义好了,不能改变其中的方法体,但是实例化出来的对象却满足不了要求,只有继承并重写了他的
子类才能满足要求。所以才把它定义为没有抽象方法的抽象类

11、接口的意义

1、重要性:在Java语言中, abstract class 和interface 是支持抽象类定义的两种机制。正是由于这两种机制
的存在,才赋予了Java强大的 面向对象能力。
2、简单、规范性:如果一个项目比较庞大,那么就需要一个能理清所有业务的架构师来定义一些主要的接口,这些接
口不仅告诉开发人员你需要实现那些业务,而且也将命名规范限制住了(防止一些开发人员随便命名导致别的程序员无法看明白)。
3、维护、拓展性:比如你要做一个画板程序,其中里面有一个面板类,主要负责绘画功能,然后你就这样定义了这个类。

可是在不久将来,你突然发现这个类满足不了你了,然后你又要重新设计这个类,更糟糕是你可能要放弃这个类,那
么其他地方可能有引用他,这样修改起来很麻烦。

如果你一开始定义一个接口,把绘制功能放在接口里,然后定义类时实现这个接口,然后你只要用这个接口去引用实
现它的类就行了,以后要换的话只不过是引用另一个类而已,这样就达到维护、拓展的方便性。

4、安全、严密性:接口是实现软件松耦合的重要手段,它描叙了系统对外的所有服务,而不涉及任何具体的实现细节。
这样就比较安全、严密一些(一般软件服务商考虑的比较多)。

12、泛型中extends和super的区别

1.<? extends T> 只能用于方法返回,告诉编译器此返参的类型的最小继承边界为T,T和T的父类都能接收,但是
入参类型无法确定,只能接受null的传入
2.<? super T>只能用于限定方法入参,告诉编译器入参只能是T或其子类型,而返参只能用Object类接收

13、父类的静态方法能否被子类重写

子类可以继承父类的静态方法,意思是可以调用,但前提是父类此方法对子类可见最重要的一点,一个类中的static
修饰的变量或者方法,都默认的会加上final关键字,大家都知道加上final关键字是肯定不能重写的,所以静态方法
是不能被重写的

当你在子类中定义跟父类同样的static方法(返回值,修饰符,参数类型以及个数),则此时父类的该方法被隐藏静态
方法跟对象无关,只跟类有关静态方法属于静态绑定,在编译阶段已经确定函数名和地址,静态方法当然是可以被继承
的,但是却不能被重写,

为什么那?因为重写的意思是重新定义父类的虚函数,但是虚函数是动态绑定的,而静态方法是静态绑定的,所以静态函
数必然不能是虚函数,也就不存在所说的重写了.你在子类中重新写一个同名的函数,覆盖了父类的同名函数,在使用子
类指针进行调用的时候,调用的就是子类的这个静态方法

14、进程和线程的区别

1.定义
进程:具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.
线程:进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥
有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他
的线程共享进程所拥有的全部资源.

2.关系
一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行.
相对进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中的其他线程共享数据,但拥有自己的栈空
间,拥有独立的执行序列。

3.区别
  进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保
护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之
间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切
换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能
用进程。
1) 简而言之,一个程序至少有一个进程,一个进程至少有一个线程.
2) 线程的划分尺度小于进程,使得多线程程序的并发性高。
3) 另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。
4) 线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是
线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
5) 从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线
程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。

4.优缺点
线程和进程在使用上各有优缺点:
线程执行开销小,但不利于资源的管理和保护;
而进程正相反。
同时,线程适合于在SMP机器上运行,而进程则可以跨机器迁移。

15、final,finally,finalize的区别

1.final:如果一个类被final修饰,意味着该类不能派生出新的子类,不能作为父类被继承。因此一个类不能被声明
为abstract,又被声明为final。将变量或方法声明为final。可以保证他们在使用的时候不被改变。其初始化可以在
两个地方:一是其定义的地方,也就是在final变量在定义的时候就对其赋值;二是在构造函数中。这两个地方只能选
其中的一个,要么在定义的时候给值,要么在构造函数中给值。被声明为final的方法也只能使用,不能重写。

2.finally:在异常处理的时候,提供finally块来执行任何的清除操作。如果抛出一个异常,那么相匹配的catch字
句就会执行,然后控制就会进入finally块,前提是有finally块。

3.finalize:finalize是方法名,java技术允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前
做必要的清理工作。这个方法是在垃圾收集器确认一个对象没有被引用时对这个对象调用的。它是在Object类中定义
的,因此,所有的类都继承了它。子类覆盖finalize()方法已整理系统资源或者执行其他清理工作。finalize()方法
是在垃圾收集器删除对象之前对这个对象调用的。

16、序列化的方式

Serializable 和Parcelable 的区别

1、作用
Serializable的作用是为了保存对象的属性到本地文件、数据库、网络流、rmi(远程方法调用Remote Method 
Invocation)以方便数据传输。
当然这种传输可以是程序内的也可以是两个程序间的。而Android的Parcelable的设计初衷是因为Serializable
效率过慢,为了在程序内不同组件间以及不同Android程序间(AIDL)高效的传输数据而设计,这些数据仅在内存中存
在,Parcelable是通过IBinder通信的消息的载体。

2、效率及选择
Parcelable的性能比Serializable好,在内存开销方面较小,所以在内存间数据传输时推荐使用Parcelable,
如activity间传输数据,而Serializable可将数据持久化方便保存,所以在需要保存或网络传输数据时选择Serializable。

3.高级功能上
Serializable序列化不保存静态变量,可以使用Transient(短暂的; 转瞬即逝的; 临时的)
关键字对部分字段不进行序列化,也可以覆盖writeObject、readObject方法以实现序列化过程自定义
说明:
Java的serialization提供了一种持久化对象实例的机制。当持久化对象时,可能有一个特殊的对象数据成员,我们
不想用serialization机制来保存它。为了在一个特定对象的一个域上关闭serialization,可以在这个域前加上关
键字transient。当一个对象被序列化的时候,transient型变量的值不包括在序列化的表示中,然而非transient
型的变量是被包括进去的。

17.静态属性和静态方法是否可以被继承?是否可以被重写?以及原因?

java中静态属性和静态方法可以被继承,但是没有被重写(overwrite)而是被隐藏.
原因:
1). 静态方法和属性是属于类的,调用的时候直接通过类名.方法名完成对,不需要继承机制及可以调用。如果子类里
面定义了静态方法和属性,那么这时候父类的静态方法或属性称之为"隐藏"。如果你想要调用父类的静态方法和属性,
直接通过父类名.方法或变量名完成,至于是否继承一说,子类是有继承静态方法和属性,但是跟实例方法和属性不
太一样,存在"隐藏"的这种情况。

2). 多态之所以能够实现依赖于继承、接口和重写、重载(继承和重写最为关键)。有了继承和重写就可以实现父类的
引用指向不同子类的对象。重写的功能是:"重写"后子类的优先级要高于父类的优先级,但是“隐藏”是没有这个优先级之分的。

3). 静态属性、静态方法和非静态的属性都可以被继承和隐藏而不能被重写,因此不能实现多态,不能实现父类的引
用可以指向不同子类的对象。非静态方法可以被继承和重写,因此可以实现多态。

18、静态内部类的设计意图

在java中类是单继承的,一个类只能继承另一个具体类或抽象类(可以实现多个接口)。这种设计的目的是因为在多
继承中,当多个父类中有重复的属性或者方法时,子类的调用结果会含糊不清,因此用了单继承。而使用内部类的原
因是:每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于
内部类都没有影响。

静态内部类与非静态内部类之间存在一个最大的区别:非静态内部类在编译完成之后会隐含地保存着一个引用,该引
用是指向创建它的外围内,但是静态内部类却没有。没有这个引用就意味着:它的创建是不需要依赖于外围类的。它不
能使用任何外围类的非static成员变量和方法。

19、成员内部类、静态内部类、局部内部类和匿名内部类的理解,以及项目中的应用

内部类有什么作用?
1.内部类可以很好的实现隐藏
一般的非内部类,是不允许有 private 与protected权限的,但内部类可以
2.内部类拥有外围类的所有元素的访问权限 (private修饰也能访问)
3.可是实现多重继承 (让多个内部类分别继承多个其他类,使外部类可以同时获取多个其他类的属性)
4.可以避免修改接口而实现同一个类中两种同名方法的调用。(外部类继承,让内部类实现接口)

静态内部类:除了访问权限修饰符比外围类多以外
除了访问权限修饰符比外围类多以外, 和外围类没有区别, 只是代码上将静态内部类组织在了外部类里面。静态内部
类不能访问外部类的非公开成员。

非静态内部类:  
非静态内部类能访问外部类的一切成员, 包括私有成员。外部类虽然不能直接访问内部类的成员, 但是可以通过内部
类的实例访问内部类的私有成员。

局部内部类:
指内部类定义在方法体内,只能在该方法或条件的作用域内才能使用,退出这写作用域就无法引用。

匿名内部类:
为了免去给内部类命名,或者只想使用一次,就可以选择使用匿名内部类。

猜你喜欢

转载自blog.csdn.net/u010725842/article/details/79452827