web相关
一、从url输入到页面展现背后发生了什么
- 浏览器根据请求的url交给dns域名解析,找到真实ip,向服务器发起请求
- 服务器交给后台返回的数据,浏览器接收文件
- 浏览器对加载到的资源进行语法解析,建立相应的内部数据结构
- 载入解析到的资源文件,渲染页面完成
三、浏览器是如何渲染页面的
- 创建DOM树
- 创建style Rules
- 构建Render Tree
- 布局layout
- 绘制painting
四、浏览器的内核有哪些,分别有什么代表的浏览器
- IE:Trident
- Firefox:Gecko
- Opera:Presto
- Chrome:Webkit
五、刷新页面,一次JS请求一般情况下有哪些地方会有缓存处理
- DNS缓存:短时间内多次访问某个网站,在限定时间内,不用多次访问DNS服务器
- CDN缓存:内容分发网络
- 浏览器缓存:浏览器在用户的磁盘上,对最新请求过的文档进行了缓存
- 服务器缓存:将需要频繁访问的web页面和对象保存在离用户更近的系统中,这样会加快访问速度
HTML相关
一、DOCTYPE 有什么作用?怎么写?
- 声明文档类型告知浏览器如何解析
- 写法:
<!DOCTYPE html>
或者<!doctype html>
二、页面出现乱码怎么回事,如何解决?
- 可能是未指定编码格式
- 解决方案:charset设置为utf-8
三、title和alt属性的作用
- title为一些描述性文字
- alt是当用户因网速等原因未加载到资源前显示的占位符
四、html注释
<!---->
五、data-属性的作用
当没有合适的属性和元素时,data属性能够存储页面的自定义数据
六、HTML全局属性
- id
- class
- title
- style
CSS相关
一、CSS 有哪些样式可以给子元素继承
- 可继承:font-size/font-weight/line-height/color
- 不可继承:display,padding,border,margin
二、行内元素、块元素、空元素有哪些
- 行内元素:input,span,a,img
- 块元素:div,h1-h6,main,aside,content
- 空元素(void):br,hr
三、用css3实现一个扇形
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>扇形</title>
<style>
.sector {
width: 0;
height: 0;
border-width: 50px;
border-style: solid;
border-color: #f00 transparent transparent;
border-radius: 50px;
}
</style>
</head>
<body>
<div class="sector"></div>
</body>
</html>
四、box-sizing常用属性有哪些,分别有啥作用?
- 有两个值content-box(标准盒模型),border-box(怪异盒模型)
- 两种盒模型计算盒子大小的方式不同
- 标准盒模型的计算方式:width+padding+border=盒子宽度
- 怪异盒模型的计算方式:width(宽度会缩小)+padding+border=盒子宽度
举例:
width:100px;padding:10px; border:10px solid red;
标准盒模型:盒子宽度=100+10+10=120
怪异盒模型:盒子宽度=60+20+20=100(怪异盒模型的宽度与指定的宽度相等)
五、清除浮动的方式,那种比较好?
-
一般有3种:.clearfix,clear:both,overflow:hidden
.clearfix{*zoom:1}//兼容ie .clearfix.after{ content:'', display:block, clear:both } clear:both(缺点:需要额外创建标签) overflow:hidden(缺点:溢出的内容会隐藏)
六、块元素水平垂直居中的方式
介绍2种方式
- 方法一:定位
.box{
position:absolute;
top:0;
right:0;
bottom:0;
left:0;
margin:auto;
}
- flex布局
.box{
display:flex;
justify-content:center;
align-items:center;
}
七、样式权重的优先级
!important > 行内样式 > id > class > tag
八、HTML语义化的理解
- html语义化即使让页面内容结构化,便于浏览器搜索引擎解析
- 在没有样式的情况下以一种文档格式显示,并且是易于阅读的
- 有利于搜索引擎优化
- 有利于阅读和维护
九、JS的数据类型
十、null和undefined的区别
- undefined 值是派生自 null 值的,因此 ECMA-262 规定对它们的相等性测试要返回 true
- alert(null == undefined); //true
- 无论在什么情况下 都没有必要把一个变量的值显式地设置为 undefined
- 而只要意在保存对象的变量还没有真正保存对象,就应该明确地让该变量保存 null
十一、JS的DOM操作
获取document.getElementById/ClassName/TagName
document.querySelector("#demo");只返回匹配的第一个元素
document.querySelectorAll() ;返回所有元素
追加节点appendChild
删除节点removeChild
上一个兄弟节点priviousSibling
下一个兄弟节点nextSibling
增加属性element.setAttribute(name, value);
删除属性element.removeAttribute(attrName);
十二、 给一个 DOM添加捕获和冒泡的两种写法的事件点击,谁先执行?
- 有拿到节点的,优先捕获,没有才往上冒泡寻找
- 若是通过node.addEventListener(‘event’,callback,bubble or capture); 谁先调用谁先执行
十三、谈谈你对ajax的理解
异步的javascript和xml,可以实现无状态刷新页面和异步提交
优点:
- 不需要插件支持
- 用户体验极佳
- 提升web程序性能
- 减轻服务器和带宽负担
缺点:
- 前进后退按钮被破坏
- 搜索引擎支持不够
- 调试工具缺乏
十四、如何实现浏览器内多个标签页之间的通信?
cookie、localStorage
十五、什么是window对象? 什么是document对象?
- window对象是指浏览器打开的窗口。
- document对象是HTML 文档对象的一个只读引用,window对象的一个属性。
十六、重绘、回流
JS相关
一、描述下cookie,sessionStorage,localStorage的差异
- cookie存储量比较小,可以设置过期时间
- sessionStorage和localStorage的存储量理论上无限制,但sessionStorage是一个会话级别的存储,数据只在浏览器关闭前有效
- localStorage是持久化存储,除非手动删除否则会一直存在
二、javascript的原型链你怎么理解?
原型链:实例与原型之间的连接
当调用实例的某个属性或方法时,会首先在实例中查找,当未找到时,会到原型中查找,当原型中也未找到时,会到继承的原型中查找,到Object
三、ES6新特性
1、箭头函数
2、类的引入导出继承
3、字符串模板
4、Promise
5、let、const
6、async/await
7、默认参数
四、var、let、const的区别
- var没有块级作用域,可以重复声明和赋值
- let有块级作用域,不可以重复声明但可以重复赋值
- const也有块级作用域,但不可重复声明和赋值
五、async await的用途
- async是一个修饰符,async定义的函数会默认的返回一个Promise对象resolve的值,因此可以对async函数可以直接进行then操作,返回的值即为then方法的传入函数
- await也是一个修饰符,但await只能放置async函数内部,await关键字的作用就是获取Promise返回的内容,获取的是Promise函数中resolve或者reject的值
- 如果await后面不是一个Promise的返回值,则会按照同步程序返回值处理
六、谈谈你对Promise的理解
七、性能优化
八、闭包
闭包指有权访问另一个函数作用域中变量的函数,创建闭包的常用方式就是在函数内创建另一个函数,通过另一个函数访问这个函数的局部变量,利用闭包可以突破作用域链,将函数内部的变量和方法传递到外部
闭包的特性
1.函数嵌套函数
2.内部函数可以访问外部的参数和变量
3.参数和变量不会被垃圾回收机制回收,因此会导致内存溢出
八、call、apply、bind的区别
call,apply,bind的作用是改变函数运行时的this执行
- call,apply是立即调用,bind是稍后调用
- call,apply必须通过函数来调用,第一个参数为对象,若第一个参数为null或者undefined,则指向window
- call和bind方法可以接收多个参数,apply方法只能接收2个参数,且第二个参数为数组或者伪数组
- call和apply方法没有返回值(即返回undefined),bind方法返回一个原函数的拷贝,并具有指定的this值和初始参数
- call和apply不能在箭头函数中使用(因为箭头函数没有自身的this,this在箭头函数中已经按照词法作用域绑定了,所以没有办法用call/apply来改变this执行)
如果箭头箭头函数包裹在非箭头函数内,那么this值就与该函数相等,否则this值就是全局对象
九、防抖和节流
防抖:将若干函数函数的调用合并为一次,并在给定时间或事件完全触发后调用一次,如scrll滚动事件
节流:当达到一定事件间隔就会执行一次,可以理解为缩减执行效率
十、面向过程和面向对象
面向过程是明确指出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候依次调用即可。
面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,二是为了描述某个事物在整个解决问题的步骤中的行为
面向过程:
优点:性能比面向对象高,因为类的调用需要实例化,开销比较大
缺点:没有面向对象易维护、易复用、易拓展
面向对象:
优点:易维护、易复用、易拓展,由于面向对象有封装、继承、多态的特性,可以设计出低耦合的系统,使系统更加灵活,更易于维护
缺点:性能比面向过程低
十一、generator
generator(生成器)是es6引入的新的数据类型。一个generator看上去像一个函数,但可以返回多次。
genenerator与普通函数比,generator可以在执行过程中多次返回,所以它看上去就像一个可以记住执行状态的函数
generator还有另一个巨大的好处,就是把异步回调变成同步代码
可以使用yield关键字发起多个ajax请求
十二、js同步和异步的区别
https://www.cnblogs.com/lchsirblog/p/12048695.html
同步和异步的区别在于在这条流水线上各个流程的执行顺序不同。
同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才会执行后一个任务
异步任务指的是,不进入主线程,而进入任务队列,只有等主线程的任务执行完毕,任务队列通知主线程,请求执行任务,该任务才会进入主线程执行。
具体来说,异步运行机制如下:
- 所有同步任务都在主线程上执行,形成一个执行栈。
- 主线程之外,还存在一个任务队列。只要异步任务有了运行结果,就在任务队列之中放置一个事件。
- 一旦执行栈中的所有同步任务执行完毕,系统就会读取任务队列,看看里面有那些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行
- 主线程不断重复上面的第三步
React相关
四、什么是PropTypes
- PropTypes为组件提供类型检查,并为其他开发人员提供很好的文档
五、如何在React中应用样式
- 外部样式
- 内联样式
- 定义样式对象并使用它
七、什么是错误边界
- 在React中通常有一个组件树。其中任何一个发生错误都会破坏整个组件树,使用错误边界可以优雅地处理这些错误
- 错误边界的作用:如果发生错误回退显示UI,纪录错误
八、什么是Fragments
- 使用Fragments我们不需要在DOM中添加额外的节点,其作用与空标签<>相同
九、什么是传送门(Protals)
Portal提供了一种将子节点渲染到父组件以外的DOM节点的优秀的方案
十、什么是Hooks
Hooks是React版本16.8的新功能。之前我们说函数组件是无状态组件,有了Hooks之后,函数组件也可以管理自己的状态
基本规则:Hooks应该在外层使用,不应该在循环、条件或嵌套函数中使用,Hooks应该只在函数组件中使用
useState
const [age,setAge]=useState(18)
useState的返回值是当前state以及更新state的函数。所以可以使用数组解构的方式将这两个值解构出来
Effect Hook可以让我们在函数组件中执行副作用操作。(副作用:ajax请求,路由跳转等)
useEffect相当于componentDidMount、componentDidUpdate、componentWillUnmount三个生命周期的统一
useEffect会在每次渲染后都执行
effect中可以返回一个函数,这个effect可选的清除机制。每个effect都可以返回一个清除函数
React何时清除effect?
React会在组件卸载的时候执行清除操作。同时React会在执行当前effect之前对上一个effect执行清除
useEffect第二个参数是一个数组,只有当数组的值发生变化时才会调用effect,如果只执行一次,传入空数组即可
十一、为什么有Class和还要使用Hooks
- 在组件之间复用状态逻辑很难
- 复杂组件变得难以理解(calss生命周期经常包含不相关的逻辑,同时优惠把相关的逻辑分散到不同的生命周期)
- 难以理解的class(如class组件中需手动绑定this)
十二、如何提高性能
- 适当使用shouldComponentUpdate,避免不必要的渲染
- 使用create-react-app搭建项目,这会创建整个项目结构,并进行大量优化
- 不可变性是提高性能的关键。不要对数据进行修改,而是始终在现有集合的基础上创建新的集合,以保持尽可能少的复制,从而提高性能
- 使用列表或表格时始终使用keys,这会让React的更新速度更快
十三、如何在重新加载页面时保留数据
使用localStorage
十四、react-router与react-router-dom使用时的区别
React-router提供的api包括Router,Route,Switch,但没有提供有关dom操作进行路由跳转的api
React-router-dom提供了BroserRouter,Route,Link等api,可以通过dom操作进行路由跳转
十五、谈谈你对state的理解
关于setState()需要了解3点
- 不要直接修改state,
例如this.state.comment='hello’此代码不会重新渲染组件,而应该使用this.setState - state的更新可能是异步的。
出于性能考虑,React可能会把多个setState的调用合并成一个。
因为this.porps和this.state可能会异步更新,所以不要依赖他们的值来更新下一个状态 - state的更新可能会被合并
当调用setState的时候,React会把你提供的对象合并到当前state。此合并为浅合并
React的生命周期
挂载、更新、卸载
挂载:
contructor() 该生命周期主要用来初始化state和为事件处理函数绑定实例
static getDerivedStateFromProps(props,state) 该生命周期会在调用render方法之前调用,并且在初始挂载及后续更新时都会被调用。它应返回一个对象来更新state,如果返回null则不更新任何内容。此生命周期适用于罕见的用例,即state的值任何时候都取决于props
render() 数据渲染
componentDidMount() 发起ajax请求,此时dom节点已经生成,获取数据setState后会重新渲染页面
更新:
static getDerivedStateFromProps(props,state) 该生命周期会在调用render方法之前调用,并且在初始挂载及后续更新时都会被调用。它应返回一个对象来更新state,如果返回null则不更新任何内容。此生命周期适用于罕见的用例,即state的值任何时候都取决于props
shouleComponentUpdate(nextProps,nextState) 当props或state发生变化时,shouleComponentUpdate()会在渲染执行之前被调用。返回值默认为true.此方法仅作为性能优化的方式。可以根据this.props.与next.props以及this.state和nextState进行比较,返回false则告知React跳过更新。(只是当前组件不更新,其子组件依然会更新)
render()
getSnapshotBeforeUpdate()
在最近一次渲染输出(提交到dom节点)之前调用。它使得组件能在发生更改之前从dom中获取一些信息如滚动位置。此声明周期的任何返回值将作为参数传递给componentDidUpdate()
componentDidUpdate(prevProps,prevState,snapshot)
会在更新后别立即调用。首次渲染不会执行此方法
可以在componentDidUpdate()中直接调用setState(),但是包裹在条件语句中,否则会导致死循环
getSnapShotBeforeUpdate的返回值为snapshot,未传递时默认未undefined
卸载
componentWillUnmount()
在组件卸载及销毁之前调用。在此方法中执行必要的清理操作,如清除timer,取消网络请求
不应在该生命周期调用setState,因为该组件永远不会重新渲染。
Promise相关
一、Promise出现的原因
主要是为了解决回调地狱的问题,回调地狱会造成代码臃肿,可读性差,耦合度高
二、什么是Promise
Promise是异步编程的一种解决方案,比传统的异步解决方案回调函数和事件更合理更强大。
三、Promise的三种状态
pending、resolved、reject
四、Promised的api
then
catch
finally
all
编程实践相关
一、对数组[1,2,3,4,5,‘6’,7,‘8’,‘a’,‘b’,‘z’]进行乱序
let tempArr = [1,2,3,4,5,'6',7,'8','a','b','z'].sort(function(){
return Math.random() > 0.5 ? -1 : 1;
})
二、求[1, 10, 11, -1,’-5’,12, 13, 14, 15, 2, 3, 4, 7, 8, 9]内最大值与最小值之差
function MaxDiffMin(arr){
return Array.isArray(arr)?Math.max(...arr)-Math.min(...arrr);
}
三、请给Array实现一个方法,去重后返回重复的字符(新数组)
let tempArr = [1, 2, 3, 4, 5, 1, 3];
let repeatArr = [];
for (var i = 0; i < tempArr.length; i++) {
for (var j = i + 1; j < tempArr.length; j++) {
if (tempArr[i] === tempArr[j]) {
repeatArr.push(tempArr[i]);
}
}
}
console.log(repeatArr);
四、请用 JS 实现年龄从小到大的排序
var par = [{age:5,name:'张三'},{age:3,name:'李四'},{age:15,name:'王五'},{age:1,name:'随便'}]
var parSort = par.sort(function(a,b){
return a.age - b.age;
})
五、JS 实现函数运行一秒后打印输出0-9
for(let i=0;i<10;i++){
setTimeout(function(){
console.log(i);
},1000);
}
六、实现对一个数组或者对象的浅拷贝和"深度"拷贝
浅拷贝两个对象指向同一个内存,一个对象改变会影响另一个
深拷贝两个对象指向不同的内存,两者互不影响
https://segmentfault.com/a/1190000018874254
浅拷贝
使用...拓展运算符或者Object.assign
深拷贝
1、JSON.parse(JSON.stringify())
2、手写递归方法
3、使用插件lodash
七、this指向问题
function函数中的this谁调用就指向谁
箭头函数中的this在哪里定义就指向谁
八、如何解决跨域问题,有哪些方法
1、jsonp
2、nginx反向代理
3、cors
Access-Control-Allow-Origin:true(允许所有源访问)
九、对于XSS 和 CSRF 如何防范
XSS(Cross Site Scripting)跨站脚本攻击
1、转义用户的内容
2、cookie设置为http-only,防止客户端篡改
华米
华为
小米
阿里巴巴
腾讯
事件委托
Promise
window.onload和document.loaded谁先谁后
跨域问题如何解决
flex布局
自我介绍
你好我叫李奇,我是2017年毕业,大学学的是电子商务专业,目前是在华泰外包做内部管理系统,
之前我们项目组只有我一个前端,今年7月份又来了一个前端。我们项目组目前的是人员分布是2个前端、3个后端、2个测试、1个BA,加上2个项目经理。
我们项目组用的技术栈是react,更准确一点是umi+dva,除了react我对服务端语言nodejs和移动端语言flutter也有些了解,主要情况就是这些
离职原因
离职原因有2点 1是在华泰待得挺久的
个人优缺点
项目说明
技术问答
项目相关
项目中遇到那些问题,是如何解决的?
问题一 每次项目升级后,浏览器需要手动刷新才能看到最新的效果
解决:这是由于浏览器的缓存造成的,解决办法是打包的时候添加一个hash值,这样每次打包生成的文件名都不相同,这样当首次打开页面时浏览器会向服务器发送请求以获取最新的资源
问题二:做一个评论的效果, 可以输入多段文字,回车时自动缩进。
解决:使用TextArea无法达到该效果,通过打开控制台查看斗鱼的评论元素,发现他使用p标签写的。于是就有了解决思路。
首先定义样式,即所有的p标签自动缩进2个字,text-indent:2em
然后监听回车事件,点击回车时创建一个p标签,然后将光标定位到该行
谈谈你对前端的理解
前端工程师属于一个比较新型的职位,各种技术层出不穷,随着客户体验越来越重要,前端需要掌握的技术越来越多,而且前端是最贴近用户的,主要负责页面交互,提升用户体验,而且有了nodejs,前端可以实现服务端的一些事情。因此我们要有一个开放的心态,关注前端趋势,活到老,学到老
阿里面试题
一面
一、简历相关
二、技术相关
https://juejin.im/post/6844903813799919623
一、css盒模型
二、元素水平垂直居中(3种)
三、如何解决跨域问题
四、知道jsonp原理吗
首先是利用script标签的src属性来实现跨域
通过将前端方法作为参数传递到服务器端,然后由服务器注入参数之后再返回,实现服务器端向客户端的通信
由于使用script的src属性,因此只支持get方法
五、重绘和重排的区别
部分渲染树需要重新分析并且节点尺寸需要重新计算,称为重排。至少会有一次重排(初始化页面布局)
由于节点的样式发生改变,如背景色、文字颜色发生改变。这样的更新称之为重绘
六、什么情况会触发重排和重绘?
添加删除更新dom节点
display:none隐藏一个dom节点(触发重绘和重排)
visibility:hidden隐藏一个dom节点(只触发重绘,因为没有几何变化)
dom节点添加动画
调整样式属性
调整窗口大小,改变字号,或者滚动
知道浏览器事件模型吗
七、浏览器的事件模型分为三个阶段
捕获阶段
目标阶段
冒泡阶段
八、React 在哪个阶段发起 XhrHttpRequest
componentDidMount
知道为什么要在这个阶段发起吗
此时dom节点已经生成,在这里发起ajax请求,返回数据setState后组件会重新渲染
九、为什么虚拟dom会提高性能
虚拟dom相当于在js和真实dom中间加了一个缓存,利用dom diff算法避免了没有必要的dom操作,从而提高了性能
十、diff算法
把树形结构按照层级分解,只比较同级元素
给列表结构的每个单元添加唯一的key属性,方便比较
React只会匹配相同class的component
合并操作,调用component的setState方法的时候,React将其标记为dirty,到每一个事件循环结束,React将所有标记为dirty的compoent重新绘制
选择性子树渲染。开发人员可以重写shouleComponentUpdate提高diff的性能
十一、从输入一个URL到页面加载完成发生了什么
十二、你觉得你和别人相比最大的优势是什么…
做事踏实认真,有始有终,有独立解决问题的能力
有良好的文档阅读能力,乐于接受新技术,会主动学习
遇到一些阻塞性问题,未能将问题抛出来,自己一个人埋头苦干,最后可能会延缓项目进度,所以现在遇到这种阻塞性问题要主动抛出来
十三、右边宽度固定,左边自适应
方法一
<style>
body {
display: flex;
}
.left {
height: 200px;
background: red;
flex: 1;
}
.right {
height: 200px;
width: 100px;
background: green;
}
</style>
</head>
<body>
<div class="left"></div>
<div class="right"></div>
</body>
方法二
<style>
.left,.right{
height: 200px;
}
.left {
float: right;
width: 200px;
background: green;
}
.right {
margin-right: 200px;
background: red;
}
</style>
</head>
<body>
<div class="left"></div>
<div class="right"></div>
</body>
十四、四种定位的区别
- static默认值
- relative 相对于自身发生偏移 未脱离文档流
- absolute 有定位父级相对于定位父级发生偏移 ,没有定位父级相对于body发生偏移,元素脱离文档流
- fixed 固定定位 元素相对于视口来定位,这意味着即使页面滚动,它还是会停留在相同的位置
十五、Flex布局
十六var let const的区别
十七、var 为什么可以重复声明
因为编辑器会在判断有已经声明的同名变量时忽略var,然后直接赋值
十八、封装一个函数,参数是定时器的时间,.then执行回调函数。
function sleep (time) {
return new Promise((resolve) => setTimeout(resolve, time));
}
十九、CommonJS 中的 require/exports 和 ES6 中的 import/export 区别?
- commonJS模块的重要特性是加载时执行,即脚本代码在require的时候,就会全部执行。一旦出现某个模块被“循环加载”,就只输出已经执行的部分,还未执行的部分不会输出
- ES6模块是动态引用,如果使用import从一个模块加载变量,那些变量不会被缓存,而是成为一个执行被加载模块的引用,需要开发者自己保证,真正取值的时候能够取到值。
- import/export最终都会编译为require/exports
- commonJS规范规定每个模块内部,module变量代表当前模块。这个变量是一个对象,它的exports属性是对外的接口。加载某个模块,其实是加载该模块的module.exports属性
- export规定的是对外的接口,必须与模块内部的变量建立一一对应的关系
二十、一行代码实现数字去重
[...new Set([1,2,3,1,'a',1,'a'])]
二十一、使用addEventListener点击li弹出内容,并且动态添加li之后有效
var ulNode = document.getElementById("ul");
ulNode.addEventListener('click', function (e) {
if (e.target && e.target.nodeName.toUpperCase() == "LI") {
alert(e.target.innerHTML);
}
}, false);
element.addEventListener(event,function,useCapture)
event指事件名 不需要on前缀
function指事件触发的执行函数
useCapture 可选布尔值 true为事件句柄在捕获阶段执行 false为事件句柄在冒泡阶段执行
二十二、怎么判断两个对象相等?
JSON.stringify转成字符串来判断
JSON.stringify(obj)==JSON.stringify(obj2);//true
JSON.stringify(obj)==JSON.stringify(obj3);//false
二十三、项目做过那些性能优化
- 减少 HTTP 请求数
- 使用 CDN托管资源
- 使用外部 JavaScript 和 CSS
- 避免重定向(重定向会增加http请求的次数)
- 图片懒加载
- 使用 iconfont
- 尽量减少 iframe 使用(iframe会阻塞页面加载)
- 减少 DOM 元素数量
- 减少 DOM 操作
- 压缩 JavaScript 、 CSS 、字体、图片等
- 减少 DNS 查询
- js放在页面底部
- 去除重复的js
- 避免图片src为空
优化 CSS Sprite
字体裁剪
多域名分发划分内容到不同域名
二十四、模块化开发是怎么做的
使用命名空间
二十五、有没有使用过webpack?
二十六、浏览器缓存
- 浏览器缓存分为强缓存和协商缓存,当客户端请求某个资源时,获取缓存的流程如下:
- 首先会判断这些资源的一些http header判断它是否命中强缓存,如果命中,则直接从本地获取缓存资源,不会发请求到服务器
- 当强缓存没有命中时,客户端会发送请求到服务器,服务器通过另一些request header验证这个资源是否命中协商缓存,称为http再验证,如果命中,服务器将请求返回,但不返回资源,二是告诉客户端直接从缓存中获取,客户端收到返回后就会从缓存中获取资源
- 当协商缓存也没有命中时,服务器就会将资源发送回客户端
- 强缓存和协商缓存的共同之处在于,如果命中缓存,服务器都不会返回资源
- 区别是,强缓存不会发送请求到服务器,但协商缓存会
- 当ctrl+f5强制刷新页面时,直接从服务器加载,跳过强缓存和协商缓存
- 当f5刷新页面时,跳过强缓存,但是会检查协商缓存
强缓存:
Expires:代表缓存资源的过期时间
Cache-Control:max-age判断缓存资源最大声明周期,单位为秒
协商缓存:
Last-Modified:最后更新时间
if-Modified-Since:通过比较两个时间来判断资源在两次请求期间是否有过修改,没有没有修改,则命中协商缓存
ETag:表示资源内容的唯一标识,随服务器response返回
if-None-Match:服务器通过请求头部的if-None-Match与当前资源的ETag是否一直来判断资源是否在两次请求之间有过修改,如果没有修改,则命中协商缓存
三、在线编程
二面
项目和平时情况
简历知识点排查
一、html5的新特性
- 语义化标签(header main footer nav aside)
- 增强型表单(input的type类型增加了color date dateTime month week time)
- 视频和音频(video audio)
- canvas
- websocket(当你获取 Web Socket 连接后,你可以通过 send() 方法来向服务器发送数据,并通过 onmessage 事件来接收服务器返回的数据。)
二、css3的新特性
- 过渡(transition)
- 动画(animation)
- 转换(transform)
- 弹性布局
- 盒模型
三、React面试题
13. 区分real dom和virtual dom
Real Dom | Virtual Dom |
---|---|
更新慢 | 更新快 |
可直接更新html | 无法直接更新html |
元素更新则创建dom | 元素更新则更新jsx |
dom操作代价很高 | dom操作简单 |
消耗内存较多 | 很少的内存消耗 |
-
什么是React
用于构建用户界面的JavaScript库 -
React有什么特点
使用虚拟dom
遵循单项数据流
可以使用服务端渲染 -
React的优点
提高应用性能
可以方便地在客户端和服务端使用
由于jsx代码的可读性很好
编写测试用例容易 -
React有那些限制
React只是一个库,不是一个完整的框架
需要一定的学习成本 -
什么是虚拟dom,解释一下它的工作原理
-
为什么浏览器无法读取JSX?
浏览器只能处理javascript对象,因此浏览器要读取jsx需要先将jsx转为js对象 -
什么是props
props是React属性的简写。props为只读属性 -
React中key的重要性
key用于表示每一个列表项,便于diff算法的比较,提高应用程序的性能 -
什么是redux
Redux 是 JavaScript 状态容器,提供可预测化的状态管理。 -
Redux三大原则
单一数据源(整个应用的state被存储在一棵object tree中,并且这个object tree只存在于唯一一个store中)
state是只读的(改变state的方法是触发action,action是一个用于描述已发生事件的普通对象)
使用纯函数来执行修改(为了描述如何改变state tree,需要我们编写reducers) -
列出Redux的组件
Action-用来描述发生了什么事情的对象
Reducer-确定状态如何变化
Store-整个应用的状态
View-只显示Store提供的数据
(1)Web 应用是一个状态机,视图与状态是一一对应的。
(2)所有的状态,保存在一个对象里面。
Store
Store是存储数据的地方,整个应用只有一个store
State
定义具体的数据
Action
是一个对象,其中type属性是必须的
Reducer
为一个纯函数,接受一个状态,返回一个新状态
纯函数是指同样的输入必定得到同样的输出
遵循以下约束
不得改写参数
不能调用系统 I/O 的API
不能调用Date.now()或者Math.random()等不纯的方法,因为每次会得到不一样的结果
完整的过程用户dispatch一个action,Store自动调用reducer,Reducer会返回一个新的state,state一旦有变化,store就会调用监听函数,这个会重新渲染视图
Dva相关
一、什么是dva
dva是一个基于redux和redux-saga的数据流方案,然后为了简化开发体验,dva还内置了react-router和fetch
二、dva的数据流向
数据的改变发生通常是通过用户交互行为或者浏览器行为触发的,此类行为改变数据的时候可以通过dispatch发起一个action,如果是同步行为会直接通过Reducers改变state,如果是异步行为会触发Effects然后流向Reduders最终改变State
Provider相关
Model变化后会自动通过ChangeNotifierProvider(订阅者),ChangeNotifierProvider内部会重新构建InheritedWidget,而依赖该InheritedWidget的子孙Widget就会更新
Git相关
Git是一个开源的分布式版本控制系统,有如下几个概念
Workspace工作区
Index/Stage暂存区
Repository仓库区
Romote远程仓库
git命令
用户名、邮箱
git config --global user.email ""
git config --global user.name ""
初始化
git init
初始化git clone git@*****
克隆一个远程项目到本地git remote add origin git@*****
链接一个本地的项目到远程git push -u origin master
流程操作
git add
把工作区修改的内容放到暂存区git commit -m '提交修改的说明' 把暂存区的内容提交到仓库
git push
把仓库的内容提交到远程git pull
把远程的最新修改内容拉取到本地来git rm
删除本地文件提交git checkout -- 文件名
把仓库的内容覆盖到本地(本地修改的内容会被忽略)git log
查看提交记录git reset --hard HEAD^^^^
版本回退
分支操作
git branch
查看本地分支git branch -a
查看所有分支git checkout *
切换分支git checkout -b
‘分支名’ 新建并且切换分支git merge '分支名'
把某个分支合并到当前分支git push origin *:*
把当前分支提交到远程git checkout -b * origin/*
拉取远程分支到本地并且切换一个新的分支
Flutter相关
- Dart属于强类型语言,但可以用var来声明变量,Dart会自推导出数据类型
- Dart中的if只支持bool类型,switch支持String类型
- Dart中的数组和List是一样的
- Dart支持闭包
- Dart中number类型分为int和double,没有float类型
- Dart中有级联操作符
- 赋值运算符
aa??'999'//如果aa为空,返回999
aa??='999'//如果aa为空,将aa设置为999
- 可选参数和默认参数
- 作用域 Dart没有关键字public private等修饰符 _代表private
node相关
- node.js是一个基于v8引擎的运行时。它具有以下特点:单线程,事件驱动,非阻塞I/O
- CommonJS中require/exports和ES6中import/export区别
- 使用npm有那些好处
通过npm可以安装和管理项目的依赖,并指明依赖项的具体版本号 - AMD和CMD规范的区别
AMD和CMD都是js模块化的规范
AMD是预加载,在并行加载该模块的同时还会解析执行该模块,CMD是懒加载,虽然一开就并行加载js文件,但是不会执行,二是在需要的时候才执行 - node怎么跟mongoDB建立连接
引入mongoose
使用mongoose.connect()方法连接到mongoDB数据库
监听连接是否成功
然后通过node编写接口,对数据库进行增删改查 - node解决跨域问题
通过使用app.all将header设置为access-control-allow-origin:true
nginx相关
为什么会出现跨域问题?
出于浏览器同源策略的限制。所谓同源就是两个页面具有相同的域名、协议和端口。跨域是浏览器行为,不是服务器行为,服务器之间不存在跨域
什么是代理?
所谓代理就是在本地和真实服务器之间搭建一台代理服务器,我们所有的请求通过它来转接
什么是正向代理?
正向代理就是我们访问不了google,但是我在国外有一台vps,它可以访问google,我访问它,叫它访问google,然后把数据传给我
什么是反向代理?
例如当我们百度的时候,背后有成千上万的服务器为我们服务,但具体是那一台我们不知道,也不需要知道,我们只需要知道百度就是我们的反向代理服务器,它会把我们的请求转到真实的服务器哪里。
总结:
正向代理隐藏了真实的客户端
反向代理隐藏了真实的服务端
Mongoose
增删改查
save/deleteOne/updateOne/find
umi相关
- 谈谈你对umi的了解
umi是可扩展的企业级前端应用框架。umi以路由为基础,支持配置式路由和约定书路由,然后配以完善的插件体系,覆盖从源码到构建产物的每个生命周期,支持各种功能拓展和业务需求 - umi常用的api
history用于获取当前路由信息
history.location.pathname
history.location.search
history.location.hash
Link NavLink(可以附着特定样式)
Prompt离开页面时的提示
MVC & MVVM
Model模型 负责对数据库的数据进行增删改查
View 视图 负责渲染数据
Controller控制器 负责用户交互
一句话描述就是Controller负责将Model的数据用View显示出来
MVVM
M模型
V视图
VM ViewModel主要负责数据解析
webpack相关
一、 对于loader的理解?
loader用于对模块的源代码进行转换。loader可以是我们在import或加载模块时预处理文件,因此loader类似于其他构建工具中的task,并提供了处理前端构建步骤的强大方法。loader可以将文件从不用的语言如ts转换成js,将内联图像转换成data url
二、webpack 打包文件体积过大
- 去除不必要的插件
- 提取第三方库(如react lodash)
- 代码压缩 (webpack自带UglifyJsPlugin)
- 代码分割(code split 即只加载当前的js代码,而非加载全部)
- 设置缓存(对于静态文件,第一次获取之后变动不大的话,让浏览器直接读取缓存文件即可,如果缓存设置过长,文件要更新怎么办,我们可以手动调用webpack的api,获取打包后的文件名,通过writeTemplate更新html代码)