博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java 面试基础问题集1
阅读量:6077 次
发布时间:2019-06-20

本文共 4349 字,大约阅读时间需要 14 分钟。

hot3.png

Q. 为什么 -0/3 结果是 0,而 -0.0/3.0 结果是 -0.0?(注意后边的结果0带负号)

A. 在Java里,整数是用补码表示的。在补码中0只有一种表示方法。另一方面,浮点数则是用 IEEE 标准表示的, 对于0有两种表示方法, 0 和 -0。

 

Q. 我可以用 % 除以一个小数吗?

A. 当然可以。比如,如果  是一个非负数,那么 angle % (2 * Math.PI) 就会把  转换到 0 到 2 π 之间。

 

Q. 当 a b 都是基本类型变量时,a += b 和 a = a + b 的效果有区别吗?

A. 当 a 和 b 的类型不同时,那两条语句的效果就可能有区别。 a += b 等同于 a = (int) (a + b),这种情况下可以是 a是int型,b是float型。但是同等情况下 a = a + b就会编译报错。

 

Q. 为什么判断字符串相等不能使用 == ?

A. 这反映了基础类型(int, double, boolean)和引用类型(String)的区别。

 

Q. 有没有在什么情况下,一条语句块的花括号不能省略的?

A. 在下面的例子中,第一段代码是合法的,第二段代码会引发编译错误。从技术角度说,那一条语句是一个变量声明,而不是语句,所以会报错。

//1 for(int i=0;i<5;i++){    int n=10;}//2    for(int i=0;i<5;i++)   int n=10; // error :Declaration not allowed here

 

Q. 在下面的两段代码里,有没有情况,它们的效果不一样?

//1for(int i=0;i<5;i++){   //TODO}//2int i=0;while(i<5){   //TODO   i++;}

A. 有的。如果在循环块里使用 continue 语句。在for的代码里,计数器会加一;而在while的代码里,因为被continue略过了,计数器不加一。

 

Q. 使用 int a[] 而不是 int[] a 去声明一个数组。这两者有什么区别?

A. 在Java中这两种用法都是合法的,他们的作用都是一样的。

前者是在C中的定义数组的方法。后者是JAVA推荐的方法,因为它的写法 int[] 更能表明这是一个 int 的数组。

 

Q. 为什么数组下标从0 开始而不是从 1 开始?

A. 这种传统起源于机器语言的编程方法。在机器语言中,数组下标被用来计算元素位置与第一个元素之间的偏移量。如果从1开始的话,计算偏移时还需要做一次减法运算,那是种浪费。

 

Q. 如果用负数作为数组下标会发生什么事?

A. 下标小于0或者大于等于数组长度,JAVA运行时会抛出ArrayIndexOutOfBoundsException 异常,并且中止程序运行。

 

Q. 使用数组时还有其他需要注意的陷阱吗?

A. 需要记住,JAVA在你创建一个数组时会去初始化它,所以声明一个数组需要O(N)的时间。

 

Q. 既然 a 是一个数组,为什么 System.out.println(a) 会打印出一个16进制的数,就像 @f62373 这样,而不是打印出数组的元素?

A. 这条语句打印出的是数组在内存中的地址,不幸的是,在绝大多数情况下,这不是你需要的。

 

Q. 我可以从标准input中重新读一次数据吗?

A. 不可以,你只能读一次。

 

Q. 怎样输入 end-of-file (eof) 符号?

A. 自动包括它了。

 

Q. 使用 printf 时还有哪些用法?

A. 对于整数来说,使用 o 输出八进制,使用 x 输出十六进制。对于浮点数来说,使用 e 或者 g 输出科学计数法形式。

 

Q. 行结束的符号是什么?

A. 不同的文件系统使用了不同的符号。在  系统上,新行的符号是 '\n' ;在 系统上,每一行都有两个字符组成的字符串终结 "\r\n" ;在 Macs 系统上,终结符号是 "\n\r" 。如果要打印行号,可以使用 System.out.println ,或者使用下面的语句得到当前操作系统下的行结束符:

String newline= System.getProperty("line.separator"); 

 

Q. 下面两种写法,哪一种更有效率?

//1String s;while(!StdId.isEmpty()){    s=StdIn.readString();}        //2while(!StdId.isEmpty()){    String s=StdIn.readString();}

A. 从效率角度说,两者没有区别。但是第二种写法更好,因为它限制了变量的作用域。

 

Q. 为什么不把所有的参数都使用传值的方式,包括对待数组?

A. 但数组很大时,复制数组需要大量的性能开销。因为这个原因,绝大多数变成语言支持把数组传入函数但不复制一个副本——语言除外。

 

Q. 有没有只能用循环而不能用递归的情况?

A. 不可能,所有的循环都可以用递归替代,虽然大多数情况下,递归需要额外的内存。

 

Q. 有没有只能用递归而不能用循环的情况?

A. 不可能,所有的递归调用都可以用循环来表示。比如你可以用while的方式来实现栈。

注:根据代码的可读性和效率性之间做权衡选择循环或递归。

Q. 使用递归代码时的空间开销和重复计算(例如用递归解Fibonacci)时需要注意什么?

