java刷题(6)
1.Thread类的方法:
A. start() - 正确。这是Thread类的关键方法,用于启动一个新线程。调用start()方法后,JVM会调用该线程的run()方法。这个方法是实现多线程的标准方式。
B. run() - 正确。这是Thread类的方法,也是Runnable接口中定义的方法。Thread类实现了Runnable接口。run()方法包含线程要执行的代码。
C. exit() - 错误。Thread类中没有exit()方法。如果要终止线程,可以使用interrupt()方法或设置标志位等方式。
D. getPriority() - 正确。这是Thread类的方法,用于获取线程的优先级。线程优先级的范围是1-10,默认优先级是5。
补充说明:
Thread类还有许多其他重要方法,如:
- sleep() - 使当前线程暂停执行指定时间
- interrupt() - 中断线程
- join() - 等待线程终止
- yield() - 暂时让出CPU执行权给其他线程
Thread的几种常用方法_thread得方法-CSDN博客https://blog.csdn.net/csdn11235813/article/details/106127259
2.final方法
总结:final关键字的核心作用是实现"不可变性",但具体的"不可变"含义要根据修饰对象来具体分析:
- 修饰类:不能被继承
- 修饰方法:不能被重写
- 修饰变量:不能被再次赋值
3.contact方法
public class Test {public static void main(String[] args) {String str = "hello#123#456#world";int n = str.indexOf("#");int k = str.indexOf("#", n + 1);int j = str.lastIndexOf("#");String subStr = ___________; // 补充代码System.out.println(subStr);}
}
这道题目考察了Java中String类的substring()方法和indexOf()方法的使用。
让我们分析代码的执行过程:
1. 原字符串为"hello#123#456#world"
2. n = str.indexOf("#") 找到第一个#的位置,n=5
3. k = str.indexOf("#", n+1) 从第一个#后面开始找第二个#的位置,k=9
4. j = str.lastIndexOf("#") 找到最后一个#的位置,j=13
要获取"123",需要从第一个#后面(不包含#)截取到第二个#前面(不包含#),因此应该使用:
str.substring(n+1,k),即从位置6开始,到位置9结束(不包含位置9)。
分析各选项:
A正确:str.substring(n+1,k) 从第一个#后面开始(位置6),到第二个#前面结束(位置9),正好截取出"123"
B错误:str.substring(n,k) 会包含第一个#,会得到"#123"
C错误:str.substring(n,j) 会从第一个#开始截取到最后一个#,会得到"#123#456"
D错误:str.substring(k,j) 会从第二个#开始截取到最后一个#,会得到"#456"
substring方法的特点是包含起始位置,但不包含结束位置的字符。因此要获取两个#之间的内容,起始位置应该是第一个#的位置+1,结束位置是第二个#的位置。
4.protect权限
Java中访问权限从大到小依次为:public > protected > 包访问权限(默认) > private。protected权限允许不同包中的子类访问,而默认的包访问权限只允许同一包内的类访问,因此protected访问权限要大于包访问权限。
选项分析:
A错误:该说法与Java访问权限的实际情况相反,protected权限范围大于包访问权限。
B正确:protected权限允许:
1) 同一包内的其他类访问
2) 不同包中的子类访问
而包访问权限只允许同一包内的类访问,不允许其他包的类访问,因此protected的访问范围更大。
这是Java语言设计的基本特性,目的是为了支持继承和多态。protected关键字可以让子类在不同包中也能访问父类的方法和属性,这对于类的扩展和代码重用非常重要。而包访问权限的设计初衷是为了实现包内部的信息隐藏,限制包外的访问。
5.super用法:
官方解析:super关键字在Java中是一个非常重要的关键字,它具有多个重要作用,选项D是完全正确的。让我们逐个分析super的三个主要功能:
1. 访问父类被隐藏的非私有成员变量(选项A)
当子类中定义了与父类同名的成员变量时,子类的变量会隐藏父类的变量。这时如果要访问父类中被隐藏的变量,就需要使用super关键字。例如:
super.variableName 可以访问父类中的变量。
2. 调用父类中被重写的方法(选项B)
当子类重写了父类的方法时,如果需要在子类中调用父类被重写的方法,就需要使用super关键字。例如:
super.methodName() 可以调用父类中被重写的方法。
3. 调用父类的构造函数(选项C)
在子类的构造函数中,可以使用super()来调用父类的构造函数。这常用于初始化从父类继承的属性。如果不显式调用,编译器会自动插入super()调用父类的无参构造函数。
6.多线程和锁
由于锁住了increment所以线程是独有的
.t1.join()和t2.join()确保主线程在两个子线程都执行完成后才会打印结果
(处理结果为原子的)
如果没有join()
,主线程可能在两个子线程完成之前就继续执行,导致程序无法获得正确的结果。以下情况可能发生:
-
子线程尚未完成所有的
increment()
操作时,主线程已经打印了共享变量x
的值。这可能会导致x
的输出值小于预期的2,000,000。 -
输出结果可能不一致,因为程序的执行顺序在多线程环境下是无法预测的,这会导致结果根据子线程完成的进度有所不同。
-
甚至在某些情况下,结果可能完全错乱,尤其是在处理时间短、任务量大的场景下。
简单来说,join()
是确保主线程等待子线程完成后再执行的关键方法,否则就会出现不确定性和潜在错误。
6.重写与重载
多态分为编译时多态(重载)和运行时多态(重写)。重载是在同一个类中实现的静态多态,而重写则是在继承体系中实现的动态多态。
7.字符编码
1. GB2312是中文字符编码标准,可以表示汉字
2. 在GB2312编码中,一个汉字占用2个字节
3. Java中的char类型是16位的Unicode字符,可以存储一个汉字
4. 当源文件以GB2312编码存储时,编译器会正确识别'中'这个字符常量
5. 使用javac -encoding GB2312命令编译确保了编译器使用正确的编码方式读取源文件
- 如果不指定编译编码,默认使用操作系统的编码方式,可能会导致乱码
- 如果源文件编码与编译命令指定的编码不一致,也会导致乱码
- Java内部始终使用Unicode存储字符,编码方式只影响源文件的读取
8.JVM
http://www.cnblogs.com/sunada2005/p/3577799.html
【深入Java虚拟机】之一:Java内存区域与内存溢出_java内存溢出案例分析-CSDN博客
A正确:程序计数器(Program Counter Register)是线程私有的一块小内存区域,用于记录线程执行的字节码行号指示器。每条线程都需要一个独立的程序计数器来保证线程切换后能恢复到正确的执行位置。
B正确:虚拟机栈(VM Stack)是线程私有的,它的生命周期与线程相同。每个方法在执行时都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息。
D正确:Java堆(Heap)是所有线程共享的一块内存区域,几乎所有的对象实例都在这里分配内存。Java堆可以处于物理上不连续的内存空间,但在逻辑上它应该被视为连续的。
总的来说,JVM中线程隔离的区域包括程序计数器、虚拟机栈和本地方法栈,而线程共享的区域包括Java堆和方法区。
9.插入字符串
在Java中,所有选项A、B、C、D均可用于合并两个字符串,但适用场景和效率不同。以下是具体解析:
选项解析
- A.String.join()
• 正确。String.join()是Java 8引入的方法,支持通过分隔符合并多个字符串(包括两个)。例如:String result = String.join("", str1, str2); // 无分隔符合并
• 特点:简洁但需指定分隔符(即使为空)。 - B.String.concat()
• 正确。String类的concat()方法直接追加字符串:String result = str1.concat(str2); // 直接合并
• 特点:简单但效率低,频繁使用会导致大量临时对象。 - C.StringBuilder.append()
• 正确。StringBuilder通过append()高效拼接:StringBuilder sb = new StringBuilder();sb.append(str1).append(str2);String result = sb.toString();
• 特点:性能最优,适合高频拼接场景。 - D.StringBuffer.insert()
• 正确。StringBuffer的insert()方法可在指定位置插入字符串:StringBuffer sb = new StringBuffer(str1);sb.insert(str1.length(), str2); // 在末尾插入
• 特点:线程安全但性能略低于StringBuilder。
性能与适用场景对比
方法 | 线程安全 | 性能 | 适用场景 |
---|---|---|---|
String.join() | 是(底层同步) | 中 | 需分隔符的少量字符串合并 |
String.concat() | 否 | 低 | 简单的两字符串合并 |
StringBuilder | 否 | 高 | 高频拼接(如循环中) |
StringBuffer | 是 | 中 | 多线程环境下的高频拼接 |
总结
• 推荐选项:
•StringBuilder.append()(C):性能最佳,通用性强。
•String.join()(A):适合需要分隔符的场景。
• 慎用选项:
•String.concat()(B):仅适合极简单场景。
•StringBuffer.insert()(D):需明确插入位置,灵活性较低。