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

C++复习

线程库(类)

在C++11之前,涉及到多线程问题,都是和平台相关的,比如Windows和Linux下各有自己的接口,这使得代码的可移植性比较差。C++11中最重要的特性就是对线程进行了支持,使得C++在并行编程时不需要依赖第三方库,而且在原子操作中还引入了原子类的概念。

thread的带参的构造函数的定义如下:

template <class Fn, class... Args>
explicit thread (Fn&& fn, Args&&... args);

线程类的使用: 

void func(int n)
{for (int i = 0; i <= n; i++){cout << i << endl;}
}
int main()
{thread t3 = thread(func, 10);t3.join();return 0;
}
  • 如果创建线程对象时提供了线程函数,那么就会启动一个线程来执行这个线程函数,该线程与主线程一起运行。
  • thread类是防拷贝的,不允许拷贝构造和拷贝赋值,但是可以移动构造和移动赋值,可以将一个线程对象关联线程的状态转移给其他线程对象,并且转移期间不影响线程的执行。
  • 线程函数的参数是以值拷贝的方式拷贝到线程栈空间中的,就算线程函数的参数为引用类型,在线程函数中修改后也不会影响到外部实参,因为其实际引用的是线程栈中的拷贝,而不是外部实参

如果要通过线程函数的形参改变外部的实参,可以参考以下三种方式:

方式一:借助std::ref函数

当线程函数的参数类型为引用类型时,如果要想线程函数形参引用的是外部传入的实参,而不是线程栈空间中的拷贝,那么在传入实参时需要借助ref函数保持对实参的引用。比如:

void add(int& num)
{num++;
}
int main()
{int num = 0;thread t(add, ref(num));t.join();cout << num << endl; //1return 0;
}

线程回收:join与,ref值引用

启动一个线程后,当这个线程退出时,需要对该线程所使用的资源进行回收,否则可能会导致内存泄露等问题。

主线程创建新线程后,可以调用join函数等待新线程终止,当新线程终止时join函数就会自动清理线程相关的资源。join函数清理线程的相关资源后,thread对象与已销毁的线程就没有关系了,因此一个线程对象一般只会使用一次join,否则程序会崩溃。比如:

void func(int n)
{for (int i = 0; i <= n; i++){cout << i << endl;}
}
int main()
{thread t(func, 20);//  t.detach(); 主线程直接分离线程,不再阻塞t.join();t.join(); //程序崩溃return 0;
}

因此采用join方式结束线程时,join的调用位置非常关键,为了避免上述问题,可以采用RAII的方式对线程对象进行封装,也就是利用对象的生命周期来控制线程资源的释放。比如:

class myThread
{
public:myThread(thread& t):_t(t){}~myThread(){if (_t.joinable())_t.join();}//防拷贝myThread(myThread const&) = delete;myThread& operator=(const myThread&) = delete;
private:thread& _t;
};

互斥量库(mutex)

mutex锁是C++11提供的最基本的互斥量,mutex对象之间不能进行拷贝,也不能进行移动。

void func(int n, mutex& mtx)
{mtx.lock(); //for循环体外加锁for (int i = 1; i <= n; i++){//mtx.lock(); //for循环体内加锁cout << i << endl;//mtx.unlock();}mtx.unlock();
}
int main()
{mutex mtx;thread t1(func, 100, ref(mtx));thread t2(func, 100, ref(mtx));t1.join();t2.join();return 0;
}

锁资源和线程资源都需要我们进行管理。都可以使用RAII风格管理。lock_guard和unique_lock

mutex mtx;
void func()
{//...//匿名局部域{lock_guard<mutex> lg(mtx); //调用构造函数加锁FILE* fout = fopen("data.txt", "r");if (fout == nullptr){//...return; //调用析构函数解锁}} //调用析构函数解锁//...
}
int main()
{func();return 0;
}

如下场景就适合使用unique_lock:

  • 要用互斥锁保护函数1的大部分代码,但是中间有一小块代码调用了函数2,而调用函数2时不需要用函数1中的互斥锁进行保护,函数2内部的代码由其他互斥锁进行保护。
  • 因此在调用函数2之前需要对当前互斥锁进行解锁,当函数2调用返回后再进行加锁,这样当调用函数2时其他线程调用函数1就能够获取到这个锁。

原子类库

原子类解决线程安全问题

C++11中引入了原子操作类型,使得线程间数据的同步变得非常高效。

  • 为了防止意外,标准库已经将atomic模板类中的拷贝构造、移动构造、operator=默认删除掉了。
  • 原子类型不仅仅支持原子的++操作,还支持原子的--、加一个值、减一个值、与、或、异或操作。

