JUC相关面试题

news2024/11/25 5:36:59

csdntup

👏作者简介:大家好,我是爱发博客的嗯哼,爱好Java的小菜鸟
🔥如果感觉博主的文章还不错的话,请👍三连支持👍一下博主哦
📝社区论坛:希望大家能加入社区共同进步
🧑‍💼个人博客:智慧笔记
📕系列专栏:面试宝典

  • 本文引自黑马程序员Java面试宝典

JUC基础薄弱的可以先看JUC详解

文章目录

      • 面试官:聊一下并行和并发有什么区别?
      • 面试官:说一下线程和进程的区别?
      • 面试官:如果在java中创建线程有哪些方式?
      • 面试官:好的,刚才你说的runnable 和 callable 两个接口创建线程有什么不同呢?
      • 面试官:线程包括哪些状态,状态之间是如何变化的?
      • 面试官:嗯,好的,刚才你说的线程中的 wait 和 sleep方法有什么不同呢?
      • 面试官:好的,我现在举一个场景,你来分析一下怎么做,新建 T1、T2、T3 三个线程,如何保证它们按顺序执行?
      • 面试官:在我们使用线程的过程中,有两个方法。线程的 run()和 start()有什么区别?
      • 面试官:那如何停止一个正在运行的线程呢?
      • 面试官:讲一下synchronized关键字的底层原理?
      • 面试官:好的,你能具体说下Monitor 吗?
      • 面试官:好的,那关于synchronized 的锁升级的情况了解吗?
      • 面试官:好的,刚才你说了synchronized它在高并发量的情况下,性能不高,在项目该如何控制使用锁呢?
      • 面试官:嗯,那你说下ReentrantLock的使用方式和底层原理?
      • 面试官:好的,刚才你说了CAS和AQS,你能介绍一下吗?
      • 面试官:synchronized和Lock有什么区别 ?
      • 面试官:死锁产生的条件是什么?
      • 面试官:那如果产出了这样的,如何进行死锁诊断?
      • 面试官:请谈谈你对 volatile 的理解
      • 面试官:那你能聊一下ConcurrentHashMap的原理吗?
      • 面试官:线程池的种类有哪些?
      • 面试官:线程池的核心参数有哪些?
      • 面试官:如何确定核心线程池呢?
      • 面试官:线程池的执行原理知道吗?
      • 面试官:为什么不建议使用Executors创建线程池呢?
      • 面试官:如果控制某一个方法允许并发访问线程的数量?
      • 面试官:好的,那该如何保证Java程序在多线程的情况下执行安全呢?
      • 面试官:你在项目中哪里用了多线程?
      • 面试官:谈谈你对ThreadLocal的理解
      • 面试官:好的,那你知道ThreadLocal的底层原理实现吗?
      • 面试官:好的,那关于ThreadLocal会导致内存溢出这个事情,了解吗?

面试官:聊一下并行和并发有什么区别?

候选人:

是这样的~~

现在都是多核CPU,在多核CPU下

并发是同一时间应对多件事情的能力,多个线程轮流使用一个或多个CPU

并行是同一时间动手做多件事情的能力,4核CPU同时执行4个线程

面试官:说一下线程和进程的区别?

候选人:

嗯,好~

  • 进程是正在运行程序的实例,进程中包含了线程,每个线程执行不同的任务
  • 不同的进程使用不同的内存空间,在当前进程下的所有线程可以共享内存空间
  • 线程更轻量,线程上下文切换成本一般上要比进程上下文切换低(上下文切换指的是从一个线程切换到另一个线程)

面试官:如果在java中创建线程有哪些方式?

候选人:

在java中一共有四种常见的创建方式,分别是:继承Thread类、实现runnable接口、实现Callable接口、线程池创建线程。通常情况下,我们项目中都会采用线程池的方式创建线程。

面试官:好的,刚才你说的runnable 和 callable 两个接口创建线程有什么不同呢?

候选人:

是这样的~

最主要的两个线程一个是有返回值,一个是没有返回值的。

Runnable 接口run方法无返回值;Callable接口call方法有返回值,是个泛型,和Future、FutureTask配合可以用来获取异步执行的结果

还有一个就是,他们异常处理也不一样。Runnable接口run方法只能抛出运行时异常,也无法捕获处理;Callable接口call方法允许抛出异常,可以获取异常信息

