代码编织梦想

第一章 Java语言

1.Java基础(前面18个是重点)

1.8为啥要有包装类?

Java语言是面向对象的语言,其设计理念是“一切皆对象”。但8种基本数据类型却出现了例外,它们不具
备对象的特性。正是为了解决这个问题,Java为每个基本数据类型都定义了一个对应的引用类型,这就
是包装类。

扩展阅读
Java之所以提供8种基本数据类型,主要是为了照顾程序员的传统习惯。这8种基本数据类型的确带来了
一定的方便性,但在某些时候也会受到一些制约。比如,所有的引用类型的变量都继承于Object类,都
可以当做Object类型的变量使用,但基本数据类型却不可以。如果某个方法需要Object类型的参数,但
实际传入的值却是数字的话,就需要做特殊的处理了。有了包装类,这种问题就可以得以简化。

1.9 说一说自动装箱、自动拆箱的应用场景

自动装箱:可以把一个基本类型的数据直接赋值给对应的包装类型;

自动拆箱:可以把一个包装类型的对象直接赋值给对应的基本类型;

通过自动装箱、自动拆箱功能,可以大大简化基本类型变量和包装类对象之间的转换过程。比如,某个方法的参数类型为包装类型,调用时我们所持有的数据却是基本类型的值,则可以不做任何特殊的处理,直接将这个基本类型的值传入给方法即可。

1.12 说一说你对面向对象的理解

面向对象思想是一种更符合我们思考习惯的思想,并将我们从执行者变成了指挥者。面向对象是一种更优秀的程序设计方法,它的基本思想是使用类、对象、继承、封装、消息等基本概念进行程序设计。它从现实世界中客观存在的事物出发来构造软件系统,并在系统构造中尽可能运用人类的自然思维方式,强调直接以现实世界中的事物为中心来思考,认识问题,并根据这些事物的本质特点,把它们抽象地表示为系统中的类,作为系统的基本构成单元,这使得软件系统的组件可以直接映像到客观世界,并保持客观世界中事物及其相互关系的本来面貌。

扩展阅读
结构化程序设计方法主张按功能来分析系统需求,其主要原则可概括为自顶向下、逐步求精、模块化
等。结构化程序设计首先采用结构化分析方法对系统进行需求分析,然后使用结构化设计方法对系统进
行概要设计、详细设计,最后采用结构化编程方法来实现系统。

因为结构化程序设计方法主张按功能把软件系统逐步细分,因此这种方法也被称为面向功能的程序设计
方法;结构化程序设计的每个功能都负责对数据进行一次处理,每个功能都接受一些数据,处理完后输
出一些数据,这种处理方式也被称为面向数据流的处理方式。

结构化程序设计里最小的程序单元是函数,每个函数都负责完成一个功能,用以接收一些输入数据,函
数对这些输入数据进行处理,处理结束后输出一些数据。整个软件系统由一个个函数组成,其中作为程
序入口的函数被称为主函数,主函数依次调用其他普通函数,普通函数之间依次调用,从而完成整个软
件系统的功能。

每个函数都是具有输入、输出的子系统,函数的输入数据包括函数形参、全局变量和常量等,函数的输
出数据包括函数返回值以及传出参数等。结构化程序设计方式有如下两个局限性:

①设计不够直观,与人类习惯思维不一致。采用结构化程序分析、设计时,开发者需要将客观世界模
型分解成一个个功能,每个功能用以完成一定的数据处理。

②适应性差,可扩展性不强。由于结构化设计采用自顶向下的设计方式,所以当用户的需求发生改变,或需要修改现有的实现方式时,都需要自顶向下地修改模块结构,这种方式的维护成本相当高。

1.13面向对象的三大特征是什么?

封装、继承、多态。

①封装:将对象的实现细节 隐藏起来,然后通过一些公用方法来暴露该对象的功能;
②继承:面向对象实现软件复用的重要手段,当 子类继承父类后,子类作为一种特殊的父类,将直接获得父类的属性和方法;
③多态:子类对象可以 直接赋给父类变量,但运行时依然表现出子类的行为特征,这意味着同一个类型的对象在执行同一个方法时,可能表现出多种行为特征。

