2017年9月15號(hào)百度前端一面
筆試其實(shí)做得蠻不好的,收到面試通知有點(diǎn)出乎意料娃胆。自覺以自己現(xiàn)在的知識(shí)深度和廣度還不足以通過大廠的層層面試哩罪,于是抱著學(xué)習(xí)的心態(tài)去了。個(gè)人感覺是一次蠻好的查漏補(bǔ)缺锁摔,總共一個(gè)小時(shí)的時(shí)間廓旬,基本每個(gè)知識(shí)點(diǎn)都問到了,從HTML到CSS谐腰,從JS到WEB安全和性能優(yōu)化孕豹。常考的知識(shí)點(diǎn)在這次面試中都有體現(xiàn)十气,也沒有什么偏題怪題励背。面試官也很和善,問到的知識(shí)點(diǎn)我大概30%沒答上吧桦踊,基本都會(huì)耐心地解釋一下椅野。
好了廢話不多話,整理一下這次面試問到的問題(有些死活也想不起來了)籍胯,老規(guī)矩的分為JS和CSS+HTML以及其他三大類竟闪,順便把答案也附上,也小伙伴們一個(gè)參考杖狼。
CSS+HTML
-
內(nèi)聯(lián)元素與塊級(jí)元素的區(qū)別
塊級(jí)元素獨(dú)占一行炼蛤;
內(nèi)聯(lián)元素不換行,內(nèi)聯(lián)元素不能設(shè)置寬高蝶涩,可以設(shè)置padding理朋,不能設(shè)置margin-top、margin-bottom绿聘。
補(bǔ)充:若設(shè)置
display:inline-block
嗽上,表現(xiàn)為同行顯示,但可以設(shè)置width熄攘、height兽愤、padding、margintext-indent
屬性只對(duì)塊級(jí)元素起作用。 -
常見的內(nèi)聯(lián)元素與塊級(jí)元素(這里只寫了我自己日常常用的浅萧,若想知道全部的內(nèi)聯(lián)和塊級(jí)有些什么的可以自行搜索)
內(nèi)聯(lián)元素:
<span><a><img>
(<img>
內(nèi)聯(lián)塊狀元素逐沙,可以設(shè)置寬高)塊級(jí)元素:
<div><p><h1-6><ol><ul><pre>
補(bǔ)充: 替換元素是瀏覽器根據(jù)標(biāo)簽的元素與屬性來判斷具體的內(nèi)容。如
<input>
-
說一下標(biāo)準(zhǔn)盒模型和IE盒模型
當(dāng)你看到這一行的時(shí)候洼畅,請按F12吩案,換到element這一欄,就會(huì)看到一個(gè)四四方方的盒子帝簇,中間有一塊數(shù)字X數(shù)字的藍(lán)色區(qū)域徘郭,這叫content,剩下的區(qū)域在上面都寫上名字了(僅針對(duì)Chrome)己儒,這就是標(biāo)準(zhǔn)盒模型崎岂。
至于什么是IE盒模型,在標(biāo)準(zhǔn)盒模型中闪湾,width指的就是content的寬冲甘,而IE中,width指的是content+padding+border途样,即是說IE把content定義為了content+padding+border(其實(shí)我覺得這種定義方式還挺利于理解的)江醇。
-
box-sizing:border-box是什么效果
在上一題盒模型的基礎(chǔ)上,border-box就類似于IE的盒模型何暇,如果你設(shè)置了一個(gè)width陶夜,同時(shí)設(shè)置了
box-sizing:border-box
,這時(shí)候?yàn)g覽器就會(huì)幫你把border和padding計(jì)算到width中去裆站。 -
寫一個(gè)左邊固定寬度条辟,右邊自適應(yīng)的兩欄布局
<div id="left"></div> <div id="right"></div>
#left{ float:left; width:200px; } #right { width:100%; margin-right:-200px; }
-
上題的基礎(chǔ)上如何清除浮動(dòng)
第一種方法答
clear:both
,問clear:both
放在哪宏胯,于是畫了一個(gè)在左右兩個(gè)div之下的div說在這里設(shè)置clear:both
羽嫡。然后又引申出來,如果用一個(gè)div元素將左右的兩個(gè)元素包裹起來肩袍,可以在容器div中設(shè)置
:after
偽類杭棵。CSS如下(其實(shí)我一直對(duì)偽類有點(diǎn)困惑,照著碼從來沒想過是啥氛赐,今天面試官給我一指瞬間就get 了):.container::after { content: " "; clear:both; }
第二種方法
(這題我問面試官魂爪,他邊說我邊記,記完我問還有嗎艰管,他愣了一下滓侍,然后反問是我面你還是你面我(⊙﹏⊙))
第二種清除浮動(dòng)的辦法就是下一題的BFC,包裹兩個(gè)div的父容器生成一個(gè)塊級(jí)格式上下文牲芋,與外面隔絕開來獨(dú)立的一塊粗井,也不管什么浮動(dòng)不浮動(dòng)了尔破。具體BFC什么樣寫在下一題。
-
BFC(清除浮動(dòng))
Block Formatting Context
BFC大概就是上面說的浇衬,一個(gè)獨(dú)立的塊級(jí)上下文,怎么才能形成BFC找了一下標(biāo)準(zhǔn)說法:
- float的值不為none
- overflow的值不為visible
- display的值為inline-block餐济、table-cell耘擂、table-caption
- position的值為absolute或fixed
這里的四個(gè)條件都是針對(duì)父元素即上面設(shè)置的
.container
的,滿足其中一個(gè)就可以生成一個(gè)BFC絮姆,自然也能做到清除浮動(dòng)了醉冤。(這里面試官主要跟我說的是設(shè)置overflow:hidden)
-
垂直margin的合并
垂直margin合并就是上下相鄰的兩個(gè)塊級(jí)元素,如果剛好篙悯,上面設(shè)置
margin-bottom
蚁阳,下面設(shè)置margin-top
,這倆外邊距相遇了鸽照,那兩個(gè)就合并了螺捐,本來可能上面margin-bottom
設(shè)置20px
,margin-top
設(shè)置10px
矮燎,合并之后兩個(gè)元素上下的距離就變?yōu)?code>20px定血,即兩個(gè)屬性中較大的值。這里補(bǔ)充的一點(diǎn)就是垂直margin合并的條件時(shí)在同一個(gè)BFC中才會(huì)發(fā)生的诞外,如果兩個(gè)BFC就算它倆的margin相遇了澜沟,也不會(huì)融合的。
-
水平居中峡谊,垂直水平居中(position)
水平居中:
margin:0 auto
這里上下的外邊距隨便設(shè)置茫虽,不一定是0,左右要自適應(yīng)即auto
既们。行內(nèi)元素如何居中:水平
text-align:center
濒析,垂直設(shè)置line-height
與height
一樣高。垂直水平居中就合并一下贤壁。垂直水平居中: ①利用flex布局悼枢,很簡單的三行代碼,在父容器里設(shè)置脾拆。
.container { display:flex; justify-content:center; align-items:center; }
②利用position:這里就不是設(shè)置父容器了馒索,而是元素本身
div{ position:absolute; margin:auto; bottom:0; top:0; left:0; right:0; }
在我說完flex之后,面試官就問利用position怎么做名船,然后我就說了上下左右都為0绰上,把margin自適應(yīng)給忘了。
補(bǔ)充:還有利用css3里的
transform
渠驼,主要是針對(duì)不定寬高(即寬高為百分比的情況)蜈块,定寬高的話可以用負(fù)的margin值來做到,都是差不多的思想。transform實(shí)現(xiàn)垂直水平居中:
div{ position: absolute; top: 50%; left: 50%; width:50%;//注意這里的寬高都為百分比 height:30%; transform: translate(-50%, -50%); }
?
-
用過哪些選擇器百揭,選擇器的優(yōu)先級(jí)(同樣的這里選擇器列舉的也是我自己用過比較熟悉的)
(這里的分類參考MDN中對(duì)選擇器的分類)
簡單選擇器:元素選擇器爽哎、類選擇器、ID選擇器器一、(*)通配選擇器课锌;通配選擇器匹配所有的元素,慎用祈秕,對(duì)性能有影響渺贤。
屬性選擇器:
[attr][attr="val"][attr~="val"]
依次是元素中包含該屬性、元素中包含該屬性且屬性值為val
请毛、元素中包含該屬性且屬性值中包含val
志鞍。其他還有|^$
等,含義類似正則方仿。偽類和偽元素: 偽類 前 一個(gè)冒號(hào)固棚,常用的
:link :visited :hover :active(love hate)
,針對(duì)鏈接兼丰;以及nth-child nth-of-type
玻孟。偽元素前兩個(gè)冒號(hào),常用的
::after ::before
(前面清除浮動(dòng)就是用到了::after
偽元素)組合選擇器和多用選擇器:①A,B:滿足A或B(A和B也行)②A B:B是A的后代節(jié)點(diǎn)③A>B:B是A的直接子節(jié)點(diǎn)④A+B:AB有相同的父結(jié)點(diǎn)鳍征,并且B緊跟在A的后面⑤A~B:AB有相同的父節(jié)點(diǎn)黍翎,B在A之后,但不一定是緊挨著A(即④是⑤ 的子集)
-
元素和元素的偽類的優(yōu)先級(jí)
屬性選擇器艳丛,偽類選擇器和class類選擇器優(yōu)先級(jí)一樣匣掸,偽元素選擇器和元素選擇器一樣
-
HTML5新增了哪些
具體可以看MDN中的介紹:點(diǎn)我
語義化方面:
<header><footer><nav><section><article><section><hgroup><aside>
視頻和音頻:
<audio><video>
圖像方面:
<canvas>、WebGL(通過canvas.getContext('webgl')獲得對(duì)象)氮双、<SVG>
數(shù)據(jù)存儲(chǔ):
sessionStorage碰酝、localStorage
-
講一下localStorage和sessionStorage
sessionStorage存儲(chǔ)一個(gè)會(huì)話中的數(shù)據(jù),會(huì)話結(jié)束后數(shù)據(jù)就會(huì)被銷毀戴差。
localStorage的數(shù)據(jù)是永久存儲(chǔ)在客戶端的送爸,除非主動(dòng)刪除,否則不會(huì)過期暖释。
一般設(shè)置大小為5M以下袭厂。
API:(localStorage和sessionStorage的API都是一樣的,這里以sessionStorage為示例)
sessionStorage.key(0) //0位索引球匕,返回第0位數(shù)據(jù)的鍵值 sessionStorage.getItem("key") //鍵值為key的屬性值 sessionStorage.setItem("key","value") //存儲(chǔ)名為key纹磺,值為value sessionStorage.removeItem("key") //刪除鍵值為key的屬性 sessionStorage.clear(); //刪除所有sessionStorage中的屬性
?
JS
-
事件代理的原理
事件冒泡
-
怎么判斷一個(gè)數(shù)組
var arr = [1,2,3]; Object.prototype.toString.call(arr);//[object Array] //還可以用instanceof arr instanceof Array; // true
-
原型、原型鏈
原型:原型是一個(gè)對(duì)象亮曹,其他對(duì)象可以通過它實(shí)現(xiàn)屬性繼承橄杨。JS中每個(gè)函數(shù)都有一個(gè)prototype屬性秘症,它指向了函數(shù)的原型對(duì)象。
原型鏈:這里先給ECMA中的定義
Every object created by a constructor has an implicit reference (called the object's prototype) to the value of its constructor's "prototype" property. Furthermore, a prototype may have a non?null implicit reference to its prototype, and so on; this is called the prototype chain.
翻譯過來大概是這么個(gè)意思:
每個(gè)由構(gòu)造函數(shù)創(chuàng)建的對(duì)象都有一個(gè)隱式原型式矫,指向構(gòu)造函數(shù)的
prototype
屬性乡摹。 此外,這個(gè)原型也可能會(huì)有一個(gè)非空的隱式原型指向它的原型采转,它的原型再指向一個(gè)原型等等等趟卸;這就叫做原型鏈。死記硬背肯定要不得氏义。一般我就畫個(gè)例子,類似什么person图云,student之類的惯悠,然后再解釋,student的原型是person竣况,person也有一個(gè)原型指向上一級(jí)的原型克婶,這樣一直向上找到
Object.prototype
,這是原型鏈最后一層了丹泉,再往上找Object.prototype.__proto__
的話情萤,就是null
了。這里再補(bǔ)充一下
prototype和__proto__
的區(qū)別摹恨。顯示原型(
prototype
):顯示原型實(shí)現(xiàn)基于原型的繼承和屬性的共享桦卒。隱式原型(
[[prototype]]
):隱式原型是的作用就是構(gòu)成原型鏈窝趣,通過隱式原型可以一層層往上查找對(duì)象的原型。__proto__
是個(gè)不標(biāo)準(zhǔn)的屬性,是瀏覽器為了實(shí)現(xiàn)對(duì)[[prototype]]
的訪問所提供的一個(gè)方法劲腿。常理來說[[prototype]]
即隱式原型是不可訪問的。ES5里提供了Object.getPrototypeOf()
這個(gè)方法來獲得[[prototype]]
畔濒。 -
寫了一個(gè)表達(dá)式讓我說元素的原型是什么
首先是寫了一個(gè)
var dog = new Animal()
顽悼,我說是Animal.prototype
;然后是var arr = [1,2,3]
较木,我說是Array.prototype
红符;最后是問Object
的原型,Object
是個(gè)構(gòu)造函數(shù)嘛伐债,那就是Function.prototype
预侯。 -
閉包
(這里的定義來自于紅寶書)閉包是指有權(quán)訪問另一個(gè)函數(shù)作用域中的變量的函數(shù)。
死記硬背肯定累泳赋,我一般都記這段代碼
function outer(){ var x = "我是來自outer的x"; return function inner(){ console.log(x); } } var a = outer(); a(); //我是來自outer的x
反正對(duì)我而言代碼比定義印象深刻多了雌桑,然后再自己用語言把這段代碼描述一下,基本就能解釋閉包了祖今。
-
作用域校坑、作用域鏈
作用域怎么解釋拣技,這個(gè)看了很多地方,都覺得不滿意耍目。還是引用高程里面這段話吧膏斤。
執(zhí)行環(huán)境(execution context)定義了變量或函數(shù)有權(quán)訪問的其他數(shù)據(jù),決定了它們各自的行為邪驮。
為什么拿出來卻是執(zhí)行環(huán)境莫辨,是因?yàn)榭戳艘黄恼拢杏X里面的說法還蠻有趣的毅访。作用域大致也是這么個(gè)意思沮榜,但作用域是靜態(tài)的,執(zhí)行環(huán)境是動(dòng)態(tài)的喻粹,也就是說執(zhí)行環(huán)境是你執(zhí)行的時(shí)候才確認(rèn)的蟆融,而作用域是定義的時(shí)候確認(rèn)的。
作用域鏈:保證對(duì)執(zhí)行環(huán)境有權(quán)訪問的所有變量和函數(shù)的有序訪問守呜。
這里我個(gè)人理解加上看高程里面的說法型酥,感覺就是類似棧的結(jié)構(gòu),全局執(zhí)行環(huán)境在棧底查乒,進(jìn)入一個(gè)函數(shù)弥喉,一個(gè)執(zhí)行環(huán)境就被壓入棧中。在當(dāng)前這個(gè)函數(shù)玛迄,即棧頂?shù)膱?zhí)行環(huán)境由境,若是沒找到需要變量,則往下找憔晒。
當(dāng)執(zhí)行完這個(gè)函數(shù)后藻肄,這個(gè)函數(shù)的執(zhí)行環(huán)境就出棧,進(jìn)入之前的執(zhí)行環(huán)境中拒担,一直到最后棧里只剩下了全局執(zhí)行環(huán)境嘹屯。
-
變量對(duì)象
每個(gè)執(zhí)行環(huán)境都有一個(gè)與之關(guān)聯(lián)的變量對(duì)象(variable object),環(huán)境中定義的所有變量和函數(shù)都保存在這個(gè)對(duì)象中从撼。
活動(dòng)對(duì)象(activation object):當(dāng)函數(shù)被調(diào)用時(shí)州弟,活動(dòng)對(duì)象就被激活了。除了包含arguments這個(gè)特殊參數(shù)外低零,還包含了與變量對(duì)象一樣的婆翔,當(dāng)前執(zhí)行環(huán)境中的所有變量和函數(shù)等等等。(我個(gè)人理解掏婶,活動(dòng)對(duì)象就是arguments+被激活的變量對(duì)象)啃奴。
-
實(shí)現(xiàn)
sub/pub(on,off,triger,triger(*,{"name":"Alex"}))
*表示所有(大概知道是怎么個(gè)思路但是讓我寫就蒙蔽了,跟面試官說了之后他跟我講說因?yàn)橐院蠊纠锩鎸懣蚣艿脑捇径紩?huì)用到觀察者模式雄妥,所以了解如何實(shí)現(xiàn)還是很有必要的)
大概題目就是一個(gè)Emitter的類最蕾,其中有
on,off,trigger
三個(gè)函數(shù)依溯。on
傳入注冊的事件名和相應(yīng)的回調(diào)函數(shù);off
傳入事件名刪除對(duì)于這個(gè)事件的監(jiān)聽瘟则;trigger
觸發(fā)事件黎炉,參數(shù)為觸發(fā)的事件及傳入回調(diào)函數(shù)中的參數(shù)。//創(chuàng)建一個(gè)對(duì)象用于保存注冊的事件 var eventObj = {}; Emitter.prototype.on = function(event,fn){ if(!eventObj[event]){ //若不存在這個(gè)事件醋拧,則在對(duì)象中創(chuàng)建一個(gè)屬性慷嗜,值為一個(gè)空的數(shù)組 eventObj[event] = []; } //將傳入回調(diào)函數(shù)添加到事件的回調(diào)函數(shù)數(shù)組中 eventObj[event].push(fn); } Emitter.prototypr.off = function(event){ if(!eventObj[event]){ //不存在該事件,直接返回false return false; } //若存在則刪除 delete eventObj[event]; } Emitter.prototype.trigger = function(event,args){ //若傳入星號(hào)丹壕,則遍歷事件對(duì)象中的所有屬性庆械,執(zhí)行對(duì)應(yīng)數(shù)組中的回調(diào)函數(shù) if(event === "*"){ for(events in eventObj){ for(let i = 0;i<events.length;i++){ events[i](args); } } //若傳入是event名,則遍歷執(zhí)行屬性對(duì)應(yīng)數(shù)組中的所有回調(diào)函數(shù) } else if(eventObj[event]){ for(let i = 0;i<eventObj[event].length;i++){ eventObj[event][i](args); } } }
這一段代碼沒測試菌赖,只大概寫了下簡單思路干奢,有什么錯(cuò)誤歡迎指出。至于什么是觀察者模式這里就不贅述了盏袄。
-
給一段英文,讓每個(gè)單詞的首字母大寫
(這是最后一個(gè)問題吧薄啥,面試官說那最后做一個(gè)小的算法吧辕羽,我一聽算法全身毛都豎起來了,結(jié)果沒想到拿出來是這么道題垄惧。刁愿。。到逊。)
看了一眼就打算說怎么做铣口,結(jié)果面試官說想想再說……嚇的我還以為有什么陷阱。仔細(xì)看了兩眼觉壶,就很普通的一段英文嘛脑题。
然后就說用正則去匹配英文中的空格逗號(hào)句號(hào)括號(hào)等等分隔符,然后
split
成數(shù)組铜靶,遍歷數(shù)組叔遂,對(duì)每個(gè)元素的首字母都toUpperCase
。面試官點(diǎn)點(diǎn)頭争剿,然后我又問還有什么更有效率的辦法嗎(
怎么好像真的我在面他)已艰,他說也可以不用split
,直接正則匹配每個(gè)單詞然后替換首字母蚕苇。?
其他
-
性能優(yōu)化
這個(gè)問題太寬泛了哩掺,而且面試中基本都會(huì)問到。這次面試回答這個(gè)問題的時(shí)候我就感覺自己說得不夠有條理涩笤,基本是在腦袋里抓到什么說什么嚼吞,這樣純靠記憶力去說盒件,也容易說不完整。(當(dāng)然性能優(yōu)化想說全面說詳細(xì)那恐怕一個(gè)小時(shí)都不夠面的了)
在這個(gè)面經(jīng)里就不詳細(xì)說了誊薄,要找文章的話網(wǎng)上一大堆履恩。打算等校招季閑下來一點(diǎn)后再慢慢按自己思路整理一篇文章出來。
-
Web安全了解哪些
這里我就說了兩個(gè)呢蔫,XSS(Cross Site Scripting)和CRSF(Cross Site Request Forgery)切心。
是什么:XSS是跨站腳本攻擊,在所有可輸入的地方片吊,沒有對(duì)輸入數(shù)據(jù)進(jìn)行處理的話绽昏,都會(huì)存在XSS漏洞;CRSF是跨站請求偽造俏脊,攻擊者盜用用戶身份全谤,發(fā)送惡意請求。
如何防范:
XSS:對(duì)輸入進(jìn)行轉(zhuǎn)義爷贫,例如
<>
轉(zhuǎn)換為HTML字符實(shí)體< >
CRSF:增加驗(yàn)證流程(驗(yàn)證碼认然,指紋驗(yàn)證等)。
-
用過什么構(gòu)建工具漫萄,介紹一下
Webpack:把你的項(xiàng)目當(dāng)做一個(gè)整體卷员,通過一個(gè)給定的主文件(如:index.js),Webpack將從這個(gè)文件開始找到你的項(xiàng)目的所有依賴文件腾务,使用loaders處理它們毕骡,最后打包為一個(gè)(或多個(gè))瀏覽器可識(shí)別的JavaScript文件。
這里我認(rèn)為webpack的關(guān)鍵字就是壓縮和打包岩瘦。接下來的就看自己實(shí)際應(yīng)用中用到了什么就再具體說一說未巫。