在实际开发中,如果需要拿到执行的结果,需要使用Callalbe接口创建线程,调用FutureTask.get()得到可以得到返回值,此方法会阻塞主进程的继续往下执行,如果不调用不会阻塞。

面试官:线程包括哪些状态,状态之间是如何变化的?

候选人:

在JDK中的Thread类中的枚举State里面定义了6中线程的状态分别是:新建、可运行、终结、阻塞、等待和有时限等待六种。

关于线程的状态切换情况比较多。我分别介绍一下

当一个线程对象被创建,但还未调用 start 方法时处于新建状态,调用了 start 方法,就会由新建进入可运行状态。如果线程内代码已经执行完毕,由可运行进入终结状态。当然这些是一个线程正常执行情况。

如果线程获取锁失败后,由可运行进入 Monitor 的阻塞队列阻塞,只有当持锁线程释放锁时,会按照一定规则唤醒阻塞队列中的阻塞线程,唤醒后的线程进入可运行状态

如果线程获取锁成功后,但由于条件不满足,调用了 wait() 方法,此时从可运行状态释放锁等待状态,当其它持锁线程调用 notify() 或 notifyAll() 方法,会恢复为可运行状态

还有一种情况是调用 sleep(long) 方法也会从可运行状态进入有时限等待状态,不需要主动唤醒,超时时间到自然恢复为可运行状态

面试官:嗯,好的,刚才你说的线程中的 wait 和 sleep方法有什么不同呢?

候选人:

它们两个的相同点是都可以让当前线程暂时放弃 CPU 的使用权,进入阻塞状态。

不同点主要有三个方面:

第一:方法归属不同

sleep(long) 是 Thread 的静态方法。而 wait(),是 Object 的成员方法,每个对象都有

第二:线程醒来时机不同

线程执行 sleep(long) 会在等待相应毫秒后醒来,而 wait() 需要被 notify 唤醒,wait() 如果不唤醒就一直等下去

第三:锁特性不同

wait 方法的调用必须先获取 wait 对象的锁,而 sleep 则无此限制

wait 方法执行后会释放对象锁,允许其它线程获得该对象锁(相当于我放弃 cpu,但你们还可以用)

而 sleep 如果在 synchronized 代码块中执行,并不会释放对象锁(相当于我放弃 cpu,你们也用不了)

面试官:好的,我现在举一个场景,你来分析一下怎么做,新建 T1、T2、T3 三个线程,如何保证它们按顺序执行?

候选人:

嗯~~,我思考一下 (适当的思考或想一下属于正常情况,脱口而出反而太假[背诵痕迹])

可以这么做,在多线程中有多种方法让线程按特定顺序执行,可以用线程类的join()方法在一个线程中启动另一个线程,另外一个线程完成该线程继续执行。

比如说:

使用join方法,T3调用T2,T2调用T1,这样就能确保T1就会先完成而T3最后完成

面试官:在我们使用线程的过程中,有两个方法。线程的 run()和 start()有什么区别?

候选人:

start方法用来启动线程,通过该线程调用run方法执行run方法中所定义的逻辑代码。start方法只能被调用一次。run方法封装了要被线程执行的代码,可以被调用多次。

面试官:那如何停止一个正在运行的线程呢?

候选人

有三种方式可以停止线程

第一:可以使用退出标志,使线程正常退出,也就是当run方法完成后线程终止,一般我们加一个标记

第二:可以使用线程的stop方法强行终止,不过一般不推荐,这个方法已作废

第三:可以使用线程的interrupt方法中断线程,内部其实也是使用中断标志来中断线程

我们项目中使用的话,建议使用第一种或第三种方式中断线程

面试官:讲一下synchronized关键字的底层原理?

候选人

嗯~~好的,

synchronized 底层使用的JVM级别中的Monitor 来决定当前线程是否获得了锁,如果某一个线程获得了锁,在没有释放锁之前,其他线程是不能或得到锁的。synchronized 属于悲观锁。

synchronized 因为需要依赖于JVM级别的Monitor ,相对性能也比较低。

面试官:好的,你能具体说下Monitor 吗?

候选人

monitor对象存在于每个Java对象的对象头中,synchronized 锁便是通过这种方式获取锁的,也是为什么Java中任意对象可以作为锁的原因

monitor内部维护了三个变量

  • WaitSet:保存处于Waiting状态的线程

  • EntryList:保存处于Blocked状态的线程

  • Owner:持有锁的线程

