热乎的字节跳动飞书一面二面:

两面面经放在一起拉,大家加油哦,如果觉得有用的话可以帮我点个赞啦!!!(同时欢迎关注我的微信号: 大明前端)

  1. ES6 语法: 解构赋值,模板字符串,promise,let,const,默认参数…
const obj = {a : 1, b : 2};
const {a, b} = obj; // a = 1; b = 2;
  1. 说一下react和vue在状态更新,组件间通信,DOM渲染的异同,这个要对这两个框架都很熟悉,这个我没答好,给大家推荐一篇文章哈哈哈。
    https://blog.csdn.net/Tokki_/article/details/90726563?ops_request_misc=%25257B%252522request%25255Fid%252522%25253A%252522160976102016780299044916%252522%25252C%252522scm%252522%25253A%25252220140713.130102334…%252522%25257D&request_id=160976102016780299044916&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-2-90726563.first_rank_v2_rank_v29_unweighted&utm_term=react%E5%92%8Cvue%E7%9A%84%E5%8C%BA%E5%88%AB%E5%8F%8A%E4%BC%98%E7%BC%BA%E7%82%B9

  2. 封装一个promise.all;

function all(promises) {
   const values = [];
   return new Promise((resolve, reject) => {
      promises.forEach((promise, index) => {
         promise.then(value => {
            values.push(value);
            if(values.length == promises.length){
               resolve(values);
            }
         }, error => { reject(error) });
      })
   })
}
  1. 手写36进制加法: (这个字节很喜欢考!!!) 我自己之前碰到过一次,现在又碰到了!!!
    function add(a, b) {} // “1” + “1z” = “20”;
    // “1b” + “1” = “1c”;
    下面我给出参考代码:希望各位
