Java知识整理2

基础问题相关:

1. 接口的意义(百度)

  1. 接口的意义用三个词概括规范,扩展,回调。

2. 抽象类的意义(百度)

  1. 为其他子类提供一个公共的类型
  2. 封装子类中重复定义的内容
  3. 定义抽象方法,子类虽然有不同的实现,但是定义是一致的。

3. 内部类的作用

  1. 内部类提供了更好的封装,可以把内部类以藏在外部类之内,不允许同一个包中的其他类访问该类。
  2. 内部类的方法可以直接访问外部类的所有数据,包括私有数据。
  3. 内部类所实现的功能使用外部同样可以实现,只是使用内部类更方便。

内部类的功能在于,每个内部类都能独立的继承一个接口的实现,所以无论外围类是否已经继承了某个(接口的)的实现,对于内部类都没有影响。内部类使得多重继承的解决方案变得完整,并且内部类允许继承多个非接口类型(类或者抽象类)。通过内部类分别继承一个基类,外部类创建内部类的对象,并使用内部类的方法,变相的实现类多重继承。

4. Java内部类的好处?为什么用内部类?

  1. 举个例子,如果你想实现一个接口,但是这个接口中的一个方法和你构想的这个类中的一个方法的名称,参数相同,你应该怎么办?这时候,你可以建一个内部类实现这个接口。由于内部类对外部类的所有内容都是可访问的,所以这样做可以完成所有你直接实现这个接口的功能。
  2. 真正原因是解决多继承

5.静态内部类的非静态内部类的区别

  1. 和非静态内部类相比,区别就在于静态内部类没有了只指向外部的引用。
  2. 在任何非静态内部类中,都不能有静态数据,静态方法或者又一个静态内部类(内部类的嵌套可不止一层)。不过静态内部类中却可以拥有这一切。

6.Java虚拟机的特性
Java语言的一个非常重要的特点就是与平台的无关性。而使用Java虚拟机是实现这一特点的关键。一般高级语言如果要在不同平台上运行,至少需要编译成不同的目标代码。而引入Java虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用模式Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需要生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。

7.哪些情况下的对象会被垃圾回收机制处理掉
Java垃圾回收机制最基本的做法是分代回收。内存中的区域被划分成不同世代,对象根据其存活的时间被保存在对应世代的区域中。一般的实现是划分成三个世代:年轻,年老,永久。内存的分配是发生在年轻世代中。当一个对象存活时间足够长的时候,它就会被复制到年老世代中。对于不同的世代可以使用不同的垃圾回收算法。进行世代划分的出发点是对应用中对象存活时间进行研究之后得出的统计规律。一般来说,一个应用中的大部分对象的存活时间都很短。比如局部变量的存活时间就只在方法的执行过程中。基于这一点,对于年轻世代的垃圾回收算法就可以很有针对性。

8.进程和线程的区别
简而言之:一个程序至少有一个进程,一个进程至少有一个线程。
线程的划分尺度小于线程,使得多线程程序的并发性高。
另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。
线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口,顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。
进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。
线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。线程自己基本上不拥有系统i资源,只拥有一些在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。
一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行。
进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程奔溃后,在保护模式下不会对其他进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,多以多进程的程序比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一点。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。

9.Java中==和equals和hashCode的区别
==是运算符,用于比较两个变量是否相等。
equals,是Object类的方法,用于比较两个对象是否相等。
hashCode()方法返回的就是一个数值,从方法的名称上就可以看出。其目的是生成一个hash码。hash码的主要作用就是在对对象进行散列的时候作为key输入,根据此很容易推断出,我们需要每个对象的hash码尽可能的不同,这样才能保证散列的存取性能。初学者可以理解成,hashCode方法实际上返回的就是对象存储的物理地址(实际上可能并不是)。

10.HashMap的实现原理
HashMap概述:HashMap是基于哈希表的Map接口的非同步实现。此实现提供所有可选的映射操作,并允许使用null值和null建。此类不保证映射的顺序,特别是它不保证该顺序恒久不变。