如下:两个线程对同一个共享变量进行++操作

void func(atomic_int& n, int times)
{for (int i = 0; i < times; i++){n++;}
}
int main()
{atomic_int n = { 0 };int times = 100000; //每个线程对n++的次数thread t1(func, ref(n), times);thread t2(func, ref(n), times);t1.join();t2.join(); //先join等两个子线程执行完毕cout << n << endl; //打印n的值return 0;
}

实现两个线程交替打印1-100

尝试用两个线程交替打印1-100的数字,要求一个线程打印奇数,另一个线程打印偶数,并且打印数字从小到大依次递增。

int main()
{int n = 100;mutex mtx;condition_variable cv;bool flag = true;//奇数thread t1([&]{int i = 1;while (i <= 100){unique_lock<mutex> ul(mtx);cv.wait(ul, [&flag]()->bool{return flag; }); //等待条件变量满足cout << this_thread::get_id() << ":" << i << endl;i += 2;flag = false;cv.notify_one(); //唤醒条件变量下等待的一个线程}});//偶数thread t2([&]{int j = 2;while (j <= 100){unique_lock<mutex> ul(mtx);cv.wait(ul, [&flag]()->bool{return !flag; }); //等待条件变量满足cout << this_thread::get_id() << ":" << j << endl;j += 2;flag = true;cv.notify_one(); //唤醒条件变量下等待的一个线程}});t1.join();t2.join();return 0;
}

C++异常

异常是面向对象语言常用的一种处理错误的方式,当一个函数发现自己无法处理的错误时就可以抛出异常,让函数直接或间接的调用者处理这个错误。

  • throw:当程序出现问题时,可以通过throw关键字抛出一个异常。
  • try:try块中放置的是可能抛出异常的代码,该代码块在执行时将进行异常错误检测,try块后面通常跟着一个或多个catch块。
  • catch:如果try块中发生错误,则可以在catch块中定义对应要执行的代码块。

异常的抛出和捕获的匹配原则:

  • 异常是通过throw 对象而引发的,该对象的类型决定了应该激活哪个catch的处理代码,如果抛出的异常对象没有捕获,或是没有匹配类型的捕获,那么程序会终止报错。
  • 被选中的处理代码(catch块)是调用链中与该对象类型匹配且离抛出异常位置最近的那一个。
  • 抛出异常对象后,会生成一个异常对象的拷贝,因为抛出的异常对象可能是一个临时对象,所以会生成一个拷贝对象,这个拷贝的临时对象会在被catch以后销毁。(类似于函数的传值返回)
  • catch(...)可以捕获任意类型的异常,但捕获后无法知道异常错误是什么。
  • 实际异常的抛出和捕获的匹配原则有个例外,捕获和抛出的异常类型并不一定要完全匹配,可以抛出派生类对象,使用基类进行捕获,这个在实际中非常有用。

最基础的异常类至少需要包含错误编号和错误描述两个成员变量,甚至还可以包含当前函数栈帧的调用链等信息。该异常类中一般还会提供两个成员函数,分别用来获取错误编号和错误描述。比如:

class Exception
{
public:Exception(int errid, const char* errmsg):_errid(errid), _errmsg(errmsg){}int GetErrid() const{return _errid;}virtual string what() const{return _errmsg;}
protected:int _errid;     //错误编号string _errmsg; //错误描述//...
};

其他模块如果要对这个异常类进行扩展,必须继承这个基础的异常类,可以在继承后的异常类中按需添加某些成员变量,或是对继承下来的虚函数what进行重写,使其能告知程序员更多的异常信息。异常类的成员变量不能设置为私有,因为私有成员在子类中是不可见的,基类Exception中的what成员函数最好定义为虚函数,方便子类对其进行重写,从而达到多态的效果。

智能指针

智能指针的原理

实现智能指针时需要考虑以下三个方面的问题:

  1. 在对象构造时获取资源,在对象析构的时候释放资源,利用对象的生命周期来控制程序资源,即RAII特性。
  2. *->运算符进行重载,使得该对象具有像指针一样的行为。
  3. 智能指针对象的拷贝问题。浅拷贝析构两次

auto_ptr管理权转移

auto_ptr是C++98中引入的智能指针,auto_ptr通过管理权转移的方式解决智能指针的拷贝问题,保证一个资源在任何时刻都只有一个对象在对其进行管理,这时同一个资源就不会被多次释放了。

 unique_ptr防拷贝

unique_ptr是C++11中引入的智能指针,unique_ptr通过防拷贝的方式解决智能指针的拷贝问题,也就是简单粗暴的防止对智能指针对象进行拷贝,这样也能保证资源不会被多次释放

