31个JAVA初学者遇到的灵魂问题,你都入坑了吗?【附答案】_大学生在学习java的常见问题

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

答:在Java中这两种用法都是合法的,他们的作用都是一样的。前者是在C中的定义数组的方法。后者是JAVA推荐的方法,因为它的写法int更能表明这是一个int的数组。

问题8:为什么数组下标从0开始而不是从1开始?

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

问题9:如果我用负数作为数组下标会发生什么事?

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

问题10:使用数组时还有其他需要注意的陷阱吗?

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

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

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

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETkDnl5vogIzkuI3oqIDnrJHogIzkuI3or63nmoTmtYXkvKQ,size_11,color_FFFFFF,t_70,g_se,x_16

四、输入输出语句

问题12:我可以从标准input中重新读一次数据吗?

答:不可以,你只能读一次。

问题13:怎样输入end-of-file(eof)符号?

答:操作系统自动包括它了。

问题14:使用printf()时还有哪些用法?

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

问题15:行结束的符号是什么?

答:不同的文件系统使用了不同的符号。

在Unix系统上,新行的符号是"\n";

在Windows 系统上,每一行都有两个字符组成的字符串终结"\r\n" ;

在 Macs 系统上,终结符号是"\n\r"。

如果要打印行号,可以使System.outprintln(),或者使用下面的语句得到当前操作系统下的行结束符:

String NEWLINE=

System.getProperty("lineseparator");

问题16:下面两种写法,哪一种更有效率?

String s;

while(!StdIn.isEmpty){while(!StdInisEmpty()

}

s=StdIn.readStringO;

String s=StdIn.readString)

……}

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

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETkDnl5vogIzkuI3oqIDnrJHogIzkuI3or63nmoTmtYXkvKQ,size_11,color_FFFFFF,t_70,g_se,x_16

五、函数调用

问题17:当把数组当作函数调用时的参数时,我常常感到疑惑?

答:是的。你需要牢记传值参数(参数是基本变量类型)和传引用参数(比如数组)之间的区别。

问题18:那为什么不把所有的参数都使用传值的方式,包括对待数组?

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

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETkDnl5vogIzkuI3oqIDnrJHogIzkuI3or63nmoTmtYXkvKQ,size_10,color_FFFFFF,t_70,g_se,x_16

六、递归调用

问题19:有没有只能用循环而不能用递归的情况?

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

问题20:有没有只能用递归而不能用循环的情况?

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

问题21:那我应该选择哪个,递归的方式还是循环的方式?

答:根据代码的可读性和效率性之间做权衡。

问题22:我担心使用递归代码时的空间开销和重复计算(例如用递归解Fibonacci)的问题。有没有其他需要担心的?

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

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETkDnl5vogIzkuI3oqIDnrJHogIzkuI3or63nmoTmtYXkvKQ,size_11,color_FFFFFF,t_70,g_se,x_16

七、排序与查找

问题23:为什么我们要花大篇幅来证明一个程序是正确的?

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

问题24:在JAVA内建库中有没有排序和查找的函数?

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

问题25:为什么JAVA库不用随机pivot方式的快速排序?

答:好问题。因为某些程序员在调试代码时,可能需要确定性的代码实现。使用随机pivot违背了这个原则。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETkDnl5vogIzkuI3oqIDnrJHogIzkuI3or63nmoTmtYXkvKQ,size_11,color_FFFFFF,t_70,g_se,x_16

八、栈和队列

问题26:在Java库中有对stacks和queues的实现吗?

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

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

private Item[]a=newItem[max];

oldfirst=first;

答:不错的尝试。不幸的是,创建一个泛型数组在Java1.5里不支持。你可以使用cast,比如下面的写法:

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

根本的原因是JAVA中的数组是“协变的(covariant)”,但是泛型并不是。比如, String[]是Object[]的一种子类型,但是

Stack并不是Stack的一种子类型。许多程序员认为“协变的”数组是JAVA在数据类型方面的一个缺点。但是,如果我们不考虑泛型,“协变的”数组是有用的,比如实现

Arrays.sort(Comparable)方法,然后当参数是 String11时它也可以被正常调用。

问题28:可不可以在数组上使用foreach方式?

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

public static void main(String[args){ for (String s:args) 

StdOut.println(s);

问题29:在linkedlist上使用iterator是不是比循环或者递归更有效率?

答:编译器在翻译时,可能把那种“尾递归”形式翻译成等价的循环形式。所以可能并没有可以被观测到的性能提升。

[color-red]尾部递归是一种编程技巧。如果在递归函数中,递归调用返回的结果总被直接返回,则称为尾部递归。尾递归是极其重要的,不用屋递归,函数的堆栈耗用难以估量,需要保存很多中间函数的堆栈。比f(n,sum)=f(n-1)+

value(n)+sum;会保存n个函数调用堆栈,而使用尾递归f(n,sum)=f(n-1,sum+value(n));这样则只保留后一个函数堆栈即可,之前的可优化删去。

问题30:自动装箱机制会怎么处理下面的情况?

Integer a=null; 

int b=a;

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

问题31:为什么第一组打印的是true,但是后面两组打印的是false?

Integer al=100; Integera2=100;

Systemoutprintln(a1==a2); // true




![img](https://img-blog.csdnimg.cn/img_convert/2afcb5c08647f0663616779bfb8b53aa.png)
![img](https://img-blog.csdnimg.cn/img_convert/e33e72fd3798c730eca8d9c8e748aa84.png)

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618668825)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**



[外链图片转存中...(img-PJBklGmJ-1715678814475)]
[外链图片转存中...(img-lrehPr3A-1715678814475)]

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618668825)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 26
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值