Skip to content

Latest commit

 

History

History
264 lines (162 loc) · 20 KB

202009.md

File metadata and controls

264 lines (162 loc) · 20 KB

“系统架构部”周刊2020年09期

0. 目录

读完本期周刊,大概需要花费您15分钟的宝贵时间,不过超值哦。

  1. 发布:Java日志脱敏库 logsafer
  2. 发布:跨机房数据库同步方案
  3. 读书:时间的形状,人类一思考,上帝就吓尿
  4. 言论:思考 —— 不看代码的思考,是最好的调试途径
  5. 代码:飞奔的定时任务
  6. 理论:编程与认知负荷
  7. 工具:vscode画图插件
  8. 哲学: 奥卡姆剃刀
  9. 哦噢:最可怕的打字错误
  10. 回顾: 写代码TabNine让你飞

周刊每周五准时发布,欢迎您提交Issue或者联系主编黄老邪(wx: bingoohuang),向本周刊投递有值得分享的内容哦,简短的一张图一段文亦可。

1. 发布:Java日志脱敏库 logsafer

欢迎大家使用,有问题请咨询系统架构部。

image

2. 发布:跨机房数据库同步方案

欢迎大家使用,有问题请咨询系统架构部。

image

image

3. 读书:时间的形状,人类一思考,上帝就吓尿

最近看了一本科普书,叫做《时间的形状》,写得很上口,我几乎是几天之内就读完了。(相比之下,另外一本老外写的《物理世界奇遇记》,就很不对我的胃口,觉得就写得没劲,读了几段就扔一边去了)

image

书的序言就吸引了我:

相对论之后,上帝改口了:“人类一思考,上帝就吓尿”。

思维实验 物体的下落速度

注:思维实验——在大脑中运行的实验

伽利略:“亲爱的亚里士多德先生,您不是说重的东西比轻的东西下落得更快吗?那么如果我们把一个铁块和一个木块用绳子拴在一起,从高处扔下来会发生什么?按照您的说法,较轻的木块下落得慢,因此它会拖累铁块的下落,所以它们会比单扔一个铁块下落得慢一点,是不是这样?” 亚里士多德:“没错,逻辑正确。” 伽利略:“但是,铁块和木块拴在一起以后,总重量却要比一个铁块更加重了啊,那么岂不是它们又应该比单个铁块下落得更快?” 亚里士多德:“呃……” 伽利略:“这个实验不用实际去做了吧,单单就在我们脑子里面做一下就可以发现您的理论是自相矛盾的。” 亚里士多德:“你让我想想,你让我想想……”

思维实验 狭义相对论之光速

光速与光源的运动无关,对于任何参考系来说,光在真空中的传播速度恒为c。 假设我现在一个人在黑漆漆的宇宙中飞行,虽然我飞得跟光一样快,但是因为没有任何参照物,我感觉不到自己的速度,就我自己的感觉而言和静止是一样的。这时候如果我身边有一束光,或者一个电磁波,我将看到什么呢?一束和我保持静止的光吗?一个静止的电磁波吗?也就是看到一个虽然在振荡的电磁场 ,但是它却不会交替感应下去吗?哦,不,这显然违背了麦克斯韦的方程组,波的速度和波源的运动速度无关,虽然我在以光速飞行,不论是我自己用发生装置发生一个电磁波,还是我飞过一个电磁波发生装置,我看到的电磁波都应该是相同的,因为介质没有变。我将看到一个振荡中的电场能够产生振荡的磁场,而一个振荡中的磁场又能够产生振荡的电场,这个交替反应绝不会停下来。再想象一下报数的情况,如果我和这队报数的人都在一节火车车厢中,火车高速行驶,但是我并不能感觉到火车是静止的还是运动着的,我会看到报数人的反应速度提高了吗?这也显然很荒谬,火车跑得再快也应该跟报数人的反应速度无关,我应该仍然看到它们以同样的反应速度传递着“一、二、三……”才对啊。 这么说来,光速应该相对于任何参照系来说,都是恒定不变的。哦,我这个想法实在有点疯狂。

广义相对论

时空弯曲 image

从黑洞到虫洞

image

4. 言论:思考 —— 不看代码的思考,是最好的调试途径

来自 Go语言之父:拿过奥运银牌,发明过航天望远镜,想用Go语言解放程序员!