shared_ptr 引用计数

类模板,shared_ptr<int> p(new int(0));

namespace xwy
{template<class T>class shared_ptr{private://++引用计数void AddRef(){_pmutex->lock();(*_pcount)++;_pmutex->unlock();}//--引用计数void ReleaseRef(){_pmutex->lock();bool flag = false;if (--(*_pcount) == 0) //将管理的资源对应的引用计数--{if (_ptr != nullptr){cout << "delete: " << _ptr << endl;delete _ptr;_ptr = nullptr;}delete _pcount;_pcount = nullptr;flag = true;}_pmutex->unlock();if (flag == true){delete _pmutex;}}public://RAIIshared_ptr(T* ptr = nullptr):_ptr(ptr), _pcount(new int(1)), _pmutex(new mutex){}~shared_ptr(){ReleaseRef();}shared_ptr(shared_ptr<T>& sp):_ptr(sp._ptr), _pcount(sp._pcount), _pmutex(sp._pmutex){AddRef();}shared_ptr& operator=(shared_ptr<T>& sp){if (_ptr != sp._ptr) //管理同一块空间的对象之间无需进行赋值操作{ReleaseRef();         //将管理的资源对应的引用计数--_ptr = sp._ptr;       //与sp对象一同管理它的资源_pcount = sp._pcount; //获取sp对象管理的资源对应的引用计数_pmutex = sp._pmutex; //获取sp对象管理的资源对应的互斥锁AddRef();             //新增一个对象来管理该资源,引用计数++}return *this;}//获取引用计数int use_count(){return *_pcount;}//可以像指针一样使用T& operator*(){return *_ptr;}T* operator->(){return _ptr;}private:T* _ptr;        //管理的资源int* _pcount;   //管理的资源对应的引用计数mutex* _pmutex; //管理的资源对应的互斥锁};
}
std::shared_ptr的定制删除器

定制删除器的用法

第二个参数传入一个 仿函数,再智能指针析构时调用

template<class T>
struct DelArr
{void operator()(const T* ptr){cout << "delete[]: " << ptr << endl;delete[] ptr;}
};
int main()
{std::shared_ptr<ListNode> sp1(new ListNode[10], DelArr<ListNode>());std::shared_ptr<FILE> sp2(fopen("test.cpp", "r"), [](FILE* ptr){cout << "fclose: " << ptr << endl;fclose(ptr);});return 0;
}

weak_ptr解决循环引用

weak_ptr支持用shared_ptr对象来构造weak_ptr对象,构造出来的weak_ptr对象与shared_ptr对象管理同一个资源,但不会增加这块资源对应的引用计数。

将ListNode中的next和prev成员的类型换成weak_ptr就不会导致循环引用问题了,此时当node1和node2生命周期结束时两个资源对应的引用计数就都会被减为0,进而释放这两个结点的资源。比如:

struct ListNode
{std::weak_ptr<ListNode> _next;std::weak_ptr<ListNode> _prev;int _val;~ListNode(){cout << "~ListNode()" << endl;}
};
int main()
{std::shared_ptr<ListNode> node1(new ListNode);std::shared_ptr<ListNode> node2(new ListNode);cout << node1.use_count() << endl;cout << node2.use_count() << endl;node1->_next = node2;node2->_prev = node1;//...cout << node1.use_count() << endl;cout << node2.use_count() << endl;return 0;
}

C语言中的类型转换

C语言中有两种形式的类型转换,分别是隐式类型转换和显式类型转换:

