Java面试题含答案,最新面试题(1)

news2024/9/27 9:22:59

Java 中 InvokeDynamic指令是干什么的?

JVM字节码指令集一直比较稳定,一直到Java7中才增加了一个InvokeDynamic 指令,这是JAVA为了实现『动态类型语言』支持而做的一种改进;但是在Java7中并没有提供直接生成InvokeDynamic 指令的方法,需要借助ASM这种底层字节码工具来产生InvokeDynamic 指令;

而到了Java 8中,InvokeDynamic 则成为了实现高级平台特性的一个首要机制;

使用这个操作码的最明确、简单的例子便是lambda表达式;

Java 中 编写多线程程序的时候你会遵循哪些最佳实践?

这是我在写Java并发程序的时候遵循的一些最佳实践:

1、 给线程命名,这样可以帮助调试;
2、 最小化同步的范围,而不是将整个方法同步,只对关键部分做同步;
3、 如果可以,更偏向于使用 volatile 而不是 synchronized;
4、 使用更高层次的并发工具,而不是使用 wait() 和 notify() 来实现线程间通信,如 BlockingQueue,CountDownLatch 及 Semeaphore;
5、 优先使用并发集合,而不是对集合进行同步;并发集合提供更好的可扩展性;

Java 中 32 位 和 64 位 JVM 中,int 的长度是多数?

1、 理论上说上 32 位的 JVM 堆内存可以到达 2^32,即 4GB,但实际上会比这个小很多;
2、 不同操作系统之间不同,如 Windows 系统大约 1.5 GB,Solaris 大约 3GB;
3、 64 位 JVM允许指定最大的堆内存,理论上可以达到 2^64,这是一个非常大的数字,实际上你可以指定堆内存大小到 100GB;
4、 甚至有的 JVM,如 Azul,堆内存到 1000G 都是可能的;
5、 32 位和 64 位的 JVM 中,int 类型变量的长度是相同的,都是 32 位或者 4 个字节(一个字节8位);
5、 Java 中,int 类型变量的长度是一个固定值,与平台无关,都是 32 位;

意思就是说,在 32 位 和 64 位 的Java 虚拟机中,int 类型的长度是相同的;

Java 中 指出下面程序的运行结果?

class A {
    static {
        System.out.print("1");
    }
    public A() {
        System.out.print("2");
    }
}
class B extends A{
    static {
        System.out.print("a");
    }
    public B() {
        System.out.print("b");
    }
}
public class Hello {
    public static void main(String[] args) {
        A ab = new B();
        ab = new B();
    }
}

执行结果:1a2b2b;

创建对象时构造器的调用顺序是:

先初始化静态成员,然后调用父类构造器,再初始化非静态成员,最后调用自身构造器;

Java 中 我们开发过程中常用包有那些?

软件开发与应用中经常需要用到,其中有些包是必要的,若是离开它,还真不能做事情了;

1、java.lang包

该包提供了Java语言进行程序设计的基础类,它是默认导入的包;该包里面的Runnable接口和Object、Math、String、StringBuffer、System、Thread以及Throwable类需要重点掌握,因为它们应用很广;

2、java.util包

该包提供了包含集合框架、遗留的集合类、事件模型、日期和时间实施、国际化和各种实用工具类(字符串标记生成器、随机数生成器和位数组);

3、java.io包

该包通过文件系统、数据流和序列化提供系统的输入与输出;

4、java.net包

该包提供实现网络应用与开发的类;

5、java.sql包

该包提供了使用Java语言访问并处理存储在数据源(通常是一个关系型数据库)中的数据API;

6、java.awt包

AWT是用于创建用户图形界面的一个工具包,提供了一系列用于实现图形界面的组件,如窗口、按钮、文本框、对话框等,在JDK中针对每个组件都提供对应的Java类;

7、javax.swing包

这两个包提供了GUI设计与开发的类;java.awt包提供了创建界面和绘制图形图像的所有类,而javax.swing包提供了一组“轻量级”的组件,尽量让这些组件在所有平台上的工作方式相同;

8、java.text包

提供了与自然语言无关的方式来处理文本、日期、数字和消息的类和接口;

关于上述这些包结构,除了第一个包是自动导入外,其余的包都需要使用import语句导入,才可使用其包里面的类与接口;若想深入了解它们,请多阅读JDKAPI文档,同时,多使用这些包里的类与接口来解决问题和满足需求;

Java 中 Math.round(11.5) 等于多少?Math.round(-11.5)等于多少?

