当前位置: 首页 > news >正文

JAVA面试部分——后端-线程前篇

3.1 线程和进程

在计算机科学中,进程和线程是操作系统管理资源的两种不同方式。

  • 进程(Process):是程序在计算机上的一次执行活动。每个进程都有自己的内存空间,包括代码、数据和系统资源。一个进程可以包含多个线程。进程之间相互独立,各自拥有独立的内存空间和系统资源,彼此不会直接共享数据,通信需要通过进程间通信机制来实现。

  • 线程(Thread):是进程中的一个执行单元。一个进程中的多个线程共享相同的内存空间和系统资源,可以共享数据。线程在同一进程中运行,相对于进程而言更加轻量级,创建和销毁的开销更小,线程间的切换开销也更小。

Java 中的线程是通过 java.lang.Thread 类来实现的。Java 程序运行时会启动一个主线程(Main Thread),可以通过创建 Thread 对象来创建新的线程,并调用 start() 方法来启动线程的执行。

多线程可以充分利用多核处理器的计算能力,提高程序的执行效率。但同时,多线程编程也需要处理同步、死锁、竞态条件等并发问题,需要谨慎编写以确保线程安全。

3.2 线程的实现方式?

继承Thread类,实现Runnable接口,实现Callable接口,创建线程池。

