本人从业Java十余年了,也经常面试应聘者,将所有常问的java面试题写出来,并分模块,方便大家看,不定期更新,如果看的人多,会加快更新的速度。
1.你认为Java与其它(你所了解的)语言相比,有什么优点和缺点?
参考答案:
首先,Java与C/C++相比。Java语言是一种完全的面向对象语言,虽然它的底层(运行时库)使用C语言开发的,可是并不依赖于C。因为Java的运行是在运行时库的支持下运行的,所以运行效率比起可以更接近底层的C/C++来说效率会有所影响,不过Java的类库采用很好的设计理念,非常好用,也非常使用,已经成为业界的一种标准开发语言。它的跨平台的特性受到开发者的青睐,只需要开发一次就能在所有安装了Java运行时库的环境上运行。
其次,Java与C#相比。C#是微软开发的一种编程语言,语法类似Java,几乎就是Java的翻版。运行原理和Java也类似,也是通过运行时库的支持运行。不过支持的平台还有很有限。Java几乎被所有平台支持,而C#目前只能被Windows和Linux支持,Windows下的支持当然是由微软自己开发的,而Linux下的支持则有mono支持。实际上,mono也是把C#应用转化为Java应用而已,所以本质上,C#仍然只是被微软自己的操作系统支持。应用平台受到限制,是它最大的缺点。
2.请回答以下几个名词的意思:JVM、JDK、JRE、JavaSE、JavaEE、JavaME、GC
参考答案:
JVM:Java虚拟机,Java Virtual Machine的缩写。是一个虚构出来的计算机,通过在实际的计算机上仿真模拟各种计算机功能来实现。Java虚拟机有自己完善的硬体架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。JVM屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。
JDK:Java开发工具包,Java Development Kit的缩写。JDK是整个Java的核心,包括了Java运行环境、Java工具和Java基础类库。
JRE:Java运行环境,Java Runtime Environment的缩写。运行Java程序所必须的环境的集合,包含JVM标准实现及Java核心类库。
JavaSE:Java Standard Edition,标准版,是我们常用的一个版本,从JDK5.0开始,改名为Java SE,主要用于桌面应用软件的编程。
JavaEE:Java Enterprise Edition,企业版。JavaSE是J2EE的一个新的名称,主要用于分布式的网络程序的开发。
JavaME:Java Micro Edition,是为机顶盒、移动电话和PDA之类嵌入式消费电子设备提供Java语言平台,包括虚拟机和一系列标准化的Java API。
GC:垃圾回收,Garbage Collection的缩写。当Java虚拟机发觉内存资源紧张时,则会自动地去清理无用对象(没有被引用到的对象)所占用的内存空间。
3.JVM能有几个实例?
参考答案:
每个Java程序对应于一个JVM实例,当一个Java程序运行时就创建一个JVM实例,因为JVM实例的个数取决于同时执行的程序个数。
4.Java跨平台是如何实现的?
参考答案:
Java是利用JVM(Java虚拟机)实现跨平台的。
Java源代码(*.java)经过Java编译器编译成Java字节码(*.class),执行Java字节码,Java字节码经过JVM解释为具体平台的具体指令,并执行。不同平台有不同的JVM,主流平台都提供了JVM,所以Java字节码可以在主流平台上能够解释执行。在这个意义上Java市跨平台的,也就是说:Java的字节码是跨平台的。
5.简述TCP/UDP协议的区别?
参考答案:
TCP/UPD协议的区别如下表所示。
比较项 | TCP | UDP |
是否可连接 | 面向连接 | 面向非连接 |
传输可靠性 | 可靠的 | 不可靠的 |
应用场合 | 传输大量的数据 | 少量数据 |
速度 | 慢 | 快 |
6.简述一下类的命名规则、方法的命名规则、变量的命名规则、包名的命名规则、常量的命名规范?
参考答案:
在Java中,类的命名、方法的命名、包名的命名以及常量的命名首先必须符合Java标识符的命名规则,规则如下:
1)可以以字母、数字、"_"和"$"符组成;
2)首字母不能以数字开头;
3)中文可以作为变量名,但不提倡使用;
4)Java大小写敏感,命名变量时需要注意;
5)不能使用Java保留字(一些Java语言规定好的,有特殊含义的字符),如:int、if、for、break等。
其次,类的命名、方法的命名、变量的命名、包名的命名以及常量的命名要符合如下规范:
1)类命名规范:首字母大写,如果由多个单词合成一个类名,要求每个单词的首字母也要大写,如:HelloWorld。
2)方法命名规范:首字母小写,中间的每个单词的首字母都要大写,如:getName。
3)变量的命名规范:变量的命名规范和方法一样,首字母小写,中间的每个单词的首字母都要大写,如:name。
4)包的命名规范:Java包的名字都是由小写单词组成。但是由于Java面向对象编程的特性,每一名Java程序员都可以编写属于自己的Java包,为了保障每个Java包命名的唯一性,在最新的Java编程规范中,要求程序员在自己定义的包的名称之前加上唯一的前缀。由于互联网上的域名名称是不会重复的,所以程序员一般采用自己在互联网上的域名称作为自己程序包的唯一前缀。例如:"com.sun.swt"一般公司会以"com.公司名.项目名.模块名"开头,所以会长一点,如com.land.oa.emp.struts.action。
5)常量的命名规范:基本数据类型的常量名为全大写,如果是由多个单词构成,可以用下划线隔开,如:WEEK_OF_MONTH。
7.阐述一下Java共有几种注释?
参考答案:
在Java中有三种注释类型:
1)单行注释符号是"//",只能注释一行。
2)块注释符合是"/* */",可以跨多行。
3)javadoc注释符号是"** */",可以跨多行,而且生成javadoc时,这样的注释会被生成标准的Java API注释。
8.如何增加代码的清晰度和可观性?
参考答案:
增加代码的清晰度和可观性常用的方式如下:
1)给代码添加注释。
2)类名包名等命名规范化。
3)缩进排版规范。
4)添加异常的处理。
5)使用测试类和测试方法。
9.Java中有两个关键字:void和null,它们有什么区别?
参考答案:
在Java中,void仅用于无返回值的方法上,例如:
public void a(){}
该方法不需要返回数据,故返回值类型设置为void。
null则代表对象/变量的值,例如:
表示变量a没有被实例化,没有指向具体的内存地址。
10.Java中结构化程序设计有哪三种基本流程,分别对应哪些语句?
参考答案:
Java中结构化程序设计有三种基本流程,分别是顺序、选择、循环。其中,顺序表示程序中的各种操作是按照它们出现的先后顺序执行的;选择对应Java语言中的if语句和switch语句;循环对应Java语言中的for语句、do-while语句以及while语句。
11.&和&&的区别?
参考答案:
&和&&都可以执行关系判断。二者的区别是:&运算是把逻辑表达式全部计算完,而&&运算具有短路计算功能。所谓短路计算,是指系统从左至右进行逻辑表达式的计算,一旦出现计算结果已经确定的情况,则计算过程即被终止。
12.写出Java中8种原始类型及字节长度?
参考答案:
Java中8种原始类型及其长度如下表所示:
类型名称 | 字节空间 | 说明 |
byte | 1字节(8位) | 存储1个字节数据 |
short | 2字节(16位) | 兼容性考虑,一般不用 |
int | 4字节(32位) | 存储整数(常用) |
long | 8字节(64位) | 存储长整数(常用) |
float | 4字节(32位) | 存储浮点数 |
double | 8字节(64位) | 存储双精度浮点数(常用) |
char | 2字节(16位) | 存储一个字符 |
boolean | 1字节(8位) | 存储逻辑变量(true、false) |
13.请描述一下JVM加载class文件的原理机制?
参考答案:
JVM中类的装载是由ClassLoader和它的子类来实现的,Java ClassLoader是一个重要的Java运行时系统组件,它负责在运行时查找和装入类文件中的类。
14.你对软件开发中迭代的含义的理解?
参考答案:
软件开发中,各个开发阶段不是顺序执行的,而各个阶段都进行迭代,然后在进入下一阶段的开发。这样对于开发中的需求变化,及人员变动都能得到更好的适应。
软件开发过程中迭代模型如下图所示。
15.什么是进程?
参考答案:
进程是操作系统结构的基础,是一个计算机中正在运行的程序实例。可以分配给处理器并由处理器执行的一个实体,由单一顺序的执行显示,一个当前状态和一组相关的系统资源所描述的活动单元。
16.什么是垃圾回收?什么时候触发垃圾回收?如何降低垃圾回收的触发频率?它能保证程序有足够的可用内存吗?
参考答案:
各问题的参考答案如下:
第一问:垃圾回收(GC)是Java语言的一个重要特性,作用是释放不再被使用的内存。
第二问:垃圾回收由系统进行管理。在系统认为需要的时候自动启动一个线程进行处理。
第三问:尽量减少垃圾内存,也就是新建对象的数量,可以降低垃圾回收的频率。
第四问:垃圾回收机制无法保证有足够的内存。
17.Java中会存在内存泄漏吗,请简单描述?
参考答案:
会出现内存泄漏。
一般来说内存泄漏有两种情况。一是在堆中分配的内存,在没有将其释放掉的时候,就将其所有能访问这块内存的方法都删掉;另一种情况则是在内存对象已经不需要的时候,还仍然保留着这块内存和它的访问方式(引用)。第一种情况,在Java中已经由于垃圾回收机制的引入,得到了很好的解决。所以,Java中的内存泄漏,主要指的是第二种情况。
下面给出了一个简单的内存泄漏的例子。在这个例子中,我们遵循申请Object对象,并将所申请的对象放入一个List中,如果我们仅仅释放引用本身,那么List仍然引用该对象,所以这个对象对GC来说是不可回收的。代码如下所示:
List list=new ArrayList(10);
for(int i=1;i<100;i++){
Object o=new Object();
list.add(o);
o=null;
}
此时,所有的Object对象都没有被释放,因为变量list引用这些对象。
18.Java源文件中是否可以包括多个类,有什么限制?
参考答案:
一个Java源文件中可以包含多个类,每个源文件中至多有一个public类,如果有的话,那么源文件的名字必须与之相同。如果源文件中没有public类,则源文件用什么名字都可以,但最后还是具有特定的意义,免得自己都不记得里面写的是什么了。一般建议一个源文件中只写一个Java类。
19.列出自己常用的jdk包?
参考答案:
常用的JDK包如下:
1.java.lang包:这个包中包含了JDK提供的基础类,比如String等都是这里面的,这个包是唯一 一个可以不用导入就可以使用的包;
2.java.io包:这个包中包含了 与输入输出相关的类,比如文件操作等;
3.java.net包:这个包中包含了与网络有关的类,比如URL,URLConnection等;
4.java.util包:这个是系统辅助类,特别是集合类Collection,List,Map等;
5.java.sql包:这个是数据库操作的类,Connection,Statement,ResultSet等。
20.简单说明什么是递归?什么情况会使用?并使用Java实现一个简单的递归程序?
参考答案:
1.递归做为一种算法在程序设计语言中广泛应用,是指函数/过程/子程序在运行过程中直接或间接调用自身而产生的重入现象。
2.递归算法一般用于解决三类问题:
1)数据的定义是按递归定义的。(Fibonacci(斐波那契)函数)
2)问题解法按递归算法实现。(回溯)
3)数据的结构形式是按递归定义的。(树的遍历,图的搜索)
3.下面是使用递归算法实现计算某个整数在二进制中的个数,代码如下所示:
/*
*计算二进制中1的个数,
*N为奇数,二进制中1的个数等于N/2的个数
*例子:
*num=13
*1.getBinary(13/2=6)+1;
*2.getBinary(6/2=3)+1
*3.getBinary(3/2=1)+1+1
*4.getBinary(1)+1+1; getBinary(1)返回1,与后边两个1相加得结果3
*/
public static int getBinary(int num){
if(num==1){
return 1;
}
if(0==num%2){//是否为偶数
return getBinary(num/2);
}else{
return getBinary(num/2)+1;
}
}
21.请写出求n!的算法?
参考答案:
public class Factorial{
public static void main(String[] args){
long n=5;
System.out.println(doFactorial(n));
}
public static long doFactorial(long n){
if(n<1){
System.out.println("ERROR");
return 0;
}else if(n==1||n==2){
return n;
}else{
return n*doFactorial(n-1);
}
}
}
22.排序都有哪几种方法?
参考答案:
排序的方法有:插入排序(直接插入排序、希尔排序)、交换排序(冒泡排序、快速排序)、选择排序(直接选择排序、堆排序)、归并排序、分配排序(箱排序、基数排序)。
23.写一个排序算法,将10个1-100随机数字进行排序?
参考答案:
选择排序算法实现10个1-100随机数字的排序,代码如下所示:
public class SelectSort{
for(int i=0;i<number.length-1;i++){
int m=i;
for(int j=i+1;j<number.length;j++){
if(number[j]<number[m])
m=j;
}
if(i!=m){
swap(number,i,m);
}
}
//用于交换数组中的索引为i、j的元素
private static void swap(int[] number,int i,int j){
int t;
t=number[i];
number[i]=number[j];
number[j]=t;
}
public static void main(String[] args){
//定义一个数组
int[] num=new int[10];
for(int i=0;i<num.length;i++){
num[i]=(int)(Math.random()*100)+1;
}
//排序
selectionSort(num);
for(int i=0;i<num.length;i++){
System.out.println(num[i]);
}
}
}
24.请用Java语言编写一个完成冒泡排序算法的程序?
参考答案:
使用Java语言实现的冒泡排序算法代码如下所示:
import java.util.Random;
import java.util.Arrays;
public class BubbleSort{
public static void main(String[] args){
int[] arr=new int[10];
for(int i=0;i<arr.length;i++){
Random ran=new Random();
arr[i]=ran.nextInt(100);
}
System.out.println(Arrays.toString(arr));
}
System.out.println("------冒泡排序 结束------");
System.out.println(Arrays.toString(arr));
}
25.有一数组a[1000]存放了1000个数,这1000个数取自1-999,且只有两个相同的数,剩下的998个数不同,写一个搜索算法找出相同的那个数的值?
参考答案:
下面代码中使用二分搜索算法实现了从数组a[1000]中,查找两个相同的数,代码如下所示:
import java.util.Arrays;
public class SearchDemo{
/**被搜索数据的大小*/
private static final int size=1000;
public static void main(String[] args){
int[] data=new int[size];
//添加测试数据
for(int k=0;k<data.length;k++){
data[k]=k+1;
}
data[999]=567;
result(data);
}
/**
*调用二分搜索算法的方法实现查找相同元素
@param data
*/
public static void result(int data[]){
Arrays.sort(data);
for(int i=0;i<data.length;i++){
int target=data[i];
data[i]=0;
int result=binaryFind(data,target);
if(result=-1){
System.out.println("相同元素为:"+data[result]);
break;
}
}
}
/**
*二分搜索算法实现
*
* @param data
* 数据集合
*
* @param target
* 搜索的数据
* @return 返回找到的数据的位置,返回-1表示没有找到。
*/
public static int binaryFind(int[] data,int target){
int start=0;
int end=data.length-1;
while(start<=end){
int middleIndex=(start+end)/2;
if(target==data[middleIndex]){
return middleIndex;
}
if(target>=data[middleIndex]){
start=middleIndex+1;
}else{
end=middleIndex-1;
}
}
return -1;
}
}
java交流群:532436438