Lyrics


< More and better />


view

面试总结

绿盟科技

变量存储,堆栈,怎么存储的
for 循环几种方式
内存回收
vue的数据双向绑定,怎么判定绑定的
for的一道题
https
webpack的loader怎么配置
webpack的单文件组件
为什么不用gulp
服务器用过哪些
博客都是自己搭的吗
es6用过哪些
restful api
vue的优点
你对前端的理解
get post delete put

美团 一面

  1. 什么都问
  2. css hack
  3. 深度优先,广度优先,遍历的应用
  4. http头部
  5. cookie 和 session 相关, 出现过什么问题, 项目里面cookie是怎么用的
  6. 项目改进
  7. 实战编程
  8. 实习三个月
  9. instanceof
  10. 状态码
  11. 平时是使用float多还是, 绝对定位多

css hack

  • IE 条件注释法
    1
    2
    3
    4
    <!--[if lt IE 9]>
    <script src="assets/js/html5shiv.js"></script>
    <script src="assets/js/respond.min.js"></script>
    <![endif]-->

cookie 和 session
set-cookie中包含的值:
NAME=VALUE 赋予 Cookie 的名称和其值(必须项)
expires=DATE Cookie 的有效期(若不明确指定则默认为浏览器关闭前为止)
path=PATH 将服务器上的文件目录作为 Cookie 的适用对象(若不指定则默认为文档所在的目录)
domain=域名 作为 Cookie 适用对象的域名(若不指定则默认为创建 Cookie 的服务器的域名)
Secure 仅在 HTTPS 安全通信时才会发送 Cookie
HttpOnly 加以限制,使 Cookie 不能被 Javascript 脚本访问

优雅降级
gulp里面的autorefixer

腾讯

  1. websocket 的 向下兼容的问题
  2. DOMContentLoaded 和 load 区别
  3. es6数组方法使用过什么
  4. 用什么方法可以得到css属性
  5. promise.all 回调
  6. localstorage 爆栈 怎么处理 还有 和cookie的区别
  7. indexedDB 和 loaclStorage 区别
  8. DOM操作的方法
  9. style 和 cssclass 性能问题
  10. 获取元素CSS值方法 获取元素CSS值之getComputedStyle方法熟悉
  11. 数组方法, slice方法, splice方法
  12. css更改样式属性,多种方法
  13. 异步的方法
  14. koa相关
  15. 第二个项目 nodejs出现过什么错误
  16. 一上来就是 nodejs 守护进程
  17. 怎么解决nodejs方面出现的问题
  18. 怎么让浏览器不缓存(请求的时候参数不一样….我说的是cache-control=nocache)
  19. 使用cookie的时候出现过什么问题
  20. ajax中设置跨域, CORS中客户端需要设置什么,除了origin,还有一个什么..
  21. ajax中的readyState 0-4 都代表什么
  22. 如果服务器端返回的是503,ajax怎么获取是503
  23. null 和 undefined 的区别
  24. typeof null 返回什么
  25. 怎么去判断对象是否有这个属性, a[b]不对, 用hasOwnPropotype
  26. 事件机制, 事件代理, 怎么阻止冒泡
  27. 怎么去改变一个css样式, 我说的去获取一个样式表
  28. generator ES6
  29. 状态码:301和302的区别,为什么一个是永久,一个是临时.403
  30. 按需加载,,然后我说webpack code-splitting
  31. 项目啊,问项目了!!!!
  32. mysql连接数上限

css更改样式属性,多种方法
style

className

cssText

美团

  1. 跨域, 然后我自己挖坑说到websocket, 然后他问降级方法, 说到comet,然后简单说了一下,不会了,然后聊websocket,问怎么维护一个多用户的用户列表
  2. url字符串的截取, 去后面的参数,保存到对象.
  3. 安全方式 xss过滤, 你都过滤了什么
  4. MVC 和 MVVM
  5. bind实现, 还有什么其他用处
  6. cookie 跨域
  7. 异步, generator async/awaite
  8. 项目相关

