生命周期和作用域,如果错误使用,会导致严重的并发问题
1. SqlSessionFactoryBuilder: 一旦创建了 SqlSessionFactory,就不再需要它了
SqlSessionFactoryBuilder 的最佳作用域是局部变量
2. SqlSessionFactory: 可以理解成数据库连接池
一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例
SqlSessionFactory 的最佳作用域是应用作用域
最简单的就是使用单例模式(保证全局只有一份变量)或者静态单例模式
3. SqlSession: 可以理解成连接到连接池的一个请求
每个线程都应该有它自己的 SqlSession 实例
SqlSession 的实例不是线程安全的,不能被共享
它的最佳作用域是请求或方法作用域
用完关闭,否则资源被占用
每个 SqlSession 能连接多个 Mapper
并发情况下,SqlSession 用完关闭,是因为 SqlSessionFactory 池子需要释放,不然会形成宕机
两台都是J1900 四核芯片,当前1号机内存8G,2号机内存4G
后将2号机内存升为8G,使用的协德牌子的内存。
硬件配置如下
1号机 配置 使用hw-probe探测硬件
hw-probe -all -upload Probe for hardware ... Ok Reading logs ... Ok Uploaded to DB, Thank you! Probe URL: https://bsd-hardware.info/?probe=bcba33e64d 1号具体配置
Host System FreeBSD 14.1Archamd64Kernel14.1-RELEASEVendorAMI »ModelAptio CRB »Year2019HWid83A65 »Typemini pc Devices (23) BUSID / ClassVendorDeviceTypeDriverStatusPCI8086:0f31:8086:0f31 »
/ 03-00-00IntelAtom Processor Z36xxx/Z37xxx Series Graphics & Displaygraphics cardvgapcidetectedPCI8086:0f04:8086:0f04 »
/ 04-03-00IntelAtom Processor Z36xxx/Z37xxx Series High Definition Audio ControllersoundhdacdetectedPCI8086:1539 »
/ 02-00-00IntelI211 Gigabit Network ConnectionnetworkigbworksPCI1b4b:9215:1b4b:9215 »
RabbitMQ基础
RabbitMQ支持的消息模型
SpringBoot集成RabbitMQ
一、发送者的可靠性 消息从发送者发送消息,到消费者处理消息,需要经过的流程是这样的:
消息从生产者到消费者的每一步都有可能导致消息丢失:
发送消息时丢失:
生产者发送消息时连接 MQ失败生产者发送消息到达 MQ 后未找到 Exchange生产者发送消息到达 MQ 的 Exchange 后,未找到合适的 Queue消息到达 MQ 后,处理消息的进程发生异常。 MQ导致丢失:
消息到达 MQ,保存到队列后,尚未消费就突然宕机。 消费者处理消费时丢失:
消息接收后尚未处理突然宕机消息接收后处理过程中抛出异常 综上 我们要解决消息丢失问题,保证 MQ 的可靠性,就必须从3个方面入手:
确保生产者一定把消息发送到 MQ确保 MQ 不会将消息弄丢确保消费者一定要处理消息 1.1、生产者重试机制 第一种情况:生产者发送消息时,出现了网络故障,导致与MQ的连接中断。为了解决这个问题,SpringAMQP 提供消息发送时重试机制。修改 publisher 模块的配置文件,添加内容如下:
spring: rabbitmq: host: 192.168.137.120 port: 5672 virtual-host: / username: admin password: 123456 connection-timeout: 1s # 设置MQ的连接超时时间 template: retry: enabled: true # 开启超时重试机制 initial-interval: 1000s # 失败后的初始等待时间 multiplier: 1 # 失败后下次等待时长倍数 max-attempts: 3 # 最大重试次数 停止rabbitMQ 服务
专栏:数学建模学习笔记
一、图与网络的基本概念 1. 无向图与有向图 无向图:由顶点集合和边集合组成,边是无方向的。表示为 G=(V,E),其中 V 是顶点集合, E 是边集合。有向图:边是有方向的,从一个顶点指向另一个顶点。表示为 G=(V,E),其中每条边用有序对表示。 2. 简单图、完全图、赋权图 简单图:无重复边和自环的图。完全图:每对顶点之间都有边的图, Kn 表示n个顶点的完全图。赋权图:边带有权值的图,用于表示边的某种属性,如距离、费用等。 3. 顶点的度 度:与顶点相连的边的数目。在无向图中,顶点的度即为相连边的数目。在有向图中,入度为指向该顶点的边数,出度为从该顶点出发的边数。 4. 子图与连通性 子图:由原图的一部分顶点和边组成的图。连通性:图中任意两顶点之间存在路径。无向图称为连通图,有向图称为强连通图。 5. 图的矩阵表示 邻接矩阵:表示顶点之间是否有边的矩阵。若顶点 i 和顶点 j 之间有边,则矩阵A[i][j] 为1,否则为0。关联矩阵:表示顶点和边关系的矩阵。若边ek 连接顶点 vi 和 vj,则矩阵 A[i][k] 和]A[j][k] 分别为1。 MATLAB代码实例 % MATLAB代码 % 创建无向图和有向图的邻接矩阵表示 % 无向图的邻接矩阵 A_undirected = [0 1 1 0; 1 0 1 1; 1 1 0 1; 0 1 1 0]; % 有向图的邻接矩阵 A_directed = [0 1 0 0; 0 0 1 0; 0 0 0 1; 1 0 0 0]; % 显示邻接矩阵 disp('无向图的邻接矩阵:'); disp(A_undirected); disp('有向图的邻接矩阵:'); disp(A_directed); % 创建图对象并可视化 G_undirected = graph(A_undirected); G_directed = digraph(A_directed); % 绘制图 figure; subplot(1,2,1); plot(G_undirected); title('无向图'); subplot(1,2,2); plot(G_directed); title('有向图'); 无向图的邻接矩阵: 0 1 1 0 1 0 1 1 1 1 0 1 0 1 1 0 有向图的邻接矩阵: 0 1 0 0 0 0 1 0 0 0 0 1 1 0 0 0 邻接矩阵表示 无向图的邻接矩阵:A_undirected 是一个4x4矩阵,其中 A_undirected(i, j) 表示顶点 i 和顶点 j 之间是否有边。对于无向图,矩阵是对称的。 有向图的邻接矩阵:A_directed 是一个4x4矩阵,其中 A_directed(i, j) 表示顶点 i 到顶点 j 之间是否有边。对于有向图,矩阵不是对称的。 显示邻接矩阵 使用 disp 函数显示无向图和有向图的邻接矩阵,以便于检查矩阵的正确性。 创建图对象并可视化 graph(A_undirected) 创建无向图对象。 digraph(A_directed) 创建有向图对象。 使用 plot 函数可视化图对象。subplot 函数将图分成两部分,分别显示无向图和有向图。 Python代码实例 import networkx as nx import matplotlib.
TensorFlow 优化器以及会话使用指南 在我的系列专栏:深度学习求解PDE 的多数文章中将用到TensoFlow 优化器及其计算图学习框架,那么本篇文章就 将解释 如何在 TensorFlow 中使用 Adam 和 L-BFGS-B 优化器进行优化,并介绍了 TensorFlow 会话的框架。
优化器简介 Adam 优化器 Adam 优化器是深度学习中常用的一种优化算法,结合了动量法和 RMSProp 的优点。
案例:使用tf.train.AdamOptimizer 优化线性模型
假设我们有一个简单的线性模型 y=wx+b,其中 w 是权重,b 是偏置,我们希望通过训练来找到最优的 w 和 b,使得模型能够较好地拟合一组给定的数据点。读者可以从这个简单的案例学会此优化器使用方法.
#test1 # 步骤 1: 导入必要的库 import tensorflow as tf import numpy as np # 步骤 2: 创建数据 #为了简单起见,我们手动创建一些线性数据并添加一些噪声。 # 生成数据 np.random.seed(0) x_data = np.linspace(-1, 1, 100)[:, np.newaxis] # 100个数据点,形状为[100, 1] noise = np.random.randn(*x_data.shape) * 0.1 # 添加噪声 y_data = 2 * x_data + 1 + noise # 真实模型为 y = 2x + 1 #步骤 3: 定义模型 # TensorFlow 1.
气球条幅 balloon 时间限制:2ms/空间限制:512MB
题意 yjq的谷子店开业了,开业当天,他的朋友lyl给他送来了很多古早(老土)的气球条幅
气球条幅就是一个气球下方坠着条幅,气球越大,气球飞得越高,一个大小为 a i ai ai的气球可以悬浮在离地 a i ai ai米的天空中。条幅没有重量,即气球上坠着的条幅不影响气球的高度
每个条幅上都写着很多内容,字数不同的条幅长度自然不同,一个由 x i xi xi个字组成的条幅长度为 x i xi xi
显然,只有当气球大小 a i ai ai大于等于条幅长度 x i xi xi时,条幅才能悬浮而不是尾端拖在地上
为此,yjq和lyl需要调整气球和条幅的配对,使得更多的条幅不要拖在地上
求最多能有多少个气球条幅悬空
输入 第1行有一个正整数 n n n,表示气球条幅的数目。
接下来 n n n行,每行有两个整数 a i , x i ai,xi ai,xi为第 i i i个气球条幅的气球大小和条幅的字数
输出 输出一个正整数,为能够悬空的最多的气球条幅的个数
样例 样例输入 5 7 3 4 5 3 6 8 5 4 4 样例输出 4 数据范围 对于 100 % 100\% 100%的数据, 1 ≤ n ≤ 1 0 6 1\le n \le 10^6 1≤n≤106, 1 ≤ a i , x i ≤ 1 0 6 1 \le ai,xi \le 10^6 1≤ai,xi≤106
文章目录 什么是 Stopwatch?使用场景优点缺点注意事项使用步骤使用案例及结果可能面试题1. **理解与解释**2. **技术细节**3. **实际应用**4. **优缺点与替代方案**5. **面向框架的具体问题**6. **高级主题** 什么是 Stopwatch? Stopwatch 是由 Apache Commons Lang 库提供的一种工具类,它允许你测量经过的时间。它可以用来追踪代码中某部分、方法或应用内任何流程的执行时间。它特别适用于性能分析和优化。
使用场景 性能剖析:识别应用中的瓶颈。日志记录:记录关键操作的执行时间。测试:确保在单元测试中某些操作能在可接受的时间范围内完成。基准测试:比较不同算法或实现的性能。 优点 易于使用:API 设计直观,容易上手。准确性:使用纳秒精度进行时间测量,适合高精度需求。灵活:可以暂停、重启、重置,适应不同的使用场景。 缺点 依赖外部库:使用 Stopwatch 需要引入 Apache Commons Lang 库,这会增加项目依赖。资源消耗:频繁使用可能带来额外的 CPU 和内存开销。 注意事项 确保在不再需要时停止并清除 Stopwatch 实例,避免资源浪费。谨慎使用,避免在性能关键路径上过度使用,以免影响应用性能。 使用步骤 添加依赖:在你的 Spring Boot 项目中添加 Apache Commons Lang 库的依赖。 <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.12.0</version> </dependency> 创建 Stopwatch 实例:在需要测量时间的地方创建一个 Stopwatch 对象。 Stopwatch stopwatch = new Stopwatch(); 开始计时:调用 start() 方法开始计时。 stopwatch.start(); 执行操作:这里插入你想测量时间的操作或代码块。停止计时:执行完操作后调用 stop() 方法停止计时。 stopwatch.stop(); 获取结果:通过 elapsed(TimeUnit) 方法获取经过的时间,可以指定返回的时间单位(如毫秒、微秒等)。 long elapsedTimeMillis = stopwatch.
目录 实验实验内容实验要求 具体实现改造联结词联结词计算函数总计算方法改命题变元值命题变元个数判断函数打印函数主函数中调用 源码 实验 实验内容 编程实现用真值表法求取含三个以内变量的合式公式的主析取范式和主合取范式。
实验要求 要求:
从屏幕输入含三个以内变量的合式公式(其中 联结词按照从高到底的顺序出现)。
规范列出所输合式公式的真值表。
给出相应主析取和主合取范式。
[外链图片转存中…(img-KttFRYgu-1719842214597)]
具体实现 具体实现可以参考以下思路:
改造联结词 在输入联结词时就会要求用!表示否定,&表示合取,|表示析取,>表示条件,-表示双条件。
我们就设计一个函数将这些联结词改造对应的数字,以便后面switch case操作(可以省略直接在case中判断符号就行)。
//! //联结词改造函数 char* conjuction(char a[], size_t len)//len表示字符串长度 { for (int i = 0; i < len; i++) { if (a[i] == '!') a[i] = '6'; else if (a[i] == '&') a[i] = '2'; else if (a[i] == '|') a[i] = '3'; else if (a[i] == '>') a[i] = '4'; else if (a[i] == '-') a[i] = '5'; } return a; } 联结词计算函数 对每个联结词对应的计算方法写成函数。
文章目录 C++ 中的容器分类1. 顺序容器2. 关联容器3. 无序容器4. 容器适配器5. 字符串容器6. 特殊容器 set1.构造函数2.迭代器3.容量相关的成员函数4.修改器类的成员函数5.容器相关操作的成员函数 multiset1.equal_range map1.初始化相关的函数2.迭代器3.容量相关的成员函数4.访问相关的成员函数5.修改器类的成员函数6.容器相关操作的成员函数 总结 C++ 中的容器分类 在C++中,标准库提供了多种容器,这些容器可以根据其数据存储方式和功能进行分类。以下是C++中常见容器的分类:
1. 顺序容器 这些容器按顺序存储元素,适用于需要保持元素顺序的场景。
vector: 动态数组,支持快速随机访问和在末尾高效插入和删除操作。deque: 双端队列,支持快速随机访问和在两端高效插入和删除操作。list: 双向链表,支持在任何位置高效插入和删除操作,但随机访问较慢。forward_list: 单向链表,只支持在头部高效插入和删除操作。array: 固定大小的数组,大小在编译时确定。 2. 关联容器 这些容器根据键值对存储元素,并自动按键排序,适用于需要快速查找的场景。
set: 集合,存储唯一的元素,元素自动按键排序。multiset: 允许重复元素的集合,元素自动按键排序。map: 键值对存储的映射,键唯一且自动排序。multimap: 允许重复键的映射,键自动排序。 3. 无序容器 这些容器使用哈希表存储元素,适用于需要快速查找和插入的场景,但不保证元素顺序。
unordered_set: 无序集合,存储唯一的元素。unordered_multiset: 无序多重集合,允许重复元素。unordered_map: 无序映射,键唯一。unordered_multimap: 无序多重映射,允许重复键。 4. 容器适配器 这些不是独立的容器,而是对现有容器的包装,提供特定用途的接口。
stack: 栈,后进先出(LIFO)结构,通常使用deque或vector实现。queue: 队列,先进先出(FIFO)结构,通常使用deque或list实现。priority_queue: 优先队列,元素按优先级排序,通常使用vector和heap算法实现。 5. 字符串容器 string: 用于存储和操作字符序列,类似于动态数组,但专门针对字符。 6. 特殊容器 bitset: 固定大小的二进制数组,提供按位操作。 这些容器各有优缺点和适用场景,选择合适的容器可以显著提高程序的性能和可维护性。
这篇文章讲的两个容器都是关联式容器
set 在C++标准库中,set容器的底层实现通常是基于红黑树这种自平衡二叉搜索树。红黑树是一种能够在插入、删除和查找操作中保持对数时间复杂度的树结构。
1.构造函数 构造函数主要分为三个:无参构造,迭代器区间构造,拷贝构造
无参构造:
set<int> s; 迭代器区间构造:
vector<int> v{ 1,2,3,4,5,6,7 }; set<int> s(v.
目录 翻译环境和运行环境翻译环境编译器预处理(预编译)编译链接 执行环境 Win32API是什么控制台程序控制台获取坐标COORDGetStdHandle函数GetConsoleCursorinfo函数CONSOLE_CURSOR_INFOSetConsoleCursorInfo函数SetConsoleCursorPostion函数GetAsyncKeyState函数 翻译环境和运行环境 翻译环境 翻译环境就是在这将源代码转换成可执行的二进制指令(机器指令)。
进行编译和链接过程。
.c源程序先单独经过编译器生成对应的目标文件.obj(在windows环境下).o(在Linux环境下)。
多个目标文件和链接库一起经过链接器生成可执行程序。
编译器 编译器分为3个过程 预处理(预编译),编译,汇编。
预处理(预编译) 主要处理源文件中#开始的预编译指令。
规则如下:
将宏定义替换进去并删除#define。处理条件编译。删除注释 。将头文件包含内容插入预编译位置。该头文件中可以包含其他头文件(可以递归进行)。添加行号和文件名表示,以便后续生成调试信息。保留#pragma的编译指令。 编译 词法分析:将代码中的字符分割为一系列记号(关键字,标识符,字面量,特殊字符等)。语法分析:将词法分析产生的记号进行语法分析,产生语法树。语义分析:对表达式的语法层面分析。 链接 过程主要包括:地址和空间分配,符号决议和重定位等步骤。
目的:将一堆文件链接在一起生成可执行文件。
执行环境 执行环境就是用于实际执行代码。
Win32API是什么 Win32API百度介绍就是这样:
意思就是有一系列函数服务于应用程序,这些函数简称API(Application Programming Interface)函数。
控制台程序 平常我们使用的黑框程序就是控制台程序,那我们可以调整它的大小吗?当然。
我们就用cmd命令来控制窗口的长宽和名字,以修改为20行,100列和贪吃蛇名字为例。
system("mode con cols=100 lines=20;") system("title 贪吃蛇"); 控制台获取坐标COORD 在控制台程序中,左顶角就是坐标(0,0),往右是x横轴,往下是y轴。
而COORD是Windows API中定义的一个结构体用来表示坐标。
类型声明如下:
typedef struct _COORD{ SHORT X; SHORT Y; }COORD,*PCOORD; GetStdHandle函数 在这个函数是用于从一个特定的标准设备(标准输入、标准输出或标准错误)中获得一个句柄(用来标识不同设备的数值),使用这个句柄可以操作设备。
HANDLE hOutPut = NULL;//初始一个句柄 hOutPut = GetStdHandle(STD_OUTPUT_HANDLE); GetConsoleCursorinfo函数 用于指定控制台屏幕缓冲区的光标大小和可见性信息。
使用例子:
HANDLE hOutPut = NULL;//初始一个句柄 //获得标准输出的句柄 hOutPut = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_CURSOR_INFO CursorInfo; GetConsoleCursorinfo(hOutPut,&CursorInfo);//获取光标信息 CONSOLE_CURSOR_INFO 这是一个结构体,包含有关控制台光标的信息。
目录 栈栈的模拟实现栈的顺序实现接口实现成员变量默认构造方法入栈判满获取栈元素个数出栈获取栈顶元素 但是不删除判空 栈的链式实现接口实现内部类入栈出栈判空获取栈顶元素 但是不删除获取栈元素个数 Java中的Stack实现的接口常用方法 栈练习 栈 栈是限定仅在表尾进行插入和删除操作的线性表,一种**先进后出**的数据结构。
栈顶: 允许插入和删除的一端。
栈底:不允许插入和删除的一端。
压栈:栈的插入操作。
出栈:栈的删除操作。
栈的模拟实现 栈的底层可以是顺序表,可以是链表实现。
栈的顺序实现 栈的顺序实现就是使用顺序表为底层实现。
接口实现 实现的接口(成员方法)如下:
顺序表可以多实现一个判满接口。
public class MyStack { //默认构造方法 public MyStack() {} //入栈 public void push(int val) {} //判满 public boolean isFull() { } //出栈 public int pop() {} //获取栈顶元素 但是不删除 public int peek() { } //获取栈元素个数 public int size(){} //判空 public boolean isEmpty() { } } 成员变量 我们使用一个数组,和一个int类型usedSize来表示栈中元素个数。
public int[] elem; public int usedSize; 默认构造方法 在构造方法中我们将数组申请10个int空间。
个人主页:学习前端的小z
个人专栏:JavaScript 精粹
本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结,欢迎大家在评论区交流讨论!
文章目录 💯Symbol🚧 1. 综述🚧2 Symbol.prototype.description🚧 2.1 深入Symbol.prototype.description 🚧3 Symbol 作为独一无二的属性键 🚧 4 实例:替换硬编码字符串🚧 5 Symbol属性名的隐藏特性🚧 6 Symbol的全局注册与检索🚧 7 内置的 Symbol 值🔱 7.1 Symbol.hasInstance🔱7.2 Symbol.isConcatSpreadable🔱7.3 Symbol.species🔱7.4 Symbol.match🔱7.5 Symbol.replace🔱7.6 Symbol.search🔱7.7 Symbol.split🔱7.8 Symbol.iterator🔱7.9 Symbol.toPrimitive🔱7.10 Symbol.toStringTag🔱7.11 Symbol.unscopables 💯Symbol 🚧 1. 综述 在ES5中,对象的属性名均为字符串,这容易导致属性名的冲突。例如,当你使用一个他人提供的对象并希望为其添加新方法时(采用mixin模式),新方法的名字可能与现有方法产生冲突。为避免此类冲突,ES6引入了Symbol。
ES6新增了一种原始数据类型Symbol,它代表独一无二的值,成为JavaScript的第七种数据类型,前六种为:undefined、null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。
Symbol值通过Symbol函数生成,意味着对象的属性名现在有两种类型:原有的字符串类型和新增的Symbol类型。凡是属性名为Symbol类型,都是独一无二的,可确保不会与其他属性名冲突。
let s = Symbol(); typeof s; // "symbol" 上述代码中,变量s是一个独一无二的值。typeof运算符的结果表明s是Symbol数据类型,而非字符串等其他类型。
需注意的是,Symbol函数前不能使用new命令,否则将报错。因为生成的Symbol是一个原始类型的值,而非对象。因此,Symbol值无法添加属性,它类似于字符串数据类型。
Symbol函数可接受一个字符串作为参数,用于描述Symbol实例,便于在控制台显示或转为字符串时区分。
let s1 = Symbol('apple'); let s2 = Symbol('banana'); s1; // Symbol(apple) s2; // Symbol(banana) s1.
前言 通过对C++的特性,类和对象的学习和C++的内存管理对C++基本上有了全面的认识,但是C++的核心在于STL
一、STL简介 什么是STL C++ STL(Standard Template Library,标准模板库)是C++编程语言中一个功能强大的模板库,它提供了一系列通用的数据结构和算法。STL的设计基于泛型编程,这意味着它使用模板来编写独立于任何特定数据类型的代码。STL的核心组件包括容器(如向量、链表、集合等)、迭代器、算法、函数对象和适配器等。这些组件使得程序员能够以简洁、高效的方式处理数据结构和算法问题,减少了编码工作量,提高了代码的可重用性和性能 STL版本 HP STL:由Alexander Stepanov和Meng Lee在惠普实验室完成的原始版本,是所有STL实现版本的始祖。PJ STL:由P. J. Plauger开发,继承自HP版本,被Windows Visual C++采用。SGI STL:由Silicon Graphics Computer Systems, Inc公司开发,继承自HP版本,被GCC(Linux)采用,可移植性好,可公开、修改甚至贩卖。STLport:由Boris Fomitchev开发,继承自SGI STL,旨在提供一个可移植到不同平台的STL版本 STL为什么可以成为C++标准库的一部分 泛型编程支持:STL利用C++的模板机制实现了泛型编程,使得容器和算法能够处理不同类型的数据,提高了代码的重用性和灵活性。 !高效的数据结构:STL提供了多种容器类,如向量(vector)、链表(list)、双端队列(deque)、集合(set)、映射(map)等,这些容器具有高效的数据存储和访问方式,并且可以方便地进行插入、删除和查找等操作。统一的迭代器接口:STL的容器和算法都使用迭代器来访问和操作元素,迭代器提供了统一的接口,使得算法可以独立于具体的数据类型进行操作丰富的算法库:STL提供了一系列算法库,包括排序、查找、合并、堆操作、数值算法等,这些算法都被实现为函数模板,可以方便地应用于不同的容器和数据类型。函数对象的使用:STL的算法库中使用了函数对象(Functor)来封装操作,通过函数对象,STL可以将自定义的操作应用于算法中,提高了代码的可定制性和扩展性。自动内存管理:STL的容器类和算法库都采用了自动的内存管理机制,有效避免了内存泄漏和访问越界等问题。 STL六大组件 STL 仿函数 空间适配器 算法 容器 迭代器 配接器 二、模板 模板特性 函数模板特化:当需要为特定类型提供不同于模板定义的函数行为时,可以使用函数模板特化。例如,对于内置类型int,可能需要一个优化过的打印函数,而对于其他类型则使用通用模板定义。类模板特化:类模板特化允许为特定类型或类型组合提供定制化的类成员函数或数据成员。这在需要为特定类型提供特定的类行为时非常有用。模板偏特化:模板偏特化是模板特化的一种形式,它允许部分参数的定制化,而保留其他参数的泛化行为。这在处理具有共同基类或接口的不同派生类型时特别有用。全特化:全特化是指为模板提供一个具体类型的实现,这样编译器在遇到该具体类型时会直接使用特化版本,而不是泛化版本。这有助于提高代码的效率和减少编译时间。参数修饰特化:参数修饰特化是通过改变模板参数的类型或数量来实现特化的技术。这可以用来解决模板参数匹配的歧义或提供额外的功能。非类型模板参数特化:非类型模板参数特化允许为特定的非类型参数值提供定制化的模板实现,这在需要根据不同的常量大小或值来调整模板行为时非常有用 泛型编程 在学习C语言的时候如果实现两个数交换 比如:整形,浮点型,字符,会写三个函数。
void Swap(int& left, int& right) { int temp = left; left = right; right = temp; } void Swap(double& left, double& right) { double temp = left; left = right; right = temp; } void Swap(char& left, char& right) { char temp = left; left = right; right = temp; } 这样重复性的代码,是很多人讨厌的地方,正因为这个出现了泛型编程。以上的代码一个用一个函数模板替代,交给编译器实现。
本文介绍三种方法查看Kafka的偏移量offset。
1. API:ConsumerRecord的offset()方法查看offset。
2. API:KafkaConsumer的position(TopicPartition partition)方法查看offset。
3. 命令行:kafka-consumer-groups.sh命令查看offset。
前提条件 Kafka安装及基本操作,可参考:Kafka安装及基本操作
Kafka API操作,可参考:Kafka API操作
三种方法查看Kafka的偏移量offset 1. API:ConsumerRecord的offset()方法查看offset。 生产者
import org.apache.kafka.clients.producer.KafkaProducer; import org.apache.kafka.clients.producer.ProducerRecord; import org.apache.kafka.clients.producer.RecordMetadata; import java.util.Properties; import java.util.concurrent.Future; public class MyProducer { public static void main(String[] args) { // 1.创建kafka生产者对象 Properties prop = new Properties(); prop.put("bootstrap.servers","node1:9092"); prop.put("acks","all"); prop.put("retries","0"); // 16k一个批量 prop.put("batch.size", 16384); prop.put("linger.ms",5); prop.put("buffer.memory", 33554432); prop.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); prop.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); KafkaProducer<Object, Object> producer = new KafkaProducer<>(prop); // 2.使用send方法生产数据 for (int i = 0; i < 10; i++) { // producer.
生成式 AI 的发展方向,是 Chat 还是 Agent? 随着生成式 AI 技术的不断进步,关于其未来发展方向的讨论也愈发激烈。究竟生成式 AI 的未来是在对话系统(Chat)中展现智慧,还是在自主代理(Agent)中体现能力?这一问题引发了广泛的讨论和探索。本文将从整体介绍、技术对比以及未来展望三个方面,探讨生成式 AI 的发展方向。
方向一:整体介绍 1.当前发展现状 生成式 AI,也称为生成对抗网络(GANs)、变分自编码器(VAEs)等,是一种通过学习大量数据来生成新内容的技术。近年来,生成式 AI 在对话系统(Chat)和自主代理(Agent)两个领域都取得了显著的进展。
对话系统(Chat):对话系统是生成式 AI 技术应用最为广泛的领域之一。从早期的简单问答机器人到如今的智能客服、虚拟助手,对话系统在自然语言处理(NLP)技术的推动下,已经能够理解用户的意图并生成自然、流畅的对话。例如,Google Assistant、Amazon Alexa 和 Apple Siri 等智能助手,都是对话系统的优秀代表。
自主代理(Agent):自主代理则是指能够自主执行任务的 AI 系统。它们不仅可以理解用户的指令,还能在复杂环境中自主决策和执行任务。例如,自动驾驶汽车、无人机和机器人等,都是自主代理技术的典型应用。
2.主要技术 对话系统(Chat):对话系统主要依赖于自然语言处理(NLP)技术,包括语言模型、意图识别、对话管理等。其中,深度学习技术如循环神经网络(RNN)、长短时记忆网络(LSTM)和 Transformer 模型在对话系统中的应用尤为广泛。
自主代理(Agent):自主代理则更多依赖于机器学习和强化学习技术。通过与环境的交互,自主代理能够学习如何执行任务并优化其行为。例如,深度强化学习(Deep RL)和多智能体系统(MAS)是自主代理技术的关键技术。
3.应用场景 对话系统(Chat):对话系统的应用场景非常广泛,包括但不限于客户服务、在线教育、医疗咨询、娱乐互动等。通过与用户的自然语言交互,对话系统能够提供个性化的服务和信息。
自主代理(Agent):自主代理的应用场景则更为多样,涵盖了自动驾驶、智能制造、智能物流、机器人服务等多个领域。通过自主决策和执行任务,自主代理能够提高效率、降低成本,并在某些危险或复杂的任务中替代人类。
方向二:技术对比 1.技术差异 对话系统(Chat):对话系统的核心在于理解和生成自然语言。其技术关键在于语言模型的准确性和对话管理的流畅性。对话系统需要能够理解用户的意图,并生成符合语境的回应。
自主代理(Agent):自主代理的核心在于任务执行和环境适应。其技术关键在于决策算法的优化和学习机制的效率。自主代理需要能够在复杂环境中自主决策,并不断优化其行为。
2.优势和劣势 对话系统(Chat):
优势:能够提供个性化服务,提高用户体验;应用场景广泛,市场需求大。劣势:对语言模型的准确性要求高,容易受到语言多样性和复杂性的影响;在处理复杂任务时可能会遇到瓶颈。 自主代理(Agent):
优势:能够执行复杂任务,提高效率和安全性;在某些领域具有不可替代的优势,如自动驾驶和机器人服务。劣势:对环境的适应性和稳定性要求高,技术实现难度大;在伦理和安全性方面存在争议。 3.技术挑战 对话系统(Chat):对话系统面临的主要技术挑战包括语言模型的泛化能力、对话管理的复杂性以及多轮对话的连贯性。此外,对话系统的可解释性和隐私保护也是当前研究的热点问题。
自主代理(Agent):自主代理面临的主要技术挑战包括决策算法的优化、学习机制的稳定性以及与环境的交互。此外,自主代理的安全性和伦理问题也是需要重点关注的领域。
方向三:具体案例 生成式 AI 在对话系统和自主代理领域的应用案例非常广泛,以下是一些具体的案例:
智能助手:如 Amazon Alexa、Google Assistant 等,它们结合了对话系统和自主代理的特点,能够与用户进行自然语言交互,并自主执行任务,如控制智能家居设备、查询天气信息、播放音乐等。11
视频创作平台 Waymark:通过集成 GPT-3 技术,Waymark 使用微调的模型来创建不同脚本编写体验,使用户可以在几秒钟内收到其业务的原始自定义脚本,从而提升了视频创作的效率和可访问性。8
公关咨询公司 BukiHQ Medi:利用基于生成式 AI 技术的语音助手 fireflies.
目录 1.avcodec_receive_frame1.1 返回解码帧(ff_decode_receive_frame)1.2 返回重建帧(ff_encode_receive_frame) 2.小结 FFmpeg相关记录:
示例工程:
【FFmpeg】调用ffmpeg库实现264软编
【FFmpeg】调用ffmpeg库实现264软解
【FFmpeg】调用ffmpeg库进行RTMP推流和拉流
【FFmpeg】调用ffmpeg库进行SDL2解码后渲染
流程分析:
【FFmpeg】编码链路上主要函数的简单分析
【FFmpeg】解码链路上主要函数的简单分析
结构体分析:
【FFmpeg】AVCodec结构体
【FFmpeg】AVCodecContext结构体
【FFmpeg】AVStream结构体
【FFmpeg】AVFormatContext结构体
【FFmpeg】AVIOContext结构体
【FFmpeg】AVPacket结构体
函数分析:
【通用】
【FFmpeg】avcodec_find_encoder和avcodec_find_decoder
【FFmpeg】关键结构体的初始化和释放(AVFormatContext、AVIOContext等)
【FFmpeg】avcodec_open2函数
【FFmpeg】内存分配和释放(av_malloc、av_realloc等)
【推流】
【FFmpeg】avformat_open_input函数
【FFmpeg】avformat_find_stream_info函数
【FFmpeg】avformat_alloc_output_context2函数
【FFmpeg】avio_open2函数
【FFmpeg】avformat_write_header函数
【FFmpeg】av_write_frame函数
【编码】
【FFmpeg】avcodec_send_frame函数
【解码】
【FFmpeg】avcodec_send_packet函数
1.avcodec_receive_frame 函数的主要功能是从解码器或编码器返回解码后的输出数据(当使用AV_CODEC_FLAG_RECON_FRAME标志时)
/** * Return decoded output data from a decoder or encoder (when the * @ref AV_CODEC_FLAG_RECON_FRAME flag is used). * * @param avctx codec context * @param frame This will be set to a reference-counted video or audio * frame (depending on the decoder type) allocated by the * codec.
在计算机编程领域,图形用户界面(GUI)的开发是提升用户体验的关键环节。Perl,作为一种功能强大的脚本语言,同样提供了多种工具和库来支持GUI的开发。本文将详细介绍Perl中进行GUI开发的几种主要方法,包括使用流行的Perl GUI工具包,以及一些实用的开发技巧和最佳实践。
Perl GUI开发工具概览 Tk - Tk是一个跨平台的GUI工具包,由Tcl语言开发,但Perl社区也提供了Perl的接口,即Tk.pm。Tk提供了丰富的控件和布局管理器,非常适合快速开发简单的GUI应用程序。
Gtk2/Gtk3 - Gtk是GNOME桌面环境的GUI工具包,Perl通过Gtk2.pm或Gtk3.pm提供了对Gtk的接口。Gtk拥有现代化的控件和主题支持,适合开发复杂的桌面应用程序。
WxPerl - WxWidgets是一个跨平台的C++库,用于创建GUI应用程序。WxPerl是它的Perl绑定,提供了丰富的控件和事件处理机制。
Qt - Qt是一个广泛使用的跨平台C++框架,用于开发具有图形用户界面的应用程序。通过Qt::Perl,Perl开发者也可以利用Qt的强大功能。
FLTK - Fast Light Toolkit(FLTK)是一个轻量级的跨平台GUI工具包。Perl通过FLTK.pm提供了对FLTK的接口。
开始Perl GUI开发 在开始Perl GUI开发之前,你需要确保已经安装了Perl环境和相应的GUI工具包。以下是一个使用Tk创建简单窗口的示例代码:
use strict; use warnings; use Tk; my $mw = MainWindow->new; $mw->title('Perl GUI Example'); my $label = $mw->Label(-text => 'Hello, GUI World!')->pack; my $button = $mw->Button(-text => 'Click Me!', -command => sub { print "Button was clicked!\n"; })->pack; MainLoop(); 这段代码创建了一个包含标签和按钮的窗口,并在按钮点击时在控制台打印一条消息。
设计GUI布局 在设计GUI时,布局管理是至关重要的。不同的GUI工具包提供了不同的布局管理器。例如,Tk提供了pack, grid, 和 place等布局管理器。以下是一个使用grid布局管理器的示例:
AI创业者的全面指南:揭开人工智能的神秘面纱 🌟 揭秘AI的真相:95%的创业者可能并未真正理解她的真实含义。
关键词:AI创业、科技创新、未来趋势
在这个充满科技变革的时代,AI(人工智能)无疑是最热门的话题之一。🔍人工智能,这个在科幻电影中被频繁提及的概念,如今已经逐步走进了我们的生活,改变了我们看待世界的方式。然而,对于许多创业者来说,AI依然是一个模糊而神秘的存在。那么,AI到底是什么?她的真实含义又是什么呢?
猫头虎是谁? 大家好,我是 猫头虎,别名猫头虎博主,擅长的技术领域包括云原生、前端、后端、运维和AI。我的博客主要分享技术教程、bug解决思路、开发工具教程、前沿科技资讯、产品评测图文、产品使用体验图文、产品优点推广文稿、产品横测对比文稿,以及线下技术沙龙活动参会体验文稿。内容涵盖云服务产品评测、AI产品横测对比、开发板性能测试和技术报告评测等。
目前,我活跃在CSDN、51CTO、腾讯云开发者社区、阿里云开发者社区、知乎、微信公众号、视频号、抖音、B站和小红书等平台,全网拥有超过30万的粉丝,统一IP名称为 猫头虎 或者 猫头虎博主。希望通过我的分享,帮助大家更好地了解和使用各类技术产品。
原创作者 ✍️ 博主:猫头虎 全网搜索关键词:猫头虎作者微信号:Libin9iOak作者公众号:猫头虎技术团队更新日期:2024年6月16日🌟 欢迎来到猫头虎的博客 — 探索技术的无限可能! 专栏链接 🔗 精选专栏: 《面试题大全》 — 面试准备的宝典!《IDEA开发秘籍》 — 提升你的IDEA技能!《100天精通鸿蒙》 — 从Web/安卓到鸿蒙大师!《100天精通Golang(基础入门篇)》 — 踏入Go语言世界的第一步!《100天精通Go语言(精品VIP版)》 — 踏入Go语言世界的第二步! 领域矩阵 🌐 猫头虎技术领域矩阵: 猫头虎技术矩阵新矩阵备用链接 加入猫头虎的技术圈,一起探索编程世界的无限可能! 🚀 文章目录 AI创业者的全面指南:揭开人工智能的神秘面纱 🌟猫头虎是谁?原创作者 ✍️专栏链接 🔗领域矩阵 🌐加入猫头虎的技术圈,一起探索编程世界的无限可能! 🚀我的AI认知历程:从初识到深入 🚀技术驱动的创新数据的力量人机协作 AI时代的创业误区:避免成为野蛮人 🤯理解AI的本质长期的投入价值创造 用AI激发创意:让自己疯狂起来 🎨那些疯狂的AI画面案例 鸟瞰AI世界:预测和洞见未来 🔭未来预测应用场景问题是这些idea从哪里来? 总结 📝参考资料 📚温馨提示🔔联系与版权声明 📩 我的AI认知历程:从初识到深入 🚀 在我的创业历程中,AI逐渐从一个陌生的术语,变成了我日常思考的一部分。回顾这些年,我看到的AI新世界不仅仅是技术的进步,更是思维方式的变革。
技术驱动的创新 从简单的自动化到复杂的机器学习算法,AI技术的不断突破让我们能够实现许多以前无法想象的应用场景。
数据的力量 在AI世界里,数据就是新黄金。通过数据,我们可以洞察到用户行为、市场趋势,甚至预测未来的发展方向。
人机协作 AI并不是要取代人类,而是与我们合作,提升我们的工作效率和生活质量。
AI时代的创业误区:避免成为野蛮人 🤯 关键词:AI创业误区、正确的AI应用
一、定义 *Blob是web worker中的一个特征,属于来自浏览器的抽象,不可在node环境中使用
Blob是一个装着二进制数据的容器对象。Blob 对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取,也可以转换成 ReadableStream 来用于数据操作。
二、属性 size:只读属性,Blob中的字节数type:只读属性,表示Blob存放的媒体类型,图片、视频、文本文件等等 三、构造函数 例子:
const array = ['<q id="a"><span id="b">hey!</span></q>']; // 一个包含单个字符串的数组 const blob = new Blob(array, { type: "text/html" }); // 得到 blob 构造函数主要有两个参数:
参数一:存放文件原始数据的可迭代对象,一般放数组。数组中可以存放各种类型的文件数据格式,例如Buffer、Blob、String等等,如下:【一般都需要在资源内容外面套个中括号[]】 // Create a new Blob object var a = new Blob(); // Create a 1024-byte ArrayBuffer // buffer could also come from reading a File var buffer = new ArrayBuffer(1024); // Create ArrayBufferView objects based on buffer var shorts = new Uint16Array(buffer, 512, 128); var bytes = new Uint8Array(buffer, shorts.
【每日刷题Day85】
🥕个人主页:开敲🍉
🔥所属专栏:每日刷题🍍
🌼文章目录🌼
1. 125. 验证回文串 - 力扣(LeetCode)
2. 43. 字符串相乘 - 力扣(LeetCode)
3. 557. 反转字符串中的单词 III - 力扣(LeetCode)
1. 125. 验证回文串 - 力扣(LeetCode) //思路:双指针遍历。两头向中间遍历,判断是否有不同字母。
bool isPalindrome(char* s)
{
char* arr = (char*)malloc(sizeof(char)*strlen(s)+1);
int count = 0;
while(*s!='\0')
{
if(*s>='A'&&*s<='Z')
{
arr[count++] = *s+32;
}
if((*s>='a'&&*s<='z')||(*s>='0'&&*s<='9'))
{
arr[count++] = *s;
}
s++;
}
arr[count] = '\0';
int left = 0;
int right = count-1;
while(left<=right)
{
if(arr[left]!=arr[right])
{