【C++】设计模式详解:单例模式
文章目录
- Ⅰ. 设计一个类,不允许被拷贝
- Ⅱ. 请设计一个类,只能在堆上创建对象
- Ⅲ. 请设计一个类,只能在栈上创建对象
- Ⅳ. 请设计一个类,不能被继承
- Ⅴ. 请设计一个类,只能创建一个对象(单例模式)
- 💥单例模式:
- 1、饿汉模式
- 2、懒汉模式
- 第一种写法:
- 第二种写法:

Ⅰ. 设计一个类,不允许被拷贝
拷贝只会发生在两个场景中:拷贝构造函数、赋值运算符重载,因此想要让一个类禁止拷贝,只需让该类不能调用拷贝构造函数以及赋值运算符重载即可。
-
C++98
的方式:-
设置成私有:如果只声明而没有设置成
private
,用户自己如果在类外定义了,还是等于可以拷贝 -
只声明不定义:不定义是因为该函数根本不会调用,定义了其实也没有什么意义,不写反而还简单,而且如果定义了就做不到防止成员函数内部拷贝了。
class CopyBan {// ...... private:// 设为私有,只声明不实现CopyBan(const CopyBan&);CopyBan& operator=(const CopyBan&); };
-
-
C++11
的方式:C++11
中扩展了delete
的用法,delete
除了释放new
申请的资源外,如果在默认成员函数后跟上=delete
,表示让编译器删除掉该默认成员函数。
class CopyBan {// 直接使用delete关键字CopyBan(const CopyBan&) = delete;CopyBan& operator=(const CopyBan&) = delete;// ...... };
Ⅱ. 请设计一个类,只能在堆上创建对象
实现方式:
-
将类的构造函数私有化,并将拷贝构造的声明也私有化,防止别人调用拷贝在栈上生成对象。(或者用
default
、delete
关键字也行) -
提供一个完成堆对象创建的静态成员函数。
顺便提一下,有人采用将析构函数变成私有的方法来使类的默认构造函数、拷贝构造、赋值重载不会自动生成,这也是可以的,但是这时候就需要我们手动去写一个释放的函数来调用,所以一般我们也只用上面的方法,而这种 将析构函数私有的方法不常用!
class HeapOnly
{
public:// static的好处就是我们不需要对象就可以在类外通过类名::函数名直接访问static HeapOnly* CreateObject(){return new HeapOnly;}
private:// 默认构造函数不能直接封掉,因为上面的CreateObject()需要调用// 可以只声明不实现,这里直接使用default关键字HeapOnly() = default;// 拷贝构造和赋值重载要封掉,防止拷贝产生栈空间对象HeapOnly(const HeapOnly&) = delete;HeapOnly& operator=(const HeapOnly&) = delete;
};int main()
{HeapOnly* h1 = HeapOnly::CreateObject();// HeapOnly h2 = h1; // ❌// static HeapOnly h3; // ❌static HeapOnly* h3 = HeapOnly::CreateObject(); // 本质还是一个指向堆空间的对象cout << typeid(h3).name() << endl;return 0;
}// 运行结果:
class HeapOnly * __ptr64
Ⅲ. 请设计一个类,只能在栈上创建对象
-
方法一:同上面那种情况一样,将构造函数私有化,然后设计静态方法创建对象返回即可。
class StackOnly { public:static StackOnly CreateObject(){return StackOnly();} private:StackOnly() = default;/* 或者只声明不定义StackOnly(){}*/ };int main() {StackOnly s1 = StackOnly::CreateObject();StackOnly* s2 = new StackOnly; // ❌static StackOnly s3; // ❌return 0; }
-
方法二:屏蔽
operator new
和operator delete
。因为new
在底层调用void* operator new(size_t size)
函数,只需将该函数屏蔽掉即可。- 注意:要防止定位
new
。 - 这种方法其实是不太好使的,因为就算我们禁用了
operator new
或者operator delete
,我们也很难防止其在静态区中产生对象,如果使用这种方法,那么还是得和方法一一样,将构造函数私有化,然后使用静态函数返回栈对象,那为何不直接使用第一种方法呢❓❓❓
class StackOnly { public:StackOnly() {} private:void* operator new(size_t size);void operator delete(void* p); };int main() {StackOnly s1;StackOnly* s2 = new StackOnly; // ❌static StackOnly s3; // 仍然可以生成静态区对象return 0; }
- 注意:要防止定位
这里要说明一个点,就是我们还是 没办法预防产生静态变量,如下面代码:
class StackOnly
{
public:static StackOnly CreateObject(){return StackOnly();}
private:StackOnly() = default;// 不能封掉拷贝构造,不然CreateObject无法return// StackOnly(const StackOnly&) = delete;
};
int main()
{StackOnly s1 = StackOnly::CreateObject();// 无法封掉这种情况,因为如果封掉拷贝构造的话,那么我们就无法在CreateObject中return一个临时栈对象了static StackOnly s2 = StackOnly::CreateObject(); cout << typeid(s2).name() << endl;return 0;
}// 运行结果:
class StackOnly
如果我们想避开这种情况,唯一的方法就是 不使用栈对象,我们只通过 CreateObject()
来调用类中的某些函数,但是一般这么做就有点一次性那味。
Ⅳ. 请设计一个类,不能被继承
-
C++98
的方式:// C++98中构造函数私有化,派生类中调不到基类的构造函数。则无法继承 class NonInherit {public:static NonInherit GetInstance(){return NonInherit();} private:NonInherit(){} };
-
C++11
的方式 :- 使用
final
修饰类,表示该类不能被继承。
class A final {// .... };
- 使用
Ⅴ. 请设计一个类,只能创建一个对象(单例模式)
设计模式(Design Pattern
)是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。为什么会产生设计模式这样的东西呢?就像人类历史发展会产生兵法。最开始部落之间打仗时都是人拼人的对砍。后来春秋战国时期,七国之间经常打仗,就发现打仗也是有套路的,后来孙子就总结出了《孙子兵法》。孙子兵法也是类似。
使用设计模式的目的:为了代码可重用性、让代码更容易被他人理解、保证代码可靠性。 设计模式使代码编写真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。
我们之前在学习 C++
的过程中其实早就接触到了设计模式,比如迭代器模式、适配器模式等等,下面我们就来讲一下单例模式:
💥单例模式:
一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息,这种方式简化了在复杂环境下的配置管理。
⚜️一般来说,单例模式下是不需要考虑资源释放的,因为我们这个单例对象是在主程序结束之后会自动释放的,如果没有特定需求说要提前释放,一般我们都不需要实现资源释放的功能,但是如果需要的话,比如说我们需要手动释放,因为一些资源可能要保存到日志等原因,所以我们就得实现释放资源函数比如说 DeleteInstance()
等等,下面的懒汉模式中会实现!
单例模式有两种实现模式:
1、饿汉模式
饿汉模式的宗旨就是说 不管你将来用不用,主程序启动时就创建一个唯一的实例对象。这就像一个饿汉一样,一旦遇到了食物,那么此时都是控制不住想直接去吃的,所以这种模式叫做饿汉模式!
- 优点:
- 控制简单
- 因为是在执行主函数之前就生成了对象,所以 没有线程安全问题。
- 如果这个单例对象 在多线程高并发环境下频繁使用,性能要求较高,那么显然使用饿汉模式来避免资源竞争,响应速度更好。
- 缺点:
- 若单例对象的成员数据过多,那么会 导致整个程序启动变慢。
- 如果有多个单例类是相互依赖并且有初始化依赖顺序的,那么饿汉模式在创建的时候是控制不了这种依赖顺序。(可参考
Effective C++
)
实现方式:
首先既然是单例模式,那么我们肯定要保证全局只能产生一个对象,那么我们想到的就是用静态变量,所以我们在 Singleton
类中定义一个静态变量 single_object
,并且用一个静态成员函数 CreateObject()
返回该对象,而这个对象就是这个单例对象。
接着为了防止生成一个栈对象、堆对象,我们得将拷贝构造和赋值重载封掉,并将构造函数私有化而且不实现!
// 饿汉模式
// 优点:简单
// 缺点:可能会导致进程启动慢,且如果有多个单例类对象实例启动顺序不确定。
class Singleton
{
public:static Singleton& CreateObject(){return single_object;}void Print(){cout << "饿汉模式::Print()" << endl;}
private:// 构造函数私有,并且不实现Singleton() {}// 拷贝构造以及赋值重载封掉Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;public:static Singleton single_object; // 声明一个当前类的静态变量
};Singleton Singleton::single_object; // 类外初始化这个静态变量int main()
{// 第一种访问方法:通过CreateObject()直接调用相关接口Singleton::CreateObject().Print();// 第二种访问方法:可以使用引用接收CreateObject(),通过该对象调用相关接口Singleton& s = Singleton::CreateObject();s.Print();Singleton s1; // ❌无法通过编译Singleton* s2 = new Singleton; // ❌无法通过编译static Singleton s3; // ❌无法通过编译return 0;
}// 运行结果:
饿汉模式::Print()
饿汉模式::Print()
💥注意:上面我们在实现饿汉模式以及后面的懒汉模式的时候,都采用 c++11
的 delete
关键字进行防止拷贝发生,而不采用 c++98
的方式!
2、懒汉模式
如果单例对象构造十分耗时或者占用很多资源,比如加载插件啊, 初始化网络连接啊,读取文件啊等等,而有可能该对象程序运行时不会用到,那么也要在程序一开始就进行初始化,就会导致程序启动时非常的缓慢。 所以这种情况使用懒汉模式(延迟加载)更好。
但是懒汉模式的问题就是涉及到了多线程安全问题,所以实现起来当然会复杂许多。
- 优点:
- 因为对象在主程序之后才会创建,所以 程序启动比饿汉模式要快。
- 可以控制不同的单例类的依赖关系以及控制依赖顺序。
- 缺点:
- 涉及到多线程安全问题,需要加锁,实现要复杂许多。
第一种写法:
这种写法涉及到了加锁的问题,所以会复杂一点。和饿汉模式一样,我们需要一个 静态成员函数 CreateObject()
用于获取这个单例对象,不同的是懒汉模式中我们不能直接在类内定义一个静态变量,因为我们要的效果是当我们调用 CreateObject()
的时候,单例对象才会被创建,而不是在程序启动之前就被创建了,所以我们在 类内定义的成员应该是一个静态指针 single_ptr
,并且将其初始化为 nullptr
,这样子当我们去调用 CreateObject()
的时候,如果判断 single_ptr
为空,则进行资源的初始化,否则说明已经被初始化过了,则不会再去初始化它,达到单例对象的目的!
这个时候问题就来了,既然出现了判断以及对成员变量的操作,那么在多线程环境中就有可能会出现问题,所以我们就 需要加锁!
我们可以直接在类内定义一把 静态的锁 _mtx
,然后在单例对象指针判空那个代码块前后分别上锁和解锁。但是这里其实还会涉及一个问题,因为我们的 single_ptr
是通过 new
出来的,那么 可能 new
还会抛异常导致死锁的问题,这个时候其实可以用异常捕获,但是我们一般不这么做,因为写法比较挫。
一般我们都会用一个 守卫锁,在头文件 <mutex>
中就有一个函数模板 lock_guard
可以直接使用,这里为了便于理解,我们手动实现一个简易的守卫锁 LockGuard
,具体看代码,其实不难,就是 在构造函数中上锁,在析构函数中解锁,所维护的就是一个锁对象!
我们自行实现的守卫锁时候,可能会出现一些问题,比如我们在定义锁对象的时候,不能直接使用它对应的锁类型,因为我们在拷贝构造函数中初始化的时候,其实是通过拷贝一个锁对象来赋值的,但是问题来了,锁是不能拷贝的!那咋整❓❓❓
这个时候我们就不能只是简单的定义一个锁对象,我们可以定义一个锁对象的引用或者指针,这里采用引用的方式!
通过锁对象的引用,就必须在构造函数中进行初始化(
C++
语法规定),这样子的话我们引用的其实就是一个传过来的锁对象的别名,就能绕开锁不能赋值的问题了! (搞不清楚这里在说什么的,可以看看下面代码中的守卫锁部分就懂了!)
除此之外,我们会发现如果我们已经生成了一个单例对象,但是如果后续还有线程调用 CreateObject()
的时候,每次都会被我们的守卫锁卡住,这势必会导致我们程序的效率低下,所以这里我们 用两层 if
判空,减少对锁的消耗,虽说写起来比较冗余,但是这大大提高了程序的效率!
另外,我们在上面提到过,单例模式一般来说是不需要释放的,但是还是避免不了有时候我们需要保存资源到日志啊等情况,那么我们就得对这个资源释放问题做一下处理,所以我们下面实现中多写了一个 静态成员函数 DeleteInstance()
用于处理资源释放问题,而我们可以在主程序或者其它函数中去手动释放它!
但是如果我们想释放又忘记释放了呢❓❓❓所以为了保险,我们可以定义一个 自动回收资源类 GC
类(garbage control
),实现并不难,我们可以将其定义在单例类里面,作为一个 内部类,这样子的话就能很方便的取到 Singleton
类中我们写的 DeleteInstance()
。
而这个 GC
类实现的思想就是在析构函数中调用上述的 DeleteInstance()
,要注意的是,因为有可能我们提前手动释放了这段空间,所以 我们需要判断 single_ptr
是否已经为空,是的话说明已经被释放,则我们不做任何动作,防止二次释放;如果不为空我们再去调用 DeleteInstance()
进行释放!
这样子 GC
类就达到该目的:如果提前手动释放,则不会回收;如果没有提前手动释放,则会在这里自动释放!
除此之外还有一个重点,就是我们定义的静态指针 single_ptr
得用 volatile
修饰,因为由于编译器可能会对代码进行优化,导致 重排序等问题,使用 volatile
关键字可以防止编译器优化,保证线程安全。
重排序的解释:
重排序是指在编译器、处理器或者运行时系统中,由于优化等原因,指令执行的顺序可能会被改变,但是最终的执行结果与原本的代码保持一致。
在多线程编程中,重排序可能会导致线程安全问题,因为线程的执行顺序是不确定的,如果在代码中没有正确的同步措施,就有可能导致意想不到的结果。
例如,在单例模式的实现中,如果不加同步措施,那么在多线程环境下,可能会出现多个实例被创建的情况。这是因为在创建实例的代码中,可能会发生指令重排序,导致另一个线程在检查实例是否为空之前,就已经获取到了一个未完成初始化的实例对象。
为了避免这种情况,可以使用
volatile
关键字来修饰单例对象指针。volatile
关键字告诉编译器不要对这个变量进行重排序优化,从而保证了单例对象的正确创建。
// 这里单独写一个守卫锁是为了方便理解
template<class Lock>
class LockGuard
{
public:LockGuard(Lock& lock):_lock(lock){_lock.lock();}~LockGuard(){_lock.unlock();}
private:// 这里的_lock要用引用接收,不然如果只是一个Lock类型的对象,那么在构造函数中是不允许拷贝构造的(锁不允许拷贝)// 当然这里也可以用指针,只不过这里用引用更贴切c++的方式Lock& _lock;
};// 懒汉模式
// 优点:第一次使用实例对象时,创建对象。进程启动无负载。多个单例实例启动顺序自由控制。
// 缺点:复杂
class Singleton
{
public:static Singleton& CreateObject(){// 涉及多线程,要加锁// 但是有可能new会抛异常导致死锁,所以我们可以用一个守卫锁// 除此之外,当前对象已经new出来之后,为了防止后面来的线程都会被锁住影响效率,我们可以用双层判断来防止这种情况if (single_ptr == nullptr){// std::lock_guard<mutex> lock(_mtx); // 当然也可以用库里的lock_guardLockGuard<mutex> lock(_mtx); // 使用守卫锁if (single_ptr == nullptr){single_ptr = new Singleton;}}return *single_ptr;}// 自动回收资源的管理类:// 如果提前手动释放,则不会回收;// 如果没有提前手动释放,则会在这里自动释放class GC{public:~GC(){// 如果没有被提前手动释放,则才会去释放,防止不小心多次释放if (single_ptr != nullptr){// 内部类是外部类的友元,可以直接调用DeleteInstance();}}};static GC _gc; // 定义一个静态成员变量,程序结束时,系统会自动调用它的析构函数从而释放单例对象// 一般我们不需要考虑释放// 但是如果我们想要保存资源的时候,就得处理一下static void DeleteInstance(){// 保存文件等操作,可自行添加// .......// 删除和保存的时候可能有多线程问题,要加锁LockGuard<mutex> lock(_mtx);if (single_ptr != nullptr){delete single_ptr;single_ptr = nullptr; // 记得置空,下一个线程进来的时候判断后就不会进入该代码块}cout << "资源处理完成,释放成功" << endl;}void Print(){cout << "懒汉模式::Print()" << endl;}
private:// 构造函数私有,并且不实现Singleton() {}// 拷贝构造以及赋值重载封掉Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;private:volatile static Singleton* single_ptr; // 单例对象指针,用volatile修饰,防止编译器过度优化static mutex _mtx; // 静态的互斥锁
};volatile Singleton* Singleton::single_ptr = nullptr; // 初始化为空
mutex Singleton::_mtx;
Singleton::GC Singleton::_gc;int main()
{// 第一种访问方法:通过CreateObject()直接调用相关接口Singleton::CreateObject().Print();// 第二种访问方法:可以使用引用接收CreateObject(),通过该对象调用相关接口Singleton& s = Singleton::CreateObject();s.Print();// s.DeleteInstance(); // 如果需要的话就提前手动释放一下//Singleton s1; // ❌//Singleton* s2 = new Singleton; // ❌//static Singleton s3; // ❌return 0;
}// 运行结果:
懒汉模式::Print()
懒汉模式::Print()
资源处理完成,释放成功
第二种写法:
这种写法相比上面就简单多了,其实利用的是 C++11
的一个新特性:局部静态变量初始化是线程安全的!
注意,这在 C++11
之前都是不保证的,所以这种方法不是通用的,但是也是很好用的一种!
其实就是在 静态成员函数 CreateObject()
中直接创建一个局部静态变量,并且返回它的引用,我们都知道,因为局部静态变量对于这个静态成员函数来说只有一份,如果其已经先被初始化了,那么后续进来之后是不会有任何初始化工作的!并且依靠 C++11
更新的这个特性,我们 无需上锁!
class Singleton
{
public:// 会不会有线程安全问题???// c++11之前,这里是不能保证single_object初始化是线程安全的!// c++11之后,这里是线程安全的!// 也就是说,c++11之后,局部静态变量初始化是线程安全的!// 所以这种写法不是通用的,比较少用,但是也是可以用的!static Singleton& CreateObject(){// 直接在CreateObject()创建一个静态单例类对象直接返回static Singleton single_object;return single_object;}void Print(){cout << "懒汉模式::Print()" << endl;}
private:// 构造函数私有,并且不实现Singleton() {}// 拷贝构造以及赋值重载封掉Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;
};int main()
{// 第一种访问方法:通过CreateObject()直接调用相关接口Singleton::CreateObject().Print();// 第二种访问方法:可以使用引用接收CreateObject(),通过该对象调用相关接口Singleton& s = Singleton::CreateObject();s.Print();//Singleton s1; // ❌//Singleton* s2 = new Singleton; // ❌//static Singleton s3; // ❌return 0;
}// 运行结果:
懒汉模式::Print()
懒汉模式::Print()
相关文章:
【C++】设计模式详解:单例模式
文章目录 Ⅰ. 设计一个类,不允许被拷贝Ⅱ. 请设计一个类,只能在堆上创建对象Ⅲ. 请设计一个类,只能在栈上创建对象Ⅳ. 请设计一个类,不能被继承Ⅴ. 请设计一个类,只能创建一个对象(单例模式)&am…...
在ubuntu下一键安装 Open WebUI
该脚本用于自动化安装 Open WebUI,并支持以下功能: 可选跳过 Ollama 安装:通过 --no-ollama 参数跳过 Ollama 的安装。自动清理旧目录:如果安装目录 (~/open-webui) 已存在,脚本会自动删除旧目录并重新安装。完整的依…...
【某大厂一面】数组和链表区别
在 Java 中,数组(Array)和链表(LinkedList)是两种常见的数据结构,它们在存储和操作方式上有显著的区别。了解它们的差异有助于选择适合特定应用场景的结构。下面是数组和链表之间的详细比较。 1. 存储结构…...
MySQL常用数据类型和表的操作
文章目录 (一)常用数据类型1.数值类2.字符串类型3.二进制类型4.日期类型 (二)表的操作1查看指定库中所有表2.创建表3.查看表结构和查看表的创建语句4.修改表5.删除表 (三)总代码 (一)常用数据类型 1.数值类 BIT([M]) 大小:bit M表示每个数的位数,取值范围为1~64,若…...
深入 Rollup:从入门到精通(三)Rollup CLI命令行实战
准备阶段:初始化项目 初始化项目,这里使用的是pnpm,也可以使用yarn或者npm # npm npm init -y # yarn yarn init -y # pnpm pnpm init安装rollup # npm npm install rollup -D # yarn yarn add rollup -D # pnpm pnpm install rollup -D在…...
3.日常英语笔记
screening discrepancies 筛选差异 The team found some screening discrepancies in the data. 团队在数据筛选中发现了些差异。 Don’t tug at it ,or it will fall over and crush you. tug 拉,拽,拖 He tugged the door open with all his might…...
sqlite3 学习笔记
文章目录 前言SQL的概念与表格相关的操作i.创建表格(增)ii 删除表格(删)iii 更改表格(改)iv 查询表格(查) 与记录相关的操作i 插入记录ii 删除记录iii 查询记录iv 修改记录 Linux中使…...
C++ | 红黑树
前言 本篇博客讲解c中数据结构红黑树,看这篇博客之前请先去看: C | AVL树_c avl树能有重复节点吗-CSDN博客 💓 个人主页:普通young man-CSDN博客 ⏩ 文章专栏:C_普通young man的博客-CSDN博客 ⏩ 本人giee: 普通小青…...
使用Ollama 在Ubuntu运行deepseek大模型:以DeepSeek-coder为例
DeepSeek大模型这几天冲上热搜啦! 咱们来亲身感受下DeepSeek模型的魅力吧! 整个操作流程非常简单方便,只需要2步,先安装Ollama,然后执行大模型即可。 安装Ollama 在Ubuntu下安装Ollama非常简单,直接sna…...
詳細講一下RN(React Native)中的列表組件FlatList和SectionList
1. FlatList 基礎使用 import React from react; import { View, Text, FlatList, StyleSheet } from react-native;export const SimpleListDemo: React.FC () > {// 1. 準備數據const data [{ id: 1, title: 項目 1 },{ id: 2, title: 項目 2 },{ id: 3, title: 項目 3…...
《深度揭秘:TPU张量计算架构如何重塑深度学习运算》
在深度学习领域,计算性能始终是推动技术发展的关键因素。从传统CPU到GPU,再到如今大放异彩的TPU(张量处理单元),每一次硬件架构的革新都为深度学习带来了质的飞跃。今天,就让我们深入探讨TPU的张量计算架构…...
QT使用eigen
QT使用eigen 1. 下载eigen https://eigen.tuxfamily.org/index.php?titleMain_Page#Download 下载后解压 2. QT引入eigen eigen源码好像只有头文件,因此只需要引入头文件就好了 qt新建项目后。修改pro文件. INCLUDEPATH E:\222078\qt\eigen-3.4.0\eigen-3.…...
工业“MCU+AI”
随着工业4.0的推进,传统工业设备正向智能化和自动化方向转型。这要求设备具备更高的算力、更强的实时处理能力以及支持AI算法的能力,以应对工业机器人、电机控制、预测性维护等复杂应用场景。 近年来越来越多的芯片厂商纷纷推出工业“MCUAI”产品&#…...
【Linux】Linux C判断两个IPv6地址是否有包含关系
功能说明 要判断两个 IPv6 地址是否具有包含关系,包括前缀的比较,可以通过以下步骤实现: 解析 IPv6 地址和前缀:将两个 IPv6 地址和它们的前缀长度解析为二进制形式。生成掩码:根据前缀长度生成掩码。按位比较&#…...
多模态论文笔记——TECO
大家好,这里是好评笔记,公主号:Goodnote,专栏文章私信限时Free。本文详细解读多模态论文TECO(Temporally Consistent Transformer),即时间一致变换器,是一种用于视频生成的创新模型&…...
AI学习(vscode+deepseek+cline)
1、网页生成不成功时,直接根据提示让模型替你解决问题 2、http://localhost:3000 拒绝链接时,cmd输入命令InetMgr,网站右键新建-配置你的网页代码物理地址,这里我还输入本机登录名及密码了,并把端口地址由默认80修改为…...
物业软件推动物业行业数字化转型 实现高效管理和优质客户体验
内容概要 在当今高速发展的数字化时代,物业软件的出现不仅使物业管理变得更加高效,也为行业转型提供了强大的支持。通过整合多种功能,物业软件显著提升了管理效率和客户体验。例如,在线收费和停车管理功能,让业主享受…...
WGCLOUD使用手册 - 登录验证码如何设置
登录页面默认是不用输入验证码的,但是我们也可以根据自己的实际场景,配置登录页面显示验证码,要求用户输入 提示:您需要需要升级到v3.5.3或以上版本,才可以支持此功能 我们在server配置文件里找到配置项vercodeCheck&…...
C# 9.0记录类型:解锁开发效率的魔法密码
一、引言:记录类型的神奇登场 在 C# 的编程世界中,数据结构就像是构建软件大厦的基石,其重要性不言而喻。然而,传统的数据结构定义方式,尤其是在处理简单的数据承载对象时,常常显得繁琐复杂。例如…...
Python 函数魔法书:基础、范例、避坑、测验与项目实战
Python 函数魔法书:基础、范例、避坑、测验与项目实战 内容简介 本系列文章是为 Python3 学习者精心设计的一套全面、实用的学习指南,旨在帮助读者从基础入门到项目实战,全面提升编程能力。文章结构由 5 个版块组成,内容层层递进…...
Unbutu虚拟机+eclipse+CDT编译调试环境搭建
问题1: 安装CDT,直接Help->eclipse Market space-> 搜cdt , install,等待重启即可. 问题2:C变量不识别vector ’could not be resolved 这是库的头文件没加好,右键Properties->C Build->Enviroment,增加…...
项目部署(springboot项目)
1、安装Nginx,并开启 2、前端项目打包:npm run build:prod--->dist 3、后端项目打包:install--->xxx.jar 4、开放需要的端口号:比如我的后端项目端口号为8282,则需要防火墙和服务器同时开发8282端口 5、将di…...
Spring MVC拦截器
文章目录 1. 拦截器(interceptor)的作用2. 拦截器和过滤器区别3. 拦截器是快速入门 1. 拦截器(interceptor)的作用 Spring MVC 的拦截器类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行预处理和后处理。 将拦截器按一定的顺序联结成一条链,这条…...
Nginx 路由匹配(Nginx Route Matching)
从小白到高手:深入Nginx 路由匹配 在现代互联网应用中,Nginx 作为一款高性能的 Web 服务器,因其灵活性和高效性而广泛应用于各类网站和服务。Nginx 的路由匹配规则是其核心功能之一,负责决定如何处理传入的请求。通过这些规则&am…...
基于RIP的MGRE实验
实验拓扑 实验要求 按照图示配置IP地址配置静态路由协议,搞通公网配置MGRE VPNNHRP的配置配置RIP路由协议来传递两端私网路由测试全网通 实验配置 1、配置IP地址 [R1]int g0/0/0 [R1-GigabitEthernet0/0/0]ip add 15.0.0.1 24 [R1]int LoopBack 0 [R1-LoopBack0]i…...
Spring Boot 中的事件发布与监听:深入理解 ApplicationEventPublisher(附Demo)
目录 前言1. 基本知识2. Demo3. 实战代码 前言 🤟 找工作,来万码优才:👉 #小程序://万码优才/r6rqmzDaXpYkJZF 基本的Java知识推荐阅读: java框架 零基础从入门到精通的学习路线 附开源项目面经等(超全&am…...
【Java基础-41.5】深入解析Java异常链:构建清晰的错误追踪体系
在Java编程中,异常处理是保证程序健壮性和可维护性的重要部分。然而,在实际开发中,异常往往不是孤立发生的,而是由一系列相关的异常引发的。为了更好地理解和处理这种复杂的异常场景,Java引入了 异常链(Exc…...
STM32使用VScode开发
文章目录 Makefile形式创建项目新建stm项目下载stm32cubemx新建项目IED makefile保存到本地arm gcc是编译的工具链G++配置编译Cmake +vscode +MSYS2方式bilibiliMSYS2 统一环境配置mingw32-make -> makewindows环境变量Cmake CmakeListnijia 编译输出elfCMAKE_GENERATOR查询…...
特权模式docker逃逸
目录 1.环境 2.上线哥斯拉 3.特权模式逃逸 1.判断是否为docker环境 2.判断是否为特权模式 3.挂载宿主机磁盘到docker 4.计划任务反弹shell 1.环境 ubuntu部署一个存在CVE-2017-12615的docker: (ip:192.168.117.147) kali(ip:192.168.117.128) 哥斯拉 2.上线哥斯拉…...
装出字符串中国第一个匹配项的下标
hello 大家好!今天开写一个新章节,每一天一道算法题。让我们一起来学习算法思维吧! function strStr(haystack, needle) {return haystack.indexOf(needle); }// 测试示例 const haystack "sadbutsad"; const needle "sad&q…...
从腾讯云数据仓库TCHouse安全地转移数据到AWS Redshift
实现从AWS Direct Connect连接到腾讯云数据仓库TCHouse-P、TCHouse-C或TCHouse-D,然后使用AWS Glue读取数据并在AWS Redshift中创建对应表并复制数据,需要按照以下步骤进行操作: 网络连接设置 AWS Direct Connect配置: 在AWS管理…...
DataComp:探索下一代多模态数据集
目录 一、TL;DR 二、方法 2.1 为什么要单独研究数据质量? 2.2 数据质量的研究范式 三、其他的工作(related work) 3.1 传统的做法 3.2 数据剪枝和去重(paper直接翻译) 四、DataComp的benchmark 4.1 竞赛条件限…...
【linux】Linux 常见目录特性、权限和功能
目录特性默认权限主要功能/用途/根目录,所有目录的起点755文件系统的顶层目录,包含所有其他子目录和文件/bin基础二进制命令目录(系统启动和修复必需的命令)755存放所有用户可用的基本命令(如 ls, cp, bash 等…...
基于SpringBoot电脑组装系统平台系统功能实现六
一、前言介绍: 1.1 项目摘要 随着科技的进步,计算机硬件技术日新月异,包括处理器(CPU)、主板、内存、显卡等关键部件的性能不断提升,为电脑组装提供了更多的选择和可能性。不同的硬件组合可以构建出不同类…...
Direct2D 极速教程(1) —— 画图形
极速导航 Direct2D 简介创建新项目:001-DrawGraphics弄一个白窗口在窗口上画图 Direct2D 简介 大家在学 WINAPI 的时候的时候有没有想过,怎么在一副窗口上画图呢?大家知道 Windows 系统是 GUI 图形用户界面 系统,以 Graphics 图形…...
DF 开发1
https://www.bilibili.com/video/BV1RFChYxEhJ/ 多个 workspace 图片上传 S3 上传大量文档 https://www.bilibili.com/video/BV1ySsEeUE6i 解决方案 返回 metadata https://www.bilibili.com/video/BV1t3e5eaENo 给出内容引用出处 模型负载均衡 可以以 ollama 在不同端口起服…...
[Computer Vision]实验二:图像特征点提取
目录 一、实验内容 二、实验过程及结果 2.1 Harris角点检测 2.2 SIFT算法 三、实验小结 一、实验内容 采用Harris与SIFT分别提取特征点及对应的描述子,对比两者的区别(特征点数量、分布、描述子维度、图像变化对二者的影响等)利用特征匹…...
在做题中学习(82):最小覆盖子串
解法:同向双指针——>滑动窗口 思路:题目要求找到s里包含t所有字符的最小子串,这就需要记录在s中每次查找并扩大范围时所包含进去的字符种类是否和t的相同,并且:题目提示t中会有重复字符,因此不能简单认…...
< OS 有关> BaiduPCS-Go 程序的 菜单脚本 Script: BaiduPCS-Go.Menu.sh (bdgo.sh)
目标: 使用 日本阿里云的 VPM 传输文件。 暂时方案: 使用 主机JPN 下载 https://huggingface.co/ 上模型从 JPN 放到 度狗上在家里从狗度下载 为了减少编程,尽量使用现在软件 ,就找到 GitHub - qjfoidnh/BaiduPCS-Go: iikira…...
redis缓存和springboot缓存包冲突怎么办
如果Redis缓存与Spring Boot缓存包发生冲突,可以采取以下几种解决方案: 排除Spring Boot缓存包:在pom.xml文件中排除Spring Boot的缓存依赖,以避免与Redis缓存冲突。例如: <dependency><groupId>org.spr…...
云计算技术深度解析与代码使用案例
云计算技术深度解析与代码使用案例 引言 随着信息技术的飞速发展,云计算作为一种革命性的技术,正在逐步改变我们的生活和工作方式。云计算不仅提供了前所未有的计算能力和存储资源,还以其灵活性和可扩展性,成为现代企业数字化转型的重要支撑。本文将深入探讨云计算的核心…...
【教学类-89-01】20250127新年篇01—— 蛇年红包(WORD模版)
祈愿在2025蛇年里, 伟大的祖国风调雨顺、国泰民安、每个人齐心协力,共同经历这百年未有之大变局时代(国际政治、AI技术……) 祝福亲友同事孩子们平安健康(安全、安全、安全)、巳巳如意! 背景需…...
React Router v6配置路由守卫
首先准备好以下页面 登录页:用户可以在此页面登录。 受保护页:只有登录的用户可以访问,否则会重定向到登录页。 公共页面:不需要鉴权,任何人都可以访问。 1. 安装依赖 首先,我们需要安装 react-router-do…...
双层Git管理项目,github托管显示正常
双层Git管理项目,github托管显示正常 背景 在写React项目时,使用Next.js,该项目默认由git托管。但是我有在项目代码外层记笔记的习惯,我就在外层使用了git托管。 目录如下 code 层内也有.git 文件,对其托管。 我没太在意&…...
Linux--权限
Linux系统的权限管理是保障系统安全的重要机制,以下详细讲解权限相关概念及操作指令: 一、基础权限机制 1. 权限的三元组,读(r)、写(w)、执行(x) 每个文件或目录有三组…...
第25章 项目启航前的密谈
在那弥漫着严谨与专注气息的会议室里,苏睿所长端坐在会议桌前,宛如一座沉稳的山峰,散发着一种让人安心的力量。他的神情认真而庄重,目光中透着几分感慨,仿佛在时光的长河中回溯着项目的点点滴滴。微微侧身看向东方艾艾…...
ModernBERT 为我们带来了哪些启示?
当谷歌在 2018 年推出 BERT 模型时,恐怕没有料到这个 3.4 亿参数的模型会成为自然语言处理领域的奠基之作。 六年后的今天,面对动辄千亿参数的大语言模型浪潮,Answer.AI、LightOn与 HuggingFace 联手打造的 ModernBERT 却选择了一条返璞归真的…...
【MySQL】--- 复合查询 内外连接
Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏: MySQL 🏠 基本查询回顾 假设有以下表结构: 查询工资高于500或岗位为MANAGER的雇员,同时还要满足他们的姓名首字母为…...
Android Studio打包APK
1.导出APK安装包 如果是首次打包,Create new 单击蓝色对话框右边文件夹📂图标 ,选择密钥保存路径,然后在下方File name对话框中填写您想要名称,再点击OK回到密钥创建对话框。 在此对话框中填写密码(Passwo…...
RKNN_C++版本-YOLOV5
1.背景 为了实现低延时,所以开始看看C版本的rknn的使用,确实有不足的地方,请指正(代码借鉴了rk官方的仓库文件)。 2.基本的操作流程 1.读取模型初始化 // 设置基本信息 // 在postprocess.h文件中定义,详见…...