zl程序教程

您现在的位置是:首页 >  其他

当前栏目

2021届秋招腾讯前端一面面经

2023-09-11 14:18:53 时间

码字不易,有帮助的同学希望能关注一下我的微信公众号:Code程序人生,感谢!代码自用自取。

在这里插入图片描述

基本信息

部门:QQ音乐
方式:电话面试

题目总结

JavaScript篇

  • 自我介绍
  • 学习前端多久
  • JavaScript常见的数据类型有哪些
  • typeof null返回什么
  • 原始类型和对象类型有什么区别
  • 如何判断是Object还是Array
  • 有接触过闭包吗?闭包有哪些应用场景
  • js的垃圾回收机制
  • 如何自己实现一个new
  • 如何自己实现一个instanceof
  • 原型链的最顶层是什么(null)
  • 原型链的继承方式有哪些,举例说明
  • 原型链有没有什么缺点
  • 子类child继承了父类的parent之后,oarent有一个属性name。这时new一个子类的实例b,如果修改了b.name是否会修改父类上的name属性
    HTTP篇
  • 如何用ajax原生实现一个post请求(XMLHTTPRequest)
  • 其中有ReadyState,解释一下它的每个值代表的含义
  • 使用ajax如何解决跨域问题
  • 使用JSONP时服务端返回什么样的数据,如何处理(callback(json拼好))
    DOM篇
  • 假设一个 ul 下有一万个 liliinnerHTML 是从 09999,当点击某个 li时输出该 li 代表的值,如何实现
  • windowOnloadDOMready 哪个先触发
    浏览器安全篇
  • 讲讲 CSRFXSS 攻击的原理,和解决方式
  • 假设有两个 tab,一个是 a.qq.com,另一个是黑客的域名,你在黑客的域名下向 a.qq.com 发起了一个请求,请问是否会带上 a 页面的 cookie
    算法篇
    爬楼梯

部分题目答案:

JavaScript常见的数据类型有哪些?

答案:
共8种。包括7种基本数据类型:

  • 表示空:null,undefined
  • 三大件:string,number,boolean
  • 两个新类型:BigInt,Symbol
    object
    解读:
    这里是按照 MDN 的说法回答的。也可以回答为 7 种 基本 数据类型,和 引用 类型。引用类型包括:
  • 普通对象 Object
  • 数组对象 Array
  • 正则对象 RegExp
  • 函数 Function

如何判断是 Object 还是 Array

答案:

Object.prototype.toString.call([]) // "[object Array]"
Object.prototype.toString.call({}) // "[object Object]"

解读:
这是目前最准确的方法,网上流传了很多种判断方法,这个是最核心的,答出这个就可以了。

除此之外,还有一种提问方式是 如何判断是不是 Array,这是偏向于考察 ES6 新增的数组方法了,可以用Array.isArray()instanceof来回答。

Array.isArray([1,2,3,4]) // true
Array.isArray({a:1, b:{c:'4'}}) // false

[1,2,3,4] instanceof Array // true
({a:1, b:{c:'4'}}) instanceof Object // true,这里使用 () 保证代码运行的优先级,不然会报语法错误

JS的垃圾回收机制

答案:
2012 年以前,相对旧的浏览器使用「引用-计数」算法(Reference Counting)进行垃圾回收,缺点是会由于循环应用导致内存泄漏。现代浏览器都使用「标记-清除」算法(Mark and Sweep),即从全局对象作为的根节点开始,向下查询引用的对象,没有查询到的对象都将被回收。
解读:
相对旧的浏览器如 ie6,ie7 是使用「引用-计数」法进行垃圾回收的。
参考链接:MDN

如何自己实现一个 new

答案:

function funcNew(obj, ...args) {
    const newObj = Object.create(obj.prototype);
    const result = obj.apply(newObj, args);
    return (typeof result === 'object' && result !== null) ? result : newObj;
}

解读:
先通过一个例子来理解 new 的作用吧:

function Person(name) {
    this.name = name;
}

Person.prototype.sayName = function() {
    console.log(this.name);
} 

const p = new Person('orange')
console.log(p.name) // 'orange'
p.sayName(); // 'orange'

代码中我们新建了一个对象 Person,它具有属性 name,且在Person.prototype 上定义了函数 sayName

当我们通过 new创建一个新的实例 p 时,便同时具有了属性 p.namep.sayName(),关系如下图:

在这里插入图片描述

知道了原理,就可以自己实现了。也就是说,自己写一个函数 funcNew(),使得 const p = new Person('orange')const p = funcNew('orange') 得到的 p 完全相同,于是得到了答案中的代码。

答案中最后一行代码如何理解?
前面的例子我们只考虑了 Person 中没有返回值的情况,如有有返回值,new 一个实例将会受到 Person 中返回值的影响。比如说:

/**
 * --- Person 中 return 一个对象,p 为该对象 ---
 */

function Person(name) {
    this.name = name;
    return {age: 35}
}

Person.prototype.sayName = function() {
    console.log(this.name);
} 

const p = new Person('orange')
console.log(p) // { age: 35 }
console.log(p.name) // undefined
p.sayName(); // TypeError: p.sayName is not a function

