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

多线程代码案例-1 单例模式

单例模式

单例模式是开发中常见的设计模式。

设计模式,是我们在编写代码时候的一种软性的规定,也就是说,我们遵守了设计模式,代码的下限就有了一定的保证。设计模式有很多种,在不同的语言中,也有不同的设计模式,设计模式也可以被认为是对编程语言语法的补充

单例即单个实例(对象),某个类在一个进程中,只应该创建出一个实例(原则上不应该创建出多个实例),使用单例模式,可以对我们的代码进行一个更为严格的校验和检查。

举个例子:有时候,代码中需要管理/持有大量的数据,此时有一个对象就可以了。比如:我需要一个对象管理10G的数据,如果我们不小心创建出多个对象,内存空间就会成倍地增长。

如何保证只有唯一的对象呢?我们可以选择“君子之约地方式”,写一个文档,文档上约定,每个接手维护代码的程序员,都不能对这个类创建多个实例(很显然,这种约定并不靠谱)我们期望让机器(编译器)能够对代码中的指定类,对创建的实例个数进行检验。如果发现创建出了多个实例,就直接编译报错,但是Java语法中本身没有办法直接约定某个对象能创建出几个实例,那么就需要程序员使用一些技巧来实现这样的效果。

实现单例模式的方式有很多种,这里介绍两种实现方式:饿汉模式和懒汉模式。

1 饿汉模式

代码如下:

//饿汉模式
//期望这个类只能有唯一的实例(一个进程中)
class Singleton{private static Singleton instance = new Singleton();//在这个类被加载时,就会初始化这个静态成员,实例创建的时机非常早——饿汉public static Singleton getInstance(){//其他代码想要使用这个类的实例就需要通过这个方法进行获取,// 不应该在其他代码中重新new这个对象而是使用这个方法获取这个现有的对象return instance;}private Singleton(){//其他代码就没法new了}
}

在这个类中,我们创建出了唯一的对象,被static修饰,说明这个变量是类变量,(由类对象所拥有(每个类的类对象只存在一个),在类加载的时候,它就已经被初始化了)

而将构造方法设为私有,就使得只能在当前类里面创建对象了,其他位置就不能再创建对象了,因此这个instance指向的对象就是唯一的对象。

其他代码要想使用这个类的实例,就需要通过这个getInstance()方法获取这个对象,而无法在其他代码中new一个对象。

上述代码,称为”饿汉模式“,是单例模式中的一种简单的写法,”饿“形容”非常迫切“,实例在类加载的时候就创建了,创建的时机非常早,相当于程序一启动,实例就创建了。 

但是,上面的代码,面对反射,是无能为力的,也就是说,仍然可以通过反射来创建对象,但反射是属于非常规的编程手段,代码中随意使用反射是非常糟糕的。

2 懒汉模式

”懒“这个词,并不是贬义词,而是褒义词。社会能进步,科技能发展,生产效率提高,有很大部分原因都是因为懒。

举个生活中的例子(不考虑卫生):

假如我每次吃完饭就洗碗,那我每次就需要洗全部的碗;但是如果我每次吃完饭把碗放着,等到下次吃饭的时候再洗,此时,如果我只要用到两个碗,那我就只需要洗两个碗就行了,很明显洗两个碗要比洗全部碗更加高效。

在计算机中,”懒“的思想就非常有意思,它通常代表着更加高效

比如有一个非常大的文件(10GB),使用编辑器打开这个文件,如果是按照”饿汉“的方式 ,编辑器就会先把这10GB的数据都加载到内存中,然后再进行统一的展示。(但是加载了这么多数据,用户还是需要一点一点地看,没法一下子看完这么多)

如果是按照”懒汉“地方式,编辑器就会只读取一小部分数据(比如只读取10KB),把这10KB先展示出来,然后随着用户进行翻页之类的操作,再继续展示后面的数据。

加载10GB的时间会很长,但是加载10KB却只是一瞬间的事情……

懒汉模式,区别于饿汉模式,创建实例的时机不一样了,创建实例的时机会更晚,一直到第一次使用getInstance方法时才会创建实例。

代码如下(注意:这是一个不完整的代码,因为还有一些线程安全问题需要解决~~):

//懒汉的方式实现单例模式class SingletonLazy{private static SingletonLazy instance = null;public static  SingletonLazy getInstance(){//饿汉模式是在类加载的时候就创建实例了,懒汉则会晚很多,且如果程序用不到这个方法就会省下了if (instance == null) {//如果首次调用就创建实例instance = new SingletonLazy();}}}//不是则返回之前创建的引用return instance;}private SingletonLazy(){}
}

第一行代码中仍然是先创建一个引用,但是这个引用不指向任何的对象。如果是首次调用getInstance方法,就会进入if条件,创建出对象并且让当前引用指向该对象。如果是后续调用getInstance方法,由于当前的instance已经不是null了,就会返回我们之前创建的引用了。

这样设定,仍然可以保证,该类的实例是唯一一个,与此同时,创建实例的时机就不再是程序驱动了,而是当第一次调用getInstance的时候,才会创建。。

而第一次调用getInstance这个操作的执行时机就不确定了,要看程序的实际需求,大概率会比饿汉这种方式要晚一些,甚至有可能整个程序压根用不到这个方法,也就把创建的操作给省下了。

有的程序,可能是根据一定的条件,来决定是否要进行某个操作,进一步来决定是否要创建实例。 

3 单例模式与线程安全

上面我们介绍的关于单例模式只是一个开始,接下来才是我们多线程的真正关键问题。即:上述我们编写的饿汉模式和懒汉模式,是否是线程安全的?

饿汉模式:

//饿汉模式
//期望这个类只能有唯一的实例(一个进程中)
class Singleton{private static Singleton instance = new Singleton();//在这个类被加载时,就会初始化这个静态成员,实例创建的时机非常早——饿汉public static Singleton getInstance(){//其他代码想要使用这个类的实例就需要通过这个方法进行获取,// 不应该在其他代码中重新new这个对象而是使用这个方法获取这个现有的对象return instance;}private Singleton(){//其他代码就没法new了}
}

对于饿汉模式来说,getInstance直接返回instance这个实例,这个操作,本质上就是一个的操作(多个线程同时读取同一变量,是不会产生线程安全问题的)。因此,在多线程下,它是线程安全的。

懒汉模式 :

//懒汉的方式实现单例模式class SingletonLazy{private static SingletonLazy instance = null;public static  SingletonLazy getInstance(){//饿汉模式是在类加载的时候就创建实例了,懒汉则会晚很多,且如果程序用不到这个方法就会省下了if (instance == null) {//如果首次调用就创建实例instance = new SingletonLazy();}//不是则返回之前创建的引用return instance;}private SingletonLazy(){}
}

再看懒汉模式,在懒汉模式中,代码中有的操作(return instance),又有的操作(instance = new SingletonLazy())。 很明显,这是一个有线程安全问题的代码!!!

问题1:线程安全问题

因为多线程之间是随机调度,抢占是执行的,如果t1和 t2 按照下列的顺序执行代码,就会出现问题。

如果是t1和t2按照上述情况操作,就会导致实例被new了两次,这就不是单例模式了,就会出现bug了!!!

那如何解决当前的代码bug,使它变为一个线程安全的代码呢?

加锁~~

知道要加锁了?那大家不妨想想:如果我把锁像如下代码这样加下去,是否线程就安全了呢?

class SingletonLazy{private static SingletonLazy instance = null;Object locker = new Object;public static  SingletonLazy getInstance(){//饿汉模式是在类加载的时候就创建实例了,懒汉则会晚很多,且如果程序用不到这个方法就会省下了if (instance == null) {//如果首次调用就创建实例sychronized(locker){instance = new SingletonLazy();}}//不是则返回之前创建的引用return instance;}private SingletonLazy(){}
}

答案很显然:不行!!!因为如上述代码加锁仍然会发生刚才那样的线程不安全的情况。

所以这里如果想要代码正确执行,需要把if和new两个操作,打包成一个原子的操作(即加锁加在if语句的外面)。 

class SingletonLazy{private static SingletonLazy instance = null;Object locker = new Object;public static  SingletonLazy getInstance(){//饿汉模式是在类加载的时候就创建实例了,懒汉则会晚很多,且如果程序用不到这个方法就会省下了synchronized(locker){    if (instance == null) {//如果首次调用就创建实例instance = new SingletonLazy();}}  //不是则返回之前创建的引用return instance;}private SingletonLazy(){}
}

 

此时因为t1拿到了锁,t2进入阻塞,等t1执行完毕后(创建完对象后),t2进行判断,此时因为t1已经创建好了对象,所以t2就只能返回当前对象的引用了。 

多线程的代码是非常复杂的,代码稍微变化一点,结论就可能截然不同。千万不能认为,代码中加了锁就一定线程安全,不加锁就一定线程不安全,具体问题要具体分析,要分析这个代码在各种调度执行顺序下不同的情况,确保每种情况都不会出现bug!!!

