加入收藏 | 设为首页 | 会员中心 | 我要投稿 淮安站长网 (https://www.0517zz.com.cn/)- 数据开发、人脸识别、智能机器人、图像处理、语音技术!
当前位置: 首页 > 站长资讯 > 评论 > 正文

我总结出10个数据科学面试必掌握概念……

发布时间:2021-01-30 10:39:30 所属栏目:评论 来源:互联网
导读:在单体数据库时代,数据库本身就支持ACID事务,开发人员甚至只要在方法上加一个@Transactional注解就可以搞定事务了,非常简单。但是到了分库分表和分布式数据库时代,传统数据库的ACID属性只能在单节点上起作用,全局事务需要一个全局的事务管理器来维护,

在单体数据库时代,数据库本身就支持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,如下图:
 

  • 时间复杂度O(n)
  • 空间复杂度O(1)

总结

本题掌握其动规的方法,就可以了,贪心的解法确实简单,但需要有数学证明,如果能自圆其说也是可以的。

其实这道题目的递推公式并不好想,而且初始化的地方也很有讲究,我在写本题的时候一开始写的代码是这样的:
 

那有同学问了,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]正好可以通过我们初始化的数值求出来。

所以遍历顺序为:

(编辑:淮安站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读