Java面试题(每天10题)-------连载(30)

news2024/11/25 19:22:12

目录

多线程篇

1、可以运行时kill掉一个线程吗?

2、关于synchronized

3、分布式锁,程序数据库中死锁机制及解决方案

4、spring单例为什么没有安全问题(ThreadLocal)

5、线程池原理

6、Java锁多个对象

7、Java线程如何启动

8、如何让保证数据不丢失

9、ThreadLocal为什么会发生内存泄漏

10、JDK8中对ConcurrentHashmap的改进 


多线程篇

1、可以运行时kill掉一个线程吗?

1、不可以,线程有 5 种状态,新建( new )、可运⾏( runnable )、运⾏中( running )、阻塞( block )、死亡(dead )。
2、  只有当线程 run ⽅法或者主线程 main ⽅法结束,⼜或者抛出异常时,线程才会结束⽣命周期。

2、关于synchronized

1. 在某个对象的所有 synchronized ⽅法中 , 在某个时刻只能有⼀个唯⼀的⼀个线程去访问这些 synchronized ⽅法
2. 如果⼀个⽅法是 synchronized ⽅法 , 那么该 synchronized 关键字表示给当前对象上锁 ( this) 相当于synchronized(this){}
3. 如果⼀个 synchronized ⽅法是 static , 那么该 synchronized 表示给当前对象所对应的 class 对象上锁 ( 每个类不管⽣成多少对象, 其对应的 class 对象只有⼀个 )

3、分布式锁,程序数据库中死锁机制及解决方案

基本原理:用一个状态值表示锁,对锁的占用和释放通过状态值来标识。

1 、三种分布式锁:

Zookeeper:基于zookeeper瞬时有序节点实现的分布式锁,其主要逻辑如下。⼤致思想即为:每个客户端对某个功能加锁时,在zookeeper上的与该功能对应的指定节点的⽬录下,⽣成⼀个唯⼀的瞬时有序节点。判断是否获取锁的⽅式很简单,只需要判断有序节点中序号最⼩的⼀个。当释放锁的时候,只需将这个瞬时节点删除即可。同时,其可以避免服务宕机导致的锁⽆法释放,⽽产⽣的死锁问题。

  1. 优点
    锁安全性⾼, zk 可持久化,且能实时监听获取锁的客户端状态。⼀旦客户端宕机,则瞬时节点随之消失, zk 因⽽能第⼀时间释放锁。这也省去了⽤分布式缓存实现锁的过程中需要加⼊超时时间判断的这⼀逻辑。
  2. 缺点
    性能开销⽐较⾼。因为其需要动态产⽣、销毁瞬时节点来实现锁功能。所以不太适合直接提供给⾼并发的场景使⽤。
  3. 实现
    可以直接采⽤ zookeeper 第三⽅库 curator 即可⽅便地实现分布式锁。
  4. 适用场景
    对可靠性要求⾮常⾼,且并发程度不⾼的场景下使⽤。如核⼼数据的定时全量
    / 增量同步等。 
memcached memcached 带有 add 函数,利⽤ add 函数的特性即可实现分布式锁。 add set 的区别在于:如果多线程并发set ,则每个 set 都会成功,但最后存储的值以最后的 set 的线程为准。⽽ add 的话则相反, add 会添加第⼀个到达的值,并返回true ,后续的添加则都会返回 false 。利⽤该点即可很轻松地实现分布式锁。
  1. 优点
    并发⾼效
  2. 缺点
    memcached采⽤列⼊LRU置换策略,所以如果内存不够,可能导致缓存中的锁信息丢失。 memcached⽆法持久化,⼀旦重启,将导致信息丢失。
  3. 使⽤场景
    ⾼并发场景。需要 1)加上超时时间避免死锁; 2)提供⾜够⽀撑锁服务的内存空间; 3)稳定的集群化管理。
redis redis 分布式锁即可以结合 zk 分布式锁锁⾼度安全和 memcached 并发场景下效率很好的优点,其实现⽅式和memcached类似,采⽤ setnx 即可实现。需要注意的是,这⾥的 redis 也需要设置超时时间,以避免死锁。可以利⽤ jedis 客户端实现。
ICacheKey cacheKey = new ConcurrentCacheKey(key, type);
return RedisDao.setnx(cacheKey, "1");
2、数据库死锁机制和解决⽅案:
  1. 死锁:死锁是指两个或者两个以上的事务在执⾏过程中,因争夺锁资源⽽造成的⼀种互相等待的现象。
  2. 处理机制:解决死锁最有⽤最简单的⽅法是不要有等待,将任何等待都转化为回滚,并且事务重新开始。但是有可能影响并发性能。
    1、超时回滚,innodb_lock_wait_time设置超时时间;
    2wait-for-graph⽅法:跟超时回滚⽐起来,这是⼀种更加主动的死锁检测⽅式。InnoDB引擎也采⽤这种⽅式。

4、spring单例为什么没有安全问题(ThreadLocal)

1 ThreadLocal spring 使⽤ ThreadLocal 解决线程安全问题; ThreadLocal 会为每⼀个线程提供⼀个独⽴的变量副本,从⽽隔离了多个线程对数据的访问冲突。因为每⼀个线程都拥有⾃⼰的变量副本,从⽽也就没有必要对该变量进⾏同步了。
ThreadLocal 提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进 ThreadLocal 。概括起来说,对于多线程资源共享的问题,同步机制采⽤了“ 以时间换空间 的⽅式,⽽ ThreadLocal 采⽤了 以空间换时间 的⽅式。前者仅提供⼀份变量,让不同的线程排队访问,⽽后者为每⼀个线程都提供了⼀份变量,因此可以同时访问⽽互不影响。在很多情况下,ThreadLocal⽐直接使⽤ synchronized 同步机制解决线程安全问题更简单,更⽅便,且结果程序拥有更⾼的并发性。
2 、单例:⽆状态的 Bean( ⽆状态就是⼀次操作,不能保存数据。⽆状态对象 (Stateless Bean) ,就是没有实例变量的对象,不能保存数据,是不变类,是线程安全的。) 适合⽤不变模式,技术就是单例模式,这样可以共享实例,提⾼性能。

5、线程池原理

1 、使⽤场景:假设⼀个服务器完成⼀项任务所需时间为: T1- 创建线程时间, T2- 在线程中执⾏任务的时间, T3- 销毁线程时间。如果T1+T3 远⼤于 T2 ,则可以使⽤线程池,以提⾼服务器性能;
2 、组成:
  1. 线程池管理器(ThreadPool):⽤于创建并管理线程池,包括 创建线程池,销毁线程池,添加新任务;
  2. ⼯作线程(PoolWorker):线程池中线程,在没有任务时处于等待状态,可以循环的执⾏任务;
  3. 任务接⼝(Task):每个任务必须实现的接⼝,以供⼯作线程调度任务的执⾏,它主要规定了任务的⼊⼝,任务执⾏完后的收尾⼯作,任务的执⾏状态等;
  4. 任务队列(taskQueue):⽤于存放没有处理的任务。提供⼀种缓冲机制。
3、原理:线程池技术正是关注如何缩短或调整 T1,T3 时间的技术,从⽽提⾼服务器程序性能的。它把 T1 T3 分别安排在服务器程序的启动和结束的时间段或者⼀些空闲的时间段,这样在服务器程序处理客户请求时,不会有T1 T3 的开销了。
4、⼯作流程:
  1. 线程池刚创建时,⾥⾯没有⼀个线程(也可以设置参数prestartAllCoreThreads启动预期数量主线程)。任务队列是作为参数传进来的。不过,就算队列⾥⾯有任务,线程池也不会⻢上执⾏它们。
  2. 当调⽤ execute() ⽅法添加⼀个任务时,线程池会做如下判断:
    如果正在运⾏的线程数量⼩于 corePoolSize,那么⻢上创建线程运⾏这个任务;
    如果正在运⾏的线程数量⼤于或等于 corePoolSize,那么将这个任务放⼊队列;
    如果这时候队列满了,⽽且正在运⾏的线程数量⼩于 maximumPoolSize,那么还是要创建⾮核⼼线程⽴刻运⾏这个任务;
    如果队列满了,⽽且正在运⾏的线程数量⼤于或等于 maximumPoolSize,那么线程池会抛出异常RejectExecutionException
  3. 当⼀个线程完成任务时,它会从队列中取下⼀个任务来执⾏。
  4. 当⼀个线程⽆事可做,超过⼀定的时间(keepAliveTime)时,线程池会判断,如果当前运⾏的线程数⼤于corePoolSize,那么这个线程就被停掉。所以线程池的所有任务完成后,它最终会收缩到corePoolSize 的⼤⼩。