  • 隐式类型转换:编译器在编译阶段自动进行,能转就转,不能转就编译失败。
  • 显式类型转换:需要用户自己处理,以(指定类型)变量的方式进行类型转换。

需要注意的是,只有相近类型之间才能发生隐式类型转换,比如int和double表示的都是数值,只不过它们表示的范围和精度不同。而指针类型表示的是地址编号,因此整型和指针类型之间不会进行隐式类型转换,如果需要转换则只能进行显式类型转换。比如:

int main()
{//隐式类型转换int i = 1;double d = i;cout << i << endl;cout << d << endl;//显式类型转换int* p = &i;int address = (int)p;cout << p << endl;cout << address << endl;return 0;
}

int a = xxx_cast<int> (b);

static_cast

static_cast用于相近类型之间的转换,编译器隐式执行的任何类型转换都可用static_cast,但它不能用于两个不相关类型之间转换。比如:

int main()
{double d = 12.34;int a = static_cast<int>(d);cout << a << endl;int* p = &a;// int address = static_cast<int>(p); //errorreturn 0;
}

reinterpret_cast

用于两个不相关类型之间的转换。比如指针转整型

int main()
{int a = 10;int* p = &a;int address = reinterpret_cast<int>(p);cout << address << endl;return 0;
}

const_cast必须转指针

const_cast用于删除变量的const属性,转换后就可以对const变量的值进行修改。提供一种修改const常量的方法,C语言中可以间接修改const常量,C++类型检查更严格。比如:

int main()
{const int a = 2; //加valatile 下面变成int* p = const_cast<int*>(&a);*p = 3;cout << a << endl;  //2cout << *p << endl; //3return 0;
}

dynamic_cast转为子类指针

向上转型: 子类的指针(或引用)→ 父类的指针(或引用)。
向下转型: 父类的指针(或引用)→ 子类的指针(或引用)。

其中,向上转型就是所说的切割/切片,是语法天然支持的,不需要进行转换,而向下转型是语法不支持的,需要进行强制类型转换。

使用dynamic_cast进行向下转型则是安全的,如果父类的指针(或引用)指向的是子类对象那么dynamic_cast会转换成功,但如果父类的指针(或引用)指向的是父类对象那么dynamic_cast会转换失败并返回一个空指针。

class A
{
public:virtual void f(){}
};
class B : public A
{};
void func(A* pa)
{B* pb1 = (B*)pa;               //不安全B* pb2 = dynamic_cast<B*>(pa); //安全cout << "pb1: " << pb1 << endl;cout << "pb2: " << pb2 << endl;
}
int main()
{A a;B b;func(&a);func(&b);return 0;
}

说明一下: dynamic_cast只能用于含有虚函数的类,因为运行时类型检查需要运行时的类型信息,而这个信息是存储在虚函数表中的,只有定义了虚函数的类才有虚函数表。

explicit

explicit用来修饰单参数构造函数,从而禁止单参数构造函数的隐式转换。

RTTI(Run-Time Type Identification)就是运行时类型识别。

C++通过以下几种方式来支持RTTI:

  1. typeid:在运行时识别出一个对象的类型。
  2. dynamic_cast:在运行时识别出一个父类的指针(或引用)指向的是父类对象还是子类对象。
  3. decltype:在运行时推演出一个表达式或函数返回值的类型。

相关文章:

C++复习

线程库(类&#xff09; 在C11之前&#xff0c;涉及到多线程问题&#xff0c;都是和平台相关的&#xff0c;比如Windows和Linux下各有自己的接口&#xff0c;这使得代码的可移植性比较差。C11中最重要的特性就是对线程进行了支持&#xff0c;使得C在并行编程时不需要依赖第三方…...

如何使用docker配置ros-noetic环境并使用rviz,gazebo

参考链接&#xff1a;【Ubuntu】Docker中配置ROS并可视化Rviz及Gazebo_docker ros-CSDN博客 前言&#xff1a; 其实这个东西是相当必要的&#xff0c;因为我们有时候需要在一台电脑上跑好几个项目&#xff0c;每个项目都有不同的依赖&#xff0c;这些依赖冲突搞得人头皮发麻&…...

计算机网络中相比于RIP,路由器动态路由协议OSPF有什么优势?

好的!以下是关于路由信息协议(RIP,Routing Information Protocol)的技术原理详解,以及其与OSPF(Open Shortest Path First)的对比分析。内容分为技术原理、对比优势和不足两部分。 一、RIP技术原理深度解析 1. 基本概念 协议类型:RIP属于距离向量路由协议(Distance-V…...

相似命令对比

awk 命令用法表格 场景命令示例说明示例输入文件内容 (input.txt)输出结果1. 基础字段提取awk -F: {print $1} /etc/passwd按分隔符提取第1列&#xff08;如用户名&#xff09;。root:x:0:0:root:/root:/bin/bashroot2. 多字段组合输出awk -F: {print $1, $3, $7} /etc/passwd…...

Vuerouter 的底层实现原理

文章目录 前言&#x1f9e9; Vue Router 底层实现核心原理&#x1f9e0; 执行流程图&#xff08;简化版&#xff09;&#x1f50d; 核心模块源码原理&#xff08;简要&#xff09;① 路由注册与匹配&#xff08;createRouterMatcher&#xff09;② 历史模式管理器&#xff08;c…...

按拼音首字母进行排序组成新的数组(vue)

数据按首字母相同的组成新的数组&#xff0c;使用​​拼音&#xff08;Pinyin&#xff09;转换​​ 比如想要的效果&#xff1a; 下载 npm install pinyin代码&#xff1a; import pinyin from "pinyin"; let studentAllList [{onLine: true,points: undefined…...

在IPv6头部中,Next Header字段

在IPv6头部中&#xff0c;Next Header字段 在IPv6头部中&#xff0c;Next Header字段是一个8位的字段&#xff0c;它的作用是指示下一个头部扩展的类型或者最终的传输层协议类型。这个字段的值决定了数据包中紧随IPv6头部之后的头部扩展的类型&#xff0c;或者是直接指向传输层…...

vue项目部署后部分子页面刷新后403

经过我的仔细分析&#xff1b;终于找到了是刷新后路径后面自动拼接了 / &#xff1b;如 66.66.66.66/aPage 刷新后变成了 66.66.66.66/aPage/ 导致403 方法一&#xff1a; 修改路由为hash模式 // router/index.jsimport { createRouter, createWebHistory, createWebHashHist…...

C# NX二次开发:曲线和点位相关UFUN函数详解

大家好&#xff0c;今天要介绍查询曲线上点位和返回沿着曲线偏移一定距离的UFUN函数。 &#xff08;1&#xff09;UF_MODL_ask_curve_points&#xff1a;这个函数的定义为按照给定条件查询曲线上的点位。 Defined in: uf_modl_curves.h Overview Returns an array of 3D …...

服务器数据恢复—硬盘坏道导致EqualLogic存储不可用的数据恢复

服务器存储数据恢复环境&故障&#xff1a; 一台EqualLogic某型号存储中有一组由16块SAS硬盘组建的RAID5阵列。上层采用VMFS文件系统&#xff0c;存放虚拟机文件&#xff0c;上层一共分了4个卷。 磁盘故障导致存储不可用&#xff0c;且设备已经过保。 服务器存储数据恢复过程…...

【2019 CWE/SANS 25 大编程错误清单】12越界写入

案例1&#xff1a; void tonly_aw21036_led_drv_pwm_init(tonly_gpio_pin_t gpio_pin, uint8_t pwm) {uint8_t pin gpio_pin - AW21036_GPIO_PIN_START;if (pin < AW21036_LED_MAX_CHANNEL){aw21036_ctx.pwm[pin] pwm; /* 有效通道号: 0-35 */}else{TONLY_LED_LOG_E(&qu…...

redis bitmap数据类型调研

一、bitmap是什么&#xff1f; redis原文&#xff1a; Bitmaps are not an actual data type, but a set of bit-oriented operations defined on the String type . This means that bitmaps can be used with string commands, and most importantly with SET and GET. 翻…...

[Windows] Ghost Downloader v3.5.9 开源多线程下载工具

[Windows] Ghost Downloader 链接&#xff1a;https://pan.xunlei.com/s/VOPejV3veb6v-im-wVmMkXkhA1?pwdpzwk# Ghost Downloader 是一款专为Windows平台设计的多线程下载工具&#xff0c;完全由Python语言开发。它以其高效的多线程下载技术和断点续传功能而著称&#xff0c…...

互联网大厂Java求职面试:AI集成与云原生架构设计

互联网大厂Java求职面试&#xff1a;AI集成与云原生架构设计 面试场景&#xff1a;技术总监与程序员郑薪苦的对话 技术总监&#xff1a;郑薪苦&#xff0c;我们今天来聊聊你在AI集成场景中的经验。你有没有尝试过将Spring AI与大模型结合&#xff1f; 郑薪苦&#xff1a;有啊…...

gitignore的相关用法

gitignore .gitignore 是 git 用于管理需要忽略追踪的文件。.gitignore 一般用于远程仓库多人协作的场景&#xff0c;最常见的情况是&#xff0c;使用 MacOS 系统的程序员要在 .gitignore 中添加 .DS_Store 防止将其推送至仓库中。或在开发代码时&#xff0c;将调试文件忽略&a…...

前端取经路——工程化渡劫:八戒的构建之道

大家好,我是老十三,一名前端开发工程师。前端工程化就像八戒的钉耙,看似简单却能降妖除魔。在本文中,我将带你探索前端工程化的九大难题,从模块化组织到CI/CD流程,从代码规范到自动化测试,揭示这些工具背后的核心原理。无论你是初学者还是资深工程师,这些构建之道都能帮…...

Android 数据持久化之 Room 数据库存储

一、简介 Room 是 Google 推出的 Android 持久层框架,建立在 SQLite 之上,提供了一个抽象层,简化了数据库操作。它通过注解和编译时检查来确保数据操作的正确性。 Room 主要由以下三个组件组成: Entity(实体):定义封装实际数据的实体类,每个实体类对应数据库中的一个…...

Selenium Web自动化测试学习笔记(一)

自动化测试 技术手段模拟人工&#xff0c;执行重复性任务&#xff0c;准确率100%&#xff0c;高于人工 selenium 可通过浏览器驱动控制浏览器&#xff0c;通过元素定位模拟人工&#xff0c;实现web自动化&#xff0c;没有焦点&#xff08;把浏览器放在最小化依然可以&#x…...

一个项目的周测试的文档(Billing Service 测试文档)

目录 Pending Pool 各项功能测试... 2 1. Assign 分配功能。测试结果&#xff1a; ok. 2 2. Reset 功能。 测试结果&#xff1a; OK. 3 3. Discard 功能。测试结果&#xff1a; 提示discard成功&#xff0c;但是historical job没有找到记录... 3 4. E…...

二分查找习题

一、二叉搜索树与双向链表&#xff08;剑指 Offer JZ36 &#xff09; 解题思路要点 - 利用中序遍历特性&#xff1a;二叉搜索树的中序遍历结果是有序序列&#xff0c;这是将二叉搜索树转化为有序双向链表的关键。通过中序遍历可以按从小到大的顺序访问节点&#xff0c;满足…...

JumpServer批量添加资产

环境说明&#xff1a;我的环境是H3C网络设备环境 一、在linux系统环境下通过Python脚本获取交换机信息&#xff0c;IP地址和设备名称一一对应&#xff0c;脚本如下&#xff1a; cat get_device-sysname.py import re from netmiko import ConnectHandler from concurrent.fut…...

使用 Python 与 Java 实现接入 AI 大模型的 MCP 协议:原理与实战

一、什么是 MCP 协议&#xff1f; MCP&#xff08;Model Context Protocol&#xff09; 是一种专为远程控制和管理 AI 大模型而设计的通信协议。它允许客户端通过网络向服务器发送请求&#xff0c;以执行诸如模型推理、状态查询、参数更新等操作&#xff0c;并接收相应的结果。…...

Nginx核心原理以及案例分析(AI)

一、Nginx核心原理分析 1. ‌事件驱动与非阻塞模型‌ ‌Epoll异步机制‌&#xff1a;基于Linux的epoll模型实现异步非阻塞I/O处理&#xff0c;单线程可高效管理数万并发连接&#xff0c;避免传统select模型的轮询性能瓶颈。‌多进程架构‌&#xff1a;采用Master-Worker模式&…...

ChromeDriverManager的具体用法

ChromeDriverManager 是 webdriver_manager 库的一部分&#xff0c;它用于自动管理 ChromeDriver 的下载和更新。使用 ChromeDriverManager 可以避免手动下载 ChromeDriver 并匹配系统中安装的 Chrome 浏览器版本。以下是 ChromeDriverManager 的基本用法&#xff1a; 步骤 1…...

Linux:认识基础IO

1.理解"⽂件" 1.1狭义理解 ⽂件在磁盘⾥ 磁盘是永久性存储介质&#xff0c;因此⽂件在磁盘上的存储是永久性的 磁盘是外设&#xff08;即是输出设备也是输⼊设备&#xff09; 磁盘上的⽂件 本质是对⽂件的所有操作&#xff0c;都是对外设的输⼊和输出 简称 IO 1.2广…...

SimpleMindMap:一个支持AI的思维导图软件

SimpleMindMap&#xff08;思绪思维导图&#xff09;是一款开源、跨平台且功能丰富的思维导图工具&#xff0c;支持 Web 端及多平台客户端&#xff08;Windows、macOS、Linux&#xff09;。 SimpleMindMap 提供的主要功能如下&#xff1a; 插件化设计&#xff0c;除了核心功能…...

数据库故障排查指南:MySQL 解决常见问题解决

数据库是现代 IT 系统的核心引擎,承载着企业最重要的数据资产。数据库的稳定、高效运行直接关系到业务的生死存亡。然而,由于软硬件、配置、应用访问等多种因素的影响,数据库故障难以完全避免。当故障发生时,能够迅速定位、分析并解决问题,同时确保数据安全不受影响,是每…...

2025年特种作业操作证考试题库及答案(登高架设作业)

一、单选题 202.带电跨越架羊角撑杆高度&#xff08;  &#xff09;m。 A.1 B.1.1 C.1.2 答案:B 203.跨越架拉线地锚埋深必须按&#xff08;  &#xff09;及架体设计要求进行。 A.现场情况决定 B.土质情况 C.地锚设计分坑图 答案:C 204.单排脚手架洞口处&#…...

Open CASCADE学习|ApplicationFramework 框架使用指南

在现代 CAD&#xff08;计算机辅助设计&#xff09;应用开发中&#xff0c;构建一个高效、可扩展且用户友好的应用程序框架是至关重要的。Open CASCADE&#xff08;简称 OCC&#xff09;提供了一个功能强大的 ApplicationFramework&#xff08;应用程序框架&#xff09;&#x…...

hadoop中的序列化和反序列化(3)

3. Java的序列化 Java提供了内置的序列化机制&#xff0c;通过java.io.Serializable接口实现。 3.1 如何实现Java序列化 让类实现Serializable接口。 使用ObjectOutputStream进行序列化。 使用ObjectInputStream进行反序列化。 示例代码 序列化 java 复制 import jav…...

PostgreSQL给新用户授权select角色

✅ 切换到你的数据库并以超级用户登录&#xff08;例如 postgres&#xff09;&#xff1a; admin#localhost: ~$ psql -U postgres -d lily✅ 创建登录的账号机密吗 lily> CREATE USER readonly_user WITH PASSWORD xxxxxxxxxxx; ✅ 确认你授予了这个表的读取权限&#xf…...

MySQL 8.0 OCP(1Z0-908)英文题库(1-10)

目录 第1题题目解析正确答案 第2题题目解析正确答案 第3题题目解析正确答案 第4题题目解析正确答案 第5题题目解析正确答案 第6题题目解析正确答案 第7题题目解析正确答案 第8题题目解析正确答案 第9题题目解析正确答案 第10题题目解析正确答案&#xff1a; 第1题 Your MySQL …...

南京市出台工作方案深化“智改数转网联”,物联网集成商从“困局”到“蓝海”!

为落实《江苏省深化制造业智能化改造数字化转型网络化联接三年行动计划&#xff08;2025-2027年&#xff09;》&#xff0c;南京市近日出台“工作方案”&#xff0c;部署五大行动17项重点任务&#xff0c;进一步深化全市制造业智能化改造、数字化转型、网络化联接&#xff08;以…...

系统思考:教育焦虑恶性循环分析

今天和团队的小伙伴一起拆解了一个父母教育焦虑与报班行为之间的系统环路图&#xff0c;报班越多 ➡ 孩子自由时间越少 ➡ 情绪调节力下降 ➡ 学习效率更低 ➡ 成绩不理想 ➡ 家长更焦虑 ➡ 继续加码报班…… 一圈一圈&#xff0c;像是陷入了“焦虑的恶性循环”。 这也是我一直…...

(已完结)完美解决C盘拓展卷是灰色的无法扩容的问题以及如何正确地在WINDOS上从一个盘扩容到C盘

众所周知&#xff0c;window系统在“计算机”管理中自带了一个磁盘管理系统 但是在使用过程中会出现各种各样无法扩容的毛病。 第一&#xff1a;首先排查&#xff0c;大多数人在扩容之前忽视了一点就是&#xff0c;我们现代的很多新机器都是默认开启BitLocker加密的&#xff…...

优选算法系列(8.多源BFS)

简介&#xff1a; 01 矩阵&#xff08;medium&#xff09;&#xff1a; 题目链接&#xff1a;542. 01 矩阵 - 力扣&#xff08;LeetCode&#xff09; 算法&#xff1a; 对于求的最终结果&#xff0c;我们有两种方式&#xff1a; 第⼀种方式&#xff1a;从每⼀个 1 开始&#…...

迈向AI辅助数据分析代码生成的透明性与知识共享

李升伟 摘译 生成式人工智能&#xff08;AI&#xff09;及尤其大型语言模型&#xff08;LLMs&#xff09;正在改变我们进行数据科学研究的方式. 最显著的例子包括科学家使用该技术与科学数据交互, 回答数据分析问题, 生成数据分析代码以及(重新)撰写科研手稿. 然而遗憾的是&am…...

autojs和冰狐智能辅助该怎么选择?

最近打算做自动化脚本&#xff0c;在autojs和冰狐智能辅助中做选择&#xff0c;不知道该怎么选。没办法只能花费大量时间仔细研究了autojs和冰狐智能辅助&#xff0c;综合考虑功能需求、开发复杂度、编程经验及项目规模等因素。以下是两者的核心对比及选择建议&#xff0c;仅供…...

小数的二进制表示

相信很多人都知道整数的二进制表示方法&#xff0c;但是小数的二进制就不一定了。 想来简单说一下整数的&#xff0c;就是不断的除以2取余数&#xff0c; 大致这样 从下往上取&#xff0c;这里42的结果就是101010 而且每个整数都有他对应的二进制数&#xff0c;但是小数转二…...

信息系统项目管理师-软考高级(软考高项)​​​​​​​​​​​2025最新(十)

个人笔记整理---仅供参考 第十章项目进度管理 10.1管理基础 10.2项目进度管理过程 10.3规划进度管理 10.4定义活动 选C 10.5排列活动顺序 10.6估算活动持续时间 10.7制订进度计划 制订进度计划4个步骤&#xff08;背&#xff0c;案例可能会考&#xff01;&#xff09; 10.8控制…...

Linux内核初始化机制全解析:从pure_initcall到late_initcall

引言 Linux内核的启动过程是一个高度有序的初始化流程,涉及数百个模块和子系统的协同工作。为了确保依赖关系正确、硬件资源按需分配,内核通过一系列初始化宏(如pure_initcall、subsys_initcall、late_initcall等)将函数划分为不同的优先级,按严格顺序执行。本文将深入探…...

pcie协议复位

pcie协议复位共有4中情况&#xff1b;cold reset&#xff1b;warm reset&#xff1b;hot reset&#xff1b;function level reset&#xff1b; 分类&#xff1a; 依据spec 6.6&#xff1a; Conventional reset&#xff08;传统复位&#xff09;&#xff1a;cold&#xff0c;…...

boost笔记: Cannot open include file: ‘boost/mpl/aux_/preprocessed/plain/.hpp‘

1. 问题描述 因为一下库定义了宏and&#xff0c;导致boost的文件包含and.hpp展开成&.hpp&#xff0c;所以出现以下错误 Cannot open include file: ‘boost/mpl/aux_/preprocessed/plain/&.hpp’ 2. 解决方案 在定义宏之前包含boost文件&#xff0c;但这种方案的缺点…...

Xilinx XCKU11P-2FFVA1156I 赛灵思 FPGA AMD Kintex UltraScale+

XCKU11P-2FFVA1156I 属于 AMD Kintex UltraScale™ FPGA 家族&#xff0c;采用 TSMC 20 nm FinFET 工艺&#xff0c;兼顾高性能与功耗效率&#xff0c;提供约 653 100 个逻辑单元、2 928 个 DSP 切片、21.1 Mb Block RAM 和 22.5 Mb UltraRAM&#xff0c;可广泛应用于网络加速、…...

hadoop中的序列化和反序列化(4)

4. Hadoop的序列化 Hadoop提供了自己的序列化机制&#xff0c;用于高效地处理分布式计算中的数据传输。Hadoop的序列化机制比Java的序列化更高效&#xff0c;更适合大规模数据处理。 4.1 Hadoop序列化的特点 高效&#xff1a;Hadoop的序列化格式紧凑&#xff0c;适合大规模数…...

实现引用计数线程安全的shared_ptr

c11引入了三个智能指针&#xff0c;用来自动管理内存&#xff0c;使用智能指针可以有效地减少内存泄漏。 其中&#xff0c;shared_ptr是共享智能指针&#xff0c;可以被多次拷贝&#xff0c;拷贝时其内部的引用计数1&#xff0c;被销毁时引用计数-1&#xff0c;如果引用计数为…...

今日行情明日机会——20250507

指数今天放量上涨&#xff0c;政策层面也释放出重大利好消息~ 上证缺口已补&#xff0c;大盘股表现总体较好 深证60分钟缺口依然未补&#xff0c;等待后续走势~ 2025年5月7日涨停股主要行业方向分析 一、核心主线方向 军工&#xff08;政策催化地缘驱动&#xff09; • 涨停…...

配置Hadoop集群-测试使用

&#xff08;一&#xff09;上传小文件 上传文件的时候&#xff0c;我们传一个大一点的&#xff08;>128M&#xff09;&#xff0c;再传一个小一点的。对于大一点的文件&#xff0c;我们要去看看它是否会按128M为单位去拆分这个大文件&#xff0c;而拆分成大文件之后&#…...

MEGA3:分子进化遗传学分析和序列比对集成软件

李升伟 摘译 摘要 在分子进化和群体遗传学的理论基础稳固确立后&#xff0c;比较DNA和蛋白质序列分析在重建物种和多基因家族的进化历史、估计分子进化速率以及推断塑造基因和基因组进化的性质和程度方面发挥了核心作用。随着高通量测序技术和新颖的统计及计算方法的发展&…...

21. LangChain金融领域:合同审查与风险预警自动化

引言&#xff1a;当AI成为24小时不眠的法律顾问 2025年某商业银行的智能合同系统&#xff0c;将百万级合同审查时间从平均3周缩短至9分钟&#xff0c;风险条款识别准确率达98.7%。本文将基于LangChain的金融法律框架&#xff0c;详解如何构建合规、精准、可追溯的智能风控体系…...