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

线程相关面试题

提示:线程相关面试题,持续更新中

文章目录

  • 一、Java线程池
    • 1、Java线程池有哪些核心参数,分别有什么的作用?
    • 2、线程池有哪些拒绝策略?
    • 3、说一说线程池的执行流程?
    • 4、线程池核心线程数怎么设置呢?
    • 4、Java线程池中submit()和execute()方法有什么区别?
  • 二、ThreadLocal
    • 1、请介绍一下ThreadLocal底层是怎么实现的?
    • 2、ThreadLocal为什么会内存泄漏?
  • 三、Thread
    • 1、请说说sleep()和wait()有什么区别?
    • 2、多个线程如何保证按顺序执行?


一、Java线程池

1、Java线程池有哪些核心参数,分别有什么的作用?


ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(8,16,60,TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(1024),Executors.defaultThreadFactory(),new ThreadPoolExecutor.CallerRunsPolicy()
);构造方法最多的是7个参数:(1int corePoolSize : 线程池中的核心线程数量allowCoreThreadTimeOut:允许核心线程超时销毁,默认false(不销毁);boolean prestartCoreThread(),初始化一个核心线程;int prestartAllCoreThreads(),初始化所有核心线程;(2int maximumPoolSize : 线程池中允许的最大线程数当核心线程全部繁忙且任务队列存满之后,线程池会临时追加线程,直到总线程数达到maximumPoolSize这个上限;(3long keepAliveTime :线程空闲超时时间如果一个非核心线程处于空闲状态,并且当前的线程数量大于corePoolSize,那么在指定时间后,这个空闲线程会被销毁;(4TimeUnit unit :keepAliveTime的时间单位(天、小时、分、秒......);(5BlockingQueue<Runnable> workQueue :任务队列当核心线程全部繁忙时,任务存放到该任务队列中,等待被核心线程来执行;(6ThreadFactory threadFactory :线程工厂用于创建线程,一般采用默认的线程工厂即可,也可以自定义实现;Executors.defaultThreadFactory():推荐使用,Executors.privilegedThreadFactory():已过时,不推荐使用,7RejectedExecutionHandler handler :拒绝策略(饱和策略)当任务太多来不及处理时,如何“拒绝”任务?“拒绝”触发条件:1、核心线程corePoolSize正在执行任务;2、线程池的任务队列workQueue已满;3、线程池中的线程数达到maximumPoolSize时;就需要“拒绝”掉新提交过来的任务;

2、线程池有哪些拒绝策略?


JDK提供了4种内置的拒绝策略:AbortPolicyCallerRunsPolicyDiscardOldestPolicyDiscardPolicy1AbortPolicy(默认):丢弃任务并抛出RejectedExecutionException异常,这是默认的拒绝策略;2DiscardPolicy:直接丢弃任务,不抛出异常,没有任何提示;3DiscardOldestPolicy:丢弃任务队列中靠最前的任务,当前提交的任务不会丢弃;4CallerRunsPolicy: 交由任务的调用线程(提交任务的线程)来执行当前任务;除了上面的四种拒绝策略,还可以通过实现RejectedExecutionHandler接口,实现自定义的拒绝策略;

3、说一说线程池的执行流程?


当提交一个新任务到线程池时,具体的执行流程如下: 1. 当我们提交任务,线程池会根据corePoolSize大小创建线程来执行任务; 2. 当任务的数量超过corePoolSize数量,后续的任务将会进入阻塞队列阻塞排队;3. 当阻塞队列也满了之后,那么将会继续创建(maximumPoolSize-corePoolSize)个数量的线程来执行任务,如果任务处理完成,maximumPoolSize-corePoolSize个额外创建的线程等待 keepAliveTime之后被自动销毁;4. 如果达到maximumPoolSize,阻塞队列还是满的状态,那么将根据不同的拒绝策略进行拒绝处理; 

在这里插入图片描述


4、线程池核心线程数怎么设置呢?

在这里插入图片描述

	
Ncpu = cpu的核心数 ,Ucpu = cpu的使用率(在0~1之间)W = 线程等待时间,C = 线程计算时间举例:
8 * 100% * (1+60/40) = 20
8 * 100% * (1+80/20) = 40----------------------------------------------------------------------------------------------------------------------------任务分为CPU密集型和IO密集型 CPU密集型线程数 = CPU核心数 + 1; 这种任务主要是消耗CPU资源, 比如像加解密、压缩、计算等一系列需要大量耗费 CPU 资源的任务;+1,比 CPU 核心数多出来的一个线程是为了防止线程偶发的缺页中断,或者其它原因导致的任务暂停而带来的影响。一旦任务暂停,CPU 就会处于空闲状态,而在这种情况下多出来的一个线程就可以充分利用 CPU 的空闲时间; IO密集型线程数 = CPU核心数 * 2;这种任务会有大部分时间在进行IO操作,比如像MySQL数据库、文件读写、网络通信等任务,这类任务不会特别消耗CPU资源,但是IO操作比较耗时,会占用比较多时间;线程在处理IO的时间段内不会占用CPU,这时就可以将CPU交出给其它线程使用,因此在IO密集型任务的应用中,可以多配置一些线程; ----------------------------------------------------------------------------------------------------------------------------基本原则:1、线程执行时间越多,就需要越少的线程;2、线程等待时间越多,就需要越多的线程;以上理论参考依据,实际项目中建议在本地或者测试环境进行压测多次调整线程池大小,找到相对理想的值大小;

4、Java线程池中submit()和execute()方法有什么区别?

1、 两个方法都可以向线程池提交任务;2、 execute只能提交Runnable,无返回值;3、 submit既可以提交Runnable,返回值为null,也可以提交Callable,返回值Future4execute()方法定义在Executor接口中;5submit()方法定义在ExecutorService接口中;6、 execute执行任务时遇到异常会直接抛出;7、 submit执行任务时遇到异常不会直接抛出,只有在调用Futureget()方法获取返回值时,才会抛出异常;-----------------------------------------------------------------------------------------------------------------------RunnableCallable都是用于定义线程执行任务的接口特性						Runnable								Callable返回值						无(void)								有(泛型V)异常处理						不能抛出受检异常							可以抛出受检异常方法签名						void run()								V call() throws Exception使用场景						简单任务,无需结果						复杂任务,需要结果或异常处理线程池集成					execute(Runnable)						submit(Callable) + Future功能扩展性					基础									支持任务取消、超时、结果获取选择建议使用Runnable:当任务简单、无需返回值且不涉及受检异常时。使用Callable:当任务需要返回值、可能抛出异常或需要高级控制(如超时、取消)时。

在这里插入图片描述


二、ThreadLocal

1、请介绍一下ThreadLocal底层是怎么实现的?

在这里插入图片描述


定义:ThreadLocalJava 中用于实现线程隔离存储的核心工具类,它为每个线程提供独立的变量副本,确保线程间数据互不干扰。-------------------------------------------------------------------------------------------------------------------------ThreadLocal是一个类似于HashMap的数据结构;ThreadLocal的实现原理就是通过set把value set到线程的threadlocals属性中,threadlocals是一个Map,其中的key是ThreadLocalthis引用,value是我们所set的值;-------------------------------------------------------------------------------------------------------------------------解释:1、线程运行时,会生成ThreadLocalMap类型的名称为threadLocals的成员变量2ThreadLocalMap底层是Entry 数组键值对存储:Entry[] 数组存储键值对,键为 ThreadLocal 对象,值为线程本地变量。弱引用键:Entry 的键是弱引用(WeakReference<ThreadLocal<?>>),避免 ThreadLocal 实例无法被 GC 回收。但值仍为强引用,需手动清理。

2、ThreadLocal为什么会内存泄漏?


一、内存泄漏的核心原因1、弱引用键(Weak Key)的特性:ThreadLocalMapEntry 键是弱引用类型,指向 ThreadLocal 对象。弱引用的特点:当 ThreadLocal 实例没有其他强引用时,GC 会回收它,但 Entry 的值(Value)仍被强引用持有。2、值对象的强引用(Strong Value):Entry 的值是强引用,指向用户存储的对象。问题:即使 ThreadLocal 实例被 GC 回收,Entry 的值仍可能被线程长期持有(如线程池中的线程),导致值对象无法被释放。二、内存泄漏的典型场景1、线程长期存活:线程池场景:线程被复用(如 ExecutorService),且未调用 ThreadLocal.remove()。后果:Entry 的值对象一直被线程持有,无法被 GC 回收。2、未调用 remove() 方法:代码疏忽:在使用完 ThreadLocal 后,未显式调用 remove() 清理值。后果:即使 ThreadLocal 实例被回收,值对象仍可能残留在 ThreadLocalMap 中。三、内存泄漏的后果1、内存占用增长:值对象无法被释放,导致堆内存占用持续增加。2OOM 风险:在极端情况下,可能引发 OutOfMemoryErrorOOM)。四、解决方案与最佳实践1、显式调用 remove():必须执行:在使用完 ThreadLocal 后,务必调用 remove() 清理值。示例:try {threadLocal.set(value);// ... 业务逻辑 ...} finally {threadLocal.remove(); // 确保清理}2、避免静态 ThreadLocal 变量:风险:静态变量生命周期长,可能导致 ThreadLocalMap 长期存活。替代方案:使用局部变量或依赖注入框架管理。3、线程池场景的特殊处理:自定义线程池:在任务执行前后清理 ThreadLocal。使用 ThreadLocal 清理工具:如阿里开源的 TransmittableThreadLocal,支持线程池传递和清理。4、依赖 GC 的局限性:不要依赖 GC:虽然 ThreadLocalMap 在 set/get 操作时会扫描并清理部分过期 Entry(expungeStaleEntry),但这种清理是启发式的,无法保证完全释放。五、底层机制补充1ThreadLocalMap 的清理逻辑:探测式清理:在 set/get 操作时,扫描 Entry 数组,发现键为 nullEntry,清除值并释放键。启发式清理:以对数复杂度清理部分过期数据,平衡性能与内存。2、为什么值不使用弱引用?设计权衡:若值也使用弱引用,可能导致用户无意识丢失数据。替代方案:通过 remove() 显式管理值的生命周期。

三、Thread


1、请说说sleep()和wait()有什么区别?


1. 所属类与方法签名sleep():属于Thread类。方法签名:public static void sleep(long millis) throws InterruptedException。是一个静态方法,作用于当前线程。wait():属于Object类。方法签名:public final void wait() throws InterruptedException(还有其他重载方法,如wait(long timeout))。是一个实例方法,必须通过对象调用。2. 核心作用sleep():让当前线程暂停执行一段时间(以毫秒为单位)。不释放锁:线程在睡眠期间仍持有对象锁或监视器锁。用途:模拟延时、暂停线程执行(如轮询间隔、超时控制)。wait():让当前线程等待,释放对象锁,直到其他线程调用notify()notifyAll()。释放锁:线程在等待期间不再持有对象锁。用途:多线程间协调,等待某个条件满足(如生产者-消费者模型)。3. 线程状态变化sleep():线程进入TIMED_WAITING状态。时间到后自动恢复执行。wait():线程进入WAITING(无超时)或TIMED_WAITING(有超时)状态。必须由其他线程调用notify()/notifyAll()(或超时)才能恢复。4. 锁的行为sleep():不释放锁:即使线程睡眠,其他线程仍无法获取该线程持有的锁。wait():释放锁:线程释放对象锁,允许其他线程竞争锁并执行同步代码块。5. 唤醒机制sleep():自动唤醒:睡眠时间到后,线程自动恢复执行。wait():被动唤醒:必须由其他线程调用notify()(唤醒单个等待线程)或notifyAll()(唤醒所有等待线程)。6. 使用场景sleep():简单延时(如定时任务、超时重试)。示例:try {Thread.sleep(1000); // 睡眠1秒} catch (InterruptedException e) {e.printStackTrace();}wait():多线程协作(如生产者-消费者模型)。示例:synchronized (lock) {while (!condition) {lock.wait(); // 等待条件满足}// 执行操作}
特性sleep()wait()
所属类ThreadObject
释放锁
唤醒方式自动(时间到)被动(notify()/notifyAll())
线程状态TIMED_WAITINGWAITING/TIMED_WAITING
典型用途简单延时多线程协作
是否静态方法否(需通过对象调用)

2、多个线程如何保证按顺序执行?


比如任务B,它需要等待任务A执行之后才能执行,任务C需要等待任务B执行之后才能执行;解决方法:1、通过join()方法使当前线程“阻塞”,等待指定线程执行完毕后继续执行;2、通过创建单一化线程池newSingleThreadExecutor()实现;3、通过倒数计时器CountDownLatch实现;4、使用Object的wait/notify方法实现;5、使用线程的Condition(条件变量)方法实现;6、使用线程的CyclicBarrier(回环栅栏)方法实现;7、使用线程的Semaphore(信号量)方法实现;

(1) 通过join()方法使当前线程“阻塞”,等待指定线程执行完毕后继续执行:


方法1public static void main(String[] args) throws Exception {// t1线程Thread t1 = new Thread(() -> {System.out.println(Thread.currentThread().getName() + " 执行");}, "t1");// t2线程Thread t2 = new Thread(() -> {try {t1.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + " 执行");}, "t2");// t3线程Thread t3 = new Thread(() -> {try {t2.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + " 执行");}, "t3");t1.start();t2.start();t3.start();}---------------------------------------------------------------------------------------------------------------------------
方法2public static void main(String[] args) throws Exception {// t1线程Thread t1 = new Thread(() -> {System.out.println(Thread.currentThread().getName() + " 执行");}, "t1");// t2线程Thread t2 = new Thread(() -> {System.out.println(Thread.currentThread().getName() + " 执行");}, "t2");// t3线程Thread t3 = new Thread(() -> {System.out.println(Thread.currentThread().getName() + " 执行");}, "t3");t1.start();t1.join();t2.start();t2.join();t3.start();}

(2) 通过创建单一化线程池newSingleThreadExecutor()实现:

public class Test {//自己手动创建单一化线程池(推荐使用)private static final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1,1,0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>(1024),Executors.defaultThreadFactory(),new ThreadPoolExecutor.DiscardOldestPolicy());//创建单一化线程池(不建议使用Executors)private static ExecutorService executorService = Executors.newSingleThreadExecutor();public static void main(String[] args) throws Exception {// t1线程Thread t1 = new Thread(() -> {System.out.println(Thread.currentThread().getName() + " t1执行");}, "t1");// t2线程Thread t2 = new Thread(() -> {System.out.println(Thread.currentThread().getName() + " t2执行");}, "t2");// t3线程Thread t3 = new Thread(() -> {System.out.println(Thread.currentThread().getName() + " t3执行");}, "t3");threadPoolExecutor.execute(t1);threadPoolExecutor.execute(t2);threadPoolExecutor.execute(t3);threadPoolExecutor.shutdown();}
}

(3) 通过倒数计时器CountDownLatch实现:

public class Test {/** 用于判断t1线程是否执行,倒计时设置为1,执行后减1 */private static final CountDownLatch countDownLatch1 = new CountDownLatch(1);/** 用于判断t2线程是否执行,倒计时设置为1,执行后减1 */private static final CountDownLatch countDownLatch2 = new CountDownLatch(1);public static void main(String[] args) throws Exception {// t1线程Thread t1 = new Thread(() -> {System.out.println(Thread.currentThread().getName() + " 执行");countDownLatch1.countDown(); // -1}, "t1");// t2线程Thread t2 = new Thread(() -> {try {countDownLatch1.await(); //只有当 countDownLatch1 的计数器归零后,才会继续执行后续代码} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + " 执行");countDownLatch2.countDown();}, "t2");// t3线程Thread t3 = new Thread(() -> {try {countDownLatch2.await(); //只有当 countDownLatch2 的计数器归零后,才会继续执行后续代码} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + " 执行");}, "t3");t1.start();t2.start();t3.start();}
}

相关文章:

线程相关面试题

提示&#xff1a;线程相关面试题&#xff0c;持续更新中 文章目录 一、Java线程池1、Java线程池有哪些核心参数&#xff0c;分别有什么的作用&#xff1f;2、线程池有哪些拒绝策略&#xff1f;3、说一说线程池的执行流程?4、线程池核心线程数怎么设置呢&#xff1f;4、Java线程…...

pikachu通关教程-目录遍历漏洞(../../)

目录遍历漏洞也可以叫做信息泄露漏洞、非授权文件包含漏洞等. 原理:目录遍历漏洞的原理比较简单&#xff0c;就是程序在实现上没有充分过滤用户输入的../之类的目录跳转符&#xff0c;导致恶意用户可以通过提交目录跳转来遍历服务器上的任意文件。 这里的目录跳转符可以是../…...

Maven-生命周期

目录 1.项目对象模型 2.依赖管理模型 3.仓库&#xff1a;用于存储资源&#xff0c;管理各种jar包 4.本地仓库路径 1.项目对象模型 2.依赖管理模型 3.仓库&#xff1a;用于存储资源&#xff0c;管理各种jar包 4.本地仓库路径...

Hadoop复习(九)

Azkaban工作流管理器 选择 问题 1 判断题 2 / 2 分 工作流是指具有依赖的一组job任务&#xff0c;被依赖的job任务最后执行 正确 错误 问题 2 判断题 2 / 2 分 Azkaban兼容任何版本的Hadoop 正确 错误 问题 3 判断题 2 / 2 分 独立服务器模式下&#xff0c;Azkab…...

Matlab实现LSTM-SVM回归预测,作者:机器学习之心

Matlab实现LSTM-SVM回归预测&#xff0c;作者&#xff1a;机器学习之心 目录 Matlab实现LSTM-SVM回归预测&#xff0c;作者&#xff1a;机器学习之心效果一览基本介绍程序设计参考资料 效果一览 基本介绍 代码主要功能 该代码实现了一个LSTM-SVM回归预测模型&#xff0c;核心流…...

Spring Boot 自动配置原理:从入门到精通

Spring Boot 的自动配置是其核心特性之一&#xff0c;它极大地简化了 Spring 应用的开发&#xff0c;让开发者可以专注于业务逻辑&#xff0c;而无需编写大量的配置代码。 本文将深入探讨 Spring Boot 自动配置的原理&#xff0c;帮助你理解其工作机制&#xff0c;并能灵活运用…...

实践深度学习:构建一个简单的图像分类器

引言 深度学习在图像识别领域取得了巨大的成功。本文将指导你如何使用深度学习框架来构建一个简单的图像分类器&#xff0c;我们将以Python和TensorFlow为例&#xff0c;展示从数据准备到模型训练的完整流程。 环境准备 在开始之前&#xff0c;请确保你的环境中安装了以下工…...

腾讯 ovCompose 开源,Kuikly 鸿蒙和 Compose DSL 开源,腾讯的“双”鸿蒙方案发布

近日&#xff0c;腾讯的 ovCompose 和 Kuikly 都发布了全新开源更新&#xff0c;其中 Kuikly 在之前我们聊过&#xff0c;本次 Kuikly 主要是正式开源鸿蒙支持部分和 Compose DSL 的相关支持&#xff0c;而 ovCompose 是腾讯视频团队基于 Compose Multiplatform 生态推出的跨平…...

PYTHON调用讯飞C/C++动态库实现离线语音合成并且实时播放

语音合成(Text-to-Speech, TTS)技术在现代应用中扮演着越来越重要的角色&#xff0c;从智能客服到有声读物&#xff0c;从导航系统到辅助工具&#xff0c;TTS技术无处不在。本文将详细介绍如何使用Python结合科大讯飞的离线SDK实现一个本地化的语音合成系统。 技术背景 离线语…...

黑马Java面试笔记之 消息中间件篇(RabbitMQ)

一. 消息丢失问题 RabbitMQ如何保证消息不丢失&#xff1f; 使用场景有&#xff1a; 异步发送&#xff08;验证码、短信、邮件... &#xff09;MYSQL和Redis&#xff0c;ES之间的数据同步分布式事务削峰填谷...... 消息丢失原因会有三种情况&#xff0c;分别分析一下 1.1 生…...

Vue中安装插件的方式

一. 认识Vue插件 1.1. 通常向Vue全局添加一些功能时&#xff0c;会采用插件的模式&#xff0c;它有两种编写方式&#xff1a; 1.1.1. 对象类型&#xff1a;一个对象&#xff0c;但是必须包含一个install的函数&#xff0c;该函数会在安装插件时执行 // 方式一&#xff1a;传入…...

如何提高工作效率

最近&#xff0c;跟一个同事同时测同一业务&#xff0c;在对比自己与同事的产出过程中&#xff0c;发现&#xff0c;别人工作效率极高&#xff0c;产出也比较大。最重要的是&#xff0c;别人每天晚上走得早&#xff0c;自己就算加班到九点十点&#xff0c;似乎产出都没别人高。…...

Redisson学习专栏(五):源码阅读及Redisson的Netty通信层设计

文章目录 前言一、分布式锁核心实现&#xff1a;RedissonLock源码深度解析1.1 加锁机制&#xff1a;原子性与重入性实现1.2 看门狗机制&#xff1a;锁自动续期设计1.3 解锁机制&#xff1a;安全释放与通知1.4 锁竞争处理&#xff1a;等待队列与公平性1.5 容错机制&#xff1a;异…...

Spring AI 项目实战(一):Spring AI 核心模块入门

系列文章 序号文章名称1Spring AI 项目实战(一):Spring AI 核心模块入门一、引言:Java 生态下 AI 应用开发的新机遇 在数字化转型浪潮席卷全球的当下,人工智能(AI)技术早已突破实验室的边界,深度融入企业级应用开发核心领域。对于Java开发者而言,如何将成熟稳定的Spr…...

字节跳动开源图标库:2000+图标一键换肤的魔法

一个SVG文件生成四种主题的神奇技术&#xff0c;正在颠覆前端开发者的图标工作流。 深夜两点&#xff0c;设计师小王对着屏幕抓狂——产品经理临时要求将整套线性图标改为双色风格&#xff0c;这意味着他需要重新导出上百个SVG文件。 而隔壁工位的前端小张同样崩溃&#xff1a;…...

结合 AI 生成 mermaid、plantuml 等图表

AI 画图 AI 画图并不是真的让 AI 画一个图片&#xff0c;而是让 AI 根据你的需求&#xff0c;生成对应的需求文本&#xff0c;再根据 “文本画图” 来生成图片。 Mermaid mermaid 支持流程图、时序图、架构图等等多种图片绘制。当然最终生成的效果和样式会根据不同的“文本代…...

行列式详解:从定义到应用

行列式详解&#xff1a;从定义到应用 引言 行列式是线性代数中的核心概念之一&#xff0c;它不仅是矩阵理论的重要组成部分&#xff0c;更是解决线性方程组、计算向量空间体积、判断矩阵可逆性等问题的关键工具。本文将从行列式的基本定义出发&#xff0c;系统地介绍其性质、…...

R语言使用随机过采样(Random Oversampling)平衡数据集

随机过采样&#xff08;Random Oversampling&#xff09;是一种用于平衡数据集的技术&#xff0c;常用于机器学习中处理类别不平衡问题。当某个类别的样本数量远少于其他类别时&#xff08;例如二分类中的正负样本比例悬殊&#xff09;&#xff0c;模型可能会偏向多数类&#x…...

HertzBeat的安装和使用教程

以下是HertzBeat的安装和使用教程&#xff1a; 安装 • Docker安装&#xff1a;执行命令docker run -d -p 1157:1157 -p 1158:1158 --name hertzbeat apache/hertzbeat。启动后&#xff0c;访问http://localhost:1157&#xff0c;默认账号密码是admin/hertzbeat。 • 包安装…...

【Kotlin】高阶函数Lambda内联函数

【Kotlin】简介&变量&类&接口 【Kotlin】数字&字符串&数组&集合 【Kotlin】高阶函数&Lambda&内联函数 【Kotlin】表达式&关键字 文章目录 函数还是属性高阶函数抽象和高阶函数实例&#xff1a; 函数作为参数的需求方法引用表达式更多使用场…...

从0开始学vue:vue3和vue2的关系

一、版本演进关系1. 继承关系2. 版本生命周期 二、核心差异对比三、关键演进方向1. Composition API2. 性能优化 四、迁移策略1. 兼容构建模式2. 关键破坏性变更 五、生态演进1. 官方库升级2. 构建工具链 六、选型建议1. 新项目2. 现有项目 七、未来展望 一、版本演进关系 1. …...

MySQL关系型数据库学习

学习参考链接&#xff1a;https://www.runoob.com/mysql/mysql-tutorial.html Windows 安装MYSQL服务端的步骤&#xff1a;https://www.runoob.com/w3cnote/windows10-mysql-installer.html 1. 概念学习 MySQL 是一种关联数据库管理系统&#xff0c;关联数据库将数据保存在不…...

嵌入式硬件篇---龙芯2k1000串口

针对串口错误 “device reports readiness to read but returned no data (Device disconnected or multiple access on port?)” 的排查和解决方法 硬件方面 检查连接 确认串口设备&#xff08;如串口线、连接的模块等&#xff09;与龙芯设备之间的物理连接是否牢固&#xf…...

4-C#的不同窗口传值

C#的不同窗口传值 1.通过构造函数传值 this.Hide(); Form1 form01 new Form1(textBox2.Text); //Application.Run(form01); form01.Show();public Form1(string aaa) {InitializeComponent();label12.Text aaa; }2.全局类传值 namespace WindowsFormsApp1 {public class G…...

谷歌地图苹果版v6.138.2 - 前端工具导航

谷歌地图(Google maps)苹果版是是由谷歌官方推出的一款手机地图应用。软件功能强大&#xff0c;支持本地搜索查找世界各地的地址、地点和商家&#xff1b;支持在街景视图中查看世界各地的360度全景图&#xff1b;支持查找乘坐火车、公交车和地铁的路线&#xff0c;或者查找步行…...

NSSCTF [LitCTF 2025]test_your_nc

[复现]绕过学的还是太差了&#xff0c;多积累吧 ​​​​​​题目 题目: 给了一个python文件 #!/bin/python3 import osprint("input your command")blacklist [cat,ls, ,cd,echo,<,${IFS},sh,\\]while True:command input()for i in blacklist:if i in com…...

第十九章 正则表达式

第十九章 正则表达式 文本型数据在所有的类UNIX系统(如 Linux)中会扮演着重要角色&#xff0c;在完全领会这些工具的全部特征之前&#xff0c;要先了解一下工具最为复杂的用法和相关技术&#xff1a;正则表达式。 什么是正则表达式 简单地说&#xff0c;正则表达式是一种用于…...

browser-use Agent 日志链路分析

browser-use Agent 日志链路分析 本节详细梳理 browser-use Agent 的日志输出&#xff0c;从 Agent 初始化到每一步的行为日志&#xff0c;帮助理解其行为轨迹。 1. Agent 初始化阶段 日志点&#xff1a; logger.info(&#x1f9e0; Starting a browser-use agent ...) 记录 …...

Qwen3高效微调

高效微调 场景、模型、数据、算力 高效微调的应用场景 对话风格微调&#xff1a;高效微调可以用于根据特定需求调整模型的对话风格。例如&#xff0c;针对客服系统、虚拟助理等场景&#xff0c;模型可以通过微调来适应不同的 语气、礼貌程度 或 回答方式&#xff0c;从而在与…...

Gitee Wiki:重塑关键领域软件研发的知识管理范式

在数字化转型浪潮席卷全球的当下&#xff0c;关键领域软件研发正面临前所未有的知识管理挑战。传统文档管理模式的局限性日益凸显&#xff0c;知识传承的断层问题愈发严重&#xff0c;团队协作效率的瓶颈亟待突破。Gitee Wiki作为新一代知识管理平台&#xff0c;正在通过技术创…...