/**
 * --- Person 返回非对象,return 不影响结果 ---
 */

function Person(name) {
    this.name = name;
    return 'free'
}

Person.prototype.sayName = function() {
    console.log(this.name);
} 

const p = new Person('orange')
console.log(p) // Person { name: 'orange' }
console.log(p.name) // orange
p.sayName(); // orange

上面的例子中,如果返回了一个对象,我们需要返回该对象;如果不是对象,则 return 没用,正常处理。

如何自己实现一个instanceof

答案:

/*
 * --- 手动实现 instanceof ---
 */

function newInstanceOf (leftValue, rightValue) {
    if (typeof leftValue !== 'object' || rightValue == null) { 
        return false;
    }
    
    let rightProto = rightValue.prototype;
    leftValue = leftValue.__proto__;
    
    while (true) {
        if (leftValue === null) return false;
        if (leftValue === rightProto) return true;
        leftValue = leftValue.__proto__;
    }
}

/*
 * --- 验证 ---
 */

const a = [];
const b = {};

function Foo () {}

var c = new Foo()
function Child () {}
function Father() {}
Child.prototype = new Father()
var d = new Child()

console.log(newInstanceOf(a, Array)) // true
console.log(newInstanceOf(b, Object)) // true
console.log(newInstanceOf(b, Array)) // false
console.log(newInstanceOf(a, Object)) // true
console.log(newInstanceOf(c, Foo)) // true
console.log(newInstanceOf(d, Child)) // true
console.log(newInstanceOf(d, Father)) // true
console.log(newInstanceOf(123, Object)) // false 
console.log(123 instanceof Object) // false

解读:
这个问题既考察了 instanceof 的原理,又考察了原型链,还考察了代码能力,是一个好问题。

在实现代码中,我们判断 leftValue 是否为 rightValue 的实例,思想是在 leftValue 的原型链上,即 leftValue.__proto__ 上寻找是否存在 rightValue.prototype。原理图如下:

在这里插入图片描述

这需要我们熟练掌握原型链的相关知识。

如何用ajax原生实现一个post请求

答案:

function ajax_post(url, data) {
    // 1. 异步对象 ajax
    var ajax = new XMLHttpRequest();
    
    // 2. url 方法
    ajax.open('post', url);
    
    // 3. 设置请求报文
    ajax.setRequestHeader('Content-type', 'text/plain');
    
    // 4. 发送
    if (data) {
        ajax.send(data);
    } else {
        ajax.send();
    }
    
    // 5. 注册事件
    ajax.onreadystatechange = function () {
        if (ajax.readyState === 4 && ajax.status === 200) {
            console.log(ajax.respenseText);
        }
    }
}

上述代码中,ReadyState每个值的含义

答案:
在这里插入图片描述

DOM题目

假设一个 ul 下有一万个 liliinnerHTML 是从 09999,当点击某个 li 时输出该 li 代表的值,如何实现

答案:
采用事件委托:

<ul id="ul">
    <li>0</li>
    <li>1</li>
    <li>2</li>
    ...
    <li>9999</li>
</ul>
window.onload = function () {
    var uli = document.getElementById("ul");
    uli.onclick = function(event) {
        alert(event.target.innerText);
    }
}

解读:
首先,我们当然不可能为每一个 li 标签手动添加一个 click 事件(容易累死);其次,我们可能会想到使用 for 循环遍历每个元素,然后为其添加 click 事件,但这样会频繁操作 DOM,降低性能,卡到爆炸。

而事件委托意义就在于此:减少 DOM 操作,从而减少浏览器的重绘与重排次数,提升性能。

事件委托的原理是,将 li 上监听的 click 事件委托到 ul上。这里运用到了 事件冒泡 的机制,即 onclick 事件以 li -> ul -> body -> html -> document 的冒泡顺序逐步传递。

所以,我们可以选择在其中的 ul 上监听 click 事件,从而实现事件委托。

如何创建 100000 个 <li> 呢?总不能复制粘贴 100000 次吧?

创建 100000个 <li> 标签,思路是将 0∼9999 保存在数组中,然后转化为字符串 "<li>0</li><li>1</li>...<li>9999</li>",最后将他们作为 ul 标签的 innerHTML 即可。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<script src="create100000li.js"></script>
<body>
<ul>
</ul>
</body>
</html>
/* --- create100000li.js --- */

window.onload = function() {
    var ul = document.getElementsByTagName("ul");
    var arr = [];
    for (let i = 0; i < 100000; i++) {
        arr.push(i);
    }
    ul[0].innerHTML = '<li>' + arr.join('</li><li>') + '</li>'
}

有微信小程序课设、毕设需求联系个人QQ:505417246

关注下面微信公众号,可以领取微信小程序、Vue、TypeScript、前端、uni-app、全栈、Nodejs、Python等实战学习资料
最新最全的前端知识总结和项目源码都会第一时间发布到微信公众号,请大家多多关注,谢谢

关注公众号后,回复前端面试题,领取大量前端面试题汇总pdf资料
在这里插入图片描述