Java高级开发面试题整理

这篇具有很好参考价值的文章主要介绍了Java高级开发面试题整理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、并发编程

1、什么是进程和线程?

进程是指程序的一次执行过程,是系统运行程序的基本单位,系统运行一个程序就是一个进程创建、运行、到销毁的过程;一个进程可以有多个线程。比如我跑一个java的main方法,系统就创建了一个java进程,这个main方法所在的线程就是这个进程的一个线程,也称为主线程。

2、java实现线程安全的几种方式

1)、使用synchronized关键字,直接修饰方法或编写同步代码块来保证线程安全,建议类内部实现一个object对象锁,不使用“this”,可避免极端死锁情况

2)、Lock可重入锁(ReentrantLock)

3)、使用concurrent包下的集合或是原子性对象包括 AtomicInteger,AtomicLong,AtomicBoolean等

总结:synchronized是jvm层面的,并发较低的情况下推荐使用,并发较高时推荐使用Lock

3、简述多线程的作用

1)、多线程可以提升系统的并发能力及性能,更好的利用服务器资源来提高程序的运行速度及执行效率。

4、线程的生命周期 ?

1)、NEW:初始状态,线程被创建,但是没有被调用start()

2)、RUNABLE:运行状态,线程被调用start()方法,等待运行

3)、BLOCKED:阻塞状态,需要等待锁释放

4)、WAITING:等待状态,该线程需要等待其他线程做出特定动作(通知或中断)

5)、TIMED_WAITING:超时等待状态,可以在指定时间后返回,而不是想WAITING那样一直等待

6)、TERMINATED:终止,表示该线程已经执行完毕

java高级开发面试题,面试题,java,java面试题,java基础,java进阶,java高级

4、悲观锁与乐观锁

悲观锁是假设最坏的情况,认为每次访问共享资源都会出现问题,比如共享数据被修改;所以在每次获取资源的时候就上锁,其他线程获取则被阻塞需要等待,直到线程结束才释放资源;所以悲观锁适用多写的场景。

乐观锁是假设共享资源每次访问不会出现问题,只在修改共享资源的时候判断该资源是否被其他线程修改,若没有则修改成功,有则修改失败;实现乐观锁最常见的方式就是使用版本号机制,修改数据的同时带上版本号条件,检验版本号是否有变化来判断数据是否被其他线程修改。

5、synchronized关键字

它是java语言的一个关键字,代表同步的意思,被它修饰的方法或代码块在同一时刻只能有一个线程执行;一些访问量较高的接口或方法且需要保证唯一性的场景(单机部署的情况下),可以使用该关键字来解决并发问题,比如代码生成自增ID。

值得注意的是,静态synchronized方法与实例synchronized方法之间的调用是非互斥的,因为前者是当前类的锁,后者是当前类的实例对象锁。

6、ThreadLocal

JDK自带的ThreadLocal类是为了让每个线程拥有自己的数据空间,通常我们定义的成员变量,每个线程都是可以修改的,而ThreadLocal存放的只有当前线程自己的值。

其内部有一个ThreadLocalMap,相当于每个线程拥有一个自己的ThreadLocalMap,来存放自己的数据,从而实现线程与线程之间的数据隔离。

注意:使用完ThreadLocal后记得手动调用remove()方法,避免出现内存泄露

7、为什么要用线程池?

1)、降低资源的消耗:避免频繁的创建和销毁线程造成系统资源的消耗

2)、提高响应速度:当程序需要使用线程时,直接从线程池中获取创建好的线程,响应更快

3)、线程可集中管理:统一管理,控制风险,线程不能无限制的创建

8、用过 CountDownLatch 么?什么场景下用的?

CountDownLatch类用来实现多线程的情况下,阻塞主线程等待count个子线程执行完毕再继续往下执行的目的。比如我们使用10个线程同时读取10个文件,现在需要等待10个文件都读取完毕再执行某个操作就要用到CountDownLatch来实现了,伪代码如下:

public class CountDownLatchExample1 {
    // 处理文件的数量
    private static final int threadCount = 10;

    public static void main(String[] args) throws InterruptedException {
        // 创建一个具有固定线程数量的线程池对象(推荐使用构造方法创建)
        ExecutorService threadPool = Executors.newFixedThreadPool(10);
        final CountDownLatch countDownLatch = new CountDownLatch(threadCount);
        for (int i = 0; i < threadCount; i++) {
            final int threadnum = i;
            threadPool.execute(() -> {
                try {
                    //处理文件的业务操作
                    //......
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    //表示一个文件已经被完成
                    countDownLatch.countDown();
                }
            });
        }
        //线程阻塞,直至count=0才结束等待
        countDownLatch.await();
        threadPool.shutdown();
        System.out.println("ok");
    }
}

9、如何实现分布式锁

