字节跳动前端实习生二面总结与反思

上一篇:一面总结

二面是现场面试,到约定时间就开始了。这不像视频面试还有个记录,我只能凭记忆尽量还原。面试过程如下:

一、自我介绍

首先要求自我介绍。

我吸取了一面的教训,我提前总结了自己做的和前端有关的项目。我简单介绍了我的教育背景,提到了已经保研,在大学期间没有接触过前端,然后说上一个实习的情况,我是Java开发实习生但是会涉及到前端。

期间面试官问了一些问题。

问题一:对深造和工作的看法。

答:深造可以对某一专业领域进行深入研究,读很多论文,可以对算法进行优化;工作可以锻炼实践能力,是一种任务型学习,可以更快地掌握知识。

问题二:为什么选择前端。

答:实习期间接触了前端,发现很有趣,相关知识也学得很快,做出前端的页面很有成就感。

问题三:谈一谈上一个项目。

答:我就讲解了我实现的一些前端功能,当然整体偏简单,还没讲完面试官就就进入下一环节了。

二、考官出题

面试官说会问一些前端的相关知识和计算机的基础知识。

1.前端进阶知识

1.1 cookie

首先问cookie是什么,cookie和localstorage有什么区别。

我回答,cookie用来存储用户的身份信息,保存在本地,比如登录一个网页,下次打开会自动登录。我没了解过loaclstorage。

网上查了资料,cookie指某些网站为了辨别用户身份而储存在用户本地终端(Client Side)上的数据。

localStorage是HTML5的本地存储方式,cookie会在http请求中携带,会在服务器和客户端间传递,所以cookie会有大小限制,不能超过4k,而且存在在设定的path下。localStorage只会存在本地,大小要比cookie大。cookie和localStorage整个浏览器都可以数据共享。

参考文章:前端存储浅谈——cookie、sessionStorage、localStorage

1.2 跨域

cookie是不可跨域的,了解同源策略吗,有什么解决方法。

我回答,不同源的窗口之间不能进行数据交换,不同源指协议、域名和端口号不同。跨域的实现技术由 jsonp ,修改 document.domain ,通过 window 的 name 属性也可以传递一定长度的数据,还有 H5 的 window.postMessage 方法。

又问,有没有了解过 CORS(跨域资源共享),我说没有。面试官说这种技术在服务器设置Access-Control-Allow-Origin,就可以实现跨域访问。

参考文章:前端常见跨域解决方案

1.3 CSRF

面试官又问,有没有了解过CSRF,比如一个网站有一个链接,点击链接就会出现问题。

我回答,了解过,但我忘了名字(跨站请求伪造),只说是假冒用户身份访问网站。

又问,该怎么防御。回答,每次给服务器的请求要进行验证,比如用验证码,或者请求加个字段,随机数之类的,使请求无规律可循。

参考文章:程序猿必读-防范CSRF跨站请求伪造

1.4 闭包

了解过闭包吗?简单描述下。

我说,闭包就是一个函数,是子函数,通过返回值的形式让外面的对象可调用。

问闭包的用途,这个我不会。

面试官说:闭包是用来实现一种类似“封装”的功能,如果想实现私有属性,可以把属性值通过闭包返回。

参考文章:闭包,是真的美

1.5 this

js有一个很重要的概念就是this,谈一下this指向什么。

我回答,this 指向最后一个调用它的对象,如果没有谁调用这个函数,this 指向 window 。

有什么改变 this 指向的方法。

我回答,在一个函数内,如果还有子函数,就在上一级用一个变量如 me 保存 this,在子函数内就调用me的属性。还可以用三个函数call,apply,bind改变 this 指向。

参考文章:理解JS中的call、apply、bind方法

1.6 new 操作符

new 一个对象,发生了什么。

我其实不太清楚,就说,分配了内存空间,对象的引用指向了这片内存。面试官说这是 Java 的说法。

面试官又问 new 一个对象 this 的指向和属性怎么变,我不太清楚。

参考文章:深入理解 new 操作符

1.7 原型链

又问你了解过继承吗,一个对象如何继承另一个对象的属性?我说是原型链吗?他说是。

我说,var person = new Person(); 那么,person._ proto _ = Person.prototype。

又问为什么可以继承。我说 Person.prototype 是 person 的原型对象,查询这个实例的属性,查不到就会找原型对象的属性,这样就可以继承。

下面的文章提到了继承:

关于继承,前面我们讲到“每一个对象都会从原型‘继承’属性”,实际上,继承是一个十分具有迷惑性的说法,引用《你不知道的JavaScript》中的话,就是:继承意味着复制操作,然而 JavaScript 默认并不会复制对象的属性,相反,JavaScript 只是在两个对象之间创建一个关联,这样,一个对象就可以通过委托访问另一个对象的属性和函数,所以与其叫继承,委托的说法反而更准确些。

参考文章:JavaScript深入之从原型到原型链

实际上,this ,new,原型链是在一个问题里问的,但我不是很清楚,所以在面试官的引导下,每个方面说了一点儿。

2.算法题

2.1 ajax,setTimeout

实现一个有试错次数的ajax函数,假如可以试错三次,那第一二次请求出错都可以再次请求。

函数形式 function retryAjax(url,retries,success,error)

//参数:请求的路径,可试错次数,成功回调函数,失败回调函数
function retryAjax(url,retries,success,error){
	$.ajax({
		url: url,
		type: GET,
		async: false,
		success: function(){
			success();
		},
		error: function(){
			if(retries > 0){ //还有试错机会
			    var r = retries  - 1;
				retryAjax(url,r,success,error);
			}
			error();
		}
	});
}

再加一个要求,两次调用期间有一定时间间隔,比如每隔3000ms才能调用一次,少于这个时间段不能再次调用。

我说用 setTimeout(),但一直没想好往哪儿加,最后面试官提示加到判断试错次数那里。

//参数:请求的路径,可试错次数,试错时间间隔,成功回调函数,失败回调函数
function retryAjax(url,retries,retrytime,success,error){
	$.ajax({
		url: url,
		type: GET,
		async: false,
		success: function(){
			success();
		},
		error: function(){
			setTimeout(){
				"if(retries > 0){ //还有试错机会
				    var r = retries  - 1;
					retryAjax(url,r,success,error);
				} ",retrytime};
			error();
		}
	});
}

2.2 Array

给一个数组arr,无序且可能有重复元素,比如arr = [1,4,2,2,0,2,3]。再给一个变量n,求数组中和等于n的数组对,如上数组就返回 [[1,3],[0,4],[2,2]],要求返回的数组对去重,时间复杂度不要太高。

我最开始想的是两重for循环,遍历找,最后去重。然后又想到可以先给数组排序,这样从排好序的数组的头尾往中间找,一重循环就能找完,但现场没有实现,我不知道该怎么处理有多个相同数据的情况。这道题不了了之。

面试完,我又想了想,可以先处理有相同元素的情况,把相同元素剔除,再排查一个没有重复数字的数组。

function query(arr, n){
	var len = arr.length;
	var tmp1 = new Array();
	tmp1 = arr.sort();
	//不存在满足情况的数组对
	if(len<2 || tmp1[0] + tmp1[len - 1] < n)
		return;
	var tmp2 = new Array();//存储没有重复元素的数组
	var result = new Array();//存储数组对
	tmp2.push(tmp1[0]);
	for(var i =  1;i <len;i++){
		if(tmp1[i] != tmp1[i-1]){
			tmp2.push(tmp1[i]);
			continue;
		}
		if(tmp1[i] + tmp1[i-1] == n){
			if(result.length!=0){
				var obj = result[result.length - 1][0];
				if(obj == tmp1[i])
					continue;//数组中已经有这个值了
			}
			result.push( [tmp1[i],tmp1[i]] );
		}
	}
	var len2 = tmp2.length;//没有重复元素的有序数组
	for(var a = 0;a < len2; a++){
		for(var b = a+1;b < len2; b++){
			if(tmp2[a]+tmp2[b] == n){
				result.push([tmp2[a],tmp2[b]]);
			}
		}
	}
	return result;
}

然后我调试了一下 ,是成功的。

html文件:
在这里插入图片描述
输出:
在这里插入图片描述

三、其他交流

面试官还问我有没有了解现在很流行的框架,我说没有,只学过 jquery,extjs,miniUI。

然后他说,有什么问题可以问我,我就问了几个问题。

我先问了前端是怎么开发的,在与后台交互的方面。他说,一般后台会写好一些接口,有数据的返回类型,他们自己造一些数据用于开发,等真正有数据了再测试。那前端会涉及到后台的内容吗?他说很少,但会自己实现一些交互层的API。

我又问现在后台的主要语言是什么。是 Python 和 Go ,当然 Go 的性能更强一些。

最后面试官说了对前端开发的一些看法。

前端开发要求的技术面很广,前端的框架更新换代也很快,需要不停地学习,但是框架在变,有些原理和思想是可以“继承”的。学一个框架,应该深入学习它的原理,比如 jquery ,虽然很早就有了,但现在仍然在用,是有他的道理的,它的链式调用就应该好好理解。

我们也需要主动学习新的流行框架,比如 vue,node.js。

总结:一面问的是前端基础知识(html+css+js)和算法,二面问的更多的是原理和算法。就像面试官说的,要懂原理,要主动学习框架。面试的一个小技巧是,如果你答不上来,可以说一下这个考点是什么,让面试官知道你了解的东西。

猜你喜欢

转载自blog.csdn.net/weixin_38673554/article/details/86615744