java84道面试题

1.简单说一下java的跨平台原理(2018.11.12)
java通过不同的系统、不同版本、不同位数的java虚拟机(jvm),来屏蔽不同系统指令差异而对外统一的接口(java API,对于我们普通的java开发者而言,只需要按照接口开发即可,如果系统需要部署到不同的环境时,只需要在系统上面按照对应的版本中的虚拟机即可。

jdk,jre,jvm之间的关系
在这里插入图片描述
2.搭建一个Java开发环境的步骤(2018.11.13)
Java开发环境需要些生命?
1.适用于我们开发环境的jdk
2.对应开发环境eclipse/idea
3.需要web服务(tomcat)

3.Java中的基本数据类型?
8种
byte 8位,
short 16位,
int 32位,
long 64位,
float 32位,
double 64位,
char 16位,
boolean 1位
int 占4个字节,32位
boolean占1位,1字节,因为最小1位,也是占了一个字节。

4. 简单说一下基本数据类型的包装类型、还有装箱和拆箱的理解。
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean

总结:int 和 char有点特殊,就是单独记忆。
其他都是首字母大写。
装箱:把基本数据类型转换为对应的包装类型就是装箱。
拆箱:把包装类型转换为基本数据类型就是拆箱。
有了基本数据类型为什么还需要包装类型?
java是一门面向对象的语言,而基本的数据类型不具备面向对象的特征。
integer可以用null来表示,int只能用0来表示。

5. 面对对象的特性有哪些?(2018.11.14)
封装,继承,多态,抽象
抽象:把现实中的对象,抽象为类。

封装:

概念:将类的属性或者方法隐藏在类的内部,只能通过自己对外提供的访问方式,来实现访问。
优点:只能通过规定的方法来访问,隐藏类的实现的细节,避免代码的重复和冗余。
我们最常用的就是get&set方法,也是最标准的,例如实体类的注入和获得实体属性。还比如平常使用的工具类,都是用了java的封装的特性。
实现:get&set,使用访问修饰符4个中的private,创建get&set方法,然后在get&set方法中添加合法的控制语句。
继承(extends):

概念:继承是类与类之间的一种关系,父类是基类,子类是派生类。
优点:继承可以使子类拥有父类的属性和方法(除了私有的),实现代码的复用。
比如所有的类都继承自Object类,所以所有的类都有Object的equals()、toString()、getClass()等的方法。
实现:通过extends关键字。
注意:
在对象继承时有时需要使用子类的属性,有时需要使用父类的属性,所以在子类中可以通过super和this关键字来区分是父类还是子类。
父类提供的构造方法不能满足子类的需求,我们就可以在子类中重写父类的构造方法。
java中的继承时单继承。但支持多重继承。子类可以有父类,还可以有爷类。
多态:

概念:多态就是对象的多种形式。简单点说:“一个接口,多种实现”。
优点:屏蔽不同子类对象的差异,写出通用的代码,做出通用的编程,适应需求的不断变化。
比如Map map = new HashMap(); List list = new ArrayList();都是多态的一种体现。
实现:

  1. 父类引用指向子类
  2. 接口引用指向实现类

注意:

  1. 继承是多态的基础。
  2. 如果我们在子类中编写一个独有的方法(没有继承父类的方法),此时就不能通过父类的引用创建的子类对象来调用该方法

1遍是看不懂的,太长了也没有耐性,多看几遍。
详见(非常详细,非常重要!):https://www.cnblogs.com/hysum/p/7100874.html#_label0

6.谈谈你对final的理解
final可以修饰类、方法和变量。
被final修饰的类不能被继承,被final修饰的方法不能被重写,被final修饰的变量不能被改变,一旦赋予初始值就不能被改变。

7.一个.java源文件是否可以包括多个类?有什么限制?
可以由很多个类,但只能有一个public类,并且与public类的名称必须一致。
8.说说&和&& 的区别
相同点:都表示逻辑与,(and)
不同点:
&:不短路,可以进行位运算;
&& :可以短路,通常他用于逻辑运算;
9. java中如何跳出当前的多重循环
外层的循环条件表达式的结果可以收到里层循环体代码的控制。
在外层定义一个boolean类型的变量,再循环里面使用if判断句来控制boolean的值,在使用break;跳出多重循环。

int arr[][] = {{1,2,3},{4,5,6,7},{9}};
booolean found = false;
for (int i=0;i<arr.length && !found;i++){
		for(int j=0;j<arr[i].length;j++){
			System.out.println("i=" + i + ",j=" + j );
			if(arr[i][j] == 5) {
				found = true;
				break;
			}
		}
}

break 和 continue的区别:
break:通常使用在switch语句中,结束整个循环体。
continue:结束单次循环,程序继续走。可以是外层的循环,外层没有循环直接执行之后的代码。
10.switch语句的作用范围。
switch语句可以作用在 byte,short ,char,int上,包括他们的包装类型;
因为前三种他们都能隐式转换为int。
11.char类型变量可以存储一个汉字吗?
可以,char是用来存储Unicode编码的字符串,它中间包含汉字。
unicode编码占用两个字节,所以char占用两个字节。
12.使用final变量修饰一个变量时,是引用不能变,还是引用类型不能变?
引用变量不能变。引用可以改变。

final StringBuffer a = new StringBuffer("immutable");
a = new StringBuffer(" ");//编译报错
a.append("broken!");//通过编译。

13.==和equal的区别?
== 是用来比较基本数据类型的。
equal:比较的是对象。
这里最容易出错的是String,和自定义的类。
String人最容易把他当成基本数据类型。所以直接使用==,这种方法是不对的,即使字符串相等也会返回false。
自定义的类没有自己的equal方法,那么它继承的是Object的类的equal方法,那么比较的时候就需要重写equal,才可以比较,否则内容相等,也会返回false。
14.静态变量(类变量)和实例变量的区别?
在这里插入图片描述
类只要一加载,就会给静态变量分配空间,可以通过类名直接调用。
实例变量必须创建对象才能调用。
15.是否可以从一个静态方法内部调用非静态方法?
1.静态方法内部不能调用非静态的方法。
因为类加载的时候静态变量就会被分配空间,但是非静态的方法这时没有创建对象,就无法调用。
非静态的方法可以调用静态方法。
16.Integer与int的区别
java为每个原始类型提供了封装方法,int的默认值是0,integer的默认值为null,举例如果想表示成绩的字段,在web层就不适合用0来区分是否来参加考试,null是缺考,0是考试了但是没有成绩。所以integer更适合web的表单数据的展示。
另外Interger还有对字符串转换成整数的方法,Interger.valueOf(“12”);
还能表示最大的和最小的整数的常量,大概是21亿。
17.Math的方法(ceil,floor,round)
ceil是天花板函数:向上取整

Math.ceil(11.5);//12
Math.ceil(-11.5);//-11

floor是地板函数:向下取整

Math.floor(11.5);//11
Math.floor(-11.5);//-12

round是四舍五入

Math.round(11.5);//12=====》Math.floor(11.5+0.5);
	他的底层是floor方法,所以 Math.floor(11.5+0.5);=12
Math.round(-11.5);//-11====》Math.floor(-11.5+0.5);
	他的底层是floor方法,所以 Math.floor(-11.5+0.5);=-11

18.下面代码有什么不妥之处?

if(username.equals("zxxx"));//容易报空指针
纠正:if("zxxx".equals(username));
int x = 1;
	return x == 1?true:false;//x==1结果本身就是boolean型的
纠正:
int x = 1;
	return x == 1

19.public protected 默认 private
在这里插入图片描述
20.overload和override的区别?
overload(重载)
方法名相同,但是参数列表的数量、顺序、类型来区分方法。
不能通过访问权限,返回类型,抛出的异常来进行重载。
方法的异常类型和异常数目不能影响的重载。
如果存在继承关系,父类的权限修饰符是prvate,那么在子类对其进行重载。如果真要定义,那么只是重新定义了一个新的方法。而不会达到重载的效果。
override(重写):
重写一定牵扯继承或者是实现接口,最最常见的就是继承接口,接口中声明一个方法,但是不写其中的内容,实现接口的类来重写方法。
覆盖的前提是子类的方法名必须和父类相同。
返回值必须和父类的相同。
参数列表必须和父类的相同。
子类抛出的异常必须是父类的异常,或者是父类异常的子类。
如果父类的权限修饰符为private,子类就算上面的全部符合,也只能是从新定义了一个方法,并没有完成重写的功能。
21.构造器Constructor是否可以被Override?
不可以
构造器不能被继承获得,所以不能被重写,但是他可以重载。
22.接口是否可以继承接口?
可以,接口是可以多继承的,不仅可以继承接口,还能连续继承好几个。Java中的接口是支持多继承的。

23.抽象类是否可实现接口?(易错)
可以,抽象类也是类,可以实现接口,还能实现多个接口。一个类本来就可以实现很多个接口。

24. 抽象类是否可以继承具体类?(易错)
可以,抽象类可以继承实体类,因为抽象类中不仅可以有抽象方法,也可以有非抽象方法,抽象类继承了实体类则即包括自己的抽象方法也包括了继承来的非抽象方法

25.抽象类是否可以有静态的main方法?(易错)
可以,静态类中不能有非静态方法,但是非静态的类中可以调用静态方法。

26.抽象类和接口的区别是什么?(重点)
相同点:
抽象类主要用来抽象类别,接口主要用来抽象功能.
抽象类和接口都不能被实例化。除非多态。
抽象类和接口的方法必须被子类全部实现,如果子类不能全部实现父类的方法,那么该子类必须是抽象类。
不同点:
抽象类要被子类继承(extend),接口要被实现类实现(implement)。
抽象类可以写非抽象方法的方法体。抽象类中既可以包含抽象方法,也可以包含非抽象方法。但是接口不能写方法体。
抽象类定义的变量是正常的变量,但是接口定义的变量是公共的静态的常量(public static final)
抽象类中可以没有抽象方法,但是接口中的方法都是公共的静态的抽象的方法(public static abstract)
抽象方法要被实现,所以不能是静态的,也不能是private的。
27.java中多态的机制是什么?
父类变量指向子类变量
接口指向实现类
调用方法时都是调用子类的方法或实现类的方法。
28.被static修饰
static不能修饰局部变量,他是属于类的。
static修饰的方法和变量都可以通过类名直接访问。
静态代码块,是在类中独立于类成员的static语句块,可以有多个,位置可以随便放,它不在任何的方法体内,JVM加载类时会执行这些静态的代码块,如果static代码块有多个,JVM将按照它们在类中出现的先后顺序依次执行它们,每个代码块只会被执行一次。
普通类不能被static修饰,只能修饰内部类,内部静态类。
29.native
native 是用做java 和其他语言(如c++)进行协作时用的
也就是native 后的函数的实现不是用java写的
native的意思就是通知操作系统,
这个函数你必须给我实现,因为我要使用。
所以native关键字的函数都是操作系统实现的。
30. synchronized同步锁(未完成)
31. 是否可以继承String类?
不能,String类是被声明为final类型的。java.long.String包的。

32. String和StringBuffer的区别
String是不可变的字符串,StringBuffer是可变的字符串。
String重写了equals和hashCode方法,StringBuffer需要比较字符串内容时,需要重写这两个方法。
33.StringBuffer和StringBuilder的区别?
StringBuffer是线程安全的,StringBuilder是线程不安全的。
因此StringBuffer的效率低于StringBuilder。在单线程的环境下使用StingBuilder更好。
他们的append方法是向字符串最后添加字符串,insert方法可以在指定位置添加字符串。
34. 请说一下链表跟数组的区别?
数组静态分配内存,链表动态分配内存。
数组通过下标定位,查的速度快,插入和删除效率底。
链表必须从第一个开始遍历查找,查的效率低,插入和删除速度快。
原因和时间复杂度有关。
35.如何把一段逗号分割的字符转换成一个数组?
字符串的split方法。

package com.aaa.test;

import java.util.ArrayList;
import java.util.List;

public class Split {
	public static void main(String[] args) {
		String str = "";
		for (int i = 0; i < 6; i++) {
			if(i!=5){
				str += i+",";
			} else {
				str += i;
			}
		}
		System.out.println(str);
		
		List list = new ArrayList<String>();
		String[] split = str.split(",");
		for (int i = 0; i < split.length; i++) {
			list.add(i);
		}
		System.out.println(list);
	}
}

36. 数组有没有length方法?字符串有没有length方法?
数组有length属性,没有length方法。
字符串有length方法。
37.下面这条语句共创建了几个对象?

String s = "a"+"b"+"c"+"d";

一个对象。
相当于下面代码

static String s1 = "a";
String s2 = s1 + "b";
String s3 = "a" + "b";
System.out.println(s2 == "ab");//false
System.out.println(s3 == "ab");//true

javac编译可以对字符串常量直接相加进行优化。在编译的时候直接去掉其中的加号,直接将其编译成一个常量。
异常
38.try()里有一个return语句,那么紧跟在这个try后的finally{}里的code会不会被执行,在return前还是后?
会执行,在方法return动作之后,return语句执行之后,若finally中再有return语句,则此方法以finally的return作为最终返回,若finally中无return语句,则此方法以try的return作为最终返回。
39.final,finally,finalize的区别?
final使用来修饰属性、方法、和类的,被final修饰的属性不能被改变,修饰的方法不能被重写,修饰的类不能被继承。
finally是异常处理的一部分,它用于比如关闭io流,jdbc时关闭数据库连接,不管程序有没有异常都执行。
finalize时Object的一个方法,在垃圾回收器执行的时候会调用被回收对象的该方法,可以覆盖此方法来执行其他的资源回收,比如关闭文件,jvm不保证此方法总被调用。
40.运行时异常和一般异常有什么不同?
异常(Exception)和错误(Error)都是继承了Throwable接口。
错误一般不是代码逻辑的问题,比如jvm虚拟机的问题。
其中异常又分为编译时异常和运行时异常。
不同主要是编译时期的异常必须得要使用try…catch语句来捕获,或者通过throuws来抛出,但是运行时异常对这个不是必须的,但是如果可能会发生运行时异常的代码,我们可以通过捕获的方法,来进行处理。比如spring框架的异常集中处理机制。
41.java中的异常处理机制的简单原理和应用。
java是面向对象的一门语言,所以java将可能发生的异常通过封装类的方式来表示,这些封装类里面包含了异常的信息。
不同的异常对应不同的类,但是他们都继承自同一个接口,java.lang.Throwable,它底下有两个接口,Error和Exception。
Error代表了程序发生了严重问题,但是一般和程序代码无关,比如内存溢出、线程死锁。
Exception也有两种,一种是编译时异常,另一种是运行时异常,编译时异常必须要用try…catch语句处理或者thorws来抛出,而运行时异常可以处理也可以不处理。
另外普通异常时运行环境所导致的异常,这个需要用户来解决,比如网络断了,硬盘空间不足。
42.说出几种经常看到的异常?
NullPointException --空指针异常
程序试图访问一个空的数组中的元素或访问空的对象中的 方法或变量时产生异常
IndexOutOfException–数组下标越界异常
—由于数组下标越界或字符串访问越界引起异常;
ClassCastException–类转换异常
当把一个对象归为某个类,但实际上此对象并不是由这个类 创建的,也不是其子类创建的,则会引起异常
IOException --io异常
由于文件未找到、未打开或者I/O操作不能进行而引起异常;
NoSuchMethodException --方法未找到异常
由于文件未找到、未打开或者I/O操作不能进行而引起异常;
NumberFormatException --格式化异常
字符格式化的时候引起异常
FileNotFoundException – 文件未找到异常
43. java语言如何处理异常?throws、throw、try、catch、finally分别代表什么意义?在try块中可以抛出新的异常吗?
throws 是捕获异常,函数头部。
throw是抛出异常。
try是将会发生异常的语句包起来,也可以在try中抛出新的异常。
catch:如果有异常,就会执行catch里面的语句。
finally:不论是否有一场都会进行执行的语句。
线程
44.java中有几种方法来实现线程?用什么关键字修饰同步方法?stop()和suspend()方法为什么不推荐使用?
两种。继承Tread类,和实现Runnable接口。
第一种:声明一个类继承Tread类,重写run()方法,在主函数中创建这个线程对象,然后调用start()方法来启动线程。
第二种:声明一个类实现runnable接口,实现run()方法(Runnable接口中只有一个方法),在书函数中创建这个线程的目标对象(并不是线程对象),然后通过Tread tread = new Tread(目标对象)来获取线程对象,调用start方法来开启线程。
————————————————————————————
关键字 synchronized (同步锁)
————————————————————————————
45.sleep()和wait()有什么区别?
46.同步和异步有什么不同?在什么情况下使用?举例说明。
47.下面两个方法同步吗?

class Test{
	synchronized static void sayHello3(){
	}
	synchronized void getX(){}
}

48.多线程有几种实现方式?同步有几种实现方式?
49.启动一个线程使用run()还是start()?
50.当一个线程进入一个对象的一个synchronized方法后,其他线程是否可进入此对象的其他方法?
51.线程的基本概念,线程的基本状态一级状态之间的关系。
52.简述synchronized和java.util.concurrent.locks.Lock的异同。
53.设计4个线程,其中两个线程每次对 j 增加1,两外两个线程对 j 每次减少 1 .
54.线程和进程的区别?

  • 线程是进程的一个执行流,一个进程中可以包含很多线程。
  • 当程序运行时,系统就会给程序分配内存,这时就创建了进程。
  • 进程时程序运行的最小单元,线程是进程执行的最小单元。

猜你喜欢

转载自blog.csdn.net/weixin_44001965/article/details/86615264