[关闭]
@yacent 2016-10-24T23:21:07.000000Z 字数 6635 阅读 1236

饿了么一面

面试题目


2016.05.19
在师兄的内推之下,有幸参加了ele的校招,约我时间大概是下午的5点多,估计面试官那时候才下班吧,毕竟不是正式校招的时间。一开始面试官不太方便,所以就直接用wechat来对我进行了面试,后来才打电话的,话不多说,我们来进行面试题目的总结吧。


CSS方面

首先是给了我一段代码,如下

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title></title>
  6. <style>
  7. .container div {
  8. display: inline-block;
  9. background: #333;
  10. width: 100px;
  11. height: 100px;
  12. color: #fff;
  13. }
  14. </style>
  15. </head>
  16. <body>
  17. <div class="container">
  18. <div class="a">
  19. </div>
  20. <div class="b">
  21. hello world
  22. </div>
  23. </div>
  24. </body>
  25. </html>

效果图大致如下:
demo地址: http://codepen.io/yacent/pen/BKgJao
基线对准问题

问:为什么会出现如图所显示的问题?就是inline元素上下错开

我思考了一会儿,这个问题大概是因为 基线(baseline) 对其的问题,即行内元素的对齐方式实际上是根据基线来进行对齐的,所以其会出现上下错位的问题,具体可以看看这篇的链接
那么,知道了问题,解决的办法也是挺多的,因为是可以通过 vertical-align 属性来进行调整对齐的方式的,其默认值是 baseline

解决办法: vertical-align 设置为 top | middle 都可以

vertical-align设置为 top之后,将显示为下图:

inline-block 间距

问:修改了vertical-align之后,两个div之间出现了空白,请说明原因和解决办法

这里的话,我们从代码里面进行分析吧,首先复现一下刚才写的代码,如下

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title></title>
  6. <style>
  7. .container div {
  8. display: inline-block;
  9. background: #333;
  10. width: 100px;
  11. height: 100px;
  12. color: #fff;
  13. vertical-align: top;
  14. }
  15. </style>
  16. </head>
  17. <body>
  18. <div class="container">
  19. <div class="a">
  20. </div>
  21. <div class="b">
  22. hello world
  23. </div>
  24. </div>
  25. </body>
  26. </html>

那么,分析完代码,产生的原因是因为 classadiv 闭合标签后面的换行导致的,会将换行也算作是一个DOM结点而加入到DOM树当中,所以会占据一定的文档空间。解决的办法,详见链接 总结起来,就是如下的几种方法

1. 不进行换行,即不同元素之间写成一行,再标签符内进行换行则不会产生空白符,但是不建议这种方法,代码可读性差
2. 使用margin-left的负值,但是该方法适用情况不同,不同字体大小需要调整不同的值
3. 不写闭合标签,这种方法兼容不太好,再HTML当中是可以这么写的,但是对于XHTML是不行的,而且适用的元素也不多
4. 父级元素的letter-spacing设置为负值,当前元素letter-spacing设置为默认值即可
5. 父级元素的word-spacing设置为负值,同上
6. -webkit-white-space-collapse:discard; 兼容性不好

刚才那一part算是过去了,下面继续,还是关于CSS方面的
给了我一段代码,如下

codepen地址: http://codepen.io/yacent/pen/MyMryE

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title></title>
  6. <style>
  7. ul {
  8. height: 300px;
  9. }
  10. li {
  11. height: 100px;
  12. border: 1px solid #ddd;
  13. box-sizing: border-box;
  14. }
  15. </style>
  16. </head>
  17. <body>
  18. <ul>
  19. <li>2</li>
  20. <li>2</li>
  21. <li>3</li>
  22. <li>4</li>
  23. <li>5</li>
  24. <li>6</li>
  25. <li>7</li>
  26. <li>8</li>
  27. <li>9</li>
  28. <li>10</li>
  29. </ul>
  30. </body>
  31. </html>

问: 垂直排列,超过ul的高度,从新的一列开始进行排列
面试官给了我一张最终的效果图应该是像下面一样的
垂直排列,自动换行

这个的话,用纯CSS是可以实现,即用 flex 来进行相对应的布局,具体可以看demo地址,即给ul 添加如下的属性

codepen地址: http://codepen.io/yacent/pen/MyMryE 把HTML当中的注释去掉

  1. ul {
  2. height: 300px;
  3. display: flex;
  4. flex-direction: column;
  5. flex-wrap: wrap;
  6. }

