这里记录了一些容易搞混的概念,当然这些概念并不仅仅出现在程序设计中。我会尽量通俗易懂的去解释这些概念,与此同时也会失去一定严谨性。如果有错误或者建议请在下面回复,我会改的。(°□°;)

01. 观察者模式与发布订阅模式

发布订阅模式可以理解成是观察者模式的一个扩展,观察者和被观察者之间多出了一层。

观察者模式:假如我养了只猫,我想时刻都能知道它的状态。好的,那么很简单,你只需要在家 24 小时盯着它看就好了。此时观察者是你,而被观察者就是这只猫了。

发布订阅模式:假如有一天我要出门,这样就不能 24 小时盯着它看了,怎么办?很简单,叫你的朋友来盯着它,在它乱叫的时候(行为),打电话通知你。此时订阅者是你,发布者是那只猫,而你朋友是你们之间的中间人。


发布订阅模式的优点:

  1. 低耦合:你可以把看猫的事情交给你朋友,麻麻再也不用担心我因为这只猫不能去搞事情了。
  2. 可异步:你的朋友可能不会把猫的变化第一时间内转达给你,你可能也不能在第一时间给出应对措施。

02. 共享锁与排它锁

共享锁又叫读锁,它只能读。排它锁也叫写锁,它既能读也能写。

例如有 2 个人,一个叫共享,一个叫排它。然后我把一些画给了他们。

  1. 共享:这些画是我的,但是我愿意分给更多共享的人去看,但是我不会分给排它,因为他们太自私。
  2. 排它:这些画是我一个人的,任何人都不要妄想从我这里得到它,它是我的个人财产,我甚至可以毁掉它。

03. 悲观锁与乐观锁

悲观锁和乐观锁是为保证事务中数据的一致性、隔离性而产生的技术手段。在数据库中,它们的实现是依赖于数据库本身所提供的锁机制来完成的。也就是说它们只是一种设计思想,具体的实现方式可能不太一样。

悲观锁:和它的名字一样,非常的悲观,总想着别人会修改它的数据。所以它会给这些数据加上排它锁。

乐观锁:非常的乐观,认为别人不会去修改它的数据。但是在提交这个事务的时候,会采用一种方式来检查数据是否被别人改了(比如对比修改次数,也就是版本号)。如果被改了,则不能提交这次事务,就必须回滚。而下一步要做的可能是直接报错,让用户处理,或者是重新尝试。

04. 集群、分布式、负载均衡

集群:一群机器同时干活。

分布式:一群机器同时干不同的活。

负载均衡:前面说的都是一群机器怎么干活、干什么活。但是具体每台机器要干多少没人知道。所以这时候就需要负载均衡器了,他用于向集群中的机器平均分配任务。

05. 并发与并行

有一种机器,同时只能做一件事。这时有两个任务需要做。

并发:使用一台机器轮流去做这两个任务。

并行:使用两台机器同时去做这两个任务。

并发强调的是能够处理多个任务,并行强调的是能「同时」处理多个任务。在上面的并行模型中,机器 1 做 任务 1,机器 2 做 任务 2,同时进行互不影响。

06. 同步与异步、阻塞与非阻塞

同步与异步主要体现于「被调用」方,阻塞与非阻塞体现于「调用」方。

同步异步:a 调用 b,看 b 如何将计算结果反馈给 a 方法。

阻塞非阻塞:a 调用 b,看 a 是否挂起等待 b 方法返回结果。

07. is-a 与 has-a

is-a:是 xxx,比如猫是种生物,这意味着猫继承了生物的共同特征。

has-a:有 xxx,比如猫能喵喵喵,这意味着猫还拥有了某些特殊的特征。

通俗的总结:前者强调的是 是什么 ,如继承。而后者强调的是 有什么 ,如组合。

08. 接口与抽象类

接口:接口的目的只有一个,那就是约束。接口可以理解成是制定的一系列子类要实现的标准。

抽象类:与普通类类似,抽象类只是对类的一种扩展,让类可以支持有抽象方法,而类的实质没有改变。

一个类只能继承一个抽象类,那么这个类可以说是这个抽象类的超集。同时一个类可以实现多个接口,那么可以说这个类是这些接口的集合体(包含的关系)。

所以可以发现,继承的子类和抽象类的关系并没有本质的区别,子类还是这个抽象类,只不过实现可能略有不同。而子类与接口的关系则发生了变化,因为子类是由一个或多个接口堆积而成的。

通俗不严谨的总结成:

  1. 子类抽象类(is-a);
  2. 子类由一些接口组成(has-a)。

09. 控制反转与依赖注入

控制反转:一种设计思想,是用来解耦的,通俗的说就是把控制权反转了过来。比如在类 A 中需要用到类 B,那这时候会在类 A 中写 new B() 的代码。这时候可以说类 A 在控制类 B(的实例化过程)。那么反转过来就是,不让类 A 自己实例化类 B 了,而是让别人事先 new 好后想办法让 A 能够使用,而这时候的 别人 可以成为是「容器」。

依赖注入:对控制反转的具体实现,上面说了类 B 会由「容器」实例化好想办法让类 A 用上,那么依赖注入就是这个 办法 。依赖注入的核心是「注入」,很好理解,在这里就是把类 B 注入到类 A 中,比如把类实例当做函数参数传过去。

10. URI 与 URL

URI:统一资源标识符,它的核心是「标志」。

URL:统一资源定位符,它是 URI 的子集,它的核心是「定位」。

比如 http://example.com/video/alh.mp4 这个链接,URI 只管它叫什么,所以是 video/alh.mp4 。而 URL 需要找到它,所以就需要全部的信息了(协议、主机名、路径等),所以 URL 就是这整个地址。

11. PHP 中类的 self 与 static

self:self 写在哪里,调用到的就是哪个类中的方法。

static:你当前用的是哪个类,调用到的就是哪个类中的方法。

12. JavaScript 中 for…in 与 for…of 循环

  • for…of 是在 ES6 中新加入的语法;
  • for…of 只会遍历数组中索引为数字的属性;
  • for…in 遍历得到的是键名,for…of 得到的键值;
  • for…in 会遍历自身和原型上的可枚举属性,for…of 只会遍历自身属性;
  • for…in 可以遍历普通的对象,for…of 只能遍历带有 Iterator 接口的对象,因为它就是利用 Iterator 来实现的。