只有一个线程获取到的标志就是在monitor中设置成功了Owner,一个monitor中只能有一个Owner

在上锁的过程中,如果有其他线程也来抢锁,则进入EntryList 进行阻塞,当获得锁的线程执行完了,释放了锁,就会唤醒EntryList 中等待的线程竞争锁,竞争的时候是非公平的。

面试官:好的,那关于synchronized 的锁升级的情况了解吗?

候选人

嗯,知道一些(要谦虚)

Java中的synchronized有偏向锁、轻量级锁、重量级锁三种形式,分别对应了锁只被一个线程持有、不同线程交替持有锁、多线程竞争锁三种情况。

重量级锁:底层使用的Monitor实现,里面涉及到了用户态和内核态的切换、进程的上下文切换,成本较高,性能比较低。

轻量级锁:线程加锁的时间是错开的(也就是没有竞争),可以使用轻量级锁来优化。轻量级修改了对象头的锁标志,相对重量级锁性能提升很多。每次修改都是CAS操作,保证原子性

偏向锁:一段很长的时间内都只被一个线程使用锁,可以使用了偏向锁,在第一次获得锁时,会有一个CAS操作,之后该线程再获取锁,只需要判断mark word中是否是自己的线程id即可,而不是开销相对较大的CAS命令

一旦锁发生了竞争,都会升级为重量级锁

面试官:好的,刚才你说了synchronized它在高并发量的情况下,性能不高,在项目该如何控制使用锁呢?

候选人

嗯,其实,在高并发下,我们可以采用ReentrantLock来加锁。

面试官:嗯,那你说下ReentrantLock的使用方式和底层原理?

候选人

好的,

ReentrantLock是一个可重入锁:,调用 lock 方 法获取了锁之后,再次调用 lock,是不会再阻塞,内部直接增加重入次数 就行了,标识这个线程已经重复获取一把锁而不需要等待锁的释放。

ReentrantLock是属于juc报下的类,属于api层面的锁,跟synchronized一样,都是悲观锁。通过lock()用来获取锁,unlock()释放锁。

它的底层实现原理主要利用CAS+AQS队列来实现。它支持公平锁和非公平锁,两者的实现类似

构造方法接受一个可选的公平参数(默认非公平锁),当设置为true时,表示公平锁,否则为非公平锁。公平锁的效率往往没有非公平锁的效率高。

面试官:好的,刚才你说了CAS和AQS,你能介绍一下吗?

候选人

好的。

CAS的全称是: Compare And Swap(比较再交换);它体现的一种乐观锁的思想,在无锁状态下保证线程操作数据的原子性。

  • CAS使用到的地方很多:AQS框架、AtomicXXX类

  • 在操作共享变量的时候使用的自旋锁,效率上更高一些

  • CAS的底层是调用的Unsafe类中的方法,都是操作系统提供的,其他语言实现

AQS的话,其实就一个jdk提供的类AbstractQueuedSynchronizer,是阻塞式锁和相关的同步器工具的框架。

内部有一个属性 state 属性来表示资源的状态,默认state等于0,表示没有获取锁,state等于1的时候才标明获取到了锁。通过cas 机制设置 state 状态

在它的内部还提供了基于 FIFO 的等待队列,是一个双向列表,其中

  • tail 指向队列最后一个元素

  • head 指向队列中最久的一个元素

其中我们刚刚聊的ReentrantLock底层的实现就是一个AQS。

面试官:synchronized和Lock有什么区别 ?

候选人

嗯~~,好的,主要有三个方面不太一样

第一,语法层面

  • synchronized 是关键字,源码在 jvm 中,用 c++ 语言实现,退出同步代码块锁会自动释放
  • Lock 是接口,源码由 jdk 提供,用 java 语言实现,需要手动调用 unlock 方法释放锁

第二,功能层面

  • 二者均属于悲观锁、都具备基本的互斥、同步、锁重入功能
  • Lock 提供了许多 synchronized 不具备的功能,例如获取等待状态、公平锁、可打断、可超时、多条件变量,同时Lock 可以实现不同的场景,如 ReentrantLock, ReentrantReadWriteLock

第三,性能层面

  • 在没有竞争时,synchronized 做了很多优化,如偏向锁、轻量级锁,性能不赖
  • 在竞争激烈时,Lock 的实现通常会提供更好的性能

