JAVA基础开发面试题

前言:本人学习JAVA中,此文章为自己和需要的人做准备,如果文中答案有误请提出,谢谢!

请描述一下JVM、JRE、JDK三者的关系。

1、JVM是JAVA虚拟机,是实现跨平台的核心,JVM将客户端的java程序编译成.class

2、JRE是JAVA运行环境,包含着JVM虚拟机和JAVA核心类库

3、JDK是JAVA整合工具,其中包含着JRE运行环境,JAVA工具和JAVA基础类库

为什么说Java是编译与解释并存的语言?

因为在编译JAVA程序时,计算机无法解析.class文件,所以需要通过JVM虚拟机将.class文件解释成计算机可识别的二进制机器码

continue、break和return的区别?

continue:跳出本次循环,进行下一次循环

break:结束循环体;

return:在循环体中能够跳出循环体,return+变量说明方法有返回值,在方法中直接return跳出方法体

静态方法为什么不能调用非静态成员?

因为非静态成员还未进行实例化,所以内存中的静态方法无法调用不在内存中的非静态成员

面向过程和面向对象的区别

面向过程

  • 优点:性能比面向对象好,因为类调用时需要实例化,开销比较大,比较消耗资源

  • 缺点:不易维护、不易复用、不易扩展

面向对象

  • 优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统 更加灵活、更加易于维护

  • 缺点:性能比面向过程差

重载和重写有什么区别?

重载:编译时多态,方法重载时需要同名方法中的参数列表不同,而返回值可以相同,也可以不同

重写:运行时多态,重写是指子类在调用父类的构造函数时,需要参数列表和方法名与父类相同,子类通过父类的参数和本身的参数对父类方法进行改造

构造方法有哪些特性?

1、方法名与类名必须相同

2、没有返回值,也不能用void声明构造函数

3、如果类中无构造方法,编译器将自动生成一个无参无返回值的构造方法

4、可用访问修饰符public,privete,protected修饰,默认修饰符为public

在 Java 中定义一个不做事且没有参数的构造方法有什么作用?

Java程序在执行子类中的构造方法之前,父类中若是没有这个无参的构造方法,在没有使用super()的条件下,则编译报错。

JAVA中创建对象的几种方式?

1、使用new关键字创建对象;

2、使用 Class 类的 newInstance 方法,该方法调用无参的构造器创建对象(反射):Class.forName.newInstance();

3、使用 clone() 方法;

4、反序列化,比如调用 ObjectInputStream 类的 readObject() 方法

抽象类和接口有什么区别?

1、抽象类可以定义构造函数,而接口不能定义构造函数

2、抽象类成员权限有public,默认,protected(因为需要子类重写父类构造方法,所以不能被pirvate修饰),接口的成员权限只能为public,在方法中权限默认为public abstract,成员变量默认为public static final;

3、抽象类可以有抽象方法和具体方法,而接口只能有抽象方法

4、抽象类中有静态方法,接口没有静态方法

静态变量和实例变化的区别?

静态变量:是被static修饰的变量,也称为类变量,它属于类,静态变量在内存中有且仅有一个拷贝;静态变量可以实现让多个对象共享内存。

实例变量:属于某一个实例,需要先创建对象,然后通过对象才能访问它

short s1 = 1;s1 = s1 + 1;有什么错?那么 short s1 = 1; s1 += 1;呢?有没有错误?

对于 short s1 = 1; s1 = s1 + 1; 来说,在s1+1运算时会对表达式进行隐式转换成int类型,如果int类型赋值给short类型变量会出现类型转换错误。

对于 short s1 = 1; s1 += 1; 来说,+= 是 Java 语言规定的运算符,Java 编译器会对它进行特殊处理,因此可以正确编译。

Integer和int的区别?

1、int是java的八种基本数据类型之一,而Integer是Java为int类型提供的封装类。

2、int型变量的默认值是0,Interger的变量默认值是null,Interger可以区分出未赋值和值为0

3、Integer变量必须实例化后才可以使用,而int不需要。

装箱和拆箱的区别?

