(助力校招)还在找工作的小伙伴看过来,2020年Java基础面试题

  • 时间:
  • 来源:互联网
  • 文章标签:

金九银十,马上2020年10月份就过去了,作为小白是不是还在为拿不到合适的offer烦恼,面试有技巧,知识要过关。操练题目,发挥更稳。一起来学学这些经典面试题和相关知识拓展吧!

一、数据类型

在java源代码中,每个变量都必须声明一种类型(type)。有两种类型:primitive type和reference type。引用类型引用对象(reference to object),而基本类型直接包含值(directly contain value)。因此,Java数据类型(type)可以分为两大类:基本类型(primitive types)和引用类型(reference types)。primitive types 包括boolean类型以及数值类型(numeric types)。numeric types又分为整型(integer types)和浮点型(floating-point type)。整型有5种:byte short int long char(char本质上是一种特殊的int)。浮点类型有float和double。关系整理一下如下图:
在这里插入图片描述
对象是动态创建的类实例或者动态创建的数组。The value of reference types are references to objects,而引用一般是指内存地址。所有的对象(包括数组)支持Object类中定义的方法。String literals are presented by String object.
java有两种类型(type),与之相对应的是两种数据的值(two kinds of data values that can be stored in variable, pass as arguments and returned by methods),这两只data values是:primitive values,reference values。也许这么理解起来更方便(虽然不严谨),Java变量有两种:primitive variable和reference variable,在变量中,它们分别存储primitive value和reference value。
null是一种特殊的type,但是你不能声明一个变量为null类型,null type的唯一取值就是null。null可以负值给任意的引用类型或者转化成任意的引用类型。在实践中,一般把null当做字面值(literal),这个字面值可是是任意的引用类型。

1.下面的哪些声明是合法的?(多选)( )

A.long 1 = 499
B.int i = 4L
C.float f =1.1
D.double d = 34.4

解答:AD
B.4L应该是long类型的写法,
C.1.1是double类型 ,float f=1.1f是正确写法

2.选择Java语言中的基本数据类型(多选)( )

A.byte
B.Integer
C.String
D.char
E.long

答案:ADE
基本数据类型总共有8个:byte,short,int,long,char,boolean,float,double

3.从下列选项中选择正确的Java表达式(多选)( )

A.int k=new String(“aa”)
B.String str=String(“bb”)
C.char c=74;
D.long j=8888;

解答:BCD

4.已知表达式 int m [ ] = {,1,2,3,4,5,6};下面哪个表达式的值与数组下标量总数相等?( )

A.m.length()
B.m.length
C.m.length()+1
D.m.length+1

解答:B
解答:数组下标是从零开始的,但是数据下标的总量和数据长度相同。length()表示字符串长度,length表示数组的长度。

5.给出如下声明:String s = “Example”;合法的代码由哪些?( )

A.s>>>=3
B.s[3]=”X”
C.int i = s.iength()
D.s = s +1

解答:D
A. 移位运算,要是整数类型。
B.s不是数组
C.String类取长度的方法为:length()
D. 字符串相加

6.char 型变量中能不能存贮一个中文汉字,为什么?

答:char类型可以存储一个中文汉字,因为Java中使用的编码是Unicode(不选择任何特定的编码,直接使用字符在字符集中的编号,这是统一的唯一方法),一个char类型占2个字节(16比特),所以放一个中文是没问题的。

7.int和Integer有什么区别?

答:Java是一个近乎纯洁的面向对象编程语言,但是为了编程的方便还是引入了基本数据类型,但是为了能够将这些基本数据类型当成对象操作,Java为每一个基本数据类型都引入了对应的包装类型(wrapper class),int的包装类就是Integer,从Java 5开始引入了自动装箱/拆箱机制,使得二者可以相互转换。
Java 为每个原始类型提供了包装类型:

  • 原始类型: boolean,char,byte,short,int,long,float,double
  • 包装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double

8.switch 是否能作用在byte 上,是否能作用在long 上,是否能作用在String上?

答:在Java 5以前,switch(expr)中,expr只能是byte、short、char、int。从Java 5开始,Java中引入了枚举类型,expr也可以是enum类型,从Java 7开始,expr还可以是字符串(String),但是长整型(long)在目前所有的版本中都是不可以的。

9.List、Map、Set三个接口存取元素时,各有什么特点?

答:List以特定的索引来存取元素,可以有重复元素。Set不能放重复元素(用对象的equals()方法来区分元素是否重复)。Map保存键值对(key-value pair)映射,映射关系可以说一对一或多对一。Set和Map容器都有基于哈希存储和排序树的两个版本,基于哈希存储的版本理论存取时间复杂度为O(1),而基于排序树版本的实现在插入或删除元素时会按照元素或元素的键(key)构成排序树从而达到排序和去重的效果。

10.List、Set、Map是否继承自Collection接口?

答:List、Set 是,Map 不是。Map是键值对映射容器,与List和Set有明显的区别,而Set存储的零散的元素且不允许有重复元素(数学中的集合也是如此),List是线性结构的容器,适用于按数值索引访问元素的情形。

11.String和StringBuilder、StringBuffer的区别?

答:Java平台提供了两种类型的字符串:String和StringBuffer/StringBuilder,它们可以储存和操作字符串。其中String是只读字符串,也就意味着String引用的字符串内容是不能被改变的。而StringBuffer/StringBuilder类表示的字符串对象可以直接进行修改。StringBuilder是Java 5中引入的,它和StringBuffer的方法完全相同,区别在于它是在单线程环境下使用的,因为它的所有方面都没有被synchronized修饰,因此它的效率也比StringBuffer要高。

12.怎样将GB2312编码的字符串转换为ISO-8859-1编码的字符串?

String s1 = “你好”;
String s2 = new String(s1.getBytes(“GB2312”), “ISO-8859-1”);

13.如何实现字符串的反转及替换?

答:方法很多,可以自己写实现也可以使用String或StringBuffer/StringBuilder中的方法。有一道很常见的面试题是用递归实现字符串反转,代码如下所示:

public static String reverse(String originStr) {  
   if(originStr == null || originStr.length() <= 1)   
       return originStr;  
   return reverse(originStr.substring(1)) + originStr.charAt(0);  
}

14.String s = new String(“csf”);创建了几个字符串对象?

答:两个对象,一个是静态区的"csf",一个是用new创建在堆上的对象。

二、运算符

在这里插入图片描述
在这里插入图片描述

15.关于运算符>>和>>>描述正确的是( )

A.>>执行移动
B.>>执行翻转
C.>>执行有符号左移,>>>执行无符号左移
D.>>执行无符号左移,>>>执行有符号左移

解答:C
在这里插入图片描述
<<表示左移运算符
例如8<<2,表示将8向左移2位,结果为32。低位补0。
二进制演算:
8的二进制:1 0 0 0
向左移动两位结果为1 0 0 0 0 0,换算成十进制即为32,也可以简单的理解为,左移就是将数变大,相当于8*2^2=32。
左移运算符的运算规律:将左边的数按照右边的数往左移动几位。
”>>”表示右移运算符
例如 8>>2,表示将8向右移动2位,结果为2。高位补0。
二进制演算:
8的二进制:1 0 0 0
向右移动两位:0 0 1 0即为2,也可以简单的理解为将数向右移位就是将数变小,相当于8除以2^2=2。
-1在32位二进制中表示为:11111111 11111111 11111111 11111111,-1>>1:按位右移,符号位不变,仍旧得到11111111 11111111 11111111 11111111,因此值仍为-1
右移运算符运算规律:将左边的数按照右边的数右移几位。
”>>>”表示无符号右移运算符。高位补0,忽略符号位
例如8>>>2表示将8向右移位2位,结果为2。
例如-8>>>2表示将8向右移位2位,结果为2。
|是按位或
x=5 (0101二进制)
y=11(1011二进制)
x|y = 1111 = 15
^是按位与或
x=5 (0101二进制)
y=11(1011二进制)
x^y = 1110 =14
&是按位与
x=5 (0101二进制)
y=11(1011二进制)
x&y = 0001 = 1
~是按位取反
x=5 (0101二进制)
~x = 1010 = 10

16.&和&&的区别?