腾讯

  1. jsonp 安全性问题
  2. trim 实现, 去空格
  3. 字符串方法, 数组方法
  4. vue 数据绑定原理
  5. this四个场景
  6. 闭包在项目中的引用, 内存溢出怎么处理的
  7. apply 和 call
  8. 有没有阅读过vue源码
  9. 本地缓存
  10. http缓存机制
  11. url输入之后到渲染一系列变化
  12. 事件的代理
  13. ajax跨域, 遇到的一些问题, cors, jsonp
  14. post 和 get 区别
  15. 数组里面每个下标所对应的值都是原来的两倍, 不用数组遍历的api, 怎么实现

字符串方法

concat() 连接字符串
replace() 利用正则替换
toLowerCase() 转换为小写
toUpperCase() 转化为大写
split() 分割字符串
substr() 从起始索引号提取字符串中指定数目的字符。
substring() 提取字符串中两个指定的索引号之间的字符。
indexof() 检索字符串

trim实现
. 除了换行符以外的任意字符
\w 字母 数字 下划线 汉字
\s 任意空白符
\d 数字
\b 单词开始或结尾
[^x] 出去x以外的任意字符
^ 字符串开始
$ 字符串结尾

  • 重复0次或多次
  • 一次或更多次
    ? 零次或一次
    {n} n次
    {n,} n次或更多次
    {n,m} 重复 n ~ m 次
    *? 重复任意次,但尽可能少重复
    +? 重复1次或更多次,但尽可能少重复
    ?? 重复0次或1次,但尽可能少重复
    去除前后的空格:
  1. string.replace(/^\s+/, “”).replace(/\s+$/, “”);
  2. string.replace(/^\s+(.*?)\s+$/, “$1”)
    1
    2
    ' this is my shite '.replace(/\s*(\b\w+\b)\s*/g, "$1")
    "thisismyshite"

稀疏数组
for(var index in array)去遍历
不要使用for

forEach也一样, map不会遍历那些没被赋过值, 或者delete删除的索引

腾讯

问题:

  1. 跨域都有哪些
  2. 闭包
  3. URL输入之后,都发生了什么
  4. 数组去重(13亿个数,然后辅助空间内存有限制)
  5. 二叉树的遍历
  6. 单例模式
  7. css3新特性

腾讯

问题:

  1. 冒泡排序算法(手写)
  2. 求二叉树的深度(手写)
  3. 有n-1个数,为[1~n-1],现在找出里面少了哪个数(思路)
  4. 堆排序(思路)
  5. tcp滑动窗口
  6. js文件的性能优化
  7. 解决浏览器兼容性问题
  8. 服务器端渲染和客户端渲染

tcp滑动窗口
tcp滑动窗口主要有两个作用, 一个是提供TCP的可靠性, 二是提供TCP的流控特性

原理:

  1. 对于TCP的发送方,任何在发送缓存中的数据都可以分为4类,”已发送并得到对端的ACK”,”已发送未得到对端的ACK”,”未发送但对端的ACK允许发送”,”未发送但对端的ACK不允许发送”

其中”已发送并未得到对端的ACK”和”未发送但对端允许发送”这两个是需要ACK确认请求的,这两个就组成了一个滑动窗口


1 |2 3 |4

  1. 在TCP的接收方,它的接受缓存内存有3种,”已接收”,”未接收准备接收”,”未接收并未准备接收”

“未接收并准备接收” 是需要发送方发送消息的,所以被称为接受窗口

发送窗口取决于接受窗口大小,接受窗口大小取决于本段应用,系统,硬件的限制


1| 2| 3

  1. 发送窗口只有接收到对端对于本段发送窗口的ACK确认,才会移动发送窗口左边界,接收窗口只会在前面所有段都确认的情况下才会移动左边界.
    前面还有字段未接收但收到后面字段的情况下,窗口是不会移动的,并不会对于后续字节确认,确保端会对这些数据重传

tcp滑动窗口根据自己的处理能力变化,通过本端TCP接收窗口大小来控制发送窗口的流量限制

面经

[TOC]