扩展阅读
抽象也是面向对象的重要部分,抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注 意与当前目标有关的方面。抽象并不打算了解全部问题,而只
是考虑部分问题。例如,需要考察Person 对象时,不能在程序中把Person的所有细节都定义出来,通常只能定义Person的部分数据、部分行为特征,而这些数据、行为特征是软件系统所关心的部分。

1.14封装的目的是什么,为什么要有封装?

封装是面向对象编程语言对客观世界的模拟,在客观世界里,对象的状态信息都被隐藏在对象内部,外 界无法直接操作和修改。对一个类或对象实现良好的封装,可以实现以下目的:
①隐藏类的实现细节;
②让使用者只能通过事先预定的方法来访问数据,从而可以在该方法里加入控制逻辑,限制对成员变 量的不合理访问;
③可进行数据检查,从而有利于保证对象信息的完整性;
④便于修改,提高代码的可维护性。

扩展阅读
为了实现良好的封装,需要从两个方面考虑:
①将对象的成员变量和实现细节隐藏起来,不允许外部直接访问;
②把方法暴露出来,让方法来控制对这些成员变量进行安全的访问和操作。

封装实际上有两个方面的含义:把该隐藏的隐藏起来,把该暴露的暴露出来。这两个方面都需要通过使 用Java提供的访问控制符来实现。

1.15说一说你对多态的理解

因为子类其实是一种特殊的父类,因此Java允许把一个子类对象直接赋给一个父类引用变量,无须任何 类型转换,或者被称为向上转型,向上转型由系统自动完成。当把一个子类对象直接赋给父类引用变量时,例如

BaseClass obj = new SubClass(); ,

这个obj引用变量的编译时类型是BaseClass,而运行时类型是SubClass,当运行时调用该引用变量的方法时,其 方法行为总是表现出子类方法的行为特征,而不是父
类方法的行为特征,这就可能出现:相同类型的变 量、调用同一个方法时呈现出多种不同的行为特征,这就是多态。

扩展阅读
多态可以提高程序的可扩展性,在设计程序时让代码更加简洁而优雅。例如我要设计一个司机类,他可以开轿车、巴士、卡车等等,示例代码如下:
在这里插入图片描述

在设计上述代码时,我已采用了重载机制,将方法名进行了统一。这样在进行调用时,无论要开什么交通工具,都是通过 这样的方式来调用,对调用者足够的友好。

但对于程序的开发者来说,这显得繁琐,因为实际上这个司机可以驾驶更多的交通工具。当系统需要为 这个司机增加车型时,开发者就需要相应的增加driver方法,类似的代码会堆积的越来越多,显得臃 肿。

采用多态的方式来设计上述程序,就会变得简洁很多。我们可以为所有的交通工具定义一个父类Vehicle,然后按照如下的方式设计drive方法。调用时,我们可以传入Vehicle类型的实例,也可以传入 任意的Vechile子类型的实例,对于调用者来说一样的方便,但对于开发者来说,代码却变得十分的简 洁了。
在这里插入图片描述

1.16 Java中的多态是怎么实现的?

多态的实现离不开继承。
在设计程序时,我们可以将参数的类型定义为父类型。在调用程序时,则可以 根据实际情况,传入该父类型的某个子类型的实例,这样就实现了多态。对于父类型,可以有三种形 式,即普通的类、抽象类、接口。对于子类型,则要根据它自身的特征,重写父类的某些方法,或实现 抽象类/接口的某些抽象方法。

1.20 介绍一下Object类中的方法

Object类提供了如下几个常用方法:
①Class<?> getClass():返回该对象的运行时类。
②boolean equals(Object obj):判断指定对象与该对象是否相等。
③int hashCode():返回该对象的hashCode值。在默认情况下,Object类的hashCode()方法根据该对象的地址来计算。但很多类都重写了Object类的hashCode()方法,不再根据地址来计算其hashCode()方法值。
④String toString():返回该对象的字符串表示,当程序使用System.out.println()方法输出一个对象,或者把某个对象和字符串进行连接运算时,系统会自动调用该对象的toString()方法返回该对 象的字符串表示。Object类的toString()方法返回 运行时类名@十六进制hashCode值 格式的字符串,但很多类都重写了Object类的toString()方法,用于返回可以表述该对象信息的字符串。

