Java面试题复习笔记(Java基础)

时间:2022-01-08 00:37:46

Java的跨平台原理。

答:各操作系统支持的指令集不是完全一致的,这导致程序在不同的系统上要执行不同的程序代码。Java开发了适用于不同操作系统的Java虚拟机(JVM)来屏蔽各个系统之间的差异,提供统一的接口。

Java面试题复习笔记(Java基础)

Java中int数据占几字节?有几种基本的数据类型?

答:有8种基本的数据类型,分别是boolean、byte、short、int、long、float、double、char,其中int型数据占4个字节。

Java面试题复习笔记(Java基础)

 

Java种有了基本数据类型,为什么还需要包装类型?

答:因为Java是一种面向对象的语言,而基本数据类型不具备面向对象的特征。

基本数据类型和包装类型为一一对应关系,如下表:

byte

short

int

long

float

double

char

boolean

Byte

Short

Integer

Long

Float

Double

Character

Boolean

举例:用int和Integer表示Person的ID,在判断Person是否存在的时候需要判断ID,判断Integer类型的时候只需要判断是否为null即可,而int型需要判断值是否为0.

拓展内容:装箱和拆箱。

装箱:把基本数据类型转换成相对应的包装类型。装箱又分为自动装箱和手动装箱。

(1)手动装箱:例如Integer i = Integer.ValueOf( 1 );

(2)自动装箱:例如Integer i = 1;实际上在编译过程中调用了 Integer.ValueOf(  )方法来装箱。

拆箱:把包装类型转换成对应的基本数据类型。

(1)手动拆箱:例如int j = i = intValue();

(2)自动拆箱:例如int j = i;实际上在编译过程中调用了IntValue()方法来拆箱。 

short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 +=1;有什么错?

short s1 = 1; s1 = s1 + 1;
(s1+1运算结果是int型,需要强制转换类型)
short s1 = 1; s1 += 1;(可以正确编译,+=内置运算符运算时可自动变换数据类型)

Java中的异常处理机制的简单原理和应用。

当JAVA 程序违反了JAVA的语义规则时,JAVA虚拟机就会将发生的错误表示为一个异常。违反语义规则包括2种情况。一种是JAVA类库内置的语义检查。例如数组下标越界,会引发IndexOutOfBoundsException;访问null的对象时会引发NullPointerException。另一种情况就是JAVA允许程序员扩展这种语义检查,程序员可以创建自己的异常,并*选择在何时用throw关键字引发异常。所有的异常都是java.lang.Thowable的子类。

面向对象特征有哪些方面?

答:封装,抽象,继承,多态。回答抽象问题时需举例说明!

封装:将对象封装成一个高度自治和相对封闭的个体,对象的状态(属性)由这个对象自己给出的行为(方法)来读取和改变。

EX:张三,他有名字等属性,private name,setName,getName

抽象:找出一些事物相似和共性之处,然后将这些事物归为一个类,只考虑相似和共性之处。

继承:在定义和实现一个类的时候,可以在一个已经存在的类的基础上进行,将父类定义的内容作为自己的内容,并可以加入新的内容或修改原来的方法使之更适合特殊需要。

多态:指程序中定义的引用变量所指向的具体类型和通过改引用变量发出的方法调用子啊编程时并不确定,而是在程序运行期间动态绑定。(通俗一点理解就是工具都摆在那儿,但是哪个在什么时候用并不清楚,只有在真正工作的时候需要哪个就用哪个)

EX:

Object obj=new XXX();
UserDao  userDao=new UserDaoJdbclmpl();
UserDao  userDao=new UserDaoHibernatelmpl();

理解:考的是父类或接口定义的引用变量可以指向子类或具体实现类的实例对象,而程序调用方法在运行期间才动态绑定,就是引用变量所指向的具体实例对象的方法,也就是内存里正在运行的那个对象方法,而不是引用变量的类型种定义的方法。

Overload和Override的区别?Overloaded的方法是否可以改变返回值的类型?

 

