Java面试知识点4

1.下面两段代码的区别?

short s1 = 1; 
s1 = s1 + 1;
short s1 = 1;
 s1 += 1;

第一段编译报错,s1 + 1 自动升级为int型,int型赋值给s1,需要手动强转
第二段隐含类型强转,不会报错。

2.switch能否作用在byte,long、String上?

早期JDK,switch(expr),expr可以是byte、short、char ,int;
JDK1.5开始,引入了枚举(enum),expr可以是枚举了
JDK1.7开始,expr可以是字符串(String);
长整型long是不可以的。

3.为什么不能根据返回类型来区分方法重载?

方法的重载只是要求两同三不同:
两同
1.在同一个类中;
2.相同的方法名称;
三不同
3.参数列表中参数类型,个数,顺序不同;
4.跟权限修饰符合返回值类型无关;

如果可以根据返回值类型来区分方法重载,那在仅仅调用方法不获取返回值的使用场景,JVM就不知道调用的是哪个返回值的方法了。

4.Inner Class和Static Nested Class的区别?

Inner Class内部类

  1. 内部类就是在一个类的内部定义的类 ;
  2. 内部类不能定义静态成员;
  3. 内部类可以直接访问外部类中成员变量
  4. 内部类可以在定义在外部的方法外面,也可以定义在外部类的方法体中;
  5. 在方法体外面定义的内部类的访问权限可以是public,protected,默认的,private等四种类型;
  6. 方法内部定义的内部类前面不能有访问类型修饰符,可以使用final或abstract修饰符;
  7. 创建内部类的实例对象时,一定要先创建外部类的实例对象,然后利用这个外部类的实例对象去创建
    内部类的实例对象;
  8. 内部类里还包括匿名内部类,即直接对类或接口的方法进行实现,不用单独去定义内部类;

Static Nested Class:静态嵌套类

  1. 不依赖与外部类的实例对象;
  2. 能访问外部类的非static成员变量;
  3. 不能直接访问需要创建外部类实例才能访问非静态变量;
  4. 可以直接引用外部类的static的成员变量,不需要加上外部类的名字;
  5. 在静态方法中定义的内部类也是Static Nested Class。

5.abstract方法是否可是static的?native的?synchronized的?

都不能

1.抽象方法需要子类重写,而静态的方法是无法被重写;
2.本地方法是由本地动态库实现的方法,而抽象方法是没有实现的;
3.抽象方法没有方法体;synchronized方法,需要有具体的方法体,相互矛盾。

6.内部类可以引用它的外部类的成员吗?有什么限制?

1.内部类对象可以访问创建它的外部类对象的成员,包括私有成员。

2.访问外部类的局部变量,此时局部变量必须使用final修饰。

7.创建对象时构造器的调用顺序

1.递归初始化父类静态成员和静态代码块,上层优先;
2.初始化本类静态成员和静态代码块;
3.递归父类构造器,上层优先;
4.调用自身构造器。

8.Class类的作用是什么?如何获取Class对象?

Class类是Java反射机制的起源和入口,用于获取与类相关的各种信息,提供了获取类信息的相关方法。
Class类存放类的结构信息,能够通过Class对象的方法取出相应信息:类的名字、属性、方法、构造方法、父类、接口和注解等信息。

1.对象名.getClass()
2.对象名.getSuperClass()
3.Class.forName('oracle.jdbc.driver.OracleDriver')
4.类名.class
5.包装类.TYPE
6.Class.getPrimitiveClass()

9.面向对象设计原则有哪些?

1.单一职责原则SRP;
2.开闭原则OCP;
3.里氏替代原则;
4.依赖注入原则;
5.接口分离原则;
6.迪米特原则;
7.组合/聚合复用原则。

10.反射的使用场景、作用及优缺点?

使用场景:在编译时无法知道该对象或类可能属于那些类,程序在运行时获取对象和类的信息。
作用:通过反射可以是程序代码访问装载到JVM中的类的内部信息,获取已装载类的属性信息、方法信息。

优点
1.提高了Java程序的灵活性和扩展性,降低耦合性,提高自适应能力;
2.允许程序和控制任何类的对象,无需提前硬编码目标类;
3.应用很广,测试工具,框架都用到了反射;