答:&和&&都可以用作逻辑与的运算符,表示逻辑与(and),当运算符两边的表达式的结果都为true时,整个运算结果才为true,否则,只要有一方为false,则结果为false。&&还具有短路的功能,即如果第一个表达式为false,则不再计算第二个表达式,
例如,对于if(str != null && !str.equals(“”))表达式,
  当str为null时,后面的表达式不会执行,所以不会出现NullPointerException。
  如果将&&改为&,则会抛出NullPointerException异常。
If(x == 33 & ++y>0) y会增长,If(x==33 && ++y>0)不会增长
&还可以用作位运算符,当&操作符两边的表达式不是boolean类型时,&表示按位与操作,我们通常
使用0x0f来与一个整数进行&运算,来获取该整数的最低4个bit位,例如,0x31 & 0x0f的结果为0x01。

17.用最有效率的方法计算2乘以8?

答: 2 << 3(左移3位相当于乘以2的3次方,右移3位相当于除以2的3次方)。

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);其中有隐含的强制类型转换。

三、关键字

关键字:
abstract:表明类或者成员方法具有抽象属性
assert:断言,用来进行程序调试
boolean:基本数据类型之一,声明布尔类型的关键字
break:提前跳出一个块
byte:基本数据类型之一,字节类型
case:用在switch语句之中,表示其中的一个分支
catch:用在异常处理中,用来捕捉异常
char:基本数据类型之一,字符类型
class:声明一个类
const:保留关键字,没有具体含义
continue:回到一个块的开始处
default:默认,例如,用在switch语句中,表明一个默认的分支。Java8 中也作用于声明接口函数的默认实现
do:用在do-while循环结构中
double:基本数据类型之一,双精度浮点数类型
else:用在条件语句中,表明当条件不成立时的分支
enum:枚举
extends:表明一个类型是另一个类型的子类型。对于类,可以是另一个类或者抽象类;对于接口,可以是另一个接口
final:用来说明最终属性,表明一个类不能派生出子类,或者成员方法不能被覆盖,或者成员域的值不能被改变,用来定义常量
finally:用于处理异常情况,用来声明一个基本肯定会被执行到的语句块
float:基本数据类型之一,单精度浮点数类型
for:一种循环结构的引导词
goto:保留关键字,没有具体含义
if:条件语句的引导词
implements:表明一个类实现了给定的接口
import:表明要访问指定的类或包
instanceof:用来测试一个对象是否是指定类型的实例对象
int:基本数据类型之一,整数类型
interface:接口
long:基本数据类型之一,长整数类型
native:用来声明一个方法是由与计算机相关的语言(如C/C++/FORTRAN语言)实现的
new:用来创建新实例对象
package:包
private:一种访问控制方式:私用模式
protected:一种访问控制方式:保护模式
public:一种访问控制方式:共用模式
return:从成员方法中返回数据
short:基本数据类型之一,短整数类型
static:表明具有静态属性
strictfp:用来声明FP_strict(单精度或双精度浮点数)表达式遵循IEEE 754算术规范
super:表明当前对象的父类型的引用或者父类型的构造方法
switch:分支语句结构的引导词
synchronized:表明一段代码需要同步执行
this:指向当前实例对象的引用
throw:抛出一个异常
throws:声明在当前定义的成员方法中所有需要抛出的异常
transient:声明不用序列化的成员域
try:尝试一个可能抛出异常的程序块
void:声明当前成员方法没有返回值
volatile:表明两个或者多个变量必须同步地发生变化
while:用在循环结构中
还有些关键字,如cat、future、generic、innerr、operator、outer、rest、var等都是Java保留的没有意义的关键字。
保留字:true、false、null。

19.如下哪些不是java的关键字?(多选)( )

A.const
B.NULL
C.false
D.this
E.native

解答:BC
虽然null false 还有true不是java的关键字,但是都有特殊用途,不建议作为标识符。

四、应用小程序

Applet称为JAVA小应用程序。这种Applet程序的“.class”文件可以被嵌入到Web网页中,当支持JAVA的浏览器下载含有JAVA 小应用程序的网页时,就可以解析执行其中的Applet程序。
与一般的JAVA应用程序不同,Applet不是通过main()方法来运行的。在运行时Applet通常会与用户进行互动,显示动态的画面,并且还会遵循严格的安全检查,阻止潜在的不安全因素(例如根据安全策略,限制Applet对客户端文件系统的访问)。
Applet的生命周期的四个方法:init()、start()、stop()、destroy()
init( )方法,创建Applet时执行,只执行一次
当一个新的小程序被浏览器加载,第一个被执行的方法就是init()方法,目的就是对Applet实例对象进行初始化设置。初始化工作可能包含创建Applet所需要的对象、设置初始状态、加载图像或者文字、设置参数等等。
star( )方法多次执行,当浏览器打开该主页,或者是返回该主页时执行。
系统在调用完init()方法之后,将自动调用start()方法。如果前面停止了Applet,也可能会出现重新启动。比如页面被重新访问后,调用该方法再次启动对页面进行处理。
stop( )方法多次执行,在离开主页时执行,主要功能是停止一些耗用系统资源的工作。
停止和启动是成对出现的。浏览器从当前页面跳转到其他页面时,将会调用stop()方法。该方法通常用于停止当前页面的活动线程,以便节省系统资源。也可自己以通过调用该方法使Applet自己来停止。
destroy( )方法用来释放资源,在stop( )之后执行。
正常结束浏览器进程时调用destroy()方法,可以使得Applet从内存中释放。我们可以使用destroy()方法来终止任何正在运行的线程,或者释放任何其他正在运行的对象。一般情况下,很少使用destroy()方法,除非有特定的资源需要释放。

20.下面哪个是applet传递参数的正确方式?( )

A.
B.
C.
D. <applet Test 33>

解答:B

五、函数

  • 函数是定义在类中的一段独立的代码块,用来实现某个功能。Java中,函数又被称为方法。
  • 函数的主要作用是为了提高代码的复用性。
  • 函数都是在栈内存中运行;运行的函数处在栈顶。

21.下面那几个函数是public void method(){̷}的重载函数?( )

A.public void method( int m){̷}
B.public int method(){̷}
C.public void method2(){̷}
D.public int method(int m,float f ){̷}

解答:A
重载:方法名相同,参数列表不同

22.从下面四段(A,B,C,D)代码中选择出正确的代码段( )

A.

abstract class Name {  
  	private String name;  
  	public abstract boolean isStupidName(String name) {}  
}  

B.

public class Something {  
  void doSomething () {  
    private String s =  ̶";  
	    int l = s.length();  
	}  
}  

C.

public class Something {  
	public static void main(String[] args) {  
    	Other o = new Other();  
		new Something().addOne(o);  
	}  
  	public void addOne(final Other o) {  
    	o.i++;  
	}  
}  
class Other {
	public int i;  
}  

D.

public class Something {
	public int addOne(final int x) {
	    return ++x;  
	}
}

解答:C
A.抽象方法不能有方法体
B.方法中定义的是局部变量,不能用类成员变量修饰符private
D.final修饰为常量,常量的值不能被改变

23.给出如下代码:( )

class Test{
	private int m;
	public static void fun() {  
		//some code  
	}
}

如何使成员变量m被函数fun()直接访问?

A.将private int m改为 protected int m
B.将private int m改为 public int m
C.将private int m改为 static int m
D.将private int m改为int m

解答:C
静态的方法中可以直接调用静态数据成员

24.给出下面的代码段:( )

public class Base{
	int w, x, y, z;
	public Base(int a, int b){
		x=a; y=b;
	}
	public Base(int a, int b, int c, int d){
		//assignment x=a, y=b
		w=d;z=c;
	}
}

在代码说明//assignment x=a, y=b处写下如下哪几个代码是正确的?

A.Base(a, b);
B.x=a, y=b;
C.x=a; y=b;
D.this(a,b);

解答:CD
C是直接给x,y赋值
D是使用this调用本类中其它的构造方法

25.Math.round(11.5) 等于多少?Math.round(-11.5)等于多少?

答:Math.round(11.5)的返回值是12,Math.round(-11.5)的返回值是-11。四舍五入的原理是在参数上加0.5然后进行下取整。

26.构造器(constructor)是否可被重写(override)?

答:构造器不能被继承,因此不能被重写,但可以被重载。

27.数组有没有length()方法?String有没有length()方法?

答:数组没有length()方法,有length 的属性。String 有length()方法。JavaScript中,获得字符串的长度是通过length属性得到的,这一点容易和Java混淆。

28.是否可以从一个静态(static)方法内部发出对非静态(non-static)方法的调用?

答:不可以,静态方法只能访问静态成员,因为非静态方法的调用要先创建对象,在调用静态方法时可能对象并没有被初始化。

29.抽象的(abstract)方法是否可同时是静态的(static),是否可同时是本地方法(native),是否可同时被synchronized修饰?

答:都不能。抽象方法需要子类重写,而静态的方法是无法被重写的,因此二者是矛盾的。本地方法是由本地代码(如C代码)实现的方法,而抽象方法是没有实现的,也是矛盾的。synchronized和方法的实现细节有关,抽象方法不涉及实现细节,因此也是相互矛盾的。

六、Java基础

Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程 。
Java具有简单性、面向对象、分布式、健壮性、安全性、平台独立与可移植性、多线程、动态性等特点 。Java可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用程序等 。

30. 关于Java语言,下列描述正确的是( )

A. switch 不能够作用在String类型上
B. List, Set, Map都继承自Collection接口
C. Java语言支持goto语句
D. GC是垃圾收集器,程序员不用担心内存管理

解答:D
A. switch后跟String类型在jdk1.6之前是不可以的,但是jdk1.7中开始支持了
B. Map没有继承Collection接口
C.java不支持goto语句

31.下列描述中,哪些符合Java语言的特征(多选)( )

A. 支持跨平台(Windows,Linux,Unix等)
B. GC(自动垃圾回收),提高了代码安全性
C. 支持类C的指针运算操作
D. 不支持与其它语言书写的程序进行通讯

解答:AB
C可以自由通过指针指定内存空间使用,而Java在内存空间分配上,主要依赖自动分配,无法通过指针指定区域操作

32.MAX_LENGTH 是int 型public 成员变量,变量值保持为常量1,用简短语句定义这个变量( )

A .public int MAX_LENGTH=1;
B. final int MAX_LENGTH=1;
C. final public int MAX_LENGTH=1;
D. public final int MAX_LENGTH=1.

解答:D
通过题的描述就是定义常量,在java中常量命名规范是所有字母都大写用下划线分割每个单词

33.选择下面代码的运行结果:( )

public class Test{
	public void method(){
		for(int i = ; i < 3; i++){
			System.out.print(i);
		}
		System.out.print(i);
	}
}

A.122
B.123
C.编译错误
D.没有任何输出

解答:C
i变量的作用范围是整个for循环

34.已知如下代码:(多选)( )

public class Test{
	public static void main(String arg[] ){
		int i = 5;
		do{
			System.out.print(i);
		}while(–i>5)
		System.out.print("finished");
	}
}

执行后的输出是什么?

A 5
B 4
C 6
D finished

解答:AD
输出5finished,do{}.while()循环中循环体一定会执行一次

35.下述代码的执行结果是( )

class Super {
	public int getLength() {
		return 4;
	}
}
public class Sub extends Super {
	public long getLength() {
		return 5;
	}
	public static void main (String[]args) {
		Super sooper = new Super ();
		Super sub = new Sub();
		System.out.printIn(sooper.getLength()+ “,” + sub.getLength() };
	}  
}

A. 4, 4
B. 4, 5
C. 5, 4
D. 5, 5
E. 代码不能被编译

解答:E
方法重写返回值类型与父类的一致

七、类和对象

  • 类(class)和对象(object)是两种以计算机为载体的计算机语言的合称。对象是对客观事物的抽象,类是对对象的抽象。类是一种抽象的数据类型。
  • 它们的关系是,对象是类的实例,类是对象的模板。对象是通过new classname产生的,用来调用类的方法;类的构造方法 。

36.不能用来修饰interface的有(多选)( )

A.private
B.public
C.protected
D.static

解答:ACD
修饰接口可以是public和默认
1、public:public表明该数据成员、成员函数是对所有用户开放的,所有用户都可以直接进行调用。
2、private:daoprivate表示私有,私有的意思就是除了class自己之外,任何人都不可以直接使用。
3、protected:protected对于子女、朋友来说,就是public的,可以自由使用,没有任何限制,而对于其他的外部class,protected就变成private。
4、static分static方法、static变量、static代码块
1)static方法一般称作静态方法,由于静态方法不依赖于任何对象就可以进行访问,因此对于静态方法来说,是没有this的,因为它不依附于任何对象,既然都没有对象,就谈不上this了。并且由于这个特性,在静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。
但是要注意的是,虽然在静态方法中不能访问非静态成员方法和非静态成员变量,但是在非静态成员方法中是可以访问静态成员方法/变量的。
2)static变量也称作静态变量,静态变量和非静态变量的区别是:静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。
static成员变量的初始化顺序按照定义的顺序进行初始化。
3)static代码块:static关键字还有一个比较关键的作用就是 用来形成静态代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。

37.下列哪些表达式返回true(多选)( )

String s=new String(“hello”);
String t =new String(“hello”);
char c [ ] ={‘h’,’e’,’l’,’l’,’o’};

A.s.equals(t);
B.t.equals©;
C.s= =t ;
D.t.equals (new String(“hello”));
E.t= = c;

解答:AD
String类的equals方法已经覆盖了Object类的equals方法,比较的是两个字符串的内容是否相等,双等号比较的是两个对象的内存地址是否相等

38.最后一条语句的结果是( )

类 Teacher 和 Student 是类 Person 的子类;
Teacher t;
Student s;
// t and s are all non-null.
if (t instanceof Person ){ s=(Student)t; }

A.将构造一个Student 对象;
B.表达式是合法的;
C.表达式是错误的;
D.编译时正确, 但运行时错误。

解答:D
instanceof是Java的一个二元操作符,它的作用是测试它左边的对象是否是它右边的类的实例,返回boolean类型的数据。
Teahcer和Student之间没有继承关系不能做强制类型转换。

39.下列说法错误的有(多选)( )

A. 在类方法中可用this来调用本类的类方法
B. 在类方法中调用本类的类方法时可直接调用
C. 在类方法中只能调用本类中的类方法
D. 在类方法中绝对不能调用实例方法

解答:ACD
A. 在类方法中不能使用this关键字
C.在类方法中可以调用其它类中的类方法
D.在类方法中可以通过实例化对象调用实例方法

40.欲构造ArrayList类得一个实例,此类继承了List接口,下列哪个方法是正确的( )

A ArrayList myList = new Object();
B List myList = new ArrayList();
C ArraylList myList = new List();
D List myList = new List();

解答:B

41.重载(Overload)和重写(Override)的区别。重载的方法能否根据返回类型进行区分?

答:方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载;重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常(里氏代换原则)。重载对返回类型没有特殊的要求。

42.抽象类(abstract class)和接口(interface)有什么异同?

答:抽象类和接口都不能够实例化,但可以定义抽象类和接口类型的引用。一个类如果继承了某个抽象类或者实现了某个接口都需要对其中的抽象方法全部进行实现,否则该类仍然需要被声明为抽象类。接口比抽象类更加抽象,因为抽象类中可以定义构造器,可以有抽象方法和具体方法,而接口中不能定义构造器而且其中的方法全部都是抽象方法。抽象类中的成员可以是private、默认、protected、public的,而接口中的成员全都是public的。抽象类中可以定义成员变量,而接口中定义的成员变量实际上都是常量。有抽象方法的类必须被声明为抽象类,而抽象类未必要有抽象方法。

43.静态嵌套类(Static Nested Class)和内部类(Inner Class)的不同?

答:Static Nested Class是被声明为静态(static)的内部类,它可以不依赖于外部类实例被实例化。而通常的内部类需要在外部类实例化后才能实例化,其语法看起来挺诡异的,如下所示。

44.描述JVM加载class文件的原理机制?

