Coder Social home page Coder Social logo

blog's People

Contributors

54017 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

amberliuo-o

blog's Issues

浏览器渲染实验

测试环境:IPhone 5 IOS 8, Macbook Pro 2015, Chrome 51.0 (64-bit), FireFox 47.0, Safari 9.1.1, 微信 IOS 6.3.21, 小米手机

❌ 表示阻塞首屏渲染 / 进度条. ✔️ 表示不阻塞. 🚫 表示浏览器不支持. ❗ 表示特殊情况,底部会有说明

结论

通过下表可以观察出前端的最佳实践是

  1. HTTP Headers 设置 Transform-encoding: chunked (flush)
  2. link 放在 head 中,对于较小的 CSS 应该内联,减少请求数
  3. 使用 link dns-prefetch 进行 dns 预查询

PC 端

  1. script 放在 \body 前

WebView

  1. 对于不在乎执行顺序的 script, 使用 async 属性
  2. 不使用 window load 事件

页面渲染

测试点 image 标签 flush (chunked) ajax video 标签
URL image.html chunked.html ajax.html video.html
IOS WebView ✔️ ✔️ ✔️
IOS Safari ✔️ ✔️ ✔️
Android 系统浏览器 ✔️ ✔️ ✔️ ✔️
Android WebView ✔️ ✔️ ✔️ ✔️
Chrome ✔️ ✔️ ✔️ ✔️
FireFox ✔️ ✔️ ✔️ ✔️
Safari ✔️ ✔️ ✔️
IE 10 ✔️ ✔️ ✔️ ✔️
IE 9 ✔️ ✔️ ✔️ ✔️
IE8 ✔️ ✔️ ✔️ 🚫

注明:

  1. Chrome Timeline 中 Paint 只是绘制操作,需要等待渲染层合并 Composite Layers 页面才可见。 在 HTML 中间插入 Script 只会触发 Paint,当 Script 执行时间超过 500 ms 时才会执行 Composite Layers
  2. flush (chunked) 实现方法是通过 Node.js 的 Transfrom-encoding:chunked 和 setTimeout 返回 HTML 文档实现
页面最前(head 内) 页面最前(head 内) 页面最前(head 内) 页面最后(/body 前) 页面最后(/body 前) 页面最后(/body 前)
测试点 script script async 内联 script script script async 内联 script
URL script-head.html script-head-async.html script-head-in.html script-tail.html script-tail-async.html script-tail-in.html
IOS WebView ✔️ ✔️
IOS Safari ✔️ ✔️
Android 系统浏览器 ✔️ ✔️ ✔️
Android WebView ✔️ ✔️
Chrome ✔️ ✔️ ✔️
FireFox ✔️ ✔️ ✔️
Safari ✔️ ✔️ ✔️
IE 10 ✔️ ✔️ ✔️
IE 9 ✔️
IE8 ✔️

❗ :

  1. Android WebView 对于 /body 前的 script 会时不时的阻塞页面,也有可能如 Chrome 一样将前面的 DOM 渲染显示出来
  2. IE9 和 IE8 位于 /body 前的 async script 虽然不阻塞页面渲染,但是会阻塞后续的 script 执行
页面最前(head 内) 页面最前(head 内) 页面最前(head 内) 页面最后(/body 前)
测试点 link link shortcut icon link dns-prefetch link
URL link-head.html link-icon.html link-dns.html / link-dns-off.html link-tail.html
IOS WebView ✔️ ✔️
IOS Safari ✔️ ✔️
Android 系统浏览器 ✔️ ✔️
Android WebView ✔️ ✔️
Chrome ✔️ ✔️
FireFox ✔️ ✔️
Safari ✔️ ✔️
IE 10 ✔️ ✔️
IE 9 ✔️ ✔️
IE8 ✔️ ✔️

❗ :

  1. FireFox, IE 10, 9, 8 会先渲染出页面内容,CSS 加载完毕后再次渲染,所以会出现无样式闪现

注明:

  1. link shortcut icon 加载的资源会被浏览器缓存,强制刷新无法清除,只能通过修改版本号来重新请求,它的加载也不会阻塞 load 事件
  2. 小米手机的微信 WebView favicon.ico 会被重复请求 4 次

进度条

测试点 image 标签 flush (chunked) ajax video 标签
URL image.html chunked.html ajax.html video.html
IOS WebView ✔️ ✔️
IOS Safari ✔️ ✔️
Android 系统浏览器 ✔️ ✔️
Android WebView ✔️ ✔️
Chrome ✔️
FireFox ✔️
Safari ✔️ ✔️
IE 10 ✔️ ✔️
IE 9 ✔️ ✔️
IE8 ✔️ 🚫

❗ :

  1. Chrome 加载 Video 进度条会延迟几秒才加载完(此时Video还未加载完毕)
  2. FireFox 会在收到首个响应包时完成进度条
