题目 1:JVM 整体结构是什么样的?

题目 2:JVM 运行时数据区描述下?

运行时数据区域被划分为 5 个主要组件:
方法区(Method Area)
所有类级别数据将被存储在这里,包括静态变量。每个 JVM 只有一个方法区,它是一个共享的资源。
堆区(Heap Area)
所有的对象和它们相应的实例变量以及数组将被存储在这里。每个 JVM 同样只有一个堆区。由于方法区和堆区的内存由多个线程共享,所以存储的数据不是线程安全的。
栈区(Stack Area)
对每个线程会单独创建一个运行时栈。对每个函数呼叫会在栈内存生成一个栈帧(Stack Frame)。所有的局部变量将在栈内存中创建。栈区是线程安全的,因为它不是一个共享资源。栈帧被分为三个子实体:
- 局部变量数组 – 包含多少个与方法相关的局部变量并且相应的值将被存储在这里。
- 操作数栈 – 如果需要执行任何中间操作,操作数栈作为运行时工作区去执行指令。
- 帧数据 – 方法的所有符号都保存在这里。在任意异常的情况下,catch 块的信息将会被保存在帧数据里面。
PC 寄存器
每个线程都有一个单独的 PC 寄存器来保存当前执行指令的地址,一旦该指令被执行,pc 寄存器会被更新至下条指令的地址。
本地方法栈
本地方法栈保存本地方法信息。对每一个线程,将创建一个单独的本地方法栈。
题目 3:Object 类有哪些方法?
Clone、equals、 hashcode、wait、notify、notifyall、finalize、toString、getClass
题目 4:静态变量与实例变量区别?
• 静态变量: 静态变量由于不属于任何实例对象,属于类的,所以在内存中只会有一份,在类的 加载过程中,JVM 只为静态变量分配一次内存空间。
• 实例变量: 每次创建对象,都会为每个对象分配成员变量内存空间,实例变量是属于实例对象 的,在内存中,创建几次对象,就有几份成员变量。
题目 5:String 类的常用方法有哪些?
• indexof(); 返回指定字符的的索引。
• charAt(); 返回指定索引处的字符。
• replace(); 字符串替换。
• trim(); 去除字符串两端空格。
• split();字符串分割,返回分割后的字符串数组。
• getBytes();返回字符串 byte 类型数组。
• length();返回字符串长度。
• toLowerCase(); 将字符串转换为小写字母。 •toUpperCase();将字符串转换为大写字母。
• substring(); 字符串截取。
• equals(); 比较字符串是否相等。
题目 6:数组有没有 length()方法?String 有没有 length()方法?
数组没有 length()方法,有 length 的属性。String 有 length()方法。JavaScript 中,获得字符串的长度是通过 length 属性得到的,这一点容易和 Java 混淆
题目 7:String、StringBuffer、StringBuilder 的区别?
第一点: 可变和适用范围。String 对象是不可变的,而 StringBuffer 和 StringBuilder
是可变字符序列。每次对 String 的操作相当于生成一个新的 String 对象,而对StringBuffer 和 StringBuilder 的操作是对对象本身的操作,而不会生成新的对象,所以对于频繁改变内容的字符串避免使用 String,因为频繁的生成对象将会对系统性能产生影响。
第二点: 线程安全。String 由于有 final 修饰,是 immutable 的,安全性是简单而纯粹的。StringBuilder 和 StringBuffer 的区别在于 StringBuilder 不保证同步,也就是说如果需要线程安全需要使StringBuffer,不需要同步的 StringBuilder 效率更高。
总结:
- 操作少量的数据 = String
- 单线程操作字符串缓冲区下操作大量数据 = StringBuilder
- 多线程操作字符串缓冲区下操作大量数据 = StringBuffer
题目 8:String str = “i” 和 String str = new String(“1”)一样吗?
不一样,因为内存的分配方式不一样。String str = “i”的方式 JVM 会将其分配到常量池中,此时仅产生一个字符串对象。 String str = new String(“i”),JVM 会先在堆内存分配一个 String 对象,然后该对象指向常量池的字符串常量对象,如果字符串之前不存在,相当于创建了 2 个对象。
题目 9:String s=new String(“xyz”);创建了几个字符串对象?
两个对象,一个是静态存储区的“xyz”,一个是用 new 创建在堆上的对象。
题目 10:基本数据类型,int 初始值,integer 初始值
八种基本数据类型,int 初始 0,integer 初始 null
题目 11:字符串操作:如何实现字符串的反转及替换?
可用字符串构造 StringBuffer 对象,然后调用 StringBuffer 中的 reverse 方法即可实现字符串的反转,调用 replace 方法即可实现字符串的替换。
题目 12:Java 中怎样将 bytes 转换为 long 类型?
String 接收 bytes 的构造器转成 String,再 Long.parseLong
题目 13:float f=3.4;是否正确?
不正确。3.4 是双精度数,将双精度型(double)赋值给浮点型(float)属于下转型(downcasting,也称为窄化)会造成精度损失,因此需要强制类型转换 float f=(float)3.4; 或者写 成 float f =3.4F;。
题目 14:a = a + b 与 a += b 的区别?
+= 隐式的将加操作的结果类型强制转换为持有结果的类型。如果两这个整型相加,如 byte、short 或者 int,首先会将它们提升到 int 类型,然后在执行加法操作。
byte a = 127;
byte b = 127;
b = a + b; // 错误 : cannot convert from int to byte
b += a; // 争取
(因为 a+b 操作会将 a、b 提升为 int 类型,所以将 int 类型赋值给 byte 就会编译出错)
题目 15:short s1 = 1; s1 = s1 + 1;有错吗?short s1 = 1; s1+= 1;有错吗?
对于 short s1 = 1; s1 = s1 + 1;由于 1 是 int 类型,因此 s1+1 运算结果也是 int 型,需要强制转换类型才能赋值给 short 型。而 short s1 = 1; s1+= 1;可以正确编译,因为 s1+= 1;相当于 s1 = (short)(s1 + 1);其中有隐含的强制类型转换。
题目 16:Java 中应该使用什么数据类型来计算价格?
如果不是特别关心内存和性能的话,使用BigDecimal,否则使用预定义精度的 double类型
题目 17:==与 equals 的区别?
区别 1. ==是一个运算符 equals 是 Object 类的方法
区别 2. 比较时的区别
- 用于基本类型的变量比较时: ==用于比较值是否相等,equals 不能直接用于基本数据类型的比较,需要转换为其对应的包装类型。
- 用于引用类型的比较时。==和 equals 都是比较栈内存中的地址是否相等 。相等为 true 否则为 false。但是通常会重写 equals 方法去实现对象内容的比较。
题目 18:接口和抽象类的区别是什么?
抽象类可以提供成员方法的实现细节,而接口中只能存在 public abstract 方法;
抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的;
接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;
一个类只能继承一个抽象类,而一个类却可以实现多个接口。
题目 19:Java 中的值传递和引用传递?
值传递
在方法的调用过程中,实参把它的实际值传递给形参,此传递过程就是将实参的值复制一份传递到函数中,这样如果在函数中对该值(形参的值)进行了操作将不会影响实参的值。 因为是直接复制,所以这种方式在传递大量数据时,运行效率会特别低下。
引用传递
引用传递弥补了值传递的不足,如果传递的数据量很大,直接复过去的话,会占用大量的内存空间,而引用传递就是将对象的地址值传递过去,函数接收的是原始值的首地址值。
在方法的执行过程中,形参和实参的内容相同,指向同一块内存地址,也就是说操作的其实都是源数据,所以方法的执行将会影响到实际对象
结论:
基本数据类型传值,对形参的修改不会影响实参;
引用类型传引用,形参和实参指向同一个内存地址(同一个对象),所以对参数的修改会影响到实际的对象。String, Integer, Double 等 immutable 的类型特殊处理,可以理解为传值,最后的操作不会修改实参对象
题目 20:sleep 和 wait 的区别?
sleep 是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用 sleep 不会释放对象锁。
wait 是 Object 类的方法,对此对象调用 wait 方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出 notify 方法(或 notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/275077.html