缺点
1.性能问题:反射是一种解释操作,远慢于直接代码,因此反射机制主要用在对灵活性和扩展性要求很高的系统框架上,普通程序不建议使用;
2.模糊程序内部逻辑:反射绕过了源代码,无法在源代码中看到程序的逻辑,会带来维护问题。

11.关于String[] strArr = new String[10],String类是否可以继承?为什么String类被设计用final修饰

strArr的长度为10,引用数据类型的默认值为null。

不可以继承:String类在JDK中被广泛用用,为了保证正确性,安全性,String类是用final修饰,不能被继承,方法不可以被重写。

final修饰原因
1.String类是最常用的类之一,为了效率,禁止被继承和重写;
2.为了线程安全。String类中有很多调用底层的本地方法,调用了操作系统的API,如果方法可以重写,可能被植入;

恶意代码,破坏程序。Java的安全性也体现在这里。

12.String s = new String(“xyz”),创建几个String对象?String s = “a” + “b” + “c” + “d”,创建了几个对象?

两个或一个
1.第一次调用new String(‘xyz’)时,会在堆内存中创建一个字符串对象,同时在字符串常量池中创建一个对象’xyz’;
2.第二次调用new String(‘xyz)时,只会在堆内存中创建一个字符串对象,指向之前在字符串常量池中创建的’xyz’。

1个
Java编译器对字符串常量直接相加的表达式进行优化,不等到运行期去进行加法运算没在编译时就去掉了加号,直接将其编译成一个这些常量相连的结果,所以 ‘a’+‘b’+‘c’+'d’相当于直接定义一个‘abcd’的字符串。

13.对比一下Java和JavaScript

JavaScript与Java是两个公司开发的不同的两个产品。

  1. Java是Sun公司推出的面向对象的编程语言,现在多用于互联网服务端开发,前身是Oak;
  2. Javascript是Netscape公司推出的,为了扩展Netscape浏览器功能而开发的一种可以嵌入Web页面中运行的基于对象和事件驱动的解释型语言,前身是LiveScript。

区别:

  1. 面向对象和基于对象:Java是一种面向对象的语言;Javascript是一种基于对象和事件驱动的编程语言,提供了丰富的内部对象供开发者使用;
  2. 编译和解释:Java的源代码在执行之前,必须经过编译;JavaScript是一种解释型语言,其源代码不需要经过编译,由浏览器直接解释执行;
  3. 静态和动态语言:Java是静态语言(编译时变量的数据类型即可确定语言的语言);Javascript是动态语言(运行时确定数据类型的语言);
  4. 强类型变量和类型弱变量:Java采用强类型变量检查,所有变量在编译之前必须声明类型;JavaScript中变量声明,采用弱类型,即变量在使用前不需声明类型,解释器在运行时检查其数据类型。

14.什么是assert?

assert:断言

  1. 一种常见的调试方式,很多开发语言中都支持这种机制;
  2. 通常在开发和测试时开启;
  3. 可以用来保证程序最基本、关键的正确性;
  4. 为了提高性能,发布版的程序通常关闭断言;
  5. 断言是一个包含布尔表达式的语句,在执行这个语句时假定该表达式为true;如果表达式计算为false,会报一个AssertionError;
  6. 断言在默认的情况下是禁用的,要在编译时启用断言,需使用source1.4标记,如javac -source 1.4 TestAssert.java;
  7. 要在运行时启用断言,需加载参数 -ea 或 -enabkeassertions;
  8. 要在运行时选择禁用断言,需加参数 -da 或 -disableassertions;
  9. 要在系统类中启用或禁用断言,需加参数 -esa 或 -dsa;

Java中断言有两种语法方式:
1.assert 表达式1;
2.assert 表达式1 :错误表达式;
表达式1 是一个布尔值;
错误表达式可以得出一个值,用于生成显示调试信息的字符串信息。

15.说说反射在实际开发中的使用

反射主要用于底层的框架中,Spring中就大量使用了反射,如
1.用IoC来注入和组装bean;
2.动态代理、面向切面、bean对象中的方法替换与增强,也使用了反射;
3.定义的注解,也是通过反射查找。

16.什么是泛型?为什么要使用泛型?

泛型

  1. ‘参数化类型’,将类型由具体的类型参数化,把类型也定义成参数形式(称之类型形参),然后在使用/调用时传入具体的类型(类型实参);
  2. 是JDK5中引入的一个新特性,提供了编译时类型安全监测机制,该机制允许程序员在编译时监测非法的类型;
  3. 泛型的本质是把参数的类型参数化,也就是所操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中。