页面最前(head 内) 页面最前(head 内) 页面最前(head 内) 页面最后(/body 前) 页面最后(/body 前) 页面最后(/body 前)
测试点 script script async 内联 script script script async 内联 script
URL script-head.html script-head-async.html script-head-in.html script-tail.html script-tail-async.html script-tail-in.html
IOS WebView
IOS Safari
Android 系统浏览器 ✔️
Android WebView
Chrome
FireFox
Safari ✔️ ✔️
IE 10
IE 9
IE8
页面最前(head 内) 页面最前(head 内) 页面最前(head 内) 页面最后(/body 前)
测试点 link link shortcut icon link dns-prefetch link
URL link-head.html link-icon.html link-dns.html / link-dns-off.html link-tail.html
IOS WebView ✔️ ✔️
IOS Safari ✔️ ✔️
Android 系统浏览器 ✔️ ✔️ ✔️ ✔️
Android WebView ✔️ ✔️
Chrome ✔️ ✔️
FireFox ✔️ ✔️
Safari ✔️ ✔️ ✔️ ✔️
IE 10 ✔️ ✔️
IE 9 ✔️ ✔️
IE8 ✔️ ✔️

后续资源阻塞实验

测试点 最大并发数 link 阻塞 script script 阻塞 script link 阻塞 link
URL
IOS WebView 4 ✔️ ✔️ ✔️
IOS Safari 6 ✔️ ✔️ ✔️
Android 系统浏览器 7 ✔️ ✔️ ✔️
Android WebView 6 ✔️ ✔️ ✔️
Chrome 6 ✔️ ✔️ ✔️
FireFox 6 ✔️ ✔️ ✔️
Safari 6 ✔️ ✔️ ✔️
IE 10 1
IE 9 1
IE8 1

注明:

  1. 现代浏览器遇到 script / link 标签时,main thread 会挂起对 DOM Tree 的解析,但这不会阻塞后续资源的加载。浏览器会使用另一个线程向后寻找外部资源并进行加载,这个过程不会对 DOM Tree 产生任何影响。当 script 中的 JS 执行完毕后继续 DOM Tree 的解析。
  2. 上图中的不阻塞的前提条件是当前连接没有超过最大并发数,超过了就会阻塞
  3. script 的加载和执行都不会阻塞后续资源(除了IE)
  4. 通过抓包得知最大并发数,故不提供 URL 检验

window.onload && window.addEventListener('load') 触发情况

测试点 audio audio preload="auto" audio preload="meta" audio preload="none" audio autoplay video video preload="auto" video preload="meta" video preload="none" video autoplay
URL audio-load.html audio-load-auto.html audio-load-meta.html audio-load-none.html audio-autoplay.html video.html video-load.html video-load-meta.html video-load-none.html video-autoplay.html
IOS WebView ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️
IOS Safari ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️
Android 系统浏览器 ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️
Android WebView ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️
Chrome ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️
FireFox ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️
Safari ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️
IE 10 ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️
IE 9 ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️
IE8 🚫 🚫 🚫 🚫 🚫 🚫 🚫 🚫 🚫 🚫

❗ :

  1. 对于 IOS, audio preload-none 需要在点击播放按钮后才可以触发 window load 事件

注明:

  1. window load 事件一般在获得 video / audio 首包后触发

阿里巴巴前端面试经历

阿里2017前端工程师实习offer总结

前言

博主不久以前刚拿到阿里巴巴蚂蚁金服的前端开发offer,经历了五轮技术面,一轮HR面,历时约三个星期(哈哈连面试官都喷了我的面试体验)。 在这里分享一下面试经历希望帮助一下大家,一些面试题的答案和部分整理的小知识会贴在后面。

技术一面

刚内推完1个小时,北京蚂蚁金服就打来了电话,是一个声音很有磁性的大哥哥(?)。自己完全没有准备,因为没有想到会这么快,紧张死了。 然后问了一些前端方面的知识,如下

  1. JavaScript基本数据结构
  2. IE和Chrome事件模型的区别
  3. 事件委托
  4. 跨域问题,JSONP的原理
  5. 常见HTTP状态码
  6. Style标签放置的最佳位置
  7. GET和POST的区别
  8. 常见行内元素和块级元素
  9. cookie和session区别
  10. 项目和实习经历

一面大概就是这么多,持续了十几分钟,博主一面后以为药丸了,因为太紧张答的很不好,行内元素和块级元素列举了四五个后居然就说不下去了,然后大哥哥很贴心的说出一个个标签然后让我回答是行内还是块级. 居然还有二面,真的很感激这位面试官。

技术二面

