Java工程师面试1000题31-40

31、简述Java的异常处理机制。

Java对异常进行了分类,不同类型的异常分别使用了不同的Java类表示,所有异常的父类为java.lang.Throwable,Throwable类下面派生了两个子类:ErrorException,Error表示应用程序本身无法克服和恢复的一种严重问题;Exception表示程序还能够克服和恢复的问题,其中Exception又分为系统异常普通异常,系统异常是软件本省缺陷所导致的问题,也就是软件开发人员考虑不周所导致的问题,软件使用者无法克服和恢复这种问题,但在这种问题下还可以让软件系统继续运行或者让软件死掉,例如,数组下标越界异常(ArrayIndexOutOfBoundException),空指针异常(NullPointerException)、类转换异常(ClassCastException);普通异常是软件运行环境的变化或者异常所导致的问题,是用户可以克服的问题,比如网络断线、磁盘空间不足等,发生这样的异常时,程序不应该死掉。

Java为系统异常和普通异常提供了不同的解决方案,编译器要求普通异常必须使用try…catch处理或者throws声明继续抛给上层调用方法处理,所以普通异常也称为checked异常,而系统异常****可以处理也可以不处理,编译器不强制使用try…catch处理或者throws声明,所以系统异常也称为unchecked异常。

32、说出下面程序的输出结果

public class StringEqualTest {
    public static void main(String[] args) {
        String s1 = "Programming";
        String s2 = new String("Programming");
        String s3 = "Program";
        String s4 = "ming";
        String s5 = "Program"+ "ming";
        String s6 = s3 + s4;
        System.out.println(s1 == s2);
        System.out.println(s1 == s5);
        System.out.println(s1 == s6);
        System.out.println(s1 == s6.intern());
        System.out.println(s2 == s2.intern());
    }
}

依次输出:false、true、false、true、false。s1和s2分别是两个不同对象的引用,这个两个对象里面的内容相同,但却不是一个对象,所以地址不同,第一个为false,无需过多解释;利用+直接连接两个字符串常量,虚拟机会直接把这两个字符串连接起来看成一个字符串,所以s1 == s5返回true;利用+连接两个引用,虚拟机看成StringBuilder,会创建一个StringBuilder对象,然后调用append方法进行追加操作,最后调用toString方法转换成String,所以s1 == s6返回false; String对象的intern()方法会得到字符串对象在常量池中对应的版本的引用(前提是常量池中已有一个字符串与String对象的equals结果为true),所以s1 == s6.intern()返回true;同理,s2.intern()是和s6.intern()相同的,所以最后一个的执行结果是false,因为s1 == s2返回的就是false。

33、Java的基本数据类型及各自所占字节数。

byte 1 boolean 1

short 2 char 2

int 4 float 4

long 8 double 8
比较记忆会更快噢。注意:String不是基本数据类型,String是引用类型,String的底层是使用char数组实现的。

34、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),里面已经包含了强制类型转换

35、int和Integer有什么区别?

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

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

自动装箱/拆箱机制:

Integer a = new Integer(3);
Integer b = 3;                //自动装箱为Integer类型
int c = 3;                                        
System.out.println(a == b);   //输出false,两个引用没有指向同一个对象
System.out.println(a == c);   //true,**自动拆箱成int类型进行比较**

36、下面Integer类型的数值比较的结果为?

Integer f1 = 100,f2 = 100,f3 = 150,f4 = 150;
System.out.println(f1 == f2);
System.out.println(f3 == f4);

输出:true,false。首先需要注意的是,f1,f2,f3,f4都是包装类型,所以使用**==运算符比较的不是值**,而是引用。当我们给一个Integer对象赋一个int值的时候,会调用Integer类的静态方法valueOf,查看valueOf源码我们可以知道,对于整型字面量的值在-128到127之间那么不会new新的Integer对象,而是直接引用常量池中的Integer对象,所以上面第一行输出true,第二行由于150大于了128,故输出false。

public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
}
private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];
 
        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;
 
            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
 
            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }
 
        private IntegerCache() {}
    }

(越是简单的面试题,里面的玄机就越多,需要面试者相当深厚的基础功)

37、说出String类的常用方法及功能。

int length():返回当前字符串的长度
int indexOf(int ch/String str):用于查找当前字符串中字符或子串,返回字符或子串在当前字符串中从左边起首次出现的位置,若没有出现则返回-1
int indexOf(int ch/String str, int fromIndex):与上一种类似,区别在于该方法从fromIndex位置向后查找
int lastIndexOf(int ch/String str):类似,区别在于该方法从字符串的末尾位置向前查找
int lastIndexOf(int ch/String str, int fromIndex):类似,区别于该方法从fromIndex位置向前查找。
String toLowerCase():返回将当前字符串中所有字符转换成小写后的新串
String toUpperCase():返回将当前字符串中所有字符转换成大写后的新串
String replace(char oldChar, char newChar)用字符newChar替换当前字符串中所有的oldChar字符,并返回一个新的字符串。
String replaceFirst(String regex, String replacement):该方法用字符replacement的内容替换当前字符串中遇到的第一个和字符串regex相匹配的子串,应将新的字符串返回。
String replaceAll(String regex, String replacement):该方法用字符replacement的内容替换当前字符串中遇到的所有和字符串regex相匹配的子串,应将新的字符串返回。
String trim()截去字符串两端的空格,但对于中间的空格不处理。
char charAt(int index)获取字符串中指定位置的字符
String[] split(String regex):将regex作为分隔符进行字符串分解分解后的字字符串在字符串数组中返回。

38、请说一下数据类型之间的转换

字符串转为基本数据类型调用基本数据类型对应的包装类中的方法parseXXX(String)或者valueOf(String)既可以返回相应的基本数据类型。
基本数据类型转字符串:一种方法是将基本数据类型与空字符串("")连接(+)即可获得对应的字符串,另一种方法是调用String类中的valueOf()方法返回相应字符串。

39、Java中有几种类型的流?

按照流的方向输入流(inputStream)输出流(outputStream);

按照实现的功能分节点流(可以从或向一个特定的地方(节点)读写数据,例如FileReader)、处理流(是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据的读写,例如BufferdReader,处理流的构造方法总是要带一个其他流对象做参数。一个流经过其他流的多次封装,成为流的链接)

按照处理的数据的单位可以分为字节流字符流字节流继承于InputStreamOutputStream字符流继承于InputStreamReaderoutputStreamReader

40、再谈谈String、StringBuffer、StringBuilder之间的区别?

String:字符串常量,再修改时本身不会改变,如修改等于重新生成一个新的字符串对象,String定以后不可改变,故是线程安全的
StringBuffer在修改时会改变对象自身,每次修改操作都是对StringBuffer对象本身进行修改,不是生成新的对象,适用于需要经常改变字符串的情形下,由于实现synchronized同步锁(故效率稍慢),是线程安全的,也适用于多线程环境下
StringBuilder:功能和StringBuffer基本一样,只是没有实现同步锁不是线程安全的,适用于单线程环境下,执行效率较高。

原文:https://blog.csdn.net/qq_21583077/article/details/88196780

猜你喜欢

转载自blog.csdn.net/Mr_Quinn/article/details/88578485