答:JVM中类装载是由类加载器(ClassLoader)和它的子类来实现的,Java中类加载器是一个重要的Java运行时系统组件,它负责在运行时查找和装入类文件中的类。
由于Java的跨平台性,经过编译的Java源程序并不是一个可执行程序,而是一个或多个类文件。当Java程序需要使用某个类时,JVM会确保这个类已经被加载、连接(验证、准备和解析)和初始化。类的加载是指把类的.class文件中的数据读入到内存中,通常是创建一个字节数组读入.class文件,然后产生与所加载类的对应的Class对象。加载完成后,Class对象还不完整,所以此时的类还不可用。当类加载后进入连接阶段,这一阶段包括验证、准备(为静态变量分配内存并设置默认的初始值)和解析(将括号引用替换为直接引用)三个步骤。最后JVM对类进行初始化,包括:1.如果类存在直接的父类并且这个类还没有被初始化,那么就优先初始化父类;2.如果类中存在初始化语句,就依次执行这些初始化语句。
类的加载是由类加载器完成的,类加载器包括:根加载器(BootStrap)、扩展加载器(Extension)、系统加载器(System)和用户自定义类加载器(java.lang.ClassLoader的子类)。从Java 2(JDK 1.2)开始,类加载过程采取了父亲委托机制(PDM)。PDM更好的保证了Java平台的安全性,在该机制中,JVM自带的Bootstrap是根加载器,其他的加载器都有且仅有一个父类加载器。类的加载首先请求父类加载器加载,父类加载器无能为力时才由其子类加载器自行加载。JVM不会向Java程序提供对Bootstrap的引用。下面是关于几个类加载器的说明:

Bootstrap:一般用本地代码实现,负责加载JVM基础核心类库(rt.jar);

Extension:从java.ext.dirs系统属性所指定的目录中加载类库,它的父加载器是Bootstrap;

System:又叫应用类加载器,其父类是Extension。它是应用最广泛的类加载器。它从环境变量classpath或者系统属性java.class.path所指定的目录中记载类,是用户自定义加载器的默认父加载器。

45.一个".java"源文件中是否可以包含多个类(不是内部类)?有什么限制?

答:可以,但一个源文件中最多只能有一个公开类(public class)而且文件名必须和公开类的类名完全保持一致。

46.如何实现对象克隆?

答:有两种方式:
  1). 实现Cloneable接口并重写Object类中的clone()方法;
  2). 实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆。

47.Anonymous Inner Class(匿名内部类)是否可以继承其它类?是否可以实现接口?

答:可以继承其他类或实现其他接口,在Swing编程和Android开发中常用此方式来实现事件监听和回调。

48.内部类可以引用它的包含类(外部类)的成员吗?有没有什么限制?

答:一个内部类对象可以访问创建它的外部类对象的成员,包括私有成员。

49.Java 中的final关键字有哪些用法?

答:(1)修饰类:表示该类不能被继承;
(2)修饰方法:表示方法不能被重写;
(3)修饰变量:表示变量只能一次赋值以后值不能被修改(常量)。

50.指出下面程序的运行结果?

class A {
	static {  
	    System.out.print("1");  
	} 
    public A() {  
	    System.out.print("2");  
	 }  
}
class B extends A{  
	static { 
	    System.out.print("a");  
    }
    public B() {  
	    System.out.print("b");  
    }
}
public class Hello {  
	public static void main(String[] args) {  
	    A ab = new B();  
	    ab = new B();  
	}
} 

答:执行结果:1a2b2b。创建对象时构造器的调用顺序是:先初始化静态成员,然后调用父类构造器,再初始化非静态成员,最后调用自身构造器。

51.什么时候用断言(assert)?

答:断言在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。一般来说,断言用于保证程序最基本、关键的正确性。断言检查通常在开发和测试时开启。为了保证程序的执行效率,在软件发布后断言检查通常是关闭的。断言是一个包含布尔表达式的语句,在执行这个语句时假定该表达式为true;如果表达式的值为false,那么系统会报告一个AssertionError。断言的使用如下面的代码所示:

  1. assert(a > 0); // throws an AssertionError if a <= 0
    断言可以有两种形式:
    assert Expression1;
    assert Expression1 : Expression2 ;
    Expression1 应该总是产生一个布尔值。
    Expression2 可以是得出一个值的任意表达式;这个值用于生成显示更多调试信息的字符串消息。要在运行时启用断言,可以在启动JVM时使用-enableassertions或者-ea标记。要在运行时选择禁用断言,可以在启动JVM时使用-da或者-disableassertions标记。要在系统类中启用或禁用断言,可使用-esa或-dsa标记。还可以在包的基础上启用或者禁用断言。
    注意:断言不应该以任何方式改变程序的状态。简单的说,如果希望在不满足某些条件时阻止代码的执行,就可以考虑用断言来阻止它。

52.Collection和Collections的区别?

答:Collection是一个接口,它是Set、List等容器的父接口;Collections是个一个工具类,提供了一系列的静态方法来辅助容器操作,这些方法包括对容器的搜索、排序、线程安全化等等。

53.Java中如何实现序列化,有什么意义?

答:序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决对象流读写操作时可能引发的问题(如果不进行序列化可能会存在数据乱序的问题)。
要实现序列化,需要让一个类实现Serializable接口,该接口是一个标识性接口,标注该类对象是可被序列化的,然后使用一个输出流来构造一个对象输出流并通过writeObject(Object)方法就可以将实现对象写出(即保存其状态);如果需要反序列化则可以用一个输入流建立对象输入流,然后通过readObject方法从流中读取对象。序列化除了能够实现对象的持久化之外,还能够用于对象的深度克隆。

54.接口是否可继承(extends)接口?抽象类是否可实现(implements)接口?抽象类是否可继承具体类(concrete class)?

答:接口可以继承接口,而且支持多重继承。抽象类可以实现(implements)接口,抽象类可继承具体类也可以继承抽象类。

八、设计模式

设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。

  • 创建型模式:对象实例化的模式,创建型模式用于解耦对象的实例化过程。
  • 结构型模式:把类或对象结合在一起形成一个更大的结构。
  • 行为型模式:类和对象如何交互,及划分责任和算法。
    在这里插入图片描述

55.下面的代码实现了设计模式中的什么模式( )

public class A {
	private A instance;
	private A() { }
	public static A getInstance {
		if ( A == null ) instance = new A();
		return instance;
	}
}

A. Factory
B. Abstract Factory
C. Singleton
D. Builder

解答:C
Singleton单例模式:该设计模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例
Factory 工厂模式:Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
Abstract Factory 抽象工厂模式:围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。
Builder:建造者模式:使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

九、线程

在这里插入图片描述
Java中,线程创建有三种方法:

  1. 实现Runnable接口的run方法
  2. 继承Thread类并重写run方法
  3. 使用FutureTask方式

56.方法resume()负责恢复哪些线程的执行( )

A通过调用stop()方法而停止的线程。
B通过调用sleep()方法而停止的线程。
C通过调用wait()方法而停止的线程。
D通过调用suspend()方法而停止的线程。

解答:D
Suspend可以挂起一个线程,就是把这个线程暂停了,它占着资源,但不运行,用Resume是恢复挂起的线程,让这个线程继续执行下去。Stop是停止的,需要重新run。Sleep是休息一会,他会自己恢复运行。Wait则是使用notify方法唤醒。

57.有关线程的哪些叙述是对的(多选)( )

A一旦一个线程被创建,它就立即开始运行。
B使用start()方法可以使一个线程成为可运行的,但是它不一定立即开始运行。
C当一个线程因为抢先机制而停止运行,它被放在可运行队列的前面。
D一个线程可能因为不同的原因停止并进入就绪状态。

解答: BCD
在抢占式线程模型中,操作系统可以在任何时候打断线程。通常会在它运行了一段时间(就是所谓的一个时间片)后才打断它。这样的结果自然是没有线程能够不公平地长时间霸占处理器。

58.下面能让线程停止执行的有(多选)( )

A. sleep();
B. stop();
C. notify();
D. synchronized();
E. yield();
F. wait();
G. notifyAll();

解答:ABDEF
sleep:导致此线程暂停执行指定时间
stop: 这个方法将终止所有未结束的方法,包括run方法。
synchronized():对象锁
yield:当前正在被服务的线程可能觉得cpu的服务质量不够好,于是提前退出,这就是yield。
wait:当前正在被服务的线程需要睡一会,醒来后继续被服务
notify&notifyAll:叫醒睡着的wait

59.关于sleep()和wait(),以下描述错误的一项是( )

