栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java基础复习(二)(准备大数据开发面试)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java基础复习(二)(准备大数据开发面试)

常见面试题来自牛客网:https://www.nowcoder.com/tutorial/94/4206176d637541fa92c784a4f547e979

一、前言

这个专栏是Java基础复习,将记录我准备大数据开发面试的过程,在校招面试中占了比较大的部分。希望自己现在夯实基础,笑着面对接下来的校招。那么现在开始行动起来吧!

二、常见题

1.String和StringBuffer有什么区别?
不同点:
(一)String类不可变,有"final"修饰符,规定了String类是不能被继承的,而且我们可以看到,char value[]也是final修饰,这说明一旦String对象建立,char数组的长度就等于字符串的长度,且数组长度一旦固定,就没有办法扩容,所以String类不可变。下面是String部分源码

public final class String
    implements java.io.Serializable, Comparable, CharSequence {
    
    private final char value[];

    
    private int hash; // Default to 0

    
    private static final long serialVersionUID = -6849794470754667710L;
    ...
    ...
    }

StringBuffer类可变,下面是StringBuffer部分源码

public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{

    
    private transient char[] toStringCache;

    
    static final long serialVersionUID = 3388685877147921107L;
    ...
    ...
}

(二)安全角度:String和StringBuffer是线程安全的,StringBuilder线程不安全
StringBuffer是线程安全的

	@Override
    public synchronized StringBuffer append(String str) {
        toStringCache = null;
        super.append(str);
        return this;
    }
    @Override
    public synchronized StringBuffer delete(int start, int end) {
        toStringCache = null;
        super.delete(start, end);
        return this;
    }

StringBuilder线程不安全

	@Override
    public StringBuilder append(String str) {
        super.append(str);
        return this;
    }
    @Override
    public StringBuilder delete(int start, int end) {
        super.delete(start, end);
        return this;
    }
    ...
    ...

可以很明显的看出,两者的差异在于有没有加同步锁

(三)效率角度:
StringBuffer是线程安全的,也就是多线程修改同一个StringBuffer对象的时候,过程是同步的,当然这就导致了StringBuffer的效率降低,毕竟如果要提升安全性,就必须要损失一定的效率。

StringBuilder是jdk1.5后新增的,主要就是为了提升单线程下StringBuffer的效率问题,因为StringBuilder没有了同步操作,所以效率提升了。

从执行效率快慢来看
String < StringBuffer < StringBuilder,
但是存在一种特殊情况,就是当String全是字面量相加的时候,这种情况会很快,因为字面量在编译期时,编译器会优化处理,将字面量全部合成一个字面量然后扔进方法区的常量池中,所以运行时当在执行S1指向的时候,这个对象就已经存在与常量池中了,不需要计算了。而StringBuffer 则需要在运行时进行append操作,所以这就造成了这种假象。

//String效率在这种场景下,是远要比StringBuffer快的:
        String S1 = "This is a" + " simple" + "test";
        StringBuffer Sb = new StringBuffer("This is a").append("simple").append("test");
    

但是,修改一下,把上面代码换成下面代码,String的执行效率就低了很多,因为运行时需要重新创建一个对象,将S2,S3 ,S4的值相加后再复制给这个新对象,S1再重新指向这个新对象。

//此时String速度是非常慢的:
String S2 = “This is a”;
String S3 = “ simple”;
String S4 = “ test”;
String S1 = S2 +S3 + S4;
StringBuffer Sb = new StringBuffer("This is a").append("simple").append("test");

2.’=='和equals区别?

简单来说, == 是比较内存地址是否相同,equals针对的是引用数据类型,比较内存地址上面的值是否相同(equals在不同的使用场景下,经常被重写)。基本数据类型无equals方法。

下面用代码通俗易懂的解释这个道理:

public class IntegerTest {
    public static void main(String[] args) {
		Integer aaa=new Integer(5);
        Integer bbb=new Integer(5);

        //由于Integer变量实际是对一个Integer对象的引用,所以两个通过new生成的Integer变量永远不==(因为其内存地址不同)
        System.out.println(aaa==bbb);//false
        //比较的是值,所以相等
        System.out.println(aaa.equals(bbb));//true

        int a=10;
        int b=10;
        System.out.println(a==b);//true

        String str1=new String("justice");
        String str2=new String("justice");

        System.out.println(str1==str2);//false
        System.out.println(str1.equals(str2));//true

        String str3;
        str3=str1;

        System.out.println(str1==str3);//true
        System.out.println(str1.equals(str3));//true
     }
}

aaa、bbb是两个new出来的Integer变量,内存地址永远不同,所以==结果不同,但值相同;

a和b都是基本数据类型,变量存储值,所以为==结果为true

str1和str2都是String类型,属于引用类型,变量存储地址,所以==为false,equals为true

由于str3指向str1,所以两者内存地址相同,值也相同

以下是equals的源码:

public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/678024.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号