在C++中,std::string
是一个用于操作字符串的类。以下是一些常用的std::string
成员函数和用法示例:
- 构造字符串:
cppstd::string str1 = "Hello, World!";
std::string str2; // 空字符串
- 字符串连接:
cppstd::string str1 = "Hello, ";
std::string str2 = "World!";
std::string str3 = str1 + str2; // str3 becomes "Hello, World!"
- 获取字符串长度:
cppstd::string str = "Hello, World!";
size_t length = str.length(); // length becomes 13
- 字符串比较:
cppstd::string str1 = "Hello";
std::string str2 = "World";
if (str1 < str2) {
// str1 is less than str2
}
- 查找子字符串:
cppstd::string str = "Hello, World!";
size_t found = str.find("World"); // found becomes 7
- 替换子字符串:
cppstd::string str = "Hello, World!";
str.replace(7, 5, "Zhang"); // str becomes "Hello, Zhang!"
- 字符串转换:
cppstd::string str = "123";
int num = std::stoi(str); // num becomes 123
- 字符串迭代器遍历:
cppstd::string str = "Hello";
for (auto it = str.begin(); it != str.end(); ++it) {
std::cout << *it;
}
// Outputs "Hello"
这些是std::string
的基本用法,具体使用时需要包含头文件#include <string>
。
一、软件的定义
1. 软件的定义
软件测试(英语:Software Testing),描述一种用来促进进鉴定软件的正确性、完整性、安全性和质量的过程。换句话来说,软件测试是一种与实际输出与预期输出之间的审核或者比较过程。
3. 软件的应用场景
游戏型测试、电商型测试、金融性测试、嵌入式测试等
4.软件架构分类
B/S架构软件
客户端为浏览器:百度
C/S架构软件
客户端需要安装专门的软件,如QQ、微信等
二、软件测试的定义与原则
1:为什么需要软件测试
2:软件测试的定义
- 通过人工或自动化额方式来验证软件的实际结果与用户需求是否一致的过程
3:软件测试的原则
- 原则一:尽早进入软件测试
- 原则二:穷尽测试是不可行的
- 原则三:程序员应避免检查自己的程序
- 原则四:充分注意测试中缺陷的集群现象
- 原则五:严格执行测试计划,排除测试的随意性
- 原则六:对每一个测试结果做全面的检查
- 原则七:妥善保存测试计划、测试用例、出错统计和最终分析报告,为维护提供方便
- 原则八:测试用例应由测试数据和与之对应的预期结果这两部分组成
三、测试模型的介绍
1. V模型
V模型左边下降的是开发过程各阶段,与此相对应的是右边上升的部分,即各测试过程的各个阶段。
V模型的优点在于它非常明确地标明了测试过程中存在的不同级别,并且清楚地描述了这些测试阶段的开发各阶段的对应关系。
V模型的缺陷及解决思路
V模型仅仅把测试过程作为在需求分析、系统设计及编码之后的一个阶段,忽视了测试对需求分析,系统设计的验证,需求的满足情况一直到后期的验收测试才被验证。
解决的思路是,当一个软件开发的时候,研发人员和测试人员需要同时工作,测试在软件做需求分析的同时就会有测试用例的跟踪,这样,可以尽快找出程序错误和需求偏离,从而更高效的提高程序质量,最大可能的减少成本,同时满足用户的实际软件需求。
优点:
1 每一个阶段都清晰明了,便于控制开发的每一个过程。
2 既包含单元测试又包含系统测试。
缺点:
1 测试介入的比较晚,对于前期的一些缺陷无从发现和修改。
2 测试和开发串行。
2. W模型
相对于V模型,W模型更科学。W模型是V模型的发展,强调的是测试伴随着整个软件开发周期,而且测试的对象不仅仅是程序,需求、功能和设计同样要测试。测试与开发是同步进行的,从而有利于尽早地发现问题。
优点
1 测试伴随着软件的整个生命周期,例如,在需求分析结束后就可以进行需求分析测试。
2 测试于开发是并行独立进行的。
缺点
1 对有些项目,开发过程中根本没有文档产生,故W模型无法使用。
2 对于需求和设计的测试技术要求很高,实践起来很困难。
四、软件测试的流程
阶段名 | 工作内容 | 产出物 |
---|---|---|
测试准备阶段 | 项目立项、需求分析、需求评审 | 需求文档、产品PRD |
测试计划阶段 | 编写测试计划、计划评审 | 测试计划 |
测试设计阶段 | 提取测试点、编写测试用例、用例评审 | 测试用例 |
测试执行阶段 | 冒烟测试、执行测试用例、提bug、回归测试 | 缺陷报告 |
测试完成阶段 | 验收测试、编写测试报告、项目上线 | 测试报告 |
五、软件测试的分类
1. 按技术分类
黑盒测试、白盒测试、灰盒测试
- 黑盒测试:不需要了解程序的源代码,通过使用整个软件功能来验证程序是否满足需求的测试方法
- 白盒测试:是一种按照程序内部逻辑结构和编码结构设计测试数据并完成测试的测试方法
- 灰盒测试:一种基于程序运行时的外部表现同时又结合程序内部结构来设计测试数据的测试方法
2:按阶段划分
单元测试、集成测试、系统测试、验收测试
- 单元测试:对一个模块、一个函数或者一个类来进行正确性检验的测试方法
- 集成测试:单元测试后,将单独的模块按照设计要求组装成为子系统或系统,作为整体进行测试的测试方法
- 系统测试:集成测试后,将硬件、软件看作一个整体,对系统的功能及性能的总体测试
- 验收测试: 系统测试后以用户测试为主,或有测试人员共同参与检验软件质量的测试方法
3:按内容划分
功能测试、性能测试、兼容测试
功能测试:
界面测试、冒烟测试、回归测试、业务逻辑测试、易用性测试
功能测试:根据产品操作描述和需求文档,测试一个产品的特性和可操作行为是否满足需求的测试方法
界面测试:测试用户界面的功能模块的布局是否符合客户的使用习惯,界面操作的便捷性、导航简单易懂的测试
冒烟测试:验证系统核心功能是否能够正常运行的测试方法
业务逻辑测试:在基本的功能点都已合格的基础上,准备多种测试数据,来驱动各种约束条件下业务流程,确定是最终输出的结果是否符合预期的测试
]易用性测试:指用户使用软件时是否感觉方便的测试
性能测试:
压力测试、负载测试、并发测试
- 性能测试:通过自动化的测试工具模拟多种正常、峰值以及异常负载条件来对系统的各项性能指标进行效验的测试方法
- 压力测试:通过逐步增加系统负载,测试系统性能的变化,并确定在什么条件下系统性能处于失效状态
- 负载测试:通过逐步增加系统负载,测试系统性能的变化,在满足指标的情况下,系统所能承受的最大负载 量的测试
- 并发测试:是一个负载测试和压力测试的过程,即逐渐增加并发用户数负载直到系统的瓶颈,通过分析资源监控指标等来确定系统并发性能
兼容性测试:
- 浏览器的,不同版本,分辨率
- 手机型号,不同版本,分辨率
4:按其他划分
冒烟测试、随机测试、安全性测试、回归测试、Alpha测试、Beta测试
- 随机测试:随机测试主要是根据测试者的经验无需测试用例对软件进行功能和性能抽查的测试方法
- 安全性测试:通过不同的测试方法,检验程序、网络、数据库安全性的测试方法
- Alpha测试:俗称内测, α测试。内部环境下的测试;开发人员或测试人员在现场
- Beta测试:俗称外测、公测,β测试。生成环境下的测试;开发人员和测试人员都不在现场
虽说入行门槛低,但软件测试涉及的技术知识可不少,求学之路不是容易的事,因此很多朋友纷纷吐槽——
- .没有导师,不知道从哪里开始学起;
- .学习过程中遇到困难,自己无法解决,最终放弃;
- .自律基因没有,惰性太大,不能持之以恒
如果不知道怎么规划,我和朋友们花了半个多月编写整理下面的《软件测试进阶路线》和配套【视频教程资源】,应该会给你带来很大的帮助和方向。:需要的朋友可以在文末打包获取。
测试开发工程师技能成长路径
相信使用过MFC编程的朋友对CString这个类的印象应该非常深刻吧?的确,MFC中的CString类使用起来真的非常的方便好用。但是如果离开了MFC框架,还有没有这样使用起来非常方便的类呢?答案是肯定的。也许有人会说,即使不用MFC框架,也可以想办法使用MFC中的API,具体的操作方法在本文最后给出操作方法。其实,可能很多人很可能会忽略掉标准C++中string类的使用。标准C++中提供的string类得功能也是非常强大的,一般都能满足我们开发项目时使用。现将具体用法的一部分罗列如下,只起一个抛砖引玉的作用吧,好了,废话少说,直接进入正题吧!
要想使用标准C++中string类,必须要包含
#include <string>// 注意是<string>,不是<string.h>,带.h的是C语言中的头文件
using std::string;
using std::wstring;
或
using namespace std;
下面你就可以使用string/wstring了,它们两分别对应着char和wchar_t。
string和wstring的用法是一样的,以下只用string作介绍:
string类的构造函数:
string(const char *s); //用c字符串s初始化
string(int n,char c); //用n个字符c初始化
此外,string类还支持默认构造函数和复制构造函数,如string s1;string s2="hello";都是正确的写法。当构造的string太长而无法表达时会抛出length_error异常 ;
string类的字符操作:
const char &operator[](int n)const;
const char &at(int n)const;
char &operator[](int n);
char &at(int n);
operator[]和at()均返回当前字符串中第n个字符的位置,但at函数提供范围检查,当越界时会抛出out_of_range异常,下标运算符[]不提供检查访问。
const char *data()const;//返回一个非null终止的c字符数组
const char *c_str()const;//返回一个以null终止的c字符串
int copy(char *s, int n, int pos = 0) const;//把当前串中以pos开始的n个字符拷贝到以s为起始位置的字符数组中,返回实际拷贝的数目
string的特性描述:
int capacity()const; //返回当前容量(即string中不必增加内存即可存放的元素个数)
int max_size()const; //返回string对象中可存放的最大字符串的长度
int size()const; //返回当前字符串的大小
int length()const; //返回当前字符串的长度
bool empty()const; //当前字符串是否为空
void resize(int len,char c);//把字符串当前大小置为len,并用字符c填充不足的部分
string类的输入输出操作:
string类重载运算符operator>>用于输入,同样重载运算符operator<<用于输出操作。
函数getline(istream &in,string &s);用于从输入流in中读取字符串到s中,以换行符'\n'分开。
string的赋值:
string &operator=(const string &s);//把字符串s赋给当前字符串
string &assign(const char *s);//用c类型字符串s赋值
string &assign(const char *s,int n);//用c字符串s开始的n个字符赋值
string &assign(const string &s);//把字符串s赋给当前字符串
string &assign(int n,char c);//用n个字符c赋值给当前字符串
string &assign(const string &s,int start,int n);//把字符串s中从start开始的n个字符赋给当前字符串
string &assign(const_iterator first,const_itertor last);//把first和last迭代器之间的部分赋给字符串
string的连接:
string &operator+=(const string &s);//把字符串s连接到当前字符串的结尾
string &append(const char *s); //把c类型字符串s连接到当前字符串结尾
string &append(const char *s,int n);//把c类型字符串s的前n个字符连接到当前字符串结尾
string &append(const string &s); //同operator+=()
string &append(const string &s,int pos,int n);//把字符串s中从pos开始的n个字符连接到当前字符串的结尾
string &append(int n,char c); //在当前字符串结尾添加n个字符c
string &append(const_iterator first,const_iterator last);//把迭代器first和last之间的部分连接到当前字符串的结尾
string的比较:
bool operator==(const string &s1,const string &s2)const;//比较两个字符串是否相等
运算符">","<",">=","<=","!="均被重载用于字符串的比较;
int compare(const string &s) const;//比较当前字符串和s的大小
int compare(int pos, int n,const string &s)const;//比较当前字符串从pos开始的n个字符组成的字符串与s的大小
int compare(int pos, int n,const string &s,int pos2,int n2)const;//比较当前字符串从pos开始的n个字符组成的字符串与s中
//pos2开始的n2个字符组成的字符串的大小
int compare(const char *s) const;
int compare(int pos, int n,const char *s) const;
int compare(int pos, int n,const char *s, int pos2) const;
compare函数在>时返回1,<时返回-1,==时返回0
string的子串:
string substr(int pos = 0,int n = npos) const;//返回pos开始的n个字符组成的字符串
string的交换:
void swap(string &s2); //交换当前字符串与s2的值
string类的查找函数:
int find(char c, int pos = 0) const;//从pos开始查找字符c在当前字符串的位置
int find(const char *s, int pos = 0) const;//从pos开始查找字符串s在当前串中的位置
int find(const char *s, int pos, int n) const;//从pos开始查找字符串s中前n个字符在当前串中的位置
int find(const string &s, int pos = 0) const;//从pos开始查找字符串s在当前串中的位置
//查找成功时返回所在位置,失败返回string::npos的值
int rfind(char c, int pos = npos) const;//从pos开始从后向前查找字符c在当前串中的位置
int rfind(const char *s, int pos = npos) const;
int rfind(const char *s, int pos, int n = npos) const;
int rfind(const string &s,int pos = npos) const;
//从pos开始从后向前查找字符串s中前n个字符组成的字符串在当前串中的位置,成功返回所在位置,失败时返回string::npos的值
int find_first_of(char c, int pos = 0) const;//从pos开始查找字符c第一次出现的位置
int find_first_of(const char *s, int pos = 0) const;
int find_first_of(const char *s, int pos, int n) const;
int find_first_of(const string &s,int pos = 0) const;
//从pos开始查找当前串中第一个在s的前n个字符组成的数组里的字符的位置。查找失败返回string::npos
int find_first_not_of(char c, int pos = 0) const;
int find_first_not_of(const char *s, int pos = 0) const;
int find_first_not_of(const char *s, int pos,int n) const;
int find_first_not_of(const string &s,int pos = 0) const;
//从当前串中查找第一个不在串s中的字符出现的位置,失败返回string::npos
int find_last_of(char c, int pos = npos) const;
int find_last_of(const char *s, int pos = npos) const;
int find_last_of(const char *s, int pos, int n = npos) const;
int find_last_of(const string &s,int pos = npos) const;
int find_last_not_of(char c, int pos = npos) const;
int find_last_not_of(const char *s, int pos = npos) const;
int find_last_not_of(const char *s, int pos, int n) const;
int find_last_not_of(const string &s,int pos = npos) const;
//find_last_of和find_last_not_of与find_first_of和find_first_not_of相似,只不过是从后向前查找
string类的替换函数:
string &replace(int p0, int n0,const char *s);//删除从p0开始的n0个字符,然后在p0处插入串s
string &replace(int p0, int n0,const char *s, int n);//删除p0开始的n0个字符,然后在p0处插入字符串s的前n个字符
string &replace(int p0, int n0,const string &s);//删除从p0开始的n0个字符,然后在p0处插入串s
string &replace(int p0, int n0,const string &s, int pos, int n);//删除p0开始的n0个字符,然后在p0处插入串s中从pos开始的n个字符
string &replace(int p0, int n0,int n, char c);//删除p0开始的n0个字符,然后在p0处插入n个字符c
string &replace(iterator first0, iterator last0,const char *s);//把[first0,last0)之间的部分替换为字符串s
string &replace(iterator first0, iterator last0,const char *s, int n);//把[first0,last0)之间的部分替换为s的前n个字符
string &replace(iterator first0, iterator last0,const string &s);//把[first0,last0)之间的部分替换为串s
string &replace(iterator first0, iterator last0,int n, char c);//把[first0,last0)之间的部分替换为n个字符c
string &replace(iterator first0, iterator last0,const_iterator first, const_iterator last);//把[first0,last0)之间的部分替换成[first,last)之间的字符串
string类的插入函数:
string &insert(int p0, const char *s);
string &insert(int p0, const char *s, int n);
string &insert(int p0,const string &s);
string &insert(int p0,const string &s, int pos, int n);
//前4个函数在p0位置插入字符串s中pos开始的前n个字符
string &insert(int p0, int n, char c);//此函数在p0处插入n个字符c
iterator insert(iterator it, char c);//在it处插入字符c,返回插入后迭代器的位置
void insert(iterator it, const_iterator first, const_iterator last);//在it处插入[first,last)之间的字符
void insert(iterator it, int n, char c);//在it处插入n个字符c
string类的删除函数
iterator erase(iterator first, iterator last);//删除[first,last)之间的所有字符,返回删除后迭代器的位置
iterator erase(iterator it);//删除it指向的字符,返回删除后迭代器的位置
string &erase(int pos = 0, int n = npos);//删除pos开始的n个字符,返回修改后的字符串
string类的迭代器处理:
string类提供了向前和向后遍历的迭代器iterator,迭代器提供了访问各个字符的语法,类似于指针操作,迭代器不检查范围。
用string::iterator或string::const_iterator声明迭代器变量,const_iterator不允许改变迭代的内容。常用迭代器函数有:
const_iterator begin()const;
iterator begin(); //返回string的起始位置
const_iterator end()const;
iterator end(); //返回string的最后一个字符后面的位置
const_iterator rbegin()const;
iterator rbegin(); //返回string的最后一个字符的位置
const_iterator rend()const;
iterator rend(); //返回string第一个字符位置的前面
rbegin和rend用于从后向前的迭代访问,通过设置迭代器string::reverse_iterator,string::const_reverse_iterator实现
字符串流处理:
通过定义ostringstream和istringstream变量实现,#include <sstream>头文件中
例如:
string input("hello,this is a test");
istringstream is(input);
string s1,s2,s3,s4;
is>>s1>>s2>>s3>>s4;//s1="hello,this",s2="is",s3="a",s4="test"
ostringstream os;
os<<s1<<s2<<s3<<s4;
cout<<os.str();
以上就是对C++ string类的一个简要介绍。用的好的话它所具有的功能不会比MFC中的CString类逊色多少,呵呵,个人意见!
最后要介绍如何在Win32 应用程序中引用MFC中的部分类,例如CString。
1.在工程目录下右键选择"Properties”--->"Configuration Properties”--->“General”--->"Use of MFC"--->"Use MFC in a Static Library",
默认的是:"Use Standard Windows Libraries",如下图:
2.在你所用的所有头文件之前包含#include <afxwin.h>,例如:可以在stdafx.h文件的最前面包含#include <afxwin.h>头文件,这样在你的源代码中就可以使用
CString类了,不过这样也有一个缺点,就是编译出来的程序要比原来的大很多。我试过一个小程序,选择"Use Standard Windows Libraries" 编译出来
的Release版本大概92kb,使用"Use MFC in a Static Library"编译出来的Release版本大概192kb,足足大了100kb,这个就个人考虑了......
```python
class BertPooler(nn.Module):
def __init__(self, config):
super().__init__()
self.dense = nn.Linear(config.hidden_size, config.hidden_size)
self.activation = nn.Tanh()
def forward(self, hidden_states):
# We "pool" the model by simply taking the hidden state corresponding
# to the first token.
first_token_tensor = hidden_states[:, 0]
pooled_output = self.dense(first_token_tensor)
pooled_output = self.activation(pooled_output)
return pooled_output
from transformers.models.bert.configuration_bert import *
import torch
config = BertConfig.from_pretrained("bert-base-uncased")
bert_pooler = BertPooler(config=config)
print("input to bert pooler size: {}".format(config.hidden_size))
batch_size = 1
seq_len = 2
hidden_size = 768
x = torch.rand(batch_size, seq_len, hidden_size)
y = bert_pooler(x)
print(y.size())
```