1.运行下面代码输出结果是
public class Test {
public static void main(String[] args){
int a=12,b=20;
if(a++==13 && ++b==21){
System.out.println("ok");
}
System.out.println("a="+a);
System.out.println("b="+b);
}
}
- 答案: a=13 ,b=20
2.有以下代码
int a=15;
int b=3;
把变量a和变量b的值进行交换,并且要求不能使用第三个变量
- 答案
1) 算术运算
a=a-b; //a=12,b=3
b=a+b; //a=12,b=15
a=b-a; //a=3,b=15
2) 位运算(异或运算符,相同为0,不同为1)
int a=15,b=3; //a=1101 b=0011;
a=a^b; //a=1101^0011 ->a=1110 b=0011;
b=a^b; //b=1110^0011 ->a=1110 b=1101;
a=a^b; //a=1110^1101 ->a=0011 b=1101;
3.以下代码运行结果是
public class Test{
public double div(double a,double b){
try{
return a/b;
}catch(Exception e){
System.out.println("exception");
}finally{
System.out.println("finally");
}
//return (Double) null; //应该加这句才可以编译成功,输出finally
}
public static void main(String[] args){
Test t=new Test();
t.div(1,0);
}
}
- 答案:编译不成功
4.在java.io包中有4个基本抽象基类,分别是哪四个?
//字符流
Reader //继承类:FileReader、BufferedReader
Writer //继承类:FileWriter、BufferedWriter
//字节流
InputStream //继承类:FileInputStream、BufferedInputStream
OutpuStream //继承类:FileOutputStream、BufferdOutputStream
5.说出ArrayList,Vector,LinkedList的储存性能和特性
1.ArrayList 采用的是数组形式来保存对象的,这种方式将对象放在连续的位置中,所以最大的缺点就是插入删除时非常麻烦
2.LinkedList 采用的将对象存放在独立的空间中,而且在每个空间中还保存下一个链接的索引 但是缺点就是查找非常麻烦 要丛第一个索引开始
3.ArrayList和Vector都是用数组方式存储数据,此数组元素数要大于实际的存储空间以便进行元素增加和插入操作,他们都允许直接用序号索引元素,但是插入数据元素涉及到元素移动等内存操作,所以索引数据快而插入数据慢.
4.Vector使用了sychronized方法(线程安全),所以在性能上比ArrayList要差些.
5.LinkedList使用双向链表方式存储数据,按序号索引数据需要前向或后向遍历数据,所以索引数据慢,是插入数据时只需要记录前后项即可,所以插入的速度快.
6.以下程序的运行结果是
byte b=Byte.MAX_VALUE;
b+=1;
System.out.println(b);
- 答案:-128
7.设x=1,y=2,z=3,u=false,则表达式u=y>z^x!=z 的值是什么?
- 答案:true
u=(y>z)^(x!=z) = (2>3)^(1!=3)=false^true=true
8.下面Java程序输出结果是什么?
public static void main(String[] args){
final int A=4;
int a=2;
switch (a*2) {
case A:
System.out.println(a);
default:
System.out.println(a*2);
}
}
- 答案: 2 4
9.对数组{314,298,508,123,486,145}按从小到大的顺序进行插入排序,经过两趟排序后的结果为什么?
- 答案:{298,314,508,123,486,145}
10.运行下面代码结果输出结果是什么?
public class Test {
public static void main(String[] args){
int num=10/4;
float num2=10/4;
System.out.println(num);
System.out.println(num2);
}
}
- 答案:2 2.0
11.以下代码运行结果是什么?
public class Demo extends A{
private String s="hello";
public Demo(){
hello();
}
public void hello(){
System.out.println("s="+s);
}
public static void main(String[] args) {
new Demo();
}
}
class A{
private String s2="world";
public A(){
hello();
}
public void hello(){
System.out.println("s="+s2);
}
}
- 答案:s=null,s=hello
12.System.out.println(3<2?‘a’:98)的输出结果是什么?
- 答案:b
- 解析:当int与char类型进行比较的时候,比较的是他们的ASCII码;b=98
- 三目运算符规则:<表达式1> ? <表达式2> : <表达式3>; "?"运算符的含义是:先求表达式1的值,如果为真,则执行表达式2,并返回表达式2的结果;如果表达式1的值为假,则执行表达式3,并返回表达式3的结果。
13.以下代码的运行结果是什么?
public class Bground extends Thread{
public static void main(String[] args){
Bground b=new Bground();
b.run();
}
public void start(){
for(int i=0;i<10;i++){
System.out.println("Value of i=" +i);
}
}
}
- 答案:编译无错,但不打印任何值。调用run不创建线程
- example:
public class Bground extends Thread{
public static void main(String argv[])
{
//Bground b = new Bground();
Thread b = new Thread(new MyRunnable());
b.run();
}
public void start()
{
for (int i = 0; i <10; i++){
System.out.println("Value of i = " + i);
}
}
}
class MyRunnable implements Runnable{
@Override
public void run() {
for (int i = 0; i <10; i++){
System.out.println("Value of i = " + i);
}
}
}
结果:
Value of i = 0
Value of i = 1
Value of i = 2
Value of i = 3
Value of i = 4
Value of i = 5
Value of i = 6
Value of i = 7
Value of i = 8
Value of i = 9
- 解析:调用线程类的run()方法时,如果该线程是实现的Runnable接口,那么调用run()时就会执行该Runnable,否则无反应。
14.下面这个代码的运行结果是什么?
public class HelloB extends HelloA {
public HelloB() {
System.out.println("HelloB");
}
{
System.out.println("I’m B class");
}
static {
System.out.println("static B");
}
public static void main(String[] args) {
new HelloB();
}
}
class HelloA {
public HelloA() {
System.out.println("HelloA");
}
{
System.out.println("I’m A class");
}
static {
System.out.println("static A");
}
}
- 答案:(详解见上篇:静态代码块与非静态代码块)
static A
static B
I’m A class
HelloA
I’m B class
HelloB()
15.下面代码的运行结果是什么?
public class Test{
public static void main(String[] args){
String s ;
System.out.println("s="+s);
}
}
- 答案:编译错误
- 解析:原因是s是在方法中定义的变量,没有初始值,即使用之前必须先给值,要不就报错。如果变量s在类中方法外定义有默认值null,就不会报错
16.String类和StringBuffer类的主要区别是什么?
1.就是一个变量和常量的关系。StringBuffer对象的内容可以修改;而String对象一旦产生后就不可以被修改,重新赋值其实是两个对象。
2.StringBuffer的内部实现方式和String不同,StringBuffer在进行字符串处理时,不生成新的对象,在内存使用上要优于String类。所以在实际使用时,如果经常需要对一个字符串进行修改,
3.插入、删除等操作,使用StringBuffer要更加适合一些。String对象创建以后就不能修改了,除非让String类型的引用指向另一个String对象。
17.请简述final,finally,finalize的区别
final
用于修饰类、成员变量和成员方法。final修饰的类,不能被继承(String、StrngBuilder、StringBuffer、Math,不可变类),其中所有的方法都不能被重写,所有不能同时用abstract和final修饰(abstract修饰的是抽象类,抽象类是用于被子类继承的,和final起相反的作用);final修饰的方法不能被重写,但是子类可以用父类中final修饰的方法;final修饰的成员变量是不可变的,如果成员变量是基本数据类型,初始化之后成员变量的值不能被改变,如果成员变量是引用类型,那么它只能指向初始化时指向的那个对象,不能再指向别的对象,但是对象中的内容是允许改变的。
finally
finally是在异常处理时提供finally块来执行任何清除操作。不管有没有异常被抛出、捕获都会被执行。try块中的内容是在无异常时执行到结束。catch块中的内容,是在try块内容发生catch所声明的异常时,跳转到catch块中执行。finally块则是无论异常是否发生都会执行finally块的内容,所以在代码逻辑中有需要无论发生什么都必须执行的代码,可以放在finally块中。
finalize
finalize是方法名,java技术允许使用finalize()方法在垃圾收集器将对象从内存中清楚出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的,它是在Object类中定义的,因此所有的类都继承了它。子类覆盖finalize()方法以整理系统资源或者执行其他清理工作。finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。
18.sleep()和wait()有什么区别?
类的不同:sleep() 来自 Thread,wait() 来自 Object。
释放锁:sleep() 不释放锁;wait() 释放锁。
用法不同:sleep() 时间到会自动恢复;wait() 可以使用 notify()/notifyAll()直接唤醒。
19.写一个类Student类,有id,name,score属性,把学生对象放到集合中排序,按照学生分数从高到低排(名字叫tom的学生特殊照顾一下,无论多少分都要排在第一名)
public class Student{
private int id;
private String name;
private int score;
public Student(int id, String name, int score) {
this.id = id;
this.name = name;
this.score = score;
}
public Student() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public String toString() {
return "Student
[id=" + id + ",
score=" + score+ "]";
}
}
public class MyComparator implements Comparator<Student> {
public int compare(Student o1, Student o2) {
if(o1.getName()=="tom"&&o2.getName()!="tom"){
return -1;
}else if(o1.getName()!="tom"&&o2.getName()=="tom"){
return 1;
}else{
if(o1.getScore()>o2.getScore()){
return -1;
}else if(o1.getScore()<o2.getScore()){
return 1;
}else{
return 0;
}
}
}
}
public class StudentTreeSet {
public static void main(String[] args) {
MyComparator myComparator = new MyComparator();
TreeSet<Student> treeSet = new TreeSet<Student>(myComparator);
Student s1 = new Student(1, "zhangsan1", 42);
Student s2 = new Student(2, "zhangsan2", 46);
Student s3 = new Student(3, "zhangsan3", 41);
Student s4 = new Student(4, "tom", 40);
treeSet.add(s1);
treeSet.add(s3);
treeSet.add(s4);
treeSet.add(s2);
for(Student o:treeSet){
System.out.println(o);
}
}
}
20.请写出冒泡排序,选择排序和插入排序
- 冒泡排序:
从前往后,依次比较相邻的两个数,把较大的数放到后面。一次循环,可以在当前最末尾位置得到一个当前最大值。
//冒泡排序
public class Bubble {
public static void sort(int[] arr){
int temp;
//依次将最大的数放置到数组末尾,将第二大的数放到倒数第二位...
for(int i = 0;i < arr.length-1;i++){
//从前往后,比较相邻两个数,把大的放在后边.之前已放置成功的可以不再参与比较
for(int j = 0;j < arr.length-1-i;j++){
if(arr[j]>arr[j+1]) {
swap(arr,j,j+1);
changed = true;
}
}
}
}
public static void swap(int []arr,int a ,int b){
int temp=arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
}
代码优化:在某些时候,循环还未终止,整个数组已经排好序,此时应及时终止循环。(冒泡每次都会比较相邻两个数并交换次序不对的组,若一次循环后,都没进行交换,则已经完成排序)
public class Bubble {
public static void sort(int[] arr){
int temp;
boolean changed;
for(int i = 0;i < arr.length-1;i++){
changed = false;
for(int j = 0;j < arr.length-1-i;j++){
if(arr[j]>arr[j+1]) {
swap(arr,j,j+1);
changed = true;
}
}
if(!changed){
break;
}
}
}
public static void swap(int []arr,int a ,int b){
int temp=arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
}
- 选择排序:
从数组中找到最小的元素,和第一个位置的元素互换。
从第二个位置开始,找到最小的元素,和第二个位置的元素互换。
…
直到选出array.length-1个较小元素,剩下的最大的元素自动排在最后一位。
//选择排序
public class Selection {
public static void sort(int[] arr){
for(int i=0; i<arr.length-1; i++) {
int minPos = i;
for (int j = i; j < arr.length; j++) {
if (arr[j] < arr[minPos]) {
minPos = j;//找出当前最小元素的位置
}
}
if(arr[minPos]!=arr[i]) {
swap(arr,minPos,i);
}
}
}
public static void swap(int[] arr,int a,int b){
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
}
- 插入排序:
从第一个元素开始,若当前元素i小于有序数组中的元素j,则从该元素开始将有序数组依次后移一位,并将当前元素i放置到该元素j位置
//插入排序
public class Main{
public static void main(String[] args){
int[] a=new int[]{1,3,1,2,0,4,5,2,6,2,0};
int n=a.length;
int i,j,temp;//用来暂存
for(i=1;i<n;i++){
temp=a[i];
j=i-1;
for(;j>=0&&a[j]>temp;j--)//找到插入位置的同时往一边整体移动数组
a[j+1]=a[j];
if(j!=i-1)//j等于i-1的话自然不需要填补了
a[j+1]=temp;
}
print(a);
}
public static void print(int[] a){
int n=a.length;
for(int i=0;i<n;i++)
System.out.print(a[i]+" ");
}
}
优化代码: 从有序数组最后一个元素开始,若当前元素i小于该元素j,则交换当前元素和该元素。
public class Insertion {
public static void sort(int[] arr){
int pos,temp;
for(int i=1;i<arr.length;i++){
pos = i;
while(pos!=0&&arr[pos]<arr[pos-1]){
temp = arr[pos];
arr[pos] = arr[pos-1];
arr[pos-1] = temp;
pos--;
}
}
}
}