一面完的第二天二面电话就来了,应该是技术总监,很有威严的感觉,约了下午两点,然后很准时的打过来了,期间博主拉着两个小伙伴在我旁边听我面试壮胆。问的问题都比一面深入了些,下面列出一些还记得的问题

  1. jQuery对象和JS的Element有什么区别(考实时性)
  2. jQuery对象是怎么实现的
  3. 给定一个链表找出中间的对象
  4. jQuery级联的实现
  5. WebGL渲染的过程
  6. position定位问题(absolute, relative)
  7. 闭包原理
  8. 3点一刻时针和分针的夹角

电面持续了半小时,问了挺多东西的,可是博主都忘掉啦。 答的也不算特别好,jQuery对象的实现都没答出来,药丸。 然后最后的问题,我一直答夹角为0度,233333,蠢成猪了。面完之后觉得二面过不了了,正在伤心的时候,面试官又打过来说要我去北京现场面试 ,说去联系HR后再通知我。

技术三面(视频)

过了三天后面试官又打过来说安排视频面试(好开心,不用现场面),然后博主赶紧剃了胡子,洗了脸,剪了头发。视频过来居然看的到面试官的脸啊哈哈哈哈,还以为只能他看我呢。 面试官应该还是技术总监,萌萌哒的,所以不是特别紧张。问了很多问题,持续了一小时,期间面试官还对我笑了2333333。

  1. Cache-control
  2. 项目中遇到的困难
  3. 浏览器渲染过程
  4. 手写一个冒泡排序处理事务(这里应该是考模块化和易扩展的类的**,博主GG)
  5. 圣杯布局多种解决方式
  6. React的diff原理和组件化**
  7. 浏览器缓存策略
  8. canvas的使用
  9. 树叶飘落动画的实现
  10. React Native
  11. 想在杭州还是北京工作

在面试中面试官说我所面的部门是蚂蚁金服里的蚂蚁聚宝,大多数技术人员在北京,不过博主还是说想去杭州,因为担心在北京活不下去哈哈。

技术四面

过了很久很久大概一个多星期吧,阿里杭州那边的电话打过来了,接电话的时候高兴的要命,以为是HR呢,然后发现还是技术。问的问题挺少的,主要问博主实习的工作,然后问了响应式布局和H5开发(博主不太明白主要需要说哪方面,乱说了一通)。

技术五面

又过了挺久吧,第五个电话从杭州打过来了,又以为是HR,又白开心了一下,我说我都面了五面了,面试官苦笑一下说我的面试体验太差了哈哈。 然后问的问题也比较少,主要是模块化**,组件化**吧,最后挂电话的时候说聊的不错,博主也觉得还不错2333333.

HR面

再一次过了很久很久,第六个电话打过来啦,博主当时在雨中前行着,和HR说不太方便,然后HR说只需要15分钟,然后我担心挂掉后就不会再打过来了,然后就开始面试了,之前就听说阿里HR有一票否决权,所以还很是担心,不过这位HR大姐姐还是很温柔的,问的问题杀伤性也不太大

  1. 和同学做过的最好的项目(考团队合作?)
  2. 项目中遇到的困难
  3. 有什么业余爱好(弹吉他,HR笑着问参加过比赛了吗,有没有粉丝,博主说没有,HR沉默了)
  4. 实习经历(博主大二暑假在UC实习过哒)
  5. 有没有女朋友(excuse me? HR说的时候自己都笑的花枝招展了)

博主最后问了HR阿里的工作氛围啦,HR说和UC很像,都是阿里系,轻松愉快萌萌哒的。 然后说最后的结果要等校招完统一通知,当时听到就觉得心痛,要是内推没过那岂不是GG了,校招又不能参加了,绝望的挂掉了电话。 不久以后三面技术官问我什么时候可以去实习,然后希望我早点去,博主也想早点去,可是有必修课啊啊啊,然后婉拒了。 面试官无奈的说就按照你的时间来吧。 当时还不敢跟他说HR拖着我offer呢。 不过过了几个小时后,offer就发到博主手机和邮箱啦,开心到哭泣。

好了,水了这么多,上一点点干货吧

小知识点

JS一切皆对象

数组!!!! a = [1, 2]....b[0] = a;
b[0][0] === 1; a[0] = 2; 那么b[0][0] === 2

运算符优先级

&&的优先级比||要高

行内元素&块级元素

在标准文档流里面,块级元素具有以下特点:

  1. 总是在新行上开始,占据一整行

    //他们将处在同一行
    <div>一二三</div>
    <span>四五</span>
    //他们将处在不同行
    <span>四五</span>
    <div>一二三</div>
  2. 高度,行高以及外边距和内边距都可控制;

  3. 宽带始终是与浏览器宽度一样,与内容无关;

  4. 它可以容纳内联元素和其他块元素。

