2019年总结年度最坑面试题

GoogleVip8 1年前 ⋅ 669 阅读

2019年总结年度最坑面试题

  1. String、StringBuilder、StringBuff的区别

        public static void main(String[] args) {
            String test = "";
            ArrayList<Student> list = new ArrayList<>();
            Student student = new Student("张三", 12);
            list.add(student);
            student = new Student("李四", 13);
            list.add(student);
            for (Student stu : list) {
                test += "学生名称为:" + stu.getName();
                test += "\n";
            }
            System.out.println(test);
        }
    
        public static void main(String[] args) {
            String test = "";
            ArrayList<Student> list = new ArrayList<>();
            Student student = new Student("张三", 12);
            list.add(student);
            student = new Student("李四", 13);
            list.add(student);
            StringBuilder stringBuilder = new StringBuilder();
            for (Student stu : list) {
                stringBuilder.append("学生名称为:");
                stringBuilder.append(stu.getName());
                stringBuilder.append("\n");
            }
            System.out.println(stringBuilder.toString());
        }
    
        public static void main(String[] args) {
            String test = "";
            ArrayList<Student> list = new ArrayList<>();
            Student student = new Student("张三", 12);
            list.add(student);
            student = new Student("李四", 13);
            list.add(student);
            StringBuffer stringBuffer = new StringBuffer();
            for (Student stu : list) {
                stringBuffer.append("学生名称为:");
                stringBuffer.append(stu.getName());
                stringBuffer.append("\n");
            }
            System.out.println(stringBuffer.toString());
        }
    

    String类作为java语言中最常见的字符串类被广泛使用,如果在做大量字符串拼接效率时变得比较低,因为虚拟机需要不断地将对象引用指向新的地址。因此,一般方法内的私有变量推荐使用stringBuilder来完成,如果是多线程需要同步的自然选用stringBuffer。

  2. 下面equals用法正确的是?

        private static final String readName = "张三";
        public boolean checkParam(String name){
            return name.equals(readName);
        }
    
    private static final String readName = "张三";
        public boolean checkParam(String name){
            return readName.equals(name);
        }
    

    关于这道题需要查看String类中equals的实现方法,当左边为Null时会出现NPE空指针异常。因此后续代码中需要保证equals方法左边变量不为null。

  3. 为什么下面打印结果一个为false,一个为true

            Integer one = 128;
            Integer two = 128;
            System.out.println(one==two);
    

    false

        Integer one = 100;
        Integer two = 100;
        System.out.println(one==two);
    

    true

    Integer类型当正整数小于128时是在内存栈中创建值的,并将对象指向这个值,这样当比较两个栈引用时因为是同一地址引用两者则相等。当大于127时将会调用new Integer(),两个整数对象地址引用不相等了。这就是为什么当值为128时不相等,当值为100时相等了。

  4. 将变量作为参数传递,在方法中改变参数值,变量的值改变了么?下图total值到底是几?

        public static void main(String[] args) {
            Integer total = 0;
            paramCheck(total);
            System.out.println(total);
        }
    
        private static void paramCheck(Integer total) {
            if (total < 1) {
                total += 1;
            }
        }
    

    将一个私有变量作为形参传递赋值并不会改变参数原有的值,但是如果将一个对象作为参数传递改变属性,对象的属性值就会随着改变。因此total的值仍然为0。

  5. 由数组转换的list,只能循环遍历,而不能看长度,增加元素,删除元素,这是为何?下图代码执行竟然出错!

        public static void main(String[] args) {
            String[] array = new String[]{"张三","李四","王五"};
            List<String> list = Arrays.asList(array);
            list.add("孙六");
            System.out.println(list.size());
        }
    

    因为将数组转换的列表其实不是我们经常使用的arrayList,但只是数组中内部定义的一种数据结构类型,本质还是原数组而并非列表,因此当向列表添加元素就会出现错误,这道题上当的兄弟不少吧。

  6. .将列表中李明的名字移除掉,下图实现有无问题?

        public static void main(String[] args) {
            ArrayList<String> list = new ArrayList<>();
            String removeName = "孙六";
            list.add("张三");
            list.add("李四");
            list.add("王五");
            list.add("孙六");
            for (String name : list) {
                if (removeName.equals(name)) {
                    list.remove(name);
                }
            }
        }
    

    在列表中移除最后一个元素按说应该没有问题的,但是这个算法还是出现了错误,主要是这种写法的列表循环遵循下表索引查找,当移除某个元素时,上次计算出来的长度超过了当前列表长度,故而会出现越界错误。

  7. 在指定目录下创建文件目录,到底使用哪一种呢,两个方法都没报错,为何第一次没创建目录而第二次创建?

        public static void main(String[] args) {
            String path = "D:/test/file";
            new File(path).mkdir();
            new File(path).mkdirs();
        }
    

    mkdirs()可以建立多级文件夹,而mkdir()只会建立一级的文件夹。这个主要依靠java底层调用操作系统的实现,作者愚见无须弄明白底层实现原理,只要使用中能区分不留BUG就好。

  8. 老板从客户那里回来后骂了我一顿,说是客户界面显示金额很奇怪,我的代码那里有问题?

        public static void main(String[] args) {
            Float totalMoney = 200000.8f;
            Float ownMoney = 170000.5f;
            Float leftMoney = totalMoney - ownMoney;
            System.out.println("剩余金额" + leftMoney);
        }
    

    这道题如果我是老板我会打你的,因为老板之前也写过代码。老板之所以骂你是因为客户看到的太奇怪以至于看不懂,两个float类型数据相减会丢失精度,尾部带着常常的一串数字。如果实际场景要做计算我给你两个思路:第一可以用bigdecimal来计算,第二先将单位做成整数再做除法。

  9. 你能说出来java中实现多线程的几种方法么?

    面试者:继承Thread类和实现runnable接口! 面试官:除此以外还有方法么? 面试者:就这两种实现啊?! 面试官:我们聊点别的,呵呵。

    这道题最有意思了,一般人都会干脆利索回答前两个,我工作前3年每次都是信心满满这样回答问题的。其实 实现多线程还可以实现Callable接口,利用task来接受异步线程的执行结果。希望后面再被面试官问到这道题可千万别再入坑,并且能回答这第三种方式跟前两种不同的地方(可以获取执行结果)。

  10. 我只是想让这个好好循环三次,有什么问题么?

        public static final int ENDNUMBER = Integer.MAX_VALUE;
        public static final int STARTNUMBER = ENDNUMBER - 2;
        public static void main(String[] args) {
            int count = 0;
            for (int i = STARTNUMBER; i < ENDNUMBER; i++) {
                count++;
            }
            System.out.println(count);
        }
    

    这道题主要是犯了整数符号位的问题了,大家可以了解一下

    Integer.MAX_VALUE加上1以后的数值这道陷阱题就解决了。

  11. 这个一直没有弄明白,到底返回哪个true还是false?

        public static void main(String[] args) {
            System.out.println(findResult());
        }
        public static boolean findResult(){
            try {
                return true;
            }catch (Exception e){
                return true;
            }finally {
                return false;
            }
        }
    

    这道题大家需要弄明白finally的使用场景,主要是捕获异常以后必须要执行的代码,大多是关闭流之类的。即使try的代码块已经返回结果但程序仍然会执行finally里面的代码,因此上题返回false。

  12. 课后练习:最后打印的值是多少?

     public static void main(String[] args) {
            System.out.println(findResult());
        }
    	public static Integer findResult(){
            Integer aIntaget = 5;
            try {
                return aIntaget = 6;
            }catch (Exception e){
                return aIntaget = 7;
            }finally {
                return aIntaget = 8;
            }
        }
    

    《阿里渣渣Java研发组》qq号:831363708

    点击链接加入群聊【阿里渣渣java研发组】

    本群将打造为高质量java技术群 不吹水,不开车,不斗图 做到有问必答,共同进步 那么怎么做到有问必答呢?

    1. 热心观众,自然有人愿意回答
    2. 重赏之下必有勇夫,你回答我送书
    3. 求助场外观众,我认识的6个阿里系架构师帮你解决问题

    为了减少成本,首先要做到拥有热心观众 热心观众将以内推方式加入群 以邀请人数排名前5名奖励技术书(不能是昂贵的珍藏书籍)目前已买书籍如图显示


全部评论: 0

    我有话说: