1 何为编程
编程就是让计算机为解决某个问题而使用某种程序设计语言编写程序代码,并 终得到结果的过程。
2 什么是Java
Java是一门面向对象编程语言
,不仅吸收了C++语言的各种优点
,还摒弃了 C++里
难以理解的多继承、指针等
概念
Java语言具有功能强大和简单易用
两个特征
3 jdk1.5之后的三大版本
Java SE(标准版): Java SE 以前称为 J2SE。它允许开发和部署在桌面、服务器、嵌入式环境和实时环境中使 用的 Java 应用程序。Java SE 包含了支持 JavaWeb 服务开发的类,并为Java EE和Java ME提供基础
。
Java EE(企业版): Java EE 以前称为 J2EE。企业版本帮助开发和部署可移植、健壮、可伸缩且安全的服务器 端Java 应用程序。Java EE 是在 Java SE 的基础上构建的,它提供 Web 服务、组件模型、 管理和通信 API,可以用来实现企业级的面向服务体系结构(SOA)和 Web2.0应用程序
。2018年2月,Eclipse 宣布正式将 JavaEE 更名 为 JakartaEE
Java ME(微型版) Java ME 以前称为 J2ME。Java ME 为在移动设备和嵌入式设备(比如手机、PDA、电视 机顶盒和打印机)上运行的应用程序提供一个健壮且灵活的环境。Java ME 包括灵活的用 户界面、健壮的安全模型、许多内置的网络协议以及对可以动态下载的连网和离线应用程序 的丰富支持。基于 Java ME 规范的应用程序只需编写一次,就可以用于许多设备,而且可以利用每个设备的本机功能
。
4 JVM、JRE和JDK的关系
4.1 JVM
是Java虚拟机,Java程序需要运行在虚拟机上,不同的平台有自己的虚拟机,因此Java语言可以实现跨平台
。
4.2 JRE
包括Java虚拟机和Java程序所需的核心类库等
。
- 核 心类库主要是java.lang包:包含了运行Java程序必不可少的系统类,如基本数 据类型、基本数学函数、字符串处理、线程、异常处理类等,系统缺省加载这个包
- JVM
如果想要运行一个开发好的Java程序,计算机中只需要安装JRE即可
。
4.3 JDK
是提供给Java开发人员使用的,其中包含了Java的开发工具,也包括了JRE
。所以安装了JDK,就无需再单独安装JRE
了。
其中的开发工 具:
- 编译工具(javac.exe),
- 打包工具(jar.exe)等
5 什么是跨平台性?
Java
中引入了虚拟机的概念,即在机器和编译程序之间加入了一层抽象的虚拟机器
。这台虚拟的机器在任何平台上都提供给编译程序一个的共同的接口。
所谓跨平台性,是指java语言编写的程序,一次编译后,可以在多个系统平台上运行
。
6 原理是什么
实现原理:Java程序是通过java虚拟机在系统平台上运行的,只要该系统可以安装相应的java虚拟机,该系统就可以运行java程序
。
7 Java语言有哪些特点
简单易学
(Java语言的语法与C语言和C++语言很接近)
面向对象
(封装,继承,多态)
平台无关性
(Java虚拟机实现平台无关性)
支持网络编程并且很方便
(Java语言诞生本身就是为简化网络编程设计的)
支持多线程
(多线程机制使应用程序在同一时间并行执行多项任)
健壮性
(Java语言的强类型机制、异常处理、垃圾的自动收集等)
安全性
8 什么是字节码?
字节码:Java源代码经过虚拟机编译器编译后产生的文件
(即扩展为.class的文 件
),它不面向任何特定的处理器,只面向虚拟机。
9 采用字节码的好处
Java语言通过字节码
的方式,
- 在一定程度上
解决了传统解释型语言执行效率低
的问题, - 同时又
保留了解释型语言可移植
的特点。 - 由于1和2的特点,所以Java程序运行时比较高效,
- 由于字节码并不专对一种特定的机器,因此,Java程序无须重新编译便可在多种不同的计算机上运行。
10 java中的编译器和解释器实现的跨平台
Java
中引入了虚拟机的概念,即在机器和编译程序之间加入了一层抽象的虚拟机器
。这台虚拟的机器在任何平台上都提供给编译程序一个的共同的接口。
编译程序只需要面向虚拟机,生成虚拟机能够理解的代码,然后由解释器
来将虚拟机代码转换为特定系统的机器码执行
。
在Java中,这种供虚拟机理解的代码叫做字节码(即扩展为.class的文件),它不面向任何特定的处理器,只面向虚拟机。
每一种平台的解释器是不同的,但是实现的虚拟机是相同的
。
11 java编译程序的执行过程(编译与解释并存的解释)
Java源程序经过编译器编译后变成字节码:
- 字节码由虚拟机解释执行,虚拟机将每一条要执行的字节码送给解释器,
- 解释器将其翻译成特定机器上的机器码,
- 然后在特定的机器上运行,这就是上面提到的Java的特点的
编译与解释并存的解释
。
Java源代码---->编译器---->jvm可执行的Java字节码(即虚拟指令)---->jvm---->jvm中 解释器-----> 机器可执行的二进制机器码---->程序运行
。
12 Java和C++的区别
都是面向对象的语言,都支持封装、继承和多态
Java不提供指针来直接访问内存
,程序内存更加安全
Java的类是单继承
的,C++支持多重继承
;虽然Java的类不可以多继承,但是接口可以多实现。
Java有自动内存管理机制
,不需要程序员手动释放无用内存
13 Java有哪些数据类型
数据类型分为:基本数据类型和引用数据类型
13.1 基本数据类型
类型 | 类型名称 | 关键字 | 占用内存 |
---|---|---|---|
整形 | 字节型 | byte | 1字节 |
短整型 | short | 2字节 | |
整型 | int | 4字节 | |
长整型 | long | 8字节 | |
浮点型 | 双精度浮点型 | double | 8字节 |
单精度浮点型 | float | 4字节 | |
字符型 | 字符型 | char | 2字节 |
布尔型 | 布尔型 | boolean | 1字节 |
13.2 引用数据类型
类(class)
接口(interface)
数组([])
14 switch 可以接收的数据类型
在 Java 5 以前
,switch(expr)中,expr 只能是 byte、short、char、int
。
从 Java5 开始
,Java 中引入了枚举类型
,expr 也可以是 enum 类型,
从 Java 7 开始
,expr 还可以是字符串(String)
,
但是长整型(long)在目前所有的版本中都是不可以的
15 用最有效率的方法计算 2 乘以 8
2 << 3
(左移 3 位相当于乘以 2 的 3 次方,右移 3 位相当于除以 2 的 3 次 方)。
16 Math.round(11.5) 等于多少?Math.round(-11.5) 等于多少
Math.round(11.5
)的返回值是 12
,Math.round(-11.5)
的返回值是-11
。
四舍五入的原理是在参数上加0.5 然后进行下取整
。
17 float f=3.4;是否正确
不正确
。
3.4 是双精度数
,
将双精度型(double)赋值给浮点型(float)属于下转型
(down-casting,也称为窄化)会造成精度损失
,
因此需要强制类型转换float f =(float)3.4; 或者写成 float f =3.4F;
。
18 short s1 = 1; s1 = s1 + 1;有错吗?short s1 = 1; s1 += 1;有错吗
对于 short s1 = 1; s1 = s1 + 1;
- 由于
1 是 int 类型,因此 s1+1 运算结果也是 int型
,需要强制转换类型才能赋值给 short 型。
而 short s1 = 1; s1 += 1;可以正确编译
,
- 因为
s1+= 1;相当于 s1 = (short(s1 + 1)
;其
中有隐含的强制类型转换
。
19 &和&&的区别
&运算符有两种用法:(1)按位与;(2)逻辑与。
&&运算符是短路与运算
。逻辑与跟短路与的差别是非常巨大的,虽然二者都要求运算符左右两端的布尔值都是true 整个表达式的值才是 true。
- &&之所以称为短路运算,是因为如果&&左边的表达式的值是 false,右边的表达式会被直接短路掉,不会进行运算
辑或运算符(|)和短路或运算符(||)的差别也是如此。
20 Java 有没有 goto
goto 是 Java 中的保留字
,在目前版本的 Java 中没有使用。
21 final的作用
用于修饰类、属性和方法
;
- 被final修饰的
类不可以被继承
- 被final修饰的
方法不可以被重写
- 被final修饰的
变量不可以被改变
,被final修饰不可变的是变量的引用,而不是引用指向的内容,引用指向的内容是可以改变的
22 final finally finalize区别
final
可以修饰类、变量、方法
,
finally
一般作用在try-catch代码块
中,在处理异常的时候,通常我们将一定要执行的代码方法;finally代码块中,表示不管是否出现异常,该代码块都会执行
,一般用来存放一些关闭资源的代码。
finalize
是一个方法,属于Object类的一个方法
,而Object类是所有类的父类,该方法一般由垃圾回收器来调用
,当我们调用System.gc() 方法的时候,由垃圾回收器调用finalize(),回收垃圾,`一个对象是否可回收的最后判断``。
23 this关键字的用法
this
是自身的一个对象,代表对象本身
,可以理解为:指向对象本身的一个指针
this在java的用法
- 普通的直接引用,this相当于是指向当前对象本身
- 形参与成员名字重名,用this来区分:
public Person(String name, int age) { this.name = name; this.age = age; }
- 引用本类的构造函数
class Person{
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person(String name, int age) {
this(name);
this.age = age;
}
}
24 super关键字的用法
super可以理解为是指向自己超(父)类对象的一个指针
,
超类指的是离自己最近的一个父类
。
super的三种用法
-
普通的直接引用
-
子类中的成员变量或方法与父类中的成员变量或方法同名时,用super进行区分
-
.引用父类构造函数
super(参数):调用父类中的某一个构造函数(应该为构造函数中的第一条语句
)。
this(参数):调用本类中另一种形式的构造函数(应该为构造函数中的第一条语句
)。
25 this与super的区别
1:super: 它引用当前对象的直接父类中的成员
用来访问直接父类中被隐藏的父类中成员数据或函数
,基类与派生类中有相同成员定义时
2:this:它代表当前对象名
- 在程序中
易产生二义性之处
,应使用this来指明当前对象
; - 如果
函数的形参与类中的成员数据同名
,这时需用this来指明成员变量名
super()和this()类似,区别是,
-
super()在子类中调用父类的构造方法,this()在本类内调用本类的其它构造方法。
-
super()和this()
均需放在构造方法内第一行
。 -
尽管可以用this调用一个构造器,但却
不能调用两个
。 -
this和super
不能同时出现在一个构造函数里面
, -
this()和super()都指的是对象,所以,
均不可以在static环境中使用
。 -
从本质上讲,
this是一个指向本对象的指针,
然而super是一个Java关键字
。
26 static存在的主要意义
主要意义是在于创建独立于具体对象的域变量或者方法
。以致于即使没有创建对象,也能使用属性和调用方法!
另一个比较关键的作用就是:用来形成静态代码块以优化程序性能
。
27 static 特点
1:被static修饰的变量或者方法是独立于该类的任何对象,也就是说,这些变量和方法不属于任何一个实例对象,而是被类的实例对象所共享
2:在该类被第一次加载的时候,就会去加载被static修饰的部分,而且只在类第一次使用时加载并进行初始化
,注意这是第一次用就要初始化,后面根据需要是可以再次赋值的。
3:static变量值在类加载的时候分配空间
,以后创建类对象的时候不会重新分配。赋值是可以任意赋值的
!
4:被static修饰的变量或者方法是优先于对象存在的
,也就是说当一个类加载完毕之后,即便没有创建对象,也可以去访问
28 static注意事项
1、静态只能访问静态。 2、非静态既可以访问非静态的,也可以访问静态的。
29 break ,continue ,return 的区别及作用
break
跳出总上一层循环,不再执行循环(结束当前的循环体
)
continue
跳出本次循环,继续执行下次循环(结束正在执行的循环 进入下一个循环条件
)
return
程序返回,不再执行下面的代码(结束当前的方法 直接返回
)
30 如何跳出当前的多重嵌套循环
1 :使用标记,比如flag为false时跳出
2 :在外面的循环语句前定义一个标号,然后在里层循环体的代码中使用带有标号的break 语句,即可跳出外层循环。例如:
public static void main(String[] args) {
ok:
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
System.out.println("i=" + i + ",j=" + j);
if (j == 5) {
break ok;
}
}
}
}
31 面向过程优缺点
优点
:性能比面向对象高
,因为类调用时需要实例化,开销比较大,比较消耗资源
缺点
:没有面向对象易维护、易复用、易扩展
32 面向对象优缺点
优点
:易维护、易复用、易扩展,
由于面向对象有封装、继承、多态性的特性,可以设计出低耦合
的系统,使系统更加灵活、更加易于维护
缺点
:性能比面向过程低
;
面向对象是模型化的,类似一个封闭的盒子,在这里你拥有数据也拥有解决问题的方法。需要什么功能直接使用就可以了
,不必去一步一步的实现,至于这个功能是如何实现的是没有必要去关注的。
面向对象的底层其实还是面向过程
,把面向过程抽象成类,然后封装,方便我们使用的就是面向对象
29 面向对象三大特性
抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行 抽象两方面。
抽象只关注对象有哪些属性和行为,并不关注这些行为的细节是 什么
29.1 多态
父类
或接口定义的引用变量可以指向子类或具体实现类的实例对象
。提高了程序的拓展性。
在Java中有两种形式可以实现多态:
继承
(多个子类对同一方法的重写)接口
(实现接口并覆盖接口中同一方法)。
方法重载
(overload)实现的是编译时的多态性
(也称为前绑定),
方法重写
(override)实现的是运行时的多态性
(也称为后绑定)。
29.2 封装
封装把一个对象的属性私有化,同时提供一些可以被外界访问的属性的方法
29.3 继承
继承是使用已存在的类的定义作为基础建立新类的技术,
新类的定义可以增加新的数据或新的功能
,也可以用父类的功能,但不能选择性地继承父类。通过使用 继承我们能够非常方便地复用以前的代码。
关于继承如下 3 点请记住:
- 子类拥有父类非 private 的属性和方法。
- 子类可以拥有自己属性和方法,即子类可以对父类进行扩展。
- 子类可以用自己的方式实现父类的方法
30 什么是多态机制?
所谓多态就是指程序
中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定
,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。
不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态
,这就是多态性
31 如何实现多态
Java实现多态有三个必要条件:继承、重写、向上转型
。
继承:在多态中必须存在有继承关系的子类和父类
。
重写
:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。
向上转型
:在多态中需要将子类的引用赋给父类对象,只有这样该引用才能够具备调用父类的方法和子类的方法
32 抽象类和接口的对比
抽象类
是用来捕捉子类的通用特性
的。
接口是抽象方法的集合
。
相同点
- 接口和抽象类
都不能实例化
- 都位于继承的顶端,
用于被其他实现或继承
都包含抽象方法
,其子类都必须覆写这些抽象方法
不同点:
Java8中接口中引入默认方法和静态方法,以此来减少抽象类和接口之间 的差异。
在接口和抽象类的选择上,必须遵守这样一个原则
- 行为模型应该总是通过接口而不是抽象类定义,所以
通常是优先选用接口,尽量少用抽象类
。 选择抽象类
的时候通常是如下情况:需要定义子类的行为,又要为子类提供通用的功能
33 普通类和抽象类的区别?
普通类不能包含抽象方法,抽象类可以包含抽象方法。
抽象类不能直接实例化,普通类可以直接实例化。
34 抽象类能使用 final 修饰吗?
不能
,定义抽象类就是让其他类继承的,如果定义为 final 该类就不能被继承, 这样彼此就会产生矛盾,所以 final 不能修饰抽象类
35 创建一个对象用什么关键字?
new关键字
36 对象实例与对象引用有何不同?
new创建对象实例(对象实例在堆内存中),对象引用指向对象实例
(对象引用存放在栈内存中)。
一个对象引用可以指向0个或1个对象;一个对象可以有n个引用指向它
37 在调用子类构造方法之前会先调用父类没有参数的构造方法,其 目的是?
帮助子类做初始化工作。
38 一个类的构造方法的作用是什么?
要作用是完成对类对象的初始化工作。
39 若一个类没有声明构造方法, 该程序能正确执行吗?
可以执行
。因为一个类即使没有声明构造方法也会有默认的不带参数的构造方法。
40 构造方法的特性?
名字与类名相同
;
没有返回值
,但不能用void声明构造函数;
生成类的对象时自动执行,无需调用
。
41 构造器(constructor)是否可被重写(override)
构造器不能被继承,因此不能被重写,但可以被重载。
42 重载(Overload)和重写(Override)的区别
方法的重载和重写都是实现多态的方式
,
区别在于前者实现的是编译时的多态
性,而后者实现的是运行时的多态
性。
重载:发生在同一个类中
,方法名相同参数列表不同(参数类型不同、个数不 同、顺序不同),与方法返回值和访问修饰符无关,即重载的方法不能根据返回 类型进行区分
重写:发生在父子类中
,方法名、参数列表必须相同,返回值小于等于父类
,抛出的异常小于等于父类
,访问修饰符大于等于父类
(里氏代换原则);如果父类方法访问修饰符为private则子类中就不是重写
。
41 == 和 equals 的区别是
==
: 它的作用是判断两个对象的地址是不是相等。即,判断两个对象是不是同一个对象
。
基本数据类型
==比较的是值
,引用数据类型
== 比较的是内存地址
)
equals() : 它的作用也是判断两个对象是否相等。但它一般有两种使用情况:
- 情况1:
类没有覆盖equals() 方法
。则通过 equals() 比较该类的两个对象时,等价于通过“==”比较这两个对象
。 - 情况2:
类覆盖了equals() 方法
。一般,我们都覆盖 equals() 方法来两个对象的内容相等
;若它们的内容相等,则返回 true (即,认为这两个对象相等)。
String中的equals方法是被重写过的
当创建String类型的对象时,虚拟机会在常量池中查找有没有已经存在的值和要 创建的值相同的对象,如果有就把它赋给当前引用。如果没有就在常量池中重新创建 一个String对象。
42 hashCode()介绍
hashCode()
的作用是获取哈希码
,也称为散列码;它实际上是返回一个int整数
。
这个哈希码的作用
是确定该对象在哈希表中的索引位置
。
hashCode() 定义 在JDK的Object.java中,这就意味着Java中的任何类都包含有hashCode()函数
。
43 散列表
散列表
存储的是键值对(key-value)
,它的特点是:能根据“键”快速的检索出 对应的“值”
。这其中就利用到了散列码!(可以快速找到所需要的对象)
44 为什么要有 hashCode
减少equals 的次数,相应就大大提高了执行速度。
比如HashSet中
45 hashCode()与equals()的相关规定(重写和覆盖)
如果两个对象相等
,则hashcode一定也是相同
的
两个对象相等
,对两个对象分别调用equals方法都返回true ,两个对象有相同的hashcode值
,它们也不一定是相等的
;
因此,如果equals 方法被覆盖过,则 hashCode 方法也必须被覆盖
hashCode() 的默认行为是对堆上的对象产生独特值
。如果没有重写hashCode(),则该 class 的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)
46 对象的相等与指向他们的引用相等,两者有什么不同
对象的相等
: 比的是内存中存放的内容
是否相等而
引用相等
: 比较的是他们指向的内存地址
是否相等。
47 值传递
当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里是值传递。
Java 语言的方法调用只支持参数的值传递
。
当一个对象实例作为一 个参数被传递到方法中时,参数的值就是对该对象的引用
。对象的属性
可以在被调用过程中被改变,但对对象引用
的改变是不会影响到调用者的
48 按值调用和按引用调用
按值调用
(call byvalue)表示方法接收的是调用者提供的值
,
按引用调用
(call by reference)表示方法接收的是调用者提供的变量地址
。
一个方法可以修改传递引用所对应的变量值
,而不能修改传递值调用
所对应的变量值。
49 为什么 Java 中只有值传递
Java程序设计语言总是采用按值调用
。
也就是说,方法得到的是所有参数值的一个拷贝
,也就是说,方法不能修改传递给它的任何参数变量的内容
。
50 值传递和引用传递有什么区别
值传递
:指的是在方法调用时,传递的参数是按值的拷贝传递,传递的是值的拷贝,也就是说传递后就互不相关
了。
引用传递
:指的是在方法调用时,传递的参数是按引用进行传递,其实传递的引 用的地址,也就是变量所对应的内存空间的地址。传递的是值的引用,也就是说 传递前和传递后都指向同一个引用
(也就是同一个内存空间)。