字节跳动面试官:请用js实现ajax并发请求控制(代码片段)

前端森林 前端森林     2022-12-10     454

关键词:

最近也好久没输出文章了,原因很简单,最近巨忙,,,,

讲真的,最近也很迷茫。关于技术、关于生活吧。也找了很多在大厂的朋友去聊,想需求一些后期发展的思路。这其中也聊到了面试,聊到了招聘中会给面试者出的一些题目。我正好也好久没面试了,就从中选了几道。最近也会陆续出一系列关于一些面试问题的解析。

今天这道是字节跳动的:

实现一个批量请求函数 multiRequest(urls, maxNum),要求如下:
• 要求最大并发数 maxNum
• 每当有一个请求返回,就留下一个空位,可以增加新的请求
• 所有请求完成后,结果按照 urls 里面的顺序依次打出

这道题目我想很多同学应该都或多或少的见过,下面我会依次从出现的场景、问题的分析到最终的实现,一步步力求深入浅出的给出这道题目的完整解析。

场景

假设现在有这么一种场景:现有 30 个异步请求需要发送,但由于某些原因,我们必须将同一时刻并发请求数量控制在 5 个以内,同时还要尽可能快速的拿到响应结果。

应该怎么做?

首先我们来了解一下 Ajax的串行和并行。

基于 Promise.all 实现 Ajax 的串行和并行

我们平时都是基于promise来封装异步请求的,这里也主要是针对异步请求来展开。

  • 串行:一个异步请求完了之后在进行下一个请求
  • 并行:多个异步请求同时进行

通过定义一些promise实例来具体演示串行/并行。

串行

var p = function () 
  return new Promise(function (resolve, reject) 
    setTimeout(() => 
      console.log("1000");
      resolve();
    , 1000);
  );
;
var p1 = function () 
  return new Promise(function (resolve, reject) 
    setTimeout(() => 
      console.log("2000");
      resolve();
    , 2000);
  );
;
var p2 = function () 
  return new Promise(function (resolve, reject) 
    setTimeout(() => 
      console.log("3000");
      resolve();
    , 3000);
  );
;

p()
  .then(() => 
    return p1();
  )
  .then(() => 
    return p2();
  )
  .then(() => 
    console.log("end");
  );

如示例,串行会从上到下依次执行对应接口请求。

并行

通常,我们在需要保证代码在多个异步处理之后执行,会用到:

Promise.all((promises: [])).then((fun: function));

Promise.all可以保证,promises数组中所有promise对象都达到resolve状态,才执行then回调。

var promises = function () 
  return [1000, 2000, 3000].map((current) => 
    return new Promise(function (resolve, reject) 
      setTimeout(() => 
        console.log(current);
      , current);
    );
  );
;

Promise.all(promises()).then(() => 
  console.log("end");
);

Promise.all 并发限制

这时候考虑一个场景:如果你的promises数组中每个对象都是http请求,而这样的对象有几十万个。

那么会出现的情况是,你在瞬间发出几十万个http请求,这样很有可能导致堆积了无数调用栈导致内存溢出。

这时候,我们就需要考虑对Promise.all做并发限制。

Promise.all并发限制指的是,每个时刻并发执行的promise数量是固定的,最终的执行结果还是保持与原来的Promise.all一致。

题目实现

思路分析

整体采用递归调用来实现:最初发送的请求数量上限为允许的最大值,并且这些请求中的每一个都应该在完成时继续递归发送,通过传入的索引来确定了urls里面具体是那个URL,保证最后输出的顺序不会乱,而是依次输出。

代码实现

function multiRequest(urls = [], maxNum) 
  // 请求总数量
  const len = urls.length;
  // 根据请求数量创建一个数组来保存请求的结果
  const result = new Array(len).fill(false);
  // 当前完成的数量
  let count = 0;

  return new Promise((resolve, reject) => 
    // 请求maxNum个
    while (count < maxNum) 
      next();
    
    function next() 
      let current = count++;
      // 处理边界条件
      if (current >= len) 
        // 请求全部完成就将promise置为成功状态, 然后将result作为promise值返回
        !result.includes(false) && resolve(result);
        return;
      
      const url = urls[current];
      console.log(`开始 $current`, new Date().toLocaleString());
      fetch(url)
        .then((res) => 
          // 保存请求结果
          result[current] = res;
          console.log(`完成 $current`, new Date().toLocaleString());
          // 请求没有全部完成, 就递归
          if (current < len) 
            next();
          
        )
        .catch((err) => 
          console.log(`结束 $current`, new Date().toLocaleString());
          result[current] = err;
          // 请求没有全部完成, 就递归
          if (current < len) 
            next();
          
        );
    
  );

字节跳动+京东+美团+腾讯面试总结,大厂直通车!

如何保证redis的高并发和高可用?redis的主从复制原理能介绍一下么?redis的哨兵原理能介绍一下么?面试官心理分析:其实问这个问题,主要是考考你,redis单机能承载多高并发?如果单机扛不住如何... 查看详情

字节跳动实习后端日常实习的三次面试+hr面面经

...#xff0c;目前大三上学期,方向是Java后端;投递的是字节跳动日常实习的后端实习。本来打算明年3月份春招投递,不过最近参加了字节跳动训练营,他们给了一个内推机会,就直接投了(被迫投递,哈哈&... 查看详情