手写jsonp的实现

  1. (默认情况下)浏览器的同源策略把跨域请求都禁止了
  2. HTML的<script>是例外(其实还有iframe,img)都可以突破同源策略
  3. 通过将前端给定的回调函数名作为参数传给后端,然后直接返回已经带有参数的函数调用(字符串,eval或者JSON.parse解析)

http请求头,请求体,cookie在哪个里面?url在哪里面?

cookie在请求头,url也在请求头
cache-control:no-cache不管怎么样都向服务器请求一次,查看资源是否已经被更改
cache-control:no-store禁止浏览器和所有的代理服务器缓存任何的响应,所以每次请求资源都会下载完整的响应

垂直居中,多行文本垂直居中

CSS 的属性 vertical-align 用来指定行内元素(inline)或表格单元格(table-cell)元素的垂直对齐方式。

如果是单行文本垂直居中,只要设置height和line-height相等即可

多行文本父元素不是固定宽度的:可以设置上下一样的padding把父元素撑起来.
多行文本父元素是固定宽度的:可以设置父元素为 display:table,子元素
display:table-cell,这样就可以使用vertical-align了

原型链的解释

函数对象有prototype.不同对象有__proto__
内置属性:
prototype:prototype所指向的空间来存储要共享的属性和方法
__proto__:指向创建它的函数对象原型prototype
constructor:原型对象中constructor属性指向的就是这个构造函数

对象的proto指向自己构造函数的prototype。obj.proto.proto…的原型链由此产生,包括我们的操作符instanceof正是通过探测obj.proto.proto… === Constructor.prototype来验证obj是否是Constructor的实例。

instanceof运算符检测某个构造函数的prototype属性指向的对象是否存在于另外一个对象原型链上.

hasOwnProperty 是 JavaScript 中唯一一个只涉及对象自身属性而不会遍历原型链的方法。

对闭包的理解,get,set闭包实现

  1. 保护函数内部变量的安全:如迭代器,生成器
  2. 在内存中维持变量:如缓存数据,柯里化

当一个函数中使用了其他作用域中的变量, 它就是一个闭包. 闭包能够”记住”其创建时所在的环境,能访问其他作用域中变量.

闭包是通过作用域链来记住当前的执行环境的

创建一个函数时, 这个函数的[[Scope]]下会保存创建时的作用域链, 由于这个作用域链会引用当前活动对象(或者一个Contex), 这就导致了这些对象的内存不能够被回收

避免内存泄漏,就是在退出函数之前把不使用变量都删除

null == undefined ?

null == undefined
true

基本的数据类型

基本数据类型:布尔值,Number,String,
复合数据类型:Array,Object
特殊数据类型:Null(空对象),Undefined(未定义)

基本的两列自适应布局

左定宽,右自适应:

  1. float + margin

    1
    2
    3
    4
    5
    6
    7
    <style>
    p{margin: 0;}
    .parent{overflow: hidden;zoom: 1;}
    .left{position: relative;float: left;width: 100px;}
    .rightWrap{float: left;width: 100%;margin-left: -100px;}
    .right{margin-left: 120px;}
    </style>
  2. calc()

  3. float + margin
    使用overflow属性来触发bfc,来阻止浮动造成的文字环绕效果。
  4. absolute,left和right布局 但缺点就是不能做到“不定宽”,因为.left和.right的left属性的值高度相关。
  5. table布局
  6. flex布局

OSI模型,HTTP,TCP,UDP分别在哪些层

应用层 HTTP
传输层 提供端对端的接口 TCP,UDP

tcp/ip模型:
应用层
网络层
传输层
数据链路层
物理层

网站性能优化

请求数量
合并脚本和样式表
Data URL
css sprites
拆分初始化负载
划分主域
请求带宽
开启Gzip
精简JavaScript
压缩图片 Inline SVG, srcset, css3,IconFont, webP
缓存利用
使用CDN
使用外部js和css
添加Expires(cache-control)
添加ETag试题标签
代码校验以及页面结构
样式表置顶,js置底
按需加载
避免css表达式
避免空src
缓存DOM
使用事件代理,不用事件绑定
使用ID

前端路由和后端路由

