> 2021年05月18日信息消化 ### 每天学点Golang #### Golang 单元测试详尽指引 https://mp.weixin.qq.com/s/eAptnygPQcQ5Ex8-6l0byA 基本共识: - 单元测试是比较**底层**的,关注代码的**局部**而不是整体。 - 单元测试是**开发人员**在写代码时候写的。 - 单元测试需要比其他测试运行得**快**。 ##### 意义 - **提高代码质量** - **保证重构正确性** - **单元测试是最好的文档** ##### 单元测试用例编写的原则 - **快**。单元测试是回归测试,可以在开发过程的任何时候运行,因此运行速度必须快 - **一致性**。代码没有改变的情况下,每次运行得结果应该保持确定且一致 - **原子性**。结果只有两种情况:Pass / Fail - **用例独立**。执行顺序不影响;用例间没有状态共享或者依赖关系;用例没有副作用(执行前后环境状态一致) - **单一职责**。一个用例只负责一个场景 - **隔离**。功能可能依赖于数据库、web 访问、环境变量、系统时间等;一个单元可能依赖于另一部分代码,用例应该解除这些依赖 - **可读性**。用例的名称、变量名等应该具有可读性,直接表现出该测试的目标 - **自动化**。单元测试需要全自动执行。测试程序不应该有用户输入;测试结果应该能直接被电脑获取,不应该由人来判断。 规约原则 在实际编写代码过程中,不同的团队会有不同团队的风格,只要团队内部保持有一定的规约即可,比如: - 单元测试文件名必须以 xxx_test.go 命名 - 方法必须是 TestXxx 开头,建议风格保持一致(驼峰或者下划线) - 方法参数必须 t *testing.T - 测试文件和被测试文件必须在一个包中 - 优先编写核心组件和逻辑模块的测试用例 - 发现 Bug 时一定先编写测试用例进行 Debug - 关键 util 工具类要编写测试用例,这些 util 工具适用的很频繁,所以这个原则也叫做热点原则,和第 1 点相呼应。 - 测试用户应该独立,一个文件对应一个,而且不同的测试用例之间不要互相依赖。 ##### **定义一个接口** 我们先定义一个打算 mock 的接口 Repository。 Repository 是领域驱动设计中战术设计的一个元素,用来存储领域对象,一般将对象持久化在数据库中,比如 Aerospike,Redis 或 Etcd 等。对于领域层来说,只知道对象在 Repository 中维护,并不 care 对象到底在哪持久化,这是基础设施层的职责。 ```go type Repository interface { Create(key string, value []byte) error Retrieve(key string) ([]byte, error) Update(key string, value []byte) error Delete(key string) error } ``` [Test-driven development using mocking and stubbing](https://circleci.com/blog/how-to-test-software-part-i-mocking-stubbing-and-contract-testing/) ![Testing_pyramid.jpg](https://raw.githubusercontent.com/Phalacrocorax/memo-image-host/master/PicGo/Testing_pyramid.jpg) ### 其他值得阅读 #### 软件发布管理最佳实践 原文:[4 Software Release Management Best Practices](https://launchdarkly.com/blog/4-software-release-management-best-practices) ##### 5 phases of a software release 1. Define specific requirements for the release 2. Specify your acceptance criteria - New feature displays correctly on iOS - New feature displays correctly on Android OS 3. Test your software in production 4. Iterate and refine your product 5. Release your product to end-users #### 人工意识是不可能的 原文:[Artificial Consciousness Is Impossible](https://towardsdatascience.com/artificial-consciousness-is-impossible-c1b2ab0bdc46) 这篇文章试图解释为什么意识机器的小说是不可能的。硬件和软件设计的行为本身就是一种作为设计者延伸的动力的传递,而不是有意识的意志的注入。文章的后半部分专门讨论了反驳意见。最后,列出了标题论文的一些含义。 > This article is an attempt to explain why the cherished fiction of conscious machines is an impossibility. The very act of hardware and software design is a transmission of impetus as an extension of the designers and not an infusion of conscious will. The latter half of the article is dedicated to addressing counterarguments. Lastly, some implications of the title thesis are listed. Intelligence[1]: > “…the ability to apply knowledge to manipulate one’s environment” Consciousness[2]: > “When I am in a conscious mental state, there is something it is like for me to be in that state from the subjective or first-person point of view.” ##### Volition Rooms - 机器只能看起来拥有内在的推动力 机器被编程的事实注定了它们是附属品,是程序员意志的延伸。一台机器的设计和它的编程限制和定义了它。不存在 "没有设计的设计 "或 "没有编程的编程 "这样的东西。一台机器的运作是由它的程序员和设计者从外部决定的,即使有一些混淆视听的说法(有意或无意),如 "一个程序/机器进化了,"(谁设计的进化算法?)"没有人知道黑盒子里的结果程序是怎么来的,"(谁编的程序产生的结果代码? ) "神经网没有程序,"(谁写的神经网的算法?"机器学习和适应,"(它没有 "学习...... "谁决定它如何适应?)和 "有自我修改的代码"(什么决定了这种所谓的 "自我修改 "的行为,因为它不是 "自我"。无法隐藏或逃避最终产生行为的东西--程序员的编程。 > Volition Rooms — Machines can only appear to possess intrinsic impetus > > The fact that machines are programmed dooms them as appendages, extensions of the will of their programmers. A machine’s design and its programming constrain and define it. There’s no such thing as a “design without a design” or “programming without programming.” A machine’s operations have been externally determined by its programmers and designers, even if there are obfuscating claims (intentional or otherwise) such as “a program/machine evolved,” (Who designed the evolutionary algorithm?) “no one knows how the resulting program in the black box came about,” (Who programmed the program which produced the resultant code?) “The neural net doesn’t have a program,” (Who wrote the neural net’s algorithm?) “The machine learned and adapted,” (It doesn’t “learn…” Who determined how it would adapt?) and “There’s self-modifying code” (What determines the behavior of this so-called “self-modification,” because it isn’t “self.”) There’s no hiding or escaping from what ultimately produces the behaviors- The programmers’ programming. ##### Consciousness Rooms — Conclusion, machines can only appear to be conscious 看起来有意识的人工智能是一个意识室,是一种有不同程度成功的模仿。正如我所表明的,它们既没有能力理解,也没有能力学习。不仅如此,它们也无法拥有意志力。由于编程的外在性质,人工意识是不可能的,它被语法所束缚,没有意义。 > Artificial intelligence that appears to be conscious is a Consciousness Room, an imitation with varying degrees of success. As I have shown, they are neither capable of understanding nor learning. Not only that, they are incapable of possessing volition. Artificial consciousness is impossible due to the extrinsic nature of programming which is bound to syntax and devoid of meaning. ##### Responses to counterarguments 对反驳意见的回应 ###### 功能主义的反对意见(我的回答是:他们没有说明决定权不足的问题。 Functionalist objections (My response: They fail to account for underdetermination) 许多反对意见是以一种或另一种形式的功能主义提出的。也就是说,它们都是沿着这样的一条或多条路线进行的。 - 如果我们知道一个神经元做什么,那么我们就知道大脑做什么。 - 如果我们能复制一个大脑或复制神经元的集合,那么我们就能产生人工意识。 - 如果我们能复制大脑的功能,我们就能产生人工意识。 功能主义的论点在这里不起作用,因为要复制任何功能,必须有办法确保所有的功能和它们的依赖关系是可见和可测量的。不存在 "复制 "那些未确定的东西。功能主义的 "如果我们知道/如果我们能复制 "的假设是无效的。 正如SEP的以下段落所解释的那样(重点是我的),不确定意味着不可能对大脑进行这种详尽的建模 > Many objections come in one form of functionalism or another. That is, they all go something along with one or more of these lines: > · If we know what a neuron does, then we know what the brain does. > · If we can copy a brain or reproduce collections of neurons, then we can produce artificial consciousness > · If we can copy the functions of a brain, we can produce artificial consciousness > No functionalist arguments work here, because to duplicate any function there must be ways of ensuring all functions and their dependencies are visible and measurable. There is no “copying” something that’s underdetermined. The functionalist presumptions of “if we know/if we can copy” are invalid. > Underdetermination entails no such exhaustive modeling of the brain is possible, as explained by the following passage from SEP (emphasis mine) 简而言之,当我们首先不能完全了解这个X时,我们就不能保证我们能设计出 "像X "的东西。由于不确定,不可能保证有一个完整的模型。功能主义的论点之所以失败,是因为研究结果中的相关关系并不意味着因果关系,而这些相关关系必须是100%可以发现的,才能有一个详尽的模型。即使在研究像这样的实际实验之前,功能主义的立场就已经受到了多种理论上的打击。 > In short, we have no assurances that we could engineer anything “like X” when we can’t have total knowledge of this X in the first place. There could be no assurances of a complete model due to underdetermination. Functionalist arguments fail because correlations in findings do not imply causation, and those correlations must be 100% discoverable to have an exhaustive model. There are multiple theoretical strikes against a functionalist position even before looking at actual experiments such as this one: "......一些神经元组可以引起不同动物的多种行为,有时甚至是在一只动物身上。 在不同的动物中刺激单一的神经元组,偶尔会导致不同的行为。兹拉蒂奇说,这种差异可能是由于多种原因造成的:"可能是以前的经验;可能是发育差异;可能是动物的某种个性;动物在神经元激活时发现自己处于不同的状态"。 研究小组发现,在一只动物身上刺激相同的神经元,偶尔会导致不同的行为"。 在上面引用的段落中,注意所有短语 "可能是 "和 "可能是 "的实例。它们表明有一些不确定的因素在起作用。当从随机的实验结果中存在多种可能的解释时,不可能进行详尽的建模。 > “…some neuron groups could elicit multiple behaviors across animals or sometimes even in a single animal. > Stimulating a single group of neurons in different animals occasionally resulted in different behaviors. That difference may be due to a number of things, Zlatic says: “It could be previous experience; it could be developmental differences; it could be somehow the personality of animals; different states that the animals find themselves in at the time of neuron activation.” > Stimulating the same neurons in one animal would occasionally result in different behaviors, the team found.” > In the above-quoted passage, note all instances of the phrases “may be” and “could be.” They are indications of underdetermined factors at work. No exhaustive modeling is possible when there are multiple possible explanations from random experimental results. ##### Behaviorist objections 行为学家的反对意见 这些反驳一般都说,如果我们能重现有意识的行为,那么我们就产生了意识。例如,我完全不同意《科学美国人》的一篇文章,该文章声称存在检测机器中意识的测试[16]。 > These counterarguments generally say that if we can reproduce conscious behaviors, then we have produced consciousness. For instance, I completely disagree with [a Scientific American article](https://blogs.scientificamerican.com/observations/is-anyone-home-a-way-to-find-out-if-ai-has-become-self-aware/) claiming the existence of a test for detecting consciousness in machines[16]. 可观察到的行为并不意味着什么,正如最初的 "中文房 "的论点已经证明的那样。中文房只是看起来能理解中文。机器学习并不等同于实际的学习,这也证明了这一点。 > Observable behaviors don’t mean anything, as the original Chinese Room argument had already demonstrated. The Chinese Room only appears to understand Chinese. The fact that machine learning doesn’t equate to actual learning also attests to this. ##### Emergentism via machine complexity 通过机器复杂性的新兴主义 复杂性涌现论的反例包括手机处理器中的晶体管数量与果蝇大脑中的神经元数量。为什么智能手机不比果蝇更有意识?那拥有数百万倍晶体管的超级计算机呢?相比之下更复杂的太空发射系统呢?它们有意识吗?意识并不是从复杂性中产生的。 > Counterexamples to complexity emergentism include the number of transistors in a phone processor versus the number of neurons in the brain of a fruit fly. Why isn’t a smartphone more conscious than a fruit fly? What about supercomputers that have millions of times more transistors? How about space launch systems that are even more complex in comparison… are they conscious? Consciousness doesn’t arise out of complexity. ##### “We have DNA and DNA is programming code” DNA不是编程代码。遗传构成只影响而不决定行为。DNA的功能也不像机器代码。DNA测序携带的指令具有广泛的作用,如生长和繁殖,而机器代码的功能范围则相对有限。观察表明,每个基因对每个复杂性状的影响程度都不确切[17]。这表明它们的工作原理是不确定的,而相比之下,编程代码在功能上是确定的(如果不知道程序代码应该做什么,程序员就没有办法设计行为,无论是适应性的还是 "进化的"。见讨论 "意志室 "的部分),而且相比之下,它具有严重的区隔性(给我看一个大型程序,其中每一行代码都会影响所有的行为)。DNA-编程的平行关系是一个糟糕的比喻,经不起科学观察。 > DNA is not programming code. Genetic makeup only influences and does not determine behavior. DNA doesn’t function like machine code, either. DNA sequencing carries instructions for a wide range of roles such as growth and reproduction, while the functional scope of machine code is comparatively limited. Observations suggest that every gene affects every complex trait to a degree not precisely known[17]. This shows their workings to be underdetermined, while programming code is functionally determinate in contrast (There’s no way for programmers to engineer behaviors, whether adaptive or “evolutionary,” without knowing what the program code is supposed to do. See section discussing “Volition Rooms”) and heavily compartmentalized in comparison (show me a large program in which every individual line of code influences ALL behavior). The DNA-programming parallel is a bad analogy that doesn’t stand up to scientific observation. ```text --- 评论 如果我要求一个(功能确定的)人工智能,在获得所有人类知识、材料和过程的情况下,重新创造最初的生命 .... ...它从林恩-马古利斯离开的地方开始,加入所有新的见解和工具... ...然后从头开始,一个原子一个原子地建立原生动物、古细菌或真细菌,或者G*帮助我们,一些新的突变... 它将--根据你自己的逻辑--创造意识....aka生命...:)人工意识... 先天的分子以正确的(生物-化学)序列重新组合就等于生命。现在听起来不是很像编程吗? If I were to ask a (functionally determinate) A.I., with access to all human knowledge, materials and processes, to recreate the beginning life .... ...and it picks up where Lynn Margulis left off, adds all the new insights and tools… ...and from scratch starts to build, atom by atom, a protoctist, archae- or eubacteria, or G* help us, some new mutation... it would - according to your own logic - be creating consciousness….aka life... :) artificial consciousness... Innate molecules reassembled in the right (bio-chemical) sequence equals life. Now doesn't that sound a lot like programming? --- 作者回复 在 "生命再造 "的情况下,如果我们掌握了所有的信息和材料,就不一定需要用人工智能来做(例如,实验室技术人员在试管中制造东西,这是一个原始的例子)。人工智能只是另一种工具。 In a "life recreation" scenario, we wouldn't necessarily need to use an AI to do it if we're in possession of all the information and materials (e.g., a laboratory technician making something in a test tube, for a primitive example.) AI is just another tool. 一旦创造了起始条件,让多米诺骨牌/骰子掉落和滚动,这个过程将是一个自然的过程。几百万年后的结果将是一个先天的自然智能。 Once the starting conditions are created and the dominos/dice are left falling and rolling, the process would be a natural one. The result after a couple of million years would be an innate natural intelligence. 你所描述的是一个在起源上可能是人工的,但在进展上却是自然的过程。这类的另一个过程是把一个本地物种从一个地方移走,然后把这个物种移植到一个非本地的地方(或者在某些入侵物种的情况下,这个过程可能是也可能不是故意的。 You're describing a process that may have been artificial in origin but natural in progression. Another process in such a category would be removing a native species from one location and transplanting that species in a non-native one (or in the case of certain invasive species, the process may or may not have been intentional.) 就生物化学程序而言,我的答案不会改变,因为它是双向的。这仍然是对先天意识的操纵。一旦有人对你的一些基因进行重新编程,你就不会变成人工智能了。我知道我在这里并没有真正解决泛灵论的任何细节问题,但是用这种方案自下而上/自上而下地人工创造任何东西都有问题。 As far as bio-chemical programming is concerned, my answer isn't going to change because it works both ways. It's still a manipulation of innate consciousness. You're not going to turn into an AI once someone reprograms some of your genes. I know I'm not really addressing panprotopsychism in any kind of detail here, but there are issues with bottom up / top down manual creation of anything with that scheme. ``` ### 一点收获 - [v2ex 如何评价 TDD(测试驱动开发)?](https://v2ex.com/t/588568) - 框架 核心业务 并发处理的地方可以用 TDD - 工具类的测试非常好用, 测试业务代码或者是涉及到数据库, 那就直接用集成测试 - 感觉有几点好处 1. 先行测试用例,为了测试用例的覆盖度,会强迫开发者在开发前完全理解需求,在做程序设计时,设计会更加全面易扩展,修复 Bug 的时候同理。 2. 测试驱动开发,开发者会被迫将测试用例的维护和覆盖度优先级提到最高,使得测试用例一直保持完善。 3. 几乎不用文档,对于某一模块的需求,看一遍测试用例就基本了解使用方式和功能 - 缺点也很明显,需求一旦变动,高覆盖度的测试用例的修改成本非常高,所以面向 C 端用户的应用级别软件用 TDD,效率会很低 - [项目的前期架构是否要反复的揣摩一套体系?](https://www.v2ex.com/t/777750#reply5) > 换个角度去考虑问题,如何节省成本 > 规范是为了节省成本的,什么时候技术债成本高到要用规范来减少成本,就什么时候把规范推广开。 > > 减少开发人员调试的反馈周期,能大幅减少开发周期降低成本,那么这些规范里面有什么是可以降低开发反馈周期的,可以优先做,如果加上规范反而让本地调试成本更高,周期更高了,要重新评估是不是有简化方案,还是不适合在这个时候添加对应的规范。 > 重构也是为了节省成本,当技术债务过高,达到了 重构 + 新功能 > 在原有架构上写新功能的时候,就是一个很好的重构时间节点。 - gitlab commit 强制规范 - 通过 ELK 采集日志集中分析和查看 - 对新表上线必须模拟日增数据 - 对服务的监控和熔断,限流 - git push master 必须通过所有回归测试 - 所有服务必须有基本的 readme.md 介绍 - 所有的服务必须有版本发布管理 - 所有的部署必须通过 git 钩子自动化部署 - 模块的更新必须共同开发的同学一起 code view - 模块的调用必须通过 feign 或者 MQ 来完成代码的解耦