在公司一直在做跟支付有关的项目,某日接到平安某金所一男子电话,应该是之前某猎头投的,我正好在吃早饭(也不能怪他们上班早,我们公司弹性工作制,我一般上班比较晚)。

因为饭馆信号不好,只能赶紧放下剩下的半碗馄饨(肉痛啊),走了一公里(那片移动信号真是渣)。

终于可以正常交流了。对方让我先挑一个项目说说,我一听这套路,牛啊!跟之前的阿里一样(以后找机会再聊聊那次面经),肯定是随机在我项目中找点来问了,那我就开始说,说到有个补扣款的场景,一开始设计每次客户端发差额过来,很难保证幂等性,后来设计让客户端发总额过来,幂等问题解决了。这里我重申下幂等定义啊,想必大家都知道了,就是对于一个操作,多次执行,副作用是一样的,而不是叠加的。比如我扣款,如果我无法分清客户端过来的差额是补扣还是重试,那么很可能多扣客人钱。

那么问题来了,总额模式为什么能解决问题?某金所面试官逮到机会发问,而且我注意到他的发问仿佛是循循善诱,告诉我,年轻人,你是不是不懂幂等啊,跟我这里乱讲,我知道的解决幂等的方案是不一样的喔!我当时没反应过来,觉得大牛应该不用我解释幂等吧,应该是在考校我,那么我就描述了一下场景,如果保险费原来是10元,客户端增加了10元,加一加,20元给我,那么即使这个20元给了多次,保险费还是20元不会变,是不是这个理?

然后奇葩的事情发生了,面试官开启教育模式,后面就一直是他在说,说我这个只是业务上的变动而已,并没有真正的解决幂等啊(我心想这怎么没解决幂等呢,从定义上来说解决了啊),然后又说,差额也能解决幂等问题啊,我就可以解决!我赶紧说,我也可以,就是用唯一的UUID策略,重发的话使用上次同样的UUID,那么我这边服务就不做处理落。他说,你知道为什么不说呢,这个才是技术上的正解啊,你跟我说业务上的东西干嘛啊,你说的根本解决不了问题,还是要用这方案才行。我说,这个是基础的东西,类似接口实现都会那么做啊,但是由于是老的协议,这个临时方案改动最小,也最经济。然后面试官沉默了一会儿,问我,你说说你在Java方面的心得吧,我说了一点,但是明显感觉他在敷衍了。后来就没有后来了。

说真的,这次面经真是让我深受打击,面试官到底是大牛呢,还是只知道背书的奇葩呢?但是,正是因为人家是平安某金所的总监(也许吧),我只是渣渣程序员一枚,这种地位差距导致了我对自己知识和经验的怀疑。

但是最近看到了大神Jim Webber的大作REST in Practice,我重新找回了自信心,其中介绍到HTTP的PUT方法是幂等的,为什么呢,解释是这样的(我直接打中文了),“由于PUT请求是幂等的(因为服务端状态被客户端状态整个地替代了),消费者可以安全地按照自己的需要多次重复该操作......”。

这里大神提到的其实是一种面向资源的设计理念(ROA),PUT方法实现对资源的更新,就像保险费,如果你把它看成是资源,那么每次就应该直接用新值替换(总额替代总额),而如果你把修改保险费本身看成一种操作,每次需要扣多少钱(总额减差额),那么就会破坏幂等,而我们现在大多WebService的设计都是基于操作的思维,为了实现幂等又引入一套复杂的机制,人为添加了复杂性。