6、Java锁多个对象

例如: 在银⾏系统转账时,需要锁定两个账户,这个时候,顺序使⽤两个 synchronized 可能存在死锁的情况,在⽹上搜索到下⾯的例⼦:
public class MyData {
    private int j = 0;

    public synchronized void add() {
        j++;
        System.out.println("线程" + Thread.currentThread().getName() + "j为:" + j);
    }

    public synchronized void dec() {
        j--;
        System.out.println("线程" + Thread.currentThread().getName() + "j为:" + j);
    }

    public int getData() {
        return j;
    }
}

public class AddRunnable implements Runnable {
    MyData data;

    public AddRunnable(MyData data) {
        this.data = data;
    }

    public void run() {
        data.add();
    }
}

public class DecRunnable implements Runnable {
    MyData data;

    public DecRunnable(MyData data) {
        this.data = data;
    }

    public void run() {
        data.dec();
    }
}

public class TestOne {
    public static void main(String[] args) {
        MyData data = new MyData();
        Runnable add = new AddRunnable(data);
        Runnable dec = new DecRunnable(data);
        for (int i = 0; i < 2; i++) {
            new Thread(add).start();
            new Thread(dec).start();
        }
    }
}
       

7、Java线程如何启动

1 、继承 Thread 类;
2 、实现 Runnable 接⼝;
3 、直接在函数体内:
4 、⽐较:
  1. 实现Runnable接⼝优势:
    1)适合多个相同的程序代码的线程去处理同⼀个资源
    2)可以避免java中的单继承的限制
    3)增加程序的健壮性,代码可以被多个线程共享,代码和数据独⽴。
  2. 继承Thread类优势:
    1)可以将线程类抽象出来,当需要使⽤抽象⼯⼚模式设计时。
    2)多线程同步
  3. 在函数体使⽤优势
    1)⽆需继承thread或者实现Runnable,缩⼩作⽤域。

8、如何让保证数据不丢失

1 、使⽤消息队列,消息持久化;
2 、添加标志位:未处理 0 ,处理中 1 ,已处理 2 。定时处理。

9、ThreadLocal为什么会发生内存泄漏

 1、ThreadLocal原理图

2、OOM实现:

  1. ThreadLocal的实现是这样的:每个Thread 维护⼀个 ThreadLocalMap 映射表,这个映射表的 key ThreadLocal例本身,value 是真正需要存储的 Object
  2. 也就是说 ThreadLocal 本身并不存储值,它只是作为⼀个 key 来让线程从 ThreadLocalMap 获取 value。值得注意的是图中的虚线,表示 ThreadLocalMap 是使⽤ ThreadLocal 的弱引⽤作为 Key 的,弱引⽤的对象在 GC 时会被回收。
  3. ThreadLocalMap使⽤ThreadLocal的弱引⽤作为key,如果⼀个ThreadLocal没有外部强引⽤来引⽤它,那么系统 GC的时候,这个ThreadLocal势必会被回收,这样⼀来,ThreadLocalMap中就会出现key为null的Entry,就没有办法访问这些key为null的Entry的value,如果当前线程再迟迟不结束的话,这些keynullEntryvalue就会⼀直存在⼀条强引⽤链:Thread Ref -> Thread -> ThreaLocalMap -> Entry -> value永远⽆法回收,造成内存泄漏。

3 、预防办法:在 ThreadLocal get (), set (), remove ()的时候都会清除线程 ThreadLocalMap ⾥所有 key null value
但是这些被动的预防措施并不能保证不会内存泄漏:
(1)使⽤ static ThreadLocal ,延⻓了 ThreadLocal 的⽣命周期,可能导致内存泄漏。
(2)分配使⽤了 ThreadLocal ⼜不再调⽤ get (), set (), remove ()⽅法,那么就会导致内存泄漏,因为这块内存⼀直存在。