统合来看,需要根据不同的场景来选择不同的锁的使用。

面试官:死锁产生的条件是什么?

候选人

嗯,是这样的,一个线程需要同时获取多把锁,这时就容易发生死锁,举个例子来说:

t1 线程获得A对象锁,接下来想获取B对象的锁

t2 线程获得B对象锁,接下来想获取A对象的锁

这个时候t1线程和t2线程都在互相等待对方的锁,就产生了死锁

面试官:那如果产出了这样的,如何进行死锁诊断?

候选人

这个也很容易,我们只需要通过jdk自动的工具就能搞定

我们可以先通过jps来查看当前java程序运行的进程id

然后通过jstack来查看这个进程id,就能展示出来死锁的问题,并且,可以定位代码的具体行号范围,我们再去找到对应的代码进行排查就行了。

面试官:请谈谈你对 volatile 的理解

候选人

嗯~~

volatile 是一个关键字,可以修饰类的成员变量、类的静态成员变量,主要有两个功能

第一:保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的,volatile关键字会强制将修改的值立即写入主存。

第二: 禁止进行指令重排序,可以保证代码执行有序性。底层实现原理是,添加了一个内存屏障,通过插入内存屏障禁止在内存屏障前后的指令执行重排序优化

本文作者:接《集合相关面试题》

面试官:那你能聊一下ConcurrentHashMap的原理吗?

候选人

嗯好的,

ConcurrentHashMap 是一种线程安全的高效Map集合,jdk1.7和1.8也做了很多调整。

  • JDK1.7的底层采用是分段的数组+链表 实现
  • JDK1.8 采用的数据结构跟HashMap1.8的结构一样,数组+链表/红黑二叉树。

在jdk1.7中 ConcurrentHashMap 里包含一个 Segment 数组。Segment 的结构和HashMap类似,是一 种数组和链表结构,一个 Segment 包含一个 HashEntry 数组,每个 HashEntry 是一个链表结构 的元素,每个 Segment 守护着一个HashEntry数组里的元素,当对 HashEntry 数组的数据进行修 改时,必须首先获得对应的 Segment的锁。

Segment 是一种可重入的锁 ReentrantLock,每个 Segment 守护一个HashEntry 数组里得元 素,当对 HashEntry 数组的数据进行修改时,必须首先获得对应的 Segment 锁

在jdk1.8中的ConcurrentHashMap 做了较大的优化,性能提升了不少。首先是它的数据结构与jdk1.8的hashMap数据结构完全一致。其次是放弃了Segment臃肿的设计,取而代之的是采用Node + CAS + Synchronized来保 证并发安全进行实现,synchronized只锁定当前链表或红黑二叉树的首节点,这样只要hash不冲 突,就不会产生并发 , 效率得到提升

面试官:线程池的种类有哪些?

候选人

嗯!是这样

在jdk中默认提供了4中方式创建线程池

第一个是:newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回 收空闲线程,若无可回收,则新建线程。

第二个是:newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列 中等待。

第三个是:newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。

第四个是:newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任 务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

面试官:线程池的核心参数有哪些?

候选人

在线程池中一共有7个核心参数:

  1. corePoolSize 核心线程数目 - 池中会保留的最多线程数

  2. maximumPoolSize 最大线程数目 - 核心线程+救急线程的最大数目

  3. keepAliveTime 生存时间 - 救急线程的生存时间,生存时间内没有新任务,此线程资源会释放

  4. unit 时间单位 - 救急线程的生存时间单位,如秒、毫秒等

  5. workQueue - 当没有空闲核心线程时,新来任务会加入到此队列排队,队列满会创建救急线程执行任务

  6. threadFactory 线程工厂 - 可以定制线程对象的创建,例如设置线程名字、是否是守护线程等

  7. handler 拒绝策略 - 当所有线程都在繁忙,workQueue 也放满时,会触发拒绝策略

在拒绝策略中又有4中拒绝策略

当线程数过多以后,第一种是抛异常、第二种是由调用者执行任务、第三是丢弃当前的任务,第四是丢弃最早排队任务。默认是直接抛异常。

面试官:如何确定核心线程池呢?

候选人

是这样的,我们公司当时有一些规范,为了减少线程上下文的切换,要根据当时部署的服务器的CPU核数来决定,我们规则是:CPU核数+1就是最终的核心线程数。