1)、使用redisson实现,基于redis单线程特性,通过SETNX命令实现

2)、使用zookeeper实现,使用它的create()方法来创建一个临时节点,判断这个节点是否存在来实现锁机制

3)、使用Lock实现,创建一个可重入锁的实例将其存储在所有线程可共享的资源中,调用lock()方法上锁,unlock()方式释放锁

10、java中的队列

java高级开发面试题,面试题,java,java面试题,java基础,java进阶,java高级

1)、阻塞队列

所谓的阻塞队列是指当队列是空的,获取元素的线程会被挂起直到其他线程往队列添加新的元素,反之当队列是满的添加元素的线程会被挂起直到队列被移除一个或多个元素或被清空;所谓阻塞,在某些情况下会挂起线程,一旦条件满足,被挂起的线程又会自动被唤醒。

BlockingQueue接口的核心方法:

boolean offer(E e):将元素添加到队列中,返回是否添加成功,e的值不能为null否则抛空指针异常

boolean offer(E e, long timeout, TimeUnit unit):将元素添加到队列中,如果队列已满,可指定等待时长,返回是否添加成功

boolean add(E e):将元素添加到队列中,添加成功返回true否则抛出异常,如果限制队列长度推荐使用offer()方法

put(E e):将元素添加到队列中,如果队列已满该方法会一直阻塞,直到队友有空间添加成功

E take():从队列中获取值,如果队列为空,该方法会一直阻塞直到有值并取到值

E poll(long timeout, TimeUnit unit):获取并移除队列的头元素,如果队列为空,可指定等待时长,等待超时则返回null

int remainingCapacity():获取队列中剩余的空间

remove(E e): 从队列中移除指定的值

contains(Object o): 判断队列中是否拥有该值。
drainTo(Collection c):将队列中值,全部移除,并发设置到给定的集合中
实现类

ArrayBlockingQueue:数组结构有界阻塞队列

LinkedBlockingQueue:链表结构组成的有界(默认大小是int最大值)阻塞队列

SynchronousQueue:单个元素队列,只存一个元素;如果该队列已有一元素的话,试图向队列中插入一个新元素的线程将会阻塞,直到另一个线程将该元素从队列中抽走。同样,如果该队列为空,试图向队列中抽取一个元素的线程将会阻塞,直到另一个线程向队列中插入了一条新的元素

PriorityBlockingQueue:不一定是先进先出,支持优先级的无界阻塞队列,可通过实现排序接口指定元素排序规则,无界队列会自动扩容,所有put方法永远不会阻塞

DelayQueue:不一定是先进先出,支持延迟功能的无界阻塞队列,可设置任务延迟多久后执行

二、JVM

java高级开发面试题,面试题,java,java面试题,java基础,java进阶,java高级

1、JVM重要的四个组成部分,Class Loader(类加载器)、Runtime Data Area(运行时数据区)、Execution Engine(执行引擎也称解释器)、Native Interface(本地接口)。

类加载器负责将编译后的Class文件加载到运行时数据区,然后由执行引擎将字节码翻译成指定系统指令集交给CPU去执行,在这个过程中会需要调用到不同语言为Java提供的接口,这些接口就是本地接口和本地库了。

2、Runtime Data Area(运行时数据区)

Runtime Data Area(运行时数据区)是用来存放数据的,其中包含:

Stack(栈):主要存储基本数据类型和引用类型变量,每个线程都有自己的栈空间,所以线程之间数据是不能共享的

Heap(堆):主要存储对象实例,由JVM动态分配内存空间,线程之间数据共享

例如:int a = 3; 其中a是对象引用存放在栈空间,“3”是基本类型的值也存放在栈空间

Method Area(方法区):用来存储已被虚拟机加载的类信息、常量、静态变量、编译后的代码等。JDK8之后,方法区存在于元空间

PC Register(程序计数器):每个线程都有各自独立的计数器,可以看做是字节码指令执行的行号指示器,记录了当前正在执行的字节码指令地址,如果执行的是Native方法,则程序计数器为空(Undefined)

Native Method Stack(本地方法栈):本地方法栈与虚拟机栈相似,它服务于本地方法

三、JMM(java内存模型)

1、作用

内存模型描述了程序中各个变量之间的关系,以及在程序实际运行中对变量的存储、读取、修改等操作的底层细节,它围绕有原子性、可见性、有序性三个特征来建立模型。

2、结构规范

JMM规定了所有变量都储存在主内存(Main Memory)中;每个工作线程都有自己的工作内存(Working Memory),工作内存中保存了工作线程需要用到的变量的主内存的副本,线程对变量的所有操作都必须在工作内存中完成,不能直接读写主内存中的变量(volatile关键字修饰的变量也有副本),工作线程的工作内存是互相不访问的,访问其他线程中的变量需要通过主内存来完成文章来源地址https://www.toymoban.com/news/detail-718521.html

