粉丝4.9万获赞44.7万

你知道 hybrid 端口的特点是什么吗?首先我们来看一下这个 hybrid 端口它的特点啊, hybrid 端口的最大特点是什么呢?这个特点就是如果我们在交换机上面,我们使用了 hybrid, 那么数据包 在进入 hybrid 端口的时候和出 hybrid, 那我们就要考虑两种情况,第一种情况就是是否有标签,如果没有标签,比如像我们现在这种啊,那么我们的电脑在发送消息进入交换机的时候, 是否携带网络标签呢?是没有的,我们传统的数据针是没有标签的,没有微量信息的,他进入到 happy 端口,他会怎么办呢?会加上标签,打上 pvid, 我们打上了这个标签之后,微量时在这个端口能不能转发数据呢?其实不行,为什么不能转发? 因为如果哈不是端口,要想让这个数据包进去,能够发送进去,那需要满足条件,需要端口拥有 tag 或者 ontag, 对应微烂才能转发微烂数据啊。 如果这个端口没有去写 tag vlan 十,也没有写 ontagvan 十,那么他默认就只有 ontagvan 一,那么数据包进来的时候只会打上 tag 标签,但是并不能转发。但是如果我这个端口有写 ontag 十 或者是 tax, 那我才能转发。那么同样还有一种情况,就是当我们收到一个有标签的数据啊,进入端口是 不会额外打标签的,但是同样只有当有 time 或者 on time 有对应的 villain 才能转发。像这种情况,比如说我这个端口是哈不瑞的,那么并且我这个端口呢,它的 p v i d 呢?也是十,那 现在我微烂时代的标签的数据进来的时候,我会不会打标签呢?我就不会打标签了,但能不能转发呢?能不能进入到这个交换机呢?他要看这个端口有没有针对于我这个微烂的 tag 或者 ontag, 如果有才能进来,如果没有就不能进来, 那么能不能转发呢?我们要看出出呢,是这样子,出交换机的话都是有标签的,因为交换机本身进来的时候一定会打上标签,所以出去的时候我们就要看他对应的标签了。如果有 tag 属性的微烂,则对应微烂是 带着标签转发,如果说是有 ontak 属性就没标签,则不带对应微烂标签转发。比如我进来的时候,我的标签是微烂十,我这个端口呢, 如果要转发这个微量十的数据,那我这个端口呢,它得有 type 十或者 ontag 十这样的信息,它才能 转发这个数据,不然是不能转发的。那么如果有太个十这样的属性的话,那我就是带着标签发出去,如果是 ontag 微烂时,那就没有标签时,这样的话数据包发出去的时候就没有标签。

