面试专区|【43道Java多线程高频题整理(附答案背诵版)】

请说一下进程和线程的区别?

进程和线程都是操作系统进行任务管理的基本单位,但它们之间存在一些关键的区别。

  1. 独立性:进程是操作系统分配资源(如CPU时间、内存空间等)的基本单位,它是相互独立的,一个进程内的错误不会影响其他进程。而线程是进程内的执行单元,同一进程内的线程共享进程的资源,一个线程的错误可能会影响同一进程内的其他线程。

  2. 开销:创建或删除进程的开销通常比创建或删除线程的开销大,因为进程之间没有共享资源,每个进程都有自己的地址空间,切换进程需要更多的时间和资源。而线程由于共享同一进程的资源,创建、删除和切换的开销相对较小。

  3. 通信方式:由于进程是独立的,所以进程间的通信(IPC, Inter-Process Communication)需要使用特殊的技术,如管道、消息队列、信号量等。而线程由于共享同一进程的资源,线程间的通信比较简单,可以直接通过读写进程中的共享变量进行。

  4. 应用场景:进程适用于需要进行大量计算并且需要独立运行的任务,如运行一个游戏或者一个文档编辑器。而线程适用于在同一应用程序中需要并行处理的任务,如在一个网页浏览器中,一个线程用于显示网页,另一个线程用于下载文件。

解释一下进程之间怎么进行通信?

进程间的通信(Inter-Process Communication,IPC)是为了让不同的进程能共享数据和信息。在操作系统中,有多种进程间通信的方式:

  1. 管道(Pipe):这是最简单的IPC形式,数据从一个进程流向另一个进程。但是,管道通常只能在具有共同祖先的两个进程之间使用。这种方法主要用于数据的一对一通信。

  2. 消息队列(Message Queue):它允许多个进程添加和读取数据,数据被组织成一种特定的格式(消息)。每个消息都有一个类型或优先级,进程可以按照类型或优先级读取消息。

  3. 共享内存(Shared Memory):在这种模式下,多个进程可以访问同一块内存区域。通常,一个进程会创建一块共享内存,并告诉其他进程这块内存的地址。这是最快的IPC方法,因为数据不需要在进程之间复制。但是,它需要一些同步机制,如信号量,以避免同时访问共享内存的冲突。

  4. 信号量(Semaphore):信号量主要用于同步,以避免多个进程同时访问同一资源,例如共享内存。它是一个计数器,可以表示可用资源的数量。

  5. 套接字(Socket):套接字可以用于不同机器上的进程间的通信,也可以用于同一机器上的进程间的通信。套接字支持TCP和UDP协议,因此可以用于网络通信。

以上这些方式都可以用于进程间的通信,具体使用哪种方式,要根据应用的需求来决定。

解释一下线程之间怎么进行通信?

线程间通信主要是为了同步和数据交换。由于线程是在同一进程中,他们共享同一地址空间,因此相对来说线程间的通信比进程间的通信要简单一些。以下是一些常用的线程间通信方式:

  1. 共享变量:由于线程共享内存,因此一个线程可以访问另一个线程的变量。但是,当两个线程需要访问同一个变量时,可能会产生冲突。因此,需要使用某种同步机制(如锁或信号量)来保护共享变量。

  2. 锁机制:锁是一种保护资源不被多个线程同时访问的机制。当一个线程需要访问一个被锁保护的资源时,它必须首先获得锁。如果锁已经被另一个线程占用,那么这个线程就会等待,直到锁变为可用状态。

  3. 条件变量:条件变量是一种让线程等待某个条件发生的机制。一个线程可以等待一个条件变量,而另一个线程则可以发出信号来表示某个条件已经发生,这会唤醒等待的线程。

  4. 信号量:信号量是一种更为通用的同步机制,它可以避免同时访问共享资源的冲突,并可以用于实现复杂的同步策略。

  5. 消息队列:虽然消息队列通常用于进程间通信,但是也可以用于线程间通信。线程可以将消息发送到消息队列,而其他线程则可以从消息队列中读取消息。

  6. 管道和套接字:这些也可以用于线程间的通信,但是通常不这么使用,因为它们的开销比直接使用共享变量要大。

以上就是线程间通信的常用方式,具体使用哪种方式,需要根据实际的需求和条件来决定。

解释一下原子性?

原子性是并发编程中的一个关键概念,它的意思是一个操作要么完全执行,要么完全不执行,不会被其他线程中断。换句话说,一个原子操作在执行过程中不会被任何其他的线程或者进程干扰,它是一个不可分割的工作单元。

