我总结出10个数据科学面试必掌握概念……
在单体数据库时代,数据库本身就支持ACID事务,开发人员甚至只要在方法上加一个@Transactional注解就可以搞定事务了,非常简单。但是到了分库分表和分布式数据库时代,传统数据库的ACID属性只能在单节点上起作用,全局事务需要一个全局的事务管理器来维护,复杂性很高。 而在分布式事务领域,全局事务使用的最多的指导方案就是2PC,也叫两阶段提交,但是2PC也有一些缺陷,今天我们就来看看分布式数据库是怎么对这些缺陷做优化的。 两阶段提交(2PC) 两阶段提交协议主要有2种,一种是应用层的TCC,比如阿里巴巴的seata就实现了TCC模式,这种模式的特点是每个服务都需要提供try/confirm/cancel这3个实现,这3个实现需要在业务代码中实现,对业务侵入高。 今天我分享的是面向资源的2PC协议,最早由Jim Gray提出,整个事务分为2个阶段,prepare阶段和commit阶段,这2个阶段由协调节点和DB资源管理器协作完成。 这里我们还是以经典的电商系统为例,整个系统分为订单、账户和库存3个服务,我们收到客户的购买请求后,协调节点需要协调订单服务生成订单,账户服务扣减商品款,库存服务扣减商品库存,假如这3个服务的数据库在不同切片上,这个协调过程具体如下: 1.prepare阶段
协调节点向所有服务发送prepare请求,每个服务收到prepare请求后会尝试执行本地事务,但不会真正提交本地事务。这个尝试执行的过程会检查到是否具备执行事务的条件,比如资源是否被锁定等,当所有服务都尝试执行成功后会给协调节点返回一个yes,如下图:
总结 本题掌握其动规的方法,就可以了,贪心的解法确实简单,但需要有数学证明,如果能自圆其说也是可以的。
其实这道题目的递推公式并不好想,而且初始化的地方也很有讲究,我在写本题的时候一开始写的代码是这样的: 那有同学问了,j怎么就不拆分呢? j是从1开始遍历,拆分j的情况,在遍历j的过程中其实都计算过了。 那么从1遍历j,比较(i - j) * j和dp[i - j] * j 取最大的。 递推公式:dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j)); 3.dp的初始化 不少同学应该疑惑,dp[0] dp[1]应该初始化多少呢? 有的题解里会给出dp[0] = 1,dp[1] = 1的初始化,但解释比较牵强,主要还是因为这么初始化可以把题目过了。 严格从dp[i]的定义来说,dp[0] dp[1] 就不应该初始化,也就是没有意义的数值。 拆分0和拆分1的最大乘积是多少? 这是无解的。 这里我只初始化dp[2] = 1,从dp[i]的定义来说,拆分数字2,得到的最大乘积是1,这个没有任何异议! 确定遍历顺序 确定遍历顺序,先来看看递归公式:dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j)); dp[i] 是依靠 dp[i - j]的状态,所以遍历i一定是从前向后遍历,先有dp[i - j]再有dp[i]。 枚举j的时候,是从1开始的。i是从3开始,这样dp[i - j]就是dp[2]正好可以通过我们初始化的数值求出来。
所以遍历顺序为: (编辑:淮安站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |