泛型算法 - 从泛型到函数绑定与迭代器拓展
什么是泛型
泛型是一种编程规范,它具有较高的抽象级别。泛型是描述一类函数,任何实现必要方法的对象都可以使用泛型函数。在一些其他语言中,会定义有接口的概念,它实际为一组函数的集合,任何符合全部函数的类都称为符合这个接口的。
在 C++ 标准库中存在大量的泛型函数,它们通常用于操作容器,这些泛型函数具有相同的特性,它们都将迭代器作为其主要参数,因此任何容器只要拥有足够支持的迭代器都可以使用泛型函数。
泛型函数的定义实际比较广泛,而在 C++ 中泛型通常特指迭代器实现的通用算法,其中常用的泛型算法就包括:std::find、std::sort 等,使用过这些函数的都清楚,它们的前两个参数均为迭代器对象。另外,在定义泛型时,还需要模板元语法的支持,不过本章节将着重介绍泛型的使用,我们暂时不会介绍如何定义自己的泛型。
初识迭代器
前面讲到,在 C++ 的泛型函数中,它们几乎都以迭代器作为其参数,而泛型函数要求对象具有相同的支持,换句话说它们必须满足接口(尽管 C++ 中并没有接口的概念)。那么我们首先需要了解一些基本的迭代器,了解它们具有哪些支持,因此可以用于哪些泛型函数。
迭代器类型
迭 ...
C++ 与三种智能指针 - 代码复现与辨析
前言
在 C 语言中,动态内存管理一直是一个非常头疼的问题,你需要自己申请内存与释放内存,一不小心就容易触发内存泄露、指针悬挂、重复释放等问题,这些问题可能还是隐性的,不容易排查。在 C++ 11 引入的三种智能指针 shared_ptr、unique_ptr、weak_ptr 用于自动管理动态内存,当然不规范的使用它们依然会导致一些问题。值得注意的是,在更早的 C++ 版本中的 auto_ptr 在 C++ 11 开始被弃用,在 C++ 17 被移除,你可以使用 unique_ptr 来替代它,本文不会讲解。
本文将从两个方面介绍 shared_ptr、unique_ptr、weak_ptr 三种智能指针,这包括:规范使用智能指针、智能指针原理和代码复现。
shared_ptr 共享指针
创建共享指针
shared_ptr 可以使用下面的四种方法构造:
1234567891011121314void deleter(int *p) { delete p; cout << "Free " << p << en ...
四种 cast 强制类型转换
前言
在 C 语言中,直接使用类型即可完成强制类型转换,形如 (int)x。而在 C++ 中强制类型转换被分为四类:static_cast / const_cast / reinterepret_cast / dynamic_cast 四类。当然 C++ 也保留了传统类型转换。
传统类型转换
传统 C 语言类型转换具有最高的级别,它能完成我们后面将会介绍的四种 cast 支持的所有强制类型转换。但在 C++ 中之所以提出四类 cast ,是因为将强制类型转换分门别类被认为是更安全的。首先,强制类型转换都是危险的,你需要清楚的知道进行转换可能带来的后果,四类 cast 一定程度上确保你正确进行转换,否则将会发生编译错误(dynamic_cast 可能会发生运行时错误)。
值得注意的是,在 C++ 中提出的 static_cast / const_cast / reinterepret_cast / dynamic_cast 都是关键字,足见其地位之重。
最后,传统 C 语言类型转换在 C++ 中又分为两种:C 风格类型转换、 C++ 风格传统类型转换。其实两者并没有区别,只是在语法习惯上 ...
使用 Matplotlib 绘图
前言
Matplotlib 在 Python 中提供了类似于 MATLAB 的绘图支持,有人说使用 Numpy、Pandas、Scipy、Matplotlib 就可以完全替代 MATLAB。其中,Matplotlib 提供图像库支持,而 Numpy 提供优秀的向量计算、Pandas 提供便携的结构存储、Scipy 提供额外的计算库支持。Matplotlib 经常被用于数据分析,常常和 Numpy 等一起使用,本文不会系统的介绍这些库,而是从一些示例的方式快速入手 Matplotlib。
在阅读本文方面的建议是,你无需记忆每个模块,需要时将本文中的代码粘贴到你的 IDE 中然后尝试运行并根据你的需求改写。另外,提前声明作者本人并未使用过 MATLAB 而直接学习使用的 Matplotlib。
多样式平面折线
Matplotlib 绘图最常用的就是 matplotlib.pyplot.plot 方法,它接受主参数 xdatax_{data}xdata、ydatay_{data}ydata,表示对应的 xxx 坐标和 yyy 坐标,例如 (xdata[0], ydata[0])(x_{ ...
事务隔离级别与 MVCC 机制
事务
在 MySQL 中事务提供三个关键字:BEGIN(开始事务)、COMMIT(提交事务)、ROLLBACK(回滚事务)。
事务以 BEGIN 开始,以 COMMIT 或 ROLLBACK 结束,如果事务提交那么正常结束,如果事务回滚它会回到 BEGIN 的状态。事务的作用在于,它将整个事务视为一个原子操作,必须全部完成,否则回滚。例如,我们在做一笔交易时,扣款和提交订单必须绑定完成,如果流程中出现任何故障它必须回滚。
COMMIT 示例COMMIT 输出ROLLBACK 示例ROLLBACK 输出1SELECT * FROM test;
1234BEGIN;INSERT INTO test VALUES(2, "Jhon", 20);SELECT * FROM test;COMMIT;
1SELECT * FROM test;12345+----+-----------+------+| id | name | age |+----+-----------+------+| 1 | JamhusTao | 19 |+----+--------- ...
从 MySQL 学习 PostgreSQL
本文假设您已掌握了 MySQL 的基本使用,现在快速学习 PostgreSQL。主要介绍两者差异化语法。
为什么学习 PostgreSQL最初我了解 PostgreSQL 是数据库课上,我们老师非常的特别,因为多数老师数据库教学都会选择 MySQL。
作为全英文授课,这位老师的英文教学格外清晰易懂,我英语不好但听她上课非常舒服,她讲到:由于 MySQL 被 Oracle 收购,MySQL 虽然之前一直因为开源而备受青睐,近年却颇有商业化趋势。PostgreSQL 被越来越多的当作 MySQL 的替代品被应用。
另外,PostgreSQL 由于诞生晚于 MySQL 不仅性能上更加优越,支持上更广泛,语法也更现代化。不过在学习 PostgreSQL 的过程中也会发现其一些值得诟病的地方,这里不展开描述。
个人在学习数据库课程中的感受是,PostgreSQL 在社区支持方面不如 MySQL,因此感觉在中文社区学习 MySQL 然后转向 PostgreSQL 是一个不错的选择。
下载与安装
这里我们直接选择使用图形化工具,你可以选择 PgAdmin ,它是官方开源的。
PostgreSQL ...
使用触发器与视图
触发器
什么是触发器
触发器(Trigger)顾名思义可以在一个事件发生时,自动地执行一段逻辑。当我们需要维护一系列表的信息时,可以使用一些触发器自动维护,虽然这些维护的逻辑放在业务代码中更好一些,但 MySQL 以及其他许多 SQL 提供的触发器也提供了一个解决方案。
相关语法
创建触发器:
12345CREATE TRIGGER {触发器名} {BEFORE | AFTER} {INSERT | UPDATE | DELETE} ON {检测表名} FOR EACH ROWBEGIN {执行逻辑}END;
删除触发器:
1DROP TRIGGER {触发器名};
显示触发器:
1SHOW TRIGGERS;
触发器使用示例
例如在更新外键时,使用触发器更新主表使两者保持连接。
例如插入或更新元素时,使用触发器进行复制逻辑检测,如果非法,禁止更新。
注意事项
使用触发器应防止循环递归调用,否则会发生错误。
视图
什么是视图
视图(VIEW)提供 ...
python 面向对象编程备忘
基本结构
123456789101112131415161718192021222324252627282930class Animal: count = 0 # 函数外使用静态变量 # 构造函数, __xxx__ 为特殊成员函数, 具有官方指定的特殊用途, 非私有 def __init__(self, name: str): self.name = name # 公有成员变量 self._name = name # 受保护成员变量, 使用 _ 开头, python 不强制受保护只是用户约定 self.__name = name # 私有成员变量, 使用 __ 开头 Animal.count += 1 # 函数内使用静态变量 # 公有成员函数 def get_name(self) -> str: return self.__name # 受保护成员函数, 使用 _ 开头, python 不强制受保护只是用户约定 def _get_nam ...
使用键与索引
在 SQL 中存在多种键,通常用于约束和查询。本文将介绍主键、唯一键、非空值、默认值、外键与索引。
开始前的一个小芝士本文将介绍键和索引的使用,这首先需要学会查看已有键和索引,但是初学者往往不知道如何查看表的结构。不同 SQL 语言查看的方法各不相同,对于 MySQL 可以使用下面的命令。
1SHOW CREATE TABLE {表名};
示例输出1SHOW CREATE TABLE MOvies;1234567891011121314+--------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ...
数据库中的范式
范式是一套严格的概念,本文从个人的理解解释范式,描述不一定严谨。
在关系型数据库中,关于数据表设计的基本原则和规范,被称为范式(Normal Form)。在 SQL 中对范式不作强制要求,但范式却是减少数据冗余、便利数据维护非常有效的设计原则。范式分为五级,其中常用的为前三级,每级范式满足的条件需首先满足上一级。
需要注意的是,虽然范式可以有效减少数据冗余,但随范式等级的提高,可继续减少的冗余减少,随表的变多询问效率却在下降。因此常用的范式仅为前三级和 BC 范式,另外还提出了反范式牺牲一些规范来提高效率。
键
在介绍范式前,需要再次明确键的概念,在后面范式的描述中,需要使用。
超键:可唯一确定一条记录的字段组成的元组,可以只有一个字段。
候选键:没有子集是超键的超键。通俗地讲,候选键是没有冗余字段的用于唯一确定字段的元组。
主键:用户从候选键中选择一个(或不选)作为主键,包含多个字段的主键称为联合主键。用户应选择合适的候选键作主键。
外键:用于与外表联结的键,对应外表中的主键。
主属性:包含于任意候选键的字段。
非主属性:不包含于任何候选键的字段。
第一范式(1NF)
第一 ...