面试官:线程池的执行原理知道吗?

候选人

嗯~,它是这样的

首先判断线程池里的核心线程是否都在执行任务,如果不是则创建一个新的工作线程来执行任务。如果核心线程都在执行任务,则线程池判断工作队列是否已满,如果工作队列没有满,则将新提交的任务存储在这个工作队 列里。如果工作队列满了,则判断线程池里的线程是否都处于工作状态,如果没有,则创建一个新的工作线程来执行任 务。如果已经满了,则交给拒绝策略来处理这个任务。

面试官:为什么不建议使用Executors创建线程池呢?

候选人

好的,其实这个事情在阿里提供的最新开发手册《Java开发手册-嵩山版》中也提到了

主要原因是如果使用Executors创建线程池的话,它允许的请求队列默认长度是Integer.MAX_VALUE,这样的话,有可能导致堆积大量的请求,从而导致OOM(内存溢出)。

所以,我们一般推荐使用ThreadPoolExecutor来创建线程池,这样可以明确规定线程池的参数,避免资源的耗尽。

面试官:如果控制某一个方法允许并发访问线程的数量?

候选人

嗯~~,我想一下

在jdk中提供了一个Semaphore[seməfɔːr]类(信号量)

它提供了两个方法,semaphore.acquire() 请求信号量,可以限制线程的个数,是一个正数,如果信号量是-1,就代表已经用完了信号量,其他线程需要阻塞了

第二个方法是semaphore.release(),代表是释放一个信号量,此时信号量的个数+1

面试官:好的,那该如何保证Java程序在多线程的情况下执行安全呢?

候选人

嗯,刚才讲过了导致线程安全的原因,如果解决的话,jdk中也提供了很多的类帮助我们解决多线程安全的问题,比如:

  • JDK Atomic开头的原子类、synchronized、LOCK,可以解决原子性问题
  • synchronized、volatile、LOCK,可以解决可见性问题
  • Happens-Before 规则可以解决有序性问题

面试官:你在项目中哪里用了多线程?

候选人

嗯~~,我想一下当时的场景[根据自己简历上的模块设计多线程场景]

参考场景一:

es数据批量导入

在我们项目上线之前,我们需要把数据量的数据一次性的同步到es索引库中,但是当时的数据好像是1000万左右,一次性读取数据肯定不行(oom异常),如果分批执行的话,耗时也太久了。所以,当时我就想到可以使用线程池的方式导入,利用CountDownLatch+Future来控制,就能大大提升导入的时间。

参考场景二:

在我做那个xx电商网站的时候,里面有一个数据汇总的功能,在用户下单之后需要查询订单信息,也需要获得订单中的商品详细信息(可能是多个),还需要查看物流发货信息。因为它们三个对应的分别三个微服务,如果一个一个的操作的话,互相等待的时间比较长。所以,我当时就想到可以使用线程池,让多个线程同时处理,最终再汇总结果就可以了,当然里面需要用到Future来获取每个线程执行之后的结果才行

参考场景三:

《黑马头条》项目中使用的

我当时做了一个文章搜索的功能,用户输入关键字要搜索文章,同时需要保存用户的搜索记录(搜索历史),这块我设计的时候,为了不影响用户的正常搜索,我们采用的异步的方式进行保存的,为了提升性能,我们加入了线程池,也就说在调用异步方法的时候,直接从线程池中获取线程使用

面试官:谈谈你对ThreadLocal的理解

候选人

嗯,是这样的~~

ThreadLocal 主要功能有两个,第一个是可以实现资源对象的线程隔离,让每个线程各用各的资源对象,避免争用引发的线程安全问题,第二个是实现了线程内的资源共享

面试官:好的,那你知道ThreadLocal的底层原理实现吗?

候选人

嗯,知道一些~

在ThreadLocal内部维护了一个一个 ThreadLocalMap 类型的成员变量,用来存储资源对象

当我们调用 set 方法,就是以 ThreadLocal 自己作为 key,资源对象作为 value,放入当前线程的 ThreadLocalMap 集合中

当调用 get 方法,就是以 ThreadLocal 自己作为 key,到当前线程中查找关联的资源值

当调用 remove 方法,就是以 ThreadLocal 自己作为 key,移除当前线程关联的资源值