方法的重写Overriding和重载Overloading是Java多态性的不同表现。

重写Overriding是父类与子类之间多态性的一种表现,重载O verloading是一个类中多态性的一种表现。

如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写(Overriding)。

子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被”屏蔽”了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。

Overloaded的方法是可以改变返回值的类型。

 

equals方法和“==”有什么区别?

答:“==”是用来判断两个变量的值是否相等。其中基本数据类型直接比较值,引用类型需要比较对应的引用的内存首地址。

  equals用来比较两个对象是否长得一样(字符串比较常用),判断某些特征是否一样。实际上就是调用Object的equals方法进行比较。

接口和抽象类的区别是什么?

 

Java提供和支持创建抽象类和接口。它们的实现有共同点,不同点在于:
• 接口中所有的方法隐含的都是抽象的。而抽象类则可以同时包含抽象和非抽象的方法。
• 类可以实现很多个接口,但是只能继承一个抽象类
• 类如果要实现一个接口,它必须要实现接口声明的所有方法。但是,类可以不实现抽象类声明的所有方法,当然,在这种情况下,类也必须得声明成是抽象的。
• 抽象类可以在不提供接口方法实现的情况下实现接口。
• Java接口中声明的变量默认都是final的。抽象类可以包含非final的变量。
• Java接口中的成员函数默认是public的。抽象类的成员函数可以是private,protected或者是public。
• 接口是绝对抽象的,不可以被实例化。抽象类也不可以被实例化,但是,如果它包含main方法的话是可以被调用的。
也可以参考JDK8中抽象类和接口的区别

什么是值传递和引用传递?

对象被值传递,意味着传递了对象的一个副本。因此,就算是改变了对象副本,也不会影响源对象的值。
对象被引用传递,意味着传递的并不是实际的对象,而是对象的引用。因此,外部对引用对象所做的改变会反映到所有的对象上。

 

String和StringBuilder的区别?StringBuilder和StringBuffer的区别?

答:Java种提供了三个类来表示和操作字符串:String、StringBuilder、StringBuffer

String用于表示内容不可变的字符串,因为String底层使用了一个不可变的字符数组(使用了final修饰符修饰的char[ ])。

StringBuilder和StringBuffer表示的字符串内容可变,底层使用的字符数组没有final修饰符。

最经典的就是字符串拼接:

String进行拼接如下:String c = "a"+"b";(需要一个中间变量c进行过度,a与b的内容不可变)

StringBuilder和StringBuffer进行拼接如下:

  StringBuilder sb = new StringBuilder( );

  sb.apend("a").apend("b");

StringBuilder和StringBuffer的区别是:StringBuilder是线程不安全的,但是效率高;StringBuffer是线程安全的,按时效率低。通常我们使用较多的是StringBuilder,只有限定线程安全时才使用StringBuffer。

陈述一下对Java种集合的理解?

答:根据存储分为值存储和key——value存储,即Collection和map

(1)存储值:List和Set,区别是List是有序的,可重复的;Set是无序的,不可重复的。是否重复要根据equals和hashcode判定。

如果一个对象要存储在Set种必须重写equals和hashcode方法。

(2)存储key——value:map

ArrayList和LinkedLinst的区别?

答:ArrayList底层使用的是数组,LinkedList底层使用的是结点连成的链表。

数组在在内存中是一块连续区域,插入删除是需要移动内存,所以进行插入和修改操作时效率低,但是因为有索引,进行查询操作时效率高。

链表不要求内存连续,在当前元素中存放下一个/上一个元素的地址,插入时不需要移动内存,只需要改变引用指向即可,插入删除效率高,到那时查询的时候每次都需要从头节点开始一个个找索引,进行查询操作的时候效率低。

HashMap和HashTable区别?Hashmap和ConcurrentHashMap区别?

答:HashMap和HashTable都可以用来存储key——value的数据。

区别:HashMap可以吧null作为key或者value,而HashTable不可以;HasMap线程不安全,效率高,HashTable线程安全,效率低。