例如,假设我们有一个简单的操作:i++,这个操作看起来是原子的,但实际上它不是。这个操作至少包含以下三个步骤:读取变量i的值,将值加1,然后将新的值写回内存。在并发环境中,如果这个操作不是原子的,那么可能会出现问题。例如,两个线程同时读取变量i的值,然后都将其加1,然后写回内存,这样变量i的值只增加了1,而不是2,这就是所谓的竞争条件。

在Java中,对基本数据类型(除了long和double)的读取和写入操作是原子的。但是,像i++这样的复合操作不是原子的,需要使用synchronized关键字或者java.util.concurrent包中的类(如AtomicInteger)来保证其原子性。

总的来说,原子性是确保数据在并发环境下正确访问的重要概念。

i++、i-- 操作是原子性的吗?

除了 long 和 double,其他的基本数据类型的读取和赋值操作都是原子性的。

int x = 100;
int y = x;
x++;
x = x + 1;

只有语句1是原子性的,其他的3个语句都不是原子性操作,因为它们都包含两个及以上的操作,它们都先要去读取《变量的值,再将计算后 x 的新值写入到主内存中,几个操作合起来就不是原子性操作了。

解释一下可见性?

在并发编程中,可见性是一个非常重要的概念。当我们谈论"可见性"时,我们讨论的是一个线程修改的状态对于另一个线程是什么时候可见的,即一个线程对共享变量值的修改何时能够被其他线程看到。

这是一个关键的问题,因为在现代计算机系统中,每个CPU都有缓存(Cache)。为了提高性能,系统通常会将主内存中的数据缓存到CPU近距离的缓存中。如果一个线程在CPU A上运行,并修改了一个变量,这个变量的新值可能会被存储在CPU A的缓存中,而不是主内存中。此时,如果另一个线程在CPU B上运行,并试图读取这个变量,它可能会看到这个变量的旧值。

为了解决这个问题,Java提供了一些机制来确保可见性,如volatile关键字、synchronized关键字和java.util.concurrent包中的类。例如,如果一个变量被声明为volatile,那么JVM就会确保任何对这个变量的写入操作都会立即刷新到主内存中,任何读取这个变量的操作都会从主内存中读取最新的值,从而保证了变量值的可见性。

总的来说,可见性问题是并发编程中需要特别注意的问题,否则可能会出现一些难以预料和调试的错误。

怎么保证可见性?

在Java中,有几种方式可以保证数据在多线程环境下的可见性:

  1. Synchronized:synchronized关键字可以确保可见性。当一个线程进入一个synchronized方法或块时,它会读取变量的最新值。当线程退出synchronized方法或块时,它会将在此方法或块内对这些变量的任何更改写入主内存。因此,synchronized不仅可以保证原子性,也可以保证可见性。

  2. Volatile:volatile关键字也可以确保可见性。如果一个变量被声明为volatile,那么JVM就会确保任何对这个变量的写入操作都会立即刷新到主内存中,任何读取这个变量的操作都会从主内存中读取最新的值。

  3. Final:对于final字段,JVM确保初始化过程的安全发布,这意味着一旦构造函数设置了final字段的值,任何线程都可以看到这个字段的正确值。

  4. 使用java.util.concurrent包中的类:Java提供了一些并发工具类,如AtomicIntegerAtomicLong等,这些类内部都有保证可见性的机制。

以上就是Java中保证可见性的几种常见方式,使用哪种方式,需要根据实际的需求和条件来决定。

final 可以保证可见性吗?

是的,final关键字可以保证可见性。

在Java中,final关键字用于声明一个常量,也就是说,一旦赋值后,就不能再改变。这个特性使得final字段在构造函数中赋值后,所有线程都可以看到这个字段的正确值,从而保证了可见性。

具体来说,当一个对象被创建时,如果它的final字段在构造函数中被初始化,那么当构造函数结束时,任何获取到该对象引用的线程都将看到final字段已经被初始化完成的值,即使没有使用锁或者其他同步机制。

这是因为Java内存模型为final字段提供了一个重排序规则:在构造函数中对final字段的写入,和随后把这个被构造对象的引用赋给一个引用变量,这两个操作不能重排序。这就保证了一旦一个对象被构造完成,并且该对象的引用被别的线程获得,那么这个线程能看到该对象final字段的正确值。

需要注意的是,这个规则只适用于final字段,对于非final字段,如果没有使用适当的同步机制,仍然可能看到其不正确的值。