 问题2:效率问题

上述代码还存在的另一个问题是效率问题:试想一下,当你创建完这个单例对象,你每次获取这个单例对象时(是读的操作,并不会有线程问题),每次都要去加锁、解锁,然后才能返回这个对象。(注意:加锁、解锁耗费的空间和时间都是很大的)。

所以为了优化上面的代码,我们可以再加上一层if,如果instance为null(需要执行写操作),考虑到线程安全问题,就需要加锁;如果instance不为null了,就不需要加锁了。

class SingletonLazy{private static SingletonLazy instance = null;Object locker = new Object;public static  SingletonLazy getInstance(){//饿汉模式是在类加载的时候就创建实例了,懒汉则会晚很多,且如果程序用不到这个方法就会省下了if(instance == null){synchronized(locker){    if (instance == null) {//如果首次调用就创建实例instance = new SingletonLazy();}}}    //不是则返回之前创建的引用return instance;}private SingletonLazy(){}
}

上面的代码,有两重完全相同if判断条件,但是他们的作用是完全不同的:

第一个if是判断是否需要加锁,第二个if是判断是否要创建对象!!!

巧合的是,两个if条件相同,但是他们的作用是完全不同的,这样就实现了双重校验锁。在以后的学习中,还可能出现两个if条件是相反的情况。

问题3:指令重排序问题

这个代码还有一点问题需要解决:我们之前在线程安全的原因中讲过的:指令重排序问题就在懒汉模式上出现了~~

指令重排序,也是编译器优化的一种方式。编译器会在保证逻辑不变的前提下,为了提高程序的效率,调整原有代码的执行顺序。

再举个生活中的例子:

我妈让我去超市买东西:西红柿、鸡蛋、黄瓜、茄子。

超市摊位分布图如下:

如果我按我妈给的顺序,那就会走出这样的路线: 

上述方案虽然也能完成我妈给的任务,但如果我对超市已经足够熟悉了,我就能够在保证逻辑不变

的情况下(买到4种菜),调整原有买菜的执行顺序,提高买菜效率: 

返回到代码中:

   instance = new SingletonLazy();

