从BAT面试题谈前端面试解题思路

2009 年我在支付宝做前端开发时,参与草拟了一份非正式的前端岗位招聘要求。

这里有:

1、国内最大的第三方支付舞台,体验亿万资金穿梭代码的快感;

2、一群热爱前端技术的伙伴,最快的成长经历;

3、持续的培训体系,完善的项目开发环境,最具潜力的UED团队。

你需要:

1、热爱前端,热爱设计,对新鲜事物充满好奇心,喜欢捣鼓各种互联网应用;(兴趣、学习能力、创新能力)

2、自我管理能力强,健康的创业心态,乐于分享与沟通;(心态、分享、性格)

3、具备基本的前端素质,了解WEB标准化、性能优化方法,了解可用性、可访问性;(基本技能)

4、能和设计师谈产品设计,和后端开发研讨技术实现方案,制定服务接口,崇尚团队合作;(向前向后能力)

当时在面试时最流行问的前端技术问题是:Web 标准化、AJAX 与 YSlow。

  • 问:一个 AJAX 请求从开始创建到最后的响应阶段,在其整个生命周期中,使用到了哪些 JavaScript 对象与方法?

  • 问:YSlow 的 34 条性能优化建议中,哪些与 HTTP 协议相关,请尽可能多的列举出来,并说说你的理解?

2011 年我开始成为腾讯的前端开发面试官,负责腾讯电商的前端开发(网页重构方向)笔试出题与面试工作。在 2012 年的校招过程中,我发现不论是我出的笔试题,还是其他面试官出的题目,HTTP 协议相关的知识都是必考项。例如,

  • 问:HTTP 协议中与缓存相关的 HTTP Header 有哪些?

  • 问:列举出你所知道的 HTTP 状态码,并描述它们的含义与发生的场景?

后来我在学习百度 FIS 框架的过程中,无意间看到百度 FEX 团队的这份开源前端开发面试题,不出所料,同样有一道与网络编程相关的题目:

一个页面从输入 URL 到页面加载完的过程中都发生了什么事情?越详细越好

由此可见,网络编程相关知识的确是 BAT 前端面试题中的必考项,而对于负责输出 API 接口的后台开发岗位来说,更是如此:

  • 问:一个 POST 请求的 Content-Type 有多少种,传输的数据格式有何区别?

  • 问:什么是 RESTful API,如何设计一个 Open API 的接口?

解题思路

接下来我们一起探讨下具体的解题思路,浏览完本文之后,你将会首先掌握 HTTP 协议相关的前后端基础知识。

要掌握 HTTP ,就需要先看到 HTTP 到底长什么样?(不了解「网络七层协议模型」和 TCP 的同学先不着急,本系列的后面几篇会涉及到。)

1、安装 HTTP 抓包工具

在 Chrome 开发者工具下我们可以看到,打开一个网页后,浏览器会发起许多 HTTP 的请求(HTTP Request),这些请求经过服务器端处理后会返回对应的数据(HTTP Response),浏览器会按照这些数据的类型将它们渲染出来。

Chrome 中看到的 Request/Response Header 是其格式化之后的形式,要看到它们的原始模样(Raw Source),我们需要借助两个 HTTP 接口调试利器。

其 中 Windows 系统下使用 Fiddler,Mac 系统下使用 Charles。Fiddler 具体的安装与使用教程,请自行百度(安装 Fiddler4 还需同时安装 .NET Framework 4),Charles 相关教程,推荐参考 iOS 大神唐巧的《Charles 从入门到精通》。使用 Linux 系统的说明已经是网络编程方面的大牛了,不需要继续往下看 :P

2、查看 HTTP 详细报文

运行 Fiddler(或 Charles) 之后,使用 Chrome 浏览器打开「猫哥学前班」的新浪微博主页:http://weibo.com/mgxqb

在 Fiddler 左侧面板下选中该条 HTTP 请求,再将右侧面板的请求部分和响应部分都切换到 Raw 标签页。如下图所示:

Charles 下的操作与 Fiddler 类似:

HTTP 协议规范由 W3C 制定,与具体的抓包工具无关,接下来我们主要以 Charles 为例,详细讲解下 HTTP 的报文格式,这对理解基于 HTTP 的 API 接口设计和网页性能优化有很大帮助。

我们先看一下请求头的源码(Request Raw),为了防止隐私泄露,我已删除部分 Cookie 信息:

GET /mgxqb HTTP/1.1
Host: weibo.com
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.73 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4
Cookie: YF-Page-G0=f70469e0b5607cacf38b47457e34254f; _s_tentry=passport.weibo.com

仔细观察以上源码,我们能大概总结出 HTTP 协议的格式规范:

  • 第一行定义了请求类型(GET)、请求路径(/mgxqb)与协议类型及其版本号(HTTP/1.1),使用一个半角空格间隔这三块信息;

  • 示例源码的最后是两个空行。由于 HTTP 规范中要求一个合法的 HTTP 报文至少包含有一个空行,其中第一个空行用来间隔报文的头部信息(HTTP Request/Response Header)和主体信息(HTTP Request/Response Body)。在空行的下一行是报文的主体信息,由于本例为 GET 类型请求,其主体(Body)信息通常为空,这便是第二个空行的含义;

  • 余下的部分有着相同的格式,即 「HTTP Header 字段名+半角冒号+半角空格+值」,我们可以把它看成 YAML 格式的简易版。其中 HTTP Header 在规范中有着明确的定义,具体参见 HTTP头字段列表。

这便是一个 HTTP 协议报文的源码格式,以下我们简单讲解下最常见的 HTTP header 的含义。

3、常见 HTTP header

User-Agent:客户端身份标识

User-Agent (以下简称 UA)字段记录了访问当前网页的用户浏览器的类型与版本、操作系统类型与版本。根据不同的 UA 信息,提供不同的站点内容是使用 UA 的常见场景。例如,如果用户使用手机访问魅族官网 www.meizu.com,浏览器会自动跳转至魅族手机官网 m.meizu.com。这种跳转实现既可以由前端 JavaScript 完成,也可以通过后端返回 302 重定向来完成。

JavaScript 访问 window.navigator.userAgent  属性即可获取该信息。虽然该属性是只读的,但有很多前端手段可以伪造 UA 。如下图,Chrome 开发者工具在模拟不同的手机机型时,也会改变浏览器 UA 值。由此可见,通过检测 HTTP User-Agent Header 来识别是否为爬虫程序,不是一个有效的方法。

在 PHP 中,所有的 HTTP Header 字段信息都保存在 $_SERVER 对象中,通过访问$_SERVER['HTTP_USER_AGENT'] 即可获取 User-Agent 的值。

Cookie:用户身份标识

由于 HTTP 协议最初被设计成一种无状态的数据传输协议,服务器端无法判断每次处理的请求相互之间以及与之前处理的请求之间的关系,Cookie 的设计就是为了解决这个问题。

用 户在浏览器中首次访问一个站点时,会通过请求响应头或页面JS脚本生成一些用于标识用户身份的 Cookie 信息,这些信息会按照域名分类,存放在浏览器本地缓存文件当中。例如 Windows 系统下通过访问 「C:\Users<用户名>\AppData\Local\Microsoft\Windows\Temporary Internet Files」 目录可以查看到 IE 浏览器保存在本地的 Cookie 文件。当用户再次访问该站点时,这些 Cookie 信息会被浏览器自动添加到 HTTP Request Header 的 Cookie 字段中,服务器通过读取这些信息,来区分当前请求的用户身份与状态。

浏览器可以通过读写 document.cookie 属性来添加或删除 Cookie 信息,服务器端可以通过 HTTP Response Header(响应头)中的 Set-Cookie 来改写客户端的 Cookie 信息。每一条 Cookie 属性通常都会设置一个过期时间,过期之后的 Cookie 浏览器将会自动清理它们,不会再被携带在 HTTP Request Header(请求头)中。

