前端常见面试问题 part 2

下面的大部分问题来自Github的这个仓库,排名不分先后

18. Vue和React框架的对比

先说相同之处,Vue和React都是优秀的MVVM框架。具有响应式设计的种种特点,因此数据驱动是使用这两种框架不能忘的出发点。正如上一个问题提到的那样,开发者只需处理好数据,让框架去处理易错的UI。同时,组件化前端开发流程也是它们强调的一点,用组件化之名行代码重用之实,通过组件积木去构建整个页面。最后,它们不约而同地使用虚拟DOM树(vDOM)(Vue是在2.0引入的)抽象页面的节点,通过优化的diff算法减少频繁的DOM操作,减少交互的响应时间。另外,在最新的版本中,Vue和React的源码分别通过FlowTypeScript加入类型约束,增强可读性和健壮性。

两者同时也有MVVM框架共同的短板,把过多的渲染放在客户端,在页面元素复杂时,会加大交互的延迟。同时会影响首屏时间。

再说它们的不同之处,不同之处基本都在使用细节上。

  • Vue通常把网页模板写在template属性中,默认不支持JSX语法(可以通过插件支持)。React中则是写在render里
  • Vue糅合了Angular 1.x的特点,通过一些内置的自定义标签属性减少开发者的代码量。React则更加纯粹,少了这些预设的框架
  • Vue使用Object.defineProperty实现数据绑定,React通过setState显式更新依赖。前者更加酷和自然,但是在编程风格不好时,容易出现难以debug的错误。React推荐immutable Object,每次更新时使用新对象更新自身state,出错的概率更低。
  • Vue和React在组件生命周期上有些细微的差别。Vue的生命周期更加简明,在create,mount,update,destroy前后设置钩子函数,React在state改变前后也会有钩子函数
  • Vue的脚手架使用起来较React更加顺手(个人感觉),单文件.vue的组织方式,内部支持模板语言jade、ejs,预处理语言coffeescript,sass等。React的构建方式则更加自由。
  • React的社区较之Vue更为活跃些,流行的库要更多,脚手架中的库更多是爱好者自己开发的。Vue和React生态圈中都有路由和状态管理器的工具,其中Vue的都是官方开发的。

19. TCP三次握手,四次挥手过程

过程参考下图。

因为断开连接时数据可能并未传输完成,所以挥手时要多一步。

20. CSS预处理语言

Sass和Less。Sass支持变量的定义和使用,有语法控制结构,同时支持@mixin定义mixin和@function定义函数。更多介绍可以看我之前的一段笔记

less语法使用上和Sass相近,采用JavaScript实现。支持本地和在线解析。本人没有用过,更多特性参考官网

21. JS里的错误和异常处理

try catch语句块捕获错误,catch块接受一个参数作为错误对象。对象的message属性会给出错误的详细信息。catch后还可以接上finally关键字,finally语句块在错误处理后必定执行。throw语句可以抛出错误。

22. 闭包

闭包是JavaScript中比较有特色的概念。它和JS中的作用域链(见问题4)概念密切相关。闭包发生在函数中定义的函数,在外层函数退出后,其作用域环境通过作用域链仍然保存在存活的内部环境中。利用这种特点,可以实现诸如状态保存,封装等特殊性质。

值得注意的是,内层函数的不合理操作会导致内存泄漏。且大量使用闭包会导致性能问题。不要过度依赖闭包。

23. 列举一些RESTful操作名

GET/POST/DELETE/UPDATE/PUT等

24. 列举一些CSS中的长度单位

固定长度:

  • px 像素点
  • mm 毫米
  • cm 厘米
  • in 英寸
  • pt 磅(1/72英寸)
  • pc 活字(1/6英寸)

相对长度:

  • em 以字体大小(font-size)为单位
  • ex 以小写字母大小为单位
  • rem 以根元素(默认为<html>)的字体大小为单位,用于自适应布局
  • vh 视口高度的1/100
  • vw 视口宽度的1/100
  • vmin 视口宽高较小值的1/100
  • vmax 视口宽高较大值的1/100

25. 前端职责

狭义地来说是实现UI设计师的设计稿和UE、UX的交互细节。宏观来说,是借助浏览器在技术上处理和用户交互的所有环节。近些年来,借助native的帮助,前端还可以实现后台的业务部分。

26. 职业规划

27. 获取新鲜资讯的方式

28. 前端模块化