在贝尔实验室时,Ken 教会了我一个极其重要的习惯:纠错前先思考。是因为和Ken一起做编程时,每当程序出错,我都会本能的一头扎进问题,检查报错跟踪信息,或者是添加调试打印语句,启动调试器等等。但Ken完全相反,他就静静地站在那思考,不理会也不检查出问题的代码。但奇怪的是,他却总能比我先找到问题出在什么地方。

这让Rob认识到这种编程思考模式非常的重要,也明白了思考 —— 不看代码的思考,是最好的调试途径,因为它能让我们开发出更好的软件。

大神 Ken

肯尼斯·蓝·汤普逊(英语:Kenneth Lane Thompson,1943年2月4日-)小名肯·汤普逊(英语:Ken Thompson),美国计算机科学学者和工程师。黑客文化圈子通常称他为“ken”[1]。在贝尔实验室工作期间,汤普逊设计和实现了Unix操作系统。他创造了B语言——C语言的前身,而且他是Plan 9操作系统的创造者和开发者之一。2006年,汤普逊进入Google公司工作,与他人共同设计了Go语言。他与丹尼斯·里奇同为1983年图灵奖得主。

此外,肯·汤普逊还参与过正则表达式和UTF-8编码的设计,改进了文本编辑器QED,创造了ed编辑器。他曾制造过专门用于下国际象棋的电脑“Belle”,并创建了残局数据库。

大神 Rob

罗勃特·派克(Robert C. Pike,1956年-),昵称为罗勃·派克(Rob Pike),来自加拿大的程序员,曾经加入贝尔实验室,为 UNIX小组的成员。曾经参与过贝尔实验室九号计划、Inferno,与编程语言 Limbo的开发。

他与肯·汤普逊共同开发了UTF-8。

目前为 google的工程师,参与编程语言 Go与Sawzall的研发工作。

他是能参加奥运还能设计望远镜的程序员。他参加了1980年奥运会射箭项目,还摘取了银牌。他是一位业余天文学家,并且发明了珈玛射线射电望远镜。

到现在2020年,Rob已经64岁啦,强调务实的他并没有金盆洗手,依然坚守在编程的岗位上,想为大家带来更好的编程技术!

何以 Go

2007年9月的时候,Rob一次偶然听到了一个演讲,演讲中提到的一些特性比较精妙,但是很难理解的点,像右值引用;其它的很有C++的特色,例如variadic模板;还有一些只是一些相当疯狂的,一如用户定义文字。

这时候,Rob突然问了自己一个问题:C++委员会真的认为C++的特性还不够多?有没有什么办法可以简化这门语言?

Go 开源十周年,十年重现性挑战

Go于2009年11月正式宣布推出。2012年3月28日,Go版本1.0宣布。Go 1.0如此重要的原因在于,它带来了一个承诺,即用户的程序在不确定的将来无需任何修改便可以继续进行编译和运行。

近期,有人对科学结果的可重现性进行了讨论,并得出了一些让人沮丧的结论。一项研究表明:这种可重现性只有62%。

在某些领域,情况可能更糟。任何依赖于计算的结果都面临着其编程环境不断变化的巨大风险:十年前编写的程序如果没有更改,今天构建成功的机会几乎微乎其微,更不用说运行或正确运行了。

这种担忧并不普遍,但正在增长。一个标志就是十年重现性挑战的创建,该挑战要求研究人员重新运行他们的旧代码(十年或以上,按计算标准非常旧的代码),并查看它是否仍然有效。

您还能找到你的旧代码吗? 这本身就是一个挑战。

5. 代码:飞奔的定时任务

曾经突然看到一段代码,看完就是那种感觉,闭上眼睛,眼前就一行行文字在飞奔,很Happy地在飞奔。

@Override public void run(int periodSeconds) {
    log.info("->->->->->飞奔的定时任务->->->->->飞奔的定时任务->->->->->飞奔的定时任务->->->->->飞奔的定时任务->->->->->");

    val now = DateTime.now();
    val targetTime = now.minusSeconds(periodSeconds);
    if (now.getHourOfDay() == targetTime.getHourOfDay()) {
        return; // 每小时执行
    }
    log.info("->->->->->钻研的定时任务->->->->->钻研的定时任务->->->->->钻研的定时任务->->->->->钻研的定时任务->->->->->");

    val memberCards = memberCardLatestActivateDayDao.queryUnactiveMemberCardsWithLastedActivateDay();
    for (val memberCard : memberCards) {
        tryActivateMemberCard(memberCard);
    }
}