例如,以下 PHP 语句可以通过设置 Cookie 过期时间为前一个小时来触发客户端 Cookie 过期,达到删除 Cookie 的目的:

setcookie('key', '', time() - 3600, '/'); 

由于 Cookie 通常用于记录用户「帐号信息」和用户的「操作记录」,所以泄露 Cookie 会带来个人帐号与隐私泄露的风险。这也是为什么你在百度上搜索「贷款」的关键词之后,访问其他网站时就能看到相关的推荐广告,甚至第二天就会有各种放贷电话找上门来。

又 由于 Cookie 可以随意被客户端修改(通过修改 document.cookie 属性),因此浏览器厂商们一起制定了 HttpOnly 的 Cookie 机制。服务器端在 setcookie 时,通过设置 HttpOnly 的标识,可以防止客户端通过 JavaScript 修改 Cookie 的信息。不过这种方法对于基于 HTTP 协议进行篡改的方法来说无法防范,在之后的猫哥网络编程系列中,我将会介绍如何通过监控 Wi-Fi 流量来截取、伪造用户身份。

在 YSlow 性能优化最佳实践中,有两条与 Cookie 相关的建议:

  • Reduce Cookie Size

  • Use Cookie-free Domains for Components

虽 然浏览器对 Cookie 的大小与数量有着较为严格的限制,但很多网站(尤其是包含登录态的)的 Cookie 信息量通常比其他所有 HTTP Header 加起来的还要多。为了减少不必要的 HTTP 数据传输量,YSlow 给出了以上两条优化建议。由于网页的静态资源(图片、CSS、JS)文件无需记录用户状态,因此通常会使用一个额外的域名(Cookie 是按域名来分类存储)来存放静态资源文件。

我们使用 Chrome 开发者工具查看「猫哥学前班」新浪微博主页,可以看到新浪微博使用了 img.t.sinajs.cn的域名来存放它的 CSS 文件,这个域名发起的 HTTP Request Header 中没有自动带上 Cookie 字段信息 (因为前后端脚本都没有在这个域名上设置 Cookie,而是设置在了 weibo.com 域名上):

这里还需要引申一个知识点:Session,它和 Cookie 有什么关系?由于 Session 与本文所讲的 HTTP 协议关系不大,相关知识点请自行百度。

Cache-Control:浏览器资源缓存标识

网站性能优化中,最为关键的是缓存机制(又是没有之一)。 在服务器端通常会使用 Memcached、Redis 等服务来缓存经常访问的数据。例如在一个电商网站中,用户经常访问的热卖商品数据会被缓存在内存中,用户在一定时间内访问商品详情页时,后台程序直接从缓 存服务中获取这段数据,这种方法可以大幅降低数据库的访问压力。

在 用户端,浏览器会有一系列机制通过缓存来提升页面加载速度。例如 IE/Chrome 都会缓存 GET 类型的 AJAX 请求,IE 甚至会缓存 POST 类型的请求,需要通过增加时间戳参数的方式来强制清除缓存。对于所有的静态资源文件来说,最佳实践是为它们增加一个 「Never Expires」(永不过期)的强(长)缓存,以下是一个强缓存静态资源服务器的 Nginx 配置示例:

server {listen 80;server_name yekai.net;root /var/www/yekai.net;location / {index index.html index.htm;}location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|js|css)$ {  expires 365d;  }
}

通过配置 「expires 365d」,HTTP Response Header(响应头)中会返回 「Cache-Control: max-age=31536000」 的头字段,配合 Last-Modified 头字段。浏览器便可以自动完成资源的强缓存。

Cache-Control 是浏览器缓存机制中最为重要的一个配置,以下是浏览器加载静态资源文件时的缓存检查机制流程:

由此可见,静态资源缓存优化的最佳状态是:直接从本地缓存中读取 > 304 状态 > 200 状态。关于 HTTP 状态码,与网站性能优化有关的主要是以下几个。

  • 尽量减少 200 状态码的请求。200 表示是一个正常的请求返回,此条优化规则要求尽可能多的减少页面的 HTTP Request 数量。常见的方法有:合并打包静态资源、使用 CSS Sprite 雪碧图合并、缓存 AJAX、使用 LocalStorage/UserData/Manifest 等本地缓存技术。

  • 清理返回 301/302 状态码的入口链接。301 表示永久重定向,302 表示临时重定向。服务器端使用重定向返回通常是为了兼容一个旧的入口链接。我们能做的优化是,将调用旧入口的场景进行清理,直接调用重定向之后的新 URL 地址。

  • 304 表示静态资源未更新,浏览器可直接使用本地缓存文件。通常 304 的产生与浏览器的处理机制以及服务器缓存头配置有一定的关系。304 虽然未传输文件主体内容,但 HTTP 请求的建立依然是一个可以避免的性能损耗。腾讯 KM(内部知识分享平台)上有一篇文章通过在真实海量业务场景(没记错的话是 Qzone 业务)中,正交验证 HTTP 1.0 与 1.1 协议中与缓存相关的 HTTP Header 配置,结合日志分析得出了一个最佳实践:关闭 Etag 配置,只启用 Cache-Control 与 Last-Modified 响应头。为了兼容老浏览器,可保留 Expires。因为 Etag 的缓存方案,在经过 CDN 及网关代理服务器后,会导致缓存命中率下降。从以上「浏览器缓存检查机制流程」图上可以看出,使用强缓存(Cache-Control max-age 设置为一年)后浏览器在资源过期前不会发起 HTTP 请求,那如何保证静态资源在服务器上更新后本地的缓存也能同步更新呢?可参考百度 FIS 的「文件指纹」方案。

  • 清理返回 404 状态码的入口链接。静态资源文件的 404 调用需严格避免,而入口页面的 404 则在所难免。通过在全站 404 页面进行产品引导与体验优化,并结合数据上报记录来源页(HTTP Referer Header 或 document.referrer),可以找到并清理 404 来源入口。对于由搜索引擎进入的来源,可通过主动提交新索引至搜索引擎,或使用 301/302 重定向的方式,有效利用起这些「被浪费的流量」。

  • 502 服务器出错。如果是 Nginx + FastCGI 的常见架构,通常是由于 Nginx 缓冲区溢出或服务器资源被耗尽引起,针对不同的业务场景进行 Nginx 的配置优化能显著提升服务器抗压性能。

如果你对上文提及的「网络性能优化」的知识点十分感兴趣,建议你通读 Steve Souders 的《高性能网站建设指南》与《高性能网站建设进阶指南》,Steve Souders 的个人网站上积累了很多性能优化的方法与案例。

如果你能看到这里,相信你已经知道如何解答前文提到的几道 BAT 网络编程面试题中,关于 「HTTP 协议、状态码、缓存与性能优化」相关的问题。

转载请注明本文出处:http://www.infocool.net/kb/OtherFrontDesign/201606/152439.html

