🙂一些我平时遇到的不理解的词条整理后放在这🙃

  • Thundering Herd (惊群)

    惊群效应即,有大量的进程/线程因为等待一个事件而被阻塞,当该事件发生时,所有的等待进程/线程被唤醒,但最终可能只有一个进程/线程能够获得处理该事件的资源,其他进程/线程会在竞争失败后重新被阻塞。
      惊群效应会导致内核重新调度大量的进程/线程,造成性能浪费,拉低系统性能。

  • Benford’s Law

    本福特定律说明在$b$进位制中,以数$n$起头的数出现的概率为$\log_b(n+1)-\log_b(n)$。本福特定律不但适用于个位数字,连多位的数也可用。例如在随机从十进制数中抽取的大量样本里,以$1$开头的数字根据我们的直觉来说应该占总数的$1/9$,但是实际其出现概率约为$30\%$。
    wiki 本福特定律

    该定律可以用来验证样本的真实性,分辨数据是否是人为制造。

  • X阶逻辑

    像一阶、二阶逻辑,其中的*阶一方面是表示量化的程度,另一方面是表示逻辑系统有多强的表达能力。
      首先是命题逻辑(也有人叫零阶逻辑),在它里面,一个字母代表一个命题,命题逻辑表达命题之间的关系,如“p&q”,“if p then q”等。
      一阶逻辑引入了两个量词,即任意和存在, universal quantifier()和existential quantifie(), 并且引入了一阶谓词,这使得一阶逻辑可以量化个体。
      但一阶逻辑的表达能力有限,它可以表达“∀中国人都喜欢喝茶”或“∃中国人喜欢喝茶”,但是无法表达“有80%的中国人喜欢喝茶”,因为这“80%的中国人”本身是一个个体的集合,或者可以看成是对谓词的量化,即“中国人有80%喜欢喝茶”(可能这个例子这么说有点语义逻辑问题),所以如果要这么表达就需要引入二阶逻辑。二阶逻辑可以量化谓词,表达能力更强。
      集合论上来说, 一阶量化个体, 二阶量化包含个体的集合, 三阶量化包含包含个体的集合的集合, 等等,以此类推。
    参考知乎问题 一阶逻辑和高阶逻辑的区别,能不能具象一点说明?

  • iterater与iteration作为名词时的区别

    iterate表示许多次iteration运行后的结果。所以在一个迭代函数中,每一个iteration就是一次循环,而iterate就是函数运行完后的结果。
    引自 StackExchange iterate and iteration as nouns

  • CAP定理(CAP Theorem)

      在理论计算机科学中,CAP定理,又被称作布鲁尔定理(Brewer’s theorem),它指出对于一个分布式计算系统来说,不可能同时满足以下三点:
      一致性(Consistency) :等同于所有节点访问同一份最新的数据副本;
      可用性(Availability):每次请求都能获取到非错的响应——但是不保证获取的数据为最新数据;
      分区容错性(Partition tolerance):以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择。
      根据定理,分布式系统只能满足三项中的两项而不可能满足全部三项。理解CAP理论的最简单方式是想象两个节点分处分区两侧。允许至少一个节点更新状态会导致数据不一致,即丧失了C性质。如果为了保证数据一致性,将分区一侧的节点设置为不可用,那么又丧失了A性质。除非两个节点可以互相通信,才能既保证C又保证A,这又会导致丧失P性质。
    wiki CAP定理

    《NoSQL精粹》一书中对于可用性的解释是:“如果客户可以同集群中的某个节点通信,那么该节点就必然能够处理读取及写入操作”。对于“分区容错性”的定义是:“如果发生通信故障,导致整个集群被分割成多个无法互相通信的分区时(这种情况也叫‘脑裂’,split brain),集群仍然可用”。
      集群必须要容忍”网络分区“状况,而这正是CAP定理的意义所在。CAP定理实际上是讲:当系统可能会遭遇”分区“状况时(比如分布式系统),我们需要在”一致性“与“可用性”之间进行权衡。这并不是个二选一的决定,通常来说,我们都会略微舍弃“一致性”,以获取某种程度的“可用性”。这样产生的系统,既不具备完美的“一致性”,也不具备完美的“可用性”,但是这两种不完美的特性结合起来却能够满足特定的需求。

  • 启发式算法(Heuristic Algorithm)

    启发式算法可以这样定义:一个基于直观或经验构造的算法,在可接受的花费(指计算时间和空间)下给出待解决组合优化问题每一个实例的一个可行解,该可行解与最优解的偏离程度一般不能被预计。百度百科
      启发式是基于有限的知识与认知从而得到相关问题的结论的分析行为,由此得到的解决方案有可能会偏离最佳方案。典型的启发法有试错法和排除法。– 摘自wiki
      启发式算法部分来自于自然的规律或是仿自然体,还有部分来自于人们积累的工作经验。
      启发式比盲目的寻求解决方法要有效,虽然不一定能得到最佳方法但很多时候都能得到“能用”的方法或者说近似最优解(具体怎么近似,需要针对具体问题),因此它在理论上也缺乏保障。

  • 帕累托法则(Pareto Principle)

    ”也被称为80/20法则关键少数法则, 指出,’约仅有20%的变因操纵着80%的局面‘。此一概念起源于意大利经济学家 帕累托 (Vilfredo Pareto) 在洛桑大学注意到了80/20的联系,于他的第一篇文章《政治经济学》中说明了该现象,例如:意大利约有80%的土地由20%的人口所有、80%的豌豆产量来自20%的植株等等。“ –摘自wiki
      在编程方面总被用来指出80%的应用程序性能改善源自20%的性能问题。

  • NFL定理(No Free Lunch Theorem)

    在机器学习领域,NFL定理告诉我们,如果不考虑所要解决的实际问题,那么任何算法的期望性能都是差不多的。但是你知道的,实际运用中我们会关注正在面对的问题并期望得到它的解决方案。
      周志华教授的《机器学习》一书中如是说:

      NFL定理最重要的寓意,是让我们清楚地认识到,脱离具体问题,空泛地谈论”什么学习算法更好“毫无意义,因为若考虑所有潜在的问题,则所有的算法一样好。要谈论算法的相对优劣,必须要针对具体的学习问题;在某些问题上表现好的学习算法,在另一问题上却可能不尽如人意,学习算法自身的归纳偏好与问题是否相配,往往会起到决定性作用。

  • 奥卡姆剃刀(Occam’s Razor)原则

    奥卡姆剃刀为简约之法则,它推崇简约,原文为“切勿浪费较多东西,去做‘用较少的东西,同样可以做好的事情’。”
      但是其意并不是说简单的就是正确的,它可以看作是种思维方式,一种解决问题的法则。在自然科学中,奥卡姆剃刀被作为启发法技巧来使用,“在平时也可以用来指导我们的工作,比如我们可以用A和B达到同样的效果,但B更简单,于是我们选择B”,这就算是该原则的运用。“然而,奥卡姆剃刀本身存在不同的诠释,使用奥卡姆剃刀原则并不平凡”,因为对于“更简单”这个条件的判断或理解,在很多时候是无法进行的。

  • 鸭子类型(duck typing)

    鸭子类型是动态语言所特有的概念。Wiki上的解释,有趣的类比”If it walks like a duck and it quacks like a duck, then it must be a duck.” 其意为,一个对象的到底是什么是由它的行为所决定的,我们并不关心它本质上是什么(继承自什么对象实现了什么接口),我们是通过它能干什么来判断它是什么🤔很有趣嘛。

  • 猴子补丁(monkey patching)

    起源:猴子补丁的这个叫法起源于Zope框架,大家在修正Zope的Bug的时候经常在程序后面追加更新部分,这些被称作是“杂牌军补丁(guerilla patch)”,后来guerilla就渐渐的写成了gorllia(猩猩),再后来就写了monkey(猴子),所以猴子补丁的叫法是这么莫名其妙的得来的。
      它是动态语言所特有的概念,在动态语言中,一切皆对象,例如你可以用一个对象去替换另一个对象的属性,那么这样的话你就可以非常灵活的去进行功能的追加或删改。
      关于实际例子,StackOverflow上有相关的问题:What is monkey patching?

  • 阻抗失谐(impedance mismatch)

    该词是数据库领域术语, 反用了微波电子学术语"阻抗匹配"(impedance match),用来比喻数据模型与实际编程语言不搭调的窘境。–摘自《NoSQL精粹(NoSQL Distilled)》
      这种”阻抗失谐”的现象(尤其是在关系型数据库中)表现为:关系模型和内存中的数据结构之间存在差异, 如编程语言在内存中构造的数据结构中有”嵌套”的表示, 但是在关系型数据库中却无法包含嵌套记录, 它的关系元组必须是简单的, 这就导致如果要把内存中数据结构的对象持久化到关系型数据库中就必须要将其转换成”关系”形式, 这样关系型数据库才能保存并表达, 这就发生了”阻抗失谐”: 需要在两种不同的表示形式之间转译.

  • 微服务结构 & 单体式应用

    最近看书时总是看到拿微服务结构单体式应用对比, 在此归纳总结一下.

    微服务

    微服务是以专注于单一责任与功能的小型功能模块为基础,利用模组化的方式组合出复杂的大型应用程序。
      其比较明显的特性有:1.独立性(有些地方也叫真空性),微服务模式中的每一个组成部分都是一个服务,各个服务彼此独立, 有完整的运行机制与对外接口; 2.服务是粒度最小的单位, 不可再分, 即一个微服务不能进一步划分为多个更小的服务; 3.服务能够快速重组成新的系统, 就像积木一样, 体现了模块化.

    单体式应用

    一个单体式应用里面有许多的逻辑、服务,并且都有密不可分的关系。一旦其中一个服务不可用时,就会造成另一个服务也无法使用.虽然外部结构看起来会比较简单, 但是在资源分配、测试、拓展等各方面看来都不够灵活.(所以你知道微服务的优势在哪了)。
      一个比较好理解二者之间区别的例子就是, 微服务就像是docker, 而单体式应用就像是传统的虚拟机(这只是我在理解过程中的一个比喻, 不一定准确).

  • IaaS/PaaS/SaaS/XaaS

    这里所谓的*aaS即”* as a Service“, 本质就是把*当作服务来进行出售.

      IaaS(Infrastructure as a Service, 基础设施即服务),其意指如果你只是要使用硬件设备罢了, 那就没有必要花巨资购买整套设备并为设备用地以及今后的维护、设备拓展/更新买单,你可以租用硬件, IaaS方面的公司(如Amazon[AWS])会提供服务器,存储器等硬件设备,这样就可以节约成本,利用对方公司提供的服务, 你可以随时使用这些设备来运行你的服务/应用。
      PaaS(Platform as a Service,平台即服务),这里的平台有时也叫做中间件,即云计算环境中的应用基础设施服务,也就是支撑应用和运行时环境,如虚拟服务器、操作系统、应用服务器、数据库等
      SaaS(Software as a Service,软件即服务),也就是软件提供服务了, 这个很好理解.
      IaaS、PaaS、SaaS其实是云计算领域的三个概念,基础设施在最下面,平台在中间,软件则在最上面, 如果你什么都有, 那么就是本地部署, 也就无所谓这些*aaS了.
      XaaS也就是Anything as a Service,可以说IaaS,PaaS,SaaS是其子集
    以上内容部分参考了 何足道 知乎回答

  • 方言 Dialect(computing)

    此处指计算机行业中的dialect, 其意为一门编程语言或数据交换语言的拓展或者变种形式(摘自wiki,A dialect of a programming language or a data exchange language is a (relatively small) variation or extension of the language that does not change its intrinsic nature)
      如各个关系型数据库厂商的SQL方言; Clojure是一种Lisp方言; 等

  • CI/CD/CR

    持续集成(CI, Continuous integration),持续交付(CD, Continuous delivery),持续部署(CR, Continuous release)
      所谓持续的思想就是: 既然我们知道开发的需求很难一次性完整的定下来, 那么我们就一点一点的开发, 每一次功能完成后再加到主体上去, 这样使得开发过程更加(敏捷&灵活), 有错可以及时更改, 与最后一次性对系统进行合并/集成然后再构建 测试 发布相比(风险&损失)更小, 也就符合了极限编程的要求. 持续是指整个过程中项目功能的合并, 构建, 测试, 发布产品等, 这些环节是持续的.
      持续集成很好理解, 给出的wiki链接页面中解释得很清楚, 就是每次一点代码(在开发者通过构建&测试之后)集成到主线.
      持续交付是指将集成后的代码通过更真实的类生产环境的测试后部署到生产环境中, 但是是否部署是可选的, 部署是手动的.
      而持续部署就是在持续交付的基础上进行全自动的部署. 如wiki中所描述的如果要实施持续部署,必须先实施持续交付.

  • 几种流行的部署技术

    蓝绿部署

    蓝绿部署(Blue/Green Deployment)的特点是无停机时间且风险较小,具体的流程介绍在链接的博客里已经说的很清楚了,在此不赘述.

    滚动部署

    停止部分服务并对其进行更新,完成后投入重新使用.如此重复直到所有服务都更新为新的版本.但是在升级的过程中,服务运行的环境是变化的,你并不知道哪个时候的环境是稳定,所以如果需要回滚的话,那就要回滚到稳定的环境里,意味着可能要从头再来.

    灰度部署

    不停止老版本的服务,另外开一个新版本的服务给用户使用,新版本出现问题即可回滚.
      因为跳跃式发布是很危险的,所以需要像灰度(指从黑白之间)这种平滑过渡的发布.
      与A/B测试一样,本质就是发布多个版本看效果如何,也就是试错,有问题就回滚,经过一段时间的验证后没问题就正式发布.

  • REST架构

    根据wiki定义:”具象状态传输(REST,英文:Representational State Transfer)是Roy Thomas Fielding博士于2000年在他的博士论文中提出来的一种万维网软件架构风格,目的是便于不同软件/程序在网络(例如互联网)中互相传递信息。”wiki中提到“REST是设计风格而不是标准”,这是很重要的一点,首先在理解之前你不能误解它本身的含义和存在的意义。

      具象状态传输架构风格最重要的架构约束有6个:

    • 1.客户-服务器(Client-Server):通信只能由客户端单方面发起,表现为请求-响应的形式。
    • 2.无状态(Stateless):通信的会话状态(Session State)应该全部由客户端负责维护。
    • 3.缓存(Cache):响应内容可以在通信链的某处被缓存,以改善网络效率。
    • 4.统一接口(Uniform Interface):通信链的组件之间通过统一的接口相互通信,以提高交互的可见性。
    • 5.分层系统(Layered System):通过限制组件的行为(即每个组件只能“看到”与其交互的紧邻层),将架构分解为若干等级的层。
    • 6.按需代码(Code-On-Demand,可选):支持通过下载并执行一些代码(例如Java Applet、Flash或JavaScript),对客户端的功能进行扩展。”。
      wiki 具象状态传输

    我的理解是,REST就是定义一个系统/软件的架构,以及如何设计出RESTful API的,它让系统对外提供的接口更加规范(也就是符合REST风格),如REST的提出者Roy Thomas Fielding在他提出REST的博士论文中所说:”My work is motivated by the desire to understand and evaluate the architectural design of network-based application software through principled use of architectural constraints, thereby obtaining the functional, performance, and social properties desired of an architecture.”这些RESTful的接口将会“功能强大,性能出色且友好易用”。

  • 编程语言的自举

    首先一提,能够自举是一门编程语言成熟的标志之一(不能不代表不成熟)。简单来说就是语言自身的编译器可以编译自己的编译器。引用知乎上轮子哥的回答比较简单易懂:

    你想创造一门V语言而且用V语言来写V编译器的话,你得按照下面的方法做:
    1、用C++把那个编译器(A)写出来,顺便留下很多测试用例。
    2、用V语言把那个编译器写(B)出来,用A.exe来编译B,修改直到所有测试用例都通过为止。
    3、B.exe来编译B自己得到B2.exe,修改直到B2.exe所有测试用例都通过为止。这是为了保证,就算B本身有很多bug,至少编译自己是没有bug的,从而你就可以走到第四步。
    4、当你觉得有信心了,用A.exe把B编译一遍,就得到了B.exe。然后A的代码和A.exe都在也不需要存在了,删掉他们。以后你就不断的用B.exe来编译下一个版本的B就好了。就自举了。
    vczh 知乎回答

    那么图灵完备的语言是不是都可以自举呢?从我个人“没有哪一门图灵完备语言实现的功能是另一门图灵完备语言所不能实现的”的观点来看答案是肯定的。觉得没有必要在“能不能”和“有没有实现”这个问题上纠结,这只是编程语言的一种性质,能不能自举是一回事,有没有必要真的实现就是另一回事了。

  • 图灵完备

    wiki描述:“在可计算性理论里,如果一系列操作数据的规则(如指令集、编程语言、细胞自动机)可以用来模拟单带图灵机,那么它是图灵完备的”。图灵机的基本思想是“用机器来模拟人们用纸笔进行数学运算的过程”,也就是说图灵机能执行所有可被描述的计算。
      也存在着一类问题我们人类能构造出来而图灵机不能解的,那就是悖论。悖论是不具有可计算性的,如典型的停机问题等。关于图灵机推荐这一篇论文

    编程语言的图灵完备性

    图灵完备的语言也就是可以模拟出图灵机的语言,大部分的GPL(General Purpose Language, 通用编程语言, 此处不是指GPL通用开源协议)基本都是(所以在项目实践中谈语言是否图灵完备的意义并不大),所以也易知没有哪门图灵完备语言实现的功能是另一门图灵完备语言所不能实现的(只是过程的难易程度,也就是开发成本不同)。
      相对于GPL,大部分的DSL(Domain Specific Language,领域专用语言)都不是图灵完备的,典型的就是SQL(指SQL92标准,T-SQL之类不属于)、html等。

  • 语法糖

    wiki描述:“语法糖(Syntactic sugar),也译为糖衣语法,是由英国计算机科学家彼得·兰丁发明的一个术语,指计算机语言中添加的某种语法,这种语法对语言的功能没有影响,但是更方便程序员使用。语法糖让程序更加简洁,有更高的可读性”。
      在我理解,语法糖的存在其实就是为了让代码写起来更简洁&读起来更舒服(但是我感觉它与可读性的关系并不是绝对的正相关,因为一种写法对熟悉这门语言特性的人来说可能很舒服,但是不熟悉的人可能就很难理解,编程和理解的能力永远是相对而言的),其在绝大多数情况下并不会影响到语言(特别是编译型语言)执行的效率,因为它在被语言处理器(编译器、静态分析器等)处理的过程中就被转换掉了(有点类似C++内联函数的意思),该过程如wiki所言:“把‘加糖’的结构变成基本的结构,这个过程叫做‘去糖’”。

    语法盐

    类似的也有语法盐。wiki描述:“语法盐(英语:syntactic salt)是指在计算机语言中为了降低程序员撰写出不良程式码的设计,但其中仍会有潜藏错误存在的可能。例如,C语言或C++语言中Switch指令的case中若不加break编译器并不会产生错误讯息,部分程序员认为宣告变数型态也是语法盐的一种”。
      Wiki上还举了一个容易理解的java的例子:Java中并不允许将一个宣告为float类型的变量赋值给一个宣告为int类型的变量,但是C和C++会自动把float类型的变量舍去小数并赋值给int类型的变量。

    int num1;
    float pi=3.14159;
    num1=pi;  //赋值错误