LY Front-end Dev Engineer

前端工程师面试题解答一

2017-08-14
LY

面试的时候主要看简历发挥,所以简历不能写得太浮夸,要不然面试官问到你都答不上来。

说一说你了解的css盒模型

我了解的css的盒模型有两种:标准浏览器的盒模型和IE的怪异盒模型

大多数浏览器采用的是W3C标准模型,而IE中采用的是Microsoft自己的标准。

怪异模式是“部分浏览器在支持W3C标准的同时还保留了原来的解析模式”,怪异模式的内核主要表现在IE内核的浏览器中。

对HTML文件来说,浏览器使用文件开头的 DOCTYPE 来决定用怪异模式处理或标准模式处理。为了确保你的页面使用标准模式,请确认你的页面如同本范例一样拥有 DOCTYPE:<!DOCTYPE html>

当不对doctype进行定义时,会触发怪异模式。

在标准模式下,一个块的总宽度 = width + margin(左右) + padding(左右) + border(左右)

在怪异模式下,一个块的总宽度 = width + margin(左右)(即width已经包含了padding和border值)

可以通过css3的box-sizing属性控制两种盒模型的变换。

当设置box-sizing: border-box时,将采用怪异模式解析计算。

所以在reset初始化样式中,建议使用box-sizing: border-box

这样,如果我们想要一个宽度为200px的盒子,那么我们直接设置宽度为200px,这样看起来就清晰多了。当我们再设置它的左右边框和左右填充后,它的内容会自动调整。这样就更直接和一目了然了不是吗。


box-sizing的应用场景

  1. 特殊场景的布局

假设我们有这样的一个场景,设置子类元素的margin或者border时,可能会撑破父层元素的尺寸,这时我就需要使用box-sizing: border-box来将border包含进元素的尺寸中,这样就不会存在撑破父层元素的情况了。

  1. 统一风格的表单元素

表单中有一些input元素其实还是展现的是传统IE盒模型,带有一些默认的样式,而且在不同平台或者浏览器下的表现不一,造成了表单展现的差异。此时我们可以通过box-sizing属性来构建一个风格统一的表单元素。


flex弹性布局

未知宽高元素如何上下左右垂直居中

.vertical-container {
  display: flex;
  align-items: center;
  justify-content: center;
}

css预处理器

文章1


javascript的继承、原型链和构造函数

阮一峰文章


DOM事件的绑定的几种方式

在原生的javascript中,有三种常用的绑定事件的方法:

  1. 在DOM元素中直接绑定
  <div id="test" onclick="doAction()"></div>
  1. 在javascript代码中绑定
  document.getElementById('#test').onclick = function() {
    // do some thing
  }
  1. 绑定事件监听函数
  document.getElementById('#test').addEventListener('click', function(){
    // do some thing
  }, false)

  // 第三个参数是设置事件是事件捕获执行还是事件冒泡执行,一般为事件捕获执行false

事件捕获和事件冒泡

<div id="outer">
    <p id="inner">Click me!</p>
</div>

事件冒泡是由微软提名的事件流。怎么理解呢?打个比方,把事件冒泡形象地比喻为把一颗石头丢进水中,泡泡会一直从水底冒出水面。也就是说,事件会从最内层的元素开始发生,一直向上传播,直到document对象。

---

点击上面的p元素,在事件冒泡的概念下发生click事件的顺序是:p -> div -> body -> html -> document

---

事件捕获是由微软提名的事件流。与事件冒泡恰好相反,事件会从最外层开始发生,直到具体的元素。

---

另外jquery利用javascript的“冒泡”机制,形成的事件委托处理。在dom处理方面也提高了一定的性能。

比如,有一个表格(table元素),里面有100个格子(td元素),现在要求在每个格子上面绑定一个点击事件(click),不需要将下面的代码执行100次。

$("td").on("click", function(){
  $(this).toggleClass("click");
});

只要把这个事件绑定在table元素上面就可以了,因为td元素发生点击事件之后,这个事件会”冒泡”到父元素table上面,从而被监听到。

$("table").on("click", "td", function(){
  $(this).toggleClass("click");
});

说一说你项目中用到的技术栈,觉得出色的点,或让你头疼的点,怎么解决的

网易新闻回流页项目

例如:这个文章页

文章内容部分利用node直出实现页面静态化。

数据请求在server端上提前获取,页面模板结合数据的渲染处理也在server上完成,输出最终的HTML

  1. server 上获取数据并将数据与页面模板结合,在服务端渲染成最终的 HTML
  2. 返回最终的 HTML 展示

直出能够将常用模式优化到剩下了一次 HTML 请求,加快首屏渲染时间,使页面的性能优化得到较大提高。

除了各回流页的内容采用静态化之外,其它部分,比如内容下面的一些相关新闻或广告啊,这些会动态变化的是需要另外调接口获取数据的,所以我们在html里还是会嵌入外部js文件的。

其它部分,利用webpack模块化组件开发,抽离出公共的js模块,在需要的页面使用require或import调用公共模块。

对于css和js,在回流页的项目里没有用第三方ui框架或js库,都是原生的。css用的是less预处理语言,js是用的是es6的语法。