各位小伙伴们,我们通过五分钟彻彻底底理解 ref 的原码。如果你在面试的时候让别人眼前一心, 那么很多同学都知道我们这个 relative 可以干个什么事情呢?将我们的数据变成显然式的,并且他只能代理对象,现在我在这里写了个数据,对他啊,对他一个对象,那么现在我在这里干什么?写个内测,哦不,这个是通过谁?通过 relative rest, 把什么?把我们这个 data 带领一下,带着我打印一下, look 一下, 落个下之后,你会发现他通过什么呢?通过我们的 prox 来进行代理?找对象,刷新一下,他是通过我们 prox 来进行代理的。如果干个什么事情呢?如果你这里放的是一个不是对象,他会 直接给你干什么事情呢?直接返回原有的这,返回原有这来着,那么现在我们来看一下我们的原码,这个就是我们的原码,实现我们这一个 reality 的哈。那么首先你可以 control 下 搜索一下我们这一个方形 rector, 在这里干个什么事情呢?在这里找到我们这个 record 来, 找到之后,这是我们的目标对象,这个是我们的指读的,这里返回了,实现我们的显意识的。那么找到这个方法往下走。 来到这里之后,首先第一个判断你是不是对象,如果你不是对象,是不直接返回了,现在大家清楚。紧接着往下走,你会发现他会通过我们的 newpux 来进行代理,再把 pox 返回出去,说明我们的数据通过 plus 来进行代理。紧接着继续再来, 那么这几个是我们经常你需要答出来的,如果通过 rector 带你同一个数据,比如现在我这个数据,对他,我再通过 rector 来进行代理,翻过来, 现在这里变成 oppo 这个一,我们都通过什么东西?都通过我们这一个,谁呢?都通过我们这个 reto 带你同一个数据,他会干干什么?你会发现他们两个的值是相同的,他会获取你们的缓存值,把它拿过来看,打一下 包天下刷现象,这里干个什么事情呢?就是一个数据,如果你已经被 reco 代理过了,那么你再通过 reco 带来代理,他只会读取我们的缓存数据来到我们的原码,他是怎么做的呢?往下走,你没有发现这里时间代理的这个代码,这个地方啊,有一个什么呢?有一个, 我们这一个 pos max, 这个是不是添加缓存?就是将,将什么?将我们这个代理的数据代理的数据添加到啊,添加到缓存中添加到到 到缓存啊,缓存表中,添加到我们的缓存表中。那么在上面干个什么事情呢?你在调用 read to 的时候,代理数据的时候,我在这里先读取,获取, 获取数据,获取表中的数据啊,表中的数据,如果你有,哎,有说明是已经被代理了,代理呢?我就直接返回,不再执行。什么? 不再向下执行?我这个 prox 来这儿打印一下,给他们看一下,录一下,录一下,录一下,来,看一下五五,你会发现保存一下,来看效果, 刷新一下。我这个五五是不是只执行一次啊?但是我这个 reaction 五干个什么事情呢?调用了两次,你没发现吗?什么叫两次?如果我把这里变一下啊,变成什么东西呢?变一个小空对象,这里写个 a 起 a 级写个三十啊,三十,来看一下他是不是调用两次,是不是调两次,因为这两个不相同。那么这里是怎么做的呢?通过我们的缓存表添加到我们的缓存当中去,通过谁呢?通过我们的通过谁?通过我们的 new workmap, 拿着六下 workmap 来到,你可以继续来找,来看,往上走,往上走,往上走,在这里有个谁?这个是不是我们的抬高头目标对象啊?不是这个往上走,哎,找这个地方,在这里是不是抬高头目标对象?这里有五个时餐,这是个时餐方法,教用时餐,再来往下走,往下走的时候,你会 发现我们这个地方往下走,这个方法在这里根本一二三四往下移过来。五,是不是这个 这个 plus map, 那么两种 plus map, 它的实在是它的实在是不是它 come c ctrlf 一下往上走,它是通过谁?通过我们的 newwet map 啊,来创建我们的表,其实就相当于我们的 map 啊, map 创建表的只是这个可以防止我们的内存泄露,就这样的一个好处哈,就这一个好处来,下来, 下来之后紧接着再来看,再来看,来到我们这个地方放过来,现在我们知道了 red, 如果你是 一个数据,已经被那种来代理了,你再次来代理这个数据,或许缓存的紧接着干个什么事情呢?如果你再带你原有的数据也是拿到缓存的来看好,现在我这里是不 通过 return 把这个 deta 变成显示的哦,不接个头,再通过 return 又来代理数据,这个数据是不是显示的?显示之后来保存一下来看效果,你会发现同样的指值音是读取我们缓存的,这个时候他还有个操作,往上来到圆满 原版只有往上走,这里面读取缓存数据的,对不对?那么往上走这里还有什么?怎么缓存数据?还有个操作,缓存数据啊,缓存这个原版里面缓存数据啊,缓存啊,缓存我们的数据,缓存数据他用了两个操作,一个是表创建表 创建我们的表, jeffer 们给原有的对象添加属性给 原来的原来的数据添加属性啊,这里有一个看没?这里给原来数据添加属性,来这看这个代码 tiktok 目标 对象,这里面是不是有个属性?而我们之前的目标对象里面有这个属性吗?没有,是我自己在我们获取依赖的时候,进行想意识的时候干个什么来给他添加的。如果你有这个属性,直接返回原有对象啊,直接返回原有对象,那么我们这里就知道了。 如果你通过 red, 我带你的是相同一个数据,带你多次读缓存的数据,如果你带你的数据是显示数据还是读缓存数据, 还是读我们的缓存数据,获取缓存数据,他实现的方式,一个是创建表,一个是给原有的对象添加属性,这两个需要注意,面试的时候你可以把说一下,再就是 read to, 你会发现我们再来看一下,把,这里也常见, 现在我再来串一个数据,把这里放个什么歌,把这里隐藏掉下,把这两个隐藏掉,隐藏掉之后,现在我刚刚什么事?再来一下, 你会发现我们这个 reattle 代理的数据,如果是有深层次,在这里写的什么?写个 obob, 把它放过来这儿,在这里写的什么?写上 a 几啊?写上 at, 放个三十,三十之后你会发现,如果你通过 reattle 代理的数据,哎,放过来 代理的数据,当我你是深层次的时候,他该怎么实现?懒代理?什么是懒代理?只有当你获取的时候,他才会干个什么事情呢?通过 reactor 来实现代理,来看一下效果, note 一下,挪一下,我们打一下我们这 opt 键键, opt 键的 obg 保存一下,刷新一下,你会发现 我这里的数据代理的时候是不是深层次啊?但是我这个,但是我这一个五五是不是代理只执行了一次啊?只执行了一次啊,只执行了一次啊,只执行了一次。这个 ob 是不没有代理,那什么时候被代理呢? 就当我们使用的时候再来看,再来放使用点什么呢?点我们这一个 ob, 看我们使用一下来看下效果,刷新一下,看是不是现在是不被打印了,五五是不打印了,我们再把这个打印出来,看一下, 落给下落下来着,他是用的懒,带你保存下来,看效果,刷一下看是不是带你的又变成了 box。 那么这里是怎么做的呢?看一下原码,它是通过懒带你的,那么这个时候你就要找到谁,找到我们的一字,找到我们的 rector, 而 r e c t i v rector, 那么你会发现这个 rat 有点多,是不是一个找出太麻烦了?那么你要想想,我们 plus 呢,在里面是不是有 get 方法呀? get 方法的时候在我们原版里面他用了一个什么引射啊?好啊, are you for r e 换过来 r 小写 r e f left。 请你收看 get 在这里干个什么事情?找到我们这里看, 这个表示获取数据是不获取数据, get 表获取数据,对不对?因为为什么这么写?他把 get 给他抽出去了哈, 他把这个 get 为什么给出出去的这个方法,其实这个就是我们的 ctrl c 一下, ctrl 一下,其实这个就是你写的那个 get 方法啊。 get 方法读值的那个方法,为什么这么写?因为它里面做太多的逻辑,要做什么?做逻辑做成函数颗粒化。 紧接着在这里来判断一下,看,如果你是对象干个什么?如果你是对象,如果你不是只读的啊,不是我们只读的哈,不是我们只读的,干个什么事情?如果你是只读的就只读了啊。如果你不是只读什么?再通过我们的 reaction 干个什么事情啊?再来时间带你对你这个数据 属性,这是我的属性呢?属性哪一天带你。当你获取的时候,哥们会执行这个方法,获取的时候会执行这个方法,来到这里会被来到这个地方,会被打印啊,会被打印,保证一下来看,这个就是什么东西呢?这个就是我们 rectable。 你在答的时候干个什么事情要把这个给答出来,不要只说他是响应式的,通过 praise 只能代理对象,你还要把它这些给答出来,那么后面继续关注。我后面会讲,诶,他们怎么让我们试图进行更新的啊?怎么来进行处理的?