Math.round(11.5)的返回值是12,Math.round(-11.5)的返回值是-11;

四舍五入的原理是在参数上加0.5然后进行下取整;

Java 中 抽象类可以使用final修饰吗?

不能

定义抽象类就是让其他类继承的,如果定义为 final 该类就不能被继承,这样彼此就会产生矛盾,所以 final 不能修饰抽象类;

可以自己试试,一般的编译器也会提示错误的;

Java 中 你是如何调用 wait() 方法的?使用 if 块还是循环?为什么?

处于等待状态的线程可能会收到错误警报和伪唤醒,如果不在循环中检查等待条件,程序就会在没有满足结束条件的情况下退出;

wait() 方法应该在循环调用,因为当线程获取到 CPU 开始执行的时候,其他条件可能还没有满足,所以在处理前,循环检测条件是否满足会更好;下面是一段标准的使用 wait 和 notify 方法的代码;

synchronized (monitor) {
    //  判断条件谓词是否得到满足
    while(!locked) {
    //  等待唤醒
    monitor.wait();
    }
    //  处理其他的业务逻辑
}

Java 中 对象的内存布局了解吗?

Java 中通过 new 关键字创建一个类的实例对象,对象存于内存的堆中并给其分配一个内存地址,那么是否想过如下这些问题:

1、 这个实例对象是以怎样的形态存在内存中的?
2、 一个Object对象在内存中占用多大?
3、 对象中的属性是如何在内存中分配的?

在 JVM 中,Java对象保存在堆中时,由以下三部分组成:

1、 对象头(object header) : 包括了关于堆对象的布局、类型、GC状态、同步状态和标识哈希码的基本信息;Java对象和vm内部对象都有一个共同的对象头格式;
2、 实例数据(Instance Data) :主要是存放类的数据信息,父类的信息,对象字段属性信息;
3、 对齐填充(Padding) :为了字节对齐,填充的数据,不是必须的;

如果对象是一个Java数组,那在对象头中还必须有一块用于记录数组长度的数据,因为虚拟机可以通过普通Java对象的元数据信息确定Java对象的大小,但是从数组的元数据中无法确定数组的大小;

Mark Word

用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等等;

Mark Word在32位JVM中的长度是32bit,在64位JVM中长度是64bit;我们打开openjdk的源码包,对应路径/openjdk/hotspot/src/share/vm/oops,Mark Word对应到C++的代码markOop.hpp,可以从注释中看到它们的组成,本文所有代码是基于Jdk1.8;

Mark Word在不同的锁状态下存储的内容不同;

在32位JVM中是这么存的

在64位JVM中是这么存的

虽然它们在不同位数的JVM中长度不一样,但是基本组成内容是一致的;

锁标志位(lock):区分锁状态,11时表示对象待GC回收状态, 只有最后2位锁标识(11)有效;
biased_lock:是否偏向锁,由于无锁和偏向锁的锁标识都是 01,没办法区分,这里引入一位的偏向锁标识位;
分代年龄(age):表示对象被GC的次数,当该次数到达阈值的时候,对象就会转移到老年代;
对象的hashcode(hash):运行期间调用System.identityHashCode()来计算,延迟计算,并把结果赋值到这里;当对象加锁后,计算的结果31位不够表示,在偏向锁,轻量锁,重量锁,hashcode会被转移到Monitor中;
偏向锁的线程ID(JavaThread):偏向模式的时候,当某个线程持有对象的时候,对象这里就会被置为该线程的ID; 在后面的操作中,就无需再进行尝试获取锁的动作;
epoch:偏向锁在CAS锁操作过程中,偏向性标识,表示对象更偏向哪个锁;
ptr_to_lock_record:轻量级锁状态下,指向栈中锁记录的指针;当锁获取是无竞争的时,JVM使用原子操作而不是OS互斥;这种技术称为轻量级锁定;在轻量级锁定的情况下,JVM通过CAS操作在对象的标题字中设置指向锁记录的指针;
ptr_to_heavyweight_monitor:重量级锁状态下,指向对象监视器Monitor的指针;如果两个不同的线程同时在同一个对象上竞争,则必须将轻量级锁定升级到Monitor以管理等待的线程;在重量级锁定的情况下,JVM在对象的ptr_to_heavyweight_monitor设置指向Monitor的指针;

Klass Pointer

即类型指针,是对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例;

实例数据

如果对象有属性字段,则这里会有数据信息;如果对象无属性字段,则这里就不会有数据;根据字段类型的不同占不同的字节,例如boolean类型占1个字节,int类型占4个字节等等;