工具:

构建工具:使用webpack结合gulp,gulp负责工作流生命周期里面的样式图片等资源整理合并,webpack负责脚本模块打包合并(组件开发)

自动化测试:jest。

性能优化:PageSpeed。

版本管理:git。

/////////////////////////////////////////////

视频后台管理系统

react + react-redux + webpack + babel

react ui框架用了蚂蚁金服的antdesign

/////////////////////////////////////////////

相关文章:

Node直出理论与实践总结
gulp 有哪些功能是 webpack 不能替代的?


对http2.0,websocket,https的了解

http2.0历史

在http2.0之前,经历了http1.0和http1.1这两个兄弟。虽然http2.0已经出现,但并不会像手机端app升级一样,网络协议新版本并不会快速取代旧版本。实际上1.0和1.1在之后的很长一段时间内并存,这是由于网络基础设施更新缓慢决定的。而http2.0也一样,新版本再好也需要业界产品的锤炼,需要基础设施逐年累月地升级才能普及。

http站在tcp之上

理解http之前需要对tcp有一定基础的了解,http是建立在tcp协议之上的,tcp作为传输层的协议其实离应用层并不远。http的瓶颈及优化技巧是基于tcp本身的特点产生的。比如说tcp在建立三次握手的时候会有1.5个rtt的延迟,为了避免每次请求都经历握手带来的延迟,应用层会选择不同策略的http长链接方案。又比如tcp在建立连接之初有慢启动的特性,所以连接的重用总比新建连接的效果要好。

http2.0的主要改动

多路复用、首部压缩、优先级控制、server push

1.协议解析采用二进制格式,简洁高效

http1.x的解析是基于文本的,而文本的表现形式是多样性的,而二进制不同,它的表现形式只有0和1,所以才用二进制格式,实现起来更方便。但有人可能会觉得这样调试修改请求就变得很麻烦了,而事实上,现在很多请求都走https了,要调试https请求必须有私钥才行。http2.0的绝大多数request也都是走https的,所以调试问题基本上可以不考虑。

2.连接共享(针对每个域只使用一个多路复用的连接,而不是没个文件一个连接*最大的亮点,只有在http请求量大的场景下明显突出,比如像淘宝app)

http2.0要解决的一大难题就是多路复用,即连接共享。
连接共享之后,需要优先级和请求依赖的机制配合才能解决关键请求被阻塞的问题。
优先级和依赖是可以动态调整的。
假如用户在你的app浏览商品时,快速滑动到商品列表的底部,但前面的请求先发出,如果不把后面的请求优先级设高,用户当前浏览的图片要在最后才能下载完,显然体验没有设置优先级好。

3.header压缩(首部使用特制的HPACK协议压缩)

http1.x的header由于cookie和user agent很容易膨胀,而且每次都要重新发送。http2.0使用encoder来减少需要传输的header大小,它会在通讯的时候cache一份header fields表,避免重复header的传输,又减少了需要传输的大小。高效的压缩算法可以很大地压缩header,减少发送包的数量从而减少延迟。

4.使用HPACK首部压缩算法

在http1.x中是没有首部压缩的,gzip只会压缩body,http2.0提供了首部压缩方案。一般轮询请求首部,特别是cookie占用很大部分的空间,首部压缩使得整个http数据包小了很多,传输速度也快了很多。

5.HTTP/2设计了复杂的优先级排定规则,帮助浏览器首先请求最急需的文件,而NGINX已经支持(SPDY的方案要简单一些)

6.重置连接表现更好

很多app客户端都有取消图片下载的功能场景,对于http1.x来说,是通过设置tcp segment里的reset flag来通知对端关闭连接的。这种方式会直接断开连接,下次再发请求就必须重新建立连接。http2.0引入RST_STREAM类型的frame,可以在不断开连接的前提下取消某个request的stream,表现更好。

7.更安全的SSL

HTTP2.0使用了tls的拓展ALPN来做协议升级,除此之外加密这块还有一个改动,HTTP2.0对tls的安全性做了近一步加强,通过黑名单机制禁用了几百种不再安全的加密算法,一些加密算法可能还在被继续使用。如果在ssl协商过程当中,客户端和server的cipher suite没有交集,直接就会导致协商失败,从而请求失败。在server端部署http2.0的时候要特别注意这一点。

http2.0负能量

http2.0对于ssl的依赖,使得有些开发者望而生畏,不少开发者对ssl还停留在高延迟、cpu性能损耗,配置麻烦的印象中。

如何基于一个http协议,建立一个长链接

文章

这篇文章讲得不错 使用HTTP/2提升性能的7个建议

https的加密原理

HTTPS为什么安全 &分析 HTTPS 连接建立全过程


http协议200和304的理解和区别

先说一下http的缓存基础:

资源请求的过程:

1.浏览器请求——>2.无缓存——>3.向web服务器请求——>4.请求响应、缓存协商——>5.呈现

在第4个步骤,在响应消息的头字段,会有Expires、Cache-Control、缓存时间、Etag、Last-Modified等信息。

协商缓存和强缓存