行内元素的特点:

  1. 和其他元素都在一行上;
  2. 高,行高及外边距和内边距部分可改变;
  3. 宽度只与内容有关;
  4. 行内元素只能容纳文本或者其他行内元素。不可以设置宽高,其宽度随着内容增加,高度随字体大小而改变,搜索内联元素可以设置外边界,但是外边界不对上下起作用,只能对左右起作用,也可以设置内边界,但是内边界在ie6中不对上下起作用,只能对左右起作用

ChildNodes && Children

<p title="The test paragraph">
    <strong>fsdsad</strong>
</p>

document.getElementsByTagName('p')[0].childNodes.length === 3
<p>后的换行符为一个文本节点,<strong>为一个节点<\strong>后的换行符为一个节点

变量/函数提升

第 1 种: function foo(){...} (函数声明)

第 2 种: var foo = function(){...} (等号后面必须是匿名函数,这句实质是函数表达式)

只有函数声明可以被提升

Position

  1. 对于position: absolute,元素定位将相对于最近的一个relative、fixed或absolute的父元素,如果没有则相对于body;
  2. position absolute / fixed 会脱离文档流,其他不会

写一个XMLHttpRequest

if (window.XMLHttpRequest) {
    var request = new XMLHttpRequest();
} else if (window.ActiveXObject("Microsoft.XMLHTTP")) {
    var request = new ActiveXObject("Microsoft.XMLHTTP")
}
request.open("GET", url, true) //第三个参数是异步
request.onreadystatechange = function() {
    if (request.readyState == 4) {
        if (request.status == 200 || request.status == 302) {
            alert(request.responseText);
        }
    } 
request.send();
}

readyState5种状态

状态 含义
UNSENT 0 open()尚未调用
OPENED 1 open()已调用
HEADERS_RECEIVED 2 send()已调用,收到响应头
LOADING 3 正在接受响应主体
DONE 4 响应完成

POST提交数据的方式

application/x-www-form-urlencoded

最常见,默认的方式
提交的数据按照query string的方式传递,键和值都会被URI转码比如title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3

multipart/form-data

使用表单上传文件时,必须让form的enctyped变为它,一下为一个请求示例

POST http://www.example.com HTTP/1.1
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA

------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="text"

title
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png

PNG ... content of chrome.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA--

首先生成了一个boundary用于分割不同的字段,为了避免与正文内容重复,boundary很长很复杂,然后Content-Type里指明数据是以multipart/form-data来编码的。 消息主体里按照字段个数分为多个结构类似的部分,每部分都是以boundary开始

POST, GET区别

  • GET用来从服务端获取数据,POST用于上传或者修改数据
  • GET大小限制在2KB以内,POST一般没有限制
  • GET参数在URL,POST参数在请求主体中(也就是用send发送),安全性POST高
  • 部分浏览器会缓存GET请求的response,以至于相同的GET请求会得到相同的response即使服务端的数据已经改变,POST不会被缓存
  • 使用XMLHttpRequest时,POST需要显示指定请求头(因为Post一般含有entity-body)
  • xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded;"); //用POST的时候一定要有这句 (Content-Type可以不一样)

JS同源策略

URL由协议、域名、端口和路径组成,如果两个URL的协议、域名和端口相同,则表示他们同源。

同源策略:

浏览器的同源策略,限制了来自不同源的"document"或脚本,对当前"document"读取或设置某些属性。从一个域上加载的脚本不允许访问另外一个域的文档属性。

比如一个恶意网站的页面通过iframe嵌入了银行的登录页面(二者不同源),如果没有同源限制,恶意网页上的javascript脚本就可以在用户登录银行的时候获取用户名和密码。

http://localhost:8080/test.html

<html>  
     <head><title>test same origin policy</title></head>  
     <body>  
         <iframe id="test" src="http://localhost:8081/test2.html"></iframe>  
         <script type="text/javascript">  
             document.getElementById("test").contentDocument.body.innerHTML = "write somthing";  
         </script>  
     </body>  
</html>  

http://localhost:8081/test2.html

<html>  
    <head><title>test same origin policy</title></head>  
    <body>  
        Testing.  
    </body>  
</html>  

这样是不可以的permission denied.

跨域方法

  1. JSONP( only GET )

从外部通过<script>引用的文件和当前文档属于同一个域, 这也是之所以可以调用JS中的属性方法对当前文档DOM进行操作。
JSONP就是利用<script>标签的跨域能力实现跨域数据的访问,请求动态生成的JavaScript脚本同时带一个callback函数名作为参数。其中callback函数本地文档的JavaScript函数,服务器端动态生成的脚本会产生数据,并在代码中以产生的数据为参数调用callback函数。当这段脚本加载到本地文档时,callback函数就被调用。

