当前位置: 首页 > Web前端 > vue.js

本以为精通Vue,没想到被前阿里大佬虐哭了......

时间:2023-04-01 11:23:11 vue.js

本以为自己精通Vue,没想到却被阿里前老板虐哭……我是一个入行一年多的前端菜鸟。去年夏天开始考虑换工作,先后面试了几家中小企业。我一般会把面试过程记录下来,方便面试后回顾。整理了几次采访回放的笔记。希望对有类似情况的朋友有所帮助。也方便我以后回忆。希望每个人都能找到自己想要的工作。公司概况:坐标上海,教育行业,前端团队20+人。面试官:前端负责人,前阿里P7老大,硕士毕业转投阿里。技术栈:团队目前主要使用vue,后期计划采用react。面试结果:失败o(╥﹏╥)o。面试心得:面试官亲切,遇到不懂的问题会适当指导,最后给出改进建议。我觉得自己收获了很多。明明被虐得很惨,但还是很开心。面试题目说明:题目末尾的数字代表你当时回答的分数,?表示后面会有题目重新排列。使用vue和react有什么区别?2?vue双向数据绑定的原理是什么?数组更新。8?组件之间的通信方式?Vuex的实现原理?状态改变如何导致视图改变?6?为什么选择uni-app?8(搜索查看电商小程序后)你会做哪些部分?图片加载问题,为什么不在水平方向使用intersectionobserver?IntersectionObserver随浏览器一起提供。7?为什么要做直播外挂?8你做过哪些项目优化?5?webpack配置,loader和plugin的区别。如何去除冗余代码?tree-shaking的实现原理。5?新的路由,怎么知道要下载对应的文件?(扩展:动态插入js的方式)2?按需加载?有哪些途径?你最后选择了什么?5缓存,强缓存是谁设置的?html文件会被缓存吗?4?cdn内容分发系统?为什么你项目的静态资源文件没有放到CDN。5?使用腾讯云的手机直播和即时通讯SDK有什么难点?4?sentry错误监控,错误是如何收集并上报给平台的?(http、websoket、跨域)2?某项目(简历中),详细解释一下?8项目中遇到的困难和挑战。4问题2VuevsReact的相同点:使用虚拟DOM+Diff算法。组件思维。区别:模板语法不同:react通过JSX渲染模板,vue通过扩展html语法渲染。比如react中的插值、条件、循环都是通过JS语法实现的,vue是通过指令v-bind、v-if、v-for实现的。监听数据变化的原理不同:vue通过getter和setter劫持来通知数据变化,而react采用比较引用的方式。vue使用的是响应式数据,而react是不可变数据。Vue改变数据直接赋值,而React需要调用setState方法(用新状态替换旧状态)。问题3vue响应式原理level1:在vue2.0中,响应式实现的核心是ES5的Object.defineProperty(obj,prop,descriptor)。Object.defineProperty()劫持data和props各个属性的getter和setter,getter做依赖收集,setter派发更新。总体来说是一种数据劫持+发布订阅的模式。level2:具体来说,①Vue初始化阶段(Create之前和create之前),遍历data/props,调用Object.defineProperty为每个属性添加getter和setter。②每个component和每个computed都会实例化一个watcher(当然也包括每个customwatcher),订阅用于渲染/计算的data/props/computed,一旦数据发生变化,调用setter,并通知renderingwatcher重新计算和更新组件。问题4vue组件通信level1:props+events父子组件通信(parent/parent/parent/children)、vuex任意组件通信、事件中心emit/emit/emit/on任意组件通信、attrs/attrs/attrs/listeners后代通信(提供/注入)。level2:vuex运行机制:vuex的状态作为一个仓库,提供数据驱动的vue组件渲染。view通过dispatch来dispatchaction,一些异步操作可以在action中进行。动作或视图通过commit提交给mutation,mutation改变状态。level3:源码分析:vuex其实是一个Vue.js的插件,所有的插件都需要提供一个install方法,install方法的调用会将Vue作为参数传递。vue.user(plugin)安装插件,即执行插件的install方法。全局会混入一个beforeCreate钩子函数,将实例化的Store保存到所有组件的this.$store中。level4:突变改变状态,会触发视图改变的原因?通过vue实现,【实例化vue,使用state作为数据属性。]??核心让Vuefunctioninstall(_Vue){Vue=_VuefunctionvuexInit(){constoptions=this.$optionsconsole.log('vuexInit->this.$options',this.$options)if(options.store){////根据实例this-->Vuethis.$store=typeofoptions.store==='function'?options.store():options.store}elseif(options.parent&&options.parent.$store){//组件实例this-->VueComponent,如APP,Home,About...this.$store=options.parent.$store}}Vue.mixin({beforeCreate:vuexInit})}classStore{constructor(options={}){const{state={},mutations={},getters={}}=optionsthis._mutations=mutations//getter实现原理constcomputed={}this.getters={}for(let[key,fn]ofObject.entries(getters)){computed[key]=()=>fn(this.state)Object.defineProperty(this.getters,key,{get:()=>this._vm[key]})}this._vm=newVue({data:{$$state:state},//核心原理计算})}commit(type,payload){if(this._mutations[type]){this._mutations[type](this.state,payload)}}getstate(){returnthis._vm._data.$$state}}exportdefault{store,install}问题6IntersectionObserverlevel1:推断节点是否对用户可见,可见的比例是多少,也可用在IntersectionObserverWebAPI中。level2:在Web的基础上封装了小程序中的IntersectionObserver,通过createIntersectionObserver返回一个IntersectionObserver实例。实例方法包括relativeTo、relativeToViewPort、observer、disconnect。relativeTo和relativeToViewPort,相对于指定元素或视口的指定位置。observer(selector,cb),观察指定节点,可见性变化时触发回调。level3:WebAPI,新的IntersectionObserver(cb,options)。在options中配置root和rootMargin可以实现小程序中relativeTo和relativeToViewPort方法的效果。另外thresholds属性也比较有意思,指定交集比例时触发回调。问题8项目优化去掉了生产环境的控制台打印。解决方案有很多,esling+pre-commit,使用插件自动移除,包括babel-plugin-transform-remove-console、uglifyjs-webpack-plugin、terser-webpack-plugin。最后,我选择了terser-webpack-plugin。脚手架vue-cli使用此插件启用缓存和多线程打包。无需安装额外的插件。你只需要在configureWebpack中将terser插件的drop_console设置为true即可。最好养成良好的编码习惯,等开发基本完成后,把没用的console去掉。vscode中的turboconsole就好了。按需加载第三方库。echarts,官方文档使用配置文件指定使用的模块,另一个使用babel-plugin-equire实现按需加载。element-ui使用babel-plugin-component实现按需导入。公共样式,比如element-ui部分组件(如弹出框、表格、下拉选择框等)样式的统一调整。常用的组件,比如date-picker、upload-file等,基本都进一步封装在element-ui提供的组件中。自定义组件包括预览文件、搜索框等//babel.config.js配置如下:plugins:['equire']//echarts.jsconstecharts=require(['line','tooltip','legend','dataZoom','grid']);导出默认echarts;在前后端数据互通方面,推动项目组使用蓝湖和接口文档,与后端同学协商,规范后端数据回传。雅虎军规中提到,避免css表达式,过滤器,少做DOM操作,优化图片,精灵,避免图片空链接等。性能问题:页面加载性能,动画性能,操作性能。用于记录性能数据的性能API。温特再学习前端优化技术方案:缓存:客户端控制的强缓存策略。降低请求成本:DNS由客户端控制,在一段时间后主动请求获取域名IP,而不是使用系统DNS(完全无法理解)。重用TCP/TLS连接,服务器升级为HTTP2,尽可能合并域名。减少请求次数:JS和CSS打包成HTML。JS控制图片的异步加载和延迟加载。小图片使用data-uri。更少的传输量:尝试使用SVG\gradient代替图片。根据机型和网络情况控制画面清晰度。在低分辨率图像上使用锐化来改善体验。在设计中避免大背景图像。问题9loader,plugin,treeshakingloader对模块源码进行改造,将不同语言转成JS,或者将inline图片转成数据url。如:文件、url-loader、file-loader。转换编译、babel-loader、ts-loader。模板,html加载器。样式、样式加载器、css加载器、较少加载器。清理,eslint-loader。框架,vue-loader。插件解决了loader无法实现的其他事情。比如HtmlWebpackPlugin、CleanWebpackPlugin、webpack-bundle-analyzer、DllPlugin、HotModuleReplacementPlugin。Treeshaking剔除无用的js代码(去除模块中未导出或引用的部分)。只支持ESModule的静态导入方式,不支持require运行时的动态导入方式。ES6模块引入是静态分析的,因此可以在编译时正确判断加载哪些代码。可以排除的是有限的。webpack配合uglifyJS打包文件,只能抖动部分代码,比如模块代码,有副作用,不能抖动立即执行的功能。uglifyJS不进行程序流程分析,只是简单判断变量后续是否被引用或修改,不排除可能产生副作用的代码。(rollupwill)还有,比如项目中的router.js引用了页面组件,但是在路由渲染中并没有用到,无法抖动。webpack-deep-scope-analysis-plugin:使用webpack解析模块的AST,使用scoped分析工具分析引用关系,排除不用的模块。1.babel.config.js配置,分析文件模块依赖,生成AST时保持ES6不变。{“预设”:[[“环境”,{“模块”:假}]]}2。方法一,import{Button}from'antd';方法二,从'antd/lib/button'导入{Buttion};导入'antd/lib/style';tree-shaking的效果在这两种方式上是截然不同的。(副作用范围不同)babel-plugin-import-fix插件遍历AST,找到类似于import{Button}from'antd'的结构,转换并重新生成代码。3.CSStree-shaking方法一:mini-css-extract-plugin+purifycss-webpack方法二:webpack-css-treeshaking-plugin。使用postCSS提供的解析器将CSS解析成AST,遍历得到匹配js和html代码的selector,匹配不到的删除,返回AST,重新生成代码。第十题懒加载路由考点,vue-router实现原理。level1:将需要延迟加载的子模块打包成单独的文件。ES6的import()。hashChange时,根据hash变化执行特定函数,加载子模块。level2:三种实现方式,location.hash+hashChange(),HTML5标准pushState(IE10)+popState事件监听,抽象nodejs默认值。level3:源码分析。路由安装,使用mixin为每个组件注入beforeCreated和destroy钩子函数,在Vue原型上定义route和route以及route和router,并进行响应式处理,定义全局的roter-link和router-view组件。根据路由配置建立映射关系。根据传入路径计算新路径。在路径切换过程中,执行一系列导航守卫函数,改变Url,渲染相应的组件。Question12Cachinghtml文件也会被缓存。项目中使用了index.php,后台返回html内容,不会缓存。浏览器缓存策略:强制缓存:(浏览器在指定时间内直接使用强缓存内容)过期时间:Thu.21Jan201923:59:59GMT;(HTTP1.0)Cache-Control:max-age=3600(HTTP1.1,优先级更高)【缓存指令:no-cache需要协商缓存验证是否过期;no-store不缓存;公共客户端代理服务器可以缓存;privateclientcancache]Negotiationcache:(与服务器协商确定资源是否更新)Last-Modified(serverdeliverytime):Thu.21Jan201823:59:59GMT;(HTTP1.0)If-Modified-Since(浏览器查询)【可能时间变了,但是内容没变】Etag(服务器下发);(HTTP1.1)If-None-Match(由浏览器查询)问题13CDNCDN,内容分发网络,是一种基于重新托管网络建立的虚拟分发网络,可以缓存源站点的内容到全国或世界各地的节点服务器。用户就近获取内容,提高资源访问速度,减轻源站压力。使用DNS域名解析引导用户访问缓存服务器。问题14腾讯云SDK难点封装IM类,在IM类上定义创建SDK实例,登录/注销,加入/退出群,IM事件监听和移除。手机直播SDK。一开始我并没有做小程序主播端,而是用APP推流。主要做PC和H5流媒体内容。直播协议有几种。。。最开始使用的HLS协议,使用腾讯云提供的TC-Player作为播放器。遇到的问题是高延迟。考虑换个协议,但是手机浏览器不支持flv和rtmp。腾讯云的网页端推流提供了TC-Player插件,TC-Player本质上是使用浏览器自带的video标签。使用flv作为直播协议,但不要直接使用flv格式播放。GitHub有两种方案,一种是bilibiliflv.js,将flv文件流转码复用成MPE,通过MediaSourceExtensionsAPI实现视频播放。另一种解决方案是使用CANVAS绘制视频的每一帧。问题15SentrySentry错误日志通过https发送到Sentry的网站。使用cors实现跨域。应用程序(SentryclientSDK)将消息上报给web端进行消息处理,放入消息队列(Redis/Rabbitmq)。worker从消息队列中取出数据进行处理。最后postgresql完成消息存储**requestheaders:**Sec-Fetch-Mode:corsSec-Fetch-Site:crosssite**responseheaders:**access-control-allow-origin:access-control-expose-headers:x-sentry-error,retry-after,x-sentry-rate-limits面试被虐后,开始刷面试题,整理了一下,分享它免费送给大家,希望能带来好运。由于篇幅有限,我只能分享一些面试问题。更多面试题及答案可以【点我】阅读下载~免费分享给大家。这是一种感恩回馈。