套路
- 举例
- 将不会的变成会的
- 侃侃而谈
HTML面试
- (必考)你是如何理解HTML语义化的?
- 举例:段落用p,边栏用aside,主要内容用main标签
- 最开始是 PHP 后端写 HTML,不会 CSS,于是就用 table 来布局。table 使用展示表格的。严重违反了 HTML 语义化。后来有了专门的写 CSS 的前端,他们会使用 DIV + CSS 布局,主要是用 float 和绝对定位布局。稍微符合了 HTML 语义化。再后来,前端专业化,知道 HTML 的各个标签的用法,于是会使用恰当的标签来展示内容,而不是傻傻的全用 div,会尽量使用 h1、ul、p、main、header 等标签。语义化的好处是已读、有利于SEO等。
- 对面试官请看我的博客 https://zhuanlan.zhihu.com/p/32570423
- meta viewport 是做什么的,怎么写?
- 代码:
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
- 控制页面在移动端不要缩小显示。
- 侃侃而谈:
一开始,所有页面都是给PC准备的,乔布斯推出 iPhone 3GS,页面是不适应手机屏幕的,所以乔布斯的工程师想了一个办法,默认把手机模拟成 980px,页面缩小。后来,智能手机普及,这个功能在部分网站不需要了,所以我们就用 meta:vp 让手机不要缩小我的网页。
- 代码:
- canvas元素是干什么的?
- 项目:小小画板
- 记住一些基本的API,查看MDN入门手册。
CSS面试
- (必考)盒模型
- 举例:
conten-box:width == 内容区宽度
border-box:width == 内容区宽度 + padding 宽度 + border 宽度
- 举例:
- css reset和normalize.css有什么区别?
- 考英文:
- reset重置,之前的样式我不要,a{color:red;},抛弃默认样式
- normalize让所有的浏览器的标签都跟标准规定的默认样式一致,个浏览器上的标签默认样式基本统一。
- 考英文:
- (必考)如何居中?
- 平时总结:
- 水平居中:
- 内联:父元素上写
text-align:center;
- 块级:
margin-left:auto;margin-right:auto;
- 内联:父元素上写
- 垂直居中:七种方式实现垂直居中
- 水平居中:
- 平时总结:
- 选择器优先级如何确定?
- 选择器越具体,优先级越高。#xxx大于.yyy
- 同样优先级,写在后面的覆盖前面的。
-
color:red !important;
优先级最高
- BFC是什么?
- 举例
- overflow:hidden 清除浮动。(一般常用.clearfix清楚浮动,不用overflow:hidden;)
- overflow:hidden 取消父子合并。http://jsbin.com/conulod/1/edit?html,css,js,output (解决:给一个padding-top:1px;)
- 举例
- 如何清除浮动?
-
overflow:hidden;
(不建议使用) - .clearfix 清楚浮动写在父元素上
.clearfix::after{ content:''; display:block; clear:both; } .clearfix{ zoom:1;/*兼容IE*/ }
-
JS面试
JS有哪些基本数据类型?
string、number、boolean、null、undefined、symbol、object
object包含了数组、函数、正则、日期等对象-
(必考)Promise怎么使用?
- then
$.ajax(...).then(成功函数,失败函数)
- 链式then
$.ajax(...).then(成功函数,失败函数).then(成功函数,失败函数)
- 如何自己生成Promise对象
function xxx(){ return new Promise(function(resolve,reject){ setTimeout(()=>{ resolve()或者reject() },3000) }) } xxx().then(...)
- then
-
(必考)AJAX手写一下?
let xhr = new XMLHttpRequest(); xhr.open('POST','/xxx') xhr.onreadystatechange = function(){ if(xhr.readyState === 4){ if(xhr.status === 200){ console.log(xhr.response); } else { console.log(xhr.status) } } }; xhr.onerror = function(){ console.error(xhr.status) }; xhr.send(null);
-
(必考)闭包是什么?
function(){ var n = 0; return function(){ n += 1 } } let adder = () adder()// n === 1 adder()// n === 2 console.log(n)// n is not defined
-
(必考)这段代码里的this是什么?
- fn()里面的this就是window
- fn()是stric mode,this就是undefined
- a.b.c.fn()里面的this就是a.b.c
- new F()里面的this就是新生成的实例
-
()=>console.log(this)
里面的this跟外面的this的值一模一样
-
(必考)什么是立即执行函数?使用立即执行函数的目的是什么?
;(function(){ var name }()) ;(function(){ var name })() ~function(){ var name }()
造出一个作用域,防止污染全局变量
ES6:{ let name }
-
async/await 语法了解吗?目的是什么?
function reutrnPromise(){ reutrn new Promise( function(resolve,reject){ setTimeout(()=>{ resolve('fuck') },3000) }) } returnPromise().then((result)=>{ result === 'fuck' }) var result = await reuturnPromise() result === 'fuck'
主要目的:将异步代码写成同步代码。
-
如何实现深拷贝?
- JSON来深拷贝
缺点:JSON不支持函数、引用、undefined、RegExp、Date......var a = {...} var b = JSON.parse(JSON.stringify(a))
- 递归拷贝
function clone(object){ var object2 if(! (object instanceof Object) ){ return object }else if(object instanceof Array){ object2 = [] }else if(object instanceof Function){ object2 = eval(object.toString()) }else if(object instanceof Object){ object2 = {} } 你也可以把 Array Function Object 都当做 Object 来看待,参考 https://juejin.im/post/587dab348d6d810058d87a0a for(let key in object){ object2[key] = clone(object[key]) } return object2 }
- 环
- JSON来深拷贝
-
如何实现数组去重?
- 计数排序的逻辑(只能正整数)
var a = [4,2,5,6,3,4,5] var hashTab = {} for(let i=0; i<a.length;i++){ if(a[i] in hashTab){ // 什么也不做 }else{ hashTab[ a[i] ] = true } } //hashTab: {4: true, 2: true, 5: true, 6:true, 3: true} console.log(Object.keys(hashTab)) // ['4','2','5','6','3']
- Set去重
Array.from(new Set(a))
- WeakMap 任意类型去重
- 计数排序的逻辑(只能正整数)
-
如何用正则实现string.trim()?
function trim(string){ return string.replace(/^\s+|\s+$/g, '') }
-
JS原型是什么?
- 举例
a. var a = [1,2,3]
b. 只有0、1、2、length 4个key
c. 为什么可以a.push(4),push是哪里来的?
d. a.proto === Array.prototype
e. push 就是沿着 a.prototype找到的,也就是Array.prototype.push
f. Array.prototype还有很多方法,如join、pop、slice、splice
g. Array.prototype 就是a的原型(proto)
参考:https://zhuanlan.zhihu.com/p/23090041
- 举例
-
ES6中的class了解吗?
- 把MND class章节看完
- 记住一个例子
-
JS如何实现继承
- 原型链
function Animal(){ this.body = '肉体' } Animal.prototype.move = function(){ } function Human(name){ Animal.apply(this, arguments) this.name = name } // Human.prototype.__proto__ = Animal.prototype // 非法 var f = function(){} f.prototype = Animal.prototype Human.prototype = new f() Human.prototype.useTools = function(){} var frank = new Human()
- extends关键字
class Animal{ constructor(){ this.body = '肉体' }, move(){} } class Human extends Animal{ constructor(name){ super() this.name = name }, useTools(){} } var frank = new Human()
- 原型链
DOM面试
- DOM事件模型是什么?
- 冒泡
- 捕获
- 如果这个元素是被点击的元素,那么捕获不一定在冒泡之前,顺序室友监听顺序决定的。
- 移动段的触摸事件了解吗?
- touchstart、touchmove、touchend、touchcancel
- 模拟swipe事件:记录两次touchmove的位置差,如果最后一次在前一次的右边,说明右滑了。
- 事件委托是什么?有什么好处?
- 假设父元素有4个儿子,我不监听4个儿子,而是监听父元素,看触发事件的元素是哪个儿子,这就是事件委托。
- 可以监听还没有出生的儿子(动态生成的元素)。省监听器。
function listen(element, eventType, selector, fn){ element.addEventListener(eventType, e=>{ if(e.target.matches(selector)){ fn.call(el, e, el) } }) }// 有 bug 但是可以应付面试官的事件委托 function listen(element, eventType, selector, fn) { element.addEventListener(eventType, e => { let el = e.target while (!el.matches(selector)) { if (element === el) { el = null break } el = el.parentNode } el && fn.call(el, e, el) }) return element } // 工资 12k+ 的前端写的事件委托 listen(ul, 'click', 'li', ()=>{}) ul>li*5>span
HTTP面试
- HTTP 状态码知道哪些?
- 301 和 302 的区别是什么?
- 301 永久重定向,浏览器会记住
- 302 临时重定向
- HTTP 缓存怎么做?
- Cache-Control: max-age=300
- http://cdn.com/1.js?v=1 避开缓存
- Cache-Control 和 Etag 的区别是什么?
- Cookie 是什么?Session 是什么?
- Cookie
- HTTP响应通过 Set-Cookie 设置 Cookie
- 浏览器访问指定域名是必须带上 Cookie 作为 Request Header
- Cookie 一般用来记录用户信息
- Session
- Session 是服务器端的内存(数据)
- Session 一般通过在 Cookie 里记录 SessionID 实现
- SessionID 一般是随机数
- Cookie
- LocalStorage 和 Cookie 的区别是什么?
- Cookie 会随请求被发到服务器上,而 LocalStorage 不会
- Cookie 大小一般4k以下,LocalStorage 一般5Mb 左右
- (必考)GET 和 POST 的区别是什么?
- 参数。GET 的参数放在 url 的查询参数里,POST 的参数(数据)放在请求消息体里。
- 安全(扯淡)。GET 没有 POST 安全(都不安全)
- GET 的参数(url查询参数)有长度限制,一般是 1024 个字符。POST 的参数(数据)没有长度限制(扯淡,4~10Mb 限制)
- 包。GET 请求只需要发一个包,POST 请求需要发两个以上包(因为 POST 有消息体)(扯淡,GET 也可以用消息体)
5.GET 用来读数据,POST 用来写数据,POST 不幂等(幂等的意思就是不管发多少次请求,结果都一样。)
- (必考)怎么跨域?JSONP 是什么?CORS 是什么?postMessage 是什么?
- JSONP
2.CORS
3.postMessage 看一下 MDN
- JSONP
vue面试
- (必考)Vue 有哪些生命周期钩子函数?
- 看文档:生命周期
- (必考)Vue 如何实现组件通信?
- 父子通信(使用 Prop 传递数据、使用 v-on 绑定自定义事件)
- 爷孙通信(通过两对父子通信,爷爸之间父子通信,爸儿之间父子通信)
- 兄弟通信(new Vue() 作为 eventBus)
- Vuex 的作用是什么?
- VueRouter 路由是什么?
- 看文档、博客
- Vue 的双向绑定是如何实现的?有什么缺点?
- 看文档,深入响应式原理
- Computed 计算属性的用法?跟 Methods 的区别。
算法面试
- 排序算法(背诵冒泡排序、选择排序、计数排序、快速排序、插入排序、归并排序)
- 二分查找法
- 翻转二叉树