A. sleep是线程类(Thread)的方法,wait是Object类的方法;
B. sleep不释放对象锁,wait放弃对象锁;
C. sleep暂停线程、但监控状态仍然保持,结束后会自动恢复;
D. wait后进入等待锁定池,只有针对此对象发出notify方法后获得对象锁进入运行状态。

解答:D
sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时会自动恢复。调用sleep不会释放对象锁(同步资源锁)
wait()是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后,本线程才进入对象锁定池准备获得对象锁进入运行状态(注意:notify的作用相当于叫醒睡着的人,而并不会给他分配任务,就是说notify只是让之前调用wait的线程有权利重新参与线程的调度);
sleep()方法可以在任何地方使用;wait()方法则只能在同步方法或同步块中使用
sleep()与wait()方法都不占用cpu时间及利用率

60.以下哪个方法用于定义线程的执行体?( )

A.start()
B.init()
C.run()
D.main()
E.synchronized()

解答:C
run方法是线程的执行体。init方法是初始化方法,用于在启动Applet程序之前做一些必要的初始化工作! Synchronized修饰代码块,让线程排队,加锁。Main是一个类的主方法。
Start是静态方法块。

61.关于线程设计,下列描述正确的是( )

A. 线程对象必须实现Runnable接口
B. 启动一个线程直接调用线程对象的run()方法
C. Java提供对多线程同步提供语言级的支持
D. 一个线程可以包含多个进程

解答:C
Java实现多线程的两种方法
继承Thread: 线程代码存放Thread子类run方法中,且该run方法被调用。
实现Runnable:线程代码存在实现了Runnable类接口的对象的run方法中,且该run方法被调用。
启动一个线程是调用start()方法,使线程所代表的虚拟处理机处于可运行状态,这意味着它可以由JVM调度并执行,这并不意味着线程就会立即运行。run()方法是线程启动后要进行回调(callback)的方法。
进程包含线程

62.Thread类的sleep()方法和对象的wait()方法都可以让线程暂停执行,它们有什么区别?

答:sleep()方法(休眠)是线程类(Thread)的静态方法,调用此方法会让当前线程暂停执行指定的时间,将执行机会(CPU)让给其他线程,但是对象的锁依然保持,因此休眠时间结束后会自动恢复(线程回到就绪状态,请参考第66题中的线程状态转换图)。wait()是Object类的方法,调用对象的wait()方法导致当前线程放弃对象的锁(线程暂停执行),进入对象的等待池(wait pool),只有调用对象的notify()方法(或notifyAll()方法)时才能唤醒等待池中的线程进入等锁池(lock pool),如果线程重新获得对象的锁就可以进入就绪状态。
补充:可能不少人对什么是进程,什么是线程还比较模糊,对于为什么需要多线程编程也不是特别理解。简单的说:进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,是操作系统进行资源分配和调度的一个独立单位;线程是进程的一个实体,是CPU调度和分派的基本单位,是比进程更小的能独立运行的基本单位。线程的划分尺度小于进程,这使得多线程程序的并发性高;进程在执行时通常拥有独立的内存单元,而线程之间可以共享内存。使用多线程的编程通常能够带来更好的性能和用户体验,但是多线程的程序对于其他程序是不友好的,因为它可能占用了更多的CPU资源。当然,也不是线程越多,程序的性能就越好,因为线程之间的调度和切换也会浪费CPU时间。时下很时髦的Node.js就采用了单线程异步I/O的工作模式。

63.线程的sleep()方法和yield()方法有什么区别?

答:

  1. sleep()方法给其他线程运行机会时不考虑线程的优先级,因此会给低优先级的线程以运行的机会;yield()方法只会给相同优先级或更高优先级的线程以运行的机会;
  2. 线程执行sleep()方法后转入阻塞(blocked)状态,而执行yield()方法后转入就绪(ready)状态;
  3. sleep()方法声明抛出InterruptedException,而yield()方法没有声明任何异常;
  4. sleep()方法比yield()方法(跟操作系统CPU调度相关)具有更好的可移植性。

64.当一个线程进入一个对象的synchronized方法A之后,其它线程是否可进入此对象的synchronized方法B?

答:不能。其它线程只能访问该对象的非同步方法,同步方法则不能进入。因为非静态方法上的synchronized修饰符要求执行方法时要获得对象的锁,如果已经进入A方法说明对象锁已经被取走,那么试图进入B方法的线程就只能在等锁池(注意不是等待池哦)中等待对象的锁。

65.synchronized关键字的用法?

答:synchronized关键字可以将对象或者方法标记为同步,以实现对对象和方法的互斥访问,可以用synchronized(对象) { … }定义同步代码块,或者在声明方法时将synchronized作为方法的修饰符。

66.举例说明同步和异步。

答:如果系统中存在临界资源(资源数量少于竞争资源的线程数量的资源),例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就必须进行同步存取(数据库操作中的排他锁就是最好的例子)。当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。事实上,所谓的同步就是指阻塞式操作,而异步就是非阻塞式操作。

67.启动一个线程是调用run()还是start()方法?

答:启动一个线程是调用start()方法,使线程所代表的虚拟处理机处于可运行状态,这意味着它可以由JVM 调度并执行,这并不意味着线程就会立即运行。run()方法是线程启动后要进行回调(callback)的方法。

68.什么是线程池(thread pool)?

答:在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收。所以提高服务程序效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销毁,这就是”池化资源”技术产生的原因。线程池顾名思义就是事先创建若干个可执行的线程放入一个池(容器)中,需要的时候从池中获取线程不用自行创建,使用完毕不需要销毁线程而是放回池中,从而减少创建和销毁线程对象的开销。
Java 5+中的Executor接口定义一个执行线程的工具。它的子类型即线程池接口是ExecutorService。要配置一个线程池是比较复杂的,尤其是对于线程池的原理不是很清楚的情况下,因此在工具类Executors面提供了一些静态工厂方法,生成一些常用的线程池,如下所示:

  • newSingleThreadExecutor:创建一个单线程的线程池。这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。
  • newFixedThreadPool:创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。
  • newCachedThreadPool:创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程,那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。
  • newScheduledThreadPool:创建一个大小无限的线程池。此线程池支持定时以及周期性执行任务的需求。
  • newSingleThreadExecutor:创建一个单线程的线程池。此线程池支持定时以及周期性执行任务的需求。
    如果希望在服务器上使用线程池,强烈建议使用newFixedThreadPool方法来创建线程池,这样能获得更好的性能。

69.线程的基本状态以及状态之间的关系?

答:
在这里插入图片描述
其中Running表示运行状态,Runnable表示就绪状态(万事俱备,只欠CPU),Blocked表示阻塞状态,阻塞状态又有多种情况,可能是因为调用wait()方法进入等待池,也可能是执行同步方法或同步代码块进入等锁池,或者是调用了sleep()方法或join()方法等待休眠或其他线程结束,或是因为发生了I/O中断。

70.简述synchronized 和java.util.concurrent.locks.Lock的异同?

答:Lock是Java 5以后引入的新的API,和关键字synchronized相比主要相同点:Lock 能完成synchronized所实现的所有功能;主要不同点:Lock有比synchronized更精确的线程语义和更好的性能,而且不强制性的要求一定要获得锁。synchronized会自动释放锁,而Lock一定要求程序员手工释放,并且最好在finally 块中释放(这是释放外部资源的最好的地方)。

十、流

流是个抽象的概念,是对输入输出设备的抽象,Java程序中,对于数据的输入/输出操作都是以“流”的方式进行。设备可以是文件,网络,内存等。
在这里插入图片描述
流具有方向性,至于是输入流还是输出流则是一个相对的概念,一般以程序为参考,如果数据的流向是程序至设备,我们成为输出流,反之我们称为输入流。
可以将流想象成一个“水流管道”,水流就在这管道中形成了,自然就出现了方向的概念。
在这里插入图片描述
当程序需要从某个数据源读入数据的时候,就会开启一个输入流,数据源可以是文件、内存或网络等等。相反地,需要写出数据到某个数据源目的地的时候,也会开启一个输出流,这个数据源目的地也可以是文件、内存或网络等等。

71.Java I/O程序设计中,下列描述正确的是( )

A. OutputStream用于写操作
B. InputStream用于写操作
C. Reader用于写操作
D. I/O库不支持对文件可读可写API