字节跳动实习后端日常实习的三次面试+hr面面经

...#xff0c;目前大三上学期,方向是Java后端;投递的是字节跳动日常实习的后端实习。本来打算明年3月份春招投递,不过最近参加了字节跳动训练营,他们给了一个内推机会,就直接投了(被迫投递,哈哈&... 查看详情

字节跳动面试——算法岗

目录一面二面三面一面一面是一个特别和蔼的面试官,我们用Q来代表面试官。A表示我。A:面试官,你好Q:你好,先坐一下自我介绍吧A:好的,balabala。(这个地方大家千万不要紧张,放平心态,在下面先准备好自我介绍,上去... 查看详情

字节跳动面试——c++研发工程师

目录一面二面三面一面首先做了自我介绍,然后简单回答了面试官对于项目中的一些疑问,没有太多的深入。一面面试官比较和蔼,问的问题比较专业,比较基础,简单做了一下回忆:virtual函数能不能用在构造函数中,为什么... 查看详情

字节跳动面试官:java线程池详解

Netty实战无论是想要学习Spring5、Spark、Cassandra等这样的系统,还是通过学习Netty来构建自己的基于Java的高性能网络框架,或者是更加具体的高性能Web或者游戏服务器等,本书都将是你的超强拍档。本书共分为4个部分&#x... 查看详情

字节跳动面试官:java教学视频尚硅谷(代码片段)

异步复制MySQL的复制默认是异步的,主从复制至少需要两个MYSQL服务,这些MySQL服务可以分布在不同的服务器上,也可以在同一台服务器上。MySQL主从异步复制是最常见的复制场景。数据的完整性依赖于主库BINLOG的不丢... 查看详情

字节跳动资深面试官亲述:java异步回调接口

Linux专题微服务专题微服务架构有哪些优势?微服务有哪些特点?设计微服务的最佳实践是什么?微服务架构如何运作?微服务架构的优缺点是什么?单片,SOA和微服务架构有什么区别?在使用微服务... 查看详情

字节跳动面经——实习算法岗

目录一面二面三面一面一面是一个特别和蔼的面试官,我们用Q来代表面试官。A表示我。A:面试官,你好Q:你好,先坐一下自我介绍吧A:好的,balabala。(这个地方大家千万不要紧张,放平心态,在下面先准备好自我介绍,上去... 查看详情

字节跳动+京东+美团+腾讯面试总结,逆袭面经分享

高并发架构消息队列搜索引擎缓存分库分表读写分离设计高并发系统高并发架构部分内容缓存:Redis高可用:高并发系统设计:分布式系统分布式业务系统,就是把原来用Java开发的一个大块系统,给拆分成多... 查看详情

java注解是如何玩转的,字节跳动面试官和我聊了半个小时(代码片段)

面试官:自定义的Java注解是如何生效的?小白:自定义注解后,需要定义这个注解的注解解析及处理器,在这个注解解析及处理器的内部,通过反射使用Class、Method、Field对象的getAnnotation()方法可以获取各... 查看详情

2022字节跳动数据仓库实习面经(代码片段)

👊先和大家说一下情况,3月4号面试的字节跳动数据研发岗位直接把我挂了,我满脸疑惑,但是抱着学习和提升自我的心态,打电话问问hr,像看看面试官给我面试的评价,hr说,面试官就两行,... 查看详情

字节技术官重磅推荐!377页高并发小册,面试实战齐飞

前言高并发时代,Netty、Redis、ZooKeeper是高并发时代的必备工具。据有关数据表明,高并发的面试题现在几乎蔓延至与Java项目相关的整个行业。无论是工作还是开发Java项目所必需的技术栈:分布式Java框架、Redis缓存、... 查看详情

字节面试官告诉你如何面试研发岗(代码片段)

字节面试官告诉你如何面试研发岗Hello,豆皮范儿同学们,字节跳动春招开始了,大家ready了吗?想想快毕业了是不是很激动,又很不舍,欢迎同学积极投递起来,同时社招和实习生招聘持续进行中࿰... 查看详情

js多个异步的并发控制(代码片段)

   今天在群里看到一个人发的面试题:  1,请实现如下的函数,可以批量请求数据,所有的URL地址在urls参数中,同时可以通过max参数控制请求的并发度。当所有的请求结束后,需要执行callback回调。发请求的函数可以... 查看详情

成功拿到字节跳动offer,github标星3.2k

如何保证redis的高并发和高可用?redis的主从复制原理能介绍一下么?redis的哨兵原理能介绍一下么?面试官心理分析:其实问这个问题,主要是考考你,redis单机能承载多高并发?如果单机扛不住如何... 查看详情

敖丙:春招字节跳动蘑菇街四轮面试,分别问了啥?

...有必要,可以留言让我知道你们想看啥。面试经历一.11.20字节跳动一面Java开发,直接挂(耻辱开头……)介绍主要项目,怎么做的;本来想简要介绍做的业务,但面试官要求详细介绍,所以二十分钟都在介绍业务;送命问题:... 查看详情

字节跳动——机器学习面试岗位

目录一面 二面HR面一面 1.自我介绍,项目介绍2.lightgbmGBDTxgb,问的超级细,可能持续了78分钟,XGB残差怎么用一次和二次梯度求,分裂点怎么求,思想原理是什么。XGB实际使用中重要的超参数,你们比赛中用的目标函数是... 查看详情