如果对于flex感到陌生的话,可以看看这一篇文章 Flex 布局教程:语法篇


CSS深入

问: 知道box-sizing吗?有什么用?

box-sizing 属性允许您以特定的方式定义匹配某个区域的特定元素,其默认值是 content-box,当使用border-box的时候,css属性设置 width的时候,会将padding 还有 border都算作 width的操作范围内

问: 说一下float的工作原理,在使用过程中有没有出现过什么问题?

我大致讲了一下,float的原理其实和position: absolute | fixed 的原理差不多,都是让元素脱离了文档流,而形成位置上的变化

具体的关于float的其他相关知识,可以看看这篇文章 float是如何工作的!

遇到的问题的话,就是在使用过程当中,由于浮动元素是脱了了文档流的,所以当父级元素没有其他子元素时,又没有进行清楚浮动的时候,会产生塌陷的情况

问: 如何进行浮动的清除

1. overflow: auto | hidden
2. clear: both
3. clearfix, 即再父元素的 before 和 after上进行 clear:both
三者各有利弊

具体也可以看看这篇文章 float 清除浮动


CSS深入

问: 请问,我页面上有这么一个布局,有两个div,左边的div有确定宽度,并且是固定的,右边自适应,请问你会怎么实现

codepen地址: https://codepen.io/yacent/pen/zqZPWa

一听到这个,心中飞过数百万头草泥马,这不就是圣杯布局吗,然后我给他讲了一下 实现的方式,主要思想就是要将父级元素的left预留出一定的空间,让左边div设置margin偏移过去就OK了
具体的话,可以看看codepen的地址,以前有写过这个

问: 还有没有别的方法来实现呢? 可以尝试一下使用flex来进行实现

codepen地址: https://codepen.io/yacent/pen/PNrQVa
关于 flex 的相关知识,可以看上面的 ul 布局那题的链接 进行flex属性的相关学习


代码风格方面

面试官给了我一段下面的代码

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title></title>
  6. </head>
  7. <body>
  8. <article>
  9. <div>
  10. <img src=""/>
  11. </div>
  12. <p>blablabla...</p>
  13. </article>
  14. </body>
  15. </html>

问:下面这段代码有什么不好的地方?

我思考好一会,这尼玛,我平时不会这么写,真看起来的时候,还真不好说哪里不好,我想了几分钟,说了以下的一些不好的地方

1. title没有内容,网页标题栏显示的是文件名,不太好
2. img空元素的 自闭合标签 风格不好,应该直接不写
3. img的src属性值不应该为空,浪费资源,为空时,也会发送一次HTTP请求
4. article当中不嵌套div,article当中一般只嵌套 p header footer artical等等

关于 div article section的区别,推荐一下这篇文章: https://www.qianduan.net/html5-differences-in-the-div-section-article/


JS事件绑定

又给了我一段代码,这面试官好喜欢直接给我代码呀,如下

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>1</title>
  6. <style>
  7. div, p, span {
  8. display: inline-block;
  9. margin: 30px;
  10. width: 100px;
  11. height: 100px;
  12. background: #1e89e0;
  13. }
  14. </style>
  15. </head>
  16. <body>
  17. <div></div>
  18. <p></p>
  19. <span></span>
  20. </body>
  21. </html>

问: 给div p span添加点击事件,alert 'hello world'

好吧,其实一开始,我纠结要不要一开始就写好一点的方法,但是不知道面试官的具体要求是什么,我就先写了最简单的方法给他

  1. ####单独绑定
  2. <script>
  3. window.onload = function() {
  4. document.body.getElementsByTagName("div")[0].addEventListener("click", function() {
  5. alert("hello world");
  6. }, false);
  7. document.body.getElementsByTagName("p")[0].addEventListener("click", function() {
  8. alert("hello world");
  9. }, false);
  10. document.body.getElementsByTagName("span")[0].addEventListener("click", function() {
  11. alert("hello world");
  12. }, false);
  13. }
  14. </script>

果真,面试官问我,有没有更好的方法呀,都是套路,我又写了一个 事件委托的实现方式

  1. <script>
  2. window.onload = function() {
  3. document.body.addEventListener("click", function(e) {
  4. var that = e.target;
  5. var name = that.nodeName.toLowerCase();
  6. if (name == "div" || name == "p" || name == "span") {
  7. alert("hello world");
  8. }
  9. }, false);
  10. }
  11. </script>