第一个站点的测试页面(http://localhost:8080/test.html):

<script>  
    function test_handler(data) {  
         console.log(data);  
     }  
 </script>      
 <script src="http://localhost:8081/test_data.js">  

服务器端的Javascript脚(http://localhost:8081/test_data.js):

test_handler('{"data": "something"}');

  1. 图像ping
  2. CORS

浏览器渲染过程(Chrome)

  1. 浏览器获得HTML构建DOM Tree, 获得CSS构建CSSOM (当遇到JS/script时,DOM构建过程会被吊起,需要等待JS执行完毕,当JS全部执行完后,触发DOMContentLoaded)
  2. 通过DOM Tree和CSSOM构建Render Tree
  3. 计算layout (size, position)
  4. 绘制
  5. 渲染层合并(transform opacity只触发这个阶段因此速度快)

为了更好的用户体验渲染引擎会尽快的展示出页面内容,它不会等到所有HTML都被解析再来构建渲染树, 当main thread(而不是Speculative)遇到Script标签时(只要遇到并不需要等待其网络返回和执行)Chrome会执行绘制和渲染层合并操作

当没有script标签时,如果link在\body前,firefox会重绘制导致FOUC,而Chrome会等待css加载完毕(和放在head中行为相同)

标签位置

最佳实践是将link标签置于script标签前(否则有FOUC)。script最佳实践是放在/body前(放在head会导致白屏现象)

BFC(块级格式化上下文)

一个BFC是一个至少满足以下一个条件的盒子:

  1. float不为none
  2. overflow不为visible
  3. display为table-cell, table-caption或者inline-block, flex, inline-flex
  4. position不为static或者relative
  5. 根元素

特征:

  1. 内部的盒会在垂直方向一个接一个排列(可以看作BFC中有一个的常规流);
  2. 处于同一个BFC中的元素相互影响,可能会发生margin collapse;
  3. 每个元素的margin box的左边,与容器块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此;
  4. BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然;
  5. 计算BFC的高度时,考虑BFC所包含的所有元素,连浮动元素也参与计算;
  6. BFC的区域不会与float的元素区域重叠

BFC包含创建该上下文元素的所有子元素,但不包括创建了新BFC的子元素的内部元素。(一个元素不能同时存在于两个BFC中

边距塌陷

  1. 相邻块级元素
  2. 父元素,子元素
    当没有border, padding, inline content或者clearance隔开父子元素的margin-top(bottom)和margin- top(bottom)时
  3. 空盒子(没有border, padding, inline content, height, min-height把盒子的margin-top和margin-bottom隔开的话会产生边距塌陷)

clear

相关的floats: 处于同一个BFU的处于该块前面的floats

  1. 运用到non-floating块
    这个non-floating块将会被向下移直到其border-edge在相关的floats的margin-bottom下(因此可以去除边距塌陷)
  2. 运用到floating块
    这个floating 块将被下移至其margin边缘在相关floats的margin边缘下(这会影响该floating块后续floating块,因为后续的floating块不能比前面的position高)

attachEvent & addEventHandler

微软IE6, 7, 8支持attachEvent, 它只支持冒泡事件模型

addEventListener支持捕获和冒泡,先捕获后冒泡

事件委托

document.addEventListener('click', function(e) {
    if (e.target = 'xxx') {
        ...
    } else if (e.target = 'yyy') {
        ...
})

注意父子元素

<div class="wrapper">
    <div class="content">
        我是子元素
    </div>
</div>
document.getElementById('wrapper').addEventListener('click', function(e) {
    console.log("wrapper")
});

document.getElementById('content').addEventListener('click', function(e) {
    console.log("content")
});

即使用定位absolute将子元素content移到父元素外,点击子元素会触发父元素的click事件(事件委托的机制,当子元素事件被触发,事件会向上传递)

Cache-Control

请求头包括: no-cache, no-store, max-age, max-stale, min-fresh, only-if-cached(只从cache里面拿)

响应头包括: public, private, no-cache, no-store, no-transform, must-revalidate, proxy-revalidate, max-age. 默认为private

private: 私有缓存,常见就是浏览器里内置的缓存

public: 公有缓存,常见的是代理缓存

  • 请求头中的Cache-Control为no-cache, 缓存服务器会执行validation, 否则如果请求的资源没有过期的话缓存服务器会直接发回这个资源,有了 no-cache 缓存服务器无论资源是否过期都会去validate
  • 请求头中的Cache-Control为Max-age=0, 请求链路上所有cache都会revalidate,通过if-modified-since字段,如果origin server 发现not modified则返回304(不会发送资源来节约带宽)。 当Max-age = n时表示接收在n这个时间里保持新鲜的资源
  • 响应头中的Cache-Control: max-age=259200 (max-age=0, must-revaliate 和 no-cache相同),设置freshness时间
  • Cache-Control "max-age=3600, must-revalidate"
    it is telling both client caches and proxy caches that once the content is stale (older than 3600 seconds) they must revalidate at the origin server before they can serve the content. This should be the default behavior of caching systems, but the must-revalidate directive makes this requirement unambiguous.
  • 响应头中的Cache-Control: no-cache告诉cache无论何时不管怎样必须revalidate

ETag

ETag(EntityTags)是URL的tag,用来标示URL对象是否改变,这样可利用客户端(例如浏览器)的缓存。由服务器首先产生ETag,客户端通过将该记号传回服务器要求服务器验证其(客户端)缓存。服务器使用它来判断页面是否已经被修改,如果未修改返回304,而不必重新传输整个对象。
户端通过If-Match或者说If-None-Match这个条件判断请求来验证资源是否修改。我们常见的是使用If-None-Match.请求一个文件的流程可能如下:
  

  1. 客户端发起HTTP GET请求一个文件;  
  2. 服务器处理请求,返回文件内容和一堆Header,当然包括Etag(例如"1ec5-502264e2ae4c0")(假设服务器支持Etag生成和已经开启了Etag).状态码200。 
  3. 客户端发起HTTP GET请求一个文件,这个时候客户端同时发送一个If-None-Match头,这个头的内容就是我们第一次请求时服务器返回的Etag:1ec5-502264e2ae4c0
  4. 服务器判断发送过来的Etag和计算出来的Etag是匹配的,不返回200,返回304,让客户端继续使用本地缓存。

new & Object.create

new Test()
//做的工作如下
1. create new Object() obj
2. set obj.__proto__ to Test.prototype
3. return typeof Test.call(obj) === 'Object' ?  Test.call(obj) : obj;
Object.create(Test.prototype)
//做的工作如下
1. create new Object() obj
2. set obj.__proto__ to Test.prototype
3. return obj;

所以你应该明白了,如果构造函数返回了一个对象(非primitive value),那么就返回这个对象,否则返回函数内创造的继承了原型链的对象。 当return null时,还是会返回obj即使typeof null是object

Cookie & Session

Cookie

如果不设置过期时间,则表示这个cookie生命周期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了。

这种生命期为浏览会话期的cookie被称为会话cookie。会话cookie一般不保存在硬盘上而是保存在内存里。

如果设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie依然有效直到超过设定的过期时间。存储在硬盘上的cookie可以在不同的浏览器进程间共享,比如两个IE窗口。而对于保存在内存的cookie,不同的浏览器有不同的处理方式。

因为cookie会在所有的请求中都被附上,例如图片。所以将图片等静态资源放在其他不需要cookie的域名下会节约带宽

Session

Session是服务器端使用的一种记录客户端状态的机制,使用上比Cookie简单一些,相应的也增加了服务器的存储压力。

cookie 和session 的区别:

1、cookie数据存放在客户的浏览器上,session数据放在服务器上。 cookie为字符串,session可以存储服务端支持的各种数据类型

2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗
考虑到安全应当使用session。

3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
考虑到减轻服务器性能方面,应当使用COOKIE。

4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。

5、所以建议:
将登陆信息等重要信息存放为SESSION
其他信息如果需要保留,可以放在COOKIE中

腾讯微信前端面试经历

微信前端工程师实习面试总结

博主在校招季一共投了两次简历,一次内推,一次正式实习生招聘。 内推很遗憾没能通过,正式招聘流程也全部走完了,刚拿到offer,分享一下面试的经验,帮助一下小伙伴

内推一面

从投简历到接到邀请面试的邮件大概过了半个月,于是乎就跑去了高大上的TIT创意园,一进去就可以看到各种木质的建筑,充满了小资的气息,沿路的树开着不知名的粉色鲜花,缓解了自己紧张的心情。签到后被带到 B6楼等待面试,话说微信的办公楼特别的奢华,简直不像工作的地方 23333。然后一个很柔嫩高帅的小哥过来了说他是一面面试官,他首先给了我一份笔试题,六道题全是数据结构和算法(哭),博主大概写了45分钟,基本上没写对几题。然后一面小哥没有看手写代码只是问了我一下大概思路(窃喜)然后就开始了面试环节。问的基本是前端常见的问题,如下

  1. 各种跨域方法(少见的比如使用 iframe 的 domain)
  2. 同源策略
  3. OAuth2.0 工作的流程
  4. HTML5 / CSS3 的各种新特性

其余的楼主都忘了(逃),感觉当时自己不在状态,答的比较蛋疼。不过小哥面完后说要让他 leader 来面一下,于是乎高高的 leader 出现了,特别严肃,我立马就萎了。 首先问我为什么不留在 UC移动事业群,博主 blabla 说了之后他点了点头,然后就问我对操作系统,计算机网络感不感兴趣,博主(受到一万点暴击)回答不喜欢操作系统,挺喜欢计网,leader 又问为什么不喜欢操作系统,博主心痛因为不会啊!
于是问了浏览器渲染页面的整个过程,从 DNS, TCP, HTTP 到浏览器解析文件,这里 leader 说答的还不错(毕竟是博主的杀手锏之一啊)。重点来了,leader 去看了我的手写笔试题,很认真的一行行看,然后说这里不对,那里不对,基本就没对的地方。 leader 都没什么想问我问题的兴趣了,于是放了个数据结构大招。 假设腾讯十万员工,有一个索引栏,可以通过点击部门获取属于该部门的所有员工,每个员工有一个工作的邮箱,另外还要提供(前缀/模糊)搜索功能,在输入栏输入员工的首字母拼音就可以将该员工检索出来,要求性能最高,存储压力最小。 博主到现在都不太清楚要怎么做(会做的大牛请告诉我~)

内推二面

(居然还有二面),二面在深圳,腾讯大厦果然是奢华大气,一排排的 iMac 闪瞎眼,面试官更加严肃了,问的问题全是我不知道的

  1. 怎么防止用户直接发请求到服务端(例如那种刷课软件不停发选课请求到服务器而不是通过用户点击选课按钮)
  2. 性能优化 cache-control 相关
  3. 一大堆数据结构算法题

持续了一小时,题目真的记不起来了。数据结构没有答出来,心服口服的被刷了

校招一面

在大学城雅乐轩酒店面试,进去房间前还想着不要是之前内推的面试官吧,问我同样的问题我肯定还是答不出来,所以墨菲定理?进去后我就觉得啊咧,怎么这么眼熟,面试官发话了“你还记得我吗?”。 我的天原来真的是内推一面时的 leader, 博主简直原地爆炸。当然,也真的问了之前那个部门 - 员工的数据结构题,博主说还是不知道。面试官问这两个多星期来我有没有做些什么东西,博主碰巧做了一个 WebRTC + socket.io + react 的聊天室,面试官对 WebRTC 还挺感兴趣,于是 blabla 说了一通。最后顺利过关,感谢!

校招二面

进去房间前还是想着难道又是深圳那位面试官,忐忑的走进去,感觉并没有见到过,不过面试官说 他们(其他面试官吧?)都说他面过我,可是他没有印象了问我有没有....问了很多前端方面的问题,题主嗯哼答得很棒

  1. jQuery 源码
  2. 性能优化
  3. 浏览器渲染
  4. UC 实习的项目

基本上博主准备的四大杀手锏全部使用出来啦,顺理成章的过了(逃)

HR面

简直都是痛。问了感情经历,最死而无憾的事情,最遗憾的事,腾讯的缺点。 这里博主很作死,说了腾讯实习工资太少,我也不知道我怎么这么傻,可能是因为技术面的后遗症,面试官丢给我一个问题我一定要想出一个答案来,博主一时想不到腾讯的缺点....

总结

一定不要让面试官牵着鼻子走,因为面试官不会知道你最拿手的地方在哪里,所以他会问他最了解和感兴趣的地方,你必须要引导面试官进入你的领域,比如你对性能优化有特别深入的了解,那么你一定要把面试官拖在这里听你夸夸其谈,楼主在二面的时候就是强行跑话题把有心得的地方全部讲给面试官听了 23333. 同时你的项目最好包含一些比较新颖的技术,这样容易勾起面试官的兴趣,即使是实验性的个人项目也不要紧的。
对于前端,最好你要看过某些框架的源码并且有一些自己的心得,因为这样会体现你的深入探究的能力,毕竟前端的前期学习曲线太平坦了。

杀手锏

整理附上博主的三大面试杀手锏,一般情况下博主可以水很久,三个杀手锏全部用出来,半个小时大概就过去了,面试官基本也会满意。

(面试的时候一定要多多准备一些杀手锏来俘获面试官的心!)

  1. 标签移动端的兼容性问题,当音频包含 cover(封面图片) 等非音频信息时可能导致部分机型(三星mini3)无法下载音频文件(发现这个原因的道路很曲折,博主能水很久,所以面试官觉得还挺出彩)
  2. 浏览器渲染的过程,<link> 标签为什么要在 <head> 里,<script> 标签为什么要在底部,当 <link>, <script> 同时存在的时候浏览器的行为有什么不同(白屏或者无样式内容闪烁),<script> 标签为什么不阻塞后续资源加载,为什么脱离文档流做动画还是会卡,但是使用 transform 就不会。这些问题涉及到浏览器渲染的一些知识,需要查阅各种资料和动手做实验后才有深入的了解,建议大家去google,google。
  3. jQuery 源码,(基本每个面试官都会问有没有看过哪些框架的源码呀),博主建议阅读 core 模块和 ajax 模块

WebRTC + socket.io 实现视频聊天室

具体代码请参考 omegle,Chrome 实测可运行

WebRTC 是一个支持P2P分享应用数据和进行电话会议的实时通信技术,
socket.io 基于 WebSocket 提供浏览器于服务器之间的全双工通信

信令服务器

信令是用来协调沟通的。 为了使WebRTC实现P2P的连接,WebRTC的客户端需要相互交换信息。

  • Session control messages, 连接控制消息,用来打开通信或者中断通信
  • Error messages, 发生错误时彼此告知的消息
  • Media metadata, 媒体流元数据,例如带宽,媒体类型,发送/接收方的浏览器能够接受的编码器和分辨率
  • Key data, 用来建立secure connections
  • Network data, 例如公网中的IP地址和端口信息

offer, answer and candidate

RTCPeerConnection 是 WebRTC 应用用来传递元数据的API

本地媒体数据,例如分辨率,编码器和编码能力,这些元数据被用来供 offer 和 answer 使用

candidate 指的是 WebRTC 应用主机

Alice call Eve 的过程如下(必须先交换音视频信息,才会触发 icecandidate 事件):

取得本地流

  1. Alice 使用 navigator.webkitGetUserMedia 方法获得本地流
  2. 将获取的 localMediaStream 通过 addStream 方法添加到 RTCPeerConnection 需要发送的流

音视频设备信息交换

  1. Alice 创建 RTCPeerConnection 对象
  2. Alice 通过 RTCPeerConnection 的 createOffer 方法创建一个 offer (一个SDP Session Description 在 createOffer回调函数的参数中)
  3. Alice 传递 offer 到 setLocalDescription 方法
  4. Alice 用信令机制把 offer 送到 Eve
  5. Eve 执行 setRemoteDescription 处理 Alice 发过来的 offer,此时 Eve 的 RTCPeerConnection 就知道 Alice 的音视频信息了
  6. Eve 执行 createAnswer 方法,local session description: Eve's answer 会在其回调函数中
  7. Eve 将 Eve's answer 传递到 setLocalDescription 方法
  8. Eve 使用信令机制将 Eve's answer 传递给 Alice
  9. Alice 将 Eve's answer 作为 remote session description 传递给 setRemoteDescription 方法
    +-----------+  1. 发送 offer       +------------+  2. 转发Alice offer  +-----------+       
    |           |  ---------------->  |            |  --------------->    |           |
    |   Alice   |  <---------------   |  信令服务器  |  <--------------     |    Eve    |
    |           |  4. 转发Eve answer   |            |  3. 发送 answer      |            |
    +-----------+                     +------------+                      +-----------+

网络信息交换

  1. Alice 创建 RTCPeerConnection 对象,[将 iceServer 的信息作为参数传入, 此时这个对象会自动向服务器询问自己的公网 IP 和端口]
  2. 为该 RTCPeerConnection 对象绑定 icecandidate 事件,该事件在 ICE Server 添加到 RTCPeerConnection 对象时触发(An icecandidate event is fired when an RTCIceCandidate has been added to the target)
  3. 在 icecandidate 事件中通过信令机制将 candidate(网络信息)传递给 Eve
  4. Eve 通过 addIceCandidate 方法保存 Alice 的网络信息
                             (用来NAT穿透,可以不需要)
                               +---------------+    
                               |               | 
          +----------------->  |   STUN服务器   |   <-------------+
          |                    |               |                 |
          |                    +---------------+                 |
          | 询问外网IP和端口                        询问外网IP和端口  |
          |                                                      |
          |                                                      |
    +-----------+  发送IP和端口    +------------+   转发IP和端口  +-----------+       
    |           |  ---------->   |            |  ---------->   |           |
    |   Alice   |  <----------   |  信令服务器  |  <----------  |     Eve    |
    |           |  转发IP和端口    |            |  发送IP和端口   |            |
    +-----------+                +------------+                +-----------+

要点

  • 发送者,接收者需要区分好,前者发送 offer, 后者接收 offer,返还 answer
  • RTCPeerConnection.createOffer 第三个参数接收 options, 需要设置
options = {
     offerToReceiveAudio: false, // 不接收音频
     offerToReceiveVideo: true  // 接收视频
}

长 DOM 短 DOM 渲染实验

测试环境:IPhone 5 IOS 8, Macbook Pro 2015, Chrome 51.0 (64-bit) 微信 IOS 6.3.21

实验方法:前后打点获取渲染时间,实验取众数

单位:毫秒

Chrome 下实验

数量 1K 3K 5K 10K 20K
img 40 310 800 1700 3400
img src 70 420 1100 2600 7000
div 5 12 360 800 1800
iframe 2500 2800 3000 3500 6000
span 35 280 430 1100 2000
p 5 15 460 1000 2300
a ✔️ ✔️ ✔️ ✔️ --------
section ✔️ ✔️ ✔️ ✔️ --------
script ✔️ ✔️ ✔️ ✔️ --------

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.