您的位置:首页 > 职场人生

2019滴滴前端面试总结(一面)

2019-07-04 10:51 197 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/mei0515/article/details/94594660

面试过去一个多月了,说的把面试总结一下放到博客上,总之,拖延症害死人,终于有时间写了,算是给自己这段时间面试找工作的一个总结吧,这些知识以后也有利于自己回顾,仅个人总结可以自行补充
首先,很高兴能在牛客网上投滴滴的简历通过初选,以下是面试官的问题,面试是通过zoom视频面试(一面当时自己在学校)。
先说一句很惊讶的是面试官第一句竟然不是从自我介绍开始的,直接问问题

1.为什么会出现浮动和什么时候需要清除浮动?清除浮动的方式?

浮动元素碰到包含它的边框或者浮动元素的边框停留。由于浮动元素不在文档流中,所以文档流的块框表现得就像浮动框不存在一样。浮动元素会漂浮在文档流的块框上。
浮动带来的问题:
1)父元素的高度无法被撑开,影响与父元素同级的元素
2)与浮动元素同级的非浮动元素(内联元素)会跟随其后
3)若非第一个元素浮动,则该元素之前的元素也需要浮动,否则会影响页面显示的结构。
清除浮动的方式:
1)父级div定义height
2)最后一个浮动元素后加空div标签 并添加样式clear:both。
3)包含浮动元素的父标签添加样式overflow为hidden或auto。
4)父级div定义zoom
zoom:1的清除浮动原理?
清除浮动,触发hasLayout;
Zoom属性是IE浏览器的专有属性,它可以设置或检索对象的缩放比例。解决ie下比较奇葩的bug。
譬如外边距(margin)的重叠,浮动清除,触发ie的haslayout属性等。
来龙去脉大概如下:
当设置了zoom的值之后,所设置的元素就会就会扩大或者缩小,高度宽度就会重新计算了,这里一旦改变zoom值时其实也会发生重新渲染,运用这个原理,也就解决了ie下子元素浮动时候父元素不随着自动扩大的问题。
Zoom属是IE浏览器的专有属性,火狐和老版本的webkit核心的浏览器都不支持这个属性。然而,zoom现在已经被逐步标准化,出现在 CSS 3.0 规范草案中。
目前非ie由于不支持这个属性,它们又是通过什么属性来实现元素的缩放呢?
可以通过css3里面的动画属性scale进行缩放。

2.cookie、localStorage和sessionStorage区别

3.什么是BFC? 接着延伸问FC? FFC?

在解释 BFC 是什么之前,需要先介绍 Box、Formatting Context的概念。
  Box: CSS布局的基本单位
  Box 是 CSS 布局的对象和基本单位, 直观点来说,就是一个页面是由很多个 Box 组成的。元素的类型和 display 属性,决定了这个 Box 的类型。 不同类型的 Box, 会参与不同的 Formatting Context(一个决定如何渲染文档的容器),因此Box内的元素会以不同的方式渲染。让我们看看有哪些盒子:
1.block-level box:display 属性为 block, list-item, table 的元素,会生成 block-level box。并且参与 block fomatting context; 2.inline-level box:display 属性为 inline, inline-block, inline-table的元素,会生成 inline-level box。并且参与 inline formatting context;
3.run-in box: css3中才有, 这儿先不讲了。
Formatting context
 Formatting context 是 W3C CSS2.1 规范中的一个概念。它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。最常见的 Formatting context有Block fomatting context (简称BFC)和 Inline formatting context (简称IFC)。
CSS2.1 中只有 BFC 和 IFC, CSS3 中还增加了 GFC 和 FFC。
BFC 定义
  BFC(Block formatting context)直译为"块级格式化上下文"。它是一个独立的渲染区域,只有Block-level box参与, 它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干。
BFC布局规则:
.内部的Box会在垂直方向,一个接一个地放置。
.Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠
.每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
.BFC的区域不会与float box重叠。
.BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
.计算BFC的高度时,浮动元素也参与计算
二、哪些元素会生成BFC?
.根元素
.float属性不为none
.position为absolute或fixed
.display为inline-block, table-cell, table-caption, flex, inline-flex
.overflow不为visible
三、BFC的作用及原理

  1. 自适应两栏布局
     2. 清除内部浮动
    FFC
    FFC(Flex Formatting Contexts)直译为”自适应格式化上下文”.
    display值为flex或者inline-flex的元素将会生成自适应容器(flex container),可惜这个牛逼的属性只有谷歌和火狐支持,不过在移动端也足够了,至少safari和chrome还是OK的,毕竟这俩在移动端才是王道。
    Flex Box 由伸缩容器和伸缩项目组成。通过设置元素的 display 属性为 flex 或 inline-flex 可以得到一个伸缩容器。设置为 flex 的容器被渲染为一个块级元素,而设置为 inline-flex 的容器则渲染为一个行内元素。
    伸缩容器中的每一个子元素都是一个伸缩项目。伸缩项目可以是任意数量的。伸缩容器外和伸缩项目内的一切元素都不受影响。简单地说,Flexbox 定义了伸缩容器内伸缩项目该如何布局。
    GFC
    GFC(GridLayout Formatting Contexts)直译为”网格布局格式化上下文”

    当为一个元素设置display值为grid的时候,此元素将会获得一个独立的渲染区域,我们可以通过在网格容器(grid container)上定义网格定义行(grid definition rows)和网格定义列(grid definition columns)属性,在网格项目(grid item)上定义网格行(grid row)和网格列(grid columns)为每一个网格项目(grid item)定义位置和空间。
    那么GFC有什么用呢,和table又有什么区别呢?首先同样是一个二维的表格,但GridLayout会有更加丰富的属性来控制行列,控制对齐以及更为精细的渲染语义和控制。
    IFC
    IFC(Inline Formatting Contexts)直译为”内联格式化上下文”

    IFC的line box(线框)高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的padding/margin影响)
    IFC中的line box一般左右都贴紧整个IFC,但是会因为float元素而扰乱。float元素会位于IFC与与line box之间,使得line box宽度缩短。 同个IFC下的多个line box高度会不同。 IFC中时不可能有块级元素的,当插入块级元素时(如p中插入div)会产生两个匿名块与div分隔开,即产生两个IFC,每个IFC对外表现为块级元素,与div垂直排列。
    那么IFC一般有什么用呢?
    水平居中:当一个块要在环境中水平居中时,设置其为inline-block则会在外层产生IFC,通过text-align则可以使其水平居中。
    垂直居中:创建一个IFC,用其中一个元素撑开父元素的高度,然后设置其vertical-align:middle,其他行内元素则可以在此父元素下垂直居中。

4.JS数组去重

(我找了10种方法)
Methods 1:思路:定义一个新数组,并存放原数组的第一个元素,然后将元素组一一和新数组的元素对比,若不同则存放在新数组中。

function unique(arr) {
let newArr = [arr[0]];
for (let i = 1; i < arr.length; i++) {
let repeat = false;
for (let j = 0; j < newArr.length; j++) {
if (arr[i] === newArr[j]) {
repeat = true;
break;
}else{

}
}
if (!repeat) {
newArr.push(arr[i]);
}
}
return newArr;
}
console.log(unique([1, 1, 2, 3, 5, 3, 1, 5, 6, 7, 4]));
// 结果是[1, 2, 3, 5, 6, 7, 4]

Methods 2: 思路:先将原数组排序,在与相邻的进行比较,如果不同则存入新数组。

function unique2(arr) {
var formArr = arr.sort()
var newArr=[formArr[0]]
for (let i = 1; i < formArr.length; i++) {
if (formArr[i]!==formArr[i-1]) {
newArr.push(formArr[i])
}
}
return newArr
}
console.log(unique2([1, 1, 2, 3, 5, 3, 1, 5, 6, 7, 4]));
// 结果是[1, 2, 3,  4,5, 6, 7]

Methods 3: 利用对象属性存在的特性,如果没有该属性则存入新数组。

function unique3(arr) {
var obj={}
var newArr=[]
for (let i = 0; i < arr.length; i++) {
if (!obj[arr[i]]) {
obj[arr[i]] = 1
newArr.push(arr[i])
}
}
return newArr
}
console.log(unique2([1, 1, 2, 3, 5, 3, 1, 5, 6, 7, 4]));
// 结果是[1, 2, 3, 5, 6, 7, 4]

Methods 4: 利用数组的indexOf下标属性来查询。

function unique4(arr) {
var newArr = []
for (var i = 0; i < arr.length; i++) {
if (newArr.indexOf(arr[i])===-1) {
newArr.push(arr[i])
}
}
return newArr
}
console.log(unique4([1, 1, 2, 3, 5, 3, 1, 5, 6, 7, 4]));
// 结果是[1, 2, 3, 5, 6, 7, 4]