 上面这行代码,可以拆分为三个步骤:

1、申请一段内存空间。

2、调用构造方法,创建出当前实例。

3、把这个内存地址赋给instance这个引用。

上述代码可以按1、2、3这个顺序来执行,但是编译器也可能会优化成1、3、2这个顺序执行。这两种顺序在单线程下都是能够完成任务的。

1就相当于买了个房子

2相当于装修房子

3相当于拿到了房子的钥匙

通过1、2、3得到的房子,拿到的房子已经是装修好的,称为“精装房”;通过1、3、2得到的房子,拿到的房子需要自己装修,称为“毛坯房”,我们买房子时,上面的两种情况都可能发生。

但是,如果在多线程环境下,指令重排序就会引入新问题了。

上述代码中,由于 t1 线程执行完 1 3 步骤(申请一段内存空间,把内存空间的地址赋给引用变量,但并没有进行 2 调用构造方法的操作,会导致 instance指向的是一个未被初始化的对象)之后调度走,此时 instance 指向的是一个非 null 的,但是是未初始化的对象,此时 t2 线程判定 instance == null 不成立,就会直接 return,如果 t2 继续使用 instance 里面的属性或者方法,就会出现问题,引起代码的逻辑出现问题。 

那么我们应该如何解决当前问题呢?

volatile关键字

之前讲过volatile有两个功能:

1、保证内存可见性:每次访问变量都必须要重新读取内存,而不会优化为读寄存器/缓存。

2、禁止指令重排序:针对被volatile修饰的变量的读写操作的相关指令,是不能被重排序的。

懒汉模式的完整代码:

//经典面试题!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
package Thread;
//懒汉的方式实现单例模式
//线程不安全,它在多线程环境下可能会创建多个实例
class SingletonLazy{//这个引用指向唯一实例,这个引用先初始化为null,而不是立即创建实例
private volatile static SingletonLazy instance = null;//针对这个变量的读写操作就不能重排序了
private static Object locker;
//第一次if判定是否要加锁,第二次if判定是否要创建对象//双重校验锁public static  SingletonLazy getInstance(){//饿汉模式是在类加载的时候就创建实例了,懒汉则会晚很多,且如果程序用不到这个方法就会省下了//加锁效率不高,且容易导致阻塞,所以再加一个判断提高效率if(instance ==null) {//判断是否为空,为空再加锁//不为空,说明是后续的调用就无需加锁了synchronized (locker) {if (instance == null) {//如果首次调用就创建实例instance = new SingletonLazy();}}}//不是则返回之前创建的引用return instance;}private SingletonLazy(){}
}

相关文章:

多线程代码案例-1 单例模式

单例模式 单例模式是开发中常见的设计模式。 设计模式,是我们在编写代码时候的一种软性的规定,也就是说,我们遵守了设计模式,代码的下限就有了一定的保证。设计模式有很多种,在不同的语言中,也有不同的设计…...

langChain存储文档片段,并进行相似性检索

https://python.langchain.ac.cn/docs/how_to/document_loader_pdf/#vector-search-over-pdfs 这段代码展示了如何使用LangChain框架中的InMemoryVectorStore和OpenAIEmbeddings来存储文档片段,并基于提供的查询进行相似性搜索。下面是对每一行代码的详细解释&…...

MQTT协议技术详解:深入理解物联网通信基础

MQTT协议技术详解:深入理解物联网通信基础 1. MQTT协议概述 MQTT (Message Queuing Telemetry Transport) 是一种轻量级的发布/订阅消息传输协议,专为资源受限设备和低带宽、高延迟或不可靠网络环境设计。作为物联网通信的核心协议之一,MQTT…...

python中的进程锁与线程锁

在Python中,线程和进程使用锁的机制有所不同,需分别通过threading和multiprocessing模块实现。以下是具体用法及注意事项: 一、线程锁(Thread Lock) 基本用法 线程锁用于多线程环境下保护共享资源,防止数据…...

导出导入Excel文件(详解-基于EasyExcel)

前言: 近期由于工作的需要,根据需求需要导出导入Excel模板。于是自学了一下下,在此记录并分享!! EasyExcel: 首先我要在这里非常感谢阿里的大佬们!封装这么好用的Excel相关的API,真…...

仿正点原子驱动BMP280气压传感器实例

文章目录 前言 一、寄存器头文件定义 二、设备树文件中添加节点 三、驱动文件编写 四、编写驱动测试文件并编译测试 总结 前言 本文驱动开发仿照正点原子的iic驱动实现,同时附上bmp280的数据手册,可访问下面的链接: BMP280_Bosch(博世…...

Java 反射机制(Reflection)

一、理论说明 1. 反射的定义 Java 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为 Jav…...

每日Prompt:发光线条解剖图

提示词 一幅数字插画,描绘了一个 [SUBJECT],其结构由一组发光、干净且纯净的蓝色线条勾勒而成。画面设定在深色背景之上,以突出 [SUBJECT] 的形态与特征。某个特定部位,如 [PART],通过红色光晕加以强调,以…...

从新手到高手:全面解析 AI 时代的「魔法咒语」——Prompt

引言:AI 时代的「语言炼金术」 在人工智能技术突飞猛进的今天,我们正在经历一场堪比工业革命的生产力变革。从聊天机器人到图像生成,从数据分析到自动化写作,AI 模型正在重塑人类与信息交互的方式。而在这一切背后,隐…...

【SpringBoot】集成kafka之生产者、消费者、幂等性处理和消息积压

目录 配置文件 application.properties启动类 ApplicationKafka 配置Message 消息实体类MessageRepository 消息处理消息积压监控服务Kafka消息消费者服务Kafka消息生产者服务API控制器提供测试接口关键特性说明生产环境建议 配置文件 application.properties # 应用配置 serv…...

[SAP] 通过事务码Tcode获取程序名

如何通过事务码查找对应的程序名? 方法一:直接运行事务码,跳转至功能详情页面,点击【系统】|【状态】即可获取对应事务码的程序名 从上面可以了解到自定义的事务码"ZMM01"对应的程序名为"ZYT36_ZMM001_01"&a…...

蓝桥杯12届国B 纯质数

题目描述 如果一个正整数只有 1 和它本身两个约数,则称为一个质数(又称素数)。 前几个质数是:2,3,5,7,11,13,17,19,23,29,31,37,⋅⋅⋅ 。 如果一个质数的所有十进制数位都是质数,我们称它为纯质数。例如&#xff1…...

国产大模型「五强争霸」,决战AGI!

来源 | 新智元 DeepSeek的横空出世,已经彻底改变了全球的AI局势。 从此,不仅中美大模型竞争格局改变,国产大模型的产业版图,也被一举打破! 纵观中国基础大模型的市场,可以看到,如今的基础大模…...

C++修炼:继承

Hello大家好&#xff01;很高兴我们又见面啦&#xff01;给生活添点passion&#xff0c;开始今天的编程之路&#xff01; 我的博客&#xff1a;<但凡. 我的专栏&#xff1a;《编程之路》、《数据结构与算法之美》、《题海拾贝》、《C修炼之路》 欢迎点赞&#xff0c;关注&am…...

Mysql新增

插入一个记录需要的时间由下列因素组成&#xff0c;其中的数字表示大约比例&#xff1a; 连接&#xff1a;(3)发送查询给服务器&#xff1a;(2)分析查询&#xff1a;(2)插入记录&#xff1a;&#xff08;1x记录大小&#xff09;插入索引&#xff1a;&#xff08;1x索引&#x…...

华秋2025电子设计与制造技术研讨会(华东站)成功举办!

“探索科技前沿&#xff0c;共筑创新未来”——华秋“2025电子设计与制造技术研讨会第一站&#xff1a;华东站”在江苏苏州圆满落幕。 随着电子信息产业的持续增长和数字化经济的加速转型&#xff0c;数字化电子供应链的作用愈发显著。本届研讨聚焦EDA设计、DFM软件分析、多层…...

[学习] RTKLib详解:qzslex.c、rcvraw.c与solution.c

RTKLib详解&#xff1a;qzslex.c、rcvraw.c与solution.c 本文是 RTKLlib详解 系列文章的一篇&#xff0c;目前该系列文章还在持续总结写作中&#xff0c;以发表的如下&#xff0c;有兴趣的可以翻阅。 [学习] RTKlib详解&#xff1a;功能、工具与源码结构解析 [学习]RTKLib详解…...

【Ubuntu】neovim Lazyvim安装与卸载

安装neovim # 下载 AppImage wget https://github.com/neovim/neovim/releases/latest/download/nvim-linux-x86_64.appimage# 添加执行权限 chmod ux nvim-linux-x86_64.appimage# 移动到系统路径&#xff0c;重命名为 nvim sudo mv nvim-linux-x86_64.appimage /usr/local/b…...

数据结构(一) 绪论

一. 时间复杂度: (1)定义: 时间复杂度是衡量算法执行时间随输入规模(通常用n表示)增长的变化趋势的指标,时间复杂度用O符号表示 用于描述算法在最坏情况下或平均情况下的时间需求 时间复杂度关注的是操作次数的增长率&#xff0c;而非具体执行时间 常见的时间复杂度由小到大依次…...

数据库事务并发问题

目录 脏读 幻读 不可重复读 三者的区别 脏读、幻读和不可重复读是在数据库并发操作中可能出现的问题&#xff0c;以下是对它们的详细介绍&#xff1a; 脏读 定义&#xff1a;指一个事务读取了另一个未提交事务修改的数据。示例&#xff1a;事务 A 修改了一条数据&#xf…...

Android之横向滑动列表

文章目录 前言一、效果图二、使用步骤1.xml布局2.代码3.HomeHxBean3.adapter4.item布局5.两个drawable 总结 前言 横向滑动列表有多种实现方式&#xff0c;也可以用tablayout&#xff0c;也可以用recyclerview&#xff0c;今天主要介绍recyclerview。 一、效果图 二、使用步骤…...

系统稳定性之上线三板斧

&#x1f4d5;我是廖志伟&#xff0c;一名Java开发工程师、《Java项目实战——深入理解大型互联网企业通用技术》&#xff08;基础篇&#xff09;、&#xff08;进阶篇&#xff09;、&#xff08;架构篇&#xff09;清华大学出版社签约作家、Java领域优质创作者、CSDN博客专家、…...

aardio - godking.vlistEx.listbar + win.ui.tabs 实现多标签多页面切换

方法一&#xff1a; import win.ui; import godking.vlistEx.listbar; import fonts.fontAwesome; /*DSG{{*/ mainForm win.form(text"vlistEx - table adapter";right895;bottom503) mainForm.add({ custom{cls"custom";text"自定义控件";lef…...

鸿蒙 核心与非核心装饰器

HarmonyOS NEXT 版本中完整的 ArkTS 装饰器分类整理&#xff08;含核心与非核心装饰器&#xff0c;已剔除废弃特性&#xff09; 一、核心装饰器&#xff08;Essential Decorators&#xff09; 1. 组件基础 装饰器功能Entry应用入口组件&#xff0c;每个模块必须且仅有一个&am…...

TypeScript 知识框架

一、TypeScript 基础 1. 类型系统 基本类型: number, string, boolean, null, undefined, symbol, bigint 引用类型: object, array, function, class 特殊类型: any, unknown, void, never 类型推断与类型注解 类型断言 (as 语法和 <Type> 语法) 2. 接口与类型别名 接口…...

web-ui开源程序是建立在浏览器使用的基础上,旨在使 AI 代理可以访问网站

​一、软件介绍 文末提供程序和源码下载 web-ui开源程序是建立在浏览器使用的基础上&#xff0c;旨在使 AI 代理可以访问网站。WebUI&#xff1a;基于 Gradio 构建&#xff0c;支持大部分 browser-use 功能。此 UI 设计为用户友好型&#xff0c;并支持与浏览器代理轻松交互。扩…...

【ns3】TCP三次握手源码解析

文章目录 TCP三次握手过程三次握手源码 TCP三次握手过程 三次握手源码 下面是ns3里三次握手整体过程的源码&#xff0c;和上面图解一一对应&#xff1a; TCP socket的状态枚举&#xff1a; 整体过程&#xff1a; 客户端首先connect&#xff1a;tcp-socket-base::connect调用Do…...

【YOLO模型】参数全面解读

使用YOLO模型时&#xff0c;需要调节各种参数&#xff0c;网络文章和官方文档有点不方便&#xff0c;整理了下面的内容备用&#xff1a; 获取最全最新的参数列表: Ultralytics官方文档: 这是获取YOLOv11&#xff08;以及YOLOv8等&#xff09;最权威、最详细参数信息的地方。通…...

跨境电商定价革命:亚马逊“逆向提价“策略背后的价值重构逻辑

导言&#xff1a;打破价格魔咒的销量奇迹 2024年Q3亚马逊平台上演商业悖论&#xff1a;在TOP5000卖家中&#xff0c;12%实施5%-15%温和提价的商户&#xff0c;41%实现单量30.4%的季度增长。这一现象颠覆"低价即流量"的电商铁律&#xff0c;揭开新消费时代"价值定…...

Kafka、RabbitMQ、RocketMQ的区别

以下是 RabbitMQ、RocketMQ、Kafka 的核心区别对比&#xff1a; 一、架构设计差异 ‌Kafka‌ 基于分布式日志的发布-订阅模型&#xff0c;通过分区&#xff08;Partition&#xff09;实现水平扩展&#xff0c;依赖 ZooKeeper 管理集群消费者通过消费者组&#xff08;Consumer G…...

win10 局域网内聊天

在 Windows 10 的局域网 中&#xff0c;如果你想实现 多个用户之间的聊天功能&#xff0c;可以选择以下几种方案&#xff0c;取决于你需要的是&#xff1a; • ✅ 命令行纯文字聊天&#xff08;如 Linux talk&#xff09; • ✅ 图形界面聊天室 • ✅ 局域网广播消息 • ✅ 多人…...

【前端三剑客】Ajax技术实现前端开发

目录 一、原生AJAX 1.1AJAX 简介 1.2XML 简介 1.3AJAX 的特点 1.3.1AJAX 的优点 1.3.2AJAX 的缺点 1.4AJAX 的使用 1.4.1核心对象 1.4.2使用步骤 1.4.3解决IE 缓存问题 1.4.4AJAX 请求状态 二、jQuery 中的AJAX 2.1 get 请求 2.2 post 请求 三、跨域 3.1同源策略…...

论文学习_Trex: Learning Execution Semantics from Micro-Traces for Binary Similarity

摘要&#xff1a;检测语义相似的函数在漏洞发现、恶意软件分析及取证等安全领域至关重要&#xff0c;但该任务面临实现差异大、跨架构、多编译优化及混淆等挑战。现有方法多依赖语法特征&#xff0c;难以捕捉函数的执行语义。对此&#xff0c;TREX 提出了一种基于迁移学习的框架…...

数据压缩的概念和优缺点

一、数据压缩的概念 数据压缩是通过特定算法&#xff08;压缩算法&#xff09;对数据进行重新编码&#xff0c;以减少数据存储空间或传输带宽的技术。其核心目标是在不丢失关键信息&#xff08;或允许一定程度信息损失&#xff09;的前提下&#xff0c;降低数据量&#xff0c;…...

spaCy基础入门

spaCy 概览说明 spaCy 是一个现代、快速、工业级 NLP 工具库&#xff0c;专门为实际工程应用设计&#xff0c;提供&#xff1a; • 分词&#xff08;Tokenization&#xff09; • 词性标注&#xff08;POS Tagging&#xff09; • 命名实体识别&#xff08;NER&#xff09; •…...

vue3项目创建-配置-elementPlus导入-路由自动导入

目录 方法一&#xff1a;create-vue 方法二 &#xff1a;Vite Vue Vite.config.ts配置 引入element-plus 安装 如何在项目中使用 Element Plus 完整引入 按需导入 vue3vite中自动配置路由的神器&#xff1a;vite-plugin-pages 1. 安装 2、修改vite.config.js中配置…...

2025年的电脑能装win7吗_2025年组装电脑装win7详细图文教程

2025年的电脑能装win7吗&#xff1f;2025年的电脑可以安装Win7&#xff0c;但存在一些限制和挑战。2025年的电脑基本上是14代和15代处理器&#xff0c;需要特定的条件和步骤才能安装win7&#xff0c;并且只能采用独立显卡&#xff0c;因为没有集成显卡驱动。另外注意目前2025年…...

windowsC++操作ADB

文章目录 一、ADB基础1. 工作原理2. 安装与配置 二、常用ADB指令分类1. 设备连接与管理2. 文件传输3. 应用管理4. 设备交互5. 系统信息6. 日志与调试7. 网络与端口转发 三、高级用法1. 多设备管理2. 无线ADB连接3. 批量执行命令4. ADB脚本示例 四、常见问题与解决方案五、注意事…...

Springboot实现重试机制

背景 研发工作中时常遇到要和其他服务对接&#xff0c;依赖对方能力的情况&#xff0c;最恶心的是对方提供的服务不稳定&#xff0c;时灵时不灵的&#xff0c;进而影响到自己功能的稳定性。万一发生了这种事&#xff0c;做为研发&#xff0c;咱该怎么办&#xff1f;通过容错直接…...

CS内网渗透 ----【内网渗透实战】PsExec vs Telnet:建立IPC通道实现横向移动与域控上线全解析

目录 1. 什么是 PsExec&#xff1f; 2. 什么是 Telnet&#xff1f; 3. PsExec 与 Telnet 的区别及优势 3.1 主要区别 3.2 内网渗透中的优势 4. 实际案例 —— 使用 PsExec 上线域控主机 案例背景 操作步骤 案例效果 5. 总结 利用 PsExec 建立 IPC 通道 —— IPC 的定…...

第二十三天打卡

作业&#xff1a; 整理下全部逻辑的先后顺序&#xff0c;看看能不能制作出适合所有机器学习的通用pipeline 数据预处理 → 特征选择 → 降维 → 模型训练 import pandas as pd import numpy as np from sklearn.model_selection import train_test_split, GridSearchCV from sk…...

aardio - 将文本生成CSS格式显示

import win.ui; /*DSG{{*/ var winform win.form(text"aardio form";right759;bottom469) winform.add( button{cls"button";text"Button";left340;top130;right430;bottom180;z3}; edit{cls"edit";text"我是一串文本";lef…...

【漫话机器学习系列】256.用 k-NN 填补缺失值

用 k-NN 填补缺失值&#xff1a;原理、实现与应用 在实际的数据科学项目中&#xff0c;我们经常会遇到数据缺失&#xff08;Missing Values&#xff09;的问题。缺失值如果处理不当&#xff0c;不仅会影响模型训练&#xff0c;还可能导致最终结果偏差。 今天&#xff0c;我们…...

tomcat与nginx之间实现多级代理

准备工作 准备5台虚拟主机&#xff1b;至少准备3台虚拟主机&#xff1b; 设备1作为代理服务器&#xff1b;设备2与设备4作为处理静态资源请求服务器&#xff08;使用nginx&#xff09;&#xff1b;设备3与设备5作为处理动态资源服务器&#xff08;使用tomcat&#xff09; 设…...

商业航天运动控制系统中的高可靠性芯片解决方案:挑战、策略与应用研究

摘要&#xff1a;随着商业航天领域的迅速发展&#xff0c;运动控制系统对芯片的可靠性提出了前所未有的挑战。本文深入探讨了商业航天运动控制系统中芯片可靠性面临的挑战&#xff0c;包括宇宙辐射效应、极端环境适应性及系统级可靠性保障等。同时&#xff0c;通过案例研究展示…...

[Java实战]Spring Boot 3 整合 Ehcache 3(十九)

[Java实战]Spring Boot 3 整合 Ehcache 3&#xff08;十九&#xff09; 引言 在微服务和高并发场景下&#xff0c;缓存是提升系统性能的关键技术之一。Ehcache 作为 Java 生态中成熟的内存缓存框架&#xff0c;其 3.x 版本在性能、功能和易用性上均有显著提升。本文将详细介绍…...

【Flask全栈开发指南】从零构建企业级Web应用

目录 &#x1f31f; 前言&#x1f3d7;️ 技术背景与价值&#x1f6a7; 当前技术痛点&#x1f6e0;️ 解决方案概述&#x1f465; 目标读者说明 &#x1f50d; 一、技术原理剖析&#x1f4ca; 核心概念图解&#x1f4a1; 核心作用讲解&#x1f9e9; 关键技术模块说明⚖️ 技术选…...

使用docker安装clickhouse集群

1、简介 clickhouse 作为大数据场景中&#xff0c;实现快速检索的常用列式存储数据库&#xff0c;采用物理机部署&#xff0c;会在数据量大的场景中&#xff0c;物理机器存储达到阈值需要扩容&#xff0c;会带来比较大的问题&#xff0c;因此&#xff0c;使用docker部署clickho…...

佰力博科技准静态d33测试的注意事项

准静态d33测试是测量压电材料纵向压电应变常数的重要方法&#xff0c;其注意事项包括以下几个方面&#xff1a; 选择合适的测量设备 准静态d33测试需要使用专用的压电测试仪&#xff0c;如佰力博PEAI1000高精度压电分析仪、准静态d33测量仪或PCA1000压电陶瓷综合参数分析仪。这…...

iOS设备投屏Archlinux

我的iphone手机屏太小&#xff0c;我想把手机投到archlinux电脑上看。与是我就想找一个免费的软件。 UxPlay https://github.com/FDH2/UxPlay GPLv3&#xff0c;开源。原来只支持 AirPlay Mirror 协议&#xff0c;现在新增 支持来自 AirPlay 的纯音频 &#xff08;Apple Los…...