10、JDK8中对ConcurrentHashmap的改进 

1. Java 7 为实现并⾏访问,引⼊了 Segment 这⼀结构,实现了分段锁,理论上最⼤并发度与 Segment 个数相等。
2. Java 8 为进⼀步提⾼并发性,摒弃了分段锁的⽅案,⽽是直接使⽤⼀个⼤的数组。同时为了提⾼哈希碰撞下的寻址性能,Java 8在链表⻓度超过⼀定阈值(8)时将链表(寻址时间复杂度为 O ( N ))转换为红⿊树(寻址时间复杂度为 O ( long ( N )))。
其数据结构如下图所示

3.源码

public V put(K key,V value){
        return putVal(key,value,false);
        }

/**
 * Implementation for put and putIfAbsent
 */
final V putVal(K key,V value,boolean onlyIfAbsent){
        //ConcurrentHashMap 不允许插⼊null键,HashMap允许插⼊⼀个null键
        if(key==null||value==null)throw new NullPointerException();
        //计算key的hash值
        int hash=spread(key.hashCode());
        int binCount=0;
        //for循环的作⽤:因为更新元素是使⽤CAS机制更新,需要不断的失败重试,直到成功为⽌。
        for(Node<K, V>[]tab=table;;){
        // f:链表或红⿊⼆叉树头结点,向链表中添加元素时,需要synchronized获取f的锁。
        Node<K, V> f;int n,i,fh;
        //判断Node[]数组是否初始化,没有则进⾏初始化操作
        if(tab==null||(n=tab.length)==0)
        tab=initTable();
        //通过hash定位Node[]数组的索引坐标,是否有Node节点,如果没有则使⽤CAS进⾏添加(链表的头结点),添加失败则进⼊下次循环。
        else if((f=tabAt(tab,i=(n-1)&hash))==null){
        if(casTabAt(tab,i,null,
        new Node<K, V>(hash,key,value,null)))
        break; // no lock when adding to empty bin
        }
        //检查到内部正在移动元素(Node[] 数组扩容)
        else if((fh=f.hash)==MOVED)
        //帮助它扩容
        tab=helpTransfer(tab,f);
        else{
        V oldVal=null;
//锁住链表或红⿊⼆叉树的头结点
synchronized (f){
        //判断f是否是链表的头结点
        if(tabAt(tab,i)==f){
        //如果fh>=0 是链表节点
        if(fh>=0){
        binCount=1;
        //遍历链表所有节点
        for(Node<K, V> e=f;;++binCount){
        K ek;
        //如果节点存在,则更新value
        if(e.hash==hash&&
        ((ek=e.key)==key||
        (ek!=null&&key.equals(ek)))){
        oldVal=e.val;
        if(!onlyIfAbsent)
        e.val=value;
        break;
        }
        //不存在则在链表尾部添加新节点。
        Node<K, V> pred=e;
        if((e=e.next)==null){
        pred.next=new Node<K, V>(hash,key,
        value,null);
        break;
        }
        }
        }
        //TreeBin是红⿊⼆叉树节点
        else if(f instanceof TreeBin){
        Node<K, V> p;
        binCount=2;
        //添加树节点
        if((p=((TreeBin<K, V>)f).putTreeVal(hash,key,
        value))!=null){
        oldVal=p.val;
        if(!onlyIfAbsent)
        p.val=value;
        }
        }
        }
        }

        if(binCount!=0){
        //如果链表⻓度已经达到临界值8 就需要把链表转换为树结构
        if(binCount>=TREEIFY_THRESHOLD)
        treeifyBin(tab,i);
        if(oldVal!=null)
        return oldVal;
        break;
        }
        }
        }
        //将当前ConcurrentHashMap的size数量+1
        addCount(1L,binCount);
        return null;
}

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

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

相关文章

基于opencv+tensorflow+神经网络的智能银行卡卡号识别系统——深度学习算法应用(含python、模型源码)+数据集(一)

