答案--Java面试笔试题(3年以上)

这个是之前的题目链接 Java面试笔试题(3年以上)


答案如下:


一、不定项选择题(共36分,每题3分)
1.“hello” instanceof Object 的返回值是( B )。
A.“abcd” B.true C.false D.String
2.下面有关方法覆盖的描述中,不正确的是( AC )。
A.覆盖的方法一定不能是 private 的
B.要求覆盖和被覆盖的方法必须具有相同的访问权限
C.覆盖的方法不能比被覆盖的方法抛出更多的异常
D.要求覆盖和被覆盖的方法有相同的名字、参数列以及返回值
3.下面说法正确的是( A )。
A.如果源代码中有 package 语句,则该语句必须被放在代码的第一行(不考虑注释和空格)
B.如果源代码中有 main()方法,则该方法必须被放在代码的第一行
C.如果源代码中有 import 语句,则该语句必须被放在代码的第一行(不考虑注释和空格)
D.如果某文件的源代码中定义了一个 public 的接口,则接口名和文件名可以不同
4.下面关键字中,可以用来修饰接口中的变量的是( A )。
A.static B.private C.Synchronized D.protected
(抽象类中不能用private、static、synchronized、native访问修饰符修饰 接口中包括抽象类中的但是多了个protected不能用 因为接口可以让所有的类去实现(非继承),不只是其子类 )
5.有如下代码:
String s=“xbcde”;
System.out.println(s.charA.t(4));
以下针对上述代码段的描述中,正确的是( A)。
A.输出字符 e
B.什么都没有,抛出ArrayIndexOutOfBoundsException
C.输出字符 d
D.代码编译不成功,因为 charA.t()方法不属于String 类
6.下面创建Map 集合的方式中,正确的是( D )。
A.Map m=new Map(new Collection()) B.Map m=new Map(10, 2,40)
C.Map m=new Map() D.Map 是接口,所以不能实例化
7.为了区分类中重载的同名的不同方法,要求( A )。
A.采用不同的形式参数列表 B.采用不同的返回值类型
C.调用时用类名或者对象名作前缀 D.采用不同的参数名
8.下列对于构造方法的描述中,正确的是( B C)。
A.构造方法必须用 void 声明返回类型
B.构造方法名必须与类名相同
C.构造方法可以被程序调用
D.如果编程人员没在类中定义构造方法,程序将报错
9.下列有关继承的描述中,正确的是( A )。
A.子类能继承父类的非私有方法和属性 B.子类能继承父类的所有方法和属性
C.子类只能继承父类的公有方法和属性 D.子类能继承父类的方法,而不是属性
10.下面有关子类继承父类构造方法的描述中,正确的是( BC )。
A.创建子类的对象时,先调用子类自己的构造方法,然后调用父类的构造方法
B.子类会继承父类的构造方法
C.子类必须通过关键字 super 调用父类的构造方法
D.子类无法继承父类的构造方法
11.关于被私有保护访问控制符protected修饰的成员变量,以下说法正确的是? ( AB)
A.可以被三种类所引用:该类自身、与它在同一个包中的其他类、在其他包中的该类的子类
B. 可以被两种类访问和引用:该类本身、该类的所有子类
C. 只能被该类自身所访问和修改
D.只能被同一个包中的类访问
12.有如下代码:

public class Test{
	public static void main(String[] args){
		class A{
		public int i=3;
		}
	Object o = (Object)new A(); A a = (A)o;
	System.out.println("i = "+ a.i);
	}
}

上述程序运行后的结果是( A )。
A.i=3 B.编译失败
C.运行结果为ClassCastException D.i=0


二、填空题(共15分,每题3分)
1.用于声明一个类为抽象类的关键字是( abstract ),用于将一个类修饰为最终类的关键字是
final )。
2.构造方法、成员变量初始化以及静态成员变量初始化三者的先后顺序是(静态成员变量初始化,成员变量初始化,构造函数 )。
3.在Java 语言的基本数据类型中,字符型、整型分别占用字节数为( 2 )、(4 )
4.一般有两种用于创建线程对象的方法,分别是( 继承Thread类 )与( 实现Runnable接口 )。
5.Java 语言提供了两种用于多态的机制,分别是( 覆盖 )与( 重载 )。


三、问答题
1.接口能否继承接口?抽象类是否可实现(implements)接口?抽象类是否可继承实体类?(9分)
1.接口可以继承接口…但是要使用extends~而不是用implements如:interface a{}interface b extends a{}
2.抽象类可以实现接口…比如java.util中的AbstractCollection类就是实现的Collection接口
3.抽象类可以继承实体类。下面这段执行无误的代码说明的所有的问题:interface MyInterface {}interface AnotherInterface extends MyInterface {}class EntityClass {}abstract class AbstractClass extends EntityClass implements MyInterface {}