另外,Object类还提供了wait()、notify()、notifyAll()这几个方法,通过这几个方法可以控制线程的暂停和运行。Object类还提供了一个clone()方法,该方法用于帮助其他对象来实现“自我克隆”,所谓“自我克隆”就是得到一个当前对象的副本,而且二者之间完全隔离。由于该方法使用了protected修饰,因此它 只能被子类重写或调用。

1.21 说一说hashCode()和equals()的关系

hashCode()用于获取哈希码(散列码)。
eauqls()用于比较两个对象是否相等。

它们应遵守如下规定: 如果两个对象相等,则它们必须有相同的哈希码。如果两个对象有相同的哈希码,则它们未必相等。

1.22为什么要重写hashCode()和equals()?

Object类提供的equals()方法默认是用 == 来进行比较的,也就是说只有两个对象是 同一个对象时,才能返回相等的结果。

而实际中需求的是,若两个不同的对象它们的内容是相同的,就认为它们相等。

Object类中equals()方法的默认实现是没有实用价值的,所以通常都要重 写。由于hashCode()与equals()具有联动关系(参考“说一说hashCode()和equals()的关系”一题),所以equals()方法重写时,通常也要将hashCode()进行重写,使得这两个方法始终满足相关的约定。

1.23 ==和equals()有什么区别?

==运算符:
①作用于基本数据类型时,是比较两个数值是否相等;
②作用于引用数据类型时,是比较两个对象的内存地址是否相同,即判断它们是否为同一个对象;

equals()方法:
①没有重写时,Object默认以 来实现,即比较两个对象的内存地址是否相同;
②进行重写后,一般会按照对象的内容来进行比较,若两个对象内容相同则认为对象相等,否则认为 对象不等。

1.26说一说String和StringBuffer有什么区别

String类是不可变类,即一旦一个String对象被创建以后,包含在这个对象中的字符序列是不可改变 的,直至这个对象被销毁。

StringBuffer对象则代表一个字符序列可变的字符串,当一个StringBuffer被创建以后,通过StringBuffer提供的append()、insert()、reverse()、setCharAt()、
setLength()等方法可以改变这个字符串对象的字符序列。一旦通过StringBuffer生成了最终想要的字符串,就可以调用它的toString()方法 将其转换为一个String对
象。

1.27说一说StringBuffer和StringBuilder有什么区别

StringBuffer、StringBuilder都代表可变的字符串对象,它们有共同的父类AbstractStringBuilder ,并且两个类的构造方法和成员方法也基本相同。

不同的是StringBuffer 是线程安全的,而StringBuilder是非线程安全的,所以StringBuilder性能略高。一般情况下,要创建一 个内容可变的字符串,建议优先考虑StringBuilder类。

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

1.从设计目的上来说,二者有如下的区别:

接口体现的是一种规范。对于接口的实现者而言,接口规定了实现者必须向外提供哪些服务;对于接口 的调用者而言,接口规定了调用者可以调用哪些服务,以及如
何调用这些服务。当在一个程序中使用接 口时,接口是多个模块间的耦合标准;当在多个应用程序之间使用接口时,接口是多个程序之间的通信 标准。

抽象类体现的是一种模板式设计。抽象类作为多个子类的抽象父类,可以被当成系统实现过程中的中间 产品,这个中间产品已经实现了系统的部分功能,但这个产品依然不能当成最终产品,必须有更进一步 的完善,这种完善可能有几种不同方式。

