北京理工大学计算机科学技术学院 2013-2014学年第一学期
Java语言程序设计考试试题(A)
说明:
(1)本次考试为开卷考试,允许学生携带笔记本电脑及其他资料,允许上网,但不允许以各种手段相互抄袭。
(2)考试时间为2小时。
(3)判断题答案直接写在试卷上。简答题和编程题写在试卷后所附的答题纸上,标明题号。
(4)要求代码书写规范,并添加相应的注释。
(5)部分题目没有标准答案,只要言之成理,均可给分,这类题目如发现有抄袭嫌疑的,该题判为0分。
试题设计:金旭亮
讨论:请在本文跟贴。
实时沟通:通过新浪微博 http://weibo.com/jinxuliang
*******************************************************************************
一、 判断题(正确的描述打勾,错误的打叉,每题1分,共10分)
1. Java的跨平台特性是指它的源代码可以在多个平台运行。(错)
2. Web客户端的编程语言JavaScript源自Java,其功能是Java SE的子集。(错)
3. 枚举(enum)属于原始数据类型(primitive type)。(错)
4. 在程序代码中写的注释太多,会使编译后的程序尺寸变大。 (错)
5. 在开发中使用泛型取代非泛型的数据类型(比如用ArrayList
6. Android应用中各Activity之间主要通过Intent相互传送信息。(对)
7. 我们在程序中经常使用“System.out.println()”来输出信息,语句中的System是包名,out是类名,println是方法名。(错)
8. JDK中提供的java、javac、jar等开发工具也是用Java编写的。(对)
9. 可以把任何一种数据类型的变量赋给Object类型的变量。 (对)
10. 高优先级的线程比低优先级的线程运行得更快。(错)
二、 简答题(请将答案写到答题纸上,注明题号。共20分)
11. (本题3分)我们都知道计算机只能在一定的精度范围内处理浮点数运算,然而,以下两句Java代码输出的结果大相径庭:
System.out.println(100.1*2);//输出:200.2
System.out.println(100.1*3);//输出:300.29999999999995
如此奇怪的现象是怎样产生的?请尝试解释之。
要点:乘以2的整数次幂时,计算机只需进行简单的移位操作即可
12. (本题3分)以下代码编译失败,为什么?
classMyGenericClass
T obj1=null;
V obj2=null;
void setValue(T obj){
}
void setValue(V obj){
}
}
要点: Java编译器的“擦除”原理
13. (本题3分)某同学开发一个Android应用,他想在界面上用一个TextView控件显示当前的时间(图1):
图1
以下是他所编写的代码:
public class MainActivity extendsActivity {
private TextViewtimerTextView=null;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
timerTextView = (TextView)findViewById(R.id.tvTimer);
Timer timer=new Timer();
timer.scheduleAtFixedRate(newTimerTask() {
publicvoid run() {
//在TextView控件上显示当前时间
DatenowDate = new Date();
timerTextView.setText(nowDate.toLocaleString());
}
},0, 1000);//每隔一秒种更新显示文本
}
}
可是程序运行时,Android报告以下错误(图2):
图 2
请解释原因,并修改代码消除此BUG。
要点:跨线程更新UI控件。有多种方法解决这一问题,以下仅列出一种。
参考代码:
public class MainActivity extends Activity {
private TextView timerTextView=null;
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
timerTextView=(TextView)findViewById(R.id.tvTimer);
final Runnable runnable=newRunnable() {
public void run() {
Date nowDate=new Date();
timerTextView.setText(nowDate.toLocaleString());
}
};
Timer timer=new Timer();
timer.scheduleAtFixedRate(newTimerTask() {
public void run() {
runOnUiThread(runnable);
}
}, 0, 1000);
}
}
14. (本题3分)下图是Android手机中的QQ界面载图(图3):
图 3
如何组合现有的Android控件设计出以上界面?简要叙述一下你的技术实现方案。
要点:
只需讲出你打算用哪个布局控件即可。
15. (本题4分)以下有两段功能相似的代码,一个使用int,另一个使用Integer:
代码段一 |
代码段二 |
public static int sumViaInteger( Integer from , Integer to) { Integer result=0; for(int i=from;i<=to;i++){ result+=i; } return result; } |
public static int sumViaInt(int from , int to) { int result=0; for(int i=from;i<=to;i++){ result+=i; } return result; } |
以下代码测试这两个方法的执行时间:
public static void main(String[]args) {
for(int i = 0; i < 3; i++) {
longstart = System.nanoTime();
sumViaInteger(1,100);
longend = System.nanoTime();
System.out.println(i+ " sumViaInteger(1,100)所花时间:"
+(end - start));
start= System.nanoTime();
sumViaInt(1,100);
end= System.nanoTime();
System.out.println(i+ " sumViaInt(1,100)所花时间:" + (end -start));
}
}
以下是程序某次运行的输出结果:
0 sumViaInteger(1,100)所花时间:457051
0 sumViaInt(1,100)所花时间:3499
-------------------
1 sumViaInteger(1,100)所花时间:19948
1 sumViaInt(1,100)所花时间:1400
-------------------
2 sumViaInteger(1,100)所花时间:19598
2 sumViaInt(1,100)所花时间:1400
-------------------
仔细观察以上输出结果,你发现了什么?得出了什么结论?请对出现此运行结果的可能原因进行分析。
要点:
(1)Integer比int慢得多,因为有许多装箱拆箱操作
(2)第二次运行比第一次快。原因:JVM缓存了上次编译的结果,无需再次编译
16. (本题4分)用户在使用软件系统时,可能会因为各种原因输入错误的数据。比如教师使用某教务管理系统在线录入学生考试成绩,由于疏忽,本应输入“90”,实际输入了“190”,很明显这是一个非法的分数,不应该被保存到数据库中;还有另外的可能,比如用户输入的是不能转换为int数值的字符串,比如“z90”,这将导致JVM在尝试转换“z90”字符串为int数值时抛出NumberFormatException异常。
如果由你来设计这个教务管理系统,你打算如何解决上面提出的这些与异常处理策略密切相关的实际问题?简述你的系统设计与技术实现思路。
要点:
关键看能否设计出合理的异常捕获方案,特别看看有没有学生谈到多层架构系统中的异常捕获策略。
三、 编程题(共30分)
17. (本题5分)设计一个方法,它接收一个整数数组,外界只需调用一次此方法,就能得到此数组中元素的最大值、最小值和平均值。
简单:有多种编程技巧,比如返回一个数组,返回一个对象,直接设置类中的字段等等
18. (本题5分)给定一个数组,将其转换为一个环型链表。比如某数组中包容[0,1,2,3,4],则转换为的环型链表如图 4所示:
图 4
19. (本题6分)现在需要计算1+2+3+....+30000的和。请采用多线程完成此计算工作,要求如下:
主线程启动三个线程,分别给它们分派以下任务:
线程1:计算1+2+3+...+10000
线程2:计算10001+10002+...+20000
线程3:计算20001+20002+...+30000
等三个线程都完成工作之后,主线程汇总三个工作线程的计算结果,得到最终答案:
1 + 2 + 3 + .... + 30000 = 450015000
要点:看看学生如何处理线程同步。
20. (本题14分)文件系统及对象集合编程题:
(1)编写一个方法找出指定文件夹(包括其子文件夹)中所有大于指定容量的文件(比如可以找出c:\windows下所有大于10M的文件):
public staticArrayList
(2)编写一个方法对上述方法找到的文件集合进行升序或降序排列:
public static void sortFile(List
升序还是降序由参数desc决定。
(3)编写一个方法(名字、参数、返回值类型自定),对前面getFiles()方法找到的文件集合按照文件扩展名进行分组,比如
txt文件组:
1.txt、readme.txt
exe文件组:
notepad.exe、calc.exe
无扩展名的文件组:
2、test
要点:
看看学生懂不懂是从JDK中选择合适的对象集合完成这一工作。
(4)在main()方法中启动一个工作线程执行getFiles()方法,等其工作结束得到文件集合后,如果集合不为空,则再启动两个线程完成后继处理工作,第一个线程执行sortFile()方法进行排序,第二个线程执行分组,这两个线程完成工作后,主线程汇总处理结果并输出在屏幕上。
要点:
这是一个比较复杂一些的线程同步,比较能区分出学生的多线程开发掌握程度。