皮皮网

【股票配置 源码】【spring源码网】【套料实例源码】string面试源码_java面试源码

2024-12-24 10:56:05 来源:lol信息爬虫源码

1.string?面试面试???Դ??
2.面试篇==和equals()区别、String线程安全问题(StringBuilder)
3.String,StringBuffer和StringBuilder的区别
4.stringbuffer与stringbuilder的区别?源码源码

string面试源码_java面试源码

string????Դ??

       关于String有没有长度限制的问题,我之前单独写过一篇文章分析过,面试面试最近我又抽空回顾了一下这个问题,源码源码发现又有了一些新的面试面试认识。于是源码源码股票配置 源码准备重新整理下这个内容。

       这次在之前那篇文章的面试面试基础上除了增加了一些验证过程外,还有些错误内容的源码源码修正。我这次在分析过程中会尝试对Jdk的面试面试编译过程进行debug,并且会参考一些JVM规范等全方面的源码源码介绍下这个知识点。

       想要搞清楚这个问题,面试面试首先我们需要翻阅一下String的源码源码源码,看下其中是面试面试否有关于长度的限制或者定义。

       String类中有很多重载的源码源码构造函数,其中有几个是面试面试支持用户传入length来执行长度的,但这里的spring源码网参数length是使用int类型定义的,这说明String定义的时候,最大支持的长度就是int的最大范围值,即2^ - 1。

       根据Integer类的定义,Java.lang.Integer#MAX_VALUE的最大值是2^ - 1;那么,我们是不是就可以认为String能支持的最大长度就是这个值了呢?其实并不是,这个值只是在运行期,我们构造String时可以支持的一个最大长度,而实际上,在运行期,定义字符串的时候也是有长度限制的。

       如以下代码:当我们使用如上形式定义一个字符串的时候,当我们执行javac编译时,是会抛出异常的,提示如下:那么,套料实例源码明明String的构造函数指定的长度是可以支持(2^ - 1)的,为什么像以上形式定义的时候无法编译呢?其实,形如String s = "xxx";定义String的时候,xxx被我们称之为字面量,这种字面量在编译之后会以常量的形式进入到Class常量池。那么问题就来了,因为要进入常量池,就要遵守常量池的有关规定。

       我们知道,javac是将Java文件编译成class文件的一个命令,那么在Class文件生成过程中,就需要遵守一定的格式。根据《Java虚拟机规范》中第4.4章节常量池的定义,CONSTANT_String_info 用于表示 java.lang.String 类型的常量对象,格式如下:其中,宝监工源码string_index 项的值必须是对常量池的有效索引,常量池在该索引处的项必须是 CONSTANT_Utf8_info 结构,表示一组 Unicode 码点序列,这组 Unicode 码点序列最终会被初始化为一个 String 对象。CONSTANT_Utf8_info 结构用于表示字符串常量的值,其中,length则指明了 bytes[]数组的长度,其类型为u2,即两个字节的无符号数。通过翻阅《规范》,我们可以获悉。u2表示两个字节的无符号数,那么1个字节有8位,2个字节就有位。位无符号数可表示的汇编转换+源码最大值位2^ - 1 = 。也就是说,Class文件中常量池的格式规定了,其字符串常量的长度不能超过。

       那么,我们尝试使用以下方式定义字符串:尝试使用javac编译,同样会得到"错误: 常量字符串过长",那么原因是什么呢?其实,这个原因在javac的代码中是可以找到的,在Gen类中有如下代码:代码中可以看出,当参数类型为String,并且长度大于等于的时候,就会导致编译失败。这个地方大家可以尝试着debug一下javac的编译过程(视频中有对java的编译过程进行debug的方法),也可以发现这个地方会报错。如果我们尝试以个字符定义字符串,则会发现可以正常编译。其实,关于这个值,在《Java虚拟机规范》也有过说明:if the Java Virtual Machine code for a method is exactly bytes long and ends with an instruction that is 1 byte long, then that instruction cannot be protected by an exception handler. A compiler writer can work around this bug by limiting the maximum size of the generated Java Virtual Machine code for any method, instance initialization method, or static initializer (the size of any code array) to bytes。

       上面提到的这种String长度的限制是编译期的限制,也就是使用String s= “”;这种字面值方式定义的时候才会有的限制。那么。String在运行期有没有限制呢,答案是有的,就是我们前文提到的那个Integer.MAX_VALUE ,这个值约等于4G,在运行期,如果String的长度超过这个范围,就可能会抛出异常。(在jdk 1.9之前)int 是一个 位变量类型,取正数部分来算的话,他们最长可以有近 4G 的容量。很多人会有疑惑,编译的时候最大长度都要求小于了,运行期怎么会出现大于的情况呢。这其实很常见,如以下代码:得到的字符串长度就有万,另外我之前在实际应用中遇到过这个问题。之前一次系统对接,需要传输高清,约定的传输方式是对方将转成BASE6编码,我们接收到之后再转成。在将BASE编码后的内容赋值给字符串的时候就抛了异常。

       总结来说,字符串有长度限制,在编译期,要求字符串常量池中的常量不能超过,并且在javac执行过程中控制了最大值为。在运行期,长度不能超过Int的范围,否则会抛异常。最后,这个知识点,我录制了视频,其中有关于如何进行实验测试、如何查阅Java规范以及如何对javac进行debug的技巧。欢迎进一步学习。

