又到了金三银四的找工做季啦 ✿✿ヽ(°▽°)ノ✿。我是一个入行一年多的前端菜鸟,去年夏天开始考虑换工做,陆续面试了几家中小公司。面试过程我通常会录音,方便结束后进行复盘。整理了几回面试复盘的笔记,但愿对类似状况的小伙伴有所帮助「😝 也是方便本身之后回忆」,愿你们都能找到心仪的工做。❤️php
说明:问题末尾的数字表明对本身当时回答的打分,✔ 表明后面有关于该问题的从新整理。css
相同点:html
不一样点:前端
level1: vue2.0中,响应式实现的核心就是 ES5的Object.defineProperty(obj, prop, descriptor). 经过Object.defineProperty()劫持data和props各个属性的getter和setter,getter作依赖收集,setter派发更新。总体来讲是一个 数据劫持 + 发布-订阅者模式。vue
level2: 具体来讲, ① vue初始化阶段(beforeCreate以后create以前),遍历data/props,调用Object.defineProperty给每一个属性加上getter、setter。② 每一个组件、每一个computed都会实例化一个watcher(固然也包括每一个自定义watcher),订阅渲染/计算所用到的所用data/props/computed,一旦数据发生变化,setter被调用,会通知渲染watcher从新计算、更新组件。node
level1: props+events 父子组件通讯( children),vuex 任何组件通讯,事件中心 on 任何组件的通讯, listeners 后代通讯(provide / inject)。react
level2: vuex运行机制:vuex的state做为一个仓库,提供数据驱动vue component渲染。视图经过dispach派发actions,actions中能够作一些异步操做。actions或者视图经过commit提交给mutations,mutation去改变state。webpack
level3: 源码分析:vuex实际上是一个Vue.js插件,插件都须要提供一个install方法,install方法调用会将Vue做为参数传入。Vue.user(plugin)安装插件,也就是执行插件的install方法。会在全局混入一个beforeCreate钩子函数,把示例化的Store保存到全部组件的this.$store中。git
level4: mutation改变state, 会触发视图改变的缘由?经过vue实现的,[实例化vue,把state做为一个data属性。] ↔️ 核心github
let Vue
function install(_Vue) {
Vue = _Vue
function vuexInit() {
const options = this.$options
console.log('vuexInit -> this.$options', this.$options)
if (options.store) {
// // 根实例 this --> Vue
this.$store =
typeof options.store === 'function' ? options.store() : options.store
} else if (options.parent && options.parent.$store) {
// 组件实例 this --> VueComponent, 如 APP, Home, About...
this.$store = options.parent.$store
}
}
Vue.mixin({ beforeCreate: vuexInit })
}
class Store {
constructor(options = {}) {
const { state = {}, mutations = {}, getters = {} } = options
this._mutations = mutations
// getter实现原理
const computed = {}
this.getters = {}
for (let [key, fn] of Object.entries(getters)) {
computed[key] = () => fn(this.state)
Object.defineProperty(this.getters, key, {
get: () => this._vm[key]
})
}
this._vm = new Vue({
data: { $$state: state }, // 核心原理
computed
})
}
commit(type, payload) {
if (this._mutations[type]) {
this._mutations[type](this.state, payload)
}
}
get state() {
return this._vm._data.$$state
}
}
export default { Store, install }
复制代码
level1: 推断节点是否为用户可见,以及多少比例可见,交叉观察器。web API中也有。
level2: 小程序中的IntersectionObserver在Web的基础上,作了一些封装,经过createIntersectionObserver返回一个IntersectionObserver实例。实例方法包括relativeTo、relativeToViewPort、observer、disconnect。relativeTo和relativeToViewPort,相对指定元素或视口的指定位置。observer(selector, cb),观察指定节点,可见性发生变化时触发回调。
level3: Web API, new IntersectionObserver(cb, options)。options里root、rootMargin的配置,可实现小程序中relativeTo、relativeToViewPort方法的效果。另外 thresholds 属性也蛮有趣的,在指定的几个相交比例时触发回调。
// babel.config.js配置以下:
plugins: ['equire']
// echarts.js
const echarts = equire(['line', 'tooltip', 'legend', 'dataZoom', 'grid']);
export default echarts;
复制代码
先后端数据交换方面,推进项目组使用蓝湖、接口文档,与后端同窗协商,规范后台数据返回。
雅虎军规提到的,避免css表达式、滤镜,较少DOM操做,优化图片、精灵图,避免图片空连接等。
性能问题:页面加载性能、动画性能、操做性能。Performance API,记录性能数据。
winter重学前端 优化技术方案:
loader
对模块的源代码进行转换,将不一样的语言转换为JS,或将内联图像转换为data url。如:文件,url-loader、file-loader。转换编译,babel-loader、ts-loader。模板,html-loader。样式,style-loader、css-loader、less-loader。清理,eslint-loader。框架,vue-loader。
plugin
解决loader没法实现的其余事儿。好比 HtmlWebpackPlugin、CleanWebpackPlugin、webpack-bundle-analyzer、DllPlugin、HotModuleReplacementPlugin。
tree shaking
消除无用的js代码(剔除模块中没有导出或引用的部分)。仅支持ES Module静态引入方式,不支持require运行时动态引入方式。
ES6模块引入是静态分析的,故而可在编译时正确判断加载哪些代码。
可剔除的内容有限。webpack配合uglifyJS打包文件,只能shaking部分代码,像模块代码存在反作用,当即执行函数等都不能shaking。uglifyJS不进行程序流分析,只简单判断变量后续是否被引用、修改,不去排除有可能有反作用的代码。(rollup会)还有,好比项目中router.js引用了页面组件,可是在路由渲染中没有用到,也没法shaking掉。
webpack-deep-scope-analysis-plugin:利用webpack解析出来模块的AST,利用scoped分析工具解析引用关系,排除掉没有用到的模块。
1. babel.config.js 配置,分析文件模块依赖关系,生成AST时,保持ES6不动。
{
"presets": [ ["env", { "modules": false }] ]
}
2. 方式1,import {Button} from 'antd';
方式2,import {Buttion} from 'antd/lib/button';
import 'antd/lib/style';
这两种方式,tree-shaking效果差异很大。(反作用范围不一样)
babel-plugin-import-fix 插件,遍历AST找出相似import {Button} from 'antd'的结构,进行转换从新生成代码。
3. CSS tree-shaking <https://juejin.cn/post/6844903808397475847>
方式1:mini-css-extract-plugin + purifycss-webpack
方式2:webpack-css-treeshaking-plugin。
利用postCSS提供的解析器,将CSS解析成AST,遍历获取选择器与js、html代码匹配,删除匹配不到的,返回AST,从新生成代码。
复制代码
考点,vue-router实现原理。
level1:
level2: 实现的三种方式,location.hash + hashChange(),HTML5规范的pushState(IE10) + popState事件监听,abstract nodejs默认值。
**level3:**源码分析。路由安装,利用mixin给每一个组件注入beforeCreated和destory钩子函数,在Vue原型上定义 router,并进行响应式处理,定义全局的roter-link和router-view组件。根据路由配置建立映射关系。根据传入路径计算出新的路径,在路劲切换过程当中,执行一系列的导航守卫函数,更改Url,渲染对应组件。
html文件也会缓存。项目中使用index.php,后端返回html内容,不会被缓存。
浏览器缓存策略:
强制缓存:(在指定时间内,浏览器直接使用强缓存的内容)
Expires:Thu.21 Jan 2019 23:59:59 GMT; (HTTP1.0)
Cache-Control:max-age=3600(HTTP1.1,优先级更高)
【缓存指令:no-cache须要协商缓存来验证是否过时;no-store不缓存;public客户端代理服务器均可以缓存;private客户端可缓存】
协商缓存:(与服务器协商,肯定资源是否更新)
Last-Modified(服务器下发时间):Thu.21 Jan 2018 23:59:59 GMT;(HTTP1.0)
If-Modified-Since(浏览器询问) 【可能时间变了,内容没变】
Etag(服务器下发); (HTTP1.1)
If-None-Match(浏览器询问)
CDN,内容分发网络,是创建再承载网基础上的虚拟分布式网络,可以将源站内容缓存到全国或全球的节点服务器上。用户就近获取内容,提升了资源的访问速度,分担源站压力。
使用DNS域名解析引导用户来访问cache服务器。
封装IM类,在IM类上定义建立SDK实例,登陆/退出,群组加入/退出,IM事件监听和移除。
sentry错误日志经过https发送到sentry的web站点。使用cors实现跨域。
**request headers:**
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross site
**response headers:**
access-control-allow-origin: <http://localhost:8080>
access-control-expose-headers: x-sentry-error, retry-after, x-sentry-rate-limits
复制代码