HashMap的数据结构:在Java语言中,最基本的结构就是两种,一个是数组,一个是模拟指针(引用),所有的数据结合都可以用这两个基本结构来构造,HashMap也不例外。HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。

11.string——stringbuffer——stringbuilder的区别

  1. String字符串常量
  2. StringBuffer字符串变量(线程安全)
  3. StringBuilder字符串变量(非线程安全)

简要地说,String类型和StringBuffer类型的主要性能区别其实在于String是不可变的对象,因此在每次对String类型进行改变的时候其实都等同于生成了一个新的String对象,然后将指针指向新的String对象,所以经常改变内容的字符串最好不要使用String,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后,JVM的GC就会开始工作,那速度一定会非常慢。

而如果是使用StringBuffer类则结果就不一样了,每次结果都会对StringBuffer对象本身进行操作,而不是生成新的对象,再改变对象引用。所以在一般情况下我们推荐使用StringBuffer,特别是字符串对象经常改变的情况下。而某些特别情况下,String对象的字符串拼接其实是被JVM解释成了StringBuffer的拼接,所以这时候String对象的速度并不会比stringBuffer对象慢,而特别是以下的字符串对象生成中,String效率是远要比StringBuffer快的:

String S1 = "this is only a"+"simple"+"test";
StringBuffer Sb = new StringBuffer("This is only a").append("simple").append("test");

你会惊讶的发现,生成String S1对象的速度简直太快了,而这个时候StringBuffer在速度上一点都不占优势。其实这是JVM的一个把戏,在JVM眼里,这个String S1 = “this is only a”+”simple”+”test”;其实就是String S1 = “this is only a simple test”;所以当然不需要太多时间。但是要注意,如果你的字符串来自另外的String对象的话,速度就没那么快了,譬如:

String S2 = "This is only a";
String S3 = "simple";
String S4 = "test";
String S1 = S1 + S2 + S3 +S4;

这个时候JVM就会按照原来的方式去做。

在大部分情况下 StringBuffer > String

Java.lang.StringBuffer线程安全的可变字符序列。一个类似与String的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。

可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。

StringBuffer上的主要操作是append和insert方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效的将给定的数据转换成字符串,然后将该字符串的字符追加或者插入到字符串缓冲区中。append方法始终将这些字符串添加到缓冲区的末端;而insert方法则在指定点添加字符。

在大部分情况下 StringBuilder > StringBuffer

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

12.什么导致线程阻塞

13.多线程同步机制

14.ArrayMap对比HashMap

15.HashMap和HashTable的区别

16.容器类之间的区别

17抽象类和接口区别

  1. 默认的方法实现:
    抽象类可以有默认的方法实现完全是抽象的。接口根本不存在方法的实现

  2. 实现:
    子类使用extends关键字来继承抽象类。如果子类不是抽象类的话,他需要提供抽象类中所有声明的方法的实现。
    子类使用关键字implements来实现接口。他需要提供接口中所有声明的方法的实现。

  3. 构造器:
    抽象类可以有构造器
    接口不能偶构造器

  4. 与正常Java类的区别:
    除了你不能实例化抽象类之外,它和普通Java类没有任何区别。
    接口是完全不同的类型。

  5. 访问修饰符:
    抽象方法可以有public,protected和default这些修饰符。
    接口方法默认修饰符是public。你不可以使用其他修饰符。

  6. main方法:
    抽象方法可以有main方法并且我们可以运行它
    接口没有main方法,一次不能运行它。

  7. 多继承
    抽象类在Java语言中便是的是一种继承关系,一个子类只能存在一个父类,但是可以存在多个接口。

  8. 速度:
    比接口速度要快
    接口速度是点慢,因为它需要时间去寻找在类中实现的方法

    9 . 添加新方法:
    如果你往抽象类中添加新的方法,你可以给它提供默认的实现。因此你不需要改变你现在的代码。
    而接口中添加新方法,那么那必须要改变实现该接口的类。


猜你喜欢

转载自blog.csdn.net/adonis044/article/details/80812492
今日推荐