function add(a, b) {
   let dictMap = ['0', '1', '2', '3', '4', '5', ......, 'z'];
   let str1 = a.split("").reverse(); // ["z", "1"]
   let str2 = b.split("").reverse();// ["1"]
   let aLen = a.length, bLen = b.length, len = (aLen > bLen ? aLen : bLen) + 1;
   let sum = new Array(len).fill(0);
   for(let i = 0; i < aLen; i++) {
      sum[i] = dictMap.indexof(str1[i]);// [0, 0, 0] => [35, 1, 0];
   }
   for(let j = 0; j < bLen; j++) { // [1]
      sum[j] += dictMap.indexof(str2[i]);// => [36, 1, 0];
   }
   // 进位
   for(let i = 0; i < sum.length-1; i++) {
      if(sum[i] > 35) { 
         sum[i] %= 36;
         sum[i+1] += (sum[i] / 36); // [0, 2, 0];
      }
   }
   // 反向添加
   let builder = "";
   for(let i = len - 1; i >= 0; i--) {
      builder += (dictMap[sum[i]);
   }
   // 以0开头要特判
   if(builder.chat(0) == "0"){
      builder = builder.substring(1);
   }
   return builder;
}
  1. 封装一个EventEmitter类,包括on,emit,off,once.
class EventEmitter {
        constructor() {
            this.handles = {};
        }

        on(evName, callback){
            this.handles[evName] = this.handles[evName] || [];
            this.handles[evName].push(callback);
            return this;
        }

        off(evName, callback){
            let callbacks = this.handles[evName];
            if (callbacks) {]
                this.handles[evName = callbacks && callbacks.filter(fn => fn !== callback);
            }
            return this;
        }

        trigger(evName, ...args) {
            let callbacks = this.handles[evName];
            if (callbacks) {
                callbacks.forEach(callback => {
                    callback.call(this, ...args);
                })
            }
        }

        once(evName, callback) {
            let wrapFunc = (...args) => {
                callback.call(this, ...args);
                this.off(evName, wrapFunc);
            }
            this.on(evName, wrapFunc);
        }
    }
  1. 手写一个节流函数: throttle
function throttle(fn, delay) {
   let timer = null;
   return function(){
      let context = this;
      let args = argument;
      if(!timer){
         setTimeout(() => {
           fn.apply(context, args);
           timer = null;
         }, delay);
      }
   }
}
  1. 说一下三栏布局(左定右定中间自适应): 两种方式( flex + (定位+浮动) ) 比较基础。
    html搭建结构
<div class="container">
   <div class="middle"><h2>中间自适应</h2></div>
   <div class="left"><h2>左边栏</h2></div>
   <div class="right"><h2>右边栏</h2></div>
</div>
.container { 
    height:200px;
    overflow:hidden;
    padding: 0 200px;
 }
.middle {
    width: 100%;
    height: 200px; 
    background-color: deeppink;
    float:left;
 }
.left { 
    width: 200px;
    height: 200px;
    background-color: blue;
    float:left;
    /* 让左边的盒子上去 需要设置其左边距为负的中间盒子的宽度 */
    margin-left: -100%;
    position: relative;
    left: -200px;
 }
.right { 
    width: 200px;
    height: 200px;
    background-color: darkorchid;
    float:left;
    /* 让右边的盒子上去 需要设置其左边距为负的自己的宽度 */
    margin-left: -200px;
    position: relative;
    right: -200px;
 }
  1. 手写一个算法题:给定一个包含非负整数的m * n网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和最小。
    (简单的动态规划,代码就不贴了)。
// 状态转移方程:
// dp[i][j] = nums[i][j] + Math.min(dp[i-1][j], dp[i][j-1])
  1. js如何构建二叉树:
    参考链接: https://blog.csdn.net/zhenzuo_x/article/details/87968492;
  2. 给定一个URL数组,请问js如何实现串行执行[url1, url2, url3,…]
    串行本质上是一个接着一个执行,应该是构建一个promise数组
       const promise1 = new Promise((resolve, reject) => {
                setTimeout(() => {
                    resolve(5)
                },200)
        })
       const promise2 = new Promise((resolve, reject) => {
                 setTimeout(() => {
                    resolve(1)
                },300)
        })
     
        const promise3 = new Promise((resolve, reject) => {
                setTimeout(() => {
                    resolve(7)
                },100)
        })
        var arr=[promise1,promise2,promise3];
    // 第一种方法: async函数
       var fn=async function(arr){
            for(let i=0,len=arr.length;i<len;i++){
                var result=await arr[i]
                console.log(result)
            }
         }   
       fn(arr)
    // Generator
    // 这个递归设计的很巧妙
            const Cgenerator = function (arr) {
            const fn = function* () {
                for (let i = 0, len = arr.length; i < len; i++) {
                    yield arr[i]
                }
            }
            const gen = fn();

            const step = function (nextF) {
                let next=nextF()
                if (next.done) {
                    return;
                }
                if (next.value) {
                    next.value.then((data) => {
                        console.log(data)
                        step(() => { return gen.next(); })
                    })
                }
            }
            step(() => { return gen.next(); })
        }
        Cgenerator(arr)
 // Promise.resolve
 // 这个链式调用设计的也相当巧妙: 前一个promsie执行完毕后返回promise赋值给res
        const promiseThen=function(arr){
            let res=Promise.resolve()
            arr.forEach(item => {
                res=res.then(()=>{
                    return item    
                }).then((data)=>{
                    console.log(data)
                })
            });
        }
        promiseThen(arr)


参考文献:
https://blog.csdn.net/qq_39816673/article/details/94209106?ops_request_misc=%25257B%252522request%25255Fid%252522%25253A%252522160976378116780263018323%252522%25252C%252522scm%252522%25253A%25252220140713.130102334…%252522%25257D&request_id=160976378116780263018323&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-3-94209106.first_rank_v2_rank_v29_unweighted&utm_term=promise%E4%B8%B2%E8%A1%8C%E6%89%A7%E8%A1%8C

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值