2.从使用方式上来说,二者有如下的区别:
①接口里只能包含抽象方法、静态方法、默认方法和私有方法,不能为普通方法提供方法实现;抽象 类则完全可以包含普通方法。
②接口里只能定义静态常量,不能定义普通成员变量;抽象类里则既可以定义普通成员变量,也可以 定义静态常量。
③接口里不包含构造器;抽象类里可以包含构造器,抽象类里的构造器并不是用于创建对象,而是让 其子类调用这些构造器来完成属于抽象类的初始化操作。
④接口里不能包含初始化块;但抽象类则完全可以包含初始化块。
⑤一个类最多只能有一个直接父类,包括抽象类;但一个类可以直接实现多个接口,通过实现多个接 口可以弥补Java单继承的不足。

扩展阅读
接口和抽象类很像,它们都具有如下共同的特征:
①接口和抽象类都不能被实例化,它们都位于继承树的顶端,用于被其他类实现和继承。
②接口和抽象类都可以包含抽象方法,实现接口或继承抽象类的普通子类都必须实
现这些抽象方法。

1.41说一说你对static关键字的理解

在Java类里只能包含成员变量、方法、构造器、初始化块、内部类(包括接口、枚举)5种成员,而 static可以修饰成员变量、方法、初始化块、内部类(包括接口、
枚举),以static修饰的成员就是类成 员。类成员属于整个类,而不属于单个对象。

对static关键字而言,有一条非常重要的规则:类成员(包括成员变量、方法、初始化块、内部类和内 部枚举)不能访问实例成员(包括成员变量、方法、初始化块、内部类和内部枚举)。因为类成员是属 于类的,类成员的作用域比实例成员的 作用域更大,完全可能出现类成员已经初始化完成,但实例成员 还不曾初始化的情况,如果允许类成员访问实例成员将会引起大量错误。

1.43 static和final有什么区别?

static关键字可以修饰成员变量、成员方法、初始化块、内部类,被static修饰的成员是类的成员,它属 于类、不属于单个对象。以下是static修饰这4种成员时表现出
的特征:
①类变量:被static修饰的成员变量叫类变量(静态变量)。类变量属于类,它随类的信息存储在方 法区,并不随对象存储在堆中,类变量可以通过类名来访
问,也可以通过对象名来访问,但建议通 过类名访问它。
②类方法:被static修饰的成员方法叫类方法(静态方法)。类方法属于类,可以
通过类名访问,也 可以通过对象名访问,建议通过类名访问它。
③静态块:被static修饰的初始化块叫静态初始化块。静态块属于类,它在类加载的时候被隐式调用 一次,之后便不会被调用了。
④静态内部类:被static修饰的内部类叫静态内部类。静态内部类可以包含静态成员,也可以包含非 静态成员。静态内部类不能访问外部类的实例成员,只能访问外部类的静态成员。外部类的所有方 法、初始化块都能访问其内部定义的静态内部类。

final关键字可以修饰类、方法、变量,以下是final修饰这3种目标时
①表现出的特征: final类:final关键字修饰的类不可以被继承。
②final方法:final关键字修饰的方法不可以被重写。
③final变量:final关键字修饰的变量,一旦获得了初始值,就不可以被修改。

1.47 说一说你对Java反射机制的理解

1.49 说一说Java的四种引用方式

1.1 为什么Java代码可以实现一次编写、到处运行?

因为有JVM,这是是Java跨平台的关键。

在程序运行前,Java源代码(.java)需要经过编译器编译成字节码(.class)。

在程序运行时,JVM将字节码翻译成特定平台下的机器码并运行,也就是说,只要在不同的平台上安装对应的JVM,就可以运行字节码文件。

注意事项

  1. 编译的结果是生成字节码,字节码不能直接运行,必须通过JVM翻译成机器码才能运行;
  2. 跨平台的是Java程序、而不是JVM,JVM是C/C++开发的软件,不同平台下需要安装不同版本的JVM。

1.2 一个Java文件里可以有多个类吗(不含内部类)?

  1. 一个java文件里可以有多个类,但最多只能有一个被public修饰的类;
  2. 如果这个java文件中包含public修饰的类,则这个类的名称必须和java文件名一致。

1.3 说一说你对Java访问权限的了解

提供了三种访问修饰符,即private、protected、public,在使用这些修饰符修饰目标时,一共可以形成四种访问权限,即private、defalut、protected、public,注意在不加任何修饰符时为default访问权限。