解答:A
B.InputStream用于读操作
C.Reader用于读操作
D.I/O支持对文件的读写
IO流用来处理设备之间的数据传输,上传文件和下载文件,Java对数据的操作是通过流的方式,Java用于操作流的对象都在IO包中。按照数据流向可分为:输入流(读入数据)、输出流(写出数据),按照数据类型:字节流、字符流。字节流的抽象基类:InputStream ,OutputStream。字符流的抽象基类:Reader,Writer。
注:由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。
如:InputStream的子类FileInputStream。
如:Reader的子类FileReader。
在这里插入图片描述
在这里插入图片描述

72.Java中有几种类型的流?

答:字节流和字符流。字节流继承于InputStream、OutputStream,字符流继承于Reader、Writer。在java.io 包中还有许多其他的流,主要是为了提高性能和使用方便。关于Java的I/O需要注意的有两点:一是两种对称性(输入和输出的对称性,字节和字符的对称性);二是两种设计模式(适配器模式和装潢模式)。另外Java中的流不同于C#的是它只有一个维度一个方向。

73.编程实现文件拷贝?

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public final class MyUtil {

	private MyUtil() {
		throw new AssertionError();
	}

	public static void fileCopy(String source, String target) throws 			IOException {
		try (InputStream in = new FileInputStream(source)) {  
			try (OutputStream out = new FileOutputStream(target)) {  
				byte[] buffer = new byte[4096];  
				int bytesToRead;
				while((bytesToRead = in.read(buffer)) != -1) {
					out.write(buffer, 0, bytesToRead);
				}  
			}
		}
	}

	public static void fileCopyNIO(String source, String target) throws IOException {
		try (FileInputStream in = new FileInputStream(source)) {
			try (FileOutputStream out = new FileOutputStream(target)) {
				FileChannel inChannel = in.getChannel();
				FileChannel outChannel = out.getChannel();
				ByteBuffer buffer = ByteBuffer.allocate(4096);
				while(inChannel.read(buffer) != -1) {
					buffer.flip();
					outChannel.write(buffer);
					buffer.clear();
				}
			}
		}
	}
}

注意:上面用到Java 7的TWR,使用TWR后可以不用在finally中释放外部资源 ,从而让代码更加优雅。

74.写一个方法,输入一个文件名和一个字符串,统计这个字符串在这个文件中出现的次数。

import java.io.BufferedReader;  
import java.io.FileReader;

public final class MyUtil {  

	// 工具类中的方法都是静态方式访问的因此将构造器私有不允许创建对象(绝对好习惯)  
	private MyUtil() {  
		throw new AssertionError();  
	}  

	/** 
	* 统计给定文件中给定字符串的出现次数 
	*  
	* @param filename  文件名 
	* @param word 字符串 
	* @return 字符串在文件中出现的次数 
	*/  
	public static int countWordInFile(String filename, String word) {  
		int counter = 0;  
		try (FileReader fr = new FileReader(filename)) {  
			try (BufferedReader br = new BufferedReader(fr)) {
				String line = null;  
				while ((line = br.readLine()) != null) {  
					int index = -1;  
					while (line.length() >= word.length() && (index = line.indexOf(word)) >= 0) {  
						counter++;  
						line = line.substring(index + word.length());  
					}  
				}  
			}  
		} catch (Exception ex) {  
			ex.printStackTrace();  
		}  
		return counter;  
	}  
}

十一、布局管理器

各组件在容器中的大小以及摆放位置。实现跨平台特性并获得动态布局的效果;Java组件布局由布局管理器对象来管理;布局管理器会确定组件打大小和位置;在容器发生变化是做出动态调整。

  • FlowLayout:流式布局管理器
  • BorderLayout:边界布局管理器
  • GridLayout:网格布局管理器
  • GridBagLayout:网格组布局管理器
  • GardLayout:卡片布局管理器
  • BoxLayout:箱式布局管理器
  • SpringLayout:弹簧布局管理器

75.下面哪个可以改变容器的布局?( )

A. setLayout(aLayoutManager);
B. addLayout(aLayoutManager);
C. layout(aLayoutManager);
D. setLayoutManager(aLayoutManager);

解答:A
Java Swing布局管理器:FlowLayout(流式布局管理器)、BorderLayout(东、南、西、北、中)、CardLayout(层级)、BoxLayout(xy轴)、GirdBagLayout(复杂) 和 GirdLayout(网格)
Java设置布局管理器setLayout()

十二、数据库

Java.sql提供使用 JavaTM 编程语言访问并处理存储在数据源(通常是一个关系数据库)中的数据的 API。此 API 包括一个框架,凭借此框架可以动态地安装不同驱动程序来访问不同数据源。

76.提供Java存取数据库能力的包是( )

A.java.sql
B.java.awt
C.java.lang
D.java.swing

解答:A
java.sql是JDBC的编程接口
java.awt和java.swing是做图像界面的类库
java.lang: Java 编程语言进行程序设计的基础类

十三、框架

Java十大常用框架

  1. SpringMVC
  2. Spring
  3. Mybatis
  4. Dubbo
  5. Maven
  6. RabbitMQ
  7. Log4j
  8. Ehcache
  9. Redis
  10. Shiro

77.在Struts中实现页面跳转主要通过什么方法来实现?( )

A、server.transfer
B、response.redirect
C、mapping.findForward
D、response.sendRedirect

解答:C
Server.Transfer只能够转跳到本地虚拟目录指定的页面。
Response.Redirect("");页面跳转
mapping.findforward("");负责转发,request请求作用域
response.sendRedirect("");重定向网页

78.下列哪些是J2EE的体系(多选)()

A、JSP
B、JAVA
C、Servlet
D、WebService

解答:ACD
J2EE现在更多使用的名字是Java EE JSP是JavaEE设计模式MVC中的显示部分,Servlet是控制部分,WebService是JavaEE的服务器。

十四、异常

在Java中异常被当做对象来处理,根类是java.lang.Throwable类,在Java中定义了很多异常类(如OutOfMemoryError、NullPointerException、IndexOutOfBoundsException等),这些异常类分为两大类:Error和Exception。
Error是无法处理的异常,比如OutOfMemoryError,一般发生这种异常,JVM会选择终止程序。因此我们编写程序时不需要关心这类异常。
Exception,也就是我们经常见到的一些异常情况,比如NullPointerException、IndexOutOfBoundsException,这些异常是我们可以处理的异常。
Exception类的异常包括checked exception和unchecked exception(unchecked exception也称运行时异常RuntimeException,当然这里的运行时异常并不是前面我所说的运行期间的异常,只是Java中用运行时异常这个术语来表示,Exception类的异常都是在运行期间发生的)。
unchecked exception(非检查异常),也称运行时异常(RuntimeException),比如常见的NullPointerException、IndexOutOfBoundsException。对于运行时异常,java编译器不要求必须进行异常捕获处理或者抛出声明,由程序员自行决定。
checked exception(检查异常),也称非运行时异常(运行时异常以外的异常就是非运行时异常),java编译器强制程序员必须进行捕获处理,比如常见的IOExeption和SQLException。对于非运行时异常如果不进行捕获或者抛出声明处理,编译都不会通过。

79.关于异常(Exception),下列描述正确的是(多选)( )

A. 异常的基类为Exception,所有异常都必须直接或者间接继承它
B. 异常可以用try{}catch(Exception e){}来捕获并进行处理
C. 如果某异常继承RuntimeException,则该异常可以不被声明
D. 异常可以随便处理,而不是抛给外层的程序进行处理

解答:ABC
在这里插入图片描述

80.Error和Exception有什么区别?

答:Error表示系统级的错误和程序不必处理的异常,是恢复不是不可能但很困难的情况下的一种严重问题;比如内存溢出,不可能指望程序能处理这样的情况;Exception表示需要捕捉或者需要程序进行处理的异常,是一种设计或实现问题;也就是说,它表示如果程序运行正常,从不会发生的情况。

81.try{}里有一个return语句,那么紧跟在这个try后的finally{}里的代码会不会被执行,什么时候被执行,在return前还是后?

