面试题解(Day01)

今天在上课期间,有几个同学在问我一些面试题的问题,仔细看过题目之后,感觉题目还有点意思,考察的方面还是比较细节的,所以在给他们解释之后,自己回头还看了看,觉得可以写出一份博客来记录。

第一道题目是这样的:

1.Java工具类Arrays.asList()方法把数组转换成集合时,对该集合进行以下函数操作会出现错误的是()

A. size

B. add

C. remove

D. clear
这道题我第一眼看到的时候是有点疑惑的,我感觉他就是个集合的问题,在底层源码里面它应该是有这几种方法的,所以我给他们说的是应该这些方法都能够使用,但是当我自己阅读过源码之后,我发现我错了,我不仅错了而且错的很离谱。我忽略了对于底层源码的了解。
所以,我把我犯的错总结一下,写成博客的形式,希望我的拙见可以被大家认可。
解析过程是这样的:我写一个程序,给大家仔细说一下这个题目。
在里面使用的方法有:

Java.util下的一个工具类,它有一个方法叫做asList
asList的作用,就是将你传进来的一个数组,帮你变成一个集合,
数组是如何传的呢,它其实是利用一个动态列表的形式。
返回值是一个list集合,集合是可以泛型的,这里我们泛型的是String


import java.util.Arrays;
import java.util.List;

public class Test01 {
    public static void main(String[] args) {

        List<String>  list = Arrays.asList("a","b","c","d");
        System.out.println(list.size());
 
//        list.add("Z");
//        list.remove("a");
//        list.clear();

    }

}

当程序执行的时候,当执行第一个输出语句,即 System.out.println(list.size());语句的时候,它会正确输出list中的长度,程序运行结果是,4。这个是没有问题的。这个方法是可以使用的。
但是,当我们使用下面的方法的时候,比如我们使用add这个方法的时候,它就会出现异常,异常结果是:UnsupportedOperationException,另外,使用下面的remove,clear方法的时候也是会出现异常,而且异常还是和add的异常一样,都是UnsupportedOperationException。至于为什么会出现这样的问题,我们就需要对底层源码进行剖析。
打开asList,方法是这样的,如果你传过来的是个数组,这个数组我就给你拿过来给你构建一个集合,看起来好像是new了一个集合,但这个集合是不是我们用到的呢,答案是非也,当你点进去看这个集合,
在这里插入图片描述,点击这个ArrayList集合,前面没有修饰符,继续往上查看,会看到这个,在这里插入图片描述
,也就是说,它是自己定义了一个内部类,私有的静态内部类,它也叫做arrayList,但它不是我们使用的在java.util下的那个,所以它其实就是一个自己的一个集合,在这个集合当中,只提供了size方法,还有诸如toArray,还有get,set方法,indexof,contains,等等方法当我们仔细阅读完源码之后,我们会发现,它当中没有给我们提供add,remove和clear等等一些我们常用的方法。所以说,它看起来是个集合,但不是我们常用的那个。
考察点:考察是否对底层原理的理解。
个人感觉:这道题目就是考察我们对于底层原理的理解能力,考察的较为细节。

第二道题目是这样的:

2.一道关于String底层的问题的+拼接以及==和equals的考察问题。
相信很多人都接触过Java,而且对于Java也能较为熟练的掌握,但是,当你问他这几个的区别和联系的时候,他也有可能答不上来,这里我就举一个简单的例子来解释一下,仅代表个人拙见。

曾经有一个不是我同专业的女孩子问过我这个问题,但是当初的我没好好给她解释这个问题,现在想想,真的是,哎。好了,不说闲言了,上题目:


public class Test02 {
    public static void main(String[] args) {
        String A = "aaa";
        String B = "aaa";
        String C = A+B;
        String D = "aaa"+"aaa";
        System.out.println(C==D);//false
        System.out.println(C.equals(D));//true
    }
}