面试篇==和equals()区别、String线程安全问题(StringBuilder)

       equals(值相等) ==(引用相等)

       equals源代码中可以看到:

       JDK自带的equals有两种,针对Object对象及String对象

       1、String中的equals

       ==判断是否相等,相等直接返回true->再判断是否为string类型,否直接返回false->是则继续判断对象length->循环判断char是否相等(jdk8使用的是char,高版本的jdk已使用效率更高的byte)

       2、Object中的equals

       直接return (this == obj),一般业务对象比较要改造equals方法

       p.s.自定义对象需要重写equals

       二、String线程安全问题

       String中的对象是不可变的,也就可以理解为常量,线程安全。AbstractStringBuilder 是 StringBuilder 与 StringBuffer 的公共父类,定义了一些字符串的基本操作,如 expandCapacity、append、insert、indexOf 等公共方法。StringBuffer 对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。StringBuilder 并没有对方法进行加同步锁,所以是非线程安全的。

String,StringBuffer和StringBuilder的区别

       java中String、StringBuffer、StringBuilder是编程中经常使用的字符串类,他们之间的区别也是经常在面试中会问到的问题。现在总结一下,看看他们的不同与相同。

       1.可变与不可变

       ã€€ã€€String类中使用字符数组保存字符串,如下就是,因为有“final”修饰符,所以可以知道string对象是不可变的。

       ã€€ã€€ã€€ã€€private final char value[];

       ã€€ã€€StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串,如下就是,可知这两种对象都是可变的。

       ã€€ã€€ã€€ã€€char[] value;

       2.是否多线程安全

       ã€€ã€€String中的对象是不可变的,也就可以理解为常量,显然线程安全。

       ã€€ã€€AbstractStringBuilder是StringBuilder与StringBuffer的公共父类,定义了一些字符串的基本操作,如expandCapacity、append、insert、indexOf等公共方法。

       ã€€ã€€StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。看如下源码:

1 public synchronized StringBuffer reverse() {

       2     super.reverse();

       3     return this;

       4 }

       5 

       6 public int indexOf(String str) {

       7     return indexOf(str, 0);        //存在 public synchronized int indexOf(String str, int fromIndex) æ–¹æ³•

       8 }

       ã€€ã€€StringBuilder并没有对方法进行加同步锁,所以是非线程安全的。

        3.StringBuilder与StringBuffer共同点

       ã€€ã€€StringBuilder与StringBuffer有公共父类AbstractStringBuilder(抽象类)。

       ã€€ã€€æŠ½è±¡ç±»ä¸ŽæŽ¥å£çš„其中一个区别是:抽象类中可以定义一些子类的公共方法,子类只需要增加新的功能,不需要重复写已经存在的方法;而接口中只是对方法的申明和常量的定义。

       ã€€ã€€StringBuilder、StringBuffer的方法都会调用AbstractStringBuilder中的公共方法,如super.append(...)。只是StringBuffer会在方法上加synchronized关键字,进行同步。

       ã€€ã€€æœ€åŽï¼Œå¦‚果程序不是多线程的,那么使用StringBuilder效率高于StringBuffer。

stringbuffer与stringbuilder的区别?

       äºŒè€…的区别主要是在运行速度和线程安全这两方面。

       1、StringBuffer 与 StringBuilder 中的方法和功能完全是等价的

       2、只是StringBuffer 中的方法大都采用了 synchronized å…³é”®å­—进行修饰,因此是线程安全的,而 StringBuilder 没有这个修饰,可以被认为是线程不安全的。

       3、在单线程程序下,StringBuilder效率更快,因为它不需要加锁,不具备多线程安全而StringBuffer则每次都需要判断锁,效率相对更低。