• 如何在MongoDB上实现转账事务

    4.0 版本之前,MongoDB 是不支持事务的,只能由应用程序自行保证事务性。本文以银行转账为例,讲解如何在不支持事务的 MongoDB 上实现转账事务。

    转账场景

    客户账上余额由 accounts 表保存,表结构大致如下:

    1
    2
    
    {"_id": "A", "balance": 100} // 客户A账上有100元
    {"_id": "B", "balance": 100} // 客户B账上有100

    如果客户 A 发起一笔转账,转 10 元给 B ,那么余额表应该是这样的(假设没有其他操作):

    1
    2
    
    {"_id": "A", "balance": 90} // 客户A账上有90元
    {"_id": "B", "balance": 110} // 客户B账上有110

    由于转账需要同时修改两条账户记录,为保证数据一致性,我们必须保证:它们要么全都修改成功,要么全都保持初始原因,不能有中间状态。

    这就是转账操作的事务性要求,那么我们应该如何实现这一点呢?

    阅读全文
  • Blob对象应用实战

    背景

    Blob 对象是 二进制大型对象binary large object )的简称,顾名思义用来表示二进制数据内容。Blob 对象数据可以按文本或二进制格式进行读取,而且是不可变的。

    数据可以来源于文件,因此 Blob 可以用来读写文件,比如读写一个图片文件的内容。操作文件通常采用 File 对象,File 继承了 Blob 的数据读写功能,并在此基础上扩展实现文件系统相关功能。

    本文先讲解 Blob 对象相关接口,再讲解一些典型应用场景,最终彻底掌握 Blob 对象用法。

    阅读全文
  • IEEE-754浮点数那些坑:0.1加0.2不等于0.3!

    浮点数是计算机程序中最基本的数据类型,几乎所有编程语言都有浮点类型。但你或许不知道,浮点数可能有精度不足的问题,使用不当会酿成大祸。以 JS 为例,我们来看一个例子:

    1
    
    0.1 + 0.2 === 0.3 // false
    

    0.1 加上 0.2 居然不等于 0.3 ,那结果等于多少呢?

    1
    
    0.1 + 0.2 // 0.30000000000000004
    

    结果等于一个非常接近 0.3 的值,但不等于 0.3 !真是令人瞠目结舌!这是为什么呢?

    想要回答这个问题,我们得知道浮点数在计算机内部是怎么表示的。IEEE 754 是目前使用最广泛的浮点数表示和运算标准,从中即可找到问题的答案。不过想要学习它之前,我们得先掌握 科学记数法scientific notation )。

    阅读全文
  • 面向错误编程

    背景

    公司有一个应急系统,管理各种类型的应急策略,前端代码质量一言难尽。最近有新需求,领导要求梳理主机异常应急策略,为此我们给系统添加一种新的策略类型——主机异常应急策略。

    后端加上新类型后,您猜咋滴?前端好几个页面白屏了!只要数据里有新类型的策略就会!

    我看了看代码,您猜咋滴?问题出在策略类型标签上:类型字段后端为英文常量,前端将其展示成一个中文标签。由于类型有好几种,前端用一个字典来映射渲染函数,代码大致如下:

    1
    2
    3
    4
    5
    6
    7
    
    const strategyTypes = {
      Link: () => <Tag color="magenta">链接</Tag>,
      CheckList: () => <Tag color="orange">确认表</Tag>,
      Card: () => <Tag color="green">应急卡片</Tag>,
      Routine: () => <Tag color="cyan">常规应急操作</Tag>,
      Host: () => <Tag color="red">主机异常策略</Tag>,
    };
    
    阅读全文
  • 用Go语言模板引擎提取数据

    最近在开发一个通用消息通知工具,可以从 API 、数据库等数据源获取数据,然后根据数据渲染消息模板,然后通过企微、邮件、短信、电话语音等渠道推送消息。整个工作的设计思想,就是想提供一种低代码、配置化的消息通知解决方案。

    简言之,工具对日常消息通知开发场景进行抽象建模,让所有要素都支持配置:

    • 数据源
    • 消息模板
    • 通知渠道
    • 通知对象
    • 发送策略(手动触发或定时任务)

    那在开发的过程中,就不可避免要面对数据提取问题。比如,有个系统提需求说他们的变更单需要每天催一次,列表通过 API 给我,结构如下:

    1
    2
    3
    4
    5
    6
    7
    
    {
        "success": true,
        "data": [
          {"name": "变更①"},
          {"name": "变更②"}
        ]
    }
    
    阅读全文
  • 写于辛丑腊月廿九除夕日

    上周末收到公众号平台提醒,说小菜获得定制红包封面的机会。

    时间飞逝,又一年除夕佳节到了,在这先给各位老铁拜个年。

    还记得去年我特地看了能否自己定制红包封面,但没资格;所以收到通知时竟有一点小激动。

    微信应该是想鼓励原创,原来这一年小菜学编程上发表了 95 篇原创文章!我一直比较随意,有空就写没空就停,写写停停,但只要坚持还算有些收获。

    阅读全文
  • 谈谈我对Promise和异步函数的理解

    后端同学组织了技术分享,交流《Unix环境高级编程》读书心得,前端同学怎能落下?

    实际上,前端圈的分享会稍早前就开始组织了,只不过我没空将其中的点滴一一记录。

    作为项目的技术负责人,前端本不是我的主业。目前,前端团队无论从代码质量还是技术水平,都不太令人满意。我每周合并代码时,有时会瞟一眼,有些同学的代码真的堪忧。

    目前,前端团队都是初级工程师,功底较差,做出来的东西只是能用而已。他们既不会总结经验,形成最佳实践;做事又随便,总是机械地应付任务。我苦口婆心地劝他们要多看看书,思考代码要怎么写更好,但收效甚微。

    既然规劝没用,我就强制他们学习!我定的第一个课题是 TypeScript ,因为他们的代码质量很差,希望引入 TypeScript 后提升代码健壮性。前后端分享频率都是每周一次,但我有点忙不过来,后续改成双周一次。

    组织过好几次 TypeScript 学习后,有同学提议分享自己感兴趣的研究课题,我没反对。最近李同学在研究 Promise ,因此 Promise 便成了本周的分享主题。

    我是后端出身,虽然前端项目也是我在主导,但知识盲区还有很多。Promise 之前就一直没用对,真是贻笑大方。正好趁着这次机会,好好梳理下 Promise 的来龙去脉,故有此篇。

    阅读全文
  • 想不到写个cat命令都有这么多门道!

    《Unix环境高级编程》第一次读书分享会由廖同学主持,主要讲解 文件操作Unix/Linux 提供了这几个系统调用来操作文件:

    • open ,操作前先打开文件,获得一个 文件描述符file descriptor );
    • read ,从文件指定位置读取数据(传打开文件的描述符);
    • write ,将数据写到文件指定位置(传文件描述符);
    • lseek ,更新文件当前偏移量,偏移量决定 readwrite 读写位置;
    • close ,操作完毕后关闭文件,回收系统资源,并释放文件描述符;

    Unix/Linux 文件操作很简单,无非是打开、关闭、读写和指针移动( lseek ),对吧?尽管如此,简单的东西还是有很多需要考究的地方。

    为了提高学习效果,增强每位同学的参与感,我特地安排了课前作业。既然是学习文件操作,那就模仿着开发一个 cat 命令呗。

    cat 是一个非常简单的 Unix/Linux 命令,用于读取文件数据,并输出到标准输出。但就这么简单的一个作业,初学者还是很难写好。

    那么,实现 cat 命令背后都有哪些门道呢?简单的表象下,又暗藏哪些玄机呢?

    阅读全文
  • 带着新人刷《Unix环境高级编程》

    背景

    团队内来了不少年轻人,水平参差不齐,有些干了好几个年头还不知道什么是 进程间通信IPC )。

    当时在讨论一个后台服务的设计,它内部由若干协程组成,协程间需要传递一些数据,他想用 Redis 来做队列……我表示不解,在同一个程序内的通信,为什么要通过一个外部的 Redis 来进行呢?

    我很好奇,问他:你没学过 进程间通信IPC )吗?同一台主机下的进程进行通信,当然是首选操作系统提供的进程间通信机制,除非应用进程可能跨机器协作。但他一脸懵逼,表示没听过进程间通信……

    我当时有点震惊,一个干了好几年的后端,居然没听过进程间通信!这不是校招必考题吗?

    想当年没读《Unix环境高级编程》都不好意思去面试,而进程间通信就是其中一个主题。但他们可能起点较低,没认真学好这些基础课,也没经历过大厂面试的洗礼,因而功底比较薄弱。

    阅读全文
  • 给团队内的年轻人灌了一大碗鸡汤

    团队来了不少年轻人,水平却参差不齐,有些干了好几个年头还不知道什么是 进程间通信IPC )。

    最近突发奇想,准备搞一搞技术分享,带他们阅读一些经典的技术书。《Unix环境高级编程》是后端必读书目,我问了一圈竟无一人读过,因而被我选中。学习模式大致是这样的:大家轮流学习某个知识点,然后讲给其他人听,每周一次。

    第一次我原本准备亲自讲,给他们吹吹水,灌灌鸡汤。无奈这周身体抱恙,有点小感冒讲话不方便,遂写成文字分享给他们,乃有此篇。

    技术视野

    有本叫《性能之巅》的技术书很出名,作者在前言中引用美国国防部长拉姆斯菲尔德说的一句话,很有意思。他说世界上的事物可以分为三种:

    • A 已知的已知 ,比如我会 Go 语言;
    • B 已知的未知 ,比如我知道有一门语言 Rust 最近很火,但我不会;
    • C 未知的未知 ,……
    阅读全文