模块化规范包括CommonJS,CMD(SeaJS),AMD(RequireJS)等。我此前做过一个小型的笔记

29. position类型

static, relative, absolute, fix四种。

  • static 正常文档流
  • relative 正常文档流,指定top, left等CSS属性相对原位置移动
  • absolute 脱离文档流,相对上一个非static元素定位
  • fix 脱离文档流,相对html定位

通常建议使用正常文档流减少潜在bug。绘制复杂动画时,建议使用脱离文档流的布局。

30. 盒模型

盒模型意为所有渲染的元素都是一个个的矩形。矩形区域内包含margin, border, paddingcontent4层。CSS属性中只有两种盒模型:border-boxcontent-box。后者是默认值。可以通过box-sizing属性设置。

31. 使用原生JS发送AJAX

现代浏览器中都通过XMLHttpRquest对象实现Ajax请求。古老的IE浏览器会有不同的实现方法(目前已经很少见了),如:

1
2
new ActiveXObject("Microsoft.XMLHTTP");
new ActiveXObject("Msxml2.XMLHTTP.6.0");

通常使用XMLHttpRequest发送GET的方法如下:

1
2
3
var xhr = new XMLHttpRequest();
xhr.open("GET", "demo.php?id=1");
xhr.send()

发送POST和其他复杂请求时,需要设置request header,在需要接受AJAX返回时,还可以监听readyState的change事件
,大致像下面这样:

1
2
3
4
5
6
7
8
var xhr = new XMLHttpRequest();
xhr.open("POST", "ajax_post.php");
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log("ok" + xhr.responseText);
}
}

XMLHttpRequest2中又引入了进度,跨域,中止等新特性。

另外,使用新的Fetch API也可以完成Ajax请求。Fetch提出的目标是提供访问和操纵HTTP的接口,异步的获取网络资源。它和XMLHttpRequst的区别是:

  • 即使响应是404或500,返回的Promise也会正常解决
  • 默认情况下,fetch在服务端不会发送或接受任何cookies

在Ajax需要跨域时,最常用的方法是使用jsonp的形式实现。不过目前通过XMLHttpRequest2或fetch也都能完成跨域请求。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function jsonp(url, success) {
var ud = '_' + +new Date,
script = document.createElement('script'),
head = document.getElementsByTagName('head')[0]
|| document.documentElement;
window[ud] = function(data) {
head.removeChild(script);
success && success(data);
};
script.src = url.replace('callback=?', 'callback=' + ud);
head.appendChild(script);
}
jsonp('http://soundcloud.com/oembed?url=http%3A//soundcloud.com/forss/flickermood&format=js&callback=?', function(data){
console.log(data);
})

31. 如何加快访问速度

这个问题实际上很大,可以从各个方面去优化

  • 压缩并打包资源文件
  • 使用CDN存储资源文件
  • 设置缓存
  • CSS sprites
  • 图片压缩
  • 图片懒加载
  • 合理的DOM层级设置
  • <script>标签设置deferasync或动态异步加载
  • 一般情况下,CSS在前,JS在后
  • 使用MVVM框架时,使用服务端渲染或预渲染

32. 前端的未来发展

随着大前端的风吹来,前端工作在横向和纵向都获得了更多的机会。横向上,由PC端到移动端甚至有界面展示的智能终端。不过后两者需要记住native库的帮助。纵向上,在NodeJS的帮助下,后台的部分业务功能抽离出来交由前端完成,前端对界面有完整的控制,数据通过接口的形式向后台索取。现在看来,身为一个前端工程师,不仅要对HTML,CSS,JavaScript老三样了如指掌,对Android或iOS也渐渐有了些要求。

33. CSS selector的优先级顺序

how browsers work中有介绍。根据CSS3 selectors specificity中的定义,一个选择器的优先级计算如下

  1. 如果声明来自于style属性,而不是带有选择器的规则,则记为1,否则记为0 (= a)
  2. 记为选择器中ID属性的个数 (= b)
    3.记为选择器中其他属性和伪类的个数 (= c)
  3. 记为选择器中元素名称和伪元素的个数 (= d)

将四个数字按a-b-c-d这样连接起来(位于大数进制的数字系统中),构成特异性。所使用的进制取决于上述类别中的最高计数。最终决定优先级顺序。简而言之就是,style > id > class > tag > pseudo class,统计情况下看个数,有!important时,以!important为准。

34. 连等的赋值顺序

