2019年总结年度最坑面试题
-
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。
-
下面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。
-
为什么下面打印结果一个为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时相等了。
-
将变量作为参数传递,在方法中改变参数值,变量的值改变了么?下图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。
-
由数组转换的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,但只是数组中内部定义的一种数据结构类型,本质还是原数组而并非列表,因此当向列表添加元素就会出现错误,这道题上当的兄弟不少吧。
-
.将列表中李明的名字移除掉,下图实现有无问题?
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); } } }
在列表中移除最后一个元素按说应该没有问题的,但是这个算法还是出现了错误,主要是这种写法的列表循环遵循下表索引查找,当移除某个元素时,上次计算出来的长度超过了当前列表长度,故而会出现越界错误。
-
在指定目录下创建文件目录,到底使用哪一种呢,两个方法都没报错,为何第一次没创建目录而第二次创建?
public static void main(String[] args) { String path = "D:/test/file"; new File(path).mkdir(); new File(path).mkdirs(); }
mkdirs()可以建立多级文件夹,而mkdir()只会建立一级的文件夹。这个主要依靠java底层调用操作系统的实现,作者愚见无须弄明白底层实现原理,只要使用中能区分不留BUG就好。
-
老板从客户那里回来后骂了我一顿,说是客户界面显示金额很奇怪,我的代码那里有问题?
public static void main(String[] args) { Float totalMoney = 200000.8f; Float ownMoney = 170000.5f; Float leftMoney = totalMoney - ownMoney; System.out.println("剩余金额" + leftMoney); }
这道题如果我是老板我会打你的,因为老板之前也写过代码。老板之所以骂你是因为客户看到的太奇怪以至于看不懂,两个float类型数据相减会丢失精度,尾部带着常常的一串数字。如果实际场景要做计算我给你两个思路:第一可以用bigdecimal来计算,第二先将单位做成整数再做除法。
-
你能说出来java中实现多线程的几种方法么?
面试者:继承Thread类和实现runnable接口! 面试官:除此以外还有方法么? 面试者:就这两种实现啊?! 面试官:我们聊点别的,呵呵。
这道题最有意思了,一般人都会干脆利索回答前两个,我工作前3年每次都是信心满满这样回答问题的。其实 实现多线程还可以实现Callable接口,利用task来接受异步线程的执行结果。希望后面再被面试官问到这道题可千万别再入坑,并且能回答这第三种方式跟前两种不同的地方(可以获取执行结果)。
-
我只是想让这个好好循环三次,有什么问题么?
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以后的数值这道陷阱题就解决了。
-
这个一直没有弄明白,到底返回哪个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。
-
课后练习:最后打印的值是多少?
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技术群 不吹水,不开车,不斗图 做到有问必答,共同进步 那么怎么做到有问必答呢?
- 热心观众,自然有人愿意回答
- 重赏之下必有勇夫,你回答我送书
- 求助场外观众,我认识的6个阿里系架构师帮你解决问题
为了减少成本,首先要做到拥有热心观众 热心观众将以内推方式加入群 以邀请人数排名前5名奖励技术书(不能是昂贵的珍藏书籍)目前已买书籍如图显示
注意:本文归作者所有,未经作者允许,不得转载