Java封神之路:Java面试备战(五)

1.76 如果有两个类A、B(注意不是接口),你想同时使用这两个类的功能,那么你会如何编写这个C类呢?

因为类A、B不是接口,所以是不可以直接实现的,但可以将A、B类定义成父子类,那么C类就能实现A、B类的功能了。假如A为B的父类,B为C的父类,此时C就能使用A、B的功能

1.77 一个类的构造方法是否可以被重载(overloading),是否可以被子类重写(overrding)

构造方法可以被重载,但是构造方法不能被重写,子类也不能继承到父类的构造方法

1.78 Java中byte表示的数值范围是什么?

范围是-128至127

1.79 如何将日期类型格式化为:2013-02-18 10:53:10

public class DateFormat{public static void main(String[] args) throws Exception {        //第一步:将字符串(2013-02-18 10:53:10)转换成日期Date        DateFormat  sdf=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");        String sdate="2013-02-18 10:53:10";        Date date=sdf.parse(sdate);        System.out.println(date);        //第二步:将日期Date转换成字符串String        DateFormat  sdf2=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");        String sdate2=sdf2.format(date);        System.out.println(sdate2);    }}

1.80 下面哪些是对称加密算法

1.81 以下Java代码段会产生几个对象

String a="a";          String b="b";        String c="c";        c=a "" b "" c;        System.out.print(c);

一个对象,因为编译期进行了优化,3个字符串常量直接折叠为一个

1.82 Math.round(-11.2)的运行结果是

四舍五入

1.83 System.out.println(‘a’ 1);的结果是

'a’是char型,1 是int行,int与char相加,char会被强转为int行,char的ASCII码对应的值是97,所以加一起打印98

1.84 下列说法正确的是

1.85 下列语句正确的是

1.86 成员变量用static修饰和不用static修饰有什么区别

1、两个变量的生命周期不同。

成员变量随着对象的创建而存在,随着对象的被回收而释放。

静态变量随着类的加载而存在,随着类的消失而消失。

2、调用方式不同。

成员变量只能被对象调用。

成员变量只能被对象调用。

成员变量只能被对象调用。

类名调用 :Person.country

3、别名不同。

成员变量也称为实例变量。

静态变量称为类变量。

4、数据存储位置不同。

成员变量数据存储在堆内存的对象中,所以也叫对象的特有数据.

静态变量数据存储在方法区(共享数据区)的静态区,所以也叫对象的共享数据.

1.87 float f=3.4;是否正确

不正确。3.4是双精度数,将双精度型(double)赋值给浮点型(float)属于下转型(down-casting,也称为窄化)会造成精度损失,因此需要强制类型转换float f =(float)3.4; 或者写成float f =3.4F

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

1.89 Java 有没有goto

goto 是Java中的保留字,在目前版本的Java中没有使用,其中有goto和const,但是这两个是目前无法使用的关键字,因此有些地方将其称之为保留字,其实保留字这个词应该有更广泛的意义,因为熟悉C语言的程序员都知道,在系统类库中使用过的有特殊意义的单词或单词的组合都被视为保留字

1.90 swtich 是否能作用在byte 上,是否能作用在long 上,是否能作用在String上

早期的JDK中,switch(expr)中,expr可以是byte、short、char、int。从1.5版开始,Java中引入了枚举类型(enum),expr也可以是枚举,从JDK 1.7版开始,还可以是字符串(String)。长整型(long)是不可以的

1.91 两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对

不对,如果两个对象x和y满足x.equals(y) == true,它们的哈希码(hash code)应当相同。Java对于eqauls方法和hashCode方法是这样规定的:(1)如果两个对象相同(equals方法返回true),那么它们的hashCode值一定要相同;(2)如果两个对象的hashCode相同,它们并不一定相同。当然,你未必要按照要求去做,但是如果你违背了上述原则就会发现在使用容器时,相同的对象可以出现在Set集合中,同时增加新元素的效率会大大下降(对于使用哈希存储的系统,如果哈希码频繁的冲突将会造成存取性能急剧下降)

1.92 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递

是值传递。Java 编程语言只有值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的属性可以在被调用过程中被改变,但对象的引用是永远不会改变的。C 和C#中可以通过传引用或传输出参数来改变传入的参数的值。

1.93 为什么不能根据返回类型来区分重载,为什么

方法的重载,即使返回值类型不同,也不能改变实现功能相同或类似这一既定事实;同时方法的重载只是要求两同三不同,即在同一个类中,相同的方法名称,参数列表当中的参数类型、个数、顺序不同;跟权限修饰符和返回值类无关

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

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

1.95 静态变量和实例变量的区别

静态变量是被static修饰符修饰的变量,也称为类变量,它属于类,不属于类的任何一个对象,一个类不管创建多少个对象,静态变量在内存中有且仅有一个拷贝;实例变量必须依存于某一实例,需要先创建对象然后通过对象才能访问到它,静态变量可以实现让多个对象共享内存。两者的相同点:都有默认值而且在类的任何地方都可以调用。在Java开发中,上下文类和工具类中通常会有大量的静态成员

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

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

1.97 如何实现对象的克隆

import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream; public class MyUtil {      private MyUtil() {        throw new AssertionError();    }      public static <T> T clone(T obj) throws Exception {        ByteArrayOutputStream bout = new ByteArrayOutputStream();        ObjectOutputStream oos = new ObjectOutputStream(bout);        oos.writeObject(obj);        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());        ObjectInputStream ois = new ObjectInputStream(bin);        return (T) ois.readObject();        // 说明:调用ByteArrayInputStream或ByteArrayOutputStream对象的close方法没有任何意义        // 这两个基于内存的流只要垃圾回收器清理对象就能够释放资源}}

有两种方式:

1.实现Cloneable接口并重写Object类中的clone()方法;

2.实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆,代码如下

import java.io.Serializable;/** * 人类 * @author sxt*/class Person implements Serializable {    private static final long serialVersionUID = -9102017020286042305L;    private String name;    // 姓名    private int age;        // 年龄    private Car car;        // 座驾     public Person(String name, int age, Car car) {        this.name = name;        this.age = age;        this.car = car;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    public Car getCar() {        return car;    }    public void setCar(Car car) {        this.car = car;    }    @Override    public String toString() {     return "Person [name="   name   ", age="   age   ", car="   car   "]";    }  }  /** * 小汽车类 * @author sxt*/class Car implements Serializable {    private static final long serialVersionUID = -5713945027627603702L;    private String brand;       // 品牌    private int maxSpeed;       // 最高时速     public Car(String brand, int maxSpeed) {        this.brand = brand;        this.maxSpeed = maxSpeed;    }    public String getBrand() {        return brand;    }    public void setBrand(String brand) {        this.brand = brand;    }    public int getMaxSpeed() {        return maxSpeed;    }     public void setMaxSpeed(int maxSpeed) {        this.maxSpeed = maxSpeed;    }     @Override    public String toString() {        return "Car [brand="   brand   ", maxSpeed="   maxSpeed   "]";    }  } class CloneTest {  public static void main(String[] args) {        try {            Person p1 = new Person("Hao LUO", 33, new Car("Benz", 300));            Person p2 = MyUtil.clone(p1);   // 深度克隆            p2.getCar().setBrand("BYD");            // 修改克隆的Person对象p2关联的汽车对象的品牌属性            // 原来的Person对象p1关联的汽车不会受到任何影响            // 因为在克隆Person对象时其关联的汽车对象也被克隆了            System.out.println(p1);        } catch (Exception e) {            e.printStackTrace();        }    }}

注意:基于序列化和反序列化实现的克隆不仅仅是深度克隆,更重要的是通过泛型限定,可以检查出要克隆的对象是否支持序列化,这项检查是编译器完成的,不是在运行时抛出异常,这种是方案明显优于使用Object类的clone方法克隆对象。

1.98 接口是否可继承接口? 抽象类是否可实现接口? 抽象类是否可继承具体类

接口可以继承接口。抽象类可以实现(implements)接口,抽象类可以继承具体类。抽象类中可以有静态的main方法。

备注:只要明白了接口和抽象类的本质和作用,这些问题都很好回答,你想想,如果你是java语言的设计者,你是否会提供这样的支持,如果不提供的话,有什么理由吗?如果你没有道理不提供,那答案就是肯定的了。

只有记住抽象类与普通类的唯一区别就是不能创建实例对象和允许有abstract方法。

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

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

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

一个内部类对象可以访问创建它的外部类对象的成员,包括私有成员。如果要访问外部类的局部变量,此时局部变量必须使用final修饰,否则无法访问。

1.101 指出下面程序的运行结果

public class Hello {    public static void main(String[] args){        A ab = new B();        ab = new B();    }}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");    }}

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

考点:静态代码块优先级 > 构造方法的优先级如果再加一个普通代码块,优先顺序如下:静态代码块>普通代码块>构造方法

1.102 说说数据类型之间的转换

1 ) 如何将字符串转换为基本数据类型?

调用基本数据类型对应的包装类中的方法parseXXX(String)或valueOf(String)即可返回相应基本类型;

2 ) 如何将基本数据类型转换为字符串?

一种方法是将基本数据类型与空字符串(””)连接( )即可获得其所对应的字符串;另一种方法是调用String 类中的valueOf(…)方法返回相应字符串

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

String s1 = “你好”;

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

在String类的构造方法当中,存在一个字符集设置的方法,

1.104 Java中的日期和时间

1 ) 如何取得年月日、小时分钟秒?

创建java.util.Calendar 实例,调用其get()方法传入不同的参数即可获得参数所对应的值

2 ) 如何取得从1970年1月1日0时0分0秒到现在的毫秒数?

Calendar.getInstance().getTimeInMillis();

3 ) 如何取得某月的最后一天?

time.getActualMaximum(Calendar.DAY_OF_MONTH);

4 ) 如何格式化日期?

利用java.text.DataFormat 的子类(如SimpleDateFormat类)中的format(Date)方法可将日期格式化。

1.105 Comparable和Comparator接口是干什么的,列出它们的区别

这两个接口都是用来做比较的

区别:

1、如果实现类没有实现Comparable接口,又想对两个类进行比较(或者实现类实现了Comparable接口,但是compareTo方法内的比较算法不满意),那么可以实现Comparator接口,自定义一个比较器,写比较算法

2、实现Comparable接口的方式比实现Comparator接口的耦合性要强一些

(0)

相关推荐