写这个代码的不一定是高级程序员,但我想一定是一位快乐的码农。这个有点让我想起"Go语言趣味教材:并发不是并行"中囊地鼠gopher很Happy地运书的一张图片

image

囊地鼠运书,运得很快乐啊。也感觉像一枚枚成功飞向太空的小火箭(猎鹰重型首射的有效载荷是代号为Starman的红色特斯拉跑车Tesla Roadster),也飞得很Happy。

image

GIT看一下这段代码的提交记录,还是热热乎乎(昨天提交)的代码,提交注释是test

image

于是我就问原始作者,

问:小雨,你打算什么时候去掉它? 答:我不准备去掉它,留着很好啊。 问:四段重复的话,中间大量的箭头字符,留着有什么意义? 答:打日志的时候会看得很清楚啊。 问:万一大家也都跟风,也都这么的打印,那你还能从日志中看定时任务看得很清楚呢? 答:……

也许我担忧过头了,只要诸多打日志的代码中,有且仅有这么一处这么打印的话,问题倒也不大,而且还感觉有『某种新意』。但是,经常是『好事不出门,坏事传千里』,这毕竟不是一个好的打印日志的方式,开启了这么一个方便之门后,后面其他人活着新来的同学也都这么打印,就会导致满屏幕火箭飞了,到底是飞的定时任务的小火箭,还是飞的其它业务的火箭,就不是那么容易区分了。而且,大概率还会嘟嘟说,组长就是这么写代码的,那就不好了。

调试用的日志

明显“飞奔的定时任务”属于调试性的日志,可以用debug级别。另外,靠肉眼去看日志,只适合在开发环境,在生产环境大量访问情况下,这种打印日志的方式,只会造成日志大小的无意义的增长。如果不删除,至少建议改动如下:

@Override public void run(int periodSeconds) {
    log.debug("定时任务检查开始");

    val now = DateTime.now();
    val targetTime = now.minusSeconds(periodSeconds);
    if (now.getHourOfDay() == targetTime.getHourOfDay()) {
        return; // 每小时执行
    }
    log.debug("定时任务执行开始");

    val memberCards = memberCardLatestActivateDayDao.queryUnactiveMemberCardsWithLastedActivateDay();
    for (val memberCard : memberCards) {
        tryActivateMemberCard(memberCard);
    }
}

改了:

  1. 级别从info改成了debug;
  2. 去除了日志中的噪音,只打印日志的初心。

6. 理论:编程与认知负荷

软件工程领域的一句名言:

程序必须为人们所阅读而编写,而且只能偶尔由机器来执行。 - Abelson & Sussman,《计算机程序的构造和解释》,第一版序言

从表面上看,所有开发人员都要学会遵循一些简单的经验法则,例如选择好的变量和函数名、正确地格式化代码以及编写相关的非冗余注释。 但是,通过考虑我们在阅读时如何处理信息,以及我们的大脑如何运作,对提高可读性和可维护性的追求可以在更深层次上得到解释。 从这种编程方式得出的结论可能与我们编写代码时的一些传统观点不一致。

什么是认知负荷

认知负荷是认知心理学中的一个概念,最初由约翰 · 斯韦勒提出,通常是与学习有关的讨论。 它是对工作记忆所花费的努力程度的一种测量。 工作记忆,宽泛地说,是认知系统的一部分,负责处理与个人当前所做事情相关的信息(与保留结构化知识的长期记忆形成对比)。 我们知道工作记忆的容量是相当有限的(试着在听到一个电话号码之后记住它) ,并且容易超负荷。

image

王珏老师用“冰山上的北极熊”一图来表达认知负荷理论中的三种负荷。

  1. 内在认知负荷是学习任务本身的难点。 当学习如何制作蛋糕时,比如说,需要努力称重并正确地混合所有的配料,适量地搅拌面糊,预热烤箱,正确地计算烘烤时间等等。
  2. 相关的认知负荷是用于形成新的低层次表征的子部分的任务。 食谱的一部分可能会用来详细解释如何制作糖衣。 然而,随着时间的推移,一个经验丰富的面包师将学会如何制作糖衣,因此整个蛋糕制作任务的一部分将被简单地“制作糖衣”。
  3. 外在的认知负荷是额外的努力施加的方式,学习的发生。 在蛋糕的例子中,想象一下,如果所有的单位都以磅和盎司表示,但是你习惯于以克和公斤表示。 外部负载将花费时间转换之间的帝制和公制在每一步的方式