目录 前言总体设计系统整体结构图系统流程图 运行环境Python环境TensorFlow 环境OpenCV环境 相关其它博客工程源代码下载其它资料下载 前言 本项目基于从网络获取的多种银行卡数据集&#xff0c;采用OpenCV库的函数进行图像处理&#xff0c;并通过神经网络进行模型训练。最终实…

雅虎、美客多、Temu、Allegro、亚马逊跨境平台选品技巧方法,测评养号攻略。

&#xff08;1) Best Sellers选品法 这个方法顾名思义&#xff0c;就是大家熟悉的热销榜单选品法。 不做过多解释&#xff0c;在自己熟悉的品类&#xff0c;隔几天就会观察一下前100名里有没有冒出什么新品。 它和现有的产品相同还是不同&#xff0c;自己做哪些搭配或者迭代…

数字农业农村解决方案:PPT全文69页,附下载

关键词&#xff1a;智慧农业解决方案&#xff0c;数字农村&#xff0c;数字农业&#xff0c;智慧农业大数据平台 一、数字农业建设背景 数字农业建设是在国家大数据战略和“互联网”行动计划的指引下&#xff0c;充分利用现代信息技术和人工智能手段&#xff0c;对农业农村领…

ioc是什么

IOC是什么&#xff1f; 在面向对象的软件设计中&#xff0c;底层都是由多个对象耦合组成共同实现逻辑业务的&#xff0c;如下图&#xff1a; 耦合关系不仅会出现在对象与对象之间&#xff0c;也会出现在软件系统的各模块之间&#xff0c;以及软件系统和硬件系统之间。如何降低…

电脑监控软件丨功能详情丨特点分析

电脑监控软件的出现&#xff0c;是在信息技术的飞速发展以及计算机使用的普及的背景下产生的。随着计算机在企业、学校以及家庭等各个场所的广泛使用&#xff0c;管理和保护计算机数据安全的问题变得越来越重要。因此&#xff0c;电脑监控软件应运而生&#xff0c;旨在帮助用户…

企业大楼门禁,千万不要这么管理!太慢了!

随着社会科技的飞速发展&#xff0c;安全管理已经成为各行业关注的焦点之一。在这个信息化时代&#xff0c;门禁监控系统作为一种全面提升安全性、管理效率的关键工具&#xff0c;逐渐成为企事业单位、学校、医疗机构等场所的不可或缺的一部分。 传统的门禁系统已经无法满足现代…

threejs太阳系(源码加相关素材)

目录 前言 效果预览图 完整代码 html部分 js部分 模块aa 前言 Three.js 是一款基于原生 WebGL 封装通用 Web 3D 引擎&#xff0c;在小游戏、产品展示、物联网、数字孪生、智慧城市园区、机械、建筑、全景看房、GIS 等各个领域基本上都有 three.js 的身影。本篇文章简单的使…

开源维修上门服务小程序SAAS系统源码 带完整搭建教程

在现代生活中&#xff0c;家电设备维修往往是一个耗时且繁琐的过程。消费者需要花费大量时间寻找合适的维修人员&#xff0c;并面临服务质量不稳定的风险。同时&#xff0c;对于维修人员来说&#xff0c;寻找客户和接收订单的过程也十分繁琐。因此&#xff0c;开发一款基于小程…

cryptopp Base64Encoder \n问题

1、问题&#xff1a; new Base64Encoder(new StringSink(out_base)) 调用库函数Base64Encoder进行base64加密后确认多出来了\n 2、原因 base64加密的问题, 由于base64一行不能超过76字符, 超过就会添加回车换行符(在Windows中是 \r\n , 在Linux中是 \n ) 3、解决 方法一、给定参…

Python中的filter函数用法详解

目录 引言 一、filter函数基本用法 二、filter函数应用场景 1、筛选符合条件的元素 2、数据清洗和预处理 3、复杂条件筛选 4、与其他函数结合使用 三、filter函数与lambda表达式 四、filter函数与列表推导式 五、总结 引言 Python中的filter函数是一种内置的高效过滤…

电脑桌面图标打不开?三种方法让你轻松应对