对齐数据

对象可以有对齐数据也可以没有;默认情况下,Java虚拟机堆中对象的起始地址需要对齐至8的倍数;

如果一个对象用不到8N个字节则需要对其填充,以此来补齐对象头和实例数据占用内存之后剩余的空间大小;

如果对象头和实例数据已经占满了JVM所分配的内存空间,那么就不用再进行对齐填充了;

所有的对象分配的字节总SIZE需要是8的倍数,如果前面的对象头和实例数据占用的总SIZE不满足要求,则通过对齐数据来填满;

为什么要对齐数据

字段内存对齐的其中一个原因,是让字段只出现在同一CPU的缓存行中;如果字段不是对齐的,那么就有可能出现跨缓存行的字段;也就是说,该字段的读取可能需要替换两个缓存行,而该字段的存储也会同时污染两个缓存行;这两种情况对程序的执行效率而言都是不利的;其实对其填充的最终目的是为了计算机高效寻址;

至此,我们已经了解了对象在堆内存中的整体结构布局,如下图所示;

Java 中 乐观锁和悲观锁的理解及如何实现,有哪些实现方式?

悲观锁:

总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁;传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁;再比如 Java里面的同步原语 synchronized 关键字的实现也是悲观锁;

乐观锁:

顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制;乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于 write_condition 机制,其实都是提供的乐观锁;在 Java中java.util.concurrent.atomic 包下面的原子变量类就是使用了乐观锁的一种实现方式 CAS 实现的;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/175458.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

自定义类型:结构体,枚举,联合