后端路由:每次跳转到不同的url,然后重新访问服务器,获取页面
前端路由:跳转到不同的url,都是前端使用的锚点路由,js根据url不同操作dom vue history.pushState

介绍一下webpack和gulp

而各种检查,各种预处理就应该交给gulp之流了,Gulp / Grunt 是一种工具,能够优化前端工作流程。比如自动刷新页面、combo、压缩css、js、编译less等等。

就如前面所说,webpack只是一个模块打包器,所以,交予webpack处理的应该已是经过各种lint检查,各种编译处理的代码

前后端分离的意义以及对前端工程化的理解

Restful Api

(1)每一个URI代表一种资源;
(2)客户端和服务器之间,传递这种资源的某种表现层;
(3)客户端通过四个HTTP动词,对服务器端资源进行操作,实现”表现层状态转化”。

有几种方式可以判断数据类型?

  1. typeof
  2. 判断已知对象类型的方法: instanceof
  3. 根据对象的constructor判断: constructor

ajax

初始化,open,send,onreadystatechange,

responseText和responseXML得到date

事件机制

事件委托
e.target来定位到当前点击的button。

websocket 原理和使用场景

原理:都属于应用层协议,基于TCP,HTML5提供了一些API,websocket利用http来建立连接,建立之后就与http无关了,双向实时通讯
场景:社交聊天、弹幕、多玩家游戏、协同编辑

前端路由实现原理

方法一:
history.pushState 和 history.replaceState
方法二:
hash也就是锚点, 需要一个hashcahnge函数

ES6有什么特性,promise实现原理

  1. 箭头函数
  2. let
  3. Proxy
  4. 解构赋值
  5. 尾递归优化
  6. 模板字符串
  7. Promise

promise实现原理:
有三种状态:等待(pending),已成功(fulfilled),已拒绝(rejected)
只能从等待转换到fulfilled或者rejected,不存在其他的转化路径
promise必须实现then方法,而且then方法必须返回一个promise,然后回调函数的执行顺序就是promise被定义的执行顺序
then有两个参数,一个是成功(reslove)的回调函数,一个是失败(rejected)的回调函数

手写after方式清除浮动,一个冒号和两个冒号的区别

1
2
3
4
5
::after{
content: "";
display: table;
clear: both;
}

一个冒号是伪类,两个冒号是伪元素

nth-child(n) 和 nth-type(n)区别

li:nth-child(n) 父元素的第n个子元素,而且这个子元素是li
li:nth-type(n) 父元素第n个li元素

函数声明有哪几种形式,function aaa(){} 和var aaa= function(){}有什么区别

  1. 函数声明
  2. 函数表达式
  3. new Function()

函数声明和函数表达式的区别:函数声明会提前,但是函数表达式只会提前函数声明,函数的初始化代码还是在原来的位置

跨域的实现方法

  1. jsonp jsonp只能发送get请求
  2. document.domain来跨子域
  3. window.name
  4. window.postMessage
  5. CORS cors会忽略cookie
  6. 服务器跨域 服务器跨域需要另起服务器

src和href的区别

href:并行下载该文档,并且不会停止对当前文档的处理。这也是建议使用link,而不采用@import加载css的原因。
src:当浏览器解析到该元素时,会暂停浏览器的渲染,知道该资源加载完毕。这也是将js脚本放在底部而不是头部得原因。

(1) link属于HTML标签,而@import是CSS提供的;
(2) 页面被加载的时,link会同时被加载,而@import引用的CSS会等到页面被加载完再加载;
(3) import只在IE5以上才能识别,而link是HTML标签,无兼容问题;
(4) link方式的样式的权重 高于@import的权重.

事件代理

1
2
3
4
5
6
7
8
document.getElementById("parentlist").addEventListener("click",function(e) {
// 检查事件源e.targe是否为Li
if(e.target && e.target.nodeName.toUpperCase() == "LI") {
// 真正的处理过程在这里 //
alert(123);
console.log("List item ",e.target.id," was clicked!");
}
});

你认为什么是前端

前端工程–基础篇
为了提升其前端开发效率和运行性能
库/框架选型
简单构建优化
JS/CSS模块化开发
组件化开发与资源管理