到了这里,关于Java高级开发面试题整理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android架构进阶之高级UI系列(精编解析,值得收藏),Android开发面试技能介绍

    CallbackRecord callbacks; synchronized (mLock) { final long now = System.nanoTime(); // 根据指定的类型CallbackkQueue中查找到达执行时间的CallbackRecord callbacks = mCallbackQueues[callbackType].extractDueCallbacksLocked( now / TimeUtils.NANOS_PER_MS); if (callbacks == null) { return; } mCallbacksRunning = true; if (callbackType == Choreograph

    2024年04月13日
    浏览(42)
  • JAVA后端开发面试基础知识(八)——Spring

    Spring是一个轻量级Java开发框架 我们一般说 Spring 框架指的都是 Spring Framework,它是很多模块的集合,使用这些模块可以很方便地协助我们进行开发,比如说 Spring 支持 IoC(Inverse of Control:控制反转) 和 AOP(Aspect-Oriented Programming:面向切面编程)、可以很方便地对数据库进行访问、

    2024年03月10日
    浏览(71)
  • JAVA后端开发面试基础知识(一)——JVM

    Class loader(类装载) 根据给定的全限定名类名(如: java.lang.Object)来装载class文件到 Runtime data area中的method area。 Execution engine(执行引擎) 执行classes中的指令。 Native Interface(本地接口) 与native libraries交互,是其它编程语言交互的接口。 Runtime data area(运行时数据区域) 这就是我们常说

    2024年03月10日
    浏览(58)
  • Java安全 URLDNS链分析,网络安全开发面试基础

    this代表的是当前对象的指针,也可以用 this.name 的方式调用当前对象中的成员 那我们去 URLStreamHandler类 当中,查看下 hashCode方法 的代码 protected int hashCode(URL u) { int h = 0; // Generate the protocol part. String protocol = u.getProtocol(); if (protocol != null) h += protocol.hashCode(); // Generate the host pa

    2024年04月23日
    浏览(35)
  • 【面试】Java高频面试题(2023最新整理)

    JDK(Java Development Kit),Java开发工具包 JRE(Java Runtime Environment),Java运行环境 JDK中包含JRE,JDK中有一个名为jre的目录,里面包含两个文件夹bin和lib,bin就是JVM,lib 就是JVM工作所需要的类库。 对于基本类型,== 比较的是值; 对于引用类型,==比较的是地址; equals不能用于基

    2023年04月08日
    浏览(49)
  • Java面试整理(一)

    面试,应该都是打工人需要面对的事情。我记得自己以前开始准备Java工程师面试时,都会去看那个《面试宝典》,当时这个“宝典”真的很经典,现在应该还是不少朋友会看这个。我自己经历过了找工作的面试,和企业招聘工作。所以我自己更加想从这两个不同的角度去和大

    2024年02月09日
    浏览(31)
  • JAVA面试题整理

    ①抽象类里可以有构造方法,而接口内不能有构造方法。 ②抽象类中可以有普通成员变量,而接口中不能有普通成员变量。 ③抽象类中可以包含非抽象的普通方法,而接口中所有的方法必须是抽象的,不能有非抽象的普通方法。 ④抽象类中的抽象方法的访问类型可以是 pu

    2024年02月08日
    浏览(41)
  • Java面试整理(二)《JavaSE》

    说明:我会根据我自己的经验,给每个内容标注重要程度,共有三个等级:低、中、高。仅个人参考意见。 JVM是Java Virtual Machine的缩写,是用于运行Java字节码的虚拟机,JVM是运行在操作系统之上,这也是Java程序为什么能够运行在不同的平台或操作系统的原因。 JVM是Java语言

    2024年02月09日
    浏览(32)
  • Android-高级-UI-进阶之路-(七)-SVG-基础使用-+-绘制中国地图,Android面试中常问的MMAP到底是啥东东

    iv.setImageDrawable(animatedVectorDrawable) val animatable = iv.drawable as Animatable animatable.start() } } 输入搜索动画 利用在线绘制 SVG 图标网站 制作搜索图标 可以自己随意捣鼓绘制,绘制好了之后点击视图-源代码,将 SVG 代码复制出来保存成 search_svg.xml 在线转换 svg2vector 点击空白或者直接将

    2024年04月25日
    浏览(47)
  • 【面试】Java面试频繁问到的题最新整理(附答案)

    封装 :对象只需要 选择性的对外公开一些属性和行为 。 继承 :子对象 可以继承父对象的属性和行为 ,并且可以在其之上进行修改以适合更特殊的场景需求。 多态 : 允许不同类的对象对同一消息做出响应 。 数据类型 占用字节 byte 1 short 2 int 4 long 8 float 4 double 8 char 2 boo

    2024年02月07日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包