在这三种负荷中,对“相关认知负荷”的理解,恐怕是教学设计中最为关键的,它是关于在信息之间建立关联、信息打包、信息处理模式化和自动化的。

编程与认知负荷

编程和相关的任务(比如跟踪 bug)非常依赖于工作内存。 作为程序员,我们熟悉“把程序加载到大脑中”的感觉,也就是在大脑中保存算法或数据模型的子集,这样你就可以开始推理了。 当我们被要求查看一段新的、不熟悉的代码时(比如说,如果我们刚刚开始在一家新公司工作) ,这种情况就会发生。 但是这也发生在我们维护多年的软件上。 任何非微不足道的软件系统都是如此复杂,以至于没有一个开发人员能够一直理解或记住整个系统是如何工作的,因此我们必须重新熟悉代码库中某个特定部分的内部工作,然后才能开始进行更改或修复 bug。 维护软件本质上是一个不断学习的过程,因此认知负荷的理论基础可以应用。

原文编程与认知负荷提供了一个编程的实际例子来讲解了不一样的编程方式,带来的不一样的认知负荷,建议前往继续阅读。(原文英文,建议对英文不感冒的同学,直接开启浏览器插件"彩云小译"-火力全开(周刊第1期就有介绍哦),可以有效降低阅读文章的外在认知负荷)

7. 工具:vscode画图插件

神器vscode,不仅可以用做文本编辑器 ,可以用来做IDE,装个vscode画图插件,还能用来画图,或者微信读书一下亦可。安利一下。还在用sublime text的童鞋们可以换了,下次就不用问我列编辑这些基本的用法怎么玩了。

image

8. 哲学:奥卡姆剃刀

哲学剃刀(Philosophical razor)指的是能指导人们排除(剃掉)一个现象中不太可能的解释或避免不必要行动的一个原则或经验法则。有名的剃刀如下:

  1. 奥卡姆剃刀:更简单的解释更可能是正确的。引申为某个命题成立,所需要的假设越少越好。

    学者詹姆士·摩尔说:“图灵测试的场景符合奥卡姆剃刀,无法区别的对象应视作相同,仅当观测到有差异时再进行区分。我们把图灵测试看作一种让测试者给被测试对象打标签的认证过程:‘如果它看起来像鸭子,走起来像鸭子,叫起来也像鸭子,我们就给它打上鸭子的标签。’”

  2. 汉隆剃刀:可以归咎于愚蠢的事情,不要归咎于恶意。
  3. 希钦斯剃刀:凡是无证据的断言,也可以无证据地驳回。
  4. 休谟剃刀:从一样东西是什么,无法推导出它应该是什么,即无法从事实推导出价值判断。
  5. 牛顿剃刀:无法通过实验或观察解决的问题,不值得争论。
  6. 萨根标准:非同寻常的主张,需要非同寻常的证据。
  7. 波普原则:一个理论被认为是正确的,前提必须是有可能证明它是错误的,即必须是可证伪的。

更多,见wiki 哲学剃刀哲思碎片(一)--剃刀大全图解

奥卡姆剃刀

这个原理称为“如无必要,勿增实体”,即“简单有效原理”。

举一个例子:一阵风把门吹开。正常逻辑:空气流动,门被空气停开。而宗教逻辑:上帝让空气流动,空气流动,门被空气顶开。

明显,宗教逻辑比正常逻辑复杂,根据奥卡姆剃刀,宗教逻辑的解释力一般来讲就比正常逻辑弱(che)得多。

奥卡姆剃刀是原则,是方法,是工具,是一种思考问题的方式,是一种审视设计的角度,但它绝不是真理。 它的目的不在于求至真,不在于求至简,而在于求合情合理的真和合情合理的简。凡事切记用力过猛。 如果在人生的各方面,尝试用“剃刀”修一下,你的生活会更轻松,你的精力会更聚焦,你的目标会更明确,你成功的机会也会更大一点。

9. 哦噢:最可怕的打字错误

不小心多了一个空格,真会要了老命,系统就要被删了。点我看详情

image

10. 回顾: 写代码TabNine让你飞

2020年第07期周刊

Tabnine 使用深度学习来帮助您更快地编写代码

image

黄老邪一直用着它,只能借一句流行语来形容它:真香。

image