这节我们回到梦开始的地方——Java基础,其实过了萌新阶段,面试问基础就问的不多,但是保不齐突然问一下。想一下,总不能张口高并发、闭口分布式,结果什么是面向对象,说不清,那多少有点魔幻。所以赶紧来看看,这些基础有没有你不会的!
Java概述
1.什么是Java?
PS:碎怂Java,有啥好介绍的。哦,面试啊。
Java是一门面向对象的编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的优秀代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程 。
2.Java语言有哪些特点?
Java语言有很多优秀(可吹)的特点,以下几个是比较突出的:
- 面向对象(封装,继承,多态);
- 平台无关性,平台无关性的具体表现在于,Java 是“一次编写,到处运行(Write Once,Run any Where)”的语言,因此采用 Java 语言编写的程序具有很好的可移植性,而保证这一点的正是 Java 的虚拟机机制。在引入虚拟机之后,Java 语言在不同的平台上运行不需要重新编译。
- 支持多线程。C++ 语言没有内置的多线程机制,因此必须调用操作系统的多线程功能来进行多线程程序设计,而 Java 语言却提供了多线程支持;
- 编译与解释并存;
3.JVM、JDK 和 JRE 有什么区别?
JVM:Java Virtual Machine,Java虚拟机,Java程序运行在Java虚拟机上。针对不同系统的实现(Windows,Linux,macOS)不同的JVM,因此Java语言可以实现跨平台。
JRE: Java 运⾏时环境。它是运⾏已编译 Java 程序所需的所有内容的集合,包括 Java 虚拟机(JVM),Java 类库,Java 命令和其他的⼀些基础构件。但是,它不能⽤于创建新程序。
JDK: Java Development Kit,它是功能⻬全的 Java SDK。它拥有 JRE 所拥有的⼀切,还有编译器(javac)和⼯具(如 javadoc 和 jdb)。它能够创建和编译程序。
简单来说,JDK包含JRE,JRE包含JVM。
4.说说什么是跨平台性?原理是什么
所谓跨平台性,是指Java语言编写的程序,一次编译后,可以在多个系统平台上运行。
实现原理:Java程序是通过Java虚拟机在系统平台上运行的,只要该系统可以安装相应的Java虚拟机,该系统就可以运行java程序。
5.什么是字节码?采用字节码的好处是什么?
所谓的字节码,就是Java程序经过编译之类产生的.class文件,字节码能够被虚拟机识别,从而实现Java程序的跨平台性。
Java 程序从源代码到运行主要有三步:
- 编译:将我们的代码(.java)编译成虚拟机可以识别理解的字节码(.class)
- 解释:虚拟机执行Java字节码,将字节码翻译成机器能识别的机器码
- 执行:对应的机器执行二进制机器码
只需要把Java程序编译成Java虚拟机能识别的Java字节码,不同的平台安装对应的Java虚拟机,这样就可以可以实现Java语言的平台无关性。
6.为什么说 Java 语言“编译与解释并存”?
高级编程语言按照程序的执行方式分为编译型和解释型两种。
简单来说,编译型语言是指编译器针对特定的操作系统将源代码一次性翻译成可被该平台执行的机器码;解释型语言是指解释器对源程序逐行解释成特定平台的机器码并立即执行。
比如,你想读一本外国的小说,你可以找一个翻译人员帮助你翻译,有两种选择方式,你可以先等翻译人员将全本的小说(也就是源码)都翻译成汉语,再去阅读,也可以让翻译人员翻译一段,你在旁边阅读一段,慢慢把书读完。
Java 语言既具有编译型语言的特征,也具有解释型语言的特征,因为 Java 程序要经过先编译,后解释两个步骤,由 Java 编写的程序需要先经过编译步骤,生成字节码(\*.class
文件),这种字节码必须再经过JVM,解释成操作系统能识别的机器码,在由操作系统执行。因此,我们可以认为 Java 语言编译与解释并存。
基础语法
7.Java有哪些数据类型?
定义:Java语言是强类型语言,对于每一种数据都定义了明确的具体的数据类型,在内存中分配了不同大小的内存空间。
Java语言数据类型分为两种:基本数据类型和引用数据类型。
基本数据类型:
- 数值型
- 整数类型(byte、short、long)
- 浮点类型(float、long)
- 字符型(char)
- 布尔型(boolean)
Java基本数据类型范围和默认值:
基本类型 | 位数 | 字节 | 默认值 |
---|---|---|---|
int |
32 | 4 | 0 |
short |
16 | 2 | 0 |
long |
64 | 8 | 0L |
byte |
8 | 1 | 0 |
char |
16 | 2 | 'u0000' |
float |
32 | 4 | 0f |
double |
64 | 8 | 0d |
boolean |
1 | false |
引用数据类型:
- 类(class)
- 接口(interface)
- 数组([])
8.自动类型转换、强制类型转换?看看这几行代码?
Java 所有的数值型变量可以相互转换,当把一个表数范围小的数值或变量直接赋给另一个表数范围大的变量时,可以进行自动类型转换;反之,需要强制转换。
这就好像,小杯里的水倒进大杯没问题,但大杯的水倒进小杯就不行了,可能会溢出。
float f=3.4
,对吗?
不正确。3.4 是单精度数,将双精度型(double)赋值给浮点型(float)属于下转型(down-casting,也称为窄化)会造成精度损失,因此需要强制类型转换float f =(float)3.4;
或者写成 float f =3.4F
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);其中有隐含的强制类型转换。
9.什么是自动拆箱/封箱?
- 装箱:将基本类型用它们对应的引用类型包装起来;
- 拆箱:将包装类型转换为基本数据类型;
Java可以自动对基本数据类型和它们的包装类进行装箱和拆箱。
举例:
Integer i = 10; //装箱
int n = i; //拆箱
复制代码
10.&和&&有什么区别?
&运算符有两种用法:短路与
、逻辑与
。
&&运算符是短路与运算。逻辑与跟短路与的差别是非常巨大的,虽然二者都要求运算符左右两端的布尔值都是true 整个表达式的值才是 true。
&&之所以称为短路运算是因为,如果&&左边的表达式的值是 false,右边的表达式会被直接短路掉,不会进行运算。很多时候我们可能都需要用&&而不是&。
例如在验证用户登录时判定用户名不是 null 而且不是空字符串,应当写为 username != null &&!username.equals("")
,二者的顺序不能交换,更不能用&运算符,因为第一个条件如果不成立,根本不能进行字符串的 equals 比较,否则会产生 NullPointerException 异常。
注意:逻辑或运算符(|)和短路或运算符(||)的差别也是如此。
11.switch 是否能作用在 byte/long/String上?
Java5 以前 switch(expr)中,expr 只能是 byte、short、char、int。
从 Java 5 开始,Java 中引入了枚举类型, expr 也可以是 enum 类型。
从 Java 7 开始,expr还可以是字符串(String),但是长整型(long)在目前所有的版本中都是不可以的。
12.break ,continue ,return 的区别及作用?
- break 跳出整个循环,不再执行循环(结束当前的循环体)
- continue 跳出本次循环,继续执行下次循环(结束正在执行的循环 进入下一个循环条件)
- return 程序返回,不再执行下面的代码(结束当前的方法 直接返回)
13.用最有效率的方法计算2乘以8?
2 << 3。位运算,数字的二进制位左移三位相当于乘以2的三次方。
14.说说自增自减运算?看下这几个代码运行结果?
在写代码的过程中,常见的一种情况是需要某个整数类型变量增加 1 或减少 1,Java 提供了一种特殊的运算符,用于这种表达式,叫做自增运算符(++)和自减运算符(--)。
++和--运算符可以放在变量之前,也可以放在变量之后。
当运算符放在变量之前时(前缀),先自增/减,再赋值;当运算符放在变量之后时(后缀),先赋值,再自增/减。
例如,当 b = ++a
时,先自增(自己增加 1),再赋值(赋值给 b);当 b = a++
时,先赋值(赋值给 b),再自增(自己增加 1)。也就是,++a 输出的是 a+1 的值,a++输出的是 a 值。
用一句口诀就是:“符号在前就先加/减,符号在后就后加/减”。
看一下这段代码运行结果?
int i = 1;
i = i++;
System.out.println(i);
复制代码
答案是1。有点离谱对不对。
对于JVM而言,它对自增运算的处理,是会先定义一个临时变量来接收i的值,然后进行自增运算,最后又将临时变量赋给了值为2的i,所以最后的结果为1。
相当于这样的代码:
int i = 1;
int temp = i;
i++;
i = temp;
System.out.println(i);
复制代码
这段代码会输出什么?
int count = 0;
for(int i = 0;i < 100;i++)
{
count = count++;
}
System.out.println("count = "+count);
复制代码
答案是0。
和上面的题目一样的道理,同样是用了临时变量,count实际是等于临时变量的值。
int autoAdd(int count)
{
int temp = count;
count = coutn + 1;
return temp;
}
复制代码
PS:笔试面试可能会碰到的奇葩题,开发这么写,见一次吊一次。
面向对象
15.⾯向对象和⾯向过程的区别?
- ⾯向过程 :面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候再一个一个的一次调用就可以。
- ⾯向对象 :面向对象,把构成问题的事务分解成各个对象,而建立对象的目的也不是为了完成一个个步骤,而是为了描述某个事件在解决整个问题的过程所发生的行为。 目的是为了写出通用的代码,加强代码的重用,屏蔽差异性。
用一个比喻:面向过程是编年体;面向对象是纪传体。