2.面向对象的特征有哪些方面?(10分)

  • 抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面。抽象只关注对象有哪些属性和行为,并不关注这些行为的细节是什么。
  • 继承:继承是从已有类得到继承信息创建新类的过程。提供继承信息的类被称为父类(超类、基类);得到继承信息的类被称为子类(派生类)。继承让变化中的软件系统有了一定的延续性,同时继承也是封装程序中可变因素的重要手段(如果不能理解请阅读阎宏博士的《Java与模式》或《设计模式精解》中关于桥梁模式的部分)。
  • 封装:通常认为封装是把数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的接口。面向对象的本质就是将现实世界描绘成一系列完全自治、封闭的对象。我们在类中编写的方法就是对实现细节的一种封装;我们编写一个类就是对数据和数据操作的封装。可以说,封装就是隐藏一切可隐藏的东西,只向外界提供最简单的编程接口(可以想想普通洗衣机和全自动洗衣机的差别,明显全自动洗衣机封装更好因此操作起来更简单;我们现在使用的智能手机也是封装得足够好的,因为几个按键就搞定了所有的事情)。
  • 多态性:多态性是指允许不同子类型的对象对同一消息作出不同的响应。简单的说就是用同样的对象引用调用同样的方法但是做了不同的事情。多态性分为编译时的多态性和运行时的多态性。如果将对象的方法视为对象向外界提供的服务,那么运行时的多态性可以解释为:当A系统访问B系统提供的服务时,B系统有多种提供服务的方式,但一切对A系统来说都是透明的(就像电动剃须刀是A系统,它的供电系统是B系统,B系统可以使用电池供电或者用交流电,甚至还有可能是太阳能,A系统只会通过B类对象调用供电的方法,但并不知道供电系统的底层实现是什么,究竟通过何种方式获得了动力)。方法重载(overload)实现的是编译时的多态性(也称为前绑定),而方法重写(override)实现的是运行时的多态性(也称为后绑定)。运行时的多态是面向对象最精髓的东西,要实现多态需要做两件事:1). 方法重写(子类继承父类并重写父类中已有的或抽象的方法);2). 对象造型(用父类型引用引用子类型对象,这样同样的引用调用同样的方法就会根据子类对象的不同而表现出不同的行为)。

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

4.final、finally 和 finalize 的区别是什么?(10分)

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

    5.ArrayList、Vector 和 LinkedList 有什么特点?HashMap 和 HashTable 有什么区别? (10分)
    都是List的直接子类或者间接子类,实现的是顺序集合,都提供了add,delete,index,遍历等操作
    区别是:
    Vector是线程安全的,性能略差,自动扩容按照1倍扩容,适合按照顺序检索的场景;
    ArrayLIst是非线程安全的,性能高,扩容基数0.5, 适合按照顺序检索的场景;
    LinkedList是双向链表,是非线程安全的,性能高,不存在扩容,适合增加,删除的场景
    ArrayList 和Vector是采用数组方式存储数据的,是根据索引来访问元素的,都可以根据需要自动扩展内部数据长度,以便增加和插入元素,都允许直接序号索引元素,但是插入数据要涉及到数组元素移动等内存操作,所以索引数据快插入数据慢,他们最大的区别就是synchronized同步的使用
    LinkedList使用双向链表实现存储,按序号索引数据需要进行向前或向后遍历,但是插入数据时只需要记录本项的前后项即可,所以插入数度较快!
    如果只是查找特定位置的元素或只在集合的末端增加、移除元素,那么使用Vector或ArrayList都可以。如果是对其它指定位置的插入、删除操作,最好选择LinkedList
    HashMap、HashTable的区别及其优缺点
    HashTable 中的方法是同步的 HashMap的方法在缺省情况下是非同步的 因此在多线程环境下需要做额外的同步机制
    HashTable不允许有null值 key和value都不允许,而HashMap允许有null值 key和value都允许 因此HashMap 使用containKey()来判断是否存在某个键
    HashTable 使用Enumeration ,而HashMap使用iterator
    Hashtable是Dictionary的子类,HashMap是Map接口的一个实现类

四、附加题
1.编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串。但是要保证汉字不被截半个,例如“人 ABC”,4 ,应该截为“人 AB”,输入“人 ABC 们DEF”,6 ,应该输出为“人ABC”而不是“人ABC+们的半个”。(汉字默认两个字节)(20分)
一、需要分析
1、输入为一个字符串和字节数,输出为按字节截取的字符串--------------》按照字节[byte]截取操作字符串,先将String转换成byte类型
2、汉字不可以截半汉字截半的话对应字节的ASC码为小于0的数值
二、技术难点
1、知道汉字截半的话对应字节的ASC码为小于0的数值
2、对字符串操作应该都要面对的一个问题,字符串是否有效null, 字符串的长度0,1这种边界处理

public class SplitStr{
  	public static void splitString(String src, int len) {
		int byteNum = 0;
 		if (null == src) {
			System.out.println("The source String is null!");
			return;
		}
 		byteNum = src.length();
		byte bt[] = src.getBytes(); // 将String转换成byte字节数组
 

		if (len > byteNum) {
			len = byteNum;
		}
 		// 判断是否出现了截半,截半的话字节对于的ASC码是小于0的值
		if (bt[len] < 0) {
			String subStrx = new String(bt, 0, --len);
			System.out.println("subStrx==" + subStrx);
		} else {
			String subStrx = new String(bt, 0, len);
			System.out.println("subStrx==" + subStrx);
		}
	}
public static void main(String[] args) {
	String srcStr1 = "我ABC";
	String srcStr2 = "我ABC汉DEF";
 
	splitString(srcStr1, 4);
	splitString(srcStr2, 6);
}

2.排序有哪几种方法?用Java 语言实现一个插入排序? (20分)
插入排序(直接插入排序、希尔排序),交换排序(冒泡排序、快速排序),选择排序(直接选择排序、堆排序),归并排序,分配排序(箱排序、基数排序)
整体流程是:先后移再比较

public void insertOrder(int a[], int len)  
    {  
        int i,j,temp;  
        for (i=1; i<len; i++)  
        {  
            temp = a[i];  
            for (j=i-1; j>=0; j--)  
            {  
                if (temp > a[j]) 
                break;        
                a[j+1] = a[j];                
            }  
            a[j+1] = temp;  
            for(int n:a){
                System.out.print("..."+n);
                }
            System.out.println("");
        }  
    } 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值