面试官:好的,那关于ThreadLocal会导致内存溢出这个事情,了解吗?

候选人

嗯,我之前看过源码,我想一下~~

是应为ThreadLocalMap 中的 key 被设计为弱引用,它是被动的被GC调用释放key,不过关键的是只有key可以得到内存释放,而value不会,因为value是一个强引用。

在使用ThreadLocal 时都把它作为静态变量(即强引用),因此无法被动依靠 GC 回收,建议主动的remove 释放 key,这样就能避免内存溢出。

往期文章推荐

  • 细谈left join和join
  • JUC详解
  • 缓存穿透、缓存击穿和缓存雪崩
  • 消息中间件相关面试题
  • Java集合相关面试题
  • Java集合详解
  • 微服务相关面试题
  • redis相关面试题

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

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

相关文章

亲测好用-obsidian无法打开插件库安装或更新的解决办法-结合FastGithub

写在前面 经过半年左右时间的使用情况验证该方案稳定可靠。 方案:插件“Plugin Proxy” 软件“FastGithub” 效果: 插件“Plugin Proxy” 下载地址: https://github.com/gslnzfq/obsidian-proxy-server 插件安装: 插件设置为…

虚拟人三维动画宣传片案例分享 | 广州“五羊”城市文化IP商业体裸眼3D广告影片

随着时代的发展元宇宙的助推,裸眼3D形式的宣传方式逐渐出现在大众眼前。以数字人IP的3D立体效果吸引大众目光,让其驻足拍照、录视频分享至社交平台,为企业品牌带来高频传播价值。 近日,广州“五羊”城市文化IP裸眼3D广告宣传片在广…

设计模式解析之模板方法模式:设计灵活可扩展的算法框架

目录 1. 引言2. 概要2.1 概念2.2 结构2.3 类图2.4 工作流程 3. 应用场景3.1 适用情况:3.2 常见例子: 4. 代码衍化过程初版:甲乙学生都抄试卷第二版:提炼代码第三版:抽象出算法骨架第四版:模板方法变化过程总…

视频转gif的几个方法

视频转gif的软件,视频转gif的几个方法~什么是gif图?其实简单一点来说就是一张会动的图片,gif既有图片的属性,也具有视频的特点,因为严格来说gif属于一直图片文件的特殊,但是它的展现方式又和视频非常的像。…

【计算机视觉 | 图像模型】常见的计算机视觉 image model(CNNs Transformers) 的介绍合集(二)

文章目录 一、SqueezeNet二、Inception-v3三、Visual Geometry Group 19 Layer CNN四、MobileNetV1五、Data-efficient Image Transformer六、MobileNetV3七、self-DIstillation with NO labels(DINO)八、MLP-Mixer九、WideResNet十、Darknet-19十一、HR…

普通项目(java项目)使用lombok报错

java: JPS incremental annotation processing is disabled. Compilation results on partial recompilation may be inaccurate. Use build process "jps.track.ap.dependencies" VM flag to enable/disable incremental annotation processing environment. 解决方…

【ROS】机器人使用Nomachine进行远程控制

官网:NoMachine - Free Remote Desktop for Everybody 支持的系统: WindowsMacLinux 树莓派其他ARM板IOSAndroid 由于网速问题,可以使用我下载好的:(8.8.1_1) 链接:https://pan.baidu.com/s/…

CSS 修改el-calendar的样式,自定义样式

需求&#xff1a;自定义elementui的日历的样式&#xff1b;给符合条件的时间展示红点。 elementui的原始样式&#xff1a; 目标样式&#xff1a; 代码实现&#xff1a; html: <el-calendar v-model"calendarValue"><template slot"dateCell" …

AI人工智能时代: 大一新生如何入手IT行业?

AI人工智能时代: 大一新生如何入手IT行业? AI人工智能时代: 大一新生如何入手IT行业?引言1. 了解IT行业的基础1.1 什么是IT&#xff1f;1.2 AI是如何改变IT行业的&#xff1f; 2. 如何选择合适的编程语言2.1 常见的编程语言有哪些&#xff1f;2.2 如何选择&#xff1f; 3. 制…

OPCEnum作用OPC常见通讯问题

目录 1 OPCEnum作用 1.1 检索server列表 1.2 检索失败原因 1.3 是否可以没有OPCEnum 2 OPC通讯常见问题 2.1 不能浏览OPCServer列表 2.2不能连接远程OPC Server 2.3 数据显示Bad 2.4 OPC通讯错误码 1 OPCEnum作用 你知道OPCEnum有什么用吗&#xff1f;看完本文你就对O…

