00:00
人们5000块啊,大家好,刚才打断一下啊。呃,我是上回谷的卢老师啊。好,我们声音就大啊,今天主要给大家讲一下这个找朋友啊这个小项目。啊,首先看看需求,然后他就是说什么呢,就是一个很小很小的表。是吧,需求就是说,诶其实这个与其说好友,不是说是粉丝啊,因为他都是单向的,A有什么B粉他,C粉他,D粉EF粉他,E粉他,O粉他是吧,就这种类型,然后找AB之间有共同有哪些粉丝,它其实就是。处理一个这样的一个需求。然后看着需求是吧,有很多很多想法是吧。文档上我那个方法我也看了是吧。呃,就如果说整只针对于这么小一个文件啊,这种需求而言。
01:02
觉得文档上的方法是比较反人类的。因为你想你正常人,你你看我,比方说我和蓝翔的朋友,那肯定是我的朋友,哪些蓝翔朋友哪些,哎,我们中间。教一下对不对。你不会说把朋友全部倒过来去看对吧?我第一想法就没有,没有是按照那个文档上那种走。然后。我第一想法是什么呢?大家看这个东西。这个东西像像不像一个迪卡耳机一样。实际上就是A,我把里面的有哪些粉丝,我分别跟这他自自身重新全部比较一次。我就可以得出其实它有哪些,最后你再进行一次筛选,当然这是第一种方式,没经过优化的,就所以这个东西啊。就像像一个什么呢。这个东西就像个矩阵。一样,你看啊,就A与AA与BA,当A与A自身啊,A与BA与CA与DA与E。
02:00
就这一张大表,就是一个完,是一哈机嘛,就是完全交集嘛。然后呢,这种方式呢,其实有些东西是多余的,比如说这条对角线上的所有数据也是不要的,比如说你自身和自身那不存在关系,然后这个对角线右上方也是都不要的,因为你A和B与B与A其实是同样的。两个同样的人,你的好友数肯定好友人数肯定是同样的。所以说基于它又衍生出了一种这样的东西,就实际上我们求的就是白色的,白色这一块,这个需求就是说白色这块有的哪些BB跟A的是吧,然后C跟AC跟B是吧。是实际上,实际上最终得出的结果应该是一个这样的。呃,然后就是代码是怎么怎么怎么思考的,我是通,第一种就是方式,就是通过这种。加载的缓存里也不叫缓存,加载我自己内存里,就是我把整个表啊,我。加载进自己的内存。
03:01
那然后放了这个给了个催麦,然后把I行数据。你假如说A有A这个master是吧,我就作为它的这个。然后后面他哪些好友作为一条value,一条一条逐行读到这个map里去。然后呢?我进入map这个流程。这个业务去怎么实现呢。呃,首先啊,这边这个图就是说他这个没画完啊,这个篇幅文件。就就这个map,就是经过setup是吧,初始化环境初始化之后我。把所有的内容全部加载进来了,就是右边这个,这时候我一条数据进来了,我第一步我先把这个按冒号切分。我A这边是master是吧,BCD,然后我又按逗号切分,就把他这些等一下好友拿出来了就。就分成这两个,这时候。进行一个什么操作呢,我把这个B。
04:00
第一个数。跟。这个里面呢。假设第一条记录,我把跟他的好友,我去判断他是不是在这一串字符串中。如果在,那就代表他们有这个好友。那同样的第二个数依次做,然后做个循环。也就是这边这个整个步骤,然后如果说假如说我B在这里面,哎哟,这。情况。B在这里面我就把它,我因为我这边初始化了一个空,呃空的。那个,然后我就把它拼接起来。没有一个我就拼接进来,你有没有一个拼接进来,然后当然这个这种写法,你最终要注意的是,你在写出去的时候,要把。结束时要把它重新制空,否则的话。他会会有有所影响。然后。这就是,呃,这就是这个有点像什么,就是刚才那种写法,就是完全的一个。
05:00
一个矩阵,那么把所有的全包含进去,里面包含了自身与重复数据,那么在reduce中也做一次过滤,就在这边。如果说我我我把它包到了一个buffer里面,然后把它倒过来,如果说。他有有这个东西,或者有它倒过来的,或者是它是一个空的,那我都不要,其他的我依次写出,那么最终就可以得出这道题的答案。给大家提供思路。然后这种写法就是。会产生很多垃圾、不必要的数据,那么怎么去优化它?那。怎么去优化它,就是说你后来你就想到我。这张表。这个东西。你是看你再仔细去看,就是B,实际上我跟ABC跟AB比,D跟ABC比这个像什么,就是我跟都是前前面已经输出过的东西进行比较。
06:07
那么基于它的优化算法就就出来了,就怎么说呢,就是我进来一个数据进来一条。我去判断这个map这个圈外是空嘛,所以风一起的时候,它是也是个空嘛,它就不存在,它就走掉了,然后我把这条数据加进去。接来第二条,然后我去跟他在for for一起的时候,For循环的时候去比较,诶我发现他有东西,那我就还是按照上面那种思维思路,我去跟他比,然后比完,如果有我就往外写,然后把它再加进去。第三个数进来,我跟前两个一起比,就先比这个,再比这个。然后比完写出去再加进去,这样的话就相当于数据量你少了大概估计有1/2,其实不准确了这个数。嗯,这个就是。优化后的就是我直接不用加载数据了。
07:00
然后然后因为我不修嘛,我直接就可以把reduce阶段就直接干掉了。就我只需要map map阶段我出来就可以得到最终的数据。那么大家想一想看,像这种东西啊,它的优缺点在哪里啊,就优点就是它很小对吧。很快,那是建立在他的需求,问需求,建立他需求上,就是这个需求,你的输入文件很小,那我用这种方法是OK的,没有问题的,尤其像这种优化,优化过后的那是完全没有问题。但是如果你大家设想一下,如果它这个东西一旦超过了快大小,会发生什么样的情况,它发生切片。那你每个切片都会setup一次,那你。就相当于你比较的数目就变少了,我可能第二次,我第二次进来的第二个切片的数据,我没有第一个切片中的数据。那我没法进行。比较是不是有共同好友,这样的话,你汇总出来的数据就会就会发生缺失,那就是就优化后。
08:00
的缺点,然后但是如果优化前呢,是可以去做这个东西的。但是怎么搞的,那就很浪费空间,比如说我一个G的数据进来了,我内存首先要加载一个G。然后我才能执行这种方法。所以说这个。只能说根据需求来吧,如果说这种需求很小的话,我觉得这种方式是会比较优一点。哦,然后我今天的。分享就这么多了,然后给主要是给大家提供了思路,然后。大家有什么问题吗?跑一下,跑在我肩上。那个各位组长打分发给这个班长。
10:51
假三马就行,不一定用跑,不一定非得跑。
11:00
呃,这个需求,呃。反正大家都已经很清楚了。这个需求大家都很清楚,就是有这样一个表格,然后前面是。一个人,然后后面是他的一些好友。然后的话。然后这是我的分析的一个思路,就是。根据一个呃这样的一个表格,然后把它转化成map就是。全部都转化成map在呃,就转成呃,中间这个这个样子,然后呢,就把这个map嘞,就每次就取出。从迭代的取,就是第一次取A,然后第二个就取B。然后当然,然后就取出这样一个数据,然后就把他们俩呃放在一起做一个交集。然后做一个交集的话,就得出他们的公共好友,然后依次这样去迭代,然后就。可以了,然后在A跟C就这样再取,然后A跟D1直到最后一个一个人,然后求共同好友,然后。
12:08
再从再从B到CB到D,一直到最后一个,然后一直这样迭代下去,就相当于说。就相当于说就作为做两次迭代,然后就把所有的好友就这样两个两个的取出来,其实思想很简单,就是任意取出两个人,然后他们的好友取个交集,就是他们共同的好友,然后输出来就可以了。这就是。这个思路。然后。代码的话。就是map阶段,Map阶段很简单,就是读取的数字数据进来之后,就是这样的一个数据,然后以冒号切割,它就分成两个两块。第一块呢,就把它写到K里面,第二块就写到呃,Value里面。
13:01
然后相当于第一块的话就是一个A,第二块就是他的好友,然后这就是map,然后再传到reduce里面。然后在里面呢。然后就。就相当于说先定一个map,定一个map,然后就是把A把前面的一个人当做一个。呃,K,然后把那个好友啊当做one,然后全部就是写进来一个就加到map里面,写进来一个就加到里面,然后就相当于说实现了刚才刚才那一步。把刚才一个表全部转化成map,这样一个一个过程,然后呢。呃,这个阶段呢。这个阶段就是实现,就是怎么去迭代取出,分别取出这样这样的一个好友,然后呃。呃。这个呢,就是把那个map的所有的主键取出来,就是把所有的人取出来,就是前面的K全部取出来,就是A到O的一个。人取出来,人取出来之后,为了把它。
14:02
把它相当于说,呃。这个就是把它转成一个数组,因为它取出来之后是个集合,就是这是这是前面我们学过的map,怎么去取它的主件KK3,然后取出来之后呢,因为是个集合,要把集合转成数组。然后转成数组之后呢。然后就开始迭代,迭代,然后呃,这三这四步呢,其实很简单,就是就是取出来一个A值,取出来一个就是map。就是这是第一个,呃,从零开始就是取出第一个的。第一个的一个主键的一个K值。呃,取出他的一个不是取出他的一个就是好友。取出他的一个好友,然后把他好友,然后以逗号切切割开,然后切割开了之后,相当于说这一步就是相当于说把他的好友就是做成一个集合,做成集合封装到这个里面,把第一个人的封装到第这个里面,然后这一步呢,就相当于把第二个人的封装到第二个集合里面。
15:04
然后呢,就是两个呢,求一个交集。就是第一个交集第二个,然后他结果是存在第一个里面的存。在第一个人的好友里面,然后再把这个嘞,再转化成为一个。数组。转化成数组就可以了,相当于这就他们的好友就求出来了。So,就是他们的一个好友,然后这一步呢,就相当于说把他们的好友拼接成为一个。字符串。然后在这呢,就是相当于说,因为有的人他是没有共同好友的,所以要把共没有共同好友的人呢,给他去掉,所以说就是如果说。呃,拼接之后这个共同好友是零是个是个空的话,然后他们就不进入这里面,然后这里面就是拼他们一个好友。啊,第一个第二个。然后共同好友。所以。然后这一步就就相当于说把那个写进去,因为呃歪扭直接是没有的,直接都封装到这里面去了。
16:09
然后就是那个。最后一个。说啊。课件在哪?
17:29
呃,那个我。我那个首先看到这题目的时候是想他。那个。说这个数据。首先划分的时候,这里有个冒号,还有逗号进行划分,还有另外一个问题就是这些数据其实很小。但,呃,如果。如果以后工作或者什么其他就很大量的数据的话,我们应该怎么做?那时候想了想。好像。
18:01
都需要去比较一下,看你你的好友跟我的好友有没有相同。涉都涉及到比较就。你觉得?应该。实际想不出什么优化的方法,然后就只有跟大家那种方法差不多就是。拿出A,他的好友和接下来BCDEF进行比较。有的好友进行,就是把它,如果呃A和B它有好友相同,就把它存储起来。然后呃,我那个。代码实现是。先用。呃,先创建一个,呃。呃,List集合来存储这个用呃用户用户名,然后在创建一个list来存储那个好友好友集。然后呃,还有创建一个pass。来存储呃,他们最终输出的结果就是呃,A。
19:03
呃,A-B,呃。的好友A-B深圳第一个的key,然后好友他们的共同好友是后面这个,呃,第二个。然后这个。呃,刚开始进来就是用那个TV进行,呃,切割就用冒号进行切割,切割首先切割出那个用户。用户ACD,然后存储在那个用户里面,然后第二步,呃,第二步用map来用逗号进行切割。呃,把那些呃那些好友,他的好友存储在好友集里面。然后第三步再进行。首先,呃,首先进行。呃,获取。就进行。呃,如果AA第一个的话,就A到接下来的那些好,呃,用户进行。
20:03
比较。然后第一步A。A。加上那个用A的用户,加上拼接上杠号,再加拼接上那个。呃,第二个第三个的用户进行拼接获取用户组合存储在那个。哈妹里面。然后第二个进行获取,呃。获取A的用户,第一个用户。然后跟呃第二个的用户进行遍列,就A。呃,A的就第一个B的好,呃,B的用他的A的好友是B,然后用这个B去跟下面的好友进行并列,如果有相同的话,好就把它存储起来。然后就,呃,经过两就。经过,呃。整个病例就把那个他们相同的好友取出来。然后就可以得到,然后最后一步在这个有个cleanup里面有个呃,在进行。
21:06
呃,把那个都写到。都写到那个reduce里面,然后里面其实也没有。用什么直接就把它输出就来就就好了。哦。然后就这样,就。我发吧,应该。大家都差不多这个方法吧。
22:36
我是直接用的那个文档里面那个那个思路啊。之间。先取出啊,得到一个,比如说A,它分别是哪些用户的好友。B是哪些用户好友?C是哪些用户的好友?第一是哪些用法呀,这样。
23:00
然后。这里就是。跟。第一个的那个一样,就是把这个。把这个结果封装成好友人,然后输出。然后我这里用了一个。么来就是处理它那个中间结果。首先是com reduce来获取它那个第一步的那个结果。就是这样。然后把它放到一个map里面。空间结果传来。然后。在cleanup里面。那个便利,那个map。便利便利,他便利那个麦就是。相当于做那个文档里面第二部的。把它。换成那种就是AAB,然后。
24:02
他们的共同好友是谁?那样?然后把那个结果放。看到应该不是练。就是这个,这个就相当于存储那个。最终的那个结果。陈述完了之后,然后便利便。那个将它呃封装,然后写出。然后再是从。里面写出那个最终的结果。
25:04
喂喂喂。等一下啊,这个。
26:16
呃,我的思想跟第一组,第二组,第三组的核心思想是一样。呃呃。第二三组,呃,写的很棒,然后呃,可能我们之间的差异就是。呃,个人用的一些小方法不一样。呃,我代码也是跟第一组与工一样,呃,只有一个。那就只有这么一点。流行的。然后先说一下我的思路啊。讲慢一点,呃,首先大家拿到这个需求,肯定第一想法都是跟我一样,呃,直截了当就是,嗯。
27:04
两个两个一起比嘛,比他们共同好友嘛,首先A和B比,然后A-B串起来,然后他们之间之间的共同好友就是C和一嘛,比完之后,然后A和C比,A和D比,A和一比,然后一是这样,呃,相当于快速排序的那种比法。呃,但是要注意一个事情,就是说外它只能是一行一行一行的这样读完,然后读完之后它就输入出去了,所以我们必须要把这个文件,嗯。先缓存到那个呃,Job里面去,然后再从那个map map阶段的那个setup。提前把这个文件呃拿出来,呃,我思路是这样子,嗯。就是把这个整个文件缓存进去了嘛,在外那里拿嘛。拿出来之后,呃,对他先做这么两件事情,第一个首先将他这个所有文件每一行的这个人嘛。
28:03
前面这一行是人嘛,这一行就是他他人的好友嘛。嗯,就是把ABCD1直到O先放到一个里面去。呃,放进去之后呢,目的是。好好好比较嘛,就是说我放进去之后直接编辑这个例子的,然后就可以直接呃A和BA和C,呃A和D这样比嘛。但是我我的目的是要比他后面那个好友嘛,并不是比这个人嘛,然后我还要将这每一行的数据,同时呃把放到一个哈map里面,呃,他这个左边这个人作为那个key,然后后面这一串这一长串整个作为这个value放到哈map里面去。然后放进去啊,放进去之后呢,嗯。呃,我就呃,首先呢,我还是要用一点外的。
29:02
呃,切割就是读一行切割的一点特性。呃,放进去之后,嗯。首先呃,Map读取一行嘛,从第一行开始读嘛,读过来这是一行。然后嗯嗯。读过来之后,呃,我首先。呃,这个A,嗯。这个A找出,呃,这个A在这个例子里面的这个索引位置是几?呃,因为这个我是逐同行去放进里面去的。呃,他就是相当于先进先出。呃,它那个导出它索引当然是是零嘛,对吧,零的话,然后呃,我定位一个循环就是呃。我定位第一次的循环就是嗯。Ii等于I等于零嘛,I等于零,从这里比,然后就是说。
30:00
拿到了,呃,我这里第一,呃第四次读到了第一行,然后我呃循环。就是说拿到第一行的A,然后我再从。呃,通过第一行A这个作为K,去他map里面拿,拿他的那个外点值。拿到之后,我我再通过,呃。嗯,我再通过这个第二个索引,第二个索引就是B嘛,我。拿到B,然后再通过这个B这个K嘛。这个key去哈金里面拿,拿到它后面一串窝底这个值,然后呃,再把第一行这个逗号切开,第二行逗号切开,然后一个快速排序的一个小算法,然后以相同的呃,首先是E跟ACEEK,然后CCD,呃,CCCEC这样比,然后如果是相同的话,然后我会把它拼接到那个street build里面去。
31:07
呃,Studio的线路不安全的,效率高点,拼接到一起,就比如说我先把C跟一拼接在一起,一个字符串。然后A。杠B也拼接到一起,作为一个字符串。然后呃,这个作为呃,A和B1杠作为T,然后CE作为Y,然后直接把它写出去这样子。呃,然后下面呃,依次读第二行的时候。呃,不,这还没完。读完第一行,然后A跟B比,A跟CA跟DA跟一,这样依次比比比,比完了之后把它输出。呃,输入出去,就是说这里有个小问题要注意一点,就是我最外面这个大循环,这里只能循环一次,因为一次只读取一行。然后最里面这个循环就是从第二从第一个的加一开始比嘛,然后一次从比到O嘛,这样比。
32:08
然后就这样子,就比比。然后第二次读的话,从B开始读嘛。然后也是只循环一次,然后他比的话只能跟C比。然后一直比,比到。呃,只能只能这样搞,不然你这里如果你两次或者以上的话,它会产生很多重复数据是无效的。呃,比完之后差不多就可以。你就可以直接输入出去,我先运行一下。海哥,那个原文件在哪里?我们一起给大家看一下。
34:29
试一下,先看一下楼底下有没有。
35:35
大家稍等。
36:00
在我份那个。
39:09
行啊是吧,呃,应该是这个考的时候哪一方呢。好沉啊。我相信它那个电脑上一定是能。我就稍微调一下就OK,嗯,行,班长同意出来吗?行啊,能能感觉到啊,大家都是做这东西非常用心的啊呃,能看到这个大家这么用心的去做这个项目啊,我就我就放心了啊,因为。能感觉到大家非常聪明,真的很聪明。呃,我看大家这个都喜欢用。内存啊集合。玩的都很溜啊,包括这个各种循环啊。呃,70哈。呃,在开发中,呃。
40:00
还是要少用啊或者啊。因为这东西。真的很宝贵很宝贵啊,用的特别多,你在你的内存中啊,加载了大量的数据。这也是风险还是很高的哈,很高的。而且有一些,呃,你内存就那么大啊,非常少,你像磁盘的话,你可以很多很多无限的往里扩展,都没什么大的问题啊。当然了,你像这种这种算法类东西哈,你可能就得用一些这个集合来处理啊,会更好一些。呃,能感觉到确实很聪明啊,这个跟。呃,其实没给你们讲的一个是公安局的一个项目啊,那个跟这个差不太多啊,找好友们这个东西啊,里面用到的技术啊,各方面,呃,都是咱们讲过的啊。挺好的,我觉得这个小吴这个那个思想还是。哎,这少画那个图啊,很形象啊,就是说这个。变现的这个。这结果人都打完分了才说的啊。
41:02
还是挺有思想的,包括这个,呃,像这个第二组,第三组第四组我。都可以啊。至少我觉得都比我那个。强是吧,所以说我就说这东西它一定是,呃,有很多种方式去实现啊,并不是说这个某一种啊实现的这东西,呃,包括你在开发中也是啊。这东西是你必须要不断的优化迭代,优化迭代这个过程代码不是你一下子就写的,就是非常非常非常好啊,它需要一个不断的一个打磨的过程啊,就跟你看咱这个上课笔记是一样的,这个笔记如果说你这个今天这样,明天这样,后天这样啊,一直都是这样的话。那你东西早晚会被淘汰的。是一定的道理啊。行啊。
我来说两句