00:02
好,那首先的话呢,我们今天先给大家讲一个,呃,就是Java基础阶段非常重要的一个知识点。缓存和缓冲。的区别。缓存和缓冲的一个区别。这个知识点的话呢,其实很多人都不知道他俩的区别到底在哪,尤其是在面试的过程中呢,呃,是让大家很诧异的一一个事情啊,就是说很多人都分不清楚这个缓冲和缓存的一个区别,其实这个是一个很基础的知识点,大家都应该去掌握。所以呢,今天我们就首先把这个缓和缓冲的区别呢,讲清楚以后,我们再遇到这样的一个问题啊,就没问题了啊,肯定能答上来了啊,首先的话呢,我们再来说什么是缓冲。缓冲的话呢,叫buff。对不对,一看这个关键字大家肯定都比较熟悉,因为我们之前在IO流里边是不是使用到了缓冲流,有buffer reader buffer对吧,包括buffer input stream bufferd output stream咱们都用过,但是呢,我们可能并没有去,呃,详细的去说一下这个东西到底是干嘛的啊,以及跟缓存的区别,很多同学一看这个本来名字就很像啊,一个缓存一个缓冲,所以很容易搞混,其实两个是完全不同的一个功能。
01:18
对吧。那么我们首先来说缓冲啊,我们要学习一个技术,就首先你一定要去知道这个东西是用来干嘛的。那么缓冲是用来干嘛的呢?缓冲它的作用呢?它就是协调上下。上下层应用。之间的性能差异。哎,他就是干这个事情的啊,所以说这句话可能很多同学都没有听过啊,缓冲用来协调上下层应用之间的性能差异,这句话啥意思呢?我们来画一个图。就是说我们这个程序呢。可能是分为上下层的两个,两层不同的程序上上层应用以及下层应用,就比如说我们的这个service跟这个controller对不对,你可以理解它就是两层啊,当然我们这边这个两层可能更多的是这种两个,呃,两个系统之间的一个差异,它并不是说我们两个业务层的啊。
02:11
上层应用。我们给他换个颜色。然后再来一个下层应用。字体改大点。老师。下层应用啊。瞎走。给他换一个颜色,这样的话大家好区分它。我们两个不同的这个应用,然后他们两个之间呢。我们说是性能是有差异的,对不对,所以这个是。这四个字是关键啊,因为他们有性能差异,竞争差异,假设我们说上层的话呢,它的效率比较高,速度比较快,或者它的流量比较大。流量大。对不对,速度快。
03:04
那下层的话呢,流量小,速度慢。速度慢。然后呢,上下层之间呢,是需要去啊,互相调用的。那么他们互相调用的时候,就会带来一个问题,我们把它俩进行对接的时候呢,什么意思啊,就下层它接不住上层东西。对吧,我们就以L举例,比如说我上层啊,一个单位时间内,我比如说给你来了。来了六个数据对不对,但是我下层呢,在单位时间内只能接收三个,那是不是六对三肯定对不住嘛,对不对,肯定接不住,也就是说我这边上面东西太多了,我这边下面接不住对不对,就相当于我们。我们比如说啊,我们现在有两个瓶子,有两个水瓶,然后这个水瓶里边呢,装满了水,我们现在要把上面的这个瓶子里边的这个水呢。对吧,我们给它注入到下层。但是呢,这两个瓶子区别在哪呢?上层我们是一个敞口瓶,就它这个口瓶啊,这个瓶口比较比较粗对吧,比较粗啊,但是下下层的话是一个细口瓶,对不对,它是这样一个形状的啊,这样的形状一个瓶子,所以说这个口是一个细的,这个口是一个粗的,那你说这个我们如果说这样去把这个水倒下来。
04:18
你说这个水能保证全部进入到这个细火瓶吗?肯定不可能啊,对不对,是不是肯定会有一些水就洒到外面了,对不对。下面接不住上面嘛。因为它两个完全这个尺寸啊,它这个它这个流流口和这个进口它完全不对等,尺寸完全不一样,所以肯定会造成这个水的一个丢失,对不对,这个应该很好理解啊,大家自己你可以自己在家试一下啊,这肯定没问题,你不可能说你技术再好,你也不可能把这水一滴不落的全部倒在这个细火瓶里边,如果你把细火瓶倒在这儿。应该问题不大,但是你把这个敞口瓶倒在气口瓶里边,肯定这个水会有一定的这个呃丢失对不对,那回到我们程序里边是不是一样的道理啊,一样的道理啊,就是这边的话,我们这个数据呢,肯定会有丢失的,因为我这个单位时间内只能接受这么点,你一下来这么多。
05:05
对吧,肯定会有数据丢失的,所以说我们不希望看到这样一个数据丢失,怎么办呢。怎么怎么解决呢?是不是要中间加一个东西来衔接上下层啊,如果是我们的水的话呢,我们怎么加呢。怎么样?大家见过漏斗吧?换了啊。假设水平好,大家见过漏斗吧,你直接这样去对接是不行的,诶我给它加一个漏斗,漏斗是这这种形状的对不对,漏斗是这样一个形状的啊,应该都见过漏斗。比如说买醋啊,买什么,呃,过去那个买酒是不是都是用这个漏斗,然后把它插到这个吸口瓶里边,然后呢,是不是从这把这个东西倒进去就OK了,你看这样的话,是不是肯定能把这个水全部接收过来,因为我现在有了一个漏斗,所以说你这些水过来之后呢,它是不是直接进到这个漏斗里边,然后漏斗的话是上宽下窄的。这么一个结构,那是不是就可以保证这些水是不是全部进入到漏斗里边,然后呢,再通过这个下面这个细口,是不是再把漏斗里边这些水是全部注入到这个下面这个瓶子里边,也就是说用漏斗的话呢,可能这个呃水的流速会相对较慢一些啊,因为你毕竟是有一个这个呃宽度差嘛,它的水流速可能会更慢一些,但是呢,它可以保证让我们的这个数据,让我们这个水是不是全部一滴不落的,全部进入到我们下面这个瓶子里边,是不是可以解决这个问题啊。
06:28
对吧,这个大家应该很清楚啊,非常简单的概念啊,这个你还是回去可以自己试一下,插了漏斗之后,你看把水倒进去,它可能稍微有点慢,但是呢,它不至于说把水漏出去。OK吧,所以呢,我们这边也是同样道理啊,怎么去解决这个问题呢?我就给它中间加个漏斗就OK,那这个漏斗是啥呢?就是缓冲嘛,对吧?啊,这不就引入我们的缓冲了,它就是一个缓冲缓冲区。我们通过一个缓冲区啊,缓冲区它的形状可能这样,我给大家给你画一下吧。呃,找一个找一个这个形状看。
07:03
它们它是上面宽下面窄。啊,这。对吧,这玩意儿就是缓冲区。这个东西诶。这个字,因为我把它。转了180度啊,所以说这字也反了,反正去。有缓冲性的换个颜色。对吧,你看有这么一个装置之后的话,上面的这些水啊,上面这些数据啊,是不是直接全部进入到我们的缓冲器里边,这数据流全部进到这儿。不至于说丢失嘛,对吧,你总之先进到这个漏斗里边OK啊,进到漏斗里边之后呢,由我们这个漏斗呢,再把这些水呢。给他。可能速度会比较慢,但是会保证这些水呢都可以啊,一滴不落的全部进入到我们下层应用,对吧,保证这些数据可以这样进去啊,这就是这就是缓冲区的一个作用。
08:03
来把这个图画出来啊,看它大概就是这么一个作用,对吧,这就是缓冲区啊。OK吧,所以通过这个例子大家应该很清楚,呃,很明白的,很清晰的去了解到这个缓冲仪它的作用到底干嘛的,它就是为了解决这个性能差异的,我们是一个漏斗,然后呢,可以去承载上层的比较大的数据流,然后呢,呃,用这个漏斗的一个缓冲机制呢,把这个数据流呢,慢慢的给它加到这个下层应用啊,其实这个跟我们后面的一些。呃,就是咱们企业级开发里边使用的一些组件,其实很像的,比如说我们这个,呃,消息队列对不对,消息队列它其实它的它的思想呢,跟这是一样,就是我们去衔接两个不同应用,它们之间的一个性能差,哎,我用消息队列去暂时去把这个上层的这个请求接收下来,然后呢,下层请求呢,它可能没有做高并发处理它的呃速度会比较慢,然后呢,你慢慢的从缓冲区里边,从从这个消息队列里边把这个把这个请求拿过去,然后进行处理就OK了,对吧?我们在这个高并发的一个场景里边,我们会使用到消息队列做一个流量学风啊,这个到后面我们都会讲到,对吧,其实道理是一样的,我们讲到那之后,我们再去说这个,大家就可以回忆起来,我们之前讲过,这个缓冲区的一个作用跟它是一模一样的啊。
09:25
所以呢,在程序里边,我们很多的这个技术,它背后的这个道理都是一样的啊,只不过说我们在不同的阶段,我们使用的技术,它的这个量级不一样,但是呢,道理都是相通的啊。对吧,那么我们通过这样一个结构呢,就可以解决我们这个呃,上下层服务之间的一个不对等的一个这样一个问题,上层组件呢,不需要等待下层组件完全接收全部数据即可返回操作,这样的话呢,就加快了上层组件它的一个处理速度,从而从而提升了呃整体的一个一个性能啊,我们把这个给大家简单记一下。
10:06
就是通过呃缓冲区。华中区的这个设置啊。缓冲区的这个要应该叫什么,应该叫缓冲吧,通过缓冲区的缓冲的。我们就可以解决这个。性能差异的一个问题。上层组件。当上层组件性能优于。下层组件的时候。缓冲。可以有效减少。有效减少。有效减少什么呢?可以有效减少上层对下层的一个等待的一个时间。上东医院。对下层组件等待的时间。
11:00
对呗。你想想吧。如果说时间啊。如果说。我们这个上层啊,它需要呢,比如说发六个这个数据流过来,但是呢,你下层是不是一次只能接收三个,所以说我是不是就假设我处理三个,我处理三个数据流的时间假设是一秒钟,对不对,那是不是我就上层,因为得等待两秒钟,是不是才能把这个功能做完,把这个把这个业务做完,我要把六个数据给你,但是你同一时间只能处理三个,是不是我得分两次,然后处理一个是一秒钟,加起来是不是两秒钟,对不对,所以说我上应用就需要两秒钟的时间呢?去呃,去把这个工作做完,但是如果说我们有了缓冲区之后就不一样了,缓冲区的话呢,它是不是一次性可以把这六个全部加进来。加进来之后呢,他就可以去做其他事情了,他不用在这儿等着,然后是不是有缓冲区,利用他这样一个缓冲结构,是慢慢的把这六个一个一个去做一个消化,对吧。
12:00
然后传给下层,所以呢,有了这样一个装置之后呢,上层应用是不是就不用去等待下层的一个应用的接收了,它可以直接把东西一下丢到这个缓冲区里边,他就去做其他事情,而不用在这等待,是不是可以减少上层组件对下层组件的一个等待时间?对不对啊,所以说基于这样的结构。基于这样的结构呢,上层组件。它就不需要等待下层组件。不需要等待下层总监完全接收。全部数据。不需要等它全部完全接收,全部数据即可返回。进行其他操作。对吧,即可返回其他进行其他操作,这样的话呢,加快了上层组件的一个处理速度,从而提升了整体性能的,整体我们系统的一个整体的一个性能。加快了。上层组件。
13:00
处理速度。初二。其中整个。系统的。这个性能对吧,因为你上组组件这个处理速度快了之后呢,是不是整体它的性能就上去了啊,你下组组件因为本来就很慢,所以说这个也不会对我们性能呢造成一个影响,对吧?好。这种思想的话,我们说在消息队列里边表现的淋漓尽致啊,当然消息队列我们这边没有接触到,这个是在分布式的项目当中啊,我们需要去处理到的,到后面的话,我们再讲他的思想都是一样的,OK。好,那接下来的话,我们通过代码来看一下啊,这个缓冲啊,到底会给我们带来怎样的一个好处,所以说我们打开idea,我们来写一个代码,通过代码的方式呢,我们来对比一下,因为我们是这边只是光说嘛,对吧。最终的话,我们肯定还是需要用我们的这个,呃,实际的结果呢,做一个验证。挨点打开。
14:21
新建工程吧。那我们写个什么东西呢?我们还是用这个IO流嘛,对吧,因为我们目前呢,目前的话呢,是在IO6里边儿,我们是用到了这个。缓冲嘛,其他地方我们可能暂时还没有用到啊,所以呢,我是在L里边去处理一下,呃,我在在这个。
15:02
比如说这边有一个f.text啊,打开看里边啥东西。哎,这里边我把它改一下,这里边儿怎么是。关掉关掉,我重新我把它删了,重新建一个,这个是之前的一个测试的,应该是。我就叫few。叫好。那么我在这里边呢,去给他加一些数据。加一数据啊。我们从网上随便找一段东西。
16:04
随便复制点东西过来,让它里边有一些数据,然后呢,我们对这个数据呢,进行一个读取。放到这,OK。放到这儿,不管它里边啥东西,总之里边有数据,OK了。好,现在的话,我们这边有了一个f.text里边存了一些内容,对吧,接下来的话,我们通过I物流呢。把这个数据呢读进来。新建一个类。然后呢,我们在这边去教他的论方法,在焖方法里边,我们怎么办呢,我们这边呃。因为我们都是字符嘛,所以我用字符6WRITER。Writer等于。等于。
17:00
Writer等于new一个。Feel better。对吧的话,把我们这个文件啊,给他路径给它拿过来。Build their text。好,这个的话呢,我们给它呃呃拆开处理一下。好,拿到它之后的话,接下来我们要读取它,读取它的话怎么读呢?非常简单吗。比如说呢,我们这边给他。啊,这边我们是给他写吧,呃,写的话呢,我就把它里边先清空啊,我们这边用。用这个。输出流去测试吧,好。用输出流去测试啊,不用输出流了,用输出流的话效果可能更好一些,好这边的话呢,我先要给它里边写东西对不对。怎么去写呢?那写东西的话,你这边用循环去写吧。
18:00
比如说我就把这个012345678这些数据给它写进去,我们来看一下它的一个性能,因为我们是我们说是就是这个。是不是要用缓冲流,是不是往里边去加东西啊,而不是读东西啊,所以说我们用这个呃,字符流,字符流字符输出流,然后呢,我这边往里边往里边输出就可以了,往里边输出就可了,所以说我把这个一开始这个就给它清空就OK了啊。啊,我们不是读,是喜啊。然后这边怎么写呢?比如说我就把10万,把零到10万给它写进去,把这个数字写进去对不对,那这边怎么办呢?这边的话我们就可以先定一个long类型的number等于10万。对不对,好,注意这个数字大家可以怎么去写呢?因为如果说这个数字很大的话,可能后面这个零啊,我们就是不是特别好去计算啊,所以呢,这个加号里边提供了一个写法,用一个下划线去。去分割就可以了,所以写数字的话,我们是可以加下划线的啊,就你这样去写跟不加是一样的,但是你加上去之后呢,是不是这个数字就区分的很清楚,后面是不是四个零,所以说是不是以万为单位,前面再加个十是不是10万。
19:05
对吧,这样的话呢,是不是就区分的很清楚啊,就跟我们写这个,呃,我们一般去记录这个金额的时候是不是。是不是?是调,你去记录吧。这边是不是三个千位,是不是就加个逗号,这样的话是不是方便我们去读取整个的一个数据啊,这边也是一样的啊。而且这个斜杠这个这个下线你在哪加都可以啊,随你的对吧,我们就在这加,因为10万嘛。好,接下来的话,我们写一个循环,把这10万给它全部读进去。Therefore。对不对,好。right.right把这个I写进去就OK了。对不对,写完之后的话,我们在这把它把它给它关掉啊。回到之后呢,这边同样需要去处理一下。来,开始啊。这边我们把异常给它改一下。
20:19
啊,它这个是类型不匹配,我给他改成特吧。加上头。改成int就OK了,因为这边的话它要求传输int,但是我们这边刚才我定义是浪啊,所以说把它改成int就OK了,这样的话呢,我们就可以通过一个循环呢,把这个是不是零到10万,把这个数据给它写到这个文件里边,对不对,但是我们这边并不是说我给他写入写的东西是啥啊,我们不关注这东西,我们关注的是它的一个效率。对不对?那么我们怎么计算它的效率呢?我是不是就可以计算一下,我把这10万个数字写进去一共花了多长时间啊,对吧?那怎么计算这个时间呢?就是在这个循环开始之前,我是不是可以获取一下系统的时间叫begin time开始的时间等于什么呢?System。
21:03
第二。Current。Ten minutes,对对,获取当前的系统时间是以毫秒为单位的,然后循环执行完成之后,我是不是可以再来获取一次时间?那这两个时间差,那不就是我们这个循环它总共运行的时间嘛,对不对,在开始获取一下系统时间,在结束之后再获取系统时间,然后呢,我们把这个呃,N time减比begin time它的一个差值求出来,就是我们这个循环它总共的总耗时OK吧。好,那么我们接下来来看一下这个结果啊,走。对吧,大家可以看到一共用了118毫秒。一共用了118毫秒,我们把这个数据给它写进去了啊,当然这个衔接少我们就不管了,总之呢,我就用了118毫秒,把这个数据给它写进去了,好那么如果说我们现在使用缓冲流的话呢,我们来看一下这个效率啊,会不会有一些提升呢?好,我们用缓冲流再写一个。
22:07
我们再写一个buff。Test。那首先的话,你还是需要去定义这个write now。完了之后呢,我们再来定义一个发的。Writer是不是缓冲流啊,等于now?接下来的话呢。呃,我们先把这个数据清一下啊。对吧,你看我写进去之后,它读出来是这样一个东西啊。
23:03
把它清掉啊。重新写。然后这边呢,开始去实例化,这个writer等于new一个writer。把这路径拿过来。然后的话呢,是不是再来实例画八等于又一个。The writer,把这个writer传进去就OK了啊,然后在file里边把它俩关掉。B right叫ose。点对吧,把它关掉好。在这的话呢,一样代码啊,还是去写同样的一个数据,还是long number等于10万。
24:03
For循环。把它改成。定的。这边我们用b right啊b right.right方法对吧,区别就在这儿好。这边是不是同样去获取一个begin。刚才我们用了是一百一十八一百一十八毫秒啊,这个东西我们记一下啊,我们用这个不使用。不使用缓冲流。耗时118毫秒。对吧?接下来我们来看使用缓冲流,我们的耗时是多少。这边再来一个long time。等于system.minutes OK,输出n time减start,呃,点点这个 begintime.sit out,走。
25:01
看区别啊。看到没有,是不是只用了31毫秒啊?使用缓冲流。耗时。31毫秒。对不对,是不是性能将近提升了啊,将近四倍对不对,是不是将近提升了四倍啊,所以你看。就是这么一简单一个操作,所以说所以为什么我们很多时候都需要去加这个B的啊,很多同学说这边不一样嘛,都是调一个right,然后还是把这个I传进去啊,这俩有什么区别呢?啊,其实从代码层面来看没有太大区别,但是从性能的层面来看,是不是提升了四倍。这边需要118毫秒,这边只需要31毫秒搞定了,提升了四倍啊,整整提升四倍,这可是一个不小的一个,这个提升了啊,很大的一个提升了,对不对,你看数据是一模一样,都是10万嘛,而这个也是一样的。对吧,数据是10万循环也是一模一样的,我们唯独换的是一个这个数据流,这边我们用的是write,这边我们用用的是buffer buffer就是一个缓冲流,所以说使用缓冲流是不是可以极大提升我们的一个性性系统的一个性能,对吧,其实就把它速度啊,让它变得更快了。
26:12
OK吧,所以这个例子啊,大家记一下。这边是使用缓动六。OK,好。这个的话呢,就是我们说,呃,这个。缓冲buffer的一个使用。然后的话大家可以看一下啊,我们这边再扩展一下吧,就是这个buffer writer啊,它其实是有两个构造函数的。The writer。它是有两个构造函数。我们这边使用的是其中的一个,有两个呢。八的要加个ED。Brir。
27:04
一个参数的传进来一个writer。还有另外一个构造器。传进来一个writer。之外呢,还需要再传一个int类型的一个size OK。In size啊,那这两个构造器有什么区别呢?看这个都是面试的时候喜欢问的啊,构造有什么区别?它们的区别在哪呢?就第一个构造器,它默认创建8KB的一个缓冲区。它其实有缓冲区的,它并不是说没有,但是呢,它的,呃,这个。缓冲区的大小呢,是八个KB。8KB。的缓冲区好。然后第二个构造器,它的缓冲区是多少呢?
28:01
是不是可以由你自己来指定啊,对不对。他的这个缓冲区啊,可以自己指定。管桩区的大小。对吧,那你后面传这个size不就是干这个事吗。对不对。然后这边大家要注意啊,这个缓冲区你也不能给他弄太大了,缓冲区的大小呢,需要适中。需要适中,你不能说给他弄的特别大的一个缓冲区,太小的话呢。太小,起不到缓冲的作用。起不到。对不对,就相当于你这边给他来一个漏斗对吧,但是你这个你这个漏斗的话呢,他可能他可能是这样的一个,呃,他可能是是这样的一个东西啊,我给你找个梯形吧。或者就类似于这样吧。就是它的它的上下的这个。它上下这个差异不大啊,上下上下这个差异不大,你说这个能能不能起到缓冲作用,能起到,但是作用不明显,对不对,所以还是这种。
29:04
这种结构,这种结构它的缓冲区更大一些,这样的话呢,它的缓冲的效果更明显一些啊,因为缓冲区是不是暂时把这个东西存起来嘛,你想想如果说呃,也不说这个形状不一样,假如说它的它的个头本来就很小,就这么一点点东西,你说这点东西能存几个数据啊。是不是起不到特别好的一个缓冲的一个作用,所以这个东西还是要适当的。合适的一个尺寸是不是才能起到这样一个缓冲作用啊,对不对,太小的话起不到缓冲的作用,太大的话也不行啊。你不能说给他弄一个特别大的啊,这个东西不是说特越大越好。太大的这个缓冲区的话呢,它会消耗我们的系统的资源。消耗系统一个内存,给这个垃圾回收机制呢,造成一个负担啊,也不行的,所以说这个东西必须要适中才可以,太大也不行,太小也不行,任何的一个东西都是这样的啊,我们一定要去找它合适的一个大小。太大会。浪费系统资源。
30:01
对不对,然后呢,增加这个GC的。负担好。所以它的大小一定要合适。OK,这就是我们的缓冲,说完缓冲之后呢,接下来我们来说缓存啊。缓存的话呢,这个东西我们其实用的也非常多。缓存是用来干嘛的?缓存,它也是为了提升系统的性能而开辟的一个空间。也是为了提升系统性能。而开辟的。一块空间,所以它们两个作用呢,都是用来提升系统性能,但是它的方向不一样。跟缓冲不同的在哪呢?与缓冲不同。的是什么呢?与法中不同的是。缓冲啊是反复。是将反复被使用的数据呢存储起来。哎,不是缓冲缓存,缓存是将。
31:00
反复。被使用的数据呢,给他。存储起来。共程序。直接调用。对不对,供程序直接调用。避免呢程序反复,比如说从数据库里边读取相同的数据。运行程序反复重。数据库中读取相同的数据。因为我们知道在很多场合下呢,数据的获取呢,可能是非常耗时的。当这个请求量很大的时候呢,频繁的数据访问就会消耗我们CPU的一个资源,对吧?那么缓存的作用呢,就是将这些数据呢存储起来,当有其他线程或者客户端需要访问相同的数据的时候,直接从缓存里边,从缓存里边返回这个结果。避免重复去访问数据库或者其他的处理,从而呢,提升咱们的系统的一个响应的一个时间,对吧,所以这个缓存其实在哪使用的比较多呢,在我们这个。
32:09
OM框架当中使用的非常多,OM框架中使用很多,对吧,你比如说这个MY。包括harbert框架。对不对,主流的OM框架都是有缓存机制的。缓存机制。对吧,我们还是画个图啊。哎,假设呢,这是我们的数据库。DB。这个呢,是我们的加入应用程序。加应用号。换个颜色吧。对不对,那么现在假设我们要查询数据库里边的数据啊,那是不是你通过GDBC或者通过OM框架去处理就OK了啊,比如说我们这边呢,去查一查一个数据,比如user。
33:12
返回给你去用对不对,然后假如说你在另外一个业务当中呢,比如我们这个U的I等于一啊一啊,在另外一个业务当中,我们还需要再次查询ID等于一这样一个对象,同一个对象对不对,如果说没有缓存的话呢,没有缓存的话,你这边查完之后呢,你下一个业务你还得再查一遍。还是再查一遍,然后把同样的一个数据再给你返回一次啊,如果说我们还有其他业务的话,可能还是一个重复的操作,我们还会把同样的一个数据呢,再查一次。再给你返回,所以你看这样的话呢,是不是会造成我们的一个系统资源浪费,因为这三个对象是一模一样对象为什么要查三次呢。对不对,X34是不是等于多了两次这样一个数据库交互,肯定对于系统的性能是有这个损耗的,那么我们怎么办呢?我们是不是要去节约这个资源,我们是不是要。
34:01
使用这个复用性对吧,把这个复用体现出来,就是说这个对象查一次就OK了,查一次之后呢,后面两次就不用再查了,那怎么办呢?我们是不是加一个缓存啊。对不对,也就是说你查出来之后呢。加一个缓存机制好。中间加一个缓存。开始。啊,缓存是派。RK啊,缓冲是八分,缓存是catch。我们家有缓存机制。加了缓存机制之后呢,假设你现在还是需要去拿这个user,对不对,ID等于一,那个对象好I等于一,这时候你先去开里边去找,先去缓存里边去找,如果说缓存里边没有的话呢,没有的话怎么办呢?我们去数据库里边去找。去数据库里边去找,然后找到之后的话,数据库给你返回吗。返回之后,我们就直接把这个东西啊,直接给它存到缓存里边,把这个ID1这个东西啊,直接存到缓存里边啊,存到缓存里边之后呢,再有缓存再返给我们的程序。
35:03
对吧,再返给我们的程序,当我们下一次请求过来的时候,我依然是不是还是从缓存里边找,诶这时候发现A点一已经在这儿了,是不是直接返回就可以了,而不用去连接数据库了。对不对,就是这样的话,就可以重复去利用这个对象,这个是不是跟我们那个字符串常量池是不是有点类似,对不对?假设我们要使用一个字符串的话,先去常量池里边去找,如果说这个字符串已经存在,直接返回,如果不存在,我是在创建,所以这样的话呢,是不是只需要创建一个字符串对象就可以被多次使用。这边也是一样的。我们同样一个一数据,我给他放到缓存里边,第一次的话我去缓存里边查,如果缓存里边没有,我再去数据库查,查完之后我就给它放到缓存里边。当我们第二次、第三次的时候,他还是先去找缓存,缓存里边已经有这个数据了,是不是直接返回,不用去连接数据库了,是不是效率更高一些?这样的话性能是不是提升上来了。OK吧,就是这样一个区别啊好。
36:01
嗯,怎么画,这样画吧。表示可以多次使用。对不对啊,大家理解一下这个图啊,这个我们说第一次使用。第一次使用的话,你需要去连数据库,后面的话就不需要了。好,这就是缓存,所以说这就是我们缓冲和缓存的区别,你一定要去给他讲清楚,缓存是干嘛的,缓冲是干嘛的,他们两个之间其实没有什么联系,对,完全是两个东西。只是因为他的名字比较像啊,前面第一个字都是缓,后面这个字不一样,所以导致很多同学到这一块是分不清楚的。OK吧,所以说经过我这样一个讲解,大家对于缓冲缓存这块的区别应该是没有任何问题了吧。
37:03
OK,好。
我来说两句