电脑桌面上的图标是我们日常使用电脑的入口&#xff0c;但有时候您可能会遇到一个常见问题&#xff0c;电脑桌面图标打不开。这个问题可能会让您感到困惑&#xff0c;但幸运的是&#xff0c;通常有多种方法可以解决。本文将详细介绍三种常见的解决方法&#xff0c;帮助您恢复桌…

测试:面试问题(多精全)

目录 面试问题 1&#xff0c;你们原来项目的测试流程是怎么样的&#xff1f; 2&#xff0c;你介绍下&#xff0c;你最熟悉的项目&#xff1f; 3&#xff0c;你们原来项目的主要的功能模块有哪些&#xff0c;你主要负责哪些模块&#xff1f; 4&#xff0c;你说原来充值…

Axure9学习

产品经理零基础入门&#xff08;四&#xff09;Axure 原型图教程&#xff0c;2小时学会_哔哩哔哩_bilibili 1. ① 页面对应页面个数&#xff0c;概要对应每个页面的具体内容 ② 文件类型 ③ 备用间隔改为5分钟 ④ 当多个元件重叠&#xff0c;想把在下面的元件b直接拖出来&…

一款IT团队都在用的私有化知识库,技术开放,还开源了!

IT和软件开发团队需要处理大量的技术文档和知识&#xff0c;通过建立内部知识库&#xff0c;可以将技术文档、代码示例、最佳实践等知识整理和归档起来&#xff0c;方便团队成员查找和参考。 IT和软件开发团队为什么要建立内部知识库&#xff1f; 提高知识管理效率&#xff1a…

汇川(Inovance) PLC——H2u 和H3u:编程口通讯协议

文章目录 说明通讯帧通讯命令字通讯数据地址汇川 H2u H3u通讯协议举例 说明 该协议适用于汇川H2u系列和H3u系列PLC。 通讯帧 通讯采用ASCII码&#xff0c;校验方式采用和校验。 请求帧格式:报文开始命令字地址&#xff08;有些无&#xff09;长度&#xff08;有些无&#xf…

怎样用 vs2017编写一个cpp并运行

02 第一个C程序-C书写HelloWorld_哔哩哔哩_bilibili 1 第一个C程序 编写一个C程序总共分为4个步骤 创建项目 创建文件 编写代码 运行程序 1.1 创建项目 Visual Studio是我们用来编写C程序的主要工具&#xff0c;我们先将它打开 1.2 创建文件 右键源文件&#xff0c;选…

解决企业项目管理难题:痛点分析与实用解决方案探索

在当前竞争激烈的商业环境中&#xff0c;产品力已然成为市场竞争的核心&#xff0c;这背后的驱动力是技术、人才和管理能力的综合体现——研发创新能力。其中&#xff0c;项目管理能力扮演着至关重要的角色&#xff0c;它能最大化地发挥和释放以上三者的优势。因此&#xff0c;…

教资笔记(目录)

2023.9.16教资考试 笔试成绩是150分&#xff0c;但是考试折合成120分满分&#xff0c;70分及格。 计划&#xff1a;2024上半年再战科一 名称类型中学科二急救班中学中小学科一模板通用科目二简答题汇总中学教资学习笔记总结中学《综合素质》通用 小学中学科一&#xff08;通…

基于springboot实现小学家校一体“作业帮”系统项目【项目源码】计算机毕业设计

基于springboot实现小学家校一体“作业帮”系统演示 Java语言简介 Java是由SUN公司推出&#xff0c;该公司于2010年被oracle公司收购。Java本是印度尼西亚的一个叫做爪洼岛的英文名称&#xff0c;也因此得来java是一杯正冒着热气咖啡的标识。Java语言在移动互联网的大背景下具…

电子零部件工厂的WMS系统:业务特点、产品特点与优势

一、电子零部件工厂的业务特点 电子零部件工厂的业务涉及各种电子元器件的生产、组装和配送。其业务特点包括&#xff1a; 高度复杂性&#xff1a;电子零部件工厂的生产流程涉及多种原材料、半成品和成品&#xff0c;每种产品都有不同的规格、属性及存储要求。 严格的质量控…