Web安全(文件上传的漏洞)

文件上传漏洞和危害 文件上传漏洞是指网络攻击者上传了一个可执行的文件到服务器上&#xff0c;当开发者没有对该文件进行合理的校验及处理的时候&#xff0c;很有可能让程序执行这个上传文件导致安全漏洞。大部分网站都会有文件上传的功能&#xff0c;例如头像、图片、视频等…

如何从Docker镜像中提取恶意文件

当发生容器安全事件时&#xff0c;需要从容器或镜像中提取恶意文件进行分析和处理。 本文主要介绍3种常见的方法&#xff1a; (1) 从运行的容器中复制文件 首先&#xff0c;需要从镜像运行启动一个容器&#xff0c;然后&#xff0c;使用docker cp命令从容器中提取文件到宿主机。…

Flutter——启动页白屏的优化

flutter启动页白屏的优化&#xff1a;使用图片替代白屏 结构图 核心的代码如上图&#xff0c;修改两个launch_background.xml里的代码为&#xff1a; <item><bitmapandroid:gravity"center"android:src"mipmap/ic_launcher" /></item>…

如何使用极狐GitLab 支持 ISO 27001 合规

目录 组织控制 技术控制 了解更多 本文来源&#xff1a;about.gitlab.com 作者&#xff1a;Joseph Longo 译者&#xff1a;武让 极狐GitLab 高级解决方案架构师 作为一体化平台&#xff0c;通过极狐GitLab 可以很容易实现 DevSecOps 全生命周期管理。极狐GitLab 使开发人员能…

numpy笔记:广播应用:实现一个对比学习的loss function

论文笔记&#xff1a;SUPERVISED CONTRASTIVE REGRESSION_UQI-LIUWJ的博客-CSDN博客的loss function 出于简单考虑&#xff0c;我们令vy&#xff0c;同时sim就是两个向量的内积&#xff0c;d是两个向量逐元素差的绝对值之和 1 数据 import numpy as npanp.array([[1,3,4],[2,…

点评项目核心内容

目录 拦截器设置 集群的session共享问题 基于redis实现共享session登录 创建bean对象技巧 什么是缓存 使用缓存来处理对象 使用String类型缓存来处理集合 缓存更新策略 主动更新策略 缓存穿透 空串""和null的区别 缓存null值解决穿透问题 缓存雪崩 缓存击穿…

二刷力扣--字符串

字符串 摘自Python文档-标准库&#xff1a; 在Python中&#xff0c; 字符串是由 Unicode 码位构成的不可变序列。 由于不存在单独的“字符”类型&#xff0c;对字符串做索引操作将产生一个长度为 1 的字符串。 也就是说&#xff0c;对于一个非空字符串 s, s[0] s[0:1]。 不存…

震惊!idea里斗地主还不算我还要玩大富翁!vscode也安排一个

1. 介绍 本来呢前段时间大约是三四月份吧&#xff0c;摸鱼的时候找到了这个插件 xechat-idea, 可以在idea里边摸鱼&#xff0c;斗地主&#xff0c;聊天等,项目地址为 https://github.com/anlingyi/xechat-idea , QQ群号754126966 然后我尝试着开发了两个游戏 一个是大富翁 一个…

Kubernetes(K8S)集群部署

目录 一、创建3台虚拟机 二、为每台虚拟机安装Docker 三、安装kubelet 3.1 安装要求 3.2 为每台服务器完成前置设置 3.3 为每台服务器安装kubelet、kubeadm、kubectl 四、使用kubeadm引导集群 4.1 master服务器 4.2 node1、node2服务器 4.3 初始化主节点 4.4 work节…

使用内网端口映射方案,轻松实现U8用友ERP的本地部署异地远程访问——“cpolar内网穿透”

文章目录 前言1. 服务器本机安装U8并调试设置2. 用友U8借助cpolar实现企业远程办公2.1 在被控端电脑上&#xff0c;点击开始菜单栏&#xff0c;打开设置——系统2.2 找到远程桌面2.3 启用远程桌面 3. 安装cpolar内网穿透3.1 注册cpolar账号3.2 下载cpolar客户端 4. 获取远程桌面…