【面试总结】记一次失败的 bilibili 面试总结
前几日去B站面试了一次前端,不算资深B站用户,平常也蛮喜欢在B站观看视频的,能获得这样的面试机会,实在是受宠若惊。但无奈实力有限加上琐事缠身,并没有做好充足的准备,导致面试失败。
(ps:属实还是有点紧张,发挥也受到影响)
这次面试过程我思前想后觉得有必要总结一下,希望自己下次再有这样的机会的时候能够把握的更好。
因内容比较多,所以准备可能分多篇博客更新内容,这里给出传送门
HTML布局、CSS选择器及JS基础综合能力知识点
算法基础:数组 flat、去重及排序
react vue 理解及基础知识
跨域问题解决方案
http协议状态码
缓存及更新问题
webview与原生应用交互
服务器端知识
ps:这是大纲,后续可能有变化。比如服务器端知识,我没有接触过,面试官就没问,但确实是面试过程中的一个大类的问题。
面试感受
面试过程整体感觉很舒服,面试官很有耐心,面试题由浅入深,面试打分的话,我会给5颗星。
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结构,需求如下:
完成经典的上 header ,下 footer ,左边是侧边栏,右边是内容。
去掉列表前面的 · ,列表项水平排列,注意里面的br标签需要换行,同时每两个li后有一条竖线。
点击列表项不跳转,弹出href内的内容。
ANSWER 1:
时光回溯:
这道面试题是基础题,我应该要多向面试官展示一下我的基本功,同时也要告诉面试官,我是有关注前端最新的动态的,既然不考虑兼容性,我得先用 Grid 的方案实现一遍,然后在告诉面试官我大概还有108种不同的解法,????哈哈哈…。然后 Grid 除了 display: grid 外,好久没有写了,我都忘记的差不多了吧。在思考 Grid 的时候,时间浪费了太久,我得赶紧找个简单的写法先提交,不然基础题都得做这么久,印象肯定不行。
浮动解决方案:
/**
* 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 去实现这个需求。或者请求高人指点一二。
晚上吃饭的时候突然有了 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 解决方案:
参考资料
MDN Grid 介绍
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: '|';
}
我目前是在职前端开发,如果你现在也想学习前端开发技术,在入门学习前端的过程当中有遇见任何关于学习方法,
学习路线,学习效率等方面的问题,你都可以申请加入我的前端学习交流3000人裙:前面:851 中间:231 最后:348。
里面聚集了一些正在自学前端的初学者裙文件里面也有我做前端技术这段时间整理的一些前端学习手册,
前端面试题,前端开发工具,PDF文档书籍教程,需要的话都可以自行来获取下载。
后来询问了面试官这个应该如何解决,得知可以考虑兄弟选择器试试。
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 工程化之后,*用的多了,但是也得了解底层才行啊。