目录一、结构体内存对齐二、位段2.1 什么是位段2.2 位段内存分配规则2.3 位段的跨平台问题三、枚举四、联合体4.1 联合类型的定义4.2联合的特点4.3 联合大小的计算4.4 练习一、结构体内存对齐 struct s {char c1;int i;char c2; }; int main() {printf("%d\n", size…

【Hadoop】HDFS体系结构分析

文章目录1. NameNode2. Secondary NameNode3. DataNodeHDFS主要包含NameNode、Secondary NameNode和DataNode三部分,且这三部分在分布式文件系统中分属不同的机器,其中Secondary NameNode不是必须的,在HA架构中Standby NameNode可以替代它。 …

【深度学习】详解 SimCLR

目录 摘要 一、引言 二、方法 2.1 The Contrastive Learning Framework 2.2. Training with Large Batch Size 2.3. Evaluation Protocol 三、用于对比表示学习的数据增广 3.1 Composition of data augmentation operations is crucial for learning good representa…

5-2中央处理器-指令周期的数据流

文章目录一.指令周期二.数据流向1.取指周期2.间址周期3.执行周期4.中断周期三.指令执行方案1.单指令周期2.多指令周期3.流水线方案一.指令周期 指令周期:CPU从主存中每取出并执行一条指令所需的全部时间。 此处:取指周期取指令指令译码 指令周期常用若…

SSM整合(Spring + SpringMVC + MyBatis)

SSM Spring SpringMVC MyBatis 准备数据库 SET FOREIGN_KEY_CHECKS0; DROP TABLE IF EXISTS user; CREATE TABLE user (id int(11) NOT NULL AUTO_INCREMENT,username varchar(20) NOT NULL COMMENT 用户名,password varchar(255) NOT NULL COMMENT 密码,real_name varchar(…

Linux常用命令——startx命令

在线Linux命令查询工具(http://www.lzltool.com/LinuxCommand) startx 用来启动X Window 补充说明 startx命令用来启动X Window,实际上启动X Window的程序为xinit。 语法 startx(参数)参数 客户端及选项:X客户端及选项;服务器及选项&a…

[LeetCode周赛复盘] 第 329 场周赛20230122

[LeetCode周赛复盘] 第 329 场周赛20230122 一、本周周赛总结二、 [Easy] 6296. 交替数字和1. 题目描述2. 思路分析3. 代码实现三、[Medium] 6297. 根据第 K 场考试的分数排序1. 题目描述2. 思路分析3. 代码实现四、[Medium] 6298. 执行逐位运算使字符串相等1. 题目描述2. 思路…

深入理解 OpenMP 线程同步机制

深入理解 OpenMP 线程同步机制 前言 在本篇文章当中主要给大家介绍 OpenMP 当中线程的同步和互斥机制,在 OpenMP 当中主要有三种不同的线程之间的互斥方式: 使用 critical 子句,使用这个子句主要是用于创建临界区和 OpenMP 提供的运行时库…

连续系统的数字PID控制仿真-1

被控对象为一电机模型传递函数:式中,J 0.0067;B0.10。采用M函数的形式,利用ODE45的方法求解连续对象方程,输入指令信号为yd(k)0.50sin(2*3.14*t),采用PID控制方法设计控制器,其中kp20.0 ,kd0.50。PID正弦跟…

12个开源的后台管理系统

1. D2admin 开源地址:https://github.com/d2-projects/d2-admin 文档地址:https://d2.pub/zh/doc/d2-admin/ 效果预览:https://d2.pub/d2-admin/preview/#/index 开源协议:MIT 2. vue-element-admin 开源地址:htt…

Kettle(3):快速入门

1 需求 有一个txt文件,内容如下: id,name,age,gender,province,city,region,phone,birthday,hobby,register_date 392456197008193000,张三,20,0,北京市,昌平区,回龙观,18589407692,1970-8-19,美食;篮球;足球,2018-8-6 9:44 267456198006210000,李四,2…

Vue3 – Composition API

1、认识CompositionAPI 1.1、Options API的弊端 在Vue2中,我们编写组件的方式是Options API: Options API的一大特点就是在对应的属性中编写对应的功能模块;比如data定义数据、methods中定义方法、computed中定义计算属性、watch中监听属性…

【快速简单登录认证】SpringBoot使用Sa-Token-Quick-Login插件快速登录认证

一、解决的问题 Sa-Token-Quick-Login 可以为一个系统快速的、零代码 注入一个登录页面 试想一下,假如我们开发了一个非常简单的小系统,比如说:服务器性能监控页面, 我们将它部署在服务器上,通过访问这个页面&#xf…

学习字符串函数和内存函数必看

字符串函数 1.strlen函数 strlen库函数 #include<stdio.h> #include<string.h> int main() {char arr[] "abc";char arr1[] { a,b,c };int len strlen(arr);int len1 strlen(arr1);//没有\0就无法停止printf("%d\n",len);printf("%…

VUE中的provide和inject用法

一、Vue中 常见的组件通信方式可分为三类 父子通信 父向子传递数据是通过 props&#xff0c;子向父是通过 events&#xff08;$emit&#xff09;&#xff1b; 通过父链 / 子链也可以通信&#xff08;$parent / $children&#xff09;&#xff1b; ref 也可以访问组件实例&…

XLSReadWriteII 写了一个DBGrdiEh创建EXCEL表的函数

XLSReadWriteII 写了一个DBGrdiEh创建EXCEL表的函数 自己通过XLSReadWriteII&#xff0c;写了一个由DBGridEh数据集&#xff0c;通过参数调用&#xff0c;创建EXCEL表格的函数&#xff0c;通过调用的参数设置&#xff0c;可以较为方便地&#xff0c;创建指定数据集的常用EXCEL表…

自动化和Selenium

作者&#xff1a;~小明学编程 文章专栏&#xff1a;测试开发 格言&#xff1a;热爱编程的&#xff0c;终将被编程所厚爱。 目录 什么是自动化&#xff0c;我们为什么需要自动化的测试&#xff1f; 为什么选择selenium来作为我们的web自动化测试的工具&#xff1f; 定位元素…

【C进阶】找单身狗

⭐博客主页&#xff1a;️CS semi主页 ⭐欢迎关注&#xff1a;点赞收藏留言 ⭐系列专栏&#xff1a;C语言进阶 ⭐代码仓库&#xff1a;C Advanced 家人们更新不易&#xff0c;你们的点赞和关注对我而言十分重要&#xff0c;友友们麻烦多多点赞&#xff0b;关注&#xff0c;你们…

Spring事务(事务的实现、隔离级别、传播机制)

目录 一、事务的定义和意义 二、事务的实现 1、MySQL事务的回顾 2、Spring声明式事务&#xff08;利⽤注解⾃动开启和提交事务&#xff09; 前置知识及概念 实例分析&#xff1a;事务的回滚 &#x1f514;特殊情况&#xff08;无自动回滚&#xff09; &#x1f514;事务…

VueJs中如何使用provide与inject

前言在vue2.0里面provide与inject是以选项式(配置)API的方式在组件中进行使用的,解决的是跨组件(祖孙)间通信的一种方式也就是父子组件间的通信,父组件上通过自定义属性,而子组件间通过props这种方式接收,如果想要一层一层的传递,这种方式就会比较麻烦,不灵活provide与inject就…