3.3 有三个线程,制定一种机制,保证线程a在线程b之前运行,线程b在线程c之前运行
你可以使用线程同步工具来实现这种机制。其中最常见的是使用Java的wait()和notify()方法。首先,为每个线程创建一个类,并在类中定义一个共享的Object,我们称之为syncObj。这个对象用于线程间的通信。
java
public class ThreadA extends Thread {  private Object syncObj;  public ThreadA(Object syncObj) {  this.syncObj = syncObj;  }  @Override  public void run() {  synchronized (syncObj) {  // 线程a的代码  System.out.println("Thread A is running");  // 通过notify唤醒线程b  syncObj.notify();  }  }  
}  public class ThreadB extends Thread {  private Object syncObj;  public ThreadB(Object syncObj) {  this.syncObj = syncObj;  }  @Override  public void run() {  synchronized (syncObj) {  // 线程b的代码  System.out.println("Thread B is running");  // 通过notify唤醒线程c  syncObj.notify();  }  }  
}  public class ThreadC extends Thread {  private Object syncObj;  public ThreadC(Object syncObj) {  this.syncObj = syncObj;  }  @Override  public void run() {  synchronized (syncObj) {  // 线程c的代码  System.out.println("Thread C is running");  }  }  
}
//然后在主程序中创建并启动这些线程:
​
java
public static void main(String[] args) {  Object syncObj = new Object();  ThreadA threadA = new ThreadA(syncObj);  ThreadB threadB = new ThreadB(syncObj);  ThreadC threadC = new ThreadC(syncObj);  threadA.start();  threadB.start();  threadC.start();  
}
这样,线程a会在其他线程之前运行,然后唤醒线程b,线程b再唤醒线程c。但是需要注意的是,Java的wait()和notify()方法在实际使用时需要非常小心,因为如果没有正确地使用它们,可能会导致死锁或者无法预料的后果。例如,如果线程b没有在调用notify()之前唤醒线程a,那么线程a可能会永远被阻塞。
3.4 Runnable与Callable的区别?

实现Callable接口的任务线程能返回执行结果;而实现Runnable接口的任务线程不能返回结果; Callable接口的call()方法允许抛出异常;而Runnable接口的run()方法的异常只能在内部消化,不能继续上抛。

3.5 list中有20条数据分为5个线程每个线程4个数据,每条数据+1,怎么拿到他们组合成一个list?

采用Callable的异步算法(call方法有返回值,run方法没有返回值)。

在Java中,你可以使用ExecutorServiceCallable来实现你的需求。Callable是一种可以返回结果的任务接口,它的对象可以被ExecutorService线程池执行。

import java.util.*;  
import java.util.concurrent.*;  public class Main {  public static void main(String[] args) throws InterruptedException, ExecutionException {  // 假设的20条数据  List<Integer> data = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20));  // 分成5组,每组4个数据  List<List<Integer>> groups = new ArrayList<>();  for (int i = 0; i < data.size(); i += 4) {  groups.add(new ArrayList<>(data.subList(i, Math.min(data.size(), i + 4))));  }  // 创建一个固定大小的线程池  ExecutorService executor = Executors.newFixedThreadPool(5);  // 对每个组执行加1操作,并收集结果  List<Future<List<Integer>>> futures = new ArrayList<>();  for (List<Integer> group : groups) {  futures.add(executor.submit(new Callable<List<Integer>>() {  @Override  public List<Integer> call() throws Exception {  return processGroup(group);  }  }));  }  // 等待所有操作完成,并收集结果  List<Integer> combinedList = new ArrayList<>();  for (Future<List<Integer>> future : futures) {  combinedList.addAll(future.get());  }  System.out.println(combinedList); // 打印结果  }  private static List<Integer> processGroup(List<Integer> group) {  // 对每个元素加1操作  List<Integer> result = new ArrayList<>();  for (Integer num : group) {  result.add(num + 1);  }  return result;  }  
}
3.6 线程池是什么?什么情况下需要使用线程池?使用线程池的好处

以下是一些需要使用线程池的情况:

  • 并发任务处理:线程池可以用于处理并发的任务,例如处理请求、批量处理数据、并行计算等。通过线程池,可以管理和复用线程,提高任务的执行效率。

  • 异步任务执行:线程池可以用于执行异步任务,将任务提交给线程池后,可以立即返回并继续执行后续代码,不必等待任务完成。适用于需要在后台执行耗时任务,同时不阻塞主线程的场景。

  • 定时任务调度:线程池提供了定时任务执行的功能,可以周期性地执行任务或在指定的时间点执行任务。适用于需要按计划执行任务的场景,例如定时任务、定时检查等。

  • 资源池管理:线程池可以用于管理资源池,例如数据库连接池、线程池等。通过线程池,可以复用和管理资源,提高资源利用率,同时控制资源的并发访问。

  • 并行计算:线程池可以用于并行计算,将计算任务分解为多个子任务,分配给线程池中的线程并行执行,加速计算过程。适用于需要高性能并行计算的场景,如数据处理、图像处理等。

  • 长时间运行的任务:线程池适用于长时间运行的任务,可以控制线程的生命周期,避免频繁创建和销毁线程的开销,提高系统的稳定性和性能。

总之,无论是在Web服务器、桌面应用程序还是大规模分布式系统中,线程池都可以提供更好的性能、可扩展性和资源管理。选择合适的线程池并进行适当的调优,可以有效地提高系统的性能和稳定性。

3.7 线程池:核心线程数,最大线程数,队列的选择,线程初始化的时候线程数量是怎么变化的?
  • 核心线程数:线程池中保持活动线程的最小数量。这些线程会在进程启动时创建,并且只要线程池需要,就会持续存在。核心线程数通常由corePoolSize属性设置。

  • 最大线程数:线程池中允许存在的最大线程数量。如果队列满了并且已经达到了核心线程数,那么线程池会根据需要创建更多的线程,直到达到这个最大值。最大线程数通常由maximumPoolSize属性设置。

  • 队列的选择:当有新的任务提交给线程池,而当前线程数未达到核心线程数时,这些任务会被放在一个队列中等待。常见的队列类型有:无界队列(如LinkedBlockingQueue)、有界队列(如ArrayBlockingQueue)以及优先队列(如PriorityBlockingQueue)等。队列的选择需要根据实际需求来决定。

    线程池的队列选择取决于多个因素,包括任务的特性、线程池的实现方式以及具体的应用场景。以下是关于几种常见队列的讨论:

    1. SynchronousQueue:一种无缓冲的等待队列,类似于无中介的直接交易,有点像原始社会中的生产者和消费者,生产者拿着产品去集市销售给产品的最终消费者,而消费者必须亲自去集市找到所要商品的直接生产者。如果有经销商,生产者直接把产品批发给经销商,而无需在意经销商最终会将这些产品卖给那些消费者,由于经销商可以库存一部分商品,因此相对于直接交易模式,总体来说采用中间经销商的模式会吞吐量高一些(可以批量买卖);但另一方面,又因为经销商的引入,使得产品从生产者到消费者中间增加了额外的交易环节,单个产品的及时响应性能可能会降低。声明一个SynchronousQueue有两种不同的方式,它们之间有着不太一样的行为。

    2. ArrayBlockingQueue:是一种有界队列,它实现了BlockingQueue接口。此队列按 FIFO(先进先出)原则对元素进行排序。此队列的容量必须指定,在创建后就不能改变。如果尝试向已满的队列中添加元素,操作就会阻塞。如果尝试从空的队列中获取元素但该队列已经不再有可用元素(即队列为空),则操作也会阻塞。

    3. LinkedBlockingQueue:是一种无界队列(LinkedBlockingQueue的容量仅受制于内存的大小),它实现了BlockingQueue接口。此队列按照 FIFO(先进先出)原则对元素进行排序。

    4. PriorityBlockingQueue:是一种无界队列,它实现了BlockingQueue接口。此队列按照元素的优先级对元素进行排序。如果多个元素具有相同的优先级,则将按照它们的自然顺序(例如它们的自然排序或者插入顺序)进行排序。

    5. 选择队列时需要考虑任务的数量、任务的优先级以及系统的内存情况等因素。例如,如果系统需要处理大量低优先级的任务,那么选择LinkedBlockingQueue可能更为合适;如果任务数量有限,那么可以选择ArrayBlockingQueue,这样可以避免队列过大导致的内存压力。另外,如果任务具有不同的优先级,可以选择PriorityBlockingQueue来保证高优先级的任务能够优先得到处理。

  • 线程初始化的时候线程数量:初始时,线程池中的线程数量通常等于核心线程数。如果任务提交的速度超过了核心线程的处理速度,那么队列会逐渐增长,直到达到最大队列长度。如果当前线程数已经达到了最大线程数,但队列已经满了,那么新提交的任务将会被拒绝。

在实际应用中,选择合适的线程池和参数配置需要根据具体的应用场景和需求来决定。例如,对于处理大量并发请求的Web应用,可以选择ThreadPoolExecutorForkJoinPool;对于需要处理大量计算任务的场景,可以选择ForkJoinPoolExecutorService等。

3.8 说一下常见的几个线程池?(Java里面有4个线程池)

常见的线程池有以下几种:

  • newSingleThreadExecutor():创建一个只有一个线程的线程池。这个线程池会保证所有的任务按照提交的顺序一个一个地执行。如果这个线程池中的线程因为任务异常结束,那么它会立即创建一个新的线程替代。

  • newFixedThreadPool():创建一个定长的线程池。这个线程池会一次性创建指定数量的线程,然后每次提交的任务都会被一个线程立即执行。如果所有线程都在执行任务,那么新的任务就会进入等待队列,等待有线程空闲时再执行。

  • newCacheThreadPool():创建一个可缓存的线程池。这个线程池的大小会根据需要动态调整。如果线程池的大小超过了处理任务所需的线程数,那么就回收部分线程(一般是60S内未执行)。

  • newScheduledThreadPool():创建一个定长的线程池,支持定时和周期性任务执行。

  • newSingleThreadScheduledExecutor():创建一个单例的线程池,支持定期或延时执行任务。

以上就是Java中常见的五种线程池,了解它们可以帮助我们更好地利用多线程处理任务,提高程序的执行效率。

3.9 线程怎么释放的?

线程池中的线程可以通过以下方式释放:

  • 执行器自动关闭旧线程:当线程池中的线程完成任务后,执行器会自动关闭状态为非运行状态的线程。

  • 线程自愿退出:在线程没有获取到任务,并且在指定的等待时间内也没有任务可执行时,线程会自愿退出,通过processWorkerExit()方法可以证实这一点。

  • 定时器触发线程回收:对于核心线程,如果长时间没有任务执行,定时器会触发回收线程。

需要注意的是,线程池中的线程数量没有固定,可以根据需要动态调整。当任务量增大时,线程池会自动增加线程数量;当任务量减少时,线程池会自动减少线程数量。同时,线程池中的线程状态也不同,有些是核心线程,有些是非核心线程。核心线程在空闲1分钟后也会被回收。

在Spring框架中,可以通过配置线程池来管理线程的释放。以下是一些常用的配置选项:
​
1.使用ThreadPoolTaskExecutor类创建线程池:
java
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();  
executor.setCorePoolSize(5);  
executor.setMaxPoolSize(10);  
executor.setKeepAliveSeconds(60);  
executor.setQueueCapacity(25);  
executor.setThreadNamePrefix("MyThreadPool-");  
executor.initialize();
​
2.在Spring的配置文件中配置线程池:
xml
<task:executor id="myExecutor" pool-size="5-10" keep-alive-seconds="60" queue-capacity="25" thread-name-prefix="MyThreadPool-" />
​
3.在Spring的配置文件中配置ThreadPoolTaskExecutor:
xml
<task:executor id="myExecutor" pool-size="5-10" keep-alive-seconds="60" queue-capacity="25" thread-name-prefix="MyThreadPool-" />
​
这些配置选项可以设置线程池的核心线程数、最大线程数、线程的存活时间、队列容量以及线程名称前缀等参数。根据实际需求,可以调整这些参数来优化线程池的性能。
3.10 为什么要线程同步?并说一说线程同步的方式

线程同步的目的是为了保证多个线程之间的协同工作,避免出现数据竞争和不一致的情况。线程同步可以确保在同一时刻只有一个线程可以访问共享资源,避免多个线程同时对同一份数据进行修改或操作,保证数据的一致性和完整性。

线程同步的方式有多种,常见的有以下几种:

  • 互斥锁(Mutex):通过使用互斥锁,只有一个线程可以在同一时刻持有这个锁,其他线程必须等待该线程释放锁之后才能访问共享资源。

  • 信号量(Semaphore):信号量是一种更高级的同步机制,可以用于控制多个线程对共享资源的访问。信号量可以初始化为一个特定的值,表示可以同时访问共享资源的线程数量。当线程访问共享资源时,需要获取一个信号量许可,当访问完成后释放许可,让其他线程可以继续访问。

  • 条件变量(Condition):条件变量允许线程等待某个条件满足后才继续执行。它可以让线程等待特定的信号或事件发生,而不会浪费CPU时间。

  • 读写锁(Read-Write Lock):读写锁是一种特殊的锁机制,适用于读操作比写操作更频繁的情况。它允许多个线程同时进行读操作,但只允许一个线程进行写操作。

  • 临界区(Critical Section):临界区是一段必须互斥执行的代码,用于保护共享资源的访问。只有拥有临界区的线程才能执行其中的代码,其他线程必须等待。

这些线程同步方式各有优缺点,应根据具体情况选择适合的同步方式。

3.11 线程池怎么从等待队列中拿任务的?(头结点)

线程池从等待队列中拿任务的核心过程如下:

  • 线程池首先会检查等待队列是否为空,如果等待队列为空,则无法从队列中获取任务。

  • 如果等待队列不为空,线程池会尝试从队列头部获取一个任务。

  • 如果无法从队列头部获取任务,说明队列已经被占用,这时线程池会尝试创建新的线程来执行任务。

  • 如果无法创建新的线程,线程池会采取拒绝策略来处理无法执行的任务。

通过以上步骤,线程池就可以从等待队列中获取任务并执行。

相关文章:

JAVA面试部分——后端-线程前篇

3.1 线程和进程 在计算机科学中&#xff0c;进程和线程是操作系统管理资源的两种不同方式。 进程&#xff08;Process&#xff09;&#xff1a;是程序在计算机上的一次执行活动。每个进程都有自己的内存空间&#xff0c;包括代码、数据和系统资源。一个进程可以包含多个线程。…...

【小沐学C++】C++ 实现鼠标键盘钩子HOOK

文章目录 1、简介2、相关函数2.1 SetWindowsHookEx2.2 UnhookWindowsHookEx2.3 CallNextHookEx 3、相关结构体3.1 KBDLLHOOKSTRUCT3.2 MSLLHOOKSTRUCT 4、挂钩过程5、代码测试5.1 代码1 结语 1、简介 https://learn.microsoft.com/zh-cn/windows/win32/winmsg/about-hooks 挂…...

【pycharm】常见问题与解决

记录一些Pycharm中经常遇到的问题 1. “Open file or Project” always in loading state (hang) a) 老版本 (2021年左右) since build 211.6693.14, it is possible to use a native file chooser on Windows. The feature is experimental; to enable it, add the followi…...

flask web学习之表单(一)

文章目录 一、使用Flask-WTF处理表单1.1 安装Flask-WTF库1.2 定义WTForms表单类常用的WTForm字段实例化字段类常用参数常用的WTForm验证器 1.3 输出HTML代码使用render_kw属性在调用字段时传入 1.4 在模板中渲染表单 在web程序中&#xff0c;表单是用户交互最常见的方式之一。用…...

@ControllerAdvice 使用场景

ControllerAdvice 是Spring 框架中的注解&#xff0c;多用在Spring MVC应用程序中。 使用场景1&#xff1a;处理异常 # 示例1 import org.apache.ibatis.javassist.NotFoundException; import org.springframework.http.HttpStatus; import org.springframework.http.Respons…...

二极管选型怎么选?常用参数要熟练~

同学们大家好&#xff0c;今天我们继续学习杨欣的《电子设计从零开始》&#xff0c;这本书从基本原理出发&#xff0c;知识点遍及无线电通讯、仪器设计、三极管电路、集成电路、传感器、数字电路基础、单片机及应用实例&#xff0c;可以说是全面系统地介绍了电子设计所需的知识…...

【小白专用】C#关于角色权限系统

&#xff08;C#&#xff09;用户、角色、权限 https://www.cnblogs.com/huangwen/articles/638050.html 权限管理系统——数据库的设计&#xff08;一&#xff09; https://www.cnblogs.com/cmsdn/p/3371576.html 权限管理系统——菜单模块的实现&#xff08;二&#xff09; …...

代码随想录算法训练营

一刷打卡记录&#xff1a; 日期打卡2023/10/25 day01二分查找有点转不过弯&#xff0c;快慢指针能理解&#xff0c;自己写也可能写不出来&#xff0c;但是能记住了&#xff0c;能看懂&#xff0c;还有其他解法待补充看完&#xff0c;花了挺长时间的2023/10/26 day02还好&#…...

统计学-R语言-3

文章目录 前言给直方图增加正态曲线的不恰当之处直方图与条形图的区别核密度图时间序列图洛伦茨曲线计算绘制洛伦茨曲线所需的各百分比数值绘制洛伦茨曲线 练习 前言 本篇文章是介绍对数据的部分图形可视化的图型展现。 给直方图增加正态曲线的不恰当之处 需要注意的是&#…...

spring动态控制定时任务

在spring框架中&#xff0c;对于简单的定时任务&#xff0c;可以使用 Scheduled 注解实现&#xff0c;在实际项目中&#xff0c;经常需要动态的控制定时任务&#xff0c;比如通过接口增加、启动、停止、删除定时任务&#xff0c;动态的改变定时任务的执行时间等。 我们可以通过…...

3. Mybatis 中SQL 执行原理

2. Mybatis 中SQL 执行原理 这里有两种方式&#xff0c;一种为常用的 Spring 依赖注入 Mapper 的方式。另一种为直接使用 SqlSessionTemplate 执行 Sql 的方式。 Spring 依赖注入 Mapper 的方式 Mapper 接口注入 SpringIOC 容器 Spring 容器在扫描 BeanDefinition 阶段会扫…...

第一次在RUST官方论坛上留言发布我的Rust板箱

第一次在RUST官方论坛上发帖子&#xff0c;有点紧张~地址在这里&#xff1a; 【My Rust Crate】obtains linux local information - The Rust Programming Language Forum (rust-lang.org)...

LabVIEW 智能化矿用定向钻机液压系统监测

简介 在矿用定向钻机的液压系统监测中&#xff0c;实现实时监控和异常预警对于保障设备运行的稳定性至关重要。传统的人工监测方法效率低下而且准确性不能满足要求&#xff0c;针对这种情况采用 LabVIEW 开发平台&#xff0c;设计并实现了一套智能化矿用定向钻机液压系统的状态…...

GO数据库操作

Golang 出色的 ORM 库为 GORM。 官网文档&#xff1a;https://gorm.io/docs/ 我们来说说增删改查的用法&#xff0c;更深入的研究可以去官网看看。 GORM功能概览&#xff1a; 关联&#xff08;有一个、有多个、属于、多对多、多态性、单表继承&#xff09;挂钩&#xff08;创…...

PyTorch简单理解ChannelShuffle与数据并行技术解析

目录 torch.nn子模块详解 nn.ChannelShuffle 用法与用途 使用技巧 注意事项 参数 示例代码 nn.DataParallel 用法与用途 使用技巧 注意事项 参数 示例 nn.parallel.DistributedDataParallel 用法与用途 使用技巧 注意事项 参数 示例 总结 torch.nn子模块详…...

MySQL 8查询语句之查询所有字段、特定字段、去除重复字段、Where判断条件

《MySQL 8创建数据库、数据表、插入数据并且查询数据》里边有我使用到的数据。 再使用下方的语句补充一些数据&#xff1a; insert into Bookbought.bookuser(id,username,userphone,userage,sex,userpassword) values (11,Book Break,22245678911,18,male,good#111); insert…...

LLaMA-Factory添加adalora

感谢https://github.com/tsingcoo/LLaMA-Efficient-Tuning/commit/f3a532f56b4aa7d4200f24d93fade4b2c9042736和https://github.com/huggingface/peft/issues/432的帮助。 在LLaMA-Factory中添加adalora 1. 修改src/llmtuner/hparams/finetuning_args.py代码 在FinetuningArg…...

多端多用户万能DIY商城系统源码:自营+多商户入驻商城系统 独立部署 带完整的安装代码包以及搭建教程

电子商务行业日新月异&#xff0c;许多企业希望能够通过线上商城拓展业务。但是&#xff0c;传统商城系统往往无法满足多样化、个性化的需求&#xff0c;而且开发周期长、成本高。罗峰就来给大家分享一款多端多用户万能DIY商城系统源码&#xff0c;搭建简单。 以下是部分代码示…...

Qt 6之七:学习资源

Qt 6之七&#xff1a;学习资源 Qt是一种跨平台的C应用程序开发框架&#xff0c;它提供了一套丰富的工具和库&#xff0c;可以帮助开发者快速构建跨平台的应用程序&#xff0c;用于开发图形用户界面&#xff08;GUI&#xff09;和非GUI应用程序。 Qt 6之一&#xff1a;简介、安…...

解决大模型的幻觉问题:一种全新的视角

在人工智能领域&#xff0c;大模型已经成为了一个重要的研究方向。然而&#xff0c;随着模型规模的不断扩大&#xff0c;一种新的问题开始浮出水面&#xff0c;那就是“幻觉”问题。这种问题的出现&#xff0c;不仅影响了模型的性能&#xff0c;也对人工智能的发展带来了新的挑…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

初学 pytest 记录

安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...

基于PHP的连锁酒店管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...

macOS 终端智能代理检测

&#x1f9e0; 终端智能代理检测&#xff1a;自动判断是否需要设置代理访问 GitHub 在开发中&#xff0c;使用 GitHub 是非常常见的需求。但有时候我们会发现某些命令失败、插件无法更新&#xff0c;例如&#xff1a; fatal: unable to access https://github.com/ohmyzsh/oh…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现指南针功能

指南针功能是许多位置服务应用的基础功能之一。下面我将详细介绍如何在HarmonyOS 5中使用DevEco Studio实现指南针功能。 1. 开发环境准备 确保已安装DevEco Studio 3.1或更高版本确保项目使用的是HarmonyOS 5.0 SDK在项目的module.json5中配置必要的权限 2. 权限配置 在mo…...