Methods 5: 利用数组原型对象上的includes

function unique5(arr) {
var newArr = []
for (var i = 0; i < arr.length; i++) {
if (!newArr.includes(arr[i])) {
newArr.push(arr[i])
}
}
return newArr
}
console.log(unique5([1, 1, 2, 3, 5, 3, 1, 5, 6, 7, 4]));
// 结果是[1, 2, 3, 5, 6, 7, 4]

Methods 6: 利用数组原型对象上的 filter 和 includes方法。

function unique6(arr) {
var newArr = []
newArr = arr.filter(function (item) {
return newArr.includes(item) ? '' : newArr.push(item)
})
return newArr
}
console.log(unique6([1, 1, 2, 3, 5, 3, 1, 5, 6, 7, 4]));
// 结果是[1, 2, 3, 5, 6, 7, 4]

Methods 7: 利用数组原型对象上的 forEach 和 includes方法。

function unique7(arr) {
var newArr = []
array.forEach(item => {
return newArr.includes(item) ? '' : newArr.push(item)
});
return newArr
}
console.log(unique7([1, 1, 2, 3, 5, 3, 1, 5, 6, 7, 4]));
// 结果是[1, 2, 3, 5, 6, 7, 4]

Methods 8: 利用数组原型对象上的 splice 方法。

function unique8(arr) {
var i,j,len = arr.length;
for (i = 0; i < len; i++) {
for (j = i + 1; j < len; j++) {
if (arr[i] == arr[j]) {
arr.splice(j, 1);
len--;
j--;
}
}
}
return arr;
}
console.log(unique8([1, 1, 2, 3, 5, 3, 1, 5, 6, 7, 4]));

Methods 9: 利用数组原型对象上的 lastIndexOf 方法。

function unique9(arr) {
var res = [];
for (var i = 0; i < arr.length; i++) {
res.lastIndexOf(arr[i]) !== -1 ? '' : res.push(arr[i]);
}
return res;
}
console.log(unique9([1, 1, 2, 3, 5, 3, 1, 5, 6, 7, 4]));
// 结果是[1, 2, 3, 5, 6, 7, 4]

Methods 10: 利用 ES6的set 方法。(最简单的方法)

function unique10(arr) {
//Set数据结构,它类似于数组,其成员的值都是唯一的
return Array.from(new Set(arr)); // 利用Array.from将Set结构转换成数组
}
console.log(unique10([1, 1, 2, 3, 5, 3, 1, 5, 6, 7, 4]));
// 结果是[1, 2, 3, 5, 6, 7, 4]

5.闭包什么是闭包(closure),为什么要用它?

官方解释 闭包是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量,利用闭包可以突破作用链域,将函数内部的变量和方法传递到外部。
通俗的解释闭包是就是函数中的函数,里面的函数可以访问外面函数的变量,外面的变量的是这个内部函数的一部分。
闭包的特性:
1.函数内再嵌套函数
2.内部函数可以引用外层的参数和变量
3.参数和变量不会被垃圾回收机制回收
闭包的作用
1.使用闭包可以访问函数中的变量。
2.以使变量长期保存在内存中,生命周期比较长。
可加分项
**闭包不能滥用,否则会导致内存泄露,影响网页的性能。闭包使用完了后,要立即释放资源,将引用变量指向null。 **

6.原型,原型对象、原型链等问题

构造函数中有prototype属性,也是一个对象,称之为原型对象,而该构造函数的原型对象中有constructor构造器指向自己的构造函数。构造函数可以实例化对象,实例化对象中有__proto__,它的指向为该构造函数的的原型对象。
原型:
(1)实例对象中__proto__这个属性,叫原型,是一个对象,是供浏览器使用的,不是标准的属性。__proto__可以称之为原型对象。
(2)构造函数中有prototype这个属性,叫原型,也是一个对象,这个对象程序员使用。 同时,构造函数中prototype称之为原型对象。
原型链:
它是一种关系,实例对象和原型对象之间的关系就叫原型链。它们的关系是通过原型(__proto)来联系的。如上图所示。

7.AJAX等问题

**同步现象:**客户端发送请求到服务器端,当服务器返回响应之前,客户端都处于等待 卡死状态
异步现象:客户端发送请求到服务器端,无论服务器是否返回响应,客户端都可以随 意做其他事情,不会被卡死
什么是 Ajax 和 JSON,它们的优缺点?
ajax的概念:ajax是一种通过后台与服务器进行少量的数据交换,使页面实现异步更新是一种创建交互式网页应用的网页开发技术。
json的概念:json是一种轻量级的数据交换格式,具有良好的可读和便于快速编写的特性
ajax的优缺点
优点:异步请求响应快,用户体验好;页面无刷新、数据局部更新;按需取数据,减少了冗余请求和服务器的负担;
缺点:异步回调问题、this指向问题、路由跳转back问题;对搜索引擎的支持比较弱,对于一些手机还不是很好的支持
json的优缺点
优点:
1.数据格式比较简单,易于读写,格式都是压缩的,占用宽带小
2.支持多种语言,.JSON格式的编码比较简单
3.JSON的解码难度较低比起XML简单的多
5.JSON和js交互更加方便
6.JSON的速度远远快于XML
缺点 :

  1. 没有XML格式这么推广的深入人心和使用广泛, 没有XML那么通用性
  2. JSON格式目前在Web Service中推广还属于初级阶段PS: 据说Google的Ajax是使用 JSON+模板 做的
    ajax与jsonp的异同
    1、ajax和jsonp这两种技术在调用方式上”看起来”很像,目的也一样,都是请求一个url,然后把服务器返回的数据进行处理,因此jquery和ext等框架都把jsonp作为ajax的一种形式进行了封装。
    2、但ajax和jsonp其实本质上是不同的东西。ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加script标签来调用服务器提供的js脚本。
    3、所以说,其实ajax与jsonp的区别不在于是否跨域,ajax通过服务端代理一样可以实现跨域,jsonp本身也不排斥同域的数据的获取。
    4、还有就是,jsonp是一种方式或者说非强制性协议,如同ajax一样,它也不一定非要用json格式来传递数据,如果你愿意,字符串都行,只不过这样不利于用jsonp提供公开服务。
    总而言之,jsonp不是ajax的一个特例,哪怕jquery等巨头把jsonp封装进了ajax,也不能改变这一点!

8.深拷贝和浅拷贝

**浅拷贝:**拷贝即复制,就相当于把一个对象中所有的内容复制一份给另外一个对象,直接复制,或把一个对象的地址给另外一个对象,它们的指向相同,两个对象之间有共同的属性或方法,都可以使用。
深拷贝:把一个对象中所有的属性或方法,通过遍历对象一个一个的找到,并且在另一个对象中开辟相应的空间,然后一个一个的存储到另一个对象中。

9.面向对象问题

面向对象的概念:
理解面向对象:
(1) 面向对象是相对于面向的过程而言的。
(2)面向过程和面向对象都是强调的一种思想。
(3) 面向过程:强调的是功能的行为。
(4)面向对象是基于面向过程的。
(5) 面向对象是基于面向过程的。
面向对象特点
1、是一种符合人们思考习惯的思想。
2、将复杂的问题简单化。
3、使程序员从动作的执行者变为动作的指挥者。
4、完成指定的需求时:
先去找具有所需功能的对象来用。
如果该对象不存在,那么创建一个具有所需功能的对象。
这样简化了开发并且提高了复用性。
面向对象开发、设计、过程
开发过程:其实就是不断的创建对象、调用对象、指挥对象做事情。
设计过程:其实就是在管理和维护对象与对象之间的关系。
面向对象的特性:
继承、封装、多态、抽象也算

10.深度优先遍历与广度优先遍历

图的遍历,所谓遍历,即是对结点的访问。一个图有那么多个结点,如何遍历这些结点,
深度优先遍历,从初始访问结点出发,我们知道初始访问结点可能有多个邻接结点,深度优先遍历的策略就是首先访问第一个邻接结点,然后再以这个被访问的邻接结点作为初始结点,访问它的第一个邻接结点。总结起来可以这样说:每次都在访问完当前结点后首先访问当前结点的第一个邻接结点。
广度优先遍历
类似于一个分层搜索的过程,广度优先遍历需要使用一个队列以保持访问过的结点的顺序,以便按这个顺序来访问这些结点的邻接结点。

说在最后的话之总结

由于自己技术很菜一面之后就没有下文了,然后我想说的是,作为前端人员基础一定一定一定要牢固,不牢固的赶紧去补!面试过程中被面试官看不起的感觉自己永远忘不了,这也会一直鞭策自己,现在自己只是刚开始实习,还未毕业,我想说,我们江湖再见!到那时我定会让你刮目相看!生命不止,学习不止,加油!!!

欢迎有兴趣的小伙伴一起监督学习和讨论学习方法呀!

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: