cristinazhou / Blog

1 stars 0 forks source link

字节生活服务面经 一面 #1

Open cristinazhou opened 2 years ago

cristinazhou commented 2 years ago

1、typeof 和 instanceof 区别, 判断数组的方法有哪些?

typeof 来判断number, string, object, boolean, function, undefined, symbol 这七种类型 js 在底层存储变量的时候,会在变量的机器码的低位1-3位存储其类型信息 ,typeof 在判断 null 的时候就出现问题了,由于 null 的所有机器码均为0,因此直接被当做了对象来看待。

数组判断: Object.prototype.toString.call()、 a instanceof Array Array.isArray是ES5标准中增加的方法,部分比较老的浏览器可能会有兼容问题,重新封装的方法如下

if (!Array.isArray) {
Array.isArray = function(arg) {
return Object.prototype.toString.call(arg) === '[object Array]';
};
}

2、自己实现一个instanceof

function new_instance_of(left, right) { 
    let rightProto = right.prototype; // 取右表达式的 prototype 值
    left = left.__proto__; // 取左表达式的__proto__值
    while (true) {
        if (left === null) {
            return false;   
        }
        if (left === rightProto) {
            return true;    
        } 
        left = left.__proto__ 
    }
}

3、基础类型和引用类型的区别?

基本类型的值是不可变的,基本类型的变量是存放在栈区的;

引用类型的值是可变的,引用类型的存储需要内存的栈区和堆区(堆区是指内存里的堆内存)共同完成,栈区内存保存变量标识符和指向堆内存中该对象的指针,引用类型的比较是引用的比较;

4、实现一个对象的深拷贝?

5、React 组件通信的方法有哪些?

父组件向子组件通信:props、 ref ,子组件向父组件通信 : 回调函数,跨层级 复杂状态管理: Context、redux、mobx;

6、React 的setState是同步的还是异步的?

在react事件触发的setState,不会同步更新this.state(通过addEventListener或者setTimeout/setInterval)会同步执行this.state

原理:在React的setState函数实现中,会根据一个变量isBatchingUpdates判断是直接更新this.state还是放到队列中回头再说,而isBatchingUpdates默认是false,也就表示setState会同步更新this.state,但是,有一个函数batchedUpdates,这个函数会把isBatchingUpdates修改为true,而当React在调用事件处理函数之前就会调用这个batchedUpdates,造成的后果,就是由React控制的事件处理过程setState不会同步更新this.state(不是真正的同步异步)

面试官追问为什么这么做 ?😯

我: react 事件中方便控制,异步setState可以 减少虚拟dom的对比,以及重复渲染的开销(这部分需要再深入研究下)

7、React 的 class 组件和函数组件的区别 ?

8、算法: 最长递增子序列 (动态规划)

输入:nums = [10,9,2,5,3,7,101,18]
输出:4
解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。

var lengthOfLIS = function(nums) {
    const len = nums.length;
    if (len < 2) {
        return len;
    }
let max = 0;
const dp = new Array(len).fill(1); // 以i为结尾的最⻓⼦串的⻓度
    for (let i = 1; i< len; i++) {
        for (let j = 0; j < i; j++) {
            if (nums[i] > nums[j]) {
                dp[i] = Math.max(dp[j] + 1, dp[i]);
            }
        }
    max = Math.max(dp[i], max);
    }
return max;

};

9、模板字符串的解析

const template = 'I'm ${name}, i love ${city}.'
const context = {name: 'coder',city: 'shanghai'}
处理后结果:I'm coder, i love shanghai.  (写的时候没用正则,硬拆字符串弄出来的 -_-||)

function parse_str(template, context) {
      return template.replace(/\$\{(.+?)\}/g, (match, key) => context[key]);
 }

//  .*? 是正则固定搭配用法,表示非贪婪匹配模式,尽可能匹配少的,

算法

10、快排

最小K个数
输入: arr = [1,3,5,7,2,4,6,8], k = 4
输出: [1,2,3,4]
var smallestK = function(arr, k) {
    if (k >= arr.length) {
        return arr;
    }
    quickSort(arr, 0, arr.length - 1, k);
    return arr.slice(0, k);
};

function quickSort(arr, start, end, k) {
    if (start > k || start >= end) {
        return ;
    }
    let left = start;
    let right = end;
    let mid = arr[left];
    while(left < right) {
        while(left < right && arr[right] >= mid) {
            right--;
        }
        if (left < right) {
            arr[left++] = arr[right];
        }
        while(left < right && arr[left] <= mid) {
            left++;
        }
        if (left < right) {
            arr[right--] = arr[left];
        }
    }
    arr[left] = mid;
    if (left === k) {
        return ;
    }
    quickSort(arr, start, left - 1, k);
    quickSort(arr, left + 1, end, k);
}