专业术语解释 - 持续更新

序列化

序列化:就是把对象的状态信息转化为可存储或可传输的字节序列。

举个例子。数据在传输的过程中,都是以流的形式传输的。所以,当我们在网上下载各种文件,比如图片、视频、音频的时候,我们下载的实际上是这些文件被序列化后的数据流。当我们用记事本打开那些文件的时候,我们看到了就是一串乱七八糟的字符,这就是被序列化后的对象。

反序列化

反序列化:就是把字节序列重新恢复成对象。

举个例子。最明显的应用就是各种播放器。图片查看器、音频播放器、视频播放器等。他们的作用就是根据不同的格式把字节序列反序列化成对象。

线程安全和脏读

线程安全:当多个线程同时访问时,其能表现出正确的行为或状态。如果符合这个条件,我们可以说这是线程安全的。在java中,我们一般用synchronized关键字对其加线程锁,以保证其数据的同步。而脏读,就是拿到的这个不正确的行为或状态。

举个例子。假如某车站分ABCD4个窗口进行售票。每次卖票前,售票员都会查一下余票还剩多少。现在车站只剩下最后一张票了,有俩人分别到A窗口和C窗口车站买票。此时A和C同时去查票,他们得到的余票结果都是1。A取票出来卖给乘客以后,C去取票,发现取不出来,但查到的结果明明是还剩下1张票。这种情况下,我们称售票这个操作是线程不安全的。而C拿到的结果,就是脏读出来的数据。

假如我们给售票这个函数加上synchronized线程锁以后,就会出现这种情况

最后一张票!A和C谁先进入售票操作,谁就能先售票,而另一个窗口就会进入等待状态。比如A先进入操作,那整个资源都会A独自占用。此时C是访问不到结果的,因为售票这个操作已经被锁上了。C只能等A卖完了以后才能继续售票。此时线程是处于安全的状态。线程安全的情况下是不存在脏读的。

BIO通信

BIO(Blocking I/O):同步阻塞式通信。在客户端和服务端通信时,通常采用一个Acceptor线程监听所有的客户端的连接。也就是ServerSocket调用accept方法的时候。此时,每有一个客户端连接到服务端,Acceptor就会创建一个新的线程处理客户端的请求。处理结束后,线程就销毁。这就是客户端:线程模型=1:1的模式。但是系统的线程资源是有限的。这样的弊端就是,一旦客户端连接数量过大,系统就会宕机。

举个例子。假如你点了个外卖。外卖公司就会派一个外卖小哥去帮你拿外卖,送到你手里。送完以后,外卖小哥就走了。假如,你们一个公司1000个人都在同一家店点了外卖。外卖公司就会派1000个外卖小哥去店里拿外卖。但是一个店能容纳的人是有限的。这样的话,店主就会选择停止接单,你就不能在那家店点外卖了。外卖服务也就宕掉了。

伪异步I/O通信

伪异步I/O实际上还是阻塞式的通信。只不过线程不是由Accetpor来创建了。而是由线程池来管理。线程池管理线程的话,就有效的控制的线程数量,保证了系统资源的控制,实现了客户端:线程模型 = N :M的模式。但正因为线程数量有限,如果发起了大量请求,超过最大线程数的请求就会阻塞,处于等待状态。有三种情况线程会被恢复使用:

  • 有数据可读
  • 可用数据读取完毕
  • IO异常或空指针

举个例子。还是外卖问题。现在外卖公司只派10个外卖小哥去服务那家店。现在你们公司100个人去买那家店的外卖。十个外卖小哥都出动了。先下单的10个人的请求会被优先接受。后来的90个人就会等外卖小哥接单。一旦有一个同事的外卖送到了以后,这个外卖小哥就会接受第11个人的请求。下面由三种情况会让外卖小哥继续接单。
1. 有新的单子出来了
2. 外卖送完了
3. 客户联系不上了(md不送了)

TCP粘包

​TCP是个 “流” 协议。所谓流,就是没有界限的一串数据。数据在传输时,就像河里的水。他们是连成一片的,并没有分界线。TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行包的划分。所以在业务上认为,一个完整的包会被TCP拆分成多个包进行发送,也有可能把多个小包封装成一个大包发送。这就造成了所谓的TCP粘包问题。

举个例子。现在有两个包A和B,分别是15KB和5KB大小。缓冲区是10KB。TCP传输时,A包会被拆成10KB 和 5KB,前面一个10KB会被打包成一个包。后面的5KB和B包的5KB会被打包成另外一个包,分成两个包进行传输。这样,数据粘包的问题就出现了。

IoC控制反转

控制反转是个比较抽象的概念。我个人认为不仅是技术上的升华,更是思想上的。何为「反转」,它是相对于传统的编程来说的。传统意义上的编程使用对象时,都是通过自身new的方式主动去创建对象。而IoC就是将这个过程「反转」过来,只要在配置文件中描述各种对象(Bean)。【在Spring的世界中,万物皆Bean】,就可以通过Spring的IoC容器使用对象。

举个例子。假如你是一家奶茶店的店主,你的奶茶店就是个容器,而所有的奶茶品种都是不同的Bean。现在,你写了几个奶茶配方贴在店里。这个行为就相当于你在配置文件中描述Bean该如何创建。终于有一天,你的奶茶店开张了!(此处应该有掌声!!!);这个行为就相当于你的IoC容器启动了。开张以后,店员按照配方,每种奶茶都做了足量放在容器中。现在顾客A需要一份奶茶,他描述了一下他要的奶茶的成分。然后你对着配方(配置文件)找到了奶茶(Bean)给了他一份奶茶;然后顾客B也来要一份奶茶,他也描述了一下,你又对着配方看了一下他要的奶茶。发现你并没有写那种奶茶的配方。然后你就告诉他没有(抛个异常)。以此类推,顾客C…顾客D…,你的店(容器)就红红火火的运作起来了。

如果是传统意义上的编程:

举个例子。假如你需要一杯奶茶。你就得自个哼哧哼哧买牛奶,买椰果等各种你想要的。每次想要奶茶都哼哧哼哧自个儿做。久而久之都不知道自己做过哪些奶茶了。但是奶茶店就不一样了,他清楚的知道各种奶茶分别卖出了多少份。

AOP切面编程

这个概念很难理解。我理解了很久,但也不是非常的透彻。所以,以下观点仅供参考,如果错了,欢迎指正!
AOP是一种编程思想。它不是仅在Spring中存在,它在各种语言编程中都存在,只是Spring支持AOP而已。切面!我个人觉的是对类一系列行为的抽象。

举个例子。每年开学都有新生注册入学。但学生有小学生,中学生,大学生。而注册入学这项流程不只归小学生所有,也不只归中学生、大学生所有。它归所有的学生所有。所有我们可以把注册入学抽象出来作为切面。只要有新生注册入学,我们就通知他去切面执行一波流程。报到 >>> 缴费 >>> 领书 >>> 完成注册。如果有一天,突然改了需求,缴费前先审核证件。这样我们只需要在切面中修改流程即可。假如我们还是用OOP面向对象的编程,则需要在每一个类中都需要增加这样一个流程。这样的话,代码就显得臃肿,复用性也降低了。

猜你喜欢

转载自blog.csdn.net/yujiumin/article/details/80650773
今日推荐