有的时候看到的网页请求状态是200,而有的时候看到的是304。我觉得这个应该是运维那边控制的吧,如果运维移除Entity Tag(ETag),就会一直出现200的状态吧,没有移除,两者就会交替出现。

简单来说,200状态是浏览器没有跟服务器确认,直接用了浏览器缓存,也就是from cache;而304是浏览器和服务器多确认了一次缓存有效性,再用的缓存,也就是not modefied。

200是直接点击链接访问,输入网址按回车访问触发,不会有ETag。 304是刷新页面时触发,或是设置了长缓存、或当ETag没有移除时触发。

来说说304:

当你第一次请求一个资源的时候,server会同时生成并返回一个字符串在响应头里,叫Etag。 浏览器接到资源后,缓存资源的同时也会把这个Etag保存下来,成为If-None_Match 。Etag可以看作是一个资源的唯一标识,当你第二次请求这个资源的时候,请求头里会带着这个Etag,server会拿server该资源现在的Etag跟请求头中的If-None_Match做对比,然后看看If-Modified-Since过没过期,如果一样,直接告诉他:你就用本地的吧,我没变,就不给你返回了。所以返回了304,304就是这样。

再说说200 From Cache:

这个虽然是200,但他根本就没有跟server做交互,直接拉的本地缓存。 上边已经说了From Cache的触发条件,但如果想一直持续From Cache不想304怎么办? 可以在Server端配置移除Etag


DOM事件中target和currentTarget的区别

e.target 指向触发事件监听的对象。
e.currentTarget 指向添加监听事件的对象。

在事件冒泡和事件捕获阶段,e.target和e.currentTarget是不同的。
在事件目标阶段,它两是相同的。


如何解决跨域

只要协议、域名、端口有任何一个不同,都被当作是不同的域
如果是协议和端口造成的跨域问题,前端是解决不了的
在跨域问题上,域仅仅是通过“URL的首部”来识别而不会去尝试判断相同的ip地址对应着两个域或两个域是否在同一个ip上。
“url的首部”是指window.location.protocol + window.location.host ( + abc.123.com)

jsonp跨域

在浏览器端全局注册一个callback回调函数,这个函数接受一个参数,参数是期望给到的服务端返回数据,函数的具体内容是处理这个数据。
jsonp是从其他域中加载代码执行,安全无保障;而且请求是否失败不容易判定,且只支持Get请求,优点是可以支持早起的浏览器。

document.domain + iframe的设置

看这篇文章

1、安全性,当一个站点(b.a.com)被攻击后,另一个站点(c.a.com)会引起安全漏洞。
2、如果一个页面中引入多个iframe,要想能够操作所有iframe,必须都得设置相同domain。

利用iframe和location.hash

原理是利用location.hash来传值,改变hash并不会导致页面刷新,所以可以利用hash值来进行数据传递。
当然这样做也存在很多缺点,诸如数据直接暴露在了url中,数据容量和类型都有限等……

window.name实现跨域数据传输

详细看此文章

跨域资源共享cors

W3C出了一个标准————CORS,它允许浏览器向跨源服务器发出XMLHttpRequest请求,从而克服了ajax只能同源使用的限制。
首先来说 CORS 需要浏览器和服务端同时支持的,对于兼容性来说主要是ie10+,其它现代浏览器都是支持的。
使用 CORS 跨域的时候其实和普通的 ajax 过程是一样的,只是浏览器在发现这是一个跨域请求的时候会自动帮我们处理一些事,比如验证等等,所以说只要服务端提供支持,前端是不需要做额外的事情的。

详细看此文章

WebSockets

详细看此文章

使用HTML5 postMessage

跨文档消息传输Cross Document Messaging


深拷贝的实现原理

浅复制是对对象地址的复制
深复制则是开辟新的栈

JavaScript存储对象都是存地址的,所以浅拷贝会导致 obj1 和obj2 指向同一块内存地址。改变了其中一方的内容,都是在原来的内存上做修改会导致拷贝对象和源对象都发生改变,而深拷贝是开辟一块新的内存地址,将原对象的各个属性逐个复制进去。对拷贝对象和源对象各自的操作互不影响。

详细看这篇文章


webpack的一些原理和机制


babel把ES6转成ES5的原理

详细请看这篇文章

babel 的 AST 生成是直接使用 babylon 这个单独的 AST 解析器包,它基于 ESTree 规范。


git团队协作,持续集成

持续集成的概念

git多人协作


函数式编程

这篇文章不错

JS的API有哪些应用到了函数柯里化的实现?


ES6的箭头函数this问题

胖箭头函数里的this遵循词法作用域


JS模块化Commonjs,UMD,CMD规范的了解,以及ES6的模块化跟其他几种的区别,以及出现的意义

Js模块化

es6模块化


vue实现双向数据绑定原理,vuejs和reactjs异同点,如何选择

文章 文章

像vuejs这种MVVM框架,是通过Object.defineProperty来实现数据的双向绑定。

如何选择前端开发模式

文章1
文章二


scroll和元素的位置

文章


为什么学习前端


学习前端的过程


Similar Posts

Comments