【面试总结】记一次失败的 bilibili 面试总结(1)

前几日去B站面试了一次前端,不算资深B站用户,日常也蛮喜欢在B站观看视频的,能得到这样的面试机会,实在是受宠若惊。但无奈实力有限加上杂事缠身,并无作好充足的准备,致使面试失败。javascript

(ps:属实仍是有点紧张,发挥也受到影响)css

此次面试过程我思前想后以为有必要总结一下,但愿本身下次再有这样的机会的时候可以把握的更好。html

因内容比较多,因此准备可能分多篇博客更新内容,这里给出传送门前端

ps:这是大纲,后续可能有变化。好比服务器端知识,我没有接触过,面试官就没问,但确实是面试过程当中的一个大类的问题。vue


面试感觉

面试过程总体感受很舒服,面试官颇有耐心,面试题由浅入深,面试打分的话,我会给5颗星。java


HTML布局、CSS选择器及JS基础综合能力知识点

<!DOCTYPE html>
  <html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style> * { margin: 0; padding: 0; } html, body, #app { margin: 0; padding: 0; height: 100%; } #header, #footer { height: 50px; line-height: 50px; text-align: center; background: #555; color: #fff; } #side { width: 200px; background: #eee; } /* css here */ </style>
  </head>
  <body>
    <div id="app">
      <header id="header">header</header>
      <aside id="side">side</aside>
      <div id="main">
        <ul>
          <li><a href="https://www.bilibili.com/1">Link1</a></li>
          <li><a href="https://www.bilibili.com/1">Link2</a></li>
          <li><a href="https://www.bilibili.com/1">Link3</a></li>
          <br>
          <li><a href="https://www.bilibili.com/1">Link4</a></li>
          <li><a href="https://www.bilibili.com/1">Link5</a></li>
        </ul>
      </div>
      <footer id="footer">footer</footer>
    </div>
    <script> // JS here </script>
  </body>
</html>
复制代码

不考虑兼容性且不能更改dom结构,需求以下:react

  1. 完成经典的上 header ,下 footer ,左边是侧边栏,右边是内容。
  2. 去掉列表前面的 · ,列表项水平排列,注意里面的br标签须要换行,同时每两个li后有一条竖线。
  3. 点击列表项不跳转,弹出href内的内容。

ANSWER 1:

时光回溯:

这道面试题是基础题,我应该要多向面试官展现一下个人基本功,同时也要告诉面试官,我是有关注前端最新的动态的,既然不考虑兼容性,我得先用 Grid 的方案实现一遍,而后在告诉面试官我大概还有108种不一样的解法,😃哈哈哈...。而后 Grid 除了 display: grid 外,很久没有写了,我都忘记的差很少了吧。在思考 Grid 的时候,时间浪费了过久,我得赶忙找个简单的写法先提交,否则基础题都得作这么久,印象确定不行。css3

浮动解决方案:

/** * calc 是 css的一个函数 * 不明白的同窗我附上连接 * https://developer.mozilla.org/zh-CN/docs/Web/CSS/calc */
#side {
  /* 设置 侧边栏 左浮动 */
  float: left; 
  height: calc(100% - 100px);
}

#main {
  height: calc(100% - 100px);
}
复制代码

position 解决方案:

#app {
  /* 父级元素 设置 相对定位 */
  position: relative;
}

#side {
  /* 左边栏 设置 绝对定位 */
  position: absolute;
  top: 50px;
  bottom: 50px;
  left: 0;
}

#main {
  /* 内容区 设置 绝对定位 */
  position: absolute;
  top: 50px;
  right: 0;
  bottom: 50px;
  left: 200px;
}

#footer {
  /* footer 设置 绝对定位 */
  position: absolute;
  bottom: 0;
  width: 100%; /* 设置浮动后,补上宽度 */
}
复制代码

Flex 解决方案:

❌受限于没法更改 DOM 结构,我以为难以使用 Flex 去实现这个需求。或者请求高人指点一二。web

