亲宝软件园·资讯

展开

腾讯实习前端工程师面经-一面

JobsOfferings 人气:2
# 腾讯前端面经一面 [TOC] ## 写在前面   博主现在读大三,前端小白一只,上一个随笔发出了最近的美团一面的面试题与注意事项,这里博主整理了一下腾讯二月二十九日的第一次面试题与解题思路,注意事项,希望对大家的面试有所帮助。 ## 面试题相关 ### 垂直居中问题 ***题目***   **屏幕正中间有一个元素A,随着屏幕宽度的增加,需要满足以下条件:** + A元素垂直居中于屏幕中央; + A元素距离屏幕左右边距各10px; + A元素里面的文字"A"的font-size:20px;水平垂直居中; + A元素高度始终为A元素宽度的50%;(如果搞不定可以实现为A元素的高度固定为200px) 请用**html**及**css**实现 ![图1](https://images.cnblogs.com/cnblogs_com/JobsOfferings/1363202/o_2003191531301.png "图1") --- ***解题思路***   这个题目考察的是主要是**垂直居中**的措施,具体的方法大家可以自行查找,这里贴出我自己的代码。主要的地方是使用calc计算属性去设置左右边距,然后height也顺带实现A元素高度始终为A元素宽度的50% ```html * { margin: 0; padding: 0; } body { width: 100%; height: 100vh; display: flex; align-items: center; justify-content: center; } .fa-area { position: relative; width: calc(100% - 20px); height: calc(50% - 10px); margin-left: 10px; background-color: #376AF3; } .fa-area>div { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: #fff; font-size: 20px; }
A
``` ### arguments ***题目***   **函数中的arguments是数组吗?若不是,如何将它转化为真正的数组?** --- ***解题思路***   这个题目考察对arguments的认识,以及call的使用,并没有提及手写call函数。 `不是` 转化方案: `arguments = [].slice.call(arguments);` ### 隐式类型转换 ***题目***   **请说出以下代码打印的结果** ```js if([] == false) {console.log(1);} if({} == false) {console.log(2);} if([]) {console.log(3);} if([1] == [1]) {console.log(4);} ``` --- ***解题思路***   这个题目主要考察对JS隐式转换的知识。   值得注意的是,当使用 == 的时候,JS会将两侧数据转换为number值,再进行==判断,再转换为bool值。所以第一行会打印,第二行不会打印(这里的原因是,对象转number的时候,会调用toString()方法,返回一个字符串直接量,js将这个字符串转换成数字类型,并返回这个数字。这一段在《JavaScript权威指南》可以查到)。   而若直接空数组转bool的话,所有的对象object,用于判断条件时就会被转化为true,所以第三行会打印。   第四行的话,对象是引用类型,看起来都是一样的两个空数组,但是其实是不同的两个对象,在内存中的地址是不同的,所以第四行不打印。   这里当时不太明白,所以只根据自己的想象打出了答案,但是没有讲出1、2、3行的理由。 答:`1 3` ### 异步问题 ***题目***   **请说出以下代码打印的结果** ```js async function async1(){ console.log('async1 start'); await async2(); console.log('async1 end'); } async function async2(){ console.log('async2'); } console.log('script start'); setTimeout(function() { console.log('setTimeout'); }); async1(); new Promise(function(resolve) { console.log('promise1'); resolve(); }).then(function() { console.log('promise2'); }); console.log('script end'); ``` --- ***解题思路***   这个题目主要考察对JS异步、JS执行机制的知识。   这题其实我没有很大把握,所以面试官准许我放在node环境下打印后问我原因,然后根据async1、async2的样子写出对应的Promise语句。 ```js new Promise((resolve) => { console.log('async1 start'); new Promise((resolve1) => { console.log('async2'); }) }).then(() => { console.log('async1 end'); }) ``` JS是一个单线程语言,所以是按照语句的执行顺序执行的。一般任务分为两类 + 同步任务:该任务在主线程上排队,一次执行 + 异步任务:没有立马执行的任务,放在任务队列中执行 而除了这两种,任务还可以分为以下两种 + 宏任务:整体代码script,setTimeout,setInterval等 + 微任务:Promise,process.nextTick等   在event loop中,宏任务执行完后,会判断内部有无可执行微任务,若有则执行可执行微任务,若无则执行接下来的宏任务。   所以我们可以这么分析这类题目:先执行宏代码,遇到微任务就先加入队列等待执行,宏任务执行完后按入队列顺序执行,再执行setTimeout队列代码。 答: ``` script start async1 start async2 promise1 script end promise2 async1 end setTimeout ``` ### this指向 ***题目***   **以最小的改动解决以下代码的错误**(可以使用ES6) ```js const obj = { name: 'jsCoder', skill: ['es6', 'react', 'angular'], say: function () { for (var i = 0, len = this.skill.length; i < len; i++) { setTimeout(function() { console.log('N0.' + i + this.name); console.log(this.skill[i]); console.log('------------------'); }, 0); console.log(i); } } } obj.say(); // 期望得到以下结果 1 2 3 N0.1 jsCoder es6 ------------------ N0.2 jsCoder react ------------------ N0.3 jsCoder angular ------------------ ``` --- ***解题思路***   这个题目主要考察对this指向、闭包的知识。   最初运行的时候是报错了,显示数组越界,所以for循环里的`i`改成了`i + 1`,然后`var i = 0`改成了`let i = 0`处理了这里的闭包问题(我并不希望`setTimeout`里面的`i`全是`4`),然后`this`的指向我是使用了匿名函数取代了`setTimeout`里面的函数,或者大家可以在外面使用`var that = this;`来绑定`this`。   以下是我的答案: ```js const obj = { name: 'jsCoder', skill: ['es6', 'react', 'angular'], say: function () { for (let i = 0, len = this.skill.length; i < len; i++) { setTimeout(()=> { console.log('N0.' + (i + 1) + this.name); console.log(this.skill[i]); console.log('------------------'); }, 0); console.log(i + 1); } } } obj.say(); ``` ### 手写bind ***题目***   **实现Function的bind方法** --- ***解题思路***   这个bind方法在各个博客中都有很详细的原理与解析,所以这里我只将我的答案贴上,希望轻喷。 ```js Function.prototype.bind = function (context) { // 这里要存一下this而不能把返回里的函数对象转为匿名函数 // 因为这本身就是为了因为bind()函数发布在ES5中,不能很好的兼容所有浏览器 var self = this; return function () { return self.apply(context, arguments); } } ``` ### 手写节流函数 ***题目***   **实现一个节流函数**   这里其实是用了一个很复杂的图来说节流的好处,然后让我写节流。   当时我不会写节流函数,但是我会写防抖,所以我和面试官说我的项目上的防抖的原理,所以面试官让我先写了一个防抖函数,写完之后解释了节流函数,再让我写了一次。不得不夸一下,这个面试官非常的有耐心,节流和要点都有和我讲到,所以我才能安心写出这个我没接触过的函数。下面贴出此题一种解法。 --- ***解题思路*** ```js window.onload = () => { // 这两行代码大家可以不用管,是因为我想演示效果,所以大家随便用一个点击div的事件就可以 let myInput = document.getElementById('myInput'); let inputSet; // 节流函数 myInput.addEventListener('click', () => { if (!inputSet) { // 第一次执行 console.log(myInput.value); inputSet = setTimeout(() => { inputSet = undefined; }, 500); } }) } ``` ### 算法题 ***题目***   **手写排序算法**   这里面试官是问了你知道哪些常见的排序算法?然后我说冒泡排序、快速排序、归并排序、希尔排序(注意这个希尔我是不会的,所以千万放后面说,如果面试官对快速或归并感兴趣,会让你停下来的,别硬讲你不懂的技术,不然很拉低面试官的印象分),然后他让我写一个快速排序,这个我有写过,但是当时写的时候里面的逻辑没有理清,面试官一直陪着梳理思路,最后还是写完了这个算法。 --- ***解题思路*** ```js function sort(arr, flag) { function swap(arr, a, b) { let temp = arr[a]; arr[a] = arr[b]; arr[b] = temp; } function partition(arr, left, right) { // 基准 let pt = arr[right]; // 指针 let storeIndex = left; for (let i = left; i < right; i++) { if (arr[i] < pt) { swap(arr, i, storeIndex); storeIndex++; } } swap(arr, right, storeIndex); return storeIndex; } function quickSort(arr, left, right) { if (left > right) return; var storeIndex = partition(arr, left, right); quickSort(arr, left, storeIndex - 1); quickSort(arr, storeIndex + 1, right); } quickSort(arr, 0, arr.length - 1); return arr; } console.log(sort([1, 4, 2, 10, 5, 7, 2, 4, 6, 7])); ``` ## 总结   其实一面都是一些很基础的问题,但是它会将考察点掺杂在所有的问题中,一旦你触及了这个方面,他就会问你这个相关知识,所以你需要在问题中提炼出他想问的知识点,**不要等他来问**:"这个可以用call来做吗?",**而是你自己在回答的时候就觉察出来**,并直接展示出来。   但是对于你不熟悉的技术,千万别硬掺杂在一系列名词中吐露出来,面试官万一就觉得你可能不会,硬问这个,你就难顶了。   希望大家都能收获自己期望的offer!

加载全部内容

相关教程
猜你喜欢
用户评论