解释一下有序性?

public void clear(){Node<K,V>[] tab;modCount++;if((tab = table) != null && size > 0){size = 0;for(int i = 0; i < tab.length; ++i)tab[i] = null;}
}

程序的执行顺序必须按照代码的先后顺序来执行

为什么要使用多线程?

多线程的主要用途是提高应用程序的性能和响应速度。

  1. 利用多核CPU资源:在现代多核CPU硬件上,多线程可以帮助我们充分利用CPU资源,实现并行处理,提高程序的执行效率。比如,如果你需要执行一个复杂的计算任务,你可以将其拆分成多个子任务,然后并行的在多个线程上执行,从而提高整体的执行速度。

  2. 提高响应性:在某些情况下,我们可能希望一部分代码能够立即响应用户的交互,而不必等待其他耗时的操作完成。比如,一个文本编辑器在保存大文件时,我们并不希望整个界面冻结,无法进行编辑或者响应其他用户操作。这种情况下,我们可以将文件保存的操作放在一个单独的线程中执行,主线程则继续响应用户的其他操作。

  3. 简化编程模型:在某些情况下,多线程可以使得程序设计变得更加简单。比如,一个服务器程序需要同时处理多个客户端的请求,采用多线程模型,每到来一个请求就启动一个线程进行处理,可以使得程序设计变得简单直接。

总的来说,多线程能够帮助我们实现并行处理,提高程序的性能和响应速度,同时也能简化一些复杂的编程模型。

创建线程的几种方式有哪些?

在Java中,主要有四种创建线程的方式:

  1. 继承Thread类:创建一个新的类作为Thread类的子类,然后重写Thread类的run()方法,将创建的线程要执行的代码放在run()方法中。然后创建子类的实例并调用其start()方法来启动线程。