平安某金所奇葩的面经-关于幂等和ROA设计的反思的更多相关文章

  1. [从源码学设计]蚂蚁金服SOFARegistry之消息总线

    [从源码学设计]蚂蚁金服SOFARegistry之消息总线 目录 [从源码学设计]蚂蚁金服SOFARegistry之消息总线 0x00 摘要 0x01 相关概念 1.1 事件驱动模型 1.1.1 概念 ...

  2. [从源码学设计]蚂蚁金服SOFARegistry之存储结构

    [从源码学设计]蚂蚁金服SOFARegistry之存储结构 目录 [从源码学设计]蚂蚁金服SOFARegistry之存储结构 0x00 摘要 0x01 业务范畴 1.1 缓存 1.2 DataServ ...

  3. [从源码学设计]蚂蚁金服SOFARegistry之服务上线

    [从源码学设计]蚂蚁金服SOFARegistry之服务上线 目录 [从源码学设计]蚂蚁金服SOFARegistry之服务上线 0x00 摘要 0x01 业务领域 1.1 应用场景 1.1.1 服务发布 ...

  4. [从源码学设计]蚂蚁金服SOFARegistry之配置信息

    [从源码学设计]蚂蚁金服SOFARegistry之配置信息 目录 [从源码学设计]蚂蚁金服SOFARegistry之配置信息 0x00 摘要 0x01 业务范畴 1.1 配置作用 1.2 学习方向 0 ...

  5. EntityFreamWork和Mvc 精品知识点

    定义了DbRepository<TEntity>:IRepository<TEntity> ,SimpleDbContext继承了DbContext, UnitOfWork:I ...

  6. Android子线程更新主界面

    学习什么的还是要真正的有应用,有需求才能在最短的时间里面牢牢掌握一项技术. 今天就是这样的,产品一个需求下来,十万火急啊.然后之前只稍稍接触过,只能硬着头皮上了.最后牢牢地掌握了最简单的Handler ...

  7. OO第1~3次作业总结

    作业1——多项式运算 基于度量和类图分析设计 先看Metrics插件做出的复杂度分析: 乍一看没有红色报警,其实是因为选中某一行时会自动将该行改为黑色,无论之前是红色还是蓝色emmm 真正展开第一行时 ...

  8. go递归函数如何传递数组切片slice

    数组切片slice这个东西看起来很美好,真正用起来会发现有诸多的不爽. 第一,数组.数组切片混淆不清,使用方式完全一样,有时候一些特性又完全不一样,搞不清原理很容易误使用. 第二,数组切片的appen ...

  9. 软工网络15团队作业8——Beta阶段敏捷冲刺(Day4)

    提供当天站立式会议照片一张 每个人的工作 1.讨论项目每个成员的昨天进展 赵铭: 在知晓云上建立数据表 吴慧婷:做了背单词界面并学习了词库界面的设计. 陈敏: 我的词库-全部词汇功能/新建词汇功能全部 ...

随机推荐

  1. 【TCP/IP 合约】 TCP/IP 基金会

    总结 : 通过学习 TCP/IP 基础, 并总结相关笔记 和 绘制思维导图 到博客上, 对 TCP/IP 框架有了大致了解, 之后開始详细学习数据链路层的各种细节协议, 并作出笔记; 博客地址 : h ...

  2. Reorder List [leetcode] 这两种思路

    第一个想法随着vector保存全部Node* 表拼接出来 void reorderList(ListNode *head) { vector<ListNode*> content; Lis ...

  3. Java Math的floor,round,ceil函数小结

    转自 http://blog.csdn.net/foart/article/details/4295645 floor 返回不大于的最大整数 round 则是4舍5入的计算,入的时候是到大于它的整数( ...

  4. JDNI

    JNDI是为了一个最最核心的问题:是为了解耦,是为了开发出更加可维护.可扩展的系统JNDI和JDBC起的作用类似:JDBC(Java Data Base Connectivity,java数据库连接) ...

  5. MVC5个人用户账户身份验证集成google和facebook的OAuth2登陆

    最终效果 官方文档:MVC 5 App with Facebook, Twitter, LinkedIn and Google OAuth2 Sign-on 内容简介:上面传送门的博客中讲解了如何在M ...

  6. 对LevelDB的“升级版”存储引擎RocksDB的调研成果

    Google的leveldb是个非常优秀的存储引擎.但还是有一些不尽人意的地方,比方leveldb不支持多线程合并.对key范围查找的支持还非常easy,未做优化措施,等等.而Facebook的Roc ...

  7. ADT后windows菜单未找到Android SDK Manager和Android Virtual Device Manager该解决方案的选择

    打开今天凌晨ADT准备编译androidproject的时候,突然发现windows菜单下的Android SDK Manager和Android Virtual Device Manager选项不见 ...

  8. swift 笔记 (十九) —— 协议

    协议(Protocols) 协议仅是用定义某些任务或者是功能必须的方法和属性. 类似于java里的interface的作用.但协议并不会实现详细的功能. 我猜这个名字源于OO中提到的"契约& ...

  9. C++学习笔记13-类继承

    1.  类模板的 static 成员[不同于C#中的static] 类模板能够像随意其它类一样声明static 成员.下面代码: template <class T> class Foo ...

  10. 移动web点5像素的秘密(转)

    最近和一个朋友聊天,朋友吐露了工作上的一些不开心,说自己总是喜欢跟别人比较,活得比较累,这种感觉大部分人经历过,往往觉得是自己心态不好,其实不然,这是人性,此时应该快速摆脱这种状态,想到DOTA大9神 ...