问题是,有这样一段代码,问原理是什么:

1
2
3
4
var foo = { n: 1 };
var bar = foo;
foo.x = foo = { n: 2 };
console.log(foo.x); // undefined

我们来细化一下过程,首先我们要明确JavaScript中对象是引用类型:

  • 第一句里,首先创建了一个字面量对象,并将foo指向之
  • 第二句里,将foo赋值给bar,即bar也指向{ n: 1 }这个对象
  • 第三句里,又创建了一个{ n: 2 }的对象,首先寻找foo指向对象中是否有x属性,没有时则新建一个x属性指向这个字面量对象,接着改变foo存储的地址,指向这个新的对象。
  • 第四句里,由于新的对象没有x属性,foo.x将返回undefined

这时,如果我们console.log(bar)结果将是{x: {n: 2}, n: 1}`。

35. JavaScript的hoist行为

hoist特性又叫变量声明提升。是JavaScript中比较有特点的特性。意为将作用域中所有变量(包括函数)声明提升到语句的开头。如下面的语句

1
2
3
4
5
6
7
a = 1;
fun(a);

var a = 0;
function fun(num) {
return num + 1;
}

等同于

1
2
3
4
5
6
7
8
var a;
function fun(num) {
return num + 1;
}
a = 1;
fun(a);

a = 0;

需要注意的是当通过函数表达式声明函数时,会提示fun未定义。因为,此时的语句等同于

1
2
3
4
5
6
7
8
9
var a;
var fun;
a = 1;
fun(a);

a = 0;
fun = function(num) {
return num + 1;
}

最后,最佳的风格是所有的变量先声明再使用。这也是JSLint和JSHint等linter工具推荐的。

36. 优雅降级和渐进增强

又名graceful degration和progressive enhancement。是两种开发的思路。前者意为针对最高级的浏览器设计开发,再保证向下兼容;后者意为针对低版本浏览器设计,保证基础性能,再追对现代浏览器追加效果,提高用户体验。

37. 优化网页资源

  1. 使用CDN
  2. 分布存放
  3. CSS sprites
  4. disable etag

38. 浏览器一次可以从同一domain加载多少资源

2~8,因浏览器而异。这里有个非常全的表。

39. 轮播图设计思路

可以用display实现,配合渐变效果。需要看到幻灯片移动时,可以结合transform和scale实现,配合overflow: hidden

40. CSS3的部分新特性

  • border: border-radiusborder-image
  • background: background-sizebackground-origin
  • text: font-facetext-overflowtext-shadowword-breakword-wrap
  • transform: translaterotateskewscale
  • transition: transitionanimation
  • other: box-shadow

41. ARIA

ARIA全称Accessible Rich Internet Application。主旨是提升网页易用性,方便有阅读障碍的人使用。比较常用的属性有

  • role 当前元素的作用,
  • <label>, aria-label 元素名
  • aria-hidden 是否隐藏

42. CSS animation和JavaScript animation

前者方便简单,通过keyframe就可以画出动画,且浏览器会做一些优化,因此性能也比较好。后者更加灵活,可以暂停和反转,且支持交互性。更详细的分析参考这里

43. doctype是什么

doctype出现在HTML4.1。用于规范HTML和XML文档格式,在推出时,HTML有3种标准可以选择:strict, transitional, frameset。

1
2
3
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">

在HTML5中,只有一种doctype可以选择,那就是html:

1
<!DOCTYPE html>

44. standard mode和quirks mode

分别是标准模式和怪异模式。由于历史原因,为了兼容标准建立前就已存在的古老网站,浏览器存在着两种解析网页的模式。在怪异模式下,排版会模拟Navigator 4与Internet Explorer 5的非标准行为。为了支持在网络标准被广泛采用前,就已经建好的网站,这么做是必要的。在标准模式下,行为即(但愿如此)由HTML与CSS的规范描述的行为。在<!DOCTYPE>中指定html将自动启用标准模式。这里有更多介绍。

45. XHTML和HTML

XHTML伴随HTML4.01一同提出,使用更加严谨的语法。MIMEtype为application/xhtml+xml,比如:html元素需要有xml相关属性,元素名必须是小写字母,元素属性用"包围不能为空值,在内容里不能有&, 需要转义,包括其他特殊字符<>,空元素以/>结尾。由于语法过于严苛,使用的人不多。未推出的XHTML1.1便被html5取代。