设计原则
依赖倒置原则(DIP)
高层模块(稳定)不应该依赖于低层模块(变化),二者都应该依赖 于抽象(稳定)
抽象(稳定)不应该依赖于实现细节(变化),实现细节应该依赖于 抽象(稳定)
开放封闭原则(OCP)
对扩展开放,对更改封闭
类模块应该是可扩展的,但是不可修改
模版方法(Template Method)
模式动机
一些功能在底层开发模块时不知具体实现,而需要在高层模块实现
在转账场景中,A向B转账100元。转账过程需要保证的是要么转账成功,要么转账失败恢复到原始值(原子性 Atomicity);转账前后A与B账号的存款总数不变(一致性 Consistency);转账过程中A与B的其他转账操作不影响当前转账(隔离性 Isolation);转账成功则不可撤回(持久性 Durability)。所以引入事务(Transaction)的概念
InnoDB 引擎通过什么技术来保证事务的这四个特性的呢?
一级封锁协议
事务 T 在修改数据 W 之前必须先对其加 X 锁,直到事务结束才释放(读不加锁)
一级封锁协议可防止 丢失修改
二级封锁协议
一级封锁协议基础上,事务 T 在读取数据 R 之前必须先对其加 S 锁,读完后即可释放 S 锁
**二级封锁协议可以防止 丢失修改 和 读 “脏” 数据 **
三级封锁协议
一级封锁协议基础上,事务 T 在读取数据 R 之前必须先对其加 S 锁,直到事务结束才释放
三级封锁协议可防止 丢失修改、读脏数据和不可重复读
几个事务的并行执行是正确的,当且仅当其结果与按某一次序串行地执行它们时的结果相同。 这种并行调度策略称为可串行化(Serializable) 的调度
可串行性是并行事务正确性的唯一准则
冲突操作是指读写操作和写写操作
类不是实体,对象是实体
成员变量(filed)属于对象
成员函数(member function)属于类
列表初始化(initialize list)仅对成员变量初始化。
在构造函数里对成员变量初始化则为先初始化(默认)后赋值,故所有成员变量必须要有默认的初始化方法(成员变量包含其他类但该类没有默认构造函数则会报错)。构造函数无法主动调用。
尽量使用列表初始化
1 | class A{ |
使用B+树作为存储结构,非叶子结点存放索引,叶子节点才会存放实际数据(索引+记录)
B+树与B树的对比如下
当通过主键指定条件时,通过主键索引遍历到叶子结点,获得主键值和其对应的数据
对于回归或分类问题使用合适的模型,在本文中对于回归问题使用线形回归模型,对于分类问题使用Logistic回归模型
$$
J(w,b) = \frac{1}{2m} \sum\limits_{i = 0}^{m-1} (f_{w,b}(x^{(i)}) - y^{(i)})^2
$$
$$
f_{w,b}(x^{(i)}) = wx^{(i)} + b \tag{2}
$$
计算预测值与现实值的均方误差后取平均(除以2是为了在求导时与平方的2约去)
如果不同属性的取值返回相差过大则会导致模型收敛得很慢,所以要对属性值做映射。
常用缩放方法:
均值标准化
$$
x_i := \dfrac{x_i - \mu_i}{max - min}\tag{Mean normalization}
$$
1 | vector<vector<int>> build_tree_with_table(int node_count,vector<vector<int>> prerequisites) |
1 | vector<vector<int>> build_tree_with_martix(int node_count,vector<vector<int>> prerequisites) |
使用on_path
判断当前访问的结点是否在当前访问列表中,如果在则表示有环
1 | vector<vector<int>> path_lists; |