字节pico前端面试

2,045 阅读2分钟

tranform

tranform: translate(30px, 0) rotate(45deg) 和 tranform: rotate(45deg) translate(30px, 0) 有区别吗?

有区别:tranform的转换,在没有改变原点的情况下,是以元素的中心点为transfrom-origin。(默认样下)水平发方向为x轴,竖直方向为y轴
详解:CSS3 transform属性的使用

transform原理

transform的原点默认是 50% 50%
XY轴是和元素关联的,对于元素来说,永远都是不会改变的

http chunk

浏览器地址栏中输入url后发生了什么

  • 浏览器进程中的网络线程请求获取到html数据后,通过IPC将数据传递给渲染器进程的主线程
  • 主线程将html解析构造dom树,然后进行样式计算,根据dom树和生成好的样式生成Layout tree
  • 通过遍历Layout tree 生成绘制顺序表,遍历Layout tree生成Layer tree
  • 然后主线程将Layer tree和绘制顺序一起传给合成器线程
  • 合成器线程按照规则进行分图层,并把图层分为更小的图块(tiles)传给栅格线程
  • 栅格线程进行栅格化,栅格化完成后
  • 合成器线程会获得栅格化线程传过来的draw quads图块信息,根据这些信息合成了一个合成器帧
  • 然后将该合成器帧通过IPC传回给浏览器进程
  • 浏览器进程在传给GPU进行绘制,最后就展示到了我们屏幕

详细分析:浏览器如何运作-页面渲染

px的理解,dpr是怎么计算的

px: 逻辑像素。
dpr: 设备像素比。 dpr = 物理像素 / 逻辑像素
CSS中的<length>(<number> + 单位)

原型题

输出结果以及原因

Function.prototype.a = 'function';
Object.ptototype.a = 'object';
function Person () {};
let child = new Person();
console.log(child.a); // 'object'
console.log(Parent.a); // 'function'

输出结果: object 、function
原因:child自身没有a属性,就会沿原型链查找,child的__proto__属性,指向其构造函数Person的原型prototype属性,此时仍然无法查找到a属性,继续沿上查找,Person.prototype.__proto__指向Object.prototype,所以最后返回的结果是object
查找关系如下 child --> child.__proto --> Person.prototype --> Person.prototype.proto --> Object.prototype --> 返回a属性的值

详细知识点:原型和原型链

AO 和 GO

AO:Active Object 执行上下中的一个
GO:Global Object
JS预编译-执行上下文

垃圾回收机制

详解垃圾回收机制

编程题

function timeout(time) {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve();
        }, time);
    });
}
const supervene = new Supervene();
function addTask(time, name) {
    supervene.add(() => timeout(time)).then(() => {
        console.log(`任务${name}完成`);
    });
}
addTask(10000, 1); // 10000ms后输出 任务1完成
addTask(5000, 2); // 5000ms后输出 任务1完成
addTask(3000, 3); // 8000ms后输出 任务3完成
addTask(4000, 4); // 11000ms后输出 任务4完成
addTask(5000, 5); // 15000ms后输出 任务5完成

题解:

function SuperTask(maxTaskNumber = 2) {
    this.tasks = [];
    this.runTaskNumber = 0;
    this.maxTaskNumber = maxTaskNumber;
}
SuperTask.prototype.add = function(fn) {
    return new Promise(resolve => {
        const task = () => {
            return fn.call(null).then(() => {
                resolve();
            })
        }
        this.tasks.push(task);
        this.run();
    })

}
SuperTask.prototype.run = function() {
    while(this.runTaskNumber < this.maxTaskNumber && this.tasks.length) {
        this.runTaskNumber++;
        const task = this.tasks.shift();
        task().then(() => {
            this.runTaskNumber--;
            this.run();
        })
    }
}

详解:JS实现并发任务调度