class MyThread extends Thread {public void run(){// 代码}
}
public class Main {public static void main(String[] args) {MyThread t = new MyThread();t.start();}
}
  1. 实现Runnable接口:创建一个新的类来实现Runnable接口,然后重写Runnable接口的run()方法。然后创建Runnable子类的实例,并以此实例作为Thread的参数来创建Thread对象,该Thread对象才是真正的线程对象。
class MyRunnable implements Runnable {public void run(){// 代码}
}
public class Main {public static void main(String[] args) {MyRunnable r = new MyRunnable();Thread t = new Thread(r);t.start();}
}
  1. 实现Callable和Future接口:与Runnable相比,Callable可以有返回值,返回值通过FutureTask进行封装。
class MyCallable implements Callable<Integer> {public Integer call() {// 代码,返回值为Integer}
}
public class Main {public static void main(String[] args) throws Exception {MyCallable c = new MyCallable();FutureTask<Integer> task = new FutureTask<>(c);new Thread(task).start();Integer result = task.get(); //获取线程返回值}
}
  1. 使用线程池:Java 1.5开始,可以通过Executor框架在Java中创建线程池。
public class Main {public static void main(String[] args) {ExecutorService executor = Executors.newFixedThreadPool(5);for (int i = 0; i < 10; i++) {executor.execute(new Runnable() {public void run() {// 代码}});}executor.shutdown();}
}

以上就是Java创建线程的四种方式,各有适用的场景和优点。

守护线程是什么?

在Java中,线程分为两种类型:用户线程和守护线程。

守护线程是一种特殊的线程,它在后台默默地完成一些系统性的服务,比如垃圾回收线程,JIT线程就可以理解为守护线程。这些线程并不属于程序中不可或缺的部分。因此,当所有的非守护线程结束时,Java虚拟机也就退出了。守护线程并不会阻止Java虚拟机退出。

设置守护线程的方法是调用Thread对象的setDaemon(true)方法。需要注意的是,一定要在调用线程的start()方法之前设置。

这是一个简单的守护线程的例子:

public class DaemonThreadExample extends Thread {public void run() {while (true) {processSomething();}}private void processSomething() {// processing some jobtry {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}}public static void main(String[] args) {Thread t = new DaemonThreadExample();t.setDaemon(true);t.start();// continue program// daemon thread will automatically exit when all user threads are done.}
}

在这个例子中,DaemonThreadExample是一个守护线程,它会在所有用户线程(这里指主线程)结束后自动退出。

线程的状态有哪几种? 怎么转换的?

Java线程在运行生命周期中主要有五种状态:

  1. 新建(New):线程对象被创建后就进入了新建状态,例如:Thread thread = new Thread()。

  2. 就绪(Runnable):当调用线程对象的start()方法(thread.start()),线程就进入就绪状态。就绪状态的线程被调度器(Scheduler)选中后,就会被赋予CPU资源,此时线程便进入了运行(Running)状态。

  3. 运行(Running):线程获取到CPU资源并执行其run()方法。

  4. 阻塞(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:等待阻塞(通过调用线程的wait()方法,线程放弃对象锁,进入等待池中,等待notify()/notifyAll()方法的唤醒,或者等待的时间到达,线程重新获得对象锁进入就绪状态);同步阻塞(线程在获取synchronized同步锁失败(因为锁被其他线程所持有),它会进入同步阻塞状态);其他阻塞(通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或超时、或者I/O处理完毕时,线程重新进入就绪状态)。

  5. 死亡(Dead):线程run()、main() 方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生。

线程状态的转换关系如下:新建状态通过start()方法转换为就绪状态,就绪状态通过获取CPU资源转换为运行状态,运行状态通过yield()方法可以转换为就绪状态,运行状态通过sleep()、wait()、join()、阻塞I/O或获取不到同步锁可以转换为阻塞状态,阻塞状态解除阻塞后可以转换为就绪状态,运行状态结束生命周期转换为死亡状态。

线程的优先级的作用是?

线程的优先级是一个整数,其范围从Thread.MIN_PRIORITY(值为1)到Thread.MAX_PRIORITY(值为10)。默认的优先级是Thread.NORM_PRIORITY(值为5)。

线程优先级的主要作用是决定线程获取CPU执行权的顺序。优先级高的线程比优先级低的线程会有更大的可能性获得CPU的执行时间,也就是说优先级高的线程更有可能先执行。但是需要注意的是,线程优先级并不能保证线程的执行顺序,线程的调度行为依赖于操作系统的具体实现。

在Java中,我们可以通过Thread类的setPriority(int newPriority)方法来设置线程的优先级,通过getPriority()方法来获取线程的优先级。

需要注意的是,不同的操作系统对于线程优先级的处理可能会有所不同,所以在进行跨平台开发时,过分依赖线程优先级可能会导致程序的行为不可预知。因此,一般推荐使用其他同步机制,比如锁和信号量,来控制线程的执行顺序,而不是过分依赖线程的优先

i++ 是线程安全的吗?

i++并不是线程安全的。

i++这个操作实际上包含了三个步骤:读取i的值,对i加1,将新值写回到i。在多线程环境下,这三个步骤可能会被打断,例如,一个线程在读取了i的值并且加1之后,但还没来得及将新值写回i,这时另一个线程也来读取i的值并加1,然后写回i,这时第一个线程再将它计算的值写回i,就会覆盖掉第二个线程的计算结果,导致实际上i只增加了1,而不是2。这就是所谓的线程安全问题。

对于这种情况,我们通常会使用同步机制(如synchronized关键字)或者使用原子操作类(如AtomicInteger)来保证操作的原子性,从而避免线程安全问题。

例如,使用AtomicInteger:

import java.util.concurrent.atomic.AtomicInteger;public class Main {private static AtomicInteger atomicI = new AtomicInteger(0);public static void safeIncrement() {atomicI.incrementAndGet();}
}

在这个例子中,我们使用了AtomicInteger的incrementAndGet方法,这个方法是线程安全的,它会以原子方式将当前值加1,并返回新的值,所以我们可以确保在多线程环境下,每次调用safeIncrement方法,atomicI的值都会正确地增加1。

由于内容太多,更多内容以链接形势给大家,点击进去就是答案了

16. 说说 JDK1.6 之后的 synchronized 关键字底层做了哪些优化,可以详细介绍一下这些优化吗?

17. 谈谈 synchronized 和 ReenTrantLock 的区别?

18. synchronized 和 volatile 的区别是什么?

19. 谈一下你对 volatile 关键字的理解?

20. 说下对 ReentrantReadWriteLock 的理解?

21. 说下对悲观锁和乐观锁的理解?

22. 乐观锁常见的两种实现方式是什么?

23. 乐观锁的缺点有哪些?

24. CAS 和 synchronized 的使用场景?

25. 简单说下对 Java 中的原子类的理解?

26. atomic 的原理是什么?

27. 说下对同步器 AQS 的理解?

28. AQS 的原理是什么?

29. AQS 对资源的共享模式有哪些?

30. AQS 底层使用了模板方法模式,你能说出几个需要重写的方法吗?

31. 说下对信号量 Semaphore 的理解?

32. CountDownLatch 和 CyclicBarrier 有什么区别?

33. 说下对线程池的理解?为什么要使用线程池?

34. 创建线程池的参数有哪些?

35. 如何创建线程池?

36. 线程池中的的线程数一般怎么设置?需要考虑哪些问题?

37. 执行 execute() 方法和 submit() 方法的区别是什么呢?

38. 说下对 Fork和Join 并行计算框架的理解?

39. JDK 中提供了哪些并发容器?

40. 谈谈对 CopyOnWriteArrayList 的理解?

41. 谈谈对 BlockingQueue 的理解?分别有哪些实现类?

42. 谈谈对 ConcurrentSkipListMap 的理解?

43. 说下你对 Java 内存模型的理解?

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

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

相关文章

数据结构之ArrayList与顺序表(下)

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;数据结构&#xff08;Java版&#xff09; 目录 ArrayList的具体使用 118. 杨辉三角 扑克洗牌算法 接上篇&#xff1a;数据结构之ArrayLis…

【环境搭建】2.阿里云ECS服务器 安装MySQL

在阿里云的 Alibaba Cloud Linux 3.2104 LTS 64位系统上安装 MySQL 8&#xff0c;可以按照以下步骤进行&#xff1a; 1.更新系统软件包&#xff1a; 首先&#xff0c;更新系统软件包以确保所有软件包都是最新的&#xff1a; sudo yum update -y2.下载 MySQL 8 官方 Yum 仓库…

【Python列表解锁】:掌握序列精髓,驾驭动态数据集合

文章目录 &#x1f680;一、列表&#x1f308;二、常规操作&#x1f4a5;增&#x1f4a5;删&#x1f4a5;改&#x1f4a5;查 ⭐三、补充操作 &#x1f680;一、列表 列表是一个能够存储多个同一或不同元素的序列 列表&#xff1a;list ---- [] 列表属于序列类型&#xff08;容器…

【Java面试】十二、Kafka相关

文章目录 1、Kafka如何保证消息不丢失1.1 生产者发消息到Brocker丢失&#xff1a;设置异步发送1.2 消息在Broker存储时丢失&#xff1a;发送确认机制1.3 消费者从Brocker接收消息丢失1.4 同步 异步组合提交偏移量 2、Kafka如何保证消费的顺序性3、Kafka高可用机制3.1 集群模式…

深度搜索算法2(c++)

红与黑 题目描述 有一间长方形的房子&#xff0c;地上铺了红色、黑色两种颜色的正方形瓷砖。你站在其中一块黑色的瓷砖上&#xff0c;只能向相邻的黑 色瓷砖移动。请写一个程序&#xff0c;计算你总共能够到达多少块黑色的瓷砖。 输入 包括多组数据。每组数据的第一行是两个…

Vue.js ECharts使用

一、介绍 ECharts 是一个使用 JavaScript 实现的开源可视化库&#xff0c;涵盖各行业图表&#xff0c;满足各种需求。ECharts 提供了丰富的图表类型和交互能力&#xff0c;使用户能够通过简单的配置生成各种各样的图表&#xff0c;包括但不限于折线图、柱状图、散点图、饼图、雷…

02Linux文件,目录,过滤,管道常用命令

Linux基础概述 Linux基础目录 Linux没有盘符这个概念, 只有一个顶级根目录 /, 所有文件都在它下面 在Windows系统中路径之间的层级关系使用/来表示在Linux系统中路径之间的层级关系使用/来表示,出现在开头的/表示根目录, /home/a.txt表示根目录下的home文件夹内有a.txt文件 …

2024年6月8日_第十五周_周六_分享技术:麻将技术

四人下午打麻将大纲 一、背景设定 时间&#xff1a;一个悠闲的下午地点&#xff1a;某人家中的麻将室或客厅人物&#xff1a; A先生&#xff1a;一个经验丰富的麻将老手&#xff0c;喜欢沉稳地分析牌局B女士&#xff1a;麻将新手&#xff0c;但好学不倦&#xff0c;喜欢尝试新…

微服务开发与实战Day03

一、导入黑马商城项目 资料文档&#xff1a;Docs 1. 安装MySQL ①删除root目录下的mysql rm -rf mysql/ ②把课前资料里的mysql目录上传到root目录下 ③创建一个通用网络 docker network create hm-net ④使用下面的命令安装MySQL docker run -d \--name mysql \-p 330…

自然资源-国土空间规划术语集合

自然资源-国土空间规划术语集合 国土空间&#xff1a; 国家主权与主权权利管辖下的地域空间&#xff0c;是人类生产生活的载体和场所&#xff0c;包括陆地国土空间和海洋国土空间。 国土空间规划&#xff1a; 对一定区域国土空间开发保护在空间和时间上作出的安排&#xff…

C++ OpenCV 图像分类魔法:探索神奇的模型与代码

⭐️我叫忆_恒心&#xff0c;一名喜欢书写博客的研究生&#x1f468;‍&#x1f393;。 如果觉得本文能帮到您&#xff0c;麻烦点个赞&#x1f44d;呗&#xff01; 近期会不断在专栏里进行更新讲解博客~~~ 有什么问题的小伙伴 欢迎留言提问欧&#xff0c;喜欢的小伙伴给个三连支…

TensorFlow2.x基础与mnist手写数字识别示例

文章目录 Github官网文档Playground安装声明张量常量变量 张量计算张量数据类型转换张量数据维度转换ReLU 函数Softmax 函数卷积神经网络训练模型测试模型数据集保存目录显示每层网络的结果 TensorFlow 是一个开源的深度学习框架&#xff0c;由 Google Brain 团队开发和维护。它…

IP纯净度是什么,对用户有多么重要?

在网络应用和数据采集等领域&#xff0c;代理IP被广泛使用&#xff0c;而代理IP的纯净度则直接影响其性能和可用性。代理IP的纯净度主要涉及到代理IP在网络传输过程中的稳定性、匿名性和安全性。今天就带大家一起了解代理IP纯净度对用户的重要性。 第一&#xff0c;保护用户的隐…

adb多设备多屏幕调试

开发中有一种场景&#xff0c;就是将不同的应用界面投到不同的设备上&#xff0c;那么我们可以用以下方法 adb 多屏幕调试 准备工作 1、获取设备ID&#xff0c;SN码2、查看目前有几块屏幕&#xff0c;获取display-id 通过以下命令查看device-id&#xff08;SN&#xff09; a…

springboot+vue前后端项目接口校验通信数据完整性

方案&#xff1a;使用国密SM3算法实现数字签名 服务端 maven的pom文件引用 <!-- 国密算法支持 --><dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15to18</artifactId><version>1.69</version><…

Android Ble低功耗蓝牙开发

一、新建项目 在Android Studio中新建一个项目&#xff0c;如下图所示&#xff1a; 选择No Activity&#xff0c;然后点击Next 点击Finish&#xff0c;完成项目创建。 1、配置build.gradle 在android{}闭包中添加viewBinding&#xff0c;用于获取控件 buildFeatures {viewB…

关于Redis中事务

事务的四个特性 Redis到底有没有原子性 Redis中的原子性不同于MySQL&#xff0c;相比于MySQL&#xff0c;Redis中的原子性几乎不值一提。 MySQL中的原子性&#xff0c;不仅仅是“要么全都执行&#xff0c;要么全都不执行”&#xff0c;它还保证了“一旦执行&#xff0c;结果…

Docker面试整理-如何管理Docker容器的安全?

管理 Docker 容器的安全是确保整个应用和基础设施安全的关键部分。以下是一些重要的实践和策略,可帮助你提高 Docker 容器的安全性: 1. 使用官方和受信任的镜像: ● 仅从可信赖的源下载镜像,如 Docker Hub 上的官方镜像或已验证的发布者。 ● 定期检查和更新你的镜像以确保…

Flutter基础 -- Flutter容器布局

目录 1. MaterialApp 1.1 组件定义 1.2 主要功能和属性 1.3 示例 2. 脚手架 Scaffold 2.1 定义 2.2 Scaffold 的属性 2.3 示例 PS: 对于 Scaffold 和 MaterialApp 3. 线性布局 Column Row 3.1 Row 3.2 Column 4. 盒模型 Box Model 4.1 定义 4.2 示例 5. 容器 C…

dbus-cleanup-sockets`:Linux 中的 D-Bus 套接字清理工具

dbus-cleanup-sockets&#xff1a;Linux 中的 D-Bus 套接字清理工具 在 Linux 系统中&#xff0c;D-Bus 是一种消息总线系统&#xff0c;用于应用程序之间的通信。然而&#xff0c;在某些情况下&#xff0c;D-Bus 套接字文件可能会因为各种原因而残留&#xff0c;导致系统资源…