各位学前端的同学,如果你想成为三十 k 以上的架构师,那你一定要理解依赖注入。为什么要理解依赖注入? 因为它能大幅提高附用性,降低业务开发难度。什么意思呢?就比如打印信息这个功能。实际工作中, note 中开发环境的信息一般是直接在控制台输出,而生产环境呢,一般是放在一个日制里, 使用的时候会根据环境来去判断我要用哪个方法。那如果我现在在另一个地方也需要打印,那我就得把这一坨再写一遍。 所以呢,一般来说,我们会把这个东西啊抽成一个公共的方法,这样我在别的地方如果需要打印,我只需要调用这个方法就可以了。好问题来了,如果我当前的项目不是一个工程项目,它没有 process 对 象,或者说我当前的环境是一个浏览器环境,它不支持文件模块, 那你这个方法还能用吗?如果不能用,那这个方法的使用场景就很受限,你必须是工程环境的 note 项目,那这肯定不行啊,作为一个合格的架构师,你肯定是希望我抽出来的这个方法能在任意环境都能正常使用,那这时候就需要依赖注入了。 那什么是依赖注入呢?想理解这个,你就得先理解什么是依赖。依赖就是一个代码单元想要完成其功能所需要的任何外部资源,就比如像这里的 process, write to blog, 还有 console, 这些对象和方法的定义都不在这个方法里,所以它们就是外部资源,也就是依赖。那依赖注入呢?依赖注入就是一种架构模式,对于函数来说,就是通过参数的形式将依赖传进来,从而实现控制反转。 就比如我们经常实现的最简单的求和,还有像组建里的父子传职,都是依赖注入,就是我只关心我要做的逻辑是什么,至于你这个职具体是什么,或者说这逻辑里需要的一些实现,我并不关心你给我什么,我用什么。 那这也太简单了,还用得着讲吗?那就要看你用的复杂程度。咱们再说回咱们的刚才这个系统,假如说我想让公司里的所有前端项目在打印的时候啊,都只用一种写法,就是不管你环境如何,是 node 也好还是 web 也好,我都可以使用。 那这个时候就需要设计一下,像现在的这个方法,它只能在 node 环境里用,外部环境用不了怎么办呢?我们呢可以抽出一个公共的方法,这个方法接收两个参数,然后返回一个对象,而这个对象呢,也对应着两个方法。然后我们不同项目一般都会有一个公共的 utos 文件,对吧? 我在这里比如说 web 的 utools, 我 导入这个公共方法,并且给这个方法注入 console log 和 console arrow。 因为你是 web 环境嘛,所以基本上你的打印只能用 console, 那 在 node 环境中呢,我就对你的这个 create log 注入 write to log 和 write to arrow 的 方法, 这样我在 no 的 环境中同样是调用 log info 这个方法,这样就实现了不同环境下我的写法完全相同,但是呢,它实际执行的逻辑是完全不同的,所以说依赖注入实际上就是将逻辑 与实现完全的分离,这样就可以让我们同样的写法,但是可以适配多种环境。