晚上吃饭的时候忽然有了 Flex 解决这个问题的思路,感谢评论区同窗给的帮助。面试

#app {
  display: flex;
  flex-wrap: wrap;
}

#header {
  flex-basis: 100%;
}

#side {
  height: calc(100% - 100px);
}

#main {
  flex: 1; 
  height: calc(100% - 100px);
}

#footer {
  flex-basis: 100%;
}
复制代码

Grid 解决方案:

参考资料

本文不赘述Grid的全部内容,有须要的朋友能够传送门详细了解。下面我会介绍我用到的部分。

#app {
  /* app 为 grid 布局的容器,因此在此处建立 grid 布局 */
  display: grid;
  /** 这是一种缩略的写法 等价于 grid-template-rows: 50px auto 50px; grid-template-columns: 200px auto; 建立了一个 3 * 2 的格子 高度是 50px 自动 50px 宽度是 200px 自动 */
  grid: 50px auto 50px / 200px auto;
}

/* 这个时候其实打开页面看着很奇怪,header 缩在角落,等等 */

#header, #footer {
  /** -*- 重要 -*- 下面的写法 等价于 grid-column-star: 1; grid-column-end: 3; 该 grid 的子项 开始与 第一根 column 线 结束与 第三根 column 线 */
  grid-column: 1 / 3;
}
复制代码
#app {
  display: grid;
  /** 等价于 grid-template-rows: 50px auto 50px; grid-template-columns: 200px auto; grid-template-areas: "header header" "side main" "footer footer"; 注意: 每一 row 只是一个字符串 */
  grid: "header header" 50px "side main" auto "footer footer" 50px / 200px auto;
}

#header {
  /* 注意: header 没有双引号 */
  grid-area: header;
}

#footer {
  grid-area: footer;
}
复制代码

ANSWER 2:

时间回溯:

取消 · 没有难度。这个题目的难点就在这个 br 标签,原本能够直接使用 flex 布局,如今的话看状况应该只能使用 inline 或者 inline-block 的方式进行水平排列了。加竖线能够用伪类选择器和伪类元素选择器组合实现,可是我忘记了 :nth-of-type 伪类选择器。

ul {
  /* 去掉 · */
  list-style: none; 
}

ul li {
  /* 水平排列,两个都行*/
  display: inline;
  /* display: inline-block; */
}
复制代码

当时最后一个加竖线的需求,我是这样写的。

/* 伪类选择器 + 伪类元素选择器 */
ul li:nth-child(2n)::after {
  content: '|';
}
复制代码

可是只有 Link2 Link5 后面会出现 "|",由于 br 标签的缘故,失败。

但只须要稍加修改就能够完成,但面试的时候没有完成。

/* 伪类选择器 + 伪类元素选择器 */
ul li:nth-of-type(2n)::after {
  content: '|';
}
复制代码

后来询问了面试官这个应该如何解决,得知能够考虑兄弟选择器试试。

TODO: 我目前尚未想出来如何处理。Help!

ANSWER 3:

没啥好说的。把事件绑定在父元素上,节约内存。考察点就是原生dom的一些操做吧。

document.querySelectorAll('ul')[0].addEventListener('click',event => {
  if(event.target.tagName === 'A') {
    event.preventDefault(); // 阻止默认行为
    alert(event.target.getAttribute('href'));
  }
});
复制代码

总结:

  • 前三种方式都是比较传统的布局方式,确实能解决问题,可是比较抽象。
  • Grid 的布局方式是一个二维的基于网格的布局系统,它的目标是彻底改变咱们基于网格的用户界面的布局方式。当使用这种布局方式的时候,在chrome中打开调试,能很清晰的看见网格的存在。相对于前三种,直观方便快捷。
  • 伪类选择器这种平常可能不经常使用的东西可能就是面试的盲点。
  • javascript 工程化以后,轮子用的多了,可是也得了解底层才行啊。
相关文章
相关标签/搜索