估计阅读时长:10min(未完待更)
你好,我是星辉,幸会幸会。
今天下午我参加了字节跳动EE部门的前端视频第一次面试,把它记录总结下来,希望能够对大家带来帮助。
在准备前面文章中所说的前端面试的时候,听说字节跳动的EE部门在学校开宣讲会并进行笔试,抱着试一试的态度和记录一下题型为接下来的面试做下准备的心态就和我的小伙伴一起去参加了笔试。
EE部门即效率工程(efficiency engineer),为字节跳动公司创造提升公司效率工具的部门。
听着宣讲,心里开始活络了起来。哇,这个部门好适合我,我在平时生活中就是一个注重效率的人,EE在公司中有些提升效率的方法我也用过。
然后笔试,前后端混合考,听朋友说,考的是算法竞赛的一些题,总体来说是不会的。
然后…笔试就通过了,我想应该是对前端算法的要求比较低的缘故,不过我也把笔试总结在小技巧了。
我在面试前准备以下几点东西,似乎没有解决到面试的任何问题
这次面试和上一次不同,不再是用牛客网的连接了,使用的是视频会议室zoom。还在看博客,叮咚,面试官上线了。
这次面试官没有开视频,我无法通过视频得到面试官即时的情绪反馈,说话开始变得语无伦次,说着说着就想尽快终止了,自我介绍刚开始就崩盘。
来了来了,直接就开始问技术的问题了。
<meta name="viewport" content="width=device-width, initial-scale=1.0">
// 绝对像素单位变为rem相对单位
px=>rem
// 保持高宽比
// 使用width属性
img {
width: 100%;
height: auto;
}
// 使用max-width属性
img {
max-width: 100%;
height: auto;
}
// media query 不同设备显示不同图片和样式
/* For width smaller than 400px: */
body {
background-image: url('img_smallflower.jpg');
}
/* For width 400px and larger: */
@media only screen and (min-width: 400px) {
body {
background-image: url('img_flowers.jpg');
}
}
相同点:都表示“值的空缺”,相等运算符"=="认为两者是相等的,两者都可以转化为false,不包含任何属性和方法
不同点:严格相等运算符"==="认为两者是相等的
arguments 是一个对应于传递给函数的参数的类数组对象。
arguments对象不是一个 Array 。它类似于Array,但除了length属性和索引元素之外没有任何Array属性。例如,它没有 pop 方法。但是它可以被转换为一个真正的Array。
// 转化真正的数组
var args = Array.prototype.slice.call(arguments);
var args = [].slice.call(arguments);
// ES6使用Array.from()方法或扩展运算符将参数转换为真实数组
var args = Array.from(arguments);
var args = [...arguments];
返回 ‘object’
它类似于Array,但除了length属性和索引元素之外没有任何Array属性。例如,它没有 pop 方法。但是它可以被转换为一个真正的Array。被称为类数组。
1. 引用块级作用域的概念,可使用let命令和const命令
2. 数组的解构赋值(ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构。)
3. 字符串的拓展(模板字符串,新增includes()等方法)
4. 数值的拓展(ES6 将全局方法parseInt()和parseFloat(),移植到Number对象上面,行为完全保持不变,这样做的目的,是逐步减少全局性方法,使得语言逐步模块化)
5. 数组的拓展(数组的拓展运算符,新增Array.from()等API)
6. 对象的拓展(属性简洁表示,对象的拓展运算符,对象的合并等)
7. 函数的拓展(参数默认值,参数解构赋值,剩余操作符,箭头函数)
8. Promise对象
9. async函数
10. class类(super关键字)
11. Module的语法(export和import命令)
function timeout(ms) {
return new Promise((resolve, reject) => {
setTimeout(resolve, ms, 'done');
});
}
timeout(100).then(console.log)
所有异步任务都返回一个 Promise 实例。Promise 实例有一个then方法,用来指定下一步的回调函数。
Promise 对象起到代理作用,充当异步操作与回调函数之间的中介,使得异步操作具备同步操作的接口。
把执行代码和处理代码分离开,使异步操作逻辑更加清晰。
Promise对象代表一个异步操作,有三种状态:
初始状态:pending
操作成功:fulfilled
操作失败:rejected
对象的状态不受外界影响:只有异步操作的结果可以决定当前是哪一种状态,其他操作都不会影响状态改变
一旦状态改变,就不会再变
优点
可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数
对象提供统一的接口,使得控制异步操作更加容易
缺点
无法取消 Promise,一旦新建它就会立即执行,无法中途取消
如果不设置回调函数,Promise内部抛出的错误,不会反应到外部
当处于Pending状态时,无法得知目前进展到哪一个阶段
// 正常任务
setTimeout(function() {
console.log(1);
}, 0);
// 微任务
new Promise(function (resolve, reject) {
resolve(2);
}).then(console.log);
// 同步任务
console.log(3);
// 3
// 2
// 1
async 函数就是 Generator 函数的语法糖。
let promise = function (val){
return new Promise(function (resolve, reject){
setTimeout(()=>{
console.log(val);
resolve(val);
},1000);
});
};
let gen = function* (){
let p1 = yield promise('1');
let p2 = yield promise('2');
};
let genF = gen();
let promise = function (val){
return new Promise(function (resolve, reject){
setTimeout(()=>{
console.log(val);
resolve(val);
},1000);
});
};
let gen = async function (){
let p1 = await promise('1');
let p2 = await promise('2');
};
async用来申明里面包裹的内容可以进行同步的方式执行,await则是进行执行顺序控制,每次执行一个await,阻塞代码执行等待await返回值,然后再执行之后的await。
await后面调用的函数需要返回一个promise。
await只能用在async函数之中,用在普通函数中会报错。
await命令后面的Promise对象,运行结果可能是rejected,所以最好把await命令放在try…catch代码块中。
// 原型链的方式
// 用function定义对象
function Person(name, age) {
this.name = name
this.age = age
this.say = function() {
console.log(this.name)
console.log(this.age)
}
}
// 新对象继承Person
function Man(name,age) {
this.name = name
this.age = age
}
Man.prototype = new Person()
Man.prototype.speak = function() {
console.log("你好啊")
}
var m = new Man('hv',20)
m.say()
// apply方法的方式
function ClassA(name){
this.name = name;
this.sayName = function(){
console.log(this.name);
}
}
function ClassB(name,age){
ClassA.apply(this,arguments);
this.age = age;
this.sayAge = function (){
console.log(this.age);
}
}
// 输出全为10
for(var i=0;i<10;i++){
setTimeout(function(){
console.log(i);
},50);
}
// 输出相应的输出
for(var i=0;i<10;i++){
(function(i){
setTimeout(function(){
console.log(i);
},50);
})(i);
}
// 如果你引用一个方法,它将失去和对象的连接
> var func = jane.describe;
> func()
TypeError: Cannot read property 'name' of undefined
// 解决办法是使用函数内置的bind()方法。它创建一个新函数,其this值固定为给定的值。
> var func2 = jane.describe.bind(jane);
> func2()
'Person named Jane'
function f(y) {return this.x + y}
var o = {x : 1}
var g = f.bind(o)
console.log(g(2))// 3
CSS盒模型和IE盒模型的区别:
在 标准盒子模型中,width 和 height 指的是内容区域的宽度和高度。增加内边距、边框和外边距不会影响内容区域的尺寸,但是会增加元素框的总尺寸。
box-sizing: content-box; // 在宽度和高度之外绘制元素的内边距和边框。内容盒模型
IE盒子模型中,width 和 height 指的是内容区域+border+padding的宽度和高度。
box-sizing: border-box; // 通过从已设定的宽度和高度分别减去边框和内边距才能得到内容的宽度和高度。IE盒模型
// 基本类型:值相同即可
var a = 5
var b = 5
console.log(a == b) // true
// 对象类型:值和引用都相同才可
var a = [1,2,3]
var b = [1,2,3]
console.log(a == b) // false
// 修改b的同时也在修改a
var a = [1,2,3]
var b = a
console.log(a == b) // true
箭头函数相当于匿名函数,并且简化了函数定义。
// 箭头函数
x => x * x
// 相当于下面的函数
function (x) {
return x * x;
}
var fn = x => x * x
console.log(fn(4))
只包含一个表达式,连{ … }和return都省略掉了
包含多条语句,这时候就不能省略{ … }和return
x => x * x
x => {
if (x > 0) {
return x * x;
}
else {
return - x * x;
}
}
// 如果参数不是一个,就需要用括号()括起来
(x, y) => x * x + y * y
箭头函数完全修复了this的指向,this总是指向词法作用域,也就是外层调用者obj
考试不会写也要尽量把卷子给写满 题目不会写代码的话尽量往上面写代码思路 总结来说,“会就多写,不会就瞎比比”
笔试通过后我总结了一下,发现学校所教众多能力也不是不无用处。我想我笔试通过上面两项能力起到了至关重要的作用。