怎么阻止冒泡,怎么阻止默认事件

阻止冒泡: e.stopPropagation()
阻止默认事件: e.preventDefault(), return false

HTTP2.0

改进传输性能,实现低延迟和高吞吐量

  1. 二进制分帧层,是在应用层和传输层之间加了一层,会将所有传输的信息
  2. 分割为更小的消息和帧,并用二进制方式编码(首部->Header帧,request body -> Data帧)
  3. 首部压缩,,对于相同的数据,不再通过每次请求和响应发送首部表
    所有请求都在一个TCP链接上
  4. 并行双向字节流的请求和响应
  5. 服务器推送

状态码

200: ok 正常请求,返回相应内容
204: No Content 没有新文档,继续使用原来的文档
301: 永久重定向 Location首部包含资源现在的URI
302: 临时重定向 Location
303: 临时重定向 但是post变为get Location
400: 存在语法错误
401: 未认证
403: 请求被拒绝,权限受限
404: Not Found 资源未找到
500: 表示服务器在执行请求时候,发生错误
503: 服务器暂时处于超负荷或停机维护,无法处理请求

HTML5

  1. 语义化标签
  2. 音频视频API
  3. Canvas
  4. 地理API
  5. LocalStorage
  6. SessionStorage
  7. 表单控件
  8. inline SVG
  9. web worker

CSS3

  1. 圆角
  2. 阴影
  3. 渐变
  4. 旋转(rotate), 缩放(scale), 定位(translate), 倾斜(skew)
  5. 高级选择器
  6. WebFont
  7. 媒体查询
  8. 新增伪类

http 请求方法

head: 和get一样只是,没有相应主体

get: 获取资源

put : PUT请求是向服务器端发送数据的,从而改变信息,该请求就像数据库的update操作一样,用来修改数据的内容,但是不会增加数据的种类等,也就是说无论进行多少次PUT操作,其结果并没有不同。

post : POST请求同PUT请求类似,都是向服务器端发送数据的,但是该请求会改变数据的种类等资源,就像数据库的insert操作一样,会创建新的内容。几乎目前所有的提交操作都是用POST请求的。

DELETE: 删除资源

OPTIONS: 返回服务器支持的所有的HTTP请求方法

TRACE: 回显其收到的请求信息, HTTP请求的测试

PATCH: put是资源的整体更新,patch是部分更新

el:nth-child(n) 和 el:nth-of-type(n)

elem:nth-of-type(n)是“选择父元素下第n个elem元素”。

而elem:nth-child(n)是“这个伪类选中父元素下的第n个子元素,并且个子元素的标签名为elem”。

判断数据类型

typeof
instanceof
constructor
Object.prototype.toString.call(value)

let 和 var

没有变量提升
块级作用域
不能重复声明
const 常量

函数式编程

  1. 函数是”第一等公民”
  2. 只用”表达式”,不用”语句”
  3. 没有”副作用”
  4. 不修改状态
  5. 引用透明

箭头函数 和 普通函数