不加权限修饰符,其访问能力与default修饰符相同。竖着记忆:我自己,我邻居,我儿子,陌生人。
在这里插入图片描述
在修饰时,该类只有两种访问权限,对应的访问权限的含义如下:
①defalut:该类可以被同一包下其他的类访问。
②public:该类可以被任意包下,任意的类所访问。

1.4介绍一下Java的数据类型

Java数据类型包括:基本数据类型,引用数据类型两大类。

①基本数据类型有8个,可以分为4个小类,分别是整数类型(byte/short/int/long)、浮点类型
(float/double)、字符类型(char)、布尔类型(boolean)。

其中,4个整数类型中,int类型最为常用。2个浮点类型中,double最为常用。

另外,在这8个基本类型当中,除了布尔类型之外的其他7个类型,都可以看做是数字类型,它们相互之间可以进行类型转换。

②引用类型就是对一个对象的引用,根据引用对象类型的不同,可以将引用类型分为3类,即数组、类、接口类型。

引用类型本质上就是通过指针,指向堆中对象所持有的内存空间,只是Java语言不再沿用指针这个说法而已。

③扩展阅读
对于基本数据类型,你需要了解每种类型所占据的内存空间,面试官可能会追问这类问题:
在这里插入图片描述
对于引用数据类型,需要了解JVM的内存分布情况,知道引用以及引用对象存放的位置,详见JVM部
分的题目。

1.5 int类型的数据范围是多少?

int类型占4字节(32位),数据范围是 -2^31 ~ 2^31-1 。

1.6 请介绍全局变量和局部变量的区别

在这里插入图片描述

注意事项:Java中没有真正的全局变量,面试官应该是出于其他语言的习惯说全局变量的,他的本意应该是指成员变量。

1.7 请介绍一下实例变量的默认值

实例变量若为引用数据类型,其默认值一律为null。

若为基本数据类型,其默认值如下:
byte:0
short:0
int:0
long:0L
float:0.0F
double:0.0
char:’\u0000’
boolean:false

注意事项:上述默认值规则适用于所有的成员变量,所以对于类变量也是适用的。

1.10 如何对Integer和Double类型判断相等?

Integer、Double不能直接进行比较,这包括:
1.不能用==进行直接比较,它们是不同的数据类型;
2.不能转为字符串进行比较,转为字符串后,浮点值带小数点,整数值不带,也不相等;
3.不能使用compareTo方法进行比较,该方法只能对相同类型进行比较。

整数、浮点类型的包装类,都继承于Number类型,而Number类型分别定义了将数字转换为byte、short、int、long、float、double的方法。所以,可以将Integer、Double先转为转换为相同的基本数据类型(如double),然后使用==进行比较

示例代码

Integer i = 100;
Double d = 100.00;
System.out.println(i.doubleValue() == d.doubleValue());

1.11 int和Integer有什么区别,二者在做==运算时会得到什么结果?

int是基本数据类型,Integer是int的包装类。二者在做==运算时,Integer会自动拆箱为int类型,然后再进行比较。如果两个int值相等则返回true,否则就返回false。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_40532137/article/details/123616667

java面试题全集(上)-爱代码爱编程

2013年年底的时候,我看到了网上流传的一个叫做《Java面试题大全》的东西,认真的阅读了以后发现里面的很多题目是重复且没有价值的题目,还有不少的参考答案也是错误的,于是我花了半个月时间对这个所谓的《Java面试大全》进行了

最新java面试题,常见面试题及答案汇总_jack方的博客-爱代码爱编程_java面试题

Java最新常见面试题 + 答案汇总 原文地址:https://blog.csdn.net/sufu1065/article/details/88051083 1、面试题模块汇总 面试题包括以下十九个模块: J

常用工具类StringUtils-爱代码爱编程

public class StringUtils { // 两次点击间隔不能少于1000ms private static final int FAST_CLICK_DELAY_TIME = 2000; private static long lastClickTime; public static boolean isFastClick() {