【前端面试】字节跳动2019校招面经 - 前端开发岗(一)
字节跳动2019校招面经 - 前端开发岗(一)
1. 介绍以及项目经历
吧啦吧啦……此处省略10000字面试官会从项目经历入手,考察项目中遇到的难题,以及解决方法,强调个人的努力以及在解决过程中扮演的角色(是主导还是参与)。
每个人都有不一样的精彩经历,好好琢磨简历怎么写吧 Q-Q
2. 浏览器基础
从浏览器输入网址到网页呈现,中间发生了什么?
具体可以参照我的另外一篇文章《【前端芝士树】从浏览器搜索框输入网址到网页呈现发生了什么?》
3. Javascript相关
字符串数组的倒序
题目如下
var input = 'Hello my best friend'; function reverse(){ //todo Please code here. }; console.log(reverse(input));//'friend best my Hello'
我的解法
先把字符串切分成数组,然后进行倒序插入
let input = 'Hello my best friend'; /** * reverse * @param str * */ function reverse(str) { let arr = str.split(' '); let result = []; let length = arr.length; for (let i = length - 1; i > -1; i--) { result.push(arr[i]); } return result.join(' '); } function reverse_2(str){ return str.split(' ').reverse().join(' '); } console.log(reverse(input));//'friend best my Hello' console.log(reverse_2(input));//'friend best my Hello'
Javascript中,this的指向是什么?
> 定义:this的指向是包含它的函数作为方法被调用时所属的对象。 1. 包含它的函数 2. 作为方法被调用时 3. 所属的对象。
比如
function hello(){ console.log(this.name); } hello(); //undefined
this
所在的方法是hello()
, 而hello()
的执行语境为全局,也就是说其所属的对象为windows
。
因为windows
是没有name
整个属性的,所以结果为undefined
。
再看下面的一段代码:
function hello(){ console.log('Hello ' + this.name); } var person = { name: 'Alice' }; person.hello = hello; person.hello(); //Hello Alice
在这段代码中,可以看到我们实现了一个person的对象,然后将方法赋值为person的一个函数属性。
当person.hello()
被调用时,this
指针指向的对象为person
,所以结果为Hello Alice
在实际应用场景中,常常分为四种情况进行讨论:
全局环境
全局环境下,this
就代表Window对象。var name = 'zhar'; function say(){ console.log(this.name);//zhar } say();
对象环境
对象环境中的this
指向对象本身。var obj = { name : "zhar", say : function(){ console.log(this.name);//zhar } } obj.say();
构造函数环境
构造函数中的this
会指向创建出来的实例对象function Person() { this.name = 'zhar'; } var p = new Person(); console.log(p.name);
事件对象
在 DOM 事件中使用this
,this
指向了触发事件的 DOM 元素本身li.onclick = function(){ console.log(this.innerHTML); }
如何修改this的指向?
使用局部变量来代替this指针
var name = "zhar"; var obj = { name : "zhar", say : function(){ var _this = this; //使用一个变量指向 this setTimeout(function(){ //把执行语境变成了全局环境 console.log(_this.name); },0); } } obj.say();
使用call 或 apply 方法
call 普通传参
function say(arg1,arg2){ console.log(this.name,arg1,arg2); }; var obj = { name : 'tom', say : function(){ console.log(this.name); } } say.call(obj,'one','two');//tom one two
apply 以数组的形式传参
function say(arg1,arg2){ console.log(this.name,arg1,arg2); }; var obj = { name : 'tom', say : function(){ console.log(this.name); } } say.apply(obj,['one','two']);//tom one two
4. CSS相关
实现一个宽度为父容器一半的位置居中的正方形
HTML代码如下
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div class="father"> <div class="item"></div> </div> </body> </html>
首先分解题目的几个关键点
- 宽度为父容器一半的正方形
- 位置居中
一些边写边问的过程中涉及的知识点
div
的默认display是block(块级元素)块级元素 和 行内元素 的区别
- 块级元素 独占一行, 其宽度自动填满父元素宽度,可以设置高度
[div
/h1~h6
-p
/ol
-ul
-li
/form
-button
-textarea
-select
/table
] - 行内元素 可以与其他行内元素排列在同一行中,宽高无效
[a
/img
/span
-strong
-b
-i
-em
/label
]
- 块级元素 独占一行, 其宽度自动填满父元素宽度,可以设置高度
父元素的display设置为flex后,子元素的display是?
- emmm,难道不是默认值static?
几种解题的方法
我按各个点,在代码中列举了几种方法,欢迎提供其他的思路
HTML
<!DOCTYPE html> <html lang="ch"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div> <div class="father center_1"> <div class="item square_1"></div> </div> <div class="father center_2"> <div class="item square_2"></div> </div> <div class="father center_3"> <div class="item square_2"></div> </div> </div> </body> </html>
CSS
.father { position: relative; width: 500px; height: 300px; margin: auto auto 2rem; background: lightskyblue; } .item { background: indianred; } /* 实现宽度为父元素一半的正方形 */ .square_1 { width: 250px; height: 250px; } .square_2 { width: 50%; padding-top: 50%; height: 0; } /* 实现位置居中 */ .center_1 { display: flex; align-items: center; /* 决定交叉轴上的对齐方式(垂直方向)*/ justify-content: center; /* 决定主轴上的对齐方式(水平方向)*/ } .center_2 .item { position: absolute; margin: auto; top: 0; right: 0; bottom: 0; left: 0; } .center_3 .item{ position: relative; top: 50%; left: 50%; transform: translate(-50%, -50%); }
5. 算法相关
抛硬币问题
假设你是小A,和小B玩一个抛硬币的游戏,硬币为正面时获胜,如果一方失败了则交由另一方,现在由你先开始,求获胜的概率?经典概率问题
- 假设小A第一次就抛到了正面,那小A获胜而游戏结束,概率为二分之一
- 假设小A第一次抛到的是反面,想要小A获胜只能小B抛反面,小A再抛回正面,至此概率为八分之一
- 后续同理,依次乘以四分之一,所有的概率进行相加,求极限可得结果为三分之二