A. 在递归代码中创建类型(比如数组)时需要额外注意,随着递归的推进,内存使用将会迅速增加,由于内存使用增加,管理内存的时间开销也会增加。

 

Q. 为什么我们要花大篇幅来证明一个程序是正确的?

A. 为了防止错误的结果。

二分查找就是一个例子。现在,你懂得了二分查找的原理,你就能把递归形式的二分查找改写成循环形式的二分查找。Knuth 教授在 1946年就发表了二分查找的论文,但是第一个正确的二分查找的程序在 1962年在出现。

 

Q. 在JAVA内建库中有没有排序和查找的函数?

A. 有的。在 java.util.Arrays 中包含了 Arrays.sort 和 Arrays.binarySearch 方法。对于Comparable 类型它使用了归并排序,对于基本数据类型,它使用了快速排序。因为基本类型是值传递,快速排序比归并排序更快而且不需要额外的空间。

 

Q. 为什么JAVA库不用随机方式的快速排序?

A. 因为某些在调试代码时,可能需要确定性的代码实现。使用随机违背了这个原则。

 

Q. 在Java库中有对stacks 和 queues 的实现吗?

A. Java库中内建 java.util.Stack,但是你应该避免使用它如果你需要一个真正的栈的话。因为它是实现了额外的功能,比如访问第N个元素。另外,它也支持从栈底部插入元素,所以它看上去更像是一个队列。尽管实现了这些额外的功能对编程人员是一个加分,可是我们使用并不只是想使用所有功能,而是需要我们正好需要的那种结构。JAVA对于栈的实现就是一个典型的宽接口的例子。

 

Q. 我想使用数组来表示一个包含泛型的栈,但是以下代码编译报错。为什么?

private Item[] a = new Item[max]; oldfirst = first;

A. 创建一个泛型数组在 Java 1.5里不支持。你可以使用cast,比如下面的写法:

private Item[] a = (Item[]) new Object[max]; oldfirst = first;

根本的原因是JAVA中的数组是“协变的(covariant)”,但是泛型并不是。比如, String 是 Object的一种子类型,但是 Stack<String>并不是 Stack<Object> 的一种子类型。 许多认为“协变的”数组是JAVA在数据类型方面的一个缺点。但是,如果我们不考虑泛型,“协变的”数组是有用的,比如实现Arrays.sort(Comparable) 方法,然后当参数是 String时它也可以被正常调用。

 

Q. 可不可以在数组上使用 foreach 方式?

A. 可以的(虽然数组并没有实现  接口)。请参考下面的代码:

public static void main(String[] args) {     for (String s : args)        StdOut.println(s); }

Q. 在 linked list 上使用  是不是比循环或者递归更有效率?

A. 在时,可能把那种“”形式成等价的循环形式。所以可能并没有可以被观测到的性能提升。

是一种编程技巧。如果在递归函数中,递归调用返回的结果总被直接返回,则称为。尾递归是极其重要的,不用尾递归,函数的堆栈耗用难以估量,需要保存很多中间函数的堆栈。比如f(n, ) = f(n-1) + value(n) + sum; 会保存n个函数调用堆栈,而使用f(n, sum) = f(n-1, +value(n)); 这样则只保留后一个函数堆栈即可,之前的可优化删去。

Q. 自动装箱机制会怎么处理下面的情况?

Integer a = null; int b = a;

A. 它将返回一个运行时错误。基础类型不允许它对应的装箱类型里的值是null。

Q. 为什么第一组打印的是 true,但是后面两组打印的是 false?

Integer a1 = 100; Integer a2 = 100; System.out.println(a1 == a2); // true Integer b1 = new Integer(100); Integer b2 = new Integer(100); System.out.println(b1 == b2); // false Integer c1 = 150; Integer c2 = 150; System.out.println(c1 == c2); // false

A. 第二组代码打印 false 是因为 b1 和 b2 指向不同的 Integer 对象引用。第一组和第三组依赖于自动装箱机制。令人意外的第一组打印了 true 是因为在 -128 和 127之间的值会自动转换成同样的immutable型的Integer 对象。对于超出那个范围的数,会对于每一个数创建一个新的Integer对象。

 

转载于:https://my.oschina.net/u/574036/blog/888033

你可能感兴趣的文章
tomcat多应用之间如何共享jar
查看>>
Flex前后台交互,service层调用后台服务的简单封装
查看>>
MySQL入门12-数据类型
查看>>
Windows Azure 保留已存在的虚拟网络外网IP(云服务)
查看>>
修改字符集
查看>>
HackTheGame 攻略 - 第四关
查看>>
js删除数组元素
查看>>
带空格文件名的处理(find xargs grep ..etc)
查看>>
华为Access、Hybrid和Trunk的区别和设置
查看>>
centos使用docker下安装mysql并配置、nginx
查看>>
关于HTML5的理解
查看>>
需要学的东西
查看>>
Internet Message Access Protocol --- IMAP协议
查看>>
Linux 获取文件夹下的所有文件
查看>>
对 Sea.js 进行配置(一) seajs.config
查看>>
第六周
查看>>
解释一下 P/NP/NP-Complete/NP-Hard 等问题
查看>>
javafx for android or ios ?
查看>>
微软职位内部推荐-Senior Software Engineer II-Sharepoint
查看>>
sql 字符串操作
查看>>