我个人觉得这种方法算比较好的了,面试官说,这个也不错的,然后问我有没有用过querySelectorAll,假如要你用,你怎么去实现,我的天,这面试官好爱玩啊,我继续用querySelectorAll写了一个

  1. <script>
  2. window.onload = function() {
  3. var nodeList = document.querySelectorAll("p, div, span");
  4. for (var i = 0, len = nodeList.length; i < len; i++) {
  5. nodeList[i].addEventListener("click", function() {
  6. alert("hello world");
  7. }, false);
  8. }
  9. }
  10. </script>

继续发问我 如果不用循环呢,你会怎么做
我没想到什么好的,就直接说了一句,用forEach来做可以吗,竟然又要我写,好吧,不过用forEach的话,因为它是数组的迭代方法,而用querySelectorAll返回的是一个dom的list,是伪数组,要先转换为 数组,才能调用forEach

  1. <script>
  2. window.onload = function() {
  3. var nodeList = document.querySelectorAll("p, div, span");
  4. var arr = Array.prototype.slice.call(nodeList);
  5. arr.forEach(function(item) {
  6. item.addEventListener("click", function() {
  7. alert("hello world");
  8. }, false);
  9. })
  10. }
  11. </script>

好吧,到这里 这题也就这么过去了


js 基础知识

问: 你说一下检测一个对象是不是数组的方法

我说了以下三种

1. Array.isArray()
2. Object.prototype.toString.call()
3. instanceof

其实后来去查阅了一些资料,使用instancof的时候,并不一定都可以检查是否为 Array类型,可以看看这篇文章,instanceof 在多个 iframe之间穿梭的时候,就会出现问题, 具体原因可以看看这篇文章 arr instanceof Array 并不总是对的

问: 用 typeof可以用来检测数组吗?然后typeof和instanceof有什么差别

typeof不能用来检测一个对象是不是数组,typeof只能用来检测基本数据类型,如number string  boolean null undefined,检测引用类型得用instanceof,instanceof的原理,实际上是判断 实例的 __proto__和构造函数的 prototype是不是指向同一个 原型对象,具体可以看看 http://www.ibm.com/developerworks/cn/web/1306_jiangjj_jsinstanceof/

问: typeof(null) 和 typeof(undefined)分别返回什么?

平时的确没有记这个东西,但是还是有一点点映象,typeof(null)返回的是 object, undefined的话,就返回undefied

问: null 和 undefined有什么差别

从目前的使用方法来看,null表示"没有对象",即表示此处不应该有值,而是指向一个空对象
    1. 作为函数的参数,表示该函数的参数不是对象
    2. 作为对象原型链的终点
而undefined的话,表示声明了,但缺少值,应该有一个值,还未定义
    1. 变量被声明了,但没有赋值时,就等于undefined。
    2. 调用函数时,应该提供的参数没有提供,该参数等于undefined。
    3. 对象没有赋值的属性,该属性的值为undefined
    4. 函数没有返回值时,默认返回undefined

js 基础

问: 一个字符串 '12345',如何将它 逆序输出?

这太应该是简单的送分提,学过js的人应该都是可以搞定的,我的答案如下
str.split('').reverse().join('')

排序算法

问: 你说一下 快速排序的实现吧

我还是喜欢用我比较熟悉的方法,原理是一样,因为一开始的快速排序是选一个基准,然后用两个指针,一个从左边开始,一个从右边开始,然后去和基准值进行比较,左边的比 Pivot大的,左指针停下,右边第一个比pivot小的,右指针停下,然后指针所对应的值呼唤,如此重复直到左右倆指针相遇,然后将pivot交换至中间

  1. function quickSort(arr) {
  2. if (Object.prototype.toString.call(arr) != '[object Array]') {
  3. return;
  4. } else {
  5. if (arr.length <= 1) {
  6. return arr;
  7. }
  8. var middle = Math.floor(arr.length / 2);
  9. var pivot = arr.splice(middle, 1)[0];
  10. var left = [];
  11. var right = [];
  12. for (var i = 0; i < arr.length; i++) {
  13. if (arr[i] < pivot) {
  14. left.push(arr[i]);
  15. } else {
  16. right.push(arr[i]);
  17. }
  18. }
  19. return quickSort(left).concat([pivot], quickSort(right));
  20. }
  21. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注