自动装箱Java编译器在基本数据类型和对应的引用类型之间做一个转化。比如:int转化成Integer,double转化成Double等等。反之就是自动拆箱。

原始类型:boolean、char、byte、short、int、long、float、double

封装类型:Boolean、Character、Byte、Short、Integer、Long、Float、Double

switch 语句能否作用在 byte 上,能否作用在 long 上,能否作用在 String 上?

在switch中,表达式只能是一个整数表达式,或者枚举常量。而整数表达式可以是int基本数据类型或者Integer引用类型。由于byte、short、char都可以隐式转换成int,所以这些基本数据类型以及这些类型的引用类型也可以使用在switch上。而long和String类型都不符合switch的语法规定,并且不能被隐式转换成int类型,所以它们不能用在switch语句中。但是,在jdk1.7版本之后String就可以作用在switch上了。

final、finally、finalize 的区别?

final:用于声明属性、方法和类,分别表示属性不可变,方法不可覆盖、被其修饰的类不可继承;

finally:异常处理语句结构的一部分,表示总是执行;

finalize:Object类的一个方法,在垃圾回收时会调用被回收的对象finalize;

== 和equals的区别?

==:如果比较的是基本数据类型,==比较的是数值是否相等;如果比较的是引用数据类型,则比较的是对象的地址值是否相等;

equals:用来比较两个对象的内容是否相等;equals方法不能用于比较基本数据类型的变量。如果没有对equals方法进行重写,则比较的是引用类型所指向的对象的地址。但是一般情况下很多类都重写了equals方法,例如String、Integer等把他们变成了比较值,所以一般情况下equals比较的是值是否相等。

两个对象的hashCode()相同,则equals()也一定为true吗?

两个对象的hashCode()相同,equals()不一定为true。因为在散列表中,hashCode()相等即两个键的哈希值相等,然而哈希值相等,并不一定能得出两个键值相等。

&和&&的区别?

Java中&&和&都表示与的逻辑运算符,也表示逻辑运算符and,当两边的表达式都为true的时候,整个运算结果才为true,否则为false。

&&(短路与):顾名思义,有短路功能。意思是当第一个表达式为false的时候,则不再计算第二个表达式;

&(逻辑与):不管第一个表达式的结果是否为true,第二个都会执行。除此之外,&还可以作为位运算符:当&两边的表达式不是Boolean类型的时候,&表示按位操作。

Java中的参数传递时传值呢?还是传引用?

java的参数是以值的形势传入方法中,而不是通过引用来传递值

当传递方法的参数类型为基本数据类型时,方法不能修改基本数据类型的参数。

当传递方法的参数类型为引用数据类型,方法可以修改引用数据类型的参数所指向的值。

如何实现对象的克隆?

1.实现Cloneable接口并重写Object类中的clone()方法;

2.实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深克隆;

深克隆和浅克隆的区别?

浅克隆:拷贝对象和原始对象的引用类型引用同一个对象。浅克隆在拷贝时只是使用了对象的引用地址,两个对象指向同一个内存地址,所以修改其中任意的值,另一个都会随之变化,这就是浅克隆。

深克隆:拷贝对象和原始对象的引用类型引用不同对象、深拷贝是将对象和值复制过来,两个对象修改其中任意的值,另一个值不会改变,这就是深拷贝。

什么是Java的序列化,如何实现Java的序列化?

对象序列化是一个用于将对象转换为字节流的过程,可以将其保存到磁盘文件中或通过网络发送到任何其他程序。而从字节流转换成对象的过程称为反序列化。而创建的字节流是与平台无关的,在一个平台上序列化的对象可以在不同的平台上反序列化。序列化是为了解决在对象流进行读写操作操作时所引发的问题。

序列化的实现:将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,只是用于标注该对象是可被序列化的,然后使用一个输入流(如:FileOutputStream)来构造一个ObjectOutputStream对象,接着通过ObjectOutputStream对象的writeObject(Object obj)方法可以将参数为obj的对象写出,要恢复的话则使用输入流。

什么情况下需要序列化?

1.当你想把内存中的对象状态保存到一个文件中或者数据库中的时候;

2.当你想用套接字在网络上传输对象的时候;

3.但你想通过RMI传输对象的时候。

Java的泛型是如何工作的?什么是类型擦出?

泛型是通过类型擦出来实现的,编译器在编译时擦出了所有类型相关的信息,所以在运行时不存在任何类型相关的信息。

类型擦除:泛型信息只存在于代码编译阶段,在进入JVM之前,与泛型相关的信息会被擦除掉,这也称之为类型擦出。在泛型被擦除的时候,之前的泛型类中的类型参数如果没有制定上限,如<T>则会被转译成普通的Object类型,如果制定了上限如<T extends String>则类型参数就被替换成类型上限。

什么是泛型中的限定通配符和非限定通配符?

限定通配符对类型进行了限制。有两种限定通配符,一种是<? extends T>,它通过确保类型必须是T的子类来设定类型的上界,另一种是<? super T>它通过确保类型必须是T的父类来设定类型的下界。泛型类型必须用限定内的类型来进行初始化,否则会导致编译错误。另一方面<?>表示了非限定通配符,因为<?>可以用任意类型来代替。

List< ? extends T > 和 List < ? super T > 之间有什么区别 ?

这两个List的生命都是限定通配符,List<? extends T>可以接受任何继承自T的类型的List,而List<? super T>可以接受任何T本身或其父类构成的List。

static关键字的作用?

  1. 静态变量:又称为类变量,也就是说这个变量属于类的,类说有的实例都共享静态变量,可以直接通过类名来访问它。静态变量在内存中只存在一份;
  2. 静态方法:静态方法在类加载是就存在了,它不依赖任何实例。所以静态方法必须有实现,也就是说不能是抽象方法。只能访问所属类的静态字段和静态方法,方法中不能有this关键字和super关键字;
  3. 静态语句块:静态语句块在类初始化时运行一次;
  4. 静态内部类:非静态内部类依赖于外部的实例,而静态内部类不需要。静态内部类不能访问外部类的非静态的变量和方法;
  5. 初始化顺序:静态变量和静态语句块优先于实例变量和普通语句块,静态变量和静态语句块的初始化顺序取决于他们在代码的顺序。

super关键字的作用?

  1. 访问父类的构造函数,可以使用super()函数访问父类的构造函数,从而委托父类完成一些初始化工作。
  2. 访问父类的成员:如果子类重写了父类的某个方法,可以通过super关键字来引用父类的方法实现。
  3. this和super不能用时出现在一个构造函数里面,因为this必然会调用其他的构造函数,其他的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过。

字节和字符的区别?

字节是存储容量的基本单位;

字符是数字、字母、汉字以及其他语言的各种符号;

1字节=8个二进制单位,一个字符由一个字节或多个字节的二进制单位组成。

String为什么要设计不可变类?

在Java中将String设计成不可变的是综合考虑到各种因素的结果。主要的原因有三点:

  1. 字符串常量池的需要:字符串常量池是Java堆内存中一个特殊的存储区域,当创建一个String对象时,假如此字符串值已经存在于常量池中,则不会创建一个新的对象,而是引用已存在的对象;
  2. 运行String对象缓存HashCode:Java中String对象的哈希码被频繁使用,比如在HashMap等容器中。字符串不变性保证了hash码的唯一性,因此可以放心地缓存。这也是一种性能优化手段,意味着不必每次都去计算新的哈希码;
  3. String被许多的Java类库用来当做参数,例如:网络连接地址URL、文件路径path、还有反射机制所需要的String参数等,假若String不是固定不变的,将会引起各种安全隐患。

String、StringBuilder、StringBuffer的区别?

String:用于字符串操作,属于不可变类;也是引用数据类型、底层由char数组实现。

StringBuilder:与StringBuffer类似,都是字符串缓冲区,但线程不安全;

StringBuffer:也用于字符串操作,不同之处是StringBuffer属于可变类,对方法加了同步锁,线程安全;(StringBuffer中并不是所有方法都使用了Synchronized修饰来实现同步)

String str = "i" 与String str = new String("i")一样吗?

不一样,因为内存的分配方式不一样。String str = "i"的方式,Java虚拟机会将其分配到常量池中;而String str = new String("i")则会被分到堆内存中。

String类的常用方法都有哪些?

indexOf():返回指定字符的索引。

charAt():返回指定索引处的字符。

replace():字符串替换。

trim():去除字符串两端空白。

split():分割字符串,返回一个分割后的字符串数组。

getByte():返回字符串的byte类型数组。

length():返回字符串长度。

toLowerCase():将字符串转成小写字母。

toUpperCase():将字符串转成大写字符。

substring():截取字符串。

equals():字符串比较。

final修饰StringBuffer后还可以append吗?

可以,final修饰的是引用变量,这个引用始终只能指向这个对象,但是这个对象内部的属性是可以变化的。

String字符串修改现实的原理?

当用String类型来对字符串进行修改时,其实现方法是首先创建一个StringBuilder,其次调用StringBuilder的append()方法,最后调用StringBuilder的toString()方法把结果返回。

final修饰StringBuffer后还可以append吗?

可以,final修饰的是引用变量,这个引用始终只能指向这个对象,但是这个对象内部的属性是可以变化的。

Java中的IO流的分类?说出几个你熟悉的实现类?

按功能来分:输入流(input)、输出流(output)。

按类型来分:字节流和字符流。

字节流:

InputStream/OutputStream是字节流的抽象类,这两个抽象类又派生了若干子类,不同的子类分别处理不同的操作类型。具体子类如下所示:

 

字符流:

Reader/Writer是字符的抽象类,这两个抽象类也派生了若干子类,不同的子类分别处理不同的操作类型。

​​​​​​​

 

字节流和字符流有什么区别?

字节流按8位传输,以字节为单位输入输出数据,字符流按16位传输,以字符为单位输入输出数据。

但是不管文件读写还是网络发送接收,信息的最小存储单元都是字节。

BIO、NIO、AIO有什么区别?

BIO:Block IO同步阻塞式IO,就是我们平常使用的传统IO,它的特点是模式简单使用方便,并发处理能力低。同步阻塞I/O模式,数据的读取写入必须阻塞在一个线程内等待其完成。在活动连接数不是特别高(小于单机1000)的情况下,这种迷行是比较不错的,可以让每一个连接专注于自己的I/O。并且编程模型简单,也不用过多考虑系统的过载、限流等问题。线程池本身就是一个天然的漏斗,可以缓冲一些系统处理不了的连接或请求。但是,但面对十万甚至百万级连接的时候,传统的BIO模型是无能为力的。因此,我们需要一种更高效的I/O处理模型来应对更高的并发量。

NIO:New IO同步非阻塞IO,是传统IO的升级,客户端和服务器端通过Channel(通道)通讯,实现了多路复用。NIO是一种同步非阻塞的I/O模型,在Java1.4中引入了NIO狂阶,对相应java.nio包,提供了Channel,Selector,Buffer等抽象。NIO中的N可以理解为Non-blocking,不是单纯的New。它支持面向缓冲的,基于通道的I/O操作方法。NIO提供了与传统BIO模型中的Socket和ServerSocket相对应的SocketChannel和ServerSocketChannel两种不同的套接字通道实现,两种通道都支持阻塞和非阻塞两种模式。阻塞模式使用就向传统中的支持一样,比较简单,但是性能和可靠性都不好;非阻塞模式正好与之相反。对于低负载、低并发的应用程序,可以使用同步阻塞I/O来提升开发速率和更好的维护性;对于高负载、高并发的(网络)应用,应使用NIO的非阻塞模式来开发。

AIO:Asynchronous IO是NIO的升级,也叫NIO2,实现了异步非堵塞IO,异步IO的操作基于事件和回调机制。也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。AIO是异步IO的缩写,虽然NIO在网络操作中,提供了非阻塞的方法,但是NIO的行为还是同步的。对于NIO来说,我们的业务线程是在IO操作准备好时,得到通知,借着就由这个线程自行进行IO操作,IO操作本身是同步的。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值