C++编程实践——数据交互的处理

一、数据交互

计算机技术能够迅速普及并发展到今天,一个重要的原因就是能够与操作者的各种交互,但从本质上讲,其就是数据的交互。不管是所谓的命令还是什么按键,其最终体现到计算机系统中,都是对数据的不同情况的应对,从而产生不同的运行结果。一般来说,常见的用户与计算机的交互方式有以下几种情况:

  1. 命令行交互
    这是最典型也是最较早的交互方式,特别是在Dos时代,基本上就是主流。也就是大家常见的一个黑乎乎的窗口,在里面输入各种命令并查看相关的结果
  2. UI交互方式
    自从windows出现后,这种交互方式逐渐成为了主流,而命令交互方式的复杂性则渐渐被淡化。这就交互方式有很多,比如通过键盘、鼠标或触屏等都可以划到这个范畴内
  3. 文件交互方式
    在与计算机的交互过程中,通过文件的方式传入或传出相关的数据,是很经典的一种方式。即使在现在,文件也是与计算机交互的一种重要的类型。另外,设备和或软件也可以抽象做为一种文件,这种方式现在也极为常见,如Linux中一切皆为文件。
  4. 智能交互方式
    这种方式是最近这些年才逐渐被大家所重视,即通过算法或AI系统实现了以语音、图像识别、手势等的交互方式
  5. 其它
    包括一些小众的如打卡机为代表的老式的交互方式以及在实验室中的脑机接口等等先进的交互方式

二、交互的安全性和效率

不知道大家有没有看到过前些年报道的一个系统级的问题,一个外国小女孩胡乱的反复的按键盘则可以直接进入系统,而不需要输入用户名和密码。这其实就是一个非常少见但典型的实际的例子。也就是说,对于绝大多数人来说,大家都是在一个规则中进行操作,极少或者根本不可能做出一些非法的操作。举一个现实的例子大家就明白了,大家都知道闯红灯违法,所以对于正常的人,极大概率是不会闯红灯的。但这不代表没人去闯红灯,这些人可能包括一些本身有问题的人,有紧急情况的人,有大意过失的人,如此等等。但终归这些情况是少数,否则交通不早就乱成一锅粥了。
而计算机与操作者的数据交互,同样需要处理这种少数的行为并且不能因为这种处理降低对正常交互的效率。即达到一个平衡,既不能因为效率而放弃安全性,也不能因为安全性而增加过于臃肿和复杂的安全校验。安全性和效率一般需要注意以下几点:

  1. 数据的正确性验证
    包括使用断言、正则等来判断数据的交互的正确性。或在将数据输出前进行数据的各种检验等等。常见的例子包括用户邮箱的输入、人脸交互时的活体检测等等。
  2. 错误和异常的处理
    在错误和异常出现,如何对数据交互的状态进行安全控制,从而保证程序的继续安全运行并恢复相关的运行状态等等。举一个例子,大家在命令窗口中故意输入一个错误的命令,窗口会提示没有这个命令,并返回当前的命令状态和相关说明,如果有相近的命令则会进行提示是否是想输入这些命令。

三、常见的处理方式

对于数据交互的处理,在基于安全性的前提下,一般会有以下几种处理方式:

  1. 整体的交互设计
    软件的健壮性是根本,而交互数据的破坏往往是软件Crash的一个重要原因。所以必须从整体上对交互的数据进行各种的安全检查和逻辑判断等等控制。如在网页上对于是否是机器人在操作就要进行验证。
  2. 数据的检查和预处理
    包括常见的密码的长度、命令的参数等等,都需要进行限制和检查;同时需要对相关的数据输入和输出进行预处理,也就是常见的数据清洗和过滤。最常见的例子就是,在把分析好的数据向外吐出前,必须把敏感数据进行清洗和过滤,否则,可能会引起社会性的程序不健壮
  3. 容错和恢复机制
    要允许适当的可控的错误的输入,并且对不可控的错误输入导致的异常时,能够恢复到初始或指定的状态(即降级,这在电商等网站是一种强需求),不影响下一步的数据交互
  4. 日志和监控
    能够利用日志将相关的问题记录(包括感兴趣的细节,如操作者等等),并在监控到问题时,及时的向相关人员进行通知
  5. 全面的测试
    这个开发者应该都明白,从单元测试一直到最后的集成测试等等,是极大的降低数据交互问题的重要的保障机制

四、C++中的实践

针对上面的处理方式,在C++中一般使用下面的处理方式:

  1. 数据的检查
//数组越界
#define N 100

int arr[N] ={0};
void test(int i){
if (i < N){...}
}
//正则邮箱检查
bool isValid(const std::string&email){
const std::regex pattern(
        R"(^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$)"
    );
    
auto ret = std::regex_match(email, pattern);
return ret;
}
  1. 错误的处理
//断言
assert(b !=0);
int c = a/b;
//错误码 
int fd = open("test.txt", O_RDONLY);
if (fd = -1){}
//异常
#include <iostream>
#include <stdexcept> // 包含标准异常类

void checkNumber(int number) {
     throw std::runtime_error("run err!"); 
}

int main() {
    try {
        checkNumber(3);  
    } catch (const std::excetion& e) { 
        std::cerr << "exception: " << e.what() << std::endl;
    }
    return 0;
}

  1. 日志记录
//使用谷哥日志
LOG(INFO)<<"test info!";
  1. 类型验证
//SFINAE
template<typename T, typename = void>
struct IsBase : std::false_type {};

template<typename T>
struct IsBase<T, std::enable_if_t<std::is_base_of<Base, T>::value>> : std::true_type {};
//概念或约束
template<typename T>
void checkIsBase() {
    if constexpr (std::is_base_of_v<Base, T>) {
        std::cout <<  " is OK!" << std::endl;
    } else {
        std::cout <<  " no is!" << std::endl;
    }
}

上面的代码还是很容易理解的,大家可以对照着看一看。其实真正写过类似的代码的同学们都明白,数据的校验往往是很复杂的。特别是和钱有关系的交互接口,往往验证都复杂的一批。

五、总结

在现实世界的工地上经常看到类似于“安全大于一切”的标语。其实计算机世界也也是如此,数据交互做为计算机成为人类最有效的工具的前提之一,对其进行各种安全处理,是一种非常重要且必然的机制和手段。一个优秀的架构师和开发人员,如果不能看清这个前提,那么所做的工作就会变成无本之木。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值