这道题其实并不难,我们先来说说这道题的结果是什么?第一个C==D的结果应该是false,第二个.equals(D)的结果是true。到这里就会有同学好奇了,说为什么是这样的呢,如果有一点基础的同学应该知道,这里的这个aaa是一个常量,也就是我们常说的常量对象,它储存的位置是我们的字符串常量区当中,常量对象在编译加载的时候只有一份。在这里的意思就是,这里的A和B这两个String型的变量的空间指向的是同一个常量对象aaa,C在这里呢它是等于A+B的,大家知道,这里的+底层所做的事情是什么呢,它其实做的是一个关于StringBuilder的拼接,(这里不懂String的同学可以稍候一下,过些天我把StringBuffer,StringBuilder的联系和区别总结一下发出来),其实就是产生了一个StringBuilder的对象,它把A先放进,然后再把B通过append再放入,它是变完之后再变成toString再变回来,所以它底层就是做了一个StringBuilder的拼接过程,现在这里的两个aaa想加之后,它在底层就不是使用的StringBuilder的拼接,这里的aaa就是直接拼接起来,在编译的时候,你会发现。它的底层是不同的,打开class字节码文件,在这里插入图片描述
你会发现,这里的String D = “aaaaaa”;是和我们源码是不一样的,这里的D是直接把两个aaa拼接在了一起,按照我的理解是,就是它直接将我们这个D变成了一个字符串常量对象,所以这里这个常量字符串对象,我们当然是储存在我们的字符串常量区当中。而C呢就是产生了一个新的StringBuilder的对象,再通过toString再变回来,所以C和D就肯定不是一个对象。所以这样的情况下,你去使用 ==号去比较的时候,两个对象的内存地址是不相同的,所以它的结果就是false。但是,如果是.equals()呢,它比较的是一个值,就是将一个值循环的方式一个一个进行比较的,所以它最后的结果就是true。
再补充一点,在String类里面提供了一个方法,叫做concat()方法,该方法用于讲两个字符串拼接为同一个字符串,与+连接符类似。

		String A = "aaa";
        String B = "aaa";
        String C = A.concat(B);
        System.out.println(C);

个人感觉:考察的不仅有String类的问题,还有jvm的字符常量池的问题

  • 12
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
1. 什么是Git?它有什么优点? Git是一款版本控制系统,它可以记录代码的历史变化,便于多人协作开发和管理代码。它的优点包括: - 分布式管理:每个开发者都可以拥有一份完整的代码仓库,不需要依赖中央服务器。 - 强大的分支和合并功能:可以轻松地创建和合并分支,便于团队协作和版本管理。 - 快速轻便:Git采用了一些高效的算法和数据结构,使得它的速度非常快。 - 安全性高:Git使用SHA-1算法来保证代码的完整性和安全性。 2. Git的三个区域分别是什么? Git的三个区域分别是工作区、暂存区和版本库。 - 工作区:保存了实际的文件,也就是我们编辑的文件。 - 暂存区:保存了即将提交到版本库的文件,也就是我们通过`git add`命令添加的文件。 - 版本库:保存了所有的提交历史和代码版本,也就是我们通过`git commit`命令提交到Git的代码仓库。 3. 如何创建一个新的分支并切换到这个分支? 可以使用`git branch`命令创建新分支,然后使用`git checkout`命令切换到新分支: ``` $ git branch new_branch # 创建新分支 $ git checkout new_branch # 切换到新分支 ``` 也可以使用`git checkout`命令的`-b`选项,一步完成创建和切换: ``` $ git checkout -b new_branch # 创建新分支并切换到新分支 ``` 4. 如何合并两个分支? 可以使用`git merge`命令合并两个分支: ``` $ git checkout master # 切换到要合并的分支(通常是主分支) $ git merge feature_branch # 合并另一个分支 ``` 在合并过程中,Git会自动检测两个分支的差异,并尝试自动合并代码。如果合并过程中发生冲突,需要手动决冲突,然后再次执行`git merge`命令。 5. 如何撤销上一次提交? 可以使用`git revert`命令撤销上一次提交: ``` $ git revert HEAD # 撤销上一次提交 ``` 这会创建一个新的提交,用于撤销上一次提交的变更。如果需要撤销多个提交,可以使用`git revert`命令的`-n`选项,指定要撤销的提交数量。 6. 如何回退到某个提交? 可以使用`git reset`命令回退到某个提交: ``` $ git reset --hard commit_id # 回退到指定的提交 ``` 这会将当前分支回退到指定的提交,并重写工作区和暂存区的内容。这会丢失当前提交之后的所有提交记录,谨慎使用。 7. 如何查看提交历史? 可以使用`git log`命令查看提交历史: ``` $ git log # 查看提交历史 ``` 这会列出所有提交的记录,包括提交的哈希值、作者、时间、提交消息等信息。可以使用`--pretty`选项指定输出格式。 8. 如何查看文件的差异? 可以使用`git diff`命令查看文件的差异: ``` $ git diff file_path # 查看工作区与当前版本库的差异 $ git diff commit_a..commit_b file_path # 查看两个提交之间的差异 ``` 这会输出文件的变更内容,包括添加、修改、删除等操作。如果需要查看某个文件的历史变更记录,可以使用`git log`命令的`--follow`选项。 9. 如何从远程仓库拉取代码? 可以使用`git pull`命令从远程仓库拉取代码: ``` $ git pull origin master # 从远程仓库的主分支拉取代码 ``` 这会将远程仓库的代码拉取到本地,并自动合并到当前分支。如果需要从其他分支拉取代码,可以修改`origin master`为相应的分支名称。 10. 如何推送代码到远程仓库? 可以使用`git push`命令将代码推送到远程仓库: ``` $ git push origin master # 将代码推送到远程仓库的主分支 ``` 这会将当前分支的代码推送到远程仓库,并更新远程仓库的代码。如果需要推送到其他分支,可以修改`origin master`为相应的分支名称。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值