前端面试编程题(异步调度,Promise实现、占用空间大小、渲染虚拟节点、实现for of)
目录
异步调度问题
题目一
答案
题目二
答案
递归输出
题目一
答案
Promise相关
题目一
答案
占用空间大小
题目一
答案
渲染虚拟节点
题目一
答案
实现for of
题目一
答案
异步调度问题
题目一
1.实现一个带并发限制的异步调度Scheduler,保证同时运行的任务最多有N个。完善下面代码中的Scheduler类,使以下程序能正确输出
class Scheduler {add(promiseCreator) {}
}
const timeout = (time) => new Promise(resolve => {setTimeout(resolve, time)
})
const scheduler = new Scheduler(3)
const addTask = (time, order) => {scheduler.add(() => timeout(time)).then(() => console.log(order))
}
addTask(1000, 'a')
addTask(500, 'b')
addTask(100, 'c')
addTask(2000, 'd')
addTask(10, 'f')
答案
方法一
class Schdule {constructor(n) {this.max = maxthis.count = 0this.queue = []}async add(promiseCreator) {if (this.count >= this.max) {await new Promise((resolve, reject) => this.queue.push(resolve))}this.count++;let res = await promiseCreator()this.count--;if (this.queue.length) {this.queue.shift()()}return res}
}
方法二
class Schdule {constructor(n) {this.max = maxthis.count = 0this.queue = []}add(promiseCreator) {return new Promise(resolve => {promiseCreator.resolve = resolve; // 保存当前promise的状态if (this.count < this.max) { // 最大并发任务处理this.runWork(promiseCreator)} else {this.queue.push(promiseCreator)}})}runWork(promiseCreator) {this.count++promiseCreator().then(() => {promiseCreator.resolve()this.count--if (this.queue.length) {this.runWork(this.queue.shift())}})}
}
题目二
实现一个带并发限制的异步调度PromiseQueue,保证同时运行的任务最多有N个且按优先级运行任务。完善下面代码中的PromiseQueue类,使以下程序能正确输出
link1start
link2start
link3start
link2end
high prioritystart
link1end
link5start
link3end
link4start
high priorityend
link4end
link5end
const urls = [{info: 'link1',time: 3000,priority: 1}, {info: 'link2',time: 2000,priority: 2}, {info: 'link3',time: 3000,priority: 3}, {info: 'link4',time: 2000,priority: 2}, {info: 'link5',time: 5000,priority: 5}
]
function loadImg(url) {return new Promise((resolve, reject) => {console.log(url.info + 'start')setTimeout(() => {console.log(url.info + 'end')resolve()}, url.time)})
}
class PromiseQueue {}
const q = new PromiseQueue({concurrency: 3
})
const formatTask = (url) => {return {fn: () => loadImg(url),priority: url.priority}
}
urls.forEach(url => {q.add(formatTask(url))
})
const highPriorityTask = {priority: 10,info: 'high priority',time: 2000
}
q.add(formatTask(highPriorityTask))
答案
class PromiseQueue {constructor(options = {}) {this.concurrency = options.concurrency || 1;this.currentCount = 0this.pendingList = []}add(task) {this.pendingList.push(task)this.run()}run() {if (this.pendingList.length === 0) {return;}if (this.concurrency === this.currentCount) {return;}this.currentCount++const { fn } = this.pendingList.sort((a, b) => b.priority - a.priority).shift()fn().then(this.completeOne.bind(this)).catch(this.completeOne.bind(this))}completeOne() {this.currentCount--this.run()}
}
递归输出
题目一
实现compose函数使下面的代码输出顺序为1,2,3,3.3,2.2,1.1 。
let middleware = []
middleware.push((next)=>{console.log(1)next()console.log(1.1)
})
middleware.push((next)=>{console.log(2)next()console.log(2.2)
})
middleware.push((next)=>{console.log(3)next()console.log(3.3)
})
let fn = compose(middleware)
fn()
这里观察输出1后执行next,然后输出2,执行next在到3,然后3.3,回到2.2,再回到1.1,这里明显为一个递归调用,传入的参数next为递归的函数,每次调用便会执行下一个函数。
答案
function compose(...args){let index = 0;return function fn() {if(args[0].length<=index){return;}return args[0][index++](fn)}
}
function compose(middlewares) {const copyMidlewares = [...middlewares];let index = 0const fn = () => {if (index >= copyMidlewares.length) {return ;}const middlewares = copyMidlewares[index];index++;return middlewares(fn)}return fn;
}
Promise相关
题目一
编写Promise.all和Promise.race方法。
答案
Promise.all = (arr) => {if (!Array.isArray(arr)) {return;}let counter = 0;let result = []return new Promise((resolve, reject) => {arr.forEach((item, index) => {Promise.resolve(item).then(value => {result[index] = value;counter++;if (counter === arr.length) {resolve(result);}}).catch(err => {reject(err)})})});
}
Promise.rRace = function (arr) {if (!Array.isArray(arr)) {return;}return new Promise((resolve, reject) => {arr.forEach(v => {Promise.resolve(v).then(value=>{resolve(value)}).catch(err => reject(err))})})
}
占用空间大小
题目一
1.计算一个变量占用的字节数(string占2字节,boolean占4字节,number占8字节)
注意
1.对象的属性值也占用字
2.相同的引用只能算一次
答案
const set = new Set()
function sizeOfObject(object) {if (object == null) {return 0}let bytes = 0;const properties = Object.keys(object)for (let i = 0; i < properties.length; i++) {const key = properties[i]if (typeof object[key] === 'object' && object[key] !== null) {if (set.has(object[key])) {bytes += calculator(key)continue}set.add(object[key])}bytes += calculator(key)bytes += calculator(object[key])}return bytes
}
function calculator(object) {switch (typeof object) {case 'string': {return object.length * 2}case 'boolean': {return 4}case 'number': {return 8}case 'object': {if (Array.isArray(object)) {return object.map(calculator).reduce((res, current) => res + current, 0)}return sizeOfObject(object)}}
}
渲染虚拟节点
题目一
1.将如下数据格式的虚拟dom为真实dom
const vnode = {tag: 'DIV',attrs: {id: 'app'},children: [{tag: 'SPAN',children: [{tag: 'A',children: []}]},{tag:'SPAN',children:[{tag:'A',children:[]},{tag:'',children:[]}]}]
}
答案
function render(vnode){if(typeof vnode === 'number'){vnode = String(vnode)}if(typeof vnode=== 'string'){return document.createTextNode(vnode);}const element = document.createElement(vnode.tag);if(vnode.attrs){Object.keys(vnode.attrs).forEach(key=>{element.setAttribute(key,vnode.attrs[key])})}if(vnode.children.length){vnode.children.forEach(v=>{element.appendChild(render(v))})}return element
}
实现for of
题目一
如何使对象实现for of。
答案
方法一
obj[Symbol.iterator]=function(){const _this = this//也可使用: keys = Object.getOwnPropertyNames(this)const keys = Object.keys(this)let index = 0return {next(){return {value: _this[keys[index++]],done: index>keys.length}}}
}
方法二
obj[Symbol.iterator] = function *(){for(let prop in this){yield this[prop]}
}
相关文章:
前端面试编程题(异步调度,Promise实现、占用空间大小、渲染虚拟节点、实现for of)
目录 异步调度问题 题目一 答案 题目二 答案 递归输出 题目一 答案 Promise相关 题目一 答案 占用空间大小 题目一 答案 渲染虚拟节点 题目一 答案 实现for of 题目一 答案 异步调度问题 题目一 1.实现一个带并发限制的异步调度Scheduler,保证同…...

复旦团队发布国内首个模型MOSS 类ChatGPT
复旦团队发布国内首个模型MOSS 类ChatGPT 首先看到这个标题,还有这个名字,我是正经(zhen jing)的 (bu shi 流浪地球?550W?不了解的可以把550W倒过来写,就懂了 看到新闻里的一些图…...

5.35 综合案例2.0 -称重数据上传云端
综合案例2.0 - 称重数据上传云端案例说明连线功能实现1.阿里云平台连接代码应用开发3.1新建‘普通项目’3.2关联产品和设备3.3新建‘移动应用’3.4添加组件3.5配置组件信息3.6保存预览案例说明 使用hx711串口模块称重,结合IOT studio制作手机APP远程控制并采集物体重量。 hx7…...

如何让人机对话更自然?
来源:投稿 作者:顾相欢 编辑:学姐 AAAI-2022|定制对话的人设和知识背景 原文标题: Call for Customized Conversation: Customized Conversation Grounding Persona and Knowledge 原文链接: https://arxiv.org/ab…...

Python每日一练(20230224)
目录 1. 列表奇偶拆分 ★ 2. 二叉树的后序遍历 ★★ 3. 接雨水 ★★★ 附录 二叉树 特点 性质 特殊二叉树 满二叉树 完全二叉树 完全二叉树性质 二叉树的遍历 1. 列表奇偶拆分 【问题描述】 输入一个列表,包含若干个整数(允许为空ÿ…...

【Linux】-- Shell的运行原理、Linux当中的权限
目录 Shell的运行原理 Linux权限的概念 su命令 权限 文件访问权限的相关设置方法 chmod指令 chown指令 chgrp指令 sudo命令 文件的常见问题 umask 粘滞位 关于权限的总结 Shell的运行原理 Shell运行原理 —— 外壳程序。 Linux严格意义上说的是一个操作系统&…...

MOS管选型参数:VGS(th)
MOS管选型参数:VGS(th) VGS(th):开启电压(阀值电压)。当外加栅极控制电压 VGS 超过 VGS(th) 时,漏区和源区的表面反型层形成了连接的沟道。应用中,常将漏极短…...

二.线性表之顺序表
文章目录前言一.顺序表的概念及结构二.顺序表的接口实现1.顺序表的动态存储2.顺序表的初始化3.顺序表尾插#封装:扩容函数4.顺序表尾删5.顺序表头插6.顺序表头删7.顺序表查找8.顺序表在pos位置插入x9.顺序表删除pos位置的值10.顺序表销毁11.顺序表打印三.源1.Seqlist…...
ElasticSearch - SpringBoot整合ElasticSearch实现文档的增删改
文章目录1. ElasticSearch和kibana的安装和配置2. SpringBoot 项目环境搭建3. 创建索引4. 索引文档5. 更新文档6. 删除文档https://www.elastic.co/guide/en/elasticsearch/reference/current/search-your-data.htmlhttps://www.elastic.co/guide/cn/elasticsearch/guide/curre…...

JavaScript 库
文章目录JavaScript 库JavaScript 框架(库)jQueryPrototypeMooTools其他框架CDN -内容分发网络引用 jQuery使用框架JavaScript 库 JavaScript 库 - jQuery、Prototype、MooTools。 JavaScript 框架(库) JavaScript 高级程序设计…...
云解析DNS为什么要配置默认线路?
传统解析技术不会判断访客IP,而是会随机选择一个IP返回给访问者,这样就有可能造成移动用户访问电信服务器IP,北京用户访问深圳服务器IP这种跨域跨网访问的情况,产生非常大的延迟,带来很不好的访问体验。 而云解析DNS会…...

Linux命令之awk
awk是一个有强大的文本格式化能力的linux命令,早期是在Unix上实现的,linux后来也可以使用了,我们在Linux上使用的awk是gawk(GNU awk的意思) 语法 awk [option] 模式{动作} file option表示awk的可选参数,可…...

实战-缓存数据一致+binlog初始+cannel监听+数据迁移,数据一致性架构设计
前言 一. 解决缓存不命中(高并发操作击穿打挂DB的风险) 当并发量打的时候,当我们的缓存过期时,就算到数据库的比例偏小的时候,我们的请求时比较大的。那也会存在数据库崩掉的情况。解决方案想法如下(总体…...
nginx配置中proxy_pass反向代理502的bug
记录一个坑人的bug, 我今天在一台新的liunx上运行nginx来进行反向代理时候,发现怎么测都是502 我把配置全部删了从头开始配置,发现80端口正常,80端口index.html正常,反向代理转向http://127.0.0.1/也正常,…...

JavaScript 两种方案打开文件对话框
JavaScript 两种方案打开文件对话框 文章目录JavaScript 两种方案打开文件对话框一、文件对话框二、传统方案表单元素🌈三、文件系统访问API💦四、更进一步使用六、代码仓库🌐七、参考资料💘七、推荐博文🍗一、文件对话…...

Pycharm远程服务器常见问题
2023年02月23日 问题描述:Pycharm远程服务器跑代码时,不小心把Pycharm关掉了,但服务器代码还在运行? 解决办法:kill进程 先用watch -n 0.5 nvidia_smi查看进程,然后kill -9 <进程> 1、nvidia-smi…...

内容团队如何快速出稿
对于内容团队而言,每个内容选题就相当于一个小项目,它们并非简单的线性工作流,相反其复杂程度不亚于一个小型工厂。一个内容选题会涉及内容形式,选题类型等多个变量,这些变量因素组合起来就是十几种不同类型的工作流。…...
es-08索引的批量操作
索引的批量操作 批量查询和批量增删改 批量查询 GET /_mget#批量查询 GET product/_search GET /_mget {"docs": [{"_index": "product","_id": 2},{"_index": "product","_id": 3}] }GET product/_mge…...

诈金花的概率
游戏使用一副除去大小王的扑克牌,共4个花色52张牌。 1、豹子(AAA最大,222最小)。2、同花顺(AKQ最大,A23最小)。3、同花(AKQ最大,352最小)。4、顺子ÿ…...

ESP32设备驱动-MLX90393磁场传感器驱动
MLX90393磁场传感器驱动 文章目录 MLX90393磁场传感器驱动1、MLX90393介绍2、硬件准备3、软件准备4、驱动实现1、MLX90393介绍 MLX90393 磁场传感器可以在运行时重新编程为不同的模式和不同的设置。 该传感器使用 Melexis 专有的 Triaxis 技术提供与沿 XYZ 轴感应的磁通密度成…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版
7种色调职场工作汇报PPT,橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版:职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...

GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

uniapp手机号一键登录保姆级教程(包含前端和后端)
目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号(第三种)后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...
【JavaSE】多线程基础学习笔记
多线程基础 -线程相关概念 程序(Program) 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存…...

【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...

【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...