没有合适的资源?快使用搜索试试~ 我知道了~
java面试题.doc
0 下载量 26 浏览量
2024-05-15
09:22:09
上传
评论
收藏 42KB DOC 举报
温馨提示
试读
11页
java面试题.doc
资源推荐
资源详情
资源评论
多线程、并发及线程的基础问题:
1)Java 中能创建 volatile 数组吗?
能,Java 中可以创建 volatile 类型数组,不过只是一个指向数组的引用,而不是整个数组。
我的意思是,如果改变引用指向的数组,将会受到 volatile 的保护,但是如果多个线程同
时改变数组的元素,volatile 标示符就不能起到之前的保护作用了。
2)volatile 能使得一个非原子操作变成原子操作吗?
一个典型的例子是在类中有一个 long 类型的成员变量。如果你知道该成员变量会被多个线
程访问,如计数器、价格等,你最好是将其设置为 volatile。为什么?因为 Java 中读取 long
类型变量不是原子的,需要分成两步,如果一个线程正在修改该 long 变量的值,另一个线
程可能只能看到该值的一半(前 32 位)。但是对一个 volatile 型的 long 或 double 变量
的读写是原子。
3)volatile 修饰符的有过什么实践?
一种实践是用 volatile 修饰 long 和 double 变量,使其能按原子类型来读写。double 和
long 都是 64 位宽,因此对这两种类型的读是分为两部分的,第一次读取第一个 32 位,
然后再读剩下的 32 位,这个过程不是原子的,但 Java 中 volatile 型的 long 或 double
变量的读写是原子的。volatile 修复符的另一个作用是提供内存屏障(memory barrier),例
如在分布式框架中的应用。简单的说,就是当你写一个 volatile 变量之前,Java 内存模型
会插入一个写屏障(write barrier),读一个 volatile 变量之前,会插入一个读屏障(read
barrier)。意思就是说,在你写一个 volatile 域时,能保证任何线程都能看到你写的值,同
时,在写之前,也能保证任何数值的更新对所有线程是可见的,因为内存屏障会将其他所有
写的值更新到缓存。
4)volatile 类型变量提供什么保证?
volatile 变量提供顺序和可见性保证,例如,JVM 或者 JIT 为了获得更好的性能会对语句
重排序,但是 volatile 类型变量即使在没有同步块的情况下赋值也不会与其他语句重排序。
volatile 提供 happens-before 的保证,确保一个线程的修改能对其他线程是可见的。某些
情况下,volatile 还能提供原子性,如读 64 位数据类型,像 long 和 double 都不是原子
的,但 volatile 类型的 double 和 long 就是原子的。
5)你是如何调用 wait()方法的?使用 if 块还是循环?为什么?
wait() 方法应该在循环调用,因为当线程获取到 CPU 开始执行的时候,其他条件可能还没
有满足,所以在处理前,循环检测条件是否满足会更好。下面是一段标准的使用 wait 和
notify 方法的代码:
// The standard idiom for using the wait method
synchronized (obj) {
while (condition does not hold)
obj.wait(); // (Releases lock, and reacquires on wakeup)
... // Perform action appropriate to condition
}
6)什么是多线程环境下的伪共享(false sharing)?
伪共享是多线程系统(每个处理器有自己的局部缓存)中一个众所周知的性能问题。伪共享
发生在不同处理器的上的线程对变量的修改依赖于相同的缓存行,如下图所示:
7)什么是 Busy spin?我们为什么要使用它?
Busy spin 是一种在不释放 CPU 的基础上等待事件的技术。它经常用于避免丢失 CPU 缓
存中的数据(如果线程先暂停,之后在其他 CPU 上运行就会丢失)。所以,如果你的工作
要求低延迟,并且你的线程目前没有任何顺序,这样你就可以通过循环检测队列中的新消息
来代替调用 sleep() 或 wait() 方法。它唯一的好处就是你只需等待很短的时间,如几微秒
或 几 纳 秒 。 LMAX 分 布 式 框 架 是 一 个 高 性 能 线 程 间 通 信 的 库 , 该 库 有 一 个
BusySpinWaitStrategy 类 就 是 基 于 这 个 概 念 实 现 的 , 使 用 busy spin 循 环
EventProcessors 等待屏障。
8)什么是线程局部变量?
线程局部变量是局限于线程内部的变量,属于线程自身所有,不在多个线程间共享。Java
提供 ThreadLocal 类来支持线程局部变量,是一种实现线程安全的方式。但是在管理环境
下(如 web 服务器)使用线程局部变量的时候要特别小心,在这种情况下,工作线程的生
命周期比任何应用变量的生命周期都要长。任何线程局部变量一旦在工作完成后没有释放,
Java 应用就存在内存泄露的风险。
9)Java 中 sleep 方法和 wait 方法的区别?
虽然两者都是用来暂停当前运行的线程,但是 sleep() 实际上只是短暂停顿,因为它不会
释放锁,而 wait() 意味着条件等待,这就是为什么该方法要释放锁,因为只有这样,其他
等待的线程才能在满足条件时获取到该锁。
10)什么是不可变对象(immutable object)?Java 中怎么创建一个不可变对象?
不可变对象指对象一旦被创建,状态就不能再改变。任何修改都会创建一个新的对象,如
String、Integer 及其它包装类。
11)我们能创建一个包含可变对象的不可变对象吗?
是的,我们是可以创建一个包含可变对象的不可变对象的,你只需要谨慎一点,不要共享可
变对象的引用就可以了,如果需要变化时,就返回原对象的一个拷贝。最常见的例子就是对
象中包含一个日期对象的引用。
数据类型和 Java 基础面试问题
12)Java 中应该使用什么数据类型来代表价格?
如果不是特别关心内存和性能的话,使用 BigDecimal,否则使用预定义精度的 double 类
型。
13)怎么将 byte 转换为 String?
可以使用 String 接收 byte[] 参数的构造器来进行转换,需要注意的点是要使用的正确的
编码,否则会使用平台默认编码,这个编码可能跟原来的编码相同,也可能不同。
14)我们能将 int 强制转换为 byte 类型的变量吗?如果该值大于 byte 类型的范围,将
会出现什么现象?
是的,我们可以做强制转换,但是 Java 中 int 是 32 位的,而 byte 是 8 位的,所以,
如果强制转化是,int 类型的高 24 位将会被丢弃,byte 类型的范围是从 -128 到 128。
15)Java 中 ++ 操作符是线程安全的吗?
不是线程安全的操作。它涉及到多个指令,如读取变量值,增加,然后存储回内存,这个过
程可能会出现多个线程交差。
16)a = a + b 与 a += b 的区别?
+= 隐式的将加操作的结果类型强制转换为持有结果的类型。如果两这个整型相加,如 byte、
short 或者 int,首先会将它们提升到 int 类型,然后在执行加法操作。如果加法操作的结
果比 a 的最大值要大,则 a+b 会出现编译错误,但是 a += b 没问题,如下:
byte a = 127;
byte b = 127;
b = a + b; // error : cannot convert from int to byte
b += a; // ok
剩余10页未读,继续阅读
资源评论
平头哥在等你
- 粉丝: 2
- 资源: 7332
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- python+Django+xadmin 人事信息管理系统
- Happy Children's Day
- Bandizip7.32 64位专业版
- 亚博智能k210开发板py版本拓展例程源码
- 数知识领域: GUI开发 技术关键词: Tkinter、PyQt、GUI编程、用户界面设计 内容关键词: 窗口、控件、事件处理
- 知识领域: 图像处理 技术关键词: OpenCV、图像处理、计算机视觉、图像识别 内容关键词: 图像读取、滤波、特征提取
- anaconda安装知识领域: 数据可视化 技术关键词: Matplotlib、Seaborn、数据可视化、图表绘制
- 计算机网络试题库含答案
- 基于springboot的音乐网站
- jsp码头船只出行及配套货柜码放管理系统的设计与实现
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功