答:会执行,在方法返回调用者前执行。
注意:在finally中改变返回值的做法是不好的,因为如果存在finally代码块,try中的return语句不会立马返回调用者,而是记录下返回值待finally代码块执行完毕之后再向调用者返回其值,然后如果在finally中修改了返回值,就会返回修改后的值。显然,在finally中返回或者修改返回值会对程序造成很大的困扰,C#中直接用编译错误的方式来阻止程序员干这种龌龊的事情,Java中也可以通过提升编译器的语法检查级别来产生警告或错误,Eclipse中可以在如图所示的地方进行设置,强烈建议将此项设置为编译错误。

82.Java语言如何进行异常处理,关键字:throws、throw、try、catch、finally分别如何使用?

答:Java通过面向对象的方法进行异常处理,把各种不同的异常进行分类,并提供了良好的接口。在Java中,每个异常都是一个对象,它是Throwable类或其子类的实例。当一个方法出现异常后便抛出一个异常对象,该对象中包含有异常信息,调用这个对象的方法可以捕获到这个异常并可以对其进行处理。Java的异常处理是通过5个关键词来实现的:try、catch、throw、throws和finally。一般情况下是用try来执行一段程序,如果系统会抛出(throw)一个异常对象,可以通过它的类型来捕获(catch)它,或通过总是执行代码块(finally)来处理;try用来指定一块预防所有异常的程序;catch子句紧跟在try块后面,用来指定你想要捕获的异常的类型;throw语句用来明确地抛出一个异常;throws用来声明一个方法可能抛出的各种异常(当然声明异常时允许无病呻吟);finally为确保一段代码不管发生什么异常状况都要被执行;try语句可以嵌套,每当遇到一个try语句,异常的结构就会被放入异常栈中,直到所有的try语句都完成。如果下一级的try语句没有对某种异常进行处理,异常栈就会执行出栈操作,直到遇到有处理这种异常的try语句或者最终将异常抛给JVM。

83.列出一些你常见的运行时异常?

答:

  • ArithmeticException(算术异常)
  • ClassCastException (类转换异常)
  • IllegalArgumentException (非法参数异常)
  • IndexOutOfBoundsException (下标越界异常)
  • NullPointerException (空指针异常)
  • SecurityException (安全异常)

84.阐述final、finally、finalize的区别。

答:

  • final:修饰符(关键字)有三种用法:如果一个类被声明为final,意味着它不能再派生出新的子类,即不能被继承,因此它和abstract是反义词。将变量声明为final,可以保证它们在使用中不被改变,被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取不可修改。被声明为final的方法也同样只能使用,不能在子类中被重写。
  • finally:通常放在try…catch…的后面构造总是执行代码块,这就意味着程序无论正常执行还是发生异常,这里的代码只要JVM不关闭都能执行,可以将释放外部资源的代码写在finally块中。
  • finalize:Object类中定义的方法,Java中允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在销毁对象时调用的,通过重写finalize()方法可以整理系统资源或者执行其他清理工作。

十五、网络和通信

网络通信协议有很多种,目前应用最广泛的是TCP/IP协议(Transmission Control Protocal/Internet Protoal传输控制协议/英特网互联协议),它是一个包括TCP协议和IP协议,UDP(User Datagram Protocol)协议和其它一些协议的协议组,在学习具体协议之前首先了解一下TCP/IP协议组的层次结构。
在进行数据传输时,要求发送的数据与收到的数据完全一样,这时,就需要在原有的数据上添加很多信息 ,以保证数据在传输过程中数据格式完全一致。TCP/IP协议的层次结构比较简单,共分为四层,如图所示。
在这里插入图片描述

85.在使用匿名登录ftp时,用户名为( )

A、login users
B、anonymous
C、root
D、guest

解答:B
FTP(File Transfer Protocol,文件传输协议) 是 TCP/IP 协议组中的协议之一。FTP协议包括两个组成部分,其一为FTP服务器,其二为FTP客户端。

86.TCP通信建立在连接的基础上,TCP连接的建立要使用几次握手的过程( )

A.2
B.3
C.4
D.5

解答:B
每一次TCP连接都需要三个阶段:连接建立、数据传送和连接释放。“三次握手”就发生在连接建立阶段。“三次握手”的目的是“为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误”。

87.用于电子邮件的协议是( )

A.IP
B.TCP
C.SNMP
D.SMTP

解答:D

88.以下各DOS命令能够显示出本机DNS服务器地址的是 ()

A.ping -a
B.ipconfig -all
C.netstat
D.telnet

解答:C
ping命令:利用它可以检查网络是否能够连通,用好它可以很好地帮助我们分析判定网络故障
ifconfig all :显示或设置网络设备
netstat: 用于查看当前基于 NETBIOS 的 TCP/IP 连接状态,通过该工具你可以 获得远程或本地的组名和机器名。
telnet: 使用telnet命令访问远程计算机

89.下列IP地址中,属于C类IP地址的是()

A. 21.222.1.65
B. 1.2.1.1
C. 129.63.2.99
D. 255.255.255.255

解答:C
在这里插入图片描述
A类地址(1.0.0.0-126.255.255.255)用于最大型的网络,该网络的节点数可达16,777,216个。
B类地址(128.0.0.0-191.255.255.255)用于中型网络,节点数可达65,536个。
C类地址(192.0.0.0-223.255.255.255)用于256个节点以下的小型网络的单点网络通信。
D类地址为多播地址,不常用
E类地址为保留地址

90.路由器工作在ISO/OSI参考模型的( )

A. 数据链路层
B. 网络层
C. 传输层
D. 应用层

解答:B
在这里插入图片描述
在这里插入图片描述
网络层属于OSI中的较高层次了,从它的名字可以看出,它解决的是网络与网络之间,即网际的通信问题,而不是同一网段内部的事。网络层的主要功能即是提供路由,即选择到达目标主机的最佳路径,并沿该路径传送数据包。除此之外,网络层还要能够消除网络拥挤,具有流量控制和拥挤控制的能力。网络边界中的路由器就工作在这个层次上,现在较高档的交换机也可直接工作在这个层次上,因此它们也提供了路由功能,俗称“第三层交换机”。
数据链路层是OSI参考模型中的第二层,介乎于物理层和网络层之间。数据链路层在物理层提供的服务的基础上向网络层提供服务,其最基本的服务是将源自网络层来的数据可靠地传输到相邻节点的目标机网络层。

91.OSI体系结构定义了一个几层模型( )

A.6
B.7
C.8
D.9

解答:B
OSI-RM ISO/OSI Reference Model该模型是国际标准化组织(ISO)为网络通信制定的协议,根据网络通信的功能要求,它把通信过程分为七层,分别为物理层、数据链路层、网络层、传输层、会话层、表示层和应用层,每层都规定了完成的功能及相应的协议。

92.以下哪个命令用于测试网络连通( )

A.telnet
B. netstat
C. ping
D. ftp

解答:C
telnet: 使用telnet命令访问远程计算机
netstat: 用于查看当前基于 NETBIOS 的 TCP/IP 连接状态,通过该工具你可以 获得远程或本地的组名和机器名。
ping命令:利用它可以检查网络是否能够连通,用好它可以很好地帮助我们分析判定网络故障
ftp:文件传输协议,是 TCP/IP 协议组中的协议之一。

93.在一个办公室内,将6台计算机用交换机连接成网络,该网络的屋里拓扑结构为( )

A 星型
B 总线型
C 树型
D 环型

解答:A
选项A:星型拓扑结构 是一种以中央节点为中心,把若干外围节点连接起来的辐射式互联结构。这种结构适用于局域网,特别是近年来连接的局域网大都采用这种连接方式。这种连接方式以双绞线或同轴电缆作连接线路。
优点:结构简单、容易实现、便于管理,通常以集线器(Hub)作为中央节点,便于维护和管理。
缺点:中心结点是全网络的可靠瓶颈,中心结点出现故障会导致网络的瘫痪。
选项B:总线拓扑结构 是将网络中的所有设备通过相应的硬件接口直接连接到公共总线上,结点之间按广播方式通信,一个结点发出的信息,总线上的其它结点均可“收听”到。
优点:结构简单、布线容易、可靠性较高,易于扩充,节点的故障不会殃及系统,是局域网常采用的拓扑结构。
缺点:所有的数据都需经过总线传送,总线成为整个网络的瓶颈;出现故障诊断较为困难。另外,由于信道共享,连接的节点不宜过多,总线自身的故障可以导致系统的崩溃。最著名的总线拓扑结构是以太网(Ethernet)。
选项C :树型拓扑结构 是一种层次结构,结点按层次连结,信息交换主要在上下结点之间进行,相邻结点或同层结点之间一般不进行数据交换。
优点:连结简单,维护方便,适用于汇集信息的应用要求。
缺点:资源共享能力较低,可靠性不高,任何一个工作站或链路的故障都会影响整个网络的运行。
选项D: 环形拓扑结构 各结点通过通信线路组成闭合回路,环中数据只能单向传输,信息在每台设备上的延时时间是固定的。特别适合实时控制的局域网系统。
优点:结构简单,适合使用光纤,传输距离远,传输延迟确定。
缺点:环网中的每个结点均成为网络可靠性的瓶颈,任意结点出现故障都会造成网络瘫痪,另外故障诊断也较困难。最著名的环形拓扑结构网络是令牌环网(Token Ring)