为什么要使用泛型

  1. 使用泛型编写的程序代码,要比使用Object变量再进行强制类型转换的代码更具安全性和可读性;
  2. 多种数据类型执行相同的代码使用泛型可以复用代码.

17.Java和C++的区别?

1.Java是解释型语言,所谓的解释型语言,就是源码会先经过一次编译,成为中间码,中间码再被解释器解释成机器码。对于Java而言,中间码就是字节码(.class),而解释器在JVM中内置了;

2.C++是编译型语言,所谓编译型语言,就是源码一次编译,直接在编译的过程中链接了,形成了机器码;

3.C++比Java执行速度快,但是Java可以利用JVM跨平台;

4.Java是纯面向对象的语言,所有代码(包括函数、变量)都必须在类中定义。而C++中还有面向过程的东西,比如是全局变量和全局函数;

5.C++中有指针,Java中没有,但是有引用;

6.C++支持多继承,Java中类都是单继承的。但是继承都有传递性,同时Java中的接口是多继承,类对接口的实现也是多实现;

7.C++中,开发需要自己去管理内存,但是Java中JVM有自己的GC机制,虽然有自己的GC机制,但是也会出现OOM和内存泄漏的问题。C++中有析构函数,Java中Object的finalize方法;

8.C++运算符可以重载,但是Java中不可以。同时C++中支持强制自动转型,Java中不行,会出现ClassCastException(类型不匹配)。

18.缓存优点是什么?

缓存主要是为了提高系统性能和处理高并发请求。当从数据库或者磁盘文件中读取速度较慢,并且结果不是易变的时候,将结果放入缓存,提高请求的响应速度;在高并发场景下,缓存的使用可以降低数据库等的压力。

19.请解释为什么集合类没有实现Cloneable和Serializable接口?

克隆(cloning)或者是序列化(serialization)的语义和含义是跟具体的实现相关的。因此,应该由集合类的具体实现来决定如何被克隆或者是序列化。

实现Serializable序列化的作用:将对象的状态保存在存储媒体中以便可以在以后重写创建出完全相同的副本;按值将对象从一个从一个应用程序域发向另一个应用程序域。

实现 Serializable接口的作用就是可以把对象存到字节流,然后可以恢复。所以你想如果你的对象没有序列化,怎么才能进行网络传输呢?要网络传输就得转为字节流,所以在分布式应用中,你就得实现序列化。如果你不需要分布式应用,那就没必要实现实现序列化。

20.请问Java的反射,主要用他做什么,Java的泛型,主要作用是什么?

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

Java反射可以用来获取一个class对象或实例化一个class表示的类的对象,还可以获取构造方法,成员变量,成员方法。

java中泛型的引入主要是为了解决两个方面的问题:

  1. 集合类型元素在运行期出现类型装换异常,增加编译时类型的检查;
  2. 解决的时重复代码的编写,能够复用算法。下面通过例子来说明编译器的类型检查。

21…jvm是如何实现线程的?

1.使用内核线程实现:内核线程(Kernel-Level Thread, KLT)就是直接由操作系统内核支持的线程,用户态和内核态切换消耗内核资源;

2 使用用户线程实现;

3 用户线程加轻量级进程混合实现:java虚拟机的多线程是通过线程轮流切换分配处理执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)都只会执行一条程序中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要一个独立的程序计数器,各条线程之间计数器互不影响,独立存储。简单点说,对于单核处理器,是通过快速切换线程执行指令来达到多线程的,因为单核处理器同时只能处理一条指令,只是这种切换速度很快,我们根本不会感知到。

22.请介绍一下什么是生产者消费者模式?

通过一个容器来解决生产者和消费者的强耦合关系,生产者生成数据无需等待消费者索取,消费者无需等待直接索要数据。两者并不进行任何通讯,而是通过容器来进行操作。可以实现解耦、支持并发,流量缓冲等功能。

23.请你讲讲一个十进制的数在内存中是怎么存的?

以二进制补码形式存储,最高位是符号位,正数的补码是它的原码,负数的补码是它的反码加1,在求反码时符号位不变,符号位为1,其他位取反。

猜你喜欢

转载自blog.csdn.net/qq_42748009/article/details/112002716
今日推荐