(1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。

(2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。

(3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用Rest参数代替。

(4)不可以使用yield命令,因此箭头函数不能用作Generator函数。

HTML5 离线缓存

webStorage
manifest
indexedDB & webSQL

BFC

BFC: 就是创建了一个独立的盒子, 这个盒子内部不受外部的影响, 也不会影响外部元素
但是它有一些特性:

  1. 解决margin叠加的问题
  2. 可以包含浮动元素,防止父元素高度塌陷
  3. 防止块级元素被浮动元素覆盖.

触发条件:

  1. float 除了 none
  2. 绝对定位
  3. display: inline-block 和 table-cell
  4. overflow 除了 visible

清楚浮动

  1. 空标签 clear both
  2. 父元素浮动
  3. overflow: hidden
  4. 伪元素 after
  5. BFC

浮动

浮动的框可以向左或向右移动,直到它的外边缘碰到包含框或另一个浮动框的边框为止。由于浮动框不在文档的普通流中,相当于不占用空间,所以文档的普通流中的块框表现得就像浮动框不存在一样。

inline-block 间隙

缘由: 换行符或回车
去除方法: 书写格式, font: 0, 负margin

png gif jpg选择

Chrome Data Compression Proxy 来 让chrome 所有图片都为webp格式
不能支持的, webpjs插件
安卓4.0原生支持,ios和4.0以后可以使用官方解析库

webpack优点

loader
插件
热替换
code-splitting
tree-shaking

规避同源策略

除了代理服务器

  • jsonp
    简单适用,浏览器都可以支持
  • websocket
    是一种通信协议, 只要服务器支持就可以通过它进行跨域通信, origin表示请求源
  • CORS
    CORS分为两种请求:
    是 HEAD, GET, POST三种方法之一, 只能是content-type: appliction/x-www-from-yrlencodeed, mutipart/form-Data, text/plain之一, 就是简单请求, 其他的都是非简单请求.
    简单请求:
    浏览器直接发送CORS请求, 然后再头部加上origin, 如果origin指定的源不在许可的范围内, 服务器返回的头部没有access-control-allow-orogin 字段, 可以被XHR的onerror捕获.
    如果是许可范围内的,服务器头部返回这些信息字段:
    1
    2
    3
    access-control-allow-origin : xxx,
    access-control-allow-credentials: true, //跨域cookie,该字段表示该跨域请求是否允许带上cookie
    access-control-expose-headers: Foobar //本来getResponseHeader(),只可以拿到Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma,然后设置这个之后, 就可以取Foobar的值

要想cookie跨域,在服务器端设置access-cotrol-allow-credentials,还需要在ajax中设置xhr.withCredentials = true, document.cookie无法读取跨域的cookie
非简单请求:
put, delete, 或者 content-type 是 application/json的请求, 首先会发送一个 options 请求, 预检 是否在服务器允许跨域的列表里, 还有允许的http请求方法和信息字段.
Access-Control-Request-Method, Access-Control-Request-Headers

前端图片缓存

在js加载和执行的时候, 浏览器会停止渲染, 直到js文件加载执行完毕

几个http缓存头部优先级: cache-control > expires > Etag > last-modified

web worker缺点

堆和栈的区别

堆(操作系统): 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。
由于从操作系统管理的内存分配,所以在分配和销毁时都要占用时间,因此用堆的效率非常低.但是堆的优点在于,编译器不必知道要从堆里分配多少存储空间,也不必知道存储的数据要在堆里停留多长的时间,因此,用堆保存数据时会得到更大的灵活性。
是不连续的内存区域(一定限制的树型结构)

栈(操作系统):由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。是一块连续的内存的区域.(先进后出)

ajax遇到gbk

发送请求时候: encodeURI(), encodeURIComponent() , 解码decode…
服务器相应的时候: 在头部加上Content-Type:text/html;charset=GB2312

跨域

script为什么可以跨域:
可以加载并执行其他域JS文件
因为不能阻止,比如使用别人的库或者框架 , get请求比较安全

postmessage实现跨域的原理是什么:
会在所有页面脚本执行完毕之后(e.g., 在该方法之后设置的事件、之前设置的timeout 事件,etc.)向目标窗口派发一个 MessageEvent 消息。
替代window.name、url查询字符和hash片段

1
2
var popup = window.open('http://bbb.com', 'title');
popup.postMessage('Hello World!', 'http://bbb.com');

js捕获异常

try-catch 只能在单一的作用域内有效。在一个异常被抛出的同时,解释器就会从 try-catch 中离开,ajax也是一样的。所以有两种选择,一种是在异步调用里面捕获异常:
全局异常处理可以在任何执行上下文中执行

前后端分离

  1. 彻底解放前端
  2. 提高工作效率,分工更加明确
  3. 局部性能提升
  4. 降低维护成本

闭包的使用场景

在网页中有时候会需要遮罩层,调用的时候我就创建一个,但是你不可能每次调用创建吧,所以如果存在就用以前的,如果不存在就创建新的,但同时有可能我永远都不需要这个遮罩层,所以我也有可能一直都不需要创建。

添加监听器时记录索引

模拟private变量

柯里化