好,各位学前端同学,像 e s 模块化是咱们面试的常考题,而在这些考题里边有一个非常非常重要的大题,就是让你解释一下整个 e s 六模块化的解析过程, 它到底是怎么运作的?那要回答这个问题的话,首先你要确定一个范围,就是我们的 e s 模块化啊,它在浏览器里面可以支持你,像这种情况,对吧?写个 type 等于 mark 九,然后呢导入一个 g s, 它就是在使用 e s 六的模块化来解析模块, 除了浏览器可以支持之外呢,在一些工程化的环境里边,像什么 wifi 啊, vs 啊,它也可以支持。所以说我们要限定一个环境,只在浏览器环境里边讨论,因为这种面试题呢,它只在乎浏览器。那么这里呢,我们就以一个例子啊,来分析一下它整个的模块解析和执行的过程。首先第一步他要做啥呢?要做的事情是模块的解析,所 谓的模块解析呢,就是把那些相关的 gs 文件全部下载下来,那他具体是怎么做的呢?首先他会找到这个你入口的文件 mate gs 呢,他会把它转换成绝对度记。 然后呢就开始下载了啊,整个下载过程呢,需要耗一段时间,它会等待,等它下载完成之后呢,它会进入到这个 g s 里边去看看啥呢?看的是它顶层的静态导入语句, 你看这些动态的导入语句呢,它是不看的,为什么是顶层?也就说它写到什么循环呀,判断里边是不看的啊,而且呢它有不符合语法。像这些静态导入语句啊,是不能写到判断和循环里, 他必须写到顶层。好,他找到这些静态导入语句之后呢,他会把它提前提到整个代码的最前面,这也在告诉我们,我们平时数学代码的时候啊,要注意一下规范,像这些静态导入语句啊,你不要把它写到中间,也不要把它写到后面,你 写了也没用啊,浏览器呢,有纠错机制,他会把它提前好,提前了过后呢?然后呢,同样道理,又去第一规的去下载,并且解析对应的 gs, 因此呢,他针对这个负点 gs, 负点 gs 又会去进行下载啊, 下载完成好,等他下载完成了之后呢,还是一样的道理,又会进入他们对应的 gs 文件里边又去看。好,那你看这个负点 gs 里边是不是还是要导入这个八点 gs, 对 吧?因此呢,这个负点 gs 呢,他有一个依赖,依赖八点 gs, 而这个八点 gs 呢,已经下载过了,或者是正在下载中,那么他就不管了,他只管那些没有下载过的,而这个八点 gs 里边呢,就没有什么依赖了。那么第一步就完成了,我们的所有的模块文件都被下载到了本地, 那么接下来就会进入第二个步骤,就是模块的执行,他要开始执行代码了。执行代码的时候呢,也是从头开始啊,从入口文件开始,先进这个微调键 s, 进了这个微调键 s 之后呢,你会看到啊,他首先遇到了这么一句话,那么这句话呢,会导致他进入负点键 s, 负点键 s 第一行代码呢,是这个,那么又会进入到 bug 键 s 啊,就这么个意思, bug 键 s 第一行呢,就打印啊打印,于是控制台里边多了一个 bug, 然后 bug 键 s 呢,就执行完成了啊,默认导出啊,是一个 bug, 一个字母串。那么注意啊,这里他的默认导出会变成什么样子呢?他会给这个模块呢,生成一个表格,每个模块最终都会变成一个表格, 表格里边会记录这个模块他导出的结果,他为什么要记录呢?是为了方便缓存,你后续再去导入这个 bug 的 时候呢,他不会从头到尾运行了啊,只会从这个表格里边取出相应的结果,直接给你好,于是呢, bug 点 js 运行完成好,运行完成过后呢,又回到负点 js 啊,那么这一会呢,他又导入了一个 bug, 他 把那个默认导出了,放到这个标识符 bug 里边。 那么这个时候注意啊,整个 js 里边出现了一个非常特别的地方,他这里不是一个简单的赋值,不是说把这个字母串赋值给这个变量 bug, 不是 的,他们做的是一个符号绑定, 就是这个 bar 啊,和这个 default 啊,它用的是同一个内存空间,这在整个 gs 语言里边是绝无仅有的,它叫做符号绑定这一块,如果说不小心的话,会给我们开发了造成一些问题。之前呢,我有一段短视频啊,也详细的讲过啊,有兴趣的同学可以往前翻一翻,当然,我更加推荐的是你直接来看我的大师课,大师课同样是免费的啊, 但是呢,跟短视频不太一样,短视频呢,时间有限,只能解决你工作当中的一些小问题,讲一些小知识啊,小技巧。但大师课讲的是要解决你薪资高低和职业生涯的大问题的。 虽然呢,这个大师课呢有一定难度,但是整个课程是沿着前端技术的根源展开的,可以说大师课里边的内容是整个前端技术的中疏,是前端最核心最根源的东西,以至于其他的任何前端知识都是在他们基础上生长出来的。因此呢,你只要把大师课搞定了,其他的很多前端知识基本上就一碰就会,一碰就明白。 所以说,无论你是在哪个阶段,大师课永远是你需要最先搞明白的东西。关键是个课呢,目前可以免费领啊,怎么领?在咱们账号主页,点击头像进入账号主页,点击提示领取。完事了啊,好说回来啊。呃,然后呢,这里得到了这个字母串 bar 啊,然后呢进行打印,打印出来一个负 bar 啊,然后这一块也有导出,对吧,导出的结果呢,也会形成一个表格啊,就这么个意思。 然后接下来呢,就运行到 v 点 g s 的 下一行了啊,就这一行的话,因为这个 bar 啊以前已经运行过了,所以说拿到这个结果过后呢,就得到结果了啊。 接下来是一个动态导入语句哎,这个 g s 呢,以前没有下载过,所以说一样的道理,先去进行下载解析啊,不过呢,这个过程呢是异步的需要耗时的吗?因此呢,整个主县城呢,是不需要等待他的,直接往后运行啊,打印这个相应的结果。那么媚的 g s 呢,运行结束 好,那么现在呢,等到这个模块下载完成之后,那么是不是进入到这个模块代码又同样道理进行模块解析啊,这里呢也有导入这个 bug 呢,已经有这个结果了。然后呢,这里也有导出啊,导出呢也会生成一个表格,是一样的道理啊, 那么至此呢,这个模块也运行完成了,然后呢,这个任意方法里边的回调就可以调用了,因为这个 promise 完成了吧。好,那么这个任意方法里边的 m 这玩意是啥呢? m 就是 这个表格啊,就是它,所以说这一块呢,打印的结果呢,就是相应的结果。 好,这就是整个 es 模块的解析和执行过程,一共是分为两步,先下载解析,然后呢再依次执行。每一个模块的执行过后呢,它会生成相应的表格来缓存它的执行结果。抓住这些关键点,这个面试题呢,就很好回答了。