从BAT面试题谈前端面试解题思路相关推荐

  1. 「offer来了」浅谈前端面试中开发环境常考知识点

    「面试专栏」前端面试之开发环境篇

  2. 2018 浅谈前端面试那些事

    1.HTML HTML5新特性,语义化 浏览器的标准模式和怪异模式 xhtml和html的区别 使用data-的好处 meta标签 canvas HTML废弃的标签 IE6 bug,和一些定位写法 c ...

  3. 梳理了一下前端面试必考知识点

    大家好,我是若川.最近收到不少朋友留言说,前端面试越来越难,尤其是技术面. 既要熟悉各种框架,又要精通每个知识点的底层逻辑,甚至连前端工程化的内容都拿来考察. 哪怕是有 3-5 年经验的老前端,都极有 ...

  4. web前端面试高频考点——Vue原理(理解MVVM模型、深度/监听data变化、监听数组变化、深入了解虚拟DOM)

    系列文章目录 内容 参考链接 Vue基本使用 Vue的基本使用(一文掌握Vue最基础的知识点) Vue通信和高级特性 Vue组件间的通信及高级特性(多种组件间的通信.自定义v-model.nextTi ...

  5. Web前端开发——BAT面试题汇总及答案01

    目录: 目录: HTML&CSS篇: 1.你做的页面在哪些流览器测试过?这些浏览器的内核分别是什么? 2.每个 HTML 文件里开头都有个很重要的东西,Doctype,知道这是干什么的吗? 3 ...

  6. 2010年3月再谈前端工程师的笔试题

    最近在收集前端开发工程师的笔试题,正好看到Adam Lu.的这篇博客,感觉挺不错的转载过来! HTML && CSS 1.Doctype? 严格模式与混杂模式-如何触发这两种模式,区分 ...

  7. 前端面试总结以及面试题

    前沿 小编在这几年的前端开发过程中,经历了由js,jquery到vue,由操作dom到数据驱动页面,由只写pc网站,到写移动端网页,再到移动端app,再到微信公众号,小程序,可谓是风云变幻,不得不感叹 ...

  8. 看完跳槽少说涨 5 K,前端面试从准备到谈薪完全指南(全是精华)

    首先我们将从以下几个角度来聊聊面试这件事情 面试题篇 面试题只能应对 1 - 2 面,刷题固然重要,但是对于项目相关的准备也是必须的.一般来说目前面试题能准备的范围如下: JS 基础 / 进阶相关HT ...

  9. 看完跳槽少说涨 5 K,前端面试从准备到谈薪完全指南(近万字精华)

    本文将从以下几个角度来聊聊面试这件事情 文章首发自我的 Github,欢迎关注. 面试题篇 面试题只能应对 1 - 2 面,刷题固然重要,但是对于项目相关的准备也是必须的.一般来说目前面试题能准备的范 ...

最新文章

  1. WCF服务的REST / SOAP端点
  2. 概率编程库Pymc3案例之线性回归
  3. 深度学习目标检测系列:RCNN系列算法图解
  4. 关于字符串比较时候出现的空指针问题的坑
  5. Servlet 运行原理
  6. LeetCode 701. 二叉搜索树中的插入操作(二叉查找树/插入)
  7. 启动zookeeper时IDEA启动项目时提示8080端口被占用
  8. violin 结构介绍
  9. 基于Spark的电影推荐系统实现
  10. Stream流简单使用之List集合排序
  11. 纯CSS3制作优惠券线性UI效果
  12. 构建 Web 应用之 Service Worker 初探
  13. 木门工厂木门、门套、套线公式和算法
  14. 通过java解析域名获得IP地址
  15. 企业经营发展战略的选择
  16. “达内”JAVA技术培训有感(一)
  17. 酷狗歌曲赏析评论覃瑞2
  18. 判断iOS6/iOS7, 3.5inch/4.0inch
  19. EasyBPM进销存之物料管理
  20. 第四章 STM32+LD3320+SYN6288+DHT11实现语音获取温湿度数值(上)

热门文章

  1. 淘宝整店商品列表查询接口(店铺所有商品API接口)
  2. hdu计算机学院大学生程序设计竞赛(2015’11)1003 玩骰子
  3. DIY孔明锁(6根)自制鲁班锁
  4. 企业电子招标采购系统源码之项目说明和开发类型
  5. EasyUI常用图标:图标——名字
  6. 基于爬虫的诗人APP
  7. 什么是十六进制法_十六进制中的abcdef是什么意思
  8. 计算机主机名和全限定域名,什么是完全限定域名?
  9. [简洁版] CentOS NTP服务器搭建
  10. 根据身高体重计算标准身高和BMI指数