既想线程安全,又想效率高(ConcurrentHashMap)

通过把整个Map分为n个Segment(类似于HashTable);可以提供相同的线程安全,但是效率提升n倍,默认为16倍。

实现一个拷贝文件的工具使用字节流还是字符流?

答:文件不确定是只包含字符流,有可能有字节流(图片,声音,图像等),为考虑通用性,要使用字节流。

同步方法和同步代码块的区别是什么?

在Java语言中,每一个对象有一把锁。线程可以使用synchronized关键字来获取对象上的锁。

synchronized关键字可应用在方法级别(粗粒度锁:这里的锁对象可以是This)或者是代码块级别(细粒度锁:这里的锁对象就是任意对象)。

什么是死锁(deadlock)?

两个进程都在等待对方执行完毕才能继续往下执行的时候就发生了死锁。结果就是两个进程都陷入了无限的等待中。

如何确保N个线程可以访问N个资源同时又不导致死锁?

使用多线程的时候,一种非常简单的避免死锁的方式就是:指定获取锁的顺序,并强制线程按照指定的顺序获取锁。因此,如果所有的线程都是以同样的顺序加锁和释放锁,就不会出现死锁了。

 

Iterator和ListIterator的区别是什么?

下面列出了他们的区别:
• Iterator可用来遍历Set和List集合,但是ListIterator只能用来遍历List。
• Iterator对集合只能是前向遍历,ListIterator既可以前向也可以后向。
• ListIterator实现了Iterator接口,并包含其他的功能,比如:增加元素,替换元素,获取前一个和后一个元素的索引,等等。

 

线程的几种实现方式?怎么启动?怎么区分?什么是线程池?什么是线程并发库?

进程:运行中的应用程序,每个进程都有自己独立的内存空间。

线程:进程中的一个实体,被系统独立独立调度和分派的基本单位,有就绪,阻塞,运行三种基本状态。一个进程可以有多个线程(即多线程编程)

实现:(1)通过继承Thread类实现一个线程

   (2)通过实现runnable接口实现一个线程

继承的扩展性不强,Java总是支持单继承,如果一个类继承了Thread就不能继承其他类了

启动:调用start方法

Thread theard = new Thread(继承了Thread的对象/实现了runnable的对象);
thread.satrt;

启动了以后执行的是run方法。

区分:

thread.setName("设置一个线程名称")

EX:一个系统中有很多线程,每个线程都会打印日志,怎么区分是哪个线程打印的。

这是一个规范,在创建线程完成后都需要设置名称。

并发库:(简单了解过)

Java.util.current包中提供了对线程优化,管理的各项操作,使得线程的使用变得得心应手,提供了线程的运行,线程池的创建,线程生命周期的控制。

线程池:Java通过Executors提供四个静态方法创建四种线程池:

newCachedThreadPool:可缓存线程池,若线程池长度超过处理需要,可灵活回收空闲线程,若无可回收则新建新城。

newFixedThreadPool:定长线程池,可控制线程最大并发数,超出的线程会在队列等候。

newScheduledThreadPool:预定线程池,支持定时和周期性任务执行。

newSingleThreadPool:单线程化的线程池,只会用唯一的工作线程来执行任务,并保证所有任务按照指定顺序执行。

线程池的作用:

      (1)限定线程的个数,不会导致由于线程过多导致系统运行缓慢或崩溃

      (2)线程池在开始不需要每次都去创建或销毁,节约了资源

      (3)响应时间快

什么是设计模式?常用的有哪些?

答:在设计过程中可以反复使用的,可以解决特定问题的设计方法。

单例模式:(1)构造方法私有化,让除了自己类中能创建外其他大方都不能创建

     (2)在自己类中创建一个单实例

     (3)提供一个方法获取该单实例对象

     单例模式又分为饱汉模式(一出来就创建单实例)和饥汉模式(需要的时候才创建,创建时需要进行方法同步)

工厂模式:Spring IOC 对象的创建交给一个工厂

代理模式:Spring AOP使用动态代理