94.Java网络程序设计中,下列正确的描述是(多选)()

A. Java网络编程API建立在Socket基础之上
B. Java网络接口只支持TCP以及其上层协议
C. Java网络接口只支持UDP以及其上层协议
D. Java网络接口支持IP以上的所有高层协议

解答:AD
在这里插入图片描述

95.管理计算机通信的规则称为( )

A.协议
B.介质
C.服务
D.网络操作系统

解答:A

96.中央处理单元(CPU)的两个主要组成部分是运算器和什么( )

A.寄存器
B.主存储器
C.控制器
D.辅助存储器

解答:C
控制器:由程序计数器、指令寄存器、指令译码器、时序产生器和操作控制器组成,它是发布命令的“决策机构”,即完成协调和指挥整个计算机系统的操作。
运算器:arithmetic unit,计算机中执行各种算术和逻辑运算操作的部件。运算器由:算术逻辑单元(ALU)、累加器、状态寄存器、通用寄存器组等组成。主要功能:执行所有的算术运算;执行所有的逻辑运算,并进行逻辑测试,如零值测试或两个值的比较。

十六、扩展标记语言

XML 指可扩展标记语言(eXtensible Markup Language)。XML是一种可扩展的标记语言,可扩展就是<>内的东西可以自己定义,可以随便写。标记语言就是加了<>符号的 。HTML是超文本标记语言,不可以拓展,因为你写个< p> 浏览器知道这个是段落,你写个 < shuyunquan>浏览器就不认识了,所以不可拓展。
因此XML 被设计用来传输和存储数据。HTML 被设计用来显示数据。

97.下列没有直接采用XML技术的是( )

A. UDDI
B. SOAP
C. AJAX
D. DCOM

解答:D
DCOM(分布式组件对象模型,分布式组件对象模式)是一系列微软的概念和程序接口,利用这个接口,客户端程序对象能够请求来自网络中另一台计算机上的服务器程序对象。DCOM基于组件对象模型(COM),COM提供了一套允许同一台计算机上的客户端和服务器之间进行通信的接口(运行在Windows95或者其后的版本上)。

98.下列可以用来解析XML的是( )

A.CSS
B.DTD
C.SAX
D.XSL

解答:C
java解析xml文件四种方式:SAX DOM JDOM DOM4J

十七、内存

在这里插入图片描述

99.Java 中会存在内存泄漏吗,请简单描述?

答:理论上Java因为有垃圾回收机制(GC)不会存在内存泄露问题(这也是Java被广泛使用于服务器端编程的一个重要原因);然而在实际开发中,可能会存在无用但可达的对象,这些对象不能被GC回收,因此也会导致内存泄露的发生。例如Hibernate的Session(一级缓存)中的对象属于持久态,垃圾回收器是不会回收这些对象的,然而这些对象中可能存在无用的垃圾对象,如果不及时关闭(close)或清空(flush)一级缓存就可能导致内存泄露。下面例子中的代码也会导致内存泄露。

import java.util.Arrays;  
import java.util.EmptyStackException;  
 
public class MyStack<T> {  
	private T[] elements;  
	private int size = 0;  

	private static final int INIT_CAPACITY = 16;  

	public MyStack() {  
		elements = (T[]) new Object[INIT_CAPACITY];  
	}  

	public void push(T elem) {  
		ensureCapacity();  
		elements[size++] = elem;  
	}  

	public T pop() {  
		if(size == 0)   
		throw new EmptyStackException();  
		return elements[--size];  
	}  

	private void ensureCapacity() {  
		if(elements.length == size) {  
			elements = Arrays.copyOf(elements, 2 * size + 1);  
		}  
	}  
}  

上面的代码实现了一个栈(先进后出(FILO))结构,乍看之下似乎没有什么明显的问题,它甚至可以通过你编写的各种单元测试。然而其中的pop方法却存在内存泄露的问题,当我们用pop方法弹出栈中的对象时,该对象不会被当作垃圾回收,即使使用栈的程序不再引用这些对象,因为栈内部维护着对这些对象的过期引用(obsolete reference)。在支持垃圾回收的语言中,内存泄露是很隐蔽的,这种内存泄露其实就是无意识的对象保持。如果一个对象引用被无意识的保留起来了,那么垃圾回收器不会处理这个对象,也不会处理该对象引用的其他对象,即使这样的对象只有少数几个,也可能会导致很多的对象被排除在垃圾回收之外,从而对性能造成重大影响,极端情况下会引发Disk Paging(物理内存与硬盘的虚拟内存交换数据),甚至造成OutOfMemoryError。

100.GC是什么,为什么要有GC?

答:GC是垃圾收集的意思,内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操作方法。Java程序员不用担心内存管理,因为垃圾收集器会自动进行管理。要请求垃圾收集,可以调用下面的方法之一:System.gc() 或Runtime.getRuntime().gc() ,但JVM可以屏蔽掉显示的垃圾回收调用。
垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低优先级的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清除和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。在Java诞生初期,垃圾回收是Java最大的亮点之一,因为服务器端的编程需要有效的防止内存泄露问题,然而时过境迁,如今Java的垃圾回收机制已经成为被诟病的东西。移动智能终端用户通常觉得iOS的系统比Android系统有更好的用户体验,其中一个深层次的原因就在于Android系统中垃圾回收的不可预知性。
补充:垃圾回收机制有很多种,包括:分代复制垃圾回收、标记垃圾回收、增量垃圾回收等方式。标准的Java进程既有栈又有堆。栈保存了原始型局部变量,堆保存了要创建的对象。Java平台对堆内存回收和再利用的基本算法被称为标记和清除,但是Java对其进行了改进,采用“分代式垃圾收集”。这种方法会跟Java对象的生命周期将堆内存划分为不同的区域,在垃圾收集过程中,可能会将对象移动到不同区域:

  • 伊甸园(Eden):这是对象最初诞生的区域,并且对大多数对象来说,这里是它们唯一存在过的区域。
  • 幸存者乐园(Survivor):从伊甸园幸存下来的对象会被挪到这里。
  • 终身颐养园(Tenured):这是足够老的幸存对象的归宿。年轻代收集(Minor-GC)过程是不会触及这个地方的。当年轻代收集不能把对象放进终身颐养园时,就会触发一次完全收集
    (Major-G),这里可能还会牵扯到压缩,以便为大对象腾出足够的空间。

与垃圾回收相关的JVM参数:
-Xms / -Xmx — 堆的初始大小 / 堆的最大大小
-Xmn — 堆中年轻代的大小
-XX:-DisableExplicitGC — 让System.gc()不产生任何作用
-XX:+PrintGCDetails — 打印GC的细节
-XX:+PrintGCDateStamps — 打印GC操作的时间戳
-XX:NewSize / XX:MaxNewSize — 设置新生代大小/新生代最大大小
-XX:NewRatio — 可以设置老生代和新生代的比例
-XX:PrintTenuringDistribution — 设置每次新生代GC后输出幸存者乐园中对象年龄的分布
-XX:InitialTenuringThreshold / -XX:MaxTenuringThreshold:设置老年代阀值的初始值和最大值
-XX:TargetSurvivorRatio:设置幸存区的目标使用率C),这里可能还会牵扯到压缩,以便为大对象腾出足够的空间。

声明:本文纯属知识技术类分享,由本人整理,